From 300256392c9d9397f3664a4ecd8370e39e18c7af Mon Sep 17 00:00:00 2001 From: Andrew Kundrock Date: Fri, 2 Dec 2022 15:34:11 -0700 Subject: [PATCH 1/7] Add field selection rendering of allowedProjects for BitbucketRepoPicker Signed-off-by: Andrew Kundrock --- .../bitbucket-demo/template.yaml | 10 ++++- .../BitbucketRepoPicker.test.tsx | 16 ++++++++ .../RepoUrlPicker/BitbucketRepoPicker.tsx | 41 +++++++++++++++---- .../fields/RepoUrlPicker/RepoUrlPicker.tsx | 16 +++++++- .../components/fields/RepoUrlPicker/schema.ts | 4 ++ 5 files changed, 77 insertions(+), 10 deletions(-) diff --git a/plugins/scaffolder-backend/sample-templates/bitbucket-demo/template.yaml b/plugins/scaffolder-backend/sample-templates/bitbucket-demo/template.yaml index ee1bc634b4..95854eaf84 100644 --- a/plugins/scaffolder-backend/sample-templates/bitbucket-demo/template.yaml +++ b/plugins/scaffolder-backend/sample-templates/bitbucket-demo/template.yaml @@ -20,7 +20,15 @@ spec: ui:options: allowedHosts: - bitbucket.org - - server.bitbucket.com + allowedOwners: + - WORKSPACE1 + - WORKSPACE2 + allowedProjects: + - PROJECT1 + - PROJECT2 + allowedRepos: + - REPO1 + - REPO2 - title: Fill in some steps required: - name diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx index fc643e7360..6fe93ce512 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx @@ -56,6 +56,22 @@ describe('BitbucketRepoPicker', () => { expect(getAllByRole('textbox')).toHaveLength(1); }); + + it('renders a select if there is a list of allowed projects', async () => { + const allowedProjects = ['project1', 'project2']; + const { findByText } = render( + , + ); + + expect(await findByText('project1')).toBeInTheDocument(); + expect(await findByText('project2')).toBeInTheDocument(); + }); + describe('workspace field', () => { it('calls onChange when the workspace changes', () => { const onChange = jest.fn(); diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx index 5bc1380553..75922a3efb 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx @@ -23,15 +23,25 @@ import { RepoUrlPickerState } from './types'; export const BitbucketRepoPicker = (props: { allowedOwners?: string[]; + allowedProjects?: string[]; onChange: (state: RepoUrlPickerState) => void; state: RepoUrlPickerState; rawErrors: string[]; }) => { - const { allowedOwners = [], onChange, rawErrors, state } = props; + const { + allowedOwners = [], + allowedProjects = [], + onChange, + rawErrors, + state, + } = props; const { host, workspace, project } = state; const ownerItems: SelectItem[] = allowedOwners ? allowedOwners?.map(i => ({ label: i, value: i })) : []; + const projectItems: SelectItem[] = allowedProjects + ? allowedProjects?.map(i => ({ label: i, value: i })) + : []; useEffect(() => { if (host === 'bitbucket.org' && allowedOwners.length) { @@ -69,7 +79,7 @@ export const BitbucketRepoPicker = (props: { )} - The Organization that this repo will belong to + The Workspace that this repo will belong to )} @@ -78,12 +88,27 @@ export const BitbucketRepoPicker = (props: { required error={rawErrors?.length > 0 && !project} > - Project - onChange({ project: e.target.value })} - value={project} - /> + {allowedProjects?.length ? ( + onChange({ project: e.target.value })} + value={project} + /> + + )} The Project that this repo will belong to diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx index 827eff6ea2..79b7f23da6 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx @@ -60,12 +60,16 @@ export const RepoUrlPicker = (props: RepoUrlPickerProps) => { () => uiSchema?.['ui:options']?.allowedOwners ?? [], [uiSchema], ); + const allowedProjects = useMemo( + () => uiSchema?.['ui:options']?.allowedProjects ?? [], + [uiSchema], + ); const allowedRepos = useMemo( () => uiSchema?.['ui:options']?.allowedRepos ?? [], [uiSchema], ); - const { owner, organization, repoName } = state; + const { owner, organization, project, repoName } = state; useEffect(() => { onChange(serializeRepoPickerUrl(state)); @@ -90,6 +94,15 @@ export const RepoUrlPicker = (props: RepoUrlPickerProps) => { } }, [setState, allowedOwners, owner]); + useEffect(() => { + if (allowedProjects.length > 0 && !project) { + setState(prevState => ({ + ...prevState, + project: allowedProjects[0], + })); + } + }, [setState, allowedProjects, project]); + useEffect(() => { if (allowedRepos.length > 0 && !repoName) { setState(prevState => ({ ...prevState, repoName: allowedRepos[0] })); @@ -169,6 +182,7 @@ export const RepoUrlPicker = (props: RepoUrlPickerProps) => { {hostType === 'bitbucket' && ( Date: Fri, 2 Dec 2022 15:42:52 -0700 Subject: [PATCH 2/7] Add changeset Signed-off-by: Andrew Kundrock --- .changeset/wet-tips-yawn.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/wet-tips-yawn.md diff --git a/.changeset/wet-tips-yawn.md b/.changeset/wet-tips-yawn.md new file mode 100644 index 0000000000..d4bc6726ce --- /dev/null +++ b/.changeset/wet-tips-yawn.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': minor +--- + +Add field selection rendering of allowedProjects for BitbucketRepoPicker. Allows a user to define allowed projects via the ui:field RepoUrlPicker ui:options allowedProjects From 531f0facea9c834a16409436a8bf5f859862e369 Mon Sep 17 00:00:00 2001 From: Andrew Kundrock Date: Fri, 2 Dec 2022 15:49:37 -0700 Subject: [PATCH 3/7] Update changeset Signed-off-by: Andrew Kundrock --- .changeset/wet-tips-yawn.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.changeset/wet-tips-yawn.md b/.changeset/wet-tips-yawn.md index d4bc6726ce..88a44e46fc 100644 --- a/.changeset/wet-tips-yawn.md +++ b/.changeset/wet-tips-yawn.md @@ -1,5 +1,6 @@ --- '@backstage/plugin-scaffolder': minor +'@backstage/plugin-scaffolder-backend': minor --- -Add field selection rendering of allowedProjects for BitbucketRepoPicker. Allows a user to define allowed projects via the ui:field RepoUrlPicker ui:options allowedProjects +Add field selection rendering of allowed Projects for BitbucketRepoPicker. Allows a user to define allowed projects via the ui:field RepoUrlPicker ui:options allowed Projects From 8f9864e8e217d36172c5cc2acfadfe2b0c5a9198 Mon Sep 17 00:00:00 2001 From: Andrew Kundrock Date: Fri, 2 Dec 2022 16:17:21 -0700 Subject: [PATCH 4/7] Update api-report Signed-off-by: Andrew Kundrock --- plugins/scaffolder/api-report.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/scaffolder/api-report.md b/plugins/scaffolder/api-report.md index 39e58a7a42..a8dcdd76ed 100644 --- a/plugins/scaffolder/api-report.md +++ b/plugins/scaffolder/api-report.md @@ -340,6 +340,7 @@ export const RepoUrlPickerFieldExtension: FieldExtensionComponent< { allowedOwners?: string[] | undefined; allowedOrganizations?: string[] | undefined; + allowedProjects?: string[] | undefined; allowedRepos?: string[] | undefined; allowedHosts?: string[] | undefined; requestUserCredentials?: @@ -365,6 +366,7 @@ export const RepoUrlPickerFieldSchema: FieldSchema< { allowedOwners?: string[] | undefined; allowedOrganizations?: string[] | undefined; + allowedProjects?: string[] | undefined; allowedRepos?: string[] | undefined; allowedHosts?: string[] | undefined; requestUserCredentials?: From afda8319d9af01c92b32d69d1f2bc76f2b5e4b07 Mon Sep 17 00:00:00 2001 From: Andrew Kundrock Date: Mon, 12 Dec 2022 20:07:26 -0700 Subject: [PATCH 5/7] Update test coverage and export docs Signed-off-by: Andrew Kundrock --- .changeset/wet-tips-yawn.md | 6 +- .../bitbucket-demo/template.yaml | 20 ++++--- .../BitbucketRepoPicker.test.tsx | 57 ++++++++++++++----- .../RepoUrlPicker/BitbucketRepoPicker.tsx | 9 +++ 4 files changed, 67 insertions(+), 25 deletions(-) diff --git a/.changeset/wet-tips-yawn.md b/.changeset/wet-tips-yawn.md index 88a44e46fc..3ab8303b8f 100644 --- a/.changeset/wet-tips-yawn.md +++ b/.changeset/wet-tips-yawn.md @@ -3,4 +3,8 @@ '@backstage/plugin-scaffolder-backend': minor --- -Add field selection rendering of allowed Projects for BitbucketRepoPicker. Allows a user to define allowed projects via the ui:field RepoUrlPicker ui:options allowed Projects +Add field selection rendering of allowed Projects for BitbucketRepoPicker. Allows a user to define allowed projects via the ui:field RepoUrlPicker ui:options allowed Projects. + +Add comments about expected values for BitbucketRepoPicker: Projects and workspaces + +Update tests to cover null, empty list, and list values for allowed Bitbucket projects diff --git a/plugins/scaffolder-backend/sample-templates/bitbucket-demo/template.yaml b/plugins/scaffolder-backend/sample-templates/bitbucket-demo/template.yaml index 95854eaf84..58955582d2 100644 --- a/plugins/scaffolder-backend/sample-templates/bitbucket-demo/template.yaml +++ b/plugins/scaffolder-backend/sample-templates/bitbucket-demo/template.yaml @@ -20,15 +20,17 @@ spec: ui:options: allowedHosts: - bitbucket.org - allowedOwners: - - WORKSPACE1 - - WORKSPACE2 - allowedProjects: - - PROJECT1 - - PROJECT2 - allowedRepos: - - REPO1 - - REPO2 + # The rest of these options are optional. + # You can read more at: https://backstage.io/docs/reference/plugin-scaffolder.repourlpickerfieldextension + # allowedOwners: + # - WORKSPACE1 + # - WORKSPACE2 + # allowedProjects: + # - PROJECT1 + # - PROJECT2 + # allowedRepos: + # - REPO1 + # - REPO2 - title: Fill in some steps required: - name diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx index 6fe93ce512..f799d68c2d 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx @@ -57,21 +57,6 @@ describe('BitbucketRepoPicker', () => { expect(getAllByRole('textbox')).toHaveLength(1); }); - it('renders a select if there is a list of allowed projects', async () => { - const allowedProjects = ['project1', 'project2']; - const { findByText } = render( - , - ); - - expect(await findByText('project1')).toBeInTheDocument(); - expect(await findByText('project2')).toBeInTheDocument(); - }); - describe('workspace field', () => { it('calls onChange when the workspace changes', () => { const onChange = jest.fn(); @@ -108,5 +93,47 @@ describe('BitbucketRepoPicker', () => { expect(onChange).toHaveBeenCalledWith({ project: 'test-project' }); }); + + it('Does not render a select if the list of allowed projects does not exist', async () => { + const { getAllByRole } = render( + , + ); + + expect(getAllByRole('textbox')).toHaveLength(2); + expect(getAllByRole('textbox')[1]).toHaveValue(''); + }); + + it('Does not render a select if the list of allowed projects is empty', async () => { + const { getAllByRole } = render( + , + ); + + expect(getAllByRole('textbox')).toHaveLength(2); + expect(getAllByRole('textbox')[1]).toHaveValue(''); + }); + + it('Does render a select if there is a list of allowed projects', async () => { + const allowedProjects = ['project1', 'project2']; + const { findByText } = render( + , + ); + + expect(await findByText('project1')).toBeInTheDocument(); + expect(await findByText('project2')).toBeInTheDocument(); + }); }); }); diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx index 75922a3efb..d070e3fee5 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx @@ -21,6 +21,15 @@ import InputLabel from '@material-ui/core/InputLabel'; import { Select, SelectItem } from '@backstage/core-components'; import { RepoUrlPickerState } from './types'; +/** + * The underlying component that is rendered in the form for the `BitbucketRepoPicker` + * field extension. + * + * @public + * @param allowedOwners - Allowed workspaces for the Bitbucket cloud repository + * @param allowedProjects - Allowed projects for the Bitbucket cloud repository + * + */ export const BitbucketRepoPicker = (props: { allowedOwners?: string[]; allowedProjects?: string[]; From abe2a77501a2d7e0784bc7c2458b7da07fc9abc7 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 13 Dec 2022 17:00:22 +0100 Subject: [PATCH 6/7] Update .changeset/wet-tips-yawn.md Signed-off-by: Patrik Oldsberg --- .changeset/wet-tips-yawn.md | 1 - 1 file changed, 1 deletion(-) diff --git a/.changeset/wet-tips-yawn.md b/.changeset/wet-tips-yawn.md index 3ab8303b8f..0e1bb7aef6 100644 --- a/.changeset/wet-tips-yawn.md +++ b/.changeset/wet-tips-yawn.md @@ -1,6 +1,5 @@ --- '@backstage/plugin-scaffolder': minor -'@backstage/plugin-scaffolder-backend': minor --- Add field selection rendering of allowed Projects for BitbucketRepoPicker. Allows a user to define allowed projects via the ui:field RepoUrlPicker ui:options allowed Projects. From 3e2e13d7a20b69817403d58e50912ad6a0464379 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 13 Dec 2022 17:00:58 +0100 Subject: [PATCH 7/7] Update .changeset/wet-tips-yawn.md Signed-off-by: Patrik Oldsberg --- .changeset/wet-tips-yawn.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.changeset/wet-tips-yawn.md b/.changeset/wet-tips-yawn.md index 0e1bb7aef6..63f3c9dd2e 100644 --- a/.changeset/wet-tips-yawn.md +++ b/.changeset/wet-tips-yawn.md @@ -2,8 +2,4 @@ '@backstage/plugin-scaffolder': minor --- -Add field selection rendering of allowed Projects for BitbucketRepoPicker. Allows a user to define allowed projects via the ui:field RepoUrlPicker ui:options allowed Projects. - -Add comments about expected values for BitbucketRepoPicker: Projects and workspaces - -Update tests to cover null, empty list, and list values for allowed Bitbucket projects +The `RepoUrlPicker` field extension now has an `allowedProjects` option for narrowing the selection of Bitbucket URLs.