Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-04-28 12:24:19 +00:00
parent 70c1d0352e
commit 72cb3bee79
59 changed files with 439 additions and 259 deletions

View File

@ -165,6 +165,7 @@ variables:
RSPEC_PACKED_TESTS_MAPPING_PATH: crystalball/packed-mapping.json
RSPEC_PROFILING_FOLDER_PATH: rspec/profiling
RSPEC_TESTS_MAPPING_PATH: crystalball/mapping.json
RSPEC_FAST_QUARANTINE_PATH: rspec/fast_quarantine-gitlab.txt
TMP_TEST_FOLDER: "${CI_PROJECT_DIR}/tmp/tests"
TMP_TEST_GITLAB_WORKHORSE_PATH: "${TMP_TEST_FOLDER}/${GITLAB_WORKHORSE_FOLDER}"
@ -173,7 +174,6 @@ variables:
CACHE_CLASSES: "true"
CHECK_PRECOMPILED_ASSETS: "true"
FF_USE_FASTZIP: "true"
SKIP_FLAKY_TESTS_AUTOMATICALLY: "false"
RETRY_FAILED_TESTS_IN_NEW_PROCESS: "true"
# Run with decomposed databases by default
DECOMPOSED_DB: "true"

View File

@ -1915,7 +1915,7 @@
when: never
- <<: *if-merge-request-labels-pipeline-expedite
when: never
- if: '$SKIP_FLAKY_TESTS_AUTOMATICALLY != "true" && $RETRY_FAILED_TESTS_IN_NEW_PROCESS != "true"'
- if: '$FAST_QUARANTINE == "false" && $RETRY_FAILED_TESTS_IN_NEW_PROCESS != "true"'
when: never
- <<: *if-merge-request
changes: *code-backstage-patterns

View File

@ -5007,7 +5007,7 @@ Layout/LineLength:
- 'spec/support/database/prevent_cross_database_modification.rb'
- 'spec/support/database/prevent_cross_joins.rb'
- 'spec/support/db_cleaner.rb'
- 'spec/support/flaky_tests.rb'
- 'spec/support/fast_quarantine.rb'
- 'spec/support/helpers/api_helpers.rb'
- 'spec/support/helpers/board_helpers.rb'
- 'spec/support/helpers/cycle_analytics_helpers.rb'

View File

@ -1044,7 +1044,7 @@ Style/IfUnlessModifier:
- 'spec/spec_helper.rb'
- 'spec/support/capybara.rb'
- 'spec/support/external_authorization_service_helpers.rb'
- 'spec/support/flaky_tests.rb'
- 'spec/support/fast_quarantine.rb'
- 'spec/support/generate-seed-repo-rb'
- 'spec/support/helpers/filter_spec_helper.rb'
- 'spec/support/helpers/filtered_search_helpers.rb'

View File

@ -84,7 +84,7 @@ GitLab is a Ruby on Rails application that runs on the following software:
- Ubuntu/Debian/CentOS/RHEL/OpenSUSE
- Ruby (MRI) 3.0.5
- Git 2.33+
- Redis 5.0+
- Redis 6.0+
- PostgreSQL 12+
For more information please see the [architecture](https://docs.gitlab.com/ee/development/architecture.html) and [requirements](https://docs.gitlab.com/ee/install/requirements.html) documentation.

View File

@ -17,6 +17,7 @@ export default function initNewBranchRefSelector() {
props: {
value: defaultBranchName,
name: hiddenInputName,
queryParams: { sort: 'updated_desc' },
projectId,
},
});

View File

@ -46,6 +46,7 @@ export const initCommitsRefSwitcher = () => {
return createElement(RefSelector, {
props: {
projectId,
queryParams: { sort: 'updated_desc' },
value: useSymbolicRefNames ? `refs/${refType}/${ref}` : ref,
useSymbolicRefNames,
},

View File

@ -53,10 +53,6 @@ export default {
text: s__('ProjectTemplates|Pages/Plain HTML'),
icon: '.template-option .icon-plainhtml',
},
gitbook: {
text: s__('ProjectTemplates|Pages/GitBook'),
icon: '.template-option .icon-gitbook',
},
hexo: {
text: s__('ProjectTemplates|Pages/Hexo'),
icon: '.template-option .icon-hexo',

View File

@ -14,6 +14,7 @@ export default function initNewTagRefSelector() {
props: {
value: defaultBranchName,
name: hiddenInputName,
queryParams: { sort: 'updated_desc' },
projectId,
},
});

View File

@ -1,18 +1,27 @@
<script>
import { GlEmptyState, GlLink } from '@gitlab/ui';
import { GlEmptyState, GlButton, GlModalDirective } from '@gitlab/ui';
import { s__ } from '~/locale';
import { helpPagePath } from '~/helpers/help_page_helper';
import InitCommandModal from './init_command_modal.vue';
export default {
COMMAND_MODAL_ID: 'init-command-modal',
i18n: {
title: s__("Terraform|Your project doesn't have any Terraform state files"),
description: s__('Terraform|How to use GitLab-managed Terraform state?'),
buttonDoc: s__('Terraform|Explore documentation'),
buttonCopy: s__('Terraform|Copy Terraform init command'),
},
docsUrl: helpPagePath('user/infrastructure/iac/terraform_state'),
components: {
GlEmptyState,
GlLink,
GlButton,
InitCommandModal,
},
directives: {
GlModalDirective,
},
props: {
image: {
type: String,
@ -24,8 +33,18 @@ export default {
<template>
<gl-empty-state :svg-path="image" :title="$options.i18n.title">
<template #description>
<gl-link :href="$options.docsUrl">{{ $options.i18n.description }}</gl-link>
<template #actions>
<gl-button variant="confirm" :href="$options.docsUrl">
{{ $options.i18n.buttonDoc }}</gl-button
>
<gl-button
v-gl-modal-directive="$options.COMMAND_MODAL_ID"
data-testid="terraform-state-copy-init-command"
icon="copy-to-clipboard"
>{{ $options.i18n.buttonCopy }}</gl-button
>
<init-command-modal :modal-id="$options.COMMAND_MODAL_ID" />
</template>
</gl-empty-state>
</template>

View File

@ -26,7 +26,8 @@ export default {
},
stateName: {
type: String,
required: true,
required: false,
default: '',
},
},
computed: {
@ -39,7 +40,9 @@ export default {
},
methods: {
getModalInfoCopyStr() {
const stateNameEncoded = encodeURIComponent(this.stateName);
const stateNameEncoded = this.stateName
? encodeURIComponent(this.stateName)
: '<YOUR-STATE-NAME>';
return `export GITLAB_ACCESS_TOKEN=<YOUR-ACCESS-TOKEN>
terraform init \\

View File

@ -265,29 +265,34 @@ class Projects::PipelinesController < Projects::ApplicationController
# rubocop: disable CodeReuse/ActiveRecord
def pipeline
@pipeline ||= if params[:id].blank? && params[:latest]
latest_pipeline
else
project
.all_pipelines
.includes(builds: :tags, user: :status)
.find(params[:id])
.present(current_user: current_user)
end
return @pipeline if defined?(@pipeline)
pipelines =
if find_latest_pipeline?
project.latest_pipelines(params['ref'])
else
project.all_pipelines.id_in(params[:id])
end
@pipeline = pipelines
.includes(builds: :tags, user: :status)
.take
&.present(current_user: current_user)
@pipeline || not_found
end
# rubocop: enable CodeReuse/ActiveRecord
def set_pipeline_path
@pipeline_path ||= if params[:id].blank? && params[:latest]
@pipeline_path ||= if find_latest_pipeline?
latest_project_pipelines_path(@project, params['ref'])
else
project_pipeline_path(@project, @pipeline)
end
end
def latest_pipeline
@project.latest_pipeline(params['ref'])
&.present(current_user: current_user)
def find_latest_pipeline?
params[:id].blank? && params[:latest]
end
def disable_query_limiting

View File

@ -122,21 +122,6 @@ module Projects
]
end
def access_levels_options
{
create_access_levels: levels_for_dropdown,
push_access_levels: levels_for_dropdown,
merge_access_levels: levels_for_dropdown
}
end
def levels_for_dropdown
roles = ProtectedRef::AccessLevel.human_access_levels.map do |id, text|
{ id: id, text: text, before_divider: true }
end
{ roles: roles }
end
def protectable_tags_for_dropdown
{ open_tags: ProtectableDropdown.new(@project, :tags).hash }
end
@ -154,7 +139,7 @@ module Projects
def load_gon_index
gon.push(protectable_tags_for_dropdown)
gon.push(protectable_branches_for_dropdown)
gon.push(access_levels_options)
gon.push(helpers.protected_access_levels_for_dropdowns)
gon.push(current_project_id: project.id) if project
end
end

View File

@ -0,0 +1,22 @@
# frozen_string_literal: true
module ProtectedRefsHelper
include Gitlab::Utils::StrongMemoize
def protected_access_levels_for_dropdowns
{
create_access_levels: protected_access_level_dropdown_roles,
push_access_levels: protected_access_level_dropdown_roles,
merge_access_levels: protected_access_level_dropdown_roles
}
end
def protected_access_level_dropdown_roles
roles = ProtectedRef::AccessLevel.human_access_levels.map do |id, text|
{ id: id, text: text, before_divider: true }
end
{ roles: roles }
end
strong_memoize_attr(:protected_access_level_dropdown_roles)
end

View File

@ -1260,12 +1260,16 @@ class Project < ApplicationRecord
latest_successful_build_for_ref(job_name, ref) || raise(ActiveRecord::RecordNotFound, "Couldn't find job #{job_name}")
end
def latest_pipeline(ref = default_branch, sha = nil)
def latest_pipelines(ref = default_branch, sha = nil)
ref = ref.presence || default_branch
sha ||= commit(ref)&.sha
return unless sha
return ci_pipelines.none unless sha
ci_pipelines.newest_first(ref: ref, sha: sha).take
ci_pipelines.newest_first(ref: ref, sha: sha)
end
def latest_pipeline(ref = default_branch, sha = nil)
latest_pipelines(ref, sha).take
end
def merge_base_commit(first_commit_id, second_commit_id)

View File

@ -67,7 +67,7 @@ class StageEntity < Grape::Entity
end
def preload_metadata(statuses)
Preloaders::CommitStatusPreloader.new(statuses).execute([:metadata])
Preloaders::CommitStatusPreloader.new(statuses).execute([:metadata, :pipeline])
statuses
end

View File

@ -19,6 +19,10 @@ module IssuableLinks
return error(issuables_already_assigned_message, 409)
end
if render_no_permission_error?
return error(issuables_no_permission_error_message, 403)
end
if render_not_found_error?
return error(issuables_not_found_message, 404)
end
@ -46,6 +50,7 @@ module IssuableLinks
link
end
# rubocop: enable CodeReuse/ActiveRecord
private
@ -54,6 +59,10 @@ module IssuableLinks
referenced_issuables.present? && (referenced_issuables - previous_related_issuables).empty?
end
def render_no_permission_error?
readonly_issuables(referenced_issuables).present? && linkable_issuables(referenced_issuables).empty?
end
def render_not_found_error?
linkable_issuables(referenced_issuables).empty?
end
@ -116,6 +125,10 @@ module IssuableLinks
_('%{issuable}(s) already assigned' % { issuable: target_issuable_type.capitalize })
end
def issuables_no_permission_error_message
_("Couldn't link %{issuable}. You must have at least the Reporter role in both projects." % { issuable: target_issuable_type })
end
def issuables_not_found_message
_('No matching %{issuable} found. Make sure that you are adding a valid %{issuable} URL.' % { issuable: target_issuable_type })
end
@ -133,6 +146,10 @@ module IssuableLinks
raise NotImplementedError
end
def readonly_issuables(_issuables)
[] # default to empty for non-issues
end
def previous_related_issuables
raise NotImplementedError
end

View File

@ -14,6 +14,10 @@ module IssueLinks
private
def readonly_issuables(issuables)
@readonly_issuables ||= issuables.select { |issuable| issuable.readable_by?(current_user) }
end
def track_event
track_incident_action(current_user, issuable, :incident_relate)
end

View File

@ -1,40 +0,0 @@
# frozen_string_literal: true
module WorkItems
module Widgets
module MilestoneService
class BaseService < WorkItems::Widgets::BaseService
private
def handle_milestone_change(params:)
return unless params.present? && params.key?(:milestone_id)
unless has_permission?(:set_work_item_metadata)
params.delete(:milestone_id)
return
end
if params[:milestone_id].nil?
work_item.milestone = nil
return
end
resource_group = work_item.project&.group || work_item.namespace
project_ids = [work_item.project&.id].compact
milestone = MilestonesFinder.new({
project_ids: project_ids,
group_ids: resource_group&.self_and_ancestors&.select(:id),
ids: [params[:milestone_id]]
}).execute.first
if milestone
work_item.milestone = milestone
else
params.delete(:milestone_id)
end
end
end
end
end
end

View File

@ -357,8 +357,8 @@ Depending on your installation method, this file is located at:
- Omnibus GitLab: `/var/log/gitlab/gitlab-rails/application.log`
- Installations from source: `/home/git/gitlab/log/application.log`
It helps you discover events happening in your instance such as user creation
and project deletion. For example:
It contains a less structured version of the logs in
[`application_json.log`](#application_jsonlog), like this example:
```plaintext
October 06, 2014 11:56: User "Administrator" (admin@example.com) was created
@ -377,7 +377,8 @@ Depending on your installation method, this file is located at:
- Omnibus GitLab: `/var/log/gitlab/gitlab-rails/application_json.log`
- Installations from source: `/home/git/gitlab/log/application_json.log`
It contains the JSON version of the logs in `application.log`, like this example:
It helps you discover events happening in your instance such as user creation
and project deletion. For example:
```json
{

View File

@ -18609,7 +18609,6 @@ Represents a product analytics dashboard visualization.
| <a id="projectcreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp of the project creation. |
| <a id="projectdastscannerprofiles"></a>`dastScannerProfiles` | [`DastScannerProfileConnection`](#dastscannerprofileconnection) | DAST scanner profiles associated with the project. (see [Connections](#connections)) |
| <a id="projectdastsiteprofiles"></a>`dastSiteProfiles` | [`DastSiteProfileConnection`](#dastsiteprofileconnection) | DAST Site Profiles associated with the project. (see [Connections](#connections)) |
| <a id="projectdependencies"></a>`dependencies` **{warning-solid}** | [`DependencyConnection`](#dependencyconnection) | **Introduced** in 15.9. This feature is an Experiment. It can be changed or removed at any time. Software dependencies used by the project. |
| <a id="projectdescription"></a>`description` | [`String`](#string) | Short description of the project. |
| <a id="projectdescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | GitLab Flavored Markdown rendering of `description`. |
| <a id="projectdora"></a>`dora` | [`Dora`](#dora) | Project's DORA metrics. |
@ -18980,6 +18979,26 @@ Returns [`ProjectDataTransfer`](#projectdatatransfer).
| <a id="projectdatatransferfrom"></a>`from` | [`Date`](#date) | Retain egress data for one year. Data for the current month will increase dynamically as egress occurs. |
| <a id="projectdatatransferto"></a>`to` | [`Date`](#date) | End date for the data. |
##### `Project.dependencies`
Software dependencies used by the project.
WARNING:
**Introduced** in 15.9.
This feature is an Experiment. It can be changed or removed at any time.
Returns [`DependencyConnection`](#dependencyconnection).
This field returns a [connection](#connections). It accepts the
four standard [pagination arguments](#connection-pagination-arguments):
`before: String`, `after: String`, `first: Int`, `last: Int`.
###### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="projectdependenciessort"></a>`sort` | [`DependencySort`](#dependencysort) | Sort dependencies by given criteria. |
##### `Project.deployment`
Details of the deployment of the project.
@ -23625,6 +23644,17 @@ Weight of the data visualization palette.
| <a id="dependencyproxymanifeststatuspending_destruction"></a>`PENDING_DESTRUCTION` | Dependency proxy manifest has a status of pending_destruction. |
| <a id="dependencyproxymanifeststatusprocessing"></a>`PROCESSING` | Dependency proxy manifest has a status of processing. |
### `DependencySort`
Values for sorting dependencies.
| Value | Description |
| ----- | ----------- |
| <a id="dependencysortname_asc"></a>`NAME_ASC` | Name by ascending order. |
| <a id="dependencysortname_desc"></a>`NAME_DESC` | Name by descending order. |
| <a id="dependencysortpackager_asc"></a>`PACKAGER_ASC` | Packager by ascending order. |
| <a id="dependencysortpackager_desc"></a>`PACKAGER_DESC` | Packager by descending order. |
### `DeploymentApprovalSummaryStatus`
Status of the deployment approval summary.

View File

@ -274,10 +274,7 @@ coverage-jdk11:
### Python example
The following [`.gitlab-ci.yml`](../yaml/index.md) example for Python uses [pytest-cov](https://pytest-cov.readthedocs.io/) to collect test coverage data and [coverage.py](https://coverage.readthedocs.io/) to convert the report to use full relative paths.
The information isn't displayed without the conversion.
This example assumes that the code for your package is in `src/` and your tests are in `tests.py`:
The following [`.gitlab-ci.yml`](../yaml/index.md) example uses [pytest-cov](https://pytest-cov.readthedocs.io/) to collect test coverage data:
```yaml
run tests:
@ -285,9 +282,7 @@ run tests:
image: python:3
script:
- pip install pytest pytest-cov
- coverage run -m pytest
- coverage report
- coverage xml
- pytest --cov --cov-report term --cov-report xml:coverage.xml
coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
artifacts:
reports:

View File

@ -521,12 +521,12 @@ After that, the next pipeline uses the up-to-date `knapsack/report-master.json`
We used to skip tests that are [known to be flaky](../testing_guide/flaky_tests.md#automatic-retries-and-flaky-tests-detection),
but we stopped doing so since that could actually lead to actual broken `master`.
Instead, we proactively quarantine any flaky test reported in `#master-broken` incidents
so that they're ultimately fixed by their respective group.
Instead, we introduced
[a fast-quarantining process](../testing_guide/flaky_tests.md#fast-quarantine)
to proactively quarantine any flaky test reported in `#master-broken` incidents.
The automatic skipping of flaky tests can still be enabled by setting the `$SKIP_FLAKY_TESTS_AUTOMATICALLY` variable to `true`.
See the [experiment issue](https://gitlab.com/gitlab-org/quality/quality-engineering/team-tasks/-/issues/1069).
This fast-quarantining process can be disabled by setting the `$FAST_QUARANTINE`
variable to `false`.
### Automatic retry of failing tests in a separate process

View File

@ -169,7 +169,8 @@ To remove a worker class, follow these steps over two minor releases:
MyDeprecatedWorkerOne
MyDeprecatedWorkerTwo
]
# Always use `disable_ddl_transaction!` while using the `sidekiq_remove_jobs` method, as we had multiple production incidents due to `idle-in-transaction` timeout.
disable_ddl_transaction!
def up
sidekiq_remove_jobs(job_klasses: DEPRECATED_JOB_CLASSES)
end

View File

@ -151,16 +151,28 @@ usually a good idea.
## Quarantined tests
When we have a flaky test in `master`, quarantine the test after the first failure and
create [a ~"failure::flaky-test" issue](https://about.gitlab.com/handbook/engineering/workflow/#broken-master).
When we have a flaky test in `master`:
If the test cannot be fixed in a timely fashion, there is an impact on the
productivity of all the developers, so it should be quarantined. There are two ways to quarantine tests, depending on the test framework being used: RSpec and Jest.
1. Create [a ~"failure::flaky-test" issue](https://about.gitlab.com/handbook/engineering/workflow/#broken-master) with the relevant group label.
1. Quarantine the test after the first failure.
If the test cannot be fixed in a timely fashion, there is an impact on the
productivity of all the developers, so it should be quarantined.
### RSpec
Add the corresponding category and group labels to issue using [`feature_category` metadata](../feature_categorization/index.md#rspec-examples).
For RSpec tests, you can use the `:quarantine` metadata with the issue URL.
#### Fast quarantine
To quickly quarantine a test without having to open a merge request and wait for pipelines,
you can follow [the fast quarantining process](https://gitlab.com/gitlab-org/quality/engineering-productivity/fast-quarantine/-/tree/main/#fast-quarantine-a-test).
#### Long-term quarantine
Once a test is fast-quarantined, you can proceed with the long-term quarantining process. This can be done by opening a merge request.
First, ensure the test file has a [`feature_category` metadata](../feature_categorization/index.md#rspec-examples), to ensure correct attribution of the test file.
Then, you can use the `quarantine: '<issue url>'` metadata with the URL of the
~"failure::flaky-test" issue you created previously.
```ruby
it 'succeeds', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/12345' do
@ -222,11 +234,10 @@ For example, `FLAKY_RSPEC_GENERATE_REPORT=1 bin/rspec ...`.
### Usage of the `rspec/flaky/report-suite.json` report
The `rspec/flaky/report-suite.json` report is:
- Used for [automatically skipping known flaky tests](../pipelines/index.md#automatic-skipping-of-flaky-tests).
- [Imported into Snowflake](https://gitlab.com/gitlab-data/analytics/-/blob/master/extract/gitlab_flaky_tests/upload.py)
once per day, for monitoring with the [internal dashboard](https://app.periscopedata.com/app/gitlab/888968/EP---Flaky-tests).
The `rspec/flaky/report-suite.json` report is
[imported into Snowflake](https://gitlab.com/gitlab-data/analytics/-/blob/7085bea51bb2f8f823e073393934ba5f97259459/extract/gitlab_flaky_tests/upload.py#L19)
once per day, for monitoring with the
[internal dashboard](https://app.periscopedata.com/app/gitlab/888968/EP---Flaky-tests).
## Problems we had in the past at GitLab

View File

@ -93,8 +93,8 @@ meet the other online upgrade requirements mentioned above.
## Multi-node / HA deployment
WARNING:
You can only upgrade one minor release at a time. So from 13.6 to 13.7, not to 13.8.
If you attempt more than one minor release, the upgrade may fail.
You can only upgrade one minor release at a time. So from 15.6 to 15.7, not to 15.8.
If you attempt more than one minor release, the upgrade may fail.
### Use a load balancer in front of web (Puma) nodes
@ -544,7 +544,7 @@ setting `gitlab_rails['auto_migrate'] = false` in
## Multi-node / HA deployment with Geo **(PREMIUM SELF)**
WARNING:
You can only upgrade one minor release at a time.
You can only upgrade one minor release at a time. You also must first start with the Gitaly cluster, updating Gitaly one node one at a time. This will ensure access to the Git repositories for the remainder of the upgrade process.
This section describes the steps required to upgrade a multi-node / HA
deployment with Geo. Some steps must be performed on a particular node. This

View File

@ -379,7 +379,10 @@ When transferring groups, note:
- You must update your local repositories to point to the new location.
- If the immediate parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects change to match the new parent group's visibility.
- Only explicit group membership is transferred, not inherited membership. If the group's owners have only inherited membership, this leaves the group without an owner. In this case, the user transferring the group becomes the group's owner.
- Transfers fail if [packages](../packages/index.md) exist in any of the projects in the group, or in any of its subgroups.
- Transfers fail if [npm packages](../packages/npm_registry/index.md) exist in any of the projects in the group, or in any of its subgroups.
- Existing packages that use a group-level endpoint (Maven, NuGet, PyPI, Composer, and Debian) need to be updated per the package's steps for setting up the group level endpoint.
- Existing package names need to be updated if the package uses an instance level endpoint ([Maven](../packages/maven_repository/index.md#naming-convention), [npm](../packages/npm_registry/index.md#naming-convention), [Conan](../packages/conan_repository/index.md#package-recipe-naming-convention-for-instance-remotes)) and the group was moved to another root level namespace.
- [Maven packages](../packages/maven_repository/index.md#naming-convention) follow a naming convention that prevent installing or publishing the respective package from a group level endpoint after group transfer.
- Top-level groups that have a subscription on GitLab.com cannot be transferred. To make the transfer possible, the top-level group's subscription must be removed first. Then the top-level group can be transferred as a subgroup to another top-level group.
To transfer a group:

View File

@ -22,10 +22,10 @@ Packages can be published to your project, group, or instance.
| [Generic packages](../generic_packages/index.md) | Y | N | N |
| [Terraform](../terraform_module_registry/index.md) | Y | N | N |
| [Composer](../composer_repository/index.md) | N | Y | N |
| [Conan](../conan_repository/index.md) | Y | N | N |
| [Conan](../conan_repository/index.md) | Y | N | Y |
| [Helm](../helm_repository/index.md) | Y | N | N |
| [Debian](../debian_repository/index.md) | Y | N | N |
| [Go](../go_proxy/index.md) | Y | N | Y |
| [Go](../go_proxy/index.md) | Y | N | N |
| [Ruby gems](../rubygems_registry/index.md) | Y | N | N |
## Pulling packages **(FREE)**

View File

@ -19,8 +19,8 @@ The Package Registry supports the following package manager types:
| [PyPI](../pypi_repository/index.md) | 12.10+ | GA |
| [Generic packages](../generic_packages/index.md) | 13.5+ | GA |
| [Composer](../composer_repository/index.md) | 13.2+ | [Beta](https://gitlab.com/groups/gitlab-org/-/epics/6817) |
| [Conan](../conan_repository/index.md) | 12.6+ | [Beta](https://gitlab.com/groups/gitlab-org/-/epics/6816) |
| [Helm](../helm_repository/index.md) | 14.1+ | [Beta](https://gitlab.com/groups/gitlab-org/-/epics/6366) |
| [Conan](../conan_repository/index.md) | 12.6+ | [Experiment](https://gitlab.com/groups/gitlab-org/-/epics/6816) |
| [Debian](../debian_repository/index.md) | 14.2+ | [Experiment](https://gitlab.com/groups/gitlab-org/-/epics/6057) |
| [Go](../go_proxy/index.md) | 13.1+ | [Experiment](https://gitlab.com/groups/gitlab-org/-/epics/3043) |
| [Ruby gems](../rubygems_registry/index.md) | 13.10+ | [Experiment](https://gitlab.com/groups/gitlab-org/-/epics/3200) |

View File

@ -66,7 +66,6 @@ module Gitlab
ProjectTemplate.new('pelican', 'Pages/Pelican', _('Everything you need to create a GitLab Pages site using Pelican'), 'https://gitlab.com/pages/pelican', 'illustrations/third-party-logos/pelican.svg'),
ProjectTemplate.new('jekyll', 'Pages/Jekyll', _('Everything you need to create a GitLab Pages site using Jekyll'), 'https://gitlab.com/pages/jekyll', 'illustrations/logos/jekyll.svg'),
ProjectTemplate.new('plainhtml', 'Pages/Plain HTML', _('Everything you need to create a GitLab Pages site using plain HTML'), 'https://gitlab.com/pages/plain-html'),
ProjectTemplate.new('gitbook', 'Pages/GitBook', _('Everything you need to create a GitLab Pages site using GitBook'), 'https://gitlab.com/pages/gitbook', 'illustrations/logos/gitbook.svg'),
ProjectTemplate.new('hexo', 'Pages/Hexo', _('Everything you need to create a GitLab Pages site using Hexo'), 'https://gitlab.com/pages/hexo', 'illustrations/logos/hexo.svg'),
ProjectTemplate.new('middleman', 'Pages/Middleman', _('Everything you need to create a GitLab Pages site using Middleman'), 'https://gitlab.com/gitlab-org/project-templates/middleman', 'illustrations/logos/middleman.svg'),
ProjectTemplate.new('gitpod_spring_petclinic', 'Gitpod/Spring Petclinic', _('A Gitpod configured Webapplication in Spring and Java'), 'https://gitlab.com/gitlab-org/project-templates/gitpod-spring-petclinic', 'illustrations/logos/gitpod.svg'),

View File

@ -5,9 +5,7 @@ require 'redis'
module SystemCheck
module App
class RedisVersionCheck < SystemCheck::BaseCheck
# Redis 5.x will be deprecated
# https://gitlab.com/gitlab-org/gitlab/-/issues/331468
MIN_REDIS_VERSION = '5.0.0'
MIN_REDIS_VERSION = '6.0.0'
RECOMMENDED_REDIS_VERSION = "6.0.0"
set_name "Redis version >= #{RECOMMENDED_REDIS_VERSION}?"

View File

@ -12209,6 +12209,9 @@ msgstr ""
msgid "Couldn't find event type filters where audit event type(s): %{missing_filters}"
msgstr ""
msgid "Couldn't link %{issuable}. You must have at least the Reporter role in both projects."
msgstr ""
msgid "Country / Region"
msgstr ""
@ -17448,9 +17451,6 @@ msgstr ""
msgid "Everything you need to create a GitLab Pages site using Gatsby"
msgstr ""
msgid "Everything you need to create a GitLab Pages site using GitBook"
msgstr ""
msgid "Everything you need to create a GitLab Pages site using Hexo"
msgstr ""
@ -35234,9 +35234,6 @@ msgstr ""
msgid "ProjectTemplates|Pages/Gatsby"
msgstr ""
msgid "ProjectTemplates|Pages/GitBook"
msgstr ""
msgid "ProjectTemplates|Pages/Hexo"
msgstr ""
@ -43927,15 +43924,15 @@ msgstr ""
msgid "Terraform|Download JSON"
msgstr ""
msgid "Terraform|Explore documentation"
msgstr ""
msgid "Terraform|Failed to load Terraform reports"
msgstr ""
msgid "Terraform|Generating the report caused an error."
msgstr ""
msgid "Terraform|How to use GitLab-managed Terraform state?"
msgstr ""
msgid "Terraform|Job status"
msgstr ""

View File

@ -12,6 +12,11 @@ function retrieve_tests_metadata() {
curl --location -o "${FLAKY_RSPEC_SUITE_REPORT_PATH}" "https://gitlab-org.gitlab.io/gitlab/${FLAKY_RSPEC_SUITE_REPORT_PATH}" ||
echo "{}" > "${FLAKY_RSPEC_SUITE_REPORT_PATH}"
fi
if [[ ! -f "${RSPEC_FAST_QUARANTINE_PATH}" ]]; then
curl --location -o "${RSPEC_FAST_QUARANTINE_PATH}" "https://gitlab-org.gitlab.io/quality/engineering-productivity/fast-quarantine/${RSPEC_FAST_QUARANTINE_PATH}" ||
echo "" > "${RSPEC_FAST_QUARANTINE_PATH}"
fi
}
function update_tests_metadata() {
@ -121,20 +126,20 @@ function rspec_db_library_code() {
}
function debug_rspec_variables() {
echoinfo "SKIP_FLAKY_TESTS_AUTOMATICALLY: ${SKIP_FLAKY_TESTS_AUTOMATICALLY}"
echoinfo "RETRY_FAILED_TESTS_IN_NEW_PROCESS: ${RETRY_FAILED_TESTS_IN_NEW_PROCESS}"
echoinfo "SKIP_FLAKY_TESTS_AUTOMATICALLY: ${SKIP_FLAKY_TESTS_AUTOMATICALLY:-}"
echoinfo "RETRY_FAILED_TESTS_IN_NEW_PROCESS: ${RETRY_FAILED_TESTS_IN_NEW_PROCESS:-}"
echoinfo "KNAPSACK_GENERATE_REPORT: ${KNAPSACK_GENERATE_REPORT:-}"
echoinfo "FLAKY_RSPEC_GENERATE_REPORT: ${FLAKY_RSPEC_GENERATE_REPORT:-}"
echoinfo "KNAPSACK_TEST_FILE_PATTERN: ${KNAPSACK_TEST_FILE_PATTERN}"
echoinfo "KNAPSACK_LOG_LEVEL: ${KNAPSACK_LOG_LEVEL}"
echoinfo "KNAPSACK_REPORT_PATH: ${KNAPSACK_REPORT_PATH}"
echoinfo "KNAPSACK_TEST_FILE_PATTERN: ${KNAPSACK_TEST_FILE_PATTERN:-}"
echoinfo "KNAPSACK_LOG_LEVEL: ${KNAPSACK_LOG_LEVEL:-}"
echoinfo "KNAPSACK_REPORT_PATH: ${KNAPSACK_REPORT_PATH:-}"
echoinfo "FLAKY_RSPEC_SUITE_REPORT_PATH: ${FLAKY_RSPEC_SUITE_REPORT_PATH}"
echoinfo "FLAKY_RSPEC_REPORT_PATH: ${FLAKY_RSPEC_REPORT_PATH}"
echoinfo "NEW_FLAKY_RSPEC_REPORT_PATH: ${NEW_FLAKY_RSPEC_REPORT_PATH}"
echoinfo "SKIPPED_FLAKY_TESTS_REPORT_PATH: ${SKIPPED_FLAKY_TESTS_REPORT_PATH}"
echoinfo "FLAKY_RSPEC_SUITE_REPORT_PATH: ${FLAKY_RSPEC_SUITE_REPORT_PATH:-}"
echoinfo "FLAKY_RSPEC_REPORT_PATH: ${FLAKY_RSPEC_REPORT_PATH:-}"
echoinfo "NEW_FLAKY_RSPEC_REPORT_PATH: ${NEW_FLAKY_RSPEC_REPORT_PATH:-}"
echoinfo "SKIPPED_FLAKY_TESTS_REPORT_PATH: ${SKIPPED_FLAKY_TESTS_REPORT_PATH:-}"
echoinfo "CRYSTALBALL: ${CRYSTALBALL:-}"

View File

@ -1148,7 +1148,7 @@ RSpec.describe Projects::PipelinesController, feature_category: :continuous_inte
def clear_controller_memoization
controller.clear_memoization(:pipeline_test_report)
controller.instance_variable_set(:@pipeline, nil)
controller.remove_instance_variable(:@pipeline)
end
end

View File

@ -62,7 +62,7 @@ RSpec.describe 'Developer creates tag', :js, feature_category: :source_code_mana
expect(ref_input.value).to eq 'master'
expect(find('.gl-button-text')).to have_content 'master'
find('.ref-selector').click
expect(find('.gl-new-dropdown-inner')).to have_content 'test'
expect(find('.gl-new-dropdown-inner')).to have_content 'spooky-stuff'
end
end
end

View File

@ -1,6 +1,7 @@
import { GlEmptyState, GlLink } from '@gitlab/ui';
import { GlEmptyState, GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import EmptyState from '~/terraform/components/empty_state.vue';
import InitCommandModal from '~/terraform/components/init_command_modal.vue';
describe('EmptyStateComponent', () => {
let wrapper;
@ -10,7 +11,9 @@ describe('EmptyStateComponent', () => {
};
const docsUrl = '/help/user/infrastructure/iac/terraform_state';
const findEmptyState = () => wrapper.findComponent(GlEmptyState);
const findLink = () => wrapper.findComponent(GlLink);
const findButton = () => wrapper.findComponent(GlButton);
const findCopyModal = () => wrapper.findComponent(InitCommandModal);
const findCopyButton = () => wrapper.find('[data-testid="terraform-state-copy-init-command"]');
beforeEach(() => {
wrapper = shallowMount(EmptyState, { propsData });
@ -22,7 +25,19 @@ describe('EmptyStateComponent', () => {
);
});
it('should have a link to the GitLab managed Terraform states docs', () => {
expect(findLink().attributes('href')).toBe(docsUrl);
it('buttons explore documentation should have a link to the GitLab managed Terraform states docs', () => {
expect(findButton().attributes('href')).toBe(docsUrl);
});
describe('copy command button', () => {
it('displays a copy init command button', () => {
expect(findCopyButton().text()).toBe('Copy Terraform init command');
});
it('opens the modal on copy button click', async () => {
await findCopyButton().vm.$emit('click');
expect(findCopyModal().isVisible()).toBe(true);
});
});
});

View File

@ -8,6 +8,7 @@ const terraformApiUrl = 'https://gitlab.com/api/v4/projects/1';
const username = 'username';
const modalId = 'fake-modal-id';
const stateName = 'aws/eu-central-1';
const stateNamePlaceholder = '<YOUR-STATE-NAME>';
const stateNameEncoded = encodeURIComponent(stateName);
const modalInfoCopyStr = `export GITLAB_ACCESS_TOKEN=<YOUR-ACCESS-TOKEN>
terraform init \\
@ -34,49 +35,68 @@ describe('InitCommandModal', () => {
username,
};
const findExplanatoryText = () => wrapper.findByTestId('init-command-explanatory-text');
const findLink = () => wrapper.findComponent(GlLink);
const findInitCommand = () => wrapper.findByTestId('terraform-init-command');
const findCopyButton = () => wrapper.findComponent(ModalCopyButton);
beforeEach(() => {
const mountComponent = ({ props = propsData } = {}) => {
wrapper = shallowMountExtended(InitCommandModal, {
propsData,
propsData: props,
provide: provideData,
stubs: {
GlSprintf,
},
});
};
const findExplanatoryText = () => wrapper.findByTestId('init-command-explanatory-text');
const findLink = () => wrapper.findComponent(GlLink);
const findInitCommand = () => wrapper.findByTestId('terraform-init-command');
const findCopyButton = () => wrapper.findComponent(ModalCopyButton);
describe('when has stateName', () => {
beforeEach(() => {
mountComponent();
});
describe('on rendering', () => {
it('renders the explanatory text', () => {
expect(findExplanatoryText().text()).toContain('personal access token');
});
it('renders the personal access token link', () => {
expect(findLink().attributes('href')).toBe(accessTokensPath);
});
describe('init command', () => {
it('includes correct address', () => {
expect(findInitCommand().text()).toContain(
`-backend-config="address=${terraformApiUrl}/${stateNameEncoded}"`,
);
});
it('includes correct username', () => {
expect(findInitCommand().text()).toContain(`-backend-config="username=${username}"`);
});
});
it('renders the copyToClipboard button', () => {
expect(findCopyButton().exists()).toBe(true);
});
});
describe('when copy button is clicked', () => {
it('copies init command to clipboard', () => {
expect(findCopyButton().props('text')).toBe(modalInfoCopyStr);
});
});
});
describe('on rendering', () => {
it('renders the explanatory text', () => {
expect(findExplanatoryText().text()).toContain('personal access token');
describe('when has no stateName', () => {
beforeEach(() => {
mountComponent({ props: { modalId } });
});
it('renders the personal access token link', () => {
expect(findLink().attributes('href')).toBe(accessTokensPath);
});
describe('init command', () => {
describe('on rendering', () => {
it('includes correct address', () => {
expect(findInitCommand().text()).toContain(
`-backend-config="address=${terraformApiUrl}/${stateNameEncoded}"`,
`-backend-config="address=${terraformApiUrl}/${stateNamePlaceholder}"`,
);
});
it('includes correct username', () => {
expect(findInitCommand().text()).toContain(`-backend-config="username=${username}"`);
});
});
it('renders the copyToClipboard button', () => {
expect(findCopyButton().exists()).toBe(true);
});
});
describe('when copy button is clicked', () => {
it('copies init command to clipboard', () => {
expect(findCopyButton().props('text')).toBe(modalInfoCopyStr);
});
});
});

View File

@ -1,5 +1,6 @@
import { within } from '@testing-library/dom';
import { loadHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import htmlMergeRequestWithMentions from 'test_fixtures/merge_requests/merge_request_with_mentions.html';
import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import UsersCache from '~/lib/utils/users_cache';
import initUserPopovers from '~/user_popovers';
import waitForPromises from 'helpers/wait_for_promises';
@ -10,8 +11,6 @@ jest.mock('~/api/user_api', () => ({
}));
describe('User Popovers', () => {
const fixtureTemplate = 'merge_requests/merge_request_with_mentions.html';
const selector = '.js-user-link[data-user], .js-user-link[data-user-id]';
const findFixtureLinks = () => Array.from(document.querySelectorAll(selector));
const createUserLink = () => {
@ -40,7 +39,7 @@ describe('User Popovers', () => {
};
const setupTestSubject = () => {
loadHTMLFixture(fixtureTemplate);
setHTMLFixture(htmlMergeRequestWithMentions);
const usersCacheSpy = () => Promise.resolve(dummyUser);
jest.spyOn(UsersCache, 'retrieveById').mockImplementation((userId) => usersCacheSpy(userId));

View File

@ -0,0 +1,51 @@
# frozen_string_literal: true
require "spec_helper"
RSpec.describe ProtectedRefsHelper, feature_category: :source_code_management do
describe '#protected_access_levels_for_dropdowns' do
let(:protected_access_level_dropdown_roles) { :protected_access_level_dropdown_roles }
before do
allow(helper)
.to receive(:protected_access_level_dropdown_roles)
.and_return(protected_access_level_dropdown_roles)
end
it 'returns roles for {create,push,merge}_access_levels' do
expect(helper.protected_access_levels_for_dropdowns).to eq(
{
create_access_levels: protected_access_level_dropdown_roles,
push_access_levels: protected_access_level_dropdown_roles,
merge_access_levels: protected_access_level_dropdown_roles
}
)
end
end
describe '#protected_access_level_dropdown_roles' do
let(:roles) do
[
{
id: ::Gitlab::Access::DEVELOPER,
text: 'Developers + Maintainers',
before_divider: true
},
{
id: ::Gitlab::Access::MAINTAINER,
text: 'Maintainers',
before_divider: true
},
{
id: ::Gitlab::Access::NO_ACCESS,
text: 'No one',
before_divider: true
}
]
end
it 'returns dropdown options for each protected ref access level' do
expect(helper.protected_access_level_dropdown_roles[:roles]).to include(*roles)
end
end
end

View File

@ -87,7 +87,7 @@ RSpec.describe API::IssueLinks, feature_category: :team_planning do
end
context 'when user does not have write access to given issue' do
it 'returns 404' do
it 'returns 403' do
unauthorized_project = create(:project)
target_issue = create(:issue, project: unauthorized_project)
unauthorized_project.add_guest(user)
@ -95,8 +95,8 @@ RSpec.describe API::IssueLinks, feature_category: :team_planning do
post api("/projects/#{project.id}/issues/#{issue.iid}/links", user),
params: { target_project_id: unauthorized_project.id, target_issue_iid: target_issue.iid }
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('No matching issue found. Make sure that you are adding a valid issue URL.')
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response['message']).to eq("Couldn't link issue. You must have at least the Reporter role in both projects.")
end
end

View File

@ -23,18 +23,25 @@ RSpec.describe Projects::PipelinesController, feature_category: :continuous_inte
it 'does not execute N+1 queries' do
get_pipelines_index
control_count = ActiveRecord::QueryRecorder.new do
create_pipelines
control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do
get_pipelines_index
end.count
%w[pending running success failed canceled].each do |status|
create(:ci_pipeline, project: project, status: status)
end
create_pipelines
# There appears to be one extra query for Pipelines#has_warnings? for some reason
expect { get_pipelines_index }.not_to exceed_query_limit(control_count + 1)
expect { get_pipelines_index }.not_to exceed_all_query_limit(control_count + 1)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['pipelines'].count).to eq 6
expect(json_response['pipelines'].count).to eq(11)
end
def create_pipelines
%w[pending running success failed canceled].each do |status|
pipeline = create(:ci_pipeline, project: project, status: status)
create(:ci_build, :failed, pipeline: pipeline)
end
end
def get_pipelines_index
@ -49,13 +56,21 @@ RSpec.describe Projects::PipelinesController, feature_category: :continuous_inte
it 'does not execute N+1 queries' do
request_build_stage
control_count = ActiveRecord::QueryRecorder.new do
control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do
request_build_stage
end.count
create(:ci_build, pipeline: pipeline, stage: 'build')
expect { request_build_stage }.not_to exceed_query_limit(control_count)
2.times do |i|
create(:ci_build,
name: "test retryable #{i}",
pipeline: pipeline,
stage: 'build',
status: :failed)
end
expect { request_build_stage }.not_to exceed_all_query_limit(control_count)
expect(response).to have_gitlab_http_status(:ok)
end
@ -66,13 +81,14 @@ RSpec.describe Projects::PipelinesController, feature_category: :continuous_inte
request_build_stage(retried: true)
control_count = ActiveRecord::QueryRecorder.new do
control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do
request_build_stage(retried: true)
end.count
create(:ci_build, :retried, :failed, pipeline: pipeline, stage: 'build')
create(:ci_build, :failed, pipeline: pipeline, stage: 'build')
expect { request_build_stage(retried: true) }.not_to exceed_query_limit(control_count)
expect { request_build_stage(retried: true) }.not_to exceed_all_query_limit(control_count)
expect(response).to have_gitlab_http_status(:ok)
end

View File

@ -0,0 +1,50 @@
# frozen_string_literal: true
return unless ENV['CI']
return if ENV['FAST_QUARANTINE'] == "false"
return if ENV['CI_MERGE_REQUEST_LABELS'].to_s.include?('pipeline:run-flaky-tests')
require_relative '../../tooling/rspec_flaky/config'
# rubocop:disable Style/GlobalVars
RSpec.configure do |config|
$fast_quarantined_entity_identifiers = begin
raise "#{ENV['RSPEC_FAST_QUARANTINE_PATH']} doesn't exist" unless File.exist?(ENV['RSPEC_FAST_QUARANTINE_PATH'])
quarantined_entity_identifiers = File.read(ENV['RSPEC_FAST_QUARANTINE_PATH']).lines
quarantined_entity_identifiers.compact!
quarantined_entity_identifiers.map! do |quarantined_entity_identifier|
quarantined_entity_identifier.delete_prefix('./').strip
end
rescue => e # rubocop:disable Style/RescueStandardError
puts e
[]
end
$skipped_tests = []
config.around do |example|
fast_quarantined_entity_identifier = $fast_quarantined_entity_identifiers.find do |quarantined_entity_identifier|
case quarantined_entity_identifier
when /^.+_spec\.rb\[[\d:]+\]$/ # example id, e.g. spec/tasks/gitlab/usage_data_rake_spec.rb[1:5:2:1]
example.id == "./#{quarantined_entity_identifier}"
else # whole file, e.g. ee/spec/features/boards/swimlanes/epics_swimlanes_sidebar_spec.rb
example.metadata[:rerun_file_path] == "./#{quarantined_entity_identifier}"
end
end
if fast_quarantined_entity_identifier
puts "Skipping #{example.id} '#{example.full_description}' because it's been fast-quarantined with '#{fast_quarantined_entity_identifier}'."
$skipped_tests << example.id
else
example.run
end
end
config.after(:suite) do
next unless RspecFlaky::Config.skipped_flaky_tests_report_path
next if $skipped_tests.empty?
File.write(RspecFlaky::Config.skipped_flaky_tests_report_path, "#{ENV['CI_JOB_URL']}\n#{$skipped_tests.join("\n")}\n\n")
end
end
# rubocop:enable Style/GlobalVars

View File

@ -1,37 +0,0 @@
# frozen_string_literal: true
return unless ENV['CI']
return if ENV['SKIP_FLAKY_TESTS_AUTOMATICALLY'] == "false"
return if ENV['CI_MERGE_REQUEST_LABELS'].to_s.include?('pipeline:run-flaky-tests')
require_relative '../../tooling/rspec_flaky/config'
require_relative '../../tooling/rspec_flaky/report'
RSpec.configure do |config|
$flaky_test_example_ids = begin # rubocop:disable Style/GlobalVars
raise "#{RspecFlaky::Config.suite_flaky_examples_report_path} doesn't exist" unless File.exist?(RspecFlaky::Config.suite_flaky_examples_report_path)
RspecFlaky::Report.load(RspecFlaky::Config.suite_flaky_examples_report_path).map { |_, flaky_test_data| flaky_test_data.to_h[:example_id] }
rescue => e # rubocop:disable Style/RescueStandardError
puts e
[]
end
$skipped_flaky_tests_report = [] # rubocop:disable Style/GlobalVars
config.around do |example|
# Skip flaky tests automatically
if $flaky_test_example_ids.include?(example.id) # rubocop:disable Style/GlobalVars
puts "Skipping #{example.id} '#{example.full_description}' because it's flaky."
$skipped_flaky_tests_report << example.id # rubocop:disable Style/GlobalVars
else
example.run
end
end
config.after(:suite) do
next unless RspecFlaky::Config.skipped_flaky_tests_report_path
next if $skipped_flaky_tests_report.empty? # rubocop:disable Style/GlobalVars
File.write(RspecFlaky::Config.skipped_flaky_tests_report_path, "#{ENV['CI_JOB_URL']}\n#{$skipped_flaky_tests_report.join("\n")}\n\n") # rubocop:disable Style/GlobalVars
end
end

View File

@ -4,7 +4,7 @@ module ProjectTemplateTestHelper
def all_templates
%w[
rails spring express iosswift dotnetcore android
gomicro gatsby hugo jekyll plainhtml gitbook
gomicro gatsby hugo jekyll plainhtml
hexo middleman gitpod_spring_petclinic nfhugo
nfjekyll nfplainhtml nfgitbook nfhexo salesforcedx
serverless_framework tencent_serverless_framework

View File

@ -34,7 +34,11 @@ RSpec.shared_examples 'issuable link creation' do
end
it 'returns error' do
is_expected.to eq(message: "No matching #{issuable_type} found. Make sure that you are adding a valid #{issuable_type} URL.", status: :error, http_status: 404)
if issuable_type == :issue
is_expected.to eq(message: "Couldn't link #{issuable_type}. You must have at least the Reporter role in both projects.", status: :error, http_status: 403)
else
is_expected.to eq(message: "No matching #{issuable_type} found. Make sure that you are adding a valid #{issuable_type} URL.", status: :error, http_status: 404)
end
end
it 'no relationship is created' do

Binary file not shown.

View File

@ -10,7 +10,7 @@ import (
"gitlab.com/gitlab-org/labkit/correlation"
"github.com/golang-jwt/jwt/v4"
"github.com/golang-jwt/jwt/v5"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/api"

View File

@ -10,7 +10,7 @@ require (
github.com/aws/aws-sdk-go v1.44.230
github.com/disintegration/imaging v1.6.2
github.com/getsentry/raven-go v0.2.0
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/golang-jwt/jwt/v5 v5.0.0
github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f
github.com/golang/protobuf v1.5.3
github.com/gomodule/redigo v2.0.0+incompatible
@ -26,7 +26,7 @@ require (
github.com/sirupsen/logrus v1.9.0
github.com/smartystreets/goconvey v1.7.2
github.com/stretchr/testify v1.8.2
gitlab.com/gitlab-org/gitaly/v15 v15.10.3
gitlab.com/gitlab-org/gitaly/v15 v15.11.0
gitlab.com/gitlab-org/golang-archive-zip v0.1.1
gitlab.com/gitlab-org/labkit v1.18.0
gocloud.dev v0.29.0
@ -69,6 +69,7 @@ require (
github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/pprof v0.0.0-20230111200839-76d1ae5aea2b // indirect
@ -109,11 +110,11 @@ require (
github.com/yusufpapurcu/wmi v1.2.2 // indirect
go.opencensus.io v0.24.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
golang.org/x/crypto v0.6.0 // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/sys v0.7.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect

View File

@ -1057,6 +1057,8 @@ github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w
github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
@ -1499,7 +1501,7 @@ github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJys
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
github.com/miekg/dns v1.1.48/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
github.com/miekg/dns v1.1.51 h1:0+Xg7vObnhrz/4ZCZcZh7zPXlmU0aveS2HDBd0m0qSo=
github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw=
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
@ -1930,8 +1932,8 @@ github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
gitlab.com/gitlab-org/gitaly/v15 v15.10.3 h1:TiSfXoBeLGvHSEUdtyg4HYGEOJk0Y51m7fMlfiWD0Sk=
gitlab.com/gitlab-org/gitaly/v15 v15.10.3/go.mod h1:ZsyTd8zGxT4WuSZJ0G8ydJb60mauzEP0XJtZJEy/7bc=
gitlab.com/gitlab-org/gitaly/v15 v15.11.0 h1:m1O8Z8qlKo5rkQpRtfkLAai03sNWjpxjt3xD+2g2BUU=
gitlab.com/gitlab-org/gitaly/v15 v15.11.0/go.mod h1:9iVjU+Rr+6pBkX7uHrocEubpjN4k7LrwD9ezvzSrN+Y=
gitlab.com/gitlab-org/golang-archive-zip v0.1.1 h1:35k9giivbxwF03+8A05Cm8YoxoakU8FBCj5gysjCTCE=
gitlab.com/gitlab-org/golang-archive-zip v0.1.1/go.mod h1:ZDtqpWPGPB9qBuZnZDrKQjIdJtkN7ZAoVwhT6H2o2kE=
gitlab.com/gitlab-org/labkit v1.18.0 h1:uYCIqDt/5V1hLIecTR4UNc1sD2+xiYplyKeyfpNN26A=
@ -2087,8 +2089,9 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20221012134737-56aed061732a/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -2104,7 +2107,7 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230108222341-4b8118a2686a/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/exp v0.0.0-20230124195608-d38c7dcee874/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 h1:Jvc7gsqn21cJHCmAWx0LiimpP18LZmUxkT5Mp7EZ1mI=
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e h1:qyrTQ++p1afMkO4DPEeLGq/3oTsdlvdH4vqZUBWzUKM=
golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
@ -2443,8 +2446,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=

View File

@ -3,7 +3,7 @@ package secret
import (
"fmt"
"github.com/golang-jwt/jwt/v4"
"github.com/golang-jwt/jwt/v5"
)
var (

View File

@ -13,7 +13,7 @@ import (
"testing"
"time"
"github.com/golang-jwt/jwt/v4"
"github.com/golang-jwt/jwt/v5"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/labkit/log"

View File

@ -13,7 +13,7 @@ import (
"os"
"testing"
"github.com/golang-jwt/jwt/v4"
"github.com/golang-jwt/jwt/v5"
"gitlab.com/gitlab-org/labkit/log"

View File

@ -10,7 +10,7 @@ import (
"strings"
"testing"
"github.com/golang-jwt/jwt/v4"
"github.com/golang-jwt/jwt/v5"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/api"

View File

@ -12,7 +12,7 @@ import (
"strconv"
"time"
"github.com/golang-jwt/jwt/v4"
"github.com/golang-jwt/jwt/v5"
"gitlab.com/gitlab-org/labkit/log"

View File

@ -11,7 +11,7 @@ import (
"testing"
"time"
"github.com/golang-jwt/jwt/v4"
"github.com/golang-jwt/jwt/v5"
"github.com/stretchr/testify/require"
"gocloud.dev/blob"

View File

@ -3,7 +3,7 @@ package upload
import (
"context"
"github.com/golang-jwt/jwt/v4"
"github.com/golang-jwt/jwt/v5"
"net/http"
"testing"

View File

@ -9,7 +9,7 @@ import (
"mime/multipart"
"net/http"
"github.com/golang-jwt/jwt/v4"
"github.com/golang-jwt/jwt/v5"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/helper/fail"

View File

@ -13,7 +13,7 @@ import (
"strings"
"testing"
"github.com/golang-jwt/jwt/v4"
"github.com/golang-jwt/jwt/v5"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/api"