Database changes can be one of the trickiest parts of application development. When multiple developers work on features that require database modifications, they often face challenges like conflicting schema changes, difficulty in testing migrations, and the risk of breaking the production database.
Database branching solves these problems by allowing developers to create isolated database environments for each feature branch, just like they do with code. This guide demonstrates how to implement automated database branching using Neon and GitHub Actions, where each pull request gets its own database branch, complete with the necessary schema changes. You'll build a Next.js Todo application that showcases this workflow, which automates several critical database operations, including:
- Creating a new database branch when a pull request is opened
- Automatically applying schema migrations to the new branch
- Showing schema diffs directly in your pull request
- Syncing schema changes to production when the PR is merged
By the end of this guide, you'll have a system where database changes are as seamless as code changes, with each feature safely isolated in its own environment until it's ready for production. This approach not only makes database changes safer but also gives developers the confidence to experiment with schema changes without fear of breaking the production environment.
Prerequisites
- A Neon account
- A GitHub account
- Node.js installed on your machine
- Basic familiarity with Next.js and TypeScript
Setting Up Your Neon Database
-
Create a new Neon project from the Neon Console. For instructions, see Create a project.
-
Note your connection string from the connection details page.
Your connection string will look similar to this:
Set up the project
-
Create a new Next.js project with TypeScript:
-
Install the required dependencies:
Configure the database schema
-
Create
app/db/schema.ts
: -
Create
drizzle.config.ts
in your project root: -
Add database scripts to your
package.json
: -
Create a
.env
file in your project root: -
Push your code to a Github repository.
Set up the Neon GitHub integration
The Neon GitHub integration connects your Neon project to your application repository and automatically sets a NEON_API_KEY
secret and NEON_PROJECT_ID
variable for you. These variables will support the GitHub Actions workflow we'll create in a later step.
-
In the Neon Console, navigate to the Integrations page in your Neon project.
-
Locate the GitHub card and click Add.
-
On the GitHub drawer, click Install GitHub App.
-
If you have more than one GitHub account, select the account where you want to install the GitHub app.
-
Select the GitHub repository to connect to your Neon project, and click Connect.
The final page of the GitHub integration setup provides a sample GitHub Actions workflow. With this workflow as a example, we'll create a custom GitHub Actions workflow in the next steps.
Create the GitHub Actions workflow
Create .github/workflows/neon_workflow.yaml
file and add the following code:
Note
To set up GitHub Actions correctly:
-
Enable Workflow Permissions: Go to your repository's GitHub Actions settings, navigate to Actions > General, and set Workflow permissions to Read and write permissions.
-
Add Database Connection String: Add a
DATABASE_URL
secret to your repository under Settings > Secrets and variables > Actions, using the connection string for your production database that you noted earlier. While you're here, you should see theNEON_API_KEY
secret andNEON_PROJECT_ID
variable that have already been set by the Neon GitHub integration.
Understanding the workflow
The GitHub Actions workflow automates database branching and schema management for pull requests. Here's a breakdown of the workflow:
Create Branch Job
This job runs when a pull request is opened, reopened, or synchronized:
-
Branch Creation:
- Uses Neon's
create-branch-action
to create a new database branch - Names the branch using the pattern
preview/pr-{number}-{branch_name}
- Inherits the schema and data from the parent branch
- Uses Neon's
-
Migration Handling:
- Installs project dependencies
- Generates migration files using Drizzle
- Applies migrations to the newly created branch
- Uses the branch-specific
DATABASE_URL
for migration operations
-
Schema Diff Generation:
- Uses Neon's
schema-diff-action
- Compares the schema of the new branch with the parent branch
- Automatically posts the differences as a comment on the pull request
- Helps reviewers understand database changes at a glance
- Uses Neon's
Delete Branch Job
This job executes when a pull request is closed (either merged or rejected):
-
Production Migration:
- If the PR is merged, applies migrations to the production database
- Uses the main
DATABASE_URL
stored in repository secrets - Ensures production database stays in sync with merged changes
-
Cleanup:
- Removes the preview branch using Neon's
delete-branch-action
- Removes the preview branch using Neon's
Flow Summary
Here's how the entire process works from start to finish:
- Developer creates a new feature branch and makes schema changes
- When they open a pull request:
- A new database branch is automatically created
- Schema migrations are generated and applied
- A schema diff comment is posted on the PR
- During PR review:
- Reviewers can see exactly what database changes are being made
- The isolated database branch prevents conflicts with other features
- Additional commits trigger automatic migration updates
- When the PR is approved and merged:
- Migrations are automatically applied to the production database
- The preview branch is deleted
- The schema changes are now live in production
- If the PR is closed without merging:
- The preview branch is automatically deleted
- No changes are made to the production database
This automated workflow ensures that:
- Every feature gets its own isolated database environment
- Schema changes are automatically tracked and documented in the pull request
- Migrations are consistently applied across environments
- Production database stays in sync with merged code
- Database resources are efficiently managed
- The risk of manual migration errors is minimized
Test the workflow
To test the workflow, perform the following steps:
-
Create a new feature branch:
-
Modify the schema in
db/schema/todos.ts
: -
Commit and push your changes:
-
Open a pull request on GitHub
The workflow will:
- Create a new database branch for your PR
- Apply the schema migration
- Post a schema diff comment on the PR
- After merging, apply the changes to production
Source code
You can find the complete source code for this example on GitHub.
Resources
Need help?
Join our Discord Server to ask questions or see what others are doing with Neon. Users on paid plans can open a support ticket from the console. For more details, see Getting Support.