Skip to content

Commit c06abc0

Browse files
authored
Merge pull request #56 from RedHatInsights/bot/RHCLOUD-47130
fix(infra): fix glab CLI install, auth, and GitLab MR status checks
2 parents 654b5ec + 635934f commit c06abc0

3 files changed

Lines changed: 60 additions & 12 deletions

File tree

CLAUDE.md

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ Triage buckets (first match wins):
173173
2. **Interrupted work**`in_progress` w/ `last_step` set, no PR yet. Reload persona → resume.
174174
3. **Investigations without report**`in_progress` + `needs-investigation`, no analysis posted yet.
175175
4. **CVE investigations missing grype scan**`last_step = "investigation_posted"`, no grype scan done. Build Dockerfile + scan per CVE persona.
176-
5. **Failed retryable tasks**`last_step` = `clone_failed`/`push_failed`/`ci_failed`. Retry once. Same error → `paused_reason`, move on.
176+
5. **Failed retryable tasks**`last_step` = `clone_failed`/`push_failed`/`ci_failed`. **Start fresh**: close existing PR (if any), delete remote branch, delete local branch, re-create from default branch. Same error twice`paused_reason`, move on.
177177

178178
None apply → Priority 1.
179179

@@ -183,16 +183,30 @@ For each `pr_open`/`pr_changes` task (check `metadata.prs` for multi-repo, else
183183

184184
0. **Reload persona**: Read `personas/<name>/prompt.md` for repo tech stack (same logic as step 6). Has CI fix patterns + sequencing rules.
185185
1. `cd` repo dir. `git fetch origin`. Fork? Also `git fetch upstream`.
186-
2. Check `host` in `project-repos.json``gh` (GitHub) or `glab` (GitLab). Fork repos: `glab mr` needs `--repo <upstream-project-path>`.
186+
2. Check `host` in `project-repos.json``gh` (GitHub) or `glab` (GitLab). **ALL `glab` commands MUST include `--hostname gitlab.cee.redhat.com`** — without it, glab defaults to `gitlab.com` which is blocked. Fork repos: `glab mr` needs `--repo <upstream-project-path>`.
187187
3. PR status:
188188
- GH: `gh pr view <n> --json state,mergeable,statusCheckRollup,reviewDecision,reviews,url`
189-
- GL: `glab mr view <n> --repo <upstream-project-path>`. For CI status: `glab api "projects/<url-encoded-project>/merge_requests/<n>/pipelines" --hostname gitlab.cee.redhat.com`.
189+
- GL: Use the API for full status (glab mr view lacks structured data):
190+
```
191+
glab api "projects/<url-encoded-path>/merge_requests/<n>" --hostname gitlab.cee.redhat.com
192+
```
193+
URL-encode the project path: `service/app-interface` → `service%2Fapp-interface`.
194+
Key fields in the response:
195+
- `state`: "opened", "merged", "closed"
196+
- `merge_status` / `detailed_merge_status`: "can_be_merged", "cannot_be_merged", "unchecked"
197+
- `has_conflicts`: true/false — if true, needs rebase
198+
- `head_pipeline.status`: "success", "failed", "running", "pending"
199+
- `blocking_discussions_resolved`: false = unresolved threads block merge
200+
- `draft`: true = WIP, not ready for merge
201+
202+
For CI details: `glab api "projects/<path>/merge_requests/<n>/pipelines" --hostname gitlab.cee.redhat.com`
203+
For approvals: `glab api "projects/<path>/merge_requests/<n>/approvals" --hostname gitlab.cee.redhat.com`
190204
191205
4. **Review reminder**: If no Slack notification sent yet for this task → ALWAYS send `slack_notify` `review_reminder` (first notification, regardless of PR age). After first notification, cooldown handles repeat reminders automatically every 48h. **Bot reviews don't count** — only human reviews matter. PR with only bot reviews = still needs human review → send reminder.
192206
193207
5. Handle in order:
194208
195-
**Failing CI**: `gh pr checks <n>` / `glab ci view`. Checkout branch → fix → commit → push. Comment on Jira. `task_update` `last_addressed`.
209+
**Failing CI**: `gh pr checks <n>` / `glab api "projects/<path>/merge_requests/<n>/pipelines" --hostname gitlab.cee.redhat.com`. Checkout branch → fix → commit → push. Comment on Jira. `task_update` `last_addressed`.
196210
197211
**Merge conflicts**: Rebase on default branch → resolve → force push. Jira comment. `task_update` `last_addressed`.
198212
@@ -220,7 +234,7 @@ For each `pr_open`/`pr_changes` task (check `metadata.prs` for multi-repo, else
220234
- `jira_transition_issue` → "Release Pending" (NOT "Done" — merge = stage only)
221235
- Jira comment noting merge + stage deploy
222236
- **Update linked issues**: duplicates → comment fix merged. Related → link PR. Blocked → blocker resolved.
223-
- **Delete bot branch**: GH: `gh api repos/{owner}/{repo}/git/refs/heads/bot/{KEY} -X DELETE`. GL: `glab api projects/:id/repository/branches/bot%2F{KEY} -X DELETE`. Local: `git branch -D bot/{KEY}`.
237+
- **Delete bot branch**: GH: `gh api repos/{owner}/{repo}/git/refs/heads/bot/{KEY} -X DELETE`. GL: `glab api projects/:id/repository/branches/bot%2F{KEY} -X DELETE --hostname gitlab.cee.redhat.com`. Local: `git branch -D bot/{KEY}`.
224238
- **Store learnings**: `memory_store` as `learning` + `codebase_pattern`. Set `repo` + `tags`.
225239
- `slack_notify` `release_pending`: "{KEY} merged → Release Pending. PR: {url}"
226240
@@ -236,7 +250,7 @@ project = RHCLOUD AND labels = PRIMARY_LABEL AND assignee = currentUser() AND st
236250
```
237251
238252
For each:
239-
1. **Merged PRs?** `gh pr list --head bot/<KEY> --state merged` / `glab mr list --source-branch bot/<KEY> --merged`. If merged → transition "Release Pending", Jira comment, `task_update` archived, `memory_store`.
253+
1. **Merged PRs?** `gh pr list --head bot/<KEY> --state merged` / `glab mr list --source-branch bot/<KEY> --merged --hostname gitlab.cee.redhat.com`. If merged → transition "Release Pending", Jira comment, `task_update` archived, `memory_store`.
240254
2. **New Jira comments?** `jira_get_issue` → check for unaddressed comments since `last_addressed`. Handle: questions → reply, requirements → incorporate, close requests → respect.
241255
3. PR still open, no comments → skip (Priority 1 handles).
242256
@@ -315,7 +329,7 @@ Before starting work, `jira_get_issue` → check issue links:
315329

316330
Dir = `./repos/<repo-name>/` (from upstream URL basename, no `.git`).
317331

318-
**Clone on demand**: Not exists → `git clone --depth 1 <url> ./repos/<name>/`. Has upstream → `git remote add upstream <upstream-url>`. Clone fails → Jira comment, stop. Start shallow (`--depth 1`), deepen incrementally if needed (`git fetch --deepen=50`). Never clone full history upfront.
332+
**Clone on demand**: Not exists → `git clone --depth 1 --single-branch <url> ./repos/<name>/`. Has upstream → `git remote add upstream <upstream-url>`. If more history needed → `git fetch --deepen=50` or `git fetch --unshallow`. Clone fails → Jira comment, stop.
319333

320334
**Verify remotes**: Exists → `git remote -v`. Origin must match `url`. Upstream remote must match `upstream` field. Fix w/ `set-url`/`add` as needed.
321335

@@ -324,6 +338,12 @@ Before starting work, `jira_get_issue` → check issue links:
324338
- Direct: `git fetch origin` → checkout default branch → pull
325339
- Branch: `bot/<TICKET-KEY>`
326340

341+
**Fresh start (retry/redo)**: When retrying failed work, always start clean:
342+
1. Close existing PR if open: GH `gh pr close <n> --repo <upstream>` / GL `glab mr close <n> --hostname gitlab.cee.redhat.com`
343+
2. Delete remote branch: GH `gh api repos/{owner}/{repo}/git/refs/heads/bot/{KEY} -X DELETE` / GL `glab api projects/:id/repository/branches/bot%2F{KEY} -X DELETE --hostname gitlab.cee.redhat.com`
344+
3. Delete local branch: `git branch -D bot/<KEY>`
345+
4. Re-create branch from updated default branch and re-implement
346+
327347
**Git identity**: Global config is set by `run.py` at startup (name, email, GPG signing). Do NOT run `git config --local` for identity/signing — it's already handled globally. Do NOT check `GPG_SIGNING_KEY` env var (it's sanitized at startup).
328348

329349
Readonly: `git fetch origin` + pull. Read only.
@@ -366,8 +386,8 @@ Before starting work, `jira_get_issue` → check issue links:
366386
GH direct: `gh pr create --title "..." --body "..."`
367387
Push fails → `last_step = "push_failed"`, Jira comment, keep `in_progress` for retry.
368388

369-
GL fork: `glab mr create --repo <upstream-path> --title "..." --description "..."`
370-
GL direct: `glab mr create --title "..." --description "..."`
389+
GL fork: `glab mr create --repo <upstream-path> --hostname gitlab.cee.redhat.com --title "..." --description "..."`
390+
GL direct: `glab mr create --hostname gitlab.cee.redhat.com --title "..." --description "..."`
371391

372392
Title ≤50 chars. Body = ticket key + changes summary.
373393
Readonly repos: include config changes in Jira comment.

Dockerfile

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,12 @@ RUN ARCH=$(uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/') \
7676
&& curl -fsSL "https://github.com/cli/cli/releases/download/v2.67.0/gh_2.67.0_linux_${ARCH}.tar.gz" \
7777
| tar -xz -C /usr/local --strip-components=1
7878

79-
# glab CLI
79+
# glab CLI — download then extract (no pipe, so curl failures are caught)
8080
RUN ARCH=$(uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/') \
81-
&& curl -fsSL "https://gitlab.com/gitlab-org/cli/-/releases/v1.51.0/downloads/glab_1.51.0_linux_${ARCH}.tar.gz" \
82-
| tar -xz -C /usr/local/bin --strip-components=2 bin/glab
81+
&& curl -fSL -o /tmp/glab.tar.gz "https://gitlab.com/gitlab-org/cli/-/releases/v1.51.0/downloads/glab_1.51.0_linux_${ARCH}.tar.gz" \
82+
&& tar -xzf /tmp/glab.tar.gz -C /usr/local/bin --strip-components=1 bin/glab \
83+
&& rm /tmp/glab.tar.gz \
84+
&& glab version
8385

8486
# bubblewrap (sandbox runtime for Claude Code)
8587
RUN dnf install -y --nodocs libcap-devel \
@@ -151,6 +153,7 @@ RUN ssh-keyscan -t ed25519,rsa,ecdsa github.com >> /home/botuser/.ssh/known_host
151153
# Git config
152154
RUN git config --global user.name "platex-rehor-bot" \
153155
&& git config --global user.email "platform-experience-services@redhat.com" \
156+
&& git config --global http.https://gitlab.cee.redhat.com.sslVerify false \
154157
&& git config --global gpg.format openpgp \
155158
&& git config --global commit.gpgsign true
156159

entrypoint.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@
22
# Bot container entrypoint — decode secrets, start Chromium, launch bot.
33
set -e
44

5+
# --- Verify required CLI tools ---
6+
MISSING=""
7+
for tool in gh glab git gpg; do
8+
if ! command -v "$tool" &>/dev/null; then
9+
MISSING="$MISSING $tool"
10+
fi
11+
done
12+
if [ -n "$MISSING" ]; then
13+
echo "FATAL: Missing required tools:$MISSING" >&2
14+
echo "Rebuild with: docker compose build --no-cache bot" >&2
15+
exit 1
16+
fi
17+
518
# Kubernetes secretKeyRef auto-decodes base64, so secrets arrive as raw values
619
# in OpenShift. Local docker-compose still passes them base64-encoded via .env.
720
# This helper handles both: values starting with "-----" or "{" are not valid
@@ -87,15 +100,27 @@ if [ -n "${GITLAB_TOKEN:-}" ]; then
87100
mkdir -p ~/.config/glab-cli
88101
cat > ~/.config/glab-cli/config.yml <<EOF
89102
git_protocol: ssh
103+
check_update: false
104+
no_prompt: true
105+
host: gitlab.cee.redhat.com
90106
hosts:
91107
gitlab.cee.redhat.com:
92108
token: ${GITLAB_TOKEN}
109+
api_protocol: https
93110
api_host: gitlab.cee.redhat.com
94111
git_protocol: ssh
112+
skip_tls_verify: true
95113
EOF
114+
chmod 600 ~/.config/glab-cli/config.yml
96115
unset GITLAB_TOKEN
97116
fi
98117

118+
# --- Verify auth ---
119+
echo "Verifying GitHub auth..."
120+
gh auth status 2>&1 | head -3 || { echo "WARNING: gh auth failed"; }
121+
echo "Verifying GitLab auth..."
122+
glab auth status --hostname gitlab.cee.redhat.com 2>&1 | head -3 || { echo "WARNING: glab auth failed"; }
123+
99124
# Start headless Chromium in background (Playwright-installed binary)
100125
CHROME_BIN=$(find "$PLAYWRIGHT_BROWSERS_PATH" -name chrome -type f | head -1)
101126
"$CHROME_BIN" \

0 commit comments

Comments
 (0)