# Separate to the main build workflow for access to develop
# environment secrets, largely similar to build.yaml.
name: Build and Deploy develop
on:
    push:
        branches: [develop]
    repository_dispatch:
        types: [element-web-notify]
concurrency:
    group: ${{ github.repository_owner }}-${{ github.workflow }}-${{ github.ref_name }}
    cancel-in-progress: true
env:
    NX_DEFAULT_OUTPUT_STYLE: stream-without-prefixes
permissions: {}
jobs:
    build:
        name: "Build & Deploy develop.element.io"
        # Only respect triggers from our develop branch, ignore that of forks
        if: github.repository == 'element-hq/element-web'
        runs-on: ubuntu-24.04
        environment: develop
        permissions:
            checks: read
            pages: write
            deployments: write
        env:
            R2_BUCKET: "element-web-develop"
            R2_URL: ${{ vars.CF_R2_S3_API }}
            R2_PUBLIC_URL: "https://element-web-develop.element.io"
        steps:
            - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
              with:
                  persist-credentials: false

            - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
            - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
              with:
                  cache: "pnpm"
                  node-version: "lts/*"

            - name: Install Dependencies
              run: "./scripts/layered.sh"

            - name: Build, Package & Upload sourcemaps
              working-directory: apps/web
              run: "./scripts/ci_package.sh"
              env:
                  SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
                  SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
                  SENTRY_URL: ${{ secrets.SENTRY_URL }}
                  SENTRY_ORG: element
                  SENTRY_PROJECT: riot-web
                  # We only deploy the latest bundles to Cloudflare Pages and use _redirects to fallback to R2 for
                  # older ones. This redirect means that 'self' is insufficient in the CSP,
                  # and we have to add the R2 URL.
                  # Once Cloudflare redirects support proxying mode we will be able to ditch this.
                  # See Proxying in support table at https://developers.cloudflare.com/pages/platform/redirects
                  CSP_EXTRA_SOURCE: ${{ env.R2_PUBLIC_URL }}

            - run: mv dist/element-*.tar.gz dist/develop.tar.gz
              working-directory: apps/web

            - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
              with:
                  name: webapp
                  path: apps/web/dist/develop.tar.gz
                  retention-days: 1

            - name: Extract webapp
              run: |
                  mkdir _deploy
                  tar xf apps/web/dist/develop.tar.gz -C _deploy --strip-components=1

            - name: Copy config
              run: cp apps/web/element.io/develop/config.json _deploy/config.json

            - name: Populate 404.html
              run: echo "404 Not Found" > _deploy/404.html

            - name: Populate _headers
              run: cp .github/cfp_headers _deploy/_headers

            # Redirect requests for the develop tarball and the historical bundles to R2
            # We find the latest 100 bundle.css files and add their bundles to the redirects file
            # S3 has no sane way to get the age of a directory as they don't really exist
            - name: Populate _redirects
              run: |
                  {
                      echo "/develop.tar.gz $R2_PUBLIC_URL/develop.tar.gz 301"
                      aws s3api --region auto --endpoint-url $R2_URL list-objects-v2 --bucket $R2_BUCKET \
                          --query "sort_by(Contents[?ends_with(Key, '/bundle.css')], &LastModified)[-100:].Key" \
                          --prefix "bundles/" | jq -r '.[]' | grep -oE '[^\"].*\/\s*' | while read -r path ; do
                          echo "/${path}* $R2_PUBLIC_URL/${path}:splat 301"
                      done
                  } | tee _deploy/_redirects
              env:
                  AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
                  AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_TOKEN }}

            # We may be trying to deploy the same webapp bundles again, we need to ensure that the live bundles
            # are not present in the _redirects file and instead accessed directly from Cloudflare Pages.
            - name: Trim _redirects
              working-directory: _deploy
              run: |
                  find bundles -type d -mindepth 1 -maxdepth 1 -exec sed -i "\:{}:d" _redirects \;

            - name: Wait for other steps to succeed
              uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
              with:
                  ref: ${{ github.sha }}
                  running-workflow-name: "Build & Deploy develop.element.io"
                  repo-token: ${{ secrets.GITHUB_TOKEN }}
                  wait-interval: 10
                  check-regexp: ^((?!SonarCloud|SonarQube|issue|board|label|Release|prepare|GitHub Pages|Upload|Netlify|Report).)*$

            # We keep the latest develop.tar.gz on R2 instead of relying on the github artifact uploaded earlier
            # as the expires after 24h and requires auth to download.
            # Element Desktop's fetch script uses this tarball to fetch latest develop to build Nightlies.
            # Checksum algorithm specified as per https://developers.cloudflare.com/r2/examples/aws/aws-cli/
            - name: Deploy to R2
              run: |
                  aws s3 cp apps/web/dist/develop.tar.gz s3://$R2_BUCKET/develop.tar.gz --endpoint-url $R2_URL --region=auto --checksum-algorithm CRC32
                  aws s3 cp _deploy/ s3://$R2_BUCKET/ --recursive --endpoint-url $R2_URL --region=auto --checksum-algorithm CRC32
              env:
                  AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
                  AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_TOKEN }}

            - name: Deploy to Cloudflare Pages
              id: cfp
              uses: cloudflare/pages-action@f0a1cd58cd66095dee69bfa18fa5efd1dde93bca # v1
              with:
                  apiToken: ${{ secrets.CF_PAGES_TOKEN }}
                  accountId: ${{ secrets.CF_PAGES_ACCOUNT_ID }}
                  projectName: element-web-develop
                  directory: _deploy
                  gitHubToken: ${{ secrets.GITHUB_TOKEN }}

            - run: |
                  echo "Deployed to ${STEPS_CFP_OUTPUTS_URL}" >> $GITHUB_STEP_SUMMARY
              env:
                  STEPS_CFP_OUTPUTS_URL: ${{ steps.cfp.outputs.url }}
