Skip to content

Fix qmd: multi-pattern checkouts index 0 files due to comma-joined patterns#22673

Closed
Copilot wants to merge 2 commits intomainfrom
copilot/review-file-indexing-qmd
Closed

Fix qmd: multi-pattern checkouts index 0 files due to comma-joined patterns#22673
Copilot wants to merge 2 commits intomainfrom
copilot/review-file-indexing-qmd

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 24, 2026

The qmd indexing job produced 0 indexed files when a checkout declared multiple paths patterns. The patterns were joined with commas into a single string (e.g. "docs/**,.github/agents/**,.github/aw/**") and passed as one pattern to the SDK — which treats it as a literal glob and matches nothing.

Changes

actions/setup/js/qmd_index.cjs

  • Root fix: Create one qmd collection per pattern instead of comma-joining. Single-pattern checkouts keep the original name; multi-pattern checkouts get suffixed names (repo-0, repo-1, …).
  • Per-pattern file count: New countGlobMatches() uses Node.js 22+ fs.globSync to count matched files per pattern before handing off to the SDK, logged as -> collection "gh-aw-0": pattern="docs/**" (142 file(s) matched). Errors are surfaced via core.debug().
  • Updated "0 files indexed" warning: Removed the now-resolved comma-separated-pattern cause.

pkg/workflow/qmd.go

  • Compile-time validation: New validateQmdPatterns() warns at gh aw compile time for empty patterns and patterns containing commas (common mistake), catching the mistake before the workflow ever runs. Only validates user-provided paths.

actions/setup/js/qmd_index.test.cjs

  • 3 new tests: multi-pattern sub-collections, single-pattern name preservation, dotfile patterns (.github/agents/**)
  • Fixed a pre-existing test using exact string match instead of stringContaining (inconsistent with all other tests in the file)
# Before — comma-joined, 0 files indexed
pattern="docs/src/content/docs/**,.github/agents/**,.github/aw/**"
Update complete: 0 indexed, 0 updated, 0 unchanged, 0 removed

# After — one collection per pattern
-> collection "gh-aw-0": pattern="docs/src/content/docs/**" (87 file(s) matched)
-> collection "gh-aw-1": pattern=".github/agents/**" (12 file(s) matched)
-> collection "gh-aw-2": pattern=".github/aw/**" (5 file(s) matched)

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw GO111MODULE 64/bin/go git rev-�� --show-toplevel erignore /usr/bin/git -json GO111MODULE 64/bin/go git (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw GO111MODULE de git rev-�� --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git (http block)
  • https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /usr/lib/php/sessionclean GOINSECURE GOMOD GOMODCACHE /usr/lib/php/sessionclean (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha --write **/*.cjs /opt/hostedtoolcache/uv/0.11.0/x86_64/sh **/*.json --ignore-path ../../../.pretti--show-toplevel sh -c "prettier" --write '../../../**/*.json' '!../../../pkg/workflow/js/**/*.json' --ignore-path ../.git go /home/REDACTED/node_modules/.bin/node -json GO111MODULE 64/bin/go node (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha *.json' '!../../../pkg/workflow/js/**/*.json' --ignore-path ../../../.prettierignore GO111MODULE 0/x64/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin/node GOINSECURE GOMOD GOMODCACHE go tion�� ting Go code..." GO111MODULE k/_temp/uv-python-dir/node GOINSECURE GOMOD GOMODCACHE sh (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE erignore m/_n�� -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha -json GO111MODULE /usr/bin/git GOINSECURE GOMOD GOMODCACHE git rev-�� --show-toplevel GOPROXY /usr/bin/git GOSUMDB GOWORK 64/bin/go git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel node /usr/bin/git prettier --check 64/bin/go git rev-�� --show-toplevel go 86_64/node -e -f 64/bin/go git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha -json GO111MODULE (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git rev-�� --show-toplevel sh /usr/bin/git "prettier" --chegit GOPROXY 64/bin/go git (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v8
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git rev-�� --show-toplevel sh /usr/bin/git "prettier" --chegit GOPROXY 64/bin/go git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha a9bb7eb1db202a6e3840330d313f16d009573a63:actions/setup/js/qmd_index.cjs sh /home/REDACTED/node_modules/.bin/sh ./../.prettieriggit git 64/bin/go sh -c "prettier" --write '**/*.cjs' '**/*.ts' '**/*.json' --ignore-path ../../../.prettierignore node /opt/hostedtoolcache/node/24.14.0/x64/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/n--show-toplevel --write ../../../**/*.jsrev-parse run-script/lib/n--show-toplevel sh (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha a9bb7eb1db202a6e3840330d313f16d009573a63:pkg/workflow/qmd.go node js ./../.prettieriggit scripts/**/*.js 64/bin/go sh -c "prettier" --write '**/*.cjs' '**/*.ts' '**/*.json' --ignore-path ../../../.pret.prettierignore node /usr/local/bin/sh --write ../../../**/*.jsrev-parse 64/bin/go sh (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go clean; fi GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha a9bb7eb1db202a6e3840330d313f16d009573a63:pkg/workflow/qmd.go js /home/REDACTED/work/_temp/uv-python-dir/sh ./../.prettieriggit scripts/**/*.js 64/bin/go sh -c "prettier" --write '**/*.cjs' '**/*.ts' '**/*.json' --ignore-patINVALID,NEW node /home/REDACTED/.dotnet/tools/sh --write ../../../**/*.jsrev-parse 64/bin/go sh (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha heck '**/*.cjs' '**/*.ts' '**/*.json' --ignore-path ../../../.pr**/*.json GO111MODULE tions/setup/node_modules/.bin/sh GOINSECURE GOMOD GOMODCACHE go env .go .go 64/pkg/tool/linux_amd64/compile GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/compile (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha */*.ts' '**/*.json' --ignore-patACCEPT GO111MODULE k/gh-aw/node_modules/.bin/node GOINSECURE GOMOD GOMODCACHE go m/_n�� */*.json' '!../../../pkg/workflow/js/**/*.json' --ignore-path GO111MODULE ache/go/1.25.0/x64/bin/git GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha */*.ts' '**/*.json' --ignore-patACCEPT GO111MODULE 0/x64/bin/sh GOINSECURE GOMOD GOMODCACHE go m/_n�� */*.json' '!../../../pkg/workflow/js/**/*.json' --ignore-path GO111MODULE ndor/bin/bash GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha GOSUMDB GOWORK 64/bin/go GOINSECURE GOMOD GOMODCACHE go env heck '**/*.cjs' GOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go /pre�� on' --ignore-path ../../../.pret.prettierignore GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha GOSUMDB GOWORK 64/bin/go GOINSECURE GOMOD GOMODCACHE go env heck '**/*.cjs' GOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go /pre�� on' --ignore-path ../../../.pret.prettierignore GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)

If you need me to access, download, or install something from one of these locations, you can either:


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

…ions, add per-pattern logging and compile-time validation

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/2f5695a3-96e0-429b-85e7-39402fdf3157
Copilot AI changed the title [WIP] Review why not files are indexed by qmd Fix qmd: multi-pattern checkouts index 0 files due to comma-joined patterns Mar 24, 2026
Copilot AI requested a review from pelikhan March 24, 2026 12:44
@pelikhan pelikhan marked this pull request as ready for review March 24, 2026 12:54
Copilot AI review requested due to automatic review settings March 24, 2026 12:54
@pelikhan pelikhan closed this Mar 24, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes qmd indexing producing 0 indexed files when multiple glob patterns were provided for a single checkout by avoiding comma-joined patterns and adding earlier validation/logging.

Changes:

  • Update qmd indexing action to register one qmd collection per glob pattern (instead of comma-joining patterns).
  • Add best-effort per-pattern match counting and improve “0 files indexed” diagnostics.
  • Add compile-time warnings for empty/comma-containing qmd paths and expand unit test coverage for multi-pattern checkouts.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
pkg/workflow/qmd.go Adds compile-time validation/warnings for common qmd glob pattern mistakes.
actions/setup/js/qmd_index.cjs Splits multi-pattern checkouts into multiple collections and logs per-pattern match counts.
actions/setup/js/qmd_index.test.cjs Adds tests covering multi-pattern naming behavior and dotfile pattern handling; makes an assertion less brittle.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +37 to +38
const files = globSync(pattern, { cwd: basePath });
return Array.isArray(files) ? files.length : null;
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

countGlobMatches() logs "file(s) matched" but the current globSync() call will also return directory matches for patterns like docs/**, so the count can be misleading. Consider calling globSync(pattern, { cwd: basePath, withFileTypes: true }) and counting only entries where dirent.isFile() (or otherwise filtering out directories) so the logged number reflects files.

Suggested change
const files = globSync(pattern, { cwd: basePath });
return Array.isArray(files) ? files.length : null;
const entries = globSync(pattern, { cwd: basePath, withFileTypes: true });
if (!Array.isArray(entries)) return null;
const fileCount = entries.filter((entry) =>
entry && typeof entry.isFile === "function" ? entry.isFile() : true
).length;
return fileCount;

Copilot uses AI. Check for mistakes.
@@ -139,22 +163,36 @@ async function main() {
const rawPath = checkout.path;
const resolvedPath = resolveEnvVars(rawPath);
const patterns = checkout.patterns || ["**/*.md"];
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

const patterns = checkout.patterns || ["**/*.md"]; will not apply the default when checkout.patterns is an empty array (which is truthy). That results in zero collections being registered for that checkout. Consider defaulting when the array is missing or empty (e.g., Array.isArray(checkout.patterns) && checkout.patterns.length > 0 ? checkout.patterns : ["**/*.md"]).

Suggested change
const patterns = checkout.patterns || ["**/*.md"];
const patterns =
Array.isArray(checkout.patterns) && checkout.patterns.length > 0
? checkout.patterns
: ["**/*.md"];

Copilot uses AI. Check for mistakes.
Comment on lines +179 to +195
// For single-pattern checkouts keep the original name; for multi-pattern checkouts
// append "-0", "-1", … to ensure collection names are unique in the qmd store.
const colName = patterns.length === 1 ? checkout.name : `${checkout.name}-${pi}`;

let hitInfo = "";
if (pathExists) {
const count = countGlobMatches(resolvedPath, pattern);
hitInfo = count !== null ? ` (${count} file(s) matched)` : "";
}
core.info(` -> collection "${colName}": pattern="${pattern}"${hitInfo}`);

collections[colName] = {
path: resolvedPath,
pattern,
...(checkout.context ? { context: { "/": checkout.context } } : {}),
};
}
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

When deriving colName for multi-pattern checkouts, the code can silently overwrite an existing entry in collections if another checkout already uses the same name (e.g. a separate checkout named repo-0 collides with repo pattern index 0). Consider detecting collisions before assignment and either failing fast with a clear error or generating a guaranteed-unique name (e.g. include the checkout index in the suffix).

Copilot uses AI. Check for mistakes.
@github-actions github-actions bot deleted the copilot/review-file-indexing-qmd branch April 2, 2026 13:12
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