RepoPilotOpen in app →

golang-migrate/migrate

Database migrations. CLI and Golang library.

Mixed

Mixed signals — read the receipts

worst of 4 axes
Use as dependencyConcerns

non-standard license (Other)

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 7w ago
  • 25+ active contributors
  • Other licensed
Show 4 more →
  • CI configured
  • Tests present
  • Concentrated ownership — top contributor handles 57% of recent commits
  • Non-standard license (Other) — review terms
What would change the summary?
  • Use as dependency ConcernsMixed if: clarify license terms

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/golang-migrate/migrate?axis=fork)](https://repopilot.app/r/golang-migrate/migrate)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/golang-migrate/migrate on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: golang-migrate/migrate

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/golang-migrate/migrate shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Mixed signals — read the receipts

  • Last commit 7w ago
  • 25+ active contributors
  • Other licensed
  • CI configured
  • Tests present
  • ⚠ Concentrated ownership — top contributor handles 57% of recent commits
  • ⚠ Non-standard license (Other) — review terms

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live golang-migrate/migrate repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/golang-migrate/migrate.

What it runs against: a local clone of golang-migrate/migrate — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in golang-migrate/migrate | Confirms the artifact applies here, not a fork | | 2 | License is still Other | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | Last commit ≤ 81 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>golang-migrate/migrate</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of golang-migrate/migrate. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/golang-migrate/migrate.git
#   cd migrate
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of golang-migrate/migrate and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "golang-migrate/migrate(\\.git)?\\b" \\
  && ok "origin remote is golang-migrate/migrate" \\
  || miss "origin remote is not golang-migrate/migrate (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Other)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Other\"" package.json 2>/dev/null) \\
  && ok "license is Other" \\
  || miss "license drift — was Other at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 81 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~51d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/golang-migrate/migrate"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

golang-migrate is a database migration tool and library written in Go that reads migration files from various sources and applies them to 20+ different databases (PostgreSQL, MySQL, SQLite, MongoDB, Cassandra, Neo4j, CockroachDB, etc.) in correct dependency order. It provides both a CLI binary and an importable Go library to manage schema versioning and track applied migrations via a schema_migrations table. Monorepo structure: core migrate library at root, multiple database drivers under database/{postgres,mysql,sqlite,etc}/, CLI binaries under cmd/migrate/ and cli/, test migrations under database/{driver}/examples/migrations/. Each driver implements a common Driver interface (database/driver.go). CI config in .circleci/ and .github/workflows/, Docker builds for distribution.

👥Who it's for

Go backend engineers and DevOps teams who need to version control database schema changes alongside code, and deploy migrations reliably across PostgreSQL, MySQL, SQLite, and other databases in production environments. Teams building CLI tools or embedding migration logic into Go applications.

🌱Maturity & risk

Production-ready. The project is actively maintained (CI passing via GitHub Actions/.circleci, supports Go 1.24 and 1.25), has comprehensive test coverage across multiple database drivers, and was forked from the mature mattes/migrate project. Multiple database drivers and Docker distribution indicate solid adoption.

Low-to-moderate risk. The codebase has many database driver dependencies (30+ drivers in database/), increasing maintenance surface area. Last visible activity shows active development, but dependency updates are critical since database connection libraries have security implications. Single database driver bugs could break production migrations for that specific database.

Active areas of work

Active development with GitHub Actions CI, recent Go version support (1.24, 1.25), and goreleaser configuration for automated releases. Multiple database drivers actively maintained. No specific breaking changes mentioned in visible config, suggesting stable API.

🚀Get running

git clone https://github.com/golang-migrate/migrate.git
cd migrate
make build  # Uses Makefile; builds CLI binary
# Or for library usage: go get -u github.com/golang-migrate/migrate/v4

Daily commands: For CLI: make build produces binary in bin/migrate. Run migrations: migrate -path db/migrations -database "postgres://localhost/dbname" up. For library in Go code: m, err := migrate.New("file://db/migrations", "postgres://..."); m.Up(). Docker image available: docker run migrate/migrate -path /migrations -database "..." up.

🗺️Map of the codebase

  • migrate.go: Core Migrate struct and public API (Open, Up, Down, Version, etc.) — entry point for library users
  • database/driver.go: Driver interface definition that all 20+ database drivers must implement — critical contract for extensibility
  • cmd/migrate/main.go: CLI entry point with command parsing and flag handling for migrate binary
  • source/source.go: Source interface for reading migrations from files, git, GitHub, etc. — abstraction layer for migration sources
  • database/postgres/postgres.go: Reference implementation of Driver interface for PostgreSQL — template for understanding driver pattern
  • Makefile: Build configuration, test targets, and release pipeline — defines how to build and test the project
  • .github/workflows/ci.yaml: GitHub Actions CI pipeline — shows how all database drivers are tested against containerized real databases

🛠️How to make changes

For new database driver: implement Driver interface in database/newdb/newdb.go (see database/postgres/postgres.go as template). For CLI features: modify cmd/migrate/main.go. For core library logic: edit root migrate.go and migrator.go. For tests: add database/{driver}/{driver}_test.go following existing test patterns with dktest containers. Update database/driver.go documentation when adding drivers.

🪤Traps & gotchas

Database drivers require containerized test databases (uses Docker via dktest); some drivers need specific ports open (PostgreSQL 5432, MySQL 3306, etc.). Migration files must have specific naming convention (001_name.up.sql / 001_name.down.sql). Schema_migrations tracking table name is hardcoded per driver; custom table names may not be supported on all drivers. SSL/TLS connection parameters vary by database and must be passed in connection string. The 'fake' driver for testing exists but is separate.

💡Concepts to learn

  • Migration Versioning — golang-migrate uses a schema_migrations table to track which migration files have been applied; understanding version state is critical to debugging partial migrations or failed rollbacks
  • Up/Down Migration Pairs — This project uses paired SQL files (001_name.up.sql and 001_name.down.sql) to ensure reversible schema changes; contributors must understand bidirectional semantics
  • Driver Interface Pattern — Adding support for new databases requires implementing the Driver interface with 8+ methods; understanding this pluggable adapter pattern is essential for extending the project
  • Source Abstraction — Migrations can be loaded from file system, embedded binaries, git, or GitHub URLs via the Source interface; understanding source lifecycle is crucial for custom source implementations
  • Containerized Integration Testing — golang-migrate uses dktest to spin up real database containers during tests; contributors must understand Docker-based test patterns for validating driver behavior
  • Transaction Safety in Migrations — Different databases handle DDL transactionality differently (PostgreSQL vs MySQL vs SQLite); drivers must implement correct locking/unlocking semantics to prevent concurrent migration conflicts
  • Dirty State Detection — When a migration crashes mid-execution, golang-migrate marks the database as 'dirty' to prevent auto-healing; understanding dirty state semantics prevents silent data corruption
  • flyway/flyway — Database migration tool in Java with similar philosophy (up/down scripts, multi-database support) — primary alternative in other language ecosystems
  • pressly/goose — Pure Go migration tool supporting SQL and embedded scripts — direct competitor in Go ecosystem with similar feature set
  • rubenv/sql-migrate — Go migration tool with bidirectional migration support — alternative Go approach with different DSL design
  • golang/go — Required runtime; golang-migrate targets Go 1.24+ and uses Go modules for dependency management
  • containernetwork/docker-ce — Critical for testing infrastructure; dktest depends on Docker to run real database instances during test suite

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add integration tests for Neo4j driver with test containers

The Neo4j driver exists (database/neo4j imports neo4j-go-driver) but there are no example migrations or integration tests visible in the file structure, unlike Cassandra, ClickHouse, and CockroachDB which all have examples/ directories with sample migrations. This creates a gap in test coverage and makes it harder for users to understand how to use migrate with Neo4j.

  • [ ] Create database/neo4j/examples/migrations/ directory with sample .up.sql and .down.sql files (similar to database/cockroachdb/examples/migrations/)
  • [ ] Add integration tests in database/neo4j/neo4j_test.go using dhui/dktest (already a dependency) to verify basic operations like Up/Down migrations
  • [ ] Create database/neo4j/README.md with usage examples and connection string format documentation

Add GitHub Actions workflow for automated dependency security scanning and updates

The project has extensive dependencies (AWS SDK, Google Cloud, Azure, MongoDB, etc.) but there's no visible Dependabot configuration or scheduled security audit workflow. With go.mod showing dependencies like github.com/docker/docker and various cloud SDKs, automated vulnerability detection would improve supply chain security for users relying on this tool for production migrations.

  • [ ] Create .github/dependabot.yml to enable automated dependency version updates and security alerts for go.mod
  • [ ] Add a scheduled GitHub Actions workflow (.github/workflows/security-audit.yaml) that runs 'go audit' or similar tooling on a weekly basis
  • [ ] Update SECURITY.md with instructions for reporting vulnerabilities and reference the automated scanning process

Add comprehensive error handling documentation and examples for database-specific migration failures

The repo has multiple database drivers (MySQL, PostgreSQL, Cassandra, ClickHouse, CockroachDB, Firebird, Neo4j, Snowflake, MongoDB, etc.) but MIGRATIONS.md and GETTING_STARTED.md don't document how different databases handle common failure scenarios (constraint violations, connection timeouts, permission errors). This causes confusion for users trying to debug migration issues across different database backends.

  • [ ] Expand MIGRATIONS.md with a new section 'Common Migration Errors by Database' documenting error codes and recovery strategies for at least 5 major drivers (PostgreSQL, MySQL, CockroachDB, ClickHouse, MongoDB)
  • [ ] Add specific error handling examples to cmd/migrate/README.md showing how to interpret driver-specific error messages and retry logic
  • [ ] Create or update FAQ.md with troubleshooting section addressing database-specific connection, permissions, and transaction isolation issues that affect migrations

🌿Good first issues

  • Add integration tests for database/rqlite/rqlite.go following the pattern in database/sqlite3/sqlite3_test.go using dktest container setup
  • Write godoc examples for source/source.go Source interface implementation in source/file/file.go to document migration file discovery behavior
  • Extend cmd/migrate/main.go to add a 'validate' subcommand that checks migration file syntax and ordering without executing (infrastructure exists in migrate.go for version tracking)

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 2bd822b — Merge pull request #1361 from golang-migrate/dependabot/go_modules/go_modules-6b971a9d7e (dhui)
  • 1620c56 — Bump go.opentelemetry.io/otel/sdk (dependabot[bot])
  • 257fa84 — Merge pull request #1320 from achanda/upgrade-pgxv5 (dhui)
  • 001b70a — ci: update golangci-lint to v2 (#1341) (PascalBourdier)
  • 89e308c — chore: remove dependency on "hashicorp/go-multierror" (#1322) (leonklingele)
  • fed8fe9 — Upgrade pgx v5 to latest version (achanda)
  • 472ef2e — Merge pull request #1336 from golang-migrate/dependabot/go_modules/golang.org/x/crypto-0.45.0 (dhui)
  • 8d76259 — Bump golang.org/x/crypto from 0.43.0 to 0.45.0 (dependabot[bot])
  • 9f9df7c — chore: Update cloud.google.com/go/spanner version (#1330) (jferrl)
  • a371c8e — Merge pull request #1304 from iamonah/fix/clarify-databaseName-meaning (dhui)

🔒Security observations

Failed to generate security analysis.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · golang-migrate/migrate — RepoPilot