fix: keep pipeline stages and jobs in place when a job is retried
Description
When a job is retried, the pipeline tree in the sidebar moves it: the job goes to the end of its stage, and once every job of a stage has been retried (a stage with a single job, for example), the whole stage drops below the stages that came after it.
The tree orders stages and jobs by job ID (PipelineItemModel.getChildren, since 7b0c4fb8 "fix: ci stages not correctly sorted"). The jobs GitLab creates with a pipeline get their IDs stage by stage, so the IDs give the right order until a job is retried: the retry is a new job with a higher ID, and the pipeline jobs endpoint leaves the older attempts out by default, so nothing the tree receives says where the retried job used to be.
This MR, in three commits:
- Adds tests for what the next two commits change: what
getJobsForPipelinerequests and returns, and the order of the jobs inside a stage. getJobsForPipelineasks the endpoint for the retried attempts too (include_retried=true), keeps the latest attempt of each job and setsfirstAttemptIdon a job that was retried. When GitLab adds a job, it marks every older job with the same name in the pipeline as retried (CommitStatus#update_older_statuses_retried!), so the attempt with the highest ID is the one the endpoint returns without the parameter. Callers get the same jobs as before, in the same order.PipelineItemModelorders stages and jobs byfirstAttemptId ?? idinstead ofid. A pipeline in which no job was retried shows exactly as before.
firstAttemptId is an optional field on RestJob that the API does not return; its comment says so. I kept the ordering on the REST data the tree already uses: the GraphQL API lists stages in order, but that would be another request on every refresh, and it sorts the jobs inside a stage by status or name rather than in the order the pipeline created them.
Two things this does not change:
- Trigger jobs come from the bridges endpoint, which does not document
include_retried, so a retried trigger job still moves to the end of its stage, as it does today, and a stage that holds only trigger jobs still drops below the later stages once all of them have been retried. - The jobs request now also returns the retried attempts, so a pipeline with retries returns more jobs (23 instead of 21 for the pipeline below).
Related Issues
Closes #2346 (closed)
How has this been tested?
- Everything ran in
node:22.20.0, the image CI uses. On each of the three commits:npm run test:unit(291 suites, all passing),tsc -p . --noEmit, and ESLint and Prettier on the files the commit changes. The tests the second commit adds or changes fail on the first, and the tests the third commit adds fail on the second. - At the last commit also:
npm run lint,npm run test:integrationset up as thetest-integrationjob does (60 passing, 1 pending), andscripts/commit-lint/lint.jsover the three commits and over the title. - I replayed a real pipeline of this project, 2932293056, where
test-e2e-windowsran three times: I fed the two answers gitlab.com gave for its jobs, with and withoutinclude_retried, throughgetJobsForPipelineandPipelineItemModelbefore and after this MR. Before,test-e2e-windowsis listed last in theteststage; after, it is back betweentest-integration-webandtest-webview, where it was created. In both runs the service returned the same 21 jobs in the same order. src/browserandsrc/commonare not modified.
Replay of pipeline 2932293056, before and after
-requested: https://gitlab.example.com/api/v4/projects/5261717/pipelines/2932293056/jobs
+requested: https://gitlab.example.com/api/v4/projects/5261717/pipelines/2932293056/jobs?include_retried=true
jobs: 21
same IDs, in the same order, as the default listing: true
stage .pre
no-squash-with-tags
stage application-security-testing
dependency-scanning-profile-0
stage test
gitlab-advanced-sast
gemnasium-dependency_scanning
secret_detection
package-lock-integrity
check-docs-markdown
lint
check-ci-variables
test-unit
test-integration
test-integration-web
+ test-e2e-windows
test-webview
test-webview2
test-browser-build
test-e2e
test-e2e-chat
- test-e2e-windows
stage package
package-test
stage publish
publish-pre-release::manual
publish-release::manualThe three attempts of test-e2e-windows in that pipeline are jobs 17073671958 and 17073857334 (retried) and 17074030283 (latest); the jobs created with the pipeline run from 17073671946 to 17073671966.
Screenshots (if appropriate)
What CHANGELOG entry will this MR create?
-
fix:Bug fix fixes - a user-facing issue in production - included in changelog -
feat:New feature - a user-facing change which adds functionality - included in changelog -
BREAKING CHANGE:(fix or feature that would cause existing functionality to change) - should bump major version, mentioned in the changelog - None - other non-user-facing changes