@backstage/plugin-scaffolder-backend 1.27.0-next.1 → 1.27.0-next.3

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.
Files changed (65) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/dist/ScaffolderPlugin.cjs.js +1 -0
  3. package/dist/ScaffolderPlugin.cjs.js.map +1 -1
  4. package/dist/deprecated.cjs.js.map +1 -1
  5. package/dist/index.cjs.js +2 -0
  6. package/dist/index.cjs.js.map +1 -1
  7. package/dist/index.d.ts +21 -1
  8. package/dist/lib/templating/SecureTemplater.cjs.js.map +1 -1
  9. package/dist/lib/templating/filters.cjs.js.map +1 -1
  10. package/dist/lib/templating/helpers.cjs.js.map +1 -1
  11. package/dist/scaffolder/actions/TemplateActionRegistry.cjs.js.map +1 -1
  12. package/dist/scaffolder/actions/builtin/catalog/fetch.cjs.js +11 -11
  13. package/dist/scaffolder/actions/builtin/catalog/fetch.cjs.js.map +1 -1
  14. package/dist/scaffolder/actions/builtin/catalog/fetch.examples.cjs.js.map +1 -1
  15. package/dist/scaffolder/actions/builtin/catalog/register.cjs.js.map +1 -1
  16. package/dist/scaffolder/actions/builtin/catalog/register.examples.cjs.js.map +1 -1
  17. package/dist/scaffolder/actions/builtin/catalog/write.cjs.js +4 -4
  18. package/dist/scaffolder/actions/builtin/catalog/write.cjs.js.map +1 -1
  19. package/dist/scaffolder/actions/builtin/catalog/write.examples.cjs.js.map +1 -1
  20. package/dist/scaffolder/actions/builtin/createBuiltinActions.cjs.js +2 -0
  21. package/dist/scaffolder/actions/builtin/createBuiltinActions.cjs.js.map +1 -1
  22. package/dist/scaffolder/actions/builtin/debug/log.cjs.js +4 -4
  23. package/dist/scaffolder/actions/builtin/debug/log.cjs.js.map +1 -1
  24. package/dist/scaffolder/actions/builtin/debug/log.examples.cjs.js.map +1 -1
  25. package/dist/scaffolder/actions/builtin/debug/wait.cjs.js.map +1 -1
  26. package/dist/scaffolder/actions/builtin/debug/wait.examples.cjs.js.map +1 -1
  27. package/dist/scaffolder/actions/builtin/fetch/plain.cjs.js.map +1 -1
  28. package/dist/scaffolder/actions/builtin/fetch/plain.examples.cjs.js.map +1 -1
  29. package/dist/scaffolder/actions/builtin/fetch/plainFile.cjs.js.map +1 -1
  30. package/dist/scaffolder/actions/builtin/fetch/plainFile.examples.cjs.js.map +1 -1
  31. package/dist/scaffolder/actions/builtin/fetch/template.cjs.js.map +1 -1
  32. package/dist/scaffolder/actions/builtin/fetch/template.examples.cjs.js.map +1 -1
  33. package/dist/scaffolder/actions/builtin/fetch/templateFile.cjs.js.map +1 -1
  34. package/dist/scaffolder/actions/builtin/fetch/templateFile.examples.cjs.js.map +1 -1
  35. package/dist/scaffolder/actions/builtin/filesystem/delete.cjs.js.map +1 -1
  36. package/dist/scaffolder/actions/builtin/filesystem/delete.examples.cjs.js.map +1 -1
  37. package/dist/scaffolder/actions/builtin/filesystem/read.cjs.js +68 -0
  38. package/dist/scaffolder/actions/builtin/filesystem/read.cjs.js.map +1 -0
  39. package/dist/scaffolder/actions/builtin/filesystem/rename.cjs.js.map +1 -1
  40. package/dist/scaffolder/actions/builtin/filesystem/rename.examples.cjs.js.map +1 -1
  41. package/dist/scaffolder/actions/deprecated.cjs.js.map +1 -1
  42. package/dist/scaffolder/dryrun/DecoratedActionsRegistry.cjs.js +1 -0
  43. package/dist/scaffolder/dryrun/DecoratedActionsRegistry.cjs.js.map +1 -1
  44. package/dist/scaffolder/dryrun/createDryRunner.cjs.js +10 -12
  45. package/dist/scaffolder/dryrun/createDryRunner.cjs.js.map +1 -1
  46. package/dist/scaffolder/tasks/DatabaseTaskStore.cjs.js.map +1 -1
  47. package/dist/scaffolder/tasks/DatabaseWorkspaceProvider.cjs.js.map +1 -1
  48. package/dist/scaffolder/tasks/NunjucksWorkflowRunner.cjs.js.map +1 -1
  49. package/dist/scaffolder/tasks/StorageTaskBroker.cjs.js.map +1 -1
  50. package/dist/scaffolder/tasks/TaskWorker.cjs.js.map +1 -1
  51. package/dist/scaffolder/tasks/WorkspaceService.cjs.js.map +1 -1
  52. package/dist/scaffolder/tasks/dbUtil.cjs.js.map +1 -1
  53. package/dist/scaffolder/tasks/helper.cjs.js.map +1 -1
  54. package/dist/scaffolder/tasks/logger.cjs.js.map +1 -1
  55. package/dist/scaffolder/tasks/taskRecoveryHelper.cjs.js.map +1 -1
  56. package/dist/service/conditionExports.cjs.js.map +1 -1
  57. package/dist/service/helpers.cjs.js.map +1 -1
  58. package/dist/service/router.cjs.js +26 -8
  59. package/dist/service/router.cjs.js.map +1 -1
  60. package/dist/service/rules.cjs.js +11 -11
  61. package/dist/service/rules.cjs.js.map +1 -1
  62. package/dist/util/checkPermissions.cjs.js.map +1 -1
  63. package/dist/util/metrics.cjs.js.map +1 -1
  64. package/package.json +35 -26
  65. package/alpha/package.json +0 -6
@@ -1 +1 @@
1
- {"version":3,"file":"rename.examples.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/filesystem/rename.examples.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { TemplateExample } from '@backstage/plugin-scaffolder-node';\nimport * as yaml from 'yaml';\n\nexport const examples: TemplateExample[] = [\n {\n description: 'Rename specified files ',\n example: yaml.stringify({\n steps: [\n {\n action: 'fs:rename',\n id: 'renameFiles',\n name: 'Rename files',\n input: {\n files: [\n { from: 'file1.txt', to: 'file1Renamed.txt' },\n { from: 'file2.txt', to: 'file2Renamed.txt' },\n { from: 'file3.txt', to: 'file3Renamed.txt', overwrite: true },\n ],\n },\n },\n ],\n }),\n },\n];\n"],"names":["yaml"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAmBO,MAAM,QAA8B,GAAA;AAAA,EACzC;AAAA,IACE,WAAa,EAAA,yBAAA;AAAA,IACb,OAAA,EAASA,gBAAK,SAAU,CAAA;AAAA,MACtB,KAAO,EAAA;AAAA,QACL;AAAA,UACE,MAAQ,EAAA,WAAA;AAAA,UACR,EAAI,EAAA,aAAA;AAAA,UACJ,IAAM,EAAA,cAAA;AAAA,UACN,KAAO,EAAA;AAAA,YACL,KAAO,EAAA;AAAA,cACL,EAAE,IAAA,EAAM,WAAa,EAAA,EAAA,EAAI,kBAAmB,EAAA;AAAA,cAC5C,EAAE,IAAA,EAAM,WAAa,EAAA,EAAA,EAAI,kBAAmB,EAAA;AAAA,cAC5C,EAAE,IAAM,EAAA,WAAA,EAAa,EAAI,EAAA,kBAAA,EAAoB,WAAW,IAAK,EAAA;AAAA,aAC/D;AAAA,WACF;AAAA,SACF;AAAA,OACF;AAAA,KACD,CAAA;AAAA,GACH;AACF;;;;"}
1
+ {"version":3,"file":"rename.examples.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/filesystem/rename.examples.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { TemplateExample } from '@backstage/plugin-scaffolder-node';\nimport * as yaml from 'yaml';\n\nexport const examples: TemplateExample[] = [\n {\n description: 'Rename specified files ',\n example: yaml.stringify({\n steps: [\n {\n action: 'fs:rename',\n id: 'renameFiles',\n name: 'Rename files',\n input: {\n files: [\n { from: 'file1.txt', to: 'file1Renamed.txt' },\n { from: 'file2.txt', to: 'file2Renamed.txt' },\n { from: 'file3.txt', to: 'file3Renamed.txt', overwrite: true },\n ],\n },\n },\n ],\n }),\n },\n];\n"],"names":["yaml"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAmBO,MAAM,QAA8B,GAAA;AAAA,EACzC;AAAA,IACE,WAAa,EAAA,yBAAA;AAAA,IACb,OAAA,EAASA,gBAAK,SAAU,CAAA;AAAA,MACtB,KAAO,EAAA;AAAA,QACL;AAAA,UACE,MAAQ,EAAA,WAAA;AAAA,UACR,EAAI,EAAA,aAAA;AAAA,UACJ,IAAM,EAAA,cAAA;AAAA,UACN,KAAO,EAAA;AAAA,YACL,KAAO,EAAA;AAAA,cACL,EAAE,IAAA,EAAM,WAAa,EAAA,EAAA,EAAI,kBAAmB,EAAA;AAAA,cAC5C,EAAE,IAAA,EAAM,WAAa,EAAA,EAAA,EAAI,kBAAmB,EAAA;AAAA,cAC5C,EAAE,IAAM,EAAA,WAAA,EAAa,EAAI,EAAA,kBAAA,EAAoB,WAAW,IAAK;AAAA;AAC/D;AACF;AACF;AACF,KACD;AAAA;AAEL;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"deprecated.cjs.js","sources":["../../../src/scaffolder/actions/deprecated.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport * as github from '@backstage/plugin-scaffolder-backend-module-github';\nimport * as gitlab from '@backstage/plugin-scaffolder-backend-module-gitlab';\nimport * as azure from '@backstage/plugin-scaffolder-backend-module-azure';\nimport * as bitbucket from '@backstage/plugin-scaffolder-backend-module-bitbucket';\nimport * as bitbucketCloud from '@backstage/plugin-scaffolder-backend-module-bitbucket-cloud';\nimport * as bitbucketServer from '@backstage/plugin-scaffolder-backend-module-bitbucket-server';\nimport * as gerrit from '@backstage/plugin-scaffolder-backend-module-gerrit';\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport const createGithubActionsDispatchAction =\n github.createGithubActionsDispatchAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport const createGithubDeployKeyAction = github.createGithubDeployKeyAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport const createGithubEnvironmentAction =\n github.createGithubEnvironmentAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport const createGithubIssuesLabelAction =\n github.createGithubIssuesLabelAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport type CreateGithubPullRequestActionOptions =\n github.CreateGithubPullRequestActionOptions;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport const createGithubRepoCreateAction = github.createGithubRepoCreateAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport const createGithubRepoPushAction = github.createGithubRepoPushAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport const createGithubWebhookAction = github.createGithubWebhookAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport const createPublishGithubAction = github.createPublishGithubAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport const createPublishGithubPullRequestAction =\n github.createPublishGithubPullRequestAction;\n\n/**\n * @public @deprecated use \"createPublishBitbucketCloudAction\" from \\@backstage/plugin-scaffolder-backend-module-bitbucket-cloud or \"createPublishBitbucketServerAction\" from \\@backstage/plugin-scaffolder-backend-module-bitbucket-server instead\n */\nexport const createPublishBitbucketAction =\n bitbucket.createPublishBitbucketAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud` instead\n */\nexport const createPublishBitbucketCloudAction =\n bitbucketCloud.createPublishBitbucketCloudAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-bitbucket-server` instead\n */\nexport const createPublishBitbucketServerAction =\n bitbucketServer.createPublishBitbucketServerAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-bitbucket-server` instead\n */\nexport const createPublishBitbucketServerPullRequestAction =\n bitbucketServer.createPublishBitbucketServerPullRequestAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-azure` instead\n */\nexport const createPublishAzureAction = azure.createPublishAzureAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-gerrit` instead\n */\nexport const createPublishGerritAction = gerrit.createPublishGerritAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-gerrit` instead\n */\nexport const createPublishGerritReviewAction =\n gerrit.createPublishGerritReviewAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-gitlab` instead\n */\nexport const createPublishGitlabAction = gitlab.createPublishGitlabAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-gitlab` instead\n */\nexport const createPublishGitlabMergeRequestAction =\n gitlab.createPublishGitlabMergeRequestAction;\n"],"names":["github","bitbucket","bitbucketCloud","bitbucketServer","azure","gerrit","gitlab"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BO,MAAM,oCACXA,iBAAO,CAAA,kCAAA;AAMF,MAAM,8BAA8BA,iBAAO,CAAA,4BAAA;AAM3C,MAAM,gCACXA,iBAAO,CAAA,8BAAA;AAMF,MAAM,gCACXA,iBAAO,CAAA,8BAAA;AAaF,MAAM,+BAA+BA,iBAAO,CAAA,6BAAA;AAM5C,MAAM,6BAA6BA,iBAAO,CAAA,2BAAA;AAM1C,MAAM,4BAA4BA,iBAAO,CAAA,0BAAA;AAMzC,MAAM,4BAA4BA,iBAAO,CAAA,0BAAA;AAMzC,MAAM,uCACXA,iBAAO,CAAA,qCAAA;AAKF,MAAM,+BACXC,oBAAU,CAAA,6BAAA;AAML,MAAM,oCACXC,yBAAe,CAAA,kCAAA;AAMV,MAAM,qCACXC,0BAAgB,CAAA,mCAAA;AAMX,MAAM,gDACXA,0BAAgB,CAAA,8CAAA;AAMX,MAAM,2BAA2BC,gBAAM,CAAA,yBAAA;AAMvC,MAAM,4BAA4BC,iBAAO,CAAA,0BAAA;AAMzC,MAAM,kCACXA,iBAAO,CAAA,gCAAA;AAMF,MAAM,4BAA4BC,iBAAO,CAAA,0BAAA;AAMzC,MAAM,wCACXA,iBAAO,CAAA;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"deprecated.cjs.js","sources":["../../../src/scaffolder/actions/deprecated.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport * as github from '@backstage/plugin-scaffolder-backend-module-github';\nimport * as gitlab from '@backstage/plugin-scaffolder-backend-module-gitlab';\nimport * as azure from '@backstage/plugin-scaffolder-backend-module-azure';\nimport * as bitbucket from '@backstage/plugin-scaffolder-backend-module-bitbucket';\nimport * as bitbucketCloud from '@backstage/plugin-scaffolder-backend-module-bitbucket-cloud';\nimport * as bitbucketServer from '@backstage/plugin-scaffolder-backend-module-bitbucket-server';\nimport * as gerrit from '@backstage/plugin-scaffolder-backend-module-gerrit';\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport const createGithubActionsDispatchAction =\n github.createGithubActionsDispatchAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport const createGithubDeployKeyAction = github.createGithubDeployKeyAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport const createGithubEnvironmentAction =\n github.createGithubEnvironmentAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport const createGithubIssuesLabelAction =\n github.createGithubIssuesLabelAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport type CreateGithubPullRequestActionOptions =\n github.CreateGithubPullRequestActionOptions;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport const createGithubRepoCreateAction = github.createGithubRepoCreateAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport const createGithubRepoPushAction = github.createGithubRepoPushAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport const createGithubWebhookAction = github.createGithubWebhookAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport const createPublishGithubAction = github.createPublishGithubAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead\n */\nexport const createPublishGithubPullRequestAction =\n github.createPublishGithubPullRequestAction;\n\n/**\n * @public @deprecated use \"createPublishBitbucketCloudAction\" from \\@backstage/plugin-scaffolder-backend-module-bitbucket-cloud or \"createPublishBitbucketServerAction\" from \\@backstage/plugin-scaffolder-backend-module-bitbucket-server instead\n */\nexport const createPublishBitbucketAction =\n bitbucket.createPublishBitbucketAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud` instead\n */\nexport const createPublishBitbucketCloudAction =\n bitbucketCloud.createPublishBitbucketCloudAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-bitbucket-server` instead\n */\nexport const createPublishBitbucketServerAction =\n bitbucketServer.createPublishBitbucketServerAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-bitbucket-server` instead\n */\nexport const createPublishBitbucketServerPullRequestAction =\n bitbucketServer.createPublishBitbucketServerPullRequestAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-azure` instead\n */\nexport const createPublishAzureAction = azure.createPublishAzureAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-gerrit` instead\n */\nexport const createPublishGerritAction = gerrit.createPublishGerritAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-gerrit` instead\n */\nexport const createPublishGerritReviewAction =\n gerrit.createPublishGerritReviewAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-gitlab` instead\n */\nexport const createPublishGitlabAction = gitlab.createPublishGitlabAction;\n\n/**\n * @public\n * @deprecated use import from `@backstage/plugin-scaffolder-backend-module-gitlab` instead\n */\nexport const createPublishGitlabMergeRequestAction =\n gitlab.createPublishGitlabMergeRequestAction;\n"],"names":["github","bitbucket","bitbucketCloud","bitbucketServer","azure","gerrit","gitlab"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BO,MAAM,oCACXA,iBAAO,CAAA;AAMF,MAAM,8BAA8BA,iBAAO,CAAA;AAM3C,MAAM,gCACXA,iBAAO,CAAA;AAMF,MAAM,gCACXA,iBAAO,CAAA;AAaF,MAAM,+BAA+BA,iBAAO,CAAA;AAM5C,MAAM,6BAA6BA,iBAAO,CAAA;AAM1C,MAAM,4BAA4BA,iBAAO,CAAA;AAMzC,MAAM,4BAA4BA,iBAAO,CAAA;AAMzC,MAAM,uCACXA,iBAAO,CAAA;AAKF,MAAM,+BACXC,oBAAU,CAAA;AAML,MAAM,oCACXC,yBAAe,CAAA;AAMV,MAAM,qCACXC,0BAAgB,CAAA;AAMX,MAAM,gDACXA,0BAAgB,CAAA;AAMX,MAAM,2BAA2BC,gBAAM,CAAA;AAMvC,MAAM,4BAA4BC,iBAAO,CAAA;AAMzC,MAAM,kCACXA,iBAAO,CAAA;AAMF,MAAM,4BAA4BC,iBAAO,CAAA;AAMzC,MAAM,wCACXA,iBAAO,CAAA;;;;;;;;;;;;;;;;;;;;;"}
@@ -26,6 +26,7 @@ require('../actions/builtin/fetch/template.examples.cjs.js');
26
26
  require('../actions/builtin/fetch/templateFile.examples.cjs.js');
27
27
  require('../actions/builtin/filesystem/delete.examples.cjs.js');
28
28
  require('../actions/builtin/filesystem/rename.examples.cjs.js');
29
+ require('../actions/builtin/filesystem/read.cjs.js');
29
30
  require('@backstage/plugin-scaffolder-backend-module-github');
30
31
  require('@backstage/plugin-scaffolder-backend-module-azure');
31
32
  require('@backstage/plugin-scaffolder-backend-module-bitbucket');
@@ -1 +1 @@
1
- {"version":3,"file":"DecoratedActionsRegistry.cjs.js","sources":["../../../src/scaffolder/dryrun/DecoratedActionsRegistry.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { TemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { TemplateActionRegistry } from '../actions';\n\n/** @internal */\nexport class DecoratedActionsRegistry extends TemplateActionRegistry {\n constructor(\n private readonly innerRegistry: TemplateActionRegistry,\n extraActions: Array<TemplateAction>,\n ) {\n super();\n for (const action of extraActions) {\n this.register(action);\n }\n }\n\n get(actionId: string): TemplateAction {\n try {\n return super.get(actionId);\n } catch {\n return this.innerRegistry.get(actionId);\n }\n }\n}\n"],"names":["TemplateActionRegistry"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoBO,MAAM,iCAAiCA,6CAAuB,CAAA;AAAA,EACnE,WAAA,CACmB,eACjB,YACA,EAAA;AACA,IAAM,KAAA,EAAA,CAAA;AAHW,IAAA,IAAA,CAAA,aAAA,GAAA,aAAA,CAAA;AAIjB,IAAA,KAAA,MAAW,UAAU,YAAc,EAAA;AACjC,MAAA,IAAA,CAAK,SAAS,MAAM,CAAA,CAAA;AAAA,KACtB;AAAA,GACF;AAAA,EAEA,IAAI,QAAkC,EAAA;AACpC,IAAI,IAAA;AACF,MAAO,OAAA,KAAA,CAAM,IAAI,QAAQ,CAAA,CAAA;AAAA,KACnB,CAAA,MAAA;AACN,MAAO,OAAA,IAAA,CAAK,aAAc,CAAA,GAAA,CAAI,QAAQ,CAAA,CAAA;AAAA,KACxC;AAAA,GACF;AACF;;;;"}
1
+ {"version":3,"file":"DecoratedActionsRegistry.cjs.js","sources":["../../../src/scaffolder/dryrun/DecoratedActionsRegistry.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { TemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { TemplateActionRegistry } from '../actions';\n\n/** @internal */\nexport class DecoratedActionsRegistry extends TemplateActionRegistry {\n constructor(\n private readonly innerRegistry: TemplateActionRegistry,\n extraActions: Array<TemplateAction>,\n ) {\n super();\n for (const action of extraActions) {\n this.register(action);\n }\n }\n\n get(actionId: string): TemplateAction {\n try {\n return super.get(actionId);\n } catch {\n return this.innerRegistry.get(actionId);\n }\n }\n}\n"],"names":["TemplateActionRegistry"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoBO,MAAM,iCAAiCA,6CAAuB,CAAA;AAAA,EACnE,WAAA,CACmB,eACjB,YACA,EAAA;AACA,IAAM,KAAA,EAAA;AAHW,IAAA,IAAA,CAAA,aAAA,GAAA,aAAA;AAIjB,IAAA,KAAA,MAAW,UAAU,YAAc,EAAA;AACjC,MAAA,IAAA,CAAK,SAAS,MAAM,CAAA;AAAA;AACtB;AACF,EAEA,IAAI,QAAkC,EAAA;AACpC,IAAI,IAAA;AACF,MAAO,OAAA,KAAA,CAAM,IAAI,QAAQ,CAAA;AAAA,KACnB,CAAA,MAAA;AACN,MAAO,OAAA,IAAA,CAAK,aAAc,CAAA,GAAA,CAAI,QAAQ,CAAA;AAAA;AACxC;AAEJ;;;;"}
@@ -1,15 +1,16 @@
1
1
  'use strict';
2
2
 
3
- var uuid = require('uuid');
4
3
  var url = require('url');
5
4
  var pluginScaffolderNode = require('@backstage/plugin-scaffolder-node');
5
+ var path = require('path');
6
6
  var NunjucksWorkflowRunner = require('../tasks/NunjucksWorkflowRunner.cjs.js');
7
7
  var DecoratedActionsRegistry = require('./DecoratedActionsRegistry.cjs.js');
8
8
  var fs = require('fs-extra');
9
- var backendPluginApi = require('@backstage/backend-plugin-api');
9
+ var uuid = require('uuid');
10
10
 
11
11
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
12
12
 
13
+ var path__default = /*#__PURE__*/_interopDefaultCompat(path);
13
14
  var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
14
15
 
15
16
  function createDryRunner(options) {
@@ -29,12 +30,14 @@ function createDryRunner(options) {
29
30
  })
30
31
  ])
31
32
  });
33
+ const baseUrl = input.templateInfo.baseUrl;
34
+ if (!baseUrl) {
35
+ throw new Error("baseUrl is required");
36
+ }
37
+ const basePath = url.fileURLToPath(new URL(baseUrl));
38
+ const contentsPath = path__default.default.dirname(basePath);
32
39
  const dryRunId = uuid.v4();
33
40
  const log = new Array();
34
- const contentsPath = backendPluginApi.resolveSafeChildPath(
35
- options.workingDirectory,
36
- `dry-run-content-${dryRunId}`
37
- );
38
41
  try {
39
42
  await pluginScaffolderNode.deserializeDirectoryContents(contentsPath, input.directoryContents);
40
43
  const abortSignal = new AbortController().signal;
@@ -49,12 +52,7 @@ function createDryRunner(options) {
49
52
  action: "dry-run:extract"
50
53
  }
51
54
  ],
52
- templateInfo: {
53
- entityRef: "template:default/dry-run",
54
- baseUrl: url.pathToFileURL(
55
- backendPluginApi.resolveSafeChildPath(contentsPath, "template.yaml")
56
- ).toString()
57
- }
55
+ templateInfo: input.templateInfo
58
56
  },
59
57
  secrets: input.secrets,
60
58
  getInitiatorCredentials: () => Promise.resolve(input.credentials),
@@ -1 +1 @@
1
- {"version":3,"file":"createDryRunner.cjs.js","sources":["../../../src/scaffolder/dryrun/createDryRunner.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ScmIntegrations } from '@backstage/integration';\nimport { TaskSpec } from '@backstage/plugin-scaffolder-common';\nimport { JsonObject } from '@backstage/types';\nimport { v4 as uuid } from 'uuid';\nimport { pathToFileURL } from 'url';\nimport { Logger } from 'winston';\nimport {\n createTemplateAction,\n TaskSecrets,\n TemplateFilter,\n TemplateGlobal,\n deserializeDirectoryContents,\n SerializedFile,\n serializeDirectoryContents,\n} from '@backstage/plugin-scaffolder-node';\nimport { TemplateActionRegistry } from '../actions';\nimport { NunjucksWorkflowRunner } from '../tasks/NunjucksWorkflowRunner';\nimport { DecoratedActionsRegistry } from './DecoratedActionsRegistry';\nimport fs from 'fs-extra';\nimport { PermissionEvaluator } from '@backstage/plugin-permission-common';\nimport {\n BackstageCredentials,\n resolveSafeChildPath,\n} from '@backstage/backend-plugin-api';\nimport type { UserEntity } from '@backstage/catalog-model';\n\ninterface DryRunInput {\n spec: TaskSpec;\n secrets?: TaskSecrets;\n directoryContents: SerializedFile[];\n credentials: BackstageCredentials;\n user?: {\n entity?: UserEntity;\n ref?: string;\n };\n}\n\ninterface DryRunResult {\n log: Array<{ body: JsonObject }>;\n directoryContents: SerializedFile[];\n output: JsonObject;\n}\n\n/** @internal */\nexport type TemplateTesterCreateOptions = {\n logger: Logger;\n integrations: ScmIntegrations;\n actionRegistry: TemplateActionRegistry;\n workingDirectory: string;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n permissions?: PermissionEvaluator;\n};\n\n/**\n * Executes a dry-run of the provided template.\n *\n * The provided content will be extracted into a temporary directory\n * which is then use as the base for any relative file fetch paths.\n *\n * @internal\n */\nexport function createDryRunner(options: TemplateTesterCreateOptions) {\n return async function dryRun(input: DryRunInput): Promise<DryRunResult> {\n let contentPromise;\n\n const workflowRunner = new NunjucksWorkflowRunner({\n ...options,\n actionRegistry: new DecoratedActionsRegistry(options.actionRegistry, [\n createTemplateAction({\n id: 'dry-run:extract',\n supportsDryRun: true,\n async handler(ctx) {\n contentPromise = serializeDirectoryContents(ctx.workspacePath);\n await contentPromise.catch(() => {});\n },\n }),\n ]),\n });\n\n const dryRunId = uuid();\n const log = new Array<{ body: JsonObject }>();\n const contentsPath = resolveSafeChildPath(\n options.workingDirectory,\n `dry-run-content-${dryRunId}`,\n );\n\n try {\n await deserializeDirectoryContents(contentsPath, input.directoryContents);\n\n const abortSignal = new AbortController().signal;\n\n const result = await workflowRunner.execute({\n spec: {\n ...input.spec,\n steps: [\n ...input.spec.steps,\n {\n id: dryRunId,\n name: 'dry-run:extract',\n action: 'dry-run:extract',\n },\n ],\n templateInfo: {\n entityRef: 'template:default/dry-run',\n baseUrl: pathToFileURL(\n resolveSafeChildPath(contentsPath, 'template.yaml'),\n ).toString(),\n },\n },\n secrets: input.secrets,\n getInitiatorCredentials: () => Promise.resolve(input.credentials),\n // No need to update this at the end of the run, so just hard-code it\n done: false,\n isDryRun: true,\n getWorkspaceName: async () => `dry-run-${dryRunId}`,\n cancelSignal: abortSignal,\n async emitLog(message: string, logMetadata?: JsonObject) {\n if (logMetadata?.stepId === dryRunId) {\n return;\n }\n log.push({\n body: {\n ...logMetadata,\n message,\n },\n });\n },\n complete: async () => {\n throw new Error('Not implemented');\n },\n });\n\n if (!contentPromise) {\n throw new Error('Content extraction step was skipped');\n }\n const directoryContents = await contentPromise;\n\n return {\n log,\n directoryContents,\n output: result.output,\n };\n } finally {\n await fs.remove(contentsPath);\n }\n };\n}\n"],"names":["NunjucksWorkflowRunner","DecoratedActionsRegistry","createTemplateAction","serializeDirectoryContents","uuid","resolveSafeChildPath","deserializeDirectoryContents","pathToFileURL","fs"],"mappings":"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"}
1
+ {"version":3,"file":"createDryRunner.cjs.js","sources":["../../../src/scaffolder/dryrun/createDryRunner.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ScmIntegrations } from '@backstage/integration';\nimport { TaskSpec, TemplateInfo } from '@backstage/plugin-scaffolder-common';\nimport { JsonObject } from '@backstage/types';\nimport { fileURLToPath } from 'url';\nimport { Logger } from 'winston';\nimport {\n createTemplateAction,\n TaskSecrets,\n TemplateFilter,\n TemplateGlobal,\n deserializeDirectoryContents,\n SerializedFile,\n serializeDirectoryContents,\n} from '@backstage/plugin-scaffolder-node';\nimport path from 'path';\nimport { TemplateActionRegistry } from '../actions';\nimport { NunjucksWorkflowRunner } from '../tasks/NunjucksWorkflowRunner';\nimport { DecoratedActionsRegistry } from './DecoratedActionsRegistry';\nimport fs from 'fs-extra';\nimport { PermissionEvaluator } from '@backstage/plugin-permission-common';\nimport { BackstageCredentials } from '@backstage/backend-plugin-api';\nimport type { UserEntity } from '@backstage/catalog-model';\nimport { v4 as uuid } from 'uuid';\n\ninterface DryRunInput {\n spec: TaskSpec;\n templateInfo: TemplateInfo;\n secrets?: TaskSecrets;\n directoryContents: SerializedFile[];\n credentials: BackstageCredentials;\n user?: {\n entity?: UserEntity;\n ref?: string;\n };\n}\n\ninterface DryRunResult {\n log: Array<{ body: JsonObject }>;\n directoryContents: SerializedFile[];\n output: JsonObject;\n}\n\n/** @internal */\nexport type TemplateTesterCreateOptions = {\n logger: Logger;\n integrations: ScmIntegrations;\n actionRegistry: TemplateActionRegistry;\n workingDirectory: string;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n permissions?: PermissionEvaluator;\n};\n\n/**\n * Executes a dry-run of the provided template.\n *\n * The provided content will be extracted into a temporary directory\n * which is then use as the base for any relative file fetch paths.\n *\n * @internal\n */\nexport function createDryRunner(options: TemplateTesterCreateOptions) {\n return async function dryRun(input: DryRunInput): Promise<DryRunResult> {\n let contentPromise;\n\n const workflowRunner = new NunjucksWorkflowRunner({\n ...options,\n actionRegistry: new DecoratedActionsRegistry(options.actionRegistry, [\n createTemplateAction({\n id: 'dry-run:extract',\n supportsDryRun: true,\n async handler(ctx) {\n contentPromise = serializeDirectoryContents(ctx.workspacePath);\n await contentPromise.catch(() => {});\n },\n }),\n ]),\n });\n\n // Extracting contentsPath and dryRunId from the baseUrl\n const baseUrl = input.templateInfo.baseUrl;\n if (!baseUrl) {\n throw new Error('baseUrl is required');\n }\n const basePath = fileURLToPath(new URL(baseUrl));\n const contentsPath = path.dirname(basePath);\n const dryRunId = uuid();\n\n const log = new Array<{ body: JsonObject }>();\n\n try {\n await deserializeDirectoryContents(contentsPath, input.directoryContents);\n\n const abortSignal = new AbortController().signal;\n const result = await workflowRunner.execute({\n spec: {\n ...input.spec,\n steps: [\n ...input.spec.steps,\n {\n id: dryRunId,\n name: 'dry-run:extract',\n action: 'dry-run:extract',\n },\n ],\n templateInfo: input.templateInfo,\n },\n secrets: input.secrets,\n getInitiatorCredentials: () => Promise.resolve(input.credentials),\n // No need to update this at the end of the run, so just hard-code it\n done: false,\n isDryRun: true,\n getWorkspaceName: async () => `dry-run-${dryRunId}`,\n cancelSignal: abortSignal,\n async emitLog(message: string, logMetadata?: JsonObject) {\n if (logMetadata?.stepId === dryRunId) {\n return;\n }\n log.push({\n body: {\n ...logMetadata,\n message,\n },\n });\n },\n complete: async () => {\n throw new Error('Not implemented');\n },\n });\n\n if (!contentPromise) {\n throw new Error('Content extraction step was skipped');\n }\n const directoryContents = await contentPromise;\n\n return {\n log,\n directoryContents,\n output: result.output,\n };\n } finally {\n await fs.remove(contentsPath);\n }\n };\n}\n"],"names":["NunjucksWorkflowRunner","DecoratedActionsRegistry","createTemplateAction","serializeDirectoryContents","fileURLToPath","path","uuid","deserializeDirectoryContents","fs"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"DatabaseTaskStore.cjs.js","sources":["../../../src/scaffolder/tasks/DatabaseTaskStore.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { JsonObject } from '@backstage/types';\nimport { PluginDatabaseManager } from '@backstage/backend-common';\nimport { resolvePackagePath } from '@backstage/backend-plugin-api';\nimport { ConflictError, NotFoundError } from '@backstage/errors';\nimport { Knex } from 'knex';\nimport { v4 as uuid } from 'uuid';\nimport {\n TaskStore,\n TaskStoreCreateTaskOptions,\n TaskStoreCreateTaskResult,\n TaskStoreEmitOptions,\n TaskStoreListEventsOptions,\n TaskStoreRecoverTaskOptions,\n TaskStoreShutDownTaskOptions,\n} from './types';\nimport {\n SerializedTask,\n SerializedTaskEvent,\n TaskEventType,\n TaskSecrets,\n TaskStatus,\n} from '@backstage/plugin-scaffolder-node';\nimport { DateTime, Duration } from 'luxon';\nimport { TaskRecovery, TaskSpec } from '@backstage/plugin-scaffolder-common';\nimport { trimEventsTillLastRecovery } from './taskRecoveryHelper';\nimport { intervalFromNowTill } from './dbUtil';\nimport {\n restoreWorkspace,\n serializeWorkspace,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport { flattenParams } from '../../service/helpers';\n\nconst migrationsDir = resolvePackagePath(\n '@backstage/plugin-scaffolder-backend',\n 'migrations',\n);\n\nexport type RawDbTaskRow = {\n id: string;\n spec: string;\n status: TaskStatus;\n state?: string;\n last_heartbeat_at?: string;\n created_at: string;\n created_by: string | null;\n secrets?: string | null;\n workspace?: Buffer;\n};\n\nexport type RawDbTaskEventRow = {\n id: number;\n task_id: string;\n body: string;\n event_type: TaskEventType;\n created_at: string;\n};\n\n/**\n * DatabaseTaskStore\n *\n * @public\n */\nexport type DatabaseTaskStoreOptions = {\n database: PluginDatabaseManager | Knex;\n};\n\n/**\n * Type guard to help DatabaseTaskStore understand when database is PluginDatabaseManager vs. when database is a Knex instance.\n *\n * * @public\n */\nfunction isPluginDatabaseManager(\n opt: PluginDatabaseManager | Knex,\n): opt is PluginDatabaseManager {\n return (opt as PluginDatabaseManager).getClient !== undefined;\n}\n\nconst parseSqlDateToIsoString = <T>(input: T): T | string => {\n if (typeof input === 'string') {\n const parsed = DateTime.fromSQL(input, { zone: 'UTC' });\n if (!parsed.isValid) {\n throw new Error(\n `Failed to parse database timestamp '${input}', ${parsed.invalidReason}: ${parsed.invalidExplanation}`,\n );\n }\n return parsed.toISO()!;\n }\n\n return input;\n};\n\n/**\n * DatabaseTaskStore\n *\n * @public\n */\nexport class DatabaseTaskStore implements TaskStore {\n private readonly db: Knex;\n\n static async create(\n options: DatabaseTaskStoreOptions,\n ): Promise<DatabaseTaskStore> {\n const { database } = options;\n const client = await this.getClient(database);\n\n await this.runMigrations(database, client);\n\n return new DatabaseTaskStore(client);\n }\n\n private isRecoverableTask(spec: TaskSpec): boolean {\n return ['startOver'].includes(\n spec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy ?? 'none',\n );\n }\n\n private parseSpec({ spec, id }: { spec: string; id: string }): TaskSpec {\n try {\n return JSON.parse(spec);\n } catch (error) {\n throw new Error(`Failed to parse spec of task '${id}', ${error}`);\n }\n }\n\n private parseTaskSecrets(taskRow: RawDbTaskRow): TaskSecrets | undefined {\n try {\n return taskRow.secrets ? JSON.parse(taskRow.secrets) : undefined;\n } catch (error) {\n throw new Error(\n `Failed to parse secrets of task '${taskRow.id}', ${error}`,\n );\n }\n }\n\n private static async getClient(\n database: PluginDatabaseManager | Knex,\n ): Promise<Knex> {\n if (isPluginDatabaseManager(database)) {\n return database.getClient();\n }\n\n return database;\n }\n\n private static async runMigrations(\n database: PluginDatabaseManager | Knex,\n client: Knex,\n ): Promise<void> {\n if (!isPluginDatabaseManager(database)) {\n await client.migrate.latest({\n directory: migrationsDir,\n });\n\n return;\n }\n\n if (!database.migrations?.skip) {\n await client.migrate.latest({\n directory: migrationsDir,\n });\n }\n }\n\n private constructor(client: Knex) {\n this.db = client;\n }\n\n async list(options: {\n createdBy?: string;\n status?: TaskStatus;\n filters?: {\n createdBy?: string | string[];\n status?: TaskStatus | TaskStatus[];\n };\n pagination?: {\n limit?: number;\n offset?: number;\n };\n order?: { order: 'asc' | 'desc'; field: string }[];\n }): Promise<{ tasks: SerializedTask[]; totalTasks?: number }> {\n const { createdBy, status, pagination, order, filters } = options ?? {};\n const queryBuilder = this.db<RawDbTaskRow & { count: number }>('tasks');\n\n if (createdBy || filters?.createdBy) {\n const arr: string[] = flattenParams<string>(\n createdBy,\n filters?.createdBy,\n );\n queryBuilder.whereIn('created_by', [...new Set(arr)]);\n }\n\n if (status || filters?.status) {\n const arr: TaskStatus[] = flattenParams<TaskStatus>(\n status,\n filters?.status,\n );\n queryBuilder.whereIn('status', [...new Set(arr)]);\n }\n\n const countQuery = queryBuilder.clone();\n countQuery.count('tasks.id', { as: 'count' });\n\n if (order) {\n order.forEach(f => {\n queryBuilder.orderBy(f.field, f.order);\n });\n } else {\n queryBuilder.orderBy('created_at', 'desc');\n }\n\n if (pagination?.limit !== undefined) {\n queryBuilder.limit(pagination.limit);\n }\n\n if (pagination?.offset !== undefined) {\n queryBuilder.offset(pagination.offset);\n }\n\n const [results, [{ count }]] = await Promise.all([\n queryBuilder.select(),\n countQuery,\n ]);\n\n const tasks = results.map(result => ({\n id: result.id,\n spec: JSON.parse(result.spec),\n status: result.status,\n createdBy: result.created_by ?? undefined,\n lastHeartbeatAt: parseSqlDateToIsoString(result.last_heartbeat_at),\n createdAt: parseSqlDateToIsoString(result.created_at),\n }));\n\n return { tasks, totalTasks: count };\n }\n\n async getTask(taskId: string): Promise<SerializedTask> {\n const [result] = await this.db<RawDbTaskRow>('tasks')\n .where({ id: taskId })\n .select();\n if (!result) {\n throw new NotFoundError(`No task with id '${taskId}' found`);\n }\n try {\n const spec = JSON.parse(result.spec);\n const secrets = result.secrets ? JSON.parse(result.secrets) : undefined;\n const state = result.state ? JSON.parse(result.state).state : undefined;\n return {\n id: result.id,\n spec,\n status: result.status,\n lastHeartbeatAt: parseSqlDateToIsoString(result.last_heartbeat_at),\n createdAt: parseSqlDateToIsoString(result.created_at),\n createdBy: result.created_by ?? undefined,\n secrets,\n state,\n };\n } catch (error) {\n throw new Error(`Failed to parse spec of task '${taskId}', ${error}`);\n }\n }\n\n async createTask(\n options: TaskStoreCreateTaskOptions,\n ): Promise<TaskStoreCreateTaskResult> {\n const taskId = uuid();\n await this.db<RawDbTaskRow>('tasks').insert({\n id: taskId,\n spec: JSON.stringify(options.spec),\n secrets: options.secrets ? JSON.stringify(options.secrets) : undefined,\n created_by: options.createdBy ?? null,\n status: 'open',\n });\n return { taskId };\n }\n\n async claimTask(): Promise<SerializedTask | undefined> {\n return this.db.transaction(async tx => {\n const [task] = await tx<RawDbTaskRow>('tasks')\n .where({\n status: 'open',\n })\n .limit(1)\n .select();\n\n if (!task) {\n return undefined;\n }\n\n const spec = this.parseSpec(task);\n\n const updateCount = await tx<RawDbTaskRow>('tasks')\n .where({ id: task.id, status: 'open' })\n .update({\n status: 'processing',\n last_heartbeat_at: this.db.fn.now(),\n // remove the secrets for non-recoverable tasks when moving to processing state.\n secrets: this.isRecoverableTask(spec) ? task.secrets : null,\n });\n\n if (updateCount < 1) {\n return undefined;\n }\n\n const getState = () => {\n try {\n return task.state ? JSON.parse(task.state).state : undefined;\n } catch (error) {\n throw new Error(\n `Failed to parse state of the task '${task.id}', ${error}`,\n );\n }\n };\n\n const secrets = this.parseTaskSecrets(task);\n return {\n id: task.id,\n spec,\n status: 'processing',\n lastHeartbeatAt: task.last_heartbeat_at,\n createdAt: task.created_at,\n createdBy: task.created_by ?? undefined,\n secrets,\n state: getState(),\n };\n });\n }\n\n async heartbeatTask(taskId: string): Promise<void> {\n const updateCount = await this.db<RawDbTaskRow>('tasks')\n .where({ id: taskId, status: 'processing' })\n .update({\n last_heartbeat_at: this.db.fn.now(),\n });\n if (updateCount === 0) {\n throw new ConflictError(`No running task with taskId ${taskId} found`);\n }\n }\n\n async listStaleTasks(options: { timeoutS: number }): Promise<{\n tasks: { taskId: string; recovery?: TaskRecovery }[];\n }> {\n const { timeoutS } = options;\n const heartbeatInterval = intervalFromNowTill(timeoutS, this.db);\n const rawRows = await this.db<RawDbTaskRow>('tasks')\n .where('status', 'processing')\n .andWhere('last_heartbeat_at', '<=', heartbeatInterval);\n const tasks = rawRows.map(row => ({\n recovery: (JSON.parse(row.spec) as TaskSpec).EXPERIMENTAL_recovery,\n taskId: row.id,\n }));\n return { tasks };\n }\n\n async completeTask(options: {\n taskId: string;\n status: TaskStatus;\n eventBody: JsonObject;\n }): Promise<void> {\n const { taskId, status, eventBody } = options;\n\n let oldStatus: TaskStatus;\n if (['failed', 'completed', 'cancelled'].includes(status)) {\n oldStatus = 'processing';\n } else {\n throw new Error(\n `Invalid status update of run '${taskId}' to status '${status}'`,\n );\n }\n\n await this.db.transaction(async tx => {\n const [task] = await tx<RawDbTaskRow>('tasks')\n .where({\n id: taskId,\n })\n .limit(1)\n .select();\n\n const updateTask = async (criteria: {\n id: string;\n status?: TaskStatus;\n }) => {\n const updateCount = await tx<RawDbTaskRow>('tasks')\n .where(criteria)\n .update({\n status,\n secrets: null,\n });\n\n if (updateCount !== 1) {\n throw new ConflictError(\n `Failed to update status to '${status}' for taskId ${taskId}`,\n );\n }\n\n await tx<RawDbTaskEventRow>('task_events').insert({\n task_id: taskId,\n event_type: 'completion',\n body: JSON.stringify(eventBody),\n });\n };\n\n if (status === 'cancelled') {\n await updateTask({\n id: taskId,\n });\n return;\n }\n\n if (task.status === 'cancelled') {\n return;\n }\n\n if (!task) {\n throw new Error(`No task with taskId ${taskId} found`);\n }\n if (task.status !== oldStatus) {\n throw new ConflictError(\n `Refusing to update status of run '${taskId}' to status '${status}' ` +\n `as it is currently '${task.status}', expected '${oldStatus}'`,\n );\n }\n\n await updateTask({\n id: taskId,\n status: oldStatus,\n });\n });\n }\n\n async emitLogEvent(\n options: TaskStoreEmitOptions<{ message: string } & JsonObject>,\n ): Promise<void> {\n const { taskId, body } = options;\n const serializedBody = JSON.stringify(body);\n await this.db<RawDbTaskEventRow>('task_events').insert({\n task_id: taskId,\n event_type: 'log',\n body: serializedBody,\n });\n }\n\n async getTaskState({ taskId }: { taskId: string }): Promise<\n | {\n state: JsonObject;\n }\n | undefined\n > {\n const [result] = await this.db<RawDbTaskRow>('tasks')\n .where({ id: taskId })\n .select('state');\n return result.state ? JSON.parse(result.state) : undefined;\n }\n\n async saveTaskState(options: {\n taskId: string;\n state?: JsonObject;\n }): Promise<void> {\n if (options.state) {\n const serializedState = JSON.stringify({ state: options.state });\n await this.db<RawDbTaskRow>('tasks')\n .where({ id: options.taskId })\n .update({\n state: serializedState,\n });\n }\n }\n\n async listEvents(\n options: TaskStoreListEventsOptions,\n ): Promise<{ events: SerializedTaskEvent[] }> {\n const { isTaskRecoverable, taskId, after } = options;\n const rawEvents = await this.db<RawDbTaskEventRow>('task_events')\n .where({\n task_id: taskId,\n })\n .andWhere(builder => {\n if (typeof after === 'number') {\n builder.where('id', '>', after).orWhere('event_type', 'completion');\n }\n })\n .orderBy('id')\n .select();\n\n const events = rawEvents.map(event => {\n try {\n const body = JSON.parse(event.body) as JsonObject;\n return {\n id: Number(event.id),\n isTaskRecoverable,\n taskId,\n body,\n type: event.event_type,\n createdAt: parseSqlDateToIsoString(event.created_at),\n };\n } catch (error) {\n throw new Error(\n `Failed to parse event body from event taskId=${taskId} id=${event.id}, ${error}`,\n );\n }\n });\n\n return trimEventsTillLastRecovery(events);\n }\n\n async shutdownTask(options: TaskStoreShutDownTaskOptions): Promise<void> {\n const { taskId } = options;\n const message = `This task was marked as stale as it exceeded its timeout`;\n\n const statusStepEvents = (await this.listEvents({ taskId })).events.filter(\n ({ body }) => body?.stepId,\n );\n\n const completedSteps = statusStepEvents\n .filter(\n ({ body: { status } }) => status === 'failed' || status === 'completed',\n )\n .map(step => step.body.stepId);\n\n const hungProcessingSteps = statusStepEvents\n .filter(({ body: { status } }) => status === 'processing')\n .map(event => event.body.stepId)\n .filter(step => !completedSteps.includes(step));\n\n for (const step of hungProcessingSteps) {\n await this.emitLogEvent({\n taskId,\n body: {\n message,\n stepId: step,\n status: 'failed',\n },\n });\n }\n\n await this.completeTask({\n taskId,\n status: 'failed',\n eventBody: {\n message,\n },\n });\n }\n\n async rehydrateWorkspace(options: {\n taskId: string;\n targetPath: string;\n }): Promise<void> {\n const [result] = await this.db<RawDbTaskRow>('tasks')\n .where({ id: options.taskId })\n .select('workspace');\n\n await restoreWorkspace({\n path: options.targetPath,\n buffer: result.workspace,\n });\n }\n\n async cleanWorkspace({ taskId }: { taskId: string }): Promise<void> {\n await this.db('tasks').where({ id: taskId }).update({\n workspace: null,\n });\n }\n\n async serializeWorkspace(options: {\n path: string;\n taskId: string;\n }): Promise<void> {\n if (options.path) {\n const workspace = (await serializeWorkspace(options)).contents;\n await this.db<RawDbTaskRow>('tasks')\n .where({ id: options.taskId })\n .update({\n workspace,\n });\n }\n }\n\n async cancelTask(\n options: TaskStoreEmitOptions<{ message: string } & JsonObject>,\n ): Promise<void> {\n const { taskId, body } = options;\n const serializedBody = JSON.stringify(body);\n await this.db<RawDbTaskEventRow>('task_events').insert({\n task_id: taskId,\n event_type: 'cancelled',\n body: serializedBody,\n });\n }\n\n async retryTask?(options: { taskId: string }): Promise<void> {\n await this.db.transaction(async tx => {\n const result = await tx<RawDbTaskRow>('tasks')\n .where('id', options.taskId)\n .update(\n {\n status: 'open',\n last_heartbeat_at: this.db.fn.now(),\n },\n ['id', 'spec'],\n );\n\n for (const { id, spec } of result) {\n const taskSpec = JSON.parse(spec as string) as TaskSpec;\n\n /**\n * Once task is picked up, all event types are replayed.\n * We have to remove cancelled or completion event_type as these are as actions for frontend to perform.\n * In contrary, we send 'recovered' event_type to reset the state on the frontend side.\n *\n */\n await tx<RawDbTaskEventRow>('task_events')\n .where('task_id', id)\n .andWhere(q => q.whereIn('event_type', ['cancelled', 'completion']))\n .del();\n\n await tx<RawDbTaskEventRow>('task_events').insert({\n task_id: id,\n event_type: 'recovered',\n body: JSON.stringify({\n recoverStrategy:\n taskSpec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy ?? 'none',\n }),\n });\n }\n });\n }\n\n async recoverTasks(\n options: TaskStoreRecoverTaskOptions,\n ): Promise<{ ids: string[] }> {\n const taskIdsToRecover: string[] = [];\n const timeoutS = Duration.fromObject(options.timeout).as('seconds');\n\n await this.db.transaction(async tx => {\n const heartbeatInterval = intervalFromNowTill(timeoutS, this.db);\n\n const result = await tx<RawDbTaskRow>('tasks')\n .where('status', 'processing')\n .andWhere('last_heartbeat_at', '<=', heartbeatInterval)\n .update(\n {\n status: 'open',\n last_heartbeat_at: this.db.fn.now(),\n },\n ['id', 'spec'],\n );\n\n taskIdsToRecover.push(...result.map(i => i.id));\n\n for (const { id, spec } of result) {\n const taskSpec = JSON.parse(spec as string) as TaskSpec;\n await tx<RawDbTaskEventRow>('task_events').insert({\n task_id: id,\n event_type: 'recovered',\n body: JSON.stringify({\n recoverStrategy:\n taskSpec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy ?? 'none',\n }),\n });\n }\n });\n\n return { ids: taskIdsToRecover };\n }\n}\n"],"names":["resolvePackagePath","DateTime","flattenParams","NotFoundError","uuid","ConflictError","intervalFromNowTill","trimEventsTillLastRecovery","restoreWorkspace","serializeWorkspace","Duration"],"mappings":"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"}
1
+ {"version":3,"file":"DatabaseTaskStore.cjs.js","sources":["../../../src/scaffolder/tasks/DatabaseTaskStore.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { JsonObject } from '@backstage/types';\nimport { PluginDatabaseManager } from '@backstage/backend-common';\nimport { resolvePackagePath } from '@backstage/backend-plugin-api';\nimport { ConflictError, NotFoundError } from '@backstage/errors';\nimport { Knex } from 'knex';\nimport { v4 as uuid } from 'uuid';\nimport {\n TaskStore,\n TaskStoreCreateTaskOptions,\n TaskStoreCreateTaskResult,\n TaskStoreEmitOptions,\n TaskStoreListEventsOptions,\n TaskStoreRecoverTaskOptions,\n TaskStoreShutDownTaskOptions,\n} from './types';\nimport {\n SerializedTask,\n SerializedTaskEvent,\n TaskEventType,\n TaskSecrets,\n TaskStatus,\n} from '@backstage/plugin-scaffolder-node';\nimport { DateTime, Duration } from 'luxon';\nimport { TaskRecovery, TaskSpec } from '@backstage/plugin-scaffolder-common';\nimport { trimEventsTillLastRecovery } from './taskRecoveryHelper';\nimport { intervalFromNowTill } from './dbUtil';\nimport {\n restoreWorkspace,\n serializeWorkspace,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport { flattenParams } from '../../service/helpers';\n\nconst migrationsDir = resolvePackagePath(\n '@backstage/plugin-scaffolder-backend',\n 'migrations',\n);\n\nexport type RawDbTaskRow = {\n id: string;\n spec: string;\n status: TaskStatus;\n state?: string;\n last_heartbeat_at?: string;\n created_at: string;\n created_by: string | null;\n secrets?: string | null;\n workspace?: Buffer;\n};\n\nexport type RawDbTaskEventRow = {\n id: number;\n task_id: string;\n body: string;\n event_type: TaskEventType;\n created_at: string;\n};\n\n/**\n * DatabaseTaskStore\n *\n * @public\n */\nexport type DatabaseTaskStoreOptions = {\n database: PluginDatabaseManager | Knex;\n};\n\n/**\n * Type guard to help DatabaseTaskStore understand when database is PluginDatabaseManager vs. when database is a Knex instance.\n *\n * * @public\n */\nfunction isPluginDatabaseManager(\n opt: PluginDatabaseManager | Knex,\n): opt is PluginDatabaseManager {\n return (opt as PluginDatabaseManager).getClient !== undefined;\n}\n\nconst parseSqlDateToIsoString = <T>(input: T): T | string => {\n if (typeof input === 'string') {\n const parsed = DateTime.fromSQL(input, { zone: 'UTC' });\n if (!parsed.isValid) {\n throw new Error(\n `Failed to parse database timestamp '${input}', ${parsed.invalidReason}: ${parsed.invalidExplanation}`,\n );\n }\n return parsed.toISO()!;\n }\n\n return input;\n};\n\n/**\n * DatabaseTaskStore\n *\n * @public\n */\nexport class DatabaseTaskStore implements TaskStore {\n private readonly db: Knex;\n\n static async create(\n options: DatabaseTaskStoreOptions,\n ): Promise<DatabaseTaskStore> {\n const { database } = options;\n const client = await this.getClient(database);\n\n await this.runMigrations(database, client);\n\n return new DatabaseTaskStore(client);\n }\n\n private isRecoverableTask(spec: TaskSpec): boolean {\n return ['startOver'].includes(\n spec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy ?? 'none',\n );\n }\n\n private parseSpec({ spec, id }: { spec: string; id: string }): TaskSpec {\n try {\n return JSON.parse(spec);\n } catch (error) {\n throw new Error(`Failed to parse spec of task '${id}', ${error}`);\n }\n }\n\n private parseTaskSecrets(taskRow: RawDbTaskRow): TaskSecrets | undefined {\n try {\n return taskRow.secrets ? JSON.parse(taskRow.secrets) : undefined;\n } catch (error) {\n throw new Error(\n `Failed to parse secrets of task '${taskRow.id}', ${error}`,\n );\n }\n }\n\n private static async getClient(\n database: PluginDatabaseManager | Knex,\n ): Promise<Knex> {\n if (isPluginDatabaseManager(database)) {\n return database.getClient();\n }\n\n return database;\n }\n\n private static async runMigrations(\n database: PluginDatabaseManager | Knex,\n client: Knex,\n ): Promise<void> {\n if (!isPluginDatabaseManager(database)) {\n await client.migrate.latest({\n directory: migrationsDir,\n });\n\n return;\n }\n\n if (!database.migrations?.skip) {\n await client.migrate.latest({\n directory: migrationsDir,\n });\n }\n }\n\n private constructor(client: Knex) {\n this.db = client;\n }\n\n async list(options: {\n createdBy?: string;\n status?: TaskStatus;\n filters?: {\n createdBy?: string | string[];\n status?: TaskStatus | TaskStatus[];\n };\n pagination?: {\n limit?: number;\n offset?: number;\n };\n order?: { order: 'asc' | 'desc'; field: string }[];\n }): Promise<{ tasks: SerializedTask[]; totalTasks?: number }> {\n const { createdBy, status, pagination, order, filters } = options ?? {};\n const queryBuilder = this.db<RawDbTaskRow & { count: number }>('tasks');\n\n if (createdBy || filters?.createdBy) {\n const arr: string[] = flattenParams<string>(\n createdBy,\n filters?.createdBy,\n );\n queryBuilder.whereIn('created_by', [...new Set(arr)]);\n }\n\n if (status || filters?.status) {\n const arr: TaskStatus[] = flattenParams<TaskStatus>(\n status,\n filters?.status,\n );\n queryBuilder.whereIn('status', [...new Set(arr)]);\n }\n\n const countQuery = queryBuilder.clone();\n countQuery.count('tasks.id', { as: 'count' });\n\n if (order) {\n order.forEach(f => {\n queryBuilder.orderBy(f.field, f.order);\n });\n } else {\n queryBuilder.orderBy('created_at', 'desc');\n }\n\n if (pagination?.limit !== undefined) {\n queryBuilder.limit(pagination.limit);\n }\n\n if (pagination?.offset !== undefined) {\n queryBuilder.offset(pagination.offset);\n }\n\n const [results, [{ count }]] = await Promise.all([\n queryBuilder.select(),\n countQuery,\n ]);\n\n const tasks = results.map(result => ({\n id: result.id,\n spec: JSON.parse(result.spec),\n status: result.status,\n createdBy: result.created_by ?? undefined,\n lastHeartbeatAt: parseSqlDateToIsoString(result.last_heartbeat_at),\n createdAt: parseSqlDateToIsoString(result.created_at),\n }));\n\n return { tasks, totalTasks: count };\n }\n\n async getTask(taskId: string): Promise<SerializedTask> {\n const [result] = await this.db<RawDbTaskRow>('tasks')\n .where({ id: taskId })\n .select();\n if (!result) {\n throw new NotFoundError(`No task with id '${taskId}' found`);\n }\n try {\n const spec = JSON.parse(result.spec);\n const secrets = result.secrets ? JSON.parse(result.secrets) : undefined;\n const state = result.state ? JSON.parse(result.state).state : undefined;\n return {\n id: result.id,\n spec,\n status: result.status,\n lastHeartbeatAt: parseSqlDateToIsoString(result.last_heartbeat_at),\n createdAt: parseSqlDateToIsoString(result.created_at),\n createdBy: result.created_by ?? undefined,\n secrets,\n state,\n };\n } catch (error) {\n throw new Error(`Failed to parse spec of task '${taskId}', ${error}`);\n }\n }\n\n async createTask(\n options: TaskStoreCreateTaskOptions,\n ): Promise<TaskStoreCreateTaskResult> {\n const taskId = uuid();\n await this.db<RawDbTaskRow>('tasks').insert({\n id: taskId,\n spec: JSON.stringify(options.spec),\n secrets: options.secrets ? JSON.stringify(options.secrets) : undefined,\n created_by: options.createdBy ?? null,\n status: 'open',\n });\n return { taskId };\n }\n\n async claimTask(): Promise<SerializedTask | undefined> {\n return this.db.transaction(async tx => {\n const [task] = await tx<RawDbTaskRow>('tasks')\n .where({\n status: 'open',\n })\n .limit(1)\n .select();\n\n if (!task) {\n return undefined;\n }\n\n const spec = this.parseSpec(task);\n\n const updateCount = await tx<RawDbTaskRow>('tasks')\n .where({ id: task.id, status: 'open' })\n .update({\n status: 'processing',\n last_heartbeat_at: this.db.fn.now(),\n // remove the secrets for non-recoverable tasks when moving to processing state.\n secrets: this.isRecoverableTask(spec) ? task.secrets : null,\n });\n\n if (updateCount < 1) {\n return undefined;\n }\n\n const getState = () => {\n try {\n return task.state ? JSON.parse(task.state).state : undefined;\n } catch (error) {\n throw new Error(\n `Failed to parse state of the task '${task.id}', ${error}`,\n );\n }\n };\n\n const secrets = this.parseTaskSecrets(task);\n return {\n id: task.id,\n spec,\n status: 'processing',\n lastHeartbeatAt: task.last_heartbeat_at,\n createdAt: task.created_at,\n createdBy: task.created_by ?? undefined,\n secrets,\n state: getState(),\n };\n });\n }\n\n async heartbeatTask(taskId: string): Promise<void> {\n const updateCount = await this.db<RawDbTaskRow>('tasks')\n .where({ id: taskId, status: 'processing' })\n .update({\n last_heartbeat_at: this.db.fn.now(),\n });\n if (updateCount === 0) {\n throw new ConflictError(`No running task with taskId ${taskId} found`);\n }\n }\n\n async listStaleTasks(options: { timeoutS: number }): Promise<{\n tasks: { taskId: string; recovery?: TaskRecovery }[];\n }> {\n const { timeoutS } = options;\n const heartbeatInterval = intervalFromNowTill(timeoutS, this.db);\n const rawRows = await this.db<RawDbTaskRow>('tasks')\n .where('status', 'processing')\n .andWhere('last_heartbeat_at', '<=', heartbeatInterval);\n const tasks = rawRows.map(row => ({\n recovery: (JSON.parse(row.spec) as TaskSpec).EXPERIMENTAL_recovery,\n taskId: row.id,\n }));\n return { tasks };\n }\n\n async completeTask(options: {\n taskId: string;\n status: TaskStatus;\n eventBody: JsonObject;\n }): Promise<void> {\n const { taskId, status, eventBody } = options;\n\n let oldStatus: TaskStatus;\n if (['failed', 'completed', 'cancelled'].includes(status)) {\n oldStatus = 'processing';\n } else {\n throw new Error(\n `Invalid status update of run '${taskId}' to status '${status}'`,\n );\n }\n\n await this.db.transaction(async tx => {\n const [task] = await tx<RawDbTaskRow>('tasks')\n .where({\n id: taskId,\n })\n .limit(1)\n .select();\n\n const updateTask = async (criteria: {\n id: string;\n status?: TaskStatus;\n }) => {\n const updateCount = await tx<RawDbTaskRow>('tasks')\n .where(criteria)\n .update({\n status,\n secrets: null,\n });\n\n if (updateCount !== 1) {\n throw new ConflictError(\n `Failed to update status to '${status}' for taskId ${taskId}`,\n );\n }\n\n await tx<RawDbTaskEventRow>('task_events').insert({\n task_id: taskId,\n event_type: 'completion',\n body: JSON.stringify(eventBody),\n });\n };\n\n if (status === 'cancelled') {\n await updateTask({\n id: taskId,\n });\n return;\n }\n\n if (task.status === 'cancelled') {\n return;\n }\n\n if (!task) {\n throw new Error(`No task with taskId ${taskId} found`);\n }\n if (task.status !== oldStatus) {\n throw new ConflictError(\n `Refusing to update status of run '${taskId}' to status '${status}' ` +\n `as it is currently '${task.status}', expected '${oldStatus}'`,\n );\n }\n\n await updateTask({\n id: taskId,\n status: oldStatus,\n });\n });\n }\n\n async emitLogEvent(\n options: TaskStoreEmitOptions<{ message: string } & JsonObject>,\n ): Promise<void> {\n const { taskId, body } = options;\n const serializedBody = JSON.stringify(body);\n await this.db<RawDbTaskEventRow>('task_events').insert({\n task_id: taskId,\n event_type: 'log',\n body: serializedBody,\n });\n }\n\n async getTaskState({ taskId }: { taskId: string }): Promise<\n | {\n state: JsonObject;\n }\n | undefined\n > {\n const [result] = await this.db<RawDbTaskRow>('tasks')\n .where({ id: taskId })\n .select('state');\n return result.state ? JSON.parse(result.state) : undefined;\n }\n\n async saveTaskState(options: {\n taskId: string;\n state?: JsonObject;\n }): Promise<void> {\n if (options.state) {\n const serializedState = JSON.stringify({ state: options.state });\n await this.db<RawDbTaskRow>('tasks')\n .where({ id: options.taskId })\n .update({\n state: serializedState,\n });\n }\n }\n\n async listEvents(\n options: TaskStoreListEventsOptions,\n ): Promise<{ events: SerializedTaskEvent[] }> {\n const { isTaskRecoverable, taskId, after } = options;\n const rawEvents = await this.db<RawDbTaskEventRow>('task_events')\n .where({\n task_id: taskId,\n })\n .andWhere(builder => {\n if (typeof after === 'number') {\n builder.where('id', '>', after).orWhere('event_type', 'completion');\n }\n })\n .orderBy('id')\n .select();\n\n const events = rawEvents.map(event => {\n try {\n const body = JSON.parse(event.body) as JsonObject;\n return {\n id: Number(event.id),\n isTaskRecoverable,\n taskId,\n body,\n type: event.event_type,\n createdAt: parseSqlDateToIsoString(event.created_at),\n };\n } catch (error) {\n throw new Error(\n `Failed to parse event body from event taskId=${taskId} id=${event.id}, ${error}`,\n );\n }\n });\n\n return trimEventsTillLastRecovery(events);\n }\n\n async shutdownTask(options: TaskStoreShutDownTaskOptions): Promise<void> {\n const { taskId } = options;\n const message = `This task was marked as stale as it exceeded its timeout`;\n\n const statusStepEvents = (await this.listEvents({ taskId })).events.filter(\n ({ body }) => body?.stepId,\n );\n\n const completedSteps = statusStepEvents\n .filter(\n ({ body: { status } }) => status === 'failed' || status === 'completed',\n )\n .map(step => step.body.stepId);\n\n const hungProcessingSteps = statusStepEvents\n .filter(({ body: { status } }) => status === 'processing')\n .map(event => event.body.stepId)\n .filter(step => !completedSteps.includes(step));\n\n for (const step of hungProcessingSteps) {\n await this.emitLogEvent({\n taskId,\n body: {\n message,\n stepId: step,\n status: 'failed',\n },\n });\n }\n\n await this.completeTask({\n taskId,\n status: 'failed',\n eventBody: {\n message,\n },\n });\n }\n\n async rehydrateWorkspace(options: {\n taskId: string;\n targetPath: string;\n }): Promise<void> {\n const [result] = await this.db<RawDbTaskRow>('tasks')\n .where({ id: options.taskId })\n .select('workspace');\n\n await restoreWorkspace({\n path: options.targetPath,\n buffer: result.workspace,\n });\n }\n\n async cleanWorkspace({ taskId }: { taskId: string }): Promise<void> {\n await this.db('tasks').where({ id: taskId }).update({\n workspace: null,\n });\n }\n\n async serializeWorkspace(options: {\n path: string;\n taskId: string;\n }): Promise<void> {\n if (options.path) {\n const workspace = (await serializeWorkspace(options)).contents;\n await this.db<RawDbTaskRow>('tasks')\n .where({ id: options.taskId })\n .update({\n workspace,\n });\n }\n }\n\n async cancelTask(\n options: TaskStoreEmitOptions<{ message: string } & JsonObject>,\n ): Promise<void> {\n const { taskId, body } = options;\n const serializedBody = JSON.stringify(body);\n await this.db<RawDbTaskEventRow>('task_events').insert({\n task_id: taskId,\n event_type: 'cancelled',\n body: serializedBody,\n });\n }\n\n async retryTask?(options: { taskId: string }): Promise<void> {\n await this.db.transaction(async tx => {\n const result = await tx<RawDbTaskRow>('tasks')\n .where('id', options.taskId)\n .update(\n {\n status: 'open',\n last_heartbeat_at: this.db.fn.now(),\n },\n ['id', 'spec'],\n );\n\n for (const { id, spec } of result) {\n const taskSpec = JSON.parse(spec as string) as TaskSpec;\n\n /**\n * Once task is picked up, all event types are replayed.\n * We have to remove cancelled or completion event_type as these are as actions for frontend to perform.\n * In contrary, we send 'recovered' event_type to reset the state on the frontend side.\n *\n */\n await tx<RawDbTaskEventRow>('task_events')\n .where('task_id', id)\n .andWhere(q => q.whereIn('event_type', ['cancelled', 'completion']))\n .del();\n\n await tx<RawDbTaskEventRow>('task_events').insert({\n task_id: id,\n event_type: 'recovered',\n body: JSON.stringify({\n recoverStrategy:\n taskSpec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy ?? 'none',\n }),\n });\n }\n });\n }\n\n async recoverTasks(\n options: TaskStoreRecoverTaskOptions,\n ): Promise<{ ids: string[] }> {\n const taskIdsToRecover: string[] = [];\n const timeoutS = Duration.fromObject(options.timeout).as('seconds');\n\n await this.db.transaction(async tx => {\n const heartbeatInterval = intervalFromNowTill(timeoutS, this.db);\n\n const result = await tx<RawDbTaskRow>('tasks')\n .where('status', 'processing')\n .andWhere('last_heartbeat_at', '<=', heartbeatInterval)\n .update(\n {\n status: 'open',\n last_heartbeat_at: this.db.fn.now(),\n },\n ['id', 'spec'],\n );\n\n taskIdsToRecover.push(...result.map(i => i.id));\n\n for (const { id, spec } of result) {\n const taskSpec = JSON.parse(spec as string) as TaskSpec;\n await tx<RawDbTaskEventRow>('task_events').insert({\n task_id: id,\n event_type: 'recovered',\n body: JSON.stringify({\n recoverStrategy:\n taskSpec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy ?? 'none',\n }),\n });\n }\n });\n\n return { ids: taskIdsToRecover };\n }\n}\n"],"names":["resolvePackagePath","DateTime","flattenParams","NotFoundError","uuid","ConflictError","intervalFromNowTill","trimEventsTillLastRecovery","restoreWorkspace","serializeWorkspace","Duration"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"DatabaseWorkspaceProvider.cjs.js","sources":["../../../src/scaffolder/tasks/DatabaseWorkspaceProvider.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { TaskStore } from './types';\n\nimport { WorkspaceProvider } from '@backstage/plugin-scaffolder-node/alpha';\n\nexport class DatabaseWorkspaceProvider implements WorkspaceProvider {\n static create(storage: TaskStore) {\n return new DatabaseWorkspaceProvider(storage);\n }\n\n private constructor(private readonly storage: TaskStore) {}\n\n public async serializeWorkspace(options: {\n path: string;\n taskId: string;\n }): Promise<void> {\n await this.storage.serializeWorkspace?.(options);\n }\n\n public async rehydrateWorkspace(options: {\n taskId: string;\n targetPath: string;\n }): Promise<void> {\n return this.storage.rehydrateWorkspace?.(options);\n }\n\n public async cleanWorkspace(options: { taskId: string }): Promise<void> {\n return this.storage.cleanWorkspace?.(options);\n }\n}\n"],"names":[],"mappings":";;AAoBO,MAAM,yBAAuD,CAAA;AAAA,EAK1D,YAA6B,OAAoB,EAAA;AAApB,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA,CAAA;AAAA,GAAqB;AAAA,EAJ1D,OAAO,OAAO,OAAoB,EAAA;AAChC,IAAO,OAAA,IAAI,0BAA0B,OAAO,CAAA,CAAA;AAAA,GAC9C;AAAA,EAIA,MAAa,mBAAmB,OAGd,EAAA;AAChB,IAAM,MAAA,IAAA,CAAK,OAAQ,CAAA,kBAAA,GAAqB,OAAO,CAAA,CAAA;AAAA,GACjD;AAAA,EAEA,MAAa,mBAAmB,OAGd,EAAA;AAChB,IAAO,OAAA,IAAA,CAAK,OAAQ,CAAA,kBAAA,GAAqB,OAAO,CAAA,CAAA;AAAA,GAClD;AAAA,EAEA,MAAa,eAAe,OAA4C,EAAA;AACtE,IAAO,OAAA,IAAA,CAAK,OAAQ,CAAA,cAAA,GAAiB,OAAO,CAAA,CAAA;AAAA,GAC9C;AACF;;;;"}
1
+ {"version":3,"file":"DatabaseWorkspaceProvider.cjs.js","sources":["../../../src/scaffolder/tasks/DatabaseWorkspaceProvider.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { TaskStore } from './types';\n\nimport { WorkspaceProvider } from '@backstage/plugin-scaffolder-node/alpha';\n\nexport class DatabaseWorkspaceProvider implements WorkspaceProvider {\n static create(storage: TaskStore) {\n return new DatabaseWorkspaceProvider(storage);\n }\n\n private constructor(private readonly storage: TaskStore) {}\n\n public async serializeWorkspace(options: {\n path: string;\n taskId: string;\n }): Promise<void> {\n await this.storage.serializeWorkspace?.(options);\n }\n\n public async rehydrateWorkspace(options: {\n taskId: string;\n targetPath: string;\n }): Promise<void> {\n return this.storage.rehydrateWorkspace?.(options);\n }\n\n public async cleanWorkspace(options: { taskId: string }): Promise<void> {\n return this.storage.cleanWorkspace?.(options);\n }\n}\n"],"names":[],"mappings":";;AAoBO,MAAM,yBAAuD,CAAA;AAAA,EAK1D,YAA6B,OAAoB,EAAA;AAApB,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAAA;AAAqB,EAJ1D,OAAO,OAAO,OAAoB,EAAA;AAChC,IAAO,OAAA,IAAI,0BAA0B,OAAO,CAAA;AAAA;AAC9C,EAIA,MAAa,mBAAmB,OAGd,EAAA;AAChB,IAAM,MAAA,IAAA,CAAK,OAAQ,CAAA,kBAAA,GAAqB,OAAO,CAAA;AAAA;AACjD,EAEA,MAAa,mBAAmB,OAGd,EAAA;AAChB,IAAO,OAAA,IAAA,CAAK,OAAQ,CAAA,kBAAA,GAAqB,OAAO,CAAA;AAAA;AAClD,EAEA,MAAa,eAAe,OAA4C,EAAA;AACtE,IAAO,OAAA,IAAA,CAAK,OAAQ,CAAA,cAAA,GAAiB,OAAO,CAAA;AAAA;AAEhD;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"NunjucksWorkflowRunner.cjs.js","sources":["../../../src/scaffolder/tasks/NunjucksWorkflowRunner.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ScmIntegrations } from '@backstage/integration';\nimport { TaskTrackType, WorkflowResponse, WorkflowRunner } from './types';\nimport * as winston from 'winston';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport nunjucks from 'nunjucks';\nimport { JsonArray, JsonObject, JsonValue } from '@backstage/types';\nimport { InputError, NotAllowedError, stringifyError } from '@backstage/errors';\nimport { PassThrough } from 'stream';\nimport { generateExampleOutput, isTruthy } from './helper';\nimport { validate as validateJsonSchema } from 'jsonschema';\nimport { TemplateActionRegistry } from '../actions';\nimport { metrics } from '@opentelemetry/api';\nimport {\n SecureTemplater,\n SecureTemplateRenderer,\n} from '../../lib/templating/SecureTemplater';\nimport {\n TaskRecovery,\n TaskSpec,\n TaskSpecV1beta3,\n TaskStep,\n} from '@backstage/plugin-scaffolder-common';\n\nimport {\n TemplateAction,\n TemplateFilter,\n TemplateGlobal,\n TaskContext,\n} from '@backstage/plugin-scaffolder-node';\nimport { createConditionAuthorizer } from '@backstage/plugin-permission-node';\nimport { UserEntity } from '@backstage/catalog-model';\nimport { createCounterMetric, createHistogramMetric } from '../../util/metrics';\nimport { createDefaultFilters } from '../../lib/templating/filters';\nimport {\n AuthorizeResult,\n PolicyDecision,\n} from '@backstage/plugin-permission-common';\nimport { scaffolderActionRules } from '../../service/rules';\nimport { actionExecutePermission } from '@backstage/plugin-scaffolder-common/alpha';\nimport { PermissionsService } from '@backstage/backend-plugin-api';\nimport { loggerToWinstonLogger } from '@backstage/backend-common';\nimport { BackstageLoggerTransport, WinstonLogger } from './logger';\n\ntype NunjucksWorkflowRunnerOptions = {\n workingDirectory: string;\n actionRegistry: TemplateActionRegistry;\n integrations: ScmIntegrations;\n logger: winston.Logger;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n permissions?: PermissionsService;\n};\n\ntype TemplateContext = {\n parameters: JsonObject;\n EXPERIMENTAL_recovery?: TaskRecovery;\n steps: {\n [stepName: string]: { output: { [outputName: string]: JsonValue } };\n };\n secrets?: Record<string, string>;\n user?: {\n entity?: UserEntity;\n ref?: string;\n };\n each?: JsonValue;\n};\n\ntype CheckpointState =\n | {\n status: 'failed';\n reason: string;\n }\n | {\n status: 'success';\n value: JsonValue;\n };\n\nconst isValidTaskSpec = (taskSpec: TaskSpec): taskSpec is TaskSpecV1beta3 => {\n return taskSpec.apiVersion === 'scaffolder.backstage.io/v1beta3';\n};\n\nconst createStepLogger = ({\n task,\n step,\n rootLogger,\n}: {\n task: TaskContext;\n step: TaskStep;\n rootLogger: winston.Logger;\n}) => {\n const taskLogger = WinstonLogger.create({\n level: process.env.LOG_LEVEL || 'info',\n format: winston.format.combine(\n winston.format.colorize(),\n winston.format.simple(),\n ),\n transports: [new BackstageLoggerTransport(rootLogger, task, step.id)],\n });\n\n taskLogger.addRedactions(Object.values(task.secrets ?? {}));\n\n // This stream logger should be deprecated. We're going to replace it with\n // just using the logger directly, as all those logs get written to step logs\n // using the stepLogStream above.\n // Initially this stream used to be the only way to write to the client logs, but that\n // has changed over time, there's not really a need for this anymore.\n // You can just create a simple wrapper like the below in your action to write to the main logger.\n // This way we also get recactions for free.\n const streamLogger = new PassThrough();\n streamLogger.on('data', async data => {\n const message = data.toString().trim();\n if (message?.length > 1) {\n taskLogger.info(message);\n }\n });\n\n return { taskLogger, streamLogger };\n};\n\nconst isActionAuthorized = createConditionAuthorizer(\n Object.values(scaffolderActionRules),\n);\n\nexport class NunjucksWorkflowRunner implements WorkflowRunner {\n private readonly defaultTemplateFilters: Record<string, TemplateFilter>;\n\n constructor(private readonly options: NunjucksWorkflowRunnerOptions) {\n this.defaultTemplateFilters = createDefaultFilters({\n integrations: this.options.integrations,\n });\n }\n\n private readonly tracker = scaffoldingTracker();\n\n private isSingleTemplateString(input: string) {\n const { parser, nodes } = nunjucks as unknown as {\n parser: {\n parse(\n template: string,\n ctx: object,\n options: nunjucks.ConfigureOptions,\n ): { children: { children?: unknown[] }[] };\n };\n nodes: { TemplateData: Function };\n };\n\n const parsed = parser.parse(\n input,\n {},\n {\n autoescape: false,\n tags: {\n variableStart: '${{',\n variableEnd: '}}',\n },\n },\n );\n\n return (\n parsed.children.length === 1 &&\n !(parsed.children[0]?.children?.[0] instanceof nodes.TemplateData)\n );\n }\n\n private render<T>(\n input: T,\n context: TemplateContext,\n renderTemplate: SecureTemplateRenderer,\n ): T {\n return JSON.parse(JSON.stringify(input), (_key, value) => {\n try {\n if (typeof value === 'string') {\n try {\n if (this.isSingleTemplateString(value)) {\n // Lets convert ${{ parameters.bob }} to ${{ (parameters.bob) | dump }} so we can keep the input type\n const wrappedDumped = value.replace(\n /\\${{(.+)}}/g,\n '${{ ( $1 ) | dump }}',\n );\n\n // Run the templating\n const templated = renderTemplate(wrappedDumped, context);\n\n // If there's an empty string returned, then it's undefined\n if (templated === '') {\n return undefined;\n }\n\n // Reparse the dumped string\n return JSON.parse(templated);\n }\n } catch (ex) {\n this.options.logger.error(\n `Failed to parse template string: ${value} with error ${ex.message}`,\n );\n }\n\n // Fallback to default behaviour\n const templated = renderTemplate(value, context);\n\n if (templated === '') {\n return undefined;\n }\n\n return templated;\n }\n } catch {\n return value;\n }\n return value;\n });\n }\n\n async executeStep(\n task: TaskContext,\n step: TaskStep,\n context: TemplateContext,\n renderTemplate: (template: string, values: unknown) => string,\n taskTrack: TaskTrackType,\n workspacePath: string,\n decision: PolicyDecision,\n ) {\n const stepTrack = await this.tracker.stepStart(task, step);\n\n if (task.cancelSignal.aborted) {\n throw new Error(`Step ${step.name} has been cancelled.`);\n }\n\n try {\n if (\n step.if === false ||\n (typeof step.if === 'string' &&\n !isTruthy(this.render(step.if, context, renderTemplate)))\n ) {\n await stepTrack.skipFalsy();\n return;\n }\n const action: TemplateAction<JsonObject> =\n this.options.actionRegistry.get(step.action);\n const { taskLogger, streamLogger } = createStepLogger({\n task,\n step,\n rootLogger: this.options.logger,\n });\n\n if (task.isDryRun) {\n const redactedSecrets = Object.fromEntries(\n Object.entries(task.secrets ?? {}).map(secret => [secret[0], '***']),\n );\n const debugInput =\n (step.input &&\n this.render(\n step.input,\n {\n ...context,\n secrets: redactedSecrets,\n },\n renderTemplate,\n )) ??\n {};\n taskLogger.info(\n `Running ${\n action.id\n } in dry-run mode with inputs (secrets redacted): ${JSON.stringify(\n debugInput,\n undefined,\n 2,\n )}`,\n );\n if (!action.supportsDryRun) {\n await taskTrack.skipDryRun(step, action);\n const outputSchema = action.schema?.output;\n if (outputSchema) {\n context.steps[step.id] = {\n output: generateExampleOutput(outputSchema) as {\n [name in string]: JsonValue;\n },\n };\n } else {\n context.steps[step.id] = { output: {} };\n }\n return;\n }\n }\n const iterations = (\n step.each\n ? Object.entries(this.render(step.each, context, renderTemplate)).map(\n ([key, value]) => ({\n each: { key, value },\n }),\n )\n : [{}]\n ).map(i => ({\n ...i,\n // Secrets are only passed when templating the input to actions for security reasons\n input: step.input\n ? this.render(\n step.input,\n { ...context, secrets: task.secrets ?? {}, ...i },\n renderTemplate,\n )\n : {},\n }));\n for (const iteration of iterations) {\n const actionId = `${action.id}${\n iteration.each ? `[${iteration.each.key}]` : ''\n }`;\n\n if (action.schema?.input) {\n const validateResult = validateJsonSchema(\n iteration.input,\n action.schema.input,\n );\n if (!validateResult.valid) {\n const errors = validateResult.errors.join(', ');\n throw new InputError(\n `Invalid input passed to action ${actionId}, ${errors}`,\n );\n }\n }\n if (\n !isActionAuthorized(decision, {\n action: action.id,\n input: iteration.input,\n })\n ) {\n throw new NotAllowedError(\n `Unauthorized action: ${actionId}. The action is not allowed. Input: ${JSON.stringify(\n iteration.input,\n null,\n 2,\n )}`,\n );\n }\n }\n const tmpDirs = new Array<string>();\n const stepOutput: { [outputName: string]: JsonValue } = {};\n const prevTaskState = await task.getTaskState?.();\n\n for (const iteration of iterations) {\n if (iteration.each) {\n taskLogger.info(\n `Running step each: ${JSON.stringify(\n iteration.each,\n (k, v) => (k ? v.toString() : v),\n 0,\n )}`,\n );\n }\n await action.handler({\n input: iteration.input,\n secrets: task.secrets ?? {},\n // TODO(blam): move to LoggerService and away from Winston\n logger: loggerToWinstonLogger(taskLogger),\n logStream: streamLogger,\n workspacePath,\n async checkpoint<U extends JsonValue>(\n keySuffix: string,\n fn: () => Promise<U>,\n ) {\n const key = `v1.task.checkpoint.${step.id}.${keySuffix}`;\n try {\n let prevValue: U | undefined;\n if (prevTaskState) {\n const prevState = (\n prevTaskState.state?.checkpoints as {\n [key: string]: CheckpointState;\n }\n )?.[key];\n if (prevState && prevState.status === 'success') {\n prevValue = prevState.value as U;\n }\n }\n\n const value = prevValue ? prevValue : await fn();\n\n if (!prevValue) {\n task.updateCheckpoint?.({\n key,\n status: 'success',\n value,\n });\n }\n return value;\n } catch (err) {\n task.updateCheckpoint?.({\n key,\n status: 'failed',\n reason: stringifyError(err),\n });\n throw err;\n } finally {\n await task.serializeWorkspace?.({ path: workspacePath });\n }\n },\n createTemporaryDirectory: async () => {\n const tmpDir = await fs.mkdtemp(\n `${workspacePath}_step-${step.id}-`,\n );\n tmpDirs.push(tmpDir);\n return tmpDir;\n },\n output(name: string, value: JsonValue) {\n if (step.each) {\n stepOutput[name] = stepOutput[name] || [];\n (stepOutput[name] as JsonArray).push(value);\n } else {\n stepOutput[name] = value;\n }\n },\n templateInfo: task.spec.templateInfo,\n user: task.spec.user,\n isDryRun: task.isDryRun,\n signal: task.cancelSignal,\n getInitiatorCredentials: () => task.getInitiatorCredentials(),\n });\n }\n\n // Remove all temporary directories that were created when executing the action\n for (const tmpDir of tmpDirs) {\n await fs.remove(tmpDir);\n }\n\n context.steps[step.id] = { output: stepOutput };\n\n if (task.cancelSignal.aborted) {\n throw new Error(`Step ${step.name} has been cancelled.`);\n }\n\n await stepTrack.markSuccessful();\n } catch (err) {\n await taskTrack.markFailed(step, err);\n await stepTrack.markFailed();\n throw err;\n } finally {\n await task.serializeWorkspace?.({ path: workspacePath });\n }\n }\n\n async execute(task: TaskContext): Promise<WorkflowResponse> {\n if (!isValidTaskSpec(task.spec)) {\n throw new InputError(\n 'Wrong template version executed with the workflow engine',\n );\n }\n const taskId = await task.getWorkspaceName();\n\n const workspacePath = path.join(this.options.workingDirectory, taskId);\n\n const { additionalTemplateFilters, additionalTemplateGlobals } =\n this.options;\n\n const renderTemplate = await SecureTemplater.loadRenderer({\n templateFilters: {\n ...this.defaultTemplateFilters,\n ...additionalTemplateFilters,\n },\n templateGlobals: additionalTemplateGlobals,\n });\n\n try {\n await task.rehydrateWorkspace?.({ taskId, targetPath: workspacePath });\n\n const taskTrack = await this.tracker.taskStart(task);\n await fs.ensureDir(workspacePath);\n\n const context: TemplateContext = {\n parameters: task.spec.parameters,\n steps: {},\n user: task.spec.user,\n };\n\n const [decision]: PolicyDecision[] =\n this.options.permissions && task.spec.steps.length\n ? await this.options.permissions.authorizeConditional(\n [{ permission: actionExecutePermission }],\n { credentials: await task.getInitiatorCredentials() },\n )\n : [{ result: AuthorizeResult.ALLOW }];\n\n for (const step of task.spec.steps) {\n await this.executeStep(\n task,\n step,\n context,\n renderTemplate,\n taskTrack,\n workspacePath,\n decision,\n );\n }\n\n const output = this.render(task.spec.output, context, renderTemplate);\n await taskTrack.markSuccessful();\n await task.cleanWorkspace?.();\n\n return { output };\n } finally {\n if (workspacePath) {\n await fs.remove(workspacePath);\n }\n }\n }\n}\n\nfunction scaffoldingTracker() {\n // prom-client metrics are deprecated in favour of OpenTelemetry metrics.\n const promTaskCount = createCounterMetric({\n name: 'scaffolder_task_count',\n help: 'Count of task runs',\n labelNames: ['template', 'user', 'result'],\n });\n const promTaskDuration = createHistogramMetric({\n name: 'scaffolder_task_duration',\n help: 'Duration of a task run',\n labelNames: ['template', 'result'],\n });\n const promtStepCount = createCounterMetric({\n name: 'scaffolder_step_count',\n help: 'Count of step runs',\n labelNames: ['template', 'step', 'result'],\n });\n const promStepDuration = createHistogramMetric({\n name: 'scaffolder_step_duration',\n help: 'Duration of a step runs',\n labelNames: ['template', 'step', 'result'],\n });\n\n const meter = metrics.getMeter('default');\n const taskCount = meter.createCounter('scaffolder.task.count', {\n description: 'Count of task runs',\n });\n\n const taskDuration = meter.createHistogram('scaffolder.task.duration', {\n description: 'Duration of a task run',\n unit: 'seconds',\n });\n\n const stepCount = meter.createCounter('scaffolder.step.count', {\n description: 'Count of step runs',\n });\n\n const stepDuration = meter.createHistogram('scaffolder.step.duration', {\n description: 'Duration of a step runs',\n unit: 'seconds',\n });\n\n async function taskStart(task: TaskContext) {\n await task.emitLog(`Starting up task with ${task.spec.steps.length} steps`);\n const template = task.spec.templateInfo?.entityRef || '';\n const user = task.spec.user?.ref || '';\n\n const startTime = process.hrtime();\n const taskTimer = promTaskDuration.startTimer({\n template,\n });\n\n function endTime() {\n const delta = process.hrtime(startTime);\n return delta[0] + delta[1] / 1e9;\n }\n\n async function skipDryRun(\n step: TaskStep,\n action: TemplateAction<JsonObject>,\n ) {\n task.emitLog(`Skipping because ${action.id} does not support dry-run`, {\n stepId: step.id,\n status: 'skipped',\n });\n }\n\n async function markSuccessful() {\n promTaskCount.inc({\n template,\n user,\n result: 'ok',\n });\n taskTimer({ result: 'ok' });\n\n taskCount.add(1, { template, user, result: 'ok' });\n taskDuration.record(endTime(), {\n result: 'ok',\n });\n }\n\n async function markFailed(step: TaskStep, err: Error) {\n await task.emitLog(String(err.stack), {\n stepId: step.id,\n status: 'failed',\n });\n promTaskCount.inc({\n template,\n user,\n result: 'failed',\n });\n taskTimer({ result: 'failed' });\n\n taskCount.add(1, { template, user, result: 'failed' });\n taskDuration.record(endTime(), {\n result: 'failed',\n });\n }\n\n async function markCancelled(step: TaskStep) {\n await task.emitLog(`Step ${step.id} has been cancelled.`, {\n stepId: step.id,\n status: 'cancelled',\n });\n promTaskCount.inc({\n template,\n user,\n result: 'cancelled',\n });\n taskTimer({ result: 'cancelled' });\n\n taskCount.add(1, { template, user, result: 'cancelled' });\n taskDuration.record(endTime(), {\n result: 'cancelled',\n });\n }\n\n return {\n skipDryRun,\n markCancelled,\n markSuccessful,\n markFailed,\n };\n }\n\n async function stepStart(task: TaskContext, step: TaskStep) {\n await task.emitLog(`Beginning step ${step.name}`, {\n stepId: step.id,\n status: 'processing',\n });\n const template = task.spec.templateInfo?.entityRef || '';\n\n const startTime = process.hrtime();\n const stepTimer = promStepDuration.startTimer({\n template,\n step: step.name,\n });\n\n function endTime() {\n const delta = process.hrtime(startTime);\n return delta[0] + delta[1] / 1e9;\n }\n\n async function markSuccessful() {\n await task.emitLog(`Finished step ${step.name}`, {\n stepId: step.id,\n status: 'completed',\n });\n promtStepCount.inc({\n template,\n step: step.name,\n result: 'ok',\n });\n stepTimer({ result: 'ok' });\n\n stepCount.add(1, { template, step: step.name, result: 'ok' });\n stepDuration.record(endTime(), {\n result: 'ok',\n });\n }\n\n async function markCancelled() {\n promtStepCount.inc({\n template,\n step: step.name,\n result: 'cancelled',\n });\n stepTimer({ result: 'cancelled' });\n\n stepCount.add(1, { template, step: step.name, result: 'cancelled' });\n stepDuration.record(endTime(), {\n result: 'cancelled',\n });\n }\n\n async function markFailed() {\n promtStepCount.inc({\n template,\n step: step.name,\n result: 'failed',\n });\n stepTimer({ result: 'failed' });\n\n stepCount.add(1, { template, step: step.name, result: 'failed' });\n stepDuration.record(endTime(), {\n result: 'failed',\n });\n }\n\n async function skipFalsy() {\n await task.emitLog(\n `Skipping step ${step.id} because its if condition was false`,\n { stepId: step.id, status: 'skipped' },\n );\n stepTimer({ result: 'skipped' });\n\n stepCount.add(1, { template, step: step.name, result: 'skipped' });\n stepDuration.record(endTime(), {\n result: 'skipped',\n });\n }\n\n return {\n markCancelled,\n markFailed,\n markSuccessful,\n skipFalsy,\n };\n }\n\n return {\n taskStart,\n stepStart,\n };\n}\n"],"names":["WinstonLogger","winston","BackstageLoggerTransport","PassThrough","createConditionAuthorizer","scaffolderActionRules","createDefaultFilters","nunjucks","templated","isTruthy","generateExampleOutput","validateJsonSchema","errors","InputError","NotAllowedError","loggerToWinstonLogger","stringifyError","fs","path","SecureTemplater","actionExecutePermission","AuthorizeResult","createCounterMetric","createHistogramMetric","metrics"],"mappings":"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"}
1
+ {"version":3,"file":"NunjucksWorkflowRunner.cjs.js","sources":["../../../src/scaffolder/tasks/NunjucksWorkflowRunner.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ScmIntegrations } from '@backstage/integration';\nimport { TaskTrackType, WorkflowResponse, WorkflowRunner } from './types';\nimport * as winston from 'winston';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport nunjucks from 'nunjucks';\nimport { JsonArray, JsonObject, JsonValue } from '@backstage/types';\nimport { InputError, NotAllowedError, stringifyError } from '@backstage/errors';\nimport { PassThrough } from 'stream';\nimport { generateExampleOutput, isTruthy } from './helper';\nimport { validate as validateJsonSchema } from 'jsonschema';\nimport { TemplateActionRegistry } from '../actions';\nimport { metrics } from '@opentelemetry/api';\nimport {\n SecureTemplater,\n SecureTemplateRenderer,\n} from '../../lib/templating/SecureTemplater';\nimport {\n TaskRecovery,\n TaskSpec,\n TaskSpecV1beta3,\n TaskStep,\n} from '@backstage/plugin-scaffolder-common';\n\nimport {\n TemplateAction,\n TemplateFilter,\n TemplateGlobal,\n TaskContext,\n} from '@backstage/plugin-scaffolder-node';\nimport { createConditionAuthorizer } from '@backstage/plugin-permission-node';\nimport { UserEntity } from '@backstage/catalog-model';\nimport { createCounterMetric, createHistogramMetric } from '../../util/metrics';\nimport { createDefaultFilters } from '../../lib/templating/filters';\nimport {\n AuthorizeResult,\n PolicyDecision,\n} from '@backstage/plugin-permission-common';\nimport { scaffolderActionRules } from '../../service/rules';\nimport { actionExecutePermission } from '@backstage/plugin-scaffolder-common/alpha';\nimport { PermissionsService } from '@backstage/backend-plugin-api';\nimport { loggerToWinstonLogger } from '@backstage/backend-common';\nimport { BackstageLoggerTransport, WinstonLogger } from './logger';\n\ntype NunjucksWorkflowRunnerOptions = {\n workingDirectory: string;\n actionRegistry: TemplateActionRegistry;\n integrations: ScmIntegrations;\n logger: winston.Logger;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n permissions?: PermissionsService;\n};\n\ntype TemplateContext = {\n parameters: JsonObject;\n EXPERIMENTAL_recovery?: TaskRecovery;\n steps: {\n [stepName: string]: { output: { [outputName: string]: JsonValue } };\n };\n secrets?: Record<string, string>;\n user?: {\n entity?: UserEntity;\n ref?: string;\n };\n each?: JsonValue;\n};\n\ntype CheckpointState =\n | {\n status: 'failed';\n reason: string;\n }\n | {\n status: 'success';\n value: JsonValue;\n };\n\nconst isValidTaskSpec = (taskSpec: TaskSpec): taskSpec is TaskSpecV1beta3 => {\n return taskSpec.apiVersion === 'scaffolder.backstage.io/v1beta3';\n};\n\nconst createStepLogger = ({\n task,\n step,\n rootLogger,\n}: {\n task: TaskContext;\n step: TaskStep;\n rootLogger: winston.Logger;\n}) => {\n const taskLogger = WinstonLogger.create({\n level: process.env.LOG_LEVEL || 'info',\n format: winston.format.combine(\n winston.format.colorize(),\n winston.format.simple(),\n ),\n transports: [new BackstageLoggerTransport(rootLogger, task, step.id)],\n });\n\n taskLogger.addRedactions(Object.values(task.secrets ?? {}));\n\n // This stream logger should be deprecated. We're going to replace it with\n // just using the logger directly, as all those logs get written to step logs\n // using the stepLogStream above.\n // Initially this stream used to be the only way to write to the client logs, but that\n // has changed over time, there's not really a need for this anymore.\n // You can just create a simple wrapper like the below in your action to write to the main logger.\n // This way we also get recactions for free.\n const streamLogger = new PassThrough();\n streamLogger.on('data', async data => {\n const message = data.toString().trim();\n if (message?.length > 1) {\n taskLogger.info(message);\n }\n });\n\n return { taskLogger, streamLogger };\n};\n\nconst isActionAuthorized = createConditionAuthorizer(\n Object.values(scaffolderActionRules),\n);\n\nexport class NunjucksWorkflowRunner implements WorkflowRunner {\n private readonly defaultTemplateFilters: Record<string, TemplateFilter>;\n\n constructor(private readonly options: NunjucksWorkflowRunnerOptions) {\n this.defaultTemplateFilters = createDefaultFilters({\n integrations: this.options.integrations,\n });\n }\n\n private readonly tracker = scaffoldingTracker();\n\n private isSingleTemplateString(input: string) {\n const { parser, nodes } = nunjucks as unknown as {\n parser: {\n parse(\n template: string,\n ctx: object,\n options: nunjucks.ConfigureOptions,\n ): { children: { children?: unknown[] }[] };\n };\n nodes: { TemplateData: Function };\n };\n\n const parsed = parser.parse(\n input,\n {},\n {\n autoescape: false,\n tags: {\n variableStart: '${{',\n variableEnd: '}}',\n },\n },\n );\n\n return (\n parsed.children.length === 1 &&\n !(parsed.children[0]?.children?.[0] instanceof nodes.TemplateData)\n );\n }\n\n private render<T>(\n input: T,\n context: TemplateContext,\n renderTemplate: SecureTemplateRenderer,\n ): T {\n return JSON.parse(JSON.stringify(input), (_key, value) => {\n try {\n if (typeof value === 'string') {\n try {\n if (this.isSingleTemplateString(value)) {\n // Lets convert ${{ parameters.bob }} to ${{ (parameters.bob) | dump }} so we can keep the input type\n const wrappedDumped = value.replace(\n /\\${{(.+)}}/g,\n '${{ ( $1 ) | dump }}',\n );\n\n // Run the templating\n const templated = renderTemplate(wrappedDumped, context);\n\n // If there's an empty string returned, then it's undefined\n if (templated === '') {\n return undefined;\n }\n\n // Reparse the dumped string\n return JSON.parse(templated);\n }\n } catch (ex) {\n this.options.logger.error(\n `Failed to parse template string: ${value} with error ${ex.message}`,\n );\n }\n\n // Fallback to default behaviour\n const templated = renderTemplate(value, context);\n\n if (templated === '') {\n return undefined;\n }\n\n return templated;\n }\n } catch {\n return value;\n }\n return value;\n });\n }\n\n async executeStep(\n task: TaskContext,\n step: TaskStep,\n context: TemplateContext,\n renderTemplate: (template: string, values: unknown) => string,\n taskTrack: TaskTrackType,\n workspacePath: string,\n decision: PolicyDecision,\n ) {\n const stepTrack = await this.tracker.stepStart(task, step);\n\n if (task.cancelSignal.aborted) {\n throw new Error(`Step ${step.name} has been cancelled.`);\n }\n\n try {\n if (\n step.if === false ||\n (typeof step.if === 'string' &&\n !isTruthy(this.render(step.if, context, renderTemplate)))\n ) {\n await stepTrack.skipFalsy();\n return;\n }\n const action: TemplateAction<JsonObject> =\n this.options.actionRegistry.get(step.action);\n const { taskLogger, streamLogger } = createStepLogger({\n task,\n step,\n rootLogger: this.options.logger,\n });\n\n if (task.isDryRun) {\n const redactedSecrets = Object.fromEntries(\n Object.entries(task.secrets ?? {}).map(secret => [secret[0], '***']),\n );\n const debugInput =\n (step.input &&\n this.render(\n step.input,\n {\n ...context,\n secrets: redactedSecrets,\n },\n renderTemplate,\n )) ??\n {};\n taskLogger.info(\n `Running ${\n action.id\n } in dry-run mode with inputs (secrets redacted): ${JSON.stringify(\n debugInput,\n undefined,\n 2,\n )}`,\n );\n if (!action.supportsDryRun) {\n await taskTrack.skipDryRun(step, action);\n const outputSchema = action.schema?.output;\n if (outputSchema) {\n context.steps[step.id] = {\n output: generateExampleOutput(outputSchema) as {\n [name in string]: JsonValue;\n },\n };\n } else {\n context.steps[step.id] = { output: {} };\n }\n return;\n }\n }\n const iterations = (\n step.each\n ? Object.entries(this.render(step.each, context, renderTemplate)).map(\n ([key, value]) => ({\n each: { key, value },\n }),\n )\n : [{}]\n ).map(i => ({\n ...i,\n // Secrets are only passed when templating the input to actions for security reasons\n input: step.input\n ? this.render(\n step.input,\n { ...context, secrets: task.secrets ?? {}, ...i },\n renderTemplate,\n )\n : {},\n }));\n for (const iteration of iterations) {\n const actionId = `${action.id}${\n iteration.each ? `[${iteration.each.key}]` : ''\n }`;\n\n if (action.schema?.input) {\n const validateResult = validateJsonSchema(\n iteration.input,\n action.schema.input,\n );\n if (!validateResult.valid) {\n const errors = validateResult.errors.join(', ');\n throw new InputError(\n `Invalid input passed to action ${actionId}, ${errors}`,\n );\n }\n }\n if (\n !isActionAuthorized(decision, {\n action: action.id,\n input: iteration.input,\n })\n ) {\n throw new NotAllowedError(\n `Unauthorized action: ${actionId}. The action is not allowed. Input: ${JSON.stringify(\n iteration.input,\n null,\n 2,\n )}`,\n );\n }\n }\n const tmpDirs = new Array<string>();\n const stepOutput: { [outputName: string]: JsonValue } = {};\n const prevTaskState = await task.getTaskState?.();\n\n for (const iteration of iterations) {\n if (iteration.each) {\n taskLogger.info(\n `Running step each: ${JSON.stringify(\n iteration.each,\n (k, v) => (k ? v.toString() : v),\n 0,\n )}`,\n );\n }\n await action.handler({\n input: iteration.input,\n secrets: task.secrets ?? {},\n // TODO(blam): move to LoggerService and away from Winston\n logger: loggerToWinstonLogger(taskLogger),\n logStream: streamLogger,\n workspacePath,\n async checkpoint<U extends JsonValue>(\n keySuffix: string,\n fn: () => Promise<U>,\n ) {\n const key = `v1.task.checkpoint.${step.id}.${keySuffix}`;\n try {\n let prevValue: U | undefined;\n if (prevTaskState) {\n const prevState = (\n prevTaskState.state?.checkpoints as {\n [key: string]: CheckpointState;\n }\n )?.[key];\n if (prevState && prevState.status === 'success') {\n prevValue = prevState.value as U;\n }\n }\n\n const value = prevValue ? prevValue : await fn();\n\n if (!prevValue) {\n task.updateCheckpoint?.({\n key,\n status: 'success',\n value,\n });\n }\n return value;\n } catch (err) {\n task.updateCheckpoint?.({\n key,\n status: 'failed',\n reason: stringifyError(err),\n });\n throw err;\n } finally {\n await task.serializeWorkspace?.({ path: workspacePath });\n }\n },\n createTemporaryDirectory: async () => {\n const tmpDir = await fs.mkdtemp(\n `${workspacePath}_step-${step.id}-`,\n );\n tmpDirs.push(tmpDir);\n return tmpDir;\n },\n output(name: string, value: JsonValue) {\n if (step.each) {\n stepOutput[name] = stepOutput[name] || [];\n (stepOutput[name] as JsonArray).push(value);\n } else {\n stepOutput[name] = value;\n }\n },\n templateInfo: task.spec.templateInfo,\n user: task.spec.user,\n isDryRun: task.isDryRun,\n signal: task.cancelSignal,\n getInitiatorCredentials: () => task.getInitiatorCredentials(),\n });\n }\n\n // Remove all temporary directories that were created when executing the action\n for (const tmpDir of tmpDirs) {\n await fs.remove(tmpDir);\n }\n\n context.steps[step.id] = { output: stepOutput };\n\n if (task.cancelSignal.aborted) {\n throw new Error(`Step ${step.name} has been cancelled.`);\n }\n\n await stepTrack.markSuccessful();\n } catch (err) {\n await taskTrack.markFailed(step, err);\n await stepTrack.markFailed();\n throw err;\n } finally {\n await task.serializeWorkspace?.({ path: workspacePath });\n }\n }\n\n async execute(task: TaskContext): Promise<WorkflowResponse> {\n if (!isValidTaskSpec(task.spec)) {\n throw new InputError(\n 'Wrong template version executed with the workflow engine',\n );\n }\n const taskId = await task.getWorkspaceName();\n\n const workspacePath = path.join(this.options.workingDirectory, taskId);\n\n const { additionalTemplateFilters, additionalTemplateGlobals } =\n this.options;\n\n const renderTemplate = await SecureTemplater.loadRenderer({\n templateFilters: {\n ...this.defaultTemplateFilters,\n ...additionalTemplateFilters,\n },\n templateGlobals: additionalTemplateGlobals,\n });\n\n try {\n await task.rehydrateWorkspace?.({ taskId, targetPath: workspacePath });\n\n const taskTrack = await this.tracker.taskStart(task);\n await fs.ensureDir(workspacePath);\n\n const context: TemplateContext = {\n parameters: task.spec.parameters,\n steps: {},\n user: task.spec.user,\n };\n\n const [decision]: PolicyDecision[] =\n this.options.permissions && task.spec.steps.length\n ? await this.options.permissions.authorizeConditional(\n [{ permission: actionExecutePermission }],\n { credentials: await task.getInitiatorCredentials() },\n )\n : [{ result: AuthorizeResult.ALLOW }];\n\n for (const step of task.spec.steps) {\n await this.executeStep(\n task,\n step,\n context,\n renderTemplate,\n taskTrack,\n workspacePath,\n decision,\n );\n }\n\n const output = this.render(task.spec.output, context, renderTemplate);\n await taskTrack.markSuccessful();\n await task.cleanWorkspace?.();\n\n return { output };\n } finally {\n if (workspacePath) {\n await fs.remove(workspacePath);\n }\n }\n }\n}\n\nfunction scaffoldingTracker() {\n // prom-client metrics are deprecated in favour of OpenTelemetry metrics.\n const promTaskCount = createCounterMetric({\n name: 'scaffolder_task_count',\n help: 'Count of task runs',\n labelNames: ['template', 'user', 'result'],\n });\n const promTaskDuration = createHistogramMetric({\n name: 'scaffolder_task_duration',\n help: 'Duration of a task run',\n labelNames: ['template', 'result'],\n });\n const promtStepCount = createCounterMetric({\n name: 'scaffolder_step_count',\n help: 'Count of step runs',\n labelNames: ['template', 'step', 'result'],\n });\n const promStepDuration = createHistogramMetric({\n name: 'scaffolder_step_duration',\n help: 'Duration of a step runs',\n labelNames: ['template', 'step', 'result'],\n });\n\n const meter = metrics.getMeter('default');\n const taskCount = meter.createCounter('scaffolder.task.count', {\n description: 'Count of task runs',\n });\n\n const taskDuration = meter.createHistogram('scaffolder.task.duration', {\n description: 'Duration of a task run',\n unit: 'seconds',\n });\n\n const stepCount = meter.createCounter('scaffolder.step.count', {\n description: 'Count of step runs',\n });\n\n const stepDuration = meter.createHistogram('scaffolder.step.duration', {\n description: 'Duration of a step runs',\n unit: 'seconds',\n });\n\n async function taskStart(task: TaskContext) {\n await task.emitLog(`Starting up task with ${task.spec.steps.length} steps`);\n const template = task.spec.templateInfo?.entityRef || '';\n const user = task.spec.user?.ref || '';\n\n const startTime = process.hrtime();\n const taskTimer = promTaskDuration.startTimer({\n template,\n });\n\n function endTime() {\n const delta = process.hrtime(startTime);\n return delta[0] + delta[1] / 1e9;\n }\n\n async function skipDryRun(\n step: TaskStep,\n action: TemplateAction<JsonObject>,\n ) {\n task.emitLog(`Skipping because ${action.id} does not support dry-run`, {\n stepId: step.id,\n status: 'skipped',\n });\n }\n\n async function markSuccessful() {\n promTaskCount.inc({\n template,\n user,\n result: 'ok',\n });\n taskTimer({ result: 'ok' });\n\n taskCount.add(1, { template, user, result: 'ok' });\n taskDuration.record(endTime(), {\n result: 'ok',\n });\n }\n\n async function markFailed(step: TaskStep, err: Error) {\n await task.emitLog(String(err.stack), {\n stepId: step.id,\n status: 'failed',\n });\n promTaskCount.inc({\n template,\n user,\n result: 'failed',\n });\n taskTimer({ result: 'failed' });\n\n taskCount.add(1, { template, user, result: 'failed' });\n taskDuration.record(endTime(), {\n result: 'failed',\n });\n }\n\n async function markCancelled(step: TaskStep) {\n await task.emitLog(`Step ${step.id} has been cancelled.`, {\n stepId: step.id,\n status: 'cancelled',\n });\n promTaskCount.inc({\n template,\n user,\n result: 'cancelled',\n });\n taskTimer({ result: 'cancelled' });\n\n taskCount.add(1, { template, user, result: 'cancelled' });\n taskDuration.record(endTime(), {\n result: 'cancelled',\n });\n }\n\n return {\n skipDryRun,\n markCancelled,\n markSuccessful,\n markFailed,\n };\n }\n\n async function stepStart(task: TaskContext, step: TaskStep) {\n await task.emitLog(`Beginning step ${step.name}`, {\n stepId: step.id,\n status: 'processing',\n });\n const template = task.spec.templateInfo?.entityRef || '';\n\n const startTime = process.hrtime();\n const stepTimer = promStepDuration.startTimer({\n template,\n step: step.name,\n });\n\n function endTime() {\n const delta = process.hrtime(startTime);\n return delta[0] + delta[1] / 1e9;\n }\n\n async function markSuccessful() {\n await task.emitLog(`Finished step ${step.name}`, {\n stepId: step.id,\n status: 'completed',\n });\n promtStepCount.inc({\n template,\n step: step.name,\n result: 'ok',\n });\n stepTimer({ result: 'ok' });\n\n stepCount.add(1, { template, step: step.name, result: 'ok' });\n stepDuration.record(endTime(), {\n result: 'ok',\n });\n }\n\n async function markCancelled() {\n promtStepCount.inc({\n template,\n step: step.name,\n result: 'cancelled',\n });\n stepTimer({ result: 'cancelled' });\n\n stepCount.add(1, { template, step: step.name, result: 'cancelled' });\n stepDuration.record(endTime(), {\n result: 'cancelled',\n });\n }\n\n async function markFailed() {\n promtStepCount.inc({\n template,\n step: step.name,\n result: 'failed',\n });\n stepTimer({ result: 'failed' });\n\n stepCount.add(1, { template, step: step.name, result: 'failed' });\n stepDuration.record(endTime(), {\n result: 'failed',\n });\n }\n\n async function skipFalsy() {\n await task.emitLog(\n `Skipping step ${step.id} because its if condition was false`,\n { stepId: step.id, status: 'skipped' },\n );\n stepTimer({ result: 'skipped' });\n\n stepCount.add(1, { template, step: step.name, result: 'skipped' });\n stepDuration.record(endTime(), {\n result: 'skipped',\n });\n }\n\n return {\n markCancelled,\n markFailed,\n markSuccessful,\n skipFalsy,\n };\n }\n\n return {\n taskStart,\n stepStart,\n };\n}\n"],"names":["WinstonLogger","winston","BackstageLoggerTransport","PassThrough","createConditionAuthorizer","scaffolderActionRules","createDefaultFilters","nunjucks","templated","isTruthy","generateExampleOutput","validateJsonSchema","errors","InputError","NotAllowedError","loggerToWinstonLogger","stringifyError","fs","path","SecureTemplater","actionExecutePermission","AuthorizeResult","createCounterMetric","createHistogramMetric","metrics"],"mappings":"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"}