Commit graph

7 commits

Author SHA1 Message Date
Bryan Helmkamp
501ff3df40 Push metadata branch to origin after checkpoint in Remote (Daytona) mode
After each checkpoint commit, the metadata branch (checkpoint.json, manifest,
graph DOT, artifacts) is now pushed from the host process to the GitHub remote
using a GitHub App installation token. The local custom ref (refs/arc/{run_id})
is mapped to refs/heads/arc/meta/{run_id} on the remote since GitHub rejects
branch names starting with "refs/".

Changes:
- Move ssh_url_to_https to github_app.rs as pub fn for reuse
- Add push_ref() to git.rs for pushing a ref to an explicit URL
- Add github_app field to RunConfig to thread credentials into the engine
- Add git_push_meta_host() async wrapper in engine.rs
- Call git_push_meta_host after each remote checkpoint

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 13:08:49 -05:00
Bryan Helmkamp
b2f8a55b8f Fix push credentials for public repos in Daytona sandbox
resolve_clone_credentials was short-circuiting for public repos,
returning no token. This broke git push from the sandbox since push
requires authentication regardless of repo visibility. Always generate
an installation access token.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 03:20:53 -05:00
Bryan Helmkamp
4e0f990484 Push run branch to origin after each Daytona checkpoint
When a workflow runs on a Daytona sandbox, commits on the run branch
are lost when the sandbox is deleted. This pushes the run branch to
origin after each checkpoint so the full commit history is preserved.

- Upgrade GitHub App token permission from contents:read to contents:write
- Add refresh_push_credentials to Sandbox trait (default no-op)
- Store origin URL on DaytonaSandbox and configure push credentials after clone
- Implement refresh_push_credentials on DaytonaSandbox to rotate expiring tokens
- Add git_push_remote helper, called after each remote GitCheckpoint
- Add e2e test verifying the branch appears on GitHub after push

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-06 19:38:53 -05:00
Bryan Helmkamp
942f717eb4 Fix GitHub App repo visibility check: treat 401/403 as private
The is_repo_public function called GET /repos/{owner}/{repo} with
the App JWT, but GitHub returns 401 for App JWTs on the repos
endpoint (they need an installation token). Previously this 401
was treated as an auth error, failing sandbox init.

Now 401 and 403 are treated like 404: assume private and proceed
to create an installation access token, which has the right perms.

Also add preflight phase to the DOT test runner.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-06 15:44:00 -05:00
Bryan Helmkamp
cbc1444489 Add GitHub App IAT integration tests and improve is_repo_public error handling
Add three end-to-end tests for the GitHub App Installation Access Token clone
flow (private repo clone, public repo optimization, not-installed error). Also
return an error from is_repo_public on non-404 HTTP failures instead of
attempting to parse the response as JSON.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 06:46:52 -05:00
Bryan Helmkamp
72b6e86f3d Clean up GitHub App credentials: share reqwest client, accept raw PEM, avoid clone
- Share a single reqwest::Client across GitHub API calls in resolve_clone_credentials
  to reuse the TLS connection pool
- Accept raw PEM (not just base64-encoded) in build_github_app_credentials, matching
  the existing decode_pem_env/decode_pem_value convention
- Move github_app into DaytonaSandbox::new() instead of cloning

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-05 22:45:19 -05:00
Bryan Helmkamp
cf50625824 Switch Daytona git cloning from gh CLI to GitHub App Installation Access Tokens
Replace `gh auth token` with GitHub App IATs scoped to `contents: read` for
Daytona sandbox git cloning. Public repos are auto-detected and cloned without
credentials. Private repos get short-lived, repo-scoped tokens. Clear error
messages for each failure mode (app not installed, suspended, no repo access,
auth failure). Falls back gracefully when no GitHub App is configured.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-05 22:31:40 -05:00