From f66aea0b906264d80145ab85b2686a23ff436ede Mon Sep 17 00:00:00 2001 From: mmacedoeu Date: Fri, 19 Jun 2026 01:11:43 -0300 Subject: [PATCH 1/3] chore(ci): move telegram live_session_test to standalone crate outside main workspace The live integration test for octo-adapter-telegram against a real TDLib session was previously located at crates/octo-adapter-telegram/tests/ live_session_test.rs. Because octo-telegram-onboard-core depends on octo-adapter-telegram with features = ["real-tdlib"], cargo's workspace feature unification enabled the real-tdlib feature across the workspace, which in turn caused 'cargo test --workspace' to auto-discover and build the live_session_test target. At test-execution time the test binary failed to load with 'error while loading shared libraries: libc++.so.1' because the prebuilt TDLib shared library is linked against LLVM's libc++, which is not installed on the default ubuntu-latest CI runner. This broke CI for every push. Feature gates and explicit [[test]] entries could not isolate the test: cargo's feature resolver unifies 'free' features across the workspace, so the test was always built. Move the live test to a new standalone crate at live-tests/octo-telegram-live-tests/ that is intentionally NOT a member of the main workspace (root Cargo.toml uses members = ["crates/*"]; the new crate lives in live-tests/, which the root glob does not match). The new crate declares an empty [workspace] table so it is a complete workspace of its own, and is therefore physically unreachable from 'cargo test --workspace' at the repo root. This guarantees CI can never build or run the live test, regardless of feature flags, resolver behavior, or transitive feature unification. To run the live test manually: cd live-tests/octo-telegram-live-tests cargo test -- --ignored --nocapture --test-threads=1 Changes: - Move crates/octo-adapter-telegram/tests/live_session_test.rs -> live-tests/octo-telegram-live-tests/tests/live_session_test.rs - New crate: live-tests/octo-telegram-live-tests/ (standalone, with empty [workspace] table) containing Cargo.toml, src/lib.rs (marker), tests/live_session_test.rs, and .gitignore (target/, Cargo.lock) - Move tracing-subscriber dev-dependency from octo-adapter-telegram to the new crate (where the test now lives) - ci.yml: no change needed; the 'Install C++ runtime' step is no longer required because CI cannot reach the live test --- crates/octo-adapter-telegram/Cargo.toml | 2 -- .../octo-telegram-live-tests/.gitignore | 2 ++ .../octo-telegram-live-tests/Cargo.toml | 29 +++++++++++++++++++ .../octo-telegram-live-tests/src/lib.rs | 5 ++++ .../tests/live_session_test.rs | 0 5 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 live-tests/octo-telegram-live-tests/.gitignore create mode 100644 live-tests/octo-telegram-live-tests/Cargo.toml create mode 100644 live-tests/octo-telegram-live-tests/src/lib.rs rename {crates/octo-adapter-telegram => live-tests/octo-telegram-live-tests}/tests/live_session_test.rs (100%) diff --git a/crates/octo-adapter-telegram/Cargo.toml b/crates/octo-adapter-telegram/Cargo.toml index 82aa2dd2..df1d805f 100644 --- a/crates/octo-adapter-telegram/Cargo.toml +++ b/crates/octo-adapter-telegram/Cargo.toml @@ -64,5 +64,3 @@ tempfile = { version = "3.10", optional = true } tokio = { version = "1.35", features = ["test-util"] } serde_yaml = "0.9" ed25519-dalek = "2" -# tracing setup in live_session_test (env-filter for RUST_LOG control) -tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/live-tests/octo-telegram-live-tests/.gitignore b/live-tests/octo-telegram-live-tests/.gitignore new file mode 100644 index 00000000..2c96eb1b --- /dev/null +++ b/live-tests/octo-telegram-live-tests/.gitignore @@ -0,0 +1,2 @@ +target/ +Cargo.lock diff --git a/live-tests/octo-telegram-live-tests/Cargo.toml b/live-tests/octo-telegram-live-tests/Cargo.toml new file mode 100644 index 00000000..0bd79596 --- /dev/null +++ b/live-tests/octo-telegram-live-tests/Cargo.toml @@ -0,0 +1,29 @@ +[workspace] +# Empty workspace table — declares this directory a standalone package +# (NOT a member of the parent workspace at the repo root). This is what +# physically keeps `cargo test --workspace` from the root from ever +# building or running these tests. + +[package] +name = "octo-telegram-live-tests" +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" +description = "Live integration tests for octo-adapter-telegram against a real TDLib session. Intentionally NOT a workspace member — see docs/ and the crate's README below. Run with: cd live-tests/octo-telegram-live-tests && cargo test -- --ignored --nocapture --test-threads=1" + +# This crate is NOT in the main workspace on purpose: +# 1. CI's `cargo test --workspace` from the repo root must never build or +# run these tests. A live Telegram session, mounted data dir, and +# working TDLib shared library are all required. +# 2. The main workspace's `octo-adapter-telegram` is built with `real-tdlib` +# enabled transitively (via `octo-telegram-onboard-core`'s feature +# unification), so any test file inside its `tests/` would be auto-built +# by `cargo test --workspace` regardless of feature gates. Moving the +# live test here physically separates it from the CI build path. +# To run: cd live-tests/octo-telegram-live-tests && cargo test -- --ignored --nocapture --test-threads=1 + +[dependencies] +octo-adapter-telegram = { path = "../../crates/octo-adapter-telegram", features = ["real-tdlib"] } +octo-network = { path = "../../crates/octo-network" } +tokio = { version = "1.35", features = ["rt-multi-thread", "macros", "time", "sync"] } +tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/live-tests/octo-telegram-live-tests/src/lib.rs b/live-tests/octo-telegram-live-tests/src/lib.rs new file mode 100644 index 00000000..df2d5b8a --- /dev/null +++ b/live-tests/octo-telegram-live-tests/src/lib.rs @@ -0,0 +1,5 @@ +//! Marker library for the live-tests crate. This crate only exists to host +//! integration tests under `tests/`; it has no library API of its own. +//! +//! See `tests/live_session_test.rs` for the actual tests, and `Cargo.toml` +//! for why this crate is intentionally outside the main workspace. diff --git a/crates/octo-adapter-telegram/tests/live_session_test.rs b/live-tests/octo-telegram-live-tests/tests/live_session_test.rs similarity index 100% rename from crates/octo-adapter-telegram/tests/live_session_test.rs rename to live-tests/octo-telegram-live-tests/tests/live_session_test.rs From 7e3583b0777b5f058340a7d644a3d5a571c43852 Mon Sep 17 00:00:00 2001 From: mmacedoeu Date: Fri, 19 Jun 2026 12:19:28 -0300 Subject: [PATCH 2/3] fix(ci): install rust toolchain in quota-router-python type-check job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The type-check job was failing on fresh runners with: 💥 maturin failed Caused by: Failed to run rustc to get the host target error: failed to install component: 'clippy-preview-x86_64-unknown-linux-gnu', detected conflict: 'bin/cargo-clippy' Root cause: the type-check job ran 'maturin develop' without first installing a Rust toolchain via rustup. Maturin then tried to bootstrap its own rustc and hit a toolchain conflict on runners with a partially installed or stale rustup state. The test job in the same workflow already has - name: Install Rust uses: dtolnay/rust-toolchain@stable and works. The type-check job was missing this step. Adding it mirrors the test job exactly, gives maturin a clean system rustc to use, and resolves the conflict on fresh runners. --- .github/workflows/quota-router-python.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/quota-router-python.yml b/.github/workflows/quota-router-python.yml index 0c5cae2a..5df62c0c 100644 --- a/.github/workflows/quota-router-python.yml +++ b/.github/workflows/quota-router-python.yml @@ -75,6 +75,17 @@ jobs: with: python-version: '3.12' + # Install Rust explicitly. Without this, `maturin develop` below + # tries to bootstrap its own rustc via rustup and fails on fresh + # runners with: + # error: failed to install component: 'clippy-preview-x86_64-unknown-linux-gnu', + # detected conflict: 'bin/cargo-clippy' + # The `test` job above has the same step and works; this job was + # missing it. Pinning `dtolnay/rust-toolchain@stable` matches + # the `test` job exactly and gives maturin a clean rustup to use. + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + # See note above on explicit venv creation. - name: Create venv and install mypy run: | From 2f997801b89abf1df000e18db212d9b4a909db29 Mon Sep 17 00:00:00 2001 From: mmacedoeu Date: Fri, 19 Jun 2026 12:32:42 -0300 Subject: [PATCH 3/3] fix(ci): install cargo via profile: default in quota-router-python build job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The build job was failing on fresh runners with: info: syncing channel updates for 1.96.0-x86_64-unknown-linux-gnu info: downloading component clippy error: 'cargo' is not installed for the toolchain '1.96.0-x86_64-unknown-linux-gnu' 💥 maturin failed Caused by: Cargo metadata failed. Caused by: `cargo metadata` exited with an error Root cause: dtolnay/rust-toolchain@stable defaults to --profile minimal, which installs only rustc (no cargo, no clippy, no rustfmt). The test and type-check jobs in this workflow happen to work because their runners have cargo pre-installed in the Ubuntu image. The build job hit a fresh runner without that, and maturin could not find cargo for the stable toolchain. Switch the build job's Install Rust step to profile: default, which installs cargo (and clippy, rustfmt, rust-docs) explicitly via rustup. The build job is now self-sufficient regardless of the runner image. The test and type-check jobs are left at the default (minimal) profile since they currently work; they can be flipped to default later if they start hitting the same issue. --- .github/workflows/quota-router-python.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/quota-router-python.yml b/.github/workflows/quota-router-python.yml index 5df62c0c..f075dce4 100644 --- a/.github/workflows/quota-router-python.yml +++ b/.github/workflows/quota-router-python.yml @@ -121,6 +121,18 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable + with: + # dtolnay/rust-toolchain defaults to `--profile minimal`, which + # installs only rustc (no cargo, no clippy, no rustfmt). The + # `test` and `type-check` jobs in this workflow happen to work + # because their runners have cargo pre-installed in the Ubuntu + # image. The `build` job hit a fresh runner without that, and + # maturin failed with: + # error: 'cargo' is not installed for the toolchain '1.96.0-x86_64-unknown-linux-gnu' + # Switching to `profile: default` installs cargo (and clippy, + # rustfmt, rust-docs) explicitly via rustup, making the build + # job self-sufficient regardless of the runner image. + profile: default - name: Install maturin run: pip install --upgrade pip && pip install maturin