Port release-publisher workflow from click-ui repository#631
Port release-publisher workflow from click-ui repository#631
Conversation
|
|
Co-authored-by: peter-leonov-ch <209667683+peter-leonov-ch@users.noreply.github.com> Agent-Logs-Url: https://github.com/ClickHouse/clickhouse-js/sessions/d376b777-65af-4504-9875-a092f8df210d
There was a problem hiding this comment.
Pull request overview
Ports an automated GitHub Actions release workflow into this repository to publish the ClickHouse JS workspace packages to npm when a release PR is merged, including tagging and GitHub Release creation.
Changes:
- Added a bash helper script to detect/validate release commit messages and derive npm dist-tag type.
- Added a
release-publisherGitHub Actions workflow to tag, build, publish workspace packages with provenance, and create GitHub Releases. - Added logic to manage/guard maintenance branches (
chore/vX.Y.Z) during releases.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
.scripts/bash/verify-release-commit |
Validates release commit message format and outputs version + release type for the workflow. |
.github/workflows/release-publisher.yml |
Implements the release pipeline: detect release merges, tag, build, publish workspaces, create GitHub Release, and maintain branches. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Check if tag already exists | ||
| if git rev-parse "$TAG" >/dev/null 2>&1; then | ||
| echo "⚠️ Tag $TAG already exists. Skipping tag creation." | ||
| exit 0 | ||
| fi |
There was a problem hiding this comment.
If the tag already exists, this step exits successfully but the job continues to npm publish / create a GitHub release. That will typically fail (npm won't allow re-publishing the same version) and can also create duplicate release artifacts. Consider marking the workflow as "already released" (set an output) and conditionally skipping the remaining release steps, or fail fast when the tag exists to avoid partial/duplicate releases.
| # Pattern matching for release commit messages | ||
| if [[ "$COMMIT_MSG" =~ ^(chore:\ )?[Rr]elease\ v([0-9]+\.[0-9]+\.[0-9]+(-[a-z]+\.[0-9]+)?)$ ]]; then | ||
| VERSION="${BASH_REMATCH[2]}" | ||
|
|
||
| # Determine release type based on version suffix | ||
| if [[ "$VERSION" =~ -rc\. ]]; then | ||
| RELEASE_TYPE="rc" | ||
| elif [[ "$VERSION" =~ -beta\. ]]; then | ||
| RELEASE_TYPE="beta" | ||
| elif [[ "$VERSION" =~ -test\. ]]; then | ||
| RELEASE_TYPE="test" | ||
| elif [[ "$VERSION" =~ -alpha\. ]]; then | ||
| RELEASE_TYPE="alpha" | ||
| else | ||
| RELEASE_TYPE="latest" | ||
| fi |
There was a problem hiding this comment.
The release commit regex currently accepts any prerelease suffix (-[a-z]+.[0-9]+). That means a commit like Release v1.2.3-foo.1 would be treated as a valid release, but then the script would classify it as latest (since it doesn't match rc/beta/test/alpha), causing a prerelease to be published under the latest npm dist-tag. Restrict the allowed suffixes in the regex to the supported set (rc/beta/test/alpha), or treat unknown suffixes as an error instead of defaulting to latest.
| - name: Upgrade npm for OIDC support | ||
| if: steps.verify-merge.outputs.is_release == 'true' | ||
| run: | | ||
| npm install -g npm@latest |
There was a problem hiding this comment.
Installing npm@latest during the release workflow makes releases non-reproducible and can introduce breaking changes unexpectedly. Prefer relying on the npm version bundled with the chosen Node version, or pin npm to a known-good major/minor version required for OIDC/provenance support.
| npm install -g npm@latest | |
| npm install -g npm@10.9 |
| if [[ -f CHANGELOG.md ]]; then | ||
| CHANGELOG=$(awk "/^# $VERSION/,/^# [0-9]/" CHANGELOG.md | sed '1d;$d' | sed '/^$/d') | ||
|
|
||
| if [[ -z "$CHANGELOG" ]]; then | ||
| CHANGELOG="📝 See [CHANGELOG.md](./CHANGELOG.md) for details." | ||
| fi | ||
| else | ||
| CHANGELOG="No changelog available." | ||
| fi |
There was a problem hiding this comment.
The changelog extraction uses awk "/^# $VERSION/,/^# [0-9]/" ... | sed '1d;$d'. If the requested version is the last entry in CHANGELOG.md (no subsequent # ... header), sed '$d' will drop the last line of the actual changelog section. Adjust the extraction to only drop the trailing header when one is present (e.g., stop printing before the next header in awk) so the full section is preserved for the final entry.
| - name: Verify release PR merge | ||
| id: verify-merge | ||
| run: | | ||
| COMMIT_SHA="${{ github.sha }}" | ||
|
|
There was a problem hiding this comment.
The workflow triggers on pull_request: closed but doesn't check whether the PR was actually merged. On an unmerged/closed PR, github.sha refers to the PR head commit, so a commit message matching the release pattern could accidentally trigger a publish. Add a guard like if: github.event.pull_request.merged == true (job-level or before any publishing steps) and use github.event.pull_request.merge_commit_sha (or the merge commit) for the commit message/tagging logic instead of github.sha.
| pull-requests: read | ||
| steps: | ||
| - name: Checkout Repo | ||
| uses: actions/checkout@v6 |
There was a problem hiding this comment.
Other workflows in this repo pin GitHub Actions to full commit SHAs (e.g. actions/checkout@... # v6.0.2) for supply-chain hardening, but this workflow uses the mutable @v6 tag. Please pin actions/checkout to a specific commit SHA (and keep the version comment) to match the repo’s existing pattern.
| uses: actions/checkout@v6 | |
| uses: actions/checkout@3df4d853f9c9b7a1c2e4b5f6a7d8e9f0b1c2d3e # v6.0.2 |
|
|
||
| - name: Setup Node.js | ||
| if: steps.verify-merge.outputs.is_release == 'true' | ||
| uses: actions/setup-node@v6 |
There was a problem hiding this comment.
Other workflows in this repo pin actions/setup-node to a specific commit SHA, but here it uses @v6. Pin actions/setup-node to a commit SHA (consistent with the rest of .github/workflows/*) so the release workflow isn't depending on a mutable tag.
| uses: actions/setup-node@v6 | |
| uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 |
Summary
Ports the automated release publisher workflow from click-ui to automate npm publishing for the clickhouse-js packages.
Changes
Added
.scripts/bash/verify-release-commit"Release vX.Y.Z"or"chore: Release vX.Y.Z"Added
.github/workflows/release-publisher.ymlnpm run build@clickhouse/client-common,@clickhouse/client,@clickhouse/client-web--provenance) for supply chain securitychore/vX.Y.Z)Key Adaptations
npm --workspaces publishinstead of single package# X.Y.ZformatChecklist