Release Git for Windows #69
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Release Git for Windows | |
on: | |
workflow_dispatch: | |
inputs: | |
git_artifacts_i686_workflow_run_id: | |
description: 'ID of the git-artifacts (i686) workflow run' | |
required: true | |
git_artifacts_x86_64_workflow_run_id: | |
description: 'ID of the git-artifacts (x86_64) workflow run' | |
required: true | |
git_artifacts_aarch64_workflow_run_id: | |
description: 'ID of the git-artifacts (aarch64) workflow run' | |
required: true | |
env: | |
HOME: "${{github.workspace}}\\home" | |
USERPROFILE: "${{github.workspace}}\\home" | |
OWNER: git-for-windows | |
REPO: git | |
I686_WORKFLOW_RUN_ID: "${{github.event.inputs.git_artifacts_i686_workflow_run_id}}" | |
X86_64_WORKFLOW_RUN_ID: "${{github.event.inputs.git_artifacts_x86_64_workflow_run_id}}" | |
AARCH64_WORKFLOW_RUN_ID: "${{github.event.inputs.git_artifacts_aarch64_workflow_run_id}}" | |
jobs: | |
setup: | |
runs-on: ubuntu-latest | |
if: github.event.repository.owner.login == 'git-for-windows' | |
outputs: | |
display-version: ${{ steps.bundle-artifacts.outputs.display-version }} | |
tag-name: ${{ steps.bundle-artifacts.outputs.tag-name }} | |
ver: ${{ steps.bundle-artifacts.outputs.ver }} | |
git-rev: ${{ steps.bundle-artifacts.outputs.git-rev }} | |
release-notes: ${{ steps.bundle-artifacts.outputs.release-notes }} | |
pull-request-number: ${{ steps.announcement.outputs.pull-request-number }} | |
pull-request-comment: ${{ steps.announcement.outputs.pull-request-comment }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: The `release` branch must be up to date | |
uses: actions/github-script@v7 | |
with: | |
script: | | |
const sha = await (async () => { | |
try { | |
return (await github.rest.git.getRef({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
ref: 'heads/release' | |
})).data.object.sha | |
} catch (e) { | |
// If the ref does not exist, use an undefined `sha` | |
if (e?.status === 404) return undefined | |
throw e | |
} | |
})() | |
if (sha !== '${{ github.sha }}') { | |
console.log(`Trying to update the 'release' branch by fast-forwarding to 'main' in ${context.repo.owner}/${context.repo.repo}`) | |
try { | |
const { pushGitBranch } = require('./repository-updates.js') | |
await pushGitBranch( | |
console, | |
core.setSecret, | |
${{ secrets.GH_APP_ID }}, | |
${{ toJSON(secrets.GH_APP_PRIVATE_KEY) }}, | |
context.repo.owner, | |
context.repo.repo, | |
'refs/heads/main:refs/heads/release' | |
) | |
} catch(e) { | |
console.log(e) | |
throw new Error(`The 'release' branch is not up to date! | |
Actual: ${sha}, expected: ${{ github.sha }}. | |
The idea of the 'release-git' workflow is that the runs are started from | |
the 'main' branch and the actual jobs' definitions are maintained in | |
the 'release' branch, to allow modifying them and re-starting failed jobs | |
individually. To that end, the 'release' branch is expected to point at the | |
same commit as the 'main' branch when this workflow is started.`) | |
} | |
} | |
- name: Get bundle-artifacts and sha256sums | |
id: bundle-artifacts | |
uses: actions/github-script@v7 | |
with: | |
script: | | |
const { downloadBundleArtifacts } = require('./github-release') | |
const result = await downloadBundleArtifacts( | |
console, | |
'${{ secrets.GITHUB_TOKEN }}', | |
context.repo.owner, | |
context.repo.repo, | |
process.env.I686_WORKFLOW_RUN_ID, | |
process.env.X86_64_WORKFLOW_RUN_ID, | |
process.env.AARCH64_WORKFLOW_RUN_ID | |
) | |
core.setOutput('display-version', result.displayVersion) | |
core.setOutput('tag-name', result.tagName) | |
core.setOutput('ver', result.ver) | |
core.setOutput('git-rev', result.gitCommitOID) | |
core.startGroup('Announcement email') | |
core.info(result.announcement) | |
core.endGroup() | |
core.setOutput('release-notes', result.releaseNotes) | |
- name: Re-publish bundle-artifacts so the next job can easily use it | |
uses: actions/upload-artifact@v4 | |
with: | |
name: bundle-artifacts | |
path: bundle-artifacts | |
- name: Publish announcement mail as a stand-alone artifact | |
id: announcement-email | |
uses: actions/upload-artifact@v4 | |
with: | |
name: announcement | |
path: bundle-artifacts/announce-* | |
- name: Prepare a comment about the announcement email to the Pull Request | |
id: announcement | |
uses: actions/github-script@v7 | |
with: | |
script: | | |
const gitSHA = ${{ toJson(steps.bundle-artifacts.outputs.git-rev) }} | |
const tagName = ${{ toJson(steps.bundle-artifacts.outputs.tag-name) }} | |
const ver = ${{ toJson(steps.bundle-artifacts.outputs.ver) }} | |
const announcementURL = ${{ toJson(steps.announcement-email.outputs.artifact-url) }} | |
const nth = (n) => { | |
const suffix = ((n + 89) % 100) > 2 && ['th', 'st', 'nd', 'rd'][n % 10] || 'th' | |
return `${n}${suffix}` | |
} | |
const releaseURL = `https://github.com/${process.env.OWNER}/${process.env.REPO}/releases/tag/${tagName}` | |
const [, baseVersion, rc ] = ver.match(/^(.*)-rc(\d+)$/) || [ver] | |
const skeet = | |
rc | |
? `The ${nth(Number.parseInt(rc) + 1)} preview of Git for Windows ${baseVersion} is available, please test! ${releaseURL}` | |
: `Git for Windows ${baseVersion} is available! ${releaseURL}` | |
const blueskyLink = `https://bsky.app/intent/compose?text=${encodeURIComponent(skeet)}` | |
const body = `please [Share on Bluesky](${blueskyLink}) and send [the announcement email](${announcementURL}).` | |
const q = `repo:${process.env.OWNER}/${process.env.REPO}+is:pr+is:open+${gitSHA}` | |
const { data } = await github.rest.search.issuesAndPullRequests({ q }) | |
if (data.items.length === 1) { | |
const author = data.items[0].user.login | |
core.setOutput('pull-request-number', data.items[0].number) | |
core.setOutput('pull-request-comment', `@${author}, ${body}`) | |
core.info(`Prepared a comment to add to ${data.items[0].html_url}:\n@${author}, ${body}`) | |
} else { | |
core.warning(`${data.items.length} PRs found for ${gitSHA}, not posting a comment, would have posted:\n${body}`) | |
} | |
github-release: | |
needs: ['setup'] | |
runs-on: ubuntu-latest | |
steps: | |
- name: GitHub Release | |
uses: git-for-windows/git-for-windows-automation/.github/actions/github-release@release | |
with: | |
app-id: ${{ secrets.GH_APP_ID }} | |
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} | |
owner: ${{ env.OWNER }} | |
repo: ${{ env.REPO }} | |
display-version: ${{ needs.setup.outputs.display-version }} | |
tag-name: ${{ needs.setup.outputs.tag-name }} | |
rev: ${{ needs.setup.outputs.git-rev }} | |
release-notes: ${{ needs.setup.outputs.release-notes }} | |
artifacts-repository: ${{ github.repository }} | |
artifacts-token: ${{ secrets.GITHUB_TOKEN }} | |
git_artifacts_i686_workflow_run_id: ${{ env.I686_WORKFLOW_RUN_ID }} | |
git_artifacts_x86_64_workflow_run_id: ${{ env.X86_64_WORKFLOW_RUN_ID }} | |
git_artifacts_aarch64_workflow_run_id: ${{ env.AARCH64_WORKFLOW_RUN_ID }} | |
pull-request-number: ${{ needs.setup.outputs.pull-request-number }} | |
pull-request-comment: ${{ needs.setup.outputs.pull-request-comment }} | |
gitforwindows-site: | |
needs: ['setup', 'github-release'] | |
runs-on: ubuntu-latest | |
steps: | |
- name: https://gitforwindows.org | |
uses: git-for-windows/git-for-windows-automation/.github/actions/gitforwindows.org@release | |
with: | |
app-id: ${{ secrets.GH_APP_ID }} | |
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} | |
owner: ${{ env.OWNER }} | |
repo: ${{ env.REPO }} | |
display-version: ${{ needs.setup.outputs.display-version }} | |
rev: ${{ needs.setup.outputs.git-rev }} | |
repository-updates: | |
needs: ['setup', 'github-release'] | |
runs-on: ubuntu-latest | |
steps: | |
- name: Git repository updates (build-extra, MINGW-packages) | |
uses: git-for-windows/git-for-windows-automation/.github/actions/repository-updates@release | |
with: | |
app-id: ${{ secrets.GH_APP_ID }} | |
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} | |
owner: ${{ env.OWNER }} | |
repo: ${{ env.REPO }} | |
display-version: ${{ needs.setup.outputs.display-version }} | |
rev: ${{ needs.setup.outputs.git-rev }} | |
artifacts-repository: ${{ github.repository }} | |
artifacts-token: ${{ secrets.GITHUB_TOKEN }} | |
git_artifacts_x86_64_workflow_run_id: ${{ env.X86_64_WORKFLOW_RUN_ID }} | |
pacman-packages: | |
needs: ['setup'] | |
runs-on: windows-latest | |
steps: | |
- name: Pacman packages | |
uses: git-for-windows/git-for-windows-automation/.github/actions/pacman-packages@release | |
with: | |
app-id: ${{ secrets.GH_APP_ID }} | |
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} | |
owner: ${{ env.OWNER }} | |
repo: ${{ env.REPO }} | |
display-version: ${{ needs.setup.outputs.display-version }} | |
rev: ${{ needs.setup.outputs.git-rev }} | |
artifacts-repository: ${{ github.repository }} | |
artifacts-token: ${{ secrets.GITHUB_TOKEN }} | |
git_artifacts_i686_workflow_run_id: ${{ env.I686_WORKFLOW_RUN_ID }} | |
git_artifacts_x86_64_workflow_run_id: ${{ env.X86_64_WORKFLOW_RUN_ID }} | |
git_artifacts_aarch64_workflow_run_id: ${{ env.AARCH64_WORKFLOW_RUN_ID }} | |
gpg-key: ${{ secrets.GPGKEY }} | |
priv-gpg-key: ${{ secrets.PRIVGPGKEY }} | |
azure-blobs-token: ${{ secrets.AZURE_BLOBS_TOKEN }} | |
nuget-packages: | |
needs: ['setup'] | |
runs-on: windows-latest | |
steps: | |
- name: NuGet packages | |
uses: git-for-windows/git-for-windows-automation/.github/actions/nuget-packages@release | |
with: | |
app-id: ${{ secrets.GH_APP_ID }} | |
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} | |
owner: ${{ env.OWNER }} | |
repo: ${{ env.REPO }} | |
display-version: ${{ needs.setup.outputs.display-version }} | |
rev: ${{ needs.setup.outputs.git-rev }} | |
artifacts-repository: ${{ github.repository }} | |
artifacts-token: ${{ secrets.GITHUB_TOKEN }} | |
git_artifacts_x86_64_workflow_run_id: ${{ env.X86_64_WORKFLOW_RUN_ID }} | |
nuget-api-key: ${{ secrets.NUGET_API_KEY }} |