CI jobs to bootstrap a new project created from a custom project template
Problem to solve
GitLab 11.2 introduced instance-level custom project templates. Templates avoid the tedious task of setting up new projects from scratch. However, there can be details in projects created from templates that still need manual updating.
For example, my projects have Docker Compose files that use GitLab CI predefined variables. A set of statically defined equivalents exist in a
.env file in the repository so that projects work on developers' local environments. Here are the contents from a template project.
DEPLOYMENT_NAMESPACE=api COMPOSE_FILE=components/service.yml:components/development.yml CI_REGISTRY=registry-dev.transzap.com CI_APPLICATION_REPOSITORY=registry-dev.transzap.com/templates/api-spring-boot CI_APPLICATION_TAG=master CI_ENVIRONMENT_HOST=localhost CI_ENVIRONMENT_PATH=/api TRAEFIK_NETWORK=traefik
When a new project is created from the template project, developers have to manually update items such as the value of
CI_APPLICATION_REPOSITORY for the new project.
I'm interested in defining one or more CI jobs that can be set to run only when a project is created from a template. This would allow me to bootstrap new projects that have been created from templates. Here is an example job.
update-env: stage: bootstrap script: - sed -i "s|registry-dev.transzap.com/templates/api-spring-boot|$CI_APPLICATION_TAG|g" .env
update-env CI job uses sed to update the value of
CI_APPLICATION_TAG in the repository's
.env file. It is part of the
bootstrap stage, which is a special stage whose jobs are only run when a project is created from a project template. There can be more than one job in the bootstrap stage.
The jobs in the bootstrap stage are run against a branch created from the project's default branch (typically
master). The result of each job will be a commit on that branch. The conceptual flow is:
- A project is created from a template project.
- If there are CI jobs in the
bootstrapstage, create a new branch from the project's default branch (
- For each CI job in the
- Run the CI job.
- Commit to the branch.
- Create a merge request from the branch to the default branch.
Developers can review the merge request, make further changes if desired, and then merge it to finish the bootstrap process.
One potential problem with the described flow is that the commit order across multiple bootstrap jobs is not deterministic.
What does success look like, and how can we measure that?
When a new project is created from a template project, it should automatically prepare its files as necessary. The only thing a developer has to do is accept the merge request with any required changes.