From 7b520d8d0f5e0fe7a0840750a9b8f2ac45d0a741 Mon Sep 17 00:00:00 2001 From: Joakim Olsson Date: Thu, 11 Sep 2025 09:29:09 +0200 Subject: [PATCH] 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. --- Release.gitlab-ci.yml | 101 +++++++++++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 31 deletions(-) diff --git a/Release.gitlab-ci.yml b/Release.gitlab-ci.yml index 9db360c..0482ad7 100644 --- a/Release.gitlab-ci.yml +++ b/Release.gitlab-ci.yml @@ -39,73 +39,93 @@ unbound_release_changelog: rules: - if: $UNBOUND_RELEASE_TOKEN == null when: never - - if: '$CI_COMMIT_TITLE =~ /^chore\(release\): prepare for .*$/' - when: never - if: $CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH unbound_release_handle_mr: stage: .pre 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: - unbound_release_changelog before_script: - 'apk add --no-cache git jq curl' script: - | - LATEST="$(git describe --abbrev=0 --tags 2>/dev/null || echo '')" - if [[ -n "${LATEST}" && "$(cat VERSION)" == "${LATEST}" ]]; then + VERSION="$(cat VERSION)" + 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" exit 0 fi echo "Fetching existing release MRs" - MRS=$(curl -s \ + MRS=$(curl -sf \ -H "Authorization: Bearer ${UNBOUND_RELEASE_TOKEN}" \ "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}" \ "https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/repository/branches?regex=^next-release\$") MR=$(echo "${MRS}" | jq ".[].iid") BRANCH=$(echo "${BRANCHES}" | jq ".[].name") - TITLE="chore(release): prepare for $(cat VERSION)" + TITLE="chore(release): prepare for ${VERSION}" DESCRIPTION="$(cat CHANGES.md)" CONTENT="$(base64 -w0 update - curl -sf -X PUT \ + -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 "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 \ + 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/CHANGELOG%2Emd" - fi + "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 echo "Updating existing MR" - echo "Rebasing branch" + echo "Rebasing MR" curl -sf -X PUT \ -H "Authorization: Bearer ${UNBOUND_RELEASE_TOKEN}" \ -H "Content-Type: application/json" \ "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" BODY_TMPL='{"target_branch":$target,"title":$title,"description":$description,"remove_source_branch":true,"squash":true}' BODY=$(jq --null-input -c \ @@ -135,8 +155,6 @@ unbound_release_handle_mr: rules: - if: $UNBOUND_RELEASE_TOKEN == null when: never - - if: '$CI_COMMIT_TITLE =~ /^chore\(release\): prepare for .*$/' - when: never - if: $CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH unbound_release_prepare_release: @@ -166,18 +184,30 @@ unbound_release_prepare_release: when: never - if: $CI_COMMIT_TAG == null && $CI_DEFAULT_BRANCH != $CI_COMMIT_BRANCH when: never - - if: '$CI_COMMIT_TITLE =~ /^chore\(release\): prepare for .*$/' - - if: $CI_COMMIT_TAG && $UNBOUND_RELEASE_TAG_ONLY == "true" + - if: $CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH unbound_release_create_release: stage: .pre 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: - unbound_release_prepare_release before_script: - - 'apk add --no-cache jq curl' + - 'apk add --no-cache git jq curl' 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" NAME="$(cat VERSION)" MESSAGE="$(cat CHANGES.md)" @@ -199,17 +229,26 @@ unbound_release_create_release: when: never - if: $UNBOUND_RELEASE_TAG_ONLY == "true" when: never - - if: '$CI_COMMIT_TITLE =~ /^chore\(release\): prepare for .*$/' + - if: $CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH unbound_release_tag: stage: .pre 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: - unbound_release_prepare_release before_script: - - 'apk add --no-cache curl' + - 'apk add --no-cache git jq curl' 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" NAME="$(cat VERSION)" MESSAGE="$(cat CHANGES.md)" @@ -226,4 +265,4 @@ unbound_release_tag: when: never - if: $UNBOUND_RELEASE_TAG_ONLY == "false" when: never - - if: '$CI_COMMIT_TITLE =~ /^chore\(release\): prepare for .*$/' + - if: $UNBOUND_RELEASE_TAG_ONLY == "true"