From f87c7028a3fe1fc81f8e1f5bc4566f2b7d76880a Mon Sep 17 00:00:00 2001 From: Vlada Dusek Date: Wed, 29 Jul 2026 15:40:15 +0200 Subject: [PATCH 1/2] ci: Drop cross-repo model regeneration dispatch to apify-client-python --- .github/workflows/openapi-ci.yaml | 74 ------------------------------- AGENTS.md | 26 ++++------- 2 files changed, 9 insertions(+), 91 deletions(-) diff --git a/.github/workflows/openapi-ci.yaml b/.github/workflows/openapi-ci.yaml index edd7aa311c..55d5493c74 100644 --- a/.github/workflows/openapi-ci.yaml +++ b/.github/workflows/openapi-ci.yaml @@ -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: @@ -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 diff --git a/AGENTS.md b/AGENTS.md index 2fcf787b2b..7340c53fb0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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. + +So a spec change 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 From 51344194eecdb510bf4acc9c06fe87fda7cfea66 Mon Sep 17 00:00:00 2001 From: Vlada Dusek Date: Wed, 29 Jul 2026 16:16:50 +0200 Subject: [PATCH 2/2] docs: Reword AGENTS.md sentence flagged by Vale --- AGENTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 7340c53fb0..ae82b8ce35 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -98,7 +98,7 @@ schema: 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. -So a spec change 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. +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.