Skip to content

Add --print-instructions to app security check - #8878

Merged
nickwesselman merged 3 commits into
mainfrom
nickwesselman/security-check-print-instructions
Oct 13, 2026
Merged

nickwesselman merged 3 commits into
mainfrom
nickwesselman/security-check-print-instructions

Conversation

@nickwesselman

Copy link
Copy Markdown
Contributor

WHY are these changes introduced?

Review feedback noted that --yes sounds like a general confirmation bypass, but it only selects printed coding-agent instructions. It does not answer app-selection prompts or choose the interactive default of copying.

WHAT is this pull request doing?

  • Adds --print-instructions and SHOPIFY_FLAG_APP_SECURITY_PRINT_INSTRUCTIONS as the explicit instruction-output option.
  • Keeps --yes and SHOPIFY_FLAG_YES working as a hidden, deprecated compatibility path. Normal invocations do not warn.
  • Preserves the existing instruction flow and exclusions with --skip-instructions and --list-files; --no-input still only controls interactivity. The internal option is now named printInstructions.
  • Regenerates the manifest, README, and developer flag-reference data, and adds a minor changeset. This PR is independent of the usage-examples PR.

How to manually test your changes?

  1. Run pnpm shopify app security check --help. It advertises --print-instructions, not --yes, and has no empty usage alternative.
  2. Against an app with a single valid configuration, run pnpm shopify app security check --path <app> --no-input --print-instructions. Instructions print after the scan without a delivery prompt.
  3. Run the same command with --yes instead. It still prints instructions and warns to use --print-instructions. SHOPIFY_FLAG_YES=1 remains supported too.
  4. Combining either printing flag with --skip-instructions or --list-files is rejected.

Validation

  • 131 focused command, integration, service, and layout tests passed.
  • ESLint passed for all changed TypeScript files.
  • CLI and create-app builds passed.
  • Ran pnpm refresh-manifests and pnpm build-dev-docs; verified the rendered public help and generated reference use the canonical flag.
  • git diff --check passed.

An existing missing-config path assertion fails on both untouched main and this change in a shallow checkout. All focused tests passed from a normal-depth checkout; no unrelated test fix is included.

Checklist

  • I've considered possible cross-platform impacts (Mac, Linux, Windows)
  • I've considered possible documentation changes
  • I've considered analytics changes to measure impact
  • The change is user-facing — a minor changeset is included for the new flag and deprecation notice.

PR authored by Qlaw

@github-actions github-actions Bot added shopify.dev preview Area: @shopify/cli @shopify/cli package issues labels Oct 13, 2026
@nickwesselman

Copy link
Copy Markdown
Contributor Author

/snapit

@github-actions

Copy link
Copy Markdown
Contributor

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

Built from c006c749e8dc26ac8d1a5f9482654d7f1f76df12. Workflow run.

Test the snapshot by installing your package globally:

pnpm i -g --@shopify:registry=https://registry.npmjs.org @shopify/[email protected]

Caution

After installing, validate the version by running shopify version 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.

@nickwesselman
nickwesselman marked this pull request as ready for review October 13, 2026 15:32
@nickwesselman
nickwesselman requested review from a team as code owners October 13, 2026 15:32
test.each([{flags: ['--print-instructions']}, {flags: ['--yes']}, {flags: ['--print-instructions', '--yes']}])(
'rejects $flags with --skip-instructions',
async ({flags}) => {
await expect(SecurityCheck.run([...flags, '--skip-instructions'], import.meta.url)).rejects.toThrow()

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.

Optional: this assertion passes for any error, not only the flag conflict. In these tests, every parse error becomes process.exit unexpectedly called with "1". I checked: --not-a-real-flag --skip-instructions throws the same error. So if a flag in this test is renamed later, the test still passes. Lines 219 and 278 have the same problem.

Please check the rendered message, as the test at line 243 does:

const outputMock = mockAndCaptureOutput()
// ...
await expect(SecurityCheck.run([...flags, '--skip-instructions'], import.meta.url)).rejects.toThrow(
  'process.exit unexpectedly called with "1"',
)
expect(outputMock.error()).toContain('cannot also be provided when using')

The error box wraps long lines, so match a short part of the message.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated the conflict tests to check the rendered cannot also be provided message, rather than only asserting that something throws. This includes the CLI, true/false environment, and list-files cases. Verified with an unknown-flag mutation: it now fails the conflict-message assertion.

['SHOPIFY_FLAG_APP_SECURITY_PRINT_INSTRUCTIONS', '--list-files'],
['SHOPIFY_FLAG_YES', '--skip-instructions'],
['SHOPIFY_FLAG_YES', '--list-files'],
])('rejects %s with %s', async (environment, incompatible) => {

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.

Optional: these tests set a printing variable and pass a mode flag. Some combinations are not tested:

  • A mode from the environment with a printing flag. For example, SHOPIFY_FLAG_LIST_FILES=1 with --print-instructions, or SHOPIFY_FLAG_APP_SECURITY_SKIP_INSTRUCTIONS=1 with --yes.
  • Both printing variables set.
  • A printing flag with the other printing variable set to 0. For example, --print-instructions with SHOPIFY_FLAG_YES=0.

I expect these to work, because oclif checks the exclusions of every flag that has a value. But each exclusion is declared on one flag only. For example, yes lists list-files, but list-files does not list yes. Tests for these cases would catch a future edit that removes one side.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added 12 cases covering both printing variables across all 0/1 combinations, a printing CLI flag with the other printing variable set to 0 or 1, and environment-selected list-files/skip-instructions modes with either printing CLI flag. All 143 focused tests, lint, and builds passed. Warning behavior is unchanged.

['SHOPIFY_FLAG_APP_SECURITY_PRINT_INSTRUCTIONS', '1', true, false],
['SHOPIFY_FLAG_APP_SECURITY_PRINT_INSTRUCTIONS', '0', false, false],
['SHOPIFY_FLAG_YES', '1', true, true],
['SHOPIFY_FLAG_YES', '0', false, true],

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.

Optional question: with SHOPIFY_FLAG_YES=0, the command does not print the instructions, but it still shows this warning:

Warning: The "yes" flag has been deprecated. Use "--print-instructions" instead.

I saw this with a fresh build of this head. oclif warns for every deprecated flag that has a value, and 0 is a value. This row expects the warning, so it can be intentional. But a user who sets SHOPIFY_FLAG_YES=0 does not want printing. For them, the correct change is to remove the variable, not to use --print-instructions. Consider warning only when the value turns printing on. If the current behavior is intended, ignore this.

@nickwesselman
nickwesselman added this pull request to the merge queue Oct 13, 2026
Merged via the queue into main with commit 35f53e6 Oct 13, 2026
29 of 31 checks passed
@nickwesselman
nickwesselman deleted the nickwesselman/security-check-print-instructions branch October 13, 2026 16:51
dmerand added a commit that referenced this pull request Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: @shopify/cli @shopify/cli package issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants