Skip to content

Commit eee3486

Browse files
fix(ci): keep the canary dist-tag from moving back to an older build (#3784)
Every canary publish moved the `canary` dist-tag, whatever commit it was built from. Two merges close together could publish out of order, and a re-run of an older run could publish its build last. The publish job now clones the repository's commit history and publishes a canary only when its commit comes after the commit of the canary on npm, or is the same commit under a new version. A build of an earlier commit is skipped with a warning. Commits are compared rather than versions, because a version can be higher for an older commit. Canary publishes also run one at a time, queued, so each check reads what the previous publish left on npm. Release publishes are unchanged. A scheduled run on an unchanged main now skips with a notice instead of failing on the duplicate version. Fixes #3783
1 parent 7cc64e6 commit eee3486

1 file changed

Lines changed: 35 additions & 0 deletions

File tree

‎.github/workflows/test.yml‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ jobs:
163163
name: Publish (NPM)
164164
needs: ['build', 'test', 'browser']
165165
if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'release' }}
166+
# One canary publish at a time, so the check below reads the canary the previous one published.
167+
concurrency:
168+
group: ${{ github.event_name == 'release' && github.run_id || 'canary-publish' }}
169+
cancel-in-progress: false
170+
queue: max
166171
steps:
167172
- name: Setup node
168173
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
@@ -175,7 +180,37 @@ jobs:
175180
with:
176181
name: angularfire-${{ github.run_id }}
177182
path: dist
183+
- name: Skip a canary that is not newer than npm's
184+
id: canary_check
185+
run: |
186+
VERSION=$(node -p "require('./dist/packages-dist/package.json').version")
187+
if [[ $VERSION == *-canary.* ]]; then
188+
# The dist-tags endpoint is not CDN-cached, unlike the package data `npm view` reads.
189+
DIST_TAGS=$(curl -fsS --retry 3 --max-time 30 https://registry.npmjs.org/-/package/@angular/fire/dist-tags)
190+
NPM_CANARY=$(node -p "JSON.parse(process.argv[1]).canary" "$DIST_TAGS")
191+
# Order by position on main, not by version, which can be higher for an older commit.
192+
git clone --quiet --bare --filter=tree:0 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" history.git
193+
HOW_TO_FIX="Every canary publish fails until the canary dist-tag points at a build of a commit on main. Publish rights are required to fix it with: npm dist-tag add @angular/fire@<version> canary"
194+
if ! NPM_CANARY_COMMIT=$(git -C history.git rev-parse --verify --quiet "${NPM_CANARY##*[.-]}^{commit}"); then
195+
echo "::error::Could not match the canary on npm, $NPM_CANARY, to a single commit in this repository. $HOW_TO_FIX"
196+
exit 1
197+
fi
198+
# `npm publish` always moves a dist-tag, so a canary that is not newer must not publish at all.
199+
if [[ $NPM_CANARY_COMMIT == "$GITHUB_SHA" ]]; then
200+
if [[ $VERSION == "$NPM_CANARY" ]]; then
201+
echo "::notice::Not publishing $VERSION, because it is already the canary on npm."
202+
echo "skip=true" >> "$GITHUB_OUTPUT"
203+
fi
204+
elif git -C history.git merge-base --is-ancestor "$GITHUB_SHA" "$NPM_CANARY_COMMIT"; then
205+
echo "::warning::Not publishing $VERSION, because the canary on npm, $NPM_CANARY, is from a later commit on main."
206+
echo "skip=true" >> "$GITHUB_OUTPUT"
207+
elif ! git -C history.git merge-base --is-ancestor "$NPM_CANARY_COMMIT" "$GITHUB_SHA"; then
208+
echo "::error::Not publishing $VERSION, because its commit and the commit of the canary on npm, $NPM_CANARY, are not on the same line of history. One of them is not on main. $HOW_TO_FIX"
209+
exit 1
210+
fi
211+
fi
178212
- name: Publish
213+
if: steps.canary_check.outputs.skip != 'true'
179214
run: |
180215
cd ./dist/packages-dist
181216
chmod +x publish.sh

0 commit comments

Comments
 (0)