name: Build and Deploy
on:
    # Nightly build
    schedule:
        - cron: "0 9 * * *"
    # Release build
    release:
        types: [published]
    # Manual nightly & release
    workflow_dispatch:
        inputs:
            mode:
                description: What type of build to trigger. Release builds MUST be ran from the `master` branch.
                required: true
                default: nightly
                type: choice
                options:
                    - nightly
                    - release
            macos:
                description: Build macOS
                required: true
                type: boolean
                default: true
            windows:
                description: Build Windows
                required: true
                type: boolean
                default: true
            linux:
                description: Build Linux
                required: true
                type: boolean
                default: true
            deploy:
                description: Deploy artifacts
                required: true
                type: boolean
                default: true
run-name: Element ${{ inputs.mode != 'release' && github.event_name != 'release' && 'Nightly' || 'Desktop' }}
concurrency: ${{ github.workflow }}
env:
    R2_BUCKET: ${{ vars.R2_BUCKET }}
jobs:
    prepare:
        uses: ./.github/workflows/build_prepare.yaml
        with:
            config: element.io/${{ inputs.mode || (github.event_name == 'release' && 'release') || 'nightly' }}
            version: ${{ (inputs.mode != 'release' && github.event_name != 'release') && 'develop' || '' }}
            nightly: ${{ inputs.mode != 'release' && github.event_name != 'release' }}
        secrets:
            CF_R2_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
            CF_R2_TOKEN: ${{ secrets.CF_R2_TOKEN }}

    windows:
        if: github.event_name != 'workflow_dispatch' || inputs.windows
        needs: prepare
        name: Windows ${{ matrix.arch }}
        strategy:
            matrix:
                arch: [x86, x64]
        uses: ./.github/workflows/build_windows.yaml
        secrets: inherit
        with:
            sign: true
            deploy-mode: true
            arch: ${{ matrix.arch }}
            version: ${{ needs.prepare.outputs.nightly-version }}

    macos:
        if: github.event_name != 'workflow_dispatch' || inputs.macos
        needs: prepare
        name: macOS
        uses: ./.github/workflows/build_macos.yaml
        secrets: inherit
        with:
            sign: true
            deploy-mode: true
            base-url: https://packages.element.io/${{ needs.prepare.outputs.packages-dir }}
            version: ${{ needs.prepare.outputs.nightly-version }}

    # We do not put these calls into deploy-mode as we do not want it to add to the packages.element.io artifact
    # We ship this build via reprepro only
    linux:
        if: github.event_name != 'workflow_dispatch' || inputs.linux
        needs: prepare
        name: Linux ${{ matrix.arch }} (sqlcipher system)
        strategy:
            matrix:
                arch: [amd64, arm64]
        uses: ./.github/workflows/build_linux.yaml
        with:
            arch: ${{ matrix.arch }}
            config: ${{ needs.prepare.outputs.config }}
            sqlcipher: system
            version: ${{ needs.prepare.outputs.nightly-version }}

    # We ship the static build via static tarball only
    linux_static:
        if: github.event_name != 'workflow_dispatch' || inputs.linux
        needs: prepare
        name: Linux (sqlcipher static)
        uses: ./.github/workflows/build_linux.yaml
        with:
            arch: amd64
            deploy-mode: true
            config: ${{ needs.prepare.outputs.config }}
            sqlcipher: static
            version: ${{ needs.prepare.outputs.nightly-version }}

    # This deploy job only handles Windows, macOS & linux_static as those are stateless and static.
    # Linux will be deployed via reprepro after it, but we list it as a dependency to abort if it fails.
    deploy:
        needs:
            - prepare
            - macos
            - linux
            - linux_static
            - windows
        runs-on: ubuntu-latest
        name: Deploy
        if: |
            (
                github.event_name != 'workflow_dispatch' &&
                github.event.release.prerelease != true
            ) || (
                always() && !failure() && !cancelled() && inputs.deploy &&
                (inputs.macos || inputs.windows || inputs.linux)
            )
        environment: packages.element.io
        steps:
            - name: Download artifacts
              uses: actions/download-artifact@v3
              with:
                  name: packages.element.io
                  path: packages.element.io

            - name: Deploy artifacts
              run: |
                  aws s3 cp --recursive packages.element.io/ s3://$R2_BUCKET/$DEPLOYMENT_DIR --endpoint-url $R2_URL --region auto
              env:
                  AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
                  AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_TOKEN }}
                  R2_URL: ${{ vars.CF_R2_S3_API }}
                  DEPLOYMENT_DIR: ${{ needs.prepare.outputs.packages-dir }}

            - name: Notify packages.element.io of new files
              uses: peter-evans/repository-dispatch@26b39ed245ab8f31526069329e112ab2fb224588 # v2
              with:
                  token: ${{ secrets.ELEMENT_BOT_TOKEN }}
                  repository: vector-im/packages.element.io
                  event-type: packages-index

    reprepro:
        needs:
            - linux
            # We queue this after the other deploy stage as we want to abort if that fails
            - deploy
        name: Run reprepro ${{ matrix.arch }}
        strategy:
            matrix:
                arch: [amd64, arm64]
        if: |
            (
                github.event_name != 'workflow_dispatch' &&
                github.event.release.prerelease != true
            ) || (
                always() && !failure() && !cancelled() && inputs.deploy && inputs.linux
            )
        uses: ./.github/workflows/reprepro.yaml
        secrets: inherit
        with:
            artifact-name: linux-${{ matrix.arch }}-sqlcipher-system