# 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