diff options
40 files changed, 496 insertions, 43 deletions
diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION index 3c40359d3dc..a13e7b9c87e 100644 --- a/GITLAB_SHELL_VERSION +++ b/GITLAB_SHELL_VERSION @@ -1 +1 @@ -9.4.2 +10.0.0 diff --git a/app/assets/javascripts/jobs/components/log/line.vue b/app/assets/javascripts/jobs/components/log/line.vue new file mode 100644 index 00000000000..86d0fcc3b74 --- /dev/null +++ b/app/assets/javascripts/jobs/components/log/line.vue @@ -0,0 +1,28 @@ +<script> +import LineNumber from './line_number.vue'; + +export default { + components: { + LineNumber, + }, + props: { + line: { + type: Object, + required: true, + }, + path: { + type: String, + required: true, + }, + }, +}; +</script> + +<template> + <div class="line"> + <line-number :line-number="line.lineNumber" :path="path" /> + <span v-for="(content, i) in line.content" :key="i" class="line-text" :class="content.style">{{ + content.text + }}</span> + </div> +</template> diff --git a/app/assets/javascripts/jobs/components/log/line_header.vue b/app/assets/javascripts/jobs/components/log/line_header.vue new file mode 100644 index 00000000000..4ec212d2333 --- /dev/null +++ b/app/assets/javascripts/jobs/components/log/line_header.vue @@ -0,0 +1,45 @@ +<script> +import Icon from '~/vue_shared/components/icon.vue'; +import LineNumber from './line_number.vue'; + +export default { + components: { + Icon, + LineNumber, + }, + props: { + line: { + type: Object, + required: true, + }, + isClosed: { + type: Boolean, + required: true, + }, + path: { + type: String, + required: true, + }, + }, + computed: { + iconName() { + return this.isClosed ? 'angle-right' : 'angle-down'; + }, + }, + methods: { + handleOnClick() { + this.$emit('toggleLine'); + }, + }, +}; +</script> + +<template> + <div class="line collapsible-line" role="button" @click="handleOnClick"> + <icon :name="iconName" class="arrow" /> + <line-number :line-number="line.lineNumber" :path="path" /> + <span v-for="(content, i) in line.content" :key="i" class="line-text" :class="content.style">{{ + content.text + }}</span> + </div> +</template> diff --git a/app/assets/javascripts/jobs/components/log/line_number.vue b/app/assets/javascripts/jobs/components/log/line_number.vue new file mode 100644 index 00000000000..e06836e2e97 --- /dev/null +++ b/app/assets/javascripts/jobs/components/log/line_number.vue @@ -0,0 +1,52 @@ +<script> +import { GlLink } from '@gitlab/ui'; + +export default { + components: { + GlLink, + }, + props: { + lineNumber: { + type: Number, + required: true, + }, + path: { + type: String, + required: true, + }, + }, + computed: { + /** + * Builds the url for each line number + * + * @returns {String} + */ + buildLineNumber() { + return `${this.path}#${this.lineNumberId}`; + }, + /** + * Array indexes start with 0, so we add 1 + * to create the line number + * + * @returns {Number} the line number + */ + parsedLineNumber() { + return this.lineNumber + 1; + }, + + /** + * Creates the anchor for each link + * + * @returns {String} + */ + lineNumberId() { + return `L${this.parsedLineNumber}`; + }, + }, +}; +</script> +<template> + <gl-link :id="lineNumberId" class="line-number" :href="buildLineNumber">{{ + parsedLineNumber + }}</gl-link> +</template> diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb index 2402fa8e38f..4db2b7a74e5 100644 --- a/app/models/merge_request_diff.rb +++ b/app/models/merge_request_diff.rb @@ -197,7 +197,7 @@ class MergeRequestDiff < ApplicationRecord def lines_count strong_memoize(:lines_count) do - diffs.diff_files.sum(&:line_count) + raw_diffs(limits: false).line_count end end @@ -222,6 +222,10 @@ class MergeRequestDiff < ApplicationRecord commits.last end + def last_commit + commits.first + end + def base_commit return unless base_commit_sha diff --git a/app/services/audit_event_service.rb b/app/services/audit_event_service.rb index 73f3408a240..22ade0b0658 100644 --- a/app/services/audit_event_service.rb +++ b/app/services/audit_event_service.rb @@ -21,6 +21,10 @@ class AuditEventService log_security_event_to_database end + def log_security_event_to_file + file_logger.info(base_payload.merge(formatted_details)) + end + private def base_payload @@ -39,10 +43,6 @@ class AuditEventService @details.merge(@details.slice(:from, :to).transform_values(&:to_s)) end - def log_security_event_to_file - file_logger.info(base_payload.merge(formatted_details)) - end - def log_security_event_to_database SecurityEvent.create(base_payload.merge(details: @details)) end diff --git a/app/services/auth/container_registry_authentication_service.rb b/app/services/auth/container_registry_authentication_service.rb index 9e7319c1d9b..9c210f3a1f5 100644 --- a/app/services/auth/container_registry_authentication_service.rb +++ b/app/services/auth/container_registry_authentication_service.rb @@ -2,7 +2,7 @@ module Auth class ContainerRegistryAuthenticationService < BaseService - AUDIENCE = 'container_registry'.freeze + AUDIENCE = 'container_registry' def execute(authentication_abilities:) @authentication_abilities = authentication_abilities diff --git a/app/services/auto_merge_service.rb b/app/services/auto_merge_service.rb index 95bf2db2018..053c6d71fbb 100644 --- a/app/services/auto_merge_service.rb +++ b/app/services/auto_merge_service.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class AutoMergeService < BaseService - STRATEGY_MERGE_WHEN_PIPELINE_SUCCEEDS = 'merge_when_pipeline_succeeds'.freeze + STRATEGY_MERGE_WHEN_PIPELINE_SUCCEEDS = 'merge_when_pipeline_succeeds' STRATEGIES = [STRATEGY_MERGE_WHEN_PIPELINE_SUCCEEDS].freeze class << self diff --git a/app/services/merge_requests/rebase_service.rb b/app/services/merge_requests/rebase_service.rb index 27c16ba1777..4d36dd4feae 100644 --- a/app/services/merge_requests/rebase_service.rb +++ b/app/services/merge_requests/rebase_service.rb @@ -2,7 +2,7 @@ module MergeRequests class RebaseService < MergeRequests::WorkingCopyBaseService - REBASE_ERROR = 'Rebase failed. Please rebase locally'.freeze + REBASE_ERROR = 'Rebase failed. Please rebase locally' def execute(merge_request) @merge_request = merge_request diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb index 5893b8eedff..108c4a79cde 100644 --- a/app/services/projects/destroy_service.rb +++ b/app/services/projects/destroy_service.rb @@ -6,7 +6,7 @@ module Projects DestroyError = Class.new(StandardError) - DELETED_FLAG = '+deleted'.freeze + DELETED_FLAG = '+deleted' REPO_REMOVAL_DELAY = 5.minutes.to_i def async_execute diff --git a/app/services/projects/lfs_pointers/lfs_download_link_list_service.rb b/app/services/projects/lfs_pointers/lfs_download_link_list_service.rb index 9b72480d18b..5ef7e03ea02 100644 --- a/app/services/projects/lfs_pointers/lfs_download_link_list_service.rb +++ b/app/services/projects/lfs_pointers/lfs_download_link_list_service.rb @@ -5,7 +5,7 @@ module Projects module LfsPointers class LfsDownloadLinkListService < BaseService - DOWNLOAD_ACTION = 'download'.freeze + DOWNLOAD_ACTION = 'download' DownloadLinksError = Class.new(StandardError) DownloadLinkNotFound = Class.new(StandardError) diff --git a/app/services/projects/lfs_pointers/lfs_list_service.rb b/app/services/projects/lfs_pointers/lfs_list_service.rb index 22160017f4f..a07fa93a279 100644 --- a/app/services/projects/lfs_pointers/lfs_list_service.rb +++ b/app/services/projects/lfs_pointers/lfs_list_service.rb @@ -4,7 +4,7 @@ module Projects module LfsPointers class LfsListService < BaseService - REV = 'HEAD'.freeze + REV = 'HEAD' # Retrieve all lfs blob pointers and returns a hash # with the structure { lfs_file_oid => lfs_file_size } diff --git a/app/services/projects/lfs_pointers/lfs_object_download_list_service.rb b/app/services/projects/lfs_pointers/lfs_object_download_list_service.rb index 5ba0f50f2ff..4224b56c42c 100644 --- a/app/services/projects/lfs_pointers/lfs_object_download_list_service.rb +++ b/app/services/projects/lfs_pointers/lfs_object_download_list_service.rb @@ -8,9 +8,9 @@ module Projects class LfsObjectDownloadListService < BaseService include Gitlab::Utils::StrongMemoize - HEAD_REV = 'HEAD'.freeze + HEAD_REV = 'HEAD' LFS_ENDPOINT_PATTERN = /^\t?url\s*=\s*(.+)$/.freeze - LFS_BATCH_API_ENDPOINT = '/info/lfs/objects/batch'.freeze + LFS_BATCH_API_ENDPOINT = '/info/lfs/objects/batch' LfsObjectDownloadListError = Class.new(StandardError) diff --git a/app/services/projects/open_issues_count_service.rb b/app/services/projects/open_issues_count_service.rb index ee9884e9042..bc8f7f342f7 100644 --- a/app/services/projects/open_issues_count_service.rb +++ b/app/services/projects/open_issues_count_service.rb @@ -7,8 +7,8 @@ module Projects include Gitlab::Utils::StrongMemoize # Cache keys used to store issues count - PUBLIC_COUNT_KEY = 'public_open_issues_count'.freeze - TOTAL_COUNT_KEY = 'total_open_issues_count'.freeze + PUBLIC_COUNT_KEY = 'public_open_issues_count' + TOTAL_COUNT_KEY = 'total_open_issues_count' def initialize(project, user = nil) @user = user diff --git a/app/services/projects/update_pages_service.rb b/app/services/projects/update_pages_service.rb index 5caeb4cfa5f..fa7a4f0ed82 100644 --- a/app/services/projects/update_pages_service.rb +++ b/app/services/projects/update_pages_service.rb @@ -7,11 +7,11 @@ module Projects BLOCK_SIZE = 32.kilobytes MAX_SIZE = 1.terabyte - PUBLIC_DIR = 'public'.freeze + PUBLIC_DIR = 'public' # this has to be invalid group name, # as it shares the namespace with groups - TMP_EXTRACT_PATH = '@pages.tmp'.freeze + TMP_EXTRACT_PATH = '@pages.tmp' attr_reader :build diff --git a/app/services/submit_usage_ping_service.rb b/app/services/submit_usage_ping_service.rb index 4f10f220298..415a02ab337 100644 --- a/app/services/submit_usage_ping_service.rb +++ b/app/services/submit_usage_ping_service.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class SubmitUsagePingService - URL = 'https://version.gitlab.com/usage_data'.freeze + URL = 'https://version.gitlab.com/usage_data' METRICS = %w[leader_issues instance_issues percentage_issues leader_notes instance_notes percentage_notes leader_milestones instance_milestones percentage_milestones diff --git a/app/services/wikis/create_attachment_service.rb b/app/services/wikis/create_attachment_service.rb index df31ad7c8ea..6ef6cbc3c12 100644 --- a/app/services/wikis/create_attachment_service.rb +++ b/app/services/wikis/create_attachment_service.rb @@ -2,7 +2,7 @@ module Wikis class CreateAttachmentService < Files::CreateService - ATTACHMENT_PATH = 'uploads'.freeze + ATTACHMENT_PATH = 'uploads' MAX_FILENAME_LENGTH = 255 delegate :wiki, to: :project diff --git a/changelogs/unreleased/66454-base-components.yml b/changelogs/unreleased/66454-base-components.yml new file mode 100644 index 00000000000..7a40a66f122 --- /dev/null +++ b/changelogs/unreleased/66454-base-components.yml @@ -0,0 +1,5 @@ +--- +title: Creates base components for the new job log +merge_request: +author: +type: added diff --git a/changelogs/unreleased/persist-needs-error.yml b/changelogs/unreleased/persist-needs-error.yml new file mode 100644 index 00000000000..96aaa4d11a3 --- /dev/null +++ b/changelogs/unreleased/persist-needs-error.yml @@ -0,0 +1,5 @@ +--- +title: Persist `needs:` validation as config error +merge_request: +author: +type: fixed diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 6dcaefc05d5..e3693f612e3 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -158,6 +158,7 @@ production: &base # The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to. # The placeholder can be omitted but if present, it must appear in the "user" part of the address (before the `@`). + # Please be aware that a placeholder is required for the Service Desk feature to work. address: "gitlab-incoming+%{key}@gmail.com" # Email account username diff --git a/config/routes.rb b/config/routes.rb index c333550f758..02a405a91f8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -67,7 +67,7 @@ Rails.application.routes.draw do get 'health_check(/:checks)' => 'health_check#index', as: :health_check scope path: '-' do - # '/-/health' implemented by BasicHealthMiddleware + # '/-/health' implemented by BasicHealthCheck middleware get 'liveness' => 'health#liveness' get 'readiness' => 'health#readiness' resources :metrics, only: [:index] diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml index ea165508d29..7edec576f9a 100644 --- a/config/sidekiq_queues.yml +++ b/config/sidekiq_queues.yml @@ -102,6 +102,7 @@ - [create_github_webhook, 2] - [geo, 1] - [repository_update_mirror, 1] + - [repository_push_audit_event, 1] - [new_epic, 2] - [project_import_schedule, 1] - [project_update_repository_storage, 1] diff --git a/doc/administration/index.md b/doc/administration/index.md index 650cb10a64a..711eebcd61e 100644 --- a/doc/administration/index.md +++ b/doc/administration/index.md @@ -139,6 +139,7 @@ Learn how to install, configure, update, and maintain your GitLab instance. - [Repository checks](repository_checks.md): Periodic Git repository checks. - [Repository storage paths](repository_storage_paths.md): Manage the paths used to store repositories. +- [Repository storage types](repository_storage_types.md): Information about the different repository storage types. - [Repository storage rake tasks](raketasks/storage.md): A collection of rake tasks to list and migrate existing projects and attachments associated with it from Legacy storage to Hashed storage. - [Limit repository size](../user/admin_area/settings/account_and_limit_settings.md): Set a hard limit for your repositories' size. **(STARTER ONLY)** diff --git a/doc/api/issues.md b/doc/api/issues.md index 7498d2d840b..a89a6e7c5cc 100644 --- a/doc/api/issues.md +++ b/doc/api/issues.md @@ -573,6 +573,18 @@ the `weight` parameter: } ``` +Users on GitLab [Ultimate](https://about.gitlab.com/pricing/) will additionally see +the `epic_iid` property: + +```json +{ + "project_id" : 4, + "description" : "Omnis vero earum sunt corporis dolor et placeat.", + "epic_iid" : 42, + ... +} +``` + **Note**: `assignee` column is deprecated, now we show it as a single-sized array `assignees` to conform to the GitLab EE API. **Note**: The `closed_by` attribute was [introduced in GitLab 10.6][ce-17042]. This value will only be present for issues which were closed after GitLab 10.6 and when the user account that closed the issue still exists. diff --git a/doc/development/background_migrations.md b/doc/development/background_migrations.md index 3fd95537eaa..a456bbc781f 100644 --- a/doc/development/background_migrations.md +++ b/doc/development/background_migrations.md @@ -61,8 +61,8 @@ migration classes must be defined in the namespace ## Scheduling -Scheduling a migration can be done in either a regular migration or a -post-deployment migration. To do so, simply use the following code while +Scheduling a background migration should be done in a post-deployment migration. +To do so, simply use the following code while replacing the class name and arguments with whatever values are necessary for your migration: @@ -283,10 +283,13 @@ the `services.properties` column. ## Testing -It is required to write tests for background migrations' scheduling migration -(either a regular migration or a post deployment migration), background -migration itself and a cleanup migration. You can use the `:migration` RSpec -tag when testing a regular / post deployment migration. +It is required to write tests for: + +- The background migrations' scheduling migration. +- The background migration itself. +- A cleanup migration. + +You can use the `:migration` RSpec tag when testing the migrations. See [README][migrations-readme]. When you do that, keep in mind that `before` and `after` RSpec hooks are going diff --git a/doc/user/application_security/dast/index.md b/doc/user/application_security/dast/index.md index fa84f995e58..86c6f8c167c 100644 --- a/doc/user/application_security/dast/index.md +++ b/doc/user/application_security/dast/index.md @@ -84,6 +84,8 @@ There are two ways to define the URL to be scanned by DAST: - Set the `DAST_WEBSITE` [variable](../../../ci/yaml/README.md#variables). - Add it in an `environment_url.txt` file at the root of your project. +If both values are set, the `DAST_WEBSITE` value will take precedence. + The included template will create a `dast` job in your CI/CD pipeline and scan your project's source code for possible vulnerabilities. @@ -134,7 +136,7 @@ variables: The DAST settings can be changed through environment variables by using the [`variables`](../../../ci/yaml/README.md#variables) parameter in `.gitlab-ci.yml`. -These variables are documented in the [DAST README](https://gitlab.com/gitlab-org/security-products/dast#settings). +These variables are documented in [available variables](#available-variables). For example: diff --git a/lib/api/entities.rb b/lib/api/entities.rb index ba58e125568..f7cd6d35854 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -978,7 +978,9 @@ module API expose :created_at def todo_target_class(target_type) - ::API::Entities.const_get(target_type) + # false as second argument prevents looking up in module hierarchy + # see also https://gitlab.com/gitlab-org/gitlab-ce/issues/59719 + ::API::Entities.const_get(target_type, false) end end @@ -1731,6 +1733,7 @@ API::Entities.prepend_if_ee('EE::API::Entities::Entities') ::API::Entities::Group.prepend_if_ee('EE::API::Entities::Group', with_descendants: true) ::API::Entities::GroupDetail.prepend_if_ee('EE::API::Entities::GroupDetail') ::API::Entities::IssueBasic.prepend_if_ee('EE::API::Entities::IssueBasic', with_descendants: true) +::API::Entities::Issue.prepend_if_ee('EE::API::Entities::Issue') ::API::Entities::List.prepend_if_ee('EE::API::Entities::List') ::API::Entities::MergeRequestBasic.prepend_if_ee('EE::API::Entities::MergeRequestBasic', with_descendants: true) ::API::Entities::Namespace.prepend_if_ee('EE::API::Entities::Namespace') diff --git a/lib/gitlab/ci/pipeline/chain/helpers.rb b/lib/gitlab/ci/pipeline/chain/helpers.rb index 6bb3a75291b..8ccb1066575 100644 --- a/lib/gitlab/ci/pipeline/chain/helpers.rb +++ b/lib/gitlab/ci/pipeline/chain/helpers.rb @@ -5,7 +5,12 @@ module Gitlab module Pipeline module Chain module Helpers - def error(message) + def error(message, config_error: false) + if config_error && command.save_incompleted + pipeline.yaml_errors = message + pipeline.drop!(:config_error) + end + pipeline.errors.add(:base, message) end end diff --git a/lib/gitlab/ci/pipeline/chain/populate.rb b/lib/gitlab/ci/pipeline/chain/populate.rb index 65029f5ce7f..13eca5a9d28 100644 --- a/lib/gitlab/ci/pipeline/chain/populate.rb +++ b/lib/gitlab/ci/pipeline/chain/populate.rb @@ -26,7 +26,7 @@ module Gitlab # Gather all runtime build/stage errors # if seeds_errors = pipeline.stage_seeds.flat_map(&:errors).compact.presence - return error(seeds_errors.join("\n")) + return error(seeds_errors.join("\n"), config_error: true) end ## diff --git a/lib/gitlab/git/diff_collection.rb b/lib/gitlab/git/diff_collection.rb index 5c70cb6c66c..cb9154cb1e8 100644 --- a/lib/gitlab/git/diff_collection.rb +++ b/lib/gitlab/git/diff_collection.rb @@ -81,6 +81,12 @@ module Gitlab end end + def line_count + populate! + + @line_count + end + def decorate! collection = each_with_index do |element, i| @array[i] = yield(element) diff --git a/package.json b/package.json index 782bb3a96a7..247993626a6 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "@babel/plugin-syntax-import-meta": "^7.2.0", "@babel/preset-env": "^7.5.5", "@gitlab/svgs": "^1.71.0", - "@gitlab/ui": "5.20.2", + "@gitlab/ui": "5.21.0", "@gitlab/visual-review-tools": "1.0.1", "apollo-cache-inmemory": "^1.5.1", "apollo-client": "^2.5.1", diff --git a/spec/javascripts/jobs/components/log/line_header_spec.js b/spec/javascripts/jobs/components/log/line_header_spec.js new file mode 100644 index 00000000000..4efd412a6cd --- /dev/null +++ b/spec/javascripts/jobs/components/log/line_header_spec.js @@ -0,0 +1,84 @@ +import { mount } from '@vue/test-utils'; +import LineHeader from '~/jobs/components/log/line_header.vue'; +import LineNumber from '~/jobs/components/log/line_number.vue'; + +describe('Job Log Header Line', () => { + let wrapper; + + const data = { + line: { + content: [ + { + text: 'Running with gitlab-runner 12.1.0 (de7731dd)', + style: 'term-fg-l-green', + }, + ], + lineNumber: 0, + }, + isClosed: true, + path: '/jashkenas/underscore/-/jobs/335', + }; + + const createComponent = (props = {}) => { + wrapper = mount(LineHeader, { + sync: false, + propsData: { + ...props, + }, + }); + }; + + afterEach(() => { + wrapper.destroy(); + }); + + describe('line', () => { + beforeEach(() => { + createComponent(data); + }); + + it('renders the line number component', () => { + expect(wrapper.contains(LineNumber)).toBe(true); + }); + + it('renders a span the provided text', () => { + expect(wrapper.find('span').text()).toBe(data.line.content[0].text); + }); + + it('renders the provided style as a class attribute', () => { + expect(wrapper.find('span').classes()).toContain(data.line.content[0].style); + }); + }); + + describe('when isCloses is true', () => { + beforeEach(() => { + createComponent({ ...data, isClosed: true }); + }); + + it('sets icon name to be angle-right', () => { + expect(wrapper.vm.iconName).toEqual('angle-right'); + }); + }); + + describe('when isCloses is false', () => { + beforeEach(() => { + createComponent({ ...data, isClosed: false }); + }); + + it('sets icon name to be angle-down', () => { + expect(wrapper.vm.iconName).toEqual('angle-down'); + }); + }); + + describe('on click', () => { + beforeEach(() => { + createComponent(data); + }); + + it('emits toggleLine event', () => { + wrapper.trigger('click'); + + expect(wrapper.emitted().toggleLine.length).toBe(1); + }); + }); +}); diff --git a/spec/javascripts/jobs/components/log/line_number_spec.js b/spec/javascripts/jobs/components/log/line_number_spec.js new file mode 100644 index 00000000000..fcf2edf9159 --- /dev/null +++ b/spec/javascripts/jobs/components/log/line_number_spec.js @@ -0,0 +1,40 @@ +import { shallowMount } from '@vue/test-utils'; +import LineNumber from '~/jobs/components/log/line_number.vue'; + +describe('Job Log Line Number', () => { + let wrapper; + + const data = { + lineNumber: 0, + path: '/jashkenas/underscore/-/jobs/335', + }; + + const createComponent = (props = {}) => { + wrapper = shallowMount(LineNumber, { + sync: false, + propsData: { + ...props, + }, + }); + }; + + beforeEach(() => { + createComponent(data); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('renders incremented lineNunber by 1', () => { + expect(wrapper.text()).toBe('1'); + }); + + it('renders link with lineNumber as an ID', () => { + expect(wrapper.attributes().id).toBe('L1'); + }); + + it('links to the provided path with line number as anchor', () => { + expect(wrapper.attributes().href).toBe(`${data.path}#L1`); + }); +}); diff --git a/spec/javascripts/jobs/components/log/line_spec.js b/spec/javascripts/jobs/components/log/line_spec.js new file mode 100644 index 00000000000..ea593e3c39a --- /dev/null +++ b/spec/javascripts/jobs/components/log/line_spec.js @@ -0,0 +1,49 @@ +import { shallowMount } from '@vue/test-utils'; +import Line from '~/jobs/components/log/line.vue'; +import LineNumber from '~/jobs/components/log/line_number.vue'; + +describe('Job Log Line', () => { + let wrapper; + + const data = { + line: { + content: [ + { + text: 'Running with gitlab-runner 12.1.0 (de7731dd)', + style: 'term-fg-l-green', + }, + ], + lineNumber: 0, + }, + path: '/jashkenas/underscore/-/jobs/335', + }; + + const createComponent = (props = {}) => { + wrapper = shallowMount(Line, { + sync: false, + propsData: { + ...props, + }, + }); + }; + + beforeEach(() => { + createComponent(data); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('renders the line number component', () => { + expect(wrapper.contains(LineNumber)).toBe(true); + }); + + it('renders a span the provided text', () => { + expect(wrapper.find('span').text()).toBe(data.line.content[0].text); + }); + + it('renders the provided style as a class attribute', () => { + expect(wrapper.find('span').classes()).toContain(data.line.content[0].style); + }); +}); diff --git a/spec/lib/gitlab/git/diff_collection_spec.rb b/spec/lib/gitlab/git/diff_collection_spec.rb index 81658874be7..be6ab0c1200 100644 --- a/spec/lib/gitlab/git/diff_collection_spec.rb +++ b/spec/lib/gitlab/git/diff_collection_spec.rb @@ -74,6 +74,11 @@ describe Gitlab::Git::DiffCollection, :seed_helper do end end + describe '#line_count' do + subject { super().line_count } + it { is_expected.to eq file_count * line_count } + end + context 'when limiting is disabled' do let(:limits) { false } @@ -100,6 +105,11 @@ describe Gitlab::Git::DiffCollection, :seed_helper do expect(subject.size).to eq(3) end end + + describe '#line_count' do + subject { super().line_count } + it { is_expected.to eq file_count * line_count } + end end end @@ -120,6 +130,12 @@ describe Gitlab::Git::DiffCollection, :seed_helper do subject { super().real_size } it { is_expected.to eq('0+') } end + + describe '#line_count' do + subject { super().line_count } + it { is_expected.to eq 1000 } + end + it { expect(subject.size).to eq(0) } context 'when limiting is disabled' do @@ -139,6 +155,12 @@ describe Gitlab::Git::DiffCollection, :seed_helper do subject { super().real_size } it { is_expected.to eq('3') } end + + describe '#line_count' do + subject { super().line_count } + it { is_expected.to eq file_count * line_count } + end + it { expect(subject.size).to eq(3) } end end @@ -164,6 +186,12 @@ describe Gitlab::Git::DiffCollection, :seed_helper do subject { super().real_size } it { is_expected.to eq('10+') } end + + describe '#line_count' do + subject { super().line_count } + it { is_expected.to eq 10 } + end + it { expect(subject.size).to eq(10) } context 'when limiting is disabled' do @@ -183,6 +211,12 @@ describe Gitlab::Git::DiffCollection, :seed_helper do subject { super().real_size } it { is_expected.to eq('11') } end + + describe '#line_count' do + subject { super().line_count } + it { is_expected.to eq file_count * line_count } + end + it { expect(subject.size).to eq(11) } end end @@ -204,6 +238,12 @@ describe Gitlab::Git::DiffCollection, :seed_helper do subject { super().real_size } it { is_expected.to eq('3+') } end + + describe '#line_count' do + subject { super().line_count } + it { is_expected.to eq 120 } + end + it { expect(subject.size).to eq(3) } context 'when limiting is disabled' do @@ -223,6 +263,12 @@ describe Gitlab::Git::DiffCollection, :seed_helper do subject { super().real_size } it { is_expected.to eq('11') } end + + describe '#line_count' do + subject { super().line_count } + it { is_expected.to eq file_count * line_count } + end + it { expect(subject.size).to eq(11) } end end @@ -248,6 +294,12 @@ describe Gitlab::Git::DiffCollection, :seed_helper do subject { super().real_size } it { is_expected.to eq('10') } end + + describe '#line_count' do + subject { super().line_count } + it { is_expected.to eq file_count * line_count } + end + it { expect(subject.size).to eq(10) } end end @@ -270,6 +322,12 @@ describe Gitlab::Git::DiffCollection, :seed_helper do subject { super().real_size } it { is_expected.to eq('9+') } end + + describe '#line_count' do + subject { super().line_count } + it { is_expected.to eq file_count * line_count } + end + it { expect(subject.size).to eq(9) } context 'when limiting is disabled' do @@ -289,6 +347,12 @@ describe Gitlab::Git::DiffCollection, :seed_helper do subject { super().real_size } it { is_expected.to eq('10') } end + + describe '#line_count' do + subject { super().line_count } + it { is_expected.to eq file_count * line_count } + end + it { expect(subject.size).to eq(10) } end end @@ -316,6 +380,11 @@ describe Gitlab::Git::DiffCollection, :seed_helper do subject { super().real_size } it { is_expected.to eq('0')} end + + describe '#line_count' do + subject { super().line_count } + it { is_expected.to eq 0 } + end end describe '#each' do diff --git a/spec/models/merge_request/metrics_spec.rb b/spec/models/merge_request/metrics_spec.rb index 49573af0fed..bd97cabc11e 100644 --- a/spec/models/merge_request/metrics_spec.rb +++ b/spec/models/merge_request/metrics_spec.rb @@ -3,8 +3,6 @@ require 'spec_helper' describe MergeRequest::Metrics do - subject { described_class.new } - describe 'associations' do it { is_expected.to belong_to(:merge_request) } it { is_expected.to belong_to(:latest_closed_by).class_name('User') } diff --git a/spec/models/merge_request_diff_spec.rb b/spec/models/merge_request_diff_spec.rb index e7dd7287a75..b86663fd7d9 100644 --- a/spec/models/merge_request_diff_spec.rb +++ b/spec/models/merge_request_diff_spec.rb @@ -400,6 +400,18 @@ describe MergeRequestDiff do end end + describe '#first_commit' do + it 'returns first commit' do + expect(diff_with_commits.first_commit.sha).to eq(diff_with_commits.merge_request_diff_commits.last.sha) + end + end + + describe '#last_commit' do + it 'returns last commit' do + expect(diff_with_commits.last_commit.sha).to eq(diff_with_commits.merge_request_diff_commits.first.sha) + end + end + describe '#commits_by_shas' do let(:commit_shas) { diff_with_commits.commit_shas } @@ -489,7 +501,7 @@ describe MergeRequestDiff do subject { diff_with_commits } it 'returns sum of all changed lines count in diff files' do - expect(subject.lines_count).to eq 109 + expect(subject.lines_count).to eq 189 end end end diff --git a/spec/services/audit_event_service_spec.rb b/spec/services/audit_event_service_spec.rb index e42bff607b2..96df6689bb0 100644 --- a/spec/services/audit_event_service_spec.rb +++ b/spec/services/audit_event_service_spec.rb @@ -47,4 +47,16 @@ describe AuditEventService do expect(details[:target_id]).to eq(1) end end + + describe '#log_security_event_to_file' do + it 'logs security event to file' do + expect(service).to receive(:file_logger).and_return(logger) + expect(logger).to receive(:info).with(author_id: user.id, + entity_type: 'Project', + entity_id: project.id, + action: :destroy) + + service.log_security_event_to_file + end + end end diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb index deb68899309..fad865a4811 100644 --- a/spec/services/ci/create_pipeline_service_spec.rb +++ b/spec/services/ci/create_pipeline_service_spec.rb @@ -1140,10 +1140,26 @@ describe Ci::CreatePipelineService do context 'when pipeline on feature is created' do let(:ref_name) { 'refs/heads/feature' } - it 'does not create a pipeline as test_a depends on build_a' do - expect(pipeline).not_to be_persisted - expect(pipeline.builds).to be_empty - expect(pipeline.errors[:base]).to contain_exactly("test_a: needs 'build_a'") + context 'when save_on_errors is enabled' do + let(:pipeline) { execute_service(save_on_errors: true) } + + it 'does create a pipeline as test_a depends on build_a' do + expect(pipeline).to be_persisted + expect(pipeline.builds).to be_empty + expect(pipeline.yaml_errors).to eq("test_a: needs 'build_a'") + expect(pipeline.errors[:base]).to contain_exactly("test_a: needs 'build_a'") + end + end + + context 'when save_on_errors is disabled' do + let(:pipeline) { execute_service(save_on_errors: false) } + + it 'does not create a pipeline as test_a depends on build_a' do + expect(pipeline).not_to be_persisted + expect(pipeline.builds).to be_empty + expect(pipeline.yaml_errors).to be_nil + expect(pipeline.errors[:base]).to contain_exactly("test_a: needs 'build_a'") + end end end diff --git a/yarn.lock b/yarn.lock index bd8f9014131..d17dae8f907 100644 --- a/yarn.lock +++ b/yarn.lock @@ -996,10 +996,10 @@ resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.71.0.tgz#c8e6e8f500ea91e5cbba4ac08df533fb2e622a00" integrity sha512-kkeNic/FFwaqKnzwio4NE7whBOZ/toRJ8cS0587DBotajAzSYhph5ij4TCY2GTjPa33zIJ5OUr/k90C0Kr71hQ== -"@gitlab/ui@5.20.2": - version "5.20.2" - resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-5.20.2.tgz#a51270d5a521e71059c5fd05f86cfc835f5e28ae" - integrity sha512-TSaD5Cz0YXBTsRtQwsa7LbS2O5h0CL3YkdYmBKrMZkphL76xQaN08ZImkQ5Xl8cD1ZiWN2CsTvoUbF19UP2V1w== +"@gitlab/ui@5.21.0": + version "5.21.0" + resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-5.21.0.tgz#975cf0bca3d16dd080d67ed392b9d24cd64695ac" + integrity sha512-8TMVM+pJXf7omHgKMMZ1FiltuyMOTwfQ3iFgorQzcuhio9u35DJpWi45S2TF7m6CrlpJi7dMX3BsXLbF7ViSUw== dependencies: "@babel/standalone" "^7.0.0" "@gitlab/vue-toasted" "^1.2.1" |