name: Publish
run-name: Publish Repository Actions 🛫
on:
  release:
    types:
      - published
    branches:
      - master
      - 'release/**'
permissions:
  contents: read
concurrency:
  group: '${{ github.workflow }} @ ${{ github.head_ref || github.ref }}'
  cancel-in-progress: true
jobs:
  check-tag:
    name: Check Release Tag
    if: github.repository_owner == 'obsproject'
    runs-on: ubuntu-24.04
    outputs:
      validTag: ${{ steps.check.outputs.validTag }}
      flatpakMatrix: ${{ steps.check.outputs.flatpakMatrix }}
      updateChannel: ${{ steps.check.outputs.updateChannel }}
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: recursive
          fetch-depth: 0
          set-safe-directory: ${{ env.GITHUB_WORKSPACE }}

      - name: Check Release Tag ☑️
        id: check
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          : Check Release Tag ☑️
          if [[ "${RUNNER_DEBUG}" ]]; then set -x; fi
          shopt -s extglob

          case "${GITHUB_REF_NAME}" in
            +([0-9]).+([0-9]).+([0-9]) )
              lastPreRelease="$(gh release list --exclude-drafts --limit 10 --json "publishedAt,tagName,isPrerelease" \
                --jq '[.[] | select(.isPrerelease == true)] | first | .tagName')"
              currentRelease="${GITHUB_REF_NAME}"
              isPreReleaseAhead=false

              printf '%s\n%s\n' "${currentRelease}" "${lastPreRelease}" | sort --version-sort --reverse --check=quiet &&
                isPreReleaseAhead=false || isPreReleaseAhead=true

              # Edge case: Sort considers the non-suffixed version older than a suffixed one
              if ${isPreReleaseAhead} && [[ "${currentRelease}" == "${lastPreRelease//-*}" ]]; then
                isPreReleaseAhead=false
              fi

              echo 'validTag=true' >> $GITHUB_OUTPUT
              if ! ${isPreReleaseAhead}; then
                echo 'flatpakMatrix=["beta", "stable"]' >> $GITHUB_OUTPUT
              else
                echo 'flatpakMatrix=["stable"]' >> $GITHUB_OUTPUT
              fi
              echo 'updateChannel=stable' >> $GITHUB_OUTPUT
              ;;
            +([0-9]).+([0-9]).+([0-9])-@(beta|rc)*([0-9]) )
              echo 'validTag=true' >> $GITHUB_OUTPUT
              echo 'flatpakMatrix=["beta"]' >> $GITHUB_OUTPUT
              echo 'updateChannel=beta' >> $GITHUB_OUTPUT
              ;;
            *) echo 'validTag=false' >> $GITHUB_OUTPUT ;;
          esac

  flatpak-publish:
    name: Flathub 📦
    needs: check-tag
    if: github.repository_owner == 'obsproject' && fromJSON(needs.check-tag.outputs.validTag)
    runs-on: ubuntu-24.04
    defaults:
      run:
        shell: bash
    env:
      FLATPAK_BUILD_SHARE_PATH: flatpak_app/files/share
      TWITCH_CLIENTID: ${{ secrets.TWITCH_CLIENT_ID }}
      TWITCH_HASH: ${{ secrets.TWITCH_HASH }}
      RESTREAM_CLIENTID: ${{ secrets.RESTREAM_CLIENTID }}
      RESTREAM_HASH: ${{ secrets.RESTREAM_HASH }}
      YOUTUBE_CLIENTID: ${{ secrets.YOUTUBE_CLIENTID }}
      YOUTUBE_CLIENTID_HASH: ${{ secrets.YOUTUBE_CLIENTID_HASH }}
      YOUTUBE_SECRET: ${{ secrets.YOUTUBE_SECRET }}
      YOUTUBE_SECRET_HASH: ${{ secrets.YOUTUBE_SECRET_HASH }}
    container:
      image: ghcr.io/flathub-infra/flatpak-github-actions:freedesktop-25.08
      options: --privileged
      volumes:
        - /usr/local/lib/android:/to_clean/android
        - /opt/hostedtoolcache/CodeQL:/to_clean/codeql
        - /usr/local/.ghcup:/to_clean/ghcup
        - /opt/hostedtoolcache/Python:/to_clean/python
        - /usr/share/swift:/to_clean/swift
        - /usr/share/dotnet:/to_clean/dotnet
    strategy:
      matrix:
        branch: ${{ fromJSON(needs.check-tag.outputs.flatpakMatrix) }}
    steps:
      - name: Prepare build space
        shell: bash
        run: |
          : Prepare build space

          echo ::group::Available storage
          df -h
          echo ::endgroup::

          echo ::group::Remove Android stuff
          rm -rf /to_clean/android/*
          echo ::endgroup::

          echo ::group::Remove CodeQL stuff
          rm -rf /to_clean/codeql/*
          echo ::endgroup::

          echo ::group::Remove GHCup stuff
          rm -rf /to_clean/ghcup/*
          echo ::endgroup::

          echo ::group::Remove Python stuff
          rm -rf /to_clean/python/*
          echo ::endgroup::

          echo ::group::Remove Swift stuff
          rm -rf /to_clean/swift/*
          echo ::endgroup::

          echo ::group::Remove .NET stuff
          rm -rf /to_clean/dotnet/*
          echo ::endgroup::

          echo ::group::Available storage
          df -h
          echo ::endgroup::

      - uses: actions/checkout@v4
        with:
          submodules: recursive
          fetch-depth: 0
          set-safe-directory: ${{ env.GITHUB_WORKSPACE }}

      - name: Set Up Environment 🔧
        id: setup
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          : Set Up Environment 🔧
          if [[ "${RUNNER_DEBUG}" ]]; then set -x; fi

          git config --global --add safe.directory "${GITHUB_WORKSPACE}"

          cache_key='flatpak-builder-${{ hashFiles('build-aux/com.obsproject.Studio.json') }}'
          cache_ref='master'
          read -r id key size unit created accessed <<< \
            "$(gh cache list --ref "refs/heads/${cache_ref}" --key "${cache_key}-x86_64" | head -1)"

          if [[ "${key}" ]]; then
            echo "cacheHit=true" >> $GITHUB_OUTPUT
          else
            echo "cacheHit=false" >> $GITHUB_OUTPUT
          fi

          echo "cacheKey=${cache_key}" >> $GITHUB_OUTPUT
          echo "commitHash=${GITHUB_SHA:0:9}" >> $GITHUB_OUTPUT

      - name: Validate Flatpak manifest
        uses: ./.github/actions/flatpak-builder-lint
        with:
          artifact: manifest
          path: build-aux/com.obsproject.Studio.json

      - name: Build Flatpak Manifest
        uses: flatpak/flatpak-github-actions/flatpak-builder@b8a638469ea7ec62844d7b6e487b697e6f249576
        with:
          build-bundle: false
          manifest-path: ${{ github.workspace }}/build-aux/com.obsproject.Studio.json
          cache: ${{ fromJSON(steps.setup.outputs.cacheHit) }}
          cache-key: ${{ steps.setup.outputs.cacheKey }}
          mirror-screenshots-url: https://dl.flathub.org/media
          branch: ${{ matrix.branch }}

      - name: Validate AppStream
        uses: ./.github/actions/flatpak-builder-lint
        with:
          artifact: appstream
          path: ${{ env.FLATPAK_BUILD_SHARE_PATH }}/metainfo/com.obsproject.Studio.metainfo.xml

      - name: Verify Icon and Metadata in app-info
        working-directory: ${{ env.FLATPAK_BUILD_SHARE_PATH }}
        run: |
          : Verify Icon and Metadata in app-info
          test -f app-info/icons/flatpak/128x128/com.obsproject.Studio.png || { echo "::error::Missing 128x128 icon in app-info"; exit 1; }
          test -f app-info/xmls/com.obsproject.Studio.xml.gz || { echo "::error::Missing com.obsproject.Studio.xml.gz in app-info"; exit 1; }

      - name: Validate build directory
        uses: ./.github/actions/flatpak-builder-lint
        with:
          artifact: builddir
          path: flatpak_app

      - name: Validate repository
        uses: ./.github/actions/flatpak-builder-lint
        with:
          artifact: repo
          path: repo

      - name: Publish to Flathub Beta
        uses: flatpak/flatpak-github-actions/flat-manager@b8a638469ea7ec62844d7b6e487b697e6f249576
        if: ${{ matrix.branch == 'beta' }}
        with:
          flat-manager-url: https://hub.flathub.org/
          repository: beta
          token: ${{ secrets.FLATHUB_BETA_TOKEN }}
          build-log-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

      - name: Publish to Flathub
        uses: flatpak/flatpak-github-actions/flat-manager@b8a638469ea7ec62844d7b6e487b697e6f249576
        if: ${{ matrix.branch == 'stable' }}
        with:
          flat-manager-url: https://hub.flathub.org/
          repository: stable
          token: ${{ secrets.FLATHUB_TOKEN }}
          build-log-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

  steam-upload:
    name: Upload Steam Builds 🚂
    needs: check-tag
    if: github.repository_owner == 'obsproject' && fromJSON(needs.check-tag.outputs.validTag)
    runs-on: macos-15
    steps:
      - uses: actions/checkout@v4
      - uses: ./.github/actions/steam-upload
        with:
          steamSecret: ${{ secrets.STEAM_SHARED_SECRET }}
          steamUser: ${{ secrets.STEAM_USER }}
          steamPassword: ${{ secrets.STEAM_PASSWORD }}
          workflowSecret: ${{ github.token }}
          tagName: ${{ github.ref_name }}
          preview: false

  windows-patches:
    name: Create Windows Patches 🩹
    needs: check-tag
    if: github.repository_owner == 'obsproject' && fromJSON(needs.check-tag.outputs.validTag)
    runs-on: windows-2022
    steps:
      - uses: actions/checkout@v4
      - uses: ./.github/actions/windows-patches
        with:
          tagName: ${{ github.ref_name }}
          workflowSecret: ${{ github.token }}
          channel: ${{ needs.check-tag.outputs.updateChannel }}
          gcsAccessKeyId: ${{ secrets.GCS_ACCESS_KEY_ID }}
          gcsAccessKeySecret: ${{ secrets.GCS_ACCESS_KEY_SECRET }}
