Multi-repo support🔗
This page explains how to use argocd-diff-preview when your Argo CD Applications and their managed Kubernetes resources live in separate repositories.
Terminology🔗
Let's define the two repositories we're working with:
| Repository | Contains |
|---|---|
| Application Repository | Argo CD Application and ApplicationSet manifests |
| Resource Repository | Kubernetes resources (Helm charts, Kustomize overlays, plain YAML) referenced by the applications |
If you want diffs triggered by changes in either repository, you'll need a pipeline in both.
Two key rules🔗
Rule 1: --repo must match the repository with the PR🔗
The --repo flag tells argocd-diff-preview which repository has the change. The tool uses this to redirect the correct targetRevision to the PR branch.
| Flag | Purpose |
|---|---|
--repo |
Must match the repository where the PR was opened |
--target-branch |
The PR branch that applications should be redirected to |
docker run \
--network=host \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(pwd)/main:/base-branch \
-v $(pwd)/pull-request:/target-branch \
-v $(pwd)/output:/output \
-e REPO=<org>/<repo-with-pr> \ ⬅️ Must match the repo with the PR
-e TARGET_BRANCH=<pr-branch> \ ⬅️ The branch to redirect applications to
dagandersen/argocd-diff-preview:v0.2.12
Why does this matter?
The tool only redirects applications whose spec.source.repoURL matches the --repo flag. If you specify the wrong repo, the applications won't point to your PR branch.
Rule 2: Always clone the Application Repository🔗
The /base-branch and /target-branch folders must contain the Application Repository - this is where argocd-diff-preview looks for Application and ApplicationSet manifests.
This means even when running a pipeline in the Resource Repository, you still need to clone the Application Repository into these folders.
GitHub Workflows Examples🔗
Pipeline in the Application Repository🔗
This is the standard setup - nothing unusual here:
- Clone the Application Repository (this repo)
- Provide secrets for both repositories
- Set
--repoto the Application Repository
name: Argo CD Diff Preview
on:
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4 ⬅️ We pull the Application Repository
with:
path: pull-request
- uses: actions/checkout@v4 ⬅️ We pull the Application Repository
with:
ref: main
path: main
- name: Prepare secrets
run: |
mkdir secrets
# Secret for Application Repository
cat > secrets/app-repo-creds.yaml << "EOF"
apiVersion: v1
kind: Secret
metadata:
name: app-repo-creds
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repo-creds
stringData:
url: https://github.com/<org>/<application-repository>
password: ${{ secrets.GITHUB_TOKEN }}
username: not-used
EOF
# Secret for Resource Repository
cat > secrets/resource-repo-creds.yaml << "EOF"
apiVersion: v1
kind: Secret
metadata:
name: resource-repo-creds
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repo-creds
stringData:
url: https://github.com/<org>/<resource-repository>
password: ${{ secrets.RESOURCE_REPO_TOKEN }}
username: not-used
EOF
- name: Generate Diff
run: |
docker run \
--network=host \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(pwd)/main:/base-branch \
-v $(pwd)/pull-request:/target-branch \
-v $(pwd)/output:/output \
-v $(pwd)/secrets:/secrets \ ⬅️ Mount the secrets folder
-e TARGET_BRANCH=<pr-branch> \ ⬅️ The PR branch on the Application Repository
-e REPO=<org>/<application-repository> \ ⬅️ Application Repository
dagandersen/argocd-diff-preview:v0.2.12
- name: Post diff as comment
run: |
gh pr comment ${{ github.event.number }} --repo ${{ github.repository }} --body-file output/diff.md --edit-last || \
gh pr comment ${{ github.event.number }} --repo ${{ github.repository }} --body-file output/diff.md
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Local equivalent🔗
git clone https://github.com/<org>/<application-repository> base-branch --depth 1 -q -b main
git clone https://github.com/<org>/<application-repository> target-branch --depth 1 -q -b pr-branch
mkdir secrets
# store some secrets in the ./secrets folder
docker run \
--network host \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(pwd)/output:/output \
-v $(pwd)/base-branch:/base-branch \
-v $(pwd)/target-branch:/target-branch \
-v $(pwd)/secrets:/secrets \
-e TARGET_BRANCH=<pr-branch> \
-e REPO=<org>/<application-repository> \
dagandersen/argocd-diff-preview:v0.2.12
Pipeline in the Resource Repository🔗
This is where it gets interesting:
- Clone the Application Repository (not the current repo!)
- Provide secrets for both repositories
- Set
--repoto the Resource Repository (where the PR is) - Set
--target-branchto the Resource Repository PR branch or commit SHA - Disable automatic changed-file detection, because the Application Repository clone folders are both checked out from
main - Use
--render-method="server-api"because this setup does not work with therepo-server-apirender method
name: Argo CD Diff Preview
on:
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
# ⚠️ Clone the APPLICATION Repository, not this Resource Repository!
# Both clone `main` because the PR is not on the Application Repository
- uses: actions/checkout@v4
with:
repository: <org>/<application-repository>
token: ${{ secrets.APP_REPO_TOKEN }}
ref: main
path: target-branch
- uses: actions/checkout@v4
with:
repository: <org>/<application-repository>
token: ${{ secrets.APP_REPO_TOKEN }}
ref: main
path: base-branch
- name: Prepare secrets
run: |
mkdir secrets
# Secret for Application Repository
cat > secrets/app-repo-creds.yaml << "EOF"
apiVersion: v1
kind: Secret
metadata:
name: app-repo-creds
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repo-creds
stringData:
url: https://github.com/<org>/<application-repository>
password: ${{ secrets.APP_REPO_TOKEN }}
username: not-used
EOF
# Secret for Resource Repository
cat > secrets/resource-repo-creds.yaml << "EOF"
apiVersion: v1
kind: Secret
metadata:
name: resource-repo-creds
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repo-creds
stringData:
url: https://github.com/<org>/<resource-repository>
password: ${{ secrets.GITHUB_TOKEN }}
username: not-used
EOF
- name: Generate Diff
run: |
docker run \
--network=host \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(pwd)/base-branch:/base-branch \
-v $(pwd)/target-branch:/target-branch \
-v $(pwd)/output:/output \
-v $(pwd)/secrets:/secrets \ ⬅️ Mount the secrets folder
-e TARGET_BRANCH=<pr-branch> \ ⬅️ The PR branch on the Resource Repository
-e REPO=<org>/<resource-repository> \ ⬅️ Resource Repository (where the PR is!)
-e AUTO_DETECT_FILES_CHANGED=false \ ⬅️ Disable auto-detection because the PR is not in the Application Repository
-e RENDER_METHOD=server-api \ ⬅️ This is the default. This setup does not work with RENDER_METHOD=repo-server-api
dagandersen/argocd-diff-preview:v0.2.12
- name: Post diff as comment
run: |
gh pr comment ${{ github.event.number }} --repo ${{ github.repository }} --body-file output/diff.md --edit-last || \
gh pr comment ${{ github.event.number }} --repo ${{ github.repository }} --body-file output/diff.md
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Cross-repository access
The Resource Repository pipeline needs a Personal Access Token (PAT) or GitHub App token with access to the Application Repository. The default GITHUB_TOKEN only has access to the current repository.
Local equivalent🔗
git clone https://github.com/<org>/<application-repository> base-branch --depth 1 -q -b main
git clone https://github.com/<org>/<application-repository> target-branch --depth 1 -q -b main
mkdir secrets
# store some secrets in the ./secrets folder
docker run \
--network host \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(pwd)/output:/output \
-v $(pwd)/base-branch:/base-branch \
-v $(pwd)/target-branch:/target-branch \
-v $(pwd)/secrets:/secrets \
-e TARGET_BRANCH=<pr-branch> \
-e REPO=<org>/<resource-repository> \
-e AUTO_DETECT_FILES_CHANGED=false \
-e RENDER_METHOD=server-api \
dagandersen/argocd-diff-preview:v0.2.12
Summary🔗
| Pipeline location | Clone into /base-branch and /target-branch |
--repo flag |
Changed-file detection |
|---|---|---|---|
| Application Repository | Application Repository | Application Repository | Auto-detection works by default |
| Resource Repository | Application Repository | Resource Repository | Disable auto-detection or pass Resource Repository changes explicitly |
With pipelines in both repositories, you'll get diffs for changes to either your Applications or the resources they manage.
Questions?
If you have questions or suggestions, please open an issue!