name: Docker CI

on:
  pull_request:
  push:
  schedule:
    - cron: "13 13 * * 3"

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  buildx:
    strategy:
      matrix:
        include:
          - dockerfile: debian
            cache: ${{ github.ref != 'refs/heads/master'
                    && !startsWith(github.ref, 'refs/tags/docker/') }}
            publish: ${{ github.event_name == 'push'
                      && github.repository_owner == 'coturn'
                      && (startsWith(github.ref, 'refs/tags/docker/')
                          || github.ref == 'refs/heads/master') }}
          - dockerfile: alpine
            cache: ${{ github.ref != 'refs/heads/master'
                    && !startsWith(github.ref, 'refs/tags/docker/') }}
            publish: ${{ github.event_name == 'push'
                      && github.repository_owner == 'coturn'
                      && (startsWith(github.ref, 'refs/tags/docker/')
                          || github.ref == 'refs/heads/master') }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - uses: docker/setup-qemu-action@v2
      - uses: docker/setup-buildx-action@v2

      - name: Detect correct Git ref for image build
        id: git
        uses: actions/github-script@v6
        with:
          script: |
            let out = {ref: 'HEAD', ver: ''};
            if ('${{ github.ref }}'.startsWith('refs/tags/docker/')) {
              out.ref = '${{ github.ref }}'.substring(17).split('-')[0];
              out.ver = out.ref;
            }
            return out;
      - name: Verify Git ref matches Makefile version
        run: |
          test "${{ fromJSON(steps.git.outputs.result).ref }}" \
            == "$(grep -m1 'COTURN_VER ?=' Makefile | cut -d'=' -f2 | tr -d ' ')"
        working-directory: ./docker/coturn
        if: ${{ matrix.publish
             && github.ref != 'refs/heads/master' }}

      - uses: satackey/action-docker-layer-caching@v0.0.11
        with:
          key: docker-${{ matrix.dockerfile }}-buildx-{hash}
          restore-keys: docker-${{ matrix.dockerfile }}-buildx-
        continue-on-error: true
        timeout-minutes: 10
        if: ${{ matrix.cache }}
      - name: Pre-build Docker images cache
        run: make docker.build.cache DOCKERFILE=${{ matrix.dockerfile }}
                  no-cache=${{ (matrix.cache && 'no') || 'yes' }}
                  ref=${{ fromJSON(steps.git.outputs.result).ref }}
        working-directory: ./docker/coturn

      - name: Test Docker images
        run: |
          # Enable experimental features of Docker Daemon to run multi-arch images.
          echo "$(cat /etc/docker/daemon.json)" '{"experimental": true}' \
          | jq --slurp 'reduce .[] as $item ({}; . * $item)' \
          | sudo tee /etc/docker/daemon.json
          sudo systemctl restart docker

          make npm.install
          make test.docker DOCKERFILE=${{ matrix.dockerfile }} \
               platforms=@all build=yes \
               ref=${{ fromJSON(steps.git.outputs.result).ref }}
        env:
          COTURN_VERSION: ${{ fromJSON(steps.git.outputs.result).ver }}
        working-directory: ./docker/coturn

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}
        if: ${{ matrix.publish }}
      - name: Login to Quay.io
        uses: docker/login-action@v2
        with:
          registry: quay.io
          username: ${{ secrets.QUAYIO_ROBOT_USERNAME }}
          password: ${{ secrets.QUAYIO_ROBOT_TOKEN }}
        if: ${{ matrix.publish }}
      - name: Login to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKERHUB_BOT_USER }}
          password: ${{ secrets.DOCKERHUB_BOT_PASS }}
        if: ${{ matrix.publish }}

      - name: Publish version Docker tags
        run: make docker.push DOCKERFILE=${{ matrix.dockerfile }}
                  ref=${{ fromJSON(steps.git.outputs.result).ref }}
        working-directory: ./docker/coturn
        if: ${{ matrix.publish
             && github.ref != 'refs/heads/master' }}
      - name: Publish edge Docker tags
        run: make docker.push DOCKERFILE=${{ matrix.dockerfile }}
                  tags=edge-${{ matrix.dockerfile }}
                  ref=${{ fromJSON(steps.git.outputs.result).ref }}
        working-directory: ./docker/coturn
        if: ${{ matrix.publish
             && github.ref == 'refs/heads/master' }}

      # On GitHub Container Registry README is automatically updated on pushes.
      - name: Update README on Quay.io
        uses: christian-korneck/update-container-description-action@v1
        env:
          DOCKER_APIKEY: ${{ secrets.QUAYIO_API_TOKEN }}
        with:
          provider: quay
          destination_container_repo: quay.io/coturn/coturn
          readme_file: docker/coturn/README.md
        if: ${{ matrix.publish }}
      - name: Update README on Docker Hub
        uses: christian-korneck/update-container-description-action@v1
        env:
          DOCKER_USER: ${{ secrets.DOCKERHUB_BOT_USER }}
          DOCKER_PASS: ${{ secrets.DOCKERHUB_BOT_PASS }}
        with:
          provider: dockerhub
          destination_container_repo: coturn/coturn
          readme_file: docker/coturn/README.md
        if: ${{ matrix.publish }}

  release:
    needs: ["buildx"]
    if: ${{ github.event_name == 'push'
         && github.repository_owner == 'coturn'
         && startsWith(github.ref, 'refs/tags/docker/') }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Parse semver versions from Git tag
        id: semver
        uses: actions-ecosystem/action-regex-match@v2
        with:
          text: ${{ github.ref }}
          regex: '^refs/tags/docker/(((([0-9]+)\.[0-9]+)\.[0-9]+)-(.+))$'
      - name: Parse CHANGELOG link
        id: changelog
        run: echo ::set-output name=link::${{ github.server_url }}/${{ github.repository }}/blob/docker/${{ steps.semver.outputs.group1 }}/docker/coturn/CHANGELOG.md#$(sed -n '/^## \[${{ steps.semver.outputs.group1 }}\]/{s/^## \[\(.*\)\][^0-9]*\([0-9].*\)/\1--\2/;s/[^0-9a-z-]*//g;p;}' CHANGELOG.md)
        working-directory: ./docker/coturn

      - name: Create GitHub release
        uses: softprops/action-gh-release@v1
        with:
          name: docker/${{ steps.semver.outputs.group1 }}
          body: |
            `${{ steps.semver.outputs.group1 }}` Docker image version of ${{ steps.semver.outputs.group2 }} Coturn release.

            [Docker Hub](https://hub.docker.com/r/coturn/coturn) | [GitHub Container Registry](https://github.com/orgs/coturn/packages/container/package/coturn) | [Quay.io](https://quay.io/repository/coturn/coturn)

            [Changelog](${{ steps.changelog.outputs.link }})
