Repository navigation
ci(actions): relock actions.lock remotely with gh-actions-lock #41
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
Show all changes
4 commits
Select commit
Hold shift + click to select a range
6a91826
ci(actions): relock actions.lock remotely with gh-actions-lock
claude 1a623fb
ci(actions): onboard every uses-free workflow; one AUTOMATION_TOKEN
claude 37bf88e
ci(estate-audit): port #44, call cicd-suite's reusable audit
claude 6ae9736
ci(estate-audit): pin cicd-suite#50 head afa28ff; bot keeps others' c…
claude 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,116 @@ | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
| name: Actions lock | ||
|
|
||
| # Keeps .github/workflows/actions.lock in step with the workflows, remotely. | ||
| # | ||
| # Why this exists. A workflow listed in actions.lock runs only the commits the | ||
| # lock records. When a `uses:` ref changes and the lock does not, that workflow | ||
| # ends in startup_failure with no check run at all. Dependabot bumps `uses:` | ||
| # refs but does not yet rewrite the lock (dependabot-core gates that behind its | ||
| # `github_actions_lockfile` experiment), so every Actions bump broke CI here: | ||
| # #34 moved lean-action to v1.6.1 and codeql-action to v4.38.2 while the lock | ||
| # still named v1.6.0 / v4.38.0. Branch pins also go stale: the lock held | ||
| # cicd-suite@main at 5a10b72, before cicd-suite #32 fixed the gate that fails | ||
| # estate-audit on this repo. | ||
| # | ||
| # What it does. Runs the official extension (github/gh-actions-lock, pinned | ||
| # below) with --relock, which records new refs and advances branch pins to | ||
| # upstream HEAD, then opens a PR that changes ONLY actions.lock. A run that | ||
| # wants to touch any workflow file is refused (same assert as #25). | ||
| # | ||
| # When. On every push to main that changes a workflow (so a merged Dependabot | ||
| # bump is relocked within minutes), weekly (so branch pins track latest), and | ||
| # on demand. | ||
| # | ||
| # ⚠ NO `uses:` ANYWHERE, DELIBERATELY (see labels.yml): this workflow must run | ||
| # precisely when the lock is stale, so it depends on no action. | ||
| # | ||
| # Token. Falls back to GITHUB_TOKEN. Add a repository secret | ||
| # AUTOMATION_TOKEN (fine-grained: Contents, Issues, Pull requests and Workflows | ||
| # read/write on this repo) if GitHub refuses a GITHUB_TOKEN write under | ||
| # .github/workflows/, and so that CI runs on the PR it opens (PRs opened with | ||
| # GITHUB_TOKEN do not trigger workflows). The track-*.yml workflows share it. | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| paths: | ||
| - '.github/workflows/*.yml' | ||
| - '.github/workflows/*.yaml' | ||
| schedule: | ||
| - cron: "41 6 * * 1" # weekly, after Dependabot's Monday run | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: actions-lock | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| relock: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: write | ||
| pull-requests: write | ||
| env: | ||
| GH_ACTIONS_LOCK_VERSION: v0.2.0 | ||
| GH_TOKEN: ${{ secrets.AUTOMATION_TOKEN || secrets.GITHUB_TOKEN }} | ||
| BASE: main | ||
| BRANCH: ci/relock-actions | ||
| steps: | ||
| - name: Relock and open a lockfile-only PR | ||
| run: | | ||
| set -euo pipefail | ||
| gh extension install github/gh-actions-lock --pin "$GH_ACTIONS_LOCK_VERSION" | ||
| gh auth setup-git | ||
| gh repo clone "$GITHUB_REPOSITORY" repo -- --quiet --depth 1 --branch "$BASE" | ||
| cd repo | ||
|
|
||
| # Scope: the workflows the lock already tracks, plus every workflow | ||
| # with no `uses:` (recorded as [], nothing to rewrite). An untracked | ||
| # workflow WITH refs, e.g. the estate's canonical secret-scanner | ||
| # caller, is left alone: onboarding it may rewrite its SHA ref, so | ||
| # that stays a reviewed, manual step. A scoped run never prunes | ||
| # out-of-scope entries. | ||
| mapfile -t scope < <( | ||
| { sed -n "/^workflows:/,/^dependencies:/s/^ '\(\.github\/workflows\/[^']*\)':.*$/\1/p" \ | ||
| .github/workflows/actions.lock | ||
| for f in .github/workflows/*.yml .github/workflows/*.yaml; do | ||
| [ -f "$f" ] && ! grep -qE '^[[:space:]]*(-[[:space:]]+)?uses:' "$f" && echo "$f" | ||
| done | ||
| } | sort -u | while read -r p; do [ -f "$p" ] && echo "$p"; done) | ||
| printf 'relocking: %s\n' "${scope[@]}" | ||
|
|
||
| gh actions-lock --relock --no-narrow --no-migrate-local-actions --no-interactive "${scope[@]}" | ||
|
|
||
| changed=$(git status --porcelain | awk '{print $2}') | ||
| if [ -z "$changed" ]; then | ||
| echo "actions.lock is current; nothing to do." | ||
| exit 0 | ||
| fi | ||
| if [ "$changed" != ".github/workflows/actions.lock" ]; then | ||
| echo "::error::The relock wanted to change more than actions.lock. Refusing; handle by hand:" | ||
| git status --porcelain | ||
| exit 1 | ||
| fi | ||
| git --no-pager diff --stat | ||
|
|
||
| git switch --quiet -c "$BRANCH" | ||
| git -c user.name='github-actions[bot]' \ | ||
| -c user.email='41898583+github-actions[bot]@users.noreply.github.com' \ | ||
| commit --quiet -am "chore(actions): relock actions.lock" \ | ||
| -m "Regenerated by .github/workflows/actions-lock.yml with github/gh-actions-lock $GH_ACTIONS_LOCK_VERSION (--relock --no-narrow --no-migrate-local-actions). Only actions.lock changes; every workflow file is byte-identical." | ||
| if ! git push --quiet --force origin "$BRANCH"; then | ||
| echo "::error::Push refused. If GitHub rejected a GITHUB_TOKEN write under .github/workflows/, add the AUTOMATION_TOKEN secret described at the top of this workflow." | ||
| exit 1 | ||
| fi | ||
|
|
||
| body="Regenerated by \`actions-lock.yml\` (run $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID) with \`github/gh-actions-lock $GH_ACTIONS_LOCK_VERSION --relock\`. Only \`.github/workflows/actions.lock\` changes." | ||
| if [ -n "$(gh pr list --head "$BRANCH" --state open --json number --jq '.[].number')" ]; then | ||
| echo "Updated the open relock PR." | ||
| else | ||
| gh pr create --base "$BASE" --head "$BRANCH" \ | ||
| --title "chore(actions): relock actions.lock" --body "$body" | ||
| fi | ||
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,95 +1,31 @@ | ||
| # This workflow is managed by gh actions-lock. | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
| # This workflow is managed by gh actions-lock. | ||
|
|
||
| name: Central Estate CI/CD Audit | ||
|
|
||
| # Thin caller of the estate audit, which lives in hyperpolymath/cicd-suite as | ||
| # a reusable workflow and reports five component checks: governance, | ||
| # hygiene, manifests, languages, advisory. Do not copy the audit's steps in | ||
| # here. A copy freezes this repository at whatever cicd-suite commit its | ||
| # actions.lock happened to hold, and fixes made upstream never arrive. | ||
| # | ||
| # The pin is a full SHA, advanced weekly by track-estate-audit.yml (a PR | ||
| # whose own run of this audit is the check). | ||
| # | ||
| # ⚠ DE-ONBOARDED from actions.lock, deliberately, like the secret-scanner | ||
| # caller. A reusable workflow onboarded cross-repo startup-fails with zero | ||
| # jobs under sha_pinning_required (see the header of cicd-suite's | ||
| # main-estate-audit.yml). Do not run a full-directory `gh actions-lock` that | ||
| # re-onboards this file. If one does, cicd-suite/scripts/deonboard-estate-audit.sh | ||
| # reverses it. | ||
|
|
||
| on: | ||
| push: | ||
| branches: [ "main" ] | ||
| pull_request: | ||
| branches: [ "main" ] | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| estate-audit: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v7.0.1 | ||
|
|
||
| - name: Required Files Gate | ||
| uses: hyperpolymath/cicd-suite/actions/required-files-check@main | ||
|
|
||
| - name: Code Hygiene Gate | ||
| uses: hyperpolymath/cicd-suite/actions/code-hygiene-check@main | ||
|
|
||
| - name: Manifest Validation Gate | ||
| uses: hyperpolymath/cicd-suite/actions/manifest-check@main | ||
|
|
||
| - name: Idris2 ABI Purity Gate | ||
| uses: hyperpolymath/cicd-suite/actions/idris2-abi-check@main | ||
|
|
||
| - name: Zig UnifiedApiAdapter API Gate | ||
| uses: hyperpolymath/cicd-suite/actions/zig-unified-api-adapter-check@main | ||
|
|
||
| - name: Contractile Validation Gate | ||
| uses: hyperpolymath/cicd-suite/actions/contractile-validation-check@main | ||
|
|
||
| - name: Recipes Set Validation Gate | ||
| uses: hyperpolymath/cicd-suite/actions/recipes-set-check@main | ||
|
|
||
| - name: Affirmation Document Gate | ||
| uses: hyperpolymath/cicd-suite/actions/affirmation-check@main | ||
|
|
||
| - name: Academic Referencing Gate | ||
| uses: hyperpolymath/cicd-suite/actions/referencing-check@main | ||
|
|
||
| - name: Semantic Audit Gate | ||
| uses: hyperpolymath/cicd-suite/actions/semantic-audit-check@main | ||
|
|
||
| - name: SPDX License Gate | ||
| uses: hyperpolymath/cicd-suite/actions/spdx-license-check@main | ||
|
|
||
| - name: Proof Runner Gate | ||
| uses: hyperpolymath/cicd-suite/actions/proof-runner-check@main | ||
|
|
||
| - name: PRAT Testing Gate | ||
| uses: hyperpolymath/cicd-suite/actions/prat-check@main | ||
|
|
||
| - name: Panic Attack & Pons Gate | ||
| uses: hyperpolymath/cicd-suite/actions/custom-tools-check@main | ||
|
|
||
| - name: WWW & Well-Known Compliance Gate | ||
| uses: hyperpolymath/cicd-suite/actions/www-compliance-check@main | ||
|
|
||
| - name: BoJ Cartridge Validation Gate | ||
| uses: hyperpolymath/cicd-suite/actions/boj-cartridge-check@main | ||
|
|
||
| - name: Formatting Validation Gate | ||
| uses: hyperpolymath/cicd-suite/actions/formatting-check@main | ||
|
|
||
| - name: Accreditations & Badges Gate | ||
| uses: hyperpolymath/cicd-suite/actions/badges-check@main | ||
|
|
||
| - name: Metrics Extraction Gate | ||
| uses: hyperpolymath/cicd-suite/actions/metrics-check@main | ||
|
|
||
| - name: Linguist & Banned Languages Gate | ||
| uses: hyperpolymath/cicd-suite/actions/linguist-check@main | ||
|
|
||
| - name: Test & Benchmarks Dashboard Gate | ||
| uses: hyperpolymath/cicd-suite/actions/tests-benches-check@main | ||
|
|
||
| - name: Hosting & Site Status Gate | ||
| uses: hyperpolymath/cicd-suite/actions/hosting-check@main | ||
|
|
||
| - name: Git-Sea Analytics Gate | ||
| uses: hyperpolymath/cicd-suite/actions/gitsea-check@main | ||
|
|
||
| - name: Trust & Humans Validation Gate | ||
| uses: hyperpolymath/cicd-suite/actions/trust-humans-check@main | ||
|
|
||
| - name: Are We UnAPI Gate (Secret Scanning) | ||
| uses: hyperpolymath/cicd-suite/actions/secrets-check@main | ||
|
|
||
| - name: Reasonably Good Token Validation Gate | ||
| uses: hyperpolymath/cicd-suite/actions/vaulted-tokens-check@main | ||
| estate: | ||
| uses: hyperpolymath/cicd-suite/.github/workflows/main-estate-audit.yml@afa28ff81dc89ae7bd2304eead22917ec1733904 # cicd-suite#50 head; re-pin to its merge commit |
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,90 @@ | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
| name: Track latest estate audit | ||
|
|
||
| # Weekly: is the cicd-suite estate audit this repository calls behind | ||
| # cicd-suite's main? If so, open a PR that moves the pin in | ||
| # main-estate-audit.yml to cicd-suite HEAD. The PR's own estate-audit run is | ||
| # the check: merge it when the five components are green. Nothing reaches | ||
| # main unreviewed. | ||
| # | ||
| # ⚠ NO `uses:` ANYWHERE, DELIBERATELY: actions.lock is keyed by workflow path, | ||
| # and this must run even when the lock is stale. | ||
| # | ||
| # Token: AUTOMATION_TOKEN, a fine-grained token on this repository with | ||
| # Contents, Pull requests and Workflows set to read/write. In practice it is | ||
| # required: the bump edits a file under .github/workflows/, which | ||
| # GITHUB_TOKEN may not write, and a PR opened by GITHUB_TOKEN does not trigger | ||
| # the estate-audit run that validates it. | ||
|
|
||
| on: | ||
| schedule: | ||
| - cron: "23 7 * * 1" # weekly, Monday | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: track-estate-audit | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| bump: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: write | ||
| pull-requests: write | ||
| env: | ||
| GH_TOKEN: ${{ secrets.AUTOMATION_TOKEN || secrets.GITHUB_TOKEN }} | ||
| BRANCH: ci/track-estate-audit | ||
| CALLER: .github/workflows/main-estate-audit.yml | ||
| BOT_EMAIL: 41898583+github-actions[bot]@users.noreply.github.com | ||
| steps: | ||
| - name: Move the cicd-suite pin to HEAD and open a PR | ||
| run: | | ||
| set -euo pipefail | ||
| gh auth setup-git | ||
| base=$(gh repo view "$GITHUB_REPOSITORY" --json defaultBranchRef --jq .defaultBranchRef.name) | ||
| gh repo clone "$GITHUB_REPOSITORY" repo -- --quiet --depth 1 --branch "$base" | ||
| cd repo | ||
|
|
||
| pinned=$(grep -oE 'cicd-suite/\.github/workflows/main-estate-audit\.yml@[0-9a-f]{40}' "$CALLER" \ | ||
| | sed 's/.*@//' | head -n 1 || true) | ||
| if [ -z "$pinned" ]; then | ||
| echo "::error::$CALLER does not call cicd-suite's reusable estate audit at a full SHA." | ||
| exit 1 | ||
| fi | ||
| head=$(git ls-remote https://github.com/hyperpolymath/cicd-suite.git HEAD | cut -f1) | ||
| echo "pinned ${pinned:0:7}, cicd-suite HEAD ${head:0:7}" | ||
| if [ "$pinned" = "$head" ]; then | ||
| echo "Already at cicd-suite HEAD." | ||
| exit 0 | ||
| fi | ||
|
|
||
| # The bot branch is rebuilt from the default branch each run, which | ||
| # would discard anything else on it. If someone has pushed to it | ||
| # (say, a fix the newer audit needed), leave it for review. | ||
| if git ls-remote --exit-code --heads origin "$BRANCH" >/dev/null; then | ||
| foreign=$(gh api "repos/$GITHUB_REPOSITORY/compare/$base...$BRANCH" \ | ||
| --jq "[.commits[] | select(.commit.author.email != \"$BOT_EMAIL\")] | length") | ||
| if [ "$foreign" != 0 ]; then | ||
| echo "::warning::$BRANCH carries $foreign commit(s) not made by this workflow; leaving it alone. Merge its PR or delete the branch, then re-run." | ||
| exit 0 | ||
| fi | ||
| fi | ||
|
|
||
| sed -i "s/$pinned/$head/g" "$CALLER" | ||
| git switch --quiet -c "$BRANCH" | ||
| git -c user.name='github-actions[bot]' -c user.email="$BOT_EMAIL" \ | ||
| commit --quiet -am "ci(estate-audit): track cicd-suite ${head:0:7}" | ||
| if ! git push --quiet --force origin "$BRANCH"; then | ||
| echo "::error::Push refused: writing under .github/workflows/ needs the AUTOMATION_TOKEN secret described above." | ||
| exit 1 | ||
| fi | ||
| body="Moves the estate audit to cicd-suite \`${head:0:7}\` (was \`${pinned:0:7}\`): https://github.com/hyperpolymath/cicd-suite/compare/$pinned...$head. This PR's estate-audit run is the check. Opened by \`track-estate-audit.yml\`." | ||
| if [ -n "$(gh pr list --head "$BRANCH" --state open --json number --jq '.[].number')" ]; then | ||
| gh pr edit "$BRANCH" --title "ci(estate-audit): track cicd-suite ${head:0:7}" --body "$body" | ||
| else | ||
| gh pr create --base "$base" --head "$BRANCH" \ | ||
| --title "ci(estate-audit): track cicd-suite ${head:0:7}" --body "$body" | ||
| fi |
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
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.