diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 49535021b25..3306808ef4e 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-44b902da883a92ec1f19c760a083f9bf51698e41
+0bdcff0f59fb1bc52eb93e930e53965b19296c99
diff --git a/GITLAB_PAGES_VERSION b/GITLAB_PAGES_VERSION
index 034552a83ee..34aae156b19 100644
--- a/GITLAB_PAGES_VERSION
+++ b/GITLAB_PAGES_VERSION
@@ -1 +1 @@
-1.30.0
+1.31.0
diff --git a/app/assets/javascripts/design_management/utils/tracking.js b/app/assets/javascripts/design_management/utils/tracking.js
index fccb49b574b..37296f5b4ff 100644
--- a/app/assets/javascripts/design_management/utils/tracking.js
+++ b/app/assets/javascripts/design_management/utils/tracking.js
@@ -1,20 +1,22 @@
import Tracking from '~/tracking';
-import api from '~/api';
+import Api from '~/api';
// Snowplow tracking constants
const DESIGN_TRACKING_CONTEXT_SCHEMAS = {
VIEW_DESIGN_SCHEMA: 'iglu:com.gitlab/design_management_context/jsonschema/1-0-0',
};
-const DESIGN_TRACKING_EVENTS = {
+
+export const DESIGN_TRACKING_PAGE_NAME = 'projects:issues:design';
+
+export const DESIGN_SNOWPLOW_EVENT_TYPES = {
VIEW_DESIGN: 'view_design',
CREATE_DESIGN: 'create_design',
UPDATE_DESIGN: 'update_design',
};
-// Usage ping tracking constants
-const DESIGN_ACTION = 'design_action';
-
-export const DESIGN_TRACKING_PAGE_NAME = 'projects:issues:design';
+export const DESIGN_USAGE_PING_EVENT_TYPES = {
+ DESIGN_ACTION: 'design_action',
+};
/**
* Track "design detail" view in Snowplow
@@ -25,7 +27,7 @@ export function trackDesignDetailView(
designVersion = 1,
latestVersion = false,
) {
- const eventName = DESIGN_TRACKING_EVENTS.VIEW_DESIGN;
+ const eventName = DESIGN_SNOWPLOW_EVENT_TYPES.VIEW_DESIGN;
Tracking.event(DESIGN_TRACKING_PAGE_NAME, eventName, {
label: eventName,
@@ -42,16 +44,16 @@ export function trackDesignDetailView(
}
export function trackDesignCreate() {
- return Tracking.event(DESIGN_TRACKING_PAGE_NAME, DESIGN_TRACKING_EVENTS.CREATE_DESIGN);
+ return Tracking.event(DESIGN_TRACKING_PAGE_NAME, DESIGN_SNOWPLOW_EVENT_TYPES.CREATE_DESIGN);
}
export function trackDesignUpdate() {
- return Tracking.event(DESIGN_TRACKING_PAGE_NAME, DESIGN_TRACKING_EVENTS.UPDATE_DESIGN);
+ return Tracking.event(DESIGN_TRACKING_PAGE_NAME, DESIGN_SNOWPLOW_EVENT_TYPES.UPDATE_DESIGN);
}
/**
* Track "design detail" view via usage ping
*/
export function usagePingDesignDetailView() {
- api.trackRedisHllUserEvent(DESIGN_ACTION);
+ Api.trackRedisHllUserEvent(DESIGN_USAGE_PING_EVENT_TYPES.DESIGN_ACTION);
}
diff --git a/app/assets/javascripts/related_issues/components/related_issues_root.vue b/app/assets/javascripts/related_issues/components/related_issues_root.vue
index 6f68b25b6fb..73ea13ddc40 100644
--- a/app/assets/javascripts/related_issues/components/related_issues_root.vue
+++ b/app/assets/javascripts/related_issues/components/related_issues_root.vue
@@ -204,7 +204,16 @@ export default {
onInput({ untouchedRawReferences, touchedReference }) {
this.store.addPendingReferences(untouchedRawReferences);
- this.inputValue = `${touchedReference}`;
+ this.formatInput(touchedReference);
+ },
+ formatInput(touchedReference = '') {
+ const startsWithNumber = String(touchedReference).match(/^[0-9]/) !== null;
+
+ if (startsWithNumber) {
+ this.inputValue = `#${touchedReference}`;
+ } else {
+ this.inputValue = `${touchedReference}`;
+ }
},
onBlur(newValue) {
this.processAllReferences(newValue);
diff --git a/app/assets/javascripts/sourcegraph/index.js b/app/assets/javascripts/sourcegraph/index.js
index 796e90bf08e..487a565b152 100644
--- a/app/assets/javascripts/sourcegraph/index.js
+++ b/app/assets/javascripts/sourcegraph/index.js
@@ -17,7 +17,7 @@ export default function initSourcegraph() {
return;
}
- const assetsUrl = new URL('/assets/webpack/sourcegraph/', window.location.href);
+ const assetsUrl = new URL(process.env.SOURCEGRAPH_PUBLIC_PATH, window.location.href);
const scriptPath = new URL('scripts/integration.bundle.js', assetsUrl).href;
window.SOURCEGRAPH_ASSETS_URL = assetsUrl.href;
diff --git a/app/controllers/concerns/workhorse_authorization.rb b/app/controllers/concerns/workhorse_authorization.rb
index c1ed5579712..a290ba256b6 100644
--- a/app/controllers/concerns/workhorse_authorization.rb
+++ b/app/controllers/concerns/workhorse_authorization.rb
@@ -14,7 +14,7 @@ module WorkhorseAuthorization
authorized = uploader_class.workhorse_authorize(
has_length: false,
- maximum_size: Gitlab::CurrentSettings.max_attachment_size.megabytes.to_i)
+ maximum_size: maximum_size.to_i)
render json: authorized
rescue SocketError
@@ -33,6 +33,10 @@ module WorkhorseAuthorization
raise NotImplementedError
end
+ def maximum_size
+ raise NotImplementedError
+ end
+
def file_extension_whitelist
ImportExportUploader::EXTENSION_WHITELIST
end
diff --git a/app/controllers/import/gitlab_groups_controller.rb b/app/controllers/import/gitlab_groups_controller.rb
index 99e41190912..f68b76a7b36 100644
--- a/app/controllers/import/gitlab_groups_controller.rb
+++ b/app/controllers/import/gitlab_groups_controller.rb
@@ -68,4 +68,8 @@ class Import::GitlabGroupsController < ApplicationController
def uploader_class
ImportExportUploader
end
+
+ def maximum_size
+ Gitlab::CurrentSettings.max_import_size.megabytes
+ end
end
diff --git a/app/controllers/import/gitlab_projects_controller.rb b/app/controllers/import/gitlab_projects_controller.rb
index a39d1583542..0e6b0af6baf 100644
--- a/app/controllers/import/gitlab_projects_controller.rb
+++ b/app/controllers/import/gitlab_projects_controller.rb
@@ -49,4 +49,8 @@ class Import::GitlabProjectsController < Import::BaseController
def uploader_class
ImportExportUploader
end
+
+ def maximum_size
+ Gitlab::CurrentSettings.max_import_size.megabytes
+ end
end
diff --git a/app/graphql/resolvers/project_pipeline_statistics_resolver.rb b/app/graphql/resolvers/project_pipeline_statistics_resolver.rb
new file mode 100644
index 00000000000..29ab9402f5b
--- /dev/null
+++ b/app/graphql/resolvers/project_pipeline_statistics_resolver.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class ProjectPipelineStatisticsResolver < BaseResolver
+ type Types::Ci::AnalyticsType, null: true
+
+ def resolve
+ weekly_stats = Gitlab::Ci::Charts::WeekChart.new(object)
+ monthly_stats = Gitlab::Ci::Charts::MonthChart.new(object)
+ yearly_stats = Gitlab::Ci::Charts::YearChart.new(object)
+ pipeline_times = Gitlab::Ci::Charts::PipelineTime.new(object)
+
+ {
+ week_pipelines_labels: weekly_stats.labels,
+ week_pipelines_totals: weekly_stats.total,
+ week_pipelines_successful: weekly_stats.success,
+ month_pipelines_labels: monthly_stats.labels,
+ month_pipelines_totals: monthly_stats.total,
+ month_pipelines_successful: monthly_stats.success,
+ year_pipelines_labels: yearly_stats.labels,
+ year_pipelines_totals: yearly_stats.total,
+ year_pipelines_successful: yearly_stats.success,
+ pipeline_times_labels: pipeline_times.labels,
+ pipeline_times_values: pipeline_times.pipeline_times
+ }
+ end
+ end
+end
diff --git a/app/graphql/types/ci/analytics_type.rb b/app/graphql/types/ci/analytics_type.rb
new file mode 100644
index 00000000000..c8b12c6a9b8
--- /dev/null
+++ b/app/graphql/types/ci/analytics_type.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ # rubocop: disable Graphql/AuthorizeTypes
+ class AnalyticsType < BaseObject
+ graphql_name 'PipelineAnalytics'
+
+ field :week_pipelines_totals, [GraphQL::INT_TYPE], null: true,
+ description: 'Total weekly pipeline count'
+ field :week_pipelines_successful, [GraphQL::INT_TYPE], null: true,
+ description: 'Total weekly successful pipeline count'
+ field :week_pipelines_labels, [GraphQL::STRING_TYPE], null: true,
+ description: 'Labels for the weekly pipeline count'
+ field :month_pipelines_totals, [GraphQL::INT_TYPE], null: true,
+ description: 'Total monthly pipeline count'
+ field :month_pipelines_successful, [GraphQL::INT_TYPE], null: true,
+ description: 'Total monthly successful pipeline count'
+ field :month_pipelines_labels, [GraphQL::STRING_TYPE], null: true,
+ description: 'Labels for the monthly pipeline count'
+ field :year_pipelines_totals, [GraphQL::INT_TYPE], null: true,
+ description: 'Total yearly pipeline count'
+ field :year_pipelines_successful, [GraphQL::INT_TYPE], null: true,
+ description: 'Total yearly successful pipeline count'
+ field :year_pipelines_labels, [GraphQL::STRING_TYPE], null: true,
+ description: 'Labels for the yearly pipeline count'
+ field :pipeline_times_values, [GraphQL::INT_TYPE], null: true,
+ description: 'Pipeline times'
+ field :pipeline_times_labels, [GraphQL::STRING_TYPE], null: true,
+ description: 'Pipeline times labels'
+ end
+ end
+end
diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb
index 2e32c0762ee..3d0dd8a1ffd 100644
--- a/app/graphql/types/project_type.rb
+++ b/app/graphql/types/project_type.rb
@@ -304,6 +304,13 @@ module Types
description: 'Terraform states associated with the project',
resolver: Resolvers::Terraform::StatesResolver
+ field :pipeline_analytics, Types::Ci::AnalyticsType, null: true,
+ description: 'Pipeline analytics',
+ resolver: Resolvers::ProjectPipelineStatisticsResolver
+
+ field :total_pipeline_duration, GraphQL::INT_TYPE, null: true,
+ description: 'Total pipeline duration for all of the pipelines in a project'
+
def label(title:)
BatchLoader::GraphQL.for(title).batch(key: project) do |titles, loader, args|
LabelsFinder
@@ -348,6 +355,10 @@ module Types
project.container_repositories.size
end
+ def total_pipeline_duration
+ object.all_pipelines.total_duration
+ end
+
private
def project
diff --git a/app/models/project.rb b/app/models/project.rb
index 69032b3d762..7824f5610d4 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1843,6 +1843,7 @@ class Project < ApplicationRecord
wiki.repository.expire_content_cache
DetectRepositoryLanguagesWorker.perform_async(id)
+ ProjectCacheWorker.perform_async(self.id, [], [:repository_size])
# The import assigns iid values on its own, e.g. by re-using GitHub ids.
# Flush existing InternalId records for this project for consistency reasons.
diff --git a/app/services/issues/clone_service.rb b/app/services/issues/clone_service.rb
index a8c0cb05ebe..d018ba235ad 100644
--- a/app/services/issues/clone_service.rb
+++ b/app/services/issues/clone_service.rb
@@ -4,10 +4,11 @@ module Issues
class CloneService < Issuable::Clone::BaseService
CloneError = Class.new(StandardError)
- def execute(issue, target_project)
+ def execute(issue, target_project, with_notes: false)
@target_project = target_project
+ @with_notes = with_notes
- unless issue.can_clone?(current_user, @target_project)
+ unless issue.can_clone?(current_user, target_project)
raise CloneError, s_('CloneIssue|Cannot clone issue due to insufficient permissions!')
end
@@ -17,6 +18,8 @@ module Issues
super(issue, target_project)
+ notify_participants
+
queue_copy_designs
new_entity
@@ -25,12 +28,14 @@ module Issues
private
attr_reader :target_project
+ attr_reader :with_notes
def update_new_entity
# we don't call `super` because we want to be able to decide whether or not to copy all comments over.
update_new_entity_description
update_new_entity_attributes
copy_award_emoji
+ copy_notes if with_notes
end
def update_old_entity
@@ -51,7 +56,7 @@ module Issues
# Skip creation of system notes for existing attributes of the issue. The system notes of the old
# issue are copied over so we don't want to end up with duplicate notes.
- CreateService.new(@target_project, @current_user, new_params).execute(skip_system_notes: true)
+ CreateService.new(target_project, current_user, new_params).execute(skip_system_notes: true)
end
def queue_copy_designs
@@ -66,6 +71,10 @@ module Issues
log_error(response.message) if response.error?
end
+ def notify_participants
+ notification_service.async.issue_cloned(original_entity, new_entity, current_user)
+ end
+
def add_note_from
SystemNoteService.noteable_cloned(new_entity, target_project,
original_entity, current_user,
diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb
index a2c11cb0a7c..4f40ff5f535 100644
--- a/app/services/issues/update_service.rb
+++ b/app/services/issues/update_service.rb
@@ -129,13 +129,14 @@ module Issues
def clone_issue(issue)
target_project = params.delete(:target_clone_project)
+ with_notes = params.delete(:clone_with_notes)
return unless target_project &&
issue.can_clone?(current_user, target_project)
# we've pre-empted this from running in #execute, so let's go ahead and update the Issue now.
update(issue)
- Issues::CloneService.new(project, current_user).execute(issue, target_project)
+ Issues::CloneService.new(project, current_user).execute(issue, target_project, with_notes: with_notes)
end
def create_merge_request_from_quick_action
diff --git a/app/workers/concerns/limited_capacity/worker.rb b/app/workers/concerns/limited_capacity/worker.rb
index b5a97e49300..9dd8d942146 100644
--- a/app/workers/concerns/limited_capacity/worker.rb
+++ b/app/workers/concerns/limited_capacity/worker.rb
@@ -73,7 +73,7 @@ module LimitedCapacity
raise
ensure
job_tracker.remove(jid)
- report_prometheus_metrics
+ report_prometheus_metrics(*args)
re_enqueue(*args) unless exception
end
diff --git a/changelogs/unreleased/234002-conan-create-build-info.yml b/changelogs/unreleased/234002-conan-create-build-info.yml
new file mode 100644
index 00000000000..773b279e506
--- /dev/null
+++ b/changelogs/unreleased/234002-conan-create-build-info.yml
@@ -0,0 +1,5 @@
+---
+title: Conan packages show build and commit information when published using CI
+merge_request: 49426
+author:
+type: fixed
diff --git a/changelogs/unreleased/284588-prefix-sourcegraph-url-with-version.yml b/changelogs/unreleased/284588-prefix-sourcegraph-url-with-version.yml
new file mode 100644
index 00000000000..942ceb6c577
--- /dev/null
+++ b/changelogs/unreleased/284588-prefix-sourcegraph-url-with-version.yml
@@ -0,0 +1,5 @@
+---
+title: Make sure Sourcegraph asset always loads successfully
+merge_request: 49030
+author:
+type: fixed
diff --git a/changelogs/unreleased/9421-clone_with_notes-quickaction.yml b/changelogs/unreleased/9421-clone_with_notes-quickaction.yml
new file mode 100644
index 00000000000..cee4f4b2d4c
--- /dev/null
+++ b/changelogs/unreleased/9421-clone_with_notes-quickaction.yml
@@ -0,0 +1,6 @@
+---
+title: Implement a /clone_with_notes quick-action to quickly clone an Issue will all
+ its notes
+merge_request: 48539
+author:
+type: added
diff --git a/changelogs/unreleased/jivanvl-migrate-analytics-graphql-be.yml b/changelogs/unreleased/jivanvl-migrate-analytics-graphql-be.yml
new file mode 100644
index 00000000000..46c59383a29
--- /dev/null
+++ b/changelogs/unreleased/jivanvl-migrate-analytics-graphql-be.yml
@@ -0,0 +1,5 @@
+---
+title: Add CI/CD analytics GraphQL types
+merge_request: 49384
+author:
+type: added
diff --git a/changelogs/unreleased/mk-geo-primary-backfills-checksums.yml b/changelogs/unreleased/mk-geo-primary-backfills-checksums.yml
new file mode 100644
index 00000000000..a67b982c4ea
--- /dev/null
+++ b/changelogs/unreleased/mk-geo-primary-backfills-checksums.yml
@@ -0,0 +1,5 @@
+---
+title: 'Geo: Add verification indexes for package files'
+merge_request: 47372
+author:
+type: added
diff --git a/changelogs/unreleased/pages-version-v1-31-0.yml b/changelogs/unreleased/pages-version-v1-31-0.yml
new file mode 100644
index 00000000000..027d43709d6
--- /dev/null
+++ b/changelogs/unreleased/pages-version-v1-31-0.yml
@@ -0,0 +1,5 @@
+---
+title: Upgrade Pages to 1.31.0
+merge_request: 49352
+author:
+type: added
diff --git a/changelogs/unreleased/sh-update-repo-size-after-import.yml b/changelogs/unreleased/sh-update-repo-size-after-import.yml
new file mode 100644
index 00000000000..8ae92fa9711
--- /dev/null
+++ b/changelogs/unreleased/sh-update-repo-size-after-import.yml
@@ -0,0 +1,5 @@
+---
+title: Update repository size after import
+merge_request: 49319
+author:
+type: fixed
diff --git a/changelogs/unreleased/ss-related-issues-autocomplete.yml b/changelogs/unreleased/ss-related-issues-autocomplete.yml
new file mode 100644
index 00000000000..a04d32de43e
--- /dev/null
+++ b/changelogs/unreleased/ss-related-issues-autocomplete.yml
@@ -0,0 +1,5 @@
+---
+title: 'Add ability to type a number in related issues and prepend #'
+merge_request: 48952
+author:
+type: changed
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index f2315b2a431..1fae590a4d8 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -553,6 +553,9 @@ Gitlab.ee do
Settings.cron_jobs['adjourned_projects_deletion_cron_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['adjourned_projects_deletion_cron_worker']['cron'] ||= '0 4 * * *'
Settings.cron_jobs['adjourned_projects_deletion_cron_worker']['job_class'] = 'AdjournedProjectsDeletionCronWorker'
+ Settings.cron_jobs['geo_verification_cron_worker'] ||= Settingslogic.new({})
+ Settings.cron_jobs['geo_verification_cron_worker']['cron'] ||= '* * * * *'
+ Settings.cron_jobs['geo_verification_cron_worker']['job_class'] ||= 'Geo::VerificationCronWorker'
Settings.cron_jobs['geo_file_download_dispatch_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['geo_file_download_dispatch_worker']['cron'] ||= '*/1 * * * *'
Settings.cron_jobs['geo_file_download_dispatch_worker']['job_class'] ||= 'Geo::FileDownloadDispatchWorker'
diff --git a/config/webpack.config.js b/config/webpack.config.js
index c193e0d6148..42e27ea1668 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -29,9 +29,18 @@ const WEBPACK_MEMORY_TEST =
const NO_COMPRESSION = process.env.NO_COMPRESSION && process.env.NO_COMPRESSION !== 'false';
const NO_SOURCEMAPS = process.env.NO_SOURCEMAPS && process.env.NO_SOURCEMAPS !== 'false';
+const WEBPACK_OUTPUT_PATH = path.join(ROOT_PATH, 'public/assets/webpack');
+const WEBPACK_PUBLIC_PATH = '/assets/webpack/';
+const SOURCEGRAPH_PACKAGE = '@sourcegraph/code-host-integration';
+
const VUE_VERSION = require('vue/package.json').version;
const VUE_LOADER_VERSION = require('vue-loader/package.json').version;
const WEBPACK_VERSION = require('webpack/package.json').version;
+const SOURCEGRAPH_VERSION = require(path.join(SOURCEGRAPH_PACKAGE, 'package.json')).version;
+
+const SOURCEGRAPH_PATH = path.join('sourcegraph', SOURCEGRAPH_VERSION, '/');
+const SOURCEGRAPH_OUTPUT_PATH = path.join(WEBPACK_OUTPUT_PATH, SOURCEGRAPH_PATH);
+const SOURCEGRAPH_PUBLIC_PATH = path.join(WEBPACK_PUBLIC_PATH, SOURCEGRAPH_PATH);
const devtool = IS_PRODUCTION ? 'source-map' : 'cheap-module-eval-source-map';
@@ -143,7 +152,7 @@ if (VENDOR_DLL && !IS_PRODUCTION) {
dll = {
manifestPath: path.join(dllCachePath, 'vendor.dll.manifest.json'),
cacheFrom: dllCachePath,
- cacheTo: path.join(ROOT_PATH, `public/assets/webpack/dll.${dllHash}/`),
+ cacheTo: path.join(WEBPACK_OUTPUT_PATH, `dll.${dllHash}/`),
publicPath: `dll.${dllHash}/vendor.dll.bundle.js`,
exists: null,
};
@@ -157,8 +166,8 @@ module.exports = {
entry: generateEntries,
output: {
- path: path.join(ROOT_PATH, 'public/assets/webpack'),
- publicPath: '/assets/webpack/',
+ path: WEBPACK_OUTPUT_PATH,
+ publicPath: WEBPACK_PUBLIC_PATH,
filename: IS_PRODUCTION ? '[name].[contenthash:8].bundle.js' : '[name].bundle.js',
chunkFilename: IS_PRODUCTION ? '[name].[contenthash:8].chunk.js' : '[name].chunk.js',
globalObject: 'this', // allow HMR and web workers to play nice
@@ -449,11 +458,11 @@ module.exports = {
new CopyWebpackPlugin([
{
from: path.join(ROOT_PATH, 'node_modules/pdfjs-dist/cmaps/'),
- to: path.join(ROOT_PATH, 'public/assets/webpack/cmaps/'),
+ to: path.join(WEBPACK_OUTPUT_PATH, 'cmaps/'),
},
{
- from: path.join(ROOT_PATH, 'node_modules/@sourcegraph/code-host-integration/'),
- to: path.join(ROOT_PATH, 'public/assets/webpack/sourcegraph/'),
+ from: path.join(ROOT_PATH, 'node_modules', SOURCEGRAPH_PACKAGE, '/'),
+ to: SOURCEGRAPH_OUTPUT_PATH,
ignore: ['package.json'],
},
{
@@ -461,7 +470,7 @@ module.exports = {
ROOT_PATH,
'node_modules/@gitlab/visual-review-tools/dist/visual_review_toolbar.js',
),
- to: path.join(ROOT_PATH, 'public/assets/webpack'),
+ to: WEBPACK_OUTPUT_PATH,
},
]),
@@ -555,6 +564,8 @@ module.exports = {
'process.env.IS_EE': JSON.stringify(IS_EE),
// This one is used to check against "EE" properly in application code
IS_EE: IS_EE ? 'window.gon && window.gon.ee' : JSON.stringify(false),
+ // This is used by Sourcegraph because these assets are loaded dnamically
+ 'process.env.SOURCEGRAPH_PUBLIC_PATH': JSON.stringify(SOURCEGRAPH_PUBLIC_PATH),
}),
/* Pikaday has a optional dependency to moment.
diff --git a/db/migrate/20201201033202_add_verification_indexes_for_package_files.rb b/db/migrate/20201201033202_add_verification_indexes_for_package_files.rb
new file mode 100644
index 00000000000..b7f55101682
--- /dev/null
+++ b/db/migrate/20201201033202_add_verification_indexes_for_package_files.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class AddVerificationIndexesForPackageFiles < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ PENDING_VERIFICATION_INDEX_NAME = "packages_packages_pending_verification"
+ FAILED_VERIFICATION_INDEX_NAME = "packages_packages_failed_verification"
+ NEEDS_VERIFICATION_INDEX_NAME = "packages_packages_needs_verification"
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :packages_package_files, :verified_at, where: "(verification_state = 0)", order: { verified_at: 'ASC NULLS FIRST' }, name: PENDING_VERIFICATION_INDEX_NAME
+ add_concurrent_index :packages_package_files, :verification_retry_at, where: "(verification_state = 3)", order: { verification_retry_at: 'ASC NULLS FIRST' }, name: FAILED_VERIFICATION_INDEX_NAME
+ add_concurrent_index :packages_package_files, :verification_state, where: "(verification_state = 0 OR verification_state = 3)", name: NEEDS_VERIFICATION_INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :packages_package_files, PENDING_VERIFICATION_INDEX_NAME
+ remove_concurrent_index_by_name :packages_package_files, FAILED_VERIFICATION_INDEX_NAME
+ remove_concurrent_index_by_name :packages_package_files, NEEDS_VERIFICATION_INDEX_NAME
+ end
+end
diff --git a/db/schema_migrations/20201201033202 b/db/schema_migrations/20201201033202
new file mode 100644
index 00000000000..a061dc5f404
--- /dev/null
+++ b/db/schema_migrations/20201201033202
@@ -0,0 +1 @@
+418481f8281f8908740d3a8378b420f4d83853aab139b3401f7e410fc97d2488
\ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index fdd3bcc5789..301597953ab 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -22751,6 +22751,12 @@ CREATE UNIQUE INDEX one_canonical_wiki_page_slug_per_metadata ON wiki_page_slugs
CREATE INDEX package_name_index ON packages_packages USING btree (name);
+CREATE INDEX packages_packages_failed_verification ON packages_package_files USING btree (verification_retry_at NULLS FIRST) WHERE (verification_state = 3);
+
+CREATE INDEX packages_packages_needs_verification ON packages_package_files USING btree (verification_state) WHERE ((verification_state = 0) OR (verification_state = 3));
+
+CREATE INDEX packages_packages_pending_verification ON packages_package_files USING btree (verified_at NULLS FIRST) WHERE (verification_state = 0);
+
CREATE INDEX partial_index_ci_builds_on_scheduled_at_with_scheduled_jobs ON ci_builds USING btree (scheduled_at) WHERE ((scheduled_at IS NOT NULL) AND ((type)::text = 'Ci::Build'::text) AND ((status)::text = 'scheduled'::text));
CREATE INDEX partial_index_deployments_for_legacy_successful_deployments ON deployments USING btree (id) WHERE ((finished_at IS NULL) AND (status = 2));
diff --git a/doc/.vale/gitlab/AlertBoxCaution.yml b/doc/.vale/gitlab/AlertBoxCaution.yml
deleted file mode 100644
index 49d4dc62ab5..00000000000
--- a/doc/.vale/gitlab/AlertBoxCaution.yml
+++ /dev/null
@@ -1,14 +0,0 @@
----
-# Error: gitlab.AlertBoxCaution
-#
-# Makes sure CAUTION: alert boxes follow standard formatting.
-#
-# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
-extends: substitution
-message: "CAUTION: alert boxes must be of the format 'CAUTION: **Caution:**'. 'Caution' can be replaced with 'Warning' or 'Important'."
-link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#alert-boxes
-level: warning
-nonword: true
-scope: raw
-swap:
- 'CAUTION: *?\*\*.*\*\*': 'CAUTION: \*\*(?:Caution|Warning|Important):\*\*'
diff --git a/doc/.vale/gitlab/AlertBoxDanger.yml b/doc/.vale/gitlab/AlertBoxDanger.yml
deleted file mode 100644
index 2589d34614c..00000000000
--- a/doc/.vale/gitlab/AlertBoxDanger.yml
+++ /dev/null
@@ -1,14 +0,0 @@
----
-# Error: gitlab.AlertBoxDanger
-#
-# Makes sure DANGER: alert boxes follow standard formatting.
-#
-# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
-extends: substitution
-message: "DANGER: alert boxes must be of the format 'DANGER: **Warning:**'. 'Warning' can be replaced with 'Important', 'Deprecated', or 'Required'."
-link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#alert-boxes
-level: error
-nonword: true
-scope: raw
-swap:
- 'DANGER: *?\*\*.*\*\*': 'DANGER: \*\*(?:Warning|Important|Deprecated|Required):\*\*'
diff --git a/doc/.vale/gitlab/AlertBoxNoteTip.yml b/doc/.vale/gitlab/AlertBoxNoteTip.yml
deleted file mode 100644
index 62bd89f7ca6..00000000000
--- a/doc/.vale/gitlab/AlertBoxNoteTip.yml
+++ /dev/null
@@ -1,15 +0,0 @@
----
-# Error: gitlab.AlertBoxNoteTip
-#
-# Makes sure NOTE: and TIP: alert boxes follow standard formatting.
-#
-# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
-extends: substitution
-message: "NOTE: and TIP: alert boxes must be of the format 'NOTE:' or 'TIP: **Tip:**"
-link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#alert-boxes
-level: warning
-nonword: true
-scope: raw
-swap:
- 'NOTE: *?\*\*.*\*\*': 'NOTE: \*\*Note:\*\*'
- 'TIP: *?\*\*.*\*\*': 'TIP: \*\*Tip:\*\*'
diff --git a/doc/.vale/gitlab/AlertBoxStyle.yml b/doc/.vale/gitlab/AlertBoxStyle.yml
deleted file mode 100644
index d15757d38fc..00000000000
--- a/doc/.vale/gitlab/AlertBoxStyle.yml
+++ /dev/null
@@ -1,18 +0,0 @@
----
-# Error: gitlab.AlertBoxStyle
-#
-# Makes sure alert boxes follow standard formatting.
-#
-# Checks for 2 formatting issues:
-# - Alert boxes with the note text on the same line
-# - Alert boxes using blockquote formatting, like "> **Note:**"
-#
-# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
-extends: existence
-message: 'Alert box "%s" must use the formatting in the style guide.'
-link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#alert-boxes
-level: error
-scope: raw
-raw:
- - '(\n(NOTE|TIP|CAUTION|DANGER): \*\*.*\*\*.+)|'
- - '((\n[> ]*(\*){1,2}(NOTE|Note|note|TIP|Tip|tip|CAUTION|Caution|caution|DANGER|Danger|danger):(\*){1,2}))'
diff --git a/doc/administration/geo/disaster_recovery/index.md b/doc/administration/geo/disaster_recovery/index.md
index c7aaded2f91..be84b260127 100644
--- a/doc/administration/geo/disaster_recovery/index.md
+++ b/doc/administration/geo/disaster_recovery/index.md
@@ -134,7 +134,7 @@ Note the following when promoting a secondary:
1. Promote the **secondary** node to the **primary** node.
- DANGER: **Warning:**
+ WARNING:
In GitLab 13.2 and 13.3, promoting a secondary node to a primary while the
secondary is paused fails. Do not pause replication before promoting a
secondary. If the node is paused, be sure to resume before promoting. This
@@ -174,7 +174,7 @@ conjunction with multiple servers, as it can only
perform changes on a **secondary** with only a single machine. Instead, you must
do this manually.
-DANGER: **Warning:**
+WARNING:
In GitLab 13.2 and 13.3, promoting a secondary node to a primary while the
secondary is paused fails. Do not pause replication before promoting a
secondary. If the node is paused, be sure to resume before promoting. This
diff --git a/doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md b/doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md
index 2c5cbb32903..6fe4030ff54 100644
--- a/doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md
+++ b/doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md
@@ -227,7 +227,7 @@ conjunction with multiple servers, as it can only
perform changes on a **secondary** with only a single machine. Instead, you must
do this manually.
-DANGER: **Warning:**
+WARNING:
In GitLab 13.2 and 13.3, promoting a secondary node to a primary while the
secondary is paused fails. Do not pause replication before promoting a
secondary. If the node is paused, be sure to resume before promoting. This
diff --git a/doc/administration/geo/index.md b/doc/administration/geo/index.md
index aac4411637c..408dd5e12df 100644
--- a/doc/administration/geo/index.md
+++ b/doc/administration/geo/index.md
@@ -201,7 +201,7 @@ For information on how to update your Geo nodes to the latest GitLab version, se
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35913) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.2.
-DANGER: **Warning:**
+WARNING:
In GitLab 13.2 and 13.3, promoting a secondary node to a primary while the
secondary is paused fails. Do not pause replication before promoting a
secondary. If the node is paused, be sure to resume before promoting. This
diff --git a/doc/administration/geo/replication/datatypes.md b/doc/administration/geo/replication/datatypes.md
index df9ddf6818a..0d2922c3347 100644
--- a/doc/administration/geo/replication/datatypes.md
+++ b/doc/administration/geo/replication/datatypes.md
@@ -163,7 +163,7 @@ To enable, such as for package file replication:
Feature.enable(:geo_package_file_replication)
```
-DANGER: **Warning:**
+WARNING:
Features not on this list, or with **No** in the **Replicated** column,
are not replicated on the **secondary** node. Failing over without manually
replicating data from those features will cause the data to be **lost**.
diff --git a/doc/administration/geo/replication/version_specific_updates.md b/doc/administration/geo/replication/version_specific_updates.md
index 9701bc5d647..0d8eba555ab 100644
--- a/doc/administration/geo/replication/version_specific_updates.md
+++ b/doc/administration/geo/replication/version_specific_updates.md
@@ -28,7 +28,7 @@ DROP SERVER gitlab_secondary CASCADE;
DROP EXTENSION IF EXISTS postgres_fdw;
```
-DANGER: **Warning:**
+WARNING:
In GitLab 13.3, promoting a secondary node to a primary while the secondary is
paused fails. Do not pause replication before promoting a secondary. If the
node is paused, be sure to resume before promoting. To avoid this issue,
@@ -85,7 +85,7 @@ sudo touch /etc/gitlab/disable-postgresql-upgrade
## Updating to GitLab 12.7
-DANGER: **Warning:**
+WARNING:
Only upgrade to GitLab 12.7.5 or later. Do not upgrade to versions 12.7.0
through 12.7.4 because there is [an initialization order
bug](https://gitlab.com/gitlab-org/gitlab/-/issues/199672) that causes Geo
@@ -145,7 +145,7 @@ sudo touch /etc/gitlab/disable-postgresql-upgrade
## Updating to GitLab 12.3
-DANGER: **Warning:**
+WARNING:
If the existing PostgreSQL server version is 9.6.x, it is recommended to
upgrade to GitLab 12.4 or later. By default, GitLab 12.3 attempts to update the
embedded PostgreSQL server from 9.6 to 10.9. In certain circumstances, it will
@@ -159,7 +159,7 @@ For the recommended procedure, see the
## Updating to GitLab 12.2
-DANGER: **Warning:**
+WARNING:
If the existing PostgreSQL server version is 9.6.x, it is recommended to
upgrade to GitLab 12.4 or later. By default, GitLab 12.2 attempts to update the
embedded PostgreSQL server from 9.6 to 10.9. In certain circumstances, it will
@@ -189,7 +189,7 @@ The restart avoids a version mismatch when PostgreSQL tries to load the FDW exte
## Updating to GitLab 12.1
-DANGER: **Warning:**
+WARNING:
If the existing PostgreSQL server version is 9.6.x, it is recommended to
upgrade to GitLab 12.4 or later. By default, GitLab 12.1 attempts to update the
embedded PostgreSQL server from 9.6 to 10.9. In certain circumstances, it will
diff --git a/doc/administration/gitaly/index.md b/doc/administration/gitaly/index.md
index a717f126375..a7385b88feb 100644
--- a/doc/administration/gitaly/index.md
+++ b/doc/administration/gitaly/index.md
@@ -122,7 +122,7 @@ The following list depicts the network architecture of Gitaly:
- Authentication is done through a static token which is shared among the Gitaly and GitLab Rails
nodes.
-DANGER: **Warning:**
+WARNING:
Gitaly servers must not be exposed to the public internet as Gitaly's network traffic is unencrypted
by default. The use of firewall is highly recommended to restrict access to the Gitaly server.
Another option is to [use TLS](#enable-tls-support).
@@ -451,7 +451,7 @@ server (with `gitaly_address`) unless you setup with special
When you tail the Gitaly logs on your Gitaly server, you should see requests coming in. One sure way
to trigger a Gitaly request is to clone a repository from GitLab over HTTP or HTTPS.
-DANGER: **Warning:**
+WARNING:
If you have [server hooks](../server_hooks.md) configured, either per repository or globally, you
must move these to the Gitaly servers. If you have multiple Gitaly servers, copy your server hooks
to all Gitaly servers.
diff --git a/doc/administration/job_artifacts.md b/doc/administration/job_artifacts.md
index 15d672d3885..5d07e7d1b26 100644
--- a/doc/administration/job_artifacts.md
+++ b/doc/administration/job_artifacts.md
@@ -103,7 +103,7 @@ If you configure GitLab to store artifacts on object storage, you may also want
[eliminate local disk usage for job logs](job_logs.md#prevent-local-disk-usage).
In both cases, job logs are archived and moved to object storage when the job completes.
-DANGER: **Warning:**
+WARNING:
In a multi-server setup you must use one of the options to
[eliminate local disk usage for job logs](job_logs.md#prevent-local-disk-usage), or job logs could be lost.
diff --git a/doc/administration/job_logs.md b/doc/administration/job_logs.md
index b6fc27674fa..7af167de4ad 100644
--- a/doc/administration/job_logs.md
+++ b/doc/administration/job_logs.md
@@ -121,7 +121,7 @@ job output in the UI is empty.
For example, to delete all job logs older than 60 days, run the following from a shell in your GitLab instance:
-DANGER: **Warning:**
+WARNING:
This command permanently deletes the log files and is irreversible.
```shell
diff --git a/doc/administration/monitoring/performance/grafana_configuration.md b/doc/administration/monitoring/performance/grafana_configuration.md
index e3453698da6..e76e81c6499 100644
--- a/doc/administration/monitoring/performance/grafana_configuration.md
+++ b/doc/administration/monitoring/performance/grafana_configuration.md
@@ -113,7 +113,7 @@ If you require access to your old Grafana data but don't meet one of these crite
1. [Exporting the dashboards](https://grafana.com/docs/grafana/latest/reference/export_import/#exporting-a-dashboard) you need.
1. Refreshing the data and [re-importing your dashboards](https://grafana.com/docs/grafana/latest/reference/export_import/#importing-a-dashboard).
-DANGER: **Warning:**
+WARNING:
These actions pose a temporary vulnerability while your old Grafana data is in use.
Deciding to take any of these actions should be weighed carefully with your need to access
existing data and dashboards.
diff --git a/doc/administration/operations/moving_repositories.md b/doc/administration/operations/moving_repositories.md
index a62dee813f2..ac1ce851b6a 100644
--- a/doc/administration/operations/moving_repositories.md
+++ b/doc/administration/operations/moving_repositories.md
@@ -48,7 +48,7 @@ We look at three scenarios:
- The target directory contains an outdated copy of the repositories.
- How to deal with thousands of repositories.
-DANGER: **Warning:**
+WARNING:
Each of the approaches we list can or does overwrite data in the target directory
`/mnt/gitlab/repositories`. Do not mix up the source and the target.
@@ -94,7 +94,7 @@ If you want to compress the data before it goes over the network
### The target directory contains an outdated copy of the repositories: use `rsync`
-DANGER: **Warning:**
+WARNING:
Using `rsync` to migrate Git data can cause data loss and repository corruption.
[These instructions are being reviewed](https://gitlab.com/gitlab-org/gitlab/-/issues/270422).
@@ -115,7 +115,7 @@ If you want to see progress, replace `-a` with `-av`.
#### Single `rsync` to another server
-DANGER: **Warning:**
+WARNING:
Using `rsync` to migrate Git data can cause data loss and repository corruption.
[These instructions are being reviewed](https://gitlab.com/gitlab-org/gitlab/-/issues/270422).
@@ -129,7 +129,7 @@ sudo -u git sh -c 'rsync -a --delete /var/opt/gitlab/git-data/repositories/. \
### Thousands of Git repositories: use one `rsync` per repository
-DANGER: **Warning:**
+WARNING:
Using `rsync` to migrate Git data can cause data loss and repository corruption.
[These instructions are being reviewed](https://gitlab.com/gitlab-org/gitlab/-/issues/270422).
@@ -150,7 +150,7 @@ longer exist at the source.**
#### Parallel `rsync` for all repositories known to GitLab
-DANGER: **Warning:**
+WARNING:
Using `rsync` to migrate Git data can cause data loss and repository corruption.
[These instructions are being reviewed](https://gitlab.com/gitlab-org/gitlab/-/issues/270422).
@@ -211,7 +211,7 @@ cat /home/git/transfer-logs/* | sort | uniq -u |\
#### Parallel `rsync` only for repositories with recent activity
-DANGER: **Warning:**
+WARNING:
Using `rsync` to migrate Git data can cause data loss and repository corruption.
[These instructions are being reviewed](https://gitlab.com/gitlab-org/gitlab/-/issues/270422).
diff --git a/doc/administration/packages/container_registry.md b/doc/administration/packages/container_registry.md
index 667595bc1f9..8443a781ef1 100644
--- a/doc/administration/packages/container_registry.md
+++ b/doc/administration/packages/container_registry.md
@@ -485,7 +485,7 @@ you can pull from the Container Registry, but you cannot push.
[`--dryrun`](https://docs.aws.amazon.com/cli/latest/reference/s3/sync.html)
flag and run the command.
- DANGER: **Warning:**
+ WARNING:
The [`--delete`](https://docs.aws.amazon.com/cli/latest/reference/s3/sync.html)
flag deletes files that exist in the destination but not in the source.
If you swap the source and destination, all data in the Registry is deleted.
@@ -837,7 +837,7 @@ understand the implications.
> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/3097) in Omnibus GitLab 11.10.
-DANGER: **Warning:**
+WARNING:
This is a destructive operation.
The GitLab Container Registry follows the same default workflow as Docker Distribution:
diff --git a/doc/administration/pages/index.md b/doc/administration/pages/index.md
index 3baf66756f0..13dd742b53c 100644
--- a/doc/administration/pages/index.md
+++ b/doc/administration/pages/index.md
@@ -375,7 +375,7 @@ Pages access control is disabled by default. To enable it:
1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
1. Users can now configure it in their [projects' settings](../../user/project/pages/pages_access_control.md).
-NOTE: **Important:**
+NOTE:
For this setting to be effective with multi-node setups, it has to be applied to
all the App nodes and Sidekiq nodes.
@@ -431,7 +431,7 @@ For Omnibus, this is fixed by [installing a custom CA in Omnibus GitLab](https:/
> [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/merge_requests/392) in GitLab 13.7.
-DANGER: **Warning:**
+WARNING:
These are advanced settings. The recommended default values are set inside GitLab Pages. You should
change these settings only if absolutely necessary. Use extreme caution.
@@ -575,7 +575,7 @@ your main application server.
To configure GitLab Pages on a separate server:
-DANGER: **Warning:**
+WARNING:
The following procedure includes steps to back up and edit the
`gitlab-secrets.json` file. This file contains secrets that control
database encryption. Proceed with caution.
diff --git a/doc/administration/raketasks/maintenance.md b/doc/administration/raketasks/maintenance.md
index e6e3128eeef..26381434ad4 100644
--- a/doc/administration/raketasks/maintenance.md
+++ b/doc/administration/raketasks/maintenance.md
@@ -272,7 +272,7 @@ clear it.
To clear all exclusive leases:
-DANGER: **Warning:**
+WARNING:
Don't run it while GitLab or Sidekiq is running
```shell
diff --git a/doc/administration/raketasks/storage.md b/doc/administration/raketasks/storage.md
index 68874c04043..6f7bd21ca80 100644
--- a/doc/administration/raketasks/storage.md
+++ b/doc/administration/raketasks/storage.md
@@ -74,7 +74,7 @@ To have a summary and then a list of projects and their attachments using hashed
## Migrate to hashed storage
-DANGER: **Deprecated:**
+WARNING:
In GitLab 13.0, [hashed storage](../repository_storage_types.md#hashed-storage)
is enabled by default and the legacy storage is deprecated.
Support for legacy storage will be removed in GitLab 14.0. If you're on GitLab
@@ -123,7 +123,7 @@ commands below that helps you inspect projects and attachments in both legacy an
## Rollback from hashed storage to legacy storage
-DANGER: **Deprecated:**
+WARNING:
In GitLab 13.0, [hashed storage](../repository_storage_types.md#hashed-storage)
is enabled by default and the legacy storage is deprecated.
Support for legacy storage will be removed in GitLab 14.0. If you're on GitLab
diff --git a/doc/administration/repository_storage_types.md b/doc/administration/repository_storage_types.md
index f43b5cd20bf..6ec43a8ce06 100644
--- a/doc/administration/repository_storage_types.md
+++ b/doc/administration/repository_storage_types.md
@@ -117,7 +117,7 @@ The output includes the project ID and the project name:
> [Introduced](https://gitlab.com/gitlab-org/gitaly/-/issues/1606) in GitLab 12.1.
-DANGER: **Warning:**
+WARNING:
Do not run `git prune` or `git gc` in pool repositories! This can
cause data loss in "real" repositories that depend on the pool in
question.
@@ -179,7 +179,7 @@ LFS objects are also [S3 compatible](lfs/index.md#storing-lfs-objects-in-remote-
## Legacy storage
-NOTE: **Deprecated:**
+WARNING:
In GitLab 13.0, hashed storage is enabled by default and the legacy storage is
deprecated. If you haven't migrated yet, check the
[migration instructions](raketasks/storage.md#migrate-to-hashed-storage).
diff --git a/doc/administration/snippets/index.md b/doc/administration/snippets/index.md
index 5a1b8666ff7..9bc9ebc8473 100644
--- a/doc/administration/snippets/index.md
+++ b/doc/administration/snippets/index.md
@@ -29,7 +29,7 @@ This setting is not available through the [Admin Area settings](../../user/admin
In order to configure this setting, use either the Rails console
or the [Application settings API](../../api/settings.md).
-NOTE: **IMPORTANT:**
+NOTE:
The value of the limit **must** be in bytes.
#### Through the Rails console
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index 7b05391f0b6..6697e3e327f 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -15502,6 +15502,63 @@ type Pipeline {
userPermissions: PipelinePermissions!
}
+type PipelineAnalytics {
+ """
+ Labels for the monthly pipeline count
+ """
+ monthPipelinesLabels: [String!]
+
+ """
+ Total monthly successful pipeline count
+ """
+ monthPipelinesSuccessful: [Int!]
+
+ """
+ Total monthly pipeline count
+ """
+ monthPipelinesTotals: [Int!]
+
+ """
+ Pipeline times labels
+ """
+ pipelineTimesLabels: [String!]
+
+ """
+ Pipeline times
+ """
+ pipelineTimesValues: [Int!]
+
+ """
+ Labels for the weekly pipeline count
+ """
+ weekPipelinesLabels: [String!]
+
+ """
+ Total weekly successful pipeline count
+ """
+ weekPipelinesSuccessful: [Int!]
+
+ """
+ Total weekly pipeline count
+ """
+ weekPipelinesTotals: [Int!]
+
+ """
+ Labels for the yearly pipeline count
+ """
+ yearPipelinesLabels: [String!]
+
+ """
+ Total yearly successful pipeline count
+ """
+ yearPipelinesSuccessful: [Int!]
+
+ """
+ Total yearly pipeline count
+ """
+ yearPipelinesTotals: [Int!]
+}
+
"""
Autogenerated input type of PipelineCancel
"""
@@ -16936,6 +16993,11 @@ type Project {
iid: ID!
): Pipeline
+ """
+ Pipeline analytics
+ """
+ pipelineAnalytics: PipelineAnalytics
+
"""
Build pipelines of the project
"""
@@ -17347,6 +17409,11 @@ type Project {
last: Int
): TerraformStateConnection
+ """
+ Total pipeline duration for all of the pipelines in a project
+ """
+ totalPipelineDuration: Int
+
"""
Permissions for the current user on the resource
"""
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index fcefb27c229..fafc1385709 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -46054,6 +46054,261 @@
"enumValues": null,
"possibleTypes": null
},
+ {
+ "kind": "OBJECT",
+ "name": "PipelineAnalytics",
+ "description": null,
+ "fields": [
+ {
+ "name": "monthPipelinesLabels",
+ "description": "Labels for the monthly pipeline count",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "monthPipelinesSuccessful",
+ "description": "Total monthly successful pipeline count",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "monthPipelinesTotals",
+ "description": "Total monthly pipeline count",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "pipelineTimesLabels",
+ "description": "Pipeline times labels",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "pipelineTimesValues",
+ "description": "Pipeline times",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "weekPipelinesLabels",
+ "description": "Labels for the weekly pipeline count",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "weekPipelinesSuccessful",
+ "description": "Total weekly successful pipeline count",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "weekPipelinesTotals",
+ "description": "Total weekly pipeline count",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "yearPipelinesLabels",
+ "description": "Labels for the yearly pipeline count",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "yearPipelinesSuccessful",
+ "description": "Total yearly successful pipeline count",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "yearPipelinesTotals",
+ "description": "Total yearly pipeline count",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
{
"kind": "INPUT_OBJECT",
"name": "PipelineCancelInput",
@@ -49630,6 +49885,20 @@
"isDeprecated": false,
"deprecationReason": null
},
+ {
+ "name": "pipelineAnalytics",
+ "description": "Pipeline analytics",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "PipelineAnalytics",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "pipelines",
"description": "Build pipelines of the project",
@@ -50620,6 +50889,20 @@
"isDeprecated": false,
"deprecationReason": null
},
+ {
+ "name": "totalPipelineDuration",
+ "description": "Total pipeline duration for all of the pipelines in a project",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "userPermissions",
"description": "Permissions for the current user on the resource",
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index b6b80b53bb4..1bb173bbed3 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -2402,6 +2402,22 @@ Information about pagination in a connection..
| `user` | User | Pipeline user |
| `userPermissions` | PipelinePermissions! | Permissions for the current user on the resource |
+### PipelineAnalytics
+
+| Field | Type | Description |
+| ----- | ---- | ----------- |
+| `monthPipelinesLabels` | String! => Array | Labels for the monthly pipeline count |
+| `monthPipelinesSuccessful` | Int! => Array | Total monthly successful pipeline count |
+| `monthPipelinesTotals` | Int! => Array | Total monthly pipeline count |
+| `pipelineTimesLabels` | String! => Array | Pipeline times labels |
+| `pipelineTimesValues` | Int! => Array | Pipeline times |
+| `weekPipelinesLabels` | String! => Array | Labels for the weekly pipeline count |
+| `weekPipelinesSuccessful` | Int! => Array | Total weekly successful pipeline count |
+| `weekPipelinesTotals` | Int! => Array | Total weekly pipeline count |
+| `yearPipelinesLabels` | String! => Array | Labels for the yearly pipeline count |
+| `yearPipelinesSuccessful` | Int! => Array | Total yearly successful pipeline count |
+| `yearPipelinesTotals` | Int! => Array | Total yearly pipeline count |
+
### PipelineCancelPayload
Autogenerated return type of PipelineCancel.
@@ -2505,6 +2521,7 @@ Autogenerated return type of PipelineRetry.
| `packages` | PackageConnection | Packages of the project |
| `path` | String! | Path of the project |
| `pipeline` | Pipeline | Build pipeline of the project |
+| `pipelineAnalytics` | PipelineAnalytics | Pipeline analytics |
| `pipelines` | PipelineConnection | Build pipelines of the project |
| `printingMergeRequestLinkEnabled` | Boolean | Indicates if a link to create or view a merge request should display after a push to Git repositories of the project from the command line |
| `projectMembers` | MemberInterfaceConnection | Members of the project |
@@ -2535,6 +2552,7 @@ Autogenerated return type of PipelineRetry.
| `suggestionCommitMessage` | String | The commit message used to apply merge request suggestions |
| `tagList` | String | List of project topics (not Git tags) |
| `terraformStates` | TerraformStateConnection | Terraform states associated with the project |
+| `totalPipelineDuration` | Int | Total pipeline duration for all of the pipelines in a project |
| `userPermissions` | ProjectPermissions! | Permissions for the current user on the resource |
| `visibility` | String | Visibility of the project |
| `vulnerabilities` | VulnerabilityConnection | Vulnerabilities reported on the project |
diff --git a/doc/api/issues.md b/doc/api/issues.md
index c962422ae0f..3157acc5d08 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -16,7 +16,7 @@ are paginated.
Read more on [pagination](README.md#pagination).
-DANGER: **Deprecated:**
+WARNING:
The `reference` attribute in responses is deprecated in favor of `references`.
Introduced in [GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20354).
@@ -197,7 +197,7 @@ the `health_status` parameter:
]
```
-DANGER: **Deprecated:**
+WARNING:
The `assignee` column is deprecated. We now show it as a single-sized array `assignees` to conform
to the GitLab EE API.
@@ -375,7 +375,7 @@ the `health_status` parameter:
]
```
-DANGER: **Deprecated:**
+WARNING:
The `assignee` column is deprecated. We now show it as a single-sized array `assignees` to conform to the GitLab EE API.
NOTE:
@@ -558,7 +558,7 @@ the `health_status` parameter:
]
```
-DANGER: **Deprecated:**
+WARNING:
The `assignee` column is deprecated. We now show it as a single-sized array `assignees` to conform to the GitLab EE API.
NOTE:
@@ -716,11 +716,11 @@ the `epic` property:
}
```
-DANGER: **Deprecated:**
+WARNING:
The `assignee` column is deprecated. We now show it as a single-sized array `assignees` to conform
to the GitLab EE API.
-DANGER: **Deprecated:**
+WARNING:
The `epic_iid` attribute is deprecated, and [will be removed in version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157).
Please use `iid` of the `epic` attribute instead.
@@ -878,10 +878,10 @@ property:
]
```
-DANGER: **Deprecated:**
+WARNING:
The `assignee` column is deprecated. We now show it as a single-sized array `assignees` to conform to the GitLab EE API.
-DANGER: **Deprecated:**
+WARNING:
The `epic_iid` attribute is deprecated and [will be removed in version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157).
Please use `iid` of the `epic` attribute instead.
@@ -1006,7 +1006,7 @@ the `health_status` parameter:
]
```
-DANGER: **Deprecated:**
+WARNING:
The `assignee` column is deprecated. We now show it as a single-sized array `assignees` to conform to the GitLab EE API.
NOTE:
@@ -1163,7 +1163,7 @@ NOTE:
The `closed_by` attribute was [introduced in GitLab 10.6](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17042). This value is only present for issues closed after GitLab 10.6 and if the user account that closed
the issue still exists.
-DANGER: **Deprecated:**
+WARNING:
`assignee` column is deprecated. We now show it as a single-sized array `assignees` to conform to the GitLab EE API.
## Delete an issue
@@ -1324,7 +1324,7 @@ the `health_status` parameter:
]
```
-DANGER: **Deprecated:**
+WARNING:
The `assignee` column is deprecated. We now show it as a single-sized array `assignees` to conform to the GitLab EE API.
NOTE:
@@ -1433,7 +1433,7 @@ the `weight` parameter:
}
```
-DANGER: **Deprecated:**
+WARNING:
The `assignee` column is deprecated. We now show it as a single-sized array `assignees` to conform to the GitLab EE API.
NOTE:
@@ -1623,7 +1623,7 @@ Example response:
}
```
-DANGER: **Deprecated:**
+WARNING:
The `assignee` column is deprecated. We now show it as a single-sized array `assignees` to conform to the GitLab EE API.
NOTE:
diff --git a/doc/ci/docker/using_docker_build.md b/doc/ci/docker/using_docker_build.md
index 92aef4156cb..88c92c9bead 100644
--- a/doc/ci/docker/using_docker_build.md
+++ b/doc/ci/docker/using_docker_build.md
@@ -103,7 +103,7 @@ image in privileged mode.
CI builds, follow the `docker-compose`
[installation instructions](https://docs.docker.com/compose/install/).
-DANGER: **Warning:**
+WARNING:
By enabling `--docker-privileged`, you are effectively disabling all of
the security mechanisms of containers and exposing your host to privilege
escalation which can lead to container breakout. For more information, check
diff --git a/doc/ci/pipelines/job_artifacts.md b/doc/ci/pipelines/job_artifacts.md
index 44c0b774864..56e9b285e3c 100644
--- a/doc/ci/pipelines/job_artifacts.md
+++ b/doc/ci/pipelines/job_artifacts.md
@@ -427,7 +427,7 @@ information in the UI.
## Erasing artifacts
-DANGER: **Warning:**
+WARNING:
This is a destructive action that leads to data loss. Use with caution.
You can erase a single job via the UI, which also removes the job's
diff --git a/doc/ci/triggers/README.md b/doc/ci/triggers/README.md
index 22dbbbf689a..35dec43dbb4 100644
--- a/doc/ci/triggers/README.md
+++ b/doc/ci/triggers/README.md
@@ -32,7 +32,7 @@ This also applies when using the `pipelines` or `triggers` keywords with the leg
A unique trigger token can be obtained when [adding a new trigger](#adding-a-new-trigger).
-DANGER: **Warning:**
+WARNING:
Passing plain text tokens in public projects is a security issue. Potential
attackers can impersonate the user that exposed their trigger token publicly in
their `.gitlab-ci.yml` file. Use [variables](../variables/README.md#gitlab-cicd-environment-variables)
diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md
index ae5c1f7945c..da9404421fb 100644
--- a/doc/ci/yaml/README.md
+++ b/doc/ci/yaml/README.md
@@ -4332,13 +4332,13 @@ The following keywords are deprecated.
### Globally-defined `types`
-DANGER: **Deprecated:**
+WARNING:
`types` is deprecated, and could be removed in a future release.
Use [`stages`](#stages) instead.
### Job-defined `type`
-DANGER: **Deprecated:**
+WARNING:
`type` is deprecated, and could be removed in one of the future releases.
Use [`stage`](#stage) instead.
diff --git a/doc/development/chaos_endpoints.md b/doc/development/chaos_endpoints.md
index 02e88a4f5c7..b3e655e8873 100644
--- a/doc/development/chaos_endpoints.md
+++ b/doc/development/chaos_endpoints.md
@@ -24,7 +24,7 @@ Currently, there are four endpoints for simulating the following conditions:
For obvious reasons, these endpoints are not enabled by default on `production`.
They are enabled by default on **development** environments.
-DANGER: **Warning:**
+WARNING:
It is required that you secure access to the chaos endpoints using a secret token.
You should not enable them in production unless you absolutely know what you're doing.
diff --git a/doc/development/contributing/index.md b/doc/development/contributing/index.md
index d3a498a9b6f..b9a9efea836 100644
--- a/doc/development/contributing/index.md
+++ b/doc/development/contributing/index.md
@@ -37,7 +37,7 @@ Report suspected security vulnerabilities in private to
`support@gitlab.com`, also see the
[disclosure section on the GitLab.com website](https://about.gitlab.com/security/disclosure/).
-DANGER: **Warning:**
+WARNING:
Do **NOT** create publicly viewable issues for suspected security vulnerabilities.
## Code of conduct
diff --git a/doc/development/documentation/site_architecture/release_process.md b/doc/development/documentation/site_architecture/release_process.md
index 65cd77aace3..e8ec0f39702 100644
--- a/doc/development/documentation/site_architecture/release_process.md
+++ b/doc/development/documentation/site_architecture/release_process.md
@@ -163,7 +163,7 @@ Releasing a new version is a long process that involves many moving parts.
### `test_internal_links_and_anchors` failing on dropdown merge requests
-DANGER: **Deprecated:**
+WARNING:
We now pin versions in the `.gitlab-ci.yml` of the respective branch,
so the steps below are deprecated.
diff --git a/doc/development/fe_guide/icons.md b/doc/development/fe_guide/icons.md
index 53c84a570be..9c68f4c88f9 100644
--- a/doc/development/fe_guide/icons.md
+++ b/doc/development/fe_guide/icons.md
@@ -92,7 +92,7 @@ Please use the following function inside JS to render an icon:
### Usage in HAML/Rails
-DANGER: **Warning:**
+WARNING:
Do not use the `spinner` or `icon('spinner spin')` rails helpers to insert
loading icons. These helpers rely on the Font Awesome icon library which is
deprecated.
diff --git a/doc/development/feature_flags/development.md b/doc/development/feature_flags/development.md
index 6ddd4417169..9ddc6eb29df 100644
--- a/doc/development/feature_flags/development.md
+++ b/doc/development/feature_flags/development.md
@@ -193,7 +193,7 @@ if Feature.disabled?(:my_feature_flag, project, type: :ops)
end
```
-DANGER: **Warning:**
+WARNING:
Don't use feature flags at application load time. For example, using the `Feature` class in
`config/initializers/*` or at the class level could cause an unexpected error. This error occurs
because a database that a feature flag adapter might depend on doesn't exist at load time
diff --git a/doc/development/git_object_deduplication.md b/doc/development/git_object_deduplication.md
index c642e54c6aa..11ffcd70968 100644
--- a/doc/development/git_object_deduplication.md
+++ b/doc/development/git_object_deduplication.md
@@ -33,7 +33,7 @@ configuration. Objects in A that are not in B remain in A. For this
to work, it is of course critical that **no objects ever get deleted from
B** because A might need them.
-DANGER: **Warning:**
+WARNING:
Do not run `git prune` or `git gc` in pool repositories! This can
cause data loss in "real" repositories that depend on the pool in
question.
diff --git a/doc/gitlab-basics/command-line-commands.md b/doc/gitlab-basics/command-line-commands.md
index 6c6ae20f8d4..d237fa940e3 100644
--- a/doc/gitlab-basics/command-line-commands.md
+++ b/doc/gitlab-basics/command-line-commands.md
@@ -59,14 +59,14 @@ nano README.md
It's easy to delete (remove) a file or directory, but be careful:
-DANGER: **Warning:**
+WARNING:
This will **permanently** delete a file.
```shell
rm NAME-OF-FILE
```
-DANGER: **Warning:**
+WARNING:
This will **permanently** delete a directory and **all** of its contents.
```shell
diff --git a/doc/install/aws/index.md b/doc/install/aws/index.md
index 77590443eca..5e90b102276 100644
--- a/doc/install/aws/index.md
+++ b/doc/install/aws/index.md
@@ -312,7 +312,7 @@ We need a security group for our database that will allow inbound traffic from t
### Create the database
-DANGER: **Warning:**
+WARNING:
Avoid using burstable instances (t class instances) for the database as this could lead to performance issues due to CPU credits running out during sustained periods of high load.
Now, it's time to create the database:
@@ -349,7 +349,7 @@ Now that the database is created, let's move on to setting up Redis with ElastiC
ElastiCache is an in-memory hosted caching solution. Redis maintains its own
persistence and is used to store session data, temporary cache information, and background job queues for the GitLab application.
-DANGER: **Warning:**
+WARNING:
GitLab recommends you use ElastiCache Redis version 5.0.x, because version 6.x contains
a bug that [prevents Sidekiq from processing jobs](https://gitlab.com/gitlab-org/gitlab/-/issues/281683).
diff --git a/doc/install/google_cloud_platform/index.md b/doc/install/google_cloud_platform/index.md
index f1ac1b0cb95..c895cd26e0b 100644
--- a/doc/install/google_cloud_platform/index.md
+++ b/doc/install/google_cloud_platform/index.md
@@ -10,7 +10,7 @@ type: howto
This guide will help you install GitLab on a [Google Cloud Platform (GCP)](https://cloud.google.com/) instance.
-NOTE: **Alternative installation method:**
+NOTE:
Google provides a whitepaper for [deploying production-ready GitLab on
Google Kubernetes Engine](https://cloud.google.com/solutions/deploying-production-ready-gitlab-on-gke),
including all steps and external resource configuration. These are an alternative to using a GCP VM, and use
diff --git a/doc/integration/kerberos.md b/doc/integration/kerberos.md
index 3ac1d2b7f2d..5ccb1552b39 100644
--- a/doc/integration/kerberos.md
+++ b/doc/integration/kerberos.md
@@ -216,7 +216,7 @@ GitLab users with a linked Kerberos account can also `git pull` and `git push`
using Kerberos tokens, i.e., without having to send their password with each
operation.
-DANGER: **Warning:**
+WARNING:
There is a [known issue](https://github.com/curl/curl/issues/1261) with `libcurl`
older than version 7.64.1 wherein it won't reuse connections when negotiating.
This leads to authorization issues when push is larger than `http.postBuffer`
diff --git a/doc/operations/incident_management/alert_integrations.md b/doc/operations/incident_management/alert_integrations.md
index e380df94ea1..b4597110935 100644
--- a/doc/operations/incident_management/alert_integrations.md
+++ b/doc/operations/incident_management/alert_integrations.md
@@ -170,7 +170,7 @@ If the existing alert is already `resolved`, GitLab creates a new alert instead.
## Link to your Opsgenie Alerts
-DANGER: **Deprecated:**
+WARNING:
We are building deeper integration with Opsgenie and other alerting tools through
[HTTP endpoint integrations](#generic-http-endpoint) so you can see alerts within
the GitLab interface. As a result, the previous direct link to Opsgenie Alerts from
diff --git a/doc/raketasks/cleanup.md b/doc/raketasks/cleanup.md
index e03d1cd6411..0c184aa0075 100644
--- a/doc/raketasks/cleanup.md
+++ b/doc/raketasks/cleanup.md
@@ -12,7 +12,7 @@ GitLab provides Rake tasks for cleaning up GitLab instances.
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/36628) in GitLab 12.10.
-DANGER: **Warning:**
+WARNING:
Do not run this within 12 hours of a GitLab upgrade. This is to ensure that all background migrations
have finished, which otherwise may lead to data loss.
diff --git a/doc/topics/autodevops/customize.md b/doc/topics/autodevops/customize.md
index ed863edfe7c..be7f9071dde 100644
--- a/doc/topics/autodevops/customize.md
+++ b/doc/topics/autodevops/customize.md
@@ -243,7 +243,7 @@ include:
See the [Auto DevOps template](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml) for information on available jobs.
-DANGER: **Deprecated:**
+WARNING:
Auto DevOps templates using the [`only`](../../ci/yaml/README.md#onlyexcept-basic) or
[`except`](../../ci/yaml/README.md#onlyexcept-basic) syntax have switched
to the [`rules`](../../ci/yaml/README.md#rules) syntax, starting in
diff --git a/doc/topics/autodevops/index.md b/doc/topics/autodevops/index.md
index 6cadf68d10b..11b8bcdc2f0 100644
--- a/doc/topics/autodevops/index.md
+++ b/doc/topics/autodevops/index.md
@@ -410,7 +410,7 @@ If you receive this error, you can do one of the following actions:
database by setting `AUTO_DEVOPS_POSTGRES_DELETE_V1` to a non-empty value and
redeploying.
- DANGER: **Warning:**
+ WARNING:
Deleting the channel 1 PostgreSQL database permanently deletes the existing
channel 1 database and all its data. See
[Upgrading PostgreSQL](upgrading_postgresql.md)
@@ -424,7 +424,7 @@ If you receive this error, you can do one of the following actions:
and persisted by Helm, regardless of whether or not your chart uses the
variable.
-DANGER: **Warning:**
+WARNING:
Setting `POSTGRES_ENABLED` to `false` permanently deletes any existing
channel 1 database for your environment.
diff --git a/doc/topics/autodevops/stages.md b/doc/topics/autodevops/stages.md
index 6825fd6785a..2f84b00af61 100644
--- a/doc/topics/autodevops/stages.md
+++ b/doc/topics/autodevops/stages.md
@@ -288,7 +288,7 @@ see the documentation.
To use a custom target instead of the auto-deployed review apps,
set a `DAST_WEBSITE` environment variable to the URL for DAST to scan.
-DANGER: **Warning:**
+WARNING:
If [DAST Full Scan](../../user/application_security/dast/index.md#full-scan) is
enabled, GitLab strongly advises **not**
to set `DAST_WEBSITE` to any staging or production environment. DAST Full Scan
@@ -431,7 +431,7 @@ To use Auto Deploy on a Kubernetes 1.16+ cluster:
1. If you are deploying your application for the first time and are using
GitLab 12.9 or 12.10, set `AUTO_DEVOPS_POSTGRES_CHANNEL` to `2`.
-DANGER: **Warning:**
+WARNING:
On GitLab 12.9 and 12.10, opting into
`AUTO_DEVOPS_POSTGRES_CHANNEL` version `2` deletes the version `1` PostgreSQL
database. Follow the [guide to upgrading PostgreSQL](upgrading_postgresql.md)
diff --git a/doc/topics/git/lfs/migrate_from_git_annex_to_git_lfs.md b/doc/topics/git/lfs/migrate_from_git_annex_to_git_lfs.md
index 16a14fdbd97..224dcc797d5 100644
--- a/doc/topics/git/lfs/migrate_from_git_annex_to_git_lfs.md
+++ b/doc/topics/git/lfs/migrate_from_git_annex_to_git_lfs.md
@@ -7,7 +7,7 @@ type: reference, howto
# Migration guide from Git Annex to Git LFS
-DANGER: **Deprecated:**
+WARNING:
Git Annex support [has been removed](https://gitlab.com/gitlab-org/gitlab/-/issues/1648) in GitLab Enterprise
Edition 9.0 (2017/03/22).
diff --git a/doc/user/admin_area/monitoring/health_check.md b/doc/user/admin_area/monitoring/health_check.md
index 0df651a5038..01a172fc0d1 100644
--- a/doc/user/admin_area/monitoring/health_check.md
+++ b/doc/user/admin_area/monitoring/health_check.md
@@ -105,7 +105,7 @@ This check is being exempt from Rack Attack.
## Liveness
-DANGER: **Warning:**
+WARNING:
In GitLab [12.4](https://about.gitlab.com/upcoming-releases/)
the response body of the Liveness check was changed
to match the example below.
diff --git a/doc/user/application_security/api_fuzzing/index.md b/doc/user/application_security/api_fuzzing/index.md
index 3789a8c1e19..9113b3d204d 100644
--- a/doc/user/application_security/api_fuzzing/index.md
+++ b/doc/user/application_security/api_fuzzing/index.md
@@ -139,7 +139,7 @@ This is a minimal configuration for API Fuzzing. From here you can:
- [Add authentication](#authentication).
- Learn how to [handle false positives](#handling-false-positives).
-DANGER: **Warning:**
+WARNING:
**NEVER** run fuzz testing against a production server. Not only can it perform *any* function that
the API can, it may also trigger bugs in the API. This includes actions like modifying and deleting
data. Only run fuzzing against a test server.
@@ -158,7 +158,7 @@ You can use various tools to generate HAR files:
- [Chrome](https://www.google.com/chrome/): Browser
- [Firefox](https://www.mozilla.org/en-US/firefox/): Browser
-DANGER: **Warning:**
+WARNING:
HAR files may contain sensitive information such as authentication tokens, API keys, and session
cookies. We recommend that you review the HAR file contents before adding them to a repository.
@@ -230,7 +230,7 @@ This is a minimal configuration for API Fuzzing. From here you can:
- [Add authentication](#authentication).
- Learn how to [handle false positives](#handling-false-positives).
-DANGER: **Warning:**
+WARNING:
**NEVER** run fuzz testing against a production server. Not only can it perform *any* function that
the API can, it may also trigger bugs in the API. This includes actions like modifying and deleting
data. Only run fuzzing against a test server.
@@ -247,7 +247,7 @@ When used with GitLab's API fuzzer, Postman Collections must contain definitions
test with valid data. The API fuzzer extracts all the API definitions and uses them to perform
testing.
-DANGER: **Warning:**
+WARNING:
Postman Collection files may contain sensitive information such as authentication tokens, API keys,
and session cookies. We recommend that you review the Postman Collection file contents before adding
them to a repository.
@@ -321,7 +321,7 @@ This is a minimal configuration for API Fuzzing. From here you can:
- [Add authentication](#authentication).
- Learn how to [handle false positives](#handling-false-positives).
-DANGER: **Warning:**
+WARNING:
**NEVER** run fuzz testing against a production server. Not only can it perform *any* function that
the API can, it may also trigger bugs in the API. This includes actions like modifying and deleting
data. Only run fuzzing against a test server.
diff --git a/doc/user/application_security/dast/index.md b/doc/user/application_security/dast/index.md
index 48a7c0a5f2b..f4401fa6445 100644
--- a/doc/user/application_security/dast/index.md
+++ b/doc/user/application_security/dast/index.md
@@ -204,7 +204,7 @@ The results are saved as a
that you can later download and analyze.
Due to implementation limitations, we always take the latest DAST artifact available.
-DANGER: **Warning:**
+WARNING:
**NEVER** run an authenticated scan against a production server. When an authenticated
scan is run, it may perform *any* function that the authenticated user can. This
includes actions like modifying and deleting data, submitting forms, and following links.
diff --git a/doc/user/application_security/secret_detection/index.md b/doc/user/application_security/secret_detection/index.md
index 160c245b775..19be55c0d77 100644
--- a/doc/user/application_security/secret_detection/index.md
+++ b/doc/user/application_security/secret_detection/index.md
@@ -40,19 +40,26 @@ The [default ruleset provided by Gitleaks](https://gitlab.com/gitlab-org/securit
- Cloud services:
- Amazon Web Services (AWS)
- Google Cloud Platform (GCP)
-Encryption keys:
+ - Heroku API
+- Encryption keys:
- PKCS8
- RSA
- SSH
- PGP
+ - DSA
+ - EC
- Social media platforms:
- Facebook API
- Twitter API
- Cloud SaaS vendors:
- GitHub API
- Slack Token
+ - Slack Webhook
- Stripe API
+ - Twilio API
- Generic API key strings starting with `api-`
+- Password in URL
+- U.S. Social Security Number
## Requirements
@@ -252,6 +259,27 @@ We have created a [short video walkthrough](https://youtu.be/wDtc_K00Y0A) showca
+## Running Secret Detection in an offline environment
+
+For self-managed GitLab instances in an environment with limited, restricted, or intermittent access
+to external resources through the internet, some adjustments are required for the Secret Detection job to
+run successfully. For more information, see [Offline environments](../offline_deployments/index.md).
+
+### Requirements for offline Secret Detection
+
+To use Secret Detection in an offline environment, you need:
+
+- GitLab Runner with the [`docker` or `kubernetes` executor](#requirements).
+- A Docker Container Registry with locally available copy of Secret Detection [analyzer](https://gitlab.com/gitlab-org/security-products/analyzers) images.
+- Configure certificate checking of packages (optional).
+
+GitLab Runner has a [default `pull policy` of `always`](https://docs.gitlab.com/runner/executors/docker.html#using-the-always-pull-policy),
+meaning the runner tries to pull Docker images from the GitLab container registry even if a local
+copy is available. The GitLab Runner [`pull_policy` can be set to `if-not-present`](https://docs.gitlab.com/runner/executors/docker.html#using-the-if-not-present-pull-policy)
+in an offline environment if you prefer using only locally available Docker images. However, we
+recommend keeping the pull policy setting to `always` if not in an offline environment, as this
+enables the use of updated scanners in your CI/CD pipelines.
+
### Make GitLab Secret Detection analyzer image available inside your Docker registry
Import the following default Secret Detection analyzer images from `registry.gitlab.com` into your
@@ -278,6 +306,22 @@ Support for custom certificate authorities was introduced in the following versi
| -------- | ------- |
| secrets | [v3.0.0](https://gitlab.com/gitlab-org/security-products/analyzers/secrets/-/releases/v3.0.0) |
+### Set Secret Detection CI job variables to use local Secret Detection analyzer
+
+Add the following configuration to your `.gitlab-ci.yml` file. You must replace
+`SECURE_ANALYZERS_PREFIX` to refer to your local Docker container registry:
+
+```yaml
+include:
+ - template: Security/Secret-Detection.gitlab-ci.yml
+
+variables:
+ SECURE_ANALYZERS_PREFIX: "localhost:5000/analyzers"
+```
+
+The Secret Detection job should now use local copies of the Secret Detection analyzer to scan your code and generate
+security reports without requiring internet access.
+
## Troubleshooting
### Getting warning message `gl-secret-detection-report.json: no matching files`
diff --git a/doc/user/profile/account/delete_account.md b/doc/user/profile/account/delete_account.md
index f1895e11571..e347221bd66 100644
--- a/doc/user/profile/account/delete_account.md
+++ b/doc/user/profile/account/delete_account.md
@@ -35,7 +35,7 @@ As an administrator, you can delete a user account by:
- **Delete user and contributions** to delete the user and
their associated records.
-DANGER: **Warning:**
+WARNING:
Using the **Delete user and contributions** option may result
in removing more data than intended. Please see [associated records](#associated-records)
below for additional details.
diff --git a/doc/user/profile/active_sessions.md b/doc/user/profile/active_sessions.md
index 4716740ba3d..381015f17c3 100644
--- a/doc/user/profile/active_sessions.md
+++ b/doc/user/profile/active_sessions.md
@@ -32,7 +32,7 @@ exceeds 100, the oldest ones are deleted.
1. Use the previous steps to navigate to **Active Sessions**.
1. Click on **Revoke** besides a session. The current session cannot be revoked, as this would sign you out of GitLab.
-NOTE: **Note:**
+NOTE:
When any session is revoked all **Remember me** tokens for all
devices are revoked. See ['Why do I keep getting signed out?'](index.md#why-do-i-keep-getting-signed-out)
for more information about the **Remember me** feature.
diff --git a/doc/user/project/deploy_boards.md b/doc/user/project/deploy_boards.md
index dd7b2bf99d2..90bad9529d8 100644
--- a/doc/user/project/deploy_boards.md
+++ b/doc/user/project/deploy_boards.md
@@ -74,7 +74,7 @@ To display the Deploy Boards for a specific [environment](../../ci/environments/
1. Have a Kubernetes cluster up and running.
- NOTE: **Running on OpenShift:**
+ NOTE:
If you are using OpenShift, ensure that you're using the `Deployment` resource
instead of `DeploymentConfiguration`. Otherwise, the Deploy Boards won't render
correctly. For more information, read the
diff --git a/doc/user/project/quick_actions.md b/doc/user/project/quick_actions.md
index 45289d615a8..5b82a411401 100644
--- a/doc/user/project/quick_actions.md
+++ b/doc/user/project/quick_actions.md
@@ -34,7 +34,7 @@ The following quick actions are applicable to descriptions, discussions and thre
| `/award :emoji:` | ✓ | ✓ | ✓ | Toggle emoji award. |
| `/child_epic ` | | | ✓ | Add child epic to ``. The `` value should be in the format of `&epic`, `group&epic`, or a URL to an epic ([introduced in GitLab 12.0](https://gitlab.com/gitlab-org/gitlab/-/issues/7330)). **(ULTIMATE)** |
| `/clear_weight` | ✓ | | | Clear weight. **(STARTER)** |
-| `/clone ` | ✓ | | | Clone the issue to given project, or the current one if no arguments are given ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9421) in GitLab 13.7). Copies as much data as possible as long as the target project contains equivalent labels, milestones, etc. Does not copy comments or system notes. |
+| `/clone [--with_notes]`| ✓ | | | Clone the issue to given project, or the current one if no arguments are given ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9421) in GitLab 13.7). Copies as much data as possible as long as the target project contains equivalent labels, milestones, and so on. Does not copy comments or system notes unless `--with_notes` is provided as an argument. |
| `/close` | ✓ | ✓ | ✓ | Close. |
| `/confidential` | ✓ | | | Make confidential. |
| `/copy_metadata ` | ✓ | ✓ | | Copy labels and milestone from another merge request in the project. |
diff --git a/doc/user/project/repository/reducing_the_repo_size_using_git.md b/doc/user/project/repository/reducing_the_repo_size_using_git.md
index c743d7a2fa9..3dfb0ddec95 100644
--- a/doc/user/project/repository/reducing_the_repo_size_using_git.md
+++ b/doc/user/project/repository/reducing_the_repo_size_using_git.md
@@ -18,7 +18,7 @@ We **recommend [`git filter-repo`](https://github.com/newren/git-filter-repo/blo
over [`git filter-branch`](https://git-scm.com/docs/git-filter-branch) and
[BFG](https://rtyley.github.io/bfg-repo-cleaner/).
-DANGER: **Warning:**
+WARNING:
Rewriting repository history is a destructive operation. Make sure to back up your repository before
you begin. The best way back up a repository is to
[export the project](../settings/import_export.md#exporting-a-project-and-its-data).
diff --git a/doc/user/project/service_desk.md b/doc/user/project/service_desk.md
index d3156d860c8..3b9a2319ca5 100644
--- a/doc/user/project/service_desk.md
+++ b/doc/user/project/service_desk.md
@@ -76,7 +76,7 @@ Follow these steps to do so:
address's format. The older format is still supported, however, allowing existing aliases or
contacts to continue working.
- DANGER: **Warning:**
+ WARNING:
This email address can be used by anyone to create an issue on this project, whether or not they
have access to your GitLab instance. We recommend **putting this behind an alias** so it can be
changed if needed, and **[enabling Akismet](../../integration/akismet.md)** on your GitLab
diff --git a/doc/user/search/advanced_global_search.md b/doc/user/search/advanced_global_search.md
index ccc083e94f4..3a52cb3671f 100644
--- a/doc/user/search/advanced_global_search.md
+++ b/doc/user/search/advanced_global_search.md
@@ -9,7 +9,7 @@ type: reference
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/109) in GitLab [Starter](https://about.gitlab.com/pricing/) 8.4.
-NOTE: **GitLab.com availability:**
+NOTE:
Advanced Search (powered by Elasticsearch) is enabled for Bronze and above on GitLab.com since 2020-07-10.
Leverage Elasticsearch for faster, more advanced code search across your entire
diff --git a/doc/user/search/advanced_search_syntax.md b/doc/user/search/advanced_search_syntax.md
index 6786b1053ae..afca2c349fa 100644
--- a/doc/user/search/advanced_search_syntax.md
+++ b/doc/user/search/advanced_search_syntax.md
@@ -9,7 +9,7 @@ type: reference
> - Introduced in [GitLab Enterprise Starter](https://about.gitlab.com/pricing/) 9.2
-NOTE: **GitLab.com availability:**
+NOTE:
Advanced Search (powered by Elasticsearch) is enabled for Bronze and above on GitLab.com since 2020-07-10.
Use advanced queries for more targeted search results.
diff --git a/lib/api/helpers/packages/conan/api_helpers.rb b/lib/api/helpers/packages/conan/api_helpers.rb
index 0e34a5c9a76..39ecfc171a9 100644
--- a/lib/api/helpers/packages/conan/api_helpers.rb
+++ b/lib/api/helpers/packages/conan/api_helpers.rb
@@ -222,6 +222,7 @@ module API
return unless route_authentication_setting[:job_token_allowed]
job = find_job_from_token || raise(::Gitlab::Auth::UnauthorizedError)
+ @current_authenticated_job = job # rubocop:disable Gitlab/ModuleWithInstanceVariables
job.user
end
diff --git a/lib/gitlab/quick_actions/issue_actions.rb b/lib/gitlab/quick_actions/issue_actions.rb
index 400547bb6c1..1822b0c8bd5 100644
--- a/lib/gitlab/quick_actions/issue_actions.rb
+++ b/lib/gitlab/quick_actions/issue_actions.rb
@@ -106,17 +106,28 @@ module Gitlab
explanation do |project = quick_action_target.project.full_path|
_("Clones this issue, without comments, to %{project}.") % { project: project }
end
- params 'path/to/project'
+ params 'path/to/project [--with_notes]'
types Issue
condition do
quick_action_target.persisted? &&
current_user.can?(:"admin_#{quick_action_target.to_ability_name}", project)
end
- command :clone do |target_project_path = nil|
+ command :clone do |params = ''|
+ params = params.split(' ')
+ with_notes = params.delete('--with_notes').present?
+
+ # If we have more than 1 param, then the user supplied too many spaces, or mistyped `--with_notes`
+ if params.size > 1
+ @execution_message[:clone] = _('Failed to clone this issue: wrong parameters.')
+ next
+ end
+
+ target_project_path = params[0]
target_project = target_project_path.present? ? Project.find_by_full_path(target_project_path) : quick_action_target.project
if target_project.present?
@updates[:target_clone_project] = target_project
+ @updates[:clone_with_notes] = with_notes
message = _("Cloned this issue to %{path_to_project}.") % { path_to_project: target_project_path || quick_action_target.project.full_path }
else
diff --git a/lib/gitlab/usage_data_counters/counter_events/guest_package_events.yml b/lib/gitlab/usage_data_counters/counter_events/guest_package_events.yml
new file mode 100644
index 00000000000..a9b9f8ea235
--- /dev/null
+++ b/lib/gitlab/usage_data_counters/counter_events/guest_package_events.yml
@@ -0,0 +1,34 @@
+---
+- i_package_composer_guest_delete
+- i_package_composer_guest_pull
+- i_package_composer_guest_push
+- i_package_conan_guest_delete
+- i_package_conan_guest_pull
+- i_package_conan_guest_push
+- i_package_container_guest_delete
+- i_package_container_guest_pull
+- i_package_container_guest_push
+- i_package_debian_guest_delete
+- i_package_debian_guest_pull
+- i_package_debian_guest_push
+- i_package_generic_guest_delete
+- i_package_generic_guest_pull
+- i_package_generic_guest_push
+- i_package_golang_guest_delete
+- i_package_golang_guest_pull
+- i_package_golang_guest_push
+- i_package_maven_guest_delete
+- i_package_maven_guest_pull
+- i_package_maven_guest_push
+- i_package_npm_guest_delete
+- i_package_npm_guest_pull
+- i_package_npm_guest_push
+- i_package_nuget_guest_delete
+- i_package_nuget_guest_pull
+- i_package_nuget_guest_push
+- i_package_pypi_guest_delete
+- i_package_pypi_guest_pull
+- i_package_pypi_guest_push
+- i_package_tag_guest_delete
+- i_package_tag_guest_pull
+- i_package_tag_guest_push
diff --git a/lib/gitlab/usage_data_counters/guest_package_event_counter.rb b/lib/gitlab/usage_data_counters/guest_package_event_counter.rb
new file mode 100644
index 00000000000..a9bcbfadda2
--- /dev/null
+++ b/lib/gitlab/usage_data_counters/guest_package_event_counter.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module UsageDataCounters
+ class GuestPackageEventCounter < BaseCounter
+ KNOWN_EVENTS_PATH = File.expand_path('counter_events/guest_package_events.yml', __dir__)
+ KNOWN_EVENTS = YAML.safe_load(File.read(KNOWN_EVENTS_PATH)).freeze
+ PREFIX = 'package_guest'
+ end
+ end
+end
diff --git a/lib/tasks/gitlab/packages/events.rake b/lib/tasks/gitlab/packages/events.rake
index 14d47c02e31..ca507fb5320 100644
--- a/lib/tasks/gitlab/packages/events.rake
+++ b/lib/tasks/gitlab/packages/events.rake
@@ -5,11 +5,29 @@ namespace :gitlab do
namespace :packages do
namespace :events do
task generate: :environment do
+ Rake::Task["gitlab:packages:events:generate_guest"].invoke
+ Rake::Task["gitlab:packages:events:generate_unique"].invoke
+ rescue => e
+ logger.error("Error building events list: #{e}")
+ end
+
+ task generate_guest: :environment do
logger = Logger.new(STDOUT)
logger.info('Building list of package events...')
- path = File.join(File.dirname(::Gitlab::UsageDataCounters::HLLRedisCounter::KNOWN_EVENTS_PATH), 'package_events.yml')
+ path = Gitlab::UsageDataCounters::GuestPackageEventCounter::KNOWN_EVENTS_PATH
+ File.open(path, "w") { |file| file << guest_events_list.to_yaml }
+ logger.info("Events file `#{path}` generated successfully")
+ rescue => e
+ logger.error("Error building events list: #{e}")
+ end
+
+ task generate_unique: :environment do
+ logger = Logger.new(STDOUT)
+ logger.info('Building list of package events...')
+
+ path = File.join(File.dirname(Gitlab::UsageDataCounters::HLLRedisCounter::KNOWN_EVENTS_PATH), 'package_events.yml')
File.open(path, "w") { |file| file << generate_unique_events_list.to_yaml }
logger.info("Events file `#{path}` generated successfully")
@@ -17,14 +35,16 @@ namespace :gitlab do
logger.error("Error building events list: #{e}")
end
+ private
+
def event_pairs
- ::Packages::Event.event_types.keys.product(::Packages::Event::EVENT_SCOPES.keys)
+ Packages::Event.event_types.keys.product(Packages::Event::EVENT_SCOPES.keys)
end
def generate_unique_events_list
events = event_pairs.each_with_object([]) do |(event_type, event_scope), events|
- ::Packages::Event.originator_types.keys.excluding('guest').each do |originator|
- if name = ::Packages::Event.allowed_event_name(event_scope, event_type, originator)
+ Packages::Event.originator_types.keys.excluding('guest').each do |originator|
+ if name = Packages::Event.allowed_event_name(event_scope, event_type, originator)
events << {
"name" => name,
"category" => "#{event_scope}_packages",
@@ -38,6 +58,12 @@ namespace :gitlab do
events.sort_by { |event| event["name"] }
end
+
+ def guest_events_list
+ event_pairs.map do |event_type, event_scope|
+ Packages::Event.allowed_event_name(event_scope, event_type, "guest")
+ end.compact.sort
+ end
end
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index f5113f7f441..53e92f806ee 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -11469,6 +11469,9 @@ msgstr ""
msgid "Failed to clone this issue because target project doesn't exist."
msgstr ""
+msgid "Failed to clone this issue: wrong parameters."
+msgstr ""
+
msgid "Failed to create Merge Request. Please try again."
msgstr ""
diff --git a/spec/frontend/design_management/pages/design/index_spec.js b/spec/frontend/design_management/pages/design/index_spec.js
index 88892bb1878..9c11af28cf0 100644
--- a/spec/frontend/design_management/pages/design/index_spec.js
+++ b/spec/frontend/design_management/pages/design/index_spec.js
@@ -2,7 +2,9 @@ import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueRouter from 'vue-router';
import { GlAlert } from '@gitlab/ui';
import { ApolloMutation } from 'vue-apollo';
+import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import createFlash from '~/flash';
+import Api from '~/api';
import DesignIndex from '~/design_management/pages/design/index.vue';
import DesignSidebar from '~/design_management/components/design_sidebar.vue';
import DesignPresentation from '~/design_management/components/design_presentation.vue';
@@ -20,8 +22,14 @@ import design from '../../mock_data/design';
import mockResponseWithDesigns from '../../mock_data/designs';
import mockResponseNoDesigns from '../../mock_data/no_designs';
import mockAllVersions from '../../mock_data/all_versions';
+import {
+ DESIGN_TRACKING_PAGE_NAME,
+ DESIGN_SNOWPLOW_EVENT_TYPES,
+ DESIGN_USAGE_PING_EVENT_TYPES,
+} from '~/design_management/utils/tracking';
jest.mock('~/flash');
+jest.mock('~/api.js');
const focusInput = jest.fn();
const mutate = jest.fn().mockResolvedValue();
@@ -81,7 +89,10 @@ describe('Design management design index page', () => {
const findSidebar = () => wrapper.find(DesignSidebar);
const findDesignPresentation = () => wrapper.find(DesignPresentation);
- function createComponent({ loading = false } = {}, { data = {}, intialRouteOptions = {} } = {}) {
+ function createComponent(
+ { loading = false } = {},
+ { data = {}, intialRouteOptions = {}, provide = {} } = {},
+ ) {
const $apollo = {
queries: {
design: {
@@ -106,6 +117,7 @@ describe('Design management design index page', () => {
provide: {
issueIid: '1',
projectPath: 'project-path',
+ ...provide,
},
data() {
return {
@@ -343,4 +355,64 @@ describe('Design management design index page', () => {
});
});
});
+
+ describe('tracking', () => {
+ let trackingSpy;
+
+ beforeEach(() => {
+ trackingSpy = mockTracking('_category_', undefined, jest.spyOn);
+ });
+
+ afterEach(() => {
+ unmockTracking();
+ });
+
+ describe('on mount', () => {
+ it('tracks design view in snowplow', () => {
+ createComponent({ loading: true });
+
+ expect(trackingSpy).toHaveBeenCalledTimes(1);
+ expect(trackingSpy).toHaveBeenCalledWith(
+ DESIGN_TRACKING_PAGE_NAME,
+ DESIGN_SNOWPLOW_EVENT_TYPES.VIEW_DESIGN,
+ {
+ context: {
+ data: {
+ 'design-collection-owner': 'issue',
+ 'design-is-current-version': true,
+ 'design-version-number': 1,
+ 'internal-object-referrer': 'issue-design-collection',
+ },
+ schema: 'iglu:com.gitlab/design_management_context/jsonschema/1-0-0',
+ },
+ label: DESIGN_SNOWPLOW_EVENT_TYPES.VIEW_DESIGN,
+ },
+ );
+ });
+
+ describe('with usage_data_design_action enabled', () => {
+ it('tracks design view usage ping', () => {
+ createComponent(
+ { loading: true },
+ {
+ provide: {
+ glFeatures: { usageDataDesignAction: true },
+ },
+ },
+ );
+ expect(Api.trackRedisHllUserEvent).toHaveBeenCalledTimes(1);
+ expect(Api.trackRedisHllUserEvent).toHaveBeenCalledWith(
+ DESIGN_USAGE_PING_EVENT_TYPES.DESIGN_ACTION,
+ );
+ });
+ });
+
+ describe('with usage_data_design_action disabled', () => {
+ it("doesn't track design view usage ping", () => {
+ createComponent({ loading: true });
+ expect(Api.trackRedisHllUserEvent).toHaveBeenCalledTimes(0);
+ });
+ });
+ });
+ });
});
diff --git a/spec/frontend/design_management/pages/index_spec.js b/spec/frontend/design_management/pages/index_spec.js
index 05238efd761..147169dd9aa 100644
--- a/spec/frontend/design_management/pages/index_spec.js
+++ b/spec/frontend/design_management/pages/index_spec.js
@@ -31,7 +31,10 @@ import {
moveDesignMutationResponseWithErrors,
} from '../mock_data/apollo_mock';
import moveDesignMutation from '~/design_management/graphql/mutations/move_design.mutation.graphql';
-import { DESIGN_TRACKING_PAGE_NAME } from '~/design_management/utils/tracking';
+import {
+ DESIGN_TRACKING_PAGE_NAME,
+ DESIGN_SNOWPLOW_EVENT_TYPES,
+} from '~/design_management/utils/tracking';
jest.mock('~/flash.js');
const mockPageEl = {
@@ -509,14 +512,20 @@ describe('Design management index page', () => {
wrapper.vm.onUploadDesignDone(designUploadMutationCreatedResponse);
expect(trackingSpy).toHaveBeenCalledTimes(1);
- expect(trackingSpy).toHaveBeenCalledWith(DESIGN_TRACKING_PAGE_NAME, 'create_design');
+ expect(trackingSpy).toHaveBeenCalledWith(
+ DESIGN_TRACKING_PAGE_NAME,
+ DESIGN_SNOWPLOW_EVENT_TYPES.CREATE_DESIGN,
+ );
});
it('tracks design modification', () => {
wrapper.vm.onUploadDesignDone(designUploadMutationUpdatedResponse);
expect(trackingSpy).toHaveBeenCalledTimes(1);
- expect(trackingSpy).toHaveBeenCalledWith(DESIGN_TRACKING_PAGE_NAME, 'update_design');
+ expect(trackingSpy).toHaveBeenCalledWith(
+ DESIGN_TRACKING_PAGE_NAME,
+ DESIGN_SNOWPLOW_EVENT_TYPES.UPDATE_DESIGN,
+ );
});
});
});
diff --git a/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js b/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js
index 2544d0bd030..2c02e1e1de4 100644
--- a/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js
+++ b/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js
@@ -280,7 +280,7 @@ describe('RelatedIssuesRoot', () => {
const input = 'asdf/qwer#444 #12 ';
wrapper.vm.onInput({
untouchedRawReferences: input.trim().split(/\s/),
- touchedReference: 2,
+ touchedReference: '2',
});
expect(wrapper.vm.state.pendingReferences).toHaveLength(2);
@@ -292,13 +292,37 @@ describe('RelatedIssuesRoot', () => {
const input = 'something random ';
wrapper.vm.onInput({
untouchedRawReferences: input.trim().split(/\s/),
- touchedReference: 2,
+ touchedReference: '2',
});
expect(wrapper.vm.state.pendingReferences).toHaveLength(2);
expect(wrapper.vm.state.pendingReferences[0]).toEqual('something');
expect(wrapper.vm.state.pendingReferences[1]).toEqual('random');
});
+
+ it('prepends # when user enters a numeric value [0-9]', async () => {
+ const input = '23';
+
+ wrapper.vm.onInput({
+ untouchedRawReferences: input.trim().split(/\s/),
+ touchedReference: input,
+ });
+
+ expect(wrapper.vm.inputValue).toBe(`#${input}`);
+ });
+
+ it('prepends # when user enters a number', async () => {
+ const input = 23;
+
+ wrapper.vm.onInput({
+ untouchedRawReferences: String(input)
+ .trim()
+ .split(/\s/),
+ touchedReference: input,
+ });
+
+ expect(wrapper.vm.inputValue).toBe(`#${input}`);
+ });
});
describe('onBlur', () => {
diff --git a/spec/graphql/resolvers/project_pipeline_statistics_resolver_spec.rb b/spec/graphql/resolvers/project_pipeline_statistics_resolver_spec.rb
new file mode 100644
index 00000000000..c0367f7d42e
--- /dev/null
+++ b/spec/graphql/resolvers/project_pipeline_statistics_resolver_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Resolvers::ProjectPipelineStatisticsResolver do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project) }
+
+ specify do
+ expect(described_class).to have_nullable_graphql_type(::Types::Ci::AnalyticsType)
+ end
+
+ def resolve_statistics(project, args)
+ resolve(described_class, obj: project, args: args)
+ end
+
+ describe '#resolve' do
+ it 'returns the pipelines statistics for a given project' do
+ result = resolve_statistics(project, {})
+ expect(result.keys).to contain_exactly(
+ :week_pipelines_labels,
+ :week_pipelines_totals,
+ :week_pipelines_successful,
+ :month_pipelines_labels,
+ :month_pipelines_totals,
+ :month_pipelines_successful,
+ :year_pipelines_labels,
+ :year_pipelines_totals,
+ :year_pipelines_successful,
+ :pipeline_times_labels,
+ :pipeline_times_values
+ )
+ end
+ end
+end
diff --git a/spec/graphql/types/ci/analytics_type_spec.rb b/spec/graphql/types/ci/analytics_type_spec.rb
new file mode 100644
index 00000000000..c8462d40769
--- /dev/null
+++ b/spec/graphql/types/ci/analytics_type_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::Ci::AnalyticsType do
+ it 'exposes the expected fields' do
+ expected_fields = %i[
+ weekPipelinesTotals
+ weekPipelinesLabels
+ weekPipelinesSuccessful
+ monthPipelinesLabels
+ monthPipelinesTotals
+ monthPipelinesSuccessful
+ yearPipelinesLabels
+ yearPipelinesTotals
+ yearPipelinesSuccessful
+ pipelineTimesLabels
+ pipelineTimesValues
+ ]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/project_type_spec.rb b/spec/graphql/types/project_type_spec.rb
index 141f2406e7f..ff99dd77233 100644
--- a/spec/graphql/types/project_type_spec.rb
+++ b/spec/graphql/types/project_type_spec.rb
@@ -31,6 +31,7 @@ RSpec.describe GitlabSchema.types['Project'] do
container_expiration_policy service_desk_enabled service_desk_address
issue_status_counts terraform_states alert_management_integrations
container_repositories container_repositories_count
+ pipeline_analytics total_pipeline_duration
]
expect(described_class).to include_graphql_fields(*expected_fields)
@@ -186,4 +187,11 @@ RSpec.describe GitlabSchema.types['Project'] do
end
end
end
+
+ describe 'pipeline_analytics field' do
+ subject { described_class.fields['pipelineAnalytics'] }
+
+ it { is_expected.to have_graphql_type(Types::Ci::AnalyticsType) }
+ it { is_expected.to have_graphql_resolver(Resolvers::ProjectPipelineStatisticsResolver) }
+ end
end
diff --git a/spec/lib/gitlab/usage_data_counters/guest_package_event_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/guest_package_event_counter_spec.rb
new file mode 100644
index 00000000000..d018100b041
--- /dev/null
+++ b/spec/lib/gitlab/usage_data_counters/guest_package_event_counter_spec.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::UsageDataCounters::GuestPackageEventCounter, :clean_gitlab_redis_shared_state do
+ shared_examples_for 'usage counter with totals' do |counter|
+ it 'increments counter and returns total count' do
+ expect(described_class.read(counter)).to eq(0)
+
+ 2.times { described_class.count(counter) }
+
+ expect(described_class.read(counter)).to eq(2)
+ end
+ end
+
+ it 'includes the right events' do
+ expect(described_class::KNOWN_EVENTS.size).to eq 33
+ end
+
+ described_class::KNOWN_EVENTS.each do |event|
+ it_behaves_like 'usage counter with totals', event
+ end
+
+ describe '.fetch_supported_event' do
+ subject { described_class.fetch_supported_event(event_name) }
+
+ let(:event_name) { 'package_guest_i_package_composer_guest_push' }
+
+ it { is_expected.to eq 'i_package_composer_guest_push' }
+ end
+end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 3bcb21bc828..a00cc019f59 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -4981,6 +4981,7 @@ RSpec.describe Project, factory_default: :keep do
expect(project).to receive(:after_create_default_branch)
expect(project).to receive(:refresh_markdown_cache!)
expect(InternalId).to receive(:flush_records!).with(project: project)
+ expect(ProjectCacheWorker).to receive(:perform_async).with(project.id, [], [:repository_size])
expect(DetectRepositoryLanguagesWorker).to receive(:perform_async).with(project.id)
expect(project).to receive(:write_repository_config)
diff --git a/spec/requests/api/graphql/project/project_pipeline_statistics_spec.rb b/spec/requests/api/graphql/project/project_pipeline_statistics_spec.rb
new file mode 100644
index 00000000000..0f495f3e671
--- /dev/null
+++ b/spec/requests/api/graphql/project/project_pipeline_statistics_spec.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'rendering project pipeline statistics' do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project) }
+ let(:user) { create(:user) }
+
+ let(:fields) do
+ <<~QUERY
+ weekPipelinesTotals
+ weekPipelinesLabels
+ monthPipelinesLabels
+ monthPipelinesTotals
+ yearPipelinesLabels
+ yearPipelinesTotals
+ QUERY
+ end
+
+ let(:query) do
+ graphql_query_for('project',
+ { 'fullPath' => project.full_path },
+ query_graphql_field('pipelineAnalytics', {}, fields))
+ end
+
+ before do
+ project.add_maintainer(user)
+ end
+
+ it_behaves_like 'a working graphql query' do
+ before do
+ post_graphql(query, current_user: user)
+ end
+ end
+
+ it "contains two arrays of 8 elements each for the week pipelines" do
+ post_graphql(query, current_user: user)
+
+ expect(graphql_data_at(:project, :pipelineAnalytics, :weekPipelinesTotals).length).to eq(8)
+ expect(graphql_data_at(:project, :pipelineAnalytics, :weekPipelinesLabels).length).to eq(8)
+ end
+
+ it "contains two arrays of 31 elements each for the month pipelines" do
+ post_graphql(query, current_user: user)
+
+ expect(graphql_data_at(:project, :pipelineAnalytics, :monthPipelinesTotals).length).to eq(31)
+ expect(graphql_data_at(:project, :pipelineAnalytics, :monthPipelinesLabels).length).to eq(31)
+ end
+
+ it "contains two arrays of 13 elements each for the year pipelines" do
+ post_graphql(query, current_user: user)
+
+ expect(graphql_data_at(:project, :pipelineAnalytics, :yearPipelinesTotals).length).to eq(13)
+ expect(graphql_data_at(:project, :pipelineAnalytics, :yearPipelinesLabels).length).to eq(13)
+ end
+end
diff --git a/spec/requests/import/gitlab_groups_controller_spec.rb b/spec/requests/import/gitlab_groups_controller_spec.rb
index fe8875f25f8..51f1363cf1c 100644
--- a/spec/requests/import/gitlab_groups_controller_spec.rb
+++ b/spec/requests/import/gitlab_groups_controller_spec.rb
@@ -195,6 +195,7 @@ RSpec.describe Import::GitlabGroupsController do
describe 'POST authorize' do
it_behaves_like 'handle uploads authorize request' do
let(:uploader_class) { ImportExportUploader }
+ let(:maximum_size) { Gitlab::CurrentSettings.max_import_size.megabytes }
subject { post authorize_import_gitlab_group_path, headers: workhorse_headers }
end
diff --git a/spec/requests/import/gitlab_projects_controller_spec.rb b/spec/requests/import/gitlab_projects_controller_spec.rb
index 0e92410a2de..d7d4de21a33 100644
--- a/spec/requests/import/gitlab_projects_controller_spec.rb
+++ b/spec/requests/import/gitlab_projects_controller_spec.rb
@@ -86,6 +86,7 @@ RSpec.describe Import::GitlabProjectsController do
describe 'POST authorize' do
it_behaves_like 'handle uploads authorize request' do
let(:uploader_class) { ImportExportUploader }
+ let(:maximum_size) { Gitlab::CurrentSettings.max_import_size.megabytes }
subject { post authorize_import_gitlab_project_path, headers: workhorse_headers }
end
diff --git a/spec/services/issues/clone_service_spec.rb b/spec/services/issues/clone_service_spec.rb
index d28fc40d32e..12b8781031b 100644
--- a/spec/services/issues/clone_service_spec.rb
+++ b/spec/services/issues/clone_service_spec.rb
@@ -15,10 +15,12 @@ RSpec.describe Issues::CloneService do
let_it_be(:old_project) { create(:project, namespace: sub_group_1) }
let_it_be(:new_project) { create(:project, namespace: sub_group_2) }
- let(:old_issue) do
+ let_it_be(:old_issue, reload: true) do
create(:issue, title: title, description: description, project: old_project, author: author)
end
+ let(:with_notes) { false }
+
subject(:clone_service) do
described_class.new(old_project, user)
end
@@ -35,7 +37,7 @@ RSpec.describe Issues::CloneService do
include_context 'user can clone issue'
context 'generic issue' do
- let!(:new_issue) { clone_service.execute(old_issue, new_project) }
+ let!(:new_issue) { clone_service.execute(old_issue, new_project, with_notes: with_notes) }
it 'creates a new issue in the selected project' do
expect do
@@ -91,6 +93,16 @@ RSpec.describe Issues::CloneService do
it 'does not set moved_issue' do
expect(old_issue.moved?).to eq(false)
end
+
+ context 'when copying comments' do
+ let(:with_notes) { true }
+
+ it 'does not create extra system notes' do
+ new_issue = clone_service.execute(old_issue, new_project, with_notes: with_notes)
+
+ expect(new_issue.notes.count).to eq(old_issue.notes.count)
+ end
+ end
end
context 'issue with award emoji' do
@@ -200,6 +212,34 @@ RSpec.describe Issues::CloneService do
end
end
+ # These tests verify that notes are copied. More thorough tests are in
+ # the unit test for Notes::CopyService.
+ context 'issue with notes' do
+ let_it_be(:notes) do
+ [
+ create(:note, noteable: old_issue, project: old_project, created_at: 2.weeks.ago, updated_at: 1.week.ago),
+ create(:note, noteable: old_issue, project: old_project)
+ ]
+ end
+
+ let(:new_issue) { clone_service.execute(old_issue, new_project, with_notes: with_notes) }
+
+ let(:copied_notes) { new_issue.notes.limit(notes.size) } # Remove the system note added by the copy itself
+
+ it 'does not copy notes' do
+ # only the system note
+ expect(copied_notes.order('id ASC').pluck(:note).size).to eq(1)
+ end
+
+ context 'when copying comments' do
+ let(:with_notes) { true }
+
+ it 'copies existing notes in order' do
+ expect(copied_notes.order('id ASC').pluck(:note)).to eq(notes.map(&:note))
+ end
+ end
+ end
+
context 'issue with a design', :clean_gitlab_redis_shared_state do
let_it_be(:new_project) { create(:project) }
let!(:design) { create(:design, :with_lfs_file, issue: old_issue) }
diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb
index 5dd60226e3f..55d6d5cfe2d 100644
--- a/spec/services/issues/update_service_spec.rb
+++ b/spec/services/issues/update_service_spec.rb
@@ -979,15 +979,35 @@ RSpec.describe Issues::UpdateService, :mailer do
it 'calls the move service with the proper issue and project' do
clone_stub = instance_double(Issues::CloneService)
allow(Issues::CloneService).to receive(:new).and_return(clone_stub)
- allow(clone_stub).to receive(:execute).with(issue, target_project).and_return(issue)
+ allow(clone_stub).to receive(:execute).with(issue, target_project, with_notes: nil).and_return(issue)
- expect(clone_stub).to receive(:execute).with(issue, target_project)
+ expect(clone_stub).to receive(:execute).with(issue, target_project, with_notes: nil)
update_issue(target_clone_project: target_project)
end
end
end
+ context 'clone an issue with notes' do
+ context 'valid project' do
+ let(:target_project) { create(:project) }
+
+ before do
+ target_project.add_maintainer(user)
+ end
+
+ it 'calls the move service with the proper issue and project' do
+ clone_stub = instance_double(Issues::CloneService)
+ allow(Issues::CloneService).to receive(:new).and_return(clone_stub)
+ allow(clone_stub).to receive(:execute).with(issue, target_project, with_notes: true).and_return(issue)
+
+ expect(clone_stub).to receive(:execute).with(issue, target_project, with_notes: true)
+
+ update_issue(target_clone_project: target_project, clone_with_notes: true)
+ end
+ end
+ end
+
context 'when moving an issue ' do
it 'raises an error for invalid move ids within a project' do
opts = { move_between_ids: [9000, non_existing_record_id] }
diff --git a/spec/support/shared_examples/quick_actions/issue/clone_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issue/clone_quick_action_shared_examples.rb
index 35d65302a61..a99304f7214 100644
--- a/spec/support/shared_examples/quick_actions/issue/clone_quick_action_shared_examples.rb
+++ b/spec/support/shared_examples/quick_actions/issue/clone_quick_action_shared_examples.rb
@@ -32,6 +32,34 @@ RSpec.shared_examples 'clone quick action' do
expect(page).to have_content 'Issues 1'
end
+
+ context 'when cloning with notes', :aggregate_failures do
+ it 'clones the issue with all notes' do
+ add_note("Some random note")
+ add_note("Another note")
+
+ add_note("/clone --with_notes #{target_project.full_path}")
+
+ expect(page).to have_content "Cloned this issue to #{target_project.full_path}."
+ expect(issue.reload).to be_open
+
+ visit project_issue_path(target_project, issue)
+
+ expect(page).to have_content 'Issues 1'
+ expect(page).to have_content 'Some random note'
+ expect(page).to have_content 'Another note'
+ end
+
+ it 'returns an error if the params are malformed' do
+ # Note that this is missing one `-`
+ add_note("/clone -with_notes #{target_project.full_path}")
+
+ wait_for_requests
+
+ expect(page).to have_content 'Failed to clone this issue: wrong parameters.'
+ expect(issue.reload).to be_open
+ end
+ end
end
context 'when the project is valid but the user not authorized' do
diff --git a/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb
index c56290a0aa9..49b6fc13900 100644
--- a/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb
@@ -629,6 +629,7 @@ RSpec.shared_examples 'workhorse recipe file upload endpoint' do
it_behaves_like 'rejects invalid recipe'
it_behaves_like 'rejects invalid file_name', 'conanfile.py.git%2fgit-upload-pack'
it_behaves_like 'uploads a package file'
+ it_behaves_like 'creates build_info when there is a job'
end
RSpec.shared_examples 'workhorse package file upload endpoint' do
@@ -649,6 +650,7 @@ RSpec.shared_examples 'workhorse package file upload endpoint' do
it_behaves_like 'rejects invalid recipe'
it_behaves_like 'rejects invalid file_name', 'conaninfo.txttest'
it_behaves_like 'uploads a package file'
+ it_behaves_like 'creates build_info when there is a job'
context 'tracking the conan_package.tgz upload' do
let(:file_name) { ::Packages::Conan::FileMetadatum::PACKAGE_BINARY }
@@ -657,6 +659,20 @@ RSpec.shared_examples 'workhorse package file upload endpoint' do
end
end
+RSpec.shared_examples 'creates build_info when there is a job' do
+ context 'with job token' do
+ let(:jwt) { build_jwt_from_job(job) }
+
+ it 'creates a build_info record' do
+ expect { subject }.to change { Packages::BuildInfo.count }.by(1)
+ end
+
+ it 'creates a package_file_build_info record' do
+ expect { subject }.to change { Packages::PackageFileBuildInfo.count }.by(1)
+ end
+ end
+end
+
RSpec.shared_examples 'uploads a package file' do
context 'file size above maximum limit' do
before do
diff --git a/spec/support/shared_examples/requests/uploads_auhorize_shared_examples.rb b/spec/support/shared_examples/requests/uploads_auhorize_shared_examples.rb
index 3d018fd4028..9cef5cfc25e 100644
--- a/spec/support/shared_examples/requests/uploads_auhorize_shared_examples.rb
+++ b/spec/support/shared_examples/requests/uploads_auhorize_shared_examples.rb
@@ -37,6 +37,7 @@ RSpec.shared_examples 'handle uploads authorize request' do
expect(json_response['RemoteObject']).to have_key('StoreURL')
expect(json_response['RemoteObject']).to have_key('DeleteURL')
expect(json_response['RemoteObject']).to have_key('MultipartUpload')
+ expect(json_response['MaximumSize']).to eq(maximum_size)
end
end
@@ -52,6 +53,7 @@ RSpec.shared_examples 'handle uploads authorize request' do
expect(response.media_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
expect(json_response['TempPath']).to eq(uploader_class.workhorse_local_upload_path)
expect(json_response['RemoteObject']).to be_nil
+ expect(json_response['MaximumSize']).to eq(maximum_size)
end
end
end
diff --git a/spec/tasks/gitlab/packages/events_rake_spec.rb b/spec/tasks/gitlab/packages/events_rake_spec.rb
index ac28f9b5fc2..2c3885855be 100644
--- a/spec/tasks/gitlab/packages/events_rake_spec.rb
+++ b/spec/tasks/gitlab/packages/events_rake_spec.rb
@@ -7,24 +7,26 @@ RSpec.describe 'gitlab:packages:events namespace rake task' do
Rake.application.rake_require 'tasks/gitlab/packages/events'
end
- describe 'generate' do
- subject do
- file = double('file')
- yml_file = nil
+ subject do
+ file = double('file')
+ yml_file = nil
- allow(file).to receive(:<<) { |contents| yml_file = contents }
- allow(File).to receive(:open).and_yield(file)
+ allow(file).to receive(:<<) { |contents| yml_file = contents }
+ allow(File).to receive(:open).and_yield(file)
- run_rake_task('gitlab:packages:events:generate')
+ run_rake_task("gitlab:packages:events:#{task}")
- YAML.safe_load(yml_file)
- end
+ YAML.safe_load(yml_file)
+ end
+
+ describe 'generate_unique' do
+ let(:task) { 'generate_unique' }
it 'excludes guest events' do
expect(subject.find { |event| event['name'].include?("guest") }).to be_nil
end
- ::Packages::Event::EVENT_SCOPES.keys.each do |event_scope|
+ Packages::Event::EVENT_SCOPES.keys.each do |event_scope|
it "includes includes `#{event_scope}` scope" do
expect(subject.find { |event| event['name'].include?(event_scope) }).not_to be_nil
end
@@ -35,4 +37,19 @@ RSpec.describe 'gitlab:packages:events namespace rake task' do
expect(subject.find { |event| event['name'].include?("list_package") }).to be_nil
end
end
+
+ describe 'generate_guest' do
+ let(:task) { 'generate_guest' }
+
+ Packages::Event::EVENT_SCOPES.keys.each do |event_scope|
+ it "includes includes `#{event_scope}` scope" do
+ expect(subject.find { |event| event.include?(event_scope) }).not_to be_nil
+ end
+ end
+
+ it 'excludes some event types' do
+ expect(subject.find { |event| event.include?("search_package") }).to be_nil
+ expect(subject.find { |event| event.include?("list_package") }).to be_nil
+ end
+ end
end