name: Preview (build)
on:
  pull_request:
    types: [opened, synchronize, reopened, closed]

jobs:
  build-application:
    name: Build PR image
    runs-on: ubuntu-latest
    if: ${{ github.event_name != 'pull_request' || github.event.action != 'closed' }}
    outputs:
      tags: ${{ steps.meta.outputs.tags }}
    steps:
      - name: Checkout git repo
        uses: actions/checkout@v4
      - run: |
          . versions
          echo "elixir=$elixir" >> $GITHUB_ENV
          echo "otp=$otp" >> $GITHUB_ENV
          echo "ubuntu=$ubuntu" >> $GITHUB_ENV
      # --- START build assets
      - name: Install Erlang & Elixir
        uses: erlef/setup-beam@v1
        with:
          otp-version: ${{ env.otp }}
          elixir-version: ${{ env.elixir }}
      - name: Cache Mix
        uses: actions/cache@v4
        with:
          path: |
            deps
            _build
          key: ${{ runner.os }}-mix-${{ env.elixir }}-${{ env.otp }}-${{ hashFiles('**/mix.lock') }}
          restore-keys: |
            ${{ runner.os }}-mix-${{ env.elixir }}-${{ env.otp }}-
      # Note: we need to get Phoenix and LV because package.json points to them directly
      - name: Install mix dependencies
        run: mix deps.get
      - name: Install Node
        uses: actions/setup-node@v4
        with:
          node-version: "20.x"
      - name: Cache npm dependencies
        uses: actions/cache@v4
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-
      - name: Clean generated assets
        run: rm -rf static/{js,css}
      - name: Install npm dependencies
        run: npm ci --prefix assets
      - name: Build assets
        run: npm run deploy --prefix assets
        # --- END build assets
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2
      - name: Generate UUID image name
        id: uuid
        run: echo "UUID_TAG_APP=livebook-$(uuidgen --time)" >> $GITHUB_ENV
      - name: Docker metadata
        id: meta
        uses: docker/metadata-action@v3
        with:
          images: registry.uffizzi.com/${{ env.UUID_TAG_APP }}
          tags: type=raw,value=60d
      - name: Build and Push Image to registry.uffizzi.com ephemeral registry
        uses: docker/build-push-action@v2
        with:
          push: true
          context: .
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          file: ./Dockerfile
          cache-from: type=gha
          cache-to: type=gha,mode=max
          build-args: |
            BASE_IMAGE=hexpm/elixir:${{ env.elixir }}-erlang-${{ env.otp }}-ubuntu-${{ env.ubuntu }}
            VARIANT=default

  render-compose-file:
    name: Render Docker Compose file
    # Pass output of this workflow to another triggered by `workflow_run` event.
    runs-on: ubuntu-latest
    needs:
      - build-application
    steps:
      - name: Checkout git repo
        uses: actions/checkout@v4
      - name: Render Compose File
        run: |
          APP_IMAGE=$(echo ${{ needs.build-application.outputs.tags }})
          export APP_IMAGE
          # Render simple template from environment variables.
          envsubst < ./.github/uffizzi/docker-compose.uffizzi.yml > docker-compose.rendered.yml
          cat docker-compose.rendered.yml
      - name: Upload Rendered Compose File as Artifact
        uses: actions/upload-artifact@v3
        with:
          name: preview-spec
          path: docker-compose.rendered.yml
          retention-days: 2
      - name: Serialize PR Event to File
        run: |
          cat << EOF > event.json
          ${{ toJSON(github.event) }}
          EOF
      - name: Upload PR Event as Artifact
        uses: actions/upload-artifact@v3
        with:
          name: preview-spec
          path: event.json
          retention-days: 2

  delete-preview:
    name: Mark preview for deletion
    runs-on: ubuntu-latest
    if: ${{ github.event.action == 'closed' }}
    steps:
      # If this PR is closing, we will not render a compose file nor pass it to the next workflow.
      - name: Serialize PR Event to File
        run: |
          cat << EOF > event.json
          ${{ toJSON(github.event) }}
          EOF
      - name: Upload PR Event as Artifact
        uses: actions/upload-artifact@v3
        with:
          name: preview-spec
          path: event.json
          retention-days: 2
