name: Release
on:
  push:
    branches:
      - master
  pull_request:
    paths:
      # Go
      - "go/**"
      - "!go/**.md"
      - ".goreleaser"
      - "go.*"
      - "**.go"
      # CI
      - ".github/workflows/release.yml"
      - "tool/publish-npm-package"
      # NPM package
      - "./js/packages/api"

jobs:
  semantic-release:
    name: Semantic release
    runs-on: ubuntu-latest
    outputs:
      new-release-published: ${{ steps.semantic.outputs.new_release_published }}
      release-version: ${{ steps.semantic.outputs.new_release_version }}
      android-changed: ${{ steps.changes.outputs.android }}
      ios-changed: ${{ steps.changes.outputs.ios }}
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup asdf
        uses: asdf-vm/actions/setup@9cd779f40fe38688dd19505ccbc4eaaf018b44e7
        with:
          asdf_version: 0.16.7

      - name: Setup node
        working-directory: berty-bridge-expo
        run: |
          asdf plugin add nodejs
          asdf install nodejs
          echo "NODE_VERSION=$(asdf current nodejs | xargs | cut -d ' ' -f 6)" >> $GITHUB_ENV

      - name: Set nodejs as global exec
        run: asdf set -u nodejs ${{ env.NODE_VERSION }}

      - name: Semantic Release
        uses: cycjimmy/semantic-release-action@v4
        id: semantic
        with:
          working_directory: ./berty-bridge-expo/mobile
          extra_plugins: |
            semantic-release-expo
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Check changed paths
        if: steps.semantic.outputs.new_release_published == 'true'
        uses: dorny/paths-filter@v3
        id: changes
        with:
          filters: |
            android:
              - "go/**"
              - "!go/**.md"
              - "go.*"
              - "**.go"
              - "berty-bridge-expo/**"
              - ".github/workflows/android.yml"
              - ".github/workflows/release.yml"
            ios:
              - "go/**"
              - "!go/**.md"
              - "go.*"
              - "**.go"
              - "berty-bridge-expo/**"
              - ".github/workflows/ios.yml"
              - ".github/workflows/release.yml"

      - name: Upload patched app.json
        if: steps.semantic.outputs.new_release_published == 'true'
        uses: actions/upload-artifact@v4
        with:
          name: app-json
          path: berty-bridge-expo/mobile/app.json

  build-android:
    name: Build for Android
    needs: semantic-release
    if: needs.semantic-release.outputs.new-release-published == 'true' && needs.semantic-release.outputs.android-changed == 'true'
    uses: ./.github/workflows/android.yml
    with:
      app-json-artifact: app-json
    secrets: inherit

  build-ios:
    name: Build for iOS
    needs: semantic-release
    if: needs.semantic-release.outputs.new-release-published == 'true' && needs.semantic-release.outputs.ios-changed == 'true'
    uses: ./.github/workflows/ios.yml
    with:
      app-json-artifact: app-json
    secrets: inherit

  release-on-stores:
    name: Release on stores
    runs-on: ubuntu-latest
    if: github.event_name == 'push' && github.ref == 'refs/heads/master'
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup asdf
        uses: asdf-vm/actions/setup@9cd779f40fe38688dd19505ccbc4eaaf018b44e7
        with:
          asdf_version: 0.16.7

      - name: Setup jq
        run: |
          asdf plugin add jq
          asdf install jq

      - name: Get last commit message
        env:
          EVENT: ${{ toJson(github.event) }}
        run: |
          echo "$EVENT" > $RUNNER_TEMP/event
          echo "commit_message=$(jq '.
          | select(.commits != null)
          | .after as $last_commit
          | .commits
          | map(select(.id == $last_commit))[0].message' $RUNNER_TEMP/event)" >> $GITHUB_ENV

      - name: Dispatch event to release repo
        uses: actions/github-script@v6
        with:
          github-token: ${{ secrets.REPOSITORY_DISPATCH }}
          script: |
            await github.rest.repos.createDispatchEvent({
              owner: 'berty',
              repo: 'release-on-stores',
              event_type: 'release',
              client_payload: {"commit_message":${{ env.commit_message }}},
            })

  post-semantic-release:
    needs: semantic-release
    #if: needs.semantic-release.outputs.new-release-published == 'true'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Unshallow
        run: git fetch --prune --unshallow

      - name: Setup asdf
        uses: asdf-vm/actions/setup@9cd779f40fe38688dd19505ccbc4eaaf018b44e7
        with:
          asdf_version: 0.16.7

      - name: Setup go
        run: |
          asdf plugin add golang
          asdf install golang

      - name: Setup node
        if: needs.semantic-release.outputs.new-release-published == 'true'
        working-directory: js
        run: |
          asdf plugin add nodejs
          asdf install nodejs

      - name: "Publish npm package: @berty/api (Real)"
        if: needs.semantic-release.outputs.new-release-published == 'true'
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
        continue-on-error: true
        working-directory: tool/publish-npm-package
        run: go run . -path=../../js/packages/api -version=${{ needs.semantic-release.outputs.release-version }}
      # Next step also sets up a .npmrc file for automatic publishing to npm

      - name: "Publish npm package: @berty/api (DryRun)"
        if: needs.semantic-release.outputs.new-release-published != 'true'
        working-directory: tool/publish-npm-package
        run: go run . -path=../../js/packages/api -version=0.0.0 -dry-run

      - name: Register version on pkg.go.dev
        if: needs.semantic-release.outputs.new-release-published == 'true'
        run: |
          package=$(cat go.mod | grep ^module | awk '{print $2}')
          version=v${{ needs.semantic-release.outputs.release-version }}
          url=https://proxy.golang.org/${package}/@v/${version}.info
          set -x +e
          curl -i $url

  build-asset:
    needs: semantic-release
    name: build asset
    runs-on: ${{ matrix.config.runs-on }}
    strategy:
      matrix:
        config: [
            # @FIXME(gfanton): latest ubuntu version broke `Install Linux Dependencies` step
            { runs-on: "ubuntu-latest", goos: "linux" },
            { runs-on: "macos-latest", goos: "darwin" },
            { runs-on: "windows-latest", goos: "windows" },
            # TODO: bertyguy
          ]
    env:
      OSXCROSS_DIR: /home/runner/work/osxcross
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Load variables from file
        uses: antifree/json-to-variables@v1.0.1
        with:
          filename: .github/workflows/utils/variables.json

      - name: Setup asdf
        if: matrix.config.goos != 'windows'
        uses: asdf-vm/actions/setup@9cd779f40fe38688dd19505ccbc4eaaf018b44e7
        with:
          asdf_version: 0.16.7

      - name: Setup go (Posix)
        if: matrix.config.goos != 'windows'
        run: |
          asdf plugin add golang
          asdf install golang
          echo "go_version=$(asdf current golang | xargs | cut -d ' ' -f 6)" >> $GITHUB_ENV

      - name: Get go version (Windows)
        if: matrix.config.goos == 'windows'
        shell: bash
        run: echo "go_version=$(cat .tool-versions | grep '^golang [0-9]\+\.[0-9]\+\.[0-9]\+.*$' | cut -d ' ' -f 6)" >> $GITHUB_ENV

      - name: Setup go (Windows)
        if: matrix.config.goos == 'windows'
        uses: actions/setup-go@v3
        with:
          go-version: ${{ env.go_version }}

      - name: Cache go modules
        uses: actions/cache@v4
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ env.go_version }}-${{ env.json_cache-versions_go }}-${{ hashFiles('go/**/go.sum') }}
          restore-keys: ${{ runner.os }}-go-${{ env.go_version }}-${{ env.json_cache-versions_go }}-

      - name: Install Linux Dependencies
        if: matrix.config.goos == 'linux'
        run: |
          echo 'deb http://security.ubuntu.com/ubuntu noble-security main' | sudo tee -a /etc/apt/sources.list
          sudo apt update
          sudo apt-cache policy libssl-dev
          sudo apt install -f libssl-dev
          sudo apt install -f gcc-multilib g++-multilib gcc-mingw-w64 clang
          sudo apt install -f -y libgl1 libglx-mesa0 libgl1-mesa-dev xorg-dev
          mkdir ../../osxcross
          git clone https://github.com/plentico/osxcross-target.git ../../osxcross/target

      - name: Run GoReleaser (DryRun)
        uses: goreleaser/goreleaser-action@v6
        if: needs.semantic-release.outputs.new-release-published != 'true'
        with:
          version: "~> v2"
          args: release --clean -f .github/workflows/utils/.goreleaser.${{ matrix.config.goos }}.yml --skip=publish --snapshot

      - name: Run GoReleaser (Publish)
        uses: goreleaser/goreleaser-action@v6
        if: needs.semantic-release.outputs.new-release-published == 'true'
        with:
          version: "~> v2"
          args: release --clean -f .github/workflows/utils/.goreleaser.${{ matrix.config.goos }}.yml --snapshot
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Dist/ directory listing (Posix)
        if: matrix.config.goos != 'windows'
        run: ls -lah dist

      - name: Dist/ directory listing (Windows)
        if: matrix.config.goos == 'windows'
        run: Get-ChildItem -Recurse dist
