Repository: UAlbertaALTLab/morphodict (language: python)

Issue:
Migrate CI to GitHub Actions
Travis-CI is getting _really_ slow, and the integration has broken to show statuses on our PRs. Perhaps we should attempt running the tests on ~~Travis-CI~~ GitHub Actions?


Discussion / hints:
Do you mean running tests on GitHub Actions instead?

I use GH Actions for all my projects now. Such a good user experience, great documentation, easy to set up.
Yes! Haha, messed up the comment. I think migrating the tests may be worthwhile...
Update: I migrated the unit tests, but the e2e tests with Cypress are proving to be a challenge. Particularly in spinning up a development server (Python + Django) and using the `wait-on` command to wait for the server to be up. I'm not sure what's wrong, but I deleted it in 58406025cc378298978365c2adb18ad4cffd0b8e

Fix patch:
diff --git a/.github/workflows/reformat.yml b/.github/workflows/reformat.yml
index 159d45e91..7c3f2e46c 100644
--- a/.github/workflows/reformat.yml
+++ b/.github/workflows/reformat.yml
@@ -1,7 +1,5 @@
-name: Reformats various files
-
-
-# Note: to skip both travis and github actions, add both [skip ci/travis] and [skip actions] to your commit message
+name: Reformats source files
+# write [skip reformat] to skip this workflow!
 
 on:
   push:
@@ -11,7 +9,7 @@ jobs:
   # NOTE: Do all jobs SEQUENTIALLY to avoid merges
 
   reformat-altlabel:
-    if: "! contains(toJSON(github.event.commits.*.message), '[skip actions]')"
+    if: "! contains(toJSON(github.event.commits.*.message), '[skip reformat]')"
     runs-on: ubuntu-latest
     steps:
     - uses: actions/checkout@v2
@@ -26,10 +24,9 @@ jobs:
     - name: Git Auto Commit
       uses: stefanzweifel/git-auto-commit-action@v4.3.0
       with:
-        commit_message: "🤖🧹 reformat crk.altlabel [skip travis]"
+        commit_message: "🤖🧹 reformat crk.altlabel [skip ci]"
 
   reformat-python:
-    if: "! contains(toJSON(github.event.commits.*.message), '[skip actions]')"
     runs-on: ubuntu-latest
     # Ensure this is run **sequentially**
     needs: reformat-altlabel
@@ -49,10 +46,9 @@ jobs:
     - name: Git Auto Commit
       uses: stefanzweifel/git-auto-commit-action@v4.3.0
       with:
-        commit_message: "🤖🧹 reformat Python files [skip travis]"
+        commit_message: "🤖🧹 reformat Python files [skip ci]"
 
   reformat-javascript:
-    if: "! contains(toJSON(github.event.commits.*.message), '[skip actions]')"
     runs-on: ubuntu-latest
     # Ensure this is run **sequentially**
     needs: reformat-python
@@ -71,4 +67,4 @@ jobs:
     - name: Git Auto Commit
       uses: stefanzweifel/git-auto-commit-action@v4.3.0
       with:
-        commit_message: "🤖🧹 reformat JavaScript files [skip travis]"
+        commit_message: "🤖🧹 reformat JavaScript files [skip ci]"
diff --git a/.github/workflows/update_fst.yml b/.github/workflows/update_fst.yml
index 0019a91eb..eb8e40039 100644
--- a/.github/workflows/update_fst.yml
+++ b/.github/workflows/update_fst.yml
@@ -1,12 +1,11 @@
 name: Update FST files
-
 on: repository_dispatch
 
-# Note: to skip both travis and github actions, add both [skip ci/travis] and [skip actions] to your commit message
+# TODO: this needs to be updated for the gielalt/lang-crk repo!
+# TODO: this should commit using the actions user!
 
 jobs:
   build:
-    if: "! contains(toJSON(github.event.commits.*.message), '[skip actions]')"
     runs-on: ubuntu-latest
 
     steps:
diff --git a/.gitignore b/.gitignore
index 670eae5ae..3f86a2f89 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,6 +18,7 @@ pip-delete-this-directory.txt
 .hypothesis/
 .pytest_cache/
 .mypy_cache/
+/coverage.xml
 
 # Django stuff
 DatabaseManager.log*
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 0866e5b5f..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,55 +0,0 @@
-os: linux
-dist: xenial
-language: python
-python: "3.6"
-
-# Note: this Travis feature might be deprecated in the future:
-# https://github.com/travis-ci/travis-yml/pull/121
-env:
-  global:
-    - DEBUG=True
-    - USE_TEST_DB=True
-
-addons:
-  apt:
-    packages:
-      # Ubuntu 16+ does not install this dependency by default, so we need to install it ourselves
-      - libgconf-2-4
-      - hfst
-
-cache:
-  pip: true
-  directories:
-    - $HOME/.cache
-    - node_modules # NPM packages
-
-stages:
-  - test
-  - name: deploy
-    if: branch = master && type = push
-
-jobs:
-  include:
-    - name: "Unit Tests"
-      install: pipenv install --dev
-      script: pipenv run test --cov=CreeDictionary
-      after_success: codecov
-
-    - name: "Integration Tests"
-      # turns out it's harder to configure python with language: node_js
-      # it's easier to configure node_js with language: python instead
-      install:
-        - pipenv install
-        - npm ci
-        - npm run build
-      script:
-        - npm run stop-only
-        - npm run test:ci
-
-    - stage: deploy
-      language: shell
-      # This is not redundant. You need a 'deploy' key IN ADDITION to the
-      # deploy stage :/
-      deploy:
-        provider: script
-        script: bash ./libexec/deploy-to-sapir
diff --git a/CreeDictionary/CreeDictionary/settings.py b/CreeDictionary/CreeDictionary/settings.py
index 5dec17056..b1d2c998a 100644
--- a/CreeDictionary/CreeDictionary/settings.py
+++ b/CreeDictionary/CreeDictionary/settings.py
@@ -39,7 +39,7 @@
 if RUNNING_ON_SAPIR:  # pragma: no cover
     assert not DEBUG
 
-# travis has CI equals True
+# GitHub Actions and other services set CI to `true`
 CI = to_boolean(os.environ.get("CI", False))
 
 # The Django debug toolbar is a great help when... you know... debugging Django,
diff --git a/README.md b/README.md
index c39037953..b54c69e4c 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,6 @@
 # Cree Intelligent Dictionary
 
 ![Test and deploy](https://github.com/UAlbertaALTLab/cree-intelligent-dictionary/workflows/Test%20and%20deploy/badge.svg)
-[![Build Status](https://travis-ci.org/UAlbertaALTLab/cree-intelligent-dictionary.svg?branch=master)](https://travis-ci.org/UAlbertaALTLab/cree-intelligent-dictionary)
 [![codecov](https://codecov.io/gh/UAlbertaALTLab/cree-intelligent-dictionary/branch/master/graph/badge.svg)](https://codecov.io/gh/UAlbertaALTLab/cree-intelligent-dictionary)
 [![cypress.io](https://img.shields.io/badge/cypress.io-view-blue)](https://dashboard.cypress.io/#/projects/8r2xra/runs)
 
diff --git a/docs/ci.md b/docs/ci.md
index 4afa5df01..0250f575c 100644
--- a/docs/ci.md
+++ b/docs/ci.md
@@ -8,17 +8,18 @@ We use continuous integration (CI) to test and check our code on every
 Serivces
 --------
 
- - TravisCI — runs unit and integration tests
+ - GitHub Actions
+   * runs unit and integration tests
+   * reformats reformats Python and JavaScript code on the default branch
  - codecov — measures and tracks code coverage
  - Cypress — stores test recordings
- - GitHub Actions — reformats Python and JavaScript code on the default branch
  - redeploy (proprietary) — pulls the latest code on the production server
 
 
 Cypress
 -------
 
-On TravisCI, the integration test run using this rule:
+On GitHub Actions, the integration test run using this rule:
 
     npm run test:ci
 
@@ -30,6 +31,7 @@ Which, in turn, does the following:
    tests
 
 `$CYPRESS_OPTS` is intended to be either empty or `--record`. If set to
-`--record`, it will upload recordings to the Cypress Dashboard. Note
-that **if there is no more room for recordings** on our Cypress plan, **the
-build will fail**.
+`--record --key SECRET_KEY`, it will upload recordings to the Cypress
+Dashboard. Note that **if there is no more room for recordings** on our
+Cypress plan, **the build will fail**. We're on Cypress's open-source
+plan, which should give us some extra space to deal with!
diff --git a/docs/production-on-sapir.md b/docs/production-on-sapir.md
index 2e854476f..b1e702ffb 100644
--- a/docs/production-on-sapir.md
+++ b/docs/production-on-sapir.md
@@ -10,7 +10,8 @@ production website here:
 
 ## Redeployment Script
 
-`.travis.yml` is configured so that, after a successful build on master,
+`.github/workflows/test-and-deploy.yml` is configured so that,
+after a successful build on master,
 Sapir will execute a script that updates and restarts the app. This is
 enabled by a tool `redeploy`, maintained by
 [Eddie](https://github.com/eddieantonio).
diff --git a/libexec/deploy-to-sapir b/libexec/deploy-to-sapir
deleted file mode 100644
index 47c861ae4..000000000
--- a/libexec/deploy-to-sapir
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-set -ex
-
-# When run within Travis-CI, this script deploys the Cree Dictionary to Sapir.
-URL=sapir.artsrn.ualberta.ca/redeploy/cree-dictionary
-TEMPFILE=/tmp/out.txt
-
-# shellcheck disable=SC2154
-openssl aes-256-cbc -K "$encrypted_49b37942e026_key" -iv "$encrypted_49b37942e026_iv" -in cree-dictionary.key.enc -out cree-dictionary.key -d
-http_code="$(curl --verbose -o "$TEMPFILE" -w '%{http_code}' -dsecret="$(cat cree-dictionary.key)" $URL)"
-cat "$TEMPFILE" 1>&2
-
-# Exit with an proper error code.
-[ "$http_code" -eq 200 ] || exit 22


Test patch:
diff --git a/.github/workflows/test-and-deploy.yml b/.github/workflows/test-and-deploy.yml
index a3fc9a480..5d664c2df 100644
--- a/.github/workflows/test-and-deploy.yml
+++ b/.github/workflows/test-and-deploy.yml
@@ -1,17 +1,18 @@
-# Based on: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
-
-# Note: to skip both travis and github actions, add both [skip ci/travis] and [skip actions] to your commit message
-
 name: Test and deploy
 on: [push]
+
 env:
+  # Version required to run itwêwina:
   ACTIONS_PYTHON_VERSION: 3.6
+  # Version required to run npm build:
   ACTIONS_NODE_VERSION: 12
-  # Currently available versions (2021-01-04) are:
+  # Version running on Sapir:
+  ACTIONS_OS_VERSION: ubuntu-16.04
+  # N.B.: Currently available versions (2021-01-04) are:
   #   - ubuntu-16.04
   #   - ubuntu-18.04 (@ubuntu-latest)
   #   - ubuntu-20.04 (soon-to-be @ubuntu-latest)
-  ACTIONS_OS_VERSION: ubuntu-16.04
+  # See: https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on
 
 jobs:
   # Skips tests if [skip ci] is present in the commit message
@@ -49,6 +50,7 @@ jobs:
       with:
         commit-filter: '[skip deploy]'
 
+  # Run Pytest unit tests
   unit-test:
     runs-on: ubuntu-16.04
 
@@ -74,8 +76,13 @@ jobs:
       env:
         DEBUG: "True"
         USE_TEST_DB: "True"
-      run: pipenv run test -v --cov=CreeDictionary
+      run: pipenv run test -v --cov=CreeDictionary --cov-report=xml
+    - name: 📤 Upload Codecov coverage report
+      uses: codecov/codecov-action@v1
+      with:
+        fail_ci_if_error: true
 
+  # Runs Cypress acceptance tests
   integration-test:
     runs-on: ubuntu-16.04
 
@@ -109,11 +116,13 @@ jobs:
       env:
         DEBUG: "True"
         USE_TEST_DB: "True"
+        # Enables uploading test runs to Cypress Dashboard:
+        CYPRESS_OPTS: "--record --key ${{ secrets.CYPRESS_RECORD_KEY }}"
       run: npm run test:ci
 
-# This syncs up API/schema.py to our @altlab/types package
-# If there is an update to the type output (index.ts), but the version number is untouched. This
-# will fail. Because developer needs to choose which version to bump.
+  # This syncs up API/schema.py to our @altlab/types package
+  # If there is an update to the type output (index.ts), but the version number is untouched. This
+  # will fail. Because developer needs to choose which version to bump.
   type-package-check:
     runs-on: ubuntu-20.04