-
Notifications
You must be signed in to change notification settings - Fork 0
148 lines (132 loc) · 6.22 KB
/
Copy pathrelease.yml
File metadata and controls
148 lines (132 loc) · 6.22 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
name: Release
# Conventional-Commit-driven releases, fully in CI. On every push to `main`,
# semantic-release inspects the commits since the last release and, when they
# warrant one (feat → minor, fix → patch, `!`/BREAKING → major):
# - runs the full gate (typecheck / test / reproducible bundle),
# - computes the next version, syncs it across package.json / src/types.ts,
# rebuilds the bundle (scripts/sync-version.mjs + pnpm build),
# - commits the bump back to `main` as `chore(release): <v> [skip ci]`,
# - tags `v<version>` and creates the GitHub release with auto notes.
# Consumers pin these tags: their sync-engine scripts fetch
# scripts/engine.mjs + scripts/engine.d.mts at a tag and verify ENGINE_VERSION.
#
# Image publish note: the `chore(release): <v> [skip ci]` commit and the
# `v<version>` tag above are both pushed by semantic-release using
# GITHUB_TOKEN — GitHub's anti-recursion protection means neither triggers
# `on: push` / `on: push: tags:` / `on: release:` workflows. So the
# ghcr.io/maxgfr/codeindex image can't be built from a separate
# tag/release-triggered workflow; instead this same job builds and pushes it
# right after `semantic-release` runs, gated on the `.release-version`
# sentinel file that `.releaserc.json`'s `@semantic-release/exec` publishCmd
# writes only when a release actually happened.
on:
push:
branches: [main]
permissions:
contents: write
issues: write
pull-requests: write
id-token: write
packages: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: true
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
# npm trusted publishing (OIDC) needs npm >= 11.5.1, shipped with node 24.
node-version: 24
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Gate — typecheck / test / reproducible bundle
run: |
pnpm run typecheck
pnpm test
pnpm run check:build
- name: Release (semantic-release)
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: pnpm exec semantic-release
# `.release-version` only exists when semantic-release actually cut a
# release this run (written by the exec plugin's publishCmd) — most
# pushes to main are not releases (docs/chore/no-op commits), so this
# is what tells us whether to publish an image at all.
- name: Check whether a release was published
id: release
run: |
if [ -f .release-version ]; then
echo "released=true" >> "$GITHUB_OUTPUT"
echo "version=$(cat .release-version)" >> "$GITHUB_OUTPUT"
else
echo "released=false" >> "$GITHUB_OUTPUT"
fi
- name: Set up QEMU
if: steps.release.outputs.released == 'true'
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
if: steps.release.outputs.released == 'true'
uses: docker/setup-buildx-action@v3
- name: Log in to ghcr.io
if: steps.release.outputs.released == 'true'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Build from the tag semantic-release just pushed (the release commit),
# not from the run's HEAD: HEAD here is the pre-release commit that
# `semantic-release` amended-past when it pushed `chore(release): ...`
# (that push doesn't update this checkout), so the tag is the only ref
# in this workspace that actually points at the released bundle.
- name: Check out release tag v${{ steps.release.outputs.version }}
if: steps.release.outputs.released == 'true'
run: |
git fetch origin tag "v${{ steps.release.outputs.version }}"
git checkout "v${{ steps.release.outputs.version }}"
# Multi-arch, pushed straight to the registry. This runs after the
# npm publish + GitHub release above, so a failure here (e.g. transient
# QEMU/buildx flakiness on the arm64 leg) never rolls back or blocks
# the already-completed release — it only fails this workflow run,
# which is exactly the visibility we want. Left blocking (no
# continue-on-error) on purpose: a silently-skipped image publish is
# worse than a red run we have to re-trigger.
- name: Build and push distribution image
if: steps.release.outputs.released == 'true'
run: |
VERSION="${{ steps.release.outputs.version }}"
docker buildx build \
--platform linux/amd64,linux/arm64 \
--build-arg VERSION="$VERSION" \
--push \
-t ghcr.io/maxgfr/codeindex:"$VERSION" \
-t ghcr.io/maxgfr/codeindex:latest \
.
# Package the committed tree-sitter wasm grammars (scripts/grammars/, ~22 MB)
# as a per-release asset so a consumer that vendors ONLY the zero-dependency
# engine.mjs can `codeindex grammars pull` them into its shared cache and get
# byte-identical AST extraction. Same conditional-on-release-cut gate as the
# image above, and built from the checked-out release tag so the wasms match
# the released bundle exactly. Reproducible tar (sorted, fixed owner/mtime,
# gzip -n) + a `.sha256` sidecar that `grammars pull` fetches and verifies.
- name: Package and upload grammars asset
if: steps.release.outputs.released == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ steps.release.outputs.version }}"
ASSET="grammars-${VERSION}.tar.gz"
tar --sort=name --owner=0 --group=0 --numeric-owner \
--mtime='UTC 2020-01-01' \
-cf "grammars-${VERSION}.tar" -C scripts/grammars .
gzip -n "grammars-${VERSION}.tar"
sha256sum "$ASSET" | awk '{print $1}' > "${ASSET}.sha256"
gh release upload "v${VERSION}" "$ASSET" "${ASSET}.sha256" --clobber
- name: Return to release commit
if: always() && steps.release.outputs.released == 'true'
run: git checkout ${{ github.sha }}