@backstage/plugin-scaffolder-backend 0.18.0-next.0 → 1.0.1-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +76 -0
- package/dist/index.cjs.js +75 -0
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +62 -4
- package/package.json +13 -13
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../src/scaffolder/actions/createTemplateAction.ts","../src/scaffolder/actions/builtin/catalog/register.ts","../src/scaffolder/actions/builtin/catalog/write.ts","../src/scaffolder/actions/builtin/debug/log.ts","../src/scaffolder/actions/builtin/fetch/helpers.ts","../src/scaffolder/actions/builtin/fetch/plain.ts","../src/lib/templating/SecureTemplater.ts","../src/scaffolder/actions/builtin/fetch/template.ts","../src/scaffolder/actions/builtin/filesystem/delete.ts","../src/scaffolder/actions/builtin/filesystem/rename.ts","../src/scaffolder/actions/builtin/helpers.ts","../src/scaffolder/actions/builtin/publish/util.ts","../src/scaffolder/actions/builtin/publish/azure.ts","../src/scaffolder/actions/builtin/publish/bitbucket.ts","../src/scaffolder/actions/builtin/publish/file.ts","../src/scaffolder/actions/builtin/github/helpers.ts","../src/scaffolder/actions/builtin/publish/github.ts","../src/scaffolder/actions/builtin/publish/githubPullRequest.ts","../src/scaffolder/actions/builtin/publish/gitlab.ts","../src/scaffolder/actions/builtin/publish/gitlabMergeRequest.ts","../src/scaffolder/actions/builtin/github/githubActionsDispatch.ts","../src/scaffolder/actions/builtin/github/githubWebhook.ts","../src/scaffolder/actions/builtin/createBuiltinActions.ts","../src/scaffolder/actions/TemplateActionRegistry.ts","../src/scaffolder/tasks/DatabaseTaskStore.ts","../src/scaffolder/tasks/StorageTaskBroker.ts","../src/scaffolder/tasks/helper.ts","../src/scaffolder/tasks/NunjucksWorkflowRunner.ts","../src/scaffolder/tasks/TaskWorker.ts","../src/service/helpers.ts","../src/service/router.ts","../src/processor/ScaffolderEntitiesProcessor.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 { TemplateAction } from './types';\n\n/**\n * This function is used to create new template actions to get type safety.\n * @public\n */\nexport const createTemplateAction = <TInput extends JsonObject>(\n templateAction: TemplateAction<TInput>,\n): TemplateAction<TInput> => {\n // TODO(blam): Can add some more validation here to validate the action later on\n return templateAction;\n};\n","/*\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 { InputError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport { createTemplateAction } from '../../createTemplateAction';\n\n/**\n * Registers entities from a catalog descriptor file in the workspace into the software catalog.\n * @public\n */\nexport function createCatalogRegisterAction(options: {\n catalogClient: CatalogApi;\n integrations: ScmIntegrations;\n}) {\n const { catalogClient, integrations } = options;\n\n return createTemplateAction<\n | { catalogInfoUrl: string; optional?: boolean }\n | { repoContentsUrl: string; catalogInfoPath?: string; optional?: boolean }\n >({\n id: 'catalog:register',\n description:\n 'Registers entities from a catalog descriptor file in the workspace into the software catalog.',\n schema: {\n input: {\n oneOf: [\n {\n type: 'object',\n required: ['catalogInfoUrl'],\n properties: {\n catalogInfoUrl: {\n title: 'Catalog Info URL',\n description:\n 'An absolute URL pointing to the catalog info file location',\n type: 'string',\n },\n optional: {\n title: 'Optional',\n description:\n 'Permit the registered location to optionally exist. Default: false',\n type: 'boolean',\n },\n },\n },\n {\n type: 'object',\n required: ['repoContentsUrl'],\n properties: {\n repoContentsUrl: {\n title: 'Repository Contents URL',\n description:\n 'An absolute URL pointing to the root of a repository directory tree',\n type: 'string',\n },\n catalogInfoPath: {\n title: 'Fetch URL',\n description:\n 'A relative path from the repo root pointing to the catalog info file, defaults to /catalog-info.yaml',\n type: 'string',\n },\n optional: {\n title: 'Optional',\n description:\n 'Permit the registered location to optionally exist. Default: false',\n type: 'boolean',\n },\n },\n },\n ],\n },\n },\n async handler(ctx) {\n const { input } = ctx;\n\n let catalogInfoUrl;\n if ('catalogInfoUrl' in input) {\n catalogInfoUrl = input.catalogInfoUrl;\n } else {\n const { repoContentsUrl, catalogInfoPath = '/catalog-info.yaml' } =\n input;\n const integration = integrations.byUrl(repoContentsUrl);\n if (!integration) {\n throw new InputError(\n `No integration found for host ${repoContentsUrl}`,\n );\n }\n\n catalogInfoUrl = integration.resolveUrl({\n base: repoContentsUrl,\n url: catalogInfoPath,\n });\n }\n\n ctx.logger.info(`Registering ${catalogInfoUrl} in the catalog`);\n\n await catalogClient.addLocation(\n {\n type: 'url',\n target: catalogInfoUrl,\n },\n ctx.secrets?.backstageToken\n ? { token: ctx.secrets.backstageToken }\n : {},\n );\n\n try {\n const result = await catalogClient.addLocation(\n {\n dryRun: true,\n type: 'url',\n target: catalogInfoUrl,\n },\n ctx.secrets?.backstageToken\n ? { token: ctx.secrets.backstageToken }\n : {},\n );\n\n if (result.entities.length > 0) {\n const { entities } = result;\n let entity: any;\n // prioritise 'Component' type as it is the most central kind of entity\n entity = entities.find(\n (e: any) =>\n !e.metadata.name.startsWith('generated-') &&\n e.kind === 'Component',\n );\n if (!entity) {\n entity = entities.find(\n (e: any) => !e.metadata.name.startsWith('generated-'),\n );\n }\n if (!entity) {\n entity = entities[0];\n }\n\n ctx.output('entityRef', stringifyEntityRef(entity));\n }\n } catch (e) {\n if (!input.optional) {\n throw e;\n }\n }\n\n ctx.output('catalogInfoUrl', catalogInfoUrl);\n },\n });\n}\n","/*\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 fs from 'fs-extra';\nimport { createTemplateAction } from '../../createTemplateAction';\nimport * as yaml from 'yaml';\nimport { Entity } from '@backstage/catalog-model';\nimport { resolveSafeChildPath } from '@backstage/backend-common';\n\n/**\n * Writes a catalog descriptor file containing the provided entity to a path in the workspace.\n * @public\n */\nexport function createCatalogWriteAction() {\n return createTemplateAction<{ filePath?: string; entity: Entity }>({\n id: 'catalog:write',\n description: 'Writes the catalog-info.yaml for your template',\n schema: {\n input: {\n type: 'object',\n properties: {\n filePath: {\n title: 'Catalog file path',\n description: 'Defaults to catalog-info.yaml',\n type: 'string',\n },\n entity: {\n title: 'Entity info to write catalog-info.yaml',\n description:\n 'You can provide the same values used in the Entity schema.',\n type: 'object',\n },\n },\n },\n },\n async handler(ctx) {\n ctx.logStream.write(`Writing catalog-info.yaml`);\n const { filePath, entity } = ctx.input;\n const path = filePath ?? 'catalog-info.yaml';\n\n await fs.writeFile(\n resolveSafeChildPath(ctx.workspacePath, path),\n yaml.stringify(entity),\n );\n },\n });\n}\n","/*\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 { readdir, stat } from 'fs-extra';\nimport { relative, join } from 'path';\nimport { createTemplateAction } from '../../createTemplateAction';\n\n/**\n * Writes a message into the log or lists all files in the workspace\n *\n * @remarks\n *\n * This task is useful for local development and testing of both the scaffolder\n * and scaffolder templates.\n *\n * @public\n */\nexport function createDebugLogAction() {\n return createTemplateAction<{ message?: string; listWorkspace?: boolean }>({\n id: 'debug:log',\n description:\n 'Writes a message into the log or lists all files in the workspace.',\n schema: {\n input: {\n type: 'object',\n properties: {\n message: {\n title: 'Message to output.',\n type: 'string',\n },\n listWorkspace: {\n title: 'List all files in the workspace, if true.',\n type: 'boolean',\n },\n extra: {\n title: 'Extra info',\n },\n },\n },\n },\n async handler(ctx) {\n ctx.logger.info(JSON.stringify(ctx.input, null, 2));\n\n if (ctx.input?.message) {\n ctx.logStream.write(ctx.input.message);\n }\n\n if (ctx.input?.listWorkspace) {\n const files = await recursiveReadDir(ctx.workspacePath);\n ctx.logStream.write(\n `Workspace:\\n${files\n .map(f => ` - ${relative(ctx.workspacePath, f)}`)\n .join('\\n')}`,\n );\n }\n },\n });\n}\n\nexport async function recursiveReadDir(dir: string): Promise<string[]> {\n const subdirs = await readdir(dir);\n const files = await Promise.all(\n subdirs.map(async subdir => {\n const res = join(dir, subdir);\n return (await stat(res)).isDirectory() ? recursiveReadDir(res) : [res];\n }),\n );\n return files.reduce((a, f) => a.concat(f), []);\n}\n","/*\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 { resolveSafeChildPath, UrlReader } from '@backstage/backend-common';\nimport { InputError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport fs from 'fs-extra';\nimport path from 'path';\n\n/**\n * A helper function that reads the contents of a directory from the given URL.\n * Can be used in your own actions, and also used behind fetch:template and fetch:plain\n *\n * @public\n */\nexport async function fetchContents({\n reader,\n integrations,\n baseUrl,\n fetchUrl = '.',\n outputPath,\n}: {\n reader: UrlReader;\n integrations: ScmIntegrations;\n baseUrl?: string;\n fetchUrl?: string;\n outputPath: string;\n}) {\n let fetchUrlIsAbsolute = false;\n try {\n // eslint-disable-next-line no-new\n new URL(fetchUrl);\n fetchUrlIsAbsolute = true;\n } catch {\n /* ignored */\n }\n\n // We handle both file locations and url ones\n if (!fetchUrlIsAbsolute && baseUrl?.startsWith('file://')) {\n const basePath = baseUrl.slice('file://'.length);\n const srcDir = resolveSafeChildPath(path.dirname(basePath), fetchUrl);\n await fs.copy(srcDir, outputPath);\n } else {\n let readUrl;\n\n if (fetchUrlIsAbsolute) {\n readUrl = fetchUrl;\n } else if (baseUrl) {\n const integration = integrations.byUrl(baseUrl);\n if (!integration) {\n throw new InputError(`No integration found for location ${baseUrl}`);\n }\n\n readUrl = integration.resolveUrl({\n url: fetchUrl,\n base: baseUrl,\n });\n } else {\n throw new InputError(\n `Failed to fetch, template location could not be determined and the fetch URL is relative, ${fetchUrl}`,\n );\n }\n\n const res = await reader.readTree(readUrl);\n await fs.ensureDir(outputPath);\n await res.dir({ targetDir: outputPath });\n }\n}\n","/*\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 { UrlReader, resolveSafeChildPath } from '@backstage/backend-common';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { fetchContents } from './helpers';\nimport { createTemplateAction } from '../../createTemplateAction';\n\n/**\n * Downloads content and places it in the workspace, or optionally\n * in a subdirectory specified by the 'targetPath' input option.\n * @public\n */\nexport function createFetchPlainAction(options: {\n reader: UrlReader;\n integrations: ScmIntegrations;\n}) {\n const { reader, integrations } = options;\n\n return createTemplateAction<{ url: string; targetPath?: string }>({\n id: 'fetch:plain',\n description:\n \"Downloads content and places it in the workspace, or optionally in a subdirectory specified by the 'targetPath' input option.\",\n schema: {\n input: {\n type: 'object',\n required: ['url'],\n properties: {\n url: {\n title: 'Fetch URL',\n description:\n 'Relative path or absolute URL pointing to the directory tree to fetch',\n type: 'string',\n },\n targetPath: {\n title: 'Target Path',\n description:\n 'Target path within the working directory to download the contents to.',\n type: 'string',\n },\n },\n },\n },\n async handler(ctx) {\n ctx.logger.info('Fetching plain content from remote URL');\n\n // Finally move the template result into the task workspace\n const targetPath = ctx.input.targetPath ?? './';\n const outputPath = resolveSafeChildPath(ctx.workspacePath, targetPath);\n\n await fetchContents({\n reader,\n integrations,\n baseUrl: ctx.templateInfo?.baseUrl,\n fetchUrl: ctx.input.url,\n outputPath,\n });\n },\n });\n}\n","/*\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 { VM } from 'vm2';\nimport { resolvePackagePath } from '@backstage/backend-common';\nimport fs from 'fs-extra';\nimport { JsonValue } from '@backstage/types';\nimport { RepoSpec } from '../../scaffolder/actions/builtin/publish/util';\n\n// language=JavaScript\nconst mkScript = (nunjucksSource: string) => `\nconst { render, renderCompat } = (() => {\n const module = {};\n const process = { env: {} };\n const require = (pkg) => { if (pkg === 'events') { return function (){}; }};\n\n ${nunjucksSource}\n\n const env = module.exports.configure({\n autoescape: false,\n tags: {\n variableStart: '\\${{',\n variableEnd: '}}',\n },\n });\n\n const compatEnv = module.exports.configure({\n autoescape: false,\n tags: {\n variableStart: '{{',\n variableEnd: '}}',\n },\n });\n compatEnv.addFilter('jsonify', compatEnv.getFilter('dump'));\n\n if (typeof parseRepoUrl !== 'undefined') {\n const safeHelperRef = parseRepoUrl;\n\n env.addFilter('parseRepoUrl', repoUrl => {\n return JSON.parse(safeHelperRef(repoUrl))\n });\n env.addFilter('projectSlug', repoUrl => {\n const { owner, repo } = JSON.parse(safeHelperRef(repoUrl));\n return owner + '/' + repo;\n });\n }\n\n if (typeof additionalTemplateFilters !== 'undefined') {\n for (const [filterName, filterFn] of Object.entries(additionalTemplateFilters)) {\n env.addFilter(filterName, (...args) => JSON.parse(filterFn(...args)));\n }\n }\n\n let uninstallCompat = undefined;\n\n function render(str, values) {\n try {\n if (uninstallCompat) {\n uninstallCompat();\n uninstallCompat = undefined;\n }\n return env.renderString(str, JSON.parse(values));\n } catch (error) {\n // Make sure errors don't leak anything\n throw new Error(String(error.message));\n }\n }\n\n function renderCompat(str, values) {\n try {\n if (!uninstallCompat) {\n uninstallCompat = module.exports.installJinjaCompat();\n }\n return compatEnv.renderString(str, JSON.parse(values));\n } catch (error) {\n // Make sure errors don't leak anything\n throw new Error(String(error.message));\n }\n }\n\n return { render, renderCompat };\n})();\n`;\n\n/** @public */\nexport type TemplateFilter = (...args: JsonValue[]) => JsonValue | undefined;\n\nexport interface SecureTemplaterOptions {\n /* Optional implementation of the parseRepoUrl filter */\n parseRepoUrl?(repoUrl: string): RepoSpec;\n\n /* Enables jinja compatibility and the \"jsonify\" filter */\n cookiecutterCompat?: boolean;\n\n /* Extra user-provided nunjucks filters */\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n}\n\nexport type SecureTemplateRenderer = (\n template: string,\n values: unknown,\n) => string;\n\nexport class SecureTemplater {\n static async loadRenderer(options: SecureTemplaterOptions = {}) {\n const { parseRepoUrl, cookiecutterCompat, additionalTemplateFilters } =\n options;\n const sandbox: Record<string, any> = {};\n\n if (parseRepoUrl) {\n sandbox.parseRepoUrl = (url: string) => JSON.stringify(parseRepoUrl(url));\n }\n\n if (additionalTemplateFilters) {\n sandbox.additionalTemplateFilters = Object.fromEntries(\n Object.entries(additionalTemplateFilters)\n .filter(([_, filterFunction]) => !!filterFunction)\n .map(([filterName, filterFunction]) => [\n filterName,\n (...args: JsonValue[]) => JSON.stringify(filterFunction(...args)),\n ]),\n );\n }\n\n const vm = new VM({ sandbox });\n\n const nunjucksSource = await fs.readFile(\n resolvePackagePath(\n '@backstage/plugin-scaffolder-backend',\n 'assets/nunjucks.js.txt',\n ),\n 'utf-8',\n );\n\n vm.run(mkScript(nunjucksSource));\n\n const render: SecureTemplateRenderer = (template, values) => {\n if (!vm) {\n throw new Error('SecureTemplater has not been initialized');\n }\n vm.setGlobal('templateStr', template);\n vm.setGlobal('templateValues', JSON.stringify(values));\n\n if (cookiecutterCompat) {\n return vm.run(`renderCompat(templateStr, templateValues)`);\n }\n\n return vm.run(`render(templateStr, templateValues)`);\n };\n return render;\n }\n}\n","/*\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 { extname } from 'path';\nimport { resolveSafeChildPath, UrlReader } from '@backstage/backend-common';\nimport { InputError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { fetchContents } from './helpers';\nimport { createTemplateAction } from '../../createTemplateAction';\nimport globby from 'globby';\nimport fs from 'fs-extra';\nimport { isBinaryFile } from 'isbinaryfile';\nimport {\n TemplateFilter,\n SecureTemplater,\n} from '../../../../lib/templating/SecureTemplater';\n\n/**\n * Downloads a skeleton, templates variables into file and directory names and content.\n * Then places the result in the workspace, or optionally in a subdirectory\n * specified by the 'targetPath' input option.\n *\n * @public\n */\nexport function createFetchTemplateAction(options: {\n reader: UrlReader;\n integrations: ScmIntegrations;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n}) {\n const { reader, integrations, additionalTemplateFilters } = options;\n\n return createTemplateAction<{\n url: string;\n targetPath?: string;\n values: any;\n templateFileExtension?: string | boolean;\n\n // Cookiecutter compat options\n copyWithoutRender?: string[];\n cookiecutterCompat?: boolean;\n }>({\n id: 'fetch:template',\n description:\n \"Downloads a skeleton, templates variables into file and directory names and content, and places the result in the workspace, or optionally in a subdirectory specified by the 'targetPath' input option.\",\n schema: {\n input: {\n type: 'object',\n required: ['url'],\n properties: {\n url: {\n title: 'Fetch URL',\n description:\n 'Relative path or absolute URL pointing to the directory tree to fetch',\n type: 'string',\n },\n targetPath: {\n title: 'Target Path',\n description:\n 'Target path within the working directory to download the contents to. Defaults to the working directory root.',\n type: 'string',\n },\n values: {\n title: 'Template Values',\n description: 'Values to pass on to the templating engine',\n type: 'object',\n },\n copyWithoutRender: {\n title: 'Copy Without Render',\n description:\n 'An array of glob patterns. Any files or directories which match are copied without being processed as templates.',\n type: 'array',\n items: {\n type: 'string',\n },\n },\n cookiecutterCompat: {\n title: 'Cookiecutter compatibility mode',\n description:\n 'Enable features to maximise compatibility with templates built for fetch:cookiecutter',\n type: 'boolean',\n },\n templateFileExtension: {\n title: 'Template File Extension',\n description:\n 'If set, only files with the given extension will be templated. If set to `true`, the default extension `.njk` is used.',\n type: ['string', 'boolean'],\n },\n },\n },\n },\n async handler(ctx) {\n ctx.logger.info('Fetching template content from remote URL');\n\n const workDir = await ctx.createTemporaryDirectory();\n const templateDir = resolveSafeChildPath(workDir, 'template');\n\n const targetPath = ctx.input.targetPath ?? './';\n const outputDir = resolveSafeChildPath(ctx.workspacePath, targetPath);\n\n if (\n ctx.input.copyWithoutRender &&\n !Array.isArray(ctx.input.copyWithoutRender)\n ) {\n throw new InputError(\n 'Fetch action input copyWithoutRender must be an Array',\n );\n }\n\n if (\n ctx.input.templateFileExtension &&\n (ctx.input.copyWithoutRender || ctx.input.cookiecutterCompat)\n ) {\n throw new InputError(\n 'Fetch action input extension incompatible with copyWithoutRender and cookiecutterCompat',\n );\n }\n\n let extension: string | false = false;\n if (ctx.input.templateFileExtension) {\n extension =\n ctx.input.templateFileExtension === true\n ? '.njk'\n : ctx.input.templateFileExtension;\n if (!extension.startsWith('.')) {\n extension = `.${extension}`;\n }\n }\n\n await fetchContents({\n reader,\n integrations,\n baseUrl: ctx.templateInfo?.baseUrl,\n fetchUrl: ctx.input.url,\n outputPath: templateDir,\n });\n\n ctx.logger.info('Listing files and directories in template');\n const allEntriesInTemplate = await globby(`**/*`, {\n cwd: templateDir,\n dot: true,\n onlyFiles: false,\n markDirectories: true,\n });\n\n const nonTemplatedEntries = new Set(\n (\n await Promise.all(\n (ctx.input.copyWithoutRender || []).map(pattern =>\n globby(pattern, {\n cwd: templateDir,\n dot: true,\n onlyFiles: false,\n markDirectories: true,\n }),\n ),\n )\n ).flat(),\n );\n\n // Cookiecutter prefixes all parameters in templates with\n // `cookiecutter.`. To replicate this, we wrap our parameters\n // in an object with a `cookiecutter` property when compat\n // mode is enabled.\n const { cookiecutterCompat, values } = ctx.input;\n const context = {\n [cookiecutterCompat ? 'cookiecutter' : 'values']: values,\n };\n\n ctx.logger.info(\n `Processing ${allEntriesInTemplate.length} template files/directories with input values`,\n ctx.input.values,\n );\n\n const renderTemplate = await SecureTemplater.loadRenderer({\n cookiecutterCompat: ctx.input.cookiecutterCompat,\n additionalTemplateFilters,\n });\n\n for (const location of allEntriesInTemplate) {\n let renderFilename: boolean;\n let renderContents: boolean;\n\n let localOutputPath = location;\n if (extension) {\n renderFilename = true;\n renderContents = extname(localOutputPath) === extension;\n if (renderContents) {\n localOutputPath = localOutputPath.slice(0, -extension.length);\n }\n } else {\n renderFilename = renderContents = !nonTemplatedEntries.has(location);\n }\n if (renderFilename) {\n localOutputPath = renderTemplate(localOutputPath, context);\n }\n const outputPath = resolveSafeChildPath(outputDir, localOutputPath);\n // variables have been expanded to make an empty file name\n // this is due to a conditional like if values.my_condition then file-name.txt else empty string so skip\n if (outputDir === outputPath) {\n continue;\n }\n\n if (!renderContents && !extension) {\n ctx.logger.info(\n `Copying file/directory ${location} without processing.`,\n );\n }\n\n if (location.endsWith('/')) {\n ctx.logger.info(\n `Writing directory ${location} to template output path.`,\n );\n await fs.ensureDir(outputPath);\n } else {\n const inputFilePath = resolveSafeChildPath(templateDir, location);\n\n if (await isBinaryFile(inputFilePath)) {\n ctx.logger.info(\n `Copying binary file ${location} to template output path.`,\n );\n await fs.copy(inputFilePath, outputPath);\n } else {\n const statsObj = await fs.stat(inputFilePath);\n ctx.logger.info(\n `Writing file ${location} to template output path with mode ${statsObj.mode}.`,\n );\n const inputFileContents = await fs.readFile(inputFilePath, 'utf-8');\n await fs.outputFile(\n outputPath,\n renderContents\n ? renderTemplate(inputFileContents, context)\n : inputFileContents,\n { mode: statsObj.mode },\n );\n }\n }\n }\n\n ctx.logger.info(`Template result written to ${outputDir}`);\n },\n });\n}\n","/*\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 */\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { InputError } from '@backstage/errors';\nimport { resolveSafeChildPath } from '@backstage/backend-common';\nimport fs from 'fs-extra';\n\n/**\n * Creates new action that enables deletion of files and directories in the workspace.\n * @public\n */\nexport const createFilesystemDeleteAction = () => {\n return createTemplateAction<{ files: string[] }>({\n id: 'fs:delete',\n description: 'Deletes files and directories from the workspace',\n schema: {\n input: {\n required: ['files'],\n type: 'object',\n properties: {\n files: {\n title: 'Files',\n description: 'A list of files and directories that will be deleted',\n type: 'array',\n items: {\n type: 'string',\n },\n },\n },\n },\n },\n async handler(ctx) {\n if (!Array.isArray(ctx.input?.files)) {\n throw new InputError('files must be an Array');\n }\n\n for (const file of ctx.input.files) {\n const filepath = resolveSafeChildPath(ctx.workspacePath, file);\n\n try {\n await fs.remove(filepath);\n ctx.logger.info(`File ${filepath} deleted successfully`);\n } catch (err) {\n ctx.logger.error(`Failed to delete file ${filepath}:`, err);\n throw err;\n }\n }\n },\n });\n};\n","/*\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 */\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { resolveSafeChildPath } from '@backstage/backend-common';\n\nimport { InputError } from '@backstage/errors';\nimport fs from 'fs-extra';\n\n/**\n * Creates a new action that allows renames of files and directories in the workspace.\n * @public\n */\nexport const createFilesystemRenameAction = () => {\n return createTemplateAction<{\n files: Array<{\n from: string;\n to: string;\n overwrite?: boolean;\n }>;\n }>({\n id: 'fs:rename',\n description: 'Renames files and directories within the workspace',\n schema: {\n input: {\n required: ['files'],\n type: 'object',\n properties: {\n files: {\n title: 'Files',\n description:\n 'A list of file and directory names that will be renamed',\n type: 'array',\n items: {\n type: 'object',\n required: ['from', 'to'],\n properties: {\n from: {\n type: 'string',\n title: 'The source location of the file to be renamed',\n },\n to: {\n type: 'string',\n title: 'The destination of the new file',\n },\n overwrite: {\n type: 'boolean',\n title:\n 'Overwrite existing file or directory, default is false',\n },\n },\n },\n },\n },\n },\n },\n async handler(ctx) {\n if (!Array.isArray(ctx.input?.files)) {\n throw new InputError('files must be an Array');\n }\n\n for (const file of ctx.input.files) {\n if (!file.from || !file.to) {\n throw new InputError('each file must have a from and to property');\n }\n\n const sourceFilepath = resolveSafeChildPath(\n ctx.workspacePath,\n file.from,\n );\n const destFilepath = resolveSafeChildPath(ctx.workspacePath, file.to);\n\n try {\n await fs.move(sourceFilepath, destFilepath, {\n overwrite: file.overwrite ?? false,\n });\n ctx.logger.info(\n `File ${sourceFilepath} renamed to ${destFilepath} successfully`,\n );\n } catch (err) {\n ctx.logger.error(\n `Failed to rename file ${sourceFilepath} to ${destFilepath}:`,\n err,\n );\n throw err;\n }\n }\n },\n });\n};\n","/*\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 { SpawnOptionsWithoutStdio, spawn } from 'child_process';\nimport { PassThrough, Writable } from 'stream';\nimport { Logger } from 'winston';\nimport { Git } from '@backstage/backend-common';\nimport { Octokit } from 'octokit';\nimport { assertError } from '@backstage/errors';\n\n/** @public */\nexport type RunCommandOptions = {\n /** command to run */\n command: string;\n /** arguments to pass the command */\n args: string[];\n /** options to pass to spawn */\n options?: SpawnOptionsWithoutStdio;\n /** stream to capture stdout and stderr output */\n logStream?: Writable;\n};\n\n/**\n * Run a command in a sub-process, normally a shell command.\n *\n * @public\n */\nexport const executeShellCommand = async (options: RunCommandOptions) => {\n const {\n command,\n args,\n options: spawnOptions,\n logStream = new PassThrough(),\n } = options;\n await new Promise<void>((resolve, reject) => {\n const process = spawn(command, args, spawnOptions);\n\n process.stdout.on('data', stream => {\n logStream.write(stream);\n });\n\n process.stderr.on('data', stream => {\n logStream.write(stream);\n });\n\n process.on('error', error => {\n return reject(error);\n });\n\n process.on('close', code => {\n if (code !== 0) {\n return reject(\n new Error(`Command ${command} failed, exit code: ${code}`),\n );\n }\n return resolve();\n });\n });\n};\n\nexport async function initRepoAndPush({\n dir,\n remoteUrl,\n auth,\n logger,\n defaultBranch = 'master',\n commitMessage = 'Initial commit',\n gitAuthorInfo,\n}: {\n dir: string;\n remoteUrl: string;\n auth: { username: string; password: string };\n logger: Logger;\n defaultBranch?: string;\n commitMessage?: string;\n gitAuthorInfo?: { name?: string; email?: string };\n}): Promise<void> {\n const git = Git.fromAuth({\n username: auth.username,\n password: auth.password,\n logger,\n });\n\n await git.init({\n dir,\n defaultBranch,\n });\n\n await git.add({ dir, filepath: '.' });\n\n // use provided info if possible, otherwise use fallbacks\n const authorInfo = {\n name: gitAuthorInfo?.name ?? 'Scaffolder',\n email: gitAuthorInfo?.email ?? 'scaffolder@backstage.io',\n };\n\n await git.commit({\n dir,\n message: commitMessage,\n author: authorInfo,\n committer: authorInfo,\n });\n\n await git.addRemote({\n dir,\n url: remoteUrl,\n remote: 'origin',\n });\n\n await git.push({\n dir,\n remote: 'origin',\n });\n}\n\ntype BranchProtectionOptions = {\n client: Octokit;\n owner: string;\n repoName: string;\n logger: Logger;\n requireCodeOwnerReviews: boolean;\n defaultBranch?: string;\n};\n\nexport const enableBranchProtectionOnDefaultRepoBranch = async ({\n repoName,\n client,\n owner,\n logger,\n requireCodeOwnerReviews,\n defaultBranch = 'master',\n}: BranchProtectionOptions): Promise<void> => {\n const tryOnce = async () => {\n try {\n await client.rest.repos.updateBranchProtection({\n mediaType: {\n /**\n * 👇 we need this preview because allowing a custom\n * reviewer count on branch protection is a preview\n * feature\n *\n * More here: https://docs.github.com/en/rest/overview/api-previews#require-multiple-approving-reviews\n */\n previews: ['luke-cage-preview'],\n },\n owner,\n repo: repoName,\n branch: defaultBranch,\n required_status_checks: { strict: true, contexts: [] },\n restrictions: null,\n enforce_admins: true,\n required_pull_request_reviews: {\n required_approving_review_count: 1,\n require_code_owner_reviews: requireCodeOwnerReviews,\n },\n });\n } catch (e) {\n assertError(e);\n if (\n e.message.includes(\n 'Upgrade to GitHub Pro or make this repository public to enable this feature',\n )\n ) {\n logger.warn(\n 'Branch protection was not enabled as it requires GitHub Pro for private repositories',\n );\n } else {\n throw e;\n }\n }\n };\n\n try {\n await tryOnce();\n } catch (e) {\n if (!e.message.includes('Branch not found')) {\n throw e;\n }\n\n // GitHub has eventual consistency. Fail silently, wait, and try again.\n await new Promise(resolve => setTimeout(resolve, 600));\n await tryOnce();\n }\n};\n","/*\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 { InputError } from '@backstage/errors';\nimport { isChildPath } from '@backstage/backend-common';\nimport { join as joinPath, normalize as normalizePath } from 'path';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\n\nexport const getRepoSourceDirectory = (\n workspacePath: string,\n sourcePath: string | undefined,\n) => {\n if (sourcePath) {\n const safeSuffix = normalizePath(sourcePath).replace(\n /^(\\.\\.(\\/|\\\\|$))+/,\n '',\n );\n const path = joinPath(workspacePath, safeSuffix);\n if (!isChildPath(workspacePath, path)) {\n throw new Error('Invalid source path');\n }\n return path;\n }\n return workspacePath;\n};\nexport type RepoSpec = {\n repo: string;\n host: string;\n owner?: string;\n organization?: string;\n workspace?: string;\n project?: string;\n};\n\nexport const parseRepoUrl = (\n repoUrl: string,\n integrations: ScmIntegrationRegistry,\n): RepoSpec => {\n let parsed;\n try {\n parsed = new URL(`https://${repoUrl}`);\n } catch (error) {\n throw new InputError(\n `Invalid repo URL passed to publisher, got ${repoUrl}, ${error}`,\n );\n }\n const host = parsed.host;\n const owner = parsed.searchParams.get('owner') ?? undefined;\n const organization = parsed.searchParams.get('organization') ?? undefined;\n const workspace = parsed.searchParams.get('workspace') ?? undefined;\n const project = parsed.searchParams.get('project') ?? undefined;\n\n const type = integrations.byHost(host)?.type;\n\n if (!type) {\n throw new InputError(\n `No matching integration configuration for host ${host}, please check your integrations config`,\n );\n }\n\n if (type === 'bitbucket') {\n if (host === 'bitbucket.org') {\n if (!workspace) {\n throw new InputError(\n `Invalid repo URL passed to publisher: ${repoUrl}, missing workspace`,\n );\n }\n }\n if (!project) {\n throw new InputError(\n `Invalid repo URL passed to publisher: ${repoUrl}, missing project`,\n );\n }\n } else {\n if (!owner) {\n throw new InputError(\n `Invalid repo URL passed to publisher: ${repoUrl}, missing owner`,\n );\n }\n }\n\n const repo = parsed.searchParams.get('repo');\n if (!repo) {\n throw new InputError(\n `Invalid repo URL passed to publisher: ${repoUrl}, missing repo`,\n );\n }\n\n return { host, owner, repo, organization, workspace, project };\n};\nexport const isExecutable = (fileMode: number) => {\n const executeBitMask = 0o000111;\n const res = fileMode & executeBitMask;\n return res > 0;\n};\n","/*\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 { InputError } from '@backstage/errors';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { initRepoAndPush } from '../helpers';\nimport { GitRepositoryCreateOptions } from 'azure-devops-node-api/interfaces/GitInterfaces';\nimport { getPersonalAccessTokenHandler, WebApi } from 'azure-devops-node-api';\nimport { getRepoSourceDirectory, parseRepoUrl } from './util';\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { Config } from '@backstage/config';\n\n/**\n * Creates a new action that initializes a git repository of the content in the workspace\n * and publishes it to Azure.\n * @public\n */\nexport function createPublishAzureAction(options: {\n integrations: ScmIntegrationRegistry;\n config: Config;\n}) {\n const { integrations, config } = options;\n\n return createTemplateAction<{\n repoUrl: string;\n description?: string;\n defaultBranch?: string;\n sourcePath?: string;\n token?: string;\n }>({\n id: 'publish:azure',\n description:\n 'Initializes a git repository of the content in the workspace, and publishes it to Azure.',\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n type: 'string',\n },\n description: {\n title: 'Repository Description',\n type: 'string',\n },\n defaultBranch: {\n title: 'Default Branch',\n type: 'string',\n description: `Sets the default branch on the repository. The default value is 'master'`,\n },\n sourcePath: {\n title: 'Source Path',\n description:\n 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.',\n type: 'string',\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The token to use for authorization to Azure',\n },\n },\n },\n output: {\n type: 'object',\n properties: {\n remoteUrl: {\n title: 'A URL to the repository with the provider',\n type: 'string',\n },\n repoContentsUrl: {\n title: 'A URL to the root of the repository',\n type: 'string',\n },\n },\n },\n },\n async handler(ctx) {\n const { repoUrl, defaultBranch = 'master' } = ctx.input;\n\n const { owner, repo, host, organization } = parseRepoUrl(\n repoUrl,\n integrations,\n );\n\n if (!organization) {\n throw new InputError(\n `Invalid URL provider was included in the repo URL to create ${ctx.input.repoUrl}, missing organization`,\n );\n }\n\n const integrationConfig = integrations.azure.byHost(host);\n\n if (!integrationConfig) {\n throw new InputError(\n `No matching integration configuration for host ${host}, please check your integrations config`,\n );\n }\n\n if (!integrationConfig.config.token && !ctx.input.token) {\n throw new InputError(`No token provided for Azure Integration ${host}`);\n }\n\n const token = ctx.input.token ?? integrationConfig.config.token!;\n const authHandler = getPersonalAccessTokenHandler(token);\n\n const webApi = new WebApi(`https://${host}/${organization}`, authHandler);\n const client = await webApi.getGitApi();\n const createOptions: GitRepositoryCreateOptions = { name: repo };\n const returnedRepo = await client.createRepository(createOptions, owner);\n\n if (!returnedRepo) {\n throw new InputError(\n `Unable to create the repository with Organization ${organization}, Project ${owner} and Repo ${repo}.\n Please make sure that both the Org and Project are typed corrected and exist.`,\n );\n }\n const remoteUrl = returnedRepo.remoteUrl;\n\n if (!remoteUrl) {\n throw new InputError(\n 'No remote URL returned from create repository for Azure',\n );\n }\n\n // blam: Repo contents is serialized into the path,\n // so it's just the base path I think\n const repoContentsUrl = remoteUrl;\n\n const gitAuthorInfo = {\n name: config.getOptionalString('scaffolder.defaultAuthor.name'),\n email: config.getOptionalString('scaffolder.defaultAuthor.email'),\n };\n\n await initRepoAndPush({\n dir: getRepoSourceDirectory(ctx.workspacePath, ctx.input.sourcePath),\n remoteUrl,\n defaultBranch,\n auth: {\n username: 'notempty',\n password: token,\n },\n logger: ctx.logger,\n commitMessage: config.getOptionalString(\n 'scaffolder.defaultCommitMessage',\n ),\n gitAuthorInfo,\n });\n\n ctx.output('remoteUrl', remoteUrl);\n ctx.output('repoContentsUrl', repoContentsUrl);\n },\n });\n}\n","/*\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 { InputError } from '@backstage/errors';\nimport {\n BitbucketIntegrationConfig,\n ScmIntegrationRegistry,\n} from '@backstage/integration';\nimport fetch, { Response, RequestInit } from 'node-fetch';\nimport { initRepoAndPush } from '../helpers';\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { getRepoSourceDirectory, parseRepoUrl } from './util';\nimport { Config } from '@backstage/config';\n\nconst createBitbucketCloudRepository = async (opts: {\n workspace: string;\n project: string;\n repo: string;\n description?: string;\n repoVisibility: 'private' | 'public';\n mainBranch: string;\n authorization: string;\n apiBaseUrl: string;\n}) => {\n const {\n workspace,\n project,\n repo,\n description,\n repoVisibility,\n mainBranch,\n authorization,\n apiBaseUrl,\n } = opts;\n\n const options: RequestInit = {\n method: 'POST',\n body: JSON.stringify({\n scm: 'git',\n description: description,\n is_private: repoVisibility === 'private',\n project: { key: project },\n }),\n headers: {\n Authorization: authorization,\n 'Content-Type': 'application/json',\n },\n };\n\n let response: Response;\n try {\n response = await fetch(\n `${apiBaseUrl}/repositories/${workspace}/${repo}`,\n options,\n );\n } catch (e) {\n throw new Error(`Unable to create repository, ${e}`);\n }\n\n if (response.status !== 200) {\n throw new Error(\n `Unable to create repository, ${response.status} ${\n response.statusText\n }, ${await response.text()}`,\n );\n }\n\n const r = await response.json();\n let remoteUrl = '';\n for (const link of r.links.clone) {\n if (link.name === 'https') {\n remoteUrl = link.href;\n }\n }\n\n // \"mainbranch.name\" cannot be set neither at create nor update of the repo\n // the first pushed branch will be set as \"main branch\" then\n const repoContentsUrl = `${r.links.html.href}/src/${mainBranch}`;\n return { remoteUrl, repoContentsUrl };\n};\n\nconst createBitbucketServerRepository = async (opts: {\n project: string;\n repo: string;\n description?: string;\n repoVisibility: 'private' | 'public';\n authorization: string;\n apiBaseUrl: string;\n}) => {\n const {\n project,\n repo,\n description,\n authorization,\n repoVisibility,\n apiBaseUrl,\n } = opts;\n\n let response: Response;\n const options: RequestInit = {\n method: 'POST',\n body: JSON.stringify({\n name: repo,\n description: description,\n public: repoVisibility === 'public',\n }),\n headers: {\n Authorization: authorization,\n 'Content-Type': 'application/json',\n },\n };\n\n try {\n response = await fetch(`${apiBaseUrl}/projects/${project}/repos`, options);\n } catch (e) {\n throw new Error(`Unable to create repository, ${e}`);\n }\n\n if (response.status !== 201) {\n throw new Error(\n `Unable to create repository, ${response.status} ${\n response.statusText\n }, ${await response.text()}`,\n );\n }\n\n const r = await response.json();\n let remoteUrl = '';\n for (const link of r.links.clone) {\n if (link.name === 'http') {\n remoteUrl = link.href;\n }\n }\n\n const repoContentsUrl = `${r.links.self[0].href}`;\n return { remoteUrl, repoContentsUrl };\n};\n\nconst getAuthorizationHeader = (config: BitbucketIntegrationConfig) => {\n if (config.username && config.appPassword) {\n const buffer = Buffer.from(\n `${config.username}:${config.appPassword}`,\n 'utf8',\n );\n\n return `Basic ${buffer.toString('base64')}`;\n }\n\n if (config.token) {\n return `Bearer ${config.token}`;\n }\n\n throw new Error(\n `Authorization has not been provided for Bitbucket. Please add either username + appPassword or token to the Integrations config`,\n );\n};\n\nconst performEnableLFS = async (opts: {\n authorization: string;\n host: string;\n project: string;\n repo: string;\n}) => {\n const { authorization, host, project, repo } = opts;\n\n const options: RequestInit = {\n method: 'PUT',\n headers: {\n Authorization: authorization,\n },\n };\n\n const { ok, status, statusText } = await fetch(\n `https://${host}/rest/git-lfs/admin/projects/${project}/repos/${repo}/enabled`,\n options,\n );\n\n if (!ok)\n throw new Error(\n `Failed to enable LFS in the repository, ${status}: ${statusText}`,\n );\n};\n\n/**\n * Creates a new action that initializes a git repository of the content in the workspace\n * and publishes it to Bitbucket.\n * @public\n */\nexport function createPublishBitbucketAction(options: {\n integrations: ScmIntegrationRegistry;\n config: Config;\n}) {\n const { integrations, config } = options;\n\n return createTemplateAction<{\n repoUrl: string;\n description?: string;\n defaultBranch?: string;\n repoVisibility?: 'private' | 'public';\n sourcePath?: string;\n enableLFS?: boolean;\n token?: string;\n }>({\n id: 'publish:bitbucket',\n description:\n 'Initializes a git repository of the content in the workspace, and publishes it to Bitbucket.',\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n type: 'string',\n },\n description: {\n title: 'Repository Description',\n type: 'string',\n },\n repoVisibility: {\n title: 'Repository Visibility',\n type: 'string',\n enum: ['private', 'public'],\n },\n defaultBranch: {\n title: 'Default Branch',\n type: 'string',\n description: `Sets the default branch on the repository. The default value is 'master'`,\n },\n sourcePath: {\n title: 'Source Path',\n description:\n 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.',\n type: 'string',\n },\n enableLFS: {\n title: 'Enable LFS?',\n description:\n 'Enable LFS for the repository. Only available for hosted Bitbucket.',\n type: 'boolean',\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The token to use for authorization to BitBucket',\n },\n },\n },\n output: {\n type: 'object',\n properties: {\n remoteUrl: {\n title: 'A URL to the repository with the provider',\n type: 'string',\n },\n repoContentsUrl: {\n title: 'A URL to the root of the repository',\n type: 'string',\n },\n },\n },\n },\n async handler(ctx) {\n const {\n repoUrl,\n description,\n defaultBranch = 'master',\n repoVisibility = 'private',\n enableLFS = false,\n } = ctx.input;\n\n const { workspace, project, repo, host } = parseRepoUrl(\n repoUrl,\n integrations,\n );\n\n // Workspace is only required for bitbucket cloud\n if (host === 'bitbucket.org') {\n if (!workspace) {\n throw new InputError(\n `Invalid URL provider was included in the repo URL to create ${ctx.input.repoUrl}, missing workspace`,\n );\n }\n }\n\n // Project is required for both bitbucket cloud and bitbucket server\n if (!project) {\n throw new InputError(\n `Invalid URL provider was included in the repo URL to create ${ctx.input.repoUrl}, missing project`,\n );\n }\n\n const integrationConfig = integrations.bitbucket.byHost(host);\n\n if (!integrationConfig) {\n throw new InputError(\n `No matching integration configuration for host ${host}, please check your integrations config`,\n );\n }\n\n const authorization = getAuthorizationHeader(\n ctx.input.token\n ? {\n host: integrationConfig.config.host,\n apiBaseUrl: integrationConfig.config.apiBaseUrl,\n token: ctx.input.token,\n }\n : integrationConfig.config,\n );\n\n const apiBaseUrl = integrationConfig.config.apiBaseUrl;\n\n const createMethod =\n host === 'bitbucket.org'\n ? createBitbucketCloudRepository\n : createBitbucketServerRepository;\n\n const { remoteUrl, repoContentsUrl } = await createMethod({\n authorization,\n workspace: workspace || '',\n project,\n repo,\n repoVisibility,\n mainBranch: defaultBranch,\n description,\n apiBaseUrl,\n });\n\n const gitAuthorInfo = {\n name: config.getOptionalString('scaffolder.defaultAuthor.name'),\n email: config.getOptionalString('scaffolder.defaultAuthor.email'),\n };\n\n let auth;\n\n if (ctx.input.token) {\n auth = {\n username: 'x-token-auth',\n password: ctx.input.token,\n };\n } else {\n auth = {\n username: integrationConfig.config.username\n ? integrationConfig.config.username\n : 'x-token-auth',\n password: integrationConfig.config.appPassword\n ? integrationConfig.config.appPassword\n : integrationConfig.config.token ?? '',\n };\n }\n\n await initRepoAndPush({\n dir: getRepoSourceDirectory(ctx.workspacePath, ctx.input.sourcePath),\n remoteUrl,\n auth,\n defaultBranch,\n logger: ctx.logger,\n commitMessage: config.getOptionalString(\n 'scaffolder.defaultCommitMessage',\n ),\n gitAuthorInfo,\n });\n\n if (enableLFS && host !== 'bitbucket.org') {\n await performEnableLFS({ authorization, host, project, repo });\n }\n\n ctx.output('remoteUrl', remoteUrl);\n ctx.output('repoContentsUrl', repoContentsUrl);\n },\n });\n}\n","/*\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 fs from 'fs-extra';\nimport { dirname } from 'path';\nimport { InputError } from '@backstage/errors';\nimport { createTemplateAction } from '../../createTemplateAction';\n\n/**\n * This task is useful for local development and testing of both the scaffolder\n * and scaffolder templates.\n *\n * @remarks\n *\n * This action is not installed by default and should not be installed in\n * production, as it writes the files to the local filesystem of the scaffolder.\n *\n * @public\n */\nexport function createPublishFileAction() {\n return createTemplateAction<{ path: string }>({\n id: 'publish:file',\n description: 'Writes contents of the workspace to a local directory',\n schema: {\n input: {\n type: 'object',\n required: ['path'],\n properties: {\n path: {\n title: 'Path to a directory where the output will be written',\n type: 'string',\n },\n },\n },\n },\n async handler(ctx) {\n const { path } = ctx.input;\n\n const exists = await fs.pathExists(path);\n if (exists) {\n throw new InputError('Output path already exists');\n }\n await fs.ensureDir(dirname(path));\n await fs.copy(ctx.workspacePath, path);\n },\n });\n}\n","/*\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 */\nimport { InputError } from '@backstage/errors';\nimport {\n DefaultGithubCredentialsProvider,\n GithubCredentialsProvider,\n ScmIntegrationRegistry,\n} from '@backstage/integration';\nimport { OctokitOptions } from '@octokit/core/dist-types/types';\nimport { parseRepoUrl } from '../publish/util';\n\nconst DEFAULT_TIMEOUT_MS = 60_000;\n\nexport async function getOctokitOptions(options: {\n integrations: ScmIntegrationRegistry;\n credentialsProvider?: GithubCredentialsProvider;\n token?: string;\n repoUrl: string;\n}): Promise<OctokitOptions> {\n const { integrations, credentialsProvider, repoUrl, token } = options;\n const { owner, repo, host } = parseRepoUrl(repoUrl, integrations);\n\n const requestOptions = {\n // set timeout to 60 seconds\n timeout: DEFAULT_TIMEOUT_MS,\n };\n\n if (!owner) {\n throw new InputError(`No owner provided for repo ${repoUrl}`);\n }\n\n const integrationConfig = integrations.github.byHost(host)?.config;\n\n if (!integrationConfig) {\n throw new InputError(`No integration for host ${host}`);\n }\n\n // short circuit the `githubCredentialsProvider` if there is a token provided by the caller already\n if (token) {\n return {\n auth: token,\n baseUrl: integrationConfig.apiBaseUrl,\n previews: ['nebula-preview'],\n request: requestOptions,\n };\n }\n\n const githubCredentialsProvider =\n credentialsProvider ??\n DefaultGithubCredentialsProvider.fromIntegrations(integrations);\n\n // TODO(blam): Consider changing this API to take host and repo instead of repoUrl, as we end up parsing in this function\n // and then parsing in the `getCredentials` function too the other side\n const { token: credentialProviderToken } =\n await githubCredentialsProvider.getCredentials({\n url: `https://${host}/${encodeURIComponent(owner)}/${encodeURIComponent(\n repo,\n )}`,\n });\n\n if (!credentialProviderToken) {\n throw new InputError(\n `No token available for host: ${host}, with owner ${owner}, and repo ${repo}`,\n );\n }\n\n return {\n auth: credentialProviderToken,\n baseUrl: integrationConfig.apiBaseUrl,\n previews: ['nebula-preview'],\n };\n}\n","/*\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 */\nimport {\n GithubCredentialsProvider,\n ScmIntegrationRegistry,\n} from '@backstage/integration';\nimport {\n enableBranchProtectionOnDefaultRepoBranch,\n initRepoAndPush,\n} from '../helpers';\nimport { getRepoSourceDirectory, parseRepoUrl } from './util';\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { Config } from '@backstage/config';\nimport { assertError, InputError } from '@backstage/errors';\nimport { getOctokitOptions } from '../github/helpers';\nimport { Octokit } from 'octokit';\n\n/**\n * Creates a new action that initializes a git repository of the content in the workspace\n * and publishes it to GitHub.\n *\n * @public\n */\nexport function createPublishGithubAction(options: {\n integrations: ScmIntegrationRegistry;\n config: Config;\n githubCredentialsProvider?: GithubCredentialsProvider;\n}) {\n const { integrations, config, githubCredentialsProvider } = options;\n\n return createTemplateAction<{\n repoUrl: string;\n description?: string;\n access?: string;\n defaultBranch?: string;\n deleteBranchOnMerge?: boolean;\n allowRebaseMerge?: boolean;\n allowSquashMerge?: boolean;\n allowMergeCommit?: boolean;\n sourcePath?: string;\n requireCodeOwnerReviews?: boolean;\n repoVisibility?: 'private' | 'internal' | 'public';\n collaborators?: Array<{\n username: string;\n access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage';\n }>;\n token?: string;\n topics?: string[];\n }>({\n id: 'publish:github',\n description:\n 'Initializes a git repository of contents in workspace and publishes it to GitHub.',\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the new repository name and 'owner' is an organization or username`,\n type: 'string',\n },\n description: {\n title: 'Repository Description',\n type: 'string',\n },\n access: {\n title: 'Repository Access',\n description: `Sets an admin collaborator on the repository. Can either be a user reference different from 'owner' in 'repoUrl' or team reference, eg. 'org/team-name'`,\n type: 'string',\n },\n requireCodeOwnerReviews: {\n title: 'Require CODEOWNER Reviews?',\n description:\n 'Require an approved review in PR including files with a designated Code Owner',\n type: 'boolean',\n },\n repoVisibility: {\n title: 'Repository Visibility',\n type: 'string',\n enum: ['private', 'public', 'internal'],\n },\n defaultBranch: {\n title: 'Default Branch',\n type: 'string',\n description: `Sets the default branch on the repository. The default value is 'master'`,\n },\n deleteBranchOnMerge: {\n title: 'Delete Branch On Merge',\n type: 'boolean',\n description: `Delete the branch after merging the PR. The default value is 'false'`,\n },\n allowMergeCommit: {\n title: 'Allow Merge Commits',\n type: 'boolean',\n description: `Allow merge commits. The default value is 'true'`,\n },\n allowSquashMerge: {\n title: 'Allow Squash Merges',\n type: 'boolean',\n description: `Allow squash merges. The default value is 'true'`,\n },\n allowRebaseMerge: {\n title: 'Allow Rebase Merges',\n type: 'boolean',\n description: `Allow rebase merges. The default value is 'true'`,\n },\n sourcePath: {\n title: 'Source Path',\n description:\n 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.',\n type: 'string',\n },\n collaborators: {\n title: 'Collaborators',\n description: 'Provide additional users with permissions',\n type: 'array',\n items: {\n type: 'object',\n required: ['username', 'access'],\n properties: {\n access: {\n type: 'string',\n description: 'The type of access for the user',\n enum: ['push', 'pull', 'admin', 'maintain', 'triage'],\n },\n username: {\n type: 'string',\n description: 'The username or group',\n },\n },\n },\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The token to use for authorization to GitHub',\n },\n topics: {\n title: 'Topics',\n type: 'array',\n items: {\n type: 'string',\n },\n },\n },\n },\n output: {\n type: 'object',\n properties: {\n remoteUrl: {\n title: 'A URL to the repository with the provider',\n type: 'string',\n },\n repoContentsUrl: {\n title: 'A URL to the root of the repository',\n type: 'string',\n },\n },\n },\n },\n async handler(ctx) {\n const {\n repoUrl,\n description,\n access,\n requireCodeOwnerReviews = false,\n repoVisibility = 'private',\n defaultBranch = 'master',\n deleteBranchOnMerge = false,\n allowMergeCommit = true,\n allowSquashMerge = true,\n allowRebaseMerge = true,\n collaborators,\n topics,\n token: providedToken,\n } = ctx.input;\n\n const { owner, repo } = parseRepoUrl(repoUrl, integrations);\n\n if (!owner) {\n throw new InputError('Invalid repository owner provided in repoUrl');\n }\n\n const octokitOptions = await getOctokitOptions({\n integrations,\n credentialsProvider: githubCredentialsProvider,\n token: providedToken,\n repoUrl,\n });\n\n const client = new Octokit(octokitOptions);\n\n const user = await client.rest.users.getByUsername({\n username: owner,\n });\n\n const repoCreationPromise =\n user.data.type === 'Organization'\n ? client.rest.repos.createInOrg({\n name: repo,\n org: owner,\n private: repoVisibility === 'private',\n visibility: repoVisibility,\n description: description,\n delete_branch_on_merge: deleteBranchOnMerge,\n allow_merge_commit: allowMergeCommit,\n allow_squash_merge: allowSquashMerge,\n allow_rebase_merge: allowRebaseMerge,\n })\n : client.rest.repos.createForAuthenticatedUser({\n name: repo,\n private: repoVisibility === 'private',\n description: description,\n delete_branch_on_merge: deleteBranchOnMerge,\n allow_merge_commit: allowMergeCommit,\n allow_squash_merge: allowSquashMerge,\n allow_rebase_merge: allowRebaseMerge,\n });\n\n const { data: newRepo } = await repoCreationPromise;\n if (access?.startsWith(`${owner}/`)) {\n const [, team] = access.split('/');\n await client.rest.teams.addOrUpdateRepoPermissionsInOrg({\n org: owner,\n team_slug: team,\n owner,\n repo,\n permission: 'admin',\n });\n // No need to add access if it's the person who owns the personal account\n } else if (access && access !== owner) {\n await client.rest.repos.addCollaborator({\n owner,\n repo,\n username: access,\n permission: 'admin',\n });\n }\n\n if (collaborators) {\n for (const {\n access: permission,\n username: team_slug,\n } of collaborators) {\n try {\n await client.rest.teams.addOrUpdateRepoPermissionsInOrg({\n org: owner,\n team_slug,\n owner,\n repo,\n permission,\n });\n } catch (e) {\n assertError(e);\n ctx.logger.warn(\n `Skipping ${permission} access for ${team_slug}, ${e.message}`,\n );\n }\n }\n }\n\n if (topics) {\n try {\n await client.rest.repos.replaceAllTopics({\n owner,\n repo,\n names: topics.map(t => t.toLowerCase()),\n });\n } catch (e) {\n assertError(e);\n ctx.logger.warn(`Skipping topics ${topics.join(' ')}, ${e.message}`);\n }\n }\n\n const remoteUrl = newRepo.clone_url;\n const repoContentsUrl = `${newRepo.html_url}/blob/${defaultBranch}`;\n\n const gitAuthorInfo = {\n name: config.getOptionalString('scaffolder.defaultAuthor.name'),\n email: config.getOptionalString('scaffolder.defaultAuthor.email'),\n };\n\n await initRepoAndPush({\n dir: getRepoSourceDirectory(ctx.workspacePath, ctx.input.sourcePath),\n remoteUrl,\n defaultBranch,\n auth: {\n username: 'x-access-token',\n password: octokitOptions.auth,\n },\n logger: ctx.logger,\n commitMessage: config.getOptionalString(\n 'scaffolder.defaultCommitMessage',\n ),\n gitAuthorInfo,\n });\n\n try {\n await enableBranchProtectionOnDefaultRepoBranch({\n owner,\n client,\n repoName: newRepo.name,\n logger: ctx.logger,\n defaultBranch,\n requireCodeOwnerReviews,\n });\n } catch (e) {\n assertError(e);\n ctx.logger.warn(\n `Skipping: default branch protection on '${newRepo.name}', ${e.message}`,\n );\n }\n\n ctx.output('remoteUrl', remoteUrl);\n ctx.output('repoContentsUrl', repoContentsUrl);\n },\n });\n}\n","/*\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 fs from 'fs-extra';\nimport { parseRepoUrl, isExecutable } from './util';\n\nimport {\n GithubCredentialsProvider,\n ScmIntegrationRegistry,\n} from '@backstage/integration';\nimport { zipObject } from 'lodash';\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { Octokit } from 'octokit';\nimport { InputError, CustomErrorBase } from '@backstage/errors';\nimport { createPullRequest } from 'octokit-plugin-create-pull-request';\nimport globby from 'globby';\nimport { resolveSafeChildPath } from '@backstage/backend-common';\nimport { getOctokitOptions } from '../github/helpers';\n\nexport type Encoding = 'utf-8' | 'base64';\n\nclass GithubResponseError extends CustomErrorBase {}\n\n/** @public */\nexport interface OctokitWithPullRequestPluginClient {\n createPullRequest(options: createPullRequest.Options): Promise<{\n data: { html_url: string };\n } | null>;\n}\n\n/** @public */\nexport type CreateGithubPullRequestClientFactoryInput = {\n integrations: ScmIntegrationRegistry;\n githubCredentialsProvider?: GithubCredentialsProvider;\n host: string;\n owner: string;\n repo: string;\n token?: string;\n};\n\nexport const defaultClientFactory = async ({\n integrations,\n githubCredentialsProvider,\n owner,\n repo,\n host = 'github.com',\n token: providedToken,\n}: CreateGithubPullRequestClientFactoryInput): Promise<OctokitWithPullRequestPluginClient> => {\n const [encodedHost, encodedOwner, encodedRepo] = [host, owner, repo].map(\n encodeURIComponent,\n );\n\n const octokitOptions = await getOctokitOptions({\n integrations,\n credentialsProvider: githubCredentialsProvider,\n repoUrl: `${encodedHost}?owner=${encodedOwner}&repo=${encodedRepo}`,\n token: providedToken,\n });\n\n const OctokitPR = Octokit.plugin(createPullRequest);\n return new OctokitPR(octokitOptions);\n};\n\n/** @public */\nexport interface CreateGithubPullRequestActionOptions {\n integrations: ScmIntegrationRegistry;\n githubCredentialsProvider?: GithubCredentialsProvider;\n clientFactory?: (\n input: CreateGithubPullRequestClientFactoryInput,\n ) => Promise<OctokitWithPullRequestPluginClient>;\n}\n\n/**\n * Creates a Github Pull Request action.\n * @public\n */\nexport const createPublishGithubPullRequestAction = ({\n integrations,\n githubCredentialsProvider,\n clientFactory = defaultClientFactory,\n}: CreateGithubPullRequestActionOptions) => {\n return createTemplateAction<{\n title: string;\n branchName: string;\n description: string;\n repoUrl: string;\n targetPath?: string;\n sourcePath?: string;\n token?: string;\n }>({\n id: 'publish:github:pull-request',\n schema: {\n input: {\n required: ['repoUrl', 'title', 'description', 'branchName'],\n type: 'object',\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the repository name and 'owner' is an organization or username`,\n type: 'string',\n },\n branchName: {\n type: 'string',\n title: 'Branch Name',\n description: 'The name for the branch',\n },\n title: {\n type: 'string',\n title: 'Pull Request Name',\n description: 'The name for the pull request',\n },\n description: {\n type: 'string',\n title: 'Pull Request Description',\n description: 'The description of the pull request',\n },\n sourcePath: {\n type: 'string',\n title: 'Working Subdirectory',\n description:\n 'Subdirectory of working directory to copy changes from',\n },\n targetPath: {\n type: 'string',\n title: 'Repository Subdirectory',\n description: 'Subdirectory of repository to apply changes to',\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The token to use for authorization to GitHub',\n },\n },\n },\n output: {\n required: ['remoteUrl'],\n type: 'object',\n properties: {\n remoteUrl: {\n type: 'string',\n title: 'Pull Request URL',\n description: 'Link to the pull request in Github',\n },\n },\n },\n },\n async handler(ctx) {\n const {\n repoUrl,\n branchName,\n title,\n description,\n targetPath,\n sourcePath,\n token: providedToken,\n } = ctx.input;\n\n const { owner, repo, host } = parseRepoUrl(repoUrl, integrations);\n\n if (!owner) {\n throw new InputError(\n `No owner provided for host: ${host}, and repo ${repo}`,\n );\n }\n\n const client = await clientFactory({\n integrations,\n githubCredentialsProvider,\n host,\n owner,\n repo,\n token: providedToken,\n });\n\n const fileRoot = sourcePath\n ? resolveSafeChildPath(ctx.workspacePath, sourcePath)\n : ctx.workspacePath;\n\n const localFilePaths = await globby(['./**', './**/.*', '!.git'], {\n cwd: fileRoot,\n gitignore: true,\n dot: true,\n });\n\n const fileContents = await Promise.all(\n localFilePaths.map(filePath => {\n const absPath = resolveSafeChildPath(fileRoot, filePath);\n const base64EncodedContent = fs\n .readFileSync(absPath)\n .toString('base64');\n const fileStat = fs.statSync(absPath);\n // See the properties of tree items\n // in https://docs.github.com/en/rest/reference/git#trees\n const githubTreeItemMode = isExecutable(fileStat.mode)\n ? '100755'\n : '100644';\n // Always use base64 encoding to avoid doubling a binary file in size\n // due to interpreting a binary file as utf-8 and sending github\n // the utf-8 encoded content.\n //\n // For example, the original gradle-wrapper.jar is 57.8k in https://github.com/kennethzfeng/pull-request-test/pull/5/files.\n // Its size could be doubled to 98.3K (See https://github.com/kennethzfeng/pull-request-test/pull/4/files)\n const encoding: Encoding = 'base64';\n return {\n encoding: encoding,\n content: base64EncodedContent,\n mode: githubTreeItemMode,\n };\n }),\n );\n\n const repoFilePaths = localFilePaths.map(repoFilePath => {\n return targetPath ? `${targetPath}/${repoFilePath}` : repoFilePath;\n });\n\n const changes = [\n {\n files: zipObject(repoFilePaths, fileContents),\n commit: title,\n },\n ];\n\n try {\n const response = await client.createPullRequest({\n owner,\n repo,\n title,\n changes,\n body: description,\n head: branchName,\n });\n\n if (!response) {\n throw new GithubResponseError('null response from Github');\n }\n\n ctx.output('remoteUrl', response.data.html_url);\n } catch (e) {\n throw new GithubResponseError('Pull request creation failed', e);\n }\n },\n });\n};\n","/*\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 { InputError } from '@backstage/errors';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { Gitlab } from '@gitbeaker/node';\nimport { initRepoAndPush } from '../helpers';\nimport { getRepoSourceDirectory, parseRepoUrl } from './util';\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { Config } from '@backstage/config';\n\n/**\n * Creates a new action that initializes a git repository of the content in the workspace\n * and publishes it to GitLab.\n *\n * @public\n */\nexport function createPublishGitlabAction(options: {\n integrations: ScmIntegrationRegistry;\n config: Config;\n}) {\n const { integrations, config } = options;\n\n return createTemplateAction<{\n repoUrl: string;\n defaultBranch?: string;\n repoVisibility?: 'private' | 'internal' | 'public';\n sourcePath?: string;\n token?: string;\n }>({\n id: 'publish:gitlab',\n description:\n 'Initializes a git repository of the content in the workspace, and publishes it to GitLab.',\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n type: 'string',\n },\n repoVisibility: {\n title: 'Repository Visibility',\n type: 'string',\n enum: ['private', 'public', 'internal'],\n },\n defaultBranch: {\n title: 'Default Branch',\n type: 'string',\n description: `Sets the default branch on the repository. The default value is 'master'`,\n },\n sourcePath: {\n title: 'Source Path',\n description:\n 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.',\n type: 'string',\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The token to use for authorization to GitLab',\n },\n },\n },\n output: {\n type: 'object',\n properties: {\n remoteUrl: {\n title: 'A URL to the repository with the provider',\n type: 'string',\n },\n repoContentsUrl: {\n title: 'A URL to the root of the repository',\n type: 'string',\n },\n },\n },\n },\n async handler(ctx) {\n const {\n repoUrl,\n repoVisibility = 'private',\n defaultBranch = 'master',\n } = ctx.input;\n\n const { owner, repo, host } = parseRepoUrl(repoUrl, integrations);\n\n if (!owner) {\n throw new InputError(\n `No owner provided for host: ${host}, and repo ${repo}`,\n );\n }\n\n const integrationConfig = integrations.gitlab.byHost(host);\n\n if (!integrationConfig) {\n throw new InputError(\n `No matching integration configuration for host ${host}, please check your integrations config`,\n );\n }\n\n if (!integrationConfig.config.token && !ctx.input.token) {\n throw new InputError(`No token available for host ${host}`);\n }\n\n const token = ctx.input.token || integrationConfig.config.token!;\n const tokenType = ctx.input.token ? 'oauthToken' : 'token';\n\n const client = new Gitlab({\n host: integrationConfig.config.baseUrl,\n [tokenType]: token,\n });\n\n let { id: targetNamespace } = (await client.Namespaces.show(owner)) as {\n id: number;\n };\n\n if (!targetNamespace) {\n const { id } = (await client.Users.current()) as {\n id: number;\n };\n targetNamespace = id;\n }\n\n const { http_url_to_repo } = await client.Projects.create({\n namespace_id: targetNamespace,\n name: repo,\n visibility: repoVisibility,\n });\n\n const remoteUrl = (http_url_to_repo as string).replace(/\\.git$/, '');\n const repoContentsUrl = `${remoteUrl}/-/blob/${defaultBranch}`;\n\n const gitAuthorInfo = {\n name: config.getOptionalString('scaffolder.defaultAuthor.name'),\n email: config.getOptionalString('scaffolder.defaultAuthor.email'),\n };\n\n await initRepoAndPush({\n dir: getRepoSourceDirectory(ctx.workspacePath, ctx.input.sourcePath),\n remoteUrl: http_url_to_repo as string,\n defaultBranch,\n auth: {\n username: 'oauth2',\n password: token,\n },\n logger: ctx.logger,\n commitMessage: config.getOptionalString(\n 'scaffolder.defaultCommitMessage',\n ),\n gitAuthorInfo,\n });\n\n ctx.output('remoteUrl', remoteUrl);\n ctx.output('repoContentsUrl', repoContentsUrl);\n },\n });\n}\n","/*\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 */\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { readFile } from 'fs-extra';\nimport { Gitlab } from '@gitbeaker/node';\nimport globby from 'globby';\nimport { Types } from '@gitbeaker/core';\n\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { InputError } from '@backstage/errors';\nimport { parseRepoUrl } from './util';\nimport { resolveSafeChildPath } from '@backstage/backend-common';\n\n/**\n * Create a new action that creates a gitlab merge request.\n *\n * @public\n */\nexport const createPublishGitlabMergeRequestAction = (options: {\n integrations: ScmIntegrationRegistry;\n}) => {\n const { integrations } = options;\n\n return createTemplateAction<{\n projectid: string;\n repoUrl: string;\n title: string;\n description: string;\n branchName: string;\n targetPath: string;\n token?: string;\n }>({\n id: 'publish:gitlab:merge-request',\n schema: {\n input: {\n required: ['projectid', 'repoUrl', 'targetPath', 'branchName'],\n type: 'object',\n properties: {\n repoUrl: {\n type: 'string',\n title: 'Repository Location',\n description: `Accepts the format 'gitlab.com/group_name/project_name' where 'project_name' is the repository name and 'group_name' is a group or username`,\n },\n projectid: {\n type: 'string',\n title: 'projectid',\n description: 'Project ID/Name(slug) of the Gitlab Project',\n },\n title: {\n type: 'string',\n title: 'Merge Request Name',\n description: 'The name for the merge request',\n },\n description: {\n type: 'string',\n title: 'Merge Request Description',\n description: 'The description of the merge request',\n },\n branchName: {\n type: 'string',\n title: 'Destination Branch name',\n description: 'The description of the merge request',\n },\n targetPath: {\n type: 'string',\n title: 'Repository Subdirectory',\n description: 'Subdirectory of repository to apply changes to',\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The token to use for authorization to GitLab',\n },\n },\n },\n output: {\n type: 'object',\n properties: {\n projectid: {\n title: 'Gitlab Project id/Name(slug)',\n type: 'string',\n },\n mergeRequestURL: {\n title: 'MergeRequest(MR) URL',\n type: 'string',\n description: 'Link to the merge request in GitLab',\n },\n },\n },\n },\n async handler(ctx) {\n const repoUrl = ctx.input.repoUrl;\n const { host } = parseRepoUrl(repoUrl, integrations);\n const integrationConfig = integrations.gitlab.byHost(host);\n\n const actions: Types.CommitAction[] = [];\n\n const destinationBranch = ctx.input.branchName;\n\n if (!integrationConfig) {\n throw new InputError(\n `No matching integration configuration for host ${host}, please check your integrations config`,\n );\n }\n\n if (!integrationConfig.config.token && !ctx.input.token) {\n throw new InputError(`No token available for host ${host}`);\n }\n\n const token = ctx.input.token ?? integrationConfig.config.token!;\n const tokenType = ctx.input.token ? 'oauthToken' : 'token';\n\n const api = new Gitlab({\n host: integrationConfig.config.baseUrl,\n [tokenType]: token,\n });\n\n const fileRoot = ctx.workspacePath;\n const localFilePaths = await globby([`${ctx.input.targetPath}/**`], {\n cwd: fileRoot,\n gitignore: true,\n dot: true,\n });\n\n const fileContents = await Promise.all(\n localFilePaths.map(p => readFile(resolveSafeChildPath(fileRoot, p))),\n );\n\n const repoFilePaths = localFilePaths.map(repoFilePath => {\n return repoFilePath;\n });\n\n for (let i = 0; i < repoFilePaths.length; i++) {\n actions.push({\n action: 'create',\n filePath: repoFilePaths[i],\n content: fileContents[i].toString(),\n });\n }\n\n const projects = await api.Projects.show(ctx.input.projectid);\n\n const { default_branch: defaultBranch } = projects;\n\n try {\n await api.Branches.create(\n ctx.input.projectid,\n destinationBranch,\n String(defaultBranch),\n );\n } catch (e) {\n throw new InputError(`The branch creation failed ${e}`);\n }\n\n try {\n await api.Commits.create(\n ctx.input.projectid,\n destinationBranch,\n ctx.input.title,\n actions,\n );\n } catch (e) {\n throw new InputError(\n `Committing the changes to ${destinationBranch} failed ${e}`,\n );\n }\n\n try {\n const mergeRequestUrl = await api.MergeRequests.create(\n ctx.input.projectid,\n destinationBranch,\n String(defaultBranch),\n ctx.input.title,\n { description: ctx.input.description },\n ).then((mergeRequest: { web_url: string }) => {\n return mergeRequest.web_url;\n });\n ctx.output('projectid', ctx.input.projectid);\n ctx.output('mergeRequestUrl', mergeRequestUrl);\n } catch (e) {\n throw new InputError(`Merge request creation failed${e}`);\n }\n },\n });\n};\n","/*\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 */\nimport { InputError } from '@backstage/errors';\nimport {\n GithubCredentialsProvider,\n ScmIntegrations,\n} from '@backstage/integration';\nimport { Octokit } from 'octokit';\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { parseRepoUrl } from '../publish/util';\nimport { getOctokitOptions } from './helpers';\n\n/**\n * Creates a new action that dispatches a GitHub Action workflow for a given branch or tag.\n * @public\n */\nexport function createGithubActionsDispatchAction(options: {\n integrations: ScmIntegrations;\n githubCredentialsProvider?: GithubCredentialsProvider;\n}) {\n const { integrations, githubCredentialsProvider } = options;\n\n return createTemplateAction<{\n repoUrl: string;\n workflowId: string;\n branchOrTagName: string;\n workflowInputs?: { [key: string]: string };\n token?: string;\n }>({\n id: 'github:actions:dispatch',\n description:\n 'Dispatches a GitHub Action workflow for a given branch or tag',\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl', 'workflowId', 'branchOrTagName'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the new repository name and 'owner' is an organization or username`,\n type: 'string',\n },\n workflowId: {\n title: 'Workflow ID',\n description: 'The GitHub Action Workflow filename',\n type: 'string',\n },\n branchOrTagName: {\n title: 'Branch or Tag name',\n description:\n 'The git branch or tag name used to dispatch the workflow',\n type: 'string',\n },\n workflowInputs: {\n title: 'Workflow Inputs',\n description:\n 'Inputs keys and values to send to GitHub Action configured on the workflow file. The maximum number of properties is 10. ',\n type: 'object',\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The GITHUB_TOKEN to use for authorization to GitHub',\n },\n },\n },\n },\n async handler(ctx) {\n const {\n repoUrl,\n workflowId,\n branchOrTagName,\n workflowInputs,\n token: providedToken,\n } = ctx.input;\n\n ctx.logger.info(\n `Dispatching workflow ${workflowId} for repo ${repoUrl} on ${branchOrTagName}`,\n );\n\n const { owner, repo } = parseRepoUrl(repoUrl, integrations);\n\n if (!owner) {\n throw new InputError('Invalid repository owner provided in repoUrl');\n }\n\n const client = new Octokit(\n await getOctokitOptions({\n integrations,\n repoUrl,\n credentialsProvider: githubCredentialsProvider,\n token: providedToken,\n }),\n );\n\n await client.rest.actions.createWorkflowDispatch({\n owner,\n repo,\n workflow_id: workflowId,\n ref: branchOrTagName,\n inputs: workflowInputs,\n });\n\n ctx.logger.info(`Workflow ${workflowId} dispatched successfully`);\n },\n });\n}\n","/*\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 */\nimport {\n GithubCredentialsProvider,\n ScmIntegrationRegistry,\n} from '@backstage/integration';\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { emitterEventNames } from '@octokit/webhooks';\nimport { assertError, InputError } from '@backstage/errors';\nimport { Octokit } from 'octokit';\nimport { getOctokitOptions } from './helpers';\nimport { parseRepoUrl } from '../publish/util';\n\n/**\n * Creates new action that creates a webhook for a repository on GitHub.\n * @public\n */\nexport function createGithubWebhookAction(options: {\n integrations: ScmIntegrationRegistry;\n defaultWebhookSecret?: string;\n githubCredentialsProvider?: GithubCredentialsProvider;\n}) {\n const { integrations, defaultWebhookSecret, githubCredentialsProvider } =\n options;\n\n const eventNames = emitterEventNames.filter(event => !event.includes('.'));\n\n return createTemplateAction<{\n repoUrl: string;\n webhookUrl: string;\n webhookSecret?: string;\n events?: string[];\n active?: boolean;\n contentType?: 'form' | 'json';\n insecureSsl?: boolean;\n token?: string;\n }>({\n id: 'github:webhook',\n description: 'Creates webhook for a repository on GitHub.',\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl', 'webhookUrl'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the new repository name and 'owner' is an organization or username`,\n type: 'string',\n },\n webhookUrl: {\n title: 'Webhook URL',\n description: 'The URL to which the payloads will be delivered',\n type: 'string',\n },\n webhookSecret: {\n title: 'Webhook Secret',\n description:\n 'Webhook secret value. The default can be provided internally in action creation',\n type: 'string',\n },\n events: {\n title: 'Triggering Events',\n description:\n 'Determines what events the hook is triggered for. Default: push',\n type: 'array',\n oneOf: [\n {\n items: {\n type: 'string',\n enum: eventNames,\n },\n },\n {\n items: {\n type: 'string',\n const: '*',\n },\n },\n ],\n },\n active: {\n title: 'Active',\n type: 'boolean',\n description: `Determines if notifications are sent when the webhook is triggered. Default: true`,\n },\n contentType: {\n title: 'Content Type',\n type: 'string',\n enum: ['form', 'json'],\n description: `The media type used to serialize the payloads. The default is 'form'`,\n },\n insecureSsl: {\n title: 'Insecure SSL',\n type: 'boolean',\n description: `Determines whether the SSL certificate of the host for url will be verified when delivering payloads. Default 'false'`,\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The GITHUB_TOKEN to use for authorization to GitHub',\n },\n },\n },\n },\n async handler(ctx) {\n const {\n repoUrl,\n webhookUrl,\n webhookSecret = defaultWebhookSecret,\n events = ['push'],\n active = true,\n contentType = 'form',\n insecureSsl = false,\n token: providedToken,\n } = ctx.input;\n\n ctx.logger.info(`Creating webhook ${webhookUrl} for repo ${repoUrl}`);\n const { owner, repo } = parseRepoUrl(repoUrl, integrations);\n\n if (!owner) {\n throw new InputError('Invalid repository owner provided in repoUrl');\n }\n\n const client = new Octokit(\n await getOctokitOptions({\n integrations,\n credentialsProvider: githubCredentialsProvider,\n repoUrl: repoUrl,\n token: providedToken,\n }),\n );\n\n try {\n const insecure_ssl = insecureSsl ? '1' : '0';\n await client.rest.repos.createWebhook({\n owner,\n repo,\n config: {\n url: webhookUrl,\n content_type: contentType,\n secret: webhookSecret,\n insecure_ssl,\n },\n events,\n active,\n });\n ctx.logger.info(`Webhook '${webhookUrl}' created successfully`);\n } catch (e) {\n assertError(e);\n ctx.logger.warn(\n `Failed: create webhook '${webhookUrl}' on repo: '${repo}', ${e.message}`,\n );\n }\n },\n });\n}\n","/*\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 { UrlReader } from '@backstage/backend-common';\nimport { JsonObject } from '@backstage/types';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport {\n GithubCredentialsProvider,\n ScmIntegrations,\n DefaultGithubCredentialsProvider,\n} from '@backstage/integration';\nimport { Config } from '@backstage/config';\nimport {\n createCatalogWriteAction,\n createCatalogRegisterAction,\n} from './catalog';\n\nimport { createDebugLogAction } from './debug';\nimport { createFetchPlainAction, createFetchTemplateAction } from './fetch';\nimport {\n createFilesystemDeleteAction,\n createFilesystemRenameAction,\n} from './filesystem';\nimport {\n createPublishAzureAction,\n createPublishBitbucketAction,\n createPublishGithubAction,\n createPublishGithubPullRequestAction,\n createPublishGitlabAction,\n createPublishGitlabMergeRequestAction,\n} from './publish';\nimport {\n createGithubActionsDispatchAction,\n createGithubWebhookAction,\n} from './github';\nimport { TemplateFilter } from '../../../lib';\nimport { TemplateAction } from '../types';\n\n/**\n * The options passed to {@link createBuiltinActions}\n * @public\n */\nexport interface CreateBuiltInActionsOptions {\n reader: UrlReader;\n integrations: ScmIntegrations;\n catalogClient: CatalogApi;\n config: Config;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n}\n\n/**\n * A function to generate create a list of default actions that the scaffolder provides.\n * Is called internally in the default setup, but can be used when adding your own actions or overriding the default ones\n *\n * @public\n * @returns A list of actions that can be used in the scaffolder\n */\nexport const createBuiltinActions = (\n options: CreateBuiltInActionsOptions,\n): TemplateAction<JsonObject>[] => {\n const {\n reader,\n integrations,\n catalogClient,\n config,\n additionalTemplateFilters,\n } = options;\n\n const githubCredentialsProvider: GithubCredentialsProvider =\n DefaultGithubCredentialsProvider.fromIntegrations(integrations);\n\n const actions = [\n createFetchPlainAction({\n reader,\n integrations,\n }),\n createFetchTemplateAction({\n integrations,\n reader,\n additionalTemplateFilters,\n }),\n createPublishGithubAction({\n integrations,\n config,\n githubCredentialsProvider,\n }),\n createPublishGithubPullRequestAction({\n integrations,\n githubCredentialsProvider,\n }),\n createPublishGitlabAction({\n integrations,\n config,\n }),\n createPublishGitlabMergeRequestAction({\n integrations,\n }),\n createPublishBitbucketAction({\n integrations,\n config,\n }),\n createPublishAzureAction({\n integrations,\n config,\n }),\n createDebugLogAction(),\n createCatalogRegisterAction({ catalogClient, integrations }),\n createCatalogWriteAction(),\n createFilesystemDeleteAction(),\n createFilesystemRenameAction(),\n createGithubActionsDispatchAction({\n integrations,\n githubCredentialsProvider,\n }),\n createGithubWebhookAction({\n integrations,\n githubCredentialsProvider,\n }),\n ];\n\n return actions as TemplateAction<JsonObject>[];\n};\n","/*\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 { ConflictError, NotFoundError } from '@backstage/errors';\nimport { TemplateAction } from './types';\n\n/**\n * Registry of all registered template actions.\n * @public\n */\nexport class TemplateActionRegistry {\n private readonly actions = new Map<string, TemplateAction<any>>();\n\n register<TInput extends JsonObject>(action: TemplateAction<TInput>) {\n if (this.actions.has(action.id)) {\n throw new ConflictError(\n `Template action with ID '${action.id}' has already been registered`,\n );\n }\n this.actions.set(action.id, action);\n }\n\n get(actionId: string): TemplateAction<JsonObject> {\n const action = this.actions.get(actionId);\n if (!action) {\n throw new NotFoundError(\n `Template action with ID '${actionId}' is not registered.`,\n );\n }\n return action;\n }\n\n list(): TemplateAction<JsonObject>[] {\n return [...this.actions.values()];\n }\n}\n","/*\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 { resolvePackagePath } from '@backstage/backend-common';\nimport { ConflictError, NotFoundError } from '@backstage/errors';\nimport { Knex } from 'knex';\nimport { v4 as uuid } from 'uuid';\nimport {\n SerializedTaskEvent,\n SerializedTask,\n TaskStatus,\n TaskEventType,\n TaskStore,\n TaskStoreEmitOptions,\n TaskStoreListEventsOptions,\n TaskStoreCreateTaskOptions,\n TaskStoreCreateTaskResult,\n} from './types';\nimport { DateTime } from 'luxon';\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 last_heartbeat_at?: string;\n created_at: string;\n secrets?: string | null;\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: Knex;\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 await options.database.migrate.latest({\n directory: migrationsDir,\n });\n return new DatabaseTaskStore(options);\n }\n\n private constructor(options: DatabaseTaskStoreOptions) {\n this.db = options.database;\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 return {\n id: result.id,\n spec,\n status: result.status,\n lastHeartbeatAt: result.last_heartbeat_at,\n createdAt: result.created_at,\n secrets,\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 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 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 when moving moving to processing state.\n secrets: null,\n });\n\n if (updateCount < 1) {\n return undefined;\n }\n\n try {\n const spec = JSON.parse(task.spec);\n const secrets = task.secrets ? JSON.parse(task.secrets) : undefined;\n return {\n id: task.id,\n spec,\n status: 'processing',\n lastHeartbeatAt: task.last_heartbeat_at,\n createdAt: task.created_at,\n secrets,\n };\n } catch (error) {\n throw new Error(`Failed to parse spec of task '${task.id}', ${error}`);\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({ timeoutS }: { timeoutS: number }): Promise<{\n tasks: { taskId: string }[];\n }> {\n const rawRows = await this.db<RawDbTaskRow>('tasks')\n .where('status', 'processing')\n .andWhere(\n 'last_heartbeat_at',\n '<=',\n this.db.client.config.client.includes('sqlite3')\n ? this.db.raw(`datetime('now', ?)`, [`-${timeoutS} seconds`])\n : this.db.raw(`dateadd('second', ?, ?)`, [\n `-${timeoutS}`,\n this.db.fn.now(),\n ]),\n );\n const tasks = rawRows.map(row => ({\n taskId: row.id,\n }));\n return { tasks };\n }\n\n async completeTask({\n taskId,\n status,\n eventBody,\n }: {\n taskId: string;\n status: TaskStatus;\n eventBody: JsonObject;\n }): Promise<void> {\n let oldStatus: string;\n if (status === 'failed' || status === 'completed') {\n oldStatus = 'processing';\n } else {\n throw new Error(\n `Invalid status update of run '${taskId}' to status '${status}'`,\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 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 const updateCount = await tx<RawDbTaskRow>('tasks')\n .where({\n id: taskId,\n status: oldStatus,\n })\n .update({\n status,\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\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 listEvents({\n taskId,\n after,\n }: TaskStoreListEventsOptions): Promise<{ events: SerializedTaskEvent[] }> {\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 taskId,\n body,\n type: event.event_type,\n createdAt:\n typeof event.created_at === 'string'\n ? DateTime.fromSQL(event.created_at, { zone: 'UTC' }).toISO()\n : 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 return { events };\n }\n}\n","/*\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 */\nimport { JsonObject, Observable } from '@backstage/types';\nimport ObservableImpl from 'zen-observable';\nimport { TaskSpec } from '@backstage/plugin-scaffolder-common';\nimport { Logger } from 'winston';\nimport {\n TaskCompletionState,\n TaskContext,\n TaskSecrets,\n TaskStore,\n TaskBroker,\n SerializedTaskEvent,\n SerializedTask,\n} from './types';\nimport { TaskBrokerDispatchOptions } from '.';\n\n/**\n * TaskManager\n *\n * @public\n */\nexport class TaskManager implements TaskContext {\n private isDone = false;\n\n private heartbeatTimeoutId?: ReturnType<typeof setInterval>;\n\n static create(task: CurrentClaimedTask, storage: TaskStore, logger: Logger) {\n const agent = new TaskManager(task, storage, logger);\n agent.startTimeout();\n return agent;\n }\n\n // Runs heartbeat internally\n private constructor(\n private readonly task: CurrentClaimedTask,\n private readonly storage: TaskStore,\n private readonly logger: Logger,\n ) {}\n\n get spec() {\n return this.task.spec;\n }\n\n get secrets() {\n return this.task.secrets;\n }\n\n async getWorkspaceName() {\n return this.task.taskId;\n }\n\n get done() {\n return this.isDone;\n }\n\n async emitLog(message: string, logMetadata?: JsonObject): Promise<void> {\n await this.storage.emitLogEvent({\n taskId: this.task.taskId,\n body: { message, ...logMetadata },\n });\n }\n\n async complete(\n result: TaskCompletionState,\n metadata?: JsonObject,\n ): Promise<void> {\n await this.storage.completeTask({\n taskId: this.task.taskId,\n status: result === 'failed' ? 'failed' : 'completed',\n eventBody: {\n message: `Run completed with status: ${result}`,\n ...metadata,\n },\n });\n this.isDone = true;\n if (this.heartbeatTimeoutId) {\n clearTimeout(this.heartbeatTimeoutId);\n }\n }\n\n private startTimeout() {\n this.heartbeatTimeoutId = setTimeout(async () => {\n try {\n await this.storage.heartbeatTask(this.task.taskId);\n this.startTimeout();\n } catch (error) {\n this.isDone = true;\n\n this.logger.error(\n `Heartbeat for task ${this.task.taskId} failed`,\n error,\n );\n }\n }, 1000);\n }\n}\n\n/**\n * Stores the state of the current claimed task passed to the TaskContext\n *\n * @public\n */\nexport interface CurrentClaimedTask {\n spec: TaskSpec;\n taskId: string;\n secrets?: TaskSecrets;\n}\n\nfunction defer() {\n let resolve = () => {};\n const promise = new Promise<void>(_resolve => {\n resolve = _resolve;\n });\n return { promise, resolve };\n}\n\nexport class StorageTaskBroker implements TaskBroker {\n constructor(\n private readonly storage: TaskStore,\n private readonly logger: Logger,\n ) {}\n private deferredDispatch = defer();\n\n async claim(): Promise<TaskContext> {\n for (;;) {\n const pendingTask = await this.storage.claimTask();\n if (pendingTask) {\n return TaskManager.create(\n {\n taskId: pendingTask.id,\n spec: pendingTask.spec,\n secrets: pendingTask.secrets,\n },\n this.storage,\n this.logger,\n );\n }\n\n await this.waitForDispatch();\n }\n }\n\n async dispatch(\n options: TaskBrokerDispatchOptions,\n ): Promise<{ taskId: string }> {\n const taskRow = await this.storage.createTask(options);\n this.signalDispatch();\n return {\n taskId: taskRow.taskId,\n };\n }\n\n async get(taskId: string): Promise<SerializedTask> {\n return this.storage.getTask(taskId);\n }\n\n event$(options: {\n taskId: string;\n after?: number;\n }): Observable<{ events: SerializedTaskEvent[] }> {\n return new ObservableImpl(observer => {\n const { taskId } = options;\n\n let after = options.after;\n let cancelled = false;\n\n (async () => {\n while (!cancelled) {\n const result = await this.storage.listEvents({ taskId, after });\n const { events } = result;\n if (events.length) {\n after = events[events.length - 1].id;\n observer.next(result);\n }\n\n await new Promise(resolve => setTimeout(resolve, 1000));\n }\n })();\n\n return () => {\n cancelled = true;\n };\n });\n }\n\n async vacuumTasks(options: { timeoutS: number }): Promise<void> {\n const { tasks } = await this.storage.listStaleTasks(options);\n await Promise.all(\n tasks.map(async task => {\n try {\n await this.storage.completeTask({\n taskId: task.taskId,\n status: 'failed',\n eventBody: {\n message:\n 'The task was cancelled because the task worker lost connection to the task broker',\n },\n });\n } catch (error) {\n this.logger.warn(`Failed to cancel task '${task.taskId}', ${error}`);\n }\n }),\n );\n }\n\n private waitForDispatch() {\n return this.deferredDispatch.promise;\n }\n\n private signalDispatch() {\n this.deferredDispatch.resolve();\n this.deferredDispatch = defer();\n }\n}\n","/*\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 { isArray } from 'lodash';\n\n/**\n * Returns true if the input is not `false`, `undefined`, `null`, `\"\"`, `0`, or\n * `[]`. This behavior is based on the behavior of handlebars, see\n * https://handlebarsjs.com/guide/builtin-helpers.html#if\n */\nexport function isTruthy(value: any): boolean {\n return isArray(value) ? value.length > 0 : !!value;\n}\n","/*\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 { TaskContext, WorkflowResponse, WorkflowRunner } from './types';\nimport * as winston from 'winston';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport nunjucks from 'nunjucks';\nimport { JsonObject, JsonValue } from '@backstage/types';\nimport { InputError } from '@backstage/errors';\nimport { PassThrough } from 'stream';\nimport { isTruthy } from './helper';\nimport { validate as validateJsonSchema } from 'jsonschema';\nimport { parseRepoUrl } from '../actions/builtin/publish/util';\nimport { TemplateActionRegistry } from '../actions';\nimport {\n TemplateFilter,\n SecureTemplater,\n SecureTemplateRenderer,\n} from '../../lib/templating/SecureTemplater';\nimport {\n TaskSpec,\n TaskSpecV1beta3,\n TaskStep,\n} from '@backstage/plugin-scaffolder-common';\n\ntype NunjucksWorkflowRunnerOptions = {\n workingDirectory: string;\n actionRegistry: TemplateActionRegistry;\n integrations: ScmIntegrations;\n logger: winston.Logger;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n};\n\ntype TemplateContext = {\n parameters: JsonObject;\n steps: {\n [stepName: string]: { output: { [outputName: string]: JsonValue } };\n };\n secrets?: Record<string, string>;\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}: {\n task: TaskContext;\n step: TaskStep;\n}) => {\n const metadata = { stepId: step.id };\n const taskLogger = winston.createLogger({\n level: process.env.LOG_LEVEL || 'info',\n format: winston.format.combine(\n winston.format.colorize(),\n winston.format.timestamp(),\n winston.format.simple(),\n ),\n defaultMeta: {},\n });\n\n const streamLogger = new PassThrough();\n streamLogger.on('data', async data => {\n const message = data.toString().trim();\n if (message?.length > 1) {\n await task.emitLog(message, metadata);\n }\n });\n\n taskLogger.add(new winston.transports.Stream({ stream: streamLogger }));\n\n return { taskLogger, streamLogger };\n};\n\nexport class NunjucksWorkflowRunner implements WorkflowRunner {\n constructor(private readonly options: NunjucksWorkflowRunnerOptions) {}\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 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 workspacePath = path.join(\n this.options.workingDirectory,\n await task.getWorkspaceName(),\n );\n\n const { integrations } = this.options;\n const renderTemplate = await SecureTemplater.loadRenderer({\n // TODO(blam): let's work out how we can deprecate this.\n // We shouldn't really need to be exposing these now we can deal with\n // objects in the params block.\n // Maybe we can expose a new RepoUrlPicker with secrets for V3 that provides an object already.\n parseRepoUrl(url: string) {\n return parseRepoUrl(url, integrations);\n },\n additionalTemplateFilters: this.options.additionalTemplateFilters,\n });\n\n try {\n await fs.ensureDir(workspacePath);\n await task.emitLog(\n `Starting up task with ${task.spec.steps.length} steps`,\n );\n\n const context: TemplateContext = {\n parameters: task.spec.parameters,\n steps: {},\n };\n\n for (const step of task.spec.steps) {\n try {\n if (step.if) {\n const ifResult = await this.render(\n step.if,\n context,\n renderTemplate,\n );\n if (!isTruthy(ifResult)) {\n await task.emitLog(\n `Skipping step ${step.id} because it's if condition was false`,\n { stepId: step.id, status: 'skipped' },\n );\n continue;\n }\n }\n\n await task.emitLog(`Beginning step ${step.name}`, {\n stepId: step.id,\n status: 'processing',\n });\n\n const action = this.options.actionRegistry.get(step.action);\n const { taskLogger, streamLogger } = createStepLogger({ task, step });\n\n // Secrets are only passed when templating the input to actions for security reasons\n const input =\n (step.input &&\n this.render(\n step.input,\n { ...context, secrets: task.secrets ?? {} },\n renderTemplate,\n )) ??\n {};\n\n if (action.schema?.input) {\n const validateResult = validateJsonSchema(\n 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 ${action.id}, ${errors}`,\n );\n }\n }\n\n const tmpDirs = new Array<string>();\n const stepOutput: { [outputName: string]: JsonValue } = {};\n\n await action.handler({\n input,\n secrets: task.secrets ?? {},\n logger: taskLogger,\n logStream: streamLogger,\n workspacePath,\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 stepOutput[name] = value;\n },\n templateInfo: task.spec.templateInfo,\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 await task.emitLog(`Finished step ${step.name}`, {\n stepId: step.id,\n status: 'completed',\n });\n } catch (err) {\n await task.emitLog(String(err.stack), {\n stepId: step.id,\n status: 'failed',\n });\n throw err;\n }\n }\n\n const output = this.render(task.spec.output, context, renderTemplate);\n\n return { output };\n } finally {\n if (workspacePath) {\n await fs.remove(workspacePath);\n }\n }\n }\n}\n","/*\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 { TaskContext, TaskBroker, WorkflowRunner } from './types';\nimport { NunjucksWorkflowRunner } from './NunjucksWorkflowRunner';\nimport { Logger } from 'winston';\nimport { TemplateActionRegistry } from '../actions';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { assertError } from '@backstage/errors';\nimport { TemplateFilter } from '../../lib/templating/SecureTemplater';\n\n/**\n * TaskWorkerOptions\n *\n * @public\n */\nexport type TaskWorkerOptions = {\n taskBroker: TaskBroker;\n runners: {\n workflowRunner: WorkflowRunner;\n };\n};\n\n/**\n * CreateWorkerOptions\n *\n * @public\n */\nexport type CreateWorkerOptions = {\n taskBroker: TaskBroker;\n actionRegistry: TemplateActionRegistry;\n integrations: ScmIntegrations;\n workingDirectory: string;\n logger: Logger;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n};\n\n/**\n * TaskWorker\n *\n * @public\n */\nexport class TaskWorker {\n private constructor(private readonly options: TaskWorkerOptions) {}\n\n static async create(options: CreateWorkerOptions): Promise<TaskWorker> {\n const {\n taskBroker,\n logger,\n actionRegistry,\n integrations,\n workingDirectory,\n additionalTemplateFilters,\n } = options;\n\n const workflowRunner = new NunjucksWorkflowRunner({\n actionRegistry,\n integrations,\n logger,\n workingDirectory,\n additionalTemplateFilters,\n });\n\n return new TaskWorker({\n taskBroker: taskBroker,\n runners: { workflowRunner },\n });\n }\n\n start() {\n (async () => {\n for (;;) {\n const task = await this.options.taskBroker.claim();\n await this.runOneTask(task);\n }\n })();\n }\n\n async runOneTask(task: TaskContext) {\n try {\n if (task.spec.apiVersion !== 'scaffolder.backstage.io/v1beta3') {\n throw new Error(\n `Unsupported Template apiVersion ${task.spec.apiVersion}`,\n );\n }\n\n const { output } = await this.options.runners.workflowRunner.execute(\n task,\n );\n\n await task.complete('completed', { output });\n } catch (error) {\n assertError(error);\n await task.complete('failed', {\n error: { name: error.name, message: error.message },\n });\n }\n }\n}\n","/*\n * Copyright 2020 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 { CatalogApi } from '@backstage/catalog-client';\nimport {\n Entity,\n ANNOTATION_LOCATION,\n parseLocationRef,\n ANNOTATION_SOURCE_LOCATION,\n CompoundEntityRef,\n DEFAULT_NAMESPACE,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport { assertError, InputError, NotFoundError } from '@backstage/errors';\nimport { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';\nimport fs from 'fs-extra';\nimport os from 'os';\nimport { Logger } from 'winston';\n\nexport async function getWorkingDirectory(\n config: Config,\n logger: Logger,\n): Promise<string> {\n if (!config.has('backend.workingDirectory')) {\n return os.tmpdir();\n }\n\n const workingDirectory = config.getString('backend.workingDirectory');\n try {\n // Check if working directory exists and is writable\n await fs.access(workingDirectory, fs.constants.F_OK | fs.constants.W_OK);\n logger.info(`using working directory: ${workingDirectory}`);\n } catch (err) {\n assertError(err);\n logger.error(\n `working directory ${workingDirectory} ${\n err.code === 'ENOENT' ? 'does not exist' : 'is not writable'\n }`,\n );\n throw err;\n }\n return workingDirectory;\n}\n\n/**\n * Gets the base URL of the entity location that points to the source location\n * of the entity description within a repo. If there is not source location\n * or if it has an invalid type, undefined will be returned instead.\n *\n * For file locations this will return a `file://` URL.\n */\nexport function getEntityBaseUrl(entity: Entity): string | undefined {\n let location = entity.metadata.annotations?.[ANNOTATION_SOURCE_LOCATION];\n if (!location) {\n location = entity.metadata.annotations?.[ANNOTATION_LOCATION];\n }\n if (!location) {\n return undefined;\n }\n\n const { type, target } = parseLocationRef(location);\n if (type === 'url') {\n return target;\n } else if (type === 'file') {\n return `file://${target}`;\n }\n\n // Only url and file location are handled, as we otherwise don't know if\n // what the url is pointing to makes sense to use as a baseUrl\n return undefined;\n}\n\n/**\n * Will use the provided CatalogApi to go find the given template entity with an additional token.\n * Returns the matching template, or throws a NotFoundError if no such template existed.\n */\nexport async function findTemplate(options: {\n entityRef: CompoundEntityRef;\n token?: string;\n catalogApi: CatalogApi;\n}): Promise<TemplateEntityV1beta3> {\n const { entityRef, token, catalogApi } = options;\n\n if (entityRef.namespace.toLocaleLowerCase('en-US') !== DEFAULT_NAMESPACE) {\n throw new InputError(\n `Invalid namespace, only '${DEFAULT_NAMESPACE}' namespace is supported`,\n );\n }\n if (entityRef.kind.toLocaleLowerCase('en-US') !== 'template') {\n throw new InputError(`Invalid kind, only 'Template' kind is supported`);\n }\n\n const template = await catalogApi.getEntityByRef(entityRef, { token });\n if (!template) {\n throw new NotFoundError(\n `Template ${stringifyEntityRef(entityRef)} not found`,\n );\n }\n\n return template as TemplateEntityV1beta3;\n}\n","/*\n * Copyright 2020 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 { PluginDatabaseManager, UrlReader } from '@backstage/backend-common';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';\nimport { Entity } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport { InputError, NotFoundError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport {\n TemplateEntityV1beta3,\n TaskSpec,\n} from '@backstage/plugin-scaffolder-common';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { validate } from 'jsonschema';\nimport { Logger } from 'winston';\nimport { TemplateFilter } from '../lib';\nimport {\n createBuiltinActions,\n DatabaseTaskStore,\n TaskBroker,\n TaskWorker,\n TemplateAction,\n TemplateActionRegistry,\n} from '../scaffolder';\nimport { StorageTaskBroker } from '../scaffolder/tasks/StorageTaskBroker';\nimport { getEntityBaseUrl, getWorkingDirectory, findTemplate } from './helpers';\n\n/**\n * RouterOptions\n *\n * @public\n */\nexport interface RouterOptions {\n logger: Logger;\n config: Config;\n reader: UrlReader;\n database: PluginDatabaseManager;\n catalogClient: CatalogApi;\n actions?: TemplateAction<any>[];\n taskWorkers?: number;\n taskBroker?: TaskBroker;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n}\n\nfunction isSupportedTemplate(entity: TemplateEntityV1beta3) {\n return entity.apiVersion === 'scaffolder.backstage.io/v1beta3';\n}\n\n/** @public */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const router = Router();\n router.use(express.json());\n\n const {\n logger: parentLogger,\n config,\n reader,\n database,\n catalogClient,\n actions,\n taskWorkers,\n additionalTemplateFilters,\n } = options;\n\n const logger = parentLogger.child({ plugin: 'scaffolder' });\n const workingDirectory = await getWorkingDirectory(config, logger);\n const integrations = ScmIntegrations.fromConfig(config);\n let taskBroker: TaskBroker;\n\n if (!options.taskBroker) {\n const databaseTaskStore = await DatabaseTaskStore.create({\n database: await database.getClient(),\n });\n taskBroker = new StorageTaskBroker(databaseTaskStore, logger);\n } else {\n taskBroker = options.taskBroker;\n }\n\n const actionRegistry = new TemplateActionRegistry();\n\n const workers = [];\n for (let i = 0; i < (taskWorkers || 1); i++) {\n const worker = await TaskWorker.create({\n taskBroker,\n actionRegistry,\n integrations,\n logger,\n workingDirectory,\n additionalTemplateFilters,\n });\n workers.push(worker);\n }\n\n const actionsToRegister = Array.isArray(actions)\n ? actions\n : createBuiltinActions({\n integrations,\n catalogClient,\n reader,\n config,\n additionalTemplateFilters,\n });\n\n actionsToRegister.forEach(action => actionRegistry.register(action));\n workers.forEach(worker => worker.start());\n\n router\n .get(\n '/v2/templates/:namespace/:kind/:name/parameter-schema',\n async (req, res) => {\n const { namespace, kind, name } = req.params;\n const template = await findTemplate({\n catalogApi: catalogClient,\n entityRef: { kind, namespace, name },\n token: getBearerToken(req.headers.authorization),\n });\n if (isSupportedTemplate(template)) {\n const parameters = [template.spec.parameters ?? []].flat();\n res.json({\n title: template.metadata.title ?? template.metadata.name,\n steps: parameters.map(schema => ({\n title: schema.title ?? 'Fill in template parameters',\n schema,\n })),\n });\n } else {\n throw new InputError(\n `Unsupported apiVersion field in schema entity, ${\n (template as Entity).apiVersion\n }`,\n );\n }\n },\n )\n .get('/v2/actions', async (_req, res) => {\n const actionsList = actionRegistry.list().map(action => {\n return {\n id: action.id,\n description: action.description,\n schema: action.schema,\n };\n });\n res.json(actionsList);\n })\n .post('/v2/tasks', async (req, res) => {\n const templateRef: string = req.body.templateRef;\n const { kind, namespace, name } = parseEntityRef(templateRef, {\n defaultKind: 'template',\n });\n const values = req.body.values;\n const token = getBearerToken(req.headers.authorization);\n const template = await findTemplate({\n catalogApi: catalogClient,\n entityRef: { kind, namespace, name },\n token: getBearerToken(req.headers.authorization),\n });\n\n if (!isSupportedTemplate(template)) {\n throw new InputError(\n `Unsupported apiVersion field in schema entity, ${\n (template as Entity).apiVersion\n }`,\n );\n }\n\n for (const parameters of [template.spec.parameters ?? []].flat()) {\n const result = validate(values, parameters);\n if (!result.valid) {\n res.status(400).json({ errors: result.errors });\n return;\n }\n }\n\n const baseUrl = getEntityBaseUrl(template);\n\n const taskSpec: TaskSpec = {\n apiVersion: template.apiVersion,\n steps: template.spec.steps.map((step, index) => ({\n ...step,\n id: step.id ?? `step-${index + 1}`,\n name: step.name ?? step.action,\n })),\n output: template.spec.output ?? {},\n parameters: values,\n templateInfo: {\n entityRef: stringifyEntityRef({\n kind,\n namespace,\n name: template.metadata?.name,\n }),\n baseUrl,\n },\n };\n\n const result = await taskBroker.dispatch({\n spec: taskSpec,\n secrets: {\n ...req.body.secrets,\n backstageToken: token,\n },\n });\n\n res.status(201).json({ id: result.taskId });\n })\n .get('/v2/tasks/:taskId', async (req, res) => {\n const { taskId } = req.params;\n const task = await taskBroker.get(taskId);\n if (!task) {\n throw new NotFoundError(`Task with id ${taskId} does not exist`);\n }\n // Do not disclose secrets\n delete task.secrets;\n res.status(200).json(task);\n })\n .get('/v2/tasks/:taskId/eventstream', async (req, res) => {\n const { taskId } = req.params;\n const after =\n req.query.after !== undefined ? Number(req.query.after) : undefined;\n\n logger.debug(`Event stream observing taskId '${taskId}' opened`);\n\n // Mandatory headers and http status to keep connection open\n res.writeHead(200, {\n Connection: 'keep-alive',\n 'Cache-Control': 'no-cache',\n 'Content-Type': 'text/event-stream',\n });\n\n // After client opens connection send all events as string\n const subscription = taskBroker.event$({ taskId, after }).subscribe({\n error: error => {\n logger.error(\n `Received error from event stream when observing taskId '${taskId}', ${error}`,\n );\n },\n next: ({ events }) => {\n let shouldUnsubscribe = false;\n for (const event of events) {\n res.write(\n `event: ${event.type}\\ndata: ${JSON.stringify(event)}\\n\\n`,\n );\n if (event.type === 'completion') {\n shouldUnsubscribe = true;\n }\n }\n // res.flush() is only available with the compression middleware\n res.flush?.();\n if (shouldUnsubscribe) subscription.unsubscribe();\n },\n });\n\n // When client closes connection we update the clients list\n // avoiding the disconnected one\n req.on('close', () => {\n subscription.unsubscribe();\n logger.debug(`Event stream observing taskId '${taskId}' closed`);\n });\n })\n .get('/v2/tasks/:taskId/events', async (req, res) => {\n const { taskId } = req.params;\n const after = Number(req.query.after) || undefined;\n\n // cancel the request after 30 seconds. this aligns with the recommendations of RFC 6202.\n const timeout = setTimeout(() => {\n res.json([]);\n }, 30_000);\n\n // Get all known events after an id (always includes the completion event) and return the first callback\n const subscription = taskBroker.event$({ taskId, after }).subscribe({\n error: error => {\n logger.error(\n `Received error from event stream when observing taskId '${taskId}', ${error}`,\n );\n },\n next: ({ events }) => {\n clearTimeout(timeout);\n subscription.unsubscribe();\n res.json(events);\n },\n });\n\n // When client closes connection we update the clients list\n // avoiding the disconnected one\n req.on('close', () => {\n subscription.unsubscribe();\n clearTimeout(timeout);\n });\n });\n\n const app = express();\n app.set('logger', logger);\n app.use('/', router);\n\n return app;\n}\n\nfunction getBearerToken(header?: string): string | undefined {\n return header?.match(/Bearer\\s+(\\S+)/i)?.[1];\n}\n","/*\n * Copyright 2020 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 {\n Entity,\n getCompoundEntityRef,\n parseEntityRef,\n RELATION_OWNED_BY,\n RELATION_OWNER_OF,\n} from '@backstage/catalog-model';\nimport {\n CatalogProcessor,\n CatalogProcessorEmit,\n LocationSpec,\n processingResult,\n} from '@backstage/plugin-catalog-backend';\nimport {\n TemplateEntityV1beta3,\n templateEntityV1beta3Validator,\n} from '@backstage/plugin-scaffolder-common';\n\n/** @public */\nexport class ScaffolderEntitiesProcessor implements CatalogProcessor {\n getProcessorName(): string {\n return 'ScaffolderEntitiesProcessor';\n }\n\n private readonly validators = [templateEntityV1beta3Validator];\n\n async validateEntityKind(entity: Entity): Promise<boolean> {\n for (const validator of this.validators) {\n if (await validator.check(entity)) {\n return true;\n }\n }\n\n return false;\n }\n\n async postProcessEntity(\n entity: Entity,\n _location: LocationSpec,\n emit: CatalogProcessorEmit,\n ): Promise<Entity> {\n const selfRef = getCompoundEntityRef(entity);\n\n if (\n entity.apiVersion === 'scaffolder.backstage.io/v1beta3' &&\n entity.kind === 'Template'\n ) {\n const template = entity as TemplateEntityV1beta3;\n\n const target = template.spec.owner;\n if (target) {\n const targetRef = parseEntityRef(target, {\n defaultKind: 'Group',\n defaultNamespace: selfRef.namespace,\n });\n emit(\n processingResult.relation({\n source: selfRef,\n type: RELATION_OWNED_BY,\n target: {\n kind: targetRef.kind,\n namespace: targetRef.namespace,\n name: targetRef.name,\n },\n }),\n );\n emit(\n processingResult.relation({\n source: {\n kind: targetRef.kind,\n namespace: targetRef.namespace,\n name: targetRef.name,\n },\n type: RELATION_OWNER_OF,\n target: selfRef,\n }),\n );\n }\n }\n\n return entity;\n }\n}\n"],"names":["InputError","stringifyEntityRef","fs","resolveSafeChildPath","yaml","relative","readdir","join","stat","path","VM","resolvePackagePath","globby","extname","isBinaryFile","PassThrough","spawn","Git","normalizePath","joinPath","isChildPath","getPersonalAccessTokenHandler","WebApi","fetch","dirname","DefaultGithubCredentialsProvider","Octokit","CustomErrorBase","createPullRequest","zipObject","Gitlab","readFile","emitterEventNames","ConflictError","NotFoundError","uuid","DateTime","ObservableImpl","isArray","winston","nunjucks","validateJsonSchema","errors","os","ANNOTATION_SOURCE_LOCATION","ANNOTATION_LOCATION","parseLocationRef","DEFAULT_NAMESPACE","Router","express","ScmIntegrations","parseEntityRef","validate","templateEntityV1beta3Validator","getCompoundEntityRef","processingResult","RELATION_OWNED_BY","RELATION_OWNER_OF"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/scaffolder/actions/createTemplateAction.ts","../src/scaffolder/actions/builtin/catalog/register.ts","../src/scaffolder/actions/builtin/catalog/write.ts","../src/scaffolder/actions/builtin/debug/log.ts","../src/scaffolder/actions/builtin/fetch/helpers.ts","../src/scaffolder/actions/builtin/fetch/plain.ts","../src/lib/templating/SecureTemplater.ts","../src/scaffolder/actions/builtin/fetch/template.ts","../src/scaffolder/actions/builtin/filesystem/delete.ts","../src/scaffolder/actions/builtin/filesystem/rename.ts","../src/scaffolder/actions/builtin/helpers.ts","../src/scaffolder/actions/builtin/publish/util.ts","../src/scaffolder/actions/builtin/publish/azure.ts","../src/scaffolder/actions/builtin/publish/bitbucket.ts","../src/scaffolder/actions/builtin/publish/file.ts","../src/scaffolder/actions/builtin/github/helpers.ts","../src/scaffolder/actions/builtin/publish/github.ts","../src/scaffolder/actions/builtin/publish/githubPullRequest.ts","../src/scaffolder/actions/builtin/publish/gitlab.ts","../src/scaffolder/actions/builtin/publish/gitlabMergeRequest.ts","../src/scaffolder/actions/builtin/github/githubActionsDispatch.ts","../src/scaffolder/actions/builtin/github/githubWebhook.ts","../src/scaffolder/actions/builtin/github/githubIssuesLabel.ts","../src/scaffolder/actions/builtin/createBuiltinActions.ts","../src/scaffolder/actions/TemplateActionRegistry.ts","../src/scaffolder/tasks/DatabaseTaskStore.ts","../src/scaffolder/tasks/StorageTaskBroker.ts","../src/scaffolder/tasks/helper.ts","../src/scaffolder/tasks/NunjucksWorkflowRunner.ts","../src/scaffolder/tasks/TaskWorker.ts","../src/service/helpers.ts","../src/service/router.ts","../src/processor/ScaffolderEntitiesProcessor.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 { TemplateAction } from './types';\n\n/**\n * This function is used to create new template actions to get type safety.\n * @public\n */\nexport const createTemplateAction = <TInput extends JsonObject>(\n templateAction: TemplateAction<TInput>,\n): TemplateAction<TInput> => {\n // TODO(blam): Can add some more validation here to validate the action later on\n return templateAction;\n};\n","/*\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 { InputError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport { createTemplateAction } from '../../createTemplateAction';\n\n/**\n * Registers entities from a catalog descriptor file in the workspace into the software catalog.\n * @public\n */\nexport function createCatalogRegisterAction(options: {\n catalogClient: CatalogApi;\n integrations: ScmIntegrations;\n}) {\n const { catalogClient, integrations } = options;\n\n return createTemplateAction<\n | { catalogInfoUrl: string; optional?: boolean }\n | { repoContentsUrl: string; catalogInfoPath?: string; optional?: boolean }\n >({\n id: 'catalog:register',\n description:\n 'Registers entities from a catalog descriptor file in the workspace into the software catalog.',\n schema: {\n input: {\n oneOf: [\n {\n type: 'object',\n required: ['catalogInfoUrl'],\n properties: {\n catalogInfoUrl: {\n title: 'Catalog Info URL',\n description:\n 'An absolute URL pointing to the catalog info file location',\n type: 'string',\n },\n optional: {\n title: 'Optional',\n description:\n 'Permit the registered location to optionally exist. Default: false',\n type: 'boolean',\n },\n },\n },\n {\n type: 'object',\n required: ['repoContentsUrl'],\n properties: {\n repoContentsUrl: {\n title: 'Repository Contents URL',\n description:\n 'An absolute URL pointing to the root of a repository directory tree',\n type: 'string',\n },\n catalogInfoPath: {\n title: 'Fetch URL',\n description:\n 'A relative path from the repo root pointing to the catalog info file, defaults to /catalog-info.yaml',\n type: 'string',\n },\n optional: {\n title: 'Optional',\n description:\n 'Permit the registered location to optionally exist. Default: false',\n type: 'boolean',\n },\n },\n },\n ],\n },\n },\n async handler(ctx) {\n const { input } = ctx;\n\n let catalogInfoUrl;\n if ('catalogInfoUrl' in input) {\n catalogInfoUrl = input.catalogInfoUrl;\n } else {\n const { repoContentsUrl, catalogInfoPath = '/catalog-info.yaml' } =\n input;\n const integration = integrations.byUrl(repoContentsUrl);\n if (!integration) {\n throw new InputError(\n `No integration found for host ${repoContentsUrl}`,\n );\n }\n\n catalogInfoUrl = integration.resolveUrl({\n base: repoContentsUrl,\n url: catalogInfoPath,\n });\n }\n\n ctx.logger.info(`Registering ${catalogInfoUrl} in the catalog`);\n\n await catalogClient.addLocation(\n {\n type: 'url',\n target: catalogInfoUrl,\n },\n ctx.secrets?.backstageToken\n ? { token: ctx.secrets.backstageToken }\n : {},\n );\n\n try {\n const result = await catalogClient.addLocation(\n {\n dryRun: true,\n type: 'url',\n target: catalogInfoUrl,\n },\n ctx.secrets?.backstageToken\n ? { token: ctx.secrets.backstageToken }\n : {},\n );\n\n if (result.entities.length > 0) {\n const { entities } = result;\n let entity: any;\n // prioritise 'Component' type as it is the most central kind of entity\n entity = entities.find(\n (e: any) =>\n !e.metadata.name.startsWith('generated-') &&\n e.kind === 'Component',\n );\n if (!entity) {\n entity = entities.find(\n (e: any) => !e.metadata.name.startsWith('generated-'),\n );\n }\n if (!entity) {\n entity = entities[0];\n }\n\n ctx.output('entityRef', stringifyEntityRef(entity));\n }\n } catch (e) {\n if (!input.optional) {\n throw e;\n }\n }\n\n ctx.output('catalogInfoUrl', catalogInfoUrl);\n },\n });\n}\n","/*\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 fs from 'fs-extra';\nimport { createTemplateAction } from '../../createTemplateAction';\nimport * as yaml from 'yaml';\nimport { Entity } from '@backstage/catalog-model';\nimport { resolveSafeChildPath } from '@backstage/backend-common';\n\n/**\n * Writes a catalog descriptor file containing the provided entity to a path in the workspace.\n * @public\n */\nexport function createCatalogWriteAction() {\n return createTemplateAction<{ filePath?: string; entity: Entity }>({\n id: 'catalog:write',\n description: 'Writes the catalog-info.yaml for your template',\n schema: {\n input: {\n type: 'object',\n properties: {\n filePath: {\n title: 'Catalog file path',\n description: 'Defaults to catalog-info.yaml',\n type: 'string',\n },\n entity: {\n title: 'Entity info to write catalog-info.yaml',\n description:\n 'You can provide the same values used in the Entity schema.',\n type: 'object',\n },\n },\n },\n },\n async handler(ctx) {\n ctx.logStream.write(`Writing catalog-info.yaml`);\n const { filePath, entity } = ctx.input;\n const path = filePath ?? 'catalog-info.yaml';\n\n await fs.writeFile(\n resolveSafeChildPath(ctx.workspacePath, path),\n yaml.stringify(entity),\n );\n },\n });\n}\n","/*\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 { readdir, stat } from 'fs-extra';\nimport { relative, join } from 'path';\nimport { createTemplateAction } from '../../createTemplateAction';\n\n/**\n * Writes a message into the log or lists all files in the workspace\n *\n * @remarks\n *\n * This task is useful for local development and testing of both the scaffolder\n * and scaffolder templates.\n *\n * @public\n */\nexport function createDebugLogAction() {\n return createTemplateAction<{ message?: string; listWorkspace?: boolean }>({\n id: 'debug:log',\n description:\n 'Writes a message into the log or lists all files in the workspace.',\n schema: {\n input: {\n type: 'object',\n properties: {\n message: {\n title: 'Message to output.',\n type: 'string',\n },\n listWorkspace: {\n title: 'List all files in the workspace, if true.',\n type: 'boolean',\n },\n extra: {\n title: 'Extra info',\n },\n },\n },\n },\n async handler(ctx) {\n ctx.logger.info(JSON.stringify(ctx.input, null, 2));\n\n if (ctx.input?.message) {\n ctx.logStream.write(ctx.input.message);\n }\n\n if (ctx.input?.listWorkspace) {\n const files = await recursiveReadDir(ctx.workspacePath);\n ctx.logStream.write(\n `Workspace:\\n${files\n .map(f => ` - ${relative(ctx.workspacePath, f)}`)\n .join('\\n')}`,\n );\n }\n },\n });\n}\n\nexport async function recursiveReadDir(dir: string): Promise<string[]> {\n const subdirs = await readdir(dir);\n const files = await Promise.all(\n subdirs.map(async subdir => {\n const res = join(dir, subdir);\n return (await stat(res)).isDirectory() ? recursiveReadDir(res) : [res];\n }),\n );\n return files.reduce((a, f) => a.concat(f), []);\n}\n","/*\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 { resolveSafeChildPath, UrlReader } from '@backstage/backend-common';\nimport { InputError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport fs from 'fs-extra';\nimport path from 'path';\n\n/**\n * A helper function that reads the contents of a directory from the given URL.\n * Can be used in your own actions, and also used behind fetch:template and fetch:plain\n *\n * @public\n */\nexport async function fetchContents({\n reader,\n integrations,\n baseUrl,\n fetchUrl = '.',\n outputPath,\n}: {\n reader: UrlReader;\n integrations: ScmIntegrations;\n baseUrl?: string;\n fetchUrl?: string;\n outputPath: string;\n}) {\n let fetchUrlIsAbsolute = false;\n try {\n // eslint-disable-next-line no-new\n new URL(fetchUrl);\n fetchUrlIsAbsolute = true;\n } catch {\n /* ignored */\n }\n\n // We handle both file locations and url ones\n if (!fetchUrlIsAbsolute && baseUrl?.startsWith('file://')) {\n const basePath = baseUrl.slice('file://'.length);\n const srcDir = resolveSafeChildPath(path.dirname(basePath), fetchUrl);\n await fs.copy(srcDir, outputPath);\n } else {\n let readUrl;\n\n if (fetchUrlIsAbsolute) {\n readUrl = fetchUrl;\n } else if (baseUrl) {\n const integration = integrations.byUrl(baseUrl);\n if (!integration) {\n throw new InputError(`No integration found for location ${baseUrl}`);\n }\n\n readUrl = integration.resolveUrl({\n url: fetchUrl,\n base: baseUrl,\n });\n } else {\n throw new InputError(\n `Failed to fetch, template location could not be determined and the fetch URL is relative, ${fetchUrl}`,\n );\n }\n\n const res = await reader.readTree(readUrl);\n await fs.ensureDir(outputPath);\n await res.dir({ targetDir: outputPath });\n }\n}\n","/*\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 { UrlReader, resolveSafeChildPath } from '@backstage/backend-common';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { fetchContents } from './helpers';\nimport { createTemplateAction } from '../../createTemplateAction';\n\n/**\n * Downloads content and places it in the workspace, or optionally\n * in a subdirectory specified by the 'targetPath' input option.\n * @public\n */\nexport function createFetchPlainAction(options: {\n reader: UrlReader;\n integrations: ScmIntegrations;\n}) {\n const { reader, integrations } = options;\n\n return createTemplateAction<{ url: string; targetPath?: string }>({\n id: 'fetch:plain',\n description:\n \"Downloads content and places it in the workspace, or optionally in a subdirectory specified by the 'targetPath' input option.\",\n schema: {\n input: {\n type: 'object',\n required: ['url'],\n properties: {\n url: {\n title: 'Fetch URL',\n description:\n 'Relative path or absolute URL pointing to the directory tree to fetch',\n type: 'string',\n },\n targetPath: {\n title: 'Target Path',\n description:\n 'Target path within the working directory to download the contents to.',\n type: 'string',\n },\n },\n },\n },\n async handler(ctx) {\n ctx.logger.info('Fetching plain content from remote URL');\n\n // Finally move the template result into the task workspace\n const targetPath = ctx.input.targetPath ?? './';\n const outputPath = resolveSafeChildPath(ctx.workspacePath, targetPath);\n\n await fetchContents({\n reader,\n integrations,\n baseUrl: ctx.templateInfo?.baseUrl,\n fetchUrl: ctx.input.url,\n outputPath,\n });\n },\n });\n}\n","/*\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 { VM } from 'vm2';\nimport { resolvePackagePath } from '@backstage/backend-common';\nimport fs from 'fs-extra';\nimport { JsonValue } from '@backstage/types';\nimport { RepoSpec } from '../../scaffolder/actions/builtin/publish/util';\n\n// language=JavaScript\nconst mkScript = (nunjucksSource: string) => `\nconst { render, renderCompat } = (() => {\n const module = {};\n const process = { env: {} };\n const require = (pkg) => { if (pkg === 'events') { return function (){}; }};\n\n ${nunjucksSource}\n\n const env = module.exports.configure({\n autoescape: false,\n tags: {\n variableStart: '\\${{',\n variableEnd: '}}',\n },\n });\n\n const compatEnv = module.exports.configure({\n autoescape: false,\n tags: {\n variableStart: '{{',\n variableEnd: '}}',\n },\n });\n compatEnv.addFilter('jsonify', compatEnv.getFilter('dump'));\n\n if (typeof parseRepoUrl !== 'undefined') {\n const safeHelperRef = parseRepoUrl;\n\n env.addFilter('parseRepoUrl', repoUrl => {\n return JSON.parse(safeHelperRef(repoUrl))\n });\n env.addFilter('projectSlug', repoUrl => {\n const { owner, repo } = JSON.parse(safeHelperRef(repoUrl));\n return owner + '/' + repo;\n });\n }\n\n if (typeof additionalTemplateFilters !== 'undefined') {\n for (const [filterName, filterFn] of Object.entries(additionalTemplateFilters)) {\n env.addFilter(filterName, (...args) => JSON.parse(filterFn(...args)));\n }\n }\n\n let uninstallCompat = undefined;\n\n function render(str, values) {\n try {\n if (uninstallCompat) {\n uninstallCompat();\n uninstallCompat = undefined;\n }\n return env.renderString(str, JSON.parse(values));\n } catch (error) {\n // Make sure errors don't leak anything\n throw new Error(String(error.message));\n }\n }\n\n function renderCompat(str, values) {\n try {\n if (!uninstallCompat) {\n uninstallCompat = module.exports.installJinjaCompat();\n }\n return compatEnv.renderString(str, JSON.parse(values));\n } catch (error) {\n // Make sure errors don't leak anything\n throw new Error(String(error.message));\n }\n }\n\n return { render, renderCompat };\n})();\n`;\n\n/** @public */\nexport type TemplateFilter = (...args: JsonValue[]) => JsonValue | undefined;\n\nexport interface SecureTemplaterOptions {\n /* Optional implementation of the parseRepoUrl filter */\n parseRepoUrl?(repoUrl: string): RepoSpec;\n\n /* Enables jinja compatibility and the \"jsonify\" filter */\n cookiecutterCompat?: boolean;\n\n /* Extra user-provided nunjucks filters */\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n}\n\nexport type SecureTemplateRenderer = (\n template: string,\n values: unknown,\n) => string;\n\nexport class SecureTemplater {\n static async loadRenderer(options: SecureTemplaterOptions = {}) {\n const { parseRepoUrl, cookiecutterCompat, additionalTemplateFilters } =\n options;\n const sandbox: Record<string, any> = {};\n\n if (parseRepoUrl) {\n sandbox.parseRepoUrl = (url: string) => JSON.stringify(parseRepoUrl(url));\n }\n\n if (additionalTemplateFilters) {\n sandbox.additionalTemplateFilters = Object.fromEntries(\n Object.entries(additionalTemplateFilters)\n .filter(([_, filterFunction]) => !!filterFunction)\n .map(([filterName, filterFunction]) => [\n filterName,\n (...args: JsonValue[]) => JSON.stringify(filterFunction(...args)),\n ]),\n );\n }\n\n const vm = new VM({ sandbox });\n\n const nunjucksSource = await fs.readFile(\n resolvePackagePath(\n '@backstage/plugin-scaffolder-backend',\n 'assets/nunjucks.js.txt',\n ),\n 'utf-8',\n );\n\n vm.run(mkScript(nunjucksSource));\n\n const render: SecureTemplateRenderer = (template, values) => {\n if (!vm) {\n throw new Error('SecureTemplater has not been initialized');\n }\n vm.setGlobal('templateStr', template);\n vm.setGlobal('templateValues', JSON.stringify(values));\n\n if (cookiecutterCompat) {\n return vm.run(`renderCompat(templateStr, templateValues)`);\n }\n\n return vm.run(`render(templateStr, templateValues)`);\n };\n return render;\n }\n}\n","/*\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 { extname } from 'path';\nimport { resolveSafeChildPath, UrlReader } from '@backstage/backend-common';\nimport { InputError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { fetchContents } from './helpers';\nimport { createTemplateAction } from '../../createTemplateAction';\nimport globby from 'globby';\nimport fs from 'fs-extra';\nimport { isBinaryFile } from 'isbinaryfile';\nimport {\n TemplateFilter,\n SecureTemplater,\n} from '../../../../lib/templating/SecureTemplater';\n\n/**\n * Downloads a skeleton, templates variables into file and directory names and content.\n * Then places the result in the workspace, or optionally in a subdirectory\n * specified by the 'targetPath' input option.\n *\n * @public\n */\nexport function createFetchTemplateAction(options: {\n reader: UrlReader;\n integrations: ScmIntegrations;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n}) {\n const { reader, integrations, additionalTemplateFilters } = options;\n\n return createTemplateAction<{\n url: string;\n targetPath?: string;\n values: any;\n templateFileExtension?: string | boolean;\n\n // Cookiecutter compat options\n copyWithoutRender?: string[];\n cookiecutterCompat?: boolean;\n }>({\n id: 'fetch:template',\n description:\n \"Downloads a skeleton, templates variables into file and directory names and content, and places the result in the workspace, or optionally in a subdirectory specified by the 'targetPath' input option.\",\n schema: {\n input: {\n type: 'object',\n required: ['url'],\n properties: {\n url: {\n title: 'Fetch URL',\n description:\n 'Relative path or absolute URL pointing to the directory tree to fetch',\n type: 'string',\n },\n targetPath: {\n title: 'Target Path',\n description:\n 'Target path within the working directory to download the contents to. Defaults to the working directory root.',\n type: 'string',\n },\n values: {\n title: 'Template Values',\n description: 'Values to pass on to the templating engine',\n type: 'object',\n },\n copyWithoutRender: {\n title: 'Copy Without Render',\n description:\n 'An array of glob patterns. Any files or directories which match are copied without being processed as templates.',\n type: 'array',\n items: {\n type: 'string',\n },\n },\n cookiecutterCompat: {\n title: 'Cookiecutter compatibility mode',\n description:\n 'Enable features to maximise compatibility with templates built for fetch:cookiecutter',\n type: 'boolean',\n },\n templateFileExtension: {\n title: 'Template File Extension',\n description:\n 'If set, only files with the given extension will be templated. If set to `true`, the default extension `.njk` is used.',\n type: ['string', 'boolean'],\n },\n },\n },\n },\n async handler(ctx) {\n ctx.logger.info('Fetching template content from remote URL');\n\n const workDir = await ctx.createTemporaryDirectory();\n const templateDir = resolveSafeChildPath(workDir, 'template');\n\n const targetPath = ctx.input.targetPath ?? './';\n const outputDir = resolveSafeChildPath(ctx.workspacePath, targetPath);\n\n if (\n ctx.input.copyWithoutRender &&\n !Array.isArray(ctx.input.copyWithoutRender)\n ) {\n throw new InputError(\n 'Fetch action input copyWithoutRender must be an Array',\n );\n }\n\n if (\n ctx.input.templateFileExtension &&\n (ctx.input.copyWithoutRender || ctx.input.cookiecutterCompat)\n ) {\n throw new InputError(\n 'Fetch action input extension incompatible with copyWithoutRender and cookiecutterCompat',\n );\n }\n\n let extension: string | false = false;\n if (ctx.input.templateFileExtension) {\n extension =\n ctx.input.templateFileExtension === true\n ? '.njk'\n : ctx.input.templateFileExtension;\n if (!extension.startsWith('.')) {\n extension = `.${extension}`;\n }\n }\n\n await fetchContents({\n reader,\n integrations,\n baseUrl: ctx.templateInfo?.baseUrl,\n fetchUrl: ctx.input.url,\n outputPath: templateDir,\n });\n\n ctx.logger.info('Listing files and directories in template');\n const allEntriesInTemplate = await globby(`**/*`, {\n cwd: templateDir,\n dot: true,\n onlyFiles: false,\n markDirectories: true,\n });\n\n const nonTemplatedEntries = new Set(\n (\n await Promise.all(\n (ctx.input.copyWithoutRender || []).map(pattern =>\n globby(pattern, {\n cwd: templateDir,\n dot: true,\n onlyFiles: false,\n markDirectories: true,\n }),\n ),\n )\n ).flat(),\n );\n\n // Cookiecutter prefixes all parameters in templates with\n // `cookiecutter.`. To replicate this, we wrap our parameters\n // in an object with a `cookiecutter` property when compat\n // mode is enabled.\n const { cookiecutterCompat, values } = ctx.input;\n const context = {\n [cookiecutterCompat ? 'cookiecutter' : 'values']: values,\n };\n\n ctx.logger.info(\n `Processing ${allEntriesInTemplate.length} template files/directories with input values`,\n ctx.input.values,\n );\n\n const renderTemplate = await SecureTemplater.loadRenderer({\n cookiecutterCompat: ctx.input.cookiecutterCompat,\n additionalTemplateFilters,\n });\n\n for (const location of allEntriesInTemplate) {\n let renderFilename: boolean;\n let renderContents: boolean;\n\n let localOutputPath = location;\n if (extension) {\n renderFilename = true;\n renderContents = extname(localOutputPath) === extension;\n if (renderContents) {\n localOutputPath = localOutputPath.slice(0, -extension.length);\n }\n } else {\n renderFilename = renderContents = !nonTemplatedEntries.has(location);\n }\n if (renderFilename) {\n localOutputPath = renderTemplate(localOutputPath, context);\n }\n const outputPath = resolveSafeChildPath(outputDir, localOutputPath);\n // variables have been expanded to make an empty file name\n // this is due to a conditional like if values.my_condition then file-name.txt else empty string so skip\n if (outputDir === outputPath) {\n continue;\n }\n\n if (!renderContents && !extension) {\n ctx.logger.info(\n `Copying file/directory ${location} without processing.`,\n );\n }\n\n if (location.endsWith('/')) {\n ctx.logger.info(\n `Writing directory ${location} to template output path.`,\n );\n await fs.ensureDir(outputPath);\n } else {\n const inputFilePath = resolveSafeChildPath(templateDir, location);\n\n if (await isBinaryFile(inputFilePath)) {\n ctx.logger.info(\n `Copying binary file ${location} to template output path.`,\n );\n await fs.copy(inputFilePath, outputPath);\n } else {\n const statsObj = await fs.stat(inputFilePath);\n ctx.logger.info(\n `Writing file ${location} to template output path with mode ${statsObj.mode}.`,\n );\n const inputFileContents = await fs.readFile(inputFilePath, 'utf-8');\n await fs.outputFile(\n outputPath,\n renderContents\n ? renderTemplate(inputFileContents, context)\n : inputFileContents,\n { mode: statsObj.mode },\n );\n }\n }\n }\n\n ctx.logger.info(`Template result written to ${outputDir}`);\n },\n });\n}\n","/*\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 */\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { InputError } from '@backstage/errors';\nimport { resolveSafeChildPath } from '@backstage/backend-common';\nimport fs from 'fs-extra';\n\n/**\n * Creates new action that enables deletion of files and directories in the workspace.\n * @public\n */\nexport const createFilesystemDeleteAction = () => {\n return createTemplateAction<{ files: string[] }>({\n id: 'fs:delete',\n description: 'Deletes files and directories from the workspace',\n schema: {\n input: {\n required: ['files'],\n type: 'object',\n properties: {\n files: {\n title: 'Files',\n description: 'A list of files and directories that will be deleted',\n type: 'array',\n items: {\n type: 'string',\n },\n },\n },\n },\n },\n async handler(ctx) {\n if (!Array.isArray(ctx.input?.files)) {\n throw new InputError('files must be an Array');\n }\n\n for (const file of ctx.input.files) {\n const filepath = resolveSafeChildPath(ctx.workspacePath, file);\n\n try {\n await fs.remove(filepath);\n ctx.logger.info(`File ${filepath} deleted successfully`);\n } catch (err) {\n ctx.logger.error(`Failed to delete file ${filepath}:`, err);\n throw err;\n }\n }\n },\n });\n};\n","/*\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 */\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { resolveSafeChildPath } from '@backstage/backend-common';\n\nimport { InputError } from '@backstage/errors';\nimport fs from 'fs-extra';\n\n/**\n * Creates a new action that allows renames of files and directories in the workspace.\n * @public\n */\nexport const createFilesystemRenameAction = () => {\n return createTemplateAction<{\n files: Array<{\n from: string;\n to: string;\n overwrite?: boolean;\n }>;\n }>({\n id: 'fs:rename',\n description: 'Renames files and directories within the workspace',\n schema: {\n input: {\n required: ['files'],\n type: 'object',\n properties: {\n files: {\n title: 'Files',\n description:\n 'A list of file and directory names that will be renamed',\n type: 'array',\n items: {\n type: 'object',\n required: ['from', 'to'],\n properties: {\n from: {\n type: 'string',\n title: 'The source location of the file to be renamed',\n },\n to: {\n type: 'string',\n title: 'The destination of the new file',\n },\n overwrite: {\n type: 'boolean',\n title:\n 'Overwrite existing file or directory, default is false',\n },\n },\n },\n },\n },\n },\n },\n async handler(ctx) {\n if (!Array.isArray(ctx.input?.files)) {\n throw new InputError('files must be an Array');\n }\n\n for (const file of ctx.input.files) {\n if (!file.from || !file.to) {\n throw new InputError('each file must have a from and to property');\n }\n\n const sourceFilepath = resolveSafeChildPath(\n ctx.workspacePath,\n file.from,\n );\n const destFilepath = resolveSafeChildPath(ctx.workspacePath, file.to);\n\n try {\n await fs.move(sourceFilepath, destFilepath, {\n overwrite: file.overwrite ?? false,\n });\n ctx.logger.info(\n `File ${sourceFilepath} renamed to ${destFilepath} successfully`,\n );\n } catch (err) {\n ctx.logger.error(\n `Failed to rename file ${sourceFilepath} to ${destFilepath}:`,\n err,\n );\n throw err;\n }\n }\n },\n });\n};\n","/*\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 { SpawnOptionsWithoutStdio, spawn } from 'child_process';\nimport { PassThrough, Writable } from 'stream';\nimport { Logger } from 'winston';\nimport { Git } from '@backstage/backend-common';\nimport { Octokit } from 'octokit';\nimport { assertError } from '@backstage/errors';\n\n/** @public */\nexport type RunCommandOptions = {\n /** command to run */\n command: string;\n /** arguments to pass the command */\n args: string[];\n /** options to pass to spawn */\n options?: SpawnOptionsWithoutStdio;\n /** stream to capture stdout and stderr output */\n logStream?: Writable;\n};\n\n/**\n * Run a command in a sub-process, normally a shell command.\n *\n * @public\n */\nexport const executeShellCommand = async (options: RunCommandOptions) => {\n const {\n command,\n args,\n options: spawnOptions,\n logStream = new PassThrough(),\n } = options;\n await new Promise<void>((resolve, reject) => {\n const process = spawn(command, args, spawnOptions);\n\n process.stdout.on('data', stream => {\n logStream.write(stream);\n });\n\n process.stderr.on('data', stream => {\n logStream.write(stream);\n });\n\n process.on('error', error => {\n return reject(error);\n });\n\n process.on('close', code => {\n if (code !== 0) {\n return reject(\n new Error(`Command ${command} failed, exit code: ${code}`),\n );\n }\n return resolve();\n });\n });\n};\n\nexport async function initRepoAndPush({\n dir,\n remoteUrl,\n auth,\n logger,\n defaultBranch = 'master',\n commitMessage = 'Initial commit',\n gitAuthorInfo,\n}: {\n dir: string;\n remoteUrl: string;\n auth: { username: string; password: string };\n logger: Logger;\n defaultBranch?: string;\n commitMessage?: string;\n gitAuthorInfo?: { name?: string; email?: string };\n}): Promise<void> {\n const git = Git.fromAuth({\n username: auth.username,\n password: auth.password,\n logger,\n });\n\n await git.init({\n dir,\n defaultBranch,\n });\n\n await git.add({ dir, filepath: '.' });\n\n // use provided info if possible, otherwise use fallbacks\n const authorInfo = {\n name: gitAuthorInfo?.name ?? 'Scaffolder',\n email: gitAuthorInfo?.email ?? 'scaffolder@backstage.io',\n };\n\n await git.commit({\n dir,\n message: commitMessage,\n author: authorInfo,\n committer: authorInfo,\n });\n\n await git.addRemote({\n dir,\n url: remoteUrl,\n remote: 'origin',\n });\n\n await git.push({\n dir,\n remote: 'origin',\n });\n}\n\ntype BranchProtectionOptions = {\n client: Octokit;\n owner: string;\n repoName: string;\n logger: Logger;\n requireCodeOwnerReviews: boolean;\n defaultBranch?: string;\n};\n\nexport const enableBranchProtectionOnDefaultRepoBranch = async ({\n repoName,\n client,\n owner,\n logger,\n requireCodeOwnerReviews,\n defaultBranch = 'master',\n}: BranchProtectionOptions): Promise<void> => {\n const tryOnce = async () => {\n try {\n await client.rest.repos.updateBranchProtection({\n mediaType: {\n /**\n * 👇 we need this preview because allowing a custom\n * reviewer count on branch protection is a preview\n * feature\n *\n * More here: https://docs.github.com/en/rest/overview/api-previews#require-multiple-approving-reviews\n */\n previews: ['luke-cage-preview'],\n },\n owner,\n repo: repoName,\n branch: defaultBranch,\n required_status_checks: { strict: true, contexts: [] },\n restrictions: null,\n enforce_admins: true,\n required_pull_request_reviews: {\n required_approving_review_count: 1,\n require_code_owner_reviews: requireCodeOwnerReviews,\n },\n });\n } catch (e) {\n assertError(e);\n if (\n e.message.includes(\n 'Upgrade to GitHub Pro or make this repository public to enable this feature',\n )\n ) {\n logger.warn(\n 'Branch protection was not enabled as it requires GitHub Pro for private repositories',\n );\n } else {\n throw e;\n }\n }\n };\n\n try {\n await tryOnce();\n } catch (e) {\n if (!e.message.includes('Branch not found')) {\n throw e;\n }\n\n // GitHub has eventual consistency. Fail silently, wait, and try again.\n await new Promise(resolve => setTimeout(resolve, 600));\n await tryOnce();\n }\n};\n","/*\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 { InputError } from '@backstage/errors';\nimport { isChildPath } from '@backstage/backend-common';\nimport { join as joinPath, normalize as normalizePath } from 'path';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\n\nexport const getRepoSourceDirectory = (\n workspacePath: string,\n sourcePath: string | undefined,\n) => {\n if (sourcePath) {\n const safeSuffix = normalizePath(sourcePath).replace(\n /^(\\.\\.(\\/|\\\\|$))+/,\n '',\n );\n const path = joinPath(workspacePath, safeSuffix);\n if (!isChildPath(workspacePath, path)) {\n throw new Error('Invalid source path');\n }\n return path;\n }\n return workspacePath;\n};\nexport type RepoSpec = {\n repo: string;\n host: string;\n owner?: string;\n organization?: string;\n workspace?: string;\n project?: string;\n};\n\nexport const parseRepoUrl = (\n repoUrl: string,\n integrations: ScmIntegrationRegistry,\n): RepoSpec => {\n let parsed;\n try {\n parsed = new URL(`https://${repoUrl}`);\n } catch (error) {\n throw new InputError(\n `Invalid repo URL passed to publisher, got ${repoUrl}, ${error}`,\n );\n }\n const host = parsed.host;\n const owner = parsed.searchParams.get('owner') ?? undefined;\n const organization = parsed.searchParams.get('organization') ?? undefined;\n const workspace = parsed.searchParams.get('workspace') ?? undefined;\n const project = parsed.searchParams.get('project') ?? undefined;\n\n const type = integrations.byHost(host)?.type;\n\n if (!type) {\n throw new InputError(\n `No matching integration configuration for host ${host}, please check your integrations config`,\n );\n }\n\n if (type === 'bitbucket') {\n if (host === 'bitbucket.org') {\n if (!workspace) {\n throw new InputError(\n `Invalid repo URL passed to publisher: ${repoUrl}, missing workspace`,\n );\n }\n }\n if (!project) {\n throw new InputError(\n `Invalid repo URL passed to publisher: ${repoUrl}, missing project`,\n );\n }\n } else {\n if (!owner) {\n throw new InputError(\n `Invalid repo URL passed to publisher: ${repoUrl}, missing owner`,\n );\n }\n }\n\n const repo = parsed.searchParams.get('repo');\n if (!repo) {\n throw new InputError(\n `Invalid repo URL passed to publisher: ${repoUrl}, missing repo`,\n );\n }\n\n return { host, owner, repo, organization, workspace, project };\n};\nexport const isExecutable = (fileMode: number) => {\n const executeBitMask = 0o000111;\n const res = fileMode & executeBitMask;\n return res > 0;\n};\n","/*\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 { InputError } from '@backstage/errors';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { initRepoAndPush } from '../helpers';\nimport { GitRepositoryCreateOptions } from 'azure-devops-node-api/interfaces/GitInterfaces';\nimport { getPersonalAccessTokenHandler, WebApi } from 'azure-devops-node-api';\nimport { getRepoSourceDirectory, parseRepoUrl } from './util';\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { Config } from '@backstage/config';\n\n/**\n * Creates a new action that initializes a git repository of the content in the workspace\n * and publishes it to Azure.\n * @public\n */\nexport function createPublishAzureAction(options: {\n integrations: ScmIntegrationRegistry;\n config: Config;\n}) {\n const { integrations, config } = options;\n\n return createTemplateAction<{\n repoUrl: string;\n description?: string;\n defaultBranch?: string;\n sourcePath?: string;\n token?: string;\n }>({\n id: 'publish:azure',\n description:\n 'Initializes a git repository of the content in the workspace, and publishes it to Azure.',\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n type: 'string',\n },\n description: {\n title: 'Repository Description',\n type: 'string',\n },\n defaultBranch: {\n title: 'Default Branch',\n type: 'string',\n description: `Sets the default branch on the repository. The default value is 'master'`,\n },\n sourcePath: {\n title: 'Source Path',\n description:\n 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.',\n type: 'string',\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The token to use for authorization to Azure',\n },\n },\n },\n output: {\n type: 'object',\n properties: {\n remoteUrl: {\n title: 'A URL to the repository with the provider',\n type: 'string',\n },\n repoContentsUrl: {\n title: 'A URL to the root of the repository',\n type: 'string',\n },\n },\n },\n },\n async handler(ctx) {\n const { repoUrl, defaultBranch = 'master' } = ctx.input;\n\n const { owner, repo, host, organization } = parseRepoUrl(\n repoUrl,\n integrations,\n );\n\n if (!organization) {\n throw new InputError(\n `Invalid URL provider was included in the repo URL to create ${ctx.input.repoUrl}, missing organization`,\n );\n }\n\n const integrationConfig = integrations.azure.byHost(host);\n\n if (!integrationConfig) {\n throw new InputError(\n `No matching integration configuration for host ${host}, please check your integrations config`,\n );\n }\n\n if (!integrationConfig.config.token && !ctx.input.token) {\n throw new InputError(`No token provided for Azure Integration ${host}`);\n }\n\n const token = ctx.input.token ?? integrationConfig.config.token!;\n const authHandler = getPersonalAccessTokenHandler(token);\n\n const webApi = new WebApi(`https://${host}/${organization}`, authHandler);\n const client = await webApi.getGitApi();\n const createOptions: GitRepositoryCreateOptions = { name: repo };\n const returnedRepo = await client.createRepository(createOptions, owner);\n\n if (!returnedRepo) {\n throw new InputError(\n `Unable to create the repository with Organization ${organization}, Project ${owner} and Repo ${repo}.\n Please make sure that both the Org and Project are typed corrected and exist.`,\n );\n }\n const remoteUrl = returnedRepo.remoteUrl;\n\n if (!remoteUrl) {\n throw new InputError(\n 'No remote URL returned from create repository for Azure',\n );\n }\n\n // blam: Repo contents is serialized into the path,\n // so it's just the base path I think\n const repoContentsUrl = remoteUrl;\n\n const gitAuthorInfo = {\n name: config.getOptionalString('scaffolder.defaultAuthor.name'),\n email: config.getOptionalString('scaffolder.defaultAuthor.email'),\n };\n\n await initRepoAndPush({\n dir: getRepoSourceDirectory(ctx.workspacePath, ctx.input.sourcePath),\n remoteUrl,\n defaultBranch,\n auth: {\n username: 'notempty',\n password: token,\n },\n logger: ctx.logger,\n commitMessage: config.getOptionalString(\n 'scaffolder.defaultCommitMessage',\n ),\n gitAuthorInfo,\n });\n\n ctx.output('remoteUrl', remoteUrl);\n ctx.output('repoContentsUrl', repoContentsUrl);\n },\n });\n}\n","/*\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 { InputError } from '@backstage/errors';\nimport {\n BitbucketIntegrationConfig,\n ScmIntegrationRegistry,\n} from '@backstage/integration';\nimport fetch, { Response, RequestInit } from 'node-fetch';\nimport { initRepoAndPush } from '../helpers';\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { getRepoSourceDirectory, parseRepoUrl } from './util';\nimport { Config } from '@backstage/config';\n\nconst createBitbucketCloudRepository = async (opts: {\n workspace: string;\n project: string;\n repo: string;\n description?: string;\n repoVisibility: 'private' | 'public';\n mainBranch: string;\n authorization: string;\n apiBaseUrl: string;\n}) => {\n const {\n workspace,\n project,\n repo,\n description,\n repoVisibility,\n mainBranch,\n authorization,\n apiBaseUrl,\n } = opts;\n\n const options: RequestInit = {\n method: 'POST',\n body: JSON.stringify({\n scm: 'git',\n description: description,\n is_private: repoVisibility === 'private',\n project: { key: project },\n }),\n headers: {\n Authorization: authorization,\n 'Content-Type': 'application/json',\n },\n };\n\n let response: Response;\n try {\n response = await fetch(\n `${apiBaseUrl}/repositories/${workspace}/${repo}`,\n options,\n );\n } catch (e) {\n throw new Error(`Unable to create repository, ${e}`);\n }\n\n if (response.status !== 200) {\n throw new Error(\n `Unable to create repository, ${response.status} ${\n response.statusText\n }, ${await response.text()}`,\n );\n }\n\n const r = await response.json();\n let remoteUrl = '';\n for (const link of r.links.clone) {\n if (link.name === 'https') {\n remoteUrl = link.href;\n }\n }\n\n // \"mainbranch.name\" cannot be set neither at create nor update of the repo\n // the first pushed branch will be set as \"main branch\" then\n const repoContentsUrl = `${r.links.html.href}/src/${mainBranch}`;\n return { remoteUrl, repoContentsUrl };\n};\n\nconst createBitbucketServerRepository = async (opts: {\n project: string;\n repo: string;\n description?: string;\n repoVisibility: 'private' | 'public';\n authorization: string;\n apiBaseUrl: string;\n}) => {\n const {\n project,\n repo,\n description,\n authorization,\n repoVisibility,\n apiBaseUrl,\n } = opts;\n\n let response: Response;\n const options: RequestInit = {\n method: 'POST',\n body: JSON.stringify({\n name: repo,\n description: description,\n public: repoVisibility === 'public',\n }),\n headers: {\n Authorization: authorization,\n 'Content-Type': 'application/json',\n },\n };\n\n try {\n response = await fetch(`${apiBaseUrl}/projects/${project}/repos`, options);\n } catch (e) {\n throw new Error(`Unable to create repository, ${e}`);\n }\n\n if (response.status !== 201) {\n throw new Error(\n `Unable to create repository, ${response.status} ${\n response.statusText\n }, ${await response.text()}`,\n );\n }\n\n const r = await response.json();\n let remoteUrl = '';\n for (const link of r.links.clone) {\n if (link.name === 'http') {\n remoteUrl = link.href;\n }\n }\n\n const repoContentsUrl = `${r.links.self[0].href}`;\n return { remoteUrl, repoContentsUrl };\n};\n\nconst getAuthorizationHeader = (config: BitbucketIntegrationConfig) => {\n if (config.username && config.appPassword) {\n const buffer = Buffer.from(\n `${config.username}:${config.appPassword}`,\n 'utf8',\n );\n\n return `Basic ${buffer.toString('base64')}`;\n }\n\n if (config.token) {\n return `Bearer ${config.token}`;\n }\n\n throw new Error(\n `Authorization has not been provided for Bitbucket. Please add either username + appPassword or token to the Integrations config`,\n );\n};\n\nconst performEnableLFS = async (opts: {\n authorization: string;\n host: string;\n project: string;\n repo: string;\n}) => {\n const { authorization, host, project, repo } = opts;\n\n const options: RequestInit = {\n method: 'PUT',\n headers: {\n Authorization: authorization,\n },\n };\n\n const { ok, status, statusText } = await fetch(\n `https://${host}/rest/git-lfs/admin/projects/${project}/repos/${repo}/enabled`,\n options,\n );\n\n if (!ok)\n throw new Error(\n `Failed to enable LFS in the repository, ${status}: ${statusText}`,\n );\n};\n\n/**\n * Creates a new action that initializes a git repository of the content in the workspace\n * and publishes it to Bitbucket.\n * @public\n */\nexport function createPublishBitbucketAction(options: {\n integrations: ScmIntegrationRegistry;\n config: Config;\n}) {\n const { integrations, config } = options;\n\n return createTemplateAction<{\n repoUrl: string;\n description?: string;\n defaultBranch?: string;\n repoVisibility?: 'private' | 'public';\n sourcePath?: string;\n enableLFS?: boolean;\n token?: string;\n }>({\n id: 'publish:bitbucket',\n description:\n 'Initializes a git repository of the content in the workspace, and publishes it to Bitbucket.',\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n type: 'string',\n },\n description: {\n title: 'Repository Description',\n type: 'string',\n },\n repoVisibility: {\n title: 'Repository Visibility',\n type: 'string',\n enum: ['private', 'public'],\n },\n defaultBranch: {\n title: 'Default Branch',\n type: 'string',\n description: `Sets the default branch on the repository. The default value is 'master'`,\n },\n sourcePath: {\n title: 'Source Path',\n description:\n 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.',\n type: 'string',\n },\n enableLFS: {\n title: 'Enable LFS?',\n description:\n 'Enable LFS for the repository. Only available for hosted Bitbucket.',\n type: 'boolean',\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The token to use for authorization to BitBucket',\n },\n },\n },\n output: {\n type: 'object',\n properties: {\n remoteUrl: {\n title: 'A URL to the repository with the provider',\n type: 'string',\n },\n repoContentsUrl: {\n title: 'A URL to the root of the repository',\n type: 'string',\n },\n },\n },\n },\n async handler(ctx) {\n const {\n repoUrl,\n description,\n defaultBranch = 'master',\n repoVisibility = 'private',\n enableLFS = false,\n } = ctx.input;\n\n const { workspace, project, repo, host } = parseRepoUrl(\n repoUrl,\n integrations,\n );\n\n // Workspace is only required for bitbucket cloud\n if (host === 'bitbucket.org') {\n if (!workspace) {\n throw new InputError(\n `Invalid URL provider was included in the repo URL to create ${ctx.input.repoUrl}, missing workspace`,\n );\n }\n }\n\n // Project is required for both bitbucket cloud and bitbucket server\n if (!project) {\n throw new InputError(\n `Invalid URL provider was included in the repo URL to create ${ctx.input.repoUrl}, missing project`,\n );\n }\n\n const integrationConfig = integrations.bitbucket.byHost(host);\n\n if (!integrationConfig) {\n throw new InputError(\n `No matching integration configuration for host ${host}, please check your integrations config`,\n );\n }\n\n const authorization = getAuthorizationHeader(\n ctx.input.token\n ? {\n host: integrationConfig.config.host,\n apiBaseUrl: integrationConfig.config.apiBaseUrl,\n token: ctx.input.token,\n }\n : integrationConfig.config,\n );\n\n const apiBaseUrl = integrationConfig.config.apiBaseUrl;\n\n const createMethod =\n host === 'bitbucket.org'\n ? createBitbucketCloudRepository\n : createBitbucketServerRepository;\n\n const { remoteUrl, repoContentsUrl } = await createMethod({\n authorization,\n workspace: workspace || '',\n project,\n repo,\n repoVisibility,\n mainBranch: defaultBranch,\n description,\n apiBaseUrl,\n });\n\n const gitAuthorInfo = {\n name: config.getOptionalString('scaffolder.defaultAuthor.name'),\n email: config.getOptionalString('scaffolder.defaultAuthor.email'),\n };\n\n let auth;\n\n if (ctx.input.token) {\n auth = {\n username: 'x-token-auth',\n password: ctx.input.token,\n };\n } else {\n auth = {\n username: integrationConfig.config.username\n ? integrationConfig.config.username\n : 'x-token-auth',\n password: integrationConfig.config.appPassword\n ? integrationConfig.config.appPassword\n : integrationConfig.config.token ?? '',\n };\n }\n\n await initRepoAndPush({\n dir: getRepoSourceDirectory(ctx.workspacePath, ctx.input.sourcePath),\n remoteUrl,\n auth,\n defaultBranch,\n logger: ctx.logger,\n commitMessage: config.getOptionalString(\n 'scaffolder.defaultCommitMessage',\n ),\n gitAuthorInfo,\n });\n\n if (enableLFS && host !== 'bitbucket.org') {\n await performEnableLFS({ authorization, host, project, repo });\n }\n\n ctx.output('remoteUrl', remoteUrl);\n ctx.output('repoContentsUrl', repoContentsUrl);\n },\n });\n}\n","/*\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 fs from 'fs-extra';\nimport { dirname } from 'path';\nimport { InputError } from '@backstage/errors';\nimport { createTemplateAction } from '../../createTemplateAction';\n\n/**\n * This task is useful for local development and testing of both the scaffolder\n * and scaffolder templates.\n *\n * @remarks\n *\n * This action is not installed by default and should not be installed in\n * production, as it writes the files to the local filesystem of the scaffolder.\n *\n * @public\n */\nexport function createPublishFileAction() {\n return createTemplateAction<{ path: string }>({\n id: 'publish:file',\n description: 'Writes contents of the workspace to a local directory',\n schema: {\n input: {\n type: 'object',\n required: ['path'],\n properties: {\n path: {\n title: 'Path to a directory where the output will be written',\n type: 'string',\n },\n },\n },\n },\n async handler(ctx) {\n const { path } = ctx.input;\n\n const exists = await fs.pathExists(path);\n if (exists) {\n throw new InputError('Output path already exists');\n }\n await fs.ensureDir(dirname(path));\n await fs.copy(ctx.workspacePath, path);\n },\n });\n}\n","/*\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 */\nimport { InputError } from '@backstage/errors';\nimport {\n DefaultGithubCredentialsProvider,\n GithubCredentialsProvider,\n ScmIntegrationRegistry,\n} from '@backstage/integration';\nimport { OctokitOptions } from '@octokit/core/dist-types/types';\nimport { parseRepoUrl } from '../publish/util';\n\nconst DEFAULT_TIMEOUT_MS = 60_000;\n\nexport async function getOctokitOptions(options: {\n integrations: ScmIntegrationRegistry;\n credentialsProvider?: GithubCredentialsProvider;\n token?: string;\n repoUrl: string;\n}): Promise<OctokitOptions> {\n const { integrations, credentialsProvider, repoUrl, token } = options;\n const { owner, repo, host } = parseRepoUrl(repoUrl, integrations);\n\n const requestOptions = {\n // set timeout to 60 seconds\n timeout: DEFAULT_TIMEOUT_MS,\n };\n\n if (!owner) {\n throw new InputError(`No owner provided for repo ${repoUrl}`);\n }\n\n const integrationConfig = integrations.github.byHost(host)?.config;\n\n if (!integrationConfig) {\n throw new InputError(`No integration for host ${host}`);\n }\n\n // short circuit the `githubCredentialsProvider` if there is a token provided by the caller already\n if (token) {\n return {\n auth: token,\n baseUrl: integrationConfig.apiBaseUrl,\n previews: ['nebula-preview'],\n request: requestOptions,\n };\n }\n\n const githubCredentialsProvider =\n credentialsProvider ??\n DefaultGithubCredentialsProvider.fromIntegrations(integrations);\n\n // TODO(blam): Consider changing this API to take host and repo instead of repoUrl, as we end up parsing in this function\n // and then parsing in the `getCredentials` function too the other side\n const { token: credentialProviderToken } =\n await githubCredentialsProvider.getCredentials({\n url: `https://${host}/${encodeURIComponent(owner)}/${encodeURIComponent(\n repo,\n )}`,\n });\n\n if (!credentialProviderToken) {\n throw new InputError(\n `No token available for host: ${host}, with owner ${owner}, and repo ${repo}`,\n );\n }\n\n return {\n auth: credentialProviderToken,\n baseUrl: integrationConfig.apiBaseUrl,\n previews: ['nebula-preview'],\n };\n}\n","/*\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 */\nimport {\n GithubCredentialsProvider,\n ScmIntegrationRegistry,\n} from '@backstage/integration';\nimport {\n enableBranchProtectionOnDefaultRepoBranch,\n initRepoAndPush,\n} from '../helpers';\nimport { getRepoSourceDirectory, parseRepoUrl } from './util';\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { Config } from '@backstage/config';\nimport { assertError, InputError } from '@backstage/errors';\nimport { getOctokitOptions } from '../github/helpers';\nimport { Octokit } from 'octokit';\n\n/**\n * Creates a new action that initializes a git repository of the content in the workspace\n * and publishes it to GitHub.\n *\n * @public\n */\nexport function createPublishGithubAction(options: {\n integrations: ScmIntegrationRegistry;\n config: Config;\n githubCredentialsProvider?: GithubCredentialsProvider;\n}) {\n const { integrations, config, githubCredentialsProvider } = options;\n\n return createTemplateAction<{\n repoUrl: string;\n description?: string;\n access?: string;\n defaultBranch?: string;\n deleteBranchOnMerge?: boolean;\n allowRebaseMerge?: boolean;\n allowSquashMerge?: boolean;\n allowMergeCommit?: boolean;\n sourcePath?: string;\n requireCodeOwnerReviews?: boolean;\n repoVisibility?: 'private' | 'internal' | 'public';\n collaborators?: Array<{\n username: string;\n access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage';\n }>;\n token?: string;\n topics?: string[];\n }>({\n id: 'publish:github',\n description:\n 'Initializes a git repository of contents in workspace and publishes it to GitHub.',\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the new repository name and 'owner' is an organization or username`,\n type: 'string',\n },\n description: {\n title: 'Repository Description',\n type: 'string',\n },\n access: {\n title: 'Repository Access',\n description: `Sets an admin collaborator on the repository. Can either be a user reference different from 'owner' in 'repoUrl' or team reference, eg. 'org/team-name'`,\n type: 'string',\n },\n requireCodeOwnerReviews: {\n title: 'Require CODEOWNER Reviews?',\n description:\n 'Require an approved review in PR including files with a designated Code Owner',\n type: 'boolean',\n },\n repoVisibility: {\n title: 'Repository Visibility',\n type: 'string',\n enum: ['private', 'public', 'internal'],\n },\n defaultBranch: {\n title: 'Default Branch',\n type: 'string',\n description: `Sets the default branch on the repository. The default value is 'master'`,\n },\n deleteBranchOnMerge: {\n title: 'Delete Branch On Merge',\n type: 'boolean',\n description: `Delete the branch after merging the PR. The default value is 'false'`,\n },\n allowMergeCommit: {\n title: 'Allow Merge Commits',\n type: 'boolean',\n description: `Allow merge commits. The default value is 'true'`,\n },\n allowSquashMerge: {\n title: 'Allow Squash Merges',\n type: 'boolean',\n description: `Allow squash merges. The default value is 'true'`,\n },\n allowRebaseMerge: {\n title: 'Allow Rebase Merges',\n type: 'boolean',\n description: `Allow rebase merges. The default value is 'true'`,\n },\n sourcePath: {\n title: 'Source Path',\n description:\n 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.',\n type: 'string',\n },\n collaborators: {\n title: 'Collaborators',\n description: 'Provide additional users with permissions',\n type: 'array',\n items: {\n type: 'object',\n required: ['username', 'access'],\n properties: {\n access: {\n type: 'string',\n description: 'The type of access for the user',\n enum: ['push', 'pull', 'admin', 'maintain', 'triage'],\n },\n username: {\n type: 'string',\n description: 'The username or group',\n },\n },\n },\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The token to use for authorization to GitHub',\n },\n topics: {\n title: 'Topics',\n type: 'array',\n items: {\n type: 'string',\n },\n },\n },\n },\n output: {\n type: 'object',\n properties: {\n remoteUrl: {\n title: 'A URL to the repository with the provider',\n type: 'string',\n },\n repoContentsUrl: {\n title: 'A URL to the root of the repository',\n type: 'string',\n },\n },\n },\n },\n async handler(ctx) {\n const {\n repoUrl,\n description,\n access,\n requireCodeOwnerReviews = false,\n repoVisibility = 'private',\n defaultBranch = 'master',\n deleteBranchOnMerge = false,\n allowMergeCommit = true,\n allowSquashMerge = true,\n allowRebaseMerge = true,\n collaborators,\n topics,\n token: providedToken,\n } = ctx.input;\n\n const { owner, repo } = parseRepoUrl(repoUrl, integrations);\n\n if (!owner) {\n throw new InputError('Invalid repository owner provided in repoUrl');\n }\n\n const octokitOptions = await getOctokitOptions({\n integrations,\n credentialsProvider: githubCredentialsProvider,\n token: providedToken,\n repoUrl,\n });\n\n const client = new Octokit(octokitOptions);\n\n const user = await client.rest.users.getByUsername({\n username: owner,\n });\n\n const repoCreationPromise =\n user.data.type === 'Organization'\n ? client.rest.repos.createInOrg({\n name: repo,\n org: owner,\n private: repoVisibility === 'private',\n visibility: repoVisibility,\n description: description,\n delete_branch_on_merge: deleteBranchOnMerge,\n allow_merge_commit: allowMergeCommit,\n allow_squash_merge: allowSquashMerge,\n allow_rebase_merge: allowRebaseMerge,\n })\n : client.rest.repos.createForAuthenticatedUser({\n name: repo,\n private: repoVisibility === 'private',\n description: description,\n delete_branch_on_merge: deleteBranchOnMerge,\n allow_merge_commit: allowMergeCommit,\n allow_squash_merge: allowSquashMerge,\n allow_rebase_merge: allowRebaseMerge,\n });\n\n const { data: newRepo } = await repoCreationPromise;\n if (access?.startsWith(`${owner}/`)) {\n const [, team] = access.split('/');\n await client.rest.teams.addOrUpdateRepoPermissionsInOrg({\n org: owner,\n team_slug: team,\n owner,\n repo,\n permission: 'admin',\n });\n // No need to add access if it's the person who owns the personal account\n } else if (access && access !== owner) {\n await client.rest.repos.addCollaborator({\n owner,\n repo,\n username: access,\n permission: 'admin',\n });\n }\n\n if (collaborators) {\n for (const {\n access: permission,\n username: team_slug,\n } of collaborators) {\n try {\n await client.rest.teams.addOrUpdateRepoPermissionsInOrg({\n org: owner,\n team_slug,\n owner,\n repo,\n permission,\n });\n } catch (e) {\n assertError(e);\n ctx.logger.warn(\n `Skipping ${permission} access for ${team_slug}, ${e.message}`,\n );\n }\n }\n }\n\n if (topics) {\n try {\n await client.rest.repos.replaceAllTopics({\n owner,\n repo,\n names: topics.map(t => t.toLowerCase()),\n });\n } catch (e) {\n assertError(e);\n ctx.logger.warn(`Skipping topics ${topics.join(' ')}, ${e.message}`);\n }\n }\n\n const remoteUrl = newRepo.clone_url;\n const repoContentsUrl = `${newRepo.html_url}/blob/${defaultBranch}`;\n\n const gitAuthorInfo = {\n name: config.getOptionalString('scaffolder.defaultAuthor.name'),\n email: config.getOptionalString('scaffolder.defaultAuthor.email'),\n };\n\n await initRepoAndPush({\n dir: getRepoSourceDirectory(ctx.workspacePath, ctx.input.sourcePath),\n remoteUrl,\n defaultBranch,\n auth: {\n username: 'x-access-token',\n password: octokitOptions.auth,\n },\n logger: ctx.logger,\n commitMessage: config.getOptionalString(\n 'scaffolder.defaultCommitMessage',\n ),\n gitAuthorInfo,\n });\n\n try {\n await enableBranchProtectionOnDefaultRepoBranch({\n owner,\n client,\n repoName: newRepo.name,\n logger: ctx.logger,\n defaultBranch,\n requireCodeOwnerReviews,\n });\n } catch (e) {\n assertError(e);\n ctx.logger.warn(\n `Skipping: default branch protection on '${newRepo.name}', ${e.message}`,\n );\n }\n\n ctx.output('remoteUrl', remoteUrl);\n ctx.output('repoContentsUrl', repoContentsUrl);\n },\n });\n}\n","/*\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 fs from 'fs-extra';\nimport { parseRepoUrl, isExecutable } from './util';\n\nimport {\n GithubCredentialsProvider,\n ScmIntegrationRegistry,\n} from '@backstage/integration';\nimport { zipObject } from 'lodash';\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { Octokit } from 'octokit';\nimport { InputError, CustomErrorBase } from '@backstage/errors';\nimport { createPullRequest } from 'octokit-plugin-create-pull-request';\nimport globby from 'globby';\nimport { resolveSafeChildPath } from '@backstage/backend-common';\nimport { getOctokitOptions } from '../github/helpers';\n\nexport type Encoding = 'utf-8' | 'base64';\n\nclass GithubResponseError extends CustomErrorBase {}\n\n/** @public */\nexport interface OctokitWithPullRequestPluginClient {\n createPullRequest(options: createPullRequest.Options): Promise<{\n data: {\n html_url: string;\n number: number;\n };\n } | null>;\n}\n\n/**\n * The options passed to the client factory function.\n * @public\n */\nexport type CreateGithubPullRequestClientFactoryInput = {\n integrations: ScmIntegrationRegistry;\n githubCredentialsProvider?: GithubCredentialsProvider;\n host: string;\n owner: string;\n repo: string;\n token?: string;\n};\n\nexport const defaultClientFactory = async ({\n integrations,\n githubCredentialsProvider,\n owner,\n repo,\n host = 'github.com',\n token: providedToken,\n}: CreateGithubPullRequestClientFactoryInput): Promise<OctokitWithPullRequestPluginClient> => {\n const [encodedHost, encodedOwner, encodedRepo] = [host, owner, repo].map(\n encodeURIComponent,\n );\n\n const octokitOptions = await getOctokitOptions({\n integrations,\n credentialsProvider: githubCredentialsProvider,\n repoUrl: `${encodedHost}?owner=${encodedOwner}&repo=${encodedRepo}`,\n token: providedToken,\n });\n\n const OctokitPR = Octokit.plugin(createPullRequest);\n return new OctokitPR(octokitOptions);\n};\n\n/**\n * The options passed to {@link createPublishGithubPullRequestAction} method\n * @public\n */\nexport interface CreateGithubPullRequestActionOptions {\n /**\n * An instance of {@link @backstage/integration#ScmIntegrationRegistry} that will be used in the action.\n */\n integrations: ScmIntegrationRegistry;\n /**\n * An instance of {@link @backstage/integration#GithubCredentialsProvider} that will be used to get credentials for the action.\n */\n githubCredentialsProvider?: GithubCredentialsProvider;\n /**\n * A method to return the Octokit client with the Pull Request Plugin.\n */\n clientFactory?: (\n input: CreateGithubPullRequestClientFactoryInput,\n ) => Promise<OctokitWithPullRequestPluginClient>;\n}\n\n/**\n * Creates a Github Pull Request action.\n * @public\n */\nexport const createPublishGithubPullRequestAction = ({\n integrations,\n githubCredentialsProvider,\n clientFactory = defaultClientFactory,\n}: CreateGithubPullRequestActionOptions) => {\n return createTemplateAction<{\n title: string;\n branchName: string;\n description: string;\n repoUrl: string;\n targetPath?: string;\n sourcePath?: string;\n token?: string;\n }>({\n id: 'publish:github:pull-request',\n schema: {\n input: {\n required: ['repoUrl', 'title', 'description', 'branchName'],\n type: 'object',\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the repository name and 'owner' is an organization or username`,\n type: 'string',\n },\n branchName: {\n type: 'string',\n title: 'Branch Name',\n description: 'The name for the branch',\n },\n title: {\n type: 'string',\n title: 'Pull Request Name',\n description: 'The name for the pull request',\n },\n description: {\n type: 'string',\n title: 'Pull Request Description',\n description: 'The description of the pull request',\n },\n sourcePath: {\n type: 'string',\n title: 'Working Subdirectory',\n description:\n 'Subdirectory of working directory to copy changes from',\n },\n targetPath: {\n type: 'string',\n title: 'Repository Subdirectory',\n description: 'Subdirectory of repository to apply changes to',\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The token to use for authorization to GitHub',\n },\n },\n },\n output: {\n required: ['remoteUrl'],\n type: 'object',\n properties: {\n remoteUrl: {\n type: 'string',\n title: 'Pull Request URL',\n description: 'Link to the pull request in Github',\n },\n pullRequestNumber: {\n type: 'number',\n title: 'Pull Request Number',\n description: 'The pull request number',\n },\n },\n },\n },\n async handler(ctx) {\n const {\n repoUrl,\n branchName,\n title,\n description,\n targetPath,\n sourcePath,\n token: providedToken,\n } = ctx.input;\n\n const { owner, repo, host } = parseRepoUrl(repoUrl, integrations);\n\n if (!owner) {\n throw new InputError(\n `No owner provided for host: ${host}, and repo ${repo}`,\n );\n }\n\n const client = await clientFactory({\n integrations,\n githubCredentialsProvider,\n host,\n owner,\n repo,\n token: providedToken,\n });\n\n const fileRoot = sourcePath\n ? resolveSafeChildPath(ctx.workspacePath, sourcePath)\n : ctx.workspacePath;\n\n const localFilePaths = await globby(['./**', './**/.*', '!.git'], {\n cwd: fileRoot,\n gitignore: true,\n dot: true,\n });\n\n const fileContents = await Promise.all(\n localFilePaths.map(filePath => {\n const absPath = resolveSafeChildPath(fileRoot, filePath);\n const base64EncodedContent = fs\n .readFileSync(absPath)\n .toString('base64');\n const fileStat = fs.statSync(absPath);\n // See the properties of tree items\n // in https://docs.github.com/en/rest/reference/git#trees\n const githubTreeItemMode = isExecutable(fileStat.mode)\n ? '100755'\n : '100644';\n // Always use base64 encoding to avoid doubling a binary file in size\n // due to interpreting a binary file as utf-8 and sending github\n // the utf-8 encoded content.\n //\n // For example, the original gradle-wrapper.jar is 57.8k in https://github.com/kennethzfeng/pull-request-test/pull/5/files.\n // Its size could be doubled to 98.3K (See https://github.com/kennethzfeng/pull-request-test/pull/4/files)\n const encoding: Encoding = 'base64';\n return {\n encoding: encoding,\n content: base64EncodedContent,\n mode: githubTreeItemMode,\n };\n }),\n );\n\n const repoFilePaths = localFilePaths.map(repoFilePath => {\n return targetPath ? `${targetPath}/${repoFilePath}` : repoFilePath;\n });\n\n const changes = [\n {\n files: zipObject(repoFilePaths, fileContents),\n commit: title,\n },\n ];\n\n try {\n const response = await client.createPullRequest({\n owner,\n repo,\n title,\n changes,\n body: description,\n head: branchName,\n });\n\n if (!response) {\n throw new GithubResponseError('null response from Github');\n }\n\n ctx.output('remoteUrl', response.data.html_url);\n ctx.output('pullRequestNumber', response.data.number);\n } catch (e) {\n throw new GithubResponseError('Pull request creation failed', e);\n }\n },\n });\n};\n","/*\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 { InputError } from '@backstage/errors';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { Gitlab } from '@gitbeaker/node';\nimport { initRepoAndPush } from '../helpers';\nimport { getRepoSourceDirectory, parseRepoUrl } from './util';\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { Config } from '@backstage/config';\n\n/**\n * Creates a new action that initializes a git repository of the content in the workspace\n * and publishes it to GitLab.\n *\n * @public\n */\nexport function createPublishGitlabAction(options: {\n integrations: ScmIntegrationRegistry;\n config: Config;\n}) {\n const { integrations, config } = options;\n\n return createTemplateAction<{\n repoUrl: string;\n defaultBranch?: string;\n repoVisibility?: 'private' | 'internal' | 'public';\n sourcePath?: string;\n token?: string;\n }>({\n id: 'publish:gitlab',\n description:\n 'Initializes a git repository of the content in the workspace, and publishes it to GitLab.',\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n type: 'string',\n },\n repoVisibility: {\n title: 'Repository Visibility',\n type: 'string',\n enum: ['private', 'public', 'internal'],\n },\n defaultBranch: {\n title: 'Default Branch',\n type: 'string',\n description: `Sets the default branch on the repository. The default value is 'master'`,\n },\n sourcePath: {\n title: 'Source Path',\n description:\n 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.',\n type: 'string',\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The token to use for authorization to GitLab',\n },\n },\n },\n output: {\n type: 'object',\n properties: {\n remoteUrl: {\n title: 'A URL to the repository with the provider',\n type: 'string',\n },\n repoContentsUrl: {\n title: 'A URL to the root of the repository',\n type: 'string',\n },\n },\n },\n },\n async handler(ctx) {\n const {\n repoUrl,\n repoVisibility = 'private',\n defaultBranch = 'master',\n } = ctx.input;\n\n const { owner, repo, host } = parseRepoUrl(repoUrl, integrations);\n\n if (!owner) {\n throw new InputError(\n `No owner provided for host: ${host}, and repo ${repo}`,\n );\n }\n\n const integrationConfig = integrations.gitlab.byHost(host);\n\n if (!integrationConfig) {\n throw new InputError(\n `No matching integration configuration for host ${host}, please check your integrations config`,\n );\n }\n\n if (!integrationConfig.config.token && !ctx.input.token) {\n throw new InputError(`No token available for host ${host}`);\n }\n\n const token = ctx.input.token || integrationConfig.config.token!;\n const tokenType = ctx.input.token ? 'oauthToken' : 'token';\n\n const client = new Gitlab({\n host: integrationConfig.config.baseUrl,\n [tokenType]: token,\n });\n\n let { id: targetNamespace } = (await client.Namespaces.show(owner)) as {\n id: number;\n };\n\n if (!targetNamespace) {\n const { id } = (await client.Users.current()) as {\n id: number;\n };\n targetNamespace = id;\n }\n\n const { http_url_to_repo } = await client.Projects.create({\n namespace_id: targetNamespace,\n name: repo,\n visibility: repoVisibility,\n });\n\n const remoteUrl = (http_url_to_repo as string).replace(/\\.git$/, '');\n const repoContentsUrl = `${remoteUrl}/-/blob/${defaultBranch}`;\n\n const gitAuthorInfo = {\n name: config.getOptionalString('scaffolder.defaultAuthor.name'),\n email: config.getOptionalString('scaffolder.defaultAuthor.email'),\n };\n\n await initRepoAndPush({\n dir: getRepoSourceDirectory(ctx.workspacePath, ctx.input.sourcePath),\n remoteUrl: http_url_to_repo as string,\n defaultBranch,\n auth: {\n username: 'oauth2',\n password: token,\n },\n logger: ctx.logger,\n commitMessage: config.getOptionalString(\n 'scaffolder.defaultCommitMessage',\n ),\n gitAuthorInfo,\n });\n\n ctx.output('remoteUrl', remoteUrl);\n ctx.output('repoContentsUrl', repoContentsUrl);\n },\n });\n}\n","/*\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 */\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { readFile } from 'fs-extra';\nimport { Gitlab } from '@gitbeaker/node';\nimport globby from 'globby';\nimport { Types } from '@gitbeaker/core';\n\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { InputError } from '@backstage/errors';\nimport { parseRepoUrl } from './util';\nimport { resolveSafeChildPath } from '@backstage/backend-common';\n\n/**\n * Create a new action that creates a gitlab merge request.\n *\n * @public\n */\nexport const createPublishGitlabMergeRequestAction = (options: {\n integrations: ScmIntegrationRegistry;\n}) => {\n const { integrations } = options;\n\n return createTemplateAction<{\n projectid: string;\n repoUrl: string;\n title: string;\n description: string;\n branchName: string;\n targetPath: string;\n token?: string;\n }>({\n id: 'publish:gitlab:merge-request',\n schema: {\n input: {\n required: ['projectid', 'repoUrl', 'targetPath', 'branchName'],\n type: 'object',\n properties: {\n repoUrl: {\n type: 'string',\n title: 'Repository Location',\n description: `Accepts the format 'gitlab.com/group_name/project_name' where 'project_name' is the repository name and 'group_name' is a group or username`,\n },\n projectid: {\n type: 'string',\n title: 'projectid',\n description: 'Project ID/Name(slug) of the Gitlab Project',\n },\n title: {\n type: 'string',\n title: 'Merge Request Name',\n description: 'The name for the merge request',\n },\n description: {\n type: 'string',\n title: 'Merge Request Description',\n description: 'The description of the merge request',\n },\n branchName: {\n type: 'string',\n title: 'Destination Branch name',\n description: 'The description of the merge request',\n },\n targetPath: {\n type: 'string',\n title: 'Repository Subdirectory',\n description: 'Subdirectory of repository to apply changes to',\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The token to use for authorization to GitLab',\n },\n },\n },\n output: {\n type: 'object',\n properties: {\n projectid: {\n title: 'Gitlab Project id/Name(slug)',\n type: 'string',\n },\n mergeRequestURL: {\n title: 'MergeRequest(MR) URL',\n type: 'string',\n description: 'Link to the merge request in GitLab',\n },\n },\n },\n },\n async handler(ctx) {\n const repoUrl = ctx.input.repoUrl;\n const { host } = parseRepoUrl(repoUrl, integrations);\n const integrationConfig = integrations.gitlab.byHost(host);\n\n const actions: Types.CommitAction[] = [];\n\n const destinationBranch = ctx.input.branchName;\n\n if (!integrationConfig) {\n throw new InputError(\n `No matching integration configuration for host ${host}, please check your integrations config`,\n );\n }\n\n if (!integrationConfig.config.token && !ctx.input.token) {\n throw new InputError(`No token available for host ${host}`);\n }\n\n const token = ctx.input.token ?? integrationConfig.config.token!;\n const tokenType = ctx.input.token ? 'oauthToken' : 'token';\n\n const api = new Gitlab({\n host: integrationConfig.config.baseUrl,\n [tokenType]: token,\n });\n\n const fileRoot = ctx.workspacePath;\n const localFilePaths = await globby([`${ctx.input.targetPath}/**`], {\n cwd: fileRoot,\n gitignore: true,\n dot: true,\n });\n\n const fileContents = await Promise.all(\n localFilePaths.map(p => readFile(resolveSafeChildPath(fileRoot, p))),\n );\n\n const repoFilePaths = localFilePaths.map(repoFilePath => {\n return repoFilePath;\n });\n\n for (let i = 0; i < repoFilePaths.length; i++) {\n actions.push({\n action: 'create',\n filePath: repoFilePaths[i],\n content: fileContents[i].toString(),\n });\n }\n\n const projects = await api.Projects.show(ctx.input.projectid);\n\n const { default_branch: defaultBranch } = projects;\n\n try {\n await api.Branches.create(\n ctx.input.projectid,\n destinationBranch,\n String(defaultBranch),\n );\n } catch (e) {\n throw new InputError(`The branch creation failed ${e}`);\n }\n\n try {\n await api.Commits.create(\n ctx.input.projectid,\n destinationBranch,\n ctx.input.title,\n actions,\n );\n } catch (e) {\n throw new InputError(\n `Committing the changes to ${destinationBranch} failed ${e}`,\n );\n }\n\n try {\n const mergeRequestUrl = await api.MergeRequests.create(\n ctx.input.projectid,\n destinationBranch,\n String(defaultBranch),\n ctx.input.title,\n { description: ctx.input.description },\n ).then((mergeRequest: { web_url: string }) => {\n return mergeRequest.web_url;\n });\n ctx.output('projectid', ctx.input.projectid);\n ctx.output('mergeRequestUrl', mergeRequestUrl);\n } catch (e) {\n throw new InputError(`Merge request creation failed${e}`);\n }\n },\n });\n};\n","/*\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 */\nimport { InputError } from '@backstage/errors';\nimport {\n GithubCredentialsProvider,\n ScmIntegrations,\n} from '@backstage/integration';\nimport { Octokit } from 'octokit';\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { parseRepoUrl } from '../publish/util';\nimport { getOctokitOptions } from './helpers';\n\n/**\n * Creates a new action that dispatches a GitHub Action workflow for a given branch or tag.\n * @public\n */\nexport function createGithubActionsDispatchAction(options: {\n integrations: ScmIntegrations;\n githubCredentialsProvider?: GithubCredentialsProvider;\n}) {\n const { integrations, githubCredentialsProvider } = options;\n\n return createTemplateAction<{\n repoUrl: string;\n workflowId: string;\n branchOrTagName: string;\n workflowInputs?: { [key: string]: string };\n token?: string;\n }>({\n id: 'github:actions:dispatch',\n description:\n 'Dispatches a GitHub Action workflow for a given branch or tag',\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl', 'workflowId', 'branchOrTagName'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the new repository name and 'owner' is an organization or username`,\n type: 'string',\n },\n workflowId: {\n title: 'Workflow ID',\n description: 'The GitHub Action Workflow filename',\n type: 'string',\n },\n branchOrTagName: {\n title: 'Branch or Tag name',\n description:\n 'The git branch or tag name used to dispatch the workflow',\n type: 'string',\n },\n workflowInputs: {\n title: 'Workflow Inputs',\n description:\n 'Inputs keys and values to send to GitHub Action configured on the workflow file. The maximum number of properties is 10. ',\n type: 'object',\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The GITHUB_TOKEN to use for authorization to GitHub',\n },\n },\n },\n },\n async handler(ctx) {\n const {\n repoUrl,\n workflowId,\n branchOrTagName,\n workflowInputs,\n token: providedToken,\n } = ctx.input;\n\n ctx.logger.info(\n `Dispatching workflow ${workflowId} for repo ${repoUrl} on ${branchOrTagName}`,\n );\n\n const { owner, repo } = parseRepoUrl(repoUrl, integrations);\n\n if (!owner) {\n throw new InputError('Invalid repository owner provided in repoUrl');\n }\n\n const client = new Octokit(\n await getOctokitOptions({\n integrations,\n repoUrl,\n credentialsProvider: githubCredentialsProvider,\n token: providedToken,\n }),\n );\n\n await client.rest.actions.createWorkflowDispatch({\n owner,\n repo,\n workflow_id: workflowId,\n ref: branchOrTagName,\n inputs: workflowInputs,\n });\n\n ctx.logger.info(`Workflow ${workflowId} dispatched successfully`);\n },\n });\n}\n","/*\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 */\nimport {\n GithubCredentialsProvider,\n ScmIntegrationRegistry,\n} from '@backstage/integration';\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { emitterEventNames } from '@octokit/webhooks';\nimport { assertError, InputError } from '@backstage/errors';\nimport { Octokit } from 'octokit';\nimport { getOctokitOptions } from './helpers';\nimport { parseRepoUrl } from '../publish/util';\n\n/**\n * Creates new action that creates a webhook for a repository on GitHub.\n * @public\n */\nexport function createGithubWebhookAction(options: {\n integrations: ScmIntegrationRegistry;\n defaultWebhookSecret?: string;\n githubCredentialsProvider?: GithubCredentialsProvider;\n}) {\n const { integrations, defaultWebhookSecret, githubCredentialsProvider } =\n options;\n\n const eventNames = emitterEventNames.filter(event => !event.includes('.'));\n\n return createTemplateAction<{\n repoUrl: string;\n webhookUrl: string;\n webhookSecret?: string;\n events?: string[];\n active?: boolean;\n contentType?: 'form' | 'json';\n insecureSsl?: boolean;\n token?: string;\n }>({\n id: 'github:webhook',\n description: 'Creates webhook for a repository on GitHub.',\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl', 'webhookUrl'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the new repository name and 'owner' is an organization or username`,\n type: 'string',\n },\n webhookUrl: {\n title: 'Webhook URL',\n description: 'The URL to which the payloads will be delivered',\n type: 'string',\n },\n webhookSecret: {\n title: 'Webhook Secret',\n description:\n 'Webhook secret value. The default can be provided internally in action creation',\n type: 'string',\n },\n events: {\n title: 'Triggering Events',\n description:\n 'Determines what events the hook is triggered for. Default: push',\n type: 'array',\n oneOf: [\n {\n items: {\n type: 'string',\n enum: eventNames,\n },\n },\n {\n items: {\n type: 'string',\n const: '*',\n },\n },\n ],\n },\n active: {\n title: 'Active',\n type: 'boolean',\n description: `Determines if notifications are sent when the webhook is triggered. Default: true`,\n },\n contentType: {\n title: 'Content Type',\n type: 'string',\n enum: ['form', 'json'],\n description: `The media type used to serialize the payloads. The default is 'form'`,\n },\n insecureSsl: {\n title: 'Insecure SSL',\n type: 'boolean',\n description: `Determines whether the SSL certificate of the host for url will be verified when delivering payloads. Default 'false'`,\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The GITHUB_TOKEN to use for authorization to GitHub',\n },\n },\n },\n },\n async handler(ctx) {\n const {\n repoUrl,\n webhookUrl,\n webhookSecret = defaultWebhookSecret,\n events = ['push'],\n active = true,\n contentType = 'form',\n insecureSsl = false,\n token: providedToken,\n } = ctx.input;\n\n ctx.logger.info(`Creating webhook ${webhookUrl} for repo ${repoUrl}`);\n const { owner, repo } = parseRepoUrl(repoUrl, integrations);\n\n if (!owner) {\n throw new InputError('Invalid repository owner provided in repoUrl');\n }\n\n const client = new Octokit(\n await getOctokitOptions({\n integrations,\n credentialsProvider: githubCredentialsProvider,\n repoUrl: repoUrl,\n token: providedToken,\n }),\n );\n\n try {\n const insecure_ssl = insecureSsl ? '1' : '0';\n await client.rest.repos.createWebhook({\n owner,\n repo,\n config: {\n url: webhookUrl,\n content_type: contentType,\n secret: webhookSecret,\n insecure_ssl,\n },\n events,\n active,\n });\n ctx.logger.info(`Webhook '${webhookUrl}' created successfully`);\n } catch (e) {\n assertError(e);\n ctx.logger.warn(\n `Failed: create webhook '${webhookUrl}' on repo: '${repo}', ${e.message}`,\n );\n }\n },\n });\n}\n","/*\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 */\nimport {\n GithubCredentialsProvider,\n ScmIntegrationRegistry,\n} from '@backstage/integration';\nimport { createTemplateAction } from '../../createTemplateAction';\nimport { assertError, InputError } from '@backstage/errors';\nimport { Octokit } from 'octokit';\nimport { getOctokitOptions } from './helpers';\nimport { parseRepoUrl } from '../publish/util';\n\n/**\n * Adds labels to a pull request or issue on GitHub\n * @public\n */\nexport function createGithubIssuesLabelAction(options: {\n integrations: ScmIntegrationRegistry;\n githubCredentialsProvider?: GithubCredentialsProvider;\n}) {\n const { integrations, githubCredentialsProvider } = options;\n\n return createTemplateAction<{\n repoUrl: string;\n number: number;\n labels: string[];\n token?: string;\n }>({\n id: 'github:issues:label',\n description: 'Adds labels to a pull request or issue on GitHub.',\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl', 'number', 'labels'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the repository name and 'owner' is an organization or username`,\n type: 'string',\n },\n number: {\n title: 'Pull Request or issue number',\n description: 'The pull request or issue number to add labels to',\n type: 'number',\n },\n labels: {\n title: 'Labels',\n description: 'The labels to add to the pull request or issue',\n type: 'array',\n items: {\n type: 'string',\n },\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The GITHUB_TOKEN to use for authorization to GitHub',\n },\n },\n },\n },\n async handler(ctx) {\n const { repoUrl, number, labels, token: providedToken } = ctx.input;\n\n const { owner, repo } = parseRepoUrl(repoUrl, integrations);\n ctx.logger.info(`Adding labels to ${number} issue on repo ${repo}`);\n\n if (!owner) {\n throw new InputError('Invalid repository owner provided in repoUrl');\n }\n\n const client = new Octokit(\n await getOctokitOptions({\n integrations,\n credentialsProvider: githubCredentialsProvider,\n repoUrl: repoUrl,\n token: providedToken,\n }),\n );\n\n try {\n await client.rest.issues.addLabels({\n owner,\n repo,\n issue_number: number,\n labels,\n });\n } catch (e) {\n assertError(e);\n ctx.logger.warn(\n `Failed: adding labels to issue: '${number}' on repo: '${repo}', ${e.message}`,\n );\n }\n },\n });\n}\n","/*\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 { UrlReader } from '@backstage/backend-common';\nimport { JsonObject } from '@backstage/types';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport {\n GithubCredentialsProvider,\n ScmIntegrations,\n DefaultGithubCredentialsProvider,\n} from '@backstage/integration';\nimport { Config } from '@backstage/config';\nimport {\n createCatalogWriteAction,\n createCatalogRegisterAction,\n} from './catalog';\n\nimport { createDebugLogAction } from './debug';\nimport { createFetchPlainAction, createFetchTemplateAction } from './fetch';\nimport {\n createFilesystemDeleteAction,\n createFilesystemRenameAction,\n} from './filesystem';\nimport {\n createPublishAzureAction,\n createPublishBitbucketAction,\n createPublishGithubAction,\n createPublishGithubPullRequestAction,\n createPublishGitlabAction,\n createPublishGitlabMergeRequestAction,\n} from './publish';\nimport {\n createGithubActionsDispatchAction,\n createGithubWebhookAction,\n createGithubIssuesLabelAction,\n} from './github';\nimport { TemplateFilter } from '../../../lib';\nimport { TemplateAction } from '../types';\n\n/**\n * The options passed to {@link createBuiltinActions}\n * @public\n */\nexport interface CreateBuiltInActionsOptions {\n /**\n * The {@link @backstage/backend-common#UrlReader} interface that will be used in the default actions.\n */\n reader: UrlReader;\n /**\n * The {@link @backstage/integrations#ScmIntegrations} that will be used in the default actions.\n */\n integrations: ScmIntegrations;\n /**\n * The {@link @backstage/catalog-client#CatalogApi} that will be used in the default actions.\n */\n catalogClient: CatalogApi;\n /**\n * The {@link @backstage/config#Config} that will be used in the default actions.\n */\n config: Config;\n /**\n * Additional custom filters that will be passed to the nunjucks template engine for use in\n * Template Manifests and also template skeleton files when using `fetch:template`.\n */\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n}\n\n/**\n * A function to generate create a list of default actions that the scaffolder provides.\n * Is called internally in the default setup, but can be used when adding your own actions or overriding the default ones\n *\n * @public\n * @returns A list of actions that can be used in the scaffolder\n */\nexport const createBuiltinActions = (\n options: CreateBuiltInActionsOptions,\n): TemplateAction<JsonObject>[] => {\n const {\n reader,\n integrations,\n catalogClient,\n config,\n additionalTemplateFilters,\n } = options;\n\n const githubCredentialsProvider: GithubCredentialsProvider =\n DefaultGithubCredentialsProvider.fromIntegrations(integrations);\n\n const actions = [\n createFetchPlainAction({\n reader,\n integrations,\n }),\n createFetchTemplateAction({\n integrations,\n reader,\n additionalTemplateFilters,\n }),\n createPublishGithubAction({\n integrations,\n config,\n githubCredentialsProvider,\n }),\n createPublishGithubPullRequestAction({\n integrations,\n githubCredentialsProvider,\n }),\n createPublishGitlabAction({\n integrations,\n config,\n }),\n createPublishGitlabMergeRequestAction({\n integrations,\n }),\n createPublishBitbucketAction({\n integrations,\n config,\n }),\n createPublishAzureAction({\n integrations,\n config,\n }),\n createDebugLogAction(),\n createCatalogRegisterAction({ catalogClient, integrations }),\n createCatalogWriteAction(),\n createFilesystemDeleteAction(),\n createFilesystemRenameAction(),\n createGithubActionsDispatchAction({\n integrations,\n githubCredentialsProvider,\n }),\n createGithubWebhookAction({\n integrations,\n githubCredentialsProvider,\n }),\n createGithubIssuesLabelAction({\n integrations,\n githubCredentialsProvider,\n }),\n ];\n\n return actions as TemplateAction<JsonObject>[];\n};\n","/*\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 { ConflictError, NotFoundError } from '@backstage/errors';\nimport { TemplateAction } from './types';\n\n/**\n * Registry of all registered template actions.\n * @public\n */\nexport class TemplateActionRegistry {\n private readonly actions = new Map<string, TemplateAction<any>>();\n\n register<TInput extends JsonObject>(action: TemplateAction<TInput>) {\n if (this.actions.has(action.id)) {\n throw new ConflictError(\n `Template action with ID '${action.id}' has already been registered`,\n );\n }\n this.actions.set(action.id, action);\n }\n\n get(actionId: string): TemplateAction<JsonObject> {\n const action = this.actions.get(actionId);\n if (!action) {\n throw new NotFoundError(\n `Template action with ID '${actionId}' is not registered.`,\n );\n }\n return action;\n }\n\n list(): TemplateAction<JsonObject>[] {\n return [...this.actions.values()];\n }\n}\n","/*\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 { resolvePackagePath } from '@backstage/backend-common';\nimport { ConflictError, NotFoundError } from '@backstage/errors';\nimport { Knex } from 'knex';\nimport { v4 as uuid } from 'uuid';\nimport {\n SerializedTaskEvent,\n SerializedTask,\n TaskStatus,\n TaskEventType,\n TaskStore,\n TaskStoreEmitOptions,\n TaskStoreListEventsOptions,\n TaskStoreCreateTaskOptions,\n TaskStoreCreateTaskResult,\n} from './types';\nimport { DateTime } from 'luxon';\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 last_heartbeat_at?: string;\n created_at: string;\n secrets?: string | null;\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: Knex;\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 await options.database.migrate.latest({\n directory: migrationsDir,\n });\n return new DatabaseTaskStore(options);\n }\n\n private constructor(options: DatabaseTaskStoreOptions) {\n this.db = options.database;\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 return {\n id: result.id,\n spec,\n status: result.status,\n lastHeartbeatAt: result.last_heartbeat_at,\n createdAt: result.created_at,\n secrets,\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 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 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 when moving moving to processing state.\n secrets: null,\n });\n\n if (updateCount < 1) {\n return undefined;\n }\n\n try {\n const spec = JSON.parse(task.spec);\n const secrets = task.secrets ? JSON.parse(task.secrets) : undefined;\n return {\n id: task.id,\n spec,\n status: 'processing',\n lastHeartbeatAt: task.last_heartbeat_at,\n createdAt: task.created_at,\n secrets,\n };\n } catch (error) {\n throw new Error(`Failed to parse spec of task '${task.id}', ${error}`);\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({ timeoutS }: { timeoutS: number }): Promise<{\n tasks: { taskId: string }[];\n }> {\n const rawRows = await this.db<RawDbTaskRow>('tasks')\n .where('status', 'processing')\n .andWhere(\n 'last_heartbeat_at',\n '<=',\n this.db.client.config.client.includes('sqlite3')\n ? this.db.raw(`datetime('now', ?)`, [`-${timeoutS} seconds`])\n : this.db.raw(`dateadd('second', ?, ?)`, [\n `-${timeoutS}`,\n this.db.fn.now(),\n ]),\n );\n const tasks = rawRows.map(row => ({\n taskId: row.id,\n }));\n return { tasks };\n }\n\n async completeTask({\n taskId,\n status,\n eventBody,\n }: {\n taskId: string;\n status: TaskStatus;\n eventBody: JsonObject;\n }): Promise<void> {\n let oldStatus: string;\n if (status === 'failed' || status === 'completed') {\n oldStatus = 'processing';\n } else {\n throw new Error(\n `Invalid status update of run '${taskId}' to status '${status}'`,\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 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 const updateCount = await tx<RawDbTaskRow>('tasks')\n .where({\n id: taskId,\n status: oldStatus,\n })\n .update({\n status,\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\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 listEvents({\n taskId,\n after,\n }: TaskStoreListEventsOptions): Promise<{ events: SerializedTaskEvent[] }> {\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 taskId,\n body,\n type: event.event_type,\n createdAt:\n typeof event.created_at === 'string'\n ? DateTime.fromSQL(event.created_at, { zone: 'UTC' }).toISO()\n : 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 return { events };\n }\n}\n","/*\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 */\nimport { JsonObject, Observable } from '@backstage/types';\nimport ObservableImpl from 'zen-observable';\nimport { TaskSpec } from '@backstage/plugin-scaffolder-common';\nimport { Logger } from 'winston';\nimport {\n TaskCompletionState,\n TaskContext,\n TaskSecrets,\n TaskStore,\n TaskBroker,\n SerializedTaskEvent,\n SerializedTask,\n} from './types';\nimport { TaskBrokerDispatchOptions } from '.';\n\n/**\n * TaskManager\n *\n * @public\n */\nexport class TaskManager implements TaskContext {\n private isDone = false;\n\n private heartbeatTimeoutId?: ReturnType<typeof setInterval>;\n\n static create(task: CurrentClaimedTask, storage: TaskStore, logger: Logger) {\n const agent = new TaskManager(task, storage, logger);\n agent.startTimeout();\n return agent;\n }\n\n // Runs heartbeat internally\n private constructor(\n private readonly task: CurrentClaimedTask,\n private readonly storage: TaskStore,\n private readonly logger: Logger,\n ) {}\n\n get spec() {\n return this.task.spec;\n }\n\n get secrets() {\n return this.task.secrets;\n }\n\n async getWorkspaceName() {\n return this.task.taskId;\n }\n\n get done() {\n return this.isDone;\n }\n\n async emitLog(message: string, logMetadata?: JsonObject): Promise<void> {\n await this.storage.emitLogEvent({\n taskId: this.task.taskId,\n body: { message, ...logMetadata },\n });\n }\n\n async complete(\n result: TaskCompletionState,\n metadata?: JsonObject,\n ): Promise<void> {\n await this.storage.completeTask({\n taskId: this.task.taskId,\n status: result === 'failed' ? 'failed' : 'completed',\n eventBody: {\n message: `Run completed with status: ${result}`,\n ...metadata,\n },\n });\n this.isDone = true;\n if (this.heartbeatTimeoutId) {\n clearTimeout(this.heartbeatTimeoutId);\n }\n }\n\n private startTimeout() {\n this.heartbeatTimeoutId = setTimeout(async () => {\n try {\n await this.storage.heartbeatTask(this.task.taskId);\n this.startTimeout();\n } catch (error) {\n this.isDone = true;\n\n this.logger.error(\n `Heartbeat for task ${this.task.taskId} failed`,\n error,\n );\n }\n }, 1000);\n }\n}\n\n/**\n * Stores the state of the current claimed task passed to the TaskContext\n *\n * @public\n */\nexport interface CurrentClaimedTask {\n /**\n * The TaskSpec of the current claimed task.\n */\n spec: TaskSpec;\n /**\n * The uuid of the current claimed task.\n */\n taskId: string;\n /**\n * The secrets that are stored with the task.\n */\n secrets?: TaskSecrets;\n}\n\nfunction defer() {\n let resolve = () => {};\n const promise = new Promise<void>(_resolve => {\n resolve = _resolve;\n });\n return { promise, resolve };\n}\n\nexport class StorageTaskBroker implements TaskBroker {\n constructor(\n private readonly storage: TaskStore,\n private readonly logger: Logger,\n ) {}\n private deferredDispatch = defer();\n\n /**\n * {@inheritdoc TaskBroker.claim}\n */\n async claim(): Promise<TaskContext> {\n for (;;) {\n const pendingTask = await this.storage.claimTask();\n if (pendingTask) {\n return TaskManager.create(\n {\n taskId: pendingTask.id,\n spec: pendingTask.spec,\n secrets: pendingTask.secrets,\n },\n this.storage,\n this.logger,\n );\n }\n\n await this.waitForDispatch();\n }\n }\n\n /**\n * {@inheritdoc TaskBroker.dispatch}\n */\n async dispatch(\n options: TaskBrokerDispatchOptions,\n ): Promise<{ taskId: string }> {\n const taskRow = await this.storage.createTask(options);\n this.signalDispatch();\n return {\n taskId: taskRow.taskId,\n };\n }\n\n /**\n * {@inheritdoc TaskBroker.get}\n */\n async get(taskId: string): Promise<SerializedTask> {\n return this.storage.getTask(taskId);\n }\n\n /**\n * {@inheritdoc TaskBroker.event$}\n */\n event$(options: {\n taskId: string;\n after?: number;\n }): Observable<{ events: SerializedTaskEvent[] }> {\n return new ObservableImpl(observer => {\n const { taskId } = options;\n\n let after = options.after;\n let cancelled = false;\n\n (async () => {\n while (!cancelled) {\n const result = await this.storage.listEvents({ taskId, after });\n const { events } = result;\n if (events.length) {\n after = events[events.length - 1].id;\n observer.next(result);\n }\n\n await new Promise(resolve => setTimeout(resolve, 1000));\n }\n })();\n\n return () => {\n cancelled = true;\n };\n });\n }\n\n /**\n * {@inheritdoc TaskBroker.vacuumTasks}\n */\n async vacuumTasks(options: { timeoutS: number }): Promise<void> {\n const { tasks } = await this.storage.listStaleTasks(options);\n await Promise.all(\n tasks.map(async task => {\n try {\n await this.storage.completeTask({\n taskId: task.taskId,\n status: 'failed',\n eventBody: {\n message:\n 'The task was cancelled because the task worker lost connection to the task broker',\n },\n });\n } catch (error) {\n this.logger.warn(`Failed to cancel task '${task.taskId}', ${error}`);\n }\n }),\n );\n }\n\n private waitForDispatch() {\n return this.deferredDispatch.promise;\n }\n\n private signalDispatch() {\n this.deferredDispatch.resolve();\n this.deferredDispatch = defer();\n }\n}\n","/*\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 { isArray } from 'lodash';\n\n/**\n * Returns true if the input is not `false`, `undefined`, `null`, `\"\"`, `0`, or\n * `[]`. This behavior is based on the behavior of handlebars, see\n * https://handlebarsjs.com/guide/builtin-helpers.html#if\n */\nexport function isTruthy(value: any): boolean {\n return isArray(value) ? value.length > 0 : !!value;\n}\n","/*\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 { TaskContext, WorkflowResponse, WorkflowRunner } from './types';\nimport * as winston from 'winston';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport nunjucks from 'nunjucks';\nimport { JsonObject, JsonValue } from '@backstage/types';\nimport { InputError } from '@backstage/errors';\nimport { PassThrough } from 'stream';\nimport { isTruthy } from './helper';\nimport { validate as validateJsonSchema } from 'jsonschema';\nimport { parseRepoUrl } from '../actions/builtin/publish/util';\nimport { TemplateActionRegistry } from '../actions';\nimport {\n TemplateFilter,\n SecureTemplater,\n SecureTemplateRenderer,\n} from '../../lib/templating/SecureTemplater';\nimport {\n TaskSpec,\n TaskSpecV1beta3,\n TaskStep,\n} from '@backstage/plugin-scaffolder-common';\n\ntype NunjucksWorkflowRunnerOptions = {\n workingDirectory: string;\n actionRegistry: TemplateActionRegistry;\n integrations: ScmIntegrations;\n logger: winston.Logger;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n};\n\ntype TemplateContext = {\n parameters: JsonObject;\n steps: {\n [stepName: string]: { output: { [outputName: string]: JsonValue } };\n };\n secrets?: Record<string, string>;\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}: {\n task: TaskContext;\n step: TaskStep;\n}) => {\n const metadata = { stepId: step.id };\n const taskLogger = winston.createLogger({\n level: process.env.LOG_LEVEL || 'info',\n format: winston.format.combine(\n winston.format.colorize(),\n winston.format.timestamp(),\n winston.format.simple(),\n ),\n defaultMeta: {},\n });\n\n const streamLogger = new PassThrough();\n streamLogger.on('data', async data => {\n const message = data.toString().trim();\n if (message?.length > 1) {\n await task.emitLog(message, metadata);\n }\n });\n\n taskLogger.add(new winston.transports.Stream({ stream: streamLogger }));\n\n return { taskLogger, streamLogger };\n};\n\nexport class NunjucksWorkflowRunner implements WorkflowRunner {\n constructor(private readonly options: NunjucksWorkflowRunnerOptions) {}\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 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 workspacePath = path.join(\n this.options.workingDirectory,\n await task.getWorkspaceName(),\n );\n\n const { integrations } = this.options;\n const renderTemplate = await SecureTemplater.loadRenderer({\n // TODO(blam): let's work out how we can deprecate this.\n // We shouldn't really need to be exposing these now we can deal with\n // objects in the params block.\n // Maybe we can expose a new RepoUrlPicker with secrets for V3 that provides an object already.\n parseRepoUrl(url: string) {\n return parseRepoUrl(url, integrations);\n },\n additionalTemplateFilters: this.options.additionalTemplateFilters,\n });\n\n try {\n await fs.ensureDir(workspacePath);\n await task.emitLog(\n `Starting up task with ${task.spec.steps.length} steps`,\n );\n\n const context: TemplateContext = {\n parameters: task.spec.parameters,\n steps: {},\n };\n\n for (const step of task.spec.steps) {\n try {\n if (step.if) {\n const ifResult = await this.render(\n step.if,\n context,\n renderTemplate,\n );\n if (!isTruthy(ifResult)) {\n await task.emitLog(\n `Skipping step ${step.id} because it's if condition was false`,\n { stepId: step.id, status: 'skipped' },\n );\n continue;\n }\n }\n\n await task.emitLog(`Beginning step ${step.name}`, {\n stepId: step.id,\n status: 'processing',\n });\n\n const action = this.options.actionRegistry.get(step.action);\n const { taskLogger, streamLogger } = createStepLogger({ task, step });\n\n // Secrets are only passed when templating the input to actions for security reasons\n const input =\n (step.input &&\n this.render(\n step.input,\n { ...context, secrets: task.secrets ?? {} },\n renderTemplate,\n )) ??\n {};\n\n if (action.schema?.input) {\n const validateResult = validateJsonSchema(\n 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 ${action.id}, ${errors}`,\n );\n }\n }\n\n const tmpDirs = new Array<string>();\n const stepOutput: { [outputName: string]: JsonValue } = {};\n\n await action.handler({\n input,\n secrets: task.secrets ?? {},\n logger: taskLogger,\n logStream: streamLogger,\n workspacePath,\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 stepOutput[name] = value;\n },\n templateInfo: task.spec.templateInfo,\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 await task.emitLog(`Finished step ${step.name}`, {\n stepId: step.id,\n status: 'completed',\n });\n } catch (err) {\n await task.emitLog(String(err.stack), {\n stepId: step.id,\n status: 'failed',\n });\n throw err;\n }\n }\n\n const output = this.render(task.spec.output, context, renderTemplate);\n\n return { output };\n } finally {\n if (workspacePath) {\n await fs.remove(workspacePath);\n }\n }\n }\n}\n","/*\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 { TaskContext, TaskBroker, WorkflowRunner } from './types';\nimport { NunjucksWorkflowRunner } from './NunjucksWorkflowRunner';\nimport { Logger } from 'winston';\nimport { TemplateActionRegistry } from '../actions';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { assertError } from '@backstage/errors';\nimport { TemplateFilter } from '../../lib/templating/SecureTemplater';\n\n/**\n * TaskWorkerOptions\n *\n * @public\n */\nexport type TaskWorkerOptions = {\n taskBroker: TaskBroker;\n runners: {\n workflowRunner: WorkflowRunner;\n };\n};\n\n/**\n * CreateWorkerOptions\n *\n * @public\n */\nexport type CreateWorkerOptions = {\n taskBroker: TaskBroker;\n actionRegistry: TemplateActionRegistry;\n integrations: ScmIntegrations;\n workingDirectory: string;\n logger: Logger;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n};\n\n/**\n * TaskWorker\n *\n * @public\n */\nexport class TaskWorker {\n private constructor(private readonly options: TaskWorkerOptions) {}\n\n static async create(options: CreateWorkerOptions): Promise<TaskWorker> {\n const {\n taskBroker,\n logger,\n actionRegistry,\n integrations,\n workingDirectory,\n additionalTemplateFilters,\n } = options;\n\n const workflowRunner = new NunjucksWorkflowRunner({\n actionRegistry,\n integrations,\n logger,\n workingDirectory,\n additionalTemplateFilters,\n });\n\n return new TaskWorker({\n taskBroker: taskBroker,\n runners: { workflowRunner },\n });\n }\n\n start() {\n (async () => {\n for (;;) {\n const task = await this.options.taskBroker.claim();\n await this.runOneTask(task);\n }\n })();\n }\n\n async runOneTask(task: TaskContext) {\n try {\n if (task.spec.apiVersion !== 'scaffolder.backstage.io/v1beta3') {\n throw new Error(\n `Unsupported Template apiVersion ${task.spec.apiVersion}`,\n );\n }\n\n const { output } = await this.options.runners.workflowRunner.execute(\n task,\n );\n\n await task.complete('completed', { output });\n } catch (error) {\n assertError(error);\n await task.complete('failed', {\n error: { name: error.name, message: error.message },\n });\n }\n }\n}\n","/*\n * Copyright 2020 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 { CatalogApi } from '@backstage/catalog-client';\nimport {\n Entity,\n ANNOTATION_LOCATION,\n parseLocationRef,\n ANNOTATION_SOURCE_LOCATION,\n CompoundEntityRef,\n DEFAULT_NAMESPACE,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport { assertError, InputError, NotFoundError } from '@backstage/errors';\nimport { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';\nimport fs from 'fs-extra';\nimport os from 'os';\nimport { Logger } from 'winston';\n\nexport async function getWorkingDirectory(\n config: Config,\n logger: Logger,\n): Promise<string> {\n if (!config.has('backend.workingDirectory')) {\n return os.tmpdir();\n }\n\n const workingDirectory = config.getString('backend.workingDirectory');\n try {\n // Check if working directory exists and is writable\n await fs.access(workingDirectory, fs.constants.F_OK | fs.constants.W_OK);\n logger.info(`using working directory: ${workingDirectory}`);\n } catch (err) {\n assertError(err);\n logger.error(\n `working directory ${workingDirectory} ${\n err.code === 'ENOENT' ? 'does not exist' : 'is not writable'\n }`,\n );\n throw err;\n }\n return workingDirectory;\n}\n\n/**\n * Gets the base URL of the entity location that points to the source location\n * of the entity description within a repo. If there is not source location\n * or if it has an invalid type, undefined will be returned instead.\n *\n * For file locations this will return a `file://` URL.\n */\nexport function getEntityBaseUrl(entity: Entity): string | undefined {\n let location = entity.metadata.annotations?.[ANNOTATION_SOURCE_LOCATION];\n if (!location) {\n location = entity.metadata.annotations?.[ANNOTATION_LOCATION];\n }\n if (!location) {\n return undefined;\n }\n\n const { type, target } = parseLocationRef(location);\n if (type === 'url') {\n return target;\n } else if (type === 'file') {\n return `file://${target}`;\n }\n\n // Only url and file location are handled, as we otherwise don't know if\n // what the url is pointing to makes sense to use as a baseUrl\n return undefined;\n}\n\n/**\n * Will use the provided CatalogApi to go find the given template entity with an additional token.\n * Returns the matching template, or throws a NotFoundError if no such template existed.\n */\nexport async function findTemplate(options: {\n entityRef: CompoundEntityRef;\n token?: string;\n catalogApi: CatalogApi;\n}): Promise<TemplateEntityV1beta3> {\n const { entityRef, token, catalogApi } = options;\n\n if (entityRef.namespace.toLocaleLowerCase('en-US') !== DEFAULT_NAMESPACE) {\n throw new InputError(\n `Invalid namespace, only '${DEFAULT_NAMESPACE}' namespace is supported`,\n );\n }\n if (entityRef.kind.toLocaleLowerCase('en-US') !== 'template') {\n throw new InputError(`Invalid kind, only 'Template' kind is supported`);\n }\n\n const template = await catalogApi.getEntityByRef(entityRef, { token });\n if (!template) {\n throw new NotFoundError(\n `Template ${stringifyEntityRef(entityRef)} not found`,\n );\n }\n\n return template as TemplateEntityV1beta3;\n}\n","/*\n * Copyright 2020 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 { PluginDatabaseManager, UrlReader } from '@backstage/backend-common';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';\nimport { Entity } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport { InputError, NotFoundError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport {\n TemplateEntityV1beta3,\n TaskSpec,\n} from '@backstage/plugin-scaffolder-common';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { validate } from 'jsonschema';\nimport { Logger } from 'winston';\nimport { TemplateFilter } from '../lib';\nimport {\n createBuiltinActions,\n DatabaseTaskStore,\n TaskBroker,\n TaskWorker,\n TemplateAction,\n TemplateActionRegistry,\n} from '../scaffolder';\nimport { StorageTaskBroker } from '../scaffolder/tasks/StorageTaskBroker';\nimport { getEntityBaseUrl, getWorkingDirectory, findTemplate } from './helpers';\n\n/**\n * RouterOptions\n *\n * @public\n */\nexport interface RouterOptions {\n logger: Logger;\n config: Config;\n reader: UrlReader;\n database: PluginDatabaseManager;\n catalogClient: CatalogApi;\n actions?: TemplateAction<any>[];\n taskWorkers?: number;\n taskBroker?: TaskBroker;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n}\n\nfunction isSupportedTemplate(entity: TemplateEntityV1beta3) {\n return entity.apiVersion === 'scaffolder.backstage.io/v1beta3';\n}\n\n/**\n * A method to create a router for the scaffolder backend plugin.\n * @public\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const router = Router();\n router.use(express.json());\n\n const {\n logger: parentLogger,\n config,\n reader,\n database,\n catalogClient,\n actions,\n taskWorkers,\n additionalTemplateFilters,\n } = options;\n\n const logger = parentLogger.child({ plugin: 'scaffolder' });\n const workingDirectory = await getWorkingDirectory(config, logger);\n const integrations = ScmIntegrations.fromConfig(config);\n let taskBroker: TaskBroker;\n\n if (!options.taskBroker) {\n const databaseTaskStore = await DatabaseTaskStore.create({\n database: await database.getClient(),\n });\n taskBroker = new StorageTaskBroker(databaseTaskStore, logger);\n } else {\n taskBroker = options.taskBroker;\n }\n\n const actionRegistry = new TemplateActionRegistry();\n\n const workers = [];\n for (let i = 0; i < (taskWorkers || 1); i++) {\n const worker = await TaskWorker.create({\n taskBroker,\n actionRegistry,\n integrations,\n logger,\n workingDirectory,\n additionalTemplateFilters,\n });\n workers.push(worker);\n }\n\n const actionsToRegister = Array.isArray(actions)\n ? actions\n : createBuiltinActions({\n integrations,\n catalogClient,\n reader,\n config,\n additionalTemplateFilters,\n });\n\n actionsToRegister.forEach(action => actionRegistry.register(action));\n workers.forEach(worker => worker.start());\n\n router\n .get(\n '/v2/templates/:namespace/:kind/:name/parameter-schema',\n async (req, res) => {\n const { namespace, kind, name } = req.params;\n const template = await findTemplate({\n catalogApi: catalogClient,\n entityRef: { kind, namespace, name },\n token: getBearerToken(req.headers.authorization),\n });\n if (isSupportedTemplate(template)) {\n const parameters = [template.spec.parameters ?? []].flat();\n res.json({\n title: template.metadata.title ?? template.metadata.name,\n steps: parameters.map(schema => ({\n title: schema.title ?? 'Fill in template parameters',\n schema,\n })),\n });\n } else {\n throw new InputError(\n `Unsupported apiVersion field in schema entity, ${\n (template as Entity).apiVersion\n }`,\n );\n }\n },\n )\n .get('/v2/actions', async (_req, res) => {\n const actionsList = actionRegistry.list().map(action => {\n return {\n id: action.id,\n description: action.description,\n schema: action.schema,\n };\n });\n res.json(actionsList);\n })\n .post('/v2/tasks', async (req, res) => {\n const templateRef: string = req.body.templateRef;\n const { kind, namespace, name } = parseEntityRef(templateRef, {\n defaultKind: 'template',\n });\n const values = req.body.values;\n const token = getBearerToken(req.headers.authorization);\n const template = await findTemplate({\n catalogApi: catalogClient,\n entityRef: { kind, namespace, name },\n token: getBearerToken(req.headers.authorization),\n });\n\n if (!isSupportedTemplate(template)) {\n throw new InputError(\n `Unsupported apiVersion field in schema entity, ${\n (template as Entity).apiVersion\n }`,\n );\n }\n\n for (const parameters of [template.spec.parameters ?? []].flat()) {\n const result = validate(values, parameters);\n if (!result.valid) {\n res.status(400).json({ errors: result.errors });\n return;\n }\n }\n\n const baseUrl = getEntityBaseUrl(template);\n\n const taskSpec: TaskSpec = {\n apiVersion: template.apiVersion,\n steps: template.spec.steps.map((step, index) => ({\n ...step,\n id: step.id ?? `step-${index + 1}`,\n name: step.name ?? step.action,\n })),\n output: template.spec.output ?? {},\n parameters: values,\n templateInfo: {\n entityRef: stringifyEntityRef({\n kind,\n namespace,\n name: template.metadata?.name,\n }),\n baseUrl,\n },\n };\n\n const result = await taskBroker.dispatch({\n spec: taskSpec,\n secrets: {\n ...req.body.secrets,\n backstageToken: token,\n },\n });\n\n res.status(201).json({ id: result.taskId });\n })\n .get('/v2/tasks/:taskId', async (req, res) => {\n const { taskId } = req.params;\n const task = await taskBroker.get(taskId);\n if (!task) {\n throw new NotFoundError(`Task with id ${taskId} does not exist`);\n }\n // Do not disclose secrets\n delete task.secrets;\n res.status(200).json(task);\n })\n .get('/v2/tasks/:taskId/eventstream', async (req, res) => {\n const { taskId } = req.params;\n const after =\n req.query.after !== undefined ? Number(req.query.after) : undefined;\n\n logger.debug(`Event stream observing taskId '${taskId}' opened`);\n\n // Mandatory headers and http status to keep connection open\n res.writeHead(200, {\n Connection: 'keep-alive',\n 'Cache-Control': 'no-cache',\n 'Content-Type': 'text/event-stream',\n });\n\n // After client opens connection send all events as string\n const subscription = taskBroker.event$({ taskId, after }).subscribe({\n error: error => {\n logger.error(\n `Received error from event stream when observing taskId '${taskId}', ${error}`,\n );\n },\n next: ({ events }) => {\n let shouldUnsubscribe = false;\n for (const event of events) {\n res.write(\n `event: ${event.type}\\ndata: ${JSON.stringify(event)}\\n\\n`,\n );\n if (event.type === 'completion') {\n shouldUnsubscribe = true;\n }\n }\n // res.flush() is only available with the compression middleware\n res.flush?.();\n if (shouldUnsubscribe) subscription.unsubscribe();\n },\n });\n\n // When client closes connection we update the clients list\n // avoiding the disconnected one\n req.on('close', () => {\n subscription.unsubscribe();\n logger.debug(`Event stream observing taskId '${taskId}' closed`);\n });\n })\n .get('/v2/tasks/:taskId/events', async (req, res) => {\n const { taskId } = req.params;\n const after = Number(req.query.after) || undefined;\n\n // cancel the request after 30 seconds. this aligns with the recommendations of RFC 6202.\n const timeout = setTimeout(() => {\n res.json([]);\n }, 30_000);\n\n // Get all known events after an id (always includes the completion event) and return the first callback\n const subscription = taskBroker.event$({ taskId, after }).subscribe({\n error: error => {\n logger.error(\n `Received error from event stream when observing taskId '${taskId}', ${error}`,\n );\n },\n next: ({ events }) => {\n clearTimeout(timeout);\n subscription.unsubscribe();\n res.json(events);\n },\n });\n\n // When client closes connection we update the clients list\n // avoiding the disconnected one\n req.on('close', () => {\n subscription.unsubscribe();\n clearTimeout(timeout);\n });\n });\n\n const app = express();\n app.set('logger', logger);\n app.use('/', router);\n\n return app;\n}\n\nfunction getBearerToken(header?: string): string | undefined {\n return header?.match(/Bearer\\s+(\\S+)/i)?.[1];\n}\n","/*\n * Copyright 2020 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 {\n Entity,\n getCompoundEntityRef,\n parseEntityRef,\n RELATION_OWNED_BY,\n RELATION_OWNER_OF,\n} from '@backstage/catalog-model';\nimport {\n CatalogProcessor,\n CatalogProcessorEmit,\n LocationSpec,\n processingResult,\n} from '@backstage/plugin-catalog-backend';\nimport {\n TemplateEntityV1beta3,\n templateEntityV1beta3Validator,\n} from '@backstage/plugin-scaffolder-common';\n\n/** @public */\nexport class ScaffolderEntitiesProcessor implements CatalogProcessor {\n getProcessorName(): string {\n return 'ScaffolderEntitiesProcessor';\n }\n\n private readonly validators = [templateEntityV1beta3Validator];\n\n async validateEntityKind(entity: Entity): Promise<boolean> {\n for (const validator of this.validators) {\n if (await validator.check(entity)) {\n return true;\n }\n }\n\n return false;\n }\n\n async postProcessEntity(\n entity: Entity,\n _location: LocationSpec,\n emit: CatalogProcessorEmit,\n ): Promise<Entity> {\n const selfRef = getCompoundEntityRef(entity);\n\n if (\n entity.apiVersion === 'scaffolder.backstage.io/v1beta3' &&\n entity.kind === 'Template'\n ) {\n const template = entity as TemplateEntityV1beta3;\n\n const target = template.spec.owner;\n if (target) {\n const targetRef = parseEntityRef(target, {\n defaultKind: 'Group',\n defaultNamespace: selfRef.namespace,\n });\n emit(\n processingResult.relation({\n source: selfRef,\n type: RELATION_OWNED_BY,\n target: {\n kind: targetRef.kind,\n namespace: targetRef.namespace,\n name: targetRef.name,\n },\n }),\n );\n emit(\n processingResult.relation({\n source: {\n kind: targetRef.kind,\n namespace: targetRef.namespace,\n name: targetRef.name,\n },\n type: RELATION_OWNER_OF,\n target: selfRef,\n }),\n );\n }\n }\n\n return entity;\n }\n}\n"],"names":["InputError","stringifyEntityRef","fs","resolveSafeChildPath","yaml","relative","readdir","join","stat","path","VM","resolvePackagePath","globby","extname","isBinaryFile","PassThrough","spawn","Git","assertError","normalizePath","joinPath","isChildPath","getPersonalAccessTokenHandler","WebApi","fetch","dirname","DefaultGithubCredentialsProvider","Octokit","CustomErrorBase","createPullRequest","zipObject","Gitlab","readFile","emitterEventNames","ConflictError","NotFoundError","uuid","DateTime","ObservableImpl","isArray","winston","nunjucks","validateJsonSchema","errors","os","ANNOTATION_SOURCE_LOCATION","ANNOTATION_LOCATION","parseLocationRef","DEFAULT_NAMESPACE","Router","express","ScmIntegrations","parseEntityRef","validate","templateEntityV1beta3Validator","getCompoundEntityRef","processingResult","RELATION_OWNED_BY","RELATION_OWNER_OF"],"mappings":"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"}
|