From bc441787dcc62e10ada473d557085c0f20c8fef6 Mon Sep 17 00:00:00 2001
From: Lucas Brandstaetter <lucas@brandstaetter.tech>
Date: Mon, 30 Sep 2024 01:05:00 +0200
Subject: [PATCH] Update release pipeline

* Create a tag for each commit
* Use tags instead of branches for production and latest
---
 .gitlab-ci.yml | 61 +++++++++++++++++++++++++++++++++-----------------
 1 file changed, 41 insertions(+), 20 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 2a7978404..9eb033357 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -8,16 +8,19 @@ stages:
 
 workflow:
   rules:
+    # Allow manual pipeline runs
     - if: $FORCE_PIPELINE_RUN == 'true'
+    # Tags with format "prod-yyyy-mm-dd_HH-MM" will be tagged as production and latest
     - if: $CI_COMMIT_TAG
     - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
-    - if: ($CI_COMMIT_BRANCH == "develop" || $CI_COMMIT_BRANCH == "production")
+    - if: $CI_COMMIT_BRANCH == "develop"
+    # prevent duplicate pipeline runs for merge requests
     - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
       when: never
     - if: $CI_COMMIT_BRANCH
 .default-rules:
   rules:
-    - if: ($CI_COMMIT_BRANCH == "develop" || $CI_COMMIT_BRANCH == "production")
+    - if: $CI_COMMIT_BRANCH == "develop"
     - if: $CI_COMMIT_TAG
     - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
     - if: $FORCE_PIPELINE_RUN == 'true'
@@ -375,42 +378,60 @@ test_nginx_static:
     - crane delete $CI_REGISTRY_IMAGE/ci/hub:ci-${CI_PIPELINE_ID}
     - crane delete $CI_REGISTRY_IMAGE/ci/nginx:ci-${CI_PIPELINE_ID}
 
-publish:
+publish-commit:
   extends:
     - .publish-clean
   script:
-    - crane copy $CI_REGISTRY_IMAGE/ci/hub:ci-${CI_PIPELINE_ID} $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME
-    - crane copy $CI_REGISTRY_IMAGE/ci/nginx:ci-${CI_PIPELINE_ID} $CI_REGISTRY_IMAGE/nginx:$CI_COMMIT_REF_NAME
+    - crane tag $CI_REGISTRY_IMAGE/ci/hub:ci-${CI_PIPELINE_ID} ${CI_COMMIT_SHORT_SHA}
+    - crane tag $CI_REGISTRY_IMAGE/ci/nginx:ci-${CI_PIPELINE_ID} ${CI_COMMIT_SHORT_SHA}
   rules:
-    - if: '$CI_COMMIT_BRANCH == "develop" || $CI_COMMIT_BRANCH == "production"'
+    - if: '$CI_COMMIT_BRANCH == "develop" ||  $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_TAG'
     - when: never
 
-publish_latest:
+publish-mr:
+  extends:
+    - .publish-image
   needs:
-    - publish
+    - publish-commit
+  script:
+    - crane tag $CI_REGISTRY_IMAGE/ci/hub:${CI_COMMIT_SHORT_SHA} mr-${CI_MERGE_REQUEST_ID}
+    - crane tag $CI_REGISTRY_IMAGE/ci/nginx:${CI_COMMIT_SHORT_SHA} mr-${CI_MERGE_REQUEST_ID}
+  rules:
+    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
+    - when: never
+
+publish-develop:
   extends:
     - .publish-image
+  needs:
+    - publish-commit
   script:
-    - crane tag $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME latest
-    - crane tag $CI_REGISTRY_IMAGE/nginx:$CI_COMMIT_REF_NAME latest
+    - crane copy $CI_REGISTRY_IMAGE/ci/hub:${CI_COMMIT_SHORT_SHA} $CI_REGISTRY_IMAGE:development
+    - crane copy $CI_REGISTRY_IMAGE/ci/nginx:${CI_COMMIT_SHORT_SHA} $CI_REGISTRY_IMAGE/nginx:development
   rules:
-    - if: '$CI_COMMIT_BRANCH == "production"'
+    - if: $CI_COMMIT_BRANCH == 'develop'
     - when: never
 
-publish_merge_requests:
+# Publish to production and add latest tag
+publish-production:
   extends:
-    - .publish-clean
+    - .publish-image
+  needs:
+    - publish-commit
   script:
-    - crane tag $CI_REGISTRY_IMAGE/ci/hub:ci-${CI_PIPELINE_ID} mr-$CI_MERGE_REQUEST_ID
-    - crane tag $CI_REGISTRY_IMAGE/ci/nginx:ci-${CI_PIPELINE_ID} mr-$CI_MERGE_REQUEST_ID
+    - crane copy $CI_REGISTRY_IMAGE/ci/hub:$CI_COMMIT_SHORT_SHA $CI_REGISTRY_IMAGE:production
+    - crane tag $CI_REGISTRY_IMAGE:production latest
+    - crane copy $CI_REGISTRY_IMAGE/ci/nginx:$CI_COMMIT_SHORT_SHA $CI_REGISTRY_IMAGE/nginx:production
+    - crane tag $CI_REGISTRY_IMAGE/nginx:production latest
   rules:
-    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+    - if: '$CI_COMMIT_TAG =~ /^prod-\d{4}-\d{2}-\d{2}_\d{2}-\d{2}$/'
+    - when: never
 
 deploy_develop:
   stage: deploy
   allow_failure: true
   needs:
-    - publish
+    - publish-develop
   image: python:3.11-bookworm
   script:
     - 'curl -X POST "$DEPLOYMENT_SERVICEWEBHOOK_URL_DEVELOP"'
@@ -434,7 +455,7 @@ deploy_production:
   stage: deploy
   allow_failure: true
   needs:
-    - publish
+    - publish-production
   image: python:3.11-bookworm
   script:
     - 'curl -X POST "$DEPLOYMENT_SERVICEWEBHOOK_URL_PRODUCTION"'
@@ -447,8 +468,8 @@ deploy_production:
     - if: '$DEPLOYMENT_SERVICEWEBHOOK_URL_PRODUCTION == null || $DEPLOYMENT_SERVICEWEBHOOK_URL_PRODUCTION == ""'
       when: never
 
-    # only attempt to deploy on correct branch
-    - if: '$CI_COMMIT_BRANCH == "production"'
+    # only attempt to deploy on correct tag
+    - if: '$CI_COMMIT_TAG =~ /^prod-\d{4}-\d{2}-\d{2}_\d{2}-\d{2}$/'
       when: on_success
 
     # otherwise, skip this
-- 
GitLab