|
| 1 | +--- |
| 2 | +title: Database Release CI/CD with GitHub Action |
| 3 | +author: Ningjing |
| 4 | +updated_at: 2025/02/17 18:00 |
| 5 | +tags: Tutorial |
| 6 | +integrations: API, GitHub |
| 7 | +level: Advanced |
| 8 | +estimated_time: '40 mins' |
| 9 | +description: 'Learn how to automate database release CI/CD using GitHub Actions and Bytebase API.' |
| 10 | +--- |
| 11 | + |
| 12 | +This tutorial demonstrates how to automate database release CI/CD using GitHub Actions and Bytebase API. You'll learn how to: |
| 13 | + |
| 14 | +- Set up a workflow where developers can submit SQL migration files to GitHub |
| 15 | +- Implement automated SQL review checks for pull requests |
| 16 | +- Automatically create releases in Bytebase after merging to the `main` branch and roll out to the database |
| 17 | + |
| 18 | +While this guide uses GitHub Actions, the same principles can be applied to other CI/CD platforms like GitLab CI, Bitbucket Pipelines, or Azure DevOps using the Bytebase API. |
| 19 | + |
| 20 | +<HintBlock type="info"> |
| 21 | + |
| 22 | +This tutorial code repository is at [https://github.com/bytebase/bytebase-release-cicd-workflows-example](https://github.com/bytebase/bytebase-release-cicd-workflows-example) |
| 23 | + |
| 24 | +</HintBlock> |
| 25 | + |
| 26 | +## Prerequisites |
| 27 | + |
| 28 | +- [Docker](https://www.docker.com/) installed |
| 29 | +- An [ngrok](https://ngrok.com/) account |
| 30 | + |
| 31 | +## Step 1 - Start Bytebase with ngrok |
| 32 | + |
| 33 | +<IncludeBlock url="/docs/get-started/install/vcs-with-ngrok"></IncludeBlock> |
| 34 | + |
| 35 | +## Step 2 - Create Service Account |
| 36 | + |
| 37 | +<IncludeBlock url="/docs/share/tutorials/create-service-account"></IncludeBlock> |
| 38 | + |
| 39 | +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: |
| 40 | + |
| 41 | + - plans.create |
| 42 | + - plans.get |
| 43 | + - plans.preview |
| 44 | + - releases.check |
| 45 | + - releases.create |
| 46 | + - releases.get |
| 47 | + - rollouts.create |
| 48 | + - rollouts.get |
| 49 | + - rollouts.list |
| 50 | + - sheets.create |
| 51 | + - sheets.get |
| 52 | + - taskRuns.create |
| 53 | + - planCheckRuns.list |
| 54 | + - planCheckRuns.run |
| 55 | + |
| 56 | +## Step 3 - Fork the Example Repository and Configure Variables |
| 57 | + |
| 58 | +1. Go to the [bytebase-release-cicd-workflows-example](https://github.com/bytebase/bytebase-release-cicd-workflows-example) repository and fork it. There are two workflows in this repository: |
| 59 | + |
| 60 | + - `.github/workflows/bytebase-check-release.yml`: Check the release SQL syntax when there's a pull request. |
| 61 | + - `.github/workflows/bytebase-release-cicd.yml`: Create a release in Bytebase when there's a merge to the `main` branch. |
| 62 | + |
| 63 | +1. Go into `.github/workflows/bytebase-release-cicd.yml` and `.github/workflows/bytebase-check-release.yml`. In the `env` section, replace the variable values with your own and commit the changes. |
| 64 | + |
| 65 | + - **BYTEBASE_URL**: your ngrok url |
| 66 | + - **BYTEBASE_PROJECT**: `projects/project-sample` (the sample project in the Bytebase) |
| 67 | + - **BYTEBASE_SERVICE_ACCOUNT**: `api-example@service.bytebase.com` (the service account you created in the previous step) |
| 68 | + - **BYTEBASE_TARGETS**: `instances/test-sample-instance/databases/hr_test,instances/prod-sample-instance/databases/hr_prod` (the two default databases in the sample project) |
| 69 | + |
| 70 | +1. You may paste the password of the service account you created in the previous step directly after **service-secret** or replace **service-secret** value as `${{secrets.BYTEBASE_PASSWORD}}`. Go to **Settings > Secrets and Variables > Actions**, click **New repository secret**, and add **BYTEBASE_PASSWORD**. |
| 71 | + |
| 72 | +1. Go to **Actions** tab, enable actions workflow run. |
| 73 | + |
| 74 | +## Step 4 - Create the Release and Roll out |
| 75 | + |
| 76 | +To create migration files to trigger release creation, the files have to match the following pattern: |
| 77 | + - A migration file should start with digits, which is also its version. e.g. `20250101001_create_table_ddl.sql`. |
| 78 | + - 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. |
| 79 | + |
| 80 | +1. Within your forked repository, create the following migration files under `migrations` directory: |
| 81 | + |
| 82 | + - 20250101001_create_table_t1_ddl.sql |
| 83 | + |
| 84 | + ```sql |
| 85 | + CREATE TABLE t1 ( |
| 86 | + id INT |
| 87 | + ); |
| 88 | + ``` |
| 89 | + |
| 90 | + - 20250101002_drop_t2_create_table_t2_ddl.sql |
| 91 | + |
| 92 | + ```sql |
| 93 | + DROP TABLE t1; |
| 94 | + CREATE TABLE t2 ( |
| 95 | + id INT |
| 96 | + ); |
| 97 | + ``` |
| 98 | + |
| 99 | +1. Commit to a new branch and create a pull request, the `bytebase-check-release` workflow will be triggered. |
| 100 | + |
| 101 | +  |
| 102 | + |
| 103 | + You got this SQL review is because by default, there is a SQL review configured on `Prod` environment in Bytebase. |
| 104 | + |
| 105 | +  |
| 106 | + |
| 107 | +1. 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. |
| 108 | + |
| 109 | + ```sql |
| 110 | + CREATE TABLE t1(id INT PRIMARY KEY NOT NULL); |
| 111 | + ``` |
| 112 | + |
| 113 | + ```sql |
| 114 | + ALTER TABLE t1 RENAME TO "t1_del"; |
| 115 | +
|
| 116 | + DROP TABLE "t1_del"; |
| 117 | +
|
| 118 | + CREATE TABLE t2(id INT PRIMARY KEY NOT NULL); |
| 119 | + ``` |
| 120 | + |
| 121 | +  |
| 122 | + |
| 123 | +1. When the SQL review is passed, you can merge the pull request. The `bytebase-release-cicd` 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. |
| 124 | + |
| 125 | +  |
| 126 | + |
| 127 | +1. If you click the link in the **Create release** section, you can see the release is created in Bytebase. |
| 128 | + |
| 129 | +  |
| 130 | + |
| 131 | +1. If you click the link in the **Rollout** section, you can see the rollout is applied to the databases. |
| 132 | + |
| 133 | +  |
| 134 | + |
| 135 | +## Breakdown of the GitHub Action Workflow |
| 136 | + |
| 137 | +1. Check out your repo and log in to Bytebase to gain the access token. |
| 138 | + |
| 139 | + ```yaml |
| 140 | + - name: Checkout |
| 141 | + uses: actions/checkout@v4 |
| 142 | + - name: Login to Bytebase |
| 143 | + id: login |
| 144 | + uses: bytebase/login-action@main |
| 145 | + with: |
| 146 | + bytebase-url: ${{ env.BYTEBASE_URL }} |
| 147 | + service-key: ${{ env.BYTEBASE_SERVICE_ACCOUNT }} |
| 148 | + service-secret: ${{ secrets.BYTEBASE_PASSWORD }} |
| 149 | +
|
| 150 | + ``` |
| 151 | + |
| 152 | +1. The **create_release** step scans the files matching the pattern and collects them into a bundle. Note that these files should also obey the naming scheme mentioned above. |
| 153 | + |
| 154 | + The bundle is first sent to check. If the check passes, a release is then created on Bytebase. |
| 155 | + |
| 156 | + ```yaml |
| 157 | + - name: Create release |
| 158 | + id: create_release |
| 159 | + uses: bytebase/create-release-action@v1 |
| 160 | + with: |
| 161 | + url: ${{ env.BYTEBASE_URL }} |
| 162 | + token: ${{ steps.login.outputs.token }} |
| 163 | + project: ${{ env.BYTEBASE_PROJECT }} |
| 164 | + file-pattern: ${{ env.FILE_PATTERN }} |
| 165 | + check-release: 'FAIL_ON_ERROR' |
| 166 | + targets: ${{ env.BYTEBASE_TARGETS }} |
| 167 | + validate-only: 'false' |
| 168 | + ``` |
| 169 | + |
| 170 | +1. Create a rollout and wait for completion. |
| 171 | + |
| 172 | + ```yaml |
| 173 | + - name: Create plan |
| 174 | + id: create_plan |
| 175 | + uses: bytebase/create-plan-from-release-action@v1 |
| 176 | + with: |
| 177 | + url: ${{ env.BYTEBASE_URL }} |
| 178 | + token: ${{ steps.login.outputs.token }} |
| 179 | + project: ${{ env.BYTEBASE_PROJECT }} |
| 180 | + release: ${{ steps.create_release.outputs.release }} |
| 181 | + targets: ${{ env.BYTEBASE_TARGETS }} |
| 182 | + # 'FAIL_ON_ERROR' will fail the action if plan checks report errors. |
| 183 | + # Use 'SKIP' to skip the check. |
| 184 | + # Use 'FAIL_ON_WARNING' to fail if plan checks report warning. |
| 185 | + check-plan: 'FAIL_ON_ERROR' |
| 186 | + validate-only: 'false' |
| 187 | + |
| 188 | + - name: Rollout |
| 189 | + id: rollout |
| 190 | + uses: bytebase/rollout-action@v1 |
| 191 | + with: |
| 192 | + url: ${{ env.BYTEBASE_URL }} |
| 193 | + token: ${{ steps.login.outputs.token }} |
| 194 | + plan: ${{ steps.create_plan.outputs.plan }} |
| 195 | + # set target-stage to exit after the stage completes |
| 196 | + # target-stage: 'Test Stage' |
| 197 | + ``` |
| 198 | + |
| 199 | + These are the steps: |
| 200 | + |
| 201 | + - create the plan from the release |
| 202 | + - check the plan |
| 203 | + - create the rollout |
| 204 | + - wait for the rollout to complete |
| 205 | + |
| 206 | + In the **create_plan** step, you can set check-plan to FAIL_ON_ERROR to fail the action if plan checks report errors. Use SKIP to skip plan checks. Use FAIL_ON_WARNING to fail the action if plan checks report warning. |
| 207 | + |
| 208 | + The rollout pipeline stages are created on demand in the **wait_rollout** step. You can use target-stage to early exit the step. When the target stage completes, it exits. If target-stage is not provided or not found, wait_rollout will wait until all stages complete. The target-stage is a stage title in the deployment config in the project setting. |
| 209 | + |
| 210 | +1. You can also apply releases to databases on Bytebase UI. If you wish, you can set up an action to just create the release and manually roll out later. |
| 211 | + |
| 212 | +  |
| 213 | + |
| 214 | +## Summary |
| 215 | + |
| 216 | +In this tutorial, you have learned how to create a release and then rollout to the database in Bytebase 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. |
0 commit comments