From 3b7f05b989ae6d90ed435efd786cb68a2e3b5ce4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 29 Aug 2026 04:12:54 +0000 Subject: [PATCH] chore: promote testing to main --- .github/requirements-ci.txt | 1 + .github/workflows/bonedigger.yml | 11 +- .github/workflows/lab-check.yml | 8 +- .github/workflows/pr-validation.yml | 10 +- .github/workflows/promote-testing-to-main.yml | 38 ++- .github/workflows/renovate-automerge.yml | 3 + .github/workflows/scorecard.yml | 2 +- build_files/base/20-tests.sh | 7 + docs/skills/ci/SKILL.md | 28 +- docs/skills/ci/references/failure-modes.md | 302 ++++++++++++++++++ .../ci/references/mergeraptor-checks.md | 62 +++- docs/skills/dependency-automation/SKILL.md | 10 +- docs/skills/issue-lifecycle/SKILL.md | 11 + docs/skills/release-artifacts/SKILL.md | 12 + docs/workflow.md | 5 +- image-versions.yml | 4 +- scripts/check-renovate-automerge-auth.py | 49 +++ .../extensions/blur-my-shell@aunetx | 2 +- ...adia-integration@alexandervanhee.github.io | 2 +- .../12-framework-amd-kargs-cleanup.sh | 50 +++ .../user-setup.hooks.d/20-framework.sh | 46 --- tests/test_lab_check.py | 195 +++++++++++ tests/test_renovate_automerge_auth.py | 36 +++ .../12-framework-amd-kargs-cleanup_test.bats | 147 +++++++++ tests/unit/20-framework_test.bats | 91 ------ tests/unit/20-tests_test.bats | 44 ++- 26 files changed, 1006 insertions(+), 170 deletions(-) create mode 100644 scripts/check-renovate-automerge-auth.py create mode 100644 system_files/shared/usr/share/ublue-os/privileged-setup.hooks.d/12-framework-amd-kargs-cleanup.sh delete mode 100644 system_files/shared/usr/share/ublue-os/user-setup.hooks.d/20-framework.sh create mode 100644 tests/test_lab_check.py create mode 100644 tests/test_renovate_automerge_auth.py create mode 100644 tests/unit/12-framework-amd-kargs-cleanup_test.bats delete mode 100644 tests/unit/20-framework_test.bats diff --git a/.github/requirements-ci.txt b/.github/requirements-ci.txt index 237054009..6ee7200b6 100644 --- a/.github/requirements-ci.txt +++ b/.github/requirements-ci.txt @@ -1 +1,2 @@ pre-commit==4.6.2 +PyYAML==6.0.3 diff --git a/.github/workflows/bonedigger.yml b/.github/workflows/bonedigger.yml index 726c8af13..65254246c 100644 --- a/.github/workflows/bonedigger.yml +++ b/.github/workflows/bonedigger.yml @@ -1,14 +1,21 @@ name: issue lifecycle +# Triggers are deliberately narrower than they look like they could be. The +# pinned bonedigger lifecycle has exactly two jobs, `issues.opened` and +# `issue_comment.created`, so subscribing to any other activity type dispatches +# the reusable workflow only to skip every job in it (bluefin#981). Widen this +# only alongside a bonedigger release that actually handles the new type. on: issues: - types: [opened, labeled, closed] + types: [opened] issue_comment: types: [created] +# Scoped to what the callee declares (issues: write, contents: read). It reads +# `event.issue.pull_request` straight from the payload and never calls the pulls +# API, so no pull-requests scope is needed. permissions: issues: write - pull-requests: write contents: read jobs: diff --git a/.github/workflows/lab-check.yml b/.github/workflows/lab-check.yml index 885174c24..bd6e8b012 100644 --- a/.github/workflows/lab-check.yml +++ b/.github/workflows/lab-check.yml @@ -33,7 +33,7 @@ jobs: - name: Fail with actionable message if token minting was denied if: steps.app-token.outcome == 'failure' || steps.app-token.outputs.token == '' run: | - echo "::error::MergeRaptor token mint failed — the GitHub App installation almost certainly lacks the requested 'checks: write' permission. This cannot be fixed from the repository; an org owner must grant it (Organization settings → GitHub Apps → MergeRaptor → Permissions). Verify current grants with: gh api orgs/projectbluefin/installations --jq '.installations[] | select(.app_slug == \"mergeraptor\") | .permissions' — see docs/skills/ci/references/mergeraptor-checks.md." + echo "::error::MergeRaptor token mint failed — the app lacks the requested 'checks: write' permission. This cannot be fixed from the repository; an org owner must grant it in the GitHub UI, and it may take TWO steps. Step 1, only if 'checks' is absent from 'gh api /apps/mergeraptor --jq .permissions': Organization settings → Developer settings → GitHub Apps → MergeRaptor → Permissions & events → Repository permissions → Checks: Read and write → Save. Until that is done the installation page has nothing to approve. Step 2: approve the resulting request under Organization settings → GitHub Apps → MergeRaptor → Review request. Verify with: gh api orgs/projectbluefin/installations --jq '.installations[] | select(.app_slug == \"mergeraptor\") | .permissions' — see docs/skills/ci/references/mergeraptor-checks.md." exit 1 - name: Create or update lab check @@ -82,9 +82,15 @@ jobs: STARTED_AT=$(jq -r '.started_at // empty' <<<"${CHECK_JSON}") COMPLETED_AT=$(jq -r '.completed_at // empty' <<<"${CHECK_JSON}") + # check_name filters server-side. Without it the first page is 100 + # check runs of every name, newest first, so on a busy commit the + # existing lab check falls off the page and this lookup returns + # nothing -- which silently turns every update into a duplicate + # check run (bluefin#939). CHECK_ID=$( gh api --method GET \ "repos/${GITHUB_REPOSITORY}/commits/${SHA}/check-runs" \ + -f check_name="${CHECK_NAME}" \ -f per_page=100 \ --jq '.check_runs | map(select(.name == "'"${CHECK_NAME}"'" and .app.slug == "'"${APP_SLUG}"'")) diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index a42e488f5..c82299e2b 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -50,6 +50,9 @@ jobs: - name: Check testsuite workflow contract run: python3 scripts/check-testsuite-workflow-ref.py + - name: Check Renovate auto-merge authentication contract + run: python3 scripts/check-renovate-automerge-auth.py + - name: Check for undeclared gitlinks shell: bash env: @@ -192,7 +195,12 @@ jobs: run: | set -euo pipefail # Minimum line coverage threshold (raise this as coverage improves). - THRESHOLD=30 + # Measured BATS line coverage has held steady at 53.8-54.4% across + # recent pr-validation runs (e.g. runs 31344003528, 31345539779, + # 31715546591, 31742984919). 45% keeps a buffer against normal + # run-to-run variance while still catching real regressions; see + # https://github.com/projectbluefin/bluefin/issues/518. + THRESHOLD=45 COBERTURA="coverage/kcov/cobertura.xml" if [[ ! -f "${COBERTURA}" ]]; then echo "warning: ${COBERTURA} not found; skipping threshold check" >&2 diff --git a/.github/workflows/promote-testing-to-main.yml b/.github/workflows/promote-testing-to-main.yml index 16dffde0a..23f9da624 100644 --- a/.github/workflows/promote-testing-to-main.yml +++ b/.github/workflows/promote-testing-to-main.yml @@ -21,7 +21,43 @@ permissions: statuses: write jobs: + release_window: + name: Check stable release window + runs-on: ubuntu-latest + timeout-minutes: 5 + outputs: + should_enqueue: ${{ steps.window.outputs.should_enqueue }} + steps: + - name: Determine whether to enqueue the promotion + id: window + env: + EVENT_NAME: ${{ github.event_name }} + run: | + set -euo pipefail + + case "$EVENT_NAME" in + workflow_dispatch) + echo "Manual dispatch — allowing the hotfix release escape hatch." + echo "should_enqueue=true" >> "$GITHUB_OUTPUT" + ;; + schedule) + weekday=$(date -u +%u) + if [[ "$weekday" == "2" ]]; then + echo "Tuesday UTC schedule — allowing the weekly stable release." + echo "should_enqueue=true" >> "$GITHUB_OUTPUT" + else + echo "Non-Tuesday schedule — refreshing promotion gates without enqueueing." + echo "should_enqueue=false" >> "$GITHUB_OUTPUT" + fi + ;; + *) + echo "Push trigger — refreshing the promotion PR without enqueueing." + echo "should_enqueue=false" >> "$GITHUB_OUTPUT" + ;; + esac + promote: + needs: [release_window] uses: projectbluefin/actions/.github/workflows/reusable-promote-squash.yml@v1 with: variants: >- @@ -31,5 +67,5 @@ jobs: run_e2e: false # main uses a merge queue ruleset (17070404): gh pr merge --auto is blocked. # use_merge_queue: true calls enqueuePullRequest GraphQL instead. - use_merge_queue: true + use_merge_queue: ${{ needs.release_window.outputs.should_enqueue == 'true' }} secrets: inherit diff --git a/.github/workflows/renovate-automerge.yml b/.github/workflows/renovate-automerge.yml index ebc9bd5dd..c12101041 100644 --- a/.github/workflows/renovate-automerge.yml +++ b/.github/workflows/renovate-automerge.yml @@ -15,3 +15,6 @@ jobs: uses: projectbluefin/actions/.github/workflows/reusable-renovate-automerge.yml@v1 with: head_sha: ${{ github.event.workflow_run.head_sha }} + secrets: + app_id: ${{ secrets.MERGERAPTOR_APP_ID }} + private_key: ${{ secrets.MERGERAPTOR_PRIVATE_KEY }} diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index dfb769e55..eea607b06 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -70,6 +70,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4 + uses: github/codeql-action/upload-sarif@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4 with: sarif_file: results.sarif diff --git a/build_files/base/20-tests.sh b/build_files/base/20-tests.sh index bd56824d3..a36960379 100755 --- a/build_files/base/20-tests.sh +++ b/build_files/base/20-tests.sh @@ -35,6 +35,13 @@ test -f /usr/share/ublue-os/homebrew/fonts.Brewfile test -f /usr/share/ublue-os/homebrew/preinstall.d/bluefinctl.Brewfile test -f /usr/share/ublue-os/homebrew/preinstall.d/system-cli.Brewfile test -x /usr/bin/brew-preinstall +# ExecStart names /usr/bin/brew-preinstall, but that is a two-line trampoline +# (`exec /usr/libexec/brew-preinstall`). Asserting only the trampoline still +# passes when the payload it exec's is renamed or dropped upstream -- the unit +# then fails at first login with status 127 and bluefinctl silently never +# installs, which is exactly the symptom reported in #965. Assert the file that +# actually does the work, not just the one systemd calls. +test -x /usr/libexec/brew-preinstall test -f /usr/lib/systemd/user/brew-preinstall.service grep -q '^enable brew-preinstall\.service$' /usr/lib/systemd/user-preset/01-brew-preinstall.preset diff --git a/docs/skills/ci/SKILL.md b/docs/skills/ci/SKILL.md index 55d150d0c..ddf05f7ae 100644 --- a/docs/skills/ci/SKILL.md +++ b/docs/skills/ci/SKILL.md @@ -47,22 +47,24 @@ gh run view RUN_ID --repo projectbluefin/bluefin --log-failed gh run rerun RUN_ID --repo projectbluefin/bluefin --failed-only ``` -Read the actual workflow before describing or changing its behavior. Shared -logic belongs in the reusable workflow that owns it; callers should stay thin. +Read the actual workflow before changing its behavior. Shared logic belongs in +the reusable workflow that owns it; callers should stay thin. The `unit-tests` job in `pr-validation.yml` runs BATS with kcov and publishes `bats-tap-results` plus `bats-kcov-report` artifacts for shell-test visibility. Coverage runs route child `bash