@@ -107,11 +107,79 @@ env:
107107 PYTHON_VERSION : " 3.13.1"
108108
109109jobs :
110+ auto_format_pr :
111+ if : ${{ github.event_name == 'pull_request' }}
112+ runs-on : ubuntu-latest
113+ permissions :
114+ contents : write
115+ pull-requests : write
116+ checks : read
117+ steps :
118+ - name : Checkout PR branch
119+ uses : actions/checkout@v5
120+ with :
121+ ref : ${{ github.event.pull_request.head.ref }}
122+ repository : ${{ github.event.pull_request.head.repo.full_name }}
123+ token : ${{ github.token }}
124+ fetch-depth : 0
125+
126+ - name : Setup Rust
127+ uses : dtolnay/rust-toolchain@stable
128+ with :
129+ components : rustfmt
130+
131+ - name : Run cargo fmt
132+ run : cargo fmt --all
133+
134+ - name : Configure git
135+ run : |
136+ git config user.name "github-actions[bot]"
137+ git config user.email "github-actions[bot]@users.noreply.github.com"
138+
139+ - name : git add
140+ run : git add -u
141+
142+ - name : git commit
143+ id : git-commit
144+ run : git commit -m "run `cargo fmt --all`"
145+ continue-on-error : true # Will fail if nothing to commit
146+
147+ - name : Comment on PR
148+ if : ${{ steps.git_commit.outcome == 'success' }}
149+ uses : marocchino/sticky-pull-request-comment@v2
150+ with :
151+ number : ${{ github.event.pull_request.number }}
152+ message : |
153+ **Code has been automatically formatted**
154+
155+ The code in this PR has been formatted using `cargo fmt --all`.
156+
157+ You may need to pull the latest changes before pushing again:
158+ ```bash
159+ git pull origin ${{ github.event.pull_request.head.ref }}
160+ ```
161+
162+ **Triggered by commit:** `${{ github.event.pull_request.head.sha }}`
163+ **Last formatted:** ${{ github.event.pull_request.updated_at }}
164+ **Run**: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
165+
166+ - name : git push
167+ run : git push origin HEAD:${{ github.event.pull_request.head.ref }}
168+ if : steps.git-commit.outcome == 'success'
169+
170+ # This step is not really needed as the earlier push should cancel this run anyways.
171+ # But we are making sure that we abort if we had badly formatted files.
172+ - name : Exit if changed
173+ run : exit 1
174+ if : ${{ steps.git_commit.outcome == 'success' }}
175+
110176 rust_tests :
111- if : ${{ !contains(github.event.pull_request.labels.*.name, 'skip:ci') }}
177+ if : ${{ !cancelled() && ! contains(github.event.pull_request.labels.*.name, 'skip:ci') }}
112178 env :
113179 RUST_BACKTRACE : full
114180 name : Run rust tests
181+ needs :
182+ - auto_format_pr
115183 runs-on : ${{ matrix.os }}
116184 timeout-minutes : ${{ contains(matrix.os, 'windows') && 45 || 35 }}
117185 strategy :
@@ -173,8 +241,10 @@ jobs:
173241 if : runner.os == 'macOS'
174242
175243 exotic_targets :
176- if : ${{ !contains(github.event.pull_request.labels.*.name, 'skip:ci') }}
244+ if : ${{ !cancelled() && ! contains(github.event.pull_request.labels.*.name, 'skip:ci') }}
177245 name : Ensure compilation on various targets
246+ needs :
247+ - auto_format_pr
178248 runs-on : ubuntu-latest
179249 timeout-minutes : 30
180250 steps :
@@ -234,10 +304,12 @@ jobs:
234304 # args: --ignore-rust-version
235305
236306 snippets_cpython :
237- if : ${{ !contains(github.event.pull_request.labels.*.name, 'skip:ci') }}
307+ if : ${{ !cancelled() && ! contains(github.event.pull_request.labels.*.name, 'skip:ci') }}
238308 env :
239309 RUST_BACKTRACE : full
240310 name : Run snippets and cpython tests
311+ needs :
312+ - auto_format_pr
241313 runs-on : ${{ matrix.os }}
242314 timeout-minutes : ${{ contains(matrix.os, 'windows') && 45 || 35 }}
243315 strategy :
@@ -308,6 +380,8 @@ jobs:
308380
309381 lint :
310382 name : Check Rust code with clippy
383+ needs :
384+ - auto_format_pr
311385 runs-on : ubuntu-latest
312386 steps :
313387 - uses : actions/checkout@v5
@@ -342,8 +416,10 @@ jobs:
342416 incremental_files_only : true
343417
344418 miri :
345- if : ${{ !contains(github.event.pull_request.labels.*.name, 'skip:ci') }}
419+ if : ${{ !cancelled() && ! contains(github.event.pull_request.labels.*.name, 'skip:ci') }}
346420 name : Run tests under miri
421+ needs :
422+ - auto_format_pr
347423 runs-on : ubuntu-latest
348424 timeout-minutes : 30
349425 env :
@@ -366,8 +442,10 @@ jobs:
366442 MIRIFLAGS : ' -Zmiri-ignore-leaks'
367443
368444 wasm :
369- if : ${{ !contains(github.event.pull_request.labels.*.name, 'skip:ci') }}
445+ if : ${{ !cancelled() && ! contains(github.event.pull_request.labels.*.name, 'skip:ci') }}
370446 name : Check the WASM package and demo
447+ needs :
448+ - auto_format_pr
371449 runs-on : ubuntu-latest
372450 timeout-minutes : 30
373451 steps :
@@ -427,8 +505,10 @@ jobs:
427505 PUBLISH_BRANCH : master
428506
429507 wasm-wasi :
430- if : ${{ !contains(github.event.pull_request.labels.*.name, 'skip:ci') }}
508+ if : ${{ !cancelled() && ! contains(github.event.pull_request.labels.*.name, 'skip:ci') }}
431509 name : Run snippets and cpython tests on wasm-wasi
510+ needs :
511+ - auto_format_pr
432512 runs-on : ubuntu-latest
433513 timeout-minutes : 30
434514 steps :
0 commit comments