Skip to content

feat(cli): add non-interactive flag to hydrogen upgrade command#3744

Open
z0n wants to merge 1 commit intoShopify:mainfrom
z0n:feat/hydrogen-upgrade-non-interactive
Open

feat(cli): add non-interactive flag to hydrogen upgrade command#3744
z0n wants to merge 1 commit intoShopify:mainfrom
z0n:feat/hydrogen-upgrade-non-interactive

Conversation

@z0n
Copy link
Copy Markdown

@z0n z0n commented Apr 22, 2026

WHY are these changes introduced?

Fixes #3743

I needed a non-interactive flag for the shopify hydrogen upgrade command to easily use the upgrade command via an agent skill.

WHAT is this pull request doing?

This PR adds a --non-interactive (alternatives: -y/--yes) flag which only works when a version is specified via --version. It then skips all interactive prompts and overwrites upgrade instructions if there are already some for that version upgrade.

I worked around the --version=next a bit awkwardly as it already does a few things this flag does but I didn't want to break it as I'm not sure how it's used currently.

HOW to test your changes?

In an outdated Hydrogen project, run shopify hydrogen upgrade --version 2026.4.1 --non-interactive -> it should upgrade the project without any prompts.

You can also try shopify hydrogen upgrade --version 2026.4.1 --non-interactive < /dev/null which would throw an error in previous versions as it would trigger a Failed to prompt error.

Post-merge steps

Docs need to be updated with the new flag.

Checklist

  • I've read the Contributing Guidelines
  • I've considered possible cross-platform impacts (Mac, Linux, Windows)
  • I've added a changeset if this PR contains user-facing or functional changes. Test changes or internal-only config changes do not require a changeset.
  • I've added tests to cover my changes
  • I've added or updated the documentation

@z0n z0n marked this pull request as ready for review April 22, 2026 14:56
@z0n z0n requested a review from a team as a code owner April 22, 2026 14:56
availableUpgrades: Array<Release>;
currentVersion: string;
currentDependencies: Record<string, string>;
nonInteractive?: boolean;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

non-blocking: the caller guarantees that when nonInteractive is true, targetVersion is defined (via the precondition at the top of runUpgrade). the types don't express this constraint though -- a new call site could call getSelectedRelease({nonInteractive: true}) without the precondition, and the error message below would interpolate undefined. the runtime guard makes this safe in practice, just noting the type-level information leakage.

cumulativeRelease,
currentVersion,
selectedRelease,
nonInteractive: nonInteractive || targetVersion === 'next',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

non-blocking: the caller computes the effective non-interactive state here (nonInteractive: nonInteractive || targetVersion === 'next'), but displayConfirmation handles it internally (if (targetVersion === 'next' || nonInteractive)). the same decision is split between two layers. this is pre-existing -- the targetVersion === 'next' check was already inside displayConfirmation -- and the PR correctly extends the pattern to generateUpgradeInstructionsFile. just noting the inconsistency for context.

'Run without any interactive prompts. Requires --version. Auto-accepts the upgrade confirmation and overwrites any existing upgrade instructions file.',
env: 'SHOPIFY_HYDROGEN_FLAG_NON_INTERACTIVE',
char: 'y',
aliases: ['yes'],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

non-blocking: in the broader CLI ecosystem, --yes/-y traditionally means "auto-confirm" (think apt-get -y). here, --non-interactive goes a bit further -- it requires --version, auto-overwrites files, and changes TTY detection. a user who writes shopify hydrogen upgrade -y expecting auto-confirm behaviour will get a clear error message ("requires --version"), so it's mitigated in practice. just noting the potential UX friction.

// Generate a markdown file with upgrade instructions.
// `--version=next` is treated as implicitly non-interactive to stay
// consistent with how `displayConfirmation` handles it.
const instrunctionsFilePathPromise = generateUpgradeInstructionsFile({
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

can i ask you to also fix the typo here? instrunctionsFilePathPromise should be instructionsFilePathPromise

);
});

it('bypasses the TTY check when --non-interactive is set', async () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

really good test!

* UPGRADE_TEST_LAST_N=<number> - Test last N versions
* FORCE_CHANGELOG_SOURCE=local - Read changelog from local file (set by tests)
* SHOPIFY_HYDROGEN_FLAG_FORCE=1 - Skip interactive prompts (set by tests)
* SHOPIFY_HYDROGEN_FLAG_FORCE=1 - Skip dirty git branch check (set by tests)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

praise: nice catch -- --force actually skips the dirty git branch check, not interactive prompts. good cleanup.

'@shopify/cli-hydrogen': patch
---

Add `--non-interactive` flag (alias `-y`/`--yes`, env `SHOPIFY_HYDROGEN_FLAG_NON_INTERACTIVE`) to `shopify hydrogen upgrade` so it can run in CI and other non-TTY environments. Requires `--version` to be set, auto-accepts the confirmation prompt, and auto-overwrites any existing upgrade instructions file. When run without a TTY and without this flag, the resulting error now points to it.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

praise: well-written changeset -- clearly describes the feature, aliases, env var, and behavioural details. written for merchants, which is the right audience.

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.

2 participants