GitLab CI/CD Workflow🔗
Public repositories🔗
If your repository is public and only uses public Helm charts, you can use the following GitLab CI/CD pipeline to generate a diff between the main branch and the merge request branch. The diff will then be posted as a comment on the merge request.
default:
tags:
- gitlab-org-docker
stages:
- diff
diff:
stage: diff
image: docker:24.0.5
services:
- name: docker:24.0.5-dind
variables:
GITLAB_TOKEN: $GITLAB_PAT
before_script:
- apk add -q curl jq git
script:
- |
echo "******** Running analysis ********"
git clone ${CI_REPOSITORY_URL} base-branch --depth 1 -q
git clone ${CI_REPOSITORY_URL} target-branch --depth 1 -q -b ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}
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 \
-e TARGET_BRANCH=${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} \
-e REPO=${CI_MERGE_REQUEST_PROJECT_PATH} \
dagandersen/argocd-diff-preview:v0.2.0
- |
jq --null-input --rawfile msg $(pwd)/output/diff.md '{body: $msg}' > pr_comment.json
NOTE_ID=$(curl --silent --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}/notes" | \
jq '.[] | select(.body | test("Argo CD Diff Preview")) | .id')
if [[ -n "$NOTE_ID" ]]; then
echo "Deleting existing comment (ID: $NOTE_ID)..."
curl --silent --request DELETE --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
--url "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}/notes/${NOTE_ID}"
fi
echo "Adding new comment..."
curl --silent --request POST --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
--header "Content-Type: application/json" \
--url "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}/notes" \
--data @pr_comment.json > /dev/null
echo "Comment added!"
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
Private repositories and Helm Charts🔗
In the simple code example above, we do not provide the cluster with any credentials, which only works if the image/Helm Chart registry and the Git repository are public. Since your repository might not be public, you need to provide the tool with the necessary read-access credentials for the repository. This can be done by placing the Argo CD repo secrets in a folder mounted at /secrets. When the tool starts, it will simply run kubectl apply -f /secrets to apply every resource to the cluster before starting the rendering process.
...
before_script:
- apk add -q curl jq git
- |
mkdir secrets
cat > secrets/secret.yaml << EOF
apiVersion: v1
kind: Secret
metadata:
name: private-repo
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repo-creds
stringData:
url: https://gitlab.com/${CI_PROJECT_PATH}
password: ${GITLAB_TOKEN} ⬅️ Short-lived GitLab Token
username: token
EOF
script:
- |
echo "******** Running analysis ********"
git clone ${CI_REPOSITORY_URL} base-branch --depth 1 -q
git clone ${CI_REPOSITORY_URL} target-branch --depth 1 -q -b ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}
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 \ ⬅️ Mount the secrets folder
-e TARGET_BRANCH=${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} \
-e REPO=${CI_MERGE_REQUEST_PROJECT_PATH} \
dagandersen/argocd-diff-preview:v0.2.0
For more info, see the Argo CD docs
Extracting secrets from an existing Argo CD installation
If you already have repository secrets in an existing Argo CD installation, you can extract them directly instead of writing them by hand:
kubectl get secrets -n argocd --context <your-context> \
-l 'argocd.argoproj.io/secret-type in (repository,repo-creds)' -o json \
| jq -r '.items[] | del(.metadata.creationTimestamp, .metadata.uid, .metadata.resourceVersion, .metadata.annotations, .metadata.ownerReferences) | "---", (. | @json)' \
| yq -P > secrets/repo-secrets.yaml