Skip to content

air: reject code_source include_paths entries that match no files - #7643

Draft
dimk0 wants to merge 5 commits into
mainfrom
cnxt-2649-include-paths-unmatched
Draft

dimk0 wants to merge 5 commits into
mainfrom
cnxt-2649-include-paths-unmatched

Conversation

@dimk0

@dimk0 dimk0 commented Nov 15, 2026 •

Copy link
Copy Markdown
Member

Changes

  • air run: for a working-tree snapshot (no code_source.git), reject code_source.include_paths entries that select no files, and name them, before packaging. Commit-pinned snapshots already reject missing include paths. Glob patterns, pathspec magic (:!x, :(exclude)x, :/x) and backslash escapes are left to git, which matches them as patterns.
  • Drop listing entries the tarball writer does not pack (directories such as a nested git repository or a submodule), so the empty and unmatched checks see what is uploaded.
  • Reject listed files outside root_path, which pathspec magic such as :(top)x can select.
  • The all-entries-empty error from air: refuse to upload an empty code_source snapshot #7570 still fires first. Its messages now say that nested git repositories and submodules add no files, and both errors suggest git check-ignore -v only when root_path is in a git repository.

Why

git ls-files ignores a pathspec that matches nothing, so a mistyped or stale entry was dropped from the snapshot without a warning, --dry-run passed, and the run failed on the node after compute was provisioned. A realistic case is the AI Runtime cookbook's getting-started Ray recipes, which list the shared bootstrap and the recipe directory in include_paths: include_paths: [ray_bootstrap.sh, my_job] for a my-job directory uploaded only ray_bootstrap.sh.

Replaces #7639, opened from a fork where CI could not get its OIDC token.

Tests

  • TestSnapshotFiles_IncludePathMatching accepts ., ./, a file, ? and [...] globs, and :!/:(exclude) exclusions with the expected files, and rejects [data_v2, data] naming only data.
  • TestSnapshotFiles_NestedRepoSelectsNoFiles and TestSnapshotFiles_RejectsPathspecOutsideRoot cover nested repositories and the containment check; TestSnapshotFiles_AcceptsBackslashEscapedIncludePath (not on Windows) and TestSnapshotFiles_OmitsIgnoreRuleHintOutsideGit cover backslash escapes and the hint. The earlier rejection and accepted-forms tests still pass.
  • Each behavior (the . shortcut, the path-component boundary, the glob, magic and backslash skips, the nested-repository skip, containment) fails its test when removed.
  • go test ./cmd/air/... and go test ./acceptance -run TestAccept/air pass, and golangci-lint run ./cmd/air/... reports no issues. Locally TestLogsCommandRepeatsRunLinkAfterStreaming fails on main too when DATABRICKS_WORKSPACE_ID is exported; it passes with the variable unset.
  • Not covered here: for a non-git root_path, ls-files runs without -C, so the listing depends on the working directory. That predates this change and is left for a follow-up.

This pull request and its description were written by Isaac.

dimk0 and others added 4 commits November 14, 2026 23:42
For a working-tree snapshot, git ls-files silently ignores a pathspec that
matches nothing, so a mistyped or stale include_paths entry was left out of
the snapshot. The run then failed on the node after compute was provisioned.
Commit-pinned snapshots already reject missing include_paths; working-tree
snapshots now do the same before packaging.

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
- Skip the unmatched-entry check for pathspec magic (":!x", ":(exclude)x",
  ":/x") and backslash escapes, as for globs. These are patterns, and an
  exclusion can never select a file, so the check rejected valid configs.
- Drop entries that the tarball writer does not pack (directories such as a
  nested git repository or a submodule) from the listing, so the empty and
  unmatched checks see what is uploaded.
- Reject listed files outside root_path, which pathspec magic such as
  ":(top)x" can select.
- Reword the error: it lists only the unmatched entries, and empty
  directories, nested repositories and submodules add no files.
- Cover the "." shortcut, the path-component boundary, globs, exclusions,
  nested repositories and the containment check in tests.

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
@github-actions github-actions Bot added the AIR Databricks AI Runtime CLI label Nov 15, 2026
@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Nov 15, 2026 •

Copy link
Copy Markdown
Collaborator

✅ Integration test report

Commit: c9dec55

Run: 43689981789

Env 💚​RECOVERED ✅​pass 🙈​skip Time
💚​ aws linux-2core-8gb 1 270 15 3:42
💚​ aws-windows-latest-4core-16gb 1 272 13 3:24
💚​ azure linux-2core-8gb 1 269 15 3:33
💚​ azure-windows-latest-4core-16gb 1 271 13 3:19
💚​ gcp linux-2core-8gb 1 270 15 3:30
💚​ gcp-windows-latest-4core-16gb 1 272 13 3:31
Test Name aws linux-2core-8gb aws-windows-latest-4core-16gb azure linux-2core-8gb azure-windows-latest-4core-16gb gcp linux-2core-8gb gcp-windows-latest-4core-16gb
💚​ TestAccept 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
Top 3 slowest tests (at least 2 minutes):
duration env testname
3:27 gcp-windows-latest-4core-16gb TestAccept
3:19 aws-windows-latest-4core-16gb TestAccept
3:14 azure-windows-latest-4core-16gb TestAccept

… repositories

- Only suggest `git check-ignore -v` when root_path is in a git repository;
  outside one the command fails.
- The empty-snapshot errors now say that nested git repositories and
  submodules add no files, since such entries no longer count as files.
- Test a backslash-escaped entry, which git reads as a pattern, and the hint
  outside git.

Co-authored-by: Isaac <no-reply@databricks.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AIR Databricks AI Runtime CLI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants