perf(ci): admit release candidates and isolate native image capacity (#18869)

Admit full source verification only for exact-source Docker or npm release work, while superseded pending sources complete metadata-only admission. Restart only strictly deferred runs; failed or cancelled checks require an explicit request.

Route canonical master native images to dedicated 32-core Spot profiles and keep source checks on protected verification capacity. Use the four-slot GitHub-hosted publication pool for registry work and signing, with proof waits outside that pool and a fresh source-proof check before tagging. Trim historical checkout blobs and prepared-runner disk cleanup while preserving tag and fork publication behavior.

Validation: release/source and source/artifact regressions, 665 workflow contracts, actionlint, complete latest-head PR CI, and Greptile 5/5 with all comments resolved. Existing CLI and large-file repository timing tests also passed independently; their CI shards received one scoped retry.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip authored and GitHub committed 2026-11-03 18:01:07 -06:00
1 parent 8771606fd8
commit f774992832
13 files changed
+886 -63

No files matched your search

+71 -10
View File
@@ -33,6 +33,29 @@ concurrency:
cancel-in-progress: false
jobs:
source_verification:
name: Watch exact-source verification
if: github.repository == 'paperclipai/paperclip' && github.repository_id == '1170821064' && github.ref == 'refs/heads/master'
runs-on: ${{ vars.AWS_POST_MERGE_CI_ENABLED == 'true' && github.run_attempt >= 1 && github.repository == 'paperclipai/paperclip' && github.repository_id == '1170821064' && github.ref == 'refs/heads/master' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && 'runs-on/fleet=paperclip-post-merge-x64/env=public-ci' || 'ubuntu-latest' }}
timeout-minutes: 44
permissions:
contents: read
actions: write
outputs:
verified: ${{ steps.watch.outputs.verified }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
with:
node-version: 24
- name: Stop images when source checks fail and report runner waits
id: watch
env:
GITHUB_TOKEN: ${{ github.token }}
run: node scripts/watch-release-source.mjs
reuse_canary_image:
if: github.repository == 'paperclipai/paperclip' && github.repository_id == '1170821064' && startsWith(github.ref, 'refs/tags/canary/v')
runs-on: ubuntu-latest
@@ -100,11 +123,10 @@ jobs:
- platform: linux/arm64
runner: ubuntu-24.04-arm
arch: arm64
runs-on: ${{ matrix.runner }}
# Native builds land well inside this; it is a backstop, not a budget.
# (The interim fix while this PR landed raised the single QEMU job's cap
# to 120 minutes; native per-arch legs make that headroom unnecessary.)
timeout-minutes: 60
runs-on: ${{ vars.CORE_RELEASE_AWS_ENABLED == 'true' && github.repository == 'paperclipai/paperclip' && github.repository_id == '1170821064' && github.ref == 'refs/heads/master' && format('runs-on/fleet=paperclip-core-image-{0}/env=public-ci', matrix.arch == 'amd64' && 'x64' || 'arm64') || matrix.runner }}
# Stop before the AWS worker's 45-minute maximum lifetime. Hosted tag
# builds retain their existing limit.
timeout-minutes: ${{ vars.CORE_RELEASE_AWS_ENABLED == 'true' && github.repository == 'paperclipai/paperclip' && github.repository_id == '1170821064' && github.ref == 'refs/heads/master' && 40 || 60 }}
permissions:
contents: read
packages: write
@@ -115,6 +137,9 @@ jobs:
# Full history and tags so `git describe` below can compute the
# release version to stamp into the image.
fetch-depth: 0
# Keep the version's full commit graph without downloading blobs
# from every historical revision of this large repository.
filter: blob:none
# `.git` is dockerignored, so a running image cannot derive its own
# version and otherwise reports the source package.json placeholder in
@@ -183,6 +208,7 @@ jobs:
echo "Using refreshed pnpm-lock.yaml in the Docker build context."
- name: Free runner disk
if: ${{ !(vars.CORE_RELEASE_AWS_ENABLED == 'true' && github.repository == 'paperclipai/paperclip' && github.repository_id == '1170821064' && github.ref == 'refs/heads/master') }}
run: |
set -euo pipefail
echo "Disk before cleanup:"
@@ -304,16 +330,40 @@ jobs:
if-no-files-found: error
retention-days: 1
# Wait for proof on ephemeral verification capacity. Publication runners do
# only registry/signing work. Each Spot observer stays below its 45m lifetime.
publication_verification:
name: Require exact-source verification
if: ${{ !cancelled() && github.repository == 'paperclipai/paperclip' && github.repository_id == '1170821064' && github.ref == 'refs/heads/master' && needs.build-and-push.result == 'success' && needs.source_verification.result == 'success' && needs.source_verification.outputs.verified != 'true' }}
needs: [build-and-push, source_verification]
runs-on: ${{ vars.AWS_POST_MERGE_CI_ENABLED == 'true' && github.run_attempt >= 1 && github.repository == 'paperclipai/paperclip' && github.repository_id == '1170821064' && github.ref == 'refs/heads/master' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && 'runs-on/fleet=paperclip-post-merge-x64/env=public-ci' || 'ubuntu-latest' }}
timeout-minutes: 44
permissions:
contents: read
actions: write # restart only exact-source producers deferred before admission
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
with:
node-version: 24
- name: Require source proof and migrator admission before publication
env:
GITHUB_TOKEN: ${{ github.token }}
run: node scripts/watch-release-source.mjs --require-proof
# Names the per-architecture digests as one manifest list under the real
# tags. Nothing is publicly tagged until this runs, so a half-published
# multi-arch image is not a state anything can pull.
merge-and-push:
if: ${{ !cancelled() && needs.build-and-push.result == 'success' }}
needs: build-and-push
runs-on: ubuntu-latest
if: ${{ !cancelled() && needs.build-and-push.result == 'success' && (needs.source_verification.result == 'success' || needs.source_verification.result == 'skipped') && (needs.publication_verification.result == 'success' || (needs.publication_verification.result == 'skipped' && (github.repository != 'paperclipai/paperclip' || github.repository_id != '1170821064' || github.ref != 'refs/heads/master' || needs.source_verification.outputs.verified == 'true'))) }}
needs: [build-and-push, source_verification, publication_verification]
runs-on: ${{ github.repository == 'paperclipai/paperclip' && github.repository_id == '1170821064' && github.ref == 'refs/heads/master' && (vars.CORE_PUBLICATION_RUNNER || 'cloud-release-32') || 'ubuntu-latest' }}
timeout-minutes: 20
permissions:
contents: read
actions: read
packages: write
id-token: write
attestations: write
@@ -322,8 +372,6 @@ jobs:
# script the verification step pipes in.
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 0
- name: Download digests
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
@@ -375,6 +423,19 @@ jobs:
io.github.paperclipai.schema.last-migration=${{ steps.schema.outputs.last }}
io.github.paperclipai.schema.migration-count=${{ steps.schema.outputs.count }}
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
with:
node-version: 24
# Revalidate the latest attempt after runner assignment without waiting
# here. A concurrent source retry must invalidate the earlier proof.
- name: Revalidate exact-source proof before publication
if: github.repository == 'paperclipai/paperclip' && github.repository_id == '1170821064' && github.ref == 'refs/heads/master'
env:
GITHUB_TOKEN: ${{ github.token }}
run: node scripts/watch-release-source.mjs --check-proof
- name: Create manifest list and push
working-directory: /tmp/digests
run: |