diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 1a7a45446f3e17b2903d3d1fdf265343ae873fed..f35449a52af24bc81fbd863b0a41e12ee26b4479 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -485,7 +485,10 @@ def degenerate! end def archived? - degenerated? || super + return true if degenerated? + + archive_builds_older_than = Gitlab::CurrentSettings.current_application_settings.archive_builds_older_than + archive_builds_older_than.present? && created_at < archive_builds_older_than end def playable? diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 8d228571df80c38932f0a4f4896a67c18453f3bb..35aaef9ff401f3c525d0a4d0bd25b121027c20a7 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -714,16 +714,9 @@ def stuck? end def retryable? - return false if archived? - retryable_builds.any? end - def archived? - archive_builds_older_than = Gitlab::CurrentSettings.current_application_settings.archive_builds_older_than - archive_builds_older_than.present? && created_at < archive_builds_older_than - end - def cancelable? cancelable_statuses.any? && internal_pipeline? end diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index cc2db5803f61bb6c6e6e22f9380cf04e7208e787..e289e408d295125d3a430fa3b178f85625194d06 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -290,7 +290,7 @@ def cancelable? end def archived? - pipeline.archived? + false end def stuck? diff --git a/app/policies/ci/pipeline_policy.rb b/app/policies/ci/pipeline_policy.rb index 2e65c333f8d4f3cbdaac1594475e5e722484cb39..dc86a9f7e3fca1d52851891abc79f5d297cc07d5 100644 --- a/app/policies/ci/pipeline_policy.rb +++ b/app/policies/ci/pipeline_policy.rb @@ -26,10 +26,6 @@ class PipelinePolicy < BasePolicy can?(:read_build, @subject.project) end - condition(:archived, scope: :subject) do - @subject.archived? - end - # Allow reading builds for external pipelines regardless of whether CI/CD is disabled overrides :read_build rule { project_allows_read_build | (external_pipeline & can?(:reporter_access)) }.policy do @@ -41,7 +37,7 @@ class PipelinePolicy < BasePolicy prevent :read_pipeline end - rule { archived | protected_ref }.policy do + rule { protected_ref }.policy do prevent :update_pipeline prevent :cancel_pipeline end diff --git a/app/services/ci/enqueue_job_service.rb b/app/services/ci/enqueue_job_service.rb index d43b878b05e5ec61bf6040613d6fe292a5ace492..db616473336937e8649c6f76bb646992e2f0afe4 100644 --- a/app/services/ci/enqueue_job_service.rb +++ b/app/services/ci/enqueue_job_service.rb @@ -11,8 +11,6 @@ def initialize(job, current_user:, variables: nil) end def execute(&transition) - return forbidden unless allowed? - transition ||= ->(job) { job.enqueue! } Gitlab::OptimisticLocking.retry_lock(job, name: 'ci_enqueue_job') do |job| @@ -26,15 +24,5 @@ def execute(&transition) job end - - private - - def allowed? - ::Ability.allowed?(current_user, :update_pipeline, job.pipeline) - end - - def forbidden - ServiceResponse.error(message: 'Forbidden', reason: :forbidden) - end end end diff --git a/app/services/ci/pipelines/update_metadata_service.rb b/app/services/ci/pipelines/update_metadata_service.rb index 32f593d76f51ee2956bbcc8264a0c070bc91f7a3..2f2d648c13d3d68433c1ef28b0056e96cf4bc57a 100644 --- a/app/services/ci/pipelines/update_metadata_service.rb +++ b/app/services/ci/pipelines/update_metadata_service.rb @@ -3,17 +3,16 @@ module Ci module Pipelines class UpdateMetadataService - def initialize(pipeline, current_user:, params: {}) + def initialize(pipeline, params) @pipeline = pipeline - @current_user = current_user @params = params end def execute - return forbidden unless allowed? - metadata = pipeline.pipeline_metadata + metadata = pipeline.build_pipeline_metadata(project: pipeline.project) if metadata.nil? + params[:name] = params[:name].strip if params.key?(:name) if metadata.update(params) @@ -26,15 +25,7 @@ def execute private - attr_reader :pipeline, :current_user, :params - - def allowed? - ::Ability.allowed?(current_user, :update_pipeline, pipeline) - end - - def forbidden - ServiceResponse.error(message: 'Forbidden', reason: :forbidden) - end + attr_reader :pipeline, :params end end end diff --git a/app/services/ci/retry_pipeline_service.rb b/app/services/ci/retry_pipeline_service.rb index 19abbfda7acd99f00b106ce001e20288bd748696..f6b2c90c6ec8d1d9e77d28de967563d569ca003e 100644 --- a/app/services/ci/retry_pipeline_service.rb +++ b/app/services/ci/retry_pipeline_service.rb @@ -10,14 +10,14 @@ def execute(pipeline) pipeline.ensure_scheduling_type! - builds_relation(pipeline).find_each do |job| - next unless can_be_retried?(job) + builds_relation(pipeline).find_each do |build| + next unless can_be_retried?(build) - Ci::RetryJobService.new(project, current_user).clone!(job) + Ci::RetryJobService.new(project, current_user).clone!(build) end pipeline.processables.latest.skipped.find_each do |skipped| - retry_optimistic_lock(skipped, name: 'ci_retry_pipeline') { |job| job.process(current_user) } + retry_optimistic_lock(skipped, name: 'ci_retry_pipeline') { |build| build.process(current_user) } end pipeline.reset_source_bridge!(current_user) @@ -47,8 +47,8 @@ def builds_relation(pipeline) pipeline.retryable_builds.preload_needs end - def can_be_retried?(job) - can?(current_user, :update_build, job) && job.retryable? + def can_be_retried?(build) + can?(current_user, :update_build, build) end def start_pipeline(pipeline) diff --git a/lib/api/ci/pipelines.rb b/lib/api/ci/pipelines.rb index 65ef39ba606574a9a04153d20ec05f68d175017f..2dfb703bfad2132f09ecf50149c8337241e7f9a4 100644 --- a/lib/api/ci/pipelines.rb +++ b/lib/api/ci/pipelines.rb @@ -291,9 +291,7 @@ class Pipelines < ::API::Base put ':id/pipelines/:pipeline_id/metadata', urgency: :low, feature_category: :continuous_integration do authorize! :update_pipeline, pipeline - response = ::Ci::Pipelines::UpdateMetadataService - .new(pipeline, current_user: current_user, params: params.slice(:name)) - .execute + response = ::Ci::Pipelines::UpdateMetadataService.new(pipeline, params.slice(:name)).execute if response.success? present response.payload, with: Entities::Ci::PipelineWithMetadata diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index 13bd92993c89ecc535f02f4a12c0aac5e2f8d96d..3842000a931640796556dd8f49ebc04ae02eac31 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -4991,18 +4991,14 @@ def run_job_without_exception end describe '#archived?' do - before do - pipeline.update!(created_at: 1.day.ago) - end - context 'when build is degenerated' do - subject { build_stubbed(:ci_build, :degenerated, pipeline: pipeline) } + subject { create(:ci_build, :degenerated, pipeline: pipeline) } it { is_expected.to be_archived } end - context 'for old pipelines' do - subject { build_stubbed(:ci_build, pipeline: pipeline) } + context 'for old build' do + subject { create(:ci_build, created_at: 1.day.ago, pipeline: pipeline) } context 'when archive_builds_in is set' do before do diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 516c5fe2d22a839856d7f18aa82f600e267a1140..4dc6393cf9289b4a05e7f6d4c704ace724fafa6e 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -1426,7 +1426,7 @@ def transitionable?(from, to) describe '#retryable?' do subject { pipeline.retryable? } - let_it_be(:pipeline) { create(:ci_empty_pipeline, :created, project: project, created_at: 1.day.ago) } + let_it_be(:pipeline) { create(:ci_empty_pipeline, :created, project: project) } context 'no failed builds' do before do @@ -1445,14 +1445,6 @@ def transitionable?(from, to) it 'is retryable' do is_expected.to be_truthy end - - context 'with archived pipelines' do - before do - stub_application_setting(archive_builds_in_seconds: 3600) - end - - it { is_expected.to be_falsey } - end end end @@ -6122,24 +6114,4 @@ def create_bridge(upstream:, downstream:, depends: false) end end end - - describe '#archived?' do - subject { build_stubbed(:ci_pipeline, created_at: 1.day.ago, project: project) } - - context 'when archive_builds_in is set' do - before do - stub_application_setting(archive_builds_in_seconds: 3600) - end - - it { is_expected.to be_archived } - end - - context 'when archive_builds_in is not set' do - before do - stub_application_setting(archive_builds_in_seconds: nil) - end - - it { is_expected.not_to be_archived } - end - end end diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb index ee5e73e9a2239ddb81b7aa8ecf78de1b5f582754..b82389cf38a8488d9149a4cdafe8046e5537a6a0 100644 --- a/spec/models/commit_status_spec.rb +++ b/spec/models/commit_status_spec.rb @@ -5,7 +5,7 @@ RSpec.describe CommitStatus, feature_category: :continuous_integration do let_it_be(:project) { create(:project, :repository) } - let_it_be_with_reload(:pipeline) do + let_it_be(:pipeline) do create(:ci_pipeline, project: project, sha: project.commit.id) end @@ -1046,28 +1046,4 @@ def create_status(**opts) it_behaves_like 'having enum with nil value' end - - describe '#archived?' do - before do - pipeline.update!(created_at: 1.day.ago) - end - - subject { build_stubbed(:commit_status, pipeline: pipeline) } - - context 'when archive_builds_in is set' do - before do - stub_application_setting(archive_builds_in_seconds: 3600) - end - - it { is_expected.to be_archived } - end - - context 'when archive_builds_in is not set' do - before do - stub_application_setting(archive_builds_in_seconds: nil) - end - - it { is_expected.not_to be_archived } - end - end end diff --git a/spec/policies/ci/pipeline_policy_spec.rb b/spec/policies/ci/pipeline_policy_spec.rb index 1f96406eb635b794b0ac07ad8ec73aefbd4d009b..03668291d7fc0766fb91cdf8284009533d4e6c64 100644 --- a/spec/policies/ci/pipeline_policy_spec.rb +++ b/spec/policies/ci/pipeline_policy_spec.rb @@ -5,7 +5,7 @@ RSpec.describe Ci::PipelinePolicy, :models, :request_store, :use_clean_rails_redis_caching, feature_category: :continuous_integration do let_it_be(:user) { create(:user) } let_it_be_with_reload(:project) { create(:project, :repository, developers: user) } - let_it_be_with_reload(:pipeline) { create(:ci_empty_pipeline, project: project, created_at: 1.day.ago) } + let_it_be_with_reload(:pipeline) { create(:ci_empty_pipeline, project: project) } subject(:policy) do described_class.new(user, pipeline) @@ -53,26 +53,6 @@ end end - describe 'archived rules' do - context 'when archive_builds_in is set' do - before do - stub_application_setting(archive_builds_in_seconds: 3600) - end - - it { is_expected.not_to be_allowed(:update_pipeline) } - it { is_expected.not_to be_allowed(:cancel_pipeline) } - end - - context 'when archive_builds_in is not set' do - before do - stub_application_setting(archive_builds_in_seconds: nil) - end - - it { is_expected.to be_allowed(:update_pipeline) } - it { is_expected.to be_allowed(:cancel_pipeline) } - end - end - context 'when maintainer is allowed to push to pipeline branch' do before_all do project.add_maintainer(user) @@ -82,15 +62,6 @@ it { is_expected.to be_allowed(:update_pipeline) } it { is_expected.to be_allowed(:cancel_pipeline) } - - context 'and the pipeline is archived' do - before do - stub_application_setting(archive_builds_in_seconds: 3600) - end - - it { is_expected.not_to be_allowed(:update_pipeline) } - it { is_expected.not_to be_allowed(:cancel_pipeline) } - end end context 'when user does not have access to internal CI' do diff --git a/spec/services/ci/build_unschedule_service_spec.rb b/spec/services/ci/build_unschedule_service_spec.rb index 73bd84258d14eb85fbae07348eedf6ed0bd483df..539c66047e45a334bc40406e105414c3a3080610 100644 --- a/spec/services/ci/build_unschedule_service_spec.rb +++ b/spec/services/ci/build_unschedule_service_spec.rb @@ -2,10 +2,10 @@ require 'spec_helper' -RSpec.describe Ci::BuildUnscheduleService, :aggregate_failures, feature_category: :continuous_integration do +RSpec.describe Ci::BuildUnscheduleService, feature_category: :continuous_integration do let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project) } - let_it_be(:pipeline) { create(:ci_pipeline, project: project, created_at: 1.day.ago) } + let_it_be(:pipeline) { create(:ci_pipeline, project: project) } describe '#execute' do subject(:execute) { described_class.new(build, user).execute } @@ -24,25 +24,12 @@ expect(response).to be_success expect(response.payload.reload).to be_manual end - - context 'when the pipeline is archived' do - before do - stub_application_setting(archive_builds_in_seconds: 3600) - end - - it 'responds with forbidden' do - response = execute - - expect(response).to be_error - expect(response.http_status).to eq(:forbidden) - end - end end context 'when build is not scheduled' do let!(:build) { create(:ci_build, pipeline: pipeline) } - it 'responds with unprocessable entity' do + it 'responds with unprocessable entity', :aggregate_failures do response = execute expect(response).to be_error @@ -54,7 +41,7 @@ context 'when user is not authorized to unschedule the build' do let!(:build) { create(:ci_build, :scheduled, pipeline: pipeline) } - it 'responds with forbidden' do + it 'responds with forbidden', :aggregate_failures do response = execute expect(response).to be_error diff --git a/spec/services/ci/create_commit_status_service_spec.rb b/spec/services/ci/create_commit_status_service_spec.rb index 6627eb35c36ec5c829d5035033215e481d621d84..356db9fdceadd8ca0f13000fea3c37dc86b05e55 100644 --- a/spec/services/ci/create_commit_status_service_spec.rb +++ b/spec/services/ci/create_commit_status_service_spec.rb @@ -18,11 +18,11 @@ let(:params) { { state: 'pending' } } let(:job) { response.payload[:job] } - context 'when pipeline for sha does not exists' do - %w[pending running success failed canceled skipped].each do |status| - context "for #{status}" do - let(:params) { { state: status } } + %w[pending running success failed canceled skipped].each do |status| + context "for #{status}" do + let(:params) { { state: status } } + context 'when pipeline for sha does not exists' do it 'creates commit status and sets pipeline iid' do expect(response).to be_success expect(job.sha).to eq(commit.id) @@ -41,37 +41,6 @@ end end - context 'when pipeline for sha already exists' do - let_it_be(:pipeline) { create(:ci_pipeline, project: project, sha: commit.id, created_at: 1.day.ago) } - - %w[pending running success failed canceled skipped].each do |status| - context "for #{status}" do - let(:params) { { state: status } } - - it 'creates commit status on the pipeline' do - expect(response).to be_success - expect(job.sha).to eq(commit.id) - expect(job.status).to eq(status) - expect(job.name).to eq('default') - expect(job.ref).not_to be_empty - expect(job.pipeline_id).to eq(pipeline.id) - end - - context 'when the pipeline is archived' do - before do - stub_application_setting(archive_builds_in_seconds: 3600) - end - - it 'returns an error' do - expect(response).to be_error - expect(response.http_status).to eq(:forbidden) - expect(response.message).to eq('403 Forbidden') - end - end - end - end - end - context 'when status transitions from pending' do before do execute_service(state: 'pending') diff --git a/spec/services/ci/enqueue_job_service_spec.rb b/spec/services/ci/enqueue_job_service_spec.rb index 56bd6782c4f14a53e2d01f7b5a14655275bdf1e5..4fe6c372958a40f9ff23f39fb734f430581b7a06 100644 --- a/spec/services/ci/enqueue_job_service_spec.rb +++ b/spec/services/ci/enqueue_job_service_spec.rb @@ -4,9 +4,9 @@ RSpec.describe Ci::EnqueueJobService, '#execute', feature_category: :continuous_integration do let_it_be(:project) { create(:project) } - let_it_be(:user) { create(:user, maintainer_of: project) } - let_it_be_with_reload(:pipeline) { create(:ci_pipeline, project: project, created_at: 1.day.ago) } - let_it_be_with_reload(:build) { create(:ci_build, :manual, pipeline: pipeline) } + let(:user) { create(:user, developer_of: project) } + let(:pipeline) { create(:ci_pipeline, project: project) } + let(:build) { create(:ci_build, :manual, pipeline: pipeline) } let(:service) do described_class.new(build, current_user: user) @@ -107,28 +107,4 @@ expect(build.job_variables.map(&:key)).to contain_exactly('third', 'fourth') end end - - context 'when the pipeline is archived' do - before do - stub_application_setting(archive_builds_in_seconds: 3600) - end - - it 'responds with forbidden' do - response = execute - - expect(response).to be_error - expect(response.reason).to eq(:forbidden) - end - end - - context 'when user is not authorized' do - let_it_be(:user) { create(:user, developer_of: project) } - - it 'responds with forbidden' do - response = execute - - expect(response).to be_error - expect(response.reason).to eq(:forbidden) - end - end end diff --git a/spec/services/ci/pipelines/update_metadata_service_spec.rb b/spec/services/ci/pipelines/update_metadata_service_spec.rb index 81c028f1c4bb280f3dd9c3954677f3aaf60611d5..939ce7f578566642c6db10b7dd5cfaa13f3727d4 100644 --- a/spec/services/ci/pipelines/update_metadata_service_spec.rb +++ b/spec/services/ci/pipelines/update_metadata_service_spec.rb @@ -3,64 +3,32 @@ require 'spec_helper' RSpec.describe Ci::Pipelines::UpdateMetadataService, feature_category: :continuous_integration do - let_it_be(:user) { create(:user) } - let_it_be(:project) { create(:project) } - let_it_be_with_reload(:pipeline) { create(:ci_pipeline, project: project, created_at: 1.day.ago) } + subject(:execute) { described_class.new(pipeline, { name: name }).execute } - let(:params) { { name: name } } let(:name) { 'Some random pipeline name' } - subject(:execute) { described_class.new(pipeline, current_user: user, params: params).execute } + context 'when pipeline has no name' do + let(:pipeline) { create(:ci_pipeline) } - describe '#execute' do - context 'when user is authorized' do - before_all do - project.add_maintainer(user) - end - - context 'when pipeline has no name' do - it 'updates the name' do - expect { execute }.to change { pipeline.reload.name }.to(name) - end - end - - context 'when pipeline has a name' do - let_it_be(:pipeline) { create(:ci_pipeline, project: project, name: 'Some other name') } - - it 'updates the name' do - expect { execute }.to change { pipeline.reload.name }.to(name) - end - end - - context 'when new name is too long' do - let(:name) { 'a' * 256 } - - it 'does not update the name' do - expect { execute }.not_to change { pipeline.reload.name } - end - end - - context 'when the pipeline is archived' do - before do - stub_application_setting(archive_builds_in_seconds: 3600) - end + it 'updates the name' do + expect { execute }.to change { pipeline.reload.name }.to(name) + end + end - it 'responds with forbidden' do - response = execute + context 'when pipeline has a name' do + let(:pipeline) { create(:ci_pipeline, name: 'Some other name') } - expect(response).to be_error - expect(response.reason).to eq(:forbidden) - end - end + it 'updates the name' do + expect { execute }.to change { pipeline.reload.name }.to(name) end + end - context 'when user is not authorized' do - it 'responds with forbidden' do - response = execute + context 'when new name is too long' do + let(:pipeline) { create(:ci_pipeline) } + let(:name) { 'a' * 256 } - expect(response).to be_error - expect(response.reason).to eq(:forbidden) - end + it 'does not update the name' do + expect { execute }.not_to change { pipeline.reload.name } end end end diff --git a/spec/services/ci/play_bridge_service_spec.rb b/spec/services/ci/play_bridge_service_spec.rb index 99a9d715dd9cd241cf9252692c71a343522adf45..5727ed64f8b4db106547d76f277e3bb425319364 100644 --- a/spec/services/ci/play_bridge_service_spec.rb +++ b/spec/services/ci/play_bridge_service_spec.rb @@ -3,17 +3,20 @@ require 'spec_helper' RSpec.describe Ci::PlayBridgeService, '#execute', feature_category: :continuous_integration do - let_it_be(:project) { create(:project) } - let_it_be(:downstream_project) { create(:project) } - let_it_be(:user) { create(:user, maintainer_of: [project, downstream_project]) } - let_it_be(:pipeline) { create(:ci_pipeline, project: project) } - + let(:project) { create(:project) } + let(:user) { create(:user) } + let(:pipeline) { create(:ci_pipeline, project: project) } + let(:downstream_project) { create(:project) } let(:bridge) { create(:ci_bridge, :playable, pipeline: pipeline, downstream: downstream_project) } let(:instance) { described_class.new(project, user) } subject(:execute_service) { instance.execute(bridge) } context 'when user can run the bridge' do + before do + allow(instance).to receive(:can?).with(user, :play_job, bridge).and_return(true) + end + it 'marks the bridge pending' do execute_service @@ -54,7 +57,9 @@ end context 'when user can not run the bridge' do - let_it_be(:user) { create(:user, developer_of: project) } + before do + allow(instance).to receive(:can?).with(user, :play_job, bridge).and_return(false) + end it 'allows user with developer role to play a bridge' do expect { execute_service }.to raise_error Gitlab::Access::AccessDeniedError diff --git a/spec/services/ci/retry_pipeline_service_spec.rb b/spec/services/ci/retry_pipeline_service_spec.rb index f7d27e391362ee65e82858014e79c5581a1d5187..125dbc5083c572c9462f2d8281f659a6b5e168ae 100644 --- a/spec/services/ci/retry_pipeline_service_spec.rb +++ b/spec/services/ci/retry_pipeline_service_spec.rb @@ -392,22 +392,6 @@ expect(pipeline.reload).not_to be_running end end - - context 'when the pipeline is archived' do - let(:pipeline) { create(:ci_pipeline, project: project, created_at: 1.day.ago) } - - before do - stub_application_setting(archive_builds_in_seconds: 3600) - end - - it 'returns an error' do - response = service.execute(pipeline) - - expect(response.http_status).to eq(:forbidden) - expect(response.errors).to include('403 Forbidden') - expect(pipeline.reload).not_to be_running - end - end end context 'when user is not allowed to retry pipeline' do diff --git a/spec/services/ci/run_scheduled_build_service_spec.rb b/spec/services/ci/run_scheduled_build_service_spec.rb index 53c0561c47c3ae1abbaa72df2cf088d3de8ebfa7..dcd43a887949532d46e4ee2d12a7f738f1d6f4ab 100644 --- a/spec/services/ci/run_scheduled_build_service_spec.rb +++ b/spec/services/ci/run_scheduled_build_service_spec.rb @@ -2,19 +2,17 @@ require 'spec_helper' -RSpec.describe Ci::RunScheduledBuildService, :aggregate_failures, feature_category: :continuous_integration do - let_it_be(:user) { create(:user) } - let_it_be(:project) { create(:project) } - let_it_be(:pipeline) { create(:ci_pipeline, project: project, created_at: 1.day.ago) } +RSpec.describe Ci::RunScheduledBuildService, feature_category: :continuous_integration do + let(:user) { create(:user) } + let(:project) { create(:project) } + let(:pipeline) { create(:ci_pipeline, project: project) } subject(:execute_service) { described_class.new(build).execute } context 'when user can update build' do - before_all do + before do project.add_developer(user) - end - before do create(:protected_branch, :developers_can_merge, name: pipeline.ref, project: project) end @@ -61,20 +59,6 @@ expect(build).to be_created end end - - context 'when the pipeline is archived' do - let(:build) { create(:ci_build, :scheduled, user: user, project: project, pipeline: pipeline) } - - before do - stub_application_setting(archive_builds_in_seconds: 3600) - end - - it 'can not run the build' do - expect { execute_service }.to raise_error(Gitlab::Access::AccessDeniedError) - - expect(build).to be_scheduled - end - end end context 'when user can not update build' do