Repository navigation
ci(spm): pin generated SPM dependency to a commit SHA and auto-bump it (DEVA11Y-477) #45
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
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| #!/usr/bin/env bash | ||
| # Pins the AccessibilityDevTools dependency in the synthetic Package.swift that | ||
| # scripts/{bash,zsh,fish}/spm.sh generate to an immutable commit SHA, and | ||
| # regenerates each script's .sha256 self-update sidecar (DEVA11Y-477 / F-005). | ||
| # | ||
| # Usage: .github/scripts/update-spm-pin.sh [<40-char sha>] | ||
| # With no argument, pins to the latest first-parent commit on origin/main that | ||
| # touched the plugin itself (Package.swift or Plugins/). Commits that only touch | ||
| # scripts/ (including the pin bumps this produces) never move that SHA, so a | ||
| # merged bump cannot trigger another bump. | ||
| # | ||
| # Prints the pinned SHA. Run from the repository root. | ||
| set -euo pipefail | ||
|
|
||
| SCRIPTS=(scripts/bash/spm.sh scripts/zsh/spm.sh scripts/fish/spm.sh) | ||
| DEP_URL='https://github.com/browserstack/AccessibilityDevTools.git' | ||
|
|
||
| sha="${1:-$(git log -1 --first-parent --format=%H origin/main -- Package.swift Plugins)}" | ||
| if ! printf '%s' "$sha" | grep -Eq '^[0-9a-f]{40}$'; then | ||
| echo "error: '${sha}' is not a full 40-character commit SHA" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| sha256_of() { | ||
| if command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | awk '{print $1}' | ||
| else shasum -a 256 "$1" | awk '{print $1}'; fi | ||
| } | ||
|
|
||
| for script in "${SCRIPTS[@]}"; do | ||
| # Replace whatever requirement the dependency line has today (branch: "main" or | ||
| # a previous revision: "<sha>") with the new revision pin. | ||
| sed -E "s#(\\.package\\(url: \"${DEP_URL}\", )(branch|revision): \"[^\"]*\"\\)#\\1revision: \"${sha}\")#" \ | ||
| "$script" > "${script}.tmp" | ||
| if ! grep -Fq ".package(url: \"${DEP_URL}\", revision: \"${sha}\")" "${script}.tmp"; then | ||
| rm -f "${script}.tmp" | ||
| echo "error: dependency line not found in ${script}" >&2 | ||
| exit 1 | ||
| fi | ||
| cat "${script}.tmp" > "$script" # keep the original file mode | ||
| rm -f "${script}.tmp" | ||
| printf '%s %s\n' "$(sha256_of "$script")" "$(basename "$script")" > "${script}.sha256" | ||
| done | ||
|
|
||
| echo "$sha" |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,140 @@ | ||
| name: SPM dependency pin | ||
|
|
||
| # scripts/{bash,zsh,fish}/spm.sh generate a throwaway Package.swift that depends on | ||
| # this repository. It used to track `branch: "main"`, so every scan resolved | ||
| # whatever HEAD of main was at that moment (DEVA11Y-477 / F-005, CWE-829). It is | ||
| # now pinned to an immutable `revision:` SHA, and this workflow keeps that pin | ||
| # current without going back to a mutable ref: | ||
| # | ||
| # bump — when plugin code (Package.swift / Plugins/) lands on main, runs | ||
| # .github/scripts/update-spm-pin.sh and opens (or refreshes) a PR moving | ||
| # the pin to that commit. The bump goes through review like any other | ||
| # change, so a bad commit on main does not reach users automatically. | ||
| # Bump PRs only touch scripts/, so merging one never moves the pin again. | ||
| # guard — on PRs touching scripts/, fails if any spm.sh stops pinning to a full | ||
| # 40-char revision (e.g. a revert back to `branch: "main"`). | ||
| # | ||
| # PRs opened with the default GITHUB_TOKEN do not trigger other workflows, so the | ||
| # required checks will not start on them on their own. Set a PIN_BUMP_TOKEN secret | ||
| # (GitHub App installation token or fine-grained PAT with contents + pull-requests | ||
| # write) to have them run; without it, close/reopen the bump PR to start checks. | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| paths: | ||
| - 'Package.swift' | ||
| - 'Plugins/**' | ||
| pull_request: | ||
| paths: | ||
| - 'scripts/**' | ||
| - '.github/scripts/update-spm-pin.sh' | ||
| - '.github/workflows/spm-pin-bump.yml' | ||
| schedule: | ||
| - cron: '0 6 * * 1' # weekly safety net in case a push run was missed | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| bump: | ||
| name: Open PR bumping the SPM pin | ||
| if: github.event_name != 'pull_request' | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 5 | ||
| permissions: | ||
| contents: write | ||
| pull-requests: write | ||
| concurrency: | ||
| group: spm-pin-bump | ||
| cancel-in-progress: false | ||
| env: | ||
| BUMP_BRANCH: ci/spm-pin-bump | ||
| GH_TOKEN: ${{ secrets.PIN_BUMP_TOKEN || github.token }} | ||
| steps: | ||
| - name: Checkout main (full history to find the latest plugin commit) | ||
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||
| with: | ||
| ref: main | ||
| fetch-depth: 0 | ||
| token: ${{ secrets.PIN_BUMP_TOKEN || github.token }} | ||
|
|
||
| - name: Update pin in spm.sh scripts and sidecars | ||
| id: pin | ||
| run: | | ||
| set -euo pipefail | ||
| old=$(grep -oE 'AccessibilityDevTools\.git", revision: "[0-9a-f]{40}"' scripts/bash/spm.sh \ | ||
| | grep -oE '[0-9a-f]{40}' || true) | ||
| new=$(.github/scripts/update-spm-pin.sh) | ||
| echo "old=${old}" >> "$GITHUB_OUTPUT" | ||
| echo "new=${new}" >> "$GITHUB_OUTPUT" | ||
| if git diff --quiet; then | ||
| echo "Pin already at ${new}; nothing to do." | ||
| echo "changed=false" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "changed=true" >> "$GITHUB_OUTPUT" | ||
| fi | ||
|
|
||
| - name: Push bump branch and open/update PR | ||
| if: steps.pin.outputs.changed == 'true' | ||
| env: | ||
| OLD: ${{ steps.pin.outputs.old }} | ||
| NEW: ${{ steps.pin.outputs.new }} | ||
| run: | | ||
| set -euo pipefail | ||
| short="${NEW:0:12}" | ||
| git config user.name 'github-actions[bot]' | ||
| git config user.email '41898282+github-actions[bot]@users.noreply.github.com' | ||
| git switch -C "$BUMP_BRANCH" | ||
| git commit -qam "chore(spm): pin AccessibilityDevTools dependency to ${short} (DEVA11Y-477)" | ||
| # The bump branch is bot-owned and always rebuilt from main. | ||
| git push --force origin "HEAD:refs/heads/${BUMP_BRANCH}" | ||
|
|
||
| { | ||
| echo "Moves the \`revision:\` pin in the Package.swift generated by \`scripts/{bash,zsh,fish}/spm.sh\` to \`${NEW}\`, the latest commit on \`main\` that changed the plugin, and regenerates the \`.sha256\` self-update sidecars." | ||
| echo | ||
| if [ -n "$OLD" ]; then | ||
| echo "Plugin changes since the previous pin \`${OLD:0:12}\`:" | ||
| echo | ||
| echo '```' | ||
| git log --first-parent --format='%h %s' "${OLD}..${NEW}" -- Package.swift Plugins | ||
| echo '```' | ||
| echo | ||
| fi | ||
| echo "Review those changes before merging: once merged, every \`spm.sh\` scan resolves the plugin at this commit." | ||
| echo | ||
| echo "Opened automatically by \`.github/workflows/spm-pin-bump.yml\` (DEVA11Y-477)." | ||
| } > "$RUNNER_TEMP/pr-body.md" | ||
|
|
||
| pr=$(gh pr list --head "$BUMP_BRANCH" --base main --state open --json number --jq '.[0].number // empty') | ||
| if [ -n "$pr" ]; then | ||
| gh pr edit "$pr" --title "chore(spm): pin AccessibilityDevTools dependency to ${short}" --body-file "$RUNNER_TEMP/pr-body.md" | ||
| echo "Updated PR #${pr}" | ||
| else | ||
| gh pr create --base main --head "$BUMP_BRANCH" \ | ||
| --title "chore(spm): pin AccessibilityDevTools dependency to ${short}" \ | ||
| --body-file "$RUNNER_TEMP/pr-body.md" | ||
| fi | ||
|
|
||
| guard: | ||
| name: spm.sh pins a full commit SHA | ||
| if: github.event_name == 'pull_request' | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 5 | ||
| steps: | ||
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||
|
|
||
| - name: Require revision pin in every spm.sh | ||
| run: | | ||
| set -uo pipefail | ||
| status=0 | ||
| for script in scripts/bash/spm.sh scripts/zsh/spm.sh scripts/fish/spm.sh; do | ||
| if grep -Eq '\.package\(url: "https://github\.com/browserstack/AccessibilityDevTools\.git", revision: "[0-9a-f]{40}"\)' "$script"; then | ||
| echo "OK $script" | ||
| else | ||
| echo "FAILED $script must pin AccessibilityDevTools with revision: \"<40-char sha>\" (DEVA11Y-477); run .github/scripts/update-spm-pin.sh" | ||
| status=1 | ||
| fi | ||
| done | ||
| exit "$status" | ||
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| b520c458bec538505c9ff9ca75a02ec901597fd66b3c2d951b928e58e58e60da spm.sh | ||
| 6ec53f99f4976f5769c094e015fa99a9eb92cac406a7379fb1c0ef8d166bdf88 spm.sh |
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| 982bbb10bb9bd55428208454a766384fae58c41dacabb1e5b8a74d2366f0d1e7 spm.sh | ||
| 07afdbe6582a562721f297eb5773cb5dd21b78e3ecb5de9f806ed07201aeafa3 spm.sh |
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| 1f28d5b3025636d9b81299032f34886f8804b1c6c95b830204325b325bd1d84f spm.sh | ||
| e2e9c9104892cbcca63edd3664783b058272d396efa03028a0083ae3789de90e spm.sh |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.