-
Notifications
You must be signed in to change notification settings - Fork 268
220 lines (199 loc) · 8.79 KB
/
Copy pathpublish-preview.yml
File metadata and controls
220 lines (199 loc) · 8.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
name: Publish preview build
# BUILD WORKFLOW. Builds a labeled PR and packs its packages into a workflow
# artifact. It holds no secrets and no OIDC permission, so it is safe to run
# for a pull request from a fork.
#
# Despite the name, it publishes nothing. Publishing happens in
# publish-preview-register.yml, which triggers when this workflow completes and
# runs from the default branch. The split exists because GitHub denies fork
# pull_request runs both secrets and `id-token`, so a fork PR cannot
# authenticate to the bridge from here at all.
#
# The `preview-build` label check below is a convenience gate that saves build
# minutes. It is NOT the security boundary: on pull_request events GitHub runs
# the workflow file from the merge ref, so a PR author can edit this file and
# delete the check. publish-preview-register.yml re-establishes authorization
# from the API.
#
# NOTE: the workflow NAME above is what publish-preview-register.yml matches on.
# Renaming it silently stops preview publishing.
#
# Registered builds: https://registry-bridge.viteplus.dev/-/refs
permissions: {}
on:
pull_request:
types: [labeled]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
prepare:
if: >-
github.repository == 'voidzero-dev/vite-plus' &&
github.event.label.name == 'preview-build'
name: Compute preview metadata
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
version: ${{ steps.version.outputs.version }}
docs-origin: ${{ steps.docs.outputs.origin }}
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: .node-version
package-manager-cache: false
- name: Test preview documentation origin
run: node --test .github/scripts/__tests__/preview-docs-origin.mjs
- name: Resolve preview documentation origin
id: docs
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
with:
script: |
const { previewDocsOrigin } = await import(`${process.env.GITHUB_WORKSPACE}/.github/scripts/preview-docs-origin.ts`);
core.setOutput('origin', previewDocsOrigin(context.payload.pull_request));
# Use the exact version the registry bridge serves (0.0.0-commit.<head-sha>,
# the same head SHA publish-preview-register.yml registers), so the built
# Rust binary and JS
# dist carry the version that actually gets installed: CARGO_PKG_VERSION and
# cliPkg.version both equal it, instead of the build-time release placeholder.
# `napi pre-publish` reuses this for consistent optionalDependencies entries.
- name: Compute version
id: version
run: echo "version=0.0.0-commit.${{ github.event.pull_request.head.sha }}" >> "$GITHUB_OUTPUT"
build-rust:
name: Build bindings and binaries
if: >-
github.repository == 'voidzero-dev/vite-plus' &&
github.event.label.name == 'preview-build'
needs: prepare
permissions:
contents: read
uses: ./.github/workflows/reusable-release-build.yml
with:
version: ${{ needs.prepare.outputs.version }}
docs-origin: ${{ needs.prepare.outputs.docs-origin }}
cache-key: pkg-pr-new
publish:
if: >-
github.repository == 'voidzero-dev/vite-plus' &&
github.event.label.name == 'preview-build'
name: Pack preview packages
runs-on: ubuntu-latest
needs:
- prepare
- build-rust
# Read-only, and deliberately no `id-token`. Everything that needs a write
# permission (the sticky comment, the Docker image) moved to the trusted
# workflow, because fork pull_request runs are denied those permissions
# anyway.
permissions:
contents: read
env:
VERSION: ${{ needs.prepare.outputs.version }}
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: ./.github/actions/clone
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: .node-version
package-manager-cache: false
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
# The registry bridge rewrites dependencies by package name. Stamp core
# before pnpm pack so the dependency named `vite` already aliases the
# preview version. Keep the CLI manifest aligned with its built dist too.
- name: Set preview package versions
run: |
for package in cli core; do
pnpm exec json-edit "packages/$package/package.json" '_.version = process.env.VERSION'
done
- name: Download cli dist
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: packages/cli/dist
pattern: cli
merge-multiple: true
- name: Download cli docs
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: packages/cli/docs
pattern: cli-docs
merge-multiple: true
- name: Download cli binding
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: packages/cli/artifacts
pattern: vite-plus-native-*
- name: Download core dist
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: packages/core/dist
pattern: core
merge-multiple: true
- name: Download prompts dist
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: packages/prompts/dist
pattern: prompts
merge-multiple: true
- uses: ./.github/actions/download-rolldown-binaries
with:
github-token: ${{ github.token }}
target: x86_64-unknown-linux-gnu
upload: 'false'
- name: Download Rust CLI binaries
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: rust-cli-artifacts
pattern: vp-global-cli-*
# Stops short of `npm publish` and leaves packages/cli/{npm,cli-npm}/*
# on disk for the bridge action to pack.
- name: Prepare native addon and CLI binary packages
run: node ./packages/cli/publish-native-addons.ts --mode pkg-pr-new
# Pack the locally built package directories (the two preview packages
# and every platform binary) into a workflow artifact. `mode: pack` runs
# `pnpm pack` and nothing else: no network, no credentials. The trusted
# workflow validates every archive, rewrites and re-packs it under the commit
# version, and uploads it.
#
# Runs for fork PRs too. That is the point of the split: the old
# same-repo gate here existed only because fork runs cannot read the
# admin token secret.
- name: Pack packages for the registry bridge
uses: voidzero-dev/pkg-pr-registry-bridge@4ca2c31c250c7137ae191bf01a8bb106d30aa106 # main
with:
mode: pack
# The PR head commit, not the merge commit github.sha. Advisory here;
# the publishing workflow re-derives it from workflow_run.head_sha.
sha: ${{ github.event.pull_request.head.sha }}
output-dir: bridge-packages
# The locally built directories to pack. Listed here rather than left
# to the action's default, so the published set is reviewable in this
# repo and does not move when the action does.
packages: |
packages/cli/npm/*
packages/cli/cli-npm/*
packages/cli
packages/core
packages/prompts
- name: Upload packed packages
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: bridge-packages
path: bridge-packages
# A silently empty artifact would make the publishing workflow fail with a
# confusing "no packed tarballs" instead of failing here.
if-no-files-found: error
# Must outlive the approval wait, not just the run. The publishing
# publish job is gated on a required-reviewer environment, and GitHub
# keeps a pending deployment open far longer than a day, so a
# retention of 1 would let the artifact expire out from under an
# approval given the next morning.
retention-days: 7
# The payload is already-gzipped .tgz files, so re-deflating them costs
# time for no size gain.
compression-level: 0