diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 000000000..3571ed27d
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,113 @@
+name: CI
+
+on:
+  push:
+    branches: [master]
+  pull_request:
+    branches: [master]
+
+jobs:
+  setup:
+    runs-on: ubuntu-latest
+    steps:
+      - name: checkout
+        uses: actions/checkout@master
+
+      - uses: actions/setup-node@v1
+        with:
+          node-version: '12'
+
+      - name: cache package-lock.json
+        uses: actions/cache@v2
+        with:
+          path: package-temp-dir
+          key: lock-${{ github.sha }}
+
+      - name: create package-lock.json
+        run: npm i --package-lock-only
+
+      - name: hack for singe file
+        run: |
+          if [ ! -d "package-temp-dir" ]; then
+            mkdir package-temp-dir
+          fi
+          cp package-lock.json package-temp-dir
+      - name: cache node_modules
+        id: node_modules_cache_id
+        uses: actions/cache@v2
+        with:
+          path: node_modules
+          key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
+
+      - name: install
+        if: steps.node_modules_cache_id.outputs.cache-hit != 'true'
+        run: npm ci
+
+  lint:
+    runs-on: ubuntu-latest
+    steps:
+      - name: checkout
+        uses: actions/checkout@master
+
+      - name: restore cache from package-lock.json
+        uses: actions/cache@v2
+        with:
+          path: package-temp-dir
+          key: lock-${{ github.sha }}
+
+      - name: restore cache from node_modules
+        uses: actions/cache@v2
+        with:
+          path: node_modules
+          key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
+
+      - name: lint
+        run: npm run lint
+
+    needs: setup
+
+  compile:
+    runs-on: ubuntu-latest
+    steps:
+      - name: checkout
+        uses: actions/checkout@master
+
+      - name: restore cache from package-lock.json
+        uses: actions/cache@v2
+        with:
+          path: package-temp-dir
+          key: lock-${{ github.sha }}
+
+      - name: restore cache from node_modules
+        uses: actions/cache@v2
+        with:
+          path: node_modules
+          key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
+
+      - name: compile
+        run: npm run compile
+
+    needs: setup
+
+  coverage:
+    runs-on: ubuntu-latest
+    steps:
+      - name: checkout
+        uses: actions/checkout@master
+
+      - name: restore cache from package-lock.json
+        uses: actions/cache@v2
+        with:
+          path: package-temp-dir
+          key: lock-${{ github.sha }}
+
+      - name: restore cache from node_modules
+        uses: actions/cache@v2
+        with:
+          path: node_modules
+          key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }}
+
+      - name: coverage
+        run: npm test -- --coverage && bash <(curl -s https://codecov.io/bash)
+
+    needs: setup
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index dd8a4fc66..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-language: node_js
-
-node_js:
-  - 10
-
-script:
-  - |
-    if [ "$TEST_TYPE" = test ]; then
-      npm test -- --coverage && \
-      bash <(curl -s https://codecov.io/bash)
-    else
-      npm run $TEST_TYPE
-    fi
-env:
-  matrix:
-    - TEST_TYPE=lint
-    - TEST_TYPE=test
-    - TEST_TYPE=compile
diff --git a/README.md b/README.md
index 8d4e87aec..6f577d0c5 100644
--- a/README.md
+++ b/README.md
@@ -2,12 +2,18 @@
 
 React table component with useful functions.
 
-[![NPM version][npm-image]][npm-url] [![build status][travis-image]][travis-url] [![Test coverage][codecov-image]][codecov-url] [![Dependencies][david-image]][david-url] [![DevDependencies][david-dev-image]][david-dev-url] [![npm download][download-image]][download-url] [![bundle size][bundlephobia-image]][bundlephobia-url]
+[![NPM version][npm-image]][npm-url]
+[![build status][github-actions-image]][github-actions-url]
+[![Test coverage][codecov-image]][codecov-url]
+[![Dependencies][david-image]][david-url]
+[![DevDependencies][david-dev-image]][david-dev-url]
+[![npm download][download-image]][download-url]
+[![bundle size][bundlephobia-image]][bundlephobia-url]
 
 [npm-image]: http://img.shields.io/npm/v/rc-table.svg?style=flat-square
 [npm-url]: http://npmjs.org/package/rc-table
-[travis-image]: https://img.shields.io/travis/react-component/table.svg?style=flat-square
-[travis-url]: https://travis-ci.org/react-component/table
+[github-actions-image]: https://github.com/react-component/table/workflows/CI/badge.svg
+[github-actions-url]: https://github.com/react-component/table/actions
 [coveralls-image]: https://img.shields.io/coveralls/react-component/table.svg?style=flat-square
 [coveralls-url]: https://coveralls.io/r/react-component/table?branch=master
 [codecov-image]: https://img.shields.io/codecov/c/github/react-component/table/master.svg?style=flat-square
@@ -113,7 +119,7 @@ React.render(<Table columns={columns} data={data} />, mountNode);
 | emptyText | React.Node or Function | `No Data` | Display text when data is empty |
 | columns | Object[] |  | The columns config of table, see table below |
 | components | Object |  | Override table elements, see [#171](https://github.com/react-component/table/pull/171) for more details |
-| sticky | boolean \| {offsetHeader?: number, offsetScroll?: number, getContainer?: () => Window \| HTMLElement } |  false | stick header and scroll bar |
+| sticky | boolean \| {offsetHeader?: number, offsetScroll?: number, getContainer?: () => Window \| HTMLElement } | false | stick header and scroll bar |
 
 ## Column Props
 
diff --git a/src/Body/ExpandedRow.tsx b/src/Body/ExpandedRow.tsx
index 08c1a6fe2..ebdd753fa 100644
--- a/src/Body/ExpandedRow.tsx
+++ b/src/Body/ExpandedRow.tsx
@@ -3,7 +3,7 @@ import { CustomizeComponent } from '../interface';
 import Cell from '../Cell';
 import TableContext from '../context/TableContext';
 
-export interface ExpandedRowProps<RecordType> {
+export interface ExpandedRowProps {
   prefixCls: string;
   component: CustomizeComponent;
   cellComponent: CustomizeComponent;
@@ -17,7 +17,7 @@ export interface ExpandedRowProps<RecordType> {
   colSpan: number;
 }
 
-function ExpandedRow<RecordType>({
+function ExpandedRow({
   prefixCls,
   children,
   component: Component,
@@ -29,7 +29,7 @@ function ExpandedRow<RecordType>({
   expanded,
   componentWidth,
   colSpan,
-}: ExpandedRowProps<RecordType>) {
+}: ExpandedRowProps) {
   const { scrollbarSize } = React.useContext(TableContext);
 
   // Cache render node
diff --git a/src/Footer/index.tsx b/src/Footer/index.tsx
index 732ae5a0c..d6dd703ec 100644
--- a/src/Footer/index.tsx
+++ b/src/Footer/index.tsx
@@ -3,11 +3,11 @@ import TableContext from '../context/TableContext';
 import Cell from './Cell';
 import Row from './Row';
 
-export interface FooterProps<RecordType> {
+export interface FooterProps {
   children: React.ReactNode;
 }
 
-function Footer<RecordType>({ children }: FooterProps<RecordType>) {
+function Footer({ children }: FooterProps) {
   const { prefixCls } = React.useContext(TableContext);
   return <tfoot className={`${prefixCls}-summary`}>{children}</tfoot>;
 }
