AI & ML
Building explain-ci: The AI Was the Smallest Part
Gopal C Nepal Dev.to (EN Zone)
3 views
CI goes red. Before I can think about the actual fix, I'm expanding the
failing job and scrolling through three hundred lines of dependency resolution to
find the one line that matters. Then the next person on the repo does the
same thing, from scratch.
So I built explain-ci: a GitHub
Action that reads the failed job's log and posts a plain-English explanation
as a PR comment. By the time anyone opens the PR, it's already there.
That's a real run. Here's what CI printed:
E AssertionError: assert [] == ['washers']
E Right contains one more item: 'washers'
And what the comment said: the function used < where it needed <=, so
items sitting exactly on the threshold were skipped. The traceback tells you
the assertion failed. It never tells you why. The model worked that out from
the log alone — it never saw the source file.
The AI part is about fifteen lines
I expected this to be the interesting bit. It isn't.
GitHub's job logs carry structure markers — ##[group], ##[endgroup],
##[error]. Find the first error, walk backwards to see which step was
running, slice the log into three sections. That's plain string handling, no
model involved. Then those sections go to the provider with a short prompt
asking for two things: root cause and suggested fix.
That's the whole feature. One API call and some parsing.
The one decision worth anything is what you don't send. Not the whole log —
each section is capped, and the cap keeps the tail, because errors cluster
at the end while the top is setup noise. That holds whether the job printed
200 lines or 200,000.
The rest is manners
Everything that took real time was about making the thing well-behaved enough
that you'd leave it installed.
It must never fail your pipeline. An action that explains failures has no
business causing one. If the GitHub API hiccups or the provider returns a 500,
it emits a warning and exits 0. Your build status should reflect your build,
not my action's bad day.
It edits its own comment. Re-run a failing job four times and you don't
want four bot comments. Each one carries a hidden marker, so a re-run finds
the previous comment and updates it in place.
Only the newest run comments. Scoped per workflow — a repo with five
workflows shouldn't get five explanations.
Credentials get scrubbed first. Log text goes to a third party. GitHub
masks the secrets it registered, but tokens minted or echoed during a job —
an OIDC session key, a git remote carrying a password, a verbose curl
dumping its auth header — reach the log unmasked. So they're stripped before
anything leaves the runner.
None of that is AI work. All of it is the difference between a demo and
something you'd actually install.
Two bugs worth admitting
The stale-run check was supposed to stop old runs commenting on new commits.
It queried the endpoint that returns runs from every workflow in the repo,
so if any other workflow had run more recently, the current run decided it was
stale and said nothing. In a single-workflow repo it looked fine. In a real
one it silently did nothing.
The second is more interesting, because I caused it while fixing something
else. My first pass at secret redaction flagged any long run of characters as
a possible key. Deep file paths match that trivially:
/home/runner/work/myorg/myproject/src/main/java/com/example/Service.java
-> /[REDACTED].java
It over-redacted rather than leaked, so nothing was exposed — but it removed
the failing file path, which is exactly the context the model needs. My tests
missed it because every path I'd invented happened to contain dots and
underscores, which break the match. A real path didn't.
Both bugs have the same shape: the code was tested against what I imagined the
input looked like, not against a real one.
Try it
explain-failure:
needs: test
if: always()
runs-on: ubuntu-latest
steps:
- uses: gopalcnepal/explain-ci@v1
with:
api_key: ${{ secrets.OPENAI_API_KEY }}
It has to be its own job — the failed job's log isn't queryable through the
API until that job has finished.
Bring your own key. It speaks the OpenAI-compatible API, so OpenAI, Gemini,
Claude, Groq, Mistral and friends all work, and base_url points it at a
self-hosted Ollama if your logs can't leave your network.
Marketplace
Source
A live demo PR — real bot comment, not a mockup
It's free and MIT. If you try it and it gets something wrong, I'd like to hear
about it.
Read original: https://dev.to/gopalcnepal/building-explain-ci-the-ai-was-the-smallest-part-1n2h
← Previous
My First Deep Dive Into Solana: Why High-Performance Blockchains Need a Different Design
Next →
Why a WPF ScrollViewer Does Not Scroll and How to Fix It
Related
AI: Find your way
AI & ML
1
DEV Community
Coxon resigned over a race. Governance is about the next action.
AI & ML
2
Dev.to (EN Zone)
Hello DEV! 👋 I’m Sunny — Exploring AI/ML, Development & Open Source
AI & ML
3
Dev.to (EN Zone)
Agentic AI Credential Harvesting: An Attack Built in Under Six Hours and the Separate Recon Case
AI & ML
5
DEV Community
Comments0
No comments yet — be the first