Merge pull request #20899 from ch007m/issue-13873

WIP. Adding the Gitea RepoUrlPicker
This commit is contained in:
Ben Lambert
2023-12-14 14:44:41 +01:00
committed by GitHub
8 changed files with 137 additions and 1 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder': minor
---
Add a new git repository url picker for `gitea`. This `GiteaRepoPicker` can be used in a template to scaffold a project to be cloned using gitea.
+2
View File
@@ -379,6 +379,7 @@ export const RepoUrlPickerFieldExtension: FieldExtensionComponent_2<
secretsKey: string;
additionalScopes?:
| {
gitea?: string[] | undefined;
gerrit?: string[] | undefined;
github?: string[] | undefined;
gitlab?: string[] | undefined;
@@ -405,6 +406,7 @@ export const RepoUrlPickerFieldSchema: FieldSchema<
secretsKey: string;
additionalScopes?:
| {
gitea?: string[] | undefined;
gerrit?: string[] | undefined;
github?: string[] | undefined;
gitlab?: string[] | undefined;
+1
View File
@@ -107,6 +107,7 @@ export class ScaffolderClient implements ScaffolderApi {
...this.scmIntegrationsApi.bitbucketCloud.list(),
...this.scmIntegrationsApi.bitbucketServer.list(),
...this.scmIntegrationsApi.gerrit.list(),
...this.scmIntegrationsApi.gitea.list(),
...this.scmIntegrationsApi.github.list(),
...this.scmIntegrationsApi.gitlab.list(),
]
@@ -0,0 +1,40 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import { GiteaRepoPicker } from './GiteaRepoPicker';
import { render, fireEvent } from '@testing-library/react';
describe('GiteaRepoPicker', () => {
describe('owner input field', () => {
it('calls onChange when the owner input changes', () => {
const onChange = jest.fn();
const { getAllByRole } = render(
<GiteaRepoPicker
onChange={onChange}
rawErrors={[]}
state={{ host: 'gitea.com' }}
/>,
);
const ownerInput = getAllByRole('textbox')[0];
fireEvent.change(ownerInput, { target: { value: 'test-owner' } });
expect(onChange).toHaveBeenCalledWith({ owner: 'test-owner' });
});
});
});
@@ -0,0 +1,75 @@
/*
* Copyright 2021 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import FormControl from '@material-ui/core/FormControl';
import FormHelperText from '@material-ui/core/FormHelperText';
import Input from '@material-ui/core/Input';
import InputLabel from '@material-ui/core/InputLabel';
import { Select, SelectItem } from '@backstage/core-components';
import { RepoUrlPickerState } from './types';
export const GiteaRepoPicker = (props: {
allowedOwners?: string[];
allowedRepos?: string[];
state: RepoUrlPickerState;
onChange: (state: RepoUrlPickerState) => void;
rawErrors: string[];
}) => {
const { allowedOwners = [], state, onChange, rawErrors } = props;
const ownerItems: SelectItem[] = allowedOwners
? allowedOwners.map(i => ({ label: i, value: i }))
: [{ label: 'Loading...', value: 'loading' }];
const { owner } = state;
return (
<>
<FormControl
margin="normal"
required
error={rawErrors?.length > 0 && !owner}
>
{allowedOwners?.length ? (
<Select
native
label="Owner Available"
onChange={selected =>
onChange({
owner: String(Array.isArray(selected) ? selected[0] : selected),
})
}
disabled={allowedOwners.length === 1}
selected={owner}
items={ownerItems}
/>
) : (
<>
<InputLabel htmlFor="ownerInput">Owner</InputLabel>
<Input
id="ownerInput"
onChange={e => onChange({ owner: e.target.value })}
value={owner}
/>
</>
)}
<FormHelperText>
Gitea namespace where this repository will belong to. It can be the
name of organization, group, subgroup, user, or the project.
</FormHelperText>
</FormControl>
</>
);
};
@@ -20,6 +20,7 @@ import {
} from '@backstage/integration-react';
import React, { useEffect, useState, useMemo, useCallback } from 'react';
import { GithubRepoPicker } from './GithubRepoPicker';
import { GiteaRepoPicker } from './GiteaRepoPicker';
import { GitlabRepoPicker } from './GitlabRepoPicker';
import { AzureRepoPicker } from './AzureRepoPicker';
import { BitbucketRepoPicker } from './BitbucketRepoPicker';
@@ -183,6 +184,15 @@ export const RepoUrlPicker = (props: RepoUrlPickerProps) => {
state={state}
/>
)}
{hostType === 'gitea' && (
<GiteaRepoPicker
allowedOwners={allowedOwners}
allowedRepos={allowedRepos}
rawErrors={rawErrors}
state={state}
onChange={updateLocalState}
/>
)}
{hostType === 'gitlab' && (
<GitlabRepoPicker
allowedOwners={allowedOwners}
@@ -51,6 +51,10 @@ export const RepoUrlPickerFieldSchema = makeFieldSchemaFromZod(
),
additionalScopes: z
.object({
gitea: z
.array(z.string())
.optional()
.describe('Additional Gitea scopes to request'),
gerrit: z
.array(z.string())
.optional()
@@ -64,6 +64,5 @@ export function parseRepoPickerUrl(
} catch {
/* ok */
}
return { host, owner, repoName, organization, workspace, project };
}