Skip to main content

Development

swift test # unit tests
./scripts/e2e.sh # end-to-end, with fake tools in a throwaway turnstile home
/usr/bin/python3 scripts/e2e-top-tests.py # daemon-free PTY driver checks
node --test scripts/history-report-tests.mjs # isolated report input and SQLite checks

The history-report helper accepts no arguments for a 30-day report or exactly ./scripts/history-report.sh --days <positive-integer>. Invalid arguments exit 2 before reading history or invoking SQLite. The fixture tests use disposable databases.

Pressure and restart E2E fixtures keep fake jobs alive until the required state is observed, then release their wait files and check completion.

The top driver checks exercise a fake CLI in a temporary home. Full E2E reports job visibility, pause, kill confirmation, target removal, UI exit, terminal restoration, driver errors, and caller status separately. Failures print the last status snapshot, PTY tail, and job output.

Docs​

This site lives in website/:

cd website
npm install
npm start

./scripts/record-demo.sh rerecords static/img/demo.svg, the terminal recording in the README and the intro. It runs two builds against a throwaway turnstile home, so the turnstile lines are real output. Rerun it when that output changes.

Releasing​

Bump Turnstile.version in Sources/TurnstileCore/Paths.swift, rename "Unreleased" in CHANGELOG.md to the new version, commit, push, and push a matching tag:

git tag -a v0.5.0 -m "turnstile 0.5.0"
git push origin v0.5.0

The release workflow checks dependency licenses, tests, builds the universal CLI tarball and the notarized Turnstile.app, attests their build provenance, publishes both to a release here and on mcclowes/homebrew-turnstile, with notes from the changelog, and updates the tap's formula and cask. Running the workflow by hand builds, signs, and notarizes without publishing, to check the secrets.

To check a download came from this repo's workflow:

gh attestation verify "$(which turnstile)" --repo mcclowes/turnstile

./scripts/release.sh does the same from a Mac with the Developer ID certificate and the kiln-notary notarytool profile, tagging for you. It stays as a fallback until the workflow has shipped a release.

Release secrets​

The workflow needs these Actions secrets:

SecretWhat it holds
DEVELOPER_ID_P12_BASE64The Developer ID Application certificate and its private key, exported from Keychain Access as a .p12, then base64 -i cert.p12 | pbcopy
DEVELOPER_ID_P12_PASSWORDThe password set when exporting the .p12
NOTARY_API_KEY_P8_BASE64An App Store Connect API key (Users and Access → Integrations, Developer access), the .p8 base64-encoded
NOTARY_API_KEY_IDThat key's ID
NOTARY_API_ISSUER_IDThe issuer ID shown above the keys
TAP_GITHUB_TOKENA fine-grained token for mcclowes/homebrew-turnstile alone, with Contents read and write, to publish its release and push the formula and cask

Releases on this repo use the workflow's own token.