@secureci/cli 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -11
- package/dist/advisories.js +603 -0
- package/dist/cli.js +255 -33
- package/dist/config.js +23 -1
- package/dist/init.js +12 -5
- package/dist/parser/dangerous-triggers.js +125 -0
- package/dist/parser/injection.js +281 -0
- package/dist/parser/permissions.js +145 -0
- package/dist/parser/pipeline-contract-parser.js +70 -0
- package/dist/parser/pipeline-contract-validator.js +18 -4
- package/dist/parser/validator.js +26 -1
- package/dist/pin.js +311 -0
- package/dist/report.js +7 -1
- package/dist/runner/action-fetcher.js +100 -4
- package/dist/runner/builtin-actions.js +13 -3
- package/dist/runner/dry-run.js +57 -12
- package/dist/runner/executor.js +368 -254
- package/dist/runner/expression.js +106 -8
- package/dist/runner/job-plan.js +58 -1
- package/dist/runner/job-runtime.js +3 -3
- package/dist/runner/node-action.js +11 -3
- package/dist/runner/node-binary.js +108 -0
- package/dist/runner/scheduler.js +207 -0
- package/dist/runner/steps.js +54 -2
- package/dist/utils/env-file.js +185 -0
- package/dist/utils/logger.js +36 -7
- package/dist/version.js +56 -0
- package/package.json +3 -1
package/dist/runner/steps.js
CHANGED
|
@@ -33,6 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.killProcessTree = killProcessTree;
|
|
36
37
|
exports.executeStep = executeStep;
|
|
37
38
|
exports.executeInJobContainer = executeInJobContainer;
|
|
38
39
|
const fs = __importStar(require("fs"));
|
|
@@ -47,6 +48,38 @@ const shell_1 = require("./shell");
|
|
|
47
48
|
const job_runtime_1 = require("./job-runtime");
|
|
48
49
|
const actions_1 = require("./actions");
|
|
49
50
|
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
51
|
+
/**
|
|
52
|
+
* SIGKILL a process and all its descendants (found with `pgrep -P`), so a
|
|
53
|
+
* killed step's shell doesn't leave its commands running.
|
|
54
|
+
*/
|
|
55
|
+
function killProcessTree(pid) {
|
|
56
|
+
const tree = [];
|
|
57
|
+
const visit = (parent) => {
|
|
58
|
+
tree.push(parent);
|
|
59
|
+
let children;
|
|
60
|
+
try {
|
|
61
|
+
children = (0, child_process_1.execFileSync)('pgrep', ['-P', String(parent)], {
|
|
62
|
+
encoding: 'utf-8',
|
|
63
|
+
stdio: ['ignore', 'pipe', 'ignore']
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return; // no children (or no pgrep)
|
|
68
|
+
}
|
|
69
|
+
for (const child of children.split('\n').filter(Boolean)) {
|
|
70
|
+
visit(Number(child));
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
visit(pid);
|
|
74
|
+
for (const id of tree) {
|
|
75
|
+
try {
|
|
76
|
+
process.kill(id, 'SIGKILL');
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// already gone
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
50
83
|
/**
|
|
51
84
|
* Execute a single step
|
|
52
85
|
*/
|
|
@@ -104,8 +137,9 @@ async function executeStep(step, options, runtime, ctx) {
|
|
|
104
137
|
fs.writeFileSync(scriptPath, command);
|
|
105
138
|
const workingDirectory = step['working-directory'] ?? runtime.defaults.workingDirectory;
|
|
106
139
|
const limit = (0, job_runtime_1.effectiveTimeout)(runtime);
|
|
140
|
+
let stopOnAbort;
|
|
107
141
|
try {
|
|
108
|
-
const
|
|
142
|
+
const running = execAsync((0, shell_1.shellCommandLine)(shell.template, scriptPath), {
|
|
109
143
|
timeout: limit.ms,
|
|
110
144
|
killSignal: 'SIGKILL',
|
|
111
145
|
cwd: workingDirectory
|
|
@@ -120,6 +154,17 @@ async function executeStep(step, options, runtime, ctx) {
|
|
|
120
154
|
...(0, job_runtime_1.fileCommandEnv)(files)
|
|
121
155
|
}
|
|
122
156
|
});
|
|
157
|
+
// A cancelled job (fail-fast) kills its running step, with
|
|
158
|
+
// everything the step started.
|
|
159
|
+
const child = running.child;
|
|
160
|
+
stopOnAbort = () => {
|
|
161
|
+
if (child.pid !== undefined)
|
|
162
|
+
killProcessTree(child.pid);
|
|
163
|
+
};
|
|
164
|
+
if (runtime.signal?.aborted)
|
|
165
|
+
stopOnAbort();
|
|
166
|
+
runtime.signal?.addEventListener('abort', stopOnAbort);
|
|
167
|
+
const { stdout, stderr } = await running;
|
|
123
168
|
const { outputs } = (0, job_runtime_1.finishStepOutput)(stdout, files, runtime);
|
|
124
169
|
if (stderr) {
|
|
125
170
|
logger_1.logger.warn(stderr.trim());
|
|
@@ -135,8 +180,12 @@ async function executeStep(step, options, runtime, ctx) {
|
|
|
135
180
|
}
|
|
136
181
|
catch (execError) {
|
|
137
182
|
const error = execError;
|
|
138
|
-
if (
|
|
183
|
+
if (runtime.signal?.aborted) {
|
|
184
|
+
error.message = 'The operation was canceled.';
|
|
185
|
+
}
|
|
186
|
+
else if (error.killed && limit.ms) {
|
|
139
187
|
error.message = limit.message;
|
|
188
|
+
}
|
|
140
189
|
logger_1.logger.error(`Step failed: ${error.message}`);
|
|
141
190
|
const { outputs } = (0, job_runtime_1.finishStepOutput)(error.stdout, files, runtime);
|
|
142
191
|
if (error.stderr) {
|
|
@@ -152,6 +201,9 @@ async function executeStep(step, options, runtime, ctx) {
|
|
|
152
201
|
};
|
|
153
202
|
}
|
|
154
203
|
finally {
|
|
204
|
+
if (stopOnAbort) {
|
|
205
|
+
runtime.signal?.removeEventListener('abort', stopOnAbort);
|
|
206
|
+
}
|
|
155
207
|
(0, runner_env_1.cleanupStepFiles)(files);
|
|
156
208
|
}
|
|
157
209
|
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.parseEnvFile = parseEnvFile;
|
|
37
|
+
exports.readEnvFiles = readEnvFiles;
|
|
38
|
+
exports.loadKeyValues = loadKeyValues;
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const key_value_1 = require("./key-value");
|
|
41
|
+
const logger_1 = require("./logger");
|
|
42
|
+
/**
|
|
43
|
+
* Names accepted as keys. Hyphens are allowed because input names may
|
|
44
|
+
* contain them; everything else follows shell variable naming.
|
|
45
|
+
*/
|
|
46
|
+
const KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_-]*$/;
|
|
47
|
+
const DOUBLE_QUOTE_ESCAPES = {
|
|
48
|
+
n: '\n',
|
|
49
|
+
r: '\r',
|
|
50
|
+
t: '\t',
|
|
51
|
+
'"': '"',
|
|
52
|
+
'\\': '\\'
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Parse `.env`-style content into a record (see DOCS.md for the format):
|
|
56
|
+
* `KEY=value` lines, an optional `export ` prefix, `#` comments, single
|
|
57
|
+
* quotes (literal) and double quotes (escapes, may span lines). Later keys
|
|
58
|
+
* win. Errors name `fileName:line` but never echo the line, since it may
|
|
59
|
+
* hold a secret.
|
|
60
|
+
*/
|
|
61
|
+
function parseEnvFile(content, fileName) {
|
|
62
|
+
const result = {};
|
|
63
|
+
const lines = content
|
|
64
|
+
.replace(/^\uFEFF/, '')
|
|
65
|
+
.replace(/\r\n/g, '\n')
|
|
66
|
+
.split('\n');
|
|
67
|
+
let next = 0;
|
|
68
|
+
while (next < lines.length) {
|
|
69
|
+
const lineNo = next + 1;
|
|
70
|
+
const line = lines[next++];
|
|
71
|
+
const fail = (reason) => {
|
|
72
|
+
throw new Error(`${fileName}:${lineNo}: ${reason}`);
|
|
73
|
+
};
|
|
74
|
+
const trimmed = line.trim();
|
|
75
|
+
if (trimmed === '' || trimmed.startsWith('#'))
|
|
76
|
+
continue;
|
|
77
|
+
const body = trimmed.replace(/^export\s+/, '');
|
|
78
|
+
const separator = body.indexOf('=');
|
|
79
|
+
if (separator === -1)
|
|
80
|
+
fail('expected KEY=value');
|
|
81
|
+
const key = body.slice(0, separator).trim();
|
|
82
|
+
if (!KEY_PATTERN.test(key))
|
|
83
|
+
fail('invalid variable name');
|
|
84
|
+
const raw = body.slice(separator + 1);
|
|
85
|
+
const rest = raw.trimStart();
|
|
86
|
+
let value;
|
|
87
|
+
let tail = '';
|
|
88
|
+
if (rest.startsWith("'")) {
|
|
89
|
+
const close = rest.indexOf("'", 1);
|
|
90
|
+
if (close === -1)
|
|
91
|
+
fail('unterminated single-quoted value');
|
|
92
|
+
value = rest.slice(1, close);
|
|
93
|
+
tail = rest.slice(close + 1);
|
|
94
|
+
}
|
|
95
|
+
else if (rest.startsWith('"')) {
|
|
96
|
+
let text = rest;
|
|
97
|
+
let pos = 1;
|
|
98
|
+
value = '';
|
|
99
|
+
for (;;) {
|
|
100
|
+
if (pos >= text.length) {
|
|
101
|
+
if (next >= lines.length)
|
|
102
|
+
fail('unterminated double-quoted value');
|
|
103
|
+
value += '\n';
|
|
104
|
+
text = lines[next++];
|
|
105
|
+
pos = 0;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const char = text[pos];
|
|
109
|
+
if (char === '\\' && pos + 1 < text.length) {
|
|
110
|
+
const escaped = text[pos + 1];
|
|
111
|
+
value += DOUBLE_QUOTE_ESCAPES[escaped] ?? `\\${escaped}`;
|
|
112
|
+
pos += 2;
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (char === '"') {
|
|
116
|
+
tail = text.slice(pos + 1);
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
value += char;
|
|
120
|
+
pos++;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
// A `#` starts a comment only after whitespace, so `a#b` stays intact.
|
|
125
|
+
const comment = raw.search(/\s#/);
|
|
126
|
+
value = (comment === -1 ? raw : raw.slice(0, comment)).trim();
|
|
127
|
+
}
|
|
128
|
+
const after = tail.trim();
|
|
129
|
+
if (after !== '' && !after.startsWith('#')) {
|
|
130
|
+
fail('unexpected text after closing quote');
|
|
131
|
+
}
|
|
132
|
+
result[key] = value;
|
|
133
|
+
}
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
/** Read and merge env files in order; later files override earlier ones. */
|
|
137
|
+
function readEnvFiles(files, options) {
|
|
138
|
+
const platform = options.platform ?? process.platform;
|
|
139
|
+
const result = {};
|
|
140
|
+
for (const file of files) {
|
|
141
|
+
if (!fs.existsSync(file)) {
|
|
142
|
+
throw new Error(`${options.flagName}: file not found: ${file}`);
|
|
143
|
+
}
|
|
144
|
+
// POSIX modes don't describe Windows ACLs, so the check would mislead.
|
|
145
|
+
if (options.secret && platform !== 'win32') {
|
|
146
|
+
const mode = fs.statSync(file).mode & 0o777;
|
|
147
|
+
if (mode & 0o077) {
|
|
148
|
+
logger_1.logger.warn(`Secret file ${file} is readable by other users (mode ${mode.toString(8).padStart(4, '0')}). Restrict it with: chmod 600 ${file}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
Object.assign(result, parseEnvFile(fs.readFileSync(file, 'utf-8'), file));
|
|
152
|
+
}
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
155
|
+
function configFileList(value, key) {
|
|
156
|
+
if (value === undefined)
|
|
157
|
+
return [];
|
|
158
|
+
if (typeof value === 'string')
|
|
159
|
+
return [value];
|
|
160
|
+
if (Array.isArray(value) && value.every((v) => typeof v === 'string')) {
|
|
161
|
+
return value;
|
|
162
|
+
}
|
|
163
|
+
throw new Error(`Invalid ${key} in config: expected a file path or a list of file paths`);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Resolve one family of run values (env, secrets, inputs or vars): files
|
|
167
|
+
* from the flag (or, without one, from the config), merged in order, then
|
|
168
|
+
* explicit `key=value` flags on top.
|
|
169
|
+
*/
|
|
170
|
+
function loadKeyValues(options) {
|
|
171
|
+
const configKey = options.fileFlagName.replace(/^--/, '');
|
|
172
|
+
const defaults = configFileList(options.configFiles, configKey);
|
|
173
|
+
const files = options.files && options.files.length > 0 ? options.files : defaults;
|
|
174
|
+
return {
|
|
175
|
+
...readEnvFiles(files, {
|
|
176
|
+
flagName: options.fileFlagName,
|
|
177
|
+
secret: options.secret
|
|
178
|
+
}),
|
|
179
|
+
...(0, key_value_1.parseKeyValuePairs)(options.pairs, options.flagName, {
|
|
180
|
+
redact: options.secret,
|
|
181
|
+
fromEnv: options.fromEnv
|
|
182
|
+
})
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=env-file.js.map
|
package/dist/utils/logger.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.logger = exports.LogLevel = void 0;
|
|
4
|
+
const async_hooks_1 = require("async_hooks");
|
|
4
5
|
const ansi_1 = require("./ansi");
|
|
5
6
|
var LogLevel;
|
|
6
7
|
(function (LogLevel) {
|
|
@@ -13,6 +14,8 @@ class Logger {
|
|
|
13
14
|
constructor() {
|
|
14
15
|
this.level = LogLevel.INFO;
|
|
15
16
|
this.secrets = new Set();
|
|
17
|
+
/** The labels of the job whose code is logging (see withJob). */
|
|
18
|
+
this.job = new async_hooks_1.AsyncLocalStorage();
|
|
16
19
|
}
|
|
17
20
|
setLevel(level) {
|
|
18
21
|
this.level = level;
|
|
@@ -53,48 +56,74 @@ class Logger {
|
|
|
53
56
|
}
|
|
54
57
|
return masked;
|
|
55
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Run `fn` with every message it logs (across awaits, and in anything
|
|
61
|
+
* it starts) prefixed with `[label]`, so concurrent jobs' lines can be
|
|
62
|
+
* told apart. Nested calls (a called workflow's jobs) join the labels;
|
|
63
|
+
* with `replace`, `label` takes the place of the innermost one (a matrix
|
|
64
|
+
* combination's label instead of its job's).
|
|
65
|
+
*/
|
|
66
|
+
withJob(label, fn, replace = false) {
|
|
67
|
+
const outer = this.job.getStore() ?? [];
|
|
68
|
+
return this.job.run([...(replace ? outer.slice(0, -1) : outer), label], fn);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* `head` and the masked `message`, each non-empty line prefixed with the
|
|
72
|
+
* job label inside withJob.
|
|
73
|
+
*/
|
|
74
|
+
format(head, message) {
|
|
75
|
+
const labels = this.job.getStore();
|
|
76
|
+
const masked = head + this.mask(message);
|
|
77
|
+
if (!labels)
|
|
78
|
+
return masked;
|
|
79
|
+
const prefix = `[${this.mask(labels.join(' / '))}] `;
|
|
80
|
+
return masked
|
|
81
|
+
.split('\n')
|
|
82
|
+
.map((line) => (line ? prefix + line : line))
|
|
83
|
+
.join('\n');
|
|
84
|
+
}
|
|
56
85
|
maskArg(arg) {
|
|
57
86
|
return typeof arg === 'string' ? this.mask(arg) : arg;
|
|
58
87
|
}
|
|
59
88
|
debug(message, ...args) {
|
|
60
89
|
if (this.level <= LogLevel.DEBUG) {
|
|
61
90
|
this.beforeWrite?.();
|
|
62
|
-
console.log(ansi_1.colors.gray(
|
|
91
|
+
console.log(ansi_1.colors.gray(this.format('[DEBUG] ', message)), ...args.map((a) => this.maskArg(a)));
|
|
63
92
|
}
|
|
64
93
|
}
|
|
65
94
|
info(message, ...args) {
|
|
66
95
|
if (this.level <= LogLevel.INFO) {
|
|
67
96
|
this.beforeWrite?.();
|
|
68
|
-
console.log(ansi_1.colors.blue(
|
|
97
|
+
console.log(ansi_1.colors.blue(this.format('[INFO] ', message)), ...args.map((a) => this.maskArg(a)));
|
|
69
98
|
}
|
|
70
99
|
}
|
|
71
100
|
success(message, ...args) {
|
|
72
101
|
if (this.level <= LogLevel.INFO) {
|
|
73
102
|
this.beforeWrite?.();
|
|
74
|
-
console.log(ansi_1.colors.green(
|
|
103
|
+
console.log(ansi_1.colors.green(this.format('✓ ', message)), ...args.map((a) => this.maskArg(a)));
|
|
75
104
|
}
|
|
76
105
|
}
|
|
77
106
|
warn(message, ...args) {
|
|
78
107
|
if (this.level <= LogLevel.WARN) {
|
|
79
108
|
this.beforeWrite?.();
|
|
80
|
-
console.warn(ansi_1.colors.yellow(
|
|
109
|
+
console.warn(ansi_1.colors.yellow(this.format('[WARN] ', message)), ...args.map((a) => this.maskArg(a)));
|
|
81
110
|
}
|
|
82
111
|
}
|
|
83
112
|
error(message, ...args) {
|
|
84
113
|
if (this.level <= LogLevel.ERROR) {
|
|
85
114
|
this.beforeWrite?.();
|
|
86
|
-
console.error(ansi_1.colors.red(
|
|
115
|
+
console.error(ansi_1.colors.red(this.format('[ERROR] ', message)), ...args.map((a) => this.maskArg(a)));
|
|
87
116
|
}
|
|
88
117
|
}
|
|
89
118
|
step(message) {
|
|
90
119
|
this.beforeWrite?.();
|
|
91
|
-
console.log(ansi_1.colors.cyan(`\n
|
|
120
|
+
console.log(ansi_1.colors.cyan(`\n${this.format('→ ', message)}`));
|
|
92
121
|
}
|
|
93
122
|
result(message, success) {
|
|
94
123
|
const icon = success ? '✓' : '✗';
|
|
95
124
|
const color = success ? ansi_1.colors.green : ansi_1.colors.red;
|
|
96
125
|
this.beforeWrite?.();
|
|
97
|
-
console.log(color(`${icon}
|
|
126
|
+
console.log(color(this.format(`${icon} `, message)));
|
|
98
127
|
}
|
|
99
128
|
}
|
|
100
129
|
exports.logger = new Logger();
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.readVersion = readVersion;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const EMBEDDED_VERSION = typeof __SECURECI_VERSION__ === 'string' ? __SECURECI_VERSION__ : undefined;
|
|
40
|
+
/**
|
|
41
|
+
* The CLI's version: embedded at bundle time in the standalone binary (where
|
|
42
|
+
* package.json isn't on disk), else read from the package.json next to
|
|
43
|
+
* `dist/`, else `0.0.0`.
|
|
44
|
+
*/
|
|
45
|
+
function readVersion({ embedded = EMBEDDED_VERSION, packageDir = path.join(__dirname, '..') } = {}) {
|
|
46
|
+
if (embedded)
|
|
47
|
+
return embedded;
|
|
48
|
+
try {
|
|
49
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(packageDir, 'package.json'), 'utf-8'));
|
|
50
|
+
return String(pkg.version);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return '0.0.0';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=version.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@secureci/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "SecureCI: validate, check against pipeline standards, and run GitHub Actions workflows locally",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
],
|
|
15
15
|
"scripts": {
|
|
16
16
|
"build": "tsc",
|
|
17
|
+
"build:sea": "node scripts/build-sea.mjs",
|
|
17
18
|
"test": "vitest run",
|
|
18
19
|
"test:watch": "vitest",
|
|
19
20
|
"test:coverage": "vitest run --coverage",
|
|
@@ -69,6 +70,7 @@
|
|
|
69
70
|
"@typescript-eslint/parser": "^8.71.1",
|
|
70
71
|
"@vitest/coverage-v8": "^4.1.11",
|
|
71
72
|
"eslint": "^8.56.0",
|
|
73
|
+
"postject": "1.0.0-alpha.6",
|
|
72
74
|
"typescript": "^5.3.3",
|
|
73
75
|
"vitest": "^4.1.11"
|
|
74
76
|
},
|