doc/website/blog/2022-09-06-ci-for-ent.mdx
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
To ensure the quality of their software, teams often apply Continuous Integration workflows, commonly known as CI. With CI, teams continuously run a suite of automated verifications against every change to the code-base. During CI, teams may run many kinds of verifications:
From our discussions with the Ent community, we have learned that many teams using Ent already use CI and would like to enforce some Ent-specific verifications into their workflows.
To support the community with this effort, we added a new guide to the docs which documents common best practices to verify in CI and introduces ent/contrib/ci: a GitHub Action we maintain that codifies them.
In this post, I want to share some of our initial suggestions on how you might incorporate CI to you Ent project. Towards the end of this post I will share insights into projects we are working on and would like to get the community's feedback for.
Ent heavily relies on code generation. In our experience, generated code should always be checked into source control. This is done for two reasons:
If you're using GitHub for source control, it's easy to verify that all generated
files are checked in with the ent/contrib/ci GitHub Action.
Otherwise, we supply a simple bash script that you can integrate in your existing
CI flow.
<Tabs defaultValue="gh" values={[ {label: 'GitHub Action', value: 'gh'}, {label: 'Bash', value: 'bash'}, ]}> <TabItem value="gh">
Simply add a file named .github/workflows/ent-ci.yaml in your repository:
name: EntCI
on:
push:
# Run whenever code is changed in the master.
branches:
- master
# Run on PRs where something changed under the `ent/` directory.
pull_request:
paths:
- 'ent/*'
jobs:
ent:
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
- uses: actions/setup-go@v3
with:
go-version: 1.18
- uses: ent/contrib/ci@master
go generate ./...
status=$(git status --porcelain)
if [ -n "$status" ]; then
echo "you need to run 'go generate ./...' and commit the changes"
echo "$status"
exit 1
fi
Changes to your project's Ent schema almost always result in a modification of your database. If you are using Versioned Migrations to manage changes to your database schema, you can run migration linting as part of your continuous integration flow. This is done for multiple reasons:
If you're using GitHub, you can use the Official Atlas Action to run migration linting during CI.
Add .github/workflows/atlas-ci.yaml to your repo with the following contents:
<Tabs defaultValue="mysql" values={[ {label: 'MySQL', value: 'mysql'}, {label: 'MariaDB', value: 'maria'}, {label: 'PostgreSQL', value: 'postgres'}, ]}> <TabItem value="mysql">
name: Atlas CI
on:
# Run whenever code is changed in the master branch,
# change this to your root branch.
push:
branches:
- master
# Run on PRs where something changed under the `ent/migrate/migrations/` directory.
pull_request:
paths:
- 'ent/migrate/migrations/*'
jobs:
lint:
services:
# Spin up a mysql:8.0.29 container to be used as the dev-database for analysis.
mysql:
image: mysql:8.0.29
env:
MYSQL_ROOT_PASSWORD: pass
MYSQL_DATABASE: test
ports:
- 3306:3306
options: >-
--health-cmd "mysqladmin ping -ppass"
--health-interval 10s
--health-start-period 10s
--health-timeout 5s
--health-retries 10
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
with:
fetch-depth: 0 # Mandatory unless "latest" is set below.
- uses: ariga/atlas-action@v0
with:
dir: ent/migrate/migrations
dir-format: golang-migrate # Or: atlas, goose, dbmate
dev-url: mysql://root:pass@localhost:3306/test
name: Atlas CI
on:
# Run whenever code is changed in the master branch,
# change this to your root branch.
push:
branches:
- master
# Run on PRs where something changed under the `ent/migrate/migrations/` directory.
pull_request:
paths:
- 'ent/migrate/migrations/*'
jobs:
lint:
services:
# Spin up a maria:10.7 container to be used as the dev-database for analysis.
maria:
image: mariadb:10.7
env:
MYSQL_DATABASE: test
MYSQL_ROOT_PASSWORD: pass
ports:
- 3306:3306
options: >-
--health-cmd "mysqladmin ping -ppass"
--health-interval 10s
--health-start-period 10s
--health-timeout 5s
--health-retries 10
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
with:
fetch-depth: 0 # Mandatory unless "latest" is set below.
- uses: ariga/atlas-action@v0
with:
dir: ent/migrate/migrations
dir-format: golang-migrate # Or: atlas, goose, dbmate
dev-url: maria://root:pass@localhost:3306/test
name: Atlas CI
on:
# Run whenever code is changed in the master branch,
# change this to your root branch.
push:
branches:
- master
# Run on PRs where something changed under the `ent/migrate/migrations/` directory.
pull_request:
paths:
- 'ent/migrate/migrations/*'
jobs:
lint:
services:
# Spin up a postgres:10 container to be used as the dev-database for analysis.
postgres:
image: postgres:10
env:
POSTGRES_DB: test
POSTGRES_PASSWORD: pass
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
with:
fetch-depth: 0 # Mandatory unless "latest" is set below.
- uses: ariga/atlas-action@v0
with:
dir: ent/migrate/migrations
dir-format: golang-migrate # Or: atlas, goose, dbmate
dev-url: postgres://postgres:pass@localhost:5432/test?sslmode=disable
Notice that running atlas migrate lint requires a clean dev-database
which is provided by the services block in the example code above.
To add to this modest beginning, I want to share some features that we are experimenting with at Ariga with hope to get the community's feedback on them.
ent.Schema.Create when applications start).
Assuming a project's source code is managed in a version control system (such as Git),
we compare the schema in the mainline branch (master/main/etc.) with the one in the
current feature branch and use Atlas's schema diff capability
to calculate the SQL statements that are going to be run against the database. We can then
use Atlas's linting capability to provide insights
about possible dangers the arise from the proposed change.In this post, we presented the concept of CI and discussed ways in which it can be practiced for Ent projects. Next, we presented CI checks we are experimenting with internally. If you would like to see these checks become a part of Ent or have other ideas for providing CI tools for Ent, ping us on the Ent Discord Server.
:::note For more Ent news and updates: