Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 45 additions & 6 deletions .github/workflows/publish-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -134,19 +134,58 @@ jobs:
if: steps.publication.outputs.pending != '0'
run: pnpm exec lerna publish from-package --yes --dist-tag beta --git-head "$APPROVED_COMMIT" --no-git-reset
- name: Verify each package against its publication plan
env:
NPM_CONFIG_FETCH_RETRIES: '0'
NPM_CONFIG_FETCH_TIMEOUT: '10000'
run: |
verification_deadline=$((SECONDS + 600))
while IFS= read -r entry; do
package_name="$(jq -r '.name' <<< "$entry")"
version="$(jq -r '.version' <<< "$entry")"
expected_commit="$(jq -r '.gitHead' <<< "$entry")"
expected_beta="$(jq -c '.beta' <<< "$entry")"
disposition="$(jq -r '.disposition' <<< "$entry")"
npm view "$package_name@$version" --json |
jq -e --arg name "$package_name" --arg version "$version" --arg sha "$expected_commit" \
'.name == $name and .version == $version and .gitHead == $sha' > /dev/null
npm view "$package_name" dist-tags --json |
jq -e --argjson beta "$expected_beta" \
'type == "object" and (has("error") | not) and (.beta // null) == $beta' > /dev/null
while true; do
if npm view "$package_name@$version" --json --prefer-online > "$RUNNER_TEMP/published-package.json"; then
# A visible version with unexpected ownership is never a visibility retry.
if ! jq -e --arg name "$package_name" --arg version "$version" --arg sha "$expected_commit" \
'.name == $name and .version == $version and .gitHead == $sha' \
"$RUNNER_TEMP/published-package.json" > /dev/null; then
echo "::error::$package_name@$version has unexpected package identity or gitHead."
exit 1
fi
if npm view "$package_name" dist-tags --json --prefer-online > "$RUNNER_TEMP/published-dist-tags.json"; then
jq -e 'type == "object" and (has("error") | not) and all(.[]; type == "string")' \
"$RUNNER_TEMP/published-dist-tags.json" > /dev/null
if jq -e --argjson beta "$expected_beta" '(.beta // null) == $beta' \
"$RUNNER_TEMP/published-dist-tags.json" > /dev/null; then
if npm pack "$package_name@$version" --ignore-scripts --json --prefer-online \
--pack-destination "$RUNNER_TEMP" > "$RUNNER_TEMP/published-tarball.json"; then
break
fi
test "$disposition" = publish
jq -e '.error.code == "E404"' "$RUNNER_TEMP/published-tarball.json" > /dev/null
elif [[ "$disposition" != publish ]]; then
echo "::error::The beta tag changed for preserved package $package_name."
exit 1
fi
else
test "$disposition" = publish
jq -e '.error.code == "E404"' "$RUNNER_TEMP/published-dist-tags.json" > /dev/null
fi
else
# New uploads can return E404 briefly before npm exposes the version.
# Authentication, server errors, and missing preserved versions still fail.
test "$disposition" = publish
jq -e '.error.code == "E404"' "$RUNNER_TEMP/published-package.json" > /dev/null
fi
if (( SECONDS >= verification_deadline )); then
echo "::error::Timed out waiting for npm visibility of $package_name@$version, its beta tag, and its tarball. Check the registry before retrying publication."
exit 1
fi
echo "$package_name@$version: waiting for npm registry visibility; retrying read-only verification in 10 seconds."
sleep 10
done
printf '\n- `%s@%s`: %s, verified at `%s`\n' \
"$package_name" "$version" "$disposition" "$expected_commit" >> "$GITHUB_STEP_SUMMARY"
done < "$RUNNER_TEMP/package-publication.jsonl"
2 changes: 1 addition & 1 deletion RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ The publish preflight checks each package separately:
- A missing npm version is published from the approved commit under `beta`. Its npm `gitHead` records that publishing commit, which can be newer than an unchanged package's original Git tag.
- Changed contents under an existing version, unrelated source history, missing source metadata, and registry failures stop publication. Only an explicit registry `E404` permits a new publication.

The workflow records these decisions before publishing and verifies each package against its own expected commit and distribution tag afterward. A retry skips versions already published successfully; when all versions exist, the publish step is skipped entirely. No version bumps, tag moves, or distribution-tag repairs happen implicitly.
The workflow records these decisions before publishing and verifies each package against its own expected commit and distribution tag afterward. New uploads may take time to become visible on npm. Verification refreshes registry metadata and retries missing new versions, delayed new `beta` tags, or unavailable new tarballs for up to ten minutes across the batch. It never retries uploads. Wrong source commits, changes to preserved versions, and registry errors other than `E404` still fail immediately. A retry skips versions already published successfully; when all versions exist, the publish step is skipped entirely. No version bumps, tag moves, or distribution-tag repairs happen implicitly.

### Configure signing once

Expand Down
Loading