Skip to content

feat(deploy): allow excluding files from deploys via .astro/deployignore#2168

Open
tayloramurphy wants to merge 3 commits into
astronomer:mainfrom
tayloramurphy:taylormurphy/ai-857-allow-excluding-files-from-deployments
Open

feat(deploy): allow excluding files from deploys via .astro/deployignore#2168
tayloramurphy wants to merge 3 commits into
astronomer:mainfrom
tayloramurphy:taylormurphy/ai-857-allow-excluding-files-from-deployments

Conversation

@tayloramurphy

@tayloramurphy tayloramurphy commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

Description

Users often have files that belong in version control but not in deploy artifacts - internal docs, local .venv directories, scratch files. Today there is no way to keep them out of the DAG bundle: .dockerignore only affects image builds, and .gitignore is the wrong tool because the files should stay in git. The common workaround is custom CI/CD logic that copies the project and prunes it before deploying.

This adds an optional .astro/deployignore file at the project root. It uses .dockerignore syntax (globs, **, ! negation, comments) and applies to every deploy artifact:

  • DAG bundles - astro deploy, astro deploy --dags
  • dbt bundles - astro dbt deploy (read from the dbt project's own .astro/deployignore)
  • image builds - astro deploy (patterns are appended to .dockerignore for the duration of the build; the file is restored byte-for-byte afterward)
  • client/remote images - astro remote deploy (merged into the build-context filter alongside .dockerignore)

Example

# .astro/deployignore - patterns are relative to the project root
dags/internal_docs/
**/*.md
!dags/README.md
.venv/

Behavior notes

  • Patterns are anchored at the project root for every artifact, so dags/internal_docs/ means the same thing in the image and in the DAG bundle. If the bundled directory is outside the project (e.g. --dags-path ../shared), patterns match relative to the bundle root and the CLI prints a warning.
  • deployignore patterns are evaluated after .dockerignore, so their ! negations take precedence.
  • The CLI-injected monitoring DAG and the always-included build files cannot be excluded. .git/ is now excluded from all bundles (previously the exclusion silently did not apply to DAG bundles).
  • Also fixes a latent bug where a missing source directory caused fileutil.Tar to silently upload an empty bundle — deleting all deployed DAGs — instead of returning an error.

Testing

Unit tests cover pattern parsing, project-root anchoring (including relative --dags-path and outside-root fallback), ! negation, invalid patterns, .dockerignore append/restore (LF/CRLF, created-then-removed), and an end-to-end bundle deploy asserting the uploaded tarball contents.

Adds a first-class ignore mechanism for deploys. Patterns in
.astro/deployignore (.dockerignore syntax, anchored at the project root)
are excluded from all deploy artifacts:

- DAG bundles (astro deploy / astro deploy --dags): a skip predicate is
  threaded through UploadBundle and fileutil.Tar; bundle paths are
  re-anchored at the project root so patterns like dags/docs/ work the
  same across deploy types
- dbt bundles (astro dbt deploy): patterns are read from the dbt
  project's own .astro/deployignore
- image builds (astro deploy): patterns are temporarily appended to
  .dockerignore during the build and restored byte-for-byte, reusing
  the buildImageWithoutDags machinery (now buildImageWithIgnorePatterns)
- client/remote image deploys (astro remote deploy): patterns are merged
  into the build-context copy filter alongside .dockerignore

The file lives in the committable .astro directory so the ignore list
can be version controlled independently of .gitignore.
- buildImageWithIgnorePatterns: append all patterns without deduplication.
  Dedup by exact line broke .dockerignore last-match-wins ordering in two
  ways: a restated pattern (normalized 'docs' vs raw 'docs/') was appended
  after an existing '!' negation and flipped it, and a deduped negation
  lost its re-include. Plain concatenation matches how dockerignoreSkipFunc
  orders the combined pattern list. Also merged the single-caller
  withDockerignoreAdditions wrapper into it and skip touching the file
  when there is nothing to append.
- deployIgnoreSkipFunc: make root and bundle paths absolute before
  filepath.Rel, so a relative --dags-path no longer silently disables
  project-root anchoring; fix the escape check to not misclassify
  directories whose names start with '..'; warn when the bundle lies
  outside the project root and patterns fall back to bundle-relative
  matching.
- deployDags: never let user patterns exclude the CLI-injected
  astronomer_monitoring_dag.py from hybrid deploys.
- fileutil.Tar: consult the skip predicate before symlink/header work so
  excluded irregular files (e.g. sockets in an ignored dbt target/) cannot
  fail the deploy; return the os.Stat error instead of swallowing it
  (previously a missing source dir uploaded an empty bundle, wiping
  deployed DAGs); replace the excludePathPrefixes parameter with the skip
  predicate — it matched post-prepend tar paths, so the '.git/' exclusion
  silently never fired for DAG bundles (prependBaseDir=true).
- UploadBundle: exclude .git via the source-relative skip predicate,
  which now also covers DAG bundles.
- Extract readIgnorePatternsFile shared by .dockerignore and deployignore
  parsing; unexport DeployIgnoreFilePath; attribute ignore-file errors to
  the right file in the client build-context path.
@tayloramurphy tayloramurphy requested a review from a team as a code owner June 11, 2026 20:39
@tayloramurphy tayloramurphy self-assigned this Jun 11, 2026
@coveralls-official

Copy link
Copy Markdown

Coverage Report for CI Build 27626050549

Coverage increased (+0.04%) to 45.13%

Details

  • Coverage increased (+0.04%) from the base build.
  • Patch coverage: 31 uncovered changes across 3 files (108 of 139 lines covered, 77.7%).
  • 1 coverage regression across 1 file.

Uncovered Changes

File Changed Covered %
cloud/deploy/deploy.go 56 38 67.86%
cloud/deploy/deployignore.go 56 45 80.36%
cloud/deploy/bundle.go 15 13 86.67%
Total (6 files) 139 108 77.7%

Coverage Regressions

1 previously-covered line in 1 file lost coverage.

File Lines Losing Coverage Coverage
cloud/deploy/deploy.go 1 81.1%

Coverage Stats

Coverage Status
Relevant Lines: 56450
Covered Lines: 25476
Line Coverage: 45.13%
Coverage Strength: 8.03 hits per line

💛 - Coveralls

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.

1 participant