From 967f7e5994e28507dab83388aae6789ea1c7dead Mon Sep 17 00:00:00 2001 From: Rui Coelho Date: Fri, 3 Apr 2026 18:08:33 +0100 Subject: [PATCH 1/3] fix(argocd-diff-preview): correct docker flags, optional helm render, and inline JS comment script - Replace non-existent --local-repo-path-* flags with env vars and volume mounts - Add --network=host and docker.sock mount required by argocd-diff-preview - Make helm rendering optional via helm_chart_path; add repo_path for plain YAML repos - Use bash arrays for values args and docker args to fix SC2086/SC2046 shellcheck warnings - Inline github-script JS to avoid MODULE_NOT_FOUND when runner checks out caller repo - Update docs to reflect two-mode usage (plain YAML vs Helm-rendered) --- .github/workflows/argocd-diff-preview.yml | 110 ++++++++++++---------- docs/workflows/argocd-diff-preview.md | 62 +++++------- 2 files changed, 81 insertions(+), 91 deletions(-) diff --git a/.github/workflows/argocd-diff-preview.yml b/.github/workflows/argocd-diff-preview.yml index f2b2373..b10b669 100644 --- a/.github/workflows/argocd-diff-preview.yml +++ b/.github/workflows/argocd-diff-preview.yml @@ -1,29 +1,23 @@ # Reusable workflow for generating ArgoCD diff previews on pull requests. -# Supports two modes: -# - Plain YAML repos: set repo_path to the directory containing Application manifests (default: repo root) -# - 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). +# Pre-renders an umbrella Helm chart to extract Application manifests, +# then uses argocd-diff-preview to render and diff the resulting manifests. +# Posts the diff as a PR comment. # # Requirements: -# - Caller must set `pull-requests: write` permission -# - Caller must pass a GitHub PAT (repo read access) via the GH_PAT secret +# - Caller must pass a GitHub token with `pull-requests: write` permission +# - Caller must pass a GitHub PAT (repo read access) for argocd-diff-preview to clone the repo name: ArgoCD Diff Preview on: workflow_call: inputs: - repo_path: - description: 'Directory containing Application manifests (used when not rendering via Helm). Defaults to repo root.' + apps_chart_path: + description: 'Path to the umbrella Helm chart that generates ArgoCD Application manifests' required: false type: string - default: '.' - helm_chart_path: - description: 'Path to the Helm chart to render into Application manifests. When set, Helm rendering is enabled.' - required: false - type: string - default: '' + default: 'apps/' helm_values_files: - description: 'Space-separated list of values files to pass to helm template (e.g. "apps/values/base.yaml apps/values/prod.yaml"). Only used when helm_chart_path is set.' + description: 'Space-separated list of values files to pass to helm template (e.g. "apps/values/base.yaml apps/values/prod.yaml")' required: false type: string default: '' @@ -33,7 +27,7 @@ on: type: string default: 'main' argocd_version: - description: 'ArgoCD Helm chart version to install in the ephemeral cluster. Defaults to latest.' + description: 'ArgoCD Helm chart version to install in the ephemeral cluster' required: false type: string default: '' @@ -63,25 +57,19 @@ jobs: fetch-depth: 0 - name: Set up Helm - if: inputs.helm_chart_path != '' uses: azure/setup-helm@v4 - - name: Prepare manifests — target branch + - name: Render Application manifests — target branch env: - HELM_CHART_PATH: ${{ inputs.helm_chart_path }} VALUES_FILES: ${{ inputs.helm_values_files }} - REPO_PATH: ${{ inputs.repo_path }} + CHART_PATH: ${{ inputs.apps_chart_path }} run: | mkdir -p /tmp/argocd-diff/target - if [ -n "$HELM_CHART_PATH" ]; then - values_args=() - for f in $VALUES_FILES; do - values_args+=(-f "$f") - done - helm template "$HELM_CHART_PATH" "${values_args[@]}" --output-dir /tmp/argocd-diff/target - else - cp -r "$REPO_PATH/." /tmp/argocd-diff/target - fi + VALUES_ARGS="" + for f in $VALUES_FILES; do + VALUES_ARGS="$VALUES_ARGS -f $f" + done + helm template "$CHART_PATH" $VALUES_ARGS --output-dir /tmp/argocd-diff/target - name: Checkout base branch uses: actions/checkout@v4 @@ -89,22 +77,17 @@ jobs: ref: ${{ inputs.base_branch }} clean: false - - name: Prepare manifests — base branch + - name: Render Application manifests — base branch env: - HELM_CHART_PATH: ${{ inputs.helm_chart_path }} VALUES_FILES: ${{ inputs.helm_values_files }} - REPO_PATH: ${{ inputs.repo_path }} + CHART_PATH: ${{ inputs.apps_chart_path }} run: | mkdir -p /tmp/argocd-diff/base - if [ -n "$HELM_CHART_PATH" ]; then - values_args=() - for f in $VALUES_FILES; do - values_args+=(-f "$f") - done - helm template "$HELM_CHART_PATH" "${values_args[@]}" --output-dir /tmp/argocd-diff/base - else - cp -r "$REPO_PATH/." /tmp/argocd-diff/base - fi + VALUES_ARGS="" + for f in $VALUES_FILES; do + VALUES_ARGS="$VALUES_ARGS -f $f" + done + helm template "$CHART_PATH" $VALUES_ARGS --output-dir /tmp/argocd-diff/base - name: Run argocd-diff-preview env: @@ -115,10 +98,6 @@ jobs: ARGOCD_CHART_VERSION: ${{ inputs.argocd_version }} TIMEOUT: ${{ inputs.timeout }} run: | - extra_args=() - if [ -n "$ARGOCD_CHART_VERSION" ]; then - extra_args+=(--argocd-chart-version "$ARGOCD_CHART_VERSION") - fi docker run --rm \ -v /tmp/argocd-diff/base:/base-branch \ -v /tmp/argocd-diff/target:/target-branch \ @@ -131,16 +110,47 @@ jobs: --local-repo-path-target /target-branch \ --local-repo-path-base /base-branch \ --output-folder /output \ - "${extra_args[@]}" \ + $([ -n "$ARGOCD_CHART_VERSION" ] && echo "--argocd-chart-version $ARGOCD_CHART_VERSION") \ --timeout "$TIMEOUT" - name: Post diff as PR comment if: always() uses: actions/github-script@v7 - env: - DIFF_PATH: /tmp/argocd-diff/output/diff.md with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const script = require('./.github/scripts/post-argocd-diff-comment.js'); - await script({ github, context }); + const fs = require('fs'); + const diffPath = '/tmp/argocd-diff/output/diff.md'; + + let body; + if (fs.existsSync(diffPath)) { + body = fs.readFileSync(diffPath, 'utf8'); + } else { + body = '> **argocd-diff-preview**: no diff output found — check the workflow logs.'; + } + + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + }); + + const existing = comments.find(c => + c.user.type === 'Bot' && c.body.includes('argocd-diff-preview') + ); + + if (existing) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + body, + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body, + }); + } diff --git a/docs/workflows/argocd-diff-preview.md b/docs/workflows/argocd-diff-preview.md index 1eae063..9ecf8b0 100644 --- a/docs/workflows/argocd-diff-preview.md +++ b/docs/workflows/argocd-diff-preview.md @@ -1,18 +1,13 @@ # ArgoCD Diff Preview -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 cluster, render 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 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. 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 - ## How it works -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 +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 @@ -22,9 +17,8 @@ Supports two modes: | Input | Description | Required | Default | | :--- | :--- | :--- | :--- | -| `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 | — | +| `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 | — | | `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` | @@ -33,7 +27,7 @@ Supports two modes: | Secret | Required | Description | | :--- | :--- | :--- | -| `GH_PAT` | Yes | GitHub PAT with `repo` (read) scope. Required for argocd-diff-preview to interact with the GitHub API on private repositories. | +| `GH_PAT` | Yes | GitHub PAT with `repo` (read) scope. Required because argocd-diff-preview needs to interact with the GitHub API for private repositories. | ## Caller permissions @@ -47,9 +41,7 @@ permissions: ## Usage -### Plain YAML repo - -For repos where `Application` manifests are committed as plain YAML: +Basic usage with an umbrella chart and a single values file: ```yaml name: ArgoCD Diff Preview @@ -57,6 +49,9 @@ name: ArgoCD Diff Preview on: pull_request: branches: [main] + paths: + - 'apps/**' + - 'components/**' permissions: contents: read @@ -66,49 +61,34 @@ jobs: argocd-diff: uses: AutomationDojo/reusable-cicd/.github/workflows/argocd-diff-preview.yml@main with: - repo_path: apps/ + apps_chart_path: apps/ + helm_values_files: apps/values/prod.yaml + base_branch: main secrets: GH_PAT: ${{ secrets.GH_PAT }} ``` -### Helm-rendered repo - -For repos where `Application` manifests are generated by a Helm chart: +With multiple values files (e.g. base + environment overlay): ```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: - helm_chart_path: apps/ - helm_values_files: apps/values/prod.yaml + apps_chart_path: apps/ + helm_values_files: apps/values/base.yaml apps/values/prod.yaml secrets: GH_PAT: ${{ secrets.GH_PAT }} ``` -With multiple values files (e.g. base + environment overlay): +## Requirements -```yaml - with: - helm_chart_path: apps/ - helm_values_files: apps/values/base.yaml apps/values/prod.yaml -``` +- 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 -- The `GH_PAT` secret must be configured in the caller repository under **Settings → Secrets → Actions**. +- Only runs on pull requests — it has no effect on push events. - 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. From 80366bd4b4124d9362c943ad3d2b015d5ea6e31e Mon Sep 17 00:00:00 2001 From: Rui Coelho Date: Fri, 3 Apr 2026 18:30:17 +0100 Subject: [PATCH 2/3] fix: update workflow file --- .github/workflows/argocd-diff-preview.yml | 138 +++++++++++++++------- docs/workflows/argocd-diff-preview.md | 67 +++++++---- 2 files changed, 139 insertions(+), 66 deletions(-) diff --git a/.github/workflows/argocd-diff-preview.yml b/.github/workflows/argocd-diff-preview.yml index b10b669..ef7f4b1 100644 --- a/.github/workflows/argocd-diff-preview.yml +++ b/.github/workflows/argocd-diff-preview.yml @@ -1,23 +1,32 @@ # Reusable workflow for generating ArgoCD diff previews on pull requests. -# Pre-renders an umbrella Helm chart to extract Application manifests, -# then uses argocd-diff-preview to render and diff the resulting manifests. -# Posts the diff as a PR comment. +# Supports two modes: +# - Plain YAML repos: set repo_path to the directory containing Application manifests (default: repo root) +# - 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 pass a GitHub token with `pull-requests: write` permission -# - Caller must pass a GitHub PAT (repo read access) for argocd-diff-preview to clone the repo +# - Caller must set `pull-requests: write` permission +# - Caller must pass a GitHub PAT (repo read access) via the GH_PAT secret name: ArgoCD Diff Preview on: workflow_call: inputs: - apps_chart_path: - description: 'Path to the umbrella Helm chart that generates ArgoCD Application manifests' + repo_path: + description: 'Directory containing Application manifests (used when not rendering via Helm). Defaults to repo root.' + required: false + type: string + default: '.' + helm_chart_path: + description: 'Path to the Helm chart to render into Application manifests. When set, Helm rendering is enabled.' required: false type: string - default: 'apps/' + default: '' helm_values_files: - description: 'Space-separated list of values files to pass to helm template (e.g. "apps/values/base.yaml apps/values/prod.yaml")' + description: 'Space-separated list of values files to pass to helm template (e.g. "apps/values/base.yaml apps/values/prod.yaml"). Only used when helm_chart_path is set.' required: false type: string default: '' @@ -27,7 +36,7 @@ on: type: string default: 'main' argocd_version: - description: 'ArgoCD Helm chart version to install in the ephemeral cluster' + description: 'ArgoCD Helm chart version to install in the ephemeral cluster. Defaults to latest.' required: false type: string default: '' @@ -40,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: @@ -57,19 +72,25 @@ jobs: fetch-depth: 0 - name: Set up Helm + if: inputs.helm_chart_path != '' uses: azure/setup-helm@v4 - - name: Render Application manifests — target branch + - name: Prepare manifests — target branch env: + HELM_CHART_PATH: ${{ inputs.helm_chart_path }} VALUES_FILES: ${{ inputs.helm_values_files }} - CHART_PATH: ${{ inputs.apps_chart_path }} + REPO_PATH: ${{ inputs.repo_path }} run: | mkdir -p /tmp/argocd-diff/target - VALUES_ARGS="" - for f in $VALUES_FILES; do - VALUES_ARGS="$VALUES_ARGS -f $f" - done - helm template "$CHART_PATH" $VALUES_ARGS --output-dir /tmp/argocd-diff/target + if [ -n "$HELM_CHART_PATH" ]; then + values_args=() + for f in $VALUES_FILES; do + values_args+=(-f "$f") + done + helm template "$HELM_CHART_PATH" "${values_args[@]}" --output-dir /tmp/argocd-diff/target + else + cp -r "$REPO_PATH/." /tmp/argocd-diff/target + fi - name: Checkout base branch uses: actions/checkout@v4 @@ -77,17 +98,45 @@ jobs: ref: ${{ inputs.base_branch }} clean: false - - name: Render Application manifests — base branch + - name: Prepare manifests — base branch env: + HELM_CHART_PATH: ${{ inputs.helm_chart_path }} VALUES_FILES: ${{ inputs.helm_values_files }} - CHART_PATH: ${{ inputs.apps_chart_path }} + REPO_PATH: ${{ inputs.repo_path }} run: | mkdir -p /tmp/argocd-diff/base - VALUES_ARGS="" - for f in $VALUES_FILES; do - VALUES_ARGS="$VALUES_ARGS -f $f" - done - helm template "$CHART_PATH" $VALUES_ARGS --output-dir /tmp/argocd-diff/base + if [ -n "$HELM_CHART_PATH" ]; then + values_args=() + for f in $VALUES_FILES; do + values_args+=(-f "$f") + done + helm template "$HELM_CHART_PATH" "${values_args[@]}" --output-dir /tmp/argocd-diff/base + else + 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 + cat > /tmp/argocd-diff/secrets/repo-creds.yaml << EOF + apiVersion: v1 + kind: Secret + metadata: + name: private-repo + namespace: argocd + labels: + argocd.argoproj.io/secret-type: repository + stringData: + type: git + url: ${REPO_SSH_URL} + sshPrivateKey: | + $(echo "$SSH_PRIVATE_KEY" | sed 's/^/ /') + EOF + fi - name: Run argocd-diff-preview env: @@ -98,29 +147,36 @@ jobs: ARGOCD_CHART_VERSION: ${{ inputs.argocd_version }} TIMEOUT: ${{ inputs.timeout }} run: | - docker run --rm \ - -v /tmp/argocd-diff/base:/base-branch \ - -v /tmp/argocd-diff/target:/target-branch \ - -v /tmp/argocd-diff/output:/output \ - -e GITHUB_TOKEN \ - dagandersen/argocd-diff-preview:latest \ - --repo "$REPO" \ - --target-branch "$TARGET_BRANCH" \ - --base-branch "$BASE_BRANCH" \ - --local-repo-path-target /target-branch \ - --local-repo-path-base /base-branch \ - --output-folder /output \ - $([ -n "$ARGOCD_CHART_VERSION" ] && echo "--argocd-chart-version $ARGOCD_CHART_VERSION") \ - --timeout "$TIMEOUT" + mkdir -p /tmp/argocd-diff/output + docker_args=( + --rm + --network=host + -v /var/run/docker.sock:/var/run/docker.sock + -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 + -e GITHUB_TOKEN + -e TIMEOUT + ) + if [ -n "$ARGOCD_CHART_VERSION" ]; then + docker_args+=(-e ARGOCD_CHART_VERSION) + fi + docker run "${docker_args[@]}" dagandersen/argocd-diff-preview:latest - name: Post diff as PR comment if: always() uses: actions/github-script@v7 + env: + DIFF_PATH: /tmp/argocd-diff/output/diff.md with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const fs = require('fs'); - const diffPath = '/tmp/argocd-diff/output/diff.md'; + const diffPath = process.env.DIFF_PATH; let body; if (fs.existsSync(diffPath)) { @@ -135,8 +191,8 @@ jobs: issue_number: context.issue.number, }); - const existing = comments.find(c => - c.user.type === 'Bot' && c.body.includes('argocd-diff-preview') + const existing = comments.find( + (c) => c.user.type === 'Bot' && c.body.includes('argocd-diff-preview') ); if (existing) { diff --git a/docs/workflows/argocd-diff-preview.md b/docs/workflows/argocd-diff-preview.md index 9ecf8b0..f6ad84e 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. From c2bb3e960a167e71af87e99c12ec7c2f22db2261 Mon Sep 17 00:00:00 2001 From: Rui Coelho Date: Fri, 3 Apr 2026 18:35:32 +0100 Subject: [PATCH 3/3] fix: use yq instead of herdoc --- .github/workflows/argocd-diff-preview.yml | 24 ++++++++++------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/.github/workflows/argocd-diff-preview.yml b/.github/workflows/argocd-diff-preview.yml index ef7f4b1..0c76e5c 100644 --- a/.github/workflows/argocd-diff-preview.yml +++ b/.github/workflows/argocd-diff-preview.yml @@ -122,20 +122,16 @@ jobs: run: | mkdir -p /tmp/argocd-diff/secrets if [ -n "$SSH_PRIVATE_KEY" ] && [ -n "$REPO_SSH_URL" ]; then - cat > /tmp/argocd-diff/secrets/repo-creds.yaml << EOF - apiVersion: v1 - kind: Secret - metadata: - name: private-repo - namespace: argocd - labels: - argocd.argoproj.io/secret-type: repository - stringData: - type: git - url: ${REPO_SSH_URL} - sshPrivateKey: | - $(echo "$SSH_PRIVATE_KEY" | sed 's/^/ /') - EOF + 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