mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-31 04:12:10 +03:00
fix(ci): unblock the npm publish — dynamic runner + reuse CI's next-build (#8941)
The v3.8.49 publish failed: `Build CLI bundle` runs `npm run build:cli`, which shells
out to a full `next build` when `.build/next/standalone/server.js` is missing. That
build's working set outgrew the 16 GB GitHub-hosted runner during this cycle, so the
job died at 6m20s with
Creating an optimized production build ...
##[error]The runner has received a shutdown signal.
and every step after it — artifact validation, SBOM, tarball boot-smoke, the staged
publish — was skipped. The same job had passed in 16 minutes for v3.8.48, so this is
the build growing past the runner, not the runner degrading. ci.yml already routes its
heavy jobs around this via the USE_VPS_RUNNER expression; npm-publish.yml had
`runs-on: ubuntu-latest` hardcoded and no way out.
Two changes, one for the fast path and one for the fallback:
- `runs-on` now uses the SAME expression as ci.yml's build/test-unit, so the operator
can send the publish to the 32-core self-hosted runner. Kept verbatim (including the
fork-safety clause that is always true here, since this workflow never runs on
pull_request) so the expression stays greppable across workflows.
- A best-effort step restores the `next-build` artifact that CI already produced for
the SAME commit, matching on `head_sha` — same commit, same tree, so no equality gate
is needed beyond the match itself. `build:cli` then finds the standalone tree and
skips the build entirely, turning the heaviest step into a download. Retention is one
day, so every miss (no successful CI run, expired artifact, bad extract) logs a notice
and falls through to the build — which is exactly why the dynamic runner above is the
necessary backstop rather than a nice-to-have.
Needs `actions: read` to look up the run and download the artifact. All inputs reach the
script through `env:`, never interpolated into the shell body. No new zizmor findings:
the step uses the `gh` CLI rather than a new `uses:`, so the unpinned-uses count is
unchanged (189 measured locally == the devbox side of the 190 baseline).
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
c9d4a45f18
commit
e6523da2a1
44
.github/workflows/npm-publish.yml
vendored
44
.github/workflows/npm-publish.yml
vendored
@@ -56,8 +56,15 @@ env:
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
# Same dynamic-runner rule as ci.yml's `build`/`test-unit`: `build:cli` falls back to a
|
||||
# full `next build`, whose working set outgrew the 16 GB hosted runner during the
|
||||
# v3.8.49 cycle — the publish died with "The runner has received a shutdown signal"
|
||||
# mid-"Creating an optimized production build" while v3.8.48 had still fit in 16min.
|
||||
# This job never runs on `pull_request`, so the fork-safety clause is always true here;
|
||||
# it is kept verbatim so the expression stays greppable against ci.yml.
|
||||
runs-on: ${{ (vars.USE_VPS_RUNNER == 'true' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)) && fromJSON('["self-hosted","omni-release"]') || 'ubuntu-latest' }}
|
||||
permissions:
|
||||
actions: read # find + download the CI run's next-build artifact for this SHA
|
||||
contents: write # gh release upload (attach SBOM to the GitHub Release)
|
||||
id-token: write # npm provenance
|
||||
packages: write # publish to npm.pkg.github.com
|
||||
@@ -145,6 +152,41 @@ jobs:
|
||||
run: |
|
||||
npm version "$VERSION" --no-git-tag-version --allow-same-version
|
||||
|
||||
# Fast path: CI already built the standalone tree for THIS commit and uploaded it as
|
||||
# `next-build`. `build:cli` (scripts/build/prepublish.ts) only shells out to a full
|
||||
# `next build` when `.build/next/standalone/server.js` is missing — restoring the
|
||||
# artifact turns the heaviest step of the publish into a download. Matching on
|
||||
# `head_sha` is the tree-equality guarantee: same commit, same tree.
|
||||
# Best-effort by design (retention is 1 day): every miss falls through to the build
|
||||
# step below, which is why the dynamic runner above matters as the backstop.
|
||||
- name: Reuse CI's next-build artifact (skips the heavy rebuild)
|
||||
if: steps.resolve.outputs.skip != 'true'
|
||||
continue-on-error: true
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
HEAD_SHA: ${{ github.sha }}
|
||||
REPO: ${{ github.repository }}
|
||||
run: |
|
||||
set -uo pipefail
|
||||
RUN=$(gh api "repos/$REPO/actions/runs?head_sha=$HEAD_SHA&per_page=100" \
|
||||
--jq '[.workflow_runs[] | select(.name == "CI" and .conclusion == "success")] | .[0].id // empty') || RUN=""
|
||||
if [ -z "$RUN" ]; then
|
||||
echo "::notice::no successful CI run for $HEAD_SHA — falling back to a full build"
|
||||
exit 0
|
||||
fi
|
||||
if ! gh run download "$RUN" --repo "$REPO" --name next-build --dir /tmp/next-build; then
|
||||
echo "::notice::next-build artifact unavailable for run $RUN (expired?) — falling back to a full build"
|
||||
exit 0
|
||||
fi
|
||||
tar -xzf /tmp/next-build/e2e-build.tar.gz -C .
|
||||
rm -rf /tmp/next-build
|
||||
if [ -f .build/next/standalone/server.js ]; then
|
||||
echo "✅ standalone tree restored from CI run $RUN — build:cli will skip next build"
|
||||
else
|
||||
echo "::notice::extract did not yield .build/next/standalone — falling back to a full build"
|
||||
rm -rf .build
|
||||
fi
|
||||
|
||||
- name: Build CLI bundle (standalone app)
|
||||
if: steps.resolve.outputs.skip != 'true'
|
||||
env:
|
||||
|
||||
Reference in New Issue
Block a user