diff options
36 files changed, 358 insertions, 85 deletions
diff --git a/app/assets/javascripts/diffs/components/diff_file.vue b/app/assets/javascripts/diffs/components/diff_file.vue index 8babc05f1ce..e09bf1f8005 100644 --- a/app/assets/javascripts/diffs/components/diff_file.vue +++ b/app/assets/javascripts/diffs/components/diff_file.vue @@ -58,6 +58,9 @@ export default { hasDiff() { return hasDiff(this.file); }, + isActive() { + return this.currentDiffFileId === this.file.file_hash; + }, isFileTooLarge() { return this.file.viewer.error === diffViewerErrors.too_large; }, @@ -143,7 +146,7 @@ export default { <div :id="file.file_hash" :class="{ - 'is-active': currentDiffFileId === file.file_hash, + 'is-active': isActive, }" class="diff-file file-holder" > @@ -153,6 +156,7 @@ export default { :collapsible="true" :expanded="!isCollapsed" :add-merge-request-buttons="true" + :is-active="isActive" class="js-file-title file-title" @toggleFile="handleToggle" @showForkMessage="showForkMessage" diff --git a/app/assets/javascripts/diffs/components/diff_file_header.vue b/app/assets/javascripts/diffs/components/diff_file_header.vue index d4270960f57..bad82c84601 100644 --- a/app/assets/javascripts/diffs/components/diff_file_header.vue +++ b/app/assets/javascripts/diffs/components/diff_file_header.vue @@ -55,6 +55,11 @@ export default { type: Boolean, required: true, }, + isActive: { + type: Boolean, + required: false, + default: false, + }, }, computed: { ...mapGetters('diffs', ['diffHasExpandedDiscussions', 'diffHasDiscussions']), @@ -158,6 +163,9 @@ export default { <div ref="header" class="js-file-title file-title file-title-flex-parent" + :class="{ + 'is-active': isActive, + }" @click.self="handleToggleFile" > <div class="file-header-content"> diff --git a/app/assets/javascripts/diffs/components/tree_list.vue b/app/assets/javascripts/diffs/components/tree_list.vue index eca9091f92f..fcf87807e75 100644 --- a/app/assets/javascripts/diffs/components/tree_list.vue +++ b/app/assets/javascripts/diffs/components/tree_list.vue @@ -26,7 +26,7 @@ export default { }; }, computed: { - ...mapState('diffs', ['tree', 'renderTreeList']), + ...mapState('diffs', ['tree', 'renderTreeList', 'currentDiffFileId', 'viewedDiffFileIds']), ...mapGetters('diffs', ['allBlobs']), filteredTreeList() { const search = this.search.toLowerCase().trim(); @@ -96,6 +96,8 @@ export default { :level="0" :hide-file-stats="hideFileStats" :file-row-component="$options.DiffFileRow" + :active-file="currentDiffFileId" + :viewed-files="viewedDiffFileIds" @toggleTreeOpen="toggleTreeOpen" @clickFile="scrollToFile" /> diff --git a/app/assets/javascripts/diffs/store/modules/diff_state.js b/app/assets/javascripts/diffs/store/modules/diff_state.js index 81f1506260c..f1bd9d8981d 100644 --- a/app/assets/javascripts/diffs/store/modules/diff_state.js +++ b/app/assets/javascripts/diffs/store/modules/diff_state.js @@ -26,6 +26,7 @@ export default () => ({ showTreeList: true, currentDiffFileId: '', projectPath: '', + viewedDiffFileIds: [], commentForms: [], highlightedRow: null, renderTreeList: true, diff --git a/app/assets/javascripts/diffs/store/mutations.js b/app/assets/javascripts/diffs/store/mutations.js index bb4c80b5759..6438dad4f7f 100644 --- a/app/assets/javascripts/diffs/store/mutations.js +++ b/app/assets/javascripts/diffs/store/mutations.js @@ -284,6 +284,9 @@ export default { }, [types.UPDATE_CURRENT_DIFF_FILE_ID](state, fileId) { state.currentDiffFileId = fileId; + if (!state.viewedDiffFileIds.includes(fileId)) { + state.viewedDiffFileIds = [fileId, ...state.viewedDiffFileIds]; + } }, [types.OPEN_DIFF_FILE_COMMENT_FORM](state, formData) { state.commentForms.push({ diff --git a/app/assets/javascripts/vue_shared/components/file_row.vue b/app/assets/javascripts/vue_shared/components/file_row.vue index 4d60cf5b1cc..5a953b351f9 100644 --- a/app/assets/javascripts/vue_shared/components/file_row.vue +++ b/app/assets/javascripts/vue_shared/components/file_row.vue @@ -18,6 +18,16 @@ export default { type: Number, required: true, }, + activeFile: { + type: String, + required: false, + default: '', + }, + viewedFiles: { + type: Array, + required: false, + default: () => [], + }, }, computed: { isTree() { @@ -34,8 +44,8 @@ export default { fileClass() { return { 'file-open': this.isBlob && this.file.opened, - 'is-active': this.isBlob && this.file.active, - folder: this.isTree, + 'is-active': this.isBlob && (this.file.active || this.activeFile === this.file.fileHash), + 'is-viewed': this.isBlob && this.viewedFiles.includes(this.file.fileHash), 'is-open': this.file.opened, }; }, @@ -107,15 +117,23 @@ export default { v-else :class="fileClass" :title="file.name" - class="file-row" + class="file-row text-left px-1 py-2 ml-n2 d-flex align-items-center" role="button" @click="clickFile" @mouseleave="$emit('mouseleave', $event)" > - <div class="file-row-name-container"> - <span ref="textOutput" :style="levelIndentation" class="file-row-name str-truncated"> + <div class="file-row-name-container w-100 d-flex align-items-center"> + <span + ref="textOutput" + :style="levelIndentation" + class="file-row-name str-truncated d-inline-block" + :class="[ + { 'folder font-weight-normal': isTree }, + fileClass['is-viewed'] ? 'font-weight-normal' : 'font-weight-bold', + ]" + > <file-icon - class="file-row-icon" + class="file-row-icon align-middle mr-1" :class="{ 'text-secondary': file.type === 'tree' }" :file-name="file.name" :loading="file.loading" @@ -132,14 +150,8 @@ export default { <style> .file-row { - display: flex; - align-items: center; height: 32px; - padding: 4px 8px; - margin-left: -8px; - margin-right: -8px; border-radius: 3px; - text-align: left; cursor: pointer; } @@ -157,24 +169,15 @@ export default { } .file-row-name-container { - display: flex; - width: 100%; - align-items: center; overflow: visible; } .file-row-name { - display: inline-block; flex: 1; max-width: inherit; - height: 19px; + height: 20px; line-height: 16px; text-overflow: ellipsis; white-space: nowrap; } - -.file-row-name .file-row-icon { - margin-right: 2px; - vertical-align: middle; -} </style> diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss index 0c043e4f3fb..991ee841398 100644 --- a/app/assets/stylesheets/pages/diff.scss +++ b/app/assets/stylesheets/pages/diff.scss @@ -69,6 +69,11 @@ } } + .file-title.is-active, + .file-title-flex-parent.is-active { + background-color: $gray-200; + } + @media (min-width: map-get($grid-breakpoints, md)) { &.conflict .file-title, &.conflict .file-title-flex-parent { diff --git a/app/models/project_services/teamcity_service.rb b/app/models/project_services/teamcity_service.rb index 68c07fa37f2..209b691ef98 100644 --- a/app/models/project_services/teamcity_service.rb +++ b/app/models/project_services/teamcity_service.rb @@ -86,7 +86,11 @@ class TeamcityService < CiService def calculate_reactive_cache(sha, ref) response = get_path("httpAuth/app/rest/builds/branch:unspecified:any,revision:#{sha}") - { build_page: read_build_page(response), commit_status: read_commit_status(response) } + if response + { build_page: read_build_page(response), commit_status: read_commit_status(response) } + else + { build_page: teamcity_url, commit_status: :error } + end end def execute(data) @@ -149,7 +153,7 @@ class TeamcityService < CiService end def get_path(path) - Gitlab::HTTP.get(build_url(path), verify: false, basic_auth: basic_auth) + Gitlab::HTTP.try_get(build_url(path), verify: false, basic_auth: basic_auth, extra_log_info: { project_id: project_id }) end def post_to_build_queue(data, branch) diff --git a/app/services/projects/lfs_pointers/lfs_list_service.rb b/app/services/projects/lfs_pointers/lfs_list_service.rb index a07fa93a279..59c86c08120 100644 --- a/app/services/projects/lfs_pointers/lfs_list_service.rb +++ b/app/services/projects/lfs_pointers/lfs_list_service.rb @@ -4,14 +4,12 @@ module Projects module LfsPointers class LfsListService < BaseService - REV = 'HEAD' - # Retrieve all lfs blob pointers and returns a hash # with the structure { lfs_file_oid => lfs_file_size } def execute return {} unless project&.lfs_enabled? - Gitlab::Git::LfsChanges.new(project.repository, REV) + Gitlab::Git::LfsChanges.new(project.repository) .all_pointers .map! { |blob| [blob.lfs_oid, blob.lfs_size] } .to_h diff --git a/app/workers/authorized_keys_worker.rb b/app/workers/authorized_keys_worker.rb index b2333033e56..eabfd89ba60 100644 --- a/app/workers/authorized_keys_worker.rb +++ b/app/workers/authorized_keys_worker.rb @@ -3,7 +3,7 @@ class AuthorizedKeysWorker include ApplicationWorker - PERMITTED_ACTIONS = [:add_key, :remove_key].freeze + PERMITTED_ACTIONS = %w[add_key remove_key].freeze feature_category :source_code_management urgency :high @@ -13,11 +13,13 @@ class AuthorizedKeysWorker def perform(action, *args) return unless Gitlab::CurrentSettings.authorized_keys_enabled? - case action - when :add_key + case action.to_s + when 'add_key' authorized_keys.add_key(*args) - when :remove_key + when 'remove_key' authorized_keys.remove_key(*args) + else + raise "Unknown action: #{action.inspect}" end end diff --git a/app/workers/gitlab_shell_worker.rb b/app/workers/gitlab_shell_worker.rb index 0db794793d4..b104d3c681e 100644 --- a/app/workers/gitlab_shell_worker.rb +++ b/app/workers/gitlab_shell_worker.rb @@ -13,7 +13,7 @@ class GitlabShellWorker # rubocop:disable Scalability/IdempotentWorker # enqueued in the previous release, so handle them here. # # See https://gitlab.com/gitlab-org/gitlab/-/issues/25095 for more details - if AuthorizedKeysWorker::PERMITTED_ACTIONS.include?(action) + if AuthorizedKeysWorker::PERMITTED_ACTIONS.include?(action.to_s) AuthorizedKeysWorker.new.perform(action, *arg) return diff --git a/changelogs/unreleased/208923-enable-batch-counting-for-some-individual-queries-2.yml b/changelogs/unreleased/208923-enable-batch-counting-for-some-individual-queries-2.yml new file mode 100644 index 00000000000..12456aa9b9b --- /dev/null +++ b/changelogs/unreleased/208923-enable-batch-counting-for-some-individual-queries-2.yml @@ -0,0 +1,5 @@ +--- +title: Optimize template_repositories query by using batch counting +merge_request: 27352 +author: +type: performance diff --git a/changelogs/unreleased/212178-fix-authorized-keys-worker.yml b/changelogs/unreleased/212178-fix-authorized-keys-worker.yml new file mode 100644 index 00000000000..a95f2e0e71a --- /dev/null +++ b/changelogs/unreleased/212178-fix-authorized-keys-worker.yml @@ -0,0 +1,5 @@ +--- +title: Fix updating the authorized_keys file +merge_request: 27798 +author: +type: fixed diff --git a/changelogs/unreleased/24629.yml b/changelogs/unreleased/24629.yml new file mode 100644 index 00000000000..1b39cff8d18 --- /dev/null +++ b/changelogs/unreleased/24629.yml @@ -0,0 +1,5 @@ +--- +title: Highlight currently focused/viewed file in file tree +merge_request: 27703 +author: +type: changed diff --git a/changelogs/unreleased/29825-reactivecaching-sidekiq-queue-overloaded-teamcity.yml b/changelogs/unreleased/29825-reactivecaching-sidekiq-queue-overloaded-teamcity.yml new file mode 100644 index 00000000000..face6ee9c40 --- /dev/null +++ b/changelogs/unreleased/29825-reactivecaching-sidekiq-queue-overloaded-teamcity.yml @@ -0,0 +1,5 @@ +--- +title: Set commit status to failed if the TeamCity connection is refused +merge_request: 27395 +author: +type: fixed diff --git a/db/migrate/20200316162648_add_index_on_namespace_id_and_id_to_projects.rb b/db/migrate/20200316162648_add_index_on_namespace_id_and_id_to_projects.rb new file mode 100644 index 00000000000..96fbab1e2ea --- /dev/null +++ b/db/migrate/20200316162648_add_index_on_namespace_id_and_id_to_projects.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class AddIndexOnNamespaceIdAndIdToProjects < ActiveRecord::Migration[6.0] + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def up + add_concurrent_index :projects, [:namespace_id, :id] + remove_concurrent_index :projects, :namespace_id + end + + def down + add_concurrent_index :projects, :namespace_id + remove_concurrent_index :projects, [:namespace_id, :id] + end +end diff --git a/db/migrate/20200323075043_add_max_personal_access_token_lifetime_to_namespaces.rb b/db/migrate/20200323075043_add_max_personal_access_token_lifetime_to_namespaces.rb new file mode 100644 index 00000000000..907c832ce46 --- /dev/null +++ b/db/migrate/20200323075043_add_max_personal_access_token_lifetime_to_namespaces.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class AddMaxPersonalAccessTokenLifetimeToNamespaces < ActiveRecord::Migration[6.0] + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def up + with_lock_retries do + add_column :namespaces, :max_personal_access_token_lifetime, :integer + end + end + + def down + with_lock_retries do + remove_column :namespaces, :max_personal_access_token_lifetime + end + end +end diff --git a/db/structure.sql b/db/structure.sql index 2af6dcba3fd..e5d28e499f9 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -3944,7 +3944,8 @@ CREATE TABLE public.namespaces ( max_artifacts_size integer, mentions_disabled boolean, default_branch_protection smallint, - unlock_membership_to_ldap boolean + unlock_membership_to_ldap boolean, + max_personal_access_token_lifetime integer ); CREATE SEQUENCE public.namespaces_id_seq @@ -9656,7 +9657,7 @@ CREATE INDEX index_projects_on_name_and_id ON public.projects USING btree (name, CREATE INDEX index_projects_on_name_trigram ON public.projects USING gin (name public.gin_trgm_ops); -CREATE INDEX index_projects_on_namespace_id ON public.projects USING btree (namespace_id); +CREATE INDEX index_projects_on_namespace_id_and_id ON public.projects USING btree (namespace_id, id); CREATE INDEX index_projects_on_path_and_id ON public.projects USING btree (path, id); @@ -12701,6 +12702,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20200313101649'), ('20200313123934'), ('20200316111759'), +('20200316162648'), ('20200316173312'), ('20200317142110'), ('20200318152134'), @@ -12708,5 +12710,6 @@ INSERT INTO "schema_migrations" (version) VALUES ('20200318163148'), ('20200318164448'), ('20200318165448'), -('20200319203901'); +('20200319203901'), +('20200323075043'); diff --git a/doc/development/code_review.md b/doc/development/code_review.md index 471dcba4c2a..830c3d3b3d2 100644 --- a/doc/development/code_review.md +++ b/doc/development/code_review.md @@ -73,6 +73,9 @@ from teams other than your own. **approved by a [UX lead](https://about.gitlab.com/company/team/)**. 1. If your merge request includes a new dependency or a filesystem change, it must be **approved by a [Distribution team member](https://about.gitlab.com/company/team/)**. See how to work with the [Distribution team](https://about.gitlab.com/handbook/engineering/development/enablement/distribution/#how-to-work-with-distribution) for more details. +1. If your merge request includes documentation changes, it must be **approved + by a [Technical writer](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers)**, based on + the appropriate [product category](https://about.gitlab.com/handbook/product/categories/). #### Security requirements @@ -84,12 +87,17 @@ The responsibility to find the best solution and implement it lies with the merge request author. Before assigning a merge request to a maintainer for approval and merge, they -should be confident that it actually solves the problem it was meant to solve, -that it does so in the most appropriate way, that it satisfies all requirements, -and that there are no remaining bugs, logical problems, uncovered edge cases, -or known vulnerabilities. The best way to do this, and to avoid unnecessary -back-and-forth with reviewers, is to perform a self-review of your own merge -request, following the [Code Review](#reviewing-a-merge-request) guidelines. +should be confident that: + +- It actually solves the problem it was meant to solve. +- It does so in the most appropriate way. +- It satisfies all requirements. +- There are no remaining bugs, logical problems, uncovered edge cases, + or known vulnerabilities. + +The best way to do this, and to avoid unnecessary back-and-forth with reviewers, +is to perform a self-review of your own merge request, following the +[Code Review](#reviewing-a-merge-request) guidelines. To reach the required level of confidence in their solution, an author is expected to involve other people in the investigation and implementation processes as @@ -110,11 +118,11 @@ request diff alerting the reviewer to anything important as well as for anything that demands further explanation or attention. Examples of content that may warrant a comment could be: -- The addition of a linting rule (Rubocop, JS etc) -- The addition of a library (Ruby gem, JS lib etc) -- Where not obvious, a link to the parent class or method -- Any benchmarking performed to complement the change -- Potentially insecure code +- The addition of a linting rule (Rubocop, JS etc). +- The addition of a library (Ruby gem, JS lib etc). +- Where not obvious, a link to the parent class or method. +- Any benchmarking performed to complement the change. +- Potentially insecure code. Avoid: @@ -233,6 +241,11 @@ first time. addressed. If there's an open reply, an open thread, a suggestion, a question, or anything else, the thread should be left to be resolved by the reviewer. +- It should not be assumed that all feedback requires their recommended changes + to be incorporated into the MR before it is merged. It is a judgment call by + the MR author and the reviewer as to if this is required, or if a follow-up + issue should be created to address the feedback in the future after the MR in + question is merged. - Push commits based on earlier rounds of feedback as isolated commits to the branch. Do not squash until the branch is ready to merge. Reviewers should be able to read individual updates based on their earlier feedback. diff --git a/doc/development/contributing/merge_request_workflow.md b/doc/development/contributing/merge_request_workflow.md index 030cced8c2b..0ac08ec2eae 100644 --- a/doc/development/contributing/merge_request_workflow.md +++ b/doc/development/contributing/merge_request_workflow.md @@ -48,13 +48,8 @@ request is as follows: but do not change the commit history if you're working on shared branches though. 1. Push the commit(s) to your working branch in your fork. 1. Submit a merge request (MR) to the `master` branch in the main GitLab project. - 1. Your merge request needs at least 1 approval, but feel free to require more. - For instance if you're touching both backend and frontend code, it's a good idea - to require 2 approvals: 1 from a backend maintainer and 1 from a frontend - maintainer. - 1. If you're submitting changes to documentation, you'll need approval from a technical - writer, based on the appropriate [product category](https://about.gitlab.com/handbook/product/categories/). - Only assign the MR to them when it's ready for docs review. + 1. Your merge request needs at least 1 approval, but depending on your changes + you might need additional approvals. Refer to the [Approval guidelines](../code_review.md#approval-guidelines). 1. You don't have to select any specific approvers, but you can if you really want specific people to approve your merge request. 1. The MR title should describe the change you want to make. @@ -66,18 +61,12 @@ request is as follows: 1. Mention the issue(s) your merge request solves, using the `Solves #XXX` or `Closes #XXX` syntax to [auto-close](../../user/project/issues/managing_issues.md#closing-issues-automatically) the issue(s) once the merge request is merged. -1. If you're allowed to (Core team members, for example), set a relevant milestone - and [labels](issue_workflow.md). -1. If the MR changes the UI, you'll need approval from a Product Designer (UX), based on the appropriate [product category](https://about.gitlab.com/handbook/product/categories/). UI changes should use available components from the GitLab Design System, [Pajamas](https://design.gitlab.com/). The MR must include *Before* and *After* screenshots. +1. If you're allowed to, set a relevant milestone and [labels](issue_workflow.md). +1. UI changes should use available components from the GitLab Design System, + [Pajamas](https://design.gitlab.com/). The MR must include *Before* and + *After* screenshots. 1. If the MR changes CSS classes, please include the list of affected pages, which can be found by running `grep css-class ./app -R`. -1. Be prepared to answer questions and incorporate feedback into your MR with new - commits. Once you have fully addressed a suggestion from a reviewer, click the - "Resolve thread" button beneath it to mark it resolved. - 1. The merge request author resolves only the threads they have fully addressed. - If there's an open reply or thread, a suggestion, a question, or anything else, - the thread should be left to be resolved by the reviewer. - 1. It should not be assumed that all feedback requires their recommended changes to be incorporated into the MR before it is merged. It is a judgment call by the MR author and the reviewer as to if this is required, or if a follow-up issue should be created to address the feedback in the future after the MR in question is merged. 1. If your MR touches code that executes shell commands, reads or opens files, or handles paths to files on disk, make sure it adheres to the [shell command guidelines](../shell_commands.md) @@ -98,6 +87,10 @@ request is as follows: `doc/update/upgrading_from_source.md` in the same merge request. If these instructions are specific to a version, add them to the "Version specific upgrading instructions" section. +1. Read and adhere to + [The responsibility of the merge request author](../code_review.md#the-responsibility-of-the-merge-request-author). +1. Read and follow + [Having your merge request reviewed](../code_review.md#having-your-merge-request-reviewed). If you would like quick feedback on your merge request feel free to mention someone from the [core team](https://about.gitlab.com/community/core-team/) or one of the diff --git a/doc/user/project/integrations/img/panel_context_menu_v12_10.png b/doc/user/project/integrations/img/panel_context_menu_v12_10.png Binary files differnew file mode 100644 index 00000000000..e6b0f75406d --- /dev/null +++ b/doc/user/project/integrations/img/panel_context_menu_v12_10.png diff --git a/doc/user/project/integrations/img/panel_context_menu_v12_8.png b/doc/user/project/integrations/img/panel_context_menu_v12_8.png Binary files differdeleted file mode 100644 index 86d2b26b713..00000000000 --- a/doc/user/project/integrations/img/panel_context_menu_v12_8.png +++ /dev/null diff --git a/doc/user/project/integrations/prometheus.md b/doc/user/project/integrations/prometheus.md index c64077c00f1..502e0f95dd2 100644 --- a/doc/user/project/integrations/prometheus.md +++ b/doc/user/project/integrations/prometheus.md @@ -589,7 +589,7 @@ When viewing a custom dashboard of a project, you can view the original From each of the panels in the dashboard, you can access the context menu by clicking the **{ellipsis_v}** **More actions** dropdown box above the upper right corner of the panel to take actions related to the chart's data. -![Context Menu](img/panel_context_menu_v12_8.png) +![Context Menu](img/panel_context_menu_v12_10.png) The options are: diff --git a/lib/gitlab/git/lfs_changes.rb b/lib/gitlab/git/lfs_changes.rb index 8e2a925dfea..a0fab67e450 100644 --- a/lib/gitlab/git/lfs_changes.rb +++ b/lib/gitlab/git/lfs_changes.rb @@ -3,7 +3,7 @@ module Gitlab module Git class LfsChanges - def initialize(repository, newrev) + def initialize(repository, newrev = nil) @repository = repository @newrev = newrev end diff --git a/lib/gitlab/http.rb b/lib/gitlab/http.rb index 58bce613a98..911b71c3734 100644 --- a/lib/gitlab/http.rb +++ b/lib/gitlab/http.rb @@ -25,5 +25,17 @@ module Gitlab rescue HTTParty::RedirectionTooDeep raise RedirectionTooDeep end + + def self.try_get(path, options = {}, &block) + log_info = options.delete(:extra_log_info) + self.get(path, options, &block) + + rescue *HTTP_ERRORS => e + extra_info = log_info || {} + extra_info = log_info.call(e, path, options) if log_info.respond_to?(:call) + + Gitlab::ErrorTracking.log_exception(e, extra_info) + nil + end end end diff --git a/package.json b/package.json index abf790f00fc..48c14db4e57 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "@gitlab/ui": "^9.31.1", "@gitlab/visual-review-tools": "1.5.1", "@sentry/browser": "^5.10.2", - "@sourcegraph/code-host-integration": "0.0.31", + "@sourcegraph/code-host-integration": "0.0.33", "apollo-cache-inmemory": "^1.6.3", "apollo-client": "^2.6.4", "apollo-link": "^1.2.11", diff --git a/spec/javascripts/cycle_analytics/banner_spec.js b/spec/frontend/cycle_analytics/banner_spec.js index 06fbaa68ffc..f0b8cb18a90 100644 --- a/spec/javascripts/cycle_analytics/banner_spec.js +++ b/spec/frontend/cycle_analytics/banner_spec.js @@ -1,5 +1,5 @@ import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; +import mountComponent from 'helpers/vue_mount_component_helper'; import banner from '~/cycle_analytics/components/banner.vue'; describe('Cycle analytics banner', () => { @@ -36,7 +36,7 @@ describe('Cycle analytics banner', () => { }); it('should emit an event when close button is clicked', () => { - spyOn(vm, '$emit'); + jest.spyOn(vm, '$emit').mockImplementation(() => {}); vm.$el.querySelector('.js-ca-dismiss-button').click(); diff --git a/spec/javascripts/cycle_analytics/total_time_component_spec.js b/spec/frontend/cycle_analytics/total_time_component_spec.js index 0269fc1b002..0f7f2628aca 100644 --- a/spec/javascripts/cycle_analytics/total_time_component_spec.js +++ b/spec/frontend/cycle_analytics/total_time_component_spec.js @@ -1,5 +1,5 @@ import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; +import mountComponent from 'helpers/vue_mount_component_helper'; import component from '~/cycle_analytics/components/total_time_component.vue'; describe('Total time component', () => { diff --git a/spec/frontend/diffs/components/diff_file_header_spec.js b/spec/frontend/diffs/components/diff_file_header_spec.js index e0b7e0bc0f3..8e6a5576015 100644 --- a/spec/frontend/diffs/components/diff_file_header_spec.js +++ b/spec/frontend/diffs/components/diff_file_header_spec.js @@ -61,6 +61,7 @@ describe('DiffFileHeader component', () => { const findTitleLink = () => wrapper.find({ ref: 'titleWrapper' }); const findExpandButton = () => wrapper.find({ ref: 'expandDiffToFullFileButton' }); const findFileActions = () => wrapper.find('.file-actions'); + const findActiveHeader = () => wrapper.find('.is-active'); const findModeChangedLine = () => wrapper.find({ ref: 'fileMode' }); const findLfsLabel = () => wrapper.find('.label-lfs'); const findToggleDiscussionsButton = () => wrapper.find({ ref: 'toggleDiscussionsButton' }); @@ -143,6 +144,11 @@ describe('DiffFileHeader component', () => { expect(wrapper.find(ClipboardButton).exists()).toBe(true); }); + it('contains a active header class if this is the active file header', () => { + createComponent({ isActive: true }); + expect(findActiveHeader().exists()).toBe(true); + }); + describe('for submodule', () => { const submoduleDiffFile = { ...diffFile, diff --git a/spec/frontend/vue_shared/components/file_row_spec.js b/spec/frontend/vue_shared/components/file_row_spec.js index b3ced84ddb5..75d1ce9cc5b 100644 --- a/spec/frontend/vue_shared/components/file_row_spec.js +++ b/spec/frontend/vue_shared/components/file_row_spec.js @@ -72,6 +72,19 @@ describe('File row component', () => { }); }); + it('is marked as viewed if clicked', () => { + createComponent({ + file: { + ...file(), + type: 'blob', + fileHash: '#123456789', + }, + level: 0, + viewedFiles: ['#123456789'], + }); + expect(wrapper.classes()).toContain('is-viewed'); + }); + it('indents row based on level', () => { createComponent({ file: file('t4'), diff --git a/spec/lib/gitlab/http_spec.rb b/spec/lib/gitlab/http_spec.rb index 192816ad057..85cfc8e2852 100644 --- a/spec/lib/gitlab/http_spec.rb +++ b/spec/lib/gitlab/http_spec.rb @@ -100,4 +100,127 @@ describe Gitlab::HTTP do expect { described_class.head('http://example.org') }.to raise_error(Gitlab::HTTP::RedirectionTooDeep) end end + + describe '.try_get' do + let(:path) { 'http://example.org' } + + let(:extra_log_info_proc) do + proc do |error, url, options| + { klass: error.class, url: url, options: options } + end + end + + let(:request_options) do + { + verify: false, + basic_auth: { username: 'user', password: 'pass' } + } + end + + described_class::HTTP_ERRORS.each do |exception_class| + context "with #{exception_class}" do + let(:klass) { exception_class } + + context 'with path' do + before do + expect(described_class).to receive(:get) + .with(path, {}) + .and_raise(klass) + end + + it 'handles requests without extra_log_info' do + expect(Gitlab::ErrorTracking) + .to receive(:log_exception) + .with(instance_of(klass), {}) + + expect(described_class.try_get(path)).to be_nil + end + + it 'handles requests with extra_log_info as hash' do + expect(Gitlab::ErrorTracking) + .to receive(:log_exception) + .with(instance_of(klass), { a: :b }) + + expect(described_class.try_get(path, extra_log_info: { a: :b })).to be_nil + end + + it 'handles requests with extra_log_info as proc' do + expect(Gitlab::ErrorTracking) + .to receive(:log_exception) + .with(instance_of(klass), { url: path, klass: klass, options: {} }) + + expect(described_class.try_get(path, extra_log_info: extra_log_info_proc)).to be_nil + end + end + + context 'with path and options' do + before do + expect(described_class).to receive(:get) + .with(path, request_options) + .and_raise(klass) + end + + it 'handles requests without extra_log_info' do + expect(Gitlab::ErrorTracking) + .to receive(:log_exception) + .with(instance_of(klass), {}) + + expect(described_class.try_get(path, request_options)).to be_nil + end + + it 'handles requests with extra_log_info as hash' do + expect(Gitlab::ErrorTracking) + .to receive(:log_exception) + .with(instance_of(klass), { a: :b }) + + expect(described_class.try_get(path, **request_options, extra_log_info: { a: :b })).to be_nil + end + + it 'handles requests with extra_log_info as proc' do + expect(Gitlab::ErrorTracking) + .to receive(:log_exception) + .with(instance_of(klass), { klass: klass, url: path, options: request_options }) + + expect(described_class.try_get(path, **request_options, extra_log_info: extra_log_info_proc)).to be_nil + end + end + + context 'with path, options, and block' do + let(:block) do + proc {} + end + + before do + expect(described_class).to receive(:get) + .with(path, request_options, &block) + .and_raise(klass) + end + + it 'handles requests without extra_log_info' do + expect(Gitlab::ErrorTracking) + .to receive(:log_exception) + .with(instance_of(klass), {}) + + expect(described_class.try_get(path, request_options, &block)).to be_nil + end + + it 'handles requests with extra_log_info as hash' do + expect(Gitlab::ErrorTracking) + .to receive(:log_exception) + .with(instance_of(klass), { a: :b }) + + expect(described_class.try_get(path, **request_options, extra_log_info: { a: :b }, &block)).to be_nil + end + + it 'handles requests with extra_log_info as proc' do + expect(Gitlab::ErrorTracking) + .to receive(:log_exception) + .with(instance_of(klass), { klass: klass, url: path, options: request_options }) + + expect(described_class.try_get(path, **request_options, extra_log_info: extra_log_info_proc, &block)).to be_nil + end + end + end + end + end end diff --git a/spec/models/project_services/teamcity_service_spec.rb b/spec/models/project_services/teamcity_service_spec.rb index 3d875bc49e7..0dd77b68588 100644 --- a/spec/models/project_services/teamcity_service_spec.rb +++ b/spec/models/project_services/teamcity_service_spec.rb @@ -7,6 +7,7 @@ describe TeamcityService, :use_clean_rails_memory_store_caching do include StubRequests let(:teamcity_url) { 'http://gitlab.com/teamcity' } + let(:teamcity_full_url) { 'http://gitlab.com/teamcity/httpAuth/app/rest/builds/branch:unspecified:any,revision:123' } let(:project) { create(:project) } subject(:service) do @@ -165,6 +166,16 @@ describe TeamcityService, :use_clean_rails_memory_store_caching do is_expected.to eq('http://gitlab.com/teamcity/viewLog.html?buildId=666&buildTypeId=foo') end end + + it 'returns the teamcity_url when teamcity is unreachable' do + stub_full_request(teamcity_full_url).to_raise(Errno::ECONNREFUSED) + + expect(Gitlab::ErrorTracking) + .to receive(:log_exception) + .with(instance_of(Errno::ECONNREFUSED), project_id: project.id) + + is_expected.to eq(teamcity_url) + end end context 'commit_status' do @@ -205,6 +216,16 @@ describe TeamcityService, :use_clean_rails_memory_store_caching do is_expected.to eq(:error) end + + it 'sets commit status to :error when teamcity is unreachable' do + stub_full_request(teamcity_full_url).to_raise(Errno::ECONNREFUSED) + + expect(Gitlab::ErrorTracking) + .to receive(:log_exception) + .with(instance_of(Errno::ECONNREFUSED), project_id: project.id) + + is_expected.to eq(:error) + end end end @@ -300,7 +321,6 @@ describe TeamcityService, :use_clean_rails_memory_store_caching do end def stub_request(status: 200, body: nil, build_status: 'success') - teamcity_full_url = 'http://gitlab.com/teamcity/httpAuth/app/rest/builds/branch:unspecified:any,revision:123' auth = %w(mic password) body ||= %Q({"build":{"status":"#{build_status}","id":"666"}}) diff --git a/spec/services/ci/create_cross_project_pipeline_service_spec.rb b/spec/services/ci/create_cross_project_pipeline_service_spec.rb index 99c44c3aa17..a411244e57f 100644 --- a/spec/services/ci/create_cross_project_pipeline_service_spec.rb +++ b/spec/services/ci/create_cross_project_pipeline_service_spec.rb @@ -215,7 +215,7 @@ describe Ci::CreateCrossProjectPipelineService, '#execute' do pipeline = service.execute(bridge) pipeline.reload - expect(pipeline.builds.map(&:name)).to eq %w[rspec echo] + expect(pipeline.builds.map(&:name)).to match_array(%w[rspec echo]) expect(pipeline.user).to eq bridge.user expect(pipeline.project).to eq bridge.project expect(bridge.sourced_pipelines.first.pipeline).to eq pipeline diff --git a/spec/workers/authorized_keys_worker_spec.rb b/spec/workers/authorized_keys_worker_spec.rb index 2aaa6fb2ddf..4f1dde0bfc0 100644 --- a/spec/workers/authorized_keys_worker_spec.rb +++ b/spec/workers/authorized_keys_worker_spec.rb @@ -17,7 +17,7 @@ describe AuthorizedKeysWorker do expect(instance).to receive(:add_key).with('foo', 'bar') end - worker.perform(:add_key, 'foo', 'bar') + worker.perform('add_key', 'foo', 'bar') end end @@ -27,15 +27,17 @@ describe AuthorizedKeysWorker do expect(instance).to receive(:remove_key).with('foo', 'bar') end - worker.perform(:remove_key, 'foo', 'bar') + worker.perform('remove_key', 'foo', 'bar') end end describe 'all other commands' do - it 'does nothing' do + it 'raises an error' do expect(Gitlab::AuthorizedKeys).not_to receive(:new) - worker.perform(:foo, 'bar', 'baz') + expect do + worker.perform('foo', 'bar', 'baz') + end.to raise_error('Unknown action: "foo"') end end end @@ -48,7 +50,7 @@ describe AuthorizedKeysWorker do it 'does nothing' do expect(Gitlab::AuthorizedKeys).not_to receive(:new) - worker.perform(:add_key, 'foo', 'bar') + worker.perform('add_key', 'foo', 'bar') end end end diff --git a/spec/workers/gitlab_shell_worker_spec.rb b/spec/workers/gitlab_shell_worker_spec.rb index f5884e5e8f8..0e63f48d3e8 100644 --- a/spec/workers/gitlab_shell_worker_spec.rb +++ b/spec/workers/gitlab_shell_worker_spec.rb @@ -12,7 +12,7 @@ describe GitlabShellWorker do expect(instance).to receive(:add_key).with('foo', 'bar') end - worker.perform(:add_key, 'foo', 'bar') + worker.perform('add_key', 'foo', 'bar') end end @@ -22,7 +22,7 @@ describe GitlabShellWorker do expect(instance).to receive(:remove_key).with('foo', 'bar') end - worker.perform(:remove_key, 'foo', 'bar') + worker.perform('remove_key', 'foo', 'bar') end end @@ -32,7 +32,7 @@ describe GitlabShellWorker do expect(instance).to receive(:foo).with('bar', 'baz') end - worker.perform(:foo, 'bar', 'baz') + worker.perform('foo', 'bar', 'baz') end end end diff --git a/yarn.lock b/yarn.lock index 7b3a0c5042f..8fc3c01afd7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1036,10 +1036,10 @@ "@sentry/types" "5.10.0" tslib "^1.9.3" -"@sourcegraph/code-host-integration@0.0.31": - version "0.0.31" - resolved "https://registry.yarnpkg.com/@sourcegraph/code-host-integration/-/code-host-integration-0.0.31.tgz#c4d6c7adaaf937e4b8a143c206020e110ba73e25" - integrity sha512-b0WQ1CKlEx9S+IHRs1YNRO7CcwW06ulQU6D+W9cQlfjJu+qQVTAvkyv1xjySkfrCNK8IcfVd8WZzWIhP16VVfw== +"@sourcegraph/code-host-integration@0.0.33": + version "0.0.33" + resolved "https://registry.yarnpkg.com/@sourcegraph/code-host-integration/-/code-host-integration-0.0.33.tgz#133f11535be0cc937fbadc6a6951ee9fd21fbe1d" + integrity sha512-J49ljHsSIe8KD5+ke9C3ugGO9T6R2M96miiGEZFRHJQ7FXyKi/zP5N4BFVweHjE+b15BLSicoaAnnyg4nhIBIw== "@types/anymatch@*": version "1.3.0" |