diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..a6a8971 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,85 @@ +# Trigger CI on PR updates and main branch pushes +# Uses caching and selective path triggers to optimize performance + +name: Robrix Rust CI + +# Only `main` branch +on: + push: + branches: + - main + paths: + - packaging/** + - resources/** + - src/** + - .github/** + - Cargo.toml + - rust-toolchain.toml + + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + branches: + - main + paths: + - packaging/** + - resources/** + - src/** + - .github/** + - Cargo.toml + - rust-toolchain.toml + +# Prevent concurrent CI runs and cancel in-progress runs on new pushes +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +# Global environment configuration +env: + CARGO_TERM_COLOR: always + CARGO_INCREMENTAL: "0" # Disable incremental compilation in CI + RUST_BACKTRACE: 1 + # Enable warnings as errors for strict checks + RUSTFLAGS: "-D warnings" + +jobs: + # Basic compilation check to ensure code builds + check: + if: github.event.pull_request.draft == false + name: Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + # Cache dependencies to speed up builds + - uses: Swatinem/rust-cache@v2 + with: + cache-all-crates: "true" + cache-on-failure: "true" + # Check if the code compiles with all features + - run: cargo check --workspace --all-features --all-targets + + clippy: + if: github.event.pull_request.draft == false + name: Clippy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + - uses: Swatinem/rust-cache@v2 + with: + cache-all-crates: "true" + cache-on-failure: "true" + # Run clippy with custom configuration for makepad DSL + # Allow pedantic / needless_lifetimes / too_many_arguments + - run: cargo clippy --workspace --examples --tests --all-features --all-targets + + typos: + if: github.event.pull_request.draft == false + name: Check for typos + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Check for typos + uses: crate-ci/typos@master \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 81dac81..de46ba3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -198,12 +198,21 @@ appdata_paths = [ "$LOCALAPPDATA/$PRODUCTNAME", ] +[lints.rust] +keyword_idents_2024 = "forbid" +non_ascii_idents = "forbid" +non_local_definitions = "forbid" +unsafe_op_in_unsafe_fn = "forbid" -## Configuration for clippy +unexpected_cfgs = "warn" +unnameable_types = "warn" +unused_import_braces = "warn" + +## Configuration for clippy lints. [lints.clippy] collapsible_if = "allow" collapsible_else_if = "allow" too_many_arguments = "allow" blocks_in_conditions = "allow" used_underscore_binding = "allow" -module_name_repetitions = "allow" +module_name_repetitions = "allow" \ No newline at end of file diff --git a/src/home/room_screen.rs b/src/home/room_screen.rs index 016f9fa..12f11e2 100644 --- a/src/home/room_screen.rs +++ b/src/home/room_screen.rs @@ -2957,7 +2957,7 @@ fn populate_image_message_content( // then show a message about it being unsupported. if let Some(mime) = mimetype.as_ref() { if ImageFormat::from_mimetype(mime).is_none() { - text_or_image_ref.show_text(&format!( + text_or_image_ref.show_text(format!( "{body}\n\nImages/Stickers of type {mime:?} are not yet supported.", )); return true; @@ -2983,13 +2983,13 @@ fn populate_image_message_content( true } MediaCacheEntry::Requested => { - text_or_image_ref.show_text(&format!("{body}\n\nFetching image from {:?}", mxc_uri)); + text_or_image_ref.show_text(format!("{body}\n\nFetching image from {:?}", mxc_uri)); // Do not consider this image as being fully drawn, as we're still fetching it. false } MediaCacheEntry::Failed => { text_or_image_ref - .show_text(&format!("{body}\n\nFailed to fetch image from {:?}", mxc_uri)); + .show_text(format!("{body}\n\nFailed to fetch image from {:?}", mxc_uri)); // For now, we consider this as being "complete". In the future, we could support // retrying to fetch the image on a user click/tap. true @@ -2997,7 +2997,7 @@ fn populate_image_message_content( } } Some(MediaSource::Encrypted(encrypted)) => { - text_or_image_ref.show_text(&format!( + text_or_image_ref.show_text(format!( "{body}\n\n[TODO] fetch encrypted image at {:?}", encrypted.url )); diff --git a/src/shared/html_or_plaintext.rs b/src/shared/html_or_plaintext.rs index 03c81d3..d4a3475 100644 --- a/src/shared/html_or_plaintext.rs +++ b/src/shared/html_or_plaintext.rs @@ -144,7 +144,7 @@ impl LiveHook for MatrixHtmlSpan { if let Some(doc) = scope.props.get::() { let mut walker = doc.new_walker_with_index(scope.index + 1); while let Some((lc, attr)) = walker.while_attr_lc(){ - let attr = attr.trim_matches(&['"', '\'']); + let attr = attr.trim_matches(['"', '\'']); match lc { live_id!(color) | live_id!(data-mx-color) => self.fg_color = Vec4::from_hex_str(attr).ok(), diff --git a/src/sliding_sync.rs b/src/sliding_sync.rs index 4081fc6..428bd9a 100644 --- a/src/sliding_sync.rs +++ b/src/sliding_sync.rs @@ -1973,14 +1973,13 @@ async fn spawn_sso_server( .identity_provider_id(&identity_provider_id) .initial_device_display_name(&format!("robrix-sso-{brand}")) .await - .map(|response| { + .inspect(|_| { if let Some(client) = get_client() { if client.logged_in() { is_logged_in = true; log!("Already logged in, ignore login with sso"); } } - response }) { Ok(identity_provider_res) => { if !is_logged_in {