From cbc00cd8296a361fdfe14bae7f6de92379b2f671 Mon Sep 17 00:00:00 2001 From: Joe Isaacs Date: Fri, 15 May 2026 12:35:02 +0100 Subject: [PATCH 01/10] u Signed-off-by: Joe Isaacs --- .github/workflows/fmt-fix.yml | 109 ++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 .github/workflows/fmt-fix.yml diff --git a/.github/workflows/fmt-fix.yml b/.github/workflows/fmt-fix.yml new file mode 100644 index 00000000000..eb224fd6f2b --- /dev/null +++ b/.github/workflows/fmt-fix.yml @@ -0,0 +1,109 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: Copyright the Vortex contributors + +name: Auto-fix formatting + +on: + pull_request: + types: [opened, synchronize, reopened] + workflow_run: + workflows: ["Linters and Tests"] + types: [completed] + +env: + CARGO_TERM_COLOR: always + NIGHTLY_TOOLCHAIN: nightly-2026-02-05 + +jobs: + check-fmt: + name: "Check formatting" + # For workflow_run events, only run if the triggering workflow was for a PR. + if: >- + github.event_name == 'pull_request' + || (github.event_name == 'workflow_run' + && github.event.workflow_run.event == 'pull_request' + && github.event.workflow_run.conclusion == 'completed') + runs-on: ubuntu-latest + timeout-minutes: 15 + outputs: + needs-fix: ${{ steps.check.outputs.needs-fix }} + pr-head-sha: ${{ steps.resolve.outputs.head-sha }} + pr-head-ref: ${{ steps.resolve.outputs.head-ref }} + steps: + - name: Resolve PR ref + id: resolve + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 + with: + script: | + let sha, ref; + if (context.eventName === 'pull_request') { + sha = context.payload.pull_request.head.sha; + ref = context.payload.pull_request.head.ref; + } else { + // workflow_run: look up the PR from the head branch + const wr = context.payload.workflow_run; + sha = wr.head_sha; + ref = wr.head_branch; + } + core.setOutput('head-sha', sha); + core.setOutput('head-ref', ref); + + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + ref: ${{ steps.resolve.outputs.head-sha }} + + - name: Install nightly for fmt + run: rustup toolchain install $NIGHTLY_TOOLCHAIN --component rustfmt + + - name: Check formatting + id: check + run: | + if cargo +$NIGHTLY_TOOLCHAIN fmt --all --check; then + echo "needs-fix=false" >> "$GITHUB_OUTPUT" + else + echo "needs-fix=true" >> "$GITHUB_OUTPUT" + fi + + apply-fmt: + name: "Apply formatting fix" + needs: check-fmt + if: needs.check-fmt.outputs.needs-fix == 'true' + runs-on: ubuntu-latest + timeout-minutes: 15 + environment: fmt-fix + permissions: + contents: write + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + # Check out the exact commit that triggered this workflow, not the + # latest branch HEAD (which may have moved during approval wait). + ref: ${{ needs.check-fmt.outputs.pr-head-sha }} + + - name: Install nightly for fmt + run: rustup toolchain install $NIGHTLY_TOOLCHAIN --component rustfmt + + - name: Run cargo fmt + run: cargo +$NIGHTLY_TOOLCHAIN fmt --all + + - name: Commit fix + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add -A + git diff --cached --quiet && echo "No changes to commit" && exit 0 + git commit -m "chore: cargo fmt + + Signed-off-by: github-actions[bot] " + + - name: Push (fails if branch moved since trigger) + env: + EXPECTED_SHA: ${{ needs.check-fmt.outputs.pr-head-sha }} + BRANCH: ${{ needs.check-fmt.outputs.pr-head-ref }} + run: | + # --force-with-lease atomically checks that the remote branch HEAD + # is still EXPECTED_SHA before pushing. If someone else pushed a + # commit to the PR between trigger and approval, this fails safely. + git push origin \ + "HEAD:refs/heads/$BRANCH" \ + "--force-with-lease=refs/heads/$BRANCH:$EXPECTED_SHA" From 0dbaa1094fba0df27d41f31787b9ad8b9007802c Mon Sep 17 00:00:00 2001 From: Joe Isaacs Date: Fri, 15 May 2026 12:36:29 +0100 Subject: [PATCH 02/10] u Signed-off-by: Joe Isaacs --- encodings/fastlanes/src/delta/array/delta_compress.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/encodings/fastlanes/src/delta/array/delta_compress.rs b/encodings/fastlanes/src/delta/array/delta_compress.rs index d51cef72b49..0e1cc7ed3fd 100644 --- a/encodings/fastlanes/src/delta/array/delta_compress.rs +++ b/encodings/fastlanes/src/delta/array/delta_compress.rs @@ -32,8 +32,7 @@ pub fn delta_compress( // TODO(robert): This can be avoided if we add TransposedBoolArray that performs index translation when necessary. let validity = transpose_validity(&validity, ctx)?; ( - PrimitiveArray::new(bases, array.dtype().nullability().into()), - PrimitiveArray::new(deltas, validity), + PrimitiveArray::new(bases, array.dtype().nullability().into()),PrimitiveArray::new(deltas, validity), ) }); From a9c1e24567b7f134cc2100d8745e997f3f44c5e6 Mon Sep 17 00:00:00 2001 From: Joe Isaacs Date: Fri, 15 May 2026 12:41:27 +0100 Subject: [PATCH 03/10] u Signed-off-by: Joe Isaacs --- .github/workflows/fmt-fix.yml | 98 +++++++++++++++++------------------ 1 file changed, 48 insertions(+), 50 deletions(-) diff --git a/.github/workflows/fmt-fix.yml b/.github/workflows/fmt-fix.yml index eb224fd6f2b..acfad31e9ef 100644 --- a/.github/workflows/fmt-fix.yml +++ b/.github/workflows/fmt-fix.yml @@ -4,8 +4,6 @@ name: Auto-fix formatting on: - pull_request: - types: [opened, synchronize, reopened] workflow_run: workflows: ["Linters and Tests"] types: [completed] @@ -15,59 +13,59 @@ env: NIGHTLY_TOOLCHAIN: nightly-2026-02-05 jobs: - check-fmt: - name: "Check formatting" - # For workflow_run events, only run if the triggering workflow was for a PR. - if: >- - github.event_name == 'pull_request' - || (github.event_name == 'workflow_run' - && github.event.workflow_run.event == 'pull_request' - && github.event.workflow_run.conclusion == 'completed') + check-ci-fmt: + name: "Check if CI fmt failed" + # Only act on PR runs that completed (success or failure — the fmt step + # uses continue-on-error so the workflow can "succeed" even when fmt fails). + if: github.event.workflow_run.event == 'pull_request' runs-on: ubuntu-latest - timeout-minutes: 15 + timeout-minutes: 5 outputs: - needs-fix: ${{ steps.check.outputs.needs-fix }} - pr-head-sha: ${{ steps.resolve.outputs.head-sha }} - pr-head-ref: ${{ steps.resolve.outputs.head-ref }} + fmt-failed: ${{ steps.check.outputs.fmt-failed }} + head-sha: ${{ steps.check.outputs.head-sha }} + head-ref: ${{ steps.check.outputs.head-ref }} steps: - - name: Resolve PR ref - id: resolve + - name: Check CI fmt step outcome + id: check uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 with: script: | - let sha, ref; - if (context.eventName === 'pull_request') { - sha = context.payload.pull_request.head.sha; - ref = context.payload.pull_request.head.ref; - } else { - // workflow_run: look up the PR from the head branch - const wr = context.payload.workflow_run; - sha = wr.head_sha; - ref = wr.head_branch; - } - core.setOutput('head-sha', sha); - core.setOutput('head-ref', ref); + const runId = context.payload.workflow_run.id; + const headSha = context.payload.workflow_run.head_sha; + const headBranch = context.payload.workflow_run.head_branch; - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - with: - ref: ${{ steps.resolve.outputs.head-sha }} + // Find the "Rust (lint)" job in the CI run. + const { data: { jobs } } = await github.rest.actions.listJobsForWorkflowRun({ + ...context.repo, + run_id: runId, + }); + const lintJob = jobs.find(j => j.name === 'Rust (lint)'); + if (!lintJob) { + core.info('Rust (lint) job not found — skipping'); + core.setOutput('fmt-failed', 'false'); + return; + } - - name: Install nightly for fmt - run: rustup toolchain install $NIGHTLY_TOOLCHAIN --component rustfmt + // Find the fmt step by its id ("fmt") or name. + const fmtStep = lintJob.steps.find( + s => s.name === 'Rust Lint - Format' + ); + if (!fmtStep) { + core.info('fmt step not found — skipping'); + core.setOutput('fmt-failed', 'false'); + return; + } - - name: Check formatting - id: check - run: | - if cargo +$NIGHTLY_TOOLCHAIN fmt --all --check; then - echo "needs-fix=false" >> "$GITHUB_OUTPUT" - else - echo "needs-fix=true" >> "$GITHUB_OUTPUT" - fi + const failed = fmtStep.conclusion === 'failure'; + core.info(`fmt step conclusion: ${fmtStep.conclusion}`); + core.setOutput('fmt-failed', String(failed)); + core.setOutput('head-sha', headSha); + core.setOutput('head-ref', headBranch); apply-fmt: name: "Apply formatting fix" - needs: check-fmt - if: needs.check-fmt.outputs.needs-fix == 'true' + needs: check-ci-fmt + if: needs.check-ci-fmt.outputs.fmt-failed == 'true' runs-on: ubuntu-latest timeout-minutes: 15 environment: fmt-fix @@ -76,9 +74,9 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: - # Check out the exact commit that triggered this workflow, not the - # latest branch HEAD (which may have moved during approval wait). - ref: ${{ needs.check-fmt.outputs.pr-head-sha }} + # Check out the exact commit that CI ran against, not the latest + # branch HEAD (which may have moved during the approval wait). + ref: ${{ needs.check-ci-fmt.outputs.head-sha }} - name: Install nightly for fmt run: rustup toolchain install $NIGHTLY_TOOLCHAIN --component rustfmt @@ -96,14 +94,14 @@ jobs: Signed-off-by: github-actions[bot] " - - name: Push (fails if branch moved since trigger) + - name: Push (fails if branch moved since CI ran) env: - EXPECTED_SHA: ${{ needs.check-fmt.outputs.pr-head-sha }} - BRANCH: ${{ needs.check-fmt.outputs.pr-head-ref }} + EXPECTED_SHA: ${{ needs.check-ci-fmt.outputs.head-sha }} + BRANCH: ${{ needs.check-ci-fmt.outputs.head-ref }} run: | # --force-with-lease atomically checks that the remote branch HEAD # is still EXPECTED_SHA before pushing. If someone else pushed a - # commit to the PR between trigger and approval, this fails safely. + # commit to the PR between the CI run and approval, this fails safely. git push origin \ "HEAD:refs/heads/$BRANCH" \ "--force-with-lease=refs/heads/$BRANCH:$EXPECTED_SHA" From 5ad6b21f76ae0d67a91cff54148e0e18b979f466 Mon Sep 17 00:00:00 2001 From: Joe Isaacs Date: Fri, 15 May 2026 14:30:36 +0100 Subject: [PATCH 04/10] u Signed-off-by: Joe Isaacs --- .github/workflows/fmt-fix.yml | 89 +++++++++++++++-------------------- 1 file changed, 39 insertions(+), 50 deletions(-) diff --git a/.github/workflows/fmt-fix.yml b/.github/workflows/fmt-fix.yml index acfad31e9ef..868c3e09128 100644 --- a/.github/workflows/fmt-fix.yml +++ b/.github/workflows/fmt-fix.yml @@ -13,70 +13,61 @@ env: NIGHTLY_TOOLCHAIN: nightly-2026-02-05 jobs: - check-ci-fmt: - name: "Check if CI fmt failed" - # Only act on PR runs that completed (success or failure — the fmt step - # uses continue-on-error so the workflow can "succeed" even when fmt fails). - if: github.event.workflow_run.event == 'pull_request' + check-lint-failed: + name: "Check if rust-lint failed" + # Only run when the triggering workflow was for a PR. + if: >- + github.event.workflow_run.event == 'pull_request' + && github.event.workflow_run.conclusion == 'failure' runs-on: ubuntu-latest timeout-minutes: 5 outputs: - fmt-failed: ${{ steps.check.outputs.fmt-failed }} - head-sha: ${{ steps.check.outputs.head-sha }} - head-ref: ${{ steps.check.outputs.head-ref }} + lint-failed: ${{ steps.check-job.outputs.lint-failed }} + pr-head-sha: ${{ steps.resolve.outputs.head-sha }} + pr-head-ref: ${{ steps.resolve.outputs.head-ref }} steps: - - name: Check CI fmt step outcome - id: check + - name: Resolve PR ref + id: resolve uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 with: script: | - const runId = context.payload.workflow_run.id; - const headSha = context.payload.workflow_run.head_sha; - const headBranch = context.payload.workflow_run.head_branch; + const wr = context.payload.workflow_run; + core.setOutput('head-sha', wr.head_sha); + core.setOutput('head-ref', wr.head_branch); - // Find the "Rust (lint)" job in the CI run. - const { data: { jobs } } = await github.rest.actions.listJobsForWorkflowRun({ - ...context.repo, - run_id: runId, + - name: Check if rust-lint job failed + id: check-job + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 + with: + script: | + const jobs = await github.rest.actions.listJobsForWorkflowRun({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: context.payload.workflow_run.id, }); - const lintJob = jobs.find(j => j.name === 'Rust (lint)'); - if (!lintJob) { - core.info('Rust (lint) job not found — skipping'); - core.setOutput('fmt-failed', 'false'); - return; - } - - // Find the fmt step by its id ("fmt") or name. - const fmtStep = lintJob.steps.find( - s => s.name === 'Rust Lint - Format' - ); - if (!fmtStep) { - core.info('fmt step not found — skipping'); - core.setOutput('fmt-failed', 'false'); - return; + const lintJob = jobs.data.jobs.find(j => j.name === 'Rust (lint)'); + const failed = lintJob && lintJob.conclusion === 'failure'; + core.setOutput('lint-failed', failed ? 'true' : 'false'); + if (!failed) { + core.info('rust-lint did not fail, skipping fmt fix'); } - const failed = fmtStep.conclusion === 'failure'; - core.info(`fmt step conclusion: ${fmtStep.conclusion}`); - core.setOutput('fmt-failed', String(failed)); - core.setOutput('head-sha', headSha); - core.setOutput('head-ref', headBranch); - apply-fmt: name: "Apply formatting fix" - needs: check-ci-fmt - if: needs.check-ci-fmt.outputs.fmt-failed == 'true' + needs: check-lint-failed + if: needs.check-lint-failed.outputs.lint-failed == 'true' runs-on: ubuntu-latest timeout-minutes: 15 + # The fmt-fix environment must be configured with required reviewers + # in the repo settings. This creates an accept/reject gate on the PR + # before the fmt commit is pushed. environment: fmt-fix permissions: contents: write steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: - # Check out the exact commit that CI ran against, not the latest - # branch HEAD (which may have moved during the approval wait). - ref: ${{ needs.check-ci-fmt.outputs.head-sha }} + ref: ${{ needs.check-lint-failed.outputs.pr-head-sha }} - name: Install nightly for fmt run: rustup toolchain install $NIGHTLY_TOOLCHAIN --component rustfmt @@ -84,7 +75,10 @@ jobs: - name: Run cargo fmt run: cargo +$NIGHTLY_TOOLCHAIN fmt --all - - name: Commit fix + - name: Commit and push + env: + EXPECTED_SHA: ${{ needs.check-lint-failed.outputs.pr-head-sha }} + BRANCH: ${{ needs.check-lint-failed.outputs.pr-head-ref }} run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" @@ -94,14 +88,9 @@ jobs: Signed-off-by: github-actions[bot] " - - name: Push (fails if branch moved since CI ran) - env: - EXPECTED_SHA: ${{ needs.check-ci-fmt.outputs.head-sha }} - BRANCH: ${{ needs.check-ci-fmt.outputs.head-ref }} - run: | # --force-with-lease atomically checks that the remote branch HEAD # is still EXPECTED_SHA before pushing. If someone else pushed a - # commit to the PR between the CI run and approval, this fails safely. + # commit to the PR between trigger and approval, this fails safely. git push origin \ "HEAD:refs/heads/$BRANCH" \ "--force-with-lease=refs/heads/$BRANCH:$EXPECTED_SHA" From c74c2053893a48623c628e4fb2bb571e67a10bbc Mon Sep 17 00:00:00 2001 From: Joe Isaacs Date: Fri, 15 May 2026 15:20:57 +0100 Subject: [PATCH 05/10] u Signed-off-by: Joe Isaacs --- .github/workflows/ci.yml | 14 ++++++++ .github/workflows/fmt-fix.yml | 60 ++++++++--------------------------- 2 files changed, 27 insertions(+), 47 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7da0f8a015a..315aa25cf51 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -233,6 +233,20 @@ jobs: id: clippy-default continue-on-error: true run: cargo clippy --profile ci --locked --all-targets -- -D warnings + - name: Trigger fmt-fix workflow + if: always() && steps.fmt.outcome == 'failure' && github.event_name == 'pull_request' + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 + with: + script: | + await github.rest.actions.createWorkflowDispatch({ + ...context.repo, + workflow_id: 'fmt-fix.yml', + ref: context.payload.pull_request.head.ref, + inputs: { + 'pr-head-sha': context.payload.pull_request.head.sha, + 'pr-head-ref': context.payload.pull_request.head.ref, + }, + }); - name: Check lint results if: always() uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 diff --git a/.github/workflows/fmt-fix.yml b/.github/workflows/fmt-fix.yml index 868c3e09128..54ebe5dfa23 100644 --- a/.github/workflows/fmt-fix.yml +++ b/.github/workflows/fmt-fix.yml @@ -4,58 +4,24 @@ name: Auto-fix formatting on: - workflow_run: - workflows: ["Linters and Tests"] - types: [completed] + workflow_dispatch: + inputs: + pr-head-sha: + description: "The PR head commit SHA to format" + required: true + type: string + pr-head-ref: + description: "The PR head branch name" + required: true + type: string env: CARGO_TERM_COLOR: always NIGHTLY_TOOLCHAIN: nightly-2026-02-05 jobs: - check-lint-failed: - name: "Check if rust-lint failed" - # Only run when the triggering workflow was for a PR. - if: >- - github.event.workflow_run.event == 'pull_request' - && github.event.workflow_run.conclusion == 'failure' - runs-on: ubuntu-latest - timeout-minutes: 5 - outputs: - lint-failed: ${{ steps.check-job.outputs.lint-failed }} - pr-head-sha: ${{ steps.resolve.outputs.head-sha }} - pr-head-ref: ${{ steps.resolve.outputs.head-ref }} - steps: - - name: Resolve PR ref - id: resolve - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 - with: - script: | - const wr = context.payload.workflow_run; - core.setOutput('head-sha', wr.head_sha); - core.setOutput('head-ref', wr.head_branch); - - - name: Check if rust-lint job failed - id: check-job - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 - with: - script: | - const jobs = await github.rest.actions.listJobsForWorkflowRun({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: context.payload.workflow_run.id, - }); - const lintJob = jobs.data.jobs.find(j => j.name === 'Rust (lint)'); - const failed = lintJob && lintJob.conclusion === 'failure'; - core.setOutput('lint-failed', failed ? 'true' : 'false'); - if (!failed) { - core.info('rust-lint did not fail, skipping fmt fix'); - } - apply-fmt: name: "Apply formatting fix" - needs: check-lint-failed - if: needs.check-lint-failed.outputs.lint-failed == 'true' runs-on: ubuntu-latest timeout-minutes: 15 # The fmt-fix environment must be configured with required reviewers @@ -67,7 +33,7 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: - ref: ${{ needs.check-lint-failed.outputs.pr-head-sha }} + ref: ${{ inputs.pr-head-sha }} - name: Install nightly for fmt run: rustup toolchain install $NIGHTLY_TOOLCHAIN --component rustfmt @@ -77,8 +43,8 @@ jobs: - name: Commit and push env: - EXPECTED_SHA: ${{ needs.check-lint-failed.outputs.pr-head-sha }} - BRANCH: ${{ needs.check-lint-failed.outputs.pr-head-ref }} + EXPECTED_SHA: ${{ inputs.pr-head-sha }} + BRANCH: ${{ inputs.pr-head-ref }} run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" From b8522c163a15931953e61e44f1fadab80ab4868e Mon Sep 17 00:00:00 2001 From: Joe Isaacs Date: Fri, 15 May 2026 15:53:42 +0100 Subject: [PATCH 06/10] u Signed-off-by: Joe Isaacs --- .github/workflows/ci.yml | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 315aa25cf51..659dd9e5b23 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ on: workflow_dispatch: { } permissions: - actions: read + actions: write # dispatch fmt-fix workflow on format failure contents: read checks: write # audit-check creates checks issues: write # audit-check creates issues @@ -200,6 +200,8 @@ jobs: rust-lint: name: "Rust (lint)" timeout-minutes: 30 + outputs: + fmt-failed: ${{ steps.fmt.outcome == 'failure' }} runs-on: >- ${{ github.repository == 'vortex-data/vortex' && format('runs-on={0}/runner=amd64-large/image=ubuntu24-full-x64-pre-v2/tag=rust-lint', github.run_id) @@ -233,20 +235,6 @@ jobs: id: clippy-default continue-on-error: true run: cargo clippy --profile ci --locked --all-targets -- -D warnings - - name: Trigger fmt-fix workflow - if: always() && steps.fmt.outcome == 'failure' && github.event_name == 'pull_request' - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 - with: - script: | - await github.rest.actions.createWorkflowDispatch({ - ...context.repo, - workflow_id: 'fmt-fix.yml', - ref: context.payload.pull_request.head.ref, - inputs: { - 'pr-head-sha': context.payload.pull_request.head.sha, - 'pr-head-ref': context.payload.pull_request.head.ref, - }, - }); - name: Check lint results if: always() uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 @@ -274,6 +262,26 @@ jobs: } core.setFailed(`Lint failed: ${failed.join(', ')}`); + dispatch-fmt-fix: + name: "Dispatch fmt-fix" + needs: rust-lint + if: always() && needs.rust-lint.outputs.fmt-failed == 'true' && github.event_name == 'pull_request' + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 + with: + script: | + await github.rest.actions.createWorkflowDispatch({ + ...context.repo, + workflow_id: 'fmt-fix.yml', + ref: context.payload.pull_request.head.ref, + inputs: { + 'pr-head-sha': context.payload.pull_request.head.sha, + 'pr-head-ref': context.payload.pull_request.head.ref, + }, + }); + cpp-lint: name: "C/C++ (lint)" runs-on: ubuntu-latest From 9481db59e8370214cb27c69f261f6917122e5860 Mon Sep 17 00:00:00 2001 From: Joe Isaacs Date: Fri, 15 May 2026 16:11:28 +0100 Subject: [PATCH 07/10] u Signed-off-by: Joe Isaacs --- .github/workflows/ci.yml | 69 ++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 659dd9e5b23..280049ef746 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -197,11 +197,49 @@ jobs: - uses: ./.github/actions/setup-prebuild - run: cargo minimal-versions check --direct --workspace --ignore-private + rust-fmt: + name: "Rust (fmt)" + timeout-minutes: 10 + outputs: + fmt-failed: ${{ steps.fmt.outcome == 'failure' }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - name: Install nightly for fmt + run: rustup toolchain install $NIGHTLY_TOOLCHAIN --component rustfmt + - name: Rust Lint - Format + id: fmt + continue-on-error: true + run: cargo +$NIGHTLY_TOOLCHAIN fmt --all --check + - name: Fail if fmt failed + if: steps.fmt.outcome == 'failure' + run: exit 1 + + dispatch-fmt-fix: + name: "Dispatch fmt-fix" + needs: rust-fmt + if: always() && needs.rust-fmt.outputs.fmt-failed == 'true' && github.event_name == 'pull_request' + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 + with: + script: | + await github.rest.actions.createWorkflowDispatch({ + ...context.repo, + workflow_id: 'fmt-fix.yml', + ref: context.payload.pull_request.head.ref, + inputs: { + 'pr-head-sha': context.payload.pull_request.head.sha, + 'pr-head-ref': context.payload.pull_request.head.ref, + }, + }); + rust-lint: name: "Rust (lint)" + needs: rust-fmt + if: always() timeout-minutes: 30 - outputs: - fmt-failed: ${{ steps.fmt.outcome == 'failure' }} runs-on: >- ${{ github.repository == 'vortex-data/vortex' && format('runs-on={0}/runner=amd64-large/image=ubuntu24-full-x64-pre-v2/tag=rust-lint', github.run_id) @@ -213,12 +251,6 @@ jobs: sccache: s3 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - uses: ./.github/actions/setup-prebuild - - name: Install nightly for fmt - run: rustup toolchain install $NIGHTLY_TOOLCHAIN --component rustfmt - - name: Rust Lint - Format - id: fmt - continue-on-error: true - run: cargo +$NIGHTLY_TOOLCHAIN fmt --all --check - name: Rustc check id: check continue-on-error: true @@ -241,7 +273,7 @@ jobs: with: script: | const failed = Object.entries({ - fmt: '${{ steps.fmt.outcome }}', + fmt: '${{ needs.rust-fmt.outputs.fmt-failed == 'true' && 'failure' || 'success' }}', check: '${{ steps.check.outcome }}', 'check-release': '${{ steps.check-release.outcome }}', 'clippy-all': '${{ steps.clippy-all.outcome }}', @@ -262,25 +294,6 @@ jobs: } core.setFailed(`Lint failed: ${failed.join(', ')}`); - dispatch-fmt-fix: - name: "Dispatch fmt-fix" - needs: rust-lint - if: always() && needs.rust-lint.outputs.fmt-failed == 'true' && github.event_name == 'pull_request' - runs-on: ubuntu-latest - timeout-minutes: 5 - steps: - - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 - with: - script: | - await github.rest.actions.createWorkflowDispatch({ - ...context.repo, - workflow_id: 'fmt-fix.yml', - ref: context.payload.pull_request.head.ref, - inputs: { - 'pr-head-sha': context.payload.pull_request.head.sha, - 'pr-head-ref': context.payload.pull_request.head.ref, - }, - }); cpp-lint: name: "C/C++ (lint)" From b7b0f68ce8970519f9976e8e941965b544303222 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 15 May 2026 15:13:08 +0000 Subject: [PATCH 08/10] chore: cargo fmt Signed-off-by: github-actions[bot] --- encodings/fastlanes/src/delta/array/delta_compress.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/encodings/fastlanes/src/delta/array/delta_compress.rs b/encodings/fastlanes/src/delta/array/delta_compress.rs index 0e1cc7ed3fd..d51cef72b49 100644 --- a/encodings/fastlanes/src/delta/array/delta_compress.rs +++ b/encodings/fastlanes/src/delta/array/delta_compress.rs @@ -32,7 +32,8 @@ pub fn delta_compress( // TODO(robert): This can be avoided if we add TransposedBoolArray that performs index translation when necessary. let validity = transpose_validity(&validity, ctx)?; ( - PrimitiveArray::new(bases, array.dtype().nullability().into()),PrimitiveArray::new(deltas, validity), + PrimitiveArray::new(bases, array.dtype().nullability().into()), + PrimitiveArray::new(deltas, validity), ) }); From 857ebffd8ea8a8d30c0af241bc37023f4a3d49f8 Mon Sep 17 00:00:00 2001 From: Joe Isaacs Date: Fri, 15 May 2026 17:59:38 +0100 Subject: [PATCH 09/10] u Signed-off-by: Joe Isaacs --- .github/workflows/ci.yml | 2 +- .github/workflows/fmt-fix.yml | 36 ++++++++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 280049ef746..8a855b1524c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -228,7 +228,7 @@ jobs: await github.rest.actions.createWorkflowDispatch({ ...context.repo, workflow_id: 'fmt-fix.yml', - ref: context.payload.pull_request.head.ref, + ref: 'develop', inputs: { 'pr-head-sha': context.payload.pull_request.head.sha, 'pr-head-ref': context.payload.pull_request.head.ref, diff --git a/.github/workflows/fmt-fix.yml b/.github/workflows/fmt-fix.yml index 54ebe5dfa23..af19d9f76fe 100644 --- a/.github/workflows/fmt-fix.yml +++ b/.github/workflows/fmt-fix.yml @@ -20,20 +20,41 @@ env: NIGHTLY_TOOLCHAIN: nightly-2026-02-05 jobs: + # Gate job: requires manual approval via the fmt-fix environment before + # the formatting commit is pushed. + approve: + name: "Approve formatting fix" + runs-on: ubuntu-latest + environment: fmt-fix + steps: + - run: echo "Formatting fix approved" + apply-fmt: name: "Apply formatting fix" + needs: approve runs-on: ubuntu-latest timeout-minutes: 15 - # The fmt-fix environment must be configured with required reviewers - # in the repo settings. This creates an accept/reject gate on the PR - # before the fmt commit is pushed. - environment: fmt-fix + # Use the claude-automation environment to access the GitHub App secrets + # so the push triggers CI. + environment: + name: claude-automation + deployment: false permissions: - contents: write + contents: read + id-token: write steps: + - name: Generate GitHub App token + id: app-token + uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + permission-contents: write + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: ref: ${{ inputs.pr-head-sha }} + persist-credentials: false - name: Install nightly for fmt run: rustup toolchain install $NIGHTLY_TOOLCHAIN --component rustfmt @@ -45,6 +66,7 @@ jobs: env: EXPECTED_SHA: ${{ inputs.pr-head-sha }} BRANCH: ${{ inputs.pr-head-ref }} + APP_TOKEN: ${{ steps.app-token.outputs.token }} run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" @@ -54,6 +76,10 @@ jobs: Signed-off-by: github-actions[bot] " + # Use the App token so the push triggers CI. + git remote set-url origin \ + "https://x-access-token:${APP_TOKEN}@github.com/${{ github.repository }}.git" + # --force-with-lease atomically checks that the remote branch HEAD # is still EXPECTED_SHA before pushing. If someone else pushed a # commit to the PR between trigger and approval, this fails safely. From 01f2033d80d5a1fdb28ff22e8dc34a3bc942bf73 Mon Sep 17 00:00:00 2001 From: Joe Isaacs Date: Fri, 15 May 2026 18:12:06 +0100 Subject: [PATCH 10/10] u Signed-off-by: Joe Isaacs --- encodings/fastlanes/src/delta/array/delta_compress.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/encodings/fastlanes/src/delta/array/delta_compress.rs b/encodings/fastlanes/src/delta/array/delta_compress.rs index e35778ad29e..d11a8bc0a8b 100644 --- a/encodings/fastlanes/src/delta/array/delta_compress.rs +++ b/encodings/fastlanes/src/delta/array/delta_compress.rs @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: Copyright the Vortex contributors use std::mem; -use std::mem::MaybeUninit; +use std::mem::MaybeUninit; use fastlanes::Delta; use fastlanes::FastLanes;