Commit 333ffd44 authored by Miguel Rincon's avatar Miguel Rincon Committed by Sarah Groff Hennigh-Palermo

Move ci lint components to pipeline editor

This change moves the components and queries related to CI Lint to the
pipeline editor directory, so they become part of the editor codebase.

Why?

The CI lint feature will be moved completly to the pipeline editor
and this is an initial technical iteration to move the files to their
destination.
parent 8aafdd0d
<script>
import { GlButton, GlFormCheckbox, GlIcon, GlLink, GlAlert } from '@gitlab/ui';
import EditorLite from '~/vue_shared/components/editor_lite.vue';
import CiLintResults from './ci_lint_results.vue';
import lintCIMutation from '../graphql/mutations/lint_ci.mutation.graphql';
import CiLintResults from '~/pipeline_editor/components/lint/ci_lint_results.vue';
import lintCiMutation from '~/pipeline_editor/graphql/mutations/lint_ci.mutation.graphql';
export default {
components: {
......@@ -56,7 +56,7 @@ export default {
lintCI: { valid, errors, warnings, jobs },
},
} = await this.$apollo.mutate({
mutation: lintCIMutation,
mutation: lintCiMutation,
variables: { endpoint: this.endpoint, content: this.content, dry: this.dryRun },
});
......@@ -119,6 +119,7 @@ export default {
<ci-lint-results
v-if="showingResults"
class="col-sm-12 gl-mt-5"
:valid="valid"
:jobs="jobs"
:errors="errors"
......
import axios from '~/lib/utils/axios_utils';
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;
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',
}));
},
},
};
export default resolvers;
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import { resolvers } from '~/pipeline_editor/graphql/resolvers';
import CiLint from './components/ci_lint.vue';
import resolvers from './graphql/resolvers';
Vue.use(VueApollo);
......
......@@ -90,7 +90,7 @@ export default {
</script>
<template>
<div class="col-sm-12 gl-mt-5">
<div>
<gl-alert
class="gl-mb-5"
:variant="status.variant"
......
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',
}));
},
},
};
......@@ -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]';
......
......@@ -3,8 +3,8 @@ import { shallowMount } from '@vue/test-utils';
import waitForPromises from 'helpers/wait_for_promises';
import EditorLite from '~/vue_shared/components/editor_lite.vue';
import CiLint from '~/ci_lint/components/ci_lint.vue';
import CiLintResults from '~/ci_lint/components/ci_lint_results.vue';
import lintCIMutation from '~/ci_lint/graphql/mutations/lint_ci.mutation.graphql';
import CiLintResults from '~/pipeline_editor/components/lint/ci_lint_results.vue';
import lintCIMutation from '~/pipeline_editor/graphql/mutations/lint_ci.mutation.graphql';
import { mockLintDataValid } from '../mock_data';
describe('CI Lint', () => {
......
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import httpStatus from '~/lib/utils/http_status';
import resolvers from '~/ci_lint/graphql/resolvers';
import { mockLintResponse } from '../mock_data';
describe('~/ci_lint/graphql/resolvers', () => {
let mock;
beforeEach(() => {
mock = new MockAdapter(axios);
});
afterEach(() => {
mock.restore();
});
describe('Mutation', () => {
describe('lintCI', () => {
const endpoint = '/ci/lint';
beforeEach(() => {
mock.onPost(endpoint).reply(httpStatus.OK, mockLintResponse);
});
it('resolves lint data with type names', async () => {
const result = resolvers.Mutation.lintCI(null, {
endpoint,
content: 'content',
dry_run: true,
});
await expect(result).resolves.toMatchSnapshot();
});
});
});
});
export const mockLintResponse = {
valid: true,
errors: [],
warnings: [],
jobs: [
{
name: 'job_1',
stage: 'test',
before_script: ["echo 'before script 1'"],
script: ["echo 'script 1'"],
after_script: ["echo 'after script 1"],
tag_list: ['tag 1'],
environment: 'prd',
when: 'on_success',
allow_failure: false,
only: null,
except: { refs: ['master@gitlab-org/gitlab', '/^release/.*$/@gitlab-org/gitlab'] },
},
{
name: 'job_2',
stage: 'test',
before_script: ["echo 'before script 2'"],
script: ["echo 'script 2'"],
after_script: ["echo 'after script 2"],
tag_list: ['tag 2'],
environment: 'stg',
when: 'on_success',
allow_failure: true,
only: { refs: ['web', 'chat', 'pushes'] },
except: { refs: ['master@gitlab-org/gitlab', '/^release/.*$/@gitlab-org/gitlab'] },
},
],
};
export const mockJobs = [
{
name: 'job_1',
stage: 'build',
beforeScript: [],
script: ["echo 'Building'"],
afterScript: [],
tagList: [],
environment: null,
when: 'on_success',
allowFailure: true,
only: { refs: ['web', 'chat', 'pushes'] },
except: null,
},
{
name: 'multi_project_job',
stage: 'test',
beforeScript: [],
script: [],
afterScript: [],
tagList: [],
environment: null,
when: 'on_success',
allowFailure: false,
only: { refs: ['branches', 'tags'] },
except: null,
},
{
name: 'job_2',
stage: 'test',
beforeScript: ["echo 'before script'"],
script: ["echo 'script'"],
afterScript: ["echo 'after script"],
tagList: [],
environment: null,
when: 'on_success',
allowFailure: false,
only: { refs: ['branches@gitlab-org/gitlab'] },
except: { refs: ['master@gitlab-org/gitlab', '/^release/.*$/@gitlab-org/gitlab'] },
},
];
export const mockErrors = [
'"job_1 job: chosen stage does not exist; available stages are .pre, build, test, deploy, .post"',
];
export const mockWarnings = [
'"jobs:multi_project_job may allow multiple pipelines to run for a single action due to `rules:when` clause with no `workflow:rules` - read more: https://docs.gitlab.com/ee/ci/troubleshooting.html#pipeline-warnings"',
];
import { mockJobs } from 'jest/pipeline_editor/mock_data';
export const mockLintDataValid = {
data: {
......
import { shallowMount, mount } from '@vue/test-utils';
import { GlTable, GlLink } from '@gitlab/ui';
import CiLintResults from '~/ci_lint/components/ci_lint_results.vue';
import CiLintResults from '~/pipeline_editor/components/lint/ci_lint_results.vue';
import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
import { mockJobs, mockErrors, mockWarnings } from '../mock_data';
import { mockJobs, mockErrors, mockWarnings } from '../../mock_data';
describe('CI Lint Results', () => {
let wrapper;
......
import { mount } from '@vue/test-utils';
import { GlAlert, GlSprintf } from '@gitlab/ui';
import { trimText } from 'helpers/text_helper';
import CiLintWarnings from '~/ci_lint/components/ci_lint_warnings.vue';
import CiLintWarnings from '~/pipeline_editor/components/lint/ci_lint_warnings.vue';
const warnings = ['warning 1', 'warning 2', 'warning 3'];
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`~/ci_lint/graphql/resolvers Mutation lintCI resolves lint data with type names 1`] = `
exports[`~/pipeline_editor/graphql/resolvers Mutation lintCI lint data is as expected 1`] = `
Object {
"__typename": "CiLintContent",
"errors": Array [],
......
import MockAdapter from 'axios-mock-adapter';
import Api from '~/api';
import { mockProjectPath, mockDefaultBranch, mockCiConfigPath, mockCiYml } from '../mock_data';
import {
mockCiConfigPath,
mockCiYml,
mockDefaultBranch,
mockLintResponse,
mockProjectPath,
} from '../mock_data';
import httpStatus from '~/lib/utils/http_status';
import axios from '~/lib/utils/axios_utils';
import { resolvers } from '~/pipeline_editor/graphql/resolvers';
jest.mock('~/api', () => {
......@@ -39,4 +47,43 @@ describe('~/pipeline_editor/graphql/resolvers', () => {
});
});
});
describe('Mutation', () => {
describe('lintCI', () => {
let mock;
let result;
const endpoint = '/ci/lint';
beforeEach(async () => {
mock = new MockAdapter(axios);
mock.onPost(endpoint).reply(httpStatus.OK, mockLintResponse);
result = await resolvers.Mutation.lintCI(null, {
endpoint,
content: 'content',
dry_run: true,
});
});
afterEach(() => {
mock.restore();
});
/* eslint-disable no-underscore-dangle */
it('lint data has correct type names', async () => {
expect(result.__typename).toBe('CiLintContent');
expect(result.jobs[0].__typename).toBe('CiLintJob');
expect(result.jobs[1].__typename).toBe('CiLintJob');
expect(result.jobs[1].only.__typename).toBe('CiLintJobOnlyPolicy');
});
/* eslint-enable no-underscore-dangle */
it('lint data is as expected', () => {
expect(result).toMatchSnapshot();
});
});
});
});
......@@ -11,3 +11,87 @@ job1:
script:
- echo 'test'
`;
export const mockLintResponse = {
valid: true,
errors: [],
warnings: [],
jobs: [
{
name: 'job_1',
stage: 'test',
before_script: ["echo 'before script 1'"],
script: ["echo 'script 1'"],
after_script: ["echo 'after script 1"],
tag_list: ['tag 1'],
environment: 'prd',
when: 'on_success',
allow_failure: false,
only: null,
except: { refs: ['master@gitlab-org/gitlab', '/^release/.*$/@gitlab-org/gitlab'] },
},
{
name: 'job_2',
stage: 'test',
before_script: ["echo 'before script 2'"],
script: ["echo 'script 2'"],
after_script: ["echo 'after script 2"],
tag_list: ['tag 2'],
environment: 'stg',
when: 'on_success',
allow_failure: true,
only: { refs: ['web', 'chat', 'pushes'] },
except: { refs: ['master@gitlab-org/gitlab', '/^release/.*$/@gitlab-org/gitlab'] },
},
],
};
export const mockJobs = [
{
name: 'job_1',
stage: 'build',
beforeScript: [],
script: ["echo 'Building'"],
afterScript: [],
tagList: [],
environment: null,
when: 'on_success',
allowFailure: true,
only: { refs: ['web', 'chat', 'pushes'] },
except: null,
},
{
name: 'multi_project_job',
stage: 'test',
beforeScript: [],
script: [],
afterScript: [],
tagList: [],
environment: null,
when: 'on_success',
allowFailure: false,
only: { refs: ['branches', 'tags'] },
except: null,
},
{
name: 'job_2',
stage: 'test',
beforeScript: ["echo 'before script'"],
script: ["echo 'script'"],
afterScript: ["echo 'after script"],
tagList: [],
environment: null,
when: 'on_success',
allowFailure: false,
only: { refs: ['branches@gitlab-org/gitlab'] },
except: { refs: ['master@gitlab-org/gitlab', '/^release/.*$/@gitlab-org/gitlab'] },
},
];
export const mockErrors = [
'"job_1 job: chosen stage does not exist; available stages are .pre, build, test, deploy, .post"',
];
export const mockWarnings = [
'"jobs:multi_project_job may allow multiple pipelines to run for a single action due to `rules:when` clause with no `workflow:rules` - read more: https://docs.gitlab.com/ee/ci/troubleshooting.html#pipeline-warnings"',
];
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment