Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/argocd-diff-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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 }}
Expand All @@ -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
Expand Down
69 changes: 43 additions & 26 deletions docs/workflows/argocd-diff-preview.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
# 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 <chart>` → 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.

## Inputs

| 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` |
Expand All @@ -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

Expand All @@ -41,17 +52,14 @@ permissions:

## Usage

Basic usage with an umbrella chart and a single values file:
### Plain YAML repo (public)

```yaml
name: ArgoCD Diff Preview

on:
pull_request:
branches: [main]
paths:
- 'apps/**'
- 'components/**'

permissions:
contents: read
Expand All @@ -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.