feat(scaffolder-backend-module-github): support oidc customization

Signed-off-by: Johannes Würbach <johannes.wuerbach@googlemail.com>
This commit is contained in:
Johannes Würbach
2024-02-15 12:23:10 +01:00
parent 7abc4837e1
commit 3d5c6680f6
8 changed files with 142 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend-module-github': minor
---
support oidc customization
+12
View File
@@ -205,6 +205,12 @@ export function createGithubRepoCreateAction(options: {
[key: string]: string;
}
| undefined;
oidcCustomization?:
| {
useDefault: boolean;
includeClaimKeys?: string[] | undefined;
}
| undefined;
requireCommitSigning?: boolean | undefined;
},
JsonObject
@@ -352,6 +358,12 @@ export function createPublishGithubAction(options: {
[key: string]: string;
}
| undefined;
oidcCustomization?:
| {
useDefault: boolean;
includeClaimKeys?: string[] | undefined;
}
| undefined;
requiredCommitSigning?: boolean | undefined;
},
JsonObject
@@ -77,6 +77,7 @@ const mockOctokit = {
getRepoPublicKey: jest.fn(),
},
},
request: jest.fn(),
};
jest.mock('octokit', () => ({
Octokit: class {
@@ -930,6 +931,40 @@ describe('publish:github', () => {
});
});
it('should configure oidc customizations 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',
},
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
oidcCustomization: {
useDefault: false,
includeClaimKeys: ['foo', 'bar'],
},
},
});
expect(mockOctokit.request).toHaveBeenCalledWith(
'PUT /repos/{owner}/{repo}/actions/oidc/customization/sub',
{
include_claim_keys: ['foo', 'bar'],
owner: 'owner',
repo: 'repo',
use_default: false,
},
);
});
it('should call output with the remoteUrl and the repoContentsUrl', async () => {
mockOctokit.rest.users.getByUsername.mockResolvedValue({
data: { type: 'User' },
@@ -109,6 +109,10 @@ export function createPublishGithubAction(options: {
topics?: string[];
repoVariables?: { [key: string]: string };
secrets?: { [key: string]: string };
oidcCustomization?: {
useDefault: boolean;
includeClaimKeys?: string[];
};
requiredCommitSigning?: boolean;
}>({
id: 'publish:github',
@@ -156,6 +160,7 @@ export function createPublishGithubAction(options: {
topics: inputProps.topics,
repoVariables: inputProps.repoVariables,
secrets: inputProps.secrets,
oidcCustomization: inputProps.oidcCustomization,
requiredCommitSigning: inputProps.requiredCommitSigning,
},
},
@@ -203,6 +208,7 @@ export function createPublishGithubAction(options: {
topics,
repoVariables,
secrets,
oidcCustomization,
token: providedToken,
requiredCommitSigning = false,
} = ctx.input;
@@ -243,6 +249,7 @@ export function createPublishGithubAction(options: {
topics,
repoVariables,
secrets,
oidcCustomization,
ctx.logger,
);
@@ -58,6 +58,7 @@ const mockOctokit = {
getRepoPublicKey: jest.fn(),
},
},
request: jest.fn(),
};
jest.mock('octokit', () => ({
Octokit: class {
@@ -652,6 +653,40 @@ describe('github:repo:create', () => {
});
});
it('should configure oidc customizations 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',
},
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
oidcCustomization: {
useDefault: false,
includeClaimKeys: ['foo', 'bar'],
},
},
});
expect(mockOctokit.request).toHaveBeenCalledWith(
'PUT /repos/{owner}/{repo}/actions/oidc/customization/sub',
{
include_claim_keys: ['foo', 'bar'],
owner: 'owner',
repo: 'repo',
use_default: false,
},
);
});
it('should call output with the remoteUrl', async () => {
mockOctokit.rest.users.getByUsername.mockResolvedValue({
data: { type: 'User' },
@@ -95,6 +95,10 @@ export function createGithubRepoCreateAction(options: {
topics?: string[];
repoVariables?: { [key: string]: string };
secrets?: { [key: string]: string };
oidcCustomization?: {
useDefault: boolean;
includeClaimKeys?: string[];
};
requireCommitSigning?: boolean;
}>({
id: 'github:repo:create',
@@ -133,6 +137,7 @@ export function createGithubRepoCreateAction(options: {
topics: inputProps.topics,
repoVariables: inputProps.repoVariables,
secrets: inputProps.secrets,
oidcCustomization: inputProps.oidcCustomization,
requiredCommitSigning: inputProps.requiredCommitSigning,
},
},
@@ -165,6 +170,7 @@ export function createGithubRepoCreateAction(options: {
topics,
repoVariables,
secrets,
oidcCustomization,
token: providedToken,
} = ctx.input;
@@ -204,6 +210,7 @@ export function createGithubRepoCreateAction(options: {
topics,
repoVariables,
secrets,
oidcCustomization,
ctx.logger,
);
@@ -137,6 +137,12 @@ export async function createGithubRepoWithCollaboratorsAndTopics(
topics: string[] | undefined,
repoVariables: { [key: string]: string } | undefined,
secrets: { [key: string]: string } | undefined,
oidcCustomization:
| {
useDefault: boolean;
includeClaimKeys?: string[];
}
| undefined,
logger: Logger,
) {
// eslint-disable-next-line testing-library/no-await-sync-queries
@@ -304,6 +310,18 @@ export async function createGithubRepoWithCollaboratorsAndTopics(
}
}
if (oidcCustomization) {
await client.request(
'PUT /repos/{owner}/{repo}/actions/oidc/customization/sub',
{
owner,
repo,
use_default: oidcCustomization.useDefault,
include_claim_keys: oidcCustomization.includeClaimKeys,
},
);
}
return newRepo;
}
@@ -277,6 +277,28 @@ const secrets = {
type: 'object',
};
const oidcCustomization = {
title: 'Repository OIDC customization template',
description: `OIDC customization template attached to the repository.`,
type: 'object',
additionalProperties: false,
properties: {
useDefault: {
title: 'Use Default',
type: 'boolean',
description: `Whether to use the default OIDC template or not.`,
},
includeClaimKeys: {
title: 'Include claim keys',
type: 'array',
items: {
type: 'string',
},
description: `Array of unique strings. Each claim key can only contain alphanumeric characters and underscores.`,
},
},
};
export { access };
export { allowMergeCommit };
export { allowRebaseMerge };
@@ -313,3 +335,4 @@ export { topics };
export { requiredCommitSigning };
export { repoVariables };
export { secrets };
export { oidcCustomization };