name: SAAS Pipeline

# CI/CD workflow for building, publishing, mirroring, signing container images and building release binaries.
# Actions are pinned to specific SHAs to reduce supply-chain risk. This workflow triggers on tag push events.

permissions:
  contents: read
  packages: write      # for GHCR push
  id-token: write      # for Cosign Keyless (OIDC) Signing

on:
    push:
        tags:
            - "[0-9]+.[0-9]+.[0-9]+-s.[0-9]+"

concurrency:
  group: ${{ github.ref }}
  cancel-in-progress: true

jobs:
    pre-run:
        runs-on: ubuntu-latest
        permissions: write-all
        steps:
            - name: Configure AWS credentials
              uses: aws-actions/configure-aws-credentials@v6
              with:
                  role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_ROLE_NAME }}
                  role-duration-seconds: 3600
                  aws-region: ${{ secrets.AWS_REGION }}

            - name: Verify AWS identity
              run: aws sts get-caller-identity

            - name: Start EC2 instances
              run: |
                  aws ec2 start-instances --instance-ids ${{ secrets.EC2_INSTANCE_ID_ARM_RUNNER }}
                  echo "EC2 instances started"


    release-arm:
        name: Build and Release (ARM64)
        runs-on: [self-hosted, linux, arm64, us-east-1]
        needs: [pre-run]
        if: >-
            ${{
                needs.pre-run.result == 'success'
            }}
        # Job-level timeout to avoid runaway or stuck runs
        timeout-minutes: 120
        env:
          # Target images
          AWS_IMAGE: ${{ secrets.aws_account_id }}.dkr.ecr.us-east-1.amazonaws.com/${{ github.event.repository.name }}

        steps:
            - name: Checkout code
              uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

            - name: Download MaxMind GeoLite2 databases
              env:
                MAXMIND_LICENSE_KEY: ${{ secrets.MAXMIND_LICENSE_KEY }}
              run: |
                echo "Downloading MaxMind GeoLite2 databases..."

                # Download GeoLite2-Country
                curl -L "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&license_key=${MAXMIND_LICENSE_KEY}&suffix=tar.gz" \
                  -o GeoLite2-Country.tar.gz

                # Download GeoLite2-ASN
                curl -L "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-ASN&license_key=${MAXMIND_LICENSE_KEY}&suffix=tar.gz" \
                  -o GeoLite2-ASN.tar.gz

                # Extract the .mmdb files
                tar -xzf GeoLite2-Country.tar.gz --strip-components=1 --wildcards '*.mmdb'
                tar -xzf GeoLite2-ASN.tar.gz --strip-components=1 --wildcards '*.mmdb'

                # Verify files exist
                if [ ! -f "GeoLite2-Country.mmdb" ]; then
                  echo "ERROR: Failed to download GeoLite2-Country.mmdb"
                  exit 1
                fi

                if [ ! -f "GeoLite2-ASN.mmdb" ]; then
                  echo "ERROR: Failed to download GeoLite2-ASN.mmdb"
                  exit 1
                fi

                # Clean up tar files
                rm -f GeoLite2-Country.tar.gz GeoLite2-ASN.tar.gz

                echo "MaxMind databases downloaded successfully"
                ls -lh GeoLite2-*.mmdb

            - name: Monitor storage space
              run: |
                  THRESHOLD=75
                  USED_SPACE=$(df / | grep / | awk '{ print $5 }' | sed 's/%//g')
                  echo "Used space: $USED_SPACE%"
                  if [ "$USED_SPACE" -ge "$THRESHOLD" ]; then
                      echo "Used space is below the threshold of 75% free. Running Docker system prune."
                      echo y | docker system prune -a
                  else
                      echo "Storage space is above the threshold. No action needed."
                  fi

            - name: Configure AWS credentials
              uses: aws-actions/configure-aws-credentials@v6
              with:
                  role-to-assume: arn:aws:iam::${{ secrets.aws_account_id }}:role/${{ secrets.AWS_ROLE_NAME }}
                  role-duration-seconds: 3600
                  aws-region: ${{ secrets.AWS_REGION }}

            - name: Login to Amazon ECR
              id: login-ecr
              uses: aws-actions/amazon-ecr-login@v2

            - name: Extract tag name
              id: get-tag
              run: echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
              shell: bash

            - name: Update version in package.json
              run: |
                  TAG=${{ env.TAG }}
                  sed -i "s/export const APP_VERSION = \".*\";/export const APP_VERSION = \"$TAG\";/" server/lib/consts.ts
                  cat server/lib/consts.ts
              shell: bash

            - name: Build and push Docker images (Docker Hub - ARM64)
              run: |
                  TAG=${{ env.TAG }}
                  make build-saas tag=$TAG
                  echo "Built & pushed ARM64 images to: ${{ env.AWS_IMAGE }}:${TAG}"
              shell: bash

    post-run:
        needs: [pre-run, release-arm]
        if: >-
            ${{
                always() &&
                needs.pre-run.result == 'success' &&
                (needs.release-arm.result == 'success' || needs.release-arm.result == 'skipped' || needs.release-arm.result == 'failure')
            }}
        runs-on: ubuntu-latest
        permissions: write-all
        steps:
            - name: Configure AWS credentials
              uses: aws-actions/configure-aws-credentials@v6
              with:
                  role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_ROLE_NAME }}
                  role-duration-seconds: 3600
                  aws-region: ${{ secrets.AWS_REGION }}

            - name: Verify AWS identity
              run: aws sts get-caller-identity

            - name: Stop EC2 instances
              run: |
                  aws ec2 stop-instances --instance-ids ${{ secrets.EC2_INSTANCE_ID_ARM_RUNNER }}
                  echo "EC2 instances stopped"
