@acidgreen-au/ag-cicd-cli 0.0.1 → 0.0.3
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 +32 -0
- package/dist/cli.mjs +324 -49
- package/package.json +10 -8
package/README.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# @acidgreen-au/ag-cicd-cli
|
|
2
|
+
|
|
3
|
+
CLI tools for Acidgreen CI/CD workflows. Provides commands for Shopify theme deployment, code quality checks, environment validation, and git automation.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm install -g @acidgreen-au/ag-cicd-cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or use directly with npx:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pnpx @acidgreen-au/ag-cicd-cli <command>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
ag --help
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
For help with a specific command:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
ag <command> --help
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Requirements
|
|
30
|
+
|
|
31
|
+
- Node.js >= 24.0.0
|
|
32
|
+
- Shopify CLI (for theme commands)
|
package/dist/cli.mjs
CHANGED
|
@@ -1,13 +1,60 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
2
5
|
import { program } from "commander";
|
|
3
|
-
import { execSync
|
|
4
|
-
import
|
|
6
|
+
import { execSync } from "node:child_process";
|
|
7
|
+
import prompts from "prompts";
|
|
8
|
+
import { parse, stringify } from "smol-toml";
|
|
9
|
+
import concurrently from "concurrently";
|
|
5
10
|
|
|
6
11
|
//#region src/commands/check-tag.ts
|
|
12
|
+
const helpText$9 = `
|
|
13
|
+
Details:
|
|
14
|
+
Reads the version from package.json and checks if a corresponding git tag
|
|
15
|
+
exists. Optionally creates and pushes the tag if it doesn't exist.
|
|
16
|
+
|
|
17
|
+
When --remote is specified, local tags are synced with remote before checking.
|
|
18
|
+
|
|
19
|
+
Used in CI/CD to automatically tag releases when package.json version
|
|
20
|
+
is bumped.
|
|
21
|
+
|
|
22
|
+
Exit Codes:
|
|
23
|
+
0 Tag exists, or was successfully created
|
|
24
|
+
1 Tag does not exist (when --create is not specified)
|
|
25
|
+
|
|
26
|
+
Examples:
|
|
27
|
+
$ ag check-tag
|
|
28
|
+
$ ag check-tag --create
|
|
29
|
+
$ ag check-tag --create --push
|
|
30
|
+
$ ag check-tag --create --push --remote origin
|
|
31
|
+
$ ag check-tag --prefix release-
|
|
32
|
+
|
|
33
|
+
GitLab CI/CD Authentication:
|
|
34
|
+
To push tags from GitLab CI/CD, you need to authenticate with the remote.
|
|
35
|
+
|
|
36
|
+
Create a token with write_repository scope in Settings > Access Tokens,
|
|
37
|
+
then add it as a masked CI/CD variable (e.g., GITLAB_TOKEN).
|
|
38
|
+
|
|
39
|
+
$ ag check-tag --create --push \\
|
|
40
|
+
--remote "https://oauth2:\${GITLAB_TOKEN}@\${CI_SERVER_HOST}/\${CI_PROJECT_PATH}.git"`;
|
|
41
|
+
function register$9(program$1) {
|
|
42
|
+
program$1.command("check-tag").description("Check if git tag exists for package.json version").addHelpText("after", helpText$9).option("-p, --package-path <path>", "Path to package.json", "package.json").option("--prefix <prefix>", "Tag prefix", "v").option("-c, --create", "Create the tag if it doesn't exist").option("--push", "Push the tag to remote (requires --create)").option("-r, --remote <remote>", "Remote to push to", "origin").action(checkTagCommand);
|
|
43
|
+
}
|
|
7
44
|
function getVersionFromPackage(packagePath) {
|
|
8
45
|
const content = readFileSync(packagePath, "utf-8");
|
|
9
46
|
return JSON.parse(content).version;
|
|
10
47
|
}
|
|
48
|
+
function syncTagsFromRemote(remote) {
|
|
49
|
+
execSync(`git fetch "${remote}" --prune --prune-tags --force`, {
|
|
50
|
+
encoding: "utf-8",
|
|
51
|
+
stdio: [
|
|
52
|
+
"pipe",
|
|
53
|
+
"pipe",
|
|
54
|
+
"pipe"
|
|
55
|
+
]
|
|
56
|
+
});
|
|
57
|
+
}
|
|
11
58
|
function tagExists(tag) {
|
|
12
59
|
try {
|
|
13
60
|
execSync(`git rev-parse --verify "refs/tags/${tag}"`, {
|
|
@@ -47,6 +94,7 @@ function checkTag(options) {
|
|
|
47
94
|
const packagePath = options.packagePath ?? "package.json";
|
|
48
95
|
const prefix = options.prefix ?? "v";
|
|
49
96
|
const remote = options.remote ?? "origin";
|
|
97
|
+
if (options.remote) syncTagsFromRemote(remote);
|
|
50
98
|
const version = getVersionFromPackage(packagePath);
|
|
51
99
|
const tag = `${prefix}${version}`;
|
|
52
100
|
if (tagExists(tag)) return {
|
|
@@ -245,6 +293,24 @@ const ALL_CHECKS = [
|
|
|
245
293
|
"theme-check",
|
|
246
294
|
"tsc"
|
|
247
295
|
];
|
|
296
|
+
const helpText$8 = `
|
|
297
|
+
Checks:
|
|
298
|
+
biome Runs Biome linter for TypeScript/JavaScript
|
|
299
|
+
prettier Checks file formatting with Prettier
|
|
300
|
+
theme-check Runs Shopify Theme Check for Liquid files
|
|
301
|
+
tsc Runs TypeScript compiler for type errors
|
|
302
|
+
|
|
303
|
+
Output:
|
|
304
|
+
Generates a JSON file compatible with GitLab Code Quality reports.
|
|
305
|
+
Each issue includes severity, file path, and line number.
|
|
306
|
+
|
|
307
|
+
Examples:
|
|
308
|
+
$ ag codequality
|
|
309
|
+
$ ag codequality --checks biome tsc
|
|
310
|
+
$ ag codequality --output gl-code-quality.json --path ./theme`;
|
|
311
|
+
function register$8(program$1) {
|
|
312
|
+
program$1.command("codequality").description("Run code quality checks and output GitLab-compatible JSON").addHelpText("after", helpText$8).option("-o, --output <file>", "Output JSON file path", "codequality.json").option("-p, --path <path>", "Theme directory path", "theme").option("-c, --checks <checks...>", "Specific checks to run (biome, prettier, theme-check, tsc)").action(codequality);
|
|
313
|
+
}
|
|
248
314
|
function codequality(options) {
|
|
249
315
|
const { output, path, checks = ALL_CHECKS } = options;
|
|
250
316
|
const allIssues = [];
|
|
@@ -280,6 +346,28 @@ function codequality(options) {
|
|
|
280
346
|
|
|
281
347
|
//#endregion
|
|
282
348
|
//#region src/commands/commit-msg.ts
|
|
349
|
+
const helpText$7 = `
|
|
350
|
+
Details:
|
|
351
|
+
Validates that commit messages follow the required format:
|
|
352
|
+
<PREFIX>-<NUMBER> <message>
|
|
353
|
+
|
|
354
|
+
When the branch contains a ticket ID, the commit message must reference
|
|
355
|
+
the same ticket. Branches without ticket IDs (main, development, etc.) skip
|
|
356
|
+
this check.
|
|
357
|
+
|
|
358
|
+
Designed to be called from .husky/commit-msg hook:
|
|
359
|
+
ag commit-msg --file "$1"
|
|
360
|
+
|
|
361
|
+
Exit Codes:
|
|
362
|
+
0 Commit message is valid
|
|
363
|
+
1 Commit message is invalid (blocks commit)
|
|
364
|
+
|
|
365
|
+
Examples:
|
|
366
|
+
$ ag commit-msg --file .git/COMMIT_EDITMSG
|
|
367
|
+
$ ag commit-msg -f .git/COMMIT_EDITMSG --prefix PROJ`;
|
|
368
|
+
function register$7(program$1) {
|
|
369
|
+
program$1.command("commit-msg").description("Validate commit message format for git hooks").addHelpText("after", helpText$7).requiredOption("-f, --file <file>", "Path to commit message file").option("-p, --prefix <prefix>", "JIRA project prefix", "AIR").action(commitMsg);
|
|
370
|
+
}
|
|
283
371
|
function validateCommitMsg(options) {
|
|
284
372
|
const { file, prefix } = options;
|
|
285
373
|
const ticketRegex = /* @__PURE__ */ new RegExp(`^${prefix}-[0-9]+`);
|
|
@@ -337,6 +425,82 @@ function commitMsg(options) {
|
|
|
337
425
|
process.exit(0);
|
|
338
426
|
}
|
|
339
427
|
|
|
428
|
+
//#endregion
|
|
429
|
+
//#region src/commands/config-shopify.ts
|
|
430
|
+
const helpText$6 = `
|
|
431
|
+
Details:
|
|
432
|
+
Creates or updates a shopify.theme.toml configuration file.
|
|
433
|
+
|
|
434
|
+
Without a name argument: Creates the default environment configuration.
|
|
435
|
+
With a name argument: Adds a new named environment, copying path and
|
|
436
|
+
ignore settings from the default environment.
|
|
437
|
+
|
|
438
|
+
Prompts for:
|
|
439
|
+
- Store name (required): Your myshopify.com store URL
|
|
440
|
+
- Theme ID (optional): Target theme ID for deployment
|
|
441
|
+
|
|
442
|
+
Examples:
|
|
443
|
+
$ ag config:shopify # Create/update default environment
|
|
444
|
+
$ ag config:shopify production # Add production environment
|
|
445
|
+
$ ag config:shopify staging --force # Overwrite staging environment`;
|
|
446
|
+
const DEFAULT_IGNORES = [
|
|
447
|
+
"templates/*.json",
|
|
448
|
+
"locales/*.json",
|
|
449
|
+
"config/settings_data.json",
|
|
450
|
+
"src/*",
|
|
451
|
+
"public/*"
|
|
452
|
+
];
|
|
453
|
+
const DEFAULT_PATH = "theme";
|
|
454
|
+
function register$6(program$1) {
|
|
455
|
+
program$1.command("config:shopify").description("Create or update shopify.theme.toml configuration").addHelpText("after", helpText$6).argument("[name]", "Environment name (default: 'default')").option("-f, --force", "Overwrite existing environment").action(configShopify);
|
|
456
|
+
}
|
|
457
|
+
function loadConfig(configPath) {
|
|
458
|
+
if (!existsSync(configPath)) return { environments: {} };
|
|
459
|
+
return parse(readFileSync(configPath, "utf-8"));
|
|
460
|
+
}
|
|
461
|
+
function saveConfig(configPath, config) {
|
|
462
|
+
writeFileSync(configPath, stringify(config));
|
|
463
|
+
}
|
|
464
|
+
async function configShopify(name, options) {
|
|
465
|
+
const configPath = "shopify.theme.toml";
|
|
466
|
+
const envName = name ?? "default";
|
|
467
|
+
const config = loadConfig(configPath);
|
|
468
|
+
if (!config.environments) config.environments = {};
|
|
469
|
+
if (config.environments[envName] && !options.force) {
|
|
470
|
+
console.error(`Error: Environment '${envName}' already exists. Use --force to overwrite.`);
|
|
471
|
+
process.exit(1);
|
|
472
|
+
}
|
|
473
|
+
if (envName !== "default" && !config.environments.default) {
|
|
474
|
+
console.error("Error: Default environment must be created first. Run 'ag config:shopify' without arguments.");
|
|
475
|
+
process.exit(1);
|
|
476
|
+
}
|
|
477
|
+
const response = await prompts([{
|
|
478
|
+
type: "text",
|
|
479
|
+
name: "store",
|
|
480
|
+
message: "Store name (e.g., my-store.myshopify.com)",
|
|
481
|
+
validate: (value) => value.length > 0 || "Store name is required"
|
|
482
|
+
}, {
|
|
483
|
+
type: "text",
|
|
484
|
+
name: "themeId",
|
|
485
|
+
message: "Theme ID (optional, press Enter to skip)"
|
|
486
|
+
}], { onCancel: () => {
|
|
487
|
+
console.log("\nCancelled.");
|
|
488
|
+
process.exit(0);
|
|
489
|
+
} });
|
|
490
|
+
const defaultEnv = config.environments.default;
|
|
491
|
+
const path = defaultEnv?.path ?? DEFAULT_PATH;
|
|
492
|
+
const ignore = defaultEnv?.ignore ?? DEFAULT_IGNORES;
|
|
493
|
+
const envConfig = {
|
|
494
|
+
store: response.store,
|
|
495
|
+
path,
|
|
496
|
+
ignore
|
|
497
|
+
};
|
|
498
|
+
if (response.themeId) envConfig.theme = response.themeId;
|
|
499
|
+
config.environments[envName] = envConfig;
|
|
500
|
+
saveConfig(configPath, config);
|
|
501
|
+
console.log(`\n${existsSync(configPath) ? "Updated" : "Created"} ${configPath} with '${envName}' environment`);
|
|
502
|
+
}
|
|
503
|
+
|
|
340
504
|
//#endregion
|
|
341
505
|
//#region src/utils/shopify.ts
|
|
342
506
|
function listThemes() {
|
|
@@ -375,6 +539,26 @@ const defaultIgnores = [
|
|
|
375
539
|
|
|
376
540
|
//#endregion
|
|
377
541
|
//#region src/commands/deploy.ts
|
|
542
|
+
const helpText$5 = `
|
|
543
|
+
Details:
|
|
544
|
+
Pushes theme files to a specific Shopify theme ID. Use this for deploying
|
|
545
|
+
to staging or production themes where you know the target theme ID.
|
|
546
|
+
|
|
547
|
+
Writes deployment info to deploy.env:
|
|
548
|
+
- PREVIEW_URL: Theme preview URL
|
|
549
|
+
- EDITOR_URL: Theme editor URL
|
|
550
|
+
- THEME_ID: Deployed theme ID
|
|
551
|
+
|
|
552
|
+
Environment:
|
|
553
|
+
SHOPIFY_CLI_THEME_TOKEN Shopify CLI authentication token
|
|
554
|
+
SHOPIFY_FLAG_STORE Shopify store URL
|
|
555
|
+
|
|
556
|
+
Examples:
|
|
557
|
+
$ ag deploy --theme-id 123456789
|
|
558
|
+
$ ag deploy -t 123456789 --path ./theme`;
|
|
559
|
+
function register$5(program$1) {
|
|
560
|
+
program$1.command("deploy").description("Deploy theme to an existing Shopify theme by ID").addHelpText("after", helpText$5).requiredOption("-t, --theme-id <id>", "Target Shopify theme ID").option("-p, --path <path>", "Theme directory path", "theme").action(deploy);
|
|
561
|
+
}
|
|
378
562
|
function deploy(options) {
|
|
379
563
|
const { themeId, path } = options;
|
|
380
564
|
const themeIdNum = parseInt(themeId, 10);
|
|
@@ -387,6 +571,31 @@ function deploy(options) {
|
|
|
387
571
|
|
|
388
572
|
//#endregion
|
|
389
573
|
//#region src/commands/deploy-review.ts
|
|
574
|
+
const helpText$4 = `
|
|
575
|
+
Details:
|
|
576
|
+
Creates or updates an unpublished theme for reviewing branch changes.
|
|
577
|
+
Theme is named "AG Preview: <branch>" for easy identification.
|
|
578
|
+
|
|
579
|
+
On first deploy: Clones the live theme as a starting point.
|
|
580
|
+
On subsequent deploys: Updates the existing preview theme.
|
|
581
|
+
|
|
582
|
+
Writes deployment info to deploy.env:
|
|
583
|
+
- PREVIEW_URL: Theme preview URL
|
|
584
|
+
- EDITOR_URL: Theme editor URL
|
|
585
|
+
- THEME_ID: Preview theme ID
|
|
586
|
+
- EXISTING_THEME_ID: ID if theme already existed
|
|
587
|
+
|
|
588
|
+
Environment:
|
|
589
|
+
SHOPIFY_CLI_THEME_TOKEN Shopify CLI authentication token
|
|
590
|
+
SHOPIFY_FLAG_STORE Shopify store URL
|
|
591
|
+
CI_COMMIT_REF_NAME Git branch name (GitLab CI)
|
|
592
|
+
|
|
593
|
+
Examples:
|
|
594
|
+
$ ag deploy:review --branch feature/new-header
|
|
595
|
+
$ ag deploy:review -b $CI_COMMIT_REF_NAME`;
|
|
596
|
+
function register$4(program$1) {
|
|
597
|
+
program$1.command("deploy:review").description("Deploy a review app theme for the current branch").addHelpText("after", helpText$4).requiredOption("-b, --branch <branch>", "Git branch name").option("-p, --path <path>", "Theme directory path", "theme").action(deployReview);
|
|
598
|
+
}
|
|
390
599
|
function deployReview(options) {
|
|
391
600
|
const { branch, path } = options;
|
|
392
601
|
const themeName = `AG Preview: ${branch}`;
|
|
@@ -413,48 +622,71 @@ function deployReview(options) {
|
|
|
413
622
|
|
|
414
623
|
//#endregion
|
|
415
624
|
//#region src/commands/dev.ts
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
shopify.on("close", (code) => {
|
|
448
|
-
if (code !== 0) {
|
|
449
|
-
console.error(`Shopify theme dev exited with code ${code}`);
|
|
450
|
-
vite.kill();
|
|
451
|
-
process.exit(code ?? 1);
|
|
452
|
-
}
|
|
625
|
+
const helpText$3 = `
|
|
626
|
+
Details:
|
|
627
|
+
Starts both Vite (for frontend asset compilation) and Shopify theme dev
|
|
628
|
+
servers in parallel. All additional arguments are passed to shopify theme dev.
|
|
629
|
+
|
|
630
|
+
Handles graceful shutdown of both processes on Ctrl+C or if either exits.
|
|
631
|
+
|
|
632
|
+
Arguments:
|
|
633
|
+
Any arguments after -- are passed directly to 'shopify theme dev'.
|
|
634
|
+
Common options include --store, --theme, --live-reload, etc.
|
|
635
|
+
Run \`shopify theme dev -h\` for full list of options.
|
|
636
|
+
|
|
637
|
+
Examples:
|
|
638
|
+
$ ag dev
|
|
639
|
+
$ ag dev -- --store my-store
|
|
640
|
+
$ ag dev -- --theme 123456789`;
|
|
641
|
+
function register$3(program$1) {
|
|
642
|
+
program$1.command("dev").description("Start Vite and Shopify theme dev servers concurrently").addHelpText("after", helpText$3).allowUnknownOption().allowExcessArguments().action(dev);
|
|
643
|
+
}
|
|
644
|
+
async function dev(_options, command) {
|
|
645
|
+
const { result } = concurrently([{
|
|
646
|
+
command: "pnpm exec vite",
|
|
647
|
+
name: "vite",
|
|
648
|
+
prefixColor: "cyan"
|
|
649
|
+
}, {
|
|
650
|
+
command: `shopify theme dev ${command.args.join(" ")}`,
|
|
651
|
+
name: "shopify",
|
|
652
|
+
prefixColor: "magenta"
|
|
653
|
+
}], {
|
|
654
|
+
killOthers: ["failure", "success"],
|
|
655
|
+
restartTries: 0
|
|
453
656
|
});
|
|
657
|
+
try {
|
|
658
|
+
await result;
|
|
659
|
+
} catch {
|
|
660
|
+
process.exit(1);
|
|
661
|
+
}
|
|
454
662
|
}
|
|
455
663
|
|
|
456
664
|
//#endregion
|
|
457
665
|
//#region src/commands/release.ts
|
|
666
|
+
const helpText$2 = `
|
|
667
|
+
Details:
|
|
668
|
+
Creates a new theme for production releases. Clones the current live theme
|
|
669
|
+
to preserve any theme editor customizations, then pushes your code changes.
|
|
670
|
+
|
|
671
|
+
Theme is named "AG Release: <name>" for easy identification.
|
|
672
|
+
|
|
673
|
+
Writes deployment info to deploy.env:
|
|
674
|
+
- PREVIEW_URL: Release theme preview URL
|
|
675
|
+
- EDITOR_URL: Release theme editor URL
|
|
676
|
+
- THEME_ID: New release theme ID
|
|
677
|
+
- PUBLISHED_THEME_ID: Current live theme ID (for rollback)
|
|
678
|
+
|
|
679
|
+
Environment:
|
|
680
|
+
SHOPIFY_CLI_THEME_TOKEN Shopify CLI authentication token
|
|
681
|
+
SHOPIFY_FLAG_STORE Shopify store URL
|
|
682
|
+
CI_COMMIT_TAG Git tag (GitLab CI)
|
|
683
|
+
|
|
684
|
+
Examples:
|
|
685
|
+
$ ag release --name v1.2.3
|
|
686
|
+
$ ag release -n $CI_COMMIT_TAG`;
|
|
687
|
+
function register$2(program$1) {
|
|
688
|
+
program$1.command("release").description("Create a release theme by cloning live and pushing changes").addHelpText("after", helpText$2).requiredOption("-n, --name <name>", "Release name (usually git tag)").option("-p, --path <path>", "Theme directory path", "theme").action(release);
|
|
689
|
+
}
|
|
458
690
|
function release(options) {
|
|
459
691
|
const { name, path } = options;
|
|
460
692
|
const themeName = `AG Release: ${name}`;
|
|
@@ -471,6 +703,24 @@ function release(options) {
|
|
|
471
703
|
|
|
472
704
|
//#endregion
|
|
473
705
|
//#region src/commands/stop-review.ts
|
|
706
|
+
const helpText$1 = `
|
|
707
|
+
Details:
|
|
708
|
+
Finds and deletes the unpublished theme named "AG Preview: <branch>".
|
|
709
|
+
Typically called when a merge request is closed or merged.
|
|
710
|
+
|
|
711
|
+
Safe to run even if the theme doesn't exist.
|
|
712
|
+
|
|
713
|
+
Environment:
|
|
714
|
+
SHOPIFY_CLI_THEME_TOKEN Shopify CLI authentication token
|
|
715
|
+
SHOPIFY_FLAG_STORE Shopify store URL
|
|
716
|
+
CI_COMMIT_REF_NAME Git branch name (GitLab CI)
|
|
717
|
+
|
|
718
|
+
Examples:
|
|
719
|
+
$ ag stop:review --branch feature/new-header
|
|
720
|
+
$ ag stop:review -b $CI_COMMIT_REF_NAME`;
|
|
721
|
+
function register$1(program$1) {
|
|
722
|
+
program$1.command("stop:review").description("Delete the review app theme for a branch").addHelpText("after", helpText$1).requiredOption("-b, --branch <branch>", "Git branch name").action(stopReview);
|
|
723
|
+
}
|
|
474
724
|
function stopReview(options) {
|
|
475
725
|
const { branch } = options;
|
|
476
726
|
const themeName = `AG Preview: ${branch}`;
|
|
@@ -485,6 +735,27 @@ function stopReview(options) {
|
|
|
485
735
|
|
|
486
736
|
//#endregion
|
|
487
737
|
//#region src/commands/validate-env.ts
|
|
738
|
+
const helpText = `
|
|
739
|
+
Contexts:
|
|
740
|
+
all Check all variables for all contexts (default)
|
|
741
|
+
deploy Check variables for theme deployment
|
|
742
|
+
review Check variables for review app deployment
|
|
743
|
+
release Check variables for release deployment
|
|
744
|
+
codequality Check variables for code quality checks
|
|
745
|
+
|
|
746
|
+
Details:
|
|
747
|
+
Validates that required environment variables are present before
|
|
748
|
+
running CI/CD jobs. Exits with code 1 if any required vars are missing.
|
|
749
|
+
|
|
750
|
+
Token values are redacted in output for security.
|
|
751
|
+
|
|
752
|
+
Examples:
|
|
753
|
+
$ ag validate-env
|
|
754
|
+
$ ag validate-env --context deploy
|
|
755
|
+
$ ag validate-env --vars SHOPIFY_FLAG_STORE CUSTOM_VAR`;
|
|
756
|
+
function register(program$1) {
|
|
757
|
+
program$1.command("validate-env").description("Validate required environment variables are set").addHelpText("after", helpText).option("-c, --context <context>", "Validation context (deploy, review, release, codequality, all)").option("-v, --vars <vars...>", "Specific variables to check").action(validateEnv);
|
|
758
|
+
}
|
|
488
759
|
const commonVars = [{
|
|
489
760
|
name: "SHOPIFY_CLI_THEME_TOKEN",
|
|
490
761
|
required: true,
|
|
@@ -568,16 +839,20 @@ function validateEnv(options) {
|
|
|
568
839
|
|
|
569
840
|
//#endregion
|
|
570
841
|
//#region src/cli.ts
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
program.
|
|
575
|
-
program
|
|
576
|
-
program
|
|
577
|
-
program
|
|
578
|
-
program
|
|
579
|
-
program
|
|
580
|
-
program
|
|
842
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
843
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
|
|
844
|
+
const binName = Object.keys(pkg.bin)[0];
|
|
845
|
+
program.name(binName).description("Acidgreen CI/CD CLI tools for Shopify theme development").version(pkg.version);
|
|
846
|
+
register$8(program);
|
|
847
|
+
register$5(program);
|
|
848
|
+
register$4(program);
|
|
849
|
+
register$1(program);
|
|
850
|
+
register$2(program);
|
|
851
|
+
register(program);
|
|
852
|
+
register$3(program);
|
|
853
|
+
register$7(program);
|
|
854
|
+
register$9(program);
|
|
855
|
+
register$6(program);
|
|
581
856
|
program.parse();
|
|
582
857
|
|
|
583
858
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acidgreen-au/ag-cicd-cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Acidgreen CI/CD CLI tools",
|
|
5
|
-
"repository": {
|
|
6
|
-
"type": "git",
|
|
7
|
-
"url": "https://gitlab.com/acidgreen/internal/agcicd.git"
|
|
8
|
-
},
|
|
9
5
|
"type": "module",
|
|
10
6
|
"bin": {
|
|
11
|
-
"
|
|
7
|
+
"ag": "./dist/cli.mjs"
|
|
12
8
|
},
|
|
13
9
|
"main": "./dist/cli.mjs",
|
|
14
10
|
"types": "./dist/cli.d.mts",
|
|
@@ -17,14 +13,20 @@
|
|
|
17
13
|
"./package.json": "./package.json"
|
|
18
14
|
},
|
|
19
15
|
"files": [
|
|
20
|
-
"dist"
|
|
16
|
+
"dist",
|
|
17
|
+
"package.json",
|
|
18
|
+
"README.md"
|
|
21
19
|
],
|
|
22
20
|
"dependencies": {
|
|
23
|
-
"commander": "13.1.0"
|
|
21
|
+
"commander": "13.1.0",
|
|
22
|
+
"concurrently": "^9.2.1",
|
|
23
|
+
"prompts": "^2.4.2",
|
|
24
|
+
"smol-toml": "^1.6.0"
|
|
24
25
|
},
|
|
25
26
|
"devDependencies": {
|
|
26
27
|
"@biomejs/biome": "^2.3.10",
|
|
27
28
|
"@types/node": "24.10.4",
|
|
29
|
+
"@types/prompts": "^2.4.9",
|
|
28
30
|
"husky": "^9.1.7",
|
|
29
31
|
"tsdown": "^0.18.2",
|
|
30
32
|
"typescript": "^5.9.3",
|