Skip to content

chore: make SonarQube + Tailscale non-blocking in Kotlin CI [CPONETOPS-1078] - #320

Merged
mtib merged 1 commit into
mainfrom
chore/CPONETOPS-1078/make-sonar-tailscale-optional
Jul 16, 2026
Merged

chore: make SonarQube + Tailscale non-blocking in Kotlin CI [CPONETOPS-1078]#320
mtib merged 1 commit into
mainfrom
chore/CPONETOPS-1078/make-sonar-tailscale-optional

Conversation

@mtib

@mtib mtib commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

What

Make the Tailscale VPN bring-up and the SonarQube scan non-blocking by default in the Kotlin CI workflows, so infra outages on that path stop failing PRs and deploys.

SonarQube is self-hosted behind the Monta VPN, so pull-request-kotlin.yml and sonar-cloud.yml join Tailscale before scanning. Over the last day this path has repeatedly hard-failed the whole job and blocked deploys:

  • headscale TAILSCALE_AUTHKEY expired/rotated early
  • the Tailscale package CDN returned 504 (the AWS CloudFront incident), so the action couldn't even download the tailscale binary
  • SonarQube Cloud itself had a disruption

In all these cases SonarQube is advisory, yet the failure gated every Kotlin PR and deploy.

Changes

  • pull-request-kotlin.yml
    • continue-on-error on the Tailscale step (previously it had none → any VPN/binary-download failure failed the job)
    • sonar-non-blocking now defaults to true (the Upload results to SonarQube step already honoured it)
    • Lint + tests still gate; only the VPN bring-up and Sonar upload are best-effort
  • sonar-cloud.yml
    • new sonar-non-blocking input (default true)
    • continue-on-error on the Tailscale step
    • split the bundled test koverXmlReport sonar into a gating Run tests with coverage step and a best-effort Analyze with SonarQube step, so tests still fail the job but the scan does not (mirrors the structure already used in pull-request-kotlin.yml)
  • docs/workflow-guide.md — document sonar-non-blocking, the new default, and the optional TAILSCALE_AUTHKEY secret

Behavioural change / tradeoff

SonarQube becomes advisory by default for all repos consuming these @main workflows. This is the intended fix to unblock deploys during the current outage. The known downside (raised in #guild-kotlin-backend): a genuine Sonar quality-gate failure won't block and may go unnoticed. Repos that want SonarQube to remain a hard gate can opt back in with:

with:
  sonar-non-blocking: false

Longer term the plan discussed is to move Sonar off the VPN path (self-hosted runners fetching directly), which would remove the Tailscale dependency entirely.

Validation

  • actionlint passes clean on both changed workflows

CPONETOPS-1078

…S-1078]

SonarQube is self-hosted behind the Monta VPN, so the Kotlin CI reuses a
Tailscale bring-up step before the scan. Infra outages on that path — an
expired/rotated headscale auth key, the Tailscale package CDN returning 504
(AWS CloudFront), or SonarQube being unreachable — currently fail the whole
job and block every Kotlin PR and deploy, even though SonarQube is advisory.

- pull-request-kotlin.yml: add continue-on-error to the Tailscale step and
  default sonar-non-blocking to true. Tests and lint still gate; only the VPN
  bring-up and Sonar upload are best-effort.
- sonar-cloud.yml: add a sonar-non-blocking input (default true), make the
  Tailscale step non-blocking, and split "Build and analyze" so tests + kover
  still gate while the SonarQube scan is best-effort.
- docs/workflow-guide.md: document the new input, default, and TAILSCALE_AUTHKEY.

Callers wanting SonarQube to remain a hard gate can pass sonar-non-blocking: false.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0134BvmGHE9QM5zwSAzfJJUv
@mtib
mtib requested a review from a team as a code owner July 16, 2026 09:41
@mtib
mtib requested review from JesperTerkelsen and tobias0106 and removed request for a team July 16, 2026 09:41
@mtib
mtib merged commit 7cd89f4 into main Jul 16, 2026
1 check passed
@mtib
mtib deleted the chore/CPONETOPS-1078/make-sonar-tailscale-optional branch July 16, 2026 09:47
mtib added a commit that referenced this pull request Jul 16, 2026
…078] (#321)

* chore: skip SonarQube scan when Tailscale bring-up fails [CPONETOPS-1078]

Follow-up to #320. Making the Tailscale step continue-on-error stops it from
failing the job, but the SonarQube step then still ran against a dead VPN,
failing ~30s later and logging a confusing error (job passed, but noisily).

Gate the Sonar step on the Tailscale step's outcome so a failed VPN bring-up
skips the scan entirely instead of running it doomed. Using
`outcome != 'failure'` (rather than `== 'success'`) keeps the SonarCloud path
working when Tailscale is skipped because no TAILSCALE_AUTHKEY is passed.

Applied to both pull-request-kotlin.yml and sonar-cloud.yml. With
sonar-non-blocking: false the Tailscale failure still hard-fails the job (the
scan is a required gate, so an unreachable SonarQube should block).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0134BvmGHE9QM5zwSAzfJJUv

* chore: trim comments on Sonar skip condition

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0134BvmGHE9QM5zwSAzfJJUv

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants