victorpopkov/universal-redux

View on GitHub
.github/workflows/cd.yml

Summary

Maintainability
Test Coverage
name: CD

on:
  push:
    branches:
      - develop
      - main

concurrency:
  group: cd-${{ github.ref }}
  cancel-in-progress: true
permissions: read-all

jobs:
  deploy:
    environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - name: Check out
        uses: actions/checkout@v4
      - name: Set docker outputs
        id: docker
        run: echo "cert-path=/home/runner/.docker/deploy" >> "$GITHUB_OUTPUT"
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Login to the private registry
        if: ${{ github.event_name != 'pull_request' }}
        uses: docker/login-action@v3
        with:
          registry: ${{ secrets.DOCKER_REGISTRY_HOST }}
          username: ${{ secrets.DOCKER_REGISTRY_USER }}
          password: ${{ secrets.DOCKER_REGISTRY_PASS }}
      - name: Generate an image metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          flavor: latest=${{ github.ref == 'refs/heads/main' && 'true' || 'false' }}
          images: ${{ secrets.DOCKER_REGISTRY_HOST }}/universal-redux
          labels: maintainer=victor@popkov.me
      - name: Build an image
        uses: docker/build-push-action@v5
        with:
          build-args: |
            APP_BASE_PATH=${{ secrets.APP_PUBLIC_PATH }}
            APP_PUBLIC_PATH=${{ secrets.APP_PUBLIC_PATH }}
            APP_REVISION=${{ github.sha }}
          cache-from: type=registry,ref=${{ fromJSON(steps.meta.outputs.json).tags[0] }}
          cache-to: type=inline
          context: .
          file: ./Dockerfile
          labels: ${{ steps.meta.outputs.labels }}
          platforms: linux/amd64,linux/arm64,linux/arm/v7
          pull: true
          push: true
          tags: ${{ steps.meta.outputs.tags }}
      - name: Add Docker certificates to access the remote host
        run: |
          mkdir -p "${DOCKER_CERT_PATH}"
          echo "${{ secrets.DOCKER_TLS_CA }}" > "${DOCKER_CERT_PATH}/ca.pem"
          echo "${{ secrets.DOCKER_TLS_CERT }}" > "${DOCKER_CERT_PATH}/cert.pem"
          echo "${{ secrets.DOCKER_TLS_KEY }}" > "${DOCKER_CERT_PATH}/key.pem"
          chmod 400 "${DOCKER_CERT_PATH}/ca.pem"
          chmod 400 "${DOCKER_CERT_PATH}/cert.pem"
          chmod 400 "${DOCKER_CERT_PATH}/key.pem"
        env:
          DOCKER_CERT_PATH: ${{ steps.docker.outputs.cert-path }}
      - name: Deploy Docker Stack
        run: |
          docker stack rm "${{ secrets.DOCKER_STACK_NAME }}"
          docker stack deploy \
            --with-registry-auth \
            --resolve-image=always \
            --compose-file=docker-stack.yml \
            --prune \
            "${{ secrets.DOCKER_STACK_NAME }}"
        env:
          DOCKER_CERT_PATH: ${{ steps.docker.outputs.cert-path }}
          DOCKER_HOST: ${{ secrets.DOCKER_HOST }}
          DOCKER_IMAGE: ${{ fromJSON(steps.meta.outputs.json).tags[0] }}
          DOCKER_STACK_NODE_HOSTNAME: ${{ secrets.DOCKER_STACK_NODE_HOSTNAME }}
          DOCKER_TLS_VERIFY: 1
          LOKI_PIPELINE_STAGE_FILE: ${{ secrets.LOKI_PIPELINE_STAGE_FILE }}
          LOKI_URL: ${{ secrets.LOKI_URL }}
          TRAEFIK_HOSTNAME: ${{ secrets.APP_HOSTNAME }}
          TRAEFIK_NAME: ${{ secrets.TRAEFIK_NAME }}
          TRAEFIK_PATH_PREFIX: ${{ secrets.APP_PUBLIC_PATH }}