summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-02-17 09:15:27 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-02-17 09:15:27 +0000
commit5e11fc146aba1344ad95f7fea1a99db82f0f68f2 (patch)
treeac1a69dc17cdd896fa9d8a74f2a71da97b0f88a2
parent731490c15097b022a17bfbd55d6b183e57dc994f (diff)
downloadgitlab-ce-5e11fc146aba1344ad95f7fea1a99db82f0f68f2.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--app/controllers/concerns/bizible_csp.rb15
-rw-r--r--app/controllers/projects/badges_controller.rb12
-rw-r--r--app/controllers/projects/settings/ci_cd_controller.rb2
-rw-r--r--app/controllers/registrations_controller.rb1
-rw-r--r--app/controllers/sessions_controller.rb1
-rw-r--r--app/graphql/mutations/concerns/mutations/can_mutate_spammable.rb51
-rw-r--r--app/graphql/mutations/snippets/create.rb1
-rw-r--r--app/graphql/mutations/snippets/update.rb1
-rw-r--r--app/helpers/bizible_helper.rb10
-rw-r--r--app/views/devise/confirmations/almost_there.haml1
-rw-r--r--app/views/devise/registrations/new.html.haml1
-rw-r--r--app/views/devise/sessions/new.html.haml1
-rw-r--r--app/views/layouts/_bizible.html.haml14
-rw-r--r--app/views/registrations/welcome/show.html.haml1
-rw-r--r--app/views/users/terms/index.html.haml1
-rw-r--r--config/gitlab.yml.example3
-rw-r--r--config/routes/project.rb8
-rw-r--r--data/deprecations/14-8-deprecate-projectFingerprint-from-PipelineSecurityReportFinding-GraphQL.yml19
-rw-r--r--data/deprecations/data/deprecations/14-9-secure-and-protect-analyzer-bump.yml.yml44
-rw-r--r--doc/api/graphql/reference/index.md12
-rw-r--r--doc/update/deprecations.md57
-rw-r--r--doc/user/application_security/configuration/index.md2
-rw-r--r--doc/user/compliance/license_compliance/index.md75
-rw-r--r--lib/gitlab/ci/badge/release/latest_release.rb42
-rw-r--r--lib/gitlab/ci/badge/release/metadata.rb25
-rw-r--r--lib/gitlab/ci/badge/release/template.rb44
-rw-r--r--lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml17
-rw-r--r--spec/controllers/projects/badges_controller_spec.rb168
-rw-r--r--spec/features/users/bizible_csp_spec.rb15
-rw-r--r--spec/helpers/bizible_helper_spec.rb47
-rw-r--r--spec/lib/gitlab/ci/badge/release/latest_release_spec.rb42
-rw-r--r--spec/lib/gitlab/ci/badge/release/metadata_spec.rb40
-rw-r--r--spec/lib/gitlab/ci/badge/release/template_spec.rb90
-rw-r--r--spec/support/shared_examples/graphql/mutations/can_mutate_spammable_examples.rb13
35 files changed, 672 insertions, 206 deletions
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 29f6628ae55..d3830b56098 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-5d557a52c40e2641d6ea1b44b60a897d0e9401e7
+4ac6a5906d27098bf0f6fb9e19c190ea9722c70a
diff --git a/app/controllers/concerns/bizible_csp.rb b/app/controllers/concerns/bizible_csp.rb
new file mode 100644
index 00000000000..521f3127759
--- /dev/null
+++ b/app/controllers/concerns/bizible_csp.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module BizibleCSP
+ extend ActiveSupport::Concern
+
+ included do
+ content_security_policy do |policy|
+ next unless helpers.bizible_enabled? || policy.directives.present?
+
+ default_script_src = policy.directives['script-src'] || policy.directives['default-src']
+ script_src_values = Array.wrap(default_script_src) | ["'unsafe-eval'", 'https://cdn.bizible.com/scripts/bizible.js']
+ policy.script_src(*script_src_values)
+ end
+ end
+end
diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb
index 8023e51b552..42bd87e1c01 100644
--- a/app/controllers/projects/badges_controller.rb
+++ b/app/controllers/projects/badges_controller.rb
@@ -8,6 +8,7 @@ class Projects::BadgesController < Projects::ApplicationController
feature_category :continuous_integration, [:index, :pipeline]
feature_category :code_testing, [:coverage]
+ feature_category :release_orchestration, [:release]
def pipeline
pipeline_status = Gitlab::Ci::Badge::Pipeline::Status
@@ -34,6 +35,17 @@ class Projects::BadgesController < Projects::ApplicationController
render_badge coverage_report
end
+ def release
+ latest_release = Gitlab::Ci::Badge::Release::LatestRelease
+ .new(project, current_user, opts: {
+ key_text: params[:key_text],
+ key_width: params[:key_width],
+ order_by: params[:order_by]
+ })
+
+ render_badge latest_release
+ end
+
private
def badge_layout
diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb
index c71134e0547..dd2fb57f7ac 100644
--- a/app/controllers/projects/settings/ci_cd_controller.rb
+++ b/app/controllers/projects/settings/ci_cd_controller.rb
@@ -160,6 +160,8 @@ module Projects
@badges.map! do |badge|
badge.new(@project, @ref).metadata
end
+
+ @badges.append(Gitlab::Ci::Badge::Release::LatestRelease.new(@project, current_user).metadata)
end
def define_auto_devops_variables
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index 7b688c0ccc2..057c451ace2 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -6,6 +6,7 @@ class RegistrationsController < Devise::RegistrationsController
include RecaptchaHelper
include InvisibleCaptchaOnSignup
include OneTrustCSP
+ include BizibleCSP
layout 'devise'
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 7e8e3ea8789..e907e291eeb 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -10,6 +10,7 @@ class SessionsController < Devise::SessionsController
include KnownSignIn
include Gitlab::Utils::StrongMemoize
include OneTrustCSP
+ include BizibleCSP
skip_before_action :check_two_factor_requirement, only: [:destroy]
skip_before_action :check_password_expiration, only: [:destroy]
diff --git a/app/graphql/mutations/concerns/mutations/can_mutate_spammable.rb b/app/graphql/mutations/concerns/mutations/can_mutate_spammable.rb
deleted file mode 100644
index f1ae54aa014..00000000000
--- a/app/graphql/mutations/concerns/mutations/can_mutate_spammable.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# frozen_string_literal: true
-
-module Mutations
- # This concern is deprecated and will be deleted in 14.6
- #
- # Use the SpamProtection concern instead.
- module CanMutateSpammable
- extend ActiveSupport::Concern
-
- DEPRECATION_NOTICE = {
- reason: 'Use spam protection with HTTP headers instead',
- milestone: '13.11'
- }.freeze
-
- included do
- argument :captcha_response, GraphQL::Types::String,
- required: false,
- deprecated: DEPRECATION_NOTICE,
- description: 'Valid CAPTCHA response value obtained by using the provided captchaSiteKey with a CAPTCHA API to present a challenge to be solved on the client. Required to resubmit if the previous operation returned "NeedsCaptchaResponse: true".'
-
- argument :spam_log_id, GraphQL::Types::Int,
- required: false,
- deprecated: DEPRECATION_NOTICE,
- description: 'Spam log ID which must be passed along with a valid CAPTCHA response for the operation to be completed. Required to resubmit if the previous operation returned "NeedsCaptchaResponse: true".'
-
- field :spam,
- GraphQL::Types::Boolean,
- null: true,
- deprecated: DEPRECATION_NOTICE,
- description: 'Indicates whether the operation was detected as definite spam. There is no option to resubmit the request with a CAPTCHA response.'
-
- field :needs_captcha_response,
- GraphQL::Types::Boolean,
- null: true,
- deprecated: DEPRECATION_NOTICE,
- description: 'Indicates whether the operation was detected as possible spam and not completed. If CAPTCHA is enabled, the request must be resubmitted with a valid CAPTCHA response and spam_log_id included for the operation to be completed. Included only when an operation was not completed because "NeedsCaptchaResponse" is true.'
-
- field :spam_log_id,
- GraphQL::Types::Int,
- null: true,
- deprecated: DEPRECATION_NOTICE,
- description: 'Spam log ID which must be passed along with a valid CAPTCHA response for an operation to be completed. Included only when an operation was not completed because "NeedsCaptchaResponse" is true.'
-
- field :captcha_site_key,
- GraphQL::Types::String,
- null: true,
- deprecated: DEPRECATION_NOTICE,
- description: 'CAPTCHA site key which must be used to render a challenge for the user to solve to obtain a valid captchaResponse value. Included only when an operation was not completed because "NeedsCaptchaResponse" is true.'
- end
- end
-end
diff --git a/app/graphql/mutations/snippets/create.rb b/app/graphql/mutations/snippets/create.rb
index 850e05b52c1..2921a77b86d 100644
--- a/app/graphql/mutations/snippets/create.rb
+++ b/app/graphql/mutations/snippets/create.rb
@@ -6,7 +6,6 @@ module Mutations
graphql_name 'CreateSnippet'
include ServiceCompatibility
- include CanMutateSpammable
include Mutations::SpamProtection
authorize :create_snippet
diff --git a/app/graphql/mutations/snippets/update.rb b/app/graphql/mutations/snippets/update.rb
index aa0fa5d5330..2a2941c5328 100644
--- a/app/graphql/mutations/snippets/update.rb
+++ b/app/graphql/mutations/snippets/update.rb
@@ -6,7 +6,6 @@ module Mutations
graphql_name 'UpdateSnippet'
include ServiceCompatibility
- include CanMutateSpammable
include Mutations::SpamProtection
argument :id, ::Types::GlobalIDType[::Snippet],
diff --git a/app/helpers/bizible_helper.rb b/app/helpers/bizible_helper.rb
new file mode 100644
index 00000000000..970cc6558da
--- /dev/null
+++ b/app/helpers/bizible_helper.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+module BizibleHelper
+ def bizible_enabled?
+ Feature.enabled?(:ecomm_instrumentation, type: :ops) &&
+ Gitlab.config.extra.has_key?('bizible') &&
+ Gitlab.config.extra.bizible.present? &&
+ Gitlab.config.extra.bizible == true
+ end
+end
diff --git a/app/views/devise/confirmations/almost_there.haml b/app/views/devise/confirmations/almost_there.haml
index 1d46a43e5bd..ef19ac33a15 100644
--- a/app/views/devise/confirmations/almost_there.haml
+++ b/app/views/devise/confirmations/almost_there.haml
@@ -4,6 +4,7 @@
- content_for :page_specific_javascripts do
= render "layouts/google_tag_manager_head"
= render "layouts/one_trust"
+ = render "layouts/bizible"
= render "layouts/google_tag_manager_body"
.well-confirmation.gl-text-center.gl-mb-6
diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml
index 87108c8ea78..60c3df718a1 100644
--- a/app/views/devise/registrations/new.html.haml
+++ b/app/views/devise/registrations/new.html.haml
@@ -3,6 +3,7 @@
- content_for :page_specific_javascripts do
= render "layouts/google_tag_manager_head"
= render "layouts/one_trust"
+ = render "layouts/bizible"
= render "layouts/google_tag_manager_body"
.signup-page
diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml
index 175b45dbbfa..c669f3efec6 100644
--- a/app/views/devise/sessions/new.html.haml
+++ b/app/views/devise/sessions/new.html.haml
@@ -1,6 +1,7 @@
- page_title _("Sign in")
- content_for :page_specific_javascripts do
= render "layouts/one_trust"
+ = render "layouts/bizible"
#signin-container
- if any_form_based_providers_enabled?
diff --git a/app/views/layouts/_bizible.html.haml b/app/views/layouts/_bizible.html.haml
new file mode 100644
index 00000000000..a2b28c138e5
--- /dev/null
+++ b/app/views/layouts/_bizible.html.haml
@@ -0,0 +1,14 @@
+- if bizible_enabled?
+ <!-- Bizible -->
+ = javascript_include_tag "https://cdn.bizible.com/scripts/bizible.js"
+ = javascript_tag nonce: content_security_policy_nonce do
+ :plain
+ const bizibleScript = document.createElement('script');
+ bizibleScript.src = 'https://cdn.bizible.com/scripts/bizible.js';
+ bizibleScript.nonce = '#{content_security_policy_nonce}'
+ bizibleScript.charset = 'UTF-8';
+ bizibleScript.defer = true;
+ document.head.appendChild(bizibleScript);
+
+ function OptanonWrapper() { }
+
diff --git a/app/views/registrations/welcome/show.html.haml b/app/views/registrations/welcome/show.html.haml
index ca2f225a2d8..44dffdbf70a 100644
--- a/app/views/registrations/welcome/show.html.haml
+++ b/app/views/registrations/welcome/show.html.haml
@@ -5,6 +5,7 @@
- content_for :page_specific_javascripts do
= render "layouts/google_tag_manager_head"
= render "layouts/one_trust"
+ = render "layouts/bizible"
= render "layouts/google_tag_manager_body"
.row.gl-flex-grow-1
diff --git a/app/views/users/terms/index.html.haml b/app/views/users/terms/index.html.haml
index c461250fc9b..afe257c2fc2 100644
--- a/app/views/users/terms/index.html.haml
+++ b/app/views/users/terms/index.html.haml
@@ -1,6 +1,7 @@
- content_for :page_specific_javascripts do
= render "layouts/google_tag_manager_head"
= render "layouts/one_trust"
+ = render "layouts/bizible"
= render "layouts/google_tag_manager_body"
#js-terms-of-service{ data: { terms_data: terms_data(@term, @redirect) } }
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index bcb34548f81..6758afc91c4 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -1332,6 +1332,9 @@ production: &base
## OneTrust
# one_trust_id: '_your_one_trust_id'
+ ## Bizible.
+ # bizible: true
+
## Matomo analytics.
# matomo_url: '_your_matomo_url'
# matomo_site_id: '_your_matomo_site_id'
diff --git a/config/routes/project.rb b/config/routes/project.rb
index e05033587df..8536ec9fc05 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -467,6 +467,14 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end
get :planning_hierarchy
+
+ resources :badges, only: [] do
+ collection do
+ constraints format: /svg/ do
+ get :release
+ end
+ end
+ end
end
# End of the /-/ scope.
diff --git a/data/deprecations/14-8-deprecate-projectFingerprint-from-PipelineSecurityReportFinding-GraphQL.yml b/data/deprecations/14-8-deprecate-projectFingerprint-from-PipelineSecurityReportFinding-GraphQL.yml
new file mode 100644
index 00000000000..ea75e70afe3
--- /dev/null
+++ b/data/deprecations/14-8-deprecate-projectFingerprint-from-PipelineSecurityReportFinding-GraphQL.yml
@@ -0,0 +1,19 @@
+- name: "`projectFingerprint` in `PipelineSecurityReportFinding` GraphQL" # The name of the feature to be deprecated
+ announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ breaking_change: true # If this deprecation is a breaking change, set this value to true
+ reporter: matt_wilson # GitLab username of the person reporting the deprecation
+ body: | # Do not modify this line, instead modify the lines below.
+ The `projectFingerprint` field in the [PipelineSecurityReportFinding](https://docs.gitlab.com/ee/api/graphql/reference/index.html#pipelinesecurityreportfinding)
+ GraphQL object is being deprecated. This field contains a "fingerprint" of security findings used to determine uniqueness.
+ The method for calculating fingerprints has changed, resulting in different values. Going forward, the new values will be
+ exposed in the UUID field. Data previously available in the projectFingerprint field will eventually be removed entirely.
+# The following items are not published on the docs page, but may be used in the future.
+ stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/data/deprecations/14-9-secure-and-protect-analyzer-bump.yml.yml b/data/deprecations/data/deprecations/14-9-secure-and-protect-analyzer-bump.yml.yml
new file mode 100644
index 00000000000..8f1d030f47c
--- /dev/null
+++ b/data/deprecations/data/deprecations/14-9-secure-and-protect-analyzer-bump.yml.yml
@@ -0,0 +1,44 @@
+- name: "Secure and Protect analyzer major version update" # The name of the feature to be deprecated
+ announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.00" # The milestone when this feature is planned to be removed
+ removal_date: # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ breaking_change: true # If this deprecation is a breaking change, set this value to true
+ reporter: NicoleSchwartz # GitLab username of the person reporting the deprecation
+ body: | # Do not modify this line, instead modify the lines below.
+ The Secure and Protect stages will be bumping the major versions of their analyzers in tandem with the GitLab 15.0 release. This major bump will enable a clear delineation for analyzers, between:
+
+ - Those released prior to May 22, 2022, which generate reports that _are not_ subject to stringent schema validation.
+ - Those released after May 22, 2022, which generate reports that _are_ subject to stringent schema validation.
+
+ If you are not using the default inclusion templates, or have pinned your analyzer version(s) you will need to update your CI/CD job definition to either remove the pinned version or to update the latest major version.
+ Users of GitLab 12.0-14.10 will continue to experience analyzer updates as normal until the release of GitLab 15.0, following which all newly fixed bugs and newly released features in the new major versions of the analyzers will not be available in the deprecated versions because we do not backport bugs and new features as per our [maintenance policy](https://docs.gitlab.com/ee/policy/maintenance.html). As required security patches will be backported within the latest 3 minor releases.
+ Specifically, the following are being deprecated and will no longer be updated after 15.0 GitLab release:
+
+ - API Security: version 1
+ - Container Scanning: version 4
+ - Coverage-guided fuzz testing: version 2
+ - Dependency Scanning: version 2
+ - Dynamic Application Security Testing (DAST): version 2
+ - License Scanning: version 3
+ - Secret Detection: version 3
+ - Static Application Security Testing (SAST): version 2, except security-code-scan which is version 3
+ - `bandit`: version 2
+ - `brakeman`: version 2
+ - `eslint`: version 2
+ - `flawfinder`: version 2
+ - `gosec`: version 3
+ - `kubesec`: version 2
+ - `mobsf`: version 2
+ - `nodejs-scan`: version 2
+ - `phpcs-security-audit`: version 2
+ - `pmd-apex`: version 2
+ - `security-code-scan`: version 3
+ - `semgrep`: version 2
+ - `sobelow`: version 2
+ - `spotbugs`: version 2
+# The following items are not published on the docs page, but may be used in the future.
+ stage: secure, protect # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: Free, Silver, Gold, Core, Premium, Ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350936 # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index b3bccd0b37a..b7170c2e047 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -1516,11 +1516,9 @@ Input type: `CreateSnippetInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationcreatesnippetblobactions"></a>`blobActions` | [`[SnippetBlobActionInputType!]`](#snippetblobactioninputtype) | Actions to perform over the snippet repository and blobs. |
-| <a id="mutationcreatesnippetcaptcharesponse"></a>`captchaResponse` **{warning-solid}** | [`String`](#string) | **Deprecated:** Use spam protection with HTTP headers instead. Deprecated in 13.11. |
| <a id="mutationcreatesnippetclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationcreatesnippetdescription"></a>`description` | [`String`](#string) | Description of the snippet. |
| <a id="mutationcreatesnippetprojectpath"></a>`projectPath` | [`ID`](#id) | Full path of the project the snippet is associated with. |
-| <a id="mutationcreatesnippetspamlogid"></a>`spamLogId` **{warning-solid}** | [`Int`](#int) | **Deprecated:** Use spam protection with HTTP headers instead. Deprecated in 13.11. |
| <a id="mutationcreatesnippettitle"></a>`title` | [`String!`](#string) | Title of the snippet. |
| <a id="mutationcreatesnippetuploadedfiles"></a>`uploadedFiles` | [`[String!]`](#string) | Paths to files uploaded in the snippet description. |
| <a id="mutationcreatesnippetvisibilitylevel"></a>`visibilityLevel` | [`VisibilityLevelsEnum!`](#visibilitylevelsenum) | Visibility level of the snippet. |
@@ -1529,13 +1527,9 @@ Input type: `CreateSnippetInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="mutationcreatesnippetcaptchasitekey"></a>`captchaSiteKey` **{warning-solid}** | [`String`](#string) | **Deprecated:** Use spam protection with HTTP headers instead. Deprecated in 13.11. |
| <a id="mutationcreatesnippetclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationcreatesnippeterrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationcreatesnippetneedscaptcharesponse"></a>`needsCaptchaResponse` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated:** Use spam protection with HTTP headers instead. Deprecated in 13.11. |
| <a id="mutationcreatesnippetsnippet"></a>`snippet` | [`Snippet`](#snippet) | Snippet after mutation. |
-| <a id="mutationcreatesnippetspam"></a>`spam` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated:** Use spam protection with HTTP headers instead. Deprecated in 13.11. |
-| <a id="mutationcreatesnippetspamlogid"></a>`spamLogId` **{warning-solid}** | [`Int`](#int) | **Deprecated:** Use spam protection with HTTP headers instead. Deprecated in 13.11. |
### `Mutation.createTestCase`
@@ -4938,11 +4932,9 @@ Input type: `UpdateSnippetInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationupdatesnippetblobactions"></a>`blobActions` | [`[SnippetBlobActionInputType!]`](#snippetblobactioninputtype) | Actions to perform over the snippet repository and blobs. |
-| <a id="mutationupdatesnippetcaptcharesponse"></a>`captchaResponse` **{warning-solid}** | [`String`](#string) | **Deprecated:** Use spam protection with HTTP headers instead. Deprecated in 13.11. |
| <a id="mutationupdatesnippetclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationupdatesnippetdescription"></a>`description` | [`String`](#string) | Description of the snippet. |
| <a id="mutationupdatesnippetid"></a>`id` | [`SnippetID!`](#snippetid) | Global ID of the snippet to update. |
-| <a id="mutationupdatesnippetspamlogid"></a>`spamLogId` **{warning-solid}** | [`Int`](#int) | **Deprecated:** Use spam protection with HTTP headers instead. Deprecated in 13.11. |
| <a id="mutationupdatesnippettitle"></a>`title` | [`String`](#string) | Title of the snippet. |
| <a id="mutationupdatesnippetvisibilitylevel"></a>`visibilityLevel` | [`VisibilityLevelsEnum`](#visibilitylevelsenum) | Visibility level of the snippet. |
@@ -4950,13 +4942,9 @@ Input type: `UpdateSnippetInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="mutationupdatesnippetcaptchasitekey"></a>`captchaSiteKey` **{warning-solid}** | [`String`](#string) | **Deprecated:** Use spam protection with HTTP headers instead. Deprecated in 13.11. |
| <a id="mutationupdatesnippetclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationupdatesnippeterrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
-| <a id="mutationupdatesnippetneedscaptcharesponse"></a>`needsCaptchaResponse` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated:** Use spam protection with HTTP headers instead. Deprecated in 13.11. |
| <a id="mutationupdatesnippetsnippet"></a>`snippet` | [`Snippet`](#snippet) | Snippet after mutation. |
-| <a id="mutationupdatesnippetspam"></a>`spam` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated:** Use spam protection with HTTP headers instead. Deprecated in 13.11. |
-| <a id="mutationupdatesnippetspamlogid"></a>`spamLogId` **{warning-solid}** | [`Int`](#int) | **Deprecated:** Use spam protection with HTTP headers instead. Deprecated in 13.11. |
### `Mutation.userCalloutCreate`
diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md
index 10c0e55b947..2f5146b8161 100644
--- a/doc/update/deprecations.md
+++ b/doc/update/deprecations.md
@@ -1285,6 +1285,48 @@ See the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/352564
**Planned removal milestone: 15.0 (2022-05-22)**
+### Secure and Protect analyzer major version update
+
+WARNING:
+This feature will be changed or removed in 15.00
+as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
+Before updating GitLab, review the details carefully to determine if you need to make any
+changes to your code, settings, or workflow.
+
+The Secure and Protect stages will be bumping the major versions of their analyzers in tandem with the GitLab 15.0 release. This major bump will enable a clear delineation for analyzers, between:
+
+- Those released prior to May 22, 2022, which generate reports that _are not_ subject to stringent schema validation.
+- Those released after May 22, 2022, which generate reports that _are_ subject to stringent schema validation.
+
+If you are not using the default inclusion templates, or have pinned your analyzer version(s) you will need to update your CI/CD job definition to either remove the pinned version or to update the latest major version.
+Users of GitLab 12.0-14.10 will continue to experience analyzer updates as normal until the release of GitLab 15.0, following which all newly fixed bugs and newly released features in the new major versions of the analyzers will not be available in the deprecated versions because we do not backport bugs and new features as per our [maintenance policy](https://docs.gitlab.com/ee/policy/maintenance.html). As required security patches will be backported within the latest 3 minor releases.
+Specifically, the following are being deprecated and will no longer be updated after 15.0 GitLab release:
+
+- API Security: version 1
+- Container Scanning: version 4
+- Coverage-guided fuzz testing: version 2
+- Dependency Scanning: version 2
+- Dynamic Application Security Testing (DAST): version 2
+- License Scanning: version 3
+- Secret Detection: version 3
+- Static Application Security Testing (SAST): version 2, except security-code-scan which is version 3
+ - `bandit`: version 2
+ - `brakeman`: version 2
+ - `eslint`: version 2
+ - `flawfinder`: version 2
+ - `gosec`: version 3
+ - `kubesec`: version 2
+ - `mobsf`: version 2
+ - `nodejs-scan`: version 2
+ - `phpcs-security-audit`: version 2
+ - `pmd-apex`: version 2
+ - `security-code-scan`: version 3
+ - `semgrep`: version 2
+ - `sobelow`: version 2
+ - `spotbugs`: version 2
+
+**Planned removal milestone: 15.00 ()**
+
### Support for gRPC-aware proxy deployed between Gitaly and rest of GitLab
WARNING:
@@ -1367,6 +1409,21 @@ removed in GitLab 15.0.
**Planned removal milestone: 15.0 (2022-06-22)**
+### `projectFingerprint` in `PipelineSecurityReportFinding` GraphQL
+
+WARNING:
+This feature will be changed or removed in 15.0
+as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
+Before updating GitLab, review the details carefully to determine if you need to make any
+changes to your code, settings, or workflow.
+
+The `projectFingerprint` field in the [PipelineSecurityReportFinding](https://docs.gitlab.com/ee/api/graphql/reference/index.html#pipelinesecurityreportfinding)
+GraphQL object is being deprecated. This field contains a "fingerprint" of security findings used to determine uniqueness.
+The method for calculating fingerprints has changed, resulting in different values. Going forward, the new values will be
+exposed in the UUID field. Data previously available in the projectFingerprint field will eventually be removed entirely.
+
+**Planned removal milestone: 15.0 (2022-05-22)**
+
### `started` iterations API field
WARNING:
diff --git a/doc/user/application_security/configuration/index.md b/doc/user/application_security/configuration/index.md
index 1679e04e24e..430f8e1a2a2 100644
--- a/doc/user/application_security/configuration/index.md
+++ b/doc/user/application_security/configuration/index.md
@@ -65,4 +65,4 @@ You can configure the following security controls:
You can configure the following security controls:
- [License Compliance](../../../user/compliance/license_compliance/index.md)
- - Can be configured with `.gitlab-ci.yml`. For more details, read [License Compliance](../../../user/compliance/license_compliance/index.md#configuration).
+ - Can be configured with `.gitlab-ci.yml`. For more details, read [License Compliance](../../../user/compliance/license_compliance/index.md#enable-license-compliance).
diff --git a/doc/user/compliance/license_compliance/index.md b/doc/user/compliance/license_compliance/index.md
index 20ec5dd0282..18de33ea03b 100644
--- a/doc/user/compliance/license_compliance/index.md
+++ b/doc/user/compliance/license_compliance/index.md
@@ -14,17 +14,9 @@ project's dependencies for their licenses. You can then decide whether to allow
each license. For example, if your application uses an external (open source) library whose license
is incompatible with yours, then you can deny the use of that license.
-You can take advantage of License Compliance by either:
+To detect the licenses in use, License Compliance uses the [License Finder](https://github.com/pivotal/LicenseFinder) scan tool that runs as part of the CI/CD pipeline. The License Compliance job is not dependent on any other job in
+a pipeline.
-- [Including the job](#configuration)
- in your existing `.gitlab-ci.yml` file.
-- Implicitly using
- [Auto License Compliance](../../../topics/autodevops/stages.md#auto-license-compliance),
- provided by [Auto DevOps](../../../topics/autodevops/index.md).
-
-The current major version of the License Scanning analyzer is 3.
-
-To detect the licenses in use, License Compliance uses the [License Finder](https://github.com/pivotal/LicenseFinder) scan tool that runs as part of the CI/CD pipeline.
For the job to activate, License Finder needs to find a compatible package definition in the project directory. For details, see the [Activation on License Finder documentation](https://github.com/pivotal/LicenseFinder#activation).
GitLab checks the License Compliance report, compares the
licenses between the source and target branches, and shows the information right on the merge
@@ -41,6 +33,14 @@ is displayed in the merge request area. That is the case when you add the
Consecutive merge requests have something to compare to and the license
compliance report is shown properly.
+The results are saved as a
+[License Compliance report artifact](../../../ci/yaml/artifacts_reports.md#artifactsreportslicense_scanning)
+that you can later download and analyze. Due to implementation limitations, we
+always take the latest License Compliance artifact available.
+
+WARNING:
+License Compliance Scanning does not support run-time installation of compilers and interpreters.
+
![License Compliance Widget](img/license_compliance_v13_0.png)
You can select a license to see more information.
@@ -93,27 +93,26 @@ The reported licenses might be incomplete or inaccurate.
| Rust | [Cargo](https://crates.io) |
| PHP | [Composer](https://getcomposer.org/) |
-## Requirements
+## Enable License Compliance
-WARNING:
-License Compliance Scanning does not support run-time installation of compilers and interpreters.
+To enable License Compliance in your project's pipeline, either:
-To run a License Compliance scanning job, you need GitLab Runner with the
-[`docker` executor](https://docs.gitlab.com/runner/executors/docker.html).
+- Enable [Auto License Compliance](../../../topics/autodevops/stages.md#auto-license-compliance)
+ (provided by [Auto DevOps](../../../topics/autodevops/index.md)).
+- Include the [`License-Scanning.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml) in your `.gitlab-ci.yml` file.
-## Configuration
+### Include the License Scanning template
-For GitLab 12.8 and later, to enable License Compliance, you must
-[include](../../../ci/yaml/index.md#includetemplate) the
-[`License-Scanning.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml)
-that's provided as a part of your GitLab installation.
-For older versions of GitLab from 11.9 to 12.7, you must
-[include](../../../ci/yaml/index.md#includetemplate) the
-[`License-Management.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/d2cc841c55d65bc8134bfb3a467e66c36ac32b0a/lib/gitlab/ci/templates/Security/License-Management.gitlab-ci.yml).
-For GitLab versions earlier than 11.9, you can copy and use the job as defined
-that template.
+Prerequisites:
+
+- [GitLab Runner](../../../ci/runners/index.md) available, with the
+ [`docker` executor](https://docs.gitlab.com/runner/executors/docker.html). If you're using the
+ shared runners on GitLab.com, this is enabled by default.
+- License Scanning runs in the `test` stage, which is available by default. If you redefine the stages in the
+ `.gitlab-ci.yml` file, the `test` stage is required.
-Add the following to your `.gitlab-ci.yml` file:
+To [include](../../../ci/yaml/index.md#includetemplate) the
+[`License-Scanning.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml), add it to your `.gitlab-ci.yml` file:
```yaml
include:
@@ -123,26 +122,6 @@ include:
The included template creates a `license_scanning` job in your CI/CD pipeline and scans your
dependencies to find their licenses.
-NOTE:
-Before GitLab 12.8, the `license_scanning` job was named `license_management`. GitLab 13.0 removes
-the `license_management` job, so you must migrate to the `license_scanning` job and use the new
-`License-Scanning.gitlab-ci.yml` template.
-
-The results are saved as a
-[License Compliance report artifact](../../../ci/yaml/artifacts_reports.md#artifactsreportslicense_scanning)
-that you can later download and analyze. Due to implementation limitations, we
-always take the latest License Compliance artifact available. Behind the scenes, the
-[GitLab License Compliance Docker image](https://gitlab.com/gitlab-org/security-products/analyzers/license-finder)
-is used to detect the languages/frameworks and in turn analyzes the licenses.
-
-The License Compliance settings can be changed through [CI/CD variables](#available-cicd-variables) by using the
-[`variables`](../../../ci/yaml/index.md#variables) parameter in `.gitlab-ci.yml`.
-
-### When License Compliance runs
-
-When using the GitLab `License-Scanning.gitlab-ci.yml` template, the License Compliance job doesn't
-wait for other stages to complete.
-
### Available CI/CD variables
License Compliance can be configured using CI/CD variables.
@@ -653,7 +632,7 @@ successfully run. For more information, see [Offline environments](../../applica
To use License Compliance in an offline environment, you need:
-- GitLab Runner with the [`docker` or `kubernetes` executor](#requirements).
+- To meet the standard [License Compliance prerequisites](#include-the-license-scanning-template).
- Docker Container Registry with locally available copies of License Compliance [analyzer](https://gitlab.com/gitlab-org/security-products/analyzers) images.
NOTE:
@@ -731,7 +710,7 @@ details about them.
For the licenses to appear under the license list, the following
requirements must be met:
-1. The License Compliance CI job must be [configured](#configuration) for your project.
+1. The License Compliance CI/CD job must be [enabled](#enable-license-compliance) for your project.
1. Your project must use at least one of the
[supported languages and package managers](#supported-languages-and-package-managers).
diff --git a/lib/gitlab/ci/badge/release/latest_release.rb b/lib/gitlab/ci/badge/release/latest_release.rb
new file mode 100644
index 00000000000..e73bb2a912a
--- /dev/null
+++ b/lib/gitlab/ci/badge/release/latest_release.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module Gitlab::Ci
+ module Badge
+ module Release
+ class LatestRelease < Badge::Base
+ attr_reader :project, :release, :customization
+
+ def initialize(project, current_user, opts: {})
+ @project = project
+ @customization = {
+ key_width: opts[:key_width] ? opts[:key_width].to_i : nil,
+ key_text: opts[:key_text]
+ }
+
+ # In the future, we should support `order_by=semver` for showing the
+ # latest release based on Semantic Versioning.
+ @release = ::ReleasesFinder.new(
+ project,
+ current_user,
+ order_by: opts[:order_by]).execute.first
+ end
+
+ def entity
+ 'Latest Release'
+ end
+
+ def tag
+ @release&.tag
+ end
+
+ def metadata
+ @metadata ||= Release::Metadata.new(self)
+ end
+
+ def template
+ @template ||= Release::Template.new(self)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/badge/release/metadata.rb b/lib/gitlab/ci/badge/release/metadata.rb
new file mode 100644
index 00000000000..e02959b5741
--- /dev/null
+++ b/lib/gitlab/ci/badge/release/metadata.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Gitlab::Ci
+ module Badge
+ module Release
+ class Metadata < Badge::Metadata
+ def initialize(badge)
+ @project = badge.project
+ end
+
+ def title
+ 'Latest Release'
+ end
+
+ def image_url
+ release_project_badges_url(@project, format: :svg)
+ end
+
+ def link_url
+ project_releases_url(@project)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/badge/release/template.rb b/lib/gitlab/ci/badge/release/template.rb
new file mode 100644
index 00000000000..65bff4371cf
--- /dev/null
+++ b/lib/gitlab/ci/badge/release/template.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+module Gitlab::Ci
+ module Badge
+ module Release
+ # Template object will be passed to badge.svg.erb template.
+ class Template < Badge::Template
+ STATUS_COLOR = {
+ latest: '#3076af',
+ none: '#e05d44'
+ }.freeze
+ KEY_WIDTH_DEFAULT = 90
+ VALUE_WIDTH_DEFAULT = 54
+
+ def initialize(badge)
+ @entity = badge.entity
+ @tag = badge.tag || "none"
+ @key_width = badge.customization.dig(:key_width)
+ @key_text = badge.customization.dig(:key_text)
+ end
+
+ def key_text
+ @key_text || @entity.to_s
+ end
+
+ def key_width
+ @key_width || KEY_WIDTH_DEFAULT
+ end
+
+ def value_text
+ @tag.to_s
+ end
+
+ def value_width
+ VALUE_WIDTH_DEFAULT
+ end
+
+ def value_color
+ STATUS_COLOR[@tag.to_sym] || STATUS_COLOR[:latest]
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml
index c73e84ea620..65c9232f3b9 100644
--- a/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml
@@ -37,8 +37,15 @@ dependency_scanning:
script:
- /analyzer run
+.cyclone-dx-reports:
+ artifacts:
+ paths:
+ - "**/cyclonedx-*.json"
+
gemnasium-dependency_scanning:
- extends: .ds-analyzer
+ extends:
+ - .ds-analyzer
+ - .cyclone-dx-reports
image:
name: "$DS_ANALYZER_IMAGE"
variables:
@@ -67,7 +74,9 @@ gemnasium-dependency_scanning:
- '{conan.lock,*/conan.lock,*/*/conan.lock}'
gemnasium-maven-dependency_scanning:
- extends: .ds-analyzer
+ extends:
+ - .ds-analyzer
+ - .cyclone-dx-reports
image:
name: "$DS_ANALYZER_IMAGE"
variables:
@@ -93,7 +102,9 @@ gemnasium-maven-dependency_scanning:
- '{pom.xml,*/pom.xml,*/*/pom.xml}'
gemnasium-python-dependency_scanning:
- extends: .ds-analyzer
+ extends:
+ - .ds-analyzer
+ - .cyclone-dx-reports
image:
name: "$DS_ANALYZER_IMAGE"
variables:
diff --git a/spec/controllers/projects/badges_controller_spec.rb b/spec/controllers/projects/badges_controller_spec.rb
index 242b2fd3ec6..d41e8d6169f 100644
--- a/spec/controllers/projects/badges_controller_spec.rb
+++ b/spec/controllers/projects/badges_controller_spec.rb
@@ -7,39 +7,100 @@ RSpec.describe Projects::BadgesController do
let_it_be(:pipeline, reload: true) { create(:ci_empty_pipeline, project: project) }
let_it_be(:user) { create(:user) }
- shared_examples 'a badge resource' do |badge_type|
- context 'when pipelines are public' do
+ shared_context 'renders badge irrespective of project access levels' do |badge_type|
+ context 'when project is public' do
before do
- project.update!(public_builds: true)
+ project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
end
- context 'when project is public' do
- before do
- project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
- end
+ it "returns the #{badge_type} badge to unauthenticated users" do
+ get_badge(badge_type)
- it "returns the #{badge_type} badge to unauthenticated users" do
- get_badge(badge_type)
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
- expect(response).to have_gitlab_http_status(:ok)
- end
+ context 'when project is restricted' do
+ before do
+ project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
+ project.add_guest(user)
+ sign_in(user)
end
- context 'when project is restricted' do
- before do
- project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
- project.add_guest(user)
- sign_in(user)
- end
+ it "returns the #{badge_type} badge to guest users" do
+ get_badge(badge_type)
- it "returns the #{badge_type} badge to guest users" do
- get_badge(badge_type)
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
- expect(response).to have_gitlab_http_status(:ok)
- end
+ shared_context 'when pipelines are public' do |badge_type|
+ before do
+ project.update!(public_builds: true)
+ end
+
+ it_behaves_like 'renders badge irrespective of project access levels', badge_type
+ end
+
+ shared_context 'when pipelines are not public' do |badge_type|
+ before do
+ project.update!(public_builds: false)
+ end
+
+ context 'when project is public' do
+ before do
+ project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+ end
+
+ it 'returns 404 to unauthenticated users' do
+ get_badge(badge_type)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'when project is restricted to the user' do
+ before do
+ project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
+ project.add_guest(user)
+ sign_in(user)
+ end
+
+ it 'defaults to project permissions' do
+ get_badge(badge_type)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ shared_context 'customization' do |badge_type|
+ render_views
+
+ before do
+ project.add_maintainer(user)
+ sign_in(user)
+ end
+
+ context 'when key_text param is used' do
+ it 'sets custom key text' do
+ get_badge(badge_type, key_text: 'custom key text')
+
+ expect(response.body).to include('custom key text')
+ end
+ end
+
+ context 'when key_width param is used' do
+ it 'sets custom key width' do
+ get_badge(badge_type, key_width: '123')
+
+ expect(response.body).to include('123')
end
end
+ end
+ shared_examples 'a badge resource' do |badge_type|
context 'format' do
before do
project.add_maintainer(user)
@@ -77,61 +138,11 @@ RSpec.describe Projects::BadgesController do
end
end
- context 'when pipelines are not public' do
- before do
- project.update!(public_builds: false)
- end
-
- context 'when project is public' do
- before do
- project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
- end
-
- it 'returns 404 to unauthenticated users' do
- get_badge(badge_type)
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- context 'when project is restricted to the user' do
- before do
- project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
- project.add_guest(user)
- sign_in(user)
- end
-
- it 'defaults to project permissions' do
- get_badge(badge_type)
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
- end
-
- context 'customization' do
- render_views
-
- before do
- project.add_maintainer(user)
- sign_in(user)
- end
-
- context 'when key_text param is used' do
- it 'sets custom key text' do
- get_badge(badge_type, key_text: 'custom key text')
-
- expect(response.body).to include('custom key text')
- end
- end
-
- context 'when key_width param is used' do
- it 'sets custom key width' do
- get_badge(badge_type, key_width: '123')
+ it_behaves_like 'customization', badge_type
- expect(response.body).to include('123')
- end
- end
+ if [:pipeline, :coverage].include?(badge_type)
+ it_behaves_like 'when pipelines are public', badge_type
+ it_behaves_like 'when pipelines are not public', badge_type
end
end
@@ -163,6 +174,13 @@ RSpec.describe Projects::BadgesController do
it_behaves_like 'a badge resource', :coverage
end
+ describe '#release' do
+ action = :release
+
+ it_behaves_like 'a badge resource', action
+ it_behaves_like 'renders badge irrespective of project access levels', action
+ end
+
def get_badge(badge, args = {})
params = {
namespace_id: project.namespace.to_param,
diff --git a/spec/features/users/bizible_csp_spec.rb b/spec/features/users/bizible_csp_spec.rb
new file mode 100644
index 00000000000..af0b42050b3
--- /dev/null
+++ b/spec/features/users/bizible_csp_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Bizible content security policy' do
+ before do
+ stub_config(extra: { one_trust_id: SecureRandom.uuid })
+ end
+
+ it 'has proper Content Security Policy headers' do
+ visit root_path
+
+ expect(response_headers['Content-Security-Policy']).to include('https://cdn.bizible.com/scripts/bizible.js')
+ end
+end
diff --git a/spec/helpers/bizible_helper_spec.rb b/spec/helpers/bizible_helper_spec.rb
new file mode 100644
index 00000000000..b82211d51ec
--- /dev/null
+++ b/spec/helpers/bizible_helper_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe BizibleHelper do
+ describe '#bizible_enabled?' do
+ before do
+ stub_config(extra: { bizible: SecureRandom.uuid })
+ end
+
+ context 'when bizible is disabled' do
+ before do
+ allow(helper).to receive(:bizible_enabled?).and_return(false)
+ end
+
+ it { is_expected.to be_falsey }
+ end
+
+ context 'when bizible is enabled' do
+ before do
+ allow(helper).to receive(:bizible_enabled?).and_return(true)
+ end
+
+ it { is_expected.to be_truthy }
+ end
+
+ subject(:bizible_enabled?) { helper.bizible_enabled? }
+
+ context 'with ecomm_instrumentation feature flag disabled' do
+ before do
+ stub_feature_flags(ecomm_instrumentation: false)
+ end
+
+ it { is_expected.to be_falsey }
+ end
+
+ context 'with ecomm_instrumentation feature flag enabled' do
+ context 'when no id is set' do
+ before do
+ stub_config(extra: {})
+ end
+
+ it { is_expected.to be_falsey }
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/badge/release/latest_release_spec.rb b/spec/lib/gitlab/ci/badge/release/latest_release_spec.rb
new file mode 100644
index 00000000000..36f9f4fb321
--- /dev/null
+++ b/spec/lib/gitlab/ci/badge/release/latest_release_spec.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Ci::Badge::Release::LatestRelease do
+ let(:project) { create(:project, :repository) }
+ let(:user) { create(:user) }
+
+ before do
+ project.add_guest(user)
+ create(:release, project: project, released_at: 1.day.ago)
+ end
+
+ subject { described_class.new(project, user) }
+
+ describe '#entity' do
+ it 'describes latest release' do
+ expect(subject.entity).to eq 'Latest Release'
+ end
+ end
+
+ describe '#tag' do
+ it 'returns latest release tag for the project ordered using release_at' do
+ create(:release, tag: "v1.0.0", project: project, released_at: 1.hour.ago)
+ latest_release = create(:release, tag: "v2.0.0", project: project, released_at: Time.current)
+
+ expect(subject.tag).to eq latest_release.tag
+ end
+ end
+
+ describe '#metadata' do
+ it 'returns correct metadata' do
+ expect(subject.metadata.image_url).to include 'release.svg'
+ end
+ end
+
+ describe '#template' do
+ it 'returns correct template' do
+ expect(subject.template.key_text).to eq 'Latest Release'
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/badge/release/metadata_spec.rb b/spec/lib/gitlab/ci/badge/release/metadata_spec.rb
new file mode 100644
index 00000000000..d68358f1458
--- /dev/null
+++ b/spec/lib/gitlab/ci/badge/release/metadata_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'lib/gitlab/ci/badge/shared/metadata'
+
+RSpec.describe Gitlab::Ci::Badge::Release::Metadata do
+ let(:project) { create(:project) }
+ let(:ref) { 'feature' }
+ let!(:release) { create(:release, tag: ref, project: project) }
+ let(:user) { create(:user) }
+ let(:badge) do
+ Gitlab::Ci::Badge::Release::LatestRelease.new(project, user)
+ end
+
+ let(:metadata) { described_class.new(badge) }
+
+ before do
+ project.add_guest(user)
+ end
+
+ it_behaves_like 'badge metadata'
+
+ describe '#title' do
+ it 'returns latest release title' do
+ expect(metadata.title).to eq 'Latest Release'
+ end
+ end
+
+ describe '#image_url' do
+ it 'returns valid url' do
+ expect(metadata.image_url).to include "/-/badges/release.svg"
+ end
+ end
+
+ describe '#link_url' do
+ it 'returns valid link' do
+ expect(metadata.link_url).to include "/-/releases"
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/badge/release/template_spec.rb b/spec/lib/gitlab/ci/badge/release/template_spec.rb
new file mode 100644
index 00000000000..2b66c296a94
--- /dev/null
+++ b/spec/lib/gitlab/ci/badge/release/template_spec.rb
@@ -0,0 +1,90 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Ci::Badge::Release::Template do
+ let(:project) { create(:project) }
+ let(:ref) { 'v1.2.3' }
+ let(:user) { create(:user) }
+ let!(:release) { create(:release, tag: ref, project: project) }
+ let(:badge) { Gitlab::Ci::Badge::Release::LatestRelease.new(project, user) }
+ let(:template) { described_class.new(badge) }
+
+ before do
+ project.add_guest(user)
+ end
+
+ describe '#key_text' do
+ it 'defaults to latest release' do
+ expect(template.key_text).to eq 'Latest Release'
+ end
+
+ it 'returns custom key text' do
+ key_text = 'Test Release'
+ badge = Gitlab::Ci::Badge::Release::LatestRelease.new(project, user, opts: { key_text: key_text })
+
+ expect(described_class.new(badge).key_text).to eq key_text
+ end
+ end
+
+ describe '#value_text' do
+ context 'when a release exists' do
+ it 'returns the tag of the release' do
+ expect(template.value_text).to eq ref
+ end
+ end
+
+ context 'no releases exist' do
+ before do
+ allow(badge).to receive(:tag).and_return(nil)
+ end
+
+ it 'returns string that latest release is none' do
+ expect(template.value_text).to eq 'none'
+ end
+ end
+ end
+
+ describe '#key_width' do
+ it 'returns the default key width' do
+ expect(template.key_width).to eq 90
+ end
+
+ it 'returns custom key width' do
+ key_width = 100
+ badge = Gitlab::Ci::Badge::Release::LatestRelease.new(project, user, opts: { key_width: key_width })
+
+ expect(described_class.new(badge).key_width).to eq key_width
+ end
+ end
+
+ describe '#value_width' do
+ it 'has a fixed value width' do
+ expect(template.value_width).to eq 54
+ end
+ end
+
+ describe '#key_color' do
+ it 'always has the same color' do
+ expect(template.key_color).to eq '#555'
+ end
+ end
+
+ describe '#value_color' do
+ context 'when release exists' do
+ it 'is blue' do
+ expect(template.value_color).to eq '#3076af'
+ end
+ end
+
+ context 'when release does not exist' do
+ before do
+ allow(badge).to receive(:tag).and_return(nil)
+ end
+
+ it 'is red' do
+ expect(template.value_color).to eq '#e05d44'
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_examples/graphql/mutations/can_mutate_spammable_examples.rb b/spec/support/shared_examples/graphql/mutations/can_mutate_spammable_examples.rb
index 011a2157f24..b17e59f0797 100644
--- a/spec/support/shared_examples/graphql/mutations/can_mutate_spammable_examples.rb
+++ b/spec/support/shared_examples/graphql/mutations/can_mutate_spammable_examples.rb
@@ -16,17 +16,4 @@ RSpec.shared_examples 'a mutation which can mutate a spammable' do
subject
end
end
-
- describe "#spam_action_response_fields" do
- it 'resolves with spam action fields' do
- subject
-
- # NOTE: We do not need to assert on the specific values of spam action fields here, we only need
- # to verify that #spam_action_response_fields was invoked and that the fields are present in the
- # response. The specific behavior of #spam_action_response_fields is covered in the
- # HasSpamActionResponseFields unit tests.
- expect(mutation_response.keys)
- .to include('spam', 'spamLogId', 'needsCaptchaResponse', 'captchaSiteKey')
- end
- end
end