Repository: slog-rs/slog (language: rust)

Issue:
travis-ci.org has shutdown
It looks like CI doesn't run anymore.
I don't see travis CI showing [in this PR for example ](https://github.com/slog-rs/slog/pull/290).
Furthermore tests are not even compiling with `--all-features`.


Discussion / hints:
Yeah, `travis-ci.org` has [shutdown](https://blog.travis-ci.com/2021-05-07-orgshutdown/). I *think* the new travis-ci.com is still free, but I believe most of the community has moved to Github Actions.

I'm going to switch over to using Github Actions.
Yes, it's still free, but now you get a set amount of free credits that you have to keep re-requesting. I wonder why people moved to GitHub Actions 🤔 🤔 🤔 .
.com is "free" insofar as you get 10000(?) "open-source credits", after providing your CC info. Then you pay. GHA is a good choice here.
https://docs.travis-ci.com/user/billing-overview/#free-trial-plan

https://docs.travis-ci.com/user/billing-faq/#what-if-i-am-building-open-source

Fix patch:
diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml
new file mode 100644
index 000000000..959cda03f
--- /dev/null
+++ b/.github/workflows/clippy.yml
@@ -0,0 +1,46 @@
+# This is the clippy workflow, seperate from the main 'Rust' workflow
+#
+# Right now it will always succed (should we change that?)
+on: [push, pull_request]
+name: Clippy
+
+env:
+  CARGO_TERM_COLOR: always
+  # has a history of occasional bugs (especially on old versions)
+  #
+  # the ci is free so we might as well use it ;)
+  CARGO_INCREMENTAL: 0
+
+
+jobs:
+  clippy:
+    # Only run on PRs if the source branch is on someone else's repo
+    if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
+    runs-on: ubuntu-latest
+    # Clippy is something that is nice to have, but it shoudldn't break the build
+    continue-on-error: true
+    strategy:
+      matrix:
+        rust:
+          - stable
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions-rs/toolchain@v1
+        with:
+          profile: minimal
+          toolchain: ${{ matrix.rust }}
+          override: true
+          components: clippy
+      - shell: bash
+        run: |
+          # By default, GH actions runs `set -e` to make bash immediately exit
+          # if any command has an error.
+          #
+          # However, we want this check to always "succeed", just give a warning on error.
+          #
+          # As a result we undo that setting by runing `set +e` (notice the plus)
+          set +e
+          cargo clippy
+          # Give a github warning if the command didn't succeed
+          if [[ $? -ne 0 ]]; then echo "::warning title=Clippy:: Oh no, clippy is sad :("; fi
+          true # Exit with success
diff --git a/.github/workflows/rustfmt.yml b/.github/workflows/rustfmt.yml
new file mode 100644
index 000000000..34f5552ff
--- /dev/null
+++ b/.github/workflows/rustfmt.yml
@@ -0,0 +1,39 @@
+# The file is the workflow for rustfmt
+#
+# It runs `cargo fmt --check`
+#
+# Right now it always succeeds. We should probably change this to enforce stricter formatting.
+on: [push, pull_request]
+name: rustfmt
+
+env:
+  CARGO_TERM_COLOR: always
+
+jobs:
+  rustfmt:
+    # Only run on PRs if the source branch is on someone else's repo
+    if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
+    runs-on: ubuntu-latest
+    # rustfmt is something that is nice to have, but it shoudldn't break the build
+    #
+    # TODO: Should we change this in the future to enforce stricter formatting?
+    continue-on-error: true
+    strategy:
+      matrix:
+        rust:
+          - stable
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions-rs/toolchain@v1
+        with:
+          profile: minimal
+          toolchain: ${{ matrix.rust }}
+          override: true
+          components: rustfmt
+      - shell: bash
+        run: |
+          set +e # See above
+          cargo fmt -- --check
+          # Give a github warning if the command didn't succeed
+          if [[ $? -ne 0 ]]; then echo "::warning title=rustfmt:: Formatting problems"; fi;
+          true # Exit with success
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 79ca28e8f..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-language: rust
-cache:
-  - cargo
-rust:
-  - stable
-  - 1.23.0
-  - beta
-  - nightly
-
-script:
-    # `patch` section is recent addition
-  - if [ "$TRAVIS_RUST_VERSION" != "1.23.0" ]; then make all ; fi
-  - if [ "$TRAVIS_RUST_VERSION" == "1.23.0" ]; then make build ; fi
-  - if [ "$TRAVIS_RUST_VERSION" != "1.23.0" ]; then make travistest ; fi
-  - if [ "$TRAVIS_RUST_VERSION" == "nightly" ]; then make bench ; fi
-  - if [ "$TRAVIS_RUST_VERSION" == "nightly" ]; then cargo build --no-default-features; cargo test --no-default-features; fi
-  - if [ "$TRAVIS_RUST_VERSION" == "nightly" ]; then cargo test -p test_edition2018; fi
-
-env:
-  global:
-    - RUST_BACKTRACE=1
-  matrix:
-    -
-    - RELEASE=true
-
-notifications:
-  webhooks:
-    urls:
-      - https://webhooks.gitter.im/e/87a331e1a21456b6e2ad
-    on_success: change  # options: [always|never|change] default: always
-    on_failure: change  # options: [always|never|change] default: always
-    on_start: false     # default: false
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 54ef66623..f0975696f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 
 ## Next
 
+* Switch from Travis CI to Github Actions (fixes #294)
 * Fix `#` format when not used as a last argument.
 * Implement `Value` for `std::borrow::Cow`
 
diff --git a/README.md b/README.md
index 0a5f59d76..2ac4a40e5 100644
--- a/README.md
+++ b/README.md
@@ -5,8 +5,8 @@
   </a>
   <br>
 
-  <a href="https://travis-ci.org/slog-rs/slog">
-      <img src="https://img.shields.io/travis/slog-rs/slog/master.svg" alt="Travis CI Build Status">
+  <a href="https://github.com/slog-rs/slog/actions/workflows/test.yml">
+      <img src="https://img.shields.io/github/workflow/status/slog-rs/slog/Cargo%20Test" alt="GH Actions (Cargo Test)">
   </a>
 
   <a href="https://crates.io/crates/slog">


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 000000000..ad3f2bd64
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,78 @@
+# We use `actions-rs` for most of our actions
+#
+# This file is for the main tests. clippy & rustfmt are seperate workflows
+on: [push, pull_request]
+name: Cargo Test
+
+env:
+  CARGO_TERM_COLOR: always
+  # has a history of occasional bugs (especially on old versions)
+  #
+  # the ci is free so we might as well use it ;)
+  CARGO_INCREMENTAL: 0
+
+
+# Tested versions:
+# 1. stable
+# 2. nightly
+# 3. Minimum Supported Rust Version (MSRV)
+# 4. 1.31
+#
+# A note on 1.23 & 1.31:
+# On 1.23 (our current minimum version), `cargo check --all-features` fails to compile the main crate
+# To be clear, not only do the tests fail to run, but `cargo check` fails to compile at all
+#
+# For this reason, we also test 1.31.
+# `cargo check --all-features` works on 1.31 and every version after that
+
+jobs:
+  test:
+    # Only run on PRs if the source branch is on someone else's repo
+    if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
+
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false # Even if one job fails we still want to see the other ones
+      matrix:
+        # Don't include 1.23 in the matrix because `cargo check --all-features` fails (see above)
+        rust: [1.31, stable, nightly]
+        # NOTE: Features to test must be specified manually. They are applied to all versions seperately.
+        #
+        # This has the advantage of being more flexibile and thorough
+        # This has the disadvantage of being more vebrose
+        #
+        # Specific feature combos can be overriden per-version with 'include' and 'ecclude'
+        features: ["", "nested-values dynamic-keys", "nested-values dynamic-keys nothreads"]
+        include:
+          # Manually include 1.23 (MSRV) and only compile it with default features
+          #
+          # This is because `cargo check --features nested-values` fails to compile on 1.23
+          - rust: 1.23
+            features:
+            required-success: true
+
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions-rs/toolchain@v1
+        with:
+          toolchain: ${{ matrix.rust }}
+          override: true
+      - name: Check
+        # A failing `cargo check` always ends the build
+        run: |
+          cargo check --verbose --features "${{ matrix.features }}"
+        # A failing `cargo check` always fails the build
+        continue-on-error: false
+      - name: Test
+        run: |
+          cargo test --verbose --features "${{ matrix.features }}"
+
+        # By default, we require tests to succeed if either
+        # 1. It has default features (`features == ""`)
+        #
+        # Otherwise, we allow tests to fail.
+        #
+        # This is necessary because most feature combos currently break the tests :(
+        #
+        # TODO: Add some sort of option to get around this (or fix the build)
+        continue-on-error: ${{ matrix.features == '' }}