feat(repos): make repos install/uninstall the single path for GitLab - #5846
feat(repos): make repos install/uninstall the single path for GitLab#5846ggallen wants to merge 1 commit into
Conversation
Wire GitLab-specific install and uninstall steps into repos management commands, eliminating the need for separate admin gitlab commands. Install (repos install): - Create project access token (Premium/Ultimate) or accept --gitlab-bot-token flag for free-tier instances; store as FULLSEND_FORGE_TOKEN CI/CD variable - Detect GitLab tier and create pipeline schedules (dual 5min/15min for enterprise, hourly for free) - Set forge-aware required variables (FULLSEND_CREDENTIAL_MODE, FULLSEND_FORGE) instead of GitHub-specific ones (FULLSEND_MINT_URL) Uninstall (repos uninstall): - Clean up pipeline schedules (fullsend-prefixed) - Revoke bot project access tokens - Remove all fullsend CI/CD variables including poller runtime state (DISPATCHED_KEYS, FAILED_KEYS) Also: - Make checkInstallComponents forge-aware so GitLab repos are not misreported as partially installed - Fix glWorkflowRefPattern/glShimRefPattern to not match head_ref:/base_ref: inside dispatch template scripts (word boundary) - Add [skip ci] to GitLab scaffold commits to prevent spurious failed pipelines - Add --gitlab-bot-token flag and GitLab install docs to repos.md - Add forge.gitlab.runner_tags support to repos set-default Signed-off-by: Greg Allen <gallen@redhat.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Greg Allen <gallen@redhat.com>
|
🤖 Finished Review · ✅ Success · Started 3:17 AM UTC · Completed 3:37 AM UTC |
PR Summary by QodoUnify GitLab install/uninstall under
AI Description
Diagram
High-Level Assessment
Files changed (27)
|
|
🤖 Finished Retro · ✅ Success · Started 3:21 AM UTC · Completed 3:32 AM UTC |
Code Review by Qodo
1. Region variable clobbered empty
|
| expiresAt := time.Now().AddDate(1, 0, 0).Format("2006-01-02") | ||
| token, err := glClient.CreateProjectAccessToken(ctx, owner, repo, fullsendBotTokenName, | ||
| []string{"api"}, gitlabAccessLevelMaintainer, expiresAt) | ||
| if err != nil { |
There was a problem hiding this comment.
2. Gitlab ops bypass forge.client 📘 Rule violation ⌂ Architecture
New CLI code directly depends on *gitlab.LiveClient and calls GitLab-specific APIs (e.g., CreateProjectAccessToken) instead of routing operations exclusively through the forge.Client interface. This weakens the abstraction boundary and makes multi-forge support harder to maintain.
Agent Prompt
## Issue description
Forge-specific operations are being performed in `internal/cli/` by directly calling `*gitlab.LiveClient` methods, bypassing the `forge.Client` abstraction.
## Issue Context
The CLI currently casts `forge.Client` to a concrete GitLab client and invokes GitLab-only methods for token management and tier detection. The compliance requirement is that forge operations should be routed through `forge.Client` so higher layers remain forge-agnostic.
## Fix Focus Areas
- internal/cli/repos_gitlab.go[19-56]
- internal/cli/repos_gitlab.go[58-98]
- internal/cli/repos_gitlab.go[124-151]
- internal/cli/repos.go[679-699]
- internal/forge/forge.go[1-200]
- internal/forge/gitlab/ci.go[695-866]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| case ForgeGitHub: | ||
| return map[string]string{ | ||
| "FULLSEND_MINT_URL": mintURL, | ||
| "FULLSEND_GCP_REGION": cfg.InferenceRegion, | ||
| forge.PerRepoGuardVar: "true", | ||
| }, nil |
There was a problem hiding this comment.
3. Region variable clobbered empty 🐞 Bug ≡ Correctness
installVarsForForge now always writes FULLSEND_GCP_REGION for GitHub, so when cfg.InferenceRegion is empty (e.g., secret reuse path) it can overwrite a previously valid region with "". BatchInstall’s validation only checks whether the variable exists (not whether it’s non-empty), so this can silently leave repos installed but misconfigured.
Agent Prompt
### Issue description
`installVarsForForge` always includes `FULLSEND_GCP_REGION` for GitHub, which means a run with `cfg.InferenceRegion == ""` will call `CreateOrUpdateRepoVariable(..., "FULLSEND_GCP_REGION", "")` and wipe an existing region value.
### Issue Context
`BatchInstall` allows `--inference-region` to be omitted when `FULLSEND_GCP_REGION` already exists, but it does not validate that the existing value is non-empty. The new unconditional write can therefore clear the region during a converge/reinstall that reuses existing secrets.
### Fix Focus Areas
- internal/repos/install.go[289-296]
- internal/repos/batch_install.go[177-190]
- internal/repos/batch_install.go[324-331]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| var gitlabRequiredVariables = []string{"FULLSEND_CREDENTIAL_MODE", "FULLSEND_FORGE"} | ||
|
|
||
| func requiredVarsForForge(forgeName string) []string { | ||
| if forgeName == ForgeGitLab { | ||
| return gitlabRequiredVariables |
There was a problem hiding this comment.
4. Gitlab install skips token check 🐞 Bug ≡ Correctness
checkInstallComponents for GitLab only requires FULLSEND_CREDENTIAL_MODE and FULLSEND_FORGE, so it can treat a repo as fully installed even when FULLSEND_FORGE_TOKEN is missing. The GitLab poll scaffold explicitly fails when FULLSEND_FORGE_TOKEN is unset, so repos can be reported/handled as installed but be non-functional.
Agent Prompt
### Issue description
`gitlabRequiredVariables` omits `FULLSEND_FORGE_TOKEN`, so `checkInstallComponents(..., ForgeGitLab, ...)` can return `fullyInstalled=true` even when the bot token variable is absent.
### Issue Context
The GitLab poll job exits with an error if `FULLSEND_FORGE_TOKEN` is not set, so token absence is an install-breaking condition and should be part of the “fully installed” criteria.
### Fix Focus Areas
- internal/repos/install.go[336-380]
- internal/scaffold/fullsend-repo-gitlab/.gitlab/ci/fullsend-poll.yml[52-61]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Retro: PR #5846 —
|
|
Review skipped — this PR is already closed. The Posted by fullsend post-review check |
Summary
Wire GitLab-specific install and uninstall steps into
reposmanagement commands, eliminating the need for separateadmin gitlabcommands. This is Phase 4 of the GitLab support rollout.Install (
repos install)--gitlab-bot-tokenflag for free-tier instances; store asFULLSEND_FORGE_TOKENCI/CD variableFULLSEND_CREDENTIAL_MODE,FULLSEND_FORGE) instead of GitHub-specific ones (FULLSEND_MINT_URL)Uninstall (
repos uninstall)DISPATCHED_KEYS,FAILED_KEYS).fullsend/config.yamlalong with other scaffold filesAlso
checkInstallComponentsforge-aware so GitLab repos are not misreported as partially installedglWorkflowRefPattern/glShimRefPatternto not matchhead_ref:/base_ref:inside dispatch template scripts (word boundary)[skip ci]to GitLab scaffold commits to prevent spurious failed pipelines--gitlab-bot-tokenflag and GitLab install docs torepos.mdforge.gitlab.runner_tagssupport torepos set-default__RUNNER_TAGS__placeholder to all three GitLab scaffold templatesFiles changed (27)
internal/cli/repos.go— GitLab post-install/uninstall steps,--gitlab-bot-tokenflaginternal/cli/repos_gitlab.go— new: bot token setup, schedule creation/cleanup, token cleanupinternal/cli/repos_gitlab_test.go— new: tests for setup/cleanup functionsinternal/repos/uninstall.go— GitLab-specific variable list, scaffold paths (including.fullsend/config.yaml),[skip ci]internal/repos/install.go— forge-awarecheckInstallComponents, credential mode variablesinternal/repos/forge_config.go— word boundary fix for ref regex patternsinternal/forge/gitlab/ci.go—IsEnterprise,CreateProjectAccessToken,ListPipelineSchedules,CreatePipelineSchedule,DeletePipelineScheduleinternal/scaffold/installfiles.go— runner tag injection into scaffold templatesTest plan
go build ./...go test ./internal/repos/... -count=1go test ./internal/cli/... -run 'TestSetupGitLab|TestCleanupGitLab' -count=1go test ./internal/forge/gitlab/... -count=1go test ./internal/scaffold/... -count=1gitlab.cee.redhat.com/gallen/integration-servicerepos statusno longer shows$head_refin REF column[skip ci]producesskipped(notfailed) pipeline on scaffold pushCloses #5844
🤖 Generated with Claude Code