Skip to content

Commit 185383e

Browse files
committed
Add a workflow to upgrade Git for Windows' packages
This workflow will perform the rather repetitive tasks of upgrading Git for Windows' packages to newer versions. With this workflow, we pursue a new strategy to upgrade those packages: We previously had an Azure Pipeline that edited the `PKGBUILD`, built the packages, then deployed them to the Pacman repository, and only when everything worked, the commit(s) with the update would be pushed directly to `main`. The new strategy is to instead have a workflow run (this one!) to edit the `PKGBUILD`, and then open a PR. A subsequent PR run will verify that the package builds. Another workflow (the sibling of this one, `build-and-deploy`) will then "branch-deploy", i.e. build and upload the packages from that PR. Once everything worked, the PR will be merged. Hopefully that process will make it much more transparent how the Git for Windows project is run. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 7de3bc9 commit 185383e

File tree

1 file changed

+199
-0
lines changed

1 file changed

+199
-0
lines changed

.github/workflows/open-pr.yml

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
name: Upgrade a package version and open a PR
2+
run-name: Upgrade ${{ inputs.package }} to ${{ inputs.version }}
3+
4+
on:
5+
workflow_dispatch:
6+
inputs:
7+
package:
8+
description: The package to update
9+
type: string
10+
required: true
11+
version:
12+
description: The new version of the package
13+
type: string
14+
required: true
15+
16+
env:
17+
PACKAGE_TO_UPGRADE: ${{ github.event.inputs.package }}
18+
UPGRADE_TO_VERSION: ${{ github.event.inputs.version }}
19+
OWNER: 'git-for-windows'
20+
ACTOR: "${{ github.triggering_actor }}"
21+
22+
jobs:
23+
open-pr:
24+
runs-on: windows-latest
25+
steps:
26+
- name: Determine REPO
27+
id: repo
28+
shell: bash
29+
run: |
30+
case "$PACKAGE_TO_UPGRADE" in
31+
mingw-w64-cv2pdb|mingw-w64-git-credential-manager|\
32+
mingw-w64-git-lfs|mingw-w64-git-sizer|mingw-w64-wintoast|\
33+
git-extra|git-for-windows-keyring) repo=build-extra;;
34+
mingw-w64-*) repo=MINGW-packages;;
35+
*) repo=MSYS2-packages;;
36+
esac &&
37+
echo "REPO=$repo" >>$GITHUB_ENV &&
38+
echo "repo=$repo" >>$GITHUB_OUTPUT
39+
- uses: actions/checkout@v3
40+
# Since we want to operate on _another_ repository, we sadly cannot use:
41+
#
42+
# permissions:
43+
# checks: write
44+
#
45+
# Therefore, we registered a GitHub App and stored the data required to
46+
# act as that App in repository secrets `GH_APP_ID`, `GH_APP_PRIVATE_KEY`.
47+
- name: Obtain installation token
48+
id: setup
49+
uses: actions/github-script@v6
50+
with:
51+
script: |
52+
const appId = ${{ secrets.GH_APP_ID }}
53+
const privateKey = `${{ secrets.GH_APP_PRIVATE_KEY }}`
54+
55+
const getAppInstallationId = require('./get-app-installation-id')
56+
const installationId = await getAppInstallationId(
57+
console,
58+
appId,
59+
privateKey,
60+
process.env.OWNER,
61+
process.env.REPO
62+
)
63+
64+
const getInstallationAccessToken = require('./get-installation-access-token')
65+
const accessToken = await getInstallationAccessToken(
66+
console,
67+
appId,
68+
privateKey,
69+
installationId
70+
)
71+
72+
core.setSecret(accessToken)
73+
core.setOutput('token', accessToken)
74+
- name: set up partial Git for Windows SDK
75+
uses: git-for-windows/setup-git-for-windows-sdk@v1
76+
with:
77+
flavor: minimal
78+
- name: download files necessary for `updpkgsums` to work
79+
shell: bash
80+
run: |
81+
for p in \
82+
/etc/makepkg.conf \
83+
/usr/bin/gettext.exe \
84+
/usr/bin/makepkg \
85+
/usr/bin/nproc.exe \
86+
/usr/bin/pacman.exe \
87+
/usr/bin/sha256sum.exe \
88+
/usr/bin/updpkgsums
89+
do
90+
curl -sLo $p https://github.com/git-for-windows/git-sdk-64/raw/HEAD$p || exit 1
91+
done &&
92+
for p in /usr/share/makepkg
93+
do
94+
b=${p##*/} &&
95+
d=${p%/$b} &&
96+
if test "z$b" = "z$d"
97+
then
98+
d=
99+
fi &&
100+
tree=$(curl -s https://api.github.com/repos/git-for-windows/git-sdk-64/git/trees/main:${d#/} |
101+
jq -r '.tree[] | select(.path | test("^'$b'$")) | .sha') &&
102+
mkdir -p $p &&
103+
curl -sL https://github.com/git-for-windows/git-sdk-64/tarball/$tree |
104+
tar --strip-components=1 -C $p -xzvf - || exit 1
105+
done &&
106+
ln -s "${COMSPEC%cmd.exe}curl.exe" /usr/bin/
107+
- name: Clone ${{ env.REPO }}
108+
shell: bash
109+
run: |
110+
mkdir -p /usr/src &&
111+
git clone --depth 1 --single-branch -b main "https://github.com/$OWNER/$REPO" "/usr/src/$REPO"
112+
- name: Identify actor
113+
id: actor
114+
uses: actions/github-script@v6
115+
with:
116+
script: |
117+
const githubApiRequest = require('./github-api-request')
118+
const answer = await githubApiRequest(
119+
console,
120+
'${{ steps.setup.outputs.token }}',
121+
'GET',
122+
`/users/${process.env.ACTOR}`
123+
)
124+
core.setOutput('login', answer.login)
125+
core.setOutput('name', answer.name)
126+
core.setOutput('email', answer.email)
127+
- name: Configure build
128+
shell: bash
129+
run: |
130+
USER_NAME="${{ steps.actor.outputs.name }}" &&
131+
USER_EMAIL="${{ steps.actor.outputs.email }}" &&
132+
mkdir -p "$HOME" &&
133+
git config --global user.name "$USER_NAME" &&
134+
git config --global user.email "$USER_EMAIL" &&
135+
echo "PACKAGER=$USER_NAME <$USER_EMAIL>" >>$GITHUB_ENV
136+
- name: update PKGBUILD
137+
id: update
138+
shell: bash
139+
run: |
140+
cd "/usr/src/$REPO/$PACKAGE_TO_UPGRADE" &&
141+
sed -i \
142+
-e "s/^\\(pkgver=\\).*/\\1$UPGRADE_TO_VERSION/" \
143+
-e 's/^pkgrel=.*/pkgrel=1/' \
144+
PKGBUILD &&
145+
git update-index -q --refresh &&
146+
if git diff-files --exit-code
147+
then
148+
echo "::notice::$PACKAGE_TO_UPGRADE already at $UPGRADE_TO_VERSION"
149+
exit 0
150+
fi &&
151+
152+
updpkgsums &&
153+
msg="$PACKAGE_TO_UPGRADE: update to $UPGRADE_TO_VERSION" &&
154+
git commit -sm "$msg" PKGBUILD &&
155+
echo "msg=$msg" >>$GITHUB_OUTPUT &&
156+
echo "modified=true" >>$GITHUB_OUTPUT
157+
- name: push
158+
if: steps.update.outputs.modified == 'true'
159+
shell: bash
160+
run: |
161+
auth="$(printf '%s:%s' '${{ steps.actor.outputs.login }}' '${{ steps.setup.outputs.token }}' | base64)" &&
162+
echo "::add-mask::$auth" &&
163+
cd "/usr/src/$REPO/$PACKAGE_TO_UPGRADE" &&
164+
git -c http.extraHeader="Authorization: Basic $auth" push --force origin HEAD:refs/heads/$PACKAGE_TO_UPGRADE-$UPGRADE_TO_VERSION
165+
- name: open PR
166+
if: steps.update.outputs.modified == 'true'
167+
uses: actions/github-script@v6
168+
with:
169+
github-token: ${{ steps.setup.outputs.token }}
170+
script: |
171+
let body = undefined
172+
try {
173+
const name = process.env.PACKAGE_TO_UPGRADE
174+
const version = `${name.match(/git-lfs/) ? 'v' : ''}${process.env.UPGRADE_TO_VERSION}`
175+
176+
if (name === 'mintty') body = `See https://github.com/mintty/mintty/releases/tag/${version} for details.`
177+
else if (name === 'mingw-w64-git-lfs') body = `See https://github.com/git-lfs/git-lfs/releases/tag/${version} for details.`
178+
179+
const terms = 'type:issue repo:git-for-windows/git state:open author:app/github-actions label:component-update'
180+
const { data } = await github.rest.search.issuesAndPullRequests({
181+
q: `"[New ${name.replace(/^mingw-w64-/, '')} version]" ${version} in:title ${terms}`,
182+
})
183+
if (data.total_count) body = `${body && `${body}\n\n`}This closes ${data.items[0].html_url}`
184+
} catch (e) {
185+
console.log(e)
186+
}
187+
188+
const pr = await github.rest.pulls.create({
189+
owner: process.env.OWNER,
190+
repo: process.env.REPO,
191+
base: 'main',
192+
draft: true,
193+
head: `${process.env.PACKAGE_TO_UPGRADE}-${process.env.UPGRADE_TO_VERSION}`,
194+
maintainer_can_modify: true,
195+
title: '${{ steps.update.outputs.msg }}',
196+
body
197+
})
198+
if (pr.status === 201) console.log(`::notice::${pr.data.html_url}`)
199+
else console.log(pr)

0 commit comments

Comments
 (0)