Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-10-14 06:09:23 +00:00
parent d57e092bd6
commit a5266bda12
23 changed files with 244 additions and 81 deletions

View file

@ -20,16 +20,15 @@ module ProjectsHelper
end
def link_to_member_avatar(author, opts = {})
default_opts = { size: 16, lazy_load: false }
default_opts = { size: 16 }
opts = default_opts.merge(opts)
classes = %W[avatar avatar-inline s#{opts[:size]}]
classes << opts[:avatar_class] if opts[:avatar_class]
avatar = avatar_icon_for_user(author, opts[:size])
src = opts[:lazy_load] ? nil : avatar
image_tag(src, width: opts[:size], class: classes, alt: '', "data-src" => avatar)
image_tag(avatar, width: opts[:size], class: classes, alt: '')
end
def author_content_tag(author, opts = {})

View file

@ -925,9 +925,22 @@ module Ci
end
def environments_in_self_and_descendants
environment_ids = self_and_descendants.joins(:deployments).select(:'deployments.environment_id')
if ::Feature.enabled?(:avoid_cross_joins_environments_in_self_and_descendants, default_enabled: :yaml)
# We limit to 100 unique environments for application safety.
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/340781#note_699114700
expanded_environment_names =
builds_in_self_and_descendants.joins(:metadata)
.where.not('ci_builds_metadata.expanded_environment_name' => nil)
.distinct('ci_builds_metadata.expanded_environment_name')
.limit(100)
.pluck(:expanded_environment_name)
Environment.where(id: environment_ids)
Environment.where(project: project, name: expanded_environment_names)
else
environment_ids = self_and_descendants.joins(:deployments).select(:'deployments.environment_id')
Environment.where(id: environment_ids)
end
end
# With multi-project and parent-child pipelines

View file

@ -100,13 +100,11 @@ class EnvironmentStatus
def self.build_environments_status(mr, user, pipeline)
return [] unless pipeline
::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/340781') do
pipeline.environments_in_self_and_descendants.includes(:project).available.map do |environment|
next unless Ability.allowed?(user, :read_environment, environment)
pipeline.environments_in_self_and_descendants.includes(:project).available.map do |environment|
next unless Ability.allowed?(user, :read_environment, environment)
EnvironmentStatus.new(pipeline.project, environment, mr, pipeline.sha)
end.compact
end
EnvironmentStatus.new(pipeline.project, environment, mr, pipeline.sha)
end.compact
end
private_class_method :build_environments_status
end

View file

@ -0,0 +1,8 @@
---
name: avoid_cross_joins_environments_in_self_and_descendants
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71894
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/342991
milestone: '14.4'
type: development
group: group::release
default_enabled: false

View file

@ -0,0 +1,7 @@
# frozen_string_literal: true
class AddStatusColumnToSecurityScansTable < Gitlab::Database::Migration[1.0]
def change
add_column :security_scans, :status, :integer, limit: 1, default: 0, null: false
end
end

View file

@ -0,0 +1,24 @@
# frozen_string_literal: true
class SchedulePopulateStatusColumnOfSecurityScans < Gitlab::Database::Migration[1.0]
MIGRATION = 'PopulateStatusColumnOfSecurityScans'
BATCH_SIZE = 10_000
DELAY_INTERVAL = 2.minutes
disable_ddl_transaction!
def up
return unless Gitlab.ee?
queue_background_migration_jobs_by_range_at_intervals(
define_batchable_model('security_scans'),
MIGRATION,
DELAY_INTERVAL,
batch_size: BATCH_SIZE
)
end
def down
# no-op
end
end

View file

@ -0,0 +1 @@
7abcc243cd02a4eba77ea39cbb1b1f2de74d85e55055def9ae02c4fdeaba3d9a

View file

@ -0,0 +1 @@
115427979cd7ecfc14bf4f663a9afd5abc6d481d08fafc13ca7e6a8cac9ba20c

View file

@ -19054,7 +19054,8 @@ CREATE TABLE security_scans (
info jsonb DEFAULT '{}'::jsonb NOT NULL,
project_id bigint,
pipeline_id bigint,
latest boolean DEFAULT true NOT NULL
latest boolean DEFAULT true NOT NULL,
status smallint DEFAULT 0 NOT NULL
);
CREATE SEQUENCE security_scans_id_seq

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View file

@ -825,8 +825,29 @@ FLAG:
On self-managed GitLab, by default this bug fix is not available. To make it available per project or for your entire instance, ask an administrator to [enable the `surface_environment_creation_failure` flag](../../administration/feature_flags.md). On GitLab.com, this bug fix is not available, but will be rolled out shortly.
If your project is configured to [create a dynamic environment](#create-a-dynamic-environment),
such as a [Review App](../review_apps/index.md), you might encounter this error
because the dynamically generated parameter is invalid for the system.
you might encounter this error because the dynamically generated parameter can't be used for creating an environment.
For example, your project has the following `.gitlab-ci.yml`:
```yaml
deploy:
script: echo
environment: production/$ENVIRONMENT
```
Since `$ENVIRONMENT` variable does not exist in the pipeline, GitLab tries to
create an environment with a name `production/`, which is invalid in
[the environment name constraint](../yaml/index.md).
To fix this, use one of the following solutions:
- Remove `environment` keyword from the deployment job. GitLab has already been
ignoring the invalid keyword, therefore your deployment pipelines stay intact
even after the keyword removal.
- Ensure the variable exists in the pipeline. Please note that there is
[a limitation on supported variables](../variables/where_variables_can_be_used.md#gitlab-ciyml-file).
#### If you get this error on Review Apps
For example, if you have the following in your `.gitlab-ci.yml`:
@ -841,7 +862,7 @@ the `review` job tries to create an environment with `review/bug-fix!`.
However, the `!` is an invalid character for environments, so the
deployment job fails since it was about to run without an environment.
To fix this, you can:
To fix this, use one of the following solutions:
- Re-create your feature branch without the invalid characters,
such as `bug-fix`.

View file

@ -269,7 +269,7 @@ image. Using the `DAST_VERSION` variable, you can choose how DAST updates:
- Only update fixes by pinning to a minor version (such as `1.6`).
- Prevent all updates by pinning to a specific version (such as `1.6.4`).
Find the latest DAST versions on the [Releases](https://gitlab.com/security-products/dast/-/releases)
Find the latest DAST versions on the [Releases](https://gitlab.com/gitlab-org/security-products/dast/-/releases)
page.
#### Configure DAST using the UI

View file

@ -189,26 +189,60 @@ The results are saved as a
that you can later download and analyze. Due to implementation limitations, we
always take the latest SAST artifact available.
### Configure SAST in the UI **(ULTIMATE)**
### Configure SAST in the UI
You can enable and configure SAST in the UI, either with default settings, or with customizations.
Use the method that best meets your needs.
- [Configure SAST in the UI with default settings](#configure-sast-in-the-ui-with-default-settings)
- [Configure SAST in the UI with customizations](#configure-sast-in-the-ui-with-customizations)
### Configure SAST in the UI with default settings **(FREE)**
> [Introduced](https://about.gitlab.com/releases/2021/02/22/gitlab-13-9-released/#security-configuration-page-for-all-users) in GitLab 13.9
To enable and configure SAST with default settings:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Security & Compliance** > **Configuration**.
1. In the SAST section, select `Enable via MR`.
1. Review the draft MR that enables SAST with the default recommended settings in the
`.gitlab-ci.yml` file.
1. Merge the MR to enable SAST. You should see SAST jobs run in that MR's pipeline.
NOTE:
The configuration tool works best with no existing `.gitlab-ci.yml` file, or with a minimal
configuration file. If you have a complex GitLab configuration file it may not be parsed
successfully, and an error may occur.
### Configure SAST in the UI with customizations **(ULTIMATE)**
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3659) in GitLab Ultimate 13.3.
> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/232862) in GitLab Ultimate 13.4.
> - [Improved](https://gitlab.com/groups/gitlab-org/-/epics/3635) in GitLab Ultimate 13.5.
You can enable and configure SAST with a basic configuration using the **SAST Configuration**
page:
To enable and configure SAST with customizations:
1. From the project's home page, go to **Security & Compliance** > **Configuration** in the
left sidebar.
1. If the project does not have a `.gitlab-ci.yml` file, click **Enable** in the Static Application Security Testing (SAST) row, otherwise click **Configure**.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Security & Compliance > Configuration**.
1. If the project does not have a `.gitlab-ci.yml` file, select **Enable** in the Static Application
Security Testing (SAST) row, otherwise select **Configure**.
1. Enter the custom SAST values.
Custom values are stored in the `.gitlab-ci.yml` file. For CI/CD variables not in the SAST Configuration page, their values are left unchanged. Default values are inherited from the GitLab SAST template.
Custom values are stored in the `.gitlab-ci.yml` file. For CI/CD variables not in the SAST
Configuration page, their values are left unchanged. Default values are inherited from the GitLab
SAST template.
1. Optionally, expand the **SAST analyzers** section, select individual [SAST analyzers](analyzers.md) and enter custom analyzer values.
1. Click **Create Merge Request**.
1. Optionally, expand the **SAST analyzers** section, select individual
[SAST analyzers](analyzers.md) and enter custom analyzer values.
1. Select **Create Merge Request**.
1. Review and merge the merge request.
NOTE:
The configuration tool works best with no existing `.gitlab-ci.yml` file, or with a minimal
configuration file. If you have a complex GitLab configuration file it may not be parsed
successfully, and an error may occur.
### Customizing the SAST settings
The SAST settings can be changed through [CI/CD variables](#available-cicd-variables)

View file

@ -138,7 +138,7 @@ The results are saved as a
that you can later download and analyze. Due to implementation limitations, we
always take the latest Secret Detection artifact available.
### Enable Secret Detection via an automatic merge request **(ULTIMATE SELF)**
### Enable Secret Detection via an automatic merge request **(FREE)**
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/4496) in GitLab 13.11, behind a feature flag, enabled by default.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/329886) in GitLab 14.1.
@ -153,6 +153,11 @@ from the Security Configuration page.
This automatically creates a merge request with the changes necessary to enable Secret Detection
that you can review and merge to complete the configuration.
NOTE:
The configuration tool works best with no existing `.gitlab-ci.yml` file, or with a minimal
configuration file. If you have a complex GitLab configuration file it may not be parsed
successfully, and an error may occur.
### Customizing settings
The Secret Detection scan settings can be changed through [CI/CD variables](#available-cicd-variables)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View file

@ -9,9 +9,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/725) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.0.
Configure the Insights that matter for your groups to explore data such as
triage hygiene, issues created/closed per a given period, average time for merge
requests to be merged and much more.
Configure the Insights that matter for your groups. Explore data such as
triage hygiene, issues created or closed for a given period, average time for merge
requests to be merged, and much more.
![Insights example stacked bar chart](img/insights_example_stacked_bar_chart_v13_11.png)
@ -24,23 +24,20 @@ To access your group's Insights:
## Configure your Insights
GitLab reads Insights from the [default configuration file](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/fixtures/insights/default.yml).
If you want to customize it:
1. Create a new file [`.gitlab/insights.yml`](../../project/insights/index.md)
in a project that belongs to your group.
1. On the top bar, select **Menu > Groups** and find your group.
1. On the left sidebar, select **Settings > General**.
1. Expand **Insights**.
1. Choose the project that contains your `.gitlab/insights.yml` configuration file:
![group insights configuration](img/insights_group_configuration.png)
If no configuration was set, a
[default configuration file](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/fixtures/insights/default.yml)
is used.
See the [project's Insights documentation](../../project/insights/index.md) for
details about the `.gitlab/insights.yml` configuration file.
1. Select the project that contains your `.gitlab/insights.yml` configuration file.
1. Select **Save changes**.
## Permissions
If you have access to view a group, then you have access to view their Insights.
If you have access to view a group, then you have access to view its Insights.
NOTE:
Issues or merge requests that you don't have access to (because you don't have

View file

@ -0,0 +1,13 @@
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
class PopulateStatusColumnOfSecurityScans # rubocop:disable Style/Documentation
def perform(_start_id, _end_id)
# no-op
end
end
end
end
Gitlab::BackgroundMigration::PopulateStatusColumnOfSecurityScans.prepend_mod

View file

@ -16522,9 +16522,15 @@ msgstr ""
msgid "GroupSettings|Projects will be permanently deleted after a %{waiting_period}-day delay. This delay can be %{link_start}customized by an admin%{link_end} in instance settings. Inherited by subgroups."
msgstr ""
msgid "GroupSettings|Select a project with the %{code_start}.gitlab/insights.yml%{code_end} file"
msgstr ""
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
msgid "GroupSettings|Set the maximum size of GitLab Pages for this group. %{link_start}Learn more.%{link_end}"
msgstr ""
@ -30706,15 +30712,9 @@ msgstr ""
msgid "Select a project"
msgstr ""
msgid "Select a project to read Insights configuration file"
msgstr ""
msgid "Select a reason"
msgstr ""
msgid "Select a repository"
msgstr ""
msgid "Select a repository containing templates for common files."
msgstr ""

View file

@ -1876,8 +1876,7 @@ RSpec.describe Projects::MergeRequestsController do
let(:sha) { forked.commit.sha }
let(:environment) { create(:environment, project: forked) }
let(:pipeline) { create(:ci_pipeline, sha: sha, project: forked) }
let(:build) { create(:ci_build, pipeline: pipeline) }
let!(:deployment) { create(:deployment, :succeed, environment: environment, sha: sha, ref: 'master', deployable: build) }
let!(:build) { create(:ci_build, :with_deployment, environment: environment.name, pipeline: pipeline) }
let(:merge_request) do
create(:merge_request, source_project: forked, target_project: project, target_branch: 'master', head_pipeline: pipeline)
@ -1901,8 +1900,7 @@ RSpec.describe Projects::MergeRequestsController do
let(:source_environment) { create(:environment, project: project) }
let(:merge_commit_sha) { project.repository.merge(user, forked.commit.id, merge_request, "merged in test") }
let(:post_merge_pipeline) { create(:ci_pipeline, sha: merge_commit_sha, project: project) }
let(:post_merge_build) { create(:ci_build, pipeline: post_merge_pipeline) }
let!(:source_deployment) { create(:deployment, :succeed, environment: source_environment, sha: merge_commit_sha, ref: 'master', deployable: post_merge_build) }
let!(:post_merge_build) { create(:ci_build, :with_deployment, environment: source_environment.name, pipeline: post_merge_pipeline) }
before do
merge_request.update!(merge_commit_sha: merge_commit_sha)
@ -1944,9 +1942,6 @@ RSpec.describe Projects::MergeRequestsController do
context 'when a merge request has multiple environments with deployments' do
let(:sha) { merge_request.diff_head_sha }
let(:ref) { merge_request.source_branch }
let!(:build) { create(:ci_build, pipeline: pipeline) }
let!(:pipeline) { create(:ci_pipeline, sha: sha, project: project) }
let!(:environment) { create(:environment, name: 'env_a', project: project) }
let!(:another_environment) { create(:environment, name: 'env_b', project: project) }
@ -1954,8 +1949,8 @@ RSpec.describe Projects::MergeRequestsController do
before do
merge_request.update_head_pipeline
create(:deployment, :succeed, environment: environment, sha: sha, ref: ref, deployable: build)
create(:deployment, :succeed, environment: another_environment, sha: sha, ref: ref, deployable: build)
create(:ci_build, :with_deployment, environment: environment.name, pipeline: pipeline)
create(:ci_build, :with_deployment, environment: another_environment.name, pipeline: pipeline)
end
it 'exposes multiple environment statuses' do

View file

@ -13,6 +13,8 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
let(:sha) { project.commit(ref).id }
let(:pipeline) { create(:ci_pipeline, sha: sha, project: project, ref: ref) }
let!(:manual) { }
let(:build) { create(:ci_build, :with_deployment, environment: environment.name, pipeline: pipeline) }
let!(:deployment) { build.deployment }
before do
merge_request.update!(merge_commit_sha: sha)
@ -21,8 +23,9 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
end
context 'when deployment succeeded' do
let(:build) { create(:ci_build, :success, pipeline: pipeline) }
let!(:deployment) { create(:deployment, :succeed, environment: environment, sha: sha, ref: ref, deployable: build) }
before do
build.success!
end
it 'displays that the environment is deployed' do
visit project_merge_request_path(project, merge_request)
@ -34,9 +37,8 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
context 'when a user created a new merge request with the same SHA' do
let(:pipeline2) { create(:ci_pipeline, sha: sha, project: project, ref: 'video') }
let(:build2) { create(:ci_build, :success, pipeline: pipeline2) }
let(:environment2) { create(:environment, project: project) }
let!(:deployment2) { create(:deployment, environment: environment2, sha: sha, ref: 'video', deployable: build2) }
let!(:build2) { create(:ci_build, :with_deployment, :success, environment: environment2.name, pipeline: pipeline2) }
it 'displays one environment which is related to the pipeline' do
visit project_merge_request_path(project, merge_request)
@ -50,8 +52,9 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
end
context 'when deployment failed' do
let(:build) { create(:ci_build, :failed, pipeline: pipeline) }
let!(:deployment) { create(:deployment, :failed, environment: environment, sha: sha, ref: ref, deployable: build) }
before do
build.drop!
end
it 'displays that the deployment failed' do
visit project_merge_request_path(project, merge_request)
@ -63,8 +66,9 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
end
context 'when deployment running' do
let(:build) { create(:ci_build, :running, pipeline: pipeline) }
let!(:deployment) { create(:deployment, :running, environment: environment, sha: sha, ref: ref, deployable: build) }
before do
build.run!
end
it 'displays that the running deployment' do
visit project_merge_request_path(project, merge_request)
@ -76,8 +80,8 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
end
context 'when deployment will happen' do
let(:build) { create(:ci_build, :created, pipeline: pipeline) }
let!(:deployment) { create(:deployment, environment: environment, sha: sha, ref: ref, deployable: build) }
let(:build) { create(:ci_build, :with_deployment, environment: environment.name, pipeline: pipeline) }
let!(:deployment) { build.deployment }
it 'displays that the environment name' do
visit project_merge_request_path(project, merge_request)
@ -89,8 +93,9 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
end
context 'when deployment was cancelled' do
let(:build) { create(:ci_build, :canceled, pipeline: pipeline) }
let!(:deployment) { create(:deployment, :canceled, environment: environment, sha: sha, ref: ref, deployable: build) }
before do
build.cancel!
end
it 'displays that the environment name' do
visit project_merge_request_path(project, merge_request)
@ -102,11 +107,10 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
end
context 'with stop action' do
let(:build) { create(:ci_build, :success, pipeline: pipeline) }
let!(:deployment) { create(:deployment, :succeed, environment: environment, sha: sha, ref: ref, deployable: build) }
let(:manual) { create(:ci_build, :manual, pipeline: pipeline, name: 'close_app') }
before do
build.success!
deployment.update!(on_stop: manual.name)
visit project_merge_request_path(project, merge_request)
wait_for_requests

View file

@ -45,18 +45,12 @@ RSpec.describe 'Merge request > User sees merge widget', :js do
let!(:environment) { create(:environment, project: project) }
let(:sha) { project.commit(merge_request.source_branch).sha }
let(:pipeline) { create(:ci_pipeline, status: 'success', sha: sha, project: project, ref: merge_request.source_branch) }
let(:build) { create(:ci_build, :success, pipeline: pipeline) }
let!(:deployment) do
create(:deployment, :succeed,
environment: environment,
ref: merge_request.source_branch,
deployable: build,
sha: sha)
end
let!(:build) { create(:ci_build, :with_deployment, :success, environment: environment.name, pipeline: pipeline) }
let!(:deployment) { build.deployment }
before do
merge_request.update!(head_pipeline: pipeline)
deployment.update!(status: :success)
visit project_merge_request_path(project, merge_request)
end

View file

@ -314,13 +314,13 @@ RSpec.describe ProjectsHelper do
end
it 'returns image tag for member avatar' do
expect(helper).to receive(:image_tag).with(expected, { width: 16, class: %w[avatar avatar-inline s16], alt: "", "data-src" => anything })
expect(helper).to receive(:image_tag).with(expected, { width: 16, class: %w[avatar avatar-inline s16], alt: "" })
helper.link_to_member_avatar(user)
end
it 'returns image tag with avatar class' do
expect(helper).to receive(:image_tag).with(expected, { width: 16, class: %w[avatar avatar-inline s16 any-avatar-class], alt: "", "data-src" => anything })
expect(helper).to receive(:image_tag).with(expected, { width: 16, class: %w[avatar avatar-inline s16 any-avatar-class], alt: "" })
helper.link_to_member_avatar(user, avatar_class: "any-avatar-class")
end

View file

@ -0,0 +1,48 @@
# frozen_string_literal: true
require 'spec_helper'
require_migration!
RSpec.describe SchedulePopulateStatusColumnOfSecurityScans do
before do
allow(Gitlab).to receive(:ee?).and_return(ee?)
stub_const("#{described_class.name}::BATCH_SIZE", 1)
end
context 'when the Gitlab instance is CE' do
let(:ee?) { false }
it 'does not run the migration' do
expect { migrate! }.not_to change { BackgroundMigrationWorker.jobs.size }
end
end
context 'when the Gitlab instance is EE' do
let(:ee?) { true }
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:pipelines) { table(:ci_pipelines) }
let(:builds) { table(:ci_builds) }
let(:security_scans) { table(:security_scans) }
let(:namespace) { namespaces.create!(name: "foo", path: "bar") }
let(:project) { projects.create!(namespace_id: namespace.id) }
let(:pipeline) { pipelines.create!(project_id: project.id, ref: 'master', sha: 'adf43c3a', status: 'success') }
let(:ci_build) { builds.create!(commit_id: pipeline.id, retried: false, type: 'Ci::Build') }
let!(:security_scan_1) { security_scans.create!(build_id: ci_build.id, scan_type: 1) }
let!(:security_scan_2) { security_scans.create!(build_id: ci_build.id, scan_type: 2) }
around do |example|
freeze_time { Sidekiq::Testing.fake! { example.run } }
end
it 'schedules the background jobs', :aggregate_failures do
migrate!
expect(BackgroundMigrationWorker.jobs.size).to be(2)
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, security_scan_1.id, security_scan_1.id)
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, security_scan_2.id, security_scan_2.id)
end
end
end