@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.
Files changed (2) hide show
  1. package/dist/cli.mjs +91 -48
  2. 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(path, themeId, ignorePatterns = [], allowLive = false) {
633
- const result = execSync(`shopify theme push --path ${path} --theme "${themeId}" ${ignorePatterns.map((p) => `--ignore "${path}/${p}"`).join(" ")}${allowLive ? " --allow-live" : ""} --json`, { encoding: "utf-8" });
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("-p, --path <path>", "Theme directory path", "theme").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);
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, path, allowLive, env, branch } = options;
834
- const themeIdNum = parseInt(themeId, 10);
835
- const { preview_url, editor_url } = pushTheme(path, themeIdNum, DEFAULT_IGNORES, allowLive).theme;
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-review.ts
869
+ //#region src/commands/deploy-preview.ts
849
870
  const helpText$5 = `
850
871
  Details:
851
- Creates or updates an unpublished theme for reviewing branch changes.
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:review --branch feature/new-header
873
- $ ag deploy:review -b $CI_COMMIT_REF_NAME
874
- $ ag deploy:review -b my-branch --theme 123456789
875
- $ ag deploy:review -b my-branch --source 987654321`;
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:review").description("Deploy a review app theme for the current branch").addHelpText("after", helpText$5).requiredOption("-b, --branch <branch>", "Git branch name").option("-p, --path <path>", "Theme directory path", "theme").option("-t, --theme <themeId>", "Target theme ID to update directly").option("-s, --source <themeId>", "Source theme ID to duplicate from").action(deployReview);
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 deployReview(options) {
880
- const { branch, path, theme, source } = options;
903
+ function deployPreview(options) {
904
+ const { branch, environment, theme, source } = options;
881
905
  const themeName = previewBranchName(branch);
882
- console.log(`Setting up review app for branch: ${branch}`);
883
- let reviewThemeId;
906
+ requireShopifyConfig(environment);
907
+ console.log(`Setting up preview for branch: ${branch}`);
908
+ let previewThemeId;
884
909
  let existingTheme;
885
910
  if (theme) {
886
- reviewThemeId = Number.parseInt(theme, 10);
887
- console.log(`Using provided theme ID: ${reviewThemeId}`);
888
- existingTheme = { id: reviewThemeId };
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
- reviewThemeId = duplicateTheme(sourceThemeId, themeName).theme.id;
928
+ previewThemeId = duplicateTheme(sourceThemeId, themeName).theme.id;
904
929
  } else {
905
930
  console.log(`Theme already exists with ID: ${existingTheme.id}`);
906
- reviewThemeId = existingTheme.id;
931
+ previewThemeId = existingTheme.id;
907
932
  }
908
933
  }
909
- console.log(`Deploying branch ${branch} to theme ID: ${reviewThemeId}`);
910
- const { preview_url, editor_url } = pushTheme(path, reviewThemeId, DEFAULT_IGNORES).theme;
911
- console.log("Review app deployed successfully!");
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, reviewThemeId, { EXISTING_THEME_ID: existingTheme?.id?.toString() ?? "" });
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 your code changes.
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("-p, --path <path>", "Theme directory path", "theme").action(release);
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, path } = options;
1017
+ const { name, environment, source } = options;
986
1018
  const themeName = `AG Release: ${name}`;
987
- const liveTheme = findLiveTheme();
988
- if (!liveTheme) throw new Error("No live theme found to clone from");
989
- console.log(`Cloning from published theme ID: ${liveTheme.id}`);
990
- const releaseThemeId = duplicateTheme(liveTheme.id, themeName).theme.id;
991
- const { preview_url, editor_url } = pushTheme(path, releaseThemeId, DEFAULT_IGNORES).theme;
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: liveTheme.id.toString() });
1038
+ writeDeployEnv(preview_url, editor_url, releaseThemeId, { PUBLISHED_THEME_ID: liveThemeId?.toString() ?? "" });
996
1039
  }
997
1040
 
998
1041
  //#endregion
999
- //#region src/commands/stop-review.ts
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:review --branch feature/new-header
1014
- $ ag stop:review -b $CI_COMMIT_REF_NAME`;
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:review").description("Delete the review app theme for a branch").addHelpText("after", helpText$2).requiredOption("-b, --branch <branch>", "Git branch name").action(stopReview);
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 stopReview(options) {
1061
+ function stopPreview(options) {
1019
1062
  const { branch } = options;
1020
1063
  const themeName = previewBranchName(branch);
1021
- console.log(`Cleaning up review app for branch: ${branch}`);
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("Review app cleaned up successfully!");
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
- review Check variables for review app deployment
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, review, release, codequality, all)").option("-v, --vars <vars...>", "Specific variables to check").action(validateEnv);
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
- review: [{
1111
+ preview: [{
1069
1112
  name: "CI_COMMIT_REF_NAME",
1070
1113
  required: true,
1071
- description: "Git branch name for review app"
1114
+ description: "Git branch name for preview"
1072
1115
  }],
1073
1116
  release: [{
1074
1117
  name: "CI_COMMIT_TAG",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acidgreen-au/ag-cicd-cli",
3
- "version": "0.6.1",
3
+ "version": "0.8.0",
4
4
  "description": "Acidgreen CI/CD CLI tools",
5
5
  "type": "module",
6
6
  "bin": {