Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(import): backport-add-gitlab-annotations #47

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion src/components/ImportForm/ComponentSection/GitOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,24 @@ import * as React from 'react';
import { ExpandableSection, FormSection, PageSection } from '@patternfly/react-core';
import { InputField } from 'formik-pf';
import HelpPopover from '../../HelpPopover';
import { GitProviderDropdown } from './GitProviderDropdown';

const GitOptions: React.FC<React.PropsWithChildren<unknown>> = () => {
type GitOptionProps = {
isGitAdvancedOpen: boolean;
setGitAdvancedOpen: (x) => void;
};

const GitOptions: React.FC<React.PropsWithChildren<GitOptionProps>> = ({
isGitAdvancedOpen,
setGitAdvancedOpen,
}) => {
return (
<ExpandableSection
toggleTextExpanded="Hide advanced Git options"
toggleTextCollapsed="Show advanced Git options"
data-test="advanced-git-options"
isExpanded={isGitAdvancedOpen}
onToggle={() => setGitAdvancedOpen((x) => !x)}
>
<PageSection>
<FormSection>
Expand All @@ -27,6 +39,12 @@ const GitOptions: React.FC<React.PropsWithChildren<unknown>> = () => {
<HelpPopover bodyContent="Make sure this path is correct. You might get an error if your build context folder is your root directory but your Dockerfile is in a subdirectory of that folder." />
}
/>
<GitProviderDropdown name="gitProviderAnnotation" />
<InputField
name="gitURLAnnotation"
label="Git url annotation"
data-test="url-annotation"
/>
</FormSection>
</PageSection>
</ExpandableSection>
Expand Down
34 changes: 34 additions & 0 deletions src/components/ImportForm/ComponentSection/GitProviderDropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import { useField } from 'formik';
import DropdownField from '../../../shared/components/formik-fields/DropdownField';
import { GIT_PROVIDER_ANNOTATION_VALUE } from '../../../utils/component-utils';

type GitProviderDropdownProps = Omit<
React.ComponentProps<typeof DropdownField>,
'items' | 'label' | 'placeholder'
>;

export const GitProviderDropdown: React.FC<React.PropsWithChildren<GitProviderDropdownProps>> = (
props,
) => {
const [{ value }, , { setValue }] = useField<string>(props.name);

const dropdownItems = [
{ key: GIT_PROVIDER_ANNOTATION_VALUE.GITHUB, value: GIT_PROVIDER_ANNOTATION_VALUE.GITHUB },
{ key: GIT_PROVIDER_ANNOTATION_VALUE.GITLAB, value: GIT_PROVIDER_ANNOTATION_VALUE.GITLAB },
{ key: GIT_PROVIDER_ANNOTATION_VALUE.OTHERS, value: GIT_PROVIDER_ANNOTATION_VALUE.OTHERS },
];

return (
<div className="pf-v5-u-mb-md">
<DropdownField
{...props}
label="Git provider annotation"
placeholder={'Select git provider'}
value={value}
items={dropdownItems}
onChange={(provider: string) => setValue(provider)}
/>
</div>
);
};
38 changes: 32 additions & 6 deletions src/components/ImportForm/ComponentSection/SourceSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
import { useField, useFormikContext } from 'formik';
import { InputField, SwitchField } from 'formik-pf';
import GitUrlParse from 'git-url-parse';
import { detectGitType, GitProvider } from '../../../shared/utils/git-utils';
import { GIT_PROVIDER_ANNOTATION_VALUE } from '../../../utils/component-utils';
import { ImportFormValues } from '../type';
import GitOptions from './GitOptions';

export const SourceSection = () => {
const [, { touched, error }] = useField('source.git.url');
const [isGitAdvancedOpen, setGitAdvancedOpen] = React.useState<boolean>(false);
const { touched: touchedValues, setFieldValue } = useFormikContext<ImportFormValues>();
const validated = touched
? touched && !error
Expand All @@ -16,19 +19,40 @@
: ValidatedOptions.default;

const handleChange = React.useCallback(
(event) => {
if (validated && !touchedValues.componentName) {
async (event) => {
if (validated) {
const gitType = detectGitType(event.target?.value as string);
if (gitType !== GitProvider.GITHUB && gitType !== GitProvider.GITLAB) {
await setFieldValue('gitProviderAnnotation', '');
setGitAdvancedOpen(true);
}
if (gitType === GitProvider.GITHUB) {
await setFieldValue('gitProviderAnnotation', GIT_PROVIDER_ANNOTATION_VALUE.GITHUB);
setGitAdvancedOpen(false);
}
if (gitType === GitProvider.GITLAB) {
await setFieldValue('gitProviderAnnotation', GIT_PROVIDER_ANNOTATION_VALUE.GITLAB);
setGitAdvancedOpen(false);

Check warning on line 35 in src/components/ImportForm/ComponentSection/SourceSection.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/ImportForm/ComponentSection/SourceSection.tsx#L35

Added line #L35 was not covered by tests
}

let parsed: GitUrlParse.GitUrl;

Check warning on line 38 in src/components/ImportForm/ComponentSection/SourceSection.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/ImportForm/ComponentSection/SourceSection.tsx#L38

Added line #L38 was not covered by tests
let name: string;
try {
name = GitUrlParse(event.target?.value ?? '').name;
parsed = GitUrlParse(event.target?.value ?? '');
await setFieldValue('gitURLAnnotation', parsed?.resource);
name = parsed.name;
} catch {
name = '';
await setFieldValue('gitURLAnnotation', '');
}
if (!touchedValues.componentName) {
await setFieldValue('componentName', name);
}
void setFieldValue('componentName', name);
}
},
[setFieldValue, touchedValues.componentName, validated],
);

return (
<>
<InputField
Expand All @@ -37,13 +61,15 @@
placeholder="Enter your source"
validated={validated}
isRequired
data-test="enter-source"
data-testid="enter-source"
onChange={handleChange}
/>
{validated === ValidatedOptions.success ? (
<SwitchField name="isPrivateRepo" label="Should the image produced be private?" />
) : null}
{validated === ValidatedOptions.success ? <GitOptions /> : null}
{validated === ValidatedOptions.success ? (
<GitOptions isGitAdvancedOpen={isGitAdvancedOpen} setGitAdvancedOpen={setGitAdvancedOpen} />
) : null}
</>
);
};
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { screen, waitFor } from '@testing-library/react';
import { screen, waitFor, configure } from '@testing-library/react';
import { userEvent } from '@testing-library/user-event';
import { formikRenderer } from '../../../../utils/test-utils';
import { ComponentSection } from '../ComponentSection';
import '@testing-library/jest-dom';

configure({ testIdAttribute: 'data-test' });

describe('ComponentSection', () => {
it('should render component section', () => {
formikRenderer(<ComponentSection />, { source: { git: { url: '' } } });
Expand All @@ -22,19 +24,43 @@ describe('ComponentSection', () => {
await user.tab();
await waitFor(() => screen.getByText('Show advanced Git options'));
});
it('should get private image repo switch when git src is ready', async () => {

it('should expand git options if source url is others', async () => {
formikRenderer(<ComponentSection />, {
source: { git: { url: '' } },
});
const user = userEvent.setup();
const source = screen.getByPlaceholderText('Enter your source');

await user.type(source, 'https://github.com/abcd/repo.git');
await user.type(source, 'https://bitbucket.com/abcd/repo.git');
await user.tab();
await waitFor(() => screen.getByText('Hide advanced Git options'));
});

it('should show advanced Annotation section', async () => {
formikRenderer(<ComponentSection />, {
source: { git: { url: '' } },
});
const user = userEvent.setup();
const source = screen.getByPlaceholderText('Enter your source');

await user.type(source, 'https://bitbucket.com/abcd/repo.git');
await user.tab();
await waitFor(() => screen.getByTestId('url-annotation'));
});

it('should populate annotation fields', async () => {
formikRenderer(<ComponentSection />, {
source: { git: { url: '' } },
});
const user = userEvent.setup();
const source = screen.getByPlaceholderText('Enter your source');

const switchCheckbox = screen.getByLabelText('Should the image produced be private?');
expect(switchCheckbox).not.toBeChecked();
await user.click(switchCheckbox);
expect(switchCheckbox).toBeChecked();
await user.type(source, 'https://gitlab.com/abcd/repo.git');
await user.tab();
await waitFor(() =>
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
expect((screen.getByTestId('url-annotation') as HTMLInputElement).value).toBe('gitlab.com'),
);
});
});
2 changes: 2 additions & 0 deletions src/components/ImportForm/GitImportForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export const GitImportForm: React.FC<{ applicationName: string }> = ({ applicati
inAppContext: !!applicationName,
showComponent: !!applicationName,
componentName: '',
gitProviderAnnotation: '',
gitURLAnnotation: '',
isPrivateRepo: false,
source: {
git: {
Expand Down
6 changes: 4 additions & 2 deletions src/components/ImportForm/submit-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ export const createResources = async (
source,
application,
componentName,
gitProviderAnnotation,
gitURLAnnotation,
inAppContext,
importSecrets = [],
pipeline,
Expand All @@ -66,7 +68,7 @@ export const createResources = async (
}
if (showComponent) {
await createComponent(
{ componentName, application, source },
{ componentName, application, source, gitProviderAnnotation, gitURLAnnotation },
applicationName,
namespace,
workspace,
Expand Down Expand Up @@ -102,7 +104,7 @@ export const createResources = async (
await createSecrets(importSecrets, workspace, namespace, true);

createdComponent = await createComponent(
{ componentName, application, source },
{ componentName, application, gitProviderAnnotation, source, gitURLAnnotation },
applicationName,
namespace,
workspace,
Expand Down
2 changes: 2 additions & 0 deletions src/components/ImportForm/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export type ImportFormValues = {
inAppContext: boolean;
showComponent: boolean;
componentName: string;
gitProviderAnnotation?: string;
gitURLAnnotation?: string;
isPrivateRepo: boolean;
source: {
git: {
Expand Down
2 changes: 2 additions & 0 deletions src/types/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export enum NudgeStats {

export type ComponentSpecs = {
componentName: string;
gitProviderAnnotation?: string;
gitURLAnnotation?: string;
application: string;
secret?: string;
source?: ComponentSource;
Expand Down
8 changes: 8 additions & 0 deletions src/utils/component-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ export const BUILD_REQUEST_ANNOTATION = 'build.appstudio.openshift.io/request';

export const BUILD_STATUS_ANNOTATION = 'build.appstudio.openshift.io/status';

export const GIT_PROVIDER_ANNOTATION = 'git-provider';
export const GIT_PROVIDER_ANNOTATION_VALUE = {
GITHUB: 'github',
GITLAB: 'gitlab',
OTHERS: 'others',
};
export const GITLAB_PROVIDER_URL_ANNOTATION = 'git-provider-url';

export enum ComponentBuildState {
enabled = 'enabled',
disabled = 'disabled',
Expand Down
29 changes: 25 additions & 4 deletions src/utils/create-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@
ImageRepositoryVisibility,
} from '../types';
import { ComponentSpecs } from './../types/component';
import { BUILD_REQUEST_ANNOTATION, BuildRequest } from './component-utils';
import {
BuildRequest,
BUILD_REQUEST_ANNOTATION,
GIT_PROVIDER_ANNOTATION,
GITLAB_PROVIDER_URL_ANNOTATION,
} from './component-utils';

export const sanitizeName = (name: string) => name.split(/ |\./).join('-').toLowerCase();

Expand Down Expand Up @@ -104,7 +109,17 @@
enablePac: boolean = true,
annotations?: { [key: string]: string },
) => {
const { componentName, containerImage, source, replicas, resources, env, targetPort } = component;
const {
componentName,
gitProviderAnnotation,
gitURLAnnotation,
containerImage,
source,
replicas,
resources,
env,
targetPort,
} = component;

Check warning on line 122 in src/utils/create-utils.ts

View check run for this annotation

Codecov / codecov/patch

src/utils/create-utils.ts#L122

Added line #L122 was not covered by tests

const name = component.componentName.split(/ |\./).join('-').toLowerCase();

Expand Down Expand Up @@ -140,8 +155,14 @@
verb === 'update' ? { ...originalComponent, spec: newComponent.spec } : newComponent;

// merge additional annotations
if (annotations) {
resource.metadata.annotations = { ...resource.metadata.annotations, ...annotations };
if (annotations || gitProviderAnnotation || gitURLAnnotation) {
// Add gitlab annotaions in case of gitlab repo
const newAnnotations = annotations;
if (gitProviderAnnotation || gitURLAnnotation) {
newAnnotations[GIT_PROVIDER_ANNOTATION] = gitProviderAnnotation;
newAnnotations[GITLAB_PROVIDER_URL_ANNOTATION] = gitURLAnnotation;
}
resource.metadata.annotations = { ...resource.metadata.annotations, ...newAnnotations };
}

return verb === 'create'
Expand Down
Loading