Skip to content

App Security: gather files with Git ignore rules, --exclude and --no-git-ignore - #8738

Merged
jek merged 1 commit into
app-security/results-keyfrom
app-security/gathering
Oct 5, 2026
Merged

jek merged 1 commit into
app-security/results-keyfrom
app-security/gathering

Conversation

@jek

@jek jek commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

WHY are these changes introduced?

Gathering combined a hidden default exclude list, --ignore overrides and a skip of directories holding another TOML, so it was hard to predict which files were scanned.

WHAT is this pull request doing?

Replace --ignore and the default list with Git's own rules: each file follows its own repository's ignore rules, tracked files are always scanned, and a scan directory that its repository ignores gathers only its tracked files, with a warning. --exclude takes globs relative to the working directory, and --no-git-ignore turns Git filtering off. The selected TOML is always scanned. All reads go through one reader configured per scan.

With --no-git-ignore, an untracked secret file that Git ignores is no longer reported as COMMITTED_SECRET.

How to manually test your changes?

shopify app security check --exclude 'dist/**'
shopify app security check --no-git-ignore --exclude node_modules

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 — I've identified the correct bump type (patch for bug fixes · minor for new features · major for breaking changes) and added a changeset with pnpm changeset add

@jek
jek added this pull request to stack #8741 October 2, 2026 12:59
@github-actions github-actions Bot added the no-changelog This PR doesn't include a changeset entry. Is an internal only change not relevant to end users. label Oct 2, 2026
@jek jek changed the title Gather App Security files with Git ignore rules, --exclude and --no-git-ignore App Security: gather files with Git ignore rules, --exclude and --no-git-ignore Oct 2, 2026
@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

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

We found no new type declarations in this PR

Existing type declarations

packages/cli-kit/dist/public/node/cli.d.ts
@@ -35,7 +35,6 @@ export declare function runCreateCLI(options: RunCLIOptions, launchCLI?: (option
 export declare const globalFlags: {
     'no-color': import("@oclif/core/interfaces").BooleanFlag<boolean>;
     verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
-    'no-input': import("@oclif/core/interfaces").BooleanFlag<boolean>;
 };
 export declare const jsonFlag: {
     json: import("@oclif/core/interfaces").BooleanFlag<boolean>;

@jek
jek force-pushed the app-security/gathering branch from 5187bd9 to 74700bd Compare October 2, 2026 13:35
@jek
jek force-pushed the app-security/gathering branch from 74700bd to e991491 Compare October 2, 2026 14:02
@jek
jek marked this pull request as ready for review October 2, 2026 18:36
@jek
jek requested review from a team as code owners October 2, 2026 18:36
@jek
jek requested a review from jplhomer October 2, 2026 18:38
@jek
jek force-pushed the app-security/gathering branch from e991491 to 4856f12 Compare October 2, 2026 21:07
…it-ignore

Replace --ignore and the default exclude list. Each file follows its own
repository's ignore rules, --exclude takes globs relative to the working
directory, and --no-git-ignore turns Git filtering off. A scan directory that
its repository ignores gathers only tracked files, with a warning. All reads go
through one reader configured per scan.
@jek
jek force-pushed the app-security/gathering branch from 4856f12 to 63f31b9 Compare October 5, 2026 13:46
@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

⚠️ Potential Breaking Changes Detected

This PR contains changes that may break the existing contract.

@shopify/dev_experience — this PR contains breaking changes that require coordination for the next major release.

🏳️ Removed Flags

The following flags were removed from existing commands:

Command Flag
app:security:check --ignore

@jplhomer jplhomer left a comment

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.

Only potential side effect that may bite is having all the tests/fixtures included in the run (they were ignored before with a custom list).

const parent = dirname(directory)
if (parent === directory) return false
const result = await runGit(parent, ['check-ignore', '--no-index', '-q', '--', basename(directory)])
return result?.exitCode === 0

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.

It may be worth treating a missing Git binary as a listing failure instead of trusting the exit code.

I smoke-tested the compiled CLI with Git unavailable from PATH. check exits 0, warns that the app directory is ignored by Git, gathers only the selected TOML, and reports files_scanned: 0 with no gaps and an executed COMMITTED_SECRET check with no findings. A synthetic token in an untracked .env goes unreported. The PR base reports that finding; --no-git-ignore also reports it.

The cause: when the Git spawn fails, captureOutputWithExitCode returns exit code 0 with empty output. This function then reports the directory as ignored, and listTrackedFiles returns the empty list instead of undefined, so the tracked-only branch gathers nothing and the failed listing status is never reached.

/** What gathering reports besides the result, for the caller to show. It isn't part of the stored findings. */
export interface ScanOutput extends ScanResult {
/** Absolute paths of the scan directories that their repository ignores, so only the files Git tracks in them were scanned. */
ignoredScanDirectories: string[]

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.

Did you consider surfacing ignored scan directories in the JSON output and stored coverage?

scan_directories shows the requested roots, but nothing in the machine-readable output says that a root was ignored by Git and therefore gathered tracked-only. The terminal report warns about it, yet a JSON consumer — or anyone reading deterministic-findings.json later — sees a scan that looks fully walked.

@jek
jek added this pull request to the merge queue Oct 5, 2026
Merged via the queue into main with commit 0f64488 Oct 5, 2026
31 of 57 checks passed
@jek
jek deleted the app-security/gathering branch October 5, 2026 18:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog This PR doesn't include a changeset entry. Is an internal only change not relevant to end users.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants