Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
620e22ef03
commit
3974bc83f3
20 changed files with 157 additions and 65 deletions
|
@ -160,11 +160,6 @@ class Label < ApplicationRecord
|
|||
on_project_boards(project_id).where(id: label_id).exists?
|
||||
end
|
||||
|
||||
# Generate a hex color based on hex-encoded value
|
||||
def self.color_for(value)
|
||||
"##{Digest::MD5.hexdigest(value)[0..5]}"
|
||||
end
|
||||
|
||||
def open_issues_count(user = nil)
|
||||
issues_count(user, state: 'opened')
|
||||
end
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class WorkItemPolicy < IssuePolicy
|
||||
rule { can?(:owner_access) | is_author }.enable :delete_work_item
|
||||
condition(:is_member_and_author) { is_project_member? & is_author? }
|
||||
|
||||
rule { can?(:destroy_issue) | is_member_and_author }.enable :delete_work_item
|
||||
|
||||
rule { can?(:update_issue) }.enable :update_work_item
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ module JiraImport
|
|||
jira_imports_for_project = project.jira_imports.by_jira_project_key(jira_project_key).size + 1
|
||||
title = "jira-import::#{jira_project_key}-#{jira_imports_for_project}"
|
||||
description = "Label for issues that were imported from Jira on #{import_start_time.strftime('%Y-%m-%d %H:%M:%S')}"
|
||||
color = "#{Label.color_for(title)}"
|
||||
color = "#{::Gitlab::Color.color_for(title)}"
|
||||
{ title: title, description: description, color: color }
|
||||
end
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ class Gitlab::Seeder::GroupLabels
|
|||
@label_per_group.times do
|
||||
label_title = FFaker::Product.brand
|
||||
Labels::CreateService
|
||||
.new(title: label_title, color: "##{Digest::MD5.hexdigest(label_title)[0..5]}")
|
||||
.new(title: label_title, color: "#{::Gitlab::Color.color_for(label_title)}")
|
||||
.execute(group: @group)
|
||||
print '.'
|
||||
end
|
||||
|
@ -29,7 +29,7 @@ class Gitlab::Seeder::ProjectLabels
|
|||
@label_per_project.times do
|
||||
label_title = FFaker::Vehicle.model
|
||||
Labels::CreateService
|
||||
.new(title: label_title, color: "##{Digest::MD5.hexdigest(label_title)[0..5]}")
|
||||
.new(title: label_title, color: "#{::Gitlab::Color.color_for(label_title)}")
|
||||
.execute(project: @project)
|
||||
print '.'
|
||||
end
|
||||
|
|
|
@ -111,10 +111,10 @@ class Gitlab::Seeder::TriageOps
|
|||
group = Group.find_by_full_path(group_path)
|
||||
|
||||
label_titles.each do |label_title|
|
||||
color = Digest::MD5.hexdigest(label_title[/[^:]+/])[0..5]
|
||||
color = ::Gitlab::Color.color_for(label_title[/[^:]+/])
|
||||
|
||||
Labels::CreateService
|
||||
.new(title: label_title, color: "##{color}")
|
||||
.new(title: label_title, color: "#{color}")
|
||||
.execute(group: group)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveTmpEmptyTraversalIdsRootNamespaceIndex < Gitlab::Database::Migration[2.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
ROOT_NS_INDEX_NAME = 'tmp_index_namespaces_empty_traversal_ids_with_root_namespaces'
|
||||
|
||||
def up
|
||||
remove_concurrent_index :namespaces, :id, name: ROOT_NS_INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
where_sql = "parent_id IS NULL AND traversal_ids = '{}'"
|
||||
add_concurrent_index :namespaces, :id, where: where_sql, name: ROOT_NS_INDEX_NAME
|
||||
end
|
||||
end
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveTmpEmptyTraversalIdsChildNamespaceIndex < Gitlab::Database::Migration[2.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
CHILD_INDEX_NAME = 'tmp_index_namespaces_empty_traversal_ids_with_child_namespaces'
|
||||
|
||||
def up
|
||||
remove_concurrent_index :namespaces, :id, name: CHILD_INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
where_sql = "parent_id IS NOT NULL AND traversal_ids = '{}'"
|
||||
add_concurrent_index :namespaces, :id, where: where_sql, name: CHILD_INDEX_NAME
|
||||
end
|
||||
end
|
1
db/schema_migrations/20220510003916
Normal file
1
db/schema_migrations/20220510003916
Normal file
|
@ -0,0 +1 @@
|
|||
ccafdc28ff28fc758fe67084f3a837c72f91470467bda2acdb6282de89b46e34
|
1
db/schema_migrations/20220510004501
Normal file
1
db/schema_migrations/20220510004501
Normal file
|
@ -0,0 +1 @@
|
|||
ef9c231a917e4beacff9689c4bbfea0885c4223d3d8b59823a5ffac7f3b2364f
|
|
@ -29768,10 +29768,6 @@ CREATE INDEX tmp_index_members_on_state ON members USING btree (state) WHERE (st
|
|||
|
||||
CREATE INDEX tmp_index_merge_requests_draft_and_status ON merge_requests USING btree (id) WHERE ((draft = false) AND (state_id = 1) AND ((title)::text ~* '^(\[draft\]|\(draft\)|draft:|draft|\[WIP\]|WIP:|WIP)'::text));
|
||||
|
||||
CREATE INDEX tmp_index_namespaces_empty_traversal_ids_with_child_namespaces ON namespaces USING btree (id) WHERE ((parent_id IS NOT NULL) AND (traversal_ids = '{}'::integer[]));
|
||||
|
||||
CREATE INDEX tmp_index_namespaces_empty_traversal_ids_with_root_namespaces ON namespaces USING btree (id) WHERE ((parent_id IS NULL) AND (traversal_ids = '{}'::integer[]));
|
||||
|
||||
CREATE UNIQUE INDEX tmp_index_on_tmp_project_id_on_namespaces ON namespaces USING btree (tmp_project_id);
|
||||
|
||||
CREATE INDEX tmp_index_on_vulnerabilities_non_dismissed ON vulnerabilities USING btree (id) WHERE (state <> 2);
|
||||
|
|
|
@ -154,6 +154,20 @@ WARNING:
|
|||
Do not run `git prune` or `git gc` in object pool repositories, which are stored in the `@pools` directory.
|
||||
This can cause data loss in the regular repositories that depend on the object pool.
|
||||
|
||||
### Group wiki storage
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13195) in GitLab 13.5.
|
||||
|
||||
Unlike project wikis that are stored in the `@hashed` directory, group wikis are stored in a directory called `@groups`.
|
||||
Like project wikis, group wikis follow the hashed storage folder convention, but use a hash of the group ID rather than the project ID.
|
||||
|
||||
For example:
|
||||
|
||||
```ruby
|
||||
# group wiki paths
|
||||
"@groups/#{hash[0..1]}/#{hash[2..3]}/#{hash}.wiki.git"
|
||||
```
|
||||
|
||||
### Object storage support
|
||||
|
||||
This table shows which storable objects are storable in each storage type:
|
||||
|
|
|
@ -6,7 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# Deployment safety **(FREE)**
|
||||
|
||||
Deployment jobs can be more sensitive than other jobs in a pipeline,
|
||||
[Deployment jobs](../jobs/#deployment-jobs) are a specific kind of CI/CD
|
||||
job. They can be more sensitive than other jobs in a pipeline,
|
||||
and might need to be treated with extra care. GitLab has several features
|
||||
that help maintain deployment security and stability.
|
||||
|
||||
|
@ -64,14 +65,14 @@ For more information, see [Resource Group documentation](../resource_groups/inde
|
|||
|
||||
## Skip outdated deployment jobs
|
||||
|
||||
The execution order of pipeline jobs can vary from run to run, which could cause
|
||||
undesired behavior. For example, a deployment job in a newer pipeline could
|
||||
finish before a deployment job in an older pipeline.
|
||||
This creates a race condition where the older deployment finished later,
|
||||
The effective execution order of pipeline jobs can vary from run to run, which
|
||||
could cause undesired behavior. For example, a [deployment job](../jobs/#deployment-jobs)
|
||||
in a newer pipeline could finish before a deployment job in an older pipeline.
|
||||
This creates a race condition where the older deployment finishes later,
|
||||
overwriting the "newer" deployment.
|
||||
|
||||
You can ensure that older deployment jobs are cancelled automatically when a newer deployment
|
||||
runs by enabling the [Skip outdated deployment jobs](../pipelines/settings.md#skip-outdated-deployment-jobs) feature.
|
||||
job is started by enabling the [Skip outdated deployment jobs](../pipelines/settings.md#skip-outdated-deployment-jobs) feature.
|
||||
|
||||
Example of a problematic pipeline flow **before** enabling Skip outdated deployment jobs:
|
||||
|
||||
|
@ -85,7 +86,7 @@ The improved pipeline flow **after** enabling Skip outdated deployment jobs:
|
|||
1. Pipeline-A is created on the default branch.
|
||||
1. Later, Pipeline-B is created on the default branch (with a newer SHA).
|
||||
1. The `deploy` job in Pipeline-B finishes first, and deploys the newer code.
|
||||
1. The `deploy` job in Pipeline-A is automatically cancelled, so that it doesn't overwrite the deployment from the newer pipeline.
|
||||
1. The `deploy` job in Pipeline-A was automatically cancelled, so that it doesn't overwrite the deployment from the newer pipeline.
|
||||
|
||||
## Prevent deployments during deploy freeze windows
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
type: reference
|
||||
---
|
||||
|
||||
# Keyword reference for the `.gitlab-ci.yml` file **(FREE)**
|
||||
# `.gitlab-ci.yml` keyword reference **(FREE)**
|
||||
|
||||
This document lists the configuration options for your GitLab `.gitlab-ci.yml` file.
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ Jobs pass if they are able to complete a scan. A _pass_ result does NOT indicate
|
|||
|
||||
Jobs fail if they are unable to complete a scan. You can view the pipeline logs for more information.
|
||||
|
||||
All jobs are permitted to fail by default. This means that if they fail it do not fail the pipeline.
|
||||
All jobs are permitted to fail by default. This means that if they fail, it does not fail the pipeline.
|
||||
|
||||
If you want to prevent vulnerabilities from being merged, you should do this by adding [Security Approvals in Merge Requests](#security-approvals-in-merge-requests) which prevents unknown, high or critical findings from being merged without an approval from a specific group of people that you choose.
|
||||
|
||||
|
@ -171,7 +171,7 @@ reports are available to download. To download a report, select
|
|||
|
||||
A merge request contains a security widget which displays a summary of the NEW results. New results are determined by comparing the current findings against existing findings in the target (default) branch (if there are prior findings).
|
||||
|
||||
We recommended you run a scan of the `default` branch before enabling feature branch scans for your developers. Otherwise, there is no base for comparison and all feature branches display the full scan results in the merge request security widget.
|
||||
We recommend you run a scan of the `default` branch before enabling feature branch scans for your developers. Otherwise, there is no base for comparison and all feature branches display the full scan results in the merge request security widget.
|
||||
|
||||
The merge request security widget displays only a subset of the vulnerabilities in the generated JSON artifact because it contains both NEW and EXISTING findings.
|
||||
|
||||
|
@ -408,7 +408,7 @@ You can interact with the results of the security scanning tools in several loca
|
|||
|
||||
For more details about which findings or vulnerabilities you can view in each of those locations,
|
||||
select the respective link. Each page details the ways in which you can interact with the findings
|
||||
and vulnerabilities. As an example, in most cases findings start out as _detected_ status.
|
||||
and vulnerabilities. As an example, in most cases findings start out as a _detected_ status.
|
||||
|
||||
You have the option to:
|
||||
|
||||
|
@ -622,7 +622,7 @@ involve pinning to the previous template versions, for example:
|
|||
```
|
||||
|
||||
Additionally, we provide a dedicated project containing the versioned legacy templates.
|
||||
This can be used for offline setups or anyone wishing to use [Auto DevOps](../../topics/autodevops/index.md).
|
||||
This can be used for offline setups or for anyone wishing to use [Auto DevOps](../../topics/autodevops/index.md).
|
||||
|
||||
Instructions are available in the [legacy template project](https://gitlab.com/gitlab-org/auto-devops-v12-10).
|
||||
|
||||
|
|
|
@ -132,6 +132,8 @@ migrated:
|
|||
- image URL
|
||||
- Boards
|
||||
- Board Lists
|
||||
- Releases
|
||||
- Milestones ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/339422) in GitLab 15.0).
|
||||
|
||||
## Troubleshooting Group Migration
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
variables:
|
||||
SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"
|
||||
SECRET_DETECTION_IMAGE_SUFFIX: ""
|
||||
SECRETS_ANALYZER_VERSION: "3"
|
||||
SECRETS_ANALYZER_VERSION: "4"
|
||||
SECRET_DETECTION_EXCLUDED_PATHS: ""
|
||||
|
||||
.secret-analyzer:
|
||||
|
@ -33,37 +33,4 @@ secret_detection:
|
|||
when: never
|
||||
- if: $CI_COMMIT_BRANCH # If there's no open merge request, add it to a *branch* pipeline instead.
|
||||
script:
|
||||
- if [ -n "$CI_COMMIT_TAG" ]; then echo "Skipping Secret Detection for tags. No code changes have occurred."; exit 0; fi
|
||||
# Historic scan
|
||||
- if [ "$SECRET_DETECTION_HISTORIC_SCAN" == "true" ]; then echo "Running Secret Detection Historic Scan"; /analyzer run; exit; fi
|
||||
# Default branch scan
|
||||
- if [ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]; then echo "Running Secret Detection on default branch."; /analyzer run; exit; fi
|
||||
# Push event
|
||||
- |
|
||||
if [ "$CI_COMMIT_BEFORE_SHA" == "0000000000000000000000000000000000000000" ];
|
||||
then
|
||||
# first commit on a new branch
|
||||
echo ${CI_COMMIT_SHA} >${CI_COMMIT_SHA}_commit_list.txt
|
||||
git fetch --depth=2 origin $CI_COMMIT_REF_NAME
|
||||
else
|
||||
# determine commit range so that we can fetch the appropriate depth
|
||||
# check the exit code to determine if we need to limit the commit_list.txt to CI_COMMIT_SHA.
|
||||
if ! git log --pretty=format:"%H" ${CI_COMMIT_BEFORE_SHA}..${CI_COMMIT_SHA} >${CI_COMMIT_SHA}_commit_list.txt;
|
||||
then
|
||||
echo "unable to determine commit range, limiting to ${CI_COMMIT_SHA}"
|
||||
echo ${CI_COMMIT_SHA} >${CI_COMMIT_SHA}_commit_list.txt
|
||||
else
|
||||
# append newline to to list since `git log` does not end with a
|
||||
# newline, this is to keep the log messages consistent
|
||||
echo >> ${CI_COMMIT_SHA}_commit_list.txt
|
||||
fi
|
||||
|
||||
# we need to extend the git fetch depth to the number of commits + 1 for the following reasons:
|
||||
# to include the parent commit of the base commit in this MR/Push event. This is needed because
|
||||
# `git diff -p` needs something to compare changes in that commit against
|
||||
git fetch --depth=$(($(wc -l <${CI_COMMIT_SHA}_commit_list.txt) + 1)) origin $CI_COMMIT_REF_NAME
|
||||
fi
|
||||
echo "scanning $(($(wc -l <${CI_COMMIT_SHA}_commit_list.txt))) commits for a push event"
|
||||
export SECRET_DETECTION_COMMITS_FILE=${CI_COMMIT_SHA}_commit_list.txt
|
||||
- /analyzer run
|
||||
- rm "$CI_COMMIT_SHA"_commit_list.txt
|
||||
|
|
|
@ -170,6 +170,11 @@ module Gitlab
|
|||
Constants::COLOR_NAME_TO_HEX[color.downcase] || new(color)
|
||||
end
|
||||
|
||||
# Generate a hex color based on hex-encoded value
|
||||
def self.color_for(value)
|
||||
Color.new("##{Digest::SHA256.hexdigest(value.to_s)[0..5]}")
|
||||
end
|
||||
|
||||
def to_s
|
||||
@value.to_s
|
||||
end
|
||||
|
|
|
@ -158,7 +158,7 @@ class GroupSeeder
|
|||
group = Group.find(group_id)
|
||||
label_title = FFaker::Product.brand
|
||||
|
||||
Labels::CreateService.new(title: label_title, color: "##{Digest::MD5.hexdigest(label_title)[0..5]}").execute(group: group)
|
||||
Labels::CreateService.new(title: label_title, color: "#{::Gitlab::Color.color_for(label_title)}").execute(group: group)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,6 +24,48 @@ RSpec.describe Gitlab::Color do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.color_for' do
|
||||
subject { described_class.color_for(value) }
|
||||
|
||||
shared_examples 'deterministic' do
|
||||
it 'is deterministoc' do
|
||||
expect(subject.to_s).to eq(described_class.color_for(value).to_s)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when generating color for nil value' do
|
||||
let(:value) { nil }
|
||||
|
||||
specify { is_expected.to be_valid }
|
||||
|
||||
it_behaves_like 'deterministic'
|
||||
end
|
||||
|
||||
context 'when generating color for empty string value' do
|
||||
let(:value) { '' }
|
||||
|
||||
specify { is_expected.to be_valid }
|
||||
|
||||
it_behaves_like 'deterministic'
|
||||
end
|
||||
|
||||
context 'when generating color for number value' do
|
||||
let(:value) { 1 }
|
||||
|
||||
specify { is_expected.to be_valid }
|
||||
|
||||
it_behaves_like 'deterministic'
|
||||
end
|
||||
|
||||
context 'when generating color for string value' do
|
||||
let(:value) { "1" }
|
||||
|
||||
specify { is_expected.to be_valid }
|
||||
|
||||
it_behaves_like 'deterministic'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#new' do
|
||||
it 'handles nil values' do
|
||||
expect(described_class.new(nil)).to eq(described_class.new(nil))
|
||||
|
|
|
@ -3,11 +3,13 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe WorkItemPolicy do
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:public_project) { create(:project, :public) }
|
||||
let_it_be(:group) { create(:group) }
|
||||
let_it_be(:project) { create(:project, group: group) }
|
||||
let_it_be(:public_project) { create(:project, :public, group: group) }
|
||||
let_it_be(:guest) { create(:user).tap { |user| project.add_guest(user) } }
|
||||
let_it_be(:guest_author) { create(:user).tap { |user| project.add_guest(user) } }
|
||||
let_it_be(:reporter) { create(:user).tap { |user| project.add_reporter(user) } }
|
||||
let_it_be(:group_reporter) { create(:user).tap { |user| group.add_reporter(user) } }
|
||||
let_it_be(:non_member_user) { create(:user) }
|
||||
let_it_be(:work_item) { create(:work_item, project: project) }
|
||||
let_it_be(:authored_work_item) { create(:work_item, project: project, author: guest_author) }
|
||||
|
@ -81,7 +83,9 @@ RSpec.describe WorkItemPolicy do
|
|||
let(:work_item_subject) { work_item }
|
||||
let(:current_user) { reporter }
|
||||
|
||||
it { is_expected.to be_disallowed(:delete_work_item) }
|
||||
context 'when the user is not the author of the work item' do
|
||||
it { is_expected.to be_disallowed(:delete_work_item) }
|
||||
end
|
||||
|
||||
context 'when guest authored the work item' do
|
||||
let(:work_item_subject) { authored_work_item }
|
||||
|
@ -90,5 +94,35 @@ RSpec.describe WorkItemPolicy do
|
|||
it { is_expected.to be_allowed(:delete_work_item) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is member of the project\'s group' do
|
||||
let(:current_user) { group_reporter }
|
||||
|
||||
context 'when the user is not the author of the work item' do
|
||||
it { is_expected.to be_disallowed(:delete_work_item) }
|
||||
end
|
||||
|
||||
context 'when user authored the work item' do
|
||||
let(:work_item_subject) { create(:work_item, project: project, author: current_user) }
|
||||
|
||||
it { is_expected.to be_allowed(:delete_work_item) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not a member of the project' do
|
||||
let(:current_user) { non_member_user }
|
||||
|
||||
context 'when the user authored the work item' do
|
||||
let(:work_item_subject) { create(:work_item, project: public_project, author: current_user) }
|
||||
|
||||
it { is_expected.to be_disallowed(:delete_work_item) }
|
||||
end
|
||||
|
||||
context 'when the user is not the author of the work item' do
|
||||
let(:work_item_subject) { public_work_item }
|
||||
|
||||
it { is_expected.to be_disallowed(:delete_work_item) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue