--- name: analyze-ci-failure description: Use to check GitHub Actions build status or diagnose why a workflow run failed and propose a fix. Triggered by phrases like "check the latest build", "did CI pass", "why did the build fail", "check the GitHub Actions run", "analyze this workflow run", "check run ", "check the build for this PR". --- # Skill: Analyze a GitHub Actions Run and Propose a Fix > Uses the `gh` CLI (already authenticated) to inspect workflow runs on GitHub Actions, isolate the actual failing step from a noisy log, and turn it into a root cause + a proposed fix. ## Workflows in this repo They live at `.github/workflows/`. | File | Name | Trigger | What it runs | |---|---|---|---| | `.github/workflows/ci.yml` | `Continuous integration` | Push to or pull request against `develop` | Parallel `verify` and `build-apk` jobs; `distribute` on pushes after both pass | | `.github/workflows/release.yml` | `Release` | Push of a semantic version tag (`X.Y.Z`) | Parallel `verify` and `build-release` jobs; GitHub Release, Play Store beta, and Firebase App Distribution publish after both pass | | `.github/workflows/agent-context.yml` | `Agent context` | Context, skill, adapter, root-build, or module-graph changes against `develop` | `validate`: `validateAgentContext` | ## Step 1 — Find the run | Given | Command | |---|---| | "latest build" / "latest CI run" | `gh run list --workflow ci.yml --limit 5` | | "latest release run" | `gh run list --workflow release.yml --limit 5` | | "latest context check" | `gh run list --workflow agent-context.yml --limit 5` | | A run ID or run URL | `gh run view ` | | A PR number | `gh pr checks ` | | Only failures | `gh run list --status failure --limit 10` | ## Step 2 — Check job-level status, not just the run-level conclusion `gh run view ` prints a ✓/X per job — read this before pulling logs. The Android workflows have parallel verification and artifact-build jobs followed by downstream distribution jobs. The release workflow also has Play Store and GitHub Release jobs. Confirm the failed job and its dependencies before assuming the cause; a downstream artifact failure may still originate in `build-apk` or `build-release`. ## Step 3 — Pull only the failing job's log, then filter for the signal On macOS/Linux: ```bash gh run view --log-failed | grep -inE "error:|FAILURE:|Execution failed|exception|##\[error\]" ``` ```bash gh run view --log-failed | sed -n ',p' ``` On Windows PowerShell: ```powershell gh run view --log-failed | Select-String -Pattern 'error:|FAILURE:|Execution failed|exception|##\[error\]' ` -CaseSensitive:$false ` -Context 5, 15 ``` If filtering finds nothing useful, the failure may be a plain `BUILD FAILED` with no separate `error:` line — in that case find the last `> Task :...` line before the failure; that's the failing Gradle task. ## Step 4 — Known failure signatures in this repo | Symptom in the log | Root cause | Fix | |---|---|---| | `Agent context validation failed` | A module lacks scoped guidance, an `AGENTS.md`/`CLAUDE.md` pair is broken, skill metadata is invalid, a local context link is broken, or a Copilot adapter duplicates a shared skill | Follow each listed validation error, then rerun `./gradlew validateAgentContext` | | `BUILD FAILED` with ktlint-style messages or Compose compile errors traceable to formatting | Unformatted/violating Kotlin broke compilation | Use the `spotless-fix` skill | | `e: file:///path/to/File.kt:12:5 ...` | Kotlin compiler error, points directly at file:line | Open the file, fix per `AGENTS.md` conventions | | `Fetch Firebase google-services.json` fails in either workflow | `FIREBASE_TOKEN`, `FIREBASE_APP_ID`, or `FIREBASE_PROJECT_ID` is missing/wrong, or the token cannot access the configured Firebase project/app | Use `gh secret list` to confirm all three exist. Secret values are masked and Firebase access cannot be repaired from logs; report the exact Firebase CLI error to the user | | Signing step fails in `release.yml` (`sign_aab` or `sign_apk`) | One of `SIGN_KEY`, `SIGN_KEY_ALIAS`, `SIGN_KEY_STORE_PASSWORD`, `SIGN_KEY_PASSWORD` repo secrets is missing/wrong, or the keystore is corrupt/mismatched with the alias | `gh secret list` to confirm all four exist; can't verify the keystore itself from CI logs — ask the user to check it locally | | `Deploy to Play Store` step fails with an auth/permission error | `GOOGLE_SERVICE_ACCOUNT` secret is missing, expired, or the service account lacks Play Console API access for `sk.styk.martin.apkanalyzer` | Check `gh secret list`; Play Console access itself can't be fixed from CI — flag to the user | | `Distribute APK to Firebase App Distribution` fails after a successful build | `FIREBASE_TOKEN`/`FIREBASE_APP_ID` is wrong, the token lacks access, or the `internal-testers` group is unavailable | Confirm both secrets exist with `gh secret list`, then report the Firebase CLI error; project permissions and tester groups require user access | | A future JDK bump to the Gradle toolchain (`jvmToolchain(N)`, `gradle-daemon-jvm.properties`) isn't mirrored in one of the two workflows' `setup-java` step | **Usually not the actual failure cause even if they briefly drift** — `gradle-daemon-jvm.properties` has `toolchainUrl.*` entries for the foojay Disco API, so Gradle auto-downloads a matching JDK regardless of the JDK `setup-java` installed (needs the `org.gradle.toolchains.foojay-resolver-convention` plugin in `settings.gradle.kts`, which is applied). Don't assume a JDK mismatch is the root cause without other evidence | If you do suspect it, search the log for `Downloading` / `Unpacking JDK` lines from the toolchain auto-provisioning, or a `No matching toolchains found` error, before concluding this is the cause | | `gradle: Execution failed for task ':...:compileDebugKotlin'` or similar per-module compile task | Compile error scoped to one module | Narrow reproduction locally: `./gradlew :module:path:compileDebugKotlin` | If a failure doesn't match this table, treat the filtered `error:`/`FAILURE:` line as authoritative and reason from there — don't guess. ## Step 5 — Reproduce and propose a fix 1. Where possible, reproduce locally with the same Gradle task the workflow ran (see `run:` steps in the workflow YAML) before proposing a fix — this repo's CI failures are almost always reproducible with `./gradlew `. 2. State the root cause in one sentence, citing the exact log line. 3. Propose a minimal diff: - Workflow YAML bug → confirm with the user before editing `.github/workflows/*.yml` (CI/CD pipeline changes are a shared-system change — don't push them unasked). - Application/build code bug → fix the code per `AGENTS.md` conventions and run the `spotless-fix` skill if it's formatting-related. 4. **Never "fix" a failure by hiding it** — no removing the failing step, no `continue-on-error: true`, no `|| true`, no disabling a check — unless the user explicitly asks for that. The goal is root cause, not a green checkmark. ## Verification - [ ] Identified the specific failing step (not just "the run failed") - [ ] Found the actual `error:`/`FAILURE:` line, not just generic exit-code noise - [ ] Root cause stated as one sentence with a cited log line - [ ] Fix reproduces/resolves locally where the failure type allows it (e.g. a Gradle task) - [ ] Fix addresses the cause, not just silences the check