> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bytebase.com/llms.txt
> Use this file to discover all available pages before exploring further.

# State-based Schema Management with GitHub Actions and AI Review

This is part of our database deployment series with Bytebase:

* [Database GitOps with GitHub Actions](/tutorials/gitops-github-workflow)
* [Database GitOps with Azure DevOps Pipeline](/tutorials/gitops-azure-devops-workflow)
* [Database GitOps with GitLab CI](/tutorials/gitops-gitlab-workflow)
* [Database GitOps with Bitbucket Pipelines](/tutorials/gitops-bitbucket-workflow)
* State-based Database Schema Management with GitHub Actions (this one)

***

Learn to implement state-based database schema management using GitHub Actions and Bytebase. This approach declares the desired schema state and automatically generates necessary migrations, eliminating manual script writing.

**What you'll build:**

* Declarative schema definitions in SQL files
* AI-powered SQL reviews on pull requests
* Auto-deployment of state changes on merge to main

<Info>
  **Important:** State-based workflow currently only supports PostgreSQL.
</Info>

## Repository

[https://github.com/bytebase/example-gitops-github-flow](https://github.com/bytebase/example-gitops-github-flow)

## Prerequisites

* A Bytebase instance (Bytebase Cloud or self-hosted)
* For self-hosted version, you need [Docker](https://www.docker.com/) to run Bytebase.

## State-based vs Migration-based

**Migration-based**: Write incremental scripts that transform the database step-by-step. You track which migrations have run.

**State-based**: Declare the desired schema state. The system automatically generates migrations by comparing current and desired states.

## Setup

### Step 1 - Set up Bytebase

<Tabs>
  <Tab title="Cloud">
    Use [Bytebase Cloud](https://cloud.bytebase.com/) for instant setup without infrastructure management. CI/CD services can connect immediately.

    **Best for:** Quick testing, evaluation, and small teams
  </Tab>

  <Tab title="Self-Hosted">
    Run Bytebase in Docker within your infrastructure:

    ```bash theme={null}
    docker run --rm --init \
      --name bytebase \
      --publish 8080:8080 --pull always \
      --volume ~/.bytebase/data:/var/opt/bytebase \
      bytebase/bytebase:latest
    ```

    **Network Access Options:**

    * **For testing:** Use tools such as [ngrok](https://ngrok.com/) or [VS Code port forwarding](https://code.visualstudio.com/docs/editor/port-forwarding) to temporarily expose your local Bytebase to cloud CI/CD services. After exposing, configure the **External URL** in Bytebase **Settings > General**.

    * **For production:** Use self-hosted CI/CD runners within your private network. Never expose production Bytebase to the internet.

    **Best for:** Organizations with security requirements or existing infrastructure
  </Tab>
</Tabs>

See [Network Architecture guide](/get-started/self-host/network-architecture#2-self-hosted-bytebase-production).

### 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`, and assign the `Workspace Member` and `GitOps Service Agent` roles, which are sufficient for this tutorial, then click **Confirm**.

2. Find the newly created service account and **Copy Service Key**. We will use this token to authenticate the API calls.
   <img src="https://mintcdn.com/dbx/vw8BbfZhlW9y-cr_/content/docs/tutorials/share/service-account-key.webp?fit=max&auto=format&n=vw8BbfZhlW9y-cr_&q=85&s=8817df098a420e992c8c1be0ce2196ac" alt="service-account-key" width="1354" height="218" data-path="content/docs/tutorials/share/service-account-key.webp" />

### Step 3 - Fork the Example Repository and Configure Variables

1. Fork [https://github.com/bytebase/example-gitops-github-flow](https://github.com/bytebase/example-gitops-github-flow). There are two workflows in this repository for this tutorial:

   * `.github/workflows/declarative-release-action.yml`: Deploy release in Bytebase after the PR is merged to the `main` branch.
   * `.github/workflows/declarative-sql-review-action.yml`: [Lint the generated SQL](/sql-review/review-policy/) migration after the PR is created with AI configured.

2. Go into the workflow files and update the `env` section with your own values:

   * **BYTEBASE\_URL**: Your Bytebase instance URL (e.g., `https://bytebase.your-company.com` or your Bytebase Cloud 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 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)
   * **STATE\_FILE\_PATTERN**: `schemas/*.sql` (the pattern for state definition files)

   <Note>
     The workflows run `bytebase-action check` and `bytebase-action rollout`, which verify
     version compatibility before executing. For Bytebase Cloud, use
     `bytebase/bytebase-action:cloud`; for self-hosted Bytebase, use the image tag matching
     your Bytebase server version, for example `bytebase/bytebase-action:3.14.0`.
   </Note>

3. Add the service account password as a secret named **BYTEBASE\_SERVICE\_ACCOUNT\_SECRET** in **Settings > Secrets and Variables > Actions**.

4. The **`GITHUB_TOKEN`** is automatically provided by GitHub during workflow execution.

5. Go to **Actions** tab and enable workflow runs.

### Step 4 - Configure AI Review

1. Go to Bytebase console, click **Settings > General > AI Assistant**.
2. Enable AI and choose your provider (OpenAI, Azure OpenAI, Gemini, or Claude).
3. Enter your API credentials and test the connection.
4. Create a `.bytebase/sql-review.md` file in your repository and write your team's SQL standards in natural language - no special syntax required. Here is an example:

```markdown theme={null}
# .bytebase/sql-review.md
# SQL Review Standards

## 1. Table Naming Convention
- All table names must be in snake_case
```

1. Update `.github/workflows/declarative-sql-review-action.yml` to use the `.bytebase/sql-review.md` file.

```yaml theme={null}
...
run: |
          bytebase-action check --url=${{ env.BYTEBASE_URL }} --project=${{ env.BYTEBASE_PROJECT }} --targets=${{ env.BYTEBASE_TARGETS }} --file-pattern=${{ env.FILE_PATTERN }} --declarative --custom-rules "$(cat .bytebase/sql-review.md)"

```

## Deploy the State Changes

### Step 1 - Export the Schema Definition File

State-based workflows use SQL files that define the complete desired schema.

1. To manage existing schemas, export them from Bytebase console: navigate to your database and click **Export Schema**.

2. Navigate to `Sample Project` > **Database > Databases**. Select `hr_prod` and export the schema:

   ```sql theme={null}
   COMMENT ON SCHEMA "public" IS 'standard public schema';

   CREATE TABLE "public"."audit" (
      "id" serial,
      "operation" text NOT NULL,
      "query" text,
      "user_name" text NOT NULL,
      "changed_at" timestamp(6) with time zone DEFAULT CURRENT_TIMESTAMP,
      CONSTRAINT "audit_pkey" PRIMARY KEY (id)
   );

   ...
   ```

3. Add a new table, save as `schema.sql` in the `schemas/` directory:

   ```sql theme={null}
   CREATE TABLE "public"."fakeTable" (
      "id" serial,
      "name" text NOT NULL
   );
   ```

### Step 2 - Create a Pull Request

1. Create a pull request from your branch. The workflow triggers automatically, posting review results as PR comments.

   <img src="https://mintcdn.com/dbx/Fm1oJt_Mo8NU8roJ/content/docs/tutorials/state-based-schema-management-github/gh-summary.webp?fit=max&auto=format&n=Fm1oJt_Mo8NU8roJ&q=85&s=6d35cff1d300810eb5725937fdc49802" alt="gh-summary" width="1301" height="848" data-path="content/docs/tutorials/state-based-schema-management-github/gh-summary.webp" />

   <img src="https://mintcdn.com/dbx/Fm1oJt_Mo8NU8roJ/content/docs/tutorials/state-based-schema-management-github/gh-ai-review.webp?fit=max&auto=format&n=Fm1oJt_Mo8NU8roJ&q=85&s=a03110bceaf2d4c2cb65c0bb158f139d" alt="gh-ai-review" width="1454" height="564" data-path="content/docs/tutorials/state-based-schema-management-github/gh-ai-review.webp" />

2. Fix the naming convention warning by updating the table name:

   ```sql theme={null}
   CREATE TABLE "public"."fake_table" (
      "id" serial,
      "name" text NOT NULL
   );
   ```

### Step 3 - Merge the Pull Request

1. Push the fix. Once the review passes, merge the PR.

2. Check the **Actions** tab - test deploys automatically, prod awaits approval.

   <img src="https://mintcdn.com/dbx/Fm1oJt_Mo8NU8roJ/content/docs/tutorials/state-based-schema-management-github/gh-test-done.webp?fit=max&auto=format&n=Fm1oJt_Mo8NU8roJ&q=85&s=ff43b4f04951f36f1f92bba892ada869" alt="gh-test-done" width="1408" height="632" data-path="content/docs/tutorials/state-based-schema-management-github/gh-test-done.webp" />

3. In Bytebase console, verify the release was created and applied to `hr_test`.

   <img src="https://mintcdn.com/dbx/Fm1oJt_Mo8NU8roJ/content/docs/tutorials/state-based-schema-management-github/bb-sdl-release.webp?fit=max&auto=format&n=Fm1oJt_Mo8NU8roJ&q=85&s=9d7a9f4e0fb64b7dd29e3b8be9d785ca" alt="bb-sdl-release" width="1089" height="446" data-path="content/docs/tutorials/state-based-schema-management-github/bb-sdl-release.webp" />

   <img src="https://mintcdn.com/dbx/Fm1oJt_Mo8NU8roJ/content/docs/tutorials/state-based-schema-management-github/bb-sdl-rollout-changes.webp?fit=max&auto=format&n=Fm1oJt_Mo8NU8roJ&q=85&s=247794207750c81e86d9fd09323149ef" alt="bb-sdl-rollout-changes" width="1395" height="758" data-path="content/docs/tutorials/state-based-schema-management-github/bb-sdl-rollout-changes.webp" />

   <img src="https://mintcdn.com/dbx/Fm1oJt_Mo8NU8roJ/content/docs/tutorials/state-based-schema-management-github/bb-rollout-test-done.webp?fit=max&auto=format&n=Fm1oJt_Mo8NU8roJ&q=85&s=4d49070d1dc30369465bfdec686bf5c8" alt="bb-rollout-test-done" width="1392" height="780" data-path="content/docs/tutorials/state-based-schema-management-github/bb-rollout-test-done.webp" />

4. Return to GitHub **Actions** and approve the production deployment.

5. Confirm the changes are applied to `hr_prod` in Bytebase.

   <img src="https://mintcdn.com/dbx/Fm1oJt_Mo8NU8roJ/content/docs/tutorials/state-based-schema-management-github/bb-rollout-prod-done.webp?fit=max&auto=format&n=Fm1oJt_Mo8NU8roJ&q=85&s=5883bd0b75e5bc39b38a63e06088e1c2" alt="bb-rollout-prod-done" width="1413" height="633" data-path="content/docs/tutorials/state-based-schema-management-github/bb-rollout-prod-done.webp" />

## Summary

You've successfully implemented state-based schema management with GitHub Actions, enabling declarative database changes with AI-powered reviews and automated deployments.
