Skip to content

feat(stack-cli): add --source flags to config push#1450

Open
BilalG1 wants to merge 27 commits into
devfrom
feat/config-push-source-flags
Open

feat(stack-cli): add --source flags to config push#1450
BilalG1 wants to merge 27 commits into
devfrom
feat/config-push-source-flags

Conversation

@BilalG1
Copy link
Copy Markdown
Collaborator

@BilalG1 BilalG1 commented May 20, 2026

Summary

  • Adds --source github with --source-repo, --source-path, --source-workflow-path flags to stack config push. When --source github is set, all four are required together. commit_hash / branch still come from GITHUB_SHA / GITHUB_REF_NAME.
  • Adds workflow_path to the pushed-from-github source schema (optional for backward compat — existing rows still validate).
  • Dashboard's generated workflow YAML now emits the new flags and uses ${{ github.repository }} at runtime, so the stored source reflects repo renames/transfers.
  • Project-settings UI surfaces the workflow file as a clickable GitHub link when workflow_path is set.

Files

  • packages/stack-cli/src/commands/config-file.ts — new CLI flags + validation + parseOwnerRepo (regex [A-Za-z0-9._-]+)
  • packages/stack-shared/src/schema-fields.tsworkflow_path: yupString().optional()
  • packages/template/src/lib/stack-app/projects/index.tsworkflowPath?: string on PushedConfigSource
  • packages/template/src/lib/stack-app/apps/implementations/admin-app-impl.ts — camel/snake converters round-trip the new field
  • apps/dashboard/.../link-existing-onboarding-workflow.ts — generated YAML emits new flags via ${{ github.repository }}
  • apps/dashboard/.../project-settings/page-client.tsx — "Workflow file" row with GitHub link (handles branches with /)
  • apps/e2e/tests/backend/backend-helpers.ts — type kept in sync
  • apps/backend/src/lib/seed-dummy-data.ts — seeded github source includes workflow_path

Test plan

  • pnpm lint (29/29)
  • pnpm typecheck (29/29)
  • pnpm test run on packages/stack-cli/src/commands/config-file.test.ts (20/20)
  • pnpm vitest run on link-existing-onboarding-workflow.test.ts (3/3)
  • Live round-trip against local backend: pushed with --source github, verified workflow_path round-trips through DB and GET /api/v1/internal/config/source; tightened parseOwnerRepo rejects whitespace / $ / multi-slash; happy path accepts owner.io/my_repo-2 with feature/x branch
  • Visually inspected emitted YAML — STACK_AUTH_SOURCE_REPO: ${{ github.repository }} correctly emitted as a runtime expression

BilalG1 added 22 commits May 19, 2026 10:41
- Generated workflow now passes the required --cloud-project-id flag
  (sourced from the STACK_PROJECT_ID secret), which was previously
  missing and never read — every workflow run failed.
- workflow_dispatch is now best-effort: it 404s when the workflow is
  not on the default branch, but the workflow-file commit already
  triggers a run via the push paths filter, so the flow continues.
- Config paths are normalized (leading ./ stripped) so the workflow's
  push paths filter actually matches ongoing config edits.
- The github-repository step now shows a Connect button when no GitHub
  account is connected, instead of a dead-end alert.
- "Connect new" uses linkConnectedAccount so it can actually add an
  account, rather than getOrLinkConnectedAccount which just returns
  the existing one.
- Repositories load via an effect when the step has a selected account,
  fixing the empty repo list after a connect redirect or page reload.
- Local CLI command shown to users uses --cloud-project-id, matching
  the actual CLI flag.
The generated GitHub Actions workflow ran the CLI via `pnpx`, but the
ubuntu-latest runner has Node/npx but no pnpm, so the step failed with
`pnpx: command not found` (exit 127).

- Run the CLI with `npx --yes` and add an actions/setup-node step to
  pin Node on the runner.
- Update the local CLI command shown to users to `npx` as well, since
  `pnpx` is not universally available.
- Add an npx/pnpx/bunx package-runner toggle (npx default) so users
  can pick the runner that matches their setup.
- Split the single command block into separate "Sign in" and
  "Push config" snippets so users who already ran login can copy just
  the push command.
- Move --config-file to the end of the push command so the whole
  command up to the placeholder is easy to copy.
- Reuse the shared CodeBlock component (built-in copy button) instead
  of a bare <pre> for consistency.
Remove the "skip this if already signed in" and "this pushes the
config for project ..." helper lines for a cleaner page.
`config push` and `config pull` no longer require --cloud-project-id;
when omitted, the project id is read from the STACK_PROJECT_ID
environment variable via a new resolveProjectId helper. Empty option
strings are treated as absent.

The generated GitHub Actions workflow already exports STACK_PROJECT_ID
as a step env var, so the explicit --cloud-project-id flag is dropped
from the run command.
…opdown

The connected-account selector on the 'Choose repository and branch'
step rendered with the numeric providerAccountId until the GitHub
/user fetch populated githubAccountLogins. Replace the dropdown with
a small Spinner + 'Loading GitHub account...' row while the selected
account's login is unknown, then show the dropdown once available.
- New RemoteSearchCombobox (Popover + cmdk pattern already used in
  dashboard data-tables) drives both selectors.
- Repository selector: type-ahead with debounced /search/repositories
  fetch so users with more than 100 repos can find any of them, not
  just the first /user/repos page.
- Branch selector: type-ahead with debounced /git/matching-refs/heads
  prefix search (the branches endpoint itself has no query support).
- Drop the Branch "Refresh" button — branches already auto-load on
  repository select, and the combobox can refresh by reopening.
…us update

The startStatusTransition wrap around a single Map insert into
projectStatuses wasn't deferring anything meaningful, and the
[, startStatusTransition] destructure with an unused first slot was
noise. Inline the setState call and drop the useTransition import.
- RemoteSearchCombobox derives the trigger label internally from
  items + value (falling back to the value string) instead of taking
  a selectedLabel prop, so call sites don't have to thread it.
- loadRepositories now uses a runId guard (matching the existing
  pollingRunIdRef / localMonitoringRunIdRef pattern) so a stale call
  can't clobber state set by a newer one. The repo auto-load effect's
  catch only resets the loaded-account ref when it still matches the
  failed account, for the same reason.
- Drop a defensive try/catch around parseRepositoryFullName in the
  branch-search effect; selectedRepository is already null-guarded.
- Repo search now adds `user:<login>` to the /search/repositories query so
  results stay within the connected user's repos instead of returning
  global GitHub results
- Inline rate-limit message in the repo and branch combobox when GitHub
  returns a 403/429, instead of firing a generic alert
- Refresh icon button next to the branch combobox so users who create a
  branch on GitHub mid-flow can refetch without switching repos
- Clearer log when workflow_dispatch fails because the workflow file is
  not yet on the default branch
…node}@v6

Matches the version used by every other workflow in this repo.
…-flow

# Conflicts:
#	apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding.tsx
…yaml

Inputs like "./" pass the upstream non-empty trim check but normalize to
"" inside buildWorkflowYaml, which would emit `paths: [""]` and an empty
STACK_AUTH_CONFIG_PATH env var. Fail fast at the boundary instead of
committing a silently broken workflow to the user's repo.
…I command

Matches the team convention for interpolating values into CLI commands
displayed for user copy-paste. Visually identical for current project ID
formats, defensive against future changes.
parseGithubMatchingRefs was silently returning [] on non-array input,
unlike every other parseGithub* helper in the file which throws. Match
the established pattern so a malformed response surfaces instead of
quietly producing an empty branch list.
- Render private-repo indicator as a trailing lock icon on a single-line row instead of stacking a "private" subtitle.
- Harden checkConfigPathExists against directory/symlink responses and reject `.`/`..` paths before hitting the API.
- Treat 404 from `git/trees/<sha>` as "no paths yet" so freshly-initialized repos whose commit points at the empty-tree SHA (4b825dc…) no longer surface a fatal alert on the Select config file step.
Adds `--source github` with `--source-repo`, `--source-path`, and
`--source-workflow-path` (all required together) so the CLI can declare
its provenance explicitly instead of relying solely on `GITHUB_*` env
vars. `commit_hash` and `branch` are still read from `GITHUB_SHA` /
`GITHUB_REF_NAME`.

Adds `workflow_path` to the `pushed-from-github` source schema
(optional for backward compat with existing rows). The dashboard's
generated workflow YAML now emits the new flags and uses
`${{ github.repository }}` at runtime so the stored source reflects
renames/transfers. The project-settings UI surfaces the workflow file
as a clickable GitHub link.
@vercel
Copy link
Copy Markdown

vercel Bot commented May 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
stack-auth-hosted-components Ready Ready Preview, Comment May 20, 2026 9:56pm
stack-auth-mcp Ready Ready Preview, Comment May 20, 2026 9:56pm
stack-auth-skills Ready Ready Preview, Comment May 20, 2026 9:56pm
stack-backend Ready Ready Preview, Comment May 20, 2026 9:56pm
stack-dashboard Ready Ready Preview, Comment May 20, 2026 9:56pm
stack-demo Ready Ready Preview, Comment May 20, 2026 9:56pm
stack-docs Ready Ready Preview, Comment May 20, 2026 9:56pm
stack-preview-backend Ready Ready Preview, Comment May 20, 2026 9:56pm
stack-preview-dashboard Ready Ready Preview, Comment May 20, 2026 9:56pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ecf74c9d-af72-4af7-9633-a8f2b5c04382

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/config-push-source-flags

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 20, 2026

Greptile Summary

This PR extends stack config push with explicit --source github flags (--source-repo, --source-path, --source-workflow-path), adds workflow_path to the pushed-from-github schema, and surfaces a clickable workflow-file link in the project-settings UI. The generated onboarding workflow YAML is updated to emit the new flags using ${{ github.repository }} at runtime so the stored source stays accurate after repo renames.

  • CLI (config-file.ts): New buildConfigPushSource validates --source-repo with a strict parseOwnerRepo regex and reads GITHUB_SHA/GITHUB_REF_NAME from the environment; --source-path and --source-workflow-path are accepted verbatim without an empty-string guard.
  • Dashboard UI (page-client.tsx): Workflow-file row is conditionally rendered with a correctly percent-encoded GitHub URL; branch and path segments are split-then-encoded to handle slashes.
  • Schema & types: workflow_path added as optional across schema-fields.ts, admin-app-impl.ts, projects/index.ts, and e2e helpers, keeping the change backward-compatible.

Confidence Score: 4/5

Safe to merge; the change is additive and backward-compatible, with solid test coverage across CLI flag validation, YAML generation, and type round-trips.

The only gap is that --source-path and --source-workflow-path accept empty strings without complaint, which could leave config_file_path blank in the stored source record. This requires intentional malformed CLI input to trigger and has no impact on the auto-generated workflow or the UI's graceful empty-value handling.

packages/stack-cli/src/commands/config-file.ts — the empty-string path validation gap for --source-path and --source-workflow-path.

Important Files Changed

Filename Overview
packages/stack-cli/src/commands/config-file.ts Core logic for new --source flags: adds parseOwnerRepo validation, SourceFlagOptions type, and updated buildConfigPushSource; --source-path and --source-workflow-path values are stored verbatim without empty-string guards
packages/stack-cli/src/commands/config-file.test.ts Good test coverage for new buildConfigPushSource: covers happy paths, all missing-flag combinations, invalid repo format, and GITHUB_SHA/GITHUB_REF_NAME absence; no tests for empty-string sourcePath/sourceWorkflowPath
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/project-settings/page-client.tsx Adds 'Workflow file' UI row with correctly encoded GitHub URL; branch and workflowPath segments are split-then-encoded to handle slashes; rendered only when workflowPath is truthy
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding-workflow.ts Generated workflow YAML correctly emits new env vars and CLI flags; user-provided values are JSON.stringify-escaped; STACK_AUTH_SOURCE_REPO uses GitHub runtime expression ${{ github.repository }}
packages/stack-shared/src/schema-fields.ts Adds workflow_path as optional yup string to the pushed-from-github schema; backward-compatible since existing rows without the field still validate

Sequence Diagram

sequenceDiagram
    participant GH as GitHub Actions Runner
    participant CLI as stack-cli
    participant API as Stack Backend API
    participant DB as Database
    participant UI as Dashboard UI

    GH->>CLI: npx stack-cli config push --source github
    CLI->>CLI: buildConfigPushSource()
    CLI->>API: PUT /api/v1/internal/config/override/branch
    API->>DB: Store config override + source metadata
    DB-->>API: OK
    API-->>CLI: 200 OK
    UI->>API: GET project config source
    API-->>UI: "PushedConfigSource { workflowPath }"
    UI->>UI: Render clickable GitHub link
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
packages/stack-cli/src/commands/config-file.ts:79-81
`--source-path` and `--source-workflow-path` are checked only for `=== undefined`, so an empty string `""` passes the "all flags provided" gate and gets stored verbatim as `config_file_path: ""` or `workflow_path: ""`. Only `--source-repo` is subsequently validated by `parseOwnerRepo`. An empty `config_file_path` stored in the API payload would render as a blank "Config file" row in the dashboard and create a broken GitHub link if the workflow path were also empty.

```suggestion
    const { owner, repo } = parseOwnerRepo(flags.sourceRepo!, "--source-repo");

    if (!flags.sourcePath) {
      throw new CliError("--source-path must be a non-empty path string.");
    }
    if (!flags.sourceWorkflowPath) {
      throw new CliError("--source-workflow-path must be a non-empty path string.");
    }

    const sha = process.env.GITHUB_SHA;
```

Reviews (1): Last reviewed commit: "Merge branch 'fix/github-config-link-flo..." | Re-trigger Greptile

Comment thread packages/stack-cli/src/commands/config-file.ts
…-path

Previously these flags were only checked for `=== undefined`, so passing
`--source-path ""` would store `config_file_path: ""` verbatim. Now we
require a non-empty value, matching the existing `parseOwnerRepo` check
for `--source-repo`. Adds tests covering both cases.
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