Files
pbakaus_impeccable/.github/workflows/release-engine.yml
T
Paul BakausandClaude Fable 5.1 4369ad538d Open the detector: the rule crates join the workspace, the C-ABI goes away
The detector is open source. The rules it ships were already public in this
repo's git history and in every npm tarball of the JS engine, so a closed
binary bought nothing it could keep; the moat is the service (the catalog,
the labs, the review pipeline), not the check functions. Keeping them behind
a prebuilt archive cost a C-ABI, an exact toolchain pin, a build-time
download, a second release to order ahead of every engine release, and a
serde layer that had to serve two encodings.

Deleted
- crates/core/src/ffi.rs, crates/core/build.rs, crates/core/tests/boundary.rs
  and the shim modules under src/checks and src/browser.
- crates/foundation/src/boundary.rs and the postcard dependency.
- DETECTOR_VERSION, scripts/check-detector-release.mjs and its test, the
  check:detector-release script, the detector gate and
  IMPECCABLE_SKIP_DETECTOR_CHECK in scripts/release.mjs.
- scripts/lib/detector-bundle.mjs and tests/detector-bundle.test.mjs (the
  vendoring path for the closed browser bundle).
- scripts/build-browser-detector.js and the build:browser script (a stub
  since the JS engine left the tree).
- xtask's detector-archive subcommand and its public-repo lookup.

Came back
- crates/core is now the rule logic itself: every check_* / scan_*, the
  browser adapters, the visual-contrast decisions. It re-exports foundation
  as before, so no consumer changed. Its vectors dispatcher is the union of
  both id tables again, and tests/vectors.rs replays the frozen vectors
  straight through it.
- crates/wasm and crates/xtask join the workspace. cargo xtask bundle builds
  the in-page bundle from browser-bundle/ plus the wasm core, writes
  dist/, refreshes the tracked crates/live/assets/detect-antipatterns-
  browser.js, and writes extension/detector/. bun run build:extension runs
  it instead of downloading.
- crates/live/assets/detect-antipatterns-browser.js is tracked again; live
  mode embeds it and serves it as /detect.js.
- Serde is back to plain derives: no is_human_readable branch in
  js::json_number, derived Serialize for Rgba and BrowserFinding with their
  skip_serializing_if attributes.
- profile.release has lto = "fat" again; rust-toolchain.toml is plain
  stable plus the wasm32 target. The rust, rust-windows and oracle CI jobs
  lose continue-on-error and can be required.

Verified
- cargo build --workspace --all-targets: clean, no warnings.
- cargo test --workspace: 346 pass, 0 fail (the 8 boundary tests are gone
  with the boundary).
- cargo build -p impeccable-wasm --target wasm32-unknown-unknown --release: ok.
- cargo xtask bundle && cargo xtask bundle --check: reproducible; the
  regenerated bundle is committed (it differs from the archived one, which
  was built with a pinned rustc and lto = false).
- cargo build --release -p impeccable: no linker warnings, 12.5 MB (the
  same source at lto = false is 13.1 MB).
- oracle: 795 pass, 0 fail, 0 accepted deltas, 0 missing goldens.
- bun run build, bun run build:extension, web-ext lint (0 errors,
  8 warnings), bun run test: 363 + 80 + 1 + 1 + 133 + 180 + 4 pass, 0 fail.
- impeccable detect --no-config --json tests/fixtures/antipatterns: 128.7 ms
  median of 5.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vau2X53xGTjjTCXWMVBoNY
2026-09-03 09:11:33 -07:00

88 lines
4.1 KiB
YAML

name: release-engine
# Builds the engine binary for every supported target and publishes them, with
# sha256 sidecars, as the GitHub Release `engine-v<X>` on this repo. That
# release is what the launcher (skill/scripts/impeccable), the npm shim
# (cli/bin/cli.js), `impeccable install`, and `bun run fetch:engine` download.
#
# Trigger: `bun run release:engine` (scripts/release.mjs) verifies
# ENGINE_VERSION, the npm platform-package pins, and a clean tree, then
# pushes the tag. Third-party actions are pinned to commit SHAs so a
# moved tag cannot swap the code this workflow runs.
on:
push:
tags: ['engine-v*']
permissions:
contents: write
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- { os: macos-14, target: aarch64-apple-darwin, short: darwin-arm64 }
# No Intel runner: GitHub retired macos-13. Apple's toolchain builds
# x86_64 on an arm64 host natively once the target is installed.
- { os: macos-14, target: x86_64-apple-darwin, short: darwin-x64 }
- { os: ubuntu-latest, target: x86_64-unknown-linux-musl, short: linux-x64 }
- { os: ubuntu-latest, target: aarch64-unknown-linux-musl, short: linux-arm64, cross: true }
- { os: windows-latest, target: x86_64-pc-windows-msvc, short: windows-x64 }
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
- name: Check the tag matches ENGINE_VERSION
shell: bash
run: |
set -e
want="engine-v$(tr -d '[:space:]' < ENGINE_VERSION)"
[ "$GITHUB_REF_NAME" = "$want" ] || { echo "tag $GITHUB_REF_NAME != $want"; exit 1; }
# rust-toolchain.toml names the channel; `rustup show` installs it.
# Never override the toolchain here.
- name: Install the pinned toolchain
shell: bash
run: rustup show && rustup target add ${{ matrix.target }}
- if: matrix.os == 'ubuntu-latest'
run: sudo apt-get update && sudo apt-get install -y musl-tools
- if: matrix.cross
run: cargo install cross --locked
- name: Build
shell: bash
run: ${{ matrix.cross && 'cross' || 'cargo' }} build --release -p impeccable --target ${{ matrix.target }}
- name: Smoke the binary
if: ${{ !matrix.cross }}
shell: bash
run: target/${{ matrix.target }}/release/impeccable${{ runner.os == 'Windows' && '.exe' || '' }} engine-probe
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: impeccable-${{ matrix.short }}
path: target/${{ matrix.target }}/release/impeccable${{ runner.os == 'Windows' && '.exe' || '' }}
if-no-files-found: error
publish:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with: { path: artifacts }
- name: Lay out release assets with checksums
run: |
set -e
mkdir -p out
for d in artifacts/impeccable-*; do
short=$(basename "$d" | sed 's/^impeccable-//')
f=$(ls "$d" | head -1)
case "$short" in windows-*) dest="out/impeccable-$short.exe" ;; *) dest="out/impeccable-$short" ;; esac
cp "$d/$f" "$dest"
(cd out && sha256sum "$(basename "$dest")" > "$(basename "$dest").sha256")
done
ls -la out
- name: Publish the GitHub Release
env: { GH_TOKEN: "${{ github.token }}" }
# No --clobber: a published asset is immutable. A re-run against an
# existing release fails on the first existing asset instead of
# silently replacing a binary and its sidecar hash.
run: |
set -e
tag="${GITHUB_REF_NAME}"
gh release create "$tag" --repo "$GITHUB_REPOSITORY" --title "impeccable engine $tag" \
--notes "Prebuilt impeccable engine binaries ($tag). The launcher, the npm shim and impeccable install download these on first run. Docs: https://impeccable.style" out/* || \
gh release upload "$tag" out/* --repo "$GITHUB_REPOSITORY"