-
Notifications
You must be signed in to change notification settings - Fork 188
Description
Context
I've configured an ApplicationSet with a Pull Request Generator to generate Applications on the repository PR labeled with preview. I've also configured GitHub notifications to create pr comments when the app is synced.
Everything is working fine for the PR where the source branch originates from the repository itself, but it's not working when the base branch comes from a fork.
Bug reproduction
I was able to verify that PRs coming from the fork weren’t working compared to the others by creating 2 PRs, one based on a repository branch and the second one based on a fork branch.
I was able to verify that bad behavior by triggering notifications using the command below ⬇️
kubectl exec $(kubectl get pods -l app.kubernetes.io/name=argocd-server --sort-by=.metadata.creationTimestamp -o jsonpath='{.items[0].metadata.name}') -n argocd -- argocd admin notifications template notify app-sync-succeeded my-application --recipient github:""ArgoCD Notifications configuration 🔧
The trigger.on-sync-succeeded configuration
template.app-sync-succeeded: |
message: |
{{if eq .serviceType "slack"}}:white_check_mark:{{end}} Application {{.app.metadata.name}} has been successfully synced at {{.app.status.operationState.finishedAt}}.
Sync operation details are available at: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}.
github:
repoURLPath: "{{.app.spec.source.repoURL}}"
revisionPath: "{{index .app.metadata.labels \"custom.argoproj.io/head_sha\"}}"
pullRequestComment:
content: |
:green_circle: Application **{{.app.metadata.name}}** has been successfully *synced* at {{.app.status.operationState.startedAt}}.
{{- if .app.status.summary.externalURLs }}
{{- range .app.status.summary.externalURLs }}
:arrow_right: :globe_with_meridians: {{ . }}
{{- end }}
{{- else }}
:warning: :globe_with_meridians: No external URLs found.
{{- end }}
:worm: See the details in [ArgoCD]({{.context.argocdUrl}}/applications/{{.app.metadata.name}}).
The trigger.on-sync-succeeded configuration
trigger.on-sync-succeeded: |
- description: Application syncing has succeeded
send:
- app-sync-succeeded
when: app.status.operationState != nil and app.status.operationState.phase in ['Succeeded']
Note
If the two PRs share the same branch (i.e., the same HEAD commit), you'll notice that triggering the notification on the second PR (the one with the fork branch as the source) results in the message being created on the other PR.
On the example below, the PR based on the repository branch is 1522, and the one based on the fork branch is 1355.

Investigation
In the case where I've a single PR based on a fork branch.
The request on the upstream repository /repos/$YOUR_REPOSITORY_OWNER/$YOUR_REPOSITORY_NAME/commits/$YOUR_COMMIT_ID/pulls returns nothing.
Running the same request on the fork /repos/$YOUR_FORK_REPOSITORY_OWNER/$YOUR_REPOSITORY_NAME/commits/$YOUR_COMMIT_ID/pulls returns a 404. Probably because of the scope of the ArgoCD GitHub App.
🚀 The issue seems to come from the first GitHub request!
The requests return nothing but a PR based on a fork branch exists with the passed commit ID.
I tried rerunning it locally using the same GitHub App and reached the same conclusion.
# Get the installation ID
curl --request GET \
--url "https://api.github.com/app/installations" \
--header "Accept: application/vnd.github+json" \
--header "Authorization: Bearer $YOUR_BEARER" \
--header "X-GitHub-Api-Version: 2022-11-28" | jq '[.[].id]'
# Get an access token
curl --request POST --url "https://api.github.com/app/installations/$YOUR_INSTALLATION_ID/access_tokens" \
--header "Accept: application/vnd.github+json" \
--header "Authorization: Bearer $YOUR_BEARER" \
--header "X-GitHub-Api-Version: 2022-11-28" | jq '.token'
curl --request GET \
--url "https://api.github.com/repos/$YOUR_REPOSITORY_OWNER/$YOUR_REPOSITORY_NAME/commits/$YOUR_COMMIT_ID/pulls" \
--header "Accept: application/vnd.github+json" \
--header "Authorization: token $YOUR_ACCESS_TOKEN" \
--header "X-GitHub-Api-Version: 2022-11-28" | jqSolution proposal
We could loop over all the PRs and retrieve the latest commit ID to verify if it matches our.
The big stop for this approach is the number of requests sent to GitHub.
#!/bin/bash
# === Configuration ===
GITHUB_TOKEN="$YOUR_ACCESS_TOKEN"
REPO_OWNER="$YOUR_REPOSITORY_OWNER"
REPO_NAME="$YOUR_REPOSITORY_NAME"
COMMIT_SHA="$YOUR_COMMIT_ID"
# === Script ===
API_URL="https://api.github.com"
PER_PAGE=100
PAGE=1
FOUND=0
echo "🔍 Searching PRs in $REPO_OWNER/$REPO_NAME for commit $COMMIT_SHA"
while : ; do
PRS=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
"$API_URL/repos/$REPO_OWNER/$REPO_NAME/pulls?state=all&per_page=$PER_PAGE&page=$PAGE")
PR_COUNT=$(echo "$PRS" | jq length)
if [[ "$PR_COUNT" -eq 0 ]]; then
break
fi
for pr_number in $(echo "$PRS" | jq -r '.[].number'); do
echo "🔄 Checking PR #$pr_number"
COMMITS=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
"$API_URL/repos/$REPO_OWNER/$REPO_NAME/pulls/$pr_number/commits")
if echo "$COMMITS" | jq -r '.[-1].sha' | grep -q "$COMMIT_SHA"; then
echo "✅ Found commit $COMMIT_SHA in PR #$pr_number"
FOUND=1
fi
done
((PAGE++))
done
if [[ "$FOUND" -eq 0 ]]; then
echo "❌ No PR found containing commit $COMMIT_SHA"
fi