> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/database-devops/3.0/use-db-devops/structure-git-repository/trunk-based-development.md).

# Trunk-Based Development in Harness Database DevOps

Harness Database DevOps supports **trunk-based development** for managing database schema changes. This strategy relies on a single Git branch (usually `main` or `trunk`) and leverages pipeline logic and contextual controls to manage environment-specific deployments. Trunk-based development simplifies Git workflows, reduces merge conflicts, and accelerates the flow of changes across your CI/CD pipeline.

Trunk-based development in Harness Database DevOps revolves around a single Git branch serving as the source of truth for all schema changes. Here is a quick overview:

1. Developers commit changes to `main`.
2. A Harness pipeline watches this branch for changes.
3. Based on context variables or pipeline logic, the system applies those changes to the appropriate environment.
4. Environments are defined in the pipeline, not in the Git structure.
5. Each environment can include approval gates, rollback logic, and verifications.
6. Visibility, audit logs, and drift detection are automatically managed via the Harness UI.

### Steps to implement trunk-based development in Harness <a href="#steps-to-implement-trunk-based-development-in-harness" id="steps-to-implement-trunk-based-development-in-harness"></a>

Harness supports Liquibase-style contexts to manage changes across environments from a single changelog file. In most cases, context-based filtering is applied at the **database instance level**, with each instance (for example, Dev, QA, Prod) configured with a context label like `dev`, `qa`, or `prod`. When the pipeline executes a `DBSchemaApply` step, Harness applies only the changesets matching the context tied to that specific DB instance.

This allows you to reuse the same changelog file, while ensuring each environment receives only the changes intended for it. Combined with a multi-stage pipeline structure, this forms a **hybrid deployment strategy**: context-based filtering with explicit promotion control.

#### 1. Set up your Git repository <a href="#id-1-set-up-your-git-repository" id="id-1-set-up-your-git-repository"></a>

1. Commit your Liquibase changelogs or SQL scripts to a centralized Git repo.
2. Use clear naming conventions like `changelogs/<YYYY-MM-DD>_<feature>.sql`.

#### 2. Create a database schema in Harness <a href="#id-2-create-a-database-schema-in-harness" id="id-2-create-a-database-schema-in-harness"></a>

1. Navigate to **Database Management > Schemas**
2. Click **New Schema**, connect to your Git repo, and configure your database instance(s).
3. Ensure your changelogs are structured to include environment-specific contexts (e.g., `context: dev, qa, prod`).

#### 3. Connect with database instance <a href="#id-3-connect-with-database-instance" id="id-3-connect-with-database-instance"></a>

Before deploying your database schema, connect a database instance to deploy it to:

1. Under "DB Instances", click “Add New DB Instance".
2. Click New JDBC Connector and Enter Name, JDBC URL & credentials, select the harness delegate, then Save and Finish.
   * **Name** - A name to identify the database instance.
   * **JDBC URL** - The JDBC connection string for your database instance. Go to [Setting up JDBC connectors](/database-devops/3.0/setup-db-devops/jdbc-connection-string/set-up-connectors.md) to configure connection strings.
   * **Username** - The username to connect to the database.
   * **Password** - The password for the database user.
   * **Delegate** - The Harness Delegate that will run the database operations.
3. Add the Contexts (e.g., `dev`, `qa`, `prod`) to the database instance.
4. Click `Add Database Instance`.

#### 4. Create your pipeline <a href="#id-4-create-your-pipeline" id="id-4-create-your-pipeline"></a>

1. Go to **Pipelines** and select **New Pipeline**
2. Add a `DBSchemaApply` step for each environment (e.g. `Dev`, `QA`, `Prod`)
3. In each step
   * Select the appropriate database instance.
   * Ensure the instance is configured with the right `context` label (e.g., dev, qa, prod). Harness will automatically apply only those changesets tagged with this context.

{% tabs %}
{% tab title="Visual Overview" %}
![Multiple Environments](/files/YryPvLWFawo8HFaztnzC)
{% endtab %}

{% tab title="YAML Overview" %}

```yml
pipeline:
  name: multichangeset
  identifier: multichangeset
  projectIdentifier: default_project
  orgIdentifier: default
  tags: {}
  stages:
    - stage:
        name: multi-environment
        identifier: multienvironment
        description: "Trunk Based Pipeline"
        type: Custom
        spec:
          execution:
            steps:
              - stepGroup:
                  name: cross-env
                  identifier: crossenv
                  steps:
                    - step:
                        type: DBSchemaApply
                        name: Development
                        identifier: Development
                        spec:
                          connectorRef: dockerHarness
                          dbSchema: productiondataset
                          dbInstance: Development
                          tag: dev1
                        timeout: 10m
                    - step:
                        type: DBSchemaApply
                        name: Staging
                        identifier: Staging
                        spec:
                          connectorRef: dockerHarness
                          dbSchema: productiondataset
                          dbInstance: Staging
                          tag: stage1
                        timeout: 10m
                        when:
                          stageStatus: All
                    - step:
                        type: DBSchemaApply
                        name: QA
                        identifier: QA
                        spec:
                          connectorRef: dockerHarness
                          dbSchema: productiondataset
                          dbInstance: QA
                          tag: qa1
                        timeout: 10m
                        when:
                          stageStatus: All
                    - step:
                        type: DBSchemaApply
                        name: NA
                        identifier: NA
                        spec:
                          connectorRef: dockerHarness
                          dbSchema: productiondataset
                          dbInstance: ProductionNA
                          tag: pna1
                        timeout: 10m
                        when:
                          stageStatus: All
                  stepGroupInfra:
                    type: KubernetesDirect
                    spec:
                      connectorRef: db
            rollbackSteps: []
          serviceDependencies: []
        tags: {}
    - stage:
        name: APJ
        identifier: APJ
        description: ""
        type: Custom
        spec:
          execution:
            steps:
              - stepGroup:
                  name: APJ Data
                  identifier: APJ_Data
                  steps:
                    - step:
                        type: DBSchemaApply
                        name: APJ
                        identifier: APJ
                        spec:
                          connectorRef: dockerHarness
                          dbSchema: productiondataset
                          dbInstance: ProductionAPJ
                          tag: papj1
                        timeout: 10m
                  stepGroupInfra:
                    type: KubernetesDirect
                    spec:
                      connectorRef: db
            rollbackSteps: []
          serviceDependencies: []
        tags: {}
        when:
          pipelineStatus: All
```

{% endtab %}
{% endtabs %}

\### 5. Configure triggers- Go to your pipeline settings - Add a \*\*Git trigger\*\* that listens to the \`main\` branch - Select “On Push” or “On Pull Request” depending on your workflow Go to \[How to configure Git triggers in Harness]\(<https://app.gitbook.com/s/3F2TpHXhur2QtQnORSM9/use-harness-platform/triggers/tutorial-cd-trigger>) to set up branch-based triggers.

#### 6. Set up approvals and rollbacks <a href="#id-6-set-up-approvals-and-rollbacks" id="id-6-set-up-approvals-and-rollbacks"></a>

* Insert **Approval steps** after lower environments (e.g. promote to QA only after Dev is verified)
* Add **rollback steps** using `DBRollback` or manual SQL if needed

Every time you commit to `main`, Harness will:

* Detect the change
* Trigger your pipeline
* Apply the change to the correct environment
* Log every action for audit, verification, and rollback

### Conclusion <a href="#conclusion" id="conclusion"></a>

Trunk-based development in Harness Database DevOps empowers teams to manage schema changes with agility, consistency, and confidence. By centralizing changes in a single branch and orchestrating environment-specific deployments through pipelines and contexts, this approach simplifies delivery workflows while improving traceability and compliance.

Harness provides out-of-the-box support for Liquibase contexts, multi-environment pipeline steps, approval strategies, and Git-based automation, making it easy to scale database delivery alongside application deployments. Whether you are just getting started or modernizing legacy workflows, trunk-based development offers a streamlined, GitOps-friendly path to continuous database evolution.

### FAQs <a href="#faqs" id="faqs"></a>

#### 1. Can I use trunk-based development if my team currently uses environment-specific branches? <a href="#id-1-can-i-use-trunk-based-development-if-my-team-currently-uses-environment-specific-branches" id="id-1-can-i-use-trunk-based-development-if-my-team-currently-uses-environment-specific-branches"></a>

Yes. While trunk-based development centralizes changes in a single branch (`main`), Harness supports both trunk-based and environment-by-branch workflows. You can start transitioning incrementally by adopting context-based changelogs and defining pipelines that selectively apply changes by environment.

#### 2. What if I have multiple environments? How do I control where changes get applied? <a href="#id-2-what-if-i-have-multiple-environments-how-do-i-control-where-changes-get-applied" id="id-2-what-if-i-have-multiple-environments-how-do-i-control-where-changes-get-applied"></a>

Harness lets you define one pipeline with multiple stages, each targeting a specific environment. You can:

* Use separate `DBSchemaApply` steps for `dev`, `qa`, `prod`, etc.
* Pass context labels or use pipeline conditions to control execution.
* Gate each environment with manual approvals or automated verification steps.

#### 3. Do I need to write separate changelogs for each environment? <a href="#id-3-do-i-need-to-write-separate-changelogs-for-each-environment" id="id-3-do-i-need-to-write-separate-changelogs-for-each-environment"></a>

No. You can use a single changelog file and annotate changesets with Liquibase-style contexts (e.g., `context: dev`, `context: prod`). Harness reads these contexts during deployment and applies only the relevant changes for the target environment.

#### 4. How do I handle rollback in trunk-based development? <a href="#id-4-how-do-i-handle-rollback-in-trunk-based-development" id="id-4-how-do-i-handle-rollback-in-trunk-based-development"></a>

Harness supports rollbacks through the `DBRollback` step. You can:

* Commit rollback scripts to your Git repo alongside the main changelogs.
* Trigger rollback pipelines manually or as part of a failure strategy.
* Use Harness approvals to control rollback execution in higher environments.

Harness supports associating rollback SQL with each changeset by tagging them or linking dedicated rollback files, depending on your changelog strategy. Go to [Automated rollback for database schemas](/database-devops/3.0/use-db-devops/deployment-pipeline-configuration/rollback-and-failure-strategies/rollback-for-database-schemas.md) to configure rollbacks.

### Next steps <a href="#next-steps" id="next-steps"></a>

* Go to [Create a pipeline in Database DevOps](/database-devops/3.0/use-db-devops/deployment-pipeline-configuration/create-a-pipeline.md) to build your first trunk-based database pipeline.
* Go to [Environment-by-branch development](/database-devops/3.0/use-db-devops/structure-git-repository/environment-by-branch.md) to compare the branching strategies and choose the right approach.
* Go to [Automated rollback for database schemas](/database-devops/3.0/use-db-devops/deployment-pipeline-configuration/rollback-and-failure-strategies/rollback-for-database-schemas.md) to configure rollback strategies for failed deployments.
