diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 977f27f376..c61d46c4da 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -307,15 +307,13 @@ jobs: run: python -I whats_left.py lint: - name: Check Rust code with rustfmt and clippy + name: Check Rust code with clippy runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - uses: dtolnay/rust-toolchain@stable with: - components: rustfmt, clippy - - name: run rustfmt - run: cargo fmt --check + components: clippy - name: run clippy on wasm run: cargo clippy --manifest-path=wasm/lib/Cargo.toml -- -Dwarnings - uses: actions/setup-python@v6 @@ -450,3 +448,55 @@ jobs: run: wasmer run --dir `pwd` target/wasm32-wasip1/release/rustpython.wasm -- `pwd`/extra_tests/snippets/stdlib_random.py - name: run cpython unittest run: wasmer run --dir `pwd` target/wasm32-wasip1/release/rustpython.wasm -- `pwd`/Lib/test/test_int.py + + auto_format_commit: + needs: [rust_tests, exotic_targets, snippets_cpython, lint, miri, wasm, wasm-wasi] + permissions: + contents: write + pull-requests: write + name: Auto-format code + runs-on: ubuntu-latest + if: ${{ !contains(github.event.head_commit.message, '[skip ci]') }} + concurrency: + group: fmt-${{ github.ref }} + cancel-in-progress: true + + steps: + - name: Checkout code + uses: actions/checkout@v5 + with: + fetch-depth: 0 + ref: ${{ github.head_ref || github.ref_name }} + + - name: Setup Rust + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + + - name: Run cargo fmt + run: | + echo "Running cargo fmt --all" + cargo fmt --all + + - name: Commit and push if changes + id: commit + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + if [ -n "$(git status --porcelain)" ]; then + git add -u + git commit -m "Auto-format code [skip ci]" + git push + echo "formatted=true" >> $GITHUB_OUTPUT + else + echo "formatted=false" >> $GITHUB_OUTPUT + fi + + - name: Comment on PR if formatting was applied + if: steps.commit.outputs.formatted == 'true' && github.event_name == 'pull_request' + uses: marocchino/sticky-pull-request-comment@v2 + with: + message: | + Code has been automatically formatted. + No action needed. + the changes were committed with `[skip ci]`. diff --git a/.github/workflows/pr-auto-commit.yaml b/.github/workflows/pr-auto-commit.yaml new file mode 100644 index 0000000000..8546c2abe5 --- /dev/null +++ b/.github/workflows/pr-auto-commit.yaml @@ -0,0 +1,99 @@ +name: PR Auto-format + +# This workflow triggers when a PR is opened/updated +on: + pull_request_target: + types: [opened, synchronize, reopened] + branches: + - main + - release + +concurrency: + group: pr-fmt-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + auto_format: + if: | + !contains(github.event.pull_request.labels.*.name, 'skip:ci') && + !contains(github.event.pull_request.head.sha, '[skip ci]') + permissions: + contents: write + pull-requests: write + checks: read + runs-on: ubuntu-latest + timeout-minutes: 60 + + steps: + - name: Checkout PR branch + uses: actions/checkout@v5 + with: + ref: ${{ github.event.pull_request.head.ref }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 + + # Wait for all PR check runs to complete + - name: Wait for all checks to complete + uses: poseidon/wait-for-status-checks@v0.6.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + delay: 60 + interval: 30 + timeout: 7200 + + - name: CI completed successfully + run: echo "CI workflow completed successfully - proceeding with auto-format" + + - name: Setup Rust + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + + - name: Run cargo fmt + run: | + echo "Running cargo fmt --all on PR #${{ github.event.pull_request.number }}" + cargo fmt --all + + - name: Check for formatting changes + id: check_changes + run: | + if [ -n "$(git status --porcelain)" ]; then + echo "has_changes=true" >> $GITHUB_OUTPUT + else + echo "has_changes=false" >> $GITHUB_OUTPUT + fi + + - name: Commit and push formatting changes + if: steps.check_changes.outputs.has_changes == 'true' + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + git add -u + git commit -m "Auto-format code [skip ci]" + + git push origin HEAD:${{ github.event.pull_request.head.ref }} + + - name: Comment on PR + if: steps.check_changes.outputs.has_changes == 'true' + uses: marocchino/sticky-pull-request-comment@v2 + with: + number: ${{ github.event.pull_request.number }} + message: | + **Code has been automatically formatted** + + The code in this PR has been formatted using `cargo fmt`. + The changes have been committed with `[skip ci]` to avoid triggering another CI run. + + **Triggered by commit:** `${{ github.event.pull_request.head.sha }}` + **Last formatted:** ${{ github.event.pull_request.updated_at }} + + You may need to pull the latest changes before pushing again: + ```bash + git pull origin ${{ github.event.pull_request.head.ref }} + ``` + + - name: No formatting needed + if: steps.check_changes.outputs.has_changes == 'false' + run: echo "Code is already properly formatted"