Skip to content

Regenerate Client from API Spec #79

Regenerate Client from API Spec

Regenerate Client from API Spec #79

name: Regenerate Client from API Spec
on:
workflow_dispatch:
inputs:
spec_version:
description: "API Spec Version"
required: true
type: string
spec_commit:
description: "Devgraph commit SHA that triggered this"
required: true
type: string
# Optional: Also trigger on schedule to check for missed updates
schedule:
- cron: "0 2 * * *" # Daily at 2am UTC
jobs:
regenerate:
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: 1.7.1
virtualenvs-create: true
virtualenvs-in-project: true
- name: Download API spec
run: |
mkdir -p specs
curl -o specs/openapi.yaml \
https://raw.githubusercontent.com/arctir/devgraph-api/v${{ inputs.spec_version }}/v1/spec.yaml
echo "✓ Downloaded API spec v${{ inputs.spec_version }}"
- name: Generate Python client
run: |
# Install openapi-python-client
pip install openapi-python-client
# Generate client (overwrite existing)
openapi-python-client generate \
--path specs/openapi.yaml \
--output-path . \
--config openapi-generator-config.yaml \
--overwrite
echo "✓ Client generated"
- name: Update client version
run: |
# Update version in pyproject.toml to match API version
sed -i 's/^version = .*/version = "${{ inputs.spec_version }}"/' pyproject.toml
echo "✓ Updated version to ${{ inputs.spec_version }}"
- name: Install dependencies
run: |
# Lock and install dependencies
poetry lock --no-update || poetry lock
poetry install --no-interaction
- name: Run linting
run: |
poetry run ruff check src/ || true
poetry run mypy src/ || true
- name: Run tests
run: |
# Only run tests if they exist and pytest is available
if poetry run which pytest > /dev/null 2>&1; then
poetry run pytest tests/ -v || echo "⚠️ Tests failed or no tests to run"
else
echo "⚠️ pytest not available, skipping tests"
fi
- name: Commit and push changes
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# Check if there are changes to commit
if [[ -n $(git status -s) ]]; then
git add .
git commit -m "$(cat <<'EOF'
Update client for API v${{ inputs.spec_version }}
Auto-generated from devgraph@${{ inputs.spec_commit }}
Spec URL: https://github.com/arctir/devgraph-api/tree/v${{ inputs.spec_version }}
EOF
)"
git push origin main
echo "✓ Changes committed and pushed to main"
# Extract client version from pyproject.toml
CLIENT_VERSION=$(grep '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/')
# Create and push tag
git tag -fa "v${CLIENT_VERSION}" -m "Python client v${CLIENT_VERSION} for API v${{ inputs.spec_version }}"
git push origin "v${CLIENT_VERSION}" --force
echo "✓ Tagged as v${CLIENT_VERSION}"
# Build package
poetry build
echo "✓ Package built"
else
echo "No changes to commit"
fi
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1 # Handles OIDC automatically
with:
repository-url: https://upload.pypi.org/legacy/ # Default for PyPI
- name: Create summary
if: always()
run: |
echo "## 🐍 Python Client Regenerated" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **API Version**: \`${{ inputs.spec_version }}\`" >> $GITHUB_STEP_SUMMARY
echo "- **Source Commit**: [${{ inputs.spec_commit }}](https://github.com/arctir/devgraph/commit/${{ inputs.spec_commit }})" >> $GITHUB_STEP_SUMMARY
echo "- **Spec URL**: https://github.com/arctir/devgraph-api/tree/v${{ inputs.spec_version }}" >> $GITHUB_STEP_SUMMARY