For the complete documentation index, see llms.txt. This page is also available as Markdown.

Maintaining Versions of the Database Schema in a Git Repository

Learn how to maintain versions of your database schema in a Git repository using Harness DB DevOps, including best practices for version control and collaboration.

Harness Database DevOps enables you to manage database schema changes as version-controlled .yml changelogs and changesets in a Git repository. This approach ensures consistency, traceability, and collaboration across development, staging, and production environments.

Why version your database schema?

Version-controlling database schema changes offers several advantages:

  1. Auditability: Every schema change is tracked in Git history.

  2. Collaboration: Multiple developers can work on database changes without conflicts.

  3. Rollback support: Historical versions make it easier to revert unintended changes.

  4. CI/CD alignment: Database deployments can follow the same GitOps principles as application code.

How Harness Database DevOps manages schema versions

Harness DB DevOps uses Liquibase-compatible .yml changelogs to define and track changes to your database schema.

  • Changelog file: A .yml file that lists all schema changes in sequence.

  • Changeset: An individual change unit inside the changelog.

  • Contexts: Tags that let you control which changes apply in which environment.

  • Folder structure: Changelogs and changesets can be organized by module, environment, or release.

1. Initialize your changelog in Git

Option A: generate from an existing database

If you do not have your schema tracked in Git yet, use the Harness UI to generate an initial .yml changelog from your live database schema. Go to Build a changelog to use the generate changelog feature. Then commit the generated changelog to your Git repository.

Option B: use existing files

If you already have your changelog files:

  • Organize them following your chosen Harness DB DevOps repository structure (for example, one root changelog.yml including multiple changeset files).

  • Commit your current schema state to Git.

2. Commit and push changes

In trunk-based development, database changes are committed directly to the shared main branch or short-lived branches that are merged the same day.

  1. Create or update the relevant .yml changeset in your changelog.

  2. Use descriptive commit messages:

  1. If your team enforces pull requests, open a PR against main and ensure it is reviewed and merged within hours, not days.

  2. Keep branches small and focused, ideally containing a single logical change.

3. Deploy changes with Harness pipelines

Harness executes your .yml changelogs in sequence during pipeline runs, ensuring every environment stays consistent. The pipeline automatically checks your Git repository for unapplied changesets and executes only the new ones, maintaining idempotency.

How it works:

  • Contexts: Instead of maintaining separate changelog files for each environment, you can annotate changesets with contexts (for example, dev, staging, prod).

  • Selective deployment: During pipeline execution, Harness applies only the changesets whose contexts match the target environment stage in the pipeline.

  • Rollback support: Pipelines can invoke rollback commands automatically if a deployment fails, reverting to the last known good state.

For example,

In this example:

  • When deploying to dev or staging, the changeset is applied.

  • When deploying to prod, it is skipped until explicitly marked for that context.

Keep contexts environment-specific for controlled rollouts, but avoid creating too many context tags to prevent complexity.

Best practices

Apply these practices when managing your database schema in Git.

  • One logical change per changeset: Keep each changeset focused on a single atomic change for easier rollbacks.

  • Consistent naming conventions: Use descriptive IDs and filenames (for example, 2025-08-12-add-users-table.yml).

  • Never edit applied changesets: Create a new changeset for any modification to maintain audit history.

  • Use Liquibase contexts for environment targeting: Tag changesets (dev, staging, prod) to control execution scope.

  • Keep contexts simple: Limit to environment-level tags unless there is a strong reason for finer granularity.

  • Align with your Git strategy: Follow trunk-based or release-branch workflows for schema changes.

  • Commit early and test often: Validate in lower environments before promoting upstream.

Context tagging patterns

Context Tag
Purpose
Example Usage

dev

Development environment only

Early feature testing

staging

Pre-production validation

QA and integration testing

prod

Production environment only

Final approved changes

common

Runs in all environments

Core schema objects

Next steps

Last updated

Was this helpful?