---
name: Publish Release

on:
  workflow_dispatch:
  release:
    types: [published]
  schedule:
    - cron: "0 2 * * *"

permissions:
  contents: read

jobs:
  init:
    name: Initialize build
    runs-on: ubuntu-latest
    outputs:
      tag: ${{ steps.tag.outputs.tag }}
      branch_build: ${{ steps.tag.outputs.branch_build }}
    steps:
      - uses: actions/checkout@v4.1.7
      - name: Get tag
        id: tag
        # yamllint disable rule:line-length
        run: |
          if [[ "${{ github.event_name }}" = "release" ]]; then
            TAG="${{ github.event.release.tag_name}}"
            BRANCH_BUILD="false"
          else
            TAG=$(cat esphome/const.py | sed -n -E "s/^__version__\s+=\s+\"(.+)\"$/\1/p")
            today="$(date --utc '+%Y%m%d')"
            TAG="${TAG}${today}"
            BRANCH=${GITHUB_REF#refs/heads/}
            if [[ "$BRANCH" != "dev" ]]; then
              TAG="${TAG}-${BRANCH}"
              BRANCH_BUILD="true"
            else
              BRANCH_BUILD="false"
            fi
          fi
          echo "tag=${TAG}" >> $GITHUB_OUTPUT
          echo "branch_build=${BRANCH_BUILD}" >> $GITHUB_OUTPUT
        # yamllint enable rule:line-length

  deploy-pypi:
    name: Build and publish to PyPi
    if: github.repository == 'esphome/esphome' && github.event_name == 'release'
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    steps:
      - uses: actions/checkout@v4.1.7
      - name: Set up Python
        uses: actions/setup-python@v5.1.0
        with:
          python-version: "3.x"
      - name: Set up python environment
        env:
          ESPHOME_NO_VENV: 1
        run: script/setup
      - name: Build
        run: |-
          pip3 install build
          python3 -m build
      - name: Publish
        uses: pypa/gh-action-pypi-publish@v1.9.0

  deploy-docker:
    name: Build ESPHome ${{ matrix.platform }}
    if: github.repository == 'esphome/esphome'
    permissions:
      contents: read
      packages: write
    runs-on: ubuntu-latest
    needs: [init]
    strategy:
      fail-fast: false
      matrix:
        platform:
          - linux/amd64
          - linux/arm/v7
          - linux/arm64
    steps:
      - uses: actions/checkout@v4.1.7
      - name: Set up Python
        uses: actions/setup-python@v5.1.0
        with:
          python-version: "3.9"

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3.6.1
      - name: Set up QEMU
        if: matrix.platform != 'linux/amd64'
        uses: docker/setup-qemu-action@v3.2.0

      - name: Log in to docker hub
        uses: docker/login-action@v3.3.0
        with:
          username: ${{ secrets.DOCKER_USER }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      - name: Log in to the GitHub container registry
        uses: docker/login-action@v3.3.0
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build docker
        uses: ./.github/actions/build-image
        with:
          platform: ${{ matrix.platform }}
          target: docker
          baseimg: docker
          suffix: ""
          version: ${{ needs.init.outputs.tag }}

      - name: Build ha-addon
        uses: ./.github/actions/build-image
        with:
          platform: ${{ matrix.platform }}
          target: hassio
          baseimg: hassio
          suffix: "hassio"
          version: ${{ needs.init.outputs.tag }}

      - name: Build lint
        uses: ./.github/actions/build-image
        with:
          platform: ${{ matrix.platform }}
          target: lint
          baseimg: docker
          suffix: lint
          version: ${{ needs.init.outputs.tag }}

      - name: Sanitize platform name
        id: sanitize
        run: |
          echo "${{ matrix.platform }}" | sed 's|/|-|g' > /tmp/platform
          echo name=$(cat /tmp/platform) >> $GITHUB_OUTPUT

      - name: Upload digests
        uses: actions/upload-artifact@v4.3.4
        with:
          name: digests-${{ steps.sanitize.outputs.name }}
          path: /tmp/digests
          retention-days: 1

  deploy-manifest:
    name: Publish ESPHome ${{ matrix.image.title }} to ${{ matrix.registry }}
    runs-on: ubuntu-latest
    needs:
      - init
      - deploy-docker
    if: github.repository == 'esphome/esphome'
    permissions:
      contents: read
      packages: write
    strategy:
      fail-fast: false
      matrix:
        image:
          - title: "ha-addon"
            target: "hassio"
            suffix: "hassio"
          - title: "docker"
            target: "docker"
            suffix: ""
          - title: "lint"
            target: "lint"
            suffix: "lint"
        registry:
          - ghcr
          - dockerhub
    steps:
      - uses: actions/checkout@v4.1.7

      - name: Download digests
        uses: actions/download-artifact@v4.1.8
        with:
          pattern: digests-*
          path: /tmp/digests
          merge-multiple: true

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

      - name: Log in to docker hub
        if: matrix.registry == 'dockerhub'
        uses: docker/login-action@v3.3.0
        with:
          username: ${{ secrets.DOCKER_USER }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      - name: Log in to the GitHub container registry
        if: matrix.registry == 'ghcr'
        uses: docker/login-action@v3.3.0
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Generate short tags
        id: tags
        run: |
          output=$(docker/generate_tags.py \
            --tag "${{ needs.init.outputs.tag }}" \
            --suffix "${{ matrix.image.suffix }}" \
            --registry "${{ matrix.registry }}")
          echo $output
          for l in $output; do
            echo $l >> $GITHUB_OUTPUT
          done

      - name: Create manifest list and push
        working-directory: /tmp/digests/${{ matrix.image.target }}/${{ matrix.registry }}
        run: |
          docker buildx imagetools create $(jq -Rcnr 'inputs | . / "," | map("-t " + .) | join(" ")' <<< "${{ steps.tags.outputs.tags}}") \
            $(printf '${{ steps.tags.outputs.image }}@sha256:%s ' *)

  deploy-ha-addon-repo:
    if: github.repository == 'esphome/esphome' && needs.init.outputs.branch_build == 'false'
    runs-on: ubuntu-latest
    needs:
      - init
      - deploy-manifest
    steps:
      - name: Trigger Workflow
        uses: actions/github-script@v7.0.1
        with:
          github-token: ${{ secrets.DEPLOY_HA_ADDON_REPO_TOKEN }}
          script: |
            let description = "ESPHome";
            if (context.eventName == "release") {
              description = ${{ toJSON(github.event.release.body) }};
            }
            github.rest.actions.createWorkflowDispatch({
              owner: "esphome",
              repo: "home-assistant-addon",
              workflow_id: "bump-version.yml",
              ref: "main",
              inputs: {
                version: "${{ needs.init.outputs.tag }}",
                content: description
              }
            })