Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-06-17 21:08:24 +00:00
parent 6b922f9bb0
commit 1b16af5ff9
34 changed files with 573 additions and 71 deletions

View file

@ -1 +1 @@
1.18.0
1.19.0

View file

@ -105,6 +105,7 @@ export const handleLocationHash = () => {
const topPadding = 8;
const diffFileHeader = document.querySelector('.js-file-title');
const versionMenusContainer = document.querySelector('.mr-version-menus-container');
const fixedIssuableTitle = document.querySelector('.issue-sticky-header');
let adjustment = 0;
if (fixedNav) adjustment -= fixedNav.offsetHeight;
@ -133,6 +134,10 @@ export const handleLocationHash = () => {
adjustment -= versionMenusContainer.offsetHeight;
}
if (isInIssuePage()) {
adjustment -= fixedIssuableTitle.offsetHeight;
}
if (isInMRPage()) {
adjustment -= topPadding;
}

View file

@ -21,7 +21,7 @@ module Mutations
description: 'File name of the snippet'
argument :content, GraphQL::STRING_TYPE,
required: true,
required: false,
description: 'Content of the snippet'
argument :description, GraphQL::STRING_TYPE,
@ -40,6 +40,10 @@ module Mutations
required: false,
description: 'The paths to files uploaded in the snippet description'
argument :files, [Types::Snippets::FileInputType],
description: "The snippet files to create",
required: false
def resolve(args)
project_path = args.delete(:project_path)
@ -49,13 +53,9 @@ module Mutations
raise_resource_not_available_error!
end
# We need to rename `uploaded_files` into `files` because
# it's the expected key param
args[:files] = args.delete(:uploaded_files)
service_response = ::Snippets::CreateService.new(project,
context[:current_user],
args).execute
context[:current_user],
create_params(args)).execute
snippet = service_response.payload[:snippet]
@ -82,6 +82,18 @@ module Mutations
def can_create_personal_snippet?
Ability.allowed?(context[:current_user], :create_snippet)
end
def create_params(args)
args.tap do |create_args|
# We need to rename `files` into `snippet_files` because
# it's the expected key param
create_args[:snippet_files] = create_args.delete(:files)&.map(&:to_h)
# We need to rename `uploaded_files` into `files` because
# it's the expected key param
create_args[:files] = create_args.delete(:uploaded_files)
end
end
end
end
end

View file

@ -675,10 +675,11 @@ class Project < ApplicationRecord
# '>' or its escaped form ('&gt;') are checked for because '>' is sometimes escaped
# when the reference comes from an external source.
def markdown_reference_pattern
%r{
#{reference_pattern}
(#{reference_postfix}|#{reference_postfix_escaped})
}x
@markdown_reference_pattern ||=
%r{
#{reference_pattern}
(#{reference_postfix}|#{reference_postfix_escaped})
}x
end
def trending

View file

@ -619,11 +619,12 @@ class User < ApplicationRecord
# Pattern used to extract `@user` user references from text
def reference_pattern
%r{
(?<!\w)
#{Regexp.escape(reference_prefix)}
(?<user>#{Gitlab::PathRegex::FULL_NAMESPACE_FORMAT_REGEX})
}x
@reference_pattern ||=
%r{
(?<!\w)
#{Regexp.escape(reference_prefix)}
(?<user>#{Gitlab::PathRegex::FULL_NAMESPACE_FORMAT_REGEX})
}x
end
# Return (create if necessary) the ghost user. The ghost user

View file

@ -95,7 +95,9 @@ class MergeRequestWidgetEntity < Grape::Entity
end
def can_add_ci_config_path?(merge_request)
merge_request.source_project&.uses_default_ci_config? &&
merge_request.open? &&
merge_request.source_branch_exists? &&
merge_request.source_project&.uses_default_ci_config? &&
!merge_request.source_project.has_ci? &&
merge_request.commits_count.positive? &&
can?(current_user, :read_build, merge_request.source_project) &&

View file

@ -12,7 +12,9 @@ module Snippets
super
@uploaded_assets = Array(@params.delete(:files).presence)
@snippet_files = SnippetInputActionCollection.new(Array(@params.delete(:snippet_files).presence))
input_actions = Array(@params.delete(:snippet_files).presence)
@snippet_files = SnippetInputActionCollection.new(input_actions, allowed_actions: restricted_files_actions)
filter_spam_check_params
end
@ -79,5 +81,9 @@ module Snippets
def build_actions_from_params(snippet)
raise NotImplementedError
end
def restricted_files_actions
nil
end
end
end

View file

@ -100,5 +100,9 @@ module Snippets
def build_actions_from_params(_snippet)
[{ file_path: params[:file_name], content: params[:content] }]
end
def restricted_files_actions
:create
end
end
end

View file

@ -15,7 +15,7 @@
.form-group
.form-text
%p.text-secondary
= _('Select a weight for the storage new repositories will be placed on.')
= _('Enter weights for storages for new repositories.')
= link_to icon('question-circle'), help_page_path('administration/repository_storage_paths')
.form-check
- storage_weights.each do |attribute|

View file

@ -0,0 +1,5 @@
---
title: Drop deprecated **_ANALYZER_IMAGE_PREFIX
merge_request: 34325
author:
type: removed

View file

@ -0,0 +1,5 @@
---
title: Add :section to approval_merge_request_rule unique index
merge_request: 34680
author:
type: other

View file

@ -0,0 +1,5 @@
---
title: Fix Issue sticky title URL hash offset
merge_request: 34764
author:
type: fixed

View file

@ -0,0 +1,5 @@
---
title: Add node ci template
merge_request: 25668
author:
type: other

View file

@ -0,0 +1,5 @@
---
title: Add files argument to snippet create mutation
merge_request: 34449
author:
type: changed

View file

@ -0,0 +1,5 @@
---
title: Adjust verbiage on repository storages settings page
merge_request: 34675
author:
type: changed

View file

@ -0,0 +1,5 @@
---
title: Upgrade GitLab Pages to 1.19.0
merge_request: 34730
author:
type: added

View file

@ -10,7 +10,9 @@ def get_vue_files_with_ce_and_ee_versions(files)
"ee/#{file}"
end
response = gitlab.api.get_file(gitlab.mr_json['project_id'], counterpart_path, 'master')
escaped_path = CGI.escape(counterpart_path)
api_endpoint = "https://gitlab.com/api/v4/projects/gitlab-org%2Fgitlab-ee/repository/files/#{escaped_path}?ref=master"
response = HTTParty.get(api_endpoint) # rubocop:disable Gitlab/HTTParty
response.code != 404
else
false

View file

@ -0,0 +1,116 @@
# frozen_string_literal: true
class UpdateIndexApprovalRuleNameForCodeOwnersRuleType < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
LEGACY_INDEX_NAME_RULE_TYPE = "index_approval_rule_name_for_code_owners_rule_type"
LEGACY_INDEX_NAME_CODE_OWNERS = "approval_rule_name_index_for_code_owners"
SECTIONAL_INDEX_NAME = "index_approval_rule_name_for_sectional_code_owners_rule_type"
CODE_OWNER_RULE_TYPE = 2
def up
unless index_exists_by_name?(:approval_merge_request_rules, SECTIONAL_INDEX_NAME)
# Ensure only 1 code_owner rule with the same name and section per merge_request
#
add_concurrent_index(
:approval_merge_request_rules,
[:merge_request_id, :name, :section],
unique: true,
where: "rule_type = #{CODE_OWNER_RULE_TYPE}",
name: SECTIONAL_INDEX_NAME
)
end
remove_concurrent_index_by_name :approval_merge_request_rules, LEGACY_INDEX_NAME_RULE_TYPE
remove_concurrent_index_by_name :approval_merge_request_rules, LEGACY_INDEX_NAME_CODE_OWNERS
add_concurrent_index(
:approval_merge_request_rules,
[:merge_request_id, :name],
unique: true,
where: "rule_type = #{CODE_OWNER_RULE_TYPE} AND section IS NULL",
name: LEGACY_INDEX_NAME_RULE_TYPE
)
add_concurrent_index(
:approval_merge_request_rules,
[:merge_request_id, :code_owner, :name],
unique: true,
where: "code_owner = true AND section IS NULL",
name: LEGACY_INDEX_NAME_CODE_OWNERS
)
end
def down
# In a rollback situation, we can't guarantee that there will not be
# records that were allowed under the more specific SECTIONAL_INDEX_NAME
# index but would cause uniqueness violations under both the
# LEGACY_INDEX_NAME_RULE_TYPE and LEGACY_INDEX_NAME_CODE_OWNERS indices.
# Therefore, we need to first find all the MergeRequests with
# ApprovalMergeRequestRules that would violate these "new" indices and
# delete those approval rules, then create the new index, then finally
# recreate the approval rules for those merge requests.
#
# First, find all MergeRequests with ApprovalMergeRequestRules that will
# violate the new index.
#
if Gitlab.ee?
merge_request_ids = ApprovalMergeRequestRule
.select(:merge_request_id)
.where(rule_type: CODE_OWNER_RULE_TYPE)
.group(:merge_request_id, :rule_type, :name)
.includes(:merge_request)
.having("count(*) > 1")
.collect(&:merge_request_id)
# Delete ALL their code_owner approval rules
#
merge_request_ids.each_slice(10) do |ids|
ApprovalMergeRequestRule.where(merge_request_id: ids).code_owner.delete_all
end
end
# Remove legacy partial indices that only apply to `section IS NULL` records
#
remove_concurrent_index_by_name :approval_merge_request_rules, LEGACY_INDEX_NAME_RULE_TYPE
remove_concurrent_index_by_name :approval_merge_request_rules, LEGACY_INDEX_NAME_CODE_OWNERS
# Reconstruct original "legacy" indices
#
add_concurrent_index(
:approval_merge_request_rules,
[:merge_request_id, :name],
unique: true,
where: "rule_type = #{CODE_OWNER_RULE_TYPE}",
name: LEGACY_INDEX_NAME_RULE_TYPE
)
add_concurrent_index(
:approval_merge_request_rules,
[:merge_request_id, :code_owner, :name],
unique: true,
where: "code_owner = true",
name: LEGACY_INDEX_NAME_CODE_OWNERS
)
# MergeRequest::SyncCodeOwnerApprovalRules recreates the code_owner rules
# from scratch, adding them to the index. Duplicates will be rejected.
#
if Gitlab.ee?
merge_request_ids.each_slice(10) do |ids|
MergeRequest.where(id: ids).each do |merge_request|
MergeRequests::SyncCodeOwnerApprovalRules.new(merge_request).execute
end
end
end
remove_concurrent_index_by_name :approval_merge_request_rules, SECTIONAL_INDEX_NAME
end
end

View file

@ -9163,7 +9163,7 @@ CREATE UNIQUE INDEX any_approver_merge_request_rule_type_unique_index ON public.
CREATE UNIQUE INDEX any_approver_project_rule_type_unique_index ON public.approval_project_rules USING btree (project_id) WHERE (rule_type = 3);
CREATE UNIQUE INDEX approval_rule_name_index_for_code_owners ON public.approval_merge_request_rules USING btree (merge_request_id, code_owner, name) WHERE (code_owner = true);
CREATE UNIQUE INDEX approval_rule_name_index_for_code_owners ON public.approval_merge_request_rules USING btree (merge_request_id, code_owner, name) WHERE ((code_owner = true) AND (section IS NULL));
CREATE INDEX ci_builds_gitlab_monitor_metrics ON public.ci_builds USING btree (status, created_at, project_id) WHERE ((type)::text = 'Ci::Build'::text);
@ -9341,7 +9341,9 @@ CREATE UNIQUE INDEX index_approval_project_rules_users_1 ON public.approval_proj
CREATE INDEX index_approval_project_rules_users_2 ON public.approval_project_rules_users USING btree (user_id);
CREATE UNIQUE INDEX index_approval_rule_name_for_code_owners_rule_type ON public.approval_merge_request_rules USING btree (merge_request_id, name) WHERE (rule_type = 2);
CREATE UNIQUE INDEX index_approval_rule_name_for_code_owners_rule_type ON public.approval_merge_request_rules USING btree (merge_request_id, name) WHERE ((rule_type = 2) AND (section IS NULL));
CREATE UNIQUE INDEX index_approval_rule_name_for_sectional_code_owners_rule_type ON public.approval_merge_request_rules USING btree (merge_request_id, name, section) WHERE (rule_type = 2);
CREATE INDEX index_approval_rules_code_owners_rule_type ON public.approval_merge_request_rules USING btree (merge_request_id) WHERE (rule_type = 2);
@ -13956,6 +13958,7 @@ COPY "schema_migrations" (version) FROM STDIN;
20200526153844
20200526164946
20200526164947
20200526231421
20200527092027
20200527094322
20200527095401

View file

@ -1824,7 +1824,7 @@ input CreateSnippetInput {
"""
Content of the snippet
"""
content: String!
content: String
"""
Description of the snippet
@ -1836,6 +1836,11 @@ input CreateSnippetInput {
"""
fileName: String
"""
The snippet files to create
"""
files: [SnippetFileInputType!]
"""
The project full path the snippet is associated with
"""

View file

@ -4825,13 +4825,9 @@
"name": "content",
"description": "Content of the snippet",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
@ -4887,6 +4883,24 @@
},
"defaultValue": null
},
{
"name": "files",
"description": "The snippet files to create",
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "INPUT_OBJECT",
"name": "SnippetFileInputType",
"ofType": null
}
}
},
"defaultValue": null
},
{
"name": "clientMutationId",
"description": "A unique identifier for the client performing the mutation.",

View file

@ -750,6 +750,15 @@ _Internal_ refers to documentation in the same project. When linking to document
separate projects (for example, linking to Omnibus docs from GitLab docs), you must use absolute
URLs.
Do not use absolute URLs like `https://docs.gitlab.com/ee/index.html` to crosslink
to other docs within the same project. Use relative links to the file, like `../index.md`. (These are converted to HTML when the site is rendered.)
Relative linking enables crosslinks to work:
- in Review Apps, local previews, and `/help`.
- when working on the docs locally, so you can verify that they work as early as possible in the process.
- within the GitLab UI when browsing doc files in their respective repositories. For example, the links displayed at <https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/README.md>.
To link to internal documentation:
- Use relative links to Markdown files in the same repository.

View file

@ -151,7 +151,6 @@ The following variables allow configuration of global dependency scanning settin
| Environment variable | Description |
| --------------------------------------- |------------ |
| `SECURE_ANALYZERS_PREFIX` | Override the name of the Docker registry providing the official default images (proxy). Read more about [customizing analyzers](analyzers.md). |
| `DS_ANALYZER_IMAGE_PREFIX` | **DEPRECATED:** Use `SECURE_ANALYZERS_PREFIX` instead. |
| `DS_DEFAULT_ANALYZERS` | Override the names of the official default images. Read more about [customizing analyzers](analyzers.md). |
| `DS_DISABLE_DIND` | Disable Docker-in-Docker and run analyzers [individually](#enabling-docker-in-docker). This variable is `true` by default. |
| `ADDITIONAL_CA_CERT_BUNDLE` | Bundle of CA certs to trust. |
@ -428,14 +427,14 @@ For details on saving and transporting Docker images as a file, see Docker's doc
### Set Dependency Scanning CI job variables to use local Dependency Scanning analyzers
Add the following configuration to your `.gitlab-ci.yml` file. You must replace
`DS_ANALYZER_IMAGE_PREFIX` to refer to your local Docker container registry:
`SECURE_ANALYZERS_PREFIX` to refer to your local Docker container registry:
```yaml
include:
- template: Dependency-Scanning.gitlab-ci.yml
variables:
DS_ANALYZER_IMAGE_PREFIX: "docker-registry.example.com/analyzers"
SECURE_ANALYZERS_PREFIX: "docker-registry.example.com/analyzers"
GEMNASIUM_DB_REMOTE_URL: "gitlab.example.com/gemnasium-db.git"
GIT_SSL_NO_VERIFY: "true"
```

View file

@ -278,7 +278,6 @@ The following are Docker image-related variables.
| Environment variable | Description |
|------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `SECURE_ANALYZERS_PREFIX` | Override the name of the Docker registry providing the default images (proxy). Read more about [customizing analyzers](analyzers.md). |
| `SAST_ANALYZER_IMAGE_PREFIX` | **DEPRECATED**: Use `SECURE_ANALYZERS_PREFIX` instead. |
| `SAST_ANALYZER_IMAGE_TAG` | **DEPRECATED:** Override the Docker tag of the default images. Read more about [customizing analyzers](analyzers.md). |
| `SAST_DEFAULT_ANALYZERS` | Override the names of default images. Read more about [customizing analyzers](analyzers.md). |
| `SAST_DISABLE_DIND` | Disable Docker-in-Docker and run analyzers [individually](#enabling-docker-in-docker). This variable is `true` by default. |
@ -509,7 +508,7 @@ For details on saving and transporting Docker images as a file, see Docker's doc
### Set SAST CI job variables to use local SAST analyzers
Add the following configuration to your `.gitlab-ci.yml` file. You must replace
`SAST_ANALYZER_IMAGE_PREFIX` to refer to your local Docker container registry:
`SECURE_ANALYZERS_PREFIX` to refer to your local Docker container registry:
```yaml
include:

View file

@ -9,9 +9,6 @@ variables:
# (SAST, Dependency Scanning, ...)
SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
# Deprecated, use SECURE_ANALYZERS_PREFIX instead
DS_ANALYZER_IMAGE_PREFIX: "$SECURE_ANALYZERS_PREFIX"
DS_DEFAULT_ANALYZERS: "bundler-audit, retire.js, gemnasium, gemnasium-maven, gemnasium-python"
DS_EXCLUDED_PATHS: "spec, test, tests, tmp"
DS_MAJOR_VERSION: 2
@ -45,7 +42,7 @@ dependency_scanning:
docker run \
$(propagate_env_vars \
DS_ANALYZER_IMAGES \
DS_ANALYZER_IMAGE_PREFIX \
SECURE_ANALYZERS_PREFIX \
DS_ANALYZER_IMAGE_TAG \
DS_DEFAULT_ANALYZERS \
DS_EXCLUDED_PATHS \
@ -98,7 +95,7 @@ dependency_scanning:
gemnasium-dependency_scanning:
extends: .ds-analyzer
image:
name: "$DS_ANALYZER_IMAGE_PREFIX/gemnasium:$DS_MAJOR_VERSION"
name: "$SECURE_ANALYZERS_PREFIX/gemnasium:$DS_MAJOR_VERSION"
rules:
- if: $DEPENDENCY_SCANNING_DISABLED || $DS_DISABLE_DIND == 'false'
when: never
@ -117,7 +114,7 @@ gemnasium-dependency_scanning:
gemnasium-maven-dependency_scanning:
extends: .ds-analyzer
image:
name: "$DS_ANALYZER_IMAGE_PREFIX/gemnasium-maven:$DS_MAJOR_VERSION"
name: "$SECURE_ANALYZERS_PREFIX/gemnasium-maven:$DS_MAJOR_VERSION"
rules:
- if: $DEPENDENCY_SCANNING_DISABLED || $DS_DISABLE_DIND == 'false'
when: never
@ -133,7 +130,7 @@ gemnasium-maven-dependency_scanning:
gemnasium-python-dependency_scanning:
extends: .ds-analyzer
image:
name: "$DS_ANALYZER_IMAGE_PREFIX/gemnasium-python:$DS_MAJOR_VERSION"
name: "$SECURE_ANALYZERS_PREFIX/gemnasium-python:$DS_MAJOR_VERSION"
rules:
- if: $DEPENDENCY_SCANNING_DISABLED || $DS_DISABLE_DIND == 'false'
when: never
@ -156,7 +153,7 @@ gemnasium-python-dependency_scanning:
bundler-audit-dependency_scanning:
extends: .ds-analyzer
image:
name: "$DS_ANALYZER_IMAGE_PREFIX/bundler-audit:$DS_MAJOR_VERSION"
name: "$SECURE_ANALYZERS_PREFIX/bundler-audit:$DS_MAJOR_VERSION"
rules:
- if: $DEPENDENCY_SCANNING_DISABLED || $DS_DISABLE_DIND == 'false'
when: never
@ -169,7 +166,7 @@ bundler-audit-dependency_scanning:
retire-js-dependency_scanning:
extends: .ds-analyzer
image:
name: "$DS_ANALYZER_IMAGE_PREFIX/retire.js:$DS_MAJOR_VERSION"
name: "$SECURE_ANALYZERS_PREFIX/retire.js:$DS_MAJOR_VERSION"
rules:
- if: $DEPENDENCY_SCANNING_DISABLED || $DS_DISABLE_DIND == 'false'
when: never

View file

@ -9,9 +9,6 @@ variables:
# (SAST, Dependency Scanning, ...)
SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
# Deprecated, use SECURE_ANALYZERS_PREFIX instead
SAST_ANALYZER_IMAGE_PREFIX: "$SECURE_ANALYZERS_PREFIX"
SAST_DEFAULT_ANALYZERS: "bandit, brakeman, gosec, spotbugs, flawfinder, phpcs-security-audit, security-code-scan, nodejs-scan, eslint, tslint, secrets, sobelow, pmd-apex, kubesec"
SAST_EXCLUDED_PATHS: "spec, test, tests, tmp"
SAST_ANALYZER_IMAGE_TAG: 2
@ -63,7 +60,7 @@ sast:
bandit-sast:
extends: .sast-analyzer
image:
name: "$SAST_ANALYZER_IMAGE_PREFIX/bandit:$SAST_ANALYZER_IMAGE_TAG"
name: "$SECURE_ANALYZERS_PREFIX/bandit:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@ -76,7 +73,7 @@ bandit-sast:
brakeman-sast:
extends: .sast-analyzer
image:
name: "$SAST_ANALYZER_IMAGE_PREFIX/brakeman:$SAST_ANALYZER_IMAGE_TAG"
name: "$SECURE_ANALYZERS_PREFIX/brakeman:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@ -88,7 +85,7 @@ brakeman-sast:
eslint-sast:
extends: .sast-analyzer
image:
name: "$SAST_ANALYZER_IMAGE_PREFIX/eslint:$SAST_ANALYZER_IMAGE_TAG"
name: "$SECURE_ANALYZERS_PREFIX/eslint:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@ -102,7 +99,7 @@ eslint-sast:
flawfinder-sast:
extends: .sast-analyzer
image:
name: "$SAST_ANALYZER_IMAGE_PREFIX/flawfinder:$SAST_ANALYZER_IMAGE_TAG"
name: "$SECURE_ANALYZERS_PREFIX/flawfinder:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@ -116,7 +113,7 @@ flawfinder-sast:
kubesec-sast:
extends: .sast-analyzer
image:
name: "$SAST_ANALYZER_IMAGE_PREFIX/kubesec:$SAST_ANALYZER_IMAGE_TAG"
name: "$SECURE_ANALYZERS_PREFIX/kubesec:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@ -128,7 +125,7 @@ kubesec-sast:
gosec-sast:
extends: .sast-analyzer
image:
name: "$SAST_ANALYZER_IMAGE_PREFIX/gosec:$SAST_ANALYZER_IMAGE_TAG"
name: "$SECURE_ANALYZERS_PREFIX/gosec:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@ -141,7 +138,7 @@ gosec-sast:
nodejs-scan-sast:
extends: .sast-analyzer
image:
name: "$SAST_ANALYZER_IMAGE_PREFIX/nodejs-scan:$SAST_ANALYZER_IMAGE_TAG"
name: "$SECURE_ANALYZERS_PREFIX/nodejs-scan:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@ -154,7 +151,7 @@ nodejs-scan-sast:
phpcs-security-audit-sast:
extends: .sast-analyzer
image:
name: "$SAST_ANALYZER_IMAGE_PREFIX/phpcs-security-audit:$SAST_ANALYZER_IMAGE_TAG"
name: "$SECURE_ANALYZERS_PREFIX/phpcs-security-audit:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@ -167,7 +164,7 @@ phpcs-security-audit-sast:
pmd-apex-sast:
extends: .sast-analyzer
image:
name: "$SAST_ANALYZER_IMAGE_PREFIX/pmd-apex:$SAST_ANALYZER_IMAGE_TAG"
name: "$SECURE_ANALYZERS_PREFIX/pmd-apex:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@ -180,7 +177,7 @@ pmd-apex-sast:
secrets-sast:
extends: .sast-analyzer
image:
name: "$SAST_ANALYZER_IMAGE_PREFIX/secrets:$SAST_ANALYZER_IMAGE_TAG"
name: "$SECURE_ANALYZERS_PREFIX/secrets:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@ -191,7 +188,7 @@ secrets-sast:
security-code-scan-sast:
extends: .sast-analyzer
image:
name: "$SAST_ANALYZER_IMAGE_PREFIX/security-code-scan:$SAST_ANALYZER_IMAGE_TAG"
name: "$SECURE_ANALYZERS_PREFIX/security-code-scan:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@ -205,7 +202,7 @@ security-code-scan-sast:
sobelow-sast:
extends: .sast-analyzer
image:
name: "$SAST_ANALYZER_IMAGE_PREFIX/sobelow:$SAST_ANALYZER_IMAGE_TAG"
name: "$SECURE_ANALYZERS_PREFIX/sobelow:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@ -218,7 +215,7 @@ sobelow-sast:
spotbugs-sast:
extends: .sast-analyzer
image:
name: "$SAST_ANALYZER_IMAGE_PREFIX/spotbugs:$SAST_ANALYZER_IMAGE_TAG"
name: "$SECURE_ANALYZERS_PREFIX/spotbugs:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@ -233,7 +230,7 @@ spotbugs-sast:
tslint-sast:
extends: .sast-analyzer
image:
name: "$SAST_ANALYZER_IMAGE_PREFIX/tslint:$SAST_ANALYZER_IMAGE_TAG"
name: "$SECURE_ANALYZERS_PREFIX/tslint:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never

View file

@ -0,0 +1,29 @@
image: node:latest
create_npmrc:
stage: build
script:
- |
if [ ! -f .npmrc ]; then
echo 'No .npmrc found! Creating one now. Please review the following link for more information: https://docs.gitlab.com/ee/user/packages/npm_registry/index.html#authenticating-with-a-ci-job-token'
echo "@${CI_PROJECT_NAMESPACE%%/*}:registry=\${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/" >> .npmrc
echo '//gitlab.com/api/v4/packages/npm/:_authToken=${CI_JOB_TOKEN}' >> .npmrc
echo '//gitlab.com/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN}' >> .npmrc
fi
artifacts:
paths:
- .npmrc
publish_package:
stage: deploy
script:
- export NPM_PACKAGE_NAME=$(node -p "require('./package.json').name")
- export NPM_PACKAGE_VERSION=$(node -p "require('./package.json').version")
- |
{
npm publish &&
echo "Successfully published version $NPM_PACKAGE_VERSION of $NPM_PACKAGE_NAME to GitLab's NPM registry."
} || {
echo "No new version of $NPM_PACKAGE_NAME published. This is most likely because version $NPM_PACKAGE_VERSION already exists in GitLab's NPM registry."
}

View file

@ -8543,6 +8543,9 @@ msgstr ""
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
msgid "Enter weights for storages for new repositories."
msgstr ""
msgid "Enter your password to approve"
msgstr ""
@ -20040,9 +20043,6 @@ msgstr ""
msgid "Select a timezone"
msgstr ""
msgid "Select a weight for the storage new repositories will be placed on."
msgstr ""
msgid "Select all"
msgstr ""

View file

@ -576,7 +576,10 @@ describe('RepoEditor', () => {
});
});
it('adds an image entry to the same folder for a pasted image in a markdown file', () => {
// The following test is flaky
// see https://gitlab.com/gitlab-org/gitlab/-/issues/221039
// eslint-disable-next-line jest/no-disabled-tests
it.skip('adds an image entry to the same folder for a pasted image in a markdown file', () => {
pasteImage();
return waitForPromises().then(() => {

View file

@ -134,7 +134,7 @@ describe Gitlab::Ci::Pipeline::Seed::Build::Cache do
it_behaves_like 'foo/bar directory key'
end
context 'with directories ending in slash star', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/222356' do
context 'with directories ending in slash star' do
let(:files) { ['foo/bar/*'] }
it_behaves_like 'foo/bar directory key'

View file

@ -0,0 +1,178 @@
# frozen_string_literal: true
require 'spec_helper'
require Rails.root.join('db', 'migrate', '20200526231421_update_index_approval_rule_name_for_code_owners_rule_type.rb')
describe UpdateIndexApprovalRuleNameForCodeOwnersRuleType do
let(:migration) { described_class.new }
let(:approval_rules) { table(:approval_merge_request_rules) }
let(:namespace) { table(:namespaces).create!(name: 'gitlab', path: 'gitlab') }
let(:project) do
table(:projects).create!(
namespace_id: namespace.id,
name: 'gitlab',
path: 'gitlab'
)
end
let(:merge_request) do
table(:merge_requests).create!(
target_project_id: project.id,
source_project_id: project.id,
target_branch: 'feature',
source_branch: 'master'
)
end
let(:index_names) do
ActiveRecord::Base.connection
.indexes(:approval_merge_request_rules)
.collect(&:name)
end
def create_sectional_approval_rules
approval_rules.create!(
merge_request_id: merge_request.id,
name: "*.rb",
code_owner: true,
rule_type: 2,
section: "First Section"
)
approval_rules.create!(
merge_request_id: merge_request.id,
name: "*.rb",
code_owner: true,
rule_type: 2,
section: "Second Section"
)
end
def create_two_matching_nil_section_approval_rules
2.times do
approval_rules.create!(
merge_request_id: merge_request.id,
name: "nil_section",
code_owner: true,
rule_type: 2
)
end
end
before do
approval_rules.delete_all
end
describe "#up" do
it "creates the new index and removes the 'legacy' indices" do
# Confirm that existing legacy indices prevent duplicate entries
#
expect { create_sectional_approval_rules }
.to raise_exception(ActiveRecord::RecordNotUnique)
expect { create_two_matching_nil_section_approval_rules }
.to raise_exception(ActiveRecord::RecordNotUnique)
approval_rules.delete_all
disable_migrations_output { migrate! }
# After running the migration, expect `section == nil` rules to still
# be blocked by the legacy indices, but sectional rules are allowed.
#
expect { create_sectional_approval_rules }
.to change { approval_rules.count }.by(2)
expect { create_two_matching_nil_section_approval_rules }
.to raise_exception(ActiveRecord::RecordNotUnique)
# Attempt to rerun the creation of sectional rules, and see that sectional
# rules are unique by section
#
expect { create_sectional_approval_rules }
.to raise_exception(ActiveRecord::RecordNotUnique)
expect(index_names).to include(
described_class::SECTIONAL_INDEX_NAME,
described_class::LEGACY_INDEX_NAME_RULE_TYPE,
described_class::LEGACY_INDEX_NAME_CODE_OWNERS
)
end
end
describe "#down" do
context "run as FOSS" do
before do
expect(Gitlab).to receive(:ee?).twice.and_return(false)
end
it "recreates legacy indices, but does not invoke EE-specific code" do
disable_migrations_output { migrate! }
expect(index_names).to include(
described_class::SECTIONAL_INDEX_NAME,
described_class::LEGACY_INDEX_NAME_RULE_TYPE,
described_class::LEGACY_INDEX_NAME_CODE_OWNERS
)
# Since ApprovalMergeRequestRules are EE-specific, we expect none to
# be deleted during the migration.
#
expect { disable_migrations_output { migration.down } }
.not_to change { approval_rules.count }
index_names = ActiveRecord::Base.connection
.indexes(:approval_merge_request_rules)
.collect(&:name)
expect(index_names).not_to include(described_class::SECTIONAL_INDEX_NAME)
expect(index_names).to include(
described_class::LEGACY_INDEX_NAME_RULE_TYPE,
described_class::LEGACY_INDEX_NAME_CODE_OWNERS
)
end
end
context "EE" do
it "recreates 'legacy' indices and removes duplicate code owner approval rules" do
skip("This test is skipped under FOSS") unless Gitlab.ee?
disable_migrations_output { migrate! }
expect { create_sectional_approval_rules }
.to change { approval_rules.count }.by(2)
expect { create_two_matching_nil_section_approval_rules }
.to raise_exception(ActiveRecord::RecordNotUnique)
# Run the down migration. This will remove the 2 approval rules we create
# above, and call MergeRequests::SyncCodeOwnerApprovalRules to recreate
# new ones.
#
expect(MergeRequests::SyncCodeOwnerApprovalRules)
.to receive(:new).with(MergeRequest.find(merge_request.id)).once.and_call_original
# We expect approval_rules.count to be changed by -2 as we're deleting the
# 3 rules created above, and MergeRequests::SyncCodeOwnerApprovalRules
# will not be able to create new one with an empty (or missing)
# CODEOWNERS file.
#
expect { disable_migrations_output { migration.down } }
.to change { approval_rules.count }.by(-3)
# Test that the index does not allow us to create the same rules as the
# previous sectional index.
#
expect { create_sectional_approval_rules }
.to raise_exception(ActiveRecord::RecordNotUnique)
expect { create_two_matching_nil_section_approval_rules }
.to raise_exception(ActiveRecord::RecordNotUnique)
expect(index_names).not_to include(described_class::SECTIONAL_INDEX_NAME)
expect(index_names).to include(
described_class::LEGACY_INDEX_NAME_RULE_TYPE,
described_class::LEGACY_INDEX_NAME_CODE_OWNERS
)
end
end
end
end

View file

@ -14,9 +14,8 @@ describe 'Creating a Snippet' do
let(:visibility_level) { 'public' }
let(:project_path) { nil }
let(:uploaded_files) { nil }
let(:mutation) do
variables = {
let(:mutation_vars) do
{
content: content,
description: description,
visibility_level: visibility_level,
@ -25,8 +24,10 @@ describe 'Creating a Snippet' do
project_path: project_path,
uploaded_files: uploaded_files
}
end
graphql_mutation(:create_snippet, variables)
let(:mutation) do
graphql_mutation(:create_snippet, mutation_vars)
end
def mutation_response
@ -137,6 +138,47 @@ describe 'Creating a Snippet' do
end
end
context 'when snippet is created using the files param' do
let(:action) { :create }
let(:file_1) { { filePath: 'example_file1', content: 'This is the example file 1' }}
let(:file_2) { { filePath: 'example_file2', content: 'This is the example file 2' }}
let(:actions) { [{ action: action }.merge(file_1), { action: action }.merge(file_2)] }
let(:mutation_vars) do
{
description: description,
visibility_level: visibility_level,
project_path: project_path,
title: title,
files: actions
}
end
it 'creates the Snippet' do
expect do
subject
end.to change { Snippet.count }.by(1)
end
it 'returns the created Snippet' do
subject
expect(mutation_response['snippet']['title']).to eq(title)
expect(mutation_response['snippet']['description']).to eq(description)
expect(mutation_response['snippet']['visibilityLevel']).to eq(visibility_level)
expect(mutation_response['snippet']['blobs'][0]['plainData']).to match(file_1[:content])
expect(mutation_response['snippet']['blobs'][0]['fileName']).to match(file_1[:file_path])
expect(mutation_response['snippet']['blobs'][1]['plainData']).to match(file_2[:content])
expect(mutation_response['snippet']['blobs'][1]['fileName']).to match(file_2[:file_path])
end
context 'when action is invalid' do
let(:file_1) { { filePath: 'example_file1' }}
it_behaves_like 'a mutation that returns errors in the response', errors: ['Snippet files have invalid data']
it_behaves_like 'does not create snippet'
end
end
context 'when there are ActiveRecord validation errors' do
let(:title) { '' }

View file

@ -155,6 +155,36 @@ describe MergeRequestWidgetEntity do
expect(subject[:merge_request_add_ci_config_path]).to be_nil
end
end
context 'when merge request is merged' do
before do
resource.mark_as_merged!
end
it 'returns a blank ci config path' do
expect(subject[:merge_request_add_ci_config_path]).to be_nil
end
end
context 'when merge request is closed' do
before do
resource.close!
end
it 'returns a blank ci config path' do
expect(subject[:merge_request_add_ci_config_path]).to be_nil
end
end
context 'when source branch does not exist' do
before do
resource.source_project.repository.rm_branch(user, resource.source_branch)
end
it 'returns a blank ci config path' do
expect(subject[:merge_request_add_ci_config_path]).to be_nil
end
end
end
context 'when user does not have permissions' do

View file

@ -283,6 +283,19 @@ describe Snippets::CreateService do
expect(snippet.repository.exists?).to be_falsey
end
end
context 'when snippet_files contain an action different from "create"' do
let(:snippet_files) { [{ action: 'delete', file_path: 'snippet_file_path.rb' }] }
it 'a validation error is raised' do
response = subject
snippet = response.payload[:snippet]
expect(response).to be_error
expect(snippet.errors.full_messages_for(:snippet_files)).to eq ['Snippet files have invalid data']
expect(snippet.repository.exists?).to be_falsey
end
end
end
context 'when ProjectSnippet' do