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.20.4" TEA_VERSION: "0.10.1" jobs: check-and-create-pr: name: Check and Create PR runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 with: fetch-depth: 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: Gotify Notification uses: eikendev/gotify-action@master with: gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}" gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}" notification_title: "GITEA: PR Check" notification_message: "Checking for existing PR... 🔍" - name: Check if open PR exists id: check-opened-pr-step continue-on-error: true 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 }} pr_exists=$(tea pr list \ --repo ${{ github.repository }} \ --state open \ --fields index,title,head \ | egrep '\[DOCKER\].*${{ github.ref_name }}' | tail -1 | wc -l) echo "exists=$pr_exists" >> $GITHUB_OUTPUT - name: Create PR if: ${{ steps.check-opened-pr-step.outputs.exists == '0' }} run: | tea login default gitea-rinoa pr_index_old=$(tea pr ls \ --repo ${{ github.repository }} \ --state all --fields index,title,head \ --output csv | sed -e 's|"||g' | \ egrep '^[0-9]' | head -1 | awk -F"," '{print $1}') pr_index_new=$(expr ${pr_index_old} + 1) tea pr c -r ${{ github.repository }} \ -t "[DOCKER] Automated PR for ${{ github.ref_name }} - #${pr_index_new}" \ -d "Automatically created PR for branch: ${{ github.ref_name }}" \ -a ${{ github.actor }} \ -L "Docker Compose" - name: Gotify Notification uses: eikendev/gotify-action@master with: gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}" gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}" notification_title: "GITEA: PR Check" notification_message: "PR Created 🎟️" 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@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 - name: Fetch base branch run: | git fetch origin ${{ github.event.pull_request.base.ref }} - name: Gotify Notification uses: eikendev/gotify-action@master 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: | 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 modified services..." touch service_changes.txt comm -13 services_main.txt services_head.txt | while read service; do echo "$service: added" >> service_changes.txt done comm -12 services_main.txt services_head.txt | 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 mod_svcs=$(cut -d':' -f1 service_changes.txt | sort | uniq) echo "docker_svc_list<> "$GITHUB_OUTPUT" echo "$mod_svcs" >> "$GITHUB_OUTPUT" echo "EOF" >> "$GITHUB_OUTPUT" - name: List of Services for (Re)Deployment run: | echo -e "${{ steps.detect_services.outputs.docker_svc_list }}" 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@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 - 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@master 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_USERNAME: ${{ secrets.VAULT_GITEA_USER }} HC_VAULT_PASSWORD: ${{ secrets.VAULT_GITEA_PASSWORD }} 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 with: services: ${{ env.DOCKER_SVC_LIST }} compose_profile: "rinoa-apps" - name: Docker Compose Dry Run uses: hoverkraft-tech/compose-action@b716db5b717cb9b81e391fe638e5aceaa2299e43 # v2.4.0 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@master 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@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 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 '.services[].labels.swag_url' docker-compose.yml | \ egrep -v 'null' | \ sed -e 's|"||g' | \ awk -F'.' '{print $1}' | \ sort > compose_subdomains.txt 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: Gotify Notification uses: eikendev/gotify-action@master 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@master 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." regenerate-readme-modified-services: name: Update README & Generate List of Modified Services runs-on: ubuntu-latest needs: [cloudflare-dns-setup] steps: - name: Checkout uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 - name: Install yq uses: dcarbone/install-yq-action@4075b4dca348d74bd83f2bf82d30f25d7c54539b # v1.3.1 - name: Gotify Notification uses: eikendev/gotify-action@master with: gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}" gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}" notification_title: "GITEA: README Update" notification_message: "Updating README..." - name: Generate service list run: | yq '.services | to_entries | map({"service": .key, "image": .value.image, "description": (.value.labels."homepage.description" // "")})' docker-compose.yml > services.yml - name: Generate Markdown Table uses: gazab/create-markdown-table@6686233d7008e8d8b9d4bbdbfd1fb1ae510019f0 # v1.0.7 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@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4 with: message: "chore: Update README" add: "README.md" - name: Gotify Notification uses: eikendev/gotify-action@master with: gotify_api_base: "${{ secrets.RUNNER_GOTIFY_URL }}" gotify_app_token: "${{ secrets.RUNNER_GOTIFY_TOKEN }}" notification_title: "GITEA: README Update" notification_message: "README updated" pr-merge: name: PR Merge needs: [regenerate-readme-modified-services] if: github.ref != 'refs/heads/main' runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 - 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@master 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@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 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@master 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_USERNAME: ${{ secrets.VAULT_GITEA_USER }} HC_VAULT_PASSWORD: ${{ secrets.VAULT_GITEA_PASSWORD }} HC_VAULT_SECRETS_PATH: rinoa-docker/env - name: Docker Compose Deployment uses: hoverkraft-tech/compose-action@b716db5b717cb9b81e391fe638e5aceaa2299e43 # v2.4.0 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@master 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."