1- # This workflow regenerates Pydantic models (src/apify_client/_models.py) from the OpenAPI spec whenever
2- # the spec changes in an apify/apify-docs PR. It is triggered via workflow_dispatch from the apify-docs CI pipeline.
1+ # This workflow regenerates Pydantic models (src/apify_client/_models.py) from the OpenAPI spec.
2+ #
3+ # It can be triggered in two ways:
4+ # 1. Automatically via workflow_dispatch from the apify-docs CI pipeline (with docs_pr_number and docs_workflow_run_id).
5+ # 2. Manually from the GitHub UI (without any inputs) to regenerate from the live published spec.
36
47name : Regenerate models from OpenAPI spec
58
69on :
710 workflow_dispatch :
811 inputs :
912 docs_pr_number :
10- description : PR number in apify/apify-docs that triggered this workflow
11- required : true
13+ description : PR number in apify/apify-docs that triggered this workflow (optional for manual runs)
14+ required : false
1215 type : string
1316 docs_workflow_run_id :
14- description : Workflow run ID in apify/apify-docs that built the OpenAPI spec artifact
15- required : true
17+ description : Workflow run ID in apify/apify-docs that built the OpenAPI spec artifact (optional for manual runs)
18+ required : false
1619 type : string
1720
1821permissions :
1922 contents : write
2023 pull-requests : write
2124
2225concurrency :
23- group : regenerate-models-${{ inputs.docs_pr_number }}
26+ group : regenerate-models-${{ inputs.docs_pr_number || 'manual' }}
2427 cancel-in-progress : true
2528
2629jobs :
@@ -30,17 +33,18 @@ jobs:
3033
3134 env :
3235 DOCS_PR_NUMBER : ${{ inputs.docs_pr_number }}
33- BRANCH : " update-models-docs-pr-${{ inputs.docs_pr_number }} "
34- TITLE : " [TODO]: update generated models from apify-docs PR #${{ inputs.docs_pr_number }}"
36+ BRANCH : ${{ inputs.docs_pr_number && format(' update-models-docs-pr-{0}', inputs.docs_pr_number) || 'update-models-manual' }}
37+ 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' }}"
3538
3639 steps :
3740 - name : Validate inputs
41+ if : inputs.docs_pr_number || inputs.docs_workflow_run_id
3842 run : |
39- if ! [[ "$DOCS_PR_NUMBER" =~ ^[1-9][0-9]*$ ]]; then
43+ if [[ -n "$DOCS_PR_NUMBER" ]] && ! [[ "$DOCS_PR_NUMBER" =~ ^[1-9][0-9]*$ ]]; then
4044 echo "::error::docs_pr_number must be a positive integer, got: $DOCS_PR_NUMBER"
4145 exit 1
4246 fi
43- if ! [[ "${{ inputs.docs_workflow_run_id }}" =~ ^[0-9]+$ ]]; then
47+ if [[ -n "${{ inputs.docs_workflow_run_id }}" ]] && ! [[ "${{ inputs.docs_workflow_run_id }}" =~ ^[0-9]+$ ]]; then
4448 echo "::error::docs_workflow_run_id must be a numeric run ID, got: ${{ inputs.docs_workflow_run_id }}"
4549 exit 1
4650 fi
5155 token : ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }}
5256
5357 # Download the pre-built OpenAPI spec artifact from the apify-docs workflow run.
58+ # Skipped for manual runs — datamodel-codegen will fetch from the published spec URL instead.
5459 - name : Download OpenAPI spec artifact
60+ if : inputs.docs_workflow_run_id
5561 uses : actions/download-artifact@v4
5662 with :
5763 name : openapi-bundles
6874 - name : Install dependencies
6975 run : uv run poe install-dev
7076
77+ # When a docs workflow run ID is provided, use the downloaded artifact.
78+ # Otherwise, datamodel-codegen fetches from the default URL configured in pyproject.toml.
7179 - name : Generate models from OpenAPI spec
72- run : uv run datamodel-codegen --input openapi-spec/openapi.json
80+ run : |
81+ if [[ -f openapi-spec/openapi.json ]]; then
82+ uv run datamodel-codegen --input openapi-spec/openapi.json
83+ else
84+ uv run datamodel-codegen
85+ fi
7386
7487 - name : Commit model changes
7588 id : commit
@@ -88,15 +101,16 @@ jobs:
88101 env :
89102 GH_TOKEN : ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }}
90103 run : |
91- DOCS_PR_URL="https://github.com/apify/apify-docs/pull/${DOCS_PR_NUMBER}"
92104 EXISTING_PR=$(gh pr list --head "$BRANCH" --json url --jq '.[0].url' 2>/dev/null || true)
93105
94106 if [[ -n "$EXISTING_PR" ]]; then
95107 echo "PR already exists: $EXISTING_PR"
96108 echo "pr_url=$EXISTING_PR" >> "$GITHUB_OUTPUT"
97109 echo "created=false" >> "$GITHUB_OUTPUT"
98110 else
99- BODY=$(cat <<EOF
111+ if [[ -n "$DOCS_PR_NUMBER" ]]; then
112+ DOCS_PR_URL="https://github.com/apify/apify-docs/pull/${DOCS_PR_NUMBER}"
113+ BODY=$(cat <<EOF
100114 This PR updates the auto-generated Pydantic models based on OpenAPI specification changes in [apify-docs PR #${DOCS_PR_NUMBER}](${DOCS_PR_URL}).
101115
102116 ## Changes
@@ -107,7 +121,17 @@ jobs:
107121
108122 - apify-docs PR: ${DOCS_PR_URL}
109123 EOF
110- )
124+ )
125+ else
126+ BODY=$(cat <<EOF
127+ This PR updates the auto-generated Pydantic models from the published OpenAPI specification.
128+
129+ ## Changes
130+
131+ - Regenerated \`src/apify_client/_models.py\` using \`datamodel-codegen\`
132+ EOF
133+ )
134+ fi
111135
112136 PR_URL=$(gh pr create \
113137 --title "$TITLE" \
@@ -121,7 +145,7 @@ jobs:
121145
122146 # Post a cross-repo comment on the original docs PR so reviewers know about the corresponding client-python PR.
123147 - name : Comment on apify-docs PR
124- if : steps.commit.outputs.committed == 'true'
148+ if : steps.commit.outputs.committed == 'true' && inputs.docs_pr_number
125149 env :
126150 GH_TOKEN : ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }}
127151 PR_CREATED : ${{ steps.pr.outputs.created }}
@@ -140,7 +164,7 @@ jobs:
140164 --body "$COMMENT"
141165
142166 - name : Comment on failure
143- if : failure()
167+ if : failure() && inputs.docs_pr_number
144168 env :
145169 GH_TOKEN : ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }}
146170 run : |
0 commit comments