Build on Tag Commit
Currently, the docker image builds on every commit (except documentation folder). This allows updating the latest version tag with new changes and bug fixes as the come. However, this type of release cycle can be difficult to understand, as the latest version tag changes, which should not happen.
Below gitlab ci would only build on new tag commits:
stages:
- validate
- release
- docs
- deploy
# This is a hidden job that acts as a template for all Docker build-and-push jobs.
# It uses YAML anchors (&) so we can reuse this logic with extends (*).
.docker_build_template: &docker_build_template
image: docker:latest
tags:
- dind-runner
before_script:
# Login to both registries.
- echo "$CI_JOB_TOKEN" | docker login --username gitlab-ci-token --password-stdin $CI_REGISTRY
- echo "$QUAY_PASSWORD" | docker login -u "$QUAY_USERNAME" --password-stdin quay.io
rules:
# This rule ensures these jobs ONLY run when a Git tag is pushed.
- if: $CI_COMMIT_TAG
# This job runs on EVERY branch commit. It builds all Docker images to ensure
# the Dockerfiles are not broken, but it does NOT push them. This is your CI check.
validate_dockerfiles:
stage: validate
image: docker:latest
tags:
- dind-runner
script:
- echo "Validating Dockerfiles by building them..."
- docker build --pull -t temp-image-main .
- docker build --pull -t temp-image-mapnik ./mapnik
- docker build --pull -t temp-image-r ./r
- echo "All Dockerfiles built successfully."
rules:
# Run this on any branch commit, but NOT on tags.
- if: $CI_COMMIT_BRANCH
# This job builds and pushes the main/latest/stable Jupyter image.
release:main:
stage: release
<<: *docker_build_template # This extends the template
script:
- VERSION=$CI_COMMIT_TAG
- echo "Releasing main image with version $VERSION"
- docker build --pull --build-arg VERSION=$VERSION --tag $CI_REGISTRY_IMAGE:$VERSION --tag $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:stable .
- docker push $CI_REGISTRY_IMAGE --all-tags
# Tag and push to quay.io
- docker tag $CI_REGISTRY_IMAGE:$VERSION quay.io/ioer-fdz/carto-lab-docker:$VERSION
- docker tag $CI_REGISTRY_IMAGE:latest quay.io/ioer-fdz/carto-lab-docker:latest
- docker tag $CI_REGISTRY_IMAGE:stable quay.io/ioer-fdz/carto-lab-docker:stable
- docker push quay.io/ioer-fdz/carto-lab-docker:$VERSION
- docker push quay.io/ioer-fdz/carto-lab-docker:latest
- docker push quay.io/ioer-fdz/carto-lab-docker:stable
# This job builds and pushes the Mapnik variant.
release:mapnik:
stage: release
<<: *docker_build_template # This extends the template
script:
- VERSION=$CI_COMMIT_TAG
- echo "Releasing mapnik variant with version $VERSION"
- docker build --pull --build-arg VERSION=$VERSION --tag $CI_REGISTRY_IMAGE:mapnik_$VERSION --tag $CI_REGISTRY_IMAGE:mapnik ./mapnik
- docker push $CI_REGISTRY_IMAGE --all-tags
# Tag and push to quay.io
- docker tag $CI_REGISTRY_IMAGE:mapnik_$VERSION quay.io/ioer-fdz/carto-lab-docker:mapnik_$VERSION
- docker tag $CI_REGISTRY_IMAGE:mapnik quay.io/ioer-fdz/carto-lab-docker:mapnik
- docker push quay.io/ioer-fdz/carto-lab-docker:mapnik_$VERSION
- docker push quay.io/ioer-fdz/carto-lab-docker:mapnik
# This job builds and pushes the R variant.
release:r:
stage: release
<<: *docker_build_template # This extends the template
script:
- VERSION=$CI_COMMIT_TAG
- echo "Releasing R variant with version $VERSION"
- docker build --pull --build-arg VERSION=$VERSION --tag $CI_REGISTRY_IMAGE:r_$VERSION --tag $CI_REGISTRY_IMAGE:r ./r
- docker push $CI_REGISTRY_IMAGE --all-tags
# Tag and push to quay.io
- docker tag $CI_REGISTRY_IMAGE:r_$VERSION quay.io/ioer-fdz/carto-lab-docker:r_$VERSION
- docker tag $CI_REGISTRY_IMAGE:r quay.io/ioer-fdz/carto-lab-docker:r
- docker push quay.io/ioer-fdz/carto-lab-docker:r_$VERSION
- docker push quay.io/ioer-fdz/carto-lab-docker:r
# --- Documentation Jobs (Largely Unchanged) ---
docs:artifacts:
stage: docs
image: "registry.gitlab.vgiscience.org/tud_ifk/miniconda-cidefault:0.5.1"
before_script:
- conda init bash
- source ~/.bashrc
- conda activate ci_env
script:
- cp CHANGELOG.md docs/changelog.md
# IMPORTANT: Changed versioning to use the Git tag for consistency.
- git fetch --tags
- version_var=$(git describe --tags --abbrev=0)
- echo "Version for badges $version_var"
- anybadge -l version --value="${version_var}" --file=version.svg --color=#0970B9
- anybadge -l mkdocs --value="Documentation" --file=documentation.svg --color=green
artifacts:
paths:
- '*.svg'
- docs/changelog.md
rules:
# Run this on the main branch OR on tags.
- if: $CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "master-latest" || $CI_COMMIT_TAG
docs:build:
stage: docs
image: registry.gitlab.vgiscience.org/tools/mkdocs:0.1.0
script:
- mkdocs build
- cp *.svg "site/"
artifacts:
name: site
paths:
- site
rules:
- if: $CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "master-latest" || $CI_COMMIT_TAG
deploy:docs:
stage: deploy
image: "registry.gitlab.vgiscience.org/tud_ifk/rsync-ssh-alpine:alpine3.17-r0-v4"
# This job depends on artifacts from the docs build job.
dependencies:
- docs:build
before_script:
- eval $(ssh-agent -s)
- echo "${SSH_PRIVKEY}" | ssh-add -
- mkdir -p ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\tLogLevel QUIET\n\n" > ~/.ssh/config'
script:
- rsync -avu -zz --no-perms --omit-dir-times --chown=www-data:www-data --chmod=D775,F664 site/ "${PRODUCTION_DESTINATION}"/public/cartolab/
rules:
- if: $CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "master-latest" || $CI_COMMIT_TAG
The tradeoff is that this will lead to more versions being pushed to the registry because bug-fixes that need to be immediately deployed need to be released as a new version first.