Skip to content

Commit a1163c5

Browse files
committed
add slack notif, add doc
1 parent f673832 commit a1163c5

File tree

2 files changed

+92
-42
lines changed

2 files changed

+92
-42
lines changed
Lines changed: 79 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
name: Publish Packages
22

3+
# This workflow publishes packages to NPM when changes are merged to main branch or when manually triggered.
4+
# It runs automatically after successful tests or can be run manually for specific packages.
5+
36
on:
47
workflow_run:
8+
# Only run after linting and tests have passed on main branch
59
workflows: ['Linting and Tests']
610
types: [completed]
11+
# For security reasons, this should never be set to anything but `main`
712
branches: [main]
813
workflow_dispatch:
914
inputs:
@@ -16,44 +21,40 @@ permissions:
1621
contents: read
1722

1823
env:
24+
# Use the SHA from the workflow run that triggered this or the current SHA for manual runs
1925
COMMIT_SHA: ${{ github.event.workflow_run.head_sha || github.sha }}
2026

2127
jobs:
22-
detect-packages:
28+
prepare-packages:
2329
runs-on: ubuntu-latest
30+
# Only run if manually triggered or if the triggering workflow succeeded from a push event
31+
if: github.event_name == 'workflow_dispatch' || (
32+
github.event.workflow_run.conclusion == 'success' &&
33+
github.event.workflow_run.event == 'push' &&
34+
github.repository == 'nodejs/nodejs.org')
2435
outputs:
25-
packages: ${{ steps.find-packages.outputs.packages }}
26-
steps:
27-
- name: Checkout repository
28-
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
29-
30-
- name: Find packages
31-
id: find-packages
32-
env:
33-
PACKAGE: ${{ github.event.inputs.package }}
34-
run: |
35-
if [ "$PACKAGE" != "" ]; then
36-
echo "packages=[\"$PACKAGE\"]" >> $GITHUB_OUTPUT
37-
else
38-
PACKAGES=$(ls -d packages/* | xargs -n 1 basename | jq -R -s -c 'split("\n")[:-1]')
39-
echo "packages=$PACKAGES" >> $GITHUB_OUTPUT
40-
fi
41-
42-
verify-commit:
43-
runs-on: ubuntu-latest
44-
if: github.event_name == 'workflow_dispatch' || (github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push')
36+
# Output the matrix of packages to publish for use in the publish job
37+
matrix: ${{ steps.generate-matrix.outputs.matrix }}
4538
steps:
46-
- name: Checkout repository
47-
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
39+
- name: Harden Runner
40+
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
41+
with:
42+
egress-policy: audit
4843

4944
- name: Verify commit authenticity
45+
# Skip verification for manual runs since they're initiated by trusted users
46+
if: github.event_name != 'workflow_dispatch'
5047
env:
5148
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
5249
run: |
50+
# Get commit data from GitHub API to verify its authenticity
5351
COMMIT_DATA=$(gh api repos/${{ github.repository }}/commits/$COMMIT_SHA)
52+
# Check if commit signature is verified (GPG signed)
5453
VERIFIED=$(echo "$COMMIT_DATA" | jq -r '.commit.verification.verified')
54+
# Check if commit was made through GitHub's web interface (merge queue)
5555
COMMITTER=$(echo "$COMMIT_DATA" | jq -r '.commit.committer.email')
5656
57+
# Security checks to ensure we only publish from verified and trusted sources
5758
if [[ "$VERIFIED" != "true" ]]; then
5859
echo "❌ Unverified commit! Aborting."
5960
exit 1
@@ -66,49 +67,85 @@ jobs:
6667
6768
echo "✅ Commit is verified and trusted."
6869
69-
publish:
70-
needs: [detect-packages, verify-commit]
71-
runs-on: ubuntu-latest
72-
strategy:
73-
matrix:
74-
package: ${{ fromJson(needs.detect-packages.outputs.packages) }}
75-
fail-fast: false
76-
steps:
7770
- name: Checkout repository
7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
7972
with:
80-
fetch-depth: 2
73+
fetch-depth: 2 # Need at least 2 commits to detect changes between commits
8174

82-
- name: Check for package changes
83-
if: github.event_name != 'workflow_dispatch'
84-
id: check_changes
75+
- name: Generate package matrix
76+
id: generate-matrix
8577
env:
86-
PACKAGE: ${{ matrix.package }}
78+
PACKAGE: ${{ github.event.inputs.package }}
79+
EVENT_NAME: ${{ github.event_name }}
8780
run: |
88-
if git diff --quiet $COMMIT_SHA~1 $COMMIT_SHA -- "packages/$PACKAGE/"; then
89-
echo "changed=false" >> $GITHUB_OUTPUT
81+
if [ -n "$PACKAGE" ]; then
82+
# If a specific package is requested via workflow_dispatch, just publish that one
83+
echo "matrix={\"package\":[\"$PACKAGE\"]}" >> $GITHUB_OUTPUT
9084
else
91-
echo "changed=true" >> $GITHUB_OUTPUT
85+
# Otherwise, identify all packages with changes since the last commit
86+
CHANGED_PACKAGES=()
87+
for pkg in $(ls -d packages/*); do
88+
PKG_NAME=$(basename "$pkg")
89+
# For manual runs, include all packages. For automatic runs, only include packages with changes
90+
if [ "$EVENT_NAME" == "workflow_dispatch" ] || ! git diff --quiet $COMMIT_SHA~1 $COMMIT_SHA -- "$pkg/"; then
91+
CHANGED_PACKAGES+=("$PKG_NAME")
92+
fi
93+
done
94+
95+
# Format the output for GitHub Actions matrix using jq
96+
PACKAGES_JSON=$(printf '%s\n' "${CHANGED_PACKAGES[@]}" | jq -R . | jq -s .)
97+
echo "matrix={\"package\":$PACKAGES_JSON}" >> $GITHUB_OUTPUT
9298
fi
9399
100+
publish:
101+
needs: prepare-packages
102+
runs-on: ubuntu-latest
103+
# Use the dynamic matrix from prepare-packages job to create parallel jobs for each package
104+
strategy:
105+
matrix: ${{ fromJson(needs.prepare-packages.outputs.matrix) }}
106+
fail-fast: false # Continue publishing other packages even if one fails
107+
steps:
108+
- name: Harden Runner
109+
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
110+
with:
111+
egress-policy: audit
112+
113+
- name: Checkout repository
114+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
115+
94116
- name: Set up pnpm
95117
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
96118
with:
97119
cache: true
98120

99121
- name: Setup Node.js
100-
if: github.event_name == 'workflow_dispatch' || steps.check_changes.outputs.changed == 'true'
101122
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
102123
with:
103124
node-version-file: '.nvmrc'
104125
registry-url: 'https://registry.npmjs.org'
105126
cache: pnpm
106127

107128
- name: Publish
108-
if: github.event_name == 'workflow_dispatch' || steps.check_changes.outputs.changed == 'true'
109129
working-directory: packages/${{ matrix.package }}
110130
env:
111131
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
112-
run: >
132+
run: |
133+
# Create a unique version using the commit SHA as a prerelease identifier
134+
# This ensures we can publish multiple times from the same codebase with unique versions
113135
npm version --no-git-tag-version 0.0.0-$COMMIT_SHA
136+
# Publish the package to the npm registry with public access flag
114137
pnpm publish --access public
138+
139+
- name: Notify on Manual Release
140+
if: ${{ github.event_name == 'workflow_dispatch' }}
141+
uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661 # 2.3.3
142+
env:
143+
SLACK_COLOR: '#43853D'
144+
SLACK_ICON: https://github.com/nodejs.png?size=48
145+
SLACK_TITLE: ':rocket: Package Published: ${{ matrix.package }}'
146+
SLACK_MESSAGE: |
147+
:package: *Package*: `${{ matrix.package }}` (<https://www.npmjs.com/package/${{ steps.package-info.outputs.name }}|View on npm>)
148+
:bust_in_silhouette: *Published by*: ${{ github.triggering_actor }}
149+
:octocat: *Commit*: <https://github.com/${{ github.repository }}/commit/${{ env.COMMIT_SHA }}|${{ env.COMMIT_SHA }}>
150+
SLACK_USERNAME: nodejs-bot
151+
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}

COLLABORATOR_GUIDE.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
- [General Guidelines for Unit Tests](#general-guidelines-for-unit-tests)
2121
- [General Guidelines for Playwright E2E Tests](#general-guidelines-for-playwright-e2e-tests)
2222
- [General Guidelines for Storybooks](#general-guidelines-for-storybooks)
23+
- [Publishing Packages](#publishing-packages)
2324
- [Remarks on Technologies used](#remarks-on-technologies-used)
2425
- [Seeking additional clarification](#seeking-additional-clarification)
2526

@@ -487,6 +488,18 @@ export default { component: NameOfComponent } as Meta;
487488
- We recommend reading previous Storybooks from the codebase for inspiration and code guidelines.
488489
- If you need to decorate/wrap your Component/Story with a Container/Provider, please use [Storybook Decorators](https://storybook.js.org/docs/react/writing-stories/decorators)
489490

491+
## Publishing Packages
492+
493+
The Node.js Website uses a multi-package workspace architecture where individual packages are published to the npm registry. This section outlines the process for publishing packages and the best practices to follow.
494+
495+
The package publishing process is automated through GitHub Actions and can be triggered in two ways:
496+
497+
1. **Automatically after successful tests**:
498+
When changes are merged to the main branch, the "Publish Packages" workflow runs after the "Linting and Tests" workflow completes successfully. Commits must come through GitHub's merge queue (committer must be verified from [email protected])
499+
500+
2. **Manually via workflow dispatch**:
501+
You can manually trigger publishing for specific packages through the GitHub Actions interface. When manually triggering publishing, ensure the commit hasn't already been published and is safe to do so. In the event of a manual trigger, a Slack notification will be sent to `#nodejs-website`.
502+
490503
## Remarks on Technologies Used
491504

492505
The Node.js Website is a somewhat complex application and at times non-trivial solutions have been implemented to solve certain technical challenges.

0 commit comments

Comments
 (0)