Empower Your Users to Migrate Their Own Repositories
Free your admins from migration bottlenecks. This framework enables GitHub users to migrate their own repositories through a guided, self-service workflowβwhile maintaining enterprise-grade security, access controls, and governance.
Built on GitHub Enterprise Importer (GEI) with intelligent batching, parallel processing, and comprehensive asset transfer. Supports GHES-to-GHEC, GHEC-to-GHEC, and EMU migrations with role-based access control, dry-run validation, and automatic feature detection.
| Document | Description |
|---|---|
| π README.md | Framework overview, features, and architecture (you are here) |
| π οΈ SETUP.md | Complete setup guide from prerequisites to first migration |
| π USAGE.md | How to run migrations with the 4-step guided workflow |
| π UPDATING.md | Keep your framework up-to-date with latest features |
New to this framework? Start with SETUP.md for step-by-step installation and configuration.
Ready to migrate? See USAGE.md for the complete migration workflow.
Using this as a template? See UPDATING.md for how to receive framework updates while preserving your configuration.
| Feature | Description | Benefit |
|---|---|---|
| π Issue-Driven Workflow | Users create migration requests through GitHub Issues | No admin bottleneckβusers own their migrations |
| π Role-Based Access Control | Fine-grained permissions per organization via instances.json |
Users only see what they're authorized to migrate |
| π§ͺ Safe Testing | Dry-run mode validates before production | Users can test migrations risk-free |
| π Real-Time Visibility | Progress updates posted automatically to issues | Complete transparencyβno "black box" migrations |
| Feature | Description |
|---|---|
| π’ Multi-Instance Architecture | Support for multiple GHES and GHEC instances with centralized configuration |
| π¦ Smart Batching | Automatically splits large migrations into 250-repo chunks (configurable to 256 max) |
| β‘ Parallel Execution | Up to 10 concurrent repository migrations per batch (GEI limit) |
| π Sequential Processing | Reliable batch-by-batch execution with comprehensive progress tracking |
| πΎ Complete Data Transfer | Git history, LFS, packages, releases, secrets, variables, and environments |
| π Production Mode | Secure migration with automatic source repository locking |
| π₯ User Mapping | Automatic mannequin-to-user account mapping with CSV support |
| π§Ή Cleanup Tools | Commands for dry-run cleanup and repository deletion |
| π Cancellation Support | Stop migrations gracefully with /cancel-migration command |
First time setup? Follow the complete SETUP.md guide for detailed installation instructions.
For Admins (One-Time Setup):
- β GitHub Enterprise Cloud organization (target)
- β Admin access to source and target instances
- β Self-hosted GitHub Actions runners (Ubuntu 24.04, 16+ cores, 32GB+ RAM)
- β Cloud storage (Azure Blob or AWS S3) for GEI backend
- β
Configure
instances.jsonwith organizations and authorized users
For Users (Self-Service Migration):
- β
GitHub account with access granted in
instances.json - β Knowledge of which repositories to migrate
- β Ability to create issues in the migration framework repository
π Complete setup guide: See SETUP.md for step-by-step installation instructions.
Once your framework is set up, users can migrate their own repositories using the 4-step guided workflow:
- Create Migration Issue - Select source and target instances
- Select Organizations - Choose which orgs to migrate between
- Provide Repository URLs - List the repositories to migrate
- Execute Migration - Run dry-run test or production migration
The system provides real-time progress updates and handles batching, parallelization, and feature detection automaticallyβno admin intervention required.
π Complete migration guide: See USAGE.md for detailed instructions.
| Command | Purpose |
|---|---|
/run-dry-run-migration |
Test migration safely (recommended first) |
/run-production-migration |
Execute production migration |
/delete-dry-run |
Clean up dry-run test repositories |
/cancel-migration |
Stop an ongoing migration |
CRITICAL: This system requires self-hosted GitHub Actions runners for batch processing. GitHub-hosted runners are only used for orchestration.
The migration system uses a three-tier runner architecture:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Tier 1: Orchestration (GitHub-hosted) β
β ββ Creates batches β
β ββ Dispatches workflows β
β ββ Posts progress updates β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Tier 2: Batch Processing (Self-hosted) β
β ββ Runs GEI migrations (10 parallel) β
β ββ Detects features (LFS, packages, etc.) β
β ββ Triggers feature migrations β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Tier 3: Feature Migrations (Self-hosted) β
β ββ LFS data transfer β
β ββ Packages migration β
β ββ Releases migration β
β ββ Secrets/Variables migration β
β ββ Environments migration β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Component | Runner Type | Quantity | Purpose |
|---|---|---|---|
| Orchestrator | Self-hosted | 1 | Batch creation, sequencing, progress updates |
| Batch Processing | Self-hosted | 1-10 | GEI repository migrations (10 for max concurrency) |
| Feature Migrations | Self-hosted | 0-10+ | LFS, packages, releases, environments |
Total Runners for Full Concurrency: 11 (1 orchestrator + 10 batch processors)
Option 1: Single Server (Recommended for most)
Server: Ubuntu 24.04, 32 cores, 64GB RAM, 1TB SSD
ββ 11 runner processes (all labeled: self-hosted)
ββ 1 runner: Orchestration
ββ 10 runners: Batch processing (max concurrency)
ββ Shared /opt/migration cache directory
π For complete runner installation instructions: See SETUP.md - Set Up Self-Hosted Runners
GEI requires cloud storage for temporary migration data:
| Backend | Configuration | When to Use |
|---|---|---|
| Azure Blob | AZURE_STORAGE_CONNECTION_STRING secret |
Azure infrastructure |
| AWS S3 | AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY secretsAWS_REGION + AWS_BUCKET_NAME variables |
AWS infrastructure |
Location: /opt/migration (configurable via LOCAL_CACHE_DIR variable)
Purpose: Speeds up feature detection and migration by caching:
- Package metadata
- Release data
- Environment configurations
- LFS detection results
Who needs it: Self-hosted runners running batch processing and feature migrations
π For complete storage setup: See SETUP.md - Configure Storage Backend
Control how many repositories are processed per batch:
Location: .github/workflows/trigger.yml
with:
BATCH_SIZE: 250 # Default: 250, Max: 256 (GitHub Actions matrix limit)Considerations:
- Larger batches = fewer sequential batch executions
- Maximum is 256 (GitHub Actions matrix size limit)
- Batch size doesn't affect parallelism (always max 10 concurrent per batch)
Control concurrent migrations per batch:
Location: .github/workflows/batch-processor.yml
strategy:
max-parallel: 10 # GEI hard limit, do not exceedImportant:
β οΈ Do not exceed 10 - this is a GEI CLI limitation- Each parallel job migrates one repository
- With 10 runners + max-parallel: 10, you get full parallelization
For large repositories or slow networks:
Location: .github/workflows/batch-processor.yml
timeout-minutes: 50400 # 35 days (GitHub Actions maximum)Guidelines:
- Default: 50400 minutes (35 days)
- Adjust based on largest repository size
- Includes time for LFS transfers and feature migrations
Add additional GitHub instances to instances.json:
{
"sources": {
"GHES-PROD": {
"hostname": "ghes-prod.company.com",
"tokenSecret": "GHES_PROD_TOKEN",
"orgs": {...}
},
"GHES-DEV": {
"hostname": "ghes-dev.company.com",
"tokenSecret": "GHES_DEV_TOKEN",
"orgs": {...}
},
"GHEC-ORG1": {
"hostname": "github.com",
"tokenSecret": "GHEC_ORG1_TOKEN",
"orgs": {...}
}
},
"targets": {
"GHEC-EMU-PROD": {...},
"GHEC-EMU-TEST": {...}
}
}Then update the issue template (.github/ISSUE_TEMPLATE/gei-batch-migrations.yml):
- type: dropdown
id: source-instance
attributes:
label: π Source Instance
options:
- "GHES-PROD"
- "GHES-DEV"
- "GHEC-ORG1"Fully automated - no configuration needed!
How it works:
- β Batch processor detects repository variables and secrets
- β Triggers variables-secrets.yml workflow automatically
- β Migrates variables with actual values
β οΈ Creates placeholder secrets (security requirement)
Post-migration:
- Review placeholder secrets:
https://github.com/TARGET_ORG/REPO/settings/secrets/actions - Update with actual values manually
- Verify variables migrated correctly
Security Note: GitHub API doesn't allow reading secret values, only names. Placeholders must be manually updated.
Fully automated - environments are detected and migrated automatically!
What's Migrated:
- β Environment names and settings
- β Protection rules (wait timers, required reviewers)
- β Deployment branch policies
- β Custom protection rules
β οΈ Environment secrets (as placeholders, like repo secrets)
Prerequisites:
- Target repositories must exist (β done via main migration)
- Environments CSV must be in cache (β auto-generated or pre-cached)
Verification:
Check migrated environments at: https://github.com/TARGET_ORG/REPO/settings/environments
LFS Migration:
- Detected automatically via
.gitattributesfile - Optional: Pre-populate
${LOCAL_CACHE_DIR}/${ORG}_lfs.csvfor tracking - Uses
gh-migrate-lfstool
Packages Migration:
- Detected from cached package exports
- Requires
LOCAL_CACHE_DIRwith package CSV files - Supports: npm, Maven, NuGet, Docker, RubyGems
Releases Migration:
- Detected from cached release data in
LOCAL_CACHE_DIR - Migrates: Release notes, assets, tags
- Preserves: Draft status, prerelease flags
Default behavior: Set via issue template dropdown
Advanced: Modify batch-processor.yml for custom logic:
env:
VISIBILITY: ${{ github.event.client_payload.batch.targetRepositoryVisibility }}Options:
Private- All migrated repos are privateInternal- All repos are internal (requires EMU or GHEC)Mirror- Preserves source visibility (custom implementation required)
π΄ Migration Won't Start
Symptoms:
- No response after posting migration command
- Workflows don't trigger
Checklist:
- β Verify you completed all 4 steps of the guided workflow
- β
Check PAT permissions (must include
repo,admin:org,workflow) - β
Ensure secrets names match
instances.jsontokenSecret values - β
Confirm issue has
migrationandbatchlabels - β Verify at least 1 self-hosted runner is online
- β Check Actions tab for workflow errors
Debug Commands:
# Verify secrets are configured
gh secret list --repo YOUR-ORG/migraction
# Check runner status
# Go to: https://github.com/YOUR-ORG/migraction/settings/actions/runnersπ‘ Batch Processing Stops or Times Out
Symptoms:
- Batch workflow starts but doesn't complete
- "Job was cancelled" errors
Steps:
- Check Actions tab β Select failed workflow β Review logs
- Verify runner availability:
- Go to Settings β Actions β Runners
- Ensure runners show "Idle" (green) not "Offline" (gray)
- Check runner logs on the server:
# View runner logs cat ~/actions-runner-1/_diag/Runner_*.log
- Verify GEI CLI is installed:
gei --version # If not found, set INSTALL_PREREQS=true - Check API rate limits:
gh api rate_limit --token $YOUR_TOKEN - Re-run failed batch from Actions tab
π΅ Features Not Migrating (LFS/Packages/Releases)
Symptoms:
- Main migration succeeds but features missing
- No LFS objects, packages, or releases in target
Diagnosis:
-
Check if features were detected:
- Go to Actions β Batch workflow logs
- Look for "Detect features requiring additional migration steps"
- Check output:
lfs=true,packages=true,releases=true
-
Verify LOCAL_CACHE_DIR:
# On runner machine ls -la /opt/migration/ # Should contain: packages/, releases/, *_environments.csv
-
Check feature workflow triggering:
- Go to Actions β Filter by workflow (lfs.yml, packages.yml, etc.)
- Verify workflows were dispatched
-
Pre-cache data (recommended for large migrations):
# Use gh-migrate-* tools to pre-populate cache gh extension install mona-actions/gh-migrate-releases gh migrate-releases export --source-org ORG --cache-dir /opt/migration
π Access Denied or Authorization Errors
Symptoms:
- "User does not have access" message
- Organization checkboxes don't appear
- "Unknown source instance" errors
Resolution:
-
Verify user is in allowedUsers:
// Check .github/scripts/config/instances.json { "sources": { "GHES": { "orgs": { "engineering": { "allowedUsers": ["YOUR-USERNAME", "..."] } } } } }
-
Validate instances.json:
node .github/scripts/config/validate.js
- Instance config: `"tokenSecret": "GHES_PROD_TOKEN"`
- GitHub Secret: Must be named exactly `GHES_PROD_TOKEN`
</details>
<details>
<summary>π£ <strong>Secrets/Variables Not Migrating Correctly</strong></summary>
**Expected Behavior:**
- β
Variables: Migrate with actual values
- β οΈ Secrets: Migrate as placeholders (security limitation)
**Why?**
GitHub API doesn't allow reading secret values, only names. This is by design for security.
**Post-Migration Actions:**
1. Go to target repo: `https://github.com/TARGET_ORG/REPO/settings/secrets/actions`
2. Update each placeholder secret with actual value
3. Verify variables at: `https://github.com/TARGET_ORG/REPO/settings/variables/actions`
</details>
<details>
<summary>β« <strong>Runner Out of Disk Space</strong></summary>
**Symptoms:**
- "No space left on device" errors
- LFS migrations fail
- Workflows crash unexpectedly
**Resolution:**
1. **Check disk usage:**
```bash
df -h /opt/migration
du -sh /opt/migration/*
-
Clean up old migrations:
# Remove old cache data sudo rm -rf /opt/migration/old-migration-* # Clean up GEI archives sudo find /opt/migration -name "*.tar.gz" -mtime +7 -delete
-
Increase disk space or move cache:
# Option 1: Mount larger volume to /opt/migration # Option 2: Change LOCAL_CACHE_DIR variable to new location # Settings β Variables β LOCAL_CACHE_DIR β /mnt/large-disk/migration
-
Stagger migrations: Run smaller batches to reduce concurrent disk usage
Stop an ongoing migration:
/cancel-migration
Posts comment to issue, workflows must be manually cancelled in Actions tab.
Clean up dry-run repositories:
/delete-dry-run
Delete specific repositories:
/delete-repositories
Re-run a specific failed batch:
- Go to Actions tab
- Find the failed batch workflow (e.g., "Migration Batch 3")
- Click "Re-run failed jobs" or "Re-run all jobs"
- Monitor progress in issue comments
Before opening a support issue, collect:
**Environment:**
- [ ] Number of repositories: ___
- [ ] Source instance: GHES / GHEC / Other
- [ ] Target instance: GHEC / GHEC EMU
- [ ] Number of self-hosted runners: ___
- [ ] Runner OS: Linux / Windows / macOS
**Configuration:**
- [ ] INSTALL_PREREQS value: ___
- [ ] BATCH_SIZE: ___
- [ ] max-parallel: ___
- [ ] Storage backend: Azure / AWS
**Issue Details:**
- [ ] Workflow run URL: ___
- [ ] Error messages: ___
- [ ] Issue number: #___
- [ ] Batch number (if applicable): ___
**Logs:**
- [ ] Attached workflow logs (Actions β Select run β Download logs)
- [ ] Runner logs (if available)Enable verbose logging:
Edit .github/workflows/batch-processor.yml:
- name: Execute GEI migration
run: |
# Add --verbose flag
gei migrate-repo \
--verbose \
--github-source-org $SOURCE_ORG \
...Test GEI manually:
# Test single repository migration
gei migrate-repo \
--github-source-org source-org \
--source-repo test-repo \
--github-target-org target-org \
--target-repo test-repo \
--github-source-pat $SOURCE_TOKEN \
--github-target-pat $TARGET_TOKENValidate token permissions:
# Test source token
gh auth status --hostname ghes.company.com
# Test target token
gh auth status
# Check org access
gh api /orgs/YOUR-ORG --hostname ghes.company.comβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β End Users (Self-Service Interface) β
β ββ Create migration issue via GitHub UI β
β ββ Select source/target organizations (filtered by access) β
β ββ Provide repository URLs to migrate β
β ββ Execute migrations with simple commands β
β ββ Monitor progress in real-time β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Access Control & Validation (instances.json) β
β ββ Filters organizations by user permissions β
β ββ Validates source/target configuration β
β ββ Ensures repos match selected organization β
β ββ Enforces role-based access control β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Orchestrator (GitHub-hosted: ubuntu-latest) β
β ββ Resolves tokens from instances.json config β
β ββ Creates batches (250 repos each) β
β ββ Dispatches batches sequentially β
β ββ Posts progress updates to issue β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Batch Processor (Self-hosted: 1-10 runners) β
β ββ Parallel execution (max 10 concurrent) β
β ββ GEI repository migration β
β ββ Feature detection (LFS, packages, releases, etc.) β
β ββ Triggers feature migrations β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Feature Migrations (Self-hosted: 0-10+ runners) β
β ββ Variables & Secrets β variables-secrets.yml β
β ββ LFS Objects β lfs.yml β
β ββ Packages β packages.yml β
β ββ Releases β releases.yml β
β ββ Environments β environments.yml β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Reporting & Completion β
β ββ Batch status updates posted to issue β
β ββ Feature migration reports β
β ββ Final summary with statistics β
β ββ Next steps and post-migration checklist β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
For Admins:
- π― Eliminate bottlenecks: No more fielding individual migration requests
- β° Save time: Users handle their own migrations
- π Maintain control: Define who can migrate what via
instances.json - π Full visibility: Monitor all migrations from Actions tab
- π‘οΈ Security maintained: Token security, access controls, and audit trails
For Users:
- π Move at your pace: Migrate when it's convenient for you
- π§ͺ Test safely: Dry-run migrations before production
- π Complete transparency: Real-time progress in your issue
- π― Simple process: Guided 4-step workflow
- π Self-documented: Issue comments provide automatic audit trail
sequenceDiagram
autonumber
participant User
participant Issue
participant Access Control
participant Orchestrator
participant Batch Processor
participant GEI
participant Feature Workflows
participant Target
User->>Issue: Create issue + select instances
Issue->>Access Control: Validate user access
Access Control-->>Issue: Post allowed organizations
User->>Issue: Select orgs via checkboxes
Issue->>Access Control: Validate selection
Access Control-->>Issue: Post repo URL instructions
User->>Issue: Post repository URLs
Issue->>Access Control: Validate URLs
Access Control-->>Issue: Post migration commands
User->>Issue: /run-dry-run-migration
Issue->>Orchestrator: Trigger workflow
Orchestrator->>Orchestrator: Resolve tokens (instances.json)
Orchestrator->>Orchestrator: Create batches (250 each)
loop Each Batch (Sequential)
Orchestrator->>Batch Processor: Dispatch batch
loop 10 parallel repos
Batch Processor->>GEI: Migrate repo
GEI->>Target: Transfer git data
Target-->>GEI: Complete
GEI-->>Batch Processor: Success
Batch Processor->>Batch Processor: Detect features
opt Has LFS/Packages/Releases/Secrets
Batch Processor->>Feature Workflows: Trigger migration
Feature Workflows->>Target: Transfer assets
Target-->>Feature Workflows: Complete
end
end
Batch Processor-->>Orchestrator: Batch complete
Orchestrator->>Issue: Progress update
end
Orchestrator-->>Issue: Migration complete
Issue-->>User: Summary report
| Workflow | Trigger | Runner Type | Purpose |
|---|---|---|---|
| prepare.yml | Issue opened/edited | ubuntu-latest |
Parse issue, validate access, post org selection |
| on-checkbox-edit.yml | Issue comment created/edited | ubuntu-latest |
Detect org selection, post Step 3 |
| parse-repos.yml | Issue comment | ubuntu-latest |
Parse repository URLs, post Step 4 |
| trigger.yml | Issue comment (/run-*-migration) |
ubuntu-latest |
Validate setup, trigger orchestrator |
| orchestrator.yml | Called by trigger.yml | ubuntu-latest |
Create batches, dispatch sequentially |
| batch-processor.yml | Repository dispatch | self-hosted |
Run GEI migrations (10 parallel) |
| variables-secrets.yml | Workflow dispatch | self-hosted |
Migrate repo variables & secrets |
| lfs.yml | Workflow dispatch | self-hosted |
Migrate LFS objects |
| packages.yml | Workflow dispatch | self-hosted |
Migrate packages |
| releases.yml | Workflow dispatch | self-hosted |
Migrate releases |
| environments.yml | Workflow dispatch | self-hosted |
Migrate deployment environments |
| delete.yml | Issue comment (/delete-*) |
ubuntu-latest |
Cleanup workflows |
ββββββββββββββββββββ
β instances.json β β Configuration: instances, orgs, users, tokens
ββββββββββ¬ββββββββββ
β
β
ββββββββββββββββββββ
β GitHub Secrets β β Tokens: GHES_PROD_TOKEN, GHEC_EMU_TOKEN, etc.
ββββββββββ¬ββββββββββ
β
β
ββββββββββββββββββββ
β Orchestrator β β Resolves tokens, creates batches
ββββββββββ¬ββββββββββ
β
β
ββββββββββββββββββββ
β Batch Dispatch β β repository_dispatch event with payload
ββββββββββ¬ββββββββββ
β
β
ββββββββββββββββββββ
β Batch Processor β β Receives: repos, tokens, org names
ββββββββββ¬ββββββββββ
β
ββββ GEI CLI βββ Cloud Storage (Azure/S3) βββ Target Repo
β
ββββ Feature Detection βββ LOCAL_CACHE_DIR (/opt/migration)
β
ββββ Trigger Feature Workflows
β οΈ Important: These are general guidelines only. Actual migration times vary greatly based on repository size, complexity, commit history, LFS data, and network conditions. Always run a dry-run migration first to get accurate timing for your specific repositories.
| Scale | Repositories | Batches | Est. Time | Workers |
|---|---|---|---|---|
| Small | 1-50 | 1 | 5-50 min | 10 parallel |
| Medium | 51-250 | 1 | 50-250 min | 10 parallel |
| Large | 251-1000 | 4 | 4-17 hours | 10 parallel |
| Enterprise | 1001-5000 | 20 | 17-84 hours | 10 parallel |
Time Calculation:
Total Time = (Total Repos Γ· 10 parallel) Γ Avg Time per Batch
+ (Number of Batches Γ Batch Overhead)
Where:
- 10 repos in parallel: ~10 minutes (average-sized repos)
- Avg per repo: ~1 minute when running 10 parallel
- Batch Overhead: ~2 minutes per batch
- Large/complex repos: May take significantly longer
- LFS repos: Add 30+ minutes depending on data volume
Factors Affecting Performance:
- π’ Repository size and complexity
- πΎ LFS data volume
- π¦ Number of packages
- π Network bandwidth
- π₯οΈ Runner specifications
- β‘ Whether data is pre-cached
PAT Management:
- π Store all tokens in GitHub Secrets (never in code or config files)
- π Rotate tokens after each major migration
- π Set token expiration dates (recommended: 90 days)
- π― Use minimum required permissions (see Setup)
- π₯ Create service account tokens (don't use personal tokens)
Required Scopes:
repo # Full control of repositories
admin:org # Full control of orgs and teams
workflow # Update GitHub Actions workflows
Token Storage Pattern:
// instances.json references secret names:
"tokenSecret": "GHES_PROD_TOKEN"
// Actual token stored in GitHub Secrets:
Settings β Secrets β Actions β GHES_PROD_TOKEN = "ghp_xxxxxxxxxxxx"Role-Based Access via instances.json:
{
"sources": {
"GHES": {
"orgs": {
"sensitive-org": {
"allowedUsers": ["admin1", "admin2"] // Restricted access
},
"general-org": {
"allowedUsers": ["admin1", "admin2", "dev-team", "migration-team"]
}
}
}
}
}Best Practices:
- π Limit
allowedUsersto minimum necessary personnel - π₯ Create dedicated migration teams
- π Use groups or team names (document mapping separately)
- π Review access quarterly
- π Audit who has modified instances.json (git history)
During Migration:
- πͺ Restrict issue creation to authorized teams
- π Production migrations lock source repositories
- ποΈ Monitor Actions workflow runs
- π Review migration logs for anomalies
In-Flight Data:
- ποΈ GEI uses cloud storage (Azure/S3) for temporary archives
- π Ensure storage accounts use encryption at rest
- π Use private endpoints for storage (if available)
- β° Configure lifecycle policies to auto-delete old archives (30 days)
Local Cache (/opt/migration):
- π Contains metadata and feature exports (not full repo data)
- π Set appropriate filesystem permissions (755)
- π§Ή Clean up after successful migrations
### π Audit & Compliance
**Logging:**
- π All migration actions logged in GitHub Actions workflows
- π¬ Issue comments provide audit trail
- π Workflow run history retained (default: 90 days)
**Compliance Considerations:**
- π Document migrations in change management system
- β
Obtain necessary approvals before production migrations
- π Generate reports from issue comments and workflow summaries
- π Ensure GDPR/privacy compliance (user mappings contain PII)
**Audit Checklist:**
```markdown
Pre-Migration:
- [ ] Tokens reviewed and validated
- [ ] Access control verified in instances.json
- [ ] Storage encryption enabled
- [ ] Approvals obtained
During Migration:
- [ ] Monitor workflow runs
- [ ] Review progress updates
- [ ] Check for errors or anomalies
Post-Migration:
- [ ] Verify data integrity
- [ ] Clean up temporary data
- [ ] Rotate tokens
- [ ] Document completion
- π GitHub Enterprise Importer (GEI) Official Docs
- π§ GEI CLI Repository
- π Migration Best Practices
- π Managing PATs
- gh-migrate-releases - Release migration tool
- gh-migrate-lfs - LFS migration tool
- gh-migrate-packages - Package migration tool
- gh-migrate-environments - Environment migration tool
Before opening an issue:
- π Review this README thoroughly
- π Check the Troubleshooting section
- π Review workflow logs in the Actions tab
- π§ͺ Test with a small dry-run migration first
Contributions to the framework are welcome! Please:
- π Fork the repository (for contributions only - users should use templates)
- πΏ Create a feature branch
- β Test your changes thoroughly
- π Update documentation
- π Submit a pull request to the main repository
Note: End users should use "Use this template" rather than forking. See UPDATING.md for details.
This project is provided as-is for use in GitHub migrations. Refer to your organization's policies for usage guidelines.
π― Empower Your Users | π§ Self-Service Migration | π‘οΈ Enterprise Controls
Made with β€οΈ for GitHub Enterprise Migrations