@backstage/plugin-scaffolder-node 0.4.4-next.1 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @backstage/plugin-scaffolder-node
2
2
 
3
+ ## 0.4.4
4
+
5
+ ### Patch Changes
6
+
7
+ - d229dc4: Move path utilities from `backend-common` to the `backend-plugin-api` package.
8
+ - e4b50ab: Scaffolder workspace serialization
9
+ - f633efa: To remove the dependency on the soon-to-be-deprecated `backend-common` package, this package now maintains its own isomorphic Git class implementation.
10
+ - Updated dependencies
11
+ - @backstage/plugin-scaffolder-common@1.5.2
12
+ - @backstage/catalog-model@1.5.0
13
+ - @backstage/backend-common@0.22.0
14
+ - @backstage/backend-plugin-api@0.6.18
15
+ - @backstage/integration@1.11.0
16
+
17
+ ## 0.4.4-next.2
18
+
19
+ ### Patch Changes
20
+
21
+ - e4b50ab: Scaffolder workspace serialization
22
+ - Updated dependencies
23
+ - @backstage/backend-common@0.22.0-next.2
24
+ - @backstage/integration@1.11.0-next.0
25
+
3
26
  ## 0.4.4-next.1
4
27
 
5
28
  ### Patch Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-scaffolder-node",
3
- "version": "0.4.4-next.1",
3
+ "version": "0.4.4",
4
4
  "main": "../dist/alpha.cjs.js",
5
5
  "types": "../dist/alpha.d.ts"
6
6
  }
package/dist/index.cjs.js CHANGED
@@ -3,10 +3,12 @@
3
3
  var zodToJsonSchema = require('zod-to-json-schema');
4
4
  var child_process = require('child_process');
5
5
  var stream = require('stream');
6
- var backendCommon = require('@backstage/backend-common');
6
+ var backendPluginApi = require('@backstage/backend-plugin-api');
7
7
  var errors = require('@backstage/errors');
8
8
  var fs = require('fs-extra');
9
9
  var path = require('path');
10
+ var git = require('isomorphic-git');
11
+ var http = require('isomorphic-git/http/node');
10
12
  var fs$1 = require('fs');
11
13
  var globby = require('globby');
12
14
  var limiterFactory = require('p-limit');
@@ -16,6 +18,8 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
16
18
  var zodToJsonSchema__default = /*#__PURE__*/_interopDefaultCompat(zodToJsonSchema);
17
19
  var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
18
20
  var path__default = /*#__PURE__*/_interopDefaultCompat(path);
21
+ var git__default = /*#__PURE__*/_interopDefaultCompat(git);
22
+ var http__default = /*#__PURE__*/_interopDefaultCompat(http);
19
23
  var globby__default = /*#__PURE__*/_interopDefaultCompat(globby);
20
24
  var limiterFactory__default = /*#__PURE__*/_interopDefaultCompat(limiterFactory);
21
25
 
@@ -74,7 +78,7 @@ async function fetchContents(options) {
74
78
  const fetchUrlIsAbsolute = isFetchUrlAbsolute(fetchUrl);
75
79
  if (!fetchUrlIsAbsolute && (baseUrl == null ? void 0 : baseUrl.startsWith("file://"))) {
76
80
  const basePath = baseUrl.slice("file://".length);
77
- const srcDir = backendCommon.resolveSafeChildPath(path__default.default.dirname(basePath), fetchUrl);
81
+ const srcDir = backendPluginApi.resolveSafeChildPath(path__default.default.dirname(basePath), fetchUrl);
78
82
  await fs__default.default.copy(srcDir, outputPath);
79
83
  } else {
80
84
  const readUrl = getReadUrl(fetchUrl, baseUrl, integrations);
@@ -95,7 +99,7 @@ async function fetchFile(options) {
95
99
  const fetchUrlIsAbsolute = isFetchUrlAbsolute(fetchUrl);
96
100
  if (!fetchUrlIsAbsolute && (baseUrl == null ? void 0 : baseUrl.startsWith("file://"))) {
97
101
  const basePath = baseUrl.slice("file://".length);
98
- const src = backendCommon.resolveSafeChildPath(path__default.default.dirname(basePath), fetchUrl);
102
+ const src = backendPluginApi.resolveSafeChildPath(path__default.default.dirname(basePath), fetchUrl);
99
103
  await fs__default.default.copyFile(src, outputPath);
100
104
  } else {
101
105
  const readUrl = getReadUrl(fetchUrl, baseUrl, integrations);
@@ -132,6 +136,231 @@ function getReadUrl(fetchUrl, baseUrl, integrations) {
132
136
  );
133
137
  }
134
138
 
139
+ var __defProp = Object.defineProperty;
140
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
141
+ var __publicField = (obj, key, value) => {
142
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
143
+ return value;
144
+ };
145
+ function isAuthCallbackOptions(options) {
146
+ return "onAuth" in options;
147
+ }
148
+ const _Git = class _Git {
149
+ constructor(config) {
150
+ this.config = config;
151
+ __publicField(this, "headers");
152
+ __publicField(this, "onAuth");
153
+ __publicField(this, "onProgressHandler", () => {
154
+ let currentPhase = "";
155
+ return (event) => {
156
+ var _a, _b;
157
+ if (currentPhase !== event.phase) {
158
+ currentPhase = event.phase;
159
+ (_a = this.config.logger) == null ? void 0 : _a.info(event.phase);
160
+ }
161
+ const total = event.total ? `${Math.round(event.loaded / event.total * 100)}%` : event.loaded;
162
+ (_b = this.config.logger) == null ? void 0 : _b.debug(`status={${event.phase},total={${total}}}`);
163
+ };
164
+ });
165
+ this.onAuth = config.onAuth;
166
+ this.headers = {
167
+ "user-agent": "git/@isomorphic-git",
168
+ ...config.token ? { Authorization: `Bearer ${config.token}` } : {}
169
+ };
170
+ }
171
+ async add(options) {
172
+ var _a;
173
+ const { dir, filepath } = options;
174
+ (_a = this.config.logger) == null ? void 0 : _a.info(`Adding file {dir=${dir},filepath=${filepath}}`);
175
+ return git__default.default.add({ fs: fs__default.default, dir, filepath });
176
+ }
177
+ async addRemote(options) {
178
+ var _a;
179
+ const { dir, url, remote, force } = options;
180
+ (_a = this.config.logger) == null ? void 0 : _a.info(
181
+ `Creating new remote {dir=${dir},remote=${remote},url=${url}}`
182
+ );
183
+ return git__default.default.addRemote({ fs: fs__default.default, dir, remote, url, force });
184
+ }
185
+ async deleteRemote(options) {
186
+ var _a;
187
+ const { dir, remote } = options;
188
+ (_a = this.config.logger) == null ? void 0 : _a.info(`Deleting remote {dir=${dir},remote=${remote}}`);
189
+ return git__default.default.deleteRemote({ fs: fs__default.default, dir, remote });
190
+ }
191
+ async checkout(options) {
192
+ var _a;
193
+ const { dir, ref } = options;
194
+ (_a = this.config.logger) == null ? void 0 : _a.info(`Checking out branch {dir=${dir},ref=${ref}}`);
195
+ return git__default.default.checkout({ fs: fs__default.default, dir, ref });
196
+ }
197
+ async branch(options) {
198
+ var _a;
199
+ const { dir, ref } = options;
200
+ (_a = this.config.logger) == null ? void 0 : _a.info(`Creating branch {dir=${dir},ref=${ref}`);
201
+ return git__default.default.branch({ fs: fs__default.default, dir, ref });
202
+ }
203
+ async commit(options) {
204
+ var _a;
205
+ const { dir, message, author, committer } = options;
206
+ (_a = this.config.logger) == null ? void 0 : _a.info(
207
+ `Committing file to repo {dir=${dir},message=${message}}`
208
+ );
209
+ return git__default.default.commit({ fs: fs__default.default, dir, message, author, committer });
210
+ }
211
+ /** https://isomorphic-git.org/docs/en/clone */
212
+ async clone(options) {
213
+ var _a, _b;
214
+ const { url, dir, ref, depth, noCheckout } = options;
215
+ (_a = this.config.logger) == null ? void 0 : _a.info(`Cloning repo {dir=${dir},url=${url}}`);
216
+ try {
217
+ return await git__default.default.clone({
218
+ fs: fs__default.default,
219
+ http: http__default.default,
220
+ url,
221
+ dir,
222
+ ref,
223
+ singleBranch: true,
224
+ depth: depth != null ? depth : 1,
225
+ noCheckout,
226
+ onProgress: this.onProgressHandler(),
227
+ headers: this.headers,
228
+ onAuth: this.onAuth
229
+ });
230
+ } catch (ex) {
231
+ (_b = this.config.logger) == null ? void 0 : _b.error(`Failed to clone repo {dir=${dir},url=${url}}`);
232
+ if (ex.data) {
233
+ throw new Error(`${ex.message} {data=${JSON.stringify(ex.data)}}`);
234
+ }
235
+ throw ex;
236
+ }
237
+ }
238
+ /** https://isomorphic-git.org/docs/en/currentBranch */
239
+ async currentBranch(options) {
240
+ const { dir, fullName = false } = options;
241
+ return git__default.default.currentBranch({ fs: fs__default.default, dir, fullname: fullName });
242
+ }
243
+ /** https://isomorphic-git.org/docs/en/fetch */
244
+ async fetch(options) {
245
+ var _a, _b;
246
+ const { dir, remote = "origin", tags = false } = options;
247
+ (_a = this.config.logger) == null ? void 0 : _a.info(
248
+ `Fetching remote=${remote} for repository {dir=${dir}}`
249
+ );
250
+ try {
251
+ await git__default.default.fetch({
252
+ fs: fs__default.default,
253
+ http: http__default.default,
254
+ dir,
255
+ remote,
256
+ tags,
257
+ onProgress: this.onProgressHandler(),
258
+ headers: this.headers,
259
+ onAuth: this.onAuth
260
+ });
261
+ } catch (ex) {
262
+ (_b = this.config.logger) == null ? void 0 : _b.error(
263
+ `Failed to fetch repo {dir=${dir},remote=${remote}}`
264
+ );
265
+ if (ex.data) {
266
+ throw new Error(`${ex.message} {data=${JSON.stringify(ex.data)}}`);
267
+ }
268
+ throw ex;
269
+ }
270
+ }
271
+ async init(options) {
272
+ var _a;
273
+ const { dir, defaultBranch = "master" } = options;
274
+ (_a = this.config.logger) == null ? void 0 : _a.info(`Init git repository {dir=${dir}}`);
275
+ return git__default.default.init({
276
+ fs: fs__default.default,
277
+ dir,
278
+ defaultBranch
279
+ });
280
+ }
281
+ /** https://isomorphic-git.org/docs/en/merge */
282
+ async merge(options) {
283
+ var _a;
284
+ const { dir, theirs, ours, author, committer } = options;
285
+ (_a = this.config.logger) == null ? void 0 : _a.info(
286
+ `Merging branch '${theirs}' into '${ours}' for repository {dir=${dir}}`
287
+ );
288
+ return git__default.default.merge({
289
+ fs: fs__default.default,
290
+ dir,
291
+ ours,
292
+ theirs,
293
+ author,
294
+ committer
295
+ });
296
+ }
297
+ async push(options) {
298
+ var _a, _b;
299
+ const { dir, remote, remoteRef, force } = options;
300
+ (_a = this.config.logger) == null ? void 0 : _a.info(
301
+ `Pushing directory to remote {dir=${dir},remote=${remote}}`
302
+ );
303
+ try {
304
+ return await git__default.default.push({
305
+ fs: fs__default.default,
306
+ dir,
307
+ http: http__default.default,
308
+ onProgress: this.onProgressHandler(),
309
+ remoteRef,
310
+ force,
311
+ headers: this.headers,
312
+ remote,
313
+ onAuth: this.onAuth
314
+ });
315
+ } catch (ex) {
316
+ (_b = this.config.logger) == null ? void 0 : _b.error(
317
+ `Failed to push to repo {dir=${dir}, remote=${remote}}`
318
+ );
319
+ if (ex.data) {
320
+ throw new Error(`${ex.message} {data=${JSON.stringify(ex.data)}}`);
321
+ }
322
+ throw ex;
323
+ }
324
+ }
325
+ /** https://isomorphic-git.org/docs/en/readCommit */
326
+ async readCommit(options) {
327
+ const { dir, sha } = options;
328
+ return git__default.default.readCommit({ fs: fs__default.default, dir, oid: sha });
329
+ }
330
+ /** https://isomorphic-git.org/docs/en/remove */
331
+ async remove(options) {
332
+ var _a;
333
+ const { dir, filepath } = options;
334
+ (_a = this.config.logger) == null ? void 0 : _a.info(
335
+ `Removing file from git index {dir=${dir},filepath=${filepath}}`
336
+ );
337
+ return git__default.default.remove({ fs: fs__default.default, dir, filepath });
338
+ }
339
+ /** https://isomorphic-git.org/docs/en/resolveRef */
340
+ async resolveRef(options) {
341
+ const { dir, ref } = options;
342
+ return git__default.default.resolveRef({ fs: fs__default.default, dir, ref });
343
+ }
344
+ /** https://isomorphic-git.org/docs/en/log */
345
+ async log(options) {
346
+ const { dir, ref } = options;
347
+ return git__default.default.log({
348
+ fs: fs__default.default,
349
+ dir,
350
+ ref: ref != null ? ref : "HEAD"
351
+ });
352
+ }
353
+ };
354
+ __publicField(_Git, "fromAuth", (options) => {
355
+ if (isAuthCallbackOptions(options)) {
356
+ const { onAuth, logger: logger2 } = options;
357
+ return new _Git({ onAuth, logger: logger2 });
358
+ }
359
+ const { username, password, token, logger } = options;
360
+ return new _Git({ onAuth: () => ({ username, password }), token, logger });
361
+ });
362
+ let Git = _Git;
363
+
135
364
  async function initRepoAndPush(input) {
136
365
  var _a, _b;
137
366
  const {
@@ -143,7 +372,7 @@ async function initRepoAndPush(input) {
143
372
  commitMessage = "Initial commit",
144
373
  gitAuthorInfo
145
374
  } = input;
146
- const git = backendCommon.Git.fromAuth({
375
+ const git = Git.fromAuth({
147
376
  ...auth,
148
377
  logger
149
378
  });
@@ -184,7 +413,7 @@ async function commitAndPushRepo(input) {
184
413
  branch = "master",
185
414
  remoteRef
186
415
  } = input;
187
- const git = backendCommon.Git.fromAuth({
416
+ const git = Git.fromAuth({
188
417
  ...auth,
189
418
  logger
190
419
  });
@@ -210,7 +439,7 @@ async function commitAndPushRepo(input) {
210
439
  }
211
440
  async function cloneRepo(options) {
212
441
  const { url, dir, auth, logger, ref, depth, noCheckout } = options;
213
- const git = backendCommon.Git.fromAuth({
442
+ const git = Git.fromAuth({
214
443
  ...auth,
215
444
  logger
216
445
  });
@@ -218,7 +447,7 @@ async function cloneRepo(options) {
218
447
  }
219
448
  async function createBranch(options) {
220
449
  const { dir, ref, auth, logger } = options;
221
- const git = backendCommon.Git.fromAuth({
450
+ const git = Git.fromAuth({
222
451
  ...auth,
223
452
  logger
224
453
  });
@@ -226,7 +455,7 @@ async function createBranch(options) {
226
455
  }
227
456
  async function addFiles(options) {
228
457
  const { dir, filepath, auth, logger } = options;
229
- const git = backendCommon.Git.fromAuth({
458
+ const git = Git.fromAuth({
230
459
  ...auth,
231
460
  logger
232
461
  });
@@ -244,7 +473,7 @@ async function commitAndPushBranch(options) {
244
473
  remoteRef,
245
474
  remote = "origin"
246
475
  } = options;
247
- const git = backendCommon.Git.fromAuth({
476
+ const git = Git.fromAuth({
248
477
  ...auth,
249
478
  logger
250
479
  });
@@ -273,7 +502,7 @@ const getRepoSourceDirectory = (workspacePath, sourcePath) => {
273
502
  ""
274
503
  );
275
504
  const path$1 = path.join(workspacePath, safeSuffix);
276
- if (!backendCommon.isChildPath(workspacePath, path$1)) {
505
+ if (!backendPluginApi.isChildPath(workspacePath, path$1)) {
277
506
  throw new Error("Invalid source path");
278
507
  }
279
508
  return path$1;
@@ -373,7 +602,7 @@ async function serializeDirectoryContents(sourcePath, options) {
373
602
  return false;
374
603
  if (!dirent.isSymbolicLink())
375
604
  return true;
376
- const safePath = backendCommon.resolveSafeChildPath(sourcePath, path);
605
+ const safePath = backendPluginApi.resolveSafeChildPath(sourcePath, path);
377
606
  try {
378
607
  await fs$1.promises.stat(safePath);
379
608
  return false;
@@ -385,7 +614,7 @@ async function serializeDirectoryContents(sourcePath, options) {
385
614
  valid.map(async ({ dirent, path, stats }) => ({
386
615
  path,
387
616
  content: await limiter(async () => {
388
- const absFilePath = backendCommon.resolveSafeChildPath(sourcePath, path);
617
+ const absFilePath = backendPluginApi.resolveSafeChildPath(sourcePath, path);
389
618
  if (dirent.isSymbolicLink()) {
390
619
  return fs$1.promises.readlink(absFilePath, "buffer");
391
620
  }
@@ -399,7 +628,7 @@ async function serializeDirectoryContents(sourcePath, options) {
399
628
 
400
629
  async function deserializeDirectoryContents(targetPath, files) {
401
630
  for (const file of files) {
402
- const filePath = backendCommon.resolveSafeChildPath(targetPath, file.path);
631
+ const filePath = backendPluginApi.resolveSafeChildPath(targetPath, file.path);
403
632
  await fs__default.default.ensureDir(path.dirname(filePath));
404
633
  await fs__default.default.writeFile(filePath, file.content);
405
634
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/actions/createTemplateAction.ts","../src/actions/executeShellCommand.ts","../src/actions/fetch.ts","../src/actions/gitHelpers.ts","../src/actions/util.ts","../src/files/serializeDirectoryContents.ts","../src/files/deserializeDirectoryContents.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 { ActionContext, TemplateAction } from './types';\nimport { z } from 'zod';\nimport { Schema } from 'jsonschema';\nimport zodToJsonSchema from 'zod-to-json-schema';\nimport { JsonObject } from '@backstage/types';\n\n/** @public */\nexport type TemplateExample = {\n description: string;\n example: string;\n};\n\n/** @public */\nexport type TemplateActionOptions<\n TActionInput extends JsonObject = {},\n TActionOutput extends JsonObject = {},\n TInputSchema extends Schema | z.ZodType = {},\n TOutputSchema extends Schema | z.ZodType = {},\n> = {\n id: string;\n description?: string;\n examples?: TemplateExample[];\n supportsDryRun?: boolean;\n schema?: {\n input?: TInputSchema;\n output?: TOutputSchema;\n };\n handler: (ctx: ActionContext<TActionInput, TActionOutput>) => Promise<void>;\n};\n\n/**\n * This function is used to create new template actions to get type safety.\n * Will convert zod schemas to json schemas for use throughout the system.\n * @public\n */\nexport const createTemplateAction = <\n TInputParams extends JsonObject = JsonObject,\n TOutputParams extends JsonObject = JsonObject,\n TInputSchema extends Schema | z.ZodType = {},\n TOutputSchema extends Schema | z.ZodType = {},\n TActionInput extends JsonObject = TInputSchema extends z.ZodType<\n any,\n any,\n infer IReturn\n >\n ? IReturn\n : TInputParams,\n TActionOutput extends JsonObject = TOutputSchema extends z.ZodType<\n any,\n any,\n infer IReturn\n >\n ? IReturn\n : TOutputParams,\n>(\n action: TemplateActionOptions<\n TActionInput,\n TActionOutput,\n TInputSchema,\n TOutputSchema\n >,\n): TemplateAction<TActionInput, TActionOutput> => {\n const inputSchema =\n action.schema?.input && 'safeParseAsync' in action.schema.input\n ? zodToJsonSchema(action.schema.input)\n : action.schema?.input;\n\n const outputSchema =\n action.schema?.output && 'safeParseAsync' in action.schema.output\n ? zodToJsonSchema(action.schema.output)\n : action.schema?.output;\n\n return {\n ...action,\n schema: {\n ...action.schema,\n input: inputSchema as TInputSchema,\n output: outputSchema as TOutputSchema,\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 { spawn, SpawnOptionsWithoutStdio } from 'child_process';\nimport { PassThrough, Writable } from 'stream';\n\n/**\n * Options for {@link executeShellCommand}.\n *\n * @public\n */\nexport type ExecuteShellCommandOptions = {\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 async function executeShellCommand(\n options: ExecuteShellCommandOptions,\n): Promise<void> {\n const {\n command,\n args,\n options: spawnOptions,\n logStream = new PassThrough(),\n } = options;\n\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","/*\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(options: {\n reader: UrlReader;\n integrations: ScmIntegrations;\n baseUrl?: string;\n fetchUrl?: string;\n outputPath: string;\n token?: string;\n}) {\n const {\n reader,\n integrations,\n baseUrl,\n fetchUrl = '.',\n outputPath,\n token,\n } = options;\n\n const fetchUrlIsAbsolute = isFetchUrlAbsolute(fetchUrl);\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 const readUrl = getReadUrl(fetchUrl, baseUrl, integrations);\n\n const res = await reader.readTree(readUrl, { token });\n await fs.ensureDir(outputPath);\n await res.dir({ targetDir: outputPath });\n }\n}\n\n/**\n * A helper function that reads the content of a single file from the given URL.\n * Can be used in your own actions, and also used behind `fetch:plain:file`\n *\n * @public\n */\nexport async function fetchFile(options: {\n reader: UrlReader;\n integrations: ScmIntegrations;\n baseUrl?: string;\n fetchUrl?: string;\n outputPath: string;\n token?: string;\n}) {\n const {\n reader,\n integrations,\n baseUrl,\n fetchUrl = '.',\n outputPath,\n token,\n } = options;\n\n const fetchUrlIsAbsolute = isFetchUrlAbsolute(fetchUrl);\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 src = resolveSafeChildPath(path.dirname(basePath), fetchUrl);\n await fs.copyFile(src, outputPath);\n } else {\n const readUrl = getReadUrl(fetchUrl, baseUrl, integrations);\n\n const res = await reader.readUrl(readUrl, { token });\n await fs.ensureDir(path.dirname(outputPath));\n const buffer = await res.buffer();\n await fs.outputFile(outputPath, buffer);\n }\n}\n\nfunction isFetchUrlAbsolute(fetchUrl: string) {\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 return fetchUrlIsAbsolute;\n}\n\nfunction getReadUrl(\n fetchUrl: string,\n baseUrl: string | undefined,\n integrations: ScmIntegrations,\n) {\n if (isFetchUrlAbsolute(fetchUrl)) {\n return 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 return integration.resolveUrl({\n url: fetchUrl,\n base: baseUrl,\n });\n }\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 * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Git } from '@backstage/backend-common';\nimport { Logger } from 'winston';\n\n/**\n * @public\n */\nexport async function initRepoAndPush(input: {\n dir: string;\n remoteUrl: string;\n // For use cases where token has to be used with Basic Auth\n // it has to be provided as password together with a username\n // which may be a fixed value defined by the provider.\n auth: { username: string; password: string } | { token: string };\n logger: Logger;\n defaultBranch?: string;\n commitMessage?: string;\n gitAuthorInfo?: { name?: string; email?: string };\n}): Promise<{ commitHash: string }> {\n const {\n dir,\n remoteUrl,\n auth,\n logger,\n defaultBranch = 'master',\n commitMessage = 'Initial commit',\n gitAuthorInfo,\n } = input;\n const git = Git.fromAuth({\n ...auth,\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 const commitHash = await git.commit({\n dir,\n message: commitMessage,\n author: authorInfo,\n committer: authorInfo,\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 return { commitHash };\n}\n\n/**\n * @public\n */\nexport async function commitAndPushRepo(input: {\n dir: string;\n // For use cases where token has to be used with Basic Auth\n // it has to be provided as password together with a username\n // which may be a fixed value defined by the provider.\n auth: { username: string; password: string } | { token: string };\n logger: Logger;\n commitMessage: string;\n gitAuthorInfo?: { name?: string; email?: string };\n branch?: string;\n remoteRef?: string;\n}): Promise<{ commitHash: string }> {\n const {\n dir,\n auth,\n logger,\n commitMessage,\n gitAuthorInfo,\n branch = 'master',\n remoteRef,\n } = input;\n\n const git = Git.fromAuth({\n ...auth,\n logger,\n });\n\n await git.fetch({ dir });\n await git.checkout({ dir, ref: branch });\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 const commitHash = await git.commit({\n dir,\n message: commitMessage,\n author: authorInfo,\n committer: authorInfo,\n });\n\n await git.push({\n dir,\n remote: 'origin',\n remoteRef: remoteRef ?? `refs/heads/${branch}`,\n });\n\n return { commitHash };\n}\n\n/**\n * @public\n */\nexport async function cloneRepo(options: {\n url: string;\n dir: string;\n // For use cases where token has to be used with Basic Auth\n // it has to be provided as password together with a username\n // which may be a fixed value defined by the provider.\n auth: { username: string; password: string } | { token: string };\n logger?: Logger | undefined;\n ref?: string | undefined;\n depth?: number | undefined;\n noCheckout?: boolean | undefined;\n}): Promise<void> {\n const { url, dir, auth, logger, ref, depth, noCheckout } = options;\n\n const git = Git.fromAuth({\n ...auth,\n logger,\n });\n\n await git.clone({ url, dir, ref, depth, noCheckout });\n}\n\n/**\n * @public\n */\nexport async function createBranch(options: {\n dir: string;\n ref: string;\n // For use cases where token has to be used with Basic Auth\n // it has to be provided as password together with a username\n // which may be a fixed value defined by the provider.\n auth: { username: string; password: string } | { token: string };\n logger?: Logger | undefined;\n}): Promise<void> {\n const { dir, ref, auth, logger } = options;\n const git = Git.fromAuth({\n ...auth,\n logger,\n });\n\n await git.checkout({ dir, ref });\n}\n\n/**\n * @public\n */\nexport async function addFiles(options: {\n dir: string;\n filepath: string;\n // For use cases where token has to be used with Basic Auth\n // it has to be provided as password together with a username\n // which may be a fixed value defined by the provider.\n auth: { username: string; password: string } | { token: string };\n logger?: Logger | undefined;\n}): Promise<void> {\n const { dir, filepath, auth, logger } = options;\n const git = Git.fromAuth({\n ...auth,\n logger,\n });\n\n await git.add({ dir, filepath });\n}\n\n/**\n * @public\n */\nexport async function commitAndPushBranch(options: {\n dir: string;\n // For use cases where token has to be used with Basic Auth\n // it has to be provided as password together with a username\n // which may be a fixed value defined by the provider.\n auth: { username: string; password: string } | { token: string };\n logger?: Logger | undefined;\n commitMessage: string;\n gitAuthorInfo?: { name?: string; email?: string };\n branch?: string;\n remoteRef?: string;\n remote?: string;\n}): Promise<{ commitHash: string }> {\n const {\n dir,\n auth,\n logger,\n commitMessage,\n gitAuthorInfo,\n branch = 'master',\n remoteRef,\n remote = 'origin',\n } = options;\n const git = Git.fromAuth({\n ...auth,\n logger,\n });\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 const commitHash = await git.commit({\n dir,\n message: commitMessage,\n author: authorInfo,\n committer: authorInfo,\n });\n\n await git.push({\n dir,\n remote,\n remoteRef: remoteRef ?? `refs/heads/${branch}`,\n });\n\n return { commitHash };\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\n/**\n * @public\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};\n\n/**\n * @public\n */\nexport const parseRepoUrl = (\n repoUrl: string,\n integrations: ScmIntegrationRegistry,\n): {\n repo: string;\n host: string;\n owner?: string;\n organization?: string;\n workspace?: string;\n project?: string;\n} => {\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 const repo: string = parsed.searchParams.get('repo')!;\n switch (type) {\n case 'bitbucket': {\n if (host === 'www.bitbucket.org') {\n checkRequiredParams(parsed, 'workspace');\n }\n checkRequiredParams(parsed, 'project', 'repo');\n break;\n }\n case 'gitlab': {\n // project is the projectID, and if defined, owner and repo won't be needed.\n if (!project) {\n checkRequiredParams(parsed, 'owner', 'repo');\n }\n break;\n }\n case 'gitea': {\n checkRequiredParams(parsed, 'repo');\n break;\n }\n case 'gerrit': {\n checkRequiredParams(parsed, 'repo');\n break;\n }\n default: {\n checkRequiredParams(parsed, 'repo', 'owner');\n break;\n }\n }\n\n return { host, owner, repo, organization, workspace, project };\n};\n\nfunction checkRequiredParams(repoUrl: URL, ...params: string[]) {\n for (let i = 0; i < params.length; i++) {\n if (!repoUrl.searchParams.get(params[i])) {\n throw new InputError(\n `Invalid repo URL passed to publisher: ${repoUrl.toString()}, missing ${\n params[i]\n }`,\n );\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 */\n\nimport { promises as fs } from 'fs';\nimport globby from 'globby';\nimport limiterFactory from 'p-limit';\nimport { resolveSafeChildPath } from '@backstage/backend-common';\nimport { SerializedFile } from './types';\nimport { isError } from '@backstage/errors';\n\nconst DEFAULT_GLOB_PATTERNS = ['./**', '!.git'];\n\nexport const isExecutable = (fileMode: number | undefined) => {\n if (!fileMode) {\n return false;\n }\n\n const executeBitMask = 0o000111;\n const res = fileMode & executeBitMask;\n return res > 0;\n};\n\nasync function asyncFilter<T>(\n array: T[],\n callback: (value: T, index: number, array: T[]) => Promise<boolean>,\n): Promise<T[]> {\n const filterMap = await Promise.all(array.map(callback));\n return array.filter((_value, index) => filterMap[index]);\n}\n\n/**\n * @public\n */\nexport async function serializeDirectoryContents(\n sourcePath: string,\n options?: {\n gitignore?: boolean;\n globPatterns?: string[];\n },\n): Promise<SerializedFile[]> {\n const paths = await globby(options?.globPatterns ?? DEFAULT_GLOB_PATTERNS, {\n cwd: sourcePath,\n dot: true,\n gitignore: options?.gitignore,\n followSymbolicLinks: false,\n // In order to pick up 'broken' symlinks, we oxymoronically request files AND folders yet we filter out folders\n // This is because broken symlinks aren't classed as files so we need to glob everything\n onlyFiles: false,\n objectMode: true,\n stats: true,\n });\n\n const limiter = limiterFactory(10);\n\n const valid = await asyncFilter(paths, async ({ dirent, path }) => {\n if (dirent.isDirectory()) return false;\n if (!dirent.isSymbolicLink()) return true;\n\n const safePath = resolveSafeChildPath(sourcePath, path);\n\n // we only want files that don't exist\n try {\n await fs.stat(safePath);\n return false;\n } catch (e) {\n return isError(e) && e.code === 'ENOENT';\n }\n });\n\n return Promise.all(\n valid.map(async ({ dirent, path, stats }) => ({\n path,\n content: await limiter(async () => {\n const absFilePath = resolveSafeChildPath(sourcePath, path);\n if (dirent.isSymbolicLink()) {\n return fs.readlink(absFilePath, 'buffer');\n }\n return fs.readFile(absFilePath);\n }),\n executable: isExecutable(stats?.mode),\n symlink: dirent.isSymbolicLink(),\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 */\n\nimport fs from 'fs-extra';\nimport { dirname } from 'path';\nimport { resolveSafeChildPath } from '@backstage/backend-common';\nimport { SerializedFile } from './types';\n\n/**\n * Deserializes a list of serialized files into the target directory.\n *\n * This method uses `resolveSafeChildPath` to make sure that files are\n * not written outside of the target directory.\n *\n * @public\n */\nexport async function deserializeDirectoryContents(\n targetPath: string,\n files: SerializedFile[],\n): Promise<void> {\n for (const file of files) {\n const filePath = resolveSafeChildPath(targetPath, file.path);\n await fs.ensureDir(dirname(filePath));\n await fs.writeFile(filePath, file.content); // Ignore file mode\n }\n}\n"],"names":["zodToJsonSchema","PassThrough","spawn","resolveSafeChildPath","path","fs","InputError","Git","normalizePath","joinPath","isChildPath","globby","limiterFactory","isError","dirname"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/actions/createTemplateAction.ts","../src/actions/executeShellCommand.ts","../src/actions/fetch.ts","../src/scm/git.ts","../src/actions/gitHelpers.ts","../src/actions/util.ts","../src/files/serializeDirectoryContents.ts","../src/files/deserializeDirectoryContents.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 { ActionContext, TemplateAction } from './types';\nimport { z } from 'zod';\nimport { Schema } from 'jsonschema';\nimport zodToJsonSchema from 'zod-to-json-schema';\nimport { JsonObject } from '@backstage/types';\n\n/** @public */\nexport type TemplateExample = {\n description: string;\n example: string;\n};\n\n/** @public */\nexport type TemplateActionOptions<\n TActionInput extends JsonObject = {},\n TActionOutput extends JsonObject = {},\n TInputSchema extends Schema | z.ZodType = {},\n TOutputSchema extends Schema | z.ZodType = {},\n> = {\n id: string;\n description?: string;\n examples?: TemplateExample[];\n supportsDryRun?: boolean;\n schema?: {\n input?: TInputSchema;\n output?: TOutputSchema;\n };\n handler: (ctx: ActionContext<TActionInput, TActionOutput>) => Promise<void>;\n};\n\n/**\n * This function is used to create new template actions to get type safety.\n * Will convert zod schemas to json schemas for use throughout the system.\n * @public\n */\nexport const createTemplateAction = <\n TInputParams extends JsonObject = JsonObject,\n TOutputParams extends JsonObject = JsonObject,\n TInputSchema extends Schema | z.ZodType = {},\n TOutputSchema extends Schema | z.ZodType = {},\n TActionInput extends JsonObject = TInputSchema extends z.ZodType<\n any,\n any,\n infer IReturn\n >\n ? IReturn\n : TInputParams,\n TActionOutput extends JsonObject = TOutputSchema extends z.ZodType<\n any,\n any,\n infer IReturn\n >\n ? IReturn\n : TOutputParams,\n>(\n action: TemplateActionOptions<\n TActionInput,\n TActionOutput,\n TInputSchema,\n TOutputSchema\n >,\n): TemplateAction<TActionInput, TActionOutput> => {\n const inputSchema =\n action.schema?.input && 'safeParseAsync' in action.schema.input\n ? zodToJsonSchema(action.schema.input)\n : action.schema?.input;\n\n const outputSchema =\n action.schema?.output && 'safeParseAsync' in action.schema.output\n ? zodToJsonSchema(action.schema.output)\n : action.schema?.output;\n\n return {\n ...action,\n schema: {\n ...action.schema,\n input: inputSchema as TInputSchema,\n output: outputSchema as TOutputSchema,\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 { spawn, SpawnOptionsWithoutStdio } from 'child_process';\nimport { PassThrough, Writable } from 'stream';\n\n/**\n * Options for {@link executeShellCommand}.\n *\n * @public\n */\nexport type ExecuteShellCommandOptions = {\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 async function executeShellCommand(\n options: ExecuteShellCommandOptions,\n): Promise<void> {\n const {\n command,\n args,\n options: spawnOptions,\n logStream = new PassThrough(),\n } = options;\n\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","/*\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 { resolveSafeChildPath } from '@backstage/backend-plugin-api';\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(options: {\n reader: UrlReader;\n integrations: ScmIntegrations;\n baseUrl?: string;\n fetchUrl?: string;\n outputPath: string;\n token?: string;\n}) {\n const {\n reader,\n integrations,\n baseUrl,\n fetchUrl = '.',\n outputPath,\n token,\n } = options;\n\n const fetchUrlIsAbsolute = isFetchUrlAbsolute(fetchUrl);\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 const readUrl = getReadUrl(fetchUrl, baseUrl, integrations);\n\n const res = await reader.readTree(readUrl, { token });\n await fs.ensureDir(outputPath);\n await res.dir({ targetDir: outputPath });\n }\n}\n\n/**\n * A helper function that reads the content of a single file from the given URL.\n * Can be used in your own actions, and also used behind `fetch:plain:file`\n *\n * @public\n */\nexport async function fetchFile(options: {\n reader: UrlReader;\n integrations: ScmIntegrations;\n baseUrl?: string;\n fetchUrl?: string;\n outputPath: string;\n token?: string;\n}) {\n const {\n reader,\n integrations,\n baseUrl,\n fetchUrl = '.',\n outputPath,\n token,\n } = options;\n\n const fetchUrlIsAbsolute = isFetchUrlAbsolute(fetchUrl);\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 src = resolveSafeChildPath(path.dirname(basePath), fetchUrl);\n await fs.copyFile(src, outputPath);\n } else {\n const readUrl = getReadUrl(fetchUrl, baseUrl, integrations);\n\n const res = await reader.readUrl(readUrl, { token });\n await fs.ensureDir(path.dirname(outputPath));\n const buffer = await res.buffer();\n await fs.outputFile(outputPath, buffer);\n }\n}\n\nfunction isFetchUrlAbsolute(fetchUrl: string) {\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 return fetchUrlIsAbsolute;\n}\n\nfunction getReadUrl(\n fetchUrl: string,\n baseUrl: string | undefined,\n integrations: ScmIntegrations,\n) {\n if (isFetchUrlAbsolute(fetchUrl)) {\n return 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 return integration.resolveUrl({\n url: fetchUrl,\n base: baseUrl,\n });\n }\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 * 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 git, {\n ProgressCallback,\n MergeResult,\n ReadCommitResult,\n AuthCallback,\n} from 'isomorphic-git';\nimport http from 'isomorphic-git/http/node';\nimport fs from 'fs-extra';\nimport { LoggerService } from '@backstage/backend-plugin-api';\n\nfunction isAuthCallbackOptions(\n options: StaticAuthOptions | AuthCallbackOptions,\n): options is AuthCallbackOptions {\n return 'onAuth' in options;\n}\n\n/**\n * Configure static credential for authentication\n *\n * @public\n */\nexport type StaticAuthOptions = {\n username?: string;\n password?: string;\n token?: string;\n logger?: LoggerService;\n};\n\n/**\n * Configure an authentication callback that can provide credentials on demand\n *\n * @public\n */\nexport type AuthCallbackOptions = {\n onAuth: AuthCallback;\n logger?: LoggerService;\n};\n\n/*\nprovider username password\nAzure 'notempty' token\nBitbucket Cloud 'x-token-auth' token\nBitbucket Server username password or token\nGitHub 'x-access-token' token\nGitLab 'oauth2' token\n\nFrom : https://isomorphic-git.org/docs/en/onAuth with fix for GitHub\n\nOr token provided as `token` for Bearer auth header\ninstead of Basic Auth (e.g., Bitbucket Server).\n*/\n\n/**\n * A convenience wrapper around the `isomorphic-git` library.\n *\n * @public\n */\n\nexport class Git {\n private readonly headers: {\n [x: string]: string;\n };\n\n private constructor(\n private readonly config: {\n onAuth: AuthCallback;\n token?: string;\n logger?: LoggerService;\n },\n ) {\n this.onAuth = config.onAuth;\n\n this.headers = {\n 'user-agent': 'git/@isomorphic-git',\n ...(config.token ? { Authorization: `Bearer ${config.token}` } : {}),\n };\n }\n\n async add(options: { dir: string; filepath: string }): Promise<void> {\n const { dir, filepath } = options;\n this.config.logger?.info(`Adding file {dir=${dir},filepath=${filepath}}`);\n\n return git.add({ fs, dir, filepath });\n }\n\n async addRemote(options: {\n dir: string;\n remote: string;\n url: string;\n force?: boolean;\n }): Promise<void> {\n const { dir, url, remote, force } = options;\n this.config.logger?.info(\n `Creating new remote {dir=${dir},remote=${remote},url=${url}}`,\n );\n return git.addRemote({ fs, dir, remote, url, force });\n }\n\n async deleteRemote(options: { dir: string; remote: string }): Promise<void> {\n const { dir, remote } = options;\n this.config.logger?.info(`Deleting remote {dir=${dir},remote=${remote}}`);\n return git.deleteRemote({ fs, dir, remote });\n }\n\n async checkout(options: { dir: string; ref: string }): Promise<void> {\n const { dir, ref } = options;\n this.config.logger?.info(`Checking out branch {dir=${dir},ref=${ref}}`);\n\n return git.checkout({ fs, dir, ref });\n }\n\n async branch(options: { dir: string; ref: string }): Promise<void> {\n const { dir, ref } = options;\n this.config.logger?.info(`Creating branch {dir=${dir},ref=${ref}`);\n\n return git.branch({ fs, dir, ref });\n }\n\n async commit(options: {\n dir: string;\n message: string;\n author: { name: string; email: string };\n committer: { name: string; email: string };\n }): Promise<string> {\n const { dir, message, author, committer } = options;\n this.config.logger?.info(\n `Committing file to repo {dir=${dir},message=${message}}`,\n );\n return git.commit({ fs, dir, message, author, committer });\n }\n\n /** https://isomorphic-git.org/docs/en/clone */\n async clone(options: {\n url: string;\n dir: string;\n ref?: string;\n depth?: number;\n noCheckout?: boolean;\n }): Promise<void> {\n const { url, dir, ref, depth, noCheckout } = options;\n this.config.logger?.info(`Cloning repo {dir=${dir},url=${url}}`);\n\n try {\n return await git.clone({\n fs,\n http,\n url,\n dir,\n ref,\n singleBranch: true,\n depth: depth ?? 1,\n noCheckout,\n onProgress: this.onProgressHandler(),\n headers: this.headers,\n onAuth: this.onAuth,\n });\n } catch (ex) {\n this.config.logger?.error(`Failed to clone repo {dir=${dir},url=${url}}`);\n if (ex.data) {\n throw new Error(`${ex.message} {data=${JSON.stringify(ex.data)}}`);\n }\n throw ex;\n }\n }\n\n /** https://isomorphic-git.org/docs/en/currentBranch */\n async currentBranch(options: {\n dir: string;\n fullName?: boolean;\n }): Promise<string | undefined> {\n const { dir, fullName = false } = options;\n return git.currentBranch({ fs, dir, fullname: fullName }) as Promise<\n string | undefined\n >;\n }\n\n /** https://isomorphic-git.org/docs/en/fetch */\n async fetch(options: {\n dir: string;\n remote?: string;\n tags?: boolean;\n }): Promise<void> {\n const { dir, remote = 'origin', tags = false } = options;\n this.config.logger?.info(\n `Fetching remote=${remote} for repository {dir=${dir}}`,\n );\n\n try {\n await git.fetch({\n fs,\n http,\n dir,\n remote,\n tags,\n onProgress: this.onProgressHandler(),\n headers: this.headers,\n onAuth: this.onAuth,\n });\n } catch (ex) {\n this.config.logger?.error(\n `Failed to fetch repo {dir=${dir},remote=${remote}}`,\n );\n if (ex.data) {\n throw new Error(`${ex.message} {data=${JSON.stringify(ex.data)}}`);\n }\n throw ex;\n }\n }\n\n async init(options: { dir: string; defaultBranch?: string }): Promise<void> {\n const { dir, defaultBranch = 'master' } = options;\n this.config.logger?.info(`Init git repository {dir=${dir}}`);\n\n return git.init({\n fs,\n dir,\n defaultBranch,\n });\n }\n\n /** https://isomorphic-git.org/docs/en/merge */\n async merge(options: {\n dir: string;\n theirs: string;\n ours?: string;\n author: { name: string; email: string };\n committer: { name: string; email: string };\n }): Promise<MergeResult> {\n const { dir, theirs, ours, author, committer } = options;\n this.config.logger?.info(\n `Merging branch '${theirs}' into '${ours}' for repository {dir=${dir}}`,\n );\n\n // If ours is undefined, current branch is used.\n return git.merge({\n fs,\n dir,\n ours,\n theirs,\n author,\n committer,\n });\n }\n\n async push(options: {\n dir: string;\n remote: string;\n remoteRef?: string;\n force?: boolean;\n }) {\n const { dir, remote, remoteRef, force } = options;\n this.config.logger?.info(\n `Pushing directory to remote {dir=${dir},remote=${remote}}`,\n );\n try {\n return await git.push({\n fs,\n dir,\n http,\n onProgress: this.onProgressHandler(),\n remoteRef,\n force,\n headers: this.headers,\n remote,\n onAuth: this.onAuth,\n });\n } catch (ex) {\n this.config.logger?.error(\n `Failed to push to repo {dir=${dir}, remote=${remote}}`,\n );\n if (ex.data) {\n throw new Error(`${ex.message} {data=${JSON.stringify(ex.data)}}`);\n }\n throw ex;\n }\n }\n\n /** https://isomorphic-git.org/docs/en/readCommit */\n async readCommit(options: {\n dir: string;\n sha: string;\n }): Promise<ReadCommitResult> {\n const { dir, sha } = options;\n return git.readCommit({ fs, dir, oid: sha });\n }\n\n /** https://isomorphic-git.org/docs/en/remove */\n async remove(options: { dir: string; filepath: string }): Promise<void> {\n const { dir, filepath } = options;\n this.config.logger?.info(\n `Removing file from git index {dir=${dir},filepath=${filepath}}`,\n );\n return git.remove({ fs, dir, filepath });\n }\n\n /** https://isomorphic-git.org/docs/en/resolveRef */\n async resolveRef(options: { dir: string; ref: string }): Promise<string> {\n const { dir, ref } = options;\n return git.resolveRef({ fs, dir, ref });\n }\n\n /** https://isomorphic-git.org/docs/en/log */\n async log(options: {\n dir: string;\n ref?: string;\n }): Promise<ReadCommitResult[]> {\n const { dir, ref } = options;\n return git.log({\n fs,\n dir,\n ref: ref ?? 'HEAD',\n });\n }\n\n private onAuth: AuthCallback;\n\n private onProgressHandler = (): ProgressCallback => {\n let currentPhase = '';\n\n return event => {\n if (currentPhase !== event.phase) {\n currentPhase = event.phase;\n this.config.logger?.info(event.phase);\n }\n const total = event.total\n ? `${Math.round((event.loaded / event.total) * 100)}%`\n : event.loaded;\n this.config.logger?.debug(`status={${event.phase},total={${total}}}`);\n };\n };\n\n static fromAuth = (options: StaticAuthOptions | AuthCallbackOptions) => {\n if (isAuthCallbackOptions(options)) {\n const { onAuth, logger } = options;\n return new Git({ onAuth, logger });\n }\n\n const { username, password, token, logger } = options;\n return new Git({ onAuth: () => ({ username, password }), token, logger });\n };\n}\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Logger } from 'winston';\nimport { Git } from '../scm';\n\n/**\n * @public\n */\nexport async function initRepoAndPush(input: {\n dir: string;\n remoteUrl: string;\n // For use cases where token has to be used with Basic Auth\n // it has to be provided as password together with a username\n // which may be a fixed value defined by the provider.\n auth: { username: string; password: string } | { token: string };\n logger: Logger;\n defaultBranch?: string;\n commitMessage?: string;\n gitAuthorInfo?: { name?: string; email?: string };\n}): Promise<{ commitHash: string }> {\n const {\n dir,\n remoteUrl,\n auth,\n logger,\n defaultBranch = 'master',\n commitMessage = 'Initial commit',\n gitAuthorInfo,\n } = input;\n const git = Git.fromAuth({\n ...auth,\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 const commitHash = await git.commit({\n dir,\n message: commitMessage,\n author: authorInfo,\n committer: authorInfo,\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 return { commitHash };\n}\n\n/**\n * @public\n */\nexport async function commitAndPushRepo(input: {\n dir: string;\n // For use cases where token has to be used with Basic Auth\n // it has to be provided as password together with a username\n // which may be a fixed value defined by the provider.\n auth: { username: string; password: string } | { token: string };\n logger: Logger;\n commitMessage: string;\n gitAuthorInfo?: { name?: string; email?: string };\n branch?: string;\n remoteRef?: string;\n}): Promise<{ commitHash: string }> {\n const {\n dir,\n auth,\n logger,\n commitMessage,\n gitAuthorInfo,\n branch = 'master',\n remoteRef,\n } = input;\n\n const git = Git.fromAuth({\n ...auth,\n logger,\n });\n\n await git.fetch({ dir });\n await git.checkout({ dir, ref: branch });\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 const commitHash = await git.commit({\n dir,\n message: commitMessage,\n author: authorInfo,\n committer: authorInfo,\n });\n\n await git.push({\n dir,\n remote: 'origin',\n remoteRef: remoteRef ?? `refs/heads/${branch}`,\n });\n\n return { commitHash };\n}\n\n/**\n * @public\n */\nexport async function cloneRepo(options: {\n url: string;\n dir: string;\n // For use cases where token has to be used with Basic Auth\n // it has to be provided as password together with a username\n // which may be a fixed value defined by the provider.\n auth: { username: string; password: string } | { token: string };\n logger?: Logger | undefined;\n ref?: string | undefined;\n depth?: number | undefined;\n noCheckout?: boolean | undefined;\n}): Promise<void> {\n const { url, dir, auth, logger, ref, depth, noCheckout } = options;\n\n const git = Git.fromAuth({\n ...auth,\n logger,\n });\n\n await git.clone({ url, dir, ref, depth, noCheckout });\n}\n\n/**\n * @public\n */\nexport async function createBranch(options: {\n dir: string;\n ref: string;\n // For use cases where token has to be used with Basic Auth\n // it has to be provided as password together with a username\n // which may be a fixed value defined by the provider.\n auth: { username: string; password: string } | { token: string };\n logger?: Logger | undefined;\n}): Promise<void> {\n const { dir, ref, auth, logger } = options;\n const git = Git.fromAuth({\n ...auth,\n logger,\n });\n\n await git.checkout({ dir, ref });\n}\n\n/**\n * @public\n */\nexport async function addFiles(options: {\n dir: string;\n filepath: string;\n // For use cases where token has to be used with Basic Auth\n // it has to be provided as password together with a username\n // which may be a fixed value defined by the provider.\n auth: { username: string; password: string } | { token: string };\n logger?: Logger | undefined;\n}): Promise<void> {\n const { dir, filepath, auth, logger } = options;\n const git = Git.fromAuth({\n ...auth,\n logger,\n });\n\n await git.add({ dir, filepath });\n}\n\n/**\n * @public\n */\nexport async function commitAndPushBranch(options: {\n dir: string;\n // For use cases where token has to be used with Basic Auth\n // it has to be provided as password together with a username\n // which may be a fixed value defined by the provider.\n auth: { username: string; password: string } | { token: string };\n logger?: Logger | undefined;\n commitMessage: string;\n gitAuthorInfo?: { name?: string; email?: string };\n branch?: string;\n remoteRef?: string;\n remote?: string;\n}): Promise<{ commitHash: string }> {\n const {\n dir,\n auth,\n logger,\n commitMessage,\n gitAuthorInfo,\n branch = 'master',\n remoteRef,\n remote = 'origin',\n } = options;\n const git = Git.fromAuth({\n ...auth,\n logger,\n });\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 const commitHash = await git.commit({\n dir,\n message: commitMessage,\n author: authorInfo,\n committer: authorInfo,\n });\n\n await git.push({\n dir,\n remote,\n remoteRef: remoteRef ?? `refs/heads/${branch}`,\n });\n\n return { commitHash };\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-plugin-api';\nimport { join as joinPath, normalize as normalizePath } from 'path';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\n\n/**\n * @public\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};\n\n/**\n * @public\n */\nexport const parseRepoUrl = (\n repoUrl: string,\n integrations: ScmIntegrationRegistry,\n): {\n repo: string;\n host: string;\n owner?: string;\n organization?: string;\n workspace?: string;\n project?: string;\n} => {\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 const repo: string = parsed.searchParams.get('repo')!;\n switch (type) {\n case 'bitbucket': {\n if (host === 'www.bitbucket.org') {\n checkRequiredParams(parsed, 'workspace');\n }\n checkRequiredParams(parsed, 'project', 'repo');\n break;\n }\n case 'gitlab': {\n // project is the projectID, and if defined, owner and repo won't be needed.\n if (!project) {\n checkRequiredParams(parsed, 'owner', 'repo');\n }\n break;\n }\n case 'gitea': {\n checkRequiredParams(parsed, 'repo');\n break;\n }\n case 'gerrit': {\n checkRequiredParams(parsed, 'repo');\n break;\n }\n default: {\n checkRequiredParams(parsed, 'repo', 'owner');\n break;\n }\n }\n\n return { host, owner, repo, organization, workspace, project };\n};\n\nfunction checkRequiredParams(repoUrl: URL, ...params: string[]) {\n for (let i = 0; i < params.length; i++) {\n if (!repoUrl.searchParams.get(params[i])) {\n throw new InputError(\n `Invalid repo URL passed to publisher: ${repoUrl.toString()}, missing ${\n params[i]\n }`,\n );\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 */\n\nimport { promises as fs } from 'fs';\nimport globby from 'globby';\nimport limiterFactory from 'p-limit';\nimport { resolveSafeChildPath } from '@backstage/backend-plugin-api';\nimport { SerializedFile } from './types';\nimport { isError } from '@backstage/errors';\n\nconst DEFAULT_GLOB_PATTERNS = ['./**', '!.git'];\n\nexport const isExecutable = (fileMode: number | undefined) => {\n if (!fileMode) {\n return false;\n }\n\n const executeBitMask = 0o000111;\n const res = fileMode & executeBitMask;\n return res > 0;\n};\n\nasync function asyncFilter<T>(\n array: T[],\n callback: (value: T, index: number, array: T[]) => Promise<boolean>,\n): Promise<T[]> {\n const filterMap = await Promise.all(array.map(callback));\n return array.filter((_value, index) => filterMap[index]);\n}\n\n/**\n * @public\n */\nexport async function serializeDirectoryContents(\n sourcePath: string,\n options?: {\n gitignore?: boolean;\n globPatterns?: string[];\n },\n): Promise<SerializedFile[]> {\n const paths = await globby(options?.globPatterns ?? DEFAULT_GLOB_PATTERNS, {\n cwd: sourcePath,\n dot: true,\n gitignore: options?.gitignore,\n followSymbolicLinks: false,\n // In order to pick up 'broken' symlinks, we oxymoronically request files AND folders yet we filter out folders\n // This is because broken symlinks aren't classed as files so we need to glob everything\n onlyFiles: false,\n objectMode: true,\n stats: true,\n });\n\n const limiter = limiterFactory(10);\n\n const valid = await asyncFilter(paths, async ({ dirent, path }) => {\n if (dirent.isDirectory()) return false;\n if (!dirent.isSymbolicLink()) return true;\n\n const safePath = resolveSafeChildPath(sourcePath, path);\n\n // we only want files that don't exist\n try {\n await fs.stat(safePath);\n return false;\n } catch (e) {\n return isError(e) && e.code === 'ENOENT';\n }\n });\n\n return Promise.all(\n valid.map(async ({ dirent, path, stats }) => ({\n path,\n content: await limiter(async () => {\n const absFilePath = resolveSafeChildPath(sourcePath, path);\n if (dirent.isSymbolicLink()) {\n return fs.readlink(absFilePath, 'buffer');\n }\n return fs.readFile(absFilePath);\n }),\n executable: isExecutable(stats?.mode),\n symlink: dirent.isSymbolicLink(),\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 */\n\nimport fs from 'fs-extra';\nimport { dirname } from 'path';\nimport { resolveSafeChildPath } from '@backstage/backend-plugin-api';\nimport { SerializedFile } from './types';\n\n/**\n * Deserializes a list of serialized files into the target directory.\n *\n * This method uses `resolveSafeChildPath` to make sure that files are\n * not written outside of the target directory.\n *\n * @public\n */\nexport async function deserializeDirectoryContents(\n targetPath: string,\n files: SerializedFile[],\n): Promise<void> {\n for (const file of files) {\n const filePath = resolveSafeChildPath(targetPath, file.path);\n await fs.ensureDir(dirname(filePath));\n await fs.writeFile(filePath, file.content); // Ignore file mode\n }\n}\n"],"names":["zodToJsonSchema","PassThrough","spawn","resolveSafeChildPath","path","fs","InputError","git","http","logger","normalizePath","joinPath","isChildPath","globby","limiterFactory","isError","dirname"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -109,6 +109,14 @@ interface TaskContext {
109
109
  status: 'failed';
110
110
  reason: string;
111
111
  }): Promise<void>;
112
+ serializeWorkspace?(options: {
113
+ path: string;
114
+ }): Promise<void>;
115
+ cleanWorkspace?(): Promise<void>;
116
+ rehydrateWorkspace?(options: {
117
+ taskId: string;
118
+ targetPath: string;
119
+ }): Promise<void>;
112
120
  getWorkspaceName(): Promise<string>;
113
121
  getInitiatorCredentials(): Promise<BackstageCredentials>;
114
122
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-scaffolder-node",
3
- "version": "0.4.4-next.1",
3
+ "version": "0.4.4",
4
4
  "description": "The plugin-scaffolder-node module for @backstage/plugin-scaffolder-backend",
5
5
  "backstage": {
6
6
  "role": "node-library"
@@ -44,15 +44,16 @@
44
44
  "test": "backstage-cli package test"
45
45
  },
46
46
  "dependencies": {
47
- "@backstage/backend-common": "^0.22.0-next.1",
48
- "@backstage/backend-plugin-api": "^0.6.18-next.1",
49
- "@backstage/catalog-model": "^1.5.0-next.0",
47
+ "@backstage/backend-common": "^0.22.0",
48
+ "@backstage/backend-plugin-api": "^0.6.18",
49
+ "@backstage/catalog-model": "^1.5.0",
50
50
  "@backstage/errors": "^1.2.4",
51
- "@backstage/integration": "^1.10.0",
52
- "@backstage/plugin-scaffolder-common": "^1.5.2-next.1",
51
+ "@backstage/integration": "^1.11.0",
52
+ "@backstage/plugin-scaffolder-common": "^1.5.2",
53
53
  "@backstage/types": "^1.1.1",
54
54
  "fs-extra": "^11.2.0",
55
55
  "globby": "^11.0.0",
56
+ "isomorphic-git": "^1.23.0",
56
57
  "jsonschema": "^1.2.6",
57
58
  "p-limit": "^3.1.0",
58
59
  "winston": "^3.2.1",
@@ -60,8 +61,8 @@
60
61
  "zod-to-json-schema": "^3.20.4"
61
62
  },
62
63
  "devDependencies": {
63
- "@backstage/backend-test-utils": "^0.3.8-next.1",
64
- "@backstage/cli": "^0.26.5-next.0",
64
+ "@backstage/backend-test-utils": "^0.3.8",
65
+ "@backstage/cli": "^0.26.5",
65
66
  "@backstage/config": "^1.2.0"
66
67
  }
67
68
  }