This is part of our database GitOps series with Bytebase:
This tutorial shows you how to build an database GitOps workflow using GitHub Actions and Bytebase API. You’ll learn to:
  1. Create a streamlined database release workflow where you can:
    • Submit schema migrations through GitHub
    • Automatically run SQL reviews on pull requests
    • Auto-create and deploy Bytebase releases when merging to main
  2. Manually control rollouts by stage
While we use PostgreSQL with GitHub Actions in this guide, you can apply these concepts to other SQL or NoSQL databases with any CI platforms like GitLab CI, Bitbucket Pipelines, or Azure DevOps using the Bytebase API.

Repository

https://github.com/bytebase/example-gitops-github-flow

Prerequisites

Automatic Rollout across environments

Step 1 - Start Bytebase with ngrok

ngrok is a reverse proxy tunnel that provides a public network address to access Bytebase. We use ngrok here for demonstration purposes. ngrok-reverse-proxy
  1. Run Bytebase in Docker with the following command:
    docker run --rm --init \
      --name bytebase \
      --publish 8080:8080 --pull always \
      --volume ~/.bytebase/data:/var/opt/bytebase \
      bytebase/bytebase:3.8.1
    
  2. Once Bytebase is running in Docker, you can access it at localhost:8080.
  3. Log in to the ngrok Dashboard and complete the Getting Started steps to install and configure ngrok. To use a consistent domain, navigate to Universal Gateway > Endpoints to find your assigned domain: <<YOURS>>.ngrok-free.app.
  4. Start ngrok with your domain by running:
    ngrok http --url=<<YOURS>>.ngrok-free.app 8080
    
    You should see output similar to this: terminal-ngrok
  5. You can now access Bytebase at https://<<YOURS>>.ngrok-free.app.
  6. (Optional) To configure SSO (Entra/SCIM), log in to Bytebase, click Settings > General in the left sidebar. Scroll to the Network section, set https://<<YOURS>>.ngrok-free.app as the External URL and click Confirm and update. external-url

Step 2 - Create Service Account

  1. Log in as Workspace Admin, and go to IAM & Admin > Users & Groups. Click + Add User, fill in with api-sample, choose the Workspace DBA role sufficient for this tutorial and click Confirm. service-account-create
  2. Find the newly created service account and Copy Service Key. We will use this token to authenticate the API calls. service-account-key
If you have Enterprise Plan, you can create a Custom Role for the service account which require fewer permissions, and assign this role instead of DBA:
  • plans.create
  • plans.get
  • plans.preview
  • releases.check
  • releases.create
  • releases.get
  • rollouts.create
  • rollouts.get
  • rollouts.list
  • sheets.create
  • sheets.get
  • taskRuns.create
  • planCheckRuns.list
  • planCheckRuns.run

Step 3 - Configure SQL Review in Bytebase

Since you will need to run SQL review on your PRs, you need to configure the SQL review in Bytebase.
  1. Go to CI/CD > SQL Review, click Create SQL Review.
  2. Select the Sample Template and click Next. bb-sql-review-sample
  3. Select Prod environment as the attached resources and click Confirm. Now the SQL review is enabled for the Prod environment. bb-sql-review-prod

Step 4 - Fork the Example Repository and Configure Variables

  1. Fork https://github.com/bytebase/example-gitops-github-flow. There are two workflows in this repository:
    • .github/workflows/sql-review-action.yml: Lint the SQL migration files after the PR is created.
    • .github/workflows/release-action.yml: Create a release in Bytebase after the PR is merged to the main branch.
  2. Go into .github/workflows/release-action.yml and .github/workflows/sql-review-action.yml. In the env section, replace the variable values with your own and commit the changes.
    • BYTEBASE_URL: your ngrok url
    • BYTEBASE_SERVICE_ACCOUNT: api-example@service.bytebase.com (the service account you created in the previous step)
    • BYTEBASE_PROJECT: projects/project-sample (the sample project in the Bytebase)
    • BYTEBASE_TARGETS: instances/test-sample-instance/databases/hr_test,instances/prod-sample-instance/databases/hr_prod (the two default databases in the sample project)
    • FILE_PATTERN: migrations-semver/*.sql (the pattern of the migration files)
  3. You may paste the password of the service account you created in the previous step directly after service-secret or keep the service-secret value as ${{secrets.BYTEBASE_SERVICE_ACCOUNT_SECRET}}. Go to Settings > Secrets and Variables > Actions, click New repository secret, and add BYTEBASE_SERVICE_ACCOUNT_SECRET.
  4. In .github/workflows/sql-review-action.yml, the GITHUB_TOKEN (${{ secrets.GITHUB_TOKEN }}) is included to allow the workflow to comment on pull requests with the Check release results. You don’t need to configure it manually — GitHub provides it automatically during workflow execution.
  5. Go to Actions tab, enable actions workflow run.

Step 5 - Create the migration files

To create migration files to trigger release creation, the files have to match the following pattern:
  • A migration file should start with digits, which is also its version. e.g. 202503131500_create_table_t1_ddl.sql, you can also use semantic versioning like 1.0.0_create_table_t1_ddl.sql.
  • A migration file may end with ‘ddl’ or ‘dml’ to indicate its change type. If it doesn’t end with any of the two, its change type is DDL by default.
  1. Within your forked repository, create the following migration files under migrations directory:
    • 202503131500_create_table_t1_ddl.sql
    CREATE TABLE t1 (
     id SERIAL PRIMARY KEY,
     name TEXT
    );
    
  2. Commit to a new branch and create a pull request, the sql-review-action workflow will be triggered. There will be a warning in the SQL review result. Go into the File changes tab, you can see the warning. gh-sql-review-warning gh-warning-file
  3. According to the SQL review result, you can do some changes to the SQL files and push to the branch. Then you should see the SQL review has passed. There are no warnings in the SQL review result.
     CREATE TABLE t1 (
     id SERIAL PRIMARY KEY,
     name TEXT NOT NULL
    );
    
    gh-sql-review-pass
  4. When the SQL review is passed, you can merge the pull request. The release-action workflow will be triggered to create a release in Bytebase and then roll out automatically. Go to Actions tab, you can see the workflow run and pass. gh-merge-run
  5. Click into the workflow run, you can see the release is created in Bytebase and the rollout is applied to the databases automatically. gh-deploy-automatic
  6. If you click the test stage and expand the different sections, you can follow the links to Bytebase. gh-deploy-to-test-expand bb-rollout

Manual Rollout by Environment

In the previous section, once the PR is merged, we create a release and roll out it to both test and prod environments automatically. You can also manually control the rollout by stage.
  1. In the repo, click Settings > Environments, choose Prod. Here you can add required reviewers for the stage and also set wait timer. gh-config-prod
  2. Create a new branch with this file, and create a pull request. Merge it to the main branch.
    • 202503131530_create_table_t2_ddl.sql
        CREATE TABLE t2 (
          id SERIAL PRIMARY KEY,
          name TEXT NOT NULL
       );
    
  3. Go to the Actions tab, you can see the workflow run and stop at the Prod stage. gh-waiting
  4. Wait for 5 minutes, the workflow will wait for the required reviewers to approve. gh-waiting-finish
  5. Click Approve and deploy button, the workflow will continue to rollout to the Prod stage. gh-approve-deploy gh-deploy gh-deploy-finish

Summary

Now you have learned how to database GitOps with GitHub Action. If you want to trigger a release creation with other git providers (e.g. GitLab, Bitbucket, Azure DevOps), you may customize the workflow file.