Skip to content

Commit 0492dea

Browse files
authored
chore(ci): add changesets + ci validation (#9020)
1 parent 36f4983 commit 0492dea

12 files changed

Lines changed: 650 additions & 100 deletions

File tree

‎.changeset/README.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Changesets
2+
3+
Changesets in this directory describe user-facing changes to published packages. Add one by running:
4+
5+
```shell
6+
pnpm changeset
7+
```
8+
9+
Commit the generated Markdown file with the package change. The publishing workflow consumes these files to update package versions and changelogs before publishing to npm.
10+
11+
See the [package publishing guide](../docs/package-publishing.md) for the complete release process.

‎.changeset/config.json‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"$schema": "https://unpkg.com/@changesets/config@3.1.4/schema.json",
3+
"changelog": [
4+
"@changesets/changelog-github",
5+
{ "repo": "nodejs/nodejs.org" }
6+
],
7+
"commit": false,
8+
"fixed": [],
9+
"linked": [],
10+
"access": "public",
11+
"baseBranch": "main",
12+
"updateInternalDependencies": "patch",
13+
"ignore": []
14+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'@node-core/website-i18n': patch
3+
'@node-core/rehype-shiki': patch
4+
'@node-core/remark-lint': patch
5+
'@node-core/ui-components': patch
6+
---
7+
8+
Migrate package versioning and publishing to Changesets.
Lines changed: 39 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
name: Publish Packages
22

3-
# This workflow publishes packages to npm when changes are merged to main branch or when manually triggered.
3+
# Changesets opens or updates a version PR when release notes are present. Once that PR is merged,
4+
# this workflow publishes the versioned packages to npm.
45

56
on:
67
push:
7-
paths:
8-
- 'packages/**'
98
# For security reasons, this should never be set to anything but `main`
109
branches: [main]
11-
workflow_dispatch:
12-
inputs:
13-
package:
14-
description: 'Specific package to publish (leave empty for all packages)'
15-
required: false
16-
type: string
1710

1811
permissions:
1912
contents: read
@@ -26,12 +19,15 @@ env:
2619
COMMIT_SHA: ${{ github.sha }}
2720

2821
jobs:
29-
prepare-packages:
30-
name: Prepare Packages
22+
release:
23+
name: Create Release PR or Publish
3124
runs-on: ubuntu-latest
32-
outputs:
33-
# Output the matrix of packages to publish for use in the publish job
34-
matrix: ${{ steps.generate-matrix.outputs.matrix }}
25+
# Never attempt to publish from forks (no trusted-publisher match / secrets).
26+
if: github.repository == 'nodejs/nodejs.org'
27+
permissions:
28+
contents: write
29+
id-token: write
30+
pull-requests: write
3531
steps:
3632
- name: Harden Runner
3733
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
@@ -62,83 +58,47 @@ jobs:
6258
6359
echo "✅ Commit is verified and trusted."
6460
65-
- name: Checkout repository
66-
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
67-
with:
68-
fetch-depth: 2 # Need at least 2 commits to detect changes between commits
69-
persist-credentials: false
70-
71-
- name: Generate package matrix
72-
id: generate-matrix
73-
env:
74-
PACKAGE: ${{ github.event.inputs.package }}
75-
EVENT_NAME: ${{ github.event_name }}
76-
run: |
77-
if [ -n "$PACKAGE" ]; then
78-
# If a specific package is requested via workflow_dispatch, just publish that one
79-
echo "matrix={\"package\":[\"$PACKAGE\"]}" >> $GITHUB_OUTPUT
80-
else
81-
CHANGED_PACKAGES=()
82-
for pkg in $(ls -d packages/*); do
83-
PKG_NAME=$(basename "$pkg")
84-
PKG_JSON="$pkg/package.json"
85-
86-
# Determine if the package has changed (or include all on manual trigger)
87-
if [ "$EVENT_NAME" == "workflow_dispatch" ] || ! git diff --quiet $COMMIT_SHA~1 $COMMIT_SHA -- "$pkg/"; then
88-
OLD_VERSION=$(git show $COMMIT_SHA~1:$PKG_JSON | jq -r '.version')
89-
NEW_VERSION=$(jq -r '.version' "$PKG_JSON")
90-
if [ "$OLD_VERSION" != "$NEW_VERSION" ]; then
91-
CHANGED_PACKAGES+=("$PKG_NAME")
92-
fi
93-
fi
94-
done
95-
96-
# Format the output for GitHub Actions matrix using jq
97-
PACKAGES_JSON=$(jq -n '$ARGS.positional' --args "${CHANGED_PACKAGES[@]}" -c)
98-
echo "matrix={\"package\":$PACKAGES_JSON}" >> $GITHUB_OUTPUT
99-
fi
100-
101-
publish:
102-
name: Publish
103-
needs: prepare-packages
104-
runs-on: ubuntu-latest
105-
permissions:
106-
# Required for npm OIDC publishing (https://docs.npmjs.com/trusted-publishers)
107-
id-token: write
108-
# Skip if no packages need to be published
109-
if: fromJson(needs.prepare-packages.outputs.matrix).package[0] != null
110-
# Use the dynamic matrix from prepare-packages job to create parallel jobs for each package
111-
strategy:
112-
matrix: ${{ fromJson(needs.prepare-packages.outputs.matrix) }}
113-
fail-fast: false # Continue publishing other packages even if one fails
114-
steps:
11561
- uses: nodejs/web-team/actions/setup-environment@9f3c83af227d721768d9dbb63009a47ed4f4282f
11662
with:
11763
pnpm: true
11864
use-version-file: true
11965
registry-url: 'https://registry.npmjs.org'
66+
fetch-depth: 0
12067

121-
- name: Publish
122-
working-directory: packages/${{ matrix.package }}
123-
run: |
124-
# Check if a custom publish script exists in package.json
125-
if jq -e '.scripts.release' package.json > /dev/null; then
126-
pnpm run release
127-
fi
128-
129-
# Then publish the package to npm
130-
pnpm publish --access public --no-git-checks
68+
- name: Create release pull request or publish packages
69+
id: changesets
70+
uses: changesets/action@a45c4d594aa4e2c509dc14a9f2b3b67ba3780d0d # v1.9.0
71+
with:
72+
commit: 'chore: version packages'
73+
title: 'chore: version packages'
74+
version: node --run changeset:version
75+
publish: node --run release
76+
commitMode: github-api
77+
env:
78+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
13179

132-
- name: Notify on Manual Release
133-
if: ${{ github.event_name == 'workflow_dispatch' }}
80+
- name: Format published packages
81+
if: steps.changesets.outputs.published == 'true'
82+
id: notification
83+
env:
84+
PUBLISHED_PACKAGES: ${{ steps.changesets.outputs.publishedPackages }}
85+
run: |
86+
{
87+
echo 'packages<<EOF'
88+
jq -r '.[] | ":package: *Package*: `\(.name)@\(.version)` (<https://www.npmjs.com/package/\(.name)/v/\(.version)|View on npm>)"' <<< "$PUBLISHED_PACKAGES"
89+
echo 'EOF'
90+
} >> "$GITHUB_OUTPUT"
91+
92+
- name: Notify
93+
if: steps.changesets.outputs.published == 'true'
13494
uses: rtCamp/action-slack-notify@33ca3be66c6f378fe1610fd1d5258632dbed5e58 # v2.4.0
13595
env:
13696
SLACK_COLOR: '#43853D'
13797
SLACK_ICON: https://github.com/nodejs.png?size=48
138-
SLACK_TITLE: ':rocket: Package Published: ${{ matrix.package }}'
98+
SLACK_TITLE: ':rocket: Packages Published'
13999
SLACK_MESSAGE: |
140-
:package: *Package*: `${{ matrix.package }}` (<https://www.npmjs.com/package/@node-core/${{ matrix.package }}|View on npm>)
100+
${{ steps.notification.outputs.packages }}
141101
:bust_in_silhouette: *Published by*: ${{ github.triggering_actor }}
142-
:octocat: *Commit*: <https://github.com/${{ github.repository }}/commit/${{ env.COMMIT_SHA }}|${{ env.COMMIT_SHA }}>
102+
:octocat: *Commit*: <https://github.com/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}>
143103
SLACK_USERNAME: nodejs-bot
144104
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Security Notes
2+
# Only selected Actions are allowed within this repository. Please refer to (https://github.com/nodejs/nodejs.org/settings/actions)
3+
# for the full list of available actions. If you want to add a new one, please reach out a maintainer with Admin permissions.
4+
# REVIEWERS, please always double-check security practices before merging a PR that contains workflow changes!!
5+
# AUTHORS, please only use actions with explicit SHA references, and avoid using `@master` or `@main` references or `@version` tags.
6+
7+
name: Pull Request Policy
8+
9+
on:
10+
pull_request:
11+
branches:
12+
- main
13+
types: [opened, edited, synchronize, reopened, ready_for_review]
14+
15+
permissions:
16+
contents: read
17+
18+
concurrency:
19+
group: ${{ github.workflow }}-${{ github.ref }}
20+
cancel-in-progress: true
21+
22+
jobs:
23+
changesets:
24+
name: Changesets
25+
runs-on: ubuntu-latest
26+
if: |
27+
github.event_name == 'pull_request' &&
28+
!(github.event.pull_request.head.repo.full_name == github.repository &&
29+
github.event.pull_request.head.ref == 'changeset-release/main')
30+
steps:
31+
- uses: nodejs/web-team/actions/setup-environment@9f3c83af227d721768d9dbb63009a47ed4f4282f
32+
with:
33+
pnpm: true
34+
use-version-file: true
35+
fetch-depth: 0
36+
37+
- run: pnpm changeset status --since origin/main
38+
39+
conventional-commits:
40+
name: Conventional commits
41+
runs-on: ubuntu-latest
42+
steps:
43+
- name: Check PR Title Format
44+
env:
45+
PR_TITLE: ${{ github.event.pull_request.title }}
46+
run: |
47+
REGEX="^[a-z][a-z0-9-]*(\([a-z0-9_.\/-]+\))?!?: .+"
48+
49+
if [[ ! "$PR_TITLE" =~ $REGEX || "$PR_TITLE" == *. ]]; then
50+
echo 'PR titles must use <type>[optional scope][!]: <description> and must not end with a period.'
51+
exit 1
52+
fi

‎.github/workflows/translations-sync.yml‎

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ jobs:
4848
download_translations: true
4949
localization_branch_name: ${{ env.BRANCH_NAME }}
5050
create_pull_request: true
51-
pull_request_title: '[automated]: crowdin sync'
51+
pull_request_title: 'chore(i18n): sync translations from crowdin'
5252
pull_request_body: 'New Crowdin translations from the [Node.js Crowdin project](https://crowdin.com/project/nodejs-web)'
53-
commit_message: 'chore: synced translations from crowdin'
53+
commit_message: 'chore(i18n): sync translations from crowdin'
5454
env:
5555
GITHUB_TOKEN: ${{ secrets.CROWDIN_GITHUB_BOT_TOKEN }}
5656
# A numeric ID, found at https://crowdin.com/project/nodejs-web/tools/api
@@ -92,12 +92,17 @@ jobs:
9292
cache-lint-${{ hashFiles('pnpm-lock.yaml') }}-
9393
cache-lint-
9494
95-
- name: Patch version if the files changed
96-
working-directory: packages/i18n
95+
- name: Add changeset if the files changed
9796
run: |
9897
CHANGED_FILES=$(git diff --name-only HEAD^1 HEAD)
9998
if [ -n "$CHANGED_FILES" ]; then
100-
pnpm version patch --no-git-tag-version
99+
cat > .changeset/crowdin-translations.md <<'EOF'
100+
---
101+
'@node-core/website-i18n': patch
102+
---
103+
104+
Update translations from Crowdin.
105+
EOF
101106
fi
102107
103108
- name: Run ESLint
@@ -111,7 +116,7 @@ jobs:
111116
uses: stefanzweifel/git-auto-commit-action@04702edda442b2e678b25b537cec683a1493fcb9 # v7.1.0
112117
with:
113118
commit_options: '--no-verify --signoff'
114-
commit_message: 'chore: automated format of translated files'
119+
commit_message: 'chore(i18n): format translated files'
115120
branch: ${{ env.BRANCH_NAME }}
116121

117122
- name: Save Lint Cache

‎docs/code-style.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ This project follows the [Conventional Commits](https://www.conventionalcommits.
3838
- Commit messages must include a "type" as described in Conventional Commits
3939
- Commit messages **must** be written in lowercase, except proper nouns
4040
- Commit messages **must not** end with a period `.`
41+
- Pull request titles must use the same format and pass the `Conventional commits` check in the `Pull Request Policy` workflow
4142

4243
### Commit Signing
4344

‎docs/package-publishing.md‎

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ This guide covers the package publishing process for the Node.js website's multi
66

77
- [Overview](#overview)
88
- [Repository Structure](#repository-structure)
9+
- [Adding a Changeset](#adding-a-changeset)
910
- [Publishing Process](#publishing-process)
1011

1112
## Overview
@@ -29,24 +30,44 @@ nodejs.org/
2930
└── site/ # Main website application
3031
```
3132

33+
## Adding a Changeset
34+
35+
Package versions and release notes are managed with [Changesets](https://github.com/changesets/changesets). Changes to a published package should include a changeset in the same pull request.
36+
37+
Run the Changesets CLI from the repository root:
38+
39+
```shell
40+
pnpm changeset
41+
```
42+
43+
Select every package affected by the change, choose the appropriate semantic version bump, and write a concise summary for the changelog. Commit the generated Markdown file in `.changeset/` with the rest of the change.
44+
45+
The `Pull Request Policy` workflow rejects pull requests that change files under `packages/` without a changeset.
46+
47+
If a package change only affects internal tooling and does not require a release, run `pnpm changeset add --empty` instead.
48+
49+
Use `pnpm changeset:version` only to test the versioning step locally. The release workflow normally runs it and manages the resulting version changes.
50+
3251
## Publishing Process
3352

34-
Publishing is handled automatically through GitHub Actions, when changes are merged to the main branch (or via `workflow_dispatch`):
53+
Publishing is handled automatically by the `Publish Packages` GitHub Actions workflow:
3554

3655
1. **Merge Queue**: Changes must come through GitHub's merge queue
37-
2. **CI Pipeline**: "Linting and Tests" workflow completes successfully
38-
3. **Auto-trigger**: "Publish Packages" workflow runs automatically
39-
4. **Verification**: Committer must be verified from `noreply@github.com`
40-
5. **Notification**: Slack notification sent to `#nodejs-website` if `workflow_dispatch` was the trigger.
56+
2. **Collect changesets**: Merged changesets are collected into a `chore: version packages` pull request
57+
3. **Version packages**: The version pull request updates package versions and changelogs
58+
4. **Review and merge**: The version pull request goes through the normal review and merge queue
59+
5. **Publish**: After that pull request lands, the workflow builds the workspace packages and publishes every newly versioned package to npm using trusted publishing
60+
6. **Notify**: A release notification listing the published packages is sent to `#nodejs-web-infra-alerts`
61+
62+
Package versions should not be edited or published manually. A failed publishing run can be retried from GitHub Actions after its cause is resolved.
4163

4264
```mermaid
4365
graph TD
44-
A[Code Changes] --> B[Pull Request]
45-
B --> C[CI Tests Pass]
46-
C --> D[Merge to Main]
47-
D --> E[Merge Queue]
48-
E --> F[Auto Publish Trigger]
49-
F --> G[Package Analysis]
50-
G --> H[Version Bump]
51-
H --> I[npm publish]
66+
A[Package change and changeset] --> B[Pull request]
67+
B --> C[Merge queue]
68+
C --> D[Merge to main]
69+
D --> E[Create or update Version Packages PR]
70+
E --> F[Review and merge version PR]
71+
F --> G[Build release artifacts]
72+
G --> H[Publish to npm]
5273
```

‎package.json‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
},
1515
"scripts": {
1616
"build": "turbo build",
17+
"changeset": "changeset",
18+
"changeset:version": "changeset version",
1719
"cloudflare:deploy": "turbo cloudflare:deploy",
1820
"cloudflare:preview": "turbo cloudflare:preview",
1921
"deploy": "turbo deploy",
@@ -26,6 +28,7 @@
2628
"prepare": "husky",
2729
"prettier": "prettier \"**/*.{js,mjs,ts,tsx,md,mdx,json,yml,css}\" --check --cache --cache-strategy=content --cache-location=.prettiercache",
2830
"prettier:fix": "node --run prettier -- --write",
31+
"release": "pnpm --filter './packages/*' --if-present run build && changeset publish",
2932
"scripts:release-post": "turbo scripts:release-post",
3033
"start": "turbo start",
3134
"storybook": "turbo storybook",
@@ -39,6 +42,8 @@
3942
"turbo": "2.9.16"
4043
},
4144
"devDependencies": {
45+
"@changesets/changelog-github": "^0.7.0",
46+
"@changesets/cli": "^2.31.1",
4247
"@eslint/js": "~10.0.1",
4348
"@reporters/github": "^2.0.0",
4449
"@testing-library/react": "~16.3.2",

‎packages/rehype-shiki/package.json‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
"scripts": {
2323
"build:ts": "tsc",
2424
"build": "node --run build:ts",
25-
"release": "node --run build",
2625
"lint": "node --run lint:js",
2726
"lint:fix": "node --run lint:js:fix",
2827
"lint:js": "eslint \"**/*.mjs\"",

0 commit comments

Comments
 (0)