diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-21 09:14:14 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-21 09:14:14 +0000 |
commit | 3442b76bbd896c85c06feaa56e3d9355a3945523 (patch) | |
tree | f0cf69066925ef31213ced0c4dae71a62e5cbe2c | |
parent | d1f4ef3cb7ff63c92dc17589a05848938251c7f1 (diff) | |
download | gitlab-ce-3442b76bbd896c85c06feaa56e3d9355a3945523.tar.gz |
Add latest changes from gitlab-org/gitlab@master
16 files changed, 231 insertions, 31 deletions
diff --git a/app/assets/javascripts/ide/components/jobs/stage.vue b/app/assets/javascripts/ide/components/jobs/stage.vue index 938385f0b81..796ca1349c5 100644 --- a/app/assets/javascripts/ide/components/jobs/stage.vue +++ b/app/assets/javascripts/ide/components/jobs/stage.vue @@ -1,5 +1,5 @@ <script> -import { GlLoadingIcon, GlIcon, GlTooltipDirective } from '@gitlab/ui'; +import { GlLoadingIcon, GlIcon, GlTooltipDirective, GlBadge } from '@gitlab/ui'; import CiIcon from '../../../vue_shared/components/ci_icon.vue'; import Item from './item.vue'; @@ -9,6 +9,7 @@ export default { }, components: { GlIcon, + GlBadge, CiIcon, Item, GlLoadingIcon, @@ -74,7 +75,7 @@ export default { {{ stage.name }} </strong> <div v-if="!stage.isLoading || stage.jobs.length" class="gl-mr-3 gl-ml-2"> - <span class="badge badge-pill"> {{ jobsCount }} </span> + <gl-badge>{{ jobsCount }}</gl-badge> </div> <gl-icon :name="collapseIcon" class="ide-stage-collapse-icon" /> </div> diff --git a/app/assets/javascripts/pipelines/components/parsing_utils.js b/app/assets/javascripts/pipelines/components/parsing_utils.js index fa7330ce890..cae4e11c13f 100644 --- a/app/assets/javascripts/pipelines/components/parsing_utils.js +++ b/app/assets/javascripts/pipelines/components/parsing_utils.js @@ -1,5 +1,6 @@ import { memoize } from 'lodash'; import { createNodeDict } from '../utils'; +import { EXPLICIT_NEEDS_PROPERTY, NEEDS_PROPERTY } from '../constants'; import { createSankey } from './dag/drawing_utils'; /* @@ -15,12 +16,14 @@ const deduplicate = (item, itemIndex, arr) => { return foundIdx === itemIndex; }; -export const makeLinksFromNodes = (nodes, nodeDict) => { +export const makeLinksFromNodes = (nodes, nodeDict, { needsKey = NEEDS_PROPERTY } = {}) => { const constantLinkValue = 10; // all links are the same weight return nodes .map(({ jobs, name: groupName }) => - jobs.map(({ needs = [] }) => - needs.reduce((acc, needed) => { + jobs.map((job) => { + const needs = job[needsKey] || []; + + return needs.reduce((acc, needed) => { // It's possible that we have an optional job, which // is being needed by another job. In that scenario, // the needed job doesn't exist, so we don't want to @@ -34,8 +37,8 @@ export const makeLinksFromNodes = (nodes, nodeDict) => { } return acc; - }, []), - ), + }, []); + }), ) .flat(2); }; @@ -76,9 +79,9 @@ export const filterByAncestors = (links, nodeDict) => return !allAncestors.includes(source); }); -export const parseData = (nodes) => { - const nodeDict = createNodeDict(nodes); - const allLinks = makeLinksFromNodes(nodes, nodeDict); +export const parseData = (nodes, { needsKey = NEEDS_PROPERTY } = {}) => { + const nodeDict = createNodeDict(nodes, { needsKey }); + const allLinks = makeLinksFromNodes(nodes, nodeDict, { needsKey }); const filteredLinks = allLinks.filter(deduplicate); const links = filterByAncestors(filteredLinks, nodeDict); @@ -123,7 +126,8 @@ export const removeOrphanNodes = (sankeyfiedNodes) => { export const listByLayers = ({ stages }) => { const arrayOfJobs = stages.flatMap(({ groups }) => groups); const parsedData = parseData(arrayOfJobs); - const dataWithLayers = createSankey()(parsedData); + const explicitParsedData = parseData(arrayOfJobs, { needsKey: EXPLICIT_NEEDS_PROPERTY }); + const dataWithLayers = createSankey()(explicitParsedData); const pipelineLayers = dataWithLayers.nodes.reduce((acc, { layer, name }) => { /* sort groups by layer */ diff --git a/app/assets/javascripts/pipelines/components/unwrapping_utils.js b/app/assets/javascripts/pipelines/components/unwrapping_utils.js index 2d24beb8323..d42a11c3aba 100644 --- a/app/assets/javascripts/pipelines/components/unwrapping_utils.js +++ b/app/assets/javascripts/pipelines/components/unwrapping_utils.js @@ -1,4 +1,5 @@ import { reportToSentry } from '../utils'; +import { EXPLICIT_NEEDS_PROPERTY, NEEDS_PROPERTY } from '../constants'; const unwrapGroups = (stages) => { return stages.map((stage, idx) => { @@ -27,12 +28,16 @@ const unwrapNodesWithName = (jobArray, prop, field = 'name') => { } return jobArray.map((job) => { - return { ...job, [prop]: job[prop].nodes.map((item) => item[field] || '') }; + if (job[prop]) { + return { ...job, [prop]: job[prop].nodes.map((item) => item[field] || '') }; + } + return job; }); }; const unwrapJobWithNeeds = (denodedJobArray) => { - return unwrapNodesWithName(denodedJobArray, 'needs'); + const explicitNeedsUnwrapped = unwrapNodesWithName(denodedJobArray, EXPLICIT_NEEDS_PROPERTY); + return unwrapNodesWithName(explicitNeedsUnwrapped, NEEDS_PROPERTY); }; const unwrapStagesWithNeedsAndLookup = (denodedStages) => { diff --git a/app/assets/javascripts/pipelines/constants.js b/app/assets/javascripts/pipelines/constants.js index d123f7a203c..410fc7b82cd 100644 --- a/app/assets/javascripts/pipelines/constants.js +++ b/app/assets/javascripts/pipelines/constants.js @@ -7,6 +7,8 @@ export const ANY_TRIGGER_AUTHOR = 'Any'; export const SUPPORTED_FILTER_PARAMETERS = ['username', 'ref', 'status', 'source']; export const FILTER_TAG_IDENTIFIER = 'tag'; export const SCHEDULE_ORIGIN = 'schedule'; +export const NEEDS_PROPERTY = 'needs'; +export const EXPLICIT_NEEDS_PROPERTY = 'previousStageJobsOrNeeds'; export const TestStatus = { FAILED: 'failed', diff --git a/app/assets/javascripts/pipelines/graphql/fragmentTypes.json b/app/assets/javascripts/pipelines/graphql/fragmentTypes.json new file mode 100644 index 00000000000..4601b74b5c1 --- /dev/null +++ b/app/assets/javascripts/pipelines/graphql/fragmentTypes.json @@ -0,0 +1 @@ +{"__schema":{"types":[{"kind":"UNION","name":"JobNeedUnion","possibleTypes":[{"name":"CiBuildNeed"},{"name":"CiJob"}]}]}}
\ No newline at end of file diff --git a/app/assets/javascripts/pipelines/pipeline_shared_client.js b/app/assets/javascripts/pipelines/pipeline_shared_client.js index c3be487caae..84276588d6a 100644 --- a/app/assets/javascripts/pipelines/pipeline_shared_client.js +++ b/app/assets/javascripts/pipelines/pipeline_shared_client.js @@ -1,10 +1,19 @@ import VueApollo from 'vue-apollo'; +import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory'; import createDefaultClient from '~/lib/graphql'; +import introspectionQueryResultData from './graphql/fragmentTypes.json'; + +export const fragmentMatcher = new IntrospectionFragmentMatcher({ + introspectionQueryResultData, +}); export const apolloProvider = new VueApollo({ defaultClient: createDefaultClient( {}, { + cacheConfig: { + fragmentMatcher, + }, useGet: true, }, ), diff --git a/app/assets/javascripts/pipelines/utils.js b/app/assets/javascripts/pipelines/utils.js index e28eb74fb1b..f6e1c8b7412 100644 --- a/app/assets/javascripts/pipelines/utils.js +++ b/app/assets/javascripts/pipelines/utils.js @@ -1,6 +1,6 @@ import * as Sentry from '@sentry/browser'; import { pickBy } from 'lodash'; -import { SUPPORTED_FILTER_PARAMETERS } from './constants'; +import { SUPPORTED_FILTER_PARAMETERS, NEEDS_PROPERTY } from './constants'; /* The following functions are the main engine in transforming the data as @@ -35,11 +35,11 @@ import { SUPPORTED_FILTER_PARAMETERS } from './constants'; 10 -> value (constant) */ -export const createNodeDict = (nodes) => { +export const createNodeDict = (nodes, { needsKey = NEEDS_PROPERTY } = {}) => { return nodes.reduce((acc, node) => { const newNode = { ...node, - needs: node.jobs.map((job) => job.needs || []).flat(), + needs: node.jobs.map((job) => job[needsKey] || []).flat(), }; if (node.size > 1) { diff --git a/app/graphql/queries/pipelines/get_pipeline_details.query.graphql b/app/graphql/queries/pipelines/get_pipeline_details.query.graphql index dd5c9e07488..5dece2f81cc 100644 --- a/app/graphql/queries/pipelines/get_pipeline_details.query.graphql +++ b/app/graphql/queries/pipelines/get_pipeline_details.query.graphql @@ -1,3 +1,18 @@ +fragment CiNeeds on JobNeedUnion { + ...CiBuildNeedFields + ...CiJobNeedFields +} + +fragment CiBuildNeedFields on CiBuildNeed { + id + name +} + +fragment CiJobNeedFields on CiJob { + id + name +} + fragment LinkedPipelineData on Pipeline { __typename id @@ -91,6 +106,12 @@ query getPipelineDetails($projectPath: ID!, $iid: ID!) { name } } + previousStageJobsOrNeeds { + __typename + nodes { + ...CiNeeds + } + } status: detailedStatus { __typename id diff --git a/app/views/admin/groups/_group.html.haml b/app/views/admin/groups/_group.html.haml index bbc65850794..0c2280a2f63 100644 --- a/app/views/admin/groups/_group.html.haml +++ b/app/views/admin/groups/_group.html.haml @@ -15,8 +15,7 @@ = markdown_field(group, :description) .stats.gl-text-gray-500.gl-flex-shrink-0.gl-display-none.gl-sm-display-flex - %span.badge.badge-muted.badge-pill.gl-badge.sm - = storage_counter(group.storage_size) + = gl_badge_tag storage_counter(group.storage_size), size: :sm = render_if_exists 'admin/namespace_plan_badge', namespace: group, css_class: 'gl-ml-5 gl-mr-0' = render_if_exists 'admin/groups/marked_for_deletion_badge', group: group, css_class: 'gl-ml-5' diff --git a/doc/administration/auth/ldap/index.md b/doc/administration/auth/ldap/index.md index f551c362784..32f0da100a3 100644 --- a/doc/administration/auth/ldap/index.md +++ b/doc/administration/auth/ldap/index.md @@ -21,7 +21,7 @@ This integration works with most LDAP-compliant directory servers, including: Users added through LDAP: -- Take a [licensed seat](../../../subscriptions/self_managed/index.md#billable-users). +- Usually use a [licensed seat](../../../subscriptions/self_managed/index.md#billable-users). - Can authenticate with Git using either their GitLab username or their email and LDAP password, even if password authentication for Git [is disabled](../../../user/admin_area/settings/sign_in_restrictions.md#password-authentication-enabled). diff --git a/doc/administration/instance_limits.md b/doc/administration/instance_limits.md index bfe59d5277b..ae5e5303047 100644 --- a/doc/administration/instance_limits.md +++ b/doc/administration/instance_limits.md @@ -640,7 +640,7 @@ To set this limit to `100` on a self-managed instance, run the following command [GitLab Rails console](operations/rails_console.md#starting-a-rails-console-session): ```ruby -Plan.default.actual_limits.update!(dotenv_variable_limit: 100) +Plan.default.actual_limits.update!(dotenv_variables: 100) ``` This limit is [enabled on GitLab.com](../user/gitlab_com/index.md#gitlab-cicd). @@ -658,7 +658,7 @@ To set this limit to 5KB on a self-managed installation, run the following in th [GitLab Rails console](operations/rails_console.md#starting-a-rails-console-session): ```ruby -Plan.default.actual_limits.update!(dotenv_size_limit: 5.kilobytes) +Plan.default.actual_limits.update!(dotenv_size: 5.kilobytes) ``` ## Instance monitoring and metrics diff --git a/doc/ci/pipelines/cicd_minutes.md b/doc/ci/pipelines/cicd_minutes.md index 423119880de..2e9aca572c3 100644 --- a/doc/ci/pipelines/cicd_minutes.md +++ b/doc/ci/pipelines/cicd_minutes.md @@ -103,7 +103,7 @@ These additional CI/CD minutes: - Are used only after the monthly quota included in your subscription runs out. - Are carried over to the next month, if any remain at the end of the month. -- Don't expire unless used up. +- Don't expire. If you use more CI/CD minutes than your monthly quota, when you purchase more, those CI/CD minutes are deducted from your quota. For example, with a GitLab SaaS @@ -166,10 +166,13 @@ Job duration * Cost factor The number is transformed into minutes and added to the overall quota in the job's top-level namespace. -For example: a user `alice` runs a pipeline under `gitlab-org` namespace. The CI/CD minutes consumed by each job -in the pipeline are added to the overall consumption for `gitlab-org` namespace, not `alice` namespace. -If a pipeline runs for one of `alice`'s personal project, the CI/CD minutes are added to the overall consumption -for `alice` namespace. +For example: + +- A user, `alice`, runs a pipeline under the `gitlab-org` namespace. +- The CI/CD minutes consumed by each job in the pipeline are added to the + overall consumption for the `gitlab-org` namespace, not the `alice` namespace. +- If a pipeline runs for one of the personal projects for `alice`, the CI/CD minutes + are added to the overall consumption for the `alice` namespace. ### Cost factor diff --git a/doc/user/project/issues/managing_issues.md b/doc/user/project/issues/managing_issues.md index 1a23902514a..ffb8269cd16 100644 --- a/doc/user/project/issues/managing_issues.md +++ b/doc/user/project/issues/managing_issues.md @@ -22,7 +22,7 @@ You can create an issue in many ways in GitLab: - [From another issue](#from-another-issue) - [From an issue board](#from-an-issue-board) - [By sending an email](#by-sending-an-email) -- Using a URL with prefilled fields +- [Using a URL with prefilled values](#using-a-url-with-prefilled-values) - [Using Service Desk](#using-service-desk) ### From a project diff --git a/spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap b/spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap index faa70982fac..d1cf9f2e248 100644 --- a/spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap +++ b/spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap @@ -25,11 +25,12 @@ exports[`IDE pipeline stage renders stage details & icon 1`] = ` <div class="gl-mr-3 gl-ml-2" > - <span - class="badge badge-pill" + <gl-badge-stub + size="md" + variant="muted" > - 4 - </span> + 4 + </gl-badge-stub> </div> <gl-icon-stub diff --git a/spec/frontend/pipelines/__snapshots__/utils_spec.js.snap b/spec/frontend/pipelines/__snapshots__/utils_spec.js.snap index 99de0d2a3ef..52461885342 100644 --- a/spec/frontend/pipelines/__snapshots__/utils_spec.js.snap +++ b/spec/frontend/pipelines/__snapshots__/utils_spec.js.snap @@ -13,6 +13,7 @@ Array [ "id": "6", "name": "build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl", "needs": Array [], + "previousStageJobsOrNeeds": Array [], "scheduledAt": null, "status": Object { "__typename": "DetailedStatus", @@ -53,6 +54,7 @@ Array [ "id": "11", "name": "build_b", "needs": Array [], + "previousStageJobsOrNeeds": Array [], "scheduledAt": null, "status": Object { "__typename": "DetailedStatus", @@ -93,6 +95,7 @@ Array [ "id": "16", "name": "build_c", "needs": Array [], + "previousStageJobsOrNeeds": Array [], "scheduledAt": null, "status": Object { "__typename": "DetailedStatus", @@ -133,6 +136,7 @@ Array [ "id": "21", "name": "build_d 1/3", "needs": Array [], + "previousStageJobsOrNeeds": Array [], "scheduledAt": null, "status": Object { "__typename": "DetailedStatus", @@ -157,6 +161,7 @@ Array [ "id": "24", "name": "build_d 2/3", "needs": Array [], + "previousStageJobsOrNeeds": Array [], "scheduledAt": null, "status": Object { "__typename": "DetailedStatus", @@ -181,6 +186,7 @@ Array [ "id": "27", "name": "build_d 3/3", "needs": Array [], + "previousStageJobsOrNeeds": Array [], "scheduledAt": null, "status": Object { "__typename": "DetailedStatus", @@ -221,6 +227,7 @@ Array [ "id": "59", "name": "test_c", "needs": Array [], + "previousStageJobsOrNeeds": Array [], "scheduledAt": null, "status": Object { "__typename": "DetailedStatus", @@ -267,6 +274,11 @@ Array [ "build_b", "build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl", ], + "previousStageJobsOrNeeds": Array [ + "build_c", + "build_b", + "build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl", + ], "scheduledAt": null, "status": Object { "__typename": "DetailedStatus", @@ -313,6 +325,13 @@ Array [ "build_b", "build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl", ], + "previousStageJobsOrNeeds": Array [ + "build_d 3/3", + "build_d 2/3", + "build_d 1/3", + "build_b", + "build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl", + ], "scheduledAt": null, "status": Object { "__typename": "DetailedStatus", @@ -343,6 +362,13 @@ Array [ "build_b", "build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl", ], + "previousStageJobsOrNeeds": Array [ + "build_d 3/3", + "build_d 2/3", + "build_d 1/3", + "build_b", + "build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl", + ], "scheduledAt": null, "status": Object { "__typename": "DetailedStatus", @@ -385,6 +411,9 @@ Array [ "needs": Array [ "build_b", ], + "previousStageJobsOrNeeds": Array [ + "build_b", + ], "scheduledAt": null, "status": Object { "__typename": "DetailedStatus", diff --git a/spec/frontend/pipelines/graph/mock_data.js b/spec/frontend/pipelines/graph/mock_data.js index dcbbde7bf36..41823bfdb9f 100644 --- a/spec/frontend/pipelines/graph/mock_data.js +++ b/spec/frontend/pipelines/graph/mock_data.js @@ -73,6 +73,10 @@ export const mockPipelineResponse = { __typename: 'CiBuildNeedConnection', nodes: [], }, + previousStageJobsOrNeeds: { + __typename: 'CiJobConnection', + nodes: [], + }, }, ], }, @@ -118,6 +122,10 @@ export const mockPipelineResponse = { __typename: 'CiBuildNeedConnection', nodes: [], }, + previousStageJobsOrNeeds: { + __typename: 'CiJobConnection', + nodes: [], + }, }, ], }, @@ -163,6 +171,10 @@ export const mockPipelineResponse = { __typename: 'CiBuildNeedConnection', nodes: [], }, + previousStageJobsOrNeeds: { + __typename: 'CiJobConnection', + nodes: [], + }, }, ], }, @@ -208,6 +220,10 @@ export const mockPipelineResponse = { __typename: 'CiBuildNeedConnection', nodes: [], }, + previousStageJobsOrNeeds: { + __typename: 'CiJobConnection', + nodes: [], + }, }, { __typename: 'CiJob', @@ -235,6 +251,10 @@ export const mockPipelineResponse = { __typename: 'CiBuildNeedConnection', nodes: [], }, + previousStageJobsOrNeeds: { + __typename: 'CiJobConnection', + nodes: [], + }, }, { __typename: 'CiJob', @@ -262,6 +282,10 @@ export const mockPipelineResponse = { __typename: 'CiBuildNeedConnection', nodes: [], }, + previousStageJobsOrNeeds: { + __typename: 'CiJobConnection', + nodes: [], + }, }, ], }, @@ -339,6 +363,27 @@ export const mockPipelineResponse = { }, ], }, + previousStageJobsOrNeeds: { + __typename: 'CiJobConnection', + nodes: [ + { + __typename: 'CiBuildNeed', + id: '37', + name: 'build_c', + }, + { + __typename: 'CiBuildNeed', + id: '38', + name: 'build_b', + }, + { + __typename: 'CiBuildNeed', + id: '39', + name: + 'build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl', + }, + ], + }, }, ], }, @@ -411,6 +456,37 @@ export const mockPipelineResponse = { }, ], }, + previousStageJobsOrNeeds: { + __typename: 'CiJobConnection', + nodes: [ + { + __typename: 'CiBuildNeed', + id: '45', + name: 'build_d 3/3', + }, + { + __typename: 'CiBuildNeed', + id: '46', + name: 'build_d 2/3', + }, + { + __typename: 'CiBuildNeed', + id: '47', + name: 'build_d 1/3', + }, + { + __typename: 'CiBuildNeed', + id: '48', + name: 'build_b', + }, + { + __typename: 'CiBuildNeed', + id: '49', + name: + 'build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl', + }, + ], + }, }, { __typename: 'CiJob', @@ -465,6 +541,37 @@ export const mockPipelineResponse = { }, ], }, + previousStageJobsOrNeeds: { + __typename: 'CiJobConnection', + nodes: [ + { + __typename: 'CiBuildNeed', + id: '52', + name: 'build_d 3/3', + }, + { + __typename: 'CiBuildNeed', + id: '53', + name: 'build_d 2/3', + }, + { + __typename: 'CiBuildNeed', + id: '54', + name: 'build_d 1/3', + }, + { + __typename: 'CiBuildNeed', + id: '55', + name: 'build_b', + }, + { + __typename: 'CiBuildNeed', + id: '56', + name: + 'build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl', + }, + ], + }, }, ], }, @@ -503,6 +610,10 @@ export const mockPipelineResponse = { __typename: 'CiBuildNeedConnection', nodes: [], }, + previousStageJobsOrNeeds: { + __typename: 'CiJobConnection', + nodes: [], + }, }, ], }, @@ -547,6 +658,16 @@ export const mockPipelineResponse = { }, ], }, + previousStageJobsOrNeeds: { + __typename: 'CiJobConnection', + nodes: [ + { + __typename: 'CiBuildNeed', + id: '65', + name: 'build_b', + }, + ], + }, }, ], }, @@ -720,6 +841,10 @@ export const wrappedPipelineReturn = { __typename: 'CiBuildNeedConnection', nodes: [], }, + previousStageJobsOrNeeds: { + __typename: 'CiJobConnection', + nodes: [], + }, status: { __typename: 'DetailedStatus', id: '84', |