Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
37ee806
New release config
maximilianruesch Jun 19, 2026
e69d5f8
Remove tests for now
maximilianruesch Jun 19, 2026
934317f
Formatting
maximilianruesch Jun 19, 2026
99961db
Simplify release checks
maximilianruesch Jun 19, 2026
2a06bb3
Major guarding
maximilianruesch Jun 19, 2026
87840ec
Major guarding
maximilianruesch Jun 19, 2026
442a22d
Naming is important
maximilianruesch Jun 19, 2026
32a776c
Adjust commit groups
maximilianruesch Jun 19, 2026
b9ef910
Refactor a bit
maximilianruesch Jun 19, 2026
f073697
More refactor
maximilianruesch Jun 19, 2026
fc38f1c
Auto through git cliff
maximilianruesch Jun 19, 2026
04ce3ec
Refactor
maximilianruesch Jun 19, 2026
c1174ff
Add a comment
maximilianruesch Jun 19, 2026
cbdf898
Name change
maximilianruesch Jun 19, 2026
eb39a21
Run on headref
maximilianruesch Jun 19, 2026
740a587
temp: Run on my branch
maximilianruesch Jun 19, 2026
82fa02a
Do everything in draft
maximilianruesch Jun 19, 2026
4961e50
No project
maximilianruesch Jun 19, 2026
fd46c16
More no project
maximilianruesch Jun 19, 2026
5c43e93
parse with optional minor and patch for now
maximilianruesch Jun 19, 2026
2468465
Also refresh release notes here
maximilianruesch Jun 19, 2026
fba2a13
No more project
maximilianruesch Jun 19, 2026
2b36512
Include release pr in branch name
maximilianruesch Jun 19, 2026
9552dd2
Yup
maximilianruesch Jun 19, 2026
c4d74c3
Revert "temp: Run on my branch"
maximilianruesch Jun 19, 2026
a602d98
Reapply "temp: Run on my branch"
maximilianruesch Jun 19, 2026
914123b
No extra PR refs in changelog
maximilianruesch Jun 22, 2026
d5d14a9
Specific git commits
maximilianruesch Jun 22, 2026
59abd01
Fix extract changelog
maximilianruesch Jun 22, 2026
764b45d
try releasing a thing
maximilianruesch Jun 22, 2026
7640c5b
Rename workflow
maximilianruesch Jun 22, 2026
114a0bb
Whitespace
maximilianruesch Jun 22, 2026
564bd28
Unwanted changes
maximilianruesch Jun 22, 2026
f0925cb
Formatting
maximilianruesch Jun 22, 2026
02b2b2d
Update patch release workflow
maximilianruesch Jun 22, 2026
d338ff4
Release note sync and cleanup
maximilianruesch Jun 22, 2026
d865355
Address review comments
maximilianruesch Jun 22, 2026
fa0f049
Revert "Reapply "temp: Run on my branch""
maximilianruesch Jun 22, 2026
5087b10
Revert "Remove tests for now"
maximilianruesch Jun 22, 2026
60f8123
Moar tests
maximilianruesch Jun 22, 2026
e0ff53d
EVEN MOAR
maximilianruesch Jun 22, 2026
7579b2c
Tests are my lifeblood
maximilianruesch Jun 22, 2026
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
50 changes: 50 additions & 0 deletions .github/actions/update-release-preview/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Update release-notes preview
description: >-
Refresh the verbatim release-notes preview block in a release PR's body, using
the committed changelog sections (the exact text that will be published).

Assumes that uv is set up in the job using this action.

inputs:
pr-number:
description: The release PR number to update.
required: true
guppylang-version:
description: The guppylang version being released.
required: true
internals-version:
description: The guppylang-internals version being released.
required: true
token:
description: Token with pull-requests write permission.
required: true

runs:
using: composite
steps:
- shell: bash
env:
GUPPY_VERSION: ${{ inputs.guppylang-version }}
INTERNALS_VERSION: ${{ inputs.internals-version }}
NUMBER: ${{ inputs.pr-number }}
GITHUB_TOKEN: ${{ inputs.token }} # For GH CLI auth
run: |
set -euo pipefail
# Extract verbatim sections (empty file if the section is missing).
uv run --no-project scripts/release/extract_changelog.py \
guppylang/CHANGELOG.md "$GUPPY_VERSION" > /tmp/guppy_section.md || true
uv run --no-project scripts/release/extract_changelog.py \
guppylang-internals/CHANGELOG.md "$INTERNALS_VERSION" > /tmp/internals_section.md || true

gh pr view "$NUMBER" --json body --jq .body > /tmp/pr_body.md
uv run --no-project scripts/release/render_pr_body.py \
--body /tmp/pr_body.md \
--package guppylang "$GUPPY_VERSION" /tmp/guppy_section.md \
--package guppylang-internals "$INTERNALS_VERSION" /tmp/internals_section.md \
> /tmp/pr_body_new.md

if ! cmp -s /tmp/pr_body.md /tmp/pr_body_new.md; then
gh pr edit "$NUMBER" --body-file /tmp/pr_body_new.md
else
echo "Preview already up to date."
fi
6 changes: 3 additions & 3 deletions .github/workflows/python-wheels.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build and publish python wheels
name: Python wheels
# Builds and publishes the wheels on pypi.
#
# When running on a push-to-main event, or as a workflow dispatch on a branch,
Expand Down Expand Up @@ -31,13 +31,13 @@ jobs:
name: Package wheels and test
runs-on: ubuntu-latest
steps:
# Skip the workflow when triggered by a release event for a non guppylang package.
# Skip the workflow when triggered by a release event for a non guppylang(-internals) package.
- name: Check tag
id: check-tag
run: |
echo "run=$SHOULD_RUN" >> $GITHUB_OUTPUT
env:
SHOULD_RUN: ${{ (github.event_name != 'release' && (github.ref == 'refs/heads/main' || startsWith(github.head_ref, 'release-please-')) ) || ( github.ref_type == 'tag' && (startsWith(github.ref, 'refs/tags/guppylang-v') || startsWith(github.ref, 'refs/tags/guppylang-internals-v'))) }}
SHOULD_RUN: ${{ (github.event_name != 'release' && (github.ref == 'refs/heads/main' || startsWith(github.head_ref, 'release-pr--'))) || (github.ref_type == 'tag' && (startsWith(github.ref, 'refs/tags/guppylang-v') || startsWith(github.ref, 'refs/tags/guppylang-internals-v'))) }}

- uses: actions/checkout@v6
if: ${{ steps.check-tag.outputs.run == 'true' }}
Expand Down
93 changes: 17 additions & 76 deletions .github/workflows/release-checks.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
# A check that ensures that `guppylang` and `guppylang-internals` work correctly with the lowest and highest allowed
# versions of their dependencies. Additionally, `guppylang` is tested to work with the latest released version of
# `guppylang-internals`.
# versions of their dependencies.
#
# If either checks fail, it is likely that the packages are not compatible with the respective versions of their
# dependencies and the version ranges have to be adjusted. Additionally, this might fail if `guppylang` requires an
# unreleased or unpublished version of `guppylang-internals`.
# If checks fail, it is likely that the packages are not compatible with the respective versions of their dependencies
# and the version ranges have to be adjusted.

name: 🚚 Release checks

Expand All @@ -19,15 +17,10 @@ env:
UV_VERSION: "0.9.5"

jobs:
check-release-guppylang-internals:
name: Check `guppylang-internals` release compatibility with ${{ matrix.target.resolution }} dependencies
check-release-guppylang:
name: Check release compatibility with ${{ matrix.target.resolution }} dependencies
runs-on: ubuntu-latest
# Check if we are running on a release PR, targeting some branch (sits in the middle of the release branch name)
#
# release-please always uses this branch name.
if: |
github.event_name == 'workflow_dispatch' ||
(startsWith(github.head_ref, 'release-please--') && endsWith(github.head_ref, '--components--guppylang-internals'))
if: github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-pr--')
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -59,69 +52,16 @@ jobs:
echo "\nDone! Installed dependencies:"
uv pip list
- name: Type check with mypy
run: uv run --no-sync mypy guppylang-internals
- name: Lint with ruff
run: uv run --no-sync ruff check guppylang-internals
- name: Run tests
run: UV_NO_SYNC=1 just test

check-release-guppylang:
name: Check `guppylang` release compatibility with ${{ matrix.target.resolution }} dependencies
runs-on: ubuntu-latest
# Check if we are running on a release PR, targeting some branch (sits in the middle of the release branch name)
#
# release-please always uses this branch name.
if: |
github.event_name == 'workflow_dispatch' ||
(startsWith(github.head_ref, 'release-please--') && endsWith(github.head_ref, '--components--guppylang'))
strategy:
fail-fast: false
matrix:
target:
- resolution: "highest"
python: "3.14"
- resolution: "lowest-direct"
python: "3.10"
steps:
- uses: actions/checkout@v6
- uses: mozilla-actions/sccache-action@v0.0.10
- name: Set up uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ env.UV_VERSION }}
enable-cache: true
- name: Set up Just
uses: extractions/setup-just@v4
- name: Install Python ${{ matrix.target.python }}
run: |
uv python install ${{ matrix.target.python }}
uv python pin ${{ matrix.target.python }}
- name: Setup `guppylang` with only pypi dependencies
env:
RES: ${{ matrix.target.resolution }}
run: |
UV_RESOLUTION="$RES" uv lock --prerelease=allow --no-sources -U
UV_RESOLUTION="$RES" uv sync --prerelease=allow --no-sources --no-install-workspace
# Install the latest published release of guppylang-internals.
uv pip install --no-sources --prerelease allow guppylang-internals
# Install the local version of guppylang.
uv pip install -e guppylang --no-deps
echo "\nDone! Installed dependencies:"
uv pip list
- name: Type check with mypy
run: uv run --no-sync mypy guppylang
run: uv run --no-sync mypy guppylang guppylang-internals
- name: Lint with ruff
run: uv run --no-sync ruff check guppylang
run: uv run --no-sync ruff check guppylang guppylang-internals
- name: Run tests
run: UV_NO_SYNC=1 just test


check-guppy-docs-build:
name: Check the guppy-docs build for `guppylang` release
runs-on: ubuntu-latest
if: |
github.event_name == 'workflow_dispatch' ||
(startsWith(github.head_ref, 'release-please--') && endsWith(github.head_ref, '--components--guppylang'))
if: github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-pr--')
steps:
- uses: actions/checkout@v6
with:
Expand All @@ -140,30 +80,31 @@ jobs:
run: |
cd guppy-docs
uv add "guppylang @ git+https://github.com/Quantinuum/guppylang.git@${{ github.event.pull_request.head.sha }}#subdirectory=guppylang" || uv sync --group docs
- name: Checkout guppylang release-please manifest
- name: Checkout guppylang pyproject.toml
uses: actions/checkout@v6
with:
repository: Quantinuum/guppylang
ref: ${{ github.event.pull_request.head.sha }}
path: guppylang
sparse-checkout: |
.release-please-manifest.json
guppylang/pyproject.toml
sparse-checkout-cone-mode: false
- name: Verify guppylang version
run: |
cd guppy-docs
uv run python <<'PY'
import json
import re
from pathlib import Path
import guppylang

GUPPYLANG_PACKAGE_VERSION = guppylang.__version__

with Path.open(Path("../guppylang/.release-please-manifest.json")) as json_data:
release_please_data = json.load(json_data)
MANIFEST_GUPPYLANG_VERSION = release_please_data["guppylang"]
pyproject = Path("../guppylang/guppylang/pyproject.toml").read_text()
match = re.search(r'^version = "([^"]+)"', pyproject, re.MULTILINE)
assert match is not None, "Could not find the guppylang project version"
PYPROJECT_GUPPYLANG_VERSION = match.group(1)

assert GUPPYLANG_PACKAGE_VERSION == MANIFEST_GUPPYLANG_VERSION
assert GUPPYLANG_PACKAGE_VERSION == PYPROJECT_GUPPYLANG_VERSION
print(f"Verification complete! Verified Guppy version is {GUPPYLANG_PACKAGE_VERSION}")
PY
- name: Run docs build
Expand Down
56 changes: 56 additions & 0 deletions .github/workflows/release-major-guard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Guards against an accidental major version bump of `guppylang` in a release PR.
# Add the `X-allow-major-bump` label to the release PR opt-out of this guard.

name: 🚚 Release major-bump guard

on:
pull_request:
branches:
- main
types:
- opened
- synchronize
- reopened
- labeled
- unlabeled

permissions:
contents: read

env:
ALLOW_MAJOR_BUMP_LABEL: "X-allow-major-bump"

jobs:
guard:
name: Disallow unapproved major bump
runs-on: ubuntu-latest
if: startsWith(github.head_ref, 'release-pr--')
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Compare guppylang major versions
env:
LABELS: ${{ toJSON(github.event.pull_request.labels.*.name) }}
BASE_REF: ${{ github.base_ref }}
run: |
set -euo pipefail
major() { sed -n 's/^version = "\([0-9][0-9]*\)\..*/\1/p' "$1" | head -n1; }

head_major=$(major guppylang/pyproject.toml)
git fetch origin "$BASE_REF" --depth=1
git show "origin/$BASE_REF:guppylang/pyproject.toml" > /tmp/base_pyproject.toml
base_major=$(major /tmp/base_pyproject.toml)

echo "guppylang major version: base=$base_major head=$head_major"
if [ "$head_major" -gt "$base_major" ]; then
if echo "$LABELS" | jq -e --arg l "$ALLOW_MAJOR_BUMP_LABEL" 'index($l)' >/dev/null; then
echo "Major bump permitted by the '$ALLOW_MAJOR_BUMP_LABEL' label."
else
echo "::error::guppylang major version would bump $base_major → $head_major. Add the '$ALLOW_MAJOR_BUMP_LABEL' label to allow this release."
exit 1
fi
else
echo "No major bump detected."
fi
23 changes: 0 additions & 23 deletions .github/workflows/release-please.yml

This file was deleted.

54 changes: 54 additions & 0 deletions .github/workflows/release-pr-changelog-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Keeps the release-notes preview in the release PR body in sync with the
# committed changelogs. Does not commit, so it cannot loop.

name: 🚚 Release PR changelog preview

on:
pull_request:
types:
- synchronize
branches:
- main
workflow_dispatch:

permissions:
contents: read
pull-requests: write

concurrency:
group: release-pr-preview-${{ github.head_ref }}
cancel-in-progress: true

env:
UV_VERSION: "0.11.22"

jobs:
preview:
name: Refresh release-notes preview
runs-on: ubuntu-latest
if: startsWith(github.head_ref, 'release-pr--')
steps:
- uses: actions/checkout@v6

- name: Read released versions
id: versions
run: |
set -euo pipefail
guppy=$(sed -n 's/^version = "\(.*\)"/\1/p' guppylang/pyproject.toml | head -n1)
internals=$(sed -n 's/^version = "\(.*\)"/\1/p' guppylang-internals/pyproject.toml | head -n1)
echo "guppylang=$guppy" >> "$GITHUB_OUTPUT"
echo "internals=$internals" >> "$GITHUB_OUTPUT"

- name: Set up uv
uses: astral-sh/setup-uv@v7
with:
version: ${{ env.UV_VERSION }}
enable-cache: true

- name: Refresh release-notes preview
uses: ./.github/actions/update-release-preview
with:
pr-number: ${{ github.event.pull_request.number }}
guppylang-version: ${{ steps.versions.outputs.guppylang }}
internals-version: ${{ steps.versions.outputs.internals }}
token: ${{ secrets.HUGRBOT_PAT }}
Loading
Loading