Make GitHub environment Scaffolder action use auth to resolve reviewers
Changes the github:environment:create Scaffolder action to request and use a backend auth token when resolving the reviewer entityRefs from the Backstage catalog. This is because previously it would throw a 401 error when backend auth was not disabled. The logic for requesting the token is copied from the existing catalog:fetch action, which needs to do a similar thing. Also slightly clarifies that Backstage entityRefs are expected in the reviewers list for this action. Signed-off-by: Jason Liu <a.jason.liu21@gmail.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-github': patch
|
||||
---
|
||||
|
||||
Change `github:environment:create` action to request and use a token when resolving reviewer entity refs from the Backstage catalog.
|
||||
@@ -3,6 +3,7 @@
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { AuthService } from '@backstage/backend-plugin-api';
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { Config } from '@backstage/config';
|
||||
@@ -103,6 +104,7 @@ export function createGithubDeployKeyAction(options: {
|
||||
export function createGithubEnvironmentAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
catalogClient?: CatalogApi;
|
||||
auth?: AuthService;
|
||||
}): TemplateAction<
|
||||
{
|
||||
repoUrl: string;
|
||||
|
||||
@@ -20,6 +20,7 @@ import { TemplateAction } from '@backstage/plugin-scaffolder-node';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { mockCredentials, mockServices } from '@backstage/backend-test-utils';
|
||||
|
||||
const mockOctokit = {
|
||||
rest: {
|
||||
@@ -71,6 +72,14 @@ describe('github:environment:create', () => {
|
||||
});
|
||||
|
||||
const integrations = ScmIntegrations.fromConfig(config);
|
||||
|
||||
const credentials = mockCredentials.user();
|
||||
|
||||
const token = mockCredentials.service.token({
|
||||
onBehalfOf: credentials,
|
||||
targetPluginId: 'catalog',
|
||||
});
|
||||
|
||||
let action: TemplateAction<any>;
|
||||
|
||||
const mockContext = createMockActionContext({
|
||||
@@ -78,6 +87,7 @@ describe('github:environment:create', () => {
|
||||
repoUrl: 'github.com?repo=repository&owner=owner',
|
||||
name: 'envname',
|
||||
},
|
||||
secrets: { backstageToken: token },
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -122,6 +132,7 @@ describe('github:environment:create', () => {
|
||||
action = createGithubEnvironmentAction({
|
||||
integrations,
|
||||
catalogClient: mockCatalogClient as CatalogApi,
|
||||
auth: mockServices.auth(),
|
||||
});
|
||||
});
|
||||
|
||||
@@ -453,6 +464,13 @@ describe('github:environment:create', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(mockCatalogClient.getEntitiesByRefs).toHaveBeenCalledWith(
|
||||
{
|
||||
entityRefs: ['group:default/team-a', 'user:default/johndoe'],
|
||||
},
|
||||
{ token },
|
||||
);
|
||||
|
||||
expect(
|
||||
mockOctokit.rest.repos.createOrUpdateEnvironment,
|
||||
).toHaveBeenCalledWith({
|
||||
|
||||
@@ -26,6 +26,7 @@ import Sodium from 'libsodium-wrappers';
|
||||
import { examples } from './gitHubEnvironment.examples';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { AuthService } from '@backstage/backend-plugin-api';
|
||||
|
||||
/**
|
||||
* Creates an `github:environment:create` Scaffolder action that creates a Github Environment.
|
||||
@@ -35,8 +36,9 @@ import { Entity } from '@backstage/catalog-model';
|
||||
export function createGithubEnvironmentAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
catalogClient?: CatalogApi;
|
||||
auth?: AuthService;
|
||||
}) {
|
||||
const { integrations, catalogClient } = options;
|
||||
const { integrations, catalogClient, auth } = options;
|
||||
// For more information on how to define custom actions, see
|
||||
// https://backstage.io/docs/features/software-templates/writing-custom-actions
|
||||
return createTemplateAction<{
|
||||
@@ -140,7 +142,8 @@ export function createGithubEnvironmentAction(options: {
|
||||
reviewers: {
|
||||
title: 'Reviewers',
|
||||
type: 'array',
|
||||
description: 'Reviewers for this environment',
|
||||
description:
|
||||
'Reviewers for this environment. Must be a list of Backstage entity references.',
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
@@ -163,6 +166,11 @@ export function createGithubEnvironmentAction(options: {
|
||||
reviewers,
|
||||
} = ctx.input;
|
||||
|
||||
const { token } = (await auth?.getPluginRequestToken({
|
||||
onBehalfOf: await ctx.getInitiatorCredentials(),
|
||||
targetPluginId: 'catalog',
|
||||
})) ?? { token: ctx.secrets?.backstageToken };
|
||||
|
||||
// When environment creation step is executed right after a repo publish step, the repository might not be available immediately.
|
||||
// Add a 2-second delay before initiating the steps in this action.
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
@@ -190,9 +198,14 @@ export function createGithubEnvironmentAction(options: {
|
||||
if (reviewers) {
|
||||
let reviewersEntityRefs: Array<Entity | undefined> = [];
|
||||
// Fetch reviewers from Catalog
|
||||
const catalogResponse = await catalogClient?.getEntitiesByRefs({
|
||||
entityRefs: reviewers,
|
||||
});
|
||||
const catalogResponse = await catalogClient?.getEntitiesByRefs(
|
||||
{
|
||||
entityRefs: reviewers,
|
||||
},
|
||||
{
|
||||
token,
|
||||
},
|
||||
);
|
||||
if (catalogResponse?.items?.length) {
|
||||
reviewersEntityRefs = catalogResponse.items;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user