Skip to content

Commit ba91b8e

Browse files
dbrattliclaude
andcommitted
ci: adopt EasyBuild.ShipIt for release automation
Move release management to ShipIt with a single root CHANGELOG, matching the setup used in Fable.Actor and Fable.Beam. ShipIt opens a release PR on pushes to main and the publish workflow packs and pushes to NuGet when that PR is merged. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d7c965e commit ba91b8e

5 files changed

Lines changed: 109 additions & 43 deletions

File tree

‎.config/dotnet-tools.json‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@
2222
"fantomas"
2323
],
2424
"rollForward": false
25+
},
26+
"easybuild.shipit": {
27+
"version": "2.0.0",
28+
"commands": [
29+
"shipit"
30+
],
31+
"rollForward": false
2532
}
2633
}
2734
}

‎.github/workflows/publish.yml‎

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,49 @@
1+
name: Publish NuGet
2+
13
on:
2-
release:
3-
types: [published]
4+
push:
5+
branches: [main]
46

57
permissions:
6-
contents: read
7-
8-
name: Publish NuGet
8+
contents: write
9+
pull-requests: write
910

1011
jobs:
11-
publish:
12+
shipit-pr:
13+
name: ShipIt - Pull Request
14+
runs-on: ubuntu-latest
15+
if: "!startsWith(github.event.head_commit.message, 'chore: release ')"
16+
timeout-minutes: 10
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v6
20+
with:
21+
fetch-depth: 0
22+
23+
- name: Setup .NET Core
24+
uses: actions/setup-dotnet@v5
25+
with:
26+
dotnet-version: |
27+
8.x
28+
9.x
29+
10.x
30+
31+
- name: Install tools
32+
run: dotnet tool restore
33+
34+
- name: ShipIt (Pull Request)
35+
run: dotnet shipit --pre-release rc
36+
env:
37+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
38+
39+
release:
40+
name: Release
1241
runs-on: ubuntu-latest
1342
timeout-minutes: 10
43+
if: "startsWith(github.event.head_commit.message, 'chore: release ')"
1444
steps:
1545
- name: Checkout code
16-
uses: actions/checkout@v4
46+
uses: actions/checkout@v6
1747

1848
- name: Setup .NET Core
1949
uses: actions/setup-dotnet@v5
@@ -26,16 +56,12 @@ jobs:
2656
- name: Install just
2757
uses: extractions/setup-just@v3
2858

29-
- name: Restore dependencies
59+
- name: Install tools
3060
run: |
3161
dotnet tool restore
3262
dotnet restore src
3363
34-
- name: Pack NuGet
64+
- name: Build, pack and push
65+
run: just release
3566
env:
36-
TAG_NAME: ${{ github.event.release.tag_name }}
37-
run: just pack-version ${TAG_NAME#v}
38-
39-
- name: Push NuGet
40-
run: dotnet nuget push src/bin/Release/*.nupkg -s https://api.nuget.org/v3/index.json -k ${{ secrets.NUGET_API_KEY }}
41-
continue-on-error: false
67+
NUGET_KEY: ${{ secrets.NUGET_API_KEY }}

‎CHANGELOG.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1+
---
2+
last_commit_released: 8223cc8eb8b2dcaa02c1a19566c5ed5d73242b11
3+
name: Fable.Python
4+
---
5+
16
# Changelog
27

8+
All notable changes to this project will be documented in this file.
9+
310
## [5.0.0-alpha.21.5](https://github.com/fable-compiler/Fable.Python/compare/v5.0.0-alpha.21.4...v5.0.0-alpha.21.5) (2025-12-21)
411

512
### Bug Fixes

‎RELEASING.md‎

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,52 @@
1-
# Releasing Fable.Python
1+
# Releasing
22

3-
## Version Format
3+
This project uses [EasyBuild.ShipIt](https://github.com/easybuild-org/EasyBuild.ShipIt)
4+
for release automation and [Conventional Commits](https://www.conventionalcommits.org/)
5+
for versioning.
46

5-
Fable.Python uses the version format `X.Y.Z-alpha.N.P` where:
7+
## Commit conventions
68

7-
- `X.Y.Z-alpha.N` matches the Fable version (e.g., `5.0.0-alpha.22`)
8-
- `P` is the patch version for Fable.Python releases (0, 1, 2, etc.)
9+
PR titles must follow the conventional commit format (enforced by CI):
910

10-
Example: `5.0.0-alpha.22.0`, `5.0.0-alpha.22.1`, `5.0.0-alpha.22.2`
11+
| Prefix | Version bump | Example |
12+
| --- | --- | --- |
13+
| `feat:` | minor | `feat: add Pydantic field validators` |
14+
| `fix:` | patch | `fix: correct FastAPI response type` |
15+
| `feat!:` | major | `feat!: rename Flask decorator` |
16+
| `chore:` | patch | `chore: update dependencies` |
17+
| `docs:` | patch | `docs: update README` |
18+
| `refactor:` | patch | `refactor: simplify JSON bindings` |
1119

12-
## Release Process
20+
Other valid prefixes: `test`, `perf`, `ci`, `build`, `style`, `revert`.
1321

14-
1. Go to [GitHub Releases](https://github.com/fable-compiler/Fable.Python/releases)
15-
2. Click **"Draft a new release"**
16-
3. Create a new tag in the format `v5.0.0-alpha.22.0` (with `v` prefix)
17-
4. Set the release title (e.g., `5.0.0-alpha.22.0`)
18-
5. Write release notes (or use "Generate release notes")
19-
6. For pre-release versions, check **"Set as a pre-release"**
20-
7. Click **"Publish release"**
22+
## Creating a release
2123

22-
The publish workflow will automatically build and push the NuGet package.
24+
Releases are driven automatically by the `Publish NuGet` workflow on pushes to
25+
`main`. ShipIt opens a `chore: release ...` PR that bumps the version in
26+
`CHANGELOG.md`; merging that PR triggers the publish job, which packs and pushes
27+
the NuGet package.
2328

24-
## Syncing with a New Fable Version
29+
To run ShipIt locally (for example to preview the next version or cut a release
30+
manually):
2531

26-
When Fable releases a new version (e.g., `5.0.0-alpha.23`):
32+
```bash
33+
just shipit
34+
```
2735

28-
1. Update the codebase to work with the new Fable version
29-
2. Create a release with tag `v5.0.0-alpha.23.0`
36+
This will:
3037

31-
## Version History Example
38+
1. Analyze commits since the last release
39+
2. Determine the next semantic version
40+
3. Update `CHANGELOG.md`
41+
4. Create a GitHub release with the version tag (e.g. `v5.0.0-rc.3`)
3242

33-
- `5.0.0-alpha.21.0` (initial sync with Fable 5.0.0-alpha.21)
34-
- `5.0.0-alpha.21.1` (first patch)
35-
- `5.0.0-alpha.21.2` (second patch)
36-
- `5.0.0-alpha.22.0` (sync with Fable 5.0.0-alpha.22)
37-
- `5.0.0-alpha.22.1` (first patch for alpha.22)
43+
Merging a ShipIt release PR (or publishing a release tag) triggers the workflow
44+
to:
45+
46+
1. Pack the NuGet package (`Fable.Python`) using the version from `CHANGELOG.md`
47+
2. Push it to nuget.org using the `NUGET_API_KEY` secret
48+
49+
## Prerequisites
50+
51+
- `NUGET_API_KEY` repository secret (glob pattern: `Fable.Python*`)
52+
- `GITHUB_TOKEN` or `gh` CLI authenticated (for ShipIt to create releases)

‎justfile‎

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,26 @@ test-python: build
6161
{{fable}} {{test_path}} --lang Python --outDir {{build_path}}/tests
6262
uv run pytest {{build_path}}/tests
6363

64-
# Create NuGet package
65-
pack: build
66-
dotnet pack {{src_path}} -c Release
64+
# Create NuGet package with version from CHANGELOG.md
65+
pack:
66+
#!/usr/bin/env bash
67+
set -euo pipefail
68+
VERSION=$(grep -m1 '^## ' CHANGELOG.md | sed 's/^## \[\?\([^] ]*\).*/\1/')
69+
dotnet pack {{src_path}} -c Release -p:PackageVersion=$VERSION -p:InformationalVersion=$VERSION
6770
6871
# Create NuGet package with specific version (used in CI)
6972
# Note: FileVersion must be numeric-only (e.g., 5.0.0.0), so we don't set it for prerelease versions
7073
pack-version version:
7174
dotnet pack {{src_path}} -c Release -p:PackageVersion={{version}} -p:InformationalVersion={{version}}
7275

76+
# Release: pack and push to NuGet (used in CI)
77+
release: pack
78+
dotnet nuget push '{{src_path}}/bin/Release/*.nupkg' -s https://api.nuget.org/v3/index.json -k $NUGET_KEY
79+
80+
# Run EasyBuild.ShipIt for release management
81+
shipit *args:
82+
dotnet shipit --pre-release rc {{args}}
83+
7384
# Format code with Fantomas
7485
format:
7586
dotnet fantomas {{src_path}} -r

0 commit comments

Comments
 (0)