Skip to content

auto-rollback based on git history#93

Open
xshiart wants to merge 1 commit into
jetbase-hq:mainfrom
xshiart:feature/automatic-safe-rollback
Open

auto-rollback based on git history#93
xshiart wants to merge 1 commit into
jetbase-hq:mainfrom
xshiart:feature/automatic-safe-rollback

Conversation

@xshiart

@xshiart xshiart commented Jun 16, 2026

Copy link
Copy Markdown

Summary

Adds two linked capabilities to jetbase upgrade:

  1. Migration provenance - every applied migration now records the git commit hash that was checked out at the moment it ran, in a new nullable git_commit_hash column on jetbase_migrations.
  2. Automatic safe rollback (opt-in --auto-rollback) - when an already-applied migration's file is missing locally (e.g. after checking out an older branch/release), the upgrade no longer just errors out. Instead it rolls the database back to the latest applied migration whose file still exists, then re-runs the upgrade from that baseline. The rollback SQL for the missing files is recovered read-only from the recorded commit via git show - the working tree and HEAD are never touched.

Motivation

Previously, running upgrade when a migrated version's file was absent raised FileNotFoundError and stopped, leaving the operator to manually restore files or hand-fix the migrations table. This is common when switching between branches/releases whose migrations/ directories diverge. With the recorded commit hash, jetbase can self-heal: roll back to a state that matches the current files and continue.

What changed

git_commit_hash column

  • Added (nullable) to the CREATE TABLE statement for all six dialects (Postgres, SQLite, MySQL, Snowflake, Databricks, ClickHouse).
  • run_migration records get_current_commit_hash() on every versioned / first-time-repeatable insert; INSERT statements updated for the default, ClickHouse, and Databricks dialects.
  • Existing tables are upgraded in place via an idempotent, dialect-agnostic ensure_git_commit_hash_column() (ALTER TABLE ADD COLUMN, guarded by SQLAlchemy reflection) run at the start of each upgrade.

Automatic safe rollback

  • New jetbase/engine/git.py - read-only git helpers (get_current_commit_hash, get_repo_root, read_file_at_commit) using subprocess, no new dependencies.
  • New jetbase/commands/safe_rollback.py - attempt_safe_rollback() determines the baseline, recovers missing files' rollback SQL from the recorded commit, and rolls back under the migration lock.
  • upgrade_cmd gains an auto_rollback param and a --auto-rollback CLI flag; on a missing-file error it attempts the rollback, then re-validates and re-upgrades from the new baseline.
  • New MissingMigrationFileError (subclasses FileNotFoundError for backward compatibility) distinguishes the missing-applied-file case so the recovery flow targets it precisely.

Graceful fallback (preserves old behaviour)

If the repo isn't a git checkout, the latest applied migration has no recorded hash, the missing files aren't a contiguous trailing run, or a file can't be recovered from git, attempt_safe_rollback() returns False and the original error is re-raised.

Scope notes

  • The hash is recorded on insert; it is not refreshed when repeatable migrations re-run.
  • Auto-rollback handles the contiguous trailing-missing-files case; a non-contiguous gap falls through to the original error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant