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