From 86d97403461522b89bff33c14721564c1d28e54e Mon Sep 17 00:00:00 2001 From: Conor Bronsdon <120674402+conorbronsdon@users.noreply.github.com> Date: Fri, 31 Jul 2026 14:31:32 -0700 Subject: [PATCH 1/2] Replace the removed String.write static call with the String constructor Mojo's stdlib made String.write an instance method -- both overloads now take `mut self` -- so the old static form no longer resolves and the test module fails to parse. String.__init__ takes a variadic pack of Writable arguments and Error conforms to Writable, so String(e) is the direct replacement. Test-only; nothing in src/ used the static form. Co-Authored-By: Claude Opus 5 (1M context) --- test/test_errors.mojo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_errors.mojo b/test/test_errors.mojo index 812c1bc..2fa63fd 100644 --- a/test/test_errors.mojo +++ b/test/test_errors.mojo @@ -10,7 +10,7 @@ def _assert_lc(source: String, offset: Int, line: Int, col: Int) raises: def _msg(e: Error) -> String: - return String.write(e) + return String(e) # -------------------------------------------------------------------------- From 834210d510f1c4f9f8dc9c8480d4df2e572024c6 Mon Sep 17 00:00:00 2001 From: Conor Bronsdon <120674402+conorbronsdon@users.noreply.github.com> Date: Fri, 31 Jul 2026 14:49:25 -0700 Subject: [PATCH 2/2] 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 7c8a80c..1c64b06 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 bf0c749..5e23e57 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: "27 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: Unit tests — parse-error positions run: .venv/bin/mojo run -I src test/test_errors.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 <