From 16149a75fd3cf0844491df4a2c4c52dc4acaf03c Mon Sep 17 00:00:00 2001 From: Devin Foley Date: Thu, 20 Aug 2026 23:21:43 -0700 Subject: [PATCH] ci(release): give npm publish visibility polling a 10-minute budget (#11834) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The release workflow publishes every public package to npm per master push (canary) and per promotion channel > - `release.sh` polls the registry after each publish and aborts the whole release when a version is not visible within 60 seconds > - npm accepts publishes immediately, but its CDN can lag packument propagation by several minutes; on 2026-08-21 this failed four consecutive canary runs mid-loop even though every publish succeeded > - This pull request sets the script's existing visibility-budget env overrides at the workflow level to 10 minutes > - The benefit is a release train that tolerates registry propagation lag; a healthy publish still exits the poll on its first visible check ## Linked Issues or Issue Description Not applicable for a `ci:` workflow tuning change. Evidence: four consecutive `Release` runs on master failed in `publish_canary` with "npm did not publish and expose @", while the raw registry packument shows each of those versions present minutes later (`2026.821.0-canary.0` accepted 01:36 UTC, visible 01:40; `2026.821.0-canary.1` accepted 05:54, visible 05:57). ## What Changed - Set `NPM_PUBLISH_VERIFY_ATTEMPTS: "30"` and `NPM_PUBLISH_VERIFY_DELAY_SECONDS: "10"` in the `Release` workflow's top-level `env`, raising `release.sh`'s post-publish visibility poll from 60 seconds to 5 minutes per package for every channel. Both variables are existing overrides read by the script (`scripts/release.sh` lines 311-312); no script change. - Raised the four publish jobs' `timeout-minutes` from 45 to 90 so several laggard packages fit inside the job without exhausting it before the tag push / Docker / release steps. ## Verification - `release.sh` reads the two env overrides with defaults (`${NPM_PUBLISH_VERIFY_ATTEMPTS:-12}` / `${NPM_PUBLISH_VERIFY_DELAY_SECONDS:-5}`), so workflow-level env reaches `publish_package_to_npm_and_wait` unchanged. - Not run: a live release (needs the npm-canary environment). The next master push exercises the canary path with the new budget. ## Risks - Low risk: a genuinely failed publish now takes up to 5 minutes to report instead of 1, and a pathological batch where most packages lag the full budget still fails inside the 90-minute job — that pattern means a real registry incident. The poll exits early on success, so healthy releases are unaffected. ## Model Used Claude Fable 5 (Anthropic, `claude-fable-5`) with extended thinking and agentic tool use via the Claude Code CLI (release log forensics against raw registry packument timestamps). ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable (not applicable: workflow env tuning) - [x] I have updated relevant documentation to reflect my changes (comment in the workflow documents the budget rationale) - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --- .github/workflows/release.yml | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3f0e1e98a6..db7d4a9a75 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -49,6 +49,18 @@ concurrency: group: release-${{ github.event_name }}-${{ github.ref }} cancel-in-progress: false +env: + # npm accepts a publish immediately, but the registry's CDN can lag packument + # propagation by several minutes (observed 2.5-4+ minutes on 2026-08-21, + # which failed four consecutive canary runs mid-loop). Give release.sh's + # post-publish visibility poll a 5-minute budget per package instead of its + # 60-second default; a healthy publish still exits the poll on the first + # visible check. The publish jobs' timeout-minutes are sized for several + # laggard packages; if most of a batch lags the full budget, npm is having + # a real incident and the job failing is correct. + NPM_PUBLISH_VERIFY_ATTEMPTS: "30" + NPM_PUBLISH_VERIFY_DELAY_SECONDS: "10" + jobs: verify_canary: if: github.event_name == 'push' @@ -60,7 +72,7 @@ jobs: if: github.event_name == 'push' needs: verify_canary runs-on: ubuntu-latest - timeout-minutes: 45 + timeout-minutes: 90 environment: npm-canary permissions: contents: write @@ -236,7 +248,7 @@ jobs: (needs.smoke_nightly.result == 'success' || (needs.smoke_nightly.result == 'skipped' && github.event_name == 'workflow_dispatch' && inputs.dry_run)) runs-on: ubuntu-latest - timeout-minutes: 45 + timeout-minutes: 90 environment: npm-canary # The workflow-level concurrency group is per event, so a forced dispatch # nightly could otherwise overlap the scheduled one and race it to the @@ -502,7 +514,7 @@ jobs: (needs.verify_beta_candidate.result == 'success' || (needs.verify_beta_candidate.result == 'skipped' && needs.select_beta.outputs.mode == 'promote')) runs-on: ubuntu-latest - timeout-minutes: 45 + timeout-minutes: 90 environment: npm-beta # Serialize beta publishes so two dispatches cannot race to the same next # -beta.N version; release.sh additionally refuses to double-publish a @@ -919,7 +931,7 @@ jobs: if: github.event_name == 'workflow_dispatch' && inputs.channel == 'stable' && !inputs.dry_run needs: [preflight_stable, verify_stable] runs-on: ubuntu-latest - timeout-minutes: 45 + timeout-minutes: 90 environment: npm-stable permissions: contents: write