@secureci/cli 0.1.0 ā 0.2.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 +40 -6
- package/dist/cli.js +1 -0
- package/dist/init.js +3 -2
- package/dist/report.js +1 -1
- package/dist/utils/ansi.js +47 -0
- package/dist/utils/logger.js +8 -11
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Test and vet your GitHub Actions **before you push**.
|
|
|
7
7
|
`@secureci/cli` (the `secureci` command) runs your workflows locally, validates
|
|
8
8
|
them, and checks them against your organization's pipeline standards ā without
|
|
9
9
|
committing, pushing, or waiting on a CI runner. It is the free, open-source part
|
|
10
|
-
of [SecureCI](https://
|
|
10
|
+
of [SecureCI](https://secure-ci.dev).
|
|
11
11
|
|
|
12
12
|
> š This README is the quick tour. Every flag, context and edge case lives in
|
|
13
13
|
> the **[full reference ā DOCS.md](DOCS.md)**.
|
|
@@ -38,8 +38,8 @@ npm install -g @secureci/cli
|
|
|
38
38
|
npx @secureci/cli --help
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
Node.js 20+ is required.
|
|
42
|
-
|
|
41
|
+
Node.js 20+ is required. To build from source instead:
|
|
42
|
+
`npm install && npm run build`.
|
|
43
43
|
|
|
44
44
|
## First run
|
|
45
45
|
|
|
@@ -74,6 +74,11 @@ secureci inventory --check # fail on drift (use in CI)
|
|
|
74
74
|
check.
|
|
75
75
|
- **Machine-readable output** ā `--format json|sarif` drops straight into CI and
|
|
76
76
|
GitHub code scanning.
|
|
77
|
+
- **Audit evidence** ā the contract, `secureci.lock` and reports are plain files
|
|
78
|
+
you can commit and keep. See
|
|
79
|
+
[using output as audit evidence](DOCS.md#using-output-as-audit-evidence) and
|
|
80
|
+
the [compliance mapping](https://secure-ci.dev/compliance) (PCI DSS, DORA,
|
|
81
|
+
NIS2, ISO 27001, SOC 2 and more).
|
|
77
82
|
|
|
78
83
|
See the [reference](DOCS.md) for the complete command list and flags.
|
|
79
84
|
|
|
@@ -162,8 +167,26 @@ The exact scope of each is documented in
|
|
|
162
167
|
redacted in all output, and in container mode never appear on the client
|
|
163
168
|
command line (passed via a `0600` env file). Prefer `--secret NAME` so the
|
|
164
169
|
value stays out of your shell history too.
|
|
165
|
-
- **Tokens are handled carefully** ā only
|
|
166
|
-
|
|
170
|
+
- **Tokens are handled carefully** ā sent only to the GitHub host in
|
|
171
|
+
`GITHUB_SERVER_URL` / `GITHUB_API_URL` (github.com by default), never passed
|
|
172
|
+
to actions, and masked in logs.
|
|
173
|
+
|
|
174
|
+
### What the package accesses, and why
|
|
175
|
+
|
|
176
|
+
Installing and running `secureci` involves these capabilities. Each is needed for
|
|
177
|
+
the feature named, and none runs at install time.
|
|
178
|
+
|
|
179
|
+
| Capability | Where | Why |
|
|
180
|
+
| ------------------------ | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
181
|
+
| Shell / process spawning | `run:` steps, JavaScript actions, `docker`/`podman`/`nerdctl` | Runs workflow steps in a container (or on your host with `--container-runtime host`). `commander` also loads `child_process`, used only for executable subcommands this CLI does not use. |
|
|
182
|
+
| Network | `github.com`, `api.github.com` (or the GHES host you set) | Downloads actions and workflows, and resolves tags to commit SHAs. |
|
|
183
|
+
| Environment variables | `HOME`, `PATH`, `GITHUB_*`, `GITHUB_TOKEN`, `GH_TOKEN` | Builds the runner environment and authenticates GitHub downloads. |
|
|
184
|
+
| Filesystem | `~/.secureci/`, the working directory, temp dirs | Caches actions, stores artifacts and config, and reads your workflow files. |
|
|
185
|
+
| Hard-coded URLs | GitHub documentation and JSON Schema URLs in messages and editor hints | Informational only; the CLI does not fetch them. |
|
|
186
|
+
|
|
187
|
+
No install scripts run for consumers. The published tarball contains only
|
|
188
|
+
`dist/`, `README.md`, and `LICENSE`. See [SECURITY.md](SECURITY.md) for how to
|
|
189
|
+
report a vulnerability.
|
|
167
190
|
|
|
168
191
|
Full details: [DOCS.md ā Security: what runs where](DOCS.md#security-what-runs-where)
|
|
169
192
|
and [Secret masking](DOCS.md#secret-masking).
|
|
@@ -199,4 +222,15 @@ humans and agents live in [AGENTS.md](AGENTS.md) and
|
|
|
199
222
|
|
|
200
223
|
## License
|
|
201
224
|
|
|
202
|
-
MIT
|
|
225
|
+
The code is licensed under the [MIT License](LICENSE).
|
|
226
|
+
|
|
227
|
+
## Name and trademark
|
|
228
|
+
|
|
229
|
+
The **code** is open source under MIT; the **SecureCI name and logo** are not.
|
|
230
|
+
"SecureCI", the `secureci` command branding, and the `@secureci` npm scope are
|
|
231
|
+
trademarks of SecureCI. You may use the name to describe your use of this
|
|
232
|
+
software (for example, "works with SecureCI"), but you may not use it to name or
|
|
233
|
+
brand a fork, a derivative product or service, or a hosted offering, and you may
|
|
234
|
+
not imply endorsement by SecureCI. Forks must use a different name and must not
|
|
235
|
+
publish under the `@secureci` scope. These rights are reserved and are not granted by the
|
|
236
|
+
MIT License.
|
package/dist/cli.js
CHANGED
package/dist/init.js
CHANGED
|
@@ -3,7 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.renderInitWorkflow = renderInitWorkflow;
|
|
4
4
|
/**
|
|
5
5
|
* Render a ready-to-commit `.github/workflows/secureci.yml` that runs SecureCI
|
|
6
|
-
* on every pull request via the published `secure-ci/cli` action
|
|
6
|
+
* on every pull request via the published `secure-ci/cli` action, pinned to
|
|
7
|
+
* the release tag matching this CLI's version.
|
|
7
8
|
*
|
|
8
9
|
* The output is deterministic for a given set of options, so it can be
|
|
9
10
|
* regenerated and diffed. With uploads on (the default) the workflow asks for
|
|
@@ -26,7 +27,7 @@ function renderInitWorkflow(options) {
|
|
|
26
27
|
];
|
|
27
28
|
if (upload)
|
|
28
29
|
lines.push(' security-events: write');
|
|
29
|
-
lines.push('', 'jobs:', ' secureci:', ' runs-on: ubuntu-latest', ' steps:', ' - uses: actions/checkout@v4',
|
|
30
|
+
lines.push('', 'jobs:', ' secureci:', ' runs-on: ubuntu-latest', ' steps:', ' - uses: actions/checkout@v4', ` - uses: secure-ci/cli@v${options.version}`);
|
|
30
31
|
const withLines = [];
|
|
31
32
|
if (contract)
|
|
32
33
|
withLines.push(` contract: ${yamlScalar(contract)}`);
|
package/dist/report.js
CHANGED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal terminal colouring for log output. Replaces `chalk`, whose
|
|
4
|
+
* transitive dependencies (supports-color, has-flag, ansi-styles, ...) pull in
|
|
5
|
+
* an unmaintained package and add supply-chain surface for a few log colours.
|
|
6
|
+
*
|
|
7
|
+
* Colour is used only on a terminal, and is turned off by NO_COLOR or
|
|
8
|
+
* TERM=dumb, or turned on by FORCE_COLOR, following the same conventions chalk
|
|
9
|
+
* followed.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.colors = void 0;
|
|
13
|
+
exports.createColors = createColors;
|
|
14
|
+
// [open, close] SGR codes.
|
|
15
|
+
const CODES = {
|
|
16
|
+
gray: [90, 39],
|
|
17
|
+
red: [31, 39],
|
|
18
|
+
green: [32, 39],
|
|
19
|
+
yellow: [33, 39],
|
|
20
|
+
blue: [34, 39],
|
|
21
|
+
cyan: [36, 39]
|
|
22
|
+
};
|
|
23
|
+
function colorEnabled(env, isTTY) {
|
|
24
|
+
if (env.NO_COLOR !== undefined && env.NO_COLOR !== '')
|
|
25
|
+
return false;
|
|
26
|
+
if (env.TERM === 'dumb')
|
|
27
|
+
return false;
|
|
28
|
+
if (env.FORCE_COLOR !== undefined && env.FORCE_COLOR !== '0')
|
|
29
|
+
return true;
|
|
30
|
+
return isTTY;
|
|
31
|
+
}
|
|
32
|
+
/** Build the colour functions for a given environment and output stream. */
|
|
33
|
+
function createColors(env, isTTY) {
|
|
34
|
+
const enabled = colorEnabled(env, isTTY);
|
|
35
|
+
const paint = ([open, close]) => (text) => enabled ? `\u001b[${open}m${text}\u001b[${close}m` : text;
|
|
36
|
+
return {
|
|
37
|
+
gray: paint(CODES.gray),
|
|
38
|
+
red: paint(CODES.red),
|
|
39
|
+
green: paint(CODES.green),
|
|
40
|
+
yellow: paint(CODES.yellow),
|
|
41
|
+
blue: paint(CODES.blue),
|
|
42
|
+
cyan: paint(CODES.cyan)
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/** Colours for the process's stdout. */
|
|
46
|
+
exports.colors = createColors(process.env, Boolean(process.stdout.isTTY));
|
|
47
|
+
//# sourceMappingURL=ansi.js.map
|
package/dist/utils/logger.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.logger = exports.LogLevel = void 0;
|
|
7
|
-
const
|
|
4
|
+
const ansi_1 = require("./ansi");
|
|
8
5
|
var LogLevel;
|
|
9
6
|
(function (LogLevel) {
|
|
10
7
|
LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
|
|
@@ -51,35 +48,35 @@ class Logger {
|
|
|
51
48
|
}
|
|
52
49
|
debug(message, ...args) {
|
|
53
50
|
if (this.level <= LogLevel.DEBUG) {
|
|
54
|
-
console.log(
|
|
51
|
+
console.log(ansi_1.colors.gray(`[DEBUG] ${this.mask(message)}`), ...args.map((a) => this.maskArg(a)));
|
|
55
52
|
}
|
|
56
53
|
}
|
|
57
54
|
info(message, ...args) {
|
|
58
55
|
if (this.level <= LogLevel.INFO) {
|
|
59
|
-
console.log(
|
|
56
|
+
console.log(ansi_1.colors.blue(`[INFO] ${this.mask(message)}`), ...args.map((a) => this.maskArg(a)));
|
|
60
57
|
}
|
|
61
58
|
}
|
|
62
59
|
success(message, ...args) {
|
|
63
60
|
if (this.level <= LogLevel.INFO) {
|
|
64
|
-
console.log(
|
|
61
|
+
console.log(ansi_1.colors.green(`ā ${this.mask(message)}`), ...args.map((a) => this.maskArg(a)));
|
|
65
62
|
}
|
|
66
63
|
}
|
|
67
64
|
warn(message, ...args) {
|
|
68
65
|
if (this.level <= LogLevel.WARN) {
|
|
69
|
-
console.warn(
|
|
66
|
+
console.warn(ansi_1.colors.yellow(`[WARN] ${this.mask(message)}`), ...args.map((a) => this.maskArg(a)));
|
|
70
67
|
}
|
|
71
68
|
}
|
|
72
69
|
error(message, ...args) {
|
|
73
70
|
if (this.level <= LogLevel.ERROR) {
|
|
74
|
-
console.error(
|
|
71
|
+
console.error(ansi_1.colors.red(`[ERROR] ${this.mask(message)}`), ...args.map((a) => this.maskArg(a)));
|
|
75
72
|
}
|
|
76
73
|
}
|
|
77
74
|
step(message) {
|
|
78
|
-
console.log(
|
|
75
|
+
console.log(ansi_1.colors.cyan(`\nā ${this.mask(message)}`));
|
|
79
76
|
}
|
|
80
77
|
result(message, success) {
|
|
81
78
|
const icon = success ? 'ā' : 'ā';
|
|
82
|
-
const color = success ?
|
|
79
|
+
const color = success ? ansi_1.colors.green : ansi_1.colors.red;
|
|
83
80
|
console.log(color(`${icon} ${this.mask(message)}`));
|
|
84
81
|
}
|
|
85
82
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@secureci/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "SecureCI: validate, check against pipeline standards, and run GitHub Actions workflows locally",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
}
|
|
43
43
|
],
|
|
44
44
|
"license": "MIT",
|
|
45
|
-
"homepage": "https://
|
|
45
|
+
"homepage": "https://secure-ci.dev",
|
|
46
46
|
"repository": {
|
|
47
47
|
"type": "git",
|
|
48
48
|
"url": "git+https://github.com/secure-ci/cli.git"
|
|
@@ -58,7 +58,6 @@
|
|
|
58
58
|
},
|
|
59
59
|
"prettier": "@jabraf/prettier",
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"chalk": "^4.1.2",
|
|
62
61
|
"commander": "^11.1.0",
|
|
63
62
|
"yaml": "^2.3.4"
|
|
64
63
|
},
|