From 7a1c5ba7471b233c994f5b5b313085d0d1292b5d Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Fri, 28 Apr 2017 08:56:04 +1100 Subject: [PATCH 001/196] Add index on ci_runners.contacted_at --- .../add_index_on_ci_runners_contacted_at.yml | 4 ++++ ...40_add_index_on_ci_runners_contacted_at.rb | 19 +++++++++++++++++++ db/schema.rb | 3 ++- 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/add_index_on_ci_runners_contacted_at.yml create mode 100644 db/migrate/20170426181740_add_index_on_ci_runners_contacted_at.rb diff --git a/changelogs/unreleased/add_index_on_ci_runners_contacted_at.yml b/changelogs/unreleased/add_index_on_ci_runners_contacted_at.yml new file mode 100644 index 00000000000..10c3206c2ff --- /dev/null +++ b/changelogs/unreleased/add_index_on_ci_runners_contacted_at.yml @@ -0,0 +1,4 @@ +--- +title: Add index on ci_runners.contacted_at +merge_request: 10876 +author: blackst0ne diff --git a/db/migrate/20170426181740_add_index_on_ci_runners_contacted_at.rb b/db/migrate/20170426181740_add_index_on_ci_runners_contacted_at.rb new file mode 100644 index 00000000000..879825a1934 --- /dev/null +++ b/db/migrate/20170426181740_add_index_on_ci_runners_contacted_at.rb @@ -0,0 +1,19 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddIndexOnCiRunnersContactedAt < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # Set this constant to true if this migration requires downtime. + DOWNTIME = false + + disable_ddl_transaction! + + def up + add_concurrent_index :ci_runners, :contacted_at + end + + def down + remove_concurrent_index :ci_runners, :contacted_at if index_exists?(:ci_runners, :contacted_at) + end +end diff --git a/db/schema.rb b/db/schema.rb index 49d7c996661..a615a078e49 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: 20170426175636) do +ActiveRecord::Schema.define(version: 20170425101740) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -296,6 +296,7 @@ ActiveRecord::Schema.define(version: 20170426175636) do t.boolean "locked", default: false, null: false end + add_index "ci_runners", ["contacted_at"], name: "index_ci_runners_on_contacted_at", using: :btree add_index "ci_runners", ["is_shared"], name: "index_ci_runners_on_is_shared", using: :btree add_index "ci_runners", ["locked"], name: "index_ci_runners_on_locked", using: :btree add_index "ci_runners", ["token"], name: "index_ci_runners_on_token", using: :btree From df948f8ac21568eac0cef059c2e96d009d702cc2 Mon Sep 17 00:00:00 2001 From: haseeb Date: Sun, 13 Aug 2017 12:58:19 +0530 Subject: [PATCH 002/196] fix Merge request reference in merge commit is not global --- app/models/merge_request.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index f90194041b1..de0d541f1c7 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -682,9 +682,9 @@ class MergeRequest < ActiveRecord::Base if !include_description && closes_issues_references.present? message << "Closes #{closes_issues_references.to_sentence}" end - + message << "#{description}" if include_description && description.present? - message << "See merge request #{to_reference}" + message << "See merge request #{to_reference(full: true)}" message.join("\n\n") end From f2251d1978a7fc8bad7ebb3766ed97d05e5f49e9 Mon Sep 17 00:00:00 2001 From: haseeb Date: Sun, 13 Aug 2017 18:09:30 +0530 Subject: [PATCH 003/196] fixes failing tests for full reference change --- .../merge_requests/merge_commit_message_toggle_spec.rb | 4 ++-- spec/models/merge_request_spec.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/features/merge_requests/merge_commit_message_toggle_spec.rb b/spec/features/merge_requests/merge_commit_message_toggle_spec.rb index 429bc277d73..08a3bb84aac 100644 --- a/spec/features/merge_requests/merge_commit_message_toggle_spec.rb +++ b/spec/features/merge_requests/merge_commit_message_toggle_spec.rb @@ -19,7 +19,7 @@ feature 'Clicking toggle commit message link', js: true do "Merge branch 'feature' into 'master'", merge_request.title, "Closes #{issue_1.to_reference} and #{issue_2.to_reference}", - "See merge request #{merge_request.to_reference}" + "See merge request #{merge_request.to_reference(full: true)}" ].join("\n\n") end let(:message_with_description) do @@ -27,7 +27,7 @@ feature 'Clicking toggle commit message link', js: true do "Merge branch 'feature' into 'master'", merge_request.title, merge_request.description, - "See merge request #{merge_request.to_reference}" + "See merge request #{merge_request.to_reference(full: true)}" ].join("\n\n") end diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 026bdbd26d1..e2b0d9ab005 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -604,7 +604,7 @@ describe MergeRequest do request = build_stubbed(:merge_request) expect(request.merge_commit_message) - .to match("See merge request #{request.to_reference}") + .to match("See merge request #{request.to_reference(full: true)}") end it 'excludes multiple linebreak runs when description is blank' do From 725a4fef5aeea02bea3f943133d075177424117d Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Wed, 9 Aug 2017 09:24:48 -0400 Subject: [PATCH 004/196] Add thenable ajax calls. --- app/assets/javascripts/api.js | 6 ++---- .../javascripts/repo/components/repo_commit_section.vue | 5 +++-- app/assets/javascripts/repo/services/repo_service.js | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js index 56f91e95bb9..28119362455 100644 --- a/app/assets/javascripts/api.js +++ b/app/assets/javascripts/api.js @@ -99,15 +99,13 @@ const Api = { commitMultiple(id, data, callback) { const url = Api.buildUrl(Api.commitPath) .replace(':id', id); - return $.ajax({ + return this.wrapAjaxCall({ url, type: 'POST', contentType: 'application/json; charset=utf-8', data: JSON.stringify(data), dataType: 'json', - }) - .done(commitData => callback(commitData)) - .fail(message => callback(message.responseJSON)); + }); }, // Return text for a specific license diff --git a/app/assets/javascripts/repo/components/repo_commit_section.vue b/app/assets/javascripts/repo/components/repo_commit_section.vue index 5ec4a9b6593..d06cdf2cbc2 100644 --- a/app/assets/javascripts/repo/components/repo_commit_section.vue +++ b/app/assets/javascripts/repo/components/repo_commit_section.vue @@ -42,10 +42,11 @@ export default { actions, }; Store.submitCommitsLoading = true; - Service.commitFiles(payload, this.resetCommitState); + Service.commitFiles(payload) + .then(this.resetCommitState); }, - resetCommitState() { + resetCommitState(data) { this.submitCommitsLoading = false; this.changedFiles = []; this.commitMessage = ''; diff --git a/app/assets/javascripts/repo/services/repo_service.js b/app/assets/javascripts/repo/services/repo_service.js index 3cf204e6ec8..310c03fc019 100644 --- a/app/assets/javascripts/repo/services/repo_service.js +++ b/app/assets/javascripts/repo/services/repo_service.js @@ -65,14 +65,14 @@ const RepoService = { return urlArray.join('/'); }, - commitFiles(payload, cb) { - Api.commitMultiple(Store.projectId, payload, (data) => { + commitFiles(payload) { + return Api.commitMultiple(Store.projectId, payload) + .then((data) => { if (data.short_id && data.stats) { Flash(`Your changes have been committed. Commit ${data.short_id} with ${data.stats.additions} additions, ${data.stats.deletions} deletions.`, 'notice'); } else { Flash(data.message); } - cb(); }); }, }; From cdd741ee22b3d02ea75fa4021497f80867c09f39 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Thu, 17 Aug 2017 13:05:09 -0500 Subject: [PATCH 005/196] fix eslint violations in repo editor files --- app/assets/javascripts/api.js | 3 ++- .../repo/components/repo_commit_section.vue | 5 +++-- .../javascripts/repo/services/repo_service.js | 14 +++++++------- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js index 28119362455..4319bfcc57f 100644 --- a/app/assets/javascripts/api.js +++ b/app/assets/javascripts/api.js @@ -96,7 +96,8 @@ const Api = { .done(projects => callback(projects)); }, - commitMultiple(id, data, callback) { + commitMultiple(id, data) { + // see https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions const url = Api.buildUrl(Api.commitPath) .replace(':id', id); return this.wrapAjaxCall({ diff --git a/app/assets/javascripts/repo/components/repo_commit_section.vue b/app/assets/javascripts/repo/components/repo_commit_section.vue index d06cdf2cbc2..1282828b504 100644 --- a/app/assets/javascripts/repo/components/repo_commit_section.vue +++ b/app/assets/javascripts/repo/components/repo_commit_section.vue @@ -43,10 +43,11 @@ export default { }; Store.submitCommitsLoading = true; Service.commitFiles(payload) - .then(this.resetCommitState); + .then(this.resetCommitState) + .catch(() => Flash('An error occured while committing your changes')); }, - resetCommitState(data) { + resetCommitState() { this.submitCommitsLoading = false; this.changedFiles = []; this.commitMessage = ''; diff --git a/app/assets/javascripts/repo/services/repo_service.js b/app/assets/javascripts/repo/services/repo_service.js index 310c03fc019..a8a4b419ae8 100644 --- a/app/assets/javascripts/repo/services/repo_service.js +++ b/app/assets/javascripts/repo/services/repo_service.js @@ -67,13 +67,13 @@ const RepoService = { commitFiles(payload) { return Api.commitMultiple(Store.projectId, payload) - .then((data) => { - if (data.short_id && data.stats) { - Flash(`Your changes have been committed. Commit ${data.short_id} with ${data.stats.additions} additions, ${data.stats.deletions} deletions.`, 'notice'); - } else { - Flash(data.message); - } - }); + .then((data) => { + if (data.short_id && data.stats) { + Flash(`Your changes have been committed. Commit ${data.short_id} with ${data.stats.additions} additions, ${data.stats.deletions} deletions.`, 'notice'); + } else { + Flash(data.message); + } + }); }, }; From 597f9c12bbd9954f5a8b2580cfa34a3afcd31d86 Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Fri, 18 Aug 2017 16:42:52 +1100 Subject: [PATCH 006/196] Use full path of project's avatar in webhooks --- app/models/project.rb | 2 +- .../use_full_path_in_project_avatar_url_webhook.yml | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/use_full_path_in_project_avatar_url_webhook.yml diff --git a/app/models/project.rb b/app/models/project.rb index be248bc99e1..e0085302867 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1009,7 +1009,7 @@ class Project < ActiveRecord::Base name: name, description: description, web_url: web_url, - avatar_url: avatar_url, + avatar_url: avatar_url(only_path: false), git_ssh_url: ssh_url_to_repo, git_http_url: http_url_to_repo, namespace: namespace.name, diff --git a/changelogs/unreleased/use_full_path_in_project_avatar_url_webhook.yml b/changelogs/unreleased/use_full_path_in_project_avatar_url_webhook.yml new file mode 100644 index 00000000000..0c3acce1455 --- /dev/null +++ b/changelogs/unreleased/use_full_path_in_project_avatar_url_webhook.yml @@ -0,0 +1,5 @@ +--- +title: Use full path of project's avatar in webhooks +merge_request: 13649 +author: Vitaliy @blackst0ne Klachkov +type: changed From d515ec4df908fc65496904f4705ae903db54b6a8 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 18 Aug 2017 09:54:53 +0100 Subject: [PATCH 007/196] Fixes the breadcrumb container when in issue boards Closes #36561 --- app/views/layouts/nav/_breadcrumbs.html.haml | 3 ++- app/views/projects/boards/_show.html.haml | 1 + changelogs/unreleased/issue-boards-breadcrumbs-container.yml | 5 +++++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/issue-boards-breadcrumbs-container.yml diff --git a/app/views/layouts/nav/_breadcrumbs.html.haml b/app/views/layouts/nav/_breadcrumbs.html.haml index 4db84771f4e..653452871a0 100644 --- a/app/views/layouts/nav/_breadcrumbs.html.haml +++ b/app/views/layouts/nav/_breadcrumbs.html.haml @@ -1,8 +1,9 @@ - breadcrumb_link = breadcrumb_title_link +- container = @no_breadcrumb_container ? 'container-fluid' : container_class - hide_top_links = @hide_top_links || false %nav.breadcrumbs{ role: "navigation" } - .breadcrumbs-container{ class: [container_class, @content_class] } + .breadcrumbs-container{ class: [container, @content_class] } - if defined?(@new_sidebar) = button_tag class: 'toggle-mobile-nav', type: 'button' do %span.sr-only Open sidebar diff --git a/app/views/projects/boards/_show.html.haml b/app/views/projects/boards/_show.html.haml index 2076e46fde8..5354ec8522e 100644 --- a/app/views/projects/boards/_show.html.haml +++ b/app/views/projects/boards/_show.html.haml @@ -1,3 +1,4 @@ +- @no_breadcrumb_container = true - @no_container = true - @content_class = "issue-boards-content" - page_title "Boards" diff --git a/changelogs/unreleased/issue-boards-breadcrumbs-container.yml b/changelogs/unreleased/issue-boards-breadcrumbs-container.yml new file mode 100644 index 00000000000..5e042de7000 --- /dev/null +++ b/changelogs/unreleased/issue-boards-breadcrumbs-container.yml @@ -0,0 +1,5 @@ +--- +title: Fix breadcrumbs container in issue boards +merge_request: +author: +type: fixed From 43dea824c1a0d0306714d691bb88ce3490adcae6 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Fri, 18 Aug 2017 16:44:28 -0300 Subject: [PATCH 008/196] use inline links instead of referenced --- doc/development/doc_styleguide.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/doc/development/doc_styleguide.md b/doc/development/doc_styleguide.md index 90d1d9657b9..798f40eef3d 100644 --- a/doc/development/doc_styleguide.md +++ b/doc/development/doc_styleguide.md @@ -113,13 +113,12 @@ merge request. ## Links -- If a link makes the paragraph to span across multiple lines, do not use - the regular Markdown approach: `[Text](https://example.com)`. Instead use - `[Text][identifier]` and at the very bottom of the document add: - `[identifier]: https://example.com`. This is another way to create Markdown - links which keeps the document clear and concise. Bonus points if you also - add an alternative text: `[identifier]: https://example.com "Alternative text"` - that appears when hovering your mouse on a link +- Use the regular inline link markdown markup `[Text](https://example.com)`. + It's easier to read, review, and maintain. +- If there's a link that repeats several times through the same document, + you can use `[Text][identifier]` and at the bottom of the section or the + document add: `[identifier]: https://example.com`, in which case, we do + encourage you to also add an alternative text: `[identifier]: https://example.com "Alternative text"` that appears when hovering your mouse on a link. ### Linking to inline docs From ffca8c1c3794d1e51ffee1c52c55c57c1e53c621 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Fri, 18 Aug 2017 16:44:51 -0300 Subject: [PATCH 009/196] Indexes GFM markdown guide --- doc/user/index.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/user/index.md b/doc/user/index.md index d664fd62754..0892db14900 100644 --- a/doc/user/index.md +++ b/doc/user/index.md @@ -119,6 +119,13 @@ When performing inline reviews to implementations to your codebase through merge requests you can gather feedback through [resolvable discussions](discussions/index.md#resolvable-discussions). +### GitLab Flavored Markdown (GFM) + +Read through the [GFM documentation](markdown.md) to learn how to apply +the best of GitLab Flavored Markdown in your discussions, comments, +issues and merge requests descriptions, and everywhere else GMF is +supported. + ## Todos Never forget to reply to your collaborators. [GitLab Todos](../workflow/todos.md) From d9c6bb0d34b96ffb78b9e65b5b2110b752cf5a55 Mon Sep 17 00:00:00 2001 From: Bryce Johnson Date: Fri, 18 Aug 2017 17:09:13 -0400 Subject: [PATCH 010/196] Move ConvDev index to Overview from Monitoring. --- app/views/admin/dashboard/_head.html.haml | 4 ++++ app/views/admin/monitoring/_head.html.haml | 4 ---- app/views/layouts/nav/_new_admin_sidebar.html.haml | 8 ++++---- ...34413-move-convdev-index-location-to-after-cohorts.yml | 4 ++++ 4 files changed, 12 insertions(+), 8 deletions(-) create mode 100644 changelogs/unreleased/34413-move-convdev-index-location-to-after-cohorts.yml diff --git a/app/views/admin/dashboard/_head.html.haml b/app/views/admin/dashboard/_head.html.haml index dff549f502c..c2151710884 100644 --- a/app/views/admin/dashboard/_head.html.haml +++ b/app/views/admin/dashboard/_head.html.haml @@ -31,3 +31,7 @@ = link_to admin_cohorts_path, title: 'Cohorts' do %span Cohorts + = nav_link(controller: :conversational_development_index) do + = link_to admin_conversational_development_index_path, title: 'ConvDev Index' do + %span + ConvDev Index diff --git a/app/views/admin/monitoring/_head.html.haml b/app/views/admin/monitoring/_head.html.haml index 901e30275fd..b3530915068 100644 --- a/app/views/admin/monitoring/_head.html.haml +++ b/app/views/admin/monitoring/_head.html.haml @@ -3,10 +3,6 @@ = render 'shared/nav_scroll' .nav-links.sub-nav.scrolling-tabs %ul{ class: (container_class) } - = nav_link(controller: :conversational_development_index) do - = link_to admin_conversational_development_index_path, title: 'ConvDev Index' do - %span - ConvDev Index = nav_link(controller: :system_info) do = link_to admin_system_info_path, title: 'System Info' do %span diff --git a/app/views/layouts/nav/_new_admin_sidebar.html.haml b/app/views/layouts/nav/_new_admin_sidebar.html.haml index 3cbcd841aff..424d084f0fe 100644 --- a/app/views/layouts/nav/_new_admin_sidebar.html.haml +++ b/app/views/layouts/nav/_new_admin_sidebar.html.haml @@ -42,6 +42,10 @@ = link_to admin_cohorts_path, title: 'Cohorts' do %span Cohorts + = nav_link(controller: :conversational_development_index) do + = link_to admin_conversational_development_index_path, title: 'ConvDev Index' do + %span + ConvDev Index = nav_link(controller: %w(conversational_development_index system_info background_jobs logs health_check requests_profiles)) do = link_to admin_conversational_development_index_path, title: 'Monitoring' do @@ -51,10 +55,6 @@ Monitoring %ul.sidebar-sub-level-items - = nav_link(controller: :conversational_development_index) do - = link_to admin_conversational_development_index_path, title: 'ConvDev Index' do - %span - ConvDev Index = nav_link(controller: :system_info) do = link_to admin_system_info_path, title: 'System Info' do %span diff --git a/changelogs/unreleased/34413-move-convdev-index-location-to-after-cohorts.yml b/changelogs/unreleased/34413-move-convdev-index-location-to-after-cohorts.yml new file mode 100644 index 00000000000..d33b55ef681 --- /dev/null +++ b/changelogs/unreleased/34413-move-convdev-index-location-to-after-cohorts.yml @@ -0,0 +1,4 @@ +--- +title: Move ConvDev Index location to after Cohorts. +merge_request: !13398 +author: From c5b3632f904744dd23d8079caaf44fa3b24e7e1b Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Fri, 18 Aug 2017 16:53:00 -0500 Subject: [PATCH 011/196] fix failing specs in repo_commit_section_spec.js --- spec/javascripts/repo/components/repo_commit_section_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/javascripts/repo/components/repo_commit_section_spec.js b/spec/javascripts/repo/components/repo_commit_section_spec.js index 249a2f36fcd..6f6faf5422b 100644 --- a/spec/javascripts/repo/components/repo_commit_section_spec.js +++ b/spec/javascripts/repo/components/repo_commit_section_spec.js @@ -111,7 +111,7 @@ describe('RepoCommitSection', () => { expect(submitCommit.disabled).toBeFalsy(); spyOn(vm, 'makeCommit').and.callThrough(); - spyOn(Api, 'commitMultiple'); + spyOn(Api, 'commitMultiple').and.callFake(() => Promise.resolve()); submitCommit.click(); From 05147e209e8eef7aa817d992c87956220ae14943 Mon Sep 17 00:00:00 2001 From: Hiroyuki Sato Date: Sat, 19 Aug 2017 23:12:05 +0900 Subject: [PATCH 012/196] Add filtered search to group merge requests dashboard --- app/assets/javascripts/dispatcher.js | 4 ++-- app/views/groups/merge_requests.html.haml | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index 2bba7f55de1..b71c449090e 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -184,13 +184,13 @@ import initChangesDropdown from './init_changes_dropdown'; break; case 'dashboard:issues': case 'dashboard:merge_requests': - case 'groups:merge_requests': new ProjectSelect(); initLegacyFilters(); break; case 'groups:issues': + case 'groups:merge_requests': if (filteredSearchEnabled) { - const filteredSearchManager = new gl.FilteredSearchManager('issues'); + const filteredSearchManager = new gl.FilteredSearchManager(page === 'groups:issues' ? 'issues' : 'merge_requests'); filteredSearchManager.setup(); } new ProjectSelect(); diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml index 997c82c77d9..ad5ab4b5d87 100644 --- a/app/views/groups/merge_requests.html.haml +++ b/app/views/groups/merge_requests.html.haml @@ -1,5 +1,9 @@ - page_title "Merge Requests" +- content_for :page_specific_javascripts do + = webpack_bundle_tag 'common_vue' + = webpack_bundle_tag 'filtered_search' + - if show_new_nav? && current_user - content_for :breadcrumbs_extra do = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request" @@ -13,7 +17,7 @@ .nav-controls{ class: ("visible-xs" if show_new_nav?) } = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request" - = render 'shared/issuable/filter', type: :merge_requests + = render 'shared/issuable/search_bar', type: :merge_requests .row-content-block.second-block Only merge requests from From 2ec7cfc91d81c843e82060c7c17da81aac68cb48 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sun, 20 Aug 2017 04:35:06 -0700 Subject: [PATCH 013/196] Add spec for deleting protected tags --- .../projects/protected_tags_controller_spec.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/spec/controllers/projects/protected_tags_controller_spec.rb b/spec/controllers/projects/protected_tags_controller_spec.rb index 64658988b3f..b6de90039f3 100644 --- a/spec/controllers/projects/protected_tags_controller_spec.rb +++ b/spec/controllers/projects/protected_tags_controller_spec.rb @@ -8,4 +8,21 @@ describe Projects::ProtectedTagsController do get(:index, namespace_id: project.namespace.to_param, project_id: project) end end + + describe "DELETE #destroy" do + let(:project) { create(:project, :repository) } + let(:protected_tag) { create(:protected_tag, :developers_can_create, project: project) } + let(:user) { create(:user) } + + before do + project.add_master(user) + sign_in(user) + end + + it "deletes the protected tag" do + delete(:destroy, namespace_id: project.namespace.to_param, project_id: project, id: protected_tag.id) + + expect { ProtectedTag.find(protected_tag.id) }.to raise_error(ActiveRecord::RecordNotFound) + end + end end From 1a3835796f74652f4adc9448b06a2623d4c81d59 Mon Sep 17 00:00:00 2001 From: Alexandros Keramidas Date: Mon, 21 Aug 2017 08:00:32 +0000 Subject: [PATCH 014/196] Point to /developers on docs/administration/authentiq.md --- doc/administration/auth/authentiq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/administration/auth/authentiq.md b/doc/administration/auth/authentiq.md index 1528f1d2b17..252ff1f4b15 100644 --- a/doc/administration/auth/authentiq.md +++ b/doc/administration/auth/authentiq.md @@ -4,7 +4,7 @@ To enable the Authentiq OmniAuth provider for passwordless authentication you mu Authentiq will generate a Client ID and the accompanying Client Secret for you to use. -1. Get your Client credentials (Client ID and Client Secret) at [Authentiq](https://www.authentiq.com/register). +1. Get your Client credentials (Client ID and Client Secret) at [Authentiq](https://www.authentiq.com/developers). 2. On your GitLab server, open the configuration file: From 0f01ce365731542570c9135d7cbf6390ffa42ced Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Mon, 21 Aug 2017 13:05:01 +0200 Subject: [PATCH 015/196] Extend pipelines queue mixin and add a default queue --- app/workers/concerns/pipeline_queue.rb | 12 +++++++++++- app/workers/pipeline_update_worker.rb | 2 ++ spec/workers/concerns/pipeline_queue_spec.rb | 14 ++++++++++++-- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/app/workers/concerns/pipeline_queue.rb b/app/workers/concerns/pipeline_queue.rb index ca3860e1d38..ed882e3ecef 100644 --- a/app/workers/concerns/pipeline_queue.rb +++ b/app/workers/concerns/pipeline_queue.rb @@ -1,8 +1,18 @@ +## # Concern for setting Sidekiq settings for the various CI pipeline workers. +# module PipelineQueue extend ActiveSupport::Concern included do - sidekiq_options queue: :pipeline + sidekiq_options queue: 'pipelines-default' + end + + class_methods do + def enqueue_in(queue:, group:) + raise ArgumentError if queue.empty? || group.empty? + + sidekiq_options queue: "pipelines-#{queue}-#{group}" + end end end diff --git a/app/workers/pipeline_update_worker.rb b/app/workers/pipeline_update_worker.rb index 96c4152c674..086d00b7ec8 100644 --- a/app/workers/pipeline_update_worker.rb +++ b/app/workers/pipeline_update_worker.rb @@ -2,6 +2,8 @@ class PipelineUpdateWorker include Sidekiq::Worker include PipelineQueue + enqueue_in queue: :pipeline, group: :processing + def perform(pipeline_id) Ci::Pipeline.find_by(id: pipeline_id) .try(:update_status) diff --git a/spec/workers/concerns/pipeline_queue_spec.rb b/spec/workers/concerns/pipeline_queue_spec.rb index 40794d0e42a..3049f2b2ab4 100644 --- a/spec/workers/concerns/pipeline_queue_spec.rb +++ b/spec/workers/concerns/pipeline_queue_spec.rb @@ -8,7 +8,17 @@ describe PipelineQueue do end end - it 'sets the queue name of a worker' do - expect(worker.sidekiq_options['queue'].to_s).to eq('pipeline') + it 'sets a default pipelines queue automatically' do + expect(worker.sidekiq_options['queue']) + .to eq 'pipelines-default' + end + + describe '.enqueue_in' do + it 'sets a custom sidekiq queue with prefix, name and group' do + worker.enqueue_in(queue: :build, group: :processing) + + expect(worker.sidekiq_options['queue']) + .to eq 'pipelines-build-processing' + end end end From ce274fd61bbe11c7a1353bff2176273e9b30e197 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Mon, 21 Aug 2017 13:32:00 +0200 Subject: [PATCH 016/196] Make it possible to check if worker uses a known queue --- config/sidekiq_queues.yml | 1 + .../shared_examples/sidekiq_worker_shared_examples.rb | 10 ++++++++++ spec/workers/pipeline_update_worker_spec.rb | 2 ++ 3 files changed, 13 insertions(+) create mode 100644 spec/support/shared_examples/sidekiq_worker_shared_examples.rb diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml index 83abc83c9f0..7816c0fa92e 100644 --- a/config/sidekiq_queues.yml +++ b/config/sidekiq_queues.yml @@ -27,6 +27,7 @@ - [new_merge_request, 2] - [build, 2] - [pipeline, 2] + - [pipelines-pipeline-processing, 2] - [gitlab_shell, 2] - [email_receiver, 2] - [emails_on_push, 2] diff --git a/spec/support/shared_examples/sidekiq_worker_shared_examples.rb b/spec/support/shared_examples/sidekiq_worker_shared_examples.rb new file mode 100644 index 00000000000..712cad2a0d9 --- /dev/null +++ b/spec/support/shared_examples/sidekiq_worker_shared_examples.rb @@ -0,0 +1,10 @@ +shared_examples 'sidekiq worker' do + let(:queues) do + YAML.load_file(Rails.root.join('config', 'sidekiq_queues.yml')) + .fetch(:queues, []).map(&:first) + end + + it 'is going to be processed inside a known sidekiq queue' do + expect(described_class.sidekiq_options['queue']).to be_in queues + end +end diff --git a/spec/workers/pipeline_update_worker_spec.rb b/spec/workers/pipeline_update_worker_spec.rb index 0b456cfd0da..60e7e23f0b4 100644 --- a/spec/workers/pipeline_update_worker_spec.rb +++ b/spec/workers/pipeline_update_worker_spec.rb @@ -1,6 +1,8 @@ require 'spec_helper' describe PipelineUpdateWorker do + it_behaves_like 'sidekiq worker' + describe '#perform' do context 'when pipeline exists' do let(:pipeline) { create(:ci_pipeline) } From 48776f2786d22cecab97417141d43060c6cdee26 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Mon, 21 Aug 2017 13:49:57 +0200 Subject: [PATCH 017/196] Simplify pipeline sidekiq queues naming scheme --- app/workers/concerns/pipeline_queue.rb | 8 ++++---- app/workers/pipeline_update_worker.rb | 2 +- config/sidekiq_queues.yml | 2 +- spec/workers/concerns/pipeline_queue_spec.rb | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/workers/concerns/pipeline_queue.rb b/app/workers/concerns/pipeline_queue.rb index ed882e3ecef..ddf45b91345 100644 --- a/app/workers/concerns/pipeline_queue.rb +++ b/app/workers/concerns/pipeline_queue.rb @@ -5,14 +5,14 @@ module PipelineQueue extend ActiveSupport::Concern included do - sidekiq_options queue: 'pipelines-default' + sidekiq_options queue: 'pipeline_default' end class_methods do - def enqueue_in(queue:, group:) - raise ArgumentError if queue.empty? || group.empty? + def enqueue_in(group:) + raise ArgumentError, 'Unspecified queue group!' if group.empty? - sidekiq_options queue: "pipelines-#{queue}-#{group}" + sidekiq_options queue: "pipeline_#{group}" end end end diff --git a/app/workers/pipeline_update_worker.rb b/app/workers/pipeline_update_worker.rb index 086d00b7ec8..5fa399dff4c 100644 --- a/app/workers/pipeline_update_worker.rb +++ b/app/workers/pipeline_update_worker.rb @@ -2,7 +2,7 @@ class PipelineUpdateWorker include Sidekiq::Worker include PipelineQueue - enqueue_in queue: :pipeline, group: :processing + enqueue_in group: :processing def perform(pipeline_id) Ci::Pipeline.find_by(id: pipeline_id) diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml index 7816c0fa92e..8e13ed95f19 100644 --- a/config/sidekiq_queues.yml +++ b/config/sidekiq_queues.yml @@ -27,7 +27,7 @@ - [new_merge_request, 2] - [build, 2] - [pipeline, 2] - - [pipelines-pipeline-processing, 2] + - [pipeline_processing, 2] - [gitlab_shell, 2] - [email_receiver, 2] - [emails_on_push, 2] diff --git a/spec/workers/concerns/pipeline_queue_spec.rb b/spec/workers/concerns/pipeline_queue_spec.rb index 3049f2b2ab4..eac5a770e5f 100644 --- a/spec/workers/concerns/pipeline_queue_spec.rb +++ b/spec/workers/concerns/pipeline_queue_spec.rb @@ -10,15 +10,15 @@ describe PipelineQueue do it 'sets a default pipelines queue automatically' do expect(worker.sidekiq_options['queue']) - .to eq 'pipelines-default' + .to eq 'pipeline_default' end describe '.enqueue_in' do - it 'sets a custom sidekiq queue with prefix, name and group' do - worker.enqueue_in(queue: :build, group: :processing) + it 'sets a custom sidekiq queue with prefix and group' do + worker.enqueue_in(group: :processing) expect(worker.sidekiq_options['queue']) - .to eq 'pipelines-build-processing' + .to eq 'pipeline_processing' end end end From 8417507201809daf0554c13ffb695b8142274f4f Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Mon, 21 Aug 2017 14:02:20 +0200 Subject: [PATCH 018/196] Assign all pipeline workers to specific queues --- app/workers/expire_pipeline_cache_worker.rb | 2 ++ app/workers/pipeline_hooks_worker.rb | 2 ++ app/workers/pipeline_metrics_worker.rb | 2 ++ app/workers/pipeline_notification_worker.rb | 2 ++ app/workers/pipeline_process_worker.rb | 2 ++ app/workers/pipeline_success_worker.rb | 2 ++ config/sidekiq_queues.yml | 3 +++ spec/workers/expire_pipeline_cache_worker_spec.rb | 2 ++ spec/workers/pipeline_hooks_worker_spec.rb | 2 ++ spec/workers/pipeline_metrics_worker_spec.rb | 2 ++ spec/workers/pipeline_notification_worker_spec.rb | 2 ++ spec/workers/pipeline_process_worker_spec.rb | 2 ++ spec/workers/pipeline_success_worker_spec.rb | 2 ++ 13 files changed, 27 insertions(+) diff --git a/app/workers/expire_pipeline_cache_worker.rb b/app/workers/expire_pipeline_cache_worker.rb index 7c02d6cf892..1a0e7f92875 100644 --- a/app/workers/expire_pipeline_cache_worker.rb +++ b/app/workers/expire_pipeline_cache_worker.rb @@ -2,6 +2,8 @@ class ExpirePipelineCacheWorker include Sidekiq::Worker include PipelineQueue + enqueue_in group: :cache + def perform(pipeline_id) pipeline = Ci::Pipeline.find_by(id: pipeline_id) return unless pipeline diff --git a/app/workers/pipeline_hooks_worker.rb b/app/workers/pipeline_hooks_worker.rb index 7e36eacebf8..30a75ec8435 100644 --- a/app/workers/pipeline_hooks_worker.rb +++ b/app/workers/pipeline_hooks_worker.rb @@ -2,6 +2,8 @@ class PipelineHooksWorker include Sidekiq::Worker include PipelineQueue + enqueue_in group: :hooks + def perform(pipeline_id) Ci::Pipeline.find_by(id: pipeline_id) .try(:execute_hooks) diff --git a/app/workers/pipeline_metrics_worker.rb b/app/workers/pipeline_metrics_worker.rb index 070943f1ecc..3795105ef28 100644 --- a/app/workers/pipeline_metrics_worker.rb +++ b/app/workers/pipeline_metrics_worker.rb @@ -2,6 +2,8 @@ class PipelineMetricsWorker include Sidekiq::Worker include PipelineQueue + enqueue_in group: :metrics + def perform(pipeline_id) Ci::Pipeline.find_by(id: pipeline_id).try do |pipeline| update_metrics_for_active_pipeline(pipeline) if pipeline.active? diff --git a/app/workers/pipeline_notification_worker.rb b/app/workers/pipeline_notification_worker.rb index cdb860b6675..77ff3913ad7 100644 --- a/app/workers/pipeline_notification_worker.rb +++ b/app/workers/pipeline_notification_worker.rb @@ -2,6 +2,8 @@ class PipelineNotificationWorker include Sidekiq::Worker include PipelineQueue + enqueue_in group: :hooks + def perform(pipeline_id, recipients = nil) pipeline = Ci::Pipeline.find_by(id: pipeline_id) diff --git a/app/workers/pipeline_process_worker.rb b/app/workers/pipeline_process_worker.rb index 357e4a9a1c3..8c067d05081 100644 --- a/app/workers/pipeline_process_worker.rb +++ b/app/workers/pipeline_process_worker.rb @@ -2,6 +2,8 @@ class PipelineProcessWorker include Sidekiq::Worker include PipelineQueue + enqueue_in group: :processing + def perform(pipeline_id) Ci::Pipeline.find_by(id: pipeline_id) .try(:process!) diff --git a/app/workers/pipeline_success_worker.rb b/app/workers/pipeline_success_worker.rb index cc0eb708cf9..cb8bb2ffe75 100644 --- a/app/workers/pipeline_success_worker.rb +++ b/app/workers/pipeline_success_worker.rb @@ -2,6 +2,8 @@ class PipelineSuccessWorker include Sidekiq::Worker include PipelineQueue + enqueue_in group: :processing + def perform(pipeline_id) Ci::Pipeline.find_by(id: pipeline_id).try do |pipeline| MergeRequests::MergeWhenPipelineSucceedsService diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml index 8e13ed95f19..28cfb9419de 100644 --- a/config/sidekiq_queues.yml +++ b/config/sidekiq_queues.yml @@ -28,6 +28,9 @@ - [build, 2] - [pipeline, 2] - [pipeline_processing, 2] + - [pipeline_cache, 2] + - [pipeline_metrics, 2] + - [pipeline_hooks, 2] - [gitlab_shell, 2] - [email_receiver, 2] - [emails_on_push, 2] diff --git a/spec/workers/expire_pipeline_cache_worker_spec.rb b/spec/workers/expire_pipeline_cache_worker_spec.rb index 54c9a69d329..85b24d5a8f0 100644 --- a/spec/workers/expire_pipeline_cache_worker_spec.rb +++ b/spec/workers/expire_pipeline_cache_worker_spec.rb @@ -43,4 +43,6 @@ describe ExpirePipelineCacheWorker do subject.perform(pipeline.id) end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/pipeline_hooks_worker_spec.rb b/spec/workers/pipeline_hooks_worker_spec.rb index 035e329839f..50b724d0111 100644 --- a/spec/workers/pipeline_hooks_worker_spec.rb +++ b/spec/workers/pipeline_hooks_worker_spec.rb @@ -20,4 +20,6 @@ describe PipelineHooksWorker do end end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/pipeline_metrics_worker_spec.rb b/spec/workers/pipeline_metrics_worker_spec.rb index ef71125c0b6..dac0b24d24a 100644 --- a/spec/workers/pipeline_metrics_worker_spec.rb +++ b/spec/workers/pipeline_metrics_worker_spec.rb @@ -47,4 +47,6 @@ describe PipelineMetricsWorker do end end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/pipeline_notification_worker_spec.rb b/spec/workers/pipeline_notification_worker_spec.rb index eb539ffd893..072866bf375 100644 --- a/spec/workers/pipeline_notification_worker_spec.rb +++ b/spec/workers/pipeline_notification_worker_spec.rb @@ -16,4 +16,6 @@ describe PipelineNotificationWorker, :mailer do subject.perform(Ci::Pipeline.maximum(:id).to_i.succ) end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/pipeline_process_worker_spec.rb b/spec/workers/pipeline_process_worker_spec.rb index 86e9d7f6684..81570c685ed 100644 --- a/spec/workers/pipeline_process_worker_spec.rb +++ b/spec/workers/pipeline_process_worker_spec.rb @@ -19,4 +19,6 @@ describe PipelineProcessWorker do end end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/pipeline_success_worker_spec.rb b/spec/workers/pipeline_success_worker_spec.rb index d1c84adda6f..83d006337bd 100644 --- a/spec/workers/pipeline_success_worker_spec.rb +++ b/spec/workers/pipeline_success_worker_spec.rb @@ -21,4 +21,6 @@ describe PipelineSuccessWorker do end end end + + it_behaves_like 'sidekiq worker' end From 4c93668202f8b3a02e3730e696e9ebcd6f08daca Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Mon, 21 Aug 2017 14:16:51 +0200 Subject: [PATCH 019/196] Remove sidekiq build queue and assign pipeline queue --- app/workers/build_coverage_worker.rb | 4 +++- app/workers/build_finished_worker.rb | 4 +++- app/workers/build_hooks_worker.rb | 4 +++- app/workers/build_success_worker.rb | 4 +++- app/workers/concerns/build_queue.rb | 8 -------- app/workers/expire_job_cache_worker.rb | 4 +++- spec/workers/build_coverage_worker_spec.rb | 2 ++ spec/workers/build_finished_worker_spec.rb | 2 ++ spec/workers/build_hooks_worker_spec.rb | 2 ++ spec/workers/build_success_worker_spec.rb | 2 ++ spec/workers/concerns/build_queue_spec.rb | 14 -------------- spec/workers/expire_job_cache_worker_spec.rb | 2 ++ 12 files changed, 25 insertions(+), 27 deletions(-) delete mode 100644 app/workers/concerns/build_queue.rb delete mode 100644 spec/workers/concerns/build_queue_spec.rb diff --git a/app/workers/build_coverage_worker.rb b/app/workers/build_coverage_worker.rb index f7ae996bb17..fd5ba11f73e 100644 --- a/app/workers/build_coverage_worker.rb +++ b/app/workers/build_coverage_worker.rb @@ -1,6 +1,8 @@ class BuildCoverageWorker include Sidekiq::Worker - include BuildQueue + include PipelineQueue + + enqueue_in group: :processing def perform(build_id) Ci::Build.find_by(id: build_id)&.update_coverage diff --git a/app/workers/build_finished_worker.rb b/app/workers/build_finished_worker.rb index 466410bf08c..e2a1b3dcc41 100644 --- a/app/workers/build_finished_worker.rb +++ b/app/workers/build_finished_worker.rb @@ -1,6 +1,8 @@ class BuildFinishedWorker include Sidekiq::Worker - include BuildQueue + include PipelineQueue + + enqueue_in group: :processing def perform(build_id) Ci::Build.find_by(id: build_id).try do |build| diff --git a/app/workers/build_hooks_worker.rb b/app/workers/build_hooks_worker.rb index 9965af935d4..dedaf2835e6 100644 --- a/app/workers/build_hooks_worker.rb +++ b/app/workers/build_hooks_worker.rb @@ -1,6 +1,8 @@ class BuildHooksWorker include Sidekiq::Worker - include BuildQueue + include PipelineQueue + + enqueue_in group: :hooks def perform(build_id) Ci::Build.find_by(id: build_id) diff --git a/app/workers/build_success_worker.rb b/app/workers/build_success_worker.rb index bf009dfab0f..20ec24bd18a 100644 --- a/app/workers/build_success_worker.rb +++ b/app/workers/build_success_worker.rb @@ -1,6 +1,8 @@ class BuildSuccessWorker include Sidekiq::Worker - include BuildQueue + include PipelineQueue + + enqueue_in group: :processing def perform(build_id) Ci::Build.find_by(id: build_id).try do |build| diff --git a/app/workers/concerns/build_queue.rb b/app/workers/concerns/build_queue.rb deleted file mode 100644 index cf0ead40a8b..00000000000 --- a/app/workers/concerns/build_queue.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Concern for setting Sidekiq settings for the various CI build workers. -module BuildQueue - extend ActiveSupport::Concern - - included do - sidekiq_options queue: :build - end -end diff --git a/app/workers/expire_job_cache_worker.rb b/app/workers/expire_job_cache_worker.rb index e383202260d..98a7500bffe 100644 --- a/app/workers/expire_job_cache_worker.rb +++ b/app/workers/expire_job_cache_worker.rb @@ -1,6 +1,8 @@ class ExpireJobCacheWorker include Sidekiq::Worker - include BuildQueue + include PipelineQueue + + enqueue_in group: :cache def perform(job_id) job = CommitStatus.joins(:pipeline, :project).find_by(id: job_id) diff --git a/spec/workers/build_coverage_worker_spec.rb b/spec/workers/build_coverage_worker_spec.rb index ba20488f663..e49750f6a3e 100644 --- a/spec/workers/build_coverage_worker_spec.rb +++ b/spec/workers/build_coverage_worker_spec.rb @@ -20,4 +20,6 @@ describe BuildCoverageWorker do end end end + + it_behaves_like 'sidekiq_worker' end diff --git a/spec/workers/build_finished_worker_spec.rb b/spec/workers/build_finished_worker_spec.rb index 2868167c7d4..463e8c6a60a 100644 --- a/spec/workers/build_finished_worker_spec.rb +++ b/spec/workers/build_finished_worker_spec.rb @@ -27,4 +27,6 @@ describe BuildFinishedWorker do end end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/build_hooks_worker_spec.rb b/spec/workers/build_hooks_worker_spec.rb index 97654a93f5c..3d98ffabf0a 100644 --- a/spec/workers/build_hooks_worker_spec.rb +++ b/spec/workers/build_hooks_worker_spec.rb @@ -20,4 +20,6 @@ describe BuildHooksWorker do end end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/build_success_worker_spec.rb b/spec/workers/build_success_worker_spec.rb index dba70883130..a82ed5c187d 100644 --- a/spec/workers/build_success_worker_spec.rb +++ b/spec/workers/build_success_worker_spec.rb @@ -33,4 +33,6 @@ describe BuildSuccessWorker do end end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/concerns/build_queue_spec.rb b/spec/workers/concerns/build_queue_spec.rb deleted file mode 100644 index 6bf955e0be2..00000000000 --- a/spec/workers/concerns/build_queue_spec.rb +++ /dev/null @@ -1,14 +0,0 @@ -require 'spec_helper' - -describe BuildQueue do - let(:worker) do - Class.new do - include Sidekiq::Worker - include BuildQueue - end - end - - it 'sets the queue name of a worker' do - expect(worker.sidekiq_options['queue'].to_s).to eq('build') - end -end diff --git a/spec/workers/expire_job_cache_worker_spec.rb b/spec/workers/expire_job_cache_worker_spec.rb index 1b614342a18..552e2c350de 100644 --- a/spec/workers/expire_job_cache_worker_spec.rb +++ b/spec/workers/expire_job_cache_worker_spec.rb @@ -28,4 +28,6 @@ describe ExpireJobCacheWorker do end end end + + it_behaves_like 'sidekiq worker' end From ad12ee2a78ed590194661b3d5365b0eaa14bff80 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Mon, 21 Aug 2017 14:24:05 +0200 Subject: [PATCH 020/196] Assign some CI/CD workers to pipeline default queue --- app/workers/build_coverage_worker.rb | 2 -- app/workers/pipeline_metrics_worker.rb | 2 -- app/workers/pipeline_notification_worker.rb | 2 -- config/sidekiq_queues.yml | 2 +- 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/app/workers/build_coverage_worker.rb b/app/workers/build_coverage_worker.rb index fd5ba11f73e..cd4af85d047 100644 --- a/app/workers/build_coverage_worker.rb +++ b/app/workers/build_coverage_worker.rb @@ -2,8 +2,6 @@ class BuildCoverageWorker include Sidekiq::Worker include PipelineQueue - enqueue_in group: :processing - def perform(build_id) Ci::Build.find_by(id: build_id)&.update_coverage end diff --git a/app/workers/pipeline_metrics_worker.rb b/app/workers/pipeline_metrics_worker.rb index 3795105ef28..070943f1ecc 100644 --- a/app/workers/pipeline_metrics_worker.rb +++ b/app/workers/pipeline_metrics_worker.rb @@ -2,8 +2,6 @@ class PipelineMetricsWorker include Sidekiq::Worker include PipelineQueue - enqueue_in group: :metrics - def perform(pipeline_id) Ci::Pipeline.find_by(id: pipeline_id).try do |pipeline| update_metrics_for_active_pipeline(pipeline) if pipeline.active? diff --git a/app/workers/pipeline_notification_worker.rb b/app/workers/pipeline_notification_worker.rb index 77ff3913ad7..cdb860b6675 100644 --- a/app/workers/pipeline_notification_worker.rb +++ b/app/workers/pipeline_notification_worker.rb @@ -2,8 +2,6 @@ class PipelineNotificationWorker include Sidekiq::Worker include PipelineQueue - enqueue_in group: :hooks - def perform(pipeline_id, recipients = nil) pipeline = Ci::Pipeline.find_by(id: pipeline_id) diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml index 28cfb9419de..2eeb0762b76 100644 --- a/config/sidekiq_queues.yml +++ b/config/sidekiq_queues.yml @@ -28,8 +28,8 @@ - [build, 2] - [pipeline, 2] - [pipeline_processing, 2] + - [pipeline_default, 2] - [pipeline_cache, 2] - - [pipeline_metrics, 2] - [pipeline_hooks, 2] - [gitlab_shell, 2] - [email_receiver, 2] From 82056644d5c3be0b9cc4a268ff367944472bb11e Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Mon, 21 Aug 2017 14:25:58 +0200 Subject: [PATCH 021/196] Adjust sidekiq queues weights in queues config file --- config/sidekiq_queues.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml index 2eeb0762b76..24c001362c6 100644 --- a/config/sidekiq_queues.yml +++ b/config/sidekiq_queues.yml @@ -27,9 +27,9 @@ - [new_merge_request, 2] - [build, 2] - [pipeline, 2] - - [pipeline_processing, 2] - - [pipeline_default, 2] - - [pipeline_cache, 2] + - [pipeline_processing, 5] + - [pipeline_default, 3] + - [pipeline_cache, 3] - [pipeline_hooks, 2] - [gitlab_shell, 2] - [email_receiver, 2] From 15f486e305b32ddaa8eeaf528dc79e04ed6aa98a Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Mon, 21 Aug 2017 14:31:09 +0200 Subject: [PATCH 022/196] Add sidekiq worker shared examples to workers specs --- spec/workers/authorized_projects_worker_spec.rb | 2 ++ spec/workers/background_migration_worker_spec.rb | 2 ++ spec/workers/create_gpg_signature_worker_spec.rb | 2 ++ spec/workers/delete_merged_branches_worker_spec.rb | 2 ++ spec/workers/delete_user_worker_spec.rb | 2 ++ spec/workers/email_receiver_worker_spec.rb | 2 ++ spec/workers/emails_on_push_worker_spec.rb | 2 ++ spec/workers/every_sidekiq_worker_spec.rb | 2 ++ spec/workers/expire_build_artifacts_worker_spec.rb | 2 ++ spec/workers/expire_build_instance_artifacts_worker_spec.rb | 2 ++ spec/workers/git_garbage_collect_worker_spec.rb | 2 ++ spec/workers/gitlab_usage_ping_worker_spec.rb | 2 ++ spec/workers/group_destroy_worker_spec.rb | 2 ++ spec/workers/invalid_gpg_signature_update_worker_spec.rb | 2 ++ spec/workers/merge_worker_spec.rb | 2 ++ spec/workers/namespaceless_project_destroy_worker_spec.rb | 2 ++ spec/workers/new_issue_worker_spec.rb | 2 ++ spec/workers/new_merge_request_worker_spec.rb | 2 ++ spec/workers/new_note_worker_spec.rb | 2 ++ spec/workers/pipeline_schedule_worker_spec.rb | 2 ++ spec/workers/pipeline_update_worker_spec.rb | 4 ++-- spec/workers/post_receive_spec.rb | 2 ++ spec/workers/process_commit_worker_spec.rb | 2 ++ spec/workers/project_cache_worker_spec.rb | 2 ++ spec/workers/project_destroy_worker_spec.rb | 2 ++ spec/workers/propagate_service_template_worker_spec.rb | 2 ++ spec/workers/prune_old_events_worker_spec.rb | 2 ++ spec/workers/reactive_caching_worker_spec.rb | 2 ++ spec/workers/remove_expired_group_links_worker_spec.rb | 2 ++ spec/workers/remove_expired_members_worker_spec.rb | 2 ++ spec/workers/remove_old_web_hook_logs_worker_spec.rb | 2 ++ spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb | 2 ++ spec/workers/repository_fork_worker_spec.rb | 2 ++ spec/workers/repository_import_worker_spec.rb | 2 ++ spec/workers/schedule_update_user_activity_worker_spec.rb | 2 ++ spec/workers/stuck_ci_jobs_worker_spec.rb | 2 ++ spec/workers/stuck_import_jobs_worker_spec.rb | 2 ++ spec/workers/stuck_merge_jobs_worker_spec.rb | 2 ++ spec/workers/system_hook_push_worker_spec.rb | 2 ++ spec/workers/trending_projects_worker_spec.rb | 2 ++ spec/workers/update_merge_requests_worker_spec.rb | 2 ++ spec/workers/update_user_activity_worker_spec.rb | 2 ++ spec/workers/upload_checksum_worker_spec.rb | 2 ++ spec/workers/use_key_worker_spec.rb | 2 ++ 44 files changed, 88 insertions(+), 2 deletions(-) diff --git a/spec/workers/authorized_projects_worker_spec.rb b/spec/workers/authorized_projects_worker_spec.rb index 03b9b99e263..bf9425b3d09 100644 --- a/spec/workers/authorized_projects_worker_spec.rb +++ b/spec/workers/authorized_projects_worker_spec.rb @@ -47,4 +47,6 @@ describe AuthorizedProjectsWorker do end end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/background_migration_worker_spec.rb b/spec/workers/background_migration_worker_spec.rb index 4f6e3474634..69971cf9243 100644 --- a/spec/workers/background_migration_worker_spec.rb +++ b/spec/workers/background_migration_worker_spec.rb @@ -41,4 +41,6 @@ describe BackgroundMigrationWorker, :sidekiq do end end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/create_gpg_signature_worker_spec.rb b/spec/workers/create_gpg_signature_worker_spec.rb index 54978baca88..0cfa957be06 100644 --- a/spec/workers/create_gpg_signature_worker_spec.rb +++ b/spec/workers/create_gpg_signature_worker_spec.rb @@ -36,4 +36,6 @@ describe CreateGpgSignatureWorker do described_class.new.perform(anything, nonexisting_project_id) end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/delete_merged_branches_worker_spec.rb b/spec/workers/delete_merged_branches_worker_spec.rb index 39009d9e4b2..da20d4e7e3f 100644 --- a/spec/workers/delete_merged_branches_worker_spec.rb +++ b/spec/workers/delete_merged_branches_worker_spec.rb @@ -16,4 +16,6 @@ describe DeleteMergedBranchesWorker do expect(worker.perform('unknown', project.owner.id)).to be_falsy end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/delete_user_worker_spec.rb b/spec/workers/delete_user_worker_spec.rb index 36594515005..24fcf41a0c8 100644 --- a/spec/workers/delete_user_worker_spec.rb +++ b/spec/workers/delete_user_worker_spec.rb @@ -17,4 +17,6 @@ describe DeleteUserWorker do described_class.new.perform(current_user.id, user.id, "test" => "test") end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/email_receiver_worker_spec.rb b/spec/workers/email_receiver_worker_spec.rb index e4e77c667b3..d8ffdd4b5ed 100644 --- a/spec/workers/email_receiver_worker_spec.rb +++ b/spec/workers/email_receiver_worker_spec.rb @@ -60,4 +60,6 @@ describe EmailReceiverWorker, :mailer do described_class.new.perform(raw_message) end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/emails_on_push_worker_spec.rb b/spec/workers/emails_on_push_worker_spec.rb index 318aad4bc1e..28031e2292c 100644 --- a/spec/workers/emails_on_push_worker_spec.rb +++ b/spec/workers/emails_on_push_worker_spec.rb @@ -127,4 +127,6 @@ describe EmailsOnPushWorker, :mailer do end end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb index 30908534eb3..34f5bfc8c0c 100644 --- a/spec/workers/every_sidekiq_worker_spec.rb +++ b/spec/workers/every_sidekiq_worker_spec.rb @@ -41,4 +41,6 @@ describe 'Every Sidekiq worker' do expect(queue_names).to include(worker.sidekiq_options['queue'].to_s) end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/expire_build_artifacts_worker_spec.rb b/spec/workers/expire_build_artifacts_worker_spec.rb index b47b4a02a68..751e4dfebd8 100644 --- a/spec/workers/expire_build_artifacts_worker_spec.rb +++ b/spec/workers/expire_build_artifacts_worker_spec.rb @@ -47,4 +47,6 @@ describe ExpireBuildArtifactsWorker do Sidekiq::Queues.jobs_by_worker['ExpireBuildInstanceArtifactsWorker'] end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/expire_build_instance_artifacts_worker_spec.rb b/spec/workers/expire_build_instance_artifacts_worker_spec.rb index bed5c5e2ecb..e1e6a5434fc 100644 --- a/spec/workers/expire_build_instance_artifacts_worker_spec.rb +++ b/spec/workers/expire_build_instance_artifacts_worker_spec.rb @@ -74,4 +74,6 @@ describe ExpireBuildInstanceArtifactsWorker do end end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/git_garbage_collect_worker_spec.rb b/spec/workers/git_garbage_collect_worker_spec.rb index 05f971dfd13..f2917986804 100644 --- a/spec/workers/git_garbage_collect_worker_spec.rb +++ b/spec/workers/git_garbage_collect_worker_spec.rb @@ -131,6 +131,8 @@ describe GitGarbageCollectWorker do end end + it_behaves_like 'sidekiq worker' + # Create a new commit on a random new branch def create_objects(project) rugged = project.repository.rugged diff --git a/spec/workers/gitlab_usage_ping_worker_spec.rb b/spec/workers/gitlab_usage_ping_worker_spec.rb index 49b4e04dc7c..f5ff6736993 100644 --- a/spec/workers/gitlab_usage_ping_worker_spec.rb +++ b/spec/workers/gitlab_usage_ping_worker_spec.rb @@ -10,4 +10,6 @@ describe GitlabUsagePingWorker do subject.perform end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/group_destroy_worker_spec.rb b/spec/workers/group_destroy_worker_spec.rb index a170c84ab12..2f0c55b1b91 100644 --- a/spec/workers/group_destroy_worker_spec.rb +++ b/spec/workers/group_destroy_worker_spec.rb @@ -16,4 +16,6 @@ describe GroupDestroyWorker do expect(Dir.exist?(project.path)).to be_falsey end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/invalid_gpg_signature_update_worker_spec.rb b/spec/workers/invalid_gpg_signature_update_worker_spec.rb index 5972696515b..178dc024201 100644 --- a/spec/workers/invalid_gpg_signature_update_worker_spec.rb +++ b/spec/workers/invalid_gpg_signature_update_worker_spec.rb @@ -26,4 +26,6 @@ describe InvalidGpgSignatureUpdateWorker do described_class.new.perform(nonexisting_gpg_key_id) end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/merge_worker_spec.rb b/spec/workers/merge_worker_spec.rb index ee51000161a..b63c184fdb1 100644 --- a/spec/workers/merge_worker_spec.rb +++ b/spec/workers/merge_worker_spec.rb @@ -38,4 +38,6 @@ describe MergeWorker do expect { worker.perform(merge_request.id, user.id, {}) } .to change { merge_request.reload.merge_jid }.from(nil).to('999') end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/namespaceless_project_destroy_worker_spec.rb b/spec/workers/namespaceless_project_destroy_worker_spec.rb index f2706254284..6d75e7fbfb8 100644 --- a/spec/workers/namespaceless_project_destroy_worker_spec.rb +++ b/spec/workers/namespaceless_project_destroy_worker_spec.rb @@ -76,4 +76,6 @@ describe NamespacelessProjectDestroyWorker do end end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/new_issue_worker_spec.rb b/spec/workers/new_issue_worker_spec.rb index 4e15ccc534b..e82302d5cfe 100644 --- a/spec/workers/new_issue_worker_spec.rb +++ b/spec/workers/new_issue_worker_spec.rb @@ -51,4 +51,6 @@ describe NewIssueWorker do end end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/new_merge_request_worker_spec.rb b/spec/workers/new_merge_request_worker_spec.rb index 9e0cbde45b1..a7e2e4376d6 100644 --- a/spec/workers/new_merge_request_worker_spec.rb +++ b/spec/workers/new_merge_request_worker_spec.rb @@ -53,4 +53,6 @@ describe NewMergeRequestWorker do end end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/new_note_worker_spec.rb b/spec/workers/new_note_worker_spec.rb index 575361c93d4..d935a0ae3b4 100644 --- a/spec/workers/new_note_worker_spec.rb +++ b/spec/workers/new_note_worker_spec.rb @@ -46,4 +46,6 @@ describe NewNoteWorker do described_class.new.perform(unexistent_note_id) end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/pipeline_schedule_worker_spec.rb b/spec/workers/pipeline_schedule_worker_spec.rb index 75197039f5a..4cea91a237c 100644 --- a/spec/workers/pipeline_schedule_worker_spec.rb +++ b/spec/workers/pipeline_schedule_worker_spec.rb @@ -62,4 +62,6 @@ describe PipelineScheduleWorker do expect { subject }.not_to change { project.pipelines.count } end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/pipeline_update_worker_spec.rb b/spec/workers/pipeline_update_worker_spec.rb index 60e7e23f0b4..cd8ae030ab9 100644 --- a/spec/workers/pipeline_update_worker_spec.rb +++ b/spec/workers/pipeline_update_worker_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' describe PipelineUpdateWorker do - it_behaves_like 'sidekiq worker' - describe '#perform' do context 'when pipeline exists' do let(:pipeline) { create(:ci_pipeline) } @@ -21,4 +19,6 @@ describe PipelineUpdateWorker do end end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb index af6a3c9f6c7..4968758cb6b 100644 --- a/spec/workers/post_receive_spec.rb +++ b/spec/workers/post_receive_spec.rb @@ -140,4 +140,6 @@ describe PostReceive do described_class.new.perform(gl_repository, key_id, base64_changes) end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/process_commit_worker_spec.rb b/spec/workers/process_commit_worker_spec.rb index 24f8ca67594..0580ea60742 100644 --- a/spec/workers/process_commit_worker_spec.rb +++ b/spec/workers/process_commit_worker_spec.rb @@ -134,4 +134,6 @@ describe ProcessCommitWorker do expect(commit.authored_date).to be_an_instance_of(Time) end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/project_cache_worker_spec.rb b/spec/workers/project_cache_worker_spec.rb index 6b1f2ff3227..20d18a433d3 100644 --- a/spec/workers/project_cache_worker_spec.rb +++ b/spec/workers/project_cache_worker_spec.rb @@ -87,4 +87,6 @@ describe ProjectCacheWorker do end end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/project_destroy_worker_spec.rb b/spec/workers/project_destroy_worker_spec.rb index f19c9dff941..7c2a293c5f3 100644 --- a/spec/workers/project_destroy_worker_spec.rb +++ b/spec/workers/project_destroy_worker_spec.rb @@ -33,4 +33,6 @@ describe ProjectDestroyWorker do end.not_to raise_error end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/propagate_service_template_worker_spec.rb b/spec/workers/propagate_service_template_worker_spec.rb index b8b65ead9b3..21df8eb489e 100644 --- a/spec/workers/propagate_service_template_worker_spec.rb +++ b/spec/workers/propagate_service_template_worker_spec.rb @@ -26,4 +26,6 @@ describe PropagateServiceTemplateWorker do subject.perform(service_template.id) end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/prune_old_events_worker_spec.rb b/spec/workers/prune_old_events_worker_spec.rb index ea974355050..e9b3061a1be 100644 --- a/spec/workers/prune_old_events_worker_spec.rb +++ b/spec/workers/prune_old_events_worker_spec.rb @@ -23,4 +23,6 @@ describe PruneOldEventsWorker do expect(exactly_12_months_event).to be_present end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/reactive_caching_worker_spec.rb b/spec/workers/reactive_caching_worker_spec.rb index 5f4453c15d6..44aa520d102 100644 --- a/spec/workers/reactive_caching_worker_spec.rb +++ b/spec/workers/reactive_caching_worker_spec.rb @@ -12,4 +12,6 @@ describe ReactiveCachingWorker do subject end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/remove_expired_group_links_worker_spec.rb b/spec/workers/remove_expired_group_links_worker_spec.rb index 689bc3d27b4..2615b049650 100644 --- a/spec/workers/remove_expired_group_links_worker_spec.rb +++ b/spec/workers/remove_expired_group_links_worker_spec.rb @@ -21,4 +21,6 @@ describe RemoveExpiredGroupLinksWorker do expect(non_expiring_project_group_link.reload).to be_present end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/remove_expired_members_worker_spec.rb b/spec/workers/remove_expired_members_worker_spec.rb index 058fdf4c009..1b0af031a83 100644 --- a/spec/workers/remove_expired_members_worker_spec.rb +++ b/spec/workers/remove_expired_members_worker_spec.rb @@ -55,4 +55,6 @@ describe RemoveExpiredMembersWorker do end end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/remove_old_web_hook_logs_worker_spec.rb b/spec/workers/remove_old_web_hook_logs_worker_spec.rb index 6d26ba5dfa0..4a504f34367 100644 --- a/spec/workers/remove_old_web_hook_logs_worker_spec.rb +++ b/spec/workers/remove_old_web_hook_logs_worker_spec.rb @@ -15,4 +15,6 @@ describe RemoveOldWebHookLogsWorker do expect(WebHookLog.all).not_to include(week_old_record, three_days_old_record) end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb b/spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb index 57f83c1dbe9..fccb64717ad 100644 --- a/spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb +++ b/spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb @@ -52,4 +52,6 @@ describe RemoveUnreferencedLfsObjectsWorker do expect(LfsObject.where(id: referenced_lfs_object2.id)).to be_empty end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/repository_fork_worker_spec.rb b/spec/workers/repository_fork_worker_spec.rb index d9e9409840f..6550de6f893 100644 --- a/spec/workers/repository_fork_worker_spec.rb +++ b/spec/workers/repository_fork_worker_spec.rb @@ -69,4 +69,6 @@ describe RepositoryForkWorker do expect(project.reload.import_status).to eq('failed') end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/repository_import_worker_spec.rb b/spec/workers/repository_import_worker_spec.rb index 100dfc32bbe..d67891aa388 100644 --- a/spec/workers/repository_import_worker_spec.rb +++ b/spec/workers/repository_import_worker_spec.rb @@ -43,4 +43,6 @@ describe RepositoryImportWorker do end end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/schedule_update_user_activity_worker_spec.rb b/spec/workers/schedule_update_user_activity_worker_spec.rb index 32c59381b01..362cd2a6d92 100644 --- a/spec/workers/schedule_update_user_activity_worker_spec.rb +++ b/spec/workers/schedule_update_user_activity_worker_spec.rb @@ -22,4 +22,6 @@ describe ScheduleUpdateUserActivityWorker, :clean_gitlab_redis_shared_state do subject.perform(1) end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/stuck_ci_jobs_worker_spec.rb b/spec/workers/stuck_ci_jobs_worker_spec.rb index 549635f7f33..f64de2a9c21 100644 --- a/spec/workers/stuck_ci_jobs_worker_spec.rb +++ b/spec/workers/stuck_ci_jobs_worker_spec.rb @@ -132,4 +132,6 @@ describe StuckCiJobsWorker do worker.perform end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/stuck_import_jobs_worker_spec.rb b/spec/workers/stuck_import_jobs_worker_spec.rb index a82eb54ffe4..64a69fc4872 100644 --- a/spec/workers/stuck_import_jobs_worker_spec.rb +++ b/spec/workers/stuck_import_jobs_worker_spec.rb @@ -33,4 +33,6 @@ describe StuckImportJobsWorker do end end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/stuck_merge_jobs_worker_spec.rb b/spec/workers/stuck_merge_jobs_worker_spec.rb index a5ad78393c9..a989942f913 100644 --- a/spec/workers/stuck_merge_jobs_worker_spec.rb +++ b/spec/workers/stuck_merge_jobs_worker_spec.rb @@ -47,4 +47,6 @@ describe StuckMergeJobsWorker do end end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/system_hook_push_worker_spec.rb b/spec/workers/system_hook_push_worker_spec.rb index b1d446ed25f..e0588e2a1b3 100644 --- a/spec/workers/system_hook_push_worker_spec.rb +++ b/spec/workers/system_hook_push_worker_spec.rb @@ -16,4 +16,6 @@ describe SystemHookPushWorker do subject.perform(push_data, :push_hooks) end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/trending_projects_worker_spec.rb b/spec/workers/trending_projects_worker_spec.rb index c3c6fdcf2d5..a9e0c9d1d77 100644 --- a/spec/workers/trending_projects_worker_spec.rb +++ b/spec/workers/trending_projects_worker_spec.rb @@ -8,4 +8,6 @@ describe TrendingProjectsWorker do described_class.new.perform end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/update_merge_requests_worker_spec.rb b/spec/workers/update_merge_requests_worker_spec.rb index 558ff9109ec..f40c9012db9 100644 --- a/spec/workers/update_merge_requests_worker_spec.rb +++ b/spec/workers/update_merge_requests_worker_spec.rb @@ -24,4 +24,6 @@ describe UpdateMergeRequestsWorker do perform end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/update_user_activity_worker_spec.rb b/spec/workers/update_user_activity_worker_spec.rb index 268ca1d81f2..9cd7ffc2ab4 100644 --- a/spec/workers/update_user_activity_worker_spec.rb +++ b/spec/workers/update_user_activity_worker_spec.rb @@ -32,4 +32,6 @@ describe UpdateUserActivityWorker, :clean_gitlab_redis_shared_state do expect(Gitlab::UserActivities.new.to_a).to be_empty end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/upload_checksum_worker_spec.rb b/spec/workers/upload_checksum_worker_spec.rb index 911360da66c..735aeec1046 100644 --- a/spec/workers/upload_checksum_worker_spec.rb +++ b/spec/workers/upload_checksum_worker_spec.rb @@ -16,4 +16,6 @@ describe UploadChecksumWorker do expect(upload).to have_received(:save!) end end + + it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/use_key_worker_spec.rb b/spec/workers/use_key_worker_spec.rb index e50c788b82a..c7de5bb6117 100644 --- a/spec/workers/use_key_worker_spec.rb +++ b/spec/workers/use_key_worker_spec.rb @@ -20,4 +20,6 @@ describe UseKeyWorker do expect(worker.perform(key.id + 1)).to eq false end end + + it_behaves_like 'sidekiq worker' end From 4c68ff08bb2c48f85a3f3a79db14ec7402a8ba69 Mon Sep 17 00:00:00 2001 From: "http://jneen.net/" Date: Fri, 18 Aug 2017 13:36:51 -0700 Subject: [PATCH 023/196] add a spec for a participant with a :custom setting where that custom setting is not enabled. --- spec/services/notification_service_spec.rb | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index 44b2d28d1d4..5223152ce66 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -130,7 +130,18 @@ describe NotificationService, :mailer do project.add_master(issue.author) project.add_master(assignee) project.add_master(note.author) - create(:note_on_issue, noteable: issue, project_id: issue.project_id, note: '@subscribed_participant cc this guy') + + @u_custom_off = create_user_with_notification(:custom, 'custom_off') + project.add_guest(@u_custom_off) + + create( + :note_on_issue, + author: @u_custom_off, + noteable: issue, + project_id: issue.project_id, + note: 'i think @subscribed_participant should see this' + ) + update_custom_notification(:new_note, @u_guest_custom, resource: project) update_custom_notification(:new_note, @u_custom_global) end @@ -141,7 +152,7 @@ describe NotificationService, :mailer do reset_delivered_emails! # Ensure create SentNotification by noteable = issue 6 times, not noteable = note - expect(SentNotification).to receive(:record).with(issue, any_args).exactly(8).times + expect(SentNotification).to receive(:record).with(issue, any_args).exactly(9).times notification.new_note(note) @@ -153,6 +164,7 @@ describe NotificationService, :mailer do should_email(@subscriber) should_email(@watcher_and_subscriber) should_email(@subscribed_participant) + should_email(@u_custom_off) should_not_email(@u_guest_custom) should_not_email(@u_guest_watcher) should_not_email(note.author) From 7059af29800da478edbe04f4edf63fd7698909f5 Mon Sep 17 00:00:00 2001 From: "http://jneen.net/" Date: Fri, 18 Aug 2017 13:39:12 -0700 Subject: [PATCH 024/196] actually use the :participating notification type --- app/services/notification_recipient_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/notification_recipient_service.rb b/app/services/notification_recipient_service.rb index 21c9c314a2a..c9f07c140f7 100644 --- a/app/services/notification_recipient_service.rb +++ b/app/services/notification_recipient_service.rb @@ -95,7 +95,7 @@ module NotificationRecipientService def add_participants(user) return unless target.respond_to?(:participants) - self << [target.participants(user), :watch] + self << [target.participants(user), :participating] end # Get project/group users with CUSTOM notification level From 3676275a5a07492bb24a8b1925f7221c375a2f42 Mon Sep 17 00:00:00 2001 From: "http://jneen.net/" Date: Fri, 18 Aug 2017 13:40:09 -0700 Subject: [PATCH 025/196] don't rely on order of notification levels factor out #suitable_notification_level? and check manually by notification level. this makes the notification logic clear and actually reflect what is in the documentation as to what should happen with each setting. --- app/models/notification_recipient.rb | 53 ++++++++++++++-------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/app/models/notification_recipient.rb b/app/models/notification_recipient.rb index dc862565a71..183e098d819 100644 --- a/app/models/notification_recipient.rb +++ b/app/models/notification_recipient.rb @@ -27,46 +27,45 @@ class NotificationRecipient @notification_setting ||= find_notification_setting end - def raw_notification_level - notification_setting&.level&.to_sym - end - def notification_level - # custom is treated the same as watch if it's enabled - otherwise it's - # set to :custom, meaning to send exactly when our type is :participating - # or :mention. - @notification_level ||= - case raw_notification_level - when :custom - if @custom_action && notification_setting&.event_enabled?(@custom_action) - :watch - else - :custom - end - else - raw_notification_level - end + @notification_level ||= notification_setting&.level&.to_sym end def notifiable? return false unless has_access? return false if own_activity? - return true if @type == :subscription + # even users with :disabled notifications receive manual subscriptions + return !unsubscribed? if @type == :subscription - return false if notification_level.nil? || notification_level == :disabled - - return %i[participating mention].include?(@type) if notification_level == :custom - - return false if %i[watch participating].include?(notification_level) && excluded_watcher_action? - - return false unless NotificationSetting.levels[notification_level] <= NotificationSetting.levels[@type] + return false unless suitable_notification_level? + # check this last because it's expensive + # nobody should receive notifications if they've specifically unsubscribed return false if unsubscribed? true end + def suitable_notification_level? + case notification_level + when :disabled, nil + false + when :custom + custom_enabled? || %i[participating mention].include?(@type) + when :watch, :participating + !excluded_watcher_action? + when :mention + @type == :mention + else + false + end + end + + def custom_enabled? + @custom_action && notification_setting&.event_enabled?(@custom_action) + end + def unsubscribed? return false unless @target return false unless @target.respond_to?(:subscriptions) @@ -98,7 +97,7 @@ class NotificationRecipient def excluded_watcher_action? return false unless @custom_action - return false if raw_notification_level == :custom + return false if notification_level == :custom NotificationSetting::EXCLUDED_WATCHER_EVENTS.include?(@custom_action) end From 57fb2d4f8f0c9f5dc563bdb0eb6935748674a299 Mon Sep 17 00:00:00 2001 From: "http://jneen.net/" Date: Mon, 21 Aug 2017 13:47:15 -0700 Subject: [PATCH 026/196] rm a comment that is a lie --- spec/services/notification_service_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index 5223152ce66..5b349017c8b 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -151,7 +151,6 @@ describe NotificationService, :mailer do add_users_with_subscription(note.project, issue) reset_delivered_emails! - # Ensure create SentNotification by noteable = issue 6 times, not noteable = note expect(SentNotification).to receive(:record).with(issue, any_args).exactly(9).times notification.new_note(note) From bf7f23531d78c02836decae88895609b14a2980f Mon Sep 17 00:00:00 2001 From: "http://jneen.net/" Date: Mon, 21 Aug 2017 14:19:53 -0700 Subject: [PATCH 027/196] add a changelog --- changelogs/unreleased/bugfix-notify-custom-participants.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelogs/unreleased/bugfix-notify-custom-participants.yml diff --git a/changelogs/unreleased/bugfix-notify-custom-participants.yml b/changelogs/unreleased/bugfix-notify-custom-participants.yml new file mode 100644 index 00000000000..32ba1076b09 --- /dev/null +++ b/changelogs/unreleased/bugfix-notify-custom-participants.yml @@ -0,0 +1,5 @@ +--- +title: 13680-notify-custom-participants +merge_request: 13680 +author: jneen +type: fixed From 75fa692d8def8fed50332f7846dbd8aa058c1d02 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 22 Aug 2017 10:40:56 +0200 Subject: [PATCH 028/196] Include build queue worker in the processing group --- app/workers/build_queue_worker.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/workers/build_queue_worker.rb b/app/workers/build_queue_worker.rb index fa9e097e40a..e5ceb9ef715 100644 --- a/app/workers/build_queue_worker.rb +++ b/app/workers/build_queue_worker.rb @@ -1,6 +1,8 @@ class BuildQueueWorker include Sidekiq::Worker - include BuildQueue + include PipelineQueue + + enqueue_in group: :processing def perform(build_id) Ci::Build.find_by(id: build_id).try do |build| From 086f0351df9f013b4b0f3f80f7ab5d18be0d1733 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 22 Aug 2017 10:57:52 +0200 Subject: [PATCH 029/196] Do not fire synrchonous hooks when creating a job Fire asynchronous hooks instead. --- app/models/ci/build.rb | 5 ++++- spec/models/ci/build_spec.rb | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 4692fb5644a..936e3c83dfd 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -46,7 +46,10 @@ module Ci before_save :ensure_token before_destroy { unscoped_project } - after_create :execute_hooks + after_create do |build| + BuildHooksWorker.perform_async(build.id) + end + after_commit :update_project_statistics_after_save, on: [:create, :update] after_commit :update_project_statistics, on: :destroy diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index 767f0ad9e65..4f77f0d85cd 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -21,6 +21,16 @@ describe Ci::Build do it { is_expected.to respond_to(:has_trace?) } it { is_expected.to respond_to(:trace) } + describe 'callbacks' do + context 'when running after_create callback' do + it 'triggers asynchronous build hooks worker' do + expect(BuildHooksWorker).to receive(:perform_async) + + create(:ci_build) + end + end + end + describe '.manual_actions' do let!(:manual_but_created) { create(:ci_build, :manual, status: :created, pipeline: pipeline) } let!(:manual_but_succeeded) { create(:ci_build, :manual, status: :success, pipeline: pipeline) } From 0a2998b3193cbded4f6b5a33964e9a8d953ecbda Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 22 Aug 2017 11:21:12 +0200 Subject: [PATCH 030/196] Add changelog for asynchronous job events fix --- .../backstage-gb-after-save-asynchronous-job-hooks.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelogs/unreleased/backstage-gb-after-save-asynchronous-job-hooks.yml diff --git a/changelogs/unreleased/backstage-gb-after-save-asynchronous-job-hooks.yml b/changelogs/unreleased/backstage-gb-after-save-asynchronous-job-hooks.yml new file mode 100644 index 00000000000..fd0b7c4f43c --- /dev/null +++ b/changelogs/unreleased/backstage-gb-after-save-asynchronous-job-hooks.yml @@ -0,0 +1,5 @@ +--- +title: Fire hooks asynchronously when creating a new job to improve performance +merge_request: 13734 +author: +type: changed From beb8f46e946f217f6132670c16d118f973012a48 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 22 Aug 2017 11:29:42 +0200 Subject: [PATCH 031/196] Fix typo in shared examples name in worker specs --- spec/workers/build_coverage_worker_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/workers/build_coverage_worker_spec.rb b/spec/workers/build_coverage_worker_spec.rb index e49750f6a3e..a679e5c7af6 100644 --- a/spec/workers/build_coverage_worker_spec.rb +++ b/spec/workers/build_coverage_worker_spec.rb @@ -21,5 +21,5 @@ describe BuildCoverageWorker do end end - it_behaves_like 'sidekiq_worker' + it_behaves_like 'sidekiq worker' end From c29247aadf97e17647d1c44d4aa2646cca6dcebc Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 22 Aug 2017 11:34:29 +0200 Subject: [PATCH 032/196] Fix inconsistent Sidekiq queues names in worker specs --- spec/support/shared_examples/sidekiq_worker_shared_examples.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/support/shared_examples/sidekiq_worker_shared_examples.rb b/spec/support/shared_examples/sidekiq_worker_shared_examples.rb index 712cad2a0d9..4ff267a7838 100644 --- a/spec/support/shared_examples/sidekiq_worker_shared_examples.rb +++ b/spec/support/shared_examples/sidekiq_worker_shared_examples.rb @@ -5,6 +5,6 @@ shared_examples 'sidekiq worker' do end it 'is going to be processed inside a known sidekiq queue' do - expect(described_class.sidekiq_options['queue']).to be_in queues + expect(described_class.sidekiq_options['queue'].to_s).to be_in queues end end From 75dca155af7a707b5d4a9860008d8bbaea6c2537 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 22 Aug 2017 11:37:35 +0200 Subject: [PATCH 033/196] Fix incorrect `let` in pipeline metrics worker specs --- spec/workers/pipeline_metrics_worker_spec.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/spec/workers/pipeline_metrics_worker_spec.rb b/spec/workers/pipeline_metrics_worker_spec.rb index dac0b24d24a..69ad4ddea04 100644 --- a/spec/workers/pipeline_metrics_worker_spec.rb +++ b/spec/workers/pipeline_metrics_worker_spec.rb @@ -2,7 +2,12 @@ require 'spec_helper' describe PipelineMetricsWorker do let(:project) { create(:project, :repository) } - let!(:merge_request) { create(:merge_request, source_project: project, source_branch: pipeline.ref, head_pipeline: pipeline) } + + let!(:merge_request) do + create(:merge_request, source_project: project, + source_branch: pipeline.ref, + head_pipeline: pipeline) + end let(:pipeline) do create(:ci_empty_pipeline, @@ -14,6 +19,8 @@ describe PipelineMetricsWorker do finished_at: Time.now) end + let(:status) { 'pending' } + describe '#perform' do before do described_class.new.perform(pipeline.id) From 73187801df9a128a73b36672c64fc69a87e3c519 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 22 Aug 2017 12:09:22 +0200 Subject: [PATCH 034/196] Revert adding shared examples for every sidekiq worker Since this already exists in `every_sidekiq_worker_spec.rb`. --- .../shared_examples/sidekiq_worker_shared_examples.rb | 10 ---------- spec/workers/authorized_projects_worker_spec.rb | 2 -- spec/workers/background_migration_worker_spec.rb | 2 -- spec/workers/build_coverage_worker_spec.rb | 2 -- spec/workers/build_finished_worker_spec.rb | 2 -- spec/workers/build_hooks_worker_spec.rb | 2 -- spec/workers/build_success_worker_spec.rb | 2 -- spec/workers/create_gpg_signature_worker_spec.rb | 2 -- spec/workers/delete_merged_branches_worker_spec.rb | 2 -- spec/workers/delete_user_worker_spec.rb | 2 -- spec/workers/email_receiver_worker_spec.rb | 2 -- spec/workers/emails_on_push_worker_spec.rb | 2 -- spec/workers/every_sidekiq_worker_spec.rb | 2 -- spec/workers/expire_build_artifacts_worker_spec.rb | 2 -- .../expire_build_instance_artifacts_worker_spec.rb | 2 -- spec/workers/expire_job_cache_worker_spec.rb | 2 -- spec/workers/expire_pipeline_cache_worker_spec.rb | 2 -- spec/workers/git_garbage_collect_worker_spec.rb | 2 -- spec/workers/gitlab_usage_ping_worker_spec.rb | 2 -- spec/workers/group_destroy_worker_spec.rb | 2 -- .../invalid_gpg_signature_update_worker_spec.rb | 2 -- spec/workers/merge_worker_spec.rb | 2 -- .../namespaceless_project_destroy_worker_spec.rb | 2 -- spec/workers/new_issue_worker_spec.rb | 2 -- spec/workers/new_merge_request_worker_spec.rb | 2 -- spec/workers/new_note_worker_spec.rb | 2 -- spec/workers/pipeline_hooks_worker_spec.rb | 2 -- spec/workers/pipeline_metrics_worker_spec.rb | 2 -- spec/workers/pipeline_notification_worker_spec.rb | 2 -- spec/workers/pipeline_process_worker_spec.rb | 2 -- spec/workers/pipeline_schedule_worker_spec.rb | 2 -- spec/workers/pipeline_success_worker_spec.rb | 2 -- spec/workers/pipeline_update_worker_spec.rb | 2 -- spec/workers/post_receive_spec.rb | 2 -- spec/workers/process_commit_worker_spec.rb | 2 -- spec/workers/project_cache_worker_spec.rb | 2 -- spec/workers/project_destroy_worker_spec.rb | 2 -- spec/workers/propagate_service_template_worker_spec.rb | 2 -- spec/workers/prune_old_events_worker_spec.rb | 2 -- spec/workers/reactive_caching_worker_spec.rb | 2 -- spec/workers/remove_expired_group_links_worker_spec.rb | 2 -- spec/workers/remove_expired_members_worker_spec.rb | 2 -- spec/workers/remove_old_web_hook_logs_worker_spec.rb | 2 -- .../remove_unreferenced_lfs_objects_worker_spec.rb | 2 -- spec/workers/repository_fork_worker_spec.rb | 2 -- spec/workers/repository_import_worker_spec.rb | 2 -- .../schedule_update_user_activity_worker_spec.rb | 2 -- spec/workers/stuck_ci_jobs_worker_spec.rb | 2 -- spec/workers/stuck_import_jobs_worker_spec.rb | 2 -- spec/workers/stuck_merge_jobs_worker_spec.rb | 2 -- spec/workers/system_hook_push_worker_spec.rb | 2 -- spec/workers/trending_projects_worker_spec.rb | 2 -- spec/workers/update_merge_requests_worker_spec.rb | 2 -- spec/workers/update_user_activity_worker_spec.rb | 2 -- spec/workers/upload_checksum_worker_spec.rb | 2 -- spec/workers/use_key_worker_spec.rb | 2 -- 56 files changed, 120 deletions(-) delete mode 100644 spec/support/shared_examples/sidekiq_worker_shared_examples.rb diff --git a/spec/support/shared_examples/sidekiq_worker_shared_examples.rb b/spec/support/shared_examples/sidekiq_worker_shared_examples.rb deleted file mode 100644 index 4ff267a7838..00000000000 --- a/spec/support/shared_examples/sidekiq_worker_shared_examples.rb +++ /dev/null @@ -1,10 +0,0 @@ -shared_examples 'sidekiq worker' do - let(:queues) do - YAML.load_file(Rails.root.join('config', 'sidekiq_queues.yml')) - .fetch(:queues, []).map(&:first) - end - - it 'is going to be processed inside a known sidekiq queue' do - expect(described_class.sidekiq_options['queue'].to_s).to be_in queues - end -end diff --git a/spec/workers/authorized_projects_worker_spec.rb b/spec/workers/authorized_projects_worker_spec.rb index bf9425b3d09..03b9b99e263 100644 --- a/spec/workers/authorized_projects_worker_spec.rb +++ b/spec/workers/authorized_projects_worker_spec.rb @@ -47,6 +47,4 @@ describe AuthorizedProjectsWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/background_migration_worker_spec.rb b/spec/workers/background_migration_worker_spec.rb index 69971cf9243..4f6e3474634 100644 --- a/spec/workers/background_migration_worker_spec.rb +++ b/spec/workers/background_migration_worker_spec.rb @@ -41,6 +41,4 @@ describe BackgroundMigrationWorker, :sidekiq do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/build_coverage_worker_spec.rb b/spec/workers/build_coverage_worker_spec.rb index a679e5c7af6..ba20488f663 100644 --- a/spec/workers/build_coverage_worker_spec.rb +++ b/spec/workers/build_coverage_worker_spec.rb @@ -20,6 +20,4 @@ describe BuildCoverageWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/build_finished_worker_spec.rb b/spec/workers/build_finished_worker_spec.rb index 463e8c6a60a..2868167c7d4 100644 --- a/spec/workers/build_finished_worker_spec.rb +++ b/spec/workers/build_finished_worker_spec.rb @@ -27,6 +27,4 @@ describe BuildFinishedWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/build_hooks_worker_spec.rb b/spec/workers/build_hooks_worker_spec.rb index 3d98ffabf0a..97654a93f5c 100644 --- a/spec/workers/build_hooks_worker_spec.rb +++ b/spec/workers/build_hooks_worker_spec.rb @@ -20,6 +20,4 @@ describe BuildHooksWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/build_success_worker_spec.rb b/spec/workers/build_success_worker_spec.rb index a82ed5c187d..dba70883130 100644 --- a/spec/workers/build_success_worker_spec.rb +++ b/spec/workers/build_success_worker_spec.rb @@ -33,6 +33,4 @@ describe BuildSuccessWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/create_gpg_signature_worker_spec.rb b/spec/workers/create_gpg_signature_worker_spec.rb index 0cfa957be06..54978baca88 100644 --- a/spec/workers/create_gpg_signature_worker_spec.rb +++ b/spec/workers/create_gpg_signature_worker_spec.rb @@ -36,6 +36,4 @@ describe CreateGpgSignatureWorker do described_class.new.perform(anything, nonexisting_project_id) end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/delete_merged_branches_worker_spec.rb b/spec/workers/delete_merged_branches_worker_spec.rb index da20d4e7e3f..39009d9e4b2 100644 --- a/spec/workers/delete_merged_branches_worker_spec.rb +++ b/spec/workers/delete_merged_branches_worker_spec.rb @@ -16,6 +16,4 @@ describe DeleteMergedBranchesWorker do expect(worker.perform('unknown', project.owner.id)).to be_falsy end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/delete_user_worker_spec.rb b/spec/workers/delete_user_worker_spec.rb index 24fcf41a0c8..36594515005 100644 --- a/spec/workers/delete_user_worker_spec.rb +++ b/spec/workers/delete_user_worker_spec.rb @@ -17,6 +17,4 @@ describe DeleteUserWorker do described_class.new.perform(current_user.id, user.id, "test" => "test") end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/email_receiver_worker_spec.rb b/spec/workers/email_receiver_worker_spec.rb index d8ffdd4b5ed..e4e77c667b3 100644 --- a/spec/workers/email_receiver_worker_spec.rb +++ b/spec/workers/email_receiver_worker_spec.rb @@ -60,6 +60,4 @@ describe EmailReceiverWorker, :mailer do described_class.new.perform(raw_message) end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/emails_on_push_worker_spec.rb b/spec/workers/emails_on_push_worker_spec.rb index 28031e2292c..318aad4bc1e 100644 --- a/spec/workers/emails_on_push_worker_spec.rb +++ b/spec/workers/emails_on_push_worker_spec.rb @@ -127,6 +127,4 @@ describe EmailsOnPushWorker, :mailer do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb index 34f5bfc8c0c..30908534eb3 100644 --- a/spec/workers/every_sidekiq_worker_spec.rb +++ b/spec/workers/every_sidekiq_worker_spec.rb @@ -41,6 +41,4 @@ describe 'Every Sidekiq worker' do expect(queue_names).to include(worker.sidekiq_options['queue'].to_s) end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/expire_build_artifacts_worker_spec.rb b/spec/workers/expire_build_artifacts_worker_spec.rb index 751e4dfebd8..b47b4a02a68 100644 --- a/spec/workers/expire_build_artifacts_worker_spec.rb +++ b/spec/workers/expire_build_artifacts_worker_spec.rb @@ -47,6 +47,4 @@ describe ExpireBuildArtifactsWorker do Sidekiq::Queues.jobs_by_worker['ExpireBuildInstanceArtifactsWorker'] end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/expire_build_instance_artifacts_worker_spec.rb b/spec/workers/expire_build_instance_artifacts_worker_spec.rb index e1e6a5434fc..bed5c5e2ecb 100644 --- a/spec/workers/expire_build_instance_artifacts_worker_spec.rb +++ b/spec/workers/expire_build_instance_artifacts_worker_spec.rb @@ -74,6 +74,4 @@ describe ExpireBuildInstanceArtifactsWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/expire_job_cache_worker_spec.rb b/spec/workers/expire_job_cache_worker_spec.rb index 552e2c350de..1b614342a18 100644 --- a/spec/workers/expire_job_cache_worker_spec.rb +++ b/spec/workers/expire_job_cache_worker_spec.rb @@ -28,6 +28,4 @@ describe ExpireJobCacheWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/expire_pipeline_cache_worker_spec.rb b/spec/workers/expire_pipeline_cache_worker_spec.rb index 85b24d5a8f0..54c9a69d329 100644 --- a/spec/workers/expire_pipeline_cache_worker_spec.rb +++ b/spec/workers/expire_pipeline_cache_worker_spec.rb @@ -43,6 +43,4 @@ describe ExpirePipelineCacheWorker do subject.perform(pipeline.id) end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/git_garbage_collect_worker_spec.rb b/spec/workers/git_garbage_collect_worker_spec.rb index f2917986804..05f971dfd13 100644 --- a/spec/workers/git_garbage_collect_worker_spec.rb +++ b/spec/workers/git_garbage_collect_worker_spec.rb @@ -131,8 +131,6 @@ describe GitGarbageCollectWorker do end end - it_behaves_like 'sidekiq worker' - # Create a new commit on a random new branch def create_objects(project) rugged = project.repository.rugged diff --git a/spec/workers/gitlab_usage_ping_worker_spec.rb b/spec/workers/gitlab_usage_ping_worker_spec.rb index f5ff6736993..49b4e04dc7c 100644 --- a/spec/workers/gitlab_usage_ping_worker_spec.rb +++ b/spec/workers/gitlab_usage_ping_worker_spec.rb @@ -10,6 +10,4 @@ describe GitlabUsagePingWorker do subject.perform end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/group_destroy_worker_spec.rb b/spec/workers/group_destroy_worker_spec.rb index 2f0c55b1b91..a170c84ab12 100644 --- a/spec/workers/group_destroy_worker_spec.rb +++ b/spec/workers/group_destroy_worker_spec.rb @@ -16,6 +16,4 @@ describe GroupDestroyWorker do expect(Dir.exist?(project.path)).to be_falsey end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/invalid_gpg_signature_update_worker_spec.rb b/spec/workers/invalid_gpg_signature_update_worker_spec.rb index 178dc024201..5972696515b 100644 --- a/spec/workers/invalid_gpg_signature_update_worker_spec.rb +++ b/spec/workers/invalid_gpg_signature_update_worker_spec.rb @@ -26,6 +26,4 @@ describe InvalidGpgSignatureUpdateWorker do described_class.new.perform(nonexisting_gpg_key_id) end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/merge_worker_spec.rb b/spec/workers/merge_worker_spec.rb index b63c184fdb1..ee51000161a 100644 --- a/spec/workers/merge_worker_spec.rb +++ b/spec/workers/merge_worker_spec.rb @@ -38,6 +38,4 @@ describe MergeWorker do expect { worker.perform(merge_request.id, user.id, {}) } .to change { merge_request.reload.merge_jid }.from(nil).to('999') end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/namespaceless_project_destroy_worker_spec.rb b/spec/workers/namespaceless_project_destroy_worker_spec.rb index 6d75e7fbfb8..f2706254284 100644 --- a/spec/workers/namespaceless_project_destroy_worker_spec.rb +++ b/spec/workers/namespaceless_project_destroy_worker_spec.rb @@ -76,6 +76,4 @@ describe NamespacelessProjectDestroyWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/new_issue_worker_spec.rb b/spec/workers/new_issue_worker_spec.rb index e82302d5cfe..4e15ccc534b 100644 --- a/spec/workers/new_issue_worker_spec.rb +++ b/spec/workers/new_issue_worker_spec.rb @@ -51,6 +51,4 @@ describe NewIssueWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/new_merge_request_worker_spec.rb b/spec/workers/new_merge_request_worker_spec.rb index a7e2e4376d6..9e0cbde45b1 100644 --- a/spec/workers/new_merge_request_worker_spec.rb +++ b/spec/workers/new_merge_request_worker_spec.rb @@ -53,6 +53,4 @@ describe NewMergeRequestWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/new_note_worker_spec.rb b/spec/workers/new_note_worker_spec.rb index d935a0ae3b4..575361c93d4 100644 --- a/spec/workers/new_note_worker_spec.rb +++ b/spec/workers/new_note_worker_spec.rb @@ -46,6 +46,4 @@ describe NewNoteWorker do described_class.new.perform(unexistent_note_id) end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/pipeline_hooks_worker_spec.rb b/spec/workers/pipeline_hooks_worker_spec.rb index 50b724d0111..035e329839f 100644 --- a/spec/workers/pipeline_hooks_worker_spec.rb +++ b/spec/workers/pipeline_hooks_worker_spec.rb @@ -20,6 +20,4 @@ describe PipelineHooksWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/pipeline_metrics_worker_spec.rb b/spec/workers/pipeline_metrics_worker_spec.rb index 69ad4ddea04..896f9e6e7f2 100644 --- a/spec/workers/pipeline_metrics_worker_spec.rb +++ b/spec/workers/pipeline_metrics_worker_spec.rb @@ -54,6 +54,4 @@ describe PipelineMetricsWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/pipeline_notification_worker_spec.rb b/spec/workers/pipeline_notification_worker_spec.rb index 072866bf375..eb539ffd893 100644 --- a/spec/workers/pipeline_notification_worker_spec.rb +++ b/spec/workers/pipeline_notification_worker_spec.rb @@ -16,6 +16,4 @@ describe PipelineNotificationWorker, :mailer do subject.perform(Ci::Pipeline.maximum(:id).to_i.succ) end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/pipeline_process_worker_spec.rb b/spec/workers/pipeline_process_worker_spec.rb index 81570c685ed..86e9d7f6684 100644 --- a/spec/workers/pipeline_process_worker_spec.rb +++ b/spec/workers/pipeline_process_worker_spec.rb @@ -19,6 +19,4 @@ describe PipelineProcessWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/pipeline_schedule_worker_spec.rb b/spec/workers/pipeline_schedule_worker_spec.rb index 4cea91a237c..75197039f5a 100644 --- a/spec/workers/pipeline_schedule_worker_spec.rb +++ b/spec/workers/pipeline_schedule_worker_spec.rb @@ -62,6 +62,4 @@ describe PipelineScheduleWorker do expect { subject }.not_to change { project.pipelines.count } end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/pipeline_success_worker_spec.rb b/spec/workers/pipeline_success_worker_spec.rb index 83d006337bd..d1c84adda6f 100644 --- a/spec/workers/pipeline_success_worker_spec.rb +++ b/spec/workers/pipeline_success_worker_spec.rb @@ -21,6 +21,4 @@ describe PipelineSuccessWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/pipeline_update_worker_spec.rb b/spec/workers/pipeline_update_worker_spec.rb index cd8ae030ab9..0b456cfd0da 100644 --- a/spec/workers/pipeline_update_worker_spec.rb +++ b/spec/workers/pipeline_update_worker_spec.rb @@ -19,6 +19,4 @@ describe PipelineUpdateWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb index 4968758cb6b..af6a3c9f6c7 100644 --- a/spec/workers/post_receive_spec.rb +++ b/spec/workers/post_receive_spec.rb @@ -140,6 +140,4 @@ describe PostReceive do described_class.new.perform(gl_repository, key_id, base64_changes) end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/process_commit_worker_spec.rb b/spec/workers/process_commit_worker_spec.rb index 0580ea60742..24f8ca67594 100644 --- a/spec/workers/process_commit_worker_spec.rb +++ b/spec/workers/process_commit_worker_spec.rb @@ -134,6 +134,4 @@ describe ProcessCommitWorker do expect(commit.authored_date).to be_an_instance_of(Time) end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/project_cache_worker_spec.rb b/spec/workers/project_cache_worker_spec.rb index 20d18a433d3..6b1f2ff3227 100644 --- a/spec/workers/project_cache_worker_spec.rb +++ b/spec/workers/project_cache_worker_spec.rb @@ -87,6 +87,4 @@ describe ProjectCacheWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/project_destroy_worker_spec.rb b/spec/workers/project_destroy_worker_spec.rb index 7c2a293c5f3..f19c9dff941 100644 --- a/spec/workers/project_destroy_worker_spec.rb +++ b/spec/workers/project_destroy_worker_spec.rb @@ -33,6 +33,4 @@ describe ProjectDestroyWorker do end.not_to raise_error end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/propagate_service_template_worker_spec.rb b/spec/workers/propagate_service_template_worker_spec.rb index 21df8eb489e..b8b65ead9b3 100644 --- a/spec/workers/propagate_service_template_worker_spec.rb +++ b/spec/workers/propagate_service_template_worker_spec.rb @@ -26,6 +26,4 @@ describe PropagateServiceTemplateWorker do subject.perform(service_template.id) end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/prune_old_events_worker_spec.rb b/spec/workers/prune_old_events_worker_spec.rb index e9b3061a1be..ea974355050 100644 --- a/spec/workers/prune_old_events_worker_spec.rb +++ b/spec/workers/prune_old_events_worker_spec.rb @@ -23,6 +23,4 @@ describe PruneOldEventsWorker do expect(exactly_12_months_event).to be_present end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/reactive_caching_worker_spec.rb b/spec/workers/reactive_caching_worker_spec.rb index 44aa520d102..5f4453c15d6 100644 --- a/spec/workers/reactive_caching_worker_spec.rb +++ b/spec/workers/reactive_caching_worker_spec.rb @@ -12,6 +12,4 @@ describe ReactiveCachingWorker do subject end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/remove_expired_group_links_worker_spec.rb b/spec/workers/remove_expired_group_links_worker_spec.rb index 2615b049650..689bc3d27b4 100644 --- a/spec/workers/remove_expired_group_links_worker_spec.rb +++ b/spec/workers/remove_expired_group_links_worker_spec.rb @@ -21,6 +21,4 @@ describe RemoveExpiredGroupLinksWorker do expect(non_expiring_project_group_link.reload).to be_present end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/remove_expired_members_worker_spec.rb b/spec/workers/remove_expired_members_worker_spec.rb index 1b0af031a83..058fdf4c009 100644 --- a/spec/workers/remove_expired_members_worker_spec.rb +++ b/spec/workers/remove_expired_members_worker_spec.rb @@ -55,6 +55,4 @@ describe RemoveExpiredMembersWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/remove_old_web_hook_logs_worker_spec.rb b/spec/workers/remove_old_web_hook_logs_worker_spec.rb index 4a504f34367..6d26ba5dfa0 100644 --- a/spec/workers/remove_old_web_hook_logs_worker_spec.rb +++ b/spec/workers/remove_old_web_hook_logs_worker_spec.rb @@ -15,6 +15,4 @@ describe RemoveOldWebHookLogsWorker do expect(WebHookLog.all).not_to include(week_old_record, three_days_old_record) end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb b/spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb index fccb64717ad..57f83c1dbe9 100644 --- a/spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb +++ b/spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb @@ -52,6 +52,4 @@ describe RemoveUnreferencedLfsObjectsWorker do expect(LfsObject.where(id: referenced_lfs_object2.id)).to be_empty end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/repository_fork_worker_spec.rb b/spec/workers/repository_fork_worker_spec.rb index 6550de6f893..d9e9409840f 100644 --- a/spec/workers/repository_fork_worker_spec.rb +++ b/spec/workers/repository_fork_worker_spec.rb @@ -69,6 +69,4 @@ describe RepositoryForkWorker do expect(project.reload.import_status).to eq('failed') end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/repository_import_worker_spec.rb b/spec/workers/repository_import_worker_spec.rb index d67891aa388..100dfc32bbe 100644 --- a/spec/workers/repository_import_worker_spec.rb +++ b/spec/workers/repository_import_worker_spec.rb @@ -43,6 +43,4 @@ describe RepositoryImportWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/schedule_update_user_activity_worker_spec.rb b/spec/workers/schedule_update_user_activity_worker_spec.rb index 362cd2a6d92..32c59381b01 100644 --- a/spec/workers/schedule_update_user_activity_worker_spec.rb +++ b/spec/workers/schedule_update_user_activity_worker_spec.rb @@ -22,6 +22,4 @@ describe ScheduleUpdateUserActivityWorker, :clean_gitlab_redis_shared_state do subject.perform(1) end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/stuck_ci_jobs_worker_spec.rb b/spec/workers/stuck_ci_jobs_worker_spec.rb index f64de2a9c21..549635f7f33 100644 --- a/spec/workers/stuck_ci_jobs_worker_spec.rb +++ b/spec/workers/stuck_ci_jobs_worker_spec.rb @@ -132,6 +132,4 @@ describe StuckCiJobsWorker do worker.perform end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/stuck_import_jobs_worker_spec.rb b/spec/workers/stuck_import_jobs_worker_spec.rb index 64a69fc4872..a82eb54ffe4 100644 --- a/spec/workers/stuck_import_jobs_worker_spec.rb +++ b/spec/workers/stuck_import_jobs_worker_spec.rb @@ -33,6 +33,4 @@ describe StuckImportJobsWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/stuck_merge_jobs_worker_spec.rb b/spec/workers/stuck_merge_jobs_worker_spec.rb index a989942f913..a5ad78393c9 100644 --- a/spec/workers/stuck_merge_jobs_worker_spec.rb +++ b/spec/workers/stuck_merge_jobs_worker_spec.rb @@ -47,6 +47,4 @@ describe StuckMergeJobsWorker do end end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/system_hook_push_worker_spec.rb b/spec/workers/system_hook_push_worker_spec.rb index e0588e2a1b3..b1d446ed25f 100644 --- a/spec/workers/system_hook_push_worker_spec.rb +++ b/spec/workers/system_hook_push_worker_spec.rb @@ -16,6 +16,4 @@ describe SystemHookPushWorker do subject.perform(push_data, :push_hooks) end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/trending_projects_worker_spec.rb b/spec/workers/trending_projects_worker_spec.rb index a9e0c9d1d77..c3c6fdcf2d5 100644 --- a/spec/workers/trending_projects_worker_spec.rb +++ b/spec/workers/trending_projects_worker_spec.rb @@ -8,6 +8,4 @@ describe TrendingProjectsWorker do described_class.new.perform end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/update_merge_requests_worker_spec.rb b/spec/workers/update_merge_requests_worker_spec.rb index f40c9012db9..558ff9109ec 100644 --- a/spec/workers/update_merge_requests_worker_spec.rb +++ b/spec/workers/update_merge_requests_worker_spec.rb @@ -24,6 +24,4 @@ describe UpdateMergeRequestsWorker do perform end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/update_user_activity_worker_spec.rb b/spec/workers/update_user_activity_worker_spec.rb index 9cd7ffc2ab4..268ca1d81f2 100644 --- a/spec/workers/update_user_activity_worker_spec.rb +++ b/spec/workers/update_user_activity_worker_spec.rb @@ -32,6 +32,4 @@ describe UpdateUserActivityWorker, :clean_gitlab_redis_shared_state do expect(Gitlab::UserActivities.new.to_a).to be_empty end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/upload_checksum_worker_spec.rb b/spec/workers/upload_checksum_worker_spec.rb index 735aeec1046..911360da66c 100644 --- a/spec/workers/upload_checksum_worker_spec.rb +++ b/spec/workers/upload_checksum_worker_spec.rb @@ -16,6 +16,4 @@ describe UploadChecksumWorker do expect(upload).to have_received(:save!) end end - - it_behaves_like 'sidekiq worker' end diff --git a/spec/workers/use_key_worker_spec.rb b/spec/workers/use_key_worker_spec.rb index c7de5bb6117..e50c788b82a 100644 --- a/spec/workers/use_key_worker_spec.rb +++ b/spec/workers/use_key_worker_spec.rb @@ -20,6 +20,4 @@ describe UseKeyWorker do expect(worker.perform(key.id + 1)).to eq false end end - - it_behaves_like 'sidekiq worker' end From 193b199672f5229dd6d2cff30fc8c794bb774bbd Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 22 Aug 2017 12:47:20 +0200 Subject: [PATCH 035/196] Add Sidekiq migration helpers for migrating queues --- lib/gitlab/database/migration_helpers.rb | 14 +++++ .../gitlab/database/migration_helpers_spec.rb | 51 +++++++++++++++++-- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb index b83e633c7ed..ecb23e79e80 100644 --- a/lib/gitlab/database/migration_helpers.rb +++ b/lib/gitlab/database/migration_helpers.rb @@ -611,6 +611,20 @@ module Gitlab remove_foreign_key(*args) rescue ArgumentError end + + def sidekiq_queue_migrate(queue_from, to: queue_to) + while sidekiq_queue_length(queue_from) > 0 + Sidekiq.redis do |conn| + conn.rpoplpush "queue:#{queue_from}", "queue:#{to}" + end + end + end + + def sidekiq_queue_length(queue_name) + Sidekiq.redis do |conn| + conn.llen("queue:#{queue_name}") + end + end end end end diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb index ec2274a70aa..fbbb07f2208 100644 --- a/spec/lib/gitlab/database/migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -2,9 +2,7 @@ require 'spec_helper' describe Gitlab::Database::MigrationHelpers do let(:model) do - ActiveRecord::Migration.new.extend( - described_class - ) + ActiveRecord::Migration.new.extend(described_class) end before do @@ -845,4 +843,51 @@ describe Gitlab::Database::MigrationHelpers do end end end + + describe 'sidekiq migration helpers', :sidekiq, :redis do + let(:worker) do + Class.new do + include Sidekiq::Worker + sidekiq_options queue: 'test' + end + end + + describe '#sidekiq_queue_length' do + context 'when queue is empty' do + it 'returns zero' do + Sidekiq::Testing.disable! do + expect(model.sidekiq_queue_length('test')).to eq 0 + end + end + end + + context 'when queue contains jobs' do + it 'returns correct size of the queue' do + Sidekiq::Testing.disable! do + worker.perform_async('Something', [1]) + worker.perform_async('Something', [2]) + + expect(model.sidekiq_queue_length('test')).to eq 2 + end + end + end + end + + describe '#migrate_sidekiq_queue' do + it 'migrates jobs from one sidekiq queue to another' do + Sidekiq::Testing.disable! do + worker.perform_async('Something', [1]) + worker.perform_async('Something', [2]) + + expect(model.sidekiq_queue_length('test')).to eq 2 + expect(model.sidekiq_queue_length('new_test')).to eq 0 + + model.sidekiq_queue_migrate('test', to: 'new_test') + + expect(model.sidekiq_queue_length('test')).to eq 0 + expect(model.sidekiq_queue_length('new_test')).to eq 2 + end + end + end + end end From 8b4a335ff1b0c7f4f575e63b6399889faec28456 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 22 Aug 2017 12:47:37 +0200 Subject: [PATCH 036/196] Add migration that migrates CI/CD queues --- ...170822101017_migrate_pipeline_sidekiq_queues.rb | 14 ++++++++++++++ db/schema.rb | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 db/post_migrate/20170822101017_migrate_pipeline_sidekiq_queues.rb diff --git a/db/post_migrate/20170822101017_migrate_pipeline_sidekiq_queues.rb b/db/post_migrate/20170822101017_migrate_pipeline_sidekiq_queues.rb new file mode 100644 index 00000000000..48fa3af0c60 --- /dev/null +++ b/db/post_migrate/20170822101017_migrate_pipeline_sidekiq_queues.rb @@ -0,0 +1,14 @@ +class MigratePipelineSidekiqQueues < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def up + sidekiq_queue_migrate 'build', to: 'pipeline_default' + sidekiq_queue_migrate 'pipeline', to: 'pipeline_default' + end + + def down + sidekiq_queue_migrate 'pipeline_default', to: 'pipeline' + end +end diff --git a/db/schema.rb b/db/schema.rb index 80f8cde1818..d22e8235a09 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: 20170820100558) do +ActiveRecord::Schema.define(version: 20170822101017) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" From a7c54a478e6809eb754119b492250c8c1b2f4512 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 22 Aug 2017 13:02:24 +0200 Subject: [PATCH 037/196] Add specs for pipeline sidekiq queues migration --- .../migrate_pipeline_sidekiq_queues_spec.rb | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 spec/migrations/migrate_pipeline_sidekiq_queues_spec.rb diff --git a/spec/migrations/migrate_pipeline_sidekiq_queues_spec.rb b/spec/migrations/migrate_pipeline_sidekiq_queues_spec.rb new file mode 100644 index 00000000000..fff531a78c5 --- /dev/null +++ b/spec/migrations/migrate_pipeline_sidekiq_queues_spec.rb @@ -0,0 +1,50 @@ +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20170822101017_migrate_pipeline_sidekiq_queues.rb') + +describe MigratePipelineSidekiqQueues, :sidekiq, :redis do + include Gitlab::Database::MigrationHelpers + + context 'when there are jobs in the queues' do + it 'correctly migrates queue when migrating up' do + Sidekiq::Testing.disable! do + stubbed_worker(queue: :pipeline).perform_async('Something', [1]) + stubbed_worker(queue: :build).perform_async('Something', [1]) + + described_class.new.up + + expect(sidekiq_queue_length('pipeline')).to eq 0 + expect(sidekiq_queue_length('build')).to eq 0 + expect(sidekiq_queue_length('pipeline_default')).to eq 2 + end + end + + it 'correctly migrates queue when migrating down' do + Sidekiq::Testing.disable! do + stubbed_worker(queue: :pipeline_default).perform_async('Class', [1]) + stubbed_worker(queue: :pipeline_default).perform_async('Class', [2]) + + described_class.new.down + + expect(sidekiq_queue_length('pipeline')).to eq 2 + expect(sidekiq_queue_length('pipeline_default')).to eq 0 + end + end + end + + context 'when there are no jobs in the queues' do + it 'does not raise error when migrating up' do + expect { described_class.new.up }.not_to raise_error + end + + it 'does not raise error when migrating down' do + expect { described_class.new.down }.not_to raise_error + end + end + + def stubbed_worker(queue:) + Class.new do + include Sidekiq::Worker + sidekiq_options queue: queue + end + end +end From 37881ebb75be2069f49f6faf6e01ca73223e998f Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 22 Aug 2017 14:04:34 +0200 Subject: [PATCH 038/196] Set a default CI/CD status when it is not known --- app/models/ci/stage.rb | 4 ++++ spec/models/ci/stage_spec.rb | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/app/models/ci/stage.rb b/app/models/ci/stage.rb index 4ee972fa68d..754c37518b3 100644 --- a/app/models/ci/stage.rb +++ b/app/models/ci/stage.rb @@ -17,6 +17,10 @@ module Ci validates :pipeline, presence: true, unless: :importing? validates :name, presence: true, unless: :importing? + after_initialize do |stage| + self.status = DEFAULT_STATUS if self.status.nil? + end + state_machine :status, initial: :created do event :enqueue do transition created: :pending diff --git a/spec/models/ci/stage_spec.rb b/spec/models/ci/stage_spec.rb index 74c9d6145e2..586d073eb5e 100644 --- a/spec/models/ci/stage_spec.rb +++ b/spec/models/ci/stage_spec.rb @@ -38,6 +38,17 @@ describe Ci::Stage, :models do expect(stage.status).to eq 'success' end end + + context 'when stage status is not defined' do + before do + stage.update_column(:status, nil) + end + + it 'sets the default value' do + expect(described_class.find(stage.id).status) + .to eq 'created' + end + end end describe 'update_status' do From 3366e38cc1632eba4c9e8683555c6fde6efd5d48 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 22 Aug 2017 14:57:54 +0200 Subject: [PATCH 039/196] Fix indentation in migration helpers --- .../gitlab/database/migration_helpers_spec.rb | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb index fbbb07f2208..c25fd459dd7 100644 --- a/spec/lib/gitlab/database/migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -875,18 +875,18 @@ describe Gitlab::Database::MigrationHelpers do describe '#migrate_sidekiq_queue' do it 'migrates jobs from one sidekiq queue to another' do - Sidekiq::Testing.disable! do - worker.perform_async('Something', [1]) - worker.perform_async('Something', [2]) + Sidekiq::Testing.disable! do + worker.perform_async('Something', [1]) + worker.perform_async('Something', [2]) - expect(model.sidekiq_queue_length('test')).to eq 2 - expect(model.sidekiq_queue_length('new_test')).to eq 0 + expect(model.sidekiq_queue_length('test')).to eq 2 + expect(model.sidekiq_queue_length('new_test')).to eq 0 - model.sidekiq_queue_migrate('test', to: 'new_test') + model.sidekiq_queue_migrate('test', to: 'new_test') - expect(model.sidekiq_queue_length('test')).to eq 0 - expect(model.sidekiq_queue_length('new_test')).to eq 2 - end + expect(model.sidekiq_queue_length('test')).to eq 0 + expect(model.sidekiq_queue_length('new_test')).to eq 2 + end end end end From a61f8c44bef6d3b8ad19b7791740960b4fd9a938 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 22 Aug 2017 14:59:16 +0200 Subject: [PATCH 040/196] Enqueue a new stage worker in CI/CD processing queue --- app/workers/stage_update_worker.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/workers/stage_update_worker.rb b/app/workers/stage_update_worker.rb index eef0b11e70b..c301cea5ad6 100644 --- a/app/workers/stage_update_worker.rb +++ b/app/workers/stage_update_worker.rb @@ -2,6 +2,8 @@ class StageUpdateWorker include Sidekiq::Worker include PipelineQueue + enqueue_in group: :processing + def perform(stage_id) Ci::Stage.find_by(id: stage_id).try do |stage| stage.update_status From b0f09406f50882c7e085c2a9b853be5dcf3d79dd Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Tue, 22 Aug 2017 14:04:54 +0100 Subject: [PATCH 041/196] Always return a simple diff viewer We didn't have a fallback case before, because we believed the conditions were exhaustive. They weren't, so we can always fallback to not previewing. --- lib/gitlab/diff/file.rb | 2 ++ spec/lib/gitlab/diff/file_spec.rb | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/lib/gitlab/diff/file.rb b/lib/gitlab/diff/file.rb index 6d7de52cb80..17a9ec01637 100644 --- a/lib/gitlab/diff/file.rb +++ b/lib/gitlab/diff/file.rb @@ -250,6 +250,8 @@ module Gitlab DiffViewer::Renamed elsif mode_changed? DiffViewer::ModeChanged + else + DiffViewer::NoPreview end end diff --git a/spec/lib/gitlab/diff/file_spec.rb b/spec/lib/gitlab/diff/file_spec.rb index d3d841b0668..ab60d62d88e 100644 --- a/spec/lib/gitlab/diff/file_spec.rb +++ b/spec/lib/gitlab/diff/file_spec.rb @@ -270,6 +270,20 @@ describe Gitlab::Diff::File do expect(diff_file.simple_viewer).to be_a(DiffViewer::ModeChanged) end end + + context 'when no other conditions apply' do + before do + allow(diff_file).to receive(:content_changed?).and_return(false) + allow(diff_file).to receive(:new_file?).and_return(false) + allow(diff_file).to receive(:deleted_file?).and_return(false) + allow(diff_file).to receive(:renamed_file?).and_return(false) + allow(diff_file).to receive(:mode_changed?).and_return(false) + end + + it 'returns a No Preview viewer' do + expect(diff_file.simple_viewer).to be_a(DiffViewer::NoPreview) + end + end end describe '#rich_viewer' do From dacca321af806c4955dd32d6402cb38044fa2b00 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Tue, 22 Aug 2017 14:36:17 +0100 Subject: [PATCH 042/196] Update the rbnacl gem to 4.0.2 --- Gemfile | 2 +- Gemfile.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index a0a9dddac10..df50b61e6fb 100644 --- a/Gemfile +++ b/Gemfile @@ -396,7 +396,7 @@ gem 'net-ssh', '~> 4.1.0' # Required for ED25519 SSH host key support group :ed25519 do gem 'rbnacl-libsodium' - gem 'rbnacl', '~> 3.2' + gem 'rbnacl', '~> 4.0' gem 'bcrypt_pbkdf', '~> 1.0' end diff --git a/Gemfile.lock b/Gemfile.lock index ec8349cd1df..f4f6b630a76 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -203,7 +203,7 @@ GEM multi_json fast_gettext (1.4.0) ffaker (2.4.0) - ffi (1.9.10) + ffi (1.9.18) flay (2.8.1) erubis (~> 2.7.0) path_expander (~> 1.0) @@ -682,7 +682,7 @@ GEM rake (12.0.0) rblineprof (0.3.6) debugger-ruby_core_source (~> 1.3) - rbnacl (3.4.0) + rbnacl (4.0.2) ffi rbnacl-libsodium (1.0.11) rbnacl (>= 3.0.1) @@ -1107,7 +1107,7 @@ DEPENDENCIES rainbow (~> 2.2) raindrops (~> 0.18) rblineprof (~> 0.3.6) - rbnacl (~> 3.2) + rbnacl (~> 4.0) rbnacl-libsodium rdoc (~> 4.2) re2 (~> 1.1.1) From 77c01b22d7e21cf20592e3d6d6f05a7beefc118c Mon Sep 17 00:00:00 2001 From: "http://jneen.net/" Date: Tue, 22 Aug 2017 08:39:31 -0700 Subject: [PATCH 043/196] add a description to the changelog --- changelogs/unreleased/bugfix-notify-custom-participants.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/unreleased/bugfix-notify-custom-participants.yml b/changelogs/unreleased/bugfix-notify-custom-participants.yml index 32ba1076b09..04fcb95e18a 100644 --- a/changelogs/unreleased/bugfix-notify-custom-participants.yml +++ b/changelogs/unreleased/bugfix-notify-custom-participants.yml @@ -1,5 +1,5 @@ --- -title: 13680-notify-custom-participants +title: Fixed: Notifications weren't sending to participating users with a `Custom` notification setting. merge_request: 13680 author: jneen type: fixed From b4aaced71a65faffd49ffa2c705fb574ed532701 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Mon, 21 Aug 2017 17:27:06 +0200 Subject: [PATCH 044/196] Fix display of push events for removed refs This changes the style of push events that remove tags or branches so they don't display the commit details. This prevents displaying commit details such as: 000000 . --broken encoding Instead we now simply display the header such as: Administrator deleted branch example-branch This is displayed in the same style as events for newly created branches/tags. This commit also ensures that if no commit message is present we simply don't display anything, instead of "--broken encoding". Fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/36685 Fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/36722 --- app/helpers/events_helper.rb | 1 + app/models/event.rb | 2 +- app/views/events/_event_push.atom.haml | 13 +++--- app/views/events/event/_push.html.haml | 4 -- .../fix-push-events-branch-removals.yml | 5 +++ spec/helpers/events_helper_spec.rb | 4 ++ spec/models/event_spec.rb | 44 +++++++++++++++++++ 7 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 changelogs/unreleased/fix-push-events-branch-removals.yml diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index c6f98e7e782..b331693c789 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -181,6 +181,7 @@ module EventsHelper end def event_commit_title(message) + message ||= '' (message.split("\n").first || "").truncate(70) rescue "--broken encoding" diff --git a/app/models/event.rb b/app/models/event.rb index 15ee170ca75..996768a267b 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -406,7 +406,7 @@ class Event < ActiveRecord::Base def body? if push? - push_with_commits? || rm_ref? + push_with_commits? elsif note? true else diff --git a/app/views/events/_event_push.atom.haml b/app/views/events/_event_push.atom.haml index bf655f9d21a..e3c5fd55f08 100644 --- a/app/views/events/_event_push.atom.haml +++ b/app/views/events/_event_push.atom.haml @@ -5,9 +5,10 @@ %i at = event.created_at.to_s(:short) - %blockquote= markdown(escape_once(event.commit_title), pipeline: :atom, project: event.project, author: event.author) - - if event.commits_count > 1 - %p - %i - \... and - = pluralize(event.commits_count - 1, "more commit") + - unless event.rm_ref? + %blockquote= markdown(escape_once(event.commit_title), pipeline: :atom, project: event.project, author: event.author) + - if event.commits_count > 1 + %p + %i + \... and + = pluralize(event.commits_count - 1, "more commit") diff --git a/app/views/events/event/_push.html.haml b/app/views/events/event/_push.html.haml index 973c652ad88..53ebdd6d2ff 100644 --- a/app/views/events/event/_push.html.haml +++ b/app/views/events/event/_push.html.haml @@ -41,7 +41,3 @@ %li.commits-stat = link_to create_mr_path(project.default_branch, event.ref_name, project) do Create Merge Request -- elsif event.rm_ref? - .event-body - %ul.well-list.event_commits - = render "events/commit", project: project, event: event diff --git a/changelogs/unreleased/fix-push-events-branch-removals.yml b/changelogs/unreleased/fix-push-events-branch-removals.yml new file mode 100644 index 00000000000..71f368db296 --- /dev/null +++ b/changelogs/unreleased/fix-push-events-branch-removals.yml @@ -0,0 +1,5 @@ +--- +title: Fix display of push events for removed refs +merge_request: +author: +type: fixed diff --git a/spec/helpers/events_helper_spec.rb b/spec/helpers/events_helper_spec.rb index 4b72dbb7964..d5536fcb22b 100644 --- a/spec/helpers/events_helper_spec.rb +++ b/spec/helpers/events_helper_spec.rb @@ -106,5 +106,9 @@ describe EventsHelper do it "handles empty strings" do expect(helper.event_commit_title("")).to eq("") end + + it 'handles nil values' do + expect(helper.event_commit_title(nil)).to eq('') + end end end diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index ff3224dd298..f55c161c821 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -304,6 +304,50 @@ describe Event do end end + describe '#body?' do + let(:push_event) do + event = build(:push_event) + + allow(event).to receive(:push?).and_return(true) + + event + end + + it 'returns true for a push event with commits' do + allow(push_event).to receive(:push_with_commits?).and_return(true) + + expect(push_event).to be_body + end + + it 'returns false for a push event without a valid commit range' do + allow(push_event).to receive(:push_with_commits?).and_return(false) + + expect(push_event).not_to be_body + end + + it 'returns true for a Note event' do + event = build(:event) + + allow(event).to receive(:note?).and_return(true) + + expect(event).to be_body + end + + it 'returns true if the target responds to #title' do + event = build(:event) + + allow(event).to receive(:target).and_return(double(:target, title: 'foo')) + + expect(event).to be_body + end + + it 'returns false for a regular event without a target' do + event = build(:event) + + expect(event).not_to be_body + end + end + def create_push_event(project, user) event = create(:push_event, project: project, author: user) From 258d5a50e63d5e29b6a3adc0a250727a8232695b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Rodr=C3=ADguez?= Date: Wed, 9 Aug 2017 17:47:11 -0400 Subject: [PATCH 045/196] Incorporate DiffService.CommitPatch Gitaly RPC --- GITALY_SERVER_VERSION | 2 +- Gemfile | 2 +- Gemfile.lock | 4 +-- lib/gitlab/git/commit.rb | 8 +++++- lib/gitlab/gitaly_client/commit_service.rb | 10 ++++++++ .../gitaly_client/commit_service_spec.rb | 25 +++++++++++++++++++ 6 files changed, 46 insertions(+), 5 deletions(-) diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 9eb2aa3f109..be386c9ede3 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -0.32.0 +0.33.0 diff --git a/Gemfile b/Gemfile index 6c8f64bfded..280065497f1 100644 --- a/Gemfile +++ b/Gemfile @@ -401,7 +401,7 @@ group :ed25519 do end # Gitaly GRPC client -gem 'gitaly', '~> 0.29.0' +gem 'gitaly', '~> 0.30.0' gem 'toml-rb', '~> 0.3.15', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 5118f9764d5..1674ad5e5df 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -275,7 +275,7 @@ GEM po_to_json (>= 1.0.0) rails (>= 3.2.0) gherkin-ruby (0.3.2) - gitaly (0.29.0) + gitaly (0.30.0) google-protobuf (~> 3.1) grpc (~> 1.0) github-linguist (4.7.6) @@ -1019,7 +1019,7 @@ DEPENDENCIES gettext (~> 3.2.2) gettext_i18n_rails (~> 1.8.0) gettext_i18n_rails_js (~> 1.2.0) - gitaly (~> 0.29.0) + gitaly (~> 0.30.0) github-linguist (~> 4.7.0) gitlab-flowdock-git-hook (~> 1.0.1) gitlab-markup (~> 1.5.1) diff --git a/lib/gitlab/git/commit.rb b/lib/gitlab/git/commit.rb index a499bbc6266..5ee6669050c 100644 --- a/lib/gitlab/git/commit.rb +++ b/lib/gitlab/git/commit.rb @@ -271,7 +271,13 @@ module Gitlab # # Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/324 def to_diff - rugged_diff_from_parent.patch + Gitlab::GitalyClient.migrate(:commit_patch) do |is_enabled| + if is_enabled + @repository.gitaly_commit_client.patch(id) + else + rugged_diff_from_parent.patch + end + end end # Returns a diff object for the changes from this commit's first parent. diff --git a/lib/gitlab/gitaly_client/commit_service.rb b/lib/gitlab/gitaly_client/commit_service.rb index b36e81278d6..2a984b97e92 100644 --- a/lib/gitlab/gitaly_client/commit_service.rb +++ b/lib/gitlab/gitaly_client/commit_service.rb @@ -194,6 +194,16 @@ module Gitlab response.commit end + def patch(revision) + request = Gitaly::CommitPatchRequest.new( + repository: @gitaly_repo, + revision: GitalyClient.encode(revision) + ) + response = GitalyClient.call(@repository.storage, :diff_service, :commit_patch, request) + + response.sum(&:data) + end + private def commit_diff_request_params(commit, options = {}) diff --git a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb index 7fe698fcb18..c8d5f3a08a1 100644 --- a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb +++ b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb @@ -126,4 +126,29 @@ describe Gitlab::GitalyClient::CommitService do described_class.new(repository).find_commit(revision) end end + + describe '#patch' do + let(:request) do + Gitaly::CommitPatchRequest.new( + repository: repository_message, revision: revision + ) + end + let(:response) { [double(data: "my "), double(data: "diff")] } + + subject { described_class.new(repository).patch(revision) } + + it 'sends an RPC request' do + expect_any_instance_of(Gitaly::DiffService::Stub).to receive(:commit_patch) + .with(request, kind_of(Hash)).and_return([]) + + subject + end + + it 'concatenates the responses data' do + allow_any_instance_of(Gitaly::DiffService::Stub).to receive(:commit_patch) + .with(request, kind_of(Hash)).and_return(response) + + expect(subject).to eq("my diff") + end + end end From ee22930044a997d112edf5f725096d73f3d29749 Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Tue, 22 Aug 2017 16:41:17 -0500 Subject: [PATCH 046/196] Remove tooltip from filtered search user --- app/helpers/avatars_helper.rb | 11 ++++- .../issuable/_user_dropdown_item.html.haml | 2 +- spec/helpers/avatars_helper_spec.rb | 42 ++++++++++++++++--- 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/app/helpers/avatars_helper.rb b/app/helpers/avatars_helper.rb index 4b51269533c..a4c226a6aad 100644 --- a/app/helpers/avatars_helper.rb +++ b/app/helpers/avatars_helper.rb @@ -12,11 +12,18 @@ module AvatarsHelper avatar_size = options[:size] || 16 user_name = options[:user].try(:name) || options[:user_name] avatar_url = options[:url] || avatar_icon(options[:user] || options[:user_email], avatar_size) - data_attributes = { container: 'body' } + has_tooltip = options[:has_tooltip].nil? ? true : options[:has_tooltip] + data_attributes = {} + css_class = %W[avatar s#{avatar_size}].push(*options[:css_class]) + + if has_tooltip + css_class.push('has-tooltip') + data_attributes = { container: 'body' } + end image_tag( avatar_url, - class: %W[avatar has-tooltip s#{avatar_size}].push(*options[:css_class]), + class: css_class, alt: "#{user_name}'s avatar", title: user_name, data: data_attributes, diff --git a/app/views/shared/issuable/_user_dropdown_item.html.haml b/app/views/shared/issuable/_user_dropdown_item.html.haml index c18e4975bb8..48d04678d47 100644 --- a/app/views/shared/issuable/_user_dropdown_item.html.haml +++ b/app/views/shared/issuable/_user_dropdown_item.html.haml @@ -4,7 +4,7 @@ %li.filter-dropdown-item{ class: ('js-current-user' if user == current_user) } %button.btn.btn-link.dropdown-user{ type: :button } .avatar-container.s40 - = user_avatar_without_link(user: user, lazy: avatar[:lazy], url: avatar[:url], size: 40).gsub('/images/{{avatar_url}}','{{avatar_url}}').html_safe + = user_avatar_without_link(user: user, lazy: avatar[:lazy], url: avatar[:url], size: 40, has_tooltip: false).gsub('/images/{{avatar_url}}','{{avatar_url}}').html_safe .dropdown-user-details %span = user.name diff --git a/spec/helpers/avatars_helper_spec.rb b/spec/helpers/avatars_helper_spec.rb index d16fcf21e45..4632c679972 100644 --- a/spec/helpers/avatars_helper_spec.rb +++ b/spec/helpers/avatars_helper_spec.rb @@ -28,7 +28,7 @@ describe AvatarsHelper do it 'displays user avatar' do is_expected.to eq image_tag( LazyImageTagHelper.placeholder_image, - class: 'avatar has-tooltip s16 lazy', + class: 'avatar s16 has-tooltip lazy', alt: "#{user.name}'s avatar", title: user.name, data: { container: 'body', src: avatar_icon(user, 16) } @@ -41,7 +41,7 @@ describe AvatarsHelper do it 'uses provided css_class' do is_expected.to eq image_tag( LazyImageTagHelper.placeholder_image, - class: "avatar has-tooltip s16 #{options[:css_class]} lazy", + class: "avatar s16 #{options[:css_class]} has-tooltip lazy", alt: "#{user.name}'s avatar", title: user.name, data: { container: 'body', src: avatar_icon(user, 16) } @@ -55,7 +55,7 @@ describe AvatarsHelper do it 'uses provided size' do is_expected.to eq image_tag( LazyImageTagHelper.placeholder_image, - class: "avatar has-tooltip s#{options[:size]} lazy", + class: "avatar s#{options[:size]} has-tooltip lazy", alt: "#{user.name}'s avatar", title: user.name, data: { container: 'body', src: avatar_icon(user, options[:size]) } @@ -69,7 +69,7 @@ describe AvatarsHelper do it 'uses provided url' do is_expected.to eq image_tag( LazyImageTagHelper.placeholder_image, - class: 'avatar has-tooltip s16 lazy', + class: 'avatar s16 has-tooltip lazy', alt: "#{user.name}'s avatar", title: user.name, data: { container: 'body', src: options[:url] } @@ -77,6 +77,36 @@ describe AvatarsHelper do end end + context 'with has_tooltip parameter' do + context 'with has_tooltip set to true' do + let(:options) { { user: user, has_tooltip: true } } + + it 'adds has-tooltip' do + is_expected.to eq image_tag( + LazyImageTagHelper.placeholder_image, + class: 'avatar s16 has-tooltip lazy', + alt: "#{user.name}'s avatar", + title: user.name, + data: { container: 'body', src: avatar_icon(user, 16) } + ) + end + end + + context 'with has_tooltip set to false' do + let(:options) { { user: user, has_tooltip: false } } + + it 'does not add has-tooltip or data container' do + is_expected.to eq image_tag( + LazyImageTagHelper.placeholder_image, + class: 'avatar s16 lazy', + alt: "#{user.name}'s avatar", + title: user.name, + data: { src: avatar_icon(user, 16) } + ) + end + end + end + context 'with user_name parameter' do let(:options) { { user_name: 'Tinky Winky', user_email: 'no@f.un' } } @@ -86,7 +116,7 @@ describe AvatarsHelper do it 'prefers user parameter' do is_expected.to eq image_tag( LazyImageTagHelper.placeholder_image, - class: 'avatar has-tooltip s16 lazy', + class: 'avatar s16 has-tooltip lazy', alt: "#{user.name}'s avatar", title: user.name, data: { container: 'body', src: avatar_icon(user, 16) } @@ -97,7 +127,7 @@ describe AvatarsHelper do it 'uses user_name and user_email parameter if user is not present' do is_expected.to eq image_tag( LazyImageTagHelper.placeholder_image, - class: 'avatar has-tooltip s16 lazy', + class: 'avatar s16 has-tooltip lazy', alt: "#{options[:user_name]}'s avatar", title: options[:user_name], data: { container: 'body', src: avatar_icon(options[:user_email], 16) } From da4c54e4fb81d5d93d63e4f472a4dcb1e4ff9521 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Wed, 23 Aug 2017 08:32:44 +0200 Subject: [PATCH 047/196] Run job hooks after transation commits after create --- app/models/ci/build.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 936e3c83dfd..095192e9894 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -47,7 +47,7 @@ module Ci before_destroy { unscoped_project } after_create do |build| - BuildHooksWorker.perform_async(build.id) + run_after_commit { BuildHooksWorker.perform_async(build.id) } end after_commit :update_project_statistics_after_save, on: [:create, :update] From faf92651aa5e9c6bcb88acac8de27c878d7edf06 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Wed, 23 Aug 2017 08:58:55 +0200 Subject: [PATCH 048/196] Fix invalid default argument in migration helpers --- lib/gitlab/database/migration_helpers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb index ecb23e79e80..5e2c6cc5cad 100644 --- a/lib/gitlab/database/migration_helpers.rb +++ b/lib/gitlab/database/migration_helpers.rb @@ -612,7 +612,7 @@ module Gitlab rescue ArgumentError end - def sidekiq_queue_migrate(queue_from, to: queue_to) + def sidekiq_queue_migrate(queue_from, to:) while sidekiq_queue_length(queue_from) > 0 Sidekiq.redis do |conn| conn.rpoplpush "queue:#{queue_from}", "queue:#{to}" From b0d7918a6773fb7f1696f8077ba812bea23c0983 Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Wed, 23 Aug 2017 08:17:20 +0000 Subject: [PATCH 049/196] Update README.md --- doc/ci/yaml/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 1869782fe6e..abf4ec7dbf8 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -1065,6 +1065,8 @@ a list of all previous jobs from which the artifacts should be downloaded. You can only define jobs from stages that are executed before the current one. An error will be shown if you define jobs from the current stage or next ones. Defining an empty array will skip downloading any artifacts for that job. +The status of the previous job is not considered when using `dependencies`, so +if it failed or it is a manual job that was not run, no error occurs. --- From 9b9309329207449ef022bdcf06bff5f8eae36032 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Tue, 22 Aug 2017 13:05:36 +0200 Subject: [PATCH 050/196] Decouple GitOperationService from User --- app/models/repository.rb | 27 ++++++++++++++++++--------- app/services/git_hooks_service.rb | 6 +++--- app/services/git_operation_service.rb | 11 +++++++---- lib/gitlab/git/committer.rb | 21 +++++++++++++++++++++ spec/models/repository_spec.rb | 21 +++++++++++---------- 5 files changed, 60 insertions(+), 26 deletions(-) create mode 100644 lib/gitlab/git/committer.rb diff --git a/app/models/repository.rb b/app/models/repository.rb index c1e4fcf94a4..3c5074e5157 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -164,7 +164,8 @@ class Repository return false unless newrev - GitOperationService.new(user, self).add_branch(branch_name, newrev) + committer = Gitlab::Git::Committer.from_user(user) + GitOperationService.new(committer, self).add_branch(branch_name, newrev) after_create_branch find_branch(branch_name) @@ -176,7 +177,8 @@ class Repository return false unless newrev - GitOperationService.new(user, self).add_tag(tag_name, newrev, options) + committer = Gitlab::Git::Committer.from_user(user) + GitOperationService.new(committer, self).add_tag(tag_name, newrev, options) find_tag(tag_name) end @@ -185,7 +187,8 @@ class Repository before_remove_branch branch = find_branch(branch_name) - GitOperationService.new(user, self).rm_branch(branch) + committer = Gitlab::Git::Committer.from_user(user) + GitOperationService.new(committer, self).rm_branch(branch) after_remove_branch true @@ -195,7 +198,8 @@ class Repository before_remove_tag tag = find_tag(tag_name) - GitOperationService.new(user, self).rm_tag(tag) + committer = Gitlab::Git::Committer.from_user(user) + GitOperationService.new(committer, self).rm_tag(tag) after_remove_tag true @@ -763,7 +767,8 @@ class Repository author_email: nil, author_name: nil, start_branch_name: nil, start_project: project) - GitOperationService.new(user, self).with_branch( + committer = Gitlab::Git::Committer.from_user(user) + GitOperationService.new(committer, self).with_branch( branch_name, start_branch_name: start_branch_name, start_project: start_project) do |start_commit| @@ -819,7 +824,8 @@ class Repository end def merge(user, source, merge_request, options = {}) - GitOperationService.new(user, self).with_branch( + committer = Gitlab::Git::Committer.from_user(user) + GitOperationService.new(committer, self).with_branch( merge_request.target_branch) do |start_commit| our_commit = start_commit.sha their_commit = source @@ -846,7 +852,8 @@ class Repository def revert( user, commit, branch_name, start_branch_name: nil, start_project: project) - GitOperationService.new(user, self).with_branch( + committer = Gitlab::Git::Committer.from_user(user) + GitOperationService.new(committer, self).with_branch( branch_name, start_branch_name: start_branch_name, start_project: start_project) do |start_commit| @@ -869,7 +876,8 @@ class Repository def cherry_pick( user, commit, branch_name, start_branch_name: nil, start_project: project) - GitOperationService.new(user, self).with_branch( + committer = Gitlab::Git::Committer.from_user(user) + GitOperationService.new(committer, self).with_branch( branch_name, start_branch_name: start_branch_name, start_project: start_project) do |start_commit| @@ -894,7 +902,8 @@ class Repository end def resolve_conflicts(user, branch_name, params) - GitOperationService.new(user, self).with_branch(branch_name) do + committer = Gitlab::Git::Committer.from_user(user) + GitOperationService.new(committer, self).with_branch(branch_name) do committer = user_to_committer(user) create_commit(params.merge(author: committer, committer: committer)) diff --git a/app/services/git_hooks_service.rb b/app/services/git_hooks_service.rb index eab65d09299..e85007c26e0 100644 --- a/app/services/git_hooks_service.rb +++ b/app/services/git_hooks_service.rb @@ -3,9 +3,9 @@ class GitHooksService attr_accessor :oldrev, :newrev, :ref - def execute(user, project, oldrev, newrev, ref) + def execute(committer, project, oldrev, newrev, ref) @project = project - @user = Gitlab::GlId.gl_id(user) + @gl_id = committer.gl_id @oldrev = oldrev @newrev = newrev @ref = ref @@ -27,6 +27,6 @@ class GitHooksService def run_hook(name) hook = Gitlab::Git::Hook.new(name, @project) - hook.trigger(@user, oldrev, newrev, ref) + hook.trigger(@gl_id, oldrev, newrev, ref) end end diff --git a/app/services/git_operation_service.rb b/app/services/git_operation_service.rb index 545ca0742e4..f7fce3d8a5d 100644 --- a/app/services/git_operation_service.rb +++ b/app/services/git_operation_service.rb @@ -1,8 +1,11 @@ class GitOperationService - attr_reader :user, :repository + attr_reader :committer, :repository - def initialize(new_user, new_repository) - @user = new_user + def initialize(committer, new_repository) + if committer && !committer.is_a?(Gitlab::Git::Committer) + raise "expected Gitlab::Git::Committer, got #{committer.inspect}" + end + @committer = committer @repository = new_repository end @@ -119,7 +122,7 @@ class GitOperationService def with_hooks(ref, newrev, oldrev) GitHooksService.new.execute( - user, + committer, repository.project, oldrev, newrev, diff --git a/lib/gitlab/git/committer.rb b/lib/gitlab/git/committer.rb new file mode 100644 index 00000000000..ef3576eaa1c --- /dev/null +++ b/lib/gitlab/git/committer.rb @@ -0,0 +1,21 @@ +module Gitlab + module Git + class Committer + attr_reader :name, :email, :gl_id + + def self.from_user(user) + new(user.name, user.email, Gitlab::GlId.gl_id(user)) + end + + def initialize(name, email, gl_id) + @name = name + @email = email + @gl_id = gl_id + end + + def ==(other) + [name, email, gl_id] == [other.name, other.email, other.gl_id] + end + end + end +end diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 4926d5d6c49..0b1a35d1920 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -8,6 +8,7 @@ describe Repository, models: true do let(:repository) { project.repository } let(:broken_repository) { create(:project, :broken_storage).repository } let(:user) { create(:user) } + let(:committer) { Gitlab::Git::Committer.from_user(user) } let(:commit_options) do author = repository.user_to_committer(user) @@ -885,7 +886,7 @@ describe Repository, models: true do context 'when pre hooks were successful' do it 'runs without errors' do expect_any_instance_of(GitHooksService).to receive(:execute) - .with(user, project, old_rev, blank_sha, 'refs/heads/feature') + .with(committer, project, old_rev, blank_sha, 'refs/heads/feature') expect { repository.rm_branch(user, 'feature') }.not_to raise_error end @@ -928,20 +929,20 @@ describe Repository, models: true do service = GitHooksService.new expect(GitHooksService).to receive(:new).and_return(service) expect(service).to receive(:execute) - .with(user, project, old_rev, new_rev, 'refs/heads/feature') + .with(committer, project, old_rev, new_rev, 'refs/heads/feature') .and_yield(service).and_return(true) end it 'runs without errors' do expect do - GitOperationService.new(user, repository).with_branch('feature') do + GitOperationService.new(committer, repository).with_branch('feature') do new_rev end end.not_to raise_error end it 'ensures the autocrlf Git option is set to :input' do - service = GitOperationService.new(user, repository) + service = GitOperationService.new(committer, repository) expect(service).to receive(:update_autocrlf_option) @@ -952,7 +953,7 @@ describe Repository, models: true do it 'updates the head' do expect(repository.find_branch('feature').dereferenced_target.id).to eq(old_rev) - GitOperationService.new(user, repository).with_branch('feature') do + GitOperationService.new(committer, repository).with_branch('feature') do new_rev end @@ -974,7 +975,7 @@ describe Repository, models: true do end expect do - GitOperationService.new(user, target_project.repository) + GitOperationService.new(committer, target_project.repository) .with_branch('feature', start_project: project, &:itself) @@ -996,7 +997,7 @@ describe Repository, models: true do repository.add_branch(user, branch, old_rev) expect do - GitOperationService.new(user, repository).with_branch(branch) do + GitOperationService.new(committer, repository).with_branch(branch) do new_rev end end.not_to raise_error @@ -1014,7 +1015,7 @@ describe Repository, models: true do # Updating 'master' to new_rev would lose the commits on 'master' that # are not contained in new_rev. This should not be allowed. expect do - GitOperationService.new(user, repository).with_branch(branch) do + GitOperationService.new(committer, repository).with_branch(branch) do new_rev end end.to raise_error(Repository::CommitError) @@ -1026,7 +1027,7 @@ describe Repository, models: true do allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return([false, '']) expect do - GitOperationService.new(user, repository).with_branch('feature') do + GitOperationService.new(committer, repository).with_branch('feature') do new_rev end end.to raise_error(GitHooksService::PreReceiveError) @@ -1044,7 +1045,7 @@ describe Repository, models: true do expect(repository).not_to receive(:expire_emptiness_caches) expect(repository).to receive(:expire_branches_cache) - GitOperationService.new(user, repository) + GitOperationService.new(committer, repository) .with_branch('new-feature') do new_rev end From 65f83941c39c14c2af9da5064393545ea2f7b3e5 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Tue, 22 Aug 2017 13:54:14 +0200 Subject: [PATCH 051/196] Make gl_repository a G::G::Repository attribute --- app/models/repository.rb | 2 +- app/services/git_hooks_service.rb | 8 ++--- app/services/git_operation_service.rb | 2 +- .../20140502125220_migrate_repo_size.rb | 2 +- lib/gitlab/git/hook.rb | 13 +++++--- lib/gitlab/git/repository.rb | 5 +-- spec/lib/gitlab/git/blame_spec.rb | 2 +- spec/lib/gitlab/git/blob_spec.rb | 2 +- spec/lib/gitlab/git/branch_spec.rb | 2 +- spec/lib/gitlab/git/commit_spec.rb | 8 ++--- spec/lib/gitlab/git/compare_spec.rb | 2 +- spec/lib/gitlab/git/diff_spec.rb | 2 +- spec/lib/gitlab/git/hook_spec.rb | 9 +++--- spec/lib/gitlab/git/index_spec.rb | 2 +- spec/lib/gitlab/git/repository_spec.rb | 32 +++++++++---------- spec/lib/gitlab/git/tag_spec.rb | 2 +- spec/lib/gitlab/git/tree_spec.rb | 2 +- spec/models/repository_spec.rb | 4 +-- 18 files changed, 53 insertions(+), 48 deletions(-) diff --git a/app/models/repository.rb b/app/models/repository.rb index 3c5074e5157..062f532233f 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -1194,7 +1194,7 @@ class Repository end def initialize_raw_repository - Gitlab::Git::Repository.new(project.repository_storage, disk_path + '.git') + Gitlab::Git::Repository.new(project.repository_storage, disk_path + '.git', Gitlab::GlRepository.gl_repository(project, false)) end def circuit_breaker diff --git a/app/services/git_hooks_service.rb b/app/services/git_hooks_service.rb index e85007c26e0..c14133230da 100644 --- a/app/services/git_hooks_service.rb +++ b/app/services/git_hooks_service.rb @@ -3,9 +3,9 @@ class GitHooksService attr_accessor :oldrev, :newrev, :ref - def execute(committer, project, oldrev, newrev, ref) - @project = project - @gl_id = committer.gl_id + def execute(committer, repository, oldrev, newrev, ref) + @repository = repository + @gl_id = committer.gl_id @oldrev = oldrev @newrev = newrev @ref = ref @@ -26,7 +26,7 @@ class GitHooksService private def run_hook(name) - hook = Gitlab::Git::Hook.new(name, @project) + hook = Gitlab::Git::Hook.new(name, @repository) hook.trigger(@gl_id, oldrev, newrev, ref) end end diff --git a/app/services/git_operation_service.rb b/app/services/git_operation_service.rb index f7fce3d8a5d..d20e4ed9e88 100644 --- a/app/services/git_operation_service.rb +++ b/app/services/git_operation_service.rb @@ -123,7 +123,7 @@ class GitOperationService def with_hooks(ref, newrev, oldrev) GitHooksService.new.execute( committer, - repository.project, + repository, oldrev, newrev, ref) do |service| diff --git a/db/migrate/20140502125220_migrate_repo_size.rb b/db/migrate/20140502125220_migrate_repo_size.rb index f5d5d834307..ca1b054600c 100644 --- a/db/migrate/20140502125220_migrate_repo_size.rb +++ b/db/migrate/20140502125220_migrate_repo_size.rb @@ -11,7 +11,7 @@ class MigrateRepoSize < ActiveRecord::Migration path = File.join(namespace_path, project['project_path'] + '.git') begin - repo = Gitlab::Git::Repository.new('default', path) + repo = Gitlab::Git::Repository.new('default', path, '') if repo.empty? print '-' else diff --git a/lib/gitlab/git/hook.rb b/lib/gitlab/git/hook.rb index 8f0c377ef4f..08cede42ba2 100644 --- a/lib/gitlab/git/hook.rb +++ b/lib/gitlab/git/hook.rb @@ -6,15 +6,18 @@ module Gitlab module Git class Hook GL_PROTOCOL = 'web'.freeze - attr_reader :name, :repo_path, :path + attr_reader :name, :path, :repository - def initialize(name, project) + def initialize(name, repository) @name = name - @project = project - @repo_path = project.repository.path + @repository = repository @path = File.join(repo_path.strip, 'hooks', name) end + def repo_path + repository.path + end + def exists? File.exist?(path) end @@ -44,7 +47,7 @@ module Gitlab 'GL_ID' => gl_id, 'PWD' => repo_path, 'GL_PROTOCOL' => GL_PROTOCOL, - 'GL_REPOSITORY' => Gitlab::GlRepository.gl_repository(@project, false) + 'GL_REPOSITORY' => repository.gl_repository } options = { diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index eb3731ba35a..976ea7e4035 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -49,13 +49,14 @@ module Gitlab # Rugged repo object attr_reader :rugged - attr_reader :storage + attr_reader :storage, :gl_repository, :relative_path # 'path' must be the path to a _bare_ git repository, e.g. # /path/to/my-repo.git - def initialize(storage, relative_path) + def initialize(storage, relative_path, gl_repository) @storage = storage @relative_path = relative_path + @gl_repository = gl_repository storage_path = Gitlab.config.repositories.storages[@storage]['path'] @path = File.join(storage_path, @relative_path) diff --git a/spec/lib/gitlab/git/blame_spec.rb b/spec/lib/gitlab/git/blame_spec.rb index 800c245b130..465c2012b05 100644 --- a/spec/lib/gitlab/git/blame_spec.rb +++ b/spec/lib/gitlab/git/blame_spec.rb @@ -2,7 +2,7 @@ require "spec_helper" describe Gitlab::Git::Blame, seed_helper: true do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } let(:blame) do Gitlab::Git::Blame.new(repository, SeedRepo::Commit::ID, "CONTRIBUTING.md") end diff --git a/spec/lib/gitlab/git/blob_spec.rb b/spec/lib/gitlab/git/blob_spec.rb index dfab0c2fe85..66ba00acb7d 100644 --- a/spec/lib/gitlab/git/blob_spec.rb +++ b/spec/lib/gitlab/git/blob_spec.rb @@ -3,7 +3,7 @@ require "spec_helper" describe Gitlab::Git::Blob, seed_helper: true do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } describe 'initialize' do let(:blob) { Gitlab::Git::Blob.new(name: 'test') } diff --git a/spec/lib/gitlab/git/branch_spec.rb b/spec/lib/gitlab/git/branch_spec.rb index cdf1b8beee3..318a7b7a332 100644 --- a/spec/lib/gitlab/git/branch_spec.rb +++ b/spec/lib/gitlab/git/branch_spec.rb @@ -1,7 +1,7 @@ require "spec_helper" describe Gitlab::Git::Branch, seed_helper: true do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } subject { repository.branches } diff --git a/spec/lib/gitlab/git/commit_spec.rb b/spec/lib/gitlab/git/commit_spec.rb index ac33cd8a2c9..14d64d8c4da 100644 --- a/spec/lib/gitlab/git/commit_spec.rb +++ b/spec/lib/gitlab/git/commit_spec.rb @@ -1,7 +1,7 @@ require "spec_helper" describe Gitlab::Git::Commit, seed_helper: true do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } let(:commit) { described_class.find(repository, SeedRepo::Commit::ID) } let(:rugged_commit) do repository.rugged.lookup(SeedRepo::Commit::ID) @@ -9,7 +9,7 @@ describe Gitlab::Git::Commit, seed_helper: true do describe "Commit info" do before do - repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH).rugged + repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '').rugged @committer = { email: 'mike@smith.com', @@ -59,7 +59,7 @@ describe Gitlab::Git::Commit, seed_helper: true do after do # Erase the new commit so other tests get the original repo - repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH).rugged + repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '').rugged repo.references.update("refs/heads/master", SeedRepo::LastCommit::ID) end end @@ -144,7 +144,7 @@ describe Gitlab::Git::Commit, seed_helper: true do end context 'with broken repo' do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_BROKEN_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_BROKEN_REPO_PATH, '') } it 'returns nil' do expect(described_class.find(repository, SeedRepo::Commit::ID)).to be_nil diff --git a/spec/lib/gitlab/git/compare_spec.rb b/spec/lib/gitlab/git/compare_spec.rb index 4c9f4a28f32..b6a42e422b5 100644 --- a/spec/lib/gitlab/git/compare_spec.rb +++ b/spec/lib/gitlab/git/compare_spec.rb @@ -1,7 +1,7 @@ require "spec_helper" describe Gitlab::Git::Compare, seed_helper: true do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } let(:compare) { Gitlab::Git::Compare.new(repository, SeedRepo::BigCommit::ID, SeedRepo::Commit::ID, straight: false) } let(:compare_straight) { Gitlab::Git::Compare.new(repository, SeedRepo::BigCommit::ID, SeedRepo::Commit::ID, straight: true) } diff --git a/spec/lib/gitlab/git/diff_spec.rb b/spec/lib/gitlab/git/diff_spec.rb index 7ea3386ac2a..dfbdbee48f7 100644 --- a/spec/lib/gitlab/git/diff_spec.rb +++ b/spec/lib/gitlab/git/diff_spec.rb @@ -1,7 +1,7 @@ require "spec_helper" describe Gitlab::Git::Diff, seed_helper: true do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } before do @raw_diff_hash = { diff --git a/spec/lib/gitlab/git/hook_spec.rb b/spec/lib/gitlab/git/hook_spec.rb index 19391a70cf6..ea3e4680b1d 100644 --- a/spec/lib/gitlab/git/hook_spec.rb +++ b/spec/lib/gitlab/git/hook_spec.rb @@ -10,7 +10,8 @@ describe Gitlab::Git::Hook do describe "#trigger" do let(:project) { create(:project, :repository) } - let(:repo_path) { project.repository.path } + let(:repository) { project.repository.raw_repository } + let(:repo_path) { repository.path } let(:user) { create(:user) } let(:gl_id) { Gitlab::GlId.gl_id(user) } @@ -48,7 +49,7 @@ describe Gitlab::Git::Hook do it "returns success with no errors" do create_hook(hook_name) - hook = described_class.new(hook_name, project) + hook = described_class.new(hook_name, repository) blank = Gitlab::Git::BLANK_SHA ref = Gitlab::Git::BRANCH_REF_PREFIX + 'new_branch' @@ -66,7 +67,7 @@ describe Gitlab::Git::Hook do context "when the hook is unsuccessful" do it "returns failure with errors" do create_failing_hook(hook_name) - hook = described_class.new(hook_name, project) + hook = described_class.new(hook_name, repository) blank = Gitlab::Git::BLANK_SHA ref = Gitlab::Git::BRANCH_REF_PREFIX + 'new_branch' @@ -80,7 +81,7 @@ describe Gitlab::Git::Hook do context "when the hook doesn't exist" do it "returns success with no errors" do - hook = described_class.new('unknown_hook', project) + hook = described_class.new('unknown_hook', repository) blank = Gitlab::Git::BLANK_SHA ref = Gitlab::Git::BRANCH_REF_PREFIX + 'new_branch' diff --git a/spec/lib/gitlab/git/index_spec.rb b/spec/lib/gitlab/git/index_spec.rb index 21b71654251..73fbc6a6afa 100644 --- a/spec/lib/gitlab/git/index_spec.rb +++ b/spec/lib/gitlab/git/index_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe Gitlab::Git::Index, seed_helper: true do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } let(:index) { described_class.new(repository) } before do diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index 8ec8dfe6acf..06fcdd7aa57 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -17,7 +17,7 @@ describe Gitlab::Git::Repository, seed_helper: true do end end - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } describe "Respond to" do subject { repository } @@ -56,14 +56,14 @@ describe Gitlab::Git::Repository, seed_helper: true do describe "#rugged" do describe 'when storage is broken', broken_storage: true do it 'raises a storage exception when storage is not available' do - broken_repo = described_class.new('broken', 'a/path.git') + broken_repo = described_class.new('broken', 'a/path.git', '') expect { broken_repo.rugged }.to raise_error(Gitlab::Git::Storage::Inaccessible) end end it 'raises a no repository exception when there is no repo' do - broken_repo = described_class.new('default', 'a/path.git') + broken_repo = described_class.new('default', 'a/path.git', '') expect { broken_repo.rugged }.to raise_error(Gitlab::Git::Repository::NoRepository) end @@ -257,7 +257,7 @@ describe Gitlab::Git::Repository, seed_helper: true do end describe '#submodule_url_for' do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } let(:ref) { 'master' } def submodule_url(path) @@ -295,7 +295,7 @@ describe Gitlab::Git::Repository, seed_helper: true do end context '#submodules' do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } context 'where repo has submodules' do let(:submodules) { repository.send(:submodules, 'master') } @@ -391,7 +391,7 @@ describe Gitlab::Git::Repository, seed_helper: true do describe "#delete_branch" do before(:all) do - @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH) + @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') @repo.delete_branch("feature") end @@ -407,7 +407,7 @@ describe Gitlab::Git::Repository, seed_helper: true do describe "#create_branch" do before(:all) do - @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH) + @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') end it "should create a new branch" do @@ -445,7 +445,7 @@ describe Gitlab::Git::Repository, seed_helper: true do describe "#remote_delete" do before(:all) do - @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH) + @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') @repo.remote_delete("expendable") end @@ -461,7 +461,7 @@ describe Gitlab::Git::Repository, seed_helper: true do describe "#remote_add" do before(:all) do - @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH) + @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') @repo.remote_add("new_remote", SeedHelper::GITLAB_GIT_TEST_REPO_URL) end @@ -477,7 +477,7 @@ describe Gitlab::Git::Repository, seed_helper: true do describe "#remote_update" do before(:all) do - @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH) + @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') @repo.remote_update("expendable", url: TEST_NORMAL_REPO_PATH) end @@ -506,7 +506,7 @@ describe Gitlab::Git::Repository, seed_helper: true do before(:context) do # Add new commits so that there's a renamed file in the commit history - repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH).rugged + repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '').rugged @commit_with_old_name_id = new_commit_edit_old_file(repo) @rename_commit_id = new_commit_move_file(repo) @commit_with_new_name_id = new_commit_edit_new_file(repo) @@ -514,7 +514,7 @@ describe Gitlab::Git::Repository, seed_helper: true do after(:context) do # Erase our commits so other tests get the original repo - repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH).rugged + repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '').rugged repo.references.update("refs/heads/master", SeedRepo::LastCommit::ID) end @@ -849,7 +849,7 @@ describe Gitlab::Git::Repository, seed_helper: true do describe '#autocrlf' do before(:all) do - @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH) + @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') @repo.rugged.config['core.autocrlf'] = true end @@ -864,7 +864,7 @@ describe Gitlab::Git::Repository, seed_helper: true do describe '#autocrlf=' do before(:all) do - @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH) + @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') @repo.rugged.config['core.autocrlf'] = false end @@ -933,7 +933,7 @@ describe Gitlab::Git::Repository, seed_helper: true do context 'with local and remote branches' do let(:repository) do - Gitlab::Git::Repository.new('default', File.join(TEST_MUTABLE_REPO_PATH, '.git')) + Gitlab::Git::Repository.new('default', File.join(TEST_MUTABLE_REPO_PATH, '.git'), '') end before do @@ -1128,7 +1128,7 @@ describe Gitlab::Git::Repository, seed_helper: true do describe '#local_branches' do before(:all) do - @repo = Gitlab::Git::Repository.new('default', File.join(TEST_MUTABLE_REPO_PATH, '.git')) + @repo = Gitlab::Git::Repository.new('default', File.join(TEST_MUTABLE_REPO_PATH, '.git'), '') end after(:all) do diff --git a/spec/lib/gitlab/git/tag_spec.rb b/spec/lib/gitlab/git/tag_spec.rb index 78d1e120013..cc10679ef1e 100644 --- a/spec/lib/gitlab/git/tag_spec.rb +++ b/spec/lib/gitlab/git/tag_spec.rb @@ -1,7 +1,7 @@ require "spec_helper" describe Gitlab::Git::Tag, seed_helper: true do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } shared_examples 'Gitlab::Git::Repository#tags' do describe 'first tag' do diff --git a/spec/lib/gitlab/git/tree_spec.rb b/spec/lib/gitlab/git/tree_spec.rb index 98ddd3c3664..c07a2d91768 100644 --- a/spec/lib/gitlab/git/tree_spec.rb +++ b/spec/lib/gitlab/git/tree_spec.rb @@ -1,7 +1,7 @@ require "spec_helper" describe Gitlab::Git::Tree, seed_helper: true do - let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } context :repo do let(:tree) { Gitlab::Git::Tree.where(repository, SeedRepo::Commit::ID) } diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 0b1a35d1920..62585fdb35f 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -886,7 +886,7 @@ describe Repository, models: true do context 'when pre hooks were successful' do it 'runs without errors' do expect_any_instance_of(GitHooksService).to receive(:execute) - .with(committer, project, old_rev, blank_sha, 'refs/heads/feature') + .with(committer, repository, old_rev, blank_sha, 'refs/heads/feature') expect { repository.rm_branch(user, 'feature') }.not_to raise_error end @@ -929,7 +929,7 @@ describe Repository, models: true do service = GitHooksService.new expect(GitHooksService).to receive(:new).and_return(service) expect(service).to receive(:execute) - .with(committer, project, old_rev, new_rev, 'refs/heads/feature') + .with(committer, repository, old_rev, new_rev, 'refs/heads/feature') .and_yield(service).and_return(true) end From dc7c6bede27abd4507072276ef23b40a74ee297a Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Tue, 22 Aug 2017 14:18:09 +0200 Subject: [PATCH 052/196] Move GitHooksService to Gitlab::Git --- app/services/commits/create_service.rb | 2 +- app/services/create_branch_service.rb | 2 +- app/services/delete_branch_service.rb | 2 +- app/services/git_hooks_service.rb | 32 ---------------- app/services/git_operation_service.rb | 2 +- app/services/merge_requests/merge_service.rb | 2 +- app/services/tags/create_service.rb | 2 +- app/services/tags/destroy_service.rb | 2 +- app/services/validate_new_branch_service.rb | 2 +- db/fixtures/development/17_cycle_analytics.rb | 2 +- lib/gitlab/git/hook.rb | 4 +- lib/gitlab/git/hooks_service.rb | 37 +++++++++++++++++++ spec/features/tags/master_deletes_tag_spec.rb | 4 +- spec/lib/gitlab/git_access_spec.rb | 2 +- spec/models/repository_spec.rb | 16 ++++---- spec/services/files/update_service_spec.rb | 2 +- spec/services/git_hooks_service_spec.rb | 6 +-- .../merge_requests/merge_service_spec.rb | 2 +- spec/services/tags/create_service_spec.rb | 2 +- 19 files changed, 65 insertions(+), 60 deletions(-) delete mode 100644 app/services/git_hooks_service.rb create mode 100644 lib/gitlab/git/hooks_service.rb diff --git a/app/services/commits/create_service.rb b/app/services/commits/create_service.rb index c58f04a252b..dbd0b9ef43a 100644 --- a/app/services/commits/create_service.rb +++ b/app/services/commits/create_service.rb @@ -17,7 +17,7 @@ module Commits new_commit = create_commit! success(result: new_commit) - rescue ValidationError, ChangeError, Gitlab::Git::Index::IndexError, Repository::CommitError, GitHooksService::PreReceiveError => ex + rescue ValidationError, ChangeError, Gitlab::Git::Index::IndexError, Repository::CommitError, Gitlab::Git::HooksService::PreReceiveError => ex error(ex.message) end diff --git a/app/services/create_branch_service.rb b/app/services/create_branch_service.rb index 673ed02f952..0ba6a0ac6b5 100644 --- a/app/services/create_branch_service.rb +++ b/app/services/create_branch_service.rb @@ -14,7 +14,7 @@ class CreateBranchService < BaseService else error('Invalid reference name') end - rescue GitHooksService::PreReceiveError => ex + rescue Gitlab::Git::HooksService::PreReceiveError => ex error(ex.message) end diff --git a/app/services/delete_branch_service.rb b/app/services/delete_branch_service.rb index 64b3c0118fb..1f059c31944 100644 --- a/app/services/delete_branch_service.rb +++ b/app/services/delete_branch_service.rb @@ -16,7 +16,7 @@ class DeleteBranchService < BaseService else error('Failed to remove branch') end - rescue GitHooksService::PreReceiveError => ex + rescue Gitlab::Git::HooksService::PreReceiveError => ex error(ex.message) end diff --git a/app/services/git_hooks_service.rb b/app/services/git_hooks_service.rb deleted file mode 100644 index c14133230da..00000000000 --- a/app/services/git_hooks_service.rb +++ /dev/null @@ -1,32 +0,0 @@ -class GitHooksService - PreReceiveError = Class.new(StandardError) - - attr_accessor :oldrev, :newrev, :ref - - def execute(committer, repository, oldrev, newrev, ref) - @repository = repository - @gl_id = committer.gl_id - @oldrev = oldrev - @newrev = newrev - @ref = ref - - %w(pre-receive update).each do |hook_name| - status, message = run_hook(hook_name) - - unless status - raise PreReceiveError, message - end - end - - yield(self).tap do - run_hook('post-receive') - end - end - - private - - def run_hook(name) - hook = Gitlab::Git::Hook.new(name, @repository) - hook.trigger(@gl_id, oldrev, newrev, ref) - end -end diff --git a/app/services/git_operation_service.rb b/app/services/git_operation_service.rb index d20e4ed9e88..6a983566526 100644 --- a/app/services/git_operation_service.rb +++ b/app/services/git_operation_service.rb @@ -121,7 +121,7 @@ class GitOperationService end def with_hooks(ref, newrev, oldrev) - GitHooksService.new.execute( + Gitlab::Git::HooksService.new.execute( committer, repository, oldrev, diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb index bc846e07f24..5be749cd6a0 100644 --- a/app/services/merge_requests/merge_service.rb +++ b/app/services/merge_requests/merge_service.rb @@ -49,7 +49,7 @@ module MergeRequests raise MergeError, 'Conflicts detected during merge' unless commit_id merge_request.update(merge_commit_sha: commit_id) - rescue GitHooksService::PreReceiveError => e + rescue Gitlab::Git::HooksService::PreReceiveError => e raise MergeError, e.message rescue StandardError => e raise MergeError, "Something went wrong during merge: #{e.message}" diff --git a/app/services/tags/create_service.rb b/app/services/tags/create_service.rb index 674792f6138..b3f4a72d6fe 100644 --- a/app/services/tags/create_service.rb +++ b/app/services/tags/create_service.rb @@ -13,7 +13,7 @@ module Tags new_tag = repository.add_tag(current_user, tag_name, target, message) rescue Rugged::TagError return error("Tag #{tag_name} already exists") - rescue GitHooksService::PreReceiveError => ex + rescue Gitlab::Git::HooksService::PreReceiveError => ex return error(ex.message) end diff --git a/app/services/tags/destroy_service.rb b/app/services/tags/destroy_service.rb index a368f4f5b61..d3d46064729 100644 --- a/app/services/tags/destroy_service.rb +++ b/app/services/tags/destroy_service.rb @@ -21,7 +21,7 @@ module Tags else error('Failed to remove tag') end - rescue GitHooksService::PreReceiveError => ex + rescue Gitlab::Git::HooksService::PreReceiveError => ex error(ex.message) end diff --git a/app/services/validate_new_branch_service.rb b/app/services/validate_new_branch_service.rb index d232e85cd33..7d1ed768ee8 100644 --- a/app/services/validate_new_branch_service.rb +++ b/app/services/validate_new_branch_service.rb @@ -13,7 +13,7 @@ class ValidateNewBranchService < BaseService end success - rescue GitHooksService::PreReceiveError => ex + rescue Gitlab::Git::HooksService::PreReceiveError => ex error(ex.message) end end diff --git a/db/fixtures/development/17_cycle_analytics.rb b/db/fixtures/development/17_cycle_analytics.rb index 7c1d758dada..383782112a8 100644 --- a/db/fixtures/development/17_cycle_analytics.rb +++ b/db/fixtures/development/17_cycle_analytics.rb @@ -15,7 +15,7 @@ class Gitlab::Seeder::CycleAnalytics # to disable the `pre_receive` hook in order to remove this # dependency on the GitLab API. def stub_git_pre_receive! - GitHooksService.class_eval do + Gitlab::Git::HooksService.class_eval do def run_hook(name) [true, ''] end diff --git a/lib/gitlab/git/hook.rb b/lib/gitlab/git/hook.rb index 08cede42ba2..cc35d77c6e4 100644 --- a/lib/gitlab/git/hook.rb +++ b/lib/gitlab/git/hook.rb @@ -1,6 +1,6 @@ -# Gitaly note: JV: looks like this is only used by GitHooksService in +# Gitaly note: JV: looks like this is only used by Gitlab::Git::HooksService in # app/services. We shouldn't bother migrating this until we know how -# GitHooksService will be migrated. +# Gitlab::Git::HooksService will be migrated. module Gitlab module Git diff --git a/lib/gitlab/git/hooks_service.rb b/lib/gitlab/git/hooks_service.rb new file mode 100644 index 00000000000..1da92fcc0e2 --- /dev/null +++ b/lib/gitlab/git/hooks_service.rb @@ -0,0 +1,37 @@ +module Gitlab + module Git + class HooksService + PreReceiveError = Class.new(StandardError) + + attr_accessor :oldrev, :newrev, :ref + + def execute(committer, repository, oldrev, newrev, ref) + @repository = repository + @gl_id = committer.gl_id + @oldrev = oldrev + @newrev = newrev + @ref = ref + + %w(pre-receive update).each do |hook_name| + status, message = run_hook(hook_name) + + unless status + raise PreReceiveError, message + end + end + + yield(self).tap do + run_hook('post-receive') + end + end + + private + + def run_hook(name) + hook = Gitlab::Git::Hook.new(name, @repository) + hook.trigger(@gl_id, oldrev, newrev, ref) + end + end + end +end + diff --git a/spec/features/tags/master_deletes_tag_spec.rb b/spec/features/tags/master_deletes_tag_spec.rb index 4d6fc13557f..d6a6b8fc7d5 100644 --- a/spec/features/tags/master_deletes_tag_spec.rb +++ b/spec/features/tags/master_deletes_tag_spec.rb @@ -36,8 +36,8 @@ feature 'Master deletes tag' do context 'when pre-receive hook fails', js: true do before do - allow_any_instance_of(GitHooksService).to receive(:execute) - .and_raise(GitHooksService::PreReceiveError, 'Do not delete tags') + allow_any_instance_of(Gitlab::Git::HooksService).to receive(:execute) + .and_raise(Gitlab::Git::HooksService::PreReceiveError, 'Do not delete tags') end scenario 'shows the error message' do diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb index 80dc49e99cb..295a979da76 100644 --- a/spec/lib/gitlab/git_access_spec.rb +++ b/spec/lib/gitlab/git_access_spec.rb @@ -384,7 +384,7 @@ describe Gitlab::GitAccess do def stub_git_hooks # Running the `pre-receive` hook is expensive, and not necessary for this test. - allow_any_instance_of(GitHooksService).to receive(:execute) do |service, &block| + allow_any_instance_of(Gitlab::Git::HooksService).to receive(:execute) do |service, &block| block.call(service) end end diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 62585fdb35f..462e92b8b62 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -847,7 +847,7 @@ describe Repository, models: true do expect do repository.add_branch(user, 'new_feature', 'master') - end.to raise_error(GitHooksService::PreReceiveError) + end.to raise_error(Gitlab::Git::HooksService::PreReceiveError) end it 'does not create the branch' do @@ -855,7 +855,7 @@ describe Repository, models: true do expect do repository.add_branch(user, 'new_feature', 'master') - end.to raise_error(GitHooksService::PreReceiveError) + end.to raise_error(Gitlab::Git::HooksService::PreReceiveError) expect(repository.find_branch('new_feature')).to be_nil end end @@ -885,7 +885,7 @@ describe Repository, models: true do context 'when pre hooks were successful' do it 'runs without errors' do - expect_any_instance_of(GitHooksService).to receive(:execute) + expect_any_instance_of(Gitlab::Git::HooksService).to receive(:execute) .with(committer, repository, old_rev, blank_sha, 'refs/heads/feature') expect { repository.rm_branch(user, 'feature') }.not_to raise_error @@ -906,7 +906,7 @@ describe Repository, models: true do expect do repository.rm_branch(user, 'feature') - end.to raise_error(GitHooksService::PreReceiveError) + end.to raise_error(Gitlab::Git::HooksService::PreReceiveError) end it 'does not delete the branch' do @@ -914,7 +914,7 @@ describe Repository, models: true do expect do repository.rm_branch(user, 'feature') - end.to raise_error(GitHooksService::PreReceiveError) + end.to raise_error(Gitlab::Git::HooksService::PreReceiveError) expect(repository.find_branch('feature')).not_to be_nil end end @@ -926,8 +926,8 @@ describe Repository, models: true do context 'when pre hooks were successful' do before do - service = GitHooksService.new - expect(GitHooksService).to receive(:new).and_return(service) + service = Gitlab::Git::HooksService.new + expect(Gitlab::Git::HooksService).to receive(:new).and_return(service) expect(service).to receive(:execute) .with(committer, repository, old_rev, new_rev, 'refs/heads/feature') .and_yield(service).and_return(true) @@ -1030,7 +1030,7 @@ describe Repository, models: true do GitOperationService.new(committer, repository).with_branch('feature') do new_rev end - end.to raise_error(GitHooksService::PreReceiveError) + end.to raise_error(Gitlab::Git::HooksService::PreReceiveError) end end diff --git a/spec/services/files/update_service_spec.rb b/spec/services/files/update_service_spec.rb index cc950ae6bb3..2b4f8cd42ee 100644 --- a/spec/services/files/update_service_spec.rb +++ b/spec/services/files/update_service_spec.rb @@ -76,7 +76,7 @@ describe Files::UpdateService do let(:branch_name) { "#{project.default_branch}-new" } it 'fires hooks only once' do - expect(GitHooksService).to receive(:new).once.and_call_original + expect(Gitlab::Git::HooksService).to receive(:new).once.and_call_original subject.execute end diff --git a/spec/services/git_hooks_service_spec.rb b/spec/services/git_hooks_service_spec.rb index 3ce01a995b4..ac7be531526 100644 --- a/spec/services/git_hooks_service_spec.rb +++ b/spec/services/git_hooks_service_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe GitHooksService do +describe Gitlab::Git::HooksService do include RepoHelpers let(:user) { create(:user) } @@ -31,7 +31,7 @@ describe GitHooksService do expect do service.execute(user, project, @blankrev, @newrev, @ref) - end.to raise_error(GitHooksService::PreReceiveError) + end.to raise_error(Gitlab::Git::HooksService::PreReceiveError) end end @@ -43,7 +43,7 @@ describe GitHooksService do expect do service.execute(user, project, @blankrev, @newrev, @ref) - end.to raise_error(GitHooksService::PreReceiveError) + end.to raise_error(Gitlab::Git::HooksService::PreReceiveError) end end end diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb index e593bfeeaf7..5cfdb5372f3 100644 --- a/spec/services/merge_requests/merge_service_spec.rb +++ b/spec/services/merge_requests/merge_service_spec.rb @@ -217,7 +217,7 @@ describe MergeRequests::MergeService do it 'logs and saves error if there is an PreReceiveError exception' do error_message = 'error message' - allow(service).to receive(:repository).and_raise(GitHooksService::PreReceiveError, error_message) + allow(service).to receive(:repository).and_raise(Gitlab::Git::HooksService::PreReceiveError, error_message) allow(service).to receive(:execute_hooks) service.execute(merge_request) diff --git a/spec/services/tags/create_service_spec.rb b/spec/services/tags/create_service_spec.rb index 1b31ce29f7a..57013b54560 100644 --- a/spec/services/tags/create_service_spec.rb +++ b/spec/services/tags/create_service_spec.rb @@ -41,7 +41,7 @@ describe Tags::CreateService do it 'returns an error' do expect(repository).to receive(:add_tag) .with(user, 'v1.1.0', 'master', 'Foo') - .and_raise(GitHooksService::PreReceiveError, 'something went wrong') + .and_raise(Gitlab::Git::HooksService::PreReceiveError, 'something went wrong') response = service.execute('v1.1.0', 'master', 'Foo') From c47b947a7360f21cc1438462587c6e284b40e230 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Tue, 22 Aug 2017 16:24:41 +0200 Subject: [PATCH 053/196] Move GitHooksService tests --- .../gitlab/git/hooks_service_spec.rb} | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) rename spec/{services/git_hooks_service_spec.rb => lib/gitlab/git/hooks_service_spec.rb} (69%) diff --git a/spec/services/git_hooks_service_spec.rb b/spec/lib/gitlab/git/hooks_service_spec.rb similarity index 69% rename from spec/services/git_hooks_service_spec.rb rename to spec/lib/gitlab/git/hooks_service_spec.rb index ac7be531526..e9c0209fe3b 100644 --- a/spec/services/git_hooks_service_spec.rb +++ b/spec/lib/gitlab/git/hooks_service_spec.rb @@ -1,16 +1,14 @@ require 'spec_helper' -describe Gitlab::Git::HooksService do - include RepoHelpers - - let(:user) { create(:user) } - let(:project) { create(:project, :repository) } +describe Gitlab::Git::HooksService, seed_helper: true do + let(:committer) { Gitlab::Git::Committer.new('Jane Doe', 'janedoe@example.com', 'user-456') } + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, 'project-123') } let(:service) { described_class.new } before do @blankrev = Gitlab::Git::BLANK_SHA - @oldrev = sample_commit.parent_id - @newrev = sample_commit.id + @oldrev = SeedRepo::Commit::PARENT_ID + @newrev = SeedRepo::Commit::ID @ref = 'refs/heads/feature' end @@ -20,7 +18,7 @@ describe Gitlab::Git::HooksService do hook = double(trigger: [true, nil]) expect(Gitlab::Git::Hook).to receive(:new).exactly(3).times.and_return(hook) - service.execute(user, project, @blankrev, @newrev, @ref) { } + service.execute(committer, repository, @blankrev, @newrev, @ref) { } end end @@ -30,7 +28,7 @@ describe Gitlab::Git::HooksService do expect(service).not_to receive(:run_hook).with('post-receive') expect do - service.execute(user, project, @blankrev, @newrev, @ref) + service.execute(committer, repository, @blankrev, @newrev, @ref) end.to raise_error(Gitlab::Git::HooksService::PreReceiveError) end end @@ -42,7 +40,7 @@ describe Gitlab::Git::HooksService do expect(service).not_to receive(:run_hook).with('post-receive') expect do - service.execute(user, project, @blankrev, @newrev, @ref) + service.execute(committer, repository, @blankrev, @newrev, @ref) end.to raise_error(Gitlab::Git::HooksService::PreReceiveError) end end From da769135fede9dececee8ab3e1f6951de7361e7f Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Tue, 22 Aug 2017 16:27:15 +0200 Subject: [PATCH 054/196] Rubocop whitespace --- lib/gitlab/git/committer.rb | 2 +- lib/gitlab/git/hooks_service.rb | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/gitlab/git/committer.rb b/lib/gitlab/git/committer.rb index ef3576eaa1c..1f4bcf7a3a0 100644 --- a/lib/gitlab/git/committer.rb +++ b/lib/gitlab/git/committer.rb @@ -2,7 +2,7 @@ module Gitlab module Git class Committer attr_reader :name, :email, :gl_id - + def self.from_user(user) new(user.name, user.email, Gitlab::GlId.gl_id(user)) end diff --git a/lib/gitlab/git/hooks_service.rb b/lib/gitlab/git/hooks_service.rb index 1da92fcc0e2..ea8a87a1290 100644 --- a/lib/gitlab/git/hooks_service.rb +++ b/lib/gitlab/git/hooks_service.rb @@ -2,31 +2,31 @@ module Gitlab module Git class HooksService PreReceiveError = Class.new(StandardError) - + attr_accessor :oldrev, :newrev, :ref - + def execute(committer, repository, oldrev, newrev, ref) @repository = repository @gl_id = committer.gl_id @oldrev = oldrev @newrev = newrev @ref = ref - + %w(pre-receive update).each do |hook_name| status, message = run_hook(hook_name) - + unless status raise PreReceiveError, message end end - + yield(self).tap do run_hook('post-receive') end end - + private - + def run_hook(name) hook = Gitlab::Git::Hook.new(name, @repository) hook.trigger(@gl_id, oldrev, newrev, ref) @@ -34,4 +34,3 @@ module Gitlab end end end - From bc97931e2def4efee8418ce62ebc4818a31cf163 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Tue, 22 Aug 2017 16:27:18 +0200 Subject: [PATCH 055/196] Fix Hook.new call sites in tests --- spec/features/projects/import_export/import_file_spec.rb | 2 +- spec/lib/gitlab/import_export/repo_restorer_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb index 9f2c86923b7..2eb6fab129d 100644 --- a/spec/features/projects/import_export/import_file_spec.rb +++ b/spec/features/projects/import_export/import_file_spec.rb @@ -99,6 +99,6 @@ feature 'Import/Export - project import integration test', js: true do end def project_hook_exists?(project) - Gitlab::Git::Hook.new('post-receive', project).exists? + Gitlab::Git::Hook.new('post-receive', project.repository.raw_repository).exists? end end diff --git a/spec/lib/gitlab/import_export/repo_restorer_spec.rb b/spec/lib/gitlab/import_export/repo_restorer_spec.rb index 2786bc92fe5..c49af602a01 100644 --- a/spec/lib/gitlab/import_export/repo_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/repo_restorer_spec.rb @@ -34,7 +34,7 @@ describe Gitlab::ImportExport::RepoRestorer do it 'has the webhooks' do restorer.restore - expect(Gitlab::Git::Hook.new('post-receive', project)).to exist + expect(Gitlab::Git::Hook.new('post-receive', project.repository.raw_repository)).to exist end end end From f3e4f10de22ce2cbbb5dd830b7dfe0a79f40d1c1 Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Wed, 23 Aug 2017 10:30:09 +0100 Subject: [PATCH 056/196] Update repo_commit_section to spy service --- .../repo/components/repo_commit_section_spec.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/spec/javascripts/repo/components/repo_commit_section_spec.js b/spec/javascripts/repo/components/repo_commit_section_spec.js index 6f6faf5422b..1cbb4914005 100644 --- a/spec/javascripts/repo/components/repo_commit_section_spec.js +++ b/spec/javascripts/repo/components/repo_commit_section_spec.js @@ -1,9 +1,9 @@ import Vue from 'vue'; import repoCommitSection from '~/repo/components/repo_commit_section.vue'; import RepoStore from '~/repo/stores/repo_store'; -import Api from '~/api'; +import RepoService from '~/repo/services/repo_service'; -describe('RepoCommitSection', () => { +fdescribe('RepoCommitSection', () => { const branch = 'master'; const projectUrl = 'projectUrl'; const changedFiles = [{ @@ -111,7 +111,7 @@ describe('RepoCommitSection', () => { expect(submitCommit.disabled).toBeFalsy(); spyOn(vm, 'makeCommit').and.callThrough(); - spyOn(Api, 'commitMultiple').and.callFake(() => Promise.resolve()); + spyOn(RepoService, 'commitFiles').and.callFake(() => Promise.resolve()); submitCommit.click(); @@ -119,10 +119,9 @@ describe('RepoCommitSection', () => { expect(vm.makeCommit).toHaveBeenCalled(); expect(submitCommit.querySelector('.fa-spinner.fa-spin')).toBeTruthy(); - const args = Api.commitMultiple.calls.allArgs()[0]; - const { commit_message, actions, branch: payloadBranch } = args[1]; + const args = RepoService.commitFiles.calls.allArgs()[0]; + const { commit_message, actions, branch: payloadBranch } = args[0]; - expect(args[0]).toBe(projectId); expect(commit_message).toBe(commitMessage); expect(actions.length).toEqual(2); expect(payloadBranch).toEqual(branch); From 45d1c9a47ceeea4bffcfecd77ca87bd545f1b052 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Wed, 23 Aug 2017 11:46:10 +0200 Subject: [PATCH 057/196] Fix pipeline job worker specs --- spec/workers/build_finished_worker_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/workers/build_finished_worker_spec.rb b/spec/workers/build_finished_worker_spec.rb index 2868167c7d4..8cc3f37ebe8 100644 --- a/spec/workers/build_finished_worker_spec.rb +++ b/spec/workers/build_finished_worker_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe BuildFinishedWorker do describe '#perform' do context 'when build exists' do - let(:build) { create(:ci_build) } + let!(:build) { create(:ci_build) } it 'calculates coverage and calls hooks' do expect(BuildCoverageWorker) From a99b2d8e124167cad134fb7cad104a922a57299c Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Wed, 23 Aug 2017 10:45:46 +0200 Subject: [PATCH 058/196] Expose CI_PIPELINE_SOURCE on CI jobs It was missing and expected it wouldn't hurt anyone --- app/models/ci/pipeline.rb | 3 ++- .../unreleased/zj-add-pipeline-source-variable.yml | 5 +++++ doc/ci/variables/README.md | 1 + spec/models/ci/pipeline_spec.rb | 14 +++++++++++++- 4 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 changelogs/unreleased/zj-add-pipeline-source-variable.yml diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index ea7331cb27f..2d40f8012a3 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -393,7 +393,8 @@ module Ci def predefined_variables [ { key: 'CI_PIPELINE_ID', value: id.to_s, public: true }, - { key: 'CI_CONFIG_PATH', value: ci_yaml_file_path, public: true } + { key: 'CI_CONFIG_PATH', value: ci_yaml_file_path, public: true }, + { key: 'CI_PIPELINE_SOURCE', value: source.to_s, public: true } ] end diff --git a/changelogs/unreleased/zj-add-pipeline-source-variable.yml b/changelogs/unreleased/zj-add-pipeline-source-variable.yml new file mode 100644 index 00000000000..5d98cd8086a --- /dev/null +++ b/changelogs/unreleased/zj-add-pipeline-source-variable.yml @@ -0,0 +1,5 @@ +--- +title: Add CI_PIPELINE_SOURCE variable on CI Jobs +merge_request: +author: +type: added diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md index 22e7f6879ed..e55a92dbb71 100644 --- a/doc/ci/variables/README.md +++ b/doc/ci/variables/README.md @@ -57,6 +57,7 @@ future GitLab releases.** | **CI_RUNNER_TAGS** | 8.10 | 0.5 | The defined runner tags | | **CI_PIPELINE_ID** | 8.10 | 0.5 | The unique id of the current pipeline that GitLab CI uses internally | | **CI_PIPELINE_TRIGGERED** | all | all | The flag to indicate that job was [triggered] | +| **CI_PIPELINE_SOURCE** | 10.0 | all | The source for this pipeline, one of: push, web, trigger, schedule, api, external. Pipelines created before 9.5 will have unknown as source | | **CI_PROJECT_DIR** | all | all | The full path where the repository is cloned and where the job is run | | **CI_PROJECT_ID** | all | all | The unique id of the current project that GitLab CI uses internally | | **CI_PROJECT_NAME** | 8.10 | 0.5 | The project name that is currently being built (actually it is project folder name) | diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index ac75c6501ee..b84e3ff18e8 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe Ci::Pipeline, :mailer do let(:user) { create(:user) } - let(:project) { create(:project) } + set(:project) { create(:project) } let(:pipeline) do create(:ci_empty_pipeline, status: :created, project: project) @@ -159,6 +159,18 @@ describe Ci::Pipeline, :mailer do end end + describe '#predefined_variables' do + subject { pipeline.predefined_variables } + + it { is_expected.to be_an(Array) } + + it 'includes the defined keys' do + keys = subject.map { |v| v[:key] } + + expect(keys).to include('CI_PIPELINE_ID', 'CI_CONFIG_PATH', 'CI_PIPELINE_SOURCE') + end + end + describe '#auto_canceled?' do subject { pipeline.auto_canceled? } From d8d2b73b9f17e5af9aeccb1e9ba40045486651b5 Mon Sep 17 00:00:00 2001 From: Bob Van Landuyt Date: Fri, 18 Aug 2017 17:21:01 +0200 Subject: [PATCH 059/196] Improve bare repository import - Allow imports into nested groups - Make sure it sets the correct visibility level when creating new groups While doing this, I moved the import into a testable class, that made it easier to improve. --- .../bvl-improve-bare-project-import.yml | 6 + lib/gitlab/bare_repository_importer.rb | 127 ++++++++++++++++++ lib/tasks/gitlab/import.rake | 65 +-------- .../gitlab/bare_repository_importer_spec.rb | 88 ++++++++++++ 4 files changed, 223 insertions(+), 63 deletions(-) create mode 100644 changelogs/unreleased/bvl-improve-bare-project-import.yml create mode 100644 lib/gitlab/bare_repository_importer.rb create mode 100644 spec/lib/gitlab/bare_repository_importer_spec.rb diff --git a/changelogs/unreleased/bvl-improve-bare-project-import.yml b/changelogs/unreleased/bvl-improve-bare-project-import.yml new file mode 100644 index 00000000000..74c1da4ea40 --- /dev/null +++ b/changelogs/unreleased/bvl-improve-bare-project-import.yml @@ -0,0 +1,6 @@ +--- +title: 'Improve bare project import: Allow subgroups, take default visibility level + into account' +merge_request: 13670 +author: +type: fixed diff --git a/lib/gitlab/bare_repository_importer.rb b/lib/gitlab/bare_repository_importer.rb new file mode 100644 index 00000000000..4bc3ccc3a1a --- /dev/null +++ b/lib/gitlab/bare_repository_importer.rb @@ -0,0 +1,127 @@ +module Gitlab + class BareRepositoryImporter + NoAdminError = Class.new(StandardError) + + def self.execute + Gitlab.config.repositories.storages.each do |storage_name, repository_storage| + git_base_path = repository_storage['path'] + repos_to_import = Dir.glob(git_base_path + '/**/*.git') + + repos_to_import.each do |repo_path| + if repo_path.end_with?('.wiki.git') + log " * Skipping wiki repo" + next + end + + log "Processing #{repo_path}".color(:yellow) + + repo_relative_path = repo_path[repository_storage['path'].length..-1] + .sub(/^\//, '') # Remove leading `/` + .sub(/\.git$/, '') # Remove `.git` at the end + new(storage_name, repo_relative_path).create_project_if_needed + end + end + end + + attr_reader :storage_name, :full_path, :group_path, :project_path, :user + delegate :log, to: :class + + def initialize(storage_name, repo_path) + @storage_name = storage_name + @full_path = repo_path + + unless @user = User.admins.order_id_asc.first + raise NoAdminError.new('No admin user found to import repositories') + end + + @group_path, @project_path = File.split(repo_path) + @group_path = nil if @group_path == '.' + end + + def create_project_if_needed + if project = Project.find_by_full_path(full_path) + log " * #{project.name} (#{full_path}) exists" + return project + end + + create_project + end + + private + + def create_project + group = find_or_create_group + + project_params = { + name: project_path, + path: project_path, + repository_storage: storage_name, + namespace_id: group&.id + } + + project = Projects::CreateService.new(user, project_params).execute + + if project.persisted? + log " * Created #{project.name} (#{full_path})".color(:green) + ProjectCacheWorker.perform_async(project.id) + else + log " * Failed trying to create #{project.name} (#{full_path})".color(:red) + log " Errors: #{project.errors.messages}".color(:red) + end + + project + end + + def find_or_create_group + return nil unless group_path + + if namespace = Namespace.find_by_full_path(group_path) + log " * Namespace #{group_path} exists.".color(:green) + return namespace + end + + create_group_path + end + + def create_group_path + group_path_segments = group_path.split('/') + + new_group, parent_group = nil + partial_path_segments = [] + while subgroup_name = group_path_segments.shift + partial_path_segments << subgroup_name + partial_path = partial_path_segments.join('/') + + unless new_group = Group.find_by_full_path(partial_path) + log " * Creating group #{partial_path}.".color(:green) + params = { + path: subgroup_name, + name: subgroup_name, + parent: parent_group, + visibility_level: Gitlab::CurrentSettings.current_application_settings.default_group_visibility + } + new_group = Groups::CreateService.new(user, params).execute + end + + if new_group.persisted? + log " * Group #{partial_path} (#{new_group.id}) available".color(:green) + else + log " * Failed trying to create group #{partial_path}.".color(:red) + log " * Errors: #{new_group.errors.messages}".color(:red) + end + parent_group = new_group + end + + new_group + end + + # This is called from within a rake task only used by Admins, so allow writing + # to STDOUT + # + # rubocop:disable Rails/Output + def self.log(message) + puts message + end + # rubocop:enable Rails/Output + end +end diff --git a/lib/tasks/gitlab/import.rake b/lib/tasks/gitlab/import.rake index 6e10ba374bf..d227a0c8bdb 100644 --- a/lib/tasks/gitlab/import.rake +++ b/lib/tasks/gitlab/import.rake @@ -9,6 +9,7 @@ namespace :gitlab do # * The project owner will set to the first administator of the system # * Existing projects will be skipped # + # desc "GitLab | Import bare repositories from repositories -> storages into GitLab project instance" task repos: :environment do if Project.current_application_settings.hashed_storage_enabled @@ -17,69 +18,7 @@ namespace :gitlab do exit 1 end - Gitlab.config.repositories.storages.each_value do |repository_storage| - git_base_path = repository_storage['path'] - repos_to_import = Dir.glob(git_base_path + '/**/*.git') - - repos_to_import.each do |repo_path| - # strip repo base path - repo_path[0..git_base_path.length] = '' - - path = repo_path.sub(/\.git$/, '') - group_name, name = File.split(path) - group_name = nil if group_name == '.' - - puts "Processing #{repo_path}".color(:yellow) - - if path.end_with?('.wiki') - puts " * Skipping wiki repo" - next - end - - project = Project.find_by_full_path(path) - - if project - puts " * #{project.name} (#{repo_path}) exists" - else - user = User.admins.reorder("id").first - - project_params = { - name: name, - path: name - } - - # find group namespace - if group_name - group = Namespace.find_by(path: group_name) - # create group namespace - unless group - group = Group.new(name: group_name) - group.path = group_name - group.owner = user - if group.save - puts " * Created Group #{group.name} (#{group.id})".color(:green) - else - puts " * Failed trying to create group #{group.name}".color(:red) - end - end - # set project group - project_params[:namespace_id] = group.id - end - - project = Projects::CreateService.new(user, project_params).execute - - if project.persisted? - puts " * Created #{project.name} (#{repo_path})".color(:green) - ProjectCacheWorker.perform_async(project.id) - else - puts " * Failed trying to create #{project.name} (#{repo_path})".color(:red) - puts " Errors: #{project.errors.messages}".color(:red) - end - end - end - end - - puts "Done!".color(:green) + Gitlab::BareRepositoryImporter.execute end end end diff --git a/spec/lib/gitlab/bare_repository_importer_spec.rb b/spec/lib/gitlab/bare_repository_importer_spec.rb new file mode 100644 index 00000000000..88d30a2e855 --- /dev/null +++ b/spec/lib/gitlab/bare_repository_importer_spec.rb @@ -0,0 +1,88 @@ +require 'spec_helper' + +describe Gitlab::BareRepositoryImporter, repository: true do + subject(:importer) { described_class.new('default', project_path) } + let(:project_path) { 'a-group/a-sub-group/a-project' } + let!(:admin) { create(:admin) } + + before do + allow(described_class).to receive(:log) + end + + describe '.execute' do + it 'creates a project for a repository in storage' do + FileUtils.mkdir_p(File.join(TestEnv.repos_path, "#{project_path}.git")) + fake_importer = double + + expect(described_class).to receive(:new).with('default', project_path) + .and_return(fake_importer) + expect(fake_importer).to receive(:create_project_if_needed) + + described_class.execute + end + + it 'skips wiki repos' do + FileUtils.mkdir_p(File.join(TestEnv.repos_path, 'the-group', 'the-project.wiki.git')) + + expect(described_class).to receive(:log).with(' * Skipping wiki repo') + expect(described_class).not_to receive(:new) + + described_class.execute + end + end + + describe '#initialize' do + context 'without admin users' do + let(:admin) { nil } + + it 'raises an error' do + expect { importer }.to raise_error(Gitlab::BareRepositoryImporter::NoAdminError) + end + end + end + + describe '#create_project_if_needed' do + it 'starts an import for a project that did not exist' do + expect(importer).to receive(:create_project) + + importer.create_project_if_needed + end + + it 'skips importing when the project already exists' do + group = create(:group, path: 'a-group') + subgroup = create(:group, path: 'a-sub-group', parent: group) + project = create(:project, path: 'a-project', namespace: subgroup) + + expect(importer).not_to receive(:create_project) + expect(importer).to receive(:log).with(" * #{project.name} (a-group/a-sub-group/a-project) exists") + + importer.create_project_if_needed + end + + it 'creates a project with the correct path in the database' do + importer.create_project_if_needed + + expect(Project.find_by_full_path(project_path)).not_to be_nil + end + + it 'creates group and subgroup in the database' do + importer.create_project_if_needed + + parent = Group.find_by_full_path('a-group') + child = parent.children.find_by(path: 'a-sub-group') + + expect(parent).not_to be_nil + expect(child).not_to be_nil + end + + it 'creates the group with correct visibility level' do + allow(Gitlab::CurrentSettings.current_application_settings) + .to receive(:default_group_visibility) { Gitlab::VisibilityLevel::INTERNAL } + project = importer.create_project_if_needed + + group = project.namespace + + expect(group.visibility_level).to eq(Gitlab::VisibilityLevel::INTERNAL) + end + end +end From 22ef4ba3a4be66296e5ee9231b4eb39e172c0f1f Mon Sep 17 00:00:00 2001 From: Bob Van Landuyt Date: Tue, 22 Aug 2017 12:13:25 +0200 Subject: [PATCH 060/196] Migrate creation of nested groups into a service --- app/services/groups/nested_create_service.rb | 45 ++++++++++++++++ lib/gitlab/bare_repository_importer.rb | 35 +----------- lib/tasks/import.rake | 18 +------ .../gitlab/bare_repository_importer_spec.rb | 20 ------- .../groups/nested_create_service_spec.rb | 53 +++++++++++++++++++ 5 files changed, 101 insertions(+), 70 deletions(-) create mode 100644 app/services/groups/nested_create_service.rb create mode 100644 spec/services/groups/nested_create_service_spec.rb diff --git a/app/services/groups/nested_create_service.rb b/app/services/groups/nested_create_service.rb new file mode 100644 index 00000000000..8d793f5c02e --- /dev/null +++ b/app/services/groups/nested_create_service.rb @@ -0,0 +1,45 @@ +module Groups + class NestedCreateService < Groups::BaseService + attr_reader :group_path + + def initialize(user, params) + @current_user, @params = user, params.dup + + @group_path = @params.delete(:group_path) + end + + def execute + return nil unless group_path + + if group = Group.find_by_full_path(group_path) + return group + end + + create_group_path + end + + private + + def create_group_path + group_path_segments = group_path.split('/') + + last_group = nil + partial_path_segments = [] + while subgroup_name = group_path_segments.shift + partial_path_segments << subgroup_name + partial_path = partial_path_segments.join('/') + + new_params = params.reverse_merge( + path: subgroup_name, + name: subgroup_name, + parent: last_group + ) + new_params[:visibility_level] ||= Gitlab::CurrentSettings.current_application_settings.default_group_visibility + + last_group = Group.find_by_full_path(partial_path) || Groups::CreateService.new(current_user, new_params).execute + end + + last_group + end + end +end diff --git a/lib/gitlab/bare_repository_importer.rb b/lib/gitlab/bare_repository_importer.rb index 4bc3ccc3a1a..9323bfc7fb2 100644 --- a/lib/gitlab/bare_repository_importer.rb +++ b/lib/gitlab/bare_repository_importer.rb @@ -80,39 +80,8 @@ module Gitlab return namespace end - create_group_path - end - - def create_group_path - group_path_segments = group_path.split('/') - - new_group, parent_group = nil - partial_path_segments = [] - while subgroup_name = group_path_segments.shift - partial_path_segments << subgroup_name - partial_path = partial_path_segments.join('/') - - unless new_group = Group.find_by_full_path(partial_path) - log " * Creating group #{partial_path}.".color(:green) - params = { - path: subgroup_name, - name: subgroup_name, - parent: parent_group, - visibility_level: Gitlab::CurrentSettings.current_application_settings.default_group_visibility - } - new_group = Groups::CreateService.new(user, params).execute - end - - if new_group.persisted? - log " * Group #{partial_path} (#{new_group.id}) available".color(:green) - else - log " * Failed trying to create group #{partial_path}.".color(:red) - log " * Errors: #{new_group.errors.messages}".color(:red) - end - parent_group = new_group - end - - new_group + log " * Creating Group: #{group_path}" + Groups::NestedCreateService.new(user, group_path: group_path).execute end # This is called from within a rake task only used by Admins, so allow writing diff --git a/lib/tasks/import.rake b/lib/tasks/import.rake index 96b8f59242c..1206302cb76 100644 --- a/lib/tasks/import.rake +++ b/lib/tasks/import.rake @@ -72,23 +72,7 @@ class GithubImport return @current_user.namespace if names == @current_user.namespace_path return @current_user.namespace unless @current_user.can_create_group? - full_path_namespace = Namespace.find_by_full_path(names) - - return full_path_namespace if full_path_namespace - - names.split('/').inject(nil) do |parent, name| - begin - namespace = Group.create!(name: name, - path: name, - owner: @current_user, - parent: parent) - namespace.add_owner(@current_user) - - namespace - rescue ActiveRecord::RecordNotUnique, ActiveRecord::RecordInvalid - Namespace.where(parent: parent).find_by_path_or_name(name) - end - end + Groups::NestedCreateService.new(@current_user, group_path: names).execute end def full_path_namespace(names) diff --git a/spec/lib/gitlab/bare_repository_importer_spec.rb b/spec/lib/gitlab/bare_repository_importer_spec.rb index 88d30a2e855..892f2dafc96 100644 --- a/spec/lib/gitlab/bare_repository_importer_spec.rb +++ b/spec/lib/gitlab/bare_repository_importer_spec.rb @@ -64,25 +64,5 @@ describe Gitlab::BareRepositoryImporter, repository: true do expect(Project.find_by_full_path(project_path)).not_to be_nil end - - it 'creates group and subgroup in the database' do - importer.create_project_if_needed - - parent = Group.find_by_full_path('a-group') - child = parent.children.find_by(path: 'a-sub-group') - - expect(parent).not_to be_nil - expect(child).not_to be_nil - end - - it 'creates the group with correct visibility level' do - allow(Gitlab::CurrentSettings.current_application_settings) - .to receive(:default_group_visibility) { Gitlab::VisibilityLevel::INTERNAL } - project = importer.create_project_if_needed - - group = project.namespace - - expect(group.visibility_level).to eq(Gitlab::VisibilityLevel::INTERNAL) - end end end diff --git a/spec/services/groups/nested_create_service_spec.rb b/spec/services/groups/nested_create_service_spec.rb new file mode 100644 index 00000000000..c1526456bac --- /dev/null +++ b/spec/services/groups/nested_create_service_spec.rb @@ -0,0 +1,53 @@ +require 'spec_helper' + +describe Groups::NestedCreateService do + let(:user) { create(:user) } + let(:params) { { group_path: 'a-group/a-sub-group' } } + + subject(:service) { described_class.new(user, params) } + + describe "#execute" do + it 'returns the group if it already existed' do + parent = create(:group, path: 'a-group', owner: user) + child = create(:group, path: 'a-sub-group', parent: parent, owner: user) + + expect(service.execute).to eq(child) + end + + it 'reuses a parent if it already existed' do + parent = create(:group, path: 'a-group') + parent.add_owner(user) + + expect(service.execute.parent).to eq(parent) + end + + it 'creates group and subgroup in the database' do + service.execute + + parent = Group.find_by_full_path('a-group') + child = parent.children.find_by(path: 'a-sub-group') + + expect(parent).not_to be_nil + expect(child).not_to be_nil + end + + it 'creates the group with correct visibility level' do + allow(Gitlab::CurrentSettings.current_application_settings) + .to receive(:default_group_visibility) { Gitlab::VisibilityLevel::INTERNAL } + + group = service.execute + + expect(group.visibility_level).to eq(Gitlab::VisibilityLevel::INTERNAL) + end + + context 'adding a visibility level ' do + let(:params) { { group_path: 'a-group/a-sub-group', visibility_level: Gitlab::VisibilityLevel::PRIVATE } } + + it 'overwrites the visibility level' do + group = service.execute + + expect(group.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) + end + end + end +end From f76d8c902a08040eeaacc8c7a3a9506fb55501e7 Mon Sep 17 00:00:00 2001 From: Bob Van Landuyt Date: Tue, 22 Aug 2017 14:03:40 +0200 Subject: [PATCH 061/196] Fix error when importing a GitHub-wiki repository This would occur when Wiki's are enabled on GitHub, but there is no wiki repository --- lib/github/import.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/github/import.rb b/lib/github/import.rb index 4cc01593ef4..7b848081e85 100644 --- a/lib/github/import.rb +++ b/lib/github/import.rb @@ -107,7 +107,7 @@ module Github # this means that repo has wiki enabled, but have no pages. So, # we can skip the import. if e.message !~ /repository not exported/ - errors(:wiki, wiki_url, e.message) + error(:wiki, wiki_url, e.message) end end From 6ec53f5d488fcdc6ef2b076c37a46525b5176224 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Thu, 17 Aug 2017 17:21:25 +0200 Subject: [PATCH 062/196] Cache the number of open issues and merge requests Every project page displays a navigation menu that in turn displays the number of open issues and merge requests. This means that for every project page we run two COUNT(*) queries, each taking up roughly 30 milliseconds on GitLab.com. By caching these numbers and refreshing them whenever necessary we can reduce loading times of all these pages by up to roughly 60 milliseconds. The number of open issues does not include confidential issues. This is a trade-off to keep the code simple and to ensure refreshing the data only needs 2 COUNT(*) queries instead of 3. A downside is that if a project only has 5 confidential issues the counter will be set to 0. Because we now have 3 similar counting service classes the code previously used in Projects::ForksCountService has mostly been moved to Projects::CountService, which in turn is reused by the various service classes. Fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/36622 --- app/models/issue.rb | 7 ++ app/models/merge_request.rb | 5 ++ app/models/project.rb | 6 +- app/services/issuable_base_service.rb | 4 + app/services/issues/create_service.rb | 2 + app/services/merge_requests/create_service.rb | 2 + app/services/projects/count_service.rb | 43 +++++++++++ app/services/projects/forks_count_service.rb | 28 ++----- .../projects/open_issues_count_service.rb | 15 ++++ .../open_merge_requests_count_service.rb | 13 ++++ .../nav/_new_project_sidebar.html.haml | 6 +- app/views/layouts/nav/_project.html.haml | 6 +- .../unreleased/cache-issue-and-mr-counts.yml | 5 ++ spec/models/issue_spec.rb | 18 +++++ spec/models/merge_request_spec.rb | 9 +++ spec/services/issues/close_service_spec.rb | 5 ++ spec/services/issues/create_service_spec.rb | 4 + spec/services/issues/reopen_service_spec.rb | 7 ++ .../merge_requests/close_service_spec.rb | 7 ++ .../merge_requests/create_service_spec.rb | 32 ++++---- .../merge_requests/reopen_service_spec.rb | 7 ++ spec/services/projects/count_service_spec.rb | 73 +++++++++++++++++++ .../projects/forks_count_service_spec.rb | 32 +------- .../open_issues_count_service_spec.rb | 21 ++++++ .../open_merge_requests_count_service_spec.rb | 15 ++++ 25 files changed, 301 insertions(+), 71 deletions(-) create mode 100644 app/services/projects/count_service.rb create mode 100644 app/services/projects/open_issues_count_service.rb create mode 100644 app/services/projects/open_merge_requests_count_service.rb create mode 100644 changelogs/unreleased/cache-issue-and-mr-counts.yml create mode 100644 spec/services/projects/count_service_spec.rb create mode 100644 spec/services/projects/open_issues_count_service_spec.rb create mode 100644 spec/services/projects/open_merge_requests_count_service_spec.rb diff --git a/app/models/issue.rb b/app/models/issue.rb index 1c948c8957e..d89b1c96a36 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -53,7 +53,10 @@ class Issue < ActiveRecord::Base scope :preload_associations, -> { preload(:labels, project: :namespace) } + scope :public_only, -> { where(confidential: false) } + after_save :expire_etag_cache + after_commit :update_project_counter_caches, on: :destroy attr_spammable :title, spam_title: true attr_spammable :description, spam_description: true @@ -269,6 +272,10 @@ class Issue < ActiveRecord::Base end end + def update_project_counter_caches + Projects::OpenIssuesCountService.new(project).refresh_cache + end + private # Returns `true` if the given User can read the current Issue. diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index ac08dc0ee1f..7fe7df75944 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -32,6 +32,7 @@ class MergeRequest < ActiveRecord::Base after_create :ensure_merge_request_diff, unless: :importing? after_update :reload_diff_if_branch_changed + after_commit :update_project_counter_caches, on: :destroy # When this attribute is true some MR validation is ignored # It allows us to close or modify broken merge requests @@ -937,6 +938,10 @@ class MergeRequest < ActiveRecord::Base true end + def update_project_counter_caches + Projects::OpenMergeRequestsCountService.new(target_project).refresh_cache + end + private def write_ref diff --git a/app/models/project.rb b/app/models/project.rb index be248bc99e1..ddef8b82dee 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1158,7 +1158,11 @@ class Project < ActiveRecord::Base end def open_issues_count - issues.opened.count + Projects::OpenIssuesCountService.new(self).count + end + + def open_merge_requests_count + Projects::OpenMergeRequestsCountService.new(self).count end def visibility_level_allowed_as_fork?(level = self.visibility_level) diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb index 4a4f2b91182..1486db046b5 100644 --- a/app/services/issuable_base_service.rb +++ b/app/services/issuable_base_service.rb @@ -192,6 +192,8 @@ class IssuableBaseService < BaseService def after_create(issuable) # To be overridden by subclasses + + issuable.update_project_counter_caches end def before_update(issuable) @@ -200,6 +202,8 @@ class IssuableBaseService < BaseService def after_update(issuable) # To be overridden by subclasses + + issuable.update_project_counter_caches end def update(issuable) diff --git a/app/services/issues/create_service.rb b/app/services/issues/create_service.rb index 234fcbede03..0307634c0b6 100644 --- a/app/services/issues/create_service.rb +++ b/app/services/issues/create_service.rb @@ -27,6 +27,8 @@ module Issues todo_service.new_issue(issuable, current_user) user_agent_detail_service.create resolve_discussions_with_issue(issuable) + + super end def resolve_discussions_with_issue(issue) diff --git a/app/services/merge_requests/create_service.rb b/app/services/merge_requests/create_service.rb index 194413bf321..3d53fe0646b 100644 --- a/app/services/merge_requests/create_service.rb +++ b/app/services/merge_requests/create_service.rb @@ -28,6 +28,8 @@ module MergeRequests todo_service.new_merge_request(issuable, current_user) issuable.cache_merge_request_closes_issues!(current_user) update_merge_requests_head_pipeline(issuable) + + super end private diff --git a/app/services/projects/count_service.rb b/app/services/projects/count_service.rb new file mode 100644 index 00000000000..5e633c37bf8 --- /dev/null +++ b/app/services/projects/count_service.rb @@ -0,0 +1,43 @@ +module Projects + # Base class for the various service classes that count project data (e.g. + # issues or forks). + class CountService + def initialize(project) + @project = project + end + + def relation_for_count + raise( + NotImplementedError, + '"relation_for_count" must be implemented and return an ActiveRecord::Relation' + ) + end + + def count + Rails.cache.fetch(cache_key) { uncached_count } + end + + def refresh_cache + Rails.cache.write(cache_key, uncached_count) + end + + def uncached_count + relation_for_count.count + end + + def delete_cache + Rails.cache.delete(cache_key) + end + + def cache_key_name + raise( + NotImplementedError, + '"cache_key_name" must be implemented and return a String' + ) + end + + def cache_key + ['projects', @project.id, cache_key_name] + end + end +end diff --git a/app/services/projects/forks_count_service.rb b/app/services/projects/forks_count_service.rb index e2e2b1da91d..3a0fa84b868 100644 --- a/app/services/projects/forks_count_service.rb +++ b/app/services/projects/forks_count_service.rb @@ -1,30 +1,12 @@ module Projects # Service class for getting and caching the number of forks of a project. - class ForksCountService - def initialize(project) - @project = project + class ForksCountService < CountService + def relation_for_count + @project.forks end - def count - Rails.cache.fetch(cache_key) { uncached_count } - end - - def refresh_cache - Rails.cache.write(cache_key, uncached_count) - end - - def delete_cache - Rails.cache.delete(cache_key) - end - - private - - def uncached_count - @project.forks.count - end - - def cache_key - ['projects', @project.id, 'forks_count'] + def cache_key_name + 'forks_count' end end end diff --git a/app/services/projects/open_issues_count_service.rb b/app/services/projects/open_issues_count_service.rb new file mode 100644 index 00000000000..3c0d186a73c --- /dev/null +++ b/app/services/projects/open_issues_count_service.rb @@ -0,0 +1,15 @@ +module Projects + # Service class for counting and caching the number of open issues of a + # project. + class OpenIssuesCountService < CountService + def relation_for_count + # We don't include confidential issues in this number since this would + # expose the number of confidential issues to non project members. + @project.issues.opened.public_only + end + + def cache_key_name + 'open_issues_count' + end + end +end diff --git a/app/services/projects/open_merge_requests_count_service.rb b/app/services/projects/open_merge_requests_count_service.rb new file mode 100644 index 00000000000..2a90f78b90d --- /dev/null +++ b/app/services/projects/open_merge_requests_count_service.rb @@ -0,0 +1,13 @@ +module Projects + # Service class for counting and caching the number of open merge requests of + # a project. + class OpenMergeRequestsCountService < CountService + def relation_for_count + @project.merge_requests.opened + end + + def cache_key_name + 'open_merge_requests_count' + end + end +end diff --git a/app/views/layouts/nav/_new_project_sidebar.html.haml b/app/views/layouts/nav/_new_project_sidebar.html.haml index 0ef81375c3a..81c84756ff8 100644 --- a/app/views/layouts/nav/_new_project_sidebar.html.haml +++ b/app/views/layouts/nav/_new_project_sidebar.html.haml @@ -86,7 +86,8 @@ %span.nav-item-name Issues - if @project.issues_enabled? - %span.badge.count.issue_counter= number_with_delimiter(IssuesFinder.new(current_user, project_id: @project.id).execute.opened.count) + %span.badge.count.issue_counter + = number_with_delimiter(@project.open_issues_count) %ul.sidebar-sub-level-items = nav_link(controller: :issues) do @@ -116,7 +117,8 @@ = custom_icon('mr_bold') %span.nav-item-name Merge Requests - %span.badge.count.merge_counter.js-merge-counter= number_with_delimiter(MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened.count) + %span.badge.count.merge_counter.js-merge-counter + = number_with_delimiter(@project.open_merge_requests_count) - if project_nav_tab? :pipelines = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :environments, :artifacts]) do diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml index 924cd2e9681..b88465848e3 100644 --- a/app/views/layouts/nav/_project.html.haml +++ b/app/views/layouts/nav/_project.html.haml @@ -28,7 +28,8 @@ %span Issues - if @project.issues_enabled? - %span.badge.count.issue_counter= number_with_delimiter(issuables_count_for_state(:issues, :opened, finder: IssuesFinder.new(current_user, project_id: @project.id))) + %span.badge.count.issue_counter + = number_with_delimiter(@project.open_issues_count) - if project_nav_tab? :merge_requests - controllers = [:merge_requests, 'projects/merge_requests/conflicts'] @@ -37,7 +38,8 @@ = link_to project_merge_requests_path(@project), title: 'Merge Requests', class: 'shortcuts-merge_requests' do %span Merge Requests - %span.badge.count.merge_counter.js-merge-counter= number_with_delimiter(issuables_count_for_state(:merge_requests, :opened, finder: MergeRequestsFinder.new(current_user, project_id: @project.id))) + %span.badge.count.merge_counter.js-merge-counter + = number_with_delimiter(@project.open_merge_requests_count) - if project_nav_tab? :pipelines = nav_link(controller: [:pipelines, :builds, :environments, :artifacts]) do diff --git a/changelogs/unreleased/cache-issue-and-mr-counts.yml b/changelogs/unreleased/cache-issue-and-mr-counts.yml new file mode 100644 index 00000000000..fe3fe3be976 --- /dev/null +++ b/changelogs/unreleased/cache-issue-and-mr-counts.yml @@ -0,0 +1,5 @@ +--- +title: Cache the number of open issues and merge requests +merge_request: +author: +type: other diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb index 9203f6562f2..de86788d142 100644 --- a/spec/models/issue_spec.rb +++ b/spec/models/issue_spec.rb @@ -751,4 +751,22 @@ describe Issue do end end end + + describe 'removing an issue' do + it 'refreshes the number of open issues of the project' do + project = subject.project + + expect { subject.destroy } + .to change { project.open_issues_count }.from(1).to(0) + end + end + + describe '.public_only' do + it 'only returns public issues' do + public_issue = create(:issue) + create(:issue, confidential: true) + + expect(described_class.public_only).to eq([public_issue]) + end + end end diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 026bdbd26d1..1c72513520d 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -1692,4 +1692,13 @@ describe MergeRequest do expect(subject.ref_fetched?).to be_falsey end end + + describe 'removing a merge request' do + it 'refreshes the number of open merge requests of the target project' do + project = subject.target_project + + expect { subject.destroy } + .to change { project.open_merge_requests_count }.from(1).to(0) + end + end end diff --git a/spec/services/issues/close_service_spec.rb b/spec/services/issues/close_service_spec.rb index a03f68434de..171f70c32a8 100644 --- a/spec/services/issues/close_service_spec.rb +++ b/spec/services/issues/close_service_spec.rb @@ -42,6 +42,11 @@ describe Issues::CloseService do service.execute(issue) end + it 'refreshes the number of open issues' do + expect { service.execute(issue) } + .to change { project.open_issues_count }.from(1).to(0) + end + it 'invalidates counter cache for assignees' do expect_any_instance_of(User).to receive(:invalidate_issue_cache_counts) diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb index 9b2d9e79f4f..78b11cd7991 100644 --- a/spec/services/issues/create_service_spec.rb +++ b/spec/services/issues/create_service_spec.rb @@ -35,6 +35,10 @@ describe Issues::CreateService do expect(issue.due_date).to eq Date.tomorrow end + it 'refreshes the number of open issues' do + expect { issue }.to change { project.open_issues_count }.from(0).to(1) + end + context 'when current user cannot admin issues in the project' do let(:guest) { create(:user) } diff --git a/spec/services/issues/reopen_service_spec.rb b/spec/services/issues/reopen_service_spec.rb index 205e9ebd237..48fc98b3b2f 100644 --- a/spec/services/issues/reopen_service_spec.rb +++ b/spec/services/issues/reopen_service_spec.rb @@ -34,6 +34,13 @@ describe Issues::ReopenService do described_class.new(project, user).execute(issue) end + it 'refreshes the number of opened issues' do + service = described_class.new(project, user) + + expect { service.execute(issue) } + .to change { project.open_issues_count }.from(0).to(1) + end + context 'when issue is not confidential' do it 'executes issue hooks' do expect(project).to receive(:execute_hooks).with(an_instance_of(Hash), :issue_hooks) diff --git a/spec/services/merge_requests/close_service_spec.rb b/spec/services/merge_requests/close_service_spec.rb index 04bf267d167..7e65369762c 100644 --- a/spec/services/merge_requests/close_service_spec.rb +++ b/spec/services/merge_requests/close_service_spec.rb @@ -52,6 +52,13 @@ describe MergeRequests::CloseService do end end + it 'refreshes the number of open merge requests for a valid MR' do + service = described_class.new(project, user, {}) + + expect { service.execute(merge_request) } + .to change { project.open_merge_requests_count }.from(1).to(0) + end + context 'current user is not authorized to close merge request' do before do perform_enqueued_jobs do diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb index a1f3bec42cc..d6409c0d625 100644 --- a/spec/services/merge_requests/create_service_spec.rb +++ b/spec/services/merge_requests/create_service_spec.rb @@ -18,31 +18,35 @@ describe MergeRequests::CreateService do end let(:service) { described_class.new(project, user, opts) } + let(:merge_request) { service.execute } before do project.team << [user, :master] project.team << [assignee, :developer] allow(service).to receive(:execute_hooks) - - @merge_request = service.execute end it 'creates an MR' do - expect(@merge_request).to be_valid - expect(@merge_request.title).to eq('Awesome merge_request') - expect(@merge_request.assignee).to be_nil - expect(@merge_request.merge_params['force_remove_source_branch']).to eq('1') + expect(merge_request).to be_valid + expect(merge_request.title).to eq('Awesome merge_request') + expect(merge_request.assignee).to be_nil + expect(merge_request.merge_params['force_remove_source_branch']).to eq('1') end it 'executes hooks with default action' do - expect(service).to have_received(:execute_hooks).with(@merge_request) + expect(service).to have_received(:execute_hooks).with(merge_request) + end + + it 'refreshes the number of open merge requests' do + expect { service.execute } + .to change { project.open_merge_requests_count }.from(0).to(1) end it 'does not creates todos' do attributes = { project: project, - target_id: @merge_request.id, - target_type: @merge_request.class.name + target_id: merge_request.id, + target_type: merge_request.class.name } expect(Todo.where(attributes).count).to be_zero @@ -51,8 +55,8 @@ describe MergeRequests::CreateService do it 'creates exactly 1 create MR event' do attributes = { action: Event::CREATED, - target_id: @merge_request.id, - target_type: @merge_request.class.name + target_id: merge_request.id, + target_type: merge_request.class.name } expect(Event.where(attributes).count).to eq(1) @@ -69,15 +73,15 @@ describe MergeRequests::CreateService do } end - it { expect(@merge_request.assignee).to eq assignee } + it { expect(merge_request.assignee).to eq assignee } it 'creates a todo for new assignee' do attributes = { project: project, author: user, user: assignee, - target_id: @merge_request.id, - target_type: @merge_request.class.name, + target_id: merge_request.id, + target_type: merge_request.class.name, action: Todo::ASSIGNED, state: :pending } diff --git a/spec/services/merge_requests/reopen_service_spec.rb b/spec/services/merge_requests/reopen_service_spec.rb index f02af0c582e..fa652611c6b 100644 --- a/spec/services/merge_requests/reopen_service_spec.rb +++ b/spec/services/merge_requests/reopen_service_spec.rb @@ -47,6 +47,13 @@ describe MergeRequests::ReopenService do end end + it 'refreshes the number of open merge requests for a valid MR' do + service = described_class.new(project, user, {}) + + expect { service.execute(merge_request) } + .to change { project.open_merge_requests_count }.from(0).to(1) + end + context 'current user is not authorized to reopen merge request' do before do perform_enqueued_jobs do diff --git a/spec/services/projects/count_service_spec.rb b/spec/services/projects/count_service_spec.rb new file mode 100644 index 00000000000..79b01e7620e --- /dev/null +++ b/spec/services/projects/count_service_spec.rb @@ -0,0 +1,73 @@ +require 'spec_helper' + +describe Projects::CountService do + let(:project) { build(:project, id: 1) } + let(:service) { described_class.new(project) } + + describe '#relation_for_count' do + it 'raises NotImplementedError' do + expect { service.relation_for_count }.to raise_error(NotImplementedError) + end + end + + describe '#count' do + before do + allow(service).to receive(:cache_key_name).and_return('count_service') + end + + it 'returns the number of rows' do + allow(service).to receive(:uncached_count).and_return(1) + + expect(service.count).to eq(1) + end + + it 'caches the number of rows', :use_clean_rails_memory_store_caching do + expect(service).to receive(:uncached_count).once.and_return(1) + + 2.times do + expect(service.count).to eq(1) + end + end + end + + describe '#refresh_cache', :use_clean_rails_memory_store_caching do + before do + allow(service).to receive(:cache_key_name).and_return('count_service') + end + + it 'refreshes the cache' do + expect(service).to receive(:uncached_count).once.and_return(1) + + service.refresh_cache + + expect(service.count).to eq(1) + end + end + + describe '#delete_cache', :use_clean_rails_memory_store_caching do + before do + allow(service).to receive(:cache_key_name).and_return('count_service') + end + + it 'removes the cache' do + expect(service).to receive(:uncached_count).twice.and_return(1) + + service.count + service.delete_cache + service.count + end + end + + describe '#cache_key_name' do + it 'raises NotImplementedError' do + expect { service.cache_key_name }.to raise_error(NotImplementedError) + end + end + + describe '#cache_key' do + it 'returns the cache key as an Array' do + allow(service).to receive(:cache_key_name).and_return('count_service') + expect(service.cache_key).to eq(['projects', 1, 'count_service']) + end + end +end diff --git a/spec/services/projects/forks_count_service_spec.rb b/spec/services/projects/forks_count_service_spec.rb index cf299c5d09b..9f8e7ee18a8 100644 --- a/spec/services/projects/forks_count_service_spec.rb +++ b/spec/services/projects/forks_count_service_spec.rb @@ -1,40 +1,14 @@ require 'spec_helper' describe Projects::ForksCountService do - let(:project) { build(:project, id: 42) } - let(:service) { described_class.new(project) } - describe '#count' do it 'returns the number of forks' do + project = build(:project, id: 42) + service = described_class.new(project) + allow(service).to receive(:uncached_count).and_return(1) expect(service.count).to eq(1) end - - it 'caches the forks count', :use_clean_rails_memory_store_caching do - expect(service).to receive(:uncached_count).once.and_return(1) - - 2.times { service.count } - end - end - - describe '#refresh_cache', :use_clean_rails_memory_store_caching do - it 'refreshes the cache' do - expect(service).to receive(:uncached_count).once.and_return(1) - - service.refresh_cache - - expect(service.count).to eq(1) - end - end - - describe '#delete_cache', :use_clean_rails_memory_store_caching do - it 'removes the cache' do - expect(service).to receive(:uncached_count).twice.and_return(1) - - service.count - service.delete_cache - service.count - end end end diff --git a/spec/services/projects/open_issues_count_service_spec.rb b/spec/services/projects/open_issues_count_service_spec.rb new file mode 100644 index 00000000000..f964f9972cd --- /dev/null +++ b/spec/services/projects/open_issues_count_service_spec.rb @@ -0,0 +1,21 @@ +require 'spec_helper' + +describe Projects::OpenIssuesCountService do + describe '#count' do + it 'returns the number of open issues' do + project = create(:project) + create(:issue, :opened, project: project) + + expect(described_class.new(project).count).to eq(1) + end + + it 'does not include confidential issues in the issue count' do + project = create(:project) + + create(:issue, :opened, project: project) + create(:issue, :opened, confidential: true, project: project) + + expect(described_class.new(project).count).to eq(1) + end + end +end diff --git a/spec/services/projects/open_merge_requests_count_service_spec.rb b/spec/services/projects/open_merge_requests_count_service_spec.rb new file mode 100644 index 00000000000..9f49b9ec6a2 --- /dev/null +++ b/spec/services/projects/open_merge_requests_count_service_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe Projects::OpenMergeRequestsCountService do + describe '#count' do + it 'returns the number of open merge requests' do + project = create(:project) + create(:merge_request, + :opened, + source_project: project, + target_project: project) + + expect(described_class.new(project).count).to eq(1) + end + end +end From 9240d3552a0850dc3a7a661012c51af12c9f6457 Mon Sep 17 00:00:00 2001 From: Ahmad Sherif Date: Wed, 23 Aug 2017 13:44:54 +0200 Subject: [PATCH 063/196] Properly encode Gitaly RawBlame request params --- lib/gitlab/gitaly_client/commit_service.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/gitlab/gitaly_client/commit_service.rb b/lib/gitlab/gitaly_client/commit_service.rb index 8fb7341b2dc..57f42bd35ee 100644 --- a/lib/gitlab/gitaly_client/commit_service.rb +++ b/lib/gitlab/gitaly_client/commit_service.rb @@ -175,8 +175,8 @@ module Gitlab def raw_blame(revision, path) request = Gitaly::RawBlameRequest.new( repository: @gitaly_repo, - revision: revision, - path: path + revision: GitalyClient.encode(revision), + path: GitalyClient.encode(path) ) response = GitalyClient.call(@repository.storage, :commit_service, :raw_blame, request) From f90659109487b0dd5303e5072feb86f10976ecae Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Wed, 23 Aug 2017 13:48:48 +0200 Subject: [PATCH 064/196] Fix cycle analytics test data generation and specs --- spec/support/cycle_analytics_helpers.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/support/cycle_analytics_helpers.rb b/spec/support/cycle_analytics_helpers.rb index 30911e7fa86..39586d37e93 100644 --- a/spec/support/cycle_analytics_helpers.rb +++ b/spec/support/cycle_analytics_helpers.rb @@ -78,6 +78,8 @@ module CycleAnalyticsHelpers @dummy_pipeline ||= Ci::Pipeline.new( sha: project.repository.commit('master').sha, + ref: 'master', + source: :push, project: project) end From 72018278a4bf79a3cdfa63258534d4bbc8ac8161 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Wed, 23 Aug 2017 11:28:52 +0200 Subject: [PATCH 065/196] Invalidate cache before cleaning db in tests after context --- spec/support/db_cleaner.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/support/db_cleaner.rb b/spec/support/db_cleaner.rb index b0f520d08e8..edaee03ea6c 100644 --- a/spec/support/db_cleaner.rb +++ b/spec/support/db_cleaner.rb @@ -4,18 +4,18 @@ RSpec.configure do |config| end config.append_after(:context) do - DatabaseCleaner.clean_with(:truncation) + DatabaseCleaner.clean_with(:truncation, cache_tables: false) end config.before(:each) do DatabaseCleaner.strategy = :transaction end - config.before(:each, js: true) do + config.before(:each, :js) do DatabaseCleaner.strategy = :truncation end - config.before(:each, truncate: true) do + config.before(:each, :truncate) do DatabaseCleaner.strategy = :truncation end From 438e18d8093afc31626408bb76954a7d9e635bbd Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Mon, 21 Aug 2017 23:22:17 +0900 Subject: [PATCH 066/196] Refurbish spec/features/runners_spec.rb --- app/views/projects/runners/_runner.html.haml | 2 +- spec/features/runners_spec.rb | 243 +++++++++---------- 2 files changed, 114 insertions(+), 131 deletions(-) diff --git a/app/views/projects/runners/_runner.html.haml b/app/views/projects/runners/_runner.html.haml index abc97bcdff5..25d862ab4de 100644 --- a/app/views/projects/runners/_runner.html.haml +++ b/app/views/projects/runners/_runner.html.haml @@ -8,7 +8,7 @@ - if runner.locked? = icon('lock', class: 'has-tooltip', title: 'Locked to current projects') - %small + %small.edit-runner = link_to edit_project_runner_path(@project, runner) do %i.fa.fa-edit.btn - else diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb index cac31c34ad1..4f87dbe392d 100644 --- a/spec/features/runners_spec.rb +++ b/spec/features/runners_spec.rb @@ -1,149 +1,132 @@ require 'spec_helper' -describe "Runners" do - let(:user) { create(:user) } +feature 'Runners' do + given(:user) { create(:user) } - before do + background do sign_in(user) end - describe "specific runners" do - before do - @project = FactoryGirl.create :project, shared_runners_enabled: false - @project.team << [user, :master] - - @project2 = FactoryGirl.create :project - @project2.team << [user, :master] - - @project3 = FactoryGirl.create :project - @project3.team << [user, :developer] - - @shared_runner = FactoryGirl.create :ci_runner, :shared - @specific_runner = FactoryGirl.create :ci_runner - @specific_runner2 = FactoryGirl.create :ci_runner - @specific_runner3 = FactoryGirl.create :ci_runner - @project.runners << @specific_runner - @project2.runners << @specific_runner2 - @project3.runners << @specific_runner3 - - visit runners_path(@project) - end - - before do - expect(page).not_to have_content(@specific_runner3.display_name) - expect(page).not_to have_content(@specific_runner3.display_name) - end - - it "places runners in right places" do - expect(page.find(".available-specific-runners")).to have_content(@specific_runner2.display_name) - expect(page.find(".activated-specific-runners")).to have_content(@specific_runner.display_name) - expect(page.find(".available-shared-runners")).to have_content(@shared_runner.display_name) - end - - it "enables specific runner for project" do - within ".available-specific-runners" do - click_on "Enable for this project" - end - - expect(page.find(".activated-specific-runners")).to have_content(@specific_runner2.display_name) - end - - it "disables specific runner for project" do - @project2.runners << @specific_runner - visit runners_path(@project) - - within ".activated-specific-runners" do - click_on "Disable for this project" - end - - expect(page.find(".available-specific-runners")).to have_content(@specific_runner.display_name) - end - - it "removes specific runner for project if this is last project for that runners" do - within ".activated-specific-runners" do - click_on "Remove Runner" - end - - expect(Ci::Runner.exists?(id: @specific_runner)).to be_falsey - end - end - - describe "shared runners" do - before do - @project = FactoryGirl.create :project, shared_runners_enabled: false - @project.team << [user, :master] - visit runners_path(@project) - end - - it "enables shared runners" do - click_on "Enable shared Runners" - expect(@project.reload.shared_runners_enabled).to be_truthy - end - end - - describe "shared runners description" do - let(:shared_runners_text) { 'custom **shared** runners description' } - let(:shared_runners_html) { 'custom shared runners description' } - - before do - stub_application_setting(shared_runners_text: shared_runners_text) - project = FactoryGirl.create :project, shared_runners_enabled: false - project.team << [user, :master] - visit runners_path(project) - end - - it "sees shared runners description" do - expect(page.find(".shared-runners-description")).to have_content(shared_runners_html) - end - end - - describe "show page" do - before do - @project = FactoryGirl.create :project - @project.team << [user, :master] - @specific_runner = FactoryGirl.create :ci_runner - @project.runners << @specific_runner - end - - it "shows runner information" do - visit runners_path(@project) - click_on @specific_runner.short_sha - expect(page).to have_content(@specific_runner.platform) - end - end - - feature 'configuring runners ability to picking untagged jobs' do + context 'when a project has enabled shared_runners' do given(:project) { create(:project) } - given(:runner) { create(:ci_runner) } - background do - project.team << [user, :master] - project.runners << runner - end + context 'when a specific runner is activated on the project' do + given(:specific_runner) { create(:ci_runner, :specific) } - scenario 'user checks default configuration' do - visit project_runner_path(project, runner) - - expect(page).to have_content 'Can run untagged jobs Yes' - end - - context 'when runner has tags' do - before do - runner.update_attribute(:tag_list, ['tag']) + background do + project.add_master(user) + project.runners << specific_runner end - scenario 'user wants to prevent runner from running untagged job' do + scenario 'user sees the specific runner' do visit runners_path(project) - page.within('.activated-specific-runners') do - first('small > a').click + + within '.activated-specific-runners' do + expect(page).to have_content(specific_runner.display_name) end - uncheck 'runner_run_untagged' - click_button 'Save changes' + click_on specific_runner.short_sha - expect(page).to have_content 'Can run untagged jobs No' - expect(runner.reload.run_untagged?).to eq false + expect(page).to have_content(specific_runner.platform) end + + scenario 'user removes an activated specific runner' do + visit runners_path(project) + + within '.activated-specific-runners' do + click_on 'Remove Runner' + end + + expect(page).to have_no_css('.activated-specific-runners') + end + + context 'when a runner has a tag' do + background do + specific_runner.update_attribute(:tag_list, ['tag']) + end + + scenario 'user edits runner not to run untagged jobs' do + visit runners_path(project) + + within '.activated-specific-runners' do + first('.edit-runner > a').click + end + + expect(page.find_field('runner[run_untagged]')).to be_checked + + uncheck 'runner_run_untagged' + click_button 'Save changes' + + expect(page).to have_content 'Can run untagged jobs No' + end + end + + context 'when a specific runner exists in another project' do + given(:another_project) { create(:project) } + given(:specific_runner2) { create(:ci_runner, :specific) } + + background do + another_project.add_master(user) + another_project.runners << specific_runner2 + end + + scenario 'user enables and disables a specific runner' do + visit runners_path(project) + + within '.available-specific-runners' do + click_on 'Enable for this project' + end + + expect(page.find('.activated-specific-runners')).to have_content(specific_runner2.display_name) + + within '.activated-specific-runners' do + click_on 'Disable for this project' + end + + expect(page.find('.activated-specific-runners')).not_to have_content(specific_runner2.display_name) + end + end + + context 'when a shared runner is activated on the project' do + given!(:shared_runner) { create(:ci_runner, :shared) } + + scenario 'user sees CI/CD setting page' do + visit runners_path(project) + + expect(page.find('.available-shared-runners')).to have_content(shared_runner.display_name) + end + end + end + + context 'when application settings have shared_runners_text' do + given(:shared_runners_text) { 'custom **shared** runners description' } + given(:shared_runners_html) { 'custom shared runners description' } + + background do + project.add_master(user) + stub_application_setting(shared_runners_text: shared_runners_text) + end + + scenario 'user sees shared runners description' do + visit runners_path(project) + + expect(page.find('.shared-runners-description')).to have_content(shared_runners_html) + end + end + end + + context 'when a project has disabled shared_runners' do + given(:project) { create(:project, shared_runners_enabled: false) } + + background do + project.add_master(user) + end + + scenario 'user enables shared runners' do + visit runners_path(project) + + click_on 'Enable shared Runners' + expect(page.find('.shared-runners-description')).to have_content('Disable shared Runners') end end end From 3c2bcf258ce2171617c0b89a2343a96586b750d2 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Wed, 23 Aug 2017 14:20:48 +0200 Subject: [PATCH 067/196] Fix feature specs for pages deployment --- features/steps/project/pages.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/features/steps/project/pages.rb b/features/steps/project/pages.rb index 275fb4fc010..bb69c0d6e99 100644 --- a/features/steps/project/pages.rb +++ b/features/steps/project/pages.rb @@ -35,7 +35,10 @@ class Spinach::Features::ProjectPages < Spinach::FeatureSteps end step 'pages are deployed' do - pipeline = @project.pipelines.create(ref: 'HEAD', sha: @project.commit('HEAD').sha) + pipeline = @project.pipelines.create(ref: 'HEAD', + sha: @project.commit('HEAD').sha, + source: :push) + build = build(:ci_build, project: @project, pipeline: pipeline, @@ -43,6 +46,7 @@ class Spinach::Features::ProjectPages < Spinach::FeatureSteps artifacts_file: fixture_file_upload(Rails.root + 'spec/fixtures/pages.zip'), artifacts_metadata: fixture_file_upload(Rails.root + 'spec/fixtures/pages.zip.meta') ) + result = ::Projects::UpdatePagesService.new(@project, build).execute expect(result[:status]).to eq(:success) end From 3eba43b62dc825dd8a40f74fe027bb613b8ed2a8 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Wed, 23 Aug 2017 14:48:26 +0200 Subject: [PATCH 068/196] Adjust a range and a size in stages statuses migration --- db/post_migrate/20170711145558_migrate_stages_statuses.rb | 8 ++++---- spec/migrations/migrate_stages_statuses_spec.rb | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/db/post_migrate/20170711145558_migrate_stages_statuses.rb b/db/post_migrate/20170711145558_migrate_stages_statuses.rb index 5a24fb1307f..7eb577ff3b2 100644 --- a/db/post_migrate/20170711145558_migrate_stages_statuses.rb +++ b/db/post_migrate/20170711145558_migrate_stages_statuses.rb @@ -6,7 +6,7 @@ class MigrateStagesStatuses < ActiveRecord::Migration disable_ddl_transaction! BATCH_SIZE = 10000 - RANGE_SIZE = 1000 + RANGE_SIZE = 500 MIGRATION = 'MigrateStageStatus'.freeze class Stage < ActiveRecord::Base @@ -17,10 +17,10 @@ class MigrateStagesStatuses < ActiveRecord::Migration def up Stage.where(status: nil).each_batch(of: BATCH_SIZE) do |relation, index| relation.each_batch(of: RANGE_SIZE) do |batch| - range = relation.pluck('MIN(id)', 'MAX(id)').first - schedule = index * 5.minutes + range = batch.pluck('MIN(id)', 'MAX(id)').first + delay = index * 5.minutes - BackgroundMigrationWorker.perform_in(schedule, MIGRATION, range) + BackgroundMigrationWorker.perform_in(delay, MIGRATION, range) end end end diff --git a/spec/migrations/migrate_stages_statuses_spec.rb b/spec/migrations/migrate_stages_statuses_spec.rb index 4102d57e368..094c9bc604e 100644 --- a/spec/migrations/migrate_stages_statuses_spec.rb +++ b/spec/migrations/migrate_stages_statuses_spec.rb @@ -12,7 +12,7 @@ describe MigrateStagesStatuses, :migration do before do stub_const("#{described_class.name}::BATCH_SIZE", 2) - stub_const("#{described_class.name}::RANGE_SIZE", 2) + stub_const("#{described_class.name}::RANGE_SIZE", 1) projects.create!(id: 1, name: 'gitlab1', path: 'gitlab1') projects.create!(id: 2, name: 'gitlab2', path: 'gitlab2') @@ -50,9 +50,10 @@ describe MigrateStagesStatuses, :migration do Timecop.freeze do migrate! - expect(described_class::MIGRATION).to be_scheduled_migration(5.minutes, 1, 2) + expect(described_class::MIGRATION).to be_scheduled_migration(5.minutes, 1, 1) + expect(described_class::MIGRATION).to be_scheduled_migration(5.minutes, 2, 2) expect(described_class::MIGRATION).to be_scheduled_migration(10.minutes, 3, 3) - expect(BackgroundMigrationWorker.jobs.size).to eq 2 + expect(BackgroundMigrationWorker.jobs.size).to eq 3 end end end From fab3df77cf72126f4fad95dc558fb5bf46fd20e0 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Wed, 23 Aug 2017 21:58:45 +0900 Subject: [PATCH 069/196] Fix tests --- spec/features/runners_spec.rb | 65 ++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb index 4f87dbe392d..785cfeb34bd 100644 --- a/spec/features/runners_spec.rb +++ b/spec/features/runners_spec.rb @@ -10,11 +10,14 @@ feature 'Runners' do context 'when a project has enabled shared_runners' do given(:project) { create(:project) } + background do + project.add_master(user) + end + context 'when a specific runner is activated on the project' do given(:specific_runner) { create(:ci_runner, :specific) } background do - project.add_master(user) project.runners << specific_runner end @@ -30,19 +33,19 @@ feature 'Runners' do expect(page).to have_content(specific_runner.platform) end - scenario 'user removes an activated specific runner' do + scenario 'user removes an activated specific runner if this is last project for that runners' do visit runners_path(project) within '.activated-specific-runners' do click_on 'Remove Runner' end - expect(page).to have_no_css('.activated-specific-runners') + expect(page).not_to have_content(specific_runner.display_name) end context 'when a runner has a tag' do background do - specific_runner.update_attribute(:tag_list, ['tag']) + specific_runner.update(tag_list: ['tag']) end scenario 'user edits runner not to run untagged jobs' do @@ -61,32 +64,6 @@ feature 'Runners' do end end - context 'when a specific runner exists in another project' do - given(:another_project) { create(:project) } - given(:specific_runner2) { create(:ci_runner, :specific) } - - background do - another_project.add_master(user) - another_project.runners << specific_runner2 - end - - scenario 'user enables and disables a specific runner' do - visit runners_path(project) - - within '.available-specific-runners' do - click_on 'Enable for this project' - end - - expect(page.find('.activated-specific-runners')).to have_content(specific_runner2.display_name) - - within '.activated-specific-runners' do - click_on 'Disable for this project' - end - - expect(page.find('.activated-specific-runners')).not_to have_content(specific_runner2.display_name) - end - end - context 'when a shared runner is activated on the project' do given!(:shared_runner) { create(:ci_runner, :shared) } @@ -98,12 +75,37 @@ feature 'Runners' do end end + context 'when a specific runner exists in another project' do + given(:another_project) { create(:project) } + given(:specific_runner) { create(:ci_runner, :specific) } + + background do + another_project.add_master(user) + another_project.runners << specific_runner + end + + scenario 'user enables and disables a specific runner' do + visit runners_path(project) + + within '.available-specific-runners' do + click_on 'Enable for this project' + end + + expect(page.find('.activated-specific-runners')).to have_content(specific_runner.display_name) + + within '.activated-specific-runners' do + click_on 'Disable for this project' + end + + expect(page.find('.available-specific-runners')).to have_content(specific_runner.display_name) + end + end + context 'when application settings have shared_runners_text' do given(:shared_runners_text) { 'custom **shared** runners description' } given(:shared_runners_html) { 'custom shared runners description' } background do - project.add_master(user) stub_application_setting(shared_runners_text: shared_runners_text) end @@ -126,6 +128,7 @@ feature 'Runners' do visit runners_path(project) click_on 'Enable shared Runners' + expect(page.find('.shared-runners-description')).to have_content('Disable shared Runners') end end From b47798664d8653acbebfd65ad26fb72b25454e99 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Wed, 23 Aug 2017 14:03:49 +0100 Subject: [PATCH 070/196] Update licensing query guidelines --- doc/development/licensing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/development/licensing.md b/doc/development/licensing.md index 1f115059fb8..2b16dfe0e7c 100644 --- a/doc/development/licensing.md +++ b/doc/development/licensing.md @@ -66,7 +66,7 @@ Libraries with the following licenses are unacceptable for use: ## Requesting Approval for Licenses -Libraries that are not listed in the [Acceptable Licenses][Acceptable-Licenses] or [Unacceptable Licenses][Unacceptable-Licenses] list can be submitted to the legal team for review. Please create an issue in the [Organization Repository][Org-Repo] and cc `@gl-legal`. After a decision has been made, the original requestor is responsible for updating this document. +Libraries that are not listed in the [Acceptable Licenses][Acceptable-Licenses] or [Unacceptable Licenses][Unacceptable-Licenses] list can be submitted to the legal team for review. Please email `legal@gitlab.com` with the details. After a decision has been made, the original requestor is responsible for updating this document. ## Notes From 9eb28bbf218d8d7bfdfc0db4bc49e59004c847e0 Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Wed, 23 Aug 2017 14:44:49 +0100 Subject: [PATCH 071/196] Added repo_service_spec for commitFlash and corrected repo_commit-Secion api spec --- .../javascripts/repo/services/repo_service.js | 16 +++--- .../components/repo_commit_section_spec.js | 2 +- .../repo/services/repo_service_spec.js | 50 +++++++++++++++++++ 3 files changed, 60 insertions(+), 8 deletions(-) diff --git a/app/assets/javascripts/repo/services/repo_service.js b/app/assets/javascripts/repo/services/repo_service.js index a8a4b419ae8..af83497fa39 100644 --- a/app/assets/javascripts/repo/services/repo_service.js +++ b/app/assets/javascripts/repo/services/repo_service.js @@ -67,13 +67,15 @@ const RepoService = { commitFiles(payload) { return Api.commitMultiple(Store.projectId, payload) - .then((data) => { - if (data.short_id && data.stats) { - Flash(`Your changes have been committed. Commit ${data.short_id} with ${data.stats.additions} additions, ${data.stats.deletions} deletions.`, 'notice'); - } else { - Flash(data.message); - } - }); + .then(this.commitFlash); + }, + + commitFlash(data) { + if (data.short_id && data.stats) { + window.Flash(`Your changes have been committed. Commit ${data.short_id} with ${data.stats.additions} additions, ${data.stats.deletions} deletions.`, 'notice'); + } else { + window.Flash(data.message); + } }, }; diff --git a/spec/javascripts/repo/components/repo_commit_section_spec.js b/spec/javascripts/repo/components/repo_commit_section_spec.js index 1cbb4914005..e604dcc152d 100644 --- a/spec/javascripts/repo/components/repo_commit_section_spec.js +++ b/spec/javascripts/repo/components/repo_commit_section_spec.js @@ -3,7 +3,7 @@ import repoCommitSection from '~/repo/components/repo_commit_section.vue'; import RepoStore from '~/repo/stores/repo_store'; import RepoService from '~/repo/services/repo_service'; -fdescribe('RepoCommitSection', () => { +describe('RepoCommitSection', () => { const branch = 'master'; const projectUrl = 'projectUrl'; const changedFiles = [{ diff --git a/spec/javascripts/repo/services/repo_service_spec.js b/spec/javascripts/repo/services/repo_service_spec.js index d74e6a67b1e..6f530770525 100644 --- a/spec/javascripts/repo/services/repo_service_spec.js +++ b/spec/javascripts/repo/services/repo_service_spec.js @@ -1,5 +1,7 @@ import axios from 'axios'; import RepoService from '~/repo/services/repo_service'; +import RepoStore from '~/repo/stores/repo_store'; +import Api from '~/api'; describe('RepoService', () => { it('has default json format param', () => { @@ -118,4 +120,52 @@ describe('RepoService', () => { }).catch(done.fail); }); }); + + describe('commitFiles', () => { + it('calls commitMultiple and .then commitFlash', (done) => { + const projectId = 'projectId'; + const payload = {}; + RepoStore.projectId = projectId; + + spyOn(Api, 'commitMultiple').and.returnValue(Promise.resolve()); + spyOn(RepoService, 'commitFlash'); + + const apiPromise = RepoService.commitFiles(payload); + + expect(Api.commitMultiple).toHaveBeenCalledWith(projectId, payload); + + apiPromise.then(() => { + expect(RepoService.commitFlash).toHaveBeenCalled(); + done(); + }).catch(done.fail); + }); + }); + + describe('commitFlash', () => { + it('calls Flash with data.message', () => { + const data = { + message: 'message', + }; + spyOn(window, 'Flash'); + + RepoService.commitFlash(data); + + expect(window.Flash).toHaveBeenCalledWith(data.message); + }); + + it('calls Flash with success string if short_id and stats', () => { + const data = { + short_id: 'short_id', + stats: { + additions: '4', + deletions: '5', + }, + }; + spyOn(window, 'Flash'); + + RepoService.commitFlash(data); + + expect(window.Flash).toHaveBeenCalledWith(`Your changes have been committed. Commit ${data.short_id} with ${data.stats.additions} additions, ${data.stats.deletions} deletions.`, 'notice'); + }); + }); }); From c184a135f2a17a4bcf6189ae92e6cedb31855033 Mon Sep 17 00:00:00 2001 From: Simon Knox Date: Wed, 23 Aug 2017 23:45:38 +1000 Subject: [PATCH 072/196] Update CHANGELOG.md for 9.5.1 [ci skip] --- CHANGELOG.md | 8 ++++++++ changelogs/unreleased/13719-git-gc-timeout.yml | 3 --- changelogs/unreleased/dm-commit-cache-i18n.yml | 5 ----- changelogs/unreleased/fix-broadcast-message-caching.yml | 5 ----- .../fix-gb-fix-head-pipeline-when-pipeline-has-errors.yml | 5 ----- changelogs/unreleased/only-limit-fetch-when-requested.yml | 5 ----- 6 files changed, 8 insertions(+), 23 deletions(-) delete mode 100644 changelogs/unreleased/13719-git-gc-timeout.yml delete mode 100644 changelogs/unreleased/dm-commit-cache-i18n.yml delete mode 100644 changelogs/unreleased/fix-broadcast-message-caching.yml delete mode 100644 changelogs/unreleased/fix-gb-fix-head-pipeline-when-pipeline-has-errors.yml delete mode 100644 changelogs/unreleased/only-limit-fetch-when-requested.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d969164cfe..d32b6989388 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ documentation](doc/development/changelog.md) for instructions on adding your own entry. +## 9.5.1 (2017-08-23) + +- [FIXED] Fix merge request pipeline status when pipeline has errors. !13664 +- [FIXED] Commit rows would occasionally render with the wrong language. +- [FIXED] Fix caching of future broadcast messages. +- [FIXED] Only require Sidekiq throttling library when enabled, to reduce cache misses. +- Raise Housekeeping timeout to 24 hours. !13719 + ## 9.5.0 (2017-08-22) - [FIXED] Fix timeouts when creating projects in groups with many members. !13508 diff --git a/changelogs/unreleased/13719-git-gc-timeout.yml b/changelogs/unreleased/13719-git-gc-timeout.yml deleted file mode 100644 index 13cf97ec764..00000000000 --- a/changelogs/unreleased/13719-git-gc-timeout.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: "Raise Housekeeping timeout to 24 hours" -merge_request: 13719 diff --git a/changelogs/unreleased/dm-commit-cache-i18n.yml b/changelogs/unreleased/dm-commit-cache-i18n.yml deleted file mode 100644 index d47226fd408..00000000000 --- a/changelogs/unreleased/dm-commit-cache-i18n.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Commit rows would occasionally render with the wrong language -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/fix-broadcast-message-caching.yml b/changelogs/unreleased/fix-broadcast-message-caching.yml deleted file mode 100644 index 58ec1766cfd..00000000000 --- a/changelogs/unreleased/fix-broadcast-message-caching.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix caching of future broadcast messages -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/fix-gb-fix-head-pipeline-when-pipeline-has-errors.yml b/changelogs/unreleased/fix-gb-fix-head-pipeline-when-pipeline-has-errors.yml deleted file mode 100644 index ede8031a501..00000000000 --- a/changelogs/unreleased/fix-gb-fix-head-pipeline-when-pipeline-has-errors.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix merge request pipeline status when pipeline has errors -merge_request: 13664 -author: -type: fixed diff --git a/changelogs/unreleased/only-limit-fetch-when-requested.yml b/changelogs/unreleased/only-limit-fetch-when-requested.yml deleted file mode 100644 index d9acdf56511..00000000000 --- a/changelogs/unreleased/only-limit-fetch-when-requested.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Only require Sidekiq throttling library when enabled, to reduce cache misses -merge_request: -author: -type: fixed From 0dd71ed4a8901d34dda5b485b75afe595658da53 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Gray Date: Wed, 23 Aug 2017 10:09:22 -0500 Subject: [PATCH 073/196] Fix alignment of gpg status --- app/assets/stylesheets/pages/commits.scss | 5 +++-- app/helpers/commits_helper.rb | 2 +- app/views/projects/commits/_commit.html.haml | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss index 46fbfe5f91e..d0d11b4d71c 100644 --- a/app/assets/stylesheets/pages/commits.scss +++ b/app/assets/stylesheets/pages/commits.scss @@ -286,6 +286,9 @@ .gpg-status-box { + padding: 2px 10px; + margin-right: $gl-padding; + &:empty { display: none; } @@ -314,7 +317,6 @@ &.valid { svg { border: 1px solid $brand-success; - fill: $brand-success; } } @@ -322,7 +324,6 @@ &.invalid { svg { border: 1px solid $common-gray-light; - fill: $common-gray-light; } } diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index 72e26b64e60..9651f9733f9 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -114,7 +114,7 @@ module CommitsHelper end def commit_signature_badge_classes(additional_classes) - %w(btn status-box gpg-status-box) + Array(additional_classes) + %w(btn gpg-status-box) + Array(additional_classes) end protected diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml index 7e8a5a38086..1214aabe837 100644 --- a/app/views/projects/commits/_commit.html.haml +++ b/app/views/projects/commits/_commit.html.haml @@ -37,14 +37,14 @@ .commit-actions.hidden-xs - - if commit.status(ref) - = render_commit_status(commit, ref: ref) - - if request.xhr? = render partial: 'projects/commit/signature', object: commit.signature - else = render partial: 'projects/commit/ajax_signature', locals: { commit: commit } + - if commit.status(ref) + = render_commit_status(commit, ref: ref) + = link_to commit.short_id, project_commit_path(project, commit), class: "commit-sha btn btn-transparent" = clipboard_button(text: commit.id, title: _("Copy commit SHA to clipboard")) = link_to_browse_code(project, commit) From 961da7d0a7024628ec87c02c158a147dd64b3317 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Wed, 23 Aug 2017 17:23:28 +0200 Subject: [PATCH 074/196] Add tests for Committer#== --- spec/lib/gitlab/git/committer_spec.rb | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 spec/lib/gitlab/git/committer_spec.rb diff --git a/spec/lib/gitlab/git/committer_spec.rb b/spec/lib/gitlab/git/committer_spec.rb new file mode 100644 index 00000000000..b0ddbb51449 --- /dev/null +++ b/spec/lib/gitlab/git/committer_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe Gitlab::Git::Committer do + let(:name) { 'Jane Doe' } + let(:email) { 'janedoe@example.com' } + let(:gl_id) { 'user-123' } + + subject { described_class.new(name, email, gl_id) } + + describe '#==' do + def eq_other(name, email, gl_id) + eq(described_class.new(name, email, gl_id)) + end + + it { expect(subject).to eq_other(name, email, gl_id) } + + it { expect(subject).not_to eq_other(nil, nil, nil) } + it { expect(subject).not_to eq_other(name + 'x', email, gl_id) } + it { expect(subject).not_to eq_other(name, email + 'x', gl_id) } + it { expect(subject).not_to eq_other(name, email, gl_id + 'x') } + end +end From 3611b664a94635e950c9d281bbbc8e2360a56fa3 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Wed, 23 Aug 2017 09:02:46 +0200 Subject: [PATCH 075/196] Fix blank button not resetting project template value The button didn't override a value, so the old value was posted again. --- app/views/projects/_project_templates.html.haml | 2 +- changelogs/unreleased/zj-fix-fe-blank-button.yml | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/zj-fix-fe-blank-button.yml diff --git a/app/views/projects/_project_templates.html.haml b/app/views/projects/_project_templates.html.haml index 97cf13df070..5638b7da1b0 100644 --- a/app/views/projects/_project_templates.html.haml +++ b/app/views/projects/_project_templates.html.haml @@ -1,6 +1,6 @@ .project-templates-buttons.import-buttons{ data: { toggle: "buttons" } } .btn.blank-option.active - %input{ type: "radio", autocomplete: "off", name: "project_templates", id: "blank", checked: "true" } + %input{ type: "radio", autocomplete: "off", name: "project[template_name]", id: "blank", checked: "true", value: "" } = icon('file-o', class: 'btn-template-icon') Blank - Gitlab::ProjectTemplate.all.each do |template| diff --git a/changelogs/unreleased/zj-fix-fe-blank-button.yml b/changelogs/unreleased/zj-fix-fe-blank-button.yml new file mode 100644 index 00000000000..2165d4186c1 --- /dev/null +++ b/changelogs/unreleased/zj-fix-fe-blank-button.yml @@ -0,0 +1,5 @@ +--- +title: Fix new project form not resetting the template value +merge_request: +author: +type: fixed From f5046e5258c9e53b11816490fbdca4134dd5ad0c Mon Sep 17 00:00:00 2001 From: haseeb Date: Wed, 23 Aug 2017 21:43:23 +0530 Subject: [PATCH 076/196] [ci skip] changelog entry added for full merge request ref changes --- app/models/merge_request.rb | 1 - .../36262_merge_request_reference_in_merge_commit_global.yml | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/36262_merge_request_reference_in_merge_commit_global.yml diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index de0d541f1c7..a156ef672df 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -682,7 +682,6 @@ class MergeRequest < ActiveRecord::Base if !include_description && closes_issues_references.present? message << "Closes #{closes_issues_references.to_sentence}" end - message << "#{description}" if include_description && description.present? message << "See merge request #{to_reference(full: true)}" diff --git a/changelogs/unreleased/36262_merge_request_reference_in_merge_commit_global.yml b/changelogs/unreleased/36262_merge_request_reference_in_merge_commit_global.yml new file mode 100644 index 00000000000..356857d6e8a --- /dev/null +++ b/changelogs/unreleased/36262_merge_request_reference_in_merge_commit_global.yml @@ -0,0 +1,5 @@ +--- +title: Merge request reference in merge commit changed to full reference +merge_request: 13518 +author: haseebeqx +type: fixed From 502d6464b07154d74eecbeddbf2cd6dba841380f Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Wed, 23 Aug 2017 13:01:11 +0100 Subject: [PATCH 077/196] Allow v4 API GET requests for groups to be unauthenticated --- lib/api/groups.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/api/groups.rb b/lib/api/groups.rb index 49c3b2278c7..892fd239df4 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -2,7 +2,7 @@ module API class Groups < Grape::API include PaginationParams - before { authenticate! } + before { authenticate_non_get! } helpers do params :optional_params_ce do @@ -48,10 +48,10 @@ module API end get do groups = if params[:owned] - current_user.owned_groups - elsif current_user.admin + current_user ? current_user.owned_groups : Group.none + elsif current_user&.admin? Group.all - elsif params[:all_available] + elsif params[:all_available] || current_user.nil? GroupsFinder.new(current_user).execute else current_user.groups From f67faf6a1626a245ec62f82bd89486ac76953b44 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Wed, 23 Aug 2017 19:44:10 +0200 Subject: [PATCH 078/196] Update templates to include header in the README --- vendor/project_templates/express.tar.gz | Bin 4572 -> 5645 bytes vendor/project_templates/rails.tar.gz | Bin 23749 -> 24777 bytes vendor/project_templates/spring.tar.gz | Bin 49882 -> 50845 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/vendor/project_templates/express.tar.gz b/vendor/project_templates/express.tar.gz index 6353f6605d58513ba37e85abacf1fd55753f4050..302a74637b218775aed2c8d063bab5d3a6169ebe 100644 GIT binary patch literal 5645 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 nK~dr7_y3LBXN-q6mbP3k1?g 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 ADF6Tf diff --git a/vendor/project_templates/spring.tar.gz b/vendor/project_templates/spring.tar.gz index d7c0ab74d01154ca70226d43cb72a3302da85209..02006b14406ff19a913d5d077e91f2fad2c1823c 100644 GIT binary patch delta 34673 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 JiuM5T001+eT+9Ff delta 33712 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 kF984m00000000000000000000004f>7fRi7JOJ Date: Wed, 23 Aug 2017 14:34:32 -0500 Subject: [PATCH 079/196] Hide group title on sidebar collapse; use more generic class for titles --- app/assets/stylesheets/new_sidebar.scss | 5 ++--- app/views/layouts/nav/_new_admin_sidebar.html.haml | 2 +- app/views/layouts/nav/_new_group_sidebar.html.haml | 2 +- app/views/layouts/nav/_new_profile_sidebar.html.haml | 2 +- app/views/layouts/nav/_new_project_sidebar.html.haml | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/app/assets/stylesheets/new_sidebar.scss b/app/assets/stylesheets/new_sidebar.scss index cee5b22adb9..25c6715899b 100644 --- a/app/assets/stylesheets/new_sidebar.scss +++ b/app/assets/stylesheets/new_sidebar.scss @@ -70,8 +70,7 @@ $new-sidebar-collapsed-width: 50px; background-color: $white-light; } - .project-title, - .group-title { + .sidebar-context-title { overflow: hidden; text-overflow: ellipsis; } @@ -109,7 +108,7 @@ $new-sidebar-collapsed-width: 50px; } .badge, - .project-title { + .sidebar-context-title { display: none; } diff --git a/app/views/layouts/nav/_new_admin_sidebar.html.haml b/app/views/layouts/nav/_new_admin_sidebar.html.haml index 3cbcd841aff..1c3fd4a082c 100644 --- a/app/views/layouts/nav/_new_admin_sidebar.html.haml +++ b/app/views/layouts/nav/_new_admin_sidebar.html.haml @@ -4,7 +4,7 @@ = link_to admin_root_path, title: 'Admin Overview' do .avatar-container.s40.settings-avatar = icon('wrench') - .project-title Admin Area + .sidebar-context-title Admin Area %ul.sidebar-top-level-items = nav_link(controller: %w(dashboard admin projects users groups jobs runners cohorts), html_options: {class: 'home'}) do = link_to admin_root_path, title: 'Overview', class: 'shortcuts-tree' do diff --git a/app/views/layouts/nav/_new_group_sidebar.html.haml b/app/views/layouts/nav/_new_group_sidebar.html.haml index ed5793f09fe..d90aea2e361 100644 --- a/app/views/layouts/nav/_new_group_sidebar.html.haml +++ b/app/views/layouts/nav/_new_group_sidebar.html.haml @@ -4,7 +4,7 @@ = link_to group_path(@group), title: @group.name do .avatar-container.s40.group-avatar = image_tag group_icon(@group), class: "avatar s40 avatar-tile" - .group-title + .sidebar-context-title = @group.name %ul.sidebar-top-level-items = nav_link(path: ['groups#show', 'groups#activity', 'groups#subgroups'], html_options: { class: 'home' }) do diff --git a/app/views/layouts/nav/_new_profile_sidebar.html.haml b/app/views/layouts/nav/_new_profile_sidebar.html.haml index 4234df56d1d..85b2c7630c8 100644 --- a/app/views/layouts/nav/_new_profile_sidebar.html.haml +++ b/app/views/layouts/nav/_new_profile_sidebar.html.haml @@ -4,7 +4,7 @@ = link_to profile_path, title: 'Profile Settings' do .avatar-container.s40.settings-avatar = icon('user') - .project-title User Settings + .sidebar-context-title User Settings %ul.sidebar-top-level-items = nav_link(path: 'profiles#show', html_options: {class: 'home'}) do = link_to profile_path, title: 'Profile Settings' do diff --git a/app/views/layouts/nav/_new_project_sidebar.html.haml b/app/views/layouts/nav/_new_project_sidebar.html.haml index 0ef81375c3a..9c7d9826f56 100644 --- a/app/views/layouts/nav/_new_project_sidebar.html.haml +++ b/app/views/layouts/nav/_new_project_sidebar.html.haml @@ -5,7 +5,7 @@ = link_to project_path(@project), title: @project.name do .avatar-container.s40.project-avatar = project_icon(@project, alt: @project.name, class: 'avatar s40 avatar-tile') - .project-title + .sidebar-context-title = @project.name %ul.sidebar-top-level-items = nav_link(path: ['projects#show', 'projects#activity', 'cycle_analytics#show'], html_options: { class: 'home' }) do From c1cf5f41018dd4cf0523c6a80c8617651d88658c Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 23 Aug 2017 19:18:13 +0200 Subject: [PATCH 080/196] Support simple string LDAP attribute specifications, and search for name rather than username attributes --- changelogs/unreleased/dm-ldap-adapter-attributes.yml | 6 ++++++ lib/gitlab/ldap/adapter.rb | 6 +----- lib/gitlab/ldap/person.rb | 9 +++++++++ spec/lib/gitlab/ldap/adapter_spec.rb | 6 +++--- 4 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 changelogs/unreleased/dm-ldap-adapter-attributes.yml diff --git a/changelogs/unreleased/dm-ldap-adapter-attributes.yml b/changelogs/unreleased/dm-ldap-adapter-attributes.yml new file mode 100644 index 00000000000..edd68ef08e7 --- /dev/null +++ b/changelogs/unreleased/dm-ldap-adapter-attributes.yml @@ -0,0 +1,6 @@ +--- +title: Fix signing in using LDAP when attribute mapping uses simple strings instead + of arrays +merge_request: +author: +type: fixed diff --git a/lib/gitlab/ldap/adapter.rb b/lib/gitlab/ldap/adapter.rb index 8867a91c244..cd7e4ca7b7e 100644 --- a/lib/gitlab/ldap/adapter.rb +++ b/lib/gitlab/ldap/adapter.rb @@ -73,7 +73,7 @@ module Gitlab private def user_options(field, value, limit) - options = { attributes: user_attributes } + options = { attributes: Gitlab::LDAP::Person.ldap_attributes(config).compact.uniq } options[:size] = limit if limit if field.to_sym == :dn @@ -99,10 +99,6 @@ module Gitlab filter end end - - def user_attributes - %W(#{config.uid} cn dn) + config.attributes['username'] + config.attributes['email'] - end end end end diff --git a/lib/gitlab/ldap/person.rb b/lib/gitlab/ldap/person.rb index e138b466a34..4d6f8ac79de 100644 --- a/lib/gitlab/ldap/person.rb +++ b/lib/gitlab/ldap/person.rb @@ -21,6 +21,15 @@ module Gitlab adapter.dn_matches_filter?(dn, AD_USER_DISABLED) end + def self.ldap_attributes(config) + [ + 'dn', # Used in `dn` + config.uid, # Used in `uid` + *config.attributes['name'], # Used in `name` + *config.attributes['email'] # Used in `email` + ] + end + def initialize(entry, provider) Rails.logger.debug { "Instantiating #{self.class.name} with LDIF:\n#{entry.to_ldif}" } @entry = entry diff --git a/spec/lib/gitlab/ldap/adapter_spec.rb b/spec/lib/gitlab/ldap/adapter_spec.rb index d17d440d833..d9ddb4326be 100644 --- a/spec/lib/gitlab/ldap/adapter_spec.rb +++ b/spec/lib/gitlab/ldap/adapter_spec.rb @@ -16,7 +16,7 @@ describe Gitlab::LDAP::Adapter do expect(adapter).to receive(:ldap_search) do |arg| expect(arg[:filter].to_s).to eq('(uid=johndoe)') expect(arg[:base]).to eq('dc=example,dc=com') - expect(arg[:attributes]).to match(%w{uid cn dn uid userid sAMAccountName mail email userPrincipalName}) + expect(arg[:attributes]).to match(%w{dn uid cn mail email userPrincipalName}) end.and_return({}) adapter.users('uid', 'johndoe') @@ -26,7 +26,7 @@ describe Gitlab::LDAP::Adapter do expect(adapter).to receive(:ldap_search).with( base: 'uid=johndoe,ou=users,dc=example,dc=com', scope: Net::LDAP::SearchScope_BaseObject, - attributes: %w{uid cn dn uid userid sAMAccountName mail email userPrincipalName}, + attributes: %w{dn uid cn mail email userPrincipalName}, filter: nil ).and_return({}) @@ -63,7 +63,7 @@ describe Gitlab::LDAP::Adapter do it 'uses the right uid attribute when non-default' do stub_ldap_config(uid: 'sAMAccountName') expect(adapter).to receive(:ldap_search).with( - hash_including(attributes: %w{sAMAccountName cn dn uid userid sAMAccountName mail email userPrincipalName}) + hash_including(attributes: %w{dn sAMAccountName cn mail email userPrincipalName}) ).and_return({}) adapter.users('sAMAccountName', 'johndoe') From e6c96c6ed6cb51e25974476babae1f01226b4994 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Wed, 23 Aug 2017 18:08:04 -0400 Subject: [PATCH 081/196] Remove underscore-rails gem We now manage this dependency in Yarn. --- Gemfile | 3 --- Gemfile.lock | 2 -- 2 files changed, 5 deletions(-) diff --git a/Gemfile b/Gemfile index 72fc2de426e..f71cd492387 100644 --- a/Gemfile +++ b/Gemfile @@ -207,9 +207,6 @@ gem 'kubeclient', '~> 2.2.0' # d3 gem 'd3_rails', '~> 3.5.0' -# underscore-rails -gem 'underscore-rails', '~> 1.8.0' - # Sanitize user input gem 'sanitize', '~> 2.0' gem 'babosa', '~> 1.0.2' diff --git a/Gemfile.lock b/Gemfile.lock index 7d3c53ee010..17bf48befac 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -899,7 +899,6 @@ GEM uglifier (2.7.2) execjs (>= 0.3.0) json (>= 1.8.0) - underscore-rails (1.8.3) unf (0.1.4) unf_ext unf_ext (0.0.7.2) @@ -1163,7 +1162,6 @@ DEPENDENCIES truncato (~> 0.7.8) u2f (~> 0.2.1) uglifier (~> 2.7.2) - underscore-rails (~> 1.8.0) unf (~> 0.1.4) unicorn (~> 5.1.0) unicorn-worker-killer (~> 0.4.4) From 37904108b965eecabdbe631ca2f3465a3cf18a1e Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 23 Aug 2017 22:06:42 -0700 Subject: [PATCH 082/196] Fix inconsistent number of branches when remote branches are present Users of project mirrors would see that the number of branches did not match the number in the branch dropdown because remote branches were counted when Rugged was in use. With Gitaly, only local branches are counted. Closes #36934 --- lib/gitlab/git/repository.rb | 2 +- spec/lib/gitlab/git/repository_spec.rb | 30 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index eb3731ba35a..f5747951d5e 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -153,7 +153,7 @@ module Gitlab if is_enabled gitaly_ref_client.count_branch_names else - rugged.branches.count do |ref| + rugged.branches.each(:local).count do |ref| begin ref.name && ref.target # ensures the branch is valid diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index 8ec8dfe6acf..2b70d16a264 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -977,6 +977,36 @@ describe Gitlab::Git::Repository, seed_helper: true do it 'returns the number of branches' do expect(repository.branch_count).to eq(10) end + + context 'with local and remote branches' do + let(:repository) do + Gitlab::Git::Repository.new('default', File.join(TEST_MUTABLE_REPO_PATH, '.git')) + end + + before do + create_remote_branch(repository, 'joe', 'remote_branch', 'master') + repository.create_branch('local_branch', 'master') + end + + after do + FileUtils.rm_rf(TEST_MUTABLE_REPO_PATH) + ensure_seeds + end + + it 'returns the count of local branches' do + expect(repository.branch_count).to eq(repository.local_branches.count) + end + + context 'with Gitaly disabled' do + before do + allow(Gitlab::GitalyClient).to receive(:feature_enabled?).and_return(false) + end + + it 'returns the count of local branches' do + expect(repository.branch_count).to eq(repository.local_branches.count) + end + end + end end describe "#ls_files" do From 115b598d4094a303c3941255d2bd478483f3daea Mon Sep 17 00:00:00 2001 From: Mark Fletcher Date: Thu, 24 Aug 2017 14:17:57 +0700 Subject: [PATCH 083/196] Document version Group Milestones API introduced --- .../docs-document-version-for-group-milestones-api.yml | 5 +++++ doc/api/group_milestones.md | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 changelogs/unreleased/docs-document-version-for-group-milestones-api.yml diff --git a/changelogs/unreleased/docs-document-version-for-group-milestones-api.yml b/changelogs/unreleased/docs-document-version-for-group-milestones-api.yml new file mode 100644 index 00000000000..d75c46313f4 --- /dev/null +++ b/changelogs/unreleased/docs-document-version-for-group-milestones-api.yml @@ -0,0 +1,5 @@ +--- +title: Document version Group Milestones API introduced +merge_request: +author: +type: changed diff --git a/doc/api/group_milestones.md b/doc/api/group_milestones.md index dbfc7529125..a96fb3124fc 100644 --- a/doc/api/group_milestones.md +++ b/doc/api/group_milestones.md @@ -1,5 +1,8 @@ # Group milestones API +> **Notes:** +> [Introduced][ce-12819] in GitLab 9.5. + ## List group milestones Returns a list of group milestones. @@ -118,3 +121,5 @@ Parameters: - `id` (required) - The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user - `milestone_id` (required) - The ID of a group milestone + +[ce-12819]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/12819 From d184f27ed387c1a90a9f06f68eab801ec3bd89e3 Mon Sep 17 00:00:00 2001 From: Mehdi Lahmam Date: Fri, 11 Aug 2017 11:09:07 +0200 Subject: [PATCH 084/196] Refactor Admin::ProjectsFinder by extracting finders as private methods --- app/controllers/admin/projects_controller.rb | 6 +- app/finders/admin/projects_finder.rb | 74 ++++++++++++++------ 2 files changed, 54 insertions(+), 26 deletions(-) diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb index 0b6cd71e651..50cf2643390 100644 --- a/app/controllers/admin/projects_controller.rb +++ b/app/controllers/admin/projects_controller.rb @@ -3,9 +3,9 @@ class Admin::ProjectsController < Admin::ApplicationController before_action :group, only: [:show, :transfer] def index - finder = Admin::ProjectsFinder.new(params: params, current_user: current_user) - @projects = finder.execute - @sort = finder.sort + params[:sort] ||= 'latest_activity_desc' + @sort = params[:sort] + @projects = Admin::ProjectsFinder.new(params: params, current_user: current_user).execute respond_to do |format| format.html diff --git a/app/finders/admin/projects_finder.rb b/app/finders/admin/projects_finder.rb index 7176bfe22d6..eac35ae0281 100644 --- a/app/finders/admin/projects_finder.rb +++ b/app/finders/admin/projects_finder.rb @@ -1,33 +1,61 @@ class Admin::ProjectsFinder - attr_reader :sort, :namespace_id, :visibility_level, :with_push, - :abandoned, :last_repository_check_failed, :archived, - :personal, :name, :page, :current_user + attr_reader :params, :current_user def initialize(params:, current_user:) + @params = params @current_user = current_user - @sort = params.fetch(:sort) { 'latest_activity_desc' } - @namespace_id = params[:namespace_id] - @visibility_level = params[:visibility_level] - @with_push = params[:with_push] - @abandoned = params[:abandoned] - @last_repository_check_failed = params[:last_repository_check_failed] - @archived = params[:archived] - @personal = params[:personal] - @name = params[:name] - @page = params[:page] end def execute items = Project.without_deleted.with_statistics - items = items.in_namespace(namespace_id) if namespace_id.present? - items = items.where(visibility_level: visibility_level) if visibility_level.present? - items = items.with_push if with_push.present? - items = items.abandoned if abandoned.present? - items = items.where(last_repository_check_failed: true) if last_repository_check_failed.present? - items = items.non_archived unless archived.present? - items = items.personal(current_user) if personal.present? - items = items.search(name) if name.present? - items = items.sort(sort) - items.includes(:namespace).order("namespaces.path, projects.name ASC").page(page) + items = by_namespace_id(items) + items = by_visibilty_level(items) + items = by_with_push(items) + items = by_abandoned(items) + items = by_last_repository_check_failed(items) + items = by_archived(items) + items = by_personal(items) + items = by_name(items) + items = sort(items) + items.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]) + end + + private + + def by_namespace_id(items) + params[:namespace_id].present? ? items.in_namespace(params[:namespace_id]) : items + end + + def by_visibilty_level(items) + params[:visibility_level].present? ? items.where(visibility_level: params[:visibility_level]) : items + end + + def by_with_push(items) + params[:with_push].present? ? items.with_push : items + end + + def by_abandoned(items) + params[:abandoned].present? ? items.abandoned : items + end + + def by_last_repository_check_failed(items) + params[:last_repository_check_failed].present? ? items.where(last_repository_check_failed: true) : items + end + + def by_archived(items) + items.non_archived unless params[:archived].present? + end + + def by_personal(items) + params[:personal].present? ? items.personal(current_user) : items + end + + def by_name(items) + params[:name].present? ? items.search(params[:name]) : items + end + + def sort(items) + sort = params.fetch(:sort) { 'latest_activity_desc' } + items.sort(sort) end end From 55f4ddad2b765f3b7466af5b43ef319a330c9fcd Mon Sep 17 00:00:00 2001 From: Mehdi Lahmam Date: Fri, 11 Aug 2017 11:09:17 +0200 Subject: [PATCH 085/196] Add an option to list only archived projects Closes #35994 --- app/finders/admin/projects_finder.rb | 8 +++++++- app/finders/projects_finder.rb | 17 +++++++++++++---- app/models/project.rb | 1 + app/views/shared/projects/_dropdown.html.haml | 5 ++++- .../unreleased/35994-archived-projects-only.yml | 5 +++++ spec/features/admin/admin_projects_spec.rb | 8 ++++++++ .../dashboard/archived_projects_spec.rb | 7 +++++++ spec/finders/admin/projects_finder_spec.rb | 6 ++++++ spec/finders/projects_finder_spec.rb | 6 ++++++ 9 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 changelogs/unreleased/35994-archived-projects-only.yml diff --git a/app/finders/admin/projects_finder.rb b/app/finders/admin/projects_finder.rb index eac35ae0281..d6bcd939522 100644 --- a/app/finders/admin/projects_finder.rb +++ b/app/finders/admin/projects_finder.rb @@ -43,7 +43,13 @@ class Admin::ProjectsFinder end def by_archived(items) - items.non_archived unless params[:archived].present? + if params[:archived] == 'only' + items.archived + elsif params[:archived].blank? + items.non_archived + else + items + end end def by_personal(items) diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb index aa80dfc3f37..fa6fea2588a 100644 --- a/app/finders/projects_finder.rb +++ b/app/finders/projects_finder.rb @@ -125,9 +125,18 @@ class ProjectsFinder < UnionFinder end def by_archived(projects) - # Back-compatibility with the places where `params[:archived]` can be set explicitly to `false` - params[:non_archived] = !Gitlab::Utils.to_boolean(params[:archived]) if params.key?(:archived) - - params[:non_archived] ? projects.non_archived : projects + if params[:non_archived] + projects.non_archived + elsif params.key?(:archived) # Back-compatibility with the places where `params[:archived]` can be set explicitly to `false` + if params[:archived] == 'only' + projects.archived + elsif Gitlab::Utils.to_boolean(params[:archived]) + projects + else + projects.non_archived + end + else + projects + end end end diff --git a/app/models/project.rb b/app/models/project.rb index 3118a480f7b..9d5a56db026 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -247,6 +247,7 @@ class Project < ActiveRecord::Base scope :joined, ->(user) { where('namespace_id != ?', user.namespace_id) } scope :starred_by, ->(user) { joins(:users_star_projects).where('users_star_projects.user_id': user.id) } scope :visible_to_user, ->(user) { where(id: user.authorized_projects.select(:id).reorder(nil)) } + scope :archived, -> { where(archived: true) } scope :non_archived, -> { where(archived: false) } scope :for_milestones, ->(ids) { joins(:milestones).where('milestones.id' => ids).distinct } scope :with_push, -> { joins(:events).where('events.action = ?', Event::PUSHED) } diff --git a/app/views/shared/projects/_dropdown.html.haml b/app/views/shared/projects/_dropdown.html.haml index 8939aeb6c3a..80432a73e4e 100644 --- a/app/views/shared/projects/_dropdown.html.haml +++ b/app/views/shared/projects/_dropdown.html.haml @@ -15,8 +15,11 @@ = link_to filter_projects_path(archived: nil), class: ("is-active" unless params[:archived].present?) do Hide archived projects %li - = link_to filter_projects_path(archived: true), class: ("is-active" if params[:archived].present?) do + = link_to filter_projects_path(archived: true), class: ("is-active" if Gitlab::Utils.to_boolean(params[:archived])) do Show archived projects + %li + = link_to filter_projects_path(archived: 'only'), class: ("is-active" if params[:archived] == 'only') do + Show archived projects only - if current_user %li.divider %li diff --git a/changelogs/unreleased/35994-archived-projects-only.yml b/changelogs/unreleased/35994-archived-projects-only.yml new file mode 100644 index 00000000000..ce565b177d0 --- /dev/null +++ b/changelogs/unreleased/35994-archived-projects-only.yml @@ -0,0 +1,5 @@ +--- +title: Add an option to list only archived projects +merge_request: 13492 +author: Mehdi Lahmam (@mehlah) +type: added diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb index 77710f80036..f4f2505d436 100644 --- a/spec/features/admin/admin_projects_spec.rb +++ b/spec/features/admin/admin_projects_spec.rb @@ -36,6 +36,14 @@ describe "Admin::Projects" do expect(page).to have_content(archived_project.name) expect(page).to have_xpath("//span[@class='label label-warning']", text: 'archived') end + + it 'renders only archived projects', js: true do + find(:css, '#sort-projects-dropdown').click + click_link 'Show archived projects only' + + expect(page).to have_content(archived_project.name) + expect(page).not_to have_content(project.name) + end end describe "GET /admin/projects/:namespace_id/:id" do diff --git a/spec/features/dashboard/archived_projects_spec.rb b/spec/features/dashboard/archived_projects_spec.rb index 814ec0e59c7..e8d699ff5e0 100644 --- a/spec/features/dashboard/archived_projects_spec.rb +++ b/spec/features/dashboard/archived_projects_spec.rb @@ -26,6 +26,13 @@ RSpec.describe 'Dashboard Archived Project' do expect(page).to have_link(archived_project.name) end + it 'renders only archived projects' do + click_link 'Show archived projects only' + + expect(page).to have_content(archived_project.name) + expect(page).not_to have_content(project.name) + end + it 'searchs archived projects', :js do click_button 'Last updated' click_link 'Show archived projects' diff --git a/spec/finders/admin/projects_finder_spec.rb b/spec/finders/admin/projects_finder_spec.rb index 28e36330029..4b67203a0df 100644 --- a/spec/finders/admin/projects_finder_spec.rb +++ b/spec/finders/admin/projects_finder_spec.rb @@ -118,6 +118,12 @@ describe Admin::ProjectsFinder do it { is_expected.to match_array([archived_project, shared_project, public_project, internal_project, private_project]) } end + + context 'archived=only' do + let(:params) { { archived: 'only' } } + + it { is_expected.to eq([archived_project]) } + end end context 'filter by personal' do diff --git a/spec/finders/projects_finder_spec.rb b/spec/finders/projects_finder_spec.rb index a5de586e869..0dfe6ba9c32 100644 --- a/spec/finders/projects_finder_spec.rb +++ b/spec/finders/projects_finder_spec.rb @@ -123,6 +123,12 @@ describe ProjectsFinder do it { is_expected.to match_array([public_project, internal_project, archived_project]) } end + describe 'filter by archived only' do + let(:params) { { archived: 'only' } } + + it { is_expected.to eq([archived_project]) } + end + describe 'filter by archived for backward compatibility' do let(:params) { { archived: false } } From a8efe4c469b13519b600e5ef0f5b1629cd42b01c Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Thu, 24 Aug 2017 09:19:49 +0200 Subject: [PATCH 086/196] Reword job to pipeline on the chart view This got changed for i18n in !12480, however, I forgot to understand that the meaning of the graphs changed in !12378. This corrects the behaviour. --- .../projects/pipelines/charts/_pipelines.haml | 6 ++--- .../zj-reword-job-to-pipeline-chart-view.yml | 5 +++++ features/steps/project/graph.rb | 6 ++--- locale/gitlab.pot | 22 +++++++++---------- 4 files changed, 22 insertions(+), 17 deletions(-) create mode 100644 changelogs/unreleased/zj-reword-job-to-pipeline-chart-view.yml diff --git a/app/views/projects/pipelines/charts/_pipelines.haml b/app/views/projects/pipelines/charts/_pipelines.haml index 02f1ef4b6da..7a100843f5e 100644 --- a/app/views/projects/pipelines/charts/_pipelines.haml +++ b/app/views/projects/pipelines/charts/_pipelines.haml @@ -14,19 +14,19 @@ .prepend-top-default %p.light - = _("Jobs for last week") + = _("Pipelines for last week") (#{date_from_to(Date.today - 7.days, Date.today)}) %canvas#weekChart{ height: 200 } .prepend-top-default %p.light - = _("Jobs for last month") + = _("Pipelines for last month") (#{date_from_to(Date.today - 30.days, Date.today)}) %canvas#monthChart{ height: 200 } .prepend-top-default %p.light - = _("Jobs for last year") + = _("Pipelines for last year") %canvas#yearChart.padded{ height: 250 } %script#pipelinesChartsData{ type: "application/json" } diff --git a/changelogs/unreleased/zj-reword-job-to-pipeline-chart-view.yml b/changelogs/unreleased/zj-reword-job-to-pipeline-chart-view.yml new file mode 100644 index 00000000000..474392a8cdd --- /dev/null +++ b/changelogs/unreleased/zj-reword-job-to-pipeline-chart-view.yml @@ -0,0 +1,5 @@ +--- +title: Reword job to pipeline to reflect what the graphs are really about +merge_request: +author: +type: fixed diff --git a/features/steps/project/graph.rb b/features/steps/project/graph.rb index e78e25318a6..b9cddf4041d 100644 --- a/features/steps/project/graph.rb +++ b/features/steps/project/graph.rb @@ -38,9 +38,9 @@ class Spinach::Features::ProjectGraph < Spinach::FeatureSteps step 'page should have CI graphs' do expect(page).to have_content 'Overall' - expect(page).to have_content 'Jobs for last week' - expect(page).to have_content 'Jobs for last month' - expect(page).to have_content 'Jobs for last year' + expect(page).to have_content 'Pipelines for last week' + expect(page).to have_content 'Pipelines for last month' + expect(page).to have_content 'Pipelines for last year' expect(page).to have_content 'Commit duration in minutes for last 30 commits' end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index a4a3ef6c42c..5a1db208d5a 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: gitlab 1.0.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-08-18 14:15+0530\n" -"PO-Revision-Date: 2017-08-18 14:15+0530\n" +"POT-Creation-Date: 2017-08-24 09:29+0200\n" +"PO-Revision-Date: 2017-08-24 09:29+0200\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" @@ -517,15 +517,6 @@ msgstr "" msgid "Issue events" msgstr "" -msgid "Jobs for last month" -msgstr "" - -msgid "Jobs for last week" -msgstr "" - -msgid "Jobs for last year" -msgstr "" - msgid "LFSStatus|Disabled" msgstr "" @@ -766,6 +757,15 @@ msgstr "" msgid "Pipelines charts" msgstr "" +msgid "Pipelines for last month" +msgstr "" + +msgid "Pipelines for last week" +msgstr "" + +msgid "Pipelines for last year" +msgstr "" + msgid "Pipeline|all" msgstr "" From fb49c94e49149a2043b774ba33daa3fe79febdd4 Mon Sep 17 00:00:00 2001 From: Andrew Newdigate Date: Thu, 24 Aug 2017 09:20:04 +0000 Subject: [PATCH 087/196] Delegate Repository::branch_exists? and ref_exists? to Gitlab::Git --- app/models/repository.rb | 13 ++++++++--- lib/gitlab/git/repository.rb | 23 +++++++++++++++++++ lib/gitlab/gitaly_client/ref_service.rb | 2 +- spec/features/calendar_spec.rb | 2 +- spec/features/dashboard/activity_spec.rb | 2 +- spec/lib/gitlab/git/repository_spec.rb | 28 ++++++++++++++++++++++++ spec/models/user_spec.rb | 2 +- 7 files changed, 65 insertions(+), 7 deletions(-) diff --git a/app/models/repository.rb b/app/models/repository.rb index c1e4fcf94a4..cb2cf658084 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -206,12 +206,18 @@ class Repository end def branch_exists?(branch_name) - branch_names.include?(branch_name) + return false unless raw_repository + + @branch_exists_memo ||= Hash.new do |hash, key| + hash[key] = raw_repository.branch_exists?(key) + end + + @branch_exists_memo[branch_name] end def ref_exists?(ref) - rugged.references.exist?(ref) - rescue Rugged::ReferenceError + !!raw_repository&.ref_exists?(ref) + rescue ArgumentError false end @@ -266,6 +272,7 @@ class Repository def expire_branches_cache expire_method_caches(%i(branch_names branch_count)) @local_branches = nil + @branch_exists_memo = nil end def expire_statistics_caches diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index f5747951d5e..860ed01c05d 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -201,6 +201,19 @@ module Gitlab end end + # Returns true if the given ref name exists + # + # Ref names must start with `refs/`. + def ref_exists?(ref_name) + gitaly_migrate(:ref_exists) do |is_enabled| + if is_enabled + gitaly_ref_exists?(ref_name) + else + rugged_ref_exists?(ref_name) + end + end + end + # Returns true if the given tag exists # # name - The name of the tag as a String. @@ -989,6 +1002,16 @@ module Gitlab raw_output.compact end + # Returns true if the given ref name exists + # + # Ref names must start with `refs/`. + def rugged_ref_exists?(ref_name) + raise ArgumentError, 'invalid refname' unless ref_name.start_with?('refs/') + rugged.references.exist?(ref_name) + rescue Rugged::ReferenceError + false + end + # Returns true if the given ref name exists # # Ref names must start with `refs/`. diff --git a/lib/gitlab/gitaly_client/ref_service.rb b/lib/gitlab/gitaly_client/ref_service.rb index cdcfed36740..8c0008c6971 100644 --- a/lib/gitlab/gitaly_client/ref_service.rb +++ b/lib/gitlab/gitaly_client/ref_service.rb @@ -71,7 +71,7 @@ module Gitlab end def ref_exists?(ref_name) - request = Gitaly::RefExistsRequest.new(repository: @gitaly_repo, ref: ref_name) + request = Gitaly::RefExistsRequest.new(repository: @gitaly_repo, ref: GitalyClient.encode(ref_name)) response = GitalyClient.call(@storage, :ref_service, :ref_exists, request) response.value rescue GRPC::InvalidArgument => e diff --git a/spec/features/calendar_spec.rb b/spec/features/calendar_spec.rb index 9a597a2d690..4fc6956d111 100644 --- a/spec/features/calendar_spec.rb +++ b/spec/features/calendar_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature 'Contributions Calendar', :js do let(:user) { create(:user) } - let(:contributed_project) { create(:project, :public) } + let(:contributed_project) { create(:project, :public, :repository) } let(:issue_note) { create(:note, project: contributed_project) } # Ex/ Sunday Jan 1, 2016 diff --git a/spec/features/dashboard/activity_spec.rb b/spec/features/dashboard/activity_spec.rb index 582868bac1e..bd115785646 100644 --- a/spec/features/dashboard/activity_spec.rb +++ b/spec/features/dashboard/activity_spec.rb @@ -17,7 +17,7 @@ feature 'Dashboard > Activity' do end context 'event filters', :js do - let(:project) { create(:project) } + let(:project) { create(:project, :repository) } let(:merge_request) do create(:merge_request, author: user, source_project: project, target_project: project) diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index 2b70d16a264..62da733170c 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -1110,6 +1110,34 @@ describe Gitlab::Git::Repository, seed_helper: true do end end + describe '#ref_exists?' do + shared_examples 'checks the existence of refs' do + it 'returns true for an existing tag' do + expect(repository.ref_exists?('refs/heads/master')).to eq(true) + end + + it 'returns false for a non-existing tag' do + expect(repository.ref_exists?('refs/tags/THIS_TAG_DOES_NOT_EXIST')).to eq(false) + end + + it 'raises an ArgumentError for an empty string' do + expect { repository.ref_exists?('') }.to raise_error(ArgumentError) + end + + it 'raises an ArgumentError for an invalid ref' do + expect { repository.ref_exists?('INVALID') }.to raise_error(ArgumentError) + end + end + + context 'when Gitaly ref_exists feature is enabled' do + it_behaves_like 'checks the existence of refs' + end + + context 'when Gitaly ref_exists feature is disabled', skip_gitaly_mock: true do + it_behaves_like 'checks the existence of refs' + end + end + describe '#tag_exists?' do shared_examples 'checks the existence of tags' do it 'returns true for an existing tag' do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 9a9e255f874..8e04eea56a7 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1356,7 +1356,7 @@ describe User do end it "excludes push event if branch has been deleted" do - allow_any_instance_of(Repository).to receive(:branch_names).and_return(['foo']) + allow_any_instance_of(Repository).to receive(:branch_exists?).with('master').and_return(false) expect(subject.recent_push).to eq(nil) end From e8525e107da9234d743caf8a0c7db1f46af60e89 Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Tue, 22 Aug 2017 16:27:09 +0100 Subject: [PATCH 088/196] Show un-highlighted diffs when blobs are the same For some old merge requests, we don't have enough information to figure out the old blob and the new blob for the file. This means that we can't highlight the diff correctly, but we can still display it without highlighting. --- changelogs/unreleased/fix-old-mr-diffs.yml | 6 +++ lib/gitlab/diff/file.rb | 9 ++++- spec/lib/gitlab/diff/file_spec.rb | 44 ++++++++++++++++++++-- 3 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 changelogs/unreleased/fix-old-mr-diffs.yml diff --git a/changelogs/unreleased/fix-old-mr-diffs.yml b/changelogs/unreleased/fix-old-mr-diffs.yml new file mode 100644 index 00000000000..b0a011cf354 --- /dev/null +++ b/changelogs/unreleased/fix-old-mr-diffs.yml @@ -0,0 +1,6 @@ +--- +title: Show un-highlighted text diffs when we do not have references to the correct + blobs +merge_request: +author: +type: fixed diff --git a/lib/gitlab/diff/file.rb b/lib/gitlab/diff/file.rb index 17a9ec01637..1dabd4ebdd0 100644 --- a/lib/gitlab/diff/file.rb +++ b/lib/gitlab/diff/file.rb @@ -186,7 +186,10 @@ module Gitlab end def content_changed? - old_blob && new_blob && old_blob.id != new_blob.id + return blobs_changed? if diff_refs + return false if new_file? || deleted_file? || renamed_file? + + text? && diff_lines.any? end def different_type? @@ -225,6 +228,10 @@ module Gitlab private + def blobs_changed? + old_blob && new_blob && old_blob.id != new_blob.id + end + def simple_viewer_class return DiffViewer::NotDiffable unless diffable? diff --git a/spec/lib/gitlab/diff/file_spec.rb b/spec/lib/gitlab/diff/file_spec.rb index ab60d62d88e..c91895cedc3 100644 --- a/spec/lib/gitlab/diff/file_spec.rb +++ b/spec/lib/gitlab/diff/file_spec.rb @@ -15,6 +15,17 @@ describe Gitlab::Diff::File do it { expect(diff_lines.first).to be_kind_of(Gitlab::Diff::Line) } end + describe '#highlighted_diff_lines' do + it 'highlights the diff and memoises the result' do + expect(Gitlab::Diff::Highlight).to receive(:new) + .with(diff_file, repository: project.repository) + .once + .and_call_original + + diff_file.highlighted_diff_lines + end + end + describe '#mode_changed?' do it { expect(diff_file.mode_changed?).to be_falsey } end @@ -122,8 +133,20 @@ describe Gitlab::Diff::File do let(:commit) { project.commit('2f63565e7aac07bcdadb654e253078b727143ec4') } let(:diff_file) { commit.diffs.diff_file_with_new_path('files/images/6049019_460s.jpg') } - it 'returns true' do - expect(diff_file.content_changed?).to be_truthy + context 'when the blobs are different' do + it 'returns true' do + expect(diff_file.content_changed?).to be_truthy + end + end + + context 'when there are no diff refs' do + before do + allow(diff_file).to receive(:diff_refs).and_return(nil) + end + + it 'returns false' do + expect(diff_file.content_changed?).to be_falsey + end end end @@ -131,8 +154,20 @@ describe Gitlab::Diff::File do let(:commit) { project.commit('570e7b2abdd848b95f2f578043fc23bd6f6fd24d') } let(:diff_file) { commit.diffs.diff_file_with_new_path('files/ruby/popen.rb') } - it 'returns true' do - expect(diff_file.content_changed?).to be_truthy + context 'when the blobs are different' do + it 'returns true' do + expect(diff_file.content_changed?).to be_truthy + end + end + + context 'when there are no diff refs' do + before do + allow(diff_file).to receive(:diff_refs).and_return(nil) + end + + it 'returns true' do + expect(diff_file.content_changed?).to be_truthy + end end end end @@ -278,6 +313,7 @@ describe Gitlab::Diff::File do allow(diff_file).to receive(:deleted_file?).and_return(false) allow(diff_file).to receive(:renamed_file?).and_return(false) allow(diff_file).to receive(:mode_changed?).and_return(false) + allow(diff_file).to receive(:raw_text?).and_return(false) end it 'returns a No Preview viewer' do From 061472864ceaa4dc837eebcaa583f7b81d4e7e54 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Tue, 22 Aug 2017 16:10:49 +0100 Subject: [PATCH 089/196] Fix group and project search for anonymous users --- app/assets/javascripts/api.js | 15 ++++++---- app/views/search/_form.html.haml | 2 +- ...and-project-search-for-anonymous-users.yml | 5 ++++ doc/api/groups.md | 9 ++++-- spec/features/search_spec.rb | 26 +++++++++++++++++ spec/javascripts/api_spec.js | 28 +++++++++++++++++-- spec/javascripts/project_title_spec.js | 6 ++-- spec/requests/api/groups_spec.rb | 21 ++++++++++++-- 8 files changed, 96 insertions(+), 16 deletions(-) create mode 100644 changelogs/unreleased/31409-fix-group-and-project-search-for-anonymous-users.yml diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js index 56f91e95bb9..3d0ba65fd36 100644 --- a/app/assets/javascripts/api.js +++ b/app/assets/javascripts/api.js @@ -55,13 +55,18 @@ const Api = { // Return projects list. Filtered by query projects(query, options, callback) { const url = Api.buildUrl(Api.projectsPath); + const defaults = { + search: query, + per_page: 20, + }; + + if (gon.current_user_id) { + defaults.membership = true; + } + return $.ajax({ url, - data: Object.assign({ - search: query, - per_page: 20, - membership: true, - }, options), + data: Object.assign(defaults, options), dataType: 'json', }) .done(projects => callback(projects)); diff --git a/app/views/search/_form.html.haml b/app/views/search/_form.html.haml index 3139be1cd37..a4a5cec1314 100644 --- a/app/views/search/_form.html.haml +++ b/app/views/search/_form.html.haml @@ -11,5 +11,5 @@ %span.sr-only Clear search - unless params[:snippets].eql? 'true' - = render 'filter' if current_user + = render 'filter' = button_tag "Search", class: "btn btn-success btn-search" diff --git a/changelogs/unreleased/31409-fix-group-and-project-search-for-anonymous-users.yml b/changelogs/unreleased/31409-fix-group-and-project-search-for-anonymous-users.yml new file mode 100644 index 00000000000..06e8180db64 --- /dev/null +++ b/changelogs/unreleased/31409-fix-group-and-project-search-for-anonymous-users.yml @@ -0,0 +1,5 @@ +--- +title: Fix group and project search for anonymous users +merge_request: 13745 +author: +type: fixed diff --git a/doc/api/groups.md b/doc/api/groups.md index 2b3d8e125c8..c2daa8bc029 100644 --- a/doc/api/groups.md +++ b/doc/api/groups.md @@ -2,7 +2,8 @@ ## List groups -Get a list of groups. (As user: my groups or all available, as admin: all groups). +Get a list of visible groups for the authenticated user. When accessed without +authentication, only public groups are returned. Parameters: @@ -43,7 +44,8 @@ You can search for groups by name or path, see below. ## List a group's projects -Get a list of projects in this group. +Get a list of projects in this group. When accessed without authentication, only +public projects are returned. ``` GET /groups/:id/projects @@ -109,7 +111,8 @@ Example response: ## Details of a group -Get all details of a group. +Get all details of a group. This endpoint can be accessed without authentication +if the group is publicly accessible. ``` GET /groups/:id diff --git a/spec/features/search_spec.rb b/spec/features/search_spec.rb index 6742d77937f..31d509455ba 100644 --- a/spec/features/search_spec.rb +++ b/spec/features/search_spec.rb @@ -281,4 +281,30 @@ describe "Search" do expect(page).to have_selector('.commit-row-description', count: 9) end end + + context 'anonymous user' do + let(:project) { create(:project, :public) } + + before do + sign_out(user) + end + + it 'preserves the group being searched in' do + visit search_path(group_id: project.namespace.id) + + fill_in 'search', with: 'foo' + click_button 'Search' + + expect(find('#group_id').value).to eq(project.namespace.id.to_s) + end + + it 'preserves the project being searched in' do + visit search_path(project_id: project.id) + + fill_in 'search', with: 'foo' + click_button 'Search' + + expect(find('#project_id').value).to eq(project.id.to_s) + end + end end diff --git a/spec/javascripts/api_spec.js b/spec/javascripts/api_spec.js index 867322ce8ae..8c68ceff914 100644 --- a/spec/javascripts/api_spec.js +++ b/spec/javascripts/api_spec.js @@ -17,7 +17,7 @@ describe('Api', () => { beforeEach(() => { originalGon = window.gon; - window.gon = dummyGon; + window.gon = Object.assign({}, dummyGon); }); afterEach(() => { @@ -98,14 +98,36 @@ describe('Api', () => { }); describe('projects', () => { - it('fetches projects', (done) => { + it('fetches projects with membership when logged in', (done) => { + const query = 'dummy query'; + const options = { unused: 'option' }; + const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects.json?simple=true`; + window.gon.current_user_id = 1; + const expectedData = Object.assign({ + search: query, + per_page: 20, + membership: true, + }, options); + spyOn(jQuery, 'ajax').and.callFake((request) => { + expect(request.url).toEqual(expectedUrl); + expect(request.dataType).toEqual('json'); + expect(request.data).toEqual(expectedData); + return sendDummyResponse(); + }); + + Api.projects(query, options, (response) => { + expect(response).toBe(dummyResponse); + done(); + }); + }); + + it('fetches projects without membership when not logged in', (done) => { const query = 'dummy query'; const options = { unused: 'option' }; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects.json?simple=true`; const expectedData = Object.assign({ search: query, per_page: 20, - membership: true, }, options); spyOn(jQuery, 'ajax').and.callFake((request) => { expect(request.url).toEqual(expectedUrl); diff --git a/spec/javascripts/project_title_spec.js b/spec/javascripts/project_title_spec.js index cc336180ff7..3d36bb3e4d4 100644 --- a/spec/javascripts/project_title_spec.js +++ b/spec/javascripts/project_title_spec.js @@ -7,6 +7,7 @@ import '~/project_select'; import '~/project'; describe('Project Title', () => { + const dummyApiVersion = 'v3000'; preloadFixtures('issues/open-issue.html.raw'); loadJSONFixtures('projects.json'); @@ -14,7 +15,7 @@ describe('Project Title', () => { loadFixtures('issues/open-issue.html.raw'); window.gon = {}; - window.gon.api_version = 'v3'; + window.gon.api_version = dummyApiVersion; // eslint-disable-next-line no-new new Project(); @@ -37,9 +38,10 @@ describe('Project Title', () => { it('toggles dropdown', () => { const $menu = $('.js-dropdown-menu-projects'); + window.gon.current_user_id = 1; $('.js-projects-dropdown-toggle').click(); expect($menu).toHaveClass('open'); - expect(reqUrl).toBe('/api/v3/projects.json?simple=true'); + expect(reqUrl).toBe(`/api/${dummyApiVersion}/projects.json?simple=true`); expect(reqData).toEqual({ search: '', order_by: 'last_activity_at', diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb index 313c38cd29c..a7557c7fb22 100644 --- a/spec/requests/api/groups_spec.rb +++ b/spec/requests/api/groups_spec.rb @@ -20,10 +20,15 @@ describe API::Groups do describe "GET /groups" do context "when unauthenticated" do - it "returns authentication error" do + it "returns public groups" do get api("/groups") - expect(response).to have_http_status(401) + expect(response).to have_http_status(200) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + expect(json_response.length).to eq(1) + expect(json_response) + .to satisfy_one { |group| group['name'] == group1.name } end end @@ -165,6 +170,18 @@ describe API::Groups do end describe "GET /groups/:id" do + context 'when unauthenticated' do + it 'returns 404 for a private group' do + get api("/groups/#{group2.id}") + expect(response).to have_http_status(404) + end + + it 'returns 200 for a public group' do + get api("/groups/#{group1.id}") + expect(response).to have_http_status(200) + end + end + context "when authenticated as user" do it "returns one of user1's groups" do project = create(:project, namespace: group2, path: 'Foo') From 2adff699cea2cf1e60180d7eae73dfe5e8a09235 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Thu, 24 Aug 2017 11:33:06 +0100 Subject: [PATCH 090/196] Refactor complicated API group finding rules into GroupsFinder --- app/finders/groups_finder.rb | 36 ++++++++++++++++++++++++++++++------ lib/api/groups.rb | 12 ++---------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/app/finders/groups_finder.rb b/app/finders/groups_finder.rb index e6fb112e7f2..88d71b0a87b 100644 --- a/app/finders/groups_finder.rb +++ b/app/finders/groups_finder.rb @@ -1,3 +1,19 @@ +# GroupsFinder +# +# Used to filter Groups by a set of params +# +# Arguments: +# current_user - which user is requesting groups +# params: +# owned: boolean +# parent: Group +# all_available: boolean (defaults to true) +# +# Users with full private access can see all groups. The `owned` and `parent` +# params can be used to restrict the groups that are returned. +# +# Anonymous users will never return any `owned` groups. They will return all +# public groups instead, even if `all_available` is set to false. class GroupsFinder < UnionFinder def initialize(current_user = nil, params = {}) @current_user = current_user @@ -16,13 +32,13 @@ class GroupsFinder < UnionFinder attr_reader :current_user, :params def all_groups + return [owned_groups] if params[:owned] + return [Group.all] if current_user&.full_private_access? + groups = [] - - if current_user - groups << Gitlab::GroupHierarchy.new(groups_for_ancestors, groups_for_descendants).all_groups - end - groups << Group.unscoped.public_to_user(current_user) - + groups << Gitlab::GroupHierarchy.new(groups_for_ancestors, groups_for_descendants).all_groups if current_user + groups << Group.unscoped.public_to_user(current_user) if include_public_groups? + groups << Group.none if groups.empty? groups end @@ -39,4 +55,12 @@ class GroupsFinder < UnionFinder groups.where(parent: params[:parent]) end + + def owned_groups + current_user&.groups || Group.none + end + + def include_public_groups? + current_user.nil? || params.fetch(:all_available, true) + end end diff --git a/lib/api/groups.rb b/lib/api/groups.rb index 892fd239df4..e56427304a6 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -47,16 +47,8 @@ module API use :pagination end get do - groups = if params[:owned] - current_user ? current_user.owned_groups : Group.none - elsif current_user&.admin? - Group.all - elsif params[:all_available] || current_user.nil? - GroupsFinder.new(current_user).execute - else - current_user.groups - end - + find_params = { all_available: params[:all_available], owned: params[:owned] } + groups = GroupsFinder.new(current_user, find_params).execute groups = groups.search(params[:search]) if params[:search].present? groups = groups.where.not(id: params[:skip_groups]) if params[:skip_groups].present? groups = groups.reorder(params[:order_by] => params[:sort]) From 80f657c05e8cd2f87abb4525695af19181607f04 Mon Sep 17 00:00:00 2001 From: Mark Fletcher Date: Thu, 24 Aug 2017 17:43:11 +0700 Subject: [PATCH 091/196] Disable GitLab Project Import Button if source disabled --- app/views/projects/new.html.haml | 7 ++++--- ...ble-gitlab-project-import-button-if-source-disabled.yml | 5 +++++ 2 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 changelogs/unreleased/36882-disable-gitlab-project-import-button-if-source-disabled.yml diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index 647e0a772b1..5698bb281b4 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -68,9 +68,10 @@ - if git_import_enabled? %button.btn.js-toggle-button.import_git{ type: "button" } = icon('git', text: 'Repo by URL') - .import_gitlab_project.has-tooltip{ data: { container: 'body' } } - = link_to new_import_gitlab_project_path, class: 'btn btn_import_gitlab_project project-submit' do - = icon('gitlab', text: 'GitLab export') + - if gitlab_project_import_enabled? + .import_gitlab_project.has-tooltip{ data: { container: 'body' } } + = link_to new_import_gitlab_project_path, class: 'btn btn_import_gitlab_project project-submit' do + = icon('gitlab', text: 'GitLab export') .row .col-lg-12 diff --git a/changelogs/unreleased/36882-disable-gitlab-project-import-button-if-source-disabled.yml b/changelogs/unreleased/36882-disable-gitlab-project-import-button-if-source-disabled.yml new file mode 100644 index 00000000000..a06c84c30e6 --- /dev/null +++ b/changelogs/unreleased/36882-disable-gitlab-project-import-button-if-source-disabled.yml @@ -0,0 +1,5 @@ +--- +title: Disable GitLab Project Import Button if source disabled +merge_request: +author: +type: fixed From a1a914994f6376b03d95e9d4b05dea422e8610f9 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Thu, 24 Aug 2017 14:05:24 +0200 Subject: [PATCH 092/196] Avoid committer = lines --- app/models/repository.rb | 27 +++++++++------------------ app/services/git_operation_service.rb | 5 ++--- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/app/models/repository.rb b/app/models/repository.rb index 062f532233f..59f913c7fb4 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -164,8 +164,7 @@ class Repository return false unless newrev - committer = Gitlab::Git::Committer.from_user(user) - GitOperationService.new(committer, self).add_branch(branch_name, newrev) + GitOperationService.new(user, self).add_branch(branch_name, newrev) after_create_branch find_branch(branch_name) @@ -177,8 +176,7 @@ class Repository return false unless newrev - committer = Gitlab::Git::Committer.from_user(user) - GitOperationService.new(committer, self).add_tag(tag_name, newrev, options) + GitOperationService.new(user, self).add_tag(tag_name, newrev, options) find_tag(tag_name) end @@ -187,8 +185,7 @@ class Repository before_remove_branch branch = find_branch(branch_name) - committer = Gitlab::Git::Committer.from_user(user) - GitOperationService.new(committer, self).rm_branch(branch) + GitOperationService.new(user, self).rm_branch(branch) after_remove_branch true @@ -198,8 +195,7 @@ class Repository before_remove_tag tag = find_tag(tag_name) - committer = Gitlab::Git::Committer.from_user(user) - GitOperationService.new(committer, self).rm_tag(tag) + GitOperationService.new(user, self).rm_tag(tag) after_remove_tag true @@ -767,8 +763,7 @@ class Repository author_email: nil, author_name: nil, start_branch_name: nil, start_project: project) - committer = Gitlab::Git::Committer.from_user(user) - GitOperationService.new(committer, self).with_branch( + GitOperationService.new(user, self).with_branch( branch_name, start_branch_name: start_branch_name, start_project: start_project) do |start_commit| @@ -824,8 +819,7 @@ class Repository end def merge(user, source, merge_request, options = {}) - committer = Gitlab::Git::Committer.from_user(user) - GitOperationService.new(committer, self).with_branch( + GitOperationService.new(user, self).with_branch( merge_request.target_branch) do |start_commit| our_commit = start_commit.sha their_commit = source @@ -852,8 +846,7 @@ class Repository def revert( user, commit, branch_name, start_branch_name: nil, start_project: project) - committer = Gitlab::Git::Committer.from_user(user) - GitOperationService.new(committer, self).with_branch( + GitOperationService.new(user, self).with_branch( branch_name, start_branch_name: start_branch_name, start_project: start_project) do |start_commit| @@ -876,8 +869,7 @@ class Repository def cherry_pick( user, commit, branch_name, start_branch_name: nil, start_project: project) - committer = Gitlab::Git::Committer.from_user(user) - GitOperationService.new(committer, self).with_branch( + GitOperationService.new(user, self).with_branch( branch_name, start_branch_name: start_branch_name, start_project: start_project) do |start_commit| @@ -902,8 +894,7 @@ class Repository end def resolve_conflicts(user, branch_name, params) - committer = Gitlab::Git::Committer.from_user(user) - GitOperationService.new(committer, self).with_branch(branch_name) do + GitOperationService.new(user, self).with_branch(branch_name) do committer = user_to_committer(user) create_commit(params.merge(author: committer, committer: committer)) diff --git a/app/services/git_operation_service.rb b/app/services/git_operation_service.rb index 6a983566526..6b7a56e6922 100644 --- a/app/services/git_operation_service.rb +++ b/app/services/git_operation_service.rb @@ -2,10 +2,9 @@ class GitOperationService attr_reader :committer, :repository def initialize(committer, new_repository) - if committer && !committer.is_a?(Gitlab::Git::Committer) - raise "expected Gitlab::Git::Committer, got #{committer.inspect}" - end + committer = Gitlab::Git::Committer.from_user(committer) if committer.is_a?(User) @committer = committer + @repository = new_repository end From 1971ae18f670775d48dd78e844b784d432ddaaca Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Thu, 24 Aug 2017 14:59:06 +0200 Subject: [PATCH 093/196] Use gitaly-proto 0.31.0 --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 72fc2de426e..32539842dbb 100644 --- a/Gemfile +++ b/Gemfile @@ -401,7 +401,7 @@ group :ed25519 do end # Gitaly GRPC client -gem 'gitaly', '~> 0.30.0' +gem 'gitaly-proto', '~> 0.31.0', require: 'gitaly' gem 'toml-rb', '~> 0.3.15', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 7d3c53ee010..780939df03a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -275,7 +275,7 @@ GEM po_to_json (>= 1.0.0) rails (>= 3.2.0) gherkin-ruby (0.3.2) - gitaly (0.30.0) + gitaly-proto (0.31.0) google-protobuf (~> 3.1) grpc (~> 1.0) github-linguist (4.7.6) @@ -1019,7 +1019,7 @@ DEPENDENCIES gettext (~> 3.2.2) gettext_i18n_rails (~> 1.8.0) gettext_i18n_rails_js (~> 1.2.0) - gitaly (~> 0.30.0) + gitaly-proto (~> 0.31.0) github-linguist (~> 4.7.0) gitlab-flowdock-git-hook (~> 1.0.1) gitlab-markup (~> 1.5.1) From 82c002ebce10395332485f56abc895defe656197 Mon Sep 17 00:00:00 2001 From: Dimitrie Hoekstra Date: Thu, 24 Aug 2017 14:13:24 +0000 Subject: [PATCH 094/196] Changed all font-weight values to 400 and 600 --- app/assets/stylesheets/framework/avatar.scss | 2 +- app/assets/stylesheets/framework/badges.scss | 2 +- app/assets/stylesheets/framework/blocks.scss | 4 +-- app/assets/stylesheets/framework/buttons.scss | 2 +- .../stylesheets/framework/calendar.scss | 6 ++-- app/assets/stylesheets/framework/common.scss | 16 ++++----- .../stylesheets/framework/dropdowns.scss | 12 +++---- app/assets/stylesheets/framework/filters.scss | 4 +-- app/assets/stylesheets/framework/flash.scss | 2 +- app/assets/stylesheets/framework/forms.scss | 6 ++-- app/assets/stylesheets/framework/header.scss | 6 ++-- app/assets/stylesheets/framework/lists.scss | 4 +-- app/assets/stylesheets/framework/mixins.scss | 2 +- app/assets/stylesheets/framework/modal.scss | 2 +- app/assets/stylesheets/framework/nav.scss | 4 +-- .../stylesheets/framework/page-header.scss | 2 +- app/assets/stylesheets/framework/selects.scss | 10 +++--- .../stylesheets/framework/snippets.scss | 2 +- app/assets/stylesheets/framework/tables.scss | 2 +- .../stylesheets/framework/tw_bootstrap.scss | 4 +-- .../stylesheets/framework/typography.scss | 12 +++---- .../stylesheets/framework/variables.scss | 2 ++ app/assets/stylesheets/framework/wells.scss | 2 +- app/assets/stylesheets/highlight/dark.scss | 8 ++--- app/assets/stylesheets/highlight/monokai.scss | 2 +- .../stylesheets/highlight/solarized_dark.scss | 2 +- .../highlight/solarized_light.scss | 2 +- app/assets/stylesheets/highlight/white.scss | 32 ++++++++--------- .../mailers/highlighted_diff_email.scss | 32 ++++++++--------- app/assets/stylesheets/new_nav.scss | 10 +++--- app/assets/stylesheets/new_sidebar.scss | 8 ++--- app/assets/stylesheets/pages/boards.scss | 2 +- app/assets/stylesheets/pages/builds.scss | 4 +-- app/assets/stylesheets/pages/ci_projects.scss | 2 +- app/assets/stylesheets/pages/commits.scss | 4 +-- .../stylesheets/pages/convdev_index.scss | 6 ++-- .../stylesheets/pages/cycle_analytics.scss | 10 +++--- app/assets/stylesheets/pages/diff.scss | 6 ++-- .../stylesheets/pages/environments.scss | 6 ++-- app/assets/stylesheets/pages/events.scss | 2 +- app/assets/stylesheets/pages/issuable.scss | 6 ++-- app/assets/stylesheets/pages/issues.scss | 4 +-- app/assets/stylesheets/pages/login.scss | 8 ++--- app/assets/stylesheets/pages/members.scss | 4 +-- .../stylesheets/pages/merge_requests.scss | 16 ++++----- app/assets/stylesheets/pages/milestone.scss | 4 +-- app/assets/stylesheets/pages/note_form.scss | 2 +- .../stylesheets/pages/pipeline_schedules.scss | 2 +- app/assets/stylesheets/pages/pipelines.scss | 12 +++---- app/assets/stylesheets/pages/profile.scss | 4 +-- app/assets/stylesheets/pages/projects.scss | 16 ++++----- app/assets/stylesheets/pages/repo.scss | 2 +- app/assets/stylesheets/pages/runners.scss | 2 +- app/assets/stylesheets/pages/search.scss | 2 +- app/assets/stylesheets/pages/sherlock.scss | 2 +- app/assets/stylesheets/pages/todos.scss | 6 ++-- app/assets/stylesheets/pages/tree.scss | 2 +- app/assets/stylesheets/pages/ui_dev_kit.scss | 2 +- app/assets/stylesheets/pages/wiki.scss | 4 +-- app/assets/stylesheets/pages/xterm.scss | 2 +- app/assets/stylesheets/print.scss | 2 +- app/views/layouts/errors.html.haml | 4 +-- app/views/layouts/oauth_error.html.haml | 2 +- .../unreleased/font-weight-adjusted.yml | 5 +++ public/404.html | 6 ++-- public/422.html | 6 ++-- public/500.html | 6 ++-- public/502.html | 6 ++-- public/503.html | 6 ++-- public/deploy.html | 6 ++-- spec/fixtures/emails/ios_default.eml | 12 +++---- spec/fixtures/emails/on_wrote.eml | 6 ++-- vendor/assets/stylesheets/katex.scss | 34 +++++++++---------- vendor/assets/stylesheets/xterm/xterm.css | 2 +- 74 files changed, 230 insertions(+), 223 deletions(-) create mode 100644 changelogs/unreleased/font-weight-adjusted.yml diff --git a/app/assets/stylesheets/framework/avatar.scss b/app/assets/stylesheets/framework/avatar.scss index 486d88efbc5..bdcbd4021b3 100644 --- a/app/assets/stylesheets/framework/avatar.scss +++ b/app/assets/stylesheets/framework/avatar.scss @@ -78,7 +78,7 @@ &.s60 { font-size: 32px; line-height: 58px; } &.s70 { font-size: 34px; line-height: 70px; } &.s90 { font-size: 36px; line-height: 88px; } - &.s110 { font-size: 40px; line-height: 108px; font-weight: 300; } + &.s110 { font-size: 40px; line-height: 108px; font-weight: $gl-font-weight-normal; } &.s140 { font-size: 72px; line-height: 138px; } &.s160 { font-size: 96px; line-height: 158px; } } diff --git a/app/assets/stylesheets/framework/badges.scss b/app/assets/stylesheets/framework/badges.scss index 47a8f44c709..6bbe32df772 100644 --- a/app/assets/stylesheets/framework/badges.scss +++ b/app/assets/stylesheets/framework/badges.scss @@ -1,5 +1,5 @@ .badge { - font-weight: normal; + font-weight: $gl-font-weight-normal; background-color: $badge-bg; color: $badge-color; vertical-align: baseline; diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss index 95a08c960ea..b575ec9de18 100644 --- a/app/assets/stylesheets/framework/blocks.scss +++ b/app/assets/stylesheets/framework/blocks.scss @@ -8,7 +8,7 @@ text-align: center; padding: 20px; color: $gl-text-color; - font-weight: normal; + font-weight: $gl-font-weight-normal; font-size: 14px; line-height: 36px; @@ -213,7 +213,7 @@ h1 { display: inline; - font-weight: normal; + font-weight: $gl-font-weight-normal; font-size: 24px; color: $gl-text-color; } diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss index 6eabdc63d9e..b4a6b214e98 100644 --- a/app/assets/stylesheets/framework/buttons.scss +++ b/app/assets/stylesheets/framework/buttons.scss @@ -1,7 +1,7 @@ @mixin btn-default { border-radius: 3px; font-size: $gl-font-size; - font-weight: 400; + font-weight: $gl-font-weight-normal; padding: $gl-vert-padding $gl-btn-padding; &:focus, diff --git a/app/assets/stylesheets/framework/calendar.scss b/app/assets/stylesheets/framework/calendar.scss index 0ded4a3b423..4ce767e4cc4 100644 --- a/app/assets/stylesheets/framework/calendar.scss +++ b/app/assets/stylesheets/framework/calendar.scss @@ -52,13 +52,13 @@ .pika-label { color: $gl-text-color-secondary; font-size: 14px; - font-weight: normal; + font-weight: $gl-font-weight-normal; } th { padding: 2px 0; color: $note-disabled-comment-color; - font-weight: normal; + font-weight: $gl-font-weight-normal; text-transform: lowercase; border-top: 1px solid $calendar-border-color; } @@ -88,7 +88,7 @@ .is-today { .pika-day { color: inherit; - font-weight: normal; + font-weight: $gl-font-weight-normal; } } diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss index 293aa194528..e16fbbf43b5 100644 --- a/app/assets/stylesheets/framework/common.scss +++ b/app/assets/stylesheets/framework/common.scss @@ -36,12 +36,12 @@ color: $common-gray; font-size: 14px; margin-bottom: 12px; - font-weight: normal; + font-weight: $gl-font-weight-normal; line-height: 24px; } .bold { - font-weight: 600; + font-weight: $gl-font-weight-bold; } .tab-content { @@ -89,7 +89,7 @@ hr { } } -.item-title { font-weight: 600; } +.item-title { font-weight: $gl-font-weight-bold; } /** FLASH message **/ .author_link, @@ -118,18 +118,18 @@ table a code { span.update-author { display: block; color: $update-author-color; - font-weight: normal; + font-weight: $gl-font-weight-normal; font-style: italic; strong { - font-weight: bold; + font-weight: $gl-font-weight-bold; font-style: normal; } } .user-mention { color: $user-mention-color; - font-weight: bold; + font-weight: $gl-font-weight-bold; } .field_with_errors { @@ -222,7 +222,7 @@ li.note { text-align: center; background: $error-bg; color: $white-light; - font-weight: bold; + font-weight: $gl-font-weight-bold; a { color: $white-light; @@ -339,7 +339,7 @@ table { .header-with-avatar { h3 { margin: 0; - font-weight: bold; + font-weight: $gl-font-weight-bold; } .username { diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index 5f270e288ae..a45d5a6dca0 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -195,7 +195,7 @@ margin-top: 2px; margin-bottom: 0; font-size: 14px; - font-weight: normal; + font-weight: $gl-font-weight-normal; padding: 8px 0; background-color: $white-light; border: 1px solid $dropdown-border-color; @@ -268,7 +268,7 @@ } .dropdown-bold-header { - font-weight: 600; + font-weight: $gl-font-weight-bold; line-height: 22px; padding: 0 16px; } @@ -432,7 +432,7 @@ .dropdown-menu-user-full-name { display: block; - font-weight: 500; + font-weight: $gl-font-weight-normal; line-height: 16px; text-overflow: ellipsis; overflow: hidden; @@ -468,7 +468,7 @@ &.is-indeterminate, &.is-active { - font-weight: 600; + font-weight: $gl-font-weight-bold; color: $gl-text-color; &::before { @@ -502,7 +502,7 @@ position: relative; padding: 2px 25px 10px; margin: 0 10px 10px; - font-weight: 600; + font-weight: $gl-font-weight-bold; line-height: 1; text-align: center; text-overflow: ellipsis; @@ -685,7 +685,7 @@ .dropdown-menu-inner-title { display: block; color: $gl-text-color; - font-weight: 600; + font-weight: $gl-font-weight-bold; } .dropdown-menu-inner-content { diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss index 8dcaa879b3f..a5d33d410fb 100644 --- a/app/assets/stylesheets/framework/filters.scss +++ b/app/assets/stylesheets/framework/filters.scss @@ -371,7 +371,7 @@ } > .value { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } @@ -452,7 +452,7 @@ .dropdown-light-content { font-size: 14px; - font-weight: 400; + font-weight: $gl-font-weight-normal; } .dropdown-user { diff --git a/app/assets/stylesheets/framework/flash.scss b/app/assets/stylesheets/framework/flash.scss index 38d884bc7eb..e1b086ebb2b 100644 --- a/app/assets/stylesheets/framework/flash.scss +++ b/app/assets/stylesheets/framework/flash.scss @@ -25,7 +25,7 @@ a.flash-action { margin-left: 5px; text-decoration: none; - font-weight: normal; + font-weight: $gl-font-weight-normal; border-bottom: 1px solid; &:hover { diff --git a/app/assets/stylesheets/framework/forms.scss b/app/assets/stylesheets/framework/forms.scss index 61e3897f369..be96c8ee964 100644 --- a/app/assets/stylesheets/framework/forms.scss +++ b/app/assets/stylesheets/framework/forms.scss @@ -32,7 +32,7 @@ label { } &.label-light { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } @@ -73,7 +73,7 @@ label { margin-right: 0; .control-label { - font-weight: bold; + font-weight: $gl-font-weight-bold; padding-top: 4px; } @@ -157,7 +157,7 @@ label { .form-group .control-label, .form-group .control-label-full-width { - font-weight: normal; + font-weight: $gl-font-weight-normal; } .form-control::-webkit-input-placeholder { diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss index b677882eba4..35bd97980e2 100644 --- a/app/assets/stylesheets/framework/header.scss +++ b/app/assets/stylesheets/framework/header.scss @@ -160,7 +160,7 @@ header { li { &.active a { - font-weight: bold; + font-weight: $gl-font-weight-bold; } } } @@ -250,7 +250,7 @@ header { font-size: 18px; line-height: 22px; display: inline-block; - font-weight: normal; + font-weight: $gl-font-weight-normal; color: $gl-text-color; vertical-align: top; white-space: nowrap; @@ -326,7 +326,7 @@ header { .badge { position: inherit; top: -8px; - font-weight: normal; + font-weight: $gl-font-weight-normal; margin-left: -11px; font-size: 11px; color: $white-light; diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss index df2bf561194..0fb19344510 100644 --- a/app/assets/stylesheets/framework/lists.scss +++ b/app/assets/stylesheets/framework/lists.scss @@ -113,7 +113,7 @@ ul.content-list { } .title { - font-weight: 600; + font-weight: $gl-font-weight-bold; } a { @@ -212,7 +212,7 @@ ul.content-list { } .row-title { - font-weight: 600; + font-weight: $gl-font-weight-bold; } .row-second-line { diff --git a/app/assets/stylesheets/framework/mixins.scss b/app/assets/stylesheets/framework/mixins.scss index 6f91d11b369..d40b65bb2cc 100644 --- a/app/assets/stylesheets/framework/mixins.scss +++ b/app/assets/stylesheets/framework/mixins.scss @@ -43,7 +43,7 @@ background: $gray-light; a { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } diff --git a/app/assets/stylesheets/framework/modal.scss b/app/assets/stylesheets/framework/modal.scss index a28f54936be..d1f00d3ee2c 100644 --- a/app/assets/stylesheets/framework/modal.scss +++ b/app/assets/stylesheets/framework/modal.scss @@ -8,7 +8,7 @@ } .text-danger { - font-weight: bold; + font-weight: $gl-font-weight-bold; } } diff --git a/app/assets/stylesheets/framework/nav.scss b/app/assets/stylesheets/framework/nav.scss index 071f20fc457..e20108b171b 100644 --- a/app/assets/stylesheets/framework/nav.scss +++ b/app/assets/stylesheets/framework/nav.scss @@ -70,7 +70,7 @@ &.active a { border-bottom: 2px solid $link-underline-blue; color: $black; - font-weight: 600; + font-weight: $gl-font-weight-bold; .badge { color: $black; @@ -352,7 +352,7 @@ z-index: 300; li.active { - font-weight: bold; + font-weight: $gl-font-weight-bold; } } } diff --git a/app/assets/stylesheets/framework/page-header.scss b/app/assets/stylesheets/framework/page-header.scss index f1ecd050a0a..0c879f40930 100644 --- a/app/assets/stylesheets/framework/page-header.scss +++ b/app/assets/stylesheets/framework/page-header.scss @@ -43,7 +43,7 @@ .commit-committer-link, .commit-author-link { color: $gl-text-color; - font-weight: bold; + font-weight: $gl-font-weight-bold; } .commit-info { diff --git a/app/assets/stylesheets/framework/selects.scss b/app/assets/stylesheets/framework/selects.scss index f7a0b355bf1..d93722e2174 100644 --- a/app/assets/stylesheets/framework/selects.scss +++ b/app/assets/stylesheets/framework/selects.scss @@ -76,7 +76,7 @@ } .select2-results li.select2-result-with-children > .select2-result-label { - font-weight: 600; + font-weight: $gl-font-weight-bold; color: $gl-text-color; } @@ -227,7 +227,7 @@ } .group-name { - font-weight: bold; + font-weight: $gl-font-weight-bold; } .group-path { @@ -252,12 +252,12 @@ .namespace-result { .namespace-kind { color: $namespace-kind-color; - font-weight: normal; + font-weight: $gl-font-weight-normal; } .namespace-path { margin-left: 10px; - font-weight: bolder; + font-weight: $gl-font-weight-bold; } } @@ -283,7 +283,7 @@ padding: 0 1px; .select2-match { - font-weight: bold; + font-weight: $gl-font-weight-bold; text-decoration: none; } diff --git a/app/assets/stylesheets/framework/snippets.scss b/app/assets/stylesheets/framework/snippets.scss index 5f7e1b17cc7..30c15c231d5 100644 --- a/app/assets/stylesheets/framework/snippets.scss +++ b/app/assets/stylesheets/framework/snippets.scss @@ -30,7 +30,7 @@ .snippet-title { font-size: 24px; - font-weight: 600; + font-weight: $gl-font-weight-bold; } .snippet-edited-ago { diff --git a/app/assets/stylesheets/framework/tables.scss b/app/assets/stylesheets/framework/tables.scss index 6d9fa74a030..4dd31bf28cd 100644 --- a/app/assets/stylesheets/framework/tables.scss +++ b/app/assets/stylesheets/framework/tables.scss @@ -32,7 +32,7 @@ table { th { background-color: $gray-light; - font-weight: normal; + font-weight: $gl-font-weight-normal; border-bottom: none; &.wide { diff --git a/app/assets/stylesheets/framework/tw_bootstrap.scss b/app/assets/stylesheets/framework/tw_bootstrap.scss index e54cc2866a7..d5c6ddbb4a5 100644 --- a/app/assets/stylesheets/framework/tw_bootstrap.scss +++ b/app/assets/stylesheets/framework/tw_bootstrap.scss @@ -103,7 +103,7 @@ summary { padding: 4px 5px; font-size: 12px; font-style: normal; - font-weight: normal; + font-weight: $gl-font-weight-normal; display: inline-block; &.label-gray { @@ -165,7 +165,7 @@ summary { .panel-heading { padding: 6px 15px; font-size: 13px; - font-weight: normal; + font-weight: $gl-font-weight-normal; a { color: $panel-heading-link-color; diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss index d13f9996518..71eec0e1a5e 100644 --- a/app/assets/stylesheets/framework/typography.scss +++ b/app/assets/stylesheets/framework/typography.scss @@ -74,7 +74,7 @@ h1 { font-size: 1.75em; - font-weight: 600; + font-weight: $gl-font-weight-bold; margin: 24px 0 16px; padding-bottom: 0.3em; border-bottom: 1px solid $white-dark; @@ -87,7 +87,7 @@ h2 { font-size: 1.5em; - font-weight: 600; + font-weight: $gl-font-weight-bold; margin: 24px 0 16px; padding-bottom: 0.3em; border-bottom: 1px solid $white-dark; @@ -280,7 +280,7 @@ body { margin-top: $gl-padding; line-height: 1.3; font-size: 1.25em; - font-weight: 600; + font-weight: $gl-font-weight-bold; &:last-child { margin-bottom: 0; @@ -291,7 +291,7 @@ body { margin-top: 0; line-height: 1.3; font-size: 1.25em; - font-weight: 600; + font-weight: $gl-font-weight-bold; margin: 12px 7px; } @@ -302,11 +302,11 @@ h4, h5, h6 { color: $gl-text-color; - font-weight: 600; + font-weight: $gl-font-weight-bold; } .light-header { - font-weight: 600; + font-weight: $gl-font-weight-bold; } /** CODE **/ diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 225d116e9c7..8a2e64f7bf5 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -111,6 +111,8 @@ $well-light-text-color: #5b6169; * Text */ $gl-font-size: 14px; +$gl-font-weight-normal: 400; +$gl-font-weight-bold: 600; $gl-text-color: #2e2e2e; $gl-text-color-secondary: #707070; $gl-text-color-tertiary: #949494; diff --git a/app/assets/stylesheets/framework/wells.scss b/app/assets/stylesheets/framework/wells.scss index b1ff2659131..5f9756bf58a 100644 --- a/app/assets/stylesheets/framework/wells.scss +++ b/app/assets/stylesheets/framework/wells.scss @@ -69,7 +69,7 @@ .well-centered { h1 { - font-weight: normal; + font-weight: $gl-font-weight-normal; text-align: center; font-size: 48px; } diff --git a/app/assets/stylesheets/highlight/dark.scss b/app/assets/stylesheets/highlight/dark.scss index 6e3829d994f..f0ac9b46f91 100644 --- a/app/assets/stylesheets/highlight/dark.scss +++ b/app/assets/stylesheets/highlight/dark.scss @@ -204,11 +204,11 @@ $dark-il: #de935f; .cs { color: $dark-cs; } /* Comment.Special */ .gd { color: $dark-gd; } /* Generic.Deleted */ .ge { font-style: italic; } /* Generic.Emph */ - .gh { color: $dark-gh; font-weight: bold; } /* Generic.Heading */ + .gh { color: $dark-gh; font-weight: $gl-font-weight-bold; } /* Generic.Heading */ .gi { color: $dark-gi; } /* Generic.Inserted */ - .gp { color: $dark-gp; font-weight: bold; } /* Generic.Prompt */ - .gs { font-weight: bold; } /* Generic.Strong */ - .gu { color: $dark-gu; font-weight: bold; } /* Generic.Subheading */ + .gp { color: $dark-gp; font-weight: $gl-font-weight-bold; } /* Generic.Prompt */ + .gs { font-weight: $gl-font-weight-bold; } /* Generic.Strong */ + .gu { color: $dark-gu; font-weight: $gl-font-weight-bold; } /* Generic.Subheading */ .kc { color: $dark-kc; } /* Keyword.Constant */ .kd { color: $dark-kd; } /* Keyword.Declaration */ .kn { color: $dark-kn; } /* Keyword.Namespace */ diff --git a/app/assets/stylesheets/highlight/monokai.scss b/app/assets/stylesheets/highlight/monokai.scss index 68eb0c7720f..eba7919ada9 100644 --- a/app/assets/stylesheets/highlight/monokai.scss +++ b/app/assets/stylesheets/highlight/monokai.scss @@ -203,7 +203,7 @@ $monokai-gi: #a6e22e; .c1 { color: $monokai-c1; } /* Comment.Single */ .cs { color: $monokai-cs; } /* Comment.Special */ .ge { font-style: italic; } /* Generic.Emph */ - .gs { font-weight: bold; } /* Generic.Strong */ + .gs { font-weight: $gl-font-weight-bold; } /* Generic.Strong */ .kc { color: $monokai-kc; } /* Keyword.Constant */ .kd { color: $monokai-kd; } /* Keyword.Declaration */ .kn { color: $monokai-kn; } /* Keyword.Namespace */ diff --git a/app/assets/stylesheets/highlight/solarized_dark.scss b/app/assets/stylesheets/highlight/solarized_dark.scss index 2cc968c32f2..ba53ef0352b 100644 --- a/app/assets/stylesheets/highlight/solarized_dark.scss +++ b/app/assets/stylesheets/highlight/solarized_dark.scss @@ -231,7 +231,7 @@ $solarized-dark-il: #2aa198; .gi { color: $solarized-dark-gi; } /* Generic.Inserted */ .go { color: $solarized-dark-go; } /* Generic.Output */ .gp { color: $solarized-dark-gp; } /* Generic.Prompt */ - .gs { color: $solarized-dark-gs; font-weight: bold; } /* Generic.Strong */ + .gs { color: $solarized-dark-gs; font-weight: $gl-font-weight-bold; } /* Generic.Strong */ .gu { color: $solarized-dark-gu; } /* Generic.Subheading */ .gt { color: $solarized-dark-gt; } /* Generic.Traceback */ .kc { color: $solarized-dark-kc; } /* Keyword.Constant */ diff --git a/app/assets/stylesheets/highlight/solarized_light.scss b/app/assets/stylesheets/highlight/solarized_light.scss index b61b85a2cd1..e9fccf1b58a 100644 --- a/app/assets/stylesheets/highlight/solarized_light.scss +++ b/app/assets/stylesheets/highlight/solarized_light.scss @@ -239,7 +239,7 @@ $solarized-light-il: #2aa198; .gi { color: $solarized-light-gi; } /* Generic.Inserted */ .go { color: $solarized-light-go; } /* Generic.Output */ .gp { color: $solarized-light-gp; } /* Generic.Prompt */ - .gs { color: $solarized-light-gs; font-weight: bold; } /* Generic.Strong */ + .gs { color: $solarized-light-gs; font-weight: $gl-font-weight-bold; } /* Generic.Strong */ .gu { color: $solarized-light-gu; } /* Generic.Subheading */ .gt { color: $solarized-light-gt; } /* Generic.Traceback */ .kc { color: $solarized-light-kc; } /* Keyword.Constant */ diff --git a/app/assets/stylesheets/highlight/white.scss b/app/assets/stylesheets/highlight/white.scss index 578f1902cce..65b140cd7f8 100644 --- a/app/assets/stylesheets/highlight/white.scss +++ b/app/assets/stylesheets/highlight/white.scss @@ -211,12 +211,12 @@ $white-gc-bg: #eaf2f5; .hll { background-color: $white-hll-bg; } .c { color: $white-c; font-style: italic; } .err { color: $white-err; background-color: $white-err-bg; } - .k { font-weight: bold; } - .o { font-weight: bold; } + .k { font-weight: $gl-font-weight-bold; } + .o { font-weight: $gl-font-weight-bold; } .cm { color: $white-cm; font-style: italic; } - .cp { color: $white-cp; font-weight: bold; } + .cp { color: $white-cp; font-weight: $gl-font-weight-bold; } .c1 { color: $white-c1; font-style: italic; } - .cs { color: $white-cs; font-weight: bold; font-style: italic; } + .cs { color: $white-cs; font-weight: $gl-font-weight-bold; font-style: italic; } .gd { color: $white-gd; background-color: $white-gd-bg; } .gd .x { color: $white-gd-x; background-color: $white-gd-x-bg; } .ge { font-style: italic; } @@ -226,29 +226,29 @@ $white-gc-bg: #eaf2f5; .gi .x { color: $white-gi-x; background-color: $white-gi-x-bg; } .go { color: $white-go; } .gp { color: $white-gp; } - .gs { font-weight: bold; } - .gu { color: $white-gu; font-weight: bold; } + .gs { font-weight: $gl-font-weight-bold; } + .gu { color: $white-gu; font-weight: $gl-font-weight-bold; } .gt { color: $white-gt; } - .kc { font-weight: bold; } - .kd { font-weight: bold; } - .kn { font-weight: bold; } - .kp { font-weight: bold; } - .kr { font-weight: bold; } - .kt { color: $white-kt; font-weight: bold; } + .kc { font-weight: $gl-font-weight-bold; } + .kd { font-weight: $gl-font-weight-bold; } + .kn { font-weight: $gl-font-weight-bold; } + .kp { font-weight: $gl-font-weight-bold; } + .kr { font-weight: $gl-font-weight-bold; } + .kt { color: $white-kt; font-weight: $gl-font-weight-bold; } .m { color: $white-m; } .s { color: $white-s; } .n { color: $white-n; } .na { color: $white-na; } .nb { color: $white-nb; } - .nc { color: $white-nc; font-weight: bold; } + .nc { color: $white-nc; font-weight: $gl-font-weight-bold; } .no { color: $white-no; } .ni { color: $white-ni; } - .ne { color: $white-ne; font-weight: bold; } - .nf { color: $white-nf; font-weight: bold; } + .ne { color: $white-ne; font-weight: $gl-font-weight-bold; } + .nf { color: $white-nf; font-weight: $gl-font-weight-bold; } .nn { color: $white-nn; } .nt { color: $white-nt; } .nv { color: $white-nv; } - .ow { font-weight: bold; } + .ow { font-weight: $gl-font-weight-bold; } .w { color: $white-w; } .mf { color: $white-mf; } .mh { color: $white-mh; } diff --git a/app/assets/stylesheets/mailers/highlighted_diff_email.scss b/app/assets/stylesheets/mailers/highlighted_diff_email.scss index ea40f449134..fbe538ad1d7 100644 --- a/app/assets/stylesheets/mailers/highlighted_diff_email.scss +++ b/app/assets/stylesheets/mailers/highlighted_diff_email.scss @@ -152,12 +152,12 @@ span.highlight_word { .hll { background-color: $highlighted-hll-bg; } .c { color: $highlighted-c; font-style: italic; } .err { color: $highlighted-err; background-color: $highlighted-err-bg; } -.k { font-weight: bold; } -.o { font-weight: bold; } +.k { font-weight: $gl-font-weight-bold; } +.o { font-weight: $gl-font-weight-bold; } .cm { color: $highlighted-cm; font-style: italic; } -.cp { color: $highlighted-cp; font-weight: bold; } +.cp { color: $highlighted-cp; font-weight: $gl-font-weight-bold; } .c1 { color: $highlighted-c1; font-style: italic; } -.cs { color: $highlighted-cs; font-weight: bold; font-style: italic; } +.cs { color: $highlighted-cs; font-weight: $gl-font-weight-bold; font-style: italic; } .gd { color: $highlighted-gd; background-color: $highlighted-gd-bg; } .gd .x { color: $highlighted-gd; background-color: $highlighted-gd-x-bg; } .ge { font-style: italic; } @@ -167,29 +167,29 @@ span.highlight_word { .gi .x { color: $highlighted-gi; background-color: $highlighted-gi-x-bg; } .go { color: $highlighted-go; } .gp { color: $highlighted-gp; } -.gs { font-weight: bold; } -.gu { color: $highlighted-gu; font-weight: bold; } +.gs { font-weight: $gl-font-weight-bold; } +.gu { color: $highlighted-gu; font-weight: $gl-font-weight-bold; } .gt { color: $highlighted-gt; } -.kc { font-weight: bold; } -.kd { font-weight: bold; } -.kn { font-weight: bold; } -.kp { font-weight: bold; } -.kr { font-weight: bold; } -.kt { color: $highlighted-kt; font-weight: bold; } +.kc { font-weight: $gl-font-weight-bold; } +.kd { font-weight: $gl-font-weight-bold; } +.kn { font-weight: $gl-font-weight-bold; } +.kp { font-weight: $gl-font-weight-bold; } +.kr { font-weight: $gl-font-weight-bold; } +.kt { color: $highlighted-kt; font-weight: $gl-font-weight-bold; } .m { color: $highlighted-m; } .s { color: $highlighted-s; } .n { color: $highlighted-n; } .na { color: $highlighted-na; } .nb { color: $highlighted-nb; } -.nc { color: $highlighted-nc; font-weight: bold; } +.nc { color: $highlighted-nc; font-weight: $gl-font-weight-bold; } .no { color: $highlighted-no; } .ni { color: $highlighted-ni; } -.ne { color: $highlighted-ne; font-weight: bold; } -.nf { color: $highlighted-nf; font-weight: bold; } +.ne { color: $highlighted-ne; font-weight: $gl-font-weight-bold; } +.nf { color: $highlighted-nf; font-weight: $gl-font-weight-bold; } .nn { color: $highlighted-nn; } .nt { color: $highlighted-nt; } .nv { color: $highlighted-nv; } -.ow { font-weight: bold; } +.ow { font-weight: $gl-font-weight-bold; } .w { color: $highlighted-w; } .mf { color: $highlighted-mf; } .mh { color: $highlighted-mh; } diff --git a/app/assets/stylesheets/new_nav.scss b/app/assets/stylesheets/new_nav.scss index 3e2f23e6b2a..54fa4109f8b 100644 --- a/app/assets/stylesheets/new_nav.scss +++ b/app/assets/stylesheets/new_nav.scss @@ -134,7 +134,7 @@ header.navbar-gitlab-new { li { .badge { box-shadow: none; - font-weight: 600; + font-weight: $gl-font-weight-bold; } } } @@ -193,7 +193,7 @@ header.navbar-gitlab-new { &.active > a { box-shadow: inset 0 -3px 0 $indigo-500; color: $white-light; - font-weight: 700; + font-weight: $gl-font-weight-bold; } > a { @@ -371,7 +371,7 @@ header.navbar-gitlab-new { > a { &:last-of-type:not(:first-child) { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } } @@ -411,7 +411,7 @@ header.navbar-gitlab-new { .breadcrumbs-sub-title { margin: 2px 0; font-size: 16px; - font-weight: normal; + font-weight: $gl-font-weight-normal; line-height: 1; ul { @@ -430,7 +430,7 @@ header.navbar-gitlab-new { } &:last-child a { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } diff --git a/app/assets/stylesheets/new_sidebar.scss b/app/assets/stylesheets/new_sidebar.scss index cee5b22adb9..a74d53b4f68 100644 --- a/app/assets/stylesheets/new_sidebar.scss +++ b/app/assets/stylesheets/new_sidebar.scss @@ -46,7 +46,7 @@ $new-sidebar-collapsed-width: 50px; a { border-bottom: 1px solid $border-color; - font-weight: 600; + font-weight: $gl-font-weight-bold; display: flex; align-items: center; padding: 10px 16px 10px 10px; @@ -160,7 +160,7 @@ $new-sidebar-collapsed-width: 50px; > a { color: $active-color; - font-weight: 700; + font-weight: $gl-font-weight-bold; } svg { @@ -308,7 +308,7 @@ $new-sidebar-collapsed-width: 50px; .badge { color: $active-color; - font-weight: 600; + font-weight: $gl-font-weight-bold; } .sidebar-sub-level-items { @@ -474,6 +474,6 @@ $new-sidebar-collapsed-width: 50px; border-bottom-color: $active-border; .badge { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss index e5b467a2691..0f3074076ce 100644 --- a/app/assets/stylesheets/pages/boards.scss +++ b/app/assets/stylesheets/pages/boards.scss @@ -471,7 +471,7 @@ padding-right: 35px; > strong { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } } diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss index 486424fb729..3d04df8d820 100644 --- a/app/assets/stylesheets/pages/builds.scss +++ b/app/assets/stylesheets/pages/builds.scss @@ -277,7 +277,7 @@ } .trigger-build-variable { - font-weight: normal; + font-weight: $gl-font-weight-normal; color: $code-color; } @@ -378,7 +378,7 @@ } &.active { - font-weight: bold; + font-weight: $gl-font-weight-bold; .fa-arrow-right { display: block; diff --git a/app/assets/stylesheets/pages/ci_projects.scss b/app/assets/stylesheets/pages/ci_projects.scss index 7b4eb689f1b..bf6a48889bf 100644 --- a/app/assets/stylesheets/pages/ci_projects.scss +++ b/app/assets/stylesheets/pages/ci_projects.scss @@ -22,7 +22,7 @@ vertical-align: middle !important; a { - font-weight: normal; + font-weight: $gl-font-weight-normal; text-decoration: none; } } diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss index d0d11b4d71c..c051d37aad6 100644 --- a/app/assets/stylesheets/pages/commits.scss +++ b/app/assets/stylesheets/pages/commits.scss @@ -213,7 +213,7 @@ .commit-sha { font-size: 14px; - font-weight: 600; + font-weight: $gl-font-weight-bold; } } @@ -306,7 +306,7 @@ .gpg-popover-status { display: flex; align-items: center; - font-weight: normal; + font-weight: $gl-font-weight-normal; line-height: 1.5; } diff --git a/app/assets/stylesheets/pages/convdev_index.scss b/app/assets/stylesheets/pages/convdev_index.scss index 0413114c279..16702442f50 100644 --- a/app/assets/stylesheets/pages/convdev_index.scss +++ b/app/assets/stylesheets/pages/convdev_index.scss @@ -23,7 +23,7 @@ $space-between-cards: 8px; line-height: 1; color: $gl-text-color-secondary; margin-left: 8px; - font-weight: 500; + font-weight: $gl-font-weight-normal; a { font-size: 18px; @@ -139,7 +139,7 @@ $space-between-cards: 8px; .card-score-value { font-size: 16px; color: $gl-text-color; - font-weight: 500; + font-weight: $gl-font-weight-normal; } .card-score-big { @@ -147,7 +147,7 @@ $space-between-cards: 8px; border-bottom: 1px solid $border-color; font-size: 22px; padding: 10px 0; - font-weight: 500; + font-weight: $gl-font-weight-normal; } .card-buttons { diff --git a/app/assets/stylesheets/pages/cycle_analytics.scss b/app/assets/stylesheets/pages/cycle_analytics.scss index 6753eb08285..2a92673d9fa 100644 --- a/app/assets/stylesheets/pages/cycle_analytics.scss +++ b/app/assets/stylesheets/pages/cycle_analytics.scss @@ -68,7 +68,7 @@ } .stage-name { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } @@ -93,7 +93,7 @@ .header { font-size: 30px; line-height: 38px; - font-weight: normal; + font-weight: $gl-font-weight-normal; margin: 0; } @@ -130,7 +130,7 @@ &.title { line-height: 19px; font-size: 14px; - font-weight: 600; + font-weight: $gl-font-weight-bold; color: $gl-text-color; } @@ -211,7 +211,7 @@ box-shadow: inset 2px 0 0 0 $active-item-blue; .stage-name { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } @@ -404,7 +404,7 @@ color: $gl-link-color; line-height: 1.3; vertical-align: top; - font-weight: normal; + font-weight: $gl-font-weight-normal; } .fa { diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss index 913a1a95dca..8cbf0ec6180 100644 --- a/app/assets/stylesheets/pages/diff.scss +++ b/app/assets/stylesheets/pages/diff.scss @@ -40,7 +40,7 @@ // "Changes suppressed. Click to show." link .show-suppressed-diff { font-size: 110%; - font-weight: bold; + font-weight: $gl-font-weight-bold; } } @@ -104,7 +104,7 @@ a { float: left; width: 35px; - font-weight: normal; + font-weight: $gl-font-weight-normal; &[disabled] { cursor: default; @@ -395,7 +395,7 @@ background-color: transparent; border: 0; color: $gl-link-color; - font-weight: 600; + font-weight: $gl-font-weight-bold; &:hover, &:focus { diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss index 00ebf4e26ac..a8d2ae0af28 100644 --- a/app/assets/stylesheets/pages/environments.scss +++ b/app/assets/stylesheets/pages/environments.scss @@ -6,7 +6,7 @@ } .environments-folder-name { - font-weight: normal; + font-weight: $gl-font-weight-normal; padding-top: 20px; } @@ -246,13 +246,13 @@ } .text-metric-bold { - font-weight: 600; + font-weight: $gl-font-weight-bold; } .label-axis-text, .text-metric-usage { fill: $black; - font-weight: 500; + font-weight: $gl-font-weight-normal; font-size: 12px; } diff --git a/app/assets/stylesheets/pages/events.scss b/app/assets/stylesheets/pages/events.scss index 4c3fa1fb8d4..1723d716805 100644 --- a/app/assets/stylesheets/pages/events.scss +++ b/app/assets/stylesheets/pages/events.scss @@ -57,7 +57,7 @@ .event-title { @include str-truncated(calc(100% - 174px)); - font-weight: 600; + font-weight: $gl-font-weight-bold; color: $list-text-color; } diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index 49839a9b528..ab5a901da71 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -271,7 +271,7 @@ } .light { - font-weight: normal; + font-weight: $gl-font-weight-normal; } .no-value { @@ -306,7 +306,7 @@ display: block; margin-top: 4px; font-size: 13px; - font-weight: normal; + font-weight: $gl-font-weight-normal; } .hide-expanded { @@ -689,7 +689,7 @@ .issuable-info, .task-status, .issuable-updated-at { - font-weight: normal; + font-weight: $gl-font-weight-normal; color: $gl-text-color-secondary; a { diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index 8cdb3f34ae5..e2177f96aee 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -75,7 +75,7 @@ ul.related-merge-requests > li { .merge-requests-title, .related-branches-title { font-size: 16px; - font-weight: 600; + font-weight: $gl-font-weight-bold; } .merge-request-id { @@ -244,7 +244,7 @@ ul.related-merge-requests > li { strong { display: block; - font-weight: 600; + font-weight: $gl-font-weight-bold; } } } diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss index 3cbe8dededb..d4dc43035eb 100644 --- a/app/assets/stylesheets/pages/login.scss +++ b/app/assets/stylesheets/pages/login.scss @@ -22,7 +22,7 @@ } h1:first-child { - font-weight: normal; + font-weight: $gl-font-weight-normal; margin-bottom: 0.68em; margin-top: 0; font-size: 34px; @@ -38,7 +38,7 @@ } a { - font-weight: bold; + font-weight: $gl-font-weight-bold; } } @@ -54,7 +54,7 @@ padding: 15px; .login-heading h3 { - font-weight: 300; + font-weight: $gl-font-weight-normal; line-height: 1.5; margin: 0 0 10px; } @@ -186,7 +186,7 @@ } label { - font-weight: normal; + font-weight: $gl-font-weight-normal; } .submit-container { diff --git a/app/assets/stylesheets/pages/members.scss b/app/assets/stylesheets/pages/members.scss index e7c07ef67f0..a385eb359e1 100644 --- a/app/assets/stylesheets/pages/members.scss +++ b/app/assets/stylesheets/pages/members.scss @@ -46,7 +46,7 @@ } strong { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } @@ -221,7 +221,7 @@ } .member { - font-weight: bold; + font-weight: $gl-font-weight-bold; overflow-wrap: break-word; word-break: break-all; } diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index 6bb013cca85..d1678a17aaf 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -197,7 +197,7 @@ @extend .ref-name; color: $gl-text-color; - font-weight: 600; + font-weight: $gl-font-weight-bold; overflow: hidden; word-break: break-all; @@ -228,7 +228,7 @@ .mr-widget-body { h4 { float: left; - font-weight: 600; + font-weight: $gl-font-weight-bold; font-size: 14px; line-height: inherit; margin-top: 0; @@ -239,7 +239,7 @@ } time { - font-weight: normal; + font-weight: $gl-font-weight-normal; } } @@ -249,7 +249,7 @@ } label { - font-weight: normal; + font-weight: $gl-font-weight-normal; } .spacing { @@ -257,12 +257,12 @@ } .bold { - font-weight: 600; + font-weight: $gl-font-weight-bold; color: $gl-gray-light; } .state-label { - font-weight: 600; + font-weight: $gl-font-weight-bold; padding-right: 10px; } @@ -336,7 +336,7 @@ .text { span { - font-weight: 600; + font-weight: $gl-font-weight-bold; } p { @@ -505,7 +505,7 @@ .panel-new-merge-request { .panel-heading { padding: 5px 10px; - font-weight: 600; + font-weight: $gl-font-weight-bold; line-height: 25px; } diff --git a/app/assets/stylesheets/pages/milestone.scss b/app/assets/stylesheets/pages/milestone.scss index 55e0ee1936e..32039936be7 100644 --- a/app/assets/stylesheets/pages/milestone.scss +++ b/app/assets/stylesheets/pages/milestone.scss @@ -7,7 +7,7 @@ padding: 10px 16px; h4 { - font-weight: bold; + font-weight: $gl-font-weight-bold; } .progress { @@ -81,7 +81,7 @@ } .remaining-days strong { - font-weight: normal; + font-weight: $gl-font-weight-normal; } .milestone-stat { diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss index b4468d6d0a2..9558924bbcb 100644 --- a/app/assets/stylesheets/pages/note_form.scss +++ b/app/assets/stylesheets/pages/note_form.scss @@ -188,7 +188,7 @@ .close { color: $white-light; opacity: 0.85; - font-weight: normal; + font-weight: $gl-font-weight-normal; &:hover { opacity: 1; diff --git a/app/assets/stylesheets/pages/pipeline_schedules.scss b/app/assets/stylesheets/pages/pipeline_schedules.scss index dc1654e006e..7e2297c283f 100644 --- a/app/assets/stylesheets/pages/pipeline_schedules.scss +++ b/app/assets/stylesheets/pages/pipeline_schedules.scss @@ -12,7 +12,7 @@ .interval-pattern-form-group { label { margin-right: 10px; - font-weight: normal; + font-weight: $gl-font-weight-normal; &[for='custom'] { margin-right: 0; diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 85d1905ad40..a408bde37d6 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -128,7 +128,7 @@ .branch-commit { .ref-name { - font-weight: bold; + font-weight: $gl-font-weight-bold; max-width: 120px; overflow: hidden; display: inline-block; @@ -272,7 +272,7 @@ .build-name { float: right; - font-weight: 500; + font-weight: $gl-font-weight-normal; } .ci-status-icon-failed svg { @@ -281,7 +281,7 @@ .stage { color: $gl-text-color-secondary; - font-weight: 500; + font-weight: $gl-font-weight-normal; vertical-align: middle; } } @@ -420,7 +420,7 @@ .stage-name { margin: 0 0 15px 10px; - font-weight: bold; + font-weight: $gl-font-weight-bold; width: 176px; white-space: nowrap; overflow: hidden; @@ -580,7 +580,7 @@ vertical-align: bottom; display: inline-block; position: relative; - font-weight: normal; + font-weight: $gl-font-weight-normal; } @mixin mini-pipeline-graph-color($color-light, $color-main, $color-dark) { @@ -724,7 +724,7 @@ button.mini-pipeline-graph-dropdown-toggle { .mini-pipeline-graph-dropdown-item { padding: 3px 7px 4px; clear: both; - font-weight: normal; + font-weight: $gl-font-weight-normal; line-height: 1.428571429; white-space: nowrap; margin: 0 5px; diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss index 14ad06b0ac2..c5d6ff66dd6 100644 --- a/app/assets/stylesheets/pages/profile.scss +++ b/app/assets/stylesheets/pages/profile.scss @@ -83,7 +83,7 @@ &::after { content: "\00B7"; // Middle Dot padding: 0 6px; - font-weight: bold; + font-weight: $gl-font-weight-bold; } &:last-child { @@ -277,7 +277,7 @@ table.u2f-registrations { .oauth-application-show { .scope-name { - font-weight: 600; + font-weight: $gl-font-weight-bold; } .scopes-list { diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index d01326637ea..39c4264e496 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -2,7 +2,7 @@ margin: -16px; .alert-link { - font-weight: normal; + font-weight: $gl-font-weight-normal; } } @@ -114,7 +114,7 @@ margin-top: 10px; margin-bottom: 10px; font-size: 24px; - font-weight: 400; + font-weight: $gl-font-weight-normal; line-height: 1; word-wrap: break-word; @@ -259,7 +259,7 @@ border-width: 1px; border-style: solid; font-size: 13px; - font-weight: 600; + font-weight: $gl-font-weight-bold; line-height: 13px; letter-spacing: .4px; padding: 6px 14px; @@ -309,7 +309,7 @@ } .option-title { - font-weight: normal; + font-weight: $gl-font-weight-normal; display: inline-block; color: $gl-text-color; } @@ -575,7 +575,7 @@ a.deploy-project-label { color: $gl-text-color-tertiary; transform: translateY(-50%); font-size: 12px; - font-weight: bold; + font-weight: $gl-font-weight-bold; line-height: 20px; // Mobile @@ -826,7 +826,7 @@ pre.light-well { .new-protected-tag { label { margin-top: 6px; - font-weight: normal; + font-weight: $gl-font-weight-normal; } } @@ -853,7 +853,7 @@ pre.light-well { } &.is-active { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } @@ -952,7 +952,7 @@ pre.light-well { &::before { font-family: FontAwesome; - font-weight: normal; + font-weight: $gl-font-weight-normal; font-style: normal; } } diff --git a/app/assets/stylesheets/pages/repo.scss b/app/assets/stylesheets/pages/repo.scss index 1f4d4698199..37971d6bd3a 100644 --- a/app/assets/stylesheets/pages/repo.scss +++ b/app/assets/stylesheets/pages/repo.scss @@ -267,7 +267,7 @@ display: inline-block; font-size: 10px; text-transform: uppercase; - font-weight: bold; + font-weight: $gl-font-weight-bold; color: $gray-darkest; white-space: nowrap; overflow: hidden; diff --git a/app/assets/stylesheets/pages/runners.scss b/app/assets/stylesheets/pages/runners.scss index 57c73295d1e..6cac37a4e28 100644 --- a/app/assets/stylesheets/pages/runners.scss +++ b/app/assets/stylesheets/pages/runners.scss @@ -30,7 +30,7 @@ } h4 { - font-weight: normal; + font-weight: $gl-font-weight-normal; } } diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss index b9818ffcf42..8d73246223d 100644 --- a/app/assets/stylesheets/pages/search.scss +++ b/app/assets/stylesheets/pages/search.scss @@ -94,7 +94,7 @@ input[type="checkbox"]:hover { &::before { font-family: FontAwesome; - font-weight: normal; + font-weight: $gl-font-weight-normal; font-style: normal; } } diff --git a/app/assets/stylesheets/pages/sherlock.scss b/app/assets/stylesheets/pages/sherlock.scss index 23a9c2ada80..bfe065dbbaf 100644 --- a/app/assets/stylesheets/pages/sherlock.scss +++ b/app/assets/stylesheets/pages/sherlock.scss @@ -29,5 +29,5 @@ table .sherlock-code { .sherlock-line-samples-table .slow { color: $red-500; - font-weight: bold; + font-weight: $gl-font-weight-bold; } diff --git a/app/assets/stylesheets/pages/todos.scss b/app/assets/stylesheets/pages/todos.scss index d7a9dda3770..5b9fafe31bd 100644 --- a/app/assets/stylesheets/pages/todos.scss +++ b/app/assets/stylesheets/pages/todos.scss @@ -108,14 +108,14 @@ margin: 0; float: none; display: inline-block; - font-weight: normal; + font-weight: $gl-font-weight-normal; padding: 0 5px; line-height: inherit; font-size: 14px; } .action-name { - font-weight: normal; + font-weight: $gl-font-weight-normal; } .todo-body { @@ -262,6 +262,6 @@ } a { - font-weight: 600; + font-weight: $gl-font-weight-bold; } } diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss index 0028e207f3e..224eee90a3f 100644 --- a/app/assets/stylesheets/pages/tree.scss +++ b/app/assets/stylesheets/pages/tree.scss @@ -231,7 +231,7 @@ } .upload-link { - font-weight: normal; + font-weight: $gl-font-weight-normal; color: $md-link-color; } diff --git a/app/assets/stylesheets/pages/ui_dev_kit.scss b/app/assets/stylesheets/pages/ui_dev_kit.scss index 798e060a261..48ac5b21db8 100644 --- a/app/assets/stylesheets/pages/ui_dev_kit.scss +++ b/app/assets/stylesheets/pages/ui_dev_kit.scss @@ -1,7 +1,7 @@ .gitlab-ui-dev-kit { > h2 { margin: 35px 0 20px; - font-weight: bold; + font-weight: $gl-font-weight-bold; } .example { diff --git a/app/assets/stylesheets/pages/wiki.scss b/app/assets/stylesheets/pages/wiki.scss index fa6bdd297eb..b7d4e7bf582 100644 --- a/app/assets/stylesheets/pages/wiki.scss +++ b/app/assets/stylesheets/pages/wiki.scss @@ -37,7 +37,7 @@ } .light { - font-weight: normal; + font-weight: $gl-font-weight-normal; color: $gl-text-color-secondary; } @@ -89,7 +89,7 @@ h3 { font-size: 19px; - font-weight: normal; + font-weight: $gl-font-weight-normal; margin: $gl-padding 0; } } diff --git a/app/assets/stylesheets/pages/xterm.scss b/app/assets/stylesheets/pages/xterm.scss index b085c56390d..c7297a34ad8 100644 --- a/app/assets/stylesheets/pages/xterm.scss +++ b/app/assets/stylesheets/pages/xterm.scss @@ -281,7 +281,7 @@ $xterm-fg-255: #eee; .term-bold { - font-weight: bold; + font-weight: $gl-font-weight-bold; } .term-italic { diff --git a/app/assets/stylesheets/print.scss b/app/assets/stylesheets/print.scss index 113e6e86bb5..b07a5ae22cd 100644 --- a/app/assets/stylesheets/print.scss +++ b/app/assets/stylesheets/print.scss @@ -17,7 +17,7 @@ .wiki h3 { font-size: 18px; - font-weight: bold; + font-weight: 600; } header, diff --git a/app/views/layouts/errors.html.haml b/app/views/layouts/errors.html.haml index 6d9ec043590..9382ee8715e 100644 --- a/app/views/layouts/errors.html.haml +++ b/app/views/layouts/errors.html.haml @@ -15,7 +15,7 @@ h1 { font-size: 56px; line-height: 100px; - font-weight: normal; + font-weight: 400; color: #456; } @@ -28,7 +28,7 @@ h3 { color: #456; font-size: 20px; - font-weight: normal; + font-weight: 400; line-height: 28px; } diff --git a/app/views/layouts/oauth_error.html.haml b/app/views/layouts/oauth_error.html.haml index 34bcd2a8b3a..03b387f8181 100644 --- a/app/views/layouts/oauth_error.html.haml +++ b/app/views/layouts/oauth_error.html.haml @@ -19,7 +19,7 @@ h3 { color: #456; font-size: 22px; - font-weight: bold; + font-weight: 600; margin-bottom: 6px; } diff --git a/changelogs/unreleased/font-weight-adjusted.yml b/changelogs/unreleased/font-weight-adjusted.yml new file mode 100644 index 00000000000..827f3485099 --- /dev/null +++ b/changelogs/unreleased/font-weight-adjusted.yml @@ -0,0 +1,5 @@ +--- +title: Changed all font-weight values to 400 and 600 and introduced 2 variables to + manage them +merge_request: !12896 +author: diff --git a/public/404.html b/public/404.html index 03e98e81862..4db72be6f8c 100644 --- a/public/404.html +++ b/public/404.html @@ -15,7 +15,7 @@ h1 { font-size: 56px; line-height: 100px; - font-weight: normal; + font-weight: 400; color: #456; } @@ -28,7 +28,7 @@ h3 { color: #456; font-size: 20px; - font-weight: normal; + font-weight: 400; line-height: 28px; } @@ -48,7 +48,7 @@ a { line-height: 100px; - font-weight: normal; + font-weight: 400; color: #4A8BEE; font-size: 18px; text-decoration: none; diff --git a/public/422.html b/public/422.html index 49ebbe40f39..a67dcd02200 100644 --- a/public/422.html +++ b/public/422.html @@ -15,7 +15,7 @@ h1 { font-size: 56px; line-height: 100px; - font-weight: normal; + font-weight: 400; color: #456; } @@ -28,7 +28,7 @@ h3 { color: #456; font-size: 20px; - font-weight: normal; + font-weight: 400; line-height: 28px; } @@ -48,7 +48,7 @@ a { line-height: 100px; - font-weight: normal; + font-weight: 400; color: #4A8BEE; font-size: 18px; text-decoration: none; diff --git a/public/500.html b/public/500.html index 516920f7471..7091d14dfc4 100644 --- a/public/500.html +++ b/public/500.html @@ -15,7 +15,7 @@ h1 { font-size: 56px; line-height: 100px; - font-weight: normal; + font-weight: 400; color: #456; } @@ -28,7 +28,7 @@ h3 { color: #456; font-size: 20px; - font-weight: normal; + font-weight: 400; line-height: 28px; } @@ -48,7 +48,7 @@ a { line-height: 100px; - font-weight: normal; + font-weight: 400; color: #4A8BEE; font-size: 18px; text-decoration: none; diff --git a/public/502.html b/public/502.html index 189458c9816..82afd273248 100644 --- a/public/502.html +++ b/public/502.html @@ -15,7 +15,7 @@ h1 { font-size: 56px; line-height: 100px; - font-weight: normal; + font-weight: 400; color: #456; } @@ -28,7 +28,7 @@ h3 { color: #456; font-size: 20px; - font-weight: normal; + font-weight: 400; line-height: 28px; } @@ -48,7 +48,7 @@ a { line-height: 100px; - font-weight: normal; + font-weight: 400; color: #4A8BEE; font-size: 18px; text-decoration: none; diff --git a/public/503.html b/public/503.html index b09b0e2a67e..f1486bc3e84 100644 --- a/public/503.html +++ b/public/503.html @@ -15,7 +15,7 @@ h1 { font-size: 56px; line-height: 100px; - font-weight: normal; + font-weight: 400; color: #456; } @@ -28,7 +28,7 @@ h3 { color: #456; font-size: 20px; - font-weight: normal; + font-weight: 400; line-height: 28px; } @@ -48,7 +48,7 @@ a { line-height: 100px; - font-weight: normal; + font-weight: 400; color: #4A8BEE; font-size: 18px; text-decoration: none; diff --git a/public/deploy.html b/public/deploy.html index 49ec4ac5ce1..e463b62520c 100644 --- a/public/deploy.html +++ b/public/deploy.html @@ -20,7 +20,7 @@ h1 { font-size: 56px; line-height: 100px; - font-weight: normal; + font-weight: 400; color: #456; } @@ -33,7 +33,7 @@ h3 { color: #456; font-size: 20px; - font-weight: normal; + font-weight: 400; line-height: 28px; } @@ -66,4 +66,4 @@

Please contact your GitLab administrator if this problem persists.

- \ No newline at end of file + diff --git a/spec/fixtures/emails/ios_default.eml b/spec/fixtures/emails/ios_default.eml index 8d4d58feb16..fa19475104a 100644 --- a/spec/fixtures/emails/ios_default.eml +++ b/spec/fixtures/emails/ios_default.eml @@ -76,7 +76,7 @@ Content-Transfer-Encoding: 7bit -
techAPJ
+ techAPJ
November 28 @@ -94,7 +94,7 @@ Content-Transfer-Encoding: 7bit
-

To respond, reply to this email or visit https://meta.discourse.org/t/testing-default-email-replies/22638/3 in your browser.

+

To respond, reply to this email or visit https://meta.discourse.org/t/testing-default-email-replies/22638/3 in your browser.


Previous Replies

@@ -106,7 +106,7 @@ Content-Transfer-Encoding: 7bit - codinghorror
+ codinghorror
November 28 @@ -114,7 +114,7 @@ Content-Transfer-Encoding: 7bit

We're testing the latest GitHub email processing library which we are integrating now.

-

https://github.com/github/email_reply_parser

+

https://github.com/github/email_reply_parser

Go ahead and reply to this topic and I'll reply from various email clients for testing.

@@ -126,10 +126,10 @@ Content-Transfer-Encoding: 7bit
-

To respond, reply to this email or visit https://meta.discourse.org/t/testing-default-email-replies/22638/3 in your browser.

+

To respond, reply to this email or visit https://meta.discourse.org/t/testing-default-email-replies/22638/3 in your browser.

-

To unsubscribe from these emails, visit your user preferences.

+

To unsubscribe from these emails, visit your user preferences.

diff --git a/spec/fixtures/emails/on_wrote.eml b/spec/fixtures/emails/on_wrote.eml index feb59bd27bb..af6a4e50a49 100644 --- a/spec/fixtures/emails/on_wrote.eml +++ b/spec/fixtures/emails/on_wrote.eml @@ -53,7 +53,7 @@ y > display: inline-block; > font-family: FontAwesome; > font-style: normal; -> font-weight: normal; +> font-weight: 400; > line-height: 1; > -webkit-font-smoothing: antialiased; > -moz-osx-font-smoothing: grayscale; @@ -227,7 +227,7 @@ ding:5px">.fa { display: inline-block; font-family: FontAwesome; font-style: normal; - font-weight: normal; + font-weight: 400; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; @@ -274,4 +274,4 @@ ight:bold;color:#006699" target=3D"_blank">user preferences.


---001a11c34c389e728f0502aa26a0-- \ No newline at end of file +--001a11c34c389e728f0502aa26a0-- diff --git a/vendor/assets/stylesheets/katex.scss b/vendor/assets/stylesheets/katex.scss index 9dd8a30bf51..b45836716f2 100644 --- a/vendor/assets/stylesheets/katex.scss +++ b/vendor/assets/stylesheets/katex.scss @@ -45,112 +45,112 @@ SOFTWARE. font-family: 'KaTeX_AMS'; src: url(font-path('KaTeX_AMS-Regular.eot')); src: url(font-path('KaTeX_AMS-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_AMS-Regular.woff2')) format('woff2'), url(font-path('KaTeX_AMS-Regular.woff')) format('woff'), url(font-path('KaTeX_AMS-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Caligraphic'; src: url(font-path('KaTeX_Caligraphic-Bold.eot')); src: url(font-path('KaTeX_Caligraphic-Bold.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Caligraphic-Bold.woff2')) format('woff2'), url(font-path('KaTeX_Caligraphic-Bold.woff')) format('woff'), url(font-path('KaTeX_Caligraphic-Bold.ttf')) format('truetype'); - font-weight: bold; + font-weight: 600; font-style: normal; } @font-face { font-family: 'KaTeX_Caligraphic'; src: url(font-path('KaTeX_Caligraphic-Regular.eot')); src: url(font-path('KaTeX_Caligraphic-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Caligraphic-Regular.woff2')) format('woff2'), url(font-path('KaTeX_Caligraphic-Regular.woff')) format('woff'), url(font-path('KaTeX_Caligraphic-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Fraktur'; src: url(font-path('KaTeX_Fraktur-Bold.eot')); src: url(font-path('KaTeX_Fraktur-Bold.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Fraktur-Bold.woff2')) format('woff2'), url(font-path('KaTeX_Fraktur-Bold.woff')) format('woff'), url(font-path('KaTeX_Fraktur-Bold.ttf')) format('truetype'); - font-weight: bold; + font-weight: 600; font-style: normal; } @font-face { font-family: 'KaTeX_Fraktur'; src: url(font-path('KaTeX_Fraktur-Regular.eot')); src: url(font-path('KaTeX_Fraktur-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Fraktur-Regular.woff2')) format('woff2'), url(font-path('KaTeX_Fraktur-Regular.woff')) format('woff'), url(font-path('KaTeX_Fraktur-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Main'; src: url(font-path('KaTeX_Main-Bold.eot')); src: url(font-path('KaTeX_Main-Bold.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Main-Bold.woff2')) format('woff2'), url(font-path('KaTeX_Main-Bold.woff')) format('woff'), url(font-path('KaTeX_Main-Bold.ttf')) format('truetype'); - font-weight: bold; + font-weight: 600; font-style: normal; } @font-face { font-family: 'KaTeX_Main'; src: url(font-path('KaTeX_Main-Italic.eot')); src: url(font-path('KaTeX_Main-Italic.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Main-Italic.woff2')) format('woff2'), url(font-path('KaTeX_Main-Italic.woff')) format('woff'), url(font-path('KaTeX_Main-Italic.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: italic; } @font-face { font-family: 'KaTeX_Main'; src: url(font-path('KaTeX_Main-Regular.eot')); src: url(font-path('KaTeX_Main-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Main-Regular.woff2')) format('woff2'), url(font-path('KaTeX_Main-Regular.woff')) format('woff'), url(font-path('KaTeX_Main-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Math'; src: url(font-path('KaTeX_Math-Italic.eot')); src: url(font-path('KaTeX_Math-Italic.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Math-Italic.woff2')) format('woff2'), url(font-path('KaTeX_Math-Italic.woff')) format('woff'), url(font-path('KaTeX_Math-Italic.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: italic; } @font-face { font-family: 'KaTeX_SansSerif'; src: url(font-path('KaTeX_SansSerif-Regular.eot')); src: url(font-path('KaTeX_SansSerif-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_SansSerif-Regular.woff2')) format('woff2'), url(font-path('KaTeX_SansSerif-Regular.woff')) format('woff'), url(font-path('KaTeX_SansSerif-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Script'; src: url(font-path('KaTeX_Script-Regular.eot')); src: url(font-path('KaTeX_Script-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Script-Regular.woff2')) format('woff2'), url(font-path('KaTeX_Script-Regular.woff')) format('woff'), url(font-path('KaTeX_Script-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Size1'; src: url(font-path('KaTeX_Size1-Regular.eot')); src: url(font-path('KaTeX_Size1-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Size1-Regular.woff2')) format('woff2'), url(font-path('KaTeX_Size1-Regular.woff')) format('woff'), url(font-path('KaTeX_Size1-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Size2'; src: url(font-path('KaTeX_Size2-Regular.eot')); src: url(font-path('KaTeX_Size2-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Size2-Regular.woff2')) format('woff2'), url(font-path('KaTeX_Size2-Regular.woff')) format('woff'), url(font-path('KaTeX_Size2-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Size3'; src: url(font-path('KaTeX_Size3-Regular.eot')); src: url(font-path('KaTeX_Size3-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Size3-Regular.woff2')) format('woff2'), url(font-path('KaTeX_Size3-Regular.woff')) format('woff'), url(font-path('KaTeX_Size3-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Size4'; src: url(font-path('KaTeX_Size4-Regular.eot')); src: url(font-path('KaTeX_Size4-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Size4-Regular.woff2')) format('woff2'), url(font-path('KaTeX_Size4-Regular.woff')) format('woff'), url(font-path('KaTeX_Size4-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } @font-face { font-family: 'KaTeX_Typewriter'; src: url(font-path('KaTeX_Typewriter-Regular.eot')); src: url(font-path('KaTeX_Typewriter-Regular.eot#iefix')) format('embedded-opentype'), url(font-path('KaTeX_Typewriter-Regular.woff2')) format('woff2'), url(font-path('KaTeX_Typewriter-Regular.woff')) format('woff'), url(font-path('KaTeX_Typewriter-Regular.ttf')) format('truetype'); - font-weight: normal; + font-weight: 400; font-style: normal; } .katex-display { @@ -192,7 +192,7 @@ SOFTWARE. } .katex .mathbf { font-family: KaTeX_Main; - font-weight: bold; + font-weight: 600; } .katex .amsrm { font-family: KaTeX_AMS; diff --git a/vendor/assets/stylesheets/xterm/xterm.css b/vendor/assets/stylesheets/xterm/xterm.css index b30d7b493f1..fabc51b0e3d 100644 --- a/vendor/assets/stylesheets/xterm/xterm.css +++ b/vendor/assets/stylesheets/xterm/xterm.css @@ -142,7 +142,7 @@ * Determine default colors for xterm.js */ .terminal .xterm-bold { - font-weight: bold; + font-weight: 600; } .terminal .xterm-underline { From a919188ccf90a923c12992c4070c6f680627fb48 Mon Sep 17 00:00:00 2001 From: Fabio Busatto Date: Thu, 24 Aug 2017 14:40:38 +0000 Subject: [PATCH 095/196] Update README.md --- doc/ci/variables/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md index e55a92dbb71..234dc530db0 100644 --- a/doc/ci/variables/README.md +++ b/doc/ci/variables/README.md @@ -86,6 +86,11 @@ To follow conventions of naming across GitLab, and to futher move away from the `build` term and toward `job` CI variables have been renamed for the 9.0 release. +>**Note:** +Starting with GitLab 9.0, we have deprecated the `$CI_BUILD_*` variables. **You are +strongly advised to use the new variables as we will remove the old ones in +future GitLab releases.** + | 8.x name | 9.0+ name | | --------------------- |------------------------ | | `CI_BUILD_ID` | `CI_JOB_ID` | From f8865e9c1303be7302306bea9dd1057bf3b3f608 Mon Sep 17 00:00:00 2001 From: Bob Van Landuyt Date: Wed, 26 Jul 2017 11:57:05 +0200 Subject: [PATCH 096/196] Define ldap methods at runtime This avoids loading the `OmniAuthCallbacksController` at boot time so it doesn't mess up the `before_action`-chain --- app/controllers/omniauth_callbacks_controller.rb | 8 ++++++++ app/controllers/sessions_controller.rb | 8 -------- config/initializers/omniauth.rb | 6 ------ 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index 7444826a5d1..9612b8d8514 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -10,6 +10,14 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController end end + if Gitlab::LDAP::Config.enabled? + Gitlab::LDAP::Config.available_servers.each do |server| + define_method server['provider_name'] do + ldap + end + end + end + # Extend the standard message generation to accept our custom exception def failure_message exception = env["omniauth.error"] diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 9e743685d60..be6491d042c 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -5,14 +5,6 @@ class SessionsController < Devise::SessionsController skip_before_action :check_two_factor_requirement, only: [:destroy] - # Explicitly call protect from forgery before anything else. Otherwise the - # CSFR-token might be cleared before authentication is done. This was the case - # when LDAP was enabled and the `OmniauthCallbacksController` is loaded - # - # *Note:* `prepend: true` is the default for rails4, but this will be changed - # to `prepend: false` in rails5. - protect_from_forgery prepend: true, with: :exception - prepend_before_action :check_initial_setup, only: [:new] prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create] diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb index 56c279ffcf4..fddb018e948 100644 --- a/config/initializers/omniauth.rb +++ b/config/initializers/omniauth.rb @@ -6,12 +6,6 @@ if Gitlab::LDAP::Config.enabled? const_set(server['provider_class'], Class.new(LDAP)) end end - - OmniauthCallbacksController.class_eval do - Gitlab::LDAP::Config.available_servers.each do |server| - alias_method server['provider_name'], :ldap - end - end end OmniAuth.config.full_host = Settings.gitlab['base_url'] From 8ecd9b574f82ffb04aa789d2ab1979a0af5dd6f4 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Thu, 24 Aug 2017 18:07:45 +0200 Subject: [PATCH 097/196] Remove leftover API helper for removed CI API --- spec/support/api_helpers.rb | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/spec/support/api_helpers.rb b/spec/support/api_helpers.rb index ac0aaa524b7..01aca74274c 100644 --- a/spec/support/api_helpers.rb +++ b/spec/support/api_helpers.rb @@ -45,18 +45,4 @@ module ApiHelpers oauth_access_token: oauth_access_token ) end - - def ci_api(path, user = nil) - "/ci/api/v1/#{path}" + - - # Normalize query string - (path.index('?') ? '' : '?') + - - # Append private_token if given a User object - if user.respond_to?(:private_token) - "&private_token=#{user.private_token}" - else - '' - end - end end From 5af797d4a935faf0c772b9ce5c8c24b736beedd7 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Thu, 24 Aug 2017 18:32:49 +0200 Subject: [PATCH 098/196] Re-allow appearances.description_html to be NULL This column isn't always set (e.g. when upgrading from older instances) and technically it could be NULL (e.g. when flushing the cache). Fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/36919 --- ...t-appearances-description-html-not-null.yml | 5 +++++ ...0170809142252_cleanup_appearances_schema.rb | 2 +- ..._allow_appearances_description_html_null.rb | 18 ++++++++++++++++++ db/schema.rb | 4 ++-- 4 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 changelogs/unreleased/revert-appearances-description-html-not-null.yml create mode 100644 db/migrate/20170824162758_allow_appearances_description_html_null.rb diff --git a/changelogs/unreleased/revert-appearances-description-html-not-null.yml b/changelogs/unreleased/revert-appearances-description-html-not-null.yml new file mode 100644 index 00000000000..4e3c39cb5fd --- /dev/null +++ b/changelogs/unreleased/revert-appearances-description-html-not-null.yml @@ -0,0 +1,5 @@ +--- +title: Re-allow appearances.description_html to be NULL +merge_request: +author: +type: fixed diff --git a/db/migrate/20170809142252_cleanup_appearances_schema.rb b/db/migrate/20170809142252_cleanup_appearances_schema.rb index 90d12925ba2..acf45060114 100644 --- a/db/migrate/20170809142252_cleanup_appearances_schema.rb +++ b/db/migrate/20170809142252_cleanup_appearances_schema.rb @@ -7,7 +7,7 @@ class CleanupAppearancesSchema < ActiveRecord::Migration # Set this constant to true if this migration requires downtime. DOWNTIME = false - NOT_NULL_COLUMNS = %i[title description description_html created_at updated_at] + NOT_NULL_COLUMNS = %i[title description created_at updated_at] TIME_COLUMNS = %i[created_at updated_at] diff --git a/db/migrate/20170824162758_allow_appearances_description_html_null.rb b/db/migrate/20170824162758_allow_appearances_description_html_null.rb new file mode 100644 index 00000000000..d7f481ee894 --- /dev/null +++ b/db/migrate/20170824162758_allow_appearances_description_html_null.rb @@ -0,0 +1,18 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AllowAppearancesDescriptionHtmlNull < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # Set this constant to true if this migration requires downtime. + DOWNTIME = false + + def up + change_column_null :appearances, :description_html, true + end + + def down + # This column should not have a `NOT NULL` class, so we don't want to revert + # back to re-adding it. + end +end diff --git a/db/schema.rb b/db/schema.rb index cd488630237..0f4b0c0c3b3 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: 20170820100558) do +ActiveRecord::Schema.define(version: 20170824162758) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -34,7 +34,7 @@ ActiveRecord::Schema.define(version: 20170820100558) do t.string "logo" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.text "description_html", null: false + t.text "description_html" t.integer "cached_markdown_version" end From 5904fea900c3ea6255b2c7aed7beb00ba91a6e28 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 24 Aug 2017 13:05:16 -0400 Subject: [PATCH 099/196] Add `:nested_groups` metadata to `Groups::NestedCreateService` specs --- spec/services/groups/nested_create_service_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/services/groups/nested_create_service_spec.rb b/spec/services/groups/nested_create_service_spec.rb index c1526456bac..6d11edb5842 100644 --- a/spec/services/groups/nested_create_service_spec.rb +++ b/spec/services/groups/nested_create_service_spec.rb @@ -14,14 +14,14 @@ describe Groups::NestedCreateService do expect(service.execute).to eq(child) end - it 'reuses a parent if it already existed' do + it 'reuses a parent if it already existed', :nested_groups do parent = create(:group, path: 'a-group') parent.add_owner(user) expect(service.execute.parent).to eq(parent) end - it 'creates group and subgroup in the database' do + it 'creates group and subgroup in the database', :nested_groups do service.execute parent = Group.find_by_full_path('a-group') From 9f7f78570f4dba345a71b6d14a08d0430fad8304 Mon Sep 17 00:00:00 2001 From: Michael Kozono Date: Thu, 24 Aug 2017 11:45:37 -0700 Subject: [PATCH 100/196] Reenable MySQL tests on all branches To protect master from surprise failures, as long as we continue to support MySQL. --- .gitlab-ci.yml | 15 --------------- doc/development/testing.md | 5 +---- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6f356a07576..ab9627d4ab7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -68,19 +68,6 @@ stages: - mysql:latest - redis:alpine -.only-if-want-mysql: &only-if-want-mysql - only: - - /mysql/ - - /-stable/ - - master@gitlab-org/gitlab-ce - - master@gitlab-org/gitlab-ee - - master@gitlab/gitlabhq - - master@gitlab/gitlab-ee - - tags@gitlab-org/gitlab-ce - - tags@gitlab-org/gitlab-ee - - tags@gitlab/gitlabhq - - tags@gitlab/gitlab-ee - # Skip all jobs except the ones that begin with 'docs/'. # Used for commits including ONLY documentation changes. # https://docs.gitlab.com/ce/development/writing_documentation.html#testing @@ -124,7 +111,6 @@ stages: .rspec-metadata-mysql: &rspec-metadata-mysql <<: *rspec-metadata <<: *use-mysql - <<: *only-if-want-mysql <<: *except-docs .spinach-metadata: &spinach-metadata @@ -156,7 +142,6 @@ stages: .spinach-metadata-mysql: &spinach-metadata-mysql <<: *spinach-metadata <<: *use-mysql - <<: *only-if-want-mysql <<: *except-docs .only-canonical-masters: &only-canonical-masters diff --git a/doc/development/testing.md b/doc/development/testing.md index efd56484b12..83269303005 100644 --- a/doc/development/testing.md +++ b/doc/development/testing.md @@ -529,10 +529,7 @@ slowest test files and try to improve them. ## CI setup -- On CE, the test suite only runs against PostgreSQL by default. We additionally - run the suite against MySQL for tags, `master`, and any branch that includes - `mysql` in the name. -- On EE, the test suite always runs both PostgreSQL and MySQL. +- On CE and EE, the test suite runs both PostgreSQL and MySQL. - Rails logging to `log/test.log` is disabled by default in CI [for performance reasons][logging]. To override this setting, provide the `RAILS_ENABLE_TEST_LOG` environment variable. From 38bb92197dcb67df917bb9793be5a1a48611c047 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Thu, 24 Aug 2017 12:24:58 -0700 Subject: [PATCH 101/196] Enable 5 lines of Sidekiq backtrace lines to aid in debugging Customers often have Sidekiq jobs that failed without much context. Without Sentry, there's no way to tell where these exceptions were hit. Adding in additional lines adds a bit more Redis storage overhead. This commit adds in backtrace logging for workers that delete groups/projects and import/export projects. Closes #27626 --- app/workers/concerns/exception_backtrace.rb | 8 ++++++++ app/workers/group_destroy_worker.rb | 1 + app/workers/namespaceless_project_destroy_worker.rb | 1 + app/workers/project_destroy_worker.rb | 1 + app/workers/project_export_worker.rb | 1 + app/workers/repository_import_worker.rb | 1 + 6 files changed, 13 insertions(+) create mode 100644 app/workers/concerns/exception_backtrace.rb diff --git a/app/workers/concerns/exception_backtrace.rb b/app/workers/concerns/exception_backtrace.rb new file mode 100644 index 00000000000..e3ecdfe2502 --- /dev/null +++ b/app/workers/concerns/exception_backtrace.rb @@ -0,0 +1,8 @@ +# Concern for enabling a few lines of exception backtraces in Sidekiq +module BuildQueue + extend ActiveSupport::Concern + + included do + sidekiq_options backtrace: 5 + end +end diff --git a/app/workers/group_destroy_worker.rb b/app/workers/group_destroy_worker.rb index 07e82767b06..bd8e212e928 100644 --- a/app/workers/group_destroy_worker.rb +++ b/app/workers/group_destroy_worker.rb @@ -1,6 +1,7 @@ class GroupDestroyWorker include Sidekiq::Worker include DedicatedSidekiqQueue + include ExceptionBacktrace def perform(group_id, user_id) begin diff --git a/app/workers/namespaceless_project_destroy_worker.rb b/app/workers/namespaceless_project_destroy_worker.rb index 1cfb0be759e..f1cd1769421 100644 --- a/app/workers/namespaceless_project_destroy_worker.rb +++ b/app/workers/namespaceless_project_destroy_worker.rb @@ -7,6 +7,7 @@ class NamespacelessProjectDestroyWorker include Sidekiq::Worker include DedicatedSidekiqQueue + include ExceptionBacktrace def self.bulk_perform_async(args_list) Sidekiq::Client.push_bulk('class' => self, 'queue' => sidekiq_options['queue'], 'args' => args_list) diff --git a/app/workers/project_destroy_worker.rb b/app/workers/project_destroy_worker.rb index a9188b78460..3be7e686609 100644 --- a/app/workers/project_destroy_worker.rb +++ b/app/workers/project_destroy_worker.rb @@ -1,6 +1,7 @@ class ProjectDestroyWorker include Sidekiq::Worker include DedicatedSidekiqQueue + include ExceptionBacktrace def perform(project_id, user_id, params) project = Project.find(project_id) diff --git a/app/workers/project_export_worker.rb b/app/workers/project_export_worker.rb index 6009aa1b191..f13ac9e5db2 100644 --- a/app/workers/project_export_worker.rb +++ b/app/workers/project_export_worker.rb @@ -1,6 +1,7 @@ class ProjectExportWorker include Sidekiq::Worker include DedicatedSidekiqQueue + include ExceptionBacktrace sidekiq_options retry: 3 diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb index 2c2d1e8b91f..00a021abbdc 100644 --- a/app/workers/repository_import_worker.rb +++ b/app/workers/repository_import_worker.rb @@ -3,6 +3,7 @@ class RepositoryImportWorker include Sidekiq::Worker include DedicatedSidekiqQueue + include ExceptionBacktrace sidekiq_options status_expiration: StuckImportJobsWorker::IMPORT_JOBS_EXPIRATION From 5167a76f065cda793df6d188fe472da8db0ac4ae Mon Sep 17 00:00:00 2001 From: Jacopo Date: Sun, 20 Aug 2017 11:12:23 +0200 Subject: [PATCH 102/196] Authorizations regarding OAuth - style confirmation Changed the styling of OAuth authorization page in order to follow the styling structure described in #28849. --- app/assets/stylesheets/framework/modal.scss | 8 ++ .../doorkeeper/authorizations/new.html.haml | 78 ++++++++++--------- .../35721-auth-style-confirmation.yml | 5 ++ 3 files changed, 54 insertions(+), 37 deletions(-) create mode 100644 changelogs/unreleased/35721-auth-style-confirmation.yml diff --git a/app/assets/stylesheets/framework/modal.scss b/app/assets/stylesheets/framework/modal.scss index a28f54936be..2a16b6317fa 100644 --- a/app/assets/stylesheets/framework/modal.scss +++ b/app/assets/stylesheets/framework/modal.scss @@ -16,6 +16,14 @@ body.modal-open { overflow: hidden; } +.modal-no-backdrop { + @extend .modal-dialog; + + .modal-content { + box-shadow: none; + } +} + @media (min-width: $screen-md-min) { .modal-dialog { width: 860px; diff --git a/app/views/doorkeeper/authorizations/new.html.haml b/app/views/doorkeeper/authorizations/new.html.haml index 82aa51f9778..8ba88906714 100644 --- a/app/views/doorkeeper/authorizations/new.html.haml +++ b/app/views/doorkeeper/authorizations/new.html.haml @@ -1,39 +1,43 @@ -%h3.page-title Authorization required %main{ :role => "main" } - %p.h4 - Authorize - %strong.text-info= @pre_auth.client.name - to use your account? + .modal-no-backdrop + .modal-content + .modal-header + %h3.page-title + Authorize + = link_to @pre_auth.client.name, @pre_auth.redirect_uri, target: '_blank', rel: 'noopener noreferrer' + to use your account? - - if current_user.admin? - .text-warning.prepend-top-20 - %p - = icon("exclamation-triangle fw") - You are an admin, which means granting access to - %strong= @pre_auth.client.name - will allow them to interact with GitLab as an admin as well. Proceed with caution. - - - if @pre_auth.scopes - #oauth-permissions - %p This application will be able to: - %ul.text-info - - @pre_auth.scopes.each do |scope| - %li= t scope, scope: [:doorkeeper, :scopes] - %hr/ - .actions - = form_tag oauth_authorization_path, method: :post do - = hidden_field_tag :client_id, @pre_auth.client.uid - = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri - = hidden_field_tag :state, @pre_auth.state - = hidden_field_tag :response_type, @pre_auth.response_type - = hidden_field_tag :scope, @pre_auth.scope - = hidden_field_tag :nonce, @pre_auth.nonce - = submit_tag "Authorize", class: "btn btn-success wide pull-left" - = form_tag oauth_authorization_path, method: :delete do - = hidden_field_tag :client_id, @pre_auth.client.uid - = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri - = hidden_field_tag :state, @pre_auth.state - = hidden_field_tag :response_type, @pre_auth.response_type - = hidden_field_tag :scope, @pre_auth.scope - = hidden_field_tag :nonce, @pre_auth.nonce - = submit_tag "Deny", class: "btn btn-danger prepend-left-10" + .modal-body + - if current_user.admin? + .text-warning + %p + = icon("exclamation-triangle fw") + You are an admin, which means granting access to + %strong= @pre_auth.client.name + will allow them to interact with GitLab as an admin as well. Proceed with caution. + %p + You are about to authorize + = link_to @pre_auth.client.name, @pre_auth.redirect_uri, target: '_blank', rel: 'noopener noreferrer' + to use your account. + - if @pre_auth.scopes + This application will be able to: + %ul + - @pre_auth.scopes.each do |scope| + %li= t scope, scope: [:doorkeeper, :scopes] + .form-actions.text-right + = form_tag oauth_authorization_path, method: :delete, class: 'inline' do + = hidden_field_tag :client_id, @pre_auth.client.uid + = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri + = hidden_field_tag :state, @pre_auth.state + = hidden_field_tag :response_type, @pre_auth.response_type + = hidden_field_tag :scope, @pre_auth.scope + = hidden_field_tag :nonce, @pre_auth.nonce + = submit_tag "Deny", class: "btn btn-danger" + = form_tag oauth_authorization_path, method: :post, class: 'inline' do + = hidden_field_tag :client_id, @pre_auth.client.uid + = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri + = hidden_field_tag :state, @pre_auth.state + = hidden_field_tag :response_type, @pre_auth.response_type + = hidden_field_tag :scope, @pre_auth.scope + = hidden_field_tag :nonce, @pre_auth.nonce + = submit_tag "Authorize", class: "btn btn-success prepend-left-10" diff --git a/changelogs/unreleased/35721-auth-style-confirmation.yml b/changelogs/unreleased/35721-auth-style-confirmation.yml new file mode 100644 index 00000000000..9963f76e845 --- /dev/null +++ b/changelogs/unreleased/35721-auth-style-confirmation.yml @@ -0,0 +1,5 @@ +--- +title: restyling of OAuth authorization confirmation +merge_request: +author: Jacopo Beschi @jacopo-beschi +type: changed From 986b80d0d13f3e95ed02fd721631bebcd94648c1 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Thu, 24 Aug 2017 21:31:39 +0000 Subject: [PATCH 103/196] New doc: how to install GitLab on Azure --- doc/articles/index.md | 3 +- doc/install/README.md | 10 +- .../img/azure-add-inbound-sec-rule-http.png | Bin 0 -> 16927 bytes .../img/azure-add-inbound-sec-rule-ssh.png | Bin 0 -> 16817 bytes ...create-virtual-machine-basics-password.png | Bin 0 -> 24862 bytes .../azure-create-virtual-machine-basics.png | Bin 0 -> 22925 bytes ...zure-create-virtual-machine-deployment.png | Bin 0 -> 23707 bytes .../azure-create-virtual-machine-purchase.png | Bin 0 -> 43698 bytes .../azure-create-virtual-machine-settings.png | Bin 0 -> 25686 bytes .../img/azure-create-virtual-machine-size.png | Bin 0 -> 33322 bytes .../img/azure-dashboard-highlight-nsg.png | Bin 0 -> 34248 bytes .../img/azure-dashboard-running-resources.png | Bin 0 -> 34306 bytes doc/install/azure/img/azure-dashboard.png | Bin 0 -> 36396 bytes .../img/azure-inbound-sec-rules-list.png | Bin 0 -> 24592 bytes doc/install/azure/img/azure-new-gitlab-ce.png | Bin 0 -> 22701 bytes .../azure/img/azure-new-search-gitlab.png | Bin 0 -> 19034 bytes ...re-nsg-inbound-sec-rules-add-highlight.png | Bin 0 -> 22583 bytes .../azure-nsg-inbound-sec-rules-highlight.png | Bin 0 -> 31485 bytes .../azure/img/azure-vm-domain-name.png | Bin 0 -> 23802 bytes .../img/azure-vm-management-public-ip.png | Bin 0 -> 34991 bytes ...management-settings-network-interfaces.png | Bin 0 -> 35849 bytes doc/install/azure/img/azure-vm-management.png | Bin 0 -> 35363 bytes .../azure/img/gitlab-admin-area-9.4.0.png | Bin 0 -> 35249 bytes doc/install/azure/img/gitlab-admin-area.png | Bin 0 -> 29333 bytes .../azure/img/gitlab-change-password.png | Bin 0 -> 24404 bytes doc/install/azure/img/gitlab-home.png | Bin 0 -> 26302 bytes doc/install/azure/img/gitlab-login.png | Bin 0 -> 24656 bytes doc/install/azure/img/gitlab-new-project.png | Bin 0 -> 34164 bytes .../azure/img/gitlab-project-home-empty.png | Bin 0 -> 28375 bytes .../img/gitlab-project-home-instructions.png | Bin 0 -> 31738 bytes .../img/gitlab-ssh-update-in-progress.png | Bin 0 -> 32799 bytes doc/install/azure/index.md | 439 ++++++++++++++++++ 32 files changed, 450 insertions(+), 2 deletions(-) create mode 100644 doc/install/azure/img/azure-add-inbound-sec-rule-http.png create mode 100644 doc/install/azure/img/azure-add-inbound-sec-rule-ssh.png create mode 100644 doc/install/azure/img/azure-create-virtual-machine-basics-password.png create mode 100644 doc/install/azure/img/azure-create-virtual-machine-basics.png create mode 100644 doc/install/azure/img/azure-create-virtual-machine-deployment.png create mode 100644 doc/install/azure/img/azure-create-virtual-machine-purchase.png create mode 100644 doc/install/azure/img/azure-create-virtual-machine-settings.png create mode 100644 doc/install/azure/img/azure-create-virtual-machine-size.png create mode 100644 doc/install/azure/img/azure-dashboard-highlight-nsg.png create mode 100644 doc/install/azure/img/azure-dashboard-running-resources.png create mode 100644 doc/install/azure/img/azure-dashboard.png create mode 100644 doc/install/azure/img/azure-inbound-sec-rules-list.png create mode 100644 doc/install/azure/img/azure-new-gitlab-ce.png create mode 100644 doc/install/azure/img/azure-new-search-gitlab.png create mode 100644 doc/install/azure/img/azure-nsg-inbound-sec-rules-add-highlight.png create mode 100644 doc/install/azure/img/azure-nsg-inbound-sec-rules-highlight.png create mode 100644 doc/install/azure/img/azure-vm-domain-name.png create mode 100644 doc/install/azure/img/azure-vm-management-public-ip.png create mode 100644 doc/install/azure/img/azure-vm-management-settings-network-interfaces.png create mode 100644 doc/install/azure/img/azure-vm-management.png create mode 100644 doc/install/azure/img/gitlab-admin-area-9.4.0.png create mode 100644 doc/install/azure/img/gitlab-admin-area.png create mode 100644 doc/install/azure/img/gitlab-change-password.png create mode 100644 doc/install/azure/img/gitlab-home.png create mode 100644 doc/install/azure/img/gitlab-login.png create mode 100644 doc/install/azure/img/gitlab-new-project.png create mode 100644 doc/install/azure/img/gitlab-project-home-empty.png create mode 100644 doc/install/azure/img/gitlab-project-home-instructions.png create mode 100644 doc/install/azure/img/gitlab-ssh-update-in-progress.png create mode 100644 doc/install/azure/index.md diff --git a/doc/articles/index.md b/doc/articles/index.md index 1aa65504852..4b0c85b9272 100644 --- a/doc/articles/index.md +++ b/doc/articles/index.md @@ -76,7 +76,8 @@ Learn how to deploy a static website with [GitLab Pages](../user/project/pages/i ## Install and maintain GitLab -Install, upgrade, integrate, migrate to GitLab: +[Admin](../README.md#administrator-documentation), [install](../install/README.md), +upgrade, integrate, migrate to GitLab: | Article title | Category | Publishing date | | :------------ | :------: | --------------: | diff --git a/doc/install/README.md b/doc/install/README.md index bc831a37735..1d510cb29c3 100644 --- a/doc/install/README.md +++ b/doc/install/README.md @@ -18,9 +18,17 @@ the hardware requirements. Useful for unsupported systems like *BSD. For an overview of the directory structure, read the [structure documentation](structure.md). - [Docker](https://docs.gitlab.com/omnibus/docker/) - Install GitLab using Docker. + +## Install GitLab on cloud providers + - [Installing in Kubernetes](kubernetes/index.md) - Install GitLab into a Kubernetes Cluster using our official Helm Chart Repository. -- Testing only! [DigitalOcean and Docker Machine](digitaloceandocker.md) - +- [Install GitLab on OpenShift](../articles/openshift_and_gitlab/index.md) +- [Install GitLab on DC/OS](https://mesosphere.com/blog/gitlab-dcos/) via [GitLab-Mesosphere integration](https://about.gitlab.com/2016/09/16/announcing-gitlab-and-mesosphere/) +- [Install GitLab on Azure](azure/index.md) +- [Install GitLab on Google Cloud Platform](google_cloud_platform/index.md) +- [Install on AWS](https://about.gitlab.com/aws/) +- _Testing only!_ [DigitalOcean and Docker Machine](digitaloceandocker.md) - Quickly test any version of GitLab on DigitalOcean using Docker Machine. ## Database diff --git a/doc/install/azure/img/azure-add-inbound-sec-rule-http.png b/doc/install/azure/img/azure-add-inbound-sec-rule-http.png new file mode 100644 index 0000000000000000000000000000000000000000..abf500cb63aae0604332ec605c3c1a221caff088 GIT binary patch literal 16927 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 Zy)>RN-W{vX72+`j+- literal 0 HcmV?d00001 diff --git a/doc/install/azure/img/azure-add-inbound-sec-rule-ssh.png b/doc/install/azure/img/azure-add-inbound-sec-rule-ssh.png new file mode 100644 index 0000000000000000000000000000000000000000..f7a8a04dfa70ca9dd5f61d74605e80b121ce2ffd GIT binary patch literal 16817 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 literal 0 HcmV?d00001 diff --git a/doc/install/azure/img/azure-create-virtual-machine-basics.png b/doc/install/azure/img/azure-create-virtual-machine-basics.png new file mode 100644 index 0000000000000000000000000000000000000000..229c073fe17e0e48ac3515eb2fb6d4d02c49c4f5 GIT binary patch literal 22925 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 z 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

2A*BnZG&x={siftUNUV!` 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%0AF#BW1GWc!Kw`rn?4+*0Z#8PXT_Yox+*O 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 z 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 literal 0 HcmV?d00001 diff --git a/doc/install/azure/img/azure-create-virtual-machine-settings.png b/doc/install/azure/img/azure-create-virtual-machine-settings.png new file mode 100644 index 0000000000000000000000000000000000000000..200979216606fc7b73cc08b050d94bcc4df19230 GIT binary patch literal 25686 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 literal 0 HcmV?d00001 diff --git a/doc/install/azure/img/azure-create-virtual-machine-size.png b/doc/install/azure/img/azure-create-virtual-machine-size.png new file mode 100644 index 0000000000000000000000000000000000000000..a408394151fc17b944991ceae4c1b4d392651454 GIT binary patch literal 33322 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ⅇ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 literal 0 HcmV?d00001 diff --git a/doc/install/azure/img/azure-dashboard.png b/doc/install/azure/img/azure-dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..375ec8622b8b35064e23166981018703a8dca8e6 GIT binary patch literal 36396 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 literal 0 HcmV?d00001 diff --git a/doc/install/azure/img/azure-inbound-sec-rules-list.png b/doc/install/azure/img/azure-inbound-sec-rules-list.png new file mode 100644 index 0000000000000000000000000000000000000000..1667671b21de2259bce248978ebee7a751feae4b GIT binary patch literal 24592 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 D5iD7z literal 0 HcmV?d00001 diff --git a/doc/install/azure/img/azure-new-gitlab-ce.png b/doc/install/azure/img/azure-new-gitlab-ce.png new file mode 100644 index 0000000000000000000000000000000000000000..88949f69a94b0feb06a1b8ad8610da8461117879 GIT binary patch literal 22701 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 Yie@?9Jh%yddX>Xa&seua$Km(?168SyDgXcg literal 0 HcmV?d00001 diff --git a/doc/install/azure/img/azure-new-search-gitlab.png b/doc/install/azure/img/azure-new-search-gitlab.png new file mode 100644 index 0000000000000000000000000000000000000000..f96ed577d628a159ca3bf7b5db59d7e2311ee9c6 GIT binary patch literal 19034 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 literal 0 HcmV?d00001 diff --git a/doc/install/azure/img/azure-nsg-inbound-sec-rules-add-highlight.png b/doc/install/azure/img/azure-nsg-inbound-sec-rules-add-highlight.png new file mode 100644 index 0000000000000000000000000000000000000000..c9a08b87ce631ad8628253590d2671bdbf1bb39c GIT binary patch literal 22583 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 literal 0 HcmV?d00001 diff --git a/doc/install/azure/img/azure-nsg-inbound-sec-rules-highlight.png b/doc/install/azure/img/azure-nsg-inbound-sec-rules-highlight.png new file mode 100644 index 0000000000000000000000000000000000000000..6423625ca8b6e5689757809fae420b1afc8d4166 GIT binary patch literal 31485 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 Gzxf|M8B;<4 literal 0 HcmV?d00001 diff --git a/doc/install/azure/img/azure-vm-domain-name.png b/doc/install/azure/img/azure-vm-domain-name.png new file mode 100644 index 0000000000000000000000000000000000000000..01c03004b245428ea968a82e77ce0e9ba0c83ca5 GIT binary patch literal 23802 zcmd?Q^;V*846=qBPVLi5}BD1^@s=O7G;g0Dwm*0046k z4-0)~LaXTj0KfuhsOY?B4S?j0i=hk}Bl{wGHp&oE|YmbdEKAP{I^VBqBBl^&pTA&dZ)j*V zG&C%!Y!EaL;nH#DH}Fx*TGOq&7je&Ua&pqq(TR_bx3si0Ha31Ps>mUu&B7<9Reqsf zc)+e`rkFe}4*D(R5Vy6x_4@T|R!&~Yz;?xN18M2$N=i!d^71MwDnUU(FJH2Q!C*T( zyKmpV>FeuXUR^ggH?y&^9UL5pv9K62F}FUW38bR`PDR(t`gBzfuYi*7*aLe|h^5`i zarCo?7Kdn8e%bQa*g&A(qKojrJB1p0!E8R0Af=R@RFkcEgS7yaIFo`5*NVVafN0u) zck_~7*`!s??7#Et&UM(#{#pC%-tf-J@7crD?zNl-a6sQ?Ck&O^+Lt=9m)|$xUpZsk zxNK0rWYYqPt!NC&EUI1o=k-0kb^pSpW6k8VXZ6gcyc!F?0BiHCfVLsKRqhN|)WqKL zWx?Q1+2AIo>%h~XVf)gRg!(1^ciMraZ4#e6^m4m|H4Rsw2-Sr0x*uKJJ4d}`ImGd7H23>O|u)G(({3N06n0;Mbq&}FB*?#)bl|m!dioLlT zKXC!GXdhHV;8D@He>yX_|GVQ)ba|^wSw(Sx&)3^;*vB1Nw`m-O^7wRgbYx^?=);4y z0!m8Cp57k%)(I8>00ZEmrKXKO>i<9e^rfU|l$X2z_=N-jKKxdam(lUY_%|;^i77)0 znDShAZM%Q#8bKIw&8j(gA?C*gxQZvn1VFI>%ea7gxEzJGE?n0-=@uA-m;(Q*m}rv#(hWo|U}>4NAhLNZm?Q}re& z-ZsZbapH=v^4&5rzk+w5{t4>|R?5GuDE;N-<$)Y~mr62cQRXkwG4J@thjl4J7!J8~ z#RdDOAAjBWy-d01Hy(Iz&3-BTiA*a#pvhZ5z=>!{!mkP@bTi+Ul;vIgs5L}V%cZ2M zg{NnA;+8C4p|iXtermH7exDTh{Tc@+B0M5O0Vm)OJg1qPhli&iv1am8{`Dn1?o;c} z%xG1`VhNfK!AL*q8|b4xN&Ioly7yn*ACG&E5%l;ktZ;ut#;*sKxY+*WfBpJ0<}Xs* z$jHc9vF*p-F7F!BriHh%AASU@#S_Q0R-Ng=3=dCuy@uWP&ZDcBU%z=~sQtaHOv##C z_<+k}LL#jlBxzG`e}8|DY!;P+xw!Fpzlm(G9BifrhaY@$ z1|x97oRR3n9__TJr1Qxllx9!xmz?I>*Hp+8EcGszG5jtsauU7~Nwmd%@)ak*rbH&&ba z8guyvXFPpc&qQq0D_(#8q`MmNZRFO*hg`mCLV;?FQIpTx&2;++uMK`Bco^;t zmR8JOx}uJTJldmtVP;`rKF;%oJS=K|bcMbReiqmOBe)4!5pnGC=!fUFpoqOgjokTpOx;%W7khFbU;P;qfC!=;tw(K+xRY zgpFwKi+rSIubI(fK$22QSZ3xUOs#g;Nx{dtAXV>{me0hon(8+J^Pu?-&=(l0;y0>s z&S~EED)we)(nJ9Gdt!bw#XW?N}kASJh`5FI+#HKxFaGZ zm-%_jVQ@;Z7WRRw@sS{V-j2d)#<$oj(}@ts;YK#^^XHF5zB8qL*OaxT` z7$```<_OFysp1VPYI$`e`a9oP#ssJmb$8JV zl8aqMR_($#OYLk6=P+B;SG3*JWDP`gE?#EL6DN1bz9^;)wtr>(hk??}p3};G#}UC~ zsM}QM*Zeg$WopoQ#J*5jG;u|dRc^MGvPlTv;9YE&nSj(a&$N(%m+AV+ADb63@S`C` zz7MlW4|;Sw{bEK+v@f?HzFT0to`%{rQNT(mgaHpjOIB{(=A0+{-hH3@PT#PzO&)`r z%;SX9HU7sJ#hxjT(FbWrVc#3jiD`L@l@h?iJ>Y(CNFCFsMz@OVaY>opIcQy=eYv#( z{3Ai4!h3YO^vK)9nJ#lFC@eN@pxga>yv@^?vow@{M?8g>Q~XE*!WMUG1yu6)5Xgdb z-EpJ!s4e}(MfZb)YYJ!3AFxnK%45E^3F>Dk`|yDDs2DBg`Rtgn z#)VZ8#`iI*78YUg>_xm6Rt#b$zdJi~+*3>gussW_f%ThU;JT|9d&Cd8&)2=9Aw0r- z_%*6`7Ju6R+}oNmR5bn6%L9M=XQbncUGN|of-I#du*H^HLcjs>T8c#hk8pa(JxHV>jAU}ZwCuD8M&`(}bk zh=zeSNb8^80*4F_J6e~EdK#1n&|bjcC}J_Q6Ksk9vu~+0*E45FQ#}is{IheIO7BWE z&Wbe>U0aaWTe}J%IDniRikjvP$JrSk0Xy*aTL zC%NoMlYjl9h%8t2T7QzT5z9jZc)1K_!cq=UF~XT-cYUXj)=}e4$fg2=V5&YZLCr2t z6cz1zgTSJKjX!nfeHl0OV5}FK^X6l;R8~x+hM3phD4{CsVj*~bSMYp$g&|V3$|uT3 z|CE--N5ML0JDtkn>Rl663kk|TcqJ7hi?xDMldDWIr7;{Pu7jL8@R;MH`=T6C-Ky?o zqr}ZWD`!-^M>d&_j5S;lsXUK6`FV`-#{J_O8xJF?=OrF$7U_!YEOk>FJY=iQUMj(Ir(xV(e6PG488EX?4ZXRJ^a{hnR5 zf$mMe?=zjiq?)n|u)=H(L($FJ;BzSPWfK_l4tNvOwBL5bO?l3KWb|xZz$nz}QiXZ? zzqpQ64^92a_9=?DFXvIDNZ%7z*-Y}W99zFq{$m-N<7eVmLw@wF1JU*=E5(6K$fp>N z8IlW)RZCSwkg-*--1%2gfWG%FV~0SHm1aeuCxQmXu~^$Y!Fj&x?@yH9L zXcRTXHYAruSfjB*=vfPV@LEsg zXLAKC147f{Vme00S6{$0!6H5Q^*v0kdOP!Z$^syDw&hZM%5r48y``-E2Wa>vuu?^bI)VITqnk(LJUos4g4sTW6^ z8c#Ap1~$_q`t1d>#(f(xK<4pfuC!(BGo$f~*`efq-*dc0?WVjWJ!Be{Dy)nqLiodP z?4rd*`PPjKBNG!f@iLM~#n5-hWtIHG z^=te-WM?iX=_oDEnob^#y$__1R9mO8xf1~`y!F#c3t8M#NKVe_wxBuC8ozl_8}8+$ zBD~$AdE#d@|NmCr!nnHHnVc~3noc1mV!-Ru-_{BV@hknZv1~h3WApAwId_12z^~Yq zy>pcexm9G(<=N4Smxg{$Ko-1rBM3(@$F(#y0GAkM`IUqI=gQzeogoSVtCxkbw_HWW zx!<|}(U(4RH(Uj6yie|s+^3l1AdH(`4RL!l^3whnmlM@=%ahphSM@)5D3BvecyZ^L zBkUuV4Bm3<;$`ZJ0W((n)vDhUdR(kfGQHQ`@2Tm5l2*er!PhPIbm}I&x0%1Kc;!Sd zeAS=w$~EH8Gj!X@vq<6m^#cj0nZ%2OM}km@*tXj?LYU@iM8v|ECjUw5)-P>HX1djg zUXIEZlBL?xlrpQA{MwapY0CKb%OZB}v@In6-ZM$>WU48wR+ZvFq!o^`IDZU*q=TXP zJkV`ep3O3h=2Z;scevab5+6yNs!MyZbg*?pAlJ@>(|$lSzxG9d@;|fX#SS6i-3tUko(Hg z!RUFqpRfD@S$y3i&$moCvHKex0NE(5u3dUHBKa*V@siiu%dTtzcza|!h4I-G$GW1k;<*?ArkwAnear9ka5-YdxP01B zZ%&e%g95Ci&a7@qOwcmr-J!qWZU6yDjAoK95CDetCtw{d)5VYG&H>k(H=}PJ6UK1$ zs>nx{U#*4iE|18kCp2RpYkh_{`7l-P<2K#*86PbG}N5v6d> zrLMg*v)j;3Wd*#%zN2+;p#=ThGI>x*p1Mkp+SKQ$>dLoG{ivXyBG_h5;)LQ=VirZY zhg3rCk|;jrJ`hF@9(%+Lp`_#WZB zg}l2?2A_=>c+Q%9@h7zLQ@`S4{%e4b%G?%#eiNYnFe`HV3L+wUv!E&RV)HMT$D^bm zhIlwP#7k!lW3YJ8-Nf_7S|6lL|1&+A?16h62`(c? zQ$NAGbXZ~TkNQVIT$Z_3`>T{2CnP^E5Dz2^C?&_(v_L)KUTqcC4Eu(ccODyS3dckb zB624vy4n3Wqd$h;xa~%O4PZ#NjM?b6T{$}+Lsd$b11*tg;r4pQM zj!vtzm-D;-wPp2m5e=G%C*9KjA(WWPdj-(%i!X)?HcYfyYOmFcjNG-ukL3raWXUzY z+7R}9#KSsrjd93n&6vhg=TNPm3pX1;$^ORgRvw!Z{9-P_xgn9x70EETG+hCJGwN;!SqBueQ z#8dhb;YAb~85zn;5F5h{Iz5+*U%3^4_e!{=9C7u$>0!+Nc_7vEG1PZfC;=i4MP)ef zj<&126d)T(P`f>YoQIwnpXx!&vT0wqWV-i?iz(o@fB@6O!vitys9mq#sh7FOCQd8; znyb|~t~4oHoBR8=n9_~TX6>MPOg;%q8sn!&62T)uZa5)EjE(Ale9RVGC&6qg4IN+I z(l?>B&lEn7QKtcp&E~MsGu~LUYQOzy?l4VN?d}aWOLLDe=$Nos%7@>NkUaB0(VxZ_*U=Y zII#kZe)EhqbYIidXHJA5i6F;Y0-(O^3GOYx`4y$Xh!2 z;Yd*~0CCw{peN_fEI8DKA>4y%5s5iqT?N7iWX)m$))Emlx>73Lcn$HS`e7iMiB;XF zFQ~xVr@M1UF1`azBzOI)hNv5$`G-2(mPbL5PpA}6K!vsxPCY5@3@`%wO}X9<4p8^g3{upM;)8RHHJa;%)R{xGTFrePymtt zzRR+IYWwXOcwrsb`HxOGYd^m!GXp#~F%jpr33#4k_c)`*`+atFdU5Tlx5^ZMp+2RX z;Lbk9^-OIA$X{k2ZBwe5$#R0-06K_%8P~5A7iVrP+aIugk?<;?C3=^aKe()et~OMD zz!|taw%4j*pHO(rO$^O9UPfyYoztQ`lZFiRlrPNR;oX7~bT3u%D4r(qkP;>ID(GT1Dz#W8?(qZ?cN&N#ps5&jN2QXOh30 zzDEf#NV^QMk;<+SH&h``V|T*r{@&H`7J(e{b~LyayB4BJPw|0A-p)QtmVuq{q$D=~ zM_s-k9K}M+{Qd#ggVslUG{^qQz)8{@s0JWVHc%O$} zK=3?5Hx}`1^iGoT1SNHUhl1-uk4BNahC(r}rnNj(%(8fr@a=&{^;Y9l)(wt`8?A)r z=fCM~JuhHbF$uKu&zVDwst^Y*;M*OSyS|CLbfgyQ{L0^K5}Xcv$@B<>HX^^;5t0*v z7XIeYE|Pg_fF2fe=!V!$T}3J*r?4ZhhaAOROZgx(QYV9& z_naBDVjD9c~oNLAwYM|P|6XB^vZ5tF|qg0Y5bpem0cXYPimFLmjYF6(L+;86(j zH5Xn(0P2&?83O>HIj_-xMmbaH()#pEL3(!2vJ9JH*$Z7gY_!xP2v-E6C`srX;)Q4T zcE5qQUC6()s+zrPl1zQ}c9mS(`FO;N!8`xyx1*@)*5al!2i@ivQdy|q7a>2C2jGB< zMSufaq9S(zy!y*o60V%D_z&;uHjZnw>h-0y78VQkeoS5xm3@?;l#v2n9-`y<8rbKf z!*EHc(DNZks%>elnTx3bhy_ldDpV$PS+oRv#mQL_S^kzL{mHxx9`gb^z0!01oqQk; zud$%#ezA?bs=ii!eVdc_fL2t>;Bm?bWH(4*N(3)b50mAG^E2W|Z?2C`>=87u1e&$z z=$9dZeHpFd$?p&KuKNpH%k7iWVF_UE3HPG)&hv3#&{l#62OGyVs@%fw4epn*^#+pO zDQdmzVR`wn86XQwV|-*Jl$FH-6&bnsKfaa(Be;cr`5%&!Er61eN|^2nnCv+m86k=u zD>WcTMza6+2GTT063~UH0m++ULqvQ8Bvnz@ej}c~C>eS7X3(3c>{1Z@j+<%T@FJ{B zpNjEAgdJ$(Nn|<(WDt=&!bz;N6C3ELo(Ocf8f{Gj_tz$$I6Ub?kJho+c={Sj`!dz~ z#_D=_2ZK}yzmb9!RSlail53Qo;G(PBEbaX5A)RU12RXkM>ii|4- z8R!Hvf7b2i@qHoG5*P9uM^lg*Gjv&STUynI_Rw1w?&@MH8d6FnUJ7;h*4XS3-s~x8 zw!ZmNL}E!E6p6!(-b4SDW$e@f z+cb)Am6Kb`%YP;JSAaQukR;v*<6Xe4A=-$xg$<&6UbZ54}~c$92}At8+kQ3L7_7|77a1yDx;z^7%&ZTmaKIe@ zg$e%fzchHxC{COos(Q?zWBUu{Q0{!ix4D;?BQmt--_)A_#Vf71wgCfbLB0V)%#giD z2J~swIAfWUj*JTLHCmU@%j{?>aR?t?d@qWNupd%U6Qv`rYBJU}5KBA?6`%qnFk-V9 zf8ulRvL*aw&TC{Y4J5?7=*n%xI36#!TDCdj=6bsIA%j!CK-x{MvBQPA0*I&^gVlNF zI58YG^5ASIKt~$D(>(IZUcRMbdAwG4&!&47=YcF}%ZlyQeE;$Fzb))7f=Vs5F8ZGn zU0RbD^~C+#;W&YK$2JTc{Ai^u0#$VR~M43sXDDIehYXaVd1Kt?M-8T>(E-x%L5Uw03+hWQ)=7{^^<33(A zPC!%!;0VpWy2b=xKK@%`E|S40?K&JV3Rze;TnC!;M(@9_SN~PTJS1}Ru9Tpw1Z%Je zB;V&SuOENOdm_do?{U41TaCW+fLjmE7}|_1(U1rgPg?|%lR*?6P2HI+P-ui~boq_p zXquG0O^${~BP2Z~OZHjq|Lx8HJ;wjXm80pL2+|z22u_M$1UsOr(a<_&XS*&AZ+E|4 z^-_TguK^o*|Gt$J!e$YRgSKI`yOaMy(l|3hM1ImMba>Kcs|%rz$Qg< zcOg;F-{m{zQAyd5LVSQIZTeF(G^{?SD(aG3auM9go4)2!4?-Wm7-a&Cn2$`OGK~|$Mt!;kAO@-% zANj{2!E?Ejk7Yxjs{A;wqYQOJuLQOQ>JkXAvtQqD?@erE7U26>PVBUw{)kQiH6PT@ zn8@EHg;n0_gf(RKx|sK9a(5A!&nmXpanU<4;j;uxq^G4N7{^MzF(0FgK~#JMG#KlV zQg&W#+cO;Z&xQ7G9v`|(cl9EK_|e+{)({7z4i*8*Ox*djsM4NTK!XqmAFFE6$M5r2vZ^{mJiq*at?S7ZFOF|NhgKQ!Z%tnM3%!5azpF~7NLfh_OZKq#u;W36G z=-qC#t6XNXV-bqS+UNQA^6-slO)#2a=TATv5I}4(Z&;whd8`&%W!WUAOGV}{pwS#erE%xHipd*q+L&aDu zVw6x+XVdysm3?ymlV0M%wEgCFnjTiGf9!=ITJ`4<#XSfz`Xt0^izgDRsOO-5p+VjI z6da@+B@U8RgYvtNxeN=uJ?MS>D|UlSI9QtE3)fKB#r~@g?pgw=Hf#|Q@cGCVFQ}EstYm2!te&4$Z-VyJ-zS8dL zrH%>;k_@7+WI;?nb#ypIJo^YSxb`mC4Y-ZxKGPF-yAMKeci_uS&=B%q*mjhVs-a(R zZiFYbF$Q?}ogvsip=c)mK_QoyGx1W%`0e-8A|@YN>uOFK&i3xzw(pb!uVmr4yqQv7 zf!ixtu@&yhds1ub;A&Gq(!5Fh6ZK+4*7rxzdv32DU$)KQKZw?-EZ*DiI?YO4aZy9OKu41z3Mnrcp#I^20zTh`6#yt};%w$}zkx5wvM*Y+B? zn$niIS0WY)6S-o?iP~qv{lGH*&QPaukY2>LUG6KK1gtntjWQ`=#E&~$zAaB&qJTXlQcord6{cGR$;6o+1ms<)IAj3V=H^`oB1nA4%zbkPRWbb2U zok_TZXvK$=nX^^t`UH_>c7xU#ZM4e@@p6RdvywMiI#_mAU`_ZuZ3B>g#*hv9`&DVC z>)~tP?X3F7;$0r!5~8BO)&G*i~6+==uB2Z=rrAf>hK(TiOJE}woYquZr)NW6ACG2_z=(4* z7u1?jI8p^rRQ@%;1$Gw3(}eZy$hWBlrmVsOjChaIGAAlx3Z0A9SX%pUo#E>NEVrmN z#8pUXD}^izcJ4AbUsoGc(#X3l=a#<=PGrdSuCX;lrw7B)%L~!3YXkMr5aLjMwS5Jx zC($k{DVhg&)lMIlHuCCYMuRH-#hF?&{$+}2$^WhG50iZIxKM{7o(2=i|@hc1>9bBW^eHa)EQ3R5|zneul{k&-n* z-y_XP65YfVex+A~oL#2b&Gre+WXKLY7sth>^kn&+>Um39pLG{84RDbrcUN1L5XyV7 zEP!x1f1!}bYHo>1UB@0on7a?r_ckf9Vlg+jCc%U+7{&^yQ_`ifp+d!PgesKG5zDP4 z?B=VAeV*%q6jPZrQhODjc}prOh1@Yn-J?xjVg?j|IOJtK-_VKiT=k}l9$x_Scb!c) zIs(faa^ketz<(q%M@scH%tVjmUt<=THIkh9;E7O}%{dT{-2!>ZAQ4@a;>8`H$|ZT_ zw& z#_#_p`Tobi=q6(I!KfC&lS6%oG<1xMj&v9QyYtYbmw{$LZvH4IQG{wv^n>^3XbL}+ zZMiuWsWL|Wn(8>VhrhB#+hZTXM}e|G@V<1k|ArWY3Xopy>L-PUfuy zrnh$Zvp2l#x<6%yh5&?#%6w_G4eU$W{JfF-SB<=j`T@6X3#DL`Zwv1qgwQm21O0o5 zxZfYxB<;UAg1v}7_gT~+nENb#Kd*ECt%Vf9@A4AE#`;0!^i6!{ zjINA*8jvFBs>xSo!-UBB6dx zXV(+!cM#6|TNiP#tHV*l0Ggy5ic!nB7|oCKjG?p|7(2;eYPOy7hKaUL&~B2f`(~!l z*FCgH1X;Q1=QRzunqhQy5?Tf}l1$=Q1T~S$fKcrW0F3A4YCQ?rq1!QyRp_@^=4BQQ zT=CGG(mT=F@?2;I{kUXrwe|Mm9JrC^C!G!84GK^w=LgaE`R;`A5*#Kc+lRRIcR123 zKm%&%SLx4~41%ELjV~yPEI@nL-|`xL5AltEp8839F3B2G%WYeOfG1s!@~=0j1PMd<%jP_ z|82ZqOQXC|qn#q(@>({zu5?_V@XeX?S`P45Z4L94q)M6h(i2j{ke(S+tq^{f-eOLb z@EYxPB##ZR8K4xjHK-bGbn9%egTg!*ZpqOcBRSPT*t2tb?jUu0KroOMX5-Esf~-;^ z(cpDD^TIgxDklH)p-xYqsp)5|3_%1H_pX^Rum7)x(3^h!wf8b`MDfIjAM;NqtS!%C zIvT08WRjp|W2MB{yjXFcl^NcrKw0zIJHnICxvI=Bme!5i0?04^H}2O#Fqmf(gI>O2 zWewuPrS?|}-tt90U#xiB;r}d!*?qORs!#*s(5TKO*H|T7CieFari?Nl2^ZQs@mO5o zA);_u3o4W%UF>JnnJXei=K-$x2>)|CvpvfK>37X0#WMjsBp9~w`}AVk;M{RW+=%bMM{R_cU-YPJD};IB zSLvac(e1p3H6Xg9a(NTM@UcbOvWcQkdfH3b{ioZ&>GD-<0o8t>5AJZE56Y({76r)C~p zI_a54sr@YuOj3ljC*Q05MwbkNX;??xBjVj7iGL4d>IL;ZS#^M$mUW-i?RLq``q244 z#J)*K9a)I1IQZEUG6?&Bfw7P%8Z)7+56yqk@&BW7(0lN;&^`|tgi0)J5v+(7q#5?$ zL_xn%Fh8dN;kEsKCBe)cN`Ff%p=L|^wB}q(42MPRI~sUDVo!g~pD>Teel+iNDfr&x zXRE+so*2fz>{1geieG)-e*nnnbP78oPGD}V^*h!R@4S9@!?}h64 zeZJL6Ck_#al>ST~{*w$y-9#O^Z;M8)x4Q~%AL~FVjut8y8wSR7weriPQH_LuWx-)O z7YY1v-tW66#Wud7BnbkjwS4y7hZ4(K`5{{JI&VE@n@HtWaGN7We`DSSCsNd>q+mQP za;2VDeriWLl~^ASCI63MV-Zo+U!$~~YF)!8TGMNebwLI|gc^@?6ZeSt+bW7EFccorT>%s`x z`!mE?3u+9u5=bv|S*PB}!O&YxmZS9f%w1Ou0uuR_1*HS7wLhT*_&7c+fE$ejTGE?} zEx$-B&CY`^(QZFFVR1cYx<2dT^1d^mVH3U5yKatZ*=MEr5xtugE~d1fg?PpFMGFWM9%sjnJk9-~L*mF- zs}@t4t{s*yw$f8%X+e=jy}tL{Hytr{`>kdJ^*0>A6ySLVD10&z~*WMpCf4{_L2`!Yxh5v4u*^Qg4q*ocx}e;$d$7%REB=+w{SNE>mO{P&ULhu(66C)M1sk9Od}!fL z0p~zxM<-D2tK0fK#L&59E2t4LE*AFSuroZv=o@lahgA%aO|fPF(RWxs4{QxFR5*dH z0i6F_8ov^m1qy;15Vy`Qs4XWjEWzn%&>YzLqAKJ;FxwmtwUyN$Cm}MOCma5((4>PT zG|4!c-o(7ck2r+}?SJW+b0K=rR32>&Ban>n_{IQFBx1EKCxzBNM=*WN8rx98+puTdZoSa5 zKJ{PlMEPMTb=p^te8|EKHH)vuY@b{831ZHn9rWpjAr<&&xd+Sm?ZdmRpaQwUDv&@x zXRmwjLv*G2otV=D$Qr$PyK|;v`UP_@OTtF=B>>wfvcRpr^I#)N<-We3(De z0GsiYd_wVG*(H6M9ou_+1VNV7gHS>rvjrKC{Qt5|u4so{?L}k!pFYG?o&En=nYod4 zl7D>_x(K`rFhRpGdQ9!0{}Z$yyx@nZ7JM0Uj{ShzS-%h!H=FT+H>V@KOX$vhj|vpS zFyc0NuN|G*dS$;3sR}$%EC7+124*}ArKXBn1D}pb4Oy>Kt+$^F|2IY)LbVgLW4ObM zt~J`U3k3Y90S)@(AzO?PlKz*+jMg^~Gw=7IivXUipqaqyf&+7(>kNGpn+GYAI?*|~ zaI!AmvGX)W*Q+wl{{}dPAoWkVymr3vG7MAQj0&1Ph%R;o%?OYisA@mmVPw=puPyq} zuy=yylGhpUE_dEPM~C3(q7}!o%>aBeHAjE?zXys7L4hX~od#E@>H=Q{Ktv5_ZZaB& zPymPt2%lkpR*4ZmW)mpz6JZ14z2FW7)eGHjL`6T->7Q0Uphm+&$nEClxnN89Q%Gv; z#e@xeP^Iy@QG^p}mjVie~t5FbjsEn=W&`fB{W~qeMx^s>nHBNDm&Me@sW69^} z)ufTVHbbWVnB(r|era_2#2dftRPY1Rjz_{oI#@uBBdh_k-;!6+axNEYEruqV0kwA z>-yT4yZL&)e=TVZJkDGI3c<>%1&yc7k+R*EW9QLPh|tOWAL(KaXc@g@gPc=@B?r@| zWP8-ExOt9yZyL{`jq>EQ+F!@oZ*y5~>@HZ}IS7@*hmSK!Ptq?WZE(YA=LrcDt*Hm{ zgB(q(bd#XUR&v4P&22XGliN_ z;8__vwOF|cnL6dDhdjqM<1XNJkTwKQgO|rwlbSG!ve5zVggZLGMOa_60LoMH!A+pe zjr1w7_tI$obSl?YVUr8+IRrP5V+ucn#R2iTCvyp=ELh$EWNgLV7l zejr72W@N`Qm{NSUWYoyS<0VY&U~2l=6!qgRD@tU8|-Ep~IOmL<=R3*c5*IQYpNim#Syy`hR4(A0`l`I<>@m>)HIa0i^Vl z1sbmPd1S`W&tT9%LG2@?#p|?Yyw@iuH4+*k{7>{aQzT|+{`b{*t(DAvt>pF$v zFP7q(YLnKS9R_uR*6mQkv+u`75w{=vjmRRtqU&)}ua3Q2aikZ&0U*fpbGpcVyk*53 zMVbFq!1StrUwGhawu#NaQ_U$2C4A=KhZowrLU?1knk-I@_H2%HCW*rZif4 z53S`USAp9=1Z=-JikoD^JJcetQ|p(NC1*Wn0d#~L(~H;h)oU*uYKP>HPV>~Bo(on! zd>Oh4vcK_NKZ2MvMatV^hgf7KR85x!?2=+jLP4h_xsiGpw}xNF&u431VA?q>(*`mo zWsAB?oI^9TZ3T90bNDc(se}5k`gy>=u57!1ILqTfzlK7~@)7tr8d1b45^cFA9!t#X z)xkZ0(e4^`?QX8gSiC&r1U*6B8KC3(l0)z}g^WI06%pgrCnUE4oxe%g?xch6pSg+o z+ym%ZDVkT3P&En>BMBM8EngKpS(!q={D{&~MVFqwo{*l0jy=hdLO#3B`;Aq2tVHTC zCawC2ko0Sfvu$U27RqggwHPn~Y70H?g&A1sa+HG9)c1~r`j6D&$szi`5JK1(U6&tG zxi-}yxOSa*eBQ@;eAI+Qm$s}BgMooe1kCKX3SCd~MO;sjHoCCmS?jd{=2>0VWci`) z4K{ZpR?Egac8rZK9*jXgU2(S+yv9Qc@Y4#e!>uD zI6$gV?Dv*5?~VyiD!3GmSN)r)YgR?X8H<_Cign4+iYVG)eIV(gLFJ35P{v2Yz?;<5 zdJ+gOcvJe@6w?V{a6mCR&wTM7*B4es@&=UqGguiV>;Yq(4xy9RYetj1ilBW zBYHe**2HoRE0l0*gdXKCV`n<(WPfQ|VQD#H-IWZLRc;p+ZXpnls^Gl1fMod+?K7yVKGbNf!w`e zWhv-I;K=>Cj_mmG(In0Eqc8vYEn4OX(rlE8q@nNYw$q!NGk6JT5g2;BQf%b{yP3Y3 zIj!eyd{;D-n*S||`qhtFSGV^sAZ8;w5l}h236LD8diJ=KU*!!gM+b<%N>_7mq)<9t z`FXi#;iSdagf~~EeafvjBle84C9=_Pkldpr-1l%P0_C$hf}$qgM1o9K)yJRlzb9E~ z7Rqr9R}#p*+S7~TNm=iO=?9`nWuNNyt@}(&5GCJvtt}l?kT5ouFg7**ih7}!A$4~^ zFP64neod=q;Y!0@tFM$RxBlmML|6aYCoX@r?BZq=m9owh=#AsV-`ITpW5Vgh8jTh? zIS({DC=f7ceeI&Ht)1lKzAP(oad63AoG+isB9Oy2ocyGzJXFrd;OrnH9Ey-fN!4_t042|KGr z>^K+Zp9Z9jSA+2KPV3=^zvjWQWzQSocY8pGb>#>Z+%#fWdMJa^4kT4;nQG^qMIve0 zG+0db$?p%R+NgYc)RsLmQ+E{@n(%k|7HUeO(+IM$zq{OX&tMecxw%`(383Ps0U4H( zw3w&ZYQ0KJcwI9&(H_-M*ESk)NM!`>dsoz(bRNo;x%TpF72T90pArmh$I zDex^sac=e>Q3P`SpRS3r<2sus3bCHNfP4Rwm1b#cvS}`{-oz)F0K&d7cUY0>CRgP$ z+Q4ft^0C9CdUC73Ba>CF8l;QCtXasb1v3DU(zhrBWVm87RUajrSvHNyc2DF%3o=T0 z+JrT}U_7q&s>ZS`I6|zLC_R(+(uB^W>)WF~ePUR%>^w#-bj}n?YoX#ssI0!*7KVJ0 z`xMfc)Q!-6BD=dL`3oQU=c3Cs;Zp5B8wc^aa$ItkY{8o#cEx1?1kZFK!iHrLj3S;pX7DfP<6rfts59;1hc}r<@3)qGpipS90Dmv!AaU!IK-ePEH zus@0jM2P!y>xUcWeV^b+54fC2OY=*b#hM3ab;P{bZs6AnKwH8v^cWvQwt}IF&pD}Q zb@JE}_M1=y1W1CY^*u{P0S6&Ov$ZYq^$wDpKtYsB(XY#zS2Ho4h z2`w_3r{D0DghmGHCDgstidMBq!oz3Ju}v2<;b4*ryf{b%;c< z#eO>qd@;G*LJ}CXt?BOc>wlk zqeefJ?&YtO$RlX-jMg^YH#0zcR>|_yj2)RjlGu8cagdq5_4*|fjInW3$=T1~;+MEby;_BwO5N_4kFPOG(i&pSz%RKfosxHG5{-SNND?0R$Qy6ONwd& zy_YJ_(yK=5VZ1-V0|E-9T{dSlYtG2uD2liIy<>Sq?a450){Mb6-Oo6Ge?!qdk<@qsF~ zdC$#O{KX6hSSME-zlf8GVt`foMX*c zEr1wUOeD{@1D$9G-9Jx>N=W(@|8kAE)rMg<-=C3`+n4LrKL+qmfc}+}D3K zu)Oe^=bnh5joT^rF_dz1oIiV58K!3VzagFFKcVVVk*{;xf(LSs z{v5QTc%FR<#7jskf4xoo7xUf4^cGmvaS*|_r&*%$0rx}M$v0Fc-H!dJ?VCy%xOS&C zez|oISg=L$FC2AhRrZ%|A?vN5d)C+FesLwuSrBd)D61fmG)(#-@ef&aVzT3QRp8-}g=f^#lg?;ilR3j$zPI#;&EUZbW4ZnZ9(lHprsT`BB-v-AbPLPcYk>WYafQ6I~eqU!cf z0X05e!}d?B>9$|KnPk0!JyEK{!lw9DPM53W9*uivcirN+M@l1E0w*x|!S!ZMl67Ni z>Q}*5{YVW}m-n)pjcUTl3VV`;a;h6ZzdSPG=fuAE-xUshSOZ){y2{Z6d;BQtCf5GL z_BEu7DG9>UB3vK2i$#eAx8kF_-O8TVmtV=c7=AuHRKzX8r!tjU$t{r3;Xf_=ZSs}{ z?;=}i^hu%CHtPb*uFsOU&K#Ve$}5Z|CBG~4H)iqeDvNjE2dm6nzF`hDp1iZ^wixfQ z2E+ZQl+J#Cfe5inFDm%0A?6=MKLOgwLP?7Iwwk2g@Wy8AHFb~N7T07YZGO=}OXoaG z$b-MH+f1FJKA+zcjqd5W9V+4FH@{P(FcL1cj4+Js=NDS2zT;qItta2?lIk(&0t{w$ zsC_#`Iz0lXPVo-^tYxcVqCFBUqm z#7o=p`lEc1?4$Y>zeTYJ=<9&OIukeiA8>G0k7Yh9M2iV44Y zzV~Z%HGw(-7G#U1uR+p=W3r!z0vQDp&G~FL@`;ULAl>oQ62b+l2+G zqqbZ3Tt!drPZTu>ZJSWC<`|7l;AE+p~84|`(347=AZl-M$#6XYe!ZMC# zOLrhrUDN#Gfdj3EJ->xyEnZ#;WATUNJdd@cFA`SpA@F!ioVi;xoWmX}^P`AL4o_g7 z!|xmI&Z^p}y*wz?2z*GhTZO)o!5K5Y)>~bUI~aH6$DwTx;cWsX zQV)GP`U9PZ=(RP910G4lK!!iNcPj8nz`fQ!S}RdTGekCz5*gJhPIPe{9o`+SzR(SL zoI%(bW&DK)X2_y%jmBg8li+XIRjF6isOjO}844_ueUk0XIUxB5UME4zRPF=ifY$4#tzau0oe8jF3uT-@U_oXpLW@N4L}YY5f$w} zLeL4jHan~?0d}ljb!2W}Baq9bmn+s1?NBSc8w*V<{Z?OG3@13!^rl2UfosB$IAZu` zPCITqXghx%>l@p*)ztsMR{%VPsBFkNmMe{RthqJA3PhEYGge2Y3+-TE_A)#RQ(-=K z2!pq3x_jnqgKdcHfyRlAhVoLbTTZ(sRTVoNe2C!<*c?n)S)7V$jLq=U6GgEHg8MxA zMu@sfX@s%wrtJ}$Iu#pNuX7(0QqD{3JdSlgjSEwhTD)VFD}>7p5)(L?Tb3KX{{4;< zH#=O|(SLL}7aJ&E%5pPa(5rdgdCX=uPDb;9b21&S92C9!E?@G+R08^)A?*i#%=Sm=81X zEl%zvod1ZhTzunux(3L-=fTz?YAA#1F?z%Yc6Yf~@+|32}bL-^He3+qcl z_h}eL;LmVK#9{XAKJBiij?h9-TRT48L^LfI5WoyW4vR_L{G}sToZtg5bmj9);}plx37XnAo-(L(eCV==5|?}BCX=GQ4=d4RyS3ZQ^(+%p^{mj!sV zwW-C~ro4zE6aaZ@NfHbXY}4A1SAgDk1zqda&7d~DUp=XFci1~%I5`q>cAO9u4q*h^sNn=5BO}9M~a_O;oe>LRmzQv(}x9i zUw}Dmtb?7y@>j4$$YlJAz1Xw3R9x^$Tdl>!wf7b%$AY!+Juy?%&yYU#mOw;NFg$V2d<25>8kDszbeuB<-Ok#K5 zL!3P*z_22%RP<5j%TkzVmOZ|v6aXU+2YD9NS^GJ6M|EkKS_gQlUf()eM8gOObz#~S zZ(x)4P)QyIpWGfjfCPVjWb%8l`8tcQKv<^}0Y@QfG2h|%(i-3(@9eO??>)DpwUgF} z(=e0JA2Zn(Kyb4CXl;)eG62JdMEFM&=0te(T$1Q9Wzd+%E@SqBTQY5f%HvT z_E&72iB?E>I2i|A(9ct#%gi3z3m&rky)@9kSid~rCq;xL`ku-lm&`9M^fVZ{vE535 z0xuE@$SyWO(^fOx6rHmqLN5|jRGqXiT@|}mf+bCdlRVK%& zM@`7io__T+WQsXG@q)LLaXU7+dg`AFd_cU#bbL~Y=6s0 zWKw_N6=8@rOasIp2uo-`^Th+{Wg>3pVWXU46XDWCxE zqH-1E1#TJFKMl{cc*i&-r35g>NY!91OCHSA@CLZ5XP9X@hn!uPQ5X;NGtan4M$9U z@Z}){fL+ekrhVSbq?_CttGOzGU?{n`+sVG%(i7Wfv7h6a3DioSL@-YG@~8}BlPzy# zgn)&WKr9-KmgC~FJ~Zh<=QBlAlhMRuwBRBhWyjX(Tj z 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 RZgUne(l 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≫GY{W@VG5_B?W__%t* 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 literal 0 HcmV?d00001 diff --git a/doc/install/azure/img/azure-vm-management-settings-network-interfaces.png b/doc/install/azure/img/azure-vm-management-settings-network-interfaces.png new file mode 100644 index 0000000000000000000000000000000000000000..4ff1071805979d4b3f78117535422cf4a8dfd54b GIT binary patch literal 35849 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