From 914fee612d1722a8afb018f6a75d4028b6e602d9 Mon Sep 17 00:00:00 2001 From: Conor Bronsdon <120674402+conorbronsdon@users.noreply.github.com> Date: Fri, 31 Jul 2026 14:49:43 -0700 Subject: [PATCH] Pin CI to a known-good Mojo nightly; check drift weekly Both workflows installed `mojo` from the nightly index unpinned, so every run resolved whatever nightly was current. That is why this repo went green on 7/29 and red on 7/31 with no commits in between -- a frozen library's CI decayed on its own, and the breakage surfaced on an unrelated docs PR. CI now installs exactly the nightly the repo is known to pass on. Upstream churn can no longer turn a green repo red without a commit. Pinning alone would trade one problem for a worse one: silence. So test.yml also runs weekly against the LATEST nightly. That run is advisory -- it fires on main, so it never gates a PR -- and on failure it opens (or comments on) a drift issue, because a red X on the Actions tab of a repo nobody is watching is not a signal. The weekly check reuses test.yml rather than living in its own file. A separate workflow would have to duplicate this repo's bespoke test steps and would drift out of sync with them. docs.yaml is pinned but not scheduled -- it deploys Pages, and a weekly redeploy is not wanted. `mojo doc` compiles the sources, so the test job catches the same stdlib breakage anyway. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/docs.yaml | 9 ++++-- .github/workflows/test.yml | 60 ++++++++++++++++++++++++++++++++++--- 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 44a6097..ffc6c47 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -14,6 +14,11 @@ concurrency: group: pages cancel-in-progress: true +env: + # Keep in step with test.yml's pin -- docs runs `mojo doc`, which compiles the + # sources and so breaks on the same stdlib changes the tests do. + MOJO_VERSION: "1.0.0b3.dev2026073014" + jobs: build-deploy: runs-on: ubuntu-latest @@ -27,10 +32,10 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@v5 - - name: Install Mojo nightly + - name: Install Mojo run: | uv venv - uv pip install mojo \ + uv pip install "mojo==$MOJO_VERSION" \ --index https://whl.modular.com/nightly/simple/ \ --prerelease allow diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0e2ad90..a61aa47 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,23 +4,46 @@ on: push: branches: [main] pull_request: + # Weekly drift check against the latest nightly. Advisory only -- it runs on + # main, so a failure never blocks a PR; it tells us the language moved under a + # frozen repo. See the install step for how the two modes differ. + schedule: + - cron: "47 13 * * 1" + workflow_dispatch: + +env: + # The nightly this repo is known to build and pass on. CI installs exactly + # this for pushes and PRs, so upstream churn cannot turn a green repo red + # without a commit. Bump it when the weekly drift check goes green on a newer + # one, or after fixing whatever it caught. + MOJO_VERSION: "1.0.0b3.dev2026073014" jobs: test: runs-on: ubuntu-latest timeout-minutes: 20 + permissions: + contents: read + issues: write steps: - uses: actions/checkout@v4 - name: Install uv uses: astral-sh/setup-uv@v5 - - name: Install Mojo nightly + - name: Install Mojo run: | uv venv - uv pip install mojo \ - --index https://whl.modular.com/nightly/simple/ \ - --prerelease allow + if [ "${{ github.event_name }}" = "schedule" ]; then + echo "::notice::Drift check: installing the LATEST nightly, ignoring the $MOJO_VERSION pin" + uv pip install mojo \ + --index https://whl.modular.com/nightly/simple/ \ + --prerelease allow + else + uv pip install "mojo==$MOJO_VERSION" \ + --index https://whl.modular.com/nightly/simple/ \ + --prerelease allow + fi .venv/bin/mojo --version - name: Format check @@ -33,3 +56,32 @@ jobs: - name: Conformance (NormalizationTest.txt) run: .venv/bin/mojo run -I src test/conformance.mojo + + - name: Report nightly drift + if: failure() && github.event_name == 'schedule' + env: + GH_TOKEN: ${{ github.token }} + run: | + title="Mojo nightly drift: tests fail against the latest nightly" + installed=$(.venv/bin/mojo --version 2>/dev/null || echo "unknown") + # Heredoc, not a quoted string: a multi-line shell string would keep + # this block's indentation and markdown would render the body as code. + body=$(cat <