diff --git a/.gitattributes b/.gitattributes
index 6f64db3..d7b3be5 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,7 +1,7 @@
 .gitattributes export-ignore
+.github/ export-ignore
 .gitignore export-ignore
 .scrutinizer.yml export-ignore
-.travis.yml export-ignore
 composer.json export-ignore
 phpmd.xml export-ignore
 phpunit.xml.dist export-ignore
diff --git a/.github/workflows/ci_failure_email.md.tmpl b/.github/workflows/ci_failure_email.md.tmpl
new file mode 100644
index 0000000..322186b
--- /dev/null
+++ b/.github/workflows/ci_failure_email.md.tmpl
@@ -0,0 +1,3 @@
+CI workflow ${WORKFLOW} failed!
+
+The failed job can be found in [here](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID}).
diff --git a/.github/workflows/lint-and-test.yaml b/.github/workflows/lint-and-test.yaml
new file mode 100644
index 0000000..22debee
--- /dev/null
+++ b/.github/workflows/lint-and-test.yaml
@@ -0,0 +1,51 @@
+
+name: Lint and Test
+on: push
+permissions:
+    contents: read
+jobs:
+    build:
+        runs-on: ubuntu-latest
+        strategy:
+            matrix:
+                php_version: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ]
+        steps:
+            - uses: actions/checkout@v4
+            - name: Setup PHP
+              uses: shivammathur/setup-php@v2
+              with:
+                  php-version: ${{ matrix.php_version }}
+            - uses: nowactions/envsubst@v1
+              with:
+                  input: ${{ github.workspace }}/.github/workflows/ci_failure_email.md.tmpl
+                  output: ${{ github.workspace }}/.github/workflows/ci_failure_email.md
+              env:
+                  WORKFLOW: ${{ github.workflow }}
+                  SERVER_URL: ${{ github.server_url }}
+                  REPOSITORY: ${{ github.repository }}
+                  RUN_ID: ${{ github.run_id }}
+            - name: Validate composer.json and composer.lock
+              run: composer validate --strict
+            - name: Cache Composer packages
+              id: composer-cache
+              uses: actions/cache@v3
+              with:
+                  path: vendor
+                  key: ${{ runner.os }}-php-${{ matrix.php_version}}-${{ hashFiles('**/composer.lock') }}
+            - name: Install dependencies
+              run: composer install --prefer-source --no-progress
+            - name: Run test suite
+              run: composer ci
+            - name: Send mail on failure
+              if: ${{ failure() }}
+              uses: dawidd6/action-send-mail@v3
+              with:
+                  server_address: smtp.gmail.com
+                  server_port: 465
+                  username: ${{secrets.CI_MAIL_USERNAME}}
+                  password: ${{secrets.CI_MAIL_PASSWORD}}
+                  to: wikidata-ci-status@wikimedia.de
+                  from: ${{ github.repository }} CI
+                  subject: CI job failed for ${{ github.repository }}
+                  convert_markdown: true
+                  html_body: file://${{ github.workspace }}/.github/workflows/ci_failure_email.md
diff --git a/.github/workflows/scrutinize.yaml b/.github/workflows/scrutinize.yaml
new file mode 100644
index 0000000..363ba58
--- /dev/null
+++ b/.github/workflows/scrutinize.yaml
@@ -0,0 +1,31 @@
+name: Generate and upload test coverage
+on:
+    workflow_run:
+        workflows: ['Lint and Test']
+        types:
+            - completed
+
+jobs:
+    scrutinize:
+        runs-on: ubuntu-latest
+        if: ${{ github.event.workflow_run.conclusion == 'success' }}
+        steps:
+            - uses: actions/checkout@v4
+              with:
+                  fetch-depth: 2
+            - name: Setup PHP
+              uses: shivammathur/setup-php@v2
+              with:
+                  php-version: '8.0'
+                  coverage: xdebug
+            - name: Cache Composer packages
+              uses: actions/cache@v4
+              with:
+                  path: vendor
+                  key: ${{ runner.os }}-${{ hashFiles('**/composer.lock') }}
+            - name: Generate PHP tests coverage
+              run:  vendor/bin/phpunit --coverage-clover coverage.clover
+            - name: Upload Scrutinizer coverage
+              uses: sudo-bot/action-scrutinizer@latest
+              with:
+                  cli-args: "--repository g/wmde/WikibaseInternalSerialization --format=php-clover ./coverage.clover"
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index d5a4ba5..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-language: php
-
-dist: xenial
-
-matrix:
-  fast_finish: true
-  include:
-    - php: 7.2
-    - php: 7.3
-    - php: 7.4
-    - php: 8.0
-
-sudo: false
-
-install: travis_retry composer install
-
-script: composer ci
-
-after_success:
-  - if [[ "`phpenv version-name`" != "8.0" ]]; then exit 0; fi
-  - vendor/bin/phpunit --coverage-clover coverage.clover
-  - wget https://scrutinizer-ci.com/ocular.phar
-  - php ocular.phar code-coverage:upload --format=php-clover coverage.clover
-
-notifications:
-  irc:
-    channels:
-      - "irc.libera.chat#wikidata-feed"
-    on_success: change
-    on_failure: always
-    template:
-      - "%{repository}/%{branch}/%{commit} : %{author} %{message} %{build_url}"
-
-cache:
-  directories:
-    - $HOME/.composer/cache
diff --git a/README.md b/README.md
index af1b739..61aa3b5 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
 
 Library containing serializers and deserializers for the data access layer of [Wikibase](http://wikiba.se/) Repository.
 
-[![Build Status](https://secure.travis-ci.org/wmde/WikibaseInternalSerialization.png?branch=master)](http://travis-ci.org/wmde/WikibaseInternalSerialization)
+[![Build Status](https://github.com/wmde/WikibaseInternalSerialization/actions/workflows/lint-and-test.yaml/badge.svg?branch=master)](https://github.com/wmde/WikibaseInternalSerialization/actions/workflows/lint-and-test.yaml)
 [![Code Coverage](https://scrutinizer-ci.com/g/wmde/WikibaseInternalSerialization/badges/coverage.png?s=b65f644a99b93ed3aa1a34e45efbccad798d168c)](https://scrutinizer-ci.com/g/wmde/WikibaseInternalSerialization/)
 [![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/wmde/WikibaseInternalSerialization/badges/quality-score.png?s=1cd66e5c545917f947b4b838b7bfdeee9105843e)](https://scrutinizer-ci.com/g/wmde/WikibaseInternalSerialization/)
 
@@ -106,7 +106,6 @@ Wikibase Internal Serialization has been written by
 ## Links
 
 * [Wikibase Internal Serialization on Packagist](https://packagist.org/packages/wikibase/internal-serialization)
-* [Wikibase Internal Serialization on TravisCI](https://travis-ci.org/wmde/WikibaseInternalSerialization)
 * [Wikibase Internal Serialization on ScrutinizerCI](https://scrutinizer-ci.com/g/wmde/WikibaseInternalSerialization/)
 * [Wikibase Internal Serialization on OpenHub](https://www.openhub.net/p/WikibaseInternalSerialization)