summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/models/ci/pipeline.rb4
-rw-r--r--doc/ci/multi_project_pipelines.md15
-rw-r--r--lib/gitlab/ci/pipeline/seed/build.rb5
-rw-r--r--lib/gitlab/ci/yaml_processor.rb3
-rw-r--r--spec/factories/ci/bridge.rb9
-rw-r--r--spec/lib/gitlab/ci/pipeline/seed/build_spec.rb24
-rw-r--r--spec/lib/gitlab/ci/yaml_processor_spec.rb5
-rw-r--r--spec/models/ci/bridge_spec.rb2
-rw-r--r--spec/models/ci/pipeline_spec.rb7
9 files changed, 65 insertions, 9 deletions
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 3b28eb246db..0a943a33bbb 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -328,6 +328,10 @@ module Ci
config_sources.values_at(:repository_source, :auto_devops_source, :unknown_source)
end
+ def self.bridgeable_statuses
+ ::Ci::Pipeline::AVAILABLE_STATUSES - %w[created preparing pending]
+ end
+
def stages_count
statuses.select(:stage).distinct.count
end
diff --git a/doc/ci/multi_project_pipelines.md b/doc/ci/multi_project_pipelines.md
index ced4344a0b0..cb8d383f7d9 100644
--- a/doc/ci/multi_project_pipelines.md
+++ b/doc/ci/multi_project_pipelines.md
@@ -176,6 +176,21 @@ Upstream pipelines take precedence over downstream ones. If there are two
variables with the same name defined in both upstream and downstream projects,
the ones defined in the upstream project will take precedence.
+### Mirroring status from upstream pipeline
+
+You can mirror the pipeline status from an upstream pipeline to a bridge job by
+using the `needs:pipeline` keyword. The latest pipeline status from master is
+replicated to the bridge job.
+
+Example:
+
+```yaml
+upstream_bridge:
+ stage: test
+ needs:
+ pipeline: other/project
+```
+
### Limitations
Because bridge jobs are a little different to regular jobs, it is not
diff --git a/lib/gitlab/ci/pipeline/seed/build.rb b/lib/gitlab/ci/pipeline/seed/build.rb
index b0ce7457926..7ec03d132c0 100644
--- a/lib/gitlab/ci/pipeline/seed/build.rb
+++ b/lib/gitlab/ci/pipeline/seed/build.rb
@@ -57,7 +57,10 @@ module Gitlab
end
def bridge?
- @attributes.to_h.dig(:options, :trigger).present?
+ attributes_hash = @attributes.to_h
+ attributes_hash.dig(:options, :trigger).present? ||
+ (attributes_hash.dig(:options, :bridge_needs).instance_of?(Hash) &&
+ attributes_hash.dig(:options, :bridge_needs, :pipeline).present?)
end
def to_resource
diff --git a/lib/gitlab/ci/yaml_processor.rb b/lib/gitlab/ci/yaml_processor.rb
index 998130e5bd0..2e1eab270ff 100644
--- a/lib/gitlab/ci/yaml_processor.rb
+++ b/lib/gitlab/ci/yaml_processor.rb
@@ -55,7 +55,8 @@ module Gitlab
parallel: job[:parallel],
instance: job[:instance],
start_in: job[:start_in],
- trigger: job[:trigger]
+ trigger: job[:trigger],
+ bridge_needs: job[:needs]
}.compact }.compact
end
diff --git a/spec/factories/ci/bridge.rb b/spec/factories/ci/bridge.rb
index 6491b9dca19..b1b714277e4 100644
--- a/spec/factories/ci/bridge.rb
+++ b/spec/factories/ci/bridge.rb
@@ -8,7 +8,7 @@ FactoryBot.define do
ref 'master'
tag false
created_at 'Di 29. Okt 09:50:00 CET 2013'
- status :success
+ status :created
pipeline factory: :ci_pipeline
@@ -17,6 +17,7 @@ FactoryBot.define do
end
transient { downstream nil }
+ transient { upstream nil }
after(:build) do |bridge, evaluator|
bridge.project ||= bridge.pipeline.project
@@ -26,6 +27,12 @@ FactoryBot.define do
trigger: { project: evaluator.downstream.full_path }
)
end
+
+ if evaluator.upstream.present?
+ bridge.options = bridge.options.to_h.merge(
+ bridge_needs: { pipeline: evaluator.upstream.full_path }
+ )
+ end
end
end
end
diff --git a/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
index 5d4dec5899a..1a9350d68bd 100644
--- a/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
@@ -20,20 +20,36 @@ describe Gitlab::Ci::Pipeline::Seed::Build do
describe '#bridge?' do
subject { seed_build.bridge? }
- context 'when job is a bridge' do
+ context 'when job is a downstream bridge' do
let(:attributes) do
{ name: 'rspec', ref: 'master', options: { trigger: 'my/project' } }
end
it { is_expected.to be_truthy }
+
+ context 'when trigger definition is empty' do
+ let(:attributes) do
+ { name: 'rspec', ref: 'master', options: { trigger: '' } }
+ end
+
+ it { is_expected.to be_falsey }
+ end
end
- context 'when trigger definition is empty' do
+ context 'when job is an upstream bridge' do
let(:attributes) do
- { name: 'rspec', ref: 'master', options: { trigger: '' } }
+ { name: 'rspec', ref: 'master', options: { bridge_needs: { pipeline: 'my/project' } } }
end
- it { is_expected.to be_falsey }
+ it { is_expected.to be_truthy }
+
+ context 'when upstream definition is empty' do
+ let(:attributes) do
+ { name: 'rspec', ref: 'master', options: { bridge_needs: { pipeline: '' } } }
+ end
+
+ it { is_expected.to be_falsey }
+ end
end
context 'when job is not a bridge' do
diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb
index 4ffa1fc9fd8..d5567b4f166 100644
--- a/spec/lib/gitlab/ci/yaml_processor_spec.rb
+++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb
@@ -1153,7 +1153,10 @@ module Gitlab
stage_idx: 1,
name: "test1",
options: {
- script: ["test"]
+ script: ["test"],
+ # This does not make sense, there is a follow-up:
+ # https://gitlab.com/gitlab-org/gitlab-ce/issues/65569
+ bridge_needs: %w[build1 build2]
},
needs_attributes: [
{ name: "build1" },
diff --git a/spec/models/ci/bridge_spec.rb b/spec/models/ci/bridge_spec.rb
index eb32198265b..a871f9b3fe6 100644
--- a/spec/models/ci/bridge_spec.rb
+++ b/spec/models/ci/bridge_spec.rb
@@ -23,7 +23,7 @@ describe Ci::Bridge do
let(:status) { bridge.detailed_status(user) }
it 'returns detailed status object' do
- expect(status).to be_a Gitlab::Ci::Status::Success
+ expect(status).to be_a Gitlab::Ci::Status::Created
end
end
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 1fb83fbb088..78be4a8131a 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -1929,6 +1929,13 @@ describe Ci::Pipeline, :mailer do
it { is_expected.to be_an(Array) }
end
+ describe '.bridgeable_statuses' do
+ subject { described_class.bridgeable_statuses }
+
+ it { is_expected.to be_an(Array) }
+ it { is_expected.not_to include('created', 'preparing', 'pending') }
+ end
+
describe '#status' do
let(:build) do
create(:ci_build, :created, pipeline: pipeline, name: 'test')