GitLab CI runner uploads artifacts for failed job
Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.
Summary
I have a GitLab CI job which, if successful, produces an environments file "product_versions.env" which is then captured as an artifact as follows:
artifacts: reports: dotenv: product_versions.env
As documented here (https://docs.gitlab.com/ee/ci/yaml/#artifactswhen) if the job fails, the artifact should not be uploaded if the job fails.
However, when my job fails it is still trying to upload the artifact which fails because it doesn't exist. Add "when: on_success" doesn't make a difference.
GitLab CI knows the job has failed as can be seen in the log output:
Uploading artifacts for failed job 00:01
Uploading artifacts...
Runtime platform arch=amd64 os=linux pid=3438 revision=f761588f version=14.10.1
WARNING: product_versions.env: no matching files
ERROR: No files to upload
ERROR: Job failed: exit status 1Steps to reproduce
This test job reproduces the problem:
check_variables:
stage: validate
tags:
- dev
script:
- exit 1
artifacts:
reports:
dotenv: product_versions.envExample Project
What is the current bug behavior?
Artifact uploaded / tries to upload even when the job fails.
What is the expected correct behavior?
Should not try to upload artifact because default for artifacts:when should be on_success
Relevant logs and/or screenshots
$ exit 1
Uploading artifacts for failed job 00:01
Updating CA certificates...
WARNING: ca-certificates.crt does not contain exactly one certificate or CRL: skipping
WARNING: ca-cert-ca.pem does not contain exactly one certificate or CRL: skipping
Uploading artifacts...
WARNING: product_versions.env: no matching files
ERROR: No files to upload
ERROR: Job failed: exit code 1
Output of checks
Results of GitLab environment info
GitLab Enterprise Edition 14.10.2-ee
Expand for output related to GitLab environment info
(For installations with omnibus-gitlab package run and paste the output of: `sudo gitlab-rake gitlab:env:info`) (For installations from source run and paste the output of: `sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production`)
Results of GitLab application Check
Expand for output related to the GitLab application check
(For installations with omnibus-gitlab package run and paste the output of:
sudo gitlab-rake gitlab:check SANITIZE=true)(For installations from source run and paste the output of:
sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production SANITIZE=true)(we will only investigate if the tests are passing)
Possible fixes
Wrote a quick boring solution which prevents uploading the artifact that problem (not final)
See diff
+++ b/app/services/ci/job_artifacts/create_service.rb
@@ -43,7 +43,7 @@ def execute(artifacts_file, params, metadata_file: nil)
return success if sha256_matches_existing_artifact?(params[:artifact_type], artifacts_file)
artifact, artifact_metadata = build_artifact(artifacts_file, params, metadata_file)
- result = parse_artifact(artifact)
+ result = parse_artifact(artifact, job)
track_artifact_uploader(artifact)
@@ -117,9 +117,9 @@ def build_artifact(artifacts_file, params, metadata_file)
[artifact, artifact_metadata]
end
- def parse_artifact(artifact)
+ def parse_artifact(artifact, job)
case artifact.file_type
- when 'dotenv' then parse_dotenv_artifact(artifact)
+ when 'dotenv' then parse_dotenv_artifact(artifact, job)
else success
end
end
diff --git a/app/services/ci/parse_dotenv_artifact_service.rb b/app/services/ci/parse_dotenv_artifact_service.rb
index 40e2cd82b4f..12b8e752c60 100644
--- a/app/services/ci/parse_dotenv_artifact_service.rb
+++ b/app/services/ci/parse_dotenv_artifact_service.rb
@@ -7,8 +7,8 @@ class ParseDotenvArtifactService < ::BaseService
SizeLimitError = Class.new(StandardError)
ParserError = Class.new(StandardError)
- def execute(artifact)
- validate!(artifact)
+ def execute(artifact, job)
+ validate!(artifact, job)
variables = parse!(artifact)
Ci::JobVariable.bulk_insert!(variables)
@@ -21,7 +21,7 @@ def execute(artifact)
private
- def validate!(artifact)
+ def validate!(artifact, job)
unless artifact&.dotenv?
raise ArgumentError, 'Artifact is not dotenv file type'
end
@@ -30,6 +30,10 @@ def validate!(artifact)
raise SizeLimitError,
"Dotenv Artifact Too Big. Maximum Allowable Size: #{dotenv_size_limit}"
end
+
+ if job.failed?
+ raise ArgumentError, 'Job failed'
+ end
endWe should probably don't parse this dotenv artifact at all if the job has failed.