Skip to content

ci: run core CI on the self-hosted runner (unblock from GitHub Actions billing) - #73

Merged
fabianocruz merged 1 commit into
mainfrom
chore/core-ci-self-hosted
Jun 5, 2026
Merged

ci: run core CI on the self-hosted runner (unblock from GitHub Actions billing)#73
fabianocruz merged 1 commit into
mainfrom
chore/core-ci-self-hosted

Conversation

@fabianocruz

Copy link
Copy Markdown
Member

Run core CI on the self-hosted runner

GitHub-hosted (ubuntu-latest) workflow runs no longer trigger on this repo while the org's Actions billing is blocked — core PRs get no CI at all (this is why #72 had to be validated locally and merged on MERGEABLE/UNSTABLE). codespar-enterprise is unaffected because it already runs on the org self-hosted runner.

This points all 4 jobs (ci, validate-example-skeleton, validate-example-nfse-from-natural-language, validate-example-whatsapp-installment-negotiation) at runs-on: [self-hosted, Linux, X64] — the same label enterprise uses. CI then runs free and records real PR checks again.

⚠️ Operator (org admin) — one-time, required before this works

  1. Runner group access: allow codespar-core in the self-hosted runner group's repository access (the runner is registered at the org level; core currently has 0 runners of its own).
  2. Secret: set ANTHROPIC_API_KEY in codespar-core repo secrets — the three validate-example jobs call it via npm run validate.

Note

This is a workflow-file change, so it can't be CI-validated here (CI is exactly what's blocked). It takes effect on the next PR after merge. The current main was validated locally and is green: turbo run build typecheck test → build 18/18, typecheck clean, test 35/35 (after the one-time macOS npm i @rollup/rollup-darwin-arm64 --no-save for the npm optional-deps bug).

Alternative if you'd rather not touch the runner

Fix the GitHub Actions billing and revert this — ubuntu-latest resumes on its own.

🤖 Generated with Claude Code

…ked)

GitHub-hosted (ubuntu-latest) runs no longer trigger on this repo while
Actions billing is blocked, so core PRs get no CI at all (enterprise is
unaffected — it already runs on self-hosted). Point all 4 jobs at the
org self-hosted runner ([self-hosted, Linux, X64]), the same one
codespar-enterprise uses, so CI runs free and records real PR checks.

Requires (org admin, one-time): allow codespar-core in the runner
group's repository access, and set ANTHROPIC_API_KEY in the repo secrets
for the three validate-example jobs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@fabianocruz
fabianocruz merged commit f3f6da7 into main Jun 5, 2026
0 of 4 checks passed
fabianocruz added a commit that referenced this pull request Jun 6, 2026
…n, timeouts, ledger/issue, tests) (#74)

## Close the `@codespar/cli` audit

Fixes every finding from the CLI audit, with tests.

### 🔴 Security
- **`login` echoed the API key in cleartext.** The interactive prompt
printed the key to the terminal (scrollback + screen-share leak). Now
masked — readline's echo is suppressed on a TTY; piped keys read
plainly.

### 🟠 Correctness / reliability
- **Project scoping was entirely non-functional.** `config.project` /
`CODESPAR_PROJECT` was loaded but never used — the raw `ApiClient` never
sent `x-codespar-project`, and SDK commands constructed `new
CodeSpar({apiKey, baseUrl})` with no `projectId`. Multi-project orgs
silently hit the org default. Wired through a single `resolveAuth()`:
ApiClient sends the header, all 7 SDK commands pass `projectId`, the
`logs` SSE carries the header, and a top-level `--project` flag is
added.
- **`ApiClient` had no request timeout** — a hung server hung the CLI
forever. Added a 30s `AbortController` timeout → clear `CliError`.
- **Missing `ledger` + `issue` commands** for the SDK 0.10 meta-tools
(shipped this week). Added, mirroring `charge`/`ship`, with arg
validation and a shared `meta-input` helper.

### 🟡 Hygiene / UX
- **Stale User-Agent** (`codespar-cli/0.1.0` vs package 0.4.0) + VERSION
duplicated in two spots → single `version.ts` source.
- **Non-`--json` double-print** —
`charge`/`ship`/`payment-status`/`verification-status` printed a human
summary to stderr **and** dumped the full JSON to stdout, making
`--json` redundant. Dropped the redundant dump (`execute`/`tools` keep
theirs — that's their actual result / schema output, not a duplicate).

### ✅ Tests (was: none)
19 unit tests: `ApiClient` (project header present/absent, timeout,
error detail, 204) via a mocked `fetch`; `ledger`/`issue` arg
validation; `meta-input` parsing. Added a `test` script; tests excluded
from the published `dist`.

### Verification
Core CI runs on GitHub-hosted runners, currently **billing-blocked**
(see #73 — pending the self-hosted runner-group grant), so it won't
auto-run here. Verified locally with the exact CI gate: `turbo run build
typecheck test` → **54/54 tasks green**, CLI tests **19/19**.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fabianocruz added a commit that referenced this pull request Jun 6, 2026
…EADME (#75)

Round 2 of the `@codespar/cli` audit — closes the gaps the first pass
left.

## 🔴 Security — `connect` browser-open shell injection
`openInBrowser` ran `exec(\`open ${JSON.stringify(url)}\`)`.
Double-quoting via `JSON.stringify` does **not** neutralise `$(...)` or
backticks (both stay live inside shell double-quotes), so a
malicious/compromised **Connect Link URL** (server-controlled) could run
an arbitrary command on the user's machine. Fixed: **`execFile` (no
shell, URL passed as a literal argv)** + reject non-http(s) schemes via
`assertHttpUrl` (exported + unit-tested).

## Cleanups
- **charge + ship** migrated onto the shared `meta-input` helper — drops
the duplicated resolve/parse pair.
- **README** — added the meta-tool commands
(charge/ship/**ledger**/**issue**/discover/wizard/payment-status/verification-status
— several were already missing from the table) + the `--project` flag
and `CODESPAR_PROJECT`.
- **init** audited: already safe (name regex blocks `../` traversal;
refuses a non-empty existing dir) — no change.

## Gate
Core CI is billing-blocked (#73 pending). Verified locally: `turbo run
build typecheck test` → **54/54**, CLI tests **23/23** (added a connect
URL-guard test).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant