name: Docker

on:
  workflow_dispatch:
  push:
    branches: [main]
  pull_request:
  release:
    types: [published]

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

permissions: {}

jobs:
  pre-job:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    outputs:
      should_run: ${{ steps.check.outputs.should_run }}
    steps:
      - id: token
        uses: immich-app/devtools/actions/create-workflow-token@da177fa133657503ddb7503f8ba53dccefec5da1 # create-workflow-token-action-v1.0.0
        with:
          app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
          private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}

      - name: Check what should run
        id: check
        uses: immich-app/devtools/actions/pre-job@08bac802a312fc89808e0dd589271ca0974087b5 # pre-job-action-v2.0.0
        with:
          github-token: ${{ steps.token.outputs.token }}
          filters: |
            server:
              - 'server/**'
              - 'openapi/**'
              - 'web/**'
              - 'i18n/**'
            machine-learning:
              - 'machine-learning/**'
          force-filters: |
            - '.github/workflows/docker.yml'
            - '.github/workflows/multi-runner-build.yml'
            - '.github/actions/image-build'
          force-events: 'workflow_dispatch,release'

  retag_ml:
    name: Re-Tag ML
    needs: pre-job
    permissions:
      contents: read
      packages: write
    if: ${{ fromJSON(needs.pre-job.outputs.should_run).machine-learning == false && !github.event.pull_request.head.repo.fork }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        suffix: ['', '-cuda', '-rocm', '-openvino', '-armnn', '-rknn']
    steps:
      - name: Login to GitHub Container Registry
        uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Re-tag image
        env:
          REGISTRY_NAME: 'ghcr.io'
          REPOSITORY: ${{ github.repository_owner }}/immich-machine-learning
          TAG_OLD: main${{ matrix.suffix }}
          TAG_PR: ${{ github.event.number == 0 && github.ref_name || format('pr-{0}', github.event.number) }}${{ matrix.suffix }}
          TAG_COMMIT: commit-${{ github.event_name != 'pull_request' && github.sha || github.event.pull_request.head.sha }}${{ matrix.suffix }}
        run: |
          docker buildx imagetools create -t "${REGISTRY_NAME}/${REPOSITORY}:${TAG_PR}" "${REGISTRY_NAME}/${REPOSITORY}:${TAG_OLD}"
          docker buildx imagetools create -t "${REGISTRY_NAME}/${REPOSITORY}:${TAG_COMMIT}" "${REGISTRY_NAME}/${REPOSITORY}:${TAG_OLD}"

  retag_server:
    name: Re-Tag Server
    needs: pre-job
    permissions:
      contents: read
      packages: write
    if: ${{ fromJSON(needs.pre-job.outputs.should_run).server == false && !github.event.pull_request.head.repo.fork }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        suffix: ['']
    steps:
      - name: Login to GitHub Container Registry
        uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Re-tag image
        env:
          REGISTRY_NAME: 'ghcr.io'
          REPOSITORY: ${{ github.repository_owner }}/immich-server
          TAG_OLD: main${{ matrix.suffix }}
          TAG_PR: ${{ github.event.number == 0 && github.ref_name || format('pr-{0}', github.event.number) }}${{ matrix.suffix }}
          TAG_COMMIT: commit-${{ github.event_name != 'pull_request' && github.sha || github.event.pull_request.head.sha }}${{ matrix.suffix }}
        run: |
          docker buildx imagetools create -t "${REGISTRY_NAME}/${REPOSITORY}:${TAG_PR}" "${REGISTRY_NAME}/${REPOSITORY}:${TAG_OLD}"
          docker buildx imagetools create -t "${REGISTRY_NAME}/${REPOSITORY}:${TAG_COMMIT}" "${REGISTRY_NAME}/${REPOSITORY}:${TAG_OLD}"

  machine-learning:
    name: Build and Push ML
    needs: pre-job
    if: ${{ fromJSON(needs.pre-job.outputs.should_run).machine-learning == true }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - device: cpu
          - device: cuda
            suffixes: '-cuda'
            platforms: linux/amd64
          - device: openvino
            suffixes: '-openvino'
            platforms: linux/amd64
          - device: armnn
            suffixes: '-armnn'
            platforms: linux/arm64
          - device: rknn
            suffixes: '-rknn'
            platforms: linux/arm64
          - device: rocm
            suffixes: '-rocm'
            platforms: linux/amd64
            runner-mapping: '{"linux/amd64": "pokedex-giant"}'
    uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@0477486d82313fba68f7c82c034120a4b8981297 # multi-runner-build-workflow-v2.1.0
    permissions:
      contents: read
      actions: read
      packages: write
    secrets:
      DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
      DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
    with:
      image: immich-machine-learning
      context: machine-learning
      dockerfile: machine-learning/Dockerfile
      platforms: ${{ matrix.platforms }}
      runner-mapping: ${{ matrix.runner-mapping }}
      suffixes: ${{ matrix.suffixes }}
      dockerhub-push: ${{ github.event_name == 'release' }}
      build-args: |
        DEVICE=${{ matrix.device }}

  server:
    name: Build and Push Server
    needs: pre-job
    if: ${{ fromJSON(needs.pre-job.outputs.should_run).server == true }}
    uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@0477486d82313fba68f7c82c034120a4b8981297 # multi-runner-build-workflow-v2.1.0
    permissions:
      contents: read
      actions: read
      packages: write
    secrets:
      DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
      DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
    with:
      image: immich-server
      context: .
      dockerfile: server/Dockerfile
      dockerhub-push: ${{ github.event_name == 'release' }}
      build-args: |
        DEVICE=cpu

  success-check-server:
    name: Docker Build & Push Server Success
    needs: [server, retag_server]
    permissions: {}
    runs-on: ubuntu-latest
    if: always()
    steps:
      - uses: immich-app/devtools/actions/success-check@68f10eb389bb02a3cf9d1156111964c549eb421b # 0.0.4
        with:
          needs: ${{ toJSON(needs) }}

  success-check-ml:
    name: Docker Build & Push ML Success
    needs: [machine-learning, retag_ml]
    permissions: {}
    runs-on: ubuntu-latest
    if: always()
    steps:
      - uses: immich-app/devtools/actions/success-check@68f10eb389bb02a3cf9d1156111964c549eb421b # 0.0.4
        with:
          needs: ${{ toJSON(needs) }}
