Files
hermes-agent/.github/workflows/stable-release.yml
ethernet b5d583c4ac feat(release): start the gates and the signed candidates together
Every gate and every candidate now needs only admit, so the signed macOS
and Windows builds and the docker image stop waiting behind the full CI
run. acceptance stays the one join: it still needs ci, docker and all six
candidates, so what can be promoted is unchanged.

The four gates that skipped under --skip-tests only because ci skipped
(nix, termux-checks, windows-live, install-e2e) and pm-bundle needed their
own condition. SKIPPED_BY requires the gate to observe 'skipped', so
dropping the edge alone would have left them running and blocked the
release instead of failing it.
2026-09-25 12:50:53 -04:00

618 lines
24 KiB
YAML

name: Stable Release
run-name: Stable release ${{ inputs.tag }}
# Dispatch on the tag so reusable workflows and github.sha identify the same tree.
on:
workflow_dispatch:
inputs:
tag:
description: Exact annotated claim tag, matching the selected workflow ref
required: true
type: string
baseline-manifest:
description: Optional HTTPS manifest of the previous published stable packages
default: ''
type: string
permissions:
contents: read
concurrency:
group: stable-release
cancel-in-progress: false
jobs:
admit:
name: Admit the claim
# A read token cannot see a draft release, so gh release view answers
# "release not found" for a draft that exists. Write is the permission
# that can read it.
permissions:
contents: write
runs-on: ubuntu-24.04
outputs:
claim-tag: ${{ steps.admit.outputs.claim-tag }}
claim-object: ${{ steps.admit.outputs.claim-object }}
tag: ${{ steps.admit.outputs.tag }}
commit: ${{ steps.admit.outputs.commit }}
version: ${{ steps.admit.outputs.version }}
release-id: ${{ steps.admit.outputs.release-id }}
release-epoch: ${{ steps.admit.outputs.release-epoch }}
skip-bundles: ${{ steps.admit.outputs.skip-bundles }}
skip-tests: ${{ steps.admit.outputs.skip-tests }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.sha }}
fetch-depth: 0
- uses: ./.github/actions/setup-pm
with:
cache-python: false
- id: admit
run: python -m scripts.releases.stable admit
env:
GH_TOKEN: ${{ github.token }}
RELEASE_CLAIM_TAG: ${{ inputs.tag }}
ci:
name: Full CI pipeline
needs: admit
if: needs.admit.outputs.skip-tests != 'true'
permissions:
contents: read
pull-requests: write
actions: read
security-events: write
uses: ./.github/workflows/ci.yaml
with:
release: true
docker:
name: Docker build and tests
needs: admit
# The image publish-docker pushes is built here, so a claim that skipped
# tests still runs this job with its tests off. It builds alongside the
# gates; only the acceptance join waits for CI.
if: >-
!cancelled() && needs.admit.result == 'success'
uses: ./.github/workflows/docker.yml
with:
release-phase: test
skip-tests: ${{ needs.admit.outputs.skip-tests == 'true' }}
tag: ${{ needs.admit.outputs.tag }}
version: ${{ needs.admit.outputs.version }}
nix:
needs: admit
# The claim's policy removes it, not a gate it happens to need.
if: needs.admit.outputs.skip-tests != 'true'
uses: ./.github/workflows/nix.yml
with:
release: true
version: ${{ needs.admit.outputs.version }}
pm-bundle:
needs: admit
# Bundle acceptance is a test of bundles, so either claim flag removes it.
if: >-
needs.admit.outputs.skip-bundles != 'true'
&& needs.admit.outputs.skip-tests != 'true'
uses: ./.github/workflows/pm-bundle.yml
with:
release: true
ref: ${{ github.sha }}
termux-checks:
needs: admit
if: needs.admit.outputs.skip-tests != 'true'
permissions:
contents: read
actions: read
uses: ./.github/workflows/termux-verify.yml
with:
release: true
windows-live:
needs: admit
if: needs.admit.outputs.skip-tests != 'true'
uses: ./.github/workflows/windows-venv-e2e.yml
with:
release: true
install-e2e:
name: Install and update E2E
needs: admit
if: needs.admit.outputs.skip-tests != 'true'
permissions:
contents: read
actions: read
uses: ./.github/workflows/install-e2e.yml
with:
release: true
route: all
tag-count: '3'
exclude-ref: ${{ inputs.tag }}
candidates-darwin-arm64:
name: Build signed release candidates (darwin-arm64)
needs: admit
# Starts with the gates; the acceptance join is what requires CI.
if: >-
!cancelled() && needs.admit.result == 'success' && needs.admit.outputs.skip-bundles != 'true'
permissions:
contents: write
actions: read
packages: write
id-token: write
uses: ./.github/workflows/desktop-bundled-release.yml
with:
tag: ${{ needs.admit.outputs.tag }}
claim-tag: ${{ needs.admit.outputs.claim-tag }}
claim-object: ${{ needs.admit.outputs.claim-object }}
release-phase: candidate
jobs: darwin-arm64
skip-tests: ${{ needs.admit.outputs.skip-tests == 'true' }}
candidates-darwin-x64:
name: Build signed release candidates (darwin-x64)
needs: admit
# Starts with the gates; the acceptance join is what requires CI.
if: >-
!cancelled() && needs.admit.result == 'success' && needs.admit.outputs.skip-bundles != 'true'
permissions:
contents: write
actions: read
packages: write
id-token: write
uses: ./.github/workflows/desktop-bundled-release.yml
with:
tag: ${{ needs.admit.outputs.tag }}
claim-tag: ${{ needs.admit.outputs.claim-tag }}
claim-object: ${{ needs.admit.outputs.claim-object }}
release-phase: candidate
jobs: darwin-x64
skip-tests: ${{ needs.admit.outputs.skip-tests == 'true' }}
candidates-win32-arm64:
name: Build signed release candidates (win32-arm64)
needs: admit
# Starts with the gates; the acceptance join is what requires CI.
if: >-
!cancelled() && needs.admit.result == 'success' && needs.admit.outputs.skip-bundles != 'true'
permissions:
contents: write
actions: read
packages: write
id-token: write
uses: ./.github/workflows/desktop-bundled-release.yml
with:
tag: ${{ needs.admit.outputs.tag }}
claim-tag: ${{ needs.admit.outputs.claim-tag }}
claim-object: ${{ needs.admit.outputs.claim-object }}
release-phase: candidate
jobs: win32-arm64
skip-tests: ${{ needs.admit.outputs.skip-tests == 'true' }}
candidates-win32-x64:
name: Build signed release candidates (win32-x64)
needs: admit
# Starts with the gates; the acceptance join is what requires CI.
if: >-
!cancelled() && needs.admit.result == 'success' && needs.admit.outputs.skip-bundles != 'true'
permissions:
contents: write
actions: read
packages: write
id-token: write
uses: ./.github/workflows/desktop-bundled-release.yml
with:
tag: ${{ needs.admit.outputs.tag }}
claim-tag: ${{ needs.admit.outputs.claim-tag }}
claim-object: ${{ needs.admit.outputs.claim-object }}
release-phase: candidate
jobs: win32-x64
skip-tests: ${{ needs.admit.outputs.skip-tests == 'true' }}
candidates-win32-bundle:
name: Build signed release candidates (win32-bundle)
needs: [admit, candidates-win32-arm64, candidates-win32-x64]
# Starts with the gates; the acceptance join is what requires CI.
if: >-
!cancelled() && needs.admit.result == 'success' && needs.admit.outputs.skip-bundles != 'true'
&& needs.candidates-win32-arm64.result == 'success'
&& needs.candidates-win32-x64.result == 'success'
permissions:
contents: write
actions: read
packages: write
id-token: write
uses: ./.github/workflows/desktop-bundled-release.yml
with:
tag: ${{ needs.admit.outputs.tag }}
claim-tag: ${{ needs.admit.outputs.claim-tag }}
claim-object: ${{ needs.admit.outputs.claim-object }}
release-phase: candidate
jobs: win32-bundle
skip-tests: ${{ needs.admit.outputs.skip-tests == 'true' }}
candidates-termux:
name: Build signed release candidates (termux)
needs: admit
# Starts with the gates; the acceptance join is what requires CI.
if: >-
!cancelled() && needs.admit.result == 'success' && needs.admit.outputs.skip-bundles != 'true'
permissions:
contents: write
actions: read
packages: write
id-token: write
uses: ./.github/workflows/desktop-bundled-release.yml
with:
tag: ${{ needs.admit.outputs.tag }}
claim-tag: ${{ needs.admit.outputs.claim-tag }}
claim-object: ${{ needs.admit.outputs.claim-object }}
release-phase: candidate
jobs: termux
skip-tests: ${{ needs.admit.outputs.skip-tests == 'true' }}
transitions-darwin-arm64:
name: Pin actual OLD and NEW signed packages (darwin-arm64)
needs: [admit, candidates-darwin-arm64]
if: needs.admit.outputs.skip-tests != 'true'
runs-on: ubuntu-24.04
environment: release-signing
outputs:
windows: ${{ steps.plan.outputs.windows }}
macos: ${{ steps.plan.outputs.macos }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.sha }}
fetch-depth: 0
- uses: ./.github/actions/setup-pm
with:
cache-python: false
- id: plan
run: python -m scripts.releases.stable transitions
env:
GH_TOKEN: ${{ github.token }}
RECEIPT: darwin-arm64
RECEIPT_URL: ${{ needs.candidates-darwin-arm64.outputs.darwin-arm64-receipt-url }}
RECEIPT_SHA256: ${{ needs.candidates-darwin-arm64.outputs.darwin-arm64-receipt-sha256 }}
RELEASE_TAG: ${{ needs.admit.outputs.tag }}
RELEASE_CLAIM_TAG: ${{ needs.admit.outputs.claim-tag }}
RELEASE_CLAIM_OBJECT: ${{ needs.admit.outputs.claim-object }}
BASELINE_MANIFEST_URL: ${{ inputs.baseline-manifest }}
CLOUDFLARE_R2_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_R2_ACCOUNT_ID }}
CLOUDFLARE_R2_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }}
CLOUDFLARE_R2_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }}
CLOUDFLARE_R2_BUCKET: ${{ vars.CLOUDFLARE_R2_BUCKET }}
CLOUDFLARE_R2_PUBLIC_URL: ${{ vars.CLOUDFLARE_R2_PUBLIC_URL }}
transitions-darwin-x64:
name: Pin actual OLD and NEW signed packages (darwin-x64)
needs: [admit, candidates-darwin-x64]
if: needs.admit.outputs.skip-tests != 'true'
runs-on: ubuntu-24.04
environment: release-signing
outputs:
windows: ${{ steps.plan.outputs.windows }}
macos: ${{ steps.plan.outputs.macos }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.sha }}
fetch-depth: 0
- uses: ./.github/actions/setup-pm
with:
cache-python: false
- id: plan
run: python -m scripts.releases.stable transitions
env:
GH_TOKEN: ${{ github.token }}
RECEIPT: darwin-x64
RECEIPT_URL: ${{ needs.candidates-darwin-x64.outputs.darwin-x64-receipt-url }}
RECEIPT_SHA256: ${{ needs.candidates-darwin-x64.outputs.darwin-x64-receipt-sha256 }}
RELEASE_TAG: ${{ needs.admit.outputs.tag }}
RELEASE_CLAIM_TAG: ${{ needs.admit.outputs.claim-tag }}
RELEASE_CLAIM_OBJECT: ${{ needs.admit.outputs.claim-object }}
BASELINE_MANIFEST_URL: ${{ inputs.baseline-manifest }}
CLOUDFLARE_R2_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_R2_ACCOUNT_ID }}
CLOUDFLARE_R2_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }}
CLOUDFLARE_R2_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }}
CLOUDFLARE_R2_BUCKET: ${{ vars.CLOUDFLARE_R2_BUCKET }}
CLOUDFLARE_R2_PUBLIC_URL: ${{ vars.CLOUDFLARE_R2_PUBLIC_URL }}
transitions-win32:
name: Pin actual OLD and NEW signed packages (win32)
needs: [admit, candidates-win32-bundle]
if: needs.admit.outputs.skip-tests != 'true'
runs-on: ubuntu-24.04
environment: release-signing
outputs:
windows: ${{ steps.plan.outputs.windows }}
macos: ${{ steps.plan.outputs.macos }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.sha }}
fetch-depth: 0
- uses: ./.github/actions/setup-pm
with:
cache-python: false
- id: plan
run: python -m scripts.releases.stable transitions
env:
GH_TOKEN: ${{ github.token }}
RECEIPT: win32-bundle
RECEIPT_URL: ${{ needs.candidates-win32-bundle.outputs.win32-bundle-receipt-url }}
RECEIPT_SHA256: ${{ needs.candidates-win32-bundle.outputs.win32-bundle-receipt-sha256 }}
RELEASE_TAG: ${{ needs.admit.outputs.tag }}
RELEASE_CLAIM_TAG: ${{ needs.admit.outputs.claim-tag }}
RELEASE_CLAIM_OBJECT: ${{ needs.admit.outputs.claim-object }}
BASELINE_MANIFEST_URL: ${{ inputs.baseline-manifest }}
CLOUDFLARE_R2_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_R2_ACCOUNT_ID }}
CLOUDFLARE_R2_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }}
CLOUDFLARE_R2_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }}
CLOUDFLARE_R2_BUCKET: ${{ vars.CLOUDFLARE_R2_BUCKET }}
CLOUDFLARE_R2_PUBLIC_URL: ${{ vars.CLOUDFLARE_R2_PUBLIC_URL }}
candidate-manifest:
name: Stage verified stable candidate artifacts
# Runs after every candidate call, so after every smoke (decision 23).
# The recorded smoke results are the calls' own workflow results: a
# call's stable-phase-result fails when its smokes fail, so a failed
# smoke fails this job's RELEASE_NEEDS check and stages no manifest.
if: always() && needs.admit.outputs.skip-bundles != 'true'
needs: [admit, candidates-darwin-arm64, candidates-darwin-x64, candidates-win32-arm64,
candidates-win32-x64, candidates-win32-bundle, candidates-termux]
runs-on: ubuntu-24.04
environment: release-signing
timeout-minutes: 90
outputs:
manifest-url: ${{ steps.manifest.outputs.manifest-url }}
manifest-sha256: ${{ steps.manifest.outputs.manifest-sha256 }}
env:
RELEASE_TAG: ${{ needs.admit.outputs.tag }}
RELEASE_CLAIM_TAG: ${{ needs.admit.outputs.claim-tag }}
RELEASE_CLAIM_OBJECT: ${{ needs.admit.outputs.claim-object }}
RELEASE_NEEDS: ${{ toJSON(needs) }}
CLOUDFLARE_R2_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_R2_ACCOUNT_ID }}
CLOUDFLARE_R2_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }}
CLOUDFLARE_R2_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }}
CLOUDFLARE_R2_BUCKET: ${{ vars.CLOUDFLARE_R2_BUCKET }}
CLOUDFLARE_R2_PUBLIC_URL: ${{ vars.CLOUDFLARE_R2_PUBLIC_URL }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.sha }}
fetch-depth: 0
fetch-tags: true
- uses: ./.github/actions/setup-pm
with:
cache-python: false
- id: manifest
run: python -m scripts.releases.stable candidate-manifest
windows-packaged:
name: Windows signed-package acceptance
needs: transitions-win32
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.transitions-win32.outputs.windows) }}
uses: ./.github/workflows/install-e2e-windows-run.yml
with:
install-method: packaged-app
update-method: open-app-update
install-ref: ${{ matrix.old }}
leg-id: stable-${{ matrix.id }}
bundle-manifest-url: ${{ matrix.manifest }}
bundle-manifest-sha256: ${{ matrix.manifest_sha256 }}
bundle-arch: ${{ matrix.arch }}
macos-packaged-arm64:
name: macOS arm64 signed-package acceptance
needs: transitions-darwin-arm64
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.transitions-darwin-arm64.outputs.macos) }}
uses: ./.github/workflows/install-e2e-macos-run.yml
with:
install-method: packaged-app
update-method: open-app-update
install-ref: ${{ matrix.old }}
leg-id: stable-${{ matrix.id }}
bundle-manifest-url: ${{ matrix.manifest }}
bundle-manifest-sha256: ${{ matrix.manifest_sha256 }}
bundle-arch: ${{ matrix.arch }}
macos-packaged-x64:
name: macOS x64 signed-package acceptance
needs: transitions-darwin-x64
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.transitions-darwin-x64.outputs.macos) }}
uses: ./.github/workflows/install-e2e-macos-run.yml
with:
install-method: packaged-app
update-method: open-app-update
install-ref: ${{ matrix.old }}
leg-id: stable-${{ matrix.id }}
bundle-manifest-url: ${{ matrix.manifest }}
bundle-manifest-sha256: ${{ matrix.manifest_sha256 }}
bundle-arch: ${{ matrix.arch }}
bootstrap-version:
name: Bootstrap installer release identity
needs: admit
if: needs.admit.outputs.skip-tests != 'true'
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ needs.admit.outputs.commit }}
- name: Stamp and verify the Cargo and Tauri release identity
env:
RELEASE_COMMIT: ${{ needs.admit.outputs.commit }}
RELEASE_VERSION: ${{ needs.admit.outputs.version }}
run: |
set -euo pipefail
tree="$RUNNER_TEMP/bootstrap-release"
mkdir -p "$tree"
git archive "$RELEASE_COMMIT" | tar -x -C "$tree"
python3 -m scripts.releases.stamping --tree "$tree" \
--version "$RELEASE_VERSION"
actual="$(cargo metadata --no-deps --format-version 1 \
--manifest-path "$tree/apps/bootstrap-installer/src-tauri/Cargo.toml" \
| jq -r '.packages[] | select(.name == "hermes-bootstrap") | .version')"
test "$actual" = "$RELEASE_VERSION" || {
echo "::error::Bootstrap Cargo version $actual != $RELEASE_VERSION"
exit 1
}
actual_tauri="$(python3 -c 'import json,sys; print(json.load(open(sys.argv[1]))["version"])' \
"$tree/apps/bootstrap-installer/src-tauri/tauri.conf.json")"
test "$actual_tauri" = "$RELEASE_VERSION" || {
echo "::error::Bootstrap Tauri version $actual_tauri != $RELEASE_VERSION"
exit 1
}
acceptance:
name: All release acceptance checks pass
if: always()
needs: [admit, ci, docker, nix, pm-bundle, termux-checks, windows-live, install-e2e,
candidates-darwin-arm64, candidates-darwin-x64, candidates-win32-arm64,
candidates-win32-x64, candidates-win32-bundle, candidates-termux,
candidate-manifest, transitions-darwin-arm64, transitions-darwin-x64,
transitions-win32, windows-packaged, macos-packaged-arm64, macos-packaged-x64,
bootstrap-version]
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.sha }}
- uses: ./.github/actions/setup-pm
with:
cache-python: false
- run: python -m scripts.releases.stable gate admit ci docker nix pm-bundle termux-checks windows-live install-e2e candidates-darwin-arm64 candidates-darwin-x64 candidates-win32-arm64 candidates-win32-x64 candidates-win32-bundle candidates-termux candidate-manifest transitions-darwin-arm64 transitions-darwin-x64 transitions-win32 windows-packaged macos-packaged-arm64 macos-packaged-x64 bootstrap-version
env:
RELEASE_NEEDS: ${{ toJSON(needs) }}
SKIP_BUNDLES: ${{ needs.admit.outputs.skip-bundles }}
SKIP_TESTS: ${{ needs.admit.outputs.skip-tests }}
publish-docker:
name: Publish tested Docker image
# B5: this job pushes only the immutable attempt-ref image tags; the
# stable/latest aliases move in the ordered publication pass.
needs: [admit, docker]
uses: ./.github/workflows/docker.yml
with:
release-phase: publish
tag: ${{ needs.admit.outputs.tag }}
version: ${{ needs.admit.outputs.version }}
publish-bundles:
name: Publish tested bundle artifacts
needs: [admit, acceptance, candidate-manifest]
if: needs.admit.outputs.skip-bundles != 'true'
permissions:
contents: write
actions: read
packages: write
id-token: write
uses: ./.github/workflows/desktop-bundled-release.yml
with:
tag: ${{ needs.admit.outputs.tag }}
claim-tag: ${{ needs.admit.outputs.claim-tag }}
claim-object: ${{ needs.admit.outputs.claim-object }}
release-phase: publish
manifest-sha256: ${{ needs.candidate-manifest.outputs.manifest-sha256 }}
publication:
name: All artifact publication succeeded
if: always()
needs: [admit, acceptance, publish-docker, publish-bundles]
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.sha }}
- uses: ./.github/actions/setup-pm
with:
cache-python: false
- run: python -m scripts.releases.stable gate acceptance publish-docker publish-bundles
env:
RELEASE_NEEDS: ${{ toJSON(needs) }}
SKIP_BUNDLES: ${{ needs.admit.outputs.skip-bundles }}
SKIP_TESTS: ${{ needs.admit.outputs.skip-tests }}
complete:
name: Stable release is green
if: always()
needs: [admit, ci, docker, acceptance, candidate-manifest, publication, publish-docker,
windows-packaged, macos-packaged-arm64, macos-packaged-x64]
runs-on: ubuntu-24.04
environment: release-signing
permissions:
contents: write
actions: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.sha }}
fetch-depth: 0
- uses: ./.github/actions/setup-pm
with:
cache-python: false
- name: Set up the native identity reader
uses: ./.github/actions/setup-pm
with:
toolchain: node
cache-python: false
- run: python -m scripts.releases.stable gate admit ci docker acceptance candidate-manifest publication publish-docker
env:
RELEASE_NEEDS: ${{ toJSON(needs) }}
SKIP_BUNDLES: ${{ needs.admit.outputs.skip-bundles }}
SKIP_TESTS: ${{ needs.admit.outputs.skip-tests }}
- name: Validate the accepted candidate archive
if: needs.admit.outputs.skip-bundles != 'true'
run: python -m scripts.releases.stable complete
env:
RELEASE_TAG: ${{ needs.admit.outputs.tag }}
RELEASE_CLAIM_TAG: ${{ needs.admit.outputs.claim-tag }}
RELEASE_CLAIM_OBJECT: ${{ needs.admit.outputs.claim-object }}
CANDIDATE_MANIFEST_URL: ${{ needs.candidate-manifest.outputs.manifest-url }}
CANDIDATE_MANIFEST_SHA256: ${{ needs.candidate-manifest.outputs.manifest-sha256 }}
CLOUDFLARE_R2_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_R2_ACCOUNT_ID }}
CLOUDFLARE_R2_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }}
CLOUDFLARE_R2_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }}
CLOUDFLARE_R2_BUCKET: ${{ vars.CLOUDFLARE_R2_BUCKET }}
CLOUDFLARE_R2_PUBLIC_URL: ${{ vars.CLOUDFLARE_R2_PUBLIC_URL }}
- name: Render the admitted candidate smoke results
if: needs.admit.outputs.skip-bundles != 'true'
env:
GH_TOKEN: ${{ github.token }}
RELEASE_TAG: ${{ needs.admit.outputs.tag }}
RELEASE_COMMIT: ${{ needs.admit.outputs.commit }}
CANDIDATE_MANIFEST_SHA256: ${{ needs.candidate-manifest.outputs.manifest-sha256 }}
run: |
python scripts/render-builds-table.py --tag "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" \
--archive "$RELEASE_CLAIM_TAG" \
--candidate-manifest-sha256 "$CANDIDATE_MANIFEST_SHA256" --candidate-commit "$RELEASE_COMMIT"
- name: Set up Docker Buildx for ordered alias promotion
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
- name: Log in to Docker Hub for ordered alias promotion
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Reconcile ordered stable publication
run: python -m scripts.releases.sequencer
env:
GH_TOKEN: ${{ github.token }}
REQUESTED_VERSION: ''
CLOUDFLARE_R2_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_R2_ACCOUNT_ID }}
CLOUDFLARE_R2_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }}
CLOUDFLARE_R2_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }}
CLOUDFLARE_R2_BUCKET: ${{ vars.CLOUDFLARE_R2_BUCKET }}
CLOUDFLARE_R2_PUBLIC_URL: ${{ vars.CLOUDFLARE_R2_PUBLIC_URL }}