@backstage/plugin-scaffolder-backend 1.5.0-next.1 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,48 @@
1
1
  # @backstage/plugin-scaffolder-backend
2
2
 
3
+ ## 1.5.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Fix minimum required version for `vm2`
8
+
9
+ ## 1.5.0
10
+
11
+ ### Minor Changes
12
+
13
+ - c4b452e16a: Starting the implementation of the Wizard page for the `next` scaffolder plugin
14
+ - 593dea6710: Add support for Basic Auth for Bitbucket Server.
15
+ - 3b7930b3e5: Add support for Bearer Authorization header / token-based auth at Git commands.
16
+ - 3f1316f1c5: User Bearer Authorization header at Git commands with token-based auth at Bitbucket Server.
17
+ - eeff5046ae: Updated `publish:gitlab:merge-request` action to allow commit updates and deletes
18
+ - 692d5d3405: Added `reviewers` and `teamReviewers` parameters to `publish:github:pull-request` action to add reviewers on the pull request created by the action
19
+
20
+ ### Patch Changes
21
+
22
+ - fc8a5f797b: Add a `publish:gerrit:review` scaffolder action
23
+ - c971afbf21: The `publish:file` action has been deprecated in favor of testing templates using the template editor instead. Note that this action is not and was never been installed by default.
24
+ - b10b6c4aa4: Fix issue on Windows where templated files where not properly skipped as intended.
25
+ - 56e1b4b89c: Fixed typos in alpha types.
26
+ - dad0f65494: Fail gracefully if an invalid `Authorization` header is passed to `POST /v2/tasks`
27
+ - 014b3b7776: Add missing `res.end()` in scaffolder backend `EventStream` usage
28
+ - Updated dependencies
29
+ - @backstage/backend-common@0.15.0
30
+ - @backstage/backend-plugin-api@0.1.1
31
+ - @backstage/plugin-catalog-node@1.0.1
32
+ - @backstage/integration@1.3.0
33
+ - @backstage/plugin-catalog-backend@1.3.1
34
+
35
+ ## 1.5.0-next.2
36
+
37
+ ### Minor Changes
38
+
39
+ - 692d5d3405: Added `reviewers` and `teamReviewers` parameters to `publish:github:pull-request` action to add reviewers on the pull request created by the action
40
+
41
+ ### Patch Changes
42
+
43
+ - Updated dependencies
44
+ - @backstage/plugin-catalog-backend@1.3.1-next.2
45
+
3
46
  ## 1.5.0-next.1
4
47
 
5
48
  ### Minor Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-scaffolder-backend",
3
- "version": "1.5.0-next.1",
3
+ "version": "1.5.1",
4
4
  "main": "../dist/index.cjs.js",
5
5
  "types": "../dist/index.alpha.d.ts"
6
6
  }
@@ -6,7 +6,7 @@
6
6
 
7
7
  /// <reference types="node" />
8
8
 
9
- import { BackendRegistrable } from '@backstage/backend-plugin-api';
9
+ import { BackendFeature } from '@backstage/backend-plugin-api';
10
10
  import { CatalogApi } from '@backstage/catalog-client';
11
11
  import { CatalogProcessor } from '@backstage/plugin-catalog-backend';
12
12
  import { CatalogProcessorEmit } from '@backstage/plugin-catalog-backend';
@@ -21,6 +21,7 @@ import { Knex } from 'knex';
21
21
  import { LocationSpec } from '@backstage/plugin-catalog-backend';
22
22
  import { Logger } from 'winston';
23
23
  import { Observable } from '@backstage/types';
24
+ import { Octokit } from 'octokit';
24
25
  import { PluginDatabaseManager } from '@backstage/backend-common';
25
26
  import { Schema } from 'jsonschema';
26
27
  import { ScmIntegrationRegistry } from '@backstage/integration';
@@ -418,6 +419,7 @@ token?: string | undefined;
418
419
  * production, as it writes the files to the local filesystem of the scaffolder.
419
420
  *
420
421
  * @public
422
+ * @deprecated This action will be removed, prefer testing templates using the template editor instead.
421
423
  */
422
424
  export declare function createPublishFileAction(): TemplateAction< {
423
425
  path: string;
@@ -513,6 +515,8 @@ draft?: boolean | undefined;
513
515
  targetPath?: string | undefined;
514
516
  sourcePath?: string | undefined;
515
517
  token?: string | undefined;
518
+ reviewers?: string[] | undefined;
519
+ teamReviewers?: string[] | undefined;
516
520
  }>;
517
521
 
518
522
  /**
@@ -676,14 +680,14 @@ export declare function fetchContents({ reader, integrations, baseUrl, fetchUrl,
676
680
  }): Promise<void>;
677
681
 
678
682
  /** @public */
679
- export declare interface OctokitWithPullRequestPluginClient {
683
+ export declare type OctokitWithPullRequestPluginClient = Octokit & {
680
684
  createPullRequest(options: createPullRequest.Options): Promise<{
681
685
  data: {
682
686
  html_url: string;
683
687
  number: number;
684
688
  };
685
689
  } | null>;
686
- }
690
+ };
687
691
 
688
692
  /**
689
693
  * RouterOptions
@@ -718,7 +722,7 @@ export declare type RunCommandOptions = {
718
722
  * @alpha
719
723
  * Registers the ScaffolderEntitiesProcessor with the catalog processing extension point.
720
724
  */
721
- export declare const scaffolderCatalogModule: (option: unknown) => BackendRegistrable;
725
+ export declare const scaffolderCatalogModule: (options?: unknown) => BackendFeature;
722
726
 
723
727
  /** @public */
724
728
  export declare class ScaffolderEntitiesProcessor implements CatalogProcessor {
@@ -6,7 +6,7 @@
6
6
 
7
7
  /// <reference types="node" />
8
8
 
9
- import { BackendRegistrable } from '@backstage/backend-plugin-api';
9
+ import { BackendFeature } from '@backstage/backend-plugin-api';
10
10
  import { CatalogApi } from '@backstage/catalog-client';
11
11
  import { CatalogProcessor } from '@backstage/plugin-catalog-backend';
12
12
  import { CatalogProcessorEmit } from '@backstage/plugin-catalog-backend';
@@ -21,6 +21,7 @@ import { Knex } from 'knex';
21
21
  import { LocationSpec } from '@backstage/plugin-catalog-backend';
22
22
  import { Logger } from 'winston';
23
23
  import { Observable } from '@backstage/types';
24
+ import { Octokit } from 'octokit';
24
25
  import { PluginDatabaseManager } from '@backstage/backend-common';
25
26
  import { Schema } from 'jsonschema';
26
27
  import { ScmIntegrationRegistry } from '@backstage/integration';
@@ -418,6 +419,7 @@ token?: string | undefined;
418
419
  * production, as it writes the files to the local filesystem of the scaffolder.
419
420
  *
420
421
  * @public
422
+ * @deprecated This action will be removed, prefer testing templates using the template editor instead.
421
423
  */
422
424
  export declare function createPublishFileAction(): TemplateAction< {
423
425
  path: string;
@@ -513,6 +515,8 @@ draft?: boolean | undefined;
513
515
  targetPath?: string | undefined;
514
516
  sourcePath?: string | undefined;
515
517
  token?: string | undefined;
518
+ reviewers?: string[] | undefined;
519
+ teamReviewers?: string[] | undefined;
516
520
  }>;
517
521
 
518
522
  /**
@@ -676,14 +680,14 @@ export declare function fetchContents({ reader, integrations, baseUrl, fetchUrl,
676
680
  }): Promise<void>;
677
681
 
678
682
  /** @public */
679
- export declare interface OctokitWithPullRequestPluginClient {
683
+ export declare type OctokitWithPullRequestPluginClient = Octokit & {
680
684
  createPullRequest(options: createPullRequest.Options): Promise<{
681
685
  data: {
682
686
  html_url: string;
683
687
  number: number;
684
688
  };
685
689
  } | null>;
686
- }
690
+ };
687
691
 
688
692
  /**
689
693
  * RouterOptions
package/dist/index.cjs.js CHANGED
@@ -673,7 +673,7 @@ function createFetchTemplateAction(options) {
673
673
  });
674
674
  }
675
675
  function containsSkippedContent(localOutputPath) {
676
- return localOutputPath === "" || path__default["default"].isAbsolute(localOutputPath) || localOutputPath.includes(`${path__default["default"].sep}${path__default["default"].sep}`);
676
+ return localOutputPath === "" || localOutputPath.startsWith("/") || localOutputPath.includes("//");
677
677
  }
678
678
 
679
679
  const createFilesystemDeleteAction = () => {
@@ -2561,6 +2561,9 @@ function createPublishFileAction() {
2561
2561
  }
2562
2562
  },
2563
2563
  async handler(ctx) {
2564
+ ctx.logger.warn(
2565
+ "[DEPRECATED] This action will be removed, prefer testing templates using the template editor instead."
2566
+ );
2564
2567
  const { path: path$1 } = ctx.input;
2565
2568
  const exists = await fs__default["default"].pathExists(path$1);
2566
2569
  if (exists) {
@@ -3055,6 +3058,22 @@ const createPublishGithubPullRequestAction = ({
3055
3058
  title: "Authentication Token",
3056
3059
  type: "string",
3057
3060
  description: "The token to use for authorization to GitHub"
3061
+ },
3062
+ reviewers: {
3063
+ title: "Pull Request Reviewers",
3064
+ type: "array",
3065
+ items: {
3066
+ type: "string"
3067
+ },
3068
+ description: "The users that will be added as reviewers to the pull request"
3069
+ },
3070
+ teamReviewers: {
3071
+ title: "Pull Request Team Reviewers",
3072
+ type: "array",
3073
+ items: {
3074
+ type: "string"
3075
+ },
3076
+ description: "The teams that will be added as reviewers to the pull request"
3058
3077
  }
3059
3078
  }
3060
3079
  },
@@ -3084,7 +3103,9 @@ const createPublishGithubPullRequestAction = ({
3084
3103
  draft,
3085
3104
  targetPath,
3086
3105
  sourcePath,
3087
- token: providedToken
3106
+ token: providedToken,
3107
+ reviewers,
3108
+ teamReviewers
3088
3109
  } = ctx.input;
3089
3110
  const { owner, repo, host } = parseRepoUrl(repoUrl, integrations);
3090
3111
  if (!owner) {
@@ -3132,13 +3153,46 @@ const createPublishGithubPullRequestAction = ({
3132
3153
  if (!response) {
3133
3154
  throw new GithubResponseError("null response from Github");
3134
3155
  }
3156
+ const pullRequestNumber = response.data.number;
3157
+ if (reviewers || teamReviewers) {
3158
+ const pullRequest = { owner, repo, number: pullRequestNumber };
3159
+ await requestReviewersOnPullRequest(
3160
+ pullRequest,
3161
+ reviewers,
3162
+ teamReviewers,
3163
+ client,
3164
+ ctx.logger
3165
+ );
3166
+ }
3135
3167
  ctx.output("remoteUrl", response.data.html_url);
3136
- ctx.output("pullRequestNumber", response.data.number);
3168
+ ctx.output("pullRequestNumber", pullRequestNumber);
3137
3169
  } catch (e) {
3138
3170
  throw new GithubResponseError("Pull request creation failed", e);
3139
3171
  }
3140
3172
  }
3141
3173
  });
3174
+ async function requestReviewersOnPullRequest(pr, reviewers, teamReviewers, client, logger) {
3175
+ var _a, _b, _c, _d;
3176
+ try {
3177
+ const result = await client.rest.pulls.requestReviewers({
3178
+ owner: pr.owner,
3179
+ repo: pr.repo,
3180
+ pull_number: pr.number,
3181
+ reviewers,
3182
+ team_reviewers: teamReviewers
3183
+ });
3184
+ const addedUsers = (_b = (_a = result.data.requested_reviewers) == null ? void 0 : _a.join(", ")) != null ? _b : "";
3185
+ const addedTeams = (_d = (_c = result.data.requested_teams) == null ? void 0 : _c.join(", ")) != null ? _d : "";
3186
+ logger.info(
3187
+ `Added users [${addedUsers}] and teams [${addedTeams}] as reviewers to Pull request ${pr.number}`
3188
+ );
3189
+ } catch (e) {
3190
+ logger.error(
3191
+ `Failure when adding reviewers to Pull request ${pr.number}`,
3192
+ e
3193
+ );
3194
+ }
3195
+ }
3142
3196
  };
3143
3197
 
3144
3198
  function createPublishGitlabAction(options) {
@@ -4455,7 +4509,10 @@ async function createRouter(options) {
4455
4509
  async (req, res) => {
4456
4510
  var _a, _b;
4457
4511
  const { namespace, kind, name } = req.params;
4458
- const { token } = parseBearerToken(req.headers.authorization);
4512
+ const { token } = parseBearerToken({
4513
+ header: req.headers.authorization,
4514
+ logger
4515
+ });
4459
4516
  const template = await findTemplate({
4460
4517
  catalogApi: catalogClient,
4461
4518
  entityRef: { kind, namespace, name },
@@ -4496,9 +4553,10 @@ async function createRouter(options) {
4496
4553
  const { kind, namespace, name } = catalogModel.parseEntityRef(templateRef, {
4497
4554
  defaultKind: "template"
4498
4555
  });
4499
- const { token, entityRef: userEntityRef } = parseBearerToken(
4500
- req.headers.authorization
4501
- );
4556
+ const { token, entityRef: userEntityRef } = parseBearerToken({
4557
+ header: req.headers.authorization,
4558
+ logger
4559
+ });
4502
4560
  const userEntity = userEntityRef ? await catalogClient.getEntityByRef(userEntityRef, { token }) : void 0;
4503
4561
  let auditLog = `Scaffolding task for ${templateRef}`;
4504
4562
  if (userEntityRef) {
@@ -4660,7 +4718,10 @@ data: ${JSON.stringify(event)}
4660
4718
  if (!await pluginScaffolderCommon.templateEntityV1beta3Validator.check(template)) {
4661
4719
  throw new errors.InputError("Input template is not a template");
4662
4720
  }
4663
- const { token } = parseBearerToken(req.headers.authorization);
4721
+ const { token } = parseBearerToken({
4722
+ header: req.headers.authorization,
4723
+ logger
4724
+ });
4664
4725
  for (const parameters of [(_a = template.spec.parameters) != null ? _a : []].flat()) {
4665
4726
  const result2 = jsonschema.validate(body.values, parameters);
4666
4727
  if (!result2.valid) {
@@ -4707,7 +4768,10 @@ data: ${JSON.stringify(event)}
4707
4768
  app.use("/", router);
4708
4769
  return app;
4709
4770
  }
4710
- function parseBearerToken(header) {
4771
+ function parseBearerToken({
4772
+ header,
4773
+ logger
4774
+ }) {
4711
4775
  var _a;
4712
4776
  if (!header) {
4713
4777
  return {};
@@ -4728,9 +4792,11 @@ function parseBearerToken(header) {
4728
4792
  if (typeof sub !== "string") {
4729
4793
  throw new TypeError("Expected string sub claim");
4730
4794
  }
4795
+ catalogModel.parseEntityRef(sub);
4731
4796
  return { entityRef: sub, token };
4732
4797
  } catch (e) {
4733
- throw new errors.InputError(`Invalid authorization header: ${errors.stringifyError(e)}`);
4798
+ logger.error(`Invalid authorization header: ${errors.stringifyError(e)}`);
4799
+ return {};
4734
4800
  }
4735
4801
  }
4736
4802
 
@@ -4793,12 +4859,10 @@ const scaffolderCatalogModule = backendPluginApi.createBackendModule({
4793
4859
  register(env) {
4794
4860
  env.registerInit({
4795
4861
  deps: {
4796
- catalogProcessingExtensionPoint: pluginCatalogNode.catalogProcessingExtentionPoint
4862
+ catalog: pluginCatalogNode.catalogProcessingExtensionPoint
4797
4863
  },
4798
- async init({ catalogProcessingExtensionPoint }) {
4799
- catalogProcessingExtensionPoint.addProcessor(
4800
- new ScaffolderEntitiesProcessor()
4801
- );
4864
+ async init({ catalog }) {
4865
+ catalog.addProcessor(new ScaffolderEntitiesProcessor());
4802
4866
  }
4803
4867
  });
4804
4868
  }