govgate 0.2.2 → 0.3.1
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 +16 -20
- package/dist/index.js +12 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# govgate
|
|
2
2
|
|
|
3
|
-
Pipeline-step CLI for
|
|
3
|
+
Pipeline-step CLI for Governance OS: parses standard test output (JUnit XML),
|
|
4
4
|
maps tests to test cases, reports a run, and **gates the release** via its exit code.
|
|
5
5
|
No SDK in application code — only the pipeline YAML changes.
|
|
6
6
|
|
|
@@ -19,9 +19,9 @@ standard reporter.
|
|
|
19
19
|
|
|
20
20
|
| Flag | Default | Meaning |
|
|
21
21
|
|---|---|---|
|
|
22
|
-
| `--url <url>` | `
|
|
23
|
-
| `--api-key <key>` | `
|
|
24
|
-
| `--config <path>` |
|
|
22
|
+
| `--url <url>` | `GOVGATE_URL` | Tool deployment URL |
|
|
23
|
+
| `--api-key <key>` | `GOVGATE_API_KEY` | API key (env var strongly preferred) |
|
|
24
|
+
| `--config <path>` | `govgate/config.json` searched upward | Config file |
|
|
25
25
|
| `--suite <slug>` | config `suite` | Target suite |
|
|
26
26
|
| `--env <slug>` | config `defaultEnvironment` | Environment for the run |
|
|
27
27
|
| `--name <name>` | derived from CI context | Run name |
|
|
@@ -61,7 +61,7 @@ Resolution per test (results are unioned):
|
|
|
61
61
|
what .NET JUnit loggers emit), an underscore-delimited `Mt<n>` token maps the test:
|
|
62
62
|
`Mt5_DuplicateEmail_Rejected`, `Profiles_Mt12_NotFound`, `Delete_Resolves_MT28`.
|
|
63
63
|
Embedded substrings (`GMT5_…`, `Format2_…`) do not match.
|
|
64
|
-
3. **Config patterns** in
|
|
64
|
+
3. **Config patterns** in `govgate/config.json`:
|
|
65
65
|
|
|
66
66
|
```jsonc
|
|
67
67
|
{
|
|
@@ -83,10 +83,9 @@ any passing → `pass`; all skipped → the case is not posted (stays pending
|
|
|
83
83
|
test is a non-observation). Suite cases with no mapped tests stay pending and are
|
|
84
84
|
listed as "uncovered" in the summary.
|
|
85
85
|
|
|
86
|
-
Use the `map-tests`
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
validate it.
|
|
86
|
+
Use the `map-tests` Governance OS skill (served by your deployment at
|
|
87
|
+
`${GOVGATE_URL}/api/v1/skills`) to generate the mapping semi-automatically, and
|
|
88
|
+
`--dry-run` to validate it.
|
|
90
89
|
|
|
91
90
|
## .NET specifics (learned the hard way)
|
|
92
91
|
|
|
@@ -102,28 +101,25 @@ validate it.
|
|
|
102
101
|
- **Classic Release has no source checkout**: `dotnet publish` the test project into
|
|
103
102
|
the build artifact (`drop/tests/`) and run it with the ".NET Core" task using
|
|
104
103
|
Command `custom` + `vstest` — the `run` command does NOT execute arbitrary commands.
|
|
105
|
-
- The full ADO runbook (variable groups, stage scoping, exact task configs)
|
|
106
|
-
`
|
|
107
|
-
|
|
108
|
-
repo — or run the `onboard-repo` skill.
|
|
104
|
+
- The full ADO runbook (variable groups, stage scoping, exact task configs) is the
|
|
105
|
+
`onboard-repo` Governance OS skill (served at `${GOVGATE_URL}/api/v1/skills`) — run it,
|
|
106
|
+
or read its `reference.md`.
|
|
109
107
|
|
|
110
108
|
## Multi-job pipelines
|
|
111
109
|
|
|
112
110
|
```bash
|
|
113
111
|
# job A — creates the run, leaves it open
|
|
114
|
-
govgate report unit-results.xml --no-complete # emits
|
|
112
|
+
govgate report unit-results.xml --no-complete # emits GOVGATE_RUN_ID (GH output / ADO variable)
|
|
115
113
|
|
|
116
114
|
# job B — appends to the same run
|
|
117
|
-
govgate report e2e-results.xml --run-id $
|
|
115
|
+
govgate report e2e-results.xml --run-id $GOVGATE_RUN_ID --no-complete
|
|
118
116
|
|
|
119
117
|
# final job — completes + gates over everything
|
|
120
|
-
govgate complete --run-id $
|
|
118
|
+
govgate complete --run-id $GOVGATE_RUN_ID --fail-on fail --min-executed 80
|
|
121
119
|
```
|
|
122
120
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
[Maersk-Training/mt-testing-tool](https://github.com/Maersk-Training/mt-testing-tool)
|
|
126
|
-
repo for full pipelines.
|
|
121
|
+
Full pipeline examples for GitHub Actions and Azure DevOps ship with your Governance OS
|
|
122
|
+
deployment (served alongside the skills at `${GOVGATE_URL}/api/v1/skills`).
|
|
127
123
|
|
|
128
124
|
## Registry
|
|
129
125
|
|
package/dist/index.js
CHANGED
|
@@ -104,12 +104,12 @@ function detectCiContext(env = process.env) {
|
|
|
104
104
|
};
|
|
105
105
|
}
|
|
106
106
|
function emitRunIdVariable(runId, ctx, env = process.env) {
|
|
107
|
-
console.log(`
|
|
107
|
+
console.log(`GOVGATE_RUN_ID=${runId}`);
|
|
108
108
|
if (ctx.provider === "github" && env.GITHUB_OUTPUT) {
|
|
109
109
|
appendFileSync(env.GITHUB_OUTPUT, `run-id=${runId}
|
|
110
110
|
`);
|
|
111
111
|
} else if (ctx.provider === "azure-devops") {
|
|
112
|
-
console.log(`##vso[task.setvariable variable=
|
|
112
|
+
console.log(`##vso[task.setvariable variable=GOVGATE_RUN_ID;isOutput=true]${runId}`);
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
115
|
|
|
@@ -126,7 +126,7 @@ function findConfigFile(startDir, explicitPath) {
|
|
|
126
126
|
}
|
|
127
127
|
let dir = resolve(startDir);
|
|
128
128
|
for (; ; ) {
|
|
129
|
-
const candidate = join(dir, ".
|
|
129
|
+
const candidate = join(dir, "govgate", "config.json");
|
|
130
130
|
if (existsSync(candidate)) return candidate;
|
|
131
131
|
const parent = dirname(dir);
|
|
132
132
|
if (parent === dir) return void 0;
|
|
@@ -182,23 +182,23 @@ function loadFileMappings(flags, cwd = process.cwd()) {
|
|
|
182
182
|
function resolveConfig(flags, cwd = process.cwd()) {
|
|
183
183
|
const configPath = findConfigFile(cwd, flags.config);
|
|
184
184
|
const file = configPath ? loadFileConfig(configPath) : {};
|
|
185
|
-
const url = flags.url ?? process.env.
|
|
186
|
-
const apiKey = flags.apiKey ?? process.env.
|
|
185
|
+
const url = flags.url ?? process.env.GOVGATE_URL;
|
|
186
|
+
const apiKey = flags.apiKey ?? process.env.GOVGATE_API_KEY;
|
|
187
187
|
const suite = flags.suite ?? file.suite;
|
|
188
188
|
const environment = flags.env ?? file.defaultEnvironment;
|
|
189
189
|
if (!url) {
|
|
190
190
|
throw new ConfigError(
|
|
191
|
-
"Tool URL missing. Set
|
|
191
|
+
"Tool URL missing. Set GOVGATE_URL or pass --url https://<your-deployment>"
|
|
192
192
|
);
|
|
193
193
|
}
|
|
194
194
|
if (!apiKey) {
|
|
195
195
|
throw new ConfigError(
|
|
196
|
-
"API key missing. Set
|
|
196
|
+
"API key missing. Set GOVGATE_API_KEY (create one in the tool: Admin -> API keys, scoped to this application)."
|
|
197
197
|
);
|
|
198
198
|
}
|
|
199
199
|
if (!suite) {
|
|
200
200
|
throw new ConfigError(
|
|
201
|
-
'Suite missing. Pass --suite <slug> or add { "suite": "<slug>" } to .
|
|
201
|
+
'Suite missing. Pass --suite <slug> or add { "suite": "<slug>" } to govgate/config.json in the repo root.'
|
|
202
202
|
);
|
|
203
203
|
}
|
|
204
204
|
return {
|
|
@@ -402,7 +402,7 @@ function printMappingTable(outcome) {
|
|
|
402
402
|
}
|
|
403
403
|
if (outcome.unmappedTests.length) {
|
|
404
404
|
console.log(`
|
|
405
|
-
Unmapped tests (${outcome.unmappedTests.length}) \u2014 add @mt-<case> tags or .
|
|
405
|
+
Unmapped tests (${outcome.unmappedTests.length}) \u2014 add @mt-<case> tags or govgate/config.json mappings:`);
|
|
406
406
|
for (const t of outcome.unmappedTests.slice(0, 20)) console.log(` - ${t.id}`);
|
|
407
407
|
if (outcome.unmappedTests.length > 20)
|
|
408
408
|
console.log(` \u2026 and ${outcome.unmappedTests.length - 20} more`);
|
|
@@ -486,8 +486,8 @@ async function completeAndGate(api, url, runId, gate) {
|
|
|
486
486
|
printRunUrl(url, runId);
|
|
487
487
|
if (!verdict.passed) process.exit(EXIT_GATE_FAILED);
|
|
488
488
|
}
|
|
489
|
-
var program = new Command().name("govgate").description("Report CI test results to
|
|
490
|
-
program.command("report").description("Parse test result files (JUnit XML), map tests to cases, and report a run").argument("<files...>", "result files or globs, e.g. test-results/*.xml").option("--url <url>", "tool URL (or
|
|
489
|
+
var program = new Command().name("govgate").description("Report CI test results to your testing tool and gate releases on the outcome.");
|
|
490
|
+
program.command("report").description("Parse test result files (JUnit XML), map tests to cases, and report a run").argument("<files...>", "result files or globs, e.g. test-results/*.xml").option("--url <url>", "tool URL (or GOVGATE_URL)").option("--api-key <key>", "API key (prefer GOVGATE_API_KEY)").option("--config <path>", "path to govgate/config.json (default: searched upward)").option("--suite <slug>", "suite slug (overrides config)").option("--env <slug>", "environment slug (overrides config)").option("--name <name>", "run name (default: derived from CI context)").option("--build-version <v>", "build version (default: short commit SHA from CI)").option("--external-url <url>", "link to the build/PR (default: from CI context)").option("--format <format>", "input format", "junit").option("--run-id <uuid>", "append results to an existing run instead of creating one").option("--no-complete", "leave the run in progress (multi-job pipelines); skips the gate").option("--fail-on <list>", "statuses that fail the gate: fail | fail,blocked", "fail").option("--min-executed <pct>", "minimum executed percentage required by the gate").option("--actor <label>", "tested-by label on results", "govgate").option("--dry-run", "parse and map only; post nothing").action(async (files, opts) => {
|
|
491
491
|
try {
|
|
492
492
|
const flags = {
|
|
493
493
|
url: opts.url,
|
|
@@ -564,7 +564,7 @@ function tryResolveConfig(flags) {
|
|
|
564
564
|
return void 0;
|
|
565
565
|
}
|
|
566
566
|
}
|
|
567
|
-
program.command("complete").description("Complete a run and evaluate the gate (final job of a multi-job pipeline)").requiredOption("--run-id <uuid>", "run to complete").option("--url <url>", "tool URL (or
|
|
567
|
+
program.command("complete").description("Complete a run and evaluate the gate (final job of a multi-job pipeline)").requiredOption("--run-id <uuid>", "run to complete").option("--url <url>", "tool URL (or GOVGATE_URL)").option("--api-key <key>", "API key (prefer GOVGATE_API_KEY)").option("--config <path>", "path to govgate/config.json").option("--suite <slug>", "suite slug (only used for config resolution)").option("--fail-on <list>", "statuses that fail the gate: fail | fail,blocked", "fail").option("--min-executed <pct>", "minimum executed percentage required by the gate").action(async (opts) => {
|
|
568
568
|
try {
|
|
569
569
|
const config = resolveConfig({
|
|
570
570
|
url: opts.url,
|
package/package.json
CHANGED