name: Gitea Branch PR, Cloudflare DNS, README generation, & Docker Deployment

on:
  push:
    branches-ignore:
      - main
    paths:
      - './docker-compose.yml'

jobs:
  check-and-create-pr:
    name: Check and Create PR
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Install tea
        uses: supplypike/setup-bin@v4
        with:
          uri: 'https://gitea.com/gitea/tea/releases/download/v0.9.2/tea-0.9.2-linux-amd64'
          name: 'tea'
          version: '0.9.2'
      
      - name: Check if open PR exists
        id: check-opened-pr-step
        continue-on-error: true
        run: |
          echo "Logging into Gitea..."
          tea login add --name gitea-rinoa --url ${{ secrets.RINOA_GITEA_URL }} --user gitea-sonarqube-bot --password "${{ secrets.BOT_GITEA_PASSWORD }}" --token ${{ secrets.BOT_GITEA_TOKEN }}
          echo "Setting default login to gitea-rinoa..."
          tea login default gitea-rinoa
          echo "Checking for existing PRs..."
          pr_exists=$(tea pr list --repo ${{ github.repository }} --state open --fields index,title,head | egrep ${{ github.ref_name }} | tail -1 | wc -l)
          echo ${pr_exists}
          echo "exists=$pr_exists" >> $GITHUB_OUTPUT

      - name: Create PR
        if: ${{ steps.check-opened-pr-step.outputs.exists == '0' }}
        run: |
          echo "Creating PR for branch: ${{ github.ref_name }}"
          tea pr c -r ${{ github.repository }} -t "Automated PR for ${{ github.ref_name }}" -d "Automatically created PR for branch: ${{ github.ref_name }}" -a ${{ github.actor }}

  docker-compose-test:
    name: Docker Compose Test
    needs: [check-and-create-pr]
    runs-on: ubuntu-latest
    env:
      VAULT_ADDR: ${{ secrets.RINOA_VAULT_ADDR }}
      VAULT_TOKEN: ${{ secrets.VAULT_GITEA_TOKEN }}
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      
      - name: Install jq
        uses: dcarbone/install-jq-action@v3.0.1

      - name: Install Vault
        uses: cpanato/vault-installer@main
        with:
          vault-release: '1.18.3'

      - name: Generate .env file for linting
        run: |
          vault kv get -format=json rinoa-docker/env | jq -r '.data.data' | jq -r 'keys[] as $k | "\($k)='\''\(.[$k])'\''"' > .env

      - name: Docker Compose Lint
        uses: yu-ichiro/spin-up-docker-compose-action@v1
        with:
          file: docker-compose.yml
          pull: true
          pull-opts: --dry-run
          up: true
          up-opts: --dry-run -d --remove-orphans
        env:
          DOCKER_HOST: tcp://dockerproxy:2375

  cloudflare-dns-setup:
    name: Cloudflare DNS Setup
    needs: [docker-compose-test]
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install jq
        uses: dcarbone/install-jq-action@v3.0.1

      - name: Install yq
        uses: dcarbone/install-yq-action@v1
      
      - name: Install flarectl
        uses: supplypike/setup-bin@v4
        with:
          uri: 'https://github.com/cloudflare/cloudflare-go/releases/download/v0.113.0/flarectl_0.113.0_linux_amd64.tar.gz'
          name: 'flarectl'
          version: '0.113.0'

      - name: Grab Subdomains from Docker Compose & Cloudflare
        id: grab-subdomains
        env:
          CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
          CF_API_EMAIL: ${{ secrets.CF_API_EMAIL }}
        run: |
          echo "Grabbing subdomains from docker-compose.yml..."
          yq '.services[].labels.swag_url' docker-compose.yml | egrep -v 'null' | sed -e 's|"||g' | awk -F'.' '{print $1}' | sort > compose_subdomains.txt
          echo "Grabbing subdomains from Cloudflare..."
          flarectl --json dns list --zone "trez.wtf" --type=CNAME --content "trez.wtf" | jq '.[].Name' | sed -e 's|"||g' | awk -F"." '{print $1}' | sort > cloudflare_subdomains.txt
          
      - name: Compare Subdomains
        id: compare-subdomains
        uses: LouisBrunner/diff-action@v2.2.0
        with:
          old: compose_subdomains.txt
          new: cloudflare_subdomains.txt
          mode: addition
          tolerance: mixed-better
          output: domain_compare.txt

      - name: Create Subdomains
        if: steps.compare-subdomains.outputs.output != ''
        continue-on-error: true
        env:
          CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
          CF_API_EMAIL: ${{ secrets.CF_API_EMAIL }}
        run: |
          cat domain_compare.txt | egrep '^-[a-z]' | sed -e 's|-||g' | while read -r subdomain; do
            echo "Creating $subdomain.trez.wtf..."
            flarectl dns create --zone "trez.wtf" --name "${subdomain}" --type=CNAME --content "trez.wtf" --proxy true
          done

  regenerate-readme:
    name: Update README
    runs-on: ubuntu-latest
    needs: [cloudflare-dns-setup]
    outputs:
      pr-pushed: ${{ steps.commit-readme.outputs.pushed }}
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install yq
        uses: dcarbone/install-yq-action@v1
      
      - name: Generate service list
        run: |
          yq '.services | to_entries | map({"service": .key, "image": .value.image})' docker-compose.yml > services.yml

      - name: Generate Markdown Table
        uses: gazab/create-markdown-table@v1
        id: service-table
        with:
          file: ./services.yml

      - name: Regenerate README
        run: |
          echo "# List of Services" > README.md
          echo -e "\n\n" >> README.md
          echo "${{ steps.service-table.outputs.table }}" >> README.md

      - name: Add/Commit README.md
        id: commit-readme
        uses: EndBug/add-and-commit@v9
        with:
          message: "chore: Update README"
          add: "README.md"

  pr-merge:
    name: PR Merge
    needs: [regenerate-readme]
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      
      - name: Install tea
        uses: supplypike/setup-bin@v4
        with:
          uri: 'https://gitea.com/gitea/tea/releases/download/v0.9.2/tea-0.9.2-linux-amd64'
          name: 'tea'
          version: '0.9.2'

      - name: PR Merge
        id: pr_merge
        run: |
          tea login add --name gitea-rinoa --url ${{ secrets.RINOA_GITEA_URL }} --user gitea-sonarqube-bot --password "${{ secrets.BOT_GITEA_PASSWORD }}" --token ${{ secrets.BOT_GITEA_TOKEN }}
          tea login default gitea-rinoa
          pr_index=$(tea pr ls --repo ${{ github.repository }} --state open --fields index,title,head,state --output csv | egrep ${{ gitea.ref_name }} | awk -F, '{print $1}' | sed -e 's|"||g')
          tea pr m --repo ${{ github.repository }} --title "Auto Merge of PR #${pr_index} - ${{ gitea.ref_name }}" --message "Merged by ${{ gitea.actor }}" --output table ${pr_index}

  docker-compose-deploy:
    name: Deploy via Docker Compose
    runs-on: ubuntu-latest
    needs: [pr-merge]
    env:
      VAULT_ADDR: ${{ secrets.RINOA_VAULT_ADDR }}
      VAULT_TOKEN: ${{ secrets.VAULT_GITEA_TOKEN }}
      DOCKER_HOST: tcp://dockerproxy:2375
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          ref: main

      - name: Install Vault
        uses: cpanato/vault-installer@main

      - name: Generate .env file for deployment
        run: |
           vault kv get -format=json rinoa-docker/env | jq -r '.data.data' | jq -r 'keys[] as $k | "\($k)='\''\(.[$k])'\''"' > .env

      - name: Docker Compose Deployment
        uses: keatonLiu/docker-compose-remote-action@v1.2
        with: 
          ssh_user: gitea-deploy
          ssh_host: 192.168.1.254
          ssh_host_public_key: ${{ secrets.RINOA_GITEA_PUBLIC_SSH_KEY }}
          ssh_private_key: ${{ secrets.RINOA_GITEA_PRIVATE_SSH_KEY }}
          docker_compose_file: docker-compose.yml
