Repository: nansencenter/django-geo-spaas (language: python)

Issue:
Migrate CI to Github Actions
Travis CI has changed its pricing policy; it is no longer free for open-source repositories (not without negotiating a quota).
We are migrating our CI to Github Actions.


Discussion / hints:

Fix patch:
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index c381c14d..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,84 +0,0 @@
-language: python
-python:
-  - '3.7'
-services:
-  - docker
-
-# Environment variables defined as part of the Travis CI repository configuration are:
-# - DOCKER_ORG: the docker hub organization (or user) to which the image will be pushed
-# - DOCKER_USER: the docker hub user used to log in to the docker hub
-# - DOCKER_PASS: the password of this user
-# - PYPI_TOKEN: the token associated to the pypi account for deployment. More information can be found here: https://pypi.org/help/#apitoken
-# - COVERALLS_REPO_TOKEN: authentication token for coveralls.io
-
-env:
-  global:
-    - IMAGE_NAME="${DOCKER_ORG}/geospaas"
-
-jobs:
-  include:
-    - stage: 'Unit tests'
-      if: type = push
-      env:
-        - TEST_IMAGE="${IMAGE_NAME}:latest"
-      install:
-        - docker pull "${TEST_IMAGE}" || true
-      script:
-        - >
-          docker run --rm
-          -e COVERALLS_REPO_TOKEN
-          -e "TRAVIS=true"
-          -e TRAVIS_JOB_ID
-          -e TRAVIS_BRANCH
-          -e TRAVIS_PULL_REQUEST
-          -v "$(pwd):/src"
-          ${TEST_IMAGE}
-          bash -c "source /opt/conda/bin/activate && coverage run --omit=geospaas/nansat_ingestor/tests/*,geospaas/catalog/tests/*,geospaas/vocabularies/tests/* runtests.py  && coveralls"
-      deploy:
-        - provider: pypi
-          edge: true
-          user: "__token__"
-          password: "${PYPI_TOKEN}"
-          on:
-            tags: true
-
-    - stage: 'Build Docker images'
-      name: 'Build standard image'
-      if: type = push
-      env:
-        - TAG='latest'
-      install:
-        - docker pull "${IMAGE_NAME}:${TAG}" || true
-      script:
-        - >
-          docker build .
-          --cache-from "${IMAGE_NAME}:${TAG}"
-          --build-arg BASE_IMAGE="nansencenter/nansat:${TAG}"
-          -t "${IMAGE_NAME}:tmp"
-      before_deploy:
-        - docker login -u "$DOCKER_USER" -p "$DOCKER_PASS"
-      deploy:
-        - provider: script
-          on:
-            tags: true
-          script: /bin/bash scripts/docker_push.sh $TRAVIS_TAG latest
-
-    - name: 'Build slim image'
-      if: type = push
-      env:
-        - TAG='latest-slim'
-      install:
-        - docker pull "${IMAGE_NAME}:${TAG}" || true
-      script:
-        - >
-          docker build .
-          --cache-from "${IMAGE_NAME}:${TAG}"
-          --build-arg BASE_IMAGE="nansencenter/nansat:${TAG}"
-          -t "${IMAGE_NAME}:tmp"
-      before_deploy:
-        - docker login -u "$DOCKER_USER" -p "$DOCKER_PASS"
-      deploy:
-        - provider: script
-          on:
-            tags: true
-          script: /bin/bash scripts/docker_push.sh "${TRAVIS_TAG}-slim" 'latest-slim'
diff --git a/Dockerfile b/Dockerfile
index 813255b8..3fbbfcc4 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,6 @@
 # Initialize from docker image with Python, libraries and Nansat
 ARG BASE_IMAGE='nansencenter/nansat:latest'
-FROM ${BASE_IMAGE}
+FROM ${BASE_IMAGE} as base
 LABEL purpose="Running and developing Django-Geo-SpaaS"
 ENV PYTHONUNBUFFERED=1
 
@@ -23,6 +23,9 @@ RUN apt update \
 &&  apt clean && rm -rf /var/lib/apt/lists/* \
 &&  echo "alias ll='ls -lh'" >> /root/.bashrc
 
+FROM base as full
+
+ARG DJANGO_GEO_SPAAS_RELEASE '0.0.0dev'
 # install Geo-SPaaS
 COPY geospaas /tmp/geospaas
 COPY setup.py /tmp/
diff --git a/scripts/docker_push.sh b/scripts/docker_push.sh
deleted file mode 100644
index eba56fb8..00000000
--- a/scripts/docker_push.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-for tag in $*;do
-    docker tag "${IMAGE_NAME}:tmp" "${IMAGE_NAME}:${tag}"
-    docker push "${IMAGE_NAME}:${tag}"
-done
diff --git a/setup.py b/setup.py
index b13b9131..f456b4fc 100644
--- a/setup.py
+++ b/setup.py
@@ -10,14 +10,15 @@
 # Copyright:    (c) NERSC
 # License:
 #-------------------------------------------------------------------------------
-from setuptools import setup, find_packages
+import os
 import sys
+from setuptools import setup, find_packages
 
 install_requires = []
 
 setup(
     name='django-geo-spaas',
-    version='2.4.0',
+    version=os.getenv('DJANGO_GEO_SPAAS_RELEASE', '0.0.0dev'),
     description='Geo-Scientific Platform as a Service',
     zip_safe=False,
     author='Morten W. Hansen, Anton Korosov, Artem Moiseev, Jeong-Won Park, Adrien Perrin, A.Azamifard',


Test patch:
diff --git a/.github/workflows/tests_build.yml b/.github/workflows/tests_build.yml
new file mode 100644
index 00000000..d30fd359
--- /dev/null
+++ b/.github/workflows/tests_build.yml
@@ -0,0 +1,218 @@
+---
+name: "Unit tests and build"
+on:
+  push:
+    branches: ['**']
+  release:
+    types: [released]
+env:
+  IMAGE_NAME: "${{ secrets.DOCKER_ORG }}/geospaas"
+  BASE_IMAGE_NAME: "${{ secrets.DOCKER_ORG }}/nansat"
+  BASE_STANDARD_IMAGE_TAG: v1.4.5
+  BASE_SLIM_IMAGE_TAG: v1.4.5-slim
+jobs:
+  tests:
+    name: 'Run unit tests'
+    runs-on: 'ubuntu-20.04'
+    steps:
+      - name: 'Checkout repository'
+        uses: actions/checkout@v2
+
+      - name: Set up Docker Buildx
+        uses: docker/setup-buildx-action@v1
+
+      - name: Login to DockerHub
+        uses: docker/login-action@v1
+        with:
+          username: ${{ secrets.DOCKER_USER }}
+          password: ${{ secrets.DOCKER_PASS }}
+
+      - name: Cache Docker layers
+        uses: actions/cache@v2
+        with:
+          path: /tmp/.buildx-cache
+          key: ${{ runner.os }}-buildx-testing-${{ github.sha }}
+          restore-keys: |
+            ${{ runner.os }}-buildx-testing-
+
+      - name: Build testing image
+        id: docker_build
+        uses: docker/build-push-action@v2
+        with:
+          context: .
+          target: base
+          build-args: |
+            BASE_IMAGE=${{ env.BASE_IMAGE_NAME }}:${{ env.BASE_SLIM_IMAGE_TAG }}
+          push: false
+          load: true
+          tags: ${{ env.IMAGE_NAME }}
+          cache-from: type=local,src=/tmp/.buildx-cache
+          cache-to: type=local,dest=/tmp/.buildx-cache-new
+
+        # Temp fix
+        # https://github.com/docker/build-push-action/issues/252
+        # https://github.com/moby/buildkit/issues/1896
+      - name: Move cache
+        run: |
+          rm -rf /tmp/.buildx-cache
+          mv /tmp/.buildx-cache-new /tmp/.buildx-cache
+
+      - name: 'Run tests'
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        run: >
+             docker run --rm
+             -v "$(pwd):/src"
+             -e "GITHUB_ACTIONS=$GITHUB_ACTIONS"
+             -e "GITHUB_REF=$GITHUB_REF"
+             -e "GITHUB_SHA=$GITHUB_SHA"
+             -e "GITHUB_HEAD_REF=$GITHUB_HEAD_REF"
+             -e "GITHUB_REPOSITORY=$GITHUB_REPOSITORY"
+             -e "GITHUB_RUN_ID=$GITHUB_RUN_ID"
+             -e "GITHUB_TOKEN=$GITHUB_TOKEN"
+             "${IMAGE_NAME}"
+             bash -c "coverage run --omit=geospaas/nansat_ingestor/tests/*,geospaas/catalog/tests/*,geospaas/vocabularies/tests/* runtests.py && coveralls"
+
+
+  publish_python_package:
+    name: Publish the Python package to PyPI
+    runs-on: 'ubuntu-20.04'
+    needs: 'tests'
+    if: github.event_name == 'release'
+    steps:
+      - name: 'Checkout repository'
+        uses: actions/checkout@v2
+
+      - name: Set up Python 3.7
+        uses: actions/setup-python@v1
+        with:
+          python-version: 3.7
+
+      - name: Build package
+        run: >
+             DJANGO_GEO_SPAAS_RELEASE="${GITHUB_REF#refs/tags/}"
+             python setup.py sdist
+        shell: bash
+
+      - name: Publish
+        uses: pypa/gh-action-pypi-publish@release/v1
+        with:
+          # Storing the PyPI URL in the repositories' secrets makes
+          # publishing to the test PyPI from forks easy
+          repository_url: ${{ secrets.PYPI_REPOSITORY_URL }}
+          password: ${{ secrets.PYPI_TOKEN }}
+
+
+  build_standard_docker_image:
+    runs-on: 'ubuntu-20.04'
+    needs: 'tests'
+    steps:
+      - name: 'Checkout repository'
+        uses: actions/checkout@v2
+
+      - name: "Extract tag name"
+        id: get_version
+        run: |
+          if [[ $GITHUB_REF == refs/tags/* ]];then
+            TAG="${GITHUB_REF#refs/tags/}"
+          else
+            TAG='tmp'
+          fi
+          echo "::set-output name=VERSION::${TAG}"
+
+      - name: Set up Docker Buildx
+        uses: docker/setup-buildx-action@v1
+
+      - name: Cache Docker layers
+        uses: actions/cache@v2
+        with:
+          path: /tmp/.buildx-cache
+          key: ${{ runner.os }}-buildx-standard-${{ github.sha }}
+          restore-keys: |
+            ${{ runner.os }}-buildx-standard-
+
+      - name: Login to DockerHub
+        uses: docker/login-action@v1
+        with:
+          username: ${{ secrets.DOCKER_USER }}
+          password: ${{ secrets.DOCKER_PASS }}
+
+      - name: Build docker image
+        uses: docker/build-push-action@v2
+        with:
+          context: .
+          build-args: |
+            BASE_IMAGE=${{ env.BASE_IMAGE_NAME }}:${{ env.BASE_STANDARD_IMAGE_TAG }}
+            DJANGO_GEO_SPAAS_RELEASE=${{ steps.get_version.outputs.VERSION }}
+          push: ${{ startsWith(github.ref, 'refs/tags/') }}
+          tags: |
+            ${{ env.IMAGE_NAME }}:latest
+            ${{ env.IMAGE_NAME }}:${{ steps.get_version.outputs.VERSION }}
+          cache-from: type=local,src=/tmp/.buildx-cache
+          cache-to: type=local,dest=/tmp/.buildx-cache-new
+
+        # Temp fix
+        # https://github.com/docker/build-push-action/issues/252
+        # https://github.com/moby/buildkit/issues/1896
+      - name: Move cache
+        run: |
+          rm -rf /tmp/.buildx-cache
+          mv /tmp/.buildx-cache-new /tmp/.buildx-cache
+
+  build_slim_docker_image:
+    runs-on: 'ubuntu-20.04'
+    needs: 'tests'
+    steps:
+      - name: 'Checkout repository'
+        uses: actions/checkout@v2
+
+      - name: "Extract tag name"
+        id: get_version
+        run: |
+          if [[ $GITHUB_REF == refs/tags/* ]];then
+            TAG="${GITHUB_REF#refs/tags/}"
+          else
+            TAG='tmp'
+          fi
+          echo "::set-output name=VERSION::${TAG}"
+
+      - name: Set up Docker Buildx
+        uses: docker/setup-buildx-action@v1
+
+      - name: Cache Docker layers
+        uses: actions/cache@v2
+        with:
+          path: /tmp/.buildx-cache
+          key: ${{ runner.os }}-buildx-slim-${{ github.sha }}
+          restore-keys: |
+            ${{ runner.os }}-buildx-slim-
+            ${{ runner.os }}-buildx-testing-
+
+      - name: Login to DockerHub
+        uses: docker/login-action@v1
+        with:
+          username: ${{ secrets.DOCKER_USER }}
+          password: ${{ secrets.DOCKER_PASS }}
+
+      - name: Build docker image
+        uses: docker/build-push-action@v2
+        with:
+          context: .
+          build-args: |
+            BASE_IMAGE=${{ env.BASE_IMAGE_NAME }}:${{ env.BASE_SLIM_IMAGE_TAG }}
+            DJANGO_GEO_SPAAS_RELEASE=${{ steps.get_version.outputs.VERSION }}
+          push: ${{ startsWith(github.ref, 'refs/tags/') }}
+          tags: |
+            ${{ env.IMAGE_NAME }}:latest-slim
+            ${{ env.IMAGE_NAME }}:${{ steps.get_version.outputs.VERSION }}-slim
+          cache-from: type=local,src=/tmp/.buildx-cache
+          cache-to: type=local,dest=/tmp/.buildx-cache-new
+
+        # Temp fix
+        # https://github.com/docker/build-push-action/issues/252
+        # https://github.com/moby/buildkit/issues/1896
+      - name: Move cache
+        run: |
+          rm -rf /tmp/.buildx-cache
+          mv /tmp/.buildx-cache-new /tmp/.buildx-cache
+...
\ No newline at end of file