Commit cbf25c52 authored by Brandon Labuschagne's avatar Brandon Labuschagne

Merge branch 'nicolasdular/hello-world-ci-template' into 'master'

Pipeline Empty State Experiment: Show Hello World CI template

See merge request gitlab-org/gitlab!58649
parents 5b6e8d61 61524f77
<script>
import { GlButton } from '@gitlab/ui';
import { GlButton, GlCard, GlSprintf } from '@gitlab/ui';
import { mergeUrlParams } from '~/lib/utils/url_utility';
import { s__, sprintf } from '~/locale';
import { SUGGESTED_CI_TEMPLATES } from '../../constants';
import { SUGGESTED_CI_TEMPLATES, HELLO_WORLD_TEMPLATE_KEY } from '../../constants';
export default {
components: {
GlButton,
GlCard,
GlSprintf,
},
i18n: {
title: s__('Pipelines|Try a sample CI/CD file'),
subtitle: s__(
'Pipelines|Use a sample file to implement GitLab CI/CD based on your project’s language/framework.',
),
cta: s__('Pipelines|Use template'),
description: s__(
'Pipelines|Continuous deployment template to test and deploy your %{name} project.',
),
errorMessage: s__('Pipelines|An error occurred. Please try again.'),
testTemplates: {
title: s__('Pipelines|Use a sample CI/CD template'),
subtitle: s__(
'Pipelines|Use a sample %{codeStart}.gitlab-ci.yml%{codeEnd} template file to explore how CI/CD works.',
),
helloWorld: {
title: s__('Pipelines|“Hello world” with GitLab CI/CD'),
description: s__(
'Pipelines|Get familiar with GitLab CI/CD syntax by starting with a simple pipeline that runs a “Hello world” script.',
),
},
},
templates: {
title: s__('Pipelines|Use a CI/CD template'),
subtitle: s__(
"Pipelines|Use a template based on your project's language or framework to get started with GitLab CI/CD.",
),
description: s__('Pipelines|CI/CD template to test and deploy your %{name} project.'),
},
},
inject: ['addCiYmlPath'],
data() {
......@@ -26,25 +39,63 @@ export default {
name: key,
logoPath: SUGGESTED_CI_TEMPLATES[key].logoPath,
link: mergeUrlParams({ template: key }, this.addCiYmlPath),
description: sprintf(this.$options.i18n.description, { name: key }),
description: sprintf(this.$options.i18n.templates.description, { name: key }),
};
});
return {
templates,
helloWorldTemplateUrl: mergeUrlParams(
{ template: HELLO_WORLD_TEMPLATE_KEY },
this.addCiYmlPath,
),
};
},
};
</script>
<template>
<div>
<h2>{{ $options.i18n.title }}</h2>
<p>{{ $options.i18n.subtitle }}</p>
<h2 class="gl-font-size-h2 gl-text-gray-900">{{ $options.i18n.testTemplates.title }}</h2>
<p class="gl-text-gray-800 gl-mb-6">
<gl-sprintf :message="$options.i18n.testTemplates.subtitle">
<template #code="{ content }">
<code>{{ content }}</code>
</template>
</gl-sprintf>
</p>
<div class="row gl-mb-8">
<div class="col-lg-3">
<gl-card>
<div class="gl-flex-direction-row">
<div class="gl-py-5"><gl-emoji class="gl-font-size-h2-xl" data-name="wave" /></div>
<div class="gl-mb-3">
<strong class="gl-text-gray-800 gl-mb-2">{{
$options.i18n.testTemplates.helloWorld.title
}}</strong>
</div>
<p class="gl-font-sm">{{ $options.i18n.testTemplates.helloWorld.description }}</p>
</div>
<gl-button
category="primary"
variant="confirm"
:href="helloWorldTemplateUrl"
data-testid="test-template-link"
>
{{ $options.i18n.cta }}
</gl-button>
</gl-card>
</div>
</div>
<h2 class="gl-font-size-h2 gl-text-gray-900">{{ $options.i18n.templates.title }}</h2>
<p class="gl-text-gray-800 gl-mb-6">{{ $options.i18n.templates.subtitle }}</p>
<ul class="gl-list-style-none gl-pl-0">
<li v-for="template in templates" :key="template.key">
<li v-for="template in templates" :key="template.name">
<div
class="gl-display-flex gl-align-items-center gl-justify-content-space-between gl-border-b-solid gl-border-b-1 gl-border-b-gray-100 gl-pb-5 gl-pt-5"
class="gl-display-flex gl-align-items-center gl-justify-content-space-between gl-border-b-solid gl-border-b-1 gl-border-b-gray-100 gl-pb-3 gl-pt-3"
>
<div class="gl-display-flex gl-flex-direction-row gl-align-items-center">
<img
......@@ -55,8 +106,14 @@ export default {
data-testid="template-logo"
/>
<div class="gl-flex-direction-row">
<strong class="gl-text-gray-800">{{ template.name }}</strong>
<p class="gl-mb-0" data-testid="template-description">{{ template.description }}</p>
<div class="gl-mb-3">
<strong class="gl-text-gray-800" data-testid="template-name">{{
template.name
}}</strong>
</div>
<p class="gl-mb-0 gl-font-sm" data-testid="template-description">
{{ template.description }}
</p>
</div>
</div>
<gl-button
......@@ -64,8 +121,9 @@ export default {
variant="confirm"
:href="template.link"
data-testid="template-link"
>{{ $options.i18n.cta }}</gl-button
>
{{ $options.i18n.cta }}
</gl-button>
</div>
</li>
</ul>
......
......@@ -36,7 +36,8 @@ export const UNSUPPORTED_DATA = 'unsupported_data';
export const CHILD_VIEW = 'child';
// The keys of the Object are the same as the `key` value in the template list we get from the API.
// The keys of the templates are the same as their filenames
export const HELLO_WORLD_TEMPLATE_KEY = 'Hello-World';
export const SUGGESTED_CI_TEMPLATES = {
Android: { logoPath: '/assets/illustrations/logos/android.svg' },
Bash: { logoPath: '/assets/illustrations/logos/bash.svg' },
......
---
title: Add Hello World CI Template
merge_request: 58649
author:
type: added
# This file is a template demonstrating the `script` keyword.
# Learn more about this keyword here: https://docs.gitlab.com/ee/ci/yaml/README.html#script
# After committing this template, visit CI/CD > Jobs to see the script output.
job:
script:
# provide a shell script as argument for this keyword.
- echo "Hello World"
......@@ -22914,9 +22914,6 @@ msgstr ""
msgid "Pipelines|API"
msgstr ""
msgid "Pipelines|An error occurred. Please try again."
msgstr ""
msgid "Pipelines|Are you sure you want to run this pipeline?"
msgstr ""
......@@ -22929,13 +22926,13 @@ msgstr ""
msgid "Pipelines|CI lint"
msgstr ""
msgid "Pipelines|Child pipeline"
msgid "Pipelines|CI/CD template to test and deploy your %{name} project."
msgstr ""
msgid "Pipelines|Clear runner caches"
msgid "Pipelines|Child pipeline"
msgstr ""
msgid "Pipelines|Continuous deployment template to test and deploy your %{name} project."
msgid "Pipelines|Clear runner caches"
msgstr ""
msgid "Pipelines|Copy trigger token"
......@@ -22953,6 +22950,9 @@ msgstr ""
msgid "Pipelines|Editor"
msgstr ""
msgid "Pipelines|Get familiar with GitLab CI/CD syntax by starting with a simple pipeline that runs a “Hello world” script."
msgstr ""
msgid "Pipelines|Get started with CI/CD"
msgstr ""
......@@ -23049,10 +23049,16 @@ msgstr ""
msgid "Pipelines|Trigger user has insufficient permissions to project"
msgstr ""
msgid "Pipelines|Try a sample CI/CD file"
msgid "Pipelines|Use a CI/CD template"
msgstr ""
msgid "Pipelines|Use a sample %{codeStart}.gitlab-ci.yml%{codeEnd} template file to explore how CI/CD works."
msgstr ""
msgid "Pipelines|Use a sample file to implement GitLab CI/CD based on your project’s language/framework."
msgid "Pipelines|Use a sample CI/CD template"
msgstr ""
msgid "Pipelines|Use a template based on your project's language or framework to get started with GitLab CI/CD."
msgstr ""
msgid "Pipelines|Use template"
......@@ -23076,6 +23082,9 @@ msgstr ""
msgid "Pipelines|parent"
msgstr ""
msgid "Pipelines|“Hello world” with GitLab CI/CD"
msgstr ""
msgid "Pipeline|Actions"
msgstr ""
......
......@@ -7,16 +7,23 @@ const addCiYmlPath = "/-/new/master?commit_message='Add%20.gitlab-ci.yml'";
describe('Pipelines CI Templates', () => {
let wrapper;
const GlEmoji = { template: '<img/>' };
const createWrapper = () => {
return shallowMount(PipelinesCiTemplate, {
provide: {
addCiYmlPath,
},
stubs: {
GlEmoji,
},
});
};
const findTestTemplateLinks = () => wrapper.findAll('[data-testid="test-template-link"]');
const findTemplateDescriptions = () => wrapper.findAll('[data-testid="template-description"]');
const findTemplateLinks = () => wrapper.findAll('[data-testid="template-link"]');
const findTemplateNames = () => wrapper.findAll('[data-testid="template-name"]');
const findTemplateLogos = () => wrapper.findAll('[data-testid="template-logo"]');
afterEach(() => {
......@@ -24,7 +31,19 @@ describe('Pipelines CI Templates', () => {
wrapper = null;
});
describe('renders templates', () => {
describe('renders test template', () => {
beforeEach(() => {
wrapper = createWrapper();
});
it('links to the hello world template', () => {
expect(findTestTemplateLinks().at(0).attributes('href')).toBe(
addCiYmlPath.concat('&template=Hello-World'),
);
});
});
describe('renders template list', () => {
beforeEach(() => {
wrapper = createWrapper();
});
......@@ -37,20 +56,24 @@ describe('Pipelines CI Templates', () => {
expect(content).toContain(...keys);
});
it('has the correct template name', () => {
expect(findTemplateNames().at(0).text()).toBe('Android');
});
it('links to the correct template', () => {
expect(findTemplateLinks().at(0).attributes('href')).toEqual(
expect(findTemplateLinks().at(0).attributes('href')).toBe(
addCiYmlPath.concat('&template=Android'),
);
});
it('has the description of the template', () => {
expect(findTemplateDescriptions().at(0).text()).toEqual(
'Continuous deployment template to test and deploy your Android project.',
expect(findTemplateDescriptions().at(0).text()).toBe(
'CI/CD template to test and deploy your Android project.',
);
});
it('has the right logo of the template', () => {
expect(findTemplateLogos().at(0).attributes('src')).toEqual(
expect(findTemplateLogos().at(0).attributes('src')).toBe(
'/assets/illustrations/logos/android.svg',
);
});
......
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