polyci 0.0.6 → 0.0.7
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/dist/main.js +62 -21
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -4,24 +4,65 @@ import * as path from "node:path";
|
|
|
4
4
|
import pino from "pino";
|
|
5
5
|
import pretty from "pino-pretty";
|
|
6
6
|
const log = pino(pretty());
|
|
7
|
-
const
|
|
7
|
+
const DEFAULT_TAG_TEMPLATE = "{module}-v{version}";
|
|
8
|
+
const DEFAULT_BRANCH_TAG_TEMPLATE = "{module}-v{version}-{branch}-{increment}";
|
|
9
|
+
const ALLOWED_TAG_PLACEHOLDERS = new Set(["module", "branch", "version", "increment"]);
|
|
10
|
+
function applyTagTemplate(template, moduleName) {
|
|
11
|
+
return template
|
|
12
|
+
.replaceAll("{module}", moduleName)
|
|
13
|
+
.replaceAll("{branch}", "${CI_COMMIT_BRANCH}")
|
|
14
|
+
.replaceAll("{version}", "${NEXT_VERSION}")
|
|
15
|
+
.replaceAll("{increment}", "${NEXT_INCREMENT}");
|
|
16
|
+
}
|
|
17
|
+
function getInvalidTagTemplatePlaceholders(template) {
|
|
18
|
+
const matches = template.matchAll(/\{([^}]+)\}/g);
|
|
19
|
+
const invalid = new Set();
|
|
20
|
+
for (const match of matches) {
|
|
21
|
+
const placeholder = match[1];
|
|
22
|
+
if (!ALLOWED_TAG_PLACEHOLDERS.has(placeholder)) {
|
|
23
|
+
invalid.add(placeholder);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return [...invalid];
|
|
27
|
+
}
|
|
8
28
|
function parseArgs() {
|
|
9
29
|
const program = new Command();
|
|
10
30
|
program
|
|
11
31
|
.argument("[output]", "Output pipeline file path (or use --output)")
|
|
12
32
|
.option("-o, --output <path>", "Output pipeline file path")
|
|
13
33
|
.option("--modules-root <path>", "Modules root directory", "./modules")
|
|
14
|
-
.option("--branch-rule <regex>", "Branch rule regex for module jobs", DEFAULT_BRANCH_RULE)
|
|
15
34
|
.option("--main-branch <name>", "Primary branch name for release tagging logic", "main")
|
|
35
|
+
.option("--tag-template <template>", "Template for non-primary branch tags; use placeholders {module}, {branch}, {version}, {increment}", DEFAULT_TAG_TEMPLATE)
|
|
36
|
+
.option("--branch-tag-template <template>", "Template for non-primary branch tags; use placeholders {module}, {branch}, {version}, {increment}", DEFAULT_BRANCH_TAG_TEMPLATE)
|
|
16
37
|
.option("--cwd <path>", "Working directory", process.cwd())
|
|
17
38
|
.parse();
|
|
18
39
|
const options = program.opts();
|
|
19
40
|
const output = options.output ?? program.args[0] ?? "";
|
|
20
41
|
const cwd = path.resolve(options.cwd);
|
|
21
42
|
const modulesRoot = path.resolve(cwd, options.modulesRoot);
|
|
22
|
-
const branchRule = options.branchRule;
|
|
23
43
|
const mainBranch = options.mainBranch;
|
|
24
|
-
|
|
44
|
+
const tagTemplate = options.tagTemplate;
|
|
45
|
+
const branchTagTemplate = options.branchTagTemplate;
|
|
46
|
+
const invalidPrimary = getInvalidTagTemplatePlaceholders(tagTemplate);
|
|
47
|
+
if (invalidPrimary.length > 0) {
|
|
48
|
+
program.error(`Invalid --tag-template placeholders: ${invalidPrimary
|
|
49
|
+
.map((x) => `{${x}}`)
|
|
50
|
+
.join(", ")}. Allowed: {module}, {branch}, {version}, {increment}.`);
|
|
51
|
+
}
|
|
52
|
+
const invalidSecondary = getInvalidTagTemplatePlaceholders(branchTagTemplate);
|
|
53
|
+
if (invalidSecondary.length > 0) {
|
|
54
|
+
program.error(`Invalid --branch-tag-template placeholders: ${invalidSecondary
|
|
55
|
+
.map((x) => `{${x}}`)
|
|
56
|
+
.join(", ")}. Allowed: {module}, {branch}, {version}, {increment}.`);
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
cwd,
|
|
60
|
+
output,
|
|
61
|
+
modulesRoot,
|
|
62
|
+
mainBranch,
|
|
63
|
+
tagTemplate,
|
|
64
|
+
branchTagTemplate,
|
|
65
|
+
};
|
|
25
66
|
}
|
|
26
67
|
function toPosixPath(p) {
|
|
27
68
|
return p.split(path.sep).join("/");
|
|
@@ -109,7 +150,7 @@ function appendGlobalVariables(lines) {
|
|
|
109
150
|
lines.push(" - deploy");
|
|
110
151
|
lines.push("");
|
|
111
152
|
}
|
|
112
|
-
function appendModuleBuildJob(lines, module
|
|
153
|
+
function appendModuleBuildJob(lines, module) {
|
|
113
154
|
lines.push(`${module.jobId}_build:`);
|
|
114
155
|
lines.push(" stage: build");
|
|
115
156
|
lines.push(" rules:");
|
|
@@ -130,7 +171,7 @@ function appendModuleBuildJob(lines, module, branchRule) {
|
|
|
130
171
|
lines.push(" expire_in: 1 day");
|
|
131
172
|
lines.push("");
|
|
132
173
|
}
|
|
133
|
-
function appendModuleTestJob(lines, module
|
|
174
|
+
function appendModuleTestJob(lines, module) {
|
|
134
175
|
lines.push(`${module.jobId}_test:`);
|
|
135
176
|
lines.push(" stage: test");
|
|
136
177
|
lines.push(" rules:");
|
|
@@ -148,7 +189,7 @@ function appendModuleTestJob(lines, module, branchRule) {
|
|
|
148
189
|
lines.push(' - echo "test is tasty"');
|
|
149
190
|
lines.push("");
|
|
150
191
|
}
|
|
151
|
-
function appendModuleReleaseJob(lines, module
|
|
192
|
+
function appendModuleReleaseJob(lines, module) {
|
|
152
193
|
lines.push(`${module.jobId}_release:`);
|
|
153
194
|
lines.push(" stage: release");
|
|
154
195
|
lines.push(" rules:");
|
|
@@ -197,7 +238,7 @@ function appendModuleReleaseJob(lines, module, branchRule) {
|
|
|
197
238
|
lines.push(` expire_in: 1 day`);
|
|
198
239
|
lines.push("");
|
|
199
240
|
}
|
|
200
|
-
function appendGlobalReleaseJob(lines, modules, mainBranch) {
|
|
241
|
+
function appendGlobalReleaseJob(lines, modules, mainBranch, tagTemplate, branchTagTemplate) {
|
|
201
242
|
lines.push("release_and_tag:");
|
|
202
243
|
lines.push(" stage: release");
|
|
203
244
|
lines.push(" needs:");
|
|
@@ -225,13 +266,13 @@ function appendGlobalReleaseJob(lines, modules, mainBranch) {
|
|
|
225
266
|
lines.push(" TAG_NAME=\"\"");
|
|
226
267
|
lines.push(` if [ "$CI_COMMIT_BRANCH" = "${mainBranch}" ]; then`);
|
|
227
268
|
lines.push(" if [ \"${NEXT_VERSION:-}\" != \"${LATEST_VERSION:-}\" ]; then");
|
|
228
|
-
lines.push(` TAG_NAME="${module.moduleName}
|
|
269
|
+
lines.push(` TAG_NAME="${applyTagTemplate(tagTemplate, module.moduleName)}"`);
|
|
229
270
|
lines.push(" else");
|
|
230
271
|
lines.push(` echo "Version did not change for ${module.moduleName} on branch $CI_COMMIT_BRANCH, skipping tag"`);
|
|
231
272
|
lines.push(" fi");
|
|
232
273
|
lines.push(" else");
|
|
233
274
|
lines.push(" if [ \"${NEXT_VERSION:-}\" != \"${LATEST_VERSION:-}\" ] || [ \"${NEXT_INCREMENT:-}\" != \"${LATEST_INCREMENT:-}\" ]; then");
|
|
234
|
-
lines.push(` TAG_NAME="${module.moduleName}
|
|
275
|
+
lines.push(` TAG_NAME="${applyTagTemplate(branchTagTemplate, module.moduleName)}"`);
|
|
235
276
|
lines.push(" else");
|
|
236
277
|
lines.push(` echo "Version/increment did not change for ${module.moduleName} on branch $CI_COMMIT_BRANCH, skipping tag"`);
|
|
237
278
|
lines.push(" fi");
|
|
@@ -267,7 +308,7 @@ function appendGlobalReleaseJob(lines, modules, mainBranch) {
|
|
|
267
308
|
lines.push(` expire_in: 1 day`);
|
|
268
309
|
lines.push("");
|
|
269
310
|
}
|
|
270
|
-
function appendModulePublishJob(lines, module
|
|
311
|
+
function appendModulePublishJob(lines, module) {
|
|
271
312
|
lines.push(`${module.jobId}_publish:`);
|
|
272
313
|
lines.push(" stage: publish");
|
|
273
314
|
lines.push(" rules:");
|
|
@@ -295,7 +336,7 @@ function appendModulePublishJob(lines, module, branchRule) {
|
|
|
295
336
|
lines.push(" expire_in: 1 day");
|
|
296
337
|
lines.push("");
|
|
297
338
|
}
|
|
298
|
-
function appendModuleDeployJob(lines, module
|
|
339
|
+
function appendModuleDeployJob(lines, module) {
|
|
299
340
|
lines.push(`${module.jobId}_deploy:`);
|
|
300
341
|
lines.push(" stage: deploy");
|
|
301
342
|
lines.push(" rules:");
|
|
@@ -326,23 +367,23 @@ function appendModuleDeployJob(lines, module, branchRule) {
|
|
|
326
367
|
lines.push(" - rm -rf ~/.ssh");
|
|
327
368
|
lines.push("");
|
|
328
369
|
}
|
|
329
|
-
function buildPipeline(modules,
|
|
370
|
+
function buildPipeline(modules, mainBranch, tagTemplate, branchTagTemplate) {
|
|
330
371
|
const lines = [];
|
|
331
372
|
appendGlobalVariables(lines);
|
|
332
373
|
for (const module of modules) {
|
|
333
|
-
appendModuleBuildJob(lines, module
|
|
334
|
-
appendModuleTestJob(lines, module
|
|
335
|
-
appendModuleReleaseJob(lines, module
|
|
374
|
+
appendModuleBuildJob(lines, module);
|
|
375
|
+
appendModuleTestJob(lines, module);
|
|
376
|
+
appendModuleReleaseJob(lines, module);
|
|
336
377
|
}
|
|
337
|
-
appendGlobalReleaseJob(lines, modules, mainBranch);
|
|
378
|
+
appendGlobalReleaseJob(lines, modules, mainBranch, tagTemplate, branchTagTemplate);
|
|
338
379
|
for (const module of modules) {
|
|
339
|
-
appendModulePublishJob(lines, module
|
|
340
|
-
appendModuleDeployJob(lines, module
|
|
380
|
+
appendModulePublishJob(lines, module);
|
|
381
|
+
appendModuleDeployJob(lines, module);
|
|
341
382
|
}
|
|
342
383
|
return `${lines.join("\n").trimEnd()}\n`;
|
|
343
384
|
}
|
|
344
385
|
function main() {
|
|
345
|
-
const { cwd, output, modulesRoot,
|
|
386
|
+
const { cwd, output, modulesRoot, mainBranch, tagTemplate, branchTagTemplate, } = parseArgs();
|
|
346
387
|
if (!output) {
|
|
347
388
|
log.error("Output path is required. Use [output] or --output <path>.");
|
|
348
389
|
process.exit(1);
|
|
@@ -352,7 +393,7 @@ function main() {
|
|
|
352
393
|
log.error({ cwd, modulesRoot }, "No supported modules were discovered under modules root");
|
|
353
394
|
process.exit(1);
|
|
354
395
|
}
|
|
355
|
-
const pipeline = buildPipeline(modules,
|
|
396
|
+
const pipeline = buildPipeline(modules, mainBranch, tagTemplate, branchTagTemplate);
|
|
356
397
|
const outputPath = path.resolve(cwd, output);
|
|
357
398
|
fs.writeFileSync(outputPath, pipeline, "utf8");
|
|
358
399
|
log.info({ modules: modules.map((m) => m.modulePath), outputPath }, "Generated GitLab pipeline");
|