Building on release?

Replace this template with your information

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.

1 Like