From 3380ee716d00ce65441166f80c2f2c7313da9b9c Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Thu, 23 Mar 2017 01:05:55 -0500 Subject: [PATCH 001/113] Fix container issue when switching parallel "Changes" MR tab before done loading Fix https://gitlab.com/gitlab-org/gitlab-ce/issues/29193 --- app/assets/javascripts/diff.js | 4 --- spec/javascripts/merge_request_tabs_spec.js | 30 ++++++++++++++++++++- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/diff.js b/app/assets/javascripts/diff.js index 88180149715..5aa3eb46a69 100644 --- a/app/assets/javascripts/diff.js +++ b/app/assets/javascripts/diff.js @@ -13,10 +13,6 @@ class Diff { $diffFile.each((index, file) => new gl.ImageFile(file)); - if (this.diffViewType() === 'parallel') { - $('.content-wrapper .container-fluid').removeClass('container-limited'); - } - if (!isBound) { $(document) .on('click', '.js-unfold', this.handleClickUnfold.bind(this)) diff --git a/spec/javascripts/merge_request_tabs_spec.js b/spec/javascripts/merge_request_tabs_spec.js index 7b9632be84e..65b2fd53397 100644 --- a/spec/javascripts/merge_request_tabs_spec.js +++ b/spec/javascripts/merge_request_tabs_spec.js @@ -3,6 +3,9 @@ require('~/merge_request_tabs'); require('~/breakpoints'); require('~/lib/utils/common_utils'); +require('~/diff'); +require('~/single_file_diff'); +require('~/files_comment_button'); require('vendor/jquery.scrollTo'); (function () { @@ -213,6 +216,10 @@ require('vendor/jquery.scrollTo'); describe('with "Side-by-side"/parallel diff view', () => { beforeEach(function () { this.class.diffViewType = () => 'parallel'; + gl.Diff.prototype.diffViewType = () => 'parallel'; + spyOn($, 'ajax').and.callFake(function (options) { + options.success({ html: '' }); + }); }); it('maintains `container-limited` for pipelines tab', function (done) { @@ -224,7 +231,6 @@ require('vendor/jquery.scrollTo'); }); }); }; - asyncClick('.merge-request-tabs .pipelines-tab a') .then(() => asyncClick('.merge-request-tabs .diffs-tab a')) .then(() => asyncClick('.merge-request-tabs .pipelines-tab a')) @@ -237,6 +243,28 @@ require('vendor/jquery.scrollTo'); done.fail(`Something went wrong clicking MR tabs: ${err.message}\n${err.stack}`); }); }); + + it('maintains `container-limited` when switching from "Changes" tab before it loads', function (done) { + const asyncClick = function (selector) { + return new Promise((resolve) => { + setTimeout(() => { + document.querySelector(selector).click(); + resolve(); + }); + }); + }; + + asyncClick('.merge-request-tabs .diffs-tab a') + .then(() => asyncClick('.merge-request-tabs .notes-tab a')) + .then(() => { + const hasContainerLimitedClass = document.querySelector('.content-wrapper .container-fluid').classList.contains('container-limited'); + expect(hasContainerLimitedClass).toBe(true); + }) + .then(done) + .catch((err) => { + done.fail(`Something went wrong clicking MR tabs: ${err.message}\n${err.stack}`); + }); + }); }); }); From c81ef3041e50411166620a99e6ac80f9dc97d86e Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Mon, 20 Feb 2017 01:17:24 +0300 Subject: [PATCH 002/113] 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 --- .../projects/pipelines_settings_controller.rb | 2 +- app/models/ci/pipeline.rb | 8 + app/models/concerns/has_status.rb | 1 + app/models/project.rb | 2 + app/services/ci/create_pipeline_service.rb | 12 + .../pipelines_settings/_show.html.haml | 17 +- .../8998_skip_pending_commits_if_not_head.yml | 4 + ...uto_cancel_pending_pipelines_to_project.rb | 33 +++ ...114329_add_auto_canceled_by_to_pipeline.rb | 29 +++ db/schema.rb | 6 +- doc/user/project/pipelines/settings.md | 9 + .../ci/create_pipeline_service_spec.rb | 210 ++++++++++-------- 12 files changed, 230 insertions(+), 103 deletions(-) create mode 100644 changelogs/unreleased/8998_skip_pending_commits_if_not_head.yml create mode 100644 db/migrate/20170305180853_add_auto_cancel_pending_pipelines_to_project.rb create mode 100644 db/migrate/20170312114329_add_auto_canceled_by_to_pipeline.rb diff --git a/app/controllers/projects/pipelines_settings_controller.rb b/app/controllers/projects/pipelines_settings_controller.rb index c8c80551ac9..ff50602831c 100644 --- a/app/controllers/projects/pipelines_settings_controller.rb +++ b/app/controllers/projects/pipelines_settings_controller.rb @@ -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 diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 49dec770096..0ac12d9c3dc 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -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? diff --git a/app/models/concerns/has_status.rb b/app/models/concerns/has_status.rb index 0a1a65da05a..2f61709110c 100644 --- a/app/models/concerns/has_status.rb +++ b/app/models/concerns/has_status.rb @@ -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]) } diff --git a/app/models/project.rb b/app/models/project.rb index 83660d8c431..333b7319ffa 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -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. diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index 38a85e9fc42..cb09973081a 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -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 diff --git a/app/views/projects/pipelines_settings/_show.html.haml b/app/views/projects/pipelines_settings/_show.html.haml index 132f6372e40..a3f84476dea 100644 --- a/app/views/projects/pipelines_settings/_show.html.haml +++ b/app/views/projects/pipelines_settings/_show.html.haml @@ -21,7 +21,7 @@ Git strategy for pipelines %p Choose between clone or fetch 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 diff --git a/changelogs/unreleased/8998_skip_pending_commits_if_not_head.yml b/changelogs/unreleased/8998_skip_pending_commits_if_not_head.yml new file mode 100644 index 00000000000..9852cd6e4ff --- /dev/null +++ b/changelogs/unreleased/8998_skip_pending_commits_if_not_head.yml @@ -0,0 +1,4 @@ +--- +title: Cancel pending pipelines if commits not HEAD +merge_request: 9362 +author: Rydkin Maxim diff --git a/db/migrate/20170305180853_add_auto_cancel_pending_pipelines_to_project.rb b/db/migrate/20170305180853_add_auto_cancel_pending_pipelines_to_project.rb new file mode 100644 index 00000000000..48ee9268dea --- /dev/null +++ b/db/migrate/20170305180853_add_auto_cancel_pending_pipelines_to_project.rb @@ -0,0 +1,33 @@ +# 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 diff --git a/db/migrate/20170312114329_add_auto_canceled_by_to_pipeline.rb b/db/migrate/20170312114329_add_auto_canceled_by_to_pipeline.rb new file mode 100644 index 00000000000..344b83fa253 --- /dev/null +++ b/db/migrate/20170312114329_add_auto_canceled_by_to_pipeline.rb @@ -0,0 +1,29 @@ +# 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 diff --git a/db/schema.rb b/db/schema.rb index ccf18d07179..3ec5b08ac40 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -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" diff --git a/doc/user/project/pipelines/settings.md b/doc/user/project/pipelines/settings.md index c398ac2eb25..88246e22391 100644 --- a/doc/user/project/pipelines/settings.md +++ b/doc/user/project/pipelines/settings.md @@ -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 diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb index d2f0337c260..be677facfe2 100644 --- a/spec/services/ci/create_pipeline_service_spec.rb +++ b/spec/services/ci/create_pipeline_service_spec.rb @@ -9,72 +9,127 @@ describe Ci::CreatePipelineService, services: true do end describe '#execute' do - def execute(params) + def execute_service(after: project.commit.id, message: 'Message', ref: 'refs/heads/master') + params = { ref: ref, + before: '00000000', + after: after, + commits: [{ message: message }] } + described_class.new(project, user, params).execute end - context 'valid params' do - let(:pipeline) do - execute(ref: 'refs/heads/master', - before: '00000000', - after: project.commit.id, - commits: [{ message: "Message" }]) - end - + shared_examples 'a pending pipeline' do it { expect(pipeline).to be_kind_of(Ci::Pipeline) } it { expect(pipeline).to be_valid } - it { expect(pipeline).to be_persisted } it { expect(pipeline).to eq(project.pipelines.last) } it { expect(pipeline).to have_attributes(user: user) } + it { expect(pipeline).to have_attributes(status: 'pending') } it { expect(pipeline.builds.first).to be_kind_of(Ci::Build) } end + context 'valid params' do + let(:pipeline) { execute_service } + + it_behaves_like 'a pending pipeline' + + context 'auto-cancel enabled' do + let(:pipeline_on_previous_commit) do + execute_service( + after: previous_commit_sha_from_ref('master') + ) + end + + def previous_commit_sha_from_ref(ref) + project.repository.find_commits(ref: ref, max_count: 2)[1].id + end + + before do + project.update(auto_cancel_pending_pipelines: 'enabled') + end + + it_behaves_like 'a pending pipeline' + + it 'auto cancel pending non-HEAD pipelines' do + pending_pipeline = pipeline_on_previous_commit + pipeline + + expect(pending_pipeline.reload).to have_attributes(status: 'canceled', auto_canceled_by: pipeline.id) + end + + it 'does not cancel running outdated pipelines' do + running_pipeline = pipeline_on_previous_commit + running_pipeline.run + execute_service + + expect(running_pipeline.reload).to have_attributes(status: 'running', auto_canceled_by: nil) + end + + it 'cancel created outdated pipelines' do + created_pipeline = pipeline_on_previous_commit + created_pipeline.update(status: 'created') + pipeline + + expect(created_pipeline.reload).to have_attributes(status: 'canceled', auto_canceled_by: pipeline.id) + end + + it 'does not cancel pipelines from the other branches' do + pending_pipeline = execute_service( + ref: 'refs/heads/feature', + after: previous_commit_sha_from_ref('feature') + ) + pipeline + + expect(pending_pipeline.reload).to have_attributes(status: 'pending', auto_canceled_by: nil) + end + end + end + context "skip tag if there is no build for it" do it "creates commit if there is appropriate job" do - result = execute(ref: 'refs/heads/master', - before: '00000000', - after: project.commit.id, - commits: [{ message: "Message" }]) - expect(result).to be_persisted + expect(execute_service).to be_persisted end it "creates commit if there is no appropriate job but deploy job has right ref setting" do config = YAML.dump({ deploy: { script: "ls", only: ["master"] } }) stub_ci_pipeline_yaml_file(config) - result = execute(ref: 'refs/heads/master', - before: '00000000', - after: project.commit.id, - commits: [{ message: "Message" }]) - expect(result).to be_persisted + expect(execute_service).to be_persisted end end it 'skips creating pipeline for refs without .gitlab-ci.yml' do stub_ci_pipeline_yaml_file(nil) - result = execute(ref: 'refs/heads/master', - before: '00000000', - after: project.commit.id, - commits: [{ message: 'Message' }]) - expect(result).not_to be_persisted + expect(execute_service).not_to be_persisted expect(Ci::Pipeline.count).to eq(0) end - it 'fails commits if yaml is invalid' do - message = 'message' - allow_any_instance_of(Ci::Pipeline).to receive(:git_commit_message) { message } - stub_ci_pipeline_yaml_file('invalid: file: file') - commits = [{ message: message }] - pipeline = execute(ref: 'refs/heads/master', - before: '00000000', - after: project.commit.id, - commits: commits) + shared_examples 'a failed pipeline' do + it 'creates failed pipeline' do + stub_ci_pipeline_yaml_file(ci_yaml) - expect(pipeline).to be_persisted - expect(pipeline.builds.any?).to be false - expect(pipeline.status).to eq('failed') - expect(pipeline.yaml_errors).not_to be_nil + pipeline = execute_service(message: message) + + expect(pipeline).to be_persisted + expect(pipeline.builds.any?).to be false + expect(pipeline.status).to eq('failed') + expect(pipeline.yaml_errors).not_to be_nil + end + end + + context 'when yaml is invalid' do + let(:ci_yaml) { 'invalid: file: fiile' } + let(:message) { 'Message' } + + it_behaves_like 'a failed pipeline' + + context 'when receive git commit' do + before do + allow_any_instance_of(Ci::Pipeline).to receive(:git_commit_message) { message } + end + + it_behaves_like 'a failed pipeline' + end end context 'when commit contains a [ci skip] directive' do @@ -97,11 +152,7 @@ describe Ci::CreatePipelineService, services: true do ci_messages.each do |ci_message| it "skips builds creation if the commit message is #{ci_message}" do - commits = [{ message: ci_message }] - pipeline = execute(ref: 'refs/heads/master', - before: '00000000', - after: project.commit.id, - commits: commits) + pipeline = execute_service(message: ci_message) expect(pipeline).to be_persisted expect(pipeline.builds.any?).to be false @@ -109,58 +160,34 @@ describe Ci::CreatePipelineService, services: true do end end - it "does not skips builds creation if there is no [ci skip] or [skip ci] tag in commit message" do - allow_any_instance_of(Ci::Pipeline).to receive(:git_commit_message) { "some message" } + shared_examples 'creating a pipeline' do + it 'does not skips pipeline creation' do + allow_any_instance_of(Ci::Pipeline).to receive(:git_commit_message) { commit_message } - commits = [{ message: "some message" }] - pipeline = execute(ref: 'refs/heads/master', - before: '00000000', - after: project.commit.id, - commits: commits) + pipeline = execute_service(message: commit_message) - expect(pipeline).to be_persisted - expect(pipeline.builds.first.name).to eq("rspec") + expect(pipeline).to be_persisted + expect(pipeline.builds.first.name).to eq("rspec") + end end - it "does not skip builds creation if the commit message is nil" do - allow_any_instance_of(Ci::Pipeline).to receive(:git_commit_message) { nil } + context 'when commit message does not contain [ci skip] nor [skip ci]' do + let(:commit_message) { 'some message' } - commits = [{ message: nil }] - pipeline = execute(ref: 'refs/heads/master', - before: '00000000', - after: project.commit.id, - commits: commits) - - expect(pipeline).to be_persisted - expect(pipeline.builds.first.name).to eq("rspec") + it_behaves_like 'creating a pipeline' end - it "fails builds creation if there is [ci skip] tag in commit message and yaml is invalid" do - stub_ci_pipeline_yaml_file('invalid: file: fiile') - commits = [{ message: message }] - pipeline = execute(ref: 'refs/heads/master', - before: '00000000', - after: project.commit.id, - commits: commits) + context 'when commit message is nil' do + let(:commit_message) { nil } - expect(pipeline).to be_persisted - expect(pipeline.builds.any?).to be false - expect(pipeline.status).to eq("failed") - expect(pipeline.yaml_errors).not_to be_nil + it_behaves_like 'creating a pipeline' end - end - it "creates commit with failed status if yaml is invalid" do - stub_ci_pipeline_yaml_file('invalid: file') - commits = [{ message: "some message" }] - pipeline = execute(ref: 'refs/heads/master', - before: '00000000', - after: project.commit.id, - commits: commits) + context 'when there is [ci skip] tag in commit message and yaml is invalid' do + let(:ci_yaml) { 'invalid: file: fiile' } - expect(pipeline).to be_persisted - expect(pipeline.status).to eq("failed") - expect(pipeline.builds.any?).to be false + it_behaves_like 'a failed pipeline' + end end context 'when there are no jobs for this pipeline' do @@ -170,10 +197,7 @@ describe Ci::CreatePipelineService, services: true do end it 'does not create a new pipeline' do - result = execute(ref: 'refs/heads/master', - before: '00000000', - after: project.commit.id, - commits: [{ message: 'some msg' }]) + result = execute_service expect(result).not_to be_persisted expect(Ci::Build.all).to be_empty @@ -188,10 +212,7 @@ describe Ci::CreatePipelineService, services: true do end it 'does not create a new pipeline' do - result = execute(ref: 'refs/heads/master', - before: '00000000', - after: project.commit.id, - commits: [{ message: 'some msg' }]) + result = execute_service expect(result).to be_persisted expect(result.manual_actions).not_to be_empty @@ -205,10 +226,7 @@ describe Ci::CreatePipelineService, services: true do end it 'creates the environment' do - result = execute(ref: 'refs/heads/master', - before: '00000000', - after: project.commit.id, - commits: [{ message: 'some msg' }]) + result = execute_service expect(result).to be_persisted expect(Environment.find_by(name: "review/master")).not_to be_nil From c77b1cb0fb8a156faa3f7fa828b6838b7b89d439 Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Sat, 18 Mar 2017 12:50:56 +0300 Subject: [PATCH 003/113] add `does not cancel HEAD pipeline` spec --- spec/services/ci/create_pipeline_service_spec.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb index be677facfe2..3bff0157fda 100644 --- a/spec/services/ci/create_pipeline_service_spec.rb +++ b/spec/services/ci/create_pipeline_service_spec.rb @@ -47,7 +47,13 @@ describe Ci::CreatePipelineService, services: true do project.update(auto_cancel_pending_pipelines: 'enabled') end - it_behaves_like 'a pending pipeline' + it 'does not cancel HEAD pipeline' do + pipeline + previous_pipeline = pipeline_on_previous_commit + + expect(pipeline.reload) + .to have_attributes(status: 'pending', auto_canceled_by: nil) + end it 'auto cancel pending non-HEAD pipelines' do pending_pipeline = pipeline_on_previous_commit From b1dc850ad6037def0ed47ea190cb33ba8493ac27 Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Sat, 18 Mar 2017 13:04:14 +0300 Subject: [PATCH 004/113] move `auto_cancelable_pipelines` method to `create_pipeline_service.rb` --- app/models/ci/pipeline.rb | 8 -------- app/services/ci/create_pipeline_service.rb | 11 +++++++++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 0ac12d9c3dc..49dec770096 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -127,14 +127,6 @@ 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? diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index cb09973081a..2f5ffddb12e 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -66,8 +66,7 @@ module Ci end def cancel_pending_pipelines - Gitlab::OptimisticLocking.retry_lock( - pipeline.auto_cancelable_pipelines) do |cancelables| + Gitlab::OptimisticLocking.retry_lock(auto_cancelable_pipelines) do |cancelables| cancelables.find_each do |cancelable| cancelable.cancel_running cancelable.update_attributes(auto_canceled_by: pipeline.id) @@ -75,6 +74,14 @@ module Ci end end + def auto_cancelable_pipelines + project.pipelines + .where(ref: pipeline.ref) + .where.not(id: pipeline.id) + .where.not(sha: project.repository.sha_from_ref(pipeline.ref)) + .created_or_pending + end + def commit @commit ||= project.commit(origin_sha || origin_ref) end From 9bdb869a0aee50ac03ff8e2a630d9a40fce1a59f Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Sat, 18 Mar 2017 13:35:34 +0300 Subject: [PATCH 005/113] fix typo --- spec/services/ci/create_pipeline_service_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb index 3bff0157fda..cd63eeac5fa 100644 --- a/spec/services/ci/create_pipeline_service_spec.rb +++ b/spec/services/ci/create_pipeline_service_spec.rb @@ -167,7 +167,7 @@ describe Ci::CreatePipelineService, services: true do end shared_examples 'creating a pipeline' do - it 'does not skips pipeline creation' do + it 'does not skip pipeline creation' do allow_any_instance_of(Ci::Pipeline).to receive(:git_commit_message) { commit_message } pipeline = execute_service(message: commit_message) From 67f27a1c4bb5fa87b65845bf26ef50bb05a09fcd Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Sat, 18 Mar 2017 13:38:42 +0300 Subject: [PATCH 006/113] change order of enum options in auto_cancel_pending_pipelines --- app/models/project.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/project.rb b/app/models/project.rb index 333b7319ffa..ca80b8a2dc8 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -256,7 +256,7 @@ 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 } + enum auto_cancel_pending_pipelines: { disabled: 0, enabled: 1 } # project features may be "disabled", "internal" or "enabled". If "internal", # they are only available to team members. This scope returns projects where From 40f67c1da84379e293db14b61dc7390bc4d0a4c4 Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Sat, 18 Mar 2017 13:49:14 +0300 Subject: [PATCH 007/113] more brief way of get parent commit --- spec/services/ci/create_pipeline_service_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb index cd63eeac5fa..a61c17c66f1 100644 --- a/spec/services/ci/create_pipeline_service_spec.rb +++ b/spec/services/ci/create_pipeline_service_spec.rb @@ -40,7 +40,7 @@ describe Ci::CreatePipelineService, services: true do end def previous_commit_sha_from_ref(ref) - project.repository.find_commits(ref: ref, max_count: 2)[1].id + project.commit(ref).parent.sha end before do From a4d08e6babbbdbd44267aebdcccd2cc2c63e48ed Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Sat, 18 Mar 2017 14:46:56 +0300 Subject: [PATCH 008/113] rename `auto_canceled_by` and add foreign key --- app/models/ci/pipeline.rb | 2 ++ app/services/ci/create_pipeline_service.rb | 2 +- ...29_add_auto_canceled_by_id_to_pipeline.rb} | 14 ++++++++++---- db/schema.rb | 19 ++++++++++--------- .../ci/create_pipeline_service_spec.rb | 10 +++++----- 5 files changed, 28 insertions(+), 19 deletions(-) rename db/migrate/{20170312114329_add_auto_canceled_by_to_pipeline.rb => 20170312114329_add_auto_canceled_by_id_to_pipeline.rb} (71%) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 49dec770096..5e88ba0c170 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -7,7 +7,9 @@ module Ci belongs_to :project belongs_to :user + belongs_to :auto_canceled_by, class_name: 'Ci::Pipeline' + has_many :auto_canceled_pipelines, class_name: 'Ci::Pipeline', foreign_key: 'auto_canceled_by_id' has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id has_many :builds, foreign_key: :commit_id has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index 2f5ffddb12e..f944c869922 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -69,7 +69,7 @@ module Ci Gitlab::OptimisticLocking.retry_lock(auto_cancelable_pipelines) do |cancelables| cancelables.find_each do |cancelable| cancelable.cancel_running - cancelable.update_attributes(auto_canceled_by: pipeline.id) + cancelable.update_attributes(auto_canceled_by_id: pipeline.id) end end end diff --git a/db/migrate/20170312114329_add_auto_canceled_by_to_pipeline.rb b/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb similarity index 71% rename from db/migrate/20170312114329_add_auto_canceled_by_to_pipeline.rb rename to db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb index 344b83fa253..5549a4199b2 100644 --- a/db/migrate/20170312114329_add_auto_canceled_by_to_pipeline.rb +++ b/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb @@ -1,7 +1,7 @@ # 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 +class AddAutoCanceledByIdToPipeline < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers # Set this constant to true if this migration requires downtime. @@ -21,9 +21,15 @@ class AddAutoCanceledByToPipeline < ActiveRecord::Migration # # To disable transactions uncomment the following line and remove these # comments: - # disable_ddl_transaction! + disable_ddl_transaction! - def change - add_column :ci_commits, :auto_canceled_by, :integer + def up + add_column :ci_pipelines, :auto_canceled_by_id, :integer + add_concurrent_foreign_key :ci_pipelines, :ci_pipelines, column: :auto_canceled_by_id, on_delete: 'set null' + end + + def down + remove_foreign_key :ci_pipelines, column: :auto_canceled_by_id + remove_column :ci_pipelines, :auto_canceled_by_id end end diff --git a/db/schema.rb b/db/schema.rb index 3ec5b08ac40..9481250e81d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -61,7 +61,6 @@ ActiveRecord::Schema.define(version: 20170402231018) do t.boolean "shared_runners_enabled", default: true, null: false t.integer "max_artifacts_size", default: 100, null: false t.string "runners_registration_token" - t.integer "max_pages_size", default: 100, null: false t.boolean "require_two_factor_authentication", default: false t.integer "two_factor_grace_period", default: 48 t.boolean "metrics_enabled", default: false @@ -99,17 +98,18 @@ ActiveRecord::Schema.define(version: 20170402231018) do t.text "help_page_text_html" t.text "shared_runners_text_html" t.text "after_sign_up_text_html" + t.boolean "sidekiq_throttling_enabled", default: false + t.string "sidekiq_throttling_queues" + t.decimal "sidekiq_throttling_factor" t.boolean "housekeeping_enabled", default: true, null: false t.boolean "housekeeping_bitmaps_enabled", default: true, null: false t.integer "housekeeping_incremental_repack_period", default: 10, null: false t.integer "housekeeping_full_repack_period", default: 50, null: false t.integer "housekeeping_gc_period", default: 200, null: false - t.boolean "sidekiq_throttling_enabled", default: false - t.string "sidekiq_throttling_queues" - t.decimal "sidekiq_throttling_factor" t.boolean "html_emails_enabled", default: true t.string "plantuml_url" t.boolean "plantuml_enabled" + t.integer "max_pages_size", default: 100, null: false t.integer "terminal_max_session_time", default: 0, null: false t.string "default_artifacts_expire_in", default: "0", null: false t.integer "unique_ips_limit_per_user" @@ -251,7 +251,7 @@ ActiveRecord::Schema.define(version: 20170402231018) do t.integer "duration" t.integer "user_id" t.integer "lock_version" - t.integer "auto_canceled_by" + t.integer "auto_canceled_by_id" end add_index "ci_pipelines", ["project_id", "ref", "status"], name: "index_ci_pipelines_on_project_id_and_ref_and_status", using: :btree @@ -688,10 +688,10 @@ 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.datetime "deleted_at" t.boolean "request_access_enabled", default: false, null: false - t.text "description_html" + t.datetime "deleted_at" t.boolean "lfs_enabled" + t.text "description_html" t.integer "parent_id" end @@ -920,8 +920,8 @@ ActiveRecord::Schema.define(version: 20170402231018) do t.boolean "lfs_enabled" 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 + t.boolean "printing_merge_request_link_enabled", default: true, null: false end add_index "projects", ["ci_id"], name: "index_projects_on_ci_id", using: :btree @@ -1241,10 +1241,10 @@ 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 "organization" + t.string "incoming_email_token" t.boolean "authorized_projects_populated" t.boolean "ghost" t.boolean "notified_of_own_activity" @@ -1299,6 +1299,7 @@ ActiveRecord::Schema.define(version: 20170402231018) do add_foreign_key "boards", "projects" add_foreign_key "chat_teams", "namespaces", on_delete: :cascade + add_foreign_key "ci_pipelines", "ci_pipelines", column: "auto_canceled_by_id", name: "fk_262d4c2d19", on_delete: :nullify add_foreign_key "ci_triggers", "users", column: "owner_id", name: "fk_e8e10d1964", on_delete: :cascade add_foreign_key "issue_metrics", "issues", on_delete: :cascade add_foreign_key "label_priorities", "labels", on_delete: :cascade diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb index a61c17c66f1..4c23a371484 100644 --- a/spec/services/ci/create_pipeline_service_spec.rb +++ b/spec/services/ci/create_pipeline_service_spec.rb @@ -52,14 +52,14 @@ describe Ci::CreatePipelineService, services: true do previous_pipeline = pipeline_on_previous_commit expect(pipeline.reload) - .to have_attributes(status: 'pending', auto_canceled_by: nil) + .to have_attributes(status: 'pending', auto_canceled_by_id: nil) end it 'auto cancel pending non-HEAD pipelines' do pending_pipeline = pipeline_on_previous_commit pipeline - expect(pending_pipeline.reload).to have_attributes(status: 'canceled', auto_canceled_by: pipeline.id) + expect(pending_pipeline.reload).to have_attributes(status: 'canceled', auto_canceled_by_id: pipeline.id) end it 'does not cancel running outdated pipelines' do @@ -67,7 +67,7 @@ describe Ci::CreatePipelineService, services: true do running_pipeline.run execute_service - expect(running_pipeline.reload).to have_attributes(status: 'running', auto_canceled_by: nil) + expect(running_pipeline.reload).to have_attributes(status: 'running', auto_canceled_by_id: nil) end it 'cancel created outdated pipelines' do @@ -75,7 +75,7 @@ describe Ci::CreatePipelineService, services: true do created_pipeline.update(status: 'created') pipeline - expect(created_pipeline.reload).to have_attributes(status: 'canceled', auto_canceled_by: pipeline.id) + expect(created_pipeline.reload).to have_attributes(status: 'canceled', auto_canceled_by_id: pipeline.id) end it 'does not cancel pipelines from the other branches' do @@ -85,7 +85,7 @@ describe Ci::CreatePipelineService, services: true do ) pipeline - expect(pending_pipeline.reload).to have_attributes(status: 'pending', auto_canceled_by: nil) + expect(pending_pipeline.reload).to have_attributes(status: 'pending', auto_canceled_by_id: nil) end end end From 2eb7ae9e0732778a9f654328b0d9b283370d86e8 Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Sat, 18 Mar 2017 14:53:24 +0300 Subject: [PATCH 009/113] add auto_canceled_by_id to safe_model_attributes.yml --- spec/lib/gitlab/import_export/safe_model_attributes.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml index 1ad16a9b57d..15b8fa07040 100644 --- a/spec/lib/gitlab/import_export/safe_model_attributes.yml +++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml @@ -183,6 +183,7 @@ Ci::Pipeline: - duration - user_id - lock_version +- auto_canceled_by_id CommitStatus: - id - project_id From effcbaf372001b238741fa1174dad588ef190b61 Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Sat, 18 Mar 2017 16:44:38 +0300 Subject: [PATCH 010/113] fix on_delete --- .../20170312114329_add_auto_canceled_by_id_to_pipeline.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb b/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb index 5549a4199b2..5156860586a 100644 --- a/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb +++ b/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb @@ -25,7 +25,7 @@ class AddAutoCanceledByIdToPipeline < ActiveRecord::Migration def up add_column :ci_pipelines, :auto_canceled_by_id, :integer - add_concurrent_foreign_key :ci_pipelines, :ci_pipelines, column: :auto_canceled_by_id, on_delete: 'set null' + add_concurrent_foreign_key :ci_pipelines, :ci_pipelines, column: :auto_canceled_by_id, on_delete: :nullify end def down From b5c286995c350557fa96ab4b634c8495fa5e4888 Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Sat, 18 Mar 2017 17:49:01 +0300 Subject: [PATCH 011/113] fix rubocop --- spec/services/ci/create_pipeline_service_spec.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb index 4c23a371484..b89ed7dcf44 100644 --- a/spec/services/ci/create_pipeline_service_spec.rb +++ b/spec/services/ci/create_pipeline_service_spec.rb @@ -39,17 +39,17 @@ describe Ci::CreatePipelineService, services: true do ) end - def previous_commit_sha_from_ref(ref) - project.commit(ref).parent.sha - end - before do project.update(auto_cancel_pending_pipelines: 'enabled') end + def previous_commit_sha_from_ref(ref) + project.commit(ref).parent.sha + end + it 'does not cancel HEAD pipeline' do pipeline - previous_pipeline = pipeline_on_previous_commit + pipeline_on_previous_commit expect(pipeline.reload) .to have_attributes(status: 'pending', auto_canceled_by_id: nil) From aa4a9b9b1a28d487f231d438c9410529eb69ce4f Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Sun, 19 Mar 2017 18:47:37 +0300 Subject: [PATCH 012/113] fix fallen import_export spec --- spec/lib/gitlab/import_export/all_models.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 002cffd3062..4be6ea068d8 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -89,6 +89,8 @@ pipelines: - statuses - builds - trigger_requests +- auto_canceled_by +- auto_canceled_pipelines statuses: - project - pipeline From 2d7bc6959606bc9af5144463433507685f81a9a0 Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Sun, 19 Mar 2017 21:04:45 +0300 Subject: [PATCH 013/113] adds tooltips into several places --- app/helpers/ci_status_helper.rb | 4 ++++ app/views/ci/status/_badge.html.haml | 9 +++++---- app/views/projects/builds/_header.html.haml | 2 +- app/views/projects/ci/builds/_build.html.haml | 2 +- app/views/projects/pipelines/_info.html.haml | 2 +- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb index 2de9e0de310..88e18500430 100644 --- a/app/helpers/ci_status_helper.rb +++ b/app/helpers/ci_status_helper.rb @@ -121,4 +121,8 @@ module CiStatusHelper status.respond_to?(:label) && status.respond_to?(:icon) end + + def status_title(pipeline) + "This pipeline is redundant as a newer pipeline exists (canceled by ##{pipeline.auto_canceled_by_id} pipeline)" if pipeline.auto_canceled_by_id? && pipeline.canceled? + end end diff --git a/app/views/ci/status/_badge.html.haml b/app/views/ci/status/_badge.html.haml index c00c7f7407e..c4ff1b5bdc9 100644 --- a/app/views/ci/status/_badge.html.haml +++ b/app/views/ci/status/_badge.html.haml @@ -1,12 +1,13 @@ - status = local_assigns.fetch(:status) -- link = local_assigns.fetch(:link, true) -- css_classes = "ci-status ci-#{status.group}" +- link = local_assigns.fetch(:link, true) +- title = local_assigns.fetch(:title, nil) +- css_classes = "ci-status ci-#{status.group} #{'has-tooltip' if title.present? }" - if link && status.has_details? - = link_to status.details_path, class: css_classes do + = link_to status.details_path, class: css_classes, title: title do = custom_icon(status.icon) = status.text - else - %span{ class: css_classes } + %span{ class: css_classes, title: title } = custom_icon(status.icon) = status.text diff --git a/app/views/projects/builds/_header.html.haml b/app/views/projects/builds/_header.html.haml index 7eb17e887e7..aeb1dba4b3f 100644 --- a/app/views/projects/builds/_header.html.haml +++ b/app/views/projects/builds/_header.html.haml @@ -1,6 +1,6 @@ .content-block.build-header.top-area .header-content - = render 'ci/status/badge', status: @build.detailed_status(current_user), link: false + = render 'ci/status/badge', status: @build.detailed_status(current_user), link: false, title: status_title(@build.pipeline) Job %strong.js-build-id ##{@build.id} in pipeline diff --git a/app/views/projects/ci/builds/_build.html.haml b/app/views/projects/ci/builds/_build.html.haml index aeed293a724..b9ec59df3ca 100644 --- a/app/views/projects/ci/builds/_build.html.haml +++ b/app/views/projects/ci/builds/_build.html.haml @@ -9,7 +9,7 @@ %tr.build.commit{ class: ('retried' if retried) } %td.status - = render "ci/status/badge", status: build.detailed_status(current_user) + = render "ci/status/badge", status: build.detailed_status(current_user), title: status_title(build.pipeline) %td.branch-commit - if can?(current_user, :read_build, build) diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml index 4be9a1371ec..17f38cef718 100644 --- a/app/views/projects/pipelines/_info.html.haml +++ b/app/views/projects/pipelines/_info.html.haml @@ -1,6 +1,6 @@ .page-content-header .header-main-content - = render 'ci/status/badge', status: @pipeline.detailed_status(current_user) + = render 'ci/status/badge', status: @pipeline.detailed_status(current_user), title: status_title(@pipeline) %strong Pipeline ##{@pipeline.id} triggered #{time_ago_with_tooltip(@pipeline.created_at)} - if @pipeline.user From ebf052010c14130a1ed1117c4723315c4feb57fc Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Sun, 19 Mar 2017 22:04:56 +0300 Subject: [PATCH 014/113] add tooltip on badge in pipelines index --- .../javascripts/vue_pipelines_index/components/status.js | 7 ++++++- app/serializers/pipeline_entity.rb | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/vue_pipelines_index/components/status.js b/app/assets/javascripts/vue_pipelines_index/components/status.js index 21a281af438..82db731b73c 100644 --- a/app/assets/javascripts/vue_pipelines_index/components/status.js +++ b/app/assets/javascripts/vue_pipelines_index/components/status.js @@ -36,7 +36,7 @@ export default { computed: { cssClasses() { - return `ci-status ci-${this.pipeline.details.status.group}`; + return `ci-status ci-${this.pipeline.details.status.group} has-tooltip`; }, detailsPath() { @@ -47,12 +47,17 @@ export default { content() { return `${this.svg} ${this.pipeline.details.status.text}`; }, + + tooltipTitle() { + return this.pipeline.details.status_tooltip; + } }, template: ` diff --git a/app/serializers/pipeline_entity.rb b/app/serializers/pipeline_entity.rb index 3f16dd66d54..6dc84c925fe 100644 --- a/app/serializers/pipeline_entity.rb +++ b/app/serializers/pipeline_entity.rb @@ -13,6 +13,7 @@ class PipelineEntity < Grape::Entity expose :details do expose :detailed_status, as: :status, with: StatusEntity + expose :status_tooltip expose :duration expose :finished_at expose :stages, using: StageEntity @@ -81,4 +82,8 @@ class PipelineEntity < Grape::Entity def detailed_status pipeline.detailed_status(request.user) end + + def status_tooltip + "This pipeline is redundant as a newer pipeline exists (canceled by ##{pipeline.auto_canceled_by_id} pipeline)" if pipeline.auto_canceled_by_id? && pipeline.canceled? + end end From 29db8ab982bc912c2404cf35527362b5f991e1ce Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Mon, 20 Mar 2017 01:00:10 +0300 Subject: [PATCH 015/113] fix linter error --- app/assets/javascripts/vue_pipelines_index/components/status.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/vue_pipelines_index/components/status.js b/app/assets/javascripts/vue_pipelines_index/components/status.js index 82db731b73c..ece1ec89f89 100644 --- a/app/assets/javascripts/vue_pipelines_index/components/status.js +++ b/app/assets/javascripts/vue_pipelines_index/components/status.js @@ -50,7 +50,7 @@ export default { tooltipTitle() { return this.pipeline.details.status_tooltip; - } + }, }, template: ` From d2f2168b51284bee445e10d7ad399175ed51c539 Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Mon, 20 Mar 2017 23:52:35 +0300 Subject: [PATCH 016/113] remove `a pending pipeline` shared example --- spec/services/ci/create_pipeline_service_spec.rb | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb index b89ed7dcf44..c287fe42ab2 100644 --- a/spec/services/ci/create_pipeline_service_spec.rb +++ b/spec/services/ci/create_pipeline_service_spec.rb @@ -18,19 +18,15 @@ describe Ci::CreatePipelineService, services: true do described_class.new(project, user, params).execute end - shared_examples 'a pending pipeline' do + context 'valid params' do + let(:pipeline) { execute_service } + it { expect(pipeline).to be_kind_of(Ci::Pipeline) } it { expect(pipeline).to be_valid } it { expect(pipeline).to eq(project.pipelines.last) } it { expect(pipeline).to have_attributes(user: user) } it { expect(pipeline).to have_attributes(status: 'pending') } it { expect(pipeline.builds.first).to be_kind_of(Ci::Build) } - end - - context 'valid params' do - let(:pipeline) { execute_service } - - it_behaves_like 'a pending pipeline' context 'auto-cancel enabled' do let(:pipeline_on_previous_commit) do From b49e79662e8157d7feb371737f6350dce11118e3 Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Tue, 21 Mar 2017 00:39:27 +0300 Subject: [PATCH 017/113] refactor spec --- .../services/ci/create_pipeline_service_spec.rb | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb index c287fe42ab2..a3330367f96 100644 --- a/spec/services/ci/create_pipeline_service_spec.rb +++ b/spec/services/ci/create_pipeline_service_spec.rb @@ -47,31 +47,28 @@ describe Ci::CreatePipelineService, services: true do pipeline pipeline_on_previous_commit - expect(pipeline.reload) - .to have_attributes(status: 'pending', auto_canceled_by_id: nil) + expect(pipeline.reload).to have_attributes(status: 'pending', auto_canceled_by_id: nil) end it 'auto cancel pending non-HEAD pipelines' do - pending_pipeline = pipeline_on_previous_commit + pipeline_on_previous_commit pipeline - expect(pending_pipeline.reload).to have_attributes(status: 'canceled', auto_canceled_by_id: pipeline.id) + expect(pipeline_on_previous_commit.reload).to have_attributes(status: 'canceled', auto_canceled_by_id: pipeline.id) end it 'does not cancel running outdated pipelines' do - running_pipeline = pipeline_on_previous_commit - running_pipeline.run + pipeline_on_previous_commit.run execute_service - expect(running_pipeline.reload).to have_attributes(status: 'running', auto_canceled_by_id: nil) + expect(pipeline_on_previous_commit.reload).to have_attributes(status: 'running', auto_canceled_by_id: nil) end it 'cancel created outdated pipelines' do - created_pipeline = pipeline_on_previous_commit - created_pipeline.update(status: 'created') + pipeline_on_previous_commit.update(status: 'created') pipeline - expect(created_pipeline.reload).to have_attributes(status: 'canceled', auto_canceled_by_id: pipeline.id) + expect(pipeline_on_previous_commit.reload).to have_attributes(status: 'canceled', auto_canceled_by_id: pipeline.id) end it 'does not cancel pipelines from the other branches' do From 4f748f74bc561ed6cc37f2c57077e72c0cda8c9a Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Tue, 21 Mar 2017 00:48:05 +0300 Subject: [PATCH 018/113] replace on_delete in migration with database type related expression --- ...20170312114329_add_auto_canceled_by_id_to_pipeline.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb b/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb index 5156860586a..46dab852fcf 100644 --- a/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb +++ b/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb @@ -24,8 +24,15 @@ class AddAutoCanceledByIdToPipeline < ActiveRecord::Migration disable_ddl_transaction! def up + on_delete = + if Database.mysql? + :nullify + else + 'SET NULL' + end + add_column :ci_pipelines, :auto_canceled_by_id, :integer - add_concurrent_foreign_key :ci_pipelines, :ci_pipelines, column: :auto_canceled_by_id, on_delete: :nullify + add_concurrent_foreign_key :ci_pipelines, :ci_pipelines, column: :auto_canceled_by_id, on_delete: on_delete end def down From 63dbdb9f52d1aa56cbf1e15022623c306083fdd1 Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Tue, 21 Mar 2017 01:05:52 +0300 Subject: [PATCH 019/113] add presenter for status badge --- app/helpers/ci_status_helper.rb | 2 +- .../ci/pipeline_status_badge_presenter.rb | 13 +++++++++++++ app/serializers/pipeline_entity.rb | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 app/presenters/ci/pipeline_status_badge_presenter.rb diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb index 88e18500430..da4826567d4 100644 --- a/app/helpers/ci_status_helper.rb +++ b/app/helpers/ci_status_helper.rb @@ -123,6 +123,6 @@ module CiStatusHelper end def status_title(pipeline) - "This pipeline is redundant as a newer pipeline exists (canceled by ##{pipeline.auto_canceled_by_id} pipeline)" if pipeline.auto_canceled_by_id? && pipeline.canceled? + Ci::PipelineStatusBadgePresenter.new(pipeline).status_title end end diff --git a/app/presenters/ci/pipeline_status_badge_presenter.rb b/app/presenters/ci/pipeline_status_badge_presenter.rb new file mode 100644 index 00000000000..bc6601c8a7f --- /dev/null +++ b/app/presenters/ci/pipeline_status_badge_presenter.rb @@ -0,0 +1,13 @@ +module Ci + class PipelineStatusBadgePresenter < Gitlab::View::Presenter::Delegated + presents :pipeline + + def auto_canceled? + canceled? && auto_canceled_by_id? + end + + def status_title + "Pipeline is redundant and is auto-canceled by Pipeline ##{pipeline.auto_canceled_by_id}" if auto_canceled? + end + end +end diff --git a/app/serializers/pipeline_entity.rb b/app/serializers/pipeline_entity.rb index 6dc84c925fe..82ee960f530 100644 --- a/app/serializers/pipeline_entity.rb +++ b/app/serializers/pipeline_entity.rb @@ -84,6 +84,6 @@ class PipelineEntity < Grape::Entity end def status_tooltip - "This pipeline is redundant as a newer pipeline exists (canceled by ##{pipeline.auto_canceled_by_id} pipeline)" if pipeline.auto_canceled_by_id? && pipeline.canceled? + Ci::PipelineStatusBadgePresenter.new(pipeline).status_title end end From a0de26f2c439554feb446c5283c07ea90279304c Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Tue, 21 Mar 2017 09:30:23 +0300 Subject: [PATCH 020/113] fix migration error --- .../20170312114329_add_auto_canceled_by_id_to_pipeline.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb b/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb index 46dab852fcf..6e89967e4be 100644 --- a/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb +++ b/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb @@ -25,7 +25,7 @@ class AddAutoCanceledByIdToPipeline < ActiveRecord::Migration def up on_delete = - if Database.mysql? + if Gitlab::Database.mysql? :nullify else 'SET NULL' From 86d8c2a78e3e9834bcb59a94041be6f9e40c7f98 Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Mon, 27 Mar 2017 21:14:17 +0300 Subject: [PATCH 021/113] remove redundant `pipeline` --- app/presenters/ci/pipeline_status_badge_presenter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/presenters/ci/pipeline_status_badge_presenter.rb b/app/presenters/ci/pipeline_status_badge_presenter.rb index bc6601c8a7f..ac6325dd5fa 100644 --- a/app/presenters/ci/pipeline_status_badge_presenter.rb +++ b/app/presenters/ci/pipeline_status_badge_presenter.rb @@ -7,7 +7,7 @@ module Ci end def status_title - "Pipeline is redundant and is auto-canceled by Pipeline ##{pipeline.auto_canceled_by_id}" if auto_canceled? + "Pipeline is redundant and is auto-canceled by Pipeline ##{auto_canceled_by_id}" if auto_canceled? end end end From 3a7352fddc93dc2736a3bfd24008a2006c5fc4eb Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Mon, 27 Mar 2017 21:15:23 +0300 Subject: [PATCH 022/113] remove unnecessary space --- app/views/ci/status/_badge.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/ci/status/_badge.html.haml b/app/views/ci/status/_badge.html.haml index c4ff1b5bdc9..39c7fb0eba2 100644 --- a/app/views/ci/status/_badge.html.haml +++ b/app/views/ci/status/_badge.html.haml @@ -1,7 +1,7 @@ - status = local_assigns.fetch(:status) - link = local_assigns.fetch(:link, true) - title = local_assigns.fetch(:title, nil) -- css_classes = "ci-status ci-#{status.group} #{'has-tooltip' if title.present? }" +- css_classes = "ci-status ci-#{status.group} #{'has-tooltip' if title.present?}" - if link && status.has_details? = link_to status.details_path, class: css_classes, title: title do From 14722b66a1ee0dd711a631a8d48e8761334ed4a4 Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Tue, 28 Mar 2017 20:47:11 +0300 Subject: [PATCH 023/113] rename pipeline_presenter --- app/helpers/ci_status_helper.rb | 2 +- ...pipeline_status_badge_presenter.rb => pipeline_presenter.rb} | 2 +- app/serializers/pipeline_entity.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename app/presenters/ci/{pipeline_status_badge_presenter.rb => pipeline_presenter.rb} (77%) diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb index da4826567d4..2db95729dd9 100644 --- a/app/helpers/ci_status_helper.rb +++ b/app/helpers/ci_status_helper.rb @@ -123,6 +123,6 @@ module CiStatusHelper end def status_title(pipeline) - Ci::PipelineStatusBadgePresenter.new(pipeline).status_title + Ci::PipelinePresenter.new(pipeline).status_title end end diff --git a/app/presenters/ci/pipeline_status_badge_presenter.rb b/app/presenters/ci/pipeline_presenter.rb similarity index 77% rename from app/presenters/ci/pipeline_status_badge_presenter.rb rename to app/presenters/ci/pipeline_presenter.rb index ac6325dd5fa..8f9e4fa707d 100644 --- a/app/presenters/ci/pipeline_status_badge_presenter.rb +++ b/app/presenters/ci/pipeline_presenter.rb @@ -1,5 +1,5 @@ module Ci - class PipelineStatusBadgePresenter < Gitlab::View::Presenter::Delegated + class PipelinePresenter < Gitlab::View::Presenter::Delegated presents :pipeline def auto_canceled? diff --git a/app/serializers/pipeline_entity.rb b/app/serializers/pipeline_entity.rb index 82ee960f530..c6b80dc0952 100644 --- a/app/serializers/pipeline_entity.rb +++ b/app/serializers/pipeline_entity.rb @@ -84,6 +84,6 @@ class PipelineEntity < Grape::Entity end def status_tooltip - Ci::PipelineStatusBadgePresenter.new(pipeline).status_title + Ci::PipelinePresenter.new(pipeline).status_title end end From b9f7d4b45e0456c35d8e95977bb2f9281cde69b4 Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Tue, 28 Mar 2017 21:01:28 +0300 Subject: [PATCH 024/113] split up migrations --- ...329_add_auto_canceled_by_id_to_pipeline.rb | 17 +------- ..._canceled_by_id_foreign_key_to_pipeline.rb | 40 +++++++++++++++++++ 2 files changed, 42 insertions(+), 15 deletions(-) create mode 100644 db/migrate/20170312114529_add_auto_canceled_by_id_foreign_key_to_pipeline.rb diff --git a/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb b/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb index 6e89967e4be..813813225e0 100644 --- a/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb +++ b/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb @@ -21,22 +21,9 @@ class AddAutoCanceledByIdToPipeline < ActiveRecord::Migration # # To disable transactions uncomment the following line and remove these # comments: - disable_ddl_transaction! - - def up - on_delete = - if Gitlab::Database.mysql? - :nullify - else - 'SET NULL' - end + # disable_ddl_transaction! + def change add_column :ci_pipelines, :auto_canceled_by_id, :integer - add_concurrent_foreign_key :ci_pipelines, :ci_pipelines, column: :auto_canceled_by_id, on_delete: on_delete - end - - def down - remove_foreign_key :ci_pipelines, column: :auto_canceled_by_id - remove_column :ci_pipelines, :auto_canceled_by_id end end diff --git a/db/migrate/20170312114529_add_auto_canceled_by_id_foreign_key_to_pipeline.rb b/db/migrate/20170312114529_add_auto_canceled_by_id_foreign_key_to_pipeline.rb new file mode 100644 index 00000000000..c9dd5be9799 --- /dev/null +++ b/db/migrate/20170312114529_add_auto_canceled_by_id_foreign_key_to_pipeline.rb @@ -0,0 +1,40 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddAutoCanceledByIdForeignKeyToPipeline < 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 up + on_delete = + if Gitlab::Database.mysql? + :nullify + else + 'SET NULL' + end + + add_concurrent_foreign_key :ci_pipelines, :ci_pipelines, column: :auto_canceled_by_id, on_delete: on_delete + end + + def down + remove_foreign_key :ci_pipelines, column: :auto_canceled_by_id + end +end From 2575661865be0cd230993950b78e0b4550694f78 Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Tue, 28 Mar 2017 23:27:16 +0300 Subject: [PATCH 025/113] replace helper with decorator --- app/helpers/ci_status_helper.rb | 4 ---- app/models/ci/pipeline.rb | 1 + app/serializers/pipeline_entity.rb | 2 +- app/views/projects/builds/_header.html.haml | 12 +++++++----- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb index 2db95729dd9..2de9e0de310 100644 --- a/app/helpers/ci_status_helper.rb +++ b/app/helpers/ci_status_helper.rb @@ -121,8 +121,4 @@ module CiStatusHelper status.respond_to?(:label) && status.respond_to?(:icon) end - - def status_title(pipeline) - Ci::PipelinePresenter.new(pipeline).status_title - end end diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 5e88ba0c170..9ef35ebdd50 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -4,6 +4,7 @@ module Ci include HasStatus include Importable include AfterCommitQueue + include Presentable belongs_to :project belongs_to :user diff --git a/app/serializers/pipeline_entity.rb b/app/serializers/pipeline_entity.rb index c6b80dc0952..78af8b51709 100644 --- a/app/serializers/pipeline_entity.rb +++ b/app/serializers/pipeline_entity.rb @@ -84,6 +84,6 @@ class PipelineEntity < Grape::Entity end def status_tooltip - Ci::PipelinePresenter.new(pipeline).status_title + pipeline.present(current_user: request.user).status_title end end diff --git a/app/views/projects/builds/_header.html.haml b/app/views/projects/builds/_header.html.haml index aeb1dba4b3f..67da50646c7 100644 --- a/app/views/projects/builds/_header.html.haml +++ b/app/views/projects/builds/_header.html.haml @@ -1,14 +1,16 @@ +- pipeline = @build.pipeline.present(current_user: current_user) + .content-block.build-header.top-area .header-content - = render 'ci/status/badge', status: @build.detailed_status(current_user), link: false, title: status_title(@build.pipeline) + = render 'ci/status/badge', status: @build.detailed_status(current_user), link: false, title: pipeline.status_title Job %strong.js-build-id ##{@build.id} in pipeline - = link_to pipeline_path(@build.pipeline) do - %strong ##{@build.pipeline.id} + = link_to pipeline_path(pipeline) do + %strong ##{pipeline.id} for commit - = link_to namespace_project_commit_path(@project.namespace, @project, @build.pipeline.sha) do - %strong= @build.pipeline.short_sha + = link_to namespace_project_commit_path(@project.namespace, @project, pipeline.sha) do + %strong= pipeline.short_sha from = link_to namespace_project_commits_path(@project.namespace, @project, @build.ref) do %code From c9806b47b868ca5fe424476077262edc1d64cac0 Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Tue, 4 Apr 2017 21:49:16 +0300 Subject: [PATCH 026/113] extract build.pipeline as variable --- app/views/projects/ci/builds/_build.html.haml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/views/projects/ci/builds/_build.html.haml b/app/views/projects/ci/builds/_build.html.haml index b9ec59df3ca..c57e4e81912 100644 --- a/app/views/projects/ci/builds/_build.html.haml +++ b/app/views/projects/ci/builds/_build.html.haml @@ -6,10 +6,11 @@ - stage = local_assigns.fetch(:stage, false) - coverage = local_assigns.fetch(:coverage, false) - allow_retry = local_assigns.fetch(:allow_retry, false) +- pipeline = build.pipeline.present(current_user: current_user) %tr.build.commit{ class: ('retried' if retried) } %td.status - = render "ci/status/badge", status: build.detailed_status(current_user), title: status_title(build.pipeline) + = render "ci/status/badge", status: build.detailed_status(current_user), title: pipeline.status_title %td.branch-commit - if can?(current_user, :read_build, build) @@ -51,11 +52,11 @@ - if pipeline_link %td - = link_to pipeline_path(build.pipeline) do - %span.pipeline-id ##{build.pipeline.id} + = link_to pipeline_path(pipeline) do + %span.pipeline-id ##{pipeline.id} %span by - - if build.pipeline.user - = user_avatar(user: build.pipeline.user, size: 20) + - if pipeline.user + = user_avatar(user: pipeline.user, size: 20) - else %span.monospace API From 41ff2e150c445d3b86cca5c60c353c9c21b6ed81 Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Tue, 4 Apr 2017 20:12:21 +0100 Subject: [PATCH 027/113] Removes unused code --- .../environments/folder/environments_folder_view.js | 9 --------- app/views/projects/environments/folder.html.haml | 5 +---- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/app/assets/javascripts/environments/folder/environments_folder_view.js b/app/assets/javascripts/environments/folder/environments_folder_view.js index 8abbcf0c227..d2514593e3a 100644 --- a/app/assets/javascripts/environments/folder/environments_folder_view.js +++ b/app/assets/javascripts/environments/folder/environments_folder_view.js @@ -31,12 +31,6 @@ export default Vue.component('environment-folder-view', { cssContainerClass: environmentsData.cssClass, canCreateDeployment: environmentsData.canCreateDeployment, canReadEnvironment: environmentsData.canReadEnvironment, - - // svgs - commitIconSvg: environmentsData.commitIconSvg, - playIconSvg: environmentsData.playIconSvg, - terminalIconSvg: environmentsData.terminalIconSvg, - // Pagination Properties, paginationInformation: {}, pageNumber: 1, @@ -163,9 +157,6 @@ export default Vue.component('environment-folder-view', { :environments="state.environments" :can-create-deployment="canCreateDeploymentParsed" :can-read-environment="canReadEnvironmentParsed" - :play-icon-svg="playIconSvg" - :terminal-icon-svg="terminalIconSvg" - :commit-icon-svg="commitIconSvg" :service="service"/> can?(current_user, :create_deployment, @project).to_s, "can-read-environment" => can?(current_user, :read_environment, @project).to_s, - "css-class" => container_class, - "commit-icon-svg" => custom_icon("icon_commit"), - "terminal-icon-svg" => custom_icon("icon_terminal"), - "play-icon-svg" => custom_icon("icon_play") } } + "css-class" => container_class } } From 2d4fd769a7a53f6f8ac1cd0331a8eb6b625dc8b6 Mon Sep 17 00:00:00 2001 From: Rydkin Maxim Date: Tue, 4 Apr 2017 22:21:12 +0300 Subject: [PATCH 028/113] replaced one more helper with presenter --- app/controllers/projects/pipelines_controller.rb | 2 +- app/views/projects/pipelines/_info.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index 43a1abaa662..0da0420185d 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -114,7 +114,7 @@ class Projects::PipelinesController < Projects::ApplicationController end def pipeline - @pipeline ||= project.pipelines.find_by!(id: params[:id]) + @pipeline ||= project.pipelines.find_by!(id: params[:id]).present(current_user: current_user) end def commit diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml index 17f38cef718..c9d83d23d56 100644 --- a/app/views/projects/pipelines/_info.html.haml +++ b/app/views/projects/pipelines/_info.html.haml @@ -1,6 +1,6 @@ .page-content-header .header-main-content - = render 'ci/status/badge', status: @pipeline.detailed_status(current_user), title: status_title(@pipeline) + = render 'ci/status/badge', status: @pipeline.detailed_status(current_user), title: @pipeline.status_title %strong Pipeline ##{@pipeline.id} triggered #{time_ago_with_tooltip(@pipeline.created_at)} - if @pipeline.user From d0821ae66785b18ba7af017b9498e53d3002e835 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 5 Apr 2017 10:42:31 +0100 Subject: [PATCH 029/113] Stop new merge request page tabs updating the URL The tabs on the merge_requests#new where changing the URL to URLs meant for merge_requests#show. The URL don't actually exist on the new page, so the simplest solution is to not update the URL for this page. Closes #30419 --- app/views/projects/merge_requests/_new_submit.html.haml | 3 ++- changelogs/unreleased/mr-new-page-changing-url.yml | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/mr-new-page-changing-url.yml diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml index e7fcac4c477..03069804c86 100644 --- a/app/views/projects/merge_requests/_new_submit.html.haml +++ b/app/views/projects/merge_requests/_new_submit.html.haml @@ -53,5 +53,6 @@ :javascript var merge_request = new MergeRequest({ - action: "#{(@show_changes_tab ? 'new/diffs' : 'new')}" + action: "#{(@show_changes_tab ? 'new/diffs' : 'new')}", + setUrl: false, }); diff --git a/changelogs/unreleased/mr-new-page-changing-url.yml b/changelogs/unreleased/mr-new-page-changing-url.yml new file mode 100644 index 00000000000..39de1eaa523 --- /dev/null +++ b/changelogs/unreleased/mr-new-page-changing-url.yml @@ -0,0 +1,4 @@ +--- +title: Fixed tabs on new merge request page causing incorrect URLs +merge_request: +author: From 34eea29511b9730fdab0316573d26d864d0f1e98 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 5 Apr 2017 23:33:19 +0800 Subject: [PATCH 030/113] Fix test and only show job status title if it's cancelled and the pipeline is auto-cancelled. --- app/presenters/ci/build_presenter.rb | 6 ++ app/views/projects/builds/_header.html.haml | 4 +- app/views/projects/ci/builds/_build.html.haml | 75 ++++++++++--------- .../projects/pipelines/show.html.haml_spec.rb | 10 ++- 4 files changed, 54 insertions(+), 41 deletions(-) diff --git a/app/presenters/ci/build_presenter.rb b/app/presenters/ci/build_presenter.rb index ed72ed14d72..d9970396cc6 100644 --- a/app/presenters/ci/build_presenter.rb +++ b/app/presenters/ci/build_presenter.rb @@ -11,5 +11,11 @@ module Ci def erased_by_name erased_by.name if erased_by_user? end + + def status_title + if canceled? && pipeline.auto_canceled? + "Job is redundant and is auto-canceled by Pipeline ##{pipeline.auto_canceled_by_id}" + end + end end end diff --git a/app/views/projects/builds/_header.html.haml b/app/views/projects/builds/_header.html.haml index 67da50646c7..104db85809c 100644 --- a/app/views/projects/builds/_header.html.haml +++ b/app/views/projects/builds/_header.html.haml @@ -1,8 +1,8 @@ -- pipeline = @build.pipeline.present(current_user: current_user) +- pipeline = @build.pipeline .content-block.build-header.top-area .header-content - = render 'ci/status/badge', status: @build.detailed_status(current_user), link: false, title: pipeline.status_title + = render 'ci/status/badge', status: @build.detailed_status(current_user), link: false, title: @build.status_title Job %strong.js-build-id ##{@build.id} in pipeline diff --git a/app/views/projects/ci/builds/_build.html.haml b/app/views/projects/ci/builds/_build.html.haml index c57e4e81912..238662f1125 100644 --- a/app/views/projects/ci/builds/_build.html.haml +++ b/app/views/projects/ci/builds/_build.html.haml @@ -1,3 +1,5 @@ +- job = build.present(current_user: current_user) +- pipeline = job.pipeline - admin = local_assigns.fetch(:admin, false) - ref = local_assigns.fetch(:ref, nil) - commit_sha = local_assigns.fetch(:commit_sha, nil) @@ -6,48 +8,47 @@ - stage = local_assigns.fetch(:stage, false) - coverage = local_assigns.fetch(:coverage, false) - allow_retry = local_assigns.fetch(:allow_retry, false) -- pipeline = build.pipeline.present(current_user: current_user) %tr.build.commit{ class: ('retried' if retried) } %td.status - = render "ci/status/badge", status: build.detailed_status(current_user), title: pipeline.status_title + = render "ci/status/badge", status: job.detailed_status(current_user), title: job.status_title %td.branch-commit - - if can?(current_user, :read_build, build) - = link_to namespace_project_build_url(build.project.namespace, build.project, build) do - %span.build-link ##{build.id} + - if can?(current_user, :read_build, job) + = link_to namespace_project_build_url(job.project.namespace, job.project, job) do + %span.build-link ##{job.id} - else - %span.build-link ##{build.id} + %span.build-link ##{job.id} - if ref - - if build.ref + - if job.ref .icon-container - = build.tag? ? icon('tag') : icon('code-fork') - = link_to build.ref, namespace_project_commits_path(build.project.namespace, build.project, build.ref), class: "monospace branch-name" + = job.tag? ? icon('tag') : icon('code-fork') + = link_to job.ref, namespace_project_commits_path(job.project.namespace, job.project, job.ref), class: "monospace branch-name" - else .light none .icon-container.commit-icon = custom_icon("icon_commit") - if commit_sha - = link_to build.short_sha, namespace_project_commit_path(build.project.namespace, build.project, build.sha), class: "commit-id monospace" + = link_to job.short_sha, namespace_project_commit_path(job.project.namespace, job.project, job.sha), class: "commit-id monospace" - - if build.stuck? + - if job.stuck? = icon('warning', class: 'text-warning has-tooltip', title: 'Job is stuck. Check runners.') - if retried = icon('refresh', class: 'text-warning has-tooltip', title: 'Job was retried') .label-container - - if build.tags.any? - - build.tags.each do |tag| + - if job.tags.any? + - job.tags.each do |tag| %span.label.label-primary = tag - - if build.try(:trigger_request) + - if job.try(:trigger_request) %span.label.label-info triggered - - if build.try(:allow_failure) + - if job.try(:allow_failure) %span.label.label-danger allowed to fail - - if build.action? + - if job.action? %span.label.label-info manual - if pipeline_link @@ -62,49 +63,49 @@ - if admin %td - - if build.project - = link_to build.project.name_with_namespace, admin_namespace_project_path(build.project.namespace, build.project) + - if job.project + = link_to job.project.name_with_namespace, admin_namespace_project_path(job.project.namespace, job.project) %td - - if build.try(:runner) - = runner_link(build.runner) + - if job.try(:runner) + = runner_link(job.runner) - else .light none - if stage %td - = build.stage + = job.stage %td - = build.name + = job.name %td - - if build.duration + - if job.duration %p.duration = custom_icon("icon_timer") - = duration_in_numbers(build.duration) + = duration_in_numbers(job.duration) - - if build.finished_at + - if job.finished_at %p.finished-at = icon("calendar") - %span= time_ago_with_tooltip(build.finished_at) + %span= time_ago_with_tooltip(job.finished_at) %td.coverage - - if coverage && build.try(:coverage) - #{build.coverage}% + - if coverage && job.try(:coverage) + #{job.coverage}% %td .pull-right - - if can?(current_user, :read_build, build) && build.artifacts? - = link_to download_namespace_project_build_artifacts_path(build.project.namespace, build.project, build), rel: 'nofollow', download: '', title: 'Download artifacts', class: 'btn btn-build' do + - if can?(current_user, :read_build, job) && job.artifacts? + = link_to download_namespace_project_build_artifacts_path(job.project.namespace, job.project, job), rel: 'nofollow', download: '', title: 'Download artifacts', class: 'btn btn-build' do = icon('download') - - if can?(current_user, :update_build, build) - - if build.active? - = link_to cancel_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Cancel', class: 'btn btn-build' do + - if can?(current_user, :update_build, job) + - if job.active? + = link_to cancel_namespace_project_build_path(job.project.namespace, job.project, job, return_to: request.original_url), method: :post, title: 'Cancel', class: 'btn btn-build' do = icon('remove', class: 'cred') - elsif allow_retry - - if build.playable? && !admin - = link_to play_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Play', class: 'btn btn-build' do + - if job.playable? && !admin + = link_to play_namespace_project_build_path(job.project.namespace, job.project, job, return_to: request.original_url), method: :post, title: 'Play', class: 'btn btn-build' do = custom_icon('icon_play') - - elsif build.retryable? - = link_to retry_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Retry', class: 'btn btn-build' do + - elsif job.retryable? + = link_to retry_namespace_project_build_path(job.project.namespace, job.project, job, return_to: request.original_url), method: :post, title: 'Retry', class: 'btn btn-build' do = icon('repeat') diff --git a/spec/views/projects/pipelines/show.html.haml_spec.rb b/spec/views/projects/pipelines/show.html.haml_spec.rb index dca78dec6df..bb39ec8efbf 100644 --- a/spec/views/projects/pipelines/show.html.haml_spec.rb +++ b/spec/views/projects/pipelines/show.html.haml_spec.rb @@ -5,7 +5,13 @@ describe 'projects/pipelines/show' do let(:user) { create(:user) } let(:project) { create(:project, :repository) } - let(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.id, user: user) } + + let(:pipeline) do + create(:ci_empty_pipeline, + project: project, + sha: project.commit.id, + user: user) + end before do controller.prepend_view_path('app/views/projects') @@ -21,7 +27,7 @@ describe 'projects/pipelines/show' do create(:generic_commit_status, pipeline: pipeline, stage: 'external', name: 'jenkins', stage_idx: 3) assign(:project, project) - assign(:pipeline, pipeline) + assign(:pipeline, pipeline.present(current_user: user)) assign(:commit, project.commit) allow(view).to receive(:can?).and_return(true) From 33deaaf3061bccba7bcaf591aaf9d0dc025f1e6e Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 6 Apr 2017 00:29:08 +0800 Subject: [PATCH 031/113] Remove tooltip from API and vue, follow up: https://gitlab.com/gitlab-org/gitlab-ce/issues/30511 --- .../javascripts/vue_pipelines_index/components/status.js | 7 +------ app/serializers/pipeline_entity.rb | 5 ----- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/app/assets/javascripts/vue_pipelines_index/components/status.js b/app/assets/javascripts/vue_pipelines_index/components/status.js index ece1ec89f89..21a281af438 100644 --- a/app/assets/javascripts/vue_pipelines_index/components/status.js +++ b/app/assets/javascripts/vue_pipelines_index/components/status.js @@ -36,7 +36,7 @@ export default { computed: { cssClasses() { - return `ci-status ci-${this.pipeline.details.status.group} has-tooltip`; + return `ci-status ci-${this.pipeline.details.status.group}`; }, detailsPath() { @@ -47,17 +47,12 @@ export default { content() { return `${this.svg} ${this.pipeline.details.status.text}`; }, - - tooltipTitle() { - return this.pipeline.details.status_tooltip; - }, }, template: ` diff --git a/app/serializers/pipeline_entity.rb b/app/serializers/pipeline_entity.rb index 78af8b51709..3f16dd66d54 100644 --- a/app/serializers/pipeline_entity.rb +++ b/app/serializers/pipeline_entity.rb @@ -13,7 +13,6 @@ class PipelineEntity < Grape::Entity expose :details do expose :detailed_status, as: :status, with: StatusEntity - expose :status_tooltip expose :duration expose :finished_at expose :stages, using: StageEntity @@ -82,8 +81,4 @@ class PipelineEntity < Grape::Entity def detailed_status pipeline.detailed_status(request.user) end - - def status_tooltip - pipeline.present(current_user: request.user).status_title - end end From 016e1a2906e27f519a3c67d30806a2dc5cb110b5 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 5 Apr 2017 17:24:44 +0000 Subject: [PATCH 032/113] Restore schema --- db/schema.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 9481250e81d..a7efdcbe111 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -61,6 +61,7 @@ ActiveRecord::Schema.define(version: 20170402231018) do t.boolean "shared_runners_enabled", default: true, null: false t.integer "max_artifacts_size", default: 100, null: false t.string "runners_registration_token" + t.integer "max_pages_size", default: 100, null: false t.boolean "require_two_factor_authentication", default: false t.integer "two_factor_grace_period", default: 48 t.boolean "metrics_enabled", default: false @@ -98,18 +99,17 @@ ActiveRecord::Schema.define(version: 20170402231018) do t.text "help_page_text_html" t.text "shared_runners_text_html" t.text "after_sign_up_text_html" - t.boolean "sidekiq_throttling_enabled", default: false - t.string "sidekiq_throttling_queues" - t.decimal "sidekiq_throttling_factor" t.boolean "housekeeping_enabled", default: true, null: false t.boolean "housekeeping_bitmaps_enabled", default: true, null: false t.integer "housekeeping_incremental_repack_period", default: 10, null: false t.integer "housekeeping_full_repack_period", default: 50, null: false t.integer "housekeeping_gc_period", default: 200, null: false + t.boolean "sidekiq_throttling_enabled", default: false + t.string "sidekiq_throttling_queues" + t.decimal "sidekiq_throttling_factor" t.boolean "html_emails_enabled", default: true t.string "plantuml_url" t.boolean "plantuml_enabled" - t.integer "max_pages_size", default: 100, null: false t.integer "terminal_max_session_time", default: 0, null: false t.string "default_artifacts_expire_in", default: "0", null: false t.integer "unique_ips_limit_per_user" @@ -690,8 +690,8 @@ ActiveRecord::Schema.define(version: 20170402231018) do t.integer "visibility_level", default: 20, null: false t.boolean "request_access_enabled", default: false, null: false t.datetime "deleted_at" - t.boolean "lfs_enabled" t.text "description_html" + t.boolean "lfs_enabled" t.integer "parent_id" end @@ -1243,8 +1243,8 @@ ActiveRecord::Schema.define(version: 20170402231018) do t.datetime "otp_grace_period_started_at" t.boolean "ldap_email", default: false, null: false t.boolean "external", default: false - t.string "organization" t.string "incoming_email_token" + t.string "organization" t.boolean "authorized_projects_populated" t.boolean "ghost" t.boolean "notified_of_own_activity" From 6bf1780aa81a45afdf9ddbfc32c2b9f1e0ba9285 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 6 Apr 2017 02:21:31 +0800 Subject: [PATCH 033/113] Add tests for relations and scopes, and setting --- .../projects/settings/pipelines_settings_spec.rb | 11 +++++++++++ spec/models/ci/pipeline_spec.rb | 2 ++ spec/models/concerns/has_status_spec.rb | 12 ++++++++++++ 3 files changed, 25 insertions(+) diff --git a/spec/features/projects/settings/pipelines_settings_spec.rb b/spec/features/projects/settings/pipelines_settings_spec.rb index 76cb240ea98..035c57eaa47 100644 --- a/spec/features/projects/settings/pipelines_settings_spec.rb +++ b/spec/features/projects/settings/pipelines_settings_spec.rb @@ -32,5 +32,16 @@ feature "Pipelines settings", feature: true do expect(page).to have_button('Save changes', disabled: false) expect(page).to have_field('Test coverage parsing', with: 'coverage_regex') end + + scenario 'updates auto_cancel_pending_pipelines' do + page.check('Auto-cancel redundant, pending pipelines') + click_on 'Save changes' + + expect(page.status_code).to eq(200) + expect(page).to have_button('Save changes', disabled: false) + + checkbox = find_field('project_auto_cancel_pending_pipelines') + expect(checkbox).to be_checked + end end end diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index e4a24fd63c2..38d3be926aa 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -12,10 +12,12 @@ describe Ci::Pipeline, models: true do it { is_expected.to belong_to(:project) } it { is_expected.to belong_to(:user) } + it { is_expected.to belong_to(:auto_canceled_by) } it { is_expected.to have_many(:statuses) } it { is_expected.to have_many(:trigger_requests) } it { is_expected.to have_many(:builds) } + it { is_expected.to have_many(:auto_canceled_pipelines) } it { is_expected.to validate_presence_of :sha } it { is_expected.to validate_presence_of :status } diff --git a/spec/models/concerns/has_status_spec.rb b/spec/models/concerns/has_status_spec.rb index 82abad0e2f6..67dae7cf4c0 100644 --- a/spec/models/concerns/has_status_spec.rb +++ b/spec/models/concerns/has_status_spec.rb @@ -231,6 +231,18 @@ describe HasStatus do end end + describe '.created_or_pending' do + subject { CommitStatus.created_or_pending } + + %i[created pending].each do |status| + it_behaves_like 'containing the job', status + end + + %i[running failed success].each do |status| + it_behaves_like 'not containing the job', status + end + end + describe '.finished' do subject { CommitStatus.finished } From e258e6f1471fb176e39daf6fef7785af120c2178 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 6 Apr 2017 03:10:52 +0800 Subject: [PATCH 034/113] Add test for presenters --- app/models/ci/pipeline.rb | 4 ++ app/presenters/ci/pipeline_presenter.rb | 4 -- spec/presenters/ci/build_presenter_spec.rb | 32 +++++++++++ spec/presenters/ci/pipeline_presenter_spec.rb | 54 +++++++++++++++++++ 4 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 spec/presenters/ci/pipeline_presenter_spec.rb diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 9ef35ebdd50..8aad149519e 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -219,6 +219,10 @@ module Ci statuses.cancelable.any? end + def auto_canceled? + canceled? && auto_canceled_by_id? + end + def cancel_running Gitlab::OptimisticLocking.retry_lock( statuses.cancelable) do |cancelable| diff --git a/app/presenters/ci/pipeline_presenter.rb b/app/presenters/ci/pipeline_presenter.rb index 8f9e4fa707d..b8e74bf5509 100644 --- a/app/presenters/ci/pipeline_presenter.rb +++ b/app/presenters/ci/pipeline_presenter.rb @@ -2,10 +2,6 @@ module Ci class PipelinePresenter < Gitlab::View::Presenter::Delegated presents :pipeline - def auto_canceled? - canceled? && auto_canceled_by_id? - end - def status_title "Pipeline is redundant and is auto-canceled by Pipeline ##{auto_canceled_by_id}" if auto_canceled? end diff --git a/spec/presenters/ci/build_presenter_spec.rb b/spec/presenters/ci/build_presenter_spec.rb index 7a35da38b2b..a9a8df1550d 100644 --- a/spec/presenters/ci/build_presenter_spec.rb +++ b/spec/presenters/ci/build_presenter_spec.rb @@ -57,6 +57,38 @@ describe Ci::BuildPresenter do end end + describe '#status_title' do + context 'when build is canceled' do + before do + expect(presenter).to receive(:canceled?).and_return(true) + end + + context 'when pipeline is auto-canceled' do + before do + expect(pipeline).to receive(:auto_canceled?).and_return(true) + expect(pipeline).to receive(:auto_canceled_by_id).and_return(1) + end + + it 'shows that the job is auto-canceled' do + status_title = presenter.status_title + + expect(status_title).to include('auto-canceled') + expect(status_title).to include('Pipeline #1') + end + end + + context 'when pipeline is not auto-canceled' do + before do + expect(pipeline).to receive(:auto_canceled?).and_return(false) + end + + it 'shows that the job is auto-canceled' do + expect(presenter.status_title).to be_nil + end + end + end + end + describe 'quack like a Ci::Build permission-wise' do context 'user is not allowed' do let(:project) { build_stubbed(:empty_project, public_builds: false) } diff --git a/spec/presenters/ci/pipeline_presenter_spec.rb b/spec/presenters/ci/pipeline_presenter_spec.rb new file mode 100644 index 00000000000..449e45c1f4c --- /dev/null +++ b/spec/presenters/ci/pipeline_presenter_spec.rb @@ -0,0 +1,54 @@ +require 'spec_helper' + +describe Ci::PipelinePresenter do + let(:project) { create(:empty_project) } + let(:pipeline) { create(:ci_pipeline, project: project) } + + subject(:presenter) do + described_class.new(pipeline) + end + + it 'inherits from Gitlab::View::Presenter::Delegated' do + expect(described_class.superclass).to eq(Gitlab::View::Presenter::Delegated) + end + + describe '#initialize' do + it 'takes a pipeline and optional params' do + expect { presenter }.not_to raise_error + end + + it 'exposes pipeline' do + expect(presenter.pipeline).to eq(pipeline) + end + + it 'forwards missing methods to pipeline' do + expect(presenter.ref).to eq(pipeline.ref) + end + end + + describe '#status_title' do + context 'when pipeline is auto-canceled' do + before do + expect(pipeline).to receive(:auto_canceled?).and_return(true) + expect(pipeline).to receive(:auto_canceled_by_id).and_return(1) + end + + it 'shows that the pipeline is auto-canceled' do + status_title = presenter.status_title + + expect(status_title).to include('auto-canceled') + expect(status_title).to include('Pipeline #1') + end + end + + context 'when pipeline is not auto-canceled' do + before do + expect(pipeline).to receive(:auto_canceled?).and_return(false) + end + + it 'shows that the job is auto-canceled' do + expect(presenter.status_title).to be_nil + end + end + end +end From f7014cd5bc776f9829818e535baf9db70387a416 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 6 Apr 2017 03:23:36 +0800 Subject: [PATCH 035/113] Add a test to make sure it's not auto-canceling whenever the feature is disabled in the project. --- .../ci/create_pipeline_service_spec.rb | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb index a3330367f96..fa5014cee07 100644 --- a/spec/services/ci/create_pipeline_service_spec.rb +++ b/spec/services/ci/create_pipeline_service_spec.rb @@ -21,6 +21,12 @@ describe Ci::CreatePipelineService, services: true do context 'valid params' do let(:pipeline) { execute_service } + let(:pipeline_on_previous_commit) do + execute_service( + after: previous_commit_sha_from_ref('master') + ) + end + it { expect(pipeline).to be_kind_of(Ci::Pipeline) } it { expect(pipeline).to be_valid } it { expect(pipeline).to eq(project.pipelines.last) } @@ -29,20 +35,10 @@ describe Ci::CreatePipelineService, services: true do it { expect(pipeline.builds.first).to be_kind_of(Ci::Build) } context 'auto-cancel enabled' do - let(:pipeline_on_previous_commit) do - execute_service( - after: previous_commit_sha_from_ref('master') - ) - end - before do project.update(auto_cancel_pending_pipelines: 'enabled') end - def previous_commit_sha_from_ref(ref) - project.commit(ref).parent.sha - end - it 'does not cancel HEAD pipeline' do pipeline pipeline_on_previous_commit @@ -81,6 +77,24 @@ describe Ci::CreatePipelineService, services: true do expect(pending_pipeline.reload).to have_attributes(status: 'pending', auto_canceled_by_id: nil) end end + + context 'auto-cancel disabled' do + before do + project.update(auto_cancel_pending_pipelines: 'disabled') + end + + it 'does not auto cancel pending non-HEAD pipelines' do + pipeline_on_previous_commit + pipeline + + expect(pipeline_on_previous_commit.reload) + .to have_attributes(status: 'pending', auto_canceled_by_id: nil) + end + end + + def previous_commit_sha_from_ref(ref) + project.commit(ref).parent.sha + end end context "skip tag if there is no build for it" do From 4a030326605e2ab2ce7b520d14c6ac3ad020d58b Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 6 Apr 2017 14:41:27 +0800 Subject: [PATCH 036/113] Fix rolling back for MySQL --- ...620_add_index_to_project_authorizations.rb | 3 ++- ...uto_cancel_pending_pipelines_to_project.rb | 18 ----------------- ...329_add_auto_canceled_by_id_to_pipeline.rb | 20 ------------------- ..._canceled_by_id_foreign_key_to_pipeline.rb | 18 ----------------- 4 files changed, 2 insertions(+), 57 deletions(-) diff --git a/db/migrate/20170130204620_add_index_to_project_authorizations.rb b/db/migrate/20170130204620_add_index_to_project_authorizations.rb index 629b49436e3..0884296131d 100644 --- a/db/migrate/20170130204620_add_index_to_project_authorizations.rb +++ b/db/migrate/20170130204620_add_index_to_project_authorizations.rb @@ -6,7 +6,8 @@ class AddIndexToProjectAuthorizations < ActiveRecord::Migration disable_ddl_transaction! def up - add_concurrent_index(:project_authorizations, :project_id) + add_concurrent_index(:project_authorizations, :project_id) unless + index_exists?(:project_authorizations, :project_id) end def down diff --git a/db/migrate/20170305180853_add_auto_cancel_pending_pipelines_to_project.rb b/db/migrate/20170305180853_add_auto_cancel_pending_pipelines_to_project.rb index 48ee9268dea..aa64f2dddca 100644 --- a/db/migrate/20170305180853_add_auto_cancel_pending_pipelines_to_project.rb +++ b/db/migrate/20170305180853_add_auto_cancel_pending_pipelines_to_project.rb @@ -1,26 +1,8 @@ -# 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 diff --git a/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb b/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb index 813813225e0..1690ce90564 100644 --- a/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb +++ b/db/migrate/20170312114329_add_auto_canceled_by_id_to_pipeline.rb @@ -1,28 +1,8 @@ -# See http://doc.gitlab.com/ce/development/migration_style_guide.html -# for more information on how to write migrations for GitLab. - class AddAutoCanceledByIdToPipeline < 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_pipelines, :auto_canceled_by_id, :integer end diff --git a/db/migrate/20170312114529_add_auto_canceled_by_id_foreign_key_to_pipeline.rb b/db/migrate/20170312114529_add_auto_canceled_by_id_foreign_key_to_pipeline.rb index c9dd5be9799..1e7b02ecf0e 100644 --- a/db/migrate/20170312114529_add_auto_canceled_by_id_foreign_key_to_pipeline.rb +++ b/db/migrate/20170312114529_add_auto_canceled_by_id_foreign_key_to_pipeline.rb @@ -1,26 +1,8 @@ -# See http://doc.gitlab.com/ce/development/migration_style_guide.html -# for more information on how to write migrations for GitLab. - class AddAutoCanceledByIdForeignKeyToPipeline < 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 up From 06b4ea243fef27fa79a201148f07c25df375f57d Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 6 Apr 2017 14:45:01 +0800 Subject: [PATCH 037/113] Fix a view test by using presenter --- spec/views/projects/builds/show.html.haml_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/views/projects/builds/show.html.haml_spec.rb b/spec/views/projects/builds/show.html.haml_spec.rb index 55b64808fb3..0f39df0f250 100644 --- a/spec/views/projects/builds/show.html.haml_spec.rb +++ b/spec/views/projects/builds/show.html.haml_spec.rb @@ -9,7 +9,7 @@ describe 'projects/builds/show', :view do end before do - assign(:build, build) + assign(:build, build.present) assign(:project, project) allow(view).to receive(:can?).and_return(true) From 062806e47da00dde37a2a62d7a5c6ede8341582c Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Tue, 4 Apr 2017 23:52:59 +0200 Subject: [PATCH 038/113] Define baseline for test for pipelines serializer --- spec/factories/ci/triggers.rb | 2 +- spec/serializers/pipeline_serializer_spec.rb | 29 ++++++++++++++++++++ spec/support/query_recorder.rb | 14 ++++++++-- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/spec/factories/ci/triggers.rb b/spec/factories/ci/triggers.rb index a27b04424e5..40c4663c6d8 100644 --- a/spec/factories/ci/triggers.rb +++ b/spec/factories/ci/triggers.rb @@ -1,7 +1,7 @@ FactoryGirl.define do factory :ci_trigger_without_token, class: Ci::Trigger do factory :ci_trigger do - token 'token' + sequence(:token) { |n| "token#{n}" } end end end diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb index 8642b803844..657d10aae99 100644 --- a/spec/serializers/pipeline_serializer_spec.rb +++ b/spec/serializers/pipeline_serializer_spec.rb @@ -93,6 +93,35 @@ describe PipelineSerializer do end end end + + context 'number of queries' do + let(:resource) { Ci::Pipeline.all } + + before do + Ci::Pipeline::AVAILABLE_STATUSES.each do |status| + create_pipeline(status) + end + end + + it "verifies number of queries" do + recorded = ActiveRecord::QueryRecorder.new { subject } + expect(recorded.count).to be_within(320).of(10) + end + + def create_pipeline(status) + create(:ci_empty_pipeline, status: status).tap do |pipeline| + Ci::Build::AVAILABLE_STATUSES.each do |status| + create_build(pipeline, status, status) + end + end + end + + def create_build(pipeline, stage, status) + create(:ci_build, :tags, :triggered, :artifacts, + pipeline: pipeline, stage: stage, + name: stage, status: status) + end + end end describe '#represent_status' do diff --git a/spec/support/query_recorder.rb b/spec/support/query_recorder.rb index e40d5ebd9a8..55b531b4cf7 100644 --- a/spec/support/query_recorder.rb +++ b/spec/support/query_recorder.rb @@ -1,21 +1,29 @@ module ActiveRecord class QueryRecorder - attr_reader :log + attr_reader :log, :cached def initialize(&block) @log = [] + @cached = [] ActiveSupport::Notifications.subscribed(method(:callback), 'sql.active_record', &block) end def callback(name, start, finish, message_id, values) - return if %w(CACHE SCHEMA).include?(values[:name]) - @log << values[:sql] + if values[:name]&.include?("CACHE") + @cached << values[:sql] + elsif !values[:name]&.include?("SCHEMA") + @log << values[:sql] + end end def count @log.count end + def cached_count + @cached.count + end + def log_message @log.join("\n\n") end From 3015e768f53806abf788b106d8be84486f30cd10 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Thu, 6 Apr 2017 14:31:29 +0200 Subject: [PATCH 039/113] Revert "Reverse pipelines controller changes" This reverts commit 0a60cdb110754a5e894ca1a2aa619842f2d98d1a. --- .../projects/pipelines_controller.rb | 49 +++++++++++++++---- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index 43a1abaa662..f8aba16203e 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -1,3 +1,35 @@ +module ActiveRecord + class QueryRecorder + attr_reader :log + attr_reader :start + attr_reader :end + + def initialize(&block) + @log = [] + @start = Time.now + ActiveSupport::Notifications.subscribed(method(:callback), 'sql.active_record', &block) + @end = Time.now + end + + def callback(name, start, finish, message_id, values) + return if %w(SCHEMA).include?(values[:name]) + @log << values[:sql] + end + + def time + @end - @start + end + + def count + @log.count + end + + def log_message + @log.join("\n\n") + end + end +end + class Projects::PipelinesController < Projects::ApplicationController before_action :pipeline, except: [:index, :new, :create, :charts] before_action :commit, only: [:show, :builds] @@ -29,18 +61,15 @@ class Projects::PipelinesController < Projects::ApplicationController respond_to do |format| format.html format.json do - render json: { - pipelines: PipelineSerializer + result = nil + queries = ActiveRecord::QueryRecorder.new do + result = PipelineSerializer .new(project: @project, user: @current_user) .with_pagination(request, response) - .represent(@pipelines), - count: { - all: @pipelines_count, - running: @running_count, - pending: @pending_count, - finished: @finished_count, - } - } + .represent(@pipelines) + end + + render json: { aa_queries: queries.count, aa_time: queries.time, result: result } end end end From 8a1c12aa6f9f0f4d7815b5c7c945caadcfc5e10d Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Thu, 6 Apr 2017 14:31:38 +0200 Subject: [PATCH 040/113] Introduce endpoint optimisations --- app/models/ci/build.rb | 10 ++------ app/models/ci/pipeline.rb | 27 +++++++++----------- app/models/project.rb | 14 +++++++--- app/serializers/pipeline_entity.rb | 8 +++--- app/services/ci/retry_pipeline_service.rb | 4 +-- spec/serializers/pipeline_serializer_spec.rb | 2 +- 6 files changed, 31 insertions(+), 34 deletions(-) diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index ad0be70c32a..9ef55fa6e18 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -103,18 +103,13 @@ module Ci end def playable? - project.builds_enabled? && has_commands? && - action? && manual? + action? && manual? end def action? self.when == 'manual' end - def has_commands? - commands.present? - end - def play(current_user) # Try to queue a current build if self.enqueue @@ -131,8 +126,7 @@ module Ci end def retryable? - project.builds_enabled? && has_commands? && - (success? || failed? || canceled?) + success? || failed? || canceled? end def retried? diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 49dec770096..7f9b0aaa0f1 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -12,6 +12,12 @@ module Ci has_many :builds, foreign_key: :commit_id has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id + has_many :pending_builds, -> { pending }, foreign_key: :commit_id, class_name: 'Ci::Build' + has_many :retryable_builds, -> { latest.failed_or_canceled }, foreign_key: :commit_id, class_name: 'Ci::Build' + has_many :cancelable_statuses, -> { cancelable }, foreign_key: :commit_id, class_name: 'CommitStatus' + has_many :manual_actions, -> { latest.manual_actions }, foreign_key: :commit_id, class_name: 'Ci::Build' + has_many :artifacts, -> { latest.with_artifacts_not_expired }, foreign_key: :commit_id, class_name: 'Ci::Build' + delegate :id, to: :project, prefix: true validates :sha, presence: { unless: :importing? } @@ -160,10 +166,6 @@ module Ci end end - def artifacts - builds.latest.with_artifacts_not_expired.includes(project: [:namespace]) - end - def valid_commit_sha if self.sha == Gitlab::Git::BLANK_SHA self.errors.add(:sha, " cant be 00000000 (branch removal)") @@ -200,27 +202,22 @@ module Ci !tag? end - def manual_actions - builds.latest.manual_actions.includes(project: [:namespace]) - end - def stuck? - builds.pending.includes(:project).any?(&:stuck?) + pending_builds.any?(&:stuck?) end def retryable? - builds.latest.failed_or_canceled.any?(&:retryable?) + retryable_builds.any? end def cancelable? - statuses.cancelable.any? + cancelable_statuses.any? end def cancel_running - Gitlab::OptimisticLocking.retry_lock( - statuses.cancelable) do |cancelable| - cancelable.find_each(&:cancel) - end + Gitlab::OptimisticLocking.retry_lock(cancelable_statuses) do |cancelable| + cancelable.find_each(&:cancel) + end end def retry_failed(current_user) diff --git a/app/models/project.rb b/app/models/project.rb index 83660d8c431..4da0e016756 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1093,15 +1093,23 @@ class Project < ActiveRecord::Base end def shared_runners - shared_runners_available? ? Ci::Runner.shared : Ci::Runner.none + @shared_runners ||= shared_runners_available? ? Ci::Runner.shared : Ci::Runner.none + end + + def active_runners + @active_runners ||= runners.active + end + + def active_shared_runners + @active_shared_runners ||= shared_runners.active end def any_runners?(&block) - if runners.active.any?(&block) + if active_runners.any?(&block) return true end - shared_runners.active.any?(&block) + active_shared_runners.any?(&block) end def valid_runners_token?(token) diff --git a/app/serializers/pipeline_entity.rb b/app/serializers/pipeline_entity.rb index 3f16dd66d54..ad8b4d43e8f 100644 --- a/app/serializers/pipeline_entity.rb +++ b/app/serializers/pipeline_entity.rb @@ -69,13 +69,13 @@ class PipelineEntity < Grape::Entity alias_method :pipeline, :object def can_retry? - pipeline.retryable? && - can?(request.user, :update_pipeline, pipeline) + can?(request.user, :update_pipeline, pipeline) && + pipeline.retryable? end def can_cancel? - pipeline.cancelable? && - can?(request.user, :update_pipeline, pipeline) + can?(request.user, :update_pipeline, pipeline) && + pipeline.cancelable? end def detailed_status diff --git a/app/services/ci/retry_pipeline_service.rb b/app/services/ci/retry_pipeline_service.rb index f72ddbf690c..ecc6173a96a 100644 --- a/app/services/ci/retry_pipeline_service.rb +++ b/app/services/ci/retry_pipeline_service.rb @@ -7,9 +7,7 @@ module Ci raise Gitlab::Access::AccessDeniedError end - pipeline.builds.latest.failed_or_canceled.find_each do |build| - next unless build.retryable? - + pipeline.retryable_builds.find_each do |build| Ci::RetryBuildService.new(project, current_user) .reprocess(build) end diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb index 657d10aae99..add43182cc2 100644 --- a/spec/serializers/pipeline_serializer_spec.rb +++ b/spec/serializers/pipeline_serializer_spec.rb @@ -105,7 +105,7 @@ describe PipelineSerializer do it "verifies number of queries" do recorded = ActiveRecord::QueryRecorder.new { subject } - expect(recorded.count).to be_within(320).of(10) + expect(recorded.count).to be_within(200).of(10) end def create_pipeline(status) From b828a98c1c07fa07a0e80b73eadf568d68aefeea Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Thu, 6 Apr 2017 15:04:26 +0200 Subject: [PATCH 041/113] Optimise includes --- app/serializers/pipeline_serializer.rb | 10 +++++++++- spec/serializers/pipeline_serializer_spec.rb | 3 ++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/app/serializers/pipeline_serializer.rb b/app/serializers/pipeline_serializer.rb index 7829df9fada..efeccebec41 100644 --- a/app/serializers/pipeline_serializer.rb +++ b/app/serializers/pipeline_serializer.rb @@ -13,7 +13,15 @@ class PipelineSerializer < BaseSerializer def represent(resource, opts = {}) if resource.is_a?(ActiveRecord::Relation) - resource = resource.includes(project: :namespace) + resource = resource.includes(:project) + resource = resource.includes(:pending_builds, + :retryable_builds, + :cancelable_statuses, + :manual_actions, + :artifacts) + resource = resource.includes(pending_builds: :project) + resource = resource.includes(manual_actions: :project) + resource = resource.includes(artifacts: :project) end if paginated? diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb index add43182cc2..54cb9babe45 100644 --- a/spec/serializers/pipeline_serializer_spec.rb +++ b/spec/serializers/pipeline_serializer_spec.rb @@ -105,7 +105,8 @@ describe PipelineSerializer do it "verifies number of queries" do recorded = ActiveRecord::QueryRecorder.new { subject } - expect(recorded.count).to be_within(200).of(10) + expect(recorded.count).to be_within(10).of(230) + expect(recorded.cached_count).to be_within(5).of(5) end def create_pipeline(status) From 62919a17e16de107c7fe9c1952567b3908a8f151 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Thu, 6 Apr 2017 15:14:40 +0200 Subject: [PATCH 042/113] Update tests and associations --- app/serializers/pipeline_serializer.rb | 9 +++++---- spec/serializers/pipeline_serializer_spec.rb | 7 +++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/serializers/pipeline_serializer.rb b/app/serializers/pipeline_serializer.rb index efeccebec41..d9dbd5608d6 100644 --- a/app/serializers/pipeline_serializer.rb +++ b/app/serializers/pipeline_serializer.rb @@ -13,15 +13,16 @@ class PipelineSerializer < BaseSerializer def represent(resource, opts = {}) if resource.is_a?(ActiveRecord::Relation) - resource = resource.includes(:project) resource = resource.includes(:pending_builds, :retryable_builds, :cancelable_statuses, :manual_actions, - :artifacts) + :artifacts, + :trigger_requests) resource = resource.includes(pending_builds: :project) - resource = resource.includes(manual_actions: :project) - resource = resource.includes(artifacts: :project) + resource = resource.includes(project: :namespace) + resource = resource.includes(manual_actions: { project: :namespace }) + resource = resource.includes(artifacts: { project: :namespace }) end if paginated? diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb index 54cb9babe45..997f40662c5 100644 --- a/spec/serializers/pipeline_serializer_spec.rb +++ b/spec/serializers/pipeline_serializer_spec.rb @@ -101,6 +101,13 @@ describe PipelineSerializer do Ci::Pipeline::AVAILABLE_STATUSES.each do |status| create_pipeline(status) end + + RequestStore.begin! + end + + after do + RequestStore.end! + RequestStore.clear! end it "verifies number of queries" do From 93f9e71b0dc47d88f1077ccaeaeb5ea91e51c0fc Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Thu, 6 Apr 2017 15:21:25 +0200 Subject: [PATCH 043/113] Further optimise queries --- app/serializers/pipeline_serializer.rb | 18 ++++++++++-------- spec/serializers/pipeline_serializer_spec.rb | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/app/serializers/pipeline_serializer.rb b/app/serializers/pipeline_serializer.rb index d9dbd5608d6..08a664ad4bf 100644 --- a/app/serializers/pipeline_serializer.rb +++ b/app/serializers/pipeline_serializer.rb @@ -13,16 +13,18 @@ class PipelineSerializer < BaseSerializer def represent(resource, opts = {}) if resource.is_a?(ActiveRecord::Relation) - resource = resource.includes(:pending_builds, + project_includes = [ { namespace: :route }, :route ] + resource = resource.includes( :retryable_builds, :cancelable_statuses, - :manual_actions, - :artifacts, - :trigger_requests) - resource = resource.includes(pending_builds: :project) - resource = resource.includes(project: :namespace) - resource = resource.includes(manual_actions: { project: :namespace }) - resource = resource.includes(artifacts: { project: :namespace }) + :trigger_requests + ) + resource = resource.includes( + project: project_includes, + pending_builds: [:project], + manual_actions: { project: project_includes }, + artifacts: { project: project_includes } + ) end if paginated? diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb index 997f40662c5..75cfd000809 100644 --- a/spec/serializers/pipeline_serializer_spec.rb +++ b/spec/serializers/pipeline_serializer_spec.rb @@ -112,7 +112,7 @@ describe PipelineSerializer do it "verifies number of queries" do recorded = ActiveRecord::QueryRecorder.new { subject } - expect(recorded.count).to be_within(10).of(230) + expect(recorded.count).to be_within(10).of(93) expect(recorded.cached_count).to be_within(5).of(5) end From 057c0d7a5c062f3030bcc46614ef2442009002de Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 6 Apr 2017 21:32:56 +0800 Subject: [PATCH 044/113] Also track auto-cancelling in jobs, detail: Not only tracking auto-cancelling in pipelines, we'll also track this in jobs because pipelines could be retried and the information would get lost when this happened. Also erase auto-cancelling relation for pipelines when they're retried. --- app/models/ci/pipeline.rb | 19 +++++++++- app/models/commit_status.rb | 5 +++ app/presenters/ci/build_presenter.rb | 4 +- app/presenters/ci/pipeline_presenter.rb | 4 +- app/services/ci/create_pipeline_service.rb | 3 +- ...58_add_auto_canceled_by_id_to_ci_builds.rb | 9 +++++ ...canceled_by_id_foreign_key_to_ci_builds.rb | 22 +++++++++++ db/schema.rb | 2 + spec/lib/gitlab/import_export/all_models.yml | 2 + .../import_export/safe_model_attributes.yml | 1 + spec/models/ci/pipeline_spec.rb | 37 +++++++++++++++++++ spec/models/commit_status_spec.rb | 26 +++++++++++++ spec/presenters/ci/build_presenter_spec.rb | 34 +++++++---------- spec/presenters/ci/pipeline_presenter_spec.rb | 2 +- 14 files changed, 143 insertions(+), 27 deletions(-) create mode 100644 db/migrate/20170406114958_add_auto_canceled_by_id_to_ci_builds.rb create mode 100644 db/migrate/20170406115029_add_auto_canceled_by_id_foreign_key_to_ci_builds.rb diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 8aad149519e..e03def25755 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -11,6 +11,8 @@ module Ci belongs_to :auto_canceled_by, class_name: 'Ci::Pipeline' has_many :auto_canceled_pipelines, class_name: 'Ci::Pipeline', foreign_key: 'auto_canceled_by_id' + has_many :auto_canceled_jobs, class_name: 'CommitStatus', foreign_key: 'auto_canceled_by_id' + has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id has_many :builds, foreign_key: :commit_id has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id @@ -93,6 +95,10 @@ module Ci PipelineNotificationWorker.perform_async(pipeline.id) end end + + after_transition :canceled => any - [:canceled] do |pipeline| + pipeline.update(auto_canceled_by: nil) + end end # ref can't be HEAD or SHA, can only be branch/tag name @@ -226,10 +232,21 @@ module Ci def cancel_running Gitlab::OptimisticLocking.retry_lock( statuses.cancelable) do |cancelable| - cancelable.find_each(&:cancel) + cancelable.find_each do |job| + yield(job) if block_given? + job.cancel + end end end + def auto_cancel_running(pipeline) + update(auto_canceled_by: pipeline) + + cancel_running do |job| + job.auto_canceled_by = pipeline + end + end + def retry_failed(current_user) Ci::RetryPipelineService.new(project, current_user) .execute(self) diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index 17b322b5ae3..2c4033146bf 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -7,6 +7,7 @@ class CommitStatus < ActiveRecord::Base belongs_to :project belongs_to :pipeline, class_name: 'Ci::Pipeline', foreign_key: :commit_id + belongs_to :auto_canceled_by, class_name: 'Ci::Pipeline' belongs_to :user delegate :commit, to: :pipeline @@ -137,6 +138,10 @@ class CommitStatus < ActiveRecord::Base false end + def auto_canceled? + canceled? && auto_canceled_by_id? + end + # Added in 9.0 to keep backward compatibility for projects exported in 8.17 # and prior. def gl_project_id diff --git a/app/presenters/ci/build_presenter.rb b/app/presenters/ci/build_presenter.rb index d9970396cc6..c495c3f39bb 100644 --- a/app/presenters/ci/build_presenter.rb +++ b/app/presenters/ci/build_presenter.rb @@ -13,8 +13,8 @@ module Ci end def status_title - if canceled? && pipeline.auto_canceled? - "Job is redundant and is auto-canceled by Pipeline ##{pipeline.auto_canceled_by_id}" + if auto_canceled? + "Job is redundant and is auto-canceled by Pipeline ##{auto_canceled_by_id}" end end end diff --git a/app/presenters/ci/pipeline_presenter.rb b/app/presenters/ci/pipeline_presenter.rb index b8e74bf5509..a542bdd8295 100644 --- a/app/presenters/ci/pipeline_presenter.rb +++ b/app/presenters/ci/pipeline_presenter.rb @@ -3,7 +3,9 @@ module Ci presents :pipeline def status_title - "Pipeline is redundant and is auto-canceled by Pipeline ##{auto_canceled_by_id}" if auto_canceled? + if auto_canceled? + "Pipeline is redundant and is auto-canceled by Pipeline ##{auto_canceled_by_id}" + end end end end diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index f944c869922..21350be5557 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -68,8 +68,7 @@ module Ci def cancel_pending_pipelines Gitlab::OptimisticLocking.retry_lock(auto_cancelable_pipelines) do |cancelables| cancelables.find_each do |cancelable| - cancelable.cancel_running - cancelable.update_attributes(auto_canceled_by_id: pipeline.id) + cancelable.auto_cancel_running(pipeline) end end end diff --git a/db/migrate/20170406114958_add_auto_canceled_by_id_to_ci_builds.rb b/db/migrate/20170406114958_add_auto_canceled_by_id_to_ci_builds.rb new file mode 100644 index 00000000000..c1d803b4308 --- /dev/null +++ b/db/migrate/20170406114958_add_auto_canceled_by_id_to_ci_builds.rb @@ -0,0 +1,9 @@ +class AddAutoCanceledByIdToCiBuilds < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + add_column :ci_builds, :auto_canceled_by_id, :integer + end +end diff --git a/db/migrate/20170406115029_add_auto_canceled_by_id_foreign_key_to_ci_builds.rb b/db/migrate/20170406115029_add_auto_canceled_by_id_foreign_key_to_ci_builds.rb new file mode 100644 index 00000000000..3004683933b --- /dev/null +++ b/db/migrate/20170406115029_add_auto_canceled_by_id_foreign_key_to_ci_builds.rb @@ -0,0 +1,22 @@ +class AddAutoCanceledByIdForeignKeyToCiBuilds < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def up + on_delete = + if Gitlab::Database.mysql? + :nullify + else + 'SET NULL' + end + + add_concurrent_foreign_key :ci_builds, :ci_pipelines, column: :auto_canceled_by_id, on_delete: on_delete + end + + def down + remove_foreign_key :ci_builds, column: :auto_canceled_by_id + end +end diff --git a/db/schema.rb b/db/schema.rb index 59dbe9fd69a..afc67dba702 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -223,6 +223,7 @@ ActiveRecord::Schema.define(version: 20170405080720) do t.string "token" t.integer "lock_version" t.string "coverage_regex" + t.integer "auto_canceled_by_id" end add_index "ci_builds", ["commit_id", "stage_idx", "created_at"], name: "index_ci_builds_on_commit_id_and_stage_idx_and_created_at", using: :btree @@ -1300,6 +1301,7 @@ ActiveRecord::Schema.define(version: 20170405080720) do add_foreign_key "boards", "projects" add_foreign_key "chat_teams", "namespaces", on_delete: :cascade + add_foreign_key "ci_builds", "ci_pipelines", column: "auto_canceled_by_id", name: "fk_a2141b1522", on_delete: :nullify add_foreign_key "ci_pipelines", "ci_pipelines", column: "auto_canceled_by_id", name: "fk_262d4c2d19", on_delete: :nullify add_foreign_key "ci_triggers", "users", column: "owner_id", name: "fk_e8e10d1964", on_delete: :cascade add_foreign_key "issue_metrics", "issues", on_delete: :cascade diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 8aa8e3fc1cd..5f3a83d5792 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -91,10 +91,12 @@ pipelines: - trigger_requests - auto_canceled_by - auto_canceled_pipelines +- auto_canceled_jobs statuses: - project - pipeline - user +- auto_canceled_by variables: - project triggers: diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml index 15b8fa07040..50154a67908 100644 --- a/spec/lib/gitlab/import_export/safe_model_attributes.yml +++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml @@ -224,6 +224,7 @@ CommitStatus: - token - lock_version - coverage_regex +- auto_canceled_by_id Ci::Variable: - id - project_id diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 38d3be926aa..3595601a72d 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -136,6 +136,43 @@ describe Ci::Pipeline, models: true do end end + describe '#auto_canceled?' do + subject { pipeline.auto_canceled? } + + context 'when it is canceled' do + before do + pipeline.cancel + end + + context 'when there is auto_canceled_by' do + before do + pipeline.update(auto_canceled_by: create(:ci_empty_pipeline)) + end + + it 'is auto canceled' do + is_expected.to be_truthy + end + end + + context 'when there is no auto_canceled_by' do + it 'is not auto canceled' do + is_expected.to be_falsey + end + end + + context 'when it is retried and canceled manually' do + before do + pipeline.enqueue + pipeline.cancel + end + + it 'is not auto canceled' do + is_expected.to be_falsey + end + end + end + end + describe 'pipeline stages' do before do create(:commit_status, pipeline: pipeline, diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb index 7343b735a74..3bffb8dba72 100644 --- a/spec/models/commit_status_spec.rb +++ b/spec/models/commit_status_spec.rb @@ -101,6 +101,32 @@ describe CommitStatus, :models do end end + describe '#auto_canceled?' do + subject { commit_status.auto_canceled? } + + context 'when it is canceled' do + before do + commit_status.cancel + end + + context 'when there is auto_canceled_by' do + before do + commit_status.update(auto_cancel_by: create(:ci_empty_pipeline)) + end + + it 'is auto canceled' do + is_expected.to be_truthy + end + end + + context 'when there is no auto_canceled_by' do + it 'is not auto canceled' do + is_expected.to be_falsey + end + end + end + end + describe '#duration' do subject { commit_status.duration } diff --git a/spec/presenters/ci/build_presenter_spec.rb b/spec/presenters/ci/build_presenter_spec.rb index a9a8df1550d..ebb599bb48c 100644 --- a/spec/presenters/ci/build_presenter_spec.rb +++ b/spec/presenters/ci/build_presenter_spec.rb @@ -58,33 +58,27 @@ describe Ci::BuildPresenter do end describe '#status_title' do - context 'when build is canceled' do + context 'when build is auto-canceled' do before do - expect(presenter).to receive(:canceled?).and_return(true) + expect(build).to receive(:auto_canceled?).and_return(true) + expect(build).to receive(:auto_canceled_by_id).and_return(1) end - context 'when pipeline is auto-canceled' do - before do - expect(pipeline).to receive(:auto_canceled?).and_return(true) - expect(pipeline).to receive(:auto_canceled_by_id).and_return(1) - end + it 'shows that the job is auto-canceled' do + status_title = presenter.status_title - it 'shows that the job is auto-canceled' do - status_title = presenter.status_title + expect(status_title).to include('auto-canceled') + expect(status_title).to include('Pipeline #1') + end + end - expect(status_title).to include('auto-canceled') - expect(status_title).to include('Pipeline #1') - end + context 'when build is not auto-canceled' do + before do + expect(build).to receive(:auto_canceled?).and_return(false) end - context 'when pipeline is not auto-canceled' do - before do - expect(pipeline).to receive(:auto_canceled?).and_return(false) - end - - it 'shows that the job is auto-canceled' do - expect(presenter.status_title).to be_nil - end + it 'does not have a status title' do + expect(presenter.status_title).to be_nil end end end diff --git a/spec/presenters/ci/pipeline_presenter_spec.rb b/spec/presenters/ci/pipeline_presenter_spec.rb index 449e45c1f4c..9134d1cc31c 100644 --- a/spec/presenters/ci/pipeline_presenter_spec.rb +++ b/spec/presenters/ci/pipeline_presenter_spec.rb @@ -46,7 +46,7 @@ describe Ci::PipelinePresenter do expect(pipeline).to receive(:auto_canceled?).and_return(false) end - it 'shows that the job is auto-canceled' do + it 'does not have a status title' do expect(presenter.status_title).to be_nil end end From 227a664e5e7e6c9c986b4a34ded84fa74af64001 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Thu, 6 Apr 2017 15:35:40 +0200 Subject: [PATCH 045/113] Next round --- app/serializers/pipeline_serializer.rb | 17 +++++++---------- spec/serializers/pipeline_serializer_spec.rb | 7 ++++--- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/app/serializers/pipeline_serializer.rb b/app/serializers/pipeline_serializer.rb index 08a664ad4bf..0af9ef0e3f7 100644 --- a/app/serializers/pipeline_serializer.rb +++ b/app/serializers/pipeline_serializer.rb @@ -13,18 +13,15 @@ class PipelineSerializer < BaseSerializer def represent(resource, opts = {}) if resource.is_a?(ActiveRecord::Relation) - project_includes = [ { namespace: :route }, :route ] - resource = resource.includes( + resource = resource.includes([ :retryable_builds, :cancelable_statuses, - :trigger_requests - ) - resource = resource.includes( - project: project_includes, - pending_builds: [:project], - manual_actions: { project: project_includes }, - artifacts: { project: project_includes } - ) + :trigger_requests, + :project, + { pending_builds: :project }, + { manual_actions: :project }, + { artifacts: :project } + ]) end if paginated? diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb index 75cfd000809..f6249ab4664 100644 --- a/spec/serializers/pipeline_serializer_spec.rb +++ b/spec/serializers/pipeline_serializer_spec.rb @@ -96,6 +96,7 @@ describe PipelineSerializer do context 'number of queries' do let(:resource) { Ci::Pipeline.all } + let(:project) { create(:empty_project) } before do Ci::Pipeline::AVAILABLE_STATUSES.each do |status| @@ -112,12 +113,12 @@ describe PipelineSerializer do it "verifies number of queries" do recorded = ActiveRecord::QueryRecorder.new { subject } - expect(recorded.count).to be_within(10).of(93) - expect(recorded.cached_count).to be_within(5).of(5) + expect(recorded.count).to be_within(1).of(50) + expect(recorded.cached_count).to eq(0) end def create_pipeline(status) - create(:ci_empty_pipeline, status: status).tap do |pipeline| + create(:ci_empty_pipeline, project: project, status: status).tap do |pipeline| Ci::Build::AVAILABLE_STATUSES.each do |status| create_build(pipeline, status, status) end From 38c324b95fb10d7d49a2d54e1d2cb53528f03d3f Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 6 Apr 2017 21:38:45 +0800 Subject: [PATCH 046/113] We don't have to save, transition would save for us --- app/models/ci/pipeline.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index e03def25755..23c6ad819c4 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -97,7 +97,7 @@ module Ci end after_transition :canceled => any - [:canceled] do |pipeline| - pipeline.update(auto_canceled_by: nil) + pipeline.auto_canceled_by = nil end end From 1bed2c87e92ca1f42d4e94fbd1e83b392e7736e7 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 6 Apr 2017 21:53:02 +0800 Subject: [PATCH 047/113] Add missing tests and update test description --- spec/models/ci/pipeline_spec.rb | 1 + spec/models/commit_status_spec.rb | 1 + spec/presenters/ci/build_presenter_spec.rb | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 3595601a72d..8d2533b39e3 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -18,6 +18,7 @@ describe Ci::Pipeline, models: true do it { is_expected.to have_many(:trigger_requests) } it { is_expected.to have_many(:builds) } it { is_expected.to have_many(:auto_canceled_pipelines) } + it { is_expected.to have_many(:auto_canceled_jobs) } it { is_expected.to validate_presence_of :sha } it { is_expected.to validate_presence_of :status } diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb index 3bffb8dba72..f15ff2f985d 100644 --- a/spec/models/commit_status_spec.rb +++ b/spec/models/commit_status_spec.rb @@ -16,6 +16,7 @@ describe CommitStatus, :models do it { is_expected.to belong_to(:pipeline) } it { is_expected.to belong_to(:user) } it { is_expected.to belong_to(:project) } + it { is_expected.to belong_to(:auto_canceled_by) } it { is_expected.to validate_presence_of(:name) } it { is_expected.to validate_inclusion_of(:status).in_array(%w(pending running failed success canceled)) } diff --git a/spec/presenters/ci/build_presenter_spec.rb b/spec/presenters/ci/build_presenter_spec.rb index ebb599bb48c..2190ab0e82e 100644 --- a/spec/presenters/ci/build_presenter_spec.rb +++ b/spec/presenters/ci/build_presenter_spec.rb @@ -64,7 +64,7 @@ describe Ci::BuildPresenter do expect(build).to receive(:auto_canceled_by_id).and_return(1) end - it 'shows that the job is auto-canceled' do + it 'shows that the build is auto-canceled' do status_title = presenter.status_title expect(status_title).to include('auto-canceled') From 95ecbfed50969929bec7596ebf08996704f94073 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Thu, 6 Apr 2017 15:55:52 +0200 Subject: [PATCH 048/113] Remove unused code --- .../projects/pipelines_controller.rb | 49 ++++--------------- 1 file changed, 10 insertions(+), 39 deletions(-) diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index f8aba16203e..43a1abaa662 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -1,35 +1,3 @@ -module ActiveRecord - class QueryRecorder - attr_reader :log - attr_reader :start - attr_reader :end - - def initialize(&block) - @log = [] - @start = Time.now - ActiveSupport::Notifications.subscribed(method(:callback), 'sql.active_record', &block) - @end = Time.now - end - - def callback(name, start, finish, message_id, values) - return if %w(SCHEMA).include?(values[:name]) - @log << values[:sql] - end - - def time - @end - @start - end - - def count - @log.count - end - - def log_message - @log.join("\n\n") - end - end -end - class Projects::PipelinesController < Projects::ApplicationController before_action :pipeline, except: [:index, :new, :create, :charts] before_action :commit, only: [:show, :builds] @@ -61,15 +29,18 @@ class Projects::PipelinesController < Projects::ApplicationController respond_to do |format| format.html format.json do - result = nil - queries = ActiveRecord::QueryRecorder.new do - result = PipelineSerializer + render json: { + pipelines: PipelineSerializer .new(project: @project, user: @current_user) .with_pagination(request, response) - .represent(@pipelines) - end - - render json: { aa_queries: queries.count, aa_time: queries.time, result: result } + .represent(@pipelines), + count: { + all: @pipelines_count, + running: @running_count, + pending: @pending_count, + finished: @finished_count, + } + } end end end From cdfa17c429964bb730f7c444e2163a7463963dd8 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 6 Apr 2017 22:04:45 +0800 Subject: [PATCH 049/113] Use before_transition --- app/models/ci/pipeline.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 23c6ad819c4..9165565d8fd 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -70,6 +70,10 @@ module Ci pipeline.update_duration end + before_transition :canceled => any - [:canceled] do |pipeline| + pipeline.auto_canceled_by = nil + end + after_transition [:created, :pending] => :running do |pipeline| pipeline.run_after_commit { PipelineMetricsWorker.perform_async(id) } end @@ -95,10 +99,6 @@ module Ci PipelineNotificationWorker.perform_async(pipeline.id) end end - - after_transition :canceled => any - [:canceled] do |pipeline| - pipeline.auto_canceled_by = nil - end end # ref can't be HEAD or SHA, can only be branch/tag name From 1ac44911b355ac18d279b7fff4c7db821689d9c7 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 6 Apr 2017 22:09:53 +0800 Subject: [PATCH 050/113] Bump schema version --- db/schema.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index afc67dba702..3797d2914d2 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170405080720) do +ActiveRecord::Schema.define(version: 20170406115029) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" From 7d543837f39a4a1bccff1e1e80e45cfe45e63a89 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Thu, 6 Apr 2017 17:18:51 +0200 Subject: [PATCH 051/113] Fix markdown table in API Issues docs --- doc/api/issues.md | 92 +++++++++++++++-------------------------------- 1 file changed, 29 insertions(+), 63 deletions(-) diff --git a/doc/api/issues.md b/doc/api/issues.md index 5702cdcf3c1..54c099d4bf8 100644 --- a/doc/api/issues.md +++ b/doc/api/issues.md @@ -29,17 +29,15 @@ GET /issues?iids[]=42&iids[]=43 GET /issues?search=issue+title+or+description ``` -|-------------+----------------+----------+-----------------------------------------------------------------------------------------------------------------------------| | Attribute | Type | Required | Description | -|-------------+----------------+----------+-----------------------------------------------------------------------------------------------------------------------------| +|-------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------------------| | `state` | string | no | Return all issues or just those that are `opened` or `closed` | | `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `No+Label` lists all issues with no labels | | `milestone` | string | no | The milestone title | | `iids` | Array[integer] | no | Return only the issues having the given `iid` | | `order_by` | string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` | | `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` | -| `search` | string | no | Search issues against their `title` and `description` | -|-------------+----------------+----------+-----------------------------------------------------------------------------------------------------------------------------| +| `search` | string | no | Search issues against their `title` and `description` | ```bash curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/issues @@ -111,9 +109,8 @@ GET /groups/:id/issues?iids[]=42&iids[]=43 GET /groups/:id/issues?search=issue+title+or+description ``` -|-------------+----------------+----------+-----------------------------------------------------------------------------------------------------------------------------| | Attribute | Type | Required | Description | -|-------------+----------------+----------+-----------------------------------------------------------------------------------------------------------------------------| +|-------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------------------| | `id` | integer | yes | The ID of a group | | `state` | string | no | Return all issues or just those that are `opened` or `closed` | | `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `No+Label` lists all issues with no labels | @@ -122,7 +119,6 @@ GET /groups/:id/issues?search=issue+title+or+description | `order_by` | string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` | | `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` | | `search` | string | no | Search group issues against their `title` and `description` | -|-------------+----------------+----------+-----------------------------------------------------------------------------------------------------------------------------| ```bash @@ -195,9 +191,8 @@ GET /projects/:id/issues?iids[]=42&iids[]=43 GET /projects/:id/issues?search=issue+title+or+description ``` -|-------------+----------------+----------+-----------------------------------------------------------------------------------------------------------------------------| | Attribute | Type | Required | Description | -|-------------+----------------+----------+-----------------------------------------------------------------------------------------------------------------------------| +|-------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------------------| | `id` | integer | yes | The ID of a project | | `iids` | Array[integer] | no | Return only the milestone having the given `iid` | | `state` | string | no | Return all issues or just those that are `opened` or `closed` | @@ -206,7 +201,6 @@ GET /projects/:id/issues?search=issue+title+or+description | `order_by` | string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` | | `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` | | `search` | string | no | Search project issues against their `title` and `description` | -|-------------+----------------+----------+-----------------------------------------------------------------------------------------------------------------------------| ```bash @@ -270,12 +264,10 @@ Get a single project issue. GET /projects/:id/issues/:issue_iid ``` -|-------------+---------+----------+--------------------------------------| | Attribute | Type | Required | Description | -|-------------+---------+----------+--------------------------------------| +|-------------|---------|----------|--------------------------------------| | `id` | integer | yes | The ID of a project | | `issue_iid` | integer | yes | The internal ID of a project's issue | -|-------------+---------+----------+--------------------------------------| ```bash curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/4/issues/41 @@ -337,23 +329,19 @@ Creates a new project issue. POST /projects/:id/issues ``` -|-------------------------------------------+---------+----------+------------------------------------------------------------------------------------------------------------------------------------------------------| -| Attribute | Type | Required | Description | -|-------------------------------------------+---------+----------+------------------------------------------------------------------------------------------------------------------------------------------------------| -| `id` | integer | yes | The ID of a project | -| `title` | string | yes | The title of an issue | -| `description` | string | no | The description of an issue | -| `confidential` | boolean | no | Set an issue to be confidential. Default is `false`. | -| `assignee_id` | integer | no | The ID of a user to assign issue | -| `milestone_id` | integer | no | The ID of a milestone to assign issue | -| `labels` | string | no | Comma-separated label names for an issue | -| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. `2016-03-11T03:45:40Z` (requires admin or project owner rights) | -| `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, e.g. `2016-03-11` | -| `merge_request_to_resolve_discussions_of` | integer | no | The IID of a merge request in which to resolve all issues. This will fill the issue with a default description and mark all discussions as resolved. | -| - | - | - | When passing a description or title, these values will take precedence over the default values. | -| `discussion_to_resolve` | string | no | The ID of a discussion to resolve. This will fill in the issue with a default description and mark the discussion | -| - | - | - | as resolved. Use in combination with `merge_request_to_resolve_discussions_of`. | -|-------------------------------------------+---------+----------+------------------------------------------------------------------------------------------------------------------------------------------------------| +| Attribute | Type | Required | Description | +|-------------------------------------------|---------|----------|--------------| +| `id` | integer | yes | The ID of a project | +| `title` | string | yes | The title of an issue | +| `description` | string | no | The description of an issue | +| `confidential` | boolean | no | Set an issue to be confidential. Default is `false`. | +| `assignee_id` | integer | no | The ID of a user to assign issue | +| `milestone_id` | integer | no | The ID of a milestone to assign issue | +| `labels` | string | no | Comma-separated label names for an issue | +| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. `2016-03-11T03:45:40Z` (requires admin or project owner rights) | +| `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, e.g. `2016-03-11` | +| `merge_request_to_resolve_discussions_of` | integer | no | The IID of a merge request in which to resolve all issues. This will fill the issue with a default description and mark all discussions as resolved. When passing a description or title, these values will take precedence over the default values.| +| `discussion_to_resolve` | string | no | The ID of a discussion to resolve. This will fill in the issue with a default description and mark the discussion as resolved. Use in combination with `merge_request_to_resolve_discussions_of`. | ```bash curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/4/issues?title=Issues%20with%20auth&labels=bug @@ -401,9 +389,8 @@ closed. PUT /projects/:id/issues/:issue_iid ``` -|----------------+---------+----------+------------------------------------------------------------------------------------------------------------| | Attribute | Type | Required | Description | -|----------------+---------+----------+------------------------------------------------------------------------------------------------------------| +|----------------|---------|----------|------------------------------------------------------------------------------------------------------------| | `id` | integer | yes | The ID of a project | | `issue_iid` | integer | yes | The internal ID of a project's issue | | `title` | string | no | The title of an issue | @@ -415,7 +402,6 @@ PUT /projects/:id/issues/:issue_iid | `state_event` | string | no | The state event of an issue. Set `close` to close the issue and `reopen` to reopen it | | `updated_at` | string | no | Date time string, ISO 8601 formatted, e.g. `2016-03-11T03:45:40Z` (requires admin or project owner rights) | | `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, e.g. `2016-03-11` | -|----------------+---------+----------+------------------------------------------------------------------------------------------------------------| ```bash curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/4/issues/85?state_event=close @@ -462,12 +448,10 @@ Only for admins and project owners. Soft deletes the issue in question. DELETE /projects/:id/issues/:issue_iid ``` -|-------------+---------+----------+--------------------------------------| | Attribute | Type | Required | Description | -|-------------+---------+----------+--------------------------------------| +|-------------|---------|----------|--------------------------------------| | `id` | integer | yes | The ID of a project | | `issue_iid` | integer | yes | The internal ID of a project's issue | -|-------------+---------+----------+--------------------------------------| ```bash curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/4/issues/85 @@ -486,13 +470,11 @@ project, it will then be assigned to the issue that is being moved. POST /projects/:id/issues/:issue_iid/move ``` -|-----------------+---------+----------+--------------------------------------| | Attribute | Type | Required | Description | -|-----------------+---------+----------+--------------------------------------| +|-----------------|---------|----------|--------------------------------------| | `id` | integer | yes | The ID of a project | | `issue_iid` | integer | yes | The internal ID of a project's issue | | `to_project_id` | integer | yes | The ID of the new project | -|-----------------+---------+----------+--------------------------------------| ```bash curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/4/issues/85/move @@ -544,12 +526,10 @@ is returned. POST /projects/:id/issues/:issue_iid/subscribe ``` -|-------------+---------+----------+--------------------------------------| | Attribute | Type | Required | Description | -|-------------+---------+----------+--------------------------------------| +|-------------|---------|----------|--------------------------------------| | `id` | integer | yes | The ID of a project | | `issue_iid` | integer | yes | The internal ID of a project's issue | -|-------------+---------+----------+--------------------------------------| ```bash curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/subscribe @@ -601,12 +581,10 @@ status code `304` is returned. POST /projects/:id/issues/:issue_iid/unsubscribe ``` -|-------------+---------+----------+--------------------------------------| | Attribute | Type | Required | Description | -|-------------+---------+----------+--------------------------------------| +|-------------|---------|----------|--------------------------------------| | `id` | integer | yes | The ID of a project | | `issue_iid` | integer | yes | The internal ID of a project's issue | -|-------------+---------+----------+--------------------------------------| ```bash curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/unsubscribe @@ -622,12 +600,10 @@ returned. POST /projects/:id/issues/:issue_iid/todo ``` -|-------------+---------+----------+--------------------------------------| | Attribute | Type | Required | Description | -|-------------+---------+----------+--------------------------------------| +|-------------|---------|----------|--------------------------------------| | `id` | integer | yes | The ID of a project | | `issue_iid` | integer | yes | The internal ID of a project's issue | -|-------------+---------+----------+--------------------------------------| ```bash curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/todo @@ -715,13 +691,11 @@ Sets an estimated time of work for this issue. POST /projects/:id/issues/:issue_iid/time_estimate ``` -|-------------+---------+----------+------------------------------------------| | Attribute | Type | Required | Description | -|-------------+---------+----------+------------------------------------------| +|-------------|---------|----------|------------------------------------------| | `id` | integer | yes | The ID of a project | | `issue_iid` | integer | yes | The internal ID of a project's issue | | `duration` | string | yes | The duration in human format. e.g: 3h30m | -|-------------+---------+----------+------------------------------------------| ```bash curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/time_estimate?duration=3h30m @@ -746,12 +720,10 @@ Resets the estimated time for this issue to 0 seconds. POST /projects/:id/issues/:issue_iid/reset_time_estimate ``` -|-------------+---------+----------+--------------------------------------| | Attribute | Type | Required | Description | -|-------------+---------+----------+--------------------------------------| +|-------------|---------|----------|--------------------------------------| | `id` | integer | yes | The ID of a project | | `issue_iid` | integer | yes | The internal ID of a project's issue | -|-------------+---------+----------+--------------------------------------| ```bash curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/reset_time_estimate @@ -776,13 +748,11 @@ Adds spent time for this issue POST /projects/:id/issues/:issue_iid/add_spent_time ``` -|-------------+---------+----------+------------------------------------------| | Attribute | Type | Required | Description | -|-------------+---------+----------+------------------------------------------| +|-------------|---------|----------|------------------------------------------| | `id` | integer | yes | The ID of a project | | `issue_iid` | integer | yes | The internal ID of a project's issue | | `duration` | string | yes | The duration in human format. e.g: 3h30m | -|-------------+---------+----------+------------------------------------------| ```bash curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/add_spent_time?duration=1h @@ -807,12 +777,10 @@ Resets the total spent time for this issue to 0 seconds. POST /projects/:id/issues/:issue_iid/reset_spent_time ``` -|-------------+---------+----------+--------------------------------------| | Attribute | Type | Required | Description | -|-------------+---------+----------+--------------------------------------| +|-------------|---------|----------|--------------------------------------| | `id` | integer | yes | The ID of a project | | `issue_iid` | integer | yes | The internal ID of a project's issue | -|-------------+---------+----------+--------------------------------------| ```bash curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/reset_spent_time @@ -835,12 +803,10 @@ Example response: GET /projects/:id/issues/:issue_iid/time_stats ``` -|-------------+---------+----------+--------------------------------------| | Attribute | Type | Required | Description | -|-------------+---------+----------+--------------------------------------| +|-------------|---------|----------|--------------------------------------| | `id` | integer | yes | The ID of a project | | `issue_iid` | integer | yes | The internal ID of a project's issue | -|-------------+---------+----------+--------------------------------------| ```bash curl --request GET --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/time_stats From ce55999bc4a31a2f115ec6bfed2332ff292ddf3b Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 6 Apr 2017 23:31:37 +0800 Subject: [PATCH 052/113] We no longer has has_command? method --- spec/models/ci/build_spec.rb | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index 8dbcf50ee0c..ab7cf47bd2d 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -735,40 +735,6 @@ describe Ci::Build, :models do end end - describe '#has_commands?' do - context 'when build has commands' do - let(:build) do - create(:ci_build, commands: 'rspec') - end - - it 'has commands' do - expect(build).to have_commands - end - end - - context 'when does not have commands' do - context 'when commands are an empty string' do - let(:build) do - create(:ci_build, commands: '') - end - - it 'has no commands' do - expect(build).not_to have_commands - end - end - - context 'when commands are not set at all' do - let(:build) do - create(:ci_build, commands: nil) - end - - it 'has no commands' do - expect(build).not_to have_commands - end - end - end - end - describe '#has_tags?' do context 'when build has tags' do subject { create(:ci_build, tag_list: ['tag']) } From 7547e86579a931c31f0b3dd1047e2519d5824fd5 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 6 Apr 2017 23:43:15 +0800 Subject: [PATCH 053/113] Use preload because we don't want join here --- app/serializers/pipeline_serializer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/serializers/pipeline_serializer.rb b/app/serializers/pipeline_serializer.rb index 0af9ef0e3f7..e7a9df8ac4e 100644 --- a/app/serializers/pipeline_serializer.rb +++ b/app/serializers/pipeline_serializer.rb @@ -13,7 +13,7 @@ class PipelineSerializer < BaseSerializer def represent(resource, opts = {}) if resource.is_a?(ActiveRecord::Relation) - resource = resource.includes([ + resource = resource.preload([ :retryable_builds, :cancelable_statuses, :trigger_requests, From 553c784bb29711ce03518ff2ceb9e990a5d8a317 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 6 Apr 2017 23:43:30 +0800 Subject: [PATCH 054/113] Ignore those optimization associations in import/export --- lib/gitlab/import_export/import_export.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml index f69288f7d67..5d89511449d 100644 --- a/lib/gitlab/import_export/import_export.yml +++ b/lib/gitlab/import_export/import_export.yml @@ -76,6 +76,12 @@ excluded_attributes: statuses: - :trace - :token + pipelines: + - :pending_builds + - :retryable_builds + - :cancelable_statuses + - :manual_actions + - :artifacts methods: labels: From 503f8822758fd6deb93e448bf37e1e3e70422e29 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 6 Apr 2017 23:47:37 +0800 Subject: [PATCH 055/113] Fix rubocop offenses --- app/models/ci/pipeline.rb | 2 +- .../20170402231018_remove_index_for_users_current_sign_in_at.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 9165565d8fd..250ae496b06 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -70,7 +70,7 @@ module Ci pipeline.update_duration end - before_transition :canceled => any - [:canceled] do |pipeline| + before_transition canceled: any - [:canceled] do |pipeline| pipeline.auto_canceled_by = nil end diff --git a/db/migrate/20170402231018_remove_index_for_users_current_sign_in_at.rb b/db/migrate/20170402231018_remove_index_for_users_current_sign_in_at.rb index 8316ee9eb9f..6013598b835 100644 --- a/db/migrate/20170402231018_remove_index_for_users_current_sign_in_at.rb +++ b/db/migrate/20170402231018_remove_index_for_users_current_sign_in_at.rb @@ -14,7 +14,7 @@ class RemoveIndexForUsersCurrentSignInAt < ActiveRecord::Migration if Gitlab::Database.postgresql? execute 'DROP INDEX CONCURRENTLY index_users_on_current_sign_in_at;' else - remove_index :users, :current_sign_in_at + remove_concurrent_index :users, :current_sign_in_at end end end From b85ddc8459477463da72e1213c0330c340e44fd5 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 7 Apr 2017 00:45:34 +0800 Subject: [PATCH 056/113] Fix typo --- spec/models/commit_status_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb index f15ff2f985d..8e07e6694bf 100644 --- a/spec/models/commit_status_spec.rb +++ b/spec/models/commit_status_spec.rb @@ -112,7 +112,7 @@ describe CommitStatus, :models do context 'when there is auto_canceled_by' do before do - commit_status.update(auto_cancel_by: create(:ci_empty_pipeline)) + commit_status.update(auto_canceled_by: create(:ci_empty_pipeline)) end it 'is auto canceled' do From a39ff617f80c003244d2400b384b4e857fad7f6e Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 7 Apr 2017 01:09:53 +0800 Subject: [PATCH 057/113] Fix token test by specifying a static token --- spec/models/ci/trigger_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/models/ci/trigger_spec.rb b/spec/models/ci/trigger_spec.rb index 1bcb673cb16..92c15c13c18 100644 --- a/spec/models/ci/trigger_spec.rb +++ b/spec/models/ci/trigger_spec.rb @@ -16,8 +16,8 @@ describe Ci::Trigger, models: true do expect(trigger.token).not_to be_nil end - it 'does not set an random token if one provided' do - trigger = create(:ci_trigger, project: project) + it 'does not set a random token if one provided' do + trigger = create(:ci_trigger, project: project, token: 'token') expect(trigger.token).to eq('token') end From 4f435c6c3a641d7c3dd826c316d5372fdbfd2161 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 7 Apr 2017 01:29:11 +0800 Subject: [PATCH 058/113] Reload pipeline to make sure it's updated --- spec/services/ci/process_pipeline_service_spec.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spec/services/ci/process_pipeline_service_spec.rb b/spec/services/ci/process_pipeline_service_spec.rb index bb98fb37a90..d7df6c5c22e 100644 --- a/spec/services/ci/process_pipeline_service_spec.rb +++ b/spec/services/ci/process_pipeline_service_spec.rb @@ -462,7 +462,10 @@ describe Ci::ProcessPipelineService, '#execute', :services do builds.find_by(name: name).play(user) end - delegate :manual_actions, to: :pipeline + def manual_actions + pipeline.reload + pipeline.manual_actions + end def create_build(name, **opts) create(:ci_build, :created, pipeline: pipeline, name: name, **opts) From beedfc8d94c96342a82e27b8c7b836ca7002cb43 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 7 Apr 2017 01:36:26 +0800 Subject: [PATCH 059/113] Fix test by ignoring auto_canceled_by for jobs --- spec/services/ci/retry_build_service_spec.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/spec/services/ci/retry_build_service_spec.rb b/spec/services/ci/retry_build_service_spec.rb index 8567817147b..b2d37657770 100644 --- a/spec/services/ci/retry_build_service_spec.rb +++ b/spec/services/ci/retry_build_service_spec.rb @@ -16,20 +16,21 @@ describe Ci::RetryBuildService, :services do %i[id status user token coverage trace runner artifacts_expire_at artifacts_file artifacts_metadata artifacts_size created_at updated_at started_at finished_at queued_at erased_by - erased_at].freeze + erased_at auto_canceled_by].freeze IGNORE_ACCESSORS = %i[type lock_version target_url base_tags commit_id deployments erased_by_id last_deployment project_id runner_id tag_taggings taggings tags trigger_request_id - user_id].freeze + user_id auto_canceled_by_id].freeze shared_examples 'build duplication' do let(:build) do create(:ci_build, :failed, :artifacts_expired, :erased, :queued, :coverage, :tags, :allowed_to_fail, :on_tag, :teardown_environment, :triggered, :trace, - description: 'some build', pipeline: pipeline) + description: 'some build', pipeline: pipeline, + auto_canceled_by: create(:ci_empty_pipeline)) end describe 'clone accessors' do From 5a4aee36a5bfd615475aae80d9549855b46a098c Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 7 Apr 2017 02:29:17 +0800 Subject: [PATCH 060/113] Make sure that's canceled --- spec/models/commit_status_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb index 8e07e6694bf..0ee85489574 100644 --- a/spec/models/commit_status_spec.rb +++ b/spec/models/commit_status_spec.rb @@ -107,7 +107,7 @@ describe CommitStatus, :models do context 'when it is canceled' do before do - commit_status.cancel + commit_status.update(status: 'canceled') end context 'when there is auto_canceled_by' do From 9d4b6f2261e8c1dc24949f19aab21850ab487b25 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Thu, 6 Apr 2017 21:37:28 +0200 Subject: [PATCH 061/113] Fix import export --- spec/lib/gitlab/import_export/all_models.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 002cffd3062..5a7e5fd4360 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -89,6 +89,11 @@ pipelines: - statuses - builds - trigger_requests +- pending_builds +- retryable_builds +- cancelable_statuses +- manual_actions +- artifacts statuses: - project - pipeline From 57c353fca7121a120142161b253004f33d815766 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Thu, 6 Apr 2017 21:57:04 +0200 Subject: [PATCH 062/113] Fix tests and review --- app/models/project.rb | 12 +++--------- changelogs/unreleased/optimise-pipelines-json.yml | 4 ++++ lib/gitlab/import_export/import_export.yml | 6 ------ spec/models/project_spec.rb | 1 + spec/services/ci/process_pipeline_service_spec.rb | 3 +-- 5 files changed, 9 insertions(+), 17 deletions(-) create mode 100644 changelogs/unreleased/optimise-pipelines-json.yml diff --git a/app/models/project.rb b/app/models/project.rb index 4da0e016756..112209fef30 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -168,6 +168,8 @@ class Project < ActiveRecord::Base has_many :environments, dependent: :destroy has_many :deployments, dependent: :destroy + has_many :active_runners, -> { active }, through: :runner_projects, source: :runner, class_name: 'Ci::Runner' + accepts_nested_attributes_for :variables, allow_destroy: true accepts_nested_attributes_for :project_feature @@ -1096,20 +1098,12 @@ class Project < ActiveRecord::Base @shared_runners ||= shared_runners_available? ? Ci::Runner.shared : Ci::Runner.none end - def active_runners - @active_runners ||= runners.active - end - def active_shared_runners @active_shared_runners ||= shared_runners.active end def any_runners?(&block) - if active_runners.any?(&block) - return true - end - - active_shared_runners.any?(&block) + active_runners.any?(&block) || active_shared_runners.any?(&block) end def valid_runners_token?(token) diff --git a/changelogs/unreleased/optimise-pipelines-json.yml b/changelogs/unreleased/optimise-pipelines-json.yml new file mode 100644 index 00000000000..948679dcbeb --- /dev/null +++ b/changelogs/unreleased/optimise-pipelines-json.yml @@ -0,0 +1,4 @@ +--- +title: Optimise pipelines.json endpoint +merge_request: +author: diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml index 5d89511449d..f69288f7d67 100644 --- a/lib/gitlab/import_export/import_export.yml +++ b/lib/gitlab/import_export/import_export.yml @@ -76,12 +76,6 @@ excluded_attributes: statuses: - :trace - :token - pipelines: - - :pending_builds - - :retryable_builds - - :cancelable_statuses - - :manual_actions - - :artifacts methods: labels: diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 59a2560ca06..a899cfcceb7 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -57,6 +57,7 @@ describe Project, models: true do it { is_expected.to have_many(:builds) } it { is_expected.to have_many(:runner_projects) } it { is_expected.to have_many(:runners) } + it { is_expected.to have_many(:active_runners) } it { is_expected.to have_many(:variables) } it { is_expected.to have_many(:triggers) } it { is_expected.to have_many(:pages_domains) } diff --git a/spec/services/ci/process_pipeline_service_spec.rb b/spec/services/ci/process_pipeline_service_spec.rb index d7df6c5c22e..245e19822f3 100644 --- a/spec/services/ci/process_pipeline_service_spec.rb +++ b/spec/services/ci/process_pipeline_service_spec.rb @@ -463,8 +463,7 @@ describe Ci::ProcessPipelineService, '#execute', :services do end def manual_actions - pipeline.reload - pipeline.manual_actions + pipeline.manual_actions(true) end def create_build(name, **opts) From fc8ec9504a297890365593359695b384b78b6988 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Mon, 3 Apr 2017 18:03:14 -0500 Subject: [PATCH 063/113] Corrected capitalizacion on various sections --- app/views/events/_event_last_push.html.haml | 4 +-- app/views/help/ui.html.haml | 34 +++++++++---------- app/views/import/github/new.html.haml | 4 +-- app/views/layouts/header/_default.html.haml | 4 +-- app/views/profiles/accounts/show.html.haml | 4 +-- app/views/profiles/emails/index.html.haml | 10 +++--- .../profiles/two_factor_auths/show.html.haml | 2 +- .../_personal_access_tokens_form.html.haml | 4 +-- app/views/u2f/_register.html.haml | 4 +-- 9 files changed, 35 insertions(+), 35 deletions(-) diff --git a/app/views/events/_event_last_push.html.haml b/app/views/events/_event_last_push.html.haml index a1a282178e7..1584695a62b 100644 --- a/app/views/events/_event_last_push.html.haml +++ b/app/views/events/_event_last_push.html.haml @@ -10,5 +10,5 @@ #{time_ago_with_tooltip(event.created_at)} .pull-right - = link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-info btn-sm" do - Create Merge Request + = link_to new_mr_path_from_push_event(event), title: "New merge request", class: "btn btn-info btn-sm" do + Create merge request diff --git a/app/views/help/ui.html.haml b/app/views/help/ui.html.haml index 1fb2c6271ad..207f80bedfe 100644 --- a/app/views/help/ui.html.haml +++ b/app/views/help/ui.html.haml @@ -225,7 +225,7 @@ %ul.dropdown-menu %li %a{ href: "#" } - Dropdown Option + Dropdown option .dropdown.inline.pull-right %button.dropdown-menu-toggle{ type: 'button', data: { toggle: 'dropdown' } } Dropdown @@ -233,7 +233,7 @@ %ul.dropdown-menu.dropdown-menu-align-right %li %a{ href: "#" } - Dropdown Option + Dropdown option .example %div .dropdown.inline @@ -243,7 +243,7 @@ %ul.dropdown-menu.dropdown-menu-selectable %li %a.is-active{ href: "#" } - Dropdown Option + Dropdown option .example %div .dropdown.inline @@ -262,26 +262,26 @@ %ul %li %a.is-active{ href: "#" } - Dropdown Option + Dropdown option %li %a{ href: "#" } - Dropdown Option + Dropdown option %li.divider %li %a{ href: "#" } - Dropdown Option + Dropdown option %li %a{ href: "#" } - Dropdown Option + Dropdown option %li %a{ href: "#" } - Dropdown Option + Dropdown option %li %a{ href: "#" } - Dropdown Option + Dropdown option %li %a{ href: "#" } - Dropdown Option + Dropdown option .dropdown-footer %strong Tip: If an author is not a member of this project, you can still filter by his name while using the search field. @@ -301,26 +301,26 @@ %ul %li %a.is-active{ href: "#" } - Dropdown Option + Dropdown option %li %a{ href: "#" } - Dropdown Option + Dropdown option %li.divider %li %a{ href: "#" } - Dropdown Option + Dropdown option %li %a{ href: "#" } - Dropdown Option + Dropdown option %li %a{ href: "#" } - Dropdown Option + Dropdown option %li %a{ href: "#" } - Dropdown Option + Dropdown option %li %a{ href: "#" } - Dropdown Option + Dropdown option .dropdown-footer %strong Tip: If an author is not a member of this project, you can still filter by his name while using the search field. diff --git a/app/views/import/github/new.html.haml b/app/views/import/github/new.html.haml index 4c6af0b7908..9c2da3a3eec 100644 --- a/app/views/import/github/new.html.haml +++ b/app/views/import/github/new.html.haml @@ -9,7 +9,7 @@ To import a GitHub project, you first need to authorize GitLab to access the list of your GitHub repositories: - = link_to 'List Your GitHub Repositories', status_import_github_path, class: 'btn btn-success' + = link_to 'List your GitHub repositories', status_import_github_path, class: 'btn btn-success' %hr @@ -28,7 +28,7 @@ = form_tag personal_access_token_import_github_path, method: :post, class: 'form-inline' do .form-group = text_field_tag :personal_access_token, '', class: 'form-control', placeholder: "Personal Access Token", size: 40 - = submit_tag 'List Your GitHub Repositories', class: 'btn btn-success' + = submit_tag 'List your GitHub repositories', class: 'btn btn-success' - unless github_import_configured? %hr diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index 23abf6897d4..7408fe3f6d0 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -29,11 +29,11 @@ - if current_user - if session[:impersonator_id] %li.impersonation - = link_to admin_impersonation_path, method: :delete, title: "Stop Impersonation", aria: { label: 'Stop Impersonation' }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do + = link_to admin_impersonation_path, method: :delete, title: "Stop impersonation", aria: { label: 'Stop impersonation' }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do = icon('user-secret fw') - if current_user.is_admin? %li - = link_to admin_root_path, title: 'Admin Area', aria: { label: "Admin Area" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do + = link_to admin_root_path, title: 'Admin area', aria: { label: "Admin area" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = icon('wrench fw') - if current_user.can_create_project? %li diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml index 5ce2220c907..d843cacd52d 100644 --- a/app/views/profiles/accounts/show.html.haml +++ b/app/views/profiles/accounts/show.html.haml @@ -49,14 +49,14 @@ %p Status: #{current_user.two_factor_enabled? ? 'Enabled' : 'Disabled'} - if current_user.two_factor_enabled? - = link_to 'Manage Two-Factor Authentication', profile_two_factor_auth_path, class: 'btn btn-info' + = link_to 'Manage two-factor authentication', profile_two_factor_auth_path, class: 'btn btn-info' = link_to 'Disable', profile_two_factor_auth_path, method: :delete, data: { confirm: "Are you sure? This will invalidate your registered applications and U2F devices." }, class: 'btn btn-danger' - else .append-bottom-10 - = link_to 'Enable Two-Factor Authentication', profile_two_factor_auth_path, class: 'btn btn-success' + = link_to 'Enable two-factor authentication', profile_two_factor_auth_path, class: 'btn btn-success' %hr - if button_based_providers.any? diff --git a/app/views/profiles/emails/index.html.haml b/app/views/profiles/emails/index.html.haml index dc499be885b..f5a323dbaf8 100644 --- a/app/views/profiles/emails/index.html.haml +++ b/app/views/profiles/emails/index.html.haml @@ -33,17 +33,17 @@ %li = @primary %span.pull-right - %span.label.label-success Primary Email + %span.label.label-success Primary email - if @primary === current_user.public_email - %span.label.label-info Public Email + %span.label.label-info Public email - if @primary === current_user.notification_email - %span.label.label-info Notification Email + %span.label.label-info Notification email - @emails.each do |email| %li = email.email %span.pull-right - if email.email === current_user.public_email - %span.label.label-info Public Email + %span.label.label-info Public email - if email.email === current_user.notification_email - %span.label.label-info Notification Email + %span.label.label-info Notification email = link_to 'Remove', profile_email_path(email), data: { confirm: 'Are you sure?'}, method: :delete, class: 'btn btn-sm btn-warning prepend-left-10' diff --git a/app/views/profiles/two_factor_auths/show.html.haml b/app/views/profiles/two_factor_auths/show.html.haml index 7ade5f00d47..0ff05098cd7 100644 --- a/app/views/profiles/two_factor_auths/show.html.haml +++ b/app/views/profiles/two_factor_auths/show.html.haml @@ -44,7 +44,7 @@ = label_tag :pin_code, nil, class: "label-light" = text_field_tag :pin_code, nil, class: "form-control", required: true .prepend-top-default - = submit_tag 'Register with Two-Factor App', class: 'btn btn-success' + = submit_tag 'Register with two-factor app', class: 'btn btn-success' %hr diff --git a/app/views/shared/_personal_access_tokens_form.html.haml b/app/views/shared/_personal_access_tokens_form.html.haml index af4cc90f4a7..1a445db2dc0 100644 --- a/app/views/shared/_personal_access_tokens_form.html.haml +++ b/app/views/shared/_personal_access_tokens_form.html.haml @@ -1,4 +1,4 @@ -- type = impersonation ? "Impersonation" : "Personal Access" +- type = impersonation ? "impersonation" : "personal Access" %h5.prepend-top-0 Add a #{type} Token @@ -22,7 +22,7 @@ = render 'shared/tokens/scopes_form', prefix: 'personal_access_token', token: token, scopes: scopes .prepend-top-default - = f.submit "Create #{type} Token", class: "btn btn-create" + = f.submit "Create #{type} token", class: "btn btn-create" :javascript var $dateField = $('.datepicker'); diff --git a/app/views/u2f/_register.html.haml b/app/views/u2f/_register.html.haml index adc07bcba73..54fabfc4909 100644 --- a/app/views/u2f/_register.html.haml +++ b/app/views/u2f/_register.html.haml @@ -7,13 +7,13 @@ - if current_user.two_factor_otp_enabled? .row.append-bottom-10 .col-md-3 - %button#js-setup-u2f-device.btn.btn-info Setup New U2F Device + %button#js-setup-u2f-device.btn.btn-info Setup new U2F device .col-md-9 %p Your U2F device needs to be set up. Plug it in (if not already) and click the button on the left. - else .row.append-bottom-10 .col-md-3 - %button#js-setup-u2f-device.btn.btn-info{ disabled: true } Setup New U2F Device + %button#js-setup-u2f-device.btn.btn-info{ disabled: true } Setup new U2F device .col-md-9 %p.text-warning You need to register a two-factor authentication app before you can set up a U2F device. From eb2d6a6ed5736b7f4b5868636e4ba659118d0a40 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Mon, 3 Apr 2017 18:10:06 -0500 Subject: [PATCH 064/113] Fixed rspec tests --- app/views/u2f/_register.html.haml | 2 +- .../profiles/personal_access_tokens_spec.rb | 4 ++-- .../project_owner_creates_license_file_spec.rb | 4 ++-- spec/features/tags/master_views_tags_spec.rb | 2 +- spec/features/u2f_spec.rb | 14 +++++++------- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/views/u2f/_register.html.haml b/app/views/u2f/_register.html.haml index 54fabfc4909..00788e77b6b 100644 --- a/app/views/u2f/_register.html.haml +++ b/app/views/u2f/_register.html.haml @@ -36,7 +36,7 @@ = text_field_tag 'u2f_registration[name]', nil, class: 'form-control', placeholder: "Pick a name" .col-md-3 = hidden_field_tag 'u2f_registration[device_response]', nil, class: 'form-control', required: true, id: "js-device-response" - = submit_tag "Register U2F Device", class: "btn btn-success" + = submit_tag "Register U2F device", class: "btn btn-success" :javascript var u2fRegister = new U2FRegister($("#js-register-u2f"), gon.u2f); diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb index 99fba594651..27a20e78a43 100644 --- a/spec/features/profiles/personal_access_tokens_spec.rb +++ b/spec/features/profiles/personal_access_tokens_spec.rb @@ -41,7 +41,7 @@ describe 'Profile > Personal Access Tokens', feature: true, js: true do check "api" check "read_user" - click_on "Create Personal Access Token" + click_on "Create personal access token" expect(active_personal_access_tokens).to have_text(name) expect(active_personal_access_tokens).to have_text('In') expect(active_personal_access_tokens).to have_text('api') @@ -54,7 +54,7 @@ describe 'Profile > Personal Access Tokens', feature: true, js: true do visit profile_personal_access_tokens_path fill_in "Name", with: 'My PAT' - expect { click_on "Create Personal Access Token" }.not_to change { PersonalAccessToken.count } + expect { click_on "Create personal access token" }.not_to change { PersonalAccessToken.count } expect(page).to have_content("Name cannot be nil") end end diff --git a/spec/features/projects/files/project_owner_creates_license_file_spec.rb b/spec/features/projects/files/project_owner_creates_license_file_spec.rb index 6b281e6d21d..82b096c7cc9 100644 --- a/spec/features/projects/files/project_owner_creates_license_file_spec.rb +++ b/spec/features/projects/files/project_owner_creates_license_file_spec.rb @@ -53,7 +53,7 @@ feature 'project owner creates a license file', feature: true, js: true do expect(file_content).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") fill_in :commit_message, with: 'Add a LICENSE file', visible: true - click_button 'Commit Changes' + click_button 'Commit changes' expect(current_path).to eq( namespace_project_blob_path(project.namespace, project, 'master/LICENSE')) @@ -63,7 +63,7 @@ feature 'project owner creates a license file', feature: true, js: true do def select_template(template) page.within('.js-license-selector-wrap') do - click_button 'Apply a License template' + click_button 'Apply a kicense template' click_link template wait_for_ajax end diff --git a/spec/features/tags/master_views_tags_spec.rb b/spec/features/tags/master_views_tags_spec.rb index 555f84c4772..922ac15a2eb 100644 --- a/spec/features/tags/master_views_tags_spec.rb +++ b/spec/features/tags/master_views_tags_spec.rb @@ -16,7 +16,7 @@ feature 'Master views tags', feature: true do fill_in :commit_message, with: 'Add a README file', visible: true # Remove pre-receive hook so we can push without auth FileUtils.rm_f(File.join(project.repository.path, 'hooks', 'pre-receive')) - click_button 'Commit Changes' + click_button 'Commit changes' visit namespace_project_tags_path(project.namespace, project) end diff --git a/spec/features/u2f_spec.rb b/spec/features/u2f_spec.rb index 28373098123..60941abda14 100644 --- a/spec/features/u2f_spec.rb +++ b/spec/features/u2f_spec.rb @@ -6,7 +6,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do before { allow_any_instance_of(U2fHelper).to receive(:inject_u2f_api?).and_return(true) } def manage_two_factor_authentication - click_on 'Manage Two-Factor Authentication' + click_on 'Manage two-factor authentication' expect(page).to have_content("Setup New U2F Device") wait_for_ajax end @@ -34,9 +34,9 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do it 'does not allow registering a new device' do visit profile_account_path - click_on 'Enable Two-Factor Authentication' + click_on 'Enable two-factor authentication' - expect(page).to have_button('Setup New U2F Device', disabled: true) + expect(page).to have_button('Setup new U2F device', disabled: true) end end @@ -111,9 +111,9 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do # Have the "u2f device" respond with bad data page.execute_script("u2f.register = function(_,_,_,callback) { callback('bad response'); };") - click_on 'Setup New U2F Device' + click_on 'Setup new U2F device' expect(page).to have_content('Your device was successfully set up') - click_on 'Register U2F Device' + click_on 'Register U2F device' expect(U2fRegistration.count).to eq(0) expect(page).to have_content("The form contains the following error") @@ -126,9 +126,9 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do # Failed registration page.execute_script("u2f.register = function(_,_,_,callback) { callback('bad response'); };") - click_on 'Setup New U2F Device' + click_on 'Setup new U2F device' expect(page).to have_content('Your device was successfully set up') - click_on 'Register U2F Device' + click_on 'Register U2F device' expect(page).to have_content("The form contains the following error") # Successful registration From c2a987fb9c5c8f6879516ce04c439fb45fcd8fae Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Lopez Date: Tue, 4 Apr 2017 22:36:19 +0000 Subject: [PATCH 065/113] Admin section capitalization fix --- app/views/admin/abuse_reports/_abuse_report.html.haml | 2 +- app/views/admin/application_settings/_form.html.haml | 2 +- app/views/admin/applications/index.html.haml | 2 +- app/views/admin/dashboard/index.html.haml | 6 +++--- app/views/admin/deploy_keys/index.html.haml | 2 +- app/views/admin/groups/index.html.haml | 2 +- app/views/admin/groups/show.html.haml | 2 +- app/views/admin/hooks/index.html.haml | 4 ++-- app/views/admin/identities/index.html.haml | 2 +- app/views/admin/projects/show.html.haml | 4 ++-- app/views/admin/spam_logs/_spam_log.html.haml | 2 +- app/views/admin/users/_user.html.haml | 2 +- app/views/admin/users/index.html.haml | 2 +- spec/features/admin/admin_deploy_keys_spec.rb | 2 +- spec/features/admin/admin_groups_spec.rb | 2 +- spec/features/admin/admin_hooks_spec.rb | 4 ++-- spec/features/admin/admin_manage_applications_spec.rb | 2 +- 17 files changed, 22 insertions(+), 22 deletions(-) diff --git a/app/views/admin/abuse_reports/_abuse_report.html.haml b/app/views/admin/abuse_reports/_abuse_report.html.haml index 05f3d9a3b50..18c6c559049 100644 --- a/app/views/admin/abuse_reports/_abuse_report.html.haml +++ b/app/views/admin/abuse_reports/_abuse_report.html.haml @@ -30,5 +30,5 @@ = link_to 'Block user', block_admin_user_path(user), data: {confirm: 'USER WILL BE BLOCKED! Are you sure?'}, method: :put, class: "btn btn-sm btn-block" - else .btn.btn-sm.disabled.btn-block - Already Blocked + Already blocked = link_to 'Remove report', [:admin, abuse_report], remote: true, method: :delete, class: "btn btn-sm btn-block btn-close js-remove-tr" diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml index 5d51a2b5cbc..703f611bb45 100644 --- a/app/views/admin/application_settings/_form.html.haml +++ b/app/views/admin/application_settings/_form.html.haml @@ -148,7 +148,7 @@ Sign-in enabled - if omniauth_enabled? && button_based_providers.any? .form-group - = f.label :enabled_oauth_sign_in_sources, 'Enabled OAuth Sign-In sources', class: 'control-label col-sm-2' + = f.label :enabled_oauth_sign_in_sources, 'Enabled OAuth sign-in sources', class: 'control-label col-sm-2' .col-sm-10 .btn-group{ data: { toggle: 'buttons' } } - oauth_providers_checkboxes.each do |source| diff --git a/app/views/admin/applications/index.html.haml b/app/views/admin/applications/index.html.haml index b3a3b4c1d45..eb4293c7e37 100644 --- a/app/views/admin/applications/index.html.haml +++ b/app/views/admin/applications/index.html.haml @@ -4,7 +4,7 @@ %p.light System OAuth applications don't belong to any user and can only be managed by admins %hr -%p= link_to 'New Application', new_admin_application_path, class: 'btn btn-success' +%p= link_to 'New application', new_admin_application_path, class: 'btn btn-success' %table.table.table-striped %thead %tr diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml index ebca9beb035..8c9fdc9ae42 100644 --- a/app/views/admin/dashboard/index.html.haml +++ b/app/views/admin/dashboard/index.html.haml @@ -125,7 +125,7 @@ = link_to admin_projects_path do %h1= number_with_delimiter(Project.cached_count) %hr - = link_to('New Project', new_project_path, class: "btn btn-new") + = link_to('New project', new_project_path, class: "btn btn-new") .col-sm-4 .light-well.well-centered %h4 Users @@ -133,7 +133,7 @@ = link_to admin_users_path do %h1= number_with_delimiter(User.count) %hr - = link_to 'New User', new_admin_user_path, class: "btn btn-new" + = link_to 'New user', new_admin_user_path, class: "btn btn-new" .col-sm-4 .light-well.well-centered %h4 Groups @@ -141,7 +141,7 @@ = link_to admin_groups_path do %h1= number_with_delimiter(Group.count) %hr - = link_to 'New Group', new_admin_group_path, class: "btn btn-new" + = link_to 'New group', new_admin_group_path, class: "btn btn-new" .row.prepend-top-10 .col-md-4 diff --git a/app/views/admin/deploy_keys/index.html.haml b/app/views/admin/deploy_keys/index.html.haml index 7b71bb5b287..007da8c1d29 100644 --- a/app/views/admin/deploy_keys/index.html.haml +++ b/app/views/admin/deploy_keys/index.html.haml @@ -3,7 +3,7 @@ %h3.page-title.deploy-keys-title Public deploy keys (#{@deploy_keys.count}) .pull-right - = link_to 'New Deploy Key', new_admin_deploy_key_path, class: 'btn btn-new btn-sm btn-inverted' + = link_to 'New deploy key', new_admin_deploy_key_path, class: 'btn btn-new btn-sm btn-inverted' - if @deploy_keys.any? .table-holder.deploy-keys-list diff --git a/app/views/admin/groups/index.html.haml b/app/views/admin/groups/index.html.haml index 07775247cfd..e5f380c78e2 100644 --- a/app/views/admin/groups/index.html.haml +++ b/app/views/admin/groups/index.html.haml @@ -30,7 +30,7 @@ = link_to admin_groups_path(sort: sort_value_largest_group, name: project_name) do = sort_title_largest_group = link_to new_admin_group_path, class: "btn btn-new" do - New Group + New group %ul.content-list = render @groups diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml index 30b3fabdd7e..9149b8e7fb9 100644 --- a/app/views/admin/groups/show.html.haml +++ b/app/views/admin/groups/show.html.haml @@ -116,7 +116,7 @@ group members %span.badge= @group.members.size .pull-right - = link_to icon('pencil-square-o', text: 'Manage Access'), polymorphic_url([@group, :members]), class: "btn btn-xs" + = link_to icon('pencil-square-o', text: 'Manage access'), polymorphic_url([@group, :members]), class: "btn btn-xs" %ul.well-list.group-users-list.content-list = render partial: 'shared/members/member', collection: @members, as: :member, locals: { show_controls: false } .panel-footer diff --git a/app/views/admin/hooks/index.html.haml b/app/views/admin/hooks/index.html.haml index 551edf14361..d9c7948763a 100644 --- a/app/views/admin/hooks/index.html.haml +++ b/app/views/admin/hooks/index.html.haml @@ -51,7 +51,7 @@ = f.check_box :enable_ssl_verification %strong Enable SSL verification .form-actions - = f.submit "Add System Hook", class: "btn btn-create" + = f.submit "Add system hook", class: "btn btn-create" %hr - if @hooks.any? @@ -62,7 +62,7 @@ - @hooks.each do |hook| %li .controls - = link_to 'Test Hook', admin_hook_test_path(hook), class: "btn btn-sm" + = link_to 'Test hook', admin_hook_test_path(hook), class: "btn btn-sm" = link_to 'Remove', admin_hook_path(hook), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-remove btn-sm" .monospace= hook.url %div diff --git a/app/views/admin/identities/index.html.haml b/app/views/admin/identities/index.html.haml index 741d111fb7d..ff67e59cdac 100644 --- a/app/views/admin/identities/index.html.haml +++ b/app/views/admin/identities/index.html.haml @@ -1,7 +1,7 @@ - page_title "Identities", @user.name, "Users" = render 'admin/users/head' -= link_to 'New Identity', new_admin_user_identity_path, class: 'pull-right btn btn-new' += link_to 'New identity', new_admin_user_identity_path, class: 'pull-right btn btn-new' - if @identities.present? .table-holder %table.table diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml index 2967da6e692..08a8f627113 100644 --- a/app/views/admin/projects/show.html.haml +++ b/app/views/admin/projects/show.html.haml @@ -159,7 +159,7 @@ %span.badge= @group_members.size .pull-right = link_to admin_group_path(@group), class: 'btn btn-xs' do - = icon('pencil-square-o', text: 'Manage Access') + = icon('pencil-square-o', text: 'Manage access') %ul.well-list.content-list = render partial: 'shared/members/member', collection: @group_members, as: :member, locals: { show_controls: false } .panel-footer @@ -173,7 +173,7 @@ project members %span.badge= @project.users.size .pull-right - = link_to icon('pencil-square-o', text: 'Manage Access'), polymorphic_url([@project, :members]), class: "btn btn-xs" + = link_to icon('pencil-square-o', text: 'Manage access'), polymorphic_url([@project, :members]), class: "btn btn-xs" %ul.well-list.project_members.content-list = render partial: 'shared/members/member', collection: @project_members, as: :member, locals: { show_controls: false } .panel-footer diff --git a/app/views/admin/spam_logs/_spam_log.html.haml b/app/views/admin/spam_logs/_spam_log.html.haml index 33f6d847782..ea6a0c4fb77 100644 --- a/app/views/admin/spam_logs/_spam_log.html.haml +++ b/app/views/admin/spam_logs/_spam_log.html.haml @@ -35,5 +35,5 @@ = link_to 'Block user', block_admin_user_path(user), data: {confirm: 'USER WILL BE BLOCKED! Are you sure?'}, method: :put, class: "btn btn-xs" - else .btn.btn-xs.disabled - Already Blocked + Already blocked = link_to 'Remove log', [:admin, spam_log], remote: true, method: :delete, class: "btn btn-xs btn-close js-remove-tr" diff --git a/app/views/admin/users/_user.html.haml b/app/views/admin/users/_user.html.haml index a756cb7243a..8862455688f 100644 --- a/app/views/admin/users/_user.html.haml +++ b/app/views/admin/users/_user.html.haml @@ -37,6 +37,6 @@ - if user.can_be_removed? && can?(current_user, :destroy_user, @user) %li.divider %li - = link_to 'Delete User', [:admin, user], data: { confirm: "USER #{user.name} WILL BE REMOVED! All issues, merge requests and groups linked to this user will also be removed! Consider cancelling this deletion and blocking the user instead. Are you sure?" }, + = link_to 'Delete user', [:admin, user], data: { confirm: "USER #{user.name} WILL BE REMOVED! All issues, merge requests and groups linked to this user will also be removed! Consider cancelling this deletion and blocking the user instead. Are you sure?" }, class: 'btn btn-remove btn-block', method: :delete diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml index 298cf0fa950..c7cd86527d3 100644 --- a/app/views/admin/users/index.html.haml +++ b/app/views/admin/users/index.html.haml @@ -33,7 +33,7 @@ = sort_title_recently_updated = link_to admin_users_path(sort: sort_value_oldest_updated, filter: params[:filter]) do = sort_title_oldest_updated - = link_to 'New User', new_admin_user_path, class: 'btn btn-new btn-search' + = link_to 'New user', new_admin_user_path, class: 'btn btn-new btn-search' .nav-block %ul.nav-links.wide.scrolling-tabs.white.scrolling-tabs diff --git a/spec/features/admin/admin_deploy_keys_spec.rb b/spec/features/admin/admin_deploy_keys_spec.rb index 7ce6cce0a5c..c0b6995a84a 100644 --- a/spec/features/admin/admin_deploy_keys_spec.rb +++ b/spec/features/admin/admin_deploy_keys_spec.rb @@ -18,7 +18,7 @@ RSpec.describe 'admin deploy keys', type: :feature do describe 'create new deploy key' do before do visit admin_deploy_keys_path - click_link 'New Deploy Key' + click_link 'New deploy key' end it 'creates new deploy key' do diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb index a871e370ba2..56d5c7c327e 100644 --- a/spec/features/admin/admin_groups_spec.rb +++ b/spec/features/admin/admin_groups_spec.rb @@ -24,7 +24,7 @@ feature 'Admin Groups', feature: true do it 'creates new group' do visit admin_groups_path - click_link "New Group" + click_link "New group" fill_in 'group_path', with: 'gitlab' fill_in 'group_description', with: 'Group description' click_button "Create group" diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb index 570c374a89b..fb519a9bf12 100644 --- a/spec/features/admin/admin_hooks_spec.rb +++ b/spec/features/admin/admin_hooks_spec.rb @@ -33,7 +33,7 @@ describe "Admin::Hooks", feature: true do fill_in 'hook_url', with: url check 'Enable SSL verification' - expect { click_button 'Add System Hook' }.to change(SystemHook, :count).by(1) + expect { click_button 'Add system hook' }.to change(SystemHook, :count).by(1) expect(page).to have_content 'SSL Verification: enabled' expect(current_path).to eq(admin_hooks_path) expect(page).to have_content(url) @@ -44,7 +44,7 @@ describe "Admin::Hooks", feature: true do before do WebMock.stub_request(:post, @system_hook.url) visit admin_hooks_path - click_link "Test Hook" + click_link "Test hook" end it { expect(current_path).to eq(admin_hooks_path) } diff --git a/spec/features/admin/admin_manage_applications_spec.rb b/spec/features/admin/admin_manage_applications_spec.rb index c2c618b5659..0079125889b 100644 --- a/spec/features/admin/admin_manage_applications_spec.rb +++ b/spec/features/admin/admin_manage_applications_spec.rb @@ -8,7 +8,7 @@ RSpec.describe 'admin manage applications', feature: true do it do visit admin_applications_path - click_on 'New Application' + click_on 'New application' expect(page).to have_content('New application') fill_in :doorkeeper_application_name, with: 'test' From 7997a0df7106899f1e5352e4613a3e0c3e40db64 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Lopez Date: Wed, 5 Apr 2017 05:59:49 +0000 Subject: [PATCH 066/113] Dashboard section capitalization fix --- app/views/dashboard/_groups_head.html.haml | 2 +- app/views/dashboard/_projects_head.html.haml | 2 +- app/views/dashboard/issues.html.haml | 2 +- app/views/dashboard/merge_requests.html.haml | 2 +- app/views/dashboard/milestones/index.html.haml | 2 +- features/steps/dashboard/new_project.rb | 4 ++-- spec/features/dashboard/group_spec.rb | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/views/dashboard/_groups_head.html.haml b/app/views/dashboard/_groups_head.html.haml index 13eaba41f4c..0e848386ebb 100644 --- a/app/views/dashboard/_groups_head.html.haml +++ b/app/views/dashboard/_groups_head.html.haml @@ -11,4 +11,4 @@ = render 'shared/groups/dropdown' - if current_user.can_create_group? = link_to new_group_path, class: "btn btn-new" do - New Group + New group diff --git a/app/views/dashboard/_projects_head.html.haml b/app/views/dashboard/_projects_head.html.haml index 4679b9549d1..64b737ee886 100644 --- a/app/views/dashboard/_projects_head.html.haml +++ b/app/views/dashboard/_projects_head.html.haml @@ -19,4 +19,4 @@ = render 'shared/projects/dropdown' - if current_user.can_create_project? = link_to new_project_path, class: 'btn btn-new' do - New Project + New project diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml index 10867140d4f..faa68468043 100644 --- a/app/views/dashboard/issues.html.haml +++ b/app/views/dashboard/issues.html.haml @@ -8,7 +8,7 @@ .nav-controls = link_to params.merge(rss_url_options), class: 'btn has-tooltip', title: 'Subscribe' do = icon('rss') - = render 'shared/new_project_item_select', path: 'issues/new', label: "New Issue" + = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue" = render 'shared/issuable/filter', type: :issues = render 'shared/issues' diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml index e64c78c4cb8..12966c01950 100644 --- a/app/views/dashboard/merge_requests.html.haml +++ b/app/views/dashboard/merge_requests.html.haml @@ -4,7 +4,7 @@ .top-area = render 'shared/issuable/nav', type: :merge_requests .nav-controls - = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New Merge Request" + = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request" = render 'shared/issuable/filter', type: :merge_requests = render 'shared/merge_requests' diff --git a/app/views/dashboard/milestones/index.html.haml b/app/views/dashboard/milestones/index.html.haml index 505b475f55b..664ec618b79 100644 --- a/app/views/dashboard/milestones/index.html.haml +++ b/app/views/dashboard/milestones/index.html.haml @@ -5,7 +5,7 @@ = render 'shared/milestones_filter', counts: @milestone_states .nav-controls - = render 'shared/new_project_item_select', path: 'milestones/new', label: 'New Milestone', include_groups: true + = render 'shared/new_project_item_select', path: 'milestones/new', label: 'New milestone', include_groups: true .milestones %ul.content-list diff --git a/features/steps/dashboard/new_project.rb b/features/steps/dashboard/new_project.rb index d4a04f693b8..4fb16d3bb57 100644 --- a/features/steps/dashboard/new_project.rb +++ b/features/steps/dashboard/new_project.rb @@ -3,9 +3,9 @@ class Spinach::Features::NewProject < Spinach::FeatureSteps include SharedPaths include SharedProject - step 'I click "New Project" link' do + step 'I click "New project" link' do page.within('.content') do - click_link "New Project" + click_link "New project" end end diff --git a/spec/features/dashboard/group_spec.rb b/spec/features/dashboard/group_spec.rb index d5f8470fab0..19f5d1b0f30 100644 --- a/spec/features/dashboard/group_spec.rb +++ b/spec/features/dashboard/group_spec.rb @@ -7,7 +7,7 @@ RSpec.describe 'Dashboard Group', feature: true do it 'creates new grpup' do visit dashboard_groups_path - click_link 'New Group' + click_link 'New group' fill_in 'group_path', with: 'Samurai' fill_in 'group_description', with: 'Tokugawa Shogunate' From 0e325ea6ee625ad24709dd1118e36803bbaa222e Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Lopez Date: Wed, 5 Apr 2017 20:46:58 +0000 Subject: [PATCH 067/113] Groups section capitalization fix --- app/views/groups/edit.html.haml | 2 +- app/views/groups/issues.html.haml | 2 +- app/views/groups/milestones/index.html.haml | 2 +- app/views/groups/milestones/new.html.haml | 2 +- app/views/groups/projects.html.haml | 2 +- features/steps/group/milestones.rb | 4 ++-- spec/features/groups_spec.rb | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml index 00ff40224ba..7d5add3cc1c 100644 --- a/app/views/groups/edit.html.haml +++ b/app/views/groups/edit.html.haml @@ -51,4 +51,4 @@ %strong Removed group can not be restored! .form-actions - = link_to 'Remove Group', @group, data: {confirm: 'Removed group can not be restored! Are you sure?'}, method: :delete, class: "btn btn-remove" + = link_to 'Remove group', @group, data: {confirm: 'Removed group can not be restored! Are you sure?'}, method: :delete, class: "btn btn-remove" diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml index f4c17dc2d16..182dbe2f98a 100644 --- a/app/views/groups/issues.html.haml +++ b/app/views/groups/issues.html.haml @@ -11,7 +11,7 @@ = icon('rss') %span.icon-label Subscribe - = render 'shared/new_project_item_select', path: 'issues/new', label: "New Issue" + = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue" = render 'shared/issuable/filter', type: :issues diff --git a/app/views/groups/milestones/index.html.haml b/app/views/groups/milestones/index.html.haml index 6893168f039..f91bee0b610 100644 --- a/app/views/groups/milestones/index.html.haml +++ b/app/views/groups/milestones/index.html.haml @@ -7,7 +7,7 @@ .nav-controls - if can?(current_user, :admin_milestones, @group) = link_to new_group_milestone_path(@group), class: "btn btn-new" do - New Milestone + New milestone .row-content-block Only milestones from diff --git a/app/views/groups/milestones/new.html.haml b/app/views/groups/milestones/new.html.haml index 63cadfca530..8d3aa4d1a74 100644 --- a/app/views/groups/milestones/new.html.haml +++ b/app/views/groups/milestones/new.html.haml @@ -39,5 +39,5 @@ = render "shared/milestones/form_dates", f: f .form-actions - = f.submit 'Create Milestone', class: "btn-create btn" + = f.submit 'Create milestone', class: "btn-create btn" = link_to "Cancel", group_milestones_path(@group), class: "btn btn-cancel" diff --git a/app/views/groups/projects.html.haml b/app/views/groups/projects.html.haml index 83bdd654f27..62ad47972b9 100644 --- a/app/views/groups/projects.html.haml +++ b/app/views/groups/projects.html.haml @@ -7,7 +7,7 @@ - if can? current_user, :admin_group, @group .controls = link_to new_project_path(namespace_id: @group.id), class: "btn btn-sm btn-success" do - New Project + New project %ul.well-list - @projects.each do |project| %li diff --git a/features/steps/group/milestones.rb b/features/steps/group/milestones.rb index 9996f3baf0d..f8f5e3f2382 100644 --- a/features/steps/group/milestones.rb +++ b/features/steps/group/milestones.rb @@ -46,11 +46,11 @@ class Spinach::Features::GroupMilestones < Spinach::FeatureSteps end step 'I click new milestone button' do - click_link "New Milestone" + click_link "New milestone" end step 'I press create mileston button' do - click_button "Create Milestone" + click_button "Create milestone" end step 'milestone in each project should be created' do diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb index 8bfe6f4d54b..7670c4caea4 100644 --- a/spec/features/groups_spec.rb +++ b/spec/features/groups_spec.rb @@ -153,7 +153,7 @@ feature 'Group', feature: true do end it 'removes group' do - click_link 'Remove Group' + click_link 'Remove group' expect(page).to have_content "scheduled for deletion" end From 7592137f218a1a5ef0a8031846cc93ecf185dd9f Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Tue, 4 Apr 2017 13:06:32 -0500 Subject: [PATCH 068/113] Fix rspec and spinach tests --- app/views/projects/_commit_button.html.haml | 2 +- .../projects/blob/_template_selectors.html.haml | 2 +- .../shared/_personal_access_tokens_form.html.haml | 2 +- features/project/source/browse_files.feature | 14 +++++++------- features/steps/dashboard/dashboard.rb | 6 +++--- features/steps/project/source/browse_files.rb | 4 ++-- .../admin/admin_users_impersonation_tokens_spec.rb | 2 +- spec/features/auto_deploy_spec.rb | 2 +- spec/features/projects/blobs/edit_spec.rb | 2 +- spec/features/projects/blobs/user_create_spec.rb | 2 +- .../projects/files/creating_a_file_spec.rb | 2 +- .../features/projects/files/editing_a_file_spec.rb | 2 +- .../project_owner_creates_license_file_spec.rb | 4 ++-- ...to_create_license_file_in_empty_project_spec.rb | 4 ++-- .../projects/files/template_type_dropdown_spec.rb | 4 ++-- spec/features/projects/files/undo_template_spec.rb | 4 ++-- spec/features/u2f_spec.rb | 6 +++--- spec/javascripts/u2f/register_spec.js | 2 +- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/app/views/projects/_commit_button.html.haml b/app/views/projects/_commit_button.html.haml index 640612ca433..b55dc3dce5c 100644 --- a/app/views/projects/_commit_button.html.haml +++ b/app/views/projects/_commit_button.html.haml @@ -1,5 +1,5 @@ .form-actions - = button_tag 'Commit Changes', class: 'btn commit-btn js-commit-button btn-create' + = button_tag 'Commit changes', class: 'btn commit-btn js-commit-button btn-create' = link_to 'Cancel', cancel_path, class: 'btn btn-cancel', data: {confirm: leave_edit_message} diff --git a/app/views/projects/blob/_template_selectors.html.haml b/app/views/projects/blob/_template_selectors.html.haml index d52733d2bd6..2a178325041 100644 --- a/app/views/projects/blob/_template_selectors.html.haml +++ b/app/views/projects/blob/_template_selectors.html.haml @@ -5,7 +5,7 @@ .template-type-selector.js-template-type-selector-wrap.hidden = dropdown_tag("Choose type", options: { toggle_class: 'btn js-template-type-selector', title: "Choose a template type" } ) .license-selector.js-license-selector-wrap.js-template-selector-wrap.hidden - = dropdown_tag("Apply a License template", options: { toggle_class: 'btn js-license-selector', title: "Apply a license", filter: true, placeholder: "Filter", data: { data: licenses_for_select, project: @project.name, fullname: @project.namespace.human_name } } ) + = dropdown_tag("Apply a license template", options: { toggle_class: 'btn js-license-selector', title: "Apply a license", filter: true, placeholder: "Filter", data: { data: licenses_for_select, project: @project.name, fullname: @project.namespace.human_name } } ) .gitignore-selector.js-gitignore-selector-wrap.js-template-selector-wrap.hidden = dropdown_tag("Apply a .gitignore template", options: { toggle_class: 'btn js-gitignore-selector', title: "Apply a template", filter: true, placeholder: "Filter", data: { data: gitignore_names } } ) .gitlab-ci-yml-selector.js-gitlab-ci-yml-selector-wrap.js-template-selector-wrap.hidden diff --git a/app/views/shared/_personal_access_tokens_form.html.haml b/app/views/shared/_personal_access_tokens_form.html.haml index 1a445db2dc0..e8062848fc3 100644 --- a/app/views/shared/_personal_access_tokens_form.html.haml +++ b/app/views/shared/_personal_access_tokens_form.html.haml @@ -1,4 +1,4 @@ -- type = impersonation ? "impersonation" : "personal Access" +- type = impersonation ? "impersonation" : "personal access" %h5.prepend-top-0 Add a #{type} Token diff --git a/features/project/source/browse_files.feature b/features/project/source/browse_files.feature index 5ede935c562..894c4a96bb8 100644 --- a/features/project/source/browse_files.feature +++ b/features/project/source/browse_files.feature @@ -36,7 +36,7 @@ Feature: Project Source Browse Files And I edit code And I fill the new file name And I fill the commit message - And I click on "Commit Changes" + And I click on "Commit changes" Then I am redirected to the new file And I should see its new content @@ -47,7 +47,7 @@ Feature: Project Source Browse Files And I edit code And I fill the new file name And I fill the commit message - And I click on "Commit Changes" + And I click on "Commit changes" Then I am redirected to the fork's new merge request page And I can see the new commit message @@ -57,7 +57,7 @@ Feature: Project Source Browse Files And I edit code with new lines at end of file And I fill the new file name And I fill the commit message - And I click on "Commit Changes" + And I click on "Commit changes" Then I am redirected to the new file And I click button "Edit" And I should see its content with new lines preserved at end of file @@ -69,7 +69,7 @@ Feature: Project Source Browse Files And I fill the new file name And I fill the commit message And I fill the new branch name - And I click on "Commit Changes" + And I click on "Commit changes" Then I am redirected to the new merge request page When I click on "Changes" tab And I should see its new content @@ -173,7 +173,7 @@ Feature: Project Source Browse Files And I click button "Edit" And I edit code And I fill the commit message - And I click on "Commit Changes" + And I click on "Commit changes" Then I am redirected to the ".gitignore" And I should see its new content @@ -186,7 +186,7 @@ Feature: Project Source Browse Files And I click button "Fork" And I edit code And I fill the commit message - And I click on "Commit Changes" + And I click on "Commit changes" Then I am redirected to the fork's new merge request page And I can see the new commit message @@ -197,7 +197,7 @@ Feature: Project Source Browse Files And I edit code And I fill the commit message And I fill the new branch name - And I click on "Commit Changes" + And I click on "Commit changes" Then I am redirected to the new merge request page Then I click on "Changes" tab And I should see its new content diff --git a/features/steps/dashboard/dashboard.rb b/features/steps/dashboard/dashboard.rb index 33a1c88e33c..c715c85c43c 100644 --- a/features/steps/dashboard/dashboard.rb +++ b/features/steps/dashboard/dashboard.rb @@ -18,11 +18,11 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps step 'I should see last push widget' do expect(page).to have_content "You pushed to fix" - expect(page).to have_link "Create Merge Request" + expect(page).to have_link "Create merge request" end - step 'I click "Create Merge Request" link' do - click_link "Create Merge Request" + step 'I click "Create merge request" link' do + click_link "Create merge request" end step 'I see prefilled new Merge Request page' do diff --git a/features/steps/project/source/browse_files.rb b/features/steps/project/source/browse_files.rb index 29f628763db..553e397339e 100644 --- a/features/steps/project/source/browse_files.rb +++ b/features/steps/project/source/browse_files.rb @@ -108,8 +108,8 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps click_link 'Preview Changes' end - step 'I click on "Commit Changes"' do - click_button 'Commit Changes' + step 'I click on "Commit changes"' do + click_button 'Commit changes' end step 'I click on "Changes" tab' do diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb index ff23d486355..0fb4baeb71c 100644 --- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb +++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb @@ -30,7 +30,7 @@ describe 'Admin > Users > Impersonation Tokens', feature: true, js: true do check "api" check "read_user" - expect { click_on "Create Impersonation Token" }.to change { PersonalAccessTokensFinder.new(impersonation: true).execute.count } + expect { click_on "Create impersonation token" }.to change { PersonalAccessTokensFinder.new(impersonation: true).execute.count } expect(active_impersonation_tokens).to have_text(name) expect(active_impersonation_tokens).to have_text('In') expect(active_impersonation_tokens).to have_text('api') diff --git a/spec/features/auto_deploy_spec.rb b/spec/features/auto_deploy_spec.rb index 009e9c6b04c..6f36c74c911 100644 --- a/spec/features/auto_deploy_spec.rb +++ b/spec/features/auto_deploy_spec.rb @@ -56,7 +56,7 @@ describe 'Auto deploy' do click_on 'OpenShift' end wait_for_ajax - click_button 'Commit Changes' + click_button 'Commit changes' expect(page).to have_content('New Merge Request From auto-deploy into master') end diff --git a/spec/features/projects/blobs/edit_spec.rb b/spec/features/projects/blobs/edit_spec.rb index 46f2f487e0c..aab5a72678e 100644 --- a/spec/features/projects/blobs/edit_spec.rb +++ b/spec/features/projects/blobs/edit_spec.rb @@ -22,7 +22,7 @@ feature 'Editing file blob', feature: true, js: true do wait_for_ajax find('.js-edit-blob').click execute_script('ace.edit("editor").setValue("class NextFeature\nend\n")') - click_button 'Commit Changes' + click_button 'Commit changes' end context 'from MR diff' do diff --git a/spec/features/projects/blobs/user_create_spec.rb b/spec/features/projects/blobs/user_create_spec.rb index d214a531138..fa1a753afcb 100644 --- a/spec/features/projects/blobs/user_create_spec.rb +++ b/spec/features/projects/blobs/user_create_spec.rb @@ -22,7 +22,7 @@ feature 'New blob creation', feature: true, js: true do end def commit_file - click_button 'Commit Changes' + click_button 'Commit changes' end context 'with default target branch' do diff --git a/spec/features/projects/files/creating_a_file_spec.rb b/spec/features/projects/files/creating_a_file_spec.rb index ae448706130..5d7bd3dc4ce 100644 --- a/spec/features/projects/files/creating_a_file_spec.rb +++ b/spec/features/projects/files/creating_a_file_spec.rb @@ -19,7 +19,7 @@ feature 'User wants to create a file', feature: true do file_content = find('#file-content') file_content.set options[:file_content] || 'Some content' - click_button 'Commit Changes' + click_button 'Commit changes' end scenario 'file name contains Chinese characters' do diff --git a/spec/features/projects/files/editing_a_file_spec.rb b/spec/features/projects/files/editing_a_file_spec.rb index 36a80d7575d..3e544316f28 100644 --- a/spec/features/projects/files/editing_a_file_spec.rb +++ b/spec/features/projects/files/editing_a_file_spec.rb @@ -27,7 +27,7 @@ feature 'User wants to edit a file', feature: true do scenario 'file has been updated since the user opened the edit page' do Files::UpdateService.new(project, user, commit_params).execute - click_button 'Commit Changes' + click_button 'Commit changes' expect(page).to have_content 'Someone edited the file the same time you did.' end diff --git a/spec/features/projects/files/project_owner_creates_license_file_spec.rb b/spec/features/projects/files/project_owner_creates_license_file_spec.rb index 82b096c7cc9..8ff0f5898ec 100644 --- a/spec/features/projects/files/project_owner_creates_license_file_spec.rb +++ b/spec/features/projects/files/project_owner_creates_license_file_spec.rb @@ -29,7 +29,7 @@ feature 'project owner creates a license file', feature: true, js: true do expect(file_content).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") fill_in :commit_message, with: 'Add a LICENSE file', visible: true - click_button 'Commit Changes' + click_button 'Commit changes' expect(current_path).to eq( namespace_project_blob_path(project.namespace, project, 'master/LICENSE')) @@ -63,7 +63,7 @@ feature 'project owner creates a license file', feature: true, js: true do def select_template(template) page.within('.js-license-selector-wrap') do - click_button 'Apply a kicense template' + click_button 'Apply a license template' click_link template wait_for_ajax end diff --git a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb index 87322ac2584..1a1910455a1 100644 --- a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb +++ b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb @@ -30,7 +30,7 @@ feature 'project owner sees a link to create a license file in empty project', f fill_in :commit_message, with: 'Add a LICENSE file', visible: true # Remove pre-receive hook so we can push without auth FileUtils.rm_f(File.join(project.repository.path, 'hooks', 'pre-receive')) - click_button 'Commit Changes' + click_button 'Commit changes' expect(current_path).to eq( namespace_project_blob_path(project.namespace, project, 'master/LICENSE')) @@ -40,7 +40,7 @@ feature 'project owner sees a link to create a license file in empty project', f def select_template(template) page.within('.js-license-selector-wrap') do - click_button 'Apply a License template' + click_button 'Apply a license template' click_link template wait_for_ajax end diff --git a/spec/features/projects/files/template_type_dropdown_spec.rb b/spec/features/projects/files/template_type_dropdown_spec.rb index 5ee5e5b4c4e..5fd86bb07a8 100644 --- a/spec/features/projects/files/template_type_dropdown_spec.rb +++ b/spec/features/projects/files/template_type_dropdown_spec.rb @@ -102,7 +102,7 @@ def check_type_selector_display(is_visible) end def try_selecting_all_types - try_selecting_template_type('LICENSE', 'Apply a License template') + try_selecting_template_type('LICENSE', 'Apply a license template') try_selecting_template_type('Dockerfile', 'Apply a Dockerfile template') try_selecting_template_type('.gitlab-ci.yml', 'Apply a GitLab CI Yaml template') try_selecting_template_type('.gitignore', 'Apply a .gitignore template') @@ -130,6 +130,6 @@ end def create_and_edit_file(file_name) visit namespace_project_new_blob_path(project.namespace, project, 'master', file_name: file_name) - click_button "Commit Changes" + click_button "Commit changes" visit namespace_project_edit_blob_path(project.namespace, project, File.join(project.default_branch, file_name)) end diff --git a/spec/features/projects/files/undo_template_spec.rb b/spec/features/projects/files/undo_template_spec.rb index 5479ea34610..c51851d3f94 100644 --- a/spec/features/projects/files/undo_template_spec.rb +++ b/spec/features/projects/files/undo_template_spec.rb @@ -17,7 +17,7 @@ feature 'Template Undo Button', js: true do end scenario 'reverts template application' do - try_template_undo('http://www.apache.org/licenses/', 'Apply a License template') + try_template_undo('http://www.apache.org/licenses/', 'Apply a license template') end end @@ -29,7 +29,7 @@ feature 'Template Undo Button', js: true do end scenario 'reverts template application' do - try_template_undo('http://www.apache.org/licenses/', 'Apply a License template') + try_template_undo('http://www.apache.org/licenses/', 'Apply a license template') end end end diff --git a/spec/features/u2f_spec.rb b/spec/features/u2f_spec.rb index 60941abda14..c877cfdd978 100644 --- a/spec/features/u2f_spec.rb +++ b/spec/features/u2f_spec.rb @@ -7,17 +7,17 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do def manage_two_factor_authentication click_on 'Manage two-factor authentication' - expect(page).to have_content("Setup New U2F Device") + expect(page).to have_content("Setup new U2F device") wait_for_ajax end def register_u2f_device(u2f_device = nil, name: 'My device') u2f_device ||= FakeU2fDevice.new(page, name) u2f_device.respond_to_u2f_registration - click_on 'Setup New U2F Device' + click_on 'Setup new U2F device' expect(page).to have_content('Your device was successfully set up') fill_in "Pick a name", with: name - click_on 'Register U2F Device' + click_on 'Register U2F device' u2f_device end diff --git a/spec/javascripts/u2f/register_spec.js b/spec/javascripts/u2f/register_spec.js index 0f390c8b980..3960759f7cb 100644 --- a/spec/javascripts/u2f/register_spec.js +++ b/spec/javascripts/u2f/register_spec.js @@ -22,7 +22,7 @@ require('./mock_u2f_device'); it('allows registering a U2F device', function() { var deviceResponse, inProgressMessage, registeredMessage, setupButton; setupButton = this.container.find("#js-setup-u2f-device"); - expect(setupButton.text()).toBe('Setup New U2F Device'); + expect(setupButton.text()).toBe('Setup new U2F device'); setupButton.trigger('click'); inProgressMessage = this.container.children("p"); expect(inProgressMessage.text()).toContain("Trying to communicate with your device"); From c380d7669c4c44864d3bec7db3be139576fac649 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Lopez Date: Thu, 6 Apr 2017 13:55:11 +0000 Subject: [PATCH 069/113] Fixed button capitalisation for Projects in views --- app/helpers/blob_helper.rb | 2 +- app/views/projects/_find_file_link.html.haml | 2 +- app/views/projects/_last_push.html.haml | 4 +- app/views/projects/blob/_header.html.haml | 2 +- app/views/projects/branches/_branch.html.haml | 2 +- app/views/projects/builds/index.html.haml | 2 +- .../projects/commit/_commit_box.html.haml | 2 +- app/views/projects/commits/show.html.haml | 6 +- app/views/projects/compare/_form.html.haml | 4 +- app/views/projects/forks/error.html.haml | 2 +- app/views/projects/issues/index.html.haml | 4 +- .../widget/_merged_buttons.haml | 2 +- .../widget/open/_accept.html.haml | 10 +-- .../_merge_when_pipeline_succeeds.html.haml | 4 +- app/views/projects/milestones/index.html.haml | 4 +- app/views/projects/milestones/show.html.haml | 4 +- app/views/projects/notes/_edit_form.html.haml | 2 +- .../projects/wikis/_main_links.html.haml | 4 +- app/views/projects/wikis/_new.html.haml | 2 +- app/views/projects/wikis/edit.html.haml | 4 +- app/views/shared/labels/_form.html.haml | 2 +- app/views/shared/web_hooks/_form.html.haml | 2 +- features/steps/project/builds/summary.rb | 2 +- features/steps/project/commits/commits.rb | 8 +-- features/steps/project/deploy_keys.rb | 2 +- features/steps/project/hooks.rb | 4 +- features/steps/project/issues/issues.rb | 2 +- features/steps/project/issues/labels.rb | 6 +- features/steps/project/issues/milestones.rb | 2 +- features/steps/project/merge_requests.rb | 8 +-- .../project/merge_requests/acceptance.rb | 6 +- .../steps/project/merge_requests/revert.rb | 2 +- features/steps/project/project_find_file.rb | 2 +- features/steps/project/source/browse_files.rb | 2 +- .../steps/project/source/markdown_render.rb | 8 ++- features/steps/project/wiki.rb | 28 +++++--- features/steps/shared/note.rb | 2 +- ...geable_with_unresolved_discussions_spec.rb | 8 +-- .../merge_requests/create_new_mr_spec.rb | 2 +- .../merge_immediately_with_pipeline_spec.rb | 2 +- .../merge_when_pipeline_succeeds_spec.rb | 38 +++++------ ...only_allow_merge_if_build_succeeds_spec.rb | 24 +++---- spec/features/merge_requests/widget_spec.rb | 2 +- .../files/template_type_dropdown_spec.rb | 2 +- .../projects/merge_request_button_spec.rb | 24 +++---- .../projects/wiki/markdown_preview_spec.rb | 60 +++++++++++------ .../wiki/user_creates_wiki_page_spec.rb | 65 ++++++++++++------- 47 files changed, 216 insertions(+), 167 deletions(-) diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 91d6d1852cf..dfc3bad01aa 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -102,7 +102,7 @@ module BlobHelper if Gitlab::MarkupHelper.previewable?(filename) 'Preview' else - 'Preview Changes' + 'Preview changes' end end diff --git a/app/views/projects/_find_file_link.html.haml b/app/views/projects/_find_file_link.html.haml index dbb33090670..3feb11645a0 100644 --- a/app/views/projects/_find_file_link.html.haml +++ b/app/views/projects/_find_file_link.html.haml @@ -1,3 +1,3 @@ = link_to namespace_project_find_file_path(@project.namespace, @project, @ref), class: 'btn btn-grouped shortcuts-find-file', rel: 'nofollow' do = icon('search') - %span Find File + %span Find file diff --git a/app/views/projects/_last_push.html.haml b/app/views/projects/_last_push.html.haml index a08436715d2..43399d17c1d 100644 --- a/app/views/projects/_last_push.html.haml +++ b/app/views/projects/_last_push.html.haml @@ -14,5 +14,5 @@ #{time_ago_with_tooltip(event.created_at)} .pull-right - = link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-info btn-sm" do - Create Merge Request + = link_to new_mr_path_from_push_event(event), title: "New merge request", class: "btn btn-info btn-sm" do + Create merge request diff --git a/app/views/projects/blob/_header.html.haml b/app/views/projects/blob/_header.html.haml index 6000e057ec4..828f8e073a9 100644 --- a/app/views/projects/blob/_header.html.haml +++ b/app/views/projects/blob/_header.html.haml @@ -20,7 +20,7 @@ -# only show normal/blame view links for text files - if blob_text_viewable?(blob) - if current_page? namespace_project_blame_path(@project.namespace, @project, @id) - = link_to 'Normal View', namespace_project_blob_path(@project.namespace, @project, @id), + = link_to 'Normal view', namespace_project_blob_path(@project.namespace, @project, @id), class: 'btn btn-sm' - else = link_to 'Blame', namespace_project_blame_path(@project.namespace, @project, @id), diff --git a/app/views/projects/branches/_branch.html.haml b/app/views/projects/branches/_branch.html.haml index 9eb610ba9c0..724675e659c 100644 --- a/app/views/projects/branches/_branch.html.haml +++ b/app/views/projects/branches/_branch.html.haml @@ -21,7 +21,7 @@ .controls.hidden-xs< - if merge_project && create_mr_button?(@repository.root_ref, branch.name) = link_to create_mr_path(@repository.root_ref, branch.name), class: 'btn btn-default' do - Merge Request + Merge request - if branch.name != @repository.root_ref = link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: branch.name), class: "btn btn-default #{'prepend-left-10' unless merge_project}", method: :post, title: "Compare" do diff --git a/app/views/projects/builds/index.html.haml b/app/views/projects/builds/index.html.haml index 5ffc0e20d10..65162aacda1 100644 --- a/app/views/projects/builds/index.html.haml +++ b/app/views/projects/builds/index.html.haml @@ -17,7 +17,7 @@ = link_to 'Get started with CI/CD Pipelines', help_page_path('ci/quick_start/README'), class: 'btn btn-info' = link_to ci_lint_path, class: 'btn btn-default' do - %span CI Lint + %span CI lint .content-list.builds-content-list = render "table", builds: @builds, project: @project diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml index a0a292d0508..f109a1151da 100644 --- a/app/views/projects/commit/_commit_box.html.haml +++ b/app/views/projects/commit/_commit_box.html.haml @@ -20,7 +20,7 @@ = icon('comment') = @notes_count = link_to namespace_project_tree_path(@project.namespace, @project, @commit), class: "btn btn-default append-right-10 hidden-xs hidden-sm" do - Browse Files + Browse files .dropdown.inline %a.btn.btn-default.dropdown-toggle{ data: { toggle: "dropdown" } } %span Options diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml index 38dbf2ac10b..c1c2fb3d299 100644 --- a/app/views/projects/commits/show.html.haml +++ b/app/views/projects/commits/show.html.haml @@ -18,16 +18,16 @@ .block-controls.hidden-xs.hidden-sm - if @merge_request.present? .control - = link_to "View Open Merge Request", namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: 'btn' + = link_to "View open merge request", namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: 'btn' - elsif create_mr_button?(@repository.root_ref, @ref) .control - = link_to "Create Merge Request", create_mr_path(@repository.root_ref, @ref), class: 'btn btn-success' + = link_to "Create merge request", create_mr_path(@repository.root_ref, @ref), class: 'btn btn-success' .control = form_tag(namespace_project_commits_path(@project.namespace, @project, @id), method: :get, class: 'commits-search-form') do = search_field_tag :search, params[:search], { placeholder: 'Filter by commit message', id: 'commits-search', class: 'form-control search-text-input input-short', spellcheck: false } .control - = link_to namespace_project_commits_path(@project.namespace, @project, @ref, rss_url_options), title: "Commits Feed", class: 'btn' do + = link_to namespace_project_commits_path(@project.namespace, @project, @ref, rss_url_options), title: "Commits feed", class: 'btn' do = icon("rss") %div{ id: dom_id(@project) } diff --git a/app/views/projects/compare/_form.html.haml b/app/views/projects/compare/_form.html.haml index 08236216421..0f080b6acee 100644 --- a/app/views/projects/compare/_form.html.haml +++ b/app/views/projects/compare/_form.html.haml @@ -21,6 +21,6 @@   = button_tag "Compare", class: "btn btn-create commits-compare-btn" - if @merge_request.present? - = link_to "View Open Merge Request", namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: 'prepend-left-10 btn' + = link_to "View open merge request", namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: 'prepend-left-10 btn' - elsif create_mr_button? - = link_to "Create Merge Request", create_mr_path, class: 'prepend-left-10 btn' + = link_to "Create merge request", create_mr_path, class: 'prepend-left-10 btn' diff --git a/app/views/projects/forks/error.html.haml b/app/views/projects/forks/error.html.haml index 98d81308407..524b77783ef 100644 --- a/app/views/projects/forks/error.html.haml +++ b/app/views/projects/forks/error.html.haml @@ -22,4 +22,4 @@ %p = link_to new_namespace_project_fork_path(@project.namespace, @project), title: "Fork", class: "btn" do %i.fa.fa-code-fork - Try to Fork again + Try to fork again diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml index f3a429d12d9..4ac0bc1d028 100644 --- a/app/views/projects/issues/index.html.haml +++ b/app/views/projects/issues/index.html.haml @@ -24,9 +24,9 @@ issue: { assignee_id: issues_finder.assignee.try(:id), milestone_id: issues_finder.milestones.first.try(:id) }), class: "btn btn-new", - title: "New Issue", + title: "New issue", id: "new_issue_link" do - New Issue + New issue = render 'shared/issuable/search_bar', type: :issues .issues-holder diff --git a/app/views/projects/merge_requests/widget/_merged_buttons.haml b/app/views/projects/merge_requests/widget/_merged_buttons.haml index caf3bf54eef..a0f54bd28ec 100644 --- a/app/views/projects/merge_requests/widget/_merged_buttons.haml +++ b/app/views/projects/merge_requests/widget/_merged_buttons.haml @@ -7,7 +7,7 @@ - if can_remove_source_branch = link_to namespace_project_branch_path(@merge_request.source_project.namespace, @merge_request.source_project, @merge_request.source_branch), remote: true, method: :delete, class: "btn btn-default remove_source_branch" do = icon('trash-o') - Remove Source Branch + Remove source branch - if mr_can_be_reverted = revert_commit_link(@merge_request.merge_commit, namespace_project_merge_request_path(@project.namespace, @project, @merge_request), btn_class: "close") - if mr_can_be_cherry_picked diff --git a/app/views/projects/merge_requests/widget/open/_accept.html.haml b/app/views/projects/merge_requests/widget/open/_accept.html.haml index e5ec151a61d..cb117d1908c 100644 --- a/app/views/projects/merge_requests/widget/open/_accept.html.haml +++ b/app/views/projects/merge_requests/widget/open/_accept.html.haml @@ -10,24 +10,24 @@ - if @pipeline && @pipeline.active? %span.btn-group = button_tag class: "btn btn-info js-merge-when-pipeline-succeeds-button merge-when-pipeline-succeeds" do - Merge When Pipeline Succeeds + Merge when pipeline succeeds - unless @project.only_allow_merge_if_pipeline_succeeds? = button_tag class: "btn btn-info dropdown-toggle", 'data-toggle' => 'dropdown' do = icon('caret-down') %span.sr-only - Select Merge Moment + Select merge moment %ul.js-merge-dropdown.dropdown-menu.dropdown-menu-right{ role: 'menu' } %li = link_to "#", class: "merge_when_pipeline_succeeds" do = icon('check fw') - Merge When Pipeline Succeeds + Merge when pipeline succeeds %li = link_to "#", class: "accept-merge-request" do = icon('warning fw') - Merge Immediately + Merge immediately - else = f.button class: "btn btn-grouped js-merge-button accept-merge-request" do - Accept Merge Request + Accept merge request - if @merge_request.force_remove_source_branch? .accept-control The source branch will be removed. diff --git a/app/views/projects/merge_requests/widget/open/_merge_when_pipeline_succeeds.html.haml b/app/views/projects/merge_requests/widget/open/_merge_when_pipeline_succeeds.html.haml index 5f347acce4d..76cc1ecd8a5 100644 --- a/app/views/projects/merge_requests/widget/open/_merge_when_pipeline_succeeds.html.haml +++ b/app/views/projects/merge_requests/widget/open/_merge_when_pipeline_succeeds.html.haml @@ -26,8 +26,8 @@ - if remove_source_branch_button = link_to merge_namespace_project_merge_request_path(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request, merge_params(@merge_request)), remote: true, method: :post, class: "btn btn-grouped btn-primary btn-sm remove_source_branch" do = icon('times') - Remove Source Branch When Merged + Remove source branch when merged - if user_can_cancel_automatic_merge = link_to cancel_merge_when_pipeline_succeeds_namespace_project_merge_request_path(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request), remote: true, method: :post, class: "btn btn-grouped btn-sm" do - Cancel Automatic Merge + Cancel automatic merge diff --git a/app/views/projects/milestones/index.html.haml b/app/views/projects/milestones/index.html.haml index b6340a00b29..8e85b2e8a20 100644 --- a/app/views/projects/milestones/index.html.haml +++ b/app/views/projects/milestones/index.html.haml @@ -9,8 +9,8 @@ .nav-controls = render 'shared/milestones_sort_dropdown' - if can?(current_user, :admin_milestone, @project) - = link_to new_namespace_project_milestone_path(@project.namespace, @project), class: 'btn btn-new', title: 'New Milestone' do - New Milestone + = link_to new_namespace_project_milestone_path(@project.namespace, @project), class: 'btn btn-new', title: 'New milestone' do + New milestone .milestones %ul.content-list diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml index 5249d752585..8b62b156853 100644 --- a/app/views/projects/milestones/show.html.haml +++ b/app/views/projects/milestones/show.html.haml @@ -23,9 +23,9 @@ .milestone-buttons - if can?(current_user, :admin_milestone, @project) - if @milestone.active? - = link_to 'Close Milestone', namespace_project_milestone_path(@project.namespace, @project, @milestone, milestone: {state_event: :close }), method: :put, class: "btn btn-close btn-nr btn-grouped" + = link_to 'Close milestone', namespace_project_milestone_path(@project.namespace, @project, @milestone, milestone: {state_event: :close }), method: :put, class: "btn btn-close btn-nr btn-grouped" - else - = link_to 'Reopen Milestone', namespace_project_milestone_path(@project.namespace, @project, @milestone, milestone: {state_event: :activate }), method: :put, class: "btn btn-reopen btn-nr btn-grouped" + = link_to 'Reopen milestone', namespace_project_milestone_path(@project.namespace, @project, @milestone, milestone: {state_event: :activate }), method: :put, class: "btn btn-reopen btn-nr btn-grouped" = link_to edit_namespace_project_milestone_path(@project.namespace, @project, @milestone), class: "btn btn-grouped btn-nr" do Edit diff --git a/app/views/projects/notes/_edit_form.html.haml b/app/views/projects/notes/_edit_form.html.haml index e8e450742b5..8b4e5928e0d 100644 --- a/app/views/projects/notes/_edit_form.html.haml +++ b/app/views/projects/notes/_edit_form.html.haml @@ -9,6 +9,6 @@ .note-form-actions.clearfix .settings-message.note-edit-warning.js-edit-warning Finish editing this message first! - = submit_tag 'Save Comment', class: 'btn btn-nr btn-save js-comment-button' + = submit_tag 'Save comment', class: 'btn btn-nr btn-save js-comment-button' %button.btn.btn-nr.btn-cancel.note-edit-cancel{ type: 'button' } Cancel diff --git a/app/views/projects/wikis/_main_links.html.haml b/app/views/projects/wikis/_main_links.html.haml index 5211ade1a5f..86178257af8 100644 --- a/app/views/projects/wikis/_main_links.html.haml +++ b/app/views/projects/wikis/_main_links.html.haml @@ -1,9 +1,9 @@ - if (@page && @page.persisted?) - if can?(current_user, :create_wiki, @project) = link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do - New Page + New page = link_to namespace_project_wiki_history_path(@project.namespace, @project, @page), class: "btn" do - Page History + Page history - if can?(current_user, :create_wiki, @project) && @page.latest? = link_to namespace_project_wiki_edit_path(@project.namespace, @project, @page), class: "btn" do Edit diff --git a/app/views/projects/wikis/_new.html.haml b/app/views/projects/wikis/_new.html.haml index 3d33679f07d..ba47574563d 100644 --- a/app/views/projects/wikis/_new.html.haml +++ b/app/views/projects/wikis/_new.html.haml @@ -18,4 +18,4 @@ Tip: You can specify the full path for the new file. We will automatically create any missing directories. .form-actions - = button_tag 'Create Page', class: 'build-new-wiki btn btn-create' + = button_tag 'Create page', class: 'build-new-wiki btn btn-create' diff --git a/app/views/projects/wikis/edit.html.haml b/app/views/projects/wikis/edit.html.haml index 8cf018da1b7..b995d08cd02 100644 --- a/app/views/projects/wikis/edit.html.haml +++ b/app/views/projects/wikis/edit.html.haml @@ -22,10 +22,10 @@ .nav-controls - if can?(current_user, :create_wiki, @project) = link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do - New Page + New page - if @page.persisted? = link_to namespace_project_wiki_history_path(@project.namespace, @project, @page), class: "btn" do - Page History + Page history - if can?(current_user, :admin_wiki, @project) = link_to namespace_project_wiki_path(@project.namespace, @project, @page), data: { confirm: "Are you sure you want to delete this page?"}, method: :delete, class: "btn btn-danger" do Delete diff --git a/app/views/shared/labels/_form.html.haml b/app/views/shared/labels/_form.html.haml index 647e05e5ff7..e8b04f56839 100644 --- a/app/views/shared/labels/_form.html.haml +++ b/app/views/shared/labels/_form.html.haml @@ -29,5 +29,5 @@ - if @label.persisted? = f.submit 'Save changes', class: 'btn btn-save js-save-button' - else - = f.submit 'Create Label', class: 'btn btn-create js-save-button' + = f.submit 'Create label', class: 'btn btn-create js-save-button' = link_to 'Cancel', back_path, class: 'btn btn-cancel' diff --git a/app/views/shared/web_hooks/_form.html.haml b/app/views/shared/web_hooks/_form.html.haml index 37e2a377a69..ee3be3c789a 100644 --- a/app/views/shared/web_hooks/_form.html.haml +++ b/app/views/shared/web_hooks/_form.html.haml @@ -89,7 +89,7 @@ = f.label :enable_ssl_verification do = f.check_box :enable_ssl_verification %strong Enable SSL verification - = f.submit "Add Webhook", class: "btn btn-create" + = f.submit "Add webhook", class: "btn btn-create" %hr %h5.prepend-top-default Webhooks (#{hooks.count}) diff --git a/features/steps/project/builds/summary.rb b/features/steps/project/builds/summary.rb index 124582de6b9..229e5d7cdf4 100644 --- a/features/steps/project/builds/summary.rb +++ b/features/steps/project/builds/summary.rb @@ -12,7 +12,7 @@ class Spinach::Features::ProjectBuildsSummary < Spinach::FeatureSteps step 'I see button to CI Lint' do page.within('.nav-controls') do - ci_lint_tool_link = page.find_link('CI Lint') + ci_lint_tool_link = page.find_link('CI lint') expect(ci_lint_tool_link[:href]).to eq ci_lint_path end end diff --git a/features/steps/project/commits/commits.rb b/features/steps/project/commits/commits.rb index cf75fac8ac6..97ffd4b4ea2 100644 --- a/features/steps/project/commits/commits.rb +++ b/features/steps/project/commits/commits.rb @@ -13,7 +13,7 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps end step 'I click atom feed link' do - click_link "Commits Feed" + click_link "Commits feed" end step 'I see commits atom feed' do @@ -110,16 +110,16 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps end step 'I see button to create a new merge request' do - expect(page).to have_link 'Create Merge Request' + expect(page).to have_link 'Create merge request' end step 'I should not see button to create a new merge request' do - expect(page).not_to have_link 'Create Merge Request' + expect(page).not_to have_link 'Create merge request' end step 'I should see button to the merge request' do merge_request = MergeRequest.find_by(title: 'Feature') - expect(page).to have_link "View Open Merge Request", href: namespace_project_merge_request_path(@project.namespace, @project, merge_request) + expect(page).to have_link "View open merge request", href: namespace_project_merge_request_path(@project.namespace, @project, merge_request) end step 'I see breadcrumb links' do diff --git a/features/steps/project/deploy_keys.rb b/features/steps/project/deploy_keys.rb index 580a19494c2..ec59a2c094e 100644 --- a/features/steps/project/deploy_keys.rb +++ b/features/steps/project/deploy_keys.rb @@ -26,7 +26,7 @@ class Spinach::Features::ProjectDeployKeys < Spinach::FeatureSteps end step 'I click \'New Deploy Key\'' do - click_link 'New Deploy Key' + click_link 'New deploy key' end step 'I submit new deploy key' do diff --git a/features/steps/project/hooks.rb b/features/steps/project/hooks.rb index 0a71833a8a1..945d58a6458 100644 --- a/features/steps/project/hooks.rb +++ b/features/steps/project/hooks.rb @@ -25,14 +25,14 @@ class Spinach::Features::ProjectHooks < Spinach::FeatureSteps step 'I submit new hook' do @url = 'http://example.org/1' fill_in "hook_url", with: @url - expect { click_button "Add Webhook" }.to change(ProjectHook, :count).by(1) + expect { click_button "Add webhook" }.to change(ProjectHook, :count).by(1) end step 'I submit new hook with SSL verification enabled' do @url = 'http://example.org/2' fill_in "hook_url", with: @url check "hook_enable_ssl_verification" - expect { click_button "Add Webhook" }.to change(ProjectHook, :count).by(1) + expect { click_button "Add webhook" }.to change(ProjectHook, :count).by(1) end step 'I should see newly created hook' do diff --git a/features/steps/project/issues/issues.rb b/features/steps/project/issues/issues.rb index aaf0ede67e6..c0dc48f1bb2 100644 --- a/features/steps/project/issues/issues.rb +++ b/features/steps/project/issues/issues.rb @@ -61,7 +61,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps expect(page).to have_content "Tweet control" end - step 'I click link "New Issue"' do + step 'I click link "New issue"' do page.has_link?('New Issue') ? click_link('New Issue') : click_link('New issue') end diff --git a/features/steps/project/issues/labels.rb b/features/steps/project/issues/labels.rb index 4a35b71af2f..2828e41f731 100644 --- a/features/steps/project/issues/labels.rb +++ b/features/steps/project/issues/labels.rb @@ -31,19 +31,19 @@ class Spinach::Features::ProjectIssuesLabels < Spinach::FeatureSteps step 'I submit new label \'support\'' do fill_in 'Title', with: 'support' fill_in 'Background color', with: '#F95610' - click_button 'Create Label' + click_button 'Create label' end step 'I submit new label \'bug\'' do fill_in 'Title', with: 'bug' fill_in 'Background color', with: '#F95610' - click_button 'Create Label' + click_button 'Create label' end step 'I submit new label with invalid color' do fill_in 'Title', with: 'support' fill_in 'Background color', with: '#12' - click_button 'Create Label' + click_button 'Create label' end step 'I should see label label exist error message' do diff --git a/features/steps/project/issues/milestones.rb b/features/steps/project/issues/milestones.rb index 4faa0f4707c..fe94eb03acd 100644 --- a/features/steps/project/issues/milestones.rb +++ b/features/steps/project/issues/milestones.rb @@ -16,7 +16,7 @@ class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps end step 'I click link "New Milestone"' do - click_link "New Milestone" + click_link "New milestone" end step 'I submit new milestone "v2.3"' do diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index 5510c65265a..263ec321a34 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -300,10 +300,10 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps page.within('.current-note-edit-form', visible: true) do fill_in 'note_note', with: 'Typo, please fix' - click_button 'Save Comment' + click_button 'Save comment' end - expect(page).not_to have_button 'Save Comment', disabled: true, visible: true + expect(page).not_to have_button 'Save comment', disabled: true, visible: true end end @@ -378,7 +378,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end step 'merge request is mergeable' do - expect(page).to have_button 'Accept Merge Request' + expect(page).to have_button 'Accept merge request' end step 'I modify merge commit message' do @@ -392,7 +392,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps step 'I accept this merge request' do page.within '.mr-state-widget' do - click_button "Accept Merge Request" + click_button "Accept merge request" end end diff --git a/features/steps/project/merge_requests/acceptance.rb b/features/steps/project/merge_requests/acceptance.rb index 0a3f4649870..bdc7a616ba9 100644 --- a/features/steps/project/merge_requests/acceptance.rb +++ b/features/steps/project/merge_requests/acceptance.rb @@ -15,15 +15,15 @@ class Spinach::Features::ProjectMergeRequestsAcceptance < Spinach::FeatureSteps end step 'I click on Accept Merge Request' do - click_button('Accept Merge Request') + click_button('Accept merge request') end step 'I should see the Remove Source Branch button' do - expect(page).to have_link('Remove Source Branch') + expect(page).to have_link('Remove source branch') end step 'I should not see the Remove Source Branch button' do - expect(page).not_to have_link('Remove Source Branch') + expect(page).not_to have_link('Remove source branch') end step 'There is an open Merge Request' do diff --git a/features/steps/project/merge_requests/revert.rb b/features/steps/project/merge_requests/revert.rb index 31f95b524b3..a8f4e4ef027 100644 --- a/features/steps/project/merge_requests/revert.rb +++ b/features/steps/project/merge_requests/revert.rb @@ -26,7 +26,7 @@ class Spinach::Features::RevertMergeRequests < Spinach::FeatureSteps end step 'I click on Accept Merge Request' do - click_button('Accept Merge Request') + click_button('Accept merge request') end step 'I am signed in as a developer of the project' do diff --git a/features/steps/project/project_find_file.rb b/features/steps/project/project_find_file.rb index b8da5e6435d..461160b8430 100644 --- a/features/steps/project/project_find_file.rb +++ b/features/steps/project/project_find_file.rb @@ -9,7 +9,7 @@ class Spinach::Features::ProjectFindFile < Spinach::FeatureSteps end step 'I click Find File button' do - click_link 'Find File' + click_link 'Find file' end step 'I should see "find file" page' do diff --git a/features/steps/project/source/browse_files.rb b/features/steps/project/source/browse_files.rb index 553e397339e..5bd3c1a1246 100644 --- a/features/steps/project/source/browse_files.rb +++ b/features/steps/project/source/browse_files.rb @@ -105,7 +105,7 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step 'I click link "Diff"' do - click_link 'Preview Changes' + click_link 'Preview changes' end step 'I click on "Commit changes"' do diff --git a/features/steps/project/source/markdown_render.rb b/features/steps/project/source/markdown_render.rb index 9183de76881..115b67d98fb 100644 --- a/features/steps/project/source/markdown_render.rb +++ b/features/steps/project/source/markdown_render.rb @@ -214,7 +214,9 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps step 'I add various links to the wiki page' do fill_in "wiki[content]", with: "[test](test)\n[GitLab API doc](api)\n[Rake tasks](raketasks)\n" fill_in "wiki[message]", with: "Adding links to wiki" - click_button "Create page" + page.within '.wiki-form' do + click_button "Create page" + end end step 'Wiki page should have added links' do @@ -225,7 +227,9 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps step 'I add a header to the wiki page' do fill_in "wiki[content]", with: "# Wiki header\n" fill_in "wiki[message]", with: "Add header to wiki" - click_button "Create page" + page.within '.wiki-form' do + click_button "Create page" + end end step 'Wiki header should have correct id and link' do diff --git a/features/steps/project/wiki.rb b/features/steps/project/wiki.rb index 4cb0a21fbb4..517c257d892 100644 --- a/features/steps/project/wiki.rb +++ b/features/steps/project/wiki.rb @@ -16,12 +16,16 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps step 'I create the Wiki Home page' do fill_in "wiki_content", with: '[link test](test)' - click_on "Create page" + page.within '.wiki-form' do + click_on "Create page" + end end step 'I create the Wiki Home page with no content' do fill_in "wiki_content", with: '' - click_on "Create page" + page.within '.wiki-form' do + click_on "Create page" + end end step 'I should see the newly created wiki page' do @@ -29,7 +33,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps expect(page).to have_content "link test" click_link "link test" - expect(page).to have_content "Create Page" + expect(page).to have_content "Create page" end step 'I have an existing Wiki page' do @@ -63,7 +67,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps end step 'I click the History button' do - click_on "History" + click_on 'Page history' end step 'I should see both revisions' do @@ -121,15 +125,19 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps step 'I should see the new wiki page form' do expect(current_path).to match('wikis/image.jpg') expect(page).to have_content('New Wiki Page') - expect(page).to have_content('Create Page') + expect(page).to have_content('Create page') end step 'I create a New page with paths' do - click_on 'New Page' + click_on 'New page' fill_in 'Page slug', with: 'one/two/three-test' - click_on 'Create Page' + page.within '#modal-new-wiki' do + click_on 'Create page' + end fill_in "wiki_content", with: 'wiki content' - click_on "Create page" + page.within '.wiki-form' do + click_on "Create page" + end expect(current_path).to include 'one/two/three-test' end @@ -154,11 +162,11 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps step 'I view the page history of a Wiki page that has a path' do click_on 'Three' - click_on 'Page History' + click_on 'Page history' end step 'I click on Page History' do - click_on 'Page History' + click_on 'Page history' end step 'I should see the page history' do diff --git a/features/steps/shared/note.rb b/features/steps/shared/note.rb index fd925e0d447..7885cc7ab77 100644 --- a/features/steps/shared/note.rb +++ b/features/steps/shared/note.rb @@ -141,7 +141,7 @@ module SharedNote page.within(".current-note-edit-form") do fill_in 'note[note]', with: '+1 Awesome!' - click_button 'Save Comment' + click_button 'Save comment' end end diff --git a/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb b/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb index 7f11db3c417..77b7ba4ac7a 100644 --- a/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb +++ b/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb @@ -19,7 +19,7 @@ feature 'Check if mergeable with unresolved discussions', js: true, feature: tru it 'does not allow to merge' do visit_merge_request(merge_request) - expect(page).not_to have_button 'Accept Merge Request' + expect(page).not_to have_button 'Accept merge request' expect(page).to have_content('This merge request has unresolved discussions') end end @@ -32,7 +32,7 @@ feature 'Check if mergeable with unresolved discussions', js: true, feature: tru it 'allows MR to be merged' do visit_merge_request(merge_request) - expect(page).to have_button 'Accept Merge Request' + expect(page).to have_button 'Accept merge request' end end end @@ -46,7 +46,7 @@ feature 'Check if mergeable with unresolved discussions', js: true, feature: tru it 'does not allow to merge' do visit_merge_request(merge_request) - expect(page).to have_button 'Accept Merge Request' + expect(page).to have_button 'Accept merge request' end end @@ -58,7 +58,7 @@ feature 'Check if mergeable with unresolved discussions', js: true, feature: tru it 'allows MR to be merged' do visit_merge_request(merge_request) - expect(page).to have_button 'Accept Merge Request' + expect(page).to have_button 'Accept merge request' end end end diff --git a/spec/features/merge_requests/create_new_mr_spec.rb b/spec/features/merge_requests/create_new_mr_spec.rb index d4fe67c224f..3a4ec07b2b0 100644 --- a/spec/features/merge_requests/create_new_mr_spec.rb +++ b/spec/features/merge_requests/create_new_mr_spec.rb @@ -26,7 +26,7 @@ feature 'Create New Merge Request', feature: true, js: true do end it 'selects the target branch sha when a tag with the same name exists' do - visit namespace_project_merge_requests_path(project.namespace, project) + visit namespace_project_merge_requests_path(project.namespace, project) click_link 'New merge request' diff --git a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb index 79105b1ee46..497240803d4 100644 --- a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb +++ b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb @@ -32,7 +32,7 @@ feature 'Merge immediately', :feature, :js do page.within '.mr-widget-body' do find('.dropdown-toggle').click - click_link 'Merge Immediately' + click_link 'Merge immediately' expect(find('.js-merge-when-pipeline-succeeds-button')).to have_content('Merge in progress') diff --git a/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb b/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb index ed7193b9777..646e7bab265 100644 --- a/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb +++ b/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb @@ -28,25 +28,25 @@ feature 'Merge When Pipeline Succeeds', :feature, :js do visit_merge_request(merge_request) end - it 'displays the Merge When Pipeline Succeeds button' do - expect(page).to have_button "Merge When Pipeline Succeeds" + it 'displays the Merge when pipeline succeeds button' do + expect(page).to have_button "Merge when pipeline succeeds" end - describe 'enabling Merge When Pipeline Succeeds' do - shared_examples 'Merge When Pipeline Succeeds activator' do - it 'activates the Merge When Pipeline Succeeds feature' do - click_button "Merge When Pipeline Succeeds" + describe 'enabling Merge when pipeline succeeds' do + shared_examples 'Merge when pipeline succeeds activator' do + it 'activates the Merge when pipeline succeeds feature' do + click_button "Merge when pipeline succeeds" expect(page).to have_content "Set by #{user.name} to be merged automatically when the pipeline succeeds." expect(page).to have_content "The source branch will not be removed." - expect(page).to have_link "Cancel Automatic Merge" + expect(page).to have_link "Cancel automatic merge" visit_merge_request(merge_request) # Needed to refresh the page expect(page).to have_content /enabled an automatic merge when the pipeline for \h{8} succeeds/i end end context "when enabled immediately" do - it_behaves_like 'Merge When Pipeline Succeeds activator' + it_behaves_like 'Merge when pipeline succeeds activator' end context 'when enabled after pipeline status changed' do @@ -60,16 +60,16 @@ feature 'Merge When Pipeline Succeeds', :feature, :js do expect(page).to have_content "Pipeline ##{pipeline.id} running" end - it_behaves_like 'Merge When Pipeline Succeeds activator' + it_behaves_like 'Merge when pipeline succeeds activator' end context 'when enabled after it was previously canceled' do before do - click_button "Merge When Pipeline Succeeds" - click_link "Cancel Automatic Merge" + click_button "Merge when pipeline succeeds" + click_link "Cancel automatic merge" end - it_behaves_like 'Merge When Pipeline Succeeds activator' + it_behaves_like 'Merge when pipeline succeeds activator' end context 'when it was enabled and then canceled' do @@ -83,10 +83,10 @@ feature 'Merge When Pipeline Succeeds', :feature, :js do end before do - click_link "Cancel Automatic Merge" + click_link "Cancel automatic merge" end - it_behaves_like 'Merge When Pipeline Succeeds activator' + it_behaves_like 'Merge when pipeline succeeds activator' end end end @@ -110,18 +110,18 @@ feature 'Merge When Pipeline Succeeds', :feature, :js do end it 'allows to cancel the automatic merge' do - click_link "Cancel Automatic Merge" + click_link "Cancel automatic merge" - expect(page).to have_button "Merge When Pipeline Succeeds" + expect(page).to have_button "Merge when pipeline succeeds" visit_merge_request(merge_request) # refresh the page expect(page).to have_content "canceled the automatic merge" end it "allows the user to remove the source branch" do - expect(page).to have_link "Remove Source Branch When Merged" + expect(page).to have_link "Remove source branch when merged" - click_link "Remove Source Branch When Merged" + click_link "Remove source branch when merged" expect(page).to have_content "The source branch will be removed" end @@ -141,7 +141,7 @@ feature 'Merge When Pipeline Succeeds', :feature, :js do it "does not allow to enable merge when pipeline succeeds" do visit_merge_request(merge_request) - expect(page).not_to have_link 'Merge When Pipeline Succeeds' + expect(page).not_to have_link 'Merge when pipeline succeeds' end end diff --git a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb index 447764566e0..4a590e3bf68 100644 --- a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb +++ b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb @@ -14,7 +14,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'allows MR to be merged' do visit_merge_request(merge_request) - expect(page).to have_button 'Accept Merge Request' + expect(page).to have_button 'Accept merge request' end end @@ -38,8 +38,8 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'does not allow to merge immediately' do visit_merge_request(merge_request) - expect(page).to have_button 'Merge When Pipeline Succeeds' - expect(page).not_to have_button 'Select Merge Moment' + expect(page).to have_button 'Merge when pipeline succeeds' + expect(page).not_to have_button 'Select merge moment' end end @@ -49,7 +49,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'does not allow MR to be merged' do visit_merge_request(merge_request) - expect(page).not_to have_button 'Accept Merge Request' + expect(page).not_to have_button 'Accept merge request' expect(page).to have_content('Please retry the job or push a new commit to fix the failure.') end end @@ -60,7 +60,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'does not allow MR to be merged' do visit_merge_request(merge_request) - expect(page).not_to have_button 'Accept Merge Request' + expect(page).not_to have_button 'Accept merge request' expect(page).to have_content('Please retry the job or push a new commit to fix the failure.') end end @@ -71,7 +71,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'allows MR to be merged' do visit_merge_request(merge_request) - expect(page).to have_button 'Accept Merge Request' + expect(page).to have_button 'Accept merge request' end end @@ -81,7 +81,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'allows MR to be merged' do visit_merge_request(merge_request) - expect(page).to have_button 'Accept Merge Request' + expect(page).to have_button 'Accept merge request' end end end @@ -97,10 +97,10 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'allows MR to be merged immediately', js: true do visit_merge_request(merge_request) - expect(page).to have_button 'Merge When Pipeline Succeeds' + expect(page).to have_button 'Merge when pipeline succeeds' - click_button 'Select Merge Moment' - expect(page).to have_content 'Merge Immediately' + click_button 'Select merge moment' + expect(page).to have_content 'Merge immediately' end end @@ -110,7 +110,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'allows MR to be merged' do visit_merge_request(merge_request) - expect(page).to have_button 'Accept Merge Request' + expect(page).to have_button 'Accept merge request' end end @@ -120,7 +120,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'allows MR to be merged' do visit_merge_request(merge_request) - expect(page).to have_button 'Accept Merge Request' + expect(page).to have_button 'Accept merge request' end end end diff --git a/spec/features/merge_requests/widget_spec.rb b/spec/features/merge_requests/widget_spec.rb index c2db7d8da3c..a62c5435748 100644 --- a/spec/features/merge_requests/widget_spec.rb +++ b/spec/features/merge_requests/widget_spec.rb @@ -145,7 +145,7 @@ describe 'Merge request', :feature, :js do before do allow_any_instance_of(Repository).to receive(:merge).and_return(false) visit namespace_project_merge_request_path(project.namespace, project, merge_request) - click_button 'Accept Merge Request' + click_button 'Accept merge request' wait_for_ajax end diff --git a/spec/features/projects/files/template_type_dropdown_spec.rb b/spec/features/projects/files/template_type_dropdown_spec.rb index 5fd86bb07a8..9fcf12e6cb9 100644 --- a/spec/features/projects/files/template_type_dropdown_spec.rb +++ b/spec/features/projects/files/template_type_dropdown_spec.rb @@ -48,7 +48,7 @@ feature 'Template type dropdown selector', js: true do context 'user previews changes' do before do - click_link 'Preview Changes' + click_link 'Preview changes' end scenario 'type selector is hidden and shown correctly' do diff --git a/spec/features/projects/merge_request_button_spec.rb b/spec/features/projects/merge_request_button_spec.rb index b6728960fb8..05f3162f13c 100644 --- a/spec/features/projects/merge_request_button_spec.rb +++ b/spec/features/projects/merge_request_button_spec.rb @@ -1,13 +1,13 @@ require 'spec_helper' feature 'Merge Request button', feature: true do - shared_examples 'Merge Request button only shown when allowed' do + shared_examples 'Merge request button only shown when allowed' do let(:user) { create(:user) } let(:project) { create(:project, :public) } let(:forked_project) { create(:project, :public, forked_from_project: project) } context 'not logged in' do - it 'does not show Create Merge Request button' do + it 'does not show Create merge request button' do visit url within("#content-body") do @@ -22,7 +22,7 @@ feature 'Merge Request button', feature: true do project.team << [user, :developer] end - it 'shows Create Merge Request button' do + it 'shows Create merge request button' do href = new_namespace_project_merge_request_path(project.namespace, project, merge_request: { source_branch: 'feature', @@ -40,7 +40,7 @@ feature 'Merge Request button', feature: true do project.project_feature.update!(merge_requests_access_level: ProjectFeature::DISABLED) end - it 'does not show Create Merge Request button' do + it 'does not show Create merge request button' do visit url within("#content-body") do @@ -55,7 +55,7 @@ feature 'Merge Request button', feature: true do login_as(user) end - it 'does not show Create Merge Request button' do + it 'does not show Create merge request button' do visit url within("#content-body") do @@ -66,7 +66,7 @@ feature 'Merge Request button', feature: true do context 'on own fork of project' do let(:user) { forked_project.owner } - it 'shows Create Merge Request button' do + it 'shows Create merge request button' do href = new_namespace_project_merge_request_path(forked_project.namespace, forked_project, merge_request: { source_branch: 'feature', @@ -83,24 +83,24 @@ feature 'Merge Request button', feature: true do end context 'on branches page' do - it_behaves_like 'Merge Request button only shown when allowed' do - let(:label) { 'Merge Request' } + it_behaves_like 'Merge request button only shown when allowed' do + let(:label) { 'Merge request' } let(:url) { namespace_project_branches_path(project.namespace, project) } let(:fork_url) { namespace_project_branches_path(forked_project.namespace, forked_project) } end end context 'on compare page' do - it_behaves_like 'Merge Request button only shown when allowed' do - let(:label) { 'Create Merge Request' } + it_behaves_like 'Merge request button only shown when allowed' do + let(:label) { 'Create merge request' } let(:url) { namespace_project_compare_path(project.namespace, project, from: 'master', to: 'feature') } let(:fork_url) { namespace_project_compare_path(forked_project.namespace, forked_project, from: 'master', to: 'feature') } end end context 'on commits page' do - it_behaves_like 'Merge Request button only shown when allowed' do - let(:label) { 'Create Merge Request' } + it_behaves_like 'Merge request button only shown when allowed' do + let(:label) { 'Create merge request' } let(:url) { namespace_project_commits_path(project.namespace, project, 'feature') } let(:fork_url) { namespace_project_commits_path(forked_project.namespace, forked_project, 'feature') } end diff --git a/spec/features/projects/wiki/markdown_preview_spec.rb b/spec/features/projects/wiki/markdown_preview_spec.rb index a1c386ddc18..43d8b45669e 100644 --- a/spec/features/projects/wiki/markdown_preview_spec.rb +++ b/spec/features/projects/wiki/markdown_preview_spec.rb @@ -24,12 +24,16 @@ feature 'Projects > Wiki > User previews markdown changes', feature: true, js: t context "while creating a new wiki page" do context "when there are no spaces or hyphens in the page name" do it "rewrites relative links as expected" do - click_link 'New Page' - fill_in :new_wiki_path, with: 'a/b/c/d' - click_button 'Create Page' + click_link 'New page' + page.within '#modal-new-wiki' do + fill_in :new_wiki_path, with: 'a/b/c/d' + click_button 'Create page' + end - fill_in :wiki_content, with: wiki_content - click_on "Preview" + page.within '.wiki-form' do + fill_in :wiki_content, with: wiki_content + click_on "Preview" + end expect(page).to have_content("regular link") @@ -42,12 +46,16 @@ feature 'Projects > Wiki > User previews markdown changes', feature: true, js: t context "when there are spaces in the page name" do it "rewrites relative links as expected" do - click_link 'New Page' - fill_in :new_wiki_path, with: 'a page/b page/c page/d page' - click_button 'Create Page' + click_link 'New page' + page.within '#modal-new-wiki' do + fill_in :new_wiki_path, with: 'a page/b page/c page/d page' + click_button 'Create page' + end - fill_in :wiki_content, with: wiki_content - click_on "Preview" + page.within '.wiki-form' do + fill_in :wiki_content, with: wiki_content + click_on "Preview" + end expect(page).to have_content("regular link") @@ -60,12 +68,16 @@ feature 'Projects > Wiki > User previews markdown changes', feature: true, js: t context "when there are hyphens in the page name" do it "rewrites relative links as expected" do - click_link 'New Page' - fill_in :new_wiki_path, with: 'a-page/b-page/c-page/d-page' - click_button 'Create Page' - - fill_in :wiki_content, with: wiki_content - click_on "Preview" + click_link 'New page' + page.within '#modal-new-wiki' do + fill_in :new_wiki_path, with: 'a-page/b-page/c-page/d-page' + click_button 'Create page' + end + + page.within '.wiki-form' do + fill_in :wiki_content, with: wiki_content + click_on "Preview" + end expect(page).to have_content("regular link") @@ -79,11 +91,17 @@ feature 'Projects > Wiki > User previews markdown changes', feature: true, js: t context "while editing a wiki page" do def create_wiki_page(path) - click_link 'New Page' - fill_in :new_wiki_path, with: path - click_button 'Create Page' - fill_in :wiki_content, with: 'content' - click_on "Create page" + click_link 'New page' + + page.within '#modal-new-wiki' do + fill_in :new_wiki_path, with: path + click_button 'Create page' + end + + page.within '.wiki-form' do + fill_in :wiki_content, with: 'content' + click_on "Create page" + end end context "when there are no spaces or hyphens in the page name" do diff --git a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb index 7bdaafd1beb..1ffac8cd542 100644 --- a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb @@ -21,8 +21,9 @@ feature 'Projects > Wiki > User creates wiki page', feature: true do scenario 'directly from the wiki home page' do fill_in :wiki_content, with: 'My awesome wiki!' - click_button 'Create page' - + page.within '.wiki-form' do + click_button 'Create page' + end expect(page).to have_content('Home') expect(page).to have_content("Last edited by #{user.name}") expect(page).to have_content('My awesome wiki!') @@ -36,16 +37,20 @@ feature 'Projects > Wiki > User creates wiki page', feature: true do context 'via the "new wiki page" page' do scenario 'when the wiki page has a single word name', js: true do - click_link 'New Page' + click_link 'New page' - fill_in :new_wiki_path, with: 'foo' - click_button 'Create Page' + page.within '#modal-new-wiki' do + fill_in :new_wiki_path, with: 'foo' + click_button 'Create page' + end # Commit message field should have correct value. expect(page).to have_field('wiki[message]', with: 'Create foo') - fill_in :wiki_content, with: 'My awesome wiki!' - click_button 'Create page' + page.within '.wiki-form' do + fill_in :wiki_content, with: 'My awesome wiki!' + click_button 'Create page' + end expect(page).to have_content('Foo') expect(page).to have_content("Last edited by #{user.name}") @@ -53,16 +58,20 @@ feature 'Projects > Wiki > User creates wiki page', feature: true do end scenario 'when the wiki page has spaces in the name', js: true do - click_link 'New Page' + click_link 'New page' - fill_in :new_wiki_path, with: 'Spaces in the name' - click_button 'Create Page' + page.within '#modal-new-wiki' do + fill_in :new_wiki_path, with: 'Spaces in the name' + click_button 'Create page' + end # Commit message field should have correct value. expect(page).to have_field('wiki[message]', with: 'Create spaces in the name') - fill_in :wiki_content, with: 'My awesome wiki!' - click_button 'Create page' + page.within '.wiki-form' do + fill_in :wiki_content, with: 'My awesome wiki!' + click_button 'Create page' + end expect(page).to have_content('Spaces in the name') expect(page).to have_content("Last edited by #{user.name}") @@ -70,16 +79,20 @@ feature 'Projects > Wiki > User creates wiki page', feature: true do end scenario 'when the wiki page has hyphens in the name', js: true do - click_link 'New Page' + click_link 'New page' - fill_in :new_wiki_path, with: 'hyphens-in-the-name' - click_button 'Create Page' + page.within '#modal-new-wiki' do + fill_in :new_wiki_path, with: 'hyphens-in-the-name' + click_button 'Create page' + end # Commit message field should have correct value. expect(page).to have_field('wiki[message]', with: 'Create hyphens in the name') - fill_in :wiki_content, with: 'My awesome wiki!' - click_button 'Create page' + page.within '.wiki-form' do + fill_in :wiki_content, with: 'My awesome wiki!' + click_button 'Create page' + end expect(page).to have_content('Hyphens in the name') expect(page).to have_content("Last edited by #{user.name}") @@ -99,7 +112,9 @@ feature 'Projects > Wiki > User creates wiki page', feature: true do scenario 'directly from the wiki home page' do fill_in :wiki_content, with: 'My awesome wiki!' - click_button 'Create page' + page.within '.wiki-form' do + click_button 'Create page' + end expect(page).to have_content('Home') expect(page).to have_content("Last edited by #{user.name}") @@ -113,16 +128,20 @@ feature 'Projects > Wiki > User creates wiki page', feature: true do end scenario 'via the "new wiki page" page', js: true do - click_link 'New Page' + click_link 'New page' - fill_in :new_wiki_path, with: 'foo' - click_button 'Create Page' + page.within '#modal-new-wiki' do + fill_in :new_wiki_path, with: 'foo' + click_button 'Create page' + end # Commit message field should have correct value. expect(page).to have_field('wiki[message]', with: 'Create foo') - fill_in :wiki_content, with: 'My awesome wiki!' - click_button 'Create page' + page.within '.wiki-form' do + fill_in :wiki_content, with: 'My awesome wiki!' + click_button 'Create page' + end expect(page).to have_content('Foo') expect(page).to have_content("Last edited by #{user.name}") From 745058c0529b4eb719c730d3067594b681cb0694 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Thu, 6 Apr 2017 09:44:06 -0500 Subject: [PATCH 070/113] Added CHANGELOG --- changelogs/unreleased/button-capitalization.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changelogs/unreleased/button-capitalization.yml diff --git a/changelogs/unreleased/button-capitalization.yml b/changelogs/unreleased/button-capitalization.yml new file mode 100644 index 00000000000..13b3beea40c --- /dev/null +++ b/changelogs/unreleased/button-capitalization.yml @@ -0,0 +1,4 @@ +--- +title: Changed capitalisation of buttons across GitLab +merge_request: 10418 +author: From 12c18ee546c10bd6af0dbeb5d86f16836863356b Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Thu, 6 Apr 2017 21:10:14 +0000 Subject: [PATCH 071/113] Copy diff file path as GFM --- app/assets/javascripts/copy_to_clipboard.js | 34 ++++++++++++++++--- app/helpers/blob_helper.rb | 4 +-- app/helpers/button_helper.rb | 25 ++++++++++++-- .../personal_access_tokens/index.html.haml | 2 +- app/views/projects/_last_push.html.haml | 2 +- .../projects/commit/_commit_box.html.haml | 2 +- app/views/projects/commits/_commit.html.haml | 2 +- .../projects/issues/_issue_by_email.html.haml | 2 +- .../show/_how_to_merge.html.haml | 6 ++-- app/views/projects/pipelines/_info.html.haml | 2 +- .../registry/repositories/_tag.html.haml | 2 +- .../_detailed_help.html.haml | 14 ++++---- .../slack_slash_commands/_help.html.haml | 10 +++--- .../projects/tree/_tree_content.html.haml | 2 +- .../projects/triggers/_trigger.html.haml | 2 +- app/views/shared/_clone_panel.html.haml | 2 +- .../_personal_access_tokens_table.html.haml | 2 +- app/views/shared/issuable/_sidebar.html.haml | 4 +-- .../shared/milestones/_sidebar.html.haml | 4 +-- .../dm-copy-diff-file-title-as-gfm.yml | 4 +++ 20 files changed, 88 insertions(+), 39 deletions(-) create mode 100644 changelogs/unreleased/dm-copy-diff-file-title-as-gfm.yml diff --git a/app/assets/javascripts/copy_to_clipboard.js b/app/assets/javascripts/copy_to_clipboard.js index 6dbec50b890..ab9a8e43dd1 100644 --- a/app/assets/javascripts/copy_to_clipboard.js +++ b/app/assets/javascripts/copy_to_clipboard.js @@ -38,9 +38,35 @@ showTooltip = function(target, title) { }; $(function() { - var clipboard; - - clipboard = new Clipboard('[data-clipboard-target], [data-clipboard-text]'); + const clipboard = new Clipboard('[data-clipboard-target], [data-clipboard-text]'); clipboard.on('success', genericSuccess); - return clipboard.on('error', genericError); + clipboard.on('error', genericError); + + // This a workaround around ClipboardJS limitations to allow the context-specific copy/pasting of plain text or GFM. + // The Ruby `clipboard_button` helper sneaks a JSON hash with `text` and `gfm` keys into the `data-clipboard-text` + // attribute that ClipboardJS reads from. + // When ClipboardJS creates a new `textarea` (directly inside `body`, with a `readonly` attribute`), sets its value + // to the value of this data attribute, focusses on it, and finally programmatically issues the 'Copy' command, + // this code intercepts the copy command/event at the last minute to deconstruct this JSON hash and set the + // `text/plain` and `text/x-gfm` copy data types to the intended values. + $(document).on('copy', 'body > textarea[readonly]', function(e) { + const clipboardData = e.originalEvent.clipboardData; + if (!clipboardData) return; + + const text = e.target.value; + + let json; + try { + json = JSON.parse(text); + } catch (ex) { + return; + } + + if (!json.text || !json.gfm) return; + + e.preventDefault(); + + clipboardData.setData('text/plain', json.text); + clipboardData.setData('text/x-gfm', json.gfm); + }); }); diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 91d6d1852cf..14f9b237a51 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -210,13 +210,13 @@ module BlobHelper end def copy_file_path_button(file_path) - clipboard_button(clipboard_text: file_path, class: 'btn-clipboard btn-transparent prepend-left-5', title: 'Copy file path to clipboard') + clipboard_button(text: file_path, gfm: "`#{file_path}`", class: 'btn-clipboard btn-transparent prepend-left-5', title: 'Copy file path to clipboard') end def copy_blob_content_button(blob) return if markup?(blob.name) - clipboard_button(clipboard_target: ".blob-content[data-blob-id='#{blob.id}']", class: "btn btn-sm", title: "Copy content to clipboard") + clipboard_button(target: ".blob-content[data-blob-id='#{blob.id}']", class: "btn btn-sm", title: "Copy content to clipboard") end def open_raw_file_button(path) diff --git a/app/helpers/button_helper.rb b/app/helpers/button_helper.rb index 0b30471f2ae..c85e96cf78d 100644 --- a/app/helpers/button_helper.rb +++ b/app/helpers/button_helper.rb @@ -1,23 +1,42 @@ module ButtonHelper # Output a "Copy to Clipboard" button # - # data - Data attributes passed to `content_tag` + # data - Data attributes passed to `content_tag` (default: {}): + # :text - Text to copy (optional) + # :gfm - GitLab Flavored Markdown to copy, if different from `text` (optional) + # :target - Selector for target element to copy from (optional) # # Examples: # # # Define the clipboard's text - # clipboard_button(clipboard_text: "Foo") + # clipboard_button(text: "Foo") # # => "" # # # Define the target element - # clipboard_button(clipboard_target: "div#foo") + # clipboard_button(target: "div#foo") # # => "" # # See http://clipboardjs.com/#usage def clipboard_button(data = {}) css_class = data[:class] || 'btn-clipboard btn-transparent' title = data[:title] || 'Copy to clipboard' + + # This supports code in app/assets/javascripts/copy_to_clipboard.js that + # works around ClipboardJS limitations to allow the context-specific copy/pasting of plain text or GFM. + if text = data.delete(:text) + data[:clipboard_text] = + if gfm = data.delete(:gfm) + { text: text, gfm: gfm } + else + text + end + end + + target = data.delete(:target) + data[:clipboard_target] = target if target + data = { toggle: 'tooltip', placement: 'bottom', container: 'body' }.merge(data) + content_tag :button, icon('clipboard', 'aria-hidden': 'true'), class: "btn #{css_class}", diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml index 0645ecad496..c852107e69a 100644 --- a/app/views/profiles/personal_access_tokens/index.html.haml +++ b/app/views/profiles/personal_access_tokens/index.html.haml @@ -19,7 +19,7 @@ Your New Personal Access Token .form-group = text_field_tag 'created-personal-access-token', flash[:personal_access_token], readonly: true, class: "form-control", 'aria-describedby' => "created-personal-access-token-help-block" - = clipboard_button(clipboard_text: flash[:personal_access_token], title: "Copy personal access token to clipboard", placement: "left") + = clipboard_button(text: flash[:personal_access_token], title: "Copy personal access token to clipboard", placement: "left") %span#created-personal-access-token-help-block.help-block.text-danger Make sure you save it - you won't be able to access it again. %hr diff --git a/app/views/projects/_last_push.html.haml b/app/views/projects/_last_push.html.haml index a08436715d2..ee7d4e36d4b 100644 --- a/app/views/projects/_last_push.html.haml +++ b/app/views/projects/_last_push.html.haml @@ -10,7 +10,7 @@ - if @project && event.project != @project %span at %strong= link_to_project event.project - = clipboard_button(clipboard_text: event.ref_name, class: 'btn-clipboard btn-transparent', title: 'Copy branch to clipboard') + = clipboard_button(text: event.ref_name, class: 'btn-clipboard btn-transparent', title: 'Copy branch to clipboard') #{time_ago_with_tooltip(event.created_at)} .pull-right diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml index a0a292d0508..fa951792569 100644 --- a/app/views/projects/commit/_commit_box.html.haml +++ b/app/views/projects/commit/_commit_box.html.haml @@ -1,7 +1,7 @@ .page-content-header .header-main-content %strong Commit #{@commit.short_id} - = clipboard_button(clipboard_text: @commit.id, title: "Copy commit SHA to clipboard") + = clipboard_button(text: @commit.id, title: "Copy commit SHA to clipboard") %span.hidden-xs authored #{time_ago_with_tooltip(@commit.authored_date)} %span by diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml index 4b1ff75541a..8f32d2b72e5 100644 --- a/app/views/projects/commits/_commit.html.haml +++ b/app/views/projects/commits/_commit.html.haml @@ -37,6 +37,6 @@ .commit-actions.flex-row.hidden-xs - if commit.status(ref) = render_commit_status(commit, ref: ref) - = clipboard_button(clipboard_text: commit.id, title: "Copy commit SHA to clipboard") + = clipboard_button(text: commit.id, title: "Copy commit SHA to clipboard") = link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit-short-id btn btn-transparent" = link_to_browse_code(project, commit) diff --git a/app/views/projects/issues/_issue_by_email.html.haml b/app/views/projects/issues/_issue_by_email.html.haml index d2038a2be68..da65157a10b 100644 --- a/app/views/projects/issues/_issue_by_email.html.haml +++ b/app/views/projects/issues/_issue_by_email.html.haml @@ -16,7 +16,7 @@ .email-modal-input-group.input-group = text_field_tag :issue_email, email, class: "monospace js-select-on-focus form-control", readonly: true .input-group-btn - = clipboard_button(clipboard_target: '#issue_email') + = clipboard_button(target: '#issue_email') %p The subject will be used as the title of the new issue, and the message will be the description. diff --git a/app/views/projects/merge_requests/show/_how_to_merge.html.haml b/app/views/projects/merge_requests/show/_how_to_merge.html.haml index cde0ce08e14..f3372c7657f 100644 --- a/app/views/projects/merge_requests/show/_how_to_merge.html.haml +++ b/app/views/projects/merge_requests/show/_how_to_merge.html.haml @@ -8,7 +8,7 @@ %p %strong Step 1. Fetch and check out the branch for this merge request - = clipboard_button(clipboard_target: "pre#merge-info-1", title: "Copy commands to clipboard") + = clipboard_button(target: "pre#merge-info-1", title: "Copy commands to clipboard") %pre.dark#merge-info-1 - if @merge_request.for_fork? :preserve @@ -25,7 +25,7 @@ %p %strong Step 3. Merge the branch and fix any conflicts that come up - = clipboard_button(clipboard_target: "pre#merge-info-3", title: "Copy commands to clipboard") + = clipboard_button(target: "pre#merge-info-3", title: "Copy commands to clipboard") %pre.dark#merge-info-3 - if @merge_request.for_fork? :preserve @@ -38,7 +38,7 @@ %p %strong Step 4. Push the result of the merge to GitLab - = clipboard_button(clipboard_target: "pre#merge-info-4", title: "Copy commands to clipboard") + = clipboard_button(target: "pre#merge-info-4", title: "Copy commands to clipboard") %pre.dark#merge-info-4 :preserve git push origin #{h @merge_request.target_branch} diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml index 4be9a1371ec..fc1d0989787 100644 --- a/app/views/projects/pipelines/_info.html.haml +++ b/app/views/projects/pipelines/_info.html.haml @@ -46,4 +46,4 @@ \... %span.js-details-content.hide = link_to @pipeline.sha, namespace_project_commit_path(@project.namespace, @project, @pipeline.sha), class: "monospace commit-hash-full" - = clipboard_button(clipboard_text: @pipeline.sha, title: "Copy commit SHA to clipboard") + = clipboard_button(text: @pipeline.sha, title: "Copy commit SHA to clipboard") diff --git a/app/views/projects/registry/repositories/_tag.html.haml b/app/views/projects/registry/repositories/_tag.html.haml index ee1ec0e8f9a..854b7d0ebf7 100644 --- a/app/views/projects/registry/repositories/_tag.html.haml +++ b/app/views/projects/registry/repositories/_tag.html.haml @@ -1,7 +1,7 @@ %tr.tag %td = escape_once(tag.name) - = clipboard_button(clipboard_text: "docker pull #{tag.path}") + = clipboard_button(text: "docker pull #{tag.path}") %td - if tag.revision %span.has-tooltip{ title: "#{tag.revision}" } diff --git a/app/views/projects/services/mattermost_slash_commands/_detailed_help.html.haml b/app/views/projects/services/mattermost_slash_commands/_detailed_help.html.haml index 2fb88297fb3..ef3599460f1 100644 --- a/app/views/projects/services/mattermost_slash_commands/_detailed_help.html.haml +++ b/app/views/projects/services/mattermost_slash_commands/_detailed_help.html.haml @@ -22,14 +22,14 @@ .col-sm-10.col-xs-12.input-group = text_field_tag :display_name, "GitLab / #{@project.name_with_namespace}", class: 'form-control input-sm', readonly: 'readonly' .input-group-btn - = clipboard_button(clipboard_target: '#display_name') + = clipboard_button(target: '#display_name') .form-group = label_tag :description, 'Description', class: 'col-sm-2 col-xs-12 control-label' .col-sm-10.col-xs-12.input-group = text_field_tag :description, run_actions_text, class: 'form-control input-sm', readonly: 'readonly' .input-group-btn - = clipboard_button(clipboard_target: '#description') + = clipboard_button(target: '#description') .form-group = label_tag nil, 'Command trigger word', class: 'col-sm-2 col-xs-12 control-label' @@ -46,7 +46,7 @@ .col-sm-10.col-xs-12.input-group = text_field_tag :request_url, service_trigger_url(subject), class: 'form-control input-sm', readonly: 'readonly' .input-group-btn - = clipboard_button(clipboard_target: '#request_url') + = clipboard_button(target: '#request_url') .form-group = label_tag nil, 'Request method', class: 'col-sm-2 col-xs-12 control-label' @@ -57,14 +57,14 @@ .col-sm-10.col-xs-12.input-group = text_field_tag :response_username, 'GitLab', class: 'form-control input-sm', readonly: 'readonly' .input-group-btn - = clipboard_button(clipboard_target: '#response_username') + = clipboard_button(target: '#response_username') .form-group = label_tag :response_icon, 'Response icon', class: 'col-sm-2 col-xs-12 control-label' .col-sm-10.col-xs-12.input-group = text_field_tag :response_icon, asset_url('gitlab_logo.png'), class: 'form-control input-sm', readonly: 'readonly' .input-group-btn - = clipboard_button(clipboard_target: '#response_icon') + = clipboard_button(target: '#response_icon') .form-group = label_tag nil, 'Autocomplete', class: 'col-sm-2 col-xs-12 control-label' @@ -75,14 +75,14 @@ .col-sm-10.col-xs-12.input-group = text_field_tag :autocomplete_hint, '[help]', class: 'form-control input-sm', readonly: 'readonly' .input-group-btn - = clipboard_button(clipboard_target: '#autocomplete_hint') + = clipboard_button(target: '#autocomplete_hint') .form-group = label_tag :autocomplete_description, 'Autocomplete description', class: 'col-sm-2 col-xs-12 control-label' .col-sm-10.col-xs-12.input-group = text_field_tag :autocomplete_description, run_actions_text, class: 'form-control input-sm', readonly: 'readonly' .input-group-btn - = clipboard_button(clipboard_target: '#autocomplete_description') + = clipboard_button(target: '#autocomplete_description') %hr diff --git a/app/views/projects/services/slack_slash_commands/_help.html.haml b/app/views/projects/services/slack_slash_commands/_help.html.haml index 078b7be6865..73b99453a4b 100644 --- a/app/views/projects/services/slack_slash_commands/_help.html.haml +++ b/app/views/projects/services/slack_slash_commands/_help.html.haml @@ -40,7 +40,7 @@ .col-sm-10.col-xs-12.input-group = text_field_tag :url, service_trigger_url(subject), class: 'form-control input-sm', readonly: 'readonly' .input-group-btn - = clipboard_button(clipboard_target: '#url') + = clipboard_button(target: '#url') .form-group = label_tag nil, 'Method', class: 'col-sm-2 col-xs-12 control-label' @@ -51,7 +51,7 @@ .col-sm-10.col-xs-12.input-group = text_field_tag :customize_name, 'GitLab', class: 'form-control input-sm', readonly: 'readonly' .input-group-btn - = clipboard_button(clipboard_target: '#customize_name') + = clipboard_button(target: '#customize_name') .form-group = label_tag nil, 'Customize icon', class: 'col-sm-2 col-xs-12 control-label' @@ -68,21 +68,21 @@ .col-sm-10.col-xs-12.input-group = text_field_tag :autocomplete_description, run_actions_text, class: 'form-control input-sm', readonly: 'readonly' .input-group-btn - = clipboard_button(clipboard_target: '#autocomplete_description') + = clipboard_button(target: '#autocomplete_description') .form-group = label_tag :autocomplete_usage_hint, 'Autocomplete usage hint', class: 'col-sm-2 col-xs-12 control-label' .col-sm-10.col-xs-12.input-group = text_field_tag :autocomplete_usage_hint, '[help]', class: 'form-control input-sm', readonly: 'readonly' .input-group-btn - = clipboard_button(clipboard_target: '#autocomplete_usage_hint') + = clipboard_button(target: '#autocomplete_usage_hint') .form-group = label_tag :descriptive_label, 'Descriptive label', class: 'col-sm-2 col-xs-12 control-label' .col-sm-10.col-xs-12.input-group = text_field_tag :descriptive_label, 'Perform common operations on GitLab project', class: 'form-control input-sm', readonly: 'readonly' .input-group-btn - = clipboard_button(clipboard_target: '#descriptive_label') + = clipboard_button(target: '#descriptive_label') %hr diff --git a/app/views/projects/tree/_tree_content.html.haml b/app/views/projects/tree/_tree_content.html.haml index 6855c463c6d..2497a2d91b1 100644 --- a/app/views/projects/tree/_tree_content.html.haml +++ b/app/views/projects/tree/_tree_content.html.haml @@ -10,7 +10,7 @@ %i.fa.fa-angle-right %small.light = link_to @commit.short_id, namespace_project_commit_path(@project.namespace, @project, @commit), class: "monospace" - = clipboard_button(clipboard_text: @commit.id, title: "Copy commit SHA to clipboard") + = clipboard_button(text: @commit.id, title: "Copy commit SHA to clipboard") = time_ago_with_tooltip(@commit.committed_date) \- = @commit.full_title diff --git a/app/views/projects/triggers/_trigger.html.haml b/app/views/projects/triggers/_trigger.html.haml index ed68e0ed56d..9b5f63ae81a 100644 --- a/app/views/projects/triggers/_trigger.html.haml +++ b/app/views/projects/triggers/_trigger.html.haml @@ -2,7 +2,7 @@ %td - if can?(current_user, :admin_trigger, trigger) %span= trigger.token - = clipboard_button(clipboard_text: trigger.token, title: "Copy trigger token to clipboard") + = clipboard_button(text: trigger.token, title: "Copy trigger token to clipboard") - else %span= trigger.short_token diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml index 03684389742..34a4d7398bc 100644 --- a/app/views/shared/_clone_panel.html.haml +++ b/app/views/shared/_clone_panel.html.haml @@ -19,7 +19,7 @@ = text_field_tag :project_clone, default_url_to_repo(project), class: "js-select-on-focus form-control", readonly: true .input-group-btn - = clipboard_button(clipboard_target: '#project_clone', title: "Copy URL to clipboard") + = clipboard_button(target: '#project_clone', title: "Copy URL to clipboard") :javascript $('ul.clone-options-dropdown a').on('click',function(e){ diff --git a/app/views/shared/_personal_access_tokens_table.html.haml b/app/views/shared/_personal_access_tokens_table.html.haml index 67a49815478..ab7a2db002e 100644 --- a/app/views/shared/_personal_access_tokens_table.html.haml +++ b/app/views/shared/_personal_access_tokens_table.html.haml @@ -33,7 +33,7 @@ - if impersonation %td.token-token-container = text_field_tag 'impersonation-token-token', token.token, readonly: true, class: "form-control" - = clipboard_button(clipboard_text: token.token) + = clipboard_button(text: token.token) - path = impersonation ? revoke_admin_user_impersonation_token_path(token.user, token) : revoke_profile_personal_access_token_path(token) %td= link_to "Revoke", path, method: :put, class: "btn btn-danger pull-right", data: { confirm: "Are you sure you want to revoke this #{type} Token? This action cannot be undone." } - else diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index 92d2d93a732..2e0d6a129fb 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -160,13 +160,13 @@ - project_ref = cross_project_reference(@project, issuable) .block.project-reference .sidebar-collapsed-icon.dont-change-state - = clipboard_button(clipboard_text: project_ref, title: "Copy reference to clipboard", placement: "left") + = clipboard_button(text: project_ref, title: "Copy reference to clipboard", placement: "left") .cross-project-reference.hide-collapsed %span Reference: %cite{ title: project_ref } = project_ref - = clipboard_button(clipboard_text: project_ref, title: "Copy reference to clipboard", placement: "left") + = clipboard_button(text: project_ref, title: "Copy reference to clipboard", placement: "left") :javascript gl.IssuableResource = new gl.SubbableResource('#{issuable_json_path(issuable)}'); diff --git a/app/views/shared/milestones/_sidebar.html.haml b/app/views/shared/milestones/_sidebar.html.haml index 2810f1377b2..ccc808ff43e 100644 --- a/app/views/shared/milestones/_sidebar.html.haml +++ b/app/views/shared/milestones/_sidebar.html.haml @@ -122,10 +122,10 @@ - if milestone_ref.present? .block.reference .sidebar-collapsed-icon.dont-change-state - = clipboard_button(clipboard_text: milestone_ref, title: "Copy reference to clipboard", placement: "left") + = clipboard_button(text: milestone_ref, title: "Copy reference to clipboard", placement: "left") .cross-project-reference.hide-collapsed %span Reference: %cite{ title: milestone_ref } = milestone_ref - = clipboard_button(clipboard_text: milestone_ref, title: "Copy reference to clipboard", placement: "left") + = clipboard_button(text: milestone_ref, title: "Copy reference to clipboard", placement: "left") diff --git a/changelogs/unreleased/dm-copy-diff-file-title-as-gfm.yml b/changelogs/unreleased/dm-copy-diff-file-title-as-gfm.yml new file mode 100644 index 00000000000..506883bc17d --- /dev/null +++ b/changelogs/unreleased/dm-copy-diff-file-title-as-gfm.yml @@ -0,0 +1,4 @@ +--- +title: After copying a diff file or blob path, pasting it into a comment field will format it as Markdown. +merge_request: 9876 +author: From 923a2adc8dd2698513ccdaf9306198b96431b40b Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Thu, 6 Apr 2017 21:38:44 +0000 Subject: [PATCH 072/113] Update issue board cards design --- .../boards/components/issue_card_inner.js | 67 +++++++++++++------ app/assets/stylesheets/pages/boards.scss | 43 +++++++----- .../update-issue-board-cards-design.yml | 4 ++ spec/features/boards/add_issues_modal_spec.rb | 18 ++--- 4 files changed, 87 insertions(+), 45 deletions(-) create mode 100644 changelogs/unreleased/update-issue-board-cards-design.yml diff --git a/app/assets/javascripts/boards/components/issue_card_inner.js b/app/assets/javascripts/boards/components/issue_card_inner.js index a4629b092bf..e48d3344a2b 100644 --- a/app/assets/javascripts/boards/components/issue_card_inner.js +++ b/app/assets/javascripts/boards/components/issue_card_inner.js @@ -20,6 +20,7 @@ import eventHub from '../eventhub'; list: { type: Object, required: false, + default: () => ({}), }, rootPath: { type: String, @@ -31,6 +32,26 @@ import eventHub from '../eventhub'; default: false, }, }, + computed: { + cardUrl() { + return `${this.issueLinkBase}/${this.issue.id}`; + }, + assigneeUrl() { + return `${this.rootPath}${this.issue.assignee.username}`; + }, + assigneeUrlTitle() { + return `Assigned to ${this.issue.assignee.name}`; + }, + avatarUrlTitle() { + return `Avatar for ${this.issue.assignee.name}`; + }, + issueId() { + return `#${this.issue.id}`; + }, + showLabelFooter() { + return this.issue.labels.find(l => this.showLabel(l)) !== undefined; + }, + }, methods: { showLabel(label) { if (!this.list) return true; @@ -67,35 +88,41 @@ import eventHub from '../eventhub'; }, template: `
-

- - - {{ issue.title }} - -

-