name: Docker builds

on:
  push:
    branches: ['*']
    tags:
      - v*
  pull_request:
    branches: [master]
  schedule:
    # At 01:18 every Thursday. Details in https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#schedule
    - cron: '18 1 * * 4'

env:
  IS_PUSHING_IMAGES: ${{ github.event_name != 'pull_request' && github.repository == 'photoview/photoview' }}
  # IS_PUSHING_IMAGES: true # Switch on when pushing images with forked repos.
  DOCKER_REGISTRY: ${{ github.repository != 'photoview/photoview' && 'ghcr.io/' || '' }}
  DOCKER_USERNAME: viktorstrate
  DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
  DOCKER_IMAGE: ${{ github.repository }}
  PLATFORMS: linux/amd64,linux/arm64,linux/arm/v7

jobs:
  prepare:
    name: Prepare the Matrix
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-tags: 'true'
          fetch-depth: 0

      - name: Prepare the Matrix
        id: prepare_matrix
        shell: bash
        run: |
          echo Event is '${{ github.event_name }}'
          case ${{ github.event_name }} in
            pull_request)
              echo 'tags=[{"tag": "", "ref": "${{ github.ref }}"}]' | tee -a $GITHUB_OUTPUT
              ;;
            push)
              echo 'tags=[{"tag": "${{ github.ref_name }}", "ref": "${{ github.ref }}"}]' | tee -a $GITHUB_OUTPUT
              ;;
            schedule)
              git fetch --all
              TAG=$(git describe --tags --abbrev=0 --always || exit 0)
              echo TAG is $TAG
              if [ -z "$TAG" ]; then
                echo 'tags=[{"tag": "${{ github.ref_name }}", "ref": "${{ github.ref }}"}]' | tee -a $GITHUB_OUTPUT
              else
                echo tags=[{'"'tag'"': '"'${{ github.ref_name }}'"', '"'ref'"': '"'${{ github.ref }}'"'}, {'"'tag'"': '"'${TAG#v}'"', '"'ref'"': '"'$(git show-ref --tags -d | grep "/$TAG$" | cut -d ' ' -f 2)'"'}] | tee -a $GITHUB_OUTPUT
              fi
              ;;
            *)
              echo "Run for '${{ github.event_name }}' is not expected"
              echo 'tags=[{"tag": "${{ github.ref_name }}", "ref": "${{ github.ref }}"}]' | tee -a $GITHUB_OUTPUT
              ;;
          esac

    outputs:
      tags: ${{ steps.prepare_matrix.outputs.tags }}

  build:
    name: Build Docker Image
    runs-on: ubuntu-latest
    needs: prepare
    strategy:
      fail-fast: false
      matrix:
        tags: ${{ fromJson(needs.prepare.outputs.tags) }}
    steps:
      - name: Delete huge unnecessary tools folder
        run: rm -rf /opt/hostedtoolcache

      - name: Checkout ${{ matrix.tags.ref }}
        uses: actions/checkout@v4
        with:
          ref: ${{ matrix.tags.ref }}

      - name: Fetch branches
        run: git fetch --all

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3
        with:
          platforms: ${{ env.PLATFORMS }}

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Docker Login
        if: ${{ env.IS_PUSHING_IMAGES == 'true' }}
        uses: docker/login-action@v3
        with:
          registry: ${{ env.DOCKER_REGISTRY == 'ghcr.io/' && 'ghcr.io' || '' }}
          username: ${{ env.DOCKER_REGISTRY == 'ghcr.io/' && github.actor || env.DOCKER_USERNAME }}
          password: ${{ env.DOCKER_REGISTRY == 'ghcr.io/' && github.token || env.DOCKER_PASSWORD }}

      - name: Docker meta
        id: docker_meta
        uses: docker/metadata-action@v5
        with:
          context: "git"
          images: ${{ env.DOCKER_REGISTRY }}${{ env.DOCKER_IMAGE }}
          tags: |
            ${{ github.event_name == 'schedule' && matrix.tags.tag != 'master' && 'type=semver,pattern={{version}}' || '' }}
            ${{ github.event_name == 'schedule' && matrix.tags.tag != 'master' && 'type=semver,pattern={{major}}.{{minor}}' || '' }}
            ${{ github.event_name == 'schedule' && matrix.tags.tag != 'master' && 'type=semver,pattern={{major}}' || '' }}
            ${{ github.event_name == 'schedule' && matrix.tags.tag == 'master' && 'type=ref,event=branch' || '' }}
            ${{ github.event_name == 'schedule' && matrix.tags.tag == 'master' && 'type=sha' || '' }}
            ${{ github.event_name != 'schedule' && 'type=ref,event=branch' || '' }}
            ${{ github.event_name != 'schedule' && 'type=ref,event=pr' || '' }}
            ${{ github.event_name != 'schedule' && 'type=semver,pattern={{version}}' || '' }}
            ${{ github.event_name != 'schedule' && 'type=semver,pattern={{major}}.{{minor}}' || '' }}
            ${{ github.event_name != 'schedule' && 'type=semver,pattern={{major}}' || '' }}
            ${{ github.event_name != 'schedule' && 'type=sha' || '' }}

      - name: Build and push
        uses: docker/build-push-action@v6
        with:
          context:     .
          sbom:        true
          provenance:  mode=max
          platforms:   ${{ env.PLATFORMS }}
          pull:        true
          push:        ${{ env.IS_PUSHING_IMAGES }}
          tags:        ${{ steps.docker_meta.outputs.tags }}
          labels:      ${{ steps.docker_meta.outputs.labels }}
          annotations: ${{ steps.docker_meta.outputs.annotations }}
          cache-from:  type=gha
          cache-to:    type=gha,mode=max
          build-args: |
            NODE_ENV=production
            VERSION=${{ github.ref_name }}
            COMMIT_SHA=${{ github.sha }}

  dockle:
    name: Dockle Container Analysis
    runs-on: ubuntu-latest
    needs:
      - prepare
      - build
    strategy:
      fail-fast: false
      matrix:
        tags: ${{ fromJson(needs.prepare.outputs.tags) }}
    # Comment out when pushing images with forked repos.
    if: ${{ github.event_name != 'pull_request' && github.repository == 'photoview/photoview' }}
    steps:
      # Makes sure your .dockleignore file is available to the next step
      - name: Checkout ${{ matrix.tags.ref }}
        uses: actions/checkout@v4
        with:
          ref: ${{ matrix.tags.ref }}

      - name: Docker Login
        uses: docker/login-action@v3
        with:
          registry: ${{ env.DOCKER_REGISTRY == 'ghcr.io/' && 'ghcr.io' || '' }}
          username: ${{ env.DOCKER_REGISTRY == 'ghcr.io/' && github.actor || env.DOCKER_USERNAME }}
          password: ${{ env.DOCKER_REGISTRY == 'ghcr.io/' && github.token || env.DOCKER_PASSWORD }}

      - name: Run Dockle for '${{ env.DOCKER_REGISTRY }}${{ env.DOCKER_IMAGE }}:${{ matrix.tags.tag }}'
        id: dockle
        if: ${{ matrix.tags.tag != '' }}
        continue-on-error: true
        uses: erzz/dockle-action@v1
        with:
          image:             '${{ env.DOCKER_REGISTRY }}${{ env.DOCKER_IMAGE }}:${{ matrix.tags.tag }}'
          report-name:       dockle-results-${{ matrix.tags.tag }}
          report-format:     sarif
          failure-threshold: fatal
          exit-code:         1
          timeout:           5m

      - name: Upload SARIF file
        if: ${{ steps.dockle.conclusion == 'success' }}
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: dockle-results-${{ matrix.tags.tag }}.sarif
