@@ -10,7 +10,7 @@ gh extension install github/gh-actions-pin
1010
1111## Usage
1212
13- Scan every workflow under ` .github/workflows/ ` and pin what it can — pinning
13+ Scan every workflow under ` .github/workflows/ ` and pin what it can -- pinning
1414each resolvable action to an immutable SHA and updating the lockfile:
1515
1616``` bash
@@ -23,7 +23,7 @@ Scope the scan to a single workflow (same default behavior, one file):
2323gh actions-pin .github/workflows/ci.yml
2424```
2525
26- By default, already-pinned workflows are trusted from the lockfile — their
26+ By default, already-pinned workflows are trusted from the lockfile -- their
2727reachability isn't re-checked against upstream. To force a full re-verification
2828of every recorded pin (bypassing that fast path):
2929
@@ -43,7 +43,7 @@ format. Structured results go to stdout, progress to stderr.
4343## How it works
4444
4545GitHub Actions is a package manager that forgot to ship a lockfile. Your
46- workflows are the manifest — every ` uses: ` line is a dependency, resolved by
46+ workflows are the manifest -- every ` uses: ` line is a dependency, resolved by
4747mutable tag or branch * at runtime* , on GitHub's servers, with no record of what
4848actually ran. ` gh-actions-pin ` supplies the missing half: ` .github/workflows/actions.lock ` ,
4949the Actions analogue of ` go.sum ` or ` package-lock.json ` . Each run resolves every
@@ -88,6 +88,66 @@ flowchart TD
8888The security guarantee lives in ** Verifying reachability** : a SHA pin is only
8989trustworthy if that commit is reachable from the tag/branch it claims to come
9090from. A SHA that resolves but isn't in the ref's history is an * impostor commit*
91- — the fork-network attack ` gh-actions-pin ` exists to catch — and it's flagged
91+ -- the fork-network attack ` gh-actions-pin ` exists to catch -- and it's flagged
9292rather than silently trusted.
9393
94+ ## Development
95+
96+ ### Build
97+
98+ ``` bash
99+ make build
100+ ```
101+
102+ ### Tests
103+
104+ ``` bash
105+ make test # Go unit tests
106+ make test-integration # all integration scenarios (stub + live)
107+ make test-stub # stub scenarios only (no network, fast)
108+ make test-live # live repo scenarios only (clones real repos)
109+ ```
110+
111+ ### Interactive shell
112+
113+ The test shell is a REPL for rapid iteration. It runs scenarios through a PTY
114+ so you see real ANSI output, spinners, and colors exactly as a user would.
115+
116+ ``` bash
117+ make test-shell
118+ ```
119+
120+ Inside the shell:
121+
122+ ```
123+ pin-test > list # show all scenarios by category
124+ pin-test > run happy_path # run a scenario with live PTY output
125+ pin-test > happy_path # shorthand -- bare name works too
126+ pin-test > run github/github # ad-hoc test against any repo
127+ pin-test > run all # run every scenario
128+ pin-test > build # rebuild the binary without leaving
129+ pin-test > inspect lockfile_fresh # show fixtures without running
130+ pin-test > diff # git diff from the last run
131+ pin-test > profile on # enable CPU/trace profiling
132+ pin-test > auth # show current auth source
133+ pin-test > help # full command list
134+ ```
135+
136+ Live scenarios and ad-hoc repo runs require GitHub auth. The shell uses
137+ ` gh auth token ` automatically, or you can set ` GH_TOKEN ` explicitly.
138+
139+ ### Scenario catalog
140+
141+ All scenarios are defined in ` test/scenarios/catalog.yml ` and consumed by both
142+ the Go test suite (` test/scenarios/catalog_test.go ` ) and the Ruby integration
143+ harness (` test/integration/run.rb ` ). Add new scenarios to the YAML -- both
144+ sides pick them up.
145+
146+ ### Environment variables
147+
148+ | Variable | Purpose |
149+ | ---| ---|
150+ | ` GH_TOKEN ` / ` GITHUB_TOKEN ` | Auth token for live tests (falls back to ` gh auth token ` ) |
151+ | ` GH_ACTIONS_PIN_WORKFLOWS_DIR ` | Override the workflows directory to scan (lab/testing use) |
152+ | ` KEEP_FIXTURES ` | Keep temp dirs after test runs for debugging |
153+
0 commit comments