Commit 4ede2732 authored by Frédéric Caplette's avatar Frédéric Caplette

Merge branch '300501-prepoulate-editor' into 'master'

Prepopulates the pipeline editor with a 3 stage template

See merge request gitlab-org/gitlab!63498
parents 0a79c85b d8a1ad61
<script> <script>
import { GlCard, GlLink, GlSprintf } from '@gitlab/ui'; import { GlCard, GlLink, GlSprintf } from '@gitlab/ui';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import PipelineVisualReference from '../ui/pipeline_visual_reference.vue';
export default { export default {
i18n: { i18n: {
title: s__('PipelineEditorTutorial|🚀 Run your first pipeline'), title: s__('PipelineEditorTutorial|🚀 Run your first pipeline'),
firstParagraph: s__( firstParagraph: s__(
'PipelineEditorTutorial|A typical GitLab pipeline consists of three stages: build, test and deploy. Each stage can have one or more jobs.', 'PipelineEditorTutorial|This template creates a simple test pipeline. To use it:',
),
secondParagraph: s__(
'PipelineEditorTutorial|In the example below, %{codeStart}build%{codeEnd} and %{codeStart}deploy%{codeEnd} each contain one job, and %{codeStart}test%{codeEnd} contains two jobs. Your scripts run in jobs like these.',
),
thirdParagraph: s__(
'PipelineEditorTutorial|You can use %{linkStart}CI/CD examples and templates%{linkEnd} to get your first %{codeStart}.gitlab-ci.yml%{codeEnd} configuration file started. Your first pipeline runs when you commit the changes.',
), ),
listItems: [
s__(
'PipelineEditorTutorial|Commit the file to your repository. The pipeline then runs automatically.',
),
s__('PipelineEditorTutorial|The pipeline status is at the top of the page.'),
s__(
'PipelineEditorTutorial|Select the pipeline ID to view the full details about your first pipeline run.',
),
],
note: s__( note: s__(
'PipelineEditorTutorial|If you’re using a self-managed GitLab instance, %{linkStart}make sure your instance has runners available.%{linkEnd}', 'PipelineEditorTutorial|If you’re using a self-managed GitLab instance, %{linkStart}make sure your instance has runners available.%{linkEnd}',
), ),
...@@ -23,9 +25,8 @@ export default { ...@@ -23,9 +25,8 @@ export default {
GlCard, GlCard,
GlLink, GlLink,
GlSprintf, GlSprintf,
PipelineVisualReference,
}, },
inject: ['ciExamplesHelpPagePath', 'runnerHelpPagePath'], inject: ['runnerHelpPagePath'],
}; };
</script> </script>
<template> <template>
...@@ -33,26 +34,9 @@ export default { ...@@ -33,26 +34,9 @@ export default {
<template #default> <template #default>
<h4 class="gl-font-lg gl-mt-0">{{ $options.i18n.title }}</h4> <h4 class="gl-font-lg gl-mt-0">{{ $options.i18n.title }}</h4>
<p class="gl-mb-3">{{ $options.i18n.firstParagraph }}</p> <p class="gl-mb-3">{{ $options.i18n.firstParagraph }}</p>
<p class="gl-mb-3"> <ol class="gl-mb-3">
<gl-sprintf :message="$options.i18n.secondParagraph"> <li v-for="(item, i) in $options.i18n.listItems" :key="`li-${i}`">{{ item }}</li>
<template #code="{ content }"> </ol>
<code>{{ content }}</code>
</template>
</gl-sprintf>
</p>
<pipeline-visual-reference />
<p class="gl-my-3">
<gl-sprintf :message="$options.i18n.thirdParagraph">
<template #link="{ content }">
<gl-link :href="ciExamplesHelpPagePath" target="_blank">
{{ content }}
</gl-link>
</template>
<template #code="{ content }">
<code>{{ content }}</code>
</template>
</gl-sprintf>
</p>
<p class="gl-mb-0"> <p class="gl-mb-0">
<gl-sprintf :message="$options.i18n.note"> <gl-sprintf :message="$options.i18n.note">
<template #link="{ content }"> <template #link="{ content }">
......
<script>
import { s__ } from '~/locale';
import DemoJobPill from './demo_job_pill.vue';
export default {
i18n: {
stageNames: {
build: s__('StageName|Build'),
test: s__('StageName|Test'),
deploy: s__('StageName|Deploy'),
},
jobNames: {
build: s__('JobName|build-job'),
test_1: s__('JobName|unit-test'),
test_2: s__('JobName|lint-test'),
deploy: s__('JobName|deploy-app'),
},
},
stageClasses:
'gl-bg-blue-50 gl-display-flex gl-flex-direction-column gl-align-items-center gl-p-4 gl-rounded-base',
titleClasses: 'gl-text-blue-600 gl-mb-4',
components: {
DemoJobPill,
},
};
</script>
<template>
<div class="gl-display-flex gl-justify-content-center">
<div :class="$options.stageClasses" class="gl-mr-5">
<div :class="$options.titleClasses">{{ $options.i18n.stageNames.build }}</div>
<demo-job-pill :job-name="$options.i18n.jobNames.build" />
</div>
<div :class="$options.stageClasses" class="gl-mr-5">
<div :class="$options.titleClasses">{{ $options.i18n.stageNames.test }}</div>
<demo-job-pill class="gl-mb-3" :job-name="$options.i18n.jobNames.test_1" />
<demo-job-pill :job-name="$options.i18n.jobNames.test_2" />
</div>
<div :class="$options.stageClasses">
<div :class="$options.titleClasses">{{ $options.i18n.stageNames.deploy }}</div>
<demo-job-pill :job-name="$options.i18n.jobNames.deploy" />
</div>
</div>
</template>
...@@ -31,3 +31,5 @@ export const DRAWER_EXPANDED_KEY = 'pipeline_editor_drawer_expanded'; ...@@ -31,3 +31,5 @@ export const DRAWER_EXPANDED_KEY = 'pipeline_editor_drawer_expanded';
export const BRANCH_PAGINATION_LIMIT = 20; export const BRANCH_PAGINATION_LIMIT = 20;
export const BRANCH_SEARCH_DEBOUNCE = '500'; export const BRANCH_SEARCH_DEBOUNCE = '500';
export const STARTER_TEMPLATE_NAME = 'Getting-Started';
query getTemplate($projectPath: ID!, $templateName: String!) {
project(fullPath: $projectPath) {
ciTemplate(name: $templateName) {
content
}
}
}
...@@ -14,12 +14,14 @@ import { ...@@ -14,12 +14,14 @@ import {
EDITOR_APP_STATUS_ERROR, EDITOR_APP_STATUS_ERROR,
EDITOR_APP_STATUS_LOADING, EDITOR_APP_STATUS_LOADING,
LOAD_FAILURE_UNKNOWN, LOAD_FAILURE_UNKNOWN,
STARTER_TEMPLATE_NAME,
} from './constants'; } from './constants';
import getBlobContent from './graphql/queries/blob_content.graphql'; import getBlobContent from './graphql/queries/blob_content.graphql';
import getCiConfigData from './graphql/queries/ci_config.graphql'; import getCiConfigData from './graphql/queries/ci_config.graphql';
import getAppStatus from './graphql/queries/client/app_status.graphql'; import getAppStatus from './graphql/queries/client/app_status.graphql';
import getCurrentBranch from './graphql/queries/client/current_branch.graphql'; import getCurrentBranch from './graphql/queries/client/current_branch.graphql';
import getIsNewCiConfigFile from './graphql/queries/client/is_new_ci_config_file.graphql'; import getIsNewCiConfigFile from './graphql/queries/client/is_new_ci_config_file.graphql';
import getTemplate from './graphql/queries/get_starter_template.query.graphql';
import PipelineEditorHome from './pipeline_editor_home.vue'; import PipelineEditorHome from './pipeline_editor_home.vue';
export default { export default {
...@@ -51,6 +53,7 @@ export default { ...@@ -51,6 +53,7 @@ export default {
showStartScreen: false, showStartScreen: false,
showSuccess: false, showSuccess: false,
showFailure: false, showFailure: false,
starterTemplate: '',
}; };
}, },
...@@ -135,6 +138,24 @@ export default { ...@@ -135,6 +138,24 @@ export default {
isNewCiConfigFile: { isNewCiConfigFile: {
query: getIsNewCiConfigFile, query: getIsNewCiConfigFile,
}, },
starterTemplate: {
query: getTemplate,
variables() {
return {
projectPath: this.projectFullPath,
templateName: STARTER_TEMPLATE_NAME,
};
},
skip({ isNewCiConfigFile }) {
return !isNewCiConfigFile;
},
update(data) {
return data.project?.ciTemplate?.content || '';
},
error() {
this.reportFailure(LOAD_FAILURE_UNKNOWN);
},
},
}, },
computed: { computed: {
hasUnsavedChanges() { hasUnsavedChanges() {
...@@ -149,6 +170,9 @@ export default { ...@@ -149,6 +170,9 @@ export default {
isEmpty() { isEmpty() {
return this.currentCiFileContent === ''; return this.currentCiFileContent === '';
}, },
templateOrCurrentContent() {
return this.isNewCiConfigFile ? this.starterTemplate : this.currentCiFileContent;
},
}, },
i18n: { i18n: {
tabEdit: s__('Pipelines|Edit'), tabEdit: s__('Pipelines|Edit'),
...@@ -256,7 +280,7 @@ export default { ...@@ -256,7 +280,7 @@ export default {
/> />
<pipeline-editor-home <pipeline-editor-home
:ci-config-data="ciConfigData" :ci-config-data="ciConfigData"
:ci-file-content="currentCiFileContent" :ci-file-content="templateOrCurrentContent"
:is-new-ci-config-file="isNewCiConfigFile" :is-new-ci-config-file="isNewCiConfigFile"
@commit="updateOnCommit" @commit="updateOnCommit"
@resetContent="resetContent" @resetContent="resetContent"
......
...@@ -18754,18 +18754,6 @@ msgstr "" ...@@ -18754,18 +18754,6 @@ msgstr ""
msgid "Job was retried" msgid "Job was retried"
msgstr "" msgstr ""
msgid "JobName|build-job"
msgstr ""
msgid "JobName|deploy-app"
msgstr ""
msgid "JobName|lint-test"
msgstr ""
msgid "JobName|unit-test"
msgstr ""
msgid "Jobs" msgid "Jobs"
msgstr "" msgstr ""
...@@ -23984,10 +23972,10 @@ msgstr "" ...@@ -23984,10 +23972,10 @@ msgstr ""
msgid "PipelineCharts|Total:" msgid "PipelineCharts|Total:"
msgstr "" msgstr ""
msgid "PipelineEditorTutorial|A typical GitLab pipeline consists of three stages: build, test and deploy. Each stage can have one or more jobs." msgid "PipelineEditorTutorial|Browse %{linkStart}CI/CD examples and templates%{linkEnd}"
msgstr "" msgstr ""
msgid "PipelineEditorTutorial|Browse %{linkStart}CI/CD examples and templates%{linkEnd}" msgid "PipelineEditorTutorial|Commit the file to your repository. The pipeline then runs automatically."
msgstr "" msgstr ""
msgid "PipelineEditorTutorial|Get started with GitLab CI/CD" msgid "PipelineEditorTutorial|Get started with GitLab CI/CD"
...@@ -23999,9 +23987,6 @@ msgstr "" ...@@ -23999,9 +23987,6 @@ msgstr ""
msgid "PipelineEditorTutorial|If you’re using a self-managed GitLab instance, %{linkStart}make sure your instance has runners available.%{linkEnd}" msgid "PipelineEditorTutorial|If you’re using a self-managed GitLab instance, %{linkStart}make sure your instance has runners available.%{linkEnd}"
msgstr "" msgstr ""
msgid "PipelineEditorTutorial|In the example below, %{codeStart}build%{codeEnd} and %{codeStart}deploy%{codeEnd} each contain one job, and %{codeStart}test%{codeEnd} contains two jobs. Your scripts run in jobs like these."
msgstr ""
msgid "PipelineEditorTutorial|Learn more about %{linkStart}GitLab CI/CD concepts%{linkEnd}" msgid "PipelineEditorTutorial|Learn more about %{linkStart}GitLab CI/CD concepts%{linkEnd}"
msgstr "" msgstr ""
...@@ -24011,16 +23996,22 @@ msgstr "" ...@@ -24011,16 +23996,22 @@ msgstr ""
msgid "PipelineEditorTutorial|Resources to help with your CI/CD configuration:" msgid "PipelineEditorTutorial|Resources to help with your CI/CD configuration:"
msgstr "" msgstr ""
msgid "PipelineEditorTutorial|Select the pipeline ID to view the full details about your first pipeline run."
msgstr ""
msgid "PipelineEditorTutorial|The pipeline stages and jobs are defined in a %{codeStart}.gitlab-ci.yml%{codeEnd} file. You can edit, visualize and validate the syntax in this file by using the Pipeline Editor." msgid "PipelineEditorTutorial|The pipeline stages and jobs are defined in a %{codeStart}.gitlab-ci.yml%{codeEnd} file. You can edit, visualize and validate the syntax in this file by using the Pipeline Editor."
msgstr "" msgstr ""
msgid "PipelineEditorTutorial|Use the Visualize and Lint tabs in the Pipeline Editor to visualize your pipeline and check for any errors or warnings before committing your changes." msgid "PipelineEditorTutorial|The pipeline status is at the top of the page."
msgstr "" msgstr ""
msgid "PipelineEditorTutorial|View %{linkStart}.gitlab-ci.yml syntax reference%{linkEnd}" msgid "PipelineEditorTutorial|This template creates a simple test pipeline. To use it:"
msgstr "" msgstr ""
msgid "PipelineEditorTutorial|You can use %{linkStart}CI/CD examples and templates%{linkEnd} to get your first %{codeStart}.gitlab-ci.yml%{codeEnd} configuration file started. Your first pipeline runs when you commit the changes." msgid "PipelineEditorTutorial|Use the Visualize and Lint tabs in the Pipeline Editor to visualize your pipeline and check for any errors or warnings before committing your changes."
msgstr ""
msgid "PipelineEditorTutorial|View %{linkStart}.gitlab-ci.yml syntax reference%{linkEnd}"
msgstr "" msgstr ""
msgid "PipelineEditorTutorial|⚙️ Pipeline configuration reference" msgid "PipelineEditorTutorial|⚙️ Pipeline configuration reference"
...@@ -30762,15 +30753,6 @@ msgstr "" ...@@ -30762,15 +30753,6 @@ msgstr ""
msgid "Stage" msgid "Stage"
msgstr "" msgstr ""
msgid "StageName|Build"
msgstr ""
msgid "StageName|Deploy"
msgstr ""
msgid "StageName|Test"
msgstr ""
msgid "Standard" msgid "Standard"
msgstr "" msgstr ""
......
import { getByRole } from '@testing-library/dom'; import { getByRole } from '@testing-library/dom';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import FirstPipelineCard from '~/pipeline_editor/components/drawer/cards/first_pipeline_card.vue'; import FirstPipelineCard from '~/pipeline_editor/components/drawer/cards/first_pipeline_card.vue';
import PipelineVisualReference from '~/pipeline_editor/components/drawer/ui/pipeline_visual_reference.vue';
describe('First pipeline card', () => { describe('First pipeline card', () => {
let wrapper; let wrapper;
const defaultProvide = { const defaultProvide = {
ciExamplesHelpPagePath: '/pipelines/examples',
runnerHelpPagePath: '/help/runners', runnerHelpPagePath: '/help/runners',
}; };
...@@ -20,9 +18,9 @@ describe('First pipeline card', () => { ...@@ -20,9 +18,9 @@ describe('First pipeline card', () => {
}; };
const getLinkByName = (name) => getByRole(wrapper.element, 'link', { name }).href; const getLinkByName = (name) => getByRole(wrapper.element, 'link', { name }).href;
const findPipelinesLink = () => getLinkByName(/examples and templates/i);
const findRunnersLink = () => getLinkByName(/make sure your instance has runners available/i); const findRunnersLink = () => getLinkByName(/make sure your instance has runners available/i);
const findVisualReference = () => wrapper.findComponent(PipelineVisualReference); const findInstructionsList = () => wrapper.find('ol');
const findAllInstructions = () => findInstructionsList().findAll('li');
beforeEach(() => { beforeEach(() => {
createComponent(); createComponent();
...@@ -37,11 +35,11 @@ describe('First pipeline card', () => { ...@@ -37,11 +35,11 @@ describe('First pipeline card', () => {
}); });
it('renders the content', () => { it('renders the content', () => {
expect(findVisualReference().exists()).toBe(true); expect(findInstructionsList().exists()).toBe(true);
expect(findAllInstructions()).toHaveLength(3);
}); });
it('renders the links', () => { it('renders the link', () => {
expect(findRunnersLink()).toContain(defaultProvide.runnerHelpPagePath); expect(findRunnersLink()).toContain(defaultProvide.runnerHelpPagePath);
expect(findPipelinesLink()).toContain(defaultProvide.ciExamplesHelpPagePath);
}); });
}); });
import { shallowMount } from '@vue/test-utils';
import DemoJobPill from '~/pipeline_editor/components/drawer/ui/demo_job_pill.vue';
import PipelineVisualReference from '~/pipeline_editor/components/drawer/ui/pipeline_visual_reference.vue';
describe('Demo job pill', () => {
let wrapper;
const createComponent = () => {
wrapper = shallowMount(PipelineVisualReference);
};
const findAllDemoJobPills = () => wrapper.findAllComponents(DemoJobPill);
beforeEach(() => {
createComponent();
});
afterEach(() => {
wrapper.destroy();
});
it('renders all stage names', () => {
expect(wrapper.text()).toContain(wrapper.vm.$options.i18n.stageNames.build);
expect(wrapper.text()).toContain(wrapper.vm.$options.i18n.stageNames.test);
expect(wrapper.text()).toContain(wrapper.vm.$options.i18n.stageNames.deploy);
});
it('renders all job pills', () => {
expect(findAllDemoJobPills()).toHaveLength(4);
});
});
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