Skip to content

feat(flows): GitLab as a ticket source and repository host in onboarding - #100

Merged
kjgbot merged 10 commits into
mainfrom
feat/flows-gitlab-onboarding
Sep 19, 2026
Merged

kjgbot merged 10 commits into
mainfrom
feat/flows-gitlab-onboarding

Conversation

@kjgbot

@kjgbot kjgbot commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #98 (resilient checks), which owns the generator this changes.

Why

A GitLab flow could not be set up: the onboarding offered no GitLab source, and the generated flow always ended in gh pr create, which cannot open a GitLab merge request.

Cloud contract this targets (AgentWorkforce/cloud#3800 / #3801, not changed here)

  • Deploy handoff (flow-handoff.ts) accepts sources containing "gitlab" and sourceSettings.gitlab = { project: "namespace/project", labels?: "a, b" } (it also accepts events: "issues" | "merge_request"; not offered here, for parity with GitHub, whose onboarding has no events choice either).
  • With no GitHub source, Cloud infers the deploy target as the GitLab project from sourceSettings.gitlab.project.
  • A delivered GitLab issue reaches the flow as { source: "gitlab", title, body, labels, project }.
  • Hosted repository runs have relayflow-open-change on PATH: gh pr create with the same args/exit status on GitHub, a merge request on GitLab (--title, --body-file, --draft supported).

Changes

  • Source: GitLab (project, labels) in ISSUE_SOURCES; icon (SiGitlab) and colour in the picker; validation, summaries and the generated Issue type follow from the shared tables. repositoryHost(sources) mirrors Cloud's inference and drives the "Open PR" step's icon in the workflow picker and the handoff preview.
  • Generated flow: the change request opens through open_change() { relayflow-open-change "$@" if on PATH, else gh pr create "$@" } (FLOW_OPEN_CHANGE_COMMAND), keeping --draft for failing checks.
  • Local kit: the preflight stops a GitLab origin (gitlab.com or a gitlab.* host) before any agent runs and points at the Cloud deploy; START-HERE and the Run options copy say so.

Degrades on GitLab (noted, not fixed here)

Marking a PR back to draft after a failed review/check (gh pr ready --undo) and posting the report as a comment (gh pr comment) are GitHub-only. On GitLab those steps already exit 0 and print "could not convert / could not comment", and the report stays in review-blocked.md / .relayflow/check-report.md; the MR itself is opened as a draft up front when checks fail. The fixer's task text still suggests gh pr view --comments. A relayflow-open-change counterpart for draft/comment would close this in Cloud.

Verification

  • web vitest: 20 files / 197 tests pass (new flow-gitlab-source.test.ts: source fields, validation, host rule, Issue type, local project/label filtering incl. the kit's own prefill, preview icon; new FLOW_OPEN_CHANGE_COMMAND shell tests with fake relayflow-open-change/gh on PATH: helper used when present, gh pr create fallback with identical args, exit status kept; GitLab-origin preflight for SSH, HTTPS and self-managed hosts, with the existing example.com origin as positive control).
  • tsc --noEmit (web) clean.
  • Rendered GitLab flows (cloud + local × simple + traditional): flows check passes on all four with @relayflows/surface 2.0.18, and strict tsc against the surface types is clean (a deliberately broken copy fails, so the check is real).

🤖 Generated with Claude Code


Note

Medium Risk
Touches generated flow publish steps and local preflight gates; mistakes in GitLab vs GitHub remote detection could block valid repos or allow unsupported local runs.

Overview
Adds GitLab as a flow ticket source in onboarding (project + labels), with picker icon/styling and the same validation and generated Issue shape Cloud expects.

Repository host inference (repositoryHost): when GitLab is selected without GitHub, the workflow preview and “Open PR” step show GitLab instead of GitHub, matching Cloud’s deploy target rules.

Generated flows no longer call gh pr create directly. They use FLOW_OPEN_CHANGE_COMMAND, which prefers hosted relayflow-open-change (GitHub PR or GitLab MR) and falls back to gh pr create locally.

Local kit preflight detects GitLab origin URLs (including self-managed hosts) and stops before agents run, with copy in START-HERE and Run options directing users to Cloud for GitLab repos.

Reviewed by Cursor Bugbot for commit db7adaa. Bugbot is set up for automated code reviews on this repo. Configure here.

kjgbot and others added 4 commits September 18, 2026 08:50
… the work away

The generated flow ran one hard-coded recipe (npm ci && npm test behind a
lockfile detector) and treated its exit code as the whole verdict, so a
failing test step killed the run with the agents' finished work unpushed.
Two production runs died that way:

- AgentWorkforce/cloud acbe30c1: cloud's suite needs @cloud/core built
  first, which its CI does and the recipe did not.
- AgentWorkforce/relay 139d1a46: the branch passed all 3,227 tests in a
  clean shell of the same sandbox, but 18 failed inside the flow, among
  them `transport 'file' not allowed` from Cloud's own git configuration.

The check step is now language-agnostic and resilient:

- The check script (.relayflow/check.sh) comes from the author's
  checkCommand, a committed .relayflow/check.sh, a discovery agent that
  reads CI config, Makefile/justfile and README, or an ecosystem default
  (make/just test, Node, Cargo, Go, Python, Ruby, Maven, Gradle, .NET, Mix).
- Each check step prints one token and exits 0; output goes to
  .relayflow/*.log and its tail to stderr for the journal. The check runs
  without Cloud's GIT_CONFIG_* hardening and stops itself before the
  15-minute f.run lease.
- A repair agent (two attempts) fixes missing setup in check.sh or bugs in
  the change, never by weakening tests.
- What still fails is compared with the base commit in a throwaway
  worktree. The branch is always pushed and the pull request opens as a
  draft with the verdict, the script and both outputs in its body. A
  change that breaks checks the base passes ends step_failed; a failure
  the base shares ends needs_human after the reviews.
- Working files (summary.md, plans, reviews, .relayflow/, kit files) are
  excluded through .git/info/exclude and, if an agent committed them
  anyway, removed from the branch before every push. Both production runs
  had Codex commit summary.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… setup

Check discovery ran once, before the implementer. On a repository with no
way to test itself it resolved "none", and a change that added the first
package.json and test script shipped without any check running: dev run
53f1bc98 opened AgentWorkforce/cloud-e2e-sandbox#31 with tests the flow
never ran ("no checks ran"). A "none" is now resolved again after the
implementer; any other answer is kept, so the base commit and the branch
are still checked the same way.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A software-factory run against a repository the size of
AgentWorkforce/cloud spends most of an hour in the implementer before its
CI-equivalent checks even start (dev run af3069c9: implementer still
working at 39 minutes of 60, checks not started). One hour leaves no room
for checks, repair and a base comparison. Cloud's own run ceiling is being
raised to match in a separate AgentWorkforce/cloud PR; until that lands the
hosted run is still cut at its ~55-minute cloud limit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds GitLab to the flows onboarding so a GitLab flow can be set up, against
the contract of AgentWorkforce/cloud#3800/#3801:

- GitLab source with `project` ("namespace/project") and `labels`, the
  fields Cloud's deploy handoff reads from sourceSettings.gitlab; Cloud makes
  the project the deploy target when no GitHub source is chosen, and
  `repositoryHost` mirrors that rule for the preview and picker icons.
- The generated flow opens its change through `relayflow-open-change` when
  Cloud puts it on PATH (gh pr create on GitHub, a merge request on GitLab)
  and falls back to `gh pr create` for local runs.
- Local kit: the preflight stops a GitLab origin before any agent runs,
  pointing at the Cloud deploy, since a local run only has gh.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 5f5bd081-d048-4ee2-97d7-f9499f3baae8


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.

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread web/lib/flow-local.ts
@github-actions

github-actions Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Preview deployed!

Environment URL
Web https://5d9ceea1-agentrelay-web.agent-workforce.workers.dev

This is a Cloudflare Workers preview version of this PR's build.

kjgbot and others added 4 commits September 18, 2026 16:27
The GitLab-origin guard ran only on the main preflight path; repoProblem, which
vets a relocation target, still accepted a GitLab remote, so the kit was copied
into a repository its own preflight then rejects (Cursor Bugbot on #100). Both
paths now share isGitLabOrigin and the same advice.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…n macOS, own new checks

Three Bugbot findings on the resilient check step:

- Base comparison used a cleaner tree. The branch's checks ran in a tree the
  implementer had built in; the base ran in a fresh worktree, so a default
  that builds nothing (make test, python3 -m pytest) could fail there for
  missing setup and turn a real regression into "pre-existing". The base is
  now checked in the same tree (ignored build products stay), then the branch
  is restored by name and anything the base run changed in tracked files is
  discarded; a tree with uncommitted tracked changes still uses a worktree.

- No limiter without `timeout`. macOS ships neither `timeout` nor
  `gtimeout`, so a hung check ran into the 15-minute f.run lease and failed
  the run before anything was pushed. `gtimeout` and a small Perl limiter
  (own process group, whole group stopped, exit 124) are now fallbacks.

- Checks the change introduced read as pre-existing. When the first resolve
  found nothing and the change added the test setup, the base lacks those
  files and always fails. Such a failure is now baseline "new": reported as
  the change's own and ended step_failed, like a regression.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…it is committed

The same-tree base comparison checked out the base commit in place and then
ran .relayflow/check.sh from that tree. A repository that commits the script
had it replaced or deleted by the checkout, so the base ran a different
recipe or reported none. The branch's script is now copied aside first and
both sides run it, as the worktree fallback already did.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…feat/flows-gitlab-onboarding

# Conflicts:
#	web/lib/flow-workflows.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit d3b89ef. Configure here.

Comment thread web/lib/flow-local.ts
The local kit refused GitHub remotes whose path mentions gitlab
(github.com/gitlab-org/..., a repository named gitlab): the check ran a
substring regex over the whole URL, and the template literal it lives in
also turned gitlab\.com into gitlab.com. Parse the host out of the URL or
scp-style remote and match only that.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Base automatically changed from fix/flow-resilient-checks to main September 19, 2026 02:31
…oarding

# Conflicts:
#	web/app/flows/onboarding/RunOptions.tsx
#	web/lib/flow-local.ts
#	web/lib/flow-workflows.ts
#	web/lib/test/flow-local.test.ts
#	web/lib/test/flow-onboarding.test.ts
#	web/lib/test/flow-workflows.test.ts
@kjgbot
kjgbot merged commit d0eea77 into main Sep 19, 2026
5 checks passed
@kjgbot
kjgbot deleted the feat/flows-gitlab-onboarding branch September 19, 2026 02:40
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