π Automating GitLab Migration with Bash (Real Case Study + Open-Source Scripts)
Migrating multiple repositories between GitLab instances can quickly become a complex and repetitive process β especially when dealing with groups, subgroups, CI/CD pipelines, variables, tags, and issues.
To solve this challenge efficiently, I developed a collection of Bash automation scripts used to migrate projects from a self-hosted GitLab Community Edition to GitLab Enterprise (gitlab.com).
This post summarizes the approach, structure, and benefits, and the full toolkit is now open-source for the community.
π§ Why Automate the Migration?
When migrating large environments, manual work becomes:
- β Time-consuming
- β Error-prone
- β Hard to track or repeat
Automation ensures the process is:
- βοΈ Repeatable
- βοΈ Auditable
- βοΈ Safe
- βοΈ Scalable
- βοΈ Faster
π οΈ Whatβs Included in the Toolkit?
| Script | Purpose |
|---|---|
clone-projects.sh |
Clones all repositories from the source GitLab group |
replace_gitlab-ci.sh |
Updates .gitlab-ci.yml references for the new paths |
push-projects.sh |
Pushes branches and tags to the target GitLab instance |
migrar-variaveis.sh |
Migrates group-level environment variables via API |
migrar_issues.sh |
Migrates issues and comments preserving metadata |
delete-issues.sh |
Deletes issues when resetting staging/testing |
gitlab-clone-recursive.sh |
Clones nested groups and subgroups recursively |
gitlab-push-recursive.sh |
Pushes repositories and recreates missing subgroups automatically |
Each script contains:
- Validation logic
- Logging
- Backup behavior
- Idempotent execution (safe to rerun)
βοΈ How It Works (High-Level Workflow)
- Clone repositories from the source GitLab
- Apply CI/CD path replacements if needed
- Push repositories (branches + tags) to the destination
- Migrate variables, issues, and metadata
- Validate and finalize the migration
This flow supports incremental migration, useful for large environments.
π Full Source Code
GitHub repository:
π https://github.com/clcesarval/migrar-gitlab
π Final Result
Using this automation, we achieved:
- β Complete migration of all repositories
- β Preservation of history, branches, and tags
- β Reuse of CI/CD pipelines with minimal manual work
- β Controlled and repeatable process
π‘ Final note
This project was created after going through a real-world GitLab migration and realizing how difficult it was to find clear, complete, and automated guidance β especially one that covers repositories, CI/CD files, variables, branches, tags, and issues in a structured and safe way.
Since there was no fully documented or ready-to-use solution available, I decided to share what I learned and turn the entire process into reusable automation.
The first version of this project was built in Bash since my background is strongly focused on Linux automation and Shell scripting. It allowed me to move fast and keep the migration reliable. However, the long-term goal is to refactor and evolve this into Python β making the solution more flexible, maintainable, and modular for future improvements.
If you are interested in contributing, improving features, or helping with the Python rewrite, feel free to jump in β collaboration is welcome.
If this project saved you time, inspired a better approach, or helped even a little β then publishing it was worth it.
Together, we make the DevOps community stronger. π
If you're planning or performing a GitLab migration, feel free to fork, adapt, and contribute improvements.
π¬ Feedback and collaboration are welcome!
Top comments (0)