diff --git a/.gitea/workflows/homelab-main.yml b/.gitea/workflows/homelab-main.yml index e450861..3a88260 100644 --- a/.gitea/workflows/homelab-main.yml +++ b/.gitea/workflows/homelab-main.yml @@ -6,7 +6,7 @@ name: Homelab Main - main jobs: - validate-and-deploy: + deploy: runs-on: homelab-debian steps: @@ -21,132 +21,6 @@ jobs: git checkout --force "${{ gitea.sha }}" git config --global --add safe.directory "$PWD" - - name: Verify Debian runner guardrails - run: | - set -euo pipefail - - test "$(uname -s)" = "Linux" - . /etc/os-release - test "${ID}" = "debian" - sudo -n true - - - name: Scan for leaked secrets with Gitleaks - run: | - set -euo pipefail - - gitleaks_version="8.30.1" - case "$(uname -m)" in - x86_64|amd64) - gitleaks_platform="linux_x64" - gitleaks_sha256="551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb" - ;; - aarch64|arm64) - gitleaks_platform="linux_arm64" - gitleaks_sha256="e4a487ee7ccd7d3a7f7ec08657610aa3606637dab924210b3aee62570fb4b080" - ;; - *) - echo "Unsupported runner architecture: $(uname -m)" >&2 - exit 1 - ;; - esac - - tool_dir="${HOME}/.cache/homelab-tools/gitleaks/${gitleaks_version}/${gitleaks_platform}" - gitleaks_bin="${tool_dir}/gitleaks" - if [[ ! -x "${gitleaks_bin}" ]] || [[ "$("${gitleaks_bin}" version)" != "${gitleaks_version}" ]]; then - archive="gitleaks_${gitleaks_version}_${gitleaks_platform}.tar.gz" - tmpdir="$(mktemp -d)" - trap 'rm -rf "${tmpdir}"' EXIT - - curl -fsSL -o "${tmpdir}/${archive}" \ - "https://github.com/gitleaks/gitleaks/releases/download/v${gitleaks_version}/${archive}" - printf '%s %s\n' "${gitleaks_sha256}" "${tmpdir}/${archive}" | sha256sum -c - - - mkdir -p "${tool_dir}" - tar -xzf "${tmpdir}/${archive}" -C "${tmpdir}" gitleaks - install -m 0755 "${tmpdir}/gitleaks" "${gitleaks_bin}" - fi - - "${gitleaks_bin}" git --redact=100 --verbose --exit-code 1 . - - - name: Scan for vulnerabilities and misconfigurations with Trivy - run: | - set -euo pipefail - - trivy_version="0.70.0" - case "$(uname -m)" in - x86_64|amd64) - trivy_platform="Linux-64bit" - trivy_sha256="8b4376d5d6befe5c24d503f10ff136d9e0c49f9127a4279fd110b727929a5aa9" - ;; - aarch64|arm64) - trivy_platform="Linux-ARM64" - trivy_sha256="2f6bb988b553a1bbac6bdd1ce890f5e412439564e17522b88a4541b4f364fc8d" - ;; - *) - echo "Unsupported runner architecture: $(uname -m)" >&2 - exit 1 - ;; - esac - - tool_dir="${HOME}/.cache/homelab-tools/trivy/${trivy_version}/${trivy_platform}" - trivy_bin="${tool_dir}/trivy" - installed_version="" - if [[ -x "${trivy_bin}" ]]; then - installed_version="$("${trivy_bin}" --version | awk '/^Version:/ {print $2; exit}')" - fi - if [[ "${installed_version}" != "${trivy_version}" ]]; then - archive="trivy_${trivy_version}_${trivy_platform}.tar.gz" - tmpdir="$(mktemp -d)" - trap 'rm -rf "${tmpdir}"' EXIT - - curl -fsSL -o "${tmpdir}/${archive}" \ - "https://github.com/aquasecurity/trivy/releases/download/v${trivy_version}/${archive}" - printf '%s %s\n' "${trivy_sha256}" "${tmpdir}/${archive}" | sha256sum -c - - - mkdir -p "${tool_dir}" - tar -xzf "${tmpdir}/${archive}" -C "${tmpdir}" trivy - install -m 0755 "${tmpdir}/trivy" "${trivy_bin}" - fi - - trivy_cache="${HOME}/.cache/homelab-tools/trivy/cache" - trivy_docker_config="${HOME}/.cache/homelab-tools/trivy/docker-config" - mkdir -p "${trivy_cache}" "${trivy_docker_config}" - printf '{}\n' > "${trivy_docker_config}/config.json" - export DOCKER_CONFIG="${trivy_docker_config}" - - trivy_ignore_args=() - if [[ -f .trivyignore.yaml ]]; then - trivy_ignore_args=(--ignorefile .trivyignore.yaml) - fi - - "${trivy_bin}" fs --scanners vuln,misconfig --severity HIGH,CRITICAL \ - --exit-code 0 --no-progress --cache-dir "${trivy_cache}" "${trivy_ignore_args[@]}" . - "${trivy_bin}" fs --scanners vuln,misconfig --severity CRITICAL \ - --exit-code 1 --no-progress --cache-dir "${trivy_cache}" "${trivy_ignore_args[@]}" . - - - name: Validate shell, Kubernetes manifests, and OpenTofu stacks - run: | - set -euo pipefail - - bash -n lab.sh - docker compose -f infra/gitea/docker-compose.yml config >/dev/null - - kubectl --kubeconfig "${KUBECONFIG:-/home/jv/.kube/config}" apply --dry-run=server --recursive -f apps - - set +e - kubectl --kubeconfig "${KUBECONFIG:-/home/jv/.kube/config}" diff --recursive -f apps - diff_status="$?" - set -e - if (( diff_status > 1 )); then - exit "${diff_status}" - fi - - for stack in bootstrap/provisioning bootstrap/cluster bootstrap/platform bootstrap/apps bootstrap/edge; do - tofu -chdir="${stack}" init -input=false - tofu -chdir="${stack}" fmt -check - tofu -chdir="${stack}" validate - done - - name: Block automatic deploy for Raspberry Pi Gitea changes run: | set -euo pipefail @@ -245,7 +119,7 @@ jobs: exit 1 fi - - name: Deploy validated main branch + - name: Deploy main branch run: | set -euo pipefail @@ -264,4 +138,3 @@ jobs: git -C "${deploy_dir}" push local-bootstrap HEAD:main "${deploy_dir}/lab.sh" apps - kubectl --kubeconfig "${KUBECONFIG:-/home/jv/.kube/config}" -n argocd get applications diff --git a/README.md b/README.md index efb4615..ec2130d 100644 --- a/README.md +++ b/README.md @@ -355,7 +355,7 @@ The Debian bare repo remains the GitOps mirror: ``` Argo CD consumes that Debian mirror through the default `gitops_repo_url`. -Gitea Actions pushes the validated `main` commit into the mirror before running +Gitea Actions pushes the `main` commit into the mirror before running `./lab.sh apps`. Deploy or refresh the external Gitea container from the Debian host with: @@ -406,12 +406,10 @@ This repo includes a Gitea Actions workflow at `.gitea/workflows/homelab-main.yml`. It runs only on pushes to `main` and targets a repository-scoped Debian host runner with the label `homelab-debian`. -The workflow validates shell syntax, Kubernetes manifests, and all OpenTofu -stacks before deployment. Automatic deploy is blocked only for Raspberry Pi -Gitea service changes: files under `infra/gitea/`, or edits inside the -`deploy_gitea`, `install_gitea_backup_timer`, `backup_gitea`, or -`drill_gitea_restore` functions in `lab.sh`. Other changes proceed to -`./lab.sh apps` after validation passes. +The workflow only blocks automatic deploy for Raspberry Pi Gitea service +changes: files under `infra/gitea/`, or edits inside the `deploy_gitea`, +`install_gitea_backup_timer`, `backup_gitea`, or `drill_gitea_restore` +functions in `lab.sh`. Other changes proceed directly to `./lab.sh apps`. `./lab.sh bootstrap-gitea-repo` also registers the Debian host SSH public key with the Gitea repository and switches the Debian working copy's `gitea` remote @@ -440,7 +438,7 @@ uses a host label instead of a Docker job container because deployment needs the Debian host's Docker, OpenTofu, kubeconfig, SSH keys, and local state. The deployment job is non-interactive. User `jv` must be able to run `sudo -n -true` on the Debian host or the workflow will fail before deployment. +true` on the Debian host for deployment commands that require sudo. Useful checks: