Commit Graph

60 Commits

Author SHA1 Message Date
github-actions[bot] 4ad216dc3f chore: version packages (#332)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-07 16:14:12 -07:00
github-actions[bot] be45efd105 chore: version packages (#324)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-29 15:52:43 +02:00
github-actions[bot] 754574f427 chore: version packages (#317)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-28 13:33:39 +02:00
github-actions[bot] f0b538361d chore: version packages (#311)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-22 16:31:56 +02:00
github-actions[bot] ba1c14ae7b chore: version packages (#301)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-20 11:03:42 +02:00
Peter Pistorius e2fe5761ba feat(compat): JSON source of truth + fill gaps + fix defaults.run.working-directory (#291)
* feat(compat): make compatibility.json the source of truth

Flip the compatibility matrix so packages/cli/compatibility.json is
authoritative. scripts/gen-compatibility-md.mjs renders the .md from it,
pnpm check runs a drift check, and the website imports the JSON directly
and renders inline markdown in keys/notes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test: add compat smoke coverage for secrets, working-dir defaults, runner image

Fill three audit gaps identified against packages/cli/compatibility.json:

- smoke-secrets-env-file: secrets resolved from .env.agent-ci and from
  the shell environment fallback
- smoke-defaults-workdir: workflow- and job-level
  defaults.run.working-directory plus a step-level override
- smoke-runner-image: .github/agent-ci.Dockerfile is picked up and the
  resulting image is used at job start

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(workflow): propagate defaults.run.working-directory to steps

Parse defaults.run.working-directory at workflow and job level and merge
it into each run-step's inputs with step > job > workflow precedence.
Step-level working-directory already worked; the defaults blocks were
silently ignored.

Closes #290.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(compat): add proof field to compatibility.json rows

Every `supported`/`partial` row now lists the smoke workflows that
exercise it end-to-end. `pnpm compat:gen`/`compat:check` fails if a
listed path does not resolve, catching renames.

Rows with an empty `proof: []` are the audit gaps tracked in #292.

Refs #292.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(dtu): attach step env per-step so it does not leak to siblings

Step-level env was being aggregated into the job-wide EnvironmentVariables
map (last-wins), so a later step's `env: FOO=x` would override an earlier
step's effective FOO at runtime. Emit step.Env as the mapped step's own
`environment` instead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(compat): fill audit gaps #292 — env, expressions, local action

Three smokes covering eight of the ten gaps listed in #292:
- smoke-env-scoping: workflow + job + step `env:` precedence
- smoke-expressions: hashFiles, format, join, runner.arch, type
  literals, startsWith/endsWith
- smoke-local-action: `steps[*].uses: ./.github/actions/...`
  (verified via marker file rather than steps.<id>.outputs.*)

Proof fields updated for every row these smokes cover. hashFiles
downgraded to ⚠️ partial — agent-ci emits SHA-1, GitHub Actions emits
SHA-256 (tracked by #294).

Two gaps remain open as filed issues:
- #293 defaults.run.shell / steps[*].shell not applied
- #295 ${{ steps.<id>.outputs.<name> }} leaks literal text in run
  scripts

Refs #292.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 08:47:20 +02:00
github-actions[bot] 5a9d2d1ea5 chore: version packages (#285)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-19 15:10:12 +02:00
github-actions[bot] 2e61c83619 chore: version packages (#281)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-18 20:38:25 +02:00
github-actions[bot] b24b6b45e3 chore: version packages (#278)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-18 14:09:04 +02:00
github-actions[bot] 6574e26013 chore: version packages (#276)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-18 13:27:15 +02:00
Peter Pistorius 12220befc4 Run macos-* jobs in real macOS VMs via tart (#275)
* feat(cli): run macos-* jobs in real macOS VMs via tart

When the host is darwin/arm64 with tart + sshpass installed, jobs
targeting runs-on: macos-* boot an ephemeral cirruslabs macOS VM,
rsync the macOS actions-runner binary in, and connect it to the
in-process DTU via the host bridge.

- New runner/macos-vm/ module (tart wrapper, image mapping, host
  capability probe, runner binary fetch/cache, semaphore, job driver).
- cli.ts routes macOS jobs to the VM executor when the host supports
  it; otherwise falls through to the existing skip-with-warning path.
- DTU generators.ts accepts runnerWorkDir/runnerOs/runnerArch so the
  seed payload reflects where the runner actually materializes _work
  (sibling of run.sh, not a caller-chosen path).
- runner-credentials.ts extracted from local-job.ts so the macOS path
  can reuse the same deterministic .runner/.credentials generation.

Concurrency capped at 2 VMs by default (AGENT_CI_MACOS_VM_CONCURRENCY).
Image override via AGENT_CI_MACOS_VM_IMAGE.

Closes #258.

* feat(cli): say *why* macOS jobs skip on incapable hosts

Before: the skip warning for macos-* jobs on a host that can't run the
VM just pointed at #258 and parroted the pre-Phase-3 line about only
running in a Linux container — which is no longer accurate now that
macOS jobs *can* run locally when the host supports it.

Now: formatUnsupportedOSWarning accepts the HostCapability result and
prints the specific reason + install hint when available — e.g.
'tart not installed' with a brew command, or 'requires Apple Silicon
(got x64)'.

* refactor(cli): deduplicate runs-on classification + warning body

- cli.ts: extract classifyJob(ej) + canRunMacosHere(kind) so the
  skip path and the executor-routing path share one source of truth
  for 'should this job run in the macOS VM?' — the two previously
  duplicated the parseJobRunsOn + classifyRunsOn + capability check.
- runs-on-compat.ts: flatten formatUnsupportedOSWarning to a single
  body array per kind, filter undefined, then uniformly indent —
  drops the optional-hint if-branch and the per-push indent literals.

Pure refactor; all 14 runs-on-compat tests still pass, warning output
is byte-identical across all 4 permutations (macOS with/without
capability, with/without hint, windows).

* docs: document macOS VM runner support

- README: add tart + sshpass to 'Optional' prerequisites and a new
  'macOS jobs' section (image table, env vars, caveats).
- compatibility.md: unstale the three entries that claimed Linux-only
  (jobs.<id>.runs-on, runner.os, runner.arch). runs-on now reads as a
  partial (⚠️) that explains linux/macos/windows separately.

Leaves apps/website/CompatibilityMatrix.tsx alone — it has the same
stale rows but is in an unrelated mid-merge state on this branch.

* chore: oxfmt packages/cli/README.md and compatibility.md
2026-04-18 12:32:35 +02:00
github-actions[bot] b20187ad60 chore: version packages (#272)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-18 08:33:35 +02:00
github-actions[bot] e19997e37a chore: version packages (#251)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-15 10:54:37 +02:00
Peter Pistorius e482875a95 fix: setup-node "Bad credentials" + stale-toolcache hint (#252)
* fix: setup-node "Bad credentials" + stale-toolcache hint (#171, #249)

Route setup-node's versions-manifest fetch through the DTU so it no
longer 401s against real api.github.com, and surface an actionable
hint when a stale /opt/hostedtoolcache bind mount blocks tar extract.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: unit + smoke coverage for setup-node manifest mock

Adds unit tests for rewriteSetupNodeTarball and for the cached tree/blob
route paths, plus a nested-agent-ci smoke workflow that fails if
setup-node logs "Bad credentials" (the symptom of the manifest mock
breaking and falling back to nodejs.org).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 10:46:11 +02:00
github-actions[bot] 95b748c344 chore: version packages (#246)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-13 21:57:16 +02:00
github-actions[bot] ccf77636f9 chore: version packages (#244)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-13 19:58:05 +02:00
Peter Pistorius 9f7bc6feeb fix: include default_branch in event.repository payload (#241) (#243)
Actions like dorny/paths-filter read github.event.repository.default_branch
to determine the base branch. The DTU was already passing this value in
Resources.Repositories but omitting it from the event context.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 18:10:18 +02:00
github-actions[bot] c61f27d773 chore: version packages (#239)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-13 13:22:55 +02:00
github-actions[bot] e8b638f620 chore: version packages (#237)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-13 12:50:14 +02:00
github-actions[bot] 6f1389732a chore: version packages (#235)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-13 11:10:17 +02:00
github-actions[bot] c82f51a3b8 chore: version packages (#223)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-12 15:44:12 +02:00
Peter Pistorius 71a3ebbfb5 fix: exclude test files from published dist (#222)
Test files (*.test.ts) were being compiled into dist/ and included in
the npm package. Add tsconfig exclude to keep them out of the build.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 15:43:01 +02:00
Peter Pistorius 9d1c0f4031 fix: format markdown files and auto-format after changeset version (#221)
The release workflow failed because changeset-generated CHANGELOGs weren't
formatted. Fix the existing files and run oxfmt after `changeset version`
so future Version Packages PRs include formatted markdown.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 15:35:23 +02:00
github-actions[bot] be2d64e734 chore: version packages (#205)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-12 12:32:26 +02:00
github-actions[bot] 33351243cd chore: version packages (#195)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-11 13:10:00 +02:00
github-actions[bot] e958072dfe chore: version packages (#188)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-10 14:21:21 +02:00
Peter Pistorius cd24a04107 fix: support actions/checkout@v6 by using real HEAD SHA (#189)
Checkout v6 added post-fetch validation that the checked-out ref matches
github.sha. The git shim was returning a fake placeholder SHA (aaaa...)
in dirty workspace mode while github.sha used the real HEAD SHA, causing
the validation to fail. Use realHeadSha consistently everywhere and
remove the now-unnecessary computeFakeSha helper.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 13:13:42 +02:00
github-actions[bot] 7731f9cbdc chore: version packages (#185)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-10 11:58:18 +02:00
github-actions[bot] b90191b477 chore: version packages (#181)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-10 10:53:40 +02:00
Peter Pistorius f660c11a4d feat: support composite action step outputs and changed-files actions (#174)
* feat: support composite action step outputs and push event context

Enable workflows that use composite actions with cross-step output
references (e.g. Khan/actions@get-changed-files + filter-files) by:

- Preserving steps.* expressions for runner-time evaluation instead
  of expanding them to empty string at parse time
- Using correct BasicExpression token type (type 3, not 6) matching
  the runner's wire format
- Adding ContextName to steps so the runner can resolve
  steps.<id>.outputs.<name> expressions
- Adding push event before/after SHAs and GITHUB_API_URL so
  changed-files actions can call the compare commits API
- Implementing compare commits and list-PRs-for-commit mock endpoints
  in the DTU server using git diff on the original repo

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: resolve symlinks in agent-ci-dev.sh so it works when invoked via symlink

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 23:02:21 +02:00
Peter Pistorius 6b7a95b180 feat: support local composite actions (#169)
* feat: support local composite actions (`uses: ./.github/actions/...`)

Set RepositoryType to "self" for local action references so the runner
resolves them from the workspace instead of trying to download a tarball.
Add defensive guard in actiondownloadinfo to skip local/empty actions.

Closes #162

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style: fix formatting in .docs/ files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 17:07:31 +02:00
github-actions[bot] 4de00d6948 chore: version packages (#122)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-07 15:43:50 +02:00
Peter Pistorius 73f6bf0685 fix: propagate job-level env into DTU Variables store (#104) (#131)
* fix: propagate job-level env into DTU Variables and add AGENT_CI_LOCAL to container env

Closes #104. Job-level `env` from the CLI payload was not propagated into
the DTU's Variables store or ContextData, so `AGENT_CI_LOCAL` was unavailable
to the runner's expression engine. Also adds `AGENT_CI_LOCAL=true` to the
Docker container env for shell access.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* ci: re-trigger agent-ci checks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 13:44:47 +02:00
Peter Pistorius 17ef34087e fix: pin runnerName before DTU seed to prevent cross-workflow job stealing (#103) (#127)
When running --all, jobs seeded without runnerName landed in the shared
generic pool where runners from other concurrent workflows could steal
them, causing single-job workflows to hang indefinitely.

- Pin job.runnerName = containerName before the /_dtu/seed call
- Move container and ephemeralDtu cleanup into finally block
- Add process.setMaxListeners(0) for parallel job EventEmitter warnings
- Add reproduction test for generic pool job stealing

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 11:16:49 +02:00
github-actions[bot] 70f548cdcc chore: version packages (#118)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-06 20:17:45 +02:00
Peter Pistorius c2fe31b888 feat: action tarball disk cache, step output capture, and demo recording (#117)
* feat: action tarball disk cache, step output capture, and demo recording

- Cache action tarballs on first download and serve from disk on re-runs,
  eliminating ~30s GitHub CDN delays
- Capture step output via tee to signals dir for reliable pause-on-failure
  tail display
- Fix CLI to treat empty results as failure and skip summary print
- Add marketing demo recording setup with VHS tape and test project
- Add `agent-ci` script alias in root package.json

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add tests for action tarball cache, group filtering, and empty-results fix (#119)

Cover the untested changes from the tarball cache PR: action tarball proxy
cache hit/miss, download info URL rewriting with sub-path stripping, step
output group filtering, tee output capture, and CLI empty-results exit logic.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix: prevent concurrent tarball cache-miss race condition

Use an in-flight download map so concurrent requests for the same
tarball coalesce into a single GitHub fetch instead of racing on
the same tmp file, which could cause corruption or rename errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: use relative path in demo.tape for portability

Replace hard-coded absolute path with a relative path so the demo
recording works on any contributor's machine.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: correct sanitized-refs test to assert 404 for slash-containing refs

The test was passing vacuously (status >= 200 matches 404). Now it
properly asserts that Polka does not bind :ref across slashes, so
slash-containing refs return 404 and do not serve cached content.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 20:16:18 +02:00
Jökull Sólberg 3bb8525421 fix: support large monorepos and sub-path actions
Three fixes discovered while running agent-ci against a ~40K file
pnpm/turbo monorepo:

1. Sub-path actions (e.g. `actions/cache/save@v5`) produce invalid
   tarball URLs. The DTU was using `action.nameWithOwner` directly
   which includes the sub-path, producing
   `api.github.com/repos/actions/cache/save/tarball/v5` (404).
   Fix: strip to `owner/repo` before constructing the URL.

2. `copyWorkspace` uses `execSync("git ls-files ...")` with the
   default 1MB maxBuffer. Repos with 30K+ tracked files overflow
   this, causing ENOBUFS and an empty workspace in the container.
   Fix: increase maxBuffer to 100MB.

3. Post-success cleanup `fs.rmSync(containerWorkDir)` can throw
   ENOTEMPTY when the container hasn't fully released file handles.
   Fix: wrap in try/catch for best-effort cleanup.
2026-03-27 22:58:00 +00:00
github-actions[bot] 987477bae4 chore: version packages 2026-03-27 20:32:23 +00:00
Peter Pistorius 97227c4251 Merge pull request #77 from simoncrypta/fix/docker-host-ip
fix: make Docker host resolution universal
2026-03-26 02:41:29 +13:00
Simon Gagnon a9878186a0 fix: make Docker host resolution universal 2026-03-24 19:31:00 -04:00
Simon Gagnon c7c35248ec fix: use platform-specific Docker host IP for Linux compatibility
On Linux, host.docker.internal doesn't work by default (only available
since Docker 20.10+ and requires explicit configuration). This change:

- Detects macOS vs Linux and returns appropriate host IP
- Uses 172.17.0.1 (docker bridge gateway) on Linux host
- Uses host.docker.internal on macOS
- Adds containerUrl to ephemeral DTU for container-to-host communication
- Adds ExtraHosts mapping for containers to resolve host.docker.internal

Fixes connectivity issues when running agent-ci on Linux hosts.
2026-03-24 19:31:00 -04:00
github-actions[bot] c9d76f8d2d chore: version packages 2026-03-23 18:35:52 +00:00
Peter Pistorius 179405b960 feat: add package metadata, SKILL.md, and AI agent discoverability
Improve npm and AI agent discoverability by filling in package.json
keywords/description, creating a SKILL.md for node_modules scanning,
and adding a ready-to-paste CLAUDE.md snippet to the README.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 07:07:09 +13:00
github-actions[bot] 66dfd109e1 chore: version packages 2026-03-23 09:40:16 +00:00
github-actions[bot] e5bb9804ce chore: version packages 2026-03-22 21:46:27 +00:00
Peter Pistorius 17d8a34e37 chore: version packages 0.3.3 2026-03-18 08:22:48 +13:00
Peter Pistorius 6233723198 fix(dtu): replace execa with node:child_process
execa was in devDependencies but imported in production code,
causing ERR_MODULE_NOT_FOUND when running via npx. Replaced with
Node's built-in child_process.exec and removed execa entirely.
2026-03-18 08:14:43 +13:00
Peter Pistorius 7357393c0e fix: add shebang to CLI entry point for npx compatibility
The dist/cli.js was missing #!/usr/bin/env node, causing npx to execute it as a shell script. Version 0.3.2
2026-03-18 07:04:34 +13:00
github-actions[bot] 2e9e8bb6f9 chore: version packages 2026-03-17 08:41:15 +00:00
Peter Pistorius e8e2e823ea chore: update README, add engines field, scope release workflow paths 2026-03-16 21:26:58 +13:00