Skip to content

Commit e7ca931

Browse files
Merge pull request #7299 from andrewballantyne/devfile-rework
Devfile Add Flow
2 parents 6000d5d + 508728f commit e7ca931

File tree

302 files changed

+55990
-2335
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

302 files changed

+55990
-2335
lines changed

frontend/packages/console-shared/src/utils/sample-utils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ const defaultSamples = ImmutableMap<GroupVersionKind, Sample[]>()
7272
id: 'docker-build',
7373
targetResource: getTargetResource(BuildConfigModel),
7474
},
75+
{
76+
title: 'Build from Devfile',
77+
description:
78+
'A Devfile build performs an image build using a devfile in the source repository or specified in build configuration.',
79+
id: 'devfile-build',
80+
targetResource: getTargetResource(BuildConfigModel),
81+
},
7582
{
7683
title: 'Source-to-Image (S2I) build',
7784
description:

frontend/packages/dev-console/locales/en/devconsole.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"Container Image": "Container Image",
44
"From Catalog": "From Catalog",
55
"From Dockerfile": "From Dockerfile",
6+
"From Devfile": "From Devfile",
67
"Database": "Database",
78
"Samples": "Samples",
89
"Operator Backed": "Operator Backed",
@@ -273,6 +274,8 @@
273274
"Sample repository:": "Sample repository:",
274275
"Create": "Create",
275276
"Deploy Image": "Deploy Image",
277+
"The Devfile in your Git repository is invalid.": "The Devfile in your Git repository is invalid.",
278+
"Import is not possible.": "Import is not possible.",
276279
"Hide advanced Git options": "Hide advanced Git options",
277280
"Show advanced Git options": "Show advanced Git options",
278281
"Git reference": "Git reference",
@@ -285,6 +288,7 @@
285288
"Container port": "Container port",
286289
"Port number the Container exposes.": "Port number the Container exposes.",
287290
"Validating": "Validating",
291+
"No Devfile present, unable to continue": "No Devfile present, unable to continue",
288292
"Validated": "Validated",
289293
"URL is valid but cannot be reached. If this is a private repository, enter a source Secret in advanced Git options": "URL is valid but cannot be reached. If this is a private repository, enter a source Secret in advanced Git options",
290294
"Git": "Git",
@@ -317,9 +321,11 @@
317321
"Tag": "Tag",
318322
"No tag": "No tag",
319323
"Select tag": "Select tag",
324+
"Cannot update Devfile resources": "Cannot update Devfile resources",
320325
"no application group": "no application group",
321326
"Import from Git": "Import from Git",
322327
"Import from Dockerfile": "Import from Dockerfile",
328+
"Import from Devfile": "Import from Devfile",
323329
"Create Source-to-Image Application": "Create Source-to-Image Application",
324330
"Git repo URL": "Git repo URL",
325331
"Create Sample Application": "Create Sample Application",
@@ -443,6 +449,7 @@
443449
"Developer": "Developer",
444450
"Create an Application from a code sample": "Create an Application from a code sample",
445451
"Import code from your Git repository to be built and deployed": "Import code from your Git repository to be built and deployed",
452+
"Import your Devfile from your Git repository to be built and deployed": "Import your Devfile from your Git repository to be built and deployed",
446453
"Deploy an existing Image from an Image registry or Image stream tag": "Deploy an existing Image from an Image registry or Image stream tag",
447454
"Import your Dockerfile from your Git repository to be built and deployed": "Import your Dockerfile from your Git repository to be built and deployed",
448455
"YAML": "YAML",

frontend/packages/dev-console/src/actions/add-resources.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
OsImageIcon,
55
CatalogIcon,
66
CubeIcon,
7+
LayerGroupIcon,
78
DatabaseIcon,
89
LaptopCodeIcon,
910
BoltIcon,
@@ -47,6 +48,14 @@ export const fromDockerfile = createKebabAction(
4748
allImportResourceAccess,
4849
);
4950

51+
export const fromDevfile = createKebabAction(
52+
// t('devconsole~From Devfile')
53+
'devconsole~From Devfile',
54+
<LayerGroupIcon />,
55+
ImportOptions.DEVFILE,
56+
allImportResourceAccess,
57+
);
58+
5059
export const fromDatabaseCatalog = createKebabAction(
5160
// t('devconsole~Database')
5261
'devconsole~Database',
@@ -81,17 +90,24 @@ export const addResourceMenu: KebabAction[] = [
8190
fromGit,
8291
containerImage,
8392
fromDockerfile,
93+
fromDevfile,
8494
fromCatalog,
8595
fromDatabaseCatalog,
8696
fromOperatorBacked,
8797
fromHelmCharts,
8898
];
8999

90-
export const addGroupResourceMenu: KebabAction[] = [fromGit, containerImage, fromDockerfile];
100+
export const addGroupResourceMenu: KebabAction[] = [
101+
fromGit,
102+
containerImage,
103+
fromDockerfile,
104+
fromDevfile,
105+
];
91106

92107
export const addResourceMenuWithoutCatalog: KebabAction[] = [
93108
fromGit,
94109
containerImage,
95110
fromDockerfile,
111+
fromDevfile,
96112
fromOperatorBacked,
97113
];

frontend/packages/dev-console/src/components/edit-application/EditApplication.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,15 @@ const EditApplication: React.FC<EditApplicationProps & StateProps> = ({
4646
if (values.build.strategy) {
4747
const imageStream =
4848
values.image.selected && builderImages ? builderImages[values.image.selected].obj : null;
49-
return createOrUpdateGitResources(values, imageStream, false, false, 'update', appResources);
49+
return createOrUpdateGitResources(
50+
t,
51+
values,
52+
imageStream,
53+
false,
54+
false,
55+
'update',
56+
appResources,
57+
);
5058
}
5159
return createOrUpdateDeployImageResources(values, false, 'update', appResources);
5260
};

frontend/packages/dev-console/src/components/import/ImportForm.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,12 @@ const ImportForm: React.FC<ImportFormProps & StateProps> = ({
162162
} = values;
163163

164164
const resourceActions = createOrUpdateResources(
165+
t,
165166
values,
166167
imageStream,
167168
createNewProject,
168169
true,
169-
).then(() => createOrUpdateResources(values, imageStream));
170+
).then(() => createOrUpdateResources(t, values, imageStream));
170171

171172
resourceActions
172173
.then((resources) => {

frontend/packages/dev-console/src/components/import/ImportPage.tsx

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import Helmet from 'react-helmet';
44
import { TFunction } from 'i18next';
55
import { useTranslation } from 'react-i18next';
66
import { PageHeading, Firehose, FirehoseResource } from '@console/internal/components/utils';
7-
import { ImageStreamModel } from '@console/internal/models';
7+
import DevPreviewBadge from '@console/shared/src/components/badges/DevPreviewBadge';
8+
import { ImageStreamModel, ProjectModel } from '@console/internal/models';
89
import { QUERY_PROPERTIES } from '../../const';
910
import NamespacedPage, { NamespacedPageVariants } from '../NamespacedPage';
1011
import QueryFocusApplication from '../QueryFocusApplication';
@@ -28,6 +29,15 @@ const ImportFlows = (t: TFunction): { [name: string]: ImportData } => ({
2829
loader: () =>
2930
import('./GitImportForm' /* webpackChunkName: "git-import-form" */).then((m) => m.default),
3031
},
32+
devfile: {
33+
type: ImportTypes.devfile,
34+
title: t('devconsole~Import from Devfile'),
35+
buildStrategy: 'Devfile',
36+
loader: () =>
37+
import('./devfile/DevfileImportForm' /* webpackChunkName: "devfile-import-form" */).then(
38+
(m) => m.default,
39+
),
40+
},
3141
s2i: {
3242
type: ImportTypes.s2i,
3343
title: t('devconsole~Create Source-to-Image Application'),
@@ -61,7 +71,7 @@ const ImportPage: React.FunctionComponent<ImportPageProps> = ({ match, location
6171
namespace: imageStreamNamespace,
6272
},
6373
{
64-
kind: 'Project',
74+
kind: ProjectModel.kind,
6575
prop: 'projects',
6676
isList: true,
6777
},
@@ -70,7 +80,16 @@ const ImportPage: React.FunctionComponent<ImportPageProps> = ({ match, location
7080
importData = ImportFlows(t).docker;
7181
resources = [
7282
{
73-
kind: 'Project',
83+
kind: ProjectModel.kind,
84+
prop: 'projects',
85+
isList: true,
86+
},
87+
];
88+
} else if (importType === ImportTypes.devfile) {
89+
importData = ImportFlows(t).devfile;
90+
resources = [
91+
{
92+
kind: ProjectModel.kind,
7493
prop: 'projects',
7594
isList: true,
7695
},
@@ -85,7 +104,7 @@ const ImportPage: React.FunctionComponent<ImportPageProps> = ({ match, location
85104
namespace: 'openshift',
86105
},
87106
{
88-
kind: 'Project',
107+
kind: ProjectModel.kind,
89108
prop: 'projects',
90109
isList: true,
91110
},
@@ -99,7 +118,10 @@ const ImportPage: React.FunctionComponent<ImportPageProps> = ({ match, location
99118
<Helmet>
100119
<title>{importData.title}</title>
101120
</Helmet>
102-
<PageHeading title={importData.title} />
121+
<PageHeading
122+
title={importData.title}
123+
badge={importType === ImportTypes.devfile ? <DevPreviewBadge /> : null}
124+
/>
103125
<div className="co-m-pane__body" style={{ paddingBottom: 0 }}>
104126
<Firehose resources={resources}>
105127
<ImportForm

frontend/packages/dev-console/src/components/import/ImportSamplePage.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,12 @@ const ImportSamplePage: React.FC<ImportSamplePageProps> = ({ match }) => {
163163

164164
const handleSubmit = (values, actions) => {
165165
const resourceActions = createOrUpdateResources(
166+
t,
166167
values,
167168
imageStream as K8sResourceKind,
168169
false,
169170
true,
170-
).then(() => createOrUpdateResources(values, imageStream as K8sResourceKind));
171+
).then(() => createOrUpdateResources(t, values, imageStream as K8sResourceKind));
171172

172173
return resourceActions
173174
.then(() => {

frontend/packages/dev-console/src/components/import/__tests__/import-submit-utils.spec.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import { defaultData, nodeJsBuilderImage as buildImage } from './import-submit-u
1818
const { createOrUpdateDeployment, createOrUpdateResources } = submitUtils;
1919

2020
describe('Import Submit Utils', () => {
21+
const t = jest.fn();
22+
2123
describe('createDeployment tests', () => {
2224
beforeAll(() => {
2325
jest
@@ -91,7 +93,7 @@ describe('Import Submit Utils', () => {
9193
const mockData = _.cloneDeep(defaultData);
9294
mockData.resources = Resources.Kubernetes;
9395

94-
const returnValue = await createOrUpdateResources(mockData, buildImage.obj, false);
96+
const returnValue = await createOrUpdateResources(t, mockData, buildImage.obj, false);
9597
expect(returnValue).toHaveLength(7);
9698
const models = returnValue.map((data) => _.get(data, 'model.kind'));
9799
expect(models).toEqual([
@@ -110,7 +112,7 @@ describe('Import Submit Utils', () => {
110112
const mockData = _.cloneDeep(defaultData);
111113
mockData.resources = Resources.OpenShift;
112114

113-
const returnValue = await createOrUpdateResources(mockData, buildImage.obj, false);
115+
const returnValue = await createOrUpdateResources(t, mockData, buildImage.obj, false);
114116
expect(returnValue).toHaveLength(7);
115117
const models = returnValue.map((data) => _.get(data, 'model.kind'));
116118
expect(models).toEqual([
@@ -137,7 +139,7 @@ describe('Import Submit Utils', () => {
137139
},
138140
}));
139141

140-
const returnValue = await createOrUpdateResources(mockData, buildImage.obj, false);
142+
const returnValue = await createOrUpdateResources(t, mockData, buildImage.obj, false);
141143
// createImageStream is called as separate entity
142144
expect(imageStreamSpy).toHaveBeenCalled();
143145
expect(returnValue).toHaveLength(1);
@@ -183,7 +185,7 @@ describe('Import Submit Utils', () => {
183185
'createPipelineRunForImportFlow',
184186
);
185187

186-
await createOrUpdateResources(mockData, buildImage.obj, false, false, 'create');
188+
await createOrUpdateResources(t, mockData, buildImage.obj, false, false, 'create');
187189
expect(createPipelineResourceSpy).toHaveBeenCalledWith(
188190
mockData.name,
189191
mockData.project.name,
@@ -205,6 +207,7 @@ describe('Import Submit Utils', () => {
205207
const createPipelineResourceSpy = jest.spyOn(pipelineUtils, 'createPipelineForImportFlow');
206208

207209
const returnValue = await createOrUpdateResources(
210+
t,
208211
mockData,
209212
buildImage.obj,
210213
false,
@@ -236,6 +239,7 @@ describe('Import Submit Utils', () => {
236239
.mockImplementation(() => Promise.reject(new Error('PipelineRun error')));
237240

238241
const returnValue = await createOrUpdateResources(
242+
t,
239243
mockData,
240244
buildImage.obj,
241245
false,
@@ -259,7 +263,7 @@ describe('Import Submit Utils', () => {
259263
.mockImplementation(() => Promise.reject(new Error('Deployment')));
260264

261265
await expect(
262-
createOrUpdateResources(mockData, buildImage.obj, false, false, 'create'),
266+
createOrUpdateResources(t, mockData, buildImage.obj, false, false, 'create'),
263267
).rejects.toEqual(new Error('Deployment'));
264268
done();
265269
});
@@ -268,6 +272,7 @@ describe('Import Submit Utils', () => {
268272
const mockData = _.cloneDeep(defaultData);
269273

270274
const returnValue = await createOrUpdateResources(
275+
t,
271276
mockData,
272277
buildImage.obj,
273278
false,
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import * as React from 'react';
2+
import * as _ from 'lodash';
3+
import { useTranslation } from 'react-i18next';
4+
import { Alert, Form } from '@patternfly/react-core';
5+
import { FormikProps, FormikValues } from 'formik';
6+
import { FormFooter } from '@console/shared/src/components/form-utils';
7+
import { DevfileImportFormProps } from '../import-types';
8+
import GitSection from '../git/GitSection';
9+
import AppSection from '../app/AppSection';
10+
import { useDefileServer, useDevfileDirectoryWatcher } from './devfileHooks';
11+
12+
const DevfileImportForm: React.FC<FormikProps<FormikValues> & DevfileImportFormProps> = ({
13+
values,
14+
errors,
15+
handleSubmit,
16+
handleReset,
17+
status,
18+
builderImages,
19+
isSubmitting,
20+
dirty,
21+
projects,
22+
setFieldValue,
23+
}) => {
24+
const { t } = useTranslation();
25+
26+
const [, devfileParseError] = useDefileServer(values, setFieldValue);
27+
useDevfileDirectoryWatcher(values, setFieldValue);
28+
29+
return (
30+
<Form onSubmit={handleSubmit} data-test-id="import-devfile-form">
31+
{devfileParseError && (
32+
<Alert isInline variant="danger" title={t('devconsole~Import is not possible.')}>
33+
{devfileParseError}
34+
</Alert>
35+
)}
36+
<GitSection
37+
buildStrategy="Devfile"
38+
builderImages={builderImages}
39+
defaultSample={{ url: 'https://github.com/maysunfaisal/node-bulletin-board' }}
40+
/>
41+
<AppSection
42+
project={values.project}
43+
noProjectsAvailable={projects.loaded && _.isEmpty(projects.data)}
44+
/>
45+
<FormFooter
46+
handleReset={handleReset}
47+
errorMessage={status && status.submitError}
48+
isSubmitting={isSubmitting}
49+
submitLabel={t('devconsole~Create')}
50+
sticky
51+
disableSubmit={!dirty || !_.isEmpty(errors)}
52+
resetLabel={t('devconsole~Cancel')}
53+
/>
54+
</Form>
55+
);
56+
};
57+
58+
export default DevfileImportForm;

0 commit comments

Comments
 (0)