diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 7a59d5469a12176aa50eef1ddf1345da8b44b5c4..f9ee4863a2b3f924564701a2f8bc6fc3a2a5f06d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -70,6 +70,14 @@ variables:
   GITLAB_OPENTOFU_IMAGE_BASE: "$CI_REGISTRY_IMAGE/internal"
   GITLAB_OPENTOFU_IMAGE_NAME: "$GITLAB_OPENTOFU_IMAGE_BASE/gitlab-opentofu:$CI_COMMIT_SHA-opentofu$OPENTOFU_VERSION"
 
+check-semantic-version:
+  stage: .pre
+  rules:
+    - if: $CI_COMMIT_TAG
+  image: alpine:latest
+  script:
+    - echo -n "$CI_COMMIT_TAG" | ./.gitlab/scripts/check-semantic-version.sh
+
 gitlab-opentofu-image:build:
   extends: .opentofu-versions
   stage: build
@@ -223,7 +231,7 @@ create-release:
   stage: release
   image: registry.gitlab.com/gitlab-org/release-cli:latest
   rules:
-    - if: $CI_COMMIT_TAG =~ /\d+/
+    - if: $CI_COMMIT_TAG
   before_script:
     - apk add --update yq envsubst
   script: 
diff --git a/.gitlab/scripts/check-semantic-version.sh b/.gitlab/scripts/check-semantic-version.sh
new file mode 100755
index 0000000000000000000000000000000000000000..5cfd5019b58d1607163610a43d7cd0919ccd9832
--- /dev/null
+++ b/.gitlab/scripts/check-semantic-version.sh
@@ -0,0 +1,6 @@
+#!/usr/bin/env sh
+
+# Regex from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
+SEMANTIC_VERSION_REGEX='^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'
+
+cat - | grep -qE "$SEMANTIC_VERSION_REGEX"