@backstage/plugin-scaffolder-node 0.5.0-next.0 → 0.5.0-next.2
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 +25 -0
- package/alpha/package.json +1 -1
- package/dist/actions/createTemplateAction.cjs.js +23 -0
- package/dist/actions/createTemplateAction.cjs.js.map +1 -0
- package/dist/actions/executeShellCommand.cjs.js +36 -0
- package/dist/actions/executeShellCommand.cjs.js.map +1 -0
- package/dist/actions/fetch.cjs.js +85 -0
- package/dist/actions/fetch.cjs.js.map +1 -0
- package/dist/actions/gitHelpers.cjs.js +142 -0
- package/dist/actions/gitHelpers.cjs.js.map +1 -0
- package/dist/actions/util.cjs.js +87 -0
- package/dist/actions/util.cjs.js.map +1 -0
- package/dist/alpha.cjs.js +3 -34
- package/dist/alpha.cjs.js.map +1 -1
- package/dist/files/deserializeDirectoryContents.cjs.js +20 -0
- package/dist/files/deserializeDirectoryContents.cjs.js.map +1 -0
- package/dist/files/serializeDirectoryContents.cjs.js +69 -0
- package/dist/files/serializeDirectoryContents.cjs.js.map +1 -0
- package/dist/index.cjs.js +24 -624
- package/dist/index.cjs.js.map +1 -1
- package/dist/scm/git.cjs.js +219 -0
- package/dist/scm/git.cjs.js.map +1 -0
- package/dist/tasks/serializer.cjs.js +38 -0
- package/dist/tasks/serializer.cjs.js.map +1 -0
- package/package.json +10 -10
package/dist/index.cjs.js
CHANGED
|
@@ -1,627 +1,27 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const inputSchema = action.schema?.input && "safeParseAsync" in action.schema.input ? zodToJsonSchema__default.default(action.schema.input) : action.schema?.input;
|
|
28
|
-
const outputSchema = action.schema?.output && "safeParseAsync" in action.schema.output ? zodToJsonSchema__default.default(action.schema.output) : action.schema?.output;
|
|
29
|
-
return {
|
|
30
|
-
...action,
|
|
31
|
-
schema: {
|
|
32
|
-
...action.schema,
|
|
33
|
-
input: inputSchema,
|
|
34
|
-
output: outputSchema
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
async function executeShellCommand(options) {
|
|
40
|
-
const {
|
|
41
|
-
command,
|
|
42
|
-
args,
|
|
43
|
-
options: spawnOptions,
|
|
44
|
-
logStream = new stream.PassThrough()
|
|
45
|
-
} = options;
|
|
46
|
-
await new Promise((resolve, reject) => {
|
|
47
|
-
const process = child_process.spawn(command, args, spawnOptions);
|
|
48
|
-
process.stdout.on("data", (stream) => {
|
|
49
|
-
logStream.write(stream);
|
|
50
|
-
});
|
|
51
|
-
process.stderr.on("data", (stream) => {
|
|
52
|
-
logStream.write(stream);
|
|
53
|
-
});
|
|
54
|
-
process.on("error", (error) => {
|
|
55
|
-
return reject(error);
|
|
56
|
-
});
|
|
57
|
-
process.on("close", (code) => {
|
|
58
|
-
if (code !== 0) {
|
|
59
|
-
return reject(
|
|
60
|
-
new Error(`Command ${command} failed, exit code: ${code}`)
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
return resolve();
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
async function fetchContents(options) {
|
|
69
|
-
const {
|
|
70
|
-
reader,
|
|
71
|
-
integrations,
|
|
72
|
-
baseUrl,
|
|
73
|
-
fetchUrl = ".",
|
|
74
|
-
outputPath,
|
|
75
|
-
token
|
|
76
|
-
} = options;
|
|
77
|
-
const fetchUrlIsAbsolute = isFetchUrlAbsolute(fetchUrl);
|
|
78
|
-
if (!fetchUrlIsAbsolute && baseUrl?.startsWith("file://")) {
|
|
79
|
-
const basePath = baseUrl.slice("file://".length);
|
|
80
|
-
const srcDir = backendPluginApi.resolveSafeChildPath(path__default.default.dirname(basePath), fetchUrl);
|
|
81
|
-
await fs__default.default.copy(srcDir, outputPath);
|
|
82
|
-
} else {
|
|
83
|
-
const readUrl = getReadUrl(fetchUrl, baseUrl, integrations);
|
|
84
|
-
const res = await reader.readTree(readUrl, { token });
|
|
85
|
-
await fs__default.default.ensureDir(outputPath);
|
|
86
|
-
await res.dir({ targetDir: outputPath });
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
async function fetchFile(options) {
|
|
90
|
-
const {
|
|
91
|
-
reader,
|
|
92
|
-
integrations,
|
|
93
|
-
baseUrl,
|
|
94
|
-
fetchUrl = ".",
|
|
95
|
-
outputPath,
|
|
96
|
-
token
|
|
97
|
-
} = options;
|
|
98
|
-
const fetchUrlIsAbsolute = isFetchUrlAbsolute(fetchUrl);
|
|
99
|
-
if (!fetchUrlIsAbsolute && baseUrl?.startsWith("file://")) {
|
|
100
|
-
const basePath = baseUrl.slice("file://".length);
|
|
101
|
-
const src = backendPluginApi.resolveSafeChildPath(path__default.default.dirname(basePath), fetchUrl);
|
|
102
|
-
await fs__default.default.copyFile(src, outputPath);
|
|
103
|
-
} else {
|
|
104
|
-
const readUrl = getReadUrl(fetchUrl, baseUrl, integrations);
|
|
105
|
-
const res = await reader.readUrl(readUrl, { token });
|
|
106
|
-
await fs__default.default.ensureDir(path__default.default.dirname(outputPath));
|
|
107
|
-
const buffer = await res.buffer();
|
|
108
|
-
await fs__default.default.outputFile(outputPath, buffer);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
function isFetchUrlAbsolute(fetchUrl) {
|
|
112
|
-
let fetchUrlIsAbsolute = false;
|
|
113
|
-
try {
|
|
114
|
-
new URL(fetchUrl);
|
|
115
|
-
fetchUrlIsAbsolute = true;
|
|
116
|
-
} catch {
|
|
117
|
-
}
|
|
118
|
-
return fetchUrlIsAbsolute;
|
|
119
|
-
}
|
|
120
|
-
function getReadUrl(fetchUrl, baseUrl, integrations) {
|
|
121
|
-
if (isFetchUrlAbsolute(fetchUrl)) {
|
|
122
|
-
return fetchUrl;
|
|
123
|
-
} else if (baseUrl) {
|
|
124
|
-
const integration = integrations.byUrl(baseUrl);
|
|
125
|
-
if (!integration) {
|
|
126
|
-
throw new errors.InputError(`No integration found for location ${baseUrl}`);
|
|
127
|
-
}
|
|
128
|
-
return integration.resolveUrl({
|
|
129
|
-
url: fetchUrl,
|
|
130
|
-
base: baseUrl
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
throw new errors.InputError(
|
|
134
|
-
`Failed to fetch, template location could not be determined and the fetch URL is relative, ${fetchUrl}`
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function isAuthCallbackOptions(options) {
|
|
139
|
-
return "onAuth" in options;
|
|
140
|
-
}
|
|
141
|
-
class Git {
|
|
142
|
-
constructor(config) {
|
|
143
|
-
this.config = config;
|
|
144
|
-
this.onAuth = config.onAuth;
|
|
145
|
-
this.headers = {
|
|
146
|
-
"user-agent": "git/@isomorphic-git",
|
|
147
|
-
...config.token ? { Authorization: `Bearer ${config.token}` } : {}
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
headers;
|
|
151
|
-
async add(options) {
|
|
152
|
-
const { dir, filepath } = options;
|
|
153
|
-
this.config.logger?.info(`Adding file {dir=${dir},filepath=${filepath}}`);
|
|
154
|
-
return git__default.default.add({ fs: fs__default.default, dir, filepath });
|
|
155
|
-
}
|
|
156
|
-
async addRemote(options) {
|
|
157
|
-
const { dir, url, remote, force } = options;
|
|
158
|
-
this.config.logger?.info(
|
|
159
|
-
`Creating new remote {dir=${dir},remote=${remote},url=${url}}`
|
|
160
|
-
);
|
|
161
|
-
return git__default.default.addRemote({ fs: fs__default.default, dir, remote, url, force });
|
|
162
|
-
}
|
|
163
|
-
async deleteRemote(options) {
|
|
164
|
-
const { dir, remote } = options;
|
|
165
|
-
this.config.logger?.info(`Deleting remote {dir=${dir},remote=${remote}}`);
|
|
166
|
-
return git__default.default.deleteRemote({ fs: fs__default.default, dir, remote });
|
|
167
|
-
}
|
|
168
|
-
async checkout(options) {
|
|
169
|
-
const { dir, ref } = options;
|
|
170
|
-
this.config.logger?.info(`Checking out branch {dir=${dir},ref=${ref}}`);
|
|
171
|
-
return git__default.default.checkout({ fs: fs__default.default, dir, ref });
|
|
172
|
-
}
|
|
173
|
-
async branch(options) {
|
|
174
|
-
const { dir, ref } = options;
|
|
175
|
-
this.config.logger?.info(`Creating branch {dir=${dir},ref=${ref}`);
|
|
176
|
-
return git__default.default.branch({ fs: fs__default.default, dir, ref });
|
|
177
|
-
}
|
|
178
|
-
async commit(options) {
|
|
179
|
-
const { dir, message, author, committer } = options;
|
|
180
|
-
this.config.logger?.info(
|
|
181
|
-
`Committing file to repo {dir=${dir},message=${message}}`
|
|
182
|
-
);
|
|
183
|
-
return git__default.default.commit({ fs: fs__default.default, dir, message, author, committer });
|
|
184
|
-
}
|
|
185
|
-
/** https://isomorphic-git.org/docs/en/clone */
|
|
186
|
-
async clone(options) {
|
|
187
|
-
const { url, dir, ref, depth, noCheckout } = options;
|
|
188
|
-
this.config.logger?.info(`Cloning repo {dir=${dir},url=${url}}`);
|
|
189
|
-
try {
|
|
190
|
-
return await git__default.default.clone({
|
|
191
|
-
fs: fs__default.default,
|
|
192
|
-
http: http__default.default,
|
|
193
|
-
url,
|
|
194
|
-
dir,
|
|
195
|
-
ref,
|
|
196
|
-
singleBranch: true,
|
|
197
|
-
depth: depth ?? 1,
|
|
198
|
-
noCheckout,
|
|
199
|
-
onProgress: this.onProgressHandler(),
|
|
200
|
-
headers: this.headers,
|
|
201
|
-
onAuth: this.onAuth
|
|
202
|
-
});
|
|
203
|
-
} catch (ex) {
|
|
204
|
-
this.config.logger?.error(`Failed to clone repo {dir=${dir},url=${url}}`);
|
|
205
|
-
if (ex.data) {
|
|
206
|
-
throw new Error(`${ex.message} {data=${JSON.stringify(ex.data)}}`);
|
|
207
|
-
}
|
|
208
|
-
throw ex;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
/** https://isomorphic-git.org/docs/en/currentBranch */
|
|
212
|
-
async currentBranch(options) {
|
|
213
|
-
const { dir, fullName = false } = options;
|
|
214
|
-
return git__default.default.currentBranch({ fs: fs__default.default, dir, fullname: fullName });
|
|
215
|
-
}
|
|
216
|
-
/** https://isomorphic-git.org/docs/en/fetch */
|
|
217
|
-
async fetch(options) {
|
|
218
|
-
const { dir, remote = "origin", tags = false } = options;
|
|
219
|
-
this.config.logger?.info(
|
|
220
|
-
`Fetching remote=${remote} for repository {dir=${dir}}`
|
|
221
|
-
);
|
|
222
|
-
try {
|
|
223
|
-
await git__default.default.fetch({
|
|
224
|
-
fs: fs__default.default,
|
|
225
|
-
http: http__default.default,
|
|
226
|
-
dir,
|
|
227
|
-
remote,
|
|
228
|
-
tags,
|
|
229
|
-
onProgress: this.onProgressHandler(),
|
|
230
|
-
headers: this.headers,
|
|
231
|
-
onAuth: this.onAuth
|
|
232
|
-
});
|
|
233
|
-
} catch (ex) {
|
|
234
|
-
this.config.logger?.error(
|
|
235
|
-
`Failed to fetch repo {dir=${dir},remote=${remote}}`
|
|
236
|
-
);
|
|
237
|
-
if (ex.data) {
|
|
238
|
-
throw new Error(`${ex.message} {data=${JSON.stringify(ex.data)}}`);
|
|
239
|
-
}
|
|
240
|
-
throw ex;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
async init(options) {
|
|
244
|
-
const { dir, defaultBranch = "master" } = options;
|
|
245
|
-
this.config.logger?.info(`Init git repository {dir=${dir}}`);
|
|
246
|
-
return git__default.default.init({
|
|
247
|
-
fs: fs__default.default,
|
|
248
|
-
dir,
|
|
249
|
-
defaultBranch
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
/** https://isomorphic-git.org/docs/en/merge */
|
|
253
|
-
async merge(options) {
|
|
254
|
-
const { dir, theirs, ours, author, committer } = options;
|
|
255
|
-
this.config.logger?.info(
|
|
256
|
-
`Merging branch '${theirs}' into '${ours}' for repository {dir=${dir}}`
|
|
257
|
-
);
|
|
258
|
-
return git__default.default.merge({
|
|
259
|
-
fs: fs__default.default,
|
|
260
|
-
dir,
|
|
261
|
-
ours,
|
|
262
|
-
theirs,
|
|
263
|
-
author,
|
|
264
|
-
committer
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
async push(options) {
|
|
268
|
-
const { dir, remote, remoteRef, force } = options;
|
|
269
|
-
this.config.logger?.info(
|
|
270
|
-
`Pushing directory to remote {dir=${dir},remote=${remote}}`
|
|
271
|
-
);
|
|
272
|
-
try {
|
|
273
|
-
return await git__default.default.push({
|
|
274
|
-
fs: fs__default.default,
|
|
275
|
-
dir,
|
|
276
|
-
http: http__default.default,
|
|
277
|
-
onProgress: this.onProgressHandler(),
|
|
278
|
-
remoteRef,
|
|
279
|
-
force,
|
|
280
|
-
headers: this.headers,
|
|
281
|
-
remote,
|
|
282
|
-
onAuth: this.onAuth
|
|
283
|
-
});
|
|
284
|
-
} catch (ex) {
|
|
285
|
-
this.config.logger?.error(
|
|
286
|
-
`Failed to push to repo {dir=${dir}, remote=${remote}}`
|
|
287
|
-
);
|
|
288
|
-
if (ex.data) {
|
|
289
|
-
throw new Error(`${ex.message} {data=${JSON.stringify(ex.data)}}`);
|
|
290
|
-
}
|
|
291
|
-
throw ex;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
/** https://isomorphic-git.org/docs/en/readCommit */
|
|
295
|
-
async readCommit(options) {
|
|
296
|
-
const { dir, sha } = options;
|
|
297
|
-
return git__default.default.readCommit({ fs: fs__default.default, dir, oid: sha });
|
|
298
|
-
}
|
|
299
|
-
/** https://isomorphic-git.org/docs/en/remove */
|
|
300
|
-
async remove(options) {
|
|
301
|
-
const { dir, filepath } = options;
|
|
302
|
-
this.config.logger?.info(
|
|
303
|
-
`Removing file from git index {dir=${dir},filepath=${filepath}}`
|
|
304
|
-
);
|
|
305
|
-
return git__default.default.remove({ fs: fs__default.default, dir, filepath });
|
|
306
|
-
}
|
|
307
|
-
/** https://isomorphic-git.org/docs/en/resolveRef */
|
|
308
|
-
async resolveRef(options) {
|
|
309
|
-
const { dir, ref } = options;
|
|
310
|
-
return git__default.default.resolveRef({ fs: fs__default.default, dir, ref });
|
|
311
|
-
}
|
|
312
|
-
/** https://isomorphic-git.org/docs/en/log */
|
|
313
|
-
async log(options) {
|
|
314
|
-
const { dir, ref } = options;
|
|
315
|
-
return git__default.default.log({
|
|
316
|
-
fs: fs__default.default,
|
|
317
|
-
dir,
|
|
318
|
-
ref: ref ?? "HEAD"
|
|
319
|
-
});
|
|
320
|
-
}
|
|
321
|
-
onAuth;
|
|
322
|
-
onProgressHandler = () => {
|
|
323
|
-
let currentPhase = "";
|
|
324
|
-
return (event) => {
|
|
325
|
-
if (currentPhase !== event.phase) {
|
|
326
|
-
currentPhase = event.phase;
|
|
327
|
-
this.config.logger?.info(event.phase);
|
|
328
|
-
}
|
|
329
|
-
const total = event.total ? `${Math.round(event.loaded / event.total * 100)}%` : event.loaded;
|
|
330
|
-
this.config.logger?.debug(`status={${event.phase},total={${total}}}`);
|
|
331
|
-
};
|
|
332
|
-
};
|
|
333
|
-
static fromAuth = (options) => {
|
|
334
|
-
if (isAuthCallbackOptions(options)) {
|
|
335
|
-
const { onAuth, logger: logger2 } = options;
|
|
336
|
-
return new Git({ onAuth, logger: logger2 });
|
|
337
|
-
}
|
|
338
|
-
const { username, password, token, logger } = options;
|
|
339
|
-
return new Git({ onAuth: () => ({ username, password }), token, logger });
|
|
340
|
-
};
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
async function initRepoAndPush(input) {
|
|
344
|
-
const {
|
|
345
|
-
dir,
|
|
346
|
-
remoteUrl,
|
|
347
|
-
auth,
|
|
348
|
-
logger,
|
|
349
|
-
defaultBranch = "master",
|
|
350
|
-
commitMessage = "Initial commit",
|
|
351
|
-
gitAuthorInfo
|
|
352
|
-
} = input;
|
|
353
|
-
const git = Git.fromAuth({
|
|
354
|
-
...auth,
|
|
355
|
-
logger
|
|
356
|
-
});
|
|
357
|
-
await git.init({
|
|
358
|
-
dir,
|
|
359
|
-
defaultBranch
|
|
360
|
-
});
|
|
361
|
-
await git.add({ dir, filepath: "." });
|
|
362
|
-
const authorInfo = {
|
|
363
|
-
name: gitAuthorInfo?.name ?? "Scaffolder",
|
|
364
|
-
email: gitAuthorInfo?.email ?? "scaffolder@backstage.io"
|
|
365
|
-
};
|
|
366
|
-
const commitHash = await git.commit({
|
|
367
|
-
dir,
|
|
368
|
-
message: commitMessage,
|
|
369
|
-
author: authorInfo,
|
|
370
|
-
committer: authorInfo
|
|
371
|
-
});
|
|
372
|
-
await git.addRemote({
|
|
373
|
-
dir,
|
|
374
|
-
url: remoteUrl,
|
|
375
|
-
remote: "origin"
|
|
376
|
-
});
|
|
377
|
-
await git.push({
|
|
378
|
-
dir,
|
|
379
|
-
remote: "origin"
|
|
380
|
-
});
|
|
381
|
-
return { commitHash };
|
|
382
|
-
}
|
|
383
|
-
async function commitAndPushRepo(input) {
|
|
384
|
-
const {
|
|
385
|
-
dir,
|
|
386
|
-
auth,
|
|
387
|
-
logger,
|
|
388
|
-
commitMessage,
|
|
389
|
-
gitAuthorInfo,
|
|
390
|
-
branch = "master",
|
|
391
|
-
remoteRef
|
|
392
|
-
} = input;
|
|
393
|
-
const git = Git.fromAuth({
|
|
394
|
-
...auth,
|
|
395
|
-
logger
|
|
396
|
-
});
|
|
397
|
-
await git.fetch({ dir });
|
|
398
|
-
await git.checkout({ dir, ref: branch });
|
|
399
|
-
await git.add({ dir, filepath: "." });
|
|
400
|
-
const authorInfo = {
|
|
401
|
-
name: gitAuthorInfo?.name ?? "Scaffolder",
|
|
402
|
-
email: gitAuthorInfo?.email ?? "scaffolder@backstage.io"
|
|
403
|
-
};
|
|
404
|
-
const commitHash = await git.commit({
|
|
405
|
-
dir,
|
|
406
|
-
message: commitMessage,
|
|
407
|
-
author: authorInfo,
|
|
408
|
-
committer: authorInfo
|
|
409
|
-
});
|
|
410
|
-
await git.push({
|
|
411
|
-
dir,
|
|
412
|
-
remote: "origin",
|
|
413
|
-
remoteRef: remoteRef ?? `refs/heads/${branch}`
|
|
414
|
-
});
|
|
415
|
-
return { commitHash };
|
|
416
|
-
}
|
|
417
|
-
async function cloneRepo(options) {
|
|
418
|
-
const { url, dir, auth, logger, ref, depth, noCheckout } = options;
|
|
419
|
-
const git = Git.fromAuth({
|
|
420
|
-
...auth,
|
|
421
|
-
logger
|
|
422
|
-
});
|
|
423
|
-
await git.clone({ url, dir, ref, depth, noCheckout });
|
|
424
|
-
}
|
|
425
|
-
async function createBranch(options) {
|
|
426
|
-
const { dir, ref, auth, logger } = options;
|
|
427
|
-
const git = Git.fromAuth({
|
|
428
|
-
...auth,
|
|
429
|
-
logger
|
|
430
|
-
});
|
|
431
|
-
await git.checkout({ dir, ref });
|
|
432
|
-
}
|
|
433
|
-
async function addFiles(options) {
|
|
434
|
-
const { dir, filepath, auth, logger } = options;
|
|
435
|
-
const git = Git.fromAuth({
|
|
436
|
-
...auth,
|
|
437
|
-
logger
|
|
438
|
-
});
|
|
439
|
-
await git.add({ dir, filepath });
|
|
440
|
-
}
|
|
441
|
-
async function commitAndPushBranch(options) {
|
|
442
|
-
const {
|
|
443
|
-
dir,
|
|
444
|
-
auth,
|
|
445
|
-
logger,
|
|
446
|
-
commitMessage,
|
|
447
|
-
gitAuthorInfo,
|
|
448
|
-
branch = "master",
|
|
449
|
-
remoteRef,
|
|
450
|
-
remote = "origin"
|
|
451
|
-
} = options;
|
|
452
|
-
const git = Git.fromAuth({
|
|
453
|
-
...auth,
|
|
454
|
-
logger
|
|
455
|
-
});
|
|
456
|
-
const authorInfo = {
|
|
457
|
-
name: gitAuthorInfo?.name ?? "Scaffolder",
|
|
458
|
-
email: gitAuthorInfo?.email ?? "scaffolder@backstage.io"
|
|
459
|
-
};
|
|
460
|
-
const commitHash = await git.commit({
|
|
461
|
-
dir,
|
|
462
|
-
message: commitMessage,
|
|
463
|
-
author: authorInfo,
|
|
464
|
-
committer: authorInfo
|
|
465
|
-
});
|
|
466
|
-
await git.push({
|
|
467
|
-
dir,
|
|
468
|
-
remote,
|
|
469
|
-
remoteRef: remoteRef ?? `refs/heads/${branch}`
|
|
470
|
-
});
|
|
471
|
-
return { commitHash };
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
const getRepoSourceDirectory = (workspacePath, sourcePath) => {
|
|
475
|
-
if (sourcePath) {
|
|
476
|
-
const safeSuffix = path.normalize(sourcePath).replace(
|
|
477
|
-
/^(\.\.(\/|\\|$))+/,
|
|
478
|
-
""
|
|
479
|
-
);
|
|
480
|
-
const path$1 = path.join(workspacePath, safeSuffix);
|
|
481
|
-
if (!backendPluginApi.isChildPath(workspacePath, path$1)) {
|
|
482
|
-
throw new Error("Invalid source path");
|
|
483
|
-
}
|
|
484
|
-
return path$1;
|
|
485
|
-
}
|
|
486
|
-
return workspacePath;
|
|
487
|
-
};
|
|
488
|
-
const parseRepoUrl = (repoUrl, integrations) => {
|
|
489
|
-
let parsed;
|
|
490
|
-
try {
|
|
491
|
-
parsed = new URL(`https://${repoUrl}`);
|
|
492
|
-
} catch (error) {
|
|
493
|
-
throw new errors.InputError(
|
|
494
|
-
`Invalid repo URL passed to publisher, got ${repoUrl}, ${error}`
|
|
495
|
-
);
|
|
496
|
-
}
|
|
497
|
-
const host = parsed.host;
|
|
498
|
-
const owner = parsed.searchParams.get("owner") ?? void 0;
|
|
499
|
-
const organization = parsed.searchParams.get("organization") ?? void 0;
|
|
500
|
-
const workspace = parsed.searchParams.get("workspace") ?? void 0;
|
|
501
|
-
const project = parsed.searchParams.get("project") ?? void 0;
|
|
502
|
-
const type = integrations.byHost(host)?.type;
|
|
503
|
-
if (!type) {
|
|
504
|
-
throw new errors.InputError(
|
|
505
|
-
`No matching integration configuration for host ${host}, please check your integrations config`
|
|
506
|
-
);
|
|
507
|
-
}
|
|
508
|
-
const repo = parsed.searchParams.get("repo");
|
|
509
|
-
switch (type) {
|
|
510
|
-
case "bitbucket": {
|
|
511
|
-
if (host === "www.bitbucket.org") {
|
|
512
|
-
checkRequiredParams(parsed, "workspace");
|
|
513
|
-
}
|
|
514
|
-
checkRequiredParams(parsed, "project", "repo");
|
|
515
|
-
break;
|
|
516
|
-
}
|
|
517
|
-
case "azure": {
|
|
518
|
-
checkRequiredParams(parsed, "project", "repo");
|
|
519
|
-
break;
|
|
520
|
-
}
|
|
521
|
-
case "gitlab": {
|
|
522
|
-
if (!project) {
|
|
523
|
-
checkRequiredParams(parsed, "owner", "repo");
|
|
524
|
-
}
|
|
525
|
-
break;
|
|
526
|
-
}
|
|
527
|
-
case "gitea": {
|
|
528
|
-
checkRequiredParams(parsed, "repo");
|
|
529
|
-
break;
|
|
530
|
-
}
|
|
531
|
-
case "gerrit": {
|
|
532
|
-
checkRequiredParams(parsed, "repo");
|
|
533
|
-
break;
|
|
534
|
-
}
|
|
535
|
-
default: {
|
|
536
|
-
checkRequiredParams(parsed, "repo", "owner");
|
|
537
|
-
break;
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
return { host, owner, repo, organization, workspace, project };
|
|
541
|
-
};
|
|
542
|
-
function checkRequiredParams(repoUrl, ...params) {
|
|
543
|
-
for (let i = 0; i < params.length; i++) {
|
|
544
|
-
if (!repoUrl.searchParams.get(params[i])) {
|
|
545
|
-
throw new errors.InputError(
|
|
546
|
-
`Invalid repo URL passed to publisher: ${repoUrl.toString()}, missing ${params[i]}`
|
|
547
|
-
);
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
const DEFAULT_GLOB_PATTERNS = ["./**", "!.git"];
|
|
553
|
-
const isExecutable = (fileMode) => {
|
|
554
|
-
if (!fileMode) {
|
|
555
|
-
return false;
|
|
556
|
-
}
|
|
557
|
-
const executeBitMask = 73;
|
|
558
|
-
const res = fileMode & executeBitMask;
|
|
559
|
-
return res > 0;
|
|
560
|
-
};
|
|
561
|
-
async function asyncFilter(array, callback) {
|
|
562
|
-
const filterMap = await Promise.all(array.map(callback));
|
|
563
|
-
return array.filter((_value, index) => filterMap[index]);
|
|
564
|
-
}
|
|
565
|
-
async function serializeDirectoryContents(sourcePath, options) {
|
|
566
|
-
const paths = await globby__default.default(options?.globPatterns ?? DEFAULT_GLOB_PATTERNS, {
|
|
567
|
-
cwd: sourcePath,
|
|
568
|
-
dot: true,
|
|
569
|
-
gitignore: options?.gitignore,
|
|
570
|
-
followSymbolicLinks: false,
|
|
571
|
-
// In order to pick up 'broken' symlinks, we oxymoronically request files AND folders yet we filter out folders
|
|
572
|
-
// This is because broken symlinks aren't classed as files so we need to glob everything
|
|
573
|
-
onlyFiles: false,
|
|
574
|
-
objectMode: true,
|
|
575
|
-
stats: true
|
|
576
|
-
});
|
|
577
|
-
const limiter = limiterFactory__default.default(10);
|
|
578
|
-
const valid = await asyncFilter(paths, async ({ dirent, path }) => {
|
|
579
|
-
if (dirent.isDirectory()) return false;
|
|
580
|
-
if (!dirent.isSymbolicLink()) return true;
|
|
581
|
-
const safePath = backendPluginApi.resolveSafeChildPath(sourcePath, path);
|
|
582
|
-
try {
|
|
583
|
-
await fs$1.promises.stat(safePath);
|
|
584
|
-
return false;
|
|
585
|
-
} catch (e) {
|
|
586
|
-
return errors.isError(e) && e.code === "ENOENT";
|
|
587
|
-
}
|
|
588
|
-
});
|
|
589
|
-
return Promise.all(
|
|
590
|
-
valid.map(async ({ dirent, path, stats }) => ({
|
|
591
|
-
path,
|
|
592
|
-
content: await limiter(async () => {
|
|
593
|
-
const absFilePath = backendPluginApi.resolveSafeChildPath(sourcePath, path);
|
|
594
|
-
if (dirent.isSymbolicLink()) {
|
|
595
|
-
return fs$1.promises.readlink(absFilePath, "buffer");
|
|
596
|
-
}
|
|
597
|
-
return fs$1.promises.readFile(absFilePath);
|
|
598
|
-
}),
|
|
599
|
-
executable: isExecutable(stats?.mode),
|
|
600
|
-
symlink: dirent.isSymbolicLink()
|
|
601
|
-
}))
|
|
602
|
-
);
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
async function deserializeDirectoryContents(targetPath, files) {
|
|
606
|
-
for (const file of files) {
|
|
607
|
-
const filePath = backendPluginApi.resolveSafeChildPath(targetPath, file.path);
|
|
608
|
-
await fs__default.default.ensureDir(path.dirname(filePath));
|
|
609
|
-
await fs__default.default.writeFile(filePath, file.content);
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
exports.addFiles = addFiles;
|
|
614
|
-
exports.cloneRepo = cloneRepo;
|
|
615
|
-
exports.commitAndPushBranch = commitAndPushBranch;
|
|
616
|
-
exports.commitAndPushRepo = commitAndPushRepo;
|
|
617
|
-
exports.createBranch = createBranch;
|
|
618
|
-
exports.createTemplateAction = createTemplateAction;
|
|
619
|
-
exports.deserializeDirectoryContents = deserializeDirectoryContents;
|
|
620
|
-
exports.executeShellCommand = executeShellCommand;
|
|
621
|
-
exports.fetchContents = fetchContents;
|
|
622
|
-
exports.fetchFile = fetchFile;
|
|
623
|
-
exports.getRepoSourceDirectory = getRepoSourceDirectory;
|
|
624
|
-
exports.initRepoAndPush = initRepoAndPush;
|
|
625
|
-
exports.parseRepoUrl = parseRepoUrl;
|
|
626
|
-
exports.serializeDirectoryContents = serializeDirectoryContents;
|
|
3
|
+
var createTemplateAction = require('./actions/createTemplateAction.cjs.js');
|
|
4
|
+
var executeShellCommand = require('./actions/executeShellCommand.cjs.js');
|
|
5
|
+
var fetch = require('./actions/fetch.cjs.js');
|
|
6
|
+
var gitHelpers = require('./actions/gitHelpers.cjs.js');
|
|
7
|
+
var util = require('./actions/util.cjs.js');
|
|
8
|
+
var serializeDirectoryContents = require('./files/serializeDirectoryContents.cjs.js');
|
|
9
|
+
var deserializeDirectoryContents = require('./files/deserializeDirectoryContents.cjs.js');
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
exports.createTemplateAction = createTemplateAction.createTemplateAction;
|
|
14
|
+
exports.executeShellCommand = executeShellCommand.executeShellCommand;
|
|
15
|
+
exports.fetchContents = fetch.fetchContents;
|
|
16
|
+
exports.fetchFile = fetch.fetchFile;
|
|
17
|
+
exports.addFiles = gitHelpers.addFiles;
|
|
18
|
+
exports.cloneRepo = gitHelpers.cloneRepo;
|
|
19
|
+
exports.commitAndPushBranch = gitHelpers.commitAndPushBranch;
|
|
20
|
+
exports.commitAndPushRepo = gitHelpers.commitAndPushRepo;
|
|
21
|
+
exports.createBranch = gitHelpers.createBranch;
|
|
22
|
+
exports.initRepoAndPush = gitHelpers.initRepoAndPush;
|
|
23
|
+
exports.getRepoSourceDirectory = util.getRepoSourceDirectory;
|
|
24
|
+
exports.parseRepoUrl = util.parseRepoUrl;
|
|
25
|
+
exports.serializeDirectoryContents = serializeDirectoryContents.serializeDirectoryContents;
|
|
26
|
+
exports.deserializeDirectoryContents = deserializeDirectoryContents.deserializeDirectoryContents;
|
|
627
27
|
//# sourceMappingURL=index.cjs.js.map
|