Repository: Becksteinlab/MDPOW (language: python)

Issue:
transition from Travis CI to GitHub actions
Use the free GitHub actions.

**Important** because we ran out of Travis credits.
mixed solvents are only support with Gromacs 2018 and higher versions
Based on the tests on our local workstation, Gromacs with version 2018.6 _or higher_ support mixed molecule solvent. And the solvation process in MDPOW which modifies the topology file would make the `top` file mismatch the `gro` file generated after solvation.

Maybe we can use Gromacs preprocessor directives in the file and define a variable `MDPOWPREGMX2019` (As discussed in PR #103 )

```
DRUG               1
#ifdef MDPOWPREGMX2019
OcOH               1
#endif
```

And then add to to the MDP file:
```
define  = -DMDPOWPREGMX2019
```




Discussion / hints:

Current version supports GROMACS with version >2018, but doesn't support lower versions.
that's ok, we just have to document it and fail when we detect unsupported gmx
Is this why our Gromacs 4.6.5 tests fail?

Fix patch:
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
new file mode 100644
index 00000000..1ddf5a67
--- /dev/null
+++ b/.github/workflows/ci.yaml
@@ -0,0 +1,101 @@
+name: CI
+
+on:
+  # run once a day at 5:55 UTC
+  schedule:
+    - cron: "55 5 * * *"
+  push:
+    branches:
+      - "develop"
+      - "master"
+  pull_request:
+    branches:
+      - "develop"
+
+concurrency:
+  group: "${{ github.ref }}-${{ github.head_ref }}"
+  cancel-in-progress: true
+
+jobs:
+  test:
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ubuntu-latest, macOS-latest]
+        python-version: [2.7] 
+        #python-version: [2.7, 3.8] 
+        #python-version: [2.7, 3.6, 3.7, 3.8, 3.9]
+        gromacs-version: ["4.6.5", "2018.6", "2019.1", "2021.1"]
+        # only test one GROMACS version on macOS to keep the testing
+        # matrix manageable
+        exclude:
+          - os: macOS-latest
+            gromacs-version: "4.6.5"
+          - os: macOS-latest
+            gromacs-version: "2018.6"
+          - os: macOS-latest
+            gromacs-version: "2019.1"
+
+    env:
+      MPLBACKEND: agg
+        
+
+    steps:
+    - uses: actions/checkout@v2
+
+    - uses: conda-incubator/setup-miniconda@v2
+      with:
+        python-version: ${{ matrix.python-version }}      
+        auto-update-conda: true
+        mamba-version: "*"
+        channels: conda-forge,bioconda,defaults
+        channel-priority: true
+        show-channel-urls: true
+          
+    - name: Conda info
+      shell: bash -l {0}
+      run: |
+         conda info
+         conda list
+         conda config --show-sources
+         conda config --show
+
+    - name: Python version
+      shell: bash -l {0}
+      run: |
+         python -c "import sys; print(sys.version)"                
+
+    - name: Install package dependencies
+      shell: bash -l {0}
+      run: |
+         mamba install six numpy scipy matplotlib pandas scikit-learn pyyaml mdanalysis numexpr
+         python -m pip install --no-deps numkit gromacswrapper
+         python -m pip install alchemlyb
+
+    - name: Install pytest+plugins and pybol
+      shell: bash -l {0}
+      run: |
+         mamba install pytest pytest-pep8 pytest-cov codecov
+         python -m pip install pybol
+
+    - name: Install GROMACS (${{ matrix.gromacs-version }})
+      shell: bash -l {0}
+      run: |
+         mamba install 'gromacs==${{ matrix.gromacs-version }}' pocl
+
+    - name: Install package
+      shell: bash -l {0}
+      run: |
+        python -m pip install --no-deps .
+
+    - name: Run tests
+      shell: bash -l {0}
+      run: |
+        pytest -v --durations=20 --cov=mdpow --cov-report=xml ./mdpow/tests
+
+    - name: Codecov
+      uses: codecov/codecov-action@v1
+      with:
+        file: ./coverage.xml
+        fail_ci_if_error: true
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 60a9b884..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,60 +0,0 @@
-language: generic
-sudo: false
-
-# whitelist
-branches:
-    only:
-        - master
-        - develop
-        - testing-gromacs-5-travis
-
-env:
-  global:
-    - PYTHON_VERSION=2.7
-    - CODECOV=true
-    - PYTEST_FLAGS="-v --cov=mdpow"
-    - PYTEST_LIST="mdpow/tests"
-    - MAIN_CMD="pytest ${PYTEST_LIST}"
-    - SETUP_CMD="${PYTEST_FLAGS}"
-    - BUILD_CMD="pip install -v ."
-    - CONDA_DEPENDENCIES="six matplotlib pandas gromacs"
-    # Gromacs 2018 packages from bioconda require conda-forge for
-    # dependency, see https://bioconda.github.io/#set-up-channels
-    - CONDA_CHANNELS="defaults conda-forge bioconda"
-    - CONDA_CHANNEL_PRIORITY=True
-    - PIP_DEPENDENCIES="numkit codecov pybol"
-    - NUMPY_VERSION=stable
-    - MPLBACKEND=agg
-
-  matrix:
-    # use ci-helper's PACKAGENAME_VERSION magic to pin the 'gromacs' package
-    - GROMACS_VERSION=4.6.5   PYTHON_VERSION=2.7
-    - GROMACS_VERSION=2019.1  PYTHON_VERSION=2.7
-      SETUP_CMD="${SETUP_CMD}"
-
-
-matrix:
-  fast_finish: true
-
-  include:
-    # see Gromacs packages on bioconda https://anaconda.org/bioconda/gromacs/files
-    - os: osx
-      env: GROMACS_VERSION=2019.1 PYTHON_VERSION=2.7
-
-
-install:
-  - git clone --depth 1 git://github.com/astropy/ci-helpers.git
-  - source ci-helpers/travis/setup_conda.sh
-  - eval $BUILD_CMD
-
-script:
-  - cd ${TRAVIS_BUILD_DIR}
-  - if [[ $TRAVIS_OS_NAME == 'osx' ]]; then ulimit -S -n 2048; fi
-  - echo $MAIN_CMD $SETUP_CMD
-  - eval $MAIN_CMD $SETUP_CMD
-
-after_success:
-  - |
-    if [[ $CODECOV == 'true' ]]; then \
-      codecov; \
-    fi
diff --git a/README.rst b/README.rst
index c5db41a0..43990476 100644
--- a/README.rst
+++ b/README.rst
@@ -81,9 +81,9 @@ Footnotes
 .. [#GromacsWrapperNote] The package is built on top of the GromacsWrapper_
                          framework (which is automatically installed).
 
-.. |build| image:: https://travis-ci.org/Becksteinlab/MDPOW.svg?branch=develop
+.. |build| image:: https://github.com/Becksteinlab/MDPOW/actions/workflows/ci.yaml/badge.svg?branch=develop
    :alt: Build Status
-   :target: https://travis-ci.org/Becksteinlab/MDPOW
+   :target: https://github.com/Becksteinlab/MDPOW/actions/workflows/ci.yaml
 
 .. |cov| image:: https://codecov.io/github/Becksteinlab/MDPOW/coverage.svg?branch=develop
    :alt: Coverage Status
diff --git a/mdpow/forcefields.py b/mdpow/forcefields.py
index 339d229a..c0a570b2 100644
--- a/mdpow/forcefields.py
+++ b/mdpow/forcefields.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 # POW package __init__.py
 # Copyright (c) 2012 Oliver Beckstein <orbeckst@gmail.com>
 # Released under the GNU Public License 3 (or higher, your choice)
@@ -146,7 +147,7 @@ def get_water_model(watermodel=DEFAULT_WATER_MODEL):
 
 #: Other solvents (not water, see :data:`GROMACS_WATER_MODELS` for those).
 new_octanol = '''Zangi R (2018) Refinement of the OPLSAA force-field
-                for liquid alcohols.; ACS Omega 3(12):18089–18099.
+                for liquid alcohols.; ACS Omega 3(12):18089-18099.
                 doi: 10.1021/acsomega.8b03132'''
 
 OPLS_SOLVENT_MODELS = {


Test patch:
diff --git a/mdpow/tests/test_runinput.py b/mdpow/tests/test_runinput.py
index 39e00f30..a9dca87d 100644
--- a/mdpow/tests/test_runinput.py
+++ b/mdpow/tests/test_runinput.py
@@ -79,7 +79,7 @@ class TestAlteredConfig(object):
             'stepout': 12000,
             'verbose': False,
             'nice': 12,
-            'maxthreads': 3
+            'maxthreads': 1
             }
     }
 
diff --git a/mdpow/tests/test_solvation.py b/mdpow/tests/test_solvation.py
index 8060486c..e4d4da8f 100644
--- a/mdpow/tests/test_solvation.py
+++ b/mdpow/tests/test_solvation.py
@@ -52,7 +52,11 @@ def test_solvation_octanol(setup, ff):
 def test_solvation_cyclohexane(setup):
     solvation(setup, "cyclohexane")
 
-@pytest.mark.xfail("gromacs.release().startswith('2019')")
+@pytest.mark.xfail(gromacs.release.startswith('4')
+                   or gromacs.release.startswith('5')
+                   or gromacs.release.startswith('2016'),
+                   reason="GROMACS < 2018 cannot easily work with mixed solvents "
+                   "(see issue #111)")
 @pytest.mark.parametrize("ff", ['OPLS-AA', 'CHARMM', 'AMBER'])
 def test_solvation_wetoctanol(setup, ff):
     solvation(setup, "wetoctanol", ff)
diff --git a/mdpow/tests/testing_resources/states/base/runinput.yml b/mdpow/tests/testing_resources/states/base/runinput.yml
index 32f179ca..dec9e83f 100644
--- a/mdpow/tests/testing_resources/states/base/runinput.yml
+++ b/mdpow/tests/testing_resources/states/base/runinput.yml
@@ -119,8 +119,6 @@ mdrun:
          # report progress verbosely (True is -v)
     nice: 19
          # nicel level
-    maxthreads: 3
+    maxthreads: None
          # maximum number of threads (-nt), 0 or None lets mdrun
          # automatically choose
-         # For testing on travis, needs to be either 3 or 1.
-         # See https://github.com/Becksteinlab/MDPOW/pull/77
diff --git a/mdpow/tests/testing_resources/states/md_npt/runinput.yml b/mdpow/tests/testing_resources/states/md_npt/runinput.yml
index e8827876..08b5869d 100644
--- a/mdpow/tests/testing_resources/states/md_npt/runinput.yml
+++ b/mdpow/tests/testing_resources/states/md_npt/runinput.yml
@@ -119,8 +119,7 @@ mdrun:
          # report progress verbosely (True is -v)
     nice: 19
          # nicel level
-    maxthreads: 3
+    maxthreads: None
          # maximum number of threads (-nt), 0 or None lets mdrun
          # automatically choose
-         # For testing on travis, needs to be either 3 or 1.
-         # See https://github.com/Becksteinlab/MDPOW/pull/77
+
diff --git a/mdpow/tests/testing_resources/test_configurations/altered_runinput.yml b/mdpow/tests/testing_resources/test_configurations/altered_runinput.yml
index 47710fe3..89f4abbe 100644
--- a/mdpow/tests/testing_resources/test_configurations/altered_runinput.yml
+++ b/mdpow/tests/testing_resources/test_configurations/altered_runinput.yml
@@ -119,5 +119,5 @@ mdrun:
          # report progress verbosely (True is -v)
     nice: 12
          # nicel level
-    maxthreads: 3
+    maxthreads: 1
          # maximum number of threads (-nt), 0 or None lets mdrun automatically choose