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 de1d581
Browse filesBrowse the repository at this point in the historyBrowse files
feat(cli): add --workflow flag to configure the GitHub deploy-workflow path (#245)
## What
Adds a `--workflow <path>` flag to `void github connect` and `void
github update`, letting the project owner configure which workflow file
the platform authorizes to mint an OIDC deploy token. Defaults to the
scaffolded `.github/workflows/void-deploy.yml`.
```
void github connect my-app --repo owner/app --executor github_actions --workflow .github/workflows/ci.yml
void github update my-app --workflow .github/workflows/deploy.yml
```
## Why
The authorized deploy workflow was previously hardcoded server-side.
This lets owners point the OIDC trust at their own workflow file (it
must live under `.github/workflows/` and end in `.yml`/`.yaml`). The API
is authoritative for validation and storage; the CLI just forwards the
value.
## Details
- `github-args`: parse `--workflow` for both `connect` and `update`
(trimmed, value-required).
- `github-cmd`: thread `workflowPath` into connect; `update` treats it
as flag-only (no interactive prompt) and no-ops when unchanged.
- `client`: send `workflowPath` in the POST/PATCH bodies; add
`workflow_path` to the `GithubConnection` type.
- **Fail closed**: connect/update verify the server echoed the requested
`workflow_path` and exit non-zero otherwise, so a CLI pointed at an
older API (which silently drops the field) can't leave the user
believing a custom workflow is authorized.
- `help` + `docs/reference/cli.md`: document the flag and its security
semantics.
## Testing
`vp test run` — github CLI unit tests (parser + connect/update threading
+ fail-closed verification) all pass; typecheck/fmt/lint clean.
> Pairs with a platform-side PR that adds the server `workflow_path`
column, owner-gated routes, and the OIDC pin.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Changes which workflow may mint deploy tokens (security-sensitive OIDC
trust), though validation is server-side and the CLI fails closed when
the platform does not apply the path.
>
> **Overview**
> Adds **`--workflow <path>`** to `void github connect` and `void github
update` so project owners can configure which GitHub Actions workflow
file the platform trusts for OIDC deploy-token minting (default
`.github/workflows/void-deploy.yml`).
>
> The CLI parses the flag, sends optional **`workflowPath`** on
connect/update API calls, and extends **`GithubConnection`** with
**`workflow_path`**. On **`update`**, workflow changes are flag-only (no
TTY prompt), count toward the non-interactive “at least one flag” guard,
and patch only when the value differs. **Connect** and **update** **fail
closed** if the user passed **`--workflow`** but the response
**`workflow_path`** does not match—avoiding silent success against an
older API that ignores the field.
>
> Help text and **`docs/reference/cli.md`** document the flag and OIDC
trust semantics. Unit tests cover parsing, update threading, no-op
behavior, and old-platform verification.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
ef845e8. 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>
|`--project <name>`| Project name (alias for the positional argument) |
613
+
|`--installation <id>`| GitHub App installation ID (required when you have multiple installations) |
614
+
|`--repo <owner/repo>`| Repository full name — required unless the installation grants exactly one repo |
615
+
|`--branch <name>`| Branch to deploy from — **required in non-interactive mode**|
616
+
|`--executor <type>`| Build executor: `container` (default) or `github_actions`|
617
+
|`--workflow <path>`| Authorized deploy workflow file — defaults to `.github/workflows/void-deploy.yml`|
618
+
619
+
The `--workflow` path is the workflow file the GitHub OIDC exchange authorizes to mint this project's deploy token. It defaults to the scaffolded `.github/workflows/void-deploy.yml`; set it only if your deploy step lives in a different workflow file (it must be under `.github/workflows/` and end in `.yml`/`.yaml`). Because the exchange is secretless, **only this one workflow** can mint a deploy token — any other workflow in the repo (including an unsafe `pull_request_target`) is rejected. Pointing it at a broad, multi-purpose workflow widens that trust, so prefer a dedicated file.
Update an existing connection's deploy **branch**and/or **build executor**. Use this to change settings on a project that is already connected — for example, flipping the executor from `container` to `github_actions` for a monorepo whose Void app lives in a subdirectory, or moving the deploy branch. The project must already be connected (run `void github connect` first); the repository and installation are not changed.
640
+
Update an existing connection's deploy **branch**, **build executor**, and/or authorized **workflow file**. Use this to change settings on a project that is already connected — for example, flipping the executor from `container` to `github_actions` for a monorepo whose Void app lives in a subdirectory, moving the deploy branch, or pointing the OIDC trust at a different workflow file. The project must already be connected (run `void github connect` first); the repository and installation are not changed.
|`--project <name>`| Project name (alias for the positional argument) |
647
+
|`--branch <name>`| New branch to deploy from |
648
+
|`--executor <type>`| New build executor: `container` or `github_actions`|
649
+
|`--workflow <path>`| New authorized deploy workflow file (under `.github/workflows/`) |
646
650
647
-
Interactively (TTY), `void github update` shows the current branch and executor and prompts for new values, defaulting each to the current setting. When stdin is not a TTY, it never prompts: pass at least one of `--branch` / `--executor`, or it fails closed. If nothing actually changes, the command reports "no changes" and does not call the API.
651
+
Interactively (TTY), `void github update` shows the current branch and executor and prompts for new values, defaulting each to the current setting. `--workflow` is flag-only — it is never prompted for; pass it explicitly to change the authorized workflow file. When stdin is not a TTY, it never prompts: pass at least one of `--branch` / `--executor` / `--workflow`, or it fails closed. If nothing actually changes, the command reports "no changes" and does not call the API.
`connect: server did not apply --workflow ${args.workflowPath} (got ${connection.workflow_path??'none'}). The platform may be too old to support a custom workflow path.`,
491
+
);
492
+
process.exit(1);
493
+
}
494
+
482
495
log.success(`Connected ${repoFullName} (${branch}) → project. Push to ${branch} to deploy.`);
483
496
}
484
497
@@ -497,9 +510,14 @@ export async function runGithubUpdate(
497
510
// Guard BEFORE any project resolution or connection read so this usage error
498
511
// never depends on API state (e.g. a disconnected project must not surface the
499
512
// "connect first" 404 message in place of the missing-flags error).
`update: server did not apply --workflow ${patch.workflowPath} (got ${updated.workflow_path??'none'}). The platform may be too old to support a custom workflow path.`,
0 commit comments