This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a commit to branch 
gh-readonly-queue/main/pr-11631-3db18f75b40921b8abf17daed32999ec58064f7d
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git

commit df4dc3ede59bd43b5f71847231212381d068bb72
Author: Kosta Tarasov <[email protected]>
AuthorDate: Fri Oct 23 07:02:16 2026 +0000

    Run Miri on a daily schedule, require it before releases (#11631)
    
    ## Which issue does this PR close?
    
    Part of #11548.
    
    ## Rationale for this change
    
    Miri runs are expensive and delay the merge queue. Run Miri daily and on
    demand before a release.
    
    ## What changes are included in this PR?
    
    - Remove Miri from merge-queue execution and required checks.
    - Enable manual runs through `workflow_dispatch`.
    - Run Miri daily 3:17 UTC
    - Add release instructions to run Miri before cutting a release commit,
    verify all partitions pass, and link the results in the release issue.
    
    ## Are these changes tested?
    
    Updated CI routing tests pass. Workflow linting, Markdown formatting,
    and spelling checks pass. The Miri suite itself was not run.
    
    ## Are there any significant user-facing changes?
    
    No.
    
    AI assisted with implementation and validation.
    
    ---------
    
    Co-authored-by: Andrew Lamb <[email protected]>
---
 .github/ci/scripts/check-ci-config.py | 13 +++++--------
 .github/ci/scripts/compute-changes.py |  2 +-
 .github/workflows/README.md           |  6 +++++-
 .github/workflows/ci.yml              | 12 ++++--------
 .github/workflows/miri.yaml           |  8 ++++++--
 dev/release/README.md                 | 13 +++++++++++++
 6 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/.github/ci/scripts/check-ci-config.py 
b/.github/ci/scripts/check-ci-config.py
index 2648251b4f..a902b9b4b2 100644
--- a/.github/ci/scripts/check-ci-config.py
+++ b/.github/ci/scripts/check-ci-config.py
@@ -100,8 +100,8 @@ def validate_config(root=ROOT):
     ci = load_yaml(workflows / "ci.yml")
     filters = load_yaml(root / ".github/ci/paths.yaml")
     jobs = ci["jobs"]
-    suites = set(filters["suites"]) | ALWAYS | {"miri"}
-    assert not (set(filters["suites"]) & (ALWAYS | {"miri"})), "Unexpected 
filtered suite"
+    suites = set(filters["suites"]) | ALWAYS
+    assert not (set(filters["suites"]) & ALWAYS), "Unexpected filtered suite"
     assert set(jobs) == suites | {"changes", "required-checks"}, "CI suites 
and jobs differ"
     # PyYAML's YAML 1.1 loader treats the key 'on' as the boolean True.
     events = ci[True]
@@ -146,8 +146,6 @@ def validate_config(root=ROOT):
         and "workflow_call" in load_yaml(path).get(True, {})
     }
     assert called == reusable, "A reusable workflow is missing from Required 
Checks"
-    miri = load_yaml(workflows / "miri.yaml")["jobs"]["miri-checks"]
-    assert "if" not in miri, "Miri event routing belongs in compute-changes.py"
     print("CI configuration is valid")
 
 
@@ -165,7 +163,7 @@ class RoutingTests(unittest.TestCase):
     def test_event_policy(self):
         for paths in [[], ["README.md"], ["arrow-buffer/src/lib.rs"]]:
             with self.subTest(paths=paths):
-                self.assertEqual(self.select("merge_group", paths), 
self.all_suites | {"miri"})
+                self.assertEqual(self.select("merge_group", paths), 
self.all_suites)
                 self.assertEqual(self.select("push", paths), {"docs", 
"integration", "parquet"})
                 self.assertNotIn("miri", self.select("pull_request", paths))
         with self.assertRaises(ValueError):
@@ -173,7 +171,7 @@ class RoutingTests(unittest.TestCase):
 
     def test_selector_outputs(self):
         for event, expected in [("push", {"docs", "integration", "parquet"}),
-                                ("merge_group", self.all_suites | {"miri"}),
+                                ("merge_group", self.all_suites),
                                 ("pull_request", self.always)]:
             with self.subTest(event=event), tempfile.TemporaryDirectory() as 
directory:
                 output = Path(directory) / "output"
@@ -235,10 +233,9 @@ class ConfigurationTests(unittest.TestCase):
     def test_configuration_regressions(self):
         cases = [
             (".asf.yaml", '"Required Checks"', '"Missing Check"'),
-            (".github/workflows/ci.yml", "      - miri\n", ""),
+            (".github/workflows/ci.yml", "      - arrow\n", ""),
             (".github/workflows/ci.yml", "  pull_request:\n", "  
pull_request:\n    paths: ['arrow/**']\n"),
             (".github/workflows/ci.yml", "    if: always()", "    if: 
success()"),
-            (".github/workflows/miri.yaml", "    name: MIRI\n", "    name: 
MIRI\n    if: github.event_name == 'merge_group'\n"),
             (".github/workflows/arrow.yml", "  workflow_call:", "  
workflow_call:\n  pull_request:"),
             (".github/ci/paths.yaml", "    - arrow-integration-testing/**\n", 
""),
             (".github/workflows/ci.yml", "      cache-refresh-only: ${{ 
steps.select.outputs.cache-refresh-only }}\n", ""),
diff --git a/.github/ci/scripts/compute-changes.py 
b/.github/ci/scripts/compute-changes.py
index 0b8706206c..748180b4e0 100644
--- a/.github/ci/scripts/compute-changes.py
+++ b/.github/ci/scripts/compute-changes.py
@@ -36,7 +36,7 @@ def load_yaml(path):
 def select_suites(event, paths, filters):
     suites = set(filters["suites"]) | ALWAYS
     if event == "merge_group":
-        return sorted(suites | {"miri"})
+        return sorted(suites)
     if event == "push":
         # The queue already tested the merge result. Publish docs and populate
         # main's caches through the reusable workflows' cache-refresh-only 
mode.
diff --git a/.github/workflows/README.md b/.github/workflows/README.md
index d5c5d915c6..74ea738595 100644
--- a/.github/workflows/README.md
+++ b/.github/workflows/README.md
@@ -18,6 +18,10 @@
 -->
 
 CI runs a subset of checks on pull requests, selected by the changed files.
-The merge queue runs the full test suite against the proposed merge result.
+The merge queue runs the full test suite, except Miri, against the proposed 
merge result.
 Pushes to `main` populate caches and publish documentation without repeating 
tests.
 A single required status check combines the results and blocks merging on 
failure.
+
+Miri runs separately every day at 03:17 UTC and on demand through the `miri`
+workflow's **Run workflow** button or
+`gh workflow run miri.yaml --repo apache/arrow-rs --ref <branch-or-tag>`.
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index dcd624568c..6585f1a278 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -110,11 +110,6 @@ jobs:
       contents: write
     uses: ./.github/workflows/docs.yml
 
-  miri:
-    needs: changes
-    if: contains(fromJSON(needs.changes.outputs.suites), 'miri')
-    uses: ./.github/workflows/miri.yaml
-
   required-checks:
     # Like datafusion-comet: one stable check name even when a reusable
     # workflow is skipped (its individual check names would be different).
@@ -131,15 +126,16 @@ jobs:
       - dev
       - rust
       - docs
-      - miri
     runs-on: ubuntu-slim
     steps:
       - name: Summarize suite results
         env:
           NEEDS: ${{ toJSON(needs) }}
         run: echo "$NEEDS"
-      # Path-filtered suites and Miri outside the queue are intentionally
-      # skipped. A failed/cancelled selector or suite must still block merging.
+      # Path-filtered suites are intentionally skipped. A failed/cancelled
+      # selector or suite must still block merging.
+      # Miri runs separately to reduce runner time:
+      # https://github.com/apache/arrow-rs/issues/11548
       - name: Fail if any suite failed or was cancelled
         if: needs.changes.result != 'success' || contains(needs.*.result, 
'failure') || contains(needs.*.result, 'cancelled')
         run: |
diff --git a/.github/workflows/miri.yaml b/.github/workflows/miri.yaml
index 3d99720004..48eb1d0df5 100644
--- a/.github/workflows/miri.yaml
+++ b/.github/workflows/miri.yaml
@@ -17,9 +17,13 @@
 
 name: miri
 
-# Triggered by ci.yml, which owns event routing and concurrency.
+# Run daily and on demand, including before cutting a release candidate.
+# Keep Miri out of the merge queue to reduce runner time:
+# https://github.com/apache/arrow-rs/issues/11548
 on:
-  workflow_call:
+  schedule:
+    - cron: "17 3 * * *"
+  workflow_dispatch:
 
 permissions:
   contents: read
diff --git a/dev/release/README.md b/dev/release/README.md
index 35ffc8f12d..87a5a213c3 100644
--- a/dev/release/README.md
+++ b/dev/release/README.md
@@ -92,6 +92,19 @@ Note that when reviewing the change log, rather than editing 
the
 
 Merge this PR to `main` prior to the next step.
 
+## Verify Miri results (required)
+
+Before cutting a release candidate, run the
+[Miri workflow](https://github.com/apache/arrow-rs/actions/workflows/miri.yaml)
+on `main`:
+
+```shell
+gh workflow run miri.yaml --repo apache/arrow-rs --ref main
+```
+
+All partitions must pass before creating the RC tag. Review the results and
+link the run in the release tracking issue.
+
 ## Prepare release candidate tarball
 
 After you have merged the updates to the `CHANGELOG` and version,

Reply via email to