From cdd4b0162a79c2a1d69e5364926d747dbacf6733 Mon Sep 17 00:00:00 2001 From: Alex Lebens Date: Sun, 15 Mar 2026 21:50:42 +0000 Subject: [PATCH] feat: remove old workflows (#4769) Reviewed-on: https://gitea.alexlebens.dev/alexlebens/infrastructure/pulls/4769 --- .../workflows/render-manifests-automerge.yaml | 463 ------------------ .../workflows/render-manifests-dispatch.yaml | 445 ----------------- .gitea/workflows/render-manifests-merge.yaml | 451 ----------------- .gitea/workflows/render-manifests-push.yaml | 449 ----------------- 4 files changed, 1808 deletions(-) delete mode 100644 .gitea/workflows/render-manifests-automerge.yaml delete mode 100644 .gitea/workflows/render-manifests-dispatch.yaml delete mode 100644 .gitea/workflows/render-manifests-merge.yaml delete mode 100644 .gitea/workflows/render-manifests-push.yaml diff --git a/.gitea/workflows/render-manifests-automerge.yaml b/.gitea/workflows/render-manifests-automerge.yaml deleted file mode 100644 index d049080d9..000000000 --- a/.gitea/workflows/render-manifests-automerge.yaml +++ /dev/null @@ -1,463 +0,0 @@ -name: render-manifests-automerge - -on: - workflow_dispatch: - # pull_request: - # branches: - # - main - # paths: - # - 'clusters/cl01tl/helm/**' - # types: - # - closed - -env: - CLUSTER: cl01tl - BASE_BRANCH: manifests - BRANCH_NAME_BASE: auto/update-manifests-automerge - MAIN_DIR: /workspace/alexlebens/infrastructure/infrastructure - MANIFEST_DIR: /workspace/alexlebens/infrastructure/infrastructure-manifests - -jobs: - render-manifests-automerge: - runs-on: ubuntu-js - if: ${{ (github.event.pull_request.merged == true) && (contains(github.event.pull_request.labels.*.name, 'automerge')) }} - steps: - - name: Checkout Main - uses: actions/checkout@v6 - with: - path: infrastructure - fetch-depth: 0 - - - name: Checkout Manifests - uses: actions/checkout@v6 - with: - ref: manifests - path: infrastructure-manifests - - - name: Set up Helm - uses: azure/setup-helm@v4 - with: - token: ${{ secrets.GITEA_TOKEN }} - version: v3.17.2 # Pending https://github.com/helm/helm/pull/30743 - cache: true - - - name: Configure Kubeconfig - uses: azure/k8s-set-context@v4 - with: - method: kubeconfig - kubeconfig: ${{ secrets.KUBECONFIG }} - - - name: Cache Helm Dependencies - uses: actions/cache@v5 - with: - path: | - ~/.cache/helm - ~/.config/helm - key: helm-cache-${{ runner.os }}-${{ hashFiles('infrastructure/clusters/cl01tl/helm/**/Chart.yaml', 'infrastructure/clusters/cl01tl/helm/**/Chart.lock') }} - restore-keys: | - helm-cache-${{ runner.os }}- - - - name: Prepare Manifest Branch - id: prepare-manifest-branch - run: | - cd ${MANIFEST_DIR} - - BRANCH_NAME="${BRANCH_NAME_BASE}-$(date +%Y%m%d%H%M%S)" - - echo "" - echo ">> Configure git to use gitea-bot as user ..." - git config user.name "gitea-bot" - git config user.email "gitea-bot@alexlebens.net" - - echo "" - echo ">> Creating branch ..." - git checkout -b $BRANCH_NAME - - echo "----" - - echo "BRANCH_NAME=${BRANCH_NAME}" >> $GITEA_OUTPUT - - - name: Check which Directories have Changes - id: check-dir-changes - run: | - cd "${MAIN_DIR}" - - echo "" - echo ">> Checking for changes from HEAD^..HEAD ..." - - # Extract the chart names from the git diff - RENDER_DIR=$(git diff --name-only HEAD^..HEAD | grep -E "^clusters/${CLUSTER}/helm/" | awk -F '/' '{print $4}' | sort -u || true) - - if [ -n "${RENDER_DIR}" ]; then - echo "" - echo ">> Directories to Render:" - echo "${RENDER_DIR}" - - echo "----" - - echo "changes-detected=true" >> "$GITEA_OUTPUT" - echo "render-dir<> "$GITEA_OUTPUT" - echo "${RENDER_DIR}" >> "$GITEA_OUTPUT" - echo "EOF" >> "$GITEA_OUTPUT" - - else - echo "" - echo ">> No chart changes detected" - echo "changes-detected=false" >> "$GITEA_OUTPUT" - - fi - - - name: Add Repositories - if: steps.check-dir-changes.outputs.changes-detected == 'true' - env: - RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }} - run: | - cd "${MAIN_DIR}" - - echo "" - echo ">> Adding repositories for chart dependencies ..." - for DIR in ${RENDER_DIR}; do - helm dependency list --max-col-width 120 "${MAIN_DIR}/clusters/${CLUSTER}/helm/${DIR}" 2> /dev/null \ - | tail -n +2 \ - | awk 'NF > 0 { print $1, $3 }' \ - | while read -r REPO_NAME REPO_URL; do - if [[ "${REPO_URL}" == oci://* ]]; then - echo "" - echo ">> Ignoring OCI repo: ${REPO_URL}" - - elif [[ -n "${REPO_NAME}" && -n "${REPO_URL}" ]]; then - helm repo add "${REPO_NAME}" "${REPO_URL}" - - fi - done || true - done - - if helm repo list > /dev/null 2>&1; then - echo "" - echo ">> Update repository cache ..." - helm repo update - - fi - - echo "----" - - - name: Remove Changed Manifest Files - if: steps.check-dir-changes.outputs.changes-detected == 'true' - env: - RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }} - run: | - cd "${MANIFEST_DIR}" - - echo "" - echo ">> Remove manfiest files and rebuild from source ..." - - for DIR in ${RENDER_DIR}; do - CHART_PATH=${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/${DIR} - - echo "${CHART_PATH}" - rm -rf ${CHART_PATH}/* - done - - echo "----" - - - name: Render Helm Manifests - id: render-manifests - if: steps.check-dir-changes.outputs.changes-detected == 'true' - env: - RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }} - run: | - cd ${MAIN_DIR} - - echo "" - echo ">> Rendering Manifests ..." - - render_chart() { - local DIR="$1" - local CHART_PATH="${MAIN_DIR}/clusters/${CLUSTER}/helm/${DIR}" - local CHART_NAME=$(basename "${CHART_PATH}") - - echo "" - echo ">> Rendering ..." - echo ">> Chart: ${CHART_NAME}" - echo ">> Path: ${CHART_PATH}" - - if [ -f "${CHART_PATH}/Chart.yaml" ]; then - local OUTPUT_FOLDER="${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/${CHART_NAME}/" - - mkdir -p "${OUTPUT_FOLDER}" - cd "${CHART_PATH}" - - echo "" - echo ">> Updating helm dependencies ..." - helm dependency update --skip-refresh > /dev/null - - echo "" - echo ">> Linting helm chart ..." - helm lint --namespace "${CHART_NAME}" --quiet - - local NAMESPACE="${CHART_NAME}" - case "${CHART_NAME}" in - "stack") - NAMESPACE="argocd" - echo "" - echo ">> Special Rendering into 'argocd' namespace ..." - ;; - "cilium" | "coredns" | "metrics-server" | "prometheus-operator-crds") - NAMESPACE="kube-system" - echo "" - echo ">> Special Rendering for ${CHART_NAME} into 'kube-system' namespace ..." - ;; - *) - echo "" - echo ">> Standard Rendering for ${CHART_NAME} ..." - esac - - echo "" - echo ">> Formating rendered template ..." - local TEMPLATE - TEMPLATE=$(helm template "${CHART_NAME}" ./ --namespace "${NAMESPACE}" --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute") - - # Format and split rendered template - echo "${TEMPLATE}" | yq '... comments=""' | yq 'select(. != null)' | yq -s '"'"${OUTPUT_FOLDER}"'" + .kind + "-" + .metadata.name + ".yaml"' - - # Strip comments again to ensure formatting correctness - for file in "$OUTPUT_FOLDER"/*; do - yq -i '... comments=""' $file - done - - echo "" - echo ">> Manifests for ${CHART_NAME} rendered to ${OUTPUT_FOLDER}:" - ls $OUTPUT_FOLDER - echo "" - else - echo "" - echo ">> Directory ${CHART_PATH} does not contain a Chart.yaml. Skipping ..." - echo "" - fi - } - - export -f render_chart - export MAIN_DIR CLUSTER MANIFEST_DIR - - # Run rendering in parallel - for DIR in ${RENDER_DIR}; do - echo "${DIR}" - done | xargs -n 1 -P 4 -I {} bash -c 'render_chart "$@"' _ {} - - echo "----" - - - name: Check for Changes - id: check-changes - if: steps.check-dir-changes.outputs.changes-detected == 'true' - run: | - cd "${MANIFEST_DIR}" - - GIT_CHANGES=$(git status --porcelain) - - if [ -n "${GIT_CHANGES}" ]; then - echo "" - echo ">> Changes detected" - git status --porcelain - echo "changes-detected=true" >> $GITEA_OUTPUT - - else - echo "" - echo ">> No changes detected, skipping PR creation" - - fi - - echo "----" - - - name: Commit and Push Changes - id: commit-push - if: steps.check-changes.outputs.changes-detected == 'true' - env: - BRANCH_NAME: ${{ steps.prepare-manifest-branch.outputs.BRANCH_NAME }} - run: | - cd "${MANIFEST_DIR}" - - echo "" - echo ">> Commiting changes to ${BRANCH_NAME} ..." - git add . - git commit -m "chore: Update manifests after automerge" - - REPO_URL="${{ secrets.REPO_URL }}/${{ gitea.repository }}" - echo "" - echo ">> Pushing changes to ${REPO_URL} ..." - - git push -u "https://oauth2:${{ secrets.BOT_TOKEN }}@${REPO_URL#*://}" "${BRANCH_NAME}" - - echo "----" - - echo "push=true" >> "$GITEA_OUTPUT" - - - name: Create Pull Request - id: create-pull-request - if: steps.commit-push.outputs.push == 'true' - env: - GITEA_TOKEN: ${{ secrets.BOT_TOKEN }} - GITEA_URL: ${{ secrets.REPO_URL }} - BRANCH_NAME: ${{ steps.prepare-manifest-branch.outputs.BRANCH_NAME }} - run: | - cd ${MANIFEST_DIR} - - API_ENDPOINT="${GITEA_URL}/api/v1/repos/${{ gitea.repository }}/pulls" - - PAYLOAD=$( jq -n \ - --arg head "${BRANCH_NAME}" \ - --arg base "${BASE_BRANCH}" \ - --arg title "Automated Manifest Update - Automerge" \ - --arg body "This PR contains newly rendered Kubernetes manifests automatically generated by the CI workflow. This is expected to be automerged." \ - '{head: $head, base: $base, title: $title, body: $body}' ) - - echo ">> Creating PR from branch ${BRANCH_NAME} into ${BASE_BRANCH}" - echo ">> With Endpoint of:" - echo "$API_ENDPOINT" - echo ">> With Payload of:" - echo "$PAYLOAD" - - HTTP_STATUS=$( - curl -X POST \ - --silent \ - --write-out '%{http_code}' \ - --output response_body.json \ - --dump-header response_headers.txt \ - --data "$PAYLOAD" \ - -H "Authorization: token ${GITEA_TOKEN}" \ - -H "Content-Type: application/json" \ - "$API_ENDPOINT" 2> response_errors.txt - ) - - echo ">> HTTP Status Code: $HTTP_STATUS" - echo ">> Response Output ..." - echo "----" - cat response_body.json - echo "----" - cat response_headers.txt - echo "----" - cat response_errors.txt - echo "----" - - if [ "$HTTP_STATUS" == "201" ]; then - echo ">> Pull Request created successfully!" - - PR_URL=$(cat response_body.json | jq -r .html_url) - echo ">> Pull Request URL: $PR_URL" - echo "pull-request-url=${PR_URL}" >> $GITEA_OUTPUT - - PR_NUMBER=$(cat response_body.json | jq -r .number) - echo ">> Pull Request Number: $PR_NUMBER" - echo "pull-request-number=${PR_NUMBER}" >> $GITEA_OUTPUT - - echo "pull-request-operation=created" >> $GITEA_OUTPUT - - elif [ "$HTTP_STATUS" == "422" ]; then - echo ">> Failed to create PR (HTTP 422: Unprocessable Entity), PR may already exist" - - elif [ "$HTTP_STATUS" == "409" ]; then - echo ">> Failed to create PR (HTTP 409: Conflict), PR already exists" - - else - echo ">> Failed to create PR, HTTP status code: $HTTP_STATUS" - exit 1 - fi - - echo "----" - - - name: Merge Changes - id: merge-changes - if: steps.commit-push.outputs.push == 'true' - env: - GITEA_TOKEN: ${{ secrets.BOT_TOKEN }} - GITEA_URL: ${{ secrets.REPO_URL }} - BRANCH_NAME: ${{ steps.prepare-manifest-branch.outputs.BRANCH_NAME }} - PR_NUMBER: ${{ steps.create-pull-request.outputs.pull-request-number }} - run: | - cd ${MANIFEST_DIR} - - API_ENDPOINT="${GITEA_URL}/api/v1/repos/${{ gitea.repository }}/pulls/${PR_NUMBER}/merge" - - PAYLOAD=$( jq -n \ - --arg Do "merge" \ - '{Do: $Do}' ) - - echo ">> Merging PR with ID: ${PR_NUMBER}" - echo ">> With Endpoint of:" - echo "$API_ENDPOINT" - echo ">> With Payload of:" - echo "$PAYLOAD" - - HTTP_STATUS=$( - curl -X POST \ - --silent \ - --write-out '%{http_code}' \ - --output response_body.json \ - --dump-header response_headers.txt \ - --data "$PAYLOAD" \ - -H "Authorization: token ${GITEA_TOKEN}" \ - -H "Content-Type: application/json" \ - "$API_ENDPOINT" 2> response_errors.txt - ) - - echo ">> HTTP Status Code: $HTTP_STATUS" - echo ">> Response Output ..." - echo "----" - cat response_body.json - echo "----" - cat response_headers.txt - echo "----" - cat response_errors.txt - echo "----" - - if [ "$HTTP_STATUS" == "200" ]; then - echo ">> Pull Request merged successfully!" - echo "pull-request-operation=merged" >> $GITEA_OUTPUT - - else - echo ">> Failed to create PR, HTTP status code: $HTTP_STATUS" - echo "pull-request-operation=failed" >> $GITEA_OUTPUT - exit 1 - fi - - echo "----" - - - name: Cleanup Branch - if: failure() - env: - BRANCH_NAME: ${{ steps.prepare-manifest-branch.outputs.BRANCH_NAME }} - run: | - cd ${MANIFEST_DIR} - - echo ">> Removing branch: ${BRANCH_NAME}" - git push origin --delete ${BRANCH_NAME} - - echo "----" - - - name: ntfy Merged - uses: niniyas/ntfy-action@master - if: steps.merge-changes.outputs.pull-request-operation == 'merged' - with: - url: "${{ secrets.NTFY_URL }}" - topic: "${{ secrets.NTFY_TOPIC }}" - title: "Manifest Render PR Merged - Infrastructure" - priority: 3 - headers: '{"Authorization": "Bearer ${{ secrets.NTFY_CRED }}"}' - tags: action,successfully,completed - details: "Automerge Manifest rendering for Infrastructure!" - icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/png/gitea.png" - actions: '[{"action": "view", "label": "Open Gitea", "url": "${{ steps.create-pull-request.outputs.pull-request-url }}", "clear": true}]' - - - name: ntfy Failed - uses: niniyas/ntfy-action@master - if: failure() - with: - url: "${{ secrets.NTFY_URL }}" - topic: "${{ secrets.NTFY_TOPIC }}" - title: "Manifest Render Failure - Infrastructure" - priority: 4 - headers: '{"Authorization": "Bearer ${{ secrets.NTFY_CRED }}"}' - tags: action,failed - details: "Automerge Manifest rendering for Infrastructure has failed!" - icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/png/gitea.png" - actions: '[{"action": "view", "label": "Open Gitea", "url": "https://gitea.alexlebens.dev/alexlebens/infrastructure/actions?workflow=render-manifests-automerge.yaml", "clear": true}]' - image: true diff --git a/.gitea/workflows/render-manifests-dispatch.yaml b/.gitea/workflows/render-manifests-dispatch.yaml deleted file mode 100644 index 6cfc8b517..000000000 --- a/.gitea/workflows/render-manifests-dispatch.yaml +++ /dev/null @@ -1,445 +0,0 @@ -name: render-manifests-dispatch - -on: - workflow_dispatch: - # schedule: - # - cron: '0 15 * * *' - - # workflow_dispatch: - -env: - CLUSTER: cl01tl - BASE_BRANCH: manifests - BRANCH_NAME: auto/update-manifests - ASSIGNEE: alexlebens - MAIN_DIR: /workspace/alexlebens/infrastructure/infrastructure - MANIFEST_DIR: /workspace/alexlebens/infrastructure/infrastructure-manifests - -jobs: - render-manifests-dispatch: - runs-on: ubuntu-js - steps: - - name: Checkout Main - uses: actions/checkout@v6 - with: - path: infrastructure - fetch-depth: 0 - - - name: Checkout Manifests - uses: actions/checkout@v6 - with: - ref: manifests - path: infrastructure-manifests - - - name: Set up Helm - uses: azure/setup-helm@v4 - with: - token: ${{ secrets.GITEA_TOKEN }} - version: v3.17.2 # Pending https://github.com/helm/helm/pull/30743 - cache: true - - - name: Configure Kubeconfig - uses: azure/k8s-set-context@v4 - with: - method: kubeconfig - kubeconfig: ${{ secrets.KUBECONFIG }} - - - name: Cache Helm Dependencies - uses: actions/cache@v5 - with: - path: | - ~/.cache/helm - ~/.config/helm - key: helm-cache-${{ runner.os }}-${{ hashFiles('infrastructure/clusters/cl01tl/helm/**/Chart.yaml', 'infrastructure/clusters/cl01tl/helm/**/Chart.lock') }} - restore-keys: | - helm-cache-${{ runner.os }}- - - - name: Prepare Manifest Branch - run: | - cd "${MANIFEST_DIR}" - - echo "" - echo ">> Configure git to use gitea-bot as user ..." - git config user.name "gitea-bot" - git config user.email "gitea-bot@alexlebens.net" - - echo "" - echo ">> Checking if PR branch exists ..." - if git ls-remote --exit-code --heads origin "${BRANCH_NAME}" > /dev/null 2>&1; then - echo "" - echo ">> Branch '${BRANCH_NAME}' exists, pulling changes ..." - git fetch origin "${BRANCH_NAME}" - git checkout "${BRANCH_NAME}" - git pull --rebase - - else - echo "" - echo ">> Branch '${BRANCH_NAME}' does not exist, creating ..." - git checkout -b "${BRANCH_NAME}" - - fi - - echo "----" - - - name: Check which Directories have Changes - id: check-dir-changes - run: | - cd "${MAIN_DIR}" - - echo "" - echo ">> Triggered on dispatch, will check all paths ..." - - # Extract names of charts - RENDER_DIR=$(find "clusters/${CLUSTER}/helm" -mindepth 1 -maxdepth 1 -type d -exec basename {} \; | sort -u) - - if [ -n "${RENDER_DIR}" ]; then - echo "" - echo ">> Directories to Render:" - echo "${RENDER_DIR}" - echo "----" - - echo "changes-detected=true" >> "$GITEA_OUTPUT" - echo "render-dir<> "$GITEA_OUTPUT" - echo "${RENDER_DIR}" >> "$GITEA_OUTPUT" - echo "EOF" >> "$GITEA_OUTPUT" - - else - echo ">> No directories found" - echo "changes-detected=false" >> "$GITEA_OUTPUT" - - fi - - - name: Add Repositories - if: steps.check-dir-changes.outputs.changes-detected == 'true' - env: - RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }} - run: | - cd "${MAIN_DIR}" - - echo "" - echo ">> Adding repositories for chart dependencies ..." - for DIR in ${RENDER_DIR}; do - helm dependency list --max-col-width 120 "${MAIN_DIR}/clusters/${CLUSTER}/helm/${DIR}" 2> /dev/null \ - | tail -n +2 \ - | awk 'NF > 0 { print $1, $3 }' \ - | while read -r REPO_NAME REPO_URL; do - if [[ "${REPO_URL}" == oci://* ]]; then - echo "" - echo ">> Ignoring OCI repo: ${REPO_URL}" - - elif [[ -n "${REPO_NAME}" && -n "${REPO_URL}" ]]; then - helm repo add "${REPO_NAME}" "${REPO_URL}" - - fi - done || true - done - - if helm repo list > /dev/null 2>&1; then - echo "" - echo ">> Update repository cache ..." - helm repo update - - fi - - echo "----" - - - name: Remove Changed Manifest Files - if: steps.check-dir-changes.outputs.changes-detected == 'true' - env: - RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }} - run: | - cd "${MANIFEST_DIR}" - - echo "" - echo ">> Remove manfiest files and rebuild from source ..." - - for DIR in ${RENDER_DIR}; do - CHART_PATH=${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/${DIR} - - echo "${CHART_PATH}" - rm -rf ${CHART_PATH}/* - done - - echo "----" - - - name: Render Helm Manifests - id: render-manifests - if: steps.check-dir-changes.outputs.changes-detected == 'true' - env: - RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }} - run: | - cd ${MAIN_DIR} - - echo "" - echo ">> Rendering Manifests ..." - - render_chart() { - local DIR="$1" - local CHART_PATH="${MAIN_DIR}/clusters/${CLUSTER}/helm/${DIR}" - local CHART_NAME=$(basename "${CHART_PATH}") - - echo "" - echo ">> Rendering ..." - echo ">> Chart: ${CHART_NAME}" - echo ">> Path: ${CHART_PATH}" - - if [ -f "${CHART_PATH}/Chart.yaml" ]; then - local OUTPUT_FOLDER="${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/${CHART_NAME}/" - - mkdir -p "${OUTPUT_FOLDER}" - cd "${CHART_PATH}" - - echo "" - echo ">> Updating helm dependencies ..." - helm dependency update --skip-refresh > /dev/null - - echo "" - echo ">> Linting helm chart ..." - helm lint --namespace "${CHART_NAME}" --quiet - - local NAMESPACE="${CHART_NAME}" - case "${CHART_NAME}" in - "stack") - NAMESPACE="argocd" - echo "" - echo ">> Special Rendering into 'argocd' namespace ..." - ;; - "cilium" | "coredns" | "metrics-server" | "prometheus-operator-crds") - NAMESPACE="kube-system" - echo "" - echo ">> Special Rendering for ${CHART_NAME} into 'kube-system' namespace ..." - ;; - *) - echo "" - echo ">> Standard Rendering for ${CHART_NAME} ..." - esac - - echo "" - echo ">> Formating rendered template ..." - local TEMPLATE - TEMPLATE=$(helm template "${CHART_NAME}" ./ --namespace "${NAMESPACE}" --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute") - - # Format and split rendered template - echo "${TEMPLATE}" | yq '... comments=""' | yq 'select(. != null)' | yq -s '"'"${OUTPUT_FOLDER}"'" + .kind + "-" + .metadata.name + ".yaml"' - - # Strip comments again to ensure formatting correctness - for file in "$OUTPUT_FOLDER"/*; do - yq -i '... comments=""' $file - done - - echo "" - echo ">> Manifests for ${CHART_NAME} rendered to ${OUTPUT_FOLDER}:" - ls $OUTPUT_FOLDER - echo "" - else - echo "" - echo ">> Directory ${CHART_PATH} does not contain a Chart.yaml. Skipping ..." - echo "" - fi - } - - export -f render_chart - export MAIN_DIR CLUSTER MANIFEST_DIR - - # Run rendering in parallel - for DIR in ${RENDER_DIR}; do - echo "${DIR}" - done | xargs -n 1 -P 4 -I {} bash -c 'render_chart "$@"' _ {} - - echo "----" - - - name: Check for Changes - id: check-changes - if: steps.check-dir-changes.outputs.changes-detected == 'true' - run: | - cd "${MANIFEST_DIR}" - - GIT_CHANGES=$(git status --porcelain) - - if [ -n "${GIT_CHANGES}" ]; then - echo "" - echo ">> Changes detected" - git status --porcelain - echo "changes-detected=true" >> $GITEA_OUTPUT - - else - echo "" - echo ">> No changes detected, skipping PR creation" - - fi - - echo "----" - - - name: Commit and Push Changes - id: commit-push - if: steps.check-changes.outputs.changes-detected == 'true' - run: | - cd "${MANIFEST_DIR}" - - echo "" - echo ">> Commiting changes to ${BRANCH_NAME} ..." - git add . - git commit -m "chore: Update manifests after change" - - REPO_URL="${{ secrets.REPO_URL }}/${{ gitea.repository }}" - echo "" - echo ">> Pushing changes to ${REPO_URL} ..." - - git push -u "https://oauth2:${{ secrets.BOT_TOKEN }}@${REPO_URL#*://}" "${BRANCH_NAME}" - - echo "----" - - echo "HEAD_BRANCH=${BRANCH_NAME}" >> "$GITEA_OUTPUT" - echo "push=true" >> "$GITEA_OUTPUT" - - - name: Check for Pull Request - id: check-for-pull-requst - if: steps.commit-push.outputs.push == 'true' - env: - GITEA_TOKEN: ${{ secrets.BOT_TOKEN }} - GITEA_URL: ${{ secrets.REPO_URL }} - HEAD_BRANCH: ${{ steps.commit-push.outputs.HEAD_BRANCH }} - run: | - cd ${MANIFEST_DIR} - - API_ENDPOINT="${GITEA_URL}/api/v1/repos/${{ gitea.repository }}/pulls?base_branch=${BASE_BRANCH}&state=open&page=1" - - echo ">> Checking if PR from branch ${HEAD_BRANCH} into ${BASE_BRANCH}" - echo ">> With Endpoint of:" - echo "$API_ENDPOINT" - - HTTP_STATUS=$( - curl -X GET \ - --silent \ - --write-out '%{http_code}' \ - --output response_body.json \ - --dump-header response_headers.txt \ - -H "Authorization: token ${GITEA_TOKEN}" \ - -H "Content-Type: application/json" \ - "$API_ENDPOINT" 2> response_errors.txt - ) - - echo ">> HTTP Status Code: $HTTP_STATUS" - echo ">> Response Output ..." - echo "----" - cat response_body.json - echo "----" - cat response_headers.txt - echo "----" - cat response_errors.txt - echo "----" - - if [ "$HTTP_STATUS" == "200" ] && [ "$(cat response_body.json | jq -r .[0].state)" == "open" ]; then - echo ">> Pull Request has been found open, will update" - PR_INDEX=$(cat response_body.json | jq -r .[0].number) - echo "pull-request-exists=${PR_INDEX}" >> $GITEA_OUTPUT - echo "pull-request-index=true" >> $GITEA_OUTPUT - - elif [ "$HTTP_STATUS" == "200" ] && [ "$(cat response_body.json | jq -r .[0].state)" == "closed" ]; then - echo ">> Pull Request found, but was closed" - echo "pull-request-exists=false" >> $GITEA_OUTPUT - - else - echo ">> Pull Request not found" - echo "pull-request-exists=false" >> $GITEA_OUTPUT - fi - - echo "----" - - - name: Create Pull Request - id: create-pull-request - if: steps.commit-push.outputs.push == 'true' && steps.check-for-pull-requst.outputs.pull-request-exists == 'false' - env: - GITEA_TOKEN: ${{ secrets.BOT_TOKEN }} - GITEA_URL: ${{ secrets.REPO_URL }} - HEAD_BRANCH: ${{ steps.commit-push.outputs.HEAD_BRANCH }} - run: | - cd ${MANIFEST_DIR} - - API_ENDPOINT="${GITEA_URL}/api/v1/repos/${{ gitea.repository }}/pulls" - - PAYLOAD=$( jq -n \ - --arg head "${HEAD_BRANCH}" \ - --arg base "${BASE_BRANCH}" \ - --arg assignee "${ASSIGNEE}" \ - --arg title "Automated Manifest Update" \ - --arg body "This PR contains newly rendered Kubernetes manifests automatically generated by the CI workflow." \ - '{head: $head, base: $base, assignee: $assignee, title: $title, body: $body}' ) - - echo ">> Creating PR from branch ${HEAD_BRANCH} into ${BASE_BRANCH}" - echo ">> With Endpoint of:" - echo "$API_ENDPOINT" - echo ">> With Payload of:" - echo "$PAYLOAD" - - HTTP_STATUS=$( - curl -X POST \ - --silent \ - --write-out '%{http_code}' \ - --output response_body.json \ - --dump-header response_headers.txt \ - --data "$PAYLOAD" \ - -H "Authorization: token ${GITEA_TOKEN}" \ - -H "Content-Type: application/json" \ - "$API_ENDPOINT" 2> response_errors.txt - ) - - echo ">> HTTP Status Code: $HTTP_STATUS" - echo ">> Response Output ..." - echo "----" - cat response_body.json - echo "----" - cat response_headers.txt - echo "----" - cat response_errors.txt - echo "----" - - if [ "$HTTP_STATUS" == "201" ]; then - echo ">> Pull Request created successfully!" - PR_URL=$(cat response_body.json | jq -r .html_url) - echo "pull-request-url=${PR_URL}" >> $GITEA_OUTPUT - PR_ID=$(cat response_body.json | jq -r .id) - echo "pull-request-id=${PR_ID}" >> $GITEA_OUTPUT - echo "pull-request-operation=created" >> $GITEA_OUTPUT - - elif [ "$HTTP_STATUS" == "422" ]; then - echo ">> Failed to create PR (HTTP 422: Unprocessable Entity), PR may already exist" - - elif [ "$HTTP_STATUS" == "409" ]; then - echo ">> Failed to create PR (HTTP 409: Conflict), PR already exists" - - else - echo ">> Failed to create PR, HTTP status code: $HTTP_STATUS" - exit 1 - fi - - echo "----" - - - name: ntfy Created - uses: niniyas/ntfy-action@master - if: steps.create-pull-request.outputs.pull-request-operation == 'created' - with: - url: "${{ secrets.NTFY_URL }}" - topic: "${{ secrets.NTFY_TOPIC }}" - title: "Manifest Render PR Created - Infrastructure" - priority: 3 - headers: '{"Authorization": "Bearer ${{ secrets.NTFY_CRED }}"}' - tags: action,successfully,completed - details: "Manifest rendering for Infrastructure has created a new Pull Request with ID: ${{ steps.create-pull-request.outputs.pull-request-id }}!" - icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/png/gitea.png" - actions: '[{"action": "view", "label": "Open Gitea", "url": "${{ steps.create-pull-request.outputs.pull-request-url }}", "clear": true}]' - - - name: ntfy Failed - uses: niniyas/ntfy-action@master - if: failure() - with: - url: "${{ secrets.NTFY_URL }}" - topic: "${{ secrets.NTFY_TOPIC }}" - title: "Manifest Render Failure - Infrastructure" - priority: 4 - headers: '{"Authorization": "Bearer ${{ secrets.NTFY_CRED }}"}' - tags: action,failed - details: "Manifest rendering for Infrastructure has failed!" - icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/png/gitea.png" - actions: '[{"action": "view", "label": "Open Gitea", "url": "https://gitea.alexlebens.dev/alexlebens/infrastructure/actions?workflow=render-manifests.yaml", "clear": true}]' - image: true diff --git a/.gitea/workflows/render-manifests-merge.yaml b/.gitea/workflows/render-manifests-merge.yaml deleted file mode 100644 index 3a0468c36..000000000 --- a/.gitea/workflows/render-manifests-merge.yaml +++ /dev/null @@ -1,451 +0,0 @@ -name: render-manifests-merge - -on: - workflow_dispatch: - # pull_request: - # branches: - # - main - # paths: - # - 'clusters/cl01tl/helm/**' - # types: - # - closed - -env: - CLUSTER: cl01tl - BASE_BRANCH: manifests - BRANCH_NAME: auto/update-manifests - ASSIGNEE: alexlebens - MAIN_DIR: /workspace/alexlebens/infrastructure/infrastructure - MANIFEST_DIR: /workspace/alexlebens/infrastructure/infrastructure-manifests - -jobs: - render-manifests-merge: - runs-on: ubuntu-js - if: ${{ (github.event.pull_request.merged == true) && !(contains(github.event.pull_request.labels.*.name, 'automerge')) }} - steps: - - name: Checkout Main - uses: actions/checkout@v6 - with: - path: infrastructure - fetch-depth: 0 - - - name: Checkout Manifests - uses: actions/checkout@v6 - with: - ref: manifests - path: infrastructure-manifests - - - name: Set up Helm - uses: azure/setup-helm@v4 - with: - token: ${{ secrets.GITEA_TOKEN }} - version: v3.17.2 # Pending https://github.com/helm/helm/pull/30743 - cache: true - - - name: Configure Kubeconfig - uses: azure/k8s-set-context@v4 - with: - method: kubeconfig - kubeconfig: ${{ secrets.KUBECONFIG }} - - - name: Cache Helm Dependencies - uses: actions/cache@v5 - with: - path: | - ~/.cache/helm - ~/.config/helm - key: helm-cache-${{ runner.os }}-${{ hashFiles('infrastructure/clusters/cl01tl/helm/**/Chart.yaml', 'infrastructure/clusters/cl01tl/helm/**/Chart.lock') }} - restore-keys: | - helm-cache-${{ runner.os }}- - - - name: Prepare Manifest Branch - run: | - cd "${MANIFEST_DIR}" - - echo "" - echo ">> Configure git to use gitea-bot as user ..." - git config user.name "gitea-bot" - git config user.email "gitea-bot@alexlebens.net" - - echo "" - echo ">> Checking if PR branch exists ..." - if git ls-remote --exit-code --heads origin "${BRANCH_NAME}" > /dev/null 2>&1; then - echo "" - echo ">> Branch '${BRANCH_NAME}' exists, pulling changes ..." - git fetch origin "${BRANCH_NAME}" - git checkout "${BRANCH_NAME}" - git pull --rebase - - else - echo "" - echo ">> Branch '${BRANCH_NAME}' does not exist, creating ..." - git checkout -b "${BRANCH_NAME}" - - fi - - echo "----" - - - name: Check which Directories have Changes - id: check-dir-changes - run: | - cd "${MAIN_DIR}" - - echo "" - echo ">> Checking for changes from HEAD^..HEAD ..." - - # Extract the chart names from the git diff - RENDER_DIR=$(git diff --name-only HEAD^..HEAD | grep -E "^clusters/${CLUSTER}/helm/" | awk -F '/' '{print $4}' | sort -u || true) - - if [ -n "${RENDER_DIR}" ]; then - echo "" - echo ">> Directories to Render:" - echo "${RENDER_DIR}" - - echo "----" - - echo "changes-detected=true" >> "$GITEA_OUTPUT" - echo "render-dir<> "$GITEA_OUTPUT" - echo "${RENDER_DIR}" >> "$GITEA_OUTPUT" - echo "EOF" >> "$GITEA_OUTPUT" - - else - echo "" - echo ">> No chart changes detected" - echo "changes-detected=false" >> "$GITEA_OUTPUT" - - fi - - - name: Add Repositories - if: steps.check-dir-changes.outputs.changes-detected == 'true' - env: - RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }} - run: | - cd "${MAIN_DIR}" - - echo "" - echo ">> Adding repositories for chart dependencies ..." - for DIR in ${RENDER_DIR}; do - helm dependency list --max-col-width 120 "${MAIN_DIR}/clusters/${CLUSTER}/helm/${DIR}" 2> /dev/null \ - | tail -n +2 \ - | awk 'NF > 0 { print $1, $3 }' \ - | while read -r REPO_NAME REPO_URL; do - if [[ "${REPO_URL}" == oci://* ]]; then - echo "" - echo ">> Ignoring OCI repo: ${REPO_URL}" - - elif [[ -n "${REPO_NAME}" && -n "${REPO_URL}" ]]; then - helm repo add "${REPO_NAME}" "${REPO_URL}" - - fi - done || true - done - - if helm repo list > /dev/null 2>&1; then - echo "" - echo ">> Update repository cache ..." - helm repo update - - fi - - echo "----" - - - name: Remove Changed Manifest Files - if: steps.check-dir-changes.outputs.changes-detected == 'true' - env: - RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }} - run: | - cd "${MANIFEST_DIR}" - - echo "" - echo ">> Remove manfiest files and rebuild from source ..." - - for DIR in ${RENDER_DIR}; do - CHART_PATH=${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/${DIR} - - echo "${CHART_PATH}" - rm -rf ${CHART_PATH}/* - done - - echo "----" - - - name: Render Helm Manifests - id: render-manifests - if: steps.check-dir-changes.outputs.changes-detected == 'true' - env: - RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }} - run: | - cd ${MAIN_DIR} - - echo "" - echo ">> Rendering Manifests ..." - - render_chart() { - local DIR="$1" - local CHART_PATH="${MAIN_DIR}/clusters/${CLUSTER}/helm/${DIR}" - local CHART_NAME=$(basename "${CHART_PATH}") - - echo "" - echo ">> Rendering ..." - echo ">> Chart: ${CHART_NAME}" - echo ">> Path: ${CHART_PATH}" - - if [ -f "${CHART_PATH}/Chart.yaml" ]; then - local OUTPUT_FOLDER="${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/${CHART_NAME}/" - - mkdir -p "${OUTPUT_FOLDER}" - cd "${CHART_PATH}" - - echo "" - echo ">> Updating helm dependencies ..." - helm dependency update --skip-refresh > /dev/null - - echo "" - echo ">> Linting helm chart ..." - helm lint --namespace "${CHART_NAME}" --quiet - - local NAMESPACE="${CHART_NAME}" - case "${CHART_NAME}" in - "stack") - NAMESPACE="argocd" - echo "" - echo ">> Special Rendering into 'argocd' namespace ..." - ;; - "cilium" | "coredns" | "metrics-server" | "prometheus-operator-crds") - NAMESPACE="kube-system" - echo "" - echo ">> Special Rendering for ${CHART_NAME} into 'kube-system' namespace ..." - ;; - *) - echo "" - echo ">> Standard Rendering for ${CHART_NAME} ..." - esac - - echo "" - echo ">> Formating rendered template ..." - local TEMPLATE - TEMPLATE=$(helm template "${CHART_NAME}" ./ --namespace "${NAMESPACE}" --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute") - - # Format and split rendered template - echo "${TEMPLATE}" | yq '... comments=""' | yq 'select(. != null)' | yq -s '"'"${OUTPUT_FOLDER}"'" + .kind + "-" + .metadata.name + ".yaml"' - - # Strip comments again to ensure formatting correctness - for file in "$OUTPUT_FOLDER"/*; do - yq -i '... comments=""' $file - done - - echo "" - echo ">> Manifests for ${CHART_NAME} rendered to ${OUTPUT_FOLDER}:" - ls $OUTPUT_FOLDER - echo "" - else - echo "" - echo ">> Directory ${CHART_PATH} does not contain a Chart.yaml. Skipping ..." - echo "" - fi - } - - export -f render_chart - export MAIN_DIR CLUSTER MANIFEST_DIR - - # Run rendering in parallel - for DIR in ${RENDER_DIR}; do - echo "${DIR}" - done | xargs -n 1 -P 4 -I {} bash -c 'render_chart "$@"' _ {} - - echo "----" - - - name: Check for Changes - id: check-changes - if: steps.check-dir-changes.outputs.changes-detected == 'true' - run: | - cd "${MANIFEST_DIR}" - - GIT_CHANGES=$(git status --porcelain) - - if [ -n "${GIT_CHANGES}" ]; then - echo "" - echo ">> Changes detected" - git status --porcelain - echo "changes-detected=true" >> $GITEA_OUTPUT - - else - echo "" - echo ">> No changes detected, skipping PR creation" - - fi - - echo "----" - - - name: Commit and Push Changes - id: commit-push - if: steps.check-changes.outputs.changes-detected == 'true' - run: | - cd "${MANIFEST_DIR}" - - echo "" - echo ">> Commiting changes to ${BRANCH_NAME} ..." - git add . - git commit -m "chore: Update manifests after change" - - REPO_URL="${{ secrets.REPO_URL }}/${{ gitea.repository }}" - echo "" - echo ">> Pushing changes to ${REPO_URL} ..." - - git push -u "https://oauth2:${{ secrets.BOT_TOKEN }}@${REPO_URL#*://}" "${BRANCH_NAME}" - - echo "----" - - echo "HEAD_BRANCH=${BRANCH_NAME}" >> "$GITEA_OUTPUT" - echo "push=true" >> "$GITEA_OUTPUT" - - - name: Check for Pull Request - id: check-for-pull-requst - if: steps.commit-push.outputs.push == 'true' - env: - GITEA_TOKEN: ${{ secrets.BOT_TOKEN }} - GITEA_URL: ${{ secrets.REPO_URL }} - HEAD_BRANCH: ${{ steps.commit-push.outputs.HEAD_BRANCH }} - run: | - cd ${MANIFEST_DIR} - - API_ENDPOINT="${GITEA_URL}/api/v1/repos/${{ gitea.repository }}/pulls?base_branch=${BASE_BRANCH}&state=open&page=1" - - echo ">> Checking if PR from branch ${HEAD_BRANCH} into ${BASE_BRANCH}" - echo ">> With Endpoint of:" - echo "$API_ENDPOINT" - - HTTP_STATUS=$( - curl -X GET \ - --silent \ - --write-out '%{http_code}' \ - --output response_body.json \ - --dump-header response_headers.txt \ - -H "Authorization: token ${GITEA_TOKEN}" \ - -H "Content-Type: application/json" \ - "$API_ENDPOINT" 2> response_errors.txt - ) - - echo ">> HTTP Status Code: $HTTP_STATUS" - echo ">> Response Output ..." - echo "----" - cat response_body.json - echo "----" - cat response_headers.txt - echo "----" - cat response_errors.txt - echo "----" - - if [ "$HTTP_STATUS" == "200" ] && [ "$(cat response_body.json | jq -r .[0].state)" == "open" ]; then - echo ">> Pull Request has been found open, will update" - PR_INDEX=$(cat response_body.json | jq -r .[0].number) - echo "pull-request-exists=${PR_INDEX}" >> $GITEA_OUTPUT - echo "pull-request-index=true" >> $GITEA_OUTPUT - - elif [ "$HTTP_STATUS" == "200" ] && [ "$(cat response_body.json | jq -r .[0].state)" == "closed" ]; then - echo ">> Pull Request found, but was closed" - echo "pull-request-exists=false" >> $GITEA_OUTPUT - - else - echo ">> Pull Request not found" - echo "pull-request-exists=false" >> $GITEA_OUTPUT - fi - - echo "----" - - - name: Create Pull Request - id: create-pull-request - if: steps.commit-push.outputs.push == 'true' && steps.check-for-pull-requst.outputs.pull-request-exists == 'false' - env: - GITEA_TOKEN: ${{ secrets.BOT_TOKEN }} - GITEA_URL: ${{ secrets.REPO_URL }} - HEAD_BRANCH: ${{ steps.commit-push.outputs.HEAD_BRANCH }} - run: | - cd ${MANIFEST_DIR} - - API_ENDPOINT="${GITEA_URL}/api/v1/repos/${{ gitea.repository }}/pulls" - - PAYLOAD=$( jq -n \ - --arg head "${HEAD_BRANCH}" \ - --arg base "${BASE_BRANCH}" \ - --arg assignee "${ASSIGNEE}" \ - --arg title "Automated Manifest Update" \ - --arg body "This PR contains newly rendered Kubernetes manifests automatically generated by the CI workflow." \ - '{head: $head, base: $base, assignee: $assignee, title: $title, body: $body}' ) - - echo ">> Creating PR from branch ${HEAD_BRANCH} into ${BASE_BRANCH}" - echo ">> With Endpoint of:" - echo "$API_ENDPOINT" - echo ">> With Payload of:" - echo "$PAYLOAD" - - HTTP_STATUS=$( - curl -X POST \ - --silent \ - --write-out '%{http_code}' \ - --output response_body.json \ - --dump-header response_headers.txt \ - --data "$PAYLOAD" \ - -H "Authorization: token ${GITEA_TOKEN}" \ - -H "Content-Type: application/json" \ - "$API_ENDPOINT" 2> response_errors.txt - ) - - echo ">> HTTP Status Code: $HTTP_STATUS" - echo ">> Response Output ..." - echo "----" - cat response_body.json - echo "----" - cat response_headers.txt - echo "----" - cat response_errors.txt - echo "----" - - if [ "$HTTP_STATUS" == "201" ]; then - echo ">> Pull Request created successfully!" - PR_URL=$(cat response_body.json | jq -r .html_url) - echo "pull-request-url=${PR_URL}" >> $GITEA_OUTPUT - PR_ID=$(cat response_body.json | jq -r .id) - echo "pull-request-id=${PR_ID}" >> $GITEA_OUTPUT - echo "pull-request-operation=created" >> $GITEA_OUTPUT - - elif [ "$HTTP_STATUS" == "422" ]; then - echo ">> Failed to create PR (HTTP 422: Unprocessable Entity), PR may already exist" - - elif [ "$HTTP_STATUS" == "409" ]; then - echo ">> Failed to create PR (HTTP 409: Conflict), PR already exists" - - else - echo ">> Failed to create PR, HTTP status code: $HTTP_STATUS" - exit 1 - fi - - echo "----" - - - name: ntfy Created - uses: niniyas/ntfy-action@master - if: steps.create-pull-request.outputs.pull-request-operation == 'created' - with: - url: "${{ secrets.NTFY_URL }}" - topic: "${{ secrets.NTFY_TOPIC }}" - title: "Manifest Render PR Created - Infrastructure" - priority: 3 - headers: '{"Authorization": "Bearer ${{ secrets.NTFY_CRED }}"}' - tags: action,successfully,completed - details: "Manifest rendering for Infrastructure has created a new Pull Request with ID: ${{ steps.create-pull-request.outputs.pull-request-id }}!" - icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/png/gitea.png" - actions: '[{"action": "view", "label": "Open Gitea", "url": "${{ steps.create-pull-request.outputs.pull-request-url }}", "clear": true}]' - - - name: ntfy Failed - uses: niniyas/ntfy-action@master - if: failure() - with: - url: "${{ secrets.NTFY_URL }}" - topic: "${{ secrets.NTFY_TOPIC }}" - title: "Manifest Render Failure - Infrastructure" - priority: 4 - headers: '{"Authorization": "Bearer ${{ secrets.NTFY_CRED }}"}' - tags: action,failed - details: "Manifest rendering for Infrastructure has failed!" - icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/png/gitea.png" - actions: '[{"action": "view", "label": "Open Gitea", "url": "https://gitea.alexlebens.dev/alexlebens/infrastructure/actions?workflow=render-manifests.yaml", "clear": true}]' - image: true diff --git a/.gitea/workflows/render-manifests-push.yaml b/.gitea/workflows/render-manifests-push.yaml deleted file mode 100644 index 12c3c8ad4..000000000 --- a/.gitea/workflows/render-manifests-push.yaml +++ /dev/null @@ -1,449 +0,0 @@ -name: render-manifests-push - -on: - workflow_dispatch: - # push: - # branches: - # - main - # paths: - # - 'clusters/cl01tl/helm/**' - -env: - CLUSTER: cl01tl - BASE_BRANCH: manifests - BRANCH_NAME: auto/update-manifests - ASSIGNEE: alexlebens - MAIN_DIR: /workspace/alexlebens/infrastructure/infrastructure - MANIFEST_DIR: /workspace/alexlebens/infrastructure/infrastructure-manifests - -jobs: - render-manifests-push: - runs-on: ubuntu-js - if: gitea.event.commits[0].author.username != 'renovate-bot' - steps: - - name: Checkout Main - uses: actions/checkout@v6 - with: - path: infrastructure - fetch-depth: 0 - - - name: Checkout Manifests - uses: actions/checkout@v6 - with: - ref: manifests - path: infrastructure-manifests - - - name: Set up Helm - uses: azure/setup-helm@v4 - with: - token: ${{ secrets.GITEA_TOKEN }} - version: v3.17.2 # Pending https://github.com/helm/helm/pull/30743 - cache: true - - - name: Configure Kubeconfig - uses: azure/k8s-set-context@v4 - with: - method: kubeconfig - kubeconfig: ${{ secrets.KUBECONFIG }} - - - name: Cache Helm Dependencies - uses: actions/cache@v5 - with: - path: | - ~/.cache/helm - ~/.config/helm - key: helm-cache-${{ runner.os }}-${{ hashFiles('infrastructure/clusters/cl01tl/helm/**/Chart.yaml', 'infrastructure/clusters/cl01tl/helm/**/Chart.lock') }} - restore-keys: | - helm-cache-${{ runner.os }}- - - - name: Prepare Manifest Branch - run: | - cd "${MANIFEST_DIR}" - - echo "" - echo ">> Configure git to use gitea-bot as user ..." - git config user.name "gitea-bot" - git config user.email "gitea-bot@alexlebens.net" - - echo ">> Checking if PR branch exists ..." - if git ls-remote --exit-code --heads origin "${BRANCH_NAME}" > /dev/null 2>&1; then - echo "" - echo ">> Branch '${BRANCH_NAME}' exists, pulling changes ..." - git fetch origin "${BRANCH_NAME}" - git checkout "${BRANCH_NAME}" - git pull --rebase - - else - echo "" - echo ">> Branch '${BRANCH_NAME}' does not exist, creating ..." - git checkout -b "${BRANCH_NAME}" - - fi - - echo "----" - - - name: Check which Directories have Changes - id: check-dir-changes - run: | - cd "${MAIN_DIR}" - - echo "" - echo ">> Checking for changes ..." - - # Extract the chart names from the git diff - RENDER_DIR=$(git diff --name-only ${{ gitea.event.before }}..HEAD | grep -E "^clusters/${CLUSTER}/helm/" | awk -F '/' '{print $4}' | sort -u || true) - - if [ -n "${RENDER_DIR}" ]; then - echo "" - echo ">> Directories to Render:" - echo "${RENDER_DIR}" - - echo "----" - - echo "changes-detected=true" >> "$GITEA_OUTPUT" - echo "render-dir<> "$GITEA_OUTPUT" - echo "${RENDER_DIR}" >> "$GITEA_OUTPUT" - echo "EOF" >> "$GITEA_OUTPUT" - - else - echo "" - echo ">> No chart changes detected" - echo "changes-detected=false" >> "$GITEA_OUTPUT" - - fi - - - name: Add Repositories - if: steps.check-dir-changes.outputs.changes-detected == 'true' - env: - RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }} - run: | - cd "${MAIN_DIR}" - - echo "" - echo ">> Adding repositories for chart dependencies ..." - for DIR in ${RENDER_DIR}; do - helm dependency list --max-col-width 120 "${MAIN_DIR}/clusters/${CLUSTER}/helm/${DIR}" 2> /dev/null \ - | tail -n +2 \ - | awk 'NF > 0 { print $1, $3 }' \ - | while read -r REPO_NAME REPO_URL; do - if [[ "${REPO_URL}" == oci://* ]]; then - echo "" - echo ">> Ignoring OCI repo: ${REPO_URL}" - - elif [[ -n "${REPO_NAME}" && -n "${REPO_URL}" ]]; then - helm repo add "${REPO_NAME}" "${REPO_URL}" - - fi - done || true - done - - if helm repo list > /dev/null 2>&1; then - echo "" - echo ">> Update repository cache ..." - helm repo update - - fi - - echo "----" - - - name: Remove Changed Manifest Files - if: steps.check-dir-changes.outputs.changes-detected == 'true' - env: - RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }} - run: | - cd "${MANIFEST_DIR}" - - echo "" - echo ">> Remove manfiest files and rebuild from source ..." - - for DIR in ${RENDER_DIR}; do - CHART_PATH=${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/${DIR} - - echo "" - echo "${CHART_PATH}" - rm -rf ${CHART_PATH}/* - done - - echo "----" - - - name: Render Helm Manifests - id: render-manifests - if: steps.check-dir-changes.outputs.changes-detected == 'true' - env: - RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }} - run: | - cd ${MAIN_DIR} - - echo "" - echo ">> Rendering Manifests ..." - - render_chart() { - local DIR="$1" - local CHART_PATH="${MAIN_DIR}/clusters/${CLUSTER}/helm/${DIR}" - local CHART_NAME=$(basename "${CHART_PATH}") - - echo "" - echo ">> Rendering ..." - echo ">> Chart: ${CHART_NAME}" - echo ">> Path: ${CHART_PATH}" - - if [ -f "${CHART_PATH}/Chart.yaml" ]; then - local OUTPUT_FOLDER="${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/${CHART_NAME}/" - - mkdir -p "${OUTPUT_FOLDER}" - cd "${CHART_PATH}" - - echo "" - echo ">> Updating helm dependencies ..." - helm dependency update --skip-refresh > /dev/null - - echo "" - echo ">> Linting helm chart ..." - helm lint --namespace "${CHART_NAME}" --quiet - - local NAMESPACE="${CHART_NAME}" - case "${CHART_NAME}" in - "stack") - NAMESPACE="argocd" - echo "" - echo ">> Special Rendering into 'argocd' namespace ..." - ;; - "cilium" | "coredns" | "metrics-server" | "prometheus-operator-crds") - NAMESPACE="kube-system" - echo "" - echo ">> Special Rendering for ${CHART_NAME} into 'kube-system' namespace ..." - ;; - *) - echo "" - echo ">> Standard Rendering for ${CHART_NAME} ..." - esac - - echo "" - echo ">> Formating rendered template ..." - local TEMPLATE - TEMPLATE=$(helm template "${CHART_NAME}" ./ --namespace "${NAMESPACE}" --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute") - - # Format and split rendered template - echo "${TEMPLATE}" | yq '... comments=""' | yq 'select(. != null)' | yq -s '"'"${OUTPUT_FOLDER}"'" + .kind + "-" + .metadata.name + ".yaml"' - - # Strip comments again to ensure formatting correctness - for file in "$OUTPUT_FOLDER"/*; do - yq -i '... comments=""' $file - done - - echo "" - echo ">> Manifests for ${CHART_NAME} rendered to ${OUTPUT_FOLDER}:" - ls $OUTPUT_FOLDER - echo "" - else - echo "" - echo ">> Directory ${CHART_PATH} does not contain a Chart.yaml. Skipping ..." - echo "" - fi - } - - export -f render_chart - export MAIN_DIR CLUSTER MANIFEST_DIR - - # Run rendering in parallel - for DIR in ${RENDER_DIR}; do - echo "${DIR}" - done | xargs -n 1 -P 4 -I {} bash -c 'render_chart "$@"' _ {} - - echo "----" - - - name: Check for Changes - id: check-changes - if: steps.check-dir-changes.outputs.changes-detected == 'true' - run: | - cd "${MANIFEST_DIR}" - - GIT_CHANGES=$(git status --porcelain) - - if [ -n "${GIT_CHANGES}" ]; then - echo "" - echo ">> Changes detected" - git status --porcelain - echo "changes-detected=true" >> $GITEA_OUTPUT - - else - echo "" - echo ">> No changes detected, skipping PR creation" - - fi - - echo "----" - - - name: Commit and Push Changes - id: commit-push - if: steps.check-changes.outputs.changes-detected == 'true' - run: | - cd "${MANIFEST_DIR}" - - echo "" - echo ">> Commiting changes to ${BRANCH_NAME} ..." - git add . - git commit -m "chore: Update manifests after change" - - REPO_URL="${{ secrets.REPO_URL }}/${{ gitea.repository }}" - echo "" - echo ">> Pushing changes to ${REPO_URL} ..." - - git push -u "https://oauth2:${{ secrets.BOT_TOKEN }}@${REPO_URL#*://}" "${BRANCH_NAME}" - - echo "----" - - echo "HEAD_BRANCH=${BRANCH_NAME}" >> "$GITEA_OUTPUT" - echo "push=true" >> "$GITEA_OUTPUT" - - - name: Check for Pull Request - id: check-for-pull-requst - if: steps.commit-push.outputs.push == 'true' - env: - GITEA_TOKEN: ${{ secrets.BOT_TOKEN }} - GITEA_URL: ${{ secrets.REPO_URL }} - HEAD_BRANCH: ${{ steps.commit-push.outputs.HEAD_BRANCH }} - run: | - cd ${MANIFEST_DIR} - - API_ENDPOINT="${GITEA_URL}/api/v1/repos/${{ gitea.repository }}/pulls?base_branch=${BASE_BRANCH}&state=open&page=1" - - echo ">> Checking if PR from branch ${HEAD_BRANCH} into ${BASE_BRANCH}" - echo ">> With Endpoint of:" - echo "$API_ENDPOINT" - - HTTP_STATUS=$( - curl -X GET \ - --silent \ - --write-out '%{http_code}' \ - --output response_body.json \ - --dump-header response_headers.txt \ - -H "Authorization: token ${GITEA_TOKEN}" \ - -H "Content-Type: application/json" \ - "$API_ENDPOINT" 2> response_errors.txt - ) - - echo ">> HTTP Status Code: $HTTP_STATUS" - echo ">> Response Output ..." - echo "----" - cat response_body.json - echo "----" - cat response_headers.txt - echo "----" - cat response_errors.txt - echo "----" - - if [ "$HTTP_STATUS" == "200" ] && [ "$(cat response_body.json | jq -r .[0].state)" == "open" ]; then - echo ">> Pull Request has been found open, will update" - PR_INDEX=$(cat response_body.json | jq -r .[0].number) - echo "pull-request-exists=${PR_INDEX}" >> $GITEA_OUTPUT - echo "pull-request-index=true" >> $GITEA_OUTPUT - - elif [ "$HTTP_STATUS" == "200" ] && [ "$(cat response_body.json | jq -r .[0].state)" == "closed" ]; then - echo ">> Pull Request found, but was closed" - echo "pull-request-exists=false" >> $GITEA_OUTPUT - - else - echo ">> Pull Request not found" - echo "pull-request-exists=false" >> $GITEA_OUTPUT - fi - - echo "----" - - - name: Create Pull Request - id: create-pull-request - if: steps.commit-push.outputs.push == 'true' && steps.check-for-pull-requst.outputs.pull-request-exists == 'false' - env: - GITEA_TOKEN: ${{ secrets.BOT_TOKEN }} - GITEA_URL: ${{ secrets.REPO_URL }} - HEAD_BRANCH: ${{ steps.commit-push.outputs.HEAD_BRANCH }} - run: | - cd ${MANIFEST_DIR} - - API_ENDPOINT="${GITEA_URL}/api/v1/repos/${{ gitea.repository }}/pulls" - - PAYLOAD=$( jq -n \ - --arg head "${HEAD_BRANCH}" \ - --arg base "${BASE_BRANCH}" \ - --arg assignee "${ASSIGNEE}" \ - --arg title "Automated Manifest Update" \ - --arg body "This PR contains newly rendered Kubernetes manifests automatically generated by the CI workflow." \ - '{head: $head, base: $base, assignee: $assignee, title: $title, body: $body}' ) - - echo ">> Creating PR from branch ${HEAD_BRANCH} into ${BASE_BRANCH}" - echo ">> With Endpoint of:" - echo "$API_ENDPOINT" - echo ">> With Payload of:" - echo "$PAYLOAD" - - HTTP_STATUS=$( - curl -X POST \ - --silent \ - --write-out '%{http_code}' \ - --output response_body.json \ - --dump-header response_headers.txt \ - --data "$PAYLOAD" \ - -H "Authorization: token ${GITEA_TOKEN}" \ - -H "Content-Type: application/json" \ - "$API_ENDPOINT" 2> response_errors.txt - ) - - echo ">> HTTP Status Code: $HTTP_STATUS" - echo ">> Response Output ..." - echo "----" - cat response_body.json - echo "----" - cat response_headers.txt - echo "----" - cat response_errors.txt - echo "----" - - if [ "$HTTP_STATUS" == "201" ]; then - echo ">> Pull Request created successfully!" - PR_URL=$(cat response_body.json | jq -r .html_url) - echo "pull-request-url=${PR_URL}" >> $GITEA_OUTPUT - PR_ID=$(cat response_body.json | jq -r .id) - echo "pull-request-id=${PR_ID}" >> $GITEA_OUTPUT - echo "pull-request-operation=created" >> $GITEA_OUTPUT - - elif [ "$HTTP_STATUS" == "422" ]; then - echo ">> Failed to create PR (HTTP 422: Unprocessable Entity), PR may already exist" - - elif [ "$HTTP_STATUS" == "409" ]; then - echo ">> Failed to create PR (HTTP 409: Conflict), PR already exists" - - else - echo ">> Failed to create PR, HTTP status code: $HTTP_STATUS" - exit 1 - fi - - echo "----" - - - name: ntfy Created - uses: niniyas/ntfy-action@master - if: steps.create-pull-request.outputs.pull-request-operation == 'created' - with: - url: "${{ secrets.NTFY_URL }}" - topic: "${{ secrets.NTFY_TOPIC }}" - title: "Manifest Render PR Created - Infrastructure" - priority: 3 - headers: '{"Authorization": "Bearer ${{ secrets.NTFY_CRED }}"}' - tags: action,successfully,completed - details: "Manifest rendering for Infrastructure has created a new Pull Request with ID: ${{ steps.create-pull-request.outputs.pull-request-id }}!" - icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/png/gitea.png" - actions: '[{"action": "view", "label": "Open Gitea", "url": "${{ steps.create-pull-request.outputs.pull-request-url }}", "clear": true}]' - - - name: ntfy Failed - uses: niniyas/ntfy-action@master - if: failure() - with: - url: "${{ secrets.NTFY_URL }}" - topic: "${{ secrets.NTFY_TOPIC }}" - title: "Manifest Render Failure - Infrastructure" - priority: 4 - headers: '{"Authorization": "Bearer ${{ secrets.NTFY_CRED }}"}' - tags: action,failed - details: "Manifest rendering for Infrastructure has failed!" - icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/png/gitea.png" - actions: '[{"action": "view", "label": "Open Gitea", "url": "https://gitea.alexlebens.dev/alexlebens/infrastructure/actions?workflow=render-manifests.yaml", "clear": true}]' - image: true