name: Build and Push prebuilt tools container

on:
  push:
    paths:
      - 'include/version.mk'
      - 'tools/**'
      - '.github/workflows/build-tools.yml'
      - '.github/workflows/push-containers.yml'
      - '.github/workflows/Dockerfile.tools'
      - 'toolchain/**'
      - '.github/workflows/build.yml'
      - '.github/workflows/toolchain.yml'
      - '.github/workflows/Dockerfile.toolchain'

permissions:
  contents: read

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

jobs:
  determine-container-info:
    name: Determine needed info to push containers
    if: ${{ github.repository_owner  == 'openwrt' }}
    runs-on: ubuntu-latest
    outputs:
      owner-lc: ${{ steps.generate-owner-lc.outputs.owner-lc }}
      container-tag: ${{ steps.determine-container-tag.outputs.container-tag }}

    steps:
      - name: Set lower case owner name
        id: generate-owner-lc
        env:
          OWNER: ${{ github.repository_owner }}
        run: |
          echo "owner-lc=${OWNER,,}" >> "$GITHUB_OUTPUT"

      # Per branch tools container tag
      # By default stick to latest
      # For official test targetting openwrt stable branch
      # Get the branch or parse the tag and push dedicated tools containers
      # Any branch that will match this pattern openwrt-[0-9][0-9].[0-9][0-9]
      # will refresh the tools container with the matching tag.
      # (example branch openwrt-22.03 -> tools:openwrt-22.03)
      # (example branch openwrt-22.03-test -> tools:openwrt-22.03)
      - name: Determine tools container tag
        id: determine-container-tag
        run: |
          CONTAINER_TAG=latest

          if [ ${{ github.ref_type }} == "branch" ]; then
            if echo "${{ github.ref_name }}" | grep -q -E 'openwrt-[0-9][0-9]\.[0-9][0-9]'; then
              CONTAINER_TAG="$(echo ${{ github.ref_name }} | sed 's/^\(openwrt-[0-9][0-9]\.[0-9][0-9]\).*/\1/')"
            fi
          elif [ ${{ github.ref_type }} == "tag" ]; then
            if echo "${{ github.ref_name }}" | grep -q -E 'v[0-9][0-9]\.[0-9][0-9]\..+'; then
              CONTAINER_TAG=openwrt-"$(echo ${{ github.ref_name }} | sed 's/v\([0-9][0-9]\.[0-9][0-9]\)\..\+/\1/')"
            fi
          fi

          echo "Container tag to push for tools and toolchain is $CONTAINER_TAG"
          echo "container-tag=$CONTAINER_TAG" >> "$GITHUB_OUTPUT"

  build-linux-buildbot:
    name: Build tools with buildbot container
    if: ${{ github.repository_owner  == 'openwrt' }}
    uses: ./.github/workflows/build-tools.yml
    with:
      generate_prebuilt_artifacts: true

  push-tools-container:
    needs: [ determine-container-info, build-linux-buildbot ]
    if: ${{ github.repository_owner  == 'openwrt' }}
    name: Push prebuilt tools container
    runs-on: ubuntu-latest

    permissions:
      contents: read
      packages: write

    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          path: 'openwrt'

      - name: Download prebuilt tools from build job
        uses: actions/download-artifact@v3
        with:
          name: linux-buildbot-prebuilt-tools
          path: openwrt

      - name: Extract prebuild tools
        working-directory: openwrt
        run: tar -xf tools.tar

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push
        uses: docker/build-push-action@v3
        with:
          context: openwrt
          push: true
          tags: ghcr.io/${{ needs.determine-container-info.outputs.owner-lc }}/tools:${{ needs.determine-container-info.outputs.container-tag }}
          file: openwrt/.github/workflows/Dockerfile.tools

  determine-targets:
    name: Set targets
    if: ${{ github.repository_owner  == 'openwrt' }}
    runs-on: ubuntu-latest
    outputs:
      target: ${{ steps.find_targets.outputs.target }}

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set targets
        id: find_targets
        run: |
          export TARGETS="$(perl ./scripts/dump-target-info.pl targets 2>/dev/null \
            | awk '{ print $1 }')"

          JSON='['
          FIRST=1
          for TARGET in $TARGETS; do
            TUPLE='{"target":"'"$(echo $TARGET | cut -d "/" -f 1)"'","subtarget":"'"$(echo $TARGET | cut -d "/" -f 2)"'"}'
            [[ $FIRST -ne 1 ]] && JSON="$JSON"','
            JSON="$JSON""$TUPLE"
            FIRST=0
          done
          JSON="$JSON"']'

          echo -e "\n---- targets ----\n"
          echo "$JSON"
          echo -e "\n---- targets ----\n"

          echo "target=$JSON" >> $GITHUB_OUTPUT

  build:
    name: Build Target Toolchain
    if: ${{ github.repository_owner  == 'openwrt' }}
    needs: [ determine-targets, push-tools-container ]
    permissions:
      contents: read
      packages: read
    strategy:
      fail-fast: False
      matrix:
        include: ${{fromJson(needs.determine-targets.outputs.target)}}
    uses: ./.github/workflows/build.yml
    with:
      target: ${{ matrix.target }}
      subtarget: ${{ matrix.subtarget }}
      build_toolchain: true
      build_external_toolchain: true
      upload_external_toolchain: true

  push-toolchain-container:
    name: Push Target Toolchain container
    if: ${{ github.repository_owner  == 'openwrt' }}
    needs: [ determine-container-info, determine-targets, build ]
    runs-on: ubuntu-latest

    strategy:
      fail-fast: False
      matrix:
        include: ${{fromJson(needs.determine-targets.outputs.target)}}

    permissions:
      contents: read
      packages: write

    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          path: 'openwrt'

      - name: Download external toolchain from build job
        uses: actions/download-artifact@v3
        with:
          name: ${{ matrix.target }}-${{ matrix.subtarget }}-external-toolchain
          path: openwrt

      - name: Find external toolchain name
        id: get-toolchain-name
        working-directory: openwrt
        run: |
          TOOLCHAIN_NAME=$(ls | grep toolchain-${{ matrix.target }}-${{ matrix.subtarget }})
          echo "toolchain-name=$TOOLCHAIN_NAME" >> $GITHUB_OUTPUT

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push
        uses: docker/build-push-action@v3
        with:
          context: openwrt
          push: true
          tags: ghcr.io/${{ needs.determine-container-info.outputs.owner-lc }}/toolchain:${{ matrix.target }}-${{ matrix.subtarget }}-${{ needs.determine-container-info.outputs.container-tag }}
          file: openwrt/.github/workflows/Dockerfile.toolchain
          build-args: |
            OWNER_LC=${{ needs.determine-container-info.outputs.owner-lc }}
            CONTAINER_TAG=${{ needs.determine-container-info.outputs.container-tag }}
            TOOLCHAIN_NAME=${{ steps.get-toolchain-name.outputs.toolchain-name }}
