Skip to content

Allow --development flag to create a new theme#6657

Open
graygilmore wants to merge 4 commits intomainfrom
gg-push-with-name
Open

Allow --development flag to create a new theme#6657
graygilmore wants to merge 4 commits intomainfrom
gg-push-with-name

Conversation

@graygilmore
Copy link
Contributor

@graygilmore graygilmore commented Nov 22, 2025

WHY are these changes introduced?

Developers often want to create a new development theme on a per-PR basis when reviewing theme changes. This is difficult right now because our systems try to only have one development theme per user which means that GitHub's CI is considered a single user and development themes get overwritten all the time.

WHAT is this pull request doing?

This PR solves this by allowing developers to provide a context by using the--development-context flag. The context in this case is just a name but we refer to it as a context because it's specific to development themes and we don't want to confuse with the --theme flag which accepts both an ID and a name.

When a user provides --development-context we'll search for all development themes with that name. If we find one we'll push to it otherwise we'll create a new development theme. This lets developers decide whether to keep long running contexts that get overwritten (e.g. PR #<number>) or new development themes on every push (e.g. PR #<number> - <latest_sha>).

shopify theme push --development --development-context "PR #6657"
shopify theme push -d -c "PR #6657"

How to test your changes?

  1. Installed the snapped version npm i -g --@shopify:registry=https://registry.npmjs.org @shopify/cli@0.0.0-snapshot-20260203000234
  2. Run shopify theme list --role development to see all of your development themes
  3. Run shopify theme push -d -c test-1
  4. Run shopify theme list --role development again and ensure you see the new theme
  5. Run shopify theme push -d -c test-2
  6. Run shopify theme list --role development again and ensure a new theme is created (ie, the previous development theme isn't replaced)
  7. Run shopify theme push -d -c test-1 again
  8. Run shopify theme list --role development again and ensure test-1 was replaced and there aren't two themes named test-1

@github-actions
Copy link
Contributor

github-actions bot commented Nov 22, 2025

Coverage report

St.
Category Percentage Covered / Total
🟡 Statements
79.63% (+0.41% 🔼)
14475/18177
🟡 Branches
73.97% (+0.86% 🔼)
7188/9717
🟡 Functions
79.8% (+0.43% 🔼)
3690/4624
🟡 Lines
79.99% (+0.41% 🔼)
13686/17109
Show new covered files 🐣
St.
File Statements Branches Functions Lines
🟢
... / admin-as-app.ts
100% 100% 100% 100%
🟢
... / metafield_definitions.ts
100% 100% 100% 100%
🟢
... / metaobject_definitions.ts
100% 100% 100% 100%
🟢
... / bulk-operation-cancel.ts
100% 100% 100% 100%
🟢
... / bulk-operation-run-mutation.ts
100% 100% 100% 100%
🟢
... / bulk-operation-run-query.ts
100% 100% 100% 100%
🟢
... / get-bulk-operation-by-id.ts
100% 100% 100% 100%
🟢
... / list-bulk-operations.ts
100% 100% 100% 100%
🟢
... / staged-uploads-create.ts
100% 100% 100% 100%
🟢
... / fetch_store_by_domain.ts
100% 100% 100% 100%
🟢
... / organization_exp_flags.ts
100% 100% 100% 100%
🔴
... / import-custom-data-definitions.ts
0% 100% 0% 0%
🔴
... / cancel.ts
0% 100% 0% 0%
🔴
... / execute.ts
0% 0% 0% 0%
🔴
... / status.ts
0% 0% 0% 0%
🔴
... / pull.ts
0% 100% 0% 0%
🟡
... / execute-operation.ts
75.68% 50% 100% 75.68%
🔴
... / pull.ts
0% 0% 0% 0%
🟢
... / bulk-operation-status.ts
96.55% 92.11% 100% 100%
🟢
... / cancel-bulk-operation.ts
100% 100% 100% 100%
🟢
... / constants.ts
100% 100% 100% 100%
🟢
... / download-bulk-operation-results.ts
100% 100% 100% 100%
🟢
... / execute-bulk-operation.ts
87.14% 83.67% 100% 88.41%
🟢
... / format-bulk-operation-status.ts
100% 100% 100% 100%
🟢
... / run-mutation.ts
100% 100% 100% 100%
🟢
... / run-query.ts
100% 100% 100% 100%
🟡
... / stage-file.ts
73.53% 62.5% 85.71% 72.73%
🟢
... / watch-bulk-operation.ts
100% 94.74% 100% 100%
🟢
... / utilities.ts
100% 100% 100% 100%
🟢
... / declarative-definitions.ts
98.54% 93.18% 100% 98.51%
🟢
... / common.ts
97.62% 95% 100% 97.06%
🟢
... / execute-command-helpers.ts
100% 100% 100% 100%
🟢
... / file-formatter.ts
100% 100% 100% 100%
🟢
... / find_development_theme_by_name.ts
100% 100% 100% 100%
🔴
... / promiseWithResolvers.ts
33.33% 50% 50% 33.33%
🟢
... / theme-listing.ts
100% 100% 100% 100%
Show files with reduced coverage 🔻
St.
File Statements Branches Functions Lines
🔴
... / execute.ts
0%
0% (-100% 🔻)
0% 0%
🟢
... / loader.ts
94.06% (+0.2% 🔼)
86.41% (-0.42% 🔻)
97.17% (+0.11% 🔼)
94.85% (+0.18% 🔼)
🟢
... / extension-instance.ts
84.8% (+0.23% 🔼)
77.6% (-0.91% 🔻)
92.06% (+0.13% 🔼)
85.11% (+0.24% 🔼)
🟡
... / specification.ts
69.64% (+0.55% 🔼)
75.61% (+2.44% 🔼)
76.47% (-1.31% 🔻)
69.39% (+0.64% 🔼)
🟢
... / ui_extension.ts
88.61% (-6.22% 🔻)
78.57% (-2.68% 🔻)
85.19% (-14.81% 🔻)
90.79% (-5.67% 🔻)
🟡
... / dev.ts
80% (-1.97% 🔻)
70% (-1.43% 🔻)
76.19% (-3.81% 🔻)
77.97% (-2.03% 🔻)
🟢
... / store-context.ts
100%
82.35% (-0.98% 🔻)
100% 100%
🟢
... / Logs.tsx
90%
90.91% (-5.97% 🔻)
100% 90%
🟢
... / fetch.ts
84.21% (+0.88% 🔼)
82.35% (-0.98% 🔻)
75%
85.29% (+1.42% 🔼)
🟡
... / select-app.ts
63.33% (-24.17% 🔻)
50% (-20% 🔻)
100%
64.29% (-29.05% 🔻)
🟢
... / app-event-watcher-handler.ts
86.36% (-4.11% 🔻)
75% 86.67%
85.71% (-5.19% 🔻)
🟡
... / middlewares.ts
77.33% (-0.87% 🔻)
75%
68.42% (-1.58% 🔻)
76.39% (-0.94% 🔻)
🔴
... / server.ts
1.23% (-0.02% 🔻)
0% 0%
1.3% (-0.02% 🔻)
🟢
... / setup-dev-processes.ts
93.62% (+0.14% 🔼)
66.67% (-4.76% 🔻)
90%
92.86% (+0.17% 🔼)
🟢
... / bundle.ts
93.22%
63.33% (-3.33% 🔻)
94.12% (+5.88% 🔼)
96.3%
🟢
... / developer-platform-client.ts
84.62% (-1.5% 🔻)
71.43% (+0.84% 🔼)
81.82% (+1.82% 🔼)
93.75% (+0.42% 🔼)
🔴
... / http-reverse-proxy.ts
58.97% (-4.91% 🔻)
37.04% (-2.96% 🔻)
58.33% (-5.3% 🔻)
59.46% (-5.25% 🔻)
🟢
... / api.ts
87.07% (-0.43% 🔻)
76.71% (-0.1% 🔻)
100%
86.49% (-0.43% 🔻)
🟢
... / device-authorization.ts
88.24% (-0.83% 🔻)
76.47% (-2.94% 🔻)
100%
88.24% (-0.83% 🔻)
🟢
... / SingleTask.tsx
84.21% (-15.79% 🔻)
50% (-50% 🔻)
80% (-20% 🔻)
84.21% (-15.79% 🔻)
🔴
... / environment.ts
35% (-5% 🔻)
41.18%
40% (-10% 🔻)
36.84% (-5.26% 🔻)
🔴
... / ui.tsx
49.21% (-2.41% 🔻)
40% (-8.39% 🔻)
54.55% (+1.42% 🔼)
48.39% (-2.43% 🔻)
🟢
... / fqdn.ts
93.62% (-1.94% 🔻)
88% (-3.3% 🔻)
100%
93.62% (-1.94% 🔻)
🟢
... / console.ts
81.82% (+15.15% 🔼)
75% (-25% 🔻)
100% (+33.33% 🔼)
81.82% (+15.15% 🔼)
🟢
... / init.ts
88% (-0.89% 🔻)
71.43% (+4.76% 🔼)
86.67% (+4.85% 🔼)
88% (-0.89% 🔻)
🟢
... / storefront-renderer.ts
90.2% (-0.54% 🔻)
78.95%
81.82% (-1.52% 🔻)
90.2% (-0.54% 🔻)
🟡
... / theme-polling.ts
67.57% (-0.49% 🔻)
68.75% 78.57%
66.18% (-1.47% 🔻)

Test suite run success

3734 tests passing in 1445 suites.

Report generated by 🧪jest coverage report action from d9a6149

@github-actions
Copy link
Contributor

This PR seems inactive. If it's still relevant, please add a comment saying so. Otherwise, take no action.
→ If there's no activity within a week, then a bot will automatically close this.
Thanks for helping to improve Shopify's dev tooling and experience.

@github-actions github-actions bot closed this Dec 29, 2025
@graygilmore graygilmore reopened this Jan 5, 2026
@github-actions github-actions bot closed this Jan 13, 2026
@graygilmore graygilmore reopened this Jan 13, 2026
@graygilmore graygilmore force-pushed the gg-push-with-name branch 2 times, most recently from 8b81097 to c24eece Compare February 2, 2026 21:36
@graygilmore graygilmore changed the title Add --name flag to theme push command Add --development-context flag to theme push command Feb 2, 2026
@graygilmore graygilmore force-pushed the gg-push-with-name branch 4 times, most recently from baa67ff to 8a26885 Compare February 3, 2026 00:01
@graygilmore
Copy link
Contributor Author

/snapit

@github-actions
Copy link
Contributor

github-actions bot commented Feb 3, 2026

🫰✨ Thanks @graygilmore! Your snapshot has been published to npm.

Test the snapshot by installing your package globally:

npm i -g --@shopify:registry=https://registry.npmjs.org @shopify/cli@0.0.0-snapshot-20260203000234

Caution

After installing, validate the version by running just shopify in your terminal.
If the versions don't match, you might have multiple global instances installed.
Use which shopify to find out which one you are running and uninstall it.

@Shopify Shopify deleted a comment from github-actions bot Feb 3, 2026
@graygilmore graygilmore marked this pull request as ready for review February 3, 2026 00:11
@graygilmore graygilmore requested review from a team as code owners February 3, 2026 00:11
@binarymonkey84
Copy link

Hey @graygilmore

This looks like excellent progress towards the issue I raised on the dev forums, nice one!

I haven't had a chance to test the snapshotted version yet, but, some questions/notes:

  • I think we'd probably use the commit ID as the name, or part of the name of the theme, to avoid collisions and guarantee I'm looking at the theme with the code at that specific commit state.
    • Maybe update the relevant docs to suggest commit ID?
  • Because this is going to be used in CI, I think we need to make sure the --json CLI flag works so the action script in Github can grab the theme ID, theme editor link, and theme preview link easily.
    • Can this be added to the tests?
  • It would be good to add clarity on how long the dev context theme will live for (before it is auto-deleted by Shopify) when it is used in this way.
    • At the moment, the docs say dev themes are deleted when running 'shopify auth logout'.
    • Development themes are deleted when you run shopify auth logout. If you need a preview link that can be used after you log out, then you should share your theme or push to an unpublished theme on your store.

    • How will this work in a CI context, when we'll be using a theme access password?
    • Can the docs be updated to communicate how and when these types of dev themes get deleted / how long they persist for and any rules around that? I'm assuming they don't live forever, otherwise Shopify will quickly see storage use getting out of control :)
    • Can we add a test to check the command works with theme access passwords?

Thanks again and I hope this is useful!

Really keen to see this go live so we can upgrade our CI process and streamline review.

Copy link
Contributor

@aswamy aswamy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks like a fair change! Couple comments.

These changes can be done in a separate PR if its too heavy:

1. What do you think about updating theme list so we can identify which development theme is mine. I created all of the development themes in the image, but only the latest one says "[yours]"image.png
2. When we do theme dev now, it will always select the latest development theme in your list. Should it try to pick the first Development (*) theme since it was created via theme dev? I dont have a strong opinion on it since you can always do theme dev -t <theme-id> but just wondering what you think. Having multiple development themes was always a little funky in the CLI.

@graygilmore graygilmore force-pushed the gg-push-with-name branch 2 times, most recently from c47c744 to c781447 Compare February 4, 2026 22:50
@graygilmore graygilmore changed the title Add --development-context flag to theme push command Allow --development flag to create a new theme Feb 4, 2026
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👋🏻 @binarymonkey84! Going to respond here so we can thread replies

Maybe update the relevant docs to suggest commit ID?

This is fully up to theme developers to decide how they want to leverage this. Maybe we could add it as an example of configuring a GitHub action, though!

Can this be added to the tests?

This is already working! The additional functionality I've added doesn't have any effect on the --json flag so this should continue working as normal.

It would be good to add clarity on how long the dev context theme will live for (before it is auto-deleted by Shopify) when it is used in this way. [...] Can the docs be updated to communicate how and when these types of dev themes get deleted / how long they persist for and any rules around that?

I'm not sure if we've ever shared the exact timing for this. I'll sync with the team to see if we can get some official documentation around this. Keep in mind, too, that there is a limit to the amount of development themes you can have (also undocumented, we'll see about having official guidelines on that, too).

At the moment, the docs say dev themes are deleted when running 'shopify auth logout'.

This might have been true at some point but is not true now. We'll get this cleaned up.

How will this work in a CI context, when we'll be using a theme access password?

In CI you'll be running the same command but also passing the --password flag. Perhaps I'm misunderstanding? Or is this in relation to the confusing wording about when development themes are deleted?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @graygilmore

Maybe update the relevant docs to suggest commit ID?

This is fully up to theme developers to decide how they want to leverage this. Maybe we could add it as an example of configuring a GitHub action, though!

Yeah, I guess it's just because in the PR there were already opinions on how devs could name their theme (think it was pull request name and something else), so I thought if we're making suggestions, then suggesting commit ID might be worth doing since it encourages using this for theme instances that are more likely to correspond to a PR at a specific commit. Not too fussed on this though!

This is already working! The additional functionality I've added doesn't have any effect on the --json flag so this should continue working as normal.

Great! Wasn't sure if the --json flag was only supported with certain flags or contexts. Given this will be probably used by developers in conjunction with the command, makes sense to check it does work but if it's guaranteed to work then all good.

It would be good to add clarity on how long the dev context theme will live for (before it is auto-deleted by Shopify) when it is used in this way. [...] Can the docs be updated to communicate how and when these types of dev themes get deleted / how long they persist for and any rules around that?

I'm not sure if we've ever shared the exact timing for this. I'll sync with the team to see if we can get some official documentation around this. Keep in mind, too, that there is a limit to the amount of development themes you can have (also undocumented, we'll see about having official guidelines on that, too).

At the moment, the docs say dev themes are deleted when running 'shopify auth logout'.

This might have been true at some point but is not true now. We'll get this cleaned up.

Amazing, yes having that clarity would really help to plan and set expectations.

How will this work in a CI context, when we'll be using a theme access password?

In CI you'll be running the same command but also passing the --password flag. Perhaps I'm misunderstanding? Or is this in relation to the confusing wording about when development themes are deleted?

It's just in relation to the confusing wording :) As in, if themes are deleted on 'shopify auth logout', but that CLI command won't be run in the CI action, it wasn't clear when the theme would actually be deleted.

Cheers for all your work on this!

Copy link
Contributor

aswamy commented Feb 5, 2026

/snapit

@github-actions
Copy link
Contributor

github-actions bot commented Feb 5, 2026

🫰✨ Thanks @aswamy! Your snapshot has been published to npm.

Test the snapshot by installing your package globally:

npm i -g --@shopify:registry=https://registry.npmjs.org @shopify/cli@0.0.0-snapshot-20260205141355

Caution

After installing, validate the version by running just shopify in your terminal.
If the versions don't match, you might have multiple global instances installed.
Use which shopify to find out which one you are running and uninstall it.

Copy link
Contributor

@aswamy aswamy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think oclif needs to be regenerated or something because i can't pass --development flag without args anymore

Comment on lines 60 to 72
development: Flags.custom<true | string>({
char: 'd',
description: 'Push theme files from your remote development theme.',
description:
'Push theme files from your remote development theme. Optionally specify a context name (e.g., PR number, branch name) to reuse or create a named development theme.',
env: 'SHOPIFY_FLAG_DEVELOPMENT',
}),
parse: async (input: string | undefined) => {
if (input === undefined) {
return true
}

return input
},
})(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of having a custom type, could we just change it to a string?

Logic:

  • when flag is set && value == "" => development theme with no custom name

  • when flag is set && value.length > 0 => development theme with a custom name

Not sure why it's bugging out when i tophat it, but it's currently saying --development flag needs a value. Maybe oclif needs to be regenerated?

image.png

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After all that it looks like you can't have a flag that optionally accepts a value 😭

Flag options are non-positional arguments passed to the command. Flags can either be option flags which take an argument, or boolean flags which do not. An option flag must have an argument.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im sad you had to do so much work for this :( hoping it was mostly claude 🫣

Adds a new flag called --development-context on theme push that will
allow developers to manually generate new development themes.
Particularly helpful in CI environments.
@github-actions
Copy link
Contributor

github-actions bot commented Feb 5, 2026

Differences in type declarations

We detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:

  • Some seemingly private modules might be re-exported through public modules.
  • If the branch is behind main you might see odd diffs, rebase main into this branch.

New type declarations

packages/cli-kit/dist/cli/api/graphql/admin/generated/find_development_theme_by_name.d.ts
import * as Types from './types.js';
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
export type FindDevelopmentThemeByNameQueryVariables = Types.Exact<{
    name: Types.Scalars['String']['input'];
}>;
export type FindDevelopmentThemeByNameQuery = {
    themes?: {
        nodes: {
            id: string;
            name: string;
            role: Types.ThemeRole;
            processing: boolean;
        }[];
    } | null;
};
export declare const FindDevelopmentThemeByName: DocumentNode<FindDevelopmentThemeByNameQuery, FindDevelopmentThemeByNameQueryVariables>;

Existing type declarations

packages/cli-kit/dist/public/node/themes/api.d.ts
@@ -5,6 +5,7 @@ export type ThemeParams = Partial<Pick<Theme, 'name' | 'role' | 'processing' | '
 export type AssetParams = Pick<ThemeAsset, 'key'> & Partial<Pick<ThemeAsset, 'value' | 'attachment'>>;
 export declare function fetchTheme(id: number, session: AdminSession): Promise<Theme | undefined>;
 export declare function fetchThemes(session: AdminSession): Promise<Theme[]>;
+export declare function findDevelopmentThemeByName(name: string, session: AdminSession): Promise<Theme | undefined>;
 export declare function themeCreate(params: ThemeParams, session: AdminSession): Promise<Theme | undefined>;
 export declare function fetchThemeAssets(id: number, filenames: Key[], session: AdminSession): Promise<ThemeAsset[]>;
 export declare function deleteThemeAssets(id: number, filenames: Key[], session: AdminSession): Promise<Result[]>;
packages/cli-kit/dist/public/node/themes/theme-manager.d.ts
@@ -8,8 +8,8 @@ export declare abstract class ThemeManager {
     protected abstract removeTheme(): void;
     protected abstract context: string;
     constructor(adminSession: AdminSession);
-    findOrCreate(): Promise<Theme>;
-    fetch(): Promise<Theme | undefined>;
+    findOrCreate(name?: string, role?: Role): Promise<Theme>;
+    fetch(name?: string, role?: Role): Promise<Theme | undefined>;
     generateThemeName(context: string): string;
     create(themeRole?: Role, themeName?: string): Promise<Theme>;
 }
\ No newline at end of file

@graygilmore
Copy link
Contributor Author

/snapit

@github-actions
Copy link
Contributor

github-actions bot commented Feb 5, 2026

🫰✨ Thanks @graygilmore! Your snapshot has been published to npm.

Test the snapshot by installing your package globally:

npm i -g --@shopify:registry=https://registry.npmjs.org @shopify/cli@0.0.0-snapshot-20260205225255

Caution

After installing, validate the version by running just shopify in your terminal.
If the versions don't match, you might have multiple global instances installed.
Use which shopify to find out which one you are running and uninstall it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants