@anselmdk/feature-spec-md 0.3.1 → 0.5.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/README.md +161 -11
- package/dist/cli.js +29 -0
- package/dist/cli.js.map +1 -1
- package/dist/githubActionDiffReport.d.ts +4 -0
- package/dist/githubActionDiffReport.d.ts.map +1 -0
- package/dist/githubActionDiffReport.js +209 -0
- package/dist/githubActionDiffReport.js.map +1 -0
- package/dist/githubActionFtp.d.ts +25 -0
- package/dist/githubActionFtp.d.ts.map +1 -0
- package/dist/githubActionFtp.js +210 -0
- package/dist/githubActionFtp.js.map +1 -0
- package/dist/githubActionOutput.d.ts +3 -0
- package/dist/githubActionOutput.d.ts.map +1 -0
- package/dist/githubActionOutput.js +33 -0
- package/dist/githubActionOutput.js.map +1 -0
- package/dist/githubActionReport.d.ts +2 -1
- package/dist/githubActionReport.d.ts.map +1 -1
- package/dist/githubActionReport.js +15 -182
- package/dist/githubActionReport.js.map +1 -1
- package/dist/reportTemplate.d.ts +3 -0
- package/dist/reportTemplate.d.ts.map +1 -1
- package/dist/reportTemplate.js +86 -29
- package/dist/reportTemplate.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# feature-spec-md
|
|
2
2
|
|
|
3
|
-
Markdown specs for AI-assisted, testable spec
|
|
3
|
+
Markdown specs for AI-assisted, testable spec-driven development.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`feature-spec-md` helps you describe a product in Markdown, ask an AI to turn those specs into executable tests, and then prove which parts of the specification are covered by those tests. It is intentionally small: your specs stay as plain Markdown, your tests stay in your normal test runner, and the tool connects the two through stable spec IDs.
|
|
6
6
|
|
|
7
7
|
```txt
|
|
8
8
|
model + features + stack + design
|
|
@@ -10,9 +10,44 @@ model + features + stack + design
|
|
|
10
10
|
-> validation, coverage, screenshots, and reports
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
## What the tool does
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
The shortest version is: `feature-spec-md` turns Markdown specifications into a testable contract.
|
|
16
|
+
|
|
17
|
+
It gives you:
|
|
18
|
+
|
|
19
|
+
- **Spec document formats** for domain models, product features, technical stack notes, and UI/design direction.
|
|
20
|
+
- **Stable IDs** for model items, rules, and scenarios, so tests can reference exactly what they implement.
|
|
21
|
+
- **Validation** that checks frontmatter, headings, IDs, cross-document references, and test coverage expectations.
|
|
22
|
+
- **Coverage reporting** that shows which model items, rules, and scenarios are implemented by tests.
|
|
23
|
+
- **HTML reports** that are useful for reviews, CI artifacts, or published build reports.
|
|
24
|
+
- **Screenshot evidence** for scenarios when using the Playwright helper.
|
|
25
|
+
- **A library API** for projects that want to parse specs, check coverage, collect screenshots, or render reports from their own tooling.
|
|
26
|
+
|
|
27
|
+
The specs are meant to be written with an AI before implementation. The tests are meant to be written with an AI from those specs. `feature-spec-md` then checks that the Markdown stays structured and that executable tests still cover the model items, rules, and scenarios the specs define.
|
|
28
|
+
|
|
29
|
+
## Why this exists
|
|
30
|
+
|
|
31
|
+
AI can write tests quickly, but it needs a stable source of truth. Free-form product notes are often too ambiguous, and generated tests are hard to audit later. `feature-spec-md` keeps the source of truth in readable Markdown and makes the AI preserve IDs such as `ACCOUNT-M001`, `TICKET-R001`, or `TICKET-S001` in the generated tests.
|
|
32
|
+
|
|
33
|
+
That gives humans a simple review loop:
|
|
34
|
+
|
|
35
|
+
1. Read the Markdown spec.
|
|
36
|
+
2. Read or run the generated tests.
|
|
37
|
+
3. Run `feature-spec-md check` or `coverage` to see what is missing.
|
|
38
|
+
4. Open the HTML report to review the implemented scenarios, rules, model items, and screenshots.
|
|
39
|
+
|
|
40
|
+
## Demo project
|
|
41
|
+
|
|
42
|
+
A complete demo app is available in [`anselmdk/feature-spec-md-demo`](https://github.com/anselmdk/feature-spec-md-demo). It shows a small support-ticket desk built from model, feature, stack, and design specs, with unit tests, Playwright tests, generated coverage, and a published report.
|
|
43
|
+
|
|
44
|
+
Demo reports, including scenario screenshots, are available here:
|
|
45
|
+
|
|
46
|
+
<https://feature-spec-md.anselm.dk/demo/>
|
|
47
|
+
|
|
48
|
+
Use the demo repository when you want to see the expected project shape, script names, screenshot manifest flow, and report output in a real app.
|
|
49
|
+
|
|
50
|
+
## What you write
|
|
16
51
|
|
|
17
52
|
Use four ordinary Markdown document types:
|
|
18
53
|
|
|
@@ -23,9 +58,27 @@ Use four ordinary Markdown document types:
|
|
|
23
58
|
*.design.md product, UI, and interaction direction
|
|
24
59
|
```
|
|
25
60
|
|
|
26
|
-
Each document has frontmatter, a short `## Purpose`, and stable IDs.
|
|
61
|
+
Each document has frontmatter, a short `## Purpose`, and stable IDs.
|
|
62
|
+
|
|
63
|
+
### Model specs
|
|
64
|
+
|
|
65
|
+
Model specs define the shared vocabulary that features can refer to. Use them for domain concepts, states, entities, and important business terms.
|
|
66
|
+
|
|
67
|
+
```md
|
|
68
|
+
### ACCOUNT-M001: Registered person
|
|
69
|
+
|
|
70
|
+
A person who has completed registration and can request sign-in links.
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Feature specs
|
|
74
|
+
|
|
75
|
+
Feature specs describe user-facing behavior with rules and scenarios. Rules and scenarios get stable IDs that tests can reference.
|
|
27
76
|
|
|
28
77
|
```md
|
|
78
|
+
### ACCOUNT-ACCESS-R001: Sign-in links expire
|
|
79
|
+
|
|
80
|
+
Sign-in links can only be used within the configured expiry window.
|
|
81
|
+
|
|
29
82
|
### ACCOUNT-ACCESS-S001: Registered person signs in
|
|
30
83
|
|
|
31
84
|
Given a registered person is on the sign-in page
|
|
@@ -33,13 +86,27 @@ When they request and open a valid sign-in link
|
|
|
33
86
|
Then they are signed in
|
|
34
87
|
```
|
|
35
88
|
|
|
89
|
+
### Stack specs
|
|
90
|
+
|
|
91
|
+
Stack specs document technical decisions that shape the implementation: framework, storage, test runner, deployment constraints, external services, or architecture decisions.
|
|
92
|
+
|
|
93
|
+
### Design specs
|
|
94
|
+
|
|
95
|
+
Design specs capture product, UI, and interaction direction: layout priorities, states, accessibility expectations, empty states, or copy tone.
|
|
96
|
+
|
|
97
|
+
See [SPEC_FORMAT.md](SPEC_FORMAT.md) for the exact document format.
|
|
98
|
+
|
|
99
|
+
## How tests connect to specs
|
|
100
|
+
|
|
101
|
+
Tests reference spec IDs in titles, tags, annotations, comments, or metadata. The tool scans test files and matches those references back to the Markdown documents.
|
|
102
|
+
|
|
36
103
|
```ts
|
|
37
104
|
test("ACCOUNT-ACCESS-S001 registered person signs in", async ({ page }) => {
|
|
38
105
|
// Covers ACCOUNT-ACCESS-R001 and ACCOUNT-M001.
|
|
39
106
|
});
|
|
40
107
|
```
|
|
41
108
|
|
|
42
|
-
|
|
109
|
+
This keeps the test runner independent from `feature-spec-md`. You can use Playwright, Vitest, Node test, or another runner as long as the source files contain the relevant IDs.
|
|
43
110
|
|
|
44
111
|
## Install
|
|
45
112
|
|
|
@@ -63,15 +130,17 @@ npx feature-spec-md init --kind design --dir specs
|
|
|
63
130
|
3. Ask an AI to write executable tests from the specs, preserving the relevant `-M001`, `-R001`, and `-S001` IDs in the test source.
|
|
64
131
|
4. Run `npx feature-spec-md coverage` to see which scenarios, rules, and model items have tests.
|
|
65
132
|
5. Run `npx feature-spec-md report` to generate an HTML implementation report for review or CI artifacts.
|
|
133
|
+
6. Use `npx feature-spec-md github-report` in GitHub Actions when the report should be linked from the job summary or published.
|
|
66
134
|
|
|
67
|
-
The longer flow, including AI prompts and CI setup, is in [docs/spec-driven-flow.md](docs/spec-driven-flow.md).
|
|
135
|
+
The longer flow, including AI prompts and CI setup, is in [docs/spec-driven-flow.md](docs/spec-driven-flow.md). The demo repository also shows the flow in practice: <https://github.com/anselmdk/feature-spec-md-demo>.
|
|
68
136
|
|
|
69
|
-
## CLI
|
|
137
|
+
## CLI tools
|
|
70
138
|
|
|
71
139
|
```bash
|
|
72
140
|
npx feature-spec-md check
|
|
73
141
|
npx feature-spec-md coverage --fail-on-missing
|
|
74
142
|
npx feature-spec-md report --out test-results/feature-spec-report/index.html
|
|
143
|
+
npx feature-spec-md github-report --report-dir test-results/spec-report
|
|
75
144
|
```
|
|
76
145
|
|
|
77
146
|
By default the CLI scans:
|
|
@@ -92,17 +161,85 @@ npx feature-spec-md check \
|
|
|
92
161
|
--tests "e2e/**/*.spec.ts"
|
|
93
162
|
```
|
|
94
163
|
|
|
95
|
-
|
|
164
|
+
### `init`
|
|
165
|
+
|
|
166
|
+
Creates starter Markdown files for one spec kind.
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
npx feature-spec-md init --kind feature --dir specs
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Supported kinds are `model`, `feature`, `stack`, and `design`.
|
|
173
|
+
|
|
174
|
+
### `check`
|
|
175
|
+
|
|
176
|
+
Validates the spec set and, by default, requires scenario coverage when tests are scanned.
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
npx feature-spec-md check
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
`check` validates spec structure, references between documents, and test coverage. Use `--require-scenario-coverage=false` while drafting. Use `--require-rule-coverage` and `--require-model-coverage` when rules and model items must also fail validation if they have no test references.
|
|
96
183
|
|
|
97
|
-
The
|
|
184
|
+
The demo uses stricter coverage gates for all tests:
|
|
98
185
|
|
|
99
|
-
|
|
186
|
+
```bash
|
|
187
|
+
feature-spec-md check --tests "tests/**/*.ts" --require-rule-coverage --require-model-coverage
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### `coverage`
|
|
191
|
+
|
|
192
|
+
Prints a terminal implementation report showing covered and missing model items, rules, and scenarios.
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
npx feature-spec-md coverage --fail-on-missing
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Use `--fail-on-missing` when missing model item, rule, or scenario coverage should fail CI.
|
|
199
|
+
|
|
200
|
+
### `report`
|
|
201
|
+
|
|
202
|
+
Writes an HTML report for local review, CI artifacts, or publishing.
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
npx feature-spec-md report \
|
|
206
|
+
--tests "tests/**/*.ts" \
|
|
207
|
+
--out test-results/spec-report/index.html
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
The report can include screenshot evidence from Playwright or another test runner by passing one or more screenshot manifest files:
|
|
100
211
|
|
|
101
212
|
```bash
|
|
102
213
|
npx feature-spec-md report \
|
|
103
214
|
--screenshots "test-results/spec-report/screenshots-*.json"
|
|
104
215
|
```
|
|
105
216
|
|
|
217
|
+
The demo report is published at <https://feature-spec-md.anselm.dk/demo/> and includes scenario screenshots, so it is the best place to see what the report output looks like.
|
|
218
|
+
|
|
219
|
+
### `github-report`
|
|
220
|
+
|
|
221
|
+
Writes a GitHub Actions job summary and prepares the generated report for either artifact upload or FTP publishing.
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
npx feature-spec-md github-report \
|
|
225
|
+
--report-dir test-results/spec-report \
|
|
226
|
+
--publish artifact
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Use `--publish ftp` when the report should be uploaded to a public report site from CI.
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
npx feature-spec-md github-report \
|
|
233
|
+
--report-dir test-results/spec-report \
|
|
234
|
+
--publish ftp
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Playwright screenshot evidence
|
|
238
|
+
|
|
239
|
+
The package exports a Playwright helper from `@anselmdk/feature-spec-md/playwright`. It maps scenario step text back to the spec line, wraps the implementation in a Playwright `test.step`, captures a screenshot after the step, attaches it to the test, and writes a screenshot manifest such as `test-results/spec-report/screenshots-0.json`.
|
|
240
|
+
|
|
241
|
+
That manifest can then be passed to `feature-spec-md report` with `--screenshots "test-results/spec-report/screenshots-*.json"` so the HTML report can show scenario evidence next to the relevant spec step.
|
|
242
|
+
|
|
106
243
|
## GitHub Actions report publishing
|
|
107
244
|
|
|
108
245
|
`feature-spec-md github-report` writes the GitHub Actions job summary and can either prepare outputs for a GitHub artifact upload or publish the generated report to FTP.
|
|
@@ -176,14 +313,27 @@ Most integrations can use the top-level document API:
|
|
|
176
313
|
```ts
|
|
177
314
|
import {
|
|
178
315
|
checkSpecDocuments,
|
|
316
|
+
collectSpecScreenshots,
|
|
179
317
|
parseSpecDocument,
|
|
180
318
|
renderHtmlReport,
|
|
181
319
|
validateSpecDocument,
|
|
182
320
|
} from "@anselmdk/feature-spec-md";
|
|
183
321
|
```
|
|
184
322
|
|
|
323
|
+
Useful exports include:
|
|
324
|
+
|
|
325
|
+
- `parseSpecDocument` and kind-specific parsers for reading Markdown specs.
|
|
326
|
+
- `validateSpecDocument` and `validateSpecGraph` for checking one document or a connected spec set.
|
|
327
|
+
- `checkSpecDocuments` for loading specs and tests, validating documents, and computing coverage in one call.
|
|
328
|
+
- `buildSpecCoverageSummary` and `collectSpecTestReferences` for custom coverage workflows.
|
|
329
|
+
- `renderHtmlReport` for generating the same report UI from your own integration.
|
|
330
|
+
- `collectSpecScreenshots` for loading screenshot manifest files before rendering a report.
|
|
331
|
+
- `writeTextFile` for small report-writing integrations.
|
|
332
|
+
|
|
185
333
|
Feature-only helpers such as `parseFeatureSpec` and `checkFeatureSpecs` remain available for compatibility.
|
|
186
334
|
|
|
335
|
+
The package also exports `@anselmdk/feature-spec-md/specDocuments` and `@anselmdk/feature-spec-md/playwright` for more focused imports.
|
|
336
|
+
|
|
187
337
|
## Development
|
|
188
338
|
|
|
189
339
|
```bash
|
package/dist/cli.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
7
7
|
import path from "node:path";
|
|
8
8
|
import { collectSpecScreenshots, renderHtmlReport, writeTextFile, } from "./index.js";
|
|
9
|
+
import { publishGithubActionDiffReport } from "./githubActionDiffReport.js";
|
|
9
10
|
import { publishGithubActionReport } from "./githubActionReport.js";
|
|
10
11
|
import { checkSpecDocuments } from "./specDocuments.js";
|
|
11
12
|
import { buildSpecImplementationReport, formatSpecImplementationReport, } from "./testImplementationReport.js";
|
|
@@ -26,6 +27,8 @@ async function main() {
|
|
|
26
27
|
return runCoverage(options);
|
|
27
28
|
if (command === "github-report")
|
|
28
29
|
return publishGithubActionReport(options);
|
|
30
|
+
if (command === "github-diff-report")
|
|
31
|
+
return publishGithubActionDiffReport(options);
|
|
29
32
|
if (command === "init")
|
|
30
33
|
return runInit(options);
|
|
31
34
|
printHelp();
|
|
@@ -87,6 +90,7 @@ async function runReport(options) {
|
|
|
87
90
|
coverage: result.coverage,
|
|
88
91
|
screenshots,
|
|
89
92
|
validationIssues: [...result.validationIssues, ...result.coverageIssues],
|
|
93
|
+
...githubSourceLinkOptions(),
|
|
90
94
|
}));
|
|
91
95
|
console.log(`Feature spec report written to ${out}`);
|
|
92
96
|
}
|
|
@@ -156,6 +160,28 @@ async function readPackageName() {
|
|
|
156
160
|
return undefined;
|
|
157
161
|
}
|
|
158
162
|
}
|
|
163
|
+
function githubSourceLinkOptions() {
|
|
164
|
+
const repository = process.env.GITHUB_REPOSITORY;
|
|
165
|
+
const githubRef = githubRefFromEnv();
|
|
166
|
+
if (!repository || !githubRef)
|
|
167
|
+
return {};
|
|
168
|
+
const githubBaseUrl = `${process.env.GITHUB_SERVER_URL ?? "https://github.com"}/${repository}`;
|
|
169
|
+
return {
|
|
170
|
+
githubBaseUrl,
|
|
171
|
+
githubRef,
|
|
172
|
+
repositoryUrl: githubBaseUrl,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
function githubRefFromEnv() {
|
|
176
|
+
if (process.env.GITHUB_SHA)
|
|
177
|
+
return process.env.GITHUB_SHA;
|
|
178
|
+
if (process.env.GITHUB_HEAD_REF)
|
|
179
|
+
return process.env.GITHUB_HEAD_REF;
|
|
180
|
+
if (process.env.GITHUB_REF_NAME)
|
|
181
|
+
return process.env.GITHUB_REF_NAME;
|
|
182
|
+
const ref = process.env.GITHUB_REF;
|
|
183
|
+
return ref?.replace(/^refs\/(heads|tags)\//, "");
|
|
184
|
+
}
|
|
159
185
|
function printHelp() {
|
|
160
186
|
console.log(`feature-spec-md
|
|
161
187
|
|
|
@@ -165,6 +191,7 @@ Usage:
|
|
|
165
191
|
feature-spec-md coverage [--specs "specs/**/*.model.md,specs/**/*.feature.md,specs/**/*.stack.md,specs/**/*.design.md"] [--tests "tests/**/*.spec.ts"] [--fail-on-missing]
|
|
166
192
|
feature-spec-md report [--specs "specs/**/*.model.md,specs/**/*.feature.md,specs/**/*.stack.md,specs/**/*.design.md"] [--tests "tests/**/*.spec.ts"] [--screenshots "test-results/spec-report/screenshots.json"] [--out test-results/feature-spec-report/index.html]
|
|
167
193
|
feature-spec-md github-report [--report-dir test-results/spec-report] [--publish artifact|ftp]
|
|
194
|
+
feature-spec-md github-diff-report --publish ftp --pr-number 123
|
|
168
195
|
|
|
169
196
|
Options:
|
|
170
197
|
--require-model-coverage Fail when model items have no matching test references.
|
|
@@ -182,6 +209,8 @@ GitHub report publishing:
|
|
|
182
209
|
--ftp-password FTP password, or FEATURE_SPEC_FTP_PASSWORD.
|
|
183
210
|
--ftp-remote-dir FTP root directory for reports, or FEATURE_SPEC_FTP_REMOTE_DIR.
|
|
184
211
|
--base-url Public base URL, or FEATURE_SPEC_REPORT_BASE_URL.
|
|
212
|
+
--build-number Numeric build number, or FEATURE_SPEC_BUILD_NUMBER / GITHUB_RUN_NUMBER.
|
|
213
|
+
--pr-number Numeric PR number, or FEATURE_SPEC_PR_NUMBER. Required for github-diff-report.
|
|
185
214
|
`);
|
|
186
215
|
}
|
|
187
216
|
function fileNameForKind(kind) {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type GithubActionOptions } from "./githubActionFtp.js";
|
|
2
|
+
export type GithubActionDiffReportOptions = GithubActionOptions;
|
|
3
|
+
export declare function publishGithubActionDiffReport(options: GithubActionDiffReportOptions): Promise<void>;
|
|
4
|
+
//# sourceMappingURL=githubActionDiffReport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"githubActionDiffReport.d.ts","sourceRoot":"","sources":["../src/githubActionDiffReport.ts"],"names":[],"mappings":"AAKA,OAAO,EAQL,KAAK,mBAAmB,EACzB,MAAM,sBAAsB,CAAC;AAG9B,MAAM,MAAM,6BAA6B,GAAG,mBAAmB,CAAC;AAqBhE,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,6BAA6B,iBA4DvC"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import { basename, join, relative } from "node:path";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { html } from "./html.js";
|
|
6
|
+
import { downloadRemoteFile, ftpConfig, listBuildNumbers, listRemoteFilesRecursive, pathJoin, publicUrl, uploadDirectory, } from "./githubActionFtp.js";
|
|
7
|
+
import { writeGithubOutput, writeGithubSummary } from "./githubActionOutput.js";
|
|
8
|
+
export async function publishGithubActionDiffReport(options) {
|
|
9
|
+
const config = ftpConfig(options);
|
|
10
|
+
const prNumber = config.prNumber;
|
|
11
|
+
if (!prNumber) {
|
|
12
|
+
throw new Error("Missing required option --pr-number or FEATURE_SPEC_PR_NUMBER.");
|
|
13
|
+
}
|
|
14
|
+
const buildsRoot = pathJoin(config.remoteDir, "build");
|
|
15
|
+
const builds = await listBuildNumbers(buildsRoot, config);
|
|
16
|
+
const currentBuild = config.buildNumber;
|
|
17
|
+
const previousBuild = previousBuildNumber(builds, currentBuild);
|
|
18
|
+
const currentBuildUrl = publicUrl(config.baseUrl, "build", currentBuild, "");
|
|
19
|
+
const previousBuildUrl = previousBuild
|
|
20
|
+
? publicUrl(config.baseUrl, "build", previousBuild, "")
|
|
21
|
+
: undefined;
|
|
22
|
+
const report = previousBuild
|
|
23
|
+
? await compareBuilds(config, previousBuild, currentBuild, prNumber)
|
|
24
|
+
: {
|
|
25
|
+
prNumber,
|
|
26
|
+
currentBuild,
|
|
27
|
+
currentBuildUrl,
|
|
28
|
+
files: [],
|
|
29
|
+
};
|
|
30
|
+
if (previousBuild) {
|
|
31
|
+
report.previousBuild = previousBuild;
|
|
32
|
+
report.previousBuildUrl = previousBuildUrl;
|
|
33
|
+
}
|
|
34
|
+
const localReportDir = join(tmpdir(), `feature-spec-md-pr-diff-${process.pid}-${prNumber}-${currentBuild}`);
|
|
35
|
+
await mkdir(localReportDir, { recursive: true });
|
|
36
|
+
await writeFile(join(localReportDir, "index.html"), renderDiffReport(report), "utf8");
|
|
37
|
+
const remoteReportDir = pathJoin(config.remoteDir, "pr", prNumber, currentBuild);
|
|
38
|
+
await uploadDirectory(localReportDir, remoteReportDir, config);
|
|
39
|
+
const reportUrl = publicUrl(config.baseUrl, "pr", prNumber, currentBuild, "");
|
|
40
|
+
await writeGithubSummary([
|
|
41
|
+
"## Feature Spec PR Diff",
|
|
42
|
+
"",
|
|
43
|
+
`<p><strong>Diff report:</strong> <a href=\"${html(reportUrl)}\">PR #${html(prNumber)} build ${html(currentBuild)}</a></p>`,
|
|
44
|
+
report.previousBuild
|
|
45
|
+
? `<p>Compared build <strong>${html(report.previousBuild)}</strong> with build <strong>${html(currentBuild)}</strong>.</p>`
|
|
46
|
+
: `<p>No earlier build was found, so this report establishes the first comparison baseline.</p>`,
|
|
47
|
+
"",
|
|
48
|
+
].join("\n"));
|
|
49
|
+
await writeGithubOutput({
|
|
50
|
+
"diff-report-url": reportUrl,
|
|
51
|
+
"diff-comment-body": commentBody(report, reportUrl),
|
|
52
|
+
"previous-build": report.previousBuild ?? "",
|
|
53
|
+
"current-build": currentBuild,
|
|
54
|
+
});
|
|
55
|
+
console.log(`Feature spec PR diff report uploaded to ${reportUrl}`);
|
|
56
|
+
}
|
|
57
|
+
async function compareBuilds(config, previousBuild, currentBuild, prNumber) {
|
|
58
|
+
const previousRoot = pathJoin(config.remoteDir, "build", previousBuild);
|
|
59
|
+
const currentRoot = pathJoin(config.remoteDir, "build", currentBuild);
|
|
60
|
+
const previousFiles = await listRemoteFilesRecursive(previousRoot, config);
|
|
61
|
+
const currentFiles = await listRemoteFilesRecursive(currentRoot, config);
|
|
62
|
+
const previousRelative = new Set(previousFiles.map((file) => relativeRemotePath(previousRoot, file)));
|
|
63
|
+
const currentRelative = new Set(currentFiles.map((file) => relativeRemotePath(currentRoot, file)));
|
|
64
|
+
const allPaths = Array.from(new Set([...previousRelative, ...currentRelative])).sort();
|
|
65
|
+
const localRoot = join(tmpdir(), `feature-spec-md-build-compare-${process.pid}-${previousBuild}-${currentBuild}`);
|
|
66
|
+
const files = [];
|
|
67
|
+
for (const filePath of allPaths) {
|
|
68
|
+
const previousRemote = previousRelative.has(filePath)
|
|
69
|
+
? pathJoin(previousRoot, filePath)
|
|
70
|
+
: undefined;
|
|
71
|
+
const currentRemote = currentRelative.has(filePath)
|
|
72
|
+
? pathJoin(currentRoot, filePath)
|
|
73
|
+
: undefined;
|
|
74
|
+
const previousLocal = previousRemote
|
|
75
|
+
? join(localRoot, "previous", filePath)
|
|
76
|
+
: undefined;
|
|
77
|
+
const currentLocal = currentRemote ? join(localRoot, "current", filePath) : undefined;
|
|
78
|
+
if (previousRemote && previousLocal) {
|
|
79
|
+
await downloadRemoteFile(previousRemote, previousLocal, config);
|
|
80
|
+
}
|
|
81
|
+
if (currentRemote && currentLocal) {
|
|
82
|
+
await downloadRemoteFile(currentRemote, currentLocal, config);
|
|
83
|
+
}
|
|
84
|
+
const previousInfo = previousLocal ? await fileInfo(previousLocal) : undefined;
|
|
85
|
+
const currentInfo = currentLocal ? await fileInfo(currentLocal) : undefined;
|
|
86
|
+
const status = !previousInfo
|
|
87
|
+
? "added"
|
|
88
|
+
: !currentInfo
|
|
89
|
+
? "removed"
|
|
90
|
+
: previousInfo.hash === currentInfo.hash
|
|
91
|
+
? "unchanged"
|
|
92
|
+
: "changed";
|
|
93
|
+
files.push({
|
|
94
|
+
path: filePath,
|
|
95
|
+
kind: fileKind(filePath),
|
|
96
|
+
status,
|
|
97
|
+
previousHash: previousInfo?.hash,
|
|
98
|
+
currentHash: currentInfo?.hash,
|
|
99
|
+
previousSize: previousInfo?.size,
|
|
100
|
+
currentSize: currentInfo?.size,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
prNumber,
|
|
105
|
+
previousBuild,
|
|
106
|
+
currentBuild,
|
|
107
|
+
previousBuildUrl: publicUrl(config.baseUrl, "build", previousBuild, ""),
|
|
108
|
+
currentBuildUrl: publicUrl(config.baseUrl, "build", currentBuild, ""),
|
|
109
|
+
files,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function previousBuildNumber(builds, currentBuild) {
|
|
113
|
+
const current = Number(currentBuild);
|
|
114
|
+
return builds
|
|
115
|
+
.map(Number)
|
|
116
|
+
.filter((build) => Number.isFinite(build) && build < current)
|
|
117
|
+
.sort((a, b) => b - a)
|
|
118
|
+
.at(0)
|
|
119
|
+
?.toString();
|
|
120
|
+
}
|
|
121
|
+
async function fileInfo(filePath) {
|
|
122
|
+
const buffer = await readFile(filePath);
|
|
123
|
+
return {
|
|
124
|
+
hash: createHash("sha256").update(buffer).digest("hex"),
|
|
125
|
+
size: buffer.byteLength,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function relativeRemotePath(root, filePath) {
|
|
129
|
+
return relative(root, filePath).split("\\").join("/");
|
|
130
|
+
}
|
|
131
|
+
function fileKind(filePath) {
|
|
132
|
+
const name = basename(filePath).toLowerCase();
|
|
133
|
+
if (name === "index.html" || name.endsWith(".html") || name.endsWith(".json")) {
|
|
134
|
+
return "report";
|
|
135
|
+
}
|
|
136
|
+
if (/\.(png|jpe?g|webp|gif)$/i.test(name))
|
|
137
|
+
return "screenshot";
|
|
138
|
+
return "asset";
|
|
139
|
+
}
|
|
140
|
+
function renderDiffReport(report) {
|
|
141
|
+
const changed = report.files.filter((file) => file.status !== "unchanged");
|
|
142
|
+
const byKind = (kind) => changed.filter((file) => file.kind === kind);
|
|
143
|
+
const sections = [
|
|
144
|
+
renderFileSection("Report output", byKind("report")),
|
|
145
|
+
renderFileSection("Screenshots", byKind("screenshot")),
|
|
146
|
+
renderFileSection("Other assets", byKind("asset")),
|
|
147
|
+
].join("\n");
|
|
148
|
+
return `<!doctype html>
|
|
149
|
+
<html lang="en">
|
|
150
|
+
<head>
|
|
151
|
+
<meta charset="utf-8">
|
|
152
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
153
|
+
<title>Feature spec PR diff</title>
|
|
154
|
+
<style>
|
|
155
|
+
body{font-family:system-ui,sans-serif;max-width:1180px;margin:0 auto;padding:40px 24px;color:#1f2328}
|
|
156
|
+
.panel{border:1px solid #d0d7de;border-radius:8px;padding:20px;margin:18px 0}
|
|
157
|
+
.badge{border:1px solid #d0d7de;border-radius:999px;padding:2px 8px;font-size:12px;white-space:nowrap}
|
|
158
|
+
.added{color:#1a7f37}.removed{color:#cf222e}.changed{color:#9a6700}.muted{color:#57606a}
|
|
159
|
+
table{border-collapse:collapse;width:100%;font-size:14px} th,td{border:1px solid #d0d7de;padding:6px 8px;text-align:left;vertical-align:top} th{background:#f6f8fa}
|
|
160
|
+
a{color:#0969da}
|
|
161
|
+
</style>
|
|
162
|
+
</head>
|
|
163
|
+
<body>
|
|
164
|
+
<h1>Feature spec PR diff for PR #${html(report.prNumber)}</h1>
|
|
165
|
+
<p>Generated ${html(new Date().toISOString())}.</p>
|
|
166
|
+
<section class="panel">
|
|
167
|
+
<h2>Compared builds</h2>
|
|
168
|
+
<p>${report.previousBuild ? `Previous: <a href="${html(report.previousBuildUrl ?? "")}">build ${html(report.previousBuild)}</a>` : "No previous build found."}</p>
|
|
169
|
+
<p>Current: <a href="${html(report.currentBuildUrl)}">build ${html(report.currentBuild)}</a></p>
|
|
170
|
+
<p><span class="badge">${changed.length} changed file${changed.length === 1 ? "" : "s"}</span> <span class="muted">${report.files.length} file${report.files.length === 1 ? "" : "s"} checked</span></p>
|
|
171
|
+
</section>
|
|
172
|
+
${sections}
|
|
173
|
+
</body>
|
|
174
|
+
</html>`;
|
|
175
|
+
}
|
|
176
|
+
function renderFileSection(title, files) {
|
|
177
|
+
if (!files.length) {
|
|
178
|
+
return `<section class="panel"><h2>${html(title)}</h2><p class="muted">No changes.</p></section>`;
|
|
179
|
+
}
|
|
180
|
+
return `<section class="panel"><h2>${html(title)}</h2><table><thead><tr><th>Status</th><th>File</th><th>Size change</th></tr></thead><tbody>${files
|
|
181
|
+
.map((file) => `<tr><td class="${file.status}">${html(file.status)}</td><td><code>${html(file.path)}</code></td><td>${html(sizeChange(file))}</td></tr>`)
|
|
182
|
+
.join("")}</tbody></table></section>`;
|
|
183
|
+
}
|
|
184
|
+
function sizeChange(file) {
|
|
185
|
+
if (file.previousSize === undefined)
|
|
186
|
+
return `+${file.currentSize ?? 0} bytes`;
|
|
187
|
+
if (file.currentSize === undefined)
|
|
188
|
+
return `-${file.previousSize} bytes`;
|
|
189
|
+
const diff = file.currentSize - file.previousSize;
|
|
190
|
+
if (diff === 0)
|
|
191
|
+
return "same size";
|
|
192
|
+
return `${diff > 0 ? "+" : ""}${diff} bytes`;
|
|
193
|
+
}
|
|
194
|
+
function commentBody(report, reportUrl) {
|
|
195
|
+
const changed = report.files.filter((file) => file.status !== "unchanged");
|
|
196
|
+
const reportChanges = changed.filter((file) => file.kind === "report").length;
|
|
197
|
+
const screenshotChanges = changed.filter((file) => file.kind === "screenshot").length;
|
|
198
|
+
const previous = report.previousBuild
|
|
199
|
+
? `build ${report.previousBuild} → build ${report.currentBuild}`
|
|
200
|
+
: `build ${report.currentBuild}`;
|
|
201
|
+
return [
|
|
202
|
+
"## Feature spec PR diff",
|
|
203
|
+
"",
|
|
204
|
+
`[Open the diff report](${reportUrl}) for ${previous}.`,
|
|
205
|
+
"",
|
|
206
|
+
`Changed files: **${changed.length}** total, **${reportChanges}** report output, **${screenshotChanges}** screenshots.`,
|
|
207
|
+
].join("\n");
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=githubActionDiffReport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"githubActionDiffReport.js","sourceRoot":"","sources":["../src/githubActionDiffReport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type GithubActionOptions = Record<string, string | undefined>;
|
|
2
|
+
export type FtpConfig = {
|
|
3
|
+
host: string;
|
|
4
|
+
user: string;
|
|
5
|
+
password: string;
|
|
6
|
+
port?: string;
|
|
7
|
+
secure: boolean;
|
|
8
|
+
remoteDir: string;
|
|
9
|
+
baseUrl: string;
|
|
10
|
+
buildNumber: string;
|
|
11
|
+
prNumber?: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function ftpConfig(options: GithubActionOptions): FtpConfig;
|
|
14
|
+
export declare function uploadDirectory(localDir: string, remoteDir: string, config: FtpConfig): Promise<void>;
|
|
15
|
+
export declare function uploadFile(localFile: string, remotePath: string, config: FtpConfig): Promise<void>;
|
|
16
|
+
export declare function downloadRemoteFile(remotePath: string, localFile: string, config: FtpConfig): Promise<void>;
|
|
17
|
+
export declare function listRemoteDirectory(remoteDir: string, config: FtpConfig): Promise<string>;
|
|
18
|
+
export declare function listRemoteFilesRecursive(remoteDir: string, config: FtpConfig): Promise<string[]>;
|
|
19
|
+
export declare function parseBuildNumbersFromDirectoryListing(listing: string): string[];
|
|
20
|
+
export declare function listBuildNumbers(remoteDir: string, config: FtpConfig): Promise<string[]>;
|
|
21
|
+
export declare function pathJoin(...parts: string[]): string;
|
|
22
|
+
export declare function publicUrl(baseUrl: string, ...parts: string[]): string;
|
|
23
|
+
export declare function trimTrailingSlash(value: string): string;
|
|
24
|
+
export declare function runCurl(args: string[]): Promise<string>;
|
|
25
|
+
//# sourceMappingURL=githubActionFtp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"githubActionFtp.d.ts","sourceRoot":"","sources":["../src/githubActionFtp.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAErE,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAgB,SAAS,CAAC,OAAO,EAAE,mBAAmB,GAAG,SAAS,CA0BjE;AAED,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,SAAS,iBAclB;AAED,wBAAsB,UAAU,CAC9B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,SAAS,iBAalB;AAED,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,SAAS,iBAalB;AAED,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,mBAe7E;AAED,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,SAAS,qBAuBlB;AAED,wBAAgB,qCAAqC,CAAC,OAAO,EAAE,MAAM,YAapE;AAED,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,qBAO1E;AAED,wBAAgB,QAAQ,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,UAO1C;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,UAO5D;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,UAE9C;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,mBAoB3C"}
|