Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a GitHub workflow to run updpkgsums in PRs #62

Merged
merged 2 commits into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions .github/actions/init-g4w-sdk-for-pacman/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: 'Initialize Git for Windows SDK subset to run `pacman`'
description: 'This composite GitHub Action initializes a subset of the Git for Windows SDK intended to run `pacman` and friends'
outputs:
result:
description: 'The path to the subset of the SDK'
value: '${{ steps.use-sdk.outputs.result }}'
runs:
using: 'composite'
steps:
- name: initialize bare SDK clone
id: clone-g4w-sdk
shell: bash
run: |
git clone --bare --depth=1 --single-branch --branch=main --filter=blob:none \
https://github.com/git-for-windows/git-sdk-64 .tmp &&
echo "rev=$(git -C .tmp rev-parse HEAD)" >>$GITHUB_OUTPUT
- name: restore cached git-sdk-64 subset
id: restore-g4w-sdk
uses: actions/cache/restore@v3
env:
cache-name: cache-g4w-sdk
with:
path: .sdk
key: g4w-sdk-${{ steps.clone-g4w-sdk.outputs.rev }}
- name: check out git-sdk-64 subset
if: ${{ steps.restore-g4w-sdk.outputs.cache-hit != 'true' }}
shell: bash
env:
GIT_CONFIG_PARAMETERS: "'checkout.workers=56'"
run: |
git -C .tmp config extensions.worktreeConfig true &&
git -C .tmp worktree add --no-checkout --detach "$PWD/.sdk" &&
cd .sdk &&
git config --worktree core.sparseCheckout true &&
git config --worktree core.bare false &&
sparse="$(git rev-parse --git-path info/sparse-checkout)" &&
mkdir -p "${sparse%/*}" &&
git show HEAD:.sparse/minimal-sdk >"$sparse" &&
cat >>"$sparse" <<-EOF &&
/etc/makepkg.conf
/usr/bin/base64.exe
/usr/bin/gettext.exe
/usr/bin/makepkg
/usr/bin/nproc.exe
/usr/bin/pacman.exe
/usr/bin/sha256sum.exe
/usr/bin/updpkgsums
/usr/share/makepkg/
/mingw64/bin/curl.exe
EOF
git checkout -- &&

# makepkg/updpkgsums expects `curl` to be present in `/usr/bin/`
printf '#!/bin/sh\n\nexec /mingw64/bin/curl.exe "$@"' >usr/bin/curl
- name: cache git-sdk-64 subset
if: ${{ steps.restore-g4w-sdk.outputs.cache-hit != 'true' }}
uses: actions/cache/save@v3
env:
cache-name: cache-g4w-sdk
with:
path: .sdk
key: g4w-sdk-${{ steps.clone-g4w-sdk.outputs.rev }}
- name: use git-sdk-64 subset
id: use-sdk
shell: bash
run: |
cd .sdk &&

echo "result=$(cygpath -aw .)" >>$GITHUB_OUTPUT &&

# add the SDK directories to the `PATH`
cygpath -aw "usr/bin/core_perl" >>$GITHUB_PATH &&
cygpath -aw "usr/bin" >>$GITHUB_PATH &&
cygpath -aw "mingw64/bin" >>$GITHUB_PATH &&
echo "MSYSTEM=MINGW64" >>$GITHUB_ENV
65 changes: 2 additions & 63 deletions .github/workflows/open-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,69 +74,8 @@ jobs:

core.setSecret(accessToken)
core.setOutput('token', accessToken)
- name: initialize bare SDK clone
id: clone-g4w-sdk
shell: bash
run: |
git clone --bare --depth=1 --single-branch --branch=main --filter=blob:none \
https://github.com/git-for-windows/git-sdk-64 .tmp &&
echo "rev=$(git -C .tmp rev-parse HEAD)" >>$GITHUB_OUTPUT
- name: restore cached git-sdk-64 subset
id: restore-g4w-sdk
uses: actions/cache/restore@v3
env:
cache-name: cache-g4w-sdk
with:
path: .sdk
key: g4w-sdk-${{ steps.clone-g4w-sdk.outputs.rev }}
- name: check out git-sdk-64 subset
if: ${{ steps.restore-g4w-sdk.outputs.cache-hit != 'true' }}
shell: bash
env:
GIT_CONFIG_PARAMETERS: "'checkout.workers=56'"
run: |
git -C .tmp config extensions.worktreeConfig true &&
git -C .tmp worktree add --no-checkout --detach "$PWD/.sdk" &&
cd .sdk &&
git config --worktree core.sparseCheckout true &&
git config --worktree core.bare false &&
sparse="$(git rev-parse --git-path info/sparse-checkout)" &&
mkdir -p "${sparse%/*}" &&
git show HEAD:.sparse/minimal-sdk >"$sparse" &&
cat >>"$sparse" <<-EOF &&
/etc/makepkg.conf
/usr/bin/base64.exe
/usr/bin/gettext.exe
/usr/bin/makepkg
/usr/bin/nproc.exe
/usr/bin/pacman.exe
/usr/bin/sha256sum.exe
/usr/bin/updpkgsums
/usr/share/makepkg/
/mingw64/bin/curl.exe
EOF
git checkout -- &&

# makepkg/updpkgsums expects `curl` to be present in `/usr/bin/`
printf '#!/bin/sh\n\nexec /mingw64/bin/curl.exe "$@"' >usr/bin/curl
- name: cache git-sdk-64 subset
if: ${{ steps.restore-g4w-sdk.outputs.cache-hit != 'true' }}
uses: actions/cache/save@v3
env:
cache-name: cache-g4w-sdk
with:
path: .sdk
key: g4w-sdk-${{ steps.clone-g4w-sdk.outputs.rev }}
- name: use git-sdk-64 subset
shell: bash
run: |
cd .sdk &&

# add the SDK directories to the `PATH`
cygpath -aw "usr/bin/core_perl" >>$GITHUB_PATH &&
cygpath -aw "usr/bin" >>$GITHUB_PATH &&
cygpath -aw "mingw64/bin" >>$GITHUB_PATH &&
echo "MSYSTEM=MINGW64" >>$GITHUB_ENV
- name: Initialize Git for Windows SDK subset
uses: ./.github/actions/init-g4w-sdk-for-pacman
- name: Clone ${{ env.REPO }}
shell: bash
run: |
Expand Down
194 changes: 194 additions & 0 deletions .github/workflows/updpksums.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
name: Update the checksums of a package version in an open PR
run-name: Update checksums in git-for-windows/${{ inputs.repo }}#${{ inputs.pr-number }}

on:
workflow_dispatch:
inputs:
repo:
description: The repository containing the Pull Request
type: string
required: true
pr-number:
description: The number of the Pull Request to update
type: string
required: true
actor:
description: The GitHub user on whose behalf this workflow is run
required: false

env:
REPO: ${{ github.event.inputs.repo }}
PR_NUMBER: ${{ github.event.inputs.pr-number }}
OWNER: 'git-for-windows'
ACTOR: "${{ github.event.inputs.actor || github.triggering_actor }}"

jobs:
updpkgsums:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
# Since we want to operate on _another_ repository, we sadly cannot use:
#
# permissions:
# checks: write
#
# Therefore, we registered a GitHub App and stored the data required to
# act as that App in repository secrets `GH_APP_ID`, `GH_APP_PRIVATE_KEY`.
- name: Obtain installation token
id: setup
uses: actions/github-script@v6
with:
script: |
const appId = ${{ secrets.GH_APP_ID }}
const privateKey = `${{ secrets.GH_APP_PRIVATE_KEY }}`

const getAppInstallationId = require('./get-app-installation-id')
const installationId = await getAppInstallationId(
console,
appId,
privateKey,
process.env.OWNER,
process.env.REPO
)

const getInstallationAccessToken = require('./get-installation-access-token')
const { token: accessToken } = await getInstallationAccessToken(
console,
appId,
privateKey,
installationId
)

core.setSecret(accessToken)
core.setOutput('token', accessToken)
- name: Initialize Git for Windows SDK subset
uses: ./.github/actions/init-g4w-sdk-for-pacman
- name: Clone ${{ env.REPO }}
id: clone
shell: bash
run: |
mkdir -p /usr/src &&
git init "/usr/src/$REPO" &&
cd "/usr/src/$REPO" &&
git fetch --depth 1 "https://github.com/$OWNER/$REPO" "refs/pull/$PR_NUMBER/head" &&
git checkout FETCH_HEAD &&
echo "result=$(cygpath -aw "/usr/src/$REPO")" >>$GITHUB_OUTPUT
- name: Determine modified packages
id: determine-packages
uses: actions/github-script@v6
env:
WORKTREE_PATH: '${{ steps.clone.outputs.result }}'
with:
result-encoding: string
script: |
const githubApiRequest = require('./github-api-request')
const files = await githubApiRequest(
context,
'${{ steps.setup.outputs.token }}',
'GET',
`/repos/${process.env.OWNER}/${process.env.REPO}/pulls/${process.env.PR_NUMBER}/files`
)
const fs = require('fs')
const path = require('path')
const packages = files.map(e => path.dirname(e.filename)).reduce((a, directory) => {
if (a[0] !== directory && fs.existsSync(path.join(process.env.WORKTREE_PATH, directory, 'PKGBUILD'))) {
if (directory.indexOf(' ') >= 0) throw new Error(`${directory}: contains spaces!`)
a.unshift(directory)
}
return a
}, [])
return packages.join(' ')
- name: Identify actor
if: steps.determine-packages.outputs.result != ''
id: actor
uses: actions/github-script@v6
with:
script: |
const githubApiRequest = require('./github-api-request')
const answer = await githubApiRequest(
console,
'${{ steps.setup.outputs.token }}',
'GET',
`/users/${process.env.ACTOR}`
)
core.setOutput('login', answer.login)
core.setOutput('name', answer.name)
core.setOutput('email', answer.email || `${process.env.ACTOR}@users.noreply.github.com`)
- name: Configure build
if: steps.determine-packages.outputs.result != ''
shell: bash
run: |
USER_NAME="${{ steps.actor.outputs.name }}" &&
USER_EMAIL="${{ steps.actor.outputs.email }}" &&
mkdir -p "$HOME" &&
git config --global user.name "$USER_NAME" &&
git config --global user.email "$USER_EMAIL" &&
echo "PACKAGER=$USER_NAME <$USER_EMAIL>" >>$GITHUB_ENV
- name: Update packages
if: steps.determine-packages.outputs.result != ''
id: update
shell: bash
env:
PACKAGES: ${{ steps.determine-packages.outputs.result }}
run: |
for PACKAGE_TO_UPGRADE in $PACKAGES
do
cd "/usr/src/$REPO/$PACKAGE_TO_UPGRADE" &&
update_script="$GITHUB_WORKSPACE/update-scripts/checksums/$PACKAGE_TO_UPGRADE" &&
if test -f "$update_script"
then
PACKAGE_VERSION="$(sed -n 's/^pkgver=//p' PKGBUILD)" &&
test -n "$PACKAGE_VERSION" &&
$update_script "$PACKAGE_VERSION"
else
updpkgsums
fi &&

# give `pkgver()` a chance
if grep '^pkgver *()' PKGBUILD
then
# give makepkg a chance to update the version
git fetch --unshallow "https://github.com/$OWNER/$REPO" "refs/pull/$PR_NUMBER/head" &&
makepkg --noextract --nobuild
fi ||
exit 1
done

git update-index -q --refresh &&
if git diff-files --exit-code
then
echo "::notice::No checksums needed to be updated in $PACKAGES"
exit 0
fi &&

msg="$PACKAGES: update checksums" &&
git commit -asm "$msg" &&
echo "msg=$msg" >>$GITHUB_OUTPUT &&
echo "modified=true" >>$GITHUB_OUTPUT
- name: Determine repository to push to
# PRs frequently originate from forks; Unless contributors uncheck the box to
# allow maintainers to push to their PR branch, the GitForWindowsHelper GitHub
# App credentials are still good enough to push there, we just need to figure
# out where "there" is.
if: steps.update.outputs.modified == 'true'
id: determine-repository
uses: actions/github-script@v6
with:
script: |
const githubApiRequest = require('./github-api-request')
const pr = await githubApiRequest(
context,
'${{ steps.setup.outputs.token }}',
'GET',
`/repos/${process.env.OWNER}/${process.env.REPO}/pulls/${process.env.PR_NUMBER}`
)
core.setOutput('ref', pr.head.ref)
core.setOutput('url', pr.head.repo.clone_url)
- name: Push changes
if: steps.update.outputs.modified == 'true'
shell: bash
run: |
auth="$(printf '%s:%s' '${{ steps.actor.outputs.login }}' '${{ steps.setup.outputs.token }}' | base64)" &&
echo "::add-mask::$auth" &&
cd "/usr/src/$REPO/$PACKAGE_TO_UPGRADE" &&
git -c http.extraHeader="Authorization: Basic $auth" push --force '${{ steps.determine-repository.outputs.url }}' HEAD:refs/heads/'${{ steps.determine-repository.outputs.ref }}'