diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..86ee59e59 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,12 @@ +# Protect automation that can affect CI/CD behavior or main-only trusted jobs. +/.github/workflows/** @koxudaxi +/.github/CODEOWNERS @koxudaxi +/.pre-commit-config.yaml @koxudaxi +/tox.ini @koxudaxi +/zensical.toml @koxudaxi +/scripts/update_command_help_on_markdown.py @koxudaxi +/scripts/build_cli_docs.py @koxudaxi +/scripts/build_prompt_data.py @koxudaxi +/scripts/build_schema_docs.py @koxudaxi +/scripts/build_llms_txt.py @koxudaxi +/scripts/update_docs_version.py @koxudaxi diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index 0271b3c8b..5c173ef3e 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -10,3 +10,15 @@ updates: allow: - dependency-type: direct - dependency-type: indirect +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly + day: thursday + time: "10:30" + timezone: Asia/Tokyo + open-pull-requests-limit: 10 + groups: + github-actions: + patterns: + - "*" diff --git a/.github/workflows/changelog.yaml b/.github/workflows/changelog.yaml index bfe4b85d1..42af5232d 100644 --- a/.github/workflows/changelog.yaml +++ b/.github/workflows/changelog.yaml @@ -5,15 +5,17 @@ on: types: [published] jobs: - update-changelog: + build-changelog: runs-on: ubuntu-latest permissions: - contents: write + contents: read + outputs: + has_changes: ${{ steps.patch.outputs.has_changes }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: ref: main - token: ${{ secrets.PAT }} + persist-credentials: false - name: Get release info and update CHANGELOG env: @@ -60,10 +62,56 @@ jobs: cat header.md new_entry.md old_entries.md > CHANGELOG.md rm -f header.md new_entry.md old_entries.md + - name: Create changelog patch + id: patch + env: + PATCH_PATH: ${{ runner.temp }}/changelog.patch + run: | + set -euo pipefail + if git diff --quiet -- CHANGELOG.md; then + echo "has_changes=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + git diff --binary -- CHANGELOG.md > "$PATCH_PATH" + echo "has_changes=true" >> "$GITHUB_OUTPUT" + - name: Upload changelog patch + if: steps.patch.outputs.has_changes == 'true' + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: changelog-patch + path: ${{ runner.temp }}/changelog.patch + if-no-files-found: error + + commit-changelog: + needs: build-changelog + if: needs.build-changelog.outputs.has_changes == 'true' + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + ref: main + fetch-depth: 0 + persist-credentials: false + - name: Download changelog patch + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: changelog-patch + path: ${{ runner.temp }} - name: Commit and push + env: + GH_TOKEN: ${{ github.token }} + PATCH_PATH: ${{ runner.temp }}/changelog.patch run: | + set -euo pipefail + git apply --index --whitespace=nowarn "$PATCH_PATH" + if git diff --staged --quiet; then + exit 0 + fi git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" - git add CHANGELOG.md - git diff --cached --quiet || git commit -m "docs: update CHANGELOG.md for ${{ github.event.release.tag_name }}" - git push + git commit -m "docs: update CHANGELOG.md for ${{ github.event.release.tag_name }}" + git fetch origin main + git rebase origin/main + git push "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git" HEAD:main diff --git a/.github/workflows/cli-docs.yaml b/.github/workflows/cli-docs.yaml index 30fade140..3bea76852 100644 --- a/.github/workflows/cli-docs.yaml +++ b/.github/workflows/cli-docs.yaml @@ -1,15 +1,6 @@ name: Update CLI Docs on: - push: - branches: [main] - paths: - - 'tests/main/**' - - 'tests/test_main_kr.py' - - 'src/datamodel_code_generator/arguments.py' - - 'src/datamodel_code_generator/cli_options.py' - - 'scripts/build_cli_docs.py' - - 'scripts/build_prompt_data.py' pull_request: branches: [main] paths: @@ -19,50 +10,24 @@ on: - 'src/datamodel_code_generator/cli_options.py' - 'scripts/build_cli_docs.py' - 'scripts/build_prompt_data.py' - pull_request_target: - types: [labeled] - paths: - - 'tests/main/**' - - 'tests/test_main_kr.py' - - 'src/datamodel_code_generator/arguments.py' - - 'src/datamodel_code_generator/cli_options.py' - - 'scripts/build_cli_docs.py' - - 'scripts/build_prompt_data.py' + - 'docs/cli-reference/**' + - 'src/datamodel_code_generator/prompt_data.py' permissions: - contents: write + contents: read jobs: update-cli-docs: - if: | - github.event_name == 'push' || - !github.event.pull_request.head.repo.fork || - github.actor == 'koxudaxi' || - github.actor == 'gaborbernat' || - github.actor == 'ilovelinux' || - (github.event_name == 'pull_request_target' && github.event.label.name == 'safe-to-fix' && - (github.event.sender.login == 'koxudaxi' || - github.event.sender.login == 'gaborbernat' || - github.event.sender.login == 'ilovelinux')) runs-on: ubuntu-latest steps: - # Checkout for forks (no PAT available) - - uses: actions/checkout@v4 - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 - ref: ${{ github.event.pull_request.head.ref }} + ref: ${{ github.event.pull_request.head.sha }} repository: ${{ github.event.pull_request.head.repo.full_name }} - # Checkout for same-repo PRs, pushes, and pull_request_target - - uses: actions/checkout@v4 - if: github.event_name == 'push' || github.event_name == 'pull_request_target' || github.event.pull_request.head.repo.full_name == github.repository - with: - fetch-depth: 0 - ref: ${{ github.event.pull_request.head.ref || github.ref }} - repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} - token: ${{ secrets.PAT }} + persist-credentials: false - name: Install the latest version of uv - uses: astral-sh/setup-uv@v5 + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5 - name: Install tox run: uv tool install --python-preference only-managed --python 3.13 tox --with tox-uv - name: Setup environment @@ -75,13 +40,3 @@ jobs: run: .tox/cli-docs/bin/python scripts/build_cli_docs.py - name: Build prompt data run: .tox/cli-docs/bin/python scripts/build_prompt_data.py - - name: Commit and push if changed - if: github.event_name == 'push' || github.event_name == 'pull_request_target' || github.event.pull_request.head.repo.full_name == github.repository - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add docs/cli-reference/ src/datamodel_code_generator/prompt_data.py - git diff --staged --quiet || git commit -m "docs: update CLI reference documentation and prompt data - - 🤖 Generated by GitHub Actions" - git push diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 43ca412ec..0c7dc127c 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -29,18 +29,20 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@ce64ddcb0d8d890d2df4a9d1c04ff297367dea2a # v3 with: languages: ${{ matrix.language }} queries: +security-and-quality - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@ce64ddcb0d8d890d2df4a9d1c04ff297367dea2a # v3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@ce64ddcb0d8d890d2df4a9d1c04ff297367dea2a # v3 with: category: "/language:${{ matrix.language }}" diff --git a/.github/workflows/codespell.yaml b/.github/workflows/codespell.yaml index e65eb1c9c..e0070174e 100644 --- a/.github/workflows/codespell.yaml +++ b/.github/workflows/codespell.yaml @@ -22,9 +22,11 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + persist-credentials: false - name: Codespell - uses: codespell-project/actions-codespell@v2 + uses: codespell-project/actions-codespell@406322ec52dd7b488e48c1c4b82e2a8b3a1bf630 # v2 with: exclude_file: CODE_OF_CONDUCT.md skip: ./docs/cli-reference,./docs/llms.txt,./docs/llms-full.txt diff --git a/.github/workflows/codspeed.yaml b/.github/workflows/codspeed.yaml index d4f46ccda..e95aa6782 100644 --- a/.github/workflows/codspeed.yaml +++ b/.github/workflows/codspeed.yaml @@ -13,22 +13,27 @@ concurrency: group: codespeed-${{ github.ref }} cancel-in-progress: true +permissions: + contents: read + jobs: benchmarks: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + persist-credentials: false # uv standalone build is not compatible with CodSpeedHQ # https://github.com/astral-sh/uv/issues/11006 - - uses: actions/setup-python@v6 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: python-version: "3.14.2" - name: Install the latest version of uv - uses: astral-sh/setup-uv@v5 + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5 - name: Install dependencies run: uv sync --all-extras --group benchmark - name: Run benchmarks - uses: CodSpeedHQ/action@v4 + uses: CodSpeedHQ/action@db35df748deb45fdef0960669f57d627c1956c30 # v4 with: token: ${{ secrets.CODSPEED_TOKEN }} run: .venv/bin/pytest tests/main/test_performance.py --codspeed diff --git a/.github/workflows/config-types.yaml b/.github/workflows/config-types.yaml index ccdca9bd6..45baf30de 100644 --- a/.github/workflows/config-types.yaml +++ b/.github/workflows/config-types.yaml @@ -14,13 +14,18 @@ on: - 'pyproject.toml' - '.github/workflows/config-types.yaml' +permissions: + contents: read + jobs: config-types: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + persist-credentials: false - - uses: astral-sh/setup-uv@v5 + - uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5 with: enable-cache: true diff --git a/.github/workflows/docs-deploy.yaml b/.github/workflows/docs-deploy.yaml new file mode 100644 index 000000000..0d266bb0f --- /dev/null +++ b/.github/workflows/docs-deploy.yaml @@ -0,0 +1,61 @@ +name: Docs Deploy + +on: + workflow_call: + inputs: + checkout_ref: + required: true + type: string + deploy_branch: + required: false + type: string + default: '' + secrets: + CLOUDFLARE_API_TOKEN: + required: false + CLOUDFLARE_ACCOUNT_ID: + required: false + +jobs: + build-deploy: + runs-on: ubuntu-24.04 + concurrency: + group: docs-deploy-${{ inputs.deploy_branch || inputs.checkout_ref }} + cancel-in-progress: true + permissions: + contents: read + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + ref: ${{ inputs.checkout_ref }} + persist-credentials: false + - name: Install the latest version of uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5 + with: + python-version: 3.13 + - name: Install dependencies + run: uv sync + - name: Copy CHANGELOG to docs + run: | + if [ -f CHANGELOG.md ]; then + cp CHANGELOG.md docs/changelog.md + else + echo "# Changelog" > docs/changelog.md + echo "" >> docs/changelog.md + echo "Changelog will be available after the first release." >> docs/changelog.md + fi + - name: Update GitHub Action version in docs + run: python scripts/update_docs_version.py + env: + GH_TOKEN: ${{ github.token }} + - name: Build site + run: zensical build --clean + - name: Deploy + if: inputs.deploy_branch != '' + env: + DEPLOY_BRANCH: ${{ inputs.deploy_branch }} + uses: cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + command: pages deploy site --project-name=datamodel-code-generator --branch="$DEPLOY_BRANCH" diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 1bda85d52..3b8362101 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -2,9 +2,6 @@ name: Docs on: pull_request: - push: - branches: - - main release: types: [published] workflow_dispatch: @@ -14,92 +11,67 @@ concurrency: cancel-in-progress: true jobs: - build-deploy: + build-preview: + if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository + uses: ./.github/workflows/docs-deploy.yaml + with: + checkout_ref: ${{ github.event.pull_request.head.sha }} + deploy_branch: pr-${{ github.event.pull_request.number }} + secrets: + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + + build-pr: + if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository + uses: ./.github/workflows/docs-deploy.yaml + with: + checkout_ref: ${{ github.event.pull_request.head.sha }} + + build-production: + if: github.event_name == 'release' || github.event_name == 'workflow_dispatch' + uses: ./.github/workflows/docs-deploy.yaml + with: + checkout_ref: ${{ github.event_name == 'release' && github.event.release.tag_name || github.sha }} + deploy_branch: main + secrets: + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + + comment-preview: runs-on: ubuntu-24.04 + needs: build-preview + if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository permissions: - contents: read - pull-requests: write issues: write + pull-requests: write steps: - - uses: actions/checkout@v4 - - name: Install the latest version of uv - uses: astral-sh/setup-uv@v5 - with: - python-version: 3.13 - - name: Install dependencies - run: uv sync - - name: Copy CHANGELOG to docs - run: | - if [ -f CHANGELOG.md ]; then - cp CHANGELOG.md docs/changelog.md - else - echo "# Changelog" > docs/changelog.md - echo "" >> docs/changelog.md - echo "Changelog will be available after the first release." >> docs/changelog.md - fi - - name: Update GitHub Action version in docs - run: python scripts/update_docs_version.py - env: - GH_TOKEN: ${{ github.token }} - - name: build site - run: zensical build --clean - - # PR Preview Deploy (skip forked PRs as secrets are not available) - - name: Deploy Preview - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository - uses: cloudflare/wrangler-action@v3 - with: - apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} - accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - command: pages deploy site --project-name=datamodel-code-generator --branch=pr-${{ github.event.pull_request.number }} + - name: Comment Preview URL on PR + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const previewUrl = 'https://pr-${{ github.event.pull_request.number }}.datamodel-code-generator.pages.dev'; + const body = `📚 **Docs Preview:** ${previewUrl}`; - - name: Comment Preview URL on PR - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository - uses: actions/github-script@v7 - with: - script: | - const previewUrl = 'https://pr-${{ github.event.pull_request.number }}.datamodel-code-generator.pages.dev'; - const body = `📚 **Docs Preview:** ${previewUrl}`; - - // Check if comment already exists - const comments = await github.rest.issues.listComments({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - }); - - const existingComment = comments.data.find(c => c.body.includes('Docs Preview:')); - - if (existingComment) { - await github.rest.issues.updateComment({ - owner: context.repo.owner, - repo: context.repo.repo, - comment_id: existingComment.id, - body: body - }); - } else { - await github.rest.issues.createComment({ + const comments = await github.rest.issues.listComments({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: body }); - } - # Dev Deploy (on push to main) - - name: Deploy Dev - if: github.event_name == 'push' - uses: cloudflare/wrangler-action@v3 - with: - apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} - accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - command: pages deploy site --project-name=datamodel-code-generator --branch=dev + const existingComment = comments.data.find(c => c.body.includes('Docs Preview:')); - # Production Deploy (on release only) - - name: Deploy Production - if: github.event_name == 'release' || github.event_name == 'workflow_dispatch' - uses: cloudflare/wrangler-action@v3 - with: - apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} - accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - command: pages deploy site --project-name=datamodel-code-generator --branch=main + if (existingComment) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existingComment.id, + body: body + }); + } else { + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: body + }); + } diff --git a/.github/workflows/generated-docs-sync.yaml b/.github/workflows/generated-docs-sync.yaml new file mode 100644 index 000000000..22baec9a1 --- /dev/null +++ b/.github/workflows/generated-docs-sync.yaml @@ -0,0 +1,148 @@ +name: Sync Generated Docs + +on: + push: + branches: [main] + paths: + - 'src/datamodel_code_generator/**' + - 'tests/main/**' + - 'tests/test_main_kr.py' + - 'scripts/build_cli_docs.py' + - 'scripts/build_prompt_data.py' + - 'scripts/build_schema_docs.py' + - 'scripts/build_llms_txt.py' + - 'scripts/update_docs_version.py' + - 'docs/**/*.md' + - 'CHANGELOG.md' + - 'README.md' + - 'zensical.toml' + +permissions: + contents: read + +concurrency: + group: generated-docs-main + cancel-in-progress: false + +jobs: + generate: + runs-on: ubuntu-latest + outputs: + has_changes: ${{ steps.patch.outputs.has_changes }} + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + ref: ${{ github.sha }} + persist-credentials: false + - name: Install the latest version of uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5 + - name: Install tox + run: uv tool install --python-preference only-managed --python 3.13 tox --with tox-uv + - name: Setup README environment + run: tox run -vv --notest --skip-missing-interpreters false -e readme + env: + UV_PYTHON_PREFERENCE: "only-managed" + - name: Setup CLI docs environment + run: tox run -vv --notest --skip-missing-interpreters false -e cli-docs + env: + UV_PYTHON_PREFERENCE: "only-managed" + - name: Setup schema docs environment + run: tox run -vv --notest --skip-missing-interpreters false -e schema-docs + env: + UV_PYTHON_PREFERENCE: "only-managed" + - name: Setup llms.txt environment + run: tox run -vv --notest --skip-missing-interpreters false -e llms-txt + env: + UV_PYTHON_PREFERENCE: "only-managed" + - name: Update README + run: .tox/readme/bin/python scripts/update_command_help_on_markdown.py + - name: Collect CLI doc metadata + run: .tox/cli-docs/bin/pytest --collect-cli-docs -p no:xdist -q + - name: Build CLI docs + run: .tox/cli-docs/bin/python scripts/build_cli_docs.py + - name: Build prompt data + run: .tox/cli-docs/bin/python scripts/build_prompt_data.py + - name: Build schema docs + run: .tox/schema-docs/bin/python scripts/build_schema_docs.py + - name: Build llms.txt + run: .tox/llms-txt/bin/python scripts/build_llms_txt.py + - name: Create generated docs patch + id: patch + env: + PATCH_PATH: ${{ runner.temp }}/generated-docs.patch + run: | + set -euo pipefail + if git diff --quiet -- README.md docs/index.md docs/cli-reference/ docs/llms.txt docs/llms-full.txt docs/supported_formats.md src/datamodel_code_generator/prompt_data.py; then + echo "has_changes=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + git diff --binary -- README.md docs/index.md docs/cli-reference/ docs/llms.txt docs/llms-full.txt docs/supported_formats.md src/datamodel_code_generator/prompt_data.py > "$PATCH_PATH" + echo "has_changes=true" >> "$GITHUB_OUTPUT" + - name: Upload generated docs patch + if: steps.patch.outputs.has_changes == 'true' + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: generated-docs-patch + path: ${{ runner.temp }}/generated-docs.patch + if-no-files-found: error + + push: + needs: generate + runs-on: ubuntu-latest + permissions: + contents: write + outputs: + final_sha: ${{ steps.record_sha.outputs.final_sha }} + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + fetch-depth: 0 + ref: ${{ github.sha }} + persist-credentials: false + - name: Download generated docs patch + if: needs.generate.outputs.has_changes == 'true' + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: generated-docs-patch + path: ${{ runner.temp }} + # Use GITHUB_TOKEN intentionally so this sync commit does not fan out into + # another push-triggered workflow run. Docs deployment is chained below. + - name: Commit generated docs + if: needs.generate.outputs.has_changes == 'true' + env: + GH_TOKEN: ${{ github.token }} + TARGET_REPO: ${{ github.repository }} + TARGET_REF: ${{ github.ref_name }} + PATCH_PATH: ${{ runner.temp }}/generated-docs.patch + run: | + set -euo pipefail + git apply --index --whitespace=nowarn "$PATCH_PATH" + if git diff --staged --quiet; then + exit 0 + fi + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git commit -m "docs: sync generated docs" + git fetch origin "${TARGET_REF}" + git rebase "origin/${TARGET_REF}" + git push "https://x-access-token:${GH_TOKEN}@github.com/${TARGET_REPO}.git" "HEAD:${TARGET_REF}" + - name: Record final revision + id: record_sha + env: + DEFAULT_SHA: ${{ github.sha }} + run: | + if [ "${{ needs.generate.outputs.has_changes }}" = "true" ]; then + echo "final_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" + else + echo "final_sha=${DEFAULT_SHA}" >> "$GITHUB_OUTPUT" + fi + + deploy-docs: + needs: push + uses: ./.github/workflows/docs-deploy.yaml + with: + checkout_ref: ${{ needs.push.outputs.final_sha }} + deploy_branch: dev + secrets: + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 4c2bfaab0..82269a1e3 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -2,49 +2,19 @@ name: Lint on: push: branches: [main] - pull_request: - pull_request_target: - types: [labeled] + +permissions: + contents: read jobs: lint: - if: | - github.event_name == 'push' || - github.event_name == 'pull_request' || - (github.event_name == 'pull_request_target' && github.event.label.name == 'safe-to-fix' && - (github.event.sender.login == 'koxudaxi' || - github.event.sender.login == 'gaborbernat' || - github.event.sender.login == 'ilovelinux')) runs-on: ubuntu-latest steps: - # Checkout for forks (no PAT available, auto-commit won't run anyway) - - uses: actions/checkout@v4 - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository - with: - ref: ${{ github.event.pull_request.head.ref }} - repository: ${{ github.event.pull_request.head.repo.full_name }} - # Checkout for same-repo PRs, pushes, and pull_request_target (PAT for auto-commit and workflow retrigger) - - uses: actions/checkout@v4 - if: github.event_name == 'push' || github.event_name == 'pull_request_target' || github.event.pull_request.head.repo.full_name == github.repository + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: - ref: ${{ github.event.pull_request.head.ref || github.ref }} - repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} - token: ${{ secrets.PAT }} - - uses: astral-sh/setup-uv@v5 - - uses: actions/setup-python@v5 + persist-credentials: false + - uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: python-version: "3.14" - run: SKIP=readme,config-types,schema-docs uvx prek run --all-files --show-diff-on-failure - - if: | - github.event_name == 'push' || - github.event.pull_request.head.repo.full_name == github.repository || - github.actor == 'koxudaxi' || - github.actor == 'gaborbernat' || - github.actor == 'ilovelinux' || - (github.event_name == 'pull_request_target' && github.event.label.name == 'safe-to-fix' && - (github.event.sender.login == 'koxudaxi' || - github.event.sender.login == 'gaborbernat' || - github.event.sender.login == 'ilovelinux')) - uses: stefanzweifel/git-auto-commit-action@v5 - with: - commit_message: "style: auto-fix by prek" diff --git a/.github/workflows/llms-txt.yaml b/.github/workflows/llms-txt.yaml index ee1f86af2..43f324806 100644 --- a/.github/workflows/llms-txt.yaml +++ b/.github/workflows/llms-txt.yaml @@ -1,72 +1,63 @@ name: Update llms.txt on: - push: - branches: [main] - paths: - - 'docs/**/*.md' - - 'zensical.toml' - - 'scripts/build_llms_txt.py' pull_request: branches: [main] paths: + - 'src/datamodel_code_generator/**' + - 'tests/main/**' + - 'tests/test_main_kr.py' + - 'scripts/build_cli_docs.py' + - 'scripts/build_prompt_data.py' + - 'src/datamodel_code_generator/parser/schema_version.py' + - 'scripts/build_schema_docs.py' - 'docs/**/*.md' - - 'zensical.toml' - - 'scripts/build_llms_txt.py' - pull_request_target: - types: [labeled] - paths: - - 'docs/**/*.md' + - 'README.md' - 'zensical.toml' - 'scripts/build_llms_txt.py' permissions: - contents: write + contents: read jobs: update-llms-txt: - if: | - github.event_name == 'push' || - !github.event.pull_request.head.repo.fork || - github.actor == 'koxudaxi' || - github.actor == 'gaborbernat' || - github.actor == 'ilovelinux' || - (github.event_name == 'pull_request_target' && github.event.label.name == 'safe-to-fix' && - (github.event.sender.login == 'koxudaxi' || - github.event.sender.login == 'gaborbernat' || - github.event.sender.login == 'ilovelinux')) runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 - ref: ${{ github.event.pull_request.head.ref }} + ref: ${{ github.event.pull_request.head.sha }} repository: ${{ github.event.pull_request.head.repo.full_name }} - - uses: actions/checkout@v4 - if: github.event_name == 'push' || github.event_name == 'pull_request_target' || github.event.pull_request.head.repo.full_name == github.repository - with: - fetch-depth: 0 - ref: ${{ github.event.pull_request.head.ref || github.ref }} - repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} - token: ${{ secrets.PAT }} + persist-credentials: false - name: Install the latest version of uv - uses: astral-sh/setup-uv@v5 + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5 - name: Install tox run: uv tool install --python-preference only-managed --python 3.13 tox --with tox-uv - - name: Setup environment + - name: Setup README environment + run: tox run -vv --notest --skip-missing-interpreters false -e readme + env: + UV_PYTHON_PREFERENCE: "only-managed" + - name: Setup CLI docs environment + run: tox run -vv --notest --skip-missing-interpreters false -e cli-docs + env: + UV_PYTHON_PREFERENCE: "only-managed" + - name: Setup schema docs environment + run: tox run -vv --notest --skip-missing-interpreters false -e schema-docs + env: + UV_PYTHON_PREFERENCE: "only-managed" + - name: Setup llms.txt environment run: tox run -vv --notest --skip-missing-interpreters false -e llms-txt env: UV_PYTHON_PREFERENCE: "only-managed" + - name: Update README + run: .tox/readme/bin/python scripts/update_command_help_on_markdown.py + - name: Collect CLI doc metadata + run: .tox/cli-docs/bin/pytest --collect-cli-docs -p no:xdist -q + - name: Build CLI docs + run: .tox/cli-docs/bin/python scripts/build_cli_docs.py + - name: Build prompt data + run: .tox/cli-docs/bin/python scripts/build_prompt_data.py + - name: Build schema docs + run: .tox/schema-docs/bin/python scripts/build_schema_docs.py - name: Build llms.txt run: .tox/llms-txt/bin/python scripts/build_llms_txt.py - - name: Commit and push if changed - if: github.event_name == 'push' || github.event_name == 'pull_request_target' || github.event.pull_request.head.repo.full_name == github.repository - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add docs/llms.txt docs/llms-full.txt - git diff --staged --quiet || git commit -m "docs: update llms.txt files - - Generated by GitHub Actions" - git push diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 772802870..f6b37ace1 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -11,16 +11,19 @@ env: jobs: build: runs-on: ubuntu-latest + permissions: + contents: read steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 + persist-credentials: false - name: Install the latest version of uv - uses: astral-sh/setup-uv@v5 + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5 - name: Build package run: uv build --python 3.13 --python-preference only-managed --sdist --wheel . --out-dir dist - name: Store the distribution packages - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: ${{ env.dists-artifact-name }} path: dist/* @@ -37,12 +40,12 @@ jobs: id-token: write steps: - name: Download all the dists - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: name: ${{ env.dists-artifact-name }} path: dist/ - name: Publish to PyPI - uses: pypa/gh-action-pypi-publish@v1.13.0 + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 with: attestations: true @@ -51,27 +54,31 @@ jobs: if: "success() && startsWith(github.ref, 'refs/tags/')" runs-on: ubuntu-24.04 needs: release + permissions: + contents: read steps: - name: Check out the repo - uses: actions/checkout@v2 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + persist-credentials: false - name: Docker meta id: docker_meta - uses: crazy-max/ghaction-docker-meta@v1 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5 with: images: koxudaxi/datamodel-code-generator - tag-semver: | - {{raw}} + tags: | + type=semver,pattern={{raw}} - name: Login to DockerHub - uses: docker/login-action@v1 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Set up QEMU - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - name: Build and push - uses: docker/build-push-action@v2 + uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 with: push: true tags: ${{ steps.docker_meta.outputs.tags }} diff --git a/.github/workflows/readme.yaml b/.github/workflows/readme.yaml index 300cff3e2..df3a89869 100644 --- a/.github/workflows/readme.yaml +++ b/.github/workflows/readme.yaml @@ -1,53 +1,28 @@ name: Update README on: - push: - branches: [main] - paths: - - 'src/datamodel_code_generator/**' pull_request: branches: [main] paths: - 'src/datamodel_code_generator/**' - pull_request_target: - types: [labeled] - paths: - - 'src/datamodel_code_generator/**' + - 'README.md' + - 'docs/index.md' permissions: - contents: write + contents: read jobs: update-readme: - if: | - github.event_name == 'push' || - !github.event.pull_request.head.repo.fork || - github.actor == 'koxudaxi' || - github.actor == 'gaborbernat' || - github.actor == 'ilovelinux' || - (github.event_name == 'pull_request_target' && github.event.label.name == 'safe-to-fix' && - (github.event.sender.login == 'koxudaxi' || - github.event.sender.login == 'gaborbernat' || - github.event.sender.login == 'ilovelinux')) runs-on: ubuntu-latest steps: - # Checkout for forks (no PAT available) - - uses: actions/checkout@v4 - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 - ref: ${{ github.event.pull_request.head.ref }} + ref: ${{ github.event.pull_request.head.sha }} repository: ${{ github.event.pull_request.head.repo.full_name }} - # Checkout for same-repo PRs, pushes, and pull_request_target - - uses: actions/checkout@v4 - if: github.event_name == 'push' || github.event_name == 'pull_request_target' || github.event.pull_request.head.repo.full_name == github.repository - with: - fetch-depth: 0 - ref: ${{ github.event.pull_request.head.ref || github.ref }} - repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} - token: ${{ secrets.PAT }} + persist-credentials: false - name: Install the latest version of uv - uses: astral-sh/setup-uv@v5 + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5 - name: Install tox run: uv tool install --python-preference only-managed --python 3.13 tox --with tox-uv - name: Setup environment @@ -56,13 +31,3 @@ jobs: UV_PYTHON_PREFERENCE: "only-managed" - name: Update README run: .tox/readme/bin/python scripts/update_command_help_on_markdown.py - - name: Commit and push if changed - if: github.event_name == 'push' || github.event_name == 'pull_request_target' || github.event.pull_request.head.repo.full_name == github.repository - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add README.md docs/index.md - git diff --staged --quiet || git commit -m "docs: update command help in README - - 🤖 Generated by GitHub Actions" - git push diff --git a/.github/workflows/release-draft.yaml b/.github/workflows/release-draft.yaml index 9f152cf84..72ada1400 100644 --- a/.github/workflows/release-draft.yaml +++ b/.github/workflows/release-draft.yaml @@ -13,39 +13,32 @@ concurrency: group: release-draft cancel-in-progress: false -permissions: - contents: write - pull-requests: write - jobs: - analyze-and-draft: + analyze: # Only run on merged PRs that haven't been analyzed yet if: | github.event.pull_request.merged == true && !contains(github.event.pull_request.labels.*.name, 'breaking-change-analyzed') runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 - - - name: Ensure labels exist - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - # Create labels if they don't exist (ignore errors if already exist) - gh label create "breaking-change-analyzed" --color "0E8A16" --description "PR has been analyzed for breaking changes" 2>/dev/null || true - gh label create "breaking-change" --color "D93F0B" --description "PR contains breaking changes" 2>/dev/null || true + persist-credentials: false + ref: refs/heads/main - name: Run Claude Code Analysis id: claude timeout-minutes: 10 - uses: anthropics/claude-code-action@v1 + uses: anthropics/claude-code-action@4e5d8b13ca281a6d163cdb287d8917b216e00d6f # v1 with: # OAuth authentication for Max plan subscribers claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} - github_token: ${{ secrets.GITHUB_TOKEN }} + github_token: ${{ github.token }} show_full_output: true prompt: | Analyze PR #${{ github.event.pull_request.number }} for breaking changes. @@ -86,49 +79,89 @@ jobs: id: parse env: CLAUDE_OUTPUT: ${{ steps.claude.outputs.structured_output }} + ANALYSIS_PATH: ${{ runner.temp }}/release-draft-analysis.json run: | + set -euo pipefail # Parse structured output from Claude using env var to avoid shell injection HAS_BC=$(echo "$CLAUDE_OUTPUT" | jq -r '.has_breaking_changes // false') BC_CONTENT=$(echo "$CLAUDE_OUTPUT" | jq -r '.breaking_changes_content // ""') REASONING=$(echo "$CLAUDE_OUTPUT" | jq -r '.reasoning // ""') - echo "has_breaking_changes=$HAS_BC" >> $GITHUB_OUTPUT + jq -n \ + --argjson has_breaking_changes "$HAS_BC" \ + --arg breaking_changes_content "$BC_CONTENT" \ + --arg reasoning "$REASONING" \ + '{has_breaking_changes: $has_breaking_changes, breaking_changes_content: $breaking_changes_content, reasoning: $reasoning}' \ + > "$ANALYSIS_PATH" - # Use unique delimiter to avoid collision with content - DELIMITER="EOF_$(date +%s%N)" + - name: Upload analysis artifact + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: release-draft-analysis + path: ${{ runner.temp }}/release-draft-analysis.json + if-no-files-found: error + + update-draft: + needs: analyze + if: | + github.event.pull_request.merged == true && + !contains(github.event.pull_request.labels.*.name, 'breaking-change-analyzed') + runs-on: ubuntu-latest + permissions: + contents: write + issues: write + pull-requests: read + steps: + - name: Download analysis artifact + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: release-draft-analysis + path: ${{ runner.temp }} + + - name: Load analysis result + id: analysis + env: + ANALYSIS_PATH: ${{ runner.temp }}/release-draft-analysis.json + run: | + set -euo pipefail + HAS_BC=$(jq -r '.has_breaking_changes // false' "$ANALYSIS_PATH") + BC_CONTENT=$(jq -r '.breaking_changes_content // ""' "$ANALYSIS_PATH") + REASONING=$(jq -r '.reasoning // ""' "$ANALYSIS_PATH") - # Use heredoc for multiline content with unique delimiter + echo "has_breaking_changes=$HAS_BC" >> "$GITHUB_OUTPUT" + + DELIMITER="EOF_$(date +%s%N)" { echo "breaking_changes_content<<$DELIMITER" printf '%s\n' "$BC_CONTENT" echo "$DELIMITER" - } >> $GITHUB_OUTPUT + } >> "$GITHUB_OUTPUT" { echo "reasoning<<$DELIMITER" printf '%s\n' "$REASONING" echo "$DELIMITER" - } >> $GITHUB_OUTPUT + } >> "$GITHUB_OUTPUT" - name: Add breaking-change-analyzed label env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ github.token }} run: | gh pr edit ${{ github.event.pull_request.number }} --add-label "breaking-change-analyzed" - name: Add breaking-change label if applicable - if: steps.parse.outputs.has_breaking_changes == 'true' + if: steps.analysis.outputs.has_breaking_changes == 'true' env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ github.token }} run: | gh pr edit ${{ github.event.pull_request.number }} --add-label "breaking-change" - name: Post analysis result to PR env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - HAS_BC: ${{ steps.parse.outputs.has_breaking_changes }} - BC_CONTENT: ${{ steps.parse.outputs.breaking_changes_content }} - REASONING: ${{ steps.parse.outputs.reasoning }} + GH_TOKEN: ${{ github.token }} + HAS_BC: ${{ steps.analysis.outputs.has_breaking_changes }} + BC_CONTENT: ${{ steps.analysis.outputs.breaking_changes_content }} + REASONING: ${{ steps.analysis.outputs.reasoning }} run: | # Use temp file to avoid shell escaping issues with special characters TMPFILE=$(mktemp) @@ -153,9 +186,9 @@ jobs: - name: Calculate version and update draft release env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - HAS_BC: ${{ steps.parse.outputs.has_breaking_changes }} - BC_CONTENT: ${{ steps.parse.outputs.breaking_changes_content }} + GH_TOKEN: ${{ github.token }} + HAS_BC: ${{ steps.analysis.outputs.has_breaking_changes }} + BC_CONTENT: ${{ steps.analysis.outputs.breaking_changes_content }} run: | set -euo pipefail diff --git a/.github/workflows/release-notify.yaml b/.github/workflows/release-notify.yaml index e0499aa7f..a63878003 100644 --- a/.github/workflows/release-notify.yaml +++ b/.github/workflows/release-notify.yaml @@ -8,17 +8,17 @@ on: jobs: notify: runs-on: ubuntu-latest - if: ${{ github.event.workflow_run.conclusion == 'success' }} + if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push' && github.event.workflow_run.head_repository.full_name == github.repository }} permissions: contents: read issues: write - pull-requests: write + pull-requests: read env: TARGET_OWNER: koxudaxi TARGET_REPO: datamodel-code-generator steps: - name: Post release notifications - uses: actions/github-script@v7 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | diff --git a/.github/workflows/schema-docs.yaml b/.github/workflows/schema-docs.yaml index e29aadde8..1654076a2 100644 --- a/.github/workflows/schema-docs.yaml +++ b/.github/workflows/schema-docs.yaml @@ -1,59 +1,28 @@ name: Update Schema Docs on: - push: - branches: [main] - paths: - - 'src/datamodel_code_generator/parser/schema_version.py' - - 'scripts/build_schema_docs.py' - - 'docs/supported_formats.md' pull_request: branches: [main] paths: - 'src/datamodel_code_generator/parser/schema_version.py' - 'scripts/build_schema_docs.py' - 'docs/supported_formats.md' - pull_request_target: - types: [labeled] - paths: - - 'src/datamodel_code_generator/parser/schema_version.py' - - 'scripts/build_schema_docs.py' - - 'docs/supported_formats.md' permissions: - contents: write + contents: read jobs: update-schema-docs: - if: | - github.event_name == 'push' || - !github.event.pull_request.head.repo.fork || - github.actor == 'koxudaxi' || - github.actor == 'gaborbernat' || - github.actor == 'ilovelinux' || - (github.event_name == 'pull_request_target' && github.event.label.name == 'safe-to-fix' && - (github.event.sender.login == 'koxudaxi' || - github.event.sender.login == 'gaborbernat' || - github.event.sender.login == 'ilovelinux')) runs-on: ubuntu-latest steps: - # Checkout for forks (no PAT available) - - uses: actions/checkout@v4 - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 - ref: ${{ github.event.pull_request.head.ref }} + ref: ${{ github.event.pull_request.head.sha }} repository: ${{ github.event.pull_request.head.repo.full_name }} - # Checkout for same-repo PRs, pushes, and pull_request_target - - uses: actions/checkout@v4 - if: github.event_name == 'push' || github.event_name == 'pull_request_target' || github.event.pull_request.head.repo.full_name == github.repository - with: - fetch-depth: 0 - ref: ${{ github.event.pull_request.head.ref || github.ref }} - repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} - token: ${{ secrets.PAT }} + persist-credentials: false - name: Install the latest version of uv - uses: astral-sh/setup-uv@v5 + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5 - name: Install tox run: uv tool install --python-preference only-managed --python 3.13 tox --with tox-uv - name: Setup environment @@ -62,15 +31,3 @@ jobs: UV_PYTHON_PREFERENCE: "only-managed" - name: Build schema docs run: .tox/schema-docs/bin/python scripts/build_schema_docs.py - - name: Commit and push if changed - if: github.event_name == 'push' || github.event_name == 'pull_request_target' || github.event.pull_request.head.repo.full_name == github.repository - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add docs/supported_formats.md - if ! git diff --staged --quiet; then - git commit -m "docs: update schema feature documentation - - 🤖 Generated by GitHub Actions" - git push - fi diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index ec8ee5ee2..4206ba7f5 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -13,6 +13,9 @@ concurrency: group: test-${{ github.ref }} cancel-in-progress: true +permissions: + contents: read + jobs: test: name: >- @@ -43,11 +46,12 @@ jobs: env: OS: ${{ matrix.os == '' && 'ubuntu-24.04' || matrix.os}} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 + persist-credentials: false - name: Install the latest version of uv - uses: astral-sh/setup-uv@v5 + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5 with: enable-cache: true cache-suffix: "${{ matrix.py || matrix.tox_env }}" @@ -90,7 +94,7 @@ jobs: os.rename(f".tox/.coverage.{env_name}", f".tox/.coverage.{base_name}-${{ matrix.os }}") shell: python - name: Upload coverage data - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: include-hidden-files: true name: .coverage.${{ matrix.py || matrix.tox_env }}-${{ matrix.os == '' && 'ubuntu-24.04' || matrix.os }} @@ -102,11 +106,12 @@ jobs: runs-on: ubuntu-latest needs: test steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 + persist-credentials: false - name: Install the latest version of uv - uses: astral-sh/setup-uv@v5 + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5 - name: Install tox run: uv tool install --python-preference only-managed --python 3.13 tox --with tox-uv - name: Setup coverage tool @@ -114,7 +119,7 @@ jobs: env: UV_PYTHON_PREFERENCE: only-managed - name: Download coverage data - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: path: .tox pattern: .coverage.* @@ -132,13 +137,13 @@ jobs: COVERAGE_FILE=.tox/.coverage .tox/coverage/bin/coverage report --show-missing --fail-under=0 | grep -v "100%" - name: Upload HTML report if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: html-report path: .tox/htmlcov - name: Upload coverage to Codecov if: always() - uses: codecov/codecov-action@v5 + uses: codecov/codecov-action@75cd11691c0faa626561e295848008c8a7dddffe # v5 with: flags: unittests files: .tox/coverage.xml @@ -160,11 +165,12 @@ jobs: - docs - pkg_meta steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 + persist-credentials: false - name: Install the latest version of uv - uses: astral-sh/setup-uv@v5 + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5 - name: Install tox run: uv tool install --python-preference only-managed --python 3.13 tox --with tox-uv - name: Setup check suite @@ -175,3 +181,26 @@ jobs: run: tox run --skip-uv-sync --skip-pkg-install -e ${{ matrix.tox_env }} env: UV_PYTHON_PREFERENCE: "only-managed" + + test-gate: + name: test-gate + if: always() + runs-on: ubuntu-latest + needs: + - test + - coverage + - check + steps: + - name: Fail if any test workflow job failed + run: | + test_result='${{ needs.test.result }}' + coverage_result='${{ needs.coverage.result }}' + check_result='${{ needs.check.result }}' + + echo "test: ${test_result}" + echo "coverage: ${coverage_result}" + echo "check: ${check_result}" + + [ "${test_result}" = "success" ] || exit 1 + [ "${coverage_result}" = "success" ] || exit 1 + [ "${check_result}" = "success" ] || exit 1 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5da9d8bdd..8508b0918 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,3 +1,7 @@ +ci: + autofix_commit_msg: "style: auto-fix by pre-commit.ci" + skip: [readme, config-types, schema-docs] + repos: - repo: https://github.com/python-jsonschema/check-jsonschema rev: 0.35.0