Commit c81ef304 by Maxim Rydkin

add auto-cancel for pending pipelines on branch, if they are not HEAD

fix changelog MR reference add non-HEAD builds finder and add `created` pipelines to scope add spec for auto-cancel non-HEAD pipelines and refactor create_pipeline_service_spec more refactoring for spec adds option for auto-cancel into CI/CD settings fix spec to new configuration fix rubocop fix schema.rb fix schema.rb replace Gitlab 9.0 with 9.1 in doc change wording on pipeline settings added auto_canceled_by field as identifier of autocancel subject remove unnecessary index replace service with retry_lock replace auto_cancel_pending_pipelines boolean setting with integer (and enum in model) fix schema.rb fix schema.rb remove projekt attribute and clean up spec clean up spec withcouple of shared examples added spec for "It does not cancel current pipeline" scenario add some specs to auto-cancel add spec for another branch pipelines
parent 0a4b853f
......@@ -23,7 +23,7 @@ class Projects::PipelinesSettingsController < Projects::ApplicationController
def update_params
params.require(:project).permit(
:runners_token, :builds_enabled, :build_allow_git_fetch, :build_timeout_in_minutes, :build_coverage_regex,
:public_builds
:public_builds, :auto_cancel_pending_pipelines
)
end
end
......@@ -127,6 +127,14 @@ module Ci
where.not(duration: nil).sum(:duration)
end
def auto_cancelable_pipelines
project.pipelines
.where(ref: ref)
.where.not(id: id)
.where.not(sha: project.repository.sha_from_ref(ref))
.created_or_pending
end
def stage(name)
stage = Ci::Stage.new(self, name: name)
stage unless stage.statuses_count.zero?
......
......@@ -76,6 +76,7 @@ module HasStatus
scope :canceled, -> { where(status: 'canceled') }
scope :skipped, -> { where(status: 'skipped') }
scope :manual, -> { where(status: 'manual') }
scope :created_or_pending, -> { where(status: [:created, :pending]) }
scope :running_or_pending, -> { where(status: [:running, :pending]) }
scope :finished, -> { where(status: [:success, :failed, :canceled]) }
scope :failed_or_canceled, -> { where(status: [:failed, :canceled]) }
......
......@@ -256,6 +256,8 @@ class Project < ActiveRecord::Base
scope :with_builds_enabled, -> { with_feature_enabled(:builds) }
scope :with_issues_enabled, -> { with_feature_enabled(:issues) }
enum auto_cancel_pending_pipelines: { enabled: 1, disabled: 0 }
# project features may be "disabled", "internal" or "enabled". If "internal",
# they are only available to team members. This scope returns projects where
# the feature is either enabled, or internal with permission for the user.
......
......@@ -53,6 +53,8 @@ module Ci
.execute(pipeline)
end
cancel_pending_pipelines if project.auto_cancel_pending_pipelines?
pipeline.tap(&:process!)
end
......@@ -63,6 +65,16 @@ module Ci
pipeline.git_commit_message =~ /\[(ci[ _-]skip|skip[ _-]ci)\]/i
end
def cancel_pending_pipelines
Gitlab::OptimisticLocking.retry_lock(
pipeline.auto_cancelable_pipelines) do |cancelables|
cancelables.find_each do |cancelable|
cancelable.cancel_running
cancelable.update_attributes(auto_canceled_by: pipeline.id)
end
end
end
def commit
@commit ||= project.commit(origin_sha || origin_ref)
end
......
......@@ -21,7 +21,7 @@
Git strategy for pipelines
%p
Choose between <code>clone</code> or <code>fetch</code> to get the recent application code
= link_to icon('question-circle'), help_page_path('user/project/pipelines/settings', anchor: 'git-strategy')
= link_to icon('question-circle'), help_page_path('user/project/pipelines/settings', anchor: 'git-strategy'), target: '_blank'
.radio
= f.label :build_allow_git_fetch_false do
= f.radio_button :build_allow_git_fetch, 'false'
......@@ -43,7 +43,7 @@
= f.number_field :build_timeout_in_minutes, class: 'form-control', min: '0'
%p.help-block
Per job in minutes. If a job passes this threshold, it will be marked as failed.
= link_to icon('question-circle'), help_page_path('user/project/pipelines/settings', anchor: 'timeout')
= link_to icon('question-circle'), help_page_path('user/project/pipelines/settings', anchor: 'timeout'), target: '_blank'
%hr
.form-group
......@@ -53,7 +53,16 @@
%strong Public pipelines
.help-block
Allow everyone to access pipelines for public and internal projects
= link_to icon('question-circle'), help_page_path('user/project/pipelines/settings', anchor: 'visibility-of-pipelines')
= link_to icon('question-circle'), help_page_path('user/project/pipelines/settings', anchor: 'visibility-of-pipelines'), target: '_blank'
%hr
.form-group
.checkbox
= f.label :auto_cancel_pending_pipelines do
= f.check_box :auto_cancel_pending_pipelines, {}, 'enabled', 'disabled'
%strong Auto-cancel redundant, pending pipelines
.help-block
New pipelines will cancel older, pending pipelines on the same branch
= link_to icon('question-circle'), help_page_path('user/project/pipelines/settings', anchor: 'auto-cancel-pending-pipelines'), target: '_blank'
%hr
.form-group
......@@ -65,7 +74,7 @@
%p.help-block
A regular expression that will be used to find the test coverage
output in the job trace. Leave blank to disable
= link_to icon('question-circle'), help_page_path('user/project/pipelines/settings', anchor: 'test-coverage-parsing')
= link_to icon('question-circle'), help_page_path('user/project/pipelines/settings', anchor: 'test-coverage-parsing'), target: '_blank'
.bs-callout.bs-callout-info
%p Below are examples of regex for existing tools:
%ul
......
---
title: Cancel pending pipelines if commits not HEAD
merge_request: 9362
author: Rydkin Maxim
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddAutoCancelPendingPipelinesToProject < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
# When a migration requires downtime you **must** uncomment the following
# constant and define a short and easy to understand explanation as to why the
# migration requires downtime.
# DOWNTIME_REASON = 'Creating column with default value'
# When using the methods "add_concurrent_index" or "add_column_with_default"
# you must disable the use of transactions as these methods can not run in an
# existing transaction. When using "add_concurrent_index" make sure that this
# method is the _only_ method called in the migration, any other changes
# should go in a separate migration. This ensures that upon failure _only_ the
# index creation fails and can be retried or reverted easily.
#
# To disable transactions uncomment the following line and remove these
# comments:
disable_ddl_transaction!
def up
add_column_with_default(:projects, :auto_cancel_pending_pipelines, :integer, default: 0)
end
def down
remove_column(:projects, :auto_cancel_pending_pipelines)
end
end
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddAutoCanceledByToPipeline < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
# When a migration requires downtime you **must** uncomment the following
# constant and define a short and easy to understand explanation as to why the
# migration requires downtime.
# DOWNTIME_REASON = ''
# When using the methods "add_concurrent_index" or "add_column_with_default"
# you must disable the use of transactions as these methods can not run in an
# existing transaction. When using "add_concurrent_index" make sure that this
# method is the _only_ method called in the migration, any other changes
# should go in a separate migration. This ensures that upon failure _only_ the
# index creation fails and can be retried or reverted easily.
#
# To disable transactions uncomment the following line and remove these
# comments:
# disable_ddl_transaction!
def change
add_column :ci_commits, :auto_canceled_by, :integer
end
end
......@@ -251,6 +251,7 @@ ActiveRecord::Schema.define(version: 20170402231018) do
t.integer "duration"
t.integer "user_id"
t.integer "lock_version"
t.integer "auto_canceled_by"
end
add_index "ci_pipelines", ["project_id", "ref", "status"], name: "index_ci_pipelines_on_project_id_and_ref_and_status", using: :btree
......@@ -687,8 +688,8 @@ ActiveRecord::Schema.define(version: 20170402231018) do
t.string "avatar"
t.boolean "share_with_group_lock", default: false
t.integer "visibility_level", default: 20, null: false
t.boolean "request_access_enabled", default: false, null: false
t.datetime "deleted_at"
t.boolean "request_access_enabled", default: false, null: false
t.text "description_html"
t.boolean "lfs_enabled"
t.integer "parent_id"
......@@ -920,6 +921,7 @@ ActiveRecord::Schema.define(version: 20170402231018) do
t.text "description_html"
t.boolean "only_allow_merge_if_all_discussions_are_resolved"
t.boolean "printing_merge_request_link_enabled", default: true, null: false
t.integer "auto_cancel_pending_pipelines", default: 0, null: false
end
add_index "projects", ["ci_id"], name: "index_projects_on_ci_id", using: :btree
......@@ -1239,9 +1241,9 @@ ActiveRecord::Schema.define(version: 20170402231018) do
t.boolean "hide_project_limit", default: false
t.string "unlock_token"
t.datetime "otp_grace_period_started_at"
t.string "incoming_email_token"
t.boolean "ldap_email", default: false, null: false
t.boolean "external", default: false
t.string "incoming_email_token"
t.string "organization"
t.boolean "authorized_projects_populated"
t.boolean "ghost"
......
......@@ -60,6 +60,14 @@ anyone and those logged in respectively. If you wish to hide it so that only
the members of the project or group have access to it, uncheck the **Public
pipelines** checkbox and save the changes.
## Auto-cancel pending pipelines
> [Introduced][ce-9362] in GitLab 9.1.
If you want to auto-cancel all pending non-HEAD pipelines on branch, when
new pipeline will be created (after your git push or manually from UI),
check **Auto-cancel pending pipelines** checkbox and save the changes.
## Badges
In the pipelines settings page you can find pipeline status and test coverage
......@@ -111,3 +119,4 @@ into your `README.md`:
[var]: ../../../ci/yaml/README.md#git-strategy
[coverage report]: #test-coverage-parsing
[ce-9362]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9362
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment