Skip to content

fix: track file-backed tests - #981

Open
mldangelo-oai wants to merge 88 commits into
mainfrom
mdangelo/codex/sec-file-backed-tests
Open

fix: track file-backed tests#981
mldangelo-oai wants to merge 88 commits into
mainfrom
mdangelo/codex/sec-file-backed-tests

Conversation

@mldangelo-oai

@mldangelo-oai mldangelo-oai commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes Codex Security finding csf_f207aa76a9dbf70c64f54808 (occ_164363a1279743d491ec078a).

Promptfoo accepts file-backed and structured test, prompt, provider, target, scenario, filter, and default-test configuration forms. Previously, dependency-only changes could be classified as irrelevant and skip evaluation.

This patch:

  • tracks scalar, array, mapped, object-form, and file-backed tests/prompts/providers/targets/defaultTest, including executable and structured prompts, nested provider maps, inline/external test and scenario hooks, scenarios, Nunjucks filters, HTTP transforms/parsers/file-auth/multipart/TLS/signature assets, generators, workbooks, assertion sets, and transitive refs/vars;
  • aligns path resolution, selector parsing, and target/provider fallback with Promptfoo runtime behavior; handles external configs, scalar-versus-array scenario-test bases, absolute checkout files, globs, deleted/renamed dependencies, cyclic/shared YAML aliases, and nested sheet-qualified tests while rejecting traversal, foreign Windows paths, NUL inputs, and escaping or dangling symlinks;
  • evaluates and accurately reports every action-input prompt for config/dependency/force-run evaluations while safely skipping unrelated changes; deduplicates overlapping and absolute/relative matches, normalizes evaluated paths and no-change logs to safe workspace-relative values, reports config-defined-prompt mode accurately in PR comments and workflow summaries, validates only the prompts actually evaluated, and blocks CR/LF or out-of-workspace prompt paths before execution;
  • linearly preflights numeric brace ranges and enforces the documented 1,024-expansion action/config limit with a separate matcher overflow sentinel; aligns glob-backed config/test/provider paths with Promptfoo's no-escape semantics before preflight and containment (including odd/even backslash, character-class-wrapped, zero-padded, unsafe-integer, and zero-step cases), keeps Action-input POSIX escapes separate, and preserves literal backslashes for direct HTTP TLS/signature/multipart paths;
  • bounds brace/glob/YAML and structured-file inspection (10 MiB pre-read cap), compiles one bounded POSIX dependency matcher per pattern with Promptfoo-compatible semantics, replaces the quadratic provider-selector lookahead with linear parsing, and centralizes conservative fallbacks so external-config env templates, invalid/oversized/throwing globs, executable providers, dynamic refs, and unreadable/malformed/oversized structured inputs watch both trusted roots without widening file reads;
  • bounds adversarial sheet references, sanitizes attacker-controlled warnings/debug/annotations, moves runtime csv-parse and minimatch to dependencies, and commits the exact trusted Linux-generated action bundle.

Verification

  • exercised real filesystem fixtures for external configs, direct/glob/symlink/dangling paths, selectors, nested refs/vars/assert sets, mapped providers/targets, inline and external runtime hooks, scalar and array scenario-test resolution, shared YAML aliases, CSV/JSONL (including malformed), generators, scenarios, Nunjucks filters, HTTP hooks/auth/multipart/security assets, traversal, structured/executable prompts, and oversized files;
  • verified the compiled action rejects a symlinked action-input prompt, a ../secrets/*.py prompt glob, and a 1,025-item numeric prompt range with a constant pre-exec error; compiled external-config smokes return both trusted watch roots for unresolved env templates/malformed JSONL, reject odd-backslash 4,096-item provider/test ranges in 5 ms, and reject the brace-traversal arm before enumeration;
  • provider-parser adversarial fixture completes in linear time; shared assertion-alias DAG traversal and spreadsheet suffix handling remain bounded; a real 1,024-alternative dependency matcher over 3,000 changed files completes in 54 ms and compiles once;
  • npm run build && npm run biome:check && npm test passes: 9 files, 563 tests, 100% statements/branches/functions/lines; source diff checks and trusted-artifact comparisons pass;
  • trusted Linux bundle from run 29444547813 embeds the exact source hashes for src/main.ts, src/utils/config.ts, and src/utils/glob.ts, runtime csv-parse, and the locked YAML parser/license. Final head: bc3adb61ace96524701e24d2d2c58548fc98f7c4.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 55f622e1ed

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/utils/config.ts Outdated

Copy link
Copy Markdown
Contributor Author

@codex review

Please review exact head 55f622e1edd1c0a5957c4aeb001137f072d38db5, focusing on whether every Promptfoo-supported local file-backed tests form reaches the dependency gate, remote sources remain excluded, path containment cannot be bypassed by globs or qualifiers, inline test dependencies are preserved, and the committed dist/ bundle matches source.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Fixes an action dependency-tracking gap where Promptfoo test suites provided as file-backed paths (scalar/array/object { path } forms) weren’t being included in the action’s “changed files” inventory—causing test-file-only PRs to be treated as irrelevant and skipped.

Changes:

  • Expanded PromptfooConfig.tests typing and dependency extraction to support scalar, array, and { path } test sources (including file://, bare paths, globs, function-qualified generators, and workbook sheet references).
  • Added regression tests covering the newly supported file-backed test forms and safety controls.
  • Regenerated the bundled dist/index.js.

Reviewed changes

Copilot reviewed 2 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/utils/config.ts Adds normalization/parsing of file-backed test sources and tracks them as dependencies.
tests/utils/config.test.ts Adds regression tests for scalar/array/object file-backed test suites and safety behavior.
dist/index.js Updates the bundled action output to reflect the source changes.
Comments suppressed due to low confidence (1)

tests/utils/config.test.ts:6

  • This test file imports @actions/core and asserts core.warning call counts, but it never calls vi.mock('@actions/core'). As a result, core.warning will be the real function (not a mock/spyon), and toHaveBeenCalledTimes will fail or the test will emit real warnings. Add an explicit mock so Vitest uses __mocks__/@actions/core.ts.
import * as core from '@actions/core';
import * as fs from 'fs';
import * as glob from 'glob';
import type { Mock } from 'vitest';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { extractFileDependencies } from '../../src/utils/config';

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

Comment thread src/utils/config.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 55f622e1ed

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/utils/config.ts Outdated
mldangelo and others added 7 commits July 9, 2026 00:25
…le-backed-tests

# Conflicts:
#	dist/index.js.map
Add comments explaining the remote-source skip, sheet-reference stripping,
and the drive-letter-safe function-qualifier guard in processTestFile.
Regenerate dist after merging main.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copy link
Copy Markdown
Contributor Author

@codex review

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 6 changed files in this pull request and generated 2 comments.

Comment thread src/utils/config.ts Outdated
Comment thread src/utils/config.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 85fc1b2fcd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/utils/config.ts
Comment thread src/utils/config.ts Outdated
Comment thread src/utils/config.ts
Comment thread dist/index.js Fixed
Comment thread dist/index.js Fixed

Copy link
Copy Markdown
Contributor Author

@codex review

Please review exact head 434fc338fcad50924af7c4873a256fee5921e4ed, focusing on transitive file-dependency detection, path containment, CSV assertion parsing, external per-test provider resolution, and Nunjucks-templated file references.

@mldangelo

Copy link
Copy Markdown
Member

Review (current head b0056ce) — no code change pushed

I re-reviewed this against the current head and did not push a change, because I couldn't find a simplification that's both safe and clearly beneficial — the file is clean of the duplication patterns I fixed in the sibling PRs (no duplicated glob-options constant, no repeated dependency-root sentinel).

Assessment: solid

I traced the transitive test-dependency resolver closely and it's well-built:

  • inspectedTestFiles is a correct cycle guard, keyed on file + refBaseDir + testBaseDir + fragment, so $ref chains and self-references terminate.
  • Containment is checked with realpathSync + isPathInside, so symlinked test files can't escape the workspace.
  • Executable/binary test files (xlsx/py/js) correctly fall back to a workspace marker instead of being loaded and executed.

No correctness bug found.

Top recommendation: consolidate the family

This is one of seven independent branches (#974/#977/#979/#981/#982/#983/#987) that each rewrite the same extractFileDependencies, and the largest of them. They mutually conflict — only one merges cleanly and the rest need manual reconciliation — and they don't agree on error policy (this one is fail-open return [], #974 throws, #979 returns ['./']). Merging them into one stacked, reviewable change with a single agreed error policy (I'd keep #979's conservative-watch) and shared helpers would remove a large amount of duplicated surface across the seven and is worth far more than any per-PR nit.

My original inline comments predate a branch restack and may show as "outdated".

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 24, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-08-24T08:39:24.473653Z 57ecd44 New commits
🔒 Security Review Completed 2026-08-24T08:39:46.455908Z 57ecd44 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 16b2cf7993

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/utils/config.ts Outdated
filePath = filePath.slice(0, functionIndex);
}

processFilePath(filePath, 'test file dependency');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve absolute file-backed test paths

When tests uses an absolute local URL such as file:///repo/cases.yaml, this passes /repo/cases.yaml to processFilePath, but resolveConfigDependency constructs it with path.join(configDir, filePath), which rebases the absolute path to something like /repo/evals/repo/cases.yaml. The action therefore watches a nonexistent path and can skip an evaluation when the actual absolute test file changes; resolve absolute test paths without prepending configDir.

Useful? React with 👍 / 👎.

Comment thread src/utils/config.ts Outdated
Comment on lines +153 to +155
const sheetIndex = filePath.indexOf('#');
if (sheetIndex !== -1) {
filePath = filePath.slice(0, sheetIndex);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Restrict sheet suffix stripping to Excel basenames

When a valid local test path contains # outside an Excel sheet qualifier, such as file://tests/cases#prod.yaml or file://tests#prod/cases.xlsx#Safety, this truncates the path at the first hash and records the wrong dependency. Promptfoo loads the literal hash-containing file or directory, so changing it can be classified as irrelevant; only strip a sheet suffix from the basename when the portion before it is an Excel filename.

Useful? React with 👍 / 👎.

Comment thread src/utils/config.ts Outdated
Comment on lines +158 to +160
const functionIndex = filePath.lastIndexOf(':');
if (functionIndex > 1) {
filePath = filePath.slice(0, functionIndex);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Strip function selectors only from generator scripts

On POSIX, a non-generator test filename may legally contain a colon, for example tests: file://tests/cases:prod.yaml, but this unconditionally treats the last colon as a function selector and watches tests/cases instead. Promptfoo uses the actual cases:prod.yaml file, so edits to it can still be skipped; limit selector stripping to supported script-generator extensions.

Useful? React with 👍 / 👎.

Comment thread src/utils/config.ts Outdated
Comment on lines +258 to +260
if (typeof test === 'string') {
processTestFile(test);
continue;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Inspect dependencies inside file-backed tests

When a directly referenced YAML or JSON test file contains its own local dependencies, for example tests/cases.yaml with vars.context: file://data/context.txt or a file-backed assertion, this call records only tests/cases.yaml and never reads the test file. A PR that changes only the nested data or validator can therefore be skipped even though Promptfoo loads it while evaluating; inspect supported structured test files and add their nested file references to the dependency set.

Useful? React with 👍 / 👎.

Comment thread src/utils/config.ts Outdated
Comment on lines +258 to +260
if (typeof test === 'string') {
processTestFile(test);
continue;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Evaluate all prompts when a test dependency changes

When a PR changes both one prompt file and a newly tracked file-backed test, this makes dependencyChanged true but leaves promptFiles containing the changed prompt; src/main.ts still appends --prompts whenever that list is nonempty, so Promptfoo evaluates only that prompt. Because the changed test applies to every configured prompt, results for unchanged prompt files are silently omitted; dependency changes should suppress the changed-prompt override and run the full config.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 25e1ecca4c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/main.ts Outdated
);
return repositoryFile !== configRepositoryPath;
});
allPromptFiles.push(...matchingPrompts);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Deduplicate prompt matches across overlapping globs

When multiple configured glob patterns match the same prompt, such as prompts/*.txt and prompts/shared.*, this appends that path once per pattern. A config or shared-test change then copies the duplicated list into promptFiles, so Promptfoo receives duplicate --prompts arguments and the PR comment or workflow summary repeats the file. Accumulate matches in a Set before constructing the evaluation list.

Useful? React with 👍 / 👎.

Comment thread src/main.ts Outdated
Comment on lines +521 to +523
if (configChanged || dependencyChanged) {
promptFiles.splice(0, promptFiles.length, ...allPromptFiles);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Do not report every evaluated prompt as modified

When only the config or a shared test dependency changes, this replaces promptFiles with every matched prompt even though none of those prompt files changed. The downstream PR comment uses this array in LLM prompt was modified in these files, so dependency-only PRs falsely claim that every prompt was modified; keep changed and evaluated prompt lists separate or change the reporting language.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 264c2cc004

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/main.ts Outdated
}

if (configChanged || dependencyChanged) {
promptFiles.splice(0, promptFiles.length, ...allPromptFiles);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Reject prompt matches outside the workspace

When the prompts input contains a traversal or absolute glob such as ../private/*.txt, allPromptFiles can contain files outside the checkout, and a config or dependency change now copies every match into promptFiles for Promptfoo's --prompts argument. This can cause local runner files to be read and submitted to the configured model provider; validate both the lexical and real resolved paths against workspaceRoot before evaluating these matches.

AGENTS.md reference: AGENTS.md:L56-L60

Useful? React with 👍 / 👎.

Comment thread src/utils/config.ts
Comment on lines 257 to +258
if (config.tests) {
for (const test of config.tests) {
const tests = Array.isArray(config.tests) ? config.tests : [config.tests];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Track file-backed tests nested in scenarios

When a Promptfoo config places a file-backed test under scenarios[].tests, such as scenarios: [{ tests: 'scenarios/cases.yaml' }], this block only processes top-level config.tests and records no dependency for the scenario test source. A PR that changes only scenarios/cases.yaml can therefore be classified as irrelevant and skip the evaluation even though Promptfoo loads that file.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Something went wrong. Try again later by commenting “@codex review”.

Unknown error
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fb46f79e64

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/main.ts Outdated
Comment on lines +470 to +475
const matchingPrompts = matches.filter((file) => {
const absolutePromptPath = path.resolve(workingDirectory, file);
if (
!isPathInside(workspaceRoot, absolutePromptPath) ||
!isPathInside(realWorkspaceRoot, fs.realpathSync(absolutePromptPath))
) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid validating prompts that will be skipped

When changed-file information contains no matching prompt, config, or dependency change, this still resolves and validates every glob match before reaching the skip check. Consequently, an unchanged prompt symlink that resolves outside the checkout fails every unrelated PR with INVALID_CONFIGURATION, even though that prompt would not be evaluated; select the evaluation set first and apply containment checks only to that set.

AGENTS.md reference: AGENTS.md:L43-L45

Useful? React with 👍 / 👎.

Comment thread src/utils/config.ts Outdated
Comment on lines +284 to +285
for (const scenario of config.scenarios ?? []) {
extractTests(scenario.tests);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Handle scalar scenario file entries

When a supported file-backed scenario is configured as scenarios: [scenarios/shared.yaml], each scenario here is a string, so scenario.tests is undefined and the scenario file is never recorded as a dependency. A PR changing only that shared scenario can therefore be classified as irrelevant and skipped; process string scenario entries as files before inspecting object-form scenarios.

Useful? React with 👍 / 👎.

Comment thread src/main.ts Outdated
Comment on lines +842 to +844
configChanged || dependencyChanged
? 'LLM prompts were evaluated'
: 'LLM prompt was modified';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Report config-defined prompts when overrides are disabled

When use-config-prompts is true and a config or dependency changes, promptFiles contains matches from the action's prompts globs, but command construction intentionally omits those paths and evaluates the config-defined prompts instead. This branch nevertheless reports the glob-matched files as evaluated, so configurations whose action globs differ from their config prompts produce misleading PR comments and workflow summaries; describe config-defined prompts instead in this mode.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c83e4ec2e8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/utils/config.ts Outdated
if (typeof scenario === 'string') {
processTestFile(scenario);
} else {
extractTests(scenario.tests);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Track dependencies referenced by scenario configs

When a scenario defines shared settings under scenarios[].config, for example a scenario config whose vars.context is file://data/context.json, this loop inspects only scenario.tests and never visits the scenario config. Promptfoo applies those settings while evaluating the scenario, so a PR that changes only data/context.json leaves dependencyChanged false and can incorrectly skip the evaluation; extract file references from scenario.config as well.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c83e4ec2e8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/utils/config.ts Outdated
filePath = filePath.slice(0, functionIndex);
}

processFilePath(filePath, 'test file dependency');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Validate resolved test-glob matches

When a newly supported test source is a glob beneath a repository symlink, such as tests: file://tests/external/*.yaml where tests/external resolves outside the checkout, this route accepts each match based only on its lexical path. The action can therefore enumerate and record host files outside the workspace despite the containment check; resolve each match with realpath and reject unverifiable or escaping targets before adding it.

AGENTS.md reference: AGENTS.md:L56-L60

Useful? React with 👍 / 👎.

Comment thread src/main.ts Outdated
Comment on lines +846 to +848
const reportedFiles = useConfigPrompts
? configPath
: promptFiles.join(', ');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Bound the evaluated-file list in PR comments

When a config or shared dependency changes and the action prompt globs match thousands of files, promptFiles now contains every match and this join copies the entire list into the issue-comment body. Once the filenames push the body beyond GitHub's comment-size limit, createComment rejects the request after the evaluation has completed, so the action fails without posting results; truncate or summarize the evaluated-file list before constructing the comment.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1d3c44a9b4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/utils/config.ts Outdated
let physicalBasePath: string;
try {
physicalDependencyRoot = fs.realpathSync(dependencyRoot);
physicalBasePath = fs.realpathSync(absoluteBasePath);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve deleted test-glob roots

When a PR deletes the entire static directory matched by a file-backed test glob such as tests: file://cases/*.yaml, cases/ no longer exists in the checkout, so this realpathSync throws and the extractor returns without recording either the glob or its root. The changed path cases/example.yaml then matches no dependency, allowing the action to skip the evaluation even though the configured test set changed; retain a lexically contained watch pattern/root when a nonexistent glob base cannot be physically resolved.

AGENTS.md reference: AGENTS.md:L56-L60

Useful? React with 👍 / 👎.

Comment thread src/utils/config.ts Outdated
Comment on lines +313 to +315
if (typeof test === 'string') {
processTestFile(test);
continue;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Track both sides of test-file renames

When a configured file-backed test is renamed without updating the config, this records only the now-missing source path, while the inspected PR flow keeps only GitHub's destination filename and push/manual comparisons use git diff --name-only, which likewise reports only the destination for detected renames. For example, renaming tests/cases.yaml to archive/cases.yaml leaves the dependency as tests/cases.yaml, so the action can classify the broken test configuration as irrelevant and skip the evaluation; include previous_filename for PRs and both paths from name-status rename records for git comparisons.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 57ecd44a73

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/utils/config.ts
Comment on lines +227 to +228
config.defaultTest.startsWith('file://') &&
!/\{[{%#]/.test(config.defaultTest)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Conservatively invalidate templated default-test paths

When defaultTest uses an environment template such as file://{{ env.DEFAULT_TEST_PATH }}, this condition deliberately records no dependency. If the variable resolves to defaults/test.yaml and a PR changes only that file, dependencyChanged remains false and src/main.ts can skip the evaluation even though Promptfoo loads the modified default test; record a conservative workspace dependency or the resolved path instead of dropping templated sources.

Useful? React with 👍 / 👎.

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