Skip to content

Commit d417899

Browse files
authored
ci(release): harden security [AR-63091] (#467)
Restructure the release workflow so only the publish part has access to the OIDC token. See: https://tanstack.com/blog/npm-supply-chain-compromise-postmortem
1 parent c4d5afd commit d417899

3 files changed

Lines changed: 81 additions & 18 deletions

File tree

.github/actions/install/action.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
name: Install
22
description: Install Node.js, pnpm, and dependencies
33

4+
inputs:
5+
skip-install:
6+
description: Skip installation of dependencies
7+
required: false
8+
default: false
9+
410
runs:
511
using: composite
612
steps:
@@ -15,6 +21,7 @@ runs:
1521
node-version-file: .nvmrc
1622

1723
- name: Install Dependencies
24+
if: ${{ inputs.skip-install != 'true' }}
1825
shell: bash
1926
env:
2027
# Skip Husky installation.

.github/workflows/release.yml

Lines changed: 74 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ concurrency: ${{ github.workflow }} @ ${{ github.ref }}
1010
permissions: {}
1111

1212
jobs:
13-
release:
14-
name: Release
13+
prepare:
14+
name: Prepare
1515
runs-on: ubuntu-latest
1616

1717
if: github.repository_owner == 'drivenets'
@@ -20,7 +20,9 @@ jobs:
2020
contents: write # to create release (changesets/action)
2121
issues: write # to post issue comments (changesets/action)
2222
pull-requests: write # to create pull request (changesets/action)
23-
id-token: write # for npm trusted publishing
23+
24+
outputs:
25+
should-publish: ${{ steps.changesets.outputs.hasChangesets == 'false' }}
2426

2527
steps:
2628
- name: Checkout source code
@@ -29,21 +31,33 @@ jobs:
2931
fetch-depth: 0
3032
filter: 'blob:none'
3133

32-
- name: Install pnpm
33-
uses: pnpm/action-setup@91ab88e2619ed1f46221f0ba42d1492c02baf788 # v6.0.6
34-
with:
35-
cache: true
34+
- name: Install Dependencies
35+
uses: ./.github/actions/install
3636

37-
- name: Install Node.js
38-
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
37+
- name: Create or update release PR
38+
id: changesets
39+
uses: changesets/action@63a615b9cd06ba9a3e6d13796c7fbcb080a60a0b # v1.8.0
3940
with:
40-
node-version-file: .nvmrc
41+
commit: 'chore(release): publish'
42+
title: 'chore(release): publish'
4143

42-
- name: Ensure updated npm
43-
run: npm install -g npm@11.7.0 # npm >= 11.5.1 is required for trusted publishing
44+
build:
45+
name: Build for publish
46+
needs: prepare
47+
if: needs.prepare.outputs.should-publish == 'true'
48+
runs-on: ubuntu-latest
49+
50+
permissions:
51+
contents: read
52+
53+
steps:
54+
- name: Checkout source code
55+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
56+
with:
57+
persist-credentials: false
4458

4559
- name: Install Dependencies
46-
run: pnpm i
60+
uses: ./.github/actions/install
4761

4862
- name: Cache turbo
4963
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
@@ -53,11 +67,54 @@ jobs:
5367
restore-keys: |
5468
${{ runner.os }}-turbo-build-
5569
56-
- name: Create release PR or publish
70+
- name: Build packages
71+
run: pnpm build
72+
73+
- name: Upload build
74+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
75+
with:
76+
name: release-build
77+
path: packages/*/dist
78+
if-no-files-found: error
79+
retention-days: 1
80+
include-hidden-files: false
81+
82+
# WARNING:
83+
# For security reasons, this is the only job that should have `id-token: write` permissions.
84+
# We don't want dependencies and build scripts to have access to this token.
85+
publish:
86+
name: Publish
87+
needs: build
88+
runs-on: ubuntu-latest
89+
90+
permissions:
91+
contents: write # to create release (changesets/action)
92+
id-token: write # for npm trusted publishing
93+
94+
steps:
95+
- name: Checkout source code
96+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
97+
98+
- name: Install Dependencies
99+
uses: ./.github/actions/install
100+
with:
101+
skip-install: true
102+
103+
- name: Ensure updated npm
104+
run: npm install -g npm@11.7.0 # npm >= 11.5.1 is required for trusted publishing
105+
106+
- name: Install changeset
107+
run: pnpm install -g @changesets/cli@^2.30.0
108+
109+
- name: Download build
110+
uses: actions/download-artifact@484a0b528fb4d7bd804637ccb632e47a0e638317 # v8.0.1
111+
with:
112+
name: release-build
113+
path: packages
114+
115+
- name: Publish
57116
uses: changesets/action@63a615b9cd06ba9a3e6d13796c7fbcb080a60a0b # v1.8.0
58117
with:
59-
publish: pnpm run release
60-
commit: 'chore(release): publish'
61-
title: 'chore(release): publish'
118+
publish: changeset publish
62119
env:
63120
NPM_TOKEN: '' # https://github.com/changesets/action/issues/542#issuecomment-3642334398

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
"build": "turbo run build",
2424
"build:storybook": "turbo run build:storybook",
2525
"changelog": "changeset",
26-
"release": "pnpm build && changeset publish",
2726
"prepare": "husky",
2827
"pre-commit": "lint-staged"
2928
},

0 commit comments

Comments
 (0)