chore(release): update version handling in CI script

Updates the CI script to improve version retrieval and checking logic. 
Replaces direct calls to the VERSION file with reading from a 
`.version` JSON file, ensuring proper version management. Handles 
the creation and updating of the CHANGELOG and .version files to 
enhance the release process. Adjusts conditions for executing 
release tasks based on current tags and branches to prevent 
unnecessary executions.
This commit is contained in:
2025-09-11 09:29:09 +02:00
parent f4026dcfc0
commit 7b520d8d0f
+73 -34
View File
@@ -39,73 +39,93 @@ unbound_release_changelog:
rules: rules:
- if: $UNBOUND_RELEASE_TOKEN == null - if: $UNBOUND_RELEASE_TOKEN == null
when: never when: never
- if: '$CI_COMMIT_TITLE =~ /^chore\(release\): prepare for .*$/'
when: never
- if: $CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH - if: $CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH
unbound_release_handle_mr: unbound_release_handle_mr:
stage: .pre stage: .pre
image: amd64/alpine:3.22.1@sha256:04f9172abd4691ef13a65d0c5c3057ba365a8db269e848ae24f2151e50997f99 image: amd64/alpine:3.22.1@sha256:04f9172abd4691ef13a65d0c5c3057ba365a8db269e848ae24f2151e50997f99
variables:
GIT_STRATEGY: clone # clone entire repo instead of reusing workspace
GIT_DEPTH: 0 # avoid shallow clone to have the tags available
needs: needs:
- unbound_release_changelog - unbound_release_changelog
before_script: before_script:
- 'apk add --no-cache git jq curl' - 'apk add --no-cache git jq curl'
script: script:
- | - |
LATEST="$(git describe --abbrev=0 --tags 2>/dev/null || echo '')" VERSION="$(cat VERSION)"
if [[ -n "${LATEST}" && "$(cat VERSION)" == "${LATEST}" ]]; then LATEST="$(cat .version 2>/dev/null | jq -r '.version' || git describe --abbrev=0 --tags 2>/dev/null || echo '')"
if [[ -n "${LATEST}" && "${VERSION}" == "${LATEST}" ]]; then
echo "No changes worthy of a version bump" echo "No changes worthy of a version bump"
exit 0 exit 0
fi fi
echo "Fetching existing release MRs" echo "Fetching existing release MRs"
MRS=$(curl -s \ MRS=$(curl -sf \
-H "Authorization: Bearer ${UNBOUND_RELEASE_TOKEN}" \ -H "Authorization: Bearer ${UNBOUND_RELEASE_TOKEN}" \
"https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/merge_requests?state=opened&source_branch=next-release") "https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/merge_requests?state=opened&source_branch=next-release")
BRANCHES=$(curl -s \ BRANCHES=$(curl -sf \
-H "Authorization: Bearer ${UNBOUND_RELEASE_TOKEN}" \ -H "Authorization: Bearer ${UNBOUND_RELEASE_TOKEN}" \
"https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/repository/branches?regex=^next-release\$") "https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/repository/branches?regex=^next-release\$")
MR=$(echo "${MRS}" | jq ".[].iid") MR=$(echo "${MRS}" | jq ".[].iid")
BRANCH=$(echo "${BRANCHES}" | jq ".[].name") BRANCH=$(echo "${BRANCHES}" | jq ".[].name")
TITLE="chore(release): prepare for $(cat VERSION)" TITLE="chore(release): prepare for ${VERSION}"
DESCRIPTION="$(cat CHANGES.md)" DESCRIPTION="$(cat CHANGES.md)"
CONTENT="$(base64 -w0 <CHANGELOG.md)" CONTENT="$(base64 -w0 <CHANGELOG.md)"
BODY_TMPL='{"branch": "next-release", "start_branch": $startBranch, "author_name": "Unbound Release", "content": $content, "commit_message": $title, "encoding": "base64" }' NEW_BRANCH_BODY_TMPL='{"branch": "next-release", "start_branch": $startBranch, "author_name": "Unbound Release", "content": $content, "commit_message": $title, "encoding": "base64" }'
OLD_BRANCH_BODY_TMPL='{"branch": "next-release", "author_name": "Unbound Release", "content": $content, "commit_message": $title, "encoding": "base64" }'
BODY_TMPL=${NEW_BRANCH_BODY_TMPL}
if [ -n "${BRANCH}" ]; then if [ -n "${BRANCH}" ]; then
BODY_TMPL='{"branch": "next-release", "author_name": "Unbound Release", "content": $content, "commit_message": $title, "encoding": "base64" }' BODY_TMPL=${OLD_BRANCH_BODY_TMPL}
fi fi
BODY="$(jq --null-input -c \ BODY="$(jq --null-input -c \
--arg title "${TITLE}" \ --arg title "${TITLE}" \
--arg content "${CONTENT}" \ --arg content "${CONTENT}" \
--arg startBranch "${CI_DEFAULT_BRANCH}" \ --arg startBranch "${CI_DEFAULT_BRANCH}" \
"${BODY_TMPL}")" "${BODY_TMPL}")"
# Check if CHANGELOG.md exists echo "Creating or updating CHANGELOG.md"
if curl -sf --head \
-H "Authorization: Bearer ${UNBOUND_RELEASE_TOKEN}" \
"https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/repository/files/CHANGELOG%2Emd?ref=${CI_DEFAULT_BRANCH}" || \
curl -sf --head \
-H "Authorization: Bearer ${UNBOUND_RELEASE_TOKEN}" \
"https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/repository/files/CHANGELOG%2Emd?ref=next-release"; then
# Exists => update
curl -sf -X PUT \
-H "Authorization: Bearer ${UNBOUND_RELEASE_TOKEN}" \
-H "Content-Type: application/json" \
--data "${BODY}" \
"https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/repository/files/CHANGELOG%2Emd"
else
# Not exists => create
curl -sf -X POST \ curl -sf -X POST \
-H "Authorization: Bearer ${UNBOUND_RELEASE_TOKEN}" \
-H "Content-Type: application/json" \
--data "${BODY}" \
"https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/repository/files/CHANGELOG%2Emd" || \
curl -sf -X PUT \
-H "Authorization: Bearer ${UNBOUND_RELEASE_TOKEN}" \ -H "Authorization: Bearer ${UNBOUND_RELEASE_TOKEN}" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
--data "${BODY}" \ --data "${BODY}" \
"https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/repository/files/CHANGELOG%2Emd" "https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/repository/files/CHANGELOG%2Emd"
fi CONTENT="$(jq --null-input -c --arg version "${VERSION}" '{"version":$version}' | base64 -w0)"
BODY="$(jq --null-input -c \
--arg title "${TITLE}" \
--arg content "${CONTENT}" \
--arg startBranch "${CI_DEFAULT_BRANCH}" \
"${OLD_BRANCH_BODY_TMPL}")"
echo "Creating or updating .version"
curl -s --fail-with-body -X POST \
-H "Authorization: Bearer ${UNBOUND_RELEASE_TOKEN}" \
-H "Content-Type: application/json" \
--data "${BODY}" \
"https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/repository/files/%2Eversion" || \
curl -s --fail-with-body -X PUT \
-H "Authorization: Bearer ${UNBOUND_RELEASE_TOKEN}" \
-H "Content-Type: application/json" \
--data "${BODY}" \
"https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/repository/files/%2Eversion"
if [ -n "${MR}" ]; then if [ -n "${MR}" ]; then
echo "Updating existing MR" echo "Updating existing MR"
echo "Rebasing branch" echo "Rebasing MR"
curl -sf -X PUT \ curl -sf -X PUT \
-H "Authorization: Bearer ${UNBOUND_RELEASE_TOKEN}" \ -H "Authorization: Bearer ${UNBOUND_RELEASE_TOKEN}" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
"https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/merge_requests/${MR}/rebase" "https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/merge_requests/${MR}/rebase"
rebasing="true"
while [[ "${rebasing}" == "true" ]]; do
sleep 1
echo "Checking if MR is rebased"
rebasing=$(curl -sf \
-H "Authorization: Bearer ${UNBOUND_RELEASE_TOKEN}" \
"https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/merge_requests/${MR}?include_rebase_in_progress=true" | jq -r '.rebase_in_progress')
done
echo "MR rebased"
echo "Updating title" echo "Updating title"
BODY_TMPL='{"target_branch":$target,"title":$title,"description":$description,"remove_source_branch":true,"squash":true}' BODY_TMPL='{"target_branch":$target,"title":$title,"description":$description,"remove_source_branch":true,"squash":true}'
BODY=$(jq --null-input -c \ BODY=$(jq --null-input -c \
@@ -135,8 +155,6 @@ unbound_release_handle_mr:
rules: rules:
- if: $UNBOUND_RELEASE_TOKEN == null - if: $UNBOUND_RELEASE_TOKEN == null
when: never when: never
- if: '$CI_COMMIT_TITLE =~ /^chore\(release\): prepare for .*$/'
when: never
- if: $CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH - if: $CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH
unbound_release_prepare_release: unbound_release_prepare_release:
@@ -166,18 +184,30 @@ unbound_release_prepare_release:
when: never when: never
- if: $CI_COMMIT_TAG == null && $CI_DEFAULT_BRANCH != $CI_COMMIT_BRANCH - if: $CI_COMMIT_TAG == null && $CI_DEFAULT_BRANCH != $CI_COMMIT_BRANCH
when: never when: never
- if: '$CI_COMMIT_TITLE =~ /^chore\(release\): prepare for .*$/' - if: $CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH
- if: $CI_COMMIT_TAG && $UNBOUND_RELEASE_TAG_ONLY == "true"
unbound_release_create_release: unbound_release_create_release:
stage: .pre stage: .pre
image: amd64/alpine:3.22.1@sha256:04f9172abd4691ef13a65d0c5c3057ba365a8db269e848ae24f2151e50997f99 image: amd64/alpine:3.22.1@sha256:04f9172abd4691ef13a65d0c5c3057ba365a8db269e848ae24f2151e50997f99
variables:
GIT_STRATEGY: clone # clone entire repo instead of reusing workspace
GIT_DEPTH: 0 # avoid shallow clone to have the tags available
needs: needs:
- unbound_release_prepare_release - unbound_release_prepare_release
before_script: before_script:
- 'apk add --no-cache jq curl' - 'apk add --no-cache git jq curl'
script: script:
- | - |
if [ ! -r .version ]; then
echo "Version file not found"
exit 0
fi
VERSION="$(cat .version 2>/dev/null | jq -r '.version')"
LATEST="$(git describe --abbrev=0 --tags 2>/dev/null || echo '')"
if [[ -n "${LATEST}" && "${VERSION}" == "${LATEST}" ]]; then
echo "Version ${VERSION} already exists"
exit 0
fi
echo "Creating release" echo "Creating release"
NAME="$(cat VERSION)" NAME="$(cat VERSION)"
MESSAGE="$(cat CHANGES.md)" MESSAGE="$(cat CHANGES.md)"
@@ -199,17 +229,26 @@ unbound_release_create_release:
when: never when: never
- if: $UNBOUND_RELEASE_TAG_ONLY == "true" - if: $UNBOUND_RELEASE_TAG_ONLY == "true"
when: never when: never
- if: '$CI_COMMIT_TITLE =~ /^chore\(release\): prepare for .*$/' - if: $CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH
unbound_release_tag: unbound_release_tag:
stage: .pre stage: .pre
image: amd64/alpine:3.22.1@sha256:04f9172abd4691ef13a65d0c5c3057ba365a8db269e848ae24f2151e50997f99 image: amd64/alpine:3.22.1@sha256:04f9172abd4691ef13a65d0c5c3057ba365a8db269e848ae24f2151e50997f99
variables:
GIT_STRATEGY: clone # clone entire repo instead of reusing workspace
GIT_DEPTH: 0 # avoid shallow clone to have the tags available
needs: needs:
- unbound_release_prepare_release - unbound_release_prepare_release
before_script: before_script:
- 'apk add --no-cache curl' - 'apk add --no-cache git jq curl'
script: script:
- | - |
VERSION="$(cat VERSION)"
LATEST="$(git describe --abbrev=0 --tags 2>/dev/null || echo '')"
if [[ -n "${LATEST}" && "${VERSION}" == "${LATEST}" ]]; then
echo "Version ${VERSION} already exists"
exit 0
fi
echo "Creating tag" echo "Creating tag"
NAME="$(cat VERSION)" NAME="$(cat VERSION)"
MESSAGE="$(cat CHANGES.md)" MESSAGE="$(cat CHANGES.md)"
@@ -226,4 +265,4 @@ unbound_release_tag:
when: never when: never
- if: $UNBOUND_RELEASE_TAG_ONLY == "false" - if: $UNBOUND_RELEASE_TAG_ONLY == "false"
when: never when: never
- if: '$CI_COMMIT_TITLE =~ /^chore\(release\): prepare for .*$/' - if: $UNBOUND_RELEASE_TAG_ONLY == "true"