diff --git a/.changeset/beige-pumas-tap.md b/.changeset/beige-pumas-tap.md new file mode 100644 index 0000000000..8ed8aab1f4 --- /dev/null +++ b/.changeset/beige-pumas-tap.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': minor +--- + +Add the option for a homepage when using the `github:publish` action diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index b74b5ae741..68ab024bf6 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -178,6 +178,7 @@ export function createGithubRepoCreateAction(options: { }): TemplateAction<{ repoUrl: string; description?: string | undefined; + homepage?: string | undefined; access?: string | undefined; deleteBranchOnMerge?: boolean | undefined; gitAuthorName?: string | undefined; @@ -338,6 +339,7 @@ export function createPublishGithubAction(options: { }): TemplateAction<{ repoUrl: string; description?: string | undefined; + homepage?: string | undefined; access?: string | undefined; defaultBranch?: string | undefined; protectDefaultBranch?: boolean | undefined; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.test.ts index 0e7e907917..f04a735bee 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.test.ts @@ -129,6 +129,26 @@ describe('github:repo:create', () => { allow_rebase_merge: true, visibility: 'public', }); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + homepage: 'https://example.com', + }, + }); + expect(mockOctokit.rest.repos.createInOrg).toHaveBeenCalledWith({ + description: 'description', + homepage: 'https://example.com', + name: 'repo', + org: 'owner', + private: true, + delete_branch_on_merge: false, + allow_squash_merge: true, + allow_merge_commit: true, + allow_rebase_merge: true, + visibility: 'private', + }); }); it('should call the githubApis with the correct values for createForAuthenticatedUser', async () => { @@ -171,6 +191,26 @@ describe('github:repo:create', () => { allow_merge_commit: true, allow_rebase_merge: true, }); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + homepage: 'https://example.com', + }, + }); + expect( + mockOctokit.rest.repos.createForAuthenticatedUser, + ).toHaveBeenCalledWith({ + description: 'description', + homepage: 'https://example.com', + name: 'repo', + private: true, + delete_branch_on_merge: false, + allow_squash_merge: true, + allow_merge_commit: true, + allow_rebase_merge: true, + }); }); it('should add access for the team when it starts with the owner', async () => { diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.ts index 1e92d91a64..5bc1fa8702 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.ts @@ -42,6 +42,7 @@ export function createGithubRepoCreateAction(options: { return createTemplateAction<{ repoUrl: string; description?: string; + homepage?: string; access?: string; deleteBranchOnMerge?: boolean; gitAuthorName?: string; @@ -79,6 +80,7 @@ export function createGithubRepoCreateAction(options: { properties: { repoUrl: inputProps.repoUrl, description: inputProps.description, + homepage: inputProps.homepage, access: inputProps.access, requireCodeOwnerReviews: inputProps.requireCodeOwnerReviews, requiredStatusCheckContexts: inputProps.requiredStatusCheckContexts, @@ -104,6 +106,7 @@ export function createGithubRepoCreateAction(options: { const { repoUrl, description, + homepage, access, repoVisibility = 'private', deleteBranchOnMerge = false, @@ -135,6 +138,7 @@ export function createGithubRepoCreateAction(options: { owner, repoVisibility, description, + homepage, deleteBranchOnMerge, allowMergeCommit, allowSquashMerge, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/helpers.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/helpers.ts index b60794295a..fd3899b18a 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/helpers.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/helpers.ts @@ -97,6 +97,7 @@ export async function createGithubRepoWithCollaboratorsAndTopics( owner: string, repoVisibility: 'private' | 'internal' | 'public', description: string | undefined, + homepage: string | undefined, deleteBranchOnMerge: boolean, allowMergeCommit: boolean, allowSquashMerge: boolean, @@ -138,6 +139,7 @@ export async function createGithubRepoWithCollaboratorsAndTopics( allow_merge_commit: allowMergeCommit, allow_squash_merge: allowSquashMerge, allow_rebase_merge: allowRebaseMerge, + homepage: homepage, }) : client.rest.repos.createForAuthenticatedUser({ name: repo, @@ -147,6 +149,7 @@ export async function createGithubRepoWithCollaboratorsAndTopics( allow_merge_commit: allowMergeCommit, allow_squash_merge: allowSquashMerge, allow_rebase_merge: allowRebaseMerge, + homepage: homepage, }); let newRepo; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/inputProperties.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/inputProperties.ts index b0113a4485..153b2e6941 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/inputProperties.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/inputProperties.ts @@ -23,6 +23,10 @@ const description = { title: 'Repository Description', type: 'string', }; +const homepage = { + title: 'Repository Homepage', + type: 'string', +}; const access = { title: 'Repository Access', description: `Sets an admin collaborator on the repository. Can either be a user reference different from 'owner' in 'repoUrl' or team reference, eg. 'org/team-name'`, @@ -156,6 +160,7 @@ export { description }; export { gitAuthorEmail }; export { gitAuthorName }; export { gitCommitMessage }; +export { homepage }; export { protectDefaultBranch }; export { protectEnforceAdmins }; export { repoUrl }; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts index a526e73019..6a2665bc8d 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts @@ -134,6 +134,26 @@ describe('publish:github', () => { allow_rebase_merge: true, visibility: 'public', }); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + homepage: 'https://example.com', + }, + }); + expect(mockOctokit.rest.repos.createInOrg).toHaveBeenCalledWith({ + description: 'description', + name: 'repo', + homepage: 'https://example.com', + org: 'owner', + private: true, + delete_branch_on_merge: false, + allow_squash_merge: true, + allow_merge_commit: true, + allow_rebase_merge: true, + visibility: 'private', + }); }); it('should call the githubApis with the correct values for createForAuthenticatedUser', async () => { @@ -176,6 +196,26 @@ describe('publish:github', () => { allow_merge_commit: true, allow_rebase_merge: true, }); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + homepage: 'https://example.com', + }, + }); + expect( + mockOctokit.rest.repos.createForAuthenticatedUser, + ).toHaveBeenCalledWith({ + description: 'description', + homepage: 'https://example.com', + name: 'repo', + private: true, + delete_branch_on_merge: false, + allow_squash_merge: true, + allow_merge_commit: true, + allow_rebase_merge: true, + }); }); it('should call initRepoAndPush with the correct values', async () => { @@ -812,4 +852,37 @@ describe('publish:github', () => { expect(enableBranchProtectionOnDefaultRepoBranch).not.toHaveBeenCalled(); }); + + it('should add homepage when provided', async () => { + mockOctokit.rest.users.getByUsername.mockResolvedValue({ + data: { type: 'User' }, + }); + + mockOctokit.rest.repos.createForAuthenticatedUser.mockResolvedValue({ + data: { + clone_url: 'https://github.com/clone/url.git', + html_url: 'https://github.com/html/url', + }, + }); + + mockOctokit.rest.repos.replaceAllTopics.mockResolvedValue({ + data: { + names: ['node.js'], + }, + }); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + topics: ['node.js'], + }, + }); + + expect(mockOctokit.rest.repos.replaceAllTopics).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repo', + names: ['node.js'], + }); + }); }); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts index eea006ae8f..8ce9105237 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts @@ -45,6 +45,7 @@ export function createPublishGithubAction(options: { return createTemplateAction<{ repoUrl: string; description?: string; + homepage?: string; access?: string; defaultBranch?: string; protectDefaultBranch?: boolean; @@ -88,6 +89,7 @@ export function createPublishGithubAction(options: { properties: { repoUrl: inputProps.repoUrl, description: inputProps.description, + homepage: inputProps.homepage, access: inputProps.access, requireCodeOwnerReviews: inputProps.requireCodeOwnerReviews, requiredStatusCheckContexts: inputProps.requiredStatusCheckContexts, @@ -120,6 +122,7 @@ export function createPublishGithubAction(options: { const { repoUrl, description, + homepage, access, requireCodeOwnerReviews = false, requiredStatusCheckContexts = [], @@ -159,6 +162,7 @@ export function createPublishGithubAction(options: { owner, repoVisibility, description, + homepage, deleteBranchOnMerge, allowMergeCommit, allowSquashMerge,