# Deploying DAGs with Git and CI — Apache Airflow: Orchestrate Data Pipelines

Source: https://www.geekswithgeeks.com/en/airflow/scale-deploy-ci

> Keep DAGs in Git, test them in CI and sync them to the environment.

## DAGs are code

Treat DAGs like application code: keep them in a **Git** repository, review changes through pull requests, and deploy through a pipeline rather than copying files by hand. Common patterns are **git-sync** (a sidecar that pulls the repository into the DAGs folder), baking DAGs into the container image, or syncing to object storage on managed services. In CI, at minimum run linting and **import tests**: load every DAG file with `DagBag` and fail the build if any file has import errors. Pin Airflow and provider versions, and test upgrades in staging first.

## A DAG import test

Run with `pytest` in CI. It catches syntax errors, bad imports and cycles before the scheduler sees them. The `dags/` folder path is yours.

```python
from airflow.models import DagBag

def test_no_import_errors():
    bag = DagBag(dag_folder="dags/", include_examples=False)
    assert not bag.import_errors, bag.import_errors

def test_dags_have_owner_and_tags():
    bag = DagBag(dag_folder="dags/", include_examples=False)
    for dag_id, dag in bag.dags.items():
        assert dag.tags, f"{dag_id} has no tags"
```

## Test a DAG end to end locally

`airflow dags test <dag_id> <date>` runs a DAG once in a single process without the scheduler, which is a fast way to debug logic before deploying.

**Quiz:** What does a DagBag import test catch?

- [x] Syntax errors, bad imports and cycles in DAG files
- [ ] Network outages
- [ ] Slow queries in the warehouse
- [ ] Wrong business logic automatically

*Answer:* Syntax errors, bad imports and cycles in DAG files. It loads the DAG files the way the scheduler would and reports anything that fails to parse.
