GitLab CI Component
Analyze your database migration scripts automatically on every merge request. The migracheck GitLab CI component posts a risk report as an MR note and sets a commit status that fails when severity thresholds are exceeded.
Prerequisites
- A migracheck account with a project set up for your repo.
- An API key — generate one in the web UI under your organization's API Keys page, then add it as a masked CI/CD variable named
MIGRACHECK_API_KEYin Settings → CI/CD → Variables. - A GitLab access token with
apiscope — stored as a masked CI/CD variable namedGITLAB_TOKEN. This is used by migracheck to post MR notes and set commit statuses. See Choosing a GitLab token below for which token type fits your plan. - Your project ID — visible in the web UI project page URL.
Choosing a GitLab token
GitLab offers several token types. Pick the one that fits your plan — in preference order:
| Token type | Recommended for | Where to create |
|---|---|---|
| Project access token | Most customers on Premium or Ultimate. Tied to the project, not a user; survives staff turnover and shows up as @project_NN_bot in audit logs. Default recommendation. | Repository project → Settings → Access Tokens. Scope: api. Role: Developer or above. |
| Group access token | Premium/Ultimate teams that want a single token shared across many projects in a group. Equivalent security model to project access tokens. | Group page → Settings → Access Tokens. Scope: api. |
| Personal access token (PAT) | Users on GitLab Free (project and group access tokens are not available on Free for gitlab.com). Also fine for quick testing on any tier. Tied to a specific user — rotate if that user leaves. | Top-right avatar → Edit profile → Access Tokens. Scope: api. |
In all cases, add the token as a masked CI/CD variable named GITLAB_TOKEN at Settings → CI/CD → Variables.
Why not just use CI_JOB_TOKEN? GitLab's built-in CI_JOB_TOKEN lacks the api scope needed to post MR notes and set commit statuses, so it cannot be used for this purpose.
Quick start
The component ships two templates. For most teams the analyze-changes template is the right choice — it diffs your changelog directory against the MR target branch (or the parent commit on a push) and runs migracheck on every changed migration file.
Add the following to your project's .gitlab-ci.yml:
include:
- component: gitlab.com/migracheck/gitlab-component/analyze-changes@~latest
inputs:
project_id: "42" # from the migracheck web UI
changelog_dir: "src/main/resources/db/changelog"
migration_tool: "liquibase" # or "flyway"
aurora_version: "8.0.28"
replica_count: "2"
fail_on: "critical,high"What this does
- Runs
git diffagainst the MR target branch (or the parent commit on a push) to find changed files underchangelog_dir. - For each changed file, runs
migracheck analyze, posts an MR note with per-statement findings, and sets a commit status namedmigracheck. - Exits non-zero if any finding matches
fail_on, blocking the MR (unless you setallow_failure: truefor advisory mode).
Templates
The component ships two templates:
| Template | When to use |
|---|---|
analyze-changes | Recommended. Diffs a changelog directory against the MR target (or parent commit on a push) and analyzes every changed file. One MR comment per file. |
analyze | Analyzes a single, explicitly specified file regardless of diff — useful for nightly audits or pinned files. |
Inputs — analyze-changes
| Input | Required | Default | Description |
|---|---|---|---|
project_id | Yes | — | Your migracheck project ID (from the web UI). |
changelog_dir | Yes | — | Directory containing your migrations (relative to repo root). |
file_glob | No | *.sql *.xml *.yaml *.yml | Space-separated globs under changelog_dir. For Flyway use V*.sql. |
fail_on | No | critical,high | Comma-separated severities that fail the job. |
migration_tool | No | flyway | Migration tool: flyway or liquibase. |
aurora_version | No | 8.0.28 | Target Aurora MySQL version. |
replica_count | No | 1 | Number of read replicas (affects replication lag assessment). |
stage | No | test | Pipeline stage to run in. |
image | No | registry.gitlab.com/migracheck/runner:latest | Runner image. Pin a specific tag to avoid surprise upgrades. |
job_name | No | migracheck-analyze-changes | Override when including the component multiple times in one pipeline. |
allow_failure | No | false | Advisory mode — pipeline stays green even when findings exceed threshold. |
git_depth | No | "50" | How deep to fetch the target branch for the diff. |
Inputs — analyze (single file)
| Input | Required | Default | Description |
|---|---|---|---|
project_id | Yes | — | Your migracheck project ID. |
script | Yes | — | Path to the specific file to analyze. |
fail_on | No | critical,high | Comma-separated severities that fail the job. |
migration_tool | No | flyway | Migration tool. |
aurora_version | No | 8.0.28 | Target Aurora MySQL version. |
replica_count | No | 1 | Number of read replicas. |
stage | No | test | Pipeline stage. |
image | No | registry.gitlab.com/migracheck/runner:latest | Runner image. |
job_suffix | No | "" | Appended to the job name when including the component multiple times. |
allow_failure | No | false | Advisory mode. |
Exit codes
The underlying CLI uses these exit codes to signal results:
- 0 — analysis complete, no threshold exceeded. Job passes.
- 1 — execution error (auth, network, invalid input). Job fails.
- 2 — severity threshold exceeded. Job fails, commit status is set to
failed, MR note is posted.
Blocking merges
The commit status named migracheck shows up on the MR widget. To prevent merging MRs with critical or high-severity findings, require the status to pass:
- Go to Settings → Repository → Merge request approvals (or Merge request settings, depending on GitLab tier).
- Enable Pipelines must succeed, and/or add a merge rule that requires the
migracheckstatus to be green.
Alternatively, use a Merge Request Approval Policy (Premium/Ultimate) to require passing external statuses.
Pinning
For reproducible pipelines, pin to a specific version instead of ~latest:
include:
- component: gitlab.com/migracheck/gitlab-component/[email protected]Multiple includes in one pipeline
Both templates can be included multiple times in a single pipeline — for example, to scan different directories with different thresholds. Use the job_name input (for analyze-changes) or job_suffix (for analyze) to give each inclusion a unique job name:
include:
- component: gitlab.com/migracheck/gitlab-component/analyze-changes@~latest
inputs:
job_name: "migracheck-app-migrations"
project_id: "42"
changelog_dir: "app/db/changelog"
migration_tool: "liquibase"
- component: gitlab.com/migracheck/gitlab-component/analyze-changes@~latest
inputs:
job_name: "migracheck-reporting-migrations"
project_id: "42"
changelog_dir: "reporting/db/changelog"
migration_tool: "liquibase"
fail_on: "critical" # advisory only for the reporting tierMetadata snapshots
If your project has metadata snapshots uploaded (via the CLI or web UI), the analysis automatically uses the most recent snapshot for richer risk assessment — e.g. actual row counts to classify unbatched DML more precisely. No configuration needed.
Troubleshooting
"warning: post GitLab MR note: status 401"
The job's GITLAB_TOKEN is missing, expired, or doesn't have api scope. Recreate it following Choosing a GitLab token — a project access token is the right choice on Premium/Ultimate, a personal access token on Free. Confirm the CI/CD variable is masked and not scoped to a specific environment that doesn't match this pipeline.
"No migration changes under ... — skipping analysis"
The diff against the target branch didn't find any added or modified files matching file_glob under changelog_dir. Verify the paths, and confirm the MR actually touches migration files.
Shallow-clone errors on large MRs
If your MR has diverged significantly from the target branch, increase the diff depth via the git_depth input (default: 50).