From 18f264a75caec72918371f7c5ecef222ba9feeb3 Mon Sep 17 00:00:00 2001
From: Lee Tickett <lee@tickett.net>
Date: Thu, 1 Sep 2022 18:14:26 +0000
Subject: [PATCH] Add id, size and expiry to GraphQL Job Artifact

Changelog: added
---
 .../graphql/queries/get_jobs.query.graphql     |  1 +
 .../queries/get_pipeline_jobs.query.graphql    |  1 +
 .../fragments/job_artifacts.fragment.graphql   |  1 +
 ..._merge_request_download_paths.query.graphql |  1 +
 app/graphql/types/ci/job_artifact_type.rb      |  9 +++++++++
 doc/api/graphql/reference/index.md             |  9 +++++++++
 spec/frontend/pipelines/mock_data.js           |  2 ++
 .../vue_shared/security_reports/mock_data.js   | 18 ++++++++++++++++++
 .../graphql/types/ci/job_artifact_type_spec.rb |  2 +-
 9 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql b/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql
index 98b51e8c2c40..75e1daaafbf3 100644
--- a/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql
+++ b/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql
@@ -12,6 +12,7 @@ query getJobs($fullPath: ID!, $after: String, $first: Int = 30, $statuses: [CiJo
       nodes {
         artifacts {
           nodes {
+            id
             downloadPath
             fileType
           }
diff --git a/app/assets/javascripts/pipelines/graphql/queries/get_pipeline_jobs.query.graphql b/app/assets/javascripts/pipelines/graphql/queries/get_pipeline_jobs.query.graphql
index 641ec7a3cf6a..0ed8f596d3db 100644
--- a/app/assets/javascripts/pipelines/graphql/queries/get_pipeline_jobs.query.graphql
+++ b/app/assets/javascripts/pipelines/graphql/queries/get_pipeline_jobs.query.graphql
@@ -12,6 +12,7 @@ query getPipelineJobs($fullPath: ID!, $iid: ID!, $after: String) {
         nodes {
           artifacts {
             nodes {
+              id
               downloadPath
               fileType
             }
diff --git a/app/assets/javascripts/vue_shared/security_reports/graphql/fragments/job_artifacts.fragment.graphql b/app/assets/javascripts/vue_shared/security_reports/graphql/fragments/job_artifacts.fragment.graphql
index 829b9d9f9d85..981d01cc81ab 100644
--- a/app/assets/javascripts/vue_shared/security_reports/graphql/fragments/job_artifacts.fragment.graphql
+++ b/app/assets/javascripts/vue_shared/security_reports/graphql/fragments/job_artifacts.fragment.graphql
@@ -6,6 +6,7 @@ fragment JobArtifacts on Pipeline {
       name
       artifacts {
         nodes {
+          id
           downloadPath
           fileType
         }
diff --git a/app/assets/javascripts/vue_shared/security_reports/graphql/queries/security_report_merge_request_download_paths.query.graphql b/app/assets/javascripts/vue_shared/security_reports/graphql/queries/security_report_merge_request_download_paths.query.graphql
index 2e80db30e9a4..9c5090cfc282 100644
--- a/app/assets/javascripts/vue_shared/security_reports/graphql/queries/security_report_merge_request_download_paths.query.graphql
+++ b/app/assets/javascripts/vue_shared/security_reports/graphql/queries/security_report_merge_request_download_paths.query.graphql
@@ -15,6 +15,7 @@ query securityReportDownloadPaths(
             name
             artifacts {
               nodes {
+                id
                 downloadPath
                 fileType
               }
diff --git a/app/graphql/types/ci/job_artifact_type.rb b/app/graphql/types/ci/job_artifact_type.rb
index a6ab445702ce..6346d50de3a9 100644
--- a/app/graphql/types/ci/job_artifact_type.rb
+++ b/app/graphql/types/ci/job_artifact_type.rb
@@ -6,6 +6,9 @@ module Ci
     class JobArtifactType < BaseObject
       graphql_name 'CiJobArtifact'
 
+      field :id, Types::GlobalIDType[::Ci::JobArtifact], null: false,
+                                                         description: 'ID of the artifact.'
+
       field :download_path, GraphQL::Types::String, null: true,
                                                     description: "URL for downloading the artifact's file."
 
@@ -16,6 +19,12 @@ class JobArtifactType < BaseObject
                                            description: 'File name of the artifact.',
                                            method: :filename
 
+      field :size, GraphQL::Types::Int, null: false,
+                                        description: 'Size of the artifact in bytes.'
+
+      field :expire_at, Types::TimeType, null: true,
+                                         description: 'Expiry date of the artifact.'
+
       def download_path
         ::Gitlab::Routing.url_helpers.download_project_job_artifacts_path(
           object.project,
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 99dc2b88e3ef..3c488fd2d88a 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -10245,8 +10245,11 @@ CI/CD variables for a GitLab instance.
 | Name | Type | Description |
 | ---- | ---- | ----------- |
 | <a id="cijobartifactdownloadpath"></a>`downloadPath` | [`String`](#string) | URL for downloading the artifact's file. |
+| <a id="cijobartifactexpireat"></a>`expireAt` | [`Time`](#time) | Expiry date of the artifact. |
 | <a id="cijobartifactfiletype"></a>`fileType` | [`JobArtifactFileType`](#jobartifactfiletype) | File type of the artifact. |
+| <a id="cijobartifactid"></a>`id` | [`CiJobArtifactID!`](#cijobartifactid) | ID of the artifact. |
 | <a id="cijobartifactname"></a>`name` | [`String`](#string) | File name of the artifact. |
+| <a id="cijobartifactsize"></a>`size` | [`Int!`](#int) | Size of the artifact in bytes. |
 
 ### `CiJobTokenScopeType`
 
@@ -21246,6 +21249,12 @@ A `CiBuildID` is a global ID. It is encoded as a string.
 
 An example `CiBuildID` is: `"gid://gitlab/Ci::Build/1"`.
 
+### `CiJobArtifactID`
+
+A `CiJobArtifactID` is a global ID. It is encoded as a string.
+
+An example `CiJobArtifactID` is: `"gid://gitlab/Ci::JobArtifact/1"`.
+
 ### `CiPipelineID`
 
 A `CiPipelineID` is a global ID. It is encoded as a string.
diff --git a/spec/frontend/pipelines/mock_data.js b/spec/frontend/pipelines/mock_data.js
index 57d1511d8593..24514d99078c 100644
--- a/spec/frontend/pipelines/mock_data.js
+++ b/spec/frontend/pipelines/mock_data.js
@@ -528,6 +528,7 @@ export const mockPipelineJobsQueryResponse = {
               artifacts: {
                 nodes: [
                   {
+                    id: 'gid://gitlab/Ci::JobArtifact/101',
                     downloadPath: '/root/ci-project/-/jobs/620/artifacts/download?file_type=trace',
                     fileType: 'TRACE',
                     __typename: 'CiJobArtifact',
@@ -580,6 +581,7 @@ export const mockPipelineJobsQueryResponse = {
               artifacts: {
                 nodes: [
                   {
+                    id: 'gid://gitlab/Ci::JobArtifact/102',
                     downloadPath: '/root/ci-project/-/jobs/619/artifacts/download?file_type=trace',
                     fileType: 'TRACE',
                     __typename: 'CiJobArtifact',
diff --git a/spec/frontend/vue_shared/security_reports/mock_data.js b/spec/frontend/vue_shared/security_reports/mock_data.js
index a9ad675e5383..a0e31243365e 100644
--- a/spec/frontend/vue_shared/security_reports/mock_data.js
+++ b/spec/frontend/vue_shared/security_reports/mock_data.js
@@ -356,12 +356,14 @@ export const securityReportMergeRequestDownloadPathsQueryResponse = {
               artifacts: {
                 nodes: [
                   {
+                    id: 'gid://gitlab/Ci::JobArtifact/101',
                     downloadPath:
                       '/gitlab-org/secrets-detection-test/-/jobs/1399/artifacts/download?file_type=trace',
                     fileType: 'TRACE',
                     __typename: 'CiJobArtifact',
                   },
                   {
+                    id: 'gid://gitlab/Ci::JobArtifact/102',
                     downloadPath:
                       '/gitlab-org/secrets-detection-test/-/jobs/1399/artifacts/download?file_type=secret_detection',
                     fileType: 'SECRET_DETECTION',
@@ -378,12 +380,14 @@ export const securityReportMergeRequestDownloadPathsQueryResponse = {
               artifacts: {
                 nodes: [
                   {
+                    id: 'gid://gitlab/Ci::JobArtifact/103',
                     downloadPath:
                       '/gitlab-org/secrets-detection-test/-/jobs/1400/artifacts/download?file_type=trace',
                     fileType: 'TRACE',
                     __typename: 'CiJobArtifact',
                   },
                   {
+                    id: 'gid://gitlab/Ci::JobArtifact/104',
                     downloadPath:
                       '/gitlab-org/secrets-detection-test/-/jobs/1400/artifacts/download?file_type=sast',
                     fileType: 'SAST',
@@ -400,12 +404,14 @@ export const securityReportMergeRequestDownloadPathsQueryResponse = {
               artifacts: {
                 nodes: [
                   {
+                    id: 'gid://gitlab/Ci::JobArtifact/105',
                     downloadPath:
                       '/gitlab-org/secrets-detection-test/-/jobs/1401/artifacts/download?file_type=trace',
                     fileType: 'TRACE',
                     __typename: 'CiJobArtifact',
                   },
                   {
+                    id: 'gid://gitlab/Ci::JobArtifact/106',
                     downloadPath:
                       '/gitlab-org/secrets-detection-test/-/jobs/1401/artifacts/download?file_type=sast',
                     fileType: 'SAST',
@@ -422,18 +428,21 @@ export const securityReportMergeRequestDownloadPathsQueryResponse = {
               artifacts: {
                 nodes: [
                   {
+                    id: 'gid://gitlab/Ci::JobArtifact/107',
                     downloadPath:
                       '/gitlab-org/secrets-detection-test/-/jobs/1402/artifacts/download?file_type=archive',
                     fileType: 'ARCHIVE',
                     __typename: 'CiJobArtifact',
                   },
                   {
+                    id: 'gid://gitlab/Ci::JobArtifact/108',
                     downloadPath:
                       '/gitlab-org/secrets-detection-test/-/jobs/1402/artifacts/download?file_type=trace',
                     fileType: 'TRACE',
                     __typename: 'CiJobArtifact',
                   },
                   {
+                    id: 'gid://gitlab/Ci::JobArtifact/109',
                     downloadPath:
                       '/gitlab-org/secrets-detection-test/-/jobs/1402/artifacts/download?file_type=metadata',
                     fileType: 'METADATA',
@@ -468,12 +477,14 @@ export const securityReportPipelineDownloadPathsQueryResponse = {
             artifacts: {
               nodes: [
                 {
+                  id: 'gid://gitlab/Ci::JobArtifact/110',
                   downloadPath:
                     '/gitlab-org/secrets-detection-test/-/jobs/1399/artifacts/download?file_type=trace',
                   fileType: 'TRACE',
                   __typename: 'CiJobArtifact',
                 },
                 {
+                  id: 'gid://gitlab/Ci::JobArtifact/111',
                   downloadPath:
                     '/gitlab-org/secrets-detection-test/-/jobs/1399/artifacts/download?file_type=secret_detection',
                   fileType: 'SECRET_DETECTION',
@@ -490,12 +501,14 @@ export const securityReportPipelineDownloadPathsQueryResponse = {
             artifacts: {
               nodes: [
                 {
+                  id: 'gid://gitlab/Ci::JobArtifact/112',
                   downloadPath:
                     '/gitlab-org/secrets-detection-test/-/jobs/1400/artifacts/download?file_type=trace',
                   fileType: 'TRACE',
                   __typename: 'CiJobArtifact',
                 },
                 {
+                  id: 'gid://gitlab/Ci::JobArtifact/113',
                   downloadPath:
                     '/gitlab-org/secrets-detection-test/-/jobs/1400/artifacts/download?file_type=sast',
                   fileType: 'SAST',
@@ -512,12 +525,14 @@ export const securityReportPipelineDownloadPathsQueryResponse = {
             artifacts: {
               nodes: [
                 {
+                  id: 'gid://gitlab/Ci::JobArtifact/114',
                   downloadPath:
                     '/gitlab-org/secrets-detection-test/-/jobs/1401/artifacts/download?file_type=trace',
                   fileType: 'TRACE',
                   __typename: 'CiJobArtifact',
                 },
                 {
+                  id: 'gid://gitlab/Ci::JobArtifact/115',
                   downloadPath:
                     '/gitlab-org/secrets-detection-test/-/jobs/1401/artifacts/download?file_type=sast',
                   fileType: 'SAST',
@@ -534,18 +549,21 @@ export const securityReportPipelineDownloadPathsQueryResponse = {
             artifacts: {
               nodes: [
                 {
+                  id: 'gid://gitlab/Ci::JobArtifact/116',
                   downloadPath:
                     '/gitlab-org/secrets-detection-test/-/jobs/1402/artifacts/download?file_type=archive',
                   fileType: 'ARCHIVE',
                   __typename: 'CiJobArtifact',
                 },
                 {
+                  id: 'gid://gitlab/Ci::JobArtifact/117',
                   downloadPath:
                     '/gitlab-org/secrets-detection-test/-/jobs/1402/artifacts/download?file_type=trace',
                   fileType: 'TRACE',
                   __typename: 'CiJobArtifact',
                 },
                 {
+                  id: 'gid://gitlab/Ci::JobArtifact/118',
                   downloadPath:
                     '/gitlab-org/secrets-detection-test/-/jobs/1402/artifacts/download?file_type=metadata',
                   fileType: 'METADATA',
diff --git a/spec/graphql/types/ci/job_artifact_type_spec.rb b/spec/graphql/types/ci/job_artifact_type_spec.rb
index 58b5f9cfcb7d..3e054faf0c9b 100644
--- a/spec/graphql/types/ci/job_artifact_type_spec.rb
+++ b/spec/graphql/types/ci/job_artifact_type_spec.rb
@@ -4,7 +4,7 @@
 
 RSpec.describe GitlabSchema.types['CiJobArtifact'] do
   it 'has the correct fields' do
-    expected_fields = [:download_path, :file_type, :name]
+    expected_fields = [:id, :download_path, :file_type, :name, :size, :expire_at]
 
     expect(described_class).to have_graphql_fields(*expected_fields)
   end
-- 
GitLab