name: ci on: push: branches: [main] pull_request: jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: # fetch-depth: 0, for the changelog-monotonic step below and only # for it. That check is about a DIFF — which release headings the # merge base had — so it needs the base branch's history present, # and the default depth-1 checkout has none of it. An explicit # `git fetch origin ` would be narrower, but it has to be # right on both event types and on fork PRs, and getting it subtly # wrong degrades to a SKIP (a guard that silently stops guarding — # the exact failure this repo keeps refusing). Full history on a # tree this size costs a second; the STRICT flag below turns any # remaining skip red rather than green. fetch-depth: 0 - uses: actions/setup-node@v4 with: node-version: "22" cache: npm # the secrets tests round-trip a real age identity - run: sudo apt-get update && sudo apt-get install -y age - run: npm ci - run: npm run check - run: npm run build - run: npm test - name: installer is valid bash run: bash -n install.sh bin/cast scripts/*.sh .github/scripts/*.sh - name: labels state-machine tests run: bash test/labels-reconcile.sh # ...and no SHIPPED release heading was deleted (#133; box#122's guard). # Its own step so that when it goes red the log names the invariant that # broke — and a DIFFERENT invariant from the arming rule npm test # carries: arming is a fact about this tree, monotonicity is a fact # about this tree versus its merge base. Pull requests only: on a push # to main the merge base IS HEAD, so the assert is vacuous and would # only add a green step that proves nothing. STRICT=1 so a checkout that # cannot reach the base ref fails here instead of skipping quietly # forever. - name: no shipped changelog heading was deleted if: github.event_name == 'pull_request' env: CHANGELOG_MONOTONIC_STRICT: "1" run: bash .github/scripts/changelog-monotonic.sh "origin/${{ github.base_ref }}" # The installer, proven by RUNNING it — CAST_INSTALL_SOURCE points it at # this checkout, so CI proves the installer under review (the versioned # layout, the current symlink, the PATH chain, the uninstall's absence # assert), not a hand-built imitation of it. Box's CI installs box the # same way. This is the one place the real npm ci + tsc build path runs # end to end; the vitest installer tests cover the layout semantics # offline with a shimmed npm. install: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: "22" cache: npm - name: install via install.sh, from this checkout run: | CAST_NO_MODIFY_PATH=1 CAST_INSTALL_SOURCE="$GITHUB_WORKSPACE" bash install.sh # assert what landed: the layout, the chain, and that it answers readlink -f "$HOME/.local/bin/cast" | grep '/versions/' "$HOME/.local/bin/cast" --version "$HOME/.local/bin/cast" versions - name: converging no-op — a re-run changes nothing and builds nothing run: | CAST_NO_MODIFY_PATH=1 CAST_INSTALL_SOURCE="$GITHUB_WORKSPACE" bash install.sh \ | tee /tmp/rerun.log grep -q 'already installed' /tmp/rerun.log - name: uninstall --all — ends with the absence assert run: | CAST_YES=1 "$HOME/.local/bin/cast" uninstall --all test ! -e "$HOME/.local/share/cast" test ! -e "$HOME/.local/bin/cast" test ! -L "$HOME/.local/bin/cast"