f213/education-backend

View on GitHub
.github/workflows/ci.yml

Summary

Maintainability
Test Coverage
name: CI


on:
  push:
    branches:
      - master
  pull_request:

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v4

      - name: build
        uses: ./.github/actions/build

      - name: restore mypy cache
        uses: actions/cache@v4
        with:
          path: .mypy_cache
          key: mypy-cache-${{ github.ref_name }}
          restore-keys: mypy-cache-master

      - name: lint
        run: make lint

  test:
    needs: lint
    runs-on: ${{ contains(github.triggering_actor, '[bot]') && 'ubuntu-latest' || 'ubuntu-8x' }}
    services:
      postgres:
        image: postgres:13.9-alpine
        env:
          POSTGRES_PASSWORD: secret
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432
      redis:
        image: redis:6.2.10-alpine
        ports:
          - 6379:6379

    steps:
      - uses: actions/checkout@v4

      - name: build
        uses: ./.github/actions/build

      - name: install locale stuff
        uses: awalsh128/cache-apt-pkgs-action@v1
        with:
          packages: locales-all gettext
          version: 1

      - name: get number of CPU cores
        uses: SimenB/github-actions-cpu-cores@v2.0.0
        id: cpu-cores

      - name: test
        env:
          DATABASE_URL: postgres://postgres:secret@localhost:5432/postgres
          REDISCLOUD_URL: redis://localhost:6379/5
        run: make test -e SIMULTANEOUS_TEST_JOBS=${{ steps.cpu-cores.outputs.count }}

      - name: publish test results
        uses: phoenix-actions/test-reporting@v13
        if: always()
        with:
          name: Test results
          path: "junit-*.xml"
          reporter: java-junit

      - name: upload code coverage to codeclimate
        uses: paambaati/codeclimate-action@v3.2.0
        env:
          CC_TEST_REPORTER_ID: dd4cac59d43b52ee4c29cfed9d5162098a49ff65d9e72003abc1fa65cd608f1d
        with:
          coverageLocations: |
            ${{github.workspace}}/src/coverage.xml:coverage.py

  build-docker-image:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v4

      - name: build
        uses: ./.github/actions/build

      - name: set up qemu
        uses: docker/setup-qemu-action@v2

      - name: set up buildx
        uses: docker/setup-buildx-action@v2

      - name: generate image identifier
        id: image
        uses: ASzc/change-string-case-action@v5
        with:
          string: ${{ github.repository_owner }}

      - name: login to ghcr
        uses: docker/login-action@v2
        if: ${{ github.ref == 'refs/heads/master' }}
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: build web image
        uses: docker/build-push-action@v3
        with:
          context: .
          target: web
          push: ${{ github.ref == 'refs/heads/master' }}
          tags: |
            ghcr.io/${{ steps.image.outputs.lowercase }}/monolith-web:latest
            ghcr.io/${{ steps.image.outputs.lowercase }}/monolith-web:${{ github.sha }}

          build-args: |
            PYTHON_VERSION=${{ env.python-version }}
            RELEASE=${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: build worker image
        uses: docker/build-push-action@v3
        with:
          context: .
          target: worker
          push: ${{ github.ref == 'refs/heads/master' }}
          tags: |
            ghcr.io/${{ steps.image.outputs.lowercase }}/monolith-worker:latest
            ghcr.io/${{ steps.image.outputs.lowercase }}/monolith-worker:${{ github.sha }}
          build-args: |
            PYTHON_VERSION=${{ env.python-version }}
            RELEASE=${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: build scheduler image
        uses: docker/build-push-action@v3
        with:
          context: .
          target: scheduler
          push: ${{ github.ref == 'refs/heads/master' }}
          tags: |
            ghcr.io/${{ steps.image.outputs.lowercase }}/monolith-scheduler:latest
            ghcr.io/${{ steps.image.outputs.lowercase }}/monolith-scheduler:${{ github.sha }}
          build-args: |
            PYTHON_VERSION=${{ env.python-version }}
            RELEASE=${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

  deploy:
    needs: build-docker-image
    if: github.ref == 'refs/heads/master' && github.repository_owner == 'tough-dev-school'
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v4

      - name: draft sentry release
        uses: getsentry/action-release@v1
        env:
          SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
          SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
          SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
        with:
          environment: production
          finalize: false

      - name: read image identifiers
        id: image
        uses: ASzc/change-string-case-action@v5
        with:
          string: ${{ github.repository_owner }}

      - name: update backend image
        uses: appleboy/ssh-action@v0.1.7
        with:
          host: ${{ secrets.DEPLOY_HOST }}
          username: circle
          key: ${{ secrets.DEPLOY_KEY }}
          script: docker service update app_backend --image ghcr.io/${{ steps.image.outputs.lowercase }}/monolith-web:${{ github.sha }} --with-registry-auth

      - name: update celery worker image
        uses: appleboy/ssh-action@v0.1.7
        with:
          host: ${{ secrets.DEPLOY_HOST }}
          username: circle
          key: ${{ secrets.DEPLOY_KEY }}
          script: docker service update app_worker --image ghcr.io/${{ steps.image.outputs.lowercase }}/monolith-worker:${{ github.sha }} --with-registry-auth

      - name: update amocrm worker image
        uses: appleboy/ssh-action@v0.1.7
        with:
          host: ${{ secrets.DEPLOY_HOST }}
          username: circle
          key: ${{ secrets.DEPLOY_KEY }}
          script: docker service update app_amocrm-worker --image ghcr.io/${{ steps.image.outputs.lowercase }}/monolith-worker:${{ github.sha }} --with-registry-auth

      - name: update notion worker image
        uses: appleboy/ssh-action@v0.1.7
        with:
          host: ${{ secrets.DEPLOY_HOST }}
          username: circle
          key: ${{ secrets.DEPLOY_KEY }}
          script: docker service update app_notion-worker --image ghcr.io/${{ steps.image.outputs.lowercase }}/monolith-worker:${{ github.sha }} --with-registry-auth

      - name: update celery scheduler image
        uses: appleboy/ssh-action@v0.1.7
        with:
          host: ${{ secrets.DEPLOY_HOST }}
          username: circle
          key: ${{ secrets.DEPLOY_KEY }}
          script: |
            docker service update app_scheduler --detach --image ghcr.io/${{ steps.image.outputs.lowercase }}/monolith-scheduler:${{ github.sha }} --with-registry-auth

      - name: finalize sentry release
        uses: getsentry/action-release@v1
        env:
          SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
          SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
          SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
        with:
          environment: production
          finalize: true