Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
		
							parent
							
								
									70c1d0352e
								
							
						
					
					
						commit
						72cb3bee79
					
				|  | @ -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" | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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' | ||||
|  |  | |||
|  | @ -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' | ||||
|  |  | |||
|  | @ -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. | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ export default function initNewBranchRefSelector() { | |||
|         props: { | ||||
|           value: defaultBranchName, | ||||
|           name: hiddenInputName, | ||||
|           queryParams: { sort: 'updated_desc' }, | ||||
|           projectId, | ||||
|         }, | ||||
|       }); | ||||
|  |  | |||
|  | @ -46,6 +46,7 @@ export const initCommitsRefSwitcher = () => { | |||
|       return createElement(RefSelector, { | ||||
|         props: { | ||||
|           projectId, | ||||
|           queryParams: { sort: 'updated_desc' }, | ||||
|           value: useSymbolicRefNames ? `refs/${refType}/${ref}` : ref, | ||||
|           useSymbolicRefNames, | ||||
|         }, | ||||
|  |  | |||
|  | @ -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', | ||||
|  |  | |||
|  | @ -14,6 +14,7 @@ export default function initNewTagRefSelector() { | |||
|           props: { | ||||
|             value: defaultBranchName, | ||||
|             name: hiddenInputName, | ||||
|             queryParams: { sort: 'updated_desc' }, | ||||
|             projectId, | ||||
|           }, | ||||
|         }); | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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 \\ | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  | @ -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 | ||||
| { | ||||
|  |  | |||
|  | @ -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. | ||||
|  |  | |||
|  | @ -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: | ||||
|  |  | |||
|  | @ -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 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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: | ||||
|  |  | |||
|  | @ -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)** | ||||
|  |  | |||
|  | @ -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) | | ||||
|  |  | |||
|  | @ -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'), | ||||
|  |  | |||
|  | @ -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}?" | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 "" | ||||
| 
 | ||||
|  |  | |||
|  | @ -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:-}" | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
|  |  | |||
|  | @ -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); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
|  |  | |||
|  | @ -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)); | ||||
|  |  | |||
|  | @ -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 | ||||
|  | @ -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 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  | @ -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 | ||||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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.
										
									
								
							
										
											Binary file not shown.
										
									
								
							|  | @ -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" | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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= | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ package secret | |||
| import ( | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"github.com/golang-jwt/jwt/v4" | ||||
| 	"github.com/golang-jwt/jwt/v5" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
|  |  | |||
|  | @ -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" | ||||
|  |  | |||
|  | @ -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" | ||||
| 
 | ||||
|  |  | |||
|  | @ -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" | ||||
|  |  | |||
|  | @ -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" | ||||
| 
 | ||||
|  |  | |||
|  | @ -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" | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ package upload | |||
| import ( | ||||
| 	"context" | ||||
| 
 | ||||
| 	"github.com/golang-jwt/jwt/v4" | ||||
| 	"github.com/golang-jwt/jwt/v5" | ||||
| 
 | ||||
| 	"net/http" | ||||
| 	"testing" | ||||
|  |  | |||
|  | @ -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" | ||||
|  |  | |||
|  | @ -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" | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue