Skip to content

fix(dashboard): repair and polish the GitHub link-existing project flow#1441

Open
BilalG1 wants to merge 19 commits into
devfrom
fix/github-config-link-flow
Open

fix(dashboard): repair and polish the GitHub link-existing project flow#1441
BilalG1 wants to merge 19 commits into
devfrom
fix/github-config-link-flow

Conversation

@BilalG1
Copy link
Copy Markdown
Collaborator

@BilalG1 BilalG1 commented May 19, 2026

Rework of the new-project → Link Existing Config flow on the dashboard, plus the published stack-cli it depends on.

The starting point on dev had the link-existing flow effectively broken end-to-end (the generated GitHub workflow could never authenticate, and the GitHub-account selection UI dead-ended in several states). This PR fixes the blockers, polishes the local-CLI path, and adds a searchable repo/branch picker.


What was broken

Severity Issue Fixed in
🔴 Generated workflow omitted the required --cloud-project-id flag → every run failed at Commander before the action ran. d0e6ad15f, 55ff7e319
🔴 Workflow exported STACK_PROJECT_ID env var the CLI never read. 55ff7e319 (CLI now reads it; workflow drops the explicit flag)
🔴 pnpx isn't on ubuntu-latest → step failed with command not found. 65789a1ac
🔴 "No connected GitHub account found" alert with no Connect button. d0e6ad15f
🟠 "Connect new" used getOrLinkConnectedAccount (get-or-link) → silently returned the existing account instead of starting a fresh OAuth flow. d0e6ad15f
🟠 workflow_dispatch 404s on non-default branches; threw before advancing to the logs step even though the push-triggered run worked. d0e6ad15f
🟠 Config-path suggestions prepended ./, which breaks GitHub's on.push.paths filter — ongoing config edits never re-triggered the workflow. d0e6ad15f
🟡 Account selector briefly showed the numeric providerAccountId before the GitHub /user fetch populated the username. de9ec1923
🟡 Repository / branch dropdowns capped at 100 entries with no search. 7550eaacb

What changed

Dashboard — Link Existing Config flow

  • Local CLI step rebuild (ed25eabf9, ebb090e5b): split into separate "Sign in" and "Push config" code blocks using the shared CodeBlock component (copy button built-in), added a npx / pnpx / bunx runner pill toggle (default npx), moved --config-file <path> to the end of the push command so users can copy everything up to the placeholder, trimmed redundant helper text.
  • GitHub OAuth states (d0e6ad15f, de9ec1923): empty-state "Connect GitHub account" button; "Connect new" now uses linkConnectedAccount so it actually starts OAuth; loading row instead of providerAccountId flash.
  • Searchable repo + branch combobox (7550eaacb, 5ce1b6bd9): new RemoteSearchCombobox (Popover + cmdk, same pattern as data-table/faceted-filter), debounced GitHub /search/repositories and /git/matching-refs/heads/{prefix} calls so users with > 100 repos/branches can find any of them. Branch "Refresh" button removed — branches auto-load on repo select.
  • Workflow generator (d0e6ad15f, 65789a1ac): config paths normalised (strip leading ./); workflow uses actions/setup-node@v4 + npx --yes; workflow_dispatch failure is now best-effort (the workflow-file commit's push event triggers the run on any branch).

Stack CLI

  • STACK_PROJECT_ID env-var fallback for --cloud-project-id (55ff7e319). Both config push and config pull are affected; explicit flag still wins. New resolveProjectId helper in lib/auth.ts with 5 unit tests (auth.test.ts).

Misc

  • 2faffb662 drops an unused useTransition wrapper around a setProjectStatuses Map insert in the new-project flow.

Release ordering note

The generated workflow's run: line no longer passes --cloud-project-id — the CLI reads STACK_PROJECT_ID from env instead. This means a workflow generated by this branch only works against a @stackframe/stack-cli published with the env-var fallback from 55ff7e319. The CLI and dashboard ship from the same monorepo so this should be a non-issue in the normal release cadence, but worth confirming the CLI publishes alongside the dashboard deploy.

Existing workflows already committed in user repos still have the explicit flag and continue to work unchanged.

Validation

  • pnpm --filter @stackframe/dashboard run typecheck
  • pnpm --filter @stackframe/dashboard run lint
  • pnpm --filter @stackframe/stack-cli run typecheck
  • pnpm --filter @stackframe/stack-cli run lint
  • pnpm --filter @stackframe/stack-cli test ✅ (14 tests; 5 new for resolveProjectId)

Summary by CodeRabbit

  • New Features

    • Searchable repository and branch selection UI for GitHub onboarding
    • New remote search combobox component for selecting repos/branches
    • Selectable CLI package runner and dynamic command display during onboarding
  • Improvements

    • CLI accepts STACK_PROJECT_ID env var; cloud project flag is optional
    • Workflow generation normalizes/validates config paths, sets up Node.js v20, and uses npx; onboarding dispatch is non-fatal
    • Hardened repository loading to avoid stale async updates
  • Tests

    • Added tests covering project ID resolution logic

Review Change Stack

BilalG1 added 9 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.
@vercel
Copy link
Copy Markdown

vercel Bot commented May 19, 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 2:23am
stack-auth-mcp Ready Ready Preview, Comment May 20, 2026 2:23am
stack-auth-skills Ready Ready Preview, Comment May 20, 2026 2:23am
stack-backend Ready Ready Preview, Comment May 20, 2026 2:23am
stack-dashboard Ready Ready Preview, Comment May 20, 2026 2:23am
stack-demo Ready Ready Preview, Comment May 20, 2026 2:23am
stack-docs Ready Ready Preview, Comment May 20, 2026 2:23am
stack-preview-backend Ready Ready Preview, Comment May 20, 2026 2:23am
stack-preview-dashboard Ready Ready Preview, Comment May 20, 2026 2:23am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 19, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Refactors link-existing onboarding with a RemoteSearchCombobox, guarded async repo/branch remote search, workflow YAML normalization and Node v20 setup, non-fatal workflow dispatch, runner-aware CLI command rendering, and adds resolveProjectId to make the CLI project-id flag optional.

Changes

Dashboard Onboarding Refactor

Layer / File(s) Summary
RemoteSearchCombobox Component
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-combobox.tsx
New reusable RemoteSearchCombobox component with controlled query/value, Popover UI, loading spinner and empty-state messaging, and selection handlers.
Workflow Generation Updates
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding-workflow.ts
Adds normalizeConfigPath to canonicalize GitHub Actions push path filters, validates non-empty normalized path, includes Node v20 setup, and changes CLI invocation from pnpx to npx.
useTransition Cleanup
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/content.tsx
Removes React useTransition import and the transition wrapper so projectStatuses updates run directly.
Onboarding Helpers and Constants
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding.tsx
Adds UI imports (CodeBlock, DesignPillToggle), defines PackageRunner/PACKAGE_RUNNERS, introduces parseGithubMatchingRefs and rate-limit detection, and keeps repo-relative config path suggestions.
Repository Loading Async Safety
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding.tsx
Adds repositoriesLoadedAccountRef and loadRepositoriesRunIdRef guards with isCurrent() checks; moves initial repo load into an effect keyed by account id and ensures loading state is cleared only for the current run.
Workflow Effects and Error Handling
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding.tsx
Adds debounced remote-search effects for repositories and branches with cancellation and rate-limit handling; wraps workflow dispatch in try/catch to log failures non-fatally and continue monitoring.
CLI Runner and Selection UI
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding.tsx
Renders runner-aware CLI commands via CodeBlock, adds DesignPillToggle for package runner selection, improves account selection UI, and replaces repo/branch dropdowns with RemoteSearchCombobox wired to remote search state.

CLI Project ID Resolution

Layer / File(s) Summary
resolveProjectId Implementation and Tests
packages/stack-cli/src/lib/auth.ts, packages/stack-cli/src/lib/auth.test.ts
Adds resolveProjectId(projectIdOption?: string) to prefer the CLI option then STACK_PROJECT_ID, treating empty strings as absent and throwing CliError when missing; tests validate precedence and error cases.
Config Command Integration
packages/stack-cli/src/commands/config-file.ts
Makes --cloud-project-id optional for config pull and config push, imports and uses resolveProjectId when resolving auth.

Sequence Diagram

sequenceDiagram
  participant GitHubRepositoryStep
  participant loadRepositories
  participant GitHubAPI
  participant workflowDispatch
  GitHubRepositoryStep->>loadRepositories: enter step -> start run-id
  loadRepositories->>GitHubAPI: fetch /user and repos
  GitHubAPI-->>loadRepositories: return user/repos
  loadRepositories->>GitHubRepositoryStep: set repositories (only if run-id current)
  GitHubRepositoryStep->>workflowDispatch: dispatch workflow (try/catch)
  workflowDispatch-->>GitHubRepositoryStep: log dispatch error, continue monitoring
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • mantrakp04
  • aadesh18

Poem

🐇 I hop through combobox and branch-lit code,

Debounced searches keep the results in mode,
Run-ids guard the async road,
Paths trimmed and encoded for the workflow's go,
Project IDs found so commands can flow.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.53% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main change: repairing and improving the GitHub link-existing project flow in the dashboard.
Description check ✅ Passed The description is comprehensive, detailed, and well-organized. It includes a clear table of issues fixed, detailed explanation of changes across multiple areas, validation results, and important release ordering notes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/github-config-link-flow

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 19, 2026

Greptile Summary

This PR repairs the end-to-end Link Existing Config onboarding flow in the dashboard and the stack-cli it depends on. Multiple blockers (missing --cloud-project-id flag in the generated workflow, pnpx not available on ubuntu-latest, dead-end OAuth states) are fixed, and the repo/branch pickers are upgraded to searchable comboboxes backed by debounced GitHub API calls.

  • Dashboard (link-existing-onboarding.tsx): replaces plain dropdowns with RemoteSearchCombobox, delegates repository loading to a useEffect watching selectedGithubAccount (with run-ID-based stale-response cancellation), switches "Connect new" to linkConnectedAccount, and adds an empty-state connect button. The workflow_dispatch 404 is now caught and logged as non-fatal, letting the push-triggered run proceed.
  • Workflow generator (link-existing-onboarding-workflow.ts): adds normalizeConfigPath to strip leading ./, replaces pnpx with npx --yes, adds setup-node@v4, and removes the explicit --cloud-project-id flag in favour of STACK_PROJECT_ID env var.
  • CLI (auth.ts / config-file.ts): new resolveProjectId helper reads STACK_PROJECT_ID env var as a fallback for --cloud-project-id; both config push and config pull now use it, with five unit tests covering all branches.

Confidence Score: 4/5

Safe to merge with minor follow-up. The critical workflow and CLI bugs are properly fixed, and the new combobox and useEffect-driven repo loading are logically sound.

The changes are well-reasoned and cover the stated bugs. Two small gaps exist: project.id is interpolated unescaped into the displayed bash command (against the team's escaping convention), and the config-path button guard does not account for paths like "./" that pass the trim-length check but normalize to an empty string inside buildWorkflowYaml — producing a broken workflow file if the user somehow arrives there.

link-existing-onboarding.tsx (configPushCommand escaping and config-path empty-after-normalization guard), link-existing-onboarding-workflow.ts (normalizeConfigPath edge case downstream)

Important Files Changed

Filename Overview
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding.tsx Major overhaul: replaces plain dropdowns with searchable comboboxes, fixes GitHub OAuth empty-state, switches "Connect new" to linkConnectedAccount, moves loadRepositories to a useEffect, and handles workflow_dispatch 404s gracefully. Race conditions for concurrent loads are handled via run-ID ref.
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding-workflow.ts Adds normalizeConfigPath (strips leading ./), switches pnpx → npx --yes, adds setup-node@v4 step, drops --cloud-project-id flag in favour of STACK_PROJECT_ID env var. normalizeConfigPath can return an empty string for inputs like "./", which is not guarded downstream.
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-combobox.tsx New RemoteSearchCombobox component: Popover + cmdk-based, server-side filtering (shouldFilter={false}), exposes query/onQueryChange for debounced parent-driven search. Clean, no issues found.
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/content.tsx Removes the unused useTransition wrapper around setProjectStatuses Map insert. Change is correct and safe.
packages/stack-cli/src/lib/auth.ts Adds resolveProjectId helper that prefers the explicit --cloud-project-id flag then falls back to STACK_PROJECT_ID env var; throws a CliError with guidance when neither is set. Logic is clean and well-tested.
packages/stack-cli/src/lib/auth.test.ts Adds 5 unit tests for resolveProjectId covering flag, env var, precedence, empty-string fallback, and missing-both error. Tests properly save/restore process.env.STACK_PROJECT_ID.
packages/stack-cli/src/commands/config-file.ts Converts --cloud-project-id from requiredOption to option and wraps the value with resolveProjectId for both pull and push commands. Straightforward, consistent change.

Sequence Diagram

sequenceDiagram
    participant U as User (Dashboard)
    participant GH as GitHub OAuth
    participant API as GitHub API
    participant WF as GitHub Actions
    participant CLI as stack-cli

    U->>GH: linkConnectedAccount("github")
    GH-->>U: OAuth redirect back

    Note over U: useEffect detects selectedGithubAccount
    U->>API: GET /user (githubFetch)
    U->>API: GET /user/repos

    U->>U: Select repo + branch (RemoteSearchCombobox)
    Note over U: Debounced /search/repositories on query change
    Note over U: Debounced /git/matching-refs/heads/{prefix} on branch query

    U->>U: Enter config path (normalizeConfigPath strips ./)
    U->>API: Commit workflow YAML via Contents API
    U->>API: POST workflow_dispatch (best-effort, 404 non-fatal)

    WF->>CLI: "npx --yes @stackframe/stack-cli@latest config push"
    Note over CLI: resolveProjectId reads STACK_PROJECT_ID env var
    CLI-->>U: Config pushed → step advances to github-logs
Loading

Comments Outside Diff (1)

  1. apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding.tsx, line 1615 (link)

    P2 The "Create GitHub Action" button is disabled when configPathInput.trim().length === 0, but normalizeConfigPath (called inside buildWorkflowYaml) strips all leading ./ sequences. A path of ./ trims to a non-empty string and passes the guard, but normalizes to "". The generated YAML would then contain STACK_AUTH_CONFIG_PATH: "" and the workflow run would fail with --config-file "".

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding.tsx
    Line: 1615
    
    Comment:
    The "Create GitHub Action" button is disabled when `configPathInput.trim().length === 0`, but `normalizeConfigPath` (called inside `buildWorkflowYaml`) strips all leading `./` sequences. A path of `./` trims to a non-empty string and passes the guard, but normalizes to `""`. The generated YAML would then contain `STACK_AUTH_CONFIG_PATH: ""` and the workflow run would fail with `--config-file ""`.
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding.tsx:1148
Per the team rule on escaping CLI-generated values, `project.id` should be passed through `JSON.stringify` before being interpolated into the bash command string. While project IDs are server-generated and unlikely to contain shell-special characters today, the rule exists precisely to avoid relying on that assumption — a future ID format change or an unusual character could silently produce a broken command.

```suggestion
  const configPushCommand = `${packageRunner} @stackframe/stack-cli@latest config push --cloud-project-id ${JSON.stringify(project.id)} --config-file <path-to-your-config-file>`;
```

### Issue 2 of 2
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding.tsx:1615
The "Create GitHub Action" button is disabled when `configPathInput.trim().length === 0`, but `normalizeConfigPath` (called inside `buildWorkflowYaml`) strips all leading `./` sequences. A path of `./` trims to a non-empty string and passes the guard, but normalizes to `""`. The generated YAML would then contain `STACK_AUTH_CONFIG_PATH: ""` and the workflow run would fail with `--config-file ""`.

```suggestion
        disabled={configPathInput.trim().length === 0 || normalizeConfigPath(configPathInput.trim()).length === 0}
```

Reviews (1): Last reviewed commit: "Merge branch 'dev' into fix/github-confi..." | Re-trigger Greptile

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding-workflow.ts (1)

10-15: ⚡ Quick win

Consider adding defensive validation for empty results.

The function correctly normalizes paths, but edge cases like "./" or whitespace-only input would produce an empty string. An empty config path in the generated workflow would be invalid.

🛡️ Proposed defensive check
 export function normalizeConfigPath(configPath: string): string {
-  return configPath.trim().replace(/^(?:\.\/)+/, "");
+  const normalized = configPath.trim().replace(/^(?:\.\/)+/, "");
+  if (!normalized) {
+    throw new Error("Config path cannot be empty after normalization");
+  }
+  return normalized;
 }

As per coding guidelines: "Fail early, fail loud; fail fast with an error instead of silently continuing" and "Code defensively; prefer ?? throwErr(...) over non-null assertions, with good error messages explicitly stating the assumption that must've been violated".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/dashboard/src/app/`(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding-workflow.ts
around lines 10 - 15, normalizeConfigPath currently returns an empty string for
inputs like "./" or whitespace-only, which leads to invalid workflow config;
after computing the normalized value in normalizeConfigPath (and/or before
returning), defensively validate that the result is non-empty and if it is throw
a clear error (e.g., throw new Error or use the project's throwErr helper) with
a message stating the assumption violated ("configPath must resolve to a
non-empty path after normalization"); reference the normalizeConfigPath function
name and ensure callers either catch this or rely on the thrown error to fail
fast.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@apps/dashboard/src/app/`(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding-workflow.ts:
- Around line 41-44: The GitHub Actions step named "Set up Node.js" currently
uses actions/setup-node@v4; update that usage to the latest major
(actions/setup-node@v6 or at least `@v6.4.0`) by replacing the version token in
the step (the "uses" value) so the workflow uses actions/setup-node@v6 while
preserving the existing node-version input ("20") and other step metadata.

---

Nitpick comments:
In
`@apps/dashboard/src/app/`(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding-workflow.ts:
- Around line 10-15: normalizeConfigPath currently returns an empty string for
inputs like "./" or whitespace-only, which leads to invalid workflow config;
after computing the normalized value in normalizeConfigPath (and/or before
returning), defensively validate that the result is non-empty and if it is throw
a clear error (e.g., throw new Error or use the project's throwErr helper) with
a message stating the assumption violated ("configPath must resolve to a
non-empty path after normalization"); reference the normalizeConfigPath function
name and ensure callers either catch this or rely on the thrown error to fail
fast.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d1ab8631-98db-4385-b31b-c1585677e322

📥 Commits

Reviewing files that changed from the base of the PR and between deff6c3 and 34db0d5.

📒 Files selected for processing (7)
  • apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/content.tsx
  • apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-combobox.tsx
  • apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding-workflow.ts
  • apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding.tsx
  • packages/stack-cli/src/commands/config-file.ts
  • packages/stack-cli/src/lib/auth.test.ts
  • packages/stack-cli/src/lib/auth.ts

- 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.
…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.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding.tsx (1)

363-381: 💤 Low value

Inconsistent error handling compared to other parse functions.

parseGithubMatchingRefs silently returns [] for non-array input, while similar functions (parseGithubBranches, parseGithubRepositories) throw errors. Per coding guidelines, prefer failing loudly over silent fallbacks unless there's a documented reason. If this is intentional for resilience, consider adding a comment explaining why this function differs.

🛡️ Suggested fix for consistency
 function parseGithubMatchingRefs(value: unknown): string[] {
   if (!Array.isArray(value)) {
-    return [];
+    // matching-refs can return 404 for empty matches on some repos; callers
+    // handle errors upstream, so return empty here for resilience.
+    return [];
   }

As per coding guidelines: "Fail early, fail loud. Fail fast with an error instead of silently continuing."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/dashboard/src/app/`(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding.tsx
around lines 363 - 381, The function parseGithubMatchingRefs currently returns
[] when given non-array input; update it to fail loudly like parseGithubBranches
and parseGithubRepositories by throwing a descriptive Error when value is not an
array (e.g., "Expected array of refs"), preserving the rest of the logic that
strips the "refs/heads/" prefix and returns branch names; alternatively, if the
silent behavior is intentional, add a clear comment above
parseGithubMatchingRefs explaining why it differs from the other parse
functions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@apps/dashboard/src/app/`(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding.tsx:
- Around line 363-381: The function parseGithubMatchingRefs currently returns []
when given non-array input; update it to fail loudly like parseGithubBranches
and parseGithubRepositories by throwing a descriptive Error when value is not an
array (e.g., "Expected array of refs"), preserving the rest of the logic that
strips the "refs/heads/" prefix and returns branch names; alternatively, if the
silent behavior is intentional, add a clear comment above
parseGithubMatchingRefs explaining why it differs from the other parse
functions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 52d9ee02-e293-455c-8662-bd8b7a411310

📥 Commits

Reviewing files that changed from the base of the PR and between cdf4c68 and b6783b2.

📒 Files selected for processing (1)
  • apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/link-existing-onboarding.tsx

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.
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.

2 participants