name: Gitea Branch PR, Cloudflare DNS, README generation, & Docker Deployment on: workflow_dispatch: push: branches-ignore: - "main" - "renovate/**" paths: - "**/docker-compose.yml" env: FLARECTL_VERSION: "0.116.0" HC_VAULT_VERSION: "1.21.4" TEA_VERSION: "0.14.0" jobs: check-and-create-pr: name: Check and Create PR runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: fetch-depth: 1 - name: Gotify Notification uses: eikendev/gotify-action@ca0339b85ee8db9fda9c0718aaa7f95e17b3c617 # 0.0.4 with: gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}" gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}" notification_title: "GITEA: PR Check @ Rinoa" notification_message: "Checking for existing PR... 🔍" - name: PR Check/Creation uses: https://git.trez.wtf/Trez/gitea-auto-pr@main with: url: ${{ secrets.TREZ_GITEA_URL }} token: ${{ secrets.BOT_GITEA_TOKEN }} pr-label: docker-compose,manual assignee: ${{ github.actor }} - name: Gotify Notification uses: eikendev/gotify-action@ca0339b85ee8db9fda9c0718aaa7f95e17b3c617 # 0.0.4 with: gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}" gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}" notification_title: "GITEA: PR Check @ Rinoa" notification_message: "PR Check done 🎟️" generate-service-list: name: Generate list of added/modified/deleted services runs-on: ubuntu-latest needs: [check-and-create-pr] outputs: svc_deploy_list: ${{ steps.detect_services.outputs.docker_svc_list }} steps: - name: Checkout uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Fetch base branch run: | git fetch origin ${{ github.event.pull_request.base.ref }} - name: Gotify Notification uses: eikendev/gotify-action@ca0339b85ee8db9fda9c0718aaa7f95e17b3c617 # 0.0.4 with: gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}" gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}" notification_title: "GITEA: Services TBD" notification_message: "Generating list of services to deploy..." - name: Save both versions of docker-compose.yml run: | git show origin/main:docker-compose.yml > docker-compose-main.yml || touch docker-compose-main.yml cp docker-compose.yml docker-compose-head.yml - name: Detect added, deleted, and modified services id: detect_services run: | set +e # prevent failure on non-zero exit codes echo "Getting services from main and ${{ github.ref_name }}" yq '.services | keys | .[]' docker-compose-main.yml | sort > services_main.txt yq '.services | keys | .[]' docker-compose-head.yml | sort > services_head.txt echo "Creating list of service changes..." touch service_changes.txt # Detect newly added services comm -13 services_main.txt services_head.txt 2>/dev/null | while read service; do [ -n "$service" ] && echo "$service: added" >> service_changes.txt done # Detect removed services comm -23 services_main.txt services_head.txt 2>/dev/null | while read service; do [ -n "$service" ] && echo "$service: removed" >> service_changes.txt done # Detect modified services comm -12 services_main.txt services_head.txt 2>/dev/null | while read service; do yq ".services[\"$service\"]" docker-compose-main.yml > tmp_main.yml yq ".services[\"$service\"]" docker-compose-head.yml > tmp_head.yml if ! diff -q tmp_main.yml tmp_head.yml > /dev/null; then echo "$service: modified" >> service_changes.txt fi done echo "Detected service changes:" cat service_changes.txt || echo "None" # Separate categories safely added_svcs=$(grep -E ': added' service_changes.txt 2>/dev/null | cut -d':' -f1 | sort | uniq) modified_svcs=$(grep -E ': modified' service_changes.txt 2>/dev/null | cut -d':' -f1 | sort | uniq) removed_svcs=$(grep -E ': removed' service_changes.txt 2>/dev/null | cut -d':' -f1 | sort | uniq) # Gather list of modified/added services mod_svcs=$( (echo "$added_svcs"; echo "$modified_svcs") | tr ' ' '\n' | sort -u | grep -v '^$' || true) if [ -z "$mod_svcs" ]; then echo "No modified or added services detected." echo "docker_svc_list<> "$GITHUB_OUTPUT" echo "" >> "$GITHUB_OUTPUT" echo "EOF" >> "$GITHUB_OUTPUT" else echo "Modified/added services:" echo "$mod_svcs" # Include direct dependencies (only if head file exists) if [ -f docker-compose-head.yml ]; then echo "Resolving direct dependencies..." deps_list="" for svc in $mod_svcs; do deps=$(yq -r ".services[\"$svc\"].depends_on | keys | .[]" docker-compose-head.yml 2>/dev/null || true) if [ -n "$deps" ]; then echo "$svc depends on:" echo "$deps" deps_list="$deps_list $deps" fi done all_svcs=$( (echo "$mod_svcs"; echo "$deps_list") | tr ' ' '\n' | sort -u) else all_svcs="$mod_svcs" fi echo "Final service list (including direct dependencies):" echo "$all_svcs" echo "docker_svc_list<> "$GITHUB_OUTPUT" echo "$all_svcs" >> "$GITHUB_OUTPUT" echo "EOF" >> "$GITHUB_OUTPUT" fi # Output removed services separately echo "Removed services:" echo "${removed_svcs:-None}" echo "removed_svc_list<> "$GITHUB_OUTPUT" echo "$removed_svcs" >> "$GITHUB_OUTPUT" echo "EOF" >> "$GITHUB_OUTPUT" # Always exit cleanly exit 0 docker-compose-dry-run: name: Docker Compose Dry Run needs: [generate-service-list] runs-on: ubuntu-latest env: VAULT_ADDR: ${{ secrets.TREZ_VAULT_ADDR }} VAULT_TOKEN: ${{ secrets.VAULT_GITEA_TOKEN }} VAULT_NAMESPACE: "" RINOA_REGISTRY_PASSWORD: ${{ secrets.BOT_GITEA_PASSWORD }} DOCKER_SVC_LIST: ${{ needs.generate-service-list.outputs.svc_deploy_list }} steps: - name: Checkout uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Login to Docker Hub uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 with: username: ${{ secrets.DOCKERHUB_USER }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - name: Login to GitHub Container Registry uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 with: registry: ghcr.io username: ${{ secrets.GHCR_USER }} password: ${{ secrets.GHCR_LOGIN_TOKEN }} - name: Login to Private Gitea Registry uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 with: registry: git.trez.wtf username: ${{ secrets.BOT_GITEA_USER }} password: ${{ secrets.BOT_GITEA_PASSWORD }} - name: Gotify Notification uses: eikendev/gotify-action@ca0339b85ee8db9fda9c0718aaa7f95e17b3c617 # 0.0.4 with: gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}" gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}" notification_title: "GITEA: Docker Compose Dry Run @ Rinoa" notification_message: "Starting Docker Compose dry run..." - name: Generate .env from Hashicorp Vault uses: https://git.trez.wtf/Trez/hc-vault-env@main with: HC_VAULT_VERSION: ${{ env.HC_VAULT_VERSION }} HC_VAULT_ADDR: ${{ secrets.TREZ_VAULT_ADDR }} HC_VAULT_AUTH: token HC_VAULT_TOKEN: ${{ secrets.VAULT_GITEA_TOKEN }} HC_VAULT_SECRETS_PATH: rinoa-docker/env - name: Pre-pull/build service images in parallel continue-on-error: true uses: https://git.trez.wtf/Trez/docker-select-image-pull@main env: DOCKER_HOST: tcp://dockerproxy:2375 with: services: ${{ env.DOCKER_SVC_LIST }} compose_profile: "rinoa-apps" - name: Docker Compose Dry Run uses: hoverkraft-tech/compose-action@05da55b2bb8a5a759d1c4732095044bd9018c050 # v2.4.3 env: DOCKER_HOST: tcp://dockerproxy:2375 with: services: | ${{ needs.generate-service-list.outputs.svc_deploy_list }} up-flags: -d --remove-orphans --dry-run compose-flags: --dry-run --profile rinoa-apps services-log-level: debug - name: Gotify Notification uses: eikendev/gotify-action@ca0339b85ee8db9fda9c0718aaa7f95e17b3c617 # 0.0.4 with: gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}" gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}" notification_title: "GITEA: Docker Compose Dry Run @ Rinoa" notification_message: "Docker Compose dry run completed successfully." cloudflare-dns-setup: name: Cloudflare DNS Setup needs: [docker-compose-dry-run] runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: fetch-depth: 1 - name: Install flarectl uses: supplypike/setup-bin@8e3f88b4f143d9b5c3497f0fc12d45c83c123787 # v4.0.1 with: uri: https://github.com/cloudflare/cloudflare-go/releases/download/v${{ env.FLARECTL_VERSION }}/flarectl_${{ env.FLARECTL_VERSION }}_linux_amd64.tar.gz name: flarectl version: ${{ env.FLARECTL_VERSION }} - 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: | yq -r '.services[].labels.swag_url' docker-compose.yml | \ egrep -v 'null' | \ awk -F'.' '{print $1}' | \ sort > compose_subdomains.txt flarectl --json dns list \ --zone "trez.wtf" \ --type=CNAME \ --content "trez.wtf" \ | jq -r '.[].Name' | awk -F"." '{print $1}' | \ sort > cloudflare_subdomains.txt - name: Gotify Notification uses: eikendev/gotify-action@ca0339b85ee8db9fda9c0718aaa7f95e17b3c617 # 0.0.4 with: gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}" gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}" notification_title: "GITEA: Cloudflare Setup @ Rinoa" notification_message: "Starting Cloudflare DNS setup..." - name: Compare Subdomains id: compare-subdomains uses: LouisBrunner/diff-action@9ea7b75986aa27143ad4928974c98a5a1bd92170 # 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 - name: Gotify Notification uses: eikendev/gotify-action@ca0339b85ee8db9fda9c0718aaa7f95e17b3c617 # 0.0.4 with: gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}" gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}" notification_title: "GITEA: Cloudflare Setup @ Rinoa" notification_message: "Cloudflare DNS setup completed successfully." pr-merge: name: PR Merge needs: [generate-service-list, docker-compose-dry-run] if: github.ref != 'refs/heads/main' runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Install tea uses: supplypike/setup-bin@8e3f88b4f143d9b5c3497f0fc12d45c83c123787 # v4.0.1 with: uri: https://gitea.com/gitea/tea/releases/download/v${{ env.TEA_VERSION }}/tea-${{ env.TEA_VERSION }}-linux-amd64 name: tea version: ${{ env.TEA_VERSION }} - name: PR Merge id: pr_merge run: | tea login add \ --name gitea-rinoa \ --url "${{ secrets.TREZ_GITEA_URL }}" \ --user gitea-sonarqube-bot \ --password "${{ secrets.BOT_GITEA_PASSWORD }}" \ --token ${{ secrets.BOT_GITEA_TOKEN }} tea login default gitea-rinoa echo "Merging PR..." pr_index=$(tea pr ls \ --repo ${{ github.repository }} \ --state open --fields index,title,head,state \ --output csv | \ egrep ${{ github.ref_name }} | awk -F"," '{print $1}' | sed -e 's|"||g') tea pr m \ --repo ${{ github.repository }} \ --title "Auto Merge of PR ${pr_index} - ${{ github.ref_name }}" \ --message "Merged by ${{ github.actor }}" ${pr_index} echo "pr_index=${pr_index}" >> $GITHUB_OUTPUT - name: Gotify Notification uses: eikendev/gotify-action@ca0339b85ee8db9fda9c0718aaa7f95e17b3c617 # 0.0.4 with: gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}" gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}" notification_title: "GITEA: PR Merge Successful" notification_message: "PR #${{ steps.pr_merge.outputs.pr_index }} merged." docker-compose-deploy: name: Docker Compose Deployment runs-on: ubuntu-latest needs: [generate-service-list, docker-compose-dry-run, pr-merge] env: VAULT_ADDR: ${{ secrets.TREZ_VAULT_ADDR }} VAULT_TOKEN: ${{ secrets.VAULT_GITEA_TOKEN }} DOCKER_HOST: tcp://dockerproxy:2375 RINOA_REGISTRY_PASSWORD: ${{ secrets.BOT_GITEA_PASSWORD }} DOCKER_SVC_LIST: ${{ needs.generate-service-list.outputs.svc_deploy_list }} steps: - name: Checkout uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: ref: main - name: Login to Docker Hub uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 with: username: ${{ secrets.DOCKERHUB_USER }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - name: Login to GitHub Container Registry uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 with: registry: ghcr.io username: ${{ secrets.GHCR_USER }} password: ${{ secrets.GHCR_LOGIN_TOKEN }} - name: Login to Private Gitea Registry uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 with: registry: git.trez.wtf username: ${{ secrets.BOT_GITEA_USER }} password: ${{ secrets.BOT_GITEA_PASSWORD }} - name: Gotify Notification uses: eikendev/gotify-action@ca0339b85ee8db9fda9c0718aaa7f95e17b3c617 # 0.0.4 with: gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}" gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}" notification_title: "GITEA: Docker Compose Deployment @ Rinoa" notification_message: "Starting Docker Compose run..." - name: Generate .env from Hashicorp Vault uses: https://git.trez.wtf/Trez/hc-vault-env@main with: HC_VAULT_VERSION: ${{ env.HC_VAULT_VERSION }} HC_VAULT_ADDR: ${{ secrets.TREZ_VAULT_ADDR }} HC_VAULT_AUTH: token HC_VAULT_TOKEN: ${{ secrets.VAULT_GITEA_TOKEN }} HC_VAULT_SECRETS_PATH: rinoa-docker/env - name: Pre-pull/build service images in parallel uses: https://git.trez.wtf/Trez/docker-select-image-pull@main env: DOCKER_HOST: tcp://dockerproxy:2375 with: services: ${{ env.DOCKER_SVC_LIST }} compose_profile: "rinoa-apps" - name: Docker Compose Deployment uses: hoverkraft-tech/compose-action@05da55b2bb8a5a759d1c4732095044bd9018c050 # v2.4.3 env: DOCKER_HOST: tcp://dockerproxy:2375 with: services: | ${{ needs.generate-service-list.outputs.svc_deploy_list }} up-flags: -d --remove-orphans down-flags: --dry-run compose-flags: --profile rinoa-apps services-log-level: debug - name: Docker Compose Healthcheck uses: jaracogmbh/docker-compose-health-check-action@973fbdccf7c8e396b652d3501984c8e530a9fa80 # v1.0.0 with: max-retries: 30 retry-interval: 10 compose-file: "docker-compose.yml" skip-exited: "true" skip-no-healthcheck: "true" - name: Gotify Notification uses: eikendev/gotify-action@ca0339b85ee8db9fda9c0718aaa7f95e17b3c617 # 0.0.4 with: gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}" gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}" notification_title: "GITEA: Docker Compose Deployment @ Rinoa" notification_message: "Deployment completed successfully."