From 8a90b80a81da3e4a0d63eed6b7c470fda95880ff Mon Sep 17 00:00:00 2001
From: Ole Langbehn <ole.langbehn@inoio.de>
Date: Mon, 3 Mar 2025 16:24:49 +0100
Subject: [PATCH] feat(CI): add smoketest against web environment

refs: HOLI-10337
---
 .gitlab-ci-mobile.yml |  1 +
 .gitlab-ci-web.yml    | 28 ++++++++++++++++++++++++++++
 smoketest/main.js     | 25 +++++++++++++++++++++++++
 3 files changed, 54 insertions(+)
 create mode 100644 smoketest/main.js

diff --git a/.gitlab-ci-mobile.yml b/.gitlab-ci-mobile.yml
index 4dfd29cf47..a8da49e00b 100644
--- a/.gitlab-ci-mobile.yml
+++ b/.gitlab-ci-mobile.yml
@@ -248,6 +248,7 @@ mobile_release_candidate_publish:
     - !reference [.rule_templates, only_on_production_release]
   after_script: |
     curl -X POST -H 'Content-Type: application/json' --data '{"channel": "#release-status", "branch": "'"$CI_COMMIT_REF_SLUG"'", "text":"The mobile release candidate \"'"$CI_COMMIT_BRANCH"'\" for release '$(git describe --tags --abbrev=0|sed "s|release/||")' has been updated to \"'"$CI_COMMIT_TITLE"'\" and is available for testing via:\n'"$CI_ENVIRONMENT_URL"'"}' "https://projectholi.rocket.chat/hooks/$ROCKETCHAT_HOOK_RELEASE_NOTIFIER"
+
 mobile_release_publish:
   extends: .mobile_publish
   needs: ['mobile_release_candidate_publish']
diff --git a/.gitlab-ci-web.yml b/.gitlab-ci-web.yml
index d2b3fdfd7e..a9a066c9d5 100644
--- a/.gitlab-ci-web.yml
+++ b/.gitlab-ci-web.yml
@@ -82,6 +82,15 @@ default:
   resource_group: $CI_ENVIRONMENT_SLUG # never execute terraform in parallel on the same environment
   interruptible: false
 
+.web_smoketest:
+  image: 'europe-north1-docker.pkg.dev/holi-shared/docker/holi-docker/holi-k6-builder'
+  cache: [] # explicitly disable cache
+  script:
+    - UI_DOMAIN=$(cat "$UI_DOMAIN_PATH")
+    - terraform/environments/scripts/wait-for-ssl.sh "https://${UI_DOMAIN}"
+    - BASE_URL="https://${UI_DOMAIN}/api/health" k6 run smoketest/main.js
+    # TODO should/could we roll back the service to the last working revision on test failure?
+
 # end job templates
 
 # pipeline in chronological order
@@ -215,6 +224,13 @@ web_review_deploy:
     - !reference [.rules_web_review]
     - !reference [.rule_templates, automatically_on_any_other]
 
+web_review_smoketest:
+  needs: ['web_review_deploy']
+  extends: .web_smoketest
+  rules:
+    - !reference [.rules_web_review]
+    - !reference [.rule_templates, automatically_on_any_other]
+
 web_review_e2e:
   extends: .web_e2e
   needs: ['web_review_deploy']
@@ -252,6 +268,12 @@ web_staging_deploy:
   rules:
     - !reference [.rule_templates, automatically_on_staging]
 
+web_staging_smoketest:
+  needs: ['web_staging_deploy']
+  extends: .web_smoketest
+  rules:
+    - !reference [.rule_templates, automatically_on_staging]
+
 web_staging_e2e:
   extends: .web_e2e
   needs: ['web_staging_deploy']
@@ -307,3 +329,9 @@ web_release_deploy:
       --post-data='{"channel": "#release-status", "branch": "'$CI_COMMIT_REF_SLUG'", "text":"The production web environment has been manually released from \"'$CI_COMMIT_REF_SLUG'\" for release '$(git describe --tags --abbrev=0|sed "s|release/||")'. It has been updated to \"'"$CI_COMMIT_TITLE"'\" and is available and/or updated under https://app.holi.social"}' \
       --output-document - \
       https://projectholi.rocket.chat/hooks/$ROCKETCHAT_HOOK_RELEASE_NOTIFIER
+
+web_release_smoketest:
+  needs: ['web_release_deploy']
+  extends: .web_smoketest
+  rules:
+    - !reference [.rule_templates, only_on_production_release]
diff --git a/smoketest/main.js b/smoketest/main.js
new file mode 100644
index 0000000000..a2cd41b4ca
--- /dev/null
+++ b/smoketest/main.js
@@ -0,0 +1,25 @@
+import http from 'k6/http'
+import { check } from 'k6'
+
+// You don't need to change anything in this section, it's k6 glue code.
+// See the default function at the end of the file for defining your smoketest.
+// This configuration only executes 1 test, enough for a smoketest. The smoketest will fail on any check failing.
+const allChecksNeedToPassTreshold = { checks: [{ threshold: 'rate==1', abortOnFail: true }] }
+export const options = {
+  vus: 1,
+  iterations: 1,
+  thresholds: allChecksNeedToPassTreshold,
+}
+
+// Define your smoketest(s) here.
+export default () => {
+  const response = http.get(`${__ENV.BASE_URL}`)
+  check(response, {
+    'is status 200': (r) => r.status === 200,
+  })
+  check(JSON.parse(response.body), {
+    // there can be multiple tests here, e.g.
+    //"contains topics object": (r) => typeof r.data.topics != null,
+    'returns {ok:true}': (r) => r.ok == true,
+  })
+}
-- 
GitLab