Add --ignore to app security check and instructions - #8702
Merged
Merged
Conversation
Contributor
Differences in type declarationsWe 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:
New type declarationsWe found no new type declarations in this PR Existing type declarationspackages/cli-kit/dist/public/common/command-events.d.ts@@ -23,14 +23,14 @@ export declare const commandDiagnosticEventSchema: z.ZodObject<{
export declare const commandProgressEventSchema: z.ZodObject<{
type: z.ZodLiteral<"progress">;
timestamp: z.ZodString;
- status: z.ZodEnum<["started", "updated", "retrying", "completed", "failed"]>;
+ status: z.ZodEnum<["started", "updated", "completed"]>;
operation: z.ZodString;
message: z.ZodOptional<z.ZodString>;
current: z.ZodOptional<z.ZodNumber>;
total: z.ZodOptional<z.ZodNumber>;
}, "strict", z.ZodTypeAny, {
type: "progress";
- status: "started" | "updated" | "retrying" | "completed" | "failed";
+ status: "started" | "updated" | "completed";
timestamp: string;
operation: string;
message?: string | undefined;
@@ -38,7 +38,7 @@ export declare const commandProgressEventSchema: z.ZodObject<{
total?: number | undefined;
}, {
type: "progress";
- status: "started" | "updated" | "retrying" | "completed" | "failed";
+ status: "started" | "updated" | "completed";
timestamp: string;
operation: string;
message?: string | undefined;
@@ -67,14 +67,14 @@ export declare const commandEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
}>, z.ZodObject<{
type: z.ZodLiteral<"progress">;
timestamp: z.ZodString;
- status: z.ZodEnum<["started", "updated", "retrying", "completed", "failed"]>;
+ status: z.ZodEnum<["started", "updated", "completed"]>;
operation: z.ZodString;
message: z.ZodOptional<z.ZodString>;
current: z.ZodOptional<z.ZodNumber>;
total: z.ZodOptional<z.ZodNumber>;
}, "strict", z.ZodTypeAny, {
type: "progress";
- status: "started" | "updated" | "retrying" | "completed" | "failed";
+ status: "started" | "updated" | "completed";
timestamp: string;
operation: string;
message?: string | undefined;
@@ -82,7 +82,7 @@ export declare const commandEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodO
total?: number | undefined;
}, {
type: "progress";
- status: "started" | "updated" | "retrying" | "completed" | "failed";
+ status: "started" | "updated" | "completed";
timestamp: string;
operation: string;
message?: string | undefined;
packages/cli-kit/dist/public/node/command-events.d.ts@@ -29,14 +29,14 @@ export declare const commandEventOutputSchema: import("./json-output-schema.js")
}>, import("zod").ZodObject<{
type: import("zod").ZodLiteral<"progress">;
timestamp: import("zod").ZodString;
- status: import("zod").ZodEnum<["started", "updated", "retrying", "completed", "failed"]>;
+ status: import("zod").ZodEnum<["started", "updated", "completed"]>;
operation: import("zod").ZodString;
message: import("zod").ZodOptional<import("zod").ZodString>;
current: import("zod").ZodOptional<import("zod").ZodNumber>;
total: import("zod").ZodOptional<import("zod").ZodNumber>;
}, "strict", import("zod").ZodTypeAny, {
type: "progress";
- status: "started" | "updated" | "retrying" | "completed" | "failed";
+ status: "started" | "updated" | "completed";
timestamp: string;
operation: string;
message?: string | undefined;
@@ -44,7 +44,7 @@ export declare const commandEventOutputSchema: import("./json-output-schema.js")
total?: number | undefined;
}, {
type: "progress";
- status: "started" | "updated" | "retrying" | "completed" | "failed";
+ status: "started" | "updated" | "completed";
timestamp: string;
operation: string;
message?: string | undefined;
packages/cli-kit/dist/public/node/ui.d.ts@@ -318,8 +318,6 @@ export declare function renderTasks<TContext>(tasks: Task<TContext>[], { renderO
export interface RenderSingleTaskOptions<T> {
title: TokenizedString;
task: (updateStatus: (status: TokenizedString) => void) => Promise<T>;
- /** The number of additional attempts after a failure. Defaults to zero. */
- retry?: number;
onAbort?: () => void;
renderOptions?: RenderOptions;
}
@@ -328,13 +326,12 @@ export interface RenderSingleTaskOptions<T> {
* @param options - Configuration object
* @param options.title - The initial title to display with the loading bar
* @param options.task - The async task to execute. Receives an updateStatus callback to change the displayed title.
- * @param options.retry - The number of additional attempts after a failure. Defaults to zero.
* @param options.renderOptions - Optional render configuration
* @returns The result of the task
* @example
* Loading app ...
*/
-export declare function renderSingleTask<T>({ title, task, retry, onAbort, renderOptions, }: RenderSingleTaskOptions<T>): Promise<T>;
+export declare function renderSingleTask<T>({ title, task, onAbort, renderOptions, }: RenderSingleTaskOptions<T>): Promise<T>;
export interface RenderTextPromptOptions extends Omit<TextPromptProps, 'onSubmit'> {
renderOptions?: RenderOptions;
}
packages/cli-kit/dist/private/node/ui/hooks/use-async-and-unmount.d.ts@@ -1,6 +1,6 @@
-interface Options<T> {
- onFulfilled?: (result: T) => unknown;
+interface Options {
+ onFulfilled?: () => unknown;
onRejected?: (error: Error) => void;
}
-export default function useAsyncAndUnmount<T>(asyncFunction: () => Promise<T>, { onFulfilled, onRejected }?: Options<T>): void;
+export default function useAsyncAndUnmount(asyncFunction: () => Promise<unknown>, { onFulfilled, onRejected }?: Options): void;
export {};
\ No newline at end of file
packages/cli-kit/dist/private/node/ui/components/Tasks.d.ts@@ -1,7 +1,14 @@
import { AbortSignal } from '../../../../public/node/abort.js';
-import { Task } from '../tasks.js';
+import { TokenizedString } from '../../../../public/node/output.js';
import React from 'react';
-export type { Task } from '../tasks.js';
+export interface Task<TContext = unknown> {
+ title: string | TokenizedString;
+ task: (ctx: TContext, task: Task<TContext>) => Promise<void | Task<TContext>[]>;
+ retry?: number;
+ retryCount?: number;
+ errors?: Error[];
+ skip?: (ctx: TContext) => boolean;
+}
interface TasksProps<TContext> {
tasks: Task<TContext>[];
silent?: boolean;
|
1 of 4 tasks
jek
force-pushed
the
app-security/path-filter
branch
2 times, most recently
from
September 29, 2026 22:39
94b1cc0 to
cd3543d
Compare
dmerand
reviewed
Sep 30, 2026
jek
added a commit
that referenced
this pull request
Sep 30, 2026
A nested repository is excluded like any ignored folder when the app's repository ignores it, directly or through a parent folder. Finding repositories below ignored parents would mean walking the ignored trees that pruning skips; --ignore from #8702 can opt one back in.
Each --ignore value is one .gitignore line, relative to the app directory. Patterns take precedence over the default and gitignore exclusions: they can ignore more files or, with a leading !, include ignored ones again. Later patterns take precedence over earlier ones. A file can't be included again while its parent folder is ignored, and a folder git ignores as a whole can only be included again as a folder. Patterns apply to dependency automation configuration too. When any pattern includes a path again, git's listing also covers the default directories, so .gitignore still applies inside a default folder that a pattern includes again. The generated compile and clean commands repeat the patterns, and app security instructions accepts them too, so compiling findings re-scans the same files. A findings file compiled with different patterns is rejected with a hint to reuse the scan's patterns. --ignore has no environment variable. oclif reads a repeatable flag's variable only when the command line has no value for that flag, and passes it as a single string, so it could hold one pattern and any --ignore on the command line would silently replace it. Flag values in the generated commands are always quoted, so a pattern such as -*.log or check isn't mistaken for a flag or a command word. Values that would silently do nothing or crash the scan are rejected: blank values, # comments, a lone !, an odd number of trailing backslashes, values that span more than one line, patterns with a .. path segment, which can never match because scanned paths are relative to the app directory, and any pattern the matcher can't compile, such as an unclosed [ followed by /.
App Security stays out of public release notes until it ships (#8698).
jek
force-pushed
the
app-security/path-filter
branch
from
September 30, 2026 21:12
ff1fa1c to
5606f93
Compare
instructions validated patterns with its own flags, so it accepted values such as --clean that the check commands it generates then read as flags. Nothing passes --ignore to instructions. The instructions check offers after a scan are built from check's own parsed flags, so they still repeat its patterns and always parse.
Only app-security-commands.ts uses it, and Knip rejects the unused export.
Different --ignore patterns change the hash only when they change which files are scanned.
…ed config --ignore '!inner/' re-includes a nested repository that the app's repository ignores. A pattern that excludes the selected app configuration doesn't stop it from being scanned for secrets.
dmerand
approved these changes
Sep 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #8691.
WHY are these changes introduced?
The files
shopify app security checkscans are decided entirely by the default exclusions and.gitignore(#8691). Users can't skip tracked generated code, or scan a folder the defaults exclude, such asbuild/ortest/.WHAT is this pull request doing?
Adds a repeatable
--ignoreflag toapp security check. Each value is one.gitignoreline relative to the app directory, and a leading!includes files again.!logs/, not!logs/debug.log).source_scan_idand they're rejected; the error says to reuse the scan's--ignoreand--configvalues.app security instructionsdoesn't take--ignore. It would validate patterns against its own flags, and accept values such as--cleanthat thecheckcommands it generates then read as flags. The instructionscheckoffers after a scan repeat its patterns.--ignorehas no environment variable: oclif passes a repeatable flag's variable as one string, so it could only hold one pattern.Patterns are matched with the
ignorepackage, as elsewhere in the CLI. It differs from git on some unusual syntax, such as an escaped backslash before a regex special character.How to manually test your changes?
In a git-tracked app, with a Shopify token-shaped value (
shpat_followed by 32 hex characters):generated/client.ts,git addit, and runpnpm shopify app security check --path /path/to/app: it's reported.pnpm shopify app security check --path /path/to/app --ignore 'generated/': it's no longer reported.build/config.jsand runpnpm shopify app security check --path /path/to/app --ignore '!build/': it's reported, althoughbuild/is excluded by default.pnpm shopify app security check --path /path/to/app --ignore 'src/[id/x.ts': the flag is rejected with a message.Checklist
patchfor bug fixes ·minorfor new features ·majorfor breaking changes) and added a changeset withpnpm changeset add