1- name : Publish Packages
1+ name : Release
2+
3+ # Version + publish via changesets/action. On push to main it either opens/updates
4+ # a "Version Packages" PR (running `changeset version`) or, once that PR is merged
5+ # and no changesets remain, publishes to npm. Merging the PR is the release gate.
6+ # Canary publishes live in publish-canary.yml.
27
38on :
49 push :
510 branches : [main]
6- workflow_dispatch :
7- inputs :
8- dry_run :
9- description : Generate artifacts without uploading to S3
10- type : boolean
11- default : false
1211
1312concurrency :
14- group : publish-packages
13+ group : release
1514 cancel-in-progress : false
1615
1716permissions :
18- id-token : write
19- contents : write
17+ contents : write # push the version-PR branch + tags
18+ pull-requests : write # open/update the Version Packages PR
19+ id-token : write # npm provenance
2020
2121jobs :
22- publish :
23- name : Version & Publish
22+ release :
23+ name : Version & Publish (npm)
2424 runs-on : ubuntu-latest
2525 environment : publish
2626 env :
27- NODE_OPTIONS : ' --test-reporter=spec'
2827 HUSKY : ' 0'
2928 steps :
3029 - uses : actions/checkout@v5
3130 with :
3231 fetch-depth : 0
32+ # Use the ops token so the Version Packages PR triggers CI (a PR opened
33+ # with the default GITHUB_TOKEN does not fire other workflows).
3334 token : ${{ secrets.OPS_GITHUB_TOKEN }}
3435
3536 - uses : actions/setup-node@v5
@@ -38,137 +39,15 @@ jobs:
3839 cache : npm
3940 registry-url : ' https://registry.npmjs.org'
4041
41- # Pin a fixed Blocks CLI telemetry installation ID for CI e2e runs so this
42- # traffic is consistent and identifiable (and can be excluded from product
43- # usage metrics).
44- - uses : ./.github/actions/seed-telemetry-id
45-
4642 - run : npm ci
4743
48- # ── Version bump ──────────────────────────────────────────
49- - name : Run changeset version
50- id : version
51- env :
52- GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
53- run : |
54- npx changeset version
55-
56- # Refresh package-lock.json so its mirrored workspace versions
57- # match the bumps changeset just made. Skips network fetches.
58- npm install --package-lock-only
59-
60- # Check if changeset version produced any changes
61- if git diff --quiet; then
62- echo "changed=false" >> "$GITHUB_OUTPUT"
63- echo "No version bumps — skipping publish"
64- else
65- echo "changed=true" >> "$GITHUB_OUTPUT"
66- fi
67-
68- # ── Build & Test ──────────────────────────────────────────
69- - name : Build
70- if : steps.version.outputs.changed == 'true'
71- run : npm run build
72-
73- - name : E2E Test Local
74- if : steps.version.outputs.changed == 'true'
75- run : npm run test:e2e:local
76-
77- - name : Configure AWS credentials
78- if : steps.version.outputs.changed == 'true'
79- uses : aws-actions/configure-aws-credentials@v6
44+ - uses : changesets/action@a45c4d594aa4e2c509dc14a9f2b3b67ba3780d0d # v1.9.0
8045 with :
81- role-to-assume : ${{ secrets.AWS_ROLE_ARN }}
82- aws-region : us-east-1
83-
84- # ── Commit version bumps ──────────────────────────────────
85- - name : Commit version bumps
86- if : steps.version.outputs.changed == 'true'
87- run : |
88- git config user.name "github-actions[bot]"
89- git config user.email "github-actions[bot]@users.noreply.github.com"
90- git add -A
91- git commit -m "chore: version packages [skip ci]"
92-
93- # Create a tag for each bumped package (with input sanitization)
94- for pkg in packages/*/package.json; do
95- name=$(node -p "require('./$pkg').name")
96- version=$(node -p "require('./$pkg').version")
97-
98- # Validate name and version contain only safe characters
99- if [[ ! "$name" =~ ^@?[a-zA-Z0-9/_.-]+$ ]] || [[ ! "$version" =~ ^[a-zA-Z0-9._-]+$ ]]; then
100- echo "::warning::Skipping tag for $pkg — unexpected characters in name or version"
101- continue
102- fi
103-
104- if [[ "$name" == @aws-blocks/* ]]; then
105- tag="${name}@${version}"
106- git tag "$tag" 2>/dev/null || true
107- fi
108- done
109-
110- # ── Publish ───────────────────────────────────────────────
111- - name : Publish to S3
112- if : steps.version.outputs.changed == 'true' && inputs.dry_run != true
46+ version : npx changeset version && npm install --package-lock-only
47+ publish : npm run release
48+ commit : ' chore: version packages'
49+ title : ' chore: version packages'
11350 env :
114- S3_BUCKET : ${{ vars.S3_BUCKET }}
115- CLOUDFRONT_DOMAIN : ${{ vars.CLOUDFRONT_DOMAIN }}
116- CLOUDFRONT_DISTRIBUTION_ID : ${{ vars.CLOUDFRONT_DISTRIBUTION_ID }}
117- run : npm run publish:s3
118-
119- - name : Publish to npm (dry-run)
120- if : steps.version.outputs.changed == 'true'
121- run : npm run publish:npm -- --dry-run
122-
123- - name : Publish dry-run (local)
124- if : steps.version.outputs.changed == 'true' && inputs.dry_run == true
125- run : npm run publish:dry-run
126-
127- # ── Post-publish ──────────────────────────────────────────
128- - name : Push version commit and tags
129- if : steps.version.outputs.changed == 'true' && inputs.dry_run != true
130- run : |
131- git pull --rebase origin main
132- git push --follow-tags
133-
134- - name : Upload publish manifest
135- if : steps.version.outputs.changed == 'true'
136- uses : actions/upload-artifact@v5
137- with :
138- name : publish-manifest
139- path : |
140- publish-manifest.json
141- dist-registry/publish-manifest.json
142-
143- - name : Summary
144- if : steps.version.outputs.changed == 'true'
145- run : |
146- MANIFEST=""
147- if [ -f publish-manifest.json ]; then
148- MANIFEST="publish-manifest.json"
149- elif [ -f dist-registry/publish-manifest.json ]; then
150- MANIFEST="dist-registry/publish-manifest.json"
151- fi
152-
153- if [ -n "$MANIFEST" ]; then
154- echo "## Published Packages" >> "$GITHUB_STEP_SUMMARY"
155- echo "" >> "$GITHUB_STEP_SUMMARY"
156- PUBLISHED=$(jq -r '.packages[] | "- `\(.name)@\(.version)`"' "$MANIFEST")
157- if [ -n "$PUBLISHED" ]; then
158- echo "$PUBLISHED" >> "$GITHUB_STEP_SUMMARY"
159- else
160- echo "_No new versions to publish (all unchanged)._" >> "$GITHUB_STEP_SUMMARY"
161- fi
162-
163- SKIPPED=$(jq -r '.skipped[]? | "- `\(.name)@\(.version)` (unchanged)"' "$MANIFEST")
164- if [ -n "$SKIPPED" ]; then
165- echo "" >> "$GITHUB_STEP_SUMMARY"
166- echo "### Skipped (unchanged)" >> "$GITHUB_STEP_SUMMARY"
167- echo "" >> "$GITHUB_STEP_SUMMARY"
168- echo "$SKIPPED" >> "$GITHUB_STEP_SUMMARY"
169- fi
170- fi
171-
172- - name : No changes
173- if : steps.version.outputs.changed != 'true'
174- run : echo "No version bumps detected — nothing to publish." >> "$GITHUB_STEP_SUMMARY"
51+ GITHUB_TOKEN : ${{ secrets.OPS_GITHUB_TOKEN }}
52+ NODE_AUTH_TOKEN : ${{ secrets.NPM_TOKEN }}
53+ NPM_CONFIG_PROVENANCE : ' true'
0 commit comments