name: Check generated models # Verifies the committed generated API models are still in sync with the Java # OpenAPI spec: the frontend tool API types # (frontend/editor/src/core/types/toolApiTypes.ts) and the engine tool # models (engine/src/stirling/models/tool_models.py). Regenerates both with the # single top-level `task tool-models` and fails if either committed file is # out of date. Called from build.yml when the backend Java, frontend, or engine # changes; also runs on push to main as a post-merge safety net. on: workflow_call: push: branches: [main] permissions: contents: read jobs: generated-models: runs-on: ubuntu-latest permissions: contents: read pull-requests: write env: DEPOT_TOKEN: ${{ secrets.DEPOT_TOKEN }} steps: - name: Harden the runner (Audit all outbound calls) uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install uv uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: enable-cache: true - name: Set up JDK 25 uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 with: java-version: "25" distribution: "temurin" - name: Setup Gradle uses: gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0 with: gradle-version: 9.6.0 - name: Set up Node uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: "22" cache: "npm" cache-dependency-path: frontend/package-lock.json - name: Install Task uses: go-task/setup-task@01a4adf9db2d14c1de7a560f09170b6e0df736aa # v2.1.0 # Rebuilds the OpenAPI spec from the current Java and regenerates both the # frontend types and the engine tool models from it. - name: Regenerate generated models run: task tool-models - name: Verify generated models are up to date id: models-check continue-on-error: true run: | git diff --exit-code \ frontend/editor/src/core/types/toolApiTypes.ts \ engine/src/stirling/models/tool_models.py - name: Comment on generated models check failure # Only post a comment on PRs. github-script's PR helpers need an # issue/PR number, which doesn't exist on merge_group runs. if: steps.models-check.outcome == 'failure' && github.event_name == 'pull_request' continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | const marker = ''; const body = [ marker, '### Generated Models Check Failed', '', 'The generated `frontend/editor/src/core/types/toolApiTypes.ts` and/or `engine/src/stirling/models/tool_models.py` are out of date with the Java OpenAPI spec and will need to be regenerated before they can be merged in.', '', 'Run `task tool-models` to regenerate both, then commit the updated files.', ].join('\n'); const { data: comments } = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, }); const existing = comments.find(c => c.body.includes(marker)); if (existing) { await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: existing.id, body, }); } else { await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body, }); } - name: Fail if generated models check failed if: steps.models-check.outcome == 'failure' run: | echo "============================================" echo " Generated Models Check Failed" echo "============================================" echo "" echo "The generated frontend API types and/or engine tool" echo "models are out of date with the Java OpenAPI spec and" echo "will need to be regenerated before they can be merged in." echo "" echo "Run 'task tool-models' to regenerate both, then" echo "commit the updated files." echo "============================================" exit 1 - name: Remove generated models check comment on success if: steps.models-check.outcome == 'success' && github.event_name == 'pull_request' continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | const marker = ''; const { data: comments } = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, }); const existing = comments.find(c => c.body.includes(marker)); if (existing) { await github.rest.issues.deleteComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: existing.id, }); }