Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 64 additions & 7 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# has shipped, build it through the shared release pipeline and publish
# the result as the rolling `nightly` PRERELEASE.
#
# gate ──(build=true)──▶ release-pipeline.yml ──▶ install-smoke ×3
# gate ──(build=true)──▶ release-pipeline.yml ──▶ install-smoke ×4
#
# - `gate` runs scripts/nightly-gate.sh: skip iff HEAD is exactly the
# newest `v*` tag (main is fully released) or exactly the current
Expand All @@ -14,8 +14,10 @@
# channel: nightly (build-time QUARTO_VERSION_OVERRIDE, rolling tag,
# prerelease, nightly install notes). Every release gate applies.
# - `install-smoke` then runs the README one-liners with the nightly
# flag on linux, macOS and Windows against the just-published release
# and asserts `q2 --version` reports the gate's version: the
# flag on linux, macOS and Windows (x64 and ARM64) against the
# just-published release and asserts `q2 --version` reports the
# gate's version, and on Windows that the installer picked the
# runner's native architecture: the
# end-to-end check the AGENTS.md rule asks for, every night, and the
# only CI that exercises install.sh/install.ps1 against a real release.
#
Expand Down Expand Up @@ -142,7 +144,16 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-15, windows-latest]
os: [ubuntu-latest, macos-15, windows-latest, windows-11-arm]
include:
# PE machine type install.ps1 must have picked on each Windows
# runner: 0x8664 = x64, 0xAA64 = ARM64. On windows-11-arm this
# is what catches a missing or misnamed windows_arm64 asset,
# which the installer's x64 fallback would otherwise paper over.
- os: windows-latest
pe_machine: '8664'
- os: windows-11-arm
pe_machine: 'AA64'
env:
EXPECTED: ${{ needs.gate.outputs.version }}
RAW_BASE: https://raw.githubusercontent.com/${{ github.repository }}/${{ github.ref_name }}
Expand Down Expand Up @@ -171,15 +182,61 @@ jobs:
exit 1
fi

- name: install.ps1 -Nightly
# Twice: under PowerShell 7 and under Windows PowerShell 5.1 (the
# .NET Framework one most `irm | iex` users run). The architecture
# detection in install.ps1 leans on different APIs in each.
- name: install.ps1 -Nightly (PowerShell 7)
if: runner.os == 'Windows'
shell: pwsh
env:
PE_MACHINE: ${{ matrix.pe_machine }}
run: |
$dest = Join-Path $env:RUNNER_TEMP 'q2-bin'
$dest = Join-Path $env:RUNNER_TEMP 'q2-bin-pwsh'
& ([scriptblock]::Create((irm "$env:RAW_BASE/install.ps1"))) -Nightly -Dest $dest
$raw = & (Join-Path $dest 'q2.exe') --version
$exe = Join-Path $dest 'q2.exe'
$raw = & $exe --version
Write-Host $raw
if (($raw -split '\s+')[-1] -ne $env:EXPECTED) {
Write-Host "::error::installed nightly reports '$raw', expected version $env:EXPECTED"
exit 1
}
# PE header: e_lfanew at 0x3C points at 'PE\0\0', then the
# 2-byte machine field.
$fs = [System.IO.File]::OpenRead($exe)
$b = New-Object byte[] 4096
[void]$fs.Read($b, 0, $b.Length)
$fs.Close()
$machine = '{0:X4}' -f [BitConverter]::ToUInt16($b, [BitConverter]::ToInt32($b, 0x3C) + 4)
Write-Host "q2.exe PE machine: 0x$machine"
if ($machine -ne $env:PE_MACHINE) {
Write-Host "::error::install.ps1 installed a 0x$machine binary on this runner, expected 0x$env:PE_MACHINE"
exit 1
}

- name: install.ps1 -Nightly (Windows PowerShell 5.1)
if: runner.os == 'Windows'
shell: powershell
env:
PE_MACHINE: ${{ matrix.pe_machine }}
run: |
$dest = Join-Path $env:RUNNER_TEMP 'q2-bin-powershell'
& ([scriptblock]::Create((irm "$env:RAW_BASE/install.ps1"))) -Nightly -Dest $dest
$exe = Join-Path $dest 'q2.exe'
$raw = & $exe --version
Write-Host $raw
if (($raw -split '\s+')[-1] -ne $env:EXPECTED) {
Write-Host "::error::installed nightly reports '$raw', expected version $env:EXPECTED"
exit 1
}
# PE header: e_lfanew at 0x3C points at 'PE\0\0', then the
# 2-byte machine field.
$fs = [System.IO.File]::OpenRead($exe)
$b = New-Object byte[] 4096
[void]$fs.Read($b, 0, $b.Length)
$fs.Close()
$machine = '{0:X4}' -f [BitConverter]::ToUInt16($b, [BitConverter]::ToInt32($b, 0x3C) + 4)
Write-Host "q2.exe PE machine: 0x$machine"
if ($machine -ne $env:PE_MACHINE) {
Write-Host "::error::install.ps1 installed a 0x$machine binary on this runner, expected 0x$env:PE_MACHINE"
exit 1
}
24 changes: 18 additions & 6 deletions .github/workflows/release-pipeline.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Release pipeline (bd-c6l13j79), as a REUSABLE workflow (bd-p4ljdp2e):
# web payloads → 5-target binary build → checksummed, signed artifacts →
# web payloads → 6-target binary build → checksummed, signed artifacts →
# GitHub Release. Two callers:
#
# release.yml tag push / dispatch on an existing tag → channel: release
Expand Down Expand Up @@ -447,7 +447,8 @@ jobs:
# target platform — both libc flavors on linux (glibc + Alpine
# node), both mac archs (Rosetta mismatch: x64 q2 under an
# arm64 node and vice versa), both win archs (arm64 Windows
# runs x64 q2 under emulation with a native arm64 node).
# can run either q2 under either node: x64 binaries run there
# under emulation, and older releases ship only the x64 one).
# NOTE the keyring lists stay libc-plural even though q2 itself
# is now musl-only: the addon must match the user's *node*, and
# an Alpine user runs a musl node while a Debian user runs a
Expand Down Expand Up @@ -487,6 +488,16 @@ jobs:
ext: zip
keyring: win32-x64-msvc,win32-arm64-msvc
cargo_flags: ''
# Native ARM64 build (bd-windows-arm64-nightly-xms5p652). Built
# on an arm runner rather than cross-compiled from
# windows-latest: an x64 Windows host cannot execute an ARM64
# binary, and the verify steps below must run it.
- platform: windows_arm64
target: aarch64-pc-windows-msvc
os: windows-11-arm
ext: zip
keyring: win32-arm64-msvc,win32-x64-msvc
cargo_flags: ''
steps:
- uses: actions/checkout@v6
with:
Expand Down Expand Up @@ -584,8 +595,8 @@ jobs:
cargo build --release --locked --target ${{ matrix.target }} -p quarto ${{ matrix.cargo_flags }}

# Every target in the matrix can execute on its runner (musl
# binaries are static; darwin x86_64 runs under Rosetta; windows
# runs natively), so these checks are unconditional. `shell: bash`
# binaries are static; darwin x86_64 runs under Rosetta; both
# windows legs run natively), so these checks are unconditional. `shell: bash`
# uses Git Bash on the windows runner.
#
# Beyond braid's version check, this is the anti-stale-embed /
Expand Down Expand Up @@ -820,7 +831,7 @@ jobs:
- name: Compare hashes across platforms
run: |
cd asset-hashes
EXPECTED="linux_amd64 linux_arm64 darwin_amd64 darwin_arm64 windows_amd64"
EXPECTED="linux_amd64 linux_arm64 darwin_amd64 darwin_arm64 windows_amd64 windows_arm64"
for platform in $EXPECTED; do
f="asset-manifest-hashes-$platform.txt"
if [ ! -f "$f" ]; then
Expand Down Expand Up @@ -869,7 +880,7 @@ jobs:
# "<platform>:<ext>" — Windows ships .zip, the rest .tar.gz.
for entry in linux_amd64:tar.gz linux_arm64:tar.gz \
darwin_amd64:tar.gz darwin_arm64:tar.gz \
windows_amd64:zip; do
windows_amd64:zip windows_arm64:zip; do
platform="${entry%%:*}"; ext="${entry##*:}"
for f in "q2-${VERSION}-${platform}.${ext}" \
"q2-${VERSION}-${platform}.${ext}.sha256"; do
Expand Down Expand Up @@ -981,6 +992,7 @@ jobs:
echo "| macOS Intel | \`q2-${VERSION}-darwin_amd64.tar.gz\` |"
echo "| macOS Apple Silicon | \`q2-${VERSION}-darwin_arm64.tar.gz\` |"
echo "| Windows x86_64 | \`q2-${VERSION}-windows_amd64.zip\` |"
echo "| Windows ARM64 | \`q2-${VERSION}-windows_arm64.zip\` |"
echo
echo "**Verify a manual download** (Unix archives are signed with [minisign](https://jedisct1.github.io/minisign/), Ed25519):"
echo
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Release (bd-c6l13j79): tag push (or manual dispatch on an existing tag)
# → preflight (tag must equal the workspace Cargo.toml version) → the
# shared release pipeline (release-pipeline.yml: web payloads → 5-target
# shared release pipeline (release-pipeline.yml: web payloads → 6-target
# build → checksummed, signed artifacts → GitHub Release).
#
# The build/verify/sign/publish jobs live in release-pipeline.yml
Expand Down
14 changes: 11 additions & 3 deletions claude-notes/instructions/release-runbook.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ discover.

## What a release produces

A GitHub Release at tag `vX.Y.Z` with, for five platforms
A GitHub Release at tag `vX.Y.Z` with, for six platforms
(`linux_amd64`, `linux_arm64`, `darwin_amd64`, `darwin_arm64`,
`windows_amd64`):
`windows_amd64`, `windows_arm64`):

- `q2-<version>-<platform>.tar.gz` (`.zip` on Windows) — just the `q2`
binary; the hub MCP server, preview SPA, trace viewer, and the docs
Expand Down Expand Up @@ -192,7 +192,7 @@ git tag -a vX.Y.Z -m "q2 vX.Y.Z" && git push origin vX.Y.Z
```

Re-pushing the tag re-fires the workflow from the new commit. The
`release` job only publishes when **all five** legs succeed, so a
`release` job only publishes when **all six** legs succeed, so a
partial run leaves no half-published release.

### 6. Verify the published release
Expand Down Expand Up @@ -314,6 +314,14 @@ section is what to know when the two interact.
no musl prebuilts — both musl legs 404'd at the v8 download in the
v0.1.0 dry-run, which is why the matrix was gnu from PR #280 until
bd-dofxhzaj. That dependency was removed in bd-3e3sam51.
- **Windows ships two native builds**: `windows_amd64`
(`x86_64-pc-windows-msvc` on `windows-latest`) and `windows_arm64`
(`aarch64-pc-windows-msvc` on `windows-11-arm`). The ARM64 leg builds
natively for the same reason `linux_arm64` does: an x64 host cannot
execute an ARM64 binary, and the verify steps run it. `install.ps1`
picks the asset from the OS architecture and falls back to
`windows_amd64` (which ARM64 Windows runs under emulation) for releases
that predate the ARM64 asset (bd-windows-arm64-nightly-xms5p652).
- **Because the binaries are static, the runner image no longer sets a
compatibility floor.** The old `ubuntu-22.04` pin existed *only* to
keep the glibc requirement low; with musl it bought nothing, so the
Expand Down
Loading
Loading