Skip to content

Commit 24259ef

Browse files
authored
Merge pull request #58 from samiodeh1337/chore/release-pipeline
ci: release from the branch name, deploy docs only after npm publish
2 parents 1b847ec + 881404a commit 24259ef

4 files changed

Lines changed: 99 additions & 36 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ on:
44
pull_request:
55
branches: [main]
66
push:
7-
branches: [main]
7+
branches: [main, 'release/**']
88

99
jobs:
1010
check:

‎.github/workflows/deploy-docs.yml‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
name: 📚 Deploy Docs to GitHub Pages
1+
name: 📚 Deploy Docs (manual)
2+
3+
# Redeploys the docs site from main without a release, for docs-only fixes. Run it from the
4+
# Actions tab. A release deploys the docs itself, as the last job of the publish workflow.
25

36
on:
4-
push:
5-
tags:
6-
- 'v*'
77
workflow_dispatch:
88

99
permissions:

‎.github/workflows/publish.yml‎

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
name: 📦 Publish to npm
1+
name: 📦 Publish — npm, GitHub Release, docs
2+
3+
# Runs on a vX.Y.Z tag (pushed by the release workflow). Three jobs, each needing the one before:
4+
# the full gate, then npm publish + the GitHub Release, then the docs deploy. A failed publish
5+
# stops the docs from deploying, so the site never describes a version that is not on npm.
26

37
on:
48
push:
@@ -36,6 +40,12 @@ jobs:
3640
- name: Build docs
3741
run: npm run build:docs
3842

43+
- name: Tag matches package.json
44+
run: |
45+
TAG="${GITHUB_REF_NAME#v}"
46+
PKG=$(node -p "require('./package.json').version")
47+
if [ "$TAG" != "$PKG" ]; then echo "ERROR: tag v$TAG but package.json is $PKG" && exit 1; fi
48+
3949
publish:
4050
needs: ci
4151
runs-on: ubuntu-latest
@@ -68,3 +78,44 @@ jobs:
6878
uses: softprops/action-gh-release@v2
6979
with:
7080
generate_release_notes: true
81+
82+
deploy-docs:
83+
needs: publish
84+
runs-on: ubuntu-latest
85+
permissions:
86+
contents: read
87+
pages: write
88+
id-token: write
89+
environment:
90+
name: github-pages
91+
url: ${{ steps.deployment.outputs.page_url }}
92+
concurrency:
93+
group: 'pages'
94+
cancel-in-progress: true
95+
steps:
96+
- name: Checkout
97+
uses: actions/checkout@v4
98+
99+
- name: Setup Node
100+
uses: actions/setup-node@v4
101+
with:
102+
node-version: 22
103+
cache: npm
104+
105+
- name: Install dependencies
106+
run: npm ci
107+
108+
- name: Build docs
109+
run: npm run build:docs
110+
111+
- name: Setup Pages
112+
uses: actions/configure-pages@v5
113+
114+
- name: Upload artifact
115+
uses: actions/upload-pages-artifact@v3
116+
with:
117+
path: './docs-dist'
118+
119+
- name: Deploy to GitHub Pages
120+
id: deployment
121+
uses: actions/deploy-pages@v4

‎.github/workflows/release.yml‎

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,30 @@
1-
name: 🚀 Release — Tag & Update Version
1+
name: 🚀 Release — Version & Tag
22

3-
# Runs when a release/* branch is merged into main.
4-
# Reads the version from package.json, updates index.html,
5-
# commits the change, tags main, and pushes — triggering
6-
# the publish and deploy-docs workflows.
3+
# Merging a release/X.Y.Z branch into main releases X.Y.Z: the version comes from the branch
4+
# name, so nothing is bumped by hand. The workflow sets package.json to that version, dates the
5+
# CHANGELOG heading, commits to main and pushes the tag vX.Y.Z, which runs the publish workflow
6+
# (gate, npm, GitHub Release, docs). It can also be run from the Actions tab with a version typed in.
77

88
on:
99
pull_request:
1010
types: [closed]
1111
branches: [main]
12+
workflow_dispatch:
13+
inputs:
14+
version:
15+
description: 'Version to release, e.g. 3.0.1'
16+
required: true
1217

1318
jobs:
14-
tag:
15-
if: github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'release/')
19+
release:
20+
if: >-
21+
github.event_name == 'workflow_dispatch' ||
22+
(github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'release/'))
1623
runs-on: ubuntu-latest
1724
permissions:
1825
contents: write
1926
steps:
20-
- name: Checkout
27+
- name: Checkout main
2128
uses: actions/checkout@v4
2229
with:
2330
ref: main
@@ -29,40 +36,45 @@ jobs:
2936
with:
3037
node-version: 22
3138

32-
- name: Read version from package.json
39+
- name: Version from the branch name (or the input)
3340
id: version
41+
env:
42+
HEAD_REF: ${{ github.event.pull_request.head.ref }}
43+
INPUT_VERSION: ${{ github.event.inputs.version }}
3444
run: |
35-
VERSION=$(node -p "require('./package.json').version")
36-
echo "Version: $VERSION"
37-
if [ -z "$VERSION" ]; then echo "ERROR: version is empty" && exit 1; fi
45+
if [ -n "$INPUT_VERSION" ]; then VERSION="$INPUT_VERSION"; else VERSION="${HEAD_REF#release/}"; fi
46+
VERSION="${VERSION#v}"
47+
if ! echo "$VERSION" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$'; then
48+
echo "ERROR: '$VERSION' is not a version. Name the branch release/X.Y.Z." && exit 1
49+
fi
50+
if git ls-remote --exit-code --tags origin "v$VERSION" >/dev/null 2>&1; then
51+
echo "ERROR: tag v$VERSION already exists" && exit 1
52+
fi
53+
echo "Releasing $VERSION"
3854
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
3955
40-
- name: Update version in index.html
56+
- name: Set package.json version and date the changelog
4157
run: |
4258
VERSION="${{ steps.version.outputs.version }}"
43-
sed -i "s/\"softwareVersion\": \"[^\"]*\"/\"softwareVersion\": \"$VERSION\"/" index.html
59+
npm version "$VERSION" --no-git-tag-version --allow-same-version
60+
# the heading "## 3.0.0 (unreleased …)" or "## Unreleased" becomes "## 3.0.0 (2026-10-02)"
61+
TODAY=$(date -u +%F) VERSION="$VERSION" perl -i -pe \
62+
's/^## (?=.*unreleased)(?:v?\Q$ENV{VERSION}\E|\[?Unreleased\]?).*$/## $ENV{VERSION} ($ENV{TODAY})/i' CHANGELOG.md
4463
45-
- name: Check for changes
46-
id: diff
47-
run: |
48-
if git diff --quiet; then
49-
echo "changed=false" >> "$GITHUB_OUTPUT"
50-
else
51-
echo "changed=true" >> "$GITHUB_OUTPUT"
52-
fi
53-
54-
- name: Commit version update
55-
if: steps.diff.outputs.changed == 'true'
64+
- name: Commit to main
5665
run: |
5766
git config user.name "github-actions[bot]"
5867
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
5968
git remote set-url origin https://x-access-token:${{ secrets.GH_PAT }}@github.com/${{ github.repository }}
60-
git add index.html
61-
git commit -m "chore: update version to ${{ steps.version.outputs.version }}"
62-
git push
69+
if git diff --quiet; then
70+
echo "package.json and CHANGELOG.md already at ${{ steps.version.outputs.version }}"
71+
else
72+
git add package.json package-lock.json CHANGELOG.md
73+
git commit -m "release: ${{ steps.version.outputs.version }}"
74+
git push origin main
75+
fi
6376
64-
- name: Create and push tag
77+
- name: Tag
6578
run: |
66-
git remote set-url origin https://x-access-token:${{ secrets.GH_PAT }}@github.com/${{ github.repository }}
6779
git tag "v${{ steps.version.outputs.version }}"
6880
git push origin "v${{ steps.version.outputs.version }}"

0 commit comments

Comments
 (0)