You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 94b0d4e
Browse filesBrowse the repository at this point in the historyBrowse files
## Summary
Adds `void init --github`, the CLI side of **Deploy on GitHub**. It
scaffolds `.github/workflows/void-deploy.yml`, which:
- requests a GitHub OIDC token (audience `void`) — `permissions:
id-token: write`, no long-lived secret stored in the repo
- exchanges it at `POST $VOID_API_URL/auth/github-oidc` for a
short-lived, project-scoped Void deploy token
- runs `void deploy` on the GitHub-hosted runner
On a `git push`, GitHub Actions builds and deploys via OIDC. The
platform side (GitHub App, webhooks, OIDC exchange endpoint, builds +
container executor) lives in the companion `void-platform` PR.
## Changes
- `--github` flag on `void init` (workflow-only scaffold; safe to
re-run, skips if the workflow already exists)
- `void init --github` CLI help + examples entry
- scaffolded workflow uses `VOID_API_URL` repo var (defaults to
`https://api.void.cloud`) and per-`(repo, ref)` concurrency
- docs: `docs/guide/deployment.md` + `docs/reference/cli.md`
- `init.test.ts` coverage for the new flag + scaffold
## Test
- `init.test.ts`: 129 passed
- fmt / lint / typecheck: clean
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Changes deploy credential handling in child processes and CI auth
patterns; routing publish semantics affect whether users see success vs
degraded reachability without failing the command.
>
> **Overview**
> **GitHub Actions deploy** moves from a long-lived `VOID_TOKEN` secret
and `deploy.yml` to **`void init --github`** writing
**`.github/workflows/void-deploy.yml`**: `id-token: write`, repo/ref
**concurrency**, OIDC exchange at **`POST
$VOID_API_URL/auth/github-oidc`**, then **`void deploy --project`**. The
workflow bakes in the linked slug from **`.void/project.json`** when
present, otherwise **`vars.VOID_PROJECT`**; interactive init **patches
the placeholder** after project linking. Docs and CLI help describe OIDC
and staging via **`VOID_API_URL`**.
>
> **`void deploy`** adds **`buildEnv()`** so **`CF_ACCESS_CLIENT_ID` /
`CF_ACCESS_CLIENT_SECRET`** are removed from **child** env for **`vite
build`**, git metadata, and **drizzle-kit** (parent **`process.env`**
unchanged for interactive re-auth). Deploy **done** events may include
**`published: false`**; the CLI still treats the deploy as success but
shows **degraded spinner text**, logs **`deploy_degraded`**, and
**`warnUnpublishedRouting`** after the summary.
>
> Unit tests cover OIDC workflow scaffolding, slug patching,
**`buildEnv`**, unpublished routing, and **PlatformClient** Access
header capture.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
af19690. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/guide/deployment.md
+37-11Lines changed: 37 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -64,30 +64,56 @@ If your CI pipeline runs typechecking or other static analysis before deploy, ru
64
64
65
65
## GitHub Actions
66
66
67
-
You can deploy from a GitHub repo with a simple GitHub Actions workflow. Running `void init --github` will generate this as `.github/workflows/deploy.yml` in your project:
67
+
You can deploy from a GitHub repo on every push to `main`. Running `void init --github` generates `.github/workflows/void-deploy.yml` in your project.
68
+
69
+
The workflow authenticates with [GitHub OIDC](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect) — there is **no long-lived `VOID_TOKEN` secret to store or rotate**. The job requests a short-lived OIDC token from GitHub, exchanges it at `POST $VOID_API_URL/auth/github-oidc` for a project-scoped deploy token (valid ~15 minutes), then runs `void deploy --project <slug>`:
68
70
69
71
```yaml
70
-
name: Deploy
72
+
name: Deploy to Void
71
73
on:
72
74
push:
73
75
branches: [main]
74
76
77
+
# Latest push wins: a newer commit cancels an in-flight deploy for the same
78
+
# repo + branch, so an older commit can never overtake a newer one.
To get a deploy token, run `void auth token` to copy it to your clipboard, then add it as a GitHub Actions secret.
116
+
Connect the repository to your project once in the Void dashboard to authorize it. The exact steps vary by package manager (the scaffold detects pnpm, yarn, bun, or npm). The `VOID_PROJECT` value is baked in from your linked project when known; otherwise the workflow reads a `VOID_PROJECT` repository variable. To target staging, set a `VOID_API_URL` repository variable to `https://api.staging.void.cloud`.
Copy file name to clipboardExpand all lines: docs/reference/cli.md
+4-2Lines changed: 4 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -86,7 +86,7 @@ After that, the full interactive flow walks through:
86
86
4.**Skills:** links Void skills using the same detected or selected agent context.
87
87
5.**MCP config:** writes MCP server config using that same agent context.
88
88
6.**Demo code:** for existing non-Pages projects, optionally scaffolds a `db/migrations/` directory plus an API route and typed fetch example.
89
-
7.**GitHub Actions:** optionally creates `.github/workflows/deploy.yml`withthe right package manager commands.
89
+
7.**GitHub Actions:** optionally creates `.github/workflows/void-deploy.yml`. The workflow deploys on pushes to `main` and authenticates via [GitHub OIDC](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect) — no long-lived `VOID_TOKEN` secret is stored in the repo. The job requests an OIDC token (audience `void`), exchanges it at `POST $VOID_API_URL/auth/github-oidc` for a short-lived project-scoped deploy token, then runs `void deploy --project <slug>` with the right package manager. The project slug is baked in from your linked project (`.void/project.json`) when known; otherwise the workflow reads a `VOID_PROJECT` repository variable.
90
90
8.**`env.ts` scaffold:** if the project has no `env.ts` but has `.env` / `.env.example` / `.env.local` / `.env.development*` files on disk, generates an `env.ts` pre-populated with their keys. Values get conservative type inference (`boolean`/`url`/`number`/`string`) — the file carries a banner nudging you to tighten anything the heuristic got wrong.
91
91
9.**Project setup:** optionally logs you in, lets you select or create a project, and writes `.void/project.json` so your first deploy can just be `void deploy`.
92
92
@@ -98,10 +98,12 @@ Use flags to run individual steps without prompts:
|`--agents`| Set up agent instructions, skills, and MCP config |
101
-
|`--github`| Only create GitHub Actions workflow |
101
+
|`--github`| Only create the GitHub Actions deploy workflow|
102
102
103
103
Flags can be combined. When any flag is provided, only the specified steps run and interactive prompts are skipped.
104
104
105
+
The `--github` workflow uses GitHub OIDC: you connect the repository to your Void project once (in the dashboard), and pushes to `main` deploy automatically. There is no `VOID_TOKEN` secret to create or rotate. To target staging, set a `VOID_API_URL` repository variable to `https://api.staging.void.cloud`.
106
+
105
107
For projects that already have `"extends"`, `void init --tsconfig` preserves the existing config and adds `./.void/tsconfig.json`. If the existing config defines `files` or `compilerOptions.paths`, Void also merges its generated declaration files and aliases into the root config because TypeScript replaces those fields across `extends` instead of deeply merging them.
// Committed-live in the DB but routing KV was not published. The
701
+
// deploy succeeded (do NOT throw / return an error kind) but the
702
+
// project may be unreachable (first deploy) or still serving the
703
+
// previous deploy (later deploy). Degrade the message accordingly.
704
+
s.stop(
705
+
'Deployed, but routing was not published — the project may be unreachable or still serving the previous deploy. Re-run `void deploy` to publish routing.',
'Routing was not published for this deploy. The project may be unreachable (first deploy) or still serving the previous deploy. Re-run `void deploy` to publish routing.',
1099
+
);
1100
+
}
1101
+
1040
1102
/**
1041
1103
* Emit a single aggregated lint warning when a `_redirects` file contains
1042
1104
* one or more `!` force suffixes on 3xx entries (e.g. `301!`, `302!`).
@@ -1081,6 +1143,7 @@ async function runFrameworkDeploy(
0 commit comments