@golden-frijoles/kit 1.2.0 → 1.4.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/dist/roadmap-push.mjs +41 -2
- package/package.json +1 -1
package/dist/roadmap-push.mjs
CHANGED
|
@@ -12,13 +12,14 @@
|
|
|
12
12
|
// node scripts/roadmap-push.mjs # push to $GROWTH_ENGINE_URL
|
|
13
13
|
// node scripts/roadmap-push.mjs --dry-run # print the envelope, send nothing
|
|
14
14
|
// node scripts/roadmap-push.mjs --url http://localhost:3000
|
|
15
|
+
// node scripts/roadmap-push.mjs --env-file .env.local # the key and URL `frijoles init --ingest` wrote
|
|
15
16
|
//
|
|
16
17
|
// Env: GROWTH_ENGINE_URL (default http://localhost:3000) and the project's ingest key: SELF_PROJECT_API_KEY FIRST (it only
|
|
17
18
|
// ever means this project's own key), else the SDK's GROWTH_ENGINE_API_KEY. Not the other way round — see apiKeyFrom.
|
|
18
19
|
// A missing key is a CLEAN SKIP (exit 0), not a failure — see the note in the CI step.
|
|
19
20
|
|
|
20
21
|
import { spawnSync } from 'node:child_process';
|
|
21
|
-
import { writeSync } from 'node:fs';
|
|
22
|
+
import { readFileSync, writeSync } from 'node:fs';
|
|
22
23
|
import { dirname, resolve } from 'node:path';
|
|
23
24
|
import { fileURLToPath } from 'node:url';
|
|
24
25
|
import { getKey } from './lib/config.mjs';
|
|
@@ -166,6 +167,23 @@ export async function pushRoadmap(
|
|
|
166
167
|
return { ok: res.ok, skipped: false, status: res.status, text: await res.text() };
|
|
167
168
|
}
|
|
168
169
|
|
|
170
|
+
/**
|
|
171
|
+
* setup-instruments-connects D8 — the push's own variables from a dotenv file (`frijoles init --ingest` writes them to
|
|
172
|
+
* `.env.local`). Pure, and it reads ONLY these names: nothing is evaluated (a shell `source` would run whatever the file
|
|
173
|
+
* holds), and the last assignment wins, as dotenv does. Quotes are stripped; `export ` is allowed.
|
|
174
|
+
*/
|
|
175
|
+
export const ENV_FILE_NAMES = ['GROWTH_ENGINE_URL', 'GROWTH_ENGINE_API_KEY', 'SELF_PROJECT_API_KEY'];
|
|
176
|
+
export function readEnvFile(text) {
|
|
177
|
+
const out = {};
|
|
178
|
+
for (const line of String(text).split(/\r?\n/)) {
|
|
179
|
+
const m = /^\s*(?:export\s+)?([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/.exec(line);
|
|
180
|
+
if (!m || !ENV_FILE_NAMES.includes(m[1])) continue;
|
|
181
|
+
const value = m[2].trim().replace(/^(['"])(.*)\1$/, '$2');
|
|
182
|
+
if (value) out[m[1]] = value;
|
|
183
|
+
}
|
|
184
|
+
return out;
|
|
185
|
+
}
|
|
186
|
+
|
|
169
187
|
/** The CLI's report for one push result. Exported so `roadmap-extract --sink hub` says it the same way. */
|
|
170
188
|
export function reportPush(result, count) {
|
|
171
189
|
if (result.skipped) {
|
|
@@ -189,16 +207,37 @@ export function reportPush(result, count) {
|
|
|
189
207
|
async function main() {
|
|
190
208
|
const args = process.argv.slice(2);
|
|
191
209
|
const urlFlag = args.indexOf('--url');
|
|
210
|
+
const envFlag = args.indexOf('--env-file');
|
|
211
|
+
let fromFile = {};
|
|
212
|
+
if (envFlag !== -1) {
|
|
213
|
+
const path = args[envFlag + 1];
|
|
214
|
+
if (!path) {
|
|
215
|
+
process.stderr.write('--env-file needs a path, for example --env-file .env.local\n');
|
|
216
|
+
process.exitCode = 1;
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
try {
|
|
220
|
+
fromFile = readEnvFile(readFileSync(resolve(REPO_ROOT, path), 'utf8'));
|
|
221
|
+
} catch (err) {
|
|
222
|
+
process.stderr.write(`could not read ${path}: ${err.message}\n`);
|
|
223
|
+
process.exitCode = 1;
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// An explicit --url wins, then the file, then the shell's environment.
|
|
192
228
|
const baseUrl =
|
|
193
229
|
(urlFlag !== -1 ? args[urlFlag + 1] : undefined) ||
|
|
230
|
+
fromFile.GROWTH_ENGINE_URL ||
|
|
194
231
|
process.env.GROWTH_ENGINE_URL ||
|
|
195
232
|
'http://localhost:3000';
|
|
233
|
+
// A key in the file wins over the shell's, so the key and the URL come from the same place (verifier, #338).
|
|
234
|
+
const apiKey = apiKeyFrom(fromFile) ?? apiKeyFrom(process.env);
|
|
196
235
|
const items = readExtract();
|
|
197
236
|
if (args.includes('--dry-run')) {
|
|
198
237
|
writeSync(1, `${JSON.stringify(envelopeFor(items), null, 2)}\n`);
|
|
199
238
|
return;
|
|
200
239
|
}
|
|
201
|
-
process.exitCode = reportPush(await pushRoadmap(items, { baseUrl }), items.length);
|
|
240
|
+
process.exitCode = reportPush(await pushRoadmap(items, { baseUrl, apiKey }), items.length);
|
|
202
241
|
}
|
|
203
242
|
|
|
204
243
|
const isMain = process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@golden-frijoles/kit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "The scripts the Golden Frijoles skills run, packaged so they work in any repo: planning, build-order, reporting and verification rails. Zero dependencies.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|