@@ -11,6 +11,9 @@ Unless you're providing your own override action to the default, this should be
|
||||
You can migrate using the following if you're getting typescript errors:
|
||||
|
||||
```ts
|
||||
import { catalogServiceRef } from '@backstage/plugin-catalog-node';
|
||||
import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha';
|
||||
|
||||
export const myModule = createBackendModule({
|
||||
pluginId: 'scaffolder',
|
||||
moduleId: 'test',
|
||||
@@ -18,12 +21,12 @@ export const myModule = createBackendModule({
|
||||
registerInit({
|
||||
deps: {
|
||||
scaffolder: scaffolderActionsExtensionPoint,
|
||||
catalogService: catalogServiceRef,
|
||||
catalog: catalogServiceRef,
|
||||
},
|
||||
async init({ scaffolder, catalogService }) {
|
||||
async init({ scaffolder, catalog }) {
|
||||
scaffolder.addActions(
|
||||
createGithubEnvironmentAction({
|
||||
catalogService,
|
||||
catalog,
|
||||
}),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -13,6 +13,9 @@ Unless you're providing your own override action to the default, this should be
|
||||
You can migrate using the following if you're getting typescript errors:
|
||||
|
||||
```ts
|
||||
import { catalogServiceRef } from '@backstage/plugin-catalog-node';
|
||||
import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha';
|
||||
|
||||
export const myModule = createBackendModule({
|
||||
pluginId: 'scaffolder',
|
||||
moduleId: 'test',
|
||||
@@ -20,15 +23,15 @@ export const myModule = createBackendModule({
|
||||
registerInit({
|
||||
deps: {
|
||||
scaffolder: scaffolderActionsExtensionPoint,
|
||||
catalogService: catalogServiceRef,
|
||||
catalog: catalogServiceRef,
|
||||
},
|
||||
async init({ scaffolder, catalogService }) {
|
||||
async init({ scaffolder, catalog }) {
|
||||
scaffolder.addActions(
|
||||
createCatalogRegisterAction({
|
||||
catalogService,
|
||||
catalog,
|
||||
}),
|
||||
createFetchCatalogEntityAction({
|
||||
catalogService,
|
||||
catalog,
|
||||
integrations,
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-node': minor
|
||||
---
|
||||
|
||||
**BREAKING CHANGES**
|
||||
|
||||
The soon to be removed `TaskWorker` and `CreateWorkerOptions` now take a `LoggerService` implementation as the `logger` option instead of the old `winston` logger interface. Technically this is marked as a breaking change, albeit only in rare circumstances.
|
||||
@@ -1,60 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-node': minor
|
||||
---
|
||||
|
||||
**BREAKING CHANGES**
|
||||
|
||||
The legacy methods to define `createTemplateActions` have been replaced with the new native `zod` approaches for defining input and output schemas.
|
||||
|
||||
You can migrate actions that look like the following with the below examples:
|
||||
|
||||
```ts
|
||||
// really old legacy json schema
|
||||
createTemplateAction<{ repoUrl: string }, { repoOutput: string }>({
|
||||
id: 'test',
|
||||
schema: {
|
||||
input: {
|
||||
type: 'object'
|
||||
required: ['repoUrl']
|
||||
properties: {
|
||||
repoUrl: {
|
||||
type: 'string',
|
||||
description: 'repository url description'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// old zod method
|
||||
createTemplateAction({
|
||||
id: 'test'
|
||||
schema: {
|
||||
input: {
|
||||
repoUrl: z.string({ description: 'repository url description' })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// new method:
|
||||
createTemplateAction({
|
||||
id: 'test',
|
||||
schema: {
|
||||
input: {
|
||||
repoUrl: z => z.string({ description: 'repository url description' })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// or for more complex zod types like unions
|
||||
createTemplateAction({
|
||||
id: 'test',
|
||||
schema: {
|
||||
input: z => z.object({
|
||||
repoUrl: z.string({ description: 'repository url description' })
|
||||
})
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
This breaking change also means that `logStream` has been removed entirely from `ActionsContext`, and that the `logger` is now just a `LoggerService` implementation instead. There is no replacement for the `logStream`, if you wish to still keep using a `logStream` we recommend that you create your own stream that writes to `ctx.logger` instead.
|
||||
@@ -24,11 +24,14 @@ import {
|
||||
configApiRef,
|
||||
createApiFactory,
|
||||
discoveryApiRef,
|
||||
fetchApiRef,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { AuthProxyDiscoveryApi } from './AuthProxyDiscoveryApi';
|
||||
import { formDecoratorsApiRef } from '@backstage/plugin-scaffolder/alpha';
|
||||
import { DefaultScaffolderFormDecoratorsApi } from '@backstage/plugin-scaffolder/alpha';
|
||||
import { mockDecorator } from './components/scaffolder/decorators';
|
||||
import { scaffolderApiRef } from '@backstage/plugin-scaffolder-react';
|
||||
import { ScaffolderClient } from '@backstage/plugin-scaffolder';
|
||||
|
||||
export const apis: AnyApiFactory[] = [
|
||||
createApiFactory({
|
||||
@@ -42,6 +45,22 @@ export const apis: AnyApiFactory[] = [
|
||||
factory: ({ configApi }) => ScmIntegrationsApi.fromConfig(configApi),
|
||||
}),
|
||||
|
||||
createApiFactory({
|
||||
api: scaffolderApiRef,
|
||||
deps: {
|
||||
discoveryApi: discoveryApiRef,
|
||||
fetchApi: fetchApiRef,
|
||||
scmIntegrationsApi: scmIntegrationsApiRef,
|
||||
},
|
||||
factory: ({ discoveryApi, fetchApi, scmIntegrationsApi }) =>
|
||||
new ScaffolderClient({
|
||||
useLongPollingLogs: true,
|
||||
discoveryApi,
|
||||
fetchApi,
|
||||
scmIntegrationsApi,
|
||||
}),
|
||||
}),
|
||||
|
||||
createApiFactory({
|
||||
api: formDecoratorsApiRef,
|
||||
deps: {},
|
||||
|
||||
@@ -110,7 +110,7 @@ export function createGithubDeployKeyAction(options: {
|
||||
// @public
|
||||
export function createGithubEnvironmentAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
catalogService: CatalogService;
|
||||
catalog: CatalogService;
|
||||
}): TemplateAction<
|
||||
{
|
||||
repoUrl: string;
|
||||
|
||||
+1
-1
@@ -112,7 +112,7 @@ describe('github:environment:create examples', () => {
|
||||
|
||||
action = createGithubEnvironmentAction({
|
||||
integrations,
|
||||
catalogService: mockCatalogService,
|
||||
catalog: mockCatalogService,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ describe('github:environment:create', () => {
|
||||
|
||||
action = createGithubEnvironmentAction({
|
||||
integrations,
|
||||
catalogService: mockCatalogService,
|
||||
catalog: mockCatalogService,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -34,9 +34,9 @@ import { CatalogService } from '@backstage/plugin-catalog-node';
|
||||
*/
|
||||
export function createGithubEnvironmentAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
catalogService: CatalogService;
|
||||
catalog: CatalogService;
|
||||
}) {
|
||||
const { integrations, catalogService } = options;
|
||||
const { integrations, catalog } = options;
|
||||
// For more information on how to define custom actions, see
|
||||
// https://backstage.io/docs/features/software-templates/writing-custom-actions
|
||||
return createTemplateAction({
|
||||
@@ -183,7 +183,7 @@ Wildcard characters will not match \`/\`. For example, to match tags that begin
|
||||
if (reviewers) {
|
||||
let reviewersEntityRefs: Array<Entity | undefined> = [];
|
||||
// Fetch reviewers from Catalog
|
||||
const catalogResponse = await catalogService?.getEntitiesByRefs(
|
||||
const catalogResponse = await catalog.getEntitiesByRefs(
|
||||
{
|
||||
entityRefs: reviewers,
|
||||
},
|
||||
|
||||
@@ -54,10 +54,10 @@ export const githubModule = createBackendModule({
|
||||
deps: {
|
||||
scaffolder: scaffolderActionsExtensionPoint,
|
||||
config: coreServices.rootConfig,
|
||||
catalogService: catalogServiceRef,
|
||||
catalog: catalogServiceRef,
|
||||
autocomplete: scaffolderAutocompleteExtensionPoint,
|
||||
},
|
||||
async init({ scaffolder, config, autocomplete, catalogService }) {
|
||||
async init({ scaffolder, config, autocomplete, catalog }) {
|
||||
const integrations = ScmIntegrations.fromConfig(config);
|
||||
const githubCredentialsProvider =
|
||||
DefaultGithubCredentialsProvider.fromIntegrations(integrations);
|
||||
@@ -76,7 +76,7 @@ export const githubModule = createBackendModule({
|
||||
}),
|
||||
createGithubEnvironmentAction({
|
||||
integrations,
|
||||
catalogService,
|
||||
catalog,
|
||||
}),
|
||||
createGithubIssuesLabelAction({
|
||||
integrations,
|
||||
|
||||
@@ -53,7 +53,7 @@ export type ActionPermissionRuleInput<
|
||||
|
||||
// @public
|
||||
export function createCatalogRegisterAction(options: {
|
||||
catalogService: CatalogService;
|
||||
catalog: CatalogService;
|
||||
integrations: ScmIntegrations;
|
||||
}): TemplateAction<
|
||||
| {
|
||||
@@ -106,7 +106,7 @@ export function createDebugLogAction(): TemplateAction<
|
||||
|
||||
// @public
|
||||
export function createFetchCatalogEntityAction(options: {
|
||||
catalogService: CatalogService;
|
||||
catalog: CatalogService;
|
||||
}): TemplateAction<
|
||||
{
|
||||
entityRef?: string | undefined;
|
||||
|
||||
@@ -137,7 +137,7 @@ export const scaffolderPlugin = createBackendPlugin({
|
||||
httpRouter: coreServices.httpRouter,
|
||||
httpAuth: coreServices.httpAuth,
|
||||
auditor: coreServices.auditor,
|
||||
catalogService: catalogServiceRef,
|
||||
catalog: catalogServiceRef,
|
||||
events: eventsServiceRef,
|
||||
},
|
||||
async init({
|
||||
@@ -149,7 +149,7 @@ export const scaffolderPlugin = createBackendPlugin({
|
||||
auth,
|
||||
httpRouter,
|
||||
httpAuth,
|
||||
catalogService,
|
||||
catalog,
|
||||
permissions,
|
||||
events,
|
||||
auditor,
|
||||
@@ -191,8 +191,8 @@ export const scaffolderPlugin = createBackendPlugin({
|
||||
createDebugLogAction(),
|
||||
createWaitAction(),
|
||||
// todo(blam): maybe these should be a -catalog module?
|
||||
createCatalogRegisterAction({ catalogService, integrations }),
|
||||
createFetchCatalogEntityAction({ catalogService }),
|
||||
createCatalogRegisterAction({ catalog, integrations }),
|
||||
createFetchCatalogEntityAction({ catalog }),
|
||||
createCatalogWriteAction(),
|
||||
createFilesystemDeleteAction(),
|
||||
createFilesystemRenameAction(),
|
||||
@@ -209,7 +209,7 @@ export const scaffolderPlugin = createBackendPlugin({
|
||||
logger,
|
||||
config,
|
||||
database,
|
||||
catalogService,
|
||||
catalog,
|
||||
lifecycle,
|
||||
actions,
|
||||
taskBroker,
|
||||
|
||||
+4
-4
@@ -31,10 +31,10 @@ describe('catalog:fetch examples', () => {
|
||||
},
|
||||
} as Entity;
|
||||
|
||||
const catalogService = catalogServiceMock({ entities: [entity] });
|
||||
const catalogMock = catalogServiceMock({ entities: [entity] });
|
||||
|
||||
const action = createFetchCatalogEntityAction({
|
||||
catalogService,
|
||||
catalog: catalogMock,
|
||||
});
|
||||
|
||||
const credentials = mockCredentials.user();
|
||||
@@ -43,7 +43,7 @@ describe('catalog:fetch examples', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
jest.spyOn(catalogService, 'getEntityByRef');
|
||||
jest.spyOn(catalogMock, 'getEntityByRef');
|
||||
});
|
||||
|
||||
describe('fetch single entity', () => {
|
||||
@@ -53,7 +53,7 @@ describe('catalog:fetch examples', () => {
|
||||
input: yaml.parse(examples[0].example).steps[0].input,
|
||||
});
|
||||
|
||||
expect(catalogService.getEntityByRef).toHaveBeenCalledWith(
|
||||
expect(catalogMock.getEntityByRef).toHaveBeenCalledWith(
|
||||
'component:default/name',
|
||||
{ credentials },
|
||||
);
|
||||
|
||||
@@ -39,10 +39,11 @@ describe('catalog:fetch', () => {
|
||||
|
||||
describe('fetch single entity', () => {
|
||||
it('should return entity from catalog', async () => {
|
||||
const catalogService = catalogServiceMock({ entities: [component] });
|
||||
jest.spyOn(catalogService, 'getEntityByRef');
|
||||
const catalogMock = catalogServiceMock({ entities: [component] });
|
||||
jest.spyOn(catalogMock, 'getEntityByRef');
|
||||
|
||||
const action = createFetchCatalogEntityAction({
|
||||
catalogService,
|
||||
catalog: catalogMock,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -52,7 +53,7 @@ describe('catalog:fetch', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(catalogService.getEntityByRef).toHaveBeenCalledWith(
|
||||
expect(catalogMock.getEntityByRef).toHaveBeenCalledWith(
|
||||
'component:default/test',
|
||||
{ credentials },
|
||||
);
|
||||
@@ -60,12 +61,12 @@ describe('catalog:fetch', () => {
|
||||
});
|
||||
|
||||
it('should throw error if entity fetch fails from catalog and optional is false', async () => {
|
||||
const catalogService = catalogServiceMock.mock({
|
||||
const catalogMock = catalogServiceMock.mock({
|
||||
getEntityByRef: () => Promise.reject(new Error('Not found')),
|
||||
});
|
||||
jest.spyOn(catalogService, 'getEntityByRef');
|
||||
|
||||
const action = createFetchCatalogEntityAction({
|
||||
catalogService,
|
||||
catalog: catalogMock,
|
||||
});
|
||||
|
||||
await expect(
|
||||
@@ -77,7 +78,7 @@ describe('catalog:fetch', () => {
|
||||
}),
|
||||
).rejects.toThrow('Not found');
|
||||
|
||||
expect(catalogService.getEntityByRef).toHaveBeenCalledWith(
|
||||
expect(catalogMock.getEntityByRef).toHaveBeenCalledWith(
|
||||
'component:default/test',
|
||||
{ credentials },
|
||||
);
|
||||
@@ -85,10 +86,11 @@ describe('catalog:fetch', () => {
|
||||
});
|
||||
|
||||
it('should throw error if entity not in catalog and optional is false', async () => {
|
||||
const catalogService = catalogServiceMock({ entities: [] });
|
||||
jest.spyOn(catalogService, 'getEntityByRef');
|
||||
const catalogMock = catalogServiceMock({ entities: [] });
|
||||
jest.spyOn(catalogMock, 'getEntityByRef');
|
||||
|
||||
const action = createFetchCatalogEntityAction({
|
||||
catalogService,
|
||||
catalog: catalogMock,
|
||||
});
|
||||
|
||||
await expect(
|
||||
@@ -100,7 +102,7 @@ describe('catalog:fetch', () => {
|
||||
}),
|
||||
).rejects.toThrow('Entity component:default/test not found');
|
||||
|
||||
expect(catalogService.getEntityByRef).toHaveBeenCalledWith(
|
||||
expect(catalogMock.getEntityByRef).toHaveBeenCalledWith(
|
||||
'component:default/test',
|
||||
{ credentials },
|
||||
);
|
||||
@@ -115,10 +117,12 @@ describe('catalog:fetch', () => {
|
||||
namespace: 'ns',
|
||||
},
|
||||
} as Entity;
|
||||
const catalogService = catalogServiceMock({ entities: [entity] });
|
||||
jest.spyOn(catalogService, 'getEntityByRef');
|
||||
|
||||
const catalogMock = catalogServiceMock({ entities: [entity] });
|
||||
jest.spyOn(catalogMock, 'getEntityByRef');
|
||||
|
||||
const action = createFetchCatalogEntityAction({
|
||||
catalogService,
|
||||
catalog: catalogMock,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -130,20 +134,21 @@ describe('catalog:fetch', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(catalogService.getEntityByRef).toHaveBeenCalledWith(
|
||||
'group:ns/test',
|
||||
{ credentials },
|
||||
);
|
||||
expect(catalogMock.getEntityByRef).toHaveBeenCalledWith('group:ns/test', {
|
||||
credentials,
|
||||
});
|
||||
|
||||
expect(mockContext.output).toHaveBeenCalledWith('entity', entity);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetch multiple entities', () => {
|
||||
it('should return entities from catalog', async () => {
|
||||
const catalogService = catalogServiceMock({ entities: [component] });
|
||||
jest.spyOn(catalogService, 'getEntitiesByRefs');
|
||||
const catalogMock = catalogServiceMock({ entities: [component] });
|
||||
jest.spyOn(catalogMock, 'getEntitiesByRefs');
|
||||
|
||||
const action = createFetchCatalogEntityAction({
|
||||
catalogService,
|
||||
catalog: catalogMock,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -153,7 +158,7 @@ describe('catalog:fetch', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(catalogService.getEntitiesByRefs).toHaveBeenCalledWith(
|
||||
expect(catalogMock.getEntitiesByRefs).toHaveBeenCalledWith(
|
||||
{ entityRefs: ['component:default/test'] },
|
||||
{ credentials },
|
||||
);
|
||||
@@ -161,10 +166,10 @@ describe('catalog:fetch', () => {
|
||||
});
|
||||
|
||||
it('should throw error if undefined is returned for some entity', async () => {
|
||||
const catalogService = catalogServiceMock({ entities: [component] });
|
||||
jest.spyOn(catalogService, 'getEntitiesByRefs');
|
||||
const catalogMock = catalogServiceMock({ entities: [component] });
|
||||
jest.spyOn(catalogMock, 'getEntitiesByRefs');
|
||||
const action = createFetchCatalogEntityAction({
|
||||
catalogService,
|
||||
catalog: catalogMock,
|
||||
});
|
||||
|
||||
await expect(
|
||||
@@ -177,7 +182,7 @@ describe('catalog:fetch', () => {
|
||||
}),
|
||||
).rejects.toThrow('Entity component:default/test2 not found');
|
||||
|
||||
expect(catalogService.getEntitiesByRefs).toHaveBeenCalledWith(
|
||||
expect(catalogMock.getEntitiesByRefs).toHaveBeenCalledWith(
|
||||
{
|
||||
entityRefs: ['component:default/test', 'component:default/test2'],
|
||||
},
|
||||
@@ -187,10 +192,11 @@ describe('catalog:fetch', () => {
|
||||
});
|
||||
|
||||
it('should return null in case some of the entities not found and optional is true', async () => {
|
||||
const catalogService = catalogServiceMock({ entities: [component] });
|
||||
jest.spyOn(catalogService, 'getEntitiesByRefs');
|
||||
const catalogMock = catalogServiceMock({ entities: [component] });
|
||||
jest.spyOn(catalogMock, 'getEntitiesByRefs');
|
||||
|
||||
const action = createFetchCatalogEntityAction({
|
||||
catalogService,
|
||||
catalog: catalogMock,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -201,7 +207,7 @@ describe('catalog:fetch', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(catalogService.getEntitiesByRefs).toHaveBeenCalledWith(
|
||||
expect(catalogMock.getEntitiesByRefs).toHaveBeenCalledWith(
|
||||
{ entityRefs: ['component:default/test', 'component:default/test2'] },
|
||||
{ credentials },
|
||||
);
|
||||
@@ -226,12 +232,14 @@ describe('catalog:fetch', () => {
|
||||
},
|
||||
kind: 'User',
|
||||
} as Entity;
|
||||
const catalogService = catalogServiceMock({
|
||||
|
||||
const catalogMock = catalogServiceMock({
|
||||
entities: [entity1, entity2],
|
||||
});
|
||||
jest.spyOn(catalogService, 'getEntitiesByRefs');
|
||||
jest.spyOn(catalogMock, 'getEntitiesByRefs');
|
||||
|
||||
const action = createFetchCatalogEntityAction({
|
||||
catalogService,
|
||||
catalog: catalogMock,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -243,7 +251,7 @@ describe('catalog:fetch', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(catalogService.getEntitiesByRefs).toHaveBeenCalledWith(
|
||||
expect(catalogMock.getEntitiesByRefs).toHaveBeenCalledWith(
|
||||
{ entityRefs: ['group:ns/test', 'user:default/test'] },
|
||||
{ credentials },
|
||||
);
|
||||
|
||||
@@ -27,9 +27,9 @@ const id = 'catalog:fetch';
|
||||
* @public
|
||||
*/
|
||||
export function createFetchCatalogEntityAction(options: {
|
||||
catalogService: CatalogService;
|
||||
catalog: CatalogService;
|
||||
}) {
|
||||
const { catalogService } = options;
|
||||
const { catalog } = options;
|
||||
|
||||
return createTemplateAction({
|
||||
id,
|
||||
@@ -94,7 +94,7 @@ export function createFetchCatalogEntityAction(options: {
|
||||
}
|
||||
|
||||
if (entityRef) {
|
||||
const entity = await catalogService.getEntityByRef(
|
||||
const entity = await catalog.getEntityByRef(
|
||||
stringifyEntityRef(
|
||||
parseEntityRef(entityRef, { defaultKind, defaultNamespace }),
|
||||
),
|
||||
@@ -110,7 +110,7 @@ export function createFetchCatalogEntityAction(options: {
|
||||
}
|
||||
|
||||
if (entityRefs) {
|
||||
const entities = await catalogService.getEntitiesByRefs(
|
||||
const entities = await catalog.getEntitiesByRefs(
|
||||
{
|
||||
entityRefs: entityRefs.map(ref =>
|
||||
stringifyEntityRef(
|
||||
|
||||
+6
-5
@@ -33,11 +33,11 @@ describe('catalog:register', () => {
|
||||
}),
|
||||
);
|
||||
|
||||
const catalogService = catalogServiceMock.mock();
|
||||
const catalogMock = catalogServiceMock.mock();
|
||||
|
||||
const action = createCatalogRegisterAction({
|
||||
integrations,
|
||||
catalogService,
|
||||
catalog: catalogMock,
|
||||
});
|
||||
|
||||
const credentials = mockCredentials.user();
|
||||
@@ -48,7 +48,7 @@ describe('catalog:register', () => {
|
||||
});
|
||||
|
||||
it('should register location in catalog', async () => {
|
||||
catalogService.addLocation
|
||||
catalogMock.addLocation
|
||||
.mockResolvedValueOnce({
|
||||
location: null as any,
|
||||
entities: [],
|
||||
@@ -65,12 +65,13 @@ describe('catalog:register', () => {
|
||||
} as Entity,
|
||||
],
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
...mockContext,
|
||||
input: yaml.parse(examples[0].example).steps[0].input,
|
||||
});
|
||||
|
||||
expect(catalogService.addLocation).toHaveBeenNthCalledWith(
|
||||
expect(catalogMock.addLocation).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
{
|
||||
type: 'url',
|
||||
@@ -79,7 +80,7 @@ describe('catalog:register', () => {
|
||||
},
|
||||
{ credentials },
|
||||
);
|
||||
expect(catalogService.addLocation).toHaveBeenNthCalledWith(
|
||||
expect(catalogMock.addLocation).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
{
|
||||
dryRun: true,
|
||||
|
||||
+15
-15
@@ -31,11 +31,11 @@ describe('catalog:register', () => {
|
||||
}),
|
||||
);
|
||||
|
||||
const catalogService = catalogServiceMock.mock();
|
||||
const catalogMock = catalogServiceMock.mock();
|
||||
|
||||
const action = createCatalogRegisterAction({
|
||||
integrations,
|
||||
catalogService,
|
||||
catalog: catalogMock,
|
||||
});
|
||||
|
||||
const credentials = mockCredentials.user();
|
||||
@@ -60,7 +60,7 @@ describe('catalog:register', () => {
|
||||
});
|
||||
|
||||
it('should register location in catalog', async () => {
|
||||
catalogService.addLocation
|
||||
catalogMock.addLocation
|
||||
.mockResolvedValueOnce({
|
||||
location: null as any,
|
||||
entities: [],
|
||||
@@ -84,7 +84,7 @@ describe('catalog:register', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(catalogService.addLocation).toHaveBeenNthCalledWith(
|
||||
expect(catalogMock.addLocation).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
{
|
||||
type: 'url',
|
||||
@@ -92,7 +92,7 @@ describe('catalog:register', () => {
|
||||
},
|
||||
{ credentials },
|
||||
);
|
||||
expect(catalogService.addLocation).toHaveBeenNthCalledWith(
|
||||
expect(catalogMock.addLocation).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
{
|
||||
dryRun: true,
|
||||
@@ -113,7 +113,7 @@ describe('catalog:register', () => {
|
||||
});
|
||||
|
||||
it('should return entityRef with the Component entity and not the generated location', async () => {
|
||||
catalogService.addLocation
|
||||
catalogMock.addLocation
|
||||
.mockResolvedValueOnce({
|
||||
location: null as any,
|
||||
entities: [],
|
||||
@@ -164,7 +164,7 @@ describe('catalog:register', () => {
|
||||
});
|
||||
|
||||
it('should return entityRef with the next non-generated entity if no Component kind can be found', async () => {
|
||||
catalogService.addLocation
|
||||
catalogMock.addLocation
|
||||
.mockResolvedValueOnce({
|
||||
location: null as any,
|
||||
entities: [],
|
||||
@@ -208,7 +208,7 @@ describe('catalog:register', () => {
|
||||
});
|
||||
|
||||
it('should return entityRef with the first entity if no non-generated entities can be found', async () => {
|
||||
catalogService.addLocation
|
||||
catalogMock.addLocation
|
||||
.mockResolvedValueOnce({
|
||||
location: null as any,
|
||||
entities: [],
|
||||
@@ -245,7 +245,7 @@ describe('catalog:register', () => {
|
||||
});
|
||||
|
||||
it('should not return entityRef if there are no entities', async () => {
|
||||
catalogService.addLocation
|
||||
catalogMock.addLocation
|
||||
.mockResolvedValueOnce({
|
||||
location: null as any,
|
||||
entities: [],
|
||||
@@ -267,7 +267,7 @@ describe('catalog:register', () => {
|
||||
});
|
||||
|
||||
it('should ignore failures when dry running the location in the catalog if `optional` is set', async () => {
|
||||
catalogService.addLocation
|
||||
catalogMock.addLocation
|
||||
.mockRejectedValueOnce(new Error('Not found'))
|
||||
.mockRejectedValueOnce(new Error('Not found'));
|
||||
await action.handler({
|
||||
@@ -278,7 +278,7 @@ describe('catalog:register', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(catalogService.addLocation).toHaveBeenNthCalledWith(
|
||||
expect(catalogMock.addLocation).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
{
|
||||
type: 'url',
|
||||
@@ -286,7 +286,7 @@ describe('catalog:register', () => {
|
||||
},
|
||||
{ credentials },
|
||||
);
|
||||
expect(catalogService.addLocation).toHaveBeenNthCalledWith(
|
||||
expect(catalogMock.addLocation).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
{
|
||||
dryRun: true,
|
||||
@@ -303,7 +303,7 @@ describe('catalog:register', () => {
|
||||
});
|
||||
|
||||
it('should fetch entities when adding location in the catalog fails and `optional` is set', async () => {
|
||||
catalogService.addLocation
|
||||
catalogMock.addLocation
|
||||
.mockRejectedValueOnce(new Error('Already registered'))
|
||||
.mockResolvedValueOnce({
|
||||
location: null as any,
|
||||
@@ -325,7 +325,7 @@ describe('catalog:register', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(catalogService.addLocation).toHaveBeenNthCalledWith(
|
||||
expect(catalogMock.addLocation).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
{
|
||||
type: 'url',
|
||||
@@ -333,7 +333,7 @@ describe('catalog:register', () => {
|
||||
},
|
||||
{ credentials },
|
||||
);
|
||||
expect(catalogService.addLocation).toHaveBeenNthCalledWith(
|
||||
expect(catalogMock.addLocation).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
{
|
||||
dryRun: true,
|
||||
|
||||
@@ -28,10 +28,10 @@ const id = 'catalog:register';
|
||||
* @public
|
||||
*/
|
||||
export function createCatalogRegisterAction(options: {
|
||||
catalogService: CatalogService;
|
||||
catalog: CatalogService;
|
||||
integrations: ScmIntegrations;
|
||||
}) {
|
||||
const { catalogService, integrations } = options;
|
||||
const { catalog, integrations } = options;
|
||||
|
||||
return createTemplateAction({
|
||||
id,
|
||||
@@ -99,7 +99,7 @@ export function createCatalogRegisterAction(options: {
|
||||
|
||||
try {
|
||||
// 1st try to register the location, this will throw an error if the location already exists (see catch)
|
||||
await catalogService.addLocation(
|
||||
await catalog.addLocation(
|
||||
{
|
||||
type: 'url',
|
||||
target: catalogInfoUrl,
|
||||
@@ -115,7 +115,7 @@ export function createCatalogRegisterAction(options: {
|
||||
|
||||
try {
|
||||
// 2nd retry the registration as a dry run, this will not throw an error if the location already exists
|
||||
const result = await catalogService.addLocation(
|
||||
const result = await catalog.addLocation(
|
||||
{
|
||||
dryRun: true,
|
||||
type: 'url',
|
||||
|
||||
@@ -92,16 +92,16 @@ export function getEntityBaseUrl(entity: Entity): string | undefined {
|
||||
*/
|
||||
export async function findTemplate(options: {
|
||||
entityRef: CompoundEntityRef;
|
||||
catalogService: CatalogService;
|
||||
catalog: CatalogService;
|
||||
credentials: BackstageCredentials;
|
||||
}): Promise<TemplateEntityV1beta3> {
|
||||
const { entityRef, catalogService, credentials } = options;
|
||||
const { entityRef, catalog, credentials } = options;
|
||||
|
||||
if (entityRef.kind.toLocaleLowerCase('en-US') !== 'template') {
|
||||
throw new InputError(`Invalid kind, only 'Template' kind is supported`);
|
||||
}
|
||||
|
||||
const template = await catalogService.getEntityByRef(entityRef, {
|
||||
const template = await catalog.getEntityByRef(entityRef, {
|
||||
credentials,
|
||||
});
|
||||
if (!template) {
|
||||
|
||||
@@ -187,7 +187,7 @@ describe.each([
|
||||
let app: express.Express;
|
||||
let loggerSpy: jest.SpyInstance;
|
||||
let taskBroker: TaskBroker;
|
||||
const catalogService = catalogServiceMock.mock();
|
||||
const catalogMock = catalogServiceMock.mock();
|
||||
const permissionApi = {
|
||||
authorize: jest.fn(),
|
||||
authorizeConditional: jest.fn(),
|
||||
@@ -298,7 +298,7 @@ describe.each([
|
||||
logger: logger,
|
||||
config: new ConfigReader({}),
|
||||
database: createDatabase(),
|
||||
catalogService,
|
||||
catalog: catalogMock,
|
||||
taskBroker,
|
||||
permissions: permissionApi,
|
||||
auth,
|
||||
@@ -322,7 +322,7 @@ describe.each([
|
||||
});
|
||||
app = express().use(router);
|
||||
|
||||
catalogService.getEntityByRef.mockImplementation(async ref => {
|
||||
catalogMock.getEntityByRef.mockImplementation(async ref => {
|
||||
const { kind } = parseEntityRef(ref);
|
||||
|
||||
if (kind.toLocaleLowerCase() === 'template') {
|
||||
@@ -856,9 +856,9 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{
|
||||
directoryContents: [],
|
||||
});
|
||||
|
||||
expect(catalogService.getEntityByRef).toHaveBeenCalledTimes(1);
|
||||
expect(catalogMock.getEntityByRef).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(catalogService.getEntityByRef).toHaveBeenCalledWith(
|
||||
expect(catalogMock.getEntityByRef).toHaveBeenCalledWith(
|
||||
'user:default/mock',
|
||||
expect.anything(),
|
||||
);
|
||||
@@ -884,7 +884,7 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{
|
||||
logger: logger,
|
||||
config: new ConfigReader({}),
|
||||
database: createDatabase(),
|
||||
catalogService,
|
||||
catalog: catalogMock,
|
||||
taskBroker,
|
||||
permissions: permissionApi,
|
||||
auth,
|
||||
@@ -905,7 +905,7 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{
|
||||
});
|
||||
app = express().use(router);
|
||||
|
||||
catalogService.getEntityByRef.mockImplementation(async ref => {
|
||||
catalogMock.getEntityByRef.mockImplementation(async ref => {
|
||||
const { kind } = parseEntityRef(ref);
|
||||
|
||||
if (kind.toLocaleLowerCase() === 'template') {
|
||||
@@ -1662,7 +1662,7 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{
|
||||
logger: loggerToWinstonLogger(mockServices.logger.mock()),
|
||||
config: new ConfigReader({}),
|
||||
database: createDatabase(),
|
||||
catalogService,
|
||||
catalog: catalogMock,
|
||||
taskBroker,
|
||||
permissions: permissionApi,
|
||||
auth,
|
||||
|
||||
@@ -122,7 +122,7 @@ export interface RouterOptions {
|
||||
config: Config;
|
||||
lifecycle?: LifecycleService;
|
||||
database: DatabaseService;
|
||||
catalogService: CatalogService;
|
||||
catalog: CatalogService;
|
||||
scheduler?: SchedulerService;
|
||||
actions?: TemplateAction<any, any, any>[];
|
||||
/**
|
||||
@@ -178,7 +178,7 @@ export async function createRouter(
|
||||
logger: parentLogger,
|
||||
config,
|
||||
database,
|
||||
catalogService,
|
||||
catalog,
|
||||
actions,
|
||||
scheduler,
|
||||
additionalTemplateFilters,
|
||||
@@ -439,7 +439,7 @@ export async function createRouter(
|
||||
: undefined;
|
||||
|
||||
const userEntity = userEntityRef
|
||||
? await catalogService.getEntityByRef(userEntityRef, { credentials })
|
||||
? await catalog.getEntityByRef(userEntityRef, { credentials })
|
||||
: undefined;
|
||||
|
||||
let auditLog = `Scaffolding task for ${templateRef}`;
|
||||
@@ -862,7 +862,7 @@ export async function createRouter(
|
||||
: undefined;
|
||||
|
||||
const userEntity = userEntityRef
|
||||
? await catalogService.getEntityByRef(userEntityRef, { credentials })
|
||||
? await catalog.getEntityByRef(userEntityRef, { credentials })
|
||||
: undefined;
|
||||
|
||||
const templateRef: string = `${template.kind}:${
|
||||
@@ -994,7 +994,7 @@ export async function createRouter(
|
||||
credentials: BackstageCredentials,
|
||||
) {
|
||||
const template = await findTemplate({
|
||||
catalogService,
|
||||
catalog,
|
||||
entityRef,
|
||||
credentials,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user