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
7 changes: 7 additions & 0 deletions .github/workflows/_license-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ name: License check

on:
workflow_call:
inputs:
branch:
description: 'Branch to check out'
required: false
type: string
default: main

jobs:
license-check:
Expand All @@ -11,6 +17,7 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # required: hatch-vcs runs during uv sync
ref: ${{ inputs.branch }}

- name: Install uv
uses: astral-sh/setup-uv@v5
Expand Down
28 changes: 28 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,33 @@ on:
description: 'Release version (e.g. 0.1.0 or v0.1.0 — leading v is stripped automatically)'
required: true
type: string
branch:
description: 'Branch to cut the release from (defaults to main)'
required: false
type: string
default: main

jobs:
validate-branch:
name: Validate release branch
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Check branch exists on origin
env:
GH_TOKEN: ${{ github.token }}
BRANCH: ${{ inputs.branch }}
run: |
ENCODED_BRANCH="${BRANCH//\//%2F}"
if ! gh api "repos/${{ github.repository }}/branches/${ENCODED_BRANCH}" --silent 2>/dev/null; then
echo "::error::Branch '${BRANCH}' does not exist. Check for typos."
exit 1
fi
echo "Branch '${BRANCH}' confirmed."

test:
name: Test (Python ${{ matrix.python-version }})
needs: [validate-branch]
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
Expand All @@ -21,6 +44,7 @@ jobs:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0 # required: hatch-vcs needs full tag history
ref: ${{ inputs.branch }}

- name: Install uv
uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5
Expand All @@ -35,7 +59,10 @@ jobs:
run: uv run --python ${{ matrix.python-version }} pytest -m "not postgres" --tb=short -q

license-check:
needs: [validate-branch]
uses: ./.github/workflows/_license-check.yml
Comment on lines 61 to 63

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This limitation was explicitly acknowledged in the design spec and scoped out: the license check validates installed dependencies (from pyproject.toml/uv.lock), not branch-specific source, so running it against the dispatch ref is considered acceptable for this workflow. The _license-check.yml reusable workflow has no workflow_call inputs, so it cannot receive a ref without a more involved interface change — that's a separate piece of work. Leaving as-is per the original design decision.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not address this change in this issue?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 492530e. Added a branch input (default main) to _license-check.yml's workflow_call trigger and wired ref: ${{ inputs.branch }} into its checkout step. The license-check job in release.yml now passes with: branch: ${{ inputs.branch }} through to the reusable workflow.

with:
branch: ${{ inputs.branch }}

build:
name: Build distribution
Expand All @@ -57,6 +84,7 @@ jobs:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0 # required: hatch-vcs reads tag to set version
ref: ${{ inputs.branch }}

- name: Configure git identity
run: |
Expand Down
30 changes: 25 additions & 5 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,20 @@ Releases are triggered from the GitHub Actions UI — no manual `git tag` step r

2. **Trigger the release workflow** — go to
**[Actions → Release → Run workflow](https://github.com/nauticalab/orcapod-python/actions/workflows/release.yml)**
in the GitHub UI, enter the version (e.g. `0.1.0`), and click **Run workflow**.
in the GitHub UI, enter the version (e.g. `0.1.0`), optionally enter a branch name
(defaults to `main`), and click **Run workflow**.

A leading `v` is stripped automatically — `v0.1.0` and `0.1.0` both work.

3. **CI takes over** — the workflow runs the following jobs automatically:

```
test ──────────┐
license-check ────┤─ build ─┬─ publish-testpypi ─ publish-pypi ─┐
└─ linear-sync ─────────────────────┴─ linear-complete
validate-branch ─┬─ test ──────────┐
└─ license-check ──┤─ build ─┬─ publish-testpypi ─ publish-pypi ─┐
└─ linear-sync ─────────────────────┴─ linear-complete
```

- Pre-flight: tests on Python 3.11 and 3.12, plus license check (in parallel)
- Pre-flight: branch validation, then tests on Python 3.11 and 3.12 and license check (parallel after validation)
- Build: normalises version, creates local tag, builds wheel + sdist, pushes tag to origin
- TestPyPI: publishes to test.pypi.org first as a staging step
- PyPI: publishes to pypi.org and creates a GitHub Release with generated release notes
Expand All @@ -42,6 +43,25 @@ workflow input. PyPI handles the stable vs pre-release distinction natively:
- `pip install orcapod` — installs the latest **stable** release only
- `pip install --pre orcapod` — installs the latest release including pre-releases

## Cutting a Hotfix Release

To release from a branch other than `main` — for example, a maintenance branch carrying
a critical patch — enter the branch name in the **Branch** field when triggering the
workflow.
Comment on lines +48 to +50

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 255d054. Added a step 2 to the hotfix example explicitly calling out that the Use workflow from dropdown should remain on main (not hotfix/0.1.x), so the workflow version with the Branch field is used.


**Example:** cutting `v0.1.1` from `hotfix/0.1.x`:

1. **Trigger the release workflow** — go to
**[Actions → Release → Run workflow](https://github.com/nauticalab/orcapod-python/actions/workflows/release.yml)**
2. In the **Use workflow from** dropdown, keep `main` selected (so the workflow version
includes the `Branch` field — do not select `hotfix/0.1.x` here)
3. Set **Version** to `0.1.1`
4. Set **Branch** to `hotfix/0.1.x`
5. Click **Run workflow**

The workflow will confirm the branch exists, run tests against it, create the `v0.1.1`
tag at its tip, and publish to PyPI — identical to a normal release.

## Tag Format

| Release type | Tag format | Example |
Expand Down
Loading
Loading