Operate and improve CI/CD
Make failures actionable
Use summaries, annotations, logs, artifacts, and ownership so a red run explains the next step.
A red CI run should answer three questions: what failed, where is the evidence, and who fixes it.
If the log is ten thousand lines of npm warnings and one buried assertion, people rerun the job and hope. That erodes trust fast. Soon everyone ignores red checks, and real regressions slip through.
Noise is a design choice. You can trim verbose install output, fail fast on the first test failure, and upload the detailed report as an artifact instead of printing it twice.
Write a job summary
GitHub Actions supports a job summary markdown file:
- name: Test
id: test
run: npm test
- name: Summary on failure
if: failure()
run: |
{
echo "## CI failed"
echo ""
echo "- Failed job: test"
echo "- Commit: ${{ github.sha }}"
echo "- Owner: @platform-team"
echo "- Runbook: docs/ci-failures.md"
} >> "$GITHUB_STEP_SUMMARY"
The summary appears at the top of the run page. No scrolling through raw logs.
Surface the first useful error
Configure test runners to print concise failure output. Upload junit or HTML reports as artifacts.
Use workflow commands for inline annotations when tools support them:
- run: echo "::error file=src/app.ts,line=10::Expected 200, got 500"
That links the message to a file in the pull request diff view.
Assign ownership
Name a team or runbook in the summary. “Platform on-call” beats “someone should look at CI”.
State clearly whether deployment happened. A failed smoke test after deploy is different from a failed unit test before deploy. The summary should say “production not reached” when that is true.
Give another developer only the workflow URL. Ask them to diagnose three induced failures (lint, test, deploy smoke). They should reach the right fix without you on the call.
Try this on your own project: add one $GITHUB_STEP_SUMMARY block and one artifact upload on failure.
Lesson completed