Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-05-18 18:08:05 +00:00
parent a84995f457
commit 6b5d8b17e2
132 changed files with 1829 additions and 953 deletions

View File

@ -1 +1 @@
93762b621c011fe570339c1c247d5197c2cfefcc
2106629e3af3e8949b23f20825d6bfee62c10992

View File

@ -1 +1 @@
14.3.0
14.3.1

View File

@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://gitlab.com/.gitlab-ci.yml",
"title": "Gitlab CI configuration",
"description": "Gitlab has a built-in solution for doing CI called Gitlab CI. It is configured by supplying a file called `.gitlab-ci.yml`, which will list all the jobs that are going to run for the project. A full list of all options can be found at https://docs.gitlab.com/ee/ci/yaml/. You can read more about Gitlab CI at https://docs.gitlab.com/ee/ci/README.html.",
"markdownDescription": "Gitlab has a built-in solution for doing CI called Gitlab CI. It is configured by supplying a file called `.gitlab-ci.yml`, which will list all the jobs that are going to run for the project. A full list of all options can be found [here](https://docs.gitlab.com/ee/ci/yaml). [Learn More](https://docs.gitlab.com/ee/ci/index.html).",
"type": "object",
"properties": {
"$schema": {
@ -33,7 +33,7 @@
},
"stages": {
"type": "array",
"description": "Groups jobs into stages. All jobs in one stage must complete before next stage is executed. Defaults to ['build', 'test', 'deploy'].",
"markdownDescription": "Groups jobs into stages. All jobs in one stage must complete before next stage is executed. Defaults to ['build', 'test', 'deploy']. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#stages).",
"default": ["build", "test", "deploy"],
"items": {
"type": "string"
@ -42,7 +42,7 @@
"minItems": 1
},
"include": {
"description": "Can be `IncludeItem` or `IncludeItem[]`. Each `IncludeItem` will be a string, or an object with properties for the method if including external YAML file. The external content will be fetched, included and evaluated along the `.gitlab-ci.yml`.",
"markdownDescription": "Can be `IncludeItem` or `IncludeItem[]`. Each `IncludeItem` will be a string, or an object with properties for the method if including external YAML file. The external content will be fetched, included and evaluated along the `.gitlab-ci.yml`. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#include).",
"oneOf": [
{ "$ref": "#/definitions/include_item" },
{
@ -53,7 +53,7 @@
},
"pages": {
"$ref": "#/definitions/job",
"description": "A special job used to upload static sites to Gitlab pages. Requires a `public/` directory with `artifacts.path` pointing to it."
"markdownDescription": "A special job used to upload static sites to Gitlab pages. Requires a `public/` directory with `artifacts.path` pointing to it. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#pages)."
},
"workflow": {
"type": "object",
@ -93,12 +93,12 @@
"definitions": {
"artifacts": {
"type": "object",
"description": "Used to specify a list of files and directories that should be attached to the job if it succeeds. Artifacts are sent to Gitlab where they can be downloaded.",
"markdownDescription": "Used to specify a list of files and directories that should be attached to the job if it succeeds. Artifacts are sent to Gitlab where they can be downloaded. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#artifacts).",
"additionalProperties": false,
"properties": {
"paths": {
"type": "array",
"description": "A list of paths to files/folders that should be included in the artifact.",
"markdownDescription": "A list of paths to files/folders that should be included in the artifact. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#artifactspaths).",
"items": {
"type": "string"
},
@ -106,7 +106,7 @@
},
"exclude": {
"type": "array",
"description": "A list of paths to files/folders that should be excluded in the artifact.",
"markdownDescription": "A list of paths to files/folders that should be excluded in the artifact. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#artifactsexclude).",
"items": {
"type": "string"
},
@ -114,19 +114,19 @@
},
"expose_as": {
"type": "string",
"description": "Can be used to expose job artifacts in the merge request UI. GitLab will add a link <expose_as> to the relevant merge request that points to the artifact."
"markdownDescription": "Can be used to expose job artifacts in the merge request UI. GitLab will add a link <expose_as> to the relevant merge request that points to the artifact. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#artifactsexpose_as)."
},
"name": {
"type": "string",
"description": "Name for the archive created on job success. Can use variables in the name, e.g. '$CI_JOB_NAME'"
"markdownDescription": "Name for the archive created on job success. Can use variables in the name, e.g. '$CI_JOB_NAME' [Learn More](https://docs.gitlab.com/ee/ci/yaml/#artifactsname)."
},
"untracked": {
"type": "boolean",
"description": "Whether to add all untracked files (along with 'artifacts.paths') to the artifact.",
"markdownDescription": "Whether to add all untracked files (along with 'artifacts.paths') to the artifact. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#artifactsuntracked).",
"default": false
},
"when": {
"description": "Configure when artifacts are uploaded depended on job status.",
"markdownDescription": "Configure when artifacts are uploaded depended on job status. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#artifactswhen).",
"default": "on_success",
"oneOf": [
{
@ -145,12 +145,12 @@
},
"expire_in": {
"type": "string",
"description": "How long artifacts should be kept. They are saved 30 days by default. Artifacts that have expired are removed periodically via cron job. Supports a wide variety of formats, e.g. '1 week', '3 mins 4 sec', '2 hrs 20 min', '2h20min', '6 mos 1 day', '47 yrs 6 mos and 4d', '3 weeks and 2 days'.",
"markdownDescription": "How long artifacts should be kept. They are saved 30 days by default. Artifacts that have expired are removed periodically via cron job. Supports a wide variety of formats, e.g. '1 week', '3 mins 4 sec', '2 hrs 20 min', '2h20min', '6 mos 1 day', '47 yrs 6 mos and 4d', '3 weeks and 2 days'. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#artifactsexpire_in).",
"default": "30 days"
},
"reports": {
"type": "object",
"description": "Reports will be uploaded as artifacts, and often displayed in the Gitlab UI, such as in Merge Requests.",
"markdownDescription": "Reports will be uploaded as artifacts, and often displayed in the Gitlab UI, such as in Merge Requests. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#artifactsreports).",
"additionalProperties": false,
"properties": {
"junit": {
@ -367,11 +367,11 @@
"required": ["name"]
}
],
"description": "Specifies the docker image to use for the job or globally for all jobs. Job configuration takes precedence over global setting. Requires a certain kind of Gitlab runner executor."
"markdownDescription": "Specifies the docker image to use for the job or globally for all jobs. Job configuration takes precedence over global setting. Requires a certain kind of Gitlab runner executor. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#image)."
},
"services": {
"type": "array",
"description": "Similar to `image` property, but will link the specified services to the `image` container.",
"markdownDescription": "Similar to `image` property, but will link the specified services to the `image` container. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#services).",
"items": {
"oneOf": [
{
@ -418,7 +418,7 @@
},
"secrets": {
"type": "object",
"description": "Defines secrets to be injected as environment variables",
"markdownDescription": "Defines secrets to be injected as environment variables. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#secrets).",
"additionalProperties": {
"type": "object",
"description": "Environment variable name",
@ -453,7 +453,7 @@
},
"before_script": {
"type": "array",
"description": "Defines scripts that should run *before* the job. Can be set globally or per job.",
"markdownDescription": "Defines scripts that should run *before* the job. Can be set globally or per job. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#before_script).",
"items": {
"anyOf": [
{
@ -470,7 +470,7 @@
},
"after_script": {
"type": "array",
"description": "Defines scripts that should run *after* the job. Can be set globally or per job.",
"markdownDescription": "Defines scripts that should run *after* the job. Can be set globally or per job. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#after_script).",
"items": {
"anyOf": [
{
@ -487,7 +487,7 @@
},
"rules": {
"type": "array",
"description": "Rules allows for an array of individual rule objects to be evaluated in order, until one matches and dynamically provides attributes to the job.",
"markdownDescription": "Rules allows for an array of individual rule objects to be evaluated in order, until one matches and dynamically provides attributes to the job. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#rules).",
"items": {
"type": "object",
"additionalProperties": false,
@ -503,7 +503,7 @@
}
},
"globalVariables": {
"description": "Defines environment variables globally. Job level property overrides global variables. If a job sets `variables: {}`, all global variables are turned off. You can use the value and description keywords to define variables that are prefilled when running a pipeline manually.",
"markdownDescription": "Defines environment variables globally. Job level property overrides global variables. If a job sets `variables: {}`, all global variables are turned off. You can use the value and description keywords to define variables that are prefilled when running a pipeline manually. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#variables).",
"type": "object",
"additionalProperties": {
"anyOf": [
@ -523,41 +523,41 @@
},
"if": {
"type": "string",
"description": "Expression to evaluate whether additional attributes should be provided to the job"
"markdownDescription": "Expression to evaluate whether additional attributes should be provided to the job. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#rulesif)."
},
"changes": {
"type": "array",
"description": "Additional attributes will be provided to job if any of the provided paths matches a modified file",
"markdownDescription": "Additional attributes will be provided to job if any of the provided paths matches a modified file. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#ruleschanges).",
"items": {
"type": "string"
}
},
"exists": {
"type": "array",
"description": "Additional attributes will be provided to job if any of the provided paths matches an existing file in the repository",
"markdownDescription": "Additional attributes will be provided to job if any of the provided paths matches an existing file in the repository. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#rulesexists).",
"items": {
"type": "string"
}
},
"variables": {
"type": "object",
"description": "Defines environment variables for specific jobs. Job level property overrides global variables. If a job sets `variables: {}`, all global variables are turned off.",
"markdownDescription": "Defines environment variables for specific jobs. Job level property overrides global variables. If a job sets `variables: {}`, all global variables are turned off. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#rulesvariables).",
"additionalProperties": {
"type": ["string", "integer"]
}
},
"timeout": {
"type": "string",
"description": "Allows you to configure a timeout for a specific job (e.g. `1 minute`, `1h 30m 12s`). Read more: https://docs.gitlab.com/ee/ci/yaml/README.html#timeout",
"markdownDescription": "Allows you to configure a timeout for a specific job (e.g. `1 minute`, `1h 30m 12s`). [Learn More](https://docs.gitlab.com/ee/ci/yaml/index.html#timeout).",
"minLength": 1
},
"start_in": {
"type": "string",
"description": "Used in conjunction with 'when: delayed' to set how long to delay before starting a job. e.g. '5', 5 seconds, 30 minutes, 1 week, etc. Read more: https://docs.gitlab.com/ee/ci/jobs/job_control.html#run-a-job-after-a-delay",
"markdownDescription": "Used in conjunction with 'when: delayed' to set how long to delay before starting a job. e.g. '5', 5 seconds, 30 minutes, 1 week, etc. [Learn More](https://docs.gitlab.com/ee/ci/jobs/job_control.html#run-a-job-after-a-delay).",
"minLength": 1
},
"allow_failure": {
"description": "Allow job to fail. A failed job does not cause the pipeline to fail.",
"markdownDescription": "Allow job to fail. A failed job does not cause the pipeline to fail. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#allow_failure).",
"oneOf": [
{
"description": "Setting this option to true will allow the job to fail while still letting the pipeline pass.",
@ -594,7 +594,7 @@
]
},
"when": {
"description": "Describes the conditions for when to run the job. Defaults to 'on_success'.",
"markdownDescription": "Describes the conditions for when to run the job. Defaults to 'on_success'.",
"default": "on_success",
"oneOf": [
{
@ -611,11 +611,11 @@
},
{
"enum": ["manual"],
"description": "Execute the job manually from Gitlab UI or API. Read more: https://docs.gitlab.com/ee/ci/yaml/#when-manual"
"markdownDescription": "Execute the job manually from Gitlab UI or API. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#when)."
},
{
"enum": ["delayed"],
"description": "Execute a job after the time limit in 'start_in' expires. Read more: https://docs.gitlab.com/ee/ci/yaml/#when-delayed"
"markdownDescription": "Execute a job after the time limit in 'start_in' expires. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#when)."
},
{
"enum": ["never"],
@ -626,7 +626,7 @@
"cache": {
"properties": {
"when": {
"description": "Defines when to save the cache, based on the status of the job.",
"markdownDescription": "Defines when to save the cache, based on the status of the job. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#cachewhen).",
"default": "on_success",
"oneOf": [
{
@ -778,7 +778,7 @@
},
"variables": {
"type": "array",
"description": "Filter job by checking comparing values of environment variables. Read more about variable expressions: https://docs.gitlab.com/ee/ci/variables/README.html#variables-expressions",
"markdownDescription": "Filter job by checking comparing values of CI/CD variables. [Learn More](https://docs.gitlab.com/ee/ci/jobs/job_control.html#cicd-variable-expressions).",
"items": {
"type": "string"
}
@ -795,7 +795,7 @@
]
},
"retry": {
"description": "Retry a job if it fails. Can be a simple integer or object definition.",
"markdownDescription": "Retry a job if it fails. Can be a simple integer or object definition. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#retry).",
"oneOf": [
{ "$ref": "#/definitions/retry_max" },
{
@ -804,7 +804,7 @@
"properties": {
"max": { "$ref": "#/definitions/retry_max" },
"when": {
"description": "Either a single or array of error types to trigger job retry.",
"markdownDescription": "Either a single or array of error types to trigger job retry. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#retrywhen).",
"oneOf": [
{ "$ref": "#/definitions/retry_errors" },
{
@ -884,7 +884,7 @@
},
"interruptible": {
"type": "boolean",
"description": "Interruptible is used to indicate that a job should be canceled if made redundant by a newer pipeline run.",
"markdownDescription": "Interruptible is used to indicate that a job should be canceled if made redundant by a newer pipeline run. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#interruptible).",
"default": false
},
"job": {
@ -1241,11 +1241,11 @@
"description": "Limit job concurrency. Can be used to ensure that the Runner will not run certain jobs simultaneously."
},
"trigger": {
"description": "Trigger allows you to define downstream pipeline trigger. When a job created from trigger definition is started by GitLab, a downstream pipeline gets created. Read more: https://docs.gitlab.com/ee/ci/yaml/README.html#trigger",
"markdownDescription": "Trigger allows you to define downstream pipeline trigger. When a job created from trigger definition is started by GitLab, a downstream pipeline gets created. [Learn More](https://docs.gitlab.com/ee/ci/yaml/index.html#trigger).",
"oneOf": [
{
"type": "object",
"description": "Trigger a multi-project pipeline. Read more: https://docs.gitlab.com/ee/ci/pipelines/multi_project_pipelines.html#specify-a-downstream-pipeline-branch",
"markdownDescription": "Trigger a multi-project pipeline. [Learn More](https://docs.gitlab.com/ee/ci/pipelines/multi_project_pipelines.html#specify-a-downstream-pipeline-branch).",
"additionalProperties": false,
"properties": {
"project": {
@ -1287,7 +1287,7 @@
},
{
"type": "object",
"description": "Trigger a child pipeline. Read more: https://docs.gitlab.com/ee/ci/pipelines/parent_child_pipelines.html",
"description": "Trigger a child pipeline. [Learn More](https://docs.gitlab.com/ee/ci/pipelines/parent_child_pipelines.html).",
"additionalProperties": false,
"properties": {
"include": {
@ -1398,7 +1398,7 @@
}
},
{
"description": "Path to the project, e.g. `group/project`, or `group/sub-group/project`. Read more: https://docs.gitlab.com/ee/ci/pipelines/multi_project_pipelines.html#define-multi-project-pipelines-in-your-gitlab-ciyml-file",
"markdownDescription": "Path to the project, e.g. `group/project`, or `group/sub-group/project`. [Learn More](https://docs.gitlab.com/ee/ci/pipelines/multi_project_pipelines.html#define-multi-project-pipelines-in-your-gitlab-ciyml-file).",
"type": "string",
"pattern": "\\S/\\S"
}
@ -1406,10 +1406,10 @@
},
"inherit": {
"type": "object",
"description": "Controls inheritance of globally-defined defaults and variables. Boolean values control inheritance of all default: or variables: keywords. To inherit only a subset of default: or variables: keywords, specify what you wish to inherit. Anything not listed is not inherited.",
"markdownDescription": "Controls inheritance of globally-defined defaults and variables. Boolean values control inheritance of all default: or variables: keywords. To inherit only a subset of default: or variables: keywords, specify what you wish to inherit. Anything not listed is not inherited. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#inherit).",
"properties": {
"default": {
"description": "Whether to inherit all globally-defined defaults or not. Or subset of inherited defaults",
"markdownDescription": "Whether to inherit all globally-defined defaults or not. Or subset of inherited defaults. [Learn more](https://docs.gitlab.com/ee/ci/yaml/#inheritdefault).",
"oneOf": [
{
"type": "boolean"
@ -1435,7 +1435,7 @@
]
},
"variables": {
"description": "Whether to inherit all globally-defined variables or not. Or subset of inherited variables",
"markdownDescription": "Whether to inherit all globally-defined variables or not. Or subset of inherited variables. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#inheritvariables).",
"oneOf": [
{ "type": "boolean" },
{
@ -1470,7 +1470,7 @@
},
"tags": {
"type": "array",
"description": "Used to select runners from the list of available runners. A runner must have all tags listed here to run the job.",
"markdownDescription": "Used to select runners from the list of available runners. A runner must have all tags listed here to run the job. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#tags).",
"items": {
"type": "string"
}

View File

@ -46,6 +46,9 @@ function getFallbackKey() {
export default class IssuableForm {
constructor(form) {
if (form.length === 0) {
return;
}
this.form = form;
this.toggleWip = this.toggleWip.bind(this);
this.renderWipExplanation = this.renderWipExplanation.bind(this);

View File

@ -23,6 +23,7 @@ import CsvImportExportButtons from '~/issuable/components/csv_import_export_butt
import IssuableByEmail from '~/issuable/components/issuable_by_email.vue';
import { IssuableStatus } from '~/issues/constants';
import axios from '~/lib/utils/axios_utils';
import { isPositiveInteger } from '~/lib/utils/number_utils';
import { scrollUp } from '~/lib/utils/scroll_utils';
import { getParameterByName, joinPaths } from '~/lib/utils/url_utility';
import {
@ -45,6 +46,8 @@ import {
ISSUE_REFERENCE,
MAX_LIST_SIZE,
PAGE_SIZE,
PARAM_FIRST_PAGE_SIZE,
PARAM_LAST_PAGE_SIZE,
PARAM_PAGE_AFTER,
PARAM_PAGE_BEFORE,
PARAM_SORT,
@ -390,12 +393,14 @@ export default {
},
urlParams() {
return {
page_after: this.pageParams.afterCursor,
page_before: this.pageParams.beforeCursor,
search: this.searchQuery,
sort: urlSortParams[this.sortKey],
state: this.state,
...this.urlFilterParams,
first_page_size: this.pageParams.firstPageSize,
last_page_size: this.pageParams.lastPageSize,
page_after: this.pageParams.afterCursor,
page_before: this.pageParams.beforeCursor,
};
},
hasCrmParameter() {
@ -632,6 +637,8 @@ export default {
this.showBulkEditSidebar = showBulkEditSidebar;
},
updateData(sortValue) {
const firstPageSize = getParameterByName(PARAM_FIRST_PAGE_SIZE);
const lastPageSize = getParameterByName(PARAM_LAST_PAGE_SIZE);
const pageAfter = getParameterByName(PARAM_PAGE_AFTER);
const pageBefore = getParameterByName(PARAM_PAGE_BEFORE);
const state = getParameterByName(PARAM_STATE);
@ -660,7 +667,13 @@ export default {
this.exportCsvPathWithQuery = this.getExportCsvPathWithQuery();
this.filterTokens = isSearchDisabled ? [] : getFilterTokens(window.location.search);
this.pageParams = getInitialPageParams(sortKey, pageAfter, pageBefore);
this.pageParams = getInitialPageParams(
sortKey,
isPositiveInteger(firstPageSize) ? parseInt(firstPageSize, 10) : undefined,
isPositiveInteger(lastPageSize) ? parseInt(lastPageSize, 10) : undefined,
pageAfter,
pageBefore,
);
this.sortKey = sortKey;
this.state = state || IssuableStates.Opened;
},

View File

@ -57,6 +57,8 @@ export const MAX_LIST_SIZE = 10;
export const PAGE_SIZE = 20;
export const PAGE_SIZE_MANUAL = 100;
export const PARAM_ASSIGNEE_ID = 'assignee_id';
export const PARAM_FIRST_PAGE_SIZE = 'first_page_size';
export const PARAM_LAST_PAGE_SIZE = 'last_page_size';
export const PARAM_PAGE_AFTER = 'page_after';
export const PARAM_PAGE_BEFORE = 'page_before';
export const PARAM_SORT = 'sort';

View File

@ -46,8 +46,15 @@ import {
WEIGHT_DESC,
} from './constants';
export const getInitialPageParams = (sortKey, afterCursor, beforeCursor) => ({
firstPageSize: sortKey === RELATIVE_POSITION_ASC ? PAGE_SIZE_MANUAL : PAGE_SIZE,
export const getInitialPageParams = (
sortKey,
firstPageSize = sortKey === RELATIVE_POSITION_ASC ? PAGE_SIZE_MANUAL : PAGE_SIZE,
lastPageSize,
afterCursor,
beforeCursor,
) => ({
firstPageSize: lastPageSize ? undefined : firstPageSize,
lastPageSize,
afterCursor,
beforeCursor,
});

View File

@ -25,6 +25,7 @@ import {
NOT_AVAILABLE_TEXT,
NOT_AVAILABLE_SIZE,
MORE_ACTIONS_TEXT,
COPY_IMAGE_PATH_TITLE,
} from '../../constants/index';
export default {
@ -72,6 +73,7 @@ export default {
CONFIGURATION_DETAILS_ROW_TEST,
MISSING_MANIFEST_WARNING_TOOLTIP,
MORE_ACTIONS_TEXT,
COPY_IMAGE_PATH_TITLE,
},
computed: {
formattedSize() {
@ -138,7 +140,7 @@ export default {
<clipboard-button
v-if="tag.location"
:title="tag.location"
:title="$options.i18n.COPY_IMAGE_PATH_TITLE"
:text="tag.location"
category="tertiary"
:disabled="disabled"

View File

@ -14,6 +14,7 @@ import {
IMAGE_FAILED_DELETED_STATUS,
IMAGE_MIGRATING_STATE,
ROOT_IMAGE_TEXT,
COPY_IMAGE_PATH_TITLE,
} from '../../constants/index';
import DeleteButton from '../delete_button.vue';
import CleanupStatus from './cleanup_status.vue';
@ -52,6 +53,7 @@ export default {
i18n: {
REMOVE_REPOSITORY_LABEL,
ROW_SCHEDULED_FOR_DELETION,
COPY_IMAGE_PATH_TITLE,
},
computed: {
disabledDelete() {
@ -115,7 +117,7 @@ export default {
v-if="item.location"
:disabled="deleting"
:text="item.location"
:title="item.location"
:title="$options.i18n.COPY_IMAGE_PATH_TITLE"
category="tertiary"
/>
</template>

View File

@ -41,6 +41,8 @@ export const EMPTY_RESULT_MESSAGE = s__(
'ContainerRegistry|To widen your search, change or remove the filters above.',
);
export const COPY_IMAGE_PATH_TITLE = s__('ContainerRegistry|Copy image path');
// Parameters
export const IMAGE_DELETE_SCHEDULED_STATUS = 'DELETE_SCHEDULED';

View File

@ -1,7 +1,6 @@
<script>
import { GlButton } from '@gitlab/ui';
import getAppStatus from '~/pipeline_editor/graphql/queries/client/app_status.query.graphql';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { EDITOR_APP_STATUS_EMPTY, EDITOR_APP_STATUS_LOADING } from '../../constants';
import FileTreePopover from '../popovers/file_tree_popover.vue';
import BranchSwitcher from './branch_switcher.vue';
@ -12,7 +11,6 @@ export default {
FileTreePopover,
GlButton,
},
mixins: [glFeatureFlagMixin()],
props: {
hasUnsavedChanges: {
type: Boolean,
@ -43,11 +41,7 @@ export default {
return this.appStatus === EDITOR_APP_STATUS_LOADING;
},
showFileTreeToggle() {
return (
this.glFeatures.pipelineEditorFileTree &&
!this.isNewCiConfigFile &&
this.appStatus !== EDITOR_APP_STATUS_EMPTY
);
return !this.isNewCiConfigFile && this.appStatus !== EDITOR_APP_STATUS_EMPTY;
},
},
methods: {

View File

@ -1,7 +1,6 @@
<script>
import { GlModal } from '@gitlab/ui';
import { __ } from '~/locale';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import CommitSection from './components/commit/commit_section.vue';
import PipelineEditorDrawer from './components/drawer/pipeline_editor_drawer.vue';
import PipelineEditorFileNav from './components/file_nav/pipeline_editor_file_nav.vue';
@ -34,7 +33,6 @@ export default {
PipelineEditorHeader,
PipelineEditorTabs,
},
mixins: [glFeatureFlagMixin()],
props: {
ciConfigData: {
type: Object,
@ -76,9 +74,6 @@ export default {
includesFiles() {
return this.ciConfigData?.includes || [];
},
isFileTreeVisible() {
return this.showFileTree && this.glFeatures.pipelineEditorFileTree;
},
},
mounted() {
this.showFileTree = JSON.parse(localStorage.getItem(FILE_TREE_DISPLAY_KEY)) || false;
@ -140,7 +135,7 @@ export default {
/>
<div class="gl-display-flex gl-w-full gl-sm-flex-direction-column">
<pipeline-editor-file-tree
v-if="isFileTreeVisible"
v-if="showFileTree"
class="gl-flex-shrink-0"
:includes="includesFiles"
/>

View File

@ -98,10 +98,10 @@ export default {
<template>
<div data-qa-selector="approvals_summary_content">
<strong>{{ approvalLeftMessage }}</strong>
<span class="gl-font-weight-bold">{{ approvalLeftMessage }}</span>
<template v-if="hasApprovers">
<span v-if="approvalLeftMessage">{{ message }}</span>
<strong v-else>{{ message }}</strong>
<span v-else class="gl-font-weight-bold">{{ message }}</span>
<user-avatar-list
class="gl-display-inline-block gl-vertical-align-middle"
:img-size="24"

View File

@ -234,6 +234,8 @@
.navbar-sub-nav {
display: flex;
align-items: center;
height: 100%;
margin: 0 0 0 6px;
.dropdown-chevron {

View File

@ -439,7 +439,7 @@ $browser-scrollbar-size: 10px;
/*
* Misc
*/
$header-height: var(--header-height, 40px);
$header-height: var(--header-height, 48px);
$header-zindex: 1000;
$zindex-dropdown-menu: 300;
$suggestion-header-height: 46px;

View File

@ -755,7 +755,7 @@ input {
padding: 0 16px;
z-index: 1000;
margin-bottom: 0;
min-height: var(--header-height, 40px);
min-height: var(--header-height, 48px);
border: 0;
position: fixed;
top: 0;
@ -771,7 +771,7 @@ input {
display: flex;
justify-content: space-between;
position: relative;
min-height: var(--header-height, 40px);
min-height: var(--header-height, 48px);
padding-left: 0;
}
.navbar-gitlab .header-content .title {
@ -787,9 +787,6 @@ input {
.navbar-gitlab .header-content .title img {
height: 24px;
}
.navbar-gitlab .header-content .title img + .logo-text {
margin-left: 8px;
}
.navbar-gitlab .header-content .title a {
display: flex;
align-items: center;
@ -915,6 +912,8 @@ input {
}
.navbar-sub-nav {
display: flex;
align-items: center;
height: 100%;
margin: 0 0 0 6px;
}
.caret-down,
@ -1034,7 +1033,7 @@ input {
left: 0;
z-index: 600;
width: 220px;
top: var(--header-height, 40px);
top: var(--header-height, 48px);
background-color: #303030;
transform: translate3d(0, 0, 0);
}
@ -2044,19 +2043,9 @@ body.gl-dark {
.gl-display-none {
display: none;
}
@media (min-width: 992px) {
.gl-lg-display-none\! {
display: none !important;
}
}
.gl-display-flex {
display: flex;
}
@media (min-width: 992px) {
.gl-lg-display-flex {
display: flex;
}
}
@media (min-width: 576px) {
.gl-sm-display-block {
display: block;

View File

@ -740,7 +740,7 @@ input {
padding: 0 16px;
z-index: 1000;
margin-bottom: 0;
min-height: var(--header-height, 40px);
min-height: var(--header-height, 48px);
border: 0;
position: fixed;
top: 0;
@ -756,7 +756,7 @@ input {
display: flex;
justify-content: space-between;
position: relative;
min-height: var(--header-height, 40px);
min-height: var(--header-height, 48px);
padding-left: 0;
}
.navbar-gitlab .header-content .title {
@ -772,9 +772,6 @@ input {
.navbar-gitlab .header-content .title img {
height: 24px;
}
.navbar-gitlab .header-content .title img + .logo-text {
margin-left: 8px;
}
.navbar-gitlab .header-content .title a {
display: flex;
align-items: center;
@ -900,6 +897,8 @@ input {
}
.navbar-sub-nav {
display: flex;
align-items: center;
height: 100%;
margin: 0 0 0 6px;
}
.caret-down,
@ -1019,7 +1018,7 @@ input {
left: 0;
z-index: 600;
width: 220px;
top: var(--header-height, 40px);
top: var(--header-height, 48px);
background-color: #f0f0f0;
transform: translate3d(0, 0, 0);
}
@ -1704,19 +1703,9 @@ svg.s16 {
.gl-display-none {
display: none;
}
@media (min-width: 992px) {
.gl-lg-display-none\! {
display: none !important;
}
}
.gl-display-flex {
display: flex;
}
@media (min-width: 992px) {
.gl-lg-display-flex {
display: flex;
}
}
@media (min-width: 576px) {
.gl-sm-display-block {
display: block;

View File

@ -419,7 +419,7 @@ body.navless {
}
}
.navless-container {
margin-top: var(--header-height, 40px);
margin-top: var(--header-height, 48px);
padding-top: 32px;
}
.btn {
@ -506,7 +506,7 @@ label.label-bold {
}
.navbar-empty {
justify-content: center;
height: var(--header-height, 40px);
height: var(--header-height, 48px);
background: #fff;
border-bottom: 1px solid #dbdbdb;
}

View File

@ -0,0 +1,55 @@
# frozen_string_literal: true
module Mailgun
class WebhooksController < ApplicationController
respond_to :json
skip_before_action :authenticate_user!
skip_before_action :verify_authenticity_token
before_action :ensure_feature_enabled!
before_action :authenticate_signature!
feature_category :team_planning
WEBHOOK_PROCESSORS = [
::Members::Mailgun::ProcessWebhookService
].freeze
def process_webhook
WEBHOOK_PROCESSORS.each do |processor_class|
processor = processor_class.new(params['event-data'] || {})
processor.execute if processor.should_process?
end
head :ok
end
private
def ensure_feature_enabled!
render_406 unless Gitlab::CurrentSettings.mailgun_events_enabled?
end
def authenticate_signature!
access_denied! unless valid_signature?
end
def valid_signature?
return false if Gitlab::CurrentSettings.mailgun_signing_key.blank?
# per this guide: https://documentation.mailgun.com/en/latest/user_manual.html#webhooks
digest = OpenSSL::Digest.new('SHA256')
data = [params.dig(:signature, :timestamp), params.dig(:signature, :token)].join
hmac_digest = OpenSSL::HMAC.hexdigest(digest, Gitlab::CurrentSettings.mailgun_signing_key, data)
ActiveSupport::SecurityUtils.secure_compare(params.dig(:signature, :signature), hmac_digest)
end
def render_406
# failure to stop retries per https://documentation.mailgun.com/en/latest/user_manual.html#webhooks
head :not_acceptable
end
end
end

View File

@ -1,65 +0,0 @@
# frozen_string_literal: true
module Members
module Mailgun
class PermanentFailuresController < ApplicationController
respond_to :json
skip_before_action :authenticate_user!
skip_before_action :verify_authenticity_token
before_action :ensure_feature_enabled!
before_action :authenticate_signature!
before_action :validate_invite_email!
feature_category :authentication_and_authorization
def create
webhook_processor.execute
head :ok
end
private
def ensure_feature_enabled!
render_406 unless Gitlab::CurrentSettings.mailgun_events_enabled?
end
def authenticate_signature!
access_denied! unless valid_signature?
end
def valid_signature?
return false if Gitlab::CurrentSettings.mailgun_signing_key.blank?
# per this guide: https://documentation.mailgun.com/en/latest/user_manual.html#webhooks
digest = OpenSSL::Digest.new('SHA256')
data = [params.dig(:signature, :timestamp), params.dig(:signature, :token)].join
hmac_digest = OpenSSL::HMAC.hexdigest(digest, Gitlab::CurrentSettings.mailgun_signing_key, data)
ActiveSupport::SecurityUtils.secure_compare(params.dig(:signature, :signature), hmac_digest)
end
def validate_invite_email!
# permanent_failures webhook does not provide a way to filter failures, so we'll get them all on this endpoint
# and we only care about our invite_emails
render_406 unless payload[:tags]&.include?(::Members::Mailgun::INVITE_EMAIL_TAG)
end
def webhook_processor
::Members::Mailgun::ProcessWebhookService.new(payload)
end
def payload
@payload ||= params.permit!['event-data']
end
def render_406
# failure to stop retries per https://documentation.mailgun.com/en/latest/user_manual.html#webhooks
head :not_acceptable
end
end
end
end

View File

@ -4,7 +4,6 @@ class Projects::Ci::PipelineEditorController < Projects::ApplicationController
before_action :check_can_collaborate!
before_action do
push_frontend_feature_flag(:schema_linting, @project)
push_frontend_feature_flag(:pipeline_editor_file_tree, @project)
end
feature_category :pipeline_authoring

View File

@ -52,6 +52,7 @@ module ResolvesMergeRequests
security_auto_fix: [:author],
head_pipeline: [:merge_request_diff, { head_pipeline: [:merge_request] }],
timelogs: [:timelogs],
pipelines: [:merge_request_diffs], # used by `recent_diff_head_shas` to load pipelines
committers: [merge_request_diff: [:merge_request_diff_commits]]
}
end

View File

@ -21,8 +21,9 @@ module Resolvers
super
end
def query_for(args)
resolve_pipelines(project, args).merge(merge_request.all_pipelines)
def query_for(input)
mr, args = input
resolve_pipelines(mr.source_project, args).merge(mr.all_pipelines)
end
def model_class
@ -30,7 +31,7 @@ module Resolvers
end
def query_input(**args)
args
[merge_request, args]
end
def project

View File

@ -1696,7 +1696,12 @@ class MergeRequest < ApplicationRecord
service_class.new(project, current_user, id: id, report_type: report_type).execute(comparison_base_pipeline(identifier), actual_head_pipeline)
end
def recent_diff_head_shas(limit = 100)
MAX_RECENT_DIFF_HEAD_SHAS = 100
def recent_diff_head_shas(limit = MAX_RECENT_DIFF_HEAD_SHAS)
# see MergeRequestDiff.recent
return merge_request_diffs.to_a.sort_by(&:id).reverse.first(limit).pluck(:head_commit_sha) if merge_request_diffs.loaded?
merge_request_diffs.recent(limit).pluck(:head_commit_sha)
end

View File

@ -16,6 +16,10 @@ module Members
Gitlab::ErrorTracking.track_exception(e)
end
def should_process?
payload['event'] == 'failed' && payload['severity'] == 'permanent' && payload['tags']&.include?(::Members::Mailgun::INVITE_EMAIL_TAG)
end
private
attr_reader :payload, :member

View File

@ -30,6 +30,7 @@ module Projects
validate_state!
validate_max_size!
validate_public_folder!
validate_max_entries!
build.artifacts_file.use_file do |artifacts_path|
@ -180,6 +181,10 @@ module Projects
end
end
def validate_public_folder!
raise InvalidStateError, 'Error: The `public/` folder is missing, or not declared in `.gitlab-ci.yml`.' unless total_size > 0
end
def entries_count
# we're using the full archive and pages daemon needs to read it
# so we want the total count from entries, not only "public/" directory

View File

@ -9,10 +9,7 @@
%h1.title
%span.gl-sr-only GitLab
= link_to root_path, title: _('Dashboard'), id: 'logo', **tracking_attrs('main_navigation', 'click_gitlab_logo_link', 'navigation') do
%span{ :class => "gl-display-none gl-lg-display-flex" }
= brand_header_logo({add_gitlab_white_text: true})
%span{ :class => "gl-lg-display-none! gl-display-flex" }
= brand_header_logo
= brand_header_logo
- if Gitlab.com_and_canary?
= link_to Gitlab::Saas.canary_toggle_com_url, class: 'canary-badge bg-transparent', data: { qa_selector: 'canary_badge_link' }, target: :_blank, rel: 'noopener noreferrer' do
= gl_badge_tag({ variant: :success, size: :sm }) do

View File

@ -1,3 +1,5 @@
- page_title _('Edit Release')
- add_to_breadcrumbs _('Releases'), project_releases_path(@project)
- add_to_breadcrumbs @release.name, project_release_path(@project, @release)
#js-edit-release-page{ data: data_for_edit_release_page }

View File

@ -7,6 +7,7 @@ module Database
include ApplicationWorker
include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
include Gitlab::Utils::StrongMemoize
LEASE_TIMEOUT_MULTIPLIER = 3
MINIMUM_LEASE_TIMEOUT = 10.minutes.freeze
@ -44,6 +45,15 @@ module Database
return
end
if shares_db_config?
Sidekiq.logger.info(
class: self.class.name,
database: self.class.tracking_database,
message: 'skipping migration execution for database that shares database configuration with another database')
return
end
Gitlab::Database::SharedModel.using_connection(base_model.connection) do
break unless self.class.enabled? && active_migration
@ -63,7 +73,7 @@ module Database
private
def active_migration
@active_migration ||= Gitlab::Database::BackgroundMigration::BatchedMigration.active_migration
@active_migration ||= Gitlab::Database::BackgroundMigration::BatchedMigration.active_migration(connection: base_model.connection)
end
def run_active_migration
@ -71,7 +81,13 @@ module Database
end
def base_model
@base_model ||= Gitlab::Database.database_base_models[self.class.tracking_database]
strong_memoize(:base_model) do
Gitlab::Database.database_base_models[self.class.tracking_database]
end
end
def shares_db_config?
base_model && Gitlab::Database.db_config_share_with(base_model.connection_db_config).present?
end
def with_exclusive_lease(interval)

View File

@ -13,7 +13,7 @@ module Namespaces
urgency :high
idempotent!
deduplicate :until_executing
deduplicate :until_executed
def perform
results = ::Ci::ProcessSyncEventsService.new(

View File

@ -13,7 +13,7 @@ module Projects
urgency :high
idempotent!
deduplicate :until_executing
deduplicate :until_executed
def perform
results = ::Ci::ProcessSyncEventsService.new(

View File

@ -16,6 +16,14 @@ production:
username: git
password: "secure password"
host: localhost
geo:
adapter: postgresql
encoding: unicode
database: gitlabhq_geo_production
username: git
password: "secure password"
host: localhost
#
# Development specific
#
@ -38,6 +46,13 @@ development:
host: localhost
variables:
statement_timeout: 15s
geo:
adapter: postgresql
encoding: unicode
database: gitlabhq_geo_development
username: postgres
password: "secure password"
host: localhost
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
@ -63,3 +78,10 @@ test: &test
prepared_statements: false
variables:
statement_timeout: 15s
geo:
adapter: postgresql
encoding: unicode
database: gitlabhq_geo_test
username: postgres
password:
host: localhost

View File

@ -18,6 +18,13 @@ production:
# port: 8600
# record: secondary.postgresql.service.consul
# interval: 300
geo:
adapter: postgresql
encoding: unicode
database: gitlabhq_geo_production
username: git
password: "secure password"
host: localhost
#
# Development specific
@ -32,6 +39,13 @@ development:
host: localhost
variables:
statement_timeout: 15s
geo:
adapter: postgresql
encoding: unicode
database: gitlabhq_geo_development
username: postgres
password: "secure password"
host: localhost
#
# Staging specific
@ -44,6 +58,13 @@ staging:
username: git
password: "secure password"
host: localhost
geo:
adapter: postgresql
encoding: unicode
database: gitlabhq_geo_staging
username: git
password: "secure password"
host: localhost
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
@ -59,3 +80,10 @@ test: &test
prepared_statements: false
variables:
statement_timeout: 15s
geo:
adapter: postgresql
encoding: unicode
database: gitlabhq_geo_test
username: postgres
password:
host: localhost

View File

@ -1,43 +0,0 @@
#
# PRODUCTION
#
production:
adapter: postgresql
encoding: unicode
database: gitlabhq_geo_production
username: git
password: "secure password"
host: localhost
#
# Development specific
#
development:
adapter: postgresql
encoding: unicode
database: gitlabhq_geo_development
username: postgres
password: "secure password"
host: localhost
#
# Staging specific
#
staging:
adapter: postgresql
encoding: unicode
database: gitlabhq_geo_staging
username: git
password: "secure password"
host: localhost
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test: &test
adapter: postgresql
encoding: unicode
database: gitlabhq_geo_test
username: postgres
password:
host: localhost

View File

@ -1,8 +1,8 @@
---
name: pipeline_editor_file_tree
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83910
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/357219
name: ci_show_all_projects_with_usage_sorted_descending
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83680
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/362331
milestone: '15.0'
type: development
group: group::pipeline authoring
group: group::pipeline execution
default_enabled: false

View File

@ -711,7 +711,7 @@ Gitlab.ee do
Settings.cron_jobs['ldap_sync_worker']['job_class'] = 'LdapSyncWorker'
Settings.cron_jobs['free_user_cap_data_remediation'] ||= Settingslogic.new({})
Settings.cron_jobs['free_user_cap_data_remediation']['cron'] ||= '17 6,10,14,18 * * *'
Settings.cron_jobs['free_user_cap_data_remediation']['job_class'] = 'Namespaces::FreeUserCapWorker'
Settings.cron_jobs['free_user_cap_data_remediation']['job_class'] = 'Namespaces::FreeUserCap::RemediationWorker'
Settings.cron_jobs['update_max_seats_used_for_gitlab_com_subscriptions_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['update_max_seats_used_for_gitlab_com_subscriptions_worker']['cron'] ||= '0 12 * * *'
Settings.cron_jobs['update_max_seats_used_for_gitlab_com_subscriptions_worker']['job_class'] = 'UpdateMaxSeatsUsedForGitlabComSubscriptionsWorker'

View File

@ -1,14 +1,6 @@
# frozen_string_literal: true
Gitlab.ee do
# We need to initialize the Geo database before
# setting the Geo DB connection pool size.
if File.exist?(Rails.root.join('config/database_geo.yml'))
Rails.application.configure do
config.geo_database = config_for(:database_geo)
end
end
if Gitlab::Runtime.sidekiq? && Gitlab::Geo.geo_database_configured?
# The Geo::TrackingBase model does not yet use connects_to. So,
# this will not properly support geo: from config/databse.yml

View File

@ -228,7 +228,12 @@ Rails.application.routes.draw do
draw :snippets
draw :profile
draw :members
post '/mailgun/webhooks' => 'mailgun/webhooks#process_webhook'
# Deprecated route for permanent failures
# https://gitlab.com/gitlab-org/gitlab/-/issues/362606
post '/members/mailgun/permanent_failures' => 'mailgun/webhooks#process_webhook'
# Product analytics collector
match '/collector/i', to: ProductAnalytics::CollectorApp.new, via: :all

View File

@ -1,7 +0,0 @@
# frozen_string_literal: true
namespace :members do
namespace :mailgun do
resources :permanent_failures, only: [:create]
end
end

View File

@ -0,0 +1,11 @@
# frozen_string_literal: true
class AddGitlabSchemaToBatchedBackgroundMigrations < Gitlab::Database::Migration[2.0]
# rubocop:disable Migration/AddLimitToTextColumns
# limit is added in 20220503035437_add_text_limit_to_batched_background_migrations_gitlab_schema
def change
add_column :batched_background_migrations, :gitlab_schema, :text, null: false, default: :gitlab_main
change_column_default(:batched_background_migrations, :gitlab_schema, from: :gitlab_main, to: nil)
end
# rubocop:enable Migration/AddLimitToTextColumns
end

View File

@ -0,0 +1,13 @@
# frozen_string_literal: true
class AddTextLimitToBatchedBackgroundMigrationsGitlabSchema < Gitlab::Database::Migration[2.0]
disable_ddl_transaction!
def up
add_text_limit :batched_background_migrations, :gitlab_schema, 255
end
def down
remove_text_limit :batched_background_migrations, :gitlab_schema
end
end

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
class IndexBatchedMigrationsOnGitlabSchemaAndConfiguration < Gitlab::Database::Migration[2.0]
disable_ddl_transaction!
TABLE_NAME = :batched_background_migrations
INDEX_NAME = 'index_batched_migrations_on_gl_schema_and_unique_configuration'
def up
add_concurrent_index TABLE_NAME,
%i[gitlab_schema job_class_name table_name column_name job_arguments],
unique: true,
name: INDEX_NAME
end
def down
remove_concurrent_index_by_name TABLE_NAME, INDEX_NAME
end
end

View File

@ -16,8 +16,6 @@ class BackfillIntegrationsTypeNew < ActiveRecord::Migration[6.1]
end
def down
Gitlab::Database::BackgroundMigration::BatchedMigration
.for_configuration(MIGRATION, :integrations, :id, [])
.delete_all
delete_batched_background_migration(MIGRATION, :integrations, :id, [])
end
end

View File

@ -19,8 +19,6 @@ class BackfillUserNamespace < Gitlab::Database::Migration[1.0]
end
def down
Gitlab::Database::BackgroundMigration::BatchedMigration
.for_configuration(MIGRATION, :namespaces, :id, [])
.delete_all
delete_batched_background_migration(MIGRATION, :namespaces, :id, [])
end
end

View File

@ -15,8 +15,6 @@ class BackfillIssueSearchData < Gitlab::Database::Migration[1.0]
end
def down
Gitlab::Database::BackgroundMigration::BatchedMigration
.for_configuration(MIGRATION, :issues, :id, [])
.delete_all
delete_batched_background_migration(MIGRATION, :issues, :id, [])
end
end

View File

@ -36,7 +36,6 @@ class BackfillProjectNamespacesForGroup < Gitlab::Database::Migration[1.0]
def down
return unless Gitlab.com? || Gitlab.staging?
Gitlab::Database::BackgroundMigration::BatchedMigration
.for_configuration(MIGRATION, :projects, :id, [GROUP_ID, 'up']).delete_all
delete_batched_background_migration(MIGRATION, :projects, :id, [GROUP_ID, 'up'])
end
end

View File

@ -20,8 +20,6 @@ class BackfillNamespaceIdForNamespaceRoutes < Gitlab::Database::Migration[1.0]
end
def down
Gitlab::Database::BackgroundMigration::BatchedMigration
.for_configuration(MIGRATION, :routes, :id, [])
.delete_all
delete_batched_background_migration(MIGRATION, :routes, :id, [])
end
end

View File

@ -20,8 +20,6 @@ class BackfillMemberNamespaceIdForGroupMembers < Gitlab::Database::Migration[1.0
end
def down
Gitlab::Database::BackgroundMigration::BatchedMigration
.for_configuration(MIGRATION, :members, :id, [])
.delete_all
delete_batched_background_migration(MIGRATION, :members, :id, [])
end
end

View File

@ -20,8 +20,6 @@ class ScheduleNullifyOrphanRunnerIdOnCiBuilds < Gitlab::Database::Migration[1.0]
end
def down
Gitlab::Database::BackgroundMigration::BatchedMigration
.for_configuration(MIGRATION, :ci_builds, :id, [])
.delete_all
delete_batched_background_migration(MIGRATION, :ci_builds, :id, [])
end
end

View File

@ -24,7 +24,6 @@ class BackfillAllProjectNamespaces < Gitlab::Database::Migration[1.0]
end
def down
Gitlab::Database::BackgroundMigration::BatchedMigration
.for_configuration(MIGRATION, :projects, :id, [nil, 'up']).delete_all
delete_batched_background_migration(MIGRATION, :projects, :id, [nil, 'up'])
end
end

View File

@ -22,8 +22,6 @@ class BackfillGroupFeatures < Gitlab::Database::Migration[1.0]
end
def down
Gitlab::Database::BackgroundMigration::BatchedMigration
.for_configuration(MIGRATION, :namespaces, :id, [BATCH_SIZE])
.delete_all
delete_batched_background_migration(MIGRATION, :namespaces, :id, [BATCH_SIZE])
end
end

View File

@ -22,8 +22,6 @@ class BackfillNamespaceIdForProjectRoutes < Gitlab::Database::Migration[1.0]
end
def down
Gitlab::Database::BackgroundMigration::BatchedMigration
.for_configuration(MIGRATION, :routes, :id, [])
.delete_all
delete_batched_background_migration(MIGRATION, :routes, :id, [])
end
end

View File

@ -18,8 +18,6 @@ class ScheduleBackfillProjectSettings < Gitlab::Database::Migration[1.0]
end
def down
Gitlab::Database::BackgroundMigration::BatchedMigration
.for_configuration(MIGRATION, :projects, :id, [])
.delete_all
delete_batched_background_migration(MIGRATION, :projects, :id, [])
end
end

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
class RemoveThreatMonitoringAlerts < Gitlab::Database::Migration[2.0]
disable_ddl_transaction!
restrict_gitlab_migration gitlab_schema: :gitlab_main
def up
execute("DELETE FROM alert_management_alerts WHERE domain = 1")
end
def down
# no-op
end
end

View File

@ -0,0 +1,50 @@
# frozen_string_literal: true
class RemoveWebHooksWebHookLogsWebHookIdFk < Gitlab::Database::Migration[2.0]
disable_ddl_transaction!
PARENT_TABLE_NAME = :web_hook_logs
FK_NAME = "fk_rails_bb3355782d"
def up
with_lock_retries do
execute('LOCK web_hooks, web_hook_logs IN ACCESS EXCLUSIVE MODE') if transaction_open?
remove_foreign_key_if_exists(:web_hook_logs, :web_hooks, name: FK_NAME)
end
end
def down
fk_attrs = {
name: FK_NAME, # Note we need the same name for every partition
column: :web_hook_id,
target_column: :id,
on_delete: :cascade
}
# Must add child FK's first, then to the partitioned table.
child_tables.each do |tbl|
add_concurrent_foreign_key(
tbl, :web_hooks,
# This embeds the lock table statement in the with_lock_retries inside add_concurrent_foreign_key
reverse_lock_order: true,
**fk_attrs)
end
with_lock_retries do
execute("LOCK web_hooks, #{PARENT_TABLE_NAME} IN ACCESS EXCLUSIVE MODE") if transaction_open?
add_foreign_key(:web_hook_logs, :web_hooks, **fk_attrs)
end
end
# This table is partitioned: we need to apply the index changes to each
# partition separately.
def child_tables
@child_tables ||= execute(<<~SQL.squish).pluck("child")
SELECT inhrelid::regclass AS child
FROM pg_catalog.pg_inherits
WHERE inhparent = '#{PARENT_TABLE_NAME}'::regclass
ORDER BY inhrelid ASC
SQL
end
end

View File

@ -10,9 +10,7 @@ class RescheduleExpireOAuthTokens < Gitlab::Database::Migration[2.0]
def up
# remove the original migration from db/post_migrate/20220428133724_schedule_expire_o_auth_tokens.rb
Gitlab::Database::BackgroundMigration::BatchedMigration
.for_configuration(MIGRATION, :oauth_access_tokens, :id, [])
.delete_all
delete_batched_background_migration(MIGRATION, :oauth_access_tokens, :id, [])
# reschedule
queue_batched_background_migration(
@ -24,8 +22,6 @@ class RescheduleExpireOAuthTokens < Gitlab::Database::Migration[2.0]
end
def down
Gitlab::Database::BackgroundMigration::BatchedMigration
.for_configuration(MIGRATION, :oauth_access_tokens, :id, [])
.delete_all
delete_batched_background_migration(MIGRATION, :oauth_access_tokens, :id, [])
end
end

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
class CreateConfidentialNotesIndexSynchronously < Gitlab::Database::Migration[2.0]
INDEX_NAME = 'index_notes_on_confidential'
disable_ddl_transaction!
def up
add_concurrent_index :notes, :confidential, where: 'confidential = true', name: INDEX_NAME
end
def down
remove_concurrent_index_by_name :notes, name: INDEX_NAME
end
end

View File

@ -0,0 +1,11 @@
# frozen_string_literal: true
class MigrateFreeUserCapRemediation < Gitlab::Database::Migration[2.0]
def up
sidekiq_queue_migrate 'cronjob:namespaces_free_user_cap', to: 'cronjob:namespaces_free_user_cap_remediation'
end
def down
sidekiq_queue_migrate 'cronjob:namespaces_free_user_cap_remediation', to: 'cronjob:namespaces_free_user_cap'
end
end

View File

@ -0,0 +1 @@
0eeb96f26d8f8372c70f9aef59e976c4d403ec6aec01ad8784d31a7594bbaee2

View File

@ -0,0 +1 @@
78306ca94e5f8e595d496efff983ed4749ee841ca8e2633afdb0cc5cb077e96a

View File

@ -0,0 +1 @@
6f77ac586d48274a8f88384808b56ecad33a8ce00488595c0f82a074b45d5634

View File

@ -0,0 +1 @@
16071cd85b772d86242ced867ba2f8c5e317222f6c3297e15dd456de13b4926e

View File

@ -0,0 +1 @@
bbd6be6772f4fc5aecf393d6c043c1fdc38fdde6efd1586ba4be08ddbb5886dd

View File

@ -0,0 +1 @@
74585dbb76b6744533a1df5dc995b461798fe8d0e0cd37fb6f9d52958f87a403

View File

@ -0,0 +1 @@
eadee7b8b85cce48f48dbdab2f5e0b8cd633ef4ef8363960b7de1eb73a6fe1aa

View File

@ -11767,6 +11767,8 @@ CREATE TABLE batched_background_migrations (
max_batch_size integer,
started_at timestamp with time zone,
on_hold_until timestamp with time zone,
gitlab_schema text NOT NULL,
CONSTRAINT check_0406d9776f CHECK ((char_length(gitlab_schema) <= 255)),
CONSTRAINT check_5bb0382d6f CHECK ((char_length(column_name) <= 63)),
CONSTRAINT check_6b6a06254a CHECK ((char_length(table_name) <= 63)),
CONSTRAINT check_batch_size_in_range CHECK ((batch_size >= sub_batch_size)),
@ -26911,6 +26913,8 @@ CREATE INDEX index_batched_jobs_by_batched_migration_id_and_id ON batched_backgr
CREATE INDEX index_batched_jobs_on_batched_migration_id_and_status ON batched_background_migration_jobs USING btree (batched_background_migration_id, status);
CREATE UNIQUE INDEX index_batched_migrations_on_gl_schema_and_unique_configuration ON batched_background_migrations USING btree (gitlab_schema, job_class_name, table_name, column_name, job_arguments);
CREATE INDEX index_board_assignees_on_assignee_id ON board_assignees USING btree (assignee_id);
CREATE UNIQUE INDEX index_board_assignees_on_board_id_and_assignee_id ON board_assignees USING btree (board_id, assignee_id);
@ -28425,6 +28429,8 @@ CREATE INDEX index_notes_on_author_id_and_created_at_and_id ON notes USING btree
CREATE INDEX index_notes_on_commit_id ON notes USING btree (commit_id);
CREATE INDEX index_notes_on_confidential ON notes USING btree (confidential) WHERE (confidential = true);
CREATE INDEX index_notes_on_created_at ON notes USING btree (created_at);
CREATE INDEX index_notes_on_discussion_id ON notes USING btree (discussion_id);
@ -33118,9 +33124,6 @@ ALTER TABLE ONLY approval_project_rules_users
ALTER TABLE ONLY lists
ADD CONSTRAINT fk_rails_baed5f39b7 FOREIGN KEY (milestone_id) REFERENCES milestones(id) ON DELETE CASCADE;
ALTER TABLE web_hook_logs
ADD CONSTRAINT fk_rails_bb3355782d FOREIGN KEY (web_hook_id) REFERENCES web_hooks(id) ON DELETE CASCADE;
ALTER TABLE ONLY security_findings
ADD CONSTRAINT fk_rails_bb63863cf1 FOREIGN KEY (scan_id) REFERENCES security_scans(id) ON DELETE CASCADE;

View File

@ -203,6 +203,8 @@ successfully, you must replicate their data using some other means.
|[External merge request diffs](../../merge_request_diffs.md) | **Yes** (13.5) | **Yes** (14.6) | Via Object Storage provider if supported. Native Geo support (Beta). | Replication is behind the feature flag `geo_merge_request_diff_replication`, enabled by default. Verification was behind the feature flag `geo_merge_request_diff_verification`, removed in 14.7.|
|[Versioned snippets](../../../user/snippets.md#versioned-snippets) | [**Yes** (13.7)](https://gitlab.com/groups/gitlab-org/-/epics/2809) | [**Yes** (14.2)](https://gitlab.com/groups/gitlab-org/-/epics/2810) | No | Verification was implemented behind the feature flag `geo_snippet_repository_verification` in 13.11, and the feature flag was removed in 14.2. |
|[GitLab Pages](../../pages/index.md) | [**Yes** (14.3)](https://gitlab.com/groups/gitlab-org/-/epics/589) | [**Yes**](#limitation-of-verification-for-files-in-object-storage) (14.6) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_pages_deployment_replication`, enabled by default. Verification was behind the feature flag `geo_pages_deployment_verification`, removed in 14.7. |
|[Incident Metric Images](../../../operations/incident_management/incidents.md#metrics) | [Planned](https://gitlab.com/gitlab-org/gitlab/-/issues/352326) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/362561) | No | |
|[Alert Metric Images](../../../operations/incident_management/alerts.md#metrics-tab) | [Planned](https://gitlab.com/gitlab-org/gitlab/-/issues/352326) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/362561) | No | |
|[Server-side Git hooks](../../server_hooks.md) | [Not planned](https://gitlab.com/groups/gitlab-org/-/epics/1867) | No | No | Not planned because of current implementation complexity, low customer interest, and availability of alternatives to hooks. |
|[Elasticsearch integration](../../../integration/elasticsearch.md) | [Not planned](https://gitlab.com/gitlab-org/gitlab/-/issues/1186) | No | No | Not planned because further product discovery is required and Elasticsearch (ES) clusters can be rebuilt. Secondaries use the same ES cluster as the primary. |
|[Dependency proxy images](../../../user/packages/dependency_proxy/index.md) | [Not planned](https://gitlab.com/gitlab-org/gitlab/-/issues/259694) | No | No | Blocked by [Geo: Secondary Mimicry](https://gitlab.com/groups/gitlab-org/-/epics/1528). Replication of this cache is not needed for disaster recovery purposes because it can be recreated from external sources. |

View File

@ -1,6 +1,6 @@
---
stage: Growth
group: Expansion
stage: Plan
group: Project Management
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
type: reference, howto
---
@ -9,26 +9,37 @@ type: reference, howto
When you use Mailgun to send emails for your GitLab instance and [Mailgun](https://www.mailgun.com/)
integration is enabled and configured in GitLab, you can receive their webhook for
permanent invite email failures. To set up the integration, you must:
tracking delivery failures. To set up the integration, you must:
1. [Configure your Mailgun domain](#configure-your-mailgun-domain).
1. [Enable Mailgun integration](#enable-mailgun-integration).
After completing the integration, Mailgun `permanent_failure` webhooks are sent to your GitLab instance.
After completing the integration, Mailgun `temporary_failure` and `permanent_failure` webhooks are sent to your GitLab instance.
## Configure your Mailgun domain
Before you can enable Mailgun in GitLab, set up your own Mailgun permanent failure endpoint to receive the webhooks.
> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/359113) the `/-/members/mailgun/permanent_failures` URL in GitLab 15.0.
> [Added](https://gitlab.com/gitlab-org/gitlab/-/issues/359113) the URL to handle both temporary and permanent failures in GitLab 15.0.
Before you can enable Mailgun in GitLab, set up your own Mailgun endpoints to receive the webhooks.
Using the [Mailgun webhook guide](https://www.mailgun.com/blog/a-guide-to-using-mailguns-webhooks/):
1. Add a webhook with the **Event type** set to **Permanent Failure**.
1. Fill in the URL of your instance and include the `/-/members/mailgun/permanent_failures` path.
- Example: `https://myinstance.gitlab.com/-/members/mailgun/permanent_failures`
1. Enter the URL of your instance and include the `/-/mailgun/webhooks` path.
For example:
```plaintext
https://myinstance.gitlab.com/-/mailgun/webhooks
```
1. Add another webhook with the **Event type** set to **Temporary Failure**.
1. Enter the URL of your instance and use the same `/-/mailgun/webhooks` path.
## Enable Mailgun integration
After configuring your Mailgun domain for the permanent failures endpoint,
After configuring your Mailgun domain for the webhook endpoints,
you're ready to enable the Mailgun integration:
1. Sign in to GitLab as an [Administrator](../../user/permissions.md) user.

View File

@ -23,7 +23,7 @@ alternatives to server hooks include:
- [Webhooks](../user/project/integrations/webhooks.md).
- [GitLab CI/CD](../ci/index.md).
- [Push rules](../push_rules/push_rules.md), for a user-configurable Git hook interface.
- [Push rules](../user/project/repository/push_rules.md), for a user-configurable Git hook interface.
[Geo](geo/index.md) doesn't replicate server hooks to secondary nodes.

View File

@ -619,92 +619,56 @@ Parameters:
```json
{
"id": 1,
"iid": 1,
"project_id": 3,
"title": "test1",
"description": "fixed login page css paddings",
"state": "merged",
"created_at": "2017-04-29T08:46:00Z",
"updated_at": "2017-04-29T08:46:00Z",
"id": 155016530,
"iid": 133,
"project_id": 15513260,
"title": "Manual job rules",
"description": "",
"state": "opened",
"created_at": "2022-05-13T07:26:38.402Z",
"updated_at": "2022-05-14T03:38:31.354Z",
"merged_by": null, // Deprecated and will be removed in API v5, use `merge_user` instead
"merge_user": null,
"merged_at": null,
"closed_by": null,
"closed_at": null,
"target_branch": "master",
"source_branch": "test1",
"source_branch": "manual-job-rules",
"user_notes_count": 0,
"upvotes": 0,
"downvotes": 0,
"author": {
"id": 1,
"name": "Administrator",
"username": "admin",
"id": 4155490,
"username": "marcel.amirault",
"name": "Marcel Amirault",
"state": "active",
"avatar_url": null,
"web_url" : "https://gitlab.example.com/admin"
"avatar_url": "https://gitlab.com/uploads/-/system/user/avatar/4155490/avatar.png",
"web_url": "https://gitlab.com/marcel.amirault"
},
"user" : {
"can_merge" : false
},
"assignee": {
"id": 1,
"name": "Administrator",
"username": "admin",
"state": "active",
"avatar_url": null,
"web_url" : "https://gitlab.example.com/admin"
},
"assignees": [{
"name": "Miss Monserrate Beier",
"username": "axel.block",
"id": 12,
"state": "active",
"avatar_url": "http://www.gravatar.com/avatar/46f6f7dc858ada7be1853f7fb96e81da?s=80&d=identicon",
"web_url": "https://gitlab.example.com/axel.block"
}],
"reviewers": [{
"id": 2,
"name": "Sam Bauch",
"username": "kenyatta_oconnell",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/956c92487c6f6f7616b536927e22c9a0?s=80&d=identicon",
"web_url": "http://gitlab.example.com//kenyatta_oconnell"
}],
"source_project_id": 2,
"target_project_id": 3,
"labels": [
"Community contribution",
"Manage"
],
"assignees": [],
"assignee": null,
"reviewers": [],
"source_project_id": 15513260,
"target_project_id": 15513260,
"labels": [],
"draft": false,
"work_in_progress": false,
"milestone": {
"id": 5,
"iid": 1,
"project_id": 3,
"title": "v2.0",
"description": "Assumenda aut placeat expedita exercitationem labore sunt enim earum.",
"state": "closed",
"created_at": "2015-02-02T19:49:26.013Z",
"updated_at": "2015-02-02T19:49:26.013Z",
"due_date": "2018-09-22",
"start_date": "2018-08-08",
"web_url": "https://gitlab.example.com/my-group/my-project/milestones/1"
},
"merge_when_pipeline_succeeds": true,
"milestone": null,
"merge_when_pipeline_succeeds": false,
"merge_status": "can_be_merged",
"merge_error": null,
"sha": "8888888888888888888888888888888888888888",
"sha": "e82eb4a098e32c796079ca3915e07487fc4db24c",
"merge_commit_sha": null,
"squash_commit_sha": null,
"user_notes_count": 1,
"discussion_locked": null,
"should_remove_source_branch": true,
"force_remove_source_branch": false,
"allow_collaboration": false,
"allow_maintainer_to_push": false,
"web_url": "http://gitlab.example.com/my-group/my-project/merge_requests/1",
"should_remove_source_branch": null,
"force_remove_source_branch": true,
"reference": "!133",
"references": {
"short": "!1",
"relative": "!1",
"full": "my-group/my-project!1"
"short": "!133",
"relative": "!133",
"full": "marcel.amirault/test-project!133"
},
"web_url": "https://gitlab.com/marcel.amirault/test-project/-/merge_requests/133",
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
@ -712,51 +676,80 @@ Parameters:
"human_total_time_spent": null
},
"squash": false,
"subscribed": false,
"changes_count": "1",
"merged_by": { // Deprecated and will be removed in API v5, use `merge_user` instead
"id": 87854,
"name": "Douwe Maan",
"username": "DouweM",
"state": "active",
"avatar_url": "https://gitlab.example.com/uploads/-/system/user/avatar/87854/avatar.png",
"web_url": "https://gitlab.com/DouweM"
},
"merge_user": {
"id": 87854,
"name": "Douwe Maan",
"username": "DouweM",
"state": "active",
"avatar_url": "https://gitlab.example.com/uploads/-/system/user/avatar/87854/avatar.png",
"web_url": "https://gitlab.com/DouweM"
},
"merged_at": "2018-09-07T11:16:17.520Z",
"closed_by": null,
"closed_at": null,
"latest_build_started_at": "2018-09-07T07:27:38.472Z",
"latest_build_finished_at": "2018-09-07T08:07:06.012Z",
"first_deployed_to_production_at": null,
"pipeline": {
"id": 29626725,
"sha": "2be7ddb704c7b6b83732fdd5b9f09d5a397b5f8f",
"ref": "patch-28",
"status": "success",
"web_url": "https://gitlab.example.com/my-group/my-project/pipelines/29626725"
},
"diff_refs": {
"base_sha": "c380d3acebd181f13629a25d2e2acca46ffe1e00",
"head_sha": "2be7ddb704c7b6b83732fdd5b9f09d5a397b5f8f",
"start_sha": "c380d3acebd181f13629a25d2e2acca46ffe1e00"
},
"diverged_commits_count": 2,
"rebase_in_progress": false,
"first_contribution": false,
"task_completion_status":{
"count":0,
"completed_count":0
"task_completion_status": {
"count": 0,
"completed_count": 0
},
"has_conflicts": false,
"blocking_discussions_resolved": true
"blocking_discussions_resolved": true,
"approvals_before_merge": null,
"subscribed": true,
"changes_count": "1",
"latest_build_started_at": "2022-05-13T09:46:50.032Z",
"latest_build_finished_at": null,
"first_deployed_to_production_at": null,
"pipeline": { // Old parameter, use `head_pipeline` instead.
"id": 538317940,
"iid": 1877,
"project_id": 15513260,
"sha": "1604b0c46c395822e4e9478777f8e54ac99fe5b9",
"ref": "refs/merge-requests/133/merge",
"status": "failed",
"source": "merge_request_event",
"created_at": "2022-05-13T09:46:39.560Z",
"updated_at": "2022-05-13T09:47:20.706Z",
"web_url": "https://gitlab.com/marcel.amirault/test-project/-/pipelines/538317940"
},
"head_pipeline": {
"id": 538317940,
"iid": 1877,
"project_id": 15513260,
"sha": "1604b0c46c395822e4e9478777f8e54ac99fe5b9",
"ref": "refs/merge-requests/133/merge",
"status": "failed",
"source": "merge_request_event",
"created_at": "2022-05-13T09:46:39.560Z",
"updated_at": "2022-05-13T09:47:20.706Z",
"web_url": "https://gitlab.com/marcel.amirault/test-project/-/pipelines/538317940",
"before_sha": "1604b0c46c395822e4e9478777f8e54ac99fe5b9",
"tag": false,
"yaml_errors": null,
"user": {
"id": 4155490,
"username": "marcel.amirault",
"name": "Marcel Amirault",
"state": "active",
"avatar_url": "https://gitlab.com/uploads/-/system/user/avatar/4155490/avatar.png",
"web_url": "https://gitlab.com/marcel.amirault"
},
"started_at": "2022-05-13T09:46:50.032Z",
"finished_at": "2022-05-13T09:47:20.697Z",
"committed_at": null,
"duration": 30,
"queued_duration": 10,
"coverage": null,
"detailed_status": {
"icon": "status_failed",
"text": "failed",
"label": "failed",
"group": "failed",
"tooltip": "failed",
"has_details": true,
"details_path": "/marcel.amirault/test-project/-/pipelines/538317940",
"illustration": null,
"favicon": "/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png"
}
},
"diff_refs": {
"base_sha": "1162f719d711319a2efb2a35566f3bfdadee8bab",
"head_sha": "e82eb4a098e32c796079ca3915e07487fc4db24c",
"start_sha": "1162f719d711319a2efb2a35566f3bfdadee8bab"
},
"merge_error": null,
"first_contribution": false,
"user": {
"can_merge": true
}
}
```

View File

@ -53,12 +53,8 @@ reflected in the CI lint. It displays the same results as the existing [CI Lint
## View included CI/CD configuration
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/7064) in GitLab 15.0 [with a flag](../../administration/feature_flags.md) named `pipeline_editor_file_tree`. Disabled by default.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available,
ask an administrator to [enable the feature flag](../../administration/feature_flags.md)
named `pipeline_editor_file_tree`.
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/7064) in GitLab 15.0 [with a flag](../../administration/feature_flags.md) named `pipeline_editor_file_tree`. Disabled by default.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/357219) in GitLab 15.1.
You can review configuration added with the [`include`](../yaml/index.md#include)
keyword in the pipeline editor. In the top right, select the file tree (**{file-tree}**)

View File

@ -193,9 +193,12 @@ The cost factor for a job running on a shared runner is:
### Additional costs on GitLab SaaS
On GitLab SaaS, shared runners can have different cost factors depending on the cost involved
in executing the runner. For example, a high spec shared runner could be set to have a cost factor of `2`.
Conversely, a shared runner that executes jobs for public projects could have a low cost factor, like `0.008`.
GitLab SaaS shared runners have different cost factors, depending on the runner type (Linux, Windows, macOS) and the virtual machine configuration.
| GitLab SaaS runner type | Virtual machine configuration | CI/CD minutes cost factor |
| :--------- | :------------------- | :--------- |
| Linux OS + Docker executor| 1 vCPU, 3.75 GB RAM |1|
| macOS + shell executor | 4 vCPU, 10 GB RAM| 6 |
### Monthly reset of CI/CD minutes

View File

@ -0,0 +1,121 @@
---
stage: Verify
group: Runner
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Code signing for SaaS runners on macOS
> Introduced in GitLab 15.0.
Before you can integrate GitLab with Apple services, install to a device, or deploy to the Apple App Store, you must [code sign](https://developer.apple.com/support/code-signing/) your application.
To code sign an iOS project, you need the following files:
- A certifcate issued by Apple.
- A provisioning profile.
## Code signing iOS Projects with fastlane
When you use SaaS runners on macOS, each job runs on a VM. Included in each VM is [fastlane](https://fastlane.tools/),
an open-source solution aimed at simplifying mobile app deployment.
These steps outline the minimal setup required to use fastlane to code sign your application. Refer to the fastlane [getting started guide](https://docs.fastlane.tools/), [best practices for integrating with GitLab CI](https://docs.fastlane.tools/best-practices/continuous-integration/gitlab/) and the [fastlane code signing getting started guide](https://docs.fastlane.tools/codesigning/getting-started/) for installation instructions, and an overview of how to use fastlane to handle code signing.
To use fastlane to code sign your application:
1. At the root of your project repository, on your local development system, run this command:
```plaintext
fastlane match init
```
This command creates the `fastlane` directory and adds two files: `Fastfile` and `Appfile`.
1. Open `Appfile` and edit it to include your Apple ID and app ID.
```plaintext
app_identifier("APP IDENTIFIER") # The bundle identifier of your app
apple_id("APPLE ID") # Your Apple email address
```
1. Open `Fastfile`, which includes the fastlane build steps.
In the following snippet, the steps `get_certificates`, `get_provisioning_profile,match`, `gym`, and
`upload_to_testflight` are fastlane [actions](https://docs.fastlane.tools/actions/).
```plaintext
# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
default_platform(:ios)
platform :ios do
desc "Build the application"
lane :beta do
increment_build_number(
build_number: latest_testflight_build_number + 1,
xcodeproj: "${PROJECT_NAME}.xcodeproj"
)
get_certificates
get_provisioning_profile
# match(type: "appstore",read_only: true)
gym
upload_to_testflight
end
end
```
The example configuration also includes an optional `Gymfile`. This file stores configuration
parameters and is used by the fastlane [`gym`](https://docs.fastlane.tools/actions/gym/) action.
## Using fastlane match
To simplify the code signing process and implement the
[Code Signing Best Practices Guide](https://codesigning.guide/) recommendations,
use [fastlane match](https://docs.fastlane.tools/actions/match/).
- Use one code signing identity shared across your team.
- Store the required certificates and provisioning profiles in a separate GitLab project repository.
Match automatically syncs iOS and macOS keys and provisioning profiles across all team members with access to the GitLab project. Each team member with access to the project can use the credentials for code signing.
To use fastlane match:
1. Initialize match in the project repository:
```shell
bundle exec fastlane match init
```
1. Select `git` as your storage node.
1. Enter the URL of the GitLab project you plan to use to store your code signing identities.
1. Optional. To create a new certificate and provisioning profile, run:
```shell
bundle exec fastlane match development
```
For different code signing identities' storage options, and for a complete step-by-step guide for using match,
refer to the [match documentation](https://docs.fastlane.tools/actions/match/#usage).
### Environment variables and authentication
To complete the setup, you must configure environment variables to use with fastlane. The required variables are outlined in the [fastlane documentation](https://docs.fastlane.tools/best-practices/continuous-integration/#environment-variables-to-set).
To support Apple's two factor authentication requirement, configure these variables:
- `FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD` and
- `FASTLANE_SESSION`
To authenticate fastlane with the App Store for the TestFlight upload, configure these variables:
- `FASTLANE_USER` and
- `FASTLANE_PASSWORD`
View the [fastlane authentication with Apple Services guide](https://docs.fastlane.tools/getting-started/ios/authentication/) for an overview of authentication options.
## Related topics
- [Apple Developer Support - Code Signing](https://developer.apple.com/support/code-signing/)
- [Code Signing Best Practice Guide](https://codesigning.guide/)

View File

@ -20,7 +20,7 @@ Each time you run a job that requires tooling or dependencies not available in t
GitLab SaaS provides macOS build machines on Apple servers with Intel x86-64 processors.
The expectation is that virtual machines running on the Apple M1 chip will be available in the second half of 2022.
For the [Beta](../../../../policy/alpha-beta-support.md#beta-features), there is only one available machine type, `gbc-macos-large`.
At this time there is only one available machine type offered, `gbc-macos-large`.
| Instance type | vCPUS | Memory (GB) |
| --------- | --- | ------- |

View File

@ -4,10 +4,9 @@ group: Runner
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# SaaS runners on macOS (beta) **(PREMIUM SAAS)**
# SaaS runners on macOS (Limited Availability) **(PREMIUM SAAS)**
SaaS runners on macOS are in [Beta](../../../policy/alpha-beta-support.md#beta-features)
and shouldn't be relied upon for mission-critical production jobs.
SaaS runners on macOS are now in [Limited Availability](../../../policy/alpha-beta-support.md#beta-features) for approved open source programs and customers in Premium and Ultimate plans.
SaaS runners on macOS provide an on-demand macOS build environment integrated with
GitLab SaaS [CI/CD](../../../ci/index.md).
@ -15,11 +14,17 @@ Use these runners to build, test, and deploy apps for the Apple ecosystem (macOS
of all the capabilities of the GitLab single DevOps platform and not have to manage or operate a
build environment.
CI/CD minutes used on GitLab SaaS macOS runners are included in your CI/CD minute consumption totals. CI jobs that run on macOS **will** consume CI minutes at a faster rate than CI jobs on the GitLab SaaS runners on Linux.
Refer to the CI/CD minutes [cost factor](../../../ci/pipelines/cicd_minutes.md#cost-factor) for the cost factor applied to the GitLab SaaS macOS runners.
## Quickstart
To start using SaaS runners on macOS, you must submit an access request [issue](https://gitlab.com/gitlab-com/macos-buildcloud-runners-beta/-/issues/new?issuable_template=beta_access_request). After your
access has been granted and your build environment configured, you must configure your
`.gitlab-ci.yml` pipeline file:
To start using SaaS runners on macOS, you must be an active GitLab SaaS Premium or Ultimate customer. Participants in the GitLab Open Source program are also eligible to use the service.
### Configuring your pipeline
To start using the SaaS runners on macOS to run your CI jobs, you must configure your `.gitlab-ci.yml` file:
1. Add a `.gitlab-ci.yml` file to your project repository.
1. Specify the [image](macos/environment.md#vm-images) you want to use.
@ -27,7 +32,7 @@ access has been granted and your build environment configured, you must configur
The runners automatically run your build.
## Example `.gitlab-ci.yml` file
### Example `.gitlab-ci.yml` file
The following sample `.gitlab-ci.yml` file shows how to start using the SaaS runners on macOS:
@ -42,7 +47,7 @@ stages:
- test
before_script:
- echo "started by ${GITLAB_USER_NAME}"
- echo "started by ${GITLAB_USER_NAME}"
build:
extends:
@ -60,4 +65,13 @@ test:
```
NOTE:
During the Beta period, the architecture of this solution will change. Rather than the jobs running on a specific VM instance, they will run on an ephemeral VM instance that is created by an autoscaling instance, known as the Runner Manager. We will notify all Beta participants of any downtime required to do this work.
You can specify a different Xcode image to run a job. To do so, replace the value for the `image` keyword with the value of the [virtual machine image name](macos/environment.md#vm-images) from the list of available images.
## SaaS runners on macOS service level objective
In SaaS runners on macOS, the objective is to make 90% of CI jobs start executing in 120 seconds or less. The error rate should be less than 0.5%.
## Known Limitations and Usage Constraints
- If the VM image does not include the specific software version you need for your job, then the job execution time will increase as the required software needs to be fetched and installed.
- At this time, it is not possible to bring your own OS image.

View File

@ -152,9 +152,7 @@ When you start the second post-deployment migration, delete the
previously batched migration with the provided code:
```ruby
Gitlab::Database::BackgroundMigration::BatchedMigration
.for_configuration(MIGRATION_NAME, TABLE_NAME, COLUMN, JOB_ARGUMENTS)
.delete_all
delete_batched_background_migration(MIGRATION_NAME, TABLE_NAME, COLUMN, JOB_ARGUMENTS)
```
## Cleaning up
@ -261,8 +259,7 @@ background migration.
end
def down
Gitlab::Database::BackgroundMigration::BatchedMigration
.for_configuration(MIGRATION, :routes, :id, []).delete_all
delete_batched_background_migration(MIGRATION_NAME, :routes, :id, [])
end
end
```

View File

@ -191,6 +191,8 @@ GitLab documentation should be clear and easy to understand.
### Capitalization
As a company, we tend toward lowercase.
#### Headings
Use sentence case. For example:
@ -589,6 +591,10 @@ Consider installing a plugin or extension in your editor for formatting tables:
- [Markdown Table Formatter](https://packagecontrol.io/packages/Markdown%20Table%20Formatter) for Sublime Text
- [Markdown Table Formatter](https://atom.io/packages/markdown-table-formatter) for Atom
### Table headings
Use sentence case for table headings. For example, `Keyword value` or `Project name`.
### Feature tables
When creating tables of lists of features (such the features

View File

@ -95,6 +95,7 @@ Guidelines:
- Consider notifying `#support_gitlab-com` beforehand. So in case if the feature has any side effects on user experience, they can mitigate and disable the feature flag to reduce some impact.
- If the feature meets the requirements for creating a [Change Management](https://about.gitlab.com/handbook/engineering/infrastructure/change-management/#feature-flags-and-the-change-management-process) issue, create a Change Management issue per [criticality guidelines](https://about.gitlab.com/handbook/engineering/infrastructure/change-management/#change-request-workflows).
- For simple, low-risk, easily reverted features, proceed and [enable the feature in `#production`](#process).
- For support requests to toggle feature flags for specific groups or projects, please follow the process outlined in the [support workflows](https://about.gitlab.com/handbook/support/workflows/saas_feature_flags.html).
#### Process

View File

@ -188,7 +188,7 @@ needs to be applied to the tracking database on each **secondary** site.
### Configuration
The database configuration is set in [`config/database_geo.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/database_geo.yml.postgresql).
The database configuration is set in [`config/database.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/database.yml.postgresql).
The directory [`ee/db/geo`](https://gitlab.com/gitlab-org/gitlab/-/tree/master/ee/db/geo)
contains the schema and migrations for this database.

View File

@ -1,11 +0,0 @@
---
redirect_to: '../user/project/repository/push_rules.md'
remove_date: '2022-05-10'
---
This document was moved to [another location](../user/project/repository/push_rules.md).
<!-- This redirect file can be deleted after <2022-05-10>. -->
<!-- Redirects that point to other docs in the same project expire in three months. -->
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->

View File

@ -409,6 +409,7 @@ applications.
| `AUTO_DEVOPS_BUILD_IMAGE_CNB_BUILDER` | The builder used when building with Cloud Native Buildpacks. The default builder is `heroku/buildpacks:18`. [More details](stages.md#auto-build-using-cloud-native-buildpacks). |
| `AUTO_DEVOPS_BUILD_IMAGE_EXTRA_ARGS` | Extra arguments to be passed to the `docker build` command. Note that using quotes doesn't prevent word splitting. [More details](#passing-arguments-to-docker-build). |
| `AUTO_DEVOPS_BUILD_IMAGE_FORWARDED_CI_VARIABLES` | A [comma-separated list of CI/CD variable names](#forward-cicd-variables-to-the-build-environment) to be forwarded to the build environment (the buildpack builder or `docker build`). |
| `AUTO_DEVOPS_BUILD_IMAGE_CNB_PORT` | In GitLab 15.0 and later, port exposed by the generated Docker image. Set to `false` to prevent exposing any ports. Defaults to `5000`. |
| `AUTO_DEVOPS_CHART` | Helm Chart used to deploy your apps. Defaults to the one [provided by GitLab](https://gitlab.com/gitlab-org/cluster-integration/auto-deploy-image/-/tree/master/assets/auto-deploy-app). |
| `AUTO_DEVOPS_CHART_REPOSITORY` | Helm Chart repository used to search for charts. Defaults to `https://charts.gitlab.io`. |
| `AUTO_DEVOPS_CHART_REPOSITORY_NAME` | Used to set the name of the Helm repository. Defaults to `gitlab`. |

View File

@ -156,6 +156,9 @@ gemnasium-python-dependency_scanning:
bundler-audit-dependency_scanning:
extends: .ds-analyzer
variables:
DS_ANALYZER_NAME: "bundler-audit"
DS_MAJOR_VERSION: 2
script:
- echo "This job was deprecated in GitLab 14.8 and removed in GitLab 15.0"
- echo "For more information see https://gitlab.com/gitlab-org/gitlab/-/issues/347491"
@ -165,6 +168,9 @@ bundler-audit-dependency_scanning:
retire-js-dependency_scanning:
extends: .ds-analyzer
variables:
DS_ANALYZER_NAME: "retire.js"
DS_MAJOR_VERSION: 2
script:
- echo "This job was deprecated in GitLab 14.8 and removed in GitLab 15.0"
- echo "For more information see https://gitlab.com/gitlab-org/gitlab/-/issues/289830"

View File

@ -30,9 +30,23 @@ module Gitlab
scope :created_after, ->(time) { where('created_at > ?', time) }
scope :for_configuration, ->(job_class_name, table_name, column_name, job_arguments) do
where(job_class_name: job_class_name, table_name: table_name, column_name: column_name)
scope :for_configuration, ->(gitlab_schema, job_class_name, table_name, column_name, job_arguments) do
relation = where(job_class_name: job_class_name, table_name: table_name, column_name: column_name)
.where("job_arguments = ?", job_arguments.to_json) # rubocop:disable Rails/WhereEquals
# This method is called from migrations older than the gitlab_schema column,
# check and add this filter only if the column exists.
relation = relation.for_gitlab_schema(gitlab_schema) if gitlab_schema_column_exists?
relation
end
def self.gitlab_schema_column_exists?
column_names.include?('gitlab_schema')
end
scope :for_gitlab_schema, ->(gitlab_schema) do
where(gitlab_schema: gitlab_schema)
end
state_machine :status, initial: :paused do
@ -73,12 +87,13 @@ module Gitlab
state_machine.states.map(&:name)
end
def self.find_for_configuration(job_class_name, table_name, column_name, job_arguments)
for_configuration(job_class_name, table_name, column_name, job_arguments).first
def self.find_for_configuration(gitlab_schema, job_class_name, table_name, column_name, job_arguments)
for_configuration(gitlab_schema, job_class_name, table_name, column_name, job_arguments).first
end
def self.active_migration
executable.queue_order.first
def self.active_migration(connection:)
for_gitlab_schema(Gitlab::Database.gitlab_schemas_for_connection(connection))
.executable.queue_order.first
end
def self.successful_rows_counts(migrations)

View File

@ -54,7 +54,10 @@ module Gitlab
# in order to prevent it being picked up by the background worker. Perform all pending jobs,
# then keep running until migration is finished.
def finalize(job_class_name, table_name, column_name, job_arguments)
migration = BatchedMigration.find_for_configuration(job_class_name, table_name, column_name, job_arguments)
migration = BatchedMigration.find_for_configuration(
Gitlab::Database.gitlab_schemas_for_connection(connection),
job_class_name, table_name, column_name, job_arguments
)
configuration = {
job_class_name: job_class_name,

View File

@ -945,8 +945,13 @@ module Gitlab
end
def ensure_batched_background_migration_is_finished(job_class_name:, table_name:, column_name:, job_arguments:, finalize: true)
migration = Gitlab::Database::BackgroundMigration::BatchedMigration
.for_configuration(job_class_name, table_name, column_name, job_arguments).first
Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas.require_dml_mode!
Gitlab::Database::BackgroundMigration::BatchedMigration.reset_column_information
migration = Gitlab::Database::BackgroundMigration::BatchedMigration.find_for_configuration(
Gitlab::Database.gitlab_schemas_for_connection(connection),
job_class_name, table_name, column_name, job_arguments
)
configuration = {
job_class_name: job_class_name,

View File

@ -67,10 +67,16 @@ module Gitlab
batch_class_name: BATCH_CLASS_NAME,
batch_size: BATCH_SIZE,
max_batch_size: nil,
sub_batch_size: SUB_BATCH_SIZE
sub_batch_size: SUB_BATCH_SIZE,
gitlab_schema: nil
)
Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas.require_dml_mode!
if Gitlab::Database::BackgroundMigration::BatchedMigration.for_configuration(job_class_name, batch_table_name, batch_column_name, job_arguments).exists?
gitlab_schema ||= gitlab_schema_from_context
Gitlab::Database::BackgroundMigration::BatchedMigration.reset_column_information
if Gitlab::Database::BackgroundMigration::BatchedMigration.for_configuration(gitlab_schema, job_class_name, batch_table_name, batch_column_name, job_arguments).exists?
Gitlab::AppLogger.warn "Batched background migration not enqueued because it already exists: " \
"job_class_name: #{job_class_name}, table_name: #{batch_table_name}, column_name: #{batch_column_name}, " \
"job_arguments: #{job_arguments.inspect}"
@ -119,11 +125,17 @@ module Gitlab
end
end
if migration.respond_to?(:gitlab_schema)
migration.gitlab_schema = gitlab_schema
end
migration.save!
migration
end
def finalize_batched_background_migration(job_class_name:, table_name:, column_name:, job_arguments:)
Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas.require_dml_mode!
database_name = Gitlab::Database.db_config_name(connection)
unless ActiveRecord::Base.configurations.primary?(database_name)
@ -132,12 +144,47 @@ module Gitlab
'https://docs.gitlab.com/ee/development/database/migrations_for_multiple_databases.html'
end
migration = Gitlab::Database::BackgroundMigration::BatchedMigration.find_for_configuration(job_class_name, table_name, column_name, job_arguments)
Gitlab::Database::BackgroundMigration::BatchedMigration.reset_column_information
migration = Gitlab::Database::BackgroundMigration::BatchedMigration.find_for_configuration(
gitlab_schema_from_context, job_class_name, table_name, column_name, job_arguments)
raise 'Could not find batched background migration' if migration.nil?
Gitlab::Database::BackgroundMigration::BatchedMigrationRunner.finalize(job_class_name, table_name, column_name, job_arguments, connection: connection)
end
# Deletes batched background migration for the given configuration.
#
# job_class_name - The background migration job class as a string
# table_name - The name of the table the migration iterates over
# column_name - The name of the column the migration will batch over
# job_arguments - Migration arguments
#
# Example:
#
# delete_batched_background_migration(
# 'CopyColumnUsingBackgroundMigrationJob',
# :events,
# :id,
# ['column1', 'column2'])
def delete_batched_background_migration(job_class_name, table_name, column_name, job_arguments)
Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas.require_dml_mode!
Gitlab::Database::BackgroundMigration::BatchedMigration.reset_column_information
Gitlab::Database::BackgroundMigration::BatchedMigration
.for_configuration(
gitlab_schema_from_context, job_class_name, table_name, column_name, job_arguments
).delete_all
end
def gitlab_schema_from_context
if respond_to?(:allowed_gitlab_schemas) # Gitlab::Database::Migration::V2_0
Array(allowed_gitlab_schemas).first
else # Gitlab::Database::Migration::V1_0
:gitlab_main
end
end
end
end
end

View File

@ -1,77 +1,15 @@
# frozen_string_literal: true
# The purpose of this code is to transform legacy `database.yml`
# into a `database.yml` containing `main:` as a name of a first database
#
# This should be removed once all places using legacy `database.yml`
# are fixed. The likely moment to remove this check is the %14.0.
#
# This converts the following syntax:
#
# production:
# adapter: postgresql
# database: gitlabhq_production
# username: git
# password: "secure password"
# host: localhost
#
# Into:
#
# production:
# main:
# adapter: postgresql
# database: gitlabhq_production
# username: git
# password: "secure password"
# host: localhost
#
# The purpose of this code is to set the migrations path
# for the Geo tracking database.
module Gitlab
module Patch
module DatabaseConfig
extend ActiveSupport::Concern
def load_database_yaml
return super unless Gitlab.ee?
super.deep_merge(load_geo_database_yaml)
end
# This method is taken from Rails to load a database YAML file without
# evaluating ERB. This allows us to create the rake tasks for the Geo
# tracking database without filling in the configuration values or
# loading the environment. To be removed when we start configure Geo
# tracking database in database.yml instead of custom database_geo.yml
#
# https://github.com/rails/rails/blob/v6.1.4/railties/lib/rails/application/configuration.rb#L255
def load_geo_database_yaml
path = Rails.root.join("config/database_geo.yml")
return {} unless File.exist?(path)
require "rails/application/dummy_erb_compiler"
yaml = DummyERB.new(Pathname.new(path).read).result
config = YAML.load(yaml) || {} # rubocop:disable Security/YAMLLoad
config.to_h do |env, configs|
# This check is taken from Rails where the transformation
# of a flat database.yml is done into `primary:`
# https://github.com/rails/rails/blob/v6.1.4/activerecord/lib/active_record/database_configurations.rb#L169
if configs.is_a?(Hash) && !configs.all? { |_, v| v.is_a?(Hash) }
configs = { "geo" => configs }
end
[env, configs]
end
end
def database_configuration
super.to_h do |env, configs|
if Gitlab.ee?
if !configs.key?("geo") && File.exist?(Rails.root.join("config/database_geo.yml"))
configs["geo"] = Rails.application.config_for(:database_geo).stringify_keys
end
if configs.key?("geo")
migrations_paths = Array(configs["geo"]["migrations_paths"])
migrations_paths << "ee/db/geo/migrate" if migrations_paths.empty?

View File

@ -36,7 +36,7 @@ unless Rails.env.production?
# expected.
cop_names = args.to_a
todo_dir = RuboCop::TodoDir.new(RuboCop::TodoDir::DEFAULT_TODO_DIR)
todo_dir = RuboCop::TodoDir.new(RuboCop::Formatter::TodoFormatter.base_directory)
if cop_names.any?
# We are sorting the cop names to benefit from RuboCop cache which

View File

@ -9671,6 +9671,9 @@ msgstr ""
msgid "ContainerRegistry|Copy build command"
msgstr ""
msgid "ContainerRegistry|Copy image path"
msgstr ""
msgid "ContainerRegistry|Copy login command"
msgstr ""
@ -16850,6 +16853,9 @@ msgstr ""
msgid "Geo|Shards to synchronize"
msgstr ""
msgid "Geo|Show more"
msgstr ""
msgid "Geo|Site name can't be blank"
msgstr ""
@ -40792,6 +40798,12 @@ msgstr ""
msgid "UsageQuota|This namespace has no projects which use shared runners"
msgstr ""
msgid "UsageQuota|This namespace has no projects which used shared runners in the current period"
msgstr ""
msgid "UsageQuota|This table omits projects that used 0 CI/CD minutes or 0 shared runners duration"
msgstr ""
msgid "UsageQuota|Total excess storage used"
msgstr ""

View File

@ -14,13 +14,6 @@ module RuboCop
# For example, this formatter stores offenses for `RSpec/VariableName`
# in `.rubocop_todo/rspec/variable_name.yml`.
class TodoFormatter < BaseFormatter
# Disable a cop which exceeds this limit. This way we ensure that we
# don't enable a cop by accident when moving it from
# .rubocop_todo.yml to .rubocop_todo/.
# We keep the cop disabled if it has been disabled previously explicitly
# via `Enabled: false` in .rubocop_todo.yml or .rubocop_todo/.
MAX_OFFENSE_COUNT = 15
class Todo
attr_reader :cop_name, :files, :offense_count
@ -41,12 +34,20 @@ module RuboCop
end
end
def initialize(output, options = {})
directory = options.delete(:rubocop_todo_dir) || TodoDir::DEFAULT_TODO_DIR
DEFAULT_BASE_DIRECTORY = File.expand_path('../../.rubocop_todo', __dir__)
class << self
attr_accessor :base_directory
end
self.base_directory = DEFAULT_BASE_DIRECTORY
def initialize(output, _options = {})
@directory = self.class.base_directory
@todos = Hash.new { |hash, cop_name| hash[cop_name] = Todo.new(cop_name) }
@todo_dir = TodoDir.new(directory)
@config_inspect_todo_dir = load_config_inspect_todo_dir(directory)
@config_old_todo_yml = load_config_old_todo_yml(directory)
@config_inspect_todo_dir = load_config_inspect_todo_dir
@config_old_todo_yml = load_config_old_todo_yml
check_multiple_configurations!
super
@ -71,10 +72,21 @@ module RuboCop
end
end
def self.with_base_directory(directory)
old = base_directory
self.base_directory = directory
yield
ensure
self.base_directory = old
end
private
attr_reader :directory
def relative_path(path)
parent = File.expand_path('..', @todo_dir.directory)
parent = File.expand_path('..', directory)
path.delete_prefix("#{parent}/")
end
@ -84,7 +96,7 @@ module RuboCop
yaml << '# Cop supports --auto-correct.' if todo.autocorrectable?
yaml << "#{todo.cop_name}:"
if previously_disabled?(todo) && offense_count_exceeded?(todo)
if previously_disabled?(todo)
yaml << " # Offense count: #{todo.offense_count}"
yaml << ' # Temporarily disabled due to too many offenses'
yaml << ' Enabled: false'
@ -99,10 +111,6 @@ module RuboCop
yaml.join("\n")
end
def offense_count_exceeded?(todo)
todo.offense_count > MAX_OFFENSE_COUNT
end
def check_multiple_configurations!
cop_names = @config_inspect_todo_dir.keys & @config_old_todo_yml.keys
return if cop_names.empty?
@ -121,7 +129,7 @@ module RuboCop
config['Enabled'] == false
end
def load_config_inspect_todo_dir(directory)
def load_config_inspect_todo_dir
@todo_dir.list_inspect.each_with_object({}) do |path, combined|
config = YAML.load_file(path)
combined.update(config) if Hash === config
@ -130,7 +138,7 @@ module RuboCop
# Load YAML configuration from `.rubocop_todo.yml`.
# We consider this file already old, obsolete, and to be removed soon.
def load_config_old_todo_yml(directory)
def load_config_old_todo_yml
path = File.expand_path(File.join(directory, '../.rubocop_todo.yml'))
config = YAML.load_file(path) if File.exist?(path)

View File

@ -6,22 +6,36 @@ require 'active_support/inflector/inflections'
module RuboCop
# Helper class to manage file access to RuboCop TODOs in .rubocop_todo directory.
class TodoDir
DEFAULT_TODO_DIR = File.expand_path('../.rubocop_todo', __dir__)
# Suffix a TODO file.
SUFFIX_YAML = '.yml'
# Suffix to indicate TODOs being inspected right now.
SUFFIX_INSPECT = '.inspect'
attr_reader :directory
# Instantiates a TodoDir.
#
# @param directory [String] base directory where all TODO YAML files are written to.
# @param inflector [ActiveSupport::Inflector, #underscore] an object which supports
# converting a string to its underscored version.
def initialize(directory, inflector: ActiveSupport::Inflector)
@directory = directory
@inflector = inflector
end
def read(cop_name, suffix = nil)
read_suffixed(cop_name)
# Reads content of TODO YAML for given +cop_name+.
#
# @param cop_name [String] name of the cop rule
#
# @return [String, nil] content of the TODO YAML file if it exists
def read(cop_name)
path = path_for(cop_name)
File.read(path) if File.exist?(path)
end
# Saves +content+ for given +cop_name+ to TODO YAML file.
#
# @return [String] path of the written TODO YAML file
def write(cop_name, content)
path = path_for(cop_name)
@ -31,6 +45,10 @@ module RuboCop
path
end
# Marks a TODO YAML file for inspection by renaming the original TODO YAML
# and appending the suffix +.inspect+ to it.
#
# @return [Boolean] +true+ a file was marked for inspection successfully.
def inspect(cop_name)
path = path_for(cop_name)
@ -42,38 +60,47 @@ module RuboCop
end
end
# Marks all TODO YAML files for inspection.
#
# @return [Integer] number of renamed YAML TODO files.
#
# @see inspect
def inspect_all
pattern = File.join(@directory, '**/*.yml')
pattern = File.join(@directory, "**/*#{SUFFIX_YAML}")
Dir.glob(pattern).count do |path|
FileUtils.mv(path, "#{path}#{SUFFIX_INSPECT}")
end
end
# Returns a list of TODO YAML files which are marked for inspection.
#
# @return [Array<String>] list of paths
#
# @see inspect
# @see inspect_all
def list_inspect
pattern = File.join(@directory, "**/*.yml.inspect")
pattern = File.join(@directory, "**/*#{SUFFIX_YAML}#{SUFFIX_INSPECT}")
Dir.glob(pattern)
end
# Deletes a list of TODO yaml files which were marked for inspection.
#
# @return [Integer] number of deleted YAML TODO files.
#
# @see #inspect
# @see #inspect_all
def delete_inspected
pattern = File.join(@directory, '**/*.yml.inspect')
Dir.glob(pattern).count do |path|
list_inspect.count do |path|
File.delete(path)
end
end
private
def read_suffixed(cop_name, suffix = nil)
path = path_for(cop_name, suffix)
File.read(path) if File.exist?(path)
end
def path_for(cop_name, suffix = nil)
todo_path = "#{@inflector.underscore(cop_name)}.yml#{suffix}"
def path_for(cop_name)
todo_path = "#{@inflector.underscore(cop_name)}#{SUFFIX_YAML}"
File.join(@directory, todo_path)
end

View File

@ -12,13 +12,35 @@ module Glfm
def process
output('Updating specification...')
ghfm_spec_txt_lines = download_and_write_ghfm_spec_txt
ghfm_spec_txt_lines = load_ghfm_spec_txt
glfm_spec_txt_string = build_glfm_spec_txt(ghfm_spec_txt_lines)
write_glfm_spec_txt(glfm_spec_txt_string)
end
private
def load_ghfm_spec_txt
# We only re-download the GitHub Flavored Markdown specification if the
# UPDATE_GHFM_SPEC_TXT environment variable is set to true, which should only
# ever be done manually and locally, never in CI. This provides some security
# protection against a possible injection attack vector, if the GitHub-hosted
# version of the spec is ever temporarily compromised with an injection attack.
#
# This also avoids doing external network access to download the file
# in CI jobs, which can avoid potentially flaky builds if the GitHub-hosted
# version of the file is temporarily unavailable.
if ENV['UPDATE_GHFM_SPEC_TXT'] == 'true'
download_and_write_ghfm_spec_txt
else
read_existing_ghfm_spec_txt
end
end
def read_existing_ghfm_spec_txt
output("Reading existing #{GHFM_SPEC_TXT_PATH}...")
File.open(GHFM_SPEC_TXT_PATH).readlines
end
def download_and_write_ghfm_spec_txt
output("Downloading #{GHFM_SPEC_TXT_URI}...")
ghfm_spec_txt_uri_io = URI.open(GHFM_SPEC_TXT_URI)

View File

@ -17,8 +17,11 @@ else
cp config/database.yml.postgresql config/database.yml
fi
if [ -f config/database_geo.yml.postgresql ]; then
cp config/database_geo.yml.postgresql config/database_geo.yml
# Remove Geo database setting if `ee/` directory does not exist. When it does
# not exist, it runs the GitLab test suite "as if FOSS", meaning the jobs run
# in the context of gitlab-org/gitlab-foss where the Geo is not available.
if [ ! -d "ee/" ] ; then
sed -i '/geo:/,/^$/d' config/database.yml
fi
# Set user to a non-superuser to ensure we test permissions
@ -27,11 +30,6 @@ sed -i 's/username: root/username: gitlab/g' config/database.yml
sed -i 's/localhost/postgres/g' config/database.yml
sed -i 's/username: git/username: postgres/g' config/database.yml
if [ -f config/database_geo.yml ]; then
sed -i 's/localhost/postgres/g' config/database_geo.yml
sed -i 's/username: git/username: postgres/g' config/database_geo.yml
fi
cp config/cable.yml.example config/cable.yml
sed -i 's|url:.*$|url: redis://redis:6379|g' config/cable.yml

View File

@ -94,7 +94,10 @@ RSpec.describe 'Database schema' do
vulnerability_identifiers: %w[external_id],
vulnerability_scanners: %w[external_id],
security_scans: %w[pipeline_id], # foreign key is not added as ci_pipeline table will be moved into different db soon
vulnerability_reads: %w[cluster_agent_id]
vulnerability_reads: %w[cluster_agent_id],
# See: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87584
# Fixes performance issues with the deletion of web-hooks with many log entries
web_hook_logs: %w[web_hook_id]
}.with_indifferent_access.freeze
context 'for table' do

View File

@ -95,10 +95,6 @@ FactoryBot.define do
severity { 'unknown' }
end
trait :threat_monitoring do
domain { :threat_monitoring }
end
trait :prometheus do
monitoring_tool { Gitlab::AlertManagement::Payload::MONITORING_TOOLS[:prometheus] }
payload do

View File

@ -12,6 +12,7 @@ FactoryBot.define do
sequence(:job_arguments) { |n| [["column_#{n}"], ["column_#{n}_convert_to_bigint"]] }
total_tuple_count { 10_000 }
pause_ms { 100 }
gitlab_schema { :gitlab_main }
trait(:paused) do
status { 0 }

View File

@ -12,8 +12,6 @@ RSpec.describe 'Pipeline Editor', :js do
let(:other_branch) { 'test' }
before do
stub_feature_flags(pipeline_editor_file_tree: false)
sign_in(user)
project.add_developer(user)
@ -70,14 +68,8 @@ RSpec.describe 'Pipeline Editor', :js do
expect(page).to have_content('Pipeline Editor')
end
describe 'Branch Switcher (pipeline_editor_file_tree disabled)' do
it_behaves_like 'default branch switcher behavior'
end
describe 'Branch Switcher (pipeline_editor_file_tree enabled)' do
describe 'Branch Switcher' do
before do
stub_feature_flags(pipeline_editor_file_tree: true)
visit project_ci_pipeline_editor_path(project)
wait_for_requests

View File

@ -30,10 +30,12 @@ RSpec.describe 'User edits Release', :js do
it 'renders the breadcrumbs' do
within('.breadcrumbs') do
expect(page).to have_content("#{project.creator.name} #{project.name} Edit Release")
expect(page).to have_content("#{project.creator.name} #{project.name} Releases #{release.name} Edit Release")
expect(page).to have_link(project.creator.name, href: user_path(project.creator))
expect(page).to have_link(project.name, href: project_path(project))
expect(page).to have_link(_('Releases'), href: project_releases_path(project))
expect(page).to have_link(release.name, href: project_release_path(project, release))
expect(page).to have_link('Edit Release', href: edit_project_release_path(project, release))
end
end

View File

@ -38,6 +38,7 @@ const ajv = new Ajv({
strictTuples: false,
allowMatchingProperties: true,
});
ajv.addKeyword('markdownDescription');
AjvFormats(ajv);
const schema = ajv.compile(CiSchema);

View File

@ -301,17 +301,23 @@ describe('CE IssuesListApp component', () => {
describe('initial url params', () => {
describe('page', () => {
it('page_after is set from the url params', () => {
setWindowLocation('?page_after=randomCursorString');
setWindowLocation('?page_after=randomCursorString&first_page_size=20');
wrapper = mountComponent();
expect(wrapper.vm.$route.query).toMatchObject({ page_after: 'randomCursorString' });
expect(wrapper.vm.$route.query).toMatchObject({
page_after: 'randomCursorString',
first_page_size: '20',
});
});
it('page_before is set from the url params', () => {
setWindowLocation('?page_before=anotherRandomCursorString');
setWindowLocation('?page_before=anotherRandomCursorString&last_page_size=20');
wrapper = mountComponent();
expect(wrapper.vm.$route.query).toMatchObject({ page_before: 'anotherRandomCursorString' });
expect(wrapper.vm.$route.query).toMatchObject({
page_before: 'anotherRandomCursorString',
last_page_size: '20',
});
});
});
@ -675,10 +681,10 @@ describe('CE IssuesListApp component', () => {
});
describe.each`
event | paramName | paramValue
${'next-page'} | ${'page_after'} | ${'endCursor'}
${'previous-page'} | ${'page_before'} | ${'startCursor'}
`('when "$event" event is emitted by IssuableList', ({ event, paramName, paramValue }) => {
event | params
${'next-page'} | ${{ page_after: 'endCursor', page_before: undefined, first_page_size: 20, last_page_size: undefined }}
${'previous-page'} | ${{ page_after: undefined, page_before: 'startCursor', first_page_size: undefined, last_page_size: 20 }}
`('when "$event" event is emitted by IssuableList', ({ event, params }) => {
beforeEach(() => {
wrapper = mountComponent({
data: {
@ -697,9 +703,9 @@ describe('CE IssuesListApp component', () => {
expect(scrollUp).toHaveBeenCalled();
});
it(`updates url with "${paramName}" param`, () => {
it(`updates url`, () => {
expect(wrapper.vm.$router.push).toHaveBeenCalledWith({
query: expect.objectContaining({ [paramName]: paramValue }),
query: expect.objectContaining(params),
});
});
});

Some files were not shown because too many files have changed in this diff Show More