mirror of
https://github.com/Routstr/routstrd.git
synced 2026-10-30 07:37:40 +00:00
`bun build --compile` appends its standalone payload after the linker's ad-hoc signature, so the embedded CodeDirectory no longer describes the bytes on disk. macOS 15+ validates code pages lazily and SIGKILLs the process on the first mismatching page (`Killed: 9`, exit 137). The kernel logs it as: CODE SIGNING: rejecting invalid page ... (signed:1 validated:0 tainted:1) Every standalone artifact we ship has this defect. Whether a given copy dies at launch is luck: the bad page is the last one, which is cold padding in some builds and hot startup code in others. The released v0.4.14 darwin-arm64 binary was killed on every invocation, including `--help` and `--version`, which also broke install.sh's version check. Re-signing ad-hoc restores a valid signature without touching the payload, and leaves already-valid signatures (for example a proper Developer ID signature) untouched. - install.sh: add ensure_valid_signature(), run after staging and before the version check. Only touches Mach-O files on Darwin, and only when codesign --verify fails. - release.yml: repair the signature on macOS runners after the build and before the smoke test, so the packaged artifact is signed. - standalone-update.ts: run ensureValidSignature() before verifyCandidate, which would otherwise hit the same SIGKILL during self-update. - isMachO() reads only the four magic bytes rather than loading the whole binary, which is tens of megabytes. Verified end to end: a fresh `bun build --compile` artifact reports an invalid signature, and after repair both `codesign --verify` and the binary itself succeed. install.sh repairs a broken binary and no-ops on an already-valid one.
148 lines
4.8 KiB
YAML
148 lines
4.8 KiB
YAML
name: Release
|
|
|
|
on:
|
|
pull_request:
|
|
workflow_dispatch:
|
|
push:
|
|
tags:
|
|
- "v*"
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
validate:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
persist-credentials: false
|
|
- uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: 1.4.0
|
|
- run: bun install --frozen-lockfile
|
|
- name: Verify tag version
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
run: |
|
|
package_version="$(bun -p "require('./package.json').version")"
|
|
test "${GITHUB_REF_NAME}" = "v${package_version}"
|
|
- run: bun run lint
|
|
- run: bun test
|
|
|
|
build:
|
|
needs: validate
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- runner: ubuntu-24.04
|
|
target: bun-linux-x64
|
|
platform: linux
|
|
arch: x64
|
|
- runner: ubuntu-24.04-arm
|
|
target: bun-linux-arm64
|
|
platform: linux
|
|
arch: arm64
|
|
- runner: macos-15-intel
|
|
target: bun-darwin-x64
|
|
platform: darwin
|
|
arch: x64
|
|
- runner: macos-15
|
|
target: bun-darwin-arm64
|
|
platform: darwin
|
|
arch: arm64
|
|
runs-on: ${{ matrix.runner }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
persist-credentials: false
|
|
- uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: 1.4.0
|
|
- run: bun install --frozen-lockfile
|
|
- name: Build standalone executable
|
|
run: >-
|
|
bun build --compile
|
|
--target=${{ matrix.target }}
|
|
--no-compile-autoload-dotenv
|
|
--no-compile-autoload-bunfig
|
|
src/index.ts
|
|
--outfile=build/routstrd
|
|
- name: Repair code signature (macOS)
|
|
if: runner.os == 'macOS'
|
|
run: |
|
|
# bun build --compile appends the standalone payload after the
|
|
# linker's ad-hoc signature, leaving the CodeDirectory stale. macOS
|
|
# validates code pages lazily and SIGKILLs the process on the first
|
|
# mismatching page, so re-sign before the smoke test runs the binary.
|
|
# A no-op when the artifact is already validly signed.
|
|
if codesign --verify build/routstrd >/dev/null 2>&1; then
|
|
echo "Existing signature verifies; leaving it untouched."
|
|
else
|
|
echo "Repairing stale ad-hoc signature on build/routstrd."
|
|
codesign --force --sign - --timestamp=none build/routstrd
|
|
codesign --verify --strict build/routstrd
|
|
fi
|
|
- name: Smoke test executable
|
|
run: |
|
|
package_version="$(bun -p "require('./package.json').version")"
|
|
test "$(build/routstrd --version)" = "${package_version}"
|
|
build/routstrd --help >/dev/null
|
|
- name: Package executable
|
|
run: |
|
|
package_version="$(bun -p "require('./package.json').version")"
|
|
tar -C build -czf \
|
|
"routstrd-v${package_version}-${{ matrix.platform }}-${{ matrix.arch }}.tar.gz" \
|
|
routstrd
|
|
- uses: actions/upload-artifact@v4
|
|
with:
|
|
name: routstrd-${{ matrix.platform }}-${{ matrix.arch }}
|
|
path: routstrd-*.tar.gz
|
|
if-no-files-found: error
|
|
|
|
release:
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
needs: build
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
persist-credentials: false
|
|
- uses: actions/download-artifact@v4
|
|
with:
|
|
pattern: routstrd-*
|
|
merge-multiple: true
|
|
- name: Create checksums
|
|
run: shasum -a 256 routstrd-*.tar.gz > SHA256SUMS
|
|
- name: Serve artifacts for installer smoke test
|
|
run: |
|
|
version="${GITHUB_REF_NAME#v}"
|
|
mkdir -p "serve/v${version}"
|
|
cp "routstrd-v${version}-linux-x64.tar.gz" SHA256SUMS "serve/v${version}/"
|
|
- name: Smoke test install.sh against the built artifacts
|
|
run: |
|
|
version="${GITHUB_REF_NAME#v}"
|
|
python3 -m http.server 8137 --bind 127.0.0.1 --directory serve &
|
|
server_pid=$!
|
|
trap 'kill "${server_pid}"' EXIT
|
|
sleep 1
|
|
sh install.sh \
|
|
--version "${version}" \
|
|
--platform linux \
|
|
--arch x64 \
|
|
--dir /tmp/routstrd-install-smoke \
|
|
--download-base-url http://127.0.0.1:8137
|
|
test "$(/tmp/routstrd-install-smoke/routstrd --version)" = "${version}"
|
|
- name: Publish GitHub Release
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: >-
|
|
gh release create "${GITHUB_REF_NAME}"
|
|
routstrd-*.tar.gz SHA256SUMS install.sh
|
|
--repo "${GITHUB_REPOSITORY}"
|
|
--verify-tag
|
|
--generate-notes
|
|
--title "${GITHUB_REF_NAME}"
|