name: Publish @notesnook/desktop

on:
  workflow_dispatch:
    inputs:
      publish-apple:
        type: boolean
        required: true
        default: true
        description: "Publish on Mac App Store?"
      publish-snap:
        type: boolean
        required: true
        default: true
        description: "Publish on Snapcraft?"
      publish-github:
        type: boolean
        required: true
        default: true
        description: "Publish on GitHub releases?"

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Setup Node
        uses: actions/setup-node@v3
        with:
          node-version: 16.x
          cache: "npm"
          cache-dependency-path: |
            apps/mobile/package-lock.json
            apps/web/package-lock.json
            packages/core/package-lock.json
            packages/crypto/package-lock.json
            packages/crypto-worker/package-lock.json
            packages/editor-mobile/package-lock.json
            packages/editor/package-lock.json
            packages/logger/package-lock.json
            packages/streamable-fs/package-lock.json
            packages/theme/package-lock.json

      - name: Install packages
        run: |
          npm i --ignore-scripts --prefer-offline --no-audit
          npx lerna bootstrap --ignore=@notesnook/mobile -- --prefer-offline --no-audit

      - name: Setup environment
        run: |
          echo "NX_CLOUD_ACCESS_TOKEN=${{ secrets.NX_CLOUD_ACCESS_TOKEN }}" >> $GITHUB_ENV

      - name: Generate desktop build
        run: npx nx build:desktop @notesnook/web

      - name: Archive build artifact
        uses: actions/upload-artifact@v3
        with:
          name: build
          path: apps/web/build/**/*

      - name: Collect app metadata
        id: app_metadata
        working-directory: ./apps/web/desktop
        run: |
          echo ::set-output name=app_version::$(cat package.json | jq -r .version)

      - name: Package desktop build
        run: |
          zip -r ./notesnook_build_v${{ steps.app_metadata.outputs.app_version }}.zip ./apps/web/build/
          echo "Build folder archived to ./notesnook_build_v${{ steps.app_metadata.outputs.app_version }}.zip"

      - name: Upload desktop build
        uses: softprops/action-gh-release@v1
        if: inputs.publish-github
        with:
          draft: true
          name: Notesnook Desktop v${{ steps.app_metadata.outputs.app_version }}
          tag_name: v${{ steps.app_metadata.outputs.app_version }}
          files: ./notesnook_build_v${{ steps.app_metadata.outputs.app_version }}.zip

  build-macos:
    name: Build for macOS
    needs: build
    runs-on: macos-12

    steps:
      - name: Check out Git repository
        uses: actions/checkout@v3

      - name: Setup notarization
        run: |
          mkdir -p ~/private_keys/
          echo '${{ secrets.api_key }}' > ~/private_keys/AuthKey_${{ secrets.api_key_id }}.p8

      - name: Collect app metadata
        id: app_metadata
        working-directory: ./apps/web/desktop
        run: |
          echo ::set-output name=apple_app_id::$(cat package.json | jq -r .appAppleId)
          echo ::set-output name=app_bundle_id::$(cat package.json | jq -r .build.appId)
          echo ::set-output name=app_version::$(cat package.json | jq -r .version)
          echo ::set-output name=bundle_version::$(cat package.json | jq -r .build.mac.bundleVersion)
        
      - name: Get App Store Version
        id: appstore
        uses: streetwriters/appstore-connect-app-version@develop
        with:
          app-id: ${{ steps.app_metadata.outputs.apple_app_id }}
          key-id: ${{ secrets.api_key_id }}
          issuer-id: ${{ secrets.api_key_issuer_id }}
          private-key-raw: ${{ secrets.api_key }}
          platform: "MAC_OS"

      - name: Setup Node
        uses: actions/setup-node@v3
        with:
          node-version: 16.x

      - name: Download build
        uses: actions/download-artifact@v3
        with:
          name: build
          path: ./apps/web/desktop/build

      - name: Install packages
        run: npm i
        working-directory: ./apps/web/desktop
      
      - name: Install provisioning profile
        run: echo "${{ secrets.MAC_PROVISIONING_PROFILE }}" | base64 --decode > embedded.provisionprofile
        working-directory: ./apps/web/desktop

      - name: Build app for Mac App Store
        if: inputs.publish-apple && steps.appstore.outputs.app-version-latest != steps.app_metadata.outputs.app_version
        env:
          CSC_LINK: ${{ secrets.mac_certs }}
          CSC_KEY_PASSWORD: ${{ secrets.mac_certs_password }}
        run: |
          npm run build:mas
          npx electron-builder --mac mas --universal -p never
        working-directory: ./apps/web/desktop

      - name: Build zip and dmg
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          CSC_LINK: ${{ secrets.mac_certs }}
          CSC_KEY_PASSWORD: ${{ secrets.mac_certs_password }}
          APPLE_API_KEY: ~/private_keys/AuthKey_${{ secrets.api_key_id }}.p8
          APPLE_API_KEY_ID: ${{ secrets.api_key_id }}
          APPLE_API_KEY_ISSUER: ${{ secrets.api_key_issuer_id }}
        run: |
          npm run build
          if [ ${{ inputs.publish-github }} == true ]; then
            npx electron-builder --mac zip dmg --arm64 --x64 -p always
          else
            npx electron-builder --mac zip dmg --arm64 --x64 -p never
          fi
        working-directory: ./apps/web/desktop

      - name: Deploy to Testflight
        if: inputs.publish-apple && steps.appstore.outputs.app-version-latest != steps.app_metadata.outputs.app_version
        env:
          API_KEY_ID: ${{ secrets.api_key_id }}
          API_KEY_ISSUER_ID: ${{ secrets.api_key_issuer_id }}
        run: |       
          package=$(find ./dist/mas-universal/notesnook*.pkg)

          echo "Uploading ${package} using altool..."

          xcrun altool --upload-package $package -t osx --apiKey $API_KEY_ID --apiIssuer $API_KEY_ISSUER_ID --apple-id ${{ steps.app_metadata.outputs.apple_app_id }} --bundle-id ${{ steps.app_metadata.outputs.app_bundle_id }} --bundle-short-version-string ${{ steps.app_metadata.outputs.app_version }} --bundle-version ${{ steps.app_metadata.outputs.bundle_version }}
        working-directory: ./apps/web/desktop

  build-linux:
    name: Build for Linux
    needs: build
    runs-on: ubuntu-22.04

    steps:
      - name: Check out Git repository
        uses: actions/checkout@v3

      - name: Setup Snapcraft Auth
        if: inputs.publish-snap
        run: echo "SNAPCRAFT_STORE_CREDENTIALS=${{ secrets.snapcraft_token }}" >> $GITHUB_ENV

      - name: Install Snapcraft
        uses: samuelmeuli/action-snapcraft@v1
        if: inputs.publish-snap
        
      - name: Setup Node
        uses: actions/setup-node@v3
        with:
          node-version: 16.x

      - name: Download build
        uses: actions/download-artifact@v3
        with:
          name: build
          path: ./apps/web/desktop/build

      - name: Install packages
        run: npm i
        working-directory: ./apps/web/desktop

      - name: Build Electron wrapper
        run: npm run build
        working-directory: ./apps/web/desktop

      - name: Build snap
        if: inputs.publish-snap
        run: |
          npx electron-builder --linux snap -p never
        working-directory: ./apps/web/desktop

      - name: Build AppImage deb and rpm
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          if [ ${{ inputs.publish-github }} == true ]; then
            npx electron-builder --linux AppImage deb rpm -p always
          else
            npx electron-builder --linux AppImage deb rpm -p never
          fi
        working-directory: ./apps/web/desktop

      - name: Publish on Snapcraft
        if: inputs.publish-snap
        run: |
          snapcraft upload --release=stable ./dist/notesnook_linux_amd64.snap
        working-directory: ./apps/web/desktop

  build-windows:
    name: Build for Windows
    needs: build
    runs-on: windows-latest

    steps:
      - name: Check out Git repository
        uses: actions/checkout@v3

      - name: Setup Node
        uses: actions/setup-node@v3
        with:
          node-version: 16.x

      - name: Download build
        uses: actions/download-artifact@v3
        with:
          name: build
          path: ./apps/web/desktop/build

      - name: Install packages
        run: npm i
        working-directory: ./apps/web/desktop

      - name: Build Electron wrapper
        run: npm run build
        working-directory: ./apps/web/desktop

      - name: Build app
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          if ($${{ inputs.publish-github }} -eq $true) {
            npx electron-builder --win --publish always
          } else {
            npx electron-builder --win --publish never
          }
        working-directory: ./apps/web/desktop