@secureci/cli 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +230 -2
- package/dist/cli.js +545 -0
- package/dist/config.js +190 -0
- package/dist/index.js +23 -0
- package/dist/init.js +45 -0
- package/dist/inventory.js +212 -0
- package/dist/parser/pipeline-contract-parser.js +131 -0
- package/dist/parser/pipeline-contract-validator.js +448 -0
- package/dist/parser/validator.js +232 -0
- package/dist/parser/workflow-parser.js +122 -0
- package/dist/report.js +75 -0
- package/dist/runner/action-fetcher.js +431 -0
- package/dist/runner/actions.js +495 -0
- package/dist/runner/builtin-actions.js +484 -0
- package/dist/runner/checkout.js +142 -0
- package/dist/runner/container-runtime.js +374 -0
- package/dist/runner/docker-action.js +179 -0
- package/dist/runner/dry-run.js +142 -0
- package/dist/runner/executor.js +554 -0
- package/dist/runner/expression.js +676 -0
- package/dist/runner/github-context.js +235 -0
- package/dist/runner/hash-files.js +123 -0
- package/dist/runner/job-container.js +322 -0
- package/dist/runner/job-plan.js +138 -0
- package/dist/runner/job-runtime.js +338 -0
- package/dist/runner/node-action.js +278 -0
- package/dist/runner/runner-env.js +303 -0
- package/dist/runner/shell.js +61 -0
- package/dist/runner/steps.js +250 -0
- package/dist/types/index.js +10 -0
- package/dist/utils/ansi.js +47 -0
- package/dist/utils/key-value.js +33 -0
- package/dist/utils/logger.js +84 -0
- package/dist/utils/repository.js +51 -0
- package/package.json +76 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SecureCI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,231 @@
|
|
|
1
|
-
#
|
|
1
|
+
# SecureCI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/secure-ci/cli/actions/workflows/ci.yaml)
|
|
4
|
+
|
|
5
|
+
Test and vet your GitHub Actions **before you push**.
|
|
6
|
+
|
|
7
|
+
`@secureci/cli` (the `secureci` command) runs your workflows locally, validates
|
|
8
|
+
them, and checks them against your organization's pipeline standards — without
|
|
9
|
+
committing, pushing, or waiting on a CI runner. It is the free, open-source part
|
|
10
|
+
of [SecureCI](https://www.secure-ci.dev).
|
|
11
|
+
|
|
12
|
+
> 📖 This README is the quick tour. Every flag, context and edge case lives in
|
|
13
|
+
> the **[full reference → DOCS.md](DOCS.md)**.
|
|
14
|
+
|
|
15
|
+
## What it is
|
|
16
|
+
|
|
17
|
+
A single CLI that understands GitHub Actions the way the runner does:
|
|
18
|
+
|
|
19
|
+
- **Run workflows locally** — jobs in `needs:` order, matrix builds, reusable
|
|
20
|
+
workflows, composite / JavaScript / Docker actions, and the full
|
|
21
|
+
`${{ }}` / `if:` expression language.
|
|
22
|
+
- **Validate** workflow and action files, and **check them against a pipeline
|
|
23
|
+
contract** (required/forbidden actions, ordering, minimum versions,
|
|
24
|
+
SHA-pinning rules).
|
|
25
|
+
- **Inventory** every action a workflow pulls in, resolve each tag to a commit
|
|
26
|
+
SHA, and **catch supply-chain drift** when a tag quietly starts pointing
|
|
27
|
+
somewhere new.
|
|
28
|
+
|
|
29
|
+
Because it evaluates expressions and `if:` conditions like GitHub does — honoring
|
|
30
|
+
context-availability rules and rejecting invalid `if:` the same way — you get
|
|
31
|
+
far fewer false positives than plain pattern-matching tools.
|
|
32
|
+
|
|
33
|
+
## Install
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install -g @secureci/cli
|
|
37
|
+
# or run without installing:
|
|
38
|
+
npx @secureci/cli --help
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Node.js 20+ is required. (Until the package is published to npm, build from
|
|
42
|
+
source: `npm install && npm run build`.)
|
|
43
|
+
|
|
44
|
+
## First run
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# See what a workflow would do, without running anything
|
|
48
|
+
secureci run .github/workflows/ci.yml --dry-run
|
|
49
|
+
|
|
50
|
+
# Run it for real (one container per job by default)
|
|
51
|
+
secureci run .github/workflows/ci.yml --input key=value
|
|
52
|
+
|
|
53
|
+
# Check a workflow's syntax
|
|
54
|
+
secureci validate .github/workflows/ci.yml
|
|
55
|
+
|
|
56
|
+
# Generate a ready-to-commit PR-checks workflow
|
|
57
|
+
secureci init workflow
|
|
58
|
+
|
|
59
|
+
# Lock the actions you use and catch supply-chain drift (commit secureci.lock)
|
|
60
|
+
secureci inventory # bootstraps secureci.lock, then drift-checks
|
|
61
|
+
secureci inventory --check # fail on drift (use in CI)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Where it shines
|
|
65
|
+
|
|
66
|
+
- **Fast feedback loop** — iterate on a workflow in seconds instead of
|
|
67
|
+
push-wait-repeat.
|
|
68
|
+
- **Enforce org-wide standards** — a platform team writes one
|
|
69
|
+
[pipeline contract](DOCS.md#pipeline-contracts-validate---contract) ("every
|
|
70
|
+
deploy must run `security-scan ≥ v1.2` first, pinned to a SHA") and every repo
|
|
71
|
+
is checked against it, locally and in CI.
|
|
72
|
+
- **Supply-chain visibility** — [`secureci inventory`](DOCS.md#action-inventory-and-drift-secureci-inventory)
|
|
73
|
+
with a committed lockfile turns a silently moved action tag into a failing
|
|
74
|
+
check.
|
|
75
|
+
- **Machine-readable output** — `--format json|sarif` drops straight into CI and
|
|
76
|
+
GitHub code scanning.
|
|
77
|
+
|
|
78
|
+
See the [reference](DOCS.md) for the complete command list and flags.
|
|
79
|
+
|
|
80
|
+
## Supported environments
|
|
81
|
+
|
|
82
|
+
Each job (and each matrix combination) runs in **one container**, started when
|
|
83
|
+
the job begins and removed when it ends. Every `run:` step and JavaScript action
|
|
84
|
+
in the job reuses it, so tools and files from earlier steps persist.
|
|
85
|
+
|
|
86
|
+
- **Container runtimes:** Docker (default), Podman, or containerd (via
|
|
87
|
+
[`nerdctl`](https://github.com/containerd/nerdctl)) — selected with
|
|
88
|
+
`--container-runtime`. The image follows `jobs.<id>.container`,
|
|
89
|
+
`--container-image`, or a `runs-on` → runner-image mapping you can override in
|
|
90
|
+
config.
|
|
91
|
+
- **Service containers** (`jobs.<id>.services`) — databases, caches and other
|
|
92
|
+
sidecars start before the job, join its network (reachable by hostname like
|
|
93
|
+
`postgres:5432`), wait for health checks, and are torn down with the job.
|
|
94
|
+
- **Host mode** (`--container-runtime host`) — an explicit opt-in to run steps
|
|
95
|
+
directly on your machine (see [Security](#security)).
|
|
96
|
+
|
|
97
|
+
Details, image mapping and config: [DOCS.md → Container isolation](DOCS.md#container-isolation).
|
|
98
|
+
|
|
99
|
+
## Examples
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# Run a single job with inputs and a repository variable
|
|
103
|
+
secureci run .github/workflows/ci.yml --job build --input ref=main --var ENV=staging
|
|
104
|
+
|
|
105
|
+
# Pass a secret by name (value read from your environment, not the command line)
|
|
106
|
+
secureci run .github/workflows/deploy.yml --secret TOKEN
|
|
107
|
+
|
|
108
|
+
# Validate against a central pipeline contract, recursing into called workflows
|
|
109
|
+
secureci validate .github/workflows/deploy.yml \
|
|
110
|
+
--contract contracts/platform-standard.yml --contract-recurse all
|
|
111
|
+
|
|
112
|
+
# Emit SARIF for GitHub code scanning
|
|
113
|
+
secureci validate .github/workflows/*.yml --format sarif > results.sarif
|
|
114
|
+
|
|
115
|
+
# Fail if any action drifted from the committed secureci.lock
|
|
116
|
+
secureci inventory --check
|
|
117
|
+
|
|
118
|
+
# Podman, a memory cap, and no network for the job containers
|
|
119
|
+
secureci run .github/workflows/ci.yml \
|
|
120
|
+
--container-runtime podman --container-memory 512m --no-network
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
More patterns — events, matrices, artifacts, caching, reusable workflows, CI
|
|
124
|
+
usage — are in [DOCS.md](DOCS.md).
|
|
125
|
+
|
|
126
|
+
## Limitations
|
|
127
|
+
|
|
128
|
+
The CLI aims for high runner fidelity, but it is not the GitHub runner. The main
|
|
129
|
+
things to know:
|
|
130
|
+
|
|
131
|
+
- **Linux containers only.** `windows-*` / `macos-*` jobs run in a Linux image
|
|
132
|
+
with a warning.
|
|
133
|
+
- **Matrix and reusable-workflow jobs run sequentially.** `max-parallel` is
|
|
134
|
+
accepted but has no effect.
|
|
135
|
+
- **`actions/checkout` of the current repo doesn't clone** — it uses your working
|
|
136
|
+
copy as-is (so uncommitted changes are visible); `ref:`/`fetch-depth:` are
|
|
137
|
+
ignored. Other repositories check out for real and need a token.
|
|
138
|
+
- **Artifacts and cache are local stand-ins**, stored under `~/.secureci/`;
|
|
139
|
+
nothing is uploaded to or downloaded from GitHub.
|
|
140
|
+
- **Contract checks** don't evaluate `if:` conditions and, without
|
|
141
|
+
`--contract-recurse all`, don't look inside _remote_ composite actions /
|
|
142
|
+
reusable workflows.
|
|
143
|
+
|
|
144
|
+
The exact scope of each is documented in
|
|
145
|
+
[DOCS.md](DOCS.md#contract-limitations-v1-scope).
|
|
146
|
+
|
|
147
|
+
## Security
|
|
148
|
+
|
|
149
|
+
> [!WARNING]
|
|
150
|
+
> The CLI **never silently runs steps on your machine.** If the container
|
|
151
|
+
> runtime isn't available, it reports that and exits without running anything.
|
|
152
|
+
|
|
153
|
+
- **Sandboxed by default.** Steps and actions run in a container, not on your
|
|
154
|
+
host.
|
|
155
|
+
- **Host mode is explicit.** Only `--container-runtime host` runs `run:` steps
|
|
156
|
+
and third-party actions directly, with your user's privileges — the CLI warns
|
|
157
|
+
and lists the remote actions first.
|
|
158
|
+
- **No ambient environment or secrets.** On the host, steps get only a minimal
|
|
159
|
+
allowlist plus the runner's `GITHUB_*`/`RUNNER_*` vars and the workflow's own
|
|
160
|
+
`env:`; everything else is passed explicitly.
|
|
161
|
+
- **Secret masking everywhere.** Values from `--secret` or `::add-mask::` are
|
|
162
|
+
redacted in all output, and in container mode never appear on the client
|
|
163
|
+
command line (passed via a `0600` env file). Prefer `--secret NAME` so the
|
|
164
|
+
value stays out of your shell history too.
|
|
165
|
+
- **Tokens are handled carefully** — sent only to the GitHub host in
|
|
166
|
+
`GITHUB_SERVER_URL` / `GITHUB_API_URL` (github.com by default), never passed
|
|
167
|
+
to actions, and masked in logs.
|
|
168
|
+
|
|
169
|
+
### What the package accesses, and why
|
|
170
|
+
|
|
171
|
+
Installing and running `secureci` involves these capabilities. Each is needed for
|
|
172
|
+
the feature named, and none runs at install time.
|
|
173
|
+
|
|
174
|
+
| Capability | Where | Why |
|
|
175
|
+
| ------------------------ | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
176
|
+
| 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. |
|
|
177
|
+
| Network | `github.com`, `api.github.com` (or the GHES host you set) | Downloads actions and workflows, and resolves tags to commit SHAs. |
|
|
178
|
+
| Environment variables | `HOME`, `PATH`, `GITHUB_*`, `GITHUB_TOKEN`, `GH_TOKEN` | Builds the runner environment and authenticates GitHub downloads. |
|
|
179
|
+
| Filesystem | `~/.secureci/`, the working directory, temp dirs | Caches actions, stores artifacts and config, and reads your workflow files. |
|
|
180
|
+
| Hard-coded URLs | GitHub documentation and JSON Schema URLs in messages and editor hints | Informational only; the CLI does not fetch them. |
|
|
181
|
+
|
|
182
|
+
No install scripts run for consumers. The published tarball contains only
|
|
183
|
+
`dist/`, `README.md`, and `LICENSE`. See [SECURITY.md](SECURITY.md) for how to
|
|
184
|
+
report a vulnerability.
|
|
185
|
+
|
|
186
|
+
Full details: [DOCS.md → Security: what runs where](DOCS.md#security-what-runs-where)
|
|
187
|
+
and [Secret masking](DOCS.md#secret-masking).
|
|
188
|
+
|
|
189
|
+
## Development & testing
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
npm install # install dependencies
|
|
193
|
+
npm run build # compile TypeScript
|
|
194
|
+
npm test # run the Vitest suite
|
|
195
|
+
npm run test:watch # watch mode
|
|
196
|
+
npm run lint # ESLint
|
|
197
|
+
npm run format # Prettier
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
This project follows **TDD**: write the test first, implement to pass it, then
|
|
201
|
+
refactor while keeping tests green.
|
|
202
|
+
|
|
203
|
+
Every pull request and push to `main` runs
|
|
204
|
+
[`ci.yaml`](.github/workflows/ci.yaml): lint, `prettier --check`, tests with the
|
|
205
|
+
coverage thresholds in `vitest.config.mts`, build, and SecureCI
|
|
206
|
+
validating its own workflow.
|
|
207
|
+
|
|
208
|
+
Opt-in suites:
|
|
209
|
+
|
|
210
|
+
- `RUN_DOCKER_TESTS=1 npm test` — real-engine container tests (needs a running
|
|
211
|
+
Docker daemon).
|
|
212
|
+
- `RUN_NETWORK_TESTS=1 npm test` — tests that fetch real actions from GitHub.
|
|
213
|
+
|
|
214
|
+
Want to contribute? See **[CONTRIBUTING.md](CONTRIBUTING.md)**. Deep-dives for
|
|
215
|
+
humans and agents live in [AGENTS.md](AGENTS.md) and
|
|
216
|
+
[.github/agents/](.github/agents/).
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
The code is licensed under the [MIT License](LICENSE).
|
|
221
|
+
|
|
222
|
+
## Name and trademark
|
|
223
|
+
|
|
224
|
+
The **code** is open source under MIT; the **SecureCI name and logo** are not.
|
|
225
|
+
"SecureCI", the `secureci` command branding, and the `@secureci` npm scope are
|
|
226
|
+
trademarks of SecureCI. You may use the name to describe your use of this
|
|
227
|
+
software (for example, "works with SecureCI"), but you may not use it to name or
|
|
228
|
+
brand a fork, a derivative product or service, or a hosted offering, and you may
|
|
229
|
+
not imply endorsement by SecureCI. Forks must use a different name and must not
|
|
230
|
+
publish under the `@secureci` scope. These rights are reserved and are not granted by the
|
|
231
|
+
MIT License.
|