argoproj / argoproj/notifications-engine

GitHub PR Comment notification doesn't work when source branch comes from a fork

Open
#384 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
334
Forks
217
PR merge metrics
No merged PRs in 30d

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 ⬇️
```bash
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 :wrench:

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`.
Image

## 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.

:rocket: **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.

```bash
# 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" | jq
```

## Solution 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.**

```bash
#!/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
```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reproducing the failure with the documented argocd admin notifications template notify command and compare the GitHub commits/{commit_id}/pulls requests for an upstream branch and a fork branch. The payload names no source file or test, so trace the GitHub pull-request lookup entry point and verify that fork-based PRs receive comments without an impractical increase in GitHub API requests.

Written by the indexing model from the issue text.

Assessment

Tech stack
github, go, kubernetes
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.