diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-09-14 18:12:56 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-09-14 18:12:56 +0300 |
commit | c014b6b4e5c33180dd5cbff1dd1bb4623d1eca80 (patch) | |
tree | 0aa4dbf0c9236ebd669b26240a18c08aef2cc50e | |
parent | 16daf112d6cfe2c87d8837382a00d88aa8c0ff5c (diff) |
Add latest changes from gitlab-org/gitlab@master
370 files changed, 7555 insertions, 1595 deletions
diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS index bc01f80007c..c57c2965101 100644 --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -11,7 +11,9 @@ docs/CODEOWNERS @clefelhocz1 @timzallmann @cdu1 @whaber @dsatcher @sgoldstein @j ## Allows release tooling to update the Gitaly Version GITALY_SERVER_VERSION @project_278964_bot6 @gitlab-org/maintainers/rails-backend @gitlab-org/delivery -## Excludes documentation files and deprecation/removal announcements from required approval +## Files that are excluded from required approval +/.gitlab/issue_templates/ +/.gitlab/merge_request_templates/ /doc/*.md /doc/**/*.md /doc/**/*.png @@ -332,8 +334,8 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab ^[Documentation Directories] .markdownlint.yml @marcel.amirault @eread @aqualls @dianalogan @kpaizee -/doc/.markdownlint @marcel.amirault @eread @aqualls @dianalogan @kpaizee /doc/ @gl-docsteam +/doc/.markdownlint/ @marcel.amirault @eread @aqualls @dianalogan @kpaizee /doc/.vale/ @marcel.amirault @eread @aqualls @dianalogan @kpaizee ^[Documentation Pages] diff --git a/.rubocop_todo/rails/application_controller.yml b/.rubocop_todo/rails/application_controller.yml deleted file mode 100644 index d53fd3411d3..00000000000 --- a/.rubocop_todo/rails/application_controller.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- -# Cop supports --auto-correct. -Rails/ApplicationController: - Exclude: - - 'app/controllers/acme_challenges_controller.rb' - - 'app/controllers/chaos_controller.rb' - - 'app/controllers/health_controller.rb' - - 'app/controllers/metrics_controller.rb' - - 'ee/app/controllers/oauth/geo_auth_controller.rb' - - 'ee/spec/helpers/ee/integrations_helper_spec.rb' - - 'lib/gitlab/base_doorkeeper_controller.rb' - - 'lib/gitlab/request_forgery_protection.rb' - - 'spec/controllers/concerns/continue_params_spec.rb' @@ -36,8 +36,7 @@ gem 'doorkeeper', '~> 5.5.0.rc2' gem 'doorkeeper-openid_connect', '~> 1.7.5' gem 'rexml', '~> 3.2.5' gem 'ruby-saml', '~> 1.13.0' -gem 'omniauth-rails_csrf_protection' -gem 'omniauth', '~> 2.1.0' +gem 'omniauth', '~> 1.8' gem 'omniauth-auth0', '~> 2.0.0' gem 'omniauth-azure-activedirectory-v2', '~> 1.0' gem 'omniauth-azure-oauth2', '~> 0.0.9', path: 'vendor/gems/omniauth-azure-oauth2' # See gem README.md @@ -45,16 +44,16 @@ gem 'omniauth-cas3', '~> 1.1.4', path: 'vendor/gems/omniauth-cas3' # See vendor/ gem 'omniauth-dingtalk-oauth2', '~> 1.0' gem 'omniauth-alicloud', '~> 1.0.1' gem 'omniauth-facebook', '~> 4.0.0' -gem 'omniauth-github', '2.0.0' +gem 'omniauth-github', '~> 1.4' gem 'omniauth-gitlab', '~> 4.0.0', path: 'vendor/gems/omniauth-gitlab' # See vendor/gems/omniauth-gitlab/README.md -gem 'omniauth-google-oauth2', '~> 1.0.1', path: 'vendor/gems/omniauth-google-oauth2' # See gem README.md +gem 'omniauth-google-oauth2', '~> 0.6.0', path: 'vendor/gems/omniauth-google-oauth2' # See gem README.md gem 'omniauth-oauth2-generic', '~> 0.2.2' -gem 'omniauth-saml', '~> 2.1.0' +gem 'omniauth-saml', '~> 1.10' gem 'omniauth-shibboleth', '~> 1.3.0' gem 'omniauth-twitter', '~> 1.4' gem 'omniauth_crowd', '~> 2.4.0', path: 'vendor/gems/omniauth_crowd' # See vendor/gems/omniauth_crowd/README.md gem 'omniauth-authentiq', '~> 0.3.3' -gem 'gitlab-omniauth-openid-connect', '~> 0.10.0', require: 'omniauth_openid_connect' +gem 'gitlab-omniauth-openid-connect', '~> 0.9.0', require: 'omniauth_openid_connect' gem 'omniauth-salesforce', '~> 1.0.5', path: 'vendor/gems/omniauth-salesforce' # See gem README.md gem 'omniauth-atlassian-oauth2', '~> 0.2.0' gem 'rack-oauth2', '~> 1.21.2' diff --git a/Gemfile.lock b/Gemfile.lock index 6178c733c8f..74a89c79d5e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -29,7 +29,7 @@ PATH specs: omniauth-azure-oauth2 (0.0.10) jwt (>= 1.0, < 3.0) - omniauth (~> 2.0) + omniauth (~> 1.0, < 3) omniauth-oauth2 (~> 1.4) PATH @@ -38,29 +38,28 @@ PATH omniauth-cas3 (1.1.4) addressable (~> 2.3) nokogiri (~> 1.7, >= 1.7.1) - omniauth (~> 2.0) + omniauth (~> 1.2, < 3) PATH remote: vendor/gems/omniauth-gitlab specs: omniauth-gitlab (4.0.0) - omniauth (~> 2.0) + omniauth (~> 1.0) omniauth-oauth2 (~> 1.7.1) PATH remote: vendor/gems/omniauth-google-oauth2 specs: - omniauth-google-oauth2 (1.0.1) + omniauth-google-oauth2 (0.6.0) jwt (>= 2.0) - oauth2 (~> 2.0) - omniauth (~> 2.0) - omniauth-oauth2 (~> 1.7.1) + omniauth (>= 1.9, < 3) + omniauth-oauth2 (>= 1.5) PATH remote: vendor/gems/omniauth-salesforce specs: omniauth-salesforce (1.0.5) - omniauth (~> 2.0) + omniauth (~> 1.0, < 3) omniauth-oauth2 (~> 1.0) PATH @@ -69,7 +68,7 @@ PATH omniauth_crowd (2.4.0) activesupport nokogiri (>= 1.4.4) - omniauth (~> 2.0) + omniauth (~> 1.0, < 3) GEM remote: https://rubygems.org/ @@ -566,9 +565,9 @@ GEM gitlab-mail_room (0.0.9) gitlab-markup (1.8.0) gitlab-net-dns (0.9.1) - gitlab-omniauth-openid-connect (0.10.0) + gitlab-omniauth-openid-connect (0.9.1) addressable (~> 2.7) - omniauth (>= 1.9, < 3) + omniauth (~> 1.9) openid_connect (~> 1.2) gitlab-sidekiq-fetcher (0.8.0) sidekiq (~> 6.1) @@ -914,10 +913,9 @@ GEM train-core wmi-lite (~> 1.0) oj (3.13.21) - omniauth (2.1.0) + omniauth (1.9.1) hashie (>= 3.4.6) - rack (>= 2.2.3) - rack-protection + rack (>= 1.6.2, < 3) omniauth-alicloud (1.0.1) omniauth-oauth2 (~> 1.7.1) omniauth-atlassian-oauth2 (0.2.0) @@ -934,9 +932,9 @@ GEM omniauth-oauth2 (~> 1.7) omniauth-facebook (4.0.0) omniauth-oauth2 (~> 1.2) - omniauth-github (2.0.0) - omniauth (~> 2.0) - omniauth-oauth2 (~> 1.7.1) + omniauth-github (1.4.0) + omniauth (~> 1.5) + omniauth-oauth2 (>= 1.4.0, < 2.0) omniauth-oauth (1.2.0) oauth omniauth (>= 1.0, < 3) @@ -945,12 +943,9 @@ GEM omniauth (>= 1.9, < 3) omniauth-oauth2-generic (0.2.2) omniauth-oauth2 (~> 1.0) - omniauth-rails_csrf_protection (1.0.1) - actionpack (>= 4.2) - omniauth (~> 2.0) - omniauth-saml (2.1.0) - omniauth (~> 2.0) - ruby-saml (~> 1.12) + omniauth-saml (1.10.0) + omniauth (~> 1.3, >= 1.3.2) + ruby-saml (~> 1.7) omniauth-shibboleth (1.3.0) omniauth (>= 1.0.0) omniauth-twitter (1.4.0) @@ -1059,8 +1054,6 @@ GEM httpclient json-jwt (>= 1.11.0) rack (>= 2.1.0) - rack-protection (2.2.2) - rack rack-proxy (0.7.2) rack rack-test (1.1.0) @@ -1453,7 +1446,7 @@ GEM validate_email (0.1.6) activemodel (>= 3.0) mail (>= 2.2.5) - validate_url (1.0.15) + validate_url (1.0.13) activemodel (>= 3.0.0) public_suffix validates_hostname (1.0.11) @@ -1606,7 +1599,7 @@ DEPENDENCIES gitlab-mail_room (~> 0.0.9) gitlab-markup (~> 1.8.0) gitlab-net-dns (~> 0.9.1) - gitlab-omniauth-openid-connect (~> 0.10.0) + gitlab-omniauth-openid-connect (~> 0.9.0) gitlab-sidekiq-fetcher (= 0.8.0) gitlab-styles (~> 8.0.0) gitlab_chronic_duration (~> 0.10.6.2) @@ -1673,7 +1666,7 @@ DEPENDENCIES octokit (~> 4.15) ohai (~> 16.10) oj (~> 3.13.21) - omniauth (~> 2.1.0) + omniauth (~> 1.8) omniauth-alicloud (~> 1.0.1) omniauth-atlassian-oauth2 (~> 0.2.0) omniauth-auth0 (~> 2.0.0) @@ -1683,13 +1676,12 @@ DEPENDENCIES omniauth-cas3 (~> 1.1.4)! omniauth-dingtalk-oauth2 (~> 1.0) omniauth-facebook (~> 4.0.0) - omniauth-github (= 2.0.0) + omniauth-github (~> 1.4) omniauth-gitlab (~> 4.0.0)! - omniauth-google-oauth2 (~> 1.0.1)! + omniauth-google-oauth2 (~> 0.6.0)! omniauth-oauth2-generic (~> 0.2.2) - omniauth-rails_csrf_protection omniauth-salesforce (~> 1.0.5)! - omniauth-saml (~> 2.1.0) + omniauth-saml (~> 1.10) omniauth-shibboleth (~> 1.3.0) omniauth-twitter (~> 1.4) omniauth_crowd (~> 2.4.0)! diff --git a/app/assets/javascripts/releases/stores/modules/edit_new/actions.js b/app/assets/javascripts/releases/stores/modules/edit_new/actions.js index a71a8125d65..669e5928143 100644 --- a/app/assets/javascripts/releases/stores/modules/edit_new/actions.js +++ b/app/assets/javascripts/releases/stores/modules/edit_new/actions.js @@ -16,6 +16,8 @@ import { import * as types from './mutation_types'; +class GraphQLError extends Error {} + export const initializeRelease = ({ commit, dispatch, state }) => { if (state.isExistingRelease) { // When editing an existing release, @@ -110,35 +112,35 @@ export const saveRelease = ({ commit, dispatch, state }) => { * * @param {Object} gqlResponse The response object returned by the GraphQL client * @param {String} mutationName The name of the mutation that was executed - * @param {String} messageIfError An message to build into the error object if something went wrong */ -const checkForErrorsAsData = (gqlResponse, mutationName, messageIfError) => { +const checkForErrorsAsData = (gqlResponse, mutationName) => { const allErrors = gqlResponse.data[mutationName].errors; if (allErrors.length > 0) { - const allErrorMessages = JSON.stringify(allErrors); - throw new Error(`${messageIfError}: ${allErrorMessages}`); + throw new GraphQLError(allErrors[0]); } }; -export const createRelease = async ({ commit, dispatch, state, getters }) => { +export const createRelease = async ({ commit, dispatch, getters }) => { try { const response = await gqClient.mutate({ mutation: createReleaseMutation, variables: getters.releaseCreateMutatationVariables, }); - checkForErrorsAsData( - response, - 'releaseCreate', - `Something went wrong while creating a new release with projectPath "${state.projectPath}" and tagName "${state.release.tagName}"`, - ); + checkForErrorsAsData(response, 'releaseCreate'); dispatch('receiveSaveReleaseSuccess', response.data.releaseCreate.release.links.selfUrl); } catch (error) { commit(types.RECEIVE_SAVE_RELEASE_ERROR, error); - createFlash({ - message: s__('Release|Something went wrong while creating a new release.'), - }); + if (error instanceof GraphQLError) { + createFlash({ + message: error.message, + }); + } else { + createFlash({ + message: s__('Release|Something went wrong while creating a new release.'), + }); + } } }; @@ -146,7 +148,7 @@ export const createRelease = async ({ commit, dispatch, state, getters }) => { * Deletes a single release link. * Throws an error if any network or validation errors occur. */ -const deleteReleaseLinks = async ({ state, id }) => { +const deleteReleaseLinks = async ({ id }) => { const deleteResponse = await gqClient.mutate({ mutation: deleteReleaseAssetLinkMutation, variables: { @@ -154,11 +156,7 @@ const deleteReleaseLinks = async ({ state, id }) => { }, }); - checkForErrorsAsData( - deleteResponse, - 'releaseAssetLinkDelete', - `Something went wrong while deleting release asset link for release with projectPath "${state.projectPath}", tagName "${state.tagName}", and link id "${id}"`, - ); + checkForErrorsAsData(deleteResponse, 'releaseAssetLinkDelete'); }; /** @@ -180,11 +178,7 @@ const createReleaseLink = async ({ state, link }) => { }, }); - checkForErrorsAsData( - createResponse, - 'releaseAssetLinkCreate', - `Something went wrong while creating a release asset link for release with projectPath "${state.projectPath}" and tagName "${state.tagName}"`, - ); + checkForErrorsAsData(createResponse, 'releaseAssetLinkCreate'); }; export const updateRelease = async ({ commit, dispatch, state, getters }) => { @@ -210,11 +204,7 @@ export const updateRelease = async ({ commit, dispatch, state, getters }) => { variables: getters.releaseUpdateMutatationVariables, }); - checkForErrorsAsData( - updateReleaseResponse, - 'releaseUpdate', - `Something went wrong while updating release with projectPath "${state.projectPath}" and tagName "${state.tagName}"`, - ); + checkForErrorsAsData(updateReleaseResponse, 'releaseUpdate'); // Delete all links currently associated with this Release await Promise.all( @@ -266,7 +256,7 @@ export const deleteRelease = ({ commit, getters, dispatch, state }) => { mutation: deleteReleaseMutation, variables: getters.releaseDeleteMutationVariables, }) - .then((response) => checkForErrorsAsData(response, 'releaseDelete', '')) + .then((response) => checkForErrorsAsData(response, 'releaseDelete')) .then(() => { window.sessionStorage.setItem( deleteReleaseSessionKey(state.projectPath), diff --git a/app/assets/stylesheets/_page_specific_files.scss b/app/assets/stylesheets/_page_specific_files.scss index d0b3f5bda8e..9e81e1d4771 100644 --- a/app/assets/stylesheets/_page_specific_files.scss +++ b/app/assets/stylesheets/_page_specific_files.scss @@ -4,7 +4,6 @@ @import './pages/commits'; @import './pages/deploy_keys'; @import './pages/detail_page'; -@import './pages/editor'; @import './pages/environment_logs'; @import './pages/events'; @import './pages/groups'; diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss index cba8f48071b..07516275e58 100644 --- a/app/assets/stylesheets/framework/files.scss +++ b/app/assets/stylesheets/framework/files.scss @@ -39,8 +39,8 @@ .file-title { position: relative; - background-color: $gray-light; - border-bottom: 1px solid $border-color; + background-color: var(--gray-10, $gray-10); + border-bottom: 1px solid var(--border-color, $border-color); margin: 0; text-align: left; padding: 10px $gl-padding; diff --git a/app/assets/stylesheets/pages/editor.scss b/app/assets/stylesheets/page_bundles/editor.scss index c177d0b74a2..b7b698b2128 100644 --- a/app/assets/stylesheets/pages/editor.scss +++ b/app/assets/stylesheets/page_bundles/editor.scss @@ -1,11 +1,13 @@ +@import 'page_bundles/mixins_and_variables_and_functions'; + .file-editor { .nav-links { - border-top: 1px solid $border-color; - border-right: 1px solid $border-color; - border-left: 1px solid $border-color; + border-top: 1px solid var(--border-color, $border-color); + border-right: 1px solid var(--border-color, $border-color); + border-left: 1px solid var(--border-color, $border-color); border-bottom: 0; border-radius: $border-radius-small $border-radius-small 0 0; - background: $gray-normal; + background: var(--gray-50, $gray-50); } #editor, @@ -23,10 +25,6 @@ } } - .ace_gutter-cell { - background-color: $gray-light; - } - .cancel-btn { color: $red-600; @@ -40,9 +38,9 @@ } .editor-ref { - background: $gray-light; + background: var(--gray-10, $gray-10); padding-right: $gl-padding; - border-right: 1px solid $border-color; + border-right: 1px solid var(--border-color, $border-color); display: block; float: left; margin-right: 10px; diff --git a/app/assets/stylesheets/utilities.scss b/app/assets/stylesheets/utilities.scss index 6cc4d166af7..e5b6c9811b5 100644 --- a/app/assets/stylesheets/utilities.scss +++ b/app/assets/stylesheets/utilities.scss @@ -383,3 +383,13 @@ to @gitlab/ui by https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1709 .gl-flex-flow-row-wrap { flex-flow: row wrap; } + +/* + * The below style will be moved to @gitlab/ui by + * https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1963 + */ +.gl-gap-y-3 { + > * + * { + margin-top: $gl-spacing-scale-3; + } +} diff --git a/app/controllers/acme_challenges_controller.rb b/app/controllers/acme_challenges_controller.rb index 67a39d8870b..4a7706db94e 100644 --- a/app/controllers/acme_challenges_controller.rb +++ b/app/controllers/acme_challenges_controller.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +# rubocop:disable Rails/ApplicationController class AcmeChallengesController < ActionController::Base def show if acme_order @@ -15,3 +16,4 @@ class AcmeChallengesController < ActionController::Base @acme_order ||= PagesDomainAcmeOrder.find_by_domain_and_token(params[:domain], params[:token]) end end +# rubocop:enable Rails/ApplicationController diff --git a/app/controllers/chaos_controller.rb b/app/controllers/chaos_controller.rb index 4e5af1945a4..6139168d29f 100644 --- a/app/controllers/chaos_controller.rb +++ b/app/controllers/chaos_controller.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +# rubocop:disable Rails/ApplicationController class ChaosController < ActionController::Base before_action :validate_chaos_secret, unless: :development_or_test? @@ -93,3 +94,4 @@ class ChaosController < ActionController::Base Rails.env.development? || Rails.env.test? end end +# rubocop:enable Rails/ApplicationController diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb index 0e74ac420b4..5fac7c0d663 100644 --- a/app/controllers/health_controller.rb +++ b/app/controllers/health_controller.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +# rubocop:disable Rails/ApplicationController class HealthController < ActionController::Base protect_from_forgery with: :exception, prepend: true include RequiresWhitelistedMonitoringClient @@ -39,3 +40,4 @@ class HealthController < ActionController::Base render json: result.json, status: result.http_status end end +# rubocop:enable Rails/ApplicationController diff --git a/app/controllers/metrics_controller.rb b/app/controllers/metrics_controller.rb index a0c307a0a03..bfd6181a940 100644 --- a/app/controllers/metrics_controller.rb +++ b/app/controllers/metrics_controller.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +# rubocop:disable Rails/ApplicationController class MetricsController < ActionController::Base include RequiresWhitelistedMonitoringClient @@ -34,3 +35,4 @@ class MetricsController < ActionController::Base ) end end +# rubocop:enable Rails/ApplicationController diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 3a3e5f65c9b..f0568f33b1f 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -428,6 +428,10 @@ module Ci end def self.jobs_count_in_alive_pipelines + created_after(24.hours.ago).alive.joins(:statuses).count + end + + def self.builds_count_in_alive_pipelines created_after(24.hours.ago).alive.joins(:builds).count end diff --git a/app/services/releases/create_service.rb b/app/services/releases/create_service.rb index 2588d2187a5..b7df201824a 100644 --- a/app/services/releases/create_service.rb +++ b/app/services/releases/create_service.rb @@ -4,6 +4,7 @@ module Releases class CreateService < Releases::BaseService def execute return error('Access Denied', 403) unless allowed? + return error('You are not allowed to create this tag as it is protected.', 403) unless can_create_tag? return error('Release already exists', 409) if release return error("Milestone(s) not found: #{inexistent_milestones.join(', ')}", 400) if inexistent_milestones.any? @@ -38,7 +39,7 @@ module Releases end def allowed? - Ability.allowed?(current_user, :create_release, project) && can_create_tag? + Ability.allowed?(current_user, :create_release, project) end def can_create_tag? diff --git a/app/views/notify/remote_mirror_update_failed_email.html.haml b/app/views/notify/remote_mirror_update_failed_email.html.haml index 4fb0a4c5a8a..db95398d2d6 100644 --- a/app/views/notify/remote_mirror_update_failed_email.html.haml +++ b/app/views/notify/remote_mirror_update_failed_email.html.haml @@ -6,7 +6,7 @@ %td{ style: "vertical-align:middle;color:#ffffff;text-align:center;padding-right:5px;line-height:1;" } %img{ alt: "✖", height: "13", src: image_url('mailers/ci_pipeline_notif_v1/icon-x-red-inverted.gif'), style: "display:block;", width: "13" }/ %td{ style: "vertical-align:middle;color:#ffffff;text-align:center;" } - A remote mirror update has failed. + = s_('Notify|A remote mirror update has failed.') %tr.spacer{ style: "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif;" } %td{ style: "height:18px;font-size:18px;line-height:18px;" } @@ -15,7 +15,8 @@ %table.table-info{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;" } %tbody{ style: "font-size:15px;line-height:1.4;color:#8c8c8c;" } %tr - %td{ style: "font-weight:300;padding:14px 0;margin:0;" } Project + %td{ style: "font-weight:300;padding:14px 0;margin:0;" } + = _('Project') %td{ style: "font-weight:500;padding:14px 0;margin:0;color:#333333;width:75%;padding-left:5px;" } - namespace_url = @project.group ? group_url(@project.group) : user_url(@project.namespace.owner) %a.muted{ href: namespace_url, style: "color:#333333;text-decoration:none;" } @@ -24,17 +25,20 @@ %a.muted{ href: project_url(@project), style: "color:#333333;text-decoration:none;" } = @project.name %tr - %td{ style: "font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" } Remote mirror + %td{ style: "font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" } + = s_('Notify|Remote mirror') %td{ style: "font-weight:500;padding:14px 0;margin:0;color:#333333;width:75%;padding-left:5px;border-top:1px solid #ededed;" } = @remote_mirror.safe_url %tr - %td{ style: "font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" } Last update at - %td{ style: "font-weight:500;padding:14px 0;margin:0;color:#333333;width:75%;padding-left:5px;border-top:1px solid #ededed;" } - = @remote_mirror.last_update_at + - update_at_start = '<td style="font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;">'.html_safe + - update_at_mid = '</td><td style="font-weight:500;padding:14px 0;margin:0;color:#333333;width:75%;padding-left:5px;border-top:1px solid #ededed;">'.html_safe + - update_at_end = '</td>'.html_safe + = html_escape(s_('Notify|%{update_at_start} Last update at %{update_at_mid} %{last_update_at} %{update_at_end}')) % {update_at_start: update_at_start, update_at_mid: update_at_mid, last_update_at: @remote_mirror.last_update_at, update_at_end: update_at_end} + %tr.table-warning{ style: "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif;" } %td{ style: "border: 1px solid #ededed; border-bottom: 0; border-radius: 4px 4px 0 0; overflow: hidden; background-color: #fdf4f6; color: #d22852; font-size: 14px; line-height: 1.4; text-align: center; padding: 8px 16px;" } - Logs may contain sensitive data. Please consider before forwarding this email. + = s_('Notify|Logs may contain sensitive data. Please consider before forwarding this email.') %tr.section{ style: "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif;" } %td{ style: "padding: 0 16px; border: 1px solid #ededed; border-radius: 4px; overflow: hidden; border-top: 0; border-radius: 0 0 4px 4px;" } %table.builds{ border: "0", cellpadding: "0", cellspacing: "0", style: "width: 100%; border-collapse: collapse;" } diff --git a/app/views/notify/removed_milestone_merge_request_email.html.haml b/app/views/notify/removed_milestone_merge_request_email.html.haml index 7e9205b6491..f411ea23832 100644 --- a/app/views/notify/removed_milestone_merge_request_email.html.haml +++ b/app/views/notify/removed_milestone_merge_request_email.html.haml @@ -1,2 +1,2 @@ %p - Milestone removed + = s_('Notify|Milestone removed') diff --git a/app/views/projects/blob/edit.html.haml b/app/views/projects/blob/edit.html.haml index 220319d31b5..528999f5c89 100644 --- a/app/views/projects/blob/edit.html.haml +++ b/app/views/projects/blob/edit.html.haml @@ -2,6 +2,7 @@ - page_title _("Edit"), @blob.path, @ref - content_for :prefetch_asset_tags do - webpack_preload_asset_tag('monaco') +- add_page_specific_style 'page_bundles/editor' - if @conflict = render Pajamas::AlertComponent.new(alert_options: { class: 'gl-mb-5 gl-mt-5' }, diff --git a/app/views/projects/blob/new.html.haml b/app/views/projects/blob/new.html.haml index 27f64104cf4..81b2715b228 100644 --- a/app/views/projects/blob/new.html.haml +++ b/app/views/projects/blob/new.html.haml @@ -1,5 +1,6 @@ - breadcrumb_title _("Repository") - page_title _("New File"), @path.presence, @ref +- add_page_specific_style 'page_bundles/editor' %h1.page-title.blob-new-page-title.gl-font-size-h-display = _('New file') diff --git a/app/views/projects/ci/pipeline_editor/show.html.haml b/app/views/projects/ci/pipeline_editor/show.html.haml index 18eac48d42a..bc352ff6c7d 100644 --- a/app/views/projects/ci/pipeline_editor/show.html.haml +++ b/app/views/projects/ci/pipeline_editor/show.html.haml @@ -1,4 +1,5 @@ - @force_fluid_layout = true +- add_page_specific_style 'page_bundles/editor' - add_page_specific_style 'page_bundles/pipelines' - add_page_specific_style 'page_bundles/pipeline_editor' diff --git a/config/application.rb b/config/application.rb index c93c0ae1efe..03c8eadc4b0 100644 --- a/config/application.rb +++ b/config/application.rb @@ -264,6 +264,7 @@ module Gitlab config.assets.precompile << "page_bundles/cycle_analytics.css" config.assets.precompile << "page_bundles/dashboard_projects.css" config.assets.precompile << "page_bundles/dev_ops_reports.css" + config.assets.precompile << "page_bundles/editor.css" config.assets.precompile << "page_bundles/environments.css" config.assets.precompile << "page_bundles/epics.css" config.assets.precompile << "page_bundles/error_tracking_details.css" diff --git a/config/feature_flags/development/ci_limit_active_jobs_early.yml b/config/feature_flags/development/ci_limit_active_jobs_early.yml new file mode 100644 index 00000000000..b7dba0f81e9 --- /dev/null +++ b/config/feature_flags/development/ci_limit_active_jobs_early.yml @@ -0,0 +1,8 @@ +--- +name: ci_limit_active_jobs_early +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/97700 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/373284 +milestone: '15.4' +type: development +group: group::pipeline execution +default_enabled: false diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb index 2454b5ea818..38bd1034b36 100644 --- a/config/initializers/omniauth.rb +++ b/config/initializers/omniauth.rb @@ -11,17 +11,6 @@ if Gitlab::Auth::Ldap::Config.enabled? end end -module OmniAuth - module Strategies - class AzureActivedirectoryV2 - # override until https://github.com/RIPAGlobal/omniauth-azure-activedirectory-v2/pull/6 is merged - def callback_url - full_host + callback_path - end - end - end -end - OmniAuth.config.full_host = Gitlab::OmniauthInitializer.full_host OmniAuth.config.allowed_request_methods = [:post] diff --git a/config/object_store_settings.rb b/config/object_store_settings.rb index 3280bc284ad..e55032d3987 100644 --- a/config/object_store_settings.rb +++ b/config/object_store_settings.rb @@ -16,10 +16,6 @@ class ObjectStoreSettings # we don't need to raise an error in that case ALLOWED_INCOMPLETE_TYPES = %w(pages).freeze - # A fallback switch in case anyone gets a trouble with background upload removal - # Epic: https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/734 - LEGACY_BACKGROUND_UPLOADS_ENV = "GITLAB_LEGACY_BACKGROUND_UPLOADS" - attr_accessor :settings # Legacy parser @@ -30,13 +26,8 @@ class ObjectStoreSettings object_store['remote_directory'] ) - if support_legacy_background_upload?(object_store_type) - object_store['direct_upload'] = false - object_store['background_upload'] = true - else - object_store['direct_upload'] = true - object_store['background_upload'] = false - end + object_store['direct_upload'] = true + object_store['background_upload'] = false object_store['proxy_download'] = false if object_store['proxy_download'].nil? object_store['storage_options'] ||= {} @@ -46,10 +37,6 @@ class ObjectStoreSettings object_store end - def self.support_legacy_background_upload?(object_store_type) - ENV[LEGACY_BACKGROUND_UPLOADS_ENV].to_s.split(',').map(&:strip).include?(object_store_type) - end - def self.split_bucket_prefix(bucket) return [nil, nil] unless bucket.present? diff --git a/data/removals/15_0/15-0-remove-background-upload-object-storage.yml b/data/removals/15_0/15-0-remove-background-upload-object-storage.yml index 16aab3d14c2..dac96032359 100644 --- a/data/removals/15_0/15-0-remove-background-upload-object-storage.yml +++ b/data/removals/15_0/15-0-remove-background-upload-object-storage.yml @@ -43,9 +43,8 @@ gitlab_rails['env'] = { 'GITLAB_LEGACY_BACKGROUND_UPLOADS' => 'artifacts,external_diffs,lfs,uploads,packages,dependency_proxy,terraform_state,pages' } ``` - Prefixes will be supported officially in [GitLab 15.2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91307). - This workaround will be dropped, so we encourage migrating to consolidated object storage. - + Support for prefixes was restored in GitLab 15.2 via [this MR](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91307). + Support for setting `GITLAB_LEGACY_BACKGROUND_UPLOADS` will be removed in GitLab 15.4. stage: Enablement tiers: [Core, Premium, Ultimate] diff --git a/doc/operations/error_tracking.md b/doc/operations/error_tracking.md index a42aa3c19b0..22e21c01fbd 100644 --- a/doc/operations/error_tracking.md +++ b/doc/operations/error_tracking.md @@ -46,7 +46,7 @@ least Maintainer [permissions](../user/permissions.md) to enable the Sentry inte Make sure to give the token at least the following scopes: `project:read`, `event:read`, and `event:write` (for resolving events). 1. In GitLab, enable error tracking: - 1. On the top bar, select **Menu > Projects** and find your project. + 1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > Error Tracking**. 1. Select **Enable error tracking**. 1. In GitLab, ensure error tracking is active. diff --git a/doc/operations/feature_flags.md b/doc/operations/feature_flags.md index 9e7d452c259..0dccaa6bfe9 100644 --- a/doc/operations/feature_flags.md +++ b/doc/operations/feature_flags.md @@ -37,7 +37,7 @@ with GitLab, so it's up to developers to use a compatible client library and To create and enable a feature flag: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Deployments > Feature Flags**. 1. Select **New feature flag**. 1. Enter a name that starts with a letter and contains only lowercase letters, digits, underscores (`_`), @@ -180,7 +180,7 @@ For example: To create a user list: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Deployments > Feature Flags**. 1. Select **View user lists** 1. Select **New user list**. @@ -196,7 +196,7 @@ When viewing a list, you can rename it by selecting **Edit** (**{pencil}**). To add users to a user list: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Deployments > Feature Flags**. 1. Select **Edit** (**{pencil}**) next to the list you want to add users to. 1. Select **Add Users**. @@ -210,7 +210,7 @@ To add users to a user list: To remove users from a user list: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Deployments > Feature Flags**. 1. Select **Edit** (**{pencil}**) next to the list you want to change. 1. Select **Remove** (**{remove}**) next to the ID you want to remove. @@ -224,7 +224,7 @@ code so that you can clean it up when it's time to remove the feature flag. To search for code references of a feature flag: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Deployments > Feature Flags**. 1. Edit the feature flag you want to remove. 1. Select **More actions** (**{ellipsis_v}**). @@ -235,7 +235,7 @@ To search for code references of a feature flag: In [GitLab 13.0 and earlier](https://gitlab.com/gitlab-org/gitlab/-/issues/8621), to disable a feature flag for a specific environment: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Deployments > Feature Flags**. 1. For the feature flag you want to disable, select **Edit** (**{pencil}**). 1. To disable the flag: @@ -250,7 +250,7 @@ to disable a feature flag for a specific environment: To disable a feature flag for all environments: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Deployments > Feature Flags**. 1. For the feature flag you want to disable, slide the Status toggle to **Disabled**. @@ -265,7 +265,7 @@ Then prepare your application with a client library. To get the access credentials that your application needs to communicate with GitLab: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Deployments > Feature Flags**. 1. Select **Configure** to view the following: - **API URL**: URL where the client (application) connects to get a list of feature flags. diff --git a/doc/operations/incident_management/alerts.md b/doc/operations/incident_management/alerts.md index a4b34807094..7e4223c0820 100644 --- a/doc/operations/incident_management/alerts.md +++ b/doc/operations/incident_management/alerts.md @@ -120,7 +120,7 @@ Prerequisite: To view the logs for an alert: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > Alerts**. 1. Select the alert you want to view. 1. Below the title of the alert, select the **Metrics** tab. @@ -198,7 +198,7 @@ To assign an alert: 1. Display the list of current alerts: - 1. On the top bar, select **Menu > Projects** and find your project. + 1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > Alerts**. 1. Select your desired alert to display its details. @@ -226,7 +226,7 @@ add a to-do item: 1. Display the list of current alerts: - 1. On the top bar, select **Menu > Projects** and find your project. + 1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > Alerts**. 1. Select your desired alert to display its **Alert Management Details View**. diff --git a/doc/operations/incident_management/escalation_policies.md b/doc/operations/incident_management/escalation_policies.md index c24824e55f8..56ff733e395 100644 --- a/doc/operations/incident_management/escalation_policies.md +++ b/doc/operations/incident_management/escalation_policies.md @@ -22,7 +22,7 @@ Prerequisite: To create an escalation policy: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > Escalation Policies**. 1. Select **Add an escalation policy**. 1. Enter the policy's name and description, and @@ -46,7 +46,7 @@ the paged users is created on the alert. To update an escalation policy: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > Escalation Policies**. 1. Select **Edit escalation policy** (**{pencil}**). 1. Edit the information. @@ -56,7 +56,7 @@ To update an escalation policy: To delete an escalation policy: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > Escalation Policies**. 1. Select **Delete escalation policy** (**{remove}**). 1. On the confirmation dialog, select **Delete escalation policy**. diff --git a/doc/operations/incident_management/incident_timeline_events.md b/doc/operations/incident_management/incident_timeline_events.md index a360cac0d01..743f9b429d6 100644 --- a/doc/operations/incident_management/incident_timeline_events.md +++ b/doc/operations/incident_management/incident_timeline_events.md @@ -25,7 +25,7 @@ They are grouped with dates and are listed in ascending order of the time when t To view the event timeline of an incident: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > Incidents**. 1. Select an incident. 1. Select the **Timeline** tab. @@ -44,7 +44,7 @@ Prerequisites: To create a timeline event: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > Incidents**. 1. Select an incident. 1. Select the **Timeline** tab. @@ -68,7 +68,7 @@ Prerequisites: To create a timeline event from a comment on the incident: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > Incidents**. 1. Select an incident. 1. Create a comment or choose an existing comment. @@ -86,7 +86,7 @@ Prerequisites: To delete a timeline event: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > Incidents**. 1. Select an incident. 1. Select the **Timeline** tab. diff --git a/doc/operations/incident_management/linked_resources.md b/doc/operations/incident_management/linked_resources.md index f2a1e60e9c0..3fe4a325cdb 100644 --- a/doc/operations/incident_management/linked_resources.md +++ b/doc/operations/incident_management/linked_resources.md @@ -29,7 +29,7 @@ Linked resources for an incident are listed under the **Summary** tab. To view the linked resources of an incident: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > Incidents**. 1. Select an incident. @@ -43,7 +43,7 @@ Prerequisites: To add a linked resource: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > Incidents**. 1. Select an incident. 1. In the **Linked resources** section, select the plus icon (**{plus-square}**). @@ -76,7 +76,7 @@ Prerequisites: To remove a linked resource: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > Incidents**. 1. Select an incident. 1. In the **Linked resources** section, select **Remove** (**{close}**). diff --git a/doc/operations/incident_management/oncall_schedules.md b/doc/operations/incident_management/oncall_schedules.md index 9b2e9159429..f1fb3503195 100644 --- a/doc/operations/incident_management/oncall_schedules.md +++ b/doc/operations/incident_management/oncall_schedules.md @@ -28,7 +28,7 @@ Prerequisite: To create an on-call schedule: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > On-call Schedules**. 1. Select **Add a schedule**. 1. Enter the schedule's name and description and select a time zone. @@ -43,7 +43,7 @@ create [rotations](#rotations) for your schedule. To update a schedule: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > On-call Schedules**. 1. Select **Edit schedule** (**{pencil}**). 1. Edit the information. @@ -56,7 +56,7 @@ interval (if one is set) to the corresponding times in the new time zone. To delete a schedule: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > On-call Schedules**. 1. Select **Delete escalation policy** (**{remove}**). 1. On the confirmation dialog, select **Delete schedule**. @@ -67,7 +67,7 @@ Add rotations to an existing schedule to put your team members on-call. To create a rotation: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > On-call Schedules**. 1. Select the **Add a rotation** link. 1. Enter the following information: @@ -85,7 +85,7 @@ To create a rotation: To edit a rotation: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > On-call Schedules**. 1. In the **Rotations** section, select **Edit rotation** (**{pencil}**). 1. Edit the information. @@ -95,7 +95,7 @@ To edit a rotation: To delete a rotation: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > On-call Schedules**. 1. In the **Rotations** section, select **Delete rotation** (**{remove}**). 1. On the confirmation dialog, select **Delete rotation**. diff --git a/doc/operations/incident_management/paging.md b/doc/operations/incident_management/paging.md index 3eeeb67bf51..837fc9c72f5 100644 --- a/doc/operations/incident_management/paging.md +++ b/doc/operations/incident_management/paging.md @@ -27,7 +27,7 @@ Email notifications are available in projects for triggered alerts. Project members with the **Owner** or **Maintainer** roles have the option to receive a single email notification for new alerts. -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Monitor**. 1. Expand **Alerts**. 1. On the **Alert settings** tab, select the diff --git a/doc/operations/incident_management/status_page.md b/doc/operations/incident_management/status_page.md index fe75c1812c8..ae4d75396ae 100644 --- a/doc/operations/incident_management/status_page.md +++ b/doc/operations/incident_management/status_page.md @@ -45,7 +45,7 @@ Prerequisite: To provide GitLab with the AWS account information needed to push content to your Status Page: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Monitor**. 1. Expand **Status Page**. 1. Select the **Active** checkbox. @@ -96,7 +96,7 @@ the issue can potentially [publish comments to your GitLab Status Page](#publish After creating the CI/CD variables, configure the Project you want to use for Incident issues: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Monitor**. 1. Expand **Status page**. 1. Fill in your cloud provider's credentials and make sure to select the **Active** checkbox. diff --git a/doc/operations/product_analytics.md b/doc/operations/product_analytics.md index a897e1d26e8..e21770bc579 100644 --- a/doc/operations/product_analytics.md +++ b/doc/operations/product_analytics.md @@ -28,7 +28,7 @@ Prerequisite: To access Product Analytics: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Monitor > Product Analytics**. The Product Analytics interface contains: diff --git a/doc/tutorials/make_your_first_git_commit.md b/doc/tutorials/make_your_first_git_commit.md index fafc440c6a3..879257fc3b8 100644 --- a/doc/tutorials/make_your_first_git_commit.md +++ b/doc/tutorials/make_your_first_git_commit.md @@ -83,8 +83,8 @@ Here's an overview of what we're going to do: To start, create a sample project in GitLab. -1. In GitLab, on the top bar, select **Menu > Projects > Create new project**. -1. Select **Create blank project**. +1. In GitLab, on the top bar, select **Main menu > Projects > View all projects**. +1. On the right of the page, select **New project**. 1. For **Project name**, enter `My sample project`. The project slug is generated for you. This slug is the URL you can use to access the project after it's created. 1. Ensure **Initialize repository with a README** is selected. diff --git a/doc/tutorials/move_personal_project_to_a_group.md b/doc/tutorials/move_personal_project_to_a_group.md index 5ebbf813ab9..4f94f77e2bd 100644 --- a/doc/tutorials/move_personal_project_to_a_group.md +++ b/doc/tutorials/move_personal_project_to_a_group.md @@ -46,8 +46,8 @@ Maintainer role for the group. If you don't have a group, create one: -1. On the top bar, select **Menu > Groups > Create group** -1. Select **Create group**. +1. On the top bar, select **Main menu > Groups > View all groups** +1. On the right of the page, select **New group**. 1. In **Group name**, enter a name for the group. 1. In **Group URL**, enter a path for the group, which is used as the namespace. 1. Choose the [visibility level](../user/public_access.md). @@ -64,7 +64,7 @@ Before you move your project to a group: Now you're ready to move your project: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects > View all projects** and find your project. 1. On the left sidebar, select **Settings > General**. 1. Expand **Advanced**. 1. Under **Transfer project**, choose the group to transfer the project to. @@ -85,7 +85,7 @@ your related resources and tools, such as websites and package managers. You can now view your project in your group: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. 1. Look for your project under **Subgroups and projects**. Start enjoying the benefits of a group! For example, as the group Owner, you can diff --git a/doc/update/index.md b/doc/update/index.md index dd3a62570db..41f3f9fbf67 100644 --- a/doc/update/index.md +++ b/doc/update/index.md @@ -147,7 +147,7 @@ Some installations [may need to run GitLab 14.0 for at least a day](#1400) to co To check the status of batched background migrations: -1. On the top bar, select **Menu > Admin**. +1. On the top bar, select **Main menu > Admin**. 1. On the left sidebar, select **Monitoring > Background Migrations**. ![queued batched background migrations table](img/batched_background_migrations_queued_v14_0.png) diff --git a/doc/update/plan_your_upgrade.md b/doc/update/plan_your_upgrade.md index 9dfdb7c530b..03bdf161756 100644 --- a/doc/update/plan_your_upgrade.md +++ b/doc/update/plan_your_upgrade.md @@ -132,7 +132,7 @@ to your instance and then upgrade it for any relevant features you're using. [turning on maintenance mode](../administration/maintenance_mode/index.md) during the upgrade. - About PostgreSQL: - - On the top bar, select **Menu > Admin**, and look for the version of + - On the top bar, select **Main menu > Admin**, and look for the version of PostgreSQL you are using. If [a PostgreSQL upgrade is needed](../administration/package_information/postgresql_versions.md), account for the relevant diff --git a/doc/update/removals.md b/doc/update/removals.md index 1f9b92d6600..feec0f1b29d 100644 --- a/doc/update/removals.md +++ b/doc/update/removals.md @@ -140,8 +140,8 @@ If you have set a prefix, you can use a workaround to revert to background uploa gitlab_rails['env'] = { 'GITLAB_LEGACY_BACKGROUND_UPLOADS' => 'artifacts,external_diffs,lfs,uploads,packages,dependency_proxy,terraform_state,pages' } ``` -Prefixes will be supported officially in [GitLab 15.2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91307). -This workaround will be dropped, so we encourage migrating to consolidated object storage. +Support for prefixes was restored in GitLab 15.2 via [this MR](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91307). +Support for setting `GITLAB_LEGACY_BACKGROUND_UPLOADS` will be removed in GitLab 15.4. ### Container Network and Host Security diff --git a/doc/user/crm/index.md b/doc/user/crm/index.md index e71a983ccfd..56ada837d54 100644 --- a/doc/user/crm/index.md +++ b/doc/user/crm/index.md @@ -36,7 +36,7 @@ you must enable CRM features for the subgroup. To enable customer relations management in a group or subgroup: -1. On the top bar, select **Menu > Groups** and find your group or subgroup. +1. On the top bar, select **Main menu > Groups** and find your group or subgroup. 1. On the left sidebar, select **Settings > General**. 1. Expand the **Permissions and group features** section. 1. Select **Customer relations is enabled**. @@ -48,7 +48,7 @@ To enable customer relations management in a group or subgroup: To view a group's contacts: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups** and find your group. 1. On the left sidebar, select **Customer relations > Contacts**. ![Contacts list](crm_contacts_v14_10.png) @@ -57,7 +57,7 @@ To view a group's contacts: To create a contact: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups** and find your group. 1. On the left sidebar, select **Customer relations > Contacts**. 1. Select **New contact**. 1. Complete all required fields. @@ -70,7 +70,7 @@ contacts using the GraphQL API. To edit an existing contact: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups** and find your group. 1. On the left sidebar, select **Customer relations > Contacts**. 1. Next to the contact you wish to edit, select **Edit** (**{pencil}**). 1. Edit the required fields. @@ -85,7 +85,7 @@ contacts using the GraphQL API. To view a group's organizations: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups** and find your group. 1. On the left sidebar, select **Customer relations > Organizations**. ![Organizations list](crm_organizations_v14_10.png) @@ -94,7 +94,7 @@ To view a group's organizations: To create an organization: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups** and find your group. 1. On the left sidebar, select **Customer relations > Organizations**. 1. Select **New organization**. 1. Complete all required fields. @@ -107,7 +107,7 @@ organizations using the GraphQL API. To edit an existing organization: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups** and find your group. 1. On the left sidebar, select **Customer relations > Organizations**. 1. Next to the organization you wish to edit, select **Edit** (**{pencil}**). 1. Edit the required fields. @@ -125,7 +125,7 @@ issues are linked to contacts matching the email addresses in the sender and CC To view a contact's issues, select a contact from the issue sidebar, or: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups** and find your group. 1. On the left sidebar, select **Customer relations > Contacts**. 1. Next to the contact whose issues you wish to view, select **View issues** (**{issues}**). @@ -133,7 +133,7 @@ To view a contact's issues, select a contact from the issue sidebar, or: To view an organization's issues: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups** and find your group. 1. On the left sidebar, select **Customer relations > Organizations**. 1. Next to the organization whose issues you wish to view, select **View issues** (**{issues}**). diff --git a/doc/user/discussions/index.md b/doc/user/discussions/index.md index d82a6ab5e8e..ed0bcec9f49 100644 --- a/doc/user/discussions/index.md +++ b/doc/user/discussions/index.md @@ -91,7 +91,7 @@ For example, `28719b171a056960dfdc0012b625d0b47b123196` becomes You can add comments and threads to a particular commit. -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Repository > Commits**. 1. Below the commits, in the **Comment** field, enter a comment. 1. Select **Comment** or select the down arrow (**{chevron-down}**) to select **Start thread**. @@ -339,7 +339,7 @@ You can prevent merge requests from being merged until all threads are resolved. When this setting is enabled, the **Unresolved threads** counter in a merge request is shown in orange when at least one thread remains unresolved. -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Merge requests**. 1. In the **Merge checks** section, select the **All threads must be resolved** checkbox. 1. Select **Save changes**. @@ -349,7 +349,7 @@ is shown in orange when at least one thread remains unresolved. You can set merge requests to automatically resolve threads when lines are modified with a new push. -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Merge requests**. 1. In the **Merge options** section, select **Automatically resolve merge request diff threads when they become outdated**. diff --git a/doc/user/free_user_limit.md b/doc/user/free_user_limit.md index e364624a630..60091449256 100644 --- a/doc/user/free_user_limit.md +++ b/doc/user/free_user_limit.md @@ -37,7 +37,7 @@ Prerequisite: - You must have the Owner role for the group. -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. 1. On the left sidebar, select **Settings > Usage Quotas**. 1. To view all members, select the **Seats** tab. 1. To remove a member, select **Remove user**. diff --git a/doc/user/group/access_and_permissions.md b/doc/user/group/access_and_permissions.md index aaf475733ab..949587209d6 100644 --- a/doc/user/group/access_and_permissions.md +++ b/doc/user/group/access_and_permissions.md @@ -19,7 +19,7 @@ Group push rules allow group maintainers to set In GitLab 15.4 and later, to configure push rules for a group: -1. On the left sidebar, select Push rules. +1. On the left sidebar, select **Push rules**. 1. Select the settings you want. 1. Select **Save Push Rules**. @@ -50,7 +50,8 @@ configured by an administrator. To change the permitted Git access protocols for a group: -1. Go to the group's **Settings > General** page. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. +1. On the left sidebar, select **Settings > General**. 1. Expand the **Permissions and group features** section. 1. Choose the permitted protocols from **Enabled Git access protocols**. 1. Select **Save changes**. @@ -90,7 +91,8 @@ You should consider some security implications before configuring IP address res To restrict group access by IP address: -1. Go to the group's **Settings > General** page. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. +1. On the left sidebar, select **Settings > General**. 1. Expand the **Permissions and group features** section. 1. In the **Restrict access by IP address** field, enter IPv4 or IPv6 address ranges in CIDR notation. 1. Select **Save changes**. @@ -109,7 +111,8 @@ You can prevent users with email addresses in specific domains from being added To restrict group access by domain: -1. Go to the group's **Settings > General** page. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. +1. On the left sidebar, select **Settings > General**. 1. Expand the **Permissions and group features** section. 1. In the **Restrict membership by email** field, enter the domain names. 1. Select **Save changes**. @@ -152,7 +155,7 @@ If you prevent group sharing outside the hierarchy for the **Animals** group: To prevent sharing outside of the group's hierarchy: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. 1. On the left sidebar, select **Settings > General**. 1. Expand **Permissions and group features**. 1. Select **Members cannot invite groups outside of `<group_name>` and its subgroups**. @@ -166,7 +169,8 @@ to enable tighter control over project access. To prevent a project from being shared with other groups: -1. Go to the group's **Settings > General** page. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. +1. On the left sidebar, select **Settings > General**. 1. Expand the **Permissions and group features** section. 1. Select **Projects in `<group_name>` cannot be shared with other groups**. 1. Select **Save changes**. @@ -179,7 +183,7 @@ added to a project lose access when the setting is enabled. As a group owner, you can prevent non-members from requesting access to your group. -1. On the top bar, select **Menu > Groups**. +1. On the top bar, **Main menu > Groups > View all groups** and find your group. 1. Select **Your Groups**. 1. Find the group and select it. 1. From the left menu, select **Settings > General**. @@ -201,7 +205,8 @@ If even one is set to `true`, then the group does not allow outside forks. To prevent projects from being forked outside the group: -1. Go to the top-level group's **Settings > General** page. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. +1. On the left sidebar, select **Settings > General**. 1. Expand the **Permissions and group features** section. 1. Check **Prevent project forking outside current group**. 1. Select **Save changes**. @@ -222,8 +227,8 @@ The setting does not cascade. Projects in subgroups observe the subgroup configu To prevent members from being added to projects in a group: -1. Go to the group's **Settings > General** page. -1. Expand the **Permissions and group features** section. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. +1. On the left sidebar, select **Settings > General**. 1. Under **Membership**, select **Users cannot be added to projects in this group**. 1. Select **Save changes**. @@ -269,7 +274,8 @@ To create group links via filter: LDAP user permissions can be manually overridden by an administrator. To override a user's permissions: -1. Go to your group's **Group information > Members** page. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. +1. On the left sidebar, select **Group information > Members**. 1. In the row for the user you are editing, select the pencil (**{pencil}**) icon. 1. Select **Edit permissions** in the modal. diff --git a/doc/user/group/manage.md b/doc/user/group/manage.md index 78e65297d32..d55d410acea 100644 --- a/doc/user/group/manage.md +++ b/doc/user/group/manage.md @@ -10,8 +10,7 @@ Use groups to manage one or more related projects at the same time. ## View groups -1. On the top bar, select **Menu > Groups**. -1. Select **Explore groups**. +To view groups, on the top bar, select **Main menu > Groups > View all groups**. The **Groups** page shows a list of groups, sorted by last updated date. @@ -25,7 +24,7 @@ The **Groups** page shows a list of groups, sorted by last updated date. To create a group: 1. On the top bar, either: - - Select **Menu > Groups**, and on the right, select **Create group**. + - Select **Main menu > Groups > View all groups**, and on the right, select **New group**. - To the left of the search box, select the plus sign and then **New group**. 1. Select **Create group**. 1. Enter a name for the group in **Group name**. For a list of words that cannot be used as group names, see @@ -45,7 +44,7 @@ For details about groups, watch [GitLab Namespaces (users, groups and subgroups) To remove a group and its contents: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. 1. On the left sidebar, select **Settings > General**. 1. Expand the **Advanced** section. 1. In the **Remove group** section, select **Remove group**. @@ -54,7 +53,7 @@ To remove a group and its contents: A group can also be removed from the groups dashboard: -1. On the top bar, select **Menu > Groups**. +1. On the top bar, select **Main menu > Groups > View all groups**. 1. Select **Your Groups**. 1. Select (**{ellipsis_v}**) for the group you want to delete. 1. Select **Delete**. @@ -83,7 +82,7 @@ Prerequisites: To immediately remove a group marked for deletion: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. 1. On the left sidebar, select **Settings > General**. 1. Expand **Advanced**. 1. In the "Permanently remove group" section, select **Remove group**. @@ -98,7 +97,8 @@ are deleted. To restore a group that is marked for deletion: -1. Go to your group's **Settings > General** page. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. +1. Select **Settings > General**. 1. Expand the **Path, transfer, remove** section. 1. In the Restore group section, select **Restore group**. @@ -106,7 +106,7 @@ To restore a group that is marked for deletion: As a user, you can request to be a member of a group, if an administrator allows it. -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. 1. Under the group name, select **Request Access**. As many as ten of the most-recently-active group owners receive an email with your request. @@ -127,7 +127,7 @@ To find members in a group, you can sort, filter, or search. Filter a group to find members. By default, all members in the group and subgroups are displayed. -1. Go to the group and select **Group information > Members**. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. 1. Above the list of members, in the **Filter members** box, enter filter criteria. - To view members in the group only, select **Membership = Direct**. - To view members of the group and its subgroups, select **Membership = Inherited**. @@ -138,7 +138,8 @@ Filter a group to find members. By default, all members in the group and subgrou You can search for members by name, username, or email. -1. Go to the group and select **Group information > Members**. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. +1. On the left sidebar, select **Group information > Members**. 1. Above the list of members, in the **Filter members** box, enter search criteria. 1. To the right of the **Filter members** box, select the magnifying glass (**{search}**). @@ -146,7 +147,8 @@ You can search for members by name, username, or email. You can sort members by **Account**, **Access granted**, **Max role**, or **Last sign-in**. -1. Go to the group and select **Group information > Members**. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. +1. On the left sidebar, select **Group information > Members**. 1. Above the list of members, on the top right, from the **Account** list, select the criteria to filter by. 1. To switch the sort between ascending and descending, to the right of the **Account** list, select the @@ -156,7 +158,7 @@ You can sort members by **Account**, **Access granted**, **Max role**, or **Last You can give a user access to all projects in a group. -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. 1. On the left sidebar, select **Group information > Members**. 1. Select **Invite members**. 1. Fill in the fields. @@ -182,8 +184,8 @@ Prerequisites: To remove a member from a group: -1. Go to the group. -1. From the left menu, select **Group information > Members**. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. +1. On the left sidebar, select **Group information > Members**. 1. Next to the member you want to remove, select **Remove member**. 1. Optional. On the **Remove member** confirmation box: - To remove direct user membership from subgroups and projects, select the **Also remove direct user membership from subgroups and projects** checkbox. @@ -208,7 +210,7 @@ By default, users with at least the Developer role can create projects under a g To change this setting for a specific group: -1. On the top bar, select **Menu > Groups**. +1. On the top bar, select **Main menu > Groups > View all groups**. 1. Select **Your Groups**. 1. Find the group and select it. 1. From the left menu, select **Settings > General**. @@ -224,11 +226,13 @@ You can change the owner of a group. Each group must always have at least one member with the Owner role. - As an administrator: - 1. Go to the group and from the left menu, select **Group information > Members**. + 1. On the top bar, select **Main menu > Groups > View all groups** and find your group. + 1. On the left sidebar, select **Group information > Members**. 1. Give a different member the **Owner** role. 1. Refresh the page. You can now remove the **Owner** role from the original owner. - As the current group's owner: - 1. Go to the group and from the left menu, select **Group information > Members**. + 1. On the top bar, select **Main menu > Groups > View all groups** and find your group. + 1. On the left sidebar, select **Group information > Members**. 1. Give a different member the **Owner** role. 1. Have the new owner sign in and remove the **Owner** role from you. @@ -247,7 +251,8 @@ create a new group and transfer projects to it instead. To change your group path (group URL): -1. Go to your group's **Settings > General** page. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. +1. On the left sidebar, select **Settings > General** page. 1. Expand the **Advanced** section. 1. Under **Change group URL**, enter a new name. 1. Select **Change group URL**. @@ -327,7 +332,7 @@ When transferring groups, note: To transfer a group: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. 1. On the left sidebar, select **Settings > General**. 1. Expand the **Advanced** section. 1. In the **Remove group** section, select **Transfer group**. @@ -357,7 +362,8 @@ the default setting. To enable delayed deletion of projects in a group: -1. Go to the group's **Settings > General** page. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. +1. On the left sidebar, select **Settings > General**. 1. Expand the **Permissions and group features** section. 1. Scroll to: - (GitLab 15.1 and later) **Deletion protection** and select **Keep deleted projects**. @@ -378,7 +384,8 @@ You can disable all email notifications related to the group, which includes its To disable email notifications: -1. Go to the group's **Settings > General** page. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. +1. On the left sidebar, select **Settings > General**. 1. Expand the **Permissions and group features** section. 1. Select **Email notifications are disabled**. 1. Select **Save changes**. @@ -397,7 +404,8 @@ This is particularly helpful for groups with a large number of users. To disable group mentions: -1. Go to the group's **Settings > General** page. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. +1. On the left sidebar, select **Settings > General**. 1. Expand the **Permissions and group features** section. 1. Select **Group mentions are disabled**. 1. Select **Save changes**. @@ -409,7 +417,8 @@ To disable group mentions: You can export a list of members in a group or subgroup as a CSV. -1. Go to your group or subgroup and select either **Group information > Members** or **Subgroup information > Members**. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group or subgroup. +1. On the left sidebar, select either **Group information > Members** or **Subgroup information > Members**. 1. Select **Export as CSV**. 1. After the CSV file has been generated, it is emailed as an attachment to the user that requested it. @@ -435,7 +444,7 @@ Prerequisite: To specify a user cap: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. You can set a cap on the top-level group only. 1. On the left sidebar, select **Settings > General**. 1. Expand **Permissions and group features**. @@ -457,7 +466,7 @@ Prerequisite: To remove the user cap: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. 1. On the left sidebar, select **Settings > General**. 1. Expand **Permissions and group features**. 1. In the **User cap** box, delete the value. @@ -478,7 +487,7 @@ Prerequisite: To approve members that are pending because they've exceeded the user cap: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. 1. On the left sidebar, select **Settings > Usage Quotas**. 1. On the **Seats** tab, under the alert, select **View pending approvals**. 1. For each member you want to approve, select **Approve**. @@ -509,7 +518,8 @@ Define project templates at a group level by setting a group as the template sou To enable group file templates: -1. Go to the group's **Settings > General** page. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. +1. On the left sidebar, select **Settings > General**. 1. Expand the **Templates** section. 1. Choose a project to act as the template repository. 1. Select **Save changes**. @@ -526,7 +536,8 @@ that belong to the group. To view the merge request approval settings for a group: -1. Go to the top-level group's **Settings > General** page. +1. On the top bar, select **Main menu > Groups > View all groups** and find your group. +1. On the left sidebar, select **Settings > General**. 1. Expand the **Merge request approvals** section. 1. Select the settings you want. 1. Select **Save changes**. @@ -549,7 +560,7 @@ Changes to [group wikis](../project/wiki/group.md) do not appear in group activi You can view the most recent actions taken in a group, either in your browser or in an RSS feed: -1. On the top bar, select **Menu > Groups**. +1. On the top bar, select **Main menu > Groups > View all groups**. 1. Select **Your Groups**. 1. Find the group and select it. 1. On the left sidebar, select **Group information > Activity**. diff --git a/doc/user/profile/account/create_accounts.md b/doc/user/profile/account/create_accounts.md index 694ed02a694..e3f7d47038d 100644 --- a/doc/user/profile/account/create_accounts.md +++ b/doc/user/profile/account/create_accounts.md @@ -33,7 +33,7 @@ Prerequisites: To create a user manually: -1. On the top bar, select **Menu > Admin**. +1. On the top bar, select **Main menu > Admin**. 1. On the left sidebar, select **Overview > Users** (`/admin/users`). 1. Select **New user**. 1. Complete the fields. diff --git a/doc/user/profile/account/delete_account.md b/doc/user/profile/account/delete_account.md index 5ec29814e06..d2e0c1ad834 100644 --- a/doc/user/profile/account/delete_account.md +++ b/doc/user/profile/account/delete_account.md @@ -28,7 +28,7 @@ As a user, to delete your own account: As an administrator, to delete a user account: -1. On the top bar, select **Menu > Admin**. +1. On the top bar, select **Main menu > Admin**. 1. On the left sidebar, select **Overview > Users**. 1. Select a user. 1. Under the **Account** tab, select: diff --git a/doc/user/profile/index.md b/doc/user/profile/index.md index f1f9783878d..ad67fe4bfd8 100644 --- a/doc/user/profile/index.md +++ b/doc/user/profile/index.md @@ -111,7 +111,7 @@ the README file with information, it's included on your profile page. To create a new project and add its README to your profile: -1. On the top bar, select **Menu > Project**. +1. On the top bar, select **Main menu > Projects**. 1. Select **Create new project**. 1. Select **Create blank project**. 1. Enter the project details: @@ -421,7 +421,7 @@ When you sign in to the main GitLab application, a `_gitlab_session` cookie is set. When you close your browser, the cookie is cleared client-side and it expires after a set duration. GitLab administrators can determine the duration: -1. On the top bar, select **Menu > Admin**. +1. On the top bar, select **Main menu > Admin**. 1. On the left sidebar, select **Settings > General**. 1. Expand **Account and limit**. The set duration is in **Session duration (minutes)**. diff --git a/doc/user/profile/notifications.md b/doc/user/profile/notifications.md index 0245f0615e0..1b737f14f68 100644 --- a/doc/user/profile/notifications.md +++ b/doc/user/profile/notifications.md @@ -108,7 +108,7 @@ To select a notification level for a group, use either of these methods: Or: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups** and find your group. 1. Select the notification dropdown, next to the bell icon (**{notifications}**). 1. Select the desired [notification level](#notification-levels). @@ -139,7 +139,7 @@ To select a notification level for a project, use either of these methods: Or: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. Select the notification dropdown, next to the bell icon (**{notifications}**). 1. Select the desired [notification level](#notification-levels). diff --git a/doc/user/project/issue_board.md b/doc/user/project/issue_board.md index 3e980717313..916d566bb20 100644 --- a/doc/user/project/issue_board.md +++ b/doc/user/project/issue_board.md @@ -618,6 +618,40 @@ into a different list. Learn about possible effects in [Dragging issues between To move a list, select its top bar, and drag it horizontally. You can't move the **Open** and **Closed** lists, but you can hide them when editing an issue board. +#### Move an issue to the start of the list + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/367473) in GitLab 15.4. + +You can move issues to the top of the list with a menu shortcut. + +Your issue is moved to the top of the list even if other issues are hidden by a filter. + +Prerequisites: + +- You must at least have the Reporter role for the project. + +To move an issue to the start of the list: + +1. In an issue board, hover over the card of the issue you want to move. +1. Select the vertical ellipsis (**{ellipsis_v}**), then **Move to start of list**. + +#### Move an issue to the end of the list + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/367473) in GitLab 15.4. + +You can move issues to the bottom of the list with a menu shortcut. + +Your issue is moved to the bottom of the list even if other issues are hidden by a filter. + +Prerequisites: + +- You must at least have the Reporter role for the project. + +To move an issue to the end of the list: + +1. In an issue board, hover over the card of the issue you want to move. +1. Select the vertical ellipsis (**{ellipsis_v}**), then **Move to end of list**. + #### Dragging issues between lists To move an issue to another list, select the issue card and drag it onto that list. diff --git a/doc/user/project/issues/managing_issues.md b/doc/user/project/issues/managing_issues.md index 1fe0b511551..4647631343b 100644 --- a/doc/user/project/issues/managing_issues.md +++ b/doc/user/project/issues/managing_issues.md @@ -33,7 +33,7 @@ Prerequisites: To create an issue: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. Either: - On the left sidebar, select **Issues**, and then, in the top right corner, select **New issue**. @@ -56,7 +56,7 @@ Prerequisites: To create an issue from a group: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups** and find your group. 1. On the left sidebar, select **Issues**. 1. In the top right corner, select **Select project to create issue**. 1. Select the project you'd like to create an issue for. The button now reflects the selected @@ -103,7 +103,7 @@ Prerequisites: To create an issue from a project issue board: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. Select **Issues > Boards**. 1. At the top of a board list, select **New issue** (**{plus-square}**). 1. Enter the issue's title. @@ -111,7 +111,7 @@ To create an issue from a project issue board: To create an issue from a group issue board: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups** and find your group. 1. Select **Issues > Boards**. 1. At the top of a board list, select **New issue** (**{plus-square}**). 1. Enter the issue's title. @@ -138,7 +138,7 @@ Prerequisites: To email an issue to a project: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. Select **Issues**. 1. At the bottom of the page, select **Email a new issue to this project**. 1. To copy the email address, select **Copy** (**{copy-to-clipboard}**). @@ -271,7 +271,7 @@ Prerequisites: To edit multiple issues at the same time: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Issues**. 1. Select **Edit issues**. A sidebar on the right of your screen appears. 1. Select the checkboxes next to each issue you want to edit. @@ -304,7 +304,7 @@ Prerequisites: To edit multiple issues at the same time: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups** and find your group. 1. On the left sidebar, select **Issues**. 1. Select **Edit issues**. A sidebar on the right of your screen appears. 1. Select the checkboxes next to each issue you want to edit. @@ -470,7 +470,7 @@ Prerequisites: To disable automatic issue closing: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Repository**. 1. Expand **Default branch**. 1. Clear the **Auto-close referenced issues on default branch** checkbox. @@ -598,7 +598,7 @@ GitLab displays the results on-screen, but you can also > [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/39908) in GitLab 12.1. -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Issues > List**. 1. In the **Search** box, type the issue ID. For example, enter filter `#10` to return only issue 10. diff --git a/doc/user/project/merge_requests/cherry_pick_changes.md b/doc/user/project/merge_requests/cherry_pick_changes.md index f238678b662..7d12fdac87a 100644 --- a/doc/user/project/merge_requests/cherry_pick_changes.md +++ b/doc/user/project/merge_requests/cherry_pick_changes.md @@ -51,7 +51,7 @@ Commit `G` is added after the cherry-pick. After a merge request is merged, you can cherry-pick all changes introduced by the merge request: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Merge requests**, and find your merge request. 1. Scroll to the merge request reports section, and find the **Merged by** report. 1. In the top right, select **Cherry-pick**: @@ -69,7 +69,7 @@ You can cherry-pick a single commit from multiple locations in your GitLab proje To cherry-pick a commit from the list of all commits for a project: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Repository > Commits**. 1. Select the title of the commit you want to cherry-pick. 1. In the modal window, select the project and branch to cherry-pick into. @@ -82,7 +82,7 @@ You can cherry-pick commits from any merge request in your project, regardless o whether the merge request is open or closed. To cherry-pick a commit from the list of commits included in a merge request: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Merge requests**, and find your merge request. 1. In the merge request's secondary menu, select **Commits** to display the commit details page. 1. Select the title of the commit you want to cherry-pick. @@ -96,7 +96,7 @@ list of commits included in a merge request: You can cherry-pick from the list of previous commits affecting an individual file when you view that file in your project's Git repository: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Repository > Files** and go to the file changed by the commit. 1. Select **History**, then select the title of the commit you want to cherry-pick. diff --git a/doc/user/project/merge_requests/commit_templates.md b/doc/user/project/merge_requests/commit_templates.md index 6b27ea4471c..99a1739b1a4 100644 --- a/doc/user/project/merge_requests/commit_templates.md +++ b/doc/user/project/merge_requests/commit_templates.md @@ -29,7 +29,7 @@ Prerequisite: To do this: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Merge requests**. 1. Depending on the type of template you want to create, scroll to either [**Merge commit message template**](#default-template-for-merge-commits) or diff --git a/doc/user/project/merge_requests/creating_merge_requests.md b/doc/user/project/merge_requests/creating_merge_requests.md index f30b20e9d34..232c951dd17 100644 --- a/doc/user/project/merge_requests/creating_merge_requests.md +++ b/doc/user/project/merge_requests/creating_merge_requests.md @@ -14,7 +14,7 @@ There are many different ways to create a merge request. You can create a merge request from the list of merge requests. -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left menu, select **Merge requests**. 1. In the top right, select **New merge request**. 1. Select a source and target branch and then **Compare branches and continue**. @@ -43,7 +43,7 @@ You can create a merge request when you add, edit, or upload a file to a reposit You can create a merge request when you create a branch. -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left menu, select **Repository > Branches**. 1. Type a branch name and select **New branch**. 1. Above the file list, on the right side, select **Create merge request**. @@ -90,7 +90,7 @@ to reduce the need for editing merge requests manually through the UI. You can create a merge request from your fork to contribute back to the main project. -1. On the top bar, select **Menu > Project**. +1. On the top bar, select **Main menu > Project**. 1. Select your fork of the repository. 1. On the left menu, go to **Merge requests**, and select **New merge request**. 1. In the **Source branch** drop-down list box, select the branch in your forked repository as the source branch. @@ -120,7 +120,7 @@ Prerequisites: To create a merge request by sending an email: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left menu, select **Merge requests**. 1. In the top right, select **Email a new merge request to this project**. An email address is displayed. Copy this address. @@ -165,7 +165,7 @@ scenarios when you create a new merge request: To have merge requests from a fork by default target your own fork (instead of the upstream project), you can change the default. -1. On the top bar, select **Menu > Project**. +1. On the top bar, select **Main menu > Project**. 1. On the left menu, select **Settings > General > Merge requests**. 1. In the **Target project** section, select the option you want to use for your default target project. diff --git a/doc/user/project/merge_requests/csv_export.md b/doc/user/project/merge_requests/csv_export.md index 954687212e7..f997898f5a5 100644 --- a/doc/user/project/merge_requests/csv_export.md +++ b/doc/user/project/merge_requests/csv_export.md @@ -12,7 +12,7 @@ Export all the data collected from a project's merge requests into a comma-separ To export merge requests to a CSV file: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Merge requests** . 1. Add any searches or filters. This can help you keep the size of the CSV file under the 15MB limit. The limit ensures the file can be emailed to a variety of email providers. diff --git a/doc/user/project/merge_requests/dependencies.md b/doc/user/project/merge_requests/dependencies.md index 0c481554401..5b88e69357c 100644 --- a/doc/user/project/merge_requests/dependencies.md +++ b/doc/user/project/merge_requests/dependencies.md @@ -57,7 +57,7 @@ information about the dependency: To view dependency information on a merge request: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Merge requests** and identify your merge request. 1. Scroll to the merge request reports area. Dependent merge requests display information about the total number of dependencies set, such as @@ -105,7 +105,7 @@ Prerequisite: To do this: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Merge requests** and identify your merge request. 1. Select **Edit**. 1. In **Merge request dependencies**, paste either the reference or the full URL @@ -120,7 +120,7 @@ Prerequisite: - You must have a role in the project that allows you to edit merge requests. -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Merge requests** and identify your merge request. 1. Select **Edit**. 1. Scroll to **Merge request dependencies** and select **Remove** next to the reference diff --git a/doc/user/project/merge_requests/index.md b/doc/user/project/merge_requests/index.md index 35ec075c674..ca40b724d95 100644 --- a/doc/user/project/merge_requests/index.md +++ b/doc/user/project/merge_requests/index.md @@ -27,7 +27,7 @@ You can view merge requests for your project, group, or yourself. To view all merge requests for a project: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Merge requests**. Or, to use a [keyboard shortcut](../../shortcuts.md), press <kbd>g</kbd> + <kbd>m</kbd>. @@ -36,7 +36,7 @@ Or, to use a [keyboard shortcut](../../shortcuts.md), press <kbd>g</kbd> + <kbd> To view merge requests for all projects in a group: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups** and find your group. 1. On the left sidebar, select **Merge requests**. If your group contains subgroups, this view also displays merge requests from the subgroup projects. @@ -166,7 +166,7 @@ To assign the merge request to someone else, use the `/assign @user` [quick action](../quick_actions.md#issues-merge-requests-and-epics) in a text area in a merge request, or: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Merge requests** and find your merge request. 1. On the right sidebar, expand the right sidebar and locate the **Assignees** section. 1. Select **Edit**. @@ -186,7 +186,7 @@ accountable for it: To assign multiple assignees to a merge request, use the `/assign @user` [quick action](../quick_actions.md#issues-merge-requests-and-epics) in a text area, or: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Merge requests** and find your merge request. 1. On the right sidebar, expand the right sidebar and locate the **Assignees** section. 1. Select **Edit** and, from the dropdown list, select all users you want diff --git a/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md b/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md index 6aac57ad144..57c4ff455cb 100644 --- a/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md +++ b/doc/user/project/merge_requests/merge_when_pipeline_succeeds.md @@ -34,7 +34,7 @@ To do this when pushing from the command line, use the `merge_request.merge_when To do this from the GitLab user interface: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Merge requests**. 1. Scroll to the merge request reports section. 1. Optional. Select your desired merge options, such as **Delete source branch**, @@ -57,7 +57,7 @@ Prerequisites: To do this: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Merge requests**. 1. Scroll to the merge request reports section. 1. Select **Cancel auto-merge**. @@ -83,7 +83,7 @@ Prerequisites: To enable this setting: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Merge requests**. 1. Scroll to **Merge checks**, and select **Pipelines must succeed**. This setting also prevents merge requests from being merged if there is no pipeline, @@ -104,7 +104,7 @@ Prerequisite: To change this behavior: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > General**. 1. Expand **Merge requests**. 1. Under **Merge checks**: diff --git a/doc/user/project/merge_requests/methods/index.md b/doc/user/project/merge_requests/methods/index.md index 02a784a321c..68dd6477408 100644 --- a/doc/user/project/merge_requests/methods/index.md +++ b/doc/user/project/merge_requests/methods/index.md @@ -12,7 +12,7 @@ merge requests are merged into an existing branch. ## Configure a project's merge method -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Merge requests**. 1. In the **Merge method** section, select your desired merge method. 1. Select **Save changes**. diff --git a/doc/user/project/merge_requests/revert_changes.md b/doc/user/project/merge_requests/revert_changes.md index bee7ed2cc02..a6e0740ff78 100644 --- a/doc/user/project/merge_requests/revert_changes.md +++ b/doc/user/project/merge_requests/revert_changes.md @@ -30,7 +30,7 @@ Prerequisites: To do this: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Merge requests** and identify your merge request. 1. Scroll to the merge request reports area, and find the report showing when the merge request was merged. @@ -55,7 +55,7 @@ Prerequisites: To do this: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. If you know the merge request that contains the commit: 1. On the left sidebar, select **Merge requests** and identify your merge request. 1. Select **Commits**, then select the title of the commit you want to revert. GitLab displays the contents of the commit. diff --git a/doc/user/project/merge_requests/squash_and_merge.md b/doc/user/project/merge_requests/squash_and_merge.md index e113dcfdb58..066149afbb5 100644 --- a/doc/user/project/merge_requests/squash_and_merge.md +++ b/doc/user/project/merge_requests/squash_and_merge.md @@ -60,7 +60,7 @@ squash the commits as part of the merge process: To configure the default squashing behavior for all merge requests in your project: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Merge requests**. 1. In the **Squash commits when merging** section, select your desired behavior: - **Do not allow**: Squashing is never performed, and the option is not displayed. diff --git a/doc/user/project/milestones/index.md b/doc/user/project/milestones/index.md index 61b4b311e96..723ca17ee56 100644 --- a/doc/user/project/milestones/index.md +++ b/doc/user/project/milestones/index.md @@ -37,8 +37,8 @@ For information about project and group milestones API, see: To view the milestone list: -1. On the top bar, select **Menu > Projects** and find your project or - **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Projects** and find your project or + **Main menu > Groups** and find your group. 1. Select **Issues > Milestones**. In a project, GitLab displays milestones that belong to the project. @@ -66,7 +66,7 @@ Improving this experience is tracked in issue [339009](https://gitlab.com/gitlab You can view all the milestones you have access to in the entire GitLab namespace. You might not see some milestones because they're in projects or groups you're not a member of. -To do so, on the top bar select **Menu > Milestones**. +To do so, on the top bar select **Main menu > Milestones**. ### View milestone details @@ -119,7 +119,7 @@ Prerequisites: To create a milestone: -1. On the top bar, select **Menu > Projects** and find your project or **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Projects** and find your project or **Main menu > Groups** and find your group. 1. On the left sidebar, select **Issues > Milestones**. 1. Select **New milestone**. 1. Enter the title. @@ -138,7 +138,7 @@ Prerequisites: To edit a milestone: -1. On the top bar, select **Menu > Projects** and find your project or **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Projects** and find your project or **Main menu > Groups** and find your group. 1. Select a milestone's title. 1. Select **Edit**. 1. Edit the title, start date, due date, or description. @@ -154,7 +154,7 @@ Prerequisites: To edit a milestone: -1. On the top bar, select **Menu > Projects** and find your project or **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Projects** and find your project or **Main menu > Groups** and find your group. 1. Select a milestone's title. 1. Select **Delete**. 1. Select **Delete milestone**. @@ -179,7 +179,7 @@ Prerequisites: To promote a project milestone: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. Either: - Select **Promote to Group Milestone** (**{level-up}**). - Select the milestone title, and then select **Promote**. diff --git a/doc/user/project/repository/branches/default.md b/doc/user/project/repository/branches/default.md index 3083ca5da3c..d31c64f4640 100644 --- a/doc/user/project/repository/branches/default.md +++ b/doc/user/project/repository/branches/default.md @@ -64,7 +64,7 @@ GitLab [administrators](../../../permissions.md) of self-managed instances can customize the initial branch for projects hosted on that instance. Individual groups and subgroups can override this instance-wide setting for their projects. -1. On the top bar, select **Menu > Admin**. +1. On the top bar, select **Main menu > Admin**. 1. On the left sidebar, select **Settings > Repository**. 1. Expand **Default initial branch name**. 1. Change the default initial branch to a custom name of your choice. @@ -115,7 +115,7 @@ you must either: Administrators of self-managed instances can customize the initial default branch protection for projects hosted on that instance. Individual groups and subgroups can override this instance-wide setting for their projects. -1. On the top bar, select **Menu > Admin**. +1. On the top bar, select **Main menu > Admin**. 1. On the left sidebar, select **Settings > Repository**. 1. Expand **Default branch**. 1. Select [**Initial default branch protection**](#protect-initial-default-branches). @@ -132,7 +132,7 @@ can be overridden on a per-group basis by the group's owner. In [GitLab Premium or higher](https://about.gitlab.com/pricing/), GitLab administrators can disable this privilege for group owners, enforcing the instance-level protection rule: -1. On the top bar, select **Menu > Admin**. +1. On the top bar, select **Main menu > Admin**. 1. On the left sidebar, select **Settings > Repository**. 1. Expand the **Default branch** section. 1. Clear the **Allow owners to manage default branch protection per group** checkbox. @@ -152,7 +152,7 @@ can be overridden on a per-group basis by the group's owner. In [enforce protection of initial default branches](#prevent-overrides-of-default-branch-protection) which locks this setting for group owners. -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups** and find your group. 1. On the left sidebar, select **Settings > Repository**. 1. Expand **Default branch**. 1. Select [**Initial default branch protection**](#protect-initial-default-branches). diff --git a/doc/user/project/repository/gpg_signed_commits/index.md b/doc/user/project/repository/gpg_signed_commits/index.md index b2a6c8848ce..d307a6a8580 100644 --- a/doc/user/project/repository/gpg_signed_commits/index.md +++ b/doc/user/project/repository/gpg_signed_commits/index.md @@ -193,10 +193,10 @@ you can sign individual commits manually, or configure Git to default to signed You can review commits for a merge request, or for an entire project: 1. To review commits for a project: - 1. On the top bar, select **Menu > Projects** and find your project. + 1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Repository > Commits**. 1. To review commits for a merge request: - 1. On the top bar, select **Menu > Projects** and find your project. + 1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Merge requests**, then select your merge request. 1. Select **Commits**. 1. Identify the commit you want to review. Signed commits show either a **Verified** diff --git a/doc/user/project/repository/mirror/bidirectional.md b/doc/user/project/repository/mirror/bidirectional.md index 340d7b48a47..793ca2a5f1f 100644 --- a/doc/user/project/repository/mirror/bidirectional.md +++ b/doc/user/project/repository/mirror/bidirectional.md @@ -45,7 +45,7 @@ and [pull](pull.md#pull-from-a-remote-repository) mirrors in the upstream GitLab To create the webhook in the downstream instance: 1. Create a [personal access token](../../../profile/personal_access_tokens.md) with `API` scope. -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Webhooks**. 1. Add the webhook **URL**, which (in this case) uses the [Pull Mirror API](../../../../api/projects.md#start-the-pull-mirroring-process-for-a-project) diff --git a/doc/user/project/repository/mirror/index.md b/doc/user/project/repository/mirror/index.md index b08530c34b3..176461aeba7 100644 --- a/doc/user/project/repository/mirror/index.md +++ b/doc/user/project/repository/mirror/index.md @@ -41,7 +41,7 @@ Prerequisite: - If your mirror connects with `ssh://`, the host key must be detectable on the server, or you must have a local copy of the key. -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Repository**. 1. Expand **Mirroring repositories**. 1. Enter a **Git repository URL**. For security reasons, the URL to the original @@ -89,7 +89,7 @@ Prerequisite: - You must have at least the Maintainer role for the project. -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Repository**. 1. Expand **Mirroring repositories**. 1. Scroll to **Mirrored repositories** and identify the mirror to update. @@ -141,7 +141,7 @@ When you mirror a repository and select the **SSH public key** as your authentication method, GitLab generates a public key for you. The non-GitLab server needs this key to establish trust with your GitLab repository. To copy your SSH public key: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Repository**. 1. Expand **Mirroring repositories**. 1. Scroll to **Mirrored repositories**. @@ -249,7 +249,7 @@ If you receive this error after creating a new project using Check if the repository owner is specified in the URL of your mirrored repository: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Repository**. 1. Expand **Mirroring repositories**. 1. If no repository owner is specified, delete and add the URL again in this format, diff --git a/doc/user/project/repository/mirror/pull.md b/doc/user/project/repository/mirror/pull.md index d0f2b9a8088..159580dcfa5 100644 --- a/doc/user/project/repository/mirror/pull.md +++ b/doc/user/project/repository/mirror/pull.md @@ -61,7 +61,7 @@ Prerequisite: with the `repo` scope. If 2FA is enabled, this personal access token serves as your GitHub password. -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Repository**. 1. Expand **Mirroring repositories**. 1. Enter the **Git repository URL**. Include the username diff --git a/doc/user/project/repository/mirror/push.md b/doc/user/project/repository/mirror/push.md index c00ebf415c9..10bdc54ecee 100644 --- a/doc/user/project/repository/mirror/push.md +++ b/doc/user/project/repository/mirror/push.md @@ -33,7 +33,7 @@ section. To set up push mirroring for an existing project: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Repository**. 1. Expand **Mirroring repositories**. 1. Enter a repository URL. diff --git a/doc/user/project/repository/push_rules.md b/doc/user/project/repository/push_rules.md index 46a9585604e..90d2fdb89d0 100644 --- a/doc/user/project/repository/push_rules.md +++ b/doc/user/project/repository/push_rules.md @@ -36,7 +36,7 @@ Prerequisite: To create global push rules: -1. On the top bar, select **Menu > Admin**. +1. On the top bar, select **Main menu > Admin**. 1. On the left sidebar, select **Push Rules**. 1. Expand **Push rules**. 1. Set the rule you want. @@ -48,7 +48,7 @@ The push rule of an individual project overrides the global push rule. To override global push rules for a specific project, or to update the rules for an existing project to match new global push rules: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Repository**. 1. Expand **Push rules**. 1. Set the rule you want. diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md index 900e2bd1ca9..dd5cc6b89ff 100644 --- a/doc/user/project/settings/index.md +++ b/doc/user/project/settings/index.md @@ -13,7 +13,7 @@ Use the **Settings** page to manage the configuration options in your [project]( You must have at least the Maintainer role to view project settings. -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects > View all projects** and find your project. 1. On the left sidebar, select **Settings > General**. 1. To display all settings in a section, select **Expand**. 1. Optional. Use the search box to find a setting. @@ -23,7 +23,7 @@ You must have at least the Maintainer role to view project settings. Use the project general settings to edit your project details. 1. Sign in to GitLab with at least the Maintainer role. -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects > View all projects** and find your project. 1. On the left sidebar, select **Settings > General**. 1. In the **Project name** text box, enter your project name. 1. In the **Project description** text box, enter your project description. @@ -35,7 +35,7 @@ Use topics to categorize projects and find similar new projects. To assign topics to a project: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects > View all projects** and find your project. 1. On the left sidebar, select **Settings** > **General**. 1. In the **Topics** text box, enter the project topics. Popular topics are suggested as you type. 1. Select **Save changes**. @@ -226,7 +226,7 @@ This alternative ensures the compliance pipeline does not re-start the parent pi To configure visibility, features, and permissions for a project: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects > View all projects** and find your project. 1. On the left sidebar, select **Settings > General**. 1. Expand the **Visibility, project features, permissions** section. 1. To change the project visibility, select the dropdown list. If you select to **Public**, you limit access to some features to **Only Project Members**. @@ -286,7 +286,7 @@ In some environments, users can submit a [CVE identifier request](../../applicat To disable the CVE identifier request option in issues in your project: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects > View all projects** and find your project. 1. On the left sidebar, select **Settings > General**. 1. Expand the **Visibility, project features, permissions** section. 1. Under **Issues**, turn off the **CVE ID requests in the issue sidebar** toggle. @@ -298,7 +298,7 @@ Prerequisites: - You must be an Owner of the project to disable email notifications related to the project. -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects > View all projects** and find your project. 1. On the left sidebar, select **Settings > General**. 1. Expand the **Visibility, project features, permissions** section. 1. Clear the **Disable email notifications** checkbox. @@ -339,7 +339,7 @@ other features are read-only. Archived projects are also hidden from project lis To archive a project: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects > View all projects** and find your project. 1. On the left sidebar, select **Settings > General**. 1. Expand **Advanced**. 1. In the **Archive project** section, select **Archive project**. @@ -355,7 +355,7 @@ Prerequisites: - To unarchive a project, you must be an administrator or a project Owner. 1. Find the archived project. - 1. On the top bar, select **Menu > Project**. + 1. On the top bar, select **Main menu > Projects > View all projects**. 1. Select **Explore projects**. 1. In the **Sort projects** dropdown list, select **Show archived projects**. 1. In the **Filter by name** field, enter the project name. @@ -380,7 +380,7 @@ When you change the repository path, users may experience issues if they push to To rename a repository: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects > View all projects** and find your project. 1. On the left sidebar, select **Settings > General**. 1. Expand the **Advanced** section. 1. In the **Change path** text box, edit the path. @@ -402,7 +402,7 @@ Prerequisites: To transfer a project: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects > View all projects** and find your project. 1. On the left sidebar, select **Settings > General**. 1. Expand **Advanced**. 1. Under **Transfer project**, choose the namespace to transfer the project to. @@ -433,7 +433,7 @@ Prerequisite: To delete a project: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects > View all projects** and find your project. 1. On the left sidebar, select **Settings > General**. 1. Expand **Advanced**. 1. In the "Delete project" section, select **Delete project**. @@ -472,7 +472,7 @@ Prerequisites: To immediately delete a project marked for deletion: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects > View all projects** and find your project. 1. On the left sidebar, select **Settings > General**. 1. Expand **Advanced**. 1. In the "Permanently delete project" section, select **Delete project**. @@ -504,7 +504,7 @@ To restore the fork relationship, [use the API](../../../api/projects.md#create- To remove a fork relationship: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects > View all projects** and find your project. 1. On the left sidebar, select **Settings > General**. 1. Expand **Advanced**. 1. In the **Remove fork relationship** section, select **Remove fork relationship**. diff --git a/doc/user/project/web_ide/index.md b/doc/user/project/web_ide/index.md index 5a4e300a210..2a197c733cf 100644 --- a/doc/user/project/web_ide/index.md +++ b/doc/user/project/web_ide/index.md @@ -260,7 +260,7 @@ a `main` entry point inside the Web IDE. Live Preview is enabled for all projects on GitLab.com. If you are an administrator of a self-managed GitLab instance, and you want to enable Live Preview: -1. On the top bar, select **Menu > Admin**. +1. On the top bar, select **Main menu > Admin**. 1. On the left sidebar, select **Settings > General**. 1. Scroll to **Web IDE** and select **Expand**: ![Administrator Live Preview setting](img/admin_live_preview_v13_0.png) diff --git a/doc/user/project/wiki/group.md b/doc/user/project/wiki/group.md index a3ba5789d39..03838a62d59 100644 --- a/doc/user/project/wiki/group.md +++ b/doc/user/project/wiki/group.md @@ -29,7 +29,7 @@ and higher can edit group wikis. Group wiki repositories can be moved using the To access a group wiki: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups** and find your group. 1. To display the wiki, either: - On the left sidebar, select **Wiki**. - On any page in the project, use the <kbd>g</kbd> + <kbd>w</kbd> @@ -69,7 +69,7 @@ can enable or disable a group wiki through the group settings. To open group settings: -1. On the top bar, select **Menu > Groups** and find your group. +1. On the top bar, select **Main menu > Groups** and find your group. 1. On the left sidebar, select **Settings > General**. 1. Expand **Permissions and group features**. 1. Scroll to **Wiki** and select one of these options: diff --git a/doc/user/project/wiki/index.md b/doc/user/project/wiki/index.md index c7f675417bb..dbb4c0ce097 100644 --- a/doc/user/project/wiki/index.md +++ b/doc/user/project/wiki/index.md @@ -31,7 +31,7 @@ with sibling pages listed in alphabetical order. To view a list of all pages, se To access a project wiki: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. To display the wiki, either: - On the left sidebar, select **Wiki**. - On any page in the project, use the <kbd>g</kbd> + <kbd>w</kbd> @@ -284,7 +284,7 @@ You can disable group wikis from the [group settings](group.md#configure-group-w To add a link to an external wiki from a project's left sidebar: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Integrations**. 1. Select **External wiki**. 1. Add the URL to your external wiki. @@ -300,7 +300,7 @@ To hide the internal wiki from the sidebar, [disable the project's wiki](#disabl To hide the link to an external wiki: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Settings > Integrations**. 1. Select **External wiki**. 1. In the **Enable integration** section, clear the **Active** checkbox. @@ -310,7 +310,7 @@ To hide the link to an external wiki: To disable a project's internal wiki: -1. On the top bar, select **Menu > Projects** and find your project. +1. On the top bar, select **Main menu > Projects** and find your project. 1. Go to your project and select **Settings > General**. 1. Expand **Visibility, project features, permissions**. 1. Scroll down to find **Wiki** and toggle it off (in gray). diff --git a/doc/user/project/working_with_projects.md b/doc/user/project/working_with_projects.md index 2501fa8b45c..ee85c079f04 100644 --- a/doc/user/project/working_with_projects.md +++ b/doc/user/project/working_with_projects.md @@ -11,22 +11,9 @@ code are saved in projects, and most features are in the scope of projects. ## View projects -To explore projects: +To view projects, on the top bar, select **Main menu > Projects > View all projects**. -1. On the top bar, select **Menu > Projects**. -1. Select **Explore projects**. - -The **Projects** page shows a list of projects, sorted by last updated date. - -- To view projects with the most [stars](#star-a-project), select **Most stars**. -- To view projects with the largest number of comments in the past month, select **Trending**. - -NOTE: -The **Explore projects** tab is visible to unauthenticated users unless the -[**Public** visibility level](../admin_area/settings/visibility_and_access_controls.md#restrict-visibility-levels) -is restricted. Then the tab is visible only to signed-in users. - -### Who can view the **Projects** page +### Who can view the Projects page When you select a project, the project landing page shows the project contents. @@ -53,11 +40,16 @@ visit the `/projects/:id` URL in your browser or other tool accessing the projec To explore project topics: -1. On the top bar, select **Menu > Projects**. -1. Select **Explore topics**. +1. On the top bar, select **Main menu > Projects > View all projects**. +1. Select the **Explore topics** tab. +1. To view projects associated with a topic, select a topic. + +The **Explore topics** tab shows a list of topics sorted by the number of associated projects. -The **Projects** page shows list of topics sorted by the number of associated projects. -To view projects associated with a topic, select a topic from the list. +NOTE: +The **Explore projects** tab is visible to unauthenticated users unless the +[**Public** visibility level](../admin_area/settings/visibility_and_access_controls.md#restrict-visibility-levels) +is restricted. Then the tab is visible only to signed-in users. You can assign topics to a project on the [Project Settings page](settings/index.md#assign-topics-to-a-project). @@ -68,8 +60,9 @@ If you're an instance administrator, you can administer all project topics from To create a project in GitLab: -1. On the top bar, select **Menu > Project > Create new project**. -1. On the **Create new project** page, choose if you want to: +1. On the top bar, select **Main menu > Projects > View all projects**. +1. On the right of the page, select **New project**. +1. On the **Create new project** page, select an option: - Create a [blank project](#create-a-blank-project). - Create a project from a: - [built-in template](#create-a-project-from-a-built-in-template). @@ -88,7 +81,8 @@ To create a project in GitLab: To create a blank project: -1. On the top bar, select **Menu > Projects > Create new project**. +1. On the top bar, select **Main menu > Projects > View all projects**. +1. On the right of the page, select **New project**. 1. Select **Create blank project**. 1. Enter the project details: - In the **Project name** field, enter the name of your project. You cannot use special characters at @@ -119,7 +113,8 @@ Anyone can [contribute a built-in template](../../development/project_templates. To create a project from a built-in template: -1. On the top bar, select **Menu > Projects > Create new project**. +1. On the top bar, select **Main menu > Projects > View all projects**. +1. On the right of the page, select **New project**. 1. Select **Create from template**. 1. Select the **Built-in** tab. 1. From the list of templates: @@ -145,7 +140,8 @@ Custom project templates are available at: - The [instance-level](../../user/admin_area/custom_project_templates.md) - The [group-level](../../user/group/custom_project_templates.md) -1. On the top bar, select **Menu > Projects > Create new project**. +1. On the top bar, select **Main menu > Projects > View all projects**. +1. On the right of the page, select **New project**. 1. Select **Create from template**. 1. Select the **Instance** or **Group** tab. 1. From the list of templates: @@ -171,7 +167,8 @@ HIPAA Audit Protocol published by the U.S Department of Health and Human Service To create a project from the HIPAA Audit Protocol template: -1. On the top bar, select **Menu > Projects > Create new project**. +1. On the top bar, select **Main menu > Projects > View all projects**. +1. On the right of the page, select **New project**. 1. Select **Create from template**. 1. Select the **Built-in** tab. 1. Locate the **HIPAA Audit Protocol** template: @@ -210,8 +207,7 @@ Prerequisites: [added to your GitLab account](../ssh.md#add-an-ssh-key-to-your-gitlab-account). - You must have permission to add new projects to a namespace. To check if you have permission: - 1. On the top bar, select **Menu > Projects**. - 1. Select **Groups**. + 1. On the top bar, select **Main menu > Groups > View all groups**. 1. Select a group. 1. Confirm that **New project** is visible in the upper right corner. Contact your GitLab @@ -258,15 +254,14 @@ You can add a star to projects you use frequently to make them easier to find. To add a star to a project: -1. On the top bar, select **Menu > Projects**. -1. Select **Your projects** or **Explore projects**. +1. On the top bar, select **Main menu > Projects > View all projects**. 1. Select a project. 1. In the upper right corner of the page, select **Star**. ## View starred projects -1. On the top bar, select **Menu > Projects**. -1. Select **Starred projects**. +1. On the top bar, select **Main menu > Projects > View all projects**. +1. Select the **Starred projects** tab. 1. GitLab displays information about your starred projects, including: - Project description, including name, description, and icon. @@ -284,7 +279,7 @@ called `my-project` under your username, the project is created at `https://gitl To view your personal projects: -1. On the top bar, select **Menu > Projects > Your Projects**. +1. On the top bar, select **Main menu > Projects > View all projects**. 1. Under **Your projects**, select **Personal**. ## Delete a project @@ -294,8 +289,7 @@ you can [enable delayed project removal](../group/manage.md#enable-delayed-proje To delete a project: -1. On the top bar, select **Menu > Projects**. -1. Select **Your projects** or **Explore projects**. +1. On the top bar, select **Main menu > Projects > View all projects**. 1. Select a project. 1. Select **Settings > General**. 1. Expand the **Advanced** section. @@ -315,7 +309,7 @@ projects within that group are not deleted immediately, but only after a delay. To view a list of all projects that are pending deletion: -1. On the top bar, select **Menu > Projects > Explore projects**. +1. On the top bar, select **Main menu > Projects > View all projects**. 1. Based on your GitLab version: - GitLab 14.6 and later: select the **Pending deletion** tab. - GitLab 14.5 and earlier: select the **Deleted projects** tab. @@ -330,8 +324,7 @@ Each project in the list shows: To view the activity of a project: -1. On the top bar, select **Menu > Projects**. -1. Select **Your projects** or **Explore projects**. +1. On the top bar, select **Main menu > Projects > View all projects**. 1. Select a project. 1. On the left sidebar, select **Project information > Activity**. 1. Select a tab to view the type of project activity. @@ -366,8 +359,7 @@ member and cannot contribute. To leave a project: -1. On the top bar, select **Menu > Projects**. -1. Select **Your projects** or **Explore projects**. +1. On the top bar, select **Main menu > Projects > View all projects**. 1. Select a project. 1. Select **Leave project**. The **Leave project** option only displays on the project dashboard when a project is part of a group under a diff --git a/doc/user/usage_quotas.md b/doc/user/usage_quotas.md index 56220fb9906..1f3a69944e8 100644 --- a/doc/user/usage_quotas.md +++ b/doc/user/usage_quotas.md @@ -61,7 +61,7 @@ Prerequisites: - To view storage usage for a namespace, you must have the Owner role for the namespace. 1. Go to your project or namespace: - - For a project, on the top bar, select **Menu > Projects** and find your project. + - For a project, on the top bar, select **Main menu > Projects > View all projects** and find your project. - For a namespace, enter the URL in your browser's toolbar. 1. From the left sidebar, select **Settings > Usage Quotas**. 1. Select the **Storage** tab. diff --git a/lib/gitlab/base_doorkeeper_controller.rb b/lib/gitlab/base_doorkeeper_controller.rb index 81b01395542..c8520993b8e 100644 --- a/lib/gitlab/base_doorkeeper_controller.rb +++ b/lib/gitlab/base_doorkeeper_controller.rb @@ -3,6 +3,7 @@ # This is a base controller for doorkeeper. # It adds the `can?` helper used in the views. module Gitlab + # rubocop:disable Rails/ApplicationController class BaseDoorkeeperController < ActionController::Base include Gitlab::Allowable include EnforcesTwoFactorAuthentication @@ -12,4 +13,5 @@ module Gitlab helper_method :can? end + # rubocop:enable Rails/ApplicationController end diff --git a/lib/gitlab/ci/parsers/security/validators/schema_validator.rb b/lib/gitlab/ci/parsers/security/validators/schema_validator.rb index d776b6060d5..28d6620e5c4 100644 --- a/lib/gitlab/ci/parsers/security/validators/schema_validator.rb +++ b/lib/gitlab/ci/parsers/security/validators/schema_validator.rb @@ -7,14 +7,14 @@ module Gitlab module Validators class SchemaValidator SUPPORTED_VERSIONS = { - cluster_image_scanning: %w[14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3], - container_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3], - coverage_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3], - dast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3], - api_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3], - dependency_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3], - sast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3], - secret_detection: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3] + cluster_image_scanning: %w[14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0], + container_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0], + coverage_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0], + dast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0], + api_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0], + dependency_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0], + sast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0], + secret_detection: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3 15.0.0] }.freeze VERSIONS_TO_REMOVE_IN_16_0 = [].freeze diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/cluster-image-scanning-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/cluster-image-scanning-report-format.json new file mode 100644 index 00000000000..7ccb39a2b8e --- /dev/null +++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/cluster-image-scanning-report-format.json @@ -0,0 +1,946 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/cluster-image-scanning-report-format.json", + "title": "Report format for GitLab Cluster Image Scanning", + "description": "This schema provides the the report format for Cluster Image Scanning (https://docs.gitlab.com/ee/user/application_security/cluster_image_scanning/).", + "definitions": { + "detail_type": { + "oneOf": [ + { + "$ref": "#/definitions/named_list" + }, + { + "$ref": "#/definitions/list" + }, + { + "$ref": "#/definitions/table" + }, + { + "$ref": "#/definitions/text" + }, + { + "$ref": "#/definitions/url" + }, + { + "$ref": "#/definitions/code" + }, + { + "$ref": "#/definitions/value" + }, + { + "$ref": "#/definitions/diff" + }, + { + "$ref": "#/definitions/markdown" + }, + { + "$ref": "#/definitions/commit" + }, + { + "$ref": "#/definitions/file_location" + }, + { + "$ref": "#/definitions/module_location" + } + ] + }, + "text_value": { + "type": "string" + }, + "named_field": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "$ref": "#/definitions/text_value", + "minLength": 1 + }, + "description": { + "$ref": "#/definitions/text_value" + } + } + }, + "named_list": { + "type": "object", + "description": "An object with named and typed fields", + "required": [ + "type", + "items" + ], + "properties": { + "type": { + "const": "named-list" + }, + "items": { + "type": "object", + "patternProperties": { + "^.*$": { + "allOf": [ + { + "$ref": "#/definitions/named_field" + }, + { + "$ref": "#/definitions/detail_type" + } + ] + } + } + } + } + }, + "list": { + "type": "object", + "description": "A list of typed fields", + "required": [ + "type", + "items" + ], + "properties": { + "type": { + "const": "list" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + } + } + }, + "table": { + "type": "object", + "description": "A table of typed fields", + "required": [ + "type", + "rows" + ], + "properties": { + "type": { + "const": "table" + }, + "header": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + }, + "rows": { + "type": "array", + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + } + } + } + }, + "text": { + "type": "object", + "description": "Raw text", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "text" + }, + "value": { + "$ref": "#/definitions/text_value" + } + } + }, + "url": { + "type": "object", + "description": "A single URL", + "required": [ + "type", + "href" + ], + "properties": { + "type": { + "const": "url" + }, + "text": { + "$ref": "#/definitions/text_value" + }, + "href": { + "type": "string", + "minLength": 1, + "examples": [ + "http://mysite.com" + ] + } + } + }, + "code": { + "type": "object", + "description": "A codeblock", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "code" + }, + "value": { + "type": "string" + }, + "lang": { + "type": "string", + "description": "A programming language" + } + } + }, + "value": { + "type": "object", + "description": "A field that can store a range of types of value", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "value" + }, + "value": { + "type": [ + "number", + "string", + "boolean" + ] + } + } + }, + "diff": { + "type": "object", + "description": "A diff", + "required": [ + "type", + "before", + "after" + ], + "properties": { + "type": { + "const": "diff" + }, + "before": { + "type": "string" + }, + "after": { + "type": "string" + } + } + }, + "markdown": { + "type": "object", + "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "markdown" + }, + "value": { + "$ref": "#/definitions/text_value", + "examples": [ + "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)" + ] + } + } + }, + "commit": { + "type": "object", + "description": "A commit/tag/branch within the GitLab project", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "commit" + }, + "value": { + "type": "string", + "description": "The commit SHA", + "minLength": 1 + } + } + }, + "file_location": { + "type": "object", + "description": "A location within a file in the project", + "required": [ + "type", + "file_name", + "line_start" + ], + "properties": { + "type": { + "const": "file-location" + }, + "file_name": { + "type": "string", + "minLength": 1 + }, + "line_start": { + "type": "integer" + }, + "line_end": { + "type": "integer" + } + } + }, + "module_location": { + "type": "object", + "description": "A location within a binary module of the form module+relative_offset", + "required": [ + "type", + "module_name", + "offset" + ], + "properties": { + "type": { + "const": "module-location" + }, + "module_name": { + "type": "string", + "minLength": 1, + "examples": [ + "compiled_binary" + ] + }, + "offset": { + "type": "integer", + "examples": [ + 100 + ] + } + } + } + }, + "self": { + "version": "15.0.0" + }, + "required": [ + "scan", + "version", + "vulnerabilities" + ], + "additionalProperties": true, + "properties": { + "scan": { + "type": "object", + "required": [ + "analyzer", + "end_time", + "scanner", + "start_time", + "status", + "type" + ], + "properties": { + "end_time": { + "type": "string", + "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$", + "examples": [ + "2020-01-28T03:26:02" + ] + }, + "messages": { + "type": "array", + "items": { + "type": "object", + "description": "Communication intended for the initiator of a scan.", + "required": [ + "level", + "value" + ], + "properties": { + "level": { + "type": "string", + "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.", + "enum": [ + "info", + "warn", + "fatal" + ], + "examples": [ + "info" + ] + }, + "value": { + "type": "string", + "description": "The message to communicate.", + "minLength": 1, + "examples": [ + "Permission denied, scanning aborted" + ] + } + } + } + }, + "analyzer": { + "type": "object", + "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.", + "required": [ + "id", + "name", + "version", + "vendor" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique id that identifies the analyzer.", + "minLength": 1, + "examples": [ + "gitlab-dast" + ] + }, + "name": { + "type": "string", + "description": "A human readable value that identifies the analyzer, not required to be unique.", + "minLength": 1, + "examples": [ + "GitLab DAST" + ] + }, + "url": { + "type": "string", + "pattern": "^https?://.+", + "description": "A link to more information about the analyzer.", + "examples": [ + "https://docs.gitlab.com/ee/user/application_security/dast" + ] + }, + "vendor": { + "description": "The vendor/maintainer of the analyzer.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "The name of the vendor.", + "minLength": 1, + "examples": [ + "GitLab" + ] + } + } + }, + "version": { + "type": "string", + "description": "The version of the analyzer.", + "minLength": 1, + "examples": [ + "1.0.2" + ] + } + } + }, + "scanner": { + "type": "object", + "description": "Object defining the scanner used to perform the scan.", + "required": [ + "id", + "name", + "version", + "vendor" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique id that identifies the scanner.", + "minLength": 1, + "examples": [ + "my-sast-scanner" + ] + }, + "name": { + "type": "string", + "description": "A human readable value that identifies the scanner, not required to be unique.", + "minLength": 1, + "examples": [ + "My SAST Scanner" + ] + }, + "url": { + "type": "string", + "description": "A link to more information about the scanner.", + "examples": [ + "https://scanner.url" + ] + }, + "version": { + "type": "string", + "description": "The version of the scanner.", + "minLength": 1, + "examples": [ + "1.0.2" + ] + }, + "vendor": { + "description": "The vendor/maintainer of the scanner.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "The name of the vendor.", + "minLength": 1, + "examples": [ + "GitLab" + ] + } + } + } + } + }, + "start_time": { + "type": "string", + "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$", + "examples": [ + "2020-02-14T16:01:59" + ] + }, + "status": { + "type": "string", + "description": "Result of the scan.", + "enum": [ + "success", + "failure" + ] + }, + "type": { + "type": "string", + "description": "Type of the scan.", + "enum": [ + "cluster_image_scanning" + ] + } + } + }, + "schema": { + "type": "string", + "description": "URI pointing to the validating security report schema.", + "pattern": "^https?://.+" + }, + "version": { + "type": "string", + "description": "The version of the schema to which the JSON report conforms.", + "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" + }, + "vulnerabilities": { + "type": "array", + "description": "Array of vulnerability objects.", + "items": { + "type": "object", + "description": "Describes the vulnerability using GitLab Flavored Markdown", + "required": [ + "id", + "identifiers", + "location" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.", + "examples": [ + "642735a5-1425-428d-8d4e-3c854885a3c9" + ] + }, + "name": { + "type": "string", + "maxLength": 255, + "description": "The name of the vulnerability. This must not include the finding's specific information." + }, + "description": { + "type": "string", + "maxLength": 1048576, + "description": "A long text section describing the vulnerability more fully." + }, + "severity": { + "type": "string", + "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.", + "enum": [ + "Info", + "Unknown", + "Low", + "Medium", + "High", + "Critical" + ] + }, + "solution": { + "type": "string", + "maxLength": 7000, + "description": "Explanation of how to fix the vulnerability." + }, + "identifiers": { + "type": "array", + "minItems": 1, + "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.", + "items": { + "type": "object", + "required": [ + "type", + "name", + "value" + ], + "properties": { + "type": { + "type": "string", + "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).", + "minLength": 1 + }, + "name": { + "type": "string", + "description": "Human-readable name of the identifier.", + "minLength": 1 + }, + "url": { + "type": "string", + "description": "URL of the identifier's documentation.", + "pattern": "^https?://.+" + }, + "value": { + "type": "string", + "description": "Value of the identifier, for matching purpose.", + "minLength": 1 + } + } + } + }, + "links": { + "type": "array", + "description": "An array of references to external documentation or articles that describe the vulnerability.", + "items": { + "type": "object", + "required": [ + "url" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the vulnerability details link." + }, + "url": { + "type": "string", + "description": "URL of the vulnerability details document.", + "pattern": "^https?://.+" + } + } + } + }, + "details": { + "$ref": "#/definitions/named_list/properties/items" + }, + "tracking": { + "description": "Describes how this vulnerability should be tracked as the project changes.", + "oneOf": [ + { + "description": "Declares that a series of items should be tracked using source-specific tracking methods.", + "required": [ + "items" + ], + "properties": { + "type": { + "const": "source" + }, + "items": { + "type": "array", + "items": { + "description": "An item that should be tracked using source-specific tracking methods.", + "type": "object", + "required": [ + "signatures" + ], + "properties": { + "file": { + "type": "string", + "description": "Path to the file where the vulnerability is located." + }, + "start_line": { + "type": "number", + "description": "The first line of the file that includes the vulnerability." + }, + "end_line": { + "type": "number", + "description": "The last line of the file that includes the vulnerability." + }, + "signatures": { + "type": "array", + "description": "An array of calculated tracking signatures for this tracking item.", + "minItems": 1, + "items": { + "description": "A calculated tracking signature value and metadata.", + "required": [ + "algorithm", + "value" + ], + "properties": { + "algorithm": { + "type": "string", + "description": "The algorithm used to generate the signature." + }, + "value": { + "type": "string", + "description": "The result of this signature algorithm." + } + } + } + } + } + } + } + } + } + ], + "properties": { + "type": { + "type": "string", + "description": "Each tracking type must declare its own type." + } + } + }, + "flags": { + "description": "Flags that can be attached to vulnerabilities.", + "type": "array", + "items": { + "type": "object", + "description": "Informational flags identified and assigned to a vulnerability.", + "required": [ + "type", + "origin", + "description" + ], + "properties": { + "type": { + "type": "string", + "minLength": 1, + "description": "Result of the scan.", + "enum": [ + "flagged-as-likely-false-positive" + ] + }, + "origin": { + "minLength": 1, + "description": "Tool that issued the flag.", + "type": "string" + }, + "description": { + "minLength": 1, + "description": "What the flag is about.", + "type": "string" + } + } + } + }, + "location": { + "type": "object", + "description": "Identifies the vulnerability's location.", + "required": [ + "dependency", + "image", + "kubernetes_resource" + ], + "properties": { + "dependency": { + "type": "object", + "description": "Describes the dependency of a project where the vulnerability is located.", + "required": [ + "package", + "version" + ], + "properties": { + "package": { + "type": "object", + "description": "Provides information on the package where the vulnerability is located.", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the package where the vulnerability is located." + } + } + }, + "version": { + "type": "string", + "description": "Version of the vulnerable package." + }, + "iid": { + "description": "ID that identifies the dependency in the scope of a dependency file.", + "type": "number" + }, + "direct": { + "type": "boolean", + "description": "Tells whether this is a direct, top-level dependency of the scanned project." + }, + "dependency_path": { + "type": "array", + "description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.", + "items": { + "type": "object", + "required": [ + "iid" + ], + "properties": { + "iid": { + "type": "number", + "description": "ID that is unique in the scope of a parent object, and specific to the resource type." + } + } + } + } + } + }, + "operating_system": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "description": "The operating system that contains the vulnerable package." + }, + "image": { + "type": "string", + "minLength": 1, + "description": "The analyzed Docker image.", + "examples": [ + "index.docker.io/library/nginx:1.21" + ] + }, + "kubernetes_resource": { + "type": "object", + "description": "The specific Kubernetes resource that was scanned.", + "required": [ + "namespace", + "kind", + "name", + "container_name" + ], + "properties": { + "namespace": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "description": "The Kubernetes namespace the resource that had its image scanned.", + "examples": [ + "default", + "staging", + "production" + ] + }, + "kind": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "description": "The Kubernetes kind the resource that had its image scanned.", + "examples": [ + "Deployment", + "DaemonSet" + ] + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "description": "The name of the resource that had its image scanned.", + "examples": [ + "nginx-ingress" + ] + }, + "container_name": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "description": "The name of the container that had its image scanned.", + "examples": [ + "nginx" + ] + }, + "agent_id": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "description": "The GitLab ID of the Kubernetes Agent which performed the scan.", + "examples": [ + "1234" + ] + }, + "cluster_id": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "description": "The GitLab ID of the Kubernetes cluster when using cluster integration.", + "examples": [ + "1234" + ] + } + } + } + } + } + } + } + }, + "remediations": { + "type": "array", + "description": "An array of objects containing information on available remediations, along with patch diffs to apply.", + "items": { + "type": "object", + "required": [ + "fixes", + "summary", + "diff" + ], + "properties": { + "fixes": { + "type": "array", + "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.", + "items": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.", + "examples": [ + "642735a5-1425-428d-8d4e-3c854885a3c9" + ] + } + } + } + }, + "summary": { + "type": "string", + "minLength": 1, + "description": "An overview of how the vulnerabilities were fixed." + }, + "diff": { + "type": "string", + "minLength": 1, + "description": "A base64-encoded remediation code diff, compatible with git apply." + } + } + } + } + } +} diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/container-scanning-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/container-scanning-report-format.json new file mode 100644 index 00000000000..2517832853e --- /dev/null +++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/container-scanning-report-format.json @@ -0,0 +1,880 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/container-scanning-report-format.json", + "title": "Report format for GitLab Container Scanning", + "description": "This schema provides the the report format for Container Scanning (https://docs.gitlab.com/ee/user/application_security/container_scanning).", + "definitions": { + "detail_type": { + "oneOf": [ + { + "$ref": "#/definitions/named_list" + }, + { + "$ref": "#/definitions/list" + }, + { + "$ref": "#/definitions/table" + }, + { + "$ref": "#/definitions/text" + }, + { + "$ref": "#/definitions/url" + }, + { + "$ref": "#/definitions/code" + }, + { + "$ref": "#/definitions/value" + }, + { + "$ref": "#/definitions/diff" + }, + { + "$ref": "#/definitions/markdown" + }, + { + "$ref": "#/definitions/commit" + }, + { + "$ref": "#/definitions/file_location" + }, + { + "$ref": "#/definitions/module_location" + } + ] + }, + "text_value": { + "type": "string" + }, + "named_field": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "$ref": "#/definitions/text_value", + "minLength": 1 + }, + "description": { + "$ref": "#/definitions/text_value" + } + } + }, + "named_list": { + "type": "object", + "description": "An object with named and typed fields", + "required": [ + "type", + "items" + ], + "properties": { + "type": { + "const": "named-list" + }, + "items": { + "type": "object", + "patternProperties": { + "^.*$": { + "allOf": [ + { + "$ref": "#/definitions/named_field" + }, + { + "$ref": "#/definitions/detail_type" + } + ] + } + } + } + } + }, + "list": { + "type": "object", + "description": "A list of typed fields", + "required": [ + "type", + "items" + ], + "properties": { + "type": { + "const": "list" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + } + } + }, + "table": { + "type": "object", + "description": "A table of typed fields", + "required": [ + "type", + "rows" + ], + "properties": { + "type": { + "const": "table" + }, + "header": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + }, + "rows": { + "type": "array", + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + } + } + } + }, + "text": { + "type": "object", + "description": "Raw text", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "text" + }, + "value": { + "$ref": "#/definitions/text_value" + } + } + }, + "url": { + "type": "object", + "description": "A single URL", + "required": [ + "type", + "href" + ], + "properties": { + "type": { + "const": "url" + }, + "text": { + "$ref": "#/definitions/text_value" + }, + "href": { + "type": "string", + "minLength": 1, + "examples": [ + "http://mysite.com" + ] + } + } + }, + "code": { + "type": "object", + "description": "A codeblock", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "code" + }, + "value": { + "type": "string" + }, + "lang": { + "type": "string", + "description": "A programming language" + } + } + }, + "value": { + "type": "object", + "description": "A field that can store a range of types of value", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "value" + }, + "value": { + "type": [ + "number", + "string", + "boolean" + ] + } + } + }, + "diff": { + "type": "object", + "description": "A diff", + "required": [ + "type", + "before", + "after" + ], + "properties": { + "type": { + "const": "diff" + }, + "before": { + "type": "string" + }, + "after": { + "type": "string" + } + } + }, + "markdown": { + "type": "object", + "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "markdown" + }, + "value": { + "$ref": "#/definitions/text_value", + "examples": [ + "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)" + ] + } + } + }, + "commit": { + "type": "object", + "description": "A commit/tag/branch within the GitLab project", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "commit" + }, + "value": { + "type": "string", + "description": "The commit SHA", + "minLength": 1 + } + } + }, + "file_location": { + "type": "object", + "description": "A location within a file in the project", + "required": [ + "type", + "file_name", + "line_start" + ], + "properties": { + "type": { + "const": "file-location" + }, + "file_name": { + "type": "string", + "minLength": 1 + }, + "line_start": { + "type": "integer" + }, + "line_end": { + "type": "integer" + } + } + }, + "module_location": { + "type": "object", + "description": "A location within a binary module of the form module+relative_offset", + "required": [ + "type", + "module_name", + "offset" + ], + "properties": { + "type": { + "const": "module-location" + }, + "module_name": { + "type": "string", + "minLength": 1, + "examples": [ + "compiled_binary" + ] + }, + "offset": { + "type": "integer", + "examples": [ + 100 + ] + } + } + } + }, + "self": { + "version": "15.0.0" + }, + "required": [ + "scan", + "version", + "vulnerabilities" + ], + "additionalProperties": true, + "properties": { + "scan": { + "type": "object", + "required": [ + "analyzer", + "end_time", + "scanner", + "start_time", + "status", + "type" + ], + "properties": { + "end_time": { + "type": "string", + "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$", + "examples": [ + "2020-01-28T03:26:02" + ] + }, + "messages": { + "type": "array", + "items": { + "type": "object", + "description": "Communication intended for the initiator of a scan.", + "required": [ + "level", + "value" + ], + "properties": { + "level": { + "type": "string", + "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.", + "enum": [ + "info", + "warn", + "fatal" + ], + "examples": [ + "info" + ] + }, + "value": { + "type": "string", + "description": "The message to communicate.", + "minLength": 1, + "examples": [ + "Permission denied, scanning aborted" + ] + } + } + } + }, + "analyzer": { + "type": "object", + "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.", + "required": [ + "id", + "name", + "version", + "vendor" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique id that identifies the analyzer.", + "minLength": 1, + "examples": [ + "gitlab-dast" + ] + }, + "name": { + "type": "string", + "description": "A human readable value that identifies the analyzer, not required to be unique.", + "minLength": 1, + "examples": [ + "GitLab DAST" + ] + }, + "url": { + "type": "string", + "pattern": "^https?://.+", + "description": "A link to more information about the analyzer.", + "examples": [ + "https://docs.gitlab.com/ee/user/application_security/dast" + ] + }, + "vendor": { + "description": "The vendor/maintainer of the analyzer.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "The name of the vendor.", + "minLength": 1, + "examples": [ + "GitLab" + ] + } + } + }, + "version": { + "type": "string", + "description": "The version of the analyzer.", + "minLength": 1, + "examples": [ + "1.0.2" + ] + } + } + }, + "scanner": { + "type": "object", + "description": "Object defining the scanner used to perform the scan.", + "required": [ + "id", + "name", + "version", + "vendor" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique id that identifies the scanner.", + "minLength": 1, + "examples": [ + "my-sast-scanner" + ] + }, + "name": { + "type": "string", + "description": "A human readable value that identifies the scanner, not required to be unique.", + "minLength": 1, + "examples": [ + "My SAST Scanner" + ] + }, + "url": { + "type": "string", + "description": "A link to more information about the scanner.", + "examples": [ + "https://scanner.url" + ] + }, + "version": { + "type": "string", + "description": "The version of the scanner.", + "minLength": 1, + "examples": [ + "1.0.2" + ] + }, + "vendor": { + "description": "The vendor/maintainer of the scanner.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "The name of the vendor.", + "minLength": 1, + "examples": [ + "GitLab" + ] + } + } + } + } + }, + "start_time": { + "type": "string", + "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$", + "examples": [ + "2020-02-14T16:01:59" + ] + }, + "status": { + "type": "string", + "description": "Result of the scan.", + "enum": [ + "success", + "failure" + ] + }, + "type": { + "type": "string", + "description": "Type of the scan.", + "enum": [ + "container_scanning" + ] + } + } + }, + "schema": { + "type": "string", + "description": "URI pointing to the validating security report schema.", + "pattern": "^https?://.+" + }, + "version": { + "type": "string", + "description": "The version of the schema to which the JSON report conforms.", + "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" + }, + "vulnerabilities": { + "type": "array", + "description": "Array of vulnerability objects.", + "items": { + "type": "object", + "description": "Describes the vulnerability using GitLab Flavored Markdown", + "required": [ + "id", + "identifiers", + "location" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.", + "examples": [ + "642735a5-1425-428d-8d4e-3c854885a3c9" + ] + }, + "name": { + "type": "string", + "maxLength": 255, + "description": "The name of the vulnerability. This must not include the finding's specific information." + }, + "description": { + "type": "string", + "maxLength": 1048576, + "description": "A long text section describing the vulnerability more fully." + }, + "severity": { + "type": "string", + "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.", + "enum": [ + "Info", + "Unknown", + "Low", + "Medium", + "High", + "Critical" + ] + }, + "solution": { + "type": "string", + "maxLength": 7000, + "description": "Explanation of how to fix the vulnerability." + }, + "identifiers": { + "type": "array", + "minItems": 1, + "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.", + "items": { + "type": "object", + "required": [ + "type", + "name", + "value" + ], + "properties": { + "type": { + "type": "string", + "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).", + "minLength": 1 + }, + "name": { + "type": "string", + "description": "Human-readable name of the identifier.", + "minLength": 1 + }, + "url": { + "type": "string", + "description": "URL of the identifier's documentation.", + "pattern": "^https?://.+" + }, + "value": { + "type": "string", + "description": "Value of the identifier, for matching purpose.", + "minLength": 1 + } + } + } + }, + "links": { + "type": "array", + "description": "An array of references to external documentation or articles that describe the vulnerability.", + "items": { + "type": "object", + "required": [ + "url" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the vulnerability details link." + }, + "url": { + "type": "string", + "description": "URL of the vulnerability details document.", + "pattern": "^https?://.+" + } + } + } + }, + "details": { + "$ref": "#/definitions/named_list/properties/items" + }, + "tracking": { + "description": "Describes how this vulnerability should be tracked as the project changes.", + "oneOf": [ + { + "description": "Declares that a series of items should be tracked using source-specific tracking methods.", + "required": [ + "items" + ], + "properties": { + "type": { + "const": "source" + }, + "items": { + "type": "array", + "items": { + "description": "An item that should be tracked using source-specific tracking methods.", + "type": "object", + "required": [ + "signatures" + ], + "properties": { + "file": { + "type": "string", + "description": "Path to the file where the vulnerability is located." + }, + "start_line": { + "type": "number", + "description": "The first line of the file that includes the vulnerability." + }, + "end_line": { + "type": "number", + "description": "The last line of the file that includes the vulnerability." + }, + "signatures": { + "type": "array", + "description": "An array of calculated tracking signatures for this tracking item.", + "minItems": 1, + "items": { + "description": "A calculated tracking signature value and metadata.", + "required": [ + "algorithm", + "value" + ], + "properties": { + "algorithm": { + "type": "string", + "description": "The algorithm used to generate the signature." + }, + "value": { + "type": "string", + "description": "The result of this signature algorithm." + } + } + } + } + } + } + } + } + } + ], + "properties": { + "type": { + "type": "string", + "description": "Each tracking type must declare its own type." + } + } + }, + "flags": { + "description": "Flags that can be attached to vulnerabilities.", + "type": "array", + "items": { + "type": "object", + "description": "Informational flags identified and assigned to a vulnerability.", + "required": [ + "type", + "origin", + "description" + ], + "properties": { + "type": { + "type": "string", + "minLength": 1, + "description": "Result of the scan.", + "enum": [ + "flagged-as-likely-false-positive" + ] + }, + "origin": { + "minLength": 1, + "description": "Tool that issued the flag.", + "type": "string" + }, + "description": { + "minLength": 1, + "description": "What the flag is about.", + "type": "string" + } + } + } + }, + "location": { + "type": "object", + "description": "Identifies the vulnerability's location.", + "required": [ + "dependency", + "operating_system", + "image" + ], + "properties": { + "dependency": { + "type": "object", + "description": "Describes the dependency of a project where the vulnerability is located.", + "required": [ + "package", + "version" + ], + "properties": { + "package": { + "type": "object", + "description": "Provides information on the package where the vulnerability is located.", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the package where the vulnerability is located." + } + } + }, + "version": { + "type": "string", + "description": "Version of the vulnerable package." + }, + "iid": { + "description": "ID that identifies the dependency in the scope of a dependency file.", + "type": "number" + }, + "direct": { + "type": "boolean", + "description": "Tells whether this is a direct, top-level dependency of the scanned project." + }, + "dependency_path": { + "type": "array", + "description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.", + "items": { + "type": "object", + "required": [ + "iid" + ], + "properties": { + "iid": { + "type": "number", + "description": "ID that is unique in the scope of a parent object, and specific to the resource type." + } + } + } + } + } + }, + "operating_system": { + "type": "string", + "minLength": 1, + "description": "The operating system that contains the vulnerable package." + }, + "image": { + "type": "string", + "minLength": 1, + "pattern": "^[^:]+(:\\d+[^:]*)?:[^:]+(:[^:]+)?$", + "description": "The analyzed Docker image." + }, + "default_branch_image": { + "type": "string", + "maxLength": 255, + "pattern": "^[a-zA-Z0-9/_.-]+(:\\d+[a-zA-Z0-9/_.-]*)?:[a-zA-Z0-9_.-]+$", + "description": "The name of the image on the default branch." + } + } + } + } + } + }, + "remediations": { + "type": "array", + "description": "An array of objects containing information on available remediations, along with patch diffs to apply.", + "items": { + "type": "object", + "required": [ + "fixes", + "summary", + "diff" + ], + "properties": { + "fixes": { + "type": "array", + "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.", + "items": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.", + "examples": [ + "642735a5-1425-428d-8d4e-3c854885a3c9" + ] + } + } + } + }, + "summary": { + "type": "string", + "minLength": 1, + "description": "An overview of how the vulnerabilities were fixed." + }, + "diff": { + "type": "string", + "minLength": 1, + "description": "A base64-encoded remediation code diff, compatible with git apply." + } + } + } + } + } +} diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/coverage-fuzzing-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/coverage-fuzzing-report-format.json new file mode 100644 index 00000000000..a2f9eb12992 --- /dev/null +++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/coverage-fuzzing-report-format.json @@ -0,0 +1,836 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/coverage-fuzzing-report-format.json", + "title": "Report format for GitLab Fuzz Testing", + "description": "This schema provides the report format for Coverage Guided Fuzz Testing (https://docs.gitlab.com/ee/user/application_security/coverage_fuzzing).", + "definitions": { + "detail_type": { + "oneOf": [ + { + "$ref": "#/definitions/named_list" + }, + { + "$ref": "#/definitions/list" + }, + { + "$ref": "#/definitions/table" + }, + { + "$ref": "#/definitions/text" + }, + { + "$ref": "#/definitions/url" + }, + { + "$ref": "#/definitions/code" + }, + { + "$ref": "#/definitions/value" + }, + { + "$ref": "#/definitions/diff" + }, + { + "$ref": "#/definitions/markdown" + }, + { + "$ref": "#/definitions/commit" + }, + { + "$ref": "#/definitions/file_location" + }, + { + "$ref": "#/definitions/module_location" + } + ] + }, + "text_value": { + "type": "string" + }, + "named_field": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "$ref": "#/definitions/text_value", + "minLength": 1 + }, + "description": { + "$ref": "#/definitions/text_value" + } + } + }, + "named_list": { + "type": "object", + "description": "An object with named and typed fields", + "required": [ + "type", + "items" + ], + "properties": { + "type": { + "const": "named-list" + }, + "items": { + "type": "object", + "patternProperties": { + "^.*$": { + "allOf": [ + { + "$ref": "#/definitions/named_field" + }, + { + "$ref": "#/definitions/detail_type" + } + ] + } + } + } + } + }, + "list": { + "type": "object", + "description": "A list of typed fields", + "required": [ + "type", + "items" + ], + "properties": { + "type": { + "const": "list" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + } + } + }, + "table": { + "type": "object", + "description": "A table of typed fields", + "required": [ + "type", + "rows" + ], + "properties": { + "type": { + "const": "table" + }, + "header": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + }, + "rows": { + "type": "array", + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + } + } + } + }, + "text": { + "type": "object", + "description": "Raw text", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "text" + }, + "value": { + "$ref": "#/definitions/text_value" + } + } + }, + "url": { + "type": "object", + "description": "A single URL", + "required": [ + "type", + "href" + ], + "properties": { + "type": { + "const": "url" + }, + "text": { + "$ref": "#/definitions/text_value" + }, + "href": { + "type": "string", + "minLength": 1, + "examples": [ + "http://mysite.com" + ] + } + } + }, + "code": { + "type": "object", + "description": "A codeblock", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "code" + }, + "value": { + "type": "string" + }, + "lang": { + "type": "string", + "description": "A programming language" + } + } + }, + "value": { + "type": "object", + "description": "A field that can store a range of types of value", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "value" + }, + "value": { + "type": [ + "number", + "string", + "boolean" + ] + } + } + }, + "diff": { + "type": "object", + "description": "A diff", + "required": [ + "type", + "before", + "after" + ], + "properties": { + "type": { + "const": "diff" + }, + "before": { + "type": "string" + }, + "after": { + "type": "string" + } + } + }, + "markdown": { + "type": "object", + "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "markdown" + }, + "value": { + "$ref": "#/definitions/text_value", + "examples": [ + "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)" + ] + } + } + }, + "commit": { + "type": "object", + "description": "A commit/tag/branch within the GitLab project", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "commit" + }, + "value": { + "type": "string", + "description": "The commit SHA", + "minLength": 1 + } + } + }, + "file_location": { + "type": "object", + "description": "A location within a file in the project", + "required": [ + "type", + "file_name", + "line_start" + ], + "properties": { + "type": { + "const": "file-location" + }, + "file_name": { + "type": "string", + "minLength": 1 + }, + "line_start": { + "type": "integer" + }, + "line_end": { + "type": "integer" + } + } + }, + "module_location": { + "type": "object", + "description": "A location within a binary module of the form module+relative_offset", + "required": [ + "type", + "module_name", + "offset" + ], + "properties": { + "type": { + "const": "module-location" + }, + "module_name": { + "type": "string", + "minLength": 1, + "examples": [ + "compiled_binary" + ] + }, + "offset": { + "type": "integer", + "examples": [ + 100 + ] + } + } + } + }, + "self": { + "version": "15.0.0" + }, + "required": [ + "scan", + "version", + "vulnerabilities" + ], + "additionalProperties": true, + "properties": { + "scan": { + "type": "object", + "required": [ + "analyzer", + "end_time", + "scanner", + "start_time", + "status", + "type" + ], + "properties": { + "end_time": { + "type": "string", + "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$", + "examples": [ + "2020-01-28T03:26:02" + ] + }, + "messages": { + "type": "array", + "items": { + "type": "object", + "description": "Communication intended for the initiator of a scan.", + "required": [ + "level", + "value" + ], + "properties": { + "level": { + "type": "string", + "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.", + "enum": [ + "info", + "warn", + "fatal" + ], + "examples": [ + "info" + ] + }, + "value": { + "type": "string", + "description": "The message to communicate.", + "minLength": 1, + "examples": [ + "Permission denied, scanning aborted" + ] + } + } + } + }, + "analyzer": { + "type": "object", + "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.", + "required": [ + "id", + "name", + "version", + "vendor" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique id that identifies the analyzer.", + "minLength": 1, + "examples": [ + "gitlab-dast" + ] + }, + "name": { + "type": "string", + "description": "A human readable value that identifies the analyzer, not required to be unique.", + "minLength": 1, + "examples": [ + "GitLab DAST" + ] + }, + "url": { + "type": "string", + "pattern": "^https?://.+", + "description": "A link to more information about the analyzer.", + "examples": [ + "https://docs.gitlab.com/ee/user/application_security/dast" + ] + }, + "vendor": { + "description": "The vendor/maintainer of the analyzer.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "The name of the vendor.", + "minLength": 1, + "examples": [ + "GitLab" + ] + } + } + }, + "version": { + "type": "string", + "description": "The version of the analyzer.", + "minLength": 1, + "examples": [ + "1.0.2" + ] + } + } + }, + "scanner": { + "type": "object", + "description": "Object defining the scanner used to perform the scan.", + "required": [ + "id", + "name", + "version", + "vendor" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique id that identifies the scanner.", + "minLength": 1, + "examples": [ + "my-sast-scanner" + ] + }, + "name": { + "type": "string", + "description": "A human readable value that identifies the scanner, not required to be unique.", + "minLength": 1, + "examples": [ + "My SAST Scanner" + ] + }, + "url": { + "type": "string", + "description": "A link to more information about the scanner.", + "examples": [ + "https://scanner.url" + ] + }, + "version": { + "type": "string", + "description": "The version of the scanner.", + "minLength": 1, + "examples": [ + "1.0.2" + ] + }, + "vendor": { + "description": "The vendor/maintainer of the scanner.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "The name of the vendor.", + "minLength": 1, + "examples": [ + "GitLab" + ] + } + } + } + } + }, + "start_time": { + "type": "string", + "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$", + "examples": [ + "2020-02-14T16:01:59" + ] + }, + "status": { + "type": "string", + "description": "Result of the scan.", + "enum": [ + "success", + "failure" + ] + }, + "type": { + "type": "string", + "description": "Type of the scan.", + "enum": [ + "coverage_fuzzing" + ] + } + } + }, + "schema": { + "type": "string", + "description": "URI pointing to the validating security report schema.", + "pattern": "^https?://.+" + }, + "version": { + "type": "string", + "description": "The version of the schema to which the JSON report conforms.", + "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" + }, + "vulnerabilities": { + "type": "array", + "description": "Array of vulnerability objects.", + "items": { + "type": "object", + "description": "Describes the vulnerability using GitLab Flavored Markdown", + "required": [ + "id", + "identifiers", + "location" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.", + "examples": [ + "642735a5-1425-428d-8d4e-3c854885a3c9" + ] + }, + "name": { + "type": "string", + "maxLength": 255, + "description": "The name of the vulnerability. This must not include the finding's specific information." + }, + "description": { + "type": "string", + "maxLength": 1048576, + "description": "A long text section describing the vulnerability more fully." + }, + "severity": { + "type": "string", + "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.", + "enum": [ + "Info", + "Unknown", + "Low", + "Medium", + "High", + "Critical" + ] + }, + "solution": { + "type": "string", + "maxLength": 7000, + "description": "Explanation of how to fix the vulnerability." + }, + "identifiers": { + "type": "array", + "minItems": 1, + "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.", + "items": { + "type": "object", + "required": [ + "type", + "name", + "value" + ], + "properties": { + "type": { + "type": "string", + "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).", + "minLength": 1 + }, + "name": { + "type": "string", + "description": "Human-readable name of the identifier.", + "minLength": 1 + }, + "url": { + "type": "string", + "description": "URL of the identifier's documentation.", + "pattern": "^https?://.+" + }, + "value": { + "type": "string", + "description": "Value of the identifier, for matching purpose.", + "minLength": 1 + } + } + } + }, + "links": { + "type": "array", + "description": "An array of references to external documentation or articles that describe the vulnerability.", + "items": { + "type": "object", + "required": [ + "url" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the vulnerability details link." + }, + "url": { + "type": "string", + "description": "URL of the vulnerability details document.", + "pattern": "^https?://.+" + } + } + } + }, + "details": { + "$ref": "#/definitions/named_list/properties/items" + }, + "tracking": { + "description": "Describes how this vulnerability should be tracked as the project changes.", + "oneOf": [ + { + "description": "Declares that a series of items should be tracked using source-specific tracking methods.", + "required": [ + "items" + ], + "properties": { + "type": { + "const": "source" + }, + "items": { + "type": "array", + "items": { + "description": "An item that should be tracked using source-specific tracking methods.", + "type": "object", + "required": [ + "signatures" + ], + "properties": { + "file": { + "type": "string", + "description": "Path to the file where the vulnerability is located." + }, + "start_line": { + "type": "number", + "description": "The first line of the file that includes the vulnerability." + }, + "end_line": { + "type": "number", + "description": "The last line of the file that includes the vulnerability." + }, + "signatures": { + "type": "array", + "description": "An array of calculated tracking signatures for this tracking item.", + "minItems": 1, + "items": { + "description": "A calculated tracking signature value and metadata.", + "required": [ + "algorithm", + "value" + ], + "properties": { + "algorithm": { + "type": "string", + "description": "The algorithm used to generate the signature." + }, + "value": { + "type": "string", + "description": "The result of this signature algorithm." + } + } + } + } + } + } + } + } + } + ], + "properties": { + "type": { + "type": "string", + "description": "Each tracking type must declare its own type." + } + } + }, + "flags": { + "description": "Flags that can be attached to vulnerabilities.", + "type": "array", + "items": { + "type": "object", + "description": "Informational flags identified and assigned to a vulnerability.", + "required": [ + "type", + "origin", + "description" + ], + "properties": { + "type": { + "type": "string", + "minLength": 1, + "description": "Result of the scan.", + "enum": [ + "flagged-as-likely-false-positive" + ] + }, + "origin": { + "minLength": 1, + "description": "Tool that issued the flag.", + "type": "string" + }, + "description": { + "minLength": 1, + "description": "What the flag is about.", + "type": "string" + } + } + } + }, + "location": { + "description": "The location of the error", + "type": "object", + "properties": { + "crash_address": { + "type": "string", + "description": "The relative address in memory were the crash occurred.", + "examples": [ + "0xabababab" + ] + }, + "stacktrace_snippet": { + "type": "string", + "description": "The stack trace recorded during fuzzing resulting the crash.", + "examples": [ + "func_a+0xabcd\nfunc_b+0xabcc" + ] + }, + "crash_state": { + "type": "string", + "description": "Minimised and normalized crash stack-trace (called crash_state).", + "examples": [ + "func_a+0xa\nfunc_b+0xb\nfunc_c+0xc" + ] + }, + "crash_type": { + "type": "string", + "description": "Type of the crash.", + "examples": [ + "Heap-Buffer-overflow", + "Division-by-zero" + ] + } + } + } + } + } + }, + "remediations": { + "type": "array", + "description": "An array of objects containing information on available remediations, along with patch diffs to apply.", + "items": { + "type": "object", + "required": [ + "fixes", + "summary", + "diff" + ], + "properties": { + "fixes": { + "type": "array", + "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.", + "items": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.", + "examples": [ + "642735a5-1425-428d-8d4e-3c854885a3c9" + ] + } + } + } + }, + "summary": { + "type": "string", + "minLength": 1, + "description": "An overview of how the vulnerabilities were fixed." + }, + "diff": { + "type": "string", + "minLength": 1, + "description": "A base64-encoded remediation code diff, compatible with git apply." + } + } + } + } + } +} diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dast-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dast-report-format.json new file mode 100644 index 00000000000..10fafaf8975 --- /dev/null +++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dast-report-format.json @@ -0,0 +1,1241 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/dast-report-format.json", + "title": "Report format for GitLab DAST", + "description": "This schema provides the the report format for Dynamic Application Security Testing (https://docs.gitlab.com/ee/user/application_security/dast).", + "definitions": { + "detail_type": { + "oneOf": [ + { + "$ref": "#/definitions/named_list" + }, + { + "$ref": "#/definitions/list" + }, + { + "$ref": "#/definitions/table" + }, + { + "$ref": "#/definitions/text" + }, + { + "$ref": "#/definitions/url" + }, + { + "$ref": "#/definitions/code" + }, + { + "$ref": "#/definitions/value" + }, + { + "$ref": "#/definitions/diff" + }, + { + "$ref": "#/definitions/markdown" + }, + { + "$ref": "#/definitions/commit" + }, + { + "$ref": "#/definitions/file_location" + }, + { + "$ref": "#/definitions/module_location" + } + ] + }, + "text_value": { + "type": "string" + }, + "named_field": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "$ref": "#/definitions/text_value", + "minLength": 1 + }, + "description": { + "$ref": "#/definitions/text_value" + } + } + }, + "named_list": { + "type": "object", + "description": "An object with named and typed fields", + "required": [ + "type", + "items" + ], + "properties": { + "type": { + "const": "named-list" + }, + "items": { + "type": "object", + "patternProperties": { + "^.*$": { + "allOf": [ + { + "$ref": "#/definitions/named_field" + }, + { + "$ref": "#/definitions/detail_type" + } + ] + } + } + } + } + }, + "list": { + "type": "object", + "description": "A list of typed fields", + "required": [ + "type", + "items" + ], + "properties": { + "type": { + "const": "list" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + } + } + }, + "table": { + "type": "object", + "description": "A table of typed fields", + "required": [ + "type", + "rows" + ], + "properties": { + "type": { + "const": "table" + }, + "header": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + }, + "rows": { + "type": "array", + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + } + } + } + }, + "text": { + "type": "object", + "description": "Raw text", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "text" + }, + "value": { + "$ref": "#/definitions/text_value" + } + } + }, + "url": { + "type": "object", + "description": "A single URL", + "required": [ + "type", + "href" + ], + "properties": { + "type": { + "const": "url" + }, + "text": { + "$ref": "#/definitions/text_value" + }, + "href": { + "type": "string", + "minLength": 1, + "examples": [ + "http://mysite.com" + ] + } + } + }, + "code": { + "type": "object", + "description": "A codeblock", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "code" + }, + "value": { + "type": "string" + }, + "lang": { + "type": "string", + "description": "A programming language" + } + } + }, + "value": { + "type": "object", + "description": "A field that can store a range of types of value", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "value" + }, + "value": { + "type": [ + "number", + "string", + "boolean" + ] + } + } + }, + "diff": { + "type": "object", + "description": "A diff", + "required": [ + "type", + "before", + "after" + ], + "properties": { + "type": { + "const": "diff" + }, + "before": { + "type": "string" + }, + "after": { + "type": "string" + } + } + }, + "markdown": { + "type": "object", + "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "markdown" + }, + "value": { + "$ref": "#/definitions/text_value", + "examples": [ + "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)" + ] + } + } + }, + "commit": { + "type": "object", + "description": "A commit/tag/branch within the GitLab project", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "commit" + }, + "value": { + "type": "string", + "description": "The commit SHA", + "minLength": 1 + } + } + }, + "file_location": { + "type": "object", + "description": "A location within a file in the project", + "required": [ + "type", + "file_name", + "line_start" + ], + "properties": { + "type": { + "const": "file-location" + }, + "file_name": { + "type": "string", + "minLength": 1 + }, + "line_start": { + "type": "integer" + }, + "line_end": { + "type": "integer" + } + } + }, + "module_location": { + "type": "object", + "description": "A location within a binary module of the form module+relative_offset", + "required": [ + "type", + "module_name", + "offset" + ], + "properties": { + "type": { + "const": "module-location" + }, + "module_name": { + "type": "string", + "minLength": 1, + "examples": [ + "compiled_binary" + ] + }, + "offset": { + "type": "integer", + "examples": [ + 100 + ] + } + } + } + }, + "self": { + "version": "15.0.0" + }, + "required": [ + "scan", + "version", + "vulnerabilities" + ], + "additionalProperties": true, + "properties": { + "scan": { + "type": "object", + "required": [ + "analyzer", + "end_time", + "scanned_resources", + "scanner", + "start_time", + "status", + "type" + ], + "properties": { + "end_time": { + "type": "string", + "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$", + "examples": [ + "2020-01-28T03:26:02" + ] + }, + "messages": { + "type": "array", + "items": { + "type": "object", + "description": "Communication intended for the initiator of a scan.", + "required": [ + "level", + "value" + ], + "properties": { + "level": { + "type": "string", + "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.", + "enum": [ + "info", + "warn", + "fatal" + ], + "examples": [ + "info" + ] + }, + "value": { + "type": "string", + "description": "The message to communicate.", + "minLength": 1, + "examples": [ + "Permission denied, scanning aborted" + ] + } + } + } + }, + "analyzer": { + "type": "object", + "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.", + "required": [ + "id", + "name", + "version", + "vendor" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique id that identifies the analyzer.", + "minLength": 1, + "examples": [ + "gitlab-dast" + ] + }, + "name": { + "type": "string", + "description": "A human readable value that identifies the analyzer, not required to be unique.", + "minLength": 1, + "examples": [ + "GitLab DAST" + ] + }, + "url": { + "type": "string", + "pattern": "^https?://.+", + "description": "A link to more information about the analyzer.", + "examples": [ + "https://docs.gitlab.com/ee/user/application_security/dast" + ] + }, + "vendor": { + "description": "The vendor/maintainer of the analyzer.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "The name of the vendor.", + "minLength": 1, + "examples": [ + "GitLab" + ] + } + } + }, + "version": { + "type": "string", + "description": "The version of the analyzer.", + "minLength": 1, + "examples": [ + "1.0.2" + ] + } + } + }, + "scanner": { + "type": "object", + "description": "Object defining the scanner used to perform the scan.", + "required": [ + "id", + "name", + "version", + "vendor" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique id that identifies the scanner.", + "minLength": 1, + "examples": [ + "my-sast-scanner" + ] + }, + "name": { + "type": "string", + "description": "A human readable value that identifies the scanner, not required to be unique.", + "minLength": 1, + "examples": [ + "My SAST Scanner" + ] + }, + "url": { + "type": "string", + "description": "A link to more information about the scanner.", + "examples": [ + "https://scanner.url" + ] + }, + "version": { + "type": "string", + "description": "The version of the scanner.", + "minLength": 1, + "examples": [ + "1.0.2" + ] + }, + "vendor": { + "description": "The vendor/maintainer of the scanner.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "The name of the vendor.", + "minLength": 1, + "examples": [ + "GitLab" + ] + } + } + } + } + }, + "start_time": { + "type": "string", + "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$", + "examples": [ + "2020-02-14T16:01:59" + ] + }, + "status": { + "type": "string", + "description": "Result of the scan.", + "enum": [ + "success", + "failure" + ] + }, + "type": { + "type": "string", + "description": "Type of the scan.", + "enum": [ + "dast", + "api_fuzzing" + ] + }, + "scanned_resources": { + "type": "array", + "description": "The attack surface scanned by DAST.", + "items": { + "type": "object", + "required": [ + "method", + "url", + "type" + ], + "properties": { + "method": { + "type": "string", + "minLength": 1, + "description": "HTTP method of the scanned resource.", + "examples": [ + "GET", + "POST", + "HEAD" + ] + }, + "url": { + "type": "string", + "minLength": 1, + "description": "URL of the scanned resource.", + "examples": [ + "http://my.site.com/a-page" + ] + }, + "type": { + "type": "string", + "minLength": 1, + "description": "Type of the scanned resource, for DAST, this must be 'url'.", + "examples": [ + "url" + ] + } + } + } + } + } + }, + "schema": { + "type": "string", + "description": "URI pointing to the validating security report schema.", + "pattern": "^https?://.+" + }, + "version": { + "type": "string", + "description": "The version of the schema to which the JSON report conforms.", + "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" + }, + "vulnerabilities": { + "type": "array", + "description": "Array of vulnerability objects.", + "items": { + "type": "object", + "description": "Describes the vulnerability using GitLab Flavored Markdown", + "required": [ + "id", + "identifiers", + "location" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.", + "examples": [ + "642735a5-1425-428d-8d4e-3c854885a3c9" + ] + }, + "name": { + "type": "string", + "maxLength": 255, + "description": "The name of the vulnerability. This must not include the finding's specific information." + }, + "description": { + "type": "string", + "maxLength": 1048576, + "description": "A long text section describing the vulnerability more fully." + }, + "severity": { + "type": "string", + "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.", + "enum": [ + "Info", + "Unknown", + "Low", + "Medium", + "High", + "Critical" + ] + }, + "solution": { + "type": "string", + "maxLength": 7000, + "description": "Explanation of how to fix the vulnerability." + }, + "identifiers": { + "type": "array", + "minItems": 1, + "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.", + "items": { + "type": "object", + "required": [ + "type", + "name", + "value" + ], + "properties": { + "type": { + "type": "string", + "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).", + "minLength": 1 + }, + "name": { + "type": "string", + "description": "Human-readable name of the identifier.", + "minLength": 1 + }, + "url": { + "type": "string", + "description": "URL of the identifier's documentation.", + "pattern": "^https?://.+" + }, + "value": { + "type": "string", + "description": "Value of the identifier, for matching purpose.", + "minLength": 1 + } + } + } + }, + "links": { + "type": "array", + "description": "An array of references to external documentation or articles that describe the vulnerability.", + "items": { + "type": "object", + "required": [ + "url" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the vulnerability details link." + }, + "url": { + "type": "string", + "description": "URL of the vulnerability details document.", + "pattern": "^https?://.+" + } + } + } + }, + "details": { + "$ref": "#/definitions/named_list/properties/items" + }, + "tracking": { + "description": "Describes how this vulnerability should be tracked as the project changes.", + "oneOf": [ + { + "description": "Declares that a series of items should be tracked using source-specific tracking methods.", + "required": [ + "items" + ], + "properties": { + "type": { + "const": "source" + }, + "items": { + "type": "array", + "items": { + "description": "An item that should be tracked using source-specific tracking methods.", + "type": "object", + "required": [ + "signatures" + ], + "properties": { + "file": { + "type": "string", + "description": "Path to the file where the vulnerability is located." + }, + "start_line": { + "type": "number", + "description": "The first line of the file that includes the vulnerability." + }, + "end_line": { + "type": "number", + "description": "The last line of the file that includes the vulnerability." + }, + "signatures": { + "type": "array", + "description": "An array of calculated tracking signatures for this tracking item.", + "minItems": 1, + "items": { + "description": "A calculated tracking signature value and metadata.", + "required": [ + "algorithm", + "value" + ], + "properties": { + "algorithm": { + "type": "string", + "description": "The algorithm used to generate the signature." + }, + "value": { + "type": "string", + "description": "The result of this signature algorithm." + } + } + } + } + } + } + } + } + } + ], + "properties": { + "type": { + "type": "string", + "description": "Each tracking type must declare its own type." + } + } + }, + "flags": { + "description": "Flags that can be attached to vulnerabilities.", + "type": "array", + "items": { + "type": "object", + "description": "Informational flags identified and assigned to a vulnerability.", + "required": [ + "type", + "origin", + "description" + ], + "properties": { + "type": { + "type": "string", + "minLength": 1, + "description": "Result of the scan.", + "enum": [ + "flagged-as-likely-false-positive" + ] + }, + "origin": { + "minLength": 1, + "description": "Tool that issued the flag.", + "type": "string" + }, + "description": { + "minLength": 1, + "description": "What the flag is about.", + "type": "string" + } + } + } + }, + "evidence": { + "type": "object", + "properties": { + "source": { + "type": "object", + "description": "Source of evidence", + "required": [ + "id", + "name" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "description": "Unique source identifier", + "examples": [ + "assert:LogAnalysis", + "assert:StatusCode" + ] + }, + "name": { + "type": "string", + "minLength": 1, + "description": "Source display name", + "examples": [ + "Log Analysis", + "Status Code" + ] + }, + "url": { + "type": "string", + "description": "Link to additional information", + "examples": [ + "https://docs.gitlab.com/ee/development/integrations/secure.html" + ] + } + } + }, + "summary": { + "type": "string", + "description": "Human readable string containing evidence of the vulnerability.", + "examples": [ + "Credit card 4111111111111111 found", + "Server leaked information nginx/1.17.6" + ] + }, + "request": { + "type": "object", + "description": "An HTTP request.", + "required": [ + "headers", + "method", + "url" + ], + "properties": { + "headers": { + "type": "array", + "description": "HTTP headers present on the request.", + "items": { + "type": "object", + "required": [ + "name", + "value" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "Name of the HTTP header.", + "examples": [ + "Accept", + "Content-Length", + "Content-Type" + ] + }, + "value": { + "type": "string", + "description": "Value of the HTTP header.", + "examples": [ + "*/*", + "560", + "application/json; charset=utf-8" + ] + } + } + } + }, + "method": { + "type": "string", + "minLength": 1, + "description": "HTTP method used in the request.", + "examples": [ + "GET", + "POST" + ] + }, + "url": { + "type": "string", + "minLength": 1, + "description": "URL of the request.", + "examples": [ + "http://my.site.com/vulnerable-endpoint?show-credit-card" + ] + }, + "body": { + "type": "string", + "description": "Body of the request for display purposes. Body must be suitable for display (not binary), and truncated to a reasonable size.", + "examples": [ + "user=jsmith&first=%27&last=smith" + ] + } + } + }, + "response": { + "type": "object", + "description": "An HTTP response.", + "required": [ + "headers", + "reason_phrase", + "status_code" + ], + "properties": { + "headers": { + "type": "array", + "description": "HTTP headers present on the request.", + "items": { + "type": "object", + "required": [ + "name", + "value" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "Name of the HTTP header.", + "examples": [ + "Accept", + "Content-Length", + "Content-Type" + ] + }, + "value": { + "type": "string", + "description": "Value of the HTTP header.", + "examples": [ + "*/*", + "560", + "application/json; charset=utf-8" + ] + } + } + } + }, + "reason_phrase": { + "type": "string", + "description": "HTTP reason phrase of the response.", + "examples": [ + "OK", + "Internal Server Error" + ] + }, + "status_code": { + "type": "integer", + "description": "HTTP status code of the response.", + "examples": [ + 200, + 500 + ] + }, + "body": { + "type": "string", + "description": "Body of the response for display purposes. Body must be suitable for display (not binary), and truncated to a reasonable size.", + "examples": [ + "{\"user_id\": 2}" + ] + } + } + }, + "supporting_messages": { + "type": "array", + "description": "Array of supporting http messages.", + "items": { + "type": "object", + "description": "A supporting http message.", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "Message display name.", + "examples": [ + "Unmodified", + "Recorded" + ] + }, + "request": { + "type": "object", + "description": "An HTTP request.", + "required": [ + "headers", + "method", + "url" + ], + "properties": { + "headers": { + "type": "array", + "description": "HTTP headers present on the request.", + "items": { + "type": "object", + "required": [ + "name", + "value" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "Name of the HTTP header.", + "examples": [ + "Accept", + "Content-Length", + "Content-Type" + ] + }, + "value": { + "type": "string", + "description": "Value of the HTTP header.", + "examples": [ + "*/*", + "560", + "application/json; charset=utf-8" + ] + } + } + } + }, + "method": { + "type": "string", + "minLength": 1, + "description": "HTTP method used in the request.", + "examples": [ + "GET", + "POST" + ] + }, + "url": { + "type": "string", + "minLength": 1, + "description": "URL of the request.", + "examples": [ + "http://my.site.com/vulnerable-endpoint?show-credit-card" + ] + }, + "body": { + "type": "string", + "description": "Body of the request for display purposes. Body must be suitable for display (not binary), and truncated to a reasonable size.", + "examples": [ + "user=jsmith&first=%27&last=smith" + ] + } + } + }, + "response": { + "type": "object", + "description": "An HTTP response.", + "required": [ + "headers", + "reason_phrase", + "status_code" + ], + "properties": { + "headers": { + "type": "array", + "description": "HTTP headers present on the request.", + "items": { + "type": "object", + "required": [ + "name", + "value" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "Name of the HTTP header.", + "examples": [ + "Accept", + "Content-Length", + "Content-Type" + ] + }, + "value": { + "type": "string", + "description": "Value of the HTTP header.", + "examples": [ + "*/*", + "560", + "application/json; charset=utf-8" + ] + } + } + } + }, + "reason_phrase": { + "type": "string", + "description": "HTTP reason phrase of the response.", + "examples": [ + "OK", + "Internal Server Error" + ] + }, + "status_code": { + "type": "integer", + "description": "HTTP status code of the response.", + "examples": [ + 200, + 500 + ] + }, + "body": { + "type": "string", + "description": "Body of the response for display purposes. Body must be suitable for display (not binary), and truncated to a reasonable size.", + "examples": [ + "{\"user_id\": 2}" + ] + } + } + } + } + } + } + } + }, + "location": { + "type": "object", + "description": "Identifies the vulnerability's location.", + "properties": { + "hostname": { + "type": "string", + "description": "The protocol, domain, and port of the application where the vulnerability was found." + }, + "method": { + "type": "string", + "description": "The HTTP method that was used to request the URL where the vulnerability was found." + }, + "param": { + "type": "string", + "description": "A value provided by a vulnerability rule related to the found vulnerability. Examples include a header value, or a parameter used in a HTTP POST." + }, + "path": { + "type": "string", + "description": "The path of the URL where the vulnerability was found. Typically, this would start with a forward slash." + } + } + }, + "assets": { + "type": "array", + "description": "Array of build assets associated with vulnerability.", + "items": { + "type": "object", + "description": "Describes an asset associated with vulnerability.", + "required": [ + "type", + "name", + "url" + ], + "properties": { + "type": { + "type": "string", + "description": "The type of asset", + "enum": [ + "http_session", + "postman" + ] + }, + "name": { + "type": "string", + "minLength": 1, + "description": "Display name for asset", + "examples": [ + "HTTP Messages", + "Postman Collection" + ] + }, + "url": { + "type": "string", + "minLength": 1, + "description": "Link to asset in build artifacts", + "examples": [ + "https://gitlab.com/gitlab-org/security-products/dast/-/jobs/626397001/artifacts/file//output/zap_session.data" + ] + } + } + } + } + } + } + }, + "remediations": { + "type": "array", + "description": "An array of objects containing information on available remediations, along with patch diffs to apply.", + "items": { + "type": "object", + "required": [ + "fixes", + "summary", + "diff" + ], + "properties": { + "fixes": { + "type": "array", + "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.", + "items": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.", + "examples": [ + "642735a5-1425-428d-8d4e-3c854885a3c9" + ] + } + } + } + }, + "summary": { + "type": "string", + "minLength": 1, + "description": "An overview of how the vulnerabilities were fixed." + }, + "diff": { + "type": "string", + "minLength": 1, + "description": "A base64-encoded remediation code diff, compatible with git apply." + } + } + } + } + } +} diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dependency-scanning-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dependency-scanning-report-format.json new file mode 100644 index 00000000000..ade1ce9ea8f --- /dev/null +++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/dependency-scanning-report-format.json @@ -0,0 +1,944 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/dependency-scanning-report-format.json", + "title": "Report format for GitLab Dependency Scanning", + "description": "This schema provides the the report format for Dependency Scanning analyzers (https://docs.gitlab.com/ee/user/application_security/dependency_scanning).", + "definitions": { + "detail_type": { + "oneOf": [ + { + "$ref": "#/definitions/named_list" + }, + { + "$ref": "#/definitions/list" + }, + { + "$ref": "#/definitions/table" + }, + { + "$ref": "#/definitions/text" + }, + { + "$ref": "#/definitions/url" + }, + { + "$ref": "#/definitions/code" + }, + { + "$ref": "#/definitions/value" + }, + { + "$ref": "#/definitions/diff" + }, + { + "$ref": "#/definitions/markdown" + }, + { + "$ref": "#/definitions/commit" + }, + { + "$ref": "#/definitions/file_location" + }, + { + "$ref": "#/definitions/module_location" + } + ] + }, + "text_value": { + "type": "string" + }, + "named_field": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "$ref": "#/definitions/text_value", + "minLength": 1 + }, + "description": { + "$ref": "#/definitions/text_value" + } + } + }, + "named_list": { + "type": "object", + "description": "An object with named and typed fields", + "required": [ + "type", + "items" + ], + "properties": { + "type": { + "const": "named-list" + }, + "items": { + "type": "object", + "patternProperties": { + "^.*$": { + "allOf": [ + { + "$ref": "#/definitions/named_field" + }, + { + "$ref": "#/definitions/detail_type" + } + ] + } + } + } + } + }, + "list": { + "type": "object", + "description": "A list of typed fields", + "required": [ + "type", + "items" + ], + "properties": { + "type": { + "const": "list" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + } + } + }, + "table": { + "type": "object", + "description": "A table of typed fields", + "required": [ + "type", + "rows" + ], + "properties": { + "type": { + "const": "table" + }, + "header": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + }, + "rows": { + "type": "array", + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + } + } + } + }, + "text": { + "type": "object", + "description": "Raw text", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "text" + }, + "value": { + "$ref": "#/definitions/text_value" + } + } + }, + "url": { + "type": "object", + "description": "A single URL", + "required": [ + "type", + "href" + ], + "properties": { + "type": { + "const": "url" + }, + "text": { + "$ref": "#/definitions/text_value" + }, + "href": { + "type": "string", + "minLength": 1, + "examples": [ + "http://mysite.com" + ] + } + } + }, + "code": { + "type": "object", + "description": "A codeblock", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "code" + }, + "value": { + "type": "string" + }, + "lang": { + "type": "string", + "description": "A programming language" + } + } + }, + "value": { + "type": "object", + "description": "A field that can store a range of types of value", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "value" + }, + "value": { + "type": [ + "number", + "string", + "boolean" + ] + } + } + }, + "diff": { + "type": "object", + "description": "A diff", + "required": [ + "type", + "before", + "after" + ], + "properties": { + "type": { + "const": "diff" + }, + "before": { + "type": "string" + }, + "after": { + "type": "string" + } + } + }, + "markdown": { + "type": "object", + "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "markdown" + }, + "value": { + "$ref": "#/definitions/text_value", + "examples": [ + "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)" + ] + } + } + }, + "commit": { + "type": "object", + "description": "A commit/tag/branch within the GitLab project", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "commit" + }, + "value": { + "type": "string", + "description": "The commit SHA", + "minLength": 1 + } + } + }, + "file_location": { + "type": "object", + "description": "A location within a file in the project", + "required": [ + "type", + "file_name", + "line_start" + ], + "properties": { + "type": { + "const": "file-location" + }, + "file_name": { + "type": "string", + "minLength": 1 + }, + "line_start": { + "type": "integer" + }, + "line_end": { + "type": "integer" + } + } + }, + "module_location": { + "type": "object", + "description": "A location within a binary module of the form module+relative_offset", + "required": [ + "type", + "module_name", + "offset" + ], + "properties": { + "type": { + "const": "module-location" + }, + "module_name": { + "type": "string", + "minLength": 1, + "examples": [ + "compiled_binary" + ] + }, + "offset": { + "type": "integer", + "examples": [ + 100 + ] + } + } + } + }, + "self": { + "version": "15.0.0" + }, + "required": [ + "dependency_files", + "scan", + "version", + "vulnerabilities" + ], + "additionalProperties": true, + "properties": { + "scan": { + "type": "object", + "required": [ + "analyzer", + "end_time", + "scanner", + "start_time", + "status", + "type" + ], + "properties": { + "end_time": { + "type": "string", + "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$", + "examples": [ + "2020-01-28T03:26:02" + ] + }, + "messages": { + "type": "array", + "items": { + "type": "object", + "description": "Communication intended for the initiator of a scan.", + "required": [ + "level", + "value" + ], + "properties": { + "level": { + "type": "string", + "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.", + "enum": [ + "info", + "warn", + "fatal" + ], + "examples": [ + "info" + ] + }, + "value": { + "type": "string", + "description": "The message to communicate.", + "minLength": 1, + "examples": [ + "Permission denied, scanning aborted" + ] + } + } + } + }, + "analyzer": { + "type": "object", + "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.", + "required": [ + "id", + "name", + "version", + "vendor" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique id that identifies the analyzer.", + "minLength": 1, + "examples": [ + "gitlab-dast" + ] + }, + "name": { + "type": "string", + "description": "A human readable value that identifies the analyzer, not required to be unique.", + "minLength": 1, + "examples": [ + "GitLab DAST" + ] + }, + "url": { + "type": "string", + "pattern": "^https?://.+", + "description": "A link to more information about the analyzer.", + "examples": [ + "https://docs.gitlab.com/ee/user/application_security/dast" + ] + }, + "vendor": { + "description": "The vendor/maintainer of the analyzer.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "The name of the vendor.", + "minLength": 1, + "examples": [ + "GitLab" + ] + } + } + }, + "version": { + "type": "string", + "description": "The version of the analyzer.", + "minLength": 1, + "examples": [ + "1.0.2" + ] + } + } + }, + "scanner": { + "type": "object", + "description": "Object defining the scanner used to perform the scan.", + "required": [ + "id", + "name", + "version", + "vendor" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique id that identifies the scanner.", + "minLength": 1, + "examples": [ + "my-sast-scanner" + ] + }, + "name": { + "type": "string", + "description": "A human readable value that identifies the scanner, not required to be unique.", + "minLength": 1, + "examples": [ + "My SAST Scanner" + ] + }, + "url": { + "type": "string", + "description": "A link to more information about the scanner.", + "examples": [ + "https://scanner.url" + ] + }, + "version": { + "type": "string", + "description": "The version of the scanner.", + "minLength": 1, + "examples": [ + "1.0.2" + ] + }, + "vendor": { + "description": "The vendor/maintainer of the scanner.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "The name of the vendor.", + "minLength": 1, + "examples": [ + "GitLab" + ] + } + } + } + } + }, + "start_time": { + "type": "string", + "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$", + "examples": [ + "2020-02-14T16:01:59" + ] + }, + "status": { + "type": "string", + "description": "Result of the scan.", + "enum": [ + "success", + "failure" + ] + }, + "type": { + "type": "string", + "description": "Type of the scan.", + "enum": [ + "dependency_scanning" + ] + } + } + }, + "schema": { + "type": "string", + "description": "URI pointing to the validating security report schema.", + "pattern": "^https?://.+" + }, + "version": { + "type": "string", + "description": "The version of the schema to which the JSON report conforms.", + "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" + }, + "vulnerabilities": { + "type": "array", + "description": "Array of vulnerability objects.", + "items": { + "type": "object", + "description": "Describes the vulnerability using GitLab Flavored Markdown", + "required": [ + "id", + "identifiers", + "location" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.", + "examples": [ + "642735a5-1425-428d-8d4e-3c854885a3c9" + ] + }, + "name": { + "type": "string", + "maxLength": 255, + "description": "The name of the vulnerability. This must not include the finding's specific information." + }, + "description": { + "type": "string", + "maxLength": 1048576, + "description": "A long text section describing the vulnerability more fully." + }, + "severity": { + "type": "string", + "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.", + "enum": [ + "Info", + "Unknown", + "Low", + "Medium", + "High", + "Critical" + ] + }, + "solution": { + "type": "string", + "maxLength": 7000, + "description": "Explanation of how to fix the vulnerability." + }, + "identifiers": { + "type": "array", + "minItems": 1, + "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.", + "items": { + "type": "object", + "required": [ + "type", + "name", + "value" + ], + "properties": { + "type": { + "type": "string", + "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).", + "minLength": 1 + }, + "name": { + "type": "string", + "description": "Human-readable name of the identifier.", + "minLength": 1 + }, + "url": { + "type": "string", + "description": "URL of the identifier's documentation.", + "pattern": "^https?://.+" + }, + "value": { + "type": "string", + "description": "Value of the identifier, for matching purpose.", + "minLength": 1 + } + } + } + }, + "links": { + "type": "array", + "description": "An array of references to external documentation or articles that describe the vulnerability.", + "items": { + "type": "object", + "required": [ + "url" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the vulnerability details link." + }, + "url": { + "type": "string", + "description": "URL of the vulnerability details document.", + "pattern": "^https?://.+" + } + } + } + }, + "details": { + "$ref": "#/definitions/named_list/properties/items" + }, + "tracking": { + "description": "Describes how this vulnerability should be tracked as the project changes.", + "oneOf": [ + { + "description": "Declares that a series of items should be tracked using source-specific tracking methods.", + "required": [ + "items" + ], + "properties": { + "type": { + "const": "source" + }, + "items": { + "type": "array", + "items": { + "description": "An item that should be tracked using source-specific tracking methods.", + "type": "object", + "required": [ + "signatures" + ], + "properties": { + "file": { + "type": "string", + "description": "Path to the file where the vulnerability is located." + }, + "start_line": { + "type": "number", + "description": "The first line of the file that includes the vulnerability." + }, + "end_line": { + "type": "number", + "description": "The last line of the file that includes the vulnerability." + }, + "signatures": { + "type": "array", + "description": "An array of calculated tracking signatures for this tracking item.", + "minItems": 1, + "items": { + "description": "A calculated tracking signature value and metadata.", + "required": [ + "algorithm", + "value" + ], + "properties": { + "algorithm": { + "type": "string", + "description": "The algorithm used to generate the signature." + }, + "value": { + "type": "string", + "description": "The result of this signature algorithm." + } + } + } + } + } + } + } + } + } + ], + "properties": { + "type": { + "type": "string", + "description": "Each tracking type must declare its own type." + } + } + }, + "flags": { + "description": "Flags that can be attached to vulnerabilities.", + "type": "array", + "items": { + "type": "object", + "description": "Informational flags identified and assigned to a vulnerability.", + "required": [ + "type", + "origin", + "description" + ], + "properties": { + "type": { + "type": "string", + "minLength": 1, + "description": "Result of the scan.", + "enum": [ + "flagged-as-likely-false-positive" + ] + }, + "origin": { + "minLength": 1, + "description": "Tool that issued the flag.", + "type": "string" + }, + "description": { + "minLength": 1, + "description": "What the flag is about.", + "type": "string" + } + } + } + }, + "location": { + "type": "object", + "description": "Identifies the vulnerability's location.", + "required": [ + "file", + "dependency" + ], + "properties": { + "file": { + "type": "string", + "minLength": 1, + "description": "Path to the manifest or lock file where the dependency is declared (such as yarn.lock)." + }, + "dependency": { + "type": "object", + "description": "Describes the dependency of a project where the vulnerability is located.", + "required": [ + "package", + "version" + ], + "properties": { + "package": { + "type": "object", + "description": "Provides information on the package where the vulnerability is located.", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the package where the vulnerability is located." + } + } + }, + "version": { + "type": "string", + "description": "Version of the vulnerable package." + }, + "iid": { + "description": "ID that identifies the dependency in the scope of a dependency file.", + "type": "number" + }, + "direct": { + "type": "boolean", + "description": "Tells whether this is a direct, top-level dependency of the scanned project." + }, + "dependency_path": { + "type": "array", + "description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.", + "items": { + "type": "object", + "required": [ + "iid" + ], + "properties": { + "iid": { + "type": "number", + "description": "ID that is unique in the scope of a parent object, and specific to the resource type." + } + } + } + } + } + } + } + } + } + } + }, + "remediations": { + "type": "array", + "description": "An array of objects containing information on available remediations, along with patch diffs to apply.", + "items": { + "type": "object", + "required": [ + "fixes", + "summary", + "diff" + ], + "properties": { + "fixes": { + "type": "array", + "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.", + "items": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.", + "examples": [ + "642735a5-1425-428d-8d4e-3c854885a3c9" + ] + } + } + } + }, + "summary": { + "type": "string", + "minLength": 1, + "description": "An overview of how the vulnerabilities were fixed." + }, + "diff": { + "type": "string", + "minLength": 1, + "description": "A base64-encoded remediation code diff, compatible with git apply." + } + } + } + }, + "dependency_files": { + "type": "array", + "description": "List of dependency files identified in the project.", + "items": { + "type": "object", + "required": [ + "path", + "package_manager", + "dependencies" + ], + "properties": { + "path": { + "type": "string", + "minLength": 1 + }, + "package_manager": { + "type": "string", + "minLength": 1 + }, + "dependencies": { + "type": "array", + "items": { + "type": "object", + "description": "Describes the dependency of a project where the vulnerability is located.", + "required": [ + "package", + "version" + ], + "properties": { + "package": { + "type": "object", + "description": "Provides information on the package where the vulnerability is located.", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the package where the vulnerability is located." + } + } + }, + "version": { + "type": "string", + "description": "Version of the vulnerable package." + }, + "iid": { + "description": "ID that identifies the dependency in the scope of a dependency file.", + "type": "number" + }, + "direct": { + "type": "boolean", + "description": "Tells whether this is a direct, top-level dependency of the scanned project." + }, + "dependency_path": { + "type": "array", + "description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.", + "items": { + "type": "object", + "required": [ + "iid" + ], + "properties": { + "iid": { + "type": "number", + "description": "ID that is unique in the scope of a parent object, and specific to the resource type." + } + } + } + } + } + } + } + } + } + } + } +} diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/sast-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/sast-report-format.json new file mode 100644 index 00000000000..9fae45d728e --- /dev/null +++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/sast-report-format.json @@ -0,0 +1,831 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/sast-report-format.json", + "title": "Report format for GitLab SAST", + "description": "This schema provides the report format for Static Application Security Testing analyzers (https://docs.gitlab.com/ee/user/application_security/sast).", + "definitions": { + "detail_type": { + "oneOf": [ + { + "$ref": "#/definitions/named_list" + }, + { + "$ref": "#/definitions/list" + }, + { + "$ref": "#/definitions/table" + }, + { + "$ref": "#/definitions/text" + }, + { + "$ref": "#/definitions/url" + }, + { + "$ref": "#/definitions/code" + }, + { + "$ref": "#/definitions/value" + }, + { + "$ref": "#/definitions/diff" + }, + { + "$ref": "#/definitions/markdown" + }, + { + "$ref": "#/definitions/commit" + }, + { + "$ref": "#/definitions/file_location" + }, + { + "$ref": "#/definitions/module_location" + } + ] + }, + "text_value": { + "type": "string" + }, + "named_field": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "$ref": "#/definitions/text_value", + "minLength": 1 + }, + "description": { + "$ref": "#/definitions/text_value" + } + } + }, + "named_list": { + "type": "object", + "description": "An object with named and typed fields", + "required": [ + "type", + "items" + ], + "properties": { + "type": { + "const": "named-list" + }, + "items": { + "type": "object", + "patternProperties": { + "^.*$": { + "allOf": [ + { + "$ref": "#/definitions/named_field" + }, + { + "$ref": "#/definitions/detail_type" + } + ] + } + } + } + } + }, + "list": { + "type": "object", + "description": "A list of typed fields", + "required": [ + "type", + "items" + ], + "properties": { + "type": { + "const": "list" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + } + } + }, + "table": { + "type": "object", + "description": "A table of typed fields", + "required": [ + "type", + "rows" + ], + "properties": { + "type": { + "const": "table" + }, + "header": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + }, + "rows": { + "type": "array", + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + } + } + } + }, + "text": { + "type": "object", + "description": "Raw text", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "text" + }, + "value": { + "$ref": "#/definitions/text_value" + } + } + }, + "url": { + "type": "object", + "description": "A single URL", + "required": [ + "type", + "href" + ], + "properties": { + "type": { + "const": "url" + }, + "text": { + "$ref": "#/definitions/text_value" + }, + "href": { + "type": "string", + "minLength": 1, + "examples": [ + "http://mysite.com" + ] + } + } + }, + "code": { + "type": "object", + "description": "A codeblock", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "code" + }, + "value": { + "type": "string" + }, + "lang": { + "type": "string", + "description": "A programming language" + } + } + }, + "value": { + "type": "object", + "description": "A field that can store a range of types of value", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "value" + }, + "value": { + "type": [ + "number", + "string", + "boolean" + ] + } + } + }, + "diff": { + "type": "object", + "description": "A diff", + "required": [ + "type", + "before", + "after" + ], + "properties": { + "type": { + "const": "diff" + }, + "before": { + "type": "string" + }, + "after": { + "type": "string" + } + } + }, + "markdown": { + "type": "object", + "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "markdown" + }, + "value": { + "$ref": "#/definitions/text_value", + "examples": [ + "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)" + ] + } + } + }, + "commit": { + "type": "object", + "description": "A commit/tag/branch within the GitLab project", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "commit" + }, + "value": { + "type": "string", + "description": "The commit SHA", + "minLength": 1 + } + } + }, + "file_location": { + "type": "object", + "description": "A location within a file in the project", + "required": [ + "type", + "file_name", + "line_start" + ], + "properties": { + "type": { + "const": "file-location" + }, + "file_name": { + "type": "string", + "minLength": 1 + }, + "line_start": { + "type": "integer" + }, + "line_end": { + "type": "integer" + } + } + }, + "module_location": { + "type": "object", + "description": "A location within a binary module of the form module+relative_offset", + "required": [ + "type", + "module_name", + "offset" + ], + "properties": { + "type": { + "const": "module-location" + }, + "module_name": { + "type": "string", + "minLength": 1, + "examples": [ + "compiled_binary" + ] + }, + "offset": { + "type": "integer", + "examples": [ + 100 + ] + } + } + } + }, + "self": { + "version": "15.0.0" + }, + "required": [ + "scan", + "version", + "vulnerabilities" + ], + "additionalProperties": true, + "properties": { + "scan": { + "type": "object", + "required": [ + "analyzer", + "end_time", + "scanner", + "start_time", + "status", + "type" + ], + "properties": { + "end_time": { + "type": "string", + "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$", + "examples": [ + "2020-01-28T03:26:02" + ] + }, + "messages": { + "type": "array", + "items": { + "type": "object", + "description": "Communication intended for the initiator of a scan.", + "required": [ + "level", + "value" + ], + "properties": { + "level": { + "type": "string", + "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.", + "enum": [ + "info", + "warn", + "fatal" + ], + "examples": [ + "info" + ] + }, + "value": { + "type": "string", + "description": "The message to communicate.", + "minLength": 1, + "examples": [ + "Permission denied, scanning aborted" + ] + } + } + } + }, + "analyzer": { + "type": "object", + "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.", + "required": [ + "id", + "name", + "version", + "vendor" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique id that identifies the analyzer.", + "minLength": 1, + "examples": [ + "gitlab-dast" + ] + }, + "name": { + "type": "string", + "description": "A human readable value that identifies the analyzer, not required to be unique.", + "minLength": 1, + "examples": [ + "GitLab DAST" + ] + }, + "url": { + "type": "string", + "pattern": "^https?://.+", + "description": "A link to more information about the analyzer.", + "examples": [ + "https://docs.gitlab.com/ee/user/application_security/dast" + ] + }, + "vendor": { + "description": "The vendor/maintainer of the analyzer.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "The name of the vendor.", + "minLength": 1, + "examples": [ + "GitLab" + ] + } + } + }, + "version": { + "type": "string", + "description": "The version of the analyzer.", + "minLength": 1, + "examples": [ + "1.0.2" + ] + } + } + }, + "scanner": { + "type": "object", + "description": "Object defining the scanner used to perform the scan.", + "required": [ + "id", + "name", + "version", + "vendor" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique id that identifies the scanner.", + "minLength": 1, + "examples": [ + "my-sast-scanner" + ] + }, + "name": { + "type": "string", + "description": "A human readable value that identifies the scanner, not required to be unique.", + "minLength": 1, + "examples": [ + "My SAST Scanner" + ] + }, + "url": { + "type": "string", + "description": "A link to more information about the scanner.", + "examples": [ + "https://scanner.url" + ] + }, + "version": { + "type": "string", + "description": "The version of the scanner.", + "minLength": 1, + "examples": [ + "1.0.2" + ] + }, + "vendor": { + "description": "The vendor/maintainer of the scanner.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "The name of the vendor.", + "minLength": 1, + "examples": [ + "GitLab" + ] + } + } + } + } + }, + "start_time": { + "type": "string", + "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$", + "examples": [ + "2020-02-14T16:01:59" + ] + }, + "status": { + "type": "string", + "description": "Result of the scan.", + "enum": [ + "success", + "failure" + ] + }, + "type": { + "type": "string", + "description": "Type of the scan.", + "enum": [ + "sast" + ] + } + } + }, + "schema": { + "type": "string", + "description": "URI pointing to the validating security report schema.", + "pattern": "^https?://.+" + }, + "version": { + "type": "string", + "description": "The version of the schema to which the JSON report conforms.", + "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" + }, + "vulnerabilities": { + "type": "array", + "description": "Array of vulnerability objects.", + "items": { + "type": "object", + "description": "Describes the vulnerability using GitLab Flavored Markdown", + "required": [ + "id", + "identifiers", + "location" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.", + "examples": [ + "642735a5-1425-428d-8d4e-3c854885a3c9" + ] + }, + "name": { + "type": "string", + "maxLength": 255, + "description": "The name of the vulnerability. This must not include the finding's specific information." + }, + "description": { + "type": "string", + "maxLength": 1048576, + "description": "A long text section describing the vulnerability more fully." + }, + "severity": { + "type": "string", + "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.", + "enum": [ + "Info", + "Unknown", + "Low", + "Medium", + "High", + "Critical" + ] + }, + "solution": { + "type": "string", + "maxLength": 7000, + "description": "Explanation of how to fix the vulnerability." + }, + "identifiers": { + "type": "array", + "minItems": 1, + "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.", + "items": { + "type": "object", + "required": [ + "type", + "name", + "value" + ], + "properties": { + "type": { + "type": "string", + "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).", + "minLength": 1 + }, + "name": { + "type": "string", + "description": "Human-readable name of the identifier.", + "minLength": 1 + }, + "url": { + "type": "string", + "description": "URL of the identifier's documentation.", + "pattern": "^https?://.+" + }, + "value": { + "type": "string", + "description": "Value of the identifier, for matching purpose.", + "minLength": 1 + } + } + } + }, + "links": { + "type": "array", + "description": "An array of references to external documentation or articles that describe the vulnerability.", + "items": { + "type": "object", + "required": [ + "url" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the vulnerability details link." + }, + "url": { + "type": "string", + "description": "URL of the vulnerability details document.", + "pattern": "^https?://.+" + } + } + } + }, + "details": { + "$ref": "#/definitions/named_list/properties/items" + }, + "tracking": { + "description": "Describes how this vulnerability should be tracked as the project changes.", + "oneOf": [ + { + "description": "Declares that a series of items should be tracked using source-specific tracking methods.", + "required": [ + "items" + ], + "properties": { + "type": { + "const": "source" + }, + "items": { + "type": "array", + "items": { + "description": "An item that should be tracked using source-specific tracking methods.", + "type": "object", + "required": [ + "signatures" + ], + "properties": { + "file": { + "type": "string", + "description": "Path to the file where the vulnerability is located." + }, + "start_line": { + "type": "number", + "description": "The first line of the file that includes the vulnerability." + }, + "end_line": { + "type": "number", + "description": "The last line of the file that includes the vulnerability." + }, + "signatures": { + "type": "array", + "description": "An array of calculated tracking signatures for this tracking item.", + "minItems": 1, + "items": { + "description": "A calculated tracking signature value and metadata.", + "required": [ + "algorithm", + "value" + ], + "properties": { + "algorithm": { + "type": "string", + "description": "The algorithm used to generate the signature." + }, + "value": { + "type": "string", + "description": "The result of this signature algorithm." + } + } + } + } + } + } + } + } + } + ], + "properties": { + "type": { + "type": "string", + "description": "Each tracking type must declare its own type." + } + } + }, + "flags": { + "description": "Flags that can be attached to vulnerabilities.", + "type": "array", + "items": { + "type": "object", + "description": "Informational flags identified and assigned to a vulnerability.", + "required": [ + "type", + "origin", + "description" + ], + "properties": { + "type": { + "type": "string", + "minLength": 1, + "description": "Result of the scan.", + "enum": [ + "flagged-as-likely-false-positive" + ] + }, + "origin": { + "minLength": 1, + "description": "Tool that issued the flag.", + "type": "string" + }, + "description": { + "minLength": 1, + "description": "What the flag is about.", + "type": "string" + } + } + } + }, + "location": { + "type": "object", + "description": "Identifies the vulnerability's location.", + "properties": { + "file": { + "type": "string", + "description": "Path to the file where the vulnerability is located." + }, + "start_line": { + "type": "number", + "description": "The first line of the code affected by the vulnerability." + }, + "end_line": { + "type": "number", + "description": "The last line of the code affected by the vulnerability." + }, + "class": { + "type": "string", + "description": "Provides the name of the class where the vulnerability is located." + }, + "method": { + "type": "string", + "description": "Provides the name of the method where the vulnerability is located." + } + } + }, + "raw_source_code_extract": { + "type": "string", + "description": "Provides an unsanitized excerpt of the affected source code." + } + } + } + }, + "remediations": { + "type": "array", + "description": "An array of objects containing information on available remediations, along with patch diffs to apply.", + "items": { + "type": "object", + "required": [ + "fixes", + "summary", + "diff" + ], + "properties": { + "fixes": { + "type": "array", + "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.", + "items": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.", + "examples": [ + "642735a5-1425-428d-8d4e-3c854885a3c9" + ] + } + } + } + }, + "summary": { + "type": "string", + "minLength": 1, + "description": "An overview of how the vulnerabilities were fixed." + }, + "diff": { + "type": "string", + "minLength": 1, + "description": "A base64-encoded remediation code diff, compatible with git apply." + } + } + } + } + } +} diff --git a/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/secret-detection-report-format.json b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/secret-detection-report-format.json new file mode 100644 index 00000000000..fca00e17f26 --- /dev/null +++ b/lib/gitlab/ci/parsers/security/validators/schemas/15.0.0/secret-detection-report-format.json @@ -0,0 +1,854 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/master/dist/secret-detection-report-format.json", + "title": "Report format for GitLab Secret Detection", + "description": "This schema provides the the report format for the Secret Detection analyzer (https://docs.gitlab.com/ee/user/application_security/secret_detection)", + "definitions": { + "detail_type": { + "oneOf": [ + { + "$ref": "#/definitions/named_list" + }, + { + "$ref": "#/definitions/list" + }, + { + "$ref": "#/definitions/table" + }, + { + "$ref": "#/definitions/text" + }, + { + "$ref": "#/definitions/url" + }, + { + "$ref": "#/definitions/code" + }, + { + "$ref": "#/definitions/value" + }, + { + "$ref": "#/definitions/diff" + }, + { + "$ref": "#/definitions/markdown" + }, + { + "$ref": "#/definitions/commit" + }, + { + "$ref": "#/definitions/file_location" + }, + { + "$ref": "#/definitions/module_location" + } + ] + }, + "text_value": { + "type": "string" + }, + "named_field": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "$ref": "#/definitions/text_value", + "minLength": 1 + }, + "description": { + "$ref": "#/definitions/text_value" + } + } + }, + "named_list": { + "type": "object", + "description": "An object with named and typed fields", + "required": [ + "type", + "items" + ], + "properties": { + "type": { + "const": "named-list" + }, + "items": { + "type": "object", + "patternProperties": { + "^.*$": { + "allOf": [ + { + "$ref": "#/definitions/named_field" + }, + { + "$ref": "#/definitions/detail_type" + } + ] + } + } + } + } + }, + "list": { + "type": "object", + "description": "A list of typed fields", + "required": [ + "type", + "items" + ], + "properties": { + "type": { + "const": "list" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + } + } + }, + "table": { + "type": "object", + "description": "A table of typed fields", + "required": [ + "type", + "rows" + ], + "properties": { + "type": { + "const": "table" + }, + "header": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + }, + "rows": { + "type": "array", + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/detail_type" + } + } + } + } + }, + "text": { + "type": "object", + "description": "Raw text", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "text" + }, + "value": { + "$ref": "#/definitions/text_value" + } + } + }, + "url": { + "type": "object", + "description": "A single URL", + "required": [ + "type", + "href" + ], + "properties": { + "type": { + "const": "url" + }, + "text": { + "$ref": "#/definitions/text_value" + }, + "href": { + "type": "string", + "minLength": 1, + "examples": [ + "http://mysite.com" + ] + } + } + }, + "code": { + "type": "object", + "description": "A codeblock", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "code" + }, + "value": { + "type": "string" + }, + "lang": { + "type": "string", + "description": "A programming language" + } + } + }, + "value": { + "type": "object", + "description": "A field that can store a range of types of value", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "value" + }, + "value": { + "type": [ + "number", + "string", + "boolean" + ] + } + } + }, + "diff": { + "type": "object", + "description": "A diff", + "required": [ + "type", + "before", + "after" + ], + "properties": { + "type": { + "const": "diff" + }, + "before": { + "type": "string" + }, + "after": { + "type": "string" + } + } + }, + "markdown": { + "type": "object", + "description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "markdown" + }, + "value": { + "$ref": "#/definitions/text_value", + "examples": [ + "Here is markdown `inline code` #1 [test](gitlab.com)\n\n![GitLab Logo](https://about.gitlab.com/images/press/logo/preview/gitlab-logo-white-preview.png)" + ] + } + } + }, + "commit": { + "type": "object", + "description": "A commit/tag/branch within the GitLab project", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "const": "commit" + }, + "value": { + "type": "string", + "description": "The commit SHA", + "minLength": 1 + } + } + }, + "file_location": { + "type": "object", + "description": "A location within a file in the project", + "required": [ + "type", + "file_name", + "line_start" + ], + "properties": { + "type": { + "const": "file-location" + }, + "file_name": { + "type": "string", + "minLength": 1 + }, + "line_start": { + "type": "integer" + }, + "line_end": { + "type": "integer" + } + } + }, + "module_location": { + "type": "object", + "description": "A location within a binary module of the form module+relative_offset", + "required": [ + "type", + "module_name", + "offset" + ], + "properties": { + "type": { + "const": "module-location" + }, + "module_name": { + "type": "string", + "minLength": 1, + "examples": [ + "compiled_binary" + ] + }, + "offset": { + "type": "integer", + "examples": [ + 100 + ] + } + } + } + }, + "self": { + "version": "15.0.0" + }, + "required": [ + "scan", + "version", + "vulnerabilities" + ], + "additionalProperties": true, + "properties": { + "scan": { + "type": "object", + "required": [ + "analyzer", + "end_time", + "scanner", + "start_time", + "status", + "type" + ], + "properties": { + "end_time": { + "type": "string", + "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$", + "examples": [ + "2020-01-28T03:26:02" + ] + }, + "messages": { + "type": "array", + "items": { + "type": "object", + "description": "Communication intended for the initiator of a scan.", + "required": [ + "level", + "value" + ], + "properties": { + "level": { + "type": "string", + "description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.", + "enum": [ + "info", + "warn", + "fatal" + ], + "examples": [ + "info" + ] + }, + "value": { + "type": "string", + "description": "The message to communicate.", + "minLength": 1, + "examples": [ + "Permission denied, scanning aborted" + ] + } + } + } + }, + "analyzer": { + "type": "object", + "description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.", + "required": [ + "id", + "name", + "version", + "vendor" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique id that identifies the analyzer.", + "minLength": 1, + "examples": [ + "gitlab-dast" + ] + }, + "name": { + "type": "string", + "description": "A human readable value that identifies the analyzer, not required to be unique.", + "minLength": 1, + "examples": [ + "GitLab DAST" + ] + }, + "url": { + "type": "string", + "pattern": "^https?://.+", + "description": "A link to more information about the analyzer.", + "examples": [ + "https://docs.gitlab.com/ee/user/application_security/dast" + ] + }, + "vendor": { + "description": "The vendor/maintainer of the analyzer.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "The name of the vendor.", + "minLength": 1, + "examples": [ + "GitLab" + ] + } + } + }, + "version": { + "type": "string", + "description": "The version of the analyzer.", + "minLength": 1, + "examples": [ + "1.0.2" + ] + } + } + }, + "scanner": { + "type": "object", + "description": "Object defining the scanner used to perform the scan.", + "required": [ + "id", + "name", + "version", + "vendor" + ], + "properties": { + "id": { + "type": "string", + "description": "Unique id that identifies the scanner.", + "minLength": 1, + "examples": [ + "my-sast-scanner" + ] + }, + "name": { + "type": "string", + "description": "A human readable value that identifies the scanner, not required to be unique.", + "minLength": 1, + "examples": [ + "My SAST Scanner" + ] + }, + "url": { + "type": "string", + "description": "A link to more information about the scanner.", + "examples": [ + "https://scanner.url" + ] + }, + "version": { + "type": "string", + "description": "The version of the scanner.", + "minLength": 1, + "examples": [ + "1.0.2" + ] + }, + "vendor": { + "description": "The vendor/maintainer of the scanner.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "The name of the vendor.", + "minLength": 1, + "examples": [ + "GitLab" + ] + } + } + } + } + }, + "start_time": { + "type": "string", + "description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$", + "examples": [ + "2020-02-14T16:01:59" + ] + }, + "status": { + "type": "string", + "description": "Result of the scan.", + "enum": [ + "success", + "failure" + ] + }, + "type": { + "type": "string", + "description": "Type of the scan.", + "enum": [ + "secret_detection" + ] + } + } + }, + "schema": { + "type": "string", + "description": "URI pointing to the validating security report schema.", + "pattern": "^https?://.+" + }, + "version": { + "type": "string", + "description": "The version of the schema to which the JSON report conforms.", + "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" + }, + "vulnerabilities": { + "type": "array", + "description": "Array of vulnerability objects.", + "items": { + "type": "object", + "description": "Describes the vulnerability using GitLab Flavored Markdown", + "required": [ + "id", + "identifiers", + "location" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.", + "examples": [ + "642735a5-1425-428d-8d4e-3c854885a3c9" + ] + }, + "name": { + "type": "string", + "maxLength": 255, + "description": "The name of the vulnerability. This must not include the finding's specific information." + }, + "description": { + "type": "string", + "maxLength": 1048576, + "description": "A long text section describing the vulnerability more fully." + }, + "severity": { + "type": "string", + "description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.", + "enum": [ + "Info", + "Unknown", + "Low", + "Medium", + "High", + "Critical" + ] + }, + "solution": { + "type": "string", + "maxLength": 7000, + "description": "Explanation of how to fix the vulnerability." + }, + "identifiers": { + "type": "array", + "minItems": 1, + "description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.", + "items": { + "type": "object", + "required": [ + "type", + "name", + "value" + ], + "properties": { + "type": { + "type": "string", + "description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).", + "minLength": 1 + }, + "name": { + "type": "string", + "description": "Human-readable name of the identifier.", + "minLength": 1 + }, + "url": { + "type": "string", + "description": "URL of the identifier's documentation.", + "pattern": "^https?://.+" + }, + "value": { + "type": "string", + "description": "Value of the identifier, for matching purpose.", + "minLength": 1 + } + } + } + }, + "links": { + "type": "array", + "description": "An array of references to external documentation or articles that describe the vulnerability.", + "items": { + "type": "object", + "required": [ + "url" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the vulnerability details link." + }, + "url": { + "type": "string", + "description": "URL of the vulnerability details document.", + "pattern": "^https?://.+" + } + } + } + }, + "details": { + "$ref": "#/definitions/named_list/properties/items" + }, + "tracking": { + "description": "Describes how this vulnerability should be tracked as the project changes.", + "oneOf": [ + { + "description": "Declares that a series of items should be tracked using source-specific tracking methods.", + "required": [ + "items" + ], + "properties": { + "type": { + "const": "source" + }, + "items": { + "type": "array", + "items": { + "description": "An item that should be tracked using source-specific tracking methods.", + "type": "object", + "required": [ + "signatures" + ], + "properties": { + "file": { + "type": "string", + "description": "Path to the file where the vulnerability is located." + }, + "start_line": { + "type": "number", + "description": "The first line of the file that includes the vulnerability." + }, + "end_line": { + "type": "number", + "description": "The last line of the file that includes the vulnerability." + }, + "signatures": { + "type": "array", + "description": "An array of calculated tracking signatures for this tracking item.", + "minItems": 1, + "items": { + "description": "A calculated tracking signature value and metadata.", + "required": [ + "algorithm", + "value" + ], + "properties": { + "algorithm": { + "type": "string", + "description": "The algorithm used to generate the signature." + }, + "value": { + "type": "string", + "description": "The result of this signature algorithm." + } + } + } + } + } + } + } + } + } + ], + "properties": { + "type": { + "type": "string", + "description": "Each tracking type must declare its own type." + } + } + }, + "flags": { + "description": "Flags that can be attached to vulnerabilities.", + "type": "array", + "items": { + "type": "object", + "description": "Informational flags identified and assigned to a vulnerability.", + "required": [ + "type", + "origin", + "description" + ], + "properties": { + "type": { + "type": "string", + "minLength": 1, + "description": "Result of the scan.", + "enum": [ + "flagged-as-likely-false-positive" + ] + }, + "origin": { + "minLength": 1, + "description": "Tool that issued the flag.", + "type": "string" + }, + "description": { + "minLength": 1, + "description": "What the flag is about.", + "type": "string" + } + } + } + }, + "location": { + "required": [ + "commit" + ], + "properties": { + "file": { + "type": "string", + "description": "Path to the file where the vulnerability is located" + }, + "commit": { + "type": "object", + "description": "Represents the commit in which the vulnerability was detected", + "required": [ + "sha" + ], + "properties": { + "author": { + "type": "string" + }, + "date": { + "type": "string" + }, + "message": { + "type": "string" + }, + "sha": { + "type": "string", + "minLength": 1 + } + } + }, + "start_line": { + "type": "number", + "description": "The first line of the code affected by the vulnerability" + }, + "end_line": { + "type": "number", + "description": "The last line of the code affected by the vulnerability" + }, + "class": { + "type": "string", + "description": "Provides the name of the class where the vulnerability is located" + }, + "method": { + "type": "string", + "description": "Provides the name of the method where the vulnerability is located" + } + } + }, + "raw_source_code_extract": { + "type": "string", + "description": "Provides an unsanitized excerpt of the affected source code." + } + } + } + }, + "remediations": { + "type": "array", + "description": "An array of objects containing information on available remediations, along with patch diffs to apply.", + "items": { + "type": "object", + "required": [ + "fixes", + "summary", + "diff" + ], + "properties": { + "fixes": { + "type": "array", + "description": "An array of strings that represent references to vulnerabilities fixed by this remediation.", + "items": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "description": "Unique identifier of the vulnerability. This is recommended to be a UUID.", + "examples": [ + "642735a5-1425-428d-8d4e-3c854885a3c9" + ] + } + } + } + }, + "summary": { + "type": "string", + "minLength": 1, + "description": "An overview of how the vulnerabilities were fixed." + }, + "diff": { + "type": "string", + "minLength": 1, + "description": "A base64-encoded remediation code diff, compatible with git apply." + } + } + } + } + } +} diff --git a/lib/gitlab/ci/pipeline/chain/command.rb b/lib/gitlab/ci/pipeline/chain/command.rb index 0a6f6fd740c..2419b039f24 100644 --- a/lib/gitlab/ci/pipeline/chain/command.rb +++ b/lib/gitlab/ci/pipeline/chain/command.rb @@ -117,8 +117,14 @@ module Gitlab end def observe_jobs_count_in_alive_pipelines + jobs_count = if Feature.enabled?(:ci_limit_active_jobs_early, project) + project.all_pipelines.jobs_count_in_alive_pipelines + else + project.all_pipelines.builds_count_in_alive_pipelines + end + metrics.active_jobs_histogram - .observe({ plan: project.actual_plan_name }, project.all_pipelines.jobs_count_in_alive_pipelines) + .observe({ plan: project.actual_plan_name }, jobs_count) end def increment_pipeline_failure_reason_counter(reason) diff --git a/lib/gitlab/ci/pipeline/chain/validate/external.rb b/lib/gitlab/ci/pipeline/chain/validate/external.rb index f4fa9e5fe2a..915e48828d2 100644 --- a/lib/gitlab/ci/pipeline/chain/validate/external.rb +++ b/lib/gitlab/ci/pipeline/chain/validate/external.rb @@ -107,7 +107,7 @@ module Gitlab type: pipeline.source }, builds: builds_validation_payload, - total_builds_count: current_user.pipelines.jobs_count_in_alive_pipelines + total_builds_count: current_user.pipelines.builds_count_in_alive_pipelines } end diff --git a/lib/gitlab/request_forgery_protection.rb b/lib/gitlab/request_forgery_protection.rb index a84a6ac2d14..258c904290d 100644 --- a/lib/gitlab/request_forgery_protection.rb +++ b/lib/gitlab/request_forgery_protection.rb @@ -6,6 +6,7 @@ module Gitlab module RequestForgeryProtection + # rubocop:disable Rails/ApplicationController class Controller < ActionController::Base protect_from_forgery with: :exception, prepend: true @@ -31,5 +32,6 @@ module Gitlab rescue ActionController::InvalidAuthenticityToken false end + # rubocop:enable Rails/ApplicationController end end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 89948816374..dbeb1447940 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -27054,12 +27054,18 @@ msgstr "" msgid "Notify|%{paragraph_start}Hi %{name}!%{paragraph_end} %{paragraph_start}A new public key was added to your account:%{paragraph_end} %{paragraph_start}title: %{key_title}%{paragraph_end} %{paragraph_start}If this key was added in error, you can remove it under %{removal_link}%{paragraph_end}" msgstr "" +msgid "Notify|%{update_at_start} Last update at %{update_at_mid} %{last_update_at} %{update_at_end}" +msgstr "" + msgid "Notify|%{updated_by_user_name} pushed new commits to merge request %{mr_link}" msgstr "" msgid "Notify|A new GPG key was added to your account:" msgstr "" +msgid "Notify|A remote mirror update has failed." +msgstr "" + msgid "Notify|All discussions on merge request %{mr_link} were resolved by %{name}" msgstr "" @@ -27111,6 +27117,9 @@ msgstr "" msgid "Notify|Learn more about Auto DevOps" msgstr "" +msgid "Notify|Logs may contain sensitive data. Please consider before forwarding this email." +msgstr "" + msgid "Notify|Merge request %{merge_request} can no longer be merged due to conflict." msgstr "" @@ -27147,6 +27156,9 @@ msgstr "" msgid "Notify|Pipeline %{pipeline_link} triggered by" msgstr "" +msgid "Notify|Remote mirror" +msgstr "" + msgid "Notify|The Auto DevOps pipeline failed for pipeline %{pipeline_link} and has been disabled for %{project_link}. In order to use the Auto DevOps pipeline with your project, please review the %{supported_langs_link}, adjust your project accordingly, and turn on the Auto DevOps pipeline within your %{settings_link}." msgstr "" @@ -44092,6 +44104,9 @@ msgstr "" msgid "Vulnerability|Project" msgstr "" +msgid "Vulnerability|Project:" +msgstr "" + msgid "Vulnerability|Remove identifier row" msgstr "" @@ -44119,6 +44134,9 @@ msgstr "" msgid "Vulnerability|Severity" msgstr "" +msgid "Vulnerability|Severity:" +msgstr "" + msgid "Vulnerability|Status" msgstr "" diff --git a/rubocop/code_reuse_helpers.rb b/rubocop/code_reuse_helpers.rb index 87b907f8778..245bbc31cbd 100644 --- a/rubocop/code_reuse_helpers.rb +++ b/rubocop/code_reuse_helpers.rb @@ -163,7 +163,7 @@ module RuboCop each_send_node(node) do |send_node| next unless send_receiver_name_ends_with?(send_node, suffix) - add_offense(send_node, location: :expression, message: message) + add_offense(send_node, message: message) end end diff --git a/rubocop/cop/active_model_errors_direct_manipulation.rb b/rubocop/cop/active_model_errors_direct_manipulation.rb index e1e2840f37c..0a3af067743 100644 --- a/rubocop/cop/active_model_errors_direct_manipulation.rb +++ b/rubocop/cop/active_model_errors_direct_manipulation.rb @@ -6,7 +6,7 @@ module RuboCop # in preparation to upgrade to Rails 6.1 # # See https://gitlab.com/gitlab-org/gitlab/-/issues/225874 - class ActiveModelErrorsDirectManipulation < RuboCop::Cop::Cop + class ActiveModelErrorsDirectManipulation < RuboCop::Cop::Base MSG = 'Avoid manipulating errors hash directly. For more details check https://gitlab.com/gitlab-org/gitlab/-/issues/225874' MANIPULATIVE_METHODS = ":<< :append :clear :collect! :compact! :concat :delete :delete_at :delete_if :drop :drop_while :fill :filter! :keep_if :flatten! :insert :map! :pop :prepend :push :reject! :replace :reverse! :rotate! :select! :shift :shuffle! :slice! :sort! :sort_by! :uniq! :unshift" @@ -50,10 +50,10 @@ module RuboCop PATTERN def on_send(node) - add_offense(node, location: :expression) if active_model_errors_root_assignment?(node) - add_offense(node, location: :expression) if active_model_errors_root_manipulation?(node) - add_offense(node, location: :expression) if active_model_errors_manipulation?(node) - add_offense(node, location: :expression) if active_model_errors_assignment?(node) + add_offense(node) if active_model_errors_root_assignment?(node) + add_offense(node) if active_model_errors_root_manipulation?(node) + add_offense(node) if active_model_errors_manipulation?(node) + add_offense(node) if active_model_errors_assignment?(node) end end end diff --git a/rubocop/cop/active_record_association_reload.rb b/rubocop/cop/active_record_association_reload.rb index eb9fc8a0246..9a1e9674904 100644 --- a/rubocop/cop/active_record_association_reload.rb +++ b/rubocop/cop/active_record_association_reload.rb @@ -3,7 +3,7 @@ module RuboCop module Cop # Cop that blacklists the use of `reload`. - class ActiveRecordAssociationReload < RuboCop::Cop::Cop + class ActiveRecordAssociationReload < RuboCop::Cop::Base MSG = 'Use reset instead of reload. ' \ 'For more details check the https://gitlab.com/gitlab-org/gitlab-foss/issues/60218.' @@ -14,7 +14,7 @@ module RuboCop def on_send(node) return unless reload?(node) - add_offense(node, location: :selector) + add_offense(node.loc.selector) end end end diff --git a/rubocop/cop/api/base.rb b/rubocop/cop/api/base.rb index 85b19e9a833..c10115c8265 100644 --- a/rubocop/cop/api/base.rb +++ b/rubocop/cop/api/base.rb @@ -3,7 +3,9 @@ module RuboCop module Cop module API - class Base < RuboCop::Cop::Cop + class Base < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + # This cop checks that APIs subclass API::Base. # # @example @@ -38,13 +40,9 @@ module RuboCop def on_class(node) grape_api_definition(node) do - add_offense(node.children[1]) - end - end - - def autocorrect(node) - lambda do |corrector| - corrector.replace(node, '::API::Base') + add_offense(node.children[1]) do |corrector| + corrector.replace(node.children[1], '::API::Base') + end end end end diff --git a/rubocop/cop/api/grape_array_missing_coerce.rb b/rubocop/cop/api/grape_array_missing_coerce.rb index 3d7a6a72d81..5cb80e113a4 100644 --- a/rubocop/cop/api/grape_array_missing_coerce.rb +++ b/rubocop/cop/api/grape_array_missing_coerce.rb @@ -3,7 +3,7 @@ module RuboCop module Cop module API - class GrapeArrayMissingCoerce < RuboCop::Cop::Cop + class GrapeArrayMissingCoerce < RuboCop::Cop::Base # This cop checks that Grape API parameters using an Array type # implement a coerce_with method: # diff --git a/rubocop/cop/avoid_becomes.rb b/rubocop/cop/avoid_becomes.rb index cfd6b3d2164..20df394c32c 100644 --- a/rubocop/cop/avoid_becomes.rb +++ b/rubocop/cop/avoid_becomes.rb @@ -9,7 +9,7 @@ module RuboCop # problems, even when a developer eager loaded all necessary associations. # # See https://gitlab.com/gitlab-org/gitlab/-/issues/23182 for more information. - class AvoidBecomes < RuboCop::Cop::Cop + class AvoidBecomes < RuboCop::Cop::Base MSG = 'Avoid the use of becomes(SomeConstant), as this creates a ' \ 'new object and throws away any eager loaded associations. ' \ 'When creating URLs in views, just use the path helpers directly. ' \ @@ -23,7 +23,7 @@ module RuboCop PATTERN def on_send(node) - add_offense(node, location: :expression) if becomes?(node) + add_offense(node) if becomes?(node) end end end diff --git a/rubocop/cop/avoid_break_from_strong_memoize.rb b/rubocop/cop/avoid_break_from_strong_memoize.rb index a3a8d0c3990..1a657a99966 100644 --- a/rubocop/cop/avoid_break_from_strong_memoize.rb +++ b/rubocop/cop/avoid_break_from_strong_memoize.rb @@ -20,7 +20,7 @@ module RuboCop # do_an_heavy_calculation # end # - class AvoidBreakFromStrongMemoize < RuboCop::Cop::Cop + class AvoidBreakFromStrongMemoize < RuboCop::Cop::Base MSG = 'Do not use break inside strong_memoize, use next instead.' def on_block(node) diff --git a/rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers.rb b/rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers.rb index da3cac073ad..ea7cdd5bf9d 100644 --- a/rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers.rb +++ b/rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers.rb @@ -3,7 +3,7 @@ module RuboCop module Cop # Cop that blacklists keyword arguments usage in Sidekiq workers - class AvoidKeywordArgumentsInSidekiqWorkers < RuboCop::Cop::Cop + class AvoidKeywordArgumentsInSidekiqWorkers < RuboCop::Cop::Base MSG = "Do not use keyword arguments in Sidekiq workers. " \ "For details, check https://github.com/mperham/sidekiq/issues/2372" OBSERVED_METHOD = :perform @@ -13,7 +13,7 @@ module RuboCop node.arguments.each do |argument| if argument.type == :kwarg || argument.type == :kwoptarg - add_offense(node, location: :expression) + add_offense(node) end end end diff --git a/rubocop/cop/avoid_return_from_blocks.rb b/rubocop/cop/avoid_return_from_blocks.rb index cc1868f10a4..61edfd0a789 100644 --- a/rubocop/cop/avoid_return_from_blocks.rb +++ b/rubocop/cop/avoid_return_from_blocks.rb @@ -20,7 +20,7 @@ module RuboCop # do_something_else # end # - class AvoidReturnFromBlocks < RuboCop::Cop::Cop + class AvoidReturnFromBlocks < RuboCop::Cop::Base MSG = 'Do not return from a block, use next or break instead.' DEF_METHODS = %i[define_method lambda].freeze WHITELISTED_METHODS = %i[each each_filename times loop].freeze diff --git a/rubocop/cop/avoid_route_redirect_leading_slash.rb b/rubocop/cop/avoid_route_redirect_leading_slash.rb index 0b0dc7d3d33..0535ae16a33 100644 --- a/rubocop/cop/avoid_route_redirect_leading_slash.rb +++ b/rubocop/cop/avoid_route_redirect_leading_slash.rb @@ -13,7 +13,9 @@ module RuboCop # root to: redirect('-/autocomplete/users') # - class AvoidRouteRedirectLeadingSlash < RuboCop::Cop::Cop + class AvoidRouteRedirectLeadingSlash < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + MSG = 'Do not use a leading "/" in route redirects' def_node_matcher :leading_slash_in_redirect?, <<~PATTERN @@ -24,7 +26,9 @@ module RuboCop return unless in_routes?(node) return unless leading_slash_in_redirect?(node) - add_offense(node) + add_offense(node) do |corrector| + corrector.replace(node.loc.expression, remove_leading_slash(node)) + end end def has_leading_slash?(str) @@ -38,12 +42,6 @@ module RuboCop dirname.end_with?('config/routes') || filename.end_with?('routes.rb') end - def autocorrect(node) - lambda do |corrector| - corrector.replace(node.loc.expression, remove_leading_slash(node)) - end - end - def remove_leading_slash(node) node.source.sub('/', '') end diff --git a/rubocop/cop/ban_catch_throw.rb b/rubocop/cop/ban_catch_throw.rb index 42301d5512f..3f215eb3140 100644 --- a/rubocop/cop/ban_catch_throw.rb +++ b/rubocop/cop/ban_catch_throw.rb @@ -19,7 +19,7 @@ module RuboCop # # ... # end # - class BanCatchThrow < RuboCop::Cop::Cop + class BanCatchThrow < RuboCop::Cop::Base MSG = "Do not use catch or throw unless a gem's API demands it." def on_send(node) @@ -27,7 +27,7 @@ module RuboCop return unless receiver.nil? && %i[catch throw].include?(method_name) - add_offense(node, location: :expression) + add_offense(node) end end end diff --git a/rubocop/cop/code_reuse/finder.rb b/rubocop/cop/code_reuse/finder.rb index 1d70befe79b..ed008f613a4 100644 --- a/rubocop/cop/code_reuse/finder.rb +++ b/rubocop/cop/code_reuse/finder.rb @@ -6,7 +6,7 @@ module RuboCop module Cop module CodeReuse # Cop that enforces various code reuse rules for Finders. - class Finder < RuboCop::Cop::Cop + class Finder < RuboCop::Cop::Base include CodeReuseHelpers IN_FINDER = 'Finders can not be used inside a Finder.' diff --git a/rubocop/cop/code_reuse/presenter.rb b/rubocop/cop/code_reuse/presenter.rb index 6eef5e5a4b0..9ceb7bde54e 100644 --- a/rubocop/cop/code_reuse/presenter.rb +++ b/rubocop/cop/code_reuse/presenter.rb @@ -6,7 +6,7 @@ module RuboCop module Cop module CodeReuse # Cop that enforces various code reuse rules for Presenter classes. - class Presenter < RuboCop::Cop::Cop + class Presenter < RuboCop::Cop::Base include CodeReuseHelpers IN_SERVICE = 'Presenters can not be used in a Service class.' diff --git a/rubocop/cop/code_reuse/serializer.rb b/rubocop/cop/code_reuse/serializer.rb index 17a84ec31f7..493432c69da 100644 --- a/rubocop/cop/code_reuse/serializer.rb +++ b/rubocop/cop/code_reuse/serializer.rb @@ -6,7 +6,7 @@ module RuboCop module Cop module CodeReuse # Cop that enforces various code reuse rules for Serializer classes. - class Serializer < RuboCop::Cop::Cop + class Serializer < RuboCop::Cop::Base include CodeReuseHelpers IN_SERVICE = 'Serializers can not be used in a Service class.' diff --git a/rubocop/cop/code_reuse/service_class.rb b/rubocop/cop/code_reuse/service_class.rb index e403a87093c..e9002f232a2 100644 --- a/rubocop/cop/code_reuse/service_class.rb +++ b/rubocop/cop/code_reuse/service_class.rb @@ -6,7 +6,7 @@ module RuboCop module Cop module CodeReuse # Cop that enforces various code reuse rules for Service classes. - class ServiceClass < RuboCop::Cop::Cop + class ServiceClass < RuboCop::Cop::Base include CodeReuseHelpers IN_FINDER = 'Service classes can not be used in a Finder.' diff --git a/rubocop/cop/code_reuse/worker.rb b/rubocop/cop/code_reuse/worker.rb index 3a1120ac2a1..f39ffbe9c6f 100644 --- a/rubocop/cop/code_reuse/worker.rb +++ b/rubocop/cop/code_reuse/worker.rb @@ -6,7 +6,7 @@ module RuboCop module Cop module CodeReuse # Cop that enforces various code reuse rules for workers. - class Worker < RuboCop::Cop::Cop + class Worker < RuboCop::Cop::Base include CodeReuseHelpers IN_CONTROLLER = 'Workers can not be used in a controller.' diff --git a/rubocop/cop/database/disable_referential_integrity.rb b/rubocop/cop/database/disable_referential_integrity.rb index 80d52678011..9e201e2d143 100644 --- a/rubocop/cop/database/disable_referential_integrity.rb +++ b/rubocop/cop/database/disable_referential_integrity.rb @@ -4,7 +4,7 @@ module RuboCop module Cop module Database # Cop that checks if 'disable_referential_integrity' method is called. - class DisableReferentialIntegrity < RuboCop::Cop::Cop + class DisableReferentialIntegrity < RuboCop::Cop::Base MSG = <<~TEXT Do not use `disable_referential_integrity`, disable triggers in a safe transaction instead. Follow the format: diff --git a/rubocop/cop/database/establish_connection.rb b/rubocop/cop/database/establish_connection.rb index 20454887ce2..3681974640b 100644 --- a/rubocop/cop/database/establish_connection.rb +++ b/rubocop/cop/database/establish_connection.rb @@ -3,7 +3,7 @@ module RuboCop module Cop module Database - class EstablishConnection < RuboCop::Cop::Cop + class EstablishConnection < RuboCop::Cop::Base MSG = "Don't establish new database connections, as this slows down " \ 'tests and may result in new connections using an incorrect configuration' @@ -12,7 +12,7 @@ module RuboCop PATTERN def on_send(node) - add_offense(node, location: :expression) if establish_connection?(node) + add_offense(node) if establish_connection?(node) end end end diff --git a/rubocop/cop/database/multiple_databases.rb b/rubocop/cop/database/multiple_databases.rb index 1ac9bb4473b..33ff8acd4d8 100644 --- a/rubocop/cop/database/multiple_databases.rb +++ b/rubocop/cop/database/multiple_databases.rb @@ -10,7 +10,7 @@ module RuboCop # # good # ApplicationRecord.connection # - class MultipleDatabases < RuboCop::Cop::Cop + class MultipleDatabases < RuboCop::Cop::Base AR_BASE_MESSAGE = <<~EOF Do not use methods from ActiveRecord::Base, use the ApplicationRecord class instead For fixing offenses related to the ActiveRecord::Base.transaction method, see our guidelines: @@ -32,7 +32,7 @@ module RuboCop active_record_base_method = node.children[1] return if method_is_allowed?(active_record_base_method) - add_offense(node, location: :expression, message: AR_BASE_MESSAGE) + add_offense(node, message: AR_BASE_MESSAGE) end private diff --git a/rubocop/cop/database/rescue_query_canceled.rb b/rubocop/cop/database/rescue_query_canceled.rb index 1238f9ed911..01f3ba272c2 100644 --- a/rubocop/cop/database/rescue_query_canceled.rb +++ b/rubocop/cop/database/rescue_query_canceled.rb @@ -20,7 +20,7 @@ module RuboCop # # good # # run_cheap_queries_with_each_batch - class RescueQueryCanceled < RuboCop::Cop::Cop + class RescueQueryCanceled < RuboCop::Cop::Base MSG = <<~EOF Avoid rescuing the `ActiveRecord::QueryCanceled` class. diff --git a/rubocop/cop/database/rescue_statement_timeout.rb b/rubocop/cop/database/rescue_statement_timeout.rb index 0b75a441e29..a0e9396e8f4 100644 --- a/rubocop/cop/database/rescue_statement_timeout.rb +++ b/rubocop/cop/database/rescue_statement_timeout.rb @@ -20,7 +20,7 @@ module RuboCop # # good # # run_cheap_queries_with_each_batch - class RescueStatementTimeout < RuboCop::Cop::Cop + class RescueStatementTimeout < RuboCop::Cop::Base MSG = <<~EOF Avoid rescuing the `ActiveRecord::StatementTimeout` class. diff --git a/rubocop/cop/default_scope.rb b/rubocop/cop/default_scope.rb index 39f8c8e9ed0..930a69be881 100644 --- a/rubocop/cop/default_scope.rb +++ b/rubocop/cop/default_scope.rb @@ -3,7 +3,7 @@ module RuboCop module Cop # Cop that blacklists the use of `default_scope`. - class DefaultScope < RuboCop::Cop::Cop + class DefaultScope < RuboCop::Cop::Base MSG = <<~EOF Do not use `default_scope`, as it does not follow the principle of least surprise. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33847 @@ -17,7 +17,7 @@ module RuboCop def on_send(node) return unless default_scope?(node) - add_offense(node, location: :expression) + add_offense(node) end end end diff --git a/rubocop/cop/destroy_all.rb b/rubocop/cop/destroy_all.rb index 38b6cb40f91..78e5d0f25f3 100644 --- a/rubocop/cop/destroy_all.rb +++ b/rubocop/cop/destroy_all.rb @@ -3,7 +3,7 @@ module RuboCop module Cop # Cop that blacklists the use of `destroy_all`. - class DestroyAll < RuboCop::Cop::Cop + class DestroyAll < RuboCop::Cop::Base MSG = 'Use `delete_all` instead of `destroy_all`. ' \ '`destroy_all` will load the rows into memory, then execute a ' \ '`DELETE` for every individual row.' @@ -15,7 +15,7 @@ module RuboCop def on_send(node) return unless destroy_all?(node) - add_offense(node, location: :expression) + add_offense(node) end end end diff --git a/rubocop/cop/file_decompression.rb b/rubocop/cop/file_decompression.rb index 44813244028..e1e645e6d62 100644 --- a/rubocop/cop/file_decompression.rb +++ b/rubocop/cop/file_decompression.rb @@ -3,7 +3,7 @@ module RuboCop module Cop # Check for symlinks when extracting files to avoid arbitrary file reading. - class FileDecompression < RuboCop::Cop::Cop + class FileDecompression < RuboCop::Cop::Base MSG = <<~EOF While extracting files check for symlink to avoid arbitrary file reading. https://gitlab.com/gitlab-com/gl-infra/production/-/issues/6132 @@ -29,7 +29,7 @@ module RuboCop def on_send(node) system?(node) do |match| - add_offense(node, location: :expression, message: MSG) if forbidden_command?(match) + add_offense(node, message: MSG) if forbidden_command?(match) end end diff --git a/rubocop/cop/filename_length.rb b/rubocop/cop/filename_length.rb index 815db7de3f5..948f69cc88c 100644 --- a/rubocop/cop/filename_length.rb +++ b/rubocop/cop/filename_length.rb @@ -2,7 +2,7 @@ module RuboCop module Cop - class FilenameLength < Cop + class FilenameLength < RuboCop::Cop::Base include RangeHelp FILEPATH_MAX_BYTES = 256 @@ -10,14 +10,14 @@ module RuboCop MSG_FILEPATH_LEN = "This file path is too long. It should be #{FILEPATH_MAX_BYTES} or less" MSG_FILENAME_LEN = "This file name is too long. It should be #{FILENAME_MAX_BYTES} or less" - def investigate(processed_source) + def on_new_investigation file_path = processed_source.file_path return if config.file_to_exclude?(file_path) if file_path.bytesize > FILEPATH_MAX_BYTES - add_offense(nil, location: source_range(processed_source.buffer, 1, 0, 1), message: MSG_FILEPATH_LEN) + add_offense(source_range(processed_source.buffer, 1, 0), message: MSG_FILEPATH_LEN) elsif File.basename(file_path).bytesize > FILENAME_MAX_BYTES - add_offense(nil, location: source_range(processed_source.buffer, 1, 0, 1), message: MSG_FILENAME_LEN) + add_offense(source_range(processed_source.buffer, 1, 0), message: MSG_FILENAME_LEN) end end end diff --git a/rubocop/cop/gitlab/avoid_feature_category_not_owned.rb b/rubocop/cop/gitlab/avoid_feature_category_not_owned.rb index fb790f44a96..05d7824f92e 100644 --- a/rubocop/cop/gitlab/avoid_feature_category_not_owned.rb +++ b/rubocop/cop/gitlab/avoid_feature_category_not_owned.rb @@ -5,7 +5,7 @@ require_relative '../../code_reuse_helpers' module RuboCop module Cop module Gitlab - class AvoidFeatureCategoryNotOwned < RuboCop::Cop::Cop + class AvoidFeatureCategoryNotOwned < RuboCop::Cop::Base include ::RuboCop::CodeReuseHelpers MSG = 'Avoid adding new endpoints with `feature_category :not_owned`. See https://docs.gitlab.com/ee/development/feature_categorization' @@ -25,7 +25,7 @@ module RuboCop return unless file_needs_feature_category?(node) return unless setting_not_owned?(node) - add_offense(node, location: :expression) + add_offense(node) end private diff --git a/rubocop/cop/gitlab/avoid_feature_get.rb b/rubocop/cop/gitlab/avoid_feature_get.rb index 7664f66521a..68aaff8aeff 100644 --- a/rubocop/cop/gitlab/avoid_feature_get.rb +++ b/rubocop/cop/gitlab/avoid_feature_get.rb @@ -20,7 +20,7 @@ module RuboCop # Feature.enable_percentage_of_time(:x, 100) # Feature.remove(:x) # - class AvoidFeatureGet < RuboCop::Cop::Cop + class AvoidFeatureGet < RuboCop::Cop::Base MSG = 'Use `stub_feature_flags` method instead of `Feature.get`. ' \ 'See doc/development/feature_flags/index.md#feature-flags-in-tests for more information.' @@ -31,7 +31,7 @@ module RuboCop def on_send(node) return unless feature_get?(node) - add_offense(node, location: :selector) + add_offense(node.loc.selector) end end end diff --git a/rubocop/cop/gitlab/avoid_uploaded_file_from_params.rb b/rubocop/cop/gitlab/avoid_uploaded_file_from_params.rb index 0795f96732d..cb3382c1b75 100644 --- a/rubocop/cop/gitlab/avoid_uploaded_file_from_params.rb +++ b/rubocop/cop/gitlab/avoid_uploaded_file_from_params.rb @@ -33,7 +33,7 @@ module RuboCop # uploaded_file = declared_params[:file] # end # end - class AvoidUploadedFileFromParams < RuboCop::Cop::Cop + class AvoidUploadedFileFromParams < RuboCop::Cop::Base MSG = 'Use the `UploadedFile` set by `multipart.rb` instead of calling `UploadedFile.from_params` directly. See https://docs.gitlab.com/ee/development/uploads/working_with_uploads.html' def_node_matcher :calling_uploaded_file_from_params?, <<~PATTERN @@ -43,7 +43,7 @@ module RuboCop def on_send(node) return unless calling_uploaded_file_from_params?(node) - add_offense(node, location: :expression) + add_offense(node) end end end diff --git a/rubocop/cop/gitlab/bulk_insert.rb b/rubocop/cop/gitlab/bulk_insert.rb index baaefc2533c..f88dcde2dc2 100644 --- a/rubocop/cop/gitlab/bulk_insert.rb +++ b/rubocop/cop/gitlab/bulk_insert.rb @@ -5,7 +5,7 @@ module RuboCop module Gitlab # Cop that disallows the use of `legacy_bulk_insert`, in favour of using # the `BulkInsertSafe` module. - class BulkInsert < RuboCop::Cop::Cop + class BulkInsert < RuboCop::Cop::Base MSG = 'Use the `BulkInsertSafe` concern, instead of using `LegacyBulkInsert.bulk_insert`. See https://docs.gitlab.com/ee/development/insert_into_tables_in_batches.html' def_node_matcher :raw_union?, <<~PATTERN @@ -15,7 +15,7 @@ module RuboCop def on_send(node) return unless raw_union?(node) - add_offense(node, location: :expression) + add_offense(node) end end end diff --git a/rubocop/cop/gitlab/change_timezone.rb b/rubocop/cop/gitlab/change_timezone.rb index c30a057d51c..a5d9393b6c3 100644 --- a/rubocop/cop/gitlab/change_timezone.rb +++ b/rubocop/cop/gitlab/change_timezone.rb @@ -3,7 +3,7 @@ module RuboCop module Cop module Gitlab - class ChangeTimezone < RuboCop::Cop::Cop + class ChangeTimezone < RuboCop::Cop::Base MSG = "Do not change timezone in the runtime (application or rspec), " \ "it could result in silently modifying other behavior." diff --git a/rubocop/cop/gitlab/const_get_inherit_false.rb b/rubocop/cop/gitlab/const_get_inherit_false.rb index 3d3bbc4c8d3..e44097a8d9e 100644 --- a/rubocop/cop/gitlab/const_get_inherit_false.rb +++ b/rubocop/cop/gitlab/const_get_inherit_false.rb @@ -6,7 +6,9 @@ module RuboCop # Cop that encourages usage of inherit=false for 2nd argument when using const_get. # # See https://gitlab.com/gitlab-org/gitlab/issues/27678 - class ConstGetInheritFalse < RuboCop::Cop::Cop + class ConstGetInheritFalse < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + MSG = 'Use inherit=false when using const_get.' def_node_matcher :const_get?, <<~PATTERN @@ -17,11 +19,7 @@ module RuboCop return unless const_get?(node) return if second_argument(node)&.false_type? - add_offense(node, location: :selector) - end - - def autocorrect(node) - lambda do |corrector| + add_offense(node.loc.selector) do |corrector| if arg = second_argument(node) corrector.replace(arg.source_range, 'false') else diff --git a/rubocop/cop/gitlab/delegate_predicate_methods.rb b/rubocop/cop/gitlab/delegate_predicate_methods.rb index 43b5184faab..9e6a2823719 100644 --- a/rubocop/cop/gitlab/delegate_predicate_methods.rb +++ b/rubocop/cop/gitlab/delegate_predicate_methods.rb @@ -21,7 +21,7 @@ module RuboCop # def is_foo? # !!bar&.is_foo? # end - class DelegatePredicateMethods < RuboCop::Cop::Cop + class DelegatePredicateMethods < RuboCop::Cop::Base MSG = "Using `delegate` with `allow_nil` on the following predicate methods is discouraged: %s." RESTRICT_ON_SEND = %i[delegate].freeze def_node_matcher :predicate_allow_nil_option, <<~PATTERN diff --git a/rubocop/cop/gitlab/deprecate_track_redis_hll_event.rb b/rubocop/cop/gitlab/deprecate_track_redis_hll_event.rb index 3e30f3aa4d0..58411357eeb 100644 --- a/rubocop/cop/gitlab/deprecate_track_redis_hll_event.rb +++ b/rubocop/cop/gitlab/deprecate_track_redis_hll_event.rb @@ -14,7 +14,7 @@ module RuboCop # # # good # track_event :show, name: 'g_analytics_valuestream', destinations: [:redis_hll] - class DeprecateTrackRedisHLLEvent < RuboCop::Cop::Cop + class DeprecateTrackRedisHLLEvent < RuboCop::Cop::Base MSG = '`track_redis_hll_event` is deprecated. Use `track_event` helper instead. ' \ 'See https://docs.gitlab.com/ee/development/service_ping/implement.html#add-new-events' @@ -25,7 +25,7 @@ module RuboCop def on_send(node) return unless track_redis_hll_event_used?(node) - add_offense(node, location: :selector) + add_offense(node.loc.selector) end end end diff --git a/rubocop/cop/gitlab/event_store_subscriber.rb b/rubocop/cop/gitlab/event_store_subscriber.rb index 0b2dd94bc42..7e4cc3e66cc 100644 --- a/rubocop/cop/gitlab/event_store_subscriber.rb +++ b/rubocop/cop/gitlab/event_store_subscriber.rb @@ -30,7 +30,7 @@ module RuboCop # end # end # - class EventStoreSubscriber < RuboCop::Cop::Cop + class EventStoreSubscriber < RuboCop::Cop::Base SUBSCRIBER_MODULE_NAME = 'Gitlab::EventStore::Subscriber' FORBID_PERFORM_OVERRIDE = "Do not override `perform` in a `#{SUBSCRIBER_MODULE_NAME}`." REQUIRE_HANDLE_EVENT = "A `#{SUBSCRIBER_MODULE_NAME}` must implement `#handle_event(event)`." diff --git a/rubocop/cop/gitlab/except.rb b/rubocop/cop/gitlab/except.rb index 24da6962457..d20cf47b473 100644 --- a/rubocop/cop/gitlab/except.rb +++ b/rubocop/cop/gitlab/except.rb @@ -5,7 +5,7 @@ module RuboCop module Gitlab # Cop that disallows the use of `Gitlab::SQL::Except`, in favour of using # the `FromExcept` module. - class Except < RuboCop::Cop::Cop + class Except < RuboCop::Cop::Base MSG = 'Use the `FromExcept` concern, instead of using `Gitlab::SQL::Except` directly' def_node_matcher :raw_except?, <<~PATTERN @@ -15,7 +15,7 @@ module RuboCop def on_send(node) return unless raw_except?(node) - add_offense(node, location: :expression) + add_offense(node) end end end diff --git a/rubocop/cop/gitlab/feature_available_usage.rb b/rubocop/cop/gitlab/feature_available_usage.rb index f748b7d9111..3e0385c4018 100644 --- a/rubocop/cop/gitlab/feature_available_usage.rb +++ b/rubocop/cop/gitlab/feature_available_usage.rb @@ -4,7 +4,7 @@ module RuboCop module Cop module Gitlab # Cop that checks for correct calling of #feature_available? - class FeatureAvailableUsage < RuboCop::Cop::Cop + class FeatureAvailableUsage < RuboCop::Cop::Base OBSERVED_METHOD = :feature_available? LICENSED_FEATURE_LITERAL_ARG_MSG = '`feature_available?` should not be called for features that can be licensed (`%s` given), use `licensed_feature_available?(feature)` instead.' LICENSED_FEATURE_DYNAMIC_ARG_MSG = "`feature_available?` should not be called for features that can be licensed (`%s` isn't a literal so we cannot say if it's legit or not), using `licensed_feature_available?(feature)` may be more appropriate." @@ -38,9 +38,9 @@ module RuboCop return if ALL_FEATURES.include?(feature_name(node)) && args_count(node) == 2 if !ALL_FEATURES.include?(feature_name(node)) - add_offense(node, location: :expression, message: licensed_feature_message(node)) + add_offense(node, message: licensed_feature_message(node)) elsif args_count(node) < 2 - add_offense(node, location: :expression, message: NOT_ENOUGH_ARGS_MSG) + add_offense(node, message: NOT_ENOUGH_ARGS_MSG) end end diff --git a/rubocop/cop/gitlab/finder_with_find_by.rb b/rubocop/cop/gitlab/finder_with_find_by.rb index 8fa9fe4a2f9..ac454398f9c 100644 --- a/rubocop/cop/gitlab/finder_with_find_by.rb +++ b/rubocop/cop/gitlab/finder_with_find_by.rb @@ -3,8 +3,10 @@ module RuboCop module Cop module Gitlab - class FinderWithFindBy < RuboCop::Cop::Cop - FIND_PATTERN = /\Afind(_by\!?)?\z/.freeze + class FinderWithFindBy < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + + FIND_PATTERN = /\Afind(_by!?)?\z/.freeze ALLOWED_MODULES = ['FinderMethods'].freeze def message(used_method) @@ -18,13 +20,9 @@ module RuboCop end def on_send(node) - if find_on_execute?(node) && !allowed_module?(node) - add_offense(node, location: :selector, message: message(node.method_name)) - end - end + return unless find_on_execute?(node) && !allowed_module?(node) - def autocorrect(node) - lambda do |corrector| + add_offense(node.loc.selector, message: message(node.method_name)) do |corrector| upto_including_execute = node.descendants.first.source_range before_execute = node.descendants[1].source_range range_to_remove = node.source_range diff --git a/rubocop/cop/gitlab/httparty.rb b/rubocop/cop/gitlab/httparty.rb index 20f0c381e11..f57c605ce91 100644 --- a/rubocop/cop/gitlab/httparty.rb +++ b/rubocop/cop/gitlab/httparty.rb @@ -3,7 +3,9 @@ module RuboCop module Cop module Gitlab - class HTTParty < RuboCop::Cop::Cop + class HTTParty < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + MSG_SEND = <<~EOL Avoid calling `HTTParty` directly. Instead, use the Gitlab::HTTP wrapper. To allow request to localhost or the private network set @@ -25,31 +27,18 @@ module RuboCop PATTERN def on_send(node) - add_offense(node, location: :expression, message: MSG_SEND) if httparty_node?(node) - add_offense(node, location: :expression, message: MSG_INCLUDE) if includes_httparty?(node) - end - - def autocorrect(node) - if includes_httparty?(node) - autocorrect_includes_httparty(node) - else - autocorrect_httparty_node(node) - end - end - - def autocorrect_includes_httparty(node) - lambda do |corrector| - corrector.remove(node.source_range) - end - end - - def autocorrect_httparty_node(node) - _, method_name, *arg_nodes = *node - - replacement = "Gitlab::HTTP.#{method_name}(#{arg_nodes.map(&:source).join(', ')})" - - lambda do |corrector| - corrector.replace(node.source_range, replacement) + if httparty_node?(node) + add_offense(node, message: MSG_SEND) do |corrector| + _, method_name, *arg_nodes = *node + + replacement = "Gitlab::HTTP.#{method_name}(#{arg_nodes.map(&:source).join(', ')})" + + corrector.replace(node.source_range, replacement) + end + elsif includes_httparty?(node) + add_offense(node, message: MSG_INCLUDE) do |corrector| + corrector.remove(node.source_range) + end end end end diff --git a/rubocop/cop/gitlab/intersect.rb b/rubocop/cop/gitlab/intersect.rb index 4b61073b804..e608b25cbe1 100644 --- a/rubocop/cop/gitlab/intersect.rb +++ b/rubocop/cop/gitlab/intersect.rb @@ -5,7 +5,7 @@ module RuboCop module Gitlab # Cop that disallows the use of `Gitlab::SQL::Intersect`, in favour of using # the `FromIntersect` module. - class Intersect < RuboCop::Cop::Cop + class Intersect < RuboCop::Cop::Base MSG = 'Use the `FromIntersect` concern, instead of using `Gitlab::SQL::Intersect` directly' def_node_matcher :raw_intersect?, <<~PATTERN @@ -15,7 +15,7 @@ module RuboCop def on_send(node) return unless raw_intersect?(node) - add_offense(node, location: :expression) + add_offense(node) end end end diff --git a/rubocop/cop/gitlab/json.rb b/rubocop/cop/gitlab/json.rb index d2ba0012ca0..56846e3c276 100644 --- a/rubocop/cop/gitlab/json.rb +++ b/rubocop/cop/gitlab/json.rb @@ -3,7 +3,9 @@ module RuboCop module Cop module Gitlab - class Json < RuboCop::Cop::Cop + class Json < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + MSG = <<~EOL Avoid calling `JSON` directly. Instead, use the `Gitlab::Json` wrapper. This allows us to alter the JSON parser being used. @@ -14,19 +16,13 @@ module RuboCop PATTERN def on_send(node) - add_offense(node) if json_node?(node) - end - - def autocorrect(node) - autocorrect_json_node(node) - end + return unless json_node?(node) - def autocorrect_json_node(node) - _, method_name, *arg_nodes = *node + add_offense(node) do |corrector| + _, method_name, *arg_nodes = *node - replacement = "Gitlab::Json.#{method_name}(#{arg_nodes.map(&:source).join(', ')})" + replacement = "Gitlab::Json.#{method_name}(#{arg_nodes.map(&:source).join(', ')})" - lambda do |corrector| corrector.replace(node.source_range, replacement) end end diff --git a/rubocop/cop/gitlab/mark_used_feature_flags.rb b/rubocop/cop/gitlab/mark_used_feature_flags.rb index 8fbcc56b906..8d8c84e78f5 100644 --- a/rubocop/cop/gitlab/mark_used_feature_flags.rb +++ b/rubocop/cop/gitlab/mark_used_feature_flags.rb @@ -9,7 +9,7 @@ module RuboCop # # The files set in `tmp/feature_flags/*.used` can then be used for verification purpose. # - class MarkUsedFeatureFlags < RuboCop::Cop::Cop + class MarkUsedFeatureFlags < RuboCop::Cop::Base include RuboCop::CodeReuseHelpers FEATURE_METHODS = %i[enabled? disabled?].freeze diff --git a/rubocop/cop/gitlab/module_with_instance_variables.rb b/rubocop/cop/gitlab/module_with_instance_variables.rb index 40cdc0d3a57..e43ede61b7e 100644 --- a/rubocop/cop/gitlab/module_with_instance_variables.rb +++ b/rubocop/cop/gitlab/module_with_instance_variables.rb @@ -3,7 +3,7 @@ module RuboCop module Cop module Gitlab - class ModuleWithInstanceVariables < RuboCop::Cop::Cop + class ModuleWithInstanceVariables < RuboCop::Cop::Base MSG = <<~EOL Do not use instance variables in a module. Please read this for the rationale behind it: @@ -32,12 +32,12 @@ module RuboCop if only_ivar_or_assignment?(definition) # We don't allow if any other ivar is used definition.each_descendant(:ivar) do |offense| - add_offense(offense, location: :expression) + add_offense(offense) end # We allow initialize method and single ivar elsif !initialize_method?(definition) && !single_ivar?(definition) definition.each_descendant(:ivar, :ivasgn) do |offense| - add_offense(offense, location: :expression) + add_offense(offense) end end end diff --git a/rubocop/cop/gitlab/policy_rule_boolean.rb b/rubocop/cop/gitlab/policy_rule_boolean.rb index ca69eebab6e..ddf100fc8a1 100644 --- a/rubocop/cop/gitlab/policy_rule_boolean.rb +++ b/rubocop/cop/gitlab/policy_rule_boolean.rb @@ -22,7 +22,7 @@ module RuboCop # # good # rule { conducts_electricity & can?(:magnetize) }.enable :motor # rule { ~conducts_electricity & batteries }.enable :motor - class PolicyRuleBoolean < RuboCop::Cop::Cop + class PolicyRuleBoolean < RuboCop::Cop::Base def_node_search :has_and_operator?, <<~PATTERN (and ...) PATTERN diff --git a/rubocop/cop/gitlab/predicate_memoization.rb b/rubocop/cop/gitlab/predicate_memoization.rb index 4c851f90238..3fbd004655f 100644 --- a/rubocop/cop/gitlab/predicate_memoization.rb +++ b/rubocop/cop/gitlab/predicate_memoization.rb @@ -3,7 +3,7 @@ module RuboCop module Cop module Gitlab - class PredicateMemoization < RuboCop::Cop::Cop + class PredicateMemoization < RuboCop::Cop::Base MSG = <<~EOL Avoid using `@value ||= query` inside predicate methods in order to properly memoize `false` or `nil` values. diff --git a/rubocop/cop/gitlab/rails_logger.rb b/rubocop/cop/gitlab/rails_logger.rb index 5a1695ce56e..ae05491ca7d 100644 --- a/rubocop/cop/gitlab/rails_logger.rb +++ b/rubocop/cop/gitlab/rails_logger.rb @@ -38,7 +38,7 @@ module RuboCop def on_send(node) return unless rails_logger_log?(node) - add_offense(node, location: :expression) + add_offense(node) end end end diff --git a/rubocop/cop/gitlab/union.rb b/rubocop/cop/gitlab/union.rb index c44c847657b..36ec6bb9b7f 100644 --- a/rubocop/cop/gitlab/union.rb +++ b/rubocop/cop/gitlab/union.rb @@ -5,7 +5,7 @@ module RuboCop module Gitlab # Cop that disallows the use of `Gitlab::SQL::Union`, in favour of using # the `FromUnion` module. - class Union < RuboCop::Cop::Cop + class Union < RuboCop::Cop::Base MSG = 'Use the `FromUnion` concern, instead of using `Gitlab::SQL::Union` directly' def_node_matcher :raw_union?, <<~PATTERN @@ -15,7 +15,7 @@ module RuboCop def on_send(node) return unless raw_union?(node) - add_offense(node, location: :expression) + add_offense(node) end end end diff --git a/rubocop/cop/graphql/authorize_types.rb b/rubocop/cop/graphql/authorize_types.rb index c96919343d6..7bd2cd9f7ef 100644 --- a/rubocop/cop/graphql/authorize_types.rb +++ b/rubocop/cop/graphql/authorize_types.rb @@ -3,7 +3,7 @@ module RuboCop module Cop module Graphql - class AuthorizeTypes < RuboCop::Cop::Cop + class AuthorizeTypes < RuboCop::Cop::Base MSG = 'Add an `authorize :ability` call to the type: '\ 'https://docs.gitlab.com/ee/development/graphql_guide/authorization.html#type-authorization' @@ -19,7 +19,7 @@ module RuboCop return if allowed?(class_constant(node)) return if allowed?(superclass_constant(node)) - add_offense(node, location: :expression) unless authorize?(node) + add_offense(node) unless authorize?(node) end private diff --git a/rubocop/cop/graphql/descriptions.rb b/rubocop/cop/graphql/descriptions.rb index 0d69fd55931..3c945507699 100644 --- a/rubocop/cop/graphql/descriptions.rb +++ b/rubocop/cop/graphql/descriptions.rb @@ -42,7 +42,9 @@ module RuboCop module Cop module Graphql - class Descriptions < RuboCop::Cop::Cop + class Descriptions < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + MSG_STYLE_GUIDE_LINK = 'See the description style guide: https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#description-style-guide' MSG_NO_DESCRIPTION = "Please add a `description` property. #{MSG_STYLE_GUIDE_LINK}" MSG_NO_PERIOD = "`description` strings must end with a `.`. #{MSG_STYLE_GUIDE_LINK}" @@ -74,15 +76,17 @@ module RuboCop description = locate_description(node) - return add_offense(node, location: :expression, message: MSG_NO_DESCRIPTION) unless description + message = if description.nil? + MSG_NO_DESCRIPTION + elsif no_period?(description) + MSG_NO_PERIOD + elsif bad_start?(description) + MSG_BAD_START + end - add_offense(node, location: :expression, message: MSG_NO_PERIOD) if no_period?(description) - add_offense(node, location: :expression, message: MSG_BAD_START) if bad_start?(description) - end + return unless message - # Autocorrect missing periods at end of description. - def autocorrect(node) - lambda do |corrector| + add_offense(node, message: message) do |corrector| description = locate_description(node) next unless description diff --git a/rubocop/cop/graphql/gid_expected_type.rb b/rubocop/cop/graphql/gid_expected_type.rb index 354c5516752..7e802e6d2db 100644 --- a/rubocop/cop/graphql/gid_expected_type.rb +++ b/rubocop/cop/graphql/gid_expected_type.rb @@ -3,7 +3,7 @@ module RuboCop module Cop module Graphql - class GIDExpectedType < RuboCop::Cop::Cop + class GIDExpectedType < RuboCop::Cop::Base MSG = 'Add an expected_type parameter to #object_from_id calls if possible.' def_node_search :id_from_object?, <<~PATTERN diff --git a/rubocop/cop/graphql/graphql_name_position.rb b/rubocop/cop/graphql/graphql_name_position.rb index f18d65588cc..b876fb5b088 100644 --- a/rubocop/cop/graphql/graphql_name_position.rb +++ b/rubocop/cop/graphql/graphql_name_position.rb @@ -20,7 +20,7 @@ module RuboCop module Cop module Graphql - class GraphqlNamePosition < RuboCop::Cop::Cop + class GraphqlNamePosition < RuboCop::Cop::Base MSG = '`graphql_name` should be the first line of the class: '\ 'https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#naming-conventions' @@ -32,7 +32,7 @@ module RuboCop return unless graphql_name?(node) return if node.body.single_line? - add_offense(node, location: :expression) unless graphql_name?(node.body.children.first) + add_offense(node) unless graphql_name?(node.body.children.first) end end end diff --git a/rubocop/cop/graphql/id_type.rb b/rubocop/cop/graphql/id_type.rb index ba973242efa..eb677aa4507 100644 --- a/rubocop/cop/graphql/id_type.rb +++ b/rubocop/cop/graphql/id_type.rb @@ -3,7 +3,7 @@ module RuboCop module Cop module Graphql - class IDType < RuboCop::Cop::Cop + class IDType < RuboCop::Cop::Base MSG = 'Do not use GraphQL::Types::ID, use a specific GlobalIDType instead' WHITELISTED_ARGUMENTS = %i[iid full_path project_path group_path target_project_path namespace_path].freeze diff --git a/rubocop/cop/graphql/json_type.rb b/rubocop/cop/graphql/json_type.rb index 8518a771cbd..2525dc427b8 100644 --- a/rubocop/cop/graphql/json_type.rb +++ b/rubocop/cop/graphql/json_type.rb @@ -18,7 +18,7 @@ module RuboCop module Cop module Graphql - class JSONType < RuboCop::Cop::Cop + class JSONType < RuboCop::Cop::Base MSG = 'Avoid using GraphQL::Types::JSON. See: ' \ 'https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#json' @@ -32,7 +32,7 @@ module RuboCop PATTERN def on_send(node) - add_offense(node, location: :expression) if has_json_type?(node) + add_offense(node) if has_json_type?(node) end end end diff --git a/rubocop/cop/graphql/old_types.rb b/rubocop/cop/graphql/old_types.rb index 61e8ac92dc7..9bbda4732dd 100644 --- a/rubocop/cop/graphql/old_types.rb +++ b/rubocop/cop/graphql/old_types.rb @@ -19,7 +19,7 @@ module RuboCop module Cop module Graphql - class OldTypes < RuboCop::Cop::Cop + class OldTypes < RuboCop::Cop::Base MSG_ID = 'Avoid using GraphQL::ID_TYPE. Use GraphQL::Types::ID instead' MSG_INT = 'Avoid using GraphQL::INT_TYPE. Use GraphQL::Types::Int instead' MSG_STRING = 'Avoid using GraphQL::STRING_TYPE. Use GraphQL::Types::String instead' @@ -37,7 +37,7 @@ module RuboCop old_constant = has_old_type?(node) return unless old_constant - add_offense(node, location: :expression, message: "#{self.class}::MSG_#{old_constant[0..-6]}".constantize) + add_offense(node, message: "#{self.class}::MSG_#{old_constant[0..-6]}".constantize) end end end diff --git a/rubocop/cop/graphql/resolver_type.rb b/rubocop/cop/graphql/resolver_type.rb index e9fa768fd3e..34f1d43fc2a 100644 --- a/rubocop/cop/graphql/resolver_type.rb +++ b/rubocop/cop/graphql/resolver_type.rb @@ -23,7 +23,7 @@ module RuboCop module Cop module Graphql - class ResolverType < RuboCop::Cop::Cop + class ResolverType < RuboCop::Cop::Base MSG = 'Missing type annotation: Please add `type` DSL method call. ' \ 'e.g: type UserType.connection_type, null: true' @@ -32,7 +32,7 @@ module RuboCop PATTERN def on_class(node) - add_offense(node, location: :expression) if resolver?(node) && !typed?(node) + add_offense(node) if resolver?(node) && !typed?(node) end private diff --git a/rubocop/cop/group_public_or_visible_to_user.rb b/rubocop/cop/group_public_or_visible_to_user.rb index beda0b7f8ba..d3aa230680b 100644 --- a/rubocop/cop/group_public_or_visible_to_user.rb +++ b/rubocop/cop/group_public_or_visible_to_user.rb @@ -3,7 +3,7 @@ module RuboCop module Cop # Cop that blacklists the usage of Group.public_or_visible_to_user - class GroupPublicOrVisibleToUser < RuboCop::Cop::Cop + class GroupPublicOrVisibleToUser < RuboCop::Cop::Base MSG = '`Group.public_or_visible_to_user` should be used with extreme care. ' \ 'Please ensure that you are not using it on its own and that the amount ' \ 'of rows being filtered is reasonable.' @@ -15,7 +15,7 @@ module RuboCop def on_send(node) return unless public_or_visible_to_user?(node) - add_offense(node, location: :expression) + add_offense(node) end end end diff --git a/rubocop/cop/ignored_columns.rb b/rubocop/cop/ignored_columns.rb index 4a6f1e4f2d9..542d78c59e9 100644 --- a/rubocop/cop/ignored_columns.rb +++ b/rubocop/cop/ignored_columns.rb @@ -3,7 +3,7 @@ module RuboCop module Cop # Cop that blacklists the usage of `ActiveRecord::Base.ignored_columns=` directly - class IgnoredColumns < RuboCop::Cop::Cop + class IgnoredColumns < RuboCop::Cop::Base USE_CONCERN_MSG = 'Use `IgnoredColumns` concern instead of adding to `self.ignored_columns`.' WRONG_MODEL_MSG = 'If the model exists in CE and EE, the column has to be ignored ' \ 'in the CE model. If the model only exists in EE, then it has to be added there.' @@ -22,11 +22,11 @@ module RuboCop def on_send(node) if ignored_columns?(node) - add_offense(node, location: :expression, message: USE_CONCERN_MSG) + add_offense(node, message: USE_CONCERN_MSG) end if using_ignore?(node) && used_in_wrong_model? - add_offense(node, location: :expression, message: WRONG_MODEL_MSG) + add_offense(node, message: WRONG_MODEL_MSG) end end diff --git a/rubocop/cop/include_sidekiq_worker.rb b/rubocop/cop/include_sidekiq_worker.rb index e39b8bf92c2..1a42de64aa9 100644 --- a/rubocop/cop/include_sidekiq_worker.rb +++ b/rubocop/cop/include_sidekiq_worker.rb @@ -3,7 +3,9 @@ module RuboCop module Cop # Cop that makes sure workers include `ApplicationWorker`, not `Sidekiq::Worker`. - class IncludeSidekiqWorker < RuboCop::Cop::Cop + class IncludeSidekiqWorker < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + MSG = 'Include `ApplicationWorker`, not `Sidekiq::Worker`.' def_node_matcher :includes_sidekiq_worker?, <<~PATTERN @@ -13,12 +15,8 @@ module RuboCop def on_send(node) return unless includes_sidekiq_worker?(node) - add_offense(node.arguments.first, location: :expression) - end - - def autocorrect(node) - lambda do |corrector| - corrector.replace(node.source_range, 'ApplicationWorker') + add_offense(node.arguments.first) do |corrector| + corrector.replace(node.arguments.first, 'ApplicationWorker') end end end diff --git a/rubocop/cop/inject_enterprise_edition_module.rb b/rubocop/cop/inject_enterprise_edition_module.rb index 785f1494354..7e3c44cc5fd 100644 --- a/rubocop/cop/inject_enterprise_edition_module.rb +++ b/rubocop/cop/inject_enterprise_edition_module.rb @@ -4,7 +4,9 @@ module RuboCop module Cop # Cop that blacklists the injecting of extension specific modules before any lines which are not already injecting another module. # It allows multiple module injections as long as they're all at the end. - class InjectEnterpriseEditionModule < RuboCop::Cop::Cop + class InjectEnterpriseEditionModule < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + INVALID_LINE = 'Injecting extension modules must be done on the last line of this file' \ ', outside of any class or module definitions' @@ -34,7 +36,7 @@ module RuboCop return unless check_method?(node) if DISALLOW_METHODS.include?(node.children[1]) - add_offense(node, message: DISALLOWED_METHOD) + add_offense(node, message: DISALLOWED_METHOD, &corrector(node)) else verify_line_number(node) verify_argument_type(node) @@ -52,7 +54,7 @@ module RuboCop if allowed_line ignore_node(node) elsif line < last_line - add_offense(node, message: INVALID_LINE) + add_offense(node, message: INVALID_LINE, &corrector(node)) end end @@ -61,7 +63,7 @@ module RuboCop return if argument.str_type? - add_offense(argument, message: INVALID_ARGUMENT) + add_offense(argument, message: INVALID_ARGUMENT, &corrector(argument)) end def check_method?(node) @@ -74,10 +76,12 @@ module RuboCop end end + private + # Automatically correcting these offenses is not always possible, as # sometimes code needs to be refactored to make this work. As such, we # only allow developers to easily blacklist existing offenses. - def autocorrect(node) + def corrector(node) lambda do |corrector| corrector.insert_after( node.source_range, diff --git a/rubocop/cop/lint/last_keyword_argument.rb b/rubocop/cop/lint/last_keyword_argument.rb index 80f4660eeb8..3f5ad7e20d7 100644 --- a/rubocop/cop/lint/last_keyword_argument.rb +++ b/rubocop/cop/lint/last_keyword_argument.rb @@ -9,7 +9,9 @@ module RuboCop # 1. Running specs with RECORD_DEPRECATIONS=1 # 1. Downloading the complete set of deprecations/ files from a CI # pipeline (see https://gitlab.com/gitlab-org/gitlab/-/merge_requests/47720) - class LastKeywordArgument < Cop + class LastKeywordArgument < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + MSG = 'Using the last argument as keyword parameters is deprecated' DEPRECATIONS_GLOB = File.expand_path('../../../deprecations/**/*.yml', __dir__) @@ -26,11 +28,7 @@ module RuboCop # parser thinks `a: :b, c: :d` is hash type, it's actually kwargs return if arg.hash_type? && !arg.source.match(/\A{/) - add_offense(arg) - end - - def autocorrect(arg) - lambda do |corrector| + add_offense(arg) do |corrector| if arg.hash_type? kwarg = arg.source.sub(/\A{\s*/, '').sub(/\s*}\z/, '') corrector.replace(arg, kwarg) diff --git a/rubocop/cop/migration/add_column_with_default.rb b/rubocop/cop/migration/add_column_with_default.rb index afd7d93cd47..36603e09263 100644 --- a/rubocop/cop/migration/add_column_with_default.rb +++ b/rubocop/cop/migration/add_column_with_default.rb @@ -5,7 +5,7 @@ require_relative '../../migration_helpers' module RuboCop module Cop module Migration - class AddColumnWithDefault < RuboCop::Cop::Cop + class AddColumnWithDefault < RuboCop::Cop::Base include MigrationHelpers MSG = '`add_column_with_default` is deprecated, use `add_column` instead' @@ -15,7 +15,7 @@ module RuboCop name = node.children[1] - add_offense(node, location: :selector) if name == :add_column_with_default + add_offense(node.loc.selector) if name == :add_column_with_default end end end diff --git a/rubocop/cop/migration/add_columns_to_wide_tables.rb b/rubocop/cop/migration/add_columns_to_wide_tables.rb index 41056379515..98dd605faef 100644 --- a/rubocop/cop/migration/add_columns_to_wide_tables.rb +++ b/rubocop/cop/migration/add_columns_to_wide_tables.rb @@ -6,7 +6,7 @@ module RuboCop module Cop module Migration # Cop that prevents adding columns to wide tables. - class AddColumnsToWideTables < RuboCop::Cop::Cop + class AddColumnsToWideTables < RuboCop::Cop::Base include MigrationHelpers MSG = '`%s` is a wide table with several columns, adding more should be avoided unless absolutely necessary.' \ @@ -26,7 +26,7 @@ module RuboCop return unless offense?(method_name, table_name) - add_offense(node, location: :selector, message: format(MSG, table_name.value)) + add_offense(node.loc.selector, message: format(MSG, table_name.value)) end private diff --git a/rubocop/cop/migration/add_concurrent_foreign_key.rb b/rubocop/cop/migration/add_concurrent_foreign_key.rb index ebab6aa653e..f538207d336 100644 --- a/rubocop/cop/migration/add_concurrent_foreign_key.rb +++ b/rubocop/cop/migration/add_concurrent_foreign_key.rb @@ -7,7 +7,7 @@ module RuboCop module Migration # Cop that checks if `add_concurrent_foreign_key` is used instead of # `add_foreign_key`. - class AddConcurrentForeignKey < RuboCop::Cop::Cop + class AddConcurrentForeignKey < RuboCop::Cop::Base include MigrationHelpers MSG = '`add_foreign_key` requires downtime, use `add_concurrent_foreign_key` instead' @@ -29,7 +29,7 @@ module RuboCop return if in_with_lock_retries?(node) return if not_valid_fk?(node) - add_offense(node, location: :selector) + add_offense(node.loc.selector) end def method_name(node) diff --git a/rubocop/cop/migration/add_concurrent_index.rb b/rubocop/cop/migration/add_concurrent_index.rb index bfe7c15bfdf..77b8ced4778 100644 --- a/rubocop/cop/migration/add_concurrent_index.rb +++ b/rubocop/cop/migration/add_concurrent_index.rb @@ -7,7 +7,7 @@ module RuboCop module Migration # Cop that checks if `add_concurrent_index` is used with `up`/`down` methods # and not `change`. - class AddConcurrentIndex < RuboCop::Cop::Cop + class AddConcurrentIndex < RuboCop::Cop::Base include MigrationHelpers MSG = '`add_concurrent_index` is not reversible so you must manually define ' \ @@ -21,15 +21,11 @@ module RuboCop return unless name == :add_concurrent_index node.each_ancestor(:def) do |def_node| - next unless method_name(def_node) == :change + next unless def_node.method_name == :change - add_offense(def_node, location: :name) + add_offense(def_node.loc.name) end end - - def method_name(node) - node.children.first - end end end end diff --git a/rubocop/cop/migration/add_index.rb b/rubocop/cop/migration/add_index.rb index 327e89fb040..3920fd19c98 100644 --- a/rubocop/cop/migration/add_index.rb +++ b/rubocop/cop/migration/add_index.rb @@ -6,7 +6,7 @@ module RuboCop module Cop module Migration # Cop that checks if indexes are added in a concurrent manner. - class AddIndex < RuboCop::Cop::Cop + class AddIndex < RuboCop::Cop::Base include MigrationHelpers MSG = '`add_index` requires downtime, use `add_concurrent_index` instead' @@ -29,7 +29,7 @@ module RuboCop # data in these tables yet. next if new_tables.include?(first_arg) - add_offense(send_node, location: :selector) + add_offense(send_node.loc.selector) end end diff --git a/rubocop/cop/migration/add_limit_to_text_columns.rb b/rubocop/cop/migration/add_limit_to_text_columns.rb index a47fbe0bf16..5c71fbbfaa2 100644 --- a/rubocop/cop/migration/add_limit_to_text_columns.rb +++ b/rubocop/cop/migration/add_limit_to_text_columns.rb @@ -10,7 +10,7 @@ module RuboCop # Text columns starting with `encrypted_` are very likely used # by `attr_encrypted` which controls the text length. Those columns # should not add a text limit. - class AddLimitToTextColumns < RuboCop::Cop::Cop + class AddLimitToTextColumns < RuboCop::Cop::Base include MigrationHelpers TEXT_LIMIT_ATTRIBUTE_ALLOWED_SINCE = 2021_09_10_00_00_00 @@ -43,11 +43,11 @@ module RuboCop next unless text_operation?(send_node) if text_operation_with_limit?(send_node) - add_offense(send_node, location: :selector, message: TEXT_LIMIT_ATTRIBUTE_NOT_ALLOWED) if version(node) < TEXT_LIMIT_ATTRIBUTE_ALLOWED_SINCE + add_offense(send_node.loc.selector, message: TEXT_LIMIT_ATTRIBUTE_NOT_ALLOWED) if version(node) < TEXT_LIMIT_ATTRIBUTE_ALLOWED_SINCE else # We require a limit for the same table and attribute name if text_limit_missing?(node, *table_and_attribute_name(send_node)) - add_offense(send_node, location: :selector) + add_offense(send_node.loc.selector) end end end diff --git a/rubocop/cop/migration/add_reference.rb b/rubocop/cop/migration/add_reference.rb index 33840fc7caf..02a0ef899b4 100644 --- a/rubocop/cop/migration/add_reference.rb +++ b/rubocop/cop/migration/add_reference.rb @@ -6,7 +6,7 @@ module RuboCop module Migration # add_reference can only be used with newly created tables. # Additionally, the cop here checks that we create an index for the foreign key, too. - class AddReference < RuboCop::Cop::Cop + class AddReference < RuboCop::Cop::Base include MigrationHelpers MSG = '`add_reference` requires downtime for existing tables, use `add_concurrent_foreign_key` instead. When used for new tables, `index: true` or `index: { options... } is required.`' @@ -28,12 +28,12 @@ module RuboCop # Using "add_reference" is fine for newly created tables as there's no # data in these tables yet. if existing_table?(new_tables, first_arg) - add_offense(send_node, location: :selector) + add_offense(send_node.loc.selector) end # We require an index on the foreign key column. if index_missing?(node) - add_offense(send_node, location: :selector) + add_offense(send_node.loc.selector) end end end diff --git a/rubocop/cop/migration/add_timestamps.rb b/rubocop/cop/migration/add_timestamps.rb index 01d3f01ef4f..8b09d730cbc 100644 --- a/rubocop/cop/migration/add_timestamps.rb +++ b/rubocop/cop/migration/add_timestamps.rb @@ -6,7 +6,7 @@ module RuboCop module Cop module Migration # Cop that checks if 'add_timestamps' method is called with timezone information. - class AddTimestamps < RuboCop::Cop::Cop + class AddTimestamps < RuboCop::Cop::Base include MigrationHelpers MSG = 'Do not use `add_timestamps`, use `add_timestamps_with_timezone` instead' @@ -15,7 +15,7 @@ module RuboCop def on_send(node) return unless in_migration?(node) - add_offense(node, location: :selector) if method_name(node) == :add_timestamps + add_offense(node.loc.selector) if method_name(node) == :add_timestamps end def method_name(node) diff --git a/rubocop/cop/migration/background_migration_base_class.rb b/rubocop/cop/migration/background_migration_base_class.rb index 50cbe3a69c3..9ec8403a607 100644 --- a/rubocop/cop/migration/background_migration_base_class.rb +++ b/rubocop/cop/migration/background_migration_base_class.rb @@ -3,7 +3,7 @@ module RuboCop module Cop module Migration - class BackgroundMigrationBaseClass < RuboCop::Cop::Cop + class BackgroundMigrationBaseClass < RuboCop::Cop::Base MSG = 'Batched background migration jobs should inherit from Gitlab::BackgroundMigration::BatchedMigrationJob' def_node_search :top_level_module?, <<~PATTERN @@ -25,7 +25,7 @@ module RuboCop return if top_level_class_node.nil? || inherits_batched_migration_job?(top_level_class_node) - add_offense(top_level_class_node, location: :expression) + add_offense(top_level_class_node) end end end diff --git a/rubocop/cop/migration/background_migration_record.rb b/rubocop/cop/migration/background_migration_record.rb index 2ee6b9f7b42..ee6f3fd140b 100644 --- a/rubocop/cop/migration/background_migration_record.rb +++ b/rubocop/cop/migration/background_migration_record.rb @@ -5,7 +5,7 @@ require_relative '../../migration_helpers' module RuboCop module Cop module Migration - class BackgroundMigrationRecord < RuboCop::Cop::Cop + class BackgroundMigrationRecord < RuboCop::Cop::Base include MigrationHelpers MSG = <<~MSG @@ -26,14 +26,14 @@ module RuboCop return unless in_background_migration?(node) return unless inherits_from_active_record_base?(node) - add_offense(node, location: :expression) + add_offense(node) end def on_send(node) return unless in_background_migration?(node) return unless class_new_active_record_base?(node) - add_offense(node, location: :expression) + add_offense(node) end end end diff --git a/rubocop/cop/migration/background_migrations.rb b/rubocop/cop/migration/background_migrations.rb index 39c5496e4d3..7dcc2101fb1 100644 --- a/rubocop/cop/migration/background_migrations.rb +++ b/rubocop/cop/migration/background_migrations.rb @@ -5,7 +5,7 @@ require_relative '../../migration_helpers' module RuboCop module Cop module Migration - class BackgroundMigrations < RuboCop::Cop::Cop + class BackgroundMigrations < RuboCop::Cop::Base include MigrationHelpers MSG = 'Background migrations are deprecated. Please use a Batched Background Migration instead.'\ @@ -20,7 +20,7 @@ module RuboCop migrate_in ) - add_offense(node, location: :selector) if disabled_methods.include? name + add_offense(node.loc.selector) if disabled_methods.include? name end end end diff --git a/rubocop/cop/migration/complex_indexes_require_name.rb b/rubocop/cop/migration/complex_indexes_require_name.rb index 82deb36716d..771537f2576 100644 --- a/rubocop/cop/migration/complex_indexes_require_name.rb +++ b/rubocop/cop/migration/complex_indexes_require_name.rb @@ -5,7 +5,7 @@ require_relative '../../migration_helpers' module RuboCop module Cop module Migration - class ComplexIndexesRequireName < RuboCop::Cop::Cop + class ComplexIndexesRequireName < RuboCop::Cop::Base include MigrationHelpers MSG = 'indexes added with custom options must be explicitly named' @@ -32,7 +32,7 @@ module RuboCop node.each_descendant(:send) do |send_node| next unless create_table_with_index_offense?(send_node) || add_index_offense?(send_node) - add_offense(send_node, location: :selector) + add_offense(send_node.loc.selector) end end diff --git a/rubocop/cop/migration/create_table_with_foreign_keys.rb b/rubocop/cop/migration/create_table_with_foreign_keys.rb index 382a2d6f65b..e3039ac76a9 100644 --- a/rubocop/cop/migration/create_table_with_foreign_keys.rb +++ b/rubocop/cop/migration/create_table_with_foreign_keys.rb @@ -5,7 +5,7 @@ require_relative '../../migration_helpers' module RuboCop module Cop module Migration - class CreateTableWithForeignKeys < RuboCop::Cop::Cop + class CreateTableWithForeignKeys < RuboCop::Cop::Base include MigrationHelpers MSG = 'Creating a table with more than one foreign key at once violates our migration style guide. ' \ diff --git a/rubocop/cop/migration/datetime.rb b/rubocop/cop/migration/datetime.rb index c605c8e1b6e..9cdb2d83ab5 100644 --- a/rubocop/cop/migration/datetime.rb +++ b/rubocop/cop/migration/datetime.rb @@ -6,7 +6,7 @@ module RuboCop module Cop module Migration # Cop that checks if datetime data type is added with timezone information. - class Datetime < RuboCop::Cop::Cop + class Datetime < RuboCop::Cop::Base include MigrationHelpers MSG = 'Do not use the `%s` data type, use `datetime_with_timezone` instead' @@ -19,7 +19,7 @@ module RuboCop method_name = send_node.children[1] if method_name == :datetime || method_name == :timestamp - add_offense(send_node, location: :selector, message: format(MSG, method_name)) + add_offense(send_node.loc.selector, message: format(MSG, method_name)) end end end @@ -34,7 +34,7 @@ module RuboCop last_argument = descendant.children.last if last_argument == :datetime || last_argument == :timestamp - add_offense(node, location: :expression, message: format(MSG, last_argument)) + add_offense(node, message: format(MSG, last_argument)) end end end diff --git a/rubocop/cop/migration/drop_table.rb b/rubocop/cop/migration/drop_table.rb index 531cbb14021..62dea79cbe6 100644 --- a/rubocop/cop/migration/drop_table.rb +++ b/rubocop/cop/migration/drop_table.rb @@ -7,7 +7,7 @@ module RuboCop module Migration # Cop that checks if `drop_table` is called in deployment migrations. # Calling it in deployment migrations can cause downtimes as there still may be code using the target tables. - class DropTable < RuboCop::Cop::Cop + class DropTable < RuboCop::Cop::Base include MigrationHelpers MSG = <<-MESSAGE.delete("\n").squeeze @@ -22,7 +22,7 @@ module RuboCop node.each_descendant(:send) do |send_node| next unless offensible?(send_node) - add_offense(send_node, location: :selector) + add_offense(send_node.loc.selector) end end diff --git a/rubocop/cop/migration/migration_record.rb b/rubocop/cop/migration/migration_record.rb index 291644f10e3..1543d2fff08 100644 --- a/rubocop/cop/migration/migration_record.rb +++ b/rubocop/cop/migration/migration_record.rb @@ -5,7 +5,7 @@ require_relative '../../migration_helpers' module RuboCop module Cop module Migration - class MigrationRecord < RuboCop::Cop::Cop + class MigrationRecord < RuboCop::Cop::Base include MigrationHelpers ENFORCED_SINCE = 2022_04_26_00_00_00 @@ -27,7 +27,7 @@ module RuboCop return unless relevant_migration?(node) return unless inherits_from_active_record_base?(node) || inherits_from_application_record?(node) - add_offense(node, location: :expression) + add_offense(node) end private diff --git a/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction.rb b/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction.rb index f5343f973e1..9556a16dc01 100644 --- a/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction.rb +++ b/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction.rb @@ -6,7 +6,7 @@ module RuboCop module Cop module Migration # Cop that prevents usage of `enable_lock_retries!` within the `disable_ddl_transaction!` method. - class PreventGlobalEnableLockRetriesWithDisableDdlTransaction < RuboCop::Cop::Cop + class PreventGlobalEnableLockRetriesWithDisableDdlTransaction < RuboCop::Cop::Base include MigrationHelpers MSG = '`enable_lock_retries!` cannot be used with `disable_ddl_transaction!`. Use the `with_lock_retries` helper method to define retriable code blocks.' diff --git a/rubocop/cop/migration/prevent_index_creation.rb b/rubocop/cop/migration/prevent_index_creation.rb index c383466f73b..185f36cb24b 100644 --- a/rubocop/cop/migration/prevent_index_creation.rb +++ b/rubocop/cop/migration/prevent_index_creation.rb @@ -5,7 +5,7 @@ module RuboCop module Cop module Migration # Cop that checks if new indexes are introduced to forbidden tables. - class PreventIndexCreation < RuboCop::Cop::Cop + class PreventIndexCreation < RuboCop::Cop::Base include MigrationHelpers FORBIDDEN_TABLES = %i[ci_builds].freeze @@ -41,7 +41,7 @@ module RuboCop return unless in_migration?(node) node.each_descendant(:send) do |send_node| - add_offense(send_node, location: :selector) if offense?(send_node) + add_offense(send_node.loc.selector) if offense?(send_node) end end diff --git a/rubocop/cop/migration/prevent_strings.rb b/rubocop/cop/migration/prevent_strings.rb index 57e29bf74ae..89659050f64 100644 --- a/rubocop/cop/migration/prevent_strings.rb +++ b/rubocop/cop/migration/prevent_strings.rb @@ -6,7 +6,7 @@ module RuboCop module Cop module Migration # Cop that enforces using text instead of the string data type - class PreventStrings < RuboCop::Cop::Cop + class PreventStrings < RuboCop::Cop::Base include MigrationHelpers MSG = 'Do not use the `string` data type, use `text` instead. ' \ @@ -26,7 +26,7 @@ module RuboCop node.each_descendant(:send) do |send_node| next unless string_operation?(send_node) - add_offense(send_node, location: :selector) + add_offense(send_node.loc.selector) end end diff --git a/rubocop/cop/migration/refer_to_index_by_name.rb b/rubocop/cop/migration/refer_to_index_by_name.rb index fbf3c0d7030..78619472487 100644 --- a/rubocop/cop/migration/refer_to_index_by_name.rb +++ b/rubocop/cop/migration/refer_to_index_by_name.rb @@ -5,7 +5,7 @@ require_relative '../../migration_helpers' module RuboCop module Cop module Migration - class ReferToIndexByName < RuboCop::Cop::Cop + class ReferToIndexByName < RuboCop::Cop::Base include MigrationHelpers MSG = 'migration methods that refer to existing indexes must do so by name' @@ -32,7 +32,7 @@ module RuboCop node.each_descendant(:send) do |send_node| next unless index_exists_offense?(send_node) || removing_index_offense?(send_node) - add_offense(send_node, location: :selector) + add_offense(send_node.loc.selector) end end diff --git a/rubocop/cop/migration/remove_column.rb b/rubocop/cop/migration/remove_column.rb index 6a171ac948f..e8477a211e4 100644 --- a/rubocop/cop/migration/remove_column.rb +++ b/rubocop/cop/migration/remove_column.rb @@ -7,7 +7,7 @@ module RuboCop module Migration # Cop that checks if remove_column is used in a regular (not # post-deployment) migration. - class RemoveColumn < RuboCop::Cop::Cop + class RemoveColumn < RuboCop::Cop::Base include MigrationHelpers MSG = '`remove_column` must only be used in post-deployment migrations' @@ -22,7 +22,7 @@ module RuboCop send_method = send_node.children[1] if send_method == :remove_column - add_offense(send_node, location: :selector) + add_offense(send_node.loc.selector) end end end diff --git a/rubocop/cop/migration/remove_concurrent_index.rb b/rubocop/cop/migration/remove_concurrent_index.rb index 30dd59d97bc..459f474d185 100644 --- a/rubocop/cop/migration/remove_concurrent_index.rb +++ b/rubocop/cop/migration/remove_concurrent_index.rb @@ -7,7 +7,7 @@ module RuboCop module Migration # Cop that checks if `remove_concurrent_index` is used with `up`/`down` methods # and not `change`. - class RemoveConcurrentIndex < RuboCop::Cop::Cop + class RemoveConcurrentIndex < RuboCop::Cop::Base include MigrationHelpers MSG = '`remove_concurrent_index` is not reversible so you must manually define ' \ @@ -18,13 +18,9 @@ module RuboCop return unless node.children[1] == :remove_concurrent_index node.each_ancestor(:def) do |def_node| - add_offense(def_node, location: :name) if method_name(def_node) == :change + add_offense(def_node.loc.name) if def_node.method_name == :change end end - - def method_name(node) - node.children[0] - end end end end diff --git a/rubocop/cop/migration/remove_index.rb b/rubocop/cop/migration/remove_index.rb index ca5d4af1520..26d271207dc 100644 --- a/rubocop/cop/migration/remove_index.rb +++ b/rubocop/cop/migration/remove_index.rb @@ -6,7 +6,7 @@ module RuboCop module Cop module Migration # Cop that checks if indexes are removed in a concurrent manner. - class RemoveIndex < RuboCop::Cop::Cop + class RemoveIndex < RuboCop::Cop::Base include MigrationHelpers MSG = '`remove_index` requires downtime, use `remove_concurrent_index` instead' @@ -15,7 +15,7 @@ module RuboCop return unless in_migration?(node) node.each_descendant(:send) do |send_node| - add_offense(send_node, location: :selector) if method_name(send_node) == :remove_index + add_offense(send_node.loc.selector) if method_name(send_node) == :remove_index end end diff --git a/rubocop/cop/migration/safer_boolean_column.rb b/rubocop/cop/migration/safer_boolean_column.rb index 1d780d96afa..d3d77b16357 100644 --- a/rubocop/cop/migration/safer_boolean_column.rb +++ b/rubocop/cop/migration/safer_boolean_column.rb @@ -18,7 +18,7 @@ module RuboCop # # See https://gitlab.com/gitlab-org/gitlab/issues/2750 for more # information. - class SaferBooleanColumn < RuboCop::Cop::Cop + class SaferBooleanColumn < RuboCop::Cop::Base include MigrationHelpers DEFAULT_OFFENSE = 'Boolean columns on the `%s` table should have a default. You may wish to use `add_column_with_default`.' @@ -52,7 +52,7 @@ module RuboCop NULL_OFFENSE end - add_offense(node, location: :expression, message: format(offense, table)) if offense + add_offense(node, message: format(offense, table)) if offense end def no_default?(opts) diff --git a/rubocop/cop/migration/schedule_async.rb b/rubocop/cop/migration/schedule_async.rb index 4fdedecdf64..bc98d45b9c6 100644 --- a/rubocop/cop/migration/schedule_async.rb +++ b/rubocop/cop/migration/schedule_async.rb @@ -5,7 +5,7 @@ require_relative '../../migration_helpers' module RuboCop module Cop module Migration - class ScheduleAsync < RuboCop::Cop::Cop + class ScheduleAsync < RuboCop::Cop::Base include MigrationHelpers ENFORCED_SINCE = 2020_02_12_00_00_00 @@ -32,7 +32,7 @@ module RuboCop return if version(node) < ENFORCED_SINCE return unless calls_background_migration_worker?(node) || calls_ci_database_worker?(node) - add_offense(node, location: :expression) + add_offense(node) end end end diff --git a/rubocop/cop/migration/sidekiq_queue_migrate.rb b/rubocop/cop/migration/sidekiq_queue_migrate.rb index 134bda590da..4a7aaa353a3 100644 --- a/rubocop/cop/migration/sidekiq_queue_migrate.rb +++ b/rubocop/cop/migration/sidekiq_queue_migrate.rb @@ -7,7 +7,7 @@ module RuboCop module Migration # Cop that checks if sidekiq_queue_migrate is used in a regular # (not post-deployment) migration. - class SidekiqQueueMigrate < RuboCop::Cop::Cop + class SidekiqQueueMigrate < RuboCop::Cop::Base include MigrationHelpers MSG = '`sidekiq_queue_migrate` must only be used in post-deployment migrations' @@ -19,7 +19,7 @@ module RuboCop send_method = send_node.children[1] if send_method == :sidekiq_queue_migrate - add_offense(send_node, location: :selector) + add_offense(send_node.loc.selector) end end end diff --git a/rubocop/cop/migration/timestamps.rb b/rubocop/cop/migration/timestamps.rb index 44baf17d968..5cc78a8821a 100644 --- a/rubocop/cop/migration/timestamps.rb +++ b/rubocop/cop/migration/timestamps.rb @@ -6,7 +6,7 @@ module RuboCop module Cop module Migration # Cop that checks if 'timestamps' method is called with timezone information. - class Timestamps < RuboCop::Cop::Cop + class Timestamps < RuboCop::Cop::Base include MigrationHelpers MSG = 'Do not use `timestamps`, use `timestamps_with_timezone` instead' @@ -16,7 +16,7 @@ module RuboCop return unless in_migration?(node) node.each_descendant(:send) do |send_node| - add_offense(send_node, location: :selector) if method_name(send_node) == :timestamps + add_offense(send_node.loc.selector) if method_name(send_node) == :timestamps end end diff --git a/rubocop/cop/migration/update_column_in_batches.rb b/rubocop/cop/migration/update_column_in_batches.rb index e23042e1b9f..7f4479c62e3 100644 --- a/rubocop/cop/migration/update_column_in_batches.rb +++ b/rubocop/cop/migration/update_column_in_batches.rb @@ -7,7 +7,7 @@ module RuboCop module Migration # Cop that checks if a spec file exists for any migration using # `update_column_in_batches`. - class UpdateColumnInBatches < RuboCop::Cop::Cop + class UpdateColumnInBatches < RuboCop::Cop::Base include MigrationHelpers MSG = 'Migration running `update_column_in_batches` must have a spec file at' \ @@ -19,9 +19,9 @@ module RuboCop spec_path = spec_filename(node) - unless File.exist?(File.expand_path(spec_path, rails_root)) - add_offense(node, location: :expression, message: format(MSG, spec_path)) - end + return if File.exist?(File.expand_path(spec_path, rails_root)) + + add_offense(node, message: format(MSG, spec_path)) end private diff --git a/rubocop/cop/migration/versioned_migration_class.rb b/rubocop/cop/migration/versioned_migration_class.rb index f2e4550c691..648782f1735 100644 --- a/rubocop/cop/migration/versioned_migration_class.rb +++ b/rubocop/cop/migration/versioned_migration_class.rb @@ -5,7 +5,7 @@ require_relative '../../migration_helpers' module RuboCop module Cop module Migration - class VersionedMigrationClass < RuboCop::Cop::Cop + class VersionedMigrationClass < RuboCop::Cop::Base include MigrationHelpers ENFORCED_SINCE = 2021_09_02_00_00_00 @@ -26,13 +26,13 @@ module RuboCop return unless relevant_migration?(node) return unless activerecord_migration_class?(node) - add_offense(node, location: :expression, message: MSG_INHERIT) + add_offense(node, message: MSG_INHERIT) end def on_send(node) return unless relevant_migration?(node) - add_offense(node, location: :expression, message: MSG_INCLUDE) if includes_helpers?(node) + add_offense(node, message: MSG_INCLUDE) if includes_helpers?(node) end private diff --git a/rubocop/cop/migration/with_lock_retries_disallowed_method.rb b/rubocop/cop/migration/with_lock_retries_disallowed_method.rb index b3d05ad1a6d..5c96b38dcdc 100644 --- a/rubocop/cop/migration/with_lock_retries_disallowed_method.rb +++ b/rubocop/cop/migration/with_lock_retries_disallowed_method.rb @@ -5,7 +5,7 @@ require_relative '../../migration_helpers' module RuboCop module Cop module Migration - class WithLockRetriesDisallowedMethod < RuboCop::Cop::Cop + class WithLockRetriesDisallowedMethod < RuboCop::Cop::Base include MigrationHelpers ALLOWED_MIGRATION_METHODS = %i[ @@ -60,8 +60,8 @@ module RuboCop return unless send_node?(node) name = node.children[1] - add_offense(node, location: :expression) unless ALLOWED_MIGRATION_METHODS.include?(name) - add_offense(node, location: :selector, message: MSG_ONLY_ONE_FK_ALLOWED) if multiple_fks?(node) + add_offense(node) unless ALLOWED_MIGRATION_METHODS.include?(name) + add_offense(node.loc.selector, message: MSG_ONLY_ONE_FK_ALLOWED) if multiple_fks?(node) end def multiple_fks?(node) diff --git a/rubocop/cop/migration/with_lock_retries_with_change.rb b/rubocop/cop/migration/with_lock_retries_with_change.rb index 9d11edcb6a1..59dbd6f22d2 100644 --- a/rubocop/cop/migration/with_lock_retries_with_change.rb +++ b/rubocop/cop/migration/with_lock_retries_with_change.rb @@ -6,7 +6,7 @@ module RuboCop module Cop module Migration # Cop that prevents usage of `with_lock_retries` within the `change` method. - class WithLockRetriesWithChange < RuboCop::Cop::Cop + class WithLockRetriesWithChange < RuboCop::Cop::Base include MigrationHelpers MSG = '`with_lock_retries` cannot be used within `change` so you must manually define ' \ @@ -17,13 +17,9 @@ module RuboCop return unless node.children[1] == :with_lock_retries node.each_ancestor(:def) do |def_node| - add_offense(def_node, location: :name) if method_name(def_node) == :change + add_offense(def_node.loc.name) if def_node.method_name == :change end end - - def method_name(node) - node.children.first - end end end end diff --git a/rubocop/cop/performance/active_record_subtransaction_methods.rb b/rubocop/cop/performance/active_record_subtransaction_methods.rb index 3b89d3ab858..1789e20ce45 100644 --- a/rubocop/cop/performance/active_record_subtransaction_methods.rb +++ b/rubocop/cop/performance/active_record_subtransaction_methods.rb @@ -5,7 +5,7 @@ module RuboCop module Performance # Cop that disallows certain methods that rely on subtransactions in their implementation. # Companion to Performance/ActiveRecordSubtransactions, which bans direct usage of subtransactions. - class ActiveRecordSubtransactionMethods < RuboCop::Cop::Cop + class ActiveRecordSubtransactionMethods < RuboCop::Cop::Base MSG = 'Methods that rely on subtransactions should not be used. ' \ 'For more information see: https://gitlab.com/gitlab-org/gitlab/-/issues/338346' @@ -21,7 +21,7 @@ module RuboCop def on_send(node) return unless DISALLOWED_METHODS.include?(node.method_name) - add_offense(node, location: :selector) + add_offense(node.loc.selector) end end end diff --git a/rubocop/cop/performance/active_record_subtransactions.rb b/rubocop/cop/performance/active_record_subtransactions.rb index a550b558e52..165efee7c6b 100644 --- a/rubocop/cop/performance/active_record_subtransactions.rb +++ b/rubocop/cop/performance/active_record_subtransactions.rb @@ -3,7 +3,7 @@ module RuboCop module Cop module Performance - class ActiveRecordSubtransactions < RuboCop::Cop::Cop + class ActiveRecordSubtransactions < RuboCop::Cop::Base MSG = 'Subtransactions should not be used. ' \ 'For more information see: https://gitlab.com/gitlab-org/gitlab/-/issues/338346' diff --git a/rubocop/cop/performance/ar_count_each.rb b/rubocop/cop/performance/ar_count_each.rb index 2fe8e549872..1dae473d87d 100644 --- a/rubocop/cop/performance/ar_count_each.rb +++ b/rubocop/cop/performance/ar_count_each.rb @@ -3,7 +3,7 @@ module RuboCop module Cop module Performance - class ARCountEach < RuboCop::Cop::Cop + class ARCountEach < RuboCop::Cop::Base def message(ivar) "If #{ivar} is AR relation, avoid `#{ivar}.count ...; #{ivar}.each... `, this will trigger two queries. " \ "Use `#{ivar}.load.size ...; #{ivar}.each... ` instead. If #{ivar} is an array, try to use #{ivar}.size." @@ -35,7 +35,7 @@ module RuboCop begin_node.each_descendant do |n| ivar_each = each_match(n) - add_offense(node, location: :expression, message: message(ivar_count)) if ivar_each == ivar_count + add_offense(node, message: message(ivar_count)) if ivar_each == ivar_count end end end diff --git a/rubocop/cop/performance/ar_exists_and_present_blank.rb b/rubocop/cop/performance/ar_exists_and_present_blank.rb index 54c2d6bf95a..c2ba6c2a206 100644 --- a/rubocop/cop/performance/ar_exists_and_present_blank.rb +++ b/rubocop/cop/performance/ar_exists_and_present_blank.rb @@ -3,7 +3,7 @@ module RuboCop module Cop module Performance - class ARExistsAndPresentBlank < RuboCop::Cop::Cop + class ARExistsAndPresentBlank < RuboCop::Cop::Base def message_present(ivar) "Avoid `#{ivar}.present?`, because it will generate database query 'Select TABLE.*' which is expensive. "\ "Suggest to use `#{ivar}.any?` to replace `#{ivar}.present?`" @@ -46,8 +46,8 @@ module RuboCop ivar_exists = exists_match(n) next unless ivar_exists - add_offense(node, location: :expression, message: message_present(ivar_exists)) if ivar_exists == ivar_present - add_offense(node, location: :expression, message: message_blank(ivar_exists)) if ivar_exists == ivar_blank + add_offense(node, message: message_present(ivar_exists)) if ivar_exists == ivar_present + add_offense(node, message: message_blank(ivar_exists)) if ivar_exists == ivar_blank end end end diff --git a/rubocop/cop/performance/readlines_each.rb b/rubocop/cop/performance/readlines_each.rb index cb4ffaca6e9..7a3a15020db 100644 --- a/rubocop/cop/performance/readlines_each.rb +++ b/rubocop/cop/performance/readlines_each.rb @@ -3,7 +3,9 @@ module RuboCop module Cop module Performance - class ReadlinesEach < RuboCop::Cop::Cop + class ReadlinesEach < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + MESSAGE = 'Avoid `IO.readlines.each`, since it reads contents into memory in full. ' \ 'Use `IO.each_line` or `IO.each` instead.' @@ -17,12 +19,9 @@ module RuboCop PATTERN def on_send(node) - full_file_read_via_class?(node) { add_offense(node, location: :selector, message: MESSAGE) } - full_file_read_via_instance?(node) { add_offense(node, location: :selector, message: MESSAGE) } - end + return unless full_file_read_via_class?(node) || full_file_read_via_instance?(node) - def autocorrect(node) - lambda do |corrector| + add_offense(node.loc.selector, message: MESSAGE) do |corrector| corrector.replace(node.loc.expression, node.source.gsub('readlines.each', 'each_line')) end end diff --git a/rubocop/cop/prefer_class_methods_over_module.rb b/rubocop/cop/prefer_class_methods_over_module.rb index 39b65073477..d865cc6c003 100644 --- a/rubocop/cop/prefer_class_methods_over_module.rb +++ b/rubocop/cop/prefer_class_methods_over_module.rb @@ -26,7 +26,8 @@ module RuboCop # end # end # - class PreferClassMethodsOverModule < RuboCop::Cop::Cop + class PreferClassMethodsOverModule < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector include RangeHelp MSG = 'Do not use module ClassMethods, use class_methods block instead.' @@ -36,17 +37,20 @@ module RuboCop PATTERN def on_module(node) - add_offense(node) if node.defined_module_name == 'ClassMethods' && module_extends_activesupport_concern?(node) - end + return unless class_methods_module_in_activesupport_concern?(node) - def autocorrect(node) - lambda do |corrector| + add_offense(node) do |corrector| corrector.replace(module_range(node), 'class_methods do') end end private + def class_methods_module_in_activesupport_concern?(node) + node.defined_module_name == 'ClassMethods' && + module_extends_activesupport_concern?(node) + end + def module_extends_activesupport_concern?(node) container_module = container_module_of(node) return false unless container_module diff --git a/rubocop/cop/project_path_helper.rb b/rubocop/cop/project_path_helper.rb index 0d12f2d2b12..104a352949f 100644 --- a/rubocop/cop/project_path_helper.rb +++ b/rubocop/cop/project_path_helper.rb @@ -2,7 +2,9 @@ module RuboCop module Cop - class ProjectPathHelper < RuboCop::Cop::Cop + class ProjectPathHelper < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + MSG = 'Use short project path helpers without explicitly passing the namespace: ' \ '`foo_project_bar_path(project, bar)` instead of ' \ '`foo_namespace_project_bar_path(project.namespace, project, bar)`.' @@ -19,18 +21,14 @@ module RuboCop return unless method_name(namespace_expr) == :namespace return unless receiver(namespace_expr) == project_expr - add_offense(node, location: :selector) - end - - def autocorrect(node) - helper_name = method_name(node).to_s.sub('namespace_project', 'project') + add_offense(node.loc.selector) do |corrector| + helper_name = method_name(node).to_s.sub('namespace_project', 'project') - arguments = arguments(node) - arguments.shift # Remove namespace argument + arguments = arguments(node) + arguments.shift # Remove namespace argument - replacement = "#{helper_name}(#{arguments.map(&:source).join(', ')})" + replacement = "#{helper_name}(#{arguments.map(&:source).join(', ')})" - lambda do |corrector| corrector.replace(node.source_range, replacement) end end diff --git a/rubocop/cop/put_group_routes_under_scope.rb b/rubocop/cop/put_group_routes_under_scope.rb index 9adec044da8..83afd112b99 100644 --- a/rubocop/cop/put_group_routes_under_scope.rb +++ b/rubocop/cop/put_group_routes_under_scope.rb @@ -6,7 +6,7 @@ module RuboCop module Cop # Checks for a group routes outside '/-/' scope. # For more information see: https://gitlab.com/gitlab-org/gitlab/issues/29572 - class PutGroupRoutesUnderScope < RuboCop::Cop::Cop + class PutGroupRoutesUnderScope < RuboCop::Cop::Base include RoutesUnderScope MSG = 'Put new group routes under /-/ scope' diff --git a/rubocop/cop/put_project_routes_under_scope.rb b/rubocop/cop/put_project_routes_under_scope.rb index cddb147324f..d3b86bad947 100644 --- a/rubocop/cop/put_project_routes_under_scope.rb +++ b/rubocop/cop/put_project_routes_under_scope.rb @@ -6,7 +6,7 @@ module RuboCop module Cop # Checks for a project routes outside '/-/' scope. # For more information see: https://gitlab.com/gitlab-org/gitlab/issues/29572 - class PutProjectRoutesUnderScope < RuboCop::Cop::Cop + class PutProjectRoutesUnderScope < RuboCop::Cop::Base include RoutesUnderScope MSG = 'Put new project routes under /-/ scope' diff --git a/rubocop/cop/qa/ambiguous_page_object_name.rb b/rubocop/cop/qa/ambiguous_page_object_name.rb index a4a2c04f61f..a331851bcc5 100644 --- a/rubocop/cop/qa/ambiguous_page_object_name.rb +++ b/rubocop/cop/qa/ambiguous_page_object_name.rb @@ -16,7 +16,7 @@ module RuboCop # # good # Page::Object.perform do |object| do ... # Page::Another.perform { |another| ... } - class AmbiguousPageObjectName < RuboCop::Cop::Cop + class AmbiguousPageObjectName < RuboCop::Cop::Base include QAHelpers MESSAGE = "Don't use 'page' as a name for a Page Object. Use `%s` instead." diff --git a/rubocop/cop/qa/element_with_pattern.rb b/rubocop/cop/qa/element_with_pattern.rb index d0a42497960..387ca3eb517 100644 --- a/rubocop/cop/qa/element_with_pattern.rb +++ b/rubocop/cop/qa/element_with_pattern.rb @@ -16,7 +16,7 @@ module RuboCop # # good # element :some_element # element :some_element, required: true - class ElementWithPattern < RuboCop::Cop::Cop + class ElementWithPattern < RuboCop::Cop::Base include QAHelpers MESSAGE = "Don't use a pattern for element, create a corresponding `%s` instead." diff --git a/rubocop/cop/qa/selector_usage.rb b/rubocop/cop/qa/selector_usage.rb index 568b1c30851..d615bd2926c 100644 --- a/rubocop/cop/qa/selector_usage.rb +++ b/rubocop/cop/qa/selector_usage.rb @@ -16,7 +16,7 @@ module RuboCop # # good # find('[data-testid="the_selector"]') # find('#selector') - class SelectorUsage < RuboCop::Cop::Cop + class SelectorUsage < RuboCop::Cop::Base include QAHelpers include CodeReuseHelpers diff --git a/rubocop/cop/rspec/any_instance_of.rb b/rubocop/cop/rspec/any_instance_of.rb index a939af36c13..e1cacfebfd3 100644 --- a/rubocop/cop/rspec/any_instance_of.rb +++ b/rubocop/cop/rspec/any_instance_of.rb @@ -24,7 +24,9 @@ module RuboCop # expect(instance).to receive(:invalidate_issue_cache_counts) # end # - class AnyInstanceOf < RuboCop::Cop::Cop + class AnyInstanceOf < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + MESSAGE_EXPECT = 'Do not use `expect_any_instance_of` method, use `expect_next_instance_of` instead.' MESSAGE_ALLOW = 'Do not use `allow_any_instance_of` method, use `allow_next_instance_of` instead.' @@ -37,22 +39,19 @@ module RuboCop def on_send(node) if expect_any_instance_of?(node) - add_offense(node, location: :expression, message: MESSAGE_EXPECT) + add_offense(node, message: MESSAGE_EXPECT) do |corrector| + corrector.replace( + node.loc.expression, + replacement_any_instance_of(node, 'expect') + ) + end elsif allow_any_instance_of?(node) - add_offense(node, location: :expression, message: MESSAGE_ALLOW) - end - end - - def autocorrect(node) - replacement = - if expect_any_instance_of?(node) - replacement_any_instance_of(node, 'expect') - elsif allow_any_instance_of?(node) - replacement_any_instance_of(node, 'allow') + add_offense(node, message: MESSAGE_ALLOW) do |corrector| + corrector.replace( + node.loc.expression, + replacement_any_instance_of(node, 'allow') + ) end - - lambda do |corrector| - corrector.replace(node.loc.expression, replacement) end end diff --git a/rubocop/cop/rspec/be_success_matcher.rb b/rubocop/cop/rspec/be_success_matcher.rb index dce9604b3d7..5a011845075 100644 --- a/rubocop/cop/rspec/be_success_matcher.rb +++ b/rubocop/cop/rspec/be_success_matcher.rb @@ -21,7 +21,9 @@ module RuboCop # # it { is_expected.to be_successful } # - class BeSuccessMatcher < RuboCop::Cop::Cop + class BeSuccessMatcher < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + MESSAGE = 'Do not use deprecated `success?` method, use `successful?` instead.' def_node_search :expect_to_be_success?, <<~PATTERN @@ -39,11 +41,7 @@ module RuboCop def on_send(node) return unless be_success_usage?(node) - add_offense(node, location: :expression, message: MESSAGE) - end - - def autocorrect(node) - lambda do |corrector| + add_offense(node, message: MESSAGE) do |corrector| corrector.insert_after(node.loc.expression, 'ful') end end diff --git a/rubocop/cop/rspec/env_assignment.rb b/rubocop/cop/rspec/env_assignment.rb index e3075e7bd90..add7897c624 100644 --- a/rubocop/cop/rspec/env_assignment.rb +++ b/rubocop/cop/rspec/env_assignment.rb @@ -16,7 +16,9 @@ module RuboCop # before do # stub_env('FOO', 'bar') # end - class EnvAssignment < RuboCop::Cop::Cop + class EnvAssignment < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + MESSAGE = "Don't assign to ENV, use `stub_env` instead." def_node_search :env_assignment?, <<~PATTERN @@ -28,11 +30,7 @@ module RuboCop def on_send(node) return unless env_assignment?(node) - add_offense(node, location: :expression, message: MESSAGE) - end - - def autocorrect(node) - lambda do |corrector| + add_offense(node, message: MESSAGE) do |corrector| corrector.replace(node.loc.expression, stub_env(env_key(node), env_value(node))) end end diff --git a/rubocop/cop/rspec/expect_gitlab_tracking.rb b/rubocop/cop/rspec/expect_gitlab_tracking.rb index e3f790f851c..4f92980baa4 100644 --- a/rubocop/cop/rspec/expect_gitlab_tracking.rb +++ b/rubocop/cop/rspec/expect_gitlab_tracking.rb @@ -29,7 +29,7 @@ module RuboCop # it 'does not expect a snowplow event', :snowplow do # expect_no_snowplow_event # end - class ExpectGitlabTracking < RuboCop::Cop::Cop + class ExpectGitlabTracking < RuboCop::Cop::Base MSG = 'Do not expect directly on `Gitlab::Tracking#event`, add the `snowplow` annotation and use ' \ '`expect_snowplow_event` instead. ' \ 'See https://docs.gitlab.com/ee/development/testing_guide/best_practices.html#test-snowplow-events' diff --git a/rubocop/cop/rspec/factories_in_migration_specs.rb b/rubocop/cop/rspec/factories_in_migration_specs.rb index f29bbf68cdc..6dde3d4524c 100644 --- a/rubocop/cop/rspec/factories_in_migration_specs.rb +++ b/rubocop/cop/rspec/factories_in_migration_specs.rb @@ -13,7 +13,7 @@ module RuboCop # # good # let(:users) { table(:users) } # let(:user) { users.create!(name: 'User 1', username: 'user1') } - class FactoriesInMigrationSpecs < RuboCop::Cop::Cop + class FactoriesInMigrationSpecs < RuboCop::Cop::Base MESSAGE = "Don't use FactoryBot.%s in migration specs, use `table` instead." FORBIDDEN_METHODS = %i[build build_list create create_list attributes_for].freeze @@ -29,7 +29,7 @@ module RuboCop method = node.children[1] - add_offense(node, location: :expression, message: MESSAGE % method) + add_offense(node, message: MESSAGE % method) end end end diff --git a/rubocop/cop/rspec/factory_bot/inline_association.rb b/rubocop/cop/rspec/factory_bot/inline_association.rb index 1c2b8b55b46..ccc6364fb73 100644 --- a/rubocop/cop/rspec/factory_bot/inline_association.rb +++ b/rubocop/cop/rspec/factory_bot/inline_association.rb @@ -43,7 +43,9 @@ module RuboCop # # creator_id { create(:user).id } # - class InlineAssociation < RuboCop::Cop::Cop + class InlineAssociation < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + MSG = 'Prefer inline `association` over `%{type}`. ' \ 'See https://docs.gitlab.com/ee/development/testing_guide/best_practices.html#factories' @@ -81,11 +83,7 @@ module RuboCop return if chained_call?(node.parent) return unless inside_assocation_definition?(node) - add_offense(node, message: format(MSG, type: type)) - end - - def autocorrect(node) - lambda do |corrector| + add_offense(node, message: format(MSG, type: type)) do |corrector| receiver, type = create_or_build(node) receiver = "#{receiver.source}." if receiver expression = "#{receiver}#{type}" diff --git a/rubocop/cop/rspec/have_gitlab_http_status.rb b/rubocop/cop/rspec/have_gitlab_http_status.rb index d61fb9f2368..86ece72b4f5 100644 --- a/rubocop/cop/rspec/have_gitlab_http_status.rb +++ b/rubocop/cop/rspec/have_gitlab_http_status.rb @@ -22,7 +22,9 @@ module RuboCop # expect(response).to have_gitlab_http_status(:ok) # expect(response).not_to have_gitlab_http_status(:ok) # - class HaveGitlabHttpStatus < RuboCop::Cop::Cop + class HaveGitlabHttpStatus < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + CODE_TO_SYMBOL = Rack::Utils::SYMBOL_TO_STATUS_CODE.invert MSG_MATCHER_NAME = @@ -66,13 +68,6 @@ module RuboCop offense_for_matcher(node) || offense_for_response_status(node) end - def autocorrect(node) - lambda do |corrector| - replacement = replace_matcher(node) || replace_response_status(node) - corrector.replace(node.source_range, replacement) - end - end - private def offense_for_matcher(node) @@ -85,13 +80,20 @@ module RuboCop return if offenses.empty? - add_offense(node, message: message_for(*offenses)) + add_offense(node, message: message_for(*offenses), &corrector(node)) end def offense_for_response_status(node) return unless response_status_eq?(node) - add_offense(node, message: message_for(MSG_RESPONSE_STATUS)) + add_offense(node, message: message_for(MSG_RESPONSE_STATUS), &corrector(node)) + end + + def corrector(node) + lambda do |corrector| + replacement = replace_matcher(node) || replace_response_status(node) + corrector.replace(node.source_range, replacement) + end end def replace_matcher(node) diff --git a/rubocop/cop/rspec/httparty_basic_auth.rb b/rubocop/cop/rspec/httparty_basic_auth.rb index c6b52ac9781..1e0f7ae7af0 100644 --- a/rubocop/cop/rspec/httparty_basic_auth.rb +++ b/rubocop/cop/rspec/httparty_basic_auth.rb @@ -12,7 +12,9 @@ module RuboCop # # # good # HTTParty.get(url, basic_auth: { username: 'foo' }) - class HTTPartyBasicAuth < RuboCop::Cop::Cop + class HTTPartyBasicAuth < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + MESSAGE = "`basic_auth: { user: ... }` does not work - replace `user:` with `username:`" RESTRICT_ON_SEND = %i(get put post delete).freeze @@ -35,12 +37,8 @@ module RuboCop def on_send(node) return unless m = httparty_basic_auth?(node) - add_offense(m, location: :expression, message: MESSAGE) - end - - def autocorrect(node) - lambda do |corrector| - corrector.replace(node.loc.expression, 'username') + add_offense(m, message: MESSAGE) do |corrector| + corrector.replace(m, 'username') end end end diff --git a/rubocop/cop/rspec/modify_sidekiq_middleware.rb b/rubocop/cop/rspec/modify_sidekiq_middleware.rb index c38f074eb3a..78e3ba223b0 100644 --- a/rubocop/cop/rspec/modify_sidekiq_middleware.rb +++ b/rubocop/cop/rspec/modify_sidekiq_middleware.rb @@ -20,7 +20,9 @@ module RuboCop # end # # - class ModifySidekiqMiddleware < RuboCop::Cop::Cop + class ModifySidekiqMiddleware < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + MSG = <<~MSG Don't modify global sidekiq middleware, use the `#with_sidekiq_server_middleware` helper instead @@ -35,11 +37,7 @@ module RuboCop def on_send(node) return unless modifies_sidekiq_middleware?(node) - add_offense(node, location: :expression) - end - - def autocorrect(node) - -> (corrector) do + add_offense(node) do |corrector| corrector.replace(node.loc.expression, 'with_sidekiq_server_middleware') end diff --git a/rubocop/cop/rspec/timecop_freeze.rb b/rubocop/cop/rspec/timecop_freeze.rb index 508b5df7c7f..70e37ecfa55 100644 --- a/rubocop/cop/rspec/timecop_freeze.rb +++ b/rubocop/cop/rspec/timecop_freeze.rb @@ -13,7 +13,9 @@ module RuboCop # # good # freeze_time(Time.current) { example.run } # - class TimecopFreeze < RuboCop::Cop::Cop + class TimecopFreeze < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + include MatchRange MESSAGE = 'Do not use `Timecop.freeze`, use `freeze_time` instead. ' \ 'See https://gitlab.com/gitlab-org/gitlab/-/issues/214432 for more info.' @@ -25,11 +27,7 @@ module RuboCop def on_send(node) return unless timecop_freeze?(node) - add_offense(node, location: :expression, message: MESSAGE) - end - - def autocorrect(node) - -> (corrector) do + add_offense(node, message: MESSAGE) do |corrector| each_match_range(node.source_range, /^(Timecop\.freeze)/) do |match_range| corrector.replace(match_range, 'freeze_time') end diff --git a/rubocop/cop/rspec/timecop_travel.rb b/rubocop/cop/rspec/timecop_travel.rb index e5416953af7..586567fa0cd 100644 --- a/rubocop/cop/rspec/timecop_travel.rb +++ b/rubocop/cop/rspec/timecop_travel.rb @@ -13,7 +13,9 @@ module RuboCop # # good # travel_to(1.day.ago) { create(:issue) } # - class TimecopTravel < RuboCop::Cop::Cop + class TimecopTravel < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + include MatchRange MESSAGE = 'Do not use `Timecop.travel`, use `travel_to` instead. ' \ 'See https://gitlab.com/gitlab-org/gitlab/-/issues/214432 for more info.' @@ -25,11 +27,7 @@ module RuboCop def on_send(node) return unless timecop_travel?(node) - add_offense(node, location: :expression, message: MESSAGE) - end - - def autocorrect(node) - -> (corrector) do + add_offense(node, message: MESSAGE) do |corrector| each_match_range(node.source_range, /^(Timecop\.travel)/) do |match_range| corrector.replace(match_range, 'travel_to') end diff --git a/rubocop/cop/rspec/web_mock_enable.rb b/rubocop/cop/rspec/web_mock_enable.rb index bcf7f95dbbd..0bef16a16b0 100644 --- a/rubocop/cop/rspec/web_mock_enable.rb +++ b/rubocop/cop/rspec/web_mock_enable.rb @@ -3,7 +3,9 @@ module RuboCop module Cop module RSpec - class WebMockEnable < RuboCop::Cop::Cop + class WebMockEnable < RuboCop::Cop::Base + extend RuboCop::Cop::AutoCorrector + # This cop checks for `WebMock.disable_net_connect!` usage in specs and # replaces it with `webmock_enable!` # @@ -24,13 +26,9 @@ module RuboCop def on_send(node) if webmock_disable_net_connect?(node) - add_offense(node, location: :expression, message: MESSAGE) - end - end - - def autocorrect(node) - lambda do |corrector| - corrector.replace(node, 'webmock_enable!') + add_offense(node, message: MESSAGE) do |corrector| + corrector.replace(node, 'webmock_enable!') + end end end end diff --git a/rubocop/cop/ruby_interpolation_in_translation.rb b/rubocop/cop/ruby_interpolation_in_translation.rb index c431b4a1977..fec550bf7c6 100644 --- a/rubocop/cop/ruby_interpolation_in_translation.rb +++ b/rubocop/cop/ruby_interpolation_in_translation.rb @@ -2,7 +2,7 @@ module RuboCop module Cop - class RubyInterpolationInTranslation < RuboCop::Cop::Cop + class RubyInterpolationInTranslation < RuboCop::Cop::Base MSG = "Don't use ruby interpolation \#{} inside translated strings, instead use \%{}" TRANSLATION_METHODS = ':_ :s_ :N_ :n_' diff --git a/rubocop/cop/safe_params.rb b/rubocop/cop/safe_params.rb index 2720732c161..78c40ee548e 100644 --- a/rubocop/cop/safe_params.rb +++ b/rubocop/cop/safe_params.rb @@ -2,7 +2,7 @@ module RuboCop module Cop - class SafeParams < RuboCop::Cop::Cop + class SafeParams < RuboCop::Cop::Base MSG = 'Use `safe_params` instead of `params` in url_for.' METHOD_NAME_PATTERN = :url_for @@ -11,7 +11,7 @@ module RuboCop def on_send(node) return unless method_name(node) == METHOD_NAME_PATTERN - add_offense(node, location: :expression) unless safe_params?(node) + add_offense(node) unless safe_params?(node) end private diff --git a/rubocop/cop/scalability/bulk_perform_with_context.rb b/rubocop/cop/scalability/bulk_perform_with_context.rb index bb944b2ad62..a31c20d149b 100644 --- a/rubocop/cop/scalability/bulk_perform_with_context.rb +++ b/rubocop/cop/scalability/bulk_perform_with_context.rb @@ -6,7 +6,7 @@ require_relative '../../code_reuse_helpers' module RuboCop module Cop module Scalability - class BulkPerformWithContext < RuboCop::Cop::Cop + class BulkPerformWithContext < RuboCop::Cop::Base include RuboCop::MigrationHelpers include RuboCop::CodeReuseHelpers @@ -34,7 +34,7 @@ module RuboCop return unless schedules_in_batch_without_context?(node) return if scheduled_for_background_migration?(node) - add_offense(node, location: :expression) + add_offense(node) end private diff --git a/rubocop/cop/scalability/cron_worker_context.rb b/rubocop/cop/scalability/cron_worker_context.rb index 3cc0d42d7bc..ae8b0b328e2 100644 --- a/rubocop/cop/scalability/cron_worker_context.rb +++ b/rubocop/cop/scalability/cron_worker_context.rb @@ -3,7 +3,7 @@ module RuboCop module Cop module Scalability - class CronWorkerContext < RuboCop::Cop::Cop + class CronWorkerContext < RuboCop::Cop::Base MSG = <<~MSG Manually define an ApplicationContext for cronjob-workers. The context is required to add metadata to our logs. @@ -31,7 +31,7 @@ module RuboCop return if defines_contexts?(node.parent) return if schedules_with_batch_context?(node.parent) - add_offense(node.arguments.first, location: :expression) + add_offense(node.arguments.first) end end end diff --git a/rubocop/cop/scalability/file_uploads.rb b/rubocop/cop/scalability/file_uploads.rb index 83017217e32..3ccb9110e79 100644 --- a/rubocop/cop/scalability/file_uploads.rb +++ b/rubocop/cop/scalability/file_uploads.rb @@ -25,7 +25,7 @@ module RuboCop # optional :file, type: ::API::Validations::Types::WorkhorseFile # end # - class FileUploads < RuboCop::Cop::Cop + class FileUploads < RuboCop::Cop::Base MSG = 'Do not upload files without workhorse acceleration. Please refer to https://docs.gitlab.com/ee/development/uploads.html' def_node_search :file_type_params?, <<~PATTERN @@ -43,7 +43,7 @@ module RuboCop def on_send(node) return unless be_file_param_usage?(node) - add_offense(find_file_param(node), location: :expression) + add_offense(find_file_param(node)) end private diff --git a/rubocop/cop/scalability/idempotent_worker.rb b/rubocop/cop/scalability/idempotent_worker.rb index 7abde54ce7e..88b5d796def 100644 --- a/rubocop/cop/scalability/idempotent_worker.rb +++ b/rubocop/cop/scalability/idempotent_worker.rb @@ -23,7 +23,7 @@ module RuboCop # end # end # - class IdempotentWorker < RuboCop::Cop::Cop + class IdempotentWorker < RuboCop::Cop::Base include CodeReuseHelpers HELP_LINK = 'https://github.com/mperham/sidekiq/wiki/Best-Practices#2-make-your-job-idempotent-and-transactional' @@ -51,7 +51,7 @@ module RuboCop return unless in_worker?(node) return if idempotent?(node) - add_offense(node, location: :expression) + add_offense(node) end end end diff --git a/rubocop/cop/sidekiq_load_balancing/worker_data_consistency.rb b/rubocop/cop/sidekiq_load_balancing/worker_data_consistency.rb index 7a2e7ee00b4..34c3767ad11 100644 --- a/rubocop/cop/sidekiq_load_balancing/worker_data_consistency.rb +++ b/rubocop/cop/sidekiq_load_balancing/worker_data_consistency.rb @@ -23,7 +23,7 @@ module RuboCop # end # end # - class WorkerDataConsistency < RuboCop::Cop::Cop + class WorkerDataConsistency < RuboCop::Cop::Base include CodeReuseHelpers HELP_LINK = 'https://docs.gitlab.com/ee/development/sidekiq_style_guide.html#job-data-consistency-strategies' @@ -57,7 +57,7 @@ module RuboCop return unless in_worker?(node) && application_worker?(node) return if data_consistency_defined?(node) - add_offense(node, location: :expression) + add_offense(node) end end end diff --git a/rubocop/cop/sidekiq_options_queue.rb b/rubocop/cop/sidekiq_options_queue.rb index 2574a229ec2..3eee59e69fd 100644 --- a/rubocop/cop/sidekiq_options_queue.rb +++ b/rubocop/cop/sidekiq_options_queue.rb @@ -3,7 +3,7 @@ module RuboCop module Cop # Cop that prevents manually setting a queue in Sidekiq workers. - class SidekiqOptionsQueue < RuboCop::Cop::Cop + class SidekiqOptionsQueue < RuboCop::Cop::Base MSG = 'Do not manually set a queue; `ApplicationWorker` sets one automatically.' def_node_matcher :sidekiq_options?, <<~PATTERN @@ -16,7 +16,7 @@ module RuboCop node.arguments.first.each_node(:pair) do |pair| key_name = pair.key.children[0] - add_offense(pair, location: :expression) if key_name == :queue + add_offense(pair) if key_name == :queue end end end diff --git a/rubocop/cop/static_translation_definition.rb b/rubocop/cop/static_translation_definition.rb index 121b0c18770..aea4dd6ae34 100644 --- a/rubocop/cop/static_translation_definition.rb +++ b/rubocop/cop/static_translation_definition.rb @@ -51,7 +51,7 @@ module RuboCop # end # end # - class StaticTranslationDefinition < RuboCop::Cop::Cop + class StaticTranslationDefinition < RuboCop::Cop::Base MSG = <<~TEXT.tr("\n", ' ') Translation is defined in static scope. Keep translations dynamic. See https://docs.gitlab.com/ee/development/i18n/externalization.html#keep-translations-dynamic diff --git a/rubocop/cop/usage_data/distinct_count_by_large_foreign_key.rb b/rubocop/cop/usage_data/distinct_count_by_large_foreign_key.rb index 3aad089d961..a083318288b 100644 --- a/rubocop/cop/usage_data/distinct_count_by_large_foreign_key.rb +++ b/rubocop/cop/usage_data/distinct_count_by_large_foreign_key.rb @@ -12,7 +12,7 @@ module RuboCop # # bad because pipeline_id points to a large table # distinct_count(Ci::Build, :commit_id) # - class DistinctCountByLargeForeignKey < RuboCop::Cop::Cop + class DistinctCountByLargeForeignKey < RuboCop::Cop::Base MSG = 'Avoid doing `%s` on foreign keys for large tables having above 100 million rows.' def_node_matcher :distinct_count?, <<-PATTERN @@ -25,7 +25,7 @@ module RuboCop next if batch_set_to_false?(method_arguments[2]) next if allowed_foreign_key?(method_arguments[1]) - add_offense(node, location: :selector, message: format(MSG, method_name)) + add_offense(node.loc.selector, message: format(MSG, method_name)) end end diff --git a/rubocop/cop/usage_data/histogram_with_large_table.rb b/rubocop/cop/usage_data/histogram_with_large_table.rb index 961773df55c..35ec568792c 100644 --- a/rubocop/cop/usage_data/histogram_with_large_table.rb +++ b/rubocop/cop/usage_data/histogram_with_large_table.rb @@ -11,7 +11,7 @@ module RuboCop # # bad # histogram(Issue, buckets: 1..100) # histogram(User.active, buckets: 1..100) - class HistogramWithLargeTable < RuboCop::Cop::Cop + class HistogramWithLargeTable < RuboCop::Cop::Base MSG = 'Avoid histogram method on %{model_name}' # Match one level const as Issue, Gitlab @@ -38,9 +38,9 @@ module RuboCop class_name = two_level_matches ? two_level_matches.join('::').to_sym : one_level_matches - if large_table?(class_name) - add_offense(node, location: :expression, message: format(MSG, model_name: class_name)) - end + return unless large_table?(class_name) + + add_offense(node, message: format(MSG, model_name: class_name)) end private diff --git a/rubocop/cop/usage_data/instrumentation_superclass.rb b/rubocop/cop/usage_data/instrumentation_superclass.rb index 2ff2ed47a23..601f2340582 100644 --- a/rubocop/cop/usage_data/instrumentation_superclass.rb +++ b/rubocop/cop/usage_data/instrumentation_superclass.rb @@ -16,7 +16,7 @@ module RuboCop # class CountIssues < BaseMetric # # ... # end - class InstrumentationSuperclass < RuboCop::Cop::Cop + class InstrumentationSuperclass < RuboCop::Cop::Base MSG = "Instrumentation classes should subclass one of the following: %{allowed_classes}." BASE_PATTERN = "(const nil? !#allowed_class?)" diff --git a/rubocop/cop/usage_data/large_table.rb b/rubocop/cop/usage_data/large_table.rb index d9d44f74d26..7d50eebaa83 100644 --- a/rubocop/cop/usage_data/large_table.rb +++ b/rubocop/cop/usage_data/large_table.rb @@ -3,7 +3,7 @@ module RuboCop module Cop module UsageData - class LargeTable < RuboCop::Cop::Cop + class LargeTable < RuboCop::Cop::Base # This cop checks that batch count and distinct_count are used in usage_data.rb files in metrics based on ActiveRecord models. # # @example @@ -56,7 +56,7 @@ module RuboCop counters_used = node.ancestors.any? { |ancestor| allowed_method?(ancestor) } unless counters_used - add_offense(node, location: :expression, message: format(MSG, count_methods: count_methods.join(', '), class_name: class_name)) + add_offense(node, message: format(MSG, count_methods: count_methods.join(', '), class_name: class_name)) end end diff --git a/rubocop/cop/user_admin.rb b/rubocop/cop/user_admin.rb index 3ba0e770ec1..643e620666b 100644 --- a/rubocop/cop/user_admin.rb +++ b/rubocop/cop/user_admin.rb @@ -3,7 +3,7 @@ module RuboCop module Cop # Cop that rejects the usage of `User#admin?` - class UserAdmin < RuboCop::Cop::Cop + class UserAdmin < RuboCop::Cop::Base MSG = 'Direct calls to `User#admin?` to determine admin status should be ' \ 'avoided as they will not take into account the policies framework ' \ 'and will ignore Admin Mode if enabled. Please use a policy check ' \ @@ -26,7 +26,7 @@ module RuboCop def on_handler(node) return unless admin_call?(node) - add_offense(node, location: :selector) + add_offense(node.loc.selector) end end end diff --git a/spec/config/object_store_settings_spec.rb b/spec/config/object_store_settings_spec.rb index 1555124fe03..8ddb5652dae 100644 --- a/spec/config/object_store_settings_spec.rb +++ b/spec/config/object_store_settings_spec.rb @@ -200,33 +200,6 @@ RSpec.describe ObjectStoreSettings do expect(settings.external_diffs['object_store']).to be_nil end end - - context 'with legacy config and legacy background upload is enabled' do - let(:legacy_settings) do - { - 'enabled' => true, - 'remote_directory' => 'some-bucket', - 'proxy_download' => false - } - end - - before do - stub_env(ObjectStoreSettings::LEGACY_BACKGROUND_UPLOADS_ENV, 'lfs') - settings.lfs['object_store'] = described_class.legacy_parse(legacy_settings, 'lfs') - end - - it 'enables background_upload and disables direct_upload' do - subject - - expect(settings.artifacts['object_store']).to be_nil - expect(settings.lfs['object_store']['remote_directory']).to eq('some-bucket') - expect(settings.lfs['object_store']['bucket_prefix']).to eq(nil) - # Enable background_upload if the environment variable is available - expect(settings.lfs['object_store']['direct_upload']).to eq(false) - expect(settings.lfs['object_store']['background_upload']).to eq(true) - expect(settings.external_diffs['object_store']).to be_nil - end - end end end @@ -266,48 +239,6 @@ RSpec.describe ObjectStoreSettings do expect(settings['remote_directory']).to eq 'gitlab' expect(settings['bucket_prefix']).to eq 'artifacts' end - - context 'legacy background upload environment variable is enabled' do - before do - stub_env(ObjectStoreSettings::LEGACY_BACKGROUND_UPLOADS_ENV, 'artifacts,lfs') - end - - it 'enables background_upload and disables direct_upload' do - original_settings = Settingslogic.new({ - 'enabled' => true, - 'remote_directory' => 'artifacts' - }) - - settings = described_class.legacy_parse(original_settings, 'artifacts') - - expect(settings['enabled']).to be true - expect(settings['direct_upload']).to be false - expect(settings['background_upload']).to be true - expect(settings['remote_directory']).to eq 'artifacts' - expect(settings['bucket_prefix']).to eq nil - end - end - - context 'legacy background upload environment variable is enabled for other types' do - before do - stub_env(ObjectStoreSettings::LEGACY_BACKGROUND_UPLOADS_ENV, 'uploads,lfs') - end - - it 'enables direct_upload and disables background_upload' do - original_settings = Settingslogic.new({ - 'enabled' => true, - 'remote_directory' => 'artifacts' - }) - - settings = described_class.legacy_parse(original_settings, 'artifacts') - - expect(settings['enabled']).to be true - expect(settings['direct_upload']).to be true - expect(settings['background_upload']).to be false - expect(settings['remote_directory']).to eq 'artifacts' - expect(settings['bucket_prefix']).to eq nil - end - end end describe '.split_bucket_prefix' do diff --git a/spec/controllers/concerns/continue_params_spec.rb b/spec/controllers/concerns/continue_params_spec.rb index c010e8ffbd0..ba600b8156a 100644 --- a/spec/controllers/concerns/continue_params_spec.rb +++ b/spec/controllers/concerns/continue_params_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe ContinueParams do let(:controller_class) do + # rubocop:disable Rails/ApplicationController Class.new(ActionController::Base) do include ContinueParams @@ -11,6 +12,7 @@ RSpec.describe ContinueParams do @request ||= Struct.new(:host, :port).new('test.host', 80) end end + # rubocop:enable Rails/ApplicationController end subject(:controller) { controller_class.new } diff --git a/spec/frontend/releases/stores/modules/detail/actions_spec.js b/spec/frontend/releases/stores/modules/detail/actions_spec.js index ce3b690213c..48fba3adb24 100644 --- a/spec/frontend/releases/stores/modules/detail/actions_spec.js +++ b/spec/frontend/releases/stores/modules/detail/actions_spec.js @@ -352,6 +352,32 @@ describe('Release edit/new actions', () => { }); }); + describe('when the GraphQL returns errors as data', () => { + beforeEach(() => { + gqClient.mutate.mockResolvedValue({ data: { releaseCreate: { errors: ['Yikes!'] } } }); + }); + + it(`commits ${types.RECEIVE_SAVE_RELEASE_ERROR} with an error object`, () => { + return testAction(actions.createRelease, undefined, state, [ + { + type: types.RECEIVE_SAVE_RELEASE_ERROR, + payload: expect.any(Error), + }, + ]); + }); + + it(`shows a flash message`, () => { + return actions + .createRelease({ commit: jest.fn(), dispatch: jest.fn(), state, getters: {} }) + .then(() => { + expect(createFlash).toHaveBeenCalledTimes(1); + expect(createFlash).toHaveBeenCalledWith({ + message: 'Yikes!', + }); + }); + }); + }); + describe('when the GraphQL network request fails', () => { beforeEach(() => { gqClient.mutate.mockRejectedValue(error); diff --git a/spec/graphql/mutations/releases/create_spec.rb b/spec/graphql/mutations/releases/create_spec.rb index b6b9449aa39..e7c25a20bad 100644 --- a/spec/graphql/mutations/releases/create_spec.rb +++ b/spec/graphql/mutations/releases/create_spec.rb @@ -135,7 +135,7 @@ RSpec.describe Mutations::Releases::Create do it 'has an access error' do subject - expect(resolve).to include(errors: ['Access Denied']) + expect(resolve).to include(errors: ['You are not allowed to create this tag as it is protected.']) end end end diff --git a/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb b/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb index 0f87ee82733..e730afc72b5 100644 --- a/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb +++ b/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb @@ -19,17 +19,36 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do } end + let(:report_data) do + { + 'scan' => { + 'analyzer' => { + 'id' => 'my-dast-analyzer', + 'name' => 'My DAST analyzer', + 'version' => '0.1.0', + 'vendor' => { 'name' => 'A DAST analyzer' } + }, + 'end_time' => '2020-01-28T03:26:02', + 'scanned_resources' => [], + 'scanner' => { + 'id' => 'my-dast-scanner', + 'name' => 'My DAST scanner', + 'version' => '0.2.0', + 'vendor' => { 'name' => 'A DAST scanner' } + }, + 'start_time' => '2020-01-28T03:26:01', + 'status' => 'success', + 'type' => 'dast' + }, + 'version' => report_version, + 'vulnerabilities' => [] + } + end + let(:validator) { described_class.new(report_type, report_data, report_version, project: project, scanner: scanner) } shared_examples 'report is valid' do context 'and the report is valid' do - let(:report_data) do - { - 'version' => report_version, - 'vulnerabilities' => [] - } - end - it { is_expected.to be_truthy } end end @@ -245,13 +264,6 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do shared_examples 'report is valid with no error' do context 'and the report is valid' do - let(:report_data) do - { - 'version' => report_version, - 'vulnerabilities' => [] - } - end - it { is_expected.to be_empty } end end @@ -278,7 +290,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do let(:expected_errors) do [ - 'root is missing required keys: vulnerabilities' + 'root is missing required keys: scan, vulnerabilities' ] end diff --git a/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb index e8eb3333b88..ee32661f267 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb @@ -83,19 +83,36 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Sequence do .with({ source: 'push' }, 0) end - it 'records active jobs by pipeline plan in a histogram' do - allow(command.metrics) - .to receive(:active_jobs_histogram) - .and_return(histogram) + describe 'active jobs by pipeline plan histogram' do + before do + allow(command.metrics) + .to receive(:active_jobs_histogram) + .and_return(histogram) + + pipeline = create(:ci_pipeline, :running, project: project) + create_list(:ci_build, 3, pipeline: pipeline) + create(:ci_bridge, pipeline: pipeline) + end - pipeline = create(:ci_pipeline, project: project, status: :running) - create(:ci_build, :finished, project: project, pipeline: pipeline) - create(:ci_build, :failed, project: project, pipeline: pipeline) - create(:ci_build, :running, project: project, pipeline: pipeline) - subject.build! + it 'counts all the active jobs' do + subject.build! - expect(histogram).to have_received(:observe) - .with(hash_including(plan: project.actual_plan_name), 3) + expect(histogram).to have_received(:observe) + .with(hash_including(plan: project.actual_plan_name), 4) + end + + context 'when feature flag ci_limit_active_jobs_early is disabled' do + before do + stub_feature_flags(ci_limit_active_jobs_early: false) + end + + it 'counts all the active builds' do + subject.build! + + expect(histogram).to have_received(:observe) + .with(hash_including(plan: project.actual_plan_name), 3) + end + end end end end diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 29ff0641aa9..f93aeef4f23 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -466,6 +466,48 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do end end + describe '.jobs_count_in_alive_pipelines' do + before do + ::Ci::HasStatus::ALIVE_STATUSES.each do |status| + alive_pipeline = create(:ci_pipeline, status: status, project: project) + create(:ci_build, pipeline: alive_pipeline) + create(:ci_bridge, pipeline: alive_pipeline) + end + + completed_pipeline = create(:ci_pipeline, :success, project: project) + create(:ci_build, pipeline: completed_pipeline) + + old_pipeline = create(:ci_pipeline, :running, project: project, created_at: 2.days.ago) + create(:ci_build, pipeline: old_pipeline) + end + + it 'includes all jobs in alive pipelines created in the last 24 hours' do + expect(described_class.jobs_count_in_alive_pipelines) + .to eq(::Ci::HasStatus::ALIVE_STATUSES.count * 2) + end + end + + describe '.builds_count_in_alive_pipelines' do + before do + ::Ci::HasStatus::ALIVE_STATUSES.each do |status| + alive_pipeline = create(:ci_pipeline, status: status, project: project) + create(:ci_build, pipeline: alive_pipeline) + create(:ci_bridge, pipeline: alive_pipeline) + end + + completed_pipeline = create(:ci_pipeline, :success, project: project) + create(:ci_build, pipeline: completed_pipeline) + + old_pipeline = create(:ci_pipeline, :running, project: project, created_at: 2.days.ago) + create(:ci_build, pipeline: old_pipeline) + end + + it 'includes all builds in alive pipelines created in the last 24 hours' do + expect(described_class.builds_count_in_alive_pipelines) + .to eq(::Ci::HasStatus::ALIVE_STATUSES.count) + end + end + describe '#merge_request?' do let_it_be(:merge_request) { create(:merge_request) } let_it_be_with_reload(:pipeline) do diff --git a/spec/rubocop/code_reuse_helpers_spec.rb b/spec/rubocop/code_reuse_helpers_spec.rb index a8f935426e6..a112c9754f3 100644 --- a/spec/rubocop/code_reuse_helpers_spec.rb +++ b/spec/rubocop/code_reuse_helpers_spec.rb @@ -342,7 +342,7 @@ RSpec.describe RuboCop::CodeReuseHelpers do expect(cop) .to receive(:add_offense) - .with(send_node, location: :expression, message: 'oops') + .with(send_node, message: 'oops') cop.disallow_send_to(def_node, 'Finder', 'oops') end diff --git a/spec/rubocop/cop/active_model_errors_direct_manipulation_spec.rb b/spec/rubocop/cop/active_model_errors_direct_manipulation_spec.rb index 203c3b4d019..6be2f4945fd 100644 --- a/spec/rubocop/cop/active_model_errors_direct_manipulation_spec.rb +++ b/spec/rubocop/cop/active_model_errors_direct_manipulation_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/active_model_errors_direct_manipulation' RSpec.describe RuboCop::Cop::ActiveModelErrorsDirectManipulation do - subject(:cop) { described_class.new } - context 'when modifying errors' do it 'registers an offense' do expect_offense(<<~PATTERN) diff --git a/spec/rubocop/cop/active_record_association_reload_spec.rb b/spec/rubocop/cop/active_record_association_reload_spec.rb index 8f5e40ba5dd..9f101b80d9a 100644 --- a/spec/rubocop/cop/active_record_association_reload_spec.rb +++ b/spec/rubocop/cop/active_record_association_reload_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/active_record_association_reload' RSpec.describe RuboCop::Cop::ActiveRecordAssociationReload do - subject(:cop) { described_class.new } - context 'when using ActiveRecord::Base' do it 'registers an offense on reload usage' do expect_offense(<<~PATTERN) diff --git a/spec/rubocop/cop/api/base_spec.rb b/spec/rubocop/cop/api/base_spec.rb index 3f87b6fd7a0..66e99b75643 100644 --- a/spec/rubocop/cop/api/base_spec.rb +++ b/spec/rubocop/cop/api/base_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/api/base' RSpec.describe RuboCop::Cop::API::Base do - subject(:cop) { described_class.new } - let(:corrected) do <<~CORRECTED class SomeAPI < ::API::Base diff --git a/spec/rubocop/cop/api/grape_array_missing_coerce_spec.rb b/spec/rubocop/cop/api/grape_array_missing_coerce_spec.rb index 5f310b68f18..1d1754df838 100644 --- a/spec/rubocop/cop/api/grape_array_missing_coerce_spec.rb +++ b/spec/rubocop/cop/api/grape_array_missing_coerce_spec.rb @@ -10,8 +10,6 @@ RSpec.describe RuboCop::Cop::API::GrapeArrayMissingCoerce do "https://github.com/ruby-grape/grape/blob/master/UPGRADING.md#ensure-that-array-types-have-explicit-coercions" end - subject(:cop) { described_class.new } - it 'adds an offense with a required parameter' do expect_offense(<<~TYPE) class SomeAPI < Grape::API::Instance diff --git a/spec/rubocop/cop/avoid_becomes_spec.rb b/spec/rubocop/cop/avoid_becomes_spec.rb index 4bb6c70c19f..d67b79329c9 100644 --- a/spec/rubocop/cop/avoid_becomes_spec.rb +++ b/spec/rubocop/cop/avoid_becomes_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/avoid_becomes' RSpec.describe RuboCop::Cop::AvoidBecomes do - subject(:cop) { described_class.new } - it 'flags the use of becomes with a constant parameter' do expect_offense(<<~CODE) foo.becomes(Project) diff --git a/spec/rubocop/cop/avoid_break_from_strong_memoize_spec.rb b/spec/rubocop/cop/avoid_break_from_strong_memoize_spec.rb index c66e2fb07b6..9b7d988cb24 100644 --- a/spec/rubocop/cop/avoid_break_from_strong_memoize_spec.rb +++ b/spec/rubocop/cop/avoid_break_from_strong_memoize_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/avoid_break_from_strong_memoize' RSpec.describe RuboCop::Cop::AvoidBreakFromStrongMemoize do - subject(:cop) { described_class.new } - it 'flags violation for break inside strong_memoize' do expect_offense(<<~RUBY) strong_memoize(:result) do diff --git a/spec/rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers_spec.rb b/spec/rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers_spec.rb index 76999891212..eb2417a7eef 100644 --- a/spec/rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers_spec.rb +++ b/spec/rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/avoid_keyword_arguments_in_sidekiq_workers' RSpec.describe RuboCop::Cop::AvoidKeywordArgumentsInSidekiqWorkers do - subject(:cop) { described_class.new } - it 'flags violation for keyword arguments usage in perform method signature' do expect_offense(<<~RUBY) def perform(id:) diff --git a/spec/rubocop/cop/avoid_return_from_blocks_spec.rb b/spec/rubocop/cop/avoid_return_from_blocks_spec.rb index 67e7e7912f2..e35705ae791 100644 --- a/spec/rubocop/cop/avoid_return_from_blocks_spec.rb +++ b/spec/rubocop/cop/avoid_return_from_blocks_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/avoid_return_from_blocks' RSpec.describe RuboCop::Cop::AvoidReturnFromBlocks do - subject(:cop) { described_class.new } - it 'flags violation for return inside a block' do expect_offense(<<~RUBY) call do diff --git a/spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb b/spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb index 0205bc9f02a..377050eb301 100644 --- a/spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb +++ b/spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/avoid_route_redirect_leading_slash' RSpec.describe RuboCop::Cop::AvoidRouteRedirectLeadingSlash do - subject(:cop) { described_class.new } - before do allow(cop).to receive(:in_routes?).and_return(true) end diff --git a/spec/rubocop/cop/ban_catch_throw_spec.rb b/spec/rubocop/cop/ban_catch_throw_spec.rb index 9a829a94ef5..a41868410eb 100644 --- a/spec/rubocop/cop/ban_catch_throw_spec.rb +++ b/spec/rubocop/cop/ban_catch_throw_spec.rb @@ -5,8 +5,6 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/ban_catch_throw' RSpec.describe RuboCop::Cop::BanCatchThrow do - subject(:cop) { described_class.new } - it 'registers an offense when `catch` or `throw` are used' do expect_offense(<<~CODE) catch(:foo) { diff --git a/spec/rubocop/cop/code_reuse/finder_spec.rb b/spec/rubocop/cop/code_reuse/finder_spec.rb index 4e49b2c4f9f..8e285e3d988 100644 --- a/spec/rubocop/cop/code_reuse/finder_spec.rb +++ b/spec/rubocop/cop/code_reuse/finder_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/code_reuse/finder' RSpec.describe RuboCop::Cop::CodeReuse::Finder do - subject(:cop) { described_class.new } - it 'flags the use of a Finder inside another Finder' do allow(cop) .to receive(:in_finder?) diff --git a/spec/rubocop/cop/code_reuse/presenter_spec.rb b/spec/rubocop/cop/code_reuse/presenter_spec.rb index 804e61a4c6f..fb7a95f930d 100644 --- a/spec/rubocop/cop/code_reuse/presenter_spec.rb +++ b/spec/rubocop/cop/code_reuse/presenter_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/code_reuse/presenter' RSpec.describe RuboCop::Cop::CodeReuse::Presenter do - subject(:cop) { described_class.new } - it 'flags the use of a Presenter in a Service class' do allow(cop) .to receive(:in_service_class?) diff --git a/spec/rubocop/cop/code_reuse/serializer_spec.rb b/spec/rubocop/cop/code_reuse/serializer_spec.rb index 5ff01812ebb..b1f22c7b969 100644 --- a/spec/rubocop/cop/code_reuse/serializer_spec.rb +++ b/spec/rubocop/cop/code_reuse/serializer_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/code_reuse/serializer' RSpec.describe RuboCop::Cop::CodeReuse::Serializer do - subject(:cop) { described_class.new } - it 'flags the use of a Serializer in a Service class' do allow(cop) .to receive(:in_service_class?) diff --git a/spec/rubocop/cop/code_reuse/service_class_spec.rb b/spec/rubocop/cop/code_reuse/service_class_spec.rb index 5467df9a803..5792b86a535 100644 --- a/spec/rubocop/cop/code_reuse/service_class_spec.rb +++ b/spec/rubocop/cop/code_reuse/service_class_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/code_reuse/service_class' RSpec.describe RuboCop::Cop::CodeReuse::ServiceClass do - subject(:cop) { described_class.new } - it 'flags the use of a Service class in a Finder' do allow(cop) .to receive(:in_finder?) diff --git a/spec/rubocop/cop/code_reuse/worker_spec.rb b/spec/rubocop/cop/code_reuse/worker_spec.rb index 3b3a0788d7d..2df5ebc56fa 100644 --- a/spec/rubocop/cop/code_reuse/worker_spec.rb +++ b/spec/rubocop/cop/code_reuse/worker_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/code_reuse/worker' RSpec.describe RuboCop::Cop::CodeReuse::Worker do - subject(:cop) { described_class.new } - it 'flags the use of a worker in a controller' do allow(cop) .to receive(:in_controller?) diff --git a/spec/rubocop/cop/database/disable_referential_integrity_spec.rb b/spec/rubocop/cop/database/disable_referential_integrity_spec.rb index 25d5dc7cb1d..5d31e55e586 100644 --- a/spec/rubocop/cop/database/disable_referential_integrity_spec.rb +++ b/spec/rubocop/cop/database/disable_referential_integrity_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/database/disable_referential_integrity' RSpec.describe RuboCop::Cop::Database::DisableReferentialIntegrity do - subject(:cop) { described_class.new } - it 'does not flag the use of disable_referential_integrity with a send receiver' do expect_offense(<<~SOURCE) foo.disable_referential_integrity diff --git a/spec/rubocop/cop/database/establish_connection_spec.rb b/spec/rubocop/cop/database/establish_connection_spec.rb index 88bf16083e4..987f68def75 100644 --- a/spec/rubocop/cop/database/establish_connection_spec.rb +++ b/spec/rubocop/cop/database/establish_connection_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/database/establish_connection' RSpec.describe RuboCop::Cop::Database::EstablishConnection do - subject(:cop) { described_class.new } - it 'flags the use of ActiveRecord::Base.establish_connection' do expect_offense(<<~CODE) ActiveRecord::Base.establish_connection diff --git a/spec/rubocop/cop/database/multiple_databases_spec.rb b/spec/rubocop/cop/database/multiple_databases_spec.rb index a5061735848..124e8aaf39c 100644 --- a/spec/rubocop/cop/database/multiple_databases_spec.rb +++ b/spec/rubocop/cop/database/multiple_databases_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/database/multiple_databases' RSpec.describe RuboCop::Cop::Database::MultipleDatabases do - subject(:cop) { described_class.new } - it 'flags the use of ActiveRecord::Base.connection' do expect_offense(<<~SOURCE) ActiveRecord::Base.connection.inspect diff --git a/spec/rubocop/cop/database/rescue_query_canceled_spec.rb b/spec/rubocop/cop/database/rescue_query_canceled_spec.rb index 170fe06bb9e..2418b45e3bb 100644 --- a/spec/rubocop/cop/database/rescue_query_canceled_spec.rb +++ b/spec/rubocop/cop/database/rescue_query_canceled_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/database/rescue_query_canceled' RSpec.describe RuboCop::Cop::Database::RescueQueryCanceled do - subject(:cop) { described_class.new } - it 'flags the use of ActiveRecord::QueryCanceled' do expect_offense(<<~CODE) begin diff --git a/spec/rubocop/cop/database/rescue_statement_timeout_spec.rb b/spec/rubocop/cop/database/rescue_statement_timeout_spec.rb index 9048930860d..bfeba2b4d00 100644 --- a/spec/rubocop/cop/database/rescue_statement_timeout_spec.rb +++ b/spec/rubocop/cop/database/rescue_statement_timeout_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/database/rescue_statement_timeout' RSpec.describe RuboCop::Cop::Database::RescueStatementTimeout do - subject(:cop) { described_class.new } - it 'flags the use of ActiveRecord::StatementTimeout' do expect_offense(<<~CODE) begin diff --git a/spec/rubocop/cop/default_scope_spec.rb b/spec/rubocop/cop/default_scope_spec.rb index 3a0607c32b8..d1f26cdce46 100644 --- a/spec/rubocop/cop/default_scope_spec.rb +++ b/spec/rubocop/cop/default_scope_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/default_scope' RSpec.describe RuboCop::Cop::DefaultScope do - subject(:cop) { described_class.new } - it 'does not flag the use of default_scope with a send receiver' do expect_no_offenses('foo.default_scope') end diff --git a/spec/rubocop/cop/destroy_all_spec.rb b/spec/rubocop/cop/destroy_all_spec.rb index cdc1fbbb531..f984822a4e8 100644 --- a/spec/rubocop/cop/destroy_all_spec.rb +++ b/spec/rubocop/cop/destroy_all_spec.rb @@ -4,18 +4,16 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/destroy_all' RSpec.describe RuboCop::Cop::DestroyAll do - subject(:cop) { described_class.new } - it 'flags the use of destroy_all with a send receiver' do expect_offense(<<~CODE) - foo.destroy_all # rubocop: disable Cop/DestroyAll + foo.destroy_all ^^^^^^^^^^^^^^^ Use `delete_all` instead of `destroy_all`. [...] CODE end it 'flags the use of destroy_all with a constant receiver' do expect_offense(<<~CODE) - User.destroy_all # rubocop: disable Cop/DestroyAll + User.destroy_all ^^^^^^^^^^^^^^^^ Use `delete_all` instead of `destroy_all`. [...] CODE end @@ -30,7 +28,7 @@ RSpec.describe RuboCop::Cop::DestroyAll do it 'flags the use of destroy_all with a local variable receiver' do expect_offense(<<~CODE) users = User.all - users.destroy_all # rubocop: disable Cop/DestroyAll + users.destroy_all ^^^^^^^^^^^^^^^^^ Use `delete_all` instead of `destroy_all`. [...] CODE end diff --git a/spec/rubocop/cop/file_decompression_spec.rb b/spec/rubocop/cop/file_decompression_spec.rb index 8b4aa8d57c3..19d71a2e85b 100644 --- a/spec/rubocop/cop/file_decompression_spec.rb +++ b/spec/rubocop/cop/file_decompression_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/file_decompression' RSpec.describe RuboCop::Cop::FileDecompression do - subject(:cop) { described_class.new } - it 'does not flag when using a system command not related to file decompression' do expect_no_offenses('system("ls")') end diff --git a/spec/rubocop/cop/filename_length_spec.rb b/spec/rubocop/cop/filename_length_spec.rb index d8d0affd9cc..1ea368d282f 100644 --- a/spec/rubocop/cop/filename_length_spec.rb +++ b/spec/rubocop/cop/filename_length_spec.rb @@ -5,8 +5,6 @@ require 'rubocop/rspec/support' require_relative '../../../rubocop/cop/filename_length' RSpec.describe RuboCop::Cop::FilenameLength do - subject(:cop) { described_class.new } - it 'does not flag files with names 100 characters long' do expect_no_offenses('puts "it does not matter"', 'a' * 100) end diff --git a/spec/rubocop/cop/gemspec/avoid_executing_git_spec.rb b/spec/rubocop/cop/gemspec/avoid_executing_git_spec.rb index c94fb9da113..6a1982d8101 100644 --- a/spec/rubocop/cop/gemspec/avoid_executing_git_spec.rb +++ b/spec/rubocop/cop/gemspec/avoid_executing_git_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gemspec/avoid_executing_git' RSpec.describe RuboCop::Cop::Gemspec::AvoidExecutingGit do - subject(:cop) { described_class.new } - it 'flags violation for executing git' do expect_offense(<<~RUBY) Gem::Specification.new do |gem| diff --git a/spec/rubocop/cop/gitlab/avoid_feature_category_not_owned_spec.rb b/spec/rubocop/cop/gitlab/avoid_feature_category_not_owned_spec.rb index 19a82231a80..9cacee5f75d 100644 --- a/spec/rubocop/cop/gitlab/avoid_feature_category_not_owned_spec.rb +++ b/spec/rubocop/cop/gitlab/avoid_feature_category_not_owned_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gitlab/avoid_feature_category_not_owned' RSpec.describe RuboCop::Cop::Gitlab::AvoidFeatureCategoryNotOwned do - subject(:cop) { described_class.new } - shared_examples 'defining feature category on a class' do it 'flags a method call on a class' do expect_offense(<<~SOURCE) @@ -31,7 +29,7 @@ RSpec.describe RuboCop::Cop::Gitlab::AvoidFeatureCategoryNotOwned do context 'in controllers' do before do - allow(subject).to receive(:in_controller?).and_return(true) + allow(cop).to receive(:in_controller?).and_return(true) end it_behaves_like 'defining feature category on a class' @@ -39,7 +37,7 @@ RSpec.describe RuboCop::Cop::Gitlab::AvoidFeatureCategoryNotOwned do context 'in workers' do before do - allow(subject).to receive(:in_worker?).and_return(true) + allow(cop).to receive(:in_worker?).and_return(true) end it_behaves_like 'defining feature category on a class' @@ -47,7 +45,7 @@ RSpec.describe RuboCop::Cop::Gitlab::AvoidFeatureCategoryNotOwned do context 'for grape endpoints' do before do - allow(subject).to receive(:in_api?).and_return(true) + allow(cop).to receive(:in_api?).and_return(true) end it_behaves_like 'defining feature category on a class' diff --git a/spec/rubocop/cop/gitlab/avoid_uploaded_file_from_params_spec.rb b/spec/rubocop/cop/gitlab/avoid_uploaded_file_from_params_spec.rb index bbdc6ca2470..09d5552d40c 100644 --- a/spec/rubocop/cop/gitlab/avoid_uploaded_file_from_params_spec.rb +++ b/spec/rubocop/cop/gitlab/avoid_uploaded_file_from_params_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gitlab/avoid_uploaded_file_from_params' RSpec.describe RuboCop::Cop::Gitlab::AvoidUploadedFileFromParams do - subject(:cop) { described_class.new } - context 'when using UploadedFile.from_params' do it 'flags its call' do expect_offense(<<~SOURCE) diff --git a/spec/rubocop/cop/gitlab/bulk_insert_spec.rb b/spec/rubocop/cop/gitlab/bulk_insert_spec.rb index 3cce93628fe..28fdd18b0f5 100644 --- a/spec/rubocop/cop/gitlab/bulk_insert_spec.rb +++ b/spec/rubocop/cop/gitlab/bulk_insert_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gitlab/bulk_insert' RSpec.describe RuboCop::Cop::Gitlab::BulkInsert do - subject(:cop) { described_class.new } - it 'flags the use of ApplicationRecord.legacy_bulk_insert' do expect_offense(<<~SOURCE) ApplicationRecord.legacy_bulk_insert('merge_request_diff_files', rows) diff --git a/spec/rubocop/cop/gitlab/change_timezone_spec.rb b/spec/rubocop/cop/gitlab/change_timezone_spec.rb index a3b5912e7e9..d5100cb662a 100644 --- a/spec/rubocop/cop/gitlab/change_timezone_spec.rb +++ b/spec/rubocop/cop/gitlab/change_timezone_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gitlab/change_timezone' RSpec.describe RuboCop::Cop::Gitlab::ChangeTimezone do - subject(:cop) { described_class.new } - context 'Time.zone=' do it 'registers an offense with no 2nd argument' do expect_offense(<<~PATTERN) diff --git a/spec/rubocop/cop/gitlab/const_get_inherit_false_spec.rb b/spec/rubocop/cop/gitlab/const_get_inherit_false_spec.rb index 1b13bcd4595..99cc9e0b469 100644 --- a/spec/rubocop/cop/gitlab/const_get_inherit_false_spec.rb +++ b/spec/rubocop/cop/gitlab/const_get_inherit_false_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gitlab/const_get_inherit_false' RSpec.describe RuboCop::Cop::Gitlab::ConstGetInheritFalse do - subject(:cop) { described_class.new } - context 'Object.const_get' do it 'registers an offense with no 2nd argument and corrects' do expect_offense(<<~PATTERN) diff --git a/spec/rubocop/cop/gitlab/delegate_predicate_methods_spec.rb b/spec/rubocop/cop/gitlab/delegate_predicate_methods_spec.rb index f910e8a7a54..1b497954aee 100644 --- a/spec/rubocop/cop/gitlab/delegate_predicate_methods_spec.rb +++ b/spec/rubocop/cop/gitlab/delegate_predicate_methods_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gitlab/delegate_predicate_methods' RSpec.describe RuboCop::Cop::Gitlab::DelegatePredicateMethods do - subject(:cop) { described_class.new } - it 'registers offense for single predicate method with allow_nil:true' do expect_offense(<<~SOURCE) delegate :is_foo?, :do_foo, to: :bar, allow_nil: true diff --git a/spec/rubocop/cop/gitlab/deprecate_track_redis_hll_event_spec.rb b/spec/rubocop/cop/gitlab/deprecate_track_redis_hll_event_spec.rb index a5370487794..eed30e11a98 100644 --- a/spec/rubocop/cop/gitlab/deprecate_track_redis_hll_event_spec.rb +++ b/spec/rubocop/cop/gitlab/deprecate_track_redis_hll_event_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gitlab/deprecate_track_redis_hll_event' RSpec.describe RuboCop::Cop::Gitlab::DeprecateTrackRedisHLLEvent do - subject(:cop) { described_class.new } - it 'does not flag the use of track_event' do expect_no_offenses('track_event :show, name: "p_analytics_insights"') end diff --git a/spec/rubocop/cop/gitlab/duplicate_spec_location_spec.rb b/spec/rubocop/cop/gitlab/duplicate_spec_location_spec.rb index 1a108d4cd41..9a1639806c8 100644 --- a/spec/rubocop/cop/gitlab/duplicate_spec_location_spec.rb +++ b/spec/rubocop/cop/gitlab/duplicate_spec_location_spec.rb @@ -5,8 +5,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gitlab/duplicate_spec_location' RSpec.describe RuboCop::Cop::Gitlab::DuplicateSpecLocation do - subject(:cop) { described_class.new } - let(:rails_root) { '../../../../' } def full_path(path) diff --git a/spec/rubocop/cop/gitlab/event_store_subscriber_spec.rb b/spec/rubocop/cop/gitlab/event_store_subscriber_spec.rb index 9fe28481565..7c692d5aad4 100644 --- a/spec/rubocop/cop/gitlab/event_store_subscriber_spec.rb +++ b/spec/rubocop/cop/gitlab/event_store_subscriber_spec.rb @@ -5,8 +5,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gitlab/event_store_subscriber' RSpec.describe RuboCop::Cop::Gitlab::EventStoreSubscriber do - subject(:cop) { described_class.new } - context 'when an event store subscriber overrides #perform' do it 'registers an offense' do expect_offense(<<~WORKER) diff --git a/spec/rubocop/cop/gitlab/except_spec.rb b/spec/rubocop/cop/gitlab/except_spec.rb index 60359ffa8bb..47048b8f658 100644 --- a/spec/rubocop/cop/gitlab/except_spec.rb +++ b/spec/rubocop/cop/gitlab/except_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gitlab/except' RSpec.describe RuboCop::Cop::Gitlab::Except do - subject(:cop) { described_class.new } - it 'flags the use of Gitlab::SQL::Except.new' do expect_offense(<<~SOURCE) Gitlab::SQL::Except.new([foo]) diff --git a/spec/rubocop/cop/gitlab/feature_available_usage_spec.rb b/spec/rubocop/cop/gitlab/feature_available_usage_spec.rb index 5b56800cc1c..30edd33a318 100644 --- a/spec/rubocop/cop/gitlab/feature_available_usage_spec.rb +++ b/spec/rubocop/cop/gitlab/feature_available_usage_spec.rb @@ -6,8 +6,6 @@ require 'rubocop/rspec/support' require_relative '../../../../rubocop/cop/gitlab/feature_available_usage' RSpec.describe RuboCop::Cop::Gitlab::FeatureAvailableUsage do - subject(:cop) { described_class.new } - context 'no arguments given' do it 'does not flag the use of Gitlab::Sourcegraph.feature_available? with no arguments' do expect_no_offenses('Gitlab::Sourcegraph.feature_available?') diff --git a/spec/rubocop/cop/gitlab/finder_with_find_by_spec.rb b/spec/rubocop/cop/gitlab/finder_with_find_by_spec.rb index 29a93b96228..6e01ef1bdec 100644 --- a/spec/rubocop/cop/gitlab/finder_with_find_by_spec.rb +++ b/spec/rubocop/cop/gitlab/finder_with_find_by_spec.rb @@ -5,8 +5,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gitlab/finder_with_find_by' RSpec.describe RuboCop::Cop::Gitlab::FinderWithFindBy do - subject(:cop) { described_class.new } - context 'when calling execute.find' do it 'registers an offense and corrects' do expect_offense(<<~CODE) diff --git a/spec/rubocop/cop/gitlab/httparty_spec.rb b/spec/rubocop/cop/gitlab/httparty_spec.rb index e1e72c11bd1..09204009d9b 100644 --- a/spec/rubocop/cop/gitlab/httparty_spec.rb +++ b/spec/rubocop/cop/gitlab/httparty_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gitlab/httparty' RSpec.describe RuboCop::Cop::Gitlab::HTTParty do # rubocop:disable RSpec/FilePath - subject(:cop) { described_class.new } - shared_examples('registering include offense') do it 'registers an offense when the class includes HTTParty' do expect_offense(source) diff --git a/spec/rubocop/cop/gitlab/intersect_spec.rb b/spec/rubocop/cop/gitlab/intersect_spec.rb index d2920c0b16b..c81dae9af97 100644 --- a/spec/rubocop/cop/gitlab/intersect_spec.rb +++ b/spec/rubocop/cop/gitlab/intersect_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gitlab/intersect' RSpec.describe RuboCop::Cop::Gitlab::Intersect do - subject(:cop) { described_class.new } - it 'flags the use of Gitlab::SQL::Intersect.new' do expect_offense(<<~SOURCE) Gitlab::SQL::Intersect.new([foo]) diff --git a/spec/rubocop/cop/gitlab/json_spec.rb b/spec/rubocop/cop/gitlab/json_spec.rb index c56b78c5750..e4ec107747d 100644 --- a/spec/rubocop/cop/gitlab/json_spec.rb +++ b/spec/rubocop/cop/gitlab/json_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gitlab/json' RSpec.describe RuboCop::Cop::Gitlab::Json do - subject(:cop) { described_class.new } - context 'when ::JSON is called' do it 'registers an offense' do expect_offense(<<~RUBY) diff --git a/spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb b/spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb index 515620bd820..ac7e41dda44 100644 --- a/spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb +++ b/spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb @@ -10,8 +10,6 @@ RSpec.describe RuboCop::Cop::Gitlab::MarkUsedFeatureFlags do %w[a_feature_flag foo_hello foo_world baz_experiment_percentage bar_baz] end - subject(:cop) { described_class.new } - before do allow(cop).to receive(:defined_feature_flags).and_return(defined_feature_flags) allow(cop).to receive(:usage_data_counters_known_event_feature_flags).and_return([]) diff --git a/spec/rubocop/cop/gitlab/module_with_instance_variables_spec.rb b/spec/rubocop/cop/gitlab/module_with_instance_variables_spec.rb index bf8409534f7..9f1691696eb 100644 --- a/spec/rubocop/cop/gitlab/module_with_instance_variables_spec.rb +++ b/spec/rubocop/cop/gitlab/module_with_instance_variables_spec.rb @@ -6,8 +6,6 @@ require_relative '../../../../rubocop/cop/gitlab/module_with_instance_variables' RSpec.describe RuboCop::Cop::Gitlab::ModuleWithInstanceVariables do let(:msg) { "Do not use instance variables in a module. [...]" } - subject(:cop) { described_class.new } - shared_examples('registering offense') do it 'registers an offense when instance variable is used in a module' do expect_offense(source) diff --git a/spec/rubocop/cop/gitlab/namespaced_class_spec.rb b/spec/rubocop/cop/gitlab/namespaced_class_spec.rb index f868a259f81..b16c3aba5c7 100644 --- a/spec/rubocop/cop/gitlab/namespaced_class_spec.rb +++ b/spec/rubocop/cop/gitlab/namespaced_class_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gitlab/namespaced_class' RSpec.describe RuboCop::Cop::Gitlab::NamespacedClass do - subject(:cop) { described_class.new } - shared_examples 'enforces namespaced classes' do def namespaced(code) return code unless namespace diff --git a/spec/rubocop/cop/gitlab/policy_rule_boolean_spec.rb b/spec/rubocop/cop/gitlab/policy_rule_boolean_spec.rb index ae50a1fa676..d00a9861c77 100644 --- a/spec/rubocop/cop/gitlab/policy_rule_boolean_spec.rb +++ b/spec/rubocop/cop/gitlab/policy_rule_boolean_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gitlab/policy_rule_boolean' RSpec.describe RuboCop::Cop::Gitlab::PolicyRuleBoolean do - subject(:cop) { described_class.new } - it 'registers offense for &&' do expect_offense(<<~SOURCE) rule { conducts_electricity && batteries }.enable :light_bulb diff --git a/spec/rubocop/cop/gitlab/predicate_memoization_spec.rb b/spec/rubocop/cop/gitlab/predicate_memoization_spec.rb index 40c2c30284f..1ca34ad90da 100644 --- a/spec/rubocop/cop/gitlab/predicate_memoization_spec.rb +++ b/spec/rubocop/cop/gitlab/predicate_memoization_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gitlab/predicate_memoization' RSpec.describe RuboCop::Cop::Gitlab::PredicateMemoization do - subject(:cop) { described_class.new } - shared_examples('not registering offense') do it 'does not register offenses' do expect_no_offenses(source) diff --git a/spec/rubocop/cop/gitlab/rails_logger_spec.rb b/spec/rubocop/cop/gitlab/rails_logger_spec.rb index ab47406d055..c9d361b49b8 100644 --- a/spec/rubocop/cop/gitlab/rails_logger_spec.rb +++ b/spec/rubocop/cop/gitlab/rails_logger_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gitlab/rails_logger' RSpec.describe RuboCop::Cop::Gitlab::RailsLogger do - subject(:cop) { described_class.new } - described_class::LOG_METHODS.each do |method| it "flags the use of Rails.logger.#{method} with a constant receiver" do node = "Rails.logger.#{method}('some error')" diff --git a/spec/rubocop/cop/gitlab/union_spec.rb b/spec/rubocop/cop/gitlab/union_spec.rb index d8080e8298b..4042fe0263a 100644 --- a/spec/rubocop/cop/gitlab/union_spec.rb +++ b/spec/rubocop/cop/gitlab/union_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/gitlab/union' RSpec.describe RuboCop::Cop::Gitlab::Union do - subject(:cop) { described_class.new } - it 'flags the use of Gitlab::SQL::Union.new' do expect_offense(<<~SOURCE) Gitlab::SQL::Union.new([foo]) diff --git a/spec/rubocop/cop/graphql/authorize_types_spec.rb b/spec/rubocop/cop/graphql/authorize_types_spec.rb index 3ea4d3e4a4d..a30cd5a1688 100644 --- a/spec/rubocop/cop/graphql/authorize_types_spec.rb +++ b/spec/rubocop/cop/graphql/authorize_types_spec.rb @@ -5,8 +5,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/graphql/authorize_types' RSpec.describe RuboCop::Cop::Graphql::AuthorizeTypes do - subject(:cop) { described_class.new } - it 'adds an offense when there is no authorize call' do expect_offense(<<~TYPE) module Types diff --git a/spec/rubocop/cop/graphql/descriptions_spec.rb b/spec/rubocop/cop/graphql/descriptions_spec.rb index f4fd78c846d..8826e700fdf 100644 --- a/spec/rubocop/cop/graphql/descriptions_spec.rb +++ b/spec/rubocop/cop/graphql/descriptions_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/graphql/descriptions' RSpec.describe RuboCop::Cop::Graphql::Descriptions do - subject(:cop) { described_class.new } - context 'with fields' do it 'adds an offense when there is no description' do expect_offense(<<~TYPE) diff --git a/spec/rubocop/cop/graphql/gid_expected_type_spec.rb b/spec/rubocop/cop/graphql/gid_expected_type_spec.rb index c6cd3ba0913..563c16a99df 100644 --- a/spec/rubocop/cop/graphql/gid_expected_type_spec.rb +++ b/spec/rubocop/cop/graphql/gid_expected_type_spec.rb @@ -5,8 +5,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/graphql/gid_expected_type' RSpec.describe RuboCop::Cop::Graphql::GIDExpectedType do - subject(:cop) { described_class.new } - it 'adds an offense when there is no expected_type parameter' do expect_offense(<<~TYPE) GitlabSchema.object_from_id(received_id) diff --git a/spec/rubocop/cop/graphql/graphql_name_position_spec.rb b/spec/rubocop/cop/graphql/graphql_name_position_spec.rb index 7bbbbed6e05..5db6fe6a801 100644 --- a/spec/rubocop/cop/graphql/graphql_name_position_spec.rb +++ b/spec/rubocop/cop/graphql/graphql_name_position_spec.rb @@ -5,8 +5,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/graphql/graphql_name_position' RSpec.describe RuboCop::Cop::Graphql::GraphqlNamePosition do - subject(:cop) { described_class.new } - it 'adds an offense when graphql_name is not on the first line' do expect_offense(<<~TYPE) module Types diff --git a/spec/rubocop/cop/graphql/id_type_spec.rb b/spec/rubocop/cop/graphql/id_type_spec.rb index fcd64561fe4..3a56753d39e 100644 --- a/spec/rubocop/cop/graphql/id_type_spec.rb +++ b/spec/rubocop/cop/graphql/id_type_spec.rb @@ -5,8 +5,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/graphql/id_type' RSpec.describe RuboCop::Cop::Graphql::IDType do - subject(:cop) { described_class.new } - it 'adds an offense when GraphQL::Types::ID is used as a param to #argument' do expect_offense(<<~TYPE) argument :some_arg, GraphQL::Types::ID, some: other, params: do_not_matter diff --git a/spec/rubocop/cop/graphql/json_type_spec.rb b/spec/rubocop/cop/graphql/json_type_spec.rb index d048fc4178b..c72e5b5b1c9 100644 --- a/spec/rubocop/cop/graphql/json_type_spec.rb +++ b/spec/rubocop/cop/graphql/json_type_spec.rb @@ -8,8 +8,6 @@ RSpec.describe RuboCop::Cop::Graphql::JSONType do 'Avoid using GraphQL::Types::JSON. See: https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#json' end - subject(:cop) { described_class.new } - context 'fields' do it 'adds an offense when GraphQL::Types::JSON is used' do expect_offense(<<~RUBY) diff --git a/spec/rubocop/cop/graphql/old_types_spec.rb b/spec/rubocop/cop/graphql/old_types_spec.rb index cb3d0087cbe..45d47f3b516 100644 --- a/spec/rubocop/cop/graphql/old_types_spec.rb +++ b/spec/rubocop/cop/graphql/old_types_spec.rb @@ -7,8 +7,6 @@ require_relative '../../../../rubocop/cop/graphql/old_types' RSpec.describe RuboCop::Cop::Graphql::OldTypes do using RSpec::Parameterized::TableSyntax - subject(:cop) { described_class.new } - where(:old_type, :message) do 'GraphQL::ID_TYPE' | 'Avoid using GraphQL::ID_TYPE. Use GraphQL::Types::ID instead' 'GraphQL::INT_TYPE' | 'Avoid using GraphQL::INT_TYPE. Use GraphQL::Types::Int instead' diff --git a/spec/rubocop/cop/graphql/resolver_type_spec.rb b/spec/rubocop/cop/graphql/resolver_type_spec.rb index 7b5213fdb3d..ade1bfc2cca 100644 --- a/spec/rubocop/cop/graphql/resolver_type_spec.rb +++ b/spec/rubocop/cop/graphql/resolver_type_spec.rb @@ -5,8 +5,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/graphql/resolver_type' RSpec.describe RuboCop::Cop::Graphql::ResolverType do - subject(:cop) { described_class.new } - it 'adds an offense when there is no type annotation' do expect_offense(<<~SRC) module Resolvers diff --git a/spec/rubocop/cop/group_public_or_visible_to_user_spec.rb b/spec/rubocop/cop/group_public_or_visible_to_user_spec.rb index b51c3d94aaa..c948ea606b8 100644 --- a/spec/rubocop/cop/group_public_or_visible_to_user_spec.rb +++ b/spec/rubocop/cop/group_public_or_visible_to_user_spec.rb @@ -9,8 +9,6 @@ RSpec.describe RuboCop::Cop::GroupPublicOrVisibleToUser do "Please ensure that you are not using it on its own and that the amount of rows being filtered is reasonable." end - subject(:cop) { described_class.new } - it 'flags the use of Group.public_or_visible_to_user with a constant receiver' do expect_offense(<<~CODE) Group.public_or_visible_to_user diff --git a/spec/rubocop/cop/ignored_columns_spec.rb b/spec/rubocop/cop/ignored_columns_spec.rb index 7c4f9c13856..c6c44399624 100644 --- a/spec/rubocop/cop/ignored_columns_spec.rb +++ b/spec/rubocop/cop/ignored_columns_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/ignored_columns' RSpec.describe RuboCop::Cop::IgnoredColumns do - subject(:cop) { described_class.new } - it 'flags direct use of ignored_columns instead of the IgnoredColumns concern' do expect_offense(<<~RUBY) class Foo < ApplicationRecord diff --git a/spec/rubocop/cop/include_sidekiq_worker_spec.rb b/spec/rubocop/cop/include_sidekiq_worker_spec.rb index bbb5232a1b4..f86bb1427db 100644 --- a/spec/rubocop/cop/include_sidekiq_worker_spec.rb +++ b/spec/rubocop/cop/include_sidekiq_worker_spec.rb @@ -5,8 +5,6 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/include_sidekiq_worker' RSpec.describe RuboCop::Cop::IncludeSidekiqWorker do - subject(:cop) { described_class.new } - context 'when `Sidekiq::Worker` is included' do it 'registers an offense and corrects', :aggregate_failures do expect_offense(<<~CODE) diff --git a/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb b/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb index 91ef2532e99..3063a474bd7 100644 --- a/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb +++ b/spec/rubocop/cop/inject_enterprise_edition_module_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/inject_enterprise_edition_module' RSpec.describe RuboCop::Cop::InjectEnterpriseEditionModule do - subject(:cop) { described_class.new } - it 'flags the use of `prepend_mod_with` in the middle of a file' do expect_offense(<<~SOURCE) class Foo diff --git a/spec/rubocop/cop/lint/last_keyword_argument_spec.rb b/spec/rubocop/cop/lint/last_keyword_argument_spec.rb index c2f3706cdb1..b0551a79c50 100644 --- a/spec/rubocop/cop/lint/last_keyword_argument_spec.rb +++ b/spec/rubocop/cop/lint/last_keyword_argument_spec.rb @@ -4,16 +4,15 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/lint/last_keyword_argument' RSpec.describe RuboCop::Cop::Lint::LastKeywordArgument do - subject(:cop) { described_class.new } - before do described_class.instance_variable_set(:@keyword_warnings, nil) + allow(Dir).to receive(:glob).and_call_original + allow(File).to receive(:read).and_call_original end context 'deprecation files does not exist' do before do - allow(Dir).to receive(:glob).and_return([]) - allow(File).to receive(:exist?).and_return(false) + allow(Dir).to receive(:glob).with(described_class::DEPRECATIONS_GLOB).and_return([]) end it 'does not register an offense' do @@ -58,7 +57,8 @@ RSpec.describe RuboCop::Cop::Lint::LastKeywordArgument do before do allow(Dir).to receive(:glob).and_return(['deprecations/service/create_spec.yml', 'deprecations/api/projects_spec.yml']) - allow(File).to receive(:read).and_return(create_spec_yaml, projects_spec_yaml) + allow(File).to receive(:read).with('deprecations/service/create_spec.yml').and_return(create_spec_yaml) + allow(File).to receive(:read).with('deprecations/api/projects_spec.yml').and_return(projects_spec_yaml) end it 'registers an offense for last keyword warning' do diff --git a/spec/rubocop/cop/migration/add_concurrent_index_spec.rb b/spec/rubocop/cop/migration/add_concurrent_index_spec.rb index 6344cbb3b5a..185b64b0334 100644 --- a/spec/rubocop/cop/migration/add_concurrent_index_spec.rb +++ b/spec/rubocop/cop/migration/add_concurrent_index_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/add_concurrent_index' RSpec.describe RuboCop::Cop::Migration::AddConcurrentIndex do - subject(:cop) { described_class.new } - context 'when in migration' do before do allow(cop).to receive(:in_migration?).and_return(true) diff --git a/spec/rubocop/cop/migration/add_index_spec.rb b/spec/rubocop/cop/migration/add_index_spec.rb index 595cb31e14e..338dbf73a3a 100644 --- a/spec/rubocop/cop/migration/add_index_spec.rb +++ b/spec/rubocop/cop/migration/add_index_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/add_index' RSpec.describe RuboCop::Cop::Migration::AddIndex do - subject(:cop) { described_class.new } - context 'in migration' do before do allow(cop).to receive(:in_migration?).and_return(true) diff --git a/spec/rubocop/cop/migration/add_limit_to_text_columns_spec.rb b/spec/rubocop/cop/migration/add_limit_to_text_columns_spec.rb index 78db7938fa3..85a86a27c48 100644 --- a/spec/rubocop/cop/migration/add_limit_to_text_columns_spec.rb +++ b/spec/rubocop/cop/migration/add_limit_to_text_columns_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/add_limit_to_text_columns' RSpec.describe RuboCop::Cop::Migration::AddLimitToTextColumns do - subject(:cop) { described_class.new } - context 'when in migration' do let(:msg) { 'Text columns should always have a limit set (255 is suggested)[...]' } diff --git a/spec/rubocop/cop/migration/add_timestamps_spec.rb b/spec/rubocop/cop/migration/add_timestamps_spec.rb index 593a0b00f07..fcc2f4aa363 100644 --- a/spec/rubocop/cop/migration/add_timestamps_spec.rb +++ b/spec/rubocop/cop/migration/add_timestamps_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/add_timestamps' RSpec.describe RuboCop::Cop::Migration::AddTimestamps do - subject(:cop) { described_class.new } - let(:migration_with_add_timestamps) do %q( class Users < ActiveRecord::Migration[4.2] diff --git a/spec/rubocop/cop/migration/background_migration_base_class_spec.rb b/spec/rubocop/cop/migration/background_migration_base_class_spec.rb index 140820e84bd..8cc85ac692c 100644 --- a/spec/rubocop/cop/migration/background_migration_base_class_spec.rb +++ b/spec/rubocop/cop/migration/background_migration_base_class_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/background_migration_base_class' RSpec.describe RuboCop::Cop::Migration::BackgroundMigrationBaseClass do - subject(:cop) { described_class.new } - context 'when the migration class inherits from BatchedMigrationJob' do it 'does not register any offenses' do expect_no_offenses(<<~RUBY) diff --git a/spec/rubocop/cop/migration/background_migration_record_spec.rb b/spec/rubocop/cop/migration/background_migration_record_spec.rb index 9e482293b93..d5a451e00c9 100644 --- a/spec/rubocop/cop/migration/background_migration_record_spec.rb +++ b/spec/rubocop/cop/migration/background_migration_record_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/background_migration_record' RSpec.describe RuboCop::Cop::Migration::BackgroundMigrationRecord do - subject(:cop) { described_class.new } - context 'outside of a migration' do it 'does not register any offenses' do expect_no_offenses(<<~SOURCE) diff --git a/spec/rubocop/cop/migration/complex_indexes_require_name_spec.rb b/spec/rubocop/cop/migration/complex_indexes_require_name_spec.rb index 4ffe9b17011..7329d399330 100644 --- a/spec/rubocop/cop/migration/complex_indexes_require_name_spec.rb +++ b/spec/rubocop/cop/migration/complex_indexes_require_name_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/complex_indexes_require_name' RSpec.describe RuboCop::Cop::Migration::ComplexIndexesRequireName do - subject(:cop) { described_class.new } - context 'when in migration' do let(:msg) { 'indexes added with custom options must be explicitly named' } diff --git a/spec/rubocop/cop/migration/datetime_spec.rb b/spec/rubocop/cop/migration/datetime_spec.rb index b8ec8674b56..400abe3be70 100644 --- a/spec/rubocop/cop/migration/datetime_spec.rb +++ b/spec/rubocop/cop/migration/datetime_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/datetime' RSpec.describe RuboCop::Cop::Migration::Datetime do - subject(:cop) { described_class.new } - let(:create_table_migration_without_datetime) do %q( class Users < ActiveRecord::Migration[6.0] diff --git a/spec/rubocop/cop/migration/drop_table_spec.rb b/spec/rubocop/cop/migration/drop_table_spec.rb index d172b0c5bb0..dd5f93eaafc 100644 --- a/spec/rubocop/cop/migration/drop_table_spec.rb +++ b/spec/rubocop/cop/migration/drop_table_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/drop_table' RSpec.describe RuboCop::Cop::Migration::DropTable do - subject(:cop) { described_class.new } - context 'when in deployment migration' do let(:msg) do '`drop_table` in deployment migrations requires downtime. Drop tables in post-deployment migrations instead.' diff --git a/spec/rubocop/cop/migration/migration_record_spec.rb b/spec/rubocop/cop/migration/migration_record_spec.rb index e941b8f8a87..96a1d8fa107 100644 --- a/spec/rubocop/cop/migration/migration_record_spec.rb +++ b/spec/rubocop/cop/migration/migration_record_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/migration_record' RSpec.describe RuboCop::Cop::Migration::MigrationRecord do - subject(:cop) { described_class.new } - shared_examples 'a disabled cop' do |klass| it 'does not register any offenses' do expect_no_offenses(<<~SOURCE) diff --git a/spec/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction_spec.rb b/spec/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction_spec.rb index 7afecfd39b2..1035ed2fb4a 100644 --- a/spec/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction_spec.rb +++ b/spec/rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/prevent_global_enable_lock_retries_with_disable_ddl_transaction' RSpec.describe RuboCop::Cop::Migration::PreventGlobalEnableLockRetriesWithDisableDdlTransaction do - subject(:cop) { described_class.new } - context 'when in migration' do before do allow(cop).to receive(:in_migration?).and_return(true) diff --git a/spec/rubocop/cop/migration/prevent_index_creation_spec.rb b/spec/rubocop/cop/migration/prevent_index_creation_spec.rb index 54393e69cf2..9d886467a48 100644 --- a/spec/rubocop/cop/migration/prevent_index_creation_spec.rb +++ b/spec/rubocop/cop/migration/prevent_index_creation_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/prevent_index_creation' RSpec.describe RuboCop::Cop::Migration::PreventIndexCreation do - subject(:cop) { described_class.new } - let(:forbidden_tables) { %w(ci_builds) } let(:forbidden_tables_list) { forbidden_tables.join(', ') } diff --git a/spec/rubocop/cop/migration/prevent_strings_spec.rb b/spec/rubocop/cop/migration/prevent_strings_spec.rb index 6f5d1ca4368..f1adeae6786 100644 --- a/spec/rubocop/cop/migration/prevent_strings_spec.rb +++ b/spec/rubocop/cop/migration/prevent_strings_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/prevent_strings' RSpec.describe RuboCop::Cop::Migration::PreventStrings do - subject(:cop) { described_class.new } - context 'when in migration' do before do allow(cop).to receive(:in_migration?).and_return(true) diff --git a/spec/rubocop/cop/migration/refer_to_index_by_name_spec.rb b/spec/rubocop/cop/migration/refer_to_index_by_name_spec.rb index 18d5353ce46..acdc6843584 100644 --- a/spec/rubocop/cop/migration/refer_to_index_by_name_spec.rb +++ b/spec/rubocop/cop/migration/refer_to_index_by_name_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/refer_to_index_by_name' RSpec.describe RuboCop::Cop::Migration::ReferToIndexByName do - subject(:cop) { described_class.new } - context 'when in migration' do before do allow(cop).to receive(:in_migration?).and_return(true) diff --git a/spec/rubocop/cop/migration/remove_column_spec.rb b/spec/rubocop/cop/migration/remove_column_spec.rb index 89edb3b420e..4aa842969fe 100644 --- a/spec/rubocop/cop/migration/remove_column_spec.rb +++ b/spec/rubocop/cop/migration/remove_column_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/remove_column' RSpec.describe RuboCop::Cop::Migration::RemoveColumn do - subject(:cop) { described_class.new } - def source(meth = 'change') "def #{meth}; remove_column :table, :column; end" end diff --git a/spec/rubocop/cop/migration/remove_concurrent_index_spec.rb b/spec/rubocop/cop/migration/remove_concurrent_index_spec.rb index 86bd3a2edea..1d59390d659 100644 --- a/spec/rubocop/cop/migration/remove_concurrent_index_spec.rb +++ b/spec/rubocop/cop/migration/remove_concurrent_index_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/remove_concurrent_index' RSpec.describe RuboCop::Cop::Migration::RemoveConcurrentIndex do - subject(:cop) { described_class.new } - context 'in migration' do before do allow(cop).to receive(:in_migration?).and_return(true) diff --git a/spec/rubocop/cop/migration/remove_index_spec.rb b/spec/rubocop/cop/migration/remove_index_spec.rb index bc8571b7e4d..24823b47d53 100644 --- a/spec/rubocop/cop/migration/remove_index_spec.rb +++ b/spec/rubocop/cop/migration/remove_index_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/remove_index' RSpec.describe RuboCop::Cop::Migration::RemoveIndex do - subject(:cop) { described_class.new } - context 'when in migration' do before do allow(cop).to receive(:in_migration?).and_return(true) diff --git a/spec/rubocop/cop/migration/safer_boolean_column_spec.rb b/spec/rubocop/cop/migration/safer_boolean_column_spec.rb index ef9bfb20cc8..2050051cac7 100644 --- a/spec/rubocop/cop/migration/safer_boolean_column_spec.rb +++ b/spec/rubocop/cop/migration/safer_boolean_column_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/safer_boolean_column' RSpec.describe RuboCop::Cop::Migration::SaferBooleanColumn do - subject(:cop) { described_class.new } - context 'in migration' do before do allow(cop).to receive(:in_migration?).and_return(true) diff --git a/spec/rubocop/cop/migration/sidekiq_queue_migrate_spec.rb b/spec/rubocop/cop/migration/sidekiq_queue_migrate_spec.rb index 7f451fb7b28..46c460b5d49 100644 --- a/spec/rubocop/cop/migration/sidekiq_queue_migrate_spec.rb +++ b/spec/rubocop/cop/migration/sidekiq_queue_migrate_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/sidekiq_queue_migrate' RSpec.describe RuboCop::Cop::Migration::SidekiqQueueMigrate do - subject(:cop) { described_class.new } - def source(meth = 'change') "def #{meth}; sidekiq_queue_migrate 'queue', to: 'new_queue'; end" end diff --git a/spec/rubocop/cop/migration/timestamps_spec.rb b/spec/rubocop/cop/migration/timestamps_spec.rb index 5508e0f564e..706fd8a3d0f 100644 --- a/spec/rubocop/cop/migration/timestamps_spec.rb +++ b/spec/rubocop/cop/migration/timestamps_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/timestamps' RSpec.describe RuboCop::Cop::Migration::Timestamps do - subject(:cop) { described_class.new } - let(:migration_with_timestamps) do %q( class Users < ActiveRecord::Migration[4.2] diff --git a/spec/rubocop/cop/migration/versioned_migration_class_spec.rb b/spec/rubocop/cop/migration/versioned_migration_class_spec.rb index 0ede5439069..b44f5d64a62 100644 --- a/spec/rubocop/cop/migration/versioned_migration_class_spec.rb +++ b/spec/rubocop/cop/migration/versioned_migration_class_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/versioned_migration_class' RSpec.describe RuboCop::Cop::Migration::VersionedMigrationClass do - subject(:cop) { described_class.new } - let(:migration) do <<~SOURCE class TestMigration < Gitlab::Database::Migration[1.0] diff --git a/spec/rubocop/cop/migration/with_lock_retries_disallowed_method_spec.rb b/spec/rubocop/cop/migration/with_lock_retries_disallowed_method_spec.rb index 67e45ac06e0..5762f78820c 100644 --- a/spec/rubocop/cop/migration/with_lock_retries_disallowed_method_spec.rb +++ b/spec/rubocop/cop/migration/with_lock_retries_disallowed_method_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/with_lock_retries_disallowed_method' RSpec.describe RuboCop::Cop::Migration::WithLockRetriesDisallowedMethod do - subject(:cop) { described_class.new } - context 'when in migration' do before do allow(cop).to receive(:in_migration?).and_return(true) diff --git a/spec/rubocop/cop/migration/with_lock_retries_with_change_spec.rb b/spec/rubocop/cop/migration/with_lock_retries_with_change_spec.rb index fc9f8a14e3f..fed9176ea97 100644 --- a/spec/rubocop/cop/migration/with_lock_retries_with_change_spec.rb +++ b/spec/rubocop/cop/migration/with_lock_retries_with_change_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/migration/with_lock_retries_with_change' RSpec.describe RuboCop::Cop::Migration::WithLockRetriesWithChange do - subject(:cop) { described_class.new } - context 'when in migration' do before do allow(cop).to receive(:in_migration?).and_return(true) diff --git a/spec/rubocop/cop/performance/active_record_subtransaction_methods_spec.rb b/spec/rubocop/cop/performance/active_record_subtransaction_methods_spec.rb index 1394dfe7f18..ac58ca1edf3 100644 --- a/spec/rubocop/cop/performance/active_record_subtransaction_methods_spec.rb +++ b/spec/rubocop/cop/performance/active_record_subtransaction_methods_spec.rb @@ -6,8 +6,6 @@ require 'rspec-parameterized' require_relative '../../../../rubocop/cop/performance/active_record_subtransaction_methods' RSpec.describe RuboCop::Cop::Performance::ActiveRecordSubtransactionMethods do - subject(:cop) { described_class.new } - let(:message) { described_class::MSG } shared_examples 'a method that uses a subtransaction' do |method_name| diff --git a/spec/rubocop/cop/performance/active_record_subtransactions_spec.rb b/spec/rubocop/cop/performance/active_record_subtransactions_spec.rb index 55889654272..e839a3e9367 100644 --- a/spec/rubocop/cop/performance/active_record_subtransactions_spec.rb +++ b/spec/rubocop/cop/performance/active_record_subtransactions_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/performance/active_record_subtransactions' RSpec.describe RuboCop::Cop::Performance::ActiveRecordSubtransactions do - subject(:cop) { described_class.new } - let(:message) { described_class::MSG } context 'when calling #transaction with only requires_new: true' do diff --git a/spec/rubocop/cop/performance/ar_count_each_spec.rb b/spec/rubocop/cop/performance/ar_count_each_spec.rb index e37a306efbb..a86b3f2b983 100644 --- a/spec/rubocop/cop/performance/ar_count_each_spec.rb +++ b/spec/rubocop/cop/performance/ar_count_each_spec.rb @@ -4,11 +4,9 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/performance/ar_count_each' RSpec.describe RuboCop::Cop::Performance::ARCountEach do - subject(:cop) { described_class.new } - context 'when it is not haml file' do it 'does not flag it as an offense' do - expect(subject).to receive(:in_haml_file?).with(anything).at_least(:once).and_return(false) + expect(cop).to receive(:in_haml_file?).with(anything).at_least(:once).and_return(false) expect_no_offenses <<~SOURCE show(@users.count) @@ -19,7 +17,7 @@ RSpec.describe RuboCop::Cop::Performance::ARCountEach do context 'when it is haml file' do before do - expect(subject).to receive(:in_haml_file?).with(anything).at_least(:once).and_return(true) + expect(cop).to receive(:in_haml_file?).with(anything).at_least(:once).and_return(true) end context 'when the same object uses count and each' do diff --git a/spec/rubocop/cop/performance/ar_exists_and_present_blank_spec.rb b/spec/rubocop/cop/performance/ar_exists_and_present_blank_spec.rb index 4a2e62623a4..070e792eeec 100644 --- a/spec/rubocop/cop/performance/ar_exists_and_present_blank_spec.rb +++ b/spec/rubocop/cop/performance/ar_exists_and_present_blank_spec.rb @@ -4,11 +4,9 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/performance/ar_exists_and_present_blank' RSpec.describe RuboCop::Cop::Performance::ARExistsAndPresentBlank do - subject(:cop) { described_class.new } - context 'when it is not haml file' do it 'does not flag it as an offense' do - expect(subject).to receive(:in_haml_file?).with(anything).at_least(:once).and_return(false) + expect(cop).to receive(:in_haml_file?).with(anything).at_least(:once).and_return(false) expect_no_offenses <<~SOURCE return unless @users.exists? @@ -19,7 +17,7 @@ RSpec.describe RuboCop::Cop::Performance::ARExistsAndPresentBlank do context 'when it is haml file' do before do - expect(subject).to receive(:in_haml_file?).with(anything).at_least(:once).and_return(true) + expect(cop).to receive(:in_haml_file?).with(anything).at_least(:once).and_return(true) end context 'the same object uses exists? and present?' do diff --git a/spec/rubocop/cop/performance/readlines_each_spec.rb b/spec/rubocop/cop/performance/readlines_each_spec.rb index 16421bcdaac..d876cbf79a5 100644 --- a/spec/rubocop/cop/performance/readlines_each_spec.rb +++ b/spec/rubocop/cop/performance/readlines_each_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/performance/readlines_each' RSpec.describe RuboCop::Cop::Performance::ReadlinesEach do - subject(:cop) { described_class.new } - let(:message) { 'Avoid `IO.readlines.each`, since it reads contents into memory in full. Use `IO.each_line` or `IO.each` instead.' } shared_examples_for(:class_read) do |klass| diff --git a/spec/rubocop/cop/prefer_class_methods_over_module_spec.rb b/spec/rubocop/cop/prefer_class_methods_over_module_spec.rb index 455d08951bd..a2a4270c48e 100644 --- a/spec/rubocop/cop/prefer_class_methods_over_module_spec.rb +++ b/spec/rubocop/cop/prefer_class_methods_over_module_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/prefer_class_methods_over_module' RSpec.describe RuboCop::Cop::PreferClassMethodsOverModule do - subject(:cop) { described_class.new } - it 'flags violation when using module ClassMethods and corrects', :aggregate_failures do expect_offense(<<~RUBY) module Foo diff --git a/spec/rubocop/cop/project_path_helper_spec.rb b/spec/rubocop/cop/project_path_helper_spec.rb index d8e66489e3c..3153c928c77 100644 --- a/spec/rubocop/cop/project_path_helper_spec.rb +++ b/spec/rubocop/cop/project_path_helper_spec.rb @@ -5,8 +5,6 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/project_path_helper' RSpec.describe RuboCop::Cop::ProjectPathHelper do - subject(:cop) { described_class.new } - context "when using namespace_project with the project's namespace" do let(:source) { 'edit_namespace_project_issue_path(@issue.project.namespace, @issue.project, @issue)' } let(:correct_source) { 'edit_project_issue_path(@issue.project, @issue)' } diff --git a/spec/rubocop/cop/put_group_routes_under_scope_spec.rb b/spec/rubocop/cop/put_group_routes_under_scope_spec.rb index a68cb30ac91..8697345cddc 100644 --- a/spec/rubocop/cop/put_group_routes_under_scope_spec.rb +++ b/spec/rubocop/cop/put_group_routes_under_scope_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/put_group_routes_under_scope' RSpec.describe RuboCop::Cop::PutGroupRoutesUnderScope do - subject(:cop) { described_class.new } - %w[resource resources get post put patch delete].each do |route_method| it "registers an offense when route is outside scope for `#{route_method}`" do offense = "#{route_method} :notes" diff --git a/spec/rubocop/cop/put_project_routes_under_scope_spec.rb b/spec/rubocop/cop/put_project_routes_under_scope_spec.rb index 82cafbeb73c..65d330b0f05 100644 --- a/spec/rubocop/cop/put_project_routes_under_scope_spec.rb +++ b/spec/rubocop/cop/put_project_routes_under_scope_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/put_project_routes_under_scope' RSpec.describe RuboCop::Cop::PutProjectRoutesUnderScope do - subject(:cop) { described_class.new } - %w[resource resources get post put patch delete].each do |route_method| it "registers an offense when route is outside scope for `#{route_method}`" do offense = "#{route_method} :notes" diff --git a/spec/rubocop/cop/qa/ambiguous_page_object_name_spec.rb b/spec/rubocop/cop/qa/ambiguous_page_object_name_spec.rb index dd03c531b36..ab270090c7d 100644 --- a/spec/rubocop/cop/qa/ambiguous_page_object_name_spec.rb +++ b/spec/rubocop/cop/qa/ambiguous_page_object_name_spec.rb @@ -7,8 +7,6 @@ require_relative '../../../../rubocop/cop/qa/ambiguous_page_object_name' RSpec.describe RuboCop::Cop::QA::AmbiguousPageObjectName do let(:source_file) { 'qa/page.rb' } - subject(:cop) { described_class.new } - context 'in a QA file' do before do allow(cop).to receive(:in_qa_file?).and_return(true) diff --git a/spec/rubocop/cop/qa/element_with_pattern_spec.rb b/spec/rubocop/cop/qa/element_with_pattern_spec.rb index eb098e8f288..1febdaf9c3b 100644 --- a/spec/rubocop/cop/qa/element_with_pattern_spec.rb +++ b/spec/rubocop/cop/qa/element_with_pattern_spec.rb @@ -7,8 +7,6 @@ require_relative '../../../../rubocop/cop/qa/element_with_pattern' RSpec.describe RuboCop::Cop::QA::ElementWithPattern do let(:source_file) { 'qa/page.rb' } - subject(:cop) { described_class.new } - context 'in a QA file' do before do allow(cop).to receive(:in_qa_file?).and_return(true) diff --git a/spec/rubocop/cop/qa/selector_usage_spec.rb b/spec/rubocop/cop/qa/selector_usage_spec.rb index 4045c82a5d8..0ec289c1da6 100644 --- a/spec/rubocop/cop/qa/selector_usage_spec.rb +++ b/spec/rubocop/cop/qa/selector_usage_spec.rb @@ -5,8 +5,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/qa/selector_usage' RSpec.describe RuboCop::Cop::QA::SelectorUsage do - subject(:cop) { described_class.new } - shared_examples 'non-qa file usage' do it 'reports an offense' do expect_offense(<<-RUBY) diff --git a/spec/rubocop/cop/rspec/any_instance_of_spec.rb b/spec/rubocop/cop/rspec/any_instance_of_spec.rb index 948664c110a..f9675e17842 100644 --- a/spec/rubocop/cop/rspec/any_instance_of_spec.rb +++ b/spec/rubocop/cop/rspec/any_instance_of_spec.rb @@ -5,8 +5,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/rspec/any_instance_of' RSpec.describe RuboCop::Cop::RSpec::AnyInstanceOf do - subject(:cop) { described_class.new } - context 'when calling allow_any_instance_of' do let(:source) do <<~SRC diff --git a/spec/rubocop/cop/rspec/be_success_matcher_spec.rb b/spec/rubocop/cop/rspec/be_success_matcher_spec.rb index 02eefe23df5..c26fa32db8e 100644 --- a/spec/rubocop/cop/rspec/be_success_matcher_spec.rb +++ b/spec/rubocop/cop/rspec/be_success_matcher_spec.rb @@ -6,8 +6,6 @@ require_relative '../../../../rubocop/cop/rspec/be_success_matcher' RSpec.describe RuboCop::Cop::RSpec::BeSuccessMatcher do let(:source_file) { 'spec/foo_spec.rb' } - subject(:cop) { described_class.new } - shared_examples 'cop' do |good:, bad:| context "using #{bad} call" do it 'registers an offense and corrects', :aggregate_failures do diff --git a/spec/rubocop/cop/rspec/env_assignment_spec.rb b/spec/rubocop/cop/rspec/env_assignment_spec.rb index 10559a30271..6212cda0b88 100644 --- a/spec/rubocop/cop/rspec/env_assignment_spec.rb +++ b/spec/rubocop/cop/rspec/env_assignment_spec.rb @@ -10,8 +10,6 @@ RSpec.describe RuboCop::Cop::RSpec::EnvAssignment do let(:source_file) { 'spec/foo_spec.rb' } - subject(:cop) { described_class.new } - shared_examples 'an offensive and correction ENV#[]= call' do |content, autocorrected_content| it "registers an offense for `#{content}` and corrects", :aggregate_failures do expect_offense(<<~CODE) diff --git a/spec/rubocop/cop/rspec/expect_gitlab_tracking_spec.rb b/spec/rubocop/cop/rspec/expect_gitlab_tracking_spec.rb index ad044b29a97..a07cf472ef0 100644 --- a/spec/rubocop/cop/rspec/expect_gitlab_tracking_spec.rb +++ b/spec/rubocop/cop/rspec/expect_gitlab_tracking_spec.rb @@ -6,8 +6,6 @@ require_relative '../../../../rubocop/cop/rspec/expect_gitlab_tracking' RSpec.describe RuboCop::Cop::RSpec::ExpectGitlabTracking do let(:source_file) { 'spec/foo_spec.rb' } - subject(:cop) { described_class.new } - good_samples = [ 'expect_snowplow_event(category: nil, action: nil)', 'expect_snowplow_event(category: "EventCategory", action: "event_action")', diff --git a/spec/rubocop/cop/rspec/factories_in_migration_specs_spec.rb b/spec/rubocop/cop/rspec/factories_in_migration_specs_spec.rb index 14fd5de45df..e41dd338387 100644 --- a/spec/rubocop/cop/rspec/factories_in_migration_specs_spec.rb +++ b/spec/rubocop/cop/rspec/factories_in_migration_specs_spec.rb @@ -5,8 +5,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/rspec/factories_in_migration_specs' RSpec.describe RuboCop::Cop::RSpec::FactoriesInMigrationSpecs do - subject(:cop) { described_class.new } - shared_examples 'an offensive factory call' do |namespace| %i[build build_list create create_list attributes_for].each do |forbidden_method| namespaced_forbidden_method = "#{namespace}#{forbidden_method}(:user)" diff --git a/spec/rubocop/cop/rspec/factory_bot/inline_association_spec.rb b/spec/rubocop/cop/rspec/factory_bot/inline_association_spec.rb index 260c622498f..008af734a99 100644 --- a/spec/rubocop/cop/rspec/factory_bot/inline_association_spec.rb +++ b/spec/rubocop/cop/rspec/factory_bot/inline_association_spec.rb @@ -6,8 +6,6 @@ require 'rspec-parameterized' require_relative '../../../../../rubocop/cop/rspec/factory_bot/inline_association' RSpec.describe RuboCop::Cop::RSpec::FactoryBot::InlineAssociation do - subject(:cop) { described_class.new } - shared_examples 'offense' do |code_snippet, autocorrected| # We allow `create` or `FactoryBot.create` or `::FactoryBot.create` let(:type) { code_snippet[/^(?:::)?(?:FactoryBot\.)?(\w+)/, 1] } diff --git a/spec/rubocop/cop/rspec/have_gitlab_http_status_spec.rb b/spec/rubocop/cop/rspec/have_gitlab_http_status_spec.rb index 356fe20556d..e8a60b9cad7 100644 --- a/spec/rubocop/cop/rspec/have_gitlab_http_status_spec.rb +++ b/spec/rubocop/cop/rspec/have_gitlab_http_status_spec.rb @@ -10,8 +10,6 @@ RSpec.describe RuboCop::Cop::RSpec::HaveGitlabHttpStatus do let(:source_file) { 'spec/foo_spec.rb' } - subject(:cop) { described_class.new } - shared_examples 'offense' do |bad, good| it 'registers an offense', :aggregate_failures do expect_offense(<<~CODE, node: bad) diff --git a/spec/rubocop/cop/rspec/htt_party_basic_auth_spec.rb b/spec/rubocop/cop/rspec/htt_party_basic_auth_spec.rb index 8dc68e877ce..537a7a9a7e9 100644 --- a/spec/rubocop/cop/rspec/htt_party_basic_auth_spec.rb +++ b/spec/rubocop/cop/rspec/htt_party_basic_auth_spec.rb @@ -5,8 +5,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/rspec/httparty_basic_auth' RSpec.describe RuboCop::Cop::RSpec::HTTPartyBasicAuth do - subject(:cop) { described_class.new } - context 'when passing `basic_auth: { user: ... }`' do it 'registers an offense and corrects', :aggregate_failures do expect_offense(<<~SOURCE, 'spec/foo.rb') diff --git a/spec/rubocop/cop/rspec/modify_sidekiq_middleware_spec.rb b/spec/rubocop/cop/rspec/modify_sidekiq_middleware_spec.rb index 82aa16b72bb..3227b075758 100644 --- a/spec/rubocop/cop/rspec/modify_sidekiq_middleware_spec.rb +++ b/spec/rubocop/cop/rspec/modify_sidekiq_middleware_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/rspec/modify_sidekiq_middleware' RSpec.describe RuboCop::Cop::RSpec::ModifySidekiqMiddleware do - subject(:cop) { described_class.new } - it 'registers an offense and corrects', :aggregate_failures do expect_offense(<<~CODE) Sidekiq::Testing.server_middleware do |chain| diff --git a/spec/rubocop/cop/rspec/timecop_freeze_spec.rb b/spec/rubocop/cop/rspec/timecop_freeze_spec.rb index 4e376a63617..4361f587da3 100644 --- a/spec/rubocop/cop/rspec/timecop_freeze_spec.rb +++ b/spec/rubocop/cop/rspec/timecop_freeze_spec.rb @@ -5,8 +5,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/rspec/timecop_freeze' RSpec.describe RuboCop::Cop::RSpec::TimecopFreeze do - subject(:cop) { described_class.new } - context 'when calling Timecop.freeze' do it 'registers an offense and corrects', :aggregate_failures do expect_offense(<<~CODE) diff --git a/spec/rubocop/cop/rspec/timecop_travel_spec.rb b/spec/rubocop/cop/rspec/timecop_travel_spec.rb index 3d048707878..89c46ff6c59 100644 --- a/spec/rubocop/cop/rspec/timecop_travel_spec.rb +++ b/spec/rubocop/cop/rspec/timecop_travel_spec.rb @@ -5,8 +5,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/rspec/timecop_travel' RSpec.describe RuboCop::Cop::RSpec::TimecopTravel do - subject(:cop) { described_class.new } - context 'when calling Timecop.travel' do it 'registers an offense and corrects', :aggregate_failures do expect_offense(<<~CODE) diff --git a/spec/rubocop/cop/rspec/top_level_describe_path_spec.rb b/spec/rubocop/cop/rspec/top_level_describe_path_spec.rb index 0e9a597dc11..90101e09023 100644 --- a/spec/rubocop/cop/rspec/top_level_describe_path_spec.rb +++ b/spec/rubocop/cop/rspec/top_level_describe_path_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/rspec/top_level_describe_path' RSpec.describe RuboCop::Cop::RSpec::TopLevelDescribePath do - subject(:cop) { described_class.new } - context 'when the file ends in _spec.rb' do it 'registers no offenses' do expect_no_offenses(<<~SOURCE, 'spec/foo_spec.rb') diff --git a/spec/rubocop/cop/rspec/web_mock_enable_spec.rb b/spec/rubocop/cop/rspec/web_mock_enable_spec.rb index 1b10e7c901a..63ffc06f1ca 100644 --- a/spec/rubocop/cop/rspec/web_mock_enable_spec.rb +++ b/spec/rubocop/cop/rspec/web_mock_enable_spec.rb @@ -5,8 +5,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/rspec/web_mock_enable' RSpec.describe RuboCop::Cop::RSpec::WebMockEnable do - subject(:cop) { described_class.new } - context 'when calling WebMock.disable_net_connect!' do it 'registers an offence and autocorrects it' do expect_offense(<<~RUBY) diff --git a/spec/rubocop/cop/ruby_interpolation_in_translation_spec.rb b/spec/rubocop/cop/ruby_interpolation_in_translation_spec.rb index b960a1d093e..b687e91601c 100644 --- a/spec/rubocop/cop/ruby_interpolation_in_translation_spec.rb +++ b/spec/rubocop/cop/ruby_interpolation_in_translation_spec.rb @@ -9,8 +9,6 @@ require_relative '../../../rubocop/cop/ruby_interpolation_in_translation' RSpec.describe RuboCop::Cop::RubyInterpolationInTranslation do let(:msg) { "Don't use ruby interpolation \#{} inside translated strings, instead use %{}" } - subject(:cop) { described_class.new } - it 'does not add an offense for a regular messages' do expect_no_offenses('_("Hello world")') end diff --git a/spec/rubocop/cop/safe_params_spec.rb b/spec/rubocop/cop/safe_params_spec.rb index 135e815eb53..e6d86019d18 100644 --- a/spec/rubocop/cop/safe_params_spec.rb +++ b/spec/rubocop/cop/safe_params_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/safe_params' RSpec.describe RuboCop::Cop::SafeParams do - subject(:cop) { described_class.new } - it 'flags the params as an argument of url_for' do expect_offense(<<~SOURCE) url_for(params) diff --git a/spec/rubocop/cop/scalability/bulk_perform_with_context_spec.rb b/spec/rubocop/cop/scalability/bulk_perform_with_context_spec.rb index ba5b150e1f9..bd248cd028a 100644 --- a/spec/rubocop/cop/scalability/bulk_perform_with_context_spec.rb +++ b/spec/rubocop/cop/scalability/bulk_perform_with_context_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/scalability/bulk_perform_with_context' RSpec.describe RuboCop::Cop::Scalability::BulkPerformWithContext do - subject(:cop) { described_class.new } - it "adds an offense when calling bulk_perform_async" do expect_offense(<<~CODE) Worker.bulk_perform_async(args) diff --git a/spec/rubocop/cop/scalability/cron_worker_context_spec.rb b/spec/rubocop/cop/scalability/cron_worker_context_spec.rb index bdd1406a0e6..bcf93b04d6a 100644 --- a/spec/rubocop/cop/scalability/cron_worker_context_spec.rb +++ b/spec/rubocop/cop/scalability/cron_worker_context_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/scalability/cron_worker_context' RSpec.describe RuboCop::Cop::Scalability::CronWorkerContext do - subject(:cop) { described_class.new } - it 'adds an offense when including CronjobQueue' do expect_offense(<<~CODE) class SomeWorker diff --git a/spec/rubocop/cop/scalability/file_uploads_spec.rb b/spec/rubocop/cop/scalability/file_uploads_spec.rb index c9e1e02be1a..1395615479f 100644 --- a/spec/rubocop/cop/scalability/file_uploads_spec.rb +++ b/spec/rubocop/cop/scalability/file_uploads_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/scalability/file_uploads' RSpec.describe RuboCop::Cop::Scalability::FileUploads do - subject(:cop) { described_class.new } - let(:message) { 'Do not upload files without workhorse acceleration. Please refer to https://docs.gitlab.com/ee/development/uploads.html' } context 'with required params' do diff --git a/spec/rubocop/cop/scalability/idempotent_worker_spec.rb b/spec/rubocop/cop/scalability/idempotent_worker_spec.rb index c1f841a46ec..b1984721803 100644 --- a/spec/rubocop/cop/scalability/idempotent_worker_spec.rb +++ b/spec/rubocop/cop/scalability/idempotent_worker_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/scalability/idempotent_worker' RSpec.describe RuboCop::Cop::Scalability::IdempotentWorker do - subject(:cop) { described_class.new } - before do allow(cop) .to receive(:in_worker?) diff --git a/spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_spec.rb b/spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_spec.rb index eef78397f0a..7b6578a0744 100644 --- a/spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_spec.rb +++ b/spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_spec.rb @@ -4,8 +4,6 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/sidekiq_load_balancing/worker_data_consistency' RSpec.describe RuboCop::Cop::SidekiqLoadBalancing::WorkerDataConsistency do - subject(:cop) { described_class.new } - before do allow(cop) .to receive(:in_worker?) diff --git a/spec/rubocop/cop/sidekiq_options_queue_spec.rb b/spec/rubocop/cop/sidekiq_options_queue_spec.rb index 8b7a67cff26..da126090a81 100644 --- a/spec/rubocop/cop/sidekiq_options_queue_spec.rb +++ b/spec/rubocop/cop/sidekiq_options_queue_spec.rb @@ -5,8 +5,6 @@ require 'rubocop_spec_helper' require_relative '../../../rubocop/cop/sidekiq_options_queue' RSpec.describe RuboCop::Cop::SidekiqOptionsQueue do - subject(:cop) { described_class.new } - it 'registers an offense when `sidekiq_options` is used with the `queue` option' do expect_offense(<<~CODE) sidekiq_options queue: "some_queue" diff --git a/spec/rubocop/cop/static_translation_definition_spec.rb b/spec/rubocop/cop/static_translation_definition_spec.rb index 33945064b3f..10b4f162504 100644 --- a/spec/rubocop/cop/static_translation_definition_spec.rb +++ b/spec/rubocop/cop/static_translation_definition_spec.rb @@ -11,8 +11,6 @@ RSpec.describe RuboCop::Cop::StaticTranslationDefinition do let(:msg) { described_class::MSG } - subject(:cop) { described_class.new } - shared_examples 'offense' do |code| it 'registers an offense' do expect_offense(code) diff --git a/spec/rubocop/cop/usage_data/distinct_count_by_large_foreign_key_spec.rb b/spec/rubocop/cop/usage_data/distinct_count_by_large_foreign_key_spec.rb index 14b6df8de4e..b4d113a9bcc 100644 --- a/spec/rubocop/cop/usage_data/distinct_count_by_large_foreign_key_spec.rb +++ b/spec/rubocop/cop/usage_data/distinct_count_by_large_foreign_key_spec.rb @@ -13,8 +13,6 @@ RSpec.describe RuboCop::Cop::UsageData::DistinctCountByLargeForeignKey do }) end - subject(:cop) { described_class.new(config) } - context 'when counting by disallowed key' do it 'registers an offense' do expect_offense(<<~CODE) diff --git a/spec/rubocop/cop/usage_data/histogram_with_large_table_spec.rb b/spec/rubocop/cop/usage_data/histogram_with_large_table_spec.rb index df9d538d2ae..efa4e27dc9c 100644 --- a/spec/rubocop/cop/usage_data/histogram_with_large_table_spec.rb +++ b/spec/rubocop/cop/usage_data/histogram_with_large_table_spec.rb @@ -14,8 +14,6 @@ RSpec.describe RuboCop::Cop::UsageData::HistogramWithLargeTable do }) end - subject(:cop) { described_class.new(config) } - context 'with large tables' do context 'with one-level constants' do context 'when calling histogram(Issue)' do diff --git a/spec/rubocop/cop/usage_data/instrumentation_superclass_spec.rb b/spec/rubocop/cop/usage_data/instrumentation_superclass_spec.rb index 8d2427e6e69..a55f0852f35 100644 --- a/spec/rubocop/cop/usage_data/instrumentation_superclass_spec.rb +++ b/spec/rubocop/cop/usage_data/instrumentation_superclass_spec.rb @@ -14,8 +14,6 @@ RSpec.describe RuboCop::Cop::UsageData::InstrumentationSuperclass do }) end - subject(:cop) { described_class.new(config) } - context 'with class definition' do context 'when inheriting from allowed superclass' do it 'does not register an offense' do diff --git a/spec/rubocop/cop/usage_data/large_table_spec.rb b/spec/rubocop/cop/usage_data/large_table_spec.rb index befdc1caead..fa94f878cea 100644 --- a/spec/rubocop/cop/usage_data/large_table_spec.rb +++ b/spec/rubocop/cop/usage_data/large_table_spec.rb @@ -18,8 +18,6 @@ RSpec.describe RuboCop::Cop::UsageData::LargeTable do }) end - subject(:cop) { described_class.new(config) } - context 'when in usage_data files' do before do allow(cop).to receive(:usage_data_files?).and_return(true) diff --git a/spec/rubocop/cop/user_admin_spec.rb b/spec/rubocop/cop/user_admin_spec.rb index b34418adf91..99e87d619c0 100644 --- a/spec/rubocop/cop/user_admin_spec.rb +++ b/spec/rubocop/cop/user_admin_spec.rb @@ -6,8 +6,6 @@ require 'rubocop' require_relative '../../../rubocop/cop/user_admin' RSpec.describe RuboCop::Cop::UserAdmin do - subject(:cop) { described_class.new } - it 'flags a method call' do expect_offense(<<~SOURCE) user.admin? diff --git a/spec/rubocop_spec_helper.rb b/spec/rubocop_spec_helper.rb index c49437137e3..a37415a25de 100644 --- a/spec/rubocop_spec_helper.rb +++ b/spec/rubocop_spec_helper.rb @@ -14,4 +14,7 @@ RSpec.configure do |config| config.define_derived_metadata(file_path: %r{spec/rubocop}) do |metadata| metadata[:type] = :rubocop end + + # Include config shared context for all cop specs. + config.include_context 'config', type: :rubocop end diff --git a/spec/services/releases/create_service_spec.rb b/spec/services/releases/create_service_spec.rb index 2421fab0eec..5f49eed3e77 100644 --- a/spec/services/releases/create_service_spec.rb +++ b/spec/services/releases/create_service_spec.rb @@ -70,6 +70,28 @@ RSpec.describe Releases::CreateService do expect(result[:release]).not_to be_nil end + context 'and the tag would be protected' do + let!(:protected_tag) { create(:protected_tag, project: project, name: tag_name) } + + context 'and the user does not have permissions' do + let(:user) { create(:user) } + + before do + project.add_developer(user) + end + + it 'raises an error' do + result = service.execute + + expect(result[:status]).to eq(:error) + end + end + + context 'and the user has permissions' do + it_behaves_like 'a successful release creation' + end + end + context 'and tag_message is provided' do let(:ref) { 'master' } let(:tag_name) { 'foobar' } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 160f7fda543..18820eefe31 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -125,9 +125,6 @@ RSpec.configure do |config| end end - # Re-run failures locally with `--only-failures` - config.example_status_persistence_file_path = ENV.fetch('RSPEC_LAST_RUN_RESULTS_FILE', './spec/examples.txt') - config.define_derived_metadata(file_path: %r{(ee)?/spec/.+_spec\.rb\z}) do |metadata| location = metadata[:location] diff --git a/spec/support/rspec.rb b/spec/support/rspec.rb index a11b720d060..2d37501f7c6 100644 --- a/spec/support/rspec.rb +++ b/spec/support/rspec.rb @@ -11,6 +11,9 @@ require_relative "helpers/fast_rails_root" RSpec::Expectations.configuration.on_potential_false_positives = :raise RSpec.configure do |config| + # Re-run failures locally with `--only-failures` + config.example_status_persistence_file_path = ENV.fetch('RSPEC_LAST_RUN_RESULTS_FILE', './spec/examples.txt') + config.mock_with :rspec do |mocks| mocks.verify_doubled_constant_names = true end diff --git a/vendor/gems/omniauth-azure-oauth2/Gemfile.lock b/vendor/gems/omniauth-azure-oauth2/Gemfile.lock index d2bbe3e8d2f..0bd5d401175 100644 --- a/vendor/gems/omniauth-azure-oauth2/Gemfile.lock +++ b/vendor/gems/omniauth-azure-oauth2/Gemfile.lock @@ -3,7 +3,7 @@ PATH specs: omniauth-azure-oauth2 (0.0.10) jwt (>= 1.0, < 3.0) - omniauth (~> 2.0) + omniauth (~> 1.0, < 3) omniauth-oauth2 (~> 1.4) GEM @@ -19,17 +19,16 @@ GEM multi_xml (0.6.0) mustermann (2.0.2) ruby2_keywords (~> 0.0.1) - oauth2 (2.0.3) + oauth2 (2.0.6) faraday (>= 0.17.3, < 3.0) jwt (>= 1.0, < 3.0) multi_xml (~> 0.5) rack (>= 1.2, < 3) rash_alt (>= 0.4, < 1) - version_gem (~> 1.0) - omniauth (2.1.0) + version_gem (~> 1.1) + omniauth (1.9.1) hashie (>= 3.4.6) - rack (>= 2.2.3) - rack-protection + rack (>= 1.6.2, < 3) omniauth-oauth2 (1.7.3) oauth2 (>= 1.4, < 3) omniauth (>= 1.9, < 3) @@ -71,4 +70,4 @@ DEPENDENCIES sinatra BUNDLED WITH - 2.3.21 + 2.3.20 diff --git a/vendor/gems/omniauth-azure-oauth2/lib/omniauth/strategies/azure_oauth2.rb b/vendor/gems/omniauth-azure-oauth2/lib/omniauth/strategies/azure_oauth2.rb index d71911b9876..f18babc0619 100644 --- a/vendor/gems/omniauth-azure-oauth2/lib/omniauth/strategies/azure_oauth2.rb +++ b/vendor/gems/omniauth-azure-oauth2/lib/omniauth/strategies/azure_oauth2.rb @@ -59,10 +59,8 @@ module OmniAuth super.merge(resource: azure_resource || options.resource) end - # for compatibility with OmniAuth 2.0 - # see https://github.com/RIPAGlobal/omniauth-azure-activedirectory-v2/pull/6 def callback_url - full_host + callback_path + full_host + script_name + callback_path end def raw_info diff --git a/vendor/gems/omniauth-azure-oauth2/omniauth-azure-oauth2.gemspec b/vendor/gems/omniauth-azure-oauth2/omniauth-azure-oauth2.gemspec index 1299285b945..6e1bc583881 100644 --- a/vendor/gems/omniauth-azure-oauth2/omniauth-azure-oauth2.gemspec +++ b/vendor/gems/omniauth-azure-oauth2/omniauth-azure-oauth2.gemspec @@ -15,7 +15,7 @@ Gem::Specification.new do |gem| gem.version = OmniAuth::AzureOauth2::VERSION gem.license = "MIT" - gem.add_runtime_dependency 'omniauth', '~> 2.0' + gem.add_runtime_dependency 'omniauth', '~> 1.0', '< 3' gem.add_dependency 'jwt', ['>= 1.0', '< 3.0'] gem.add_runtime_dependency 'omniauth-oauth2', '~> 1.4' diff --git a/vendor/gems/omniauth-cas3/Gemfile.lock b/vendor/gems/omniauth-cas3/Gemfile.lock index a856e78f00f..4c59eb05d50 100644 --- a/vendor/gems/omniauth-cas3/Gemfile.lock +++ b/vendor/gems/omniauth-cas3/Gemfile.lock @@ -4,30 +4,29 @@ PATH omniauth-cas3 (1.1.4) addressable (~> 2.3) nokogiri (~> 1.7, >= 1.7.1) - omniauth (~> 2.0) + omniauth (~> 1.2, < 3) GEM remote: https://rubygems.org/ specs: - addressable (2.8.1) - public_suffix (>= 2.0.2, < 6.0) + addressable (2.8.0) + public_suffix (>= 2.0.2, < 5.0) awesome_print (1.9.2) crack (0.4.5) rexml diff-lcs (1.5.0) hashdiff (1.0.1) hashie (5.0.0) + mini_portile2 (2.8.0) nokogiri (1.13.7) + mini_portile2 (~> 2.8.0) racc (~> 1.4) - omniauth (2.1.0) + omniauth (1.9.1) hashie (>= 3.4.6) - rack (>= 2.2.3) - rack-protection - public_suffix (5.0.0) + rack (>= 1.6.2, < 3) + public_suffix (4.0.7) racc (1.6.0) rack (2.2.4) - rack-protection (2.2.2) - rack rack-test (0.8.3) rack (>= 1.0, < 3) rake (10.5.0) @@ -45,7 +44,7 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.11.0) rspec-support (3.11.0) - webmock (3.18.1) + webmock (3.14.0) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -62,4 +61,4 @@ DEPENDENCIES webmock BUNDLED WITH - 2.3.21 + 2.3.18 diff --git a/vendor/gems/omniauth-cas3/omniauth-cas3.gemspec b/vendor/gems/omniauth-cas3/omniauth-cas3.gemspec index c976d85df99..abbcaa268d0 100644 --- a/vendor/gems/omniauth-cas3/omniauth-cas3.gemspec +++ b/vendor/gems/omniauth-cas3/omniauth-cas3.gemspec @@ -14,7 +14,7 @@ Gem::Specification.new do |gem| gem.require_paths = ["lib"] gem.version = Omniauth::Cas3::VERSION - gem.add_dependency 'omniauth', '~> 2.0' + gem.add_dependency 'omniauth', '~> 1.2', '< 3' gem.add_dependency 'nokogiri', '~> 1.7', '>= 1.7.1' gem.add_dependency 'addressable', '~> 2.3' diff --git a/vendor/gems/omniauth-gitlab/Gemfile.lock b/vendor/gems/omniauth-gitlab/Gemfile.lock index b59ba59b95b..b5979104080 100644 --- a/vendor/gems/omniauth-gitlab/Gemfile.lock +++ b/vendor/gems/omniauth-gitlab/Gemfile.lock @@ -2,7 +2,7 @@ PATH remote: . specs: omniauth-gitlab (4.0.0) - omniauth (~> 2.0) + omniauth (~> 1.0) omniauth-oauth2 (~> 1.7.1) GEM @@ -24,16 +24,13 @@ GEM rack (>= 1.2, < 3) rash_alt (>= 0.4, < 1) version_gem (~> 1.0) - omniauth (2.1.0) + omniauth (1.9.1) hashie (>= 3.4.6) - rack (>= 2.2.3) - rack-protection + rack (>= 1.6.2, < 3) omniauth-oauth2 (1.7.3) oauth2 (>= 1.4, < 3) omniauth (>= 1.9, < 3) - rack (2.2.4) - rack-protection (2.2.2) - rack + rack (2.2.3.1) rake (13.0.6) rash_alt (0.4.12) hashie (>= 3.4) diff --git a/vendor/gems/omniauth-gitlab/omniauth-gitlab.gemspec b/vendor/gems/omniauth-gitlab/omniauth-gitlab.gemspec index ca4b8d904f0..be25cb50af6 100644 --- a/vendor/gems/omniauth-gitlab/omniauth-gitlab.gemspec +++ b/vendor/gems/omniauth-gitlab/omniauth-gitlab.gemspec @@ -16,7 +16,7 @@ Gem::Specification.new do |gem| gem.test_files = Dir['spec/**/*.rb'] gem.require_paths = ['lib'] - gem.add_dependency 'omniauth', '~> 2.0' + gem.add_dependency 'omniauth', '~> 1.0' gem.add_dependency 'omniauth-oauth2', '~> 1.7.1' gem.add_development_dependency 'rspec', '~> 3.1' gem.add_development_dependency 'rspec-its', '~> 1.0' diff --git a/vendor/gems/omniauth-google-oauth2/CHANGELOG.md b/vendor/gems/omniauth-google-oauth2/CHANGELOG.md index 5b252048fd6..7d3e1234f2d 100644 --- a/vendor/gems/omniauth-google-oauth2/CHANGELOG.md +++ b/vendor/gems/omniauth-google-oauth2/CHANGELOG.md @@ -1,106 +1,6 @@ # Changelog All notable changes to this project will be documented in this file. -## 1.0.1 - 2022-03-10 - -### Added -- Output granted scopes in credentials block of the auth hash. -- Migrated to GitHub actions. - -### Deprecated -- Nothing. - -### Removed -- Nothing. - -### Fixed -- Overriding the `redirect_uri` via params or JSON request body. - -## 1.0.0 - 2021-03-14 - -### Added -- Support for Omniauth 2.x! - -### Deprecated -- Nothing. - -### Removed -- Support for Omniauth 1.x. - -### Fixed -- Nothing. - -## 0.8.2 - 2021-03-14 - -### Added -- Constrains the version to Omniauth 1.x. - -### Deprecated -- Nothing. - -### Removed -- Nothing. - -### Fixed -- Nothing. - -## 0.8.1 - 2020-12-12 - -### Added -- Support reading the access token from a json request body. - -### Deprecated -- Nothing. - -### Removed -- No longer verify the iat claim for JWT. - -### Fixed -- A few minor issues with .rubocop.yml. -- Issues with image resizing code when the image came with size information from Google. - -## 0.8.0 - 2019-08-21 - -### Added -- Updated omniauth-oauth2 to v1.6.0 for security fixes. - -### Deprecated -- Nothing. - -### Removed -- Ruby 2.1 support. - -### Fixed -- Nothing. - -## 0.7.0 - 2019-06-03 - -### Added -- Ensure `info[:email]` is always verified, and include `unverified_email` - -### Deprecated -- Nothing. - -### Removed -- Nothing. - -### Fixed -- Nothing. - -## 0.6.1 - 2019-03-07 - -### Added -- Return `email` and `email_verified` keys in response. - -### Deprecated -- Nothing. - -### Removed -- Nothing. - -### Fixed -- Nothing. - ## 0.6.0 - 2018-12-28 ### Added @@ -112,7 +12,6 @@ All notable changes to this project will be documented in this file. ### Removed - Support for JWT 1.x. - Support for `raw_friend_info` and `raw_image_info`. -- Stop using Google+ API endpoints. ### Fixed - Nothing. diff --git a/vendor/gems/omniauth-google-oauth2/Gemfile.lock b/vendor/gems/omniauth-google-oauth2/Gemfile.lock index 6c3f5ff3f68..a7f71e0a376 100644 --- a/vendor/gems/omniauth-google-oauth2/Gemfile.lock +++ b/vendor/gems/omniauth-google-oauth2/Gemfile.lock @@ -1,11 +1,10 @@ PATH remote: . specs: - omniauth-google-oauth2 (1.0.1) + omniauth-google-oauth2 (0.6.0) jwt (>= 2.0) - oauth2 (~> 2.0) - omniauth (~> 2.0) - omniauth-oauth2 (~> 1.7.1) + omniauth (>= 1.9, < 3) + omniauth-oauth2 (>= 1.5) GEM remote: https://rubygems.org/ @@ -26,10 +25,9 @@ GEM rack (>= 1.2, < 3) rash_alt (>= 0.4, < 1) version_gem (~> 1.0) - omniauth (2.1.0) + omniauth (1.9.2) hashie (>= 3.4.6) - rack (>= 2.2.3) - rack-protection + rack (>= 1.6.2, < 3) omniauth-oauth2 (1.7.3) oauth2 (>= 1.4, < 3) omniauth (>= 1.9, < 3) @@ -37,8 +35,6 @@ GEM parser (3.1.2.0) ast (~> 2.4.1) rack (2.2.4) - rack-protection (2.2.2) - rack rainbow (3.1.1) rake (12.3.3) rash_alt (0.4.12) diff --git a/vendor/gems/omniauth-google-oauth2/README.md b/vendor/gems/omniauth-google-oauth2/README.md index 80c611392ca..5d811693a60 100644 --- a/vendor/gems/omniauth-google-oauth2/README.md +++ b/vendor/gems/omniauth-google-oauth2/README.md @@ -1,4 +1,5 @@ [![Gem Version](https://badge.fury.io/rb/omniauth-google-oauth2.svg)](https://badge.fury.io/rb/omniauth-google-oauth2) +[![Build Status](https://travis-ci.org/zquestz/omniauth-google-oauth2.svg)](https://travis-ci.org/zquestz/omniauth-google-oauth2) # OmniAuth Google OAuth2 Strategy @@ -33,7 +34,6 @@ Here's an example for adding the middleware to a Rails app in `config/initialize Rails.application.config.middleware.use OmniAuth::Builder do provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'] end -OmniAuth.config.allowed_request_methods = %i[get] ``` You can now access the OmniAuth Google OAuth2 URL: `/auth/google_oauth2` @@ -54,10 +54,10 @@ You can configure several options, which you pass in to the `provider` method vi * `prompt`: A space-delimited list of string values that determines whether the user is re-prompted for authentication and/or consent. Possible values are: * `none`: No authentication or consent pages will be displayed; it will return an error if the user is not already authenticated and has not pre-configured consent for the requested scopes. This can be used as a method to check for existing authentication and/or consent. - * `consent`: The user will always be prompted for consent, even if they have previously allowed access a given set of scopes. + * `consent`: The user will always be prompted for consent, even if he has previously allowed access a given set of scopes. * `select_account`: The user will always be prompted to select a user account. This allows a user who has multiple current account sessions to select one amongst them. - If no value is specified, the user only sees the authentication page if they are not logged in and only sees the consent page the first time they authorize a given set of scopes. + If no value is specified, the user only sees the authentication page if he is not logged in and only sees the consent page the first time he authorizes a given set of scopes. * `image_aspect_ratio`: The shape of the user's profile picture. Possible values are: * `original`: Picture maintains its original aspect ratio. @@ -73,7 +73,7 @@ You can configure several options, which you pass in to the `provider` method vi * `hd`: (Optional) Limit sign-in to a particular Google Apps hosted domain. This can be simply string `'domain.com'` or an array `%w(domain.com domain.co)`. More information at: https://developers.google.com/accounts/docs/OpenIDConnect#hd-param -* `jwt_leeway`: Number of seconds passed to the JWT library as leeway. Defaults to 60 seconds. Note this only works if you use jwt 2.1, as the leeway option was removed in later versions. +* `jwt_leeway`: Number of seconds passed to the JWT library as leeway. Defaults to 60 seconds. * `skip_jwt`: Skip JWT processing. This is for users who are seeing JWT decoding errors with the `iat` field. Always try adjusting the leeway before disabling JWT processing. @@ -81,11 +81,9 @@ You can configure several options, which you pass in to the `provider` method vi * `include_granted_scopes`: If this is provided with the value true, and the authorization request is granted, the authorization will include any previous authorizations granted to this user/application combination for other scopes. See Google's [Incremental Authorization](https://developers.google.com/accounts/docs/OAuth2WebServer#incrementalAuth) for additional details. -* `openid_realm`: Set the OpenID realm value, to allow upgrading from OpenID based authentication to OAuth 2 based authentication. When this is set correctly an `openid_id` value will be set in `['extra']['id_info']` in the authentication hash with the value of the user's OpenID ID URL. +* `openid_realm`: Set the OpenID realm value, to allow upgrading from OpenID based authentication to OAuth 2 based authentication. When this is set correctly an `openid_id` value will be set in `[:extra][:id_info]` in the authentication hash with the value of the user's OpenID ID URL. -* `provider_ignores_state`: You will need to set this to `true` when using the `One-time Code Flow` below. In this flow there is no server side redirect that would set the state. - -Here's an example of a possible configuration where the strategy name is changed, the user is asked for extra permissions, the user is always prompted to select their account when logging in and the user's profile picture is returned as a thumbnail: +Here's an example of a possible configuration where the strategy name is changed, the user is asked for extra permissions, the user is always prompted to select his account when logging in and the user's profile picture is returned as a thumbnail: ```ruby Rails.application.config.middleware.use OmniAuth::Builder do @@ -178,8 +176,6 @@ devise :omniauthable, omniauth_providers: [:google_oauth2] Then make sure your callbacks controller is setup. ```ruby -# app/controllers/users/omniauth_callbacks_controller.rb: - class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController def google_oauth2 # You need to implement the method below in your model (e.g. app/models/user.rb) @@ -189,7 +185,7 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController flash[:notice] = I18n.t 'devise.omniauth_callbacks.success', kind: 'Google' sign_in_and_redirect @user, event: :authentication else - session['devise.google_data'] = request.env['omniauth.auth'].except('extra') # Removing extra as it can overflow some session stores + session['devise.google_data'] = request.env['omniauth.auth'].except(:extra) # Removing extra as it can overflow some session stores redirect_to new_user_registration_url, alert: @user.errors.full_messages.join("\n") end end @@ -217,10 +213,6 @@ end For your views you can login using: ```erb -<%# omniauth-google-oauth2 1.0.x uses OmniAuth 2 and requires using HTTP Post to initiate authentication: %> -<%= link_to "Sign in with Google", user_google_oauth2_omniauth_authorize_path, method: :post %> - -<%# omniauth-google-oauth2 prior 1.0.0: %> <%= link_to "Sign in with Google", user_google_oauth2_omniauth_authorize_path %> <%# Devise prior 4.1.0: %> @@ -231,7 +223,7 @@ An overview is available at https://github.com/plataformatec/devise/wiki/OmniAut ### One-time Code Flow (Hybrid Authentication) -Google describes the One-time Code Flow [here](https://developers.google.com/identity/sign-in/web/server-side-flow). This hybrid authentication flow has significant functional and security advantages over a pure server-side or pure client-side flow. The following steps occur in this flow: +Google describes the One-time Code Flow [here](https://developers.google.com/+/web/signin/server-side-flow). This hybrid authentication flow has significant functional and security advantages over a pure server-side or pure client-side flow. The following steps occur in this flow: 1. The client (web browser) authenticates the user directly via Google's JS API. During this process assorted modals may be rendered by Google. 2. On successful authentication, Google returns a one-time use code, which requires the Google client secret (which is only available server-side). @@ -240,7 +232,7 @@ Google describes the One-time Code Flow [here](https://developers.google.com/ide This flow is immune to replay attacks, and conveys no useful information to a man in the middle. -The omniauth-google-oauth2 gem supports this mode of operation when `provider_ignores_state` is set to `true`. Implementors simply need to add the appropriate JavaScript to their web page, and they can take advantage of this flow. An example JavaScript snippet follows. +The omniauth-google-oauth2 gem supports this mode of operation out of the box. Implementors simply need to add the appropriate JavaScript to their web page, and they can take advantage of this flow. An example JavaScript snippet follows. ```javascript // Basic hybrid auth example following the pattern at: @@ -255,7 +247,7 @@ function init() { // Ready. $('.google-login-button').click(function(e) { e.preventDefault(); - + gapi.auth2.authorize({ client_id: 'YOUR_CLIENT_ID', cookie_policy: 'single_host_origin', @@ -268,7 +260,7 @@ function init() { success: function(data) { // response from server } - }); + }); } else { // google authentication failed } @@ -288,66 +280,6 @@ In that case, ensure to send an additional parameter `redirect_uri=` (empty stri If you're making POST requests to `/auth/google_oauth2/callback` from another domain, then you need to make sure `'X-Requested-With': 'XMLHttpRequest'` header is included with your request, otherwise your server might respond with `OAuth2::Error, : Invalid Value` error. -#### Getting around the `redirect_uri_mismatch` error (See [Issue #365](https://github.com/zquestz/omniauth-google-oauth2/issues/365)) - -If you are struggling with a persistent `redirect_uri_mismatch`, you can instead pass the `access_token` from [`getAuthResponse`](https://developers.google.com/identity/sign-in/web/reference#googleusergetauthresponseincludeauthorizationdata) directly to the `auth/google_oauth2/callback` endpoint, like so: - -```javascript -// Initialize the GoogleAuth object -let googleAuth; -gapi.load('client:auth2', async () => { - await gapi.client.init({ scope: '...', client_id: '...' }); - googleAuth = gapi.auth2.getAuthInstance(); -}); - -// Call this when the Google Sign In button is clicked -async function signInGoogle() { - const googleUser = await googleAuth.signIn(); // wait for the user to authorize through the modal - const { access_token } = googleUser.getAuthResponse(); - - const data = new FormData(); - data.append('access_token', access_token); - - const response = await api.post('/auth/google_oauth2/callback', data) - console.log(response); -} -``` - -#### Using Axios -If you're making a GET resquests from another domain using `access_token`. -``` -axios - .get( - 'url(path to your callback}', - { params: { access_token: 'token' } }, - headers.... - ) -``` - -If you're making a POST resquests from another domain using `access_token`. -``` -axios - .post( - 'url(path to your callback}', - { access_token: 'token' }, - headers.... - ) - ---OR-- - -axios - .post( - 'url(path to your callback}', - null, - { - params: { - access_token: 'token' - }, - headers.... - } - ) -``` - ## Fixing Protocol Mismatch for `redirect_uri` in Rails Just set the `full_host` in OmniAuth based on the Rails.env. diff --git a/vendor/gems/omniauth-google-oauth2/examples/Gemfile b/vendor/gems/omniauth-google-oauth2/examples/Gemfile index ba019344a67..cd02ff9bf7d 100644 --- a/vendor/gems/omniauth-google-oauth2/examples/Gemfile +++ b/vendor/gems/omniauth-google-oauth2/examples/Gemfile @@ -2,7 +2,6 @@ source 'https://rubygems.org' -gem 'omniauth-google-oauth2', '~> 0.8.1' +gem 'omniauth-google-oauth2', '~> 0.5' gem 'rubocop' gem 'sinatra', '~> 1.4' -gem 'webrick' diff --git a/vendor/gems/omniauth-google-oauth2/examples/omni_auth.rb b/vendor/gems/omniauth-google-oauth2/examples/omni_auth.rb index 0a94164d766..127b62a9aaf 100644 --- a/vendor/gems/omniauth-google-oauth2/examples/omni_auth.rb +++ b/vendor/gems/omniauth-google-oauth2/examples/omni_auth.rb @@ -10,10 +10,6 @@ Rails.application.config.middleware.use OmniAuth::Builder do # provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], scope: 'email,profile' - # Custom redirect_uri - # - # provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], scope: 'email,profile', redirect_uri: 'https://localhost:3000/redirect' - # Manual setup for offline access with a refresh token. # # provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], access_type: 'offline' diff --git a/vendor/gems/omniauth-google-oauth2/lib/omniauth/google_oauth2/version.rb b/vendor/gems/omniauth-google-oauth2/lib/omniauth/google_oauth2/version.rb index 93ae5e9e990..565fb5d6642 100644 --- a/vendor/gems/omniauth-google-oauth2/lib/omniauth/google_oauth2/version.rb +++ b/vendor/gems/omniauth-google-oauth2/lib/omniauth/google_oauth2/version.rb @@ -2,6 +2,6 @@ module OmniAuth module GoogleOauth2 - VERSION = '1.0.1' + VERSION = '0.6.0' end end diff --git a/vendor/gems/omniauth-google-oauth2/lib/omniauth/strategies/google_oauth2.rb b/vendor/gems/omniauth-google-oauth2/lib/omniauth/strategies/google_oauth2.rb index 4ce32eb80d1..62e2d4462e5 100644 --- a/vendor/gems/omniauth-google-oauth2/lib/omniauth/strategies/google_oauth2.rb +++ b/vendor/gems/omniauth-google-oauth2/lib/omniauth/strategies/google_oauth2.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'jwt' -require 'oauth2' require 'omniauth/strategies/oauth2' require 'uri' @@ -14,7 +13,6 @@ module OmniAuth BASE_SCOPES = %w[profile email openid].freeze DEFAULT_SCOPE = 'email,profile' USER_INFO_URL = 'https://www.googleapis.com/oauth2/v3/userinfo' - IMAGE_SIZE_REGEXP = /(s\d+(-c)?)|(w\d+-h\d+(-c)?)|(w\d+(-c)?)|(h\d+(-c)?)|c/ option :name, 'google_oauth2' option :skip_friends, true @@ -49,8 +47,6 @@ module OmniAuth prune!( name: raw_info['name'], email: verified_email, - unverified_email: raw_info['email'], - email_verified: raw_info['email_verified'], first_name: raw_info['given_name'], last_name: raw_info['family_name'], image: image_url, @@ -60,11 +56,6 @@ module OmniAuth ) end - credentials do - # Tokens and expiration will be used from OAuth2 strategy credentials block - prune!({ 'scope' => token_info(access_token.token)['scope'] }) - end - extra do hash = {} hash[:id_token] = access_token['id_token'] @@ -81,7 +72,7 @@ module OmniAuth verify_sub: false, verify_expiration: true, verify_not_before: true, - verify_iat: false, + verify_iat: true, verify_jti: false, leeway: options[:jwt_leeway]) @@ -101,51 +92,31 @@ module OmniAuth verify_hd(access_token) access_token end - alias build_access_token custom_build_access_token private def callback_url - options[:redirect_uri] || (full_host + callback_path) + options[:redirect_uri] || (full_host + script_name + callback_path) end def get_access_token(request) - verifier = request.params['code'] - redirect_uri = request.params['redirect_uri'] - access_token = request.params['access_token'] - if verifier && request.xhr? - client_get_token(verifier, redirect_uri || 'postmessage') - elsif verifier - client_get_token(verifier, redirect_uri || callback_url) - elsif access_token && verify_token(access_token) + if request.xhr? && request.params['code'] + verifier = request.params['code'] + redirect_uri = request.params['redirect_uri'] || 'postmessage' + client.auth_code.get_token(verifier, get_token_options(redirect_uri), deep_symbolize(options.auth_token_params || {})) + elsif request.params['code'] && request.params['redirect_uri'] + verifier = request.params['code'] + redirect_uri = request.params['redirect_uri'] + client.auth_code.get_token(verifier, get_token_options(redirect_uri), deep_symbolize(options.auth_token_params || {})) + elsif verify_token(request.params['access_token']) ::OAuth2::AccessToken.from_hash(client, request.params.dup) - elsif request.content_type =~ /json/i - begin - body = JSON.parse(request.body.read) - request.body.rewind # rewind request body for downstream middlewares - verifier = body && body['code'] - access_token = body && body['access_token'] - redirect_uri ||= body && body['redirect_uri'] - if verifier - client_get_token(verifier, redirect_uri || 'postmessage') - elsif verify_token(access_token) - ::OAuth2::AccessToken.from_hash(client, body.dup) - end - rescue JSON::ParserError => e - warn "[omniauth google-oauth2] JSON parse error=#{e}" - end + else + verifier = request.params['code'] + client.auth_code.get_token(verifier, get_token_options(callback_url), deep_symbolize(options.auth_token_params)) end end - def client_get_token(verifier, redirect_uri) - client.auth_code.get_token(verifier, get_token_options(redirect_uri), get_token_params) - end - - def get_token_params - deep_symbolize(options.auth_token_params || {}) - end - def get_scope(params) raw_scope = params[:scope] || DEFAULT_SCOPE scope_list = raw_scope.split(' ').map { |item| item.split(',') }.flatten @@ -153,11 +124,7 @@ module OmniAuth scope_list.join(' ') end - def verified_email - raw_info['email_verified'] ? raw_info['email'] : nil - end - - def get_token_options(redirect_uri = '') + def get_token_options(redirect_uri) { redirect_uri: redirect_uri }.merge(token_params.to_hash(symbolize_keys: true)) end @@ -168,6 +135,10 @@ module OmniAuth end end + def verified_email + raw_info['email_verified'] ? raw_info['email'] : nil + end + def image_url return nil unless raw_info['picture'] @@ -178,10 +149,6 @@ module OmniAuth if path_index && image_size_opts_passed? u.path.insert(path_index, image_params) u.path = u.path.gsub('//', '/') - - # Check if the image is already sized! - split_path = u.path.split('/') - u.path = u.path.sub("/#{split_path[-3]}", '') if split_path[-3] =~ IMAGE_SIZE_REGEXP end u.query = strip_unnecessary_query_parameters(u.query) @@ -220,21 +187,12 @@ module OmniAuth URI.encode_www_form(stripped_params) end - def token_info(access_token) - return nil unless access_token - - @token_info ||= Hash.new do |h, k| - h[k] = client.request(:get, 'https://www.googleapis.com/oauth2/v3/tokeninfo', params: { access_token: access_token }).parsed - end - - @token_info[access_token] - end - def verify_token(access_token) return false unless access_token - token_info = token_info(access_token) - token_info['aud'] == options.client_id || options.authorized_client_ids.include?(token_info['aud']) + raw_response = client.request(:get, 'https://www.googleapis.com/oauth2/v3/tokeninfo', + params: { access_token: access_token }).parsed + raw_response['aud'] == options.client_id || options.authorized_client_ids.include?(raw_response['aud']) end def verify_hd(access_token) diff --git a/vendor/gems/omniauth-google-oauth2/omniauth-google-oauth2.gemspec b/vendor/gems/omniauth-google-oauth2/omniauth-google-oauth2.gemspec index a50d67bc9a0..fb66d7ee282 100644 --- a/vendor/gems/omniauth-google-oauth2/omniauth-google-oauth2.gemspec +++ b/vendor/gems/omniauth-google-oauth2/omniauth-google-oauth2.gemspec @@ -15,15 +15,14 @@ Gem::Specification.new do |gem| gem.email = ['quest@mac.com'] gem.homepage = 'https://github.com/zquestz/omniauth-google-oauth2' - gem.files = Dir.glob("lib/**/*.*") + gem.files = Dir.glob("lib/**/*.*") gem.require_paths = ['lib'] - gem.required_ruby_version = '>= 2.2' + gem.required_ruby_version = '>= 2.1' gem.add_runtime_dependency 'jwt', '>= 2.0' - gem.add_runtime_dependency 'oauth2', '~> 2.0' - gem.add_runtime_dependency 'omniauth', '~> 2.0' - gem.add_runtime_dependency 'omniauth-oauth2', '~> 1.7.1' + gem.add_runtime_dependency 'omniauth', '>= 1.9', '< 3' + gem.add_runtime_dependency 'omniauth-oauth2', '>= 1.5' gem.add_development_dependency 'rake', '~> 12.0' gem.add_development_dependency 'rspec', '~> 3.6' diff --git a/vendor/gems/omniauth-google-oauth2/spec/omniauth/strategies/google_oauth2_spec.rb b/vendor/gems/omniauth-google-oauth2/spec/omniauth/strategies/google_oauth2_spec.rb index 3a2bcf07e54..6bc6f6d9e95 100644 --- a/vendor/gems/omniauth-google-oauth2/spec/omniauth/strategies/google_oauth2_spec.rb +++ b/vendor/gems/omniauth-google-oauth2/spec/omniauth/strategies/google_oauth2_spec.rb @@ -3,7 +3,6 @@ require 'spec_helper' require 'json' require 'omniauth-google-oauth2' -require 'stringio' describe OmniAuth::Strategies::GoogleOauth2 do let(:request) { double('Request', params: {}, cookies: {}, env: {}) } @@ -178,8 +177,8 @@ describe OmniAuth::Strategies::GoogleOauth2 do describe 'scope' do it 'should expand scope shortcuts' do - @options = { scope: 'calendar' } - expect(subject.authorize_params['scope']).to eq('https://www.googleapis.com/auth/calendar') + @options = { scope: 'plus.me' } + expect(subject.authorize_params['scope']).to eq('https://www.googleapis.com/auth/plus.me') end it 'should leave base scopes as is' do @@ -289,92 +288,14 @@ describe OmniAuth::Strategies::GoogleOauth2 do end end - describe '#callback_url' do - let(:base_url) { 'https://example.com' } - + describe '#callback_path' do it 'has the correct default callback path' do - allow(subject).to receive(:full_host) { base_url } - allow(subject).to receive(:script_name) { '' } - expect(subject.send(:callback_url)).to eq(base_url + '/auth/google_oauth2/callback') - end - - it 'should set the callback path with script_name if present' do - allow(subject).to receive(:full_host) { base_url } - allow(subject).to receive(:script_name) { '/v1' } - expect(subject.send(:callback_url)).to eq(base_url + '/v1/auth/google_oauth2/callback') + expect(subject.callback_path).to eq('/auth/google_oauth2/callback') end it 'should set the callback_path parameter if present' do @options = { callback_path: '/auth/foo/callback' } - allow(subject).to receive(:full_host) { base_url } - allow(subject).to receive(:script_name) { '' } - expect(subject.send(:callback_url)).to eq(base_url + '/auth/foo/callback') - end - end - - describe '#info' do - let(:client) do - OAuth2::Client.new('abc', 'def') do |builder| - builder.request :url_encoded - builder.adapter :test do |stub| - stub.get('/oauth2/v3/userinfo') { [200, { 'content-type' => 'application/json' }, response_hash.to_json] } - end - end - end - let(:access_token) { OAuth2::AccessToken.from_hash(client, {}) } - before { allow(subject).to receive(:access_token).and_return(access_token) } - - context 'with verified email' do - let(:response_hash) do - { email: 'something@domain.invalid', email_verified: true } - end - - it 'should return equal email and unverified_email' do - expect(subject.info[:email]).to eq('something@domain.invalid') - expect(subject.info[:unverified_email]).to eq('something@domain.invalid') - end - end - - context 'with unverified email' do - let(:response_hash) do - { email: 'something@domain.invalid', email_verified: false } - end - - it 'should return nil email, and correct unverified email' do - expect(subject.info[:email]).to eq(nil) - expect(subject.info[:unverified_email]).to eq('something@domain.invalid') - end - end - end - - describe '#credentials' do - let(:client) { OAuth2::Client.new('abc', 'def') } - let(:access_token) { OAuth2::AccessToken.from_hash(client, access_token: 'valid_access_token', expires_at: 123_456_789, refresh_token: 'valid_refresh_token') } - before(:each) do - allow(subject).to receive(:access_token).and_return(access_token) - subject.options.client_options[:connection_build] = proc do |builder| - builder.request :url_encoded - builder.adapter :test do |stub| - stub.get('/oauth2/v3/tokeninfo?access_token=valid_access_token') do - [200, { 'Content-Type' => 'application/json; charset=UTF-8' }, JSON.dump( - aud: '000000000000.apps.googleusercontent.com', - sub: '123456789', - scope: 'profile email' - )] - end - end - end - end - - it 'should return access token and (optionally) refresh token' do - expect(subject.credentials.to_h).to \ - match(hash_including( - 'token' => 'valid_access_token', - 'refresh_token' => 'valid_refresh_token', - 'scope' => 'profile email', - 'expires_at' => 123_456_789, - 'expires' => true - )) + expect(subject.callback_path).to eq('/auth/foo/callback') end end @@ -392,7 +313,7 @@ describe OmniAuth::Strategies::GoogleOauth2 do before { allow(subject).to receive(:access_token).and_return(access_token) } describe 'id_token' do - shared_examples 'id_token issued by valid issuer' do |issuer| + shared_examples 'id_token issued by valid issuer' do |issuer| # rubocop:disable Metrics/BlockLength context 'when the id_token is passed into the access token' do let(:token_info) do { @@ -505,12 +426,6 @@ describe OmniAuth::Strategies::GoogleOauth2 do expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/s50/photo.jpg') end - it 'should return the image with size specified in the `image_size` option when sizing is in the picture' do - @options = { image_size: 50 } - allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh4.googleusercontent.com/url/s96-c/photo.jpg' } } - expect(subject.info[:image]).to eq('https://lh4.googleusercontent.com/url/s50/photo.jpg') - end - it 'should handle a picture with too many slashes correctly' do @options = { image_size: 50 } allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url//photo.jpg' } } @@ -541,48 +456,24 @@ describe OmniAuth::Strategies::GoogleOauth2 do expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/w50-h40/photo.jpg') end - it 'should return the image with width and height specified in the `image_size` option when sizing is in the picture' do - @options = { image_size: { width: 50, height: 40 } } - allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/w100-h80-c/photo.jpg' } } - expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/w50-h40/photo.jpg') - end - it 'should return square image when `image_aspect_ratio` is specified' do @options = { image_aspect_ratio: 'square' } allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg' } } expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/c/photo.jpg') end - it 'should return square image when `image_aspect_ratio` is specified and sizing is in the picture' do - @options = { image_aspect_ratio: 'square' } - allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/c/photo.jpg' } } - expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/c/photo.jpg') - end - it 'should return square sized image when `image_aspect_ratio` and `image_size` is set' do @options = { image_aspect_ratio: 'square', image_size: 50 } allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg' } } expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/s50-c/photo.jpg') end - it 'should return square sized image when `image_aspect_ratio` and `image_size` is set and sizing is in the picture' do - @options = { image_aspect_ratio: 'square', image_size: 50 } - allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/s90/photo.jpg' } } - expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/s50-c/photo.jpg') - end - it 'should return square sized image when `image_aspect_ratio` and `image_size` has height and width' do @options = { image_aspect_ratio: 'square', image_size: { width: 50, height: 40 } } allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photo.jpg' } } expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/w50-h40-c/photo.jpg') end - it 'should return square sized image when `image_aspect_ratio` and `image_size` has height and width and sizing is in the picture' do - @options = { image_aspect_ratio: 'square', image_size: { width: 50, height: 40 } } - allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/w100-h80/photo.jpg' } } - expect(subject.info[:image]).to eq('https://lh3.googleusercontent.com/url/w50-h40-c/photo.jpg') - end - it 'should return original image if image url does not end in `photo.jpg`' do @options = { image_size: 50 } allow(subject).to receive(:raw_info) { { 'picture' => 'https://lh3.googleusercontent.com/url/photograph.jpg' } } @@ -656,58 +547,9 @@ describe OmniAuth::Strategies::GoogleOauth2 do expect(token.client).to eq(:client) end - it 'reads the code from a json request body' do - body = StringIO.new(%({"code":"json_access_token"})) - client = double(:client) - auth_code = double(:auth_code) - - allow(request).to receive(:xhr?).and_return(false) - allow(request).to receive(:content_type).and_return('application/json') - allow(request).to receive(:body).and_return(body) - allow(client).to receive(:auth_code).and_return(auth_code) - expect(subject).to receive(:client).and_return(client) - - expect(auth_code).to receive(:get_token).with('json_access_token', { redirect_uri: 'postmessage' }, {}) - - subject.build_access_token - end - - it 'reads the redirect uri from a json request body' do - body = StringIO.new(%({"code":"json_access_token", "redirect_uri":"sample"})) - client = double(:client) - auth_code = double(:auth_code) - - allow(request).to receive(:xhr?).and_return(false) - allow(request).to receive(:content_type).and_return('application/json') - allow(request).to receive(:body).and_return(body) - allow(client).to receive(:auth_code).and_return(auth_code) - expect(subject).to receive(:client).and_return(client) - - expect(auth_code).to receive(:get_token).with('json_access_token', { redirect_uri: 'sample' }, {}) - - subject.build_access_token - end - - it 'reads the access token from a json request body' do - body = StringIO.new(%({"access_token":"valid_access_token"})) - - allow(request).to receive(:xhr?).and_return(false) - allow(request).to receive(:content_type).and_return('application/json') - allow(request).to receive(:body).and_return(body) - expect(subject).to receive(:client).and_return(:client) - - expect(subject).to receive(:verify_token).with('valid_access_token').and_return true - - token = subject.build_access_token - expect(token).to be_instance_of(::OAuth2::AccessToken) - expect(token.token).to eq('valid_access_token') - expect(token.client).to eq(:client) - end - it 'should use callback_url without query_string if this is not an AJAX request' do allow(request).to receive(:xhr?).and_return(false) allow(request).to receive(:params).and_return('code' => 'valid_code') - allow(request).to receive(:content_type).and_return('application/x-www-form-urlencoded') client = double(:client) auth_code = double(:auth_code) diff --git a/vendor/gems/omniauth-salesforce/Gemfile.lock b/vendor/gems/omniauth-salesforce/Gemfile.lock index 0317b16dd9f..0eb983bcd76 100644 --- a/vendor/gems/omniauth-salesforce/Gemfile.lock +++ b/vendor/gems/omniauth-salesforce/Gemfile.lock @@ -2,7 +2,7 @@ PATH remote: . specs: omniauth-salesforce (1.0.5) - omniauth (~> 2.0) + omniauth (~> 1.0, < 3) omniauth-oauth2 (~> 1.0) GEM @@ -53,17 +53,16 @@ GEM notiffany (0.1.3) nenv (~> 0.1) shellany (~> 0.0) - oauth2 (2.0.3) + oauth2 (2.0.7) faraday (>= 0.17.3, < 3.0) jwt (>= 1.0, < 3.0) multi_xml (~> 0.5) rack (>= 1.2, < 3) rash_alt (>= 0.4, < 1) - version_gem (~> 1.0) - omniauth (2.1.0) + version_gem (~> 1.1) + omniauth (1.9.2) hashie (>= 3.4.6) - rack (>= 2.2.3) - rack-protection + rack (>= 1.6.2, < 3) omniauth-oauth2 (1.7.3) oauth2 (>= 1.4, < 3) omniauth (>= 1.9, < 3) @@ -72,8 +71,6 @@ GEM method_source (~> 1.0) public_suffix (5.0.0) rack (2.2.4) - rack-protection (2.2.2) - rack rack-test (2.0.2) rack (>= 1.3) rash_alt (0.4.12) @@ -121,4 +118,4 @@ DEPENDENCIES webmock BUNDLED WITH - 2.3.21 + 2.3.20 diff --git a/vendor/gems/omniauth-salesforce/omniauth-salesforce.gemspec b/vendor/gems/omniauth-salesforce/omniauth-salesforce.gemspec index 9c87746e9fd..0b9cfbd73ff 100755 --- a/vendor/gems/omniauth-salesforce/omniauth-salesforce.gemspec +++ b/vendor/gems/omniauth-salesforce/omniauth-salesforce.gemspec @@ -15,7 +15,7 @@ Gem::Specification.new do |gem| gem.version = OmniAuth::Salesforce::VERSION gem.license = "MIT" - gem.add_dependency 'omniauth', '~> 2.0' + gem.add_dependency 'omniauth', '~> 1.0', '< 3' gem.add_dependency 'omniauth-oauth2', '~> 1.0' gem.add_development_dependency 'rspec', '~> 2.7' gem.add_development_dependency 'rack-test' diff --git a/vendor/gems/omniauth_crowd/Gemfile.lock b/vendor/gems/omniauth_crowd/Gemfile.lock index 43518582535..56c9bd4cc7e 100644 --- a/vendor/gems/omniauth_crowd/Gemfile.lock +++ b/vendor/gems/omniauth_crowd/Gemfile.lock @@ -4,7 +4,7 @@ PATH omniauth_crowd (2.4.0) activesupport nokogiri (>= 1.4.4) - omniauth (~> 2.0) + omniauth (~> 1.0, < 3) GEM remote: http://rubygems.org/ @@ -29,15 +29,12 @@ GEM nokogiri (1.13.8) mini_portile2 (~> 2.8.0) racc (~> 1.4) - omniauth (2.1.0) + omniauth (1.9.1) hashie (>= 3.4.6) - rack (>= 2.2.3) - rack-protection + rack (>= 1.6.2, < 3) public_suffix (4.0.7) racc (1.6.0) rack (2.2.4) - rack-protection (2.2.2) - rack rack-test (2.0.2) rack (>= 1.3) rake (13.0.6) diff --git a/vendor/gems/omniauth_crowd/omniauth_crowd.gemspec b/vendor/gems/omniauth_crowd/omniauth_crowd.gemspec index dcbf403419f..1707c7f3f10 100644 --- a/vendor/gems/omniauth_crowd/omniauth_crowd.gemspec +++ b/vendor/gems/omniauth_crowd/omniauth_crowd.gemspec @@ -15,7 +15,7 @@ Gem::Specification.new do |gem| gem.require_paths = ["lib"] gem.version = OmniAuth::Crowd::VERSION - gem.add_runtime_dependency 'omniauth', '~> 2.0' + gem.add_runtime_dependency 'omniauth', '~> 1.0', '< 3' gem.add_runtime_dependency 'nokogiri', '>= 1.4.4' gem.add_runtime_dependency 'activesupport', '>= 0' gem.add_development_dependency(%q<rack>, [">= 0"]) |