We have an existing GitLab CI build configuration, which includes creating a Docker image, though we would like to have it run when a release is made and then have the docker image use the version number of that release. Can anyone suggest how to go about this?
We are using a GitLab hosted runner.
I have looked around the docs, but I haven’t found anything yet
The gitlab-ci.yml file contents:
stages:
- tests
- docker-build
docker-build:
# Use the official docker image.
image: docker:latest
stage: docker-build
services:
- docker:dind
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
# Default branch leaves tag empty (= latest tag)
# All other branches are tagged with the escaped branch name (commit ref slug)
script:
- |
if [[ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]]; then
tag=""
echo "Running on default branch '$CI_DEFAULT_BRANCH': tag = 'latest'"
else
tag=":$CI_COMMIT_REF_SLUG"
echo "Running on branch '$CI_COMMIT_BRANCH': tag = $tag"
fi
- docker build --pull -t "$CI_REGISTRY_IMAGE${tag}" .
- docker push "$CI_REGISTRY_IMAGE${tag}"
# Run this job in a branch where a Dockerfile exists
rules:
- if: $CI_COMMIT_BRANCH
exists:
- Dockerfile
all-tests:
stage: tests
variables:
ENV: devci
NODE_ENV: "test"
image: node:10.16.3
cache:
key: "$CI_BUILD_REF_NAME"
paths:
- node_modules/
services:
- mongo
script:
- npm install
- npm run lint
- npm run build
# - npm run test-ci
This is the configuration I ended up coming up with, based on the starting point:
stages:
- tests
- docker-build
- docker-release-build
docker-dev-build:
# Use the official docker image.
image: docker:latest
stage: docker-build
services:
- docker:dind
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
# Default branch leaves tag empty (= latest tag)
# All other branches are tagged with the escaped branch name (commit ref slug)
script:
- |
if [[ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]]; then
tag=""
echo "Running on default branch '$CI_DEFAULT_BRANCH': tag = 'latest'"
else
tag=":$CI_COMMIT_REF_SLUG"
echo "Running on branch '$CI_COMMIT_BRANCH': tag = $tag"
fi
- docker build --pull -t "$CI_REGISTRY_IMAGE${tag}" .
- docker push "$CI_REGISTRY_IMAGE${tag}"
# Run this job in a branch where a Dockerfile exists
rules:
- if: $CI_COMMIT_TAG
when: never
- if: $CI_COMMIT_BRANCH
exists:
- Dockerfile
docker-release-build:
# Use the official docker image.
image: docker:latest
stage: docker-build
services:
- docker:dind
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
# Default branch leaves tag empty (= latest tag)
# All other branches are tagged with the escaped branch name (commit ref slug)
# Note: there is not $CI_COMMIT_BRANCH when $CI_COMMIT_TAG is passed by CI
script:
- env
- export
- |
tag=":$CI_COMMIT_TAG"
echo "Running release build for tag $tag"
- docker build --pull -t "$CI_REGISTRY_IMAGE${tag}" .
- docker push "$CI_REGISTRY_IMAGE${tag}"
rules:
- if: $CI_COMMIT_TAG =~ /^v\d+.\d+.\d+/
exists:
- Dockerfile
all-tests:
stage: tests
variables:
ENV: devci
NODE_ENV: "test"
image: node:10.16.3
cache:
key: "$CI_BUILD_REF_NAME"
paths:
- node_modules/
services:
- mongo
script:
- npm install
- npm run lint
- npm run build
# - npm run test-ci
The main thing is that I needed to create a second block for ‘release’ and also take into account that tags and branches are mutually exclusive during builds.