diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 94545d4ccd..12caad8637 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -157,7 +157,9 @@ it locally (`PULSE_REHEARSAL_ENGINE=podman` on hosts without Docker). would work, without building or publishing anything. It runs every Monday at 06:23 UTC and on manual dispatch from `main`. The schedule replaces the nightly release rehearsal that dispatched it until that rehearsal was switched off with -the release steward on 4 October 2026. On a `macos-15` runner it imports +the release steward on 4 October 2026. A failed scheduled run opens an issue +titled "Release signing preflight is failing", or comments on the open one, and +the next passing scheduled run closes it. On a `macos-15` runner it imports the Developer ID certificate into a throwaway keychain, requires the configured identity to be valid for code signing and at least 30 days from expiry, signs and verifies a probe binary with a secure timestamp, and reads the Apple notary diff --git a/.github/workflows/release-signing-preflight.yml b/.github/workflows/release-signing-preflight.yml index 5c818c9f7d..f05fdd92f7 100644 --- a/.github/workflows/release-signing-preflight.yml +++ b/.github/workflows/release-signing-preflight.yml @@ -166,3 +166,52 @@ jobs: exit 1 fi echo "Release signing credentials are ready." + + # Scheduled runs have no caller watching them, and GitHub only emails + # whoever last edited the cron line. Keep one open issue while the weekly + # check fails and close it when the check passes again. + report-scheduled-result: + name: Report scheduled result + needs: apple-signing-preflight + if: ${{ always() && github.event_name == 'schedule' }} + runs-on: ubuntu-24.04 + timeout-minutes: 5 + permissions: + issues: write + steps: + - name: Open, update or close the signing preflight issue + shell: bash + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + RESULT: ${{ needs.apple-signing-preflight.result }} + RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + run: | + set -euo pipefail + title="Release signing preflight is failing" + # Search by title on the server, then keep only an exact match, so + # the alert is found however many newer issues are open. + number="$(gh issue list --state open --search "\"${title}\" in:title" \ + --limit 100 --json number,title \ + --jq "map(select(.title == \"${title}\")) | first | .number // empty")" + case "${RESULT}" in + success) + if [[ -n "${number}" ]]; then + gh issue close "${number}" --comment "The weekly signing preflight passed again: ${RUN_URL}" + fi + ;; + failure) + if [[ -n "${number}" ]]; then + gh issue comment "${number}" --body "It failed again: ${RUN_URL}" + else + gh issue create --title "${title}" --body "The weekly release signing preflight failed: ${RUN_URL} + + The run's annotations name each failing check: Developer ID identity, certificate expiry, signing, or Apple notary access. Renew or replace that credential before the next release is cut, or the release will fail at signing or notarization. + + This issue closes itself when the weekly check passes again." + fi + ;; + *) + echo "The preflight ended as ${RESULT}; nothing to report." + ;; + esac