fix(ci): stop tracing a skipped job

Description

glab ci trace never returns for a job whose status is skipped: it prints <job> has been skipped. again on every poll, every 3 seconds, until it is interrupted. The trace in glab ci view and glab ci status goes through the same loop. In runTrace, the skipped case prints the message but, unlike the pending and manual cases, does not continue (utils.go#L218-219), so the loop fetches the trace and reaches the exit check at its end, which only treats success, failed and canceled as final (utils.go#L238-242).

This MR returns from the skipped case right after its message. A skipped job never ran, so it has no log: the loop no longer prints Showing logs for ... or requests the trace for it. The exit check is unchanged. A canceled job can have a partial log, so canceled stays in it (!3545 (merged) fixed its spelling there).

Behavior change: for a skipped job, the trace now exits with status 0 after one poll. A skipped job stays skipped unless a job it depends on is retried or started, which moves the same job back to created. A trace left running across such a retry used to show the job's log once it ran; now it has already returned, as it does for the other final states, and has to be started again.

Closes #8613 (closed)

How has this been tested?

A TestRunTraceJob subtest in internal/commands/ci/ciutils/utils_test.go. Its mock expects a single GetJob call and no GetTraceFile call, so a loop that polls again or requests the trace fails on an unexpected call, and it checks that the message is printed once and that Showing logs for is not printed. Without the change to utils.go it fails on the trace request. With it, it passes.

With Go 1.27.2 and golangci-lint 2.14.0: go test -race passes for ./internal/commands/ci/... and ./internal/commands/job/..., also on current main with this change applied, golangci-lint run reports 0 issues, golangci-lint fmt --diff and go run ./scripts/comment-overlap -threshold 1.0 -max-findings 0 ./cmd/... ./internal/... are clean, and the commit messages and the title pass commitlint with scripts/commit-lint/.commitlintrc.js.

End to end, I built glab from main and from this branch and ran glab ci trace against a small stub of the two job routes the trace calls. For a skipped job, the main build was still polling when timeout 20 stopped it (exit status 124), and this branch returned after the first poll with exit status 0, without requesting the trace.

Test output without and with the change

Without the change to utils.go:

=== NAME  TestRunTraceJob/stops_after_reporting_a_skipped_job_once
    utils.go:224: Unexpected call to *testing.MockJobsServiceInterface.GetTraceFile([OWNER/REPO 4243]) at .../internal/commands/ci/ciutils/utils.go:224 because: there are no expected calls of the method "GetTraceFile" for that receiver
--- FAIL: TestRunTraceJob (0.00s)
    --- FAIL: TestRunTraceJob/stops_after_reporting_a_skipped_job_once (0.00s)
FAIL	gitlab.com/gitlab-org/cli/internal/commands/ci/ciutils

With it:

    --- PASS: TestRunTraceJob/stops_after_reporting_a_skipped_job_once (0.00s)
ok  	gitlab.com/gitlab-org/cli/internal/commands/ci/ciutils

Command: go test -count=1 ./internal/commands/ci/ciutils/ -run 'TestRunTraceJob|TestTraceJob' -v

End-to-end runs against the stub

The stub answers GET /api/v4/projects/:id/jobs/:job_id and GET /api/v4/projects/:id/jobs/:job_id/trace and logs every request. Job 4243 is always skipped with an empty trace. Job 4244 is skipped for the first two polls and success from the third on, with a one-line trace: a shortened version of a skipped job that GitLab resets when a job it depends on is retried. A real one also goes through created, pending and running before it succeeds, and the trace on main keeps polling through those. Each run is timeout 20 glab ci trace <job> -R OWNER/REPO.

### main, job 4243: exit 124 after 20s
Getting job trace...
deploy has been skipped.
Showing logs for deploy job #4243.
deploy has been skipped.
deploy has been skipped.
deploy has been skipped.
deploy has been skipped.
deploy has been skipped.
(6 GET .../jobs/4243 and 6 GET .../jobs/4243/trace)

### this branch, job 4243: exit 0 after 3s
Getting job trace...
deploy has been skipped.
(1 GET .../jobs/4243, no trace request)

### main, job 4244: exit 0 after 9s
Getting job trace...
deploy has been skipped.
Showing logs for deploy job #4244.
deploy has been skipped.
deploy log line

### this branch, job 4244: exit 0 after 3s
Getting job trace...
deploy has been skipped.
Edited by José M. Requena Plens

Merge request reports

Loading
Loading