{"id":42169223,"url":"https://github.com/glideapps/migrate","last_synced_at":"2026-02-15T19:12:08.426Z","repository":{"id":333868878,"uuid":"1138585853","full_name":"glideapps/migrate","owner":"glideapps","description":"Migrate apps, not data. Track and execute filetree transformations.","archived":false,"fork":false,"pushed_at":"2026-01-21T21:53:52.000Z","size":155,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-22T01:29:24.677Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","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/glideapps.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":"CODEOWNERS","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":"2026-01-20T21:32:35.000Z","updated_at":"2026-01-21T21:53:14.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/glideapps/migrate","commit_stats":null,"previous_names":["glideapps/app-migrations"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/glideapps/migrate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glideapps%2Fmigrate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glideapps%2Fmigrate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glideapps%2Fmigrate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glideapps%2Fmigrate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/glideapps","download_url":"https://codeload.github.com/glideapps/migrate/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glideapps%2Fmigrate/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28788369,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T21:13:08.818Z","status":"ssl_error","status_checked_at":"2026-01-26T21:13:08.448Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2026-01-26T21:22:59.464Z","updated_at":"2026-02-15T19:12:08.419Z","avatar_url":"https://github.com/glideapps.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# migrate\n\nA generic file migration tool that applies ordered transformations to a project directory. Think database migrations, but for files and project setup. Migrations can be written in any language (bash, TypeScript, Python, etc.) using shebangs.\n\n## Install\n\n### Option 1: Download binary (easiest)\n\nDownload the pre-built binary for your platform from [GitHub Releases](https://github.com/glideapps/migrate/releases), then move it to a directory in your PATH:\n\n```bash\n# Example for macOS (Apple Silicon)\ncurl -L https://github.com/glideapps/migrate/releases/latest/download/migrate-aarch64-apple-darwin -o migrate\nchmod +x migrate\nsudo mv migrate /usr/local/bin/\n```\n\n### Option 2: cargo-binstall (recommended if you have Rust)\n\nIf you have Rust installed, [cargo-binstall](https://github.com/cargo-bins/cargo-binstall) downloads pre-built binaries:\n\n```bash\n# Install cargo-binstall first (if you don't have it)\ncargo install cargo-binstall\n\n# Then install migrate\ncargo binstall migrate\n```\n\n### Option 3: cargo install\n\nRequires [Rust](https://rustup.rs):\n\n```bash\ncargo install migrate\n```\n\n### Option 4: Build from source\n\n```bash\ncargo install --git https://github.com/glideapps/migrate\n```\n\n## Quick Start\n\n```bash\n# Check what migrations exist and their status\nmigrate status\n\n# Apply all pending migrations\nmigrate up\n\n# Preview what would happen without making changes\nmigrate up --dry-run\n```\n\n## Migration Lifecycle\n\n### 1. Creating Migrations\n\nCreate a new migration with `migrate create`:\n\n```bash\nmigrate create add-prettier                    # Bash script (default)\nmigrate create setup-config --template ts      # TypeScript\nmigrate create init-db --template python       # Python\n```\n\nThis generates a timestamped file like `1fb2g-add-prettier.sh` in your `migrations/` directory. The 5-character prefix ensures migrations run in chronological order.\n\n**Available templates:** `bash`, `ts`, `python`, `node`, `ruby`\n\n### 2. Writing Migrations\n\nMigrations are executable files that receive context via environment variables:\n\n| Variable | Description |\n|----------|-------------|\n| `MIGRATE_PROJECT_ROOT` | Absolute path to project root |\n| `MIGRATE_MIGRATIONS_DIR` | Where migration files live |\n| `MIGRATE_ID` | Current migration ID (e.g., `1fb2g-add-prettier`) |\n| `MIGRATE_DRY_RUN` | `true` if running in preview mode |\n\n**Bash example:**\n\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\n# Description: Add TypeScript configuration\n\ncd \"$MIGRATE_PROJECT_ROOT\"\ncat \u003e tsconfig.json \u003c\u003c 'EOF'\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"NodeNext\",\n    \"strict\": true\n  }\n}\nEOF\n```\n\n**TypeScript example:**\n\n```typescript\n#!/usr/bin/env -S npx tsx\n// Description: Add configuration file\n\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\n\nconst projectRoot = process.env.MIGRATE_PROJECT_ROOT!;\n\nawait fs.writeFile(\n  path.join(projectRoot, 'config.json'),\n  JSON.stringify({ version: 1 }, null, 2)\n);\n```\n\n### 3. Applying Migrations\n\nRun `migrate up` to apply all pending migrations in order. Each successful migration is recorded in `history`, so it won't run again.\n\n```bash\nmigrate up              # Apply all pending\nmigrate up --dry-run    # Preview without applying\n```\n\nIf a migration fails, execution stops immediately. Fix the issue and re-run `migrate up`—already-applied migrations are skipped.\n\n### 4. Checking Status\n\nUse `migrate status` to see what's been applied and what's pending:\n\n```\nVersion: 1fb2g → 1fc3h (2 pending)\n\nApplied (3):\n  ✓ 1fa1f-init-project\n  ✓ 1fa2g-add-typescript\n  ✓ 1fb2g-setup-eslint\n\nPending (2):\n  • 1fc2h-add-prettier\n  • 1fc3h-configure-ci\n```\n\n### 5. Baselining (Cleaning Up Old Migrations)\n\nOver time, your `migrations/` directory accumulates files. Once migrations have been applied everywhere (all environments, all team members), you can **baseline** to clean up.\n\nBaselining marks a version as the \"starting point\"—migrations at or before that version are considered complete and can be deleted.\n\n```bash\n# Mark version 1fb2g as baseline and delete old migration files\nmigrate baseline 1fb2g\n\n# Preview what would be deleted without making changes\nmigrate baseline 1fb2g --dry-run\n\n# Create baseline but keep the files (just update .baseline)\nmigrate baseline 1fb2g --keep\n```\n\nYou can also baseline immediately after applying migrations:\n\n```bash\nmigrate up --baseline           # Apply and baseline at final version\nmigrate up --baseline --keep    # Apply and baseline without deleting files\n```\n\n**When to baseline:**\n- All environments have applied the migrations\n- All team members have pulled and applied\n- You want to reduce clutter in the migrations directory\n\n**What baselining does:**\n- Records the baseline version in the `history` file\n- Deletes migration files at or before that version (unless `--keep`)\n- Deletes any associated asset directories (directories named after the migration ID, e.g., `1fb2g-setup-eslint/`)\n- Future `migrate up` skips migrations covered by the baseline\n\n**Asset directories:** Migrations can have companion directories for assets (templates, configs, data files). Name the directory after the migration ID:\n\n```\nmigrations/\n├── 1fb2g-setup-eslint.sh       # Migration script\n├── 1fb2g-setup-eslint/         # Asset directory (deleted with migration)\n│   ├── .eslintrc.json\n│   └── .eslintignore\n└── ...\n```\n\nWhen `1fb2g` is baselined, both the `.sh` file and the `1fb2g-setup-eslint/` directory are deleted.\n\n## Directory Structure\n\n```\nyour-project/\n├── migrations/\n│   ├── history           # Tracks applied migrations and baseline (auto-generated)\n│   ├── 1fc2h-add-prettier.sh\n│   └── 1fc3h-configure-ci.ts\n└── ...\n```\n\n## Global Options\n\nThese options work with all commands:\n\n| Option | Description | Default |\n|--------|-------------|---------|\n| `-r, --root \u003cpath\u003e` | Project root directory | `.` |\n| `-m, --migrations \u003cpath\u003e` | Migrations directory | `migrations` |\n\n## Development\n\n```bash\ngit clone https://github.com/glideapps/migrate\ncd migrate\n./scripts/setup     # Enable git hooks, fetch deps, build, test\n\ncargo build         # Build debug binary\ncargo nextest run   # Run tests\ncargo fmt           # Format code\ncargo clippy        # Lint\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglideapps%2Fmigrate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fglideapps%2Fmigrate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglideapps%2Fmigrate/lists"}