Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-11-27 15:09:14 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-11-27 15:09:14 +0300
commit95ff19a65c5236863e4c7c7e198bfc1e2fa70f07 (patch)
treee543a0b23941611b93a7d435b7644eafcdd8cbeb /app/assets/javascripts/pipeline_editor
parent2df573afed782aebce8c020d92b42e9da7d2868e (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/pipeline_editor')
-rw-r--r--app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results.vue143
-rw-r--r--app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results_param.vue26
-rw-r--r--app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results_value.vue81
-rw-r--r--app/assets/javascripts/pipeline_editor/components/lint/ci_lint_warnings.vue69
-rw-r--r--app/assets/javascripts/pipeline_editor/graphql/mutations/lint_ci.mutation.graphql22
-rw-r--r--app/assets/javascripts/pipeline_editor/graphql/resolvers.js31
-rw-r--r--app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue2
7 files changed, 371 insertions, 3 deletions
diff --git a/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results.vue b/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results.vue
new file mode 100644
index 00000000000..0d1c214c5b1
--- /dev/null
+++ b/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results.vue
@@ -0,0 +1,143 @@
+<script>
+import { GlAlert, GlLink, GlSprintf, GlTable } from '@gitlab/ui';
+import CiLintWarnings from './ci_lint_warnings.vue';
+import CiLintResultsValue from './ci_lint_results_value.vue';
+import CiLintResultsParam from './ci_lint_results_param.vue';
+import { __ } from '~/locale';
+
+const thBorderColor = 'gl-border-gray-100!';
+
+export default {
+ correct: {
+ variant: 'success',
+ text: __('syntax is correct.'),
+ },
+ incorrect: {
+ variant: 'danger',
+ text: __('syntax is incorrect.'),
+ },
+ includesText: __(
+ 'CI configuration validated, including all configuration added with the %{codeStart}includes%{codeEnd} keyword. %{link}',
+ ),
+ warningTitle: __('The form contains the following warning:'),
+ fields: [
+ {
+ key: 'parameter',
+ label: __('Parameter'),
+ thClass: thBorderColor,
+ },
+ {
+ key: 'value',
+ label: __('Value'),
+ thClass: thBorderColor,
+ },
+ ],
+ components: {
+ GlAlert,
+ GlLink,
+ GlSprintf,
+ GlTable,
+ CiLintWarnings,
+ CiLintResultsValue,
+ CiLintResultsParam,
+ },
+ props: {
+ valid: {
+ type: Boolean,
+ required: true,
+ },
+ jobs: {
+ type: Array,
+ required: true,
+ },
+ errors: {
+ type: Array,
+ required: true,
+ },
+ warnings: {
+ type: Array,
+ required: true,
+ },
+ dryRun: {
+ type: Boolean,
+ required: true,
+ },
+ lintHelpPagePath: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ isWarningDismissed: false,
+ };
+ },
+ computed: {
+ status() {
+ return this.valid ? this.$options.correct : this.$options.incorrect;
+ },
+ shouldShowTable() {
+ return this.errors.length === 0;
+ },
+ shouldShowError() {
+ return this.errors.length > 0;
+ },
+ shouldShowWarning() {
+ return this.warnings.length > 0 && !this.isWarningDismissed;
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <gl-alert
+ class="gl-mb-5"
+ :variant="status.variant"
+ :title="__('Status:')"
+ :dismissible="false"
+ data-testid="ci-lint-status"
+ >{{ status.text }}
+ <gl-sprintf :message="$options.includesText">
+ <template #code="{content}">
+ <code>
+ {{ content }}
+ </code>
+ </template>
+ <template #link>
+ <gl-link :href="lintHelpPagePath" target="_blank">
+ {{ __('More information') }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </gl-alert>
+
+ <pre
+ v-if="shouldShowError"
+ class="gl-mb-5"
+ data-testid="ci-lint-errors"
+ ><div v-for="error in errors" :key="error">{{ error }}</div></pre>
+
+ <ci-lint-warnings
+ v-if="shouldShowWarning"
+ :warnings="warnings"
+ data-testid="ci-lint-warnings"
+ @dismiss="isWarningDismissed = true"
+ />
+
+ <gl-table
+ v-if="shouldShowTable"
+ :items="jobs"
+ :fields="$options.fields"
+ bordered
+ data-testid="ci-lint-table"
+ >
+ <template #cell(parameter)="{ item }">
+ <ci-lint-results-param :stage="item.stage" :job-name="item.name" />
+ </template>
+ <template #cell(value)="{ item }">
+ <ci-lint-results-value :item="item" :dry-run="dryRun" />
+ </template>
+ </gl-table>
+ </div>
+</template>
diff --git a/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results_param.vue b/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results_param.vue
new file mode 100644
index 00000000000..23808bcb292
--- /dev/null
+++ b/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results_param.vue
@@ -0,0 +1,26 @@
+<script>
+import { __ } from '~/locale';
+import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
+
+export default {
+ props: {
+ stage: {
+ type: String,
+ required: true,
+ },
+ jobName: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ formatParameter() {
+ return __(`${capitalizeFirstCharacter(this.stage)} Job - ${this.jobName}`);
+ },
+ },
+};
+</script>
+
+<template>
+ <span data-testid="ci-lint-parameter">{{ formatParameter }}</span>
+</template>
diff --git a/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results_value.vue b/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results_value.vue
new file mode 100644
index 00000000000..4929c3206df
--- /dev/null
+++ b/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results_value.vue
@@ -0,0 +1,81 @@
+<script>
+import { isEmpty } from 'lodash';
+
+export default {
+ props: {
+ item: {
+ type: Object,
+ required: true,
+ },
+ dryRun: {
+ type: Boolean,
+ required: true,
+ },
+ },
+ computed: {
+ tagList() {
+ return this.item.tagList.join(', ');
+ },
+ onlyPolicy() {
+ return this.item.only ? this.item.only.refs.join(', ') : this.item.only;
+ },
+ exceptPolicy() {
+ return this.item.except ? this.item.except.refs.join(', ') : this.item.except;
+ },
+ scripts() {
+ return {
+ beforeScript: {
+ show: !isEmpty(this.item.beforeScript),
+ content: this.item.beforeScript.join('\n'),
+ },
+ script: {
+ show: !isEmpty(this.item.script),
+ content: this.item.script.join('\n'),
+ },
+ afterScript: {
+ show: !isEmpty(this.item.afterScript),
+ content: this.item.afterScript.join('\n'),
+ },
+ };
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <pre v-if="scripts.beforeScript.show" data-testid="ci-lint-before-script">{{
+ scripts.beforeScript.content
+ }}</pre>
+ <pre v-if="scripts.script.show" data-testid="ci-lint-script">{{ scripts.script.content }}</pre>
+ <pre v-if="scripts.afterScript.show" data-testid="ci-lint-after-script">{{
+ scripts.afterScript.content
+ }}</pre>
+
+ <ul class="gl-list-style-none gl-pl-0 gl-mb-0">
+ <li>
+ <b>{{ __('Tag list:') }}</b>
+ {{ tagList }}
+ </li>
+ <div v-if="!dryRun" data-testid="ci-lint-only-except">
+ <li>
+ <b>{{ __('Only policy:') }}</b>
+ {{ onlyPolicy }}
+ </li>
+ <li>
+ <b>{{ __('Except policy:') }}</b>
+ {{ exceptPolicy }}
+ </li>
+ </div>
+ <li>
+ <b>{{ __('Environment:') }}</b>
+ {{ item.environment }}
+ </li>
+ <li>
+ <b>{{ __('When:') }}</b>
+ {{ item.when }}
+ <b v-if="item.allowFailure">{{ __('Allowed to fail') }}</b>
+ </li>
+ </ul>
+ </div>
+</template>
diff --git a/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_warnings.vue b/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_warnings.vue
new file mode 100644
index 00000000000..ac0332cb0bd
--- /dev/null
+++ b/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_warnings.vue
@@ -0,0 +1,69 @@
+<script>
+import { GlAlert, GlSprintf } from '@gitlab/ui';
+import { __, n__ } from '~/locale';
+
+export default {
+ maxWarningsSummary: __('%{total} warnings found: showing first %{warningsDisplayed}'),
+ components: {
+ GlAlert,
+ GlSprintf,
+ },
+ props: {
+ warnings: {
+ type: Array,
+ required: true,
+ },
+ maxWarnings: {
+ type: Number,
+ required: false,
+ default: 25,
+ },
+ title: {
+ type: String,
+ required: false,
+ default: __('The form contains the following warning:'),
+ },
+ },
+ computed: {
+ totalWarnings() {
+ return this.warnings.length;
+ },
+ overMaxWarningsLimit() {
+ return this.totalWarnings > this.maxWarnings;
+ },
+ warningsSummary() {
+ return n__('%d warning found:', '%d warnings found:', this.totalWarnings);
+ },
+ summaryMessage() {
+ return this.overMaxWarningsLimit ? this.$options.maxWarningsSummary : this.warningsSummary;
+ },
+ limitWarnings() {
+ return this.warnings.slice(0, this.maxWarnings);
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-alert class="gl-mb-4" :title="title" variant="warning" @dismiss="$emit('dismiss')">
+ <details>
+ <summary>
+ <gl-sprintf :message="summaryMessage">
+ <template #total>
+ {{ totalWarnings }}
+ </template>
+ <template #warningsDisplayed>
+ {{ maxWarnings }}
+ </template>
+ </gl-sprintf>
+ </summary>
+ <p
+ v-for="(warning, index) in limitWarnings"
+ :key="`warning-${index}`"
+ data-testid="ci-lint-warning"
+ >
+ {{ warning }}
+ </p>
+ </details>
+ </gl-alert>
+</template>
diff --git a/app/assets/javascripts/pipeline_editor/graphql/mutations/lint_ci.mutation.graphql b/app/assets/javascripts/pipeline_editor/graphql/mutations/lint_ci.mutation.graphql
new file mode 100644
index 00000000000..496036f690f
--- /dev/null
+++ b/app/assets/javascripts/pipeline_editor/graphql/mutations/lint_ci.mutation.graphql
@@ -0,0 +1,22 @@
+mutation lintCI($endpoint: String, $content: String, $dry: Boolean) {
+ lintCI(endpoint: $endpoint, content: $content, dry_run: $dry) @client {
+ valid
+ errors
+ warnings
+ jobs {
+ afterScript
+ allowFailure
+ beforeScript
+ environment
+ except
+ name
+ only {
+ refs
+ }
+ afterScript
+ stage
+ tagList
+ when
+ }
+ }
+}
diff --git a/app/assets/javascripts/pipeline_editor/graphql/resolvers.js b/app/assets/javascripts/pipeline_editor/graphql/resolvers.js
index 7b8c70ac93e..c1cdb5eb2ee 100644
--- a/app/assets/javascripts/pipeline_editor/graphql/resolvers.js
+++ b/app/assets/javascripts/pipeline_editor/graphql/resolvers.js
@@ -1,4 +1,5 @@
import Api from '~/api';
+import axios from '~/lib/utils/axios_utils';
export const resolvers = {
Query: {
@@ -11,6 +12,32 @@ export const resolvers = {
};
},
},
-};
+ Mutation: {
+ lintCI: (_, { endpoint, content, dry_run }) => {
+ return axios.post(endpoint, { content, dry_run }).then(({ data }) => ({
+ valid: data.valid,
+ errors: data.errors,
+ warnings: data.warnings,
+ jobs: data.jobs.map(job => {
+ const only = job.only ? { refs: job.only.refs, __typename: 'CiLintJobOnlyPolicy' } : null;
-export default resolvers;
+ return {
+ name: job.name,
+ stage: job.stage,
+ beforeScript: job.before_script,
+ script: job.script,
+ afterScript: job.after_script,
+ tagList: job.tag_list,
+ environment: job.environment,
+ when: job.when,
+ allowFailure: job.allow_failure,
+ only,
+ except: job.except,
+ __typename: 'CiLintJob',
+ };
+ }),
+ __typename: 'CiLintContent',
+ }));
+ },
+ },
+};
diff --git a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
index 59635296de4..a4bdc27d1a0 100644
--- a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
+++ b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
@@ -6,8 +6,8 @@ import { redirectTo, mergeUrlParams, refreshCurrentPage } from '~/lib/utils/url_
import PipelineGraph from '~/pipelines/components/pipeline_graph/pipeline_graph.vue';
import CommitForm from './components/commit/commit_form.vue';
import TextEditor from './components/text_editor.vue';
-import commitCiFileMutation from './graphql/mutations/commit_ci_file.mutation.graphql';
+import commitCiFileMutation from './graphql/mutations/commit_ci_file.mutation.graphql';
import getBlobContent from './graphql/queries/blob_content.graphql';
const MR_SOURCE_BRANCH = 'merge_request[source_branch]';