À chaque tag stable, la CI extrait la section [Unreleased], l'utilise comme notes de release Forgejo, renomme la section avec la version et la date, puis commite le CHANGELOG.md mis à jour sur main. Les tags RC utilisent le contenu [Unreleased] pour les notes mais ne modifient pas le fichier. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
146 lines
4.7 KiB
YAML
146 lines
4.7 KiB
YAML
name: Release
|
|
|
|
"on":
|
|
push:
|
|
tags:
|
|
- "**"
|
|
|
|
permissions:
|
|
contents: write
|
|
releases: write
|
|
|
|
jobs:
|
|
release:
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Extract changelog and update CHANGELOG.md
|
|
id: changelog
|
|
env:
|
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
current_tag="${GITHUB_REF_NAME}"
|
|
today=$(date +%Y-%m-%d)
|
|
|
|
# Extract content of [Unreleased] section (non-empty lines)
|
|
release_notes=$(awk '/^## \[Unreleased\]/{found=1; next} found && /^## \[/{exit} found{print}' CHANGELOG.md | sed '/^[[:space:]]*$/d')
|
|
|
|
if [ -z "${release_notes}" ]; then
|
|
release_notes="Voir les commits pour le détail des changements."
|
|
fi
|
|
|
|
printf '%s\n' "${release_notes}" > release_notes.md
|
|
|
|
# For stable releases: rename [Unreleased] and insert a new empty section
|
|
case "${current_tag}" in
|
|
*-rc*|*-beta*|*-alpha*)
|
|
echo "Pre-release tag — CHANGELOG.md non modifié"
|
|
;;
|
|
*)
|
|
cat > /tmp/update_changelog.py << 'PYEOF'
|
|
import os
|
|
|
|
version = os.environ['VERSION']
|
|
today = os.environ['TODAY']
|
|
|
|
with open('CHANGELOG.md', 'r') as f:
|
|
content = f.read()
|
|
|
|
content = content.replace('## [Unreleased]', f'## [{version}] — {today}', 1)
|
|
content = content.replace('# Changelog\n', '# Changelog\n\n## [Unreleased]\n', 1)
|
|
|
|
with open('CHANGELOG.md', 'w') as f:
|
|
f.write(content)
|
|
PYEOF
|
|
|
|
VERSION="${current_tag}" TODAY="${today}" python3 /tmp/update_changelog.py
|
|
|
|
git config user.name "CI"
|
|
git config user.email "ci@forge.lclr.dev"
|
|
git remote set-url origin "https://x-token:${GITEA_TOKEN}@${GITHUB_SERVER_URL#https://}/${GITHUB_REPOSITORY}.git"
|
|
git add CHANGELOG.md
|
|
git commit -m "chore(changelog): release ${current_tag}"
|
|
git push origin HEAD:main
|
|
;;
|
|
esac
|
|
|
|
- name: Create or update release
|
|
env:
|
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
current_tag="${GITHUB_REF_NAME}"
|
|
api_url="${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases"
|
|
release_by_tag_url="${api_url}/tags/${current_tag}"
|
|
prerelease=false
|
|
|
|
case "${current_tag}" in
|
|
*-rc*|*-beta*|*-alpha*)
|
|
prerelease=true
|
|
;;
|
|
esac
|
|
|
|
json_escape() {
|
|
sed ':a;N;$!ba;s/\\/\\\\/g;s/"/\\"/g;s/\t/\\t/g;s/\r//g;s/\n/\\n/g'
|
|
}
|
|
|
|
body="$(json_escape < release_notes.md)"
|
|
payload="$(printf '{"tag_name":"%s","name":"%s","body":"%s","draft":false,"prerelease":%s}' \
|
|
"${current_tag}" \
|
|
"${current_tag}" \
|
|
"${body}" \
|
|
"${prerelease}")"
|
|
|
|
http_code="$(
|
|
curl --silent --show-error --output release.json --write-out '%{http_code}' \
|
|
--header "Authorization: token ${GITEA_TOKEN}" \
|
|
--header 'Accept: application/json' \
|
|
"${release_by_tag_url}"
|
|
)"
|
|
|
|
case "${http_code}" in
|
|
200)
|
|
release_id="$(
|
|
tr '{,' '\n' < release.json |
|
|
sed -n 's/^[[:space:]]*"id":[[:space:]]*\([0-9][0-9]*\)$/\1/p' |
|
|
head -n1
|
|
)"
|
|
|
|
if [ -z "${release_id}" ]; then
|
|
echo "failed to parse release id from existing release response" >&2
|
|
exit 1
|
|
fi
|
|
|
|
curl --silent --show-error --fail \
|
|
--request PATCH \
|
|
--header "Authorization: token ${GITEA_TOKEN}" \
|
|
--header 'Accept: application/json' \
|
|
--header 'Content-Type: application/json' \
|
|
--data "${payload}" \
|
|
"${api_url}/${release_id}" >/dev/null
|
|
;;
|
|
404)
|
|
curl --silent --show-error --fail \
|
|
--request POST \
|
|
--header "Authorization: token ${GITEA_TOKEN}" \
|
|
--header 'Accept: application/json' \
|
|
--header 'Content-Type: application/json' \
|
|
--data "${payload}" \
|
|
"${api_url}" >/dev/null
|
|
;;
|
|
*)
|
|
echo "unexpected status code while looking up release: ${http_code}" >&2
|
|
cat release.json >&2
|
|
exit 1
|
|
;;
|
|
esac
|