cryptic-game/python-daemon

View on GitHub
.github/workflows/ci.yml

Summary

Maintainability
Test Coverage
name: CI

on:
  - push
  - pull_request

env:
  PYTHON_VERSION: 3.9
  IMAGE_NAME: crypticcp/python-daemon
  GHCR_NAME: cryptic-game/python-daemon

jobs:
  codestyle:
    if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository }}
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2.3.4
        with:
          submodules: recursive

      - name: Set up Python ${{ env.PYTHON_VERSION }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ env.PYTHON_VERSION }}

      - name: Install black
        run: |
          pip install --upgrade pip
          pip install black==20.8b1

      - name: Check code formatting with black
        run: black -l 120 . --diff --check

  linter:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2.3.4
        with:
          submodules: recursive

      - name: Lint with wemake-python-styleguide
        uses: wemake-services/wemake-python-styleguide@0.15.2
        with:
          reporter: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && 'github-pr-review' || 'terminal' }}
        env:
          GITHUB_TOKEN: ${{ secrets.github_token }}

  tests:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2.3.4
        with:
          submodules: recursive

      - name: Set up Python ${{ env.PYTHON_VERSION }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ env.PYTHON_VERSION }}

      - name: Install dependencies
        run: |
          pip install --upgrade pip
          pip install pipenv
          pipenv sync --dev

      - name: Run unit tests with coverage
        run: pipenv run coverage

      - name: Send coverage report to codeclimate
        env:
          CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
        if: ${{ env.CC_TEST_REPORTER_ID != null }}
        run: |
          set -ex

          wget -O reporter https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64
          chmod +x reporter
          ./reporter after-build

  docs_build:
    if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository }}
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2.3.4
        with:
          submodules: recursive

      - name: Set up Python ${{ env.PYTHON_VERSION }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ env.PYTHON_VERSION }}

      - name: Install dependencies
        run: |
          pip install --upgrade pip
          pip install pipenv
          pipenv sync --dev

      - name: Build documentation
        run: pipenv run docs

      - name: Upload documentation
        uses: actions/upload-artifact@v2
        with:
          name: documentation
          path: build/docs.html
          retention-days: 1

  docs_push:
    runs-on: ubuntu-latest
    needs: [ docs_build ]
    if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/develop' }}

    steps:
      - name: Checkout
        uses: actions/checkout@v2.3.4
        with:
          submodules: recursive

      - name: Download documentation
        uses: actions/download-artifact@v2
        with:
          name: documentation
          path: build

      - name: Rename html file
        run: mv build/docs.html build/index.html

      - name: Publish documentation
        uses: JamesIves/github-pages-deploy-action@4.1.4
        with:
          branch: gh-pages
          folder: build
          clean: true
          git-config-name: GitHub Actions
          git-config-email: actions@github.com

  docker_build:
    if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        platform: [ "linux/amd64", "linux/arm/v7", "linux/arm64/v8" ]  #, "linux/s390x", "linux/ppc64le"

    steps:
      - name: Checkout
        uses: actions/checkout@v2.3.4
        with:
          persist-credentials: false
          submodules: recursive
          fetch-depth: 0

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v1.2.0

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1.3.0

      - name: Cache Docker layers
        uses: actions/cache@v2.1.6
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}-buildx-${{ matrix.platform }}-${{ github.sha }}
          restore-keys: ${{ runner.os }}-buildx-${{ matrix.platform }}-

      - name: Create Version
        id: version
        run: |
          set -x

          name=$IMAGE_NAME
          ghcr_name=$GHCR_NAME

          tag=${GITHUB_REF#refs/tags/v}
          branch=${GITHUB_REF#refs/heads/}
          pull=${GITHUB_REF#refs/pull/}
          pull=${pull%/merge}
          platform=${{ matrix.platform }}

          hub=0

          if [[ $GITHUB_REF = refs/tags/v* ]]; then
            tags="v$tag latest"
            hub=1
          elif [[ $GITHUB_REF = refs/heads/* ]]; then
            tags="$branch"
            if [[ $branch == develop ]]; then
              tags="$tags edge"
              hub=1
            fi
          elif [[ $GITHUB_REF = refs/pull/* ]]; then
            tags="pr-$pull"
          fi
          tags="$(echo $tags | tr / -)"

          out=""
          for t in $tags; do
            [[ $hub == "1" ]] && out="$out,$name:$t-$(echo $platform | tr / -)"
            out="$out,ghcr.io/$ghcr_name:$t-$(echo $platform | tr / -)"
            if [[ $platform == linux/amd64 ]]; then
              [[ $hub == "1" ]] && out="$out,$name:$t"
              out="$out,ghcr.io/$ghcr_name:$t"
            fi
          done

          echo ::set-output name=tags::${out:1}

      - name: Build
        uses: docker/build-push-action@v2.5.0
        with:
          push: false
          load: true
          tags: ${{ steps.version.outputs.tags }}
          platforms: ${{ matrix.platform }}
          file: Dockerfile
          context: .
          cache-from: type=local,src=/tmp/.buildx-cache
          cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max

      - name: Move cache
        run: |
          rm -rf /tmp/.buildx-cache
          mv /tmp/.buildx-cache-new /tmp/.buildx-cache

      - name: Build Docker Image Archive
        id: archive
        env:
          TAGS: ${{ steps.version.outputs.tags }}
        run: |
          set -ex
          platform=${{ matrix.platform }}
          name=$(echo $IMAGE_NAME | tr / _)_$(echo $platform | tr / -).tar.gz
          echo ::set-output name=name::${name}
          docker save $(echo $TAGS | tr , ' ') | gzip > $name

      - name: Upload Docker Image Archive
        uses: actions/upload-artifact@v2
        with:
          name: ${{ steps.archive.outputs.name }}
          path: ${{ steps.archive.outputs.name }}
          retention-days: 1

  docker_push:
    if: ${{ github.event_name != 'pull_request' && github.actor != 'dependabot[bot]' }}
    needs: [ codestyle, linter, tests, docs_build, docker_build ]
    runs-on: ubuntu-latest

    steps:
      - name: Download Docker Image Archive
        uses: actions/download-artifact@v2

      - name: Login to DockerHub
        id: login_dockerhub
        uses: docker/login-action@v1.9.0
        if: ${{ startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/develop' }}
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_PASSWORD }}

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v1.9.0
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.github_token }}

      - name: Push Docker Image
        env:
          NAME: ${{ steps.archive.outputs.name }}
        run: |
          set -ex

          for file in $(ls */*.tar.gz); do
            echo Loading $file
            docker load -qi $file | cut -d' ' -f3 | xargs -L1 docker push
          done

      - name: Clear
        if: always()
        run: rm -f ${HOME}/.docker/config.json