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
175 changes: 110 additions & 65 deletions .github/RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,110 +1,134 @@
# Release Process

## Automated Release Workflow
## Release Workflow

### 1. Create PR with Changes
Create a PR targeting the `main` branch with your changes.

### 2. Add Version Bump Label
Add ONE OR MORE of these labels to indicate version change:
- `bump:major` - Breaking changes (2025.8.11 → 2026.0.0)
- `bump:minor` - New features (2025.8.11 → 2025.9.0)
- `bump:patch` - Bug fixes (2025.8.11 → 2025.8.12)
- `bump:stable` - Remove pre-release suffix
- `bump:alpha`, `bump:beta`, `bump:rc`, `bump:post`, `bump:dev` - Pre-release
**Tip**: Write a clear PR description - it will become your GitHub Release notes!

The version-bump workflow will automatically:
- Update `pyproject.toml` and `uv.lock`
- Commit changes to your PR
- Enable auto-merge (PR will merge when all checks pass)
### 2. Bump Version Manually
On your local branch, bump the version using `uv`:

```bash
# Choose one or more bump types:
uv version --bump patch # Bug fixes: 2025.8.11 → 2025.8.12
uv version --bump minor # New features: 2025.8.11 → 2025.9.0
uv version --bump major # Breaking changes: 2025.8.11 → 2026.0.0

# Pre-release versions:
uv version --bump rc # Release candidate: 2025.9.0 → 2025.9.0rc1
uv version --bump beta # Beta: 2025.9.0 → 2025.9.0b1
uv version --bump alpha # Alpha: 2025.9.0 → 2025.9.0a1
uv version --bump stable # Remove suffix: 2025.9.0rc1 → 2025.9.0

# Multiple bumps (applied sequentially):
uv version --bump minor --bump rc # 2025.8.11 → 2025.9.0rc1
```

Commit and push the version change:
```bash
git add pyproject.toml uv.lock
git commit -m "Bump version to $(uv version --short)"
git push
```

### 3. Add Release Type Label
Add ONE of these labels:
Add ONE of these labels to your PR:
- `release` - Publish to PyPI (production)
- `test-release` - Publish to TestPyPI (testing)

### 4. Wait for Checks
Required checks must pass:
- ✅ Tests (`test.yml`)
- ✅ Version bump (`version-bump.yml`, if bump labels present)

### 5. Wait for Auto-Merge
The version-bump workflow enables auto-merge, so the PR will automatically merge once all required checks pass.
### 4. Wait for Tests
Wait for the test workflow to pass.

You can also manually merge if needed via the GitHub UI.
### 5. Merge PR
Once tests pass, merge the PR via GitHub UI.

### 6. Automatic Publishing
After merge:
- Package is built and tested
- Published to PyPI or TestPyPI
- Git tag created (e.g., `v2025.9.0`)
- GitHub Release created with:
After merge, the release workflow automatically:
- Builds package
- Runs tests
- Publishes to PyPI or TestPyPI (based on label)
- Creates git tag (e.g., `v2025.9.0`)
- Creates GitHub Release with:
- PR title and body as release notes
- Installation instructions (`pipx install quarto-batch-convert`)
- Links to package, PR, and documentation

**Tip**: Write a clear PR description - it will become your release notes!
---

## Example: Patch Release to PyPI
## Examples

1. Create PR: "Fix bug in file collection"
2. Add labels: `bump:patch`, `release`
3. Version bump workflow: `2025.8.11` → `2025.8.12`
4. Merge PR
5. Release workflow publishes to PyPI and creates tag `v2025.8.12`
### Example 1: Patch Release to PyPI

## Example: Test Release
```bash
# 1. Make your bug fix changes
# 2. Bump version
uv version --bump patch
git add pyproject.toml uv.lock
git commit -m "Bump version to $(uv version --short)"
git push

1. Create PR: "Test new feature"
2. Add labels: `bump:minor`, `bump:beta`, `test-release`
3. Version bump workflow: `2025.8.11` → `2025.9.0b1`
4. Merge PR
5. Release workflow publishes to TestPyPI (not production PyPI)
# 3. Add 'release' label to PR in GitHub UI
# 4. Merge PR
# 5. Release workflow publishes to PyPI
```

## Multiple Version Bumps
### Example 2: Test Release with RC

You can apply multiple bump labels simultaneously. They will be applied sequentially in this order: major, minor, patch, stable, alpha, beta, rc, post, dev.
```bash
# 1. Make your feature changes
# 2. Bump version
uv version --bump minor --bump rc
git add pyproject.toml uv.lock
git commit -m "Bump version to $(uv version --short)"
git push

Example:
- Labels: `bump:minor`, `bump:rc`
- Result: `2025.8.11` → `2025.9.0rc1`
# 3. Add 'test-release' label to PR in GitHub UI
# 4. Merge PR
# 5. Release workflow publishes to TestPyPI (not production)
```

---

## Workflow Details

### Version Bump Workflow (`version-bump.yml`)
- **Trigger**: When bump labels are added to a PR targeting main
- **Actions**:
- Applies version bumps using `uv version --bump <type>`
- Commits updated `pyproject.toml` and `uv.lock` to PR branch
- Posts comment with version change
- Acts as required status check
### Test Workflow (`test.yml`)
- **Trigger**: On pull requests to main
- **Actions**: Runs pytest test suite
- **Concurrency**: Cancels previous test runs when new commits pushed

### Release Workflow (`release.yml`)
- **Trigger**: When PR with release label is merged to main
- **Trigger**: When PR with `release` or `test-release` label is merged to main
- **Actions**:
- Builds package
- Runs tests
- Extracts PR number from merge commit
- Builds package and runs tests
- Publishes to PyPI or TestPyPI based on label
- Creates git tag matching version
- Creates GitHub Release
- Test releases marked as pre-release
- Creates GitHub Release with PR content as notes
- Marks test releases as pre-release

## Troubleshooting
---

### Version bump workflow doesn't run
- Ensure at least one `bump:*` label is applied
- Check that PR targets the `main` branch
- Verify workflow file is present in `.github/workflows/version-bump.yml`
## Troubleshooting

### Release workflow doesn't run
- Ensure PR was merged (not closed)
- Ensure PR was **merged** (not closed)
- Ensure either `release` or `test-release` label is applied
- Check workflow logs for errors
- Check workflow logs in Actions tab for errors

### PyPI publish fails
- Verify PyPI Trusted Publishing is configured correctly
- Check that GitHub environments (`pypi`, `testpypi`) are set up
- Ensure version doesn't already exist on PyPI
- Check that package builds successfully (run `uv build` locally)

### Wrong version published
- Check that you committed the version bump to the PR
- Run `uv version --short` to verify current version
- Ensure `pyproject.toml` and `uv.lock` are both committed

---

## Configuration Requirements

Expand All @@ -120,7 +144,28 @@ Configure at https://pypi.org/manage/account/publishing/:
- Environment: `pypi` (and separately for `testpypi`)

### Branch Protection
Main branch should have:
Main branch protection recommended settings:
- Require pull request before merging
- Require status checks: `test`, `bump-version`
- Require status check: `test`
- Require branches to be up to date

---

## Notes

### Why Manual Version Bumping?

The automated version-bump workflow was archived due to GitHub Actions limitations:
- Commits from `GITHUB_TOKEN` don't trigger other workflows
- This prevented tests from running after automated version bumps
- Caused auto-merge to block indefinitely waiting for test status

See `.github/workflows/archive/version-bump.yml` for details and potential future solutions using GitHub Apps.

### Version Bump Labels (Deprecated)

The following labels exist but are **not used** in the current manual workflow:
- `bump:major`, `bump:minor`, `bump:patch`
- `bump:stable`, `bump:alpha`, `bump:beta`, `bump:rc`, `bump:post`, `bump:dev`

These may be used in the future if automated version bumping is re-implemented with a GitHub App.
Original file line number Diff line number Diff line change
@@ -1,3 +1,50 @@
# ARCHIVED - Version Bump Workflow
#
# This workflow was archived because of fundamental GitHub Actions limitations:
#
# Problem 1: GITHUB_TOKEN commits don't trigger other workflows
# - Commits made with secrets.GITHUB_TOKEN deliberately don't trigger workflows
# (GitHub's safeguard against infinite loops)
# - After version bump commits, test workflow never runs
# - Branch protection waits for 'test' check that never comes
# - Auto-merge blocked indefinitely
#
# Problem 2: workflow_run doesn't report status to PR
# - Tried using workflow_run to trigger tests after version bump
# - workflow_run executes in main branch context, not PR context
# - Status checks created are for wrong commit SHA
# - Branch protection on PR can't see these checks
#
# Problem 3: Multiple workflow runs with labels
# - Adding multiple labels (e.g., bump:rc + test-release) triggers separate runs
# - Even with concurrency control, cancellation happens after work starts
# - Results in duplicate version bump commits before cancellation
#
# Attempted Solutions That Failed:
# - [skip ci] in commit message (doesn't work, workflow never triggers anyway)
# - workflow_run trigger (runs in wrong context, status not reported to PR)
# - Concurrency control (helps but doesn't prevent all duplicates)
# - Manual status check via API (hacky, doesn't actually re-test)
#
# Working Solutions (not implemented here):
# Option A: Use GitHub App or PAT instead of GITHUB_TOKEN
# - Commits from app/PAT DO trigger workflows
# - Requires creating GitHub App or storing PAT as secret
# - Industry standard solution (used by Renovate, Dependabot, etc.)
#
# Option B: Manual version bumping (CHOSEN)
# - Run `uv version --bump <type>` manually
# - Commit to PR branch
# - Simple, reliable, no workflow complexity
# - Trade-off: one manual step for simplicity
#
# This workflow is preserved for future reference if we decide to implement
# Option A (GitHub App/PAT) for full automation.
#
# Last used: 2025-10-21
# Archived by: Claude Code
# Related: _todo/proposal/fix-workflow-status-reporting.md

name: Version Bump

on:
Expand Down
30 changes: 5 additions & 25 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,20 @@ name: Run Tests
on:
pull_request:
branches: [ main ]
workflow_run:
workflows: ["Version Bump"]
types: [completed]

concurrency:
group: test-${{ github.event.pull_request.number }}
cancel-in-progress: true

permissions:
contents: read

jobs:
test:
# Only run on PRs or successful version bump completions
if: |
github.event_name == 'pull_request' ||
(github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success')
runs-on: ubuntu-latest

steps:
- name: Get PR details
if: github.event_name == 'workflow_run'
id: pr
env:
GH_TOKEN: ${{ github.token }}
run: |
# Get PR number from the workflow run
PR_NUMBER=$(gh api repos/${{ github.repository }}/pulls \
--jq ".[] | select(.head.sha == \"${{ github.event.workflow_run.head_sha }}\") | .number" \
| head -1)

echo "number=$PR_NUMBER" >> $GITHUB_OUTPUT
echo "PR number: $PR_NUMBER"

- name: Checkout PR branch
uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || github.event.pull_request.head.sha }}
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
Expand Down
Loading