Regenerate models #20
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # This workflow regenerates Pydantic models (src/apify_client/_models.py) from the OpenAPI spec. | |
| # | |
| # It can be triggered in two ways: | |
| # 1. Automatically via workflow_dispatch from the apify-docs CI pipeline (with docs_pr_number and docs_workflow_run_id). | |
| # 2. Manually from the GitHub UI (without any inputs) to regenerate from the live published spec. | |
| name: Regenerate models | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| docs_pr_number: | |
| description: PR number in apify/apify-docs that triggered this workflow (optional for manual runs) | |
| required: false | |
| type: string | |
| docs_workflow_run_id: | |
| description: Workflow run ID in apify/apify-docs that built the OpenAPI spec artifact (optional for manual runs) | |
| required: false | |
| type: string | |
| docs_pr_author: | |
| description: GitHub login of the apify-docs PR author (optional for manual runs) | |
| required: false | |
| type: string | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| concurrency: | |
| group: regenerate-models-${{ inputs.docs_pr_number || 'manual' }} | |
| cancel-in-progress: true | |
| jobs: | |
| regenerate-models: | |
| name: Regenerate models | |
| runs-on: ubuntu-latest | |
| env: | |
| DOCS_PR_NUMBER: ${{ inputs.docs_pr_number }} | |
| BRANCH: ${{ inputs.docs_pr_number && format('update-models-docs-pr-{0}', inputs.docs_pr_number) || 'update-models-manual' }} | |
| TITLE: "${{ inputs.docs_pr_number && format('[TODO]: update generated models from apify-docs PR #{0}', inputs.docs_pr_number) || '[TODO]: update generated models from published OpenAPI spec' }}" | |
| ASSIGNEE: ${{ inputs.docs_pr_author || github.actor }} | |
| REVIEWER: vdusek | |
| LABEL: t-tooling | |
| steps: | |
| - name: Validate inputs | |
| if: inputs.docs_pr_number || inputs.docs_workflow_run_id | |
| run: | | |
| if [[ -n "$DOCS_PR_NUMBER" ]] && ! [[ "$DOCS_PR_NUMBER" =~ ^[1-9][0-9]*$ ]]; then | |
| echo "::error::docs_pr_number must be a positive integer, got: $DOCS_PR_NUMBER" | |
| exit 1 | |
| fi | |
| if [[ -n "${{ inputs.docs_workflow_run_id }}" ]] && ! [[ "${{ inputs.docs_workflow_run_id }}" =~ ^[0-9]+$ ]]; then | |
| echo "::error::docs_workflow_run_id must be a numeric run ID, got: ${{ inputs.docs_workflow_run_id }}" | |
| exit 1 | |
| fi | |
| - name: Checkout apify-client-python | |
| uses: actions/checkout@v6 | |
| with: | |
| token: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }} | |
| # If the branch already exists on the remote (e.g. from a previous run, possibly with | |
| # reviewer commits), check it out to build on top of it instead of starting fresh. | |
| - name: Switch to existing branch or create a new one | |
| run: | | |
| if git ls-remote --exit-code --heads origin "$BRANCH" > /dev/null 2>&1; then | |
| git fetch origin "$BRANCH" | |
| git switch "$BRANCH" | |
| else | |
| git switch -c "$BRANCH" | |
| fi | |
| # Download the pre-built OpenAPI spec artifact from the apify-docs workflow run. | |
| # Skipped for manual runs — datamodel-codegen will fetch from the published spec URL instead. | |
| - name: Download OpenAPI spec artifact | |
| if: inputs.docs_workflow_run_id | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: openapi-bundles | |
| path: openapi-spec | |
| repository: apify/apify-docs | |
| run-id: ${{ inputs.docs_workflow_run_id }} | |
| github-token: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }} | |
| - name: Set up uv | |
| uses: astral-sh/setup-uv@v7 | |
| with: | |
| python-version: "3.14" | |
| - name: Install dependencies | |
| run: uv run poe install-dev | |
| # When a docs workflow run ID is provided, use the downloaded artifact. | |
| # Otherwise, datamodel-codegen fetches from the default URL configured in pyproject.toml. | |
| - name: Generate models from OpenAPI spec | |
| run: | | |
| if [[ -f openapi-spec/openapi.json ]]; then | |
| uv run poe generate-models-from-file openapi-spec/openapi.json | |
| else | |
| uv run poe generate-models | |
| fi | |
| - name: Commit and push model changes | |
| id: commit | |
| uses: EndBug/add-and-commit@v10 | |
| with: | |
| add: src/apify_client/_models.py | |
| author_name: apify-service-account | |
| author_email: apify-service-account@users.noreply.github.com | |
| message: ${{ env.TITLE }} | |
| commit: --no-verify | |
| push: -u origin ${{ env.BRANCH }} | |
| - name: Create or update PR | |
| if: steps.commit.outputs.committed == 'true' | |
| id: pr | |
| env: | |
| GH_TOKEN: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }} | |
| run: | | |
| EXISTING_PR=$(gh pr list --head "$BRANCH" --json url --jq '.[0].url' 2>/dev/null || true) | |
| if [[ -n "$EXISTING_PR" ]]; then | |
| echo "PR already exists: $EXISTING_PR" | |
| echo "pr_url=$EXISTING_PR" >> "$GITHUB_OUTPUT" | |
| echo "created=false" >> "$GITHUB_OUTPUT" | |
| else | |
| if [[ -n "$DOCS_PR_NUMBER" ]]; then | |
| DOCS_PR_URL="https://github.com/apify/apify-docs/pull/${DOCS_PR_NUMBER}" | |
| BODY="This PR updates the auto-generated Pydantic models based on OpenAPI specification changes in [apify-docs PR #${DOCS_PR_NUMBER}](${DOCS_PR_URL})." | |
| else | |
| BODY="This PR updates the auto-generated Pydantic models from the [published OpenAPI specification](https://docs.apify.com/api/openapi.json)." | |
| fi | |
| PR_URL=$(gh pr create \ | |
| --title "$TITLE" \ | |
| --body "$BODY" \ | |
| --head "$BRANCH" \ | |
| --base master \ | |
| --reviewer "$REVIEWER" \ | |
| --assignee "$ASSIGNEE" \ | |
| --label "$LABEL") | |
| echo "Created PR: $PR_URL" | |
| echo "pr_url=$PR_URL" >> "$GITHUB_OUTPUT" | |
| echo "created=true" >> "$GITHUB_OUTPUT" | |
| fi | |
| # Post a cross-repo comment on the original docs PR so reviewers know about the corresponding client-python PR. | |
| - name: Comment on apify-docs PR | |
| if: steps.commit.outputs.committed == 'true' && inputs.docs_pr_number | |
| env: | |
| GH_TOKEN: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }} | |
| PR_CREATED: ${{ steps.pr.outputs.created }} | |
| PR_URL: ${{ steps.pr.outputs.pr_url }} | |
| run: | | |
| if [[ "$PR_CREATED" = "true" ]]; then | |
| COMMENT="A PR to update the Python client models has been created: ${PR_URL} | |
| This was automatically triggered by OpenAPI specification changes in this PR." | |
| else | |
| COMMENT="The Python client model PR has been updated with the latest OpenAPI spec changes: ${PR_URL}" | |
| fi | |
| gh pr comment "$DOCS_PR_NUMBER" \ | |
| --repo apify/apify-docs \ | |
| --body "$COMMENT" | |
| - name: Comment on failure | |
| if: failure() && inputs.docs_pr_number | |
| env: | |
| GH_TOKEN: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }} | |
| run: | | |
| gh pr comment "$DOCS_PR_NUMBER" \ | |
| --repo apify/apify-docs \ | |
| --body "Python client model regeneration failed. [See workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})." \ | |
| || echo "Warning: Failed to post failure comment to apify/apify-docs PR #$DOCS_PR_NUMBER." |