diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..f39d00c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,64 @@ +name: CI + +on: + push: + branches: [master] + pull_request: + workflow_dispatch: # Allow manual trigger + +# Least privilege: this workflow only ever reads the tree. Declared +# explicitly rather than inherited, so a change to the repository's default +# token permissions cannot silently widen what a PR-triggered run can do. +permissions: + contents: read + +# A newer push to the same branch supersedes an in-flight run. +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + name: node ${{ matrix.node }}${{ matrix.bun && ' + bun' || '' }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + # Floor of the supported range (package.json engines) and current. + node: ['20', '24'] + # Buddy's rescue path reproduces Claude Code's Bun.hash() by shelling + # out to `bun`, and falls back to FNV-1a when Bun is absent. A bare + # runner only ever exercises the fallback, so the Bun branch shipped + # untested — and shipped broken: `bun -e