1name: Release
2
3on:
4 workflow_dispatch:
5 inputs:
6 version:
7 description: >-
8 Release spec. `beta` (the default) publishes the next
9 `2.0.0-beta.N`; `beta.N` publishes that exact candidate. `rc[.N]`
10 and `alpha[.N]` select those prerelease channels.
11 `patch|minor|major` or `x.y.z` publishes a stable release. Anything
12 else publishes `0.0.0-<name>`.
13 required: false
14 type: string
15 default: "beta"
16 force-latest:
17 description: Publish the release under the latest dist-tag
18 required: false
19 type: boolean
20 default: true
21
22concurrency:
23 group: release-${{ github.ref }}
24 cancel-in-progress: false
25
26permissions:
27 contents: write
28 id-token: write
29
30env:
31 ALCHEMY_REPO: alchemy-run/alchemy
32
33jobs:
34 build:
35 name: Build and pack
36 runs-on: blacksmith-8vcpu-ubuntu-2404
37 outputs:
38 sha: ${{ steps.commit.outputs.sha }}
39 tag: ${{ steps.release.outputs.tag }}
40 version: ${{ steps.release.outputs.version }}
41 channel: ${{ steps.release.outputs.channel }}
42 steps:
43 - name: Generate bot token
44 id: bot-token
45 uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
46 with:
47 app-id: ${{ secrets.ALCHEMY_VERSION_BOT_ID }}
48 private-key: ${{ secrets.ALCHEMY_VERSION_BOT_PRIVATE_KEY }}
49
50 - name: Checkout repository
51 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
52 with:
53 fetch-depth: 0
54 token: ${{ steps.bot-token.outputs.token }}
55
56 - name: Checkout distilled
57 run: git submodule update --init --depth=1 --checkout -- submodules/distilled
58
59 - name: Restore Turbo cache
60 uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
61 with:
62 path: .turbo
63 key: turbo-${{ runner.os }}-${{ github.repository_id }}-${{ github.sha }}-${{ github.workflow }}-${{ github.run_attempt }}
64 restore-keys: |
65 turbo-${{ runner.os }}-${{ github.repository_id }}-${{ github.sha }}-
66 turbo-${{ runner.os }}-${{ github.repository_id }}-
67
68 - name: Setup pnpm, Node.js, Bun and install dependencies
69 uses: pnpm/setup@703c52620218391530e48b9e8870d5c0082e1b9b # v2.1.0
70 with:
71 cache: true
72 install: true
73 require-lockfile: true
74
75 - id: release
76 name: Prepare release
77 env:
78 FORCE_LATEST: ${{ inputs.force-latest }}
79 run: |
80 set -euo pipefail
81 bun scripts/release/prepare.ts '${{ inputs.version }}' | tee -a "$GITHUB_OUTPUT"
82
83 - name: Build release packages
84 # Match preview CI: the cold tsgo build can starve the runner
85 # without Go heap limits on this 32 GB machine.
86 env:
87 GOMEMLIMIT: 6GiB
88 GOGC: "40"
89 run: >-
90 pnpm turbo run build
91 $(jq -r '.[] | "--filter=\(.name)"' release-packages.json)
92
93 - name: Pack release artifacts
94 run: |
95 set -euo pipefail
96 mkdir release-packages
97 while IFS= read -r dir; do
98 pnpm --dir "$dir" pack --pack-destination "$GITHUB_WORKSPACE/release-packages"
99 done < <(jq -r '.[].dir' release-packages.json)
100
101 - id: commit
102 name: Commit and tag
103 env:
104 VERSION: ${{ steps.release.outputs.version }}
105 CHANNEL: ${{ steps.release.outputs.channel }}
106 GITHUB_TOKEN: ${{ github.token }}
107 run: bash scripts/release/commit.sh
108
109 - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
110 with:
111 name: release-packages
112 path: release-packages/*.tgz
113 if-no-files-found: error
114 retention-days: 7
115
116 publish:
117 name: Publish
118 needs: build
119 runs-on: ubuntu-latest
120 steps:
121 - name: Checkout repository
122 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
123 with:
124 ref: ${{ needs.build.outputs.sha }}
125 fetch-depth: 0
126
127 - name: Checkout distilled
128 run: git submodule update --init --depth=1 --checkout -- submodules/distilled
129
130 - name: Setup pnpm, Node.js, Bun
131 uses: pnpm/setup@703c52620218391530e48b9e8870d5c0082e1b9b # v2.1.0
132 with:
133 cache: true
134 install: false
135
136 # Release scripts import changelogithub, but publishing does not need
137 # package lifecycle scripts or the root Turbo-backed prepare build.
138 - name: Install dependencies
139 run: pnpm install --frozen-lockfile --ignore-scripts
140
141 - name: Remove token-based npm authentication
142 run: sed -i '/always-auth/d' ~/.npmrc 2>/dev/null || true
143
144 - name: Download release artifacts
145 uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
146 with:
147 name: release-packages
148 path: release-packages
149
150 - name: Publish tarballs with OIDC
151 env:
152 PUBLISH_TAG: ${{ needs.build.outputs.tag }}
153 CHANNEL_TAG: ${{ needs.build.outputs.channel == 'release' && 'latest' || needs.build.outputs.channel == 'tag' && needs.build.outputs.tag || 'next' }}
154 FORCE_LATEST: ${{ inputs.force-latest }}
155 NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
156 run: bash scripts/release/publish.sh
157
158 - name: Create GitHub release
159 if: needs.build.outputs.channel != 'tag'
160 env:
161 GITHUB_TOKEN: ${{ github.token }}
162 VERSION: ${{ needs.build.outputs.version }}
163 CHANNEL: ${{ needs.build.outputs.channel }}
164 run: bun scripts/release/github-release.ts "v${VERSION}" "$CHANNEL"
165
166 - name: Notify Discord
167 if: needs.build.outputs.channel != 'tag'
168 env:
169 DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_URL }}
170 VERSION: ${{ needs.build.outputs.version }}
171 CHANNEL: ${{ needs.build.outputs.channel }}
172 run: bun scripts/release/discord-notify.ts "v${VERSION}" "$CHANNEL"