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
47 changes: 17 additions & 30 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,60 +1,47 @@
name: Publish
on:
workflow_dispatch:
inputs:
version_type:
type: choice
description: Version type
default: minor
options:
- major
- minor
- patch
jobs:
publish:
runs-on: ubuntu-latest
permissions:
id-token: write # required for PyPI Trusted Publishing (OIDC)
contents: write # create the GitHub Release
contents: write # create the tag and GitHub Release
pull-requests: write # comment on PRs included in the release
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
token: ${{ secrets.GH_API_TOKEN }}
- name: Setup git repo
run: |
git config user.name $GITHUB_ACTOR
git config user.email gh-actions-${GITHUB_ACTOR}@github.com
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: 3.12
- name: Resolve version to publish
id: version
run: |
version=$(python -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["tool"]["poetry"]["version"])')
echo "version=${version}" >> $GITHUB_OUTPUT
- name: Verify the release tag does not already exist
env:
TAG_NAME: ${{ steps.version.outputs.version }}
run: |
if git ls-remote --exit-code --tags origin "refs/tags/${TAG_NAME}" >/dev/null 2>&1; then
echo "::error::Tag ${TAG_NAME} already exists. Bump the version in pyproject.toml first."
exit 1
fi
- name: Install dependencies
run: |
pip install poetry
poetry install
- name: Bump Version
id: bump_version
run: |
NEW_VERSION=$(python scripts/update_version.py ${{ github.event.inputs.version_type }})
echo "NEW_VERSION=$NEW_VERSION"
echo "new_version=$(echo $NEW_VERSION)" >> $GITHUB_OUTPUT
- name: Generate with new version
run: ./scripts/generate.sh
- name: Test with pytest
run: poetry run pytest
- name: Build
run: poetry build
- name: Commit and push changes
run: |
git add ynab/configuration.py ynab/api_client.py ynab/__init__.py pyproject.toml openapi-generator-config.yaml
git commit -m 'Bumping version for ${{ steps.bump_version.outputs.new_version }}'
git push
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
- name: Create a Release
id: create-release
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
with:
tag_name: ${{ steps.bump_version.outputs.new_version }}
tag_name: ${{ steps.version.outputs.version }}
generate_release_notes: true
- name: Comment on PRs with link to release they are included in
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
Expand Down
11 changes: 7 additions & 4 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@

## Generating

1. Run `scripts/generate.sh`. This will generate the API client from the latest OpenAPI spec. Once generated, you should open a PR and merge the changes.

Alternatively, run `scripts/generate-and-pr.sh` to do the above and automate the PR. It wraps `generate.sh`, detects the old → new spec version, and (after you confirm) ensures you're on a `gen-<version>` branch, then commits, pushes, and opens a PR against `main` via `git`/`gh`, printing the PR URL. The [`claude`](https://docs.claude.com/en/docs/claude-code/overview) CLI is used only to draft the PR description from the spec diff. Requires the `gh` and `claude` CLIs to be installed and authenticated.
1. Run `scripts/generate.sh`. This will bump the package version and generate the API client from the latest OpenAPI spec. The bump defaults to `minor`; pass `major` or `patch` to change it (`scripts/generate.sh patch`), or `none` to regenerate without bumping. Once generated, you should open a PR and merge the changes.

## Publishing

Run the "Publish" GitHub Actions workflow.
The version that gets published is whatever `pyproject.toml` on the `main` branch says, so publishing is two steps.

1. Merge a PR that sets the new version. `scripts/generate.sh` does this for you. For a release that does not involve re-generating the client, run `python3 scripts/update_version.py minor` (or `major` / `patch`), which updates `pyproject.toml` and `openapi-generator-config.yaml` without creating a commit or tag.
2. Run the "Publish" GitHub Actions workflow. This builds, tests, and publishes that version to PyPI, then tags the commit and creates a GitHub release.

The workflow never changes the version itself. If the version in `pyproject.toml` has already been released, the workflow fails before publishing anything.
111 changes: 0 additions & 111 deletions scripts/generate-and-pr.sh

This file was deleted.

32 changes: 28 additions & 4 deletions scripts/generate.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,35 @@
#!/usr/bin/env bash
#
# Regenerate the API client from the latest YNAB OpenAPI spec and bump the
# package version.
#
# Usage: scripts/generate.sh [major|minor|patch|none] (defaults to minor)
#
# The generator embeds the version in pyproject.toml and the client itself, so
# the bump has to happen before generating. Pass "none" to regenerate without
# bumping.

set -x
set -euo pipefail

echo "Downloading latest YNAB API OpenAPI spec...";
VERSION_TYPE="${1:-minor}"
case "$VERSION_TYPE" in
major | minor | patch | none) ;;
*)
echo "Invalid version type: $VERSION_TYPE (expected major, minor, patch, or none)" >&2
exit 1
;;
esac

if [[ "$VERSION_TYPE" != "none" ]]; then
echo "Bumping package version ($VERSION_TYPE)..."
NEW_VERSION="$(python3 scripts/update_version.py "$VERSION_TYPE")"
echo "New package version: $NEW_VERSION"
fi

echo "Downloading latest YNAB API OpenAPI spec..."
wget https://api.ynab.com/papi/open_api_spec.yaml -O ./open_api_spec.yaml

echo "Running openapi-generator generate..."
openapi-generator generate -i ./open_api_spec.yaml -g python -t ./templates -c openapi-generator-config.yaml -o ./
openapi-generator generate -i ./open_api_spec.yaml -g python -t ./templates -c openapi-generator-config.yaml -o ./

echo "Success!"
echo "Success!"