Multi-stage / configurable environments for CI build
Description
We use GitLab CI to automatically build and deploy our SaaS web app to our servers. All our customers have slightly varying builds. Customer A for example has an amber color design, while Customer B gets a blue color design.
These aren't settings that can be made at run time (e.g. environment variables on the server that the build gets deployed to), but have to be made during build time.
Currently we have a .gitlab-ci.yml
similar to this one:
stages:
- build
- deploy
.build: &build
stage: build
only:
- master
script:
- ember build --environment production --output-path dist/${CI_BUILD_REF}-${CI_BUILD_NAME}
- >
echo "{ \"targetHost\": \"${TARGET_HOST}\" }" > ./dist/${CI_BUILD_REF}-${CI_BUILD_NAME}/deployment.json
artifacts:
name: ${CI_PROJECT_NAME}-${CI_BUILD_REF}-${CI_BUILD_NAME}
paths:
- dist
expire_in: 30 days
customer-a.example.com:
<<: *build
variables:
TARGET_HOST: 100.100.101.11
CUSTOMER: customer-a
customer-b.example.com:
<<: *build
variables:
TARGET_HOST: 100.100.101.12
CUSTOMER: customer-b
deploy:
stage: deploy
only:
- master
image: $DOCKER_REGISTRY/web/frontend-deployment
variables:
MYSQL_USER: "$DEPLOYMENT_MYSQL_USER"
MYSQL_PASSWORD: "$DEPLOYMENT_MYSQL_PASSWORD"
MYSQL_DATABASE: "$DEPLOYMENT_MYSQL_DATABASE"
MYSQL_HOST: "$DEPLOYMENT_MYSQL_HOST"
SSH_KEY: "$DEPLOYMENT_SSH_KEY"
before_script: []
script:
- node --harmony /usr/src/app/server ./dist
Which would create this build pipeline.
Basically, a push to master
triggers n different builds (one for each customer configuration) inside their respective directories inside ./dist
. All these build artifacts are then passed to the deploy
stage:
$ ls ./dist
9ec75c165c83ae4ebaf2d267bea688a15c0a86d7-customer-a.example.com
9ec75c165c83ae4ebaf2d267bea688a15c0a86d7-customer-b.example.com
These directories contain the different builds alongside the generated deployment.json
which contains the TARGET_HOST
variable so the deployment script knows where to deploy the build.
This isn't ideal and feels unnecessarily clunky.
I was really excited when I read about the new Environments feature and was hoping I could use it to improve our current setup. I was especially psyched about the merge requests integration and dynamic links as our current deploy script already logs these links:
http://customer-a.example.com/?revisionKey=19ebf467c22c15149d0177bf44cf9964
http://customer-b.example.com/?revisionKey=8c83cd889bac342d84c461a206afde57
But as it turns out, environments may only be used for deploying the same build to different deployment targets.
Proposal
Not really sure. I see this more as a pitch for discussion.
What I would have expected under the name "Environments" is a way to define different "build and deploy targets" (for lack of a better name). I'd like a GUI or config file in which I could define these environments / targets, so that I don't have to create n jobs that extend <<: *build
. GitLab could auto-generate these virtual jobs.
Obviously I haven't given this much thought yet, but I'd like to see what others come up with and maybe revisit this later when I had time to think about it. Has someone experienced similar problems?