Skip to content

Commit d145222

Browse files
committed
harden release workflow
1 parent 303aa7e commit d145222

File tree

2 files changed

+116
-38
lines changed

2 files changed

+116
-38
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: 'setup'
2+
description: 'composite for shared job setup'
3+
inputs:
4+
node-version:
5+
description: 'node version'
6+
default: '24'
7+
install-deps:
8+
description: 'install deps'
9+
default: 'true'
10+
11+
runs:
12+
using: composite
13+
steps:
14+
# the following 2 steps are a replacement for pnpms own setup action that contains a lot of code
15+
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
16+
with:
17+
node-version: ${{inputs.node-version}}
18+
package-manager-cache: false
19+
- name: install pnpm
20+
shell: bash
21+
run: |
22+
PNPM_VER=$(jq -r '.packageManager | if .[0:5] == "pnpm@" then .[5:] else "packageManager in package.json does not start with pnpm@\n" | halt_error(1) end' package.json)
23+
echo installing pnpm version $PNPM_VER
24+
npm i --ignore-scripts -g pnpm@$PNPM_VER
25+
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
26+
if: ${{inputs.install-deps == 'true'}}
27+
with:
28+
node-version: ${{inputs.node-version}}
29+
package-manager-cache: true
30+
- name: install dependencies
31+
if: ${{inputs.install-deps == 'true'}}
32+
shell: bash
33+
run: pnpm install --frozen-lockfile --ignore-scripts

.github/workflows/release.yml

Lines changed: 83 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,57 +4,102 @@ on:
44
push:
55
branches:
66
- main
7+
78
permissions: {}
89

910
jobs:
10-
release:
11+
checks:
1112
permissions:
12-
contents: write # to create release (changesets/action)
13-
id-token: write # OpenID Connect token needed for provenance
14-
pull-requests: write # to create pull request (changesets/action)
15-
# prevents this action from running on forks
13+
contents: read
1614
if: github.repository == 'sveltejs/vite-plugin-svelte'
17-
name: Release
18-
runs-on: ${{ matrix.os }}
19-
strategy:
20-
matrix:
21-
# pseudo-matrix for convenience, NEVER use more than a single combination
22-
node: [24]
23-
os: [ubuntu-latest]
15+
name: Checks
16+
runs-on: ubuntu-latest
2417
steps:
25-
- name: checkout
26-
uses: actions/checkout@v5
18+
- name: Harden the runner
19+
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
2720
with:
28-
# This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
29-
fetch-depth: 0
30-
- uses: actions/setup-node@v5
21+
egress-policy: block
22+
allowed-endpoints: >
23+
api.github.com:443
24+
github.com:443
25+
release-assets.githubusercontent.com:443
26+
registry.npmjs.org:443
27+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
3128
with:
32-
node-version: ${{ matrix.node }}
33-
package-manager-cache: false # pnpm is not installed yet
34-
- name: install pnpm
35-
shell: bash
36-
run: |
37-
PNPM_VER=$(jq -r '.packageManager | if .[0:5] == "pnpm@" then .[5:] else "packageManager in package.json does not start with pnpm@\n" | halt_error(1) end' package.json)
38-
echo installing pnpm version $PNPM_VER
39-
npm i -g pnpm@$PNPM_VER
40-
- uses: actions/setup-node@v5
41-
with:
42-
node-version: ${{ matrix.node }}
43-
package-manager-cache: true # caches pnpm via packageManager field in package.json
44-
- name: install
45-
run: pnpm install --frozen-lockfile --prefer-offline --ignore-scripts
29+
persist-credentials: 'false'
30+
- uses: ./.github/actions/setup-node
4631
- name: generated types are up to date
4732
run: pnpm generate:types && [ "`git status --porcelain=v1`" == "" ]
4833
- name: publint
4934
run: pnpm check:publint
5035

51-
- name: Create Release Pull Request or Publish to npm
36+
changesets:
37+
needs: checks
38+
permissions:
39+
contents: write # to create releases (changesets/action)
40+
pull-requests: write # to create version pull requests (changesets/action)
41+
name: Changesets
42+
runs-on: ubuntu-latest
43+
outputs:
44+
published: ${{steps.changesets.outputs.published}}
45+
publishedPackages: ${{steps.changesets.outputs.publishedPackages}}
46+
steps:
47+
- name: Harden the runner
48+
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
49+
with:
50+
egress-policy: block
51+
allowed-endpoints: >
52+
api.github.com:443
53+
github.com:443
54+
release-assets.githubusercontent.com:443
55+
registry.npmjs.org:443
56+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
57+
with:
58+
persist-credentials: 'false'
59+
- uses: ./.github/actions/setup-node
60+
- uses: changesets/action@e0145edc7d9d8679003495b11f87bd8ef63c0cba # v1.5.3
5261
id: changesets
53-
# pinned for security, always review third party action code before updating
54-
uses: changesets/action@e0145edc7d9d8679003495b11f87bd8ef63c0cba # v1.5.3
5562
with:
56-
# This expects you to have a script called release which does a build for your packages and calls changeset publish
57-
publish: pnpm release
63+
publish: pnpm exec changeset tag #only create git tag, publish to registry happens later
5864
env:
59-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
60-
NPM_CONFIG_PROVENANCE: true
65+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # needed for some github api calls changesets makes
66+
publish:
67+
needs: changesets
68+
if: needs.changesets.outputs.published == 'true'
69+
permissions:
70+
contents: read
71+
id-token: write
72+
environment: release
73+
name: Publish
74+
runs-on: ubuntu-latest
75+
steps:
76+
- name: Harden the runner
77+
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
78+
with:
79+
egress-policy: block
80+
allowed-endpoints: >
81+
api.github.com:443
82+
github.com:443
83+
release-assets.githubusercontent.com:443
84+
registry.npmjs.org:443
85+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
86+
with:
87+
persist-credentials: 'false'
88+
- uses: ./.github/actions/setup-node
89+
with:
90+
install-deps: 'false'
91+
- name: publish
92+
shell: bash
93+
run: |
94+
echo 'publishing ${{needs.changesets.outputs.publishedPackages}}'
95+
96+
# generate "--filter package1 --filter package2"
97+
PUBLISH_PACKAGES_FILTER=$(echo '${{needs.changesets.outputs.publishedPackages}}' | jq -r '.[] | " --filter " + "\"" + .name+ "\""' | xargs)
98+
99+
if [[ -f .changeset/pre.json ]]; then
100+
TAG=$(jq -r '.tag' .changeset/pre.json)
101+
else
102+
TAG=latest
103+
fi
104+
# publish
105+
pnpm -r --no-bail $PUBLISH_PACKAGES_FILTER publish --no-git-checks --tag $TAG --access public

0 commit comments

Comments
 (0)