{"id":25694005,"url":"https://github.com/realkarych/seqwall","last_synced_at":"2025-10-13T21:05:46.232Z","repository":{"id":278836041,"uuid":"936314179","full_name":"realkarych/seqwall","owner":"realkarych","description":"🧪 Testing tool for PostgreSQL migrations — schema-snapshots based, framework‑agnostic.","archived":false,"fork":false,"pushed_at":"2025-09-30T18:26:15.000Z","size":168,"stargazers_count":23,"open_issues_count":4,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-30T20:23:16.157Z","etag":null,"topics":["alembic","database","dbmate","ddl","flyway","golang","integration-testing","liquibase","migration-testing","migration-tool","migrations","postgresql","sql"],"latest_commit_sha":null,"homepage":"https://github.com/realkarych/seqwall","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/realkarych.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-02-20T22:00:03.000Z","updated_at":"2025-09-30T18:26:12.000Z","dependencies_parsed_at":"2025-04-06T20:24:04.439Z","dependency_job_id":"2e8c7e01-fbfe-4253-afc5-413e62427857","html_url":"https://github.com/realkarych/seqwall","commit_stats":null,"previous_names":["realkarych/seqwall"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/realkarych/seqwall","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realkarych%2Fseqwall","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realkarych%2Fseqwall/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realkarych%2Fseqwall/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realkarych%2Fseqwall/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/realkarych","download_url":"https://codeload.github.com/realkarych/seqwall/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realkarych%2Fseqwall/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279017015,"owners_count":26085949,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alembic","database","dbmate","ddl","flyway","golang","integration-testing","liquibase","migration-testing","migration-tool","migrations","postgresql","sql"],"created_at":"2025-02-24T23:49:43.277Z","updated_at":"2025-10-13T21:05:46.226Z","avatar_url":"https://github.com/realkarych.png","language":"Go","readme":"\u003ca href=\"https://github.com/realkarych/seqwall\"\u003e\n\u003cp align=\"center\" width=\"100%\"\u003e\n    \u003cimg width=\"50%\" alt=\"seqwall logo\" src=\"https://github.com/user-attachments/assets/4ff7fce5-4e74-44ff-a6af-bb50d39449a3\"\u003e\n\u003c/p\u003e\n\u003c/a\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/realkarych/seqwall\"\u003eSeqwall\u003c/a\u003e is a tool for PostgreSQL migrations testing.\u003cbr\u003e\n  Ensure that every migration is reversible, idempotent, compatible with others in sequence, structurally sound and verifiable.\n\u003c/p\u003e\n\n\u003c!-- Badges --\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/realkarych/seqwall/actions/workflows/ci.yml\"\u003e\u003cimg alt=\"CI status\" src=\"https://github.com/realkarych/seqwall/actions/workflows/ci.yml/badge.svg\"\u003e\u003c/a\u003e\u0026nbsp;\u003c!--\n  --\u003e\u003ca href=\"https://app.codecov.io/gh/realkarych/seqwall\"\u003e\u003cimg alt=\"coverage\" src=\"https://codecov.io/gh/realkarych/seqwall/branch/master/graph/badge.svg\"\u003e\u003c/a\u003e\u0026nbsp;\u003c!--\n  --\u003e\u003ca href=\"https://go.dev\"\u003e\u003cimg alt=\"go version\" src=\"https://img.shields.io/github/go-mod/go-version/realkarych/seqwall\"\u003e\u003c/a\u003e\u0026nbsp;\u003c!--\n  --\u003e\u003ca href=\"https://github.com/realkarych/seqwall/blob/master/LICENSE\"\u003e\u003cimg alt=\"license MIT\" src=\"https://img.shields.io/github/license/realkarych/seqwall\"\u003e\u003c/a\u003e\u0026nbsp;\u003c!--\n  --\u003e\u003cimg alt=\"platforms\" src=\"https://img.shields.io/badge/platform-linux%20%7C%20macOS%20%7C%20windows-blue\"\u003e\n\u003c/p\u003e\n\n\u003chr\u003e\n\n## \u003cp align=center\u003e📦 Installation\u003c/p\u003e\n\n### Docker images\n\n**Package:** \u003chttps://github.com/realkarych/seqwall/pkgs/container/seqwall\u003e.\n\n```bash\ndocker run --rm --network=host \\\n  ghcr.io/realkarych/seqwall:latest staircase --help\n```\n\n### Homebrew (macOS \u0026 Linux)\n\n```bash\nbrew tap realkarych/tap\nbrew install seqwall        # first install\nbrew upgrade seqwall        # later updates\n```\n\n### Debian / Ubuntu (APT)\n\n```bash\n# Import the GPG key\ncurl -fsSL https://realkarych.github.io/seqwall-apt/public.key \\\n  | sudo tee /etc/apt/trusted.gpg.d/seqwall.asc\n\n# Add the repository\necho \"deb [arch=$(dpkg --print-architecture)] \\\n  https://realkarych.github.io/seqwall-apt stable main\" \\\n  | sudo tee /etc/apt/sources.list.d/seqwall.list\n\n# Install / update\nsudo apt update\nsudo apt install seqwall          # first install\nsudo apt upgrade seqwall          # later updates\n```\n\n### Other distros / Windows\n\nDownload the pre‑built archive from the **[Releases](https://github.com/realkarych/seqwall/releases)** page, unpack,\nadd the binary to your `PATH`.\n\n\u003e On Windows, you may need `Unblock-File .\\seqwall.exe` before first run.\n\n### Go install (Go ≥ 1.17)\n\n```bash\ngo install github.com/realkarych/seqwall@latest\n# make sure $GOBIN (default ~/go/bin) is on your PATH\n```\n\n\u003chr\u003e\n\n### ✅ Once installed, verify it works\n\n```\n❯ seqwall staircase --help\nLaunch staircase testing\n\nUsage:\n  seqwall staircase [flags]\n\nFlags:\n      --postgres-url string           PostgreSQL URL (required or fallback: $DATABASE_URL environment variable)\n      --migrations-path string        Path to migrations. Migrations must be in lexicographical order (required)\n      --upgrade string                Shell command that applies next migration (required)\n      --downgrade string              Shell command that reverts current migration (required)\n      --migrations-extension string   Extension of migration files (default: .sql)\n      --schema stringArray            Schemas to test (default [public])\n      --test-snapshots                Compare schema snapshots. If false, only checks fact that migrations are applied\n                                      / reverted with no errors (default true)\n      --depth int                     Depth of staircase testing (0 = all)\n      --help                          help for staircase\n```\n\n\u003chr\u003e\n\n## \u003cp align=center\u003e🧬 Methodology \u0026 Core Principles\u003c/p\u003e\n\n### Migrations are contracts\n\nEach migration must be reversible and must not break the schema if applied, reverted, and reapplied.\n\n### Snapshots reveal the truth\n\nAfter each migration, Seqwall captures the schema using **`information_schema` views**,\nadhering to the **\u003ca href=\"https://www.iso.org/standard/76586.html\"\u003eISO/IEC 9075-11\u003c/a\u003e SQL standard**.\n\nThis includes *tables*, *columns*, *constraints*, *indexes*, *views*,\n*triggers*, *functions*, *enums*, *sequences*, and *foreign keys*.\nThe snapshots are then compared using structured diffs, allowing detection of even subtle schema differences or mismatches.\n\n### `Staircase` testing guarantees *schema* consistency\n\nWe use a 3-phase strategy:\n\n1. **`actualize`** — applying all migrations and captures *etalon* schema snapshot for each migration.\n\n2. **`down → up → down`** — starting from the latest migration, step backwards:\n   - downgrade one migration,\n   - upgrade it again,\n   - then downgrade once more (down step).\n   - At each step, the schema is compared with previously captured\n   *etalon* snapshots — both before and after — ensuring reversibility and no drift.\n\n3. **`re-actualize`** — starting from the lower point reached in step 2 (after several rollbacks):\n   - re-apply each migration one by one\n   - compare each re-applied migration with etalon\n\nThis ensures that the migration chain is robust in both directions, even when recovering from mid-chain downgrades.\n\n\u003cp align=\"center\" width=\"100%\"\u003e\n    \u003cimg width=\"75%\" alt=\"staircase\" src=\"https://github.com/user-attachments/assets/b3fad935-a08b-483c-ada1-68586288f6b7\"\u003e\n\u003c/p\u003e\n\n### Standalone by design\n\nSeqwall is a single-purpose CLI tool — it requires no server, no daemon, no embedded framework, and no special runtime.\n\nYou can run it locally or in CI/CD (recommended), with just your migrations and a database connection string.\nNo vendor lock-in, no config-files, no dependencies beyond PostgreSQL.\n\n### Test migrations as they really run\n\nSeqwall runs your actual migration scripts and commands — no wrapper DSLs, no abstractions, no mocks.\n\nYou bring your own migration runner (`dbmate`, `alembic`, `goose`, `sqlx`, `atlas`, etc.).\nSeqwall just executes shell commands.\n\n### Limitations \u0026 Scope\n\nDoes this mean Seqwall is the only tool you need for testing migrations?\n\nNo — databases involve a spectrum of concerns, and a complete testing strategy should include:\n\n- Load testing — to observe performance \u0026 regressions\n- Lock behavior analysis — to catch deadlocks and blocking issues\n- Data state testing — to ensure data survives or transforms as expected\n- Static analysis — to catch anti-patterns or unsafe operations before runtime\n- Integration tests — to validate application logic against migrated schemas\n- ...\n\nSeqwall focuses on **schema-level structural correctness** — nothing more, nothing less.\n\n## \u003cp align=\"center\"\u003e🙏 Contribution\u003c/p\u003e\n\n### Found a bug?\n\n- Please [open an issue](https://github.com/realkarych/seqwall/issues/new?template=bug.yml) with a clear description,\nreproduction steps (if possible), and expected vs. actual behavior.\n\n### Have a question?\n\n- Please [open a discussion](https://github.com/realkarych/seqwall/discussions/categories/q-a) in QA section.\nOr feel free to message me on Telegram: [`@karych`](https://t.me/karych).\n\n### Want to suggest a feature?\n\n- If you have a concrete and well-scoped idea — feel free to [open a feature request](https://github.com/realkarych/seqwall/issues/new?template=feature_request.yml).\n- If the idea is more exploratory — start a\n[discussion](https://github.com/realkarych/seqwall/discussions/categories/ideas) instead.\n\n### Ready to contribute code?\n\n- Look for issues marked with `help wanted` or `good first issue`. *In fact, you can pick any issue without Assignees* 😊️️️️️️.\n- Fork the repo, create a branch, and open a pull request when ready (and tag `@realkarych` for review).\n\nYour feedback and contributions are always welcome 💙.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frealkarych%2Fseqwall","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frealkarych%2Fseqwall","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frealkarych%2Fseqwall/lists"}