-
Notifications
You must be signed in to change notification settings - Fork 1
183 lines (166 loc) · 7.32 KB
/
Copy pathrelease.yml
File metadata and controls
183 lines (166 loc) · 7.32 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
name: Release
on:
push:
tags: ["v*"]
permissions:
contents: write
id-token: write
attestations: write
jobs:
# Refuse a tag the manifests do not declare (spec §2). Every publishable
# manifest, not only the one the binary reads its --version from: v0.13.0
# published binaries and no packages because this gate read
# packages/cli/deno.json alone and passed, while publish-packages.yml read all
# of them and refused. The weaker gate was the one standing in front of the
# irreversible half. On failure, the mistake is made visible on the release
# itself, not just in this log.
preflight:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
# Membership is deno.json's name and package.json's private, which is the
# pair scripts/gen-publish-workflow.md selects the publish jobs on. Read
# from package.json's name instead and this gate admits a different set
# than the one that publishes, which is the same partial release by
# another route. Walked rather than listed, so a new package joins by
# existing — which is how packages/git came to be absent from it.
- name: Tag matches every publishable manifest
run: |
TAG="${{ github.ref_name }}"
mismatched=0
for manifest in packages/*/deno.json; do
member="$(dirname "$manifest")"
[ -f "$member/package.json" ] || continue
name="$(jq -r '.name // ""' "$manifest")"
case "$name" in
@executablemd/*) ;;
*) continue ;;
esac
if [ "$(jq -r '.private // false' "$member/package.json")" = "true" ]; then
continue
fi
for declared_in in "$manifest" "$member/package.json"; do
declared="$(jq -r '.version // ""' "$declared_in")"
if [ "v$declared" != "$TAG" ]; then
echo "::error::$declared_in declares $declared but the tag is $TAG — bump the manifests first"
mismatched=1
fi
done
done
[ "$mismatched" -eq 0 ]
- name: Flag the release when the tag cannot build
if: failure()
env:
GH_TOKEN: ${{ github.token }}
run: |
set -u
TAG="${{ github.ref_name }}"
gh release view "$TAG" --json body --jq .body > /tmp/body.md 2>/dev/null || exit 0
{
echo "> [!CAUTION]"
echo "> This release did not build: the manifests do not declare \`${TAG#v}\`."
echo "> Delete this release and its tag, run \`deno task bump ${TAG#v}\`, merge"
echo "> the bump, and release again (release spec §2)."
echo
cat /tmp/body.md
} > /tmp/new.md
gh release edit "$TAG" --prerelease \
--title "$TAG — failed: manifests not bumped" \
--notes-file /tmp/new.md || true
build:
name: Compile ${{ matrix.target }}
needs: preflight
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- target: aarch64-apple-darwin
artifact: xmd-aarch64-apple-darwin
- target: x86_64-apple-darwin
artifact: xmd-x86_64-apple-darwin
- target: x86_64-unknown-linux-gnu
artifact: xmd-x86_64-unknown-linux-gnu
- target: aarch64-unknown-linux-gnu
artifact: xmd-aarch64-unknown-linux-gnu
- target: x86_64-pc-windows-msvc
artifact: xmd-x86_64-pc-windows-msvc.exe
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
- uses: denoland/setup-deno@e95548e56dfa95d4e1a28d6f422fafe75c4c26fb # v2.0.3
with:
deno-version: v2.9.5
# `deno compile` embeds the generated browser bundle by following the
# literal dynamic import, and compiles without complaint when the file is
# absent — producing a binary that cannot serve a form (spec §8).
- name: Install dependencies
run: deno task deps
- name: Build the browser bundle
run: deno task build:web
# The compile below is `--cached-only`, and `deno compile --target`
# resolves the npm packages of the platform it compiles *for* — which host
# preparation never cached. Each job therefore caches its own target's
# graph first; the mapping lives in `scripts/lib/release-targets.ts` and is
# held to this matrix by test.
- name: Prepare the ${{ matrix.target }} dependency graph
run: deno task deps:target ${{ matrix.target }}
# Through `scripts/compile.ts` rather than `deno compile` directly, so the
# entrypoint, the isolation flags and every embedded asset come from
# `scripts/lib/compile.ts` — the same list `deno task build` and
# `verify:clean` compile from. While each site kept its own copy, this one
# named no `components.md` and shipped binaries that could document no
# component at all.
- name: Compile ${{ matrix.target }}
run: |
deno run \
--allow-all \
--node-modules-dir=none \
--cached-only \
--frozen \
scripts/compile.ts \
--target ${{ matrix.target }} \
--output dist/${{ matrix.artifact }}
# A cross-compiled binary cannot be run by the job that produced it, so
# the Linux x64 member is the one place a release can ask a binary it just
# built whether its packaged assets are there. Before the attestation:
# a build that cannot document its own components should never become an
# attested subject, and the whole matrix is `needs:` of `release`.
- name: Smoke test the packaged documentation
if: matrix.target == 'x86_64-unknown-linux-gnu'
run: deno run --allow-all --frozen scripts/smoke-documentation.ts dist/${{ matrix.artifact }}
# Between the compile and the upload, so the provenance covers the bytes
# this job produced and an unattested binary never enters the artifact set
# `release` downloads. The whole matrix is `needs:` of `release`, so a
# failed attestation withholds the release rather than warning about it.
- name: Attest ${{ matrix.artifact }}
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
with:
subject-path: dist/${{ matrix.artifact }}
- name: Upload build artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: ${{ matrix.artifact }}
path: dist/${{ matrix.artifact }}
if-no-files-found: error
release:
name: Publish release
needs: build
runs-on: ubuntu-latest
steps:
- name: Download all binaries
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
path: dist
merge-multiple: true
- name: Generate checksums
working-directory: dist
run: sha256sum xmd-* > checksums.txt
- name: Publish to GitHub Release
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
with:
tag_name: ${{ github.ref_name }}
draft: false
fail_on_unmatched_files: true
files: |
dist/xmd-*
dist/checksums.txt