Skip to content
Draft
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
74 changes: 0 additions & 74 deletions .github/workflows/openapi-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,16 @@ name: OpenAPI checks

on:
pull_request:
# The 'closed' type is needed to trigger cleanup of the corresponding apify-client-python PR.
types: [opened, synchronize, reopened, closed]
push:
branches:
- master

permissions:
contents: read
pull-requests: read

jobs:
lint:
name: Lint specification
# Skip lint/build/validate on PR close events - those only need the cleanup job.
if: github.event_name != 'pull_request' || github.event.action != 'closed'
runs-on: ubuntu-latest

steps:
Expand Down Expand Up @@ -101,72 +96,3 @@ jobs:
exit 1
fi
echo "✓ Bundles have valid sizes"

# When a PR changes OpenAPI specs and passes validation, trigger model regeneration in apify-client-python
# so the Python client stays in sync with the API spec.
trigger-client-model-regeneration:
name: Trigger Python client model regeneration
runs-on: ubuntu-latest
needs: [validate]
if: >-
github.event_name == 'pull_request'
&& github.event.action != 'closed'
&& github.event.pull_request.head.repo.full_name == github.repository

steps:
- uses: actions/checkout@v7

- name: Check if OpenAPI files changed
id: changed-files
uses: tj-actions/changed-files@v47
with:
files: 'apify-api/openapi/**'

- name: Trigger apify-client-python model regeneration
if: steps.changed-files.outputs.any_changed == 'true'
env:
GITHUB_TOKEN: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
run: |
gh workflow run manual_regenerate_models.yaml \
--repo apify/apify-client-python \
--field docs_pr_number="$PR_NUMBER" \
--field docs_workflow_run_id="${{ github.run_id }}" \
--field docs_pr_author="$PR_AUTHOR"

# When a docs PR is closed without being merged, clean up the corresponding auto-generated PR
# in apify-client-python to avoid stale PRs piling up.
# If the docs PR is merged, the client PR is left open for manual review and merge.
cleanup-client-model-pr:
name: Close Python client model PR on docs PR close
runs-on: ubuntu-latest
if: >-
github.event_name == 'pull_request'
&& github.event.action == 'closed'
&& github.event.pull_request.merged == false
&& github.event.pull_request.head.repo.full_name == github.repository

steps:
- name: Close corresponding apify-client-python PR
env:
GITHUB_TOKEN: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
# Branch name convention must match what manual_regenerate_models.yaml creates.
run: |
BRANCH="update-models-docs-pr-${PR_NUMBER}"
EXISTING_PR=$(gh pr list \
--repo apify/apify-client-python \
--head "$BRANCH" \
--json number \
--jq '.[0].number // empty' 2>/dev/null || true)

if [[ -n "$EXISTING_PR" ]]; then
gh pr close "$EXISTING_PR" \
--repo apify/apify-client-python \
--delete-branch \
--comment "Closing this PR because the source apify-docs PR #${PR_NUMBER} was closed without merging."
echo "Closed apify-client-python PR #$EXISTING_PR"
else
echo "No corresponding apify-client-python PR found for branch $BRANCH"
fi
26 changes: 9 additions & 17 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,23 +92,15 @@ schema:

### Python API client model generation

OpenAPI spec changes in this repo automatically trigger Pydantic model regeneration in `apify-client-python`. The pipeline:

1. **This repo** (`.github/workflows/openapi-ci.yaml`):
- On PR with changes to `apify-api/openapi/**`: lint, build, and validate the bundled spec
- Upload `static/api/openapi.{json,yaml}` as artifacts
- `trigger-client-model-regeneration` job calls `gh workflow run manual_regenerate_models.yaml` in `apify/apify-client-python`, passing `docs_pr_number` and `docs_workflow_run_id`
- On PR close: `cleanup-client-model-pr` job closes the corresponding PR in `apify-client-python` and deletes its branch

2. **apify-client-python** (`.github/workflows/manual_regenerate_models.yaml`):
- Triggered via `workflow_dispatch` (automatically from this repo's CI or manually from GitHub UI)
- Downloads the OpenAPI spec artifact from this repo's workflow run (or fetches from `https://docs.apify.com/api/openapi.json` for manual runs)
- Runs `datamodel-codegen` to generate Pydantic models into `src/apify_client/_models.py`
- Runs `scripts/postprocess_generated_models.py` to fix known codegen issues (e.g. camelCase discriminator fields)
- Commits to branch `update-models-docs-pr-{PR_NUMBER}`, creates/updates a PR
- Posts a cross-repo comment on the original docs PR linking to the generated client PR

Branch naming convention `update-models-docs-pr-{N}` links the two PRs.
`apify-client-python` generates its Pydantic models from the **published** spec, and it pulls them on its own schedule - this repo does not push anything to it:

1. **This repo** (`.github/workflows/openapi-ci.yaml`): on a PR touching `apify-api/openapi/**`, lints, builds, and validates the bundled spec. Once merged and deployed, the bundle is served at `https://docs.apify.com/api/openapi.json`.

2. **apify-client-python** (`.github/workflows/on_schedule_regenerate_models.yaml`): nightly at 02:00 UTC, refreshes its committed `spec/openapi.json` snapshot from that URL, regenerates the models, and opens a PR when they change.

A spec change therefore reaches the Python client within a day of being deployed, with no coordination needed on this side. Nothing here needs to be merged in lockstep with a client PR.

This used to be a cross-repo dispatch that opened a companion client PR per docs PR. It was removed: the client can only generate from the published spec anyway, and having two mechanisms write the same generated files made them diverge.

### Theme system

Expand Down
Loading