patch: improve release process

This commit is contained in:
Madison Grubb
2026-03-12 14:22:37 -04:00
parent d479716b7a
commit abdf3d21e7
+43 -13
View File
@@ -3,39 +3,69 @@ set -e
# version
msg="${CI_COMMIT_MESSAGE:-}"
# optional PR body (written by workflow from Gitea API when this commit is a merged PR)
if [ -f .ci_pr_body ]; then
CI_PR_DESCRIPTION=$(cat .ci_pr_body); rm -f .ci_pr_body
else
CI_PR_DESCRIPTION=""
fi
export CI_PR_DESCRIPTION
bump=patch
echo "$msg" | grep -qi minor: && bump=minor
# Conventional commits: chore/fix => patch, feat => minor
echo "$msg" | grep -Eqi '(^|[[:space:]])(fix|chore)(\([^)]*\))?:' && bump=patch
echo "$msg" | grep -Eqi '(^|[[:space:]])feat(\([^)]*\))?:' && bump=minor
# Conventional commits breaking change: type!:
echo "$msg" | grep -Eqi '(^|[[:space:]])[a-zA-Z]+(\([^)]*\))?!:' && bump=major
# Explicit bump prefixes still supported (but never downgrade a major bump)
echo "$msg" | grep -qi minor: && [ "$bump" != "major" ] && bump=minor
echo "$msg" | grep -qi major: && bump=major
cur=$(awk '/"version"/ { match($0, /[0-9]+\.[0-9]+\.[0-9]+/); print substr($0, RSTART, RLENGTH); exit }' package.json)
cur=$(cat VERSION | tr -d '\n')
case "$cur" in
[0-9]*.[0-9]*.[0-9]*) ;;
*) echo "error: VERSION must be x.y.z (got: $cur)"; exit 1 ;;
esac
major=$(echo "$cur" | cut -d. -f1); minor=$(echo "$cur" | cut -d. -f2); patch=$(echo "$cur" | cut -d. -f3)
case "$bump" in major) major=$((major+1)); minor=0; patch=0 ;; minor) minor=$((minor+1)); patch=0 ;; patch) patch=$((patch+1)) ;; esac
newVersion="$major.$minor.$patch"
[ -z "$cur" ] && { echo "error: could not read version from package.json"; exit 1; }
[ -z "$cur" ] && { echo "error: could not read version from VERSION"; exit 1; }
# changelog entry (strip prefix from first line)
changelogEntry=$(echo "$msg" | head -1 | awk '{sub(/^[mM]ajor:[ \t]*/,""); sub(/^[mM]inor:[ \t]*/,""); sub(/^[pP]atch:[ \t]*/,""); print}')
# changelog entry (strip explicit bump prefixes & any conventional-commit type(scope):); optional PR description enriches it
changelogEntry=$(
echo "$msg" \
| head -1 \
| sed -E 's/^[[:space:]]*[mM]ajor:[[:space:]]*//; s/^[[:space:]]*[mM]inor:[[:space:]]*//; s/^[[:space:]]*[pP]atch:[[:space:]]*//' \
| sed -E 's/^[[:space:]]*[a-zA-Z]+(\([^)]*\))?:[[:space:]]*//'
)
[ -z "$changelogEntry" ] && changelogEntry="Release v$newVersion"
if [ -n "$CI_PR_DESCRIPTION" ]; then
changelogFull="- $changelogEntry
$CI_PR_DESCRIPTION"
else
changelogFull="- $changelogEntry"
fi
# bump files
awk -v v="$newVersion" '/"version"/ { sub(/[0-9]+\.[0-9]+\.[0-9]+/, v) } { print }' package.json > package.json.tmp && mv package.json.tmp package.json
awk -v v="$newVersion" '/^version:/ { $0 = "version: " v }; /^appVersion:/ { $0 = "appVersion: \"" v "\"" }; { print }' helm/kestrelos/Chart.yaml > helm/kestrelos/Chart.yaml.tmp && mv helm/kestrelos/Chart.yaml.tmp helm/kestrelos/Chart.yaml
awk -v v="$newVersion" '/^ tag:/ { $0 = " tag: " v }; { print }' helm/kestrelos/values.yaml > helm/kestrelos/values.yaml.tmp && mv helm/kestrelos/values.yaml.tmp helm/kestrelos/values.yaml
echo "$newVersion" > VERSION
awk -v v="$newVersion" '/^version:/ { $0 = "version: " v }; /^appVersion:/ { $0 = "appVersion: \"" v "\"" }; { print }' helm/jasper/Chart.yaml > helm/jasper/Chart.yaml.tmp && mv helm/jasper/Chart.yaml.tmp helm/jasper/Chart.yaml
awk -v v="$newVersion" '/^ tag:/ { $0 = " tag: " v }; { print }' helm/jasper/values.yaml > helm/jasper/values.yaml.tmp && mv helm/jasper/values.yaml.tmp helm/jasper/values.yaml
# changelog
new="## [$newVersion] - $(date +%Y-%m-%d)
### Changed
- $changelogEntry
$changelogFull
"
{ [ ! -f CHANGELOG.md ] && printf '# Changelog\n\n'; printf '%s' "$new"; [ -f CHANGELOG.md ] && cat CHANGELOG.md; } > CHANGELOG.md.tmp && mv CHANGELOG.md.tmp CHANGELOG.md
# Create CHANGELOG.md if missing (first release); otherwise prepend new entry to existing content.
{ [ ! -f CHANGELOG.md ] && printf '# Changelog\n\n'; printf '%s' "$new"; [ -f CHANGELOG.md ] && cat CHANGELOG.md || true; } > CHANGELOG.md.tmp && mv CHANGELOG.md.tmp CHANGELOG.md
# git
git config user.email "ci@kestrelos" && git config user.name "CI"
git add package.json helm/kestrelos/Chart.yaml helm/kestrelos/values.yaml CHANGELOG.md
git add VERSION helm/jasper/Chart.yaml helm/jasper/values.yaml CHANGELOG.md
git commit -m "release v$newVersion [skip ci]"
url="https://${CI_REPO_OWNER}:${GITEA_REPO_TOKEN}@${CI_FORGE_URL#https://}/${CI_REPO_OWNER}/${CI_REPO_NAME}.git"
git tag "v$newVersion"
# artifact for kaniko (tag list)
# artifact for docker (tag list)
printf '%s\n%s\n' "$newVersion" "latest" > .tags
retry() { n=0; while ! "$@"; do n=$((n+1)); [ $n -ge 3 ] && return 1; sleep 2; done; }
retry git push "$url" HEAD:main "v$newVersion"
@@ -43,7 +73,7 @@ retry git push "$url" HEAD:main "v$newVersion"
# gitea release
body="## Changelog
### Changed
- $changelogEntry
$changelogFull
## Installation
- [Docker image](${CI_FORGE_URL}/${CI_REPO_OWNER}/-/packages/container/${CI_REPO_NAME})