Skip to content

Commit

Permalink
Merge pull request #12593 from lokanandaprabhu/feature/OCPBUGS-7036
Browse files Browse the repository at this point in the history
OCPBUGS-7036: Add Git Repository (PAC) doesn't setup GitLab and Bitbucket configuration correct
  • Loading branch information
openshift-merge-robot committed Jun 20, 2023
2 parents 0f3c181 + 36f456e commit 0742e71
Show file tree
Hide file tree
Showing 11 changed files with 137 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { GitProvider } from '@console/git-service/src';
import { defaultRepositoryFormValues } from '@console/pipelines-plugin/src/components/repository/consts';
import { healthChecksProbeInitialData } from '../../health-checks/health-checks-probe-utils';
import { GitImportFormData, Resources } from '../import-types';
import { serverlessInitialValues } from './serverless-mock';
Expand Down Expand Up @@ -91,4 +92,10 @@ export const mockFormData: GitImportFormData = {
},
},
healthChecks: healthChecksProbeInitialData,
pac: {
pacHasError: false,
repository: {
...defaultRepositoryFormValues,
},
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { TFunction } from 'i18next';
import * as _ from 'lodash';
import * as yup from 'yup';
import { GitProvider } from '@console/git-service/src';
import { importFlowRepositoryValidationSchema } from '@console/pipelines-plugin/src/components/repository/repository-form-utils';
import { nameValidationSchema, nameRegex, resourceNameRegex } from '@console/shared';
import { healthChecksProbesValidationSchema } from '../health-checks/health-checks-probe-validation-utils';
import {
Expand Down Expand Up @@ -36,6 +37,7 @@ export const validationSchema = (t: TFunction) =>
build: buildValidationSchema,
resources: resourcesValidationSchema,
healthChecks: healthChecksProbesValidationSchema(t),
pac: importFlowRepositoryValidationSchema(t),
});

const hasDomain = (url: string, domain: string): boolean => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ export const isInteger = (message) => ({
},
message,
});

export const bitBucketUserNameRegex = /^[a-z]([a-z0-9_]-?)*[a-z0-9]$/;
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,8 @@
"Last run duration": "Last run duration",
"Name must consist of lower case alphanumeric characters, hyphens or dots, and must start and end with an alphanumeric character.": "Name must consist of lower case alphanumeric characters, hyphens or dots, and must start and end with an alphanumeric character.",
"Invalid Git URL.": "Invalid Git URL.",
"Name must consist of lower-case letters, numbers, underscores and hyphens. It must start with a letter and end with a letter or number.": "Name must consist of lower-case letters, numbers, underscores and hyphens. It must start with a letter and end with a letter or number.",
"Name must consist of lower-case letters, numbers and hyphens. It must start with a letter and end with a letter or number.": "Name must consist of lower-case letters, numbers and hyphens. It must start with a letter and end with a letter or number.",
"Repository details": "Repository details",
"Git access token": "Git access token",
"Webhook URL": "Webhook URL",
Expand Down Expand Up @@ -385,6 +387,7 @@
"use your Gitlab Personal access token. Use this <2>link</2> to create a token with api scope and give your token an expiration i.e 30d.": "use your Gitlab Personal access token. Use this <2>link</2> to create a token with api scope and give your token an expiration i.e 30d.",
"use your Bitbucket App password. Use this <2>link</2> to create a token with Read and Write scopes in Account, Workspace membership, Projects, Issues, Pull requests and give your token an expiration i.e 30d.": "use your Bitbucket App password. Use this <2>link</2> to create a token with Read and Write scopes in Account, Workspace membership, Projects, Issues, Pull requests and give your token an expiration i.e 30d.",
"Use your Git Personal token. Create a token with repo, public_repo & admin:repo_hook scopes and give your token an expiration, i.e 30d.": "Use your Git Personal token. Create a token with repo, public_repo & admin:repo_hook scopes and give your token an expiration, i.e 30d.",
"Bitbucket username": "Bitbucket username",
"Git access token secret": "Git access token secret",
"Secret with the Git access token for pulling pipeline and tasks from your Git repository.": "Secret with the Git access token for pulling pipeline and tasks from your Git repository.",
"Select a secret": "Select a secret",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { usePacInfo } from '@console/pipelines-plugin/src/components/repository/
import { recommendRepositoryName } from '@console/pipelines-plugin/src/components/repository/repository-form-utils';
import ConfigTypeSection from '@console/pipelines-plugin/src/components/repository/sections/ConfigTypeSection';
import WebhookSection from '@console/pipelines-plugin/src/components/repository/sections/WebhookSection';
import { PacConfigurationTypes } from '../../repository/consts';
import InfoPanel from './PacInfoPanel';
import './PacSection.scss';

Expand All @@ -24,6 +25,9 @@ const PacSection: React.FC = () => {
if (loaded && !!pac && pac.data['app-link']) {
setGithubAppAvailable(true);
setFieldValue('pac.repository.githubAppAvailable', true);
setFieldValue('pac.repository.method', PacConfigurationTypes.GITHUB);
} else {
setFieldValue('pac.repository.method', PacConfigurationTypes.WEBHOOK);
}
}, [pac, loaded, setFieldValue]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,11 @@ const PipelineTemplate: React.FC<PipelineTemplateProps> = ({ builderImages, exis
setIsPacRepo(true);
setFieldValue('pipeline.enabled', true);
setFieldValue('pipeline.type', PipelineType.PAC);
setFieldValue('pac.repository.gitUrl', url);
} else {
setFieldValue('pipeline.enabled', false);
setFieldValue('pipeline.type', PipelineType.PIPELINE);
setFieldValue('pac.repository.gitUrl', '');
}
setIsPipelineTypeChanged(true);
}, [url, type, ref, dir, secretResource, isRepositoryEnabled, setFieldValue]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export const defaultRepositoryFormValues: RepositoryFormValues = {
method: 'token',
secret: '',
url: '',
user: '',
},
};

Expand All @@ -75,3 +76,5 @@ export const WebhookDocLinks = {
'https://docs.gitlab.com/ee/user/project/integrations/webhooks.html#configure-a-webhook-in-gitlab',
[GitProvider.BITBUCKET]: 'https://support.atlassian.com/bitbucket-cloud/docs/manage-webhooks/',
};

export const gitProviderTypesHosts = ['github.com', 'bitbucket.org', 'gitlab.com'];
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Base64 } from 'js-base64';
import * as _ from 'lodash';
import * as yup from 'yup';
import { gitUrlRegex } from '@console/dev-console/src/components/import/validation-schema';
import { bitBucketUserNameRegex } from '@console/dev-console/src/utils/yup-validation-util';
import {
k8sCreateResource,
k8sGetResource,
Expand All @@ -18,7 +19,7 @@ import { nameRegex } from '@console/shared/src';
import { RepositoryModel } from '../../models';
import { PAC_TEMPLATE_DEFAULT } from '../pac/const';
import { PIPELINERUN_TEMPLATE_NAMESPACE } from '../pipelines/const';
import { RepositoryRuntimes } from './consts';
import { RepositoryRuntimes, gitProviderTypesHosts } from './consts';
import { RepositoryFormValues } from './types';

export const dryRunOpt = { dryRun: 'All' };
Expand All @@ -39,8 +40,76 @@ export const repositoryValidationSchema = (t: TFunction) =>
.matches(gitUrlRegex, t('pipelines-plugin~Invalid Git URL.'))
.required(t('pipelines-plugin~Required')),
accessToken: yup.string(),
webhook: yup
.object()
.when('gitProvider', {
is: GitProvider.BITBUCKET,
then: yup.object().shape({
user: yup
.string()
.matches(bitBucketUserNameRegex, {
message: t(
'pipelines-plugin~Name must consist of lower-case letters, numbers, underscores and hyphens. It must start with a letter and end with a letter or number.',
),
excludeEmptyString: true,
})
.required(t('pipelines-plugin~Required')),
}),
})
.when(['method', 'gitProvider', 'gitUrl'], {
is: (method, gitProvider, gitUrl) =>
gitUrl && !(gitProvider === GitProvider.GITHUB && method === GitProvider.GITHUB),
then: yup.object().shape({
token: yup.string().test('oneOfRequired', 'Required', function () {
return this.parent.token || this.parent.secretRef;
}),
secretRef: yup.string().test('oneOfRequired', 'Required', function () {
return this.parent.token || this.parent.secretRef;
}),
}),
}),
});

export const pipelinesAccessTokenValidationSchema = (t: TFunction) =>
yup.object().shape({
webhook: yup
.object()
.when('gitProvider', {
is: GitProvider.BITBUCKET,
then: yup.object().shape({
user: yup
.string()
.matches(nameRegex, {
message: t(
'pipelines-plugin~Name must consist of lower-case letters, numbers and hyphens. It must start with a letter and end with a letter or number.',
),
excludeEmptyString: true,
})
.required(t('pipelines-plugin~Required')),
}),
})
.when(['method', 'gitProvider', 'gitUrl'], {
is: (method, gitProvider, gitUrl) =>
gitUrl &&
gitProvider &&
!(gitProvider === GitProvider.GITHUB && method === GitProvider.GITHUB),
then: yup.object().shape({
token: yup.string().test('oneOfRequired', 'Required', function () {
return this.parent.token || this.parent.secretRef;
}),
secretRef: yup.string().test('oneOfRequired', 'Required', function () {
return this.parent.token || this.parent.secretRef;
}),
}),
}),
});

export const importFlowRepositoryValidationSchema = (t: TFunction) => {
return yup.object().shape({
repository: pipelinesAccessTokenValidationSchema(t),
});
};

const createTokenSecret = async (
repositoryName: string,
token: string,
Expand Down Expand Up @@ -79,7 +148,7 @@ export const createRepositoryResources = async (
const {
name,
gitUrl,
webhook: { secretObj, method, token, secret: webhookSecret },
webhook: { secretObj, method, token, secret: webhookSecret, user },
} = values;
const encodedSecret = Base64.encode(webhookSecret);
let secret: SecretKind;
Expand Down Expand Up @@ -112,7 +181,12 @@ export const createRepositoryResources = async (
? {
// eslint-disable-next-line @typescript-eslint/naming-convention
git_provider: {
...(gitHost !== 'github.com' ? { url: gitHost } : {}),
...(!gitProviderTypesHosts.includes(gitHost) ? { url: gitHost } : {}),
...(gitHost === 'bitbucket.org'
? {
user,
}
: {}),
...(secretRef
? {
secret: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ExpandableSection } from '@patternfly/react-core';
import { useFormikContext } from 'formik';
import { useTranslation } from 'react-i18next';
import { GitProvider } from '@console/git-service';
import { PacConfigurationTypes } from '../consts';
import { usePacInfo } from '../hooks/pac-hook';
import { RepositoryFormValues } from '../types';
import ConfigTypeSection from './ConfigTypeSection';
Expand All @@ -18,6 +19,9 @@ const AdvancedConfigurations = () => {
if (loaded && !!pac && pac.data['app-link']) {
setGithubAppAvailable(true);
setFieldValue('githubAppAvailable', true);
setFieldValue('method', PacConfigurationTypes.GITHUB);
} else {
setFieldValue('method', PacConfigurationTypes.WEBHOOK);
}
}, [pac, loaded, setFieldValue]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,18 @@ const WebhookSection: React.FC<WebhoookSectionProps> = ({ pac, formContextField

return (
<FormSection fullWidth={!fieldPrefix} extraMargin>
{gitProvider && gitProvider === GitProvider.BITBUCKET ? (
<InputField
label={t('pipelines-plugin~Bitbucket username')}
name={`${fieldPrefix}webhook.user`}
type={TextInputTypes.text}
required
/>
) : null}
<RadioGroupField
name={`${fieldPrefix}webhook.method`}
label={t('pipelines-plugin~Secret')}
required
options={[
{
value: 'token',
Expand Down Expand Up @@ -210,24 +219,29 @@ const WebhookSection: React.FC<WebhoookSectionProps> = ({ pac, formContextField
</FormGroup>
)}

<FormGroup fieldId={'webhook-secret-clipboard'} label={t('pipelines-plugin~Webhook secret')}>
<InputGroup style={{ display: 'flex' }}>
<ClipboardCopy
name={`${fieldPrefix}webhook.secret`}
hoverTip="Copy"
clickTip="Copied"
style={{ flex: '1' }}
onChange={(v) => {
setFieldValue(`${fieldPrefix}webhook.secret`, v);
}}
>
{webhookSecret}
</ClipboardCopy>
<Button data-test="generate-secret" variant="control" onClick={generateWebhookSecret}>
{t('pipelines-plugin~Generate')}
</Button>
</InputGroup>
</FormGroup>
{gitProvider && gitProvider !== GitProvider.BITBUCKET ? (
<FormGroup
fieldId={'webhook-secret-clipboard'}
label={t('pipelines-plugin~Webhook secret')}
>
<InputGroup style={{ display: 'flex' }}>
<ClipboardCopy
name={`${fieldPrefix}webhook.secret`}
hoverTip="Copy"
clickTip="Copied"
style={{ flex: '1' }}
onChange={(v) => {
setFieldValue(`${fieldPrefix}webhook.secret`, v);
}}
>
{webhookSecret}
</ClipboardCopy>
<Button data-test="generate-secret" variant="control" onClick={generateWebhookSecret}>
{t('pipelines-plugin~Generate')}
</Button>
</InputGroup>
</FormGroup>
) : null}

{gitProvider && gitProvider !== GitProvider.UNSURE ? (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@ export type RepositoryFormValues = {
secret: string;
url: string;
secretObj?: SecretKind;
user?: string;
};
};

0 comments on commit 0742e71

Please sign in to comment.