WIP. Create action to publish on gitea server
Signed-off-by: cmoulliard <cmoulliard@redhat.com>
This commit is contained in:
@@ -20,7 +20,7 @@ import yaml from 'yaml';
|
||||
export const examples: TemplateExample[] = [
|
||||
{
|
||||
description:
|
||||
'Initializes a Gitea repository of contents in workspace and publish it to Gitea with default configuration.',
|
||||
'Initializes a Gitea repository using the content of the workspace and publish it to Gitea with default configuration.',
|
||||
example: yaml.stringify({
|
||||
steps: [
|
||||
{
|
||||
@@ -52,7 +52,7 @@ export const examples: TemplateExample[] = [
|
||||
},
|
||||
{
|
||||
description:
|
||||
'Initializes a Gitea repository with a default Branch, if not set defaults to master',
|
||||
'Initializes a Gitea repository with a default Branch, if not set defaults to main',
|
||||
example: yaml.stringify({
|
||||
steps: [
|
||||
{
|
||||
@@ -61,7 +61,7 @@ export const examples: TemplateExample[] = [
|
||||
name: 'Publish to Gitea',
|
||||
input: {
|
||||
repoUrl: 'gitea.com?repo=repo&owner=owner',
|
||||
defaultBranch: 'staging',
|
||||
defaultBranch: 'main',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -14,36 +14,103 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { PassThrough } from 'stream';
|
||||
import { createAcmeExampleAction } from './gitea';
|
||||
/* import {rest} from 'msw';*/
|
||||
import { setupServer } from 'msw';
|
||||
import { setupRequestMockHandlers } from '@backstage/backend-test-utils';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { getVoidLogger } from '@backstage/backend-common';
|
||||
import { createPublishGiteaAction } from './gitea';
|
||||
import { initRepoAndPush } from '@backstage/plugin-scaffolder-node';
|
||||
|
||||
describe('acme:example', () => {
|
||||
afterEach(() => {
|
||||
jest.mock('@backstage/plugin-scaffolder-node', () => {
|
||||
return {
|
||||
...jest.requireActual('@backstage/plugin-scaffolder-node'),
|
||||
initRepoAndPush: jest.fn().mockResolvedValue({
|
||||
commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6',
|
||||
}),
|
||||
commitAndPushRepo: jest.fn().mockResolvedValue({
|
||||
commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6',
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('publish:gitea', () => {
|
||||
const config = new ConfigReader({
|
||||
integrations: {
|
||||
gitea: [
|
||||
{
|
||||
host: 'gitea.com',
|
||||
username: 'gitea_user',
|
||||
password: 'gitea_password',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const description = 'for the lols';
|
||||
const integrations = ScmIntegrations.fromConfig(config);
|
||||
const action = createPublishGiteaAction({ integrations, config });
|
||||
const mockContext = {
|
||||
input: {
|
||||
repoUrl: 'gitea.com?repo=repo',
|
||||
description,
|
||||
},
|
||||
workspacePath: 'lol',
|
||||
logger: getVoidLogger(),
|
||||
logStream: new PassThrough(),
|
||||
output: jest.fn(),
|
||||
createTemporaryDirectory: jest.fn(),
|
||||
};
|
||||
|
||||
const mockGitClient = {
|
||||
createRepository: jest.fn(),
|
||||
};
|
||||
|
||||
const server = setupServer();
|
||||
setupRequestMockHandlers(server);
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
it('should call action', async () => {
|
||||
const action = createAcmeExampleAction();
|
||||
it('should throw an error when the repoUrl is not well formed', async () => {
|
||||
await expect(
|
||||
action.handler({
|
||||
...mockContext,
|
||||
input: { repoUrl: 'gitea.com?owner=o', description },
|
||||
}),
|
||||
).rejects.toThrow(/missing repo/);
|
||||
});
|
||||
|
||||
const logger = getVoidLogger();
|
||||
jest.spyOn(logger, 'info');
|
||||
it('should throw if there is no integration config provided for missing.com host', async () => {
|
||||
await expect(
|
||||
action.handler({
|
||||
...mockContext,
|
||||
input: { repoUrl: 'missing.com?repo=repo', description },
|
||||
}),
|
||||
).rejects.toThrow(/No matching integration configuration/);
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
input: {
|
||||
myParameter: 'test',
|
||||
},
|
||||
workspacePath: '/tmp',
|
||||
logger,
|
||||
logStream: new PassThrough(),
|
||||
output: jest.fn(),
|
||||
createTemporaryDirectory() {
|
||||
// Usage of mock-fs is recommended for testing of filesystem operations
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
it('should throw if there is no repositoryId returned', async () => {
|
||||
mockGitClient.createRepository.mockImplementation(() => ({
|
||||
remoteUrl: 'https://gitea.com',
|
||||
id: null,
|
||||
}));
|
||||
|
||||
await action.handler(mockContext);
|
||||
expect(initRepoAndPush).toHaveBeenCalledWith({
|
||||
dir: mockContext.workspacePath,
|
||||
remoteUrl: 'https://gitea.com',
|
||||
defaultBranch: 'main',
|
||||
auth: { username: 'gitea_user', password: 'gitea_password' },
|
||||
logger: mockContext.logger,
|
||||
commitMessage: 'initial commit',
|
||||
gitAuthorInfo: {},
|
||||
});
|
||||
});
|
||||
|
||||
expect(logger.info).toHaveBeenCalledWith(
|
||||
'Running example template with parameters: test',
|
||||
);
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -35,20 +35,19 @@ const createGiteaProject = async (
|
||||
config: GiteaIntegrationConfig,
|
||||
options: {
|
||||
projectName: string;
|
||||
parent: string;
|
||||
// parent: string;
|
||||
owner?: string;
|
||||
description: string;
|
||||
},
|
||||
): Promise<void> => {
|
||||
const { projectName, parent, owner, description } = options;
|
||||
const { projectName, owner, description } = options;
|
||||
|
||||
const fetchOptions: RequestInit = {
|
||||
method: 'PUT',
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
parent,
|
||||
name: projectName,
|
||||
description,
|
||||
owners: owner ? [owner] : [],
|
||||
create_empty_commit: false,
|
||||
owner,
|
||||
}),
|
||||
headers: {
|
||||
...getGiteaRequestOptions(config).headers,
|
||||
@@ -57,8 +56,10 @@ const createGiteaProject = async (
|
||||
};
|
||||
|
||||
// TODO
|
||||
// Create a repository in Gitea
|
||||
// API request: https://gitea.com/api/swagger#/user/createCurrentUserRepo
|
||||
const response: Response = await fetch(
|
||||
`${config.baseUrl}/a/projects/${encodeURIComponent(projectName)}`,
|
||||
`${config.baseUrl}/api/v1/user/repos`,
|
||||
fetchOptions,
|
||||
);
|
||||
if (response.status !== 201) {
|
||||
@@ -174,31 +175,34 @@ export function createPublishGiteaAction(options: {
|
||||
sourcePath,
|
||||
} = ctx.input;
|
||||
|
||||
const { repo, host, owner, workspace } = parseRepoUrl(
|
||||
repoUrl,
|
||||
integrations,
|
||||
);
|
||||
const { owner, repo, host } = parseRepoUrl(repoUrl, integrations);
|
||||
|
||||
const integrationConfig = integrations.gitea.byHost(host);
|
||||
|
||||
if (!integrationConfig) {
|
||||
throw new InputError(
|
||||
`No matching integration configuration for host ${host}, please check your integrations config`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!workspace) {
|
||||
throw new InputError(
|
||||
`Invalid URL provider was included in the repo URL to create ${ctx.input.repoUrl}, missing workspace`,
|
||||
if (
|
||||
!integrationConfig.config.username ||
|
||||
!integrationConfig.config.password
|
||||
) {
|
||||
throw new Error(
|
||||
'Credentials for Gitea integration required for this action.',
|
||||
);
|
||||
}
|
||||
|
||||
// TODO
|
||||
// Check if the integration config includes a baseUrl
|
||||
|
||||
await createGiteaProject(integrationConfig.config, {
|
||||
description,
|
||||
owner: owner,
|
||||
projectName: repo,
|
||||
parent: workspace,
|
||||
// parent: workspace,
|
||||
});
|
||||
|
||||
const auth = {
|
||||
username: integrationConfig.config.username!,
|
||||
password: integrationConfig.config.password!,
|
||||
@@ -212,7 +216,7 @@ export function createPublishGiteaAction(options: {
|
||||
: config.getOptionalString('scaffolder.defaultAuthor.email'),
|
||||
};
|
||||
// TODO
|
||||
const remoteUrl = `${integrationConfig.config.baseUrl}/a/${repo}`;
|
||||
const remoteUrl = `${integrationConfig.config.baseUrl}/api/v1/user/${repo}`;
|
||||
const commitResult = await initRepoAndPush({
|
||||
dir: getRepoSourceDirectory(ctx.workspacePath, sourcePath),
|
||||
remoteUrl,
|
||||
|
||||
@@ -92,6 +92,10 @@ export const parseRepoUrl = (
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'gitea': {
|
||||
checkRequiredParams(parsed, 'repo');
|
||||
break;
|
||||
}
|
||||
case 'gerrit': {
|
||||
checkRequiredParams(parsed, 'repo');
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user