Expose locked artifacts on pipeline index page
Following up !59813 (merged)
Problem
By default we keep our job artifacts from our most recent successful jobs.
Job Artifacts
are not downloadable on pipeline index page.
Solution
Let's revisit our downloadable association set at the pipeline level.
This will allow us to fix this problem at the root cause and by returning any locked downloadable_artifacts
everywhere we use them.
This is not final and should be tested before moving forward.
# app/models/ci/pipeline.rb
- has_many :downloadable_artifacts, -> { not_expired.downloadable.with_job }, through: :latest_builds, source: :job_artifacts
+ has_many :downloadable_artifacts, -> { not_expired_or_locked.downloadable.with_job }, through: :latest_builds, source: :job_artifacts
# app/models/ci/job_artifact.rb
+ scope :not_expired_or_locked, -> { not_expired.or(::Ci::Pipeline.artifacts_locked).joins(job: :pipeline) }
Database
Click to see the how the SQL query looks like
Diff
+ INNER JOIN ci_pipelines ON ci_pipelines.id = jobs_ci_job_artifacts.commit_id
+ AND ((expire_at IS NULL OR expire_at > '2021-04-27 18:08:58.610838') OR ci_pipelines.locked = 1)
Before
SELECT
ci_job_artifacts.id AS t0_r0,
ci_job_artifacts.project_id AS t0_r1,
ci_job_artifacts.job_id AS t0_r2,
ci_job_artifacts.file_type AS t0_r3,
ci_job_artifacts.size AS t0_r4,
ci_job_artifacts.created_at AS t0_r5,
ci_job_artifacts.updated_at AS t0_r6,
ci_job_artifacts.expire_at AS t0_r7,
ci_job_artifacts.file AS t0_r8,
ci_job_artifacts.file_store AS t0_r9,
ci_job_artifacts.file_sha256 AS t0_r10,
ci_job_artifacts.file_format AS t0_r11,
ci_job_artifacts.file_location AS t0_r12,
ci_job_artifacts.id_convert_to_bigint AS t0_r13,
ci_job_artifacts.job_id_convert_to_bigint AS t0_r14,
jobs_ci_job_artifacts.id AS t1_r0,
jobs_ci_job_artifacts.status AS t1_r1,
jobs_ci_job_artifacts.finished_at AS t1_r2,
jobs_ci_job_artifacts.trace AS t1_r3,
jobs_ci_job_artifacts.created_at AS t1_r4,
jobs_ci_job_artifacts.updated_at AS t1_r5,
jobs_ci_job_artifacts.started_at AS t1_r6,
jobs_ci_job_artifacts.runner_id AS t1_r7,
jobs_ci_job_artifacts.coverage AS t1_r8,
jobs_ci_job_artifacts.commit_id AS t1_r9,
jobs_ci_job_artifacts.name AS t1_r10,
jobs_ci_job_artifacts.options AS t1_r11,
jobs_ci_job_artifacts.allow_failure AS t1_r12,
jobs_ci_job_artifacts.stage AS t1_r13,
jobs_ci_job_artifacts.trigger_request_id AS t1_r14,
jobs_ci_job_artifacts.stage_idx AS t1_r15,
jobs_ci_job_artifacts.tag AS t1_r16,
jobs_ci_job_artifacts.ref AS t1_r17,
jobs_ci_job_artifacts.user_id AS t1_r18,
jobs_ci_job_artifacts.type AS t1_r19,
jobs_ci_job_artifacts.target_url AS t1_r20,
jobs_ci_job_artifacts.description AS t1_r21,
jobs_ci_job_artifacts.project_id AS t1_r22,
jobs_ci_job_artifacts.erased_by_id AS t1_r23,
jobs_ci_job_artifacts.erased_at AS t1_r24,
jobs_ci_job_artifacts.artifacts_expire_at AS t1_r25,
jobs_ci_job_artifacts.environment AS t1_r26,
jobs_ci_job_artifacts.when AS t1_r27,
jobs_ci_job_artifacts.yaml_variables AS t1_r28,
jobs_ci_job_artifacts.queued_at AS t1_r29,
jobs_ci_job_artifacts.token AS t1_r30,
jobs_ci_job_artifacts.lock_version AS t1_r31,
jobs_ci_job_artifacts.coverage_regex AS t1_r32,
jobs_ci_job_artifacts.auto_canceled_by_id AS t1_r33,
jobs_ci_job_artifacts.retried AS t1_r34,
jobs_ci_job_artifacts.stage_id AS t1_r35,
jobs_ci_job_artifacts.protected AS t1_r36,
jobs_ci_job_artifacts.failure_reason AS t1_r37,
jobs_ci_job_artifacts.scheduled_at AS t1_r38,
jobs_ci_job_artifacts.token_encrypted AS t1_r39,
jobs_ci_job_artifacts.upstream_pipeline_id AS t1_r40,
jobs_ci_job_artifacts.resource_group_id AS t1_r41,
jobs_ci_job_artifacts.waiting_for_resource_at AS t1_r42,
jobs_ci_job_artifacts.processed AS t1_r43,
jobs_ci_job_artifacts.scheduling_type AS t1_r44
FROM
ci_job_artifacts
INNER JOIN ci_builds ON ci_job_artifacts.job_id = ci_builds.id
INNER JOIN ci_builds jobs_ci_job_artifacts ON jobs_ci_job_artifacts.id = ci_job_artifacts.job_id
AND jobs_ci_job_artifacts.type = 'Ci::Build'
WHERE
ci_builds.type = 'Ci::Build'
AND ci_builds.commit_id = 106
AND (ci_builds.retried = FALSE
OR ci_builds.retried IS NULL)
AND (expire_at IS NULL
OR expire_at > '2021-04-28 19:06:18.740632')
AND ci_job_artifacts.file_type IN (19, 26, 1, 17, 9, 7, 8, 6, 16, 4, 10, 101, 15, 12, 11, 24, 25, 5, 21, 22)
After
SELECT
ci_job_artifacts.id AS t0_r0,
ci_job_artifacts.project_id AS t0_r1,
ci_job_artifacts.job_id AS t0_r2,
ci_job_artifacts.file_type AS t0_r3,
ci_job_artifacts.size AS t0_r4,
ci_job_artifacts.created_at AS t0_r5,
ci_job_artifacts.updated_at AS t0_r6,
ci_job_artifacts.expire_at AS t0_r7,
ci_job_artifacts.file AS t0_r8,
ci_job_artifacts.file_store AS t0_r9,
ci_job_artifacts.file_sha256 AS t0_r10,
ci_job_artifacts.file_format AS t0_r11,
ci_job_artifacts.file_location AS t0_r12,
ci_job_artifacts.id_convert_to_bigint AS t0_r13,
ci_job_artifacts.job_id_convert_to_bigint AS t0_r14,
jobs_ci_job_artifacts.id AS t1_r0,
jobs_ci_job_artifacts.status AS t1_r1,
jobs_ci_job_artifacts.finished_at AS t1_r2,
jobs_ci_job_artifacts.trace AS t1_r3,
jobs_ci_job_artifacts.created_at AS t1_r4,
jobs_ci_job_artifacts.updated_at AS t1_r5,
jobs_ci_job_artifacts.started_at AS t1_r6,
jobs_ci_job_artifacts.runner_id AS t1_r7,
jobs_ci_job_artifacts.coverage AS t1_r8,
jobs_ci_job_artifacts.commit_id AS t1_r9,
jobs_ci_job_artifacts.name AS t1_r10,
jobs_ci_job_artifacts.options AS t1_r11,
jobs_ci_job_artifacts.allow_failure AS t1_r12,
jobs_ci_job_artifacts.stage AS t1_r13,
jobs_ci_job_artifacts.trigger_request_id AS t1_r14,
jobs_ci_job_artifacts.stage_idx AS t1_r15,
jobs_ci_job_artifacts.tag AS t1_r16,
jobs_ci_job_artifacts.ref AS t1_r17,
jobs_ci_job_artifacts.user_id AS t1_r18,
jobs_ci_job_artifacts.type AS t1_r19,
jobs_ci_job_artifacts.target_url AS t1_r20,
jobs_ci_job_artifacts.description AS t1_r21,
jobs_ci_job_artifacts.project_id AS t1_r22,
jobs_ci_job_artifacts.erased_by_id AS t1_r23,
jobs_ci_job_artifacts.erased_at AS t1_r24,
jobs_ci_job_artifacts.artifacts_expire_at AS t1_r25,
jobs_ci_job_artifacts.environment AS t1_r26,
jobs_ci_job_artifacts.when AS t1_r27,
jobs_ci_job_artifacts.yaml_variables AS t1_r28,
jobs_ci_job_artifacts.queued_at AS t1_r29,
jobs_ci_job_artifacts.token AS t1_r30,
jobs_ci_job_artifacts.lock_version AS t1_r31,
jobs_ci_job_artifacts.coverage_regex AS t1_r32,
jobs_ci_job_artifacts.auto_canceled_by_id AS t1_r33,
jobs_ci_job_artifacts.retried AS t1_r34,
jobs_ci_job_artifacts.stage_id AS t1_r35,
jobs_ci_job_artifacts.protected AS t1_r36,
jobs_ci_job_artifacts.failure_reason AS t1_r37,
jobs_ci_job_artifacts.scheduled_at AS t1_r38,
jobs_ci_job_artifacts.token_encrypted AS t1_r39,
jobs_ci_job_artifacts.upstream_pipeline_id AS t1_r40,
jobs_ci_job_artifacts.resource_group_id AS t1_r41,
jobs_ci_job_artifacts.waiting_for_resource_at AS t1_r42,
jobs_ci_job_artifacts.processed AS t1_r43,
jobs_ci_job_artifacts.scheduling_type AS t1_r44
FROM
ci_job_artifacts
INNER JOIN ci_builds ON ci_job_artifacts.job_id = ci_builds.id
INNER JOIN ci_builds jobs_ci_job_artifacts ON jobs_ci_job_artifacts.id = ci_job_artifacts.job_id
AND jobs_ci_job_artifacts.type = 'Ci::Build'
INNER JOIN ci_pipelines ON ci_pipelines.id = jobs_ci_job_artifacts.commit_id
WHERE
ci_builds.type = 'Ci::Build'
AND ci_builds.commit_id = 106
AND (ci_builds.retried = FALSE
OR ci_builds.retried IS NULL)
AND ((expire_at IS NULL
OR expire_at > '2021-04-28 19:06:37.879562')
OR ci_pipelines.locked = 1)
AND ci_job_artifacts.file_type IN (19, 26, 1, 17, 9, 7, 8, 6, 16, 4, 10, 101, 15, 12, 11, 24, 25, 5, 21, 22)
Edited by Max Orefice