-
Notifications
You must be signed in to change notification settings - Fork 0
390 lines (352 loc) · 18.8 KB
/
Copy pathrelease.yml
File metadata and controls
390 lines (352 loc) · 18.8 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
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
# .github/workflows/release.yml
#
# On git tag v* — build release binaries for all tier-1 targets and
# upload them to a GitHub Release as tar.gz archives.
#
# File naming convention: cobrust-v{version}-{target_triple}-{cpu_level}.tar.gz
# Binary inside archive: cobrust (or cobrust.exe on Windows)
#
# v0.7.0 tier-1 platform contract (ADR-0070 X.6 — the LLVM-default wheel set;
# each binary dynamically links system LLVM 18, see the wheel README below):
# - x86_64-unknown-linux-gnu Linux x86_64 (glibc dynamic)
# - aarch64-apple-darwin macOS arm64 (Apple Silicon)
#
# ADR-0065 Tier 3 CPU-level matrix: 5 wheel variants per tag at v0.7.0
# x86_64-unknown-linux-gnu: v1 (baseline) | v3 (haswell / AVX2+FMA) | v4 (skylake-avx512)
# aarch64-apple-darwin: m1 (Apple M1/M2 base) | m2 (Apple M2 Pro+ / M3+)
#
# DEFERRED at v0.7.0 (ADR-0070 X.6 / finding F77): the LLVM-default flip (X.3)
# + Cranelift-AOT removal (X.4) leave no backend that statically musl-links
# (apt libLLVM is glibc-dynamic) or cross-compiles aarch64 (the `cross` image
# lacks a target-arch libLLVM). Restore in v0.7.x (native ubuntu-24.04-arm
# runner for aarch64-linux; a static-musl libLLVM for musl):
# - x86_64-unknown-linux-musl v1 (static baseline) | v3 (static AVX2)
# - aarch64-unknown-linux-gnu neon (all ARMv8-A) | sve (Graviton3 / Altra)
#
# Queued (documented as cargo install --git path, not built):
# - x86_64-apple-darwin macOS x86_64 Intel
# - x86_64-pc-windows-msvc Windows x86_64 MSVC — DEFERRED to ADR-0058b followup
name: Release
on:
push:
tags:
- "v*"
env:
CARGO_TERM_COLOR: always
RUSTFLAGS: "-D warnings"
jobs:
# -------------------------------------------------------------------------
# Build tier-1 targets — ADR-0065 Tier 3 CPU-level matrix (Phase O wave-1)
# 5 wheel variants at v0.7.0 (ADR-0070 X.6 LLVM-default set; musl + cross
# aarch64 deferred per F77): each matrix entry has cpu_level + rustflags_extra.
# asset_suffix drives the archive name per ADR-0065 §3.2 naming convention.
# -------------------------------------------------------------------------
build-tier1:
name: Build ${{ matrix.target }} [${{ matrix.cpu_level }}]
runs-on: ${{ matrix.os }}
# F98 backstop. The "Post-package smoke gate" step below RUNS the packaged
# binary, so this job is a spawn-and-wait surface; an unbounded wait would
# burn GitHub's 6-hour default job timeout and stall the release. Generous
# (release builds do LLVM + cross + musl from a cold cache). See
# docs/agent/findings/f98-tuple-owned-str-field-hangs-on-linux.md.
timeout-minutes: 90
strategy:
fail-fast: true
matrix:
include:
# ---- x86_64-unknown-linux-gnu: v1 / v3 / v4 ----------------------
# v1: baseline, runs on all x86-64 hardware (ADR-0046 existing triple)
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
use_cross: false
install_musl_tools: false
cpu_level: v1
rustflags_extra: "-C target-cpu=x86-64"
asset_suffix: x86_64-unknown-linux-gnu-v1
# v3: Haswell+; AVX2 + FMA (ADR-0065 §3.1)
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
use_cross: false
install_musl_tools: false
cpu_level: v3
rustflags_extra: "-C target-cpu=haswell"
asset_suffix: x86_64-unknown-linux-gnu-v3
# v4: Skylake-AVX512; data-centre / HPC (ADR-0065 §3.1)
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
use_cross: false
install_musl_tools: false
cpu_level: v4
rustflags_extra: "-C target-cpu=skylake-avx512"
asset_suffix: x86_64-unknown-linux-gnu-v4
# ---- DEFERRED at v0.7.0 (ADR-0070 X.6 / finding F77) --------------
# The x86_64-unknown-linux-musl (v1/v3) + aarch64-unknown-linux-gnu
# (neon/sve) wheels are DEFERRED at v0.7.0. The LLVM-default flip
# (ADR-0070 X.3) + the Cranelift-AOT removal (X.4) leave NO backend
# that (a) statically musl-links — apt `libLLVM` is glibc-dynamic,
# incompatible with a fully-static musl binary — or (b) cross-compiles
# via `cross`, whose default image lacks a target-arch libLLVM (and
# host-arch llvm-sys cannot satisfy an aarch64 link). v0.7.0 ships the
# 5 wheels that build with a straightforward system LLVM 18:
# x86_64-linux-gnu {v1,v3,v4} + aarch64-apple-darwin {m1,m2}.
# Restoring the deferred 4 (native `ubuntu-24.04-arm` runner for
# aarch64-linux; a static-musl libLLVM for musl) is v0.7.x work
# tracked in docs/agent/findings/f77-llvm-default-blocks-musl-cross-wheels.md.
# ---- aarch64-apple-darwin: m1 / m2 --------------------------------
# m1: Apple M1 / M2 base (ADR-0065 §3.1)
- target: aarch64-apple-darwin
os: macos-latest
use_cross: false
install_musl_tools: false
cpu_level: m1
rustflags_extra: "-C target-cpu=apple-m1"
asset_suffix: aarch64-apple-darwin-m1
# m2: Apple M2 Pro+ / M3+ (ADR-0065 §3.1)
- target: aarch64-apple-darwin
os: macos-latest
use_cross: false
install_musl_tools: false
cpu_level: m2
rustflags_extra: "-C target-cpu=apple-m2"
asset_suffix: aarch64-apple-darwin-m2
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: dtolnay/rust-toolchain@stable # stable 2025-01
with:
toolchain: 1.94.1
targets: ${{ matrix.target }}
- uses: Swatinem/rust-cache@v2 # v2.7.8
with:
key: ${{ matrix.target }}-${{ matrix.cpu_level }}
# LLVM 18 is required since ADR-0070 X.3 flipped cobrust-codegen
# `default = ["llvm"]`; inkwell `llvm18-1` links system LLVM via
# llvm-sys, which reads LLVM_SYS_181_PREFIX (mirrors ci.yml). The
# v0.7.0 release matrix ships only targets a straightforward system
# LLVM 18 satisfies (x86_64-linux-gnu native + aarch64-apple native);
# the musl-static + cross-aarch64 wheels are deferred (matrix comment
# + finding F77).
- name: Install LLVM 18 (Ubuntu)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y llvm-18 llvm-18-dev libpolly-18-dev libzstd-dev
echo "LLVM_SYS_181_PREFIX=/usr/lib/llvm-18" >> "$GITHUB_ENV"
- name: Install LLVM 18 (macOS)
if: runner.os == 'macOS'
run: |
brew install llvm@18 || brew upgrade llvm@18 || true
echo "LLVM_SYS_181_PREFIX=$(brew --prefix llvm@18)" >> "$GITHUB_ENV"
- name: Install musl-tools (Linux musl static build)
if: matrix.install_musl_tools
run: sudo apt-get update -qq && sudo apt-get install -y musl-tools
- name: Install cross (Linux arm64)
if: matrix.use_cross
run: cargo install cross --git https://github.com/cross-rs/cross
- name: Build release binary (cross)
if: matrix.use_cross
env:
# CARGO_TARGET_*_RUSTFLAGS only applies to target compilation,
# NOT to build scripts (which run on the host CPU). This prevents
# SIGILL when build.rs is compiled with AVX-512 flags on runners
# that lack AVX-512 support (e.g. ubuntu-latest for v4 wheel).
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS: "-D warnings ${{ matrix.rustflags_extra }}"
run: |
# ADR-0070 X.5 (v0.7.0): the transitional -shim crates are DELETED.
# cobrust-lsp + cobrust-dap are lib-only crates reached via the
# `cobrust lsp` / `cobrust dap` subcommands of the single `cobrust`
# binary (ADR-0068 single-binary collapse). The wheel ships only
# `bin/cobrust`.
# ADR-0069 v0.6.0: same release.yml builds the prebuilt
# libcobrust_stdlib.a (via cobrust-cli build.rs invoking
# cobrust-stdlib's staticlib target).
cross build --release --locked -p cobrust-cli --target ${{ matrix.target }}
- name: Build release binary (native)
if: ${{ !matrix.use_cross }}
env:
# CARGO_TARGET_*_RUSTFLAGS only applies to target compilation,
# NOT to build scripts (which run on the host CPU). This prevents
# SIGILL when build.rs is compiled with AVX-512 flags on runners
# that lack AVX-512 support (e.g. ubuntu-latest for v4 wheel).
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS: "-D warnings ${{ matrix.rustflags_extra }}"
CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUSTFLAGS: "-D warnings ${{ matrix.rustflags_extra }}"
CARGO_TARGET_AARCH64_APPLE_DARWIN_RUSTFLAGS: "-D warnings ${{ matrix.rustflags_extra }}"
run: |
# ADR-0070 X.5 (v0.7.0): see cross build above — single `cobrust`
# binary only; the -shim crates are deleted.
cargo build --release --locked -p cobrust-cli --target ${{ matrix.target }}
- name: Package tar.gz (ADR-0069 FHS layout)
shell: bash
run: |
set -euo pipefail
VERSION="${GITHUB_REF_NAME#v}"
# ADR-0065 §3.2 naming: cobrust-<version>-<triple>-<cpu_level>.tar.gz
ARCHIVE="cobrust-v${VERSION}-${{ matrix.asset_suffix }}.tar.gz"
RELEASE_DIR="target/${{ matrix.target }}/release"
# ADR-0069 §4.1 wheel-layout: bin/, lib/cobrust/, share/cobrust/runtime/
STAGE="cobrust-v${VERSION}"
rm -rf "$STAGE"
mkdir -p "$STAGE/bin" "$STAGE/lib/cobrust" "$STAGE/share/cobrust/runtime"
# ADR-0070 X.5 (v0.7.0): single `cobrust` binary only — the
# standalone cobrust-lsp / cobrust-dap shim binaries are deleted;
# their surfaces live on as `cobrust lsp` / `cobrust dap` subcommands.
cp "${RELEASE_DIR}/cobrust" "$STAGE/bin/cobrust"
# libcobrust_stdlib.a is built by cobrust-cli's build.rs invoking
# the cobrust-stdlib staticlib target — locate it via the OUT_DIR
# bake artifact under target/<triple>/release/build/cobrust-cli-*/out/
STDLIB_ARCHIVE=$(find "target/${{ matrix.target }}/release/build" -path "*/cobrust-cli-*/out/cobrust-stdlib-build/release/libcobrust_stdlib.a" -print -quit)
if [[ -z "${STDLIB_ARCHIVE}" || ! -f "${STDLIB_ARCHIVE}" ]]; then
echo "::error::cannot locate libcobrust_stdlib.a built by cobrust-cli build.rs"
find "target/${{ matrix.target }}/release/build" -name "libcobrust_stdlib.a" -print 2>/dev/null || true
exit 1
fi
cp "${STDLIB_ARCHIVE}" "$STAGE/lib/cobrust/libcobrust_stdlib.a"
cp crates/cobrust-cli/runtime/cobrust_main.c "$STAGE/share/cobrust/runtime/"
cp crates/cobrust-cli/runtime/cpu_features.c "$STAGE/share/cobrust/runtime/"
# Tar the single top-level directory (ADR-0069 §4.1 self-contained tree).
tar czf "${ARCHIVE}" "$STAGE"
echo "ARCHIVE=${ARCHIVE}" >> "$GITHUB_ENV"
echo "STAGE_DIR=${STAGE}" >> "$GITHUB_ENV"
echo "Packaged tree:"
(cd "$STAGE" && find . -maxdepth 4 | sort)
# ADR-0069 §4.3 + F46 §3 — post-package smoke gate. Extract the
# tarball at the same path users would (relative to a clean dir),
# write a one-line .cb source, run `cobrust run` on it, assert
# stdout matches "smoke". Failure fails the job BEFORE artifact
# upload, so broken wheels never reach the GH Release.
#
# Native-only: cross-compiled tarballs cannot execute their own
# binary on the build host. Cross-compile correctness is verified
# post-publish by user-side install tests.
- name: Post-package smoke gate (ADR-0069 §4.3 + F46 §3)
if: ${{ !matrix.use_cross }}
shell: bash
run: |
set -euo pipefail
SMOKE_DIR="$(mktemp -d)"
cp "${ARCHIVE}" "${SMOKE_DIR}/"
cd "${SMOKE_DIR}"
tar xzf "${ARCHIVE}"
ls -R "${STAGE_DIR}"
cat > t.cb <<'EOF_CB'
fn main() -> i64:
print("smoke")
return 0
EOF_CB
"${STAGE_DIR}/bin/cobrust" run t.cb 2>&1 | tee out.txt
if ! grep -q "^smoke$" out.txt; then
echo "::error::post-package smoke gate FAILED: 'smoke' not in stdout"
echo "stdout was:"
cat out.txt
exit 1
fi
echo "post-package smoke gate PASS"
- name: Upload artifact
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with:
name: cobrust-${{ matrix.asset_suffix }}
path: ${{ env.ARCHIVE }}
retention-days: 1
# -------------------------------------------------------------------------
# Build best-effort targets (non-blocking)
# NOTE: x86_64-pc-windows-msvc removed from this matrix in Phase K Strand #5.
# Windows MSVC is now classified as "queued" pending ADR-0058b (stable runner
# + test-suite parity + packaging convention decision).
#
# Job intentionally OMITTED: GitHub Actions rejects `matrix.include: []` with
# "matrix must define at least one vector" at workflow-validation time —
# this fires BEFORE `if: false` job-skip evaluation, so a no-op skeleton
# cannot be retained. Re-add the entire `build-best-effort:` job (with at
# least one matrix entry) when the next tier-2 target lands.
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# Create GitHub Release and upload all artifacts
# -------------------------------------------------------------------------
release:
name: Publish GitHub Release
runs-on: ubuntu-latest
timeout-minutes: 30 # F98 backstop — download + checksum + publish only
needs: [build-tier1]
# Run after best-effort too when available; but don't gate on it.
permissions:
contents: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Download all artifacts
uses: actions/download-artifact@v4 # v4.1.8
with:
path: dist/
merge-multiple: true
- name: List artifacts
run: ls -lh dist/
# W4 (ADR-0065 §7.4): generate SHA256SUMS file for all wheel archives so
# the registry-gen index builder can populate WheelEntry.sha256.
# `sha256sum` output format: "<hex> <filename>" (two spaces, GNU coreutils).
- name: Generate SHA256SUMS
run: |
cd dist/
sha256sum cobrust-v*.tar.gz > SHA256SUMS
echo "SHA256SUMS contents:"
cat SHA256SUMS
- name: Create GitHub Release
uses: softprops/action-gh-release@v2 # v2.2.1
with:
tag_name: ${{ github.ref_name }}
name: "Cobrust ${{ github.ref_name }}"
body: |
## Installation
v0.6.0 adopts the FHS-ish `bin/lib/share` wheel layout per
ADR-0069. Tarballs extract to a single self-contained
`cobrust-${{ github.ref_name }}/` directory.
### Option A — cargo install (requires Rust toolchain)
```bash
cargo install --git https://github.com/Cobrust-lang/cobrust cobrust-cli
```
### Option B — prebuilt wheel (no Rust needed; v0.6.0 layout)
Pick the tarball for your platform + CPU level, extract to a
stable location, and symlink the `cobrust` binary into your
`$PATH`. The runtime + stdlib live in `lib/` + `share/`
siblings; do NOT move the binary out of its `bin/` directory.
```bash
# macOS Apple Silicon M1 (tier-1)
curl -L https://github.com/Cobrust-lang/cobrust/releases/download/${{ github.ref_name }}/cobrust-${{ github.ref_name }}-aarch64-apple-darwin-m1.tar.gz | tar xz -C $HOME/.local/
ln -sf $HOME/.local/cobrust-${{ github.ref_name }}/bin/cobrust $HOME/.local/bin/cobrust
# Linux x86_64 — glibc baseline (tier-1). REQUIRES system LLVM 18
# at runtime (the binary dynamically links libLLVM — ADR-0070 X.3
# made LLVM the default backend). Install it first:
# sudo apt-get install -y libllvm18 # (or: llvm-18)
curl -L https://github.com/Cobrust-lang/cobrust/releases/download/${{ github.ref_name }}/cobrust-${{ github.ref_name }}-x86_64-unknown-linux-gnu-v1.tar.gz | tar xz -C $HOME/.local/
ln -sf $HOME/.local/cobrust-${{ github.ref_name }}/bin/cobrust $HOME/.local/bin/cobrust
# NOTE: the static-musl + aarch64-linux wheels are DEFERRED at
# v0.7.0 (ADR-0070 X.6 / finding F77 — LLVM-default blocks
# static-musl-link + `cross`). On those targets use Option A
# (cargo install) until v0.7.x restores them.
```
Each wheel tarball bundles:
- `bin/cobrust` — the single driver binary; the LSP / DAP servers are the `cobrust lsp` / `cobrust dap` subcommands (ADR-0068). The transitional `cobrust-lsp` / `cobrust-dap` shim binaries were removed at v0.7.0 (ADR-0070 X.5) — IDE extensions must invoke the subcommands.
- `lib/cobrust/libcobrust_stdlib.a` — prebuilt static stdlib archive
- `share/cobrust/runtime/{cobrust_main.c,cpu_features.c}` — runtime C entrypoint + CPU feature helpers
### Option C — Alpine / distroless container (musl static binary)
DEFERRED at v0.7.0: the static-musl wheel is not built (ADR-0070
X.6 / finding F77 — LLVM-default blocks a fully-static musl link).
On Alpine, build from source (Option A, with `llvm18-dev` from the
`community` repo) or use a `glibc`-based image with the
`x86_64-unknown-linux-gnu` wheel + `libllvm18`. The musl wheel
returns in v0.7.x.
### Quick start
```bash
cobrust new hello && cd hello && cobrust run src/main.cb
# → hello, world
```
See [Getting Started](https://github.com/Cobrust-lang/cobrust/blob/main/docs/human/en/getting-started.md) for the full guide.
### Breaking change from v0.5.x
Users who manually `cp cobrust /usr/local/bin/` from a flat
v0.5.x tarball MUST re-install via the new `tar xz` →
`ln -s` flow above. Per F46: the v0.5.x flat-binary wheel
was unusable for `cobrust run` regardless because the
runtime + stdlib were not bundled (binary baked the GH
Actions runner workspace path). v0.6.0 fixes both sides.
files: |
dist/*.tar.gz
dist/SHA256SUMS
draft: false
prerelease: ${{ contains(github.ref_name, '-') }}