@acidgreen-au/ag-cicd-cli 0.6.1 → 0.8.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/cli.mjs +91 -48
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -629,8 +629,9 @@ function duplicateTheme(themeId, name) {
|
|
|
629
629
|
const result = execSync(`shopify theme duplicate -j --theme "${themeId}" --name "${name}"`, { encoding: "utf-8" });
|
|
630
630
|
return JSON.parse(result);
|
|
631
631
|
}
|
|
632
|
-
function pushTheme(
|
|
633
|
-
const
|
|
632
|
+
function pushTheme(themeId, options = {}) {
|
|
633
|
+
const { allowLive = false, environment } = options;
|
|
634
|
+
const result = execSync(`shopify theme push --theme "${themeId}"${environment ? ` --environment "${environment}"` : ""}${allowLive ? " --allow-live" : ""} --json`, { encoding: "utf-8" });
|
|
634
635
|
return JSON.parse(result);
|
|
635
636
|
}
|
|
636
637
|
function deleteTheme(themeId) {
|
|
@@ -670,6 +671,19 @@ const DEFAULT_IGNORES = [
|
|
|
670
671
|
"public/*",
|
|
671
672
|
"assets/.vite"
|
|
672
673
|
];
|
|
674
|
+
const CONFIG_PATH = "shopify.theme.toml";
|
|
675
|
+
function requireShopifyConfig(environment = "default") {
|
|
676
|
+
if (!existsSync(CONFIG_PATH)) {
|
|
677
|
+
console.error(`Error: ${CONFIG_PATH} not found.\n\nRun 'ag config:shopify --preset ci' to create the configuration.`);
|
|
678
|
+
process.exit(1);
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
const config = parse(readFileSync(CONFIG_PATH, "utf-8"));
|
|
682
|
+
if (!config.environments?.[environment]) {
|
|
683
|
+
console.error(`Error: Environment '${environment}' not found in ${CONFIG_PATH}.\n\nAvailable environments: ${Object.keys(config.environments ?? {}).join(", ") || "(none)"}\nRun 'ag config:shopify ${environment}' to create it.`);
|
|
684
|
+
process.exit(1);
|
|
685
|
+
}
|
|
686
|
+
}
|
|
673
687
|
|
|
674
688
|
//#endregion
|
|
675
689
|
//#region src/commands/config-shopify.ts
|
|
@@ -812,6 +826,9 @@ Details:
|
|
|
812
826
|
Pushes theme files to a specific Shopify theme ID. Use this for deploying
|
|
813
827
|
to staging or production themes where you know the target theme ID.
|
|
814
828
|
|
|
829
|
+
Requires shopify.theme.toml configuration. Run 'ag config:shopify --preset ci'
|
|
830
|
+
to create it. Path and ignore patterns are read from the config file.
|
|
831
|
+
|
|
815
832
|
Writes deployment info to deploy.env:
|
|
816
833
|
- PREVIEW_URL: Theme preview URL
|
|
817
834
|
- EDITOR_URL: Theme editor URL
|
|
@@ -823,16 +840,20 @@ Environment:
|
|
|
823
840
|
|
|
824
841
|
Examples:
|
|
825
842
|
$ ag deploy --theme-id 123456789
|
|
826
|
-
$ ag deploy -t 123456789 --path ./theme
|
|
827
843
|
$ ag deploy -t 123456789 --allow-live
|
|
844
|
+
$ ag deploy -t 123456789 --environment production
|
|
828
845
|
$ ag deploy -t 123456789 --env staging --branch feature/auth`;
|
|
829
846
|
function register$6(program$1) {
|
|
830
|
-
program$1.command("deploy").description("Deploy theme to an existing Shopify theme by ID").addHelpText("after", helpText$6).requiredOption("-t, --theme-id <id>", "Target Shopify theme ID").option("
|
|
847
|
+
program$1.command("deploy").description("Deploy theme to an existing Shopify theme by ID").addHelpText("after", helpText$6).requiredOption("-t, --theme-id <id>", "Target Shopify theme ID").option("--environment <env>", "Shopify theme environment from shopify.theme.toml", "default").option("--allow-live", "Allow pushing to a live (published) theme", false).option("-e, --env <env>", "Environment name for theme rename").option("-b, --branch <branch>", "Branch name for theme rename").action(deploy);
|
|
831
848
|
}
|
|
832
849
|
function deploy(options) {
|
|
833
|
-
const { themeId,
|
|
834
|
-
const themeIdNum = parseInt(themeId, 10);
|
|
835
|
-
|
|
850
|
+
const { themeId, allowLive, environment, env, branch } = options;
|
|
851
|
+
const themeIdNum = Number.parseInt(themeId, 10);
|
|
852
|
+
requireShopifyConfig(environment);
|
|
853
|
+
const { preview_url, editor_url } = pushTheme(themeIdNum, {
|
|
854
|
+
allowLive,
|
|
855
|
+
environment
|
|
856
|
+
}).theme;
|
|
836
857
|
console.log("Release deployed successfully!");
|
|
837
858
|
console.log(`Preview URL: ${preview_url}`);
|
|
838
859
|
console.log(`Editor URL: ${editor_url}`);
|
|
@@ -845,15 +866,18 @@ function deploy(options) {
|
|
|
845
866
|
}
|
|
846
867
|
|
|
847
868
|
//#endregion
|
|
848
|
-
//#region src/commands/deploy-
|
|
869
|
+
//#region src/commands/deploy-preview.ts
|
|
849
870
|
const helpText$5 = `
|
|
850
871
|
Details:
|
|
851
|
-
Creates or updates an unpublished theme for
|
|
872
|
+
Creates or updates an unpublished theme for previewing branch changes.
|
|
852
873
|
Theme is named "AG Preview: <branch>" for easy identification.
|
|
853
874
|
|
|
854
875
|
On first deploy: Clones the live theme (or --source theme) as a starting point.
|
|
855
876
|
On subsequent deploys: Updates the existing preview theme.
|
|
856
877
|
|
|
878
|
+
Requires shopify.theme.toml configuration. Run 'ag config:shopify --preset ci'
|
|
879
|
+
to create it. Path and ignore patterns are read from the config file.
|
|
880
|
+
|
|
857
881
|
Use --theme to update a specific theme directly (skips theme lookup/creation).
|
|
858
882
|
Use --source to specify which theme to clone from instead of the live theme.
|
|
859
883
|
|
|
@@ -869,23 +893,24 @@ Environment:
|
|
|
869
893
|
CI_COMMIT_REF_NAME Git branch name (GitLab CI)
|
|
870
894
|
|
|
871
895
|
Examples:
|
|
872
|
-
$ ag deploy:
|
|
873
|
-
$ ag deploy:
|
|
874
|
-
$ ag deploy:
|
|
875
|
-
$ ag deploy:
|
|
896
|
+
$ ag deploy:preview --branch feature/new-header
|
|
897
|
+
$ ag deploy:preview -b $CI_COMMIT_REF_NAME
|
|
898
|
+
$ ag deploy:preview -b my-branch --theme 123456789
|
|
899
|
+
$ ag deploy:preview -b my-branch --environment production`;
|
|
876
900
|
function register$5(program$1) {
|
|
877
|
-
program$1.command("deploy:
|
|
901
|
+
program$1.command("deploy:preview").description("Deploy a preview theme for the current branch").addHelpText("after", helpText$5).requiredOption("-b, --branch <branch>", "Git branch name").option("--environment <env>", "Shopify theme environment from shopify.theme.toml", "default").option("-t, --theme <themeId>", "Target theme ID to update directly").option("-s, --source <themeId>", "Source theme ID to duplicate from").action(deployPreview);
|
|
878
902
|
}
|
|
879
|
-
function
|
|
880
|
-
const { branch,
|
|
903
|
+
function deployPreview(options) {
|
|
904
|
+
const { branch, environment, theme, source } = options;
|
|
881
905
|
const themeName = previewBranchName(branch);
|
|
882
|
-
|
|
883
|
-
|
|
906
|
+
requireShopifyConfig(environment);
|
|
907
|
+
console.log(`Setting up preview for branch: ${branch}`);
|
|
908
|
+
let previewThemeId;
|
|
884
909
|
let existingTheme;
|
|
885
910
|
if (theme) {
|
|
886
|
-
|
|
887
|
-
console.log(`Using provided theme ID: ${
|
|
888
|
-
existingTheme = { id:
|
|
911
|
+
previewThemeId = Number.parseInt(theme, 10);
|
|
912
|
+
console.log(`Using provided theme ID: ${previewThemeId}`);
|
|
913
|
+
existingTheme = { id: previewThemeId };
|
|
889
914
|
} else {
|
|
890
915
|
existingTheme = findThemeByName(themeName);
|
|
891
916
|
if (!existingTheme) {
|
|
@@ -900,18 +925,18 @@ function deployReview(options) {
|
|
|
900
925
|
sourceThemeId = liveTheme.id;
|
|
901
926
|
console.log(`Cloning from published theme ID: ${sourceThemeId}`);
|
|
902
927
|
}
|
|
903
|
-
|
|
928
|
+
previewThemeId = duplicateTheme(sourceThemeId, themeName).theme.id;
|
|
904
929
|
} else {
|
|
905
930
|
console.log(`Theme already exists with ID: ${existingTheme.id}`);
|
|
906
|
-
|
|
931
|
+
previewThemeId = existingTheme.id;
|
|
907
932
|
}
|
|
908
933
|
}
|
|
909
|
-
console.log(`Deploying branch ${branch} to theme ID: ${
|
|
910
|
-
const { preview_url, editor_url } = pushTheme(
|
|
911
|
-
console.log("
|
|
934
|
+
console.log(`Deploying branch ${branch} to theme ID: ${previewThemeId}`);
|
|
935
|
+
const { preview_url, editor_url } = pushTheme(previewThemeId, { environment }).theme;
|
|
936
|
+
console.log("Preview deployed successfully!");
|
|
912
937
|
console.log(`Preview URL: ${preview_url}`);
|
|
913
938
|
console.log(`Editor URL: ${editor_url}`);
|
|
914
|
-
writeDeployEnv(preview_url, editor_url,
|
|
939
|
+
writeDeployEnv(preview_url, editor_url, previewThemeId, { EXISTING_THEME_ID: existingTheme?.id?.toString() ?? "" });
|
|
915
940
|
}
|
|
916
941
|
|
|
917
942
|
//#endregion
|
|
@@ -960,10 +985,16 @@ async function dev(_options, command) {
|
|
|
960
985
|
const helpText$3 = `
|
|
961
986
|
Details:
|
|
962
987
|
Creates a new theme for production releases. Clones the current live theme
|
|
963
|
-
to preserve any theme editor customizations, then pushes
|
|
988
|
+
(or --source theme) to preserve any theme editor customizations, then pushes
|
|
989
|
+
your code changes.
|
|
964
990
|
|
|
965
991
|
Theme is named "AG Release: <name>" for easy identification.
|
|
966
992
|
|
|
993
|
+
Requires shopify.theme.toml configuration. Run 'ag config:shopify --preset ci'
|
|
994
|
+
to create it. Path and ignore patterns are read from the config file.
|
|
995
|
+
|
|
996
|
+
Use --source to specify which theme to clone from instead of the live theme.
|
|
997
|
+
|
|
967
998
|
Writes deployment info to deploy.env:
|
|
968
999
|
- PREVIEW_URL: Release theme preview URL
|
|
969
1000
|
- EDITOR_URL: Release theme editor URL
|
|
@@ -977,26 +1008,38 @@ Environment:
|
|
|
977
1008
|
|
|
978
1009
|
Examples:
|
|
979
1010
|
$ ag release --name v1.2.3
|
|
980
|
-
$ ag release -n $CI_COMMIT_TAG
|
|
1011
|
+
$ ag release -n $CI_COMMIT_TAG
|
|
1012
|
+
$ ag release -n v1.2.3 --environment production`;
|
|
981
1013
|
function register$3(program$1) {
|
|
982
|
-
program$1.command("release").description("Create a release theme by cloning live and pushing changes").addHelpText("after", helpText$3).requiredOption("-n, --name <name>", "Release name (usually git tag)").option("
|
|
1014
|
+
program$1.command("release").description("Create a release theme by cloning live and pushing changes").addHelpText("after", helpText$3).requiredOption("-n, --name <name>", "Release name (usually git tag)").option("--environment <env>", "Shopify theme environment from shopify.theme.toml", "default").option("-s, --source <themeId>", "Source theme ID to clone from").action(release);
|
|
983
1015
|
}
|
|
984
1016
|
function release(options) {
|
|
985
|
-
const { name,
|
|
1017
|
+
const { name, environment, source } = options;
|
|
986
1018
|
const themeName = `AG Release: ${name}`;
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
1019
|
+
requireShopifyConfig(environment);
|
|
1020
|
+
let sourceThemeId;
|
|
1021
|
+
let liveThemeId;
|
|
1022
|
+
if (source) {
|
|
1023
|
+
sourceThemeId = Number.parseInt(source, 10);
|
|
1024
|
+
console.log(`Using provided source theme ID: ${sourceThemeId}`);
|
|
1025
|
+
liveThemeId = findLiveTheme()?.id;
|
|
1026
|
+
} else {
|
|
1027
|
+
const liveTheme = findLiveTheme();
|
|
1028
|
+
if (!liveTheme) throw new Error("No live theme found to clone from");
|
|
1029
|
+
sourceThemeId = liveTheme.id;
|
|
1030
|
+
liveThemeId = liveTheme.id;
|
|
1031
|
+
console.log(`Cloning from published theme ID: ${sourceThemeId}`);
|
|
1032
|
+
}
|
|
1033
|
+
const releaseThemeId = duplicateTheme(sourceThemeId, themeName).theme.id;
|
|
1034
|
+
const { preview_url, editor_url } = pushTheme(releaseThemeId, { environment }).theme;
|
|
992
1035
|
console.log("Release deployed successfully!");
|
|
993
1036
|
console.log(`Preview URL: ${preview_url}`);
|
|
994
1037
|
console.log(`Editor URL: ${editor_url}`);
|
|
995
|
-
writeDeployEnv(preview_url, editor_url, releaseThemeId, { PUBLISHED_THEME_ID:
|
|
1038
|
+
writeDeployEnv(preview_url, editor_url, releaseThemeId, { PUBLISHED_THEME_ID: liveThemeId?.toString() ?? "" });
|
|
996
1039
|
}
|
|
997
1040
|
|
|
998
1041
|
//#endregion
|
|
999
|
-
//#region src/commands/stop-
|
|
1042
|
+
//#region src/commands/stop-preview.ts
|
|
1000
1043
|
const helpText$2 = `
|
|
1001
1044
|
Details:
|
|
1002
1045
|
Finds and deletes the unpublished theme named "AG Preview: <branch>".
|
|
@@ -1010,20 +1053,20 @@ Environment:
|
|
|
1010
1053
|
CI_COMMIT_REF_NAME Git branch name (GitLab CI)
|
|
1011
1054
|
|
|
1012
1055
|
Examples:
|
|
1013
|
-
$ ag stop:
|
|
1014
|
-
$ ag stop:
|
|
1056
|
+
$ ag stop:preview --branch feature/new-header
|
|
1057
|
+
$ ag stop:preview -b $CI_COMMIT_REF_NAME`;
|
|
1015
1058
|
function register$2(program$1) {
|
|
1016
|
-
program$1.command("stop:
|
|
1059
|
+
program$1.command("stop:preview").description("Delete the preview theme for a branch").addHelpText("after", helpText$2).requiredOption("-b, --branch <branch>", "Git branch name").action(stopPreview);
|
|
1017
1060
|
}
|
|
1018
|
-
function
|
|
1061
|
+
function stopPreview(options) {
|
|
1019
1062
|
const { branch } = options;
|
|
1020
1063
|
const themeName = previewBranchName(branch);
|
|
1021
|
-
console.log(`Cleaning up
|
|
1064
|
+
console.log(`Cleaning up preview for branch: ${branch}`);
|
|
1022
1065
|
const theme = findThemeByName(themeName);
|
|
1023
1066
|
if (theme) {
|
|
1024
1067
|
console.log(`Deleting theme: ${themeName} (ID: ${theme.id})`);
|
|
1025
1068
|
deleteTheme(theme.id);
|
|
1026
|
-
console.log("
|
|
1069
|
+
console.log("Preview cleaned up successfully!");
|
|
1027
1070
|
} else console.log(`No theme found with name: ${themeName}`);
|
|
1028
1071
|
}
|
|
1029
1072
|
|
|
@@ -1033,7 +1076,7 @@ const helpText$1 = `
|
|
|
1033
1076
|
Contexts:
|
|
1034
1077
|
all Check all variables for all contexts (default)
|
|
1035
1078
|
deploy Check variables for theme deployment
|
|
1036
|
-
|
|
1079
|
+
preview Check variables for preview deployment
|
|
1037
1080
|
release Check variables for release deployment
|
|
1038
1081
|
codequality Check variables for code quality checks
|
|
1039
1082
|
|
|
@@ -1048,7 +1091,7 @@ Examples:
|
|
|
1048
1091
|
$ ag validate-env --context deploy
|
|
1049
1092
|
$ ag validate-env --vars SHOPIFY_FLAG_STORE CUSTOM_VAR`;
|
|
1050
1093
|
function register$1(program$1) {
|
|
1051
|
-
program$1.command("validate-env").description("Validate required environment variables are set").addHelpText("after", helpText$1).option("-c, --context <context>", "Validation context (deploy,
|
|
1094
|
+
program$1.command("validate-env").description("Validate required environment variables are set").addHelpText("after", helpText$1).option("-c, --context <context>", "Validation context (deploy, preview, release, codequality, all)").option("-v, --vars <vars...>", "Specific variables to check").action(validateEnv);
|
|
1052
1095
|
}
|
|
1053
1096
|
const commonVars = [{
|
|
1054
1097
|
name: "SHOPIFY_CLI_THEME_TOKEN",
|
|
@@ -1065,10 +1108,10 @@ const contextVars = {
|
|
|
1065
1108
|
required: true,
|
|
1066
1109
|
description: "Target theme ID for deployment"
|
|
1067
1110
|
}],
|
|
1068
|
-
|
|
1111
|
+
preview: [{
|
|
1069
1112
|
name: "CI_COMMIT_REF_NAME",
|
|
1070
1113
|
required: true,
|
|
1071
|
-
description: "Git branch name for
|
|
1114
|
+
description: "Git branch name for preview"
|
|
1072
1115
|
}],
|
|
1073
1116
|
release: [{
|
|
1074
1117
|
name: "CI_COMMIT_TAG",
|