4730bbdc1f
Includes a new condition in the CI pipeline to handle situations where the commit is a tag. This improves the robustness of the pipeline by ensuring that specific actions are only executed for tagged commits, thereby optimizing the release process.
270 lines
11 KiB
YAML
270 lines
11 KiB
YAML
stages:
|
|
- prepare
|
|
|
|
unbound_release_preconditions_failed:
|
|
stage: .pre
|
|
image: amd64/alpine:3.22.1@sha256:04f9172abd4691ef13a65d0c5c3057ba365a8db269e848ae24f2151e50997f99
|
|
script:
|
|
- |
|
|
echo "To use Unbound Release, a UNBOUND_RELEASE_TOKEN environment variable needs to be defined."
|
|
echo "It needs API access to write repository files, create MRs and releases and it needs at least Developer access."
|
|
echo " "
|
|
echo "See more info here:"
|
|
echo "Personal Access Tokens: https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html"
|
|
echo "Project Access Tokens: https://docs.gitlab.com/ee/user/project/settings/project_access_tokens.html"
|
|
echo "Group Access Tokens: https://docs.gitlab.com/ee/user/group/settings/group_access_tokens.html"
|
|
- 'false'
|
|
rules:
|
|
- if: $UNBOUND_RELEASE_TOKEN == null
|
|
|
|
unbound_release_changelog:
|
|
stage: .pre
|
|
image:
|
|
name: orhunp/git-cliff:2.10.0@sha256:ae15c208868fd474987e30b2b8486d0cdf55ee580c68ec14237b3ac6a36e0d91
|
|
entrypoint: [ "" ]
|
|
variables:
|
|
GIT_STRATEGY: clone # clone entire repo instead of reusing workspace
|
|
GIT_DEPTH: 0 # avoid shallow clone to give cliff all the info it needs
|
|
script:
|
|
- 'echo "Generating changelog"'
|
|
- 'git-cliff --bump --unreleased --strip header > CHANGES.md'
|
|
- 'git-cliff --bump | sed "s/\s\+$//" > CHANGELOG.md'
|
|
- 'echo "Bumping version"'
|
|
- 'git-cliff --bumped-version 2>/dev/null > VERSION'
|
|
artifacts:
|
|
paths:
|
|
- CHANGES.md
|
|
- CHANGELOG.md
|
|
- VERSION
|
|
rules:
|
|
- if: $UNBOUND_RELEASE_TOKEN == null
|
|
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:
|
|
- |
|
|
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 -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 -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 ${VERSION}"
|
|
DESCRIPTION="$(cat CHANGES.md)"
|
|
CONTENT="$(base64 -w0 <CHANGELOG.md)"
|
|
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
|
|
BODY_TMPL=${OLD_BRANCH_BODY_TMPL}
|
|
fi
|
|
BODY="$(jq --null-input -c \
|
|
--arg title "${TITLE}" \
|
|
--arg content "${CONTENT}" \
|
|
--arg startBranch "${CI_DEFAULT_BRANCH}" \
|
|
"${BODY_TMPL}")"
|
|
echo "Creating or updating CHANGELOG.md"
|
|
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 "Content-Type: application/json" \
|
|
--data "${BODY}" \
|
|
"https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/repository/files/CHANGELOG%2Emd"
|
|
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
|
|
echo "Updating existing MR"
|
|
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 \
|
|
--arg title "${TITLE}" \
|
|
--arg description "${DESCRIPTION}" \
|
|
--arg target "${CI_DEFAULT_BRANCH}" \
|
|
"${BODY_TMPL}")
|
|
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}/merge_requests/${MR}"
|
|
else
|
|
echo "Creating new MR"
|
|
BODY_TMPL='{"source_branch":"next-release","target_branch":$target,"title":$title,"description":$description,"remove_source_branch":true,"squash":true}'
|
|
BODY=$(jq --null-input -c \
|
|
--arg title "${TITLE}" \
|
|
--arg description "${DESCRIPTION}" \
|
|
--arg target "${CI_DEFAULT_BRANCH}" \
|
|
"${BODY_TMPL}")
|
|
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}/merge_requests"
|
|
fi
|
|
rules:
|
|
- if: $UNBOUND_RELEASE_TOKEN == null
|
|
when: never
|
|
- if: $CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH
|
|
|
|
unbound_release_prepare_release:
|
|
stage: .pre
|
|
image:
|
|
name: orhunp/git-cliff:2.10.0@sha256:ae15c208868fd474987e30b2b8486d0cdf55ee580c68ec14237b3ac6a36e0d91
|
|
entrypoint: [ "" ]
|
|
variables:
|
|
GIT_STRATEGY: clone # clone entire repo instead of reusing workspace
|
|
GIT_DEPTH: 0 # avoid shallow clone to give cliff all the info it needs
|
|
script:
|
|
- |
|
|
echo "Generating changelog"
|
|
if [ -n "${CI_COMMIT_TAG}" ]; then
|
|
git-cliff --bump --latest --strip header > CHANGES.md
|
|
else
|
|
git-cliff --bump --unreleased --strip header > CHANGES.md
|
|
fi
|
|
echo "Bumping version"
|
|
git-cliff --bumped-version 2>/dev/null > VERSION
|
|
artifacts:
|
|
paths:
|
|
- CHANGES.md
|
|
- VERSION
|
|
rules:
|
|
- if: $UNBOUND_RELEASE_TOKEN == null
|
|
when: never
|
|
- if: $CI_COMMIT_TAG == null && $CI_DEFAULT_BRANCH != $CI_COMMIT_BRANCH
|
|
when: never
|
|
- if: $CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH
|
|
- if: $CI_COMMIT_TAG
|
|
|
|
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 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)"
|
|
BODY_TMPL='{"name":$name,"tag_name":$name,"tag_message":$name,"description":$message,"ref":$ref}'
|
|
BODY="$(jq --null-input -c \
|
|
--arg name "${NAME}" \
|
|
--arg message "${MESSAGE}" \
|
|
--arg ref "${CI_DEFAULT_BRANCH}" \
|
|
"${BODY_TMPL}")"
|
|
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}/releases"
|
|
rules:
|
|
- if: $UNBOUND_RELEASE_TOKEN == null
|
|
when: never
|
|
- if: $CI_DEFAULT_BRANCH != $CI_COMMIT_BRANCH
|
|
when: never
|
|
- if: $UNBOUND_RELEASE_TAG_ONLY == "true"
|
|
when: never
|
|
- 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 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)"
|
|
curl -sf -X POST \
|
|
-H "Authorization: Bearer ${UNBOUND_RELEASE_TOKEN}" \
|
|
-H "Content-Type: application/json" \
|
|
"https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/repository/tags?tag_name=${NAME}&ref=${CI_DEFAULT_BRANCH}&message=${NAME}"
|
|
rules:
|
|
- if: $UNBOUND_RELEASE_TOKEN == null
|
|
when: never
|
|
- if: $CI_DEFAULT_BRANCH != $CI_COMMIT_BRANCH
|
|
when: never
|
|
- if: $UNBOUND_RELEASE_TAG_ONLY == null
|
|
when: never
|
|
- if: $UNBOUND_RELEASE_TAG_ONLY == "false"
|
|
when: never
|
|
- if: $UNBOUND_RELEASE_TAG_ONLY == "true"
|