@crvouga/atlas 0.13.0 → 0.15.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/CHANGELOG.md +12 -0
- package/dist/playwright-reporter/src/index.d.ts +11 -0
- package/dist/playwright-reporter/src/index.js +4 -2
- package/dist/reports/src/artifact-tag-store.d.ts +20 -0
- package/dist/reports/src/artifact-tag-store.js +70 -0
- package/dist/reports/src/artifact-tags.d.ts +96 -0
- package/dist/reports/src/artifact-tags.js +96 -0
- package/dist/reports/src/evidence-detail.d.ts +1 -1
- package/dist/reports/src/evidence-detail.js +6 -2
- package/dist/reports/src/evidence-types.d.ts +5 -0
- package/dist/reports/src/layer-merge.d.ts +1 -1
- package/dist/reports/src/layer-merge.js +3 -2
- package/dist/reports/src/layer-types.d.ts +3 -0
- package/dist/reports/src/publish-checks.js +1 -0
- package/dist/reports/src/report-cli.d.ts +1 -1
- package/dist/reports/src/report-cli.js +30 -2
- package/dist/reports/src/reporter.d.ts +1 -1
- package/dist/reports/src/reports-explorer-route.d.ts +8 -0
- package/dist/reports/src/reports-route.d.ts +8 -0
- package/dist/reports/src/test-catalog.d.ts +31 -27
- package/dist/reports/src/test-catalog.js +73 -12
- package/dist/schema/src/api.d.ts +128 -1
- package/dist/schema/src/api.js +38 -4
- package/dist/schema/src/layer.d.ts +59 -0
- package/dist/schema/src/layer.js +28 -1
- package/dist/server/src/app.js +32 -1
- package/dist/server/src/openapi.d.ts +1 -1
- package/dist/server/src/openapi.js +18 -2
- package/docs/extending.md +3 -0
- package/docs/integrating.md +8 -0
- package/docs/reference/cli.md +7 -0
- package/docs/reference/http-api.md +48 -0
- package/docs/reference/playwright-reporter.md +6 -6
- package/docs/reference/reports.md +235 -8
- package/docs/reference/schema.md +52 -1
- package/docs/report-contract.md +1 -0
- package/docs/rich-evidence.md +28 -0
- package/docs/server.md +24 -0
- package/llms-full.txt +119 -0
- package/package.json +1 -1
- package/packages/schema/schemas/check-detail.schema.json +28 -0
- package/packages/schema/schemas/effective-delta.schema.json +44 -0
- package/packages/schema/schemas/effective-evidence.schema.json +44 -0
- package/packages/schema/schemas/evidence-page.schema.json +37 -0
- package/packages/schema/schemas/layer-rows.schema.json +7 -0
- package/packages/schema/schemas/layer.schema.json +100 -0
- package/packages/schema/schemas/publish-checks.schema.json +65 -0
- package/packages/schema/schemas/report-run.schema.json +17 -1
- package/packages/schema/schemas/report-runs.schema.json +17 -1
- package/packages/schema/schemas/test-catalog.schema.json +42 -0
- package/packages/schema/schemas/test-history.schema.json +28 -0
- package/packages/server/openapi.json +886 -3
- package/packages/visualizer/src/evidence/artifact-tags.tsx +285 -0
- package/packages/visualizer/src/evidence/artifacts.tsx +18 -12
- package/packages/visualizer/src/explorer/RunsView.tsx +23 -4
- package/packages/visualizer/src/explorer/parts.tsx +2 -1
package/llms-full.txt
CHANGED
|
@@ -505,6 +505,14 @@ first commit, they are `null`: that is provenance missing, not an error, and nev
|
|
|
505
505
|
result wins. `--param key=value` (repeatable) adds a parameter that makes a result its own slot, such
|
|
506
506
|
as `--param device=iphone-15`.
|
|
507
507
|
|
|
508
|
+
Without a CI run URL, layers recorded at one branch and commit group into one run, so repeating a local demo
|
|
509
|
+
looks like one execution. To keep invocations apart, name each one: `--run-id <id>` (or `ATLAS_RUN_ID`), with
|
|
510
|
+
`--run-title <title>` (or `ATLAS_RUN_TITLE`) for a human name and `--run-started-at` / `--run-ended-at` for when
|
|
511
|
+
it ran. Every shard or batch of one invocation passes the same id and is one run; the next invocation passes a new
|
|
512
|
+
one. A run recorded from a checkout with uncommitted changes keeps saying so beside its commit. The id only
|
|
513
|
+
groups: it is not part of which result a check fills or which wins, and a producer that never passes it keeps
|
|
514
|
+
the CI-run-URL, then `branch@sha`, grouping.
|
|
515
|
+
|
|
508
516
|
The time the checks ran comes from the report (CTRF `summary.stop`, a JUnit `timestamp`, a manifest's
|
|
509
517
|
`finishedAt`), or failing that from the report file's modification time, in milliseconds. Publish in
|
|
510
518
|
the same job that wrote the report and that is the time it ran. If you copy the report first, pass
|
|
@@ -1005,6 +1013,7 @@ decided exactly as before ([the report contract](report-contract.md)). Evidence
|
|
|
1005
1013
|
| `steps` (`parentId`, `offsetMs`, `durationMs`, `status`, `kind`) | check, attempt | Draws the check's timeline: nested steps, when each started, how long it took, which one failed. |
|
|
1006
1014
|
| `attempts` | check | Every try of a retried check, with its own status, detail, steps and attachments. A check that passed after failing is flaky. |
|
|
1007
1015
|
| `tags`, `labels` | check, layer | Filters and groups (`smoke`, `flaky`, an owner, a browser). |
|
|
1016
|
+
| `tags` | attachment | Marks one recording or screenshot, for example `demo`: shown as a `#demo` chip, and searchable. See [Tagging artifacts and demos](#tagging-artifacts-and-demos). |
|
|
1008
1017
|
| `annotations`, `links` | check, step, attempt, layer | Notes, warnings and issue links next to the result. |
|
|
1009
1018
|
| `specPath` | check | The spec a check belongs to (a `.feature`, a test file), relative to the repository. Checks are grouped by it. |
|
|
1010
1019
|
| `specs[]` (`path`, `domain`, `kind`, `title`) | layer | Names each spec and its group (`domain`), so a server can group checks by spec with a title even when no [spec set](integrating.md#tell-atlas-which-spec-a-check-belongs-to) has been published. |
|
|
@@ -1013,6 +1022,33 @@ decided exactly as before ([the report contract](report-contract.md)). Evidence
|
|
|
1013
1022
|
Send `sha`, `branch` and `runUrl` on every layer too. They never change a result, but they tie results to a commit
|
|
1014
1023
|
and to the CI run that produced them.
|
|
1015
1024
|
|
|
1025
|
+
## Tagging artifacts and demos
|
|
1026
|
+
|
|
1027
|
+
To mark one recording as a demo, tag the attachment itself. A tag on a check says something about the result; a tag on
|
|
1028
|
+
an attachment says something about that file, and no Gherkin tag, label, environment or producer name is needed:
|
|
1029
|
+
|
|
1030
|
+
```ts
|
|
1031
|
+
{ name: 'checkout.webm', role: 'video', tags: ['demo'], labels: { audience: 'business' } }
|
|
1032
|
+
```
|
|
1033
|
+
|
|
1034
|
+
The viewer shows it as a `#demo` chip on the artifact card. Selecting the chip filters the result's evidence to the
|
|
1035
|
+
attachments with that tag, and says how many match. Tags describe evidence; they never change a status or a slot.
|
|
1036
|
+
|
|
1037
|
+
- **One spelling.** A tag is normalized before it is compared or stored: a leading `#` is dropped, letters are
|
|
1038
|
+
lower-cased, each run of whitespace becomes `-`, and surrounding space is trimmed, so `demo`, `#demo` and `#Demo ` are
|
|
1039
|
+
`demo`. Empty tags and tags over 64 characters are not tags and are ignored (or refused, when a reviewer enters them).
|
|
1040
|
+
Everything else is a valid tag (`team/payments`, `release=2`), and repeats are shown once.
|
|
1041
|
+
- **Inherited.** An attachment is also searchable by the tags of its check and its run. The viewer says `inherited` on
|
|
1042
|
+
such a chip, and a switch decides whether the filter counts them: a recording without a tag of its own under a run
|
|
1043
|
+
tagged `demo` is found by the inherited query and not by the exact one. In the API,
|
|
1044
|
+
`GET /api/reports/tests?artifactTag=demo` is exact and adding `&inherited=1` includes inherited tags.
|
|
1045
|
+
- **Reviewers.** After upload, a person with a publish token can add tags to an attachment (the viewer's *Add tag*
|
|
1046
|
+
button) and remove the ones a reviewer added. Those tags are not written into the layer, which is immutable: the
|
|
1047
|
+
server keeps them as an audit trail (who, when, which tags) and the viewer shows them as `added by <name>`, apart
|
|
1048
|
+
from the producer's tags. See [Tagging artifacts](server.md#tagging-artifacts). A producer's own tags stay as uploaded.
|
|
1049
|
+
- **Older layers.** A layer without attachment tags reads exactly as before. Tags on an attachment that cannot be read
|
|
1050
|
+
(not a list of strings) are dropped, and the attachment, check and layer stay.
|
|
1051
|
+
|
|
1016
1052
|
## Labels describe, parameters split
|
|
1017
1053
|
|
|
1018
1054
|
A result's **slot** is its producer, check id, part kind, spec, environment and **parameters**. The newest completed
|
|
@@ -1396,6 +1432,26 @@ against a server unchanged. A client uploads **in dependency order**: blobs, the
|
|
|
1396
1432
|
entry that makes it visible. The server checks each step and says no to a catalog entry whose manifest is not
|
|
1397
1433
|
there (`409`), so nothing half-uploaded is ever shown.
|
|
1398
1434
|
|
|
1435
|
+
## Tagging artifacts
|
|
1436
|
+
|
|
1437
|
+
A reviewer can mark a recording `#demo` after it was uploaded without uploading it again. The layer is immutable, so the
|
|
1438
|
+
tag is kept beside it: each edit is one small object under `curation/artifact-tags/` in the write backend (or the live
|
|
1439
|
+
store of a relay), named by time, never changed or removed. It records the attachment (layer, check, and the attachment's
|
|
1440
|
+
`id`, else its bytes' key, else its name), the normalized tags added and removed, the name of the token that made the
|
|
1441
|
+
edit, and the server's time. Nothing about the layer, its results or the report's winners changes.
|
|
1442
|
+
|
|
1443
|
+
- `GET /api/reports/artifact-tags` (read) returns every edit, oldest first. Fold them to get the tags that stand now: the
|
|
1444
|
+
last edit of a tag wins.
|
|
1445
|
+
- `POST /api/reports/artifact-tags` (publish, `Authorization: Bearer`) records an edit. A read token, an anonymous reader
|
|
1446
|
+
and the browser's sign-in box are refused (`403`/`401`) like any upload, so a read-only visitor can see the tags and
|
|
1447
|
+
not change them. The viewer asks for a token when a reviewer adds a tag and keeps it only in that tab.
|
|
1448
|
+
- Producer tags (`tags` on the attachment) and reviewer tags are kept apart everywhere: the viewer says who added a
|
|
1449
|
+
reviewer tag and when, and a reviewer can remove only reviewer tags. `capabilities.artifactTags` on `/api/server` says
|
|
1450
|
+
a server has this.
|
|
1451
|
+
|
|
1452
|
+
See [Tagging artifacts and demos](rich-evidence.md#tagging-artifacts-and-demos) for the tag rules. Reviewer tags are
|
|
1453
|
+
shown in the viewer's evidence; the tests API (`artifactTag`) searches the producers' tags.
|
|
1454
|
+
|
|
1399
1455
|
## Streaming
|
|
1400
1456
|
|
|
1401
1457
|
`GET /api/events` is a server-sent-events stream:
|
|
@@ -1510,6 +1566,10 @@ curl "$ATLAS_SERVER_URL/api/projects/$ATLAS_PROJECT/reports/tests?format=markdow
|
|
|
1510
1566
|
| `GET /api/projects/{project}/reports/tests/health` | read | Why specs, domains and counts disagree. |
|
|
1511
1567
|
| `GET /api/reports/tests/history` | read | One test and every result recorded for it. |
|
|
1512
1568
|
| `GET /api/projects/{project}/reports/tests/history` | read | One test and every result recorded for it. |
|
|
1569
|
+
| `GET /api/reports/artifact-tags` | read | Reviewer tags of attachments: every recorded edit. |
|
|
1570
|
+
| `GET /api/projects/{project}/reports/artifact-tags` | read | Reviewer tags of attachments: every recorded edit. |
|
|
1571
|
+
| `POST /api/reports/artifact-tags` | publish | Tag or untag one attachment after upload. |
|
|
1572
|
+
| `POST /api/projects/{project}/reports/artifact-tags` | publish | Tag or untag one attachment after upload. |
|
|
1513
1573
|
| `GET /api/reports/runs` | read | The runs that recorded the report. |
|
|
1514
1574
|
| `GET /api/projects/{project}/reports/runs` | read | The runs that recorded the report. |
|
|
1515
1575
|
| `GET /api/reports/runs/detail` | read | Every test one run recorded. |
|
|
@@ -2174,6 +2234,7 @@ Zod schema as `LayerDocumentSchema` from `@crvouga/atlas/schema`.
|
|
|
2174
2234
|
| `environment` | The client checked, or absent. Normalised to a lowercase slug: `iOS` → `ios`, `Desktop Web` → `desktop-web`, `iphone` → `ios`, `mobile browser` → `mobile-web`. Any other name is kept. Part of the slot. |
|
|
2175
2235
|
| `parameters` | Other string choices that make a result its own slot, such as `{ "device": "iphone-15" }`. A parameter named `environment` is read as the environment. Part of the slot. |
|
|
2176
2236
|
| `freshness` | `modified`: recorded from a checkout with uncommitted changes. `unknown`: origin not captured. Advisory only; see [Statuses](#statuses-and-the-gate). |
|
|
2237
|
+
| `run` | Optional `{ id, title?, startedAtMs?, endedAtMs? }`: the execution a local or manual producer names. Layers with the same `id` in one project are one run in the run list, however many shards or batches uploaded them; a later invocation at the same branch and commit gets another `id`. Without it a run is its `runUrl`, else `branch@sha`, as before. `title` is for people. Grouping and display only: it is **never part of the slot**, never decides a winner or a status, and never hides `sha`, `branch` or `freshness`. A `run` a reader cannot read is treated as absent. |
|
|
2177
2238
|
| `specs` | The specs the layer was recorded against, with a `fingerprint` of their text, so a reader can warn when a spec changed since. Optional. |
|
|
2178
2239
|
| `parts[].kind` | An open category (`behavior`, `performance`, `accessibility`, …). A new kind needs no change to any reader. Part of the slot. |
|
|
2179
2240
|
| `parts[].checks[]` | `id` (required, stable), `title`, `status`, `detail`, `specPath`, `measurements`, `durationMs`. |
|
|
@@ -2533,6 +2594,9 @@ carry any of these. Every one is optional.
|
|
|
2533
2594
|
| `extensions{}` | Structured data of your own or a tool's, under a name you own. |
|
|
2534
2595
|
| `measurements[]` | Numbers, with units and an allowance (already part of the contract). |
|
|
2535
2596
|
|
|
2597
|
+
An attachment may carry its own `tags[]` (`demo`): shown as `#demo` and searchable; see
|
|
2598
|
+
[Tagging artifacts and demos](rich-evidence.md#tagging-artifacts-and-demos).
|
|
2599
|
+
|
|
2536
2600
|
On a **layer** the same fields describe the whole run: its CI log, a coverage report, an archive of traces, the
|
|
2537
2601
|
build number, a link to the pipeline.
|
|
2538
2602
|
|
|
@@ -4246,12 +4310,14 @@ atlas report — layered evidence for any kind of spec
|
|
|
4246
4310
|
atlas report publish [--store <dir|s3://bucket/prefix>] [--producer <name>]
|
|
4247
4311
|
( --ctrf <file> | --junit <file> | --manifest <file> | --checks <file.json> )
|
|
4248
4312
|
[--environment <name>] [--branch <b>] [--sha <s>] [--run-url <u>]
|
|
4313
|
+
[--run-id <id>] [--run-title <t>] [--run-started-at <iso|ms>] [--run-ended-at <iso|ms>]
|
|
4249
4314
|
[--spec <path> | --specs <dir>] [--upload-run]
|
|
4250
4315
|
[--param key=value]... [--kind <k>] [--title <t>] [--recorded-at <iso|ms>]
|
|
4251
4316
|
[--attach [role=]<file>]... [--label key=value]... [--link [name=]<url>]...
|
|
4252
4317
|
[--attach-root <dir>]... [--max-attachment-mb <n>] [--max-total-attachment-mb <n>]
|
|
4253
4318
|
atlas report stream [--store <dir|s3://…|https://atlas.example.com>] --producer <name> [--environment <name>]
|
|
4254
4319
|
[--branch <b>] [--sha <s>] [--run-url <u>] [--kind <k>] [--param key=value]...
|
|
4320
|
+
[--run-id <id>] [--run-title <t>]
|
|
4255
4321
|
[--flush-ms 1000] [--batch 100] (checks as JSON lines on standard input)
|
|
4256
4322
|
atlas report status [--store <dir|s3://…|id=url>]... [--backends <module>]
|
|
4257
4323
|
[--specs <dir>] [--format text|json|markdown]
|
|
@@ -4272,6 +4338,11 @@ atlas report — layered evidence for any kind of spec
|
|
|
4272
4338
|
--specs <dir> link checks to the spec files in <dir> by path, or by the suite, class or
|
|
4273
4339
|
file name the report gives; also publishes the specs themselves, so the
|
|
4274
4340
|
node can show them without a checkout
|
|
4341
|
+
--run-id <id> name this execution (a local or manual run with no CI run URL; also ATLAS_RUN_ID).
|
|
4342
|
+
Layers that share an id are one run, however many shards or batches uploaded them;
|
|
4343
|
+
another invocation at the same commit gets another id. Never part of what a check is
|
|
4344
|
+
--run-title <t> a human name for the run (also ATLAS_RUN_TITLE); --run-started-at and --run-ended-at
|
|
4345
|
+
record when it ran. Without --run-id a run is its CI run URL, else branch@sha
|
|
4275
4346
|
--upload-run with --manifest: also upload the run's screenshots and clips for the viewer
|
|
4276
4347
|
--attach <file> attach a file to the whole layer: a CI log, a coverage report, a trace archive
|
|
4277
4348
|
(screenshots, videos and traces of a single test go in its CTRF or checks file)
|
|
@@ -4778,6 +4849,8 @@ Send `format=markdown` (or `Accept: text/markdown`) for the same as a Markdown r
|
|
|
4778
4849
|
- `domain` (query): Only tests whose spec is in this domain (`(no spec)` for none). Repeatable or comma-separated.
|
|
4779
4850
|
- `spec` (query): Only tests of this spec path. Repeatable or comma-separated.
|
|
4780
4851
|
- `tag` (query): Only tests with this tag. Repeatable or comma-separated.
|
|
4852
|
+
- `artifactTag` (query): Only tests with an attachment tagged this (`demo` and `#demo` are the same tag), not counting tags inherited from a check or run: the exact artifact query. `inherited=1` widens it to the tags inherited from the check and run. Repeatable or comma-separated.
|
|
4853
|
+
- `inherited` (query): With `artifactTag`: `1` also matches the tags an attachment inherits from its check and run, so a recording without a tag of its own under a run tagged `demo` is found. Without it the query is exact.
|
|
4781
4854
|
- `run` (query): Only tests recorded in this run (a `key` from `/api/reports/runs`).
|
|
4782
4855
|
- `sort` (query): The order: `spec` (default: domain, spec, title), `title`, `recent`, `slowest`, `failures`, `flaky` or `runs`.
|
|
4783
4856
|
- `offset` (query): Skip this many matching tests.
|
|
@@ -4807,6 +4880,8 @@ Scoped to one project. The same project may be selected on the unprefixed API us
|
|
|
4807
4880
|
- `domain` (query): Only tests whose spec is in this domain (`(no spec)` for none). Repeatable or comma-separated.
|
|
4808
4881
|
- `spec` (query): Only tests of this spec path. Repeatable or comma-separated.
|
|
4809
4882
|
- `tag` (query): Only tests with this tag. Repeatable or comma-separated.
|
|
4883
|
+
- `artifactTag` (query): Only tests with an attachment tagged this (`demo` and `#demo` are the same tag), not counting tags inherited from a check or run: the exact artifact query. `inherited=1` widens it to the tags inherited from the check and run. Repeatable or comma-separated.
|
|
4884
|
+
- `inherited` (query): With `artifactTag`: `1` also matches the tags an attachment inherits from its check and run, so a recording without a tag of its own under a run tagged `demo` is found. Without it the query is exact.
|
|
4810
4885
|
- `run` (query): Only tests recorded in this run (a `key` from `/api/reports/runs`).
|
|
4811
4886
|
- `sort` (query): The order: `spec` (default: domain, spec, title), `title`, `recent`, `slowest`, `failures`, `flaky` or `runs`.
|
|
4812
4887
|
- `offset` (query): Skip this many matching tests.
|
|
@@ -4875,6 +4950,50 @@ Scoped to one project. The same project may be selected on the unprefixed API us
|
|
|
4875
4950
|
|
|
4876
4951
|
Responses: `200` The test and its history.; `304` Unchanged since the `If-None-Match` ETag.; `400` No `key`.; `401` No token, or an unknown one. Send `Authorization: Bearer <token>`.; `404` No test in the report has that key.; `503` The server is still reading its backends. Retry after the number of seconds in `Retry-After`.
|
|
4877
4952
|
|
|
4953
|
+
### Reviewer tags of attachments: every recorded edit
|
|
4954
|
+
|
|
4955
|
+
`GET /api/reports/artifact-tags` · role: read
|
|
4956
|
+
|
|
4957
|
+
The audit trail of tags that reviewers added to and removed from attachments after upload, oldest first. Each entry says which attachment (`target`), which normalized tags were added and removed, the name of the token that made the edit (`by`, never the token) and when (`atMs`). The layers themselves are never rewritten, so a producer's own `tags` on an attachment stay as uploaded; fold the entries (oldest first, the last edit of a tag wins) to get the reviewer tags that stand now. Tags are normalized: `#Demo` and `demo` are `demo`.
|
|
4958
|
+
|
|
4959
|
+
- `project` (query): Project slug. Alternatively send X-Atlas-Project or use the project-prefixed route. Omit for the default project. Conflicting selectors are refused.
|
|
4960
|
+
|
|
4961
|
+
Responses: `200` The edits.; `401` No token, or an unknown one. Send `Authorization: Bearer <token>`.
|
|
4962
|
+
|
|
4963
|
+
### Reviewer tags of attachments: every recorded edit
|
|
4964
|
+
|
|
4965
|
+
`GET /api/projects/{project}/reports/artifact-tags` · role: read
|
|
4966
|
+
|
|
4967
|
+
The audit trail of tags that reviewers added to and removed from attachments after upload, oldest first. Each entry says which attachment (`target`), which normalized tags were added and removed, the name of the token that made the edit (`by`, never the token) and when (`atMs`). The layers themselves are never rewritten, so a producer's own `tags` on an attachment stay as uploaded; fold the entries (oldest first, the last edit of a tag wins) to get the reviewer tags that stand now. Tags are normalized: `#Demo` and `demo` are `demo`.
|
|
4968
|
+
|
|
4969
|
+
Scoped to one project. The same project may be selected on the unprefixed API using ?project= or X-Atlas-Project. Unknown projects return 404 on reads and are created by an authenticated upload.
|
|
4970
|
+
|
|
4971
|
+
- `project` (path, required): Project slug. Alternatively send X-Atlas-Project or use the project-prefixed route. Omit for the default project. Conflicting selectors are refused.
|
|
4972
|
+
|
|
4973
|
+
Responses: `200` The edits.; `401` No token, or an unknown one. Send `Authorization: Bearer <token>`.
|
|
4974
|
+
|
|
4975
|
+
### Tag or untag one attachment after upload
|
|
4976
|
+
|
|
4977
|
+
`POST /api/reports/artifact-tags` · role: publish
|
|
4978
|
+
|
|
4979
|
+
Records one edit of the reviewer tags of one attachment, by the name of the publish (or admin) token that sends it. It adds an immutable entry to the audit trail and changes nothing else: not the layer, not the movie, not any result. The tags it removes are reviewer tags only; a producer's tags are part of the layer and stay. A reader-only token, a browser sign-in box and an anonymous reader are refused. Name the attachment as `artifactRef` does (`id:<id>`, else `key:<bundleKey>`, else `name:<name>`).
|
|
4980
|
+
|
|
4981
|
+
- `project` (query): Project slug. Alternatively send X-Atlas-Project or use the project-prefixed route. Omit for the default project. Conflicting selectors are refused.
|
|
4982
|
+
|
|
4983
|
+
Responses: `201` The recorded entry.; `401` No token, or an unknown one. Send `Authorization: Bearer <token>`.; `403` The token is known but its role may not do this.; `413` Request too large.; `422` Not a tag edit: a bad target, an empty or over-long tag, or nothing to change.
|
|
4984
|
+
|
|
4985
|
+
### Tag or untag one attachment after upload
|
|
4986
|
+
|
|
4987
|
+
`POST /api/projects/{project}/reports/artifact-tags` · role: publish
|
|
4988
|
+
|
|
4989
|
+
Records one edit of the reviewer tags of one attachment, by the name of the publish (or admin) token that sends it. It adds an immutable entry to the audit trail and changes nothing else: not the layer, not the movie, not any result. The tags it removes are reviewer tags only; a producer's tags are part of the layer and stay. A reader-only token, a browser sign-in box and an anonymous reader are refused. Name the attachment as `artifactRef` does (`id:<id>`, else `key:<bundleKey>`, else `name:<name>`).
|
|
4990
|
+
|
|
4991
|
+
Scoped to one project. The same project may be selected on the unprefixed API using ?project= or X-Atlas-Project. Unknown projects return 404 on reads and are created by an authenticated upload.
|
|
4992
|
+
|
|
4993
|
+
- `project` (path, required): Project slug. Alternatively send X-Atlas-Project or use the project-prefixed route. Omit for the default project. Conflicting selectors are refused.
|
|
4994
|
+
|
|
4995
|
+
Responses: `201` The recorded entry.; `401` No token, or an unknown one. Send `Authorization: Bearer <token>`.; `403` The token is known but its role may not do this.; `413` Request too large.; `422` Not a tag edit: a bad target, an empty or over-long tag, or nothing to change.
|
|
4996
|
+
|
|
4878
4997
|
### The runs that recorded the report
|
|
4879
4998
|
|
|
4880
4999
|
`GET /api/reports/runs` · role: read
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crvouga/atlas",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Atlas: specs of any kind, reported as layered evidence. Publish checks from any runner (JUnit, CTRF, a script), combine them across nodes, branches, environments and backends, gate CI on the result, and run statecharts against the real app.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -169,6 +169,13 @@
|
|
|
169
169
|
"description": {
|
|
170
170
|
"type": "string"
|
|
171
171
|
},
|
|
172
|
+
"tags": {
|
|
173
|
+
"description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
|
|
174
|
+
"type": "array",
|
|
175
|
+
"items": {
|
|
176
|
+
"type": "string"
|
|
177
|
+
}
|
|
178
|
+
},
|
|
172
179
|
"at": {
|
|
173
180
|
"type": "object",
|
|
174
181
|
"properties": {
|
|
@@ -397,6 +404,13 @@
|
|
|
397
404
|
"description": {
|
|
398
405
|
"type": "string"
|
|
399
406
|
},
|
|
407
|
+
"tags": {
|
|
408
|
+
"description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
|
|
409
|
+
"type": "array",
|
|
410
|
+
"items": {
|
|
411
|
+
"type": "string"
|
|
412
|
+
}
|
|
413
|
+
},
|
|
400
414
|
"at": {
|
|
401
415
|
"type": "object",
|
|
402
416
|
"properties": {
|
|
@@ -662,6 +676,13 @@
|
|
|
662
676
|
"description": {
|
|
663
677
|
"type": "string"
|
|
664
678
|
},
|
|
679
|
+
"tags": {
|
|
680
|
+
"description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
|
|
681
|
+
"type": "array",
|
|
682
|
+
"items": {
|
|
683
|
+
"type": "string"
|
|
684
|
+
}
|
|
685
|
+
},
|
|
665
686
|
"at": {
|
|
666
687
|
"type": "object",
|
|
667
688
|
"properties": {
|
|
@@ -862,6 +883,13 @@
|
|
|
862
883
|
"description": {
|
|
863
884
|
"type": "string"
|
|
864
885
|
},
|
|
886
|
+
"tags": {
|
|
887
|
+
"description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
|
|
888
|
+
"type": "array",
|
|
889
|
+
"items": {
|
|
890
|
+
"type": "string"
|
|
891
|
+
}
|
|
892
|
+
},
|
|
865
893
|
"at": {
|
|
866
894
|
"type": "object",
|
|
867
895
|
"properties": {
|
|
@@ -132,6 +132,13 @@
|
|
|
132
132
|
"type": "string"
|
|
133
133
|
}
|
|
134
134
|
},
|
|
135
|
+
"artifactTags": {
|
|
136
|
+
"description": "Normalized tags of the attachments themselves, sorted and distinct. Absent when no attachment is tagged; never inherited from a check or run",
|
|
137
|
+
"type": "array",
|
|
138
|
+
"items": {
|
|
139
|
+
"type": "string"
|
|
140
|
+
}
|
|
141
|
+
},
|
|
135
142
|
"labels": {
|
|
136
143
|
"type": "object",
|
|
137
144
|
"propertyNames": {
|
|
@@ -256,6 +263,36 @@
|
|
|
256
263
|
"modified"
|
|
257
264
|
]
|
|
258
265
|
},
|
|
266
|
+
"run": {
|
|
267
|
+
"description": "The execution the producer named for it (one local or manual invocation). Grouping and display only; never part of the slot",
|
|
268
|
+
"type": "object",
|
|
269
|
+
"properties": {
|
|
270
|
+
"id": {
|
|
271
|
+
"type": "string",
|
|
272
|
+
"minLength": 1,
|
|
273
|
+
"maxLength": 256,
|
|
274
|
+
"description": "The execution's identity within a project, chosen by the producer: a UUID, a timestamped name. Layers with the same id are one run; it never changes after it is recorded"
|
|
275
|
+
},
|
|
276
|
+
"title": {
|
|
277
|
+
"description": "A human name for the run. Presentation only: it is not part of the identity and does not hide the commit or `freshness`",
|
|
278
|
+
"type": "string"
|
|
279
|
+
},
|
|
280
|
+
"startedAtMs": {
|
|
281
|
+
"description": "When the execution started, epoch milliseconds",
|
|
282
|
+
"type": "number",
|
|
283
|
+
"minimum": 0
|
|
284
|
+
},
|
|
285
|
+
"endedAtMs": {
|
|
286
|
+
"description": "When the execution ended, epoch milliseconds",
|
|
287
|
+
"type": "number",
|
|
288
|
+
"minimum": 0
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
"required": [
|
|
292
|
+
"id"
|
|
293
|
+
],
|
|
294
|
+
"additionalProperties": {}
|
|
295
|
+
},
|
|
259
296
|
"recording": {
|
|
260
297
|
"anyOf": [
|
|
261
298
|
{},
|
|
@@ -328,6 +365,13 @@
|
|
|
328
365
|
"type": "string"
|
|
329
366
|
}
|
|
330
367
|
},
|
|
368
|
+
"artifactTags": {
|
|
369
|
+
"description": "Normalized tags of the attachments themselves, sorted and distinct. Absent when no attachment is tagged; never inherited from a check or run",
|
|
370
|
+
"type": "array",
|
|
371
|
+
"items": {
|
|
372
|
+
"type": "string"
|
|
373
|
+
}
|
|
374
|
+
},
|
|
331
375
|
"labels": {
|
|
332
376
|
"type": "object",
|
|
333
377
|
"propertyNames": {
|
|
@@ -132,6 +132,13 @@
|
|
|
132
132
|
"type": "string"
|
|
133
133
|
}
|
|
134
134
|
},
|
|
135
|
+
"artifactTags": {
|
|
136
|
+
"description": "Normalized tags of the attachments themselves, sorted and distinct. Absent when no attachment is tagged; never inherited from a check or run",
|
|
137
|
+
"type": "array",
|
|
138
|
+
"items": {
|
|
139
|
+
"type": "string"
|
|
140
|
+
}
|
|
141
|
+
},
|
|
135
142
|
"labels": {
|
|
136
143
|
"type": "object",
|
|
137
144
|
"propertyNames": {
|
|
@@ -256,6 +263,36 @@
|
|
|
256
263
|
"modified"
|
|
257
264
|
]
|
|
258
265
|
},
|
|
266
|
+
"run": {
|
|
267
|
+
"description": "The execution the producer named for it (one local or manual invocation). Grouping and display only; never part of the slot",
|
|
268
|
+
"type": "object",
|
|
269
|
+
"properties": {
|
|
270
|
+
"id": {
|
|
271
|
+
"type": "string",
|
|
272
|
+
"minLength": 1,
|
|
273
|
+
"maxLength": 256,
|
|
274
|
+
"description": "The execution's identity within a project, chosen by the producer: a UUID, a timestamped name. Layers with the same id are one run; it never changes after it is recorded"
|
|
275
|
+
},
|
|
276
|
+
"title": {
|
|
277
|
+
"description": "A human name for the run. Presentation only: it is not part of the identity and does not hide the commit or `freshness`",
|
|
278
|
+
"type": "string"
|
|
279
|
+
},
|
|
280
|
+
"startedAtMs": {
|
|
281
|
+
"description": "When the execution started, epoch milliseconds",
|
|
282
|
+
"type": "number",
|
|
283
|
+
"minimum": 0
|
|
284
|
+
},
|
|
285
|
+
"endedAtMs": {
|
|
286
|
+
"description": "When the execution ended, epoch milliseconds",
|
|
287
|
+
"type": "number",
|
|
288
|
+
"minimum": 0
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
"required": [
|
|
292
|
+
"id"
|
|
293
|
+
],
|
|
294
|
+
"additionalProperties": {}
|
|
295
|
+
},
|
|
259
296
|
"recording": {
|
|
260
297
|
"anyOf": [
|
|
261
298
|
{},
|
|
@@ -328,6 +365,13 @@
|
|
|
328
365
|
"type": "string"
|
|
329
366
|
}
|
|
330
367
|
},
|
|
368
|
+
"artifactTags": {
|
|
369
|
+
"description": "Normalized tags of the attachments themselves, sorted and distinct. Absent when no attachment is tagged; never inherited from a check or run",
|
|
370
|
+
"type": "array",
|
|
371
|
+
"items": {
|
|
372
|
+
"type": "string"
|
|
373
|
+
}
|
|
374
|
+
},
|
|
331
375
|
"labels": {
|
|
332
376
|
"type": "object",
|
|
333
377
|
"propertyNames": {
|
|
@@ -75,6 +75,36 @@
|
|
|
75
75
|
"modified"
|
|
76
76
|
]
|
|
77
77
|
},
|
|
78
|
+
"run": {
|
|
79
|
+
"description": "The execution the producer named for it (one local or manual invocation). Grouping and display only; never part of the slot",
|
|
80
|
+
"type": "object",
|
|
81
|
+
"properties": {
|
|
82
|
+
"id": {
|
|
83
|
+
"type": "string",
|
|
84
|
+
"minLength": 1,
|
|
85
|
+
"maxLength": 256,
|
|
86
|
+
"description": "The execution's identity within a project, chosen by the producer: a UUID, a timestamped name. Layers with the same id are one run; it never changes after it is recorded"
|
|
87
|
+
},
|
|
88
|
+
"title": {
|
|
89
|
+
"description": "A human name for the run. Presentation only: it is not part of the identity and does not hide the commit or `freshness`",
|
|
90
|
+
"type": "string"
|
|
91
|
+
},
|
|
92
|
+
"startedAtMs": {
|
|
93
|
+
"description": "When the execution started, epoch milliseconds",
|
|
94
|
+
"type": "number",
|
|
95
|
+
"minimum": 0
|
|
96
|
+
},
|
|
97
|
+
"endedAtMs": {
|
|
98
|
+
"description": "When the execution ended, epoch milliseconds",
|
|
99
|
+
"type": "number",
|
|
100
|
+
"minimum": 0
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
"required": [
|
|
104
|
+
"id"
|
|
105
|
+
],
|
|
106
|
+
"additionalProperties": {}
|
|
107
|
+
},
|
|
78
108
|
"recording": {
|
|
79
109
|
"anyOf": [
|
|
80
110
|
{},
|
|
@@ -147,6 +177,13 @@
|
|
|
147
177
|
"type": "string"
|
|
148
178
|
}
|
|
149
179
|
},
|
|
180
|
+
"artifactTags": {
|
|
181
|
+
"description": "Normalized tags of the attachments themselves, sorted and distinct. Absent when no attachment is tagged; never inherited from a check or run",
|
|
182
|
+
"type": "array",
|
|
183
|
+
"items": {
|
|
184
|
+
"type": "string"
|
|
185
|
+
}
|
|
186
|
+
},
|
|
150
187
|
"labels": {
|
|
151
188
|
"type": "object",
|
|
152
189
|
"propertyNames": {
|
|
@@ -123,6 +123,13 @@
|
|
|
123
123
|
"type": "string"
|
|
124
124
|
}
|
|
125
125
|
},
|
|
126
|
+
"artifactTags": {
|
|
127
|
+
"description": "Normalized tags of the attachments themselves, sorted and distinct. Absent when no attachment is tagged; never inherited from a check or run",
|
|
128
|
+
"type": "array",
|
|
129
|
+
"items": {
|
|
130
|
+
"type": "string"
|
|
131
|
+
}
|
|
132
|
+
},
|
|
126
133
|
"labels": {
|
|
127
134
|
"type": "object",
|
|
128
135
|
"propertyNames": {
|
|
@@ -70,6 +70,36 @@
|
|
|
70
70
|
"modified"
|
|
71
71
|
]
|
|
72
72
|
},
|
|
73
|
+
"run": {
|
|
74
|
+
"description": "The execution this layer belongs to, when the producer names one (a local or manual run without a CI run URL). Grouping and display only; it never partitions a report or decides a result",
|
|
75
|
+
"type": "object",
|
|
76
|
+
"properties": {
|
|
77
|
+
"id": {
|
|
78
|
+
"type": "string",
|
|
79
|
+
"minLength": 1,
|
|
80
|
+
"maxLength": 256,
|
|
81
|
+
"description": "The execution's identity within a project, chosen by the producer: a UUID, a timestamped name. Layers with the same id are one run; it never changes after it is recorded"
|
|
82
|
+
},
|
|
83
|
+
"title": {
|
|
84
|
+
"description": "A human name for the run. Presentation only: it is not part of the identity and does not hide the commit or `freshness`",
|
|
85
|
+
"type": "string"
|
|
86
|
+
},
|
|
87
|
+
"startedAtMs": {
|
|
88
|
+
"description": "When the execution started, epoch milliseconds",
|
|
89
|
+
"type": "number",
|
|
90
|
+
"minimum": 0
|
|
91
|
+
},
|
|
92
|
+
"endedAtMs": {
|
|
93
|
+
"description": "When the execution ended, epoch milliseconds",
|
|
94
|
+
"type": "number",
|
|
95
|
+
"minimum": 0
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
"required": [
|
|
99
|
+
"id"
|
|
100
|
+
],
|
|
101
|
+
"additionalProperties": {}
|
|
102
|
+
},
|
|
73
103
|
"specs": {
|
|
74
104
|
"default": [],
|
|
75
105
|
"type": "array",
|
|
@@ -307,6 +337,13 @@
|
|
|
307
337
|
"description": {
|
|
308
338
|
"type": "string"
|
|
309
339
|
},
|
|
340
|
+
"tags": {
|
|
341
|
+
"description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
|
|
342
|
+
"type": "array",
|
|
343
|
+
"items": {
|
|
344
|
+
"type": "string"
|
|
345
|
+
}
|
|
346
|
+
},
|
|
310
347
|
"at": {
|
|
311
348
|
"type": "object",
|
|
312
349
|
"properties": {
|
|
@@ -535,6 +572,13 @@
|
|
|
535
572
|
"description": {
|
|
536
573
|
"type": "string"
|
|
537
574
|
},
|
|
575
|
+
"tags": {
|
|
576
|
+
"description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
|
|
577
|
+
"type": "array",
|
|
578
|
+
"items": {
|
|
579
|
+
"type": "string"
|
|
580
|
+
}
|
|
581
|
+
},
|
|
538
582
|
"at": {
|
|
539
583
|
"type": "object",
|
|
540
584
|
"properties": {
|
|
@@ -800,6 +844,13 @@
|
|
|
800
844
|
"description": {
|
|
801
845
|
"type": "string"
|
|
802
846
|
},
|
|
847
|
+
"tags": {
|
|
848
|
+
"description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
|
|
849
|
+
"type": "array",
|
|
850
|
+
"items": {
|
|
851
|
+
"type": "string"
|
|
852
|
+
}
|
|
853
|
+
},
|
|
803
854
|
"at": {
|
|
804
855
|
"type": "object",
|
|
805
856
|
"properties": {
|
|
@@ -1000,6 +1051,13 @@
|
|
|
1000
1051
|
"description": {
|
|
1001
1052
|
"type": "string"
|
|
1002
1053
|
},
|
|
1054
|
+
"tags": {
|
|
1055
|
+
"description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
|
|
1056
|
+
"type": "array",
|
|
1057
|
+
"items": {
|
|
1058
|
+
"type": "string"
|
|
1059
|
+
}
|
|
1060
|
+
},
|
|
1003
1061
|
"at": {
|
|
1004
1062
|
"type": "object",
|
|
1005
1063
|
"properties": {
|
|
@@ -1250,6 +1308,13 @@
|
|
|
1250
1308
|
"description": {
|
|
1251
1309
|
"type": "string"
|
|
1252
1310
|
},
|
|
1311
|
+
"tags": {
|
|
1312
|
+
"description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
|
|
1313
|
+
"type": "array",
|
|
1314
|
+
"items": {
|
|
1315
|
+
"type": "string"
|
|
1316
|
+
}
|
|
1317
|
+
},
|
|
1253
1318
|
"at": {
|
|
1254
1319
|
"type": "object",
|
|
1255
1320
|
"properties": {
|
|
@@ -1611,6 +1676,13 @@
|
|
|
1611
1676
|
"description": {
|
|
1612
1677
|
"type": "string"
|
|
1613
1678
|
},
|
|
1679
|
+
"tags": {
|
|
1680
|
+
"description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
|
|
1681
|
+
"type": "array",
|
|
1682
|
+
"items": {
|
|
1683
|
+
"type": "string"
|
|
1684
|
+
}
|
|
1685
|
+
},
|
|
1614
1686
|
"at": {
|
|
1615
1687
|
"type": "object",
|
|
1616
1688
|
"properties": {
|
|
@@ -1839,6 +1911,13 @@
|
|
|
1839
1911
|
"description": {
|
|
1840
1912
|
"type": "string"
|
|
1841
1913
|
},
|
|
1914
|
+
"tags": {
|
|
1915
|
+
"description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
|
|
1916
|
+
"type": "array",
|
|
1917
|
+
"items": {
|
|
1918
|
+
"type": "string"
|
|
1919
|
+
}
|
|
1920
|
+
},
|
|
1842
1921
|
"at": {
|
|
1843
1922
|
"type": "object",
|
|
1844
1923
|
"properties": {
|
|
@@ -2104,6 +2183,13 @@
|
|
|
2104
2183
|
"description": {
|
|
2105
2184
|
"type": "string"
|
|
2106
2185
|
},
|
|
2186
|
+
"tags": {
|
|
2187
|
+
"description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
|
|
2188
|
+
"type": "array",
|
|
2189
|
+
"items": {
|
|
2190
|
+
"type": "string"
|
|
2191
|
+
}
|
|
2192
|
+
},
|
|
2107
2193
|
"at": {
|
|
2108
2194
|
"type": "object",
|
|
2109
2195
|
"properties": {
|
|
@@ -2304,6 +2390,13 @@
|
|
|
2304
2390
|
"description": {
|
|
2305
2391
|
"type": "string"
|
|
2306
2392
|
},
|
|
2393
|
+
"tags": {
|
|
2394
|
+
"description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
|
|
2395
|
+
"type": "array",
|
|
2396
|
+
"items": {
|
|
2397
|
+
"type": "string"
|
|
2398
|
+
}
|
|
2399
|
+
},
|
|
2307
2400
|
"at": {
|
|
2308
2401
|
"type": "object",
|
|
2309
2402
|
"properties": {
|
|
@@ -2720,6 +2813,13 @@
|
|
|
2720
2813
|
"description": {
|
|
2721
2814
|
"type": "string"
|
|
2722
2815
|
},
|
|
2816
|
+
"tags": {
|
|
2817
|
+
"description": "Free labels of this one attachment, such as `demo`: shown as `#demo`, searchable, and normalized by `normalizeTag` (a leading `#` and letter case never matter). Unlike the tags of a check they say nothing about its result",
|
|
2818
|
+
"type": "array",
|
|
2819
|
+
"items": {
|
|
2820
|
+
"type": "string"
|
|
2821
|
+
}
|
|
2822
|
+
},
|
|
2723
2823
|
"at": {
|
|
2724
2824
|
"type": "object",
|
|
2725
2825
|
"properties": {
|