Merge branch 'master' of github.com:backstage/backstage into RoadieHQ-5identity-api-client-interface
This commit is contained in:
@@ -1,5 +1,18 @@
|
||||
# @backstage/plugin-scaffolder-backend
|
||||
|
||||
## 1.6.0-next.1
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 7db9613671: Added `projectId` for gitlab projects to be displayed in the `gitlab:publish` output
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 0d8d650e32: Applied the fix from version 1.5.1 of this package, which is part of the v1.5.1 release of Backstage.
|
||||
- Updated dependencies
|
||||
- @backstage/backend-common@0.15.1-next.1
|
||||
- @backstage/plugin-catalog-backend@1.4.0-next.1
|
||||
|
||||
## 1.6.0-next.0
|
||||
|
||||
### Minor Changes
|
||||
@@ -34,6 +47,12 @@
|
||||
- @backstage/plugin-scaffolder-common@1.2.0-next.0
|
||||
- @backstage/plugin-catalog-node@1.0.2-next.0
|
||||
|
||||
## 1.5.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Fix minimum required version for `vm2`
|
||||
|
||||
## 1.5.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/plugin-scaffolder-backend",
|
||||
"description": "The Backstage backend plugin that helps you create new things",
|
||||
"version": "1.6.0-next.0",
|
||||
"version": "1.6.0-next.1",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -35,14 +35,14 @@
|
||||
"build:assets": "node scripts/build-nunjucks.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.15.1-next.0",
|
||||
"@backstage/backend-common": "^0.15.1-next.1",
|
||||
"@backstage/catalog-client": "^1.0.5-next.0",
|
||||
"@backstage/catalog-model": "^1.1.0",
|
||||
"@backstage/config": "^1.0.1",
|
||||
"@backstage/errors": "^1.1.0",
|
||||
"@backstage/integration": "^1.3.1-next.0",
|
||||
"@backstage/plugin-auth-node": "^0.2.5-next.0",
|
||||
"@backstage/plugin-catalog-backend": "^1.3.2-next.0",
|
||||
"@backstage/plugin-catalog-backend": "^1.4.0-next.1",
|
||||
"@backstage/plugin-scaffolder-common": "^1.2.0-next.0",
|
||||
"@backstage/backend-plugin-api": "^0.1.2-next.0",
|
||||
"@backstage/plugin-catalog-node": "^1.0.2-next.0",
|
||||
@@ -75,13 +75,13 @@
|
||||
"uuid": "^8.2.0",
|
||||
"winston": "^3.2.1",
|
||||
"yaml": "^2.0.0",
|
||||
"vm2": "^3.9.6",
|
||||
"vm2": "^3.9.11",
|
||||
"zen-observable": "^0.8.15",
|
||||
"zod": "^3.11.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/backend-test-utils": "^0.1.28-next.0",
|
||||
"@backstage/cli": "^0.18.2-next.0",
|
||||
"@backstage/backend-test-utils": "^0.1.28-next.1",
|
||||
"@backstage/cli": "^0.19.0-next.1",
|
||||
"@types/command-exists": "^1.2.0",
|
||||
"@types/fs-extra": "^9.0.1",
|
||||
"@types/git-url-parse": "^9.0.0",
|
||||
|
||||
@@ -58,8 +58,8 @@ describe('ScaffolderEntitiesProcessor', () => {
|
||||
|
||||
await processor.postProcessEntity(mockEntity, mockLocation, emit);
|
||||
|
||||
expect(emit).toBeCalledTimes(2);
|
||||
expect(emit).toBeCalledWith({
|
||||
expect(emit).toHaveBeenCalledTimes(2);
|
||||
expect(emit).toHaveBeenCalledWith({
|
||||
type: 'relation',
|
||||
relation: {
|
||||
source: { kind: 'Group', namespace: 'default', name: 'o' },
|
||||
@@ -67,7 +67,7 @@ describe('ScaffolderEntitiesProcessor', () => {
|
||||
target: { kind: 'Template', namespace: 'default', name: 'n' },
|
||||
},
|
||||
});
|
||||
expect(emit).toBeCalledWith({
|
||||
expect(emit).toHaveBeenCalledWith({
|
||||
type: 'relation',
|
||||
relation: {
|
||||
source: { kind: 'Template', namespace: 'default', name: 'n' },
|
||||
|
||||
@@ -107,11 +107,11 @@ describe('catalog:register', () => {
|
||||
{},
|
||||
);
|
||||
|
||||
expect(mockContext.output).toBeCalledWith(
|
||||
expect(mockContext.output).toHaveBeenCalledWith(
|
||||
'entityRef',
|
||||
'component:default/test',
|
||||
);
|
||||
expect(mockContext.output).toBeCalledWith(
|
||||
expect(mockContext.output).toHaveBeenCalledWith(
|
||||
'catalogInfoUrl',
|
||||
'http://foo/var',
|
||||
);
|
||||
@@ -160,7 +160,7 @@ describe('catalog:register', () => {
|
||||
catalogInfoUrl: 'http://foo/var',
|
||||
},
|
||||
});
|
||||
expect(mockContext.output).toBeCalledWith(
|
||||
expect(mockContext.output).toHaveBeenCalledWith(
|
||||
'entityRef',
|
||||
'component:default/test',
|
||||
);
|
||||
@@ -202,7 +202,10 @@ describe('catalog:register', () => {
|
||||
catalogInfoUrl: 'http://foo/var',
|
||||
},
|
||||
});
|
||||
expect(mockContext.output).toBeCalledWith('entityRef', 'api:default/test');
|
||||
expect(mockContext.output).toHaveBeenCalledWith(
|
||||
'entityRef',
|
||||
'api:default/test',
|
||||
);
|
||||
});
|
||||
|
||||
it('should return entityRef with the first entity if no non-generated entities can be found', async () => {
|
||||
@@ -234,7 +237,7 @@ describe('catalog:register', () => {
|
||||
catalogInfoUrl: 'http://foo/var',
|
||||
},
|
||||
});
|
||||
expect(mockContext.output).toBeCalledWith(
|
||||
expect(mockContext.output).toHaveBeenCalledWith(
|
||||
'entityRef',
|
||||
'location:default/generated-1238',
|
||||
);
|
||||
@@ -254,7 +257,7 @@ describe('catalog:register', () => {
|
||||
catalogInfoUrl: 'http://foo/var',
|
||||
},
|
||||
});
|
||||
expect(mockContext.output).not.toBeCalledWith(
|
||||
expect(mockContext.output).not.toHaveBeenCalledWith(
|
||||
'entityRef',
|
||||
expect.any(String),
|
||||
);
|
||||
@@ -292,7 +295,7 @@ describe('catalog:register', () => {
|
||||
{},
|
||||
);
|
||||
|
||||
expect(mockContext.output).toBeCalledWith(
|
||||
expect(mockContext.output).toHaveBeenCalledWith(
|
||||
'catalogInfoUrl',
|
||||
'http://foo/var',
|
||||
);
|
||||
|
||||
@@ -54,7 +54,7 @@ describe('debug:log', () => {
|
||||
it('should do nothing', async () => {
|
||||
await action.handler(mockContext);
|
||||
|
||||
expect(logStream.write).toBeCalledTimes(0);
|
||||
expect(logStream.write).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('should log the workspace content, if active', async () => {
|
||||
@@ -67,11 +67,11 @@ describe('debug:log', () => {
|
||||
|
||||
await action.handler(context);
|
||||
|
||||
expect(logStream.write).toBeCalledTimes(1);
|
||||
expect(logStream.write).toBeCalledWith(
|
||||
expect(logStream.write).toHaveBeenCalledTimes(1);
|
||||
expect(logStream.write).toHaveBeenCalledWith(
|
||||
expect.stringContaining('README.md'),
|
||||
);
|
||||
expect(logStream.write).toBeCalledWith(
|
||||
expect(logStream.write).toHaveBeenCalledWith(
|
||||
expect.stringContaining(join('a-directory', 'index.md')),
|
||||
);
|
||||
});
|
||||
@@ -86,8 +86,8 @@ describe('debug:log', () => {
|
||||
|
||||
await action.handler(context);
|
||||
|
||||
expect(logStream.write).toBeCalledTimes(1);
|
||||
expect(logStream.write).toBeCalledWith(
|
||||
expect(logStream.write).toHaveBeenCalledTimes(1);
|
||||
expect(logStream.write).toHaveBeenCalledWith(
|
||||
expect.stringContaining('Hello Backstage!'),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -81,7 +81,7 @@ describe('fetchContent helper', () => {
|
||||
fetchUrl: 'foo',
|
||||
outputPath: 'somepath',
|
||||
});
|
||||
expect(fs.copy).toBeCalledWith(resolvePath('/some/foo'), 'somepath');
|
||||
expect(fs.copy).toHaveBeenCalledWith(resolvePath('/some/foo'), 'somepath');
|
||||
});
|
||||
|
||||
it('should reject if no integration matches location', async () => {
|
||||
@@ -116,7 +116,7 @@ describe('fetchContent helper', () => {
|
||||
outputPath: 'foo',
|
||||
fetchUrl: 'https://github.com/backstage/foo',
|
||||
});
|
||||
expect(fs.ensureDir).toBeCalled();
|
||||
expect(dirFunction).toBeCalledWith({ targetDir: 'foo' });
|
||||
expect(fs.ensureDir).toHaveBeenCalled();
|
||||
expect(dirFunction).toHaveBeenCalledWith({ targetDir: 'foo' });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -73,7 +73,7 @@ describe('fetch:plain', () => {
|
||||
targetPath: 'lol',
|
||||
},
|
||||
});
|
||||
expect(fetchContents).toBeCalledWith(
|
||||
expect(fetchContents).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
outputPath: resolvePath(mockContext.workspacePath, 'lol'),
|
||||
fetchUrl:
|
||||
|
||||
@@ -117,7 +117,7 @@ describe('fetch:template', () => {
|
||||
it('throws if output directory is outside the workspace', async () => {
|
||||
await expect(() =>
|
||||
action.handler(mockContext({ targetPath: '../' })),
|
||||
).rejects.toThrowError(
|
||||
).rejects.toThrow(
|
||||
/relative path is not allowed to refer to a directory outside its parent/i,
|
||||
);
|
||||
});
|
||||
@@ -127,7 +127,7 @@ describe('fetch:template', () => {
|
||||
action.handler(
|
||||
mockContext({ copyWithoutRender: 'abc' as unknown as string[] }),
|
||||
),
|
||||
).rejects.toThrowError(
|
||||
).rejects.toThrow(
|
||||
/copyWithoutRender\/copyWithoutTemplating must be an array/i,
|
||||
);
|
||||
});
|
||||
@@ -140,7 +140,7 @@ describe('fetch:template', () => {
|
||||
copyWithoutTemplating: 'def' as unknown as string[],
|
||||
}),
|
||||
),
|
||||
).rejects.toThrowError(
|
||||
).rejects.toThrow(
|
||||
/copyWithoutRender and copyWithoutTemplating can not be used at the same time/i,
|
||||
);
|
||||
});
|
||||
@@ -153,7 +153,7 @@ describe('fetch:template', () => {
|
||||
templateFileExtension: true,
|
||||
}),
|
||||
),
|
||||
).rejects.toThrowError(
|
||||
).rejects.toThrow(
|
||||
/input extension incompatible with copyWithoutRender\/copyWithoutTemplating and cookiecutterCompat/,
|
||||
);
|
||||
});
|
||||
@@ -166,7 +166,7 @@ describe('fetch:template', () => {
|
||||
templateFileExtension: true,
|
||||
}),
|
||||
),
|
||||
).rejects.toThrowError(
|
||||
).rejects.toThrow(
|
||||
/input extension incompatible with copyWithoutRender\/copyWithoutTemplating and cookiecutterCompat/,
|
||||
);
|
||||
});
|
||||
|
||||
+4
-4
@@ -302,8 +302,8 @@ describe('createPublishGithubPullRequestAction', () => {
|
||||
it('creates a pull request and requests a review from the given reviewers', async () => {
|
||||
await instance.handler(ctx);
|
||||
|
||||
expect(fakeClient.createPullRequest).toBeCalled();
|
||||
expect(fakeClient.rest.pulls.requestReviewers).toBeCalledWith({
|
||||
expect(fakeClient.createPullRequest).toHaveBeenCalled();
|
||||
expect(fakeClient.rest.pulls.requestReviewers).toHaveBeenCalledWith({
|
||||
owner: 'myorg',
|
||||
repo: 'myrepo',
|
||||
pull_number: 123,
|
||||
@@ -354,8 +354,8 @@ describe('createPublishGithubPullRequestAction', () => {
|
||||
it('does not call the API endpoint for requesting reviewers', async () => {
|
||||
await instance.handler(ctx);
|
||||
|
||||
expect(fakeClient.createPullRequest).toBeCalled();
|
||||
expect(fakeClient.rest.pulls.requestReviewers).not.toBeCalled();
|
||||
expect(fakeClient.createPullRequest).toHaveBeenCalled();
|
||||
expect(fakeClient.rest.pulls.requestReviewers).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -313,11 +313,12 @@ describe('publish:gitlab', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should call output with the remoteUrl and repoContentsUrl', async () => {
|
||||
it('should call output with the remoteUrl and repoContentsUrl and projectId', async () => {
|
||||
mockGitlabClient.Users.current.mockResolvedValue({ id: 12345 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({ id: 1234 });
|
||||
mockGitlabClient.Projects.create.mockResolvedValue({
|
||||
http_url_to_repo: 'http://mockurl.git',
|
||||
id: 1234,
|
||||
});
|
||||
|
||||
await action.handler(mockContext);
|
||||
@@ -330,6 +331,7 @@ describe('publish:gitlab', () => {
|
||||
'repoContentsUrl',
|
||||
'http://mockurl/-/blob/master',
|
||||
);
|
||||
expect(mockContext.output).toHaveBeenCalledWith('projectId', 1234);
|
||||
});
|
||||
|
||||
it('should call the correct Gitlab APIs when setUserAsOwner option is true and integration config has a token', async () => {
|
||||
|
||||
@@ -112,6 +112,10 @@ export function createPublishGitlabAction(options: {
|
||||
title: 'A URL to the root of the repository',
|
||||
type: 'string',
|
||||
},
|
||||
projectId: {
|
||||
title: 'The ID of the project',
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -214,6 +218,7 @@ export function createPublishGitlabAction(options: {
|
||||
|
||||
ctx.output('remoteUrl', remoteUrl);
|
||||
ctx.output('repoContentsUrl', repoContentsUrl);
|
||||
ctx.output('projectId', projectId);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ describe('DefaultWorkflowRunner', () => {
|
||||
steps: [{ id: 'test', name: 'name', action: 'does-not-exist' }],
|
||||
});
|
||||
|
||||
await expect(runner.execute(task)).rejects.toThrowError(
|
||||
await expect(runner.execute(task)).rejects.toThrow(
|
||||
"Template action with ID 'does-not-exist' is not registered.",
|
||||
);
|
||||
});
|
||||
@@ -142,7 +142,7 @@ describe('DefaultWorkflowRunner', () => {
|
||||
steps: [{ id: 'test', name: 'name', action: 'jest-validated-action' }],
|
||||
});
|
||||
|
||||
await expect(runner.execute(task)).rejects.toThrowError(
|
||||
await expect(runner.execute(task)).rejects.toThrow(
|
||||
/Invalid input passed to action jest-validated-action, instance requires property \"foo\"/,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -421,7 +421,7 @@ describe('createRouter', () => {
|
||||
});
|
||||
|
||||
const response = await request(app).get(`/v2/tasks`);
|
||||
expect(taskBroker.list).toBeCalledWith({
|
||||
expect(taskBroker.list).toHaveBeenCalledWith({
|
||||
createdBy: undefined,
|
||||
});
|
||||
expect(response.status).toEqual(200);
|
||||
@@ -456,7 +456,7 @@ describe('createRouter', () => {
|
||||
const response = await request(app).get(
|
||||
`/v2/tasks?createdBy=user:default/foo`,
|
||||
);
|
||||
expect(taskBroker.list).toBeCalledWith({
|
||||
expect(taskBroker.list).toHaveBeenCalledWith({
|
||||
createdBy: 'user:default/foo',
|
||||
});
|
||||
|
||||
@@ -556,18 +556,20 @@ describe('createRouter', () => {
|
||||
|
||||
expect(statusCode).toBe(200);
|
||||
expect(headers['content-type']).toBe('text/event-stream');
|
||||
expect(responseDataFn).toBeCalledTimes(2);
|
||||
expect(responseDataFn).toBeCalledWith(`event: log
|
||||
expect(responseDataFn).toHaveBeenCalledTimes(2);
|
||||
expect(responseDataFn).toHaveBeenCalledWith(`event: log
|
||||
data: {"id":0,"taskId":"a-random-id","type":"log","createdAt":"","body":{"message":"My log message"}}
|
||||
|
||||
`);
|
||||
expect(responseDataFn).toBeCalledWith(`event: completion
|
||||
expect(responseDataFn).toHaveBeenCalledWith(`event: completion
|
||||
data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{"message":"Finished!"}}
|
||||
|
||||
`);
|
||||
|
||||
expect(taskBroker.event$).toBeCalledTimes(1);
|
||||
expect(taskBroker.event$).toBeCalledWith({ taskId: 'a-random-id' });
|
||||
expect(taskBroker.event$).toHaveBeenCalledTimes(1);
|
||||
expect(taskBroker.event$).toHaveBeenCalledWith({
|
||||
taskId: 'a-random-id',
|
||||
});
|
||||
expect(subscriber!.closed).toBe(true);
|
||||
});
|
||||
|
||||
@@ -618,8 +620,8 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{
|
||||
expect(statusCode).toBe(200);
|
||||
expect(headers['content-type']).toBe('text/event-stream');
|
||||
|
||||
expect(taskBroker.event$).toBeCalledTimes(1);
|
||||
expect(taskBroker.event$).toBeCalledWith({
|
||||
expect(taskBroker.event$).toHaveBeenCalledTimes(1);
|
||||
expect(taskBroker.event$).toHaveBeenCalledWith({
|
||||
taskId: 'a-random-id',
|
||||
after: 10,
|
||||
});
|
||||
@@ -677,8 +679,10 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{
|
||||
},
|
||||
]);
|
||||
|
||||
expect(taskBroker.event$).toBeCalledTimes(1);
|
||||
expect(taskBroker.event$).toBeCalledWith({ taskId: 'a-random-id' });
|
||||
expect(taskBroker.event$).toHaveBeenCalledTimes(1);
|
||||
expect(taskBroker.event$).toHaveBeenCalledWith({
|
||||
taskId: 'a-random-id',
|
||||
});
|
||||
expect(subscriber!.closed).toBe(true);
|
||||
});
|
||||
|
||||
@@ -700,8 +704,8 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toEqual([]);
|
||||
|
||||
expect(taskBroker.event$).toBeCalledTimes(1);
|
||||
expect(taskBroker.event$).toBeCalledWith({
|
||||
expect(taskBroker.event$).toHaveBeenCalledTimes(1);
|
||||
expect(taskBroker.event$).toHaveBeenCalledWith({
|
||||
taskId: 'a-random-id',
|
||||
after: 10,
|
||||
});
|
||||
@@ -709,7 +713,6 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('providing an identity api', () => {
|
||||
beforeEach(async () => {
|
||||
const logger = getVoidLogger();
|
||||
|
||||
Reference in New Issue
Block a user