diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..fbef8ed64e9d898ab9047ff056e114ee464b9068
--- /dev/null
+++ b/.github/workflows/ci.yaml
@@ -0,0 +1,58 @@
+name: ci
+on:
+  - push
+  - pull_request
+env:
+  golang-version: '1.13'
+  kind-version: 'v0.9.0'
+jobs:
+  generate:
+    runs-on: ${{ matrix.os }}
+    strategy:
+      matrix:
+        os:
+          - macos-latest
+          - ubuntu-latest
+    name: Generate
+    steps:
+    - uses: actions/checkout@v2
+    - uses: actions/setup-go@v2
+      with:
+        go-version: ${{ env.golang-version }}
+    - run: make --always-make generate && git diff --exit-code
+  unit-tests:
+    runs-on: ubuntu-latest
+    name: Unit tests
+    steps:
+    - uses: actions/checkout@v2
+    - run: make --always-make test
+  e2e-tests:
+    name: E2E tests
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        kind-image:
+          - 'kindest/node:v1.19.0'
+    steps:
+    - uses: actions/checkout@v2
+    - name: Start KinD
+      uses: engineerd/setup-kind@v0.4.0
+      with:
+        version: ${{ env.kind-version }}
+        image: ${{ matrix.kind-image }}
+    - name: Wait for cluster to finish bootstraping
+      run: |
+        until [ "$(kubectl get pods --all-namespaces --no-headers | grep -cEv '([0-9]+)/\1')" -eq 0 ]; do
+            sleep 5s
+        done
+        kubectl cluster-info
+        kubectl get pods -A
+    - name: Create kube-prometheus stack
+      run: |
+        kubectl create -f manifests/setup
+        until kubectl get servicemonitors --all-namespaces ; do date; sleep 1; echo ""; done
+        kubectl create -f manifests/
+    - name: Run tests
+      run: |
+        export KUBECONFIG="${HOME}/.kube/config"
+        make test-e2e
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 4750d3efb18cb02ec5152b2a057803e619eb6bfd..0000000000000000000000000000000000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-sudo: required
-dist: xenial
-language: go
-
-go:
-- "1.13.x"
-go_import_path: github.com/prometheus-operator/kube-prometheus
-
-cache:
-  directories:
-  - $GOCACHE
-  - $GOPATH/pkg/mod
-
-jobs:
-  include:
-  - name: Check generated files
-    script: make --always-make generate && git diff --exit-code
-  - name: Run tests
-    script: make --always-make test
-  - name: Run e2e tests
-    script: ./tests/e2e/travis-e2e.sh
-    env: K8S_VERSION=1.19.0
diff --git a/tests/e2e/travis-e2e.sh b/tests/e2e/travis-e2e.sh
deleted file mode 100755
index 2ead7c2faf9063c6d21b19f329d7158d92edd179..0000000000000000000000000000000000000000
--- a/tests/e2e/travis-e2e.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env bash
-# exit immediately when a command fails
-set -e
-# only exit with zero if all commands of the pipeline exit successfully
-set -o pipefail
-# error on unset variables
-set -u
-# print each command before executing it
-set -x
-
-K8S_VERSION="${K8S_VERSION:-"1.19.1"}"
-
-curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
-chmod +x kubectl
-curl -Lo kind https://github.com/kubernetes-sigs/kind/releases/download/v0.9.0/kind-linux-amd64
-chmod +x kind
-
-./kind create cluster --image="kindest/node:v${K8S_VERSION}"
-# the default kube config location used by kind
-export KUBECONFIG="${HOME}/.kube/config"
-
-# create namespace, permissions, and CRDs
-./kubectl create -f manifests/setup
-
-# wait for CRD creation to complete
-until ./kubectl get servicemonitors --all-namespaces ; do date; sleep 1; echo ""; done
-
-# create monitoring components
-./kubectl create -f manifests/
-
-make test-e2e