Chapter 19Lesson 04~140 minutes

CI Integration with GitHub Actions, GitLab CI, Jenkins, and Other Runners: Diagnostics, Failure Modes, and Production Practices

Diagnose secret leaks, missing reports, lost logs, shallow checkout, action drift, analysis races, and job/gate-state confusion without hiding the first failure.

CI/CDGitHub ActionsGitLab CIJenkinsQuality Gate

Learning objectives

  • Use an evidence-first diagnostic sequence that preserves CI, scanner, server, gate, and provider evidence before correction.
  • Diagnose tokens committed to YAML, reports generated after scanning, shallow checkout, missing retained logs, and stale task metadata.
  • Recognize action/plugin version drift and replace floating references with reviewed immutable revisions.
  • Prevent same-project analysis races without inventing new project keys or deleting history.
  • Separate scanner/build/report failures from network/auth, Compute Engine, project policy, provider/CI, resource, and edition layers.
  • Repair a deliberately broken pipeline-order example while proving that the source revision stays constant.

1. Evidence-first diagnostic sequence

  1. Preserve CI job logs, checkout SHA/depth, build/test logs, report files, scanner log, and .scannerwork/report-task.txt.
  2. Record SonarQube edition/version, scanner/action/plugin/runtime versions, runner image, and build/test producer versions.
  3. Confirm exact source revision, workspace/base directory, effective analysis parameters, and report paths.
  4. Confirm scanner indexing/report upload and preserve ceTaskId.
  5. Inspect Compute Engine task status/error before rerunning.
  6. Inspect project profile/gate/New Code/security state and only then the Quality Gate result.
  7. Inspect CI/provider secret/network/status state if the server result is healthy but orchestration failed.
  8. Inspect database/search/JVM/host/container only when evidence points to server infrastructure.
  9. Apply the smallest correction and rerun the same revision/scenario where possible.

2. Failure: token stored literally in YAML

# BAD — credential becomes repository/history data.
env:
  SONAR_TOKEN: FAKE_SONAR_TOKEN_DO_NOT_USE

The correct response is not merely to replace the line in the latest commit. If a real credential was committed, revoke/rotate it immediately, preserve the incident trail, assess repository/history exposure, and move the replacement into the provider secret store. In this course, the string above is intentionally fake and nonfunctional.

Do not rewrite history casually. Rotation is the security control. History cleanup may be useful for reducing accidental exposure but must be planned with repository owners; it does not make a leaked credential secret again.

3. Intentionally broken example: scan before coverage exists

This failure is ideal for causal diagnosis because the source revision, profile, gate, and token can remain constant. Only pipeline order changes.

rm -f coverage.xml
mkdir -p evidence/broken-order

# BROKEN: scanner is told to import coverage.xml before the producer creates it.
set +e
sonar-scanner -X 2>&1 | tee evidence/broken-order/scanner.log
BROKEN_SCAN_RC=${PIPESTATUS[0]}
set -e
cp .scannerwork/report-task.txt evidence/broken-order/report-task.txt 2>/dev/null || true

# Too late: this report was not part of the already-uploaded analysis.
python -m pytest -q --cov=src --cov-report=xml:coverage.xml \
  2>&1 | tee evidence/broken-order/test-after-scan.log

git rev-parse HEAD | tee evidence/broken-order/revision.txt
printf 'broken_scanner_exit=%s\n' "$BROKEN_SCAN_RC" \
  | tee evidence/broken-order/final-state.txt

Interpret the scanner log. Expect evidence that the configured coverage path could not be imported or no coverage report was found. Even if the scanner exits successfully and coverage.xml exists by the end of the job, the SonarQube analysis cannot have consumed a file that did not exist when the scanner built its report.

4. Repair the order without gaming scope or policy

mkdir -p evidence/repaired-order
rm -rf .scannerwork coverage.xml

# Same Git revision; correct only the pipeline order.
git rev-parse HEAD | tee evidence/repaired-order/revision.txt

python -m pytest -q \
  --cov=src --cov-report=xml:coverage.xml \
  2>&1 | tee evidence/repaired-order/test.log
test -s coverage.xml

sonar-scanner -X 2>&1 | tee evidence/repaired-order/scanner.log
cp .scannerwork/report-task.txt evidence/repaired-order/report-task.txt
sed -n 's/^ceTaskId=/ceTaskId=/p' .scannerwork/report-task.txt \
  | tee evidence/repaired-order/ce-task-id.txt

The repair is valid because it does not exclude uncovered files, lower a gate, deactivate coverage, change the project key, or delete history. It changes only when a required report is created.

5. Failure: shallow checkout breaks SCM context

Current Sonar guidance for GitHub and GitLab recommends disabling shallow clone. Diagnose it with Git—not with the SonarQube database:

git rev-parse --is-shallow-repository
git log --oneline --decorate -5

# Provider repair examples:
# GitHub: checkout with fetch-depth: 0
# GitLab: GIT_DEPTH: "0"

Do not disable SCM attribution merely to suppress blame/ref warnings. Restore the required history and rerun the smallest equivalent job.

6. Failure: the job fails and the evidence disappears with the runner

Ephemeral runners are valuable for clean state, but they make artifact retention mandatory. A job that says only “failed” after its workspace vanished cannot distinguish test failure, scanner failure, Compute Engine failure, or gate failure.

  • GitHub: use an if: always() artifact step.
  • GitLab: use artifacts: when: always.
  • Jenkins: use post { always { archiveArtifacts ... } }.
  • Generic CI: copy logs/reports/task metadata to the platform artifact store before teardown.

Never delete logs/cache before preservation as a troubleshooting habit.

7. Failure: floating or unreviewed action/plugin revision

# BAD: code can change without a workflow review.
- uses: some-org/some-sonar-wrapper@main

# Better: reviewed publisher and immutable commit, with release annotation.
- uses: SonarSource/sonarqube-scan-action@22918119ff8e1ca75a623e15c8296b6ea4fbe28f # v8.2.1

Version drift is not only a security risk. Scanner action upgrades can change bundled Scanner CLI/JRE behavior, argument parsing, required runner utilities, signature verification, and cache behavior. Record the resolved revision in the evidence packet.

8. Failure: parallel jobs race analyses for one project/revision

Suppose Linux, Windows, and macOS jobs all submit the same project key and commit. You now have multiple server tasks, possibly different report populations, and no simple rule for which dashboard state represents the canonical build. The repair is orchestration:

  • Choose one canonical analysis job.
  • Make it depend on the required matrix tests.
  • Merge only supported report formats with proven provenance.
  • Use provider concurrency/resource-group controls when duplicate runs must be prevented.
  • Do not solve the race by creating a new SonarQube project key per runner.

9. Failure: “job success means gate pass”

A direct scanner invocation without gate waiting can exit successfully after upload. If the pipeline then ends, the job can be green while Compute Engine is still processing or while the gate later fails. Repair by choosing an explicit enforcement contract:

  • GitHub: Quality Gate Check Action or explicit scanner wait.
  • GitLab/generic runner: sonar.qualitygate.wait=true.
  • Jenkins: waitForQualityGate with the mandatory webhook.

Record the gate result and CI exit independently. Do not retroactively claim the scanner failed simply because the gate did.

10. Causal failure map

Evidence Likely layer Least-destructive next step
Tests fail before scan Build/test Preserve test output; do not scan stale previous artifacts.
Coverage path warning Producer/order/path Prove report exists before scan in same workspace.
Scanner 401/403 Sonar auth/permission Check project token validity/scope; do not use admin token.
Upload succeeds; CE task FAILED Compute Engine/server processing Preserve CE task/error and server logs.
CE SUCCESS; gate ERROR Project policy/result Inspect exact condition/metric; do not lower threshold as troubleshooting.
Gate PASS; CI status failed CI/orchestration/artifact/provider Inspect downstream step, artifact upload, webhook/action status.
SCM warnings Checkout history Restore full-enough Git history.
Different scanner behavior after action update Integration/tool version Compare resolved action/scanner versions and release notes.

11. Production anti-patterns to reject

  • Do not commit or echo tokens.
  • Do not disable TLS verification to solve runner certificate problems; establish the correct CA trust.
  • Do not use global/admin tokens everywhere.
  • Do not run tests after the scan when their reports are analysis inputs.
  • Do not hide a failing gate by lowering policy thresholds or suppressing issues.
  • Do not clear logs/caches before preserving first failure.
  • Do not reuse a stale report-task.txt from cache.
  • Do not replace a failed analysis with a new project key.
  • Do not restart SonarQube blindly when the failure is clearly runner-side.

Knowledge check

The job created coverage.xml, but only after the scanner step. Can a final artifact upload repair the SonarQube coverage?

A scanner gets HTTP 401. Should you generate an administrator token?

Why archive report-task.txt?

What should replace three matrix jobs all scanning the same key/revision?

A Quality Gate passes but artifact upload fails, making the CI job red. Is SonarQube wrong?

Next lesson

Produce the Chapter 19 CI evidence packet

Lesson 5 combines the launcher, pipeline, deliberate ordering defect, gate enforcement, artifacts, and cleanup into one governed checkpoint.

Official references and version notes

Version and compatibility note

Rechecked 2026-09-08. Mandatory labs target SonarQube Community Build 26.9.0.129388 and SonarScanner CLI 8.1.0.6389. The GitHub example pins SonarQube Scan Action v8.2.1 to commit 22918119ff8e1ca75a623e15c8296b6ea4fbe28f, Quality Gate Check Action v1.2.0 to cf038b0e0cdecfa9e56c198bbb7d21d751d62c3b, checkout v6.1.0 to d23441a48e516b6c34aea4fa41551a30e30af803, setup-python v6.2.0 to a309ff8b426b58ec0e2a45f0f869d46889d02405, and upload-artifact v4.6.2 to ea165f8d65b6e75b540449e92b4886f43607fa02. Current SonarSource Community Build guidance restricts GitHub analysis to the main branch and recommends full Git history; GitLab examples use GIT_DEPTH: "0". Jenkins requires the SonarQube Scanner plugin (2.11+ per current docs) and a SonarQube webhook for waitForQualityGate. Recheck action/plugin versions, runner requirements, scanner/JRE behavior, provider deprecations, and edition boundaries before copying the examples into another release.

First-failure evidence. Preserve the original ceTaskId and its server-side result before retrying a branch/PR analysis; a later successful task must not erase the causal evidence from the failed run.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.