@runveric/cli 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/README.md +185 -0
- package/dist/runveric.mjs +7999 -0
- package/dist/runveric.mjs.map +1 -0
- package/package.json +62 -0
package/README.md
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# runveric
|
|
2
|
+
|
|
3
|
+
**Author an Runveric action on your laptop — scaffold it, validate it, and run it for real in the
|
|
4
|
+
production runner image — without pushing anything or signing in.**
|
|
5
|
+
|
|
6
|
+
```sh
|
|
7
|
+
npx @runveric/cli@0.1.1 init --id yourteam/restart-web-tier
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## What this is
|
|
13
|
+
|
|
14
|
+
[Runveric](https://github.com/Mousling1992/opera-cloud) is a governed cloud-operations control
|
|
15
|
+
plane: it runs operational scripts against your cloud with approvals, least-privilege
|
|
16
|
+
short-lived credentials, an allowlisted network, and a full audit trail.
|
|
17
|
+
|
|
18
|
+
An **action** is the unit it runs — a script, plus a declaration of what that script is allowed
|
|
19
|
+
to do: which parameters it takes, which cloud permissions it needs, whether it can reach the
|
|
20
|
+
network, how risky it is, and whether it can be rolled back.
|
|
21
|
+
|
|
22
|
+
`runveric` is the local half of that. It scaffolds an action that already works, validates
|
|
23
|
+
it with **the same validator the server runs**, and executes a phase inside the same container
|
|
24
|
+
image production uses. Three of its four commands need no Runveric account and no network.
|
|
25
|
+
|
|
26
|
+
**Why it exists.** Before this, writing an action meant: create a Git repo, install a GitHub
|
|
27
|
+
App, hand-write a 25-field manifest and a parameter schema, push, import, and discover your
|
|
28
|
+
mistakes in production. The first real package took five review cycles — and the defect that
|
|
29
|
+
blocked it (a PowerShell variable followed by `?`, which reads as a variable named `Name?`,
|
|
30
|
+
expands to nothing, and silently drops the value) was found in two minutes by running the
|
|
31
|
+
script outside the platform. Nothing in the product offered that. This does.
|
|
32
|
+
|
|
33
|
+
## Requirements
|
|
34
|
+
|
|
35
|
+
- **Node.js 20 or newer** — for `init`, `check` and `publish`.
|
|
36
|
+
- **Docker** — for `test` only.
|
|
37
|
+
- An **Runveric account** — for `publish` only.
|
|
38
|
+
|
|
39
|
+
## Install
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
npx @runveric/cli@0.1.1 <command> # no install
|
|
43
|
+
npm install -g @runveric/cli # or install the `runveric` bin
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Pin the version your Runveric deployment shows you on its Author page rather than tracking
|
|
47
|
+
`@latest` — the CLI validates against a contract that ships with the control plane.
|
|
48
|
+
|
|
49
|
+
## The four verbs
|
|
50
|
+
|
|
51
|
+
| | | Needs |
|
|
52
|
+
| --- | --- | --- |
|
|
53
|
+
| `init [dir]` | Scaffold a **working** action. It passes `check` and `test` immediately. | — |
|
|
54
|
+
| `check` | Validate it. Offline — no network, no cloud, no account. | — |
|
|
55
|
+
| `test` | Run one phase in the real Runveric runner image. | Docker |
|
|
56
|
+
| `publish` | Upload it as an authored version. | An account |
|
|
57
|
+
|
|
58
|
+
`runveric --help` lists every flag.
|
|
59
|
+
|
|
60
|
+
## A worked example
|
|
61
|
+
|
|
62
|
+
Scaffold a PowerShell action, look at what you got, validate it, and run it locally:
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
$ npx @runveric/cli@0.1.1 init restart-web-tier \
|
|
66
|
+
--id acme/restart-web-tier \
|
|
67
|
+
--interpreter powershell \
|
|
68
|
+
--yes
|
|
69
|
+
|
|
70
|
+
restart-web-tier/
|
|
71
|
+
action.yaml the declaration: parameters, permissions, risk, rollback
|
|
72
|
+
run/main.ps1 what actually runs
|
|
73
|
+
README.md
|
|
74
|
+
|
|
75
|
+
$ cd restart-web-tier
|
|
76
|
+
$ runveric check
|
|
77
|
+
|
|
78
|
+
check /home/you/restart-web-tier
|
|
79
|
+
|
|
80
|
+
✓ No problems found.
|
|
81
|
+
|
|
82
|
+
$ export OPERA_RUNNER_IMAGE=<the image your Runveric runs> # the Author page shows it
|
|
83
|
+
$ runveric test --phase run --param resourceGroup=rg-prod --dry-run
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`test` writes `result.json` the way a real run does, and validates it with the control plane's
|
|
87
|
+
own validator — so a result Runveric would reject fails on your laptop first.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
### `init`
|
|
92
|
+
|
|
93
|
+
Asks for three things, because nothing else needs a decision: the id, a display name, and the
|
|
94
|
+
interpreter (`powershell` / `bash` / `python`). Everything else gets a safe default — risk level
|
|
95
|
+
`high`, no rollback, no network, no secrets — written into a complete `action.yaml` you can see
|
|
96
|
+
and edit. `validate/` and `rollback/` ship commented out, so enabling a phase is uncommenting
|
|
97
|
+
rather than authoring.
|
|
98
|
+
|
|
99
|
+
It never overwrites an existing file.
|
|
100
|
+
|
|
101
|
+
### `check`
|
|
102
|
+
|
|
103
|
+
Runs the **same validator the server runs** — literally the same function, shipped inside this
|
|
104
|
+
package. Import never rejects something `check` accepted; a test drives a shared fixture corpus
|
|
105
|
+
through both and fails if that stops being true.
|
|
106
|
+
|
|
107
|
+
On top of the validator it runs the authoring lint, which catches things a schema cannot
|
|
108
|
+
express:
|
|
109
|
+
|
|
110
|
+
- `$Name?` in PowerShell — reads as a variable called `Name?`, expands to nothing, and the
|
|
111
|
+
value silently disappears. The one that cost five review cycles.
|
|
112
|
+
- An entrypoint file that does not exist for the declared interpreter (`run/main.sh` with
|
|
113
|
+
`runtime.name: powershell`).
|
|
114
|
+
- A parameter that `dependsOn` one declared after it — the run form would ask for a VM before
|
|
115
|
+
the resource group that scopes the list.
|
|
116
|
+
- A permission for a provider the package does not declare, or one nothing in the code touches.
|
|
117
|
+
- Network declared with an empty allowlist.
|
|
118
|
+
|
|
119
|
+
Every finding names the file, the line, and the fix.
|
|
120
|
+
|
|
121
|
+
Add `--strict` to fail on warnings too, for CI.
|
|
122
|
+
|
|
123
|
+
**What `check` does NOT claim.** Three things depend on the deployment, not the package —
|
|
124
|
+
whether its runner ships your interpreter, whether it can broker outbound network, and whether
|
|
125
|
+
organization packages are enabled. Your laptop cannot know them, so `check` does not pretend to.
|
|
126
|
+
They are answered at import.
|
|
127
|
+
|
|
128
|
+
### `test`
|
|
129
|
+
|
|
130
|
+
Runs one phase in the **published runner image**, with the same `/opera/*` layout, the same
|
|
131
|
+
`OPERA_*` environment, and the same `result.json` validator the control plane uses.
|
|
132
|
+
|
|
133
|
+
```sh
|
|
134
|
+
export OPERA_RUNNER_IMAGE=<the image your Runveric runs> # the Author page shows it
|
|
135
|
+
runveric test --phase validate
|
|
136
|
+
runveric test --phase run --dry-run
|
|
137
|
+
runveric test --phase run --param resourceGroup=rg-prod
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Needs Docker. Uses your own `az login` credential (written to a file at
|
|
141
|
+
`/opera/creds/azure-token`, never an environment variable — the same way production does it).
|
|
142
|
+
|
|
143
|
+
Two things are deliberately different from production, and printed on every run so you never
|
|
144
|
+
have to guess:
|
|
145
|
+
|
|
146
|
+
- the credential is **yours**, not Runveric's brokered least-privilege lease, so a local pass does
|
|
147
|
+
not prove the connector has the permissions;
|
|
148
|
+
- egress is your machine's, not the allowlisting proxy, so a declared allowlist is **not**
|
|
149
|
+
enforced locally.
|
|
150
|
+
|
|
151
|
+
### `publish`
|
|
152
|
+
|
|
153
|
+
```sh
|
|
154
|
+
export OPERA_URL=https://your-opera.example.com
|
|
155
|
+
export OPERA_TOKEN=…
|
|
156
|
+
runveric publish
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Uploads the directory as an **authored** package version — organization tier, on the strength of
|
|
160
|
+
the authenticated principal rather than a Git source. It runs `check` first and refuses on any
|
|
161
|
+
error, including a lint error the server cannot reject.
|
|
162
|
+
|
|
163
|
+
Publishing does not adopt. Nobody can run it until somebody chooses to.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Supply chain
|
|
168
|
+
|
|
169
|
+
Every release is published from CI on a tag, with [npm
|
|
170
|
+
provenance](https://docs.npmjs.com/generating-provenance-statements) — a signed attestation
|
|
171
|
+
binding the tarball to the commit and the workflow that built it. You can verify what you
|
|
172
|
+
installed came from this repository:
|
|
173
|
+
|
|
174
|
+
```sh
|
|
175
|
+
npm audit signatures
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Links
|
|
179
|
+
|
|
180
|
+
- **Issues:** https://github.com/Mousling1992/opera-cloud/issues
|
|
181
|
+
- **Source:** https://github.com/Mousling1992/opera-cloud/tree/main/packages/action-cli
|
|
182
|
+
|
|
183
|
+
## License
|
|
184
|
+
|
|
185
|
+
Apache-2.0
|