Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ By participating in this project, you agree to abide by our [Code of Conduct](.g
- [Reporting Issues](#reporting-issues)
- [Pull Request Guidelines](#pull-request-guidelines)
- [Commit Message Guidelines](#commit-message-guidelines)
- [Changelog and Release Labels](#changelog-and-release-labels)
- [Testing](#testing)
- [Linting](#linting)
- [Documentation](#documentation)
Expand Down Expand Up @@ -63,6 +64,33 @@ When you're ready to contribute code:

---

## Changelog and Release Labels

This project uses [GitHub's automatic release notes](https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes) to generate changelogs.

### PR Labels for Changelog Categories

When submitting a PR, add one of these labels to categorize your change:

| Label | Changelog Section |
|-------|-------------------|
| `changelog:added` | Added |
| `changelog:changed` | Changed |
| `changelog:fixed` | Fixed |
| `changelog:removed` | Removed |
| `changelog:security` | Security |

PRs without labels appear under "Other Changes".

### Creating a Release

Releases are created via the `create-tag-and-exit` workflow, which:
1. Creates a GitHub Release with auto-generated notes
2. Updates CHANGELOG.md from all releases
3. Triggers the image build workflow

---

## Testing

Before submitting a PR, ensure that your changes pass all tests.
Expand Down
31 changes: 31 additions & 0 deletions .github/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Configuration for GitHub's automatically generated release notes
# https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes

changelog:
exclude:
labels:
- duplicate
- invalid
- wontfix
authors:
- dependabot
- github-actions
categories:
- title: "Added"
labels:
- "changelog:added"
- title: "Changed"
labels:
- "changelog:changed"
- title: "Fixed"
labels:
- "changelog:fixed"
- title: "Removed"
labels:
- "changelog:removed"
- title: "Security"
labels:
- "changelog:security"
- title: "Other Changes"
labels:
- "*"
82 changes: 74 additions & 8 deletions .github/workflows/create-tag-and-exit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
workflow_dispatch:
inputs:
tag:
description: 'Optional: Tag to push (e.g., v1.2.3). If omitted, patch is bumped.'
description: "Optional: Tag to push (e.g., v1.2.3). If omitted, patch is bumped."
required: false

permissions:
Expand All @@ -19,11 +19,9 @@ jobs:
with:
fetch-depth: 0

- name: Create tag (user input or bump patch)
- name: Determine tag version
id: version
run: |
git config user.name "github-actions"
git config user.email "github-actions@github.com"

if [[ -n "${{ github.event.inputs.tag }}" ]]; then
NEW_TAG="${{ github.event.inputs.tag }}"
else
Expand All @@ -33,8 +31,76 @@ jobs:
PATCH=$(echo $LAST_TAG | cut -d. -f3)
NEW_TAG="v${MAJOR}.${MINOR}.$((PATCH + 1))"
fi

echo "tag=$NEW_TAG" >> $GITHUB_OUTPUT
echo "Creating new tag: $NEW_TAG"
git tag $NEW_TAG
git push origin $NEW_TAG

- name: Create GitHub Release with auto-generated notes
env:
GH_TOKEN: ${{ github.token }}
run: |
if gh release view "${{ steps.version.outputs.tag }}" >/dev/null 2>&1; then
echo "Release ${{ steps.version.outputs.tag }} already exists; skipping creation."
else
gh release create ${{ steps.version.outputs.tag }} \
--generate-notes \
--title "${{ steps.version.outputs.tag }}"
fi

- name: Update CHANGELOG.md from releases
env:
GH_TOKEN: ${{ github.token }}
run: |
# Generate changelog header (no indentation to avoid leading spaces)
printf '%s\n' \
"# Changelog" \
"" \
"All notable changes to this project will be documented in this file." \
"The format is based on [Keep a Changelog](https://keepachangelog.com/)." \
"" \
"For releases prior to automated changelog generation, please see the" \
"[GitHub Releases](https://github.com/${{ github.repository }}/releases) page." \
"" > CHANGELOG.md

# Append all releases using JSON for reliable parsing (paginate to include all)
gh api --paginate repos/${{ github.repository }}/releases?per_page=100 \
--jq 'map({tagName: .tag_name, publishedAt: .published_at})' | jq -r '.[] | "\(.tagName) \(.publishedAt)"' | while read -r tag published_at; do
formatted_date=$(date -d "$published_at" +%Y-%m-%d 2>/dev/null || echo "$published_at")
echo "## [$tag] - $formatted_date"
echo ""
# Transform top-level headings (## ) to subheadings (### ) for changelog nesting.
# Uses negative lookahead pattern to avoid double-transforming already-nested headings.
gh release view "$tag" --json body -q '.body' | sed 's/^##\([^#]\)/###\1/'
echo ""
done >> CHANGELOG.md

- name: Commit and push CHANGELOG.md
run: |
git config user.name "github-actions"
git config user.email "github-actions@github.com"
git add CHANGELOG.md
if git diff --staged --quiet; then
echo "No changelog changes to commit"
exit 0
fi
git commit -m "chore: update changelog for ${{ steps.version.outputs.tag }}"

# Pull with rebase and push, with retry on failure
max_retries=3
for i in $(seq 1 $max_retries); do
git fetch origin main
if ! git rebase origin/main; then
if git diff --name-only --diff-filter=U | grep -q .; then
echo "Rebase failed due to conflicts; aborting."
git rebase --abort
exit 1
fi
echo "Rebase failed; aborting."
git rebase --abort || true
exit 1
fi
git push origin main && exit 0
echo "Push attempt $i failed, retrying..."
sleep 2
done
echo "Failed to push after $max_retries attempts"
exit 1
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Changelog

All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/).

For releases prior to automated changelog generation, please see the
[GitHub Releases](https://github.com/devzero-inc/zxporter/releases) page.

<!-- This file is automatically updated when releases are created -->
Loading