Fix NoMethodError in Job#artifacts_with_pages_publish_path when artifacts[:paths] is nil
Summary
A NoMethodError is occurring in lib/gitlab/ci/config/entry/job.rb when the artifacts_with_pages_publish_path method attempts to call include? on a nil value for artifacts[:paths].
Error Details
NoMethodError: undefined method `include?' for nil:NilClass (NoMethodError)
return artifacts if artifacts[:paths].include?(pages_publish_path)
^^^^^^^^^
from lib/gitlab/ci/config/entry/job.rb:244:in `artifacts_with_pages_publish_path'
from lib/gitlab/ci/config/entry/job.rb:205:in `value'
from ee/gitlab/ci/config/entry/job.rb:42:in `value'
from lib/gitlab/config/entry/node.rb:80:in `block in value'
from lib/gitlab/config/entry/node.rb:80:in `transform_values'
Sentry Error: https://new-sentry.gitlab.net/organizations/gitlab/issues/2707974
Root Cause
In the artifacts_with_pages_publish_path method, the code uses reverse_merge(paths: []) to ensure a default paths key exists. However, this doesn't guarantee that artifacts[:paths] will be an array if:
- The
artifacts_valuereturns a hash with other keys but no:pathskey - There's a symbol/string key mismatch
The current code at line 244:
return artifacts if artifacts[:paths].include?(pages_publish_path)
This fails when artifacts[:paths] is nil.
Proposed Solution
Replace the reverse_merge approach with a direct nil-safe assignment:
def artifacts_with_pages_publish_path
return artifacts_value unless pages_job?
artifacts = artifacts_value || {}
artifacts[:paths] ||= []
return artifacts if artifacts[:paths].include?(pages_publish_path)
artifacts.merge(paths: artifacts[:paths] + [pages_publish_path])
end
This ensures artifacts[:paths] is always an array before calling include?.
Test Coverage
Add test case to spec/lib/gitlab/ci/config/entry/job_spec.rb:
context 'when artifacts has no paths key' do
let(:config) { { artifacts: { name: 'my-artifact' } } }
before do
allow_next_instance_of(described_class) do |job|
allow(job).to receive(:artifacts_value).and_return({ name: 'my-artifact' })
end
end
it 'does not raise NoMethodError' do
expect { described_class.new(config, name: :pages).artifacts_with_pages_publish_path }.not_to raise_error
end
it 'adds the default publish path' do
result = described_class.new(config, name: :pages).artifacts_with_pages_publish_path
expect(result).to eq({ name: 'my-artifact', paths: ['public'] })
end
end
Impact
This bug affects pages jobs where artifacts are configured without an explicit paths key, causing pipeline configuration parsing to fail.