name: Continuous integration

on:
  - push

jobs:
  getVersionNumber:
    name: Get version number
    if: startsWith(github.ref, 'refs/tags/')
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.get-version-number.outputs.version }}
    steps:
      - id: get-version-number
        name: Get version number
        env:
          TAG: ${{ github.ref }}
        run: |
          version="${TAG/refs\/tags\//}"
          echo "::set-output name=version::$version"

  build:
    name: Lint, test, and compile documentation
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
        with:
          fetch-depth: 1

      - name: Install Python
        uses: actions/setup-python@v2
        with:
          python-version: '3.9.9' # no particular microversion of 3.9 is required; 3.9.8 behaves oddly in GitHub actions

      - name: Setup pip cache
        uses: actions/cache@v2
        with:
          path: /opt/hostedtoolcache/Python
          key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements.optional.txt') }}
          restore-keys: |
            ${{ runner.os }}-pip-

      - name: Install pip and setuptools
        run: |
          python -m pip install --upgrade pip
          python -m pip install --upgrade setuptools

      - name: Install Java # for pyNeuroML
        uses: actions/setup-java@v2
        with:
          distribution: 'adopt'
          java-version: '15'

      - name: Install Perl # for BioNetGen
        run: |
          sudo apt-get update -y
          sudo apt-get install -y --no-install-recommends perl

      - name: Install XPP
        run: |
          sudo apt-get update -y
          sudo apt-get install -y --no-install-recommends wget make gcc libx11-dev libc6-dev

          cd /tmp
          wget http://www.math.pitt.edu/~bard/bardware/xppaut_latest.tar.gz
          mkdir xpp
          tar zxvf xppaut_latest.tar.gz --directory xpp
          cd xpp
          make
          sudo make install

          cd /tmp
          rm xppaut_latest.tar.gz
          rm -r xpp

      - name: Install Singularity # to validate that the Docker image can be converted into a Singularity image
        uses: eWaterCycle/setup-singularity@v5
        with:
          singularity-version: 3.7.1

      # install package
      - name: Install the package
        run: |
          python -m pip install git+https://github.com/biosimulators/RBApy.git#egg=rbapy
          python -m pip install .[all]

      # lint
      - name: Install flake8
        run: python -m pip install flake8

      - name: Lint the package
        run: python -m flake8

      # test and upload coverage report to Codecov
      - name: Install pytest
        run: python -m pip install pytest pytest-cov

      - name: Install the requirements for the tests
        run: python -m pip install .[tests]

      - name: Run the tests
        uses: GabrielBB/xvfb-action@v1
        env:
          MPLBACKEND: PDF
          # BIOSIMULATORS_API_ENDPOINT: https://api.biosimulators.dev/  # uncomment to execute tests with the dev deployment
        with:
          run: python -m pytest tests/ --cov=./biosimulators_utils --cov-report=xml

      - name: Upload the coverage report to Codecov
        uses: codecov/codecov-action@v2
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          flags: unittests
          file: ./coverage.xml

      # compile documentation
      - name: Install the requirements for compiling the documentation
        run: python -m pip install -r docs-src/requirements.txt

      - name: Compile the documentation
        run: |
          sphinx-apidoc . setup.py --output-dir docs-src/source --force --module-first --no-toc
          mkdir -p docs-src/_static
          sphinx-build docs-src docs

  release:
    name: Release a new version
    needs: [getVersionNumber, build]
    runs-on: ubuntu-latest
    outputs:
      docsChanged: ${{ steps.commit-docs.outputs.docsChanged }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
        with:
          fetch-depth: 1
          ref: dev

      - name: Install Python
        uses: actions/setup-python@v2
        with:
          python-version: '3.9'

      - name: Setup pip cache
        uses: actions/cache@v2
        with:
          path: /opt/hostedtoolcache/Python
          key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements.optional.txt') }}
          restore-keys: |
            ${{ runner.os }}-pip-

      - name: Install pip and setuptools
        run: |
          python -m pip install --upgrade pip
          python -m pip install --upgrade setuptools

      # install package
      - name: Install the package
        run: python -m pip install .[all]

      # compile and push documentation
      - name: Install the requirements for compiling the documentation
        run: python -m pip install -r docs-src/requirements.txt

      - name: Compile the documentation
        run: |
          sphinx-apidoc . setup.py --output-dir docs-src/source --force --module-first --no-toc
          mkdir -p docs-src/_static
          sphinx-build docs-src docs

      - id: commit-docs
        name: Commit the compiled documentation
        run: |
          git config --local user.email "biosimulators.daemon@gmail.com"
          git config --local user.name "biosimulatorsdaemon"
          git config pull.rebase false
          git stash
          git pull
          set +e
          git stash pop
          git add docs
          git commit -m "chore: Updating compiled documentation"
          if [[ $? = 0 ]]; then
            docsChanged=1
          else
            docsChanged=0
          fi
          echo "::set-output name=docsChanged::$docsChanged"

      - name: Push the compiled documentation
        if: steps.commit-docs.outputs.docsChanged == '1'
        uses: ad-m/github-push-action@master
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          branch: dev

      # Create GitHub release
      - name: Create GitHub release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ needs.getVersionNumber.outputs.version }}
          release_name: Release ${{ needs.getVersionNumber.outputs.version }}

      # Create PyPI release
      - name: Install twine
        run: |
          python -m pip install wheel twine

      - name: Create packages to upload to PyPI
        run: |
          python setup.py sdist
          python setup.py bdist_wheel

      - name: Upload packages to PyPI
        env:
          TWINE_USERNAME: __token__
          TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
        run: |
          twine upload dist/*

