@cloud-cli/on 1.9.1 → 1.11.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 CHANGED
@@ -15,7 +15,9 @@ Designed with a strict **security-first boundary**, native **JavaScript AST eval
15
15
  - **Deterministic Field Evaluation:** No silent fallbacks or ambiguous type conversions. Plain strings remain literal strings; conditions in `if:` fields run as strict JS boolean expressions.
16
16
  - **Built-in Dark Mode Web UI (`/runs`):** Monitor job statuses live, inspect workspace inputs, and view ANSI-colored terminal log streams rendered in real-time.
17
17
  - **System & Container Execution Drivers:** Run steps directly as detached host process groups or inside isolated Docker/Systemd transient units.
18
- - **Automatic Secret Redaction:** Secrets loaded from `.env` are automatically masked (`***`) across all terminal log outputs and report snapshots.
18
+ - **DB-authored workflows:** Draft, validate, and publish portable YAML workflows through the authenticated API.
19
+ - **Scheduled execution:** Published workflows can run from cron expressions or local sunrise/sunset events.
20
+ - **Encrypted secret storage:** Secret ciphertext is stored in the database; the master key remains on the HTTP server.
19
21
 
20
22
  ---
21
23
 
@@ -23,10 +25,6 @@ Designed with a strict **security-first boundary**, native **JavaScript AST eval
23
25
 
24
26
  ```text
25
27
  my-project/
26
- ├── on/ # Workflow definitions directory
27
- │ ├── release.yml
28
- │ └── test.yml
29
- ├── .env # Local secrets (git-ignored)
30
28
  ├── runner.config.mjs # (Optional) Engine configuration
31
29
  └── package.json
32
30
 
@@ -41,24 +39,14 @@ my-project/
41
39
  Run the engine directly via `npx` or `pnpm dlx`:
42
40
 
43
41
  ```bash
44
- # Start full engine (Ingress HTTP Gateway + 5 Worker Loops)
45
- npx @cloud-cli/on start
42
+ # Start each role (normally managed by the supplied systemd units)
43
+ npx @cloud-cli/on start-server
44
+ npx @cloud-cli/on start-scheduler
45
+ npx @cloud-cli/on start-workers
46
46
 
47
47
  ```
48
48
 
49
- ### 2. Configure Secrets (`.env`)
50
-
51
- Secrets are automatically loaded from `.env` at the root of your project. Prefix secrets with `SECRET_`:
52
-
53
- ```env
54
- SECRET_NPM_TOKEN="npm_1234567890abcdef"
55
- SECRET_GITHUB_TOKEN="ghp_1234567890abcdef"
56
- SECRET_GITHUB_WEBHOOK_SECRET="my-webhook-secret"
57
- ```
58
-
59
- `SECRET_GITHUB_WEBHOOK_SECRET` is required to validate incoming webhooks from GitHub
60
-
61
- ### 3. Define a Workflow (`on/release.yml`)
49
+ ### 2. Define a Workflow
62
50
 
63
51
  ```yaml
64
52
  name: Build and Publish Release
@@ -110,6 +98,32 @@ steps:
110
98
  npx --yes semantic-release@24 -b main --no-ci
111
99
  ```
112
100
 
101
+ Store the YAML as a draft and publish it through the authenticated API. Only published revisions can receive webhooks or scheduled runs:
102
+
103
+ ```bash
104
+ curl -u admin:"$RUNNER_ADMIN_SECRET" -X POST http://localhost:11235/api/workflows/validate \
105
+ -H 'Content-Type: application/json' --data '{"sourceYaml":"..."}'
106
+ curl -u admin:"$RUNNER_ADMIN_SECRET" -X PUT http://localhost:11235/api/workflows/build-and-publish-release \
107
+ -H 'Content-Type: application/json' --data '{"sourceYaml":"..."}'
108
+ curl -u admin:"$RUNNER_ADMIN_SECRET" -X POST http://localhost:11235/api/workflows/build-and-publish-release/publish
109
+ ```
110
+
111
+ Time triggers are defined beside a webhook trigger:
112
+
113
+ ```yaml
114
+ on:
115
+ schedule:
116
+ - id: nightly
117
+ cron: "0 2 * * *"
118
+ timezone: Europe/Berlin
119
+ solar:
120
+ - id: morning
121
+ event: sunrise
122
+ latitude: 52.52
123
+ longitude: 13.405
124
+ offset: +15m
125
+ ```
126
+
113
127
  GitHub triggers support these preprocessor filters:
114
128
 
115
129
  | Field | Match behavior |
@@ -150,8 +164,8 @@ npx @cloud-cli/on [command] [options]
150
164
  | Command | Description |
151
165
  | ------------------- | ---------------------------------------------------------------------------------------- |
152
166
  | **`start-server`** | Runs Webhook Ingress Gateway (the HTTP server receiving webhooks). |
167
+ | **`start-scheduler`** | Dispatches published cron and solar workflow triggers. |
153
168
  | **`start-workers`** | Runs the event-driven worker scheduler (Scalable Workers). |
154
- | **`validate`** | Parses and validates all YAML workflows in your workflows folder without executing jobs. |
155
169
 
156
170
  ### CLI and Environment Options
157
171
 
@@ -160,17 +174,19 @@ npx @cloud-cli/on [command] [options]
160
174
  | `-h` | `--help` | — | - | Prints CLI help message and exits. |
161
175
  | `-c` | `--config` | `./runner.config.mjs` | `RUNNER_CONFIG_FILE` | Path to JavaScript configuration file. |
162
176
  | `-d` | `--database` | - | `RUNNER_DATABASE_URL` | SQLite database file path or HTTP URL. |
163
- | `-w` | `--workflows` | `on/` | `RUNNER_WORKFLOWS` | Directory where workflow YAML files live. |
164
177
  | `-p` | `--port` | `11235` | `PORT` | Port for the Ingress HTTP server. |
165
178
  | `-k` | `--workers` | `5` | `RUNNER_WORKERS` | Maximum concurrent jobs on this node. |
166
179
  | | | | `RUNNER_ADMIN_SECRET` | Admin token to refresh secrets via API |
180
+ | | | | `RUNNER_WORKER_SECRET` | Worker token for job events and secret retrieval |
167
181
  | | | | `RUNNER_SERVER_URL` | Webhook server URL used by workers. |
168
182
  | | | | `RUNNER_TAGS` | Comma-separated worker capability tags. |
169
183
 
170
- Set the same non-empty `RUNNER_ADMIN_SECRET` on the server and workers to publish live job-status refresh events. Job availability and the 60-second recovery refresh continue to work without it.
184
+ Set `RUNNER_ADMIN_SECRET` only on the HTTP server for dashboard and management APIs. Set the same non-empty `RUNNER_WORKER_SECRET` on the server and every worker to publish job-status refresh events and retrieve job-scoped secrets. The dashboard workflow APIs accept either Bearer authentication or HTTP Basic authentication with username `admin` and the admin secret.
171
185
 
172
186
  ### Secrets
173
187
 
188
+ Secrets are written through `PUT /api/secrets/:NAME` and are AES-256-GCM encrypted in the database. Set `RUNNER_MASTER_KEY` only on the HTTP server, or provide an `on-master-key` systemd credential. Workers receive decrypted values only after claiming a running job; values are not written to job payloads or reports.
189
+
174
190
  ---
175
191
 
176
192
  ## ⚙️ Configuration Reference
@@ -186,7 +202,6 @@ export default {
186
202
  workers: 5,
187
203
  serverUrl: 'https://runner.example.com/',
188
204
  tags: ['linux', 'docker'],
189
- workflows: '/home/workflows/',
190
205
  storagePath: '/tmp/workspaces',
191
206
  database: 'https://remote.db.com/',
192
207
 
@@ -244,7 +259,7 @@ Within `${...}`, `if:`, and `eval:` contexts, the following object scopes are ex
244
259
 
245
260
  - **`inputs`**: Payload key-values received from incoming webhooks.
246
261
  - **`env`**: Merged environment variables from global config and workflow definitions.
247
- - **`secrets`**: Unmasked secret values loaded from `.env` or environment variables (`SECRET_` prefix stripped).
262
+ - **`secrets`**: Unmasked job-scoped values from encrypted central secret storage.
248
263
  - **`steps`**: Execution statuses and outputs from previous steps in the workflow (`steps.<id>.status`, `steps.<id>.outputs`).
249
264
  - **`BUILTIN_HELPERS`**: JS utilities including `String`, `Number`, `Boolean`, and `JSON.parse` / `JSON.stringify`.
250
265
 
@@ -279,8 +294,20 @@ The Ingress Gateway listens for incoming HTTP requests and serves the live web U
279
294
  AST evaluation explicitly blocks access to dangerous JS properties (`constructor`, `__proto__`, `prototype`).
280
295
  3. **Payload Size Guard:**
281
296
  The Ingress server enforces a strict 5MB payload limit to prevent Out-Of-Memory (OOM) denial-of-service attacks.
282
- 4. **Signal Traps & Resource Cleanup:**
283
- Graceful process traps (`SIGINT`, `SIGTERM`) ensure active job handles are safely terminated, file descriptors are closed, and temp `.env`/`.out` files are removed via `try ... finally` blocks.
297
+ 4. **Single-operator API authentication:**
298
+ Workflow validation, publishing, secret management, and job details require `RUNNER_ADMIN_SECRET` over HTTPS.
299
+
300
+ ## systemd Deployment
301
+
302
+ Install the unit files from `systemd/` and create root-owned environment files in `/etc/on/`: `server.env` for `RUNNER_DATABASE_URL`, `RUNNER_SERVER_URL`, `RUNNER_ADMIN_SECRET`, and `RUNNER_WORKER_SECRET`; `scheduler.env` for `RUNNER_DATABASE_URL`; and `worker.env` for `RUNNER_DATABASE_URL`, `RUNNER_SERVER_URL`, `RUNNER_WORKER_SECRET`, `RUNNER_TAGS`, and `RUNNER_TMP`. Workers receive only `RUNNER_WORKER_SECRET`; the admin secret stays on the HTTP server. The supplied units run as root because the systemd execution driver creates transient system services. Use `systemctl edit` for per-machine overrides.
303
+
304
+ Place the server master key in `/etc/on/credentials/on-master-key` with permissions readable only by the `on` user. `runner-server.service` exposes it privately through systemd's credentials directory. Start the primary control plane with `systemctl enable --now runner.target`; enable `runner-worker.service` separately on worker machines. Use `systemctl edit runner-worker.service` for machine-specific labels and paths.
305
+
306
+ Workers now resolve the immutable revision when they claim a job. A workflow can safely use a checkout step followed by `if: files.exists('Dockerfile')`; `files` is constrained to the job's `workingDir`, so it cannot inspect files outside that workspace.
307
+
308
+ ## Future Security Work
309
+
310
+ This MVP intentionally supports one trusted operator. Before sharing the UI or exposing it beyond a private deployment, add individual accounts and roles, secure browser sessions and CSRF protection, audit logs, worker enrollment credentials, secret key rotation, encrypted systemd credentials, rate limiting, and database high availability.
284
311
 
285
312
  ## Development
286
313
 
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG5D,wBAAsB,UAAU,CAAC,MAAM,KAAA,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAyBrE;AAED,wBAAgB,aAAa,CAAC,cAAc,EAAE,gBAAgB,EAAE,aAAa,EAAE,gBAAgB,GAAG,YAAY,CAgB7G;AAED,wBAAgB,SAAS,SAwBxB;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC;IAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAwB9F"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG5D,wBAAsB,UAAU,CAAC,MAAM,KAAA,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAmBrE;AAED,wBAAgB,aAAa,CAAC,cAAc,EAAE,gBAAgB,EAAE,aAAa,EAAE,gBAAgB,GAAG,YAAY,CAgB7G;AAED,wBAAgB,SAAS,SAsBxB;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC;IAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAuB9F"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAYA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAUA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC"}