518c40be21
CI / build (pull_request) Successful in 39s
CI / helm (pull_request) Successful in 24s
CI / lint (pull_request) Successful in 1m3s
CI / push-validation (pull_request) Successful in 38s
CI / typecheck (pull_request) Successful in 1m17s
CI / quality (pull_request) Successful in 1m37s
CI / security (pull_request) Successful in 1m49s
CI / unit_tests (pull_request) Successful in 8m23s
CI / docker (pull_request) Successful in 1m41s
CI / integration_tests (pull_request) Successful in 25m16s
CI / coverage (pull_request) Successful in 14m28s
CI / status-check (pull_request) Successful in 3s
- add changelog entries summarizing watchdog supervision and documentation updates\n- add ci-log-fetcher module guide detailing interface contract and usage\n- refresh system-watchdog doc with CI-blocker escalation and struggling PR detection\n- normalize coverage threshold robot test by dropping temporary tdd_expected_fail tags\n\nISSUES CLOSED: #7987
188 lines
6.0 KiB
Markdown
188 lines
6.0 KiB
Markdown
# CI Log Fetcher
|
||
|
||
**Agent:** `ci-log-fetcher`
|
||
**Location:** `.opencode/agents/ci-log-fetcher.md`
|
||
|
||
The `ci-log-fetcher` agent retrieves CI job logs from Forgejo Actions using
|
||
web authentication. It is a **read-only utility agent** used by all PR-related
|
||
agents to access CI failure details without manual web scraping.
|
||
|
||
> **Key rule:** Callers **must not** pass `forgejo_username` or
|
||
> `forgejo_password` parameters. The agent reads `FORGEJO_USERNAME` and
|
||
> `FORGEJO_PASSWORD` from environment variables automatically.
|
||
|
||
---
|
||
|
||
## Purpose
|
||
|
||
When a PR has failing CI, agents need to read the raw log output to understand
|
||
what went wrong. The Forgejo Actions API does not expose logs in a
|
||
machine-readable way that is easy to parse, so `ci-log-fetcher` handles the
|
||
authentication and log retrieval workflow, returning the raw log text to the
|
||
caller.
|
||
|
||
---
|
||
|
||
## Usage
|
||
|
||
```yaml
|
||
# In an agent definition — grant permission to call ci-log-fetcher
|
||
permissions:
|
||
- ci-log-fetcher
|
||
```
|
||
|
||
```
|
||
# In agent prompt / instructions
|
||
To get CI logs for PR #1234, job "unit-tests":
|
||
Use the ci-log-fetcher subagent with:
|
||
pr_number: 1234
|
||
job_name: unit-tests
|
||
repository: cleveragents/cleveragents-core
|
||
|
||
DO NOT pass forgejo_username or forgejo_password — the agent
|
||
handles credentials automatically from environment variables.
|
||
```
|
||
|
||
### Parameters
|
||
|
||
| Parameter | Required | Description |
|
||
|-----------|----------|-------------|
|
||
| `pr_number` | Yes | The PR number to fetch logs for |
|
||
| `job_name` | Yes | The CI job name (e.g. `unit-tests`, `integration-tests`) |
|
||
| `repository` | Yes | `owner/repo` format (e.g. `cleveragents/cleveragents-core`) |
|
||
|
||
### Common job names
|
||
|
||
| Job | `job_name` value |
|
||
|-----|-----------------|
|
||
| Unit tests | `unit-tests` or `unit_tests` |
|
||
| Integration tests | `integration-tests` or `integration_tests` |
|
||
| Lint | `lint` |
|
||
| Typecheck | `typecheck` |
|
||
| Security scan | `security-scan` or `security_scan` |
|
||
| Coverage | `coverage` |
|
||
|
||
The agent normalises job names (converts `-` to `_` and vice versa) when
|
||
looking up the job in the PR's check runs.
|
||
|
||
---
|
||
|
||
## Optimised Workflow
|
||
|
||
The agent follows a tested, optimised workflow that minimises execution time
|
||
(~5 seconds vs. ~30 seconds for naive approaches):
|
||
|
||
```
|
||
1. Load PR page: GET /cleveragents/cleveragents-core/pulls/{pr_number}
|
||
→ Extracts all CI check run links directly from the page HTML.
|
||
→ No separate API calls needed to find job IDs.
|
||
|
||
2. Find the matching job link by normalised job name.
|
||
|
||
3. Fetch logs: GET /actions/runs/{run_id}/jobs/{job_id}/attempt/{attempt}/logs
|
||
→ Uses attempt=1 on first try (correct ~95% of the time).
|
||
→ Falls back to attempt=2 if 404.
|
||
|
||
4. Return raw log text to caller.
|
||
```
|
||
|
||
**What the agent does NOT do (saves time):**
|
||
- Does not call `/api/v1/repos/.../actions/runs` (always returns 404 for logs)
|
||
- Does not look up CSRF tokens (Forgejo login does not use them)
|
||
- Does not make multiple API calls to discover job IDs
|
||
|
||
---
|
||
|
||
## Authentication
|
||
|
||
The agent uses **web session authentication** (not the Forgejo API token):
|
||
|
||
1. `POST https://git.cleverthis.com/user/login` with `FORGEJO_USERNAME` and
|
||
`FORGEJO_PASSWORD` to obtain a session cookie.
|
||
2. All subsequent requests use the session cookie.
|
||
|
||
This is necessary because the Actions log endpoint requires a web session,
|
||
not a PAT token.
|
||
|
||
**Environment variables used:**
|
||
- `FORGEJO_USERNAME` — Forgejo username (e.g. `HAL9000`)
|
||
- `FORGEJO_PASSWORD` — Forgejo password
|
||
|
||
Both variables are pre-configured in the build environment. Callers do not
|
||
need to provide them.
|
||
|
||
---
|
||
|
||
## Output Format
|
||
|
||
The agent returns the **raw log text** directly — not a JSON wrapper. The
|
||
caller receives the full stdout/stderr of the CI job, which can then be
|
||
parsed for error messages, test failures, etc.
|
||
|
||
Example output:
|
||
```
|
||
2026-04-08T10:23:45Z ##[group]Run nox -s unit_tests
|
||
2026-04-08T10:23:45Z + nox -s unit_tests
|
||
...
|
||
2026-04-08T10:24:12Z FAILED features/session.feature:45 — AssertionError
|
||
2026-04-08T10:24:12Z 1 feature passed, 0 failed, 1 error
|
||
```
|
||
|
||
---
|
||
|
||
## Agents That Use ci-log-fetcher
|
||
|
||
All PR-related agents call `ci-log-fetcher` instead of implementing their own
|
||
CI log retrieval:
|
||
|
||
| Agent | When it calls ci-log-fetcher |
|
||
|-------|------------------------------|
|
||
| `pr-checker` | After CI fails on a PR being monitored |
|
||
| `implementation-worker` | In `pr-fix` mode, to understand CI failures |
|
||
| `pr-fix-orchestrator` | To analyse failures before dispatching fix workers |
|
||
| `pr-self-reviewer` | To check CI status before reviewing |
|
||
| `human-liaison` | When responding to PR comments about CI failures |
|
||
| `pr-status-checker` | When `include_logs=true` is requested |
|
||
| `system-watchdog` | In Audit 9 (test health) for emergency test-skip response |
|
||
|
||
---
|
||
|
||
## Performance Notes
|
||
|
||
| Metric | Value |
|
||
|--------|-------|
|
||
| Typical execution time | ~5 seconds |
|
||
| Previous execution time (before optimisation) | ~30 seconds |
|
||
| Improvement | ~85% reduction |
|
||
|
||
The main savings come from:
|
||
- Parsing job links from the PR page (1 request) instead of multi-step API
|
||
lookups (4–6 requests)
|
||
- Skipping CSRF token lookup (saves ~2 s)
|
||
- Using the correct log endpoint pattern on the first attempt (saves retries)
|
||
|
||
---
|
||
|
||
## Troubleshooting
|
||
|
||
**"Job not found" error:**
|
||
- Check that `job_name` matches one of the job names in the PR's check runs.
|
||
- Try both hyphenated and underscored variants (e.g. `unit-tests` vs `unit_tests`).
|
||
- The agent normalises names, but the PR page must have a matching check run.
|
||
|
||
**"Authentication failed" error:**
|
||
- Verify `FORGEJO_USERNAME` and `FORGEJO_PASSWORD` are set in the environment.
|
||
- The agent will log which credential source it is using (env vars vs parameters).
|
||
|
||
**Empty log output:**
|
||
- The job may not have produced any output (e.g. it was skipped or cancelled).
|
||
- Try fetching a different attempt number by checking the PR page manually.
|
||
|
||
---
|
||
|
||
## Related Documentation
|
||
|
||
- [CI/CD Pipeline](../development/ci-cd.md) — pipeline architecture
|
||
- [System Watchdog](../development/system-watchdog.md) — uses ci-log-fetcher for emergency test-skip
|
||
- [Quality Automation](../development/quality-automation.md) — CI quality gates
|