name: CI Apps

on:
  push:
    branches: [ develop, main ]
    tags: [ 'apps-v*' ]
  pull_request:

env:
  UNA_WORKSPACE: ${{ github.env.GITHUB_WORKSPACE }}
  DOCKER_DRIVER: overlay2

jobs:
  prepare:
    runs-on: ubuntu-latest
    container: python:3.11-slim
    outputs:
      apps: ${{ steps.generate.outputs.apps }}
    steps:
      - name: Setup GIT
        run: apt update && apt install -y git jq

      - name: Checkout
        uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
        with:
          fetch-depth: 0

      - name: Generate app list
        id: generate
        run: |
          output=$(python3 .github/scripts/generate-app-list.py)
          echo "apps=$(echo "$output" | jq -c .apps)" >> $GITHUB_OUTPUT

  cmake-build:
    runs-on: ubuntu-latest
    container: xanderhendriks/stm32cubeide:16.0
    needs: prepare
    strategy:
      matrix:
        app: ${{ fromJson(needs.prepare.outputs.apps) }}
    steps:
      - name: Setup GIT
        run: apt update && apt install -y git python3-full python3-pip python-is-python3 cmake

      - name: Checkout
        uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
        with:
          fetch-depth: 0

      - name: Install scripts requirements
        run: python3 -m pip install --break-system-packages -r Utilities/Scripts/app_packer/requirements.txt

      - name: Build app ${{ matrix.app }} with CMake
        run: |
          export PATH=/tmp/bin:`find /opt/st/stm32cubeide_* -type f -name arm-none-eabi-objcopy | head -n 1 | xargs dirname`:$PATH
          export PATH=/tmp/bin:`find /opt/st/stm32cubeide_* -type f -name make | head -n 1 | xargs dirname`:$PATH
          chmod +x $(find /opt/st/stm32cubeide_* -type f -name make | head -n 1)
          chmod +x $(find /opt/st/stm32cubeide_* -type f -name arm-none-eabi-gcc | head -n 1)
          chmod +x $(find /opt/st/stm32cubeide_* -type f -name arm-none-eabi-g++ | head -n 1)
          cd Examples/Apps/${{ matrix.app }}/Software/App*/*-CMake
          export UNA_SDK=$GITHUB_WORKSPACE
          mkdir -p build
          cd build
          cmake ..
          make -j$(nproc)

      - name: Upload app artifacts
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
        with:
          name: app-${{ matrix.app }}
          path: Examples/Apps/${{ matrix.app }}/Software/App*/*-CMake/build/*.uapp

  release:
    runs-on: ubuntu-latest
    needs: [cmake-build]
    if: startsWith(github.ref, 'refs/tags/apps-v')
    permissions:
      contents: write
    steps:
      - name: Install dependencies
        run: |
          sudo apt update
          sudo apt install -y curl jq git
          curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
          sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg
          echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
          sudo apt update
          sudo apt install gh -y

      - name: Checkout
        uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
        with:
          fetch-depth: 0

      - name: Download all artifacts
        uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
        with:
          path: artifacts

      - name: Prepare release zip
        env:
          REF_NAME: ${{ github.ref_name }}
        run: |
          mkdir -p temp/apps
          for dir in artifacts/app-*; do
            app=$(basename "$dir" | sed 's/^app-//')
            mkdir -p "temp/apps/$app"
            find "$dir" -name "*.uapp" -exec cp {} "temp/apps/$app/" \;
          done
          cd temp/apps
          zip -r "../../una-apps-${REF_NAME}.zip" .

      - id: create_release
        name: Release
        uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
        with:
          files: |
            una-apps-${{ github.ref_name }}.zip
          generate_release_notes: true

      - name: Make release immutable
        run: |
          gh release edit ${{ github.ref_name }} --draft=false
        env:
          GITHUB_TOKEN: ${{ github.token }}

      - id: get_slack_params
        name: Get required parameters for slack notification
        run: |
          RELEASE_JSON=$(gh release view ${{ github.ref_name }} --json body,author,createdAt,name,url)
          echo "body<<EOF" >> $GITHUB_OUTPUT
          echo "$RELEASE_JSON" | jq -r '.body' >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT
          echo "author=$(echo "$RELEASE_JSON" | jq -r '.author.login')" >> $GITHUB_OUTPUT
          echo "created_at=$(echo "$RELEASE_JSON" | jq -r '.createdAt')" >> $GITHUB_OUTPUT
          echo "name=$(echo "$RELEASE_JSON" | jq -r '.name')" >> $GITHUB_OUTPUT
          echo "url=$(echo "$RELEASE_JSON" | jq -r '.url')" >> $GITHUB_OUTPUT
        env:
          GITHUB_TOKEN: ${{ github.token }}

      - id: prepare_slack_payload
        name: Prepare Slack payload
        run: |
          BODY="${{ steps.get_slack_params.outputs.body }}"
          BODY=$(echo "$BODY" | sed 's/@\([a-zA-Z0-9_-]*\)/<https:\/\/github.com\/\1|@\1>/g')
          BODY=$(echo "$BODY" | sed 's/^## \([^$]*\)$/*\1*/')
          BODY=$(echo "$BODY" | sed 's/^* /- /')
          BODY=$(echo "$BODY" | sed 's/\*\*Full Changelog\*\*:/ *Full Changelog*\n/')
          if [ ${#BODY} -gt 2700 ]; then BODY="${BODY:0:2700}"$'\n''...'; fi
          PAYLOAD=$(jq -c -n --arg name "${{ steps.get_slack_params.outputs.name }}" --arg tag "${{ github.ref_name }}" --arg body "$BODY" --arg author "${{ steps.get_slack_params.outputs.author }}" --arg created "${{ steps.get_slack_params.outputs.created_at }}" --arg url "${{ steps.get_slack_params.outputs.url }}" '{
            text: (":roller_coaster: *UNA Apps*: " + $name),
            blocks: [
              {
                type: "section",
                text: {
                  type: "mrkdwn",
                  text: ("-------- :roller_coaster: *UNA Apps* --------\n*" + $name + "* (tag: " + $tag + ")\n\n" + $body + "\n\n:bust_in_silhouette: *Author*: " + $author + "\n:date: *Created*: " + $created + "\n\n:link: *Download*: " + $url)
                }
              }
            ]
          }')
          echo "payload<<EOF" >> $GITHUB_OUTPUT
          echo "$PAYLOAD" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: Notify Slack
        uses: slackapi/slack-github-action@37ebaef184d7626c5f204ab8d3baff4262dd30f0 # v1.27.0
        with:
          channel-id: ${{ secrets.SLACK_CHANNEL_ID }}
          payload: ${{ steps.prepare_slack_payload.outputs.payload }}
        env:
          SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
