diff --git a/.github/workflows/argocd-diff-preview.yml b/.github/workflows/argocd-diff-preview.yml index bc90347..0c76e5c 100644 --- a/.github/workflows/argocd-diff-preview.yml +++ b/.github/workflows/argocd-diff-preview.yml @@ -4,6 +4,9 @@ # - Helm-rendered repos: set helm_chart_path (and optionally helm_values_files) to pre-render before diffing # Posts the diff as a PR comment (updated in place on subsequent runs). # +# For private repos, pass SSH_PRIVATE_KEY and REPO_SSH_URL secrets. +# The caller is responsible for obtaining these (e.g. decrypting from SOPS) before calling this workflow. +# # Requirements: # - Caller must set `pull-requests: write` permission # - Caller must pass a GitHub PAT (repo read access) via the GH_PAT secret @@ -46,6 +49,12 @@ on: GH_PAT: description: 'GitHub PAT with repo read access (used by argocd-diff-preview to clone the private repo)' required: true + SSH_PRIVATE_KEY: + description: 'SSH private key for ArgoCD to clone the repo. Required for private repos.' + required: false + REPO_SSH_URL: + description: 'SSH URL of the repo (e.g. git@github.com:org/repo.git). Required when SSH_PRIVATE_KEY is set.' + required: false jobs: diff: @@ -106,6 +115,25 @@ jobs: cp -r "$REPO_PATH/." /tmp/argocd-diff/base fi + - name: Prepare ArgoCD repo credentials + env: + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + REPO_SSH_URL: ${{ secrets.REPO_SSH_URL }} + run: | + mkdir -p /tmp/argocd-diff/secrets + if [ -n "$SSH_PRIVATE_KEY" ] && [ -n "$REPO_SSH_URL" ]; then + yq -n ' + .apiVersion = "v1" | + .kind = "Secret" | + .metadata.name = "private-repo" | + .metadata.namespace = "argocd" | + .metadata.labels["argocd.argoproj.io/secret-type"] = "repository" | + .stringData.type = "git" | + .stringData.url = strenv(REPO_SSH_URL) | + .stringData.sshPrivateKey = strenv(SSH_PRIVATE_KEY) + ' > /tmp/argocd-diff/secrets/repo-creds.yaml + fi + - name: Run argocd-diff-preview env: REPO: ${{ github.repository }} @@ -123,6 +151,7 @@ jobs: -v /tmp/argocd-diff/base:/base-branch -v /tmp/argocd-diff/target:/target-branch -v /tmp/argocd-diff/output:/output + -v /tmp/argocd-diff/secrets:/secrets -e REPO -e TARGET_BRANCH -e BASE_BRANCH diff --git a/docs/workflows/argocd-diff-preview.md b/docs/workflows/argocd-diff-preview.md index 9ecf8b0..fe7a76f 100644 --- a/docs/workflows/argocd-diff-preview.md +++ b/docs/workflows/argocd-diff-preview.md @@ -1,15 +1,23 @@ # ArgoCD Diff Preview -Reusable workflow that generates an ArgoCD manifest diff for pull requests and posts it as a PR comment. It pre-renders an umbrella Helm chart to extract `Application` manifests from both the base and target branches, then uses [argocd-diff-preview](https://github.com/dag-andersen/argocd-diff-preview) to spin up an ephemeral cluster, render the manifests through ArgoCD, and compute the diff. +Reusable workflow that generates an ArgoCD manifest diff for pull requests and posts it as a PR comment. It uses [argocd-diff-preview](https://github.com/dag-andersen/argocd-diff-preview) to spin up an ephemeral Kind cluster, render manifests through ArgoCD, and compute the diff. The PR comment is created on first run and **updated in place** on subsequent runs — no comment spam. +Supports two modes: + +- **Plain YAML** — point it at a directory that already contains `Application` manifests +- **Helm-rendered** — provide a chart path and values files; the workflow pre-renders the chart before diffing + +For private repos, pass `SSH_PRIVATE_KEY` and `REPO_SSH_URL` secrets. The caller is responsible for obtaining these values (e.g. extracting from a secrets manager) before calling this workflow. + ## How it works -1. Checkout the PR branch → `helm template ` → rendered Application manifests saved to a temp folder -2. Checkout the base branch → same render → saved to another temp folder -3. `argocd-diff-preview` spins up a Kind cluster, installs ArgoCD, applies both sets of manifests, and produces a `diff.md` -4. The diff is posted (or updated) as a PR comment +1. Checkout the PR branch → prepare manifests (copy or `helm template`) → saved to a temp folder +2. Checkout the base branch → same preparation → saved to another temp folder +3. If `SSH_PRIVATE_KEY` and `REPO_SSH_URL` are provided, generate an ArgoCD repository secret YAML in `/secrets/` +4. `argocd-diff-preview` spins up a Kind cluster, installs ArgoCD (with the repo credentials), renders both sets of manifests, and produces a `diff.md` +5. The diff is posted (or updated) as a PR comment > **Note**: The ephemeral cluster adds ~60–90 seconds to each run. @@ -17,8 +25,9 @@ The PR comment is created on first run and **updated in place** on subsequent ru | Input | Description | Required | Default | | :--- | :--- | :--- | :--- | -| `apps_chart_path` | Path to the umbrella Helm chart that generates ArgoCD `Application` manifests. | No | `apps/` | -| `helm_values_files` | Space-separated list of values files to pass to `helm template` (e.g. `"apps/values/base.yaml apps/values/prod.yaml"`). | No | — | +| `repo_path` | Directory containing `Application` manifests. Used when not rendering via Helm. | No | `.` | +| `helm_chart_path` | Path to the Helm chart to render into `Application` manifests. When set, Helm rendering is enabled. | No | — | +| `helm_values_files` | Space-separated list of values files for `helm template` (e.g. `"apps/values/base.yaml apps/values/prod.yaml"`). Only used when `helm_chart_path` is set. | No | — | | `base_branch` | Branch to compare against. | No | `main` | | `argocd_version` | ArgoCD Helm chart version to install in the ephemeral cluster. When empty, uses the latest. | No | — | | `timeout` | Timeout in seconds for argocd-diff-preview. | No | `300` | @@ -27,7 +36,9 @@ The PR comment is created on first run and **updated in place** on subsequent ru | Secret | Required | Description | | :--- | :--- | :--- | -| `GH_PAT` | Yes | GitHub PAT with `repo` (read) scope. Required because argocd-diff-preview needs to interact with the GitHub API for private repositories. | +| `GH_PAT` | Yes | GitHub PAT with `repo` (read) scope. Required for argocd-diff-preview to interact with the GitHub API on private repositories. | +| `SSH_PRIVATE_KEY` | No | SSH private key for ArgoCD to clone the repo. Required for private repos. | +| `REPO_SSH_URL` | No | SSH URL of the repo (e.g. `git@github.com:org/repo.git`). Required when `SSH_PRIVATE_KEY` is set. | ## Caller permissions @@ -41,7 +52,7 @@ permissions: ## Usage -Basic usage with an umbrella chart and a single values file: +### Plain YAML repo (public) ```yaml name: ArgoCD Diff Preview @@ -49,9 +60,6 @@ name: ArgoCD Diff Preview on: pull_request: branches: [main] - paths: - - 'apps/**' - - 'components/**' permissions: contents: read @@ -61,34 +69,43 @@ jobs: argocd-diff: uses: AutomationDojo/reusable-cicd/.github/workflows/argocd-diff-preview.yml@main with: - apps_chart_path: apps/ - helm_values_files: apps/values/prod.yaml - base_branch: main + repo_path: apps/ secrets: GH_PAT: ${{ secrets.GH_PAT }} ``` -With multiple values files (e.g. base + environment overlay): +### Helm-rendered repo (private) + +For repos where `Application` manifests are generated by a Helm chart and the repo is private: ```yaml +name: ArgoCD Diff Preview + +on: + pull_request: + branches: [main] + paths: + - 'apps/**' + - 'components/**' + +permissions: + contents: read + pull-requests: write + jobs: argocd-diff: uses: AutomationDojo/reusable-cicd/.github/workflows/argocd-diff-preview.yml@main with: - apps_chart_path: apps/ - helm_values_files: apps/values/base.yaml apps/values/prod.yaml + helm_chart_path: apps/ + helm_values_files: apps/values/prod.yaml secrets: GH_PAT: ${{ secrets.GH_PAT }} + SSH_PRIVATE_KEY: ${{ secrets.ARGOCD_SSH_PRIVATE_KEY }} + REPO_SSH_URL: ${{ secrets.ARGOCD_REPO_SSH_URL }} ``` -## Requirements - -- The chart at `apps_chart_path` must render `kind: Application` manifests — argocd-diff-preview uses these to know what to render. -- If your `Application` definitions are Helm templates (not committed as plain YAML), this pre-render step is **required**. The workflow handles it automatically. -- The `GH_PAT` secret must be configured in the caller repository under **Settings → Secrets → Actions**. - ## Notes -- Only runs on pull requests — it has no effect on push events. +- `SSH_PRIVATE_KEY` and `REPO_SSH_URL` should be stored as GitHub Actions secrets in the caller repository (**Settings → Secrets → Actions**). - The workflow uses Docker and requires a `ubuntu-latest` runner with Docker available (default on GitHub-hosted runners). -- ArgoCD version can be pinned via `argocd_version` to ensure consistent rendering across runs. +- ArgoCD version can be pinned via `argocd_version` to ensure consistent rendering across runs. \ No newline at end of file