name: Branch Build

on:
  workflow_dispatch:
  push:
    branches:
      - master
      - preview
  release:
    types: [released, prereleased]

env:
  TARGET_BRANCH: ${{ github.ref_name || github.event.release.target_commitish }}

jobs:
  branch_build_setup:
    name: Build-Push Web/Space/API/Proxy Docker Image
    runs-on: ubuntu-latest
    outputs:
      gh_branch_name: ${{ steps.set_env_variables.outputs.TARGET_BRANCH }}
      gh_buildx_driver: ${{ steps.set_env_variables.outputs.BUILDX_DRIVER }}
      gh_buildx_version: ${{ steps.set_env_variables.outputs.BUILDX_VERSION }}
      gh_buildx_platforms: ${{ steps.set_env_variables.outputs.BUILDX_PLATFORMS }}
      gh_buildx_endpoint: ${{ steps.set_env_variables.outputs.BUILDX_ENDPOINT }}
      build_frontend: ${{ steps.changed_files.outputs.frontend_any_changed }}
      build_admin: ${{ steps.changed_files.outputs.admin_any_changed }}
      build_space: ${{ steps.changed_files.outputs.space_any_changed }}
      build_backend: ${{ steps.changed_files.outputs.backend_any_changed }}
      build_proxy: ${{ steps.changed_files.outputs.proxy_any_changed }}

    steps:
      - id: set_env_variables
        name: Set Environment Variables
        run: |
          if [ "${{ env.TARGET_BRANCH }}" == "master" ] || [ "${{ github.event_name }}" == "release" ]; then
            echo "BUILDX_DRIVER=cloud" >> $GITHUB_OUTPUT
            echo "BUILDX_VERSION=lab:latest" >> $GITHUB_OUTPUT
            echo "BUILDX_PLATFORMS=linux/amd64,linux/arm64" >> $GITHUB_OUTPUT
            echo "BUILDX_ENDPOINT=makeplane/plane-dev" >> $GITHUB_OUTPUT
          else
            echo "BUILDX_DRIVER=docker-container" >> $GITHUB_OUTPUT
            echo "BUILDX_VERSION=latest" >> $GITHUB_OUTPUT
            echo "BUILDX_PLATFORMS=linux/amd64" >> $GITHUB_OUTPUT
            echo "BUILDX_ENDPOINT=" >> $GITHUB_OUTPUT
          fi
          echo "TARGET_BRANCH=${{ env.TARGET_BRANCH }}" >> $GITHUB_OUTPUT

      - id: checkout_files
        name: Checkout Files
        uses: actions/checkout@v4

      - name: Get changed files
        id: changed_files
        uses: tj-actions/changed-files@v42
        with:
          files_yaml: |
            frontend:
              - web/**
              - packages/**
              - 'package.json'
              - 'yarn.lock'
              - 'tsconfig.json'
              - 'turbo.json'
            space:
              - space/**
              - packages/**
              - 'package.json'
              - 'yarn.lock'
              - 'tsconfig.json'
              - 'turbo.json'
            admin:
              - admin/**
              - packages/**
              - 'package.json'
              - 'yarn.lock'
              - 'tsconfig.json'
              - 'turbo.json'
            backend:
              - apiserver/**
            proxy:
              - nginx/**

  branch_build_push_frontend:
    if: ${{ needs.branch_build_setup.outputs.build_frontend == 'true' || github.event_name == 'workflow_dispatch' || github.event_name == 'release' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
    runs-on: ubuntu-20.04
    needs: [branch_build_setup]
    env:
      FRONTEND_TAG: ${{ secrets.DOCKERHUB_USERNAME }}/plane-frontend:${{ needs.branch_build_setup.outputs.gh_branch_name }}
      TARGET_BRANCH: ${{ needs.branch_build_setup.outputs.gh_branch_name }}
      BUILDX_DRIVER: ${{ needs.branch_build_setup.outputs.gh_buildx_driver }}
      BUILDX_VERSION: ${{ needs.branch_build_setup.outputs.gh_buildx_version }}
      BUILDX_PLATFORMS: ${{ needs.branch_build_setup.outputs.gh_buildx_platforms }}
      BUILDX_ENDPOINT: ${{ needs.branch_build_setup.outputs.gh_buildx_endpoint }}
    steps:
      - name: Set Frontend Docker Tag
        run: |
          if [ "${{ github.event_name }}" == "release" ]; then
            TAG=${{ secrets.DOCKERHUB_USERNAME }}/plane-frontend:stable,${{ secrets.DOCKERHUB_USERNAME }}/plane-frontend:${{ github.event.release.tag_name }}
          elif [ "${{ env.TARGET_BRANCH }}" == "master" ]; then
            TAG=${{ secrets.DOCKERHUB_USERNAME }}/plane-frontend:latest
          else
            TAG=${{ env.FRONTEND_TAG }}
          fi
          echo "FRONTEND_TAG=${TAG}" >> $GITHUB_ENV

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          driver: ${{ env.BUILDX_DRIVER }}
          version: ${{ env.BUILDX_VERSION }}
          endpoint: ${{ env.BUILDX_ENDPOINT }}

      - name: Check out the repo
        uses: actions/checkout@v4

      - name: Build and Push Frontend to Docker Container Registry
        uses: docker/build-push-action@v5.1.0
        with:
          context: .
          file: ./web/Dockerfile.web
          platforms: ${{ env.BUILDX_PLATFORMS }}
          tags: ${{ env.FRONTEND_TAG }}
          push: true
        env:
          DOCKER_BUILDKIT: 1
          DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
          DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}

  branch_build_push_admin:
    if: ${{ needs.branch_build_setup.outputs.build_admin== 'true' || github.event_name == 'workflow_dispatch' || github.event_name == 'release' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
    runs-on: ubuntu-20.04
    needs: [branch_build_setup]
    env:
      ADMIN_TAG: ${{ secrets.DOCKERHUB_USERNAME }}/plane-admin:${{ needs.branch_build_setup.outputs.gh_branch_name }}
      TARGET_BRANCH: ${{ needs.branch_build_setup.outputs.gh_branch_name }}
      BUILDX_DRIVER: ${{ needs.branch_build_setup.outputs.gh_buildx_driver }}
      BUILDX_VERSION: ${{ needs.branch_build_setup.outputs.gh_buildx_version }}
      BUILDX_PLATFORMS: ${{ needs.branch_build_setup.outputs.gh_buildx_platforms }}
      BUILDX_ENDPOINT: ${{ needs.branch_build_setup.outputs.gh_buildx_endpoint }}
    steps:
      - name: Set Admin Docker Tag
        run: |
          if [ "${{ github.event_name }}" == "release" ]; then
            TAG=${{ secrets.DOCKERHUB_USERNAME }}/plane-admin:stable,${{ secrets.DOCKERHUB_USERNAME }}/plane-admin:${{ github.event.release.tag_name }}
          elif [ "${{ env.TARGET_BRANCH }}" == "master" ]; then
            TAG=${{ secrets.DOCKERHUB_USERNAME }}/plane-admin:latest
          else
            TAG=${{ env.ADMIN_TAG }}
          fi
          echo "ADMIN_TAG=${TAG}" >> $GITHUB_ENV

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          driver: ${{ env.BUILDX_DRIVER }}
          version: ${{ env.BUILDX_VERSION }}
          endpoint: ${{ env.BUILDX_ENDPOINT }}

      - name: Check out the repo
        uses: actions/checkout@v4

      - name: Build and Push Frontend to Docker Container Registry
        uses: docker/build-push-action@v5.1.0
        with:
          context: .
          file: ./admin/Dockerfile.admin
          platforms: ${{ env.BUILDX_PLATFORMS }}
          tags: ${{ env.ADMIN_TAG }}
          push: true
        env:
          DOCKER_BUILDKIT: 1
          DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
          DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}

  branch_build_push_space:
    if: ${{ needs.branch_build_setup.outputs.build_space == 'true' || github.event_name == 'workflow_dispatch' || github.event_name == 'release' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
    runs-on: ubuntu-20.04
    needs: [branch_build_setup]
    env:
      SPACE_TAG: ${{ secrets.DOCKERHUB_USERNAME }}/plane-space:${{ needs.branch_build_setup.outputs.gh_branch_name }}
      TARGET_BRANCH: ${{ needs.branch_build_setup.outputs.gh_branch_name }}
      BUILDX_DRIVER: ${{ needs.branch_build_setup.outputs.gh_buildx_driver }}
      BUILDX_VERSION: ${{ needs.branch_build_setup.outputs.gh_buildx_version }}
      BUILDX_PLATFORMS: ${{ needs.branch_build_setup.outputs.gh_buildx_platforms }}
      BUILDX_ENDPOINT: ${{ needs.branch_build_setup.outputs.gh_buildx_endpoint }}
    steps:
      - name: Set Space Docker Tag
        run: |
          if [ "${{ github.event_name }}" == "release" ]; then
            TAG=${{ secrets.DOCKERHUB_USERNAME }}/plane-space:stable,${{ secrets.DOCKERHUB_USERNAME }}/plane-space:${{ github.event.release.tag_name }}
          elif [ "${{ env.TARGET_BRANCH }}" == "master" ]; then
            TAG=${{ secrets.DOCKERHUB_USERNAME }}/plane-space:latest
          else
            TAG=${{ env.SPACE_TAG }}
          fi
          echo "SPACE_TAG=${TAG}" >> $GITHUB_ENV

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          driver: ${{ env.BUILDX_DRIVER }}
          version: ${{ env.BUILDX_VERSION }}
          endpoint: ${{ env.BUILDX_ENDPOINT }}

      - name: Check out the repo
        uses: actions/checkout@v4

      - name: Build and Push Space to Docker Hub
        uses: docker/build-push-action@v5.1.0
        with:
          context: .
          file: ./space/Dockerfile.space
          platforms: ${{ env.BUILDX_PLATFORMS }}
          tags: ${{ env.SPACE_TAG }}
          push: true
        env:
          DOCKER_BUILDKIT: 1
          DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
          DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}

  branch_build_push_backend:
    if: ${{ needs.branch_build_setup.outputs.build_backend == 'true' || github.event_name == 'workflow_dispatch' || github.event_name == 'release' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
    runs-on: ubuntu-20.04
    needs: [branch_build_setup]
    env:
      BACKEND_TAG: ${{ secrets.DOCKERHUB_USERNAME }}/plane-backend:${{ needs.branch_build_setup.outputs.gh_branch_name }}
      TARGET_BRANCH: ${{ needs.branch_build_setup.outputs.gh_branch_name }}
      BUILDX_DRIVER: ${{ needs.branch_build_setup.outputs.gh_buildx_driver }}
      BUILDX_VERSION: ${{ needs.branch_build_setup.outputs.gh_buildx_version }}
      BUILDX_PLATFORMS: ${{ needs.branch_build_setup.outputs.gh_buildx_platforms }}
      BUILDX_ENDPOINT: ${{ needs.branch_build_setup.outputs.gh_buildx_endpoint }}
    steps:
      - name: Set Backend Docker Tag
        run: |
          if [ "${{ github.event_name }}" == "release" ]; then
            TAG=${{ secrets.DOCKERHUB_USERNAME }}/plane-backend:stable,${{ secrets.DOCKERHUB_USERNAME }}/plane-backend:${{ github.event.release.tag_name }}
          elif [ "${{ env.TARGET_BRANCH }}" == "master" ]; then
            TAG=${{ secrets.DOCKERHUB_USERNAME }}/plane-backend:latest
          else
            TAG=${{ env.BACKEND_TAG }}
          fi
          echo "BACKEND_TAG=${TAG}" >> $GITHUB_ENV

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          driver: ${{ env.BUILDX_DRIVER }}
          version: ${{ env.BUILDX_VERSION }}
          endpoint: ${{ env.BUILDX_ENDPOINT }}

      - name: Check out the repo
        uses: actions/checkout@v4

      - name: Build and Push Backend to Docker Hub
        uses: docker/build-push-action@v5.1.0
        with:
          context: ./apiserver
          file: ./apiserver/Dockerfile.api
          platforms: ${{ env.BUILDX_PLATFORMS }}
          push: true
          tags: ${{ env.BACKEND_TAG }}
        env:
          DOCKER_BUILDKIT: 1
          DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
          DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}

  branch_build_push_proxy:
    if: ${{ needs.branch_build_setup.outputs.build_proxy == 'true' || github.event_name == 'workflow_dispatch' || github.event_name == 'release' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
    runs-on: ubuntu-20.04
    needs: [branch_build_setup]
    env:
      PROXY_TAG: ${{ secrets.DOCKERHUB_USERNAME }}/plane-proxy:${{ needs.branch_build_setup.outputs.gh_branch_name }}
      TARGET_BRANCH: ${{ needs.branch_build_setup.outputs.gh_branch_name }}
      BUILDX_DRIVER: ${{ needs.branch_build_setup.outputs.gh_buildx_driver }}
      BUILDX_VERSION: ${{ needs.branch_build_setup.outputs.gh_buildx_version }}
      BUILDX_PLATFORMS: ${{ needs.branch_build_setup.outputs.gh_buildx_platforms }}
      BUILDX_ENDPOINT: ${{ needs.branch_build_setup.outputs.gh_buildx_endpoint }}
    steps:
      - name: Set Proxy Docker Tag
        run: |
          if [ "${{ github.event_name }}" == "release" ]; then
            TAG=${{ secrets.DOCKERHUB_USERNAME }}/plane-proxy:stable,${{ secrets.DOCKERHUB_USERNAME }}/plane-proxy:${{ github.event.release.tag_name }}
          elif [ "${{ env.TARGET_BRANCH }}" == "master" ]; then
            TAG=${{ secrets.DOCKERHUB_USERNAME }}/plane-proxy:latest
          else
            TAG=${{ env.PROXY_TAG }}
          fi
          echo "PROXY_TAG=${TAG}" >> $GITHUB_ENV

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          driver: ${{ env.BUILDX_DRIVER }}
          version: ${{ env.BUILDX_VERSION }}
          endpoint: ${{ env.BUILDX_ENDPOINT }}

      - name: Check out the repo
        uses: actions/checkout@v4

      - name: Build and Push Plane-Proxy to Docker Hub
        uses: docker/build-push-action@v5.1.0
        with:
          context: ./nginx
          file: ./nginx/Dockerfile
          platforms: ${{ env.BUILDX_PLATFORMS }}
          tags: ${{ env.PROXY_TAG }}
          push: true
        env:
          DOCKER_BUILDKIT: 1
          DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
          DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}