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
42 changes: 41 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,23 @@ jobs:
registry-url: https://npm.pkg.github.com
scope: '@codebar-ag'

# Catches the tag/manifest mismatch BEFORE spending three minutes on a
# build: `git tag v1.9.0` without the matching `npm version` bump either
# republishes the previous version or fails at the very last step.
- name: Tag must match package.json version
run: |
tag="${GITHUB_REF_NAME#v}"
manifest="$(node -p "require('./package.json').version")"

if [ "$tag" != "$manifest" ]; then
echo "::error::Tag v${tag} does not match package.json version ${manifest}." \
"Bump the manifest (npm version) and re-tag."
exit 1
fi

echo "version=${manifest}" >> "$GITHUB_OUTPUT"
id: version

- run: npm ci

- name: Typecheck + lint
Expand All @@ -40,10 +57,33 @@ jobs:
- name: Component tests (Playwright)
run: npm run test:ci

# v1.8.0's release went red here with "You cannot publish over the
# previously published versions": the version had been published BY HAND
# nine seconds after the tag push, while this job was still on `npm ci`.
# Nothing was actually wrong with the release — it had already shipped —
# but the red run made a healthy release indistinguishable from a broken
# one. Publish from CI only; if the version is somehow already on the
# registry, say so and pass rather than failing on a no-op.
- name: Publish to GitHub Packages
run: npm publish
run: |
version="${{ steps.version.outputs.version }}"

if npm view "@codebar-ag/storybook@${version}" version >/dev/null 2>&1; then
echo "::warning::@codebar-ag/storybook@${version} is already on the registry;" \
"nothing to publish. It was published outside this workflow —" \
"release by pushing a v* tag, never by running npm publish locally."
exit 0
fi

npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# The project .npmrc references ${GITHUB_TOKEN}, which npm resolves
# ahead of setup-node's userconfig — keep both env vars populated.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Verify the published version resolves
run: npm view "@codebar-ag/storybook@${{ steps.version.outputs.version }}" version
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,21 @@ npm run typecheck # vue-tsc
npm run lint
```

## Release

Publishing happens in CI, on a `v*` tag. Never run `npm publish` by hand — the
registry rejects a republish, so a manual publish turns the tag's Release run
red even though the version shipped fine, and a healthy release stops being
distinguishable from a broken one (this is exactly what happened to v1.8.0).

```bash
npm version minor # bumps package.json + creates the vX.Y.Z tag
git push --follow-tags # Release workflow builds, tests, publishes
```

The workflow refuses to run if the tag and `package.json` version disagree, and
verifies the version resolves on the registry once published.

## Changelog

Release notes, migration notes and upgrade warnings live in
Expand Down
Loading