Repository: actix/actix (language: rust)

Issue:
use GitHub Actions?
I noticed that actix-web is using GitHub Actions, might be good to have actix use it too.


Discussion / hints:

Fix patch:
diff --git a/.appveyor.yml b/.appveyor.yml
deleted file mode 100644
index 3f7c0126b..000000000
--- a/.appveyor.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-environment:
-  global:
-    PROJECT_NAME: actix
-  matrix:
-    # Stable channel
-    - TARGET: i686-pc-windows-msvc
-      CHANNEL: stable
-    - TARGET: x86_64-pc-windows-gnu
-      CHANNEL: stable
-    - TARGET: x86_64-pc-windows-msvc
-      CHANNEL: stable
-    # Nightly channel
-    - TARGET: i686-pc-windows-msvc
-      CHANNEL: nightly
-    - TARGET: x86_64-pc-windows-gnu
-      CHANNEL: nightly
-    - TARGET: x86_64-pc-windows-msvc
-      CHANNEL: nightly
-
-# Install Rust and Cargo
-# (Based on from https://github.com/rust-lang/libc/blob/master/appveyor.yml)
-install:
-  - curl -sSf -o rustup-init.exe https://win.rustup.rs
-  - rustup-init.exe --default-host %TARGET% --default-toolchain %CHANNEL% -y
-  - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin;C:\msys64\mingw64\bin;C:\msys64\usr\bin;
-  - rustc -Vv
-  - cargo -V
-
-# 'cargo test' takes care of building for us, so disable Appveyor's build stage.
-build: false
-
-# Equivalent to Travis' `script` phase
-test_script:
-  - set RUST_BACKTRACE=1
-  - cargo build
-  - cargo test
diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml
new file mode 100644
index 000000000..d84ffc00c
--- /dev/null
+++ b/.github/workflows/clippy.yml
@@ -0,0 +1,17 @@
+on: pull_request
+
+name: Clippy Check
+jobs:
+  clippy_check:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions-rs/toolchain@v1
+        with:
+          toolchain: nightly
+          components: clippy
+          override: true
+      - uses: actions-rs/clippy-check@v1
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+          args: --all-features --all --tests
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
new file mode 100644
index 000000000..41cc3d2bb
--- /dev/null
+++ b/.github/workflows/linux.yml
@@ -0,0 +1,65 @@
+name: CI (Linux)
+
+on: [push, pull_request]
+
+jobs:
+  build_and_test:
+    strategy:
+      fail-fast: false
+      matrix:
+        version:
+          - 1.39.0 # MSRV
+          - stable
+          - nightly
+
+    name: ${{ matrix.version }} - x86_64-unknown-linux-gnu
+    runs-on: ubuntu-latest
+
+    steps:
+      - uses: actions/checkout@master
+
+      - name: Install ${{ matrix.version }}
+        uses: actions-rs/toolchain@v1
+        with:
+          toolchain: ${{ matrix.version }}-x86_64-unknown-linux-gnu
+          profile: minimal
+          override: true
+
+      - name: Generate Cargo.lock
+        uses: actions-rs/cargo@v1
+        with:
+          command: generate-lockfile
+      - name: Cache cargo registry
+        uses: actions/cache@v1
+        with:
+          path: ~/.cargo/registry
+          key: ${{ matrix.version }}-x86_64-unknown-linux-gnu-cargo-registry-trimmed-${{ hashFiles('**/Cargo.lock') }}
+      - name: Cache cargo index
+        uses: actions/cache@v1
+        with:
+          path: ~/.cargo/git
+          key: ${{ matrix.version }}-x86_64-unknown-linux-gnu-cargo-index-trimmed-${{ hashFiles('**/Cargo.lock') }}
+      - name: Cache cargo build
+        uses: actions/cache@v1
+        with:
+          path: target
+          key: ${{ matrix.version }}-x86_64-unknown-linux-gnu-cargo-build-trimmed-${{ hashFiles('**/Cargo.lock') }}
+
+      - name: check build
+        uses: actions-rs/cargo@v1
+        with:
+          command: check
+          args: --all --bins --examples --tests
+
+      - name: tests
+        uses: actions-rs/cargo@v1
+        timeout-minutes: 40
+        with:
+          command: test
+          args: --all --all-features --no-fail-fast -- --nocapture
+                --skip=test_restart_sync_actor
+
+      - name: Clear the cargo caches
+        run: |
+          cargo install cargo-cache --no-default-features --features ci-autoclean
+          cargo-cache
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
new file mode 100644
index 000000000..ac94d5e7d
--- /dev/null
+++ b/.github/workflows/macos.yml
@@ -0,0 +1,64 @@
+name: CI (macOS)
+
+on: [push, pull_request]
+
+jobs:
+  build_and_test:
+    strategy:
+      fail-fast: false
+      matrix:
+        version:
+          - stable
+          - nightly
+
+    name: ${{ matrix.version }} - x86_64-apple-darwin
+    runs-on: macOS-latest
+
+    steps:
+      - uses: actions/checkout@master
+
+      - name: Install ${{ matrix.version }}
+        uses: actions-rs/toolchain@v1
+        with:
+          toolchain: ${{ matrix.version }}-x86_64-apple-darwin
+          profile: minimal
+          override: true
+
+      - name: Generate Cargo.lock
+        uses: actions-rs/cargo@v1
+        with:
+          command: generate-lockfile
+      - name: Cache cargo registry
+        uses: actions/cache@v1
+        with:
+          path: ~/.cargo/registry
+          key: ${{ matrix.version }}-x86_64-apple-darwin-cargo-registry-trimmed-${{ hashFiles('**/Cargo.lock') }}
+      - name: Cache cargo index
+        uses: actions/cache@v1
+        with:
+          path: ~/.cargo/git
+          key: ${{ matrix.version }}-x86_64-apple-darwin-cargo-index-trimmed-${{ hashFiles('**/Cargo.lock') }}
+      - name: Cache cargo build
+        uses: actions/cache@v1
+        with:
+          path: target
+          key: ${{ matrix.version }}-x86_64-apple-darwin-cargo-build-trimmed-${{ hashFiles('**/Cargo.lock') }}
+
+      - name: check build
+        uses: actions-rs/cargo@v1
+        with:
+          command: check
+          args: --all --bins --examples --tests
+
+      - name: tests
+        uses: actions-rs/cargo@v1
+        timeout-minutes: 40
+        with:
+          command: test
+          args: --all --all-features --no-fail-fast -- --nocapture
+                --skip=test_stream_timeout
+
+      - name: Clear the cargo caches
+        run: |
+          cargo install cargo-cache --no-default-features --features ci-autoclean
+          cargo-cache
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
new file mode 100644
index 000000000..d07539756
--- /dev/null
+++ b/.github/workflows/windows.yml
@@ -0,0 +1,69 @@
+name: CI (Windows)
+
+on: [push, pull_request]
+
+jobs:
+  build_and_test:
+    strategy:
+      fail-fast: false
+      matrix:
+        version:
+          - stable
+          - nightly
+        target:
+          - x86_64-pc-windows-msvc
+          - x86_64-pc-windows-gnu
+          - i686-pc-windows-msvc
+
+    name: ${{ matrix.version }} - ${{ matrix.target }}
+    runs-on: windows-latest
+
+    steps:
+      - uses: actions/checkout@master
+
+      - name: Install ${{ matrix.version }}
+        uses: actions-rs/toolchain@v1
+        with:
+          toolchain: ${{ matrix.version }}-${{ matrix.target }}
+          profile: minimal
+          override: true
+
+      - name: Generate Cargo.lock
+        uses: actions-rs/cargo@v1
+        with:
+          command: generate-lockfile
+      - name: Cache cargo registry
+        uses: actions/cache@v1
+        with:
+          path: ~/.cargo/registry
+          key: ${{ matrix.version }}-${{ matrix.target }}-cargo-registry-trimmed-${{ hashFiles('**/Cargo.lock') }}
+      - name: Cache cargo index
+        uses: actions/cache@v1
+        with:
+          path: ~/.cargo/git
+          key: ${{ matrix.version }}-${{ matrix.target }}-cargo-index-trimmed-${{ hashFiles('**/Cargo.lock') }}
+      - name: Cache cargo build
+        uses: actions/cache@v1
+        with:
+          path: target
+          key: ${{ matrix.version }}-${{ matrix.target }}-cargo-build-trimmed-${{ hashFiles('**/Cargo.lock') }}
+
+      - name: check build
+        uses: actions-rs/cargo@v1
+        with:
+          command: check
+          args: --all --bins --examples --tests
+
+      - name: tests
+        uses: actions-rs/cargo@v1
+        timeout-minutes: 40
+        with:
+          command: test
+          args: --all --all-features --no-fail-fast -- --nocapture
+                --skip=test_restart_sync_actor
+                --skip=test_start_actor_message
+
+      - name: Clear the cargo caches
+        run: |
+          cargo install cargo-cache --no-default-features --features ci-autoclean
+          cargo-cache
diff --git a/src/actors/mocker.rs b/src/actors/mocker.rs
index cf794b85f..493aa97c7 100644
--- a/src/actors/mocker.rs
+++ b/src/actors/mocker.rs
@@ -35,12 +35,14 @@ use crate::prelude::*;
 /// This actor is able to wrap another actor and accept all the messages the
 /// wrapped actor can, passing it to a closure which can mock the response of
 /// the actor.
+#[allow(clippy::type_complexity)]
 pub struct Mocker<T: Sized + Unpin + 'static> {
     phantom: PhantomData<T>,
     mock: Box<dyn FnMut(Box<dyn Any>, &mut Context<Mocker<T>>) -> Box<dyn Any>>,
 }
 
 impl<T: Unpin> Mocker<T> {
+    #[allow(clippy::type_complexity)]
     pub fn mock(
         mock: Box<dyn FnMut(Box<dyn Any>, &mut Context<Mocker<T>>) -> Box<dyn Any>>,
     ) -> Mocker<T> {
diff --git a/src/actors/resolver.rs b/src/actors/resolver.rs
index cf22a81ec..a6c6cadfa 100644
--- a/src/actors/resolver.rs
+++ b/src/actors/resolver.rs
@@ -387,6 +387,7 @@ impl ActorFuture for ResolveFut {
 }
 
 /// A TCP stream connector.
+#[allow(clippy::type_complexity)]
 pub struct TcpConnector {
     addrs: VecDeque<SocketAddr>,
     timeout: Delay,
diff --git a/src/contextitems.rs b/src/contextitems.rs
index 72754926a..89f6a2efd 100644
--- a/src/contextitems.rs
+++ b/src/contextitems.rs
@@ -97,7 +97,7 @@ where
         task: &mut task::Context<'_>,
     ) -> Poll<Self::Output> {
         let this = self.get_mut();
-        let _ = ready!(Pin::new(&mut this.timeout).poll(task));
+        ready!(Pin::new(&mut this.timeout).poll(task));
         let fut = A::handle(act, this.msg.take().unwrap(), ctx);
         fut.handle::<()>(ctx, None);
         Poll::Ready(())
diff --git a/src/fut/timeout.rs b/src/fut/timeout.rs
index 08b0fc8ab..ca0735381 100644
--- a/src/fut/timeout.rs
+++ b/src/fut/timeout.rs
@@ -51,10 +51,10 @@ where
     ) -> Poll<Self::Output> {
         let this = self.project();
 
-        match this.timeout.poll(task) {
-            Poll::Ready(_) => return Poll::Ready(Err(())),
-            _ => {}
+        if let Poll::Ready(_) = this.timeout.poll(task) {
+            return Poll::Ready(Err(()))
         }
+
         this.fut.poll(act, ctx, task).map(Ok)
     }
 }
diff --git a/src/io.rs b/src/io.rs
index 995ed6f89..f9ab53efd 100644
--- a/src/io.rs
+++ b/src/io.rs
@@ -452,9 +452,8 @@ impl<I: 'static, S: Sink<I> + Unpin + 'static> SinkWrite<I, S> {
     /// Sends an item to the sink.
     pub fn write(&mut self, item: I) -> Result<(), S::Error> {
         let res = Pin::new(&mut self.inner.borrow_mut().sink).start_send(item);
-        match res {
-            Ok(()) => self.notify_task(),
-            Err(_) => {}
+        if let Ok(()) = res {
+            self.notify_task()
         }
         res
     }
diff --git a/src/lib.rs b/src/lib.rs
index 132ddb2ea..10a67f6c3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -40,6 +40,9 @@
 //! in `current_thread`
 //! - `Stdin`, `Stderr` and `Stdout` from `tokio::io` are the same as file I/O in that regard and
 //! cannot be used in asynchronous manner in actix.
+// It's pain for this crate and has false positives.
+#![allow(clippy::needless_doctest_main)]
+
 #[doc(hidden)]
 pub use actix_derive::*;
 
@@ -180,6 +183,7 @@ pub mod dev {
 /// # Panics
 ///
 /// This function panics if the actix system is already running.
+#[allow(clippy::unit_arg)]
 pub fn run<R>(f: R) -> std::io::Result<()>
 where
     R: futures::Future<Output = ()> + 'static,


Test patch:
diff --git a/tests/derive.rs b/tests/derive.rs
index 3b99c78ad..9eeb1b7f7 100644
--- a/tests/derive.rs
+++ b/tests/derive.rs
@@ -20,7 +20,7 @@ impl Handler<Empty> for EmptyActor {
 }
 
 #[test]
-#[cfg_attr(feature = "cargo-clippy", allow(unit_cmp))]
+#[allow(clippy::unit_cmp)]
 fn response_derive_empty() {
     System::run(|| {
         let addr = EmptyActor.start();
diff --git a/tests/test_address.rs b/tests/test_address.rs
index bf30d6610..ec855b8f9 100644
--- a/tests/test_address.rs
+++ b/tests/test_address.rs
@@ -287,7 +287,7 @@ fn test_recipient_eq() {
     System::run(move || {
         let addr0 = MyActor(count0).start();
         let recipient01 = addr0.clone().recipient::<Ping>();
-        let recipient02 = addr0.clone().recipient::<Ping>();
+        let recipient02 = addr0.recipient::<Ping>();
 
         assert!(recipient01 == recipient02);
 
@@ -295,7 +295,7 @@ fn test_recipient_eq() {
         assert!(recipient01 == recipient03);
 
         let addr1 = MyActor(count1).start();
-        let recipient11 = addr1.clone().recipient::<Ping>();
+        let recipient11 = addr1.recipient::<Ping>();
 
         assert!(recipient01 != recipient11);
 
@@ -312,7 +312,7 @@ fn test_recipient_hash() {
     System::run(move || {
         let addr0 = MyActor(count0).start();
         let recipient01 = addr0.clone().recipient::<Ping>();
-        let recipient02 = addr0.clone().recipient::<Ping>();
+        let recipient02 = addr0.recipient::<Ping>();
 
         let mut recipients = HashSet::new();
         recipients.insert(recipient01.clone());
@@ -323,7 +323,7 @@ fn test_recipient_hash() {
         assert!(recipients.contains(&recipient02));
 
         let addr1 = MyActor(count1).start();
-        let recipient11 = addr1.clone().recipient::<Ping>();
+        let recipient11 = addr1.recipient::<Ping>();
         recipients.insert(recipient11.clone());
 
         assert_eq!(recipients.len(), 2);
diff --git a/tests/test_context.rs b/tests/test_context.rs
index 28939f394..227275c6a 100644
--- a/tests/test_context.rs
+++ b/tests/test_context.rs
@@ -1,4 +1,4 @@
-#![cfg_attr(feature = "cargo-clippy", allow(let_unit_value))]
+#![allow(clippy::let_unit_value)]
 use std::sync::atomic::{AtomicUsize, Ordering};
 use std::sync::Arc;
 
diff --git a/tests/test_fut.rs b/tests/test_fut.rs
index 13f0ab16a..9f32b2510 100644
--- a/tests/test_fut.rs
+++ b/tests/test_fut.rs
@@ -58,12 +58,9 @@ impl Actor for MyStreamActor {
 
         s.into_actor(self)
             .timeout(Duration::new(0, 1000))
-            .map(|e, act, _| match e {
-                Err(()) => {
-                    act.timeout.store(true, Ordering::Relaxed);
-                    System::current().stop();
-                }
-                Ok(_) => (),
+            .map(|e, act, _| if let Err(()) = e {
+                act.timeout.store(true, Ordering::Relaxed);
+                System::current().stop();
             })
             .finish()
             .wait(ctx)
diff --git a/tests/test_lifecycle.rs b/tests/test_lifecycle.rs
index f890d8e1d..16d971de8 100644
--- a/tests/test_lifecycle.rs
+++ b/tests/test_lifecycle.rs
@@ -1,4 +1,4 @@
-#![cfg_attr(feature = "cargo-clippy", allow(let_unit_value))]
+#![allow(clippy::let_unit_value)]
 
 use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::{Arc, Mutex};
diff --git a/tests/test_sink.rs b/tests/test_sink.rs
index 3c07f7a82..7a8b4816b 100644
--- a/tests/test_sink.rs
+++ b/tests/test_sink.rs
@@ -37,7 +37,7 @@ impl Sink<Bytes> for MySink {
 
             this.sender.unbounded_send(bytes[0]).unwrap();
             bytes.advance(1);
-            if bytes.len() == 0 {
+            if bytes.is_empty() {
                 this.queue.remove(0);
             }
         }
diff --git a/tests/test_sync.rs b/tests/test_sync.rs
index 9299f5704..9ba023dda 100644
--- a/tests/test_sync.rs
+++ b/tests/test_sync.rs
@@ -58,7 +58,7 @@ impl Handler<Fibonacci> for SyncActor {
 }
 
 #[test]
-#[cfg_attr(feature = "cargo-clippy", allow(mutex_atomic))]
+#[allow(clippy::mutex_atomic)]
 fn test_sync() {
     let l = Arc::new(Mutex::new(false));
     let cond = Arc::new(Condvar::new());