faf-taf-git 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/dependabot.yml +10 -0
- package/.github/workflows/ci.yml +3 -3
- package/.github/workflows/claude-code-review.yml +9 -2
- package/.github/workflows/claude.yml +2 -2
- package/CHANGELOG.md +17 -1
- package/CLAUDE.md +3 -3
- package/README.md +92 -473
- package/action.yml +4 -1
- package/agent.fafa +53 -0
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.js +123 -5
- package/dist/index.js.map +1 -1
- package/dist/parsers/index.d.ts +1 -0
- package/dist/parsers/index.d.ts.map +1 -1
- package/dist/parsers/index.js +11 -5
- package/dist/parsers/index.js.map +1 -1
- package/dist/parsers/junit.d.ts +22 -0
- package/dist/parsers/junit.d.ts.map +1 -0
- package/dist/parsers/junit.js +104 -0
- package/dist/parsers/junit.js.map +1 -0
- package/package.json +4 -4
- package/project.faf +13 -1
- package/src/cli.ts +1 -1
- package/src/index.ts +1 -0
- package/src/parsers/index.ts +9 -4
- package/src/parsers/junit.ts +110 -0
- package/tests/junit-parser.test.ts +109 -0
package/README.md
CHANGED
|
@@ -5,557 +5,176 @@
|
|
|
5
5
|
|
|
6
6
|
[](https://github.com/Wolfe-Jam/faf-taf-git)
|
|
7
7
|
[](https://github.com/anthropics/claude-code-action)
|
|
8
|
+
[](https://wolfe-jam.github.io/agent-business-card/?repo=Wolfe-Jam/faf-taf-git)
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
**A receipt printer for your tests.**
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
Every time your tests run in CI, faf-taf-git writes a small receipt: when they ran, how many passed, failed and were skipped. The receipts are saved in your repo, one after another, on their own branch. Over time they show whether your tests really kept passing.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
Anyone can get green once. Receipts show it over time.
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
> **Q: What sort of Receipts?** A: Test Receipts.
|
|
17
|
-
> **Q: Why do I need Test Receipts?** A: Proof over time.
|
|
18
|
-
>
|
|
19
|
-
> *Bonus: Cannot be gamed.*
|
|
16
|
+
`npm: faf-taf-git` · `GitHub Action: Wolfe-Jam/faf-taf-git` · MIT, free
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
## Why
|
|
22
19
|
|
|
23
|
-
**
|
|
20
|
+
- **Test results usually vanish.** CI shows today's run, then the log expires. Receipts stay.
|
|
21
|
+
- **You can look back.** When did that test start failing? Was main green before the last release?
|
|
22
|
+
- **Other people can check.** Users, reviewers, auditors and AI agents can read the history themselves instead of taking your word for it.
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
## What a receipt looks like
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
Receipts are saved in a file called `.taf`, on a branch called `taf-receipts`:
|
|
28
27
|
|
|
29
|
-
## 🎯 WHAT
|
|
30
|
-
|
|
31
|
-
**A Test Receipt Printer for git.** Every CI run produces one receipt — timestamp, counts, result, trigger — appended to `.taf` on the `taf-receipts` branch. The timeline is the proof.
|
|
32
|
-
|
|
33
|
-
**Example Test Receipt:**
|
|
34
28
|
```yaml
|
|
35
|
-
- timestamp: 2026-
|
|
29
|
+
- timestamp: 2026-10-29T20:28:58.090Z
|
|
36
30
|
result: PASSED
|
|
37
31
|
tests:
|
|
38
|
-
total:
|
|
39
|
-
passed:
|
|
32
|
+
total: 628
|
|
33
|
+
passed: 621
|
|
40
34
|
failed: 0
|
|
41
|
-
skipped:
|
|
35
|
+
skipped: 7
|
|
42
36
|
trigger: github-actions
|
|
43
37
|
```
|
|
44
38
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
📄 **Full receipt schema:** [`RECEIPT-FORMAT.md`](./RECEIPT-FORMAT.md) — the pinned `.taf` format (fields, the cannot-be-gamed mechanism, where it fits vs JUnit/TAP/SLSA).
|
|
48
|
-
|
|
49
|
-
**What you get:**
|
|
50
|
-
- **Proof over time** — longitudinal evidence, not snapshots
|
|
51
|
-
- **Pattern detection** — pass-rate trends, regression vs new failure
|
|
52
|
-
- **Platform-agnostic** — works in ANY CI/CD (GitHub Actions, GitLab, Jenkins, CircleCI, Bitbucket, Azure, local, pre-commit)
|
|
53
|
-
- **Git-native** — no external services, no SaaS lock-in
|
|
54
|
-
- **Cannot be gamed** — git SHA detects edits, append-only history detects deletions, CI sandbox prevents output forgery
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
## 👥 WHO
|
|
59
|
-
|
|
60
|
-
**For development teams who need:**
|
|
61
|
-
- Proof of testing over time (not just current state)
|
|
62
|
-
- Git-tracked test accountability (visible in PRs, commits, history)
|
|
63
|
-
- AI-readable test context (feeds into `.faf` project DNA)
|
|
64
|
-
- Platform-agnostic testing receipts (works in ANY CI/CD)
|
|
65
|
-
|
|
66
|
-
**Use cases:**
|
|
67
|
-
- Open source projects (prove your tests pass)
|
|
68
|
-
- Regulated industries (auditable test history)
|
|
69
|
-
- AI-augmented development (give AI your test timeline)
|
|
70
|
-
- Championship engineering (F1-grade accountability)
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## 🤔 WHY
|
|
75
|
-
|
|
76
|
-
### The Problem
|
|
77
|
-
Tests run, results disappear. No permanent record. No accountability.
|
|
78
|
-
|
|
79
|
-
**Before:**
|
|
80
|
-
```
|
|
81
|
-
✅ Tests passing (right now)
|
|
82
|
-
❓ Were they passing yesterday?
|
|
83
|
-
❓ When did that flaky test start failing?
|
|
84
|
-
❓ What's the trend over time?
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
**After (with .taf):**
|
|
88
|
-
```
|
|
89
|
-
✅ Tests passing (tracked in git)
|
|
90
|
-
✅ History shows: 99% pass rate over 30 days
|
|
91
|
-
✅ Flaky test identified: started failing Feb 10
|
|
92
|
-
✅ Trend: improving (was 85%, now 99%)
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
### The Solution
|
|
96
|
-
**Git-native receipts.** Every test run becomes a permanent, auditable record.
|
|
39
|
+
`result` is `PASSED` or `FAILED`. The full format is in [RECEIPT-FORMAT.md](./RECEIPT-FORMAT.md).
|
|
97
40
|
|
|
98
|
-
|
|
41
|
+
## Set it up (GitHub Actions)
|
|
99
42
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
## 📍 WHERE
|
|
103
|
-
|
|
104
|
-
Works in **ANY CI/CD** environment that runs Node.js:
|
|
105
|
-
|
|
106
|
-
| Platform | Status | Example |
|
|
107
|
-
|----------|--------|---------|
|
|
108
|
-
| **GitHub Actions** | ✅ Tested | See Quick Start |
|
|
109
|
-
| **GitLab CI** | ✅ Tested | `npx faf-taf-git --commit` |
|
|
110
|
-
| **Jenkins** | ✅ Compatible | `sh 'npx faf-taf-git --commit'` |
|
|
111
|
-
| **CircleCI** | ✅ Compatible | `run: npx faf-taf-git --commit` |
|
|
112
|
-
| **Bitbucket Pipelines** | ✅ Compatible | `npx faf-taf-git --commit` |
|
|
113
|
-
| **Travis CI** | ✅ Compatible | `npx faf-taf-git --commit` |
|
|
114
|
-
| **Azure Pipelines** | ✅ Compatible | `npx faf-taf-git --commit` |
|
|
115
|
-
| **Local development** | ✅ Works | `npm test && npx faf-taf-git` |
|
|
116
|
-
| **Pre-commit hooks** | ✅ Works | See Examples |
|
|
117
|
-
|
|
118
|
-
**Architecture:** Platform-agnostic core. No CI-specific dependencies. Pure functions.
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
## ⏰ WHEN
|
|
123
|
-
|
|
124
|
-
**Use faf-taf-git when you need:**
|
|
125
|
-
|
|
126
|
-
1. **Proof of testing over time**
|
|
127
|
-
- Regulated industries (SOC 2, ISO, HIPAA)
|
|
128
|
-
- Open source credibility (show your tests pass)
|
|
129
|
-
- Client deliverables (prove quality)
|
|
130
|
-
|
|
131
|
-
2. **AI-augmented development**
|
|
132
|
-
- Give AI your test history (feeds `.faf` format)
|
|
133
|
-
- AI can see: "Tests were 85% passing, now 99%"
|
|
134
|
-
- Better context = better AI assistance
|
|
135
|
-
|
|
136
|
-
3. **Debugging flaky tests**
|
|
137
|
-
- Timeline shows when tests started failing
|
|
138
|
-
- Pattern detection (fails on Windows only, etc.)
|
|
139
|
-
- Root cause analysis with historical data
|
|
140
|
-
|
|
141
|
-
4. **Team accountability**
|
|
142
|
-
- PRs show test impact (IMPROVED, DEGRADED, etc.)
|
|
143
|
-
- No hiding broken tests
|
|
144
|
-
- Git history = test history
|
|
145
|
-
|
|
146
|
-
**Don't use when:**
|
|
147
|
-
- You only need current test status (use a test reporter)
|
|
148
|
-
- You don't commit to git (TAF is git-native)
|
|
149
|
-
- You're not ready for accountability 😉
|
|
150
|
-
|
|
151
|
-
---
|
|
152
|
-
|
|
153
|
-
## 🧩 Use Cases
|
|
154
|
-
|
|
155
|
-
TAF works on any git repo. Adoption requires **zero ecosystem buy-in** — install the action, you get receipts. Below are the use cases TAF serves today and tomorrow:
|
|
156
|
-
|
|
157
|
-
### Standalone (no FAF required)
|
|
158
|
-
|
|
159
|
-
| Use Case | What TAF gives you |
|
|
160
|
-
|---|---|
|
|
161
|
-
| **Plain JS/TS projects** | Receipt for every Jest or Vitest run, on every CI execution |
|
|
162
|
-
| **Pytest projects** | Receipt for every Python test run *(pending pytest parser — v2.2 roadmap)* |
|
|
163
|
-
| **Open source maintainers** | "This repo has 1,847 receipts going back 14 months, none missing" |
|
|
164
|
-
| **Regulated industries** (SOC 2, ISO, HIPAA) | Append-only longitudinal evidence — auditors get a tamper-evident timeline, not a snapshot |
|
|
165
|
-
| **Supply-chain trust** | "Prove these tests ran before this artifact shipped" |
|
|
166
|
-
| **AI-agent verification** | "Prove this agent's code passed tests consistently over the last 90 days" |
|
|
43
|
+
Add this to a workflow, for example `.github/workflows/tests.yml`. Swap the install and test lines for your own.
|
|
167
44
|
|
|
168
|
-
### With FAF (optional integration)
|
|
169
|
-
|
|
170
|
-
| Use Case | What TAF gives you |
|
|
171
|
-
|---|---|
|
|
172
|
-
| **FAF-aware projects** | Receipts include `faf_score`, `faf_associated`, `faf_location` — the receipt tells you not just *did the tests pass*, but *what was the project's AI-readiness when they ran*. Score trends over time become visible. |
|
|
173
|
-
| **Full CAR Framework** | TAF (Receipt) + WJTTC (Audit) + FAF (Claim) — closed-loop attestation: project DNA → testing audit → permanent receipt |
|
|
174
|
-
|
|
175
|
-
**FAF is one tenant among many.** TAF is the platform. The receipt printer doesn't care what kind of project prints to it.
|
|
176
|
-
|
|
177
|
-
---
|
|
178
|
-
|
|
179
|
-
## 🚀 HOW
|
|
180
|
-
|
|
181
|
-
### Quick Start (GitHub Actions)
|
|
182
|
-
|
|
183
|
-
**Step 1:** Create `.taf` file
|
|
184
|
-
```bash
|
|
185
|
-
npm install -g faf-cli
|
|
186
|
-
faf taf init
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
**Step 2:** Add to CI workflow
|
|
190
45
|
```yaml
|
|
191
46
|
name: Tests
|
|
192
47
|
|
|
193
48
|
on:
|
|
194
49
|
push:
|
|
195
50
|
branches: [main]
|
|
51
|
+
pull_request:
|
|
52
|
+
workflow_dispatch:
|
|
53
|
+
|
|
54
|
+
concurrency:
|
|
55
|
+
group: tests-${{ github.ref }} # one run at a time per branch, so receipts never collide
|
|
196
56
|
|
|
197
57
|
jobs:
|
|
198
58
|
test:
|
|
199
59
|
runs-on: ubuntu-latest
|
|
200
60
|
permissions:
|
|
201
|
-
contents: write
|
|
61
|
+
contents: write # lets the action save receipts
|
|
202
62
|
|
|
203
63
|
steps:
|
|
204
64
|
- uses: actions/checkout@v6
|
|
205
|
-
|
|
206
|
-
- name: Setup Node.js
|
|
207
|
-
uses: actions/setup-node@v6
|
|
65
|
+
- uses: actions/setup-node@v6
|
|
208
66
|
with:
|
|
209
67
|
node-version: '24.x'
|
|
68
|
+
- run: npm ci
|
|
210
69
|
|
|
211
|
-
- name:
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
- name: Run Tests and Capture Output
|
|
218
|
-
run: npm test 2>&1 | tee test-output.txt
|
|
70
|
+
- name: Run tests
|
|
71
|
+
id: tests
|
|
72
|
+
continue-on-error: true # keep going, so a failed run still gets a receipt
|
|
73
|
+
run: |
|
|
74
|
+
set -o pipefail
|
|
75
|
+
npm test 2>&1 | tee test-output.txt
|
|
219
76
|
|
|
220
|
-
- name:
|
|
221
|
-
|
|
77
|
+
- name: Print the receipt
|
|
78
|
+
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
|
|
79
|
+
uses: Wolfe-Jam/faf-taf-git@v2.4.0
|
|
222
80
|
with:
|
|
223
81
|
test-output-file: test-output.txt
|
|
224
|
-
|
|
225
|
-
commit-message: 'chore(taf): update .taf receipt [skip ci]'
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
**Step 3:** Push and watch
|
|
229
|
-
- Tests run automatically
|
|
230
|
-
- `.taf` file updates with new entry
|
|
231
|
-
- Changes committed back to repo
|
|
232
|
-
- History tracked in git
|
|
233
|
-
|
|
234
|
-
### Standalone CLI (Any Platform)
|
|
235
|
-
|
|
236
|
-
```bash
|
|
237
|
-
# Run tests and update .taf
|
|
238
|
-
npm test 2>&1 | tee test-output.txt
|
|
239
|
-
npx faf-taf-git --file test-output.txt --commit
|
|
240
|
-
|
|
241
|
-
# Or in one command (legacy v1.x CLI)
|
|
242
|
-
npx faf-taf-git --command "npm test" --commit
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
### GitLab CI
|
|
246
|
-
|
|
247
|
-
```yaml
|
|
248
|
-
test:
|
|
249
|
-
script:
|
|
250
|
-
- npm ci
|
|
251
|
-
- npm test 2>&1 | tee test-output.txt
|
|
252
|
-
- npx faf-taf-git --file test-output.txt --commit --message "ci: update .taf [skip ci]"
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
### Jenkins
|
|
256
|
-
|
|
257
|
-
```groovy
|
|
258
|
-
stage('Test') {
|
|
259
|
-
steps {
|
|
260
|
-
sh 'npm ci'
|
|
261
|
-
sh 'npm test 2>&1 | tee test-output.txt'
|
|
262
|
-
sh 'npx faf-taf-git --file test-output.txt --commit'
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
### Local Development
|
|
268
|
-
|
|
269
|
-
```bash
|
|
270
|
-
# Run tests and update .taf (no commit)
|
|
271
|
-
npm test 2>&1 | tee test-output.txt
|
|
272
|
-
npx faf-taf-git --file test-output.txt --verbose
|
|
82
|
+
target-branch: taf-receipts
|
|
273
83
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
84
|
+
- name: Fail the job if the tests failed
|
|
85
|
+
if: steps.tests.outcome == 'failure'
|
|
86
|
+
run: exit 1
|
|
277
87
|
```
|
|
278
88
|
|
|
279
|
-
|
|
89
|
+
That's it. The first run creates the `taf-receipts` branch for you.
|
|
280
90
|
|
|
281
|
-
|
|
91
|
+
**Four things this recipe gets right:**
|
|
282
92
|
|
|
283
|
-
|
|
93
|
+
1. **Failed runs get a receipt too.** A red run is recorded as `FAILED`, not left out. A history with only green runs proves less.
|
|
94
|
+
2. **Only `main` gets receipts.** Pull requests and other branches still run the tests, but the record is about `main`.
|
|
95
|
+
3. **The job still goes red** when tests fail, so your checks stay honest.
|
|
96
|
+
4. **Tests run once.** The receipt reads the output of the run that just happened.
|
|
284
97
|
|
|
285
|
-
|
|
286
|
-
Step 1: Run Tests Step 2: Generate Receipt
|
|
287
|
-
┌─────────────────────┐ ┌──────────────────────┐
|
|
288
|
-
│ npm test 2>&1 | │ │ faf-taf-git reads │
|
|
289
|
-
│ tee test-output.txt │───────▶│ test-output.txt and │
|
|
290
|
-
│ │ │ updates .taf file │
|
|
291
|
-
└─────────────────────┘ └──────────────────────┘
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
**Why separate steps?**
|
|
295
|
-
- Avoids GitHub Actions execution context corruption
|
|
296
|
-
- More reliable (tested 19 methods before this breakthrough)
|
|
297
|
-
- Platform-agnostic (works in ANY CI/CD)
|
|
298
|
-
- Simpler architecture (400+ lines removed)
|
|
299
|
-
|
|
300
|
-
**Process:**
|
|
301
|
-
1. **Capture output** - `npm test 2>&1 | tee test-output.txt`
|
|
302
|
-
2. **Parse results** - Extracts test counts from Jest output
|
|
303
|
-
3. **Update .taf** - Appends new test run to timeline
|
|
304
|
-
4. **Commit** - Optionally commits changes to git
|
|
305
|
-
|
|
306
|
-
---
|
|
307
|
-
|
|
308
|
-
## 📋 API
|
|
309
|
-
|
|
310
|
-
### GitHub Action Inputs
|
|
311
|
-
|
|
312
|
-
| Input | Description | Default | Required |
|
|
313
|
-
|-------|-------------|---------|----------|
|
|
314
|
-
| `test-output-file` | Path to file containing test output | - | ✅ Yes |
|
|
315
|
-
| `auto-commit` | Automatically commit .taf updates | `true` | No |
|
|
316
|
-
| `commit-message` | Custom commit message | `chore(taf): update .taf receipt [skip ci]` | No |
|
|
317
|
-
|
|
318
|
-
### GitHub Action Outputs
|
|
319
|
-
|
|
320
|
-
| Output | Description | Example |
|
|
321
|
-
|--------|-------------|---------|
|
|
322
|
-
| `result` | Test result | `PASSED`, `FAILED`, `IMPROVED`, `DEGRADED` |
|
|
323
|
-
| `passed` | Number of tests passed | `799` |
|
|
324
|
-
| `failed` | Number of tests failed | `0` |
|
|
325
|
-
| `total` | Total number of tests | `808` |
|
|
326
|
-
| `skipped` | Number of skipped tests | `9` |
|
|
327
|
-
| `taf-updated` | Whether .taf was updated | `true` or `false` |
|
|
328
|
-
|
|
329
|
-
### CLI Options
|
|
330
|
-
|
|
331
|
-
```bash
|
|
332
|
-
npx faf-taf-git [options]
|
|
333
|
-
|
|
334
|
-
Options:
|
|
335
|
-
--file <path> Path to test output file (v2.0.0+)
|
|
336
|
-
--command <cmd> Test command to run (legacy v1.x)
|
|
337
|
-
--commit Auto-commit .taf changes
|
|
338
|
-
--message <msg> Custom commit message
|
|
339
|
-
--cwd <dir> Working directory
|
|
340
|
-
--verbose, -v Verbose output
|
|
341
|
-
--help, -h Show help
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
---
|
|
345
|
-
|
|
346
|
-
## 🧪 Test Framework Support
|
|
347
|
-
|
|
348
|
-
| Framework | Status | Notes |
|
|
349
|
-
|-----------|--------|-------|
|
|
350
|
-
| **Jest** | ✅ Fully supported | All output formats |
|
|
351
|
-
| **Vitest** | ✅ Fully supported | Including todo counts |
|
|
352
|
-
| Mocha | ⏳ Planned | - |
|
|
353
|
-
| Pytest | ⏳ Planned | - |
|
|
354
|
-
| Go test | ⏳ Planned | - |
|
|
355
|
-
| Rust cargo test | ⏳ Planned | - |
|
|
356
|
-
|
|
357
|
-
---
|
|
98
|
+
If your tests run on several operating systems, print the receipt from the one that runs the most tests.
|
|
358
99
|
|
|
359
|
-
##
|
|
100
|
+
## Works with your test runner
|
|
360
101
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
- name: Check Results
|
|
371
|
-
run: |
|
|
372
|
-
echo "Result: ${{ steps.taf.outputs.result }}"
|
|
373
|
-
echo "Tests: ${{ steps.taf.outputs.passed }}/${{ steps.taf.outputs.total }} passing"
|
|
374
|
-
if [ "${{ steps.taf.outputs.result }}" == "DEGRADED" ]; then
|
|
375
|
-
echo "⚠️ Test quality degraded!"
|
|
376
|
-
exit 1
|
|
377
|
-
fi
|
|
378
|
-
```
|
|
102
|
+
| Runner | What to give the action |
|
|
103
|
+
|---|---|
|
|
104
|
+
| **Python (pytest)** | `pytest --junitxml=report.xml`, then `test-output-file: report.xml` |
|
|
105
|
+
| **Any runner that writes JUnit XML** | the XML report file (Rust with `cargo nextest`, Go with `gotestsum --junitfile`, Java with Maven or Gradle, .NET, PHPUnit, Jest with `jest-junit`) |
|
|
106
|
+
| **Jest** | the console output (`npm test 2>&1 \| tee test-output.txt`) |
|
|
107
|
+
| **Vitest** | the console output |
|
|
108
|
+
| **Bun** | the console output of `bun test` |
|
|
109
|
+
| **WJTTC** | the console output |
|
|
379
110
|
|
|
380
|
-
|
|
111
|
+
JUnit XML is the common report format most test runners can write. If your runner isn't in the table, check whether it can write JUnit XML.
|
|
381
112
|
|
|
382
|
-
|
|
383
|
-
version: 2.1
|
|
384
|
-
|
|
385
|
-
jobs:
|
|
386
|
-
test:
|
|
387
|
-
docker:
|
|
388
|
-
- image: node:20
|
|
389
|
-
steps:
|
|
390
|
-
- checkout
|
|
391
|
-
- run: npm ci
|
|
392
|
-
- run: npm test 2>&1 | tee test-output.txt
|
|
393
|
-
- run: npx faf-taf-git --file test-output.txt --commit
|
|
394
|
-
```
|
|
113
|
+
## Other CI systems
|
|
395
114
|
|
|
396
|
-
|
|
115
|
+
The command-line tool does the same job anywhere Node.js runs (GitLab, Jenkins, CircleCI, Bitbucket, Azure, your own machine):
|
|
397
116
|
|
|
398
117
|
```bash
|
|
399
|
-
#!/bin/bash
|
|
400
|
-
# .git/hooks/pre-commit
|
|
401
|
-
|
|
402
|
-
# Run tests and capture output
|
|
403
118
|
npm test 2>&1 | tee test-output.txt
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
# Update .taf (don't commit yet - that's what the commit is for!)
|
|
407
|
-
npx faf-taf-git --file test-output.txt
|
|
408
|
-
|
|
409
|
-
# Exit with test status
|
|
410
|
-
exit $TEST_EXIT
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
---
|
|
414
|
-
|
|
415
|
-
## 🏆 The Golden Triangle
|
|
416
|
-
|
|
417
|
-
Projects with `.faf` + `repo` + `.taf` are **engineered to succeed**:
|
|
418
|
-
|
|
419
|
-
```
|
|
420
|
-
.faf
|
|
421
|
-
(WHAT IT IS)
|
|
422
|
-
/ \
|
|
423
|
-
/ \
|
|
424
|
-
/ \
|
|
425
|
-
repo ←→ .taf
|
|
426
|
-
(IMPLEMENTATION) (PROOF IT WORKS)
|
|
119
|
+
npx faf-taf-git --file test-output.txt --commit
|
|
427
120
|
```
|
|
428
121
|
|
|
429
|
-
|
|
430
|
-
- **repo** - The implementation (code doesn't lie)
|
|
431
|
-
- **.taf** - Proves it works (receipts don't negotiate)
|
|
432
|
-
|
|
433
|
-
**Why this matters:**
|
|
434
|
-
- AI reads `.faf` to understand your project
|
|
435
|
-
- AI reads `.taf` to understand test quality
|
|
436
|
-
- Better context = better AI assistance
|
|
437
|
-
- Accountability built in
|
|
438
|
-
|
|
439
|
-
---
|
|
122
|
+
`--commit` commits the updated `.taf` for you. Leave it off to just update the file.
|
|
440
123
|
|
|
441
|
-
##
|
|
124
|
+
## Read your receipts
|
|
442
125
|
|
|
443
|
-
### Build
|
|
444
126
|
```bash
|
|
445
|
-
|
|
127
|
+
git fetch origin taf-receipts
|
|
128
|
+
git show origin/taf-receipts:.taf
|
|
446
129
|
```
|
|
447
130
|
|
|
448
|
-
|
|
449
|
-
```bash
|
|
450
|
-
npm test
|
|
451
|
-
```
|
|
452
|
-
|
|
453
|
-
### Package (GitHub Action)
|
|
454
|
-
```bash
|
|
455
|
-
npm run package # Creates bundled dist/index.js
|
|
456
|
-
```
|
|
131
|
+
Make a badge for your README:
|
|
457
132
|
|
|
458
|
-
### Test Locally
|
|
459
133
|
```bash
|
|
460
|
-
|
|
461
|
-
node dist/cli.js --help
|
|
134
|
+
npx faf-taf-git badge --output badge.svg
|
|
462
135
|
```
|
|
463
136
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
## 📖 Migration from v1.x
|
|
467
|
-
|
|
468
|
-
**v2.0.0 is a breaking change** - the architecture was redesigned for reliability.
|
|
137
|
+
## Settings
|
|
469
138
|
|
|
470
|
-
|
|
139
|
+
**Action inputs**
|
|
471
140
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
**v2.x (test-output-file):**
|
|
480
|
-
```yaml
|
|
481
|
-
- run: npm test 2>&1 | tee test-output.txt
|
|
482
|
-
|
|
483
|
-
- uses: Wolfe-Jam/faf-taf-git@v2.3.0
|
|
484
|
-
with:
|
|
485
|
-
test-output-file: test-output.txt
|
|
486
|
-
```
|
|
141
|
+
| Input | What it does | Default |
|
|
142
|
+
|---|---|---|
|
|
143
|
+
| `test-output-file` | The file with your test output or JUnit XML report | required |
|
|
144
|
+
| `target-branch` | The branch receipts are saved to. Use `taf-receipts`. | the current branch |
|
|
145
|
+
| `auto-commit` | Commit and push the receipt | `true` |
|
|
146
|
+
| `commit-message` | The commit message | `chore(taf): update .taf receipt [skip ci]` |
|
|
487
147
|
|
|
488
|
-
|
|
148
|
+
**Action outputs:** `result`, `passed`, `failed`, `skipped`, `total`, `taf-updated`. For example, `${{ steps.taf.outputs.passed }}`.
|
|
489
149
|
|
|
490
|
-
|
|
491
|
-
- GitHub Actions execution context corruption
|
|
492
|
-
- Logging failures (tested 19 different methods)
|
|
493
|
-
- Filesystem operations failing silently
|
|
494
|
-
- Unreliable receipt generation
|
|
150
|
+
**Command-line options:** `--file`, `--commit`, `--message`, `--cwd`, `--verbose`. Run `npx faf-taf-git --help` for the full list.
|
|
495
151
|
|
|
496
|
-
|
|
497
|
-
- ✅ More reliable (no execution context issues)
|
|
498
|
-
- ✅ Platform-agnostic (works everywhere)
|
|
499
|
-
- ✅ Simpler (400+ lines removed, 11KB smaller)
|
|
500
|
-
- ✅ Production-ready (tested thoroughly)
|
|
152
|
+
## How hard is it to fake?
|
|
501
153
|
|
|
502
|
-
|
|
154
|
+
Receipts are written by CI from the real test output and saved in git. Editing or deleting an old receipt changes the git history, so anyone comparing the history can see it. The `taf-receipts` branch only ever grows: never rewrite, squash or force-push it.
|
|
503
155
|
|
|
504
|
-
|
|
505
|
-
2. Add test output capture step: `npm test 2>&1 | tee test-output.txt`
|
|
506
|
-
3. Update version to `@v2.3.0`
|
|
156
|
+
A receipt proves the tests passed on that commit. It does not prove a published package was built from that exact commit.
|
|
507
157
|
|
|
508
|
-
|
|
158
|
+
## With FAF (optional)
|
|
509
159
|
|
|
510
|
-
|
|
160
|
+
faf-taf-git works on any git repo; you don't need anything else. If your project also uses [FAF](https://faf.one) (a `project.faf` file describing the project for AI), the two fit together: `project.faf` says what the project is, and `.taf` shows its tests kept passing.
|
|
511
161
|
|
|
512
|
-
##
|
|
162
|
+
## Upgrading from v1
|
|
513
163
|
|
|
514
|
-
|
|
164
|
+
v1 ran your tests inside the action. v2 reads a file your own test step wrote. Replace `test-command:` with a test step that saves its output, and point `test-output-file:` at that file (see the setup above).
|
|
515
165
|
|
|
516
|
-
|
|
166
|
+
## Develop
|
|
517
167
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
- [GitHub Discussions](https://github.com/Wolfe-Jam/faf/discussions) - Ask questions
|
|
524
|
-
|
|
525
|
-
---
|
|
526
|
-
|
|
527
|
-
## 🛣️ Standards Roadmap
|
|
528
|
-
|
|
529
|
-
| Format | IANA Status |
|
|
530
|
-
|---|---|
|
|
531
|
-
| `application/vnd.faf+yaml` (FAF) | ✅ **Registered** |
|
|
532
|
-
| `application/vnd.fafm+yaml` (VML) | 🟡 **Under review** |
|
|
533
|
-
| `application/vnd.taf+yaml` (TAF) | ⏳ **Queued** |
|
|
534
|
-
|
|
535
|
-
`.taf` is filed entirely on its own merits — append-only test provenance, git-tracked, tamper-evident — independent of `.faf`'s registration.
|
|
536
|
-
|
|
537
|
-
---
|
|
538
|
-
|
|
539
|
-
If `faf-taf-git` has been useful, consider starring the repo — it helps others find it.
|
|
540
|
-
|
|
541
|
-
## 📄 License
|
|
542
|
-
|
|
543
|
-
MIT - FREE FOREVER
|
|
544
|
-
|
|
545
|
-
---
|
|
546
|
-
|
|
547
|
-
## 💎 Philosophy
|
|
548
|
-
|
|
549
|
-
**Software Accountability**
|
|
550
|
-
|
|
551
|
-
This tool implements a paradigm shift:
|
|
552
|
-
|
|
553
|
-
**Before:** Tests run → results disappear → no permanent record
|
|
168
|
+
```bash
|
|
169
|
+
npm ci
|
|
170
|
+
npm test # the test suite
|
|
171
|
+
npm run build # rebuilds dist/, which the action runs
|
|
172
|
+
```
|
|
554
173
|
|
|
555
|
-
|
|
174
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) and [CHANGELOG.md](CHANGELOG.md).
|
|
556
175
|
|
|
557
|
-
|
|
176
|
+
## License
|
|
558
177
|
|
|
559
|
-
|
|
178
|
+
MIT. Free forever.
|
|
560
179
|
|
|
561
|
-
|
|
180
|
+
If faf-taf-git is useful to you, a star helps other people find it.
|
package/action.yml
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
name: 'TAF — Testing AI Format'
|
|
2
|
-
description: '
|
|
2
|
+
description: 'A Test Receipt Printer for git. Every CI run prints a receipt to .taf — append-only, cannot be gamed. Proof over time.'
|
|
3
3
|
author: 'wolfejam'
|
|
4
4
|
|
|
5
5
|
branding:
|
|
@@ -39,6 +39,9 @@ outputs:
|
|
|
39
39
|
total:
|
|
40
40
|
description: 'Total number of tests'
|
|
41
41
|
|
|
42
|
+
skipped:
|
|
43
|
+
description: 'Number of tests skipped'
|
|
44
|
+
|
|
42
45
|
taf-updated:
|
|
43
46
|
description: 'Whether .taf file was updated (true/false)'
|
|
44
47
|
|