Skip to content

fix(ci): post the archive link on pull requests from forks - #857

Open
postoso wants to merge 1 commit into
altic-dev:mainfrom
postoso:fix/archive-comment-fork-prs
Open

fix(ci): post the archive link on pull requests from forks#857
postoso wants to merge 1 commit into
altic-dev:mainfrom
postoso:fix/archive-comment-fork-prs

Conversation

@postoso

@postoso postoso commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Description

The PR Archive Comment workflow fails on every pull request opened from a fork, so outside contributors never get the build download link.

workflow_run.pull_requests is populated only for same-repository pull requests and is empty for pull requests from forks. The job reads pull_requests[0].number, so for a fork PR the number is blank, the guard rejects it, and the job exits 1 with "The completed workflow run is not associated with a pull request."

Across the last 40 runs of this workflow: 10 failures, all fork PRs; 16 successes, all same-repo PRs; no exceptions either way. The 14 skipped runs are the job's own if: workflow_run.conclusion == 'success' condition and are unrelated.

Worth noting the archive itself is fine. The "PR Archive" job builds and uploads the artifact correctly for fork PRs, so the only thing lost is the comment linking to it. That is also why this has stayed invisible: it works for branches pushed to this repo, which is the path you would normally see.

This falls back to matching the head SHA from the workflow_run payload against the open pull requests when the event does not carry a number. Same-repo PRs keep taking the existing path.

One thing I deliberately did not do: the artifact name already encodes the PR number, which would have been a shorter fix. But that name is produced by the untrusted pull_request workflow, and this workflow is trusted and has issues: write, so a fork could name an artifact to steer the comment onto an unrelated PR. workflow_run.head_sha comes from the event payload instead.

Type of Change

  • 🐞 Bug fix
  • ✨ New feature
  • 💥 Breaking change
  • 🧹 Chore
  • 📝 Documentation update

Related Issue or Discussion

No existing issue. #847 is a concrete instance: it merged, and the contributor never received an archive comment.

Testing

  • Tested on Apple Silicon Mac
  • Tested on macOS version: 15.7.7
  • Tested on Intel Mac
  • Ran linter locally: swiftlint --strict --config .swiftlint.yml Sources
  • Ran formatter locally: swiftformat --config .swiftformat Sources
  • Ran tests locally:

No Swift changed, so the Swift toolchain checks do not apply here. I ran the resolution logic against this repository's live API instead:

Case PR Resolved
Open fork PR #387 387
Open fork PR #468 468
Open fork PR #429 429
Same-repo PR #856 856
Nonexistent SHA n/a empty, falls through to the existing guard

I first tried repos/{repo}/commits/{sha}/pulls, which is the more obvious fallback, and it does not work here. It resolves merged fork PRs (#847) but returns empty for open ones, because the head commit lives in the fork rather than this repository. That is the case the fix is for, so it is matched against the open pull requests instead.

The paginated call is one request at the current volume (48 open PRs at per_page=100). YAML validated; sed -n '1p' matches the idiom already used further down and avoids a SIGPIPE under pipefail.

Screenshots / Video

  • No UI/visual changes; screenshots/video are not applicable.

Notes

Only the fork path changes. Same-repo PRs never enter the new branch, since pull_requests[0].number is already set for them.

Happy to add a debug line logging which path resolved the number if that would help when this is running in anger.

workflow_run.pull_requests is empty for pull requests opened from forks,
so EVENT_PR_NUMBER was blank and the job exited before commenting. Fall
back to matching workflow_run.head_sha against the open pull requests.

The artifact name also encodes the number, but it comes from the
untrusted pull_request workflow, so the trusted head SHA is used instead.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 988b8e6154

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

# workflow, so it is not trusted to select the comment target here.
if [[ ! "$EVENT_PR_NUMBER" =~ ^[0-9]+$ ]]; then
EVENT_PR_NUMBER=$(
gh api "repos/$GITHUB_REPOSITORY/pulls?state=open&per_page=100" --paginate \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Resolve fork PRs after they leave the open list

When a fork PR is merged or closed before its archive run completes, workflow_run.pull_requests is still empty but this query can no longer find the PR, so the following guard exits without posting the archive link. This is plausible because the archive job in pr-archive.yml may run for up to 45 minutes and closing a PR does not cancel its existing run; the fallback should also resolve matching closed/merged PRs while avoiding ambiguous SHA matches.

Useful? React with 👍 / 👎.

@greptile-apps

greptile-apps Bot commented Aug 14, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds a head-SHA-based fallback intended to recover pull-request numbers for successful archive workflows originating from forks.

  • Exposes workflow_run.head_sha to the comment job.
  • Searches paginated open pull requests when the event contains no pull-request number.
  • Preserves the existing artifact validation and comment flow after resolution.

Confidence Score: 3/5

This PR should not merge until the fallback uses a value that can actually be supplied to the filter and matches the pull-request head SHA.

The new fork-only resolution path can return no pull-request number for two independent reasons, leaving the original missing-comment failure intact.

Files Needing Attention: .github/workflows/pr-archive-comment.yml

Fix all with Greploop

Fix All in Codex

Prompt To Fix All With AI
### Issue 1
.github/workflows/pr-archive-comment.yml:41
**Environment lookup returns no match**

When a fork run has no event PR number, `gh api --jq` does not expose the shell's `HEAD_SHA` through `env.HEAD_SHA`, so the filter returns no PR number and the guard exits without posting the archive link.

### Issue 2
.github/workflows/pr-archive-comment.yml:41
**Merge SHA cannot match head**

For the upstream `pull_request` workflow, `workflow_run.head_sha` identifies the synthetic merge commit while `.head.sha` identifies the PR's actual head commit, so the fallback finds no PR and fork contributors still receive no archive link.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "fix(ci): post the archive link on pull r..." | Re-trigger Greptile

if [[ ! "$EVENT_PR_NUMBER" =~ ^[0-9]+$ ]]; then
EVENT_PR_NUMBER=$(
gh api "repos/$GITHUB_REPOSITORY/pulls?state=open&per_page=100" --paginate \
--jq '.[] | select(.head.sha == env.HEAD_SHA) | .number' \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Environment lookup returns no match

When a fork run has no event PR number, gh api --jq does not expose the shell's HEAD_SHA through env.HEAD_SHA, so the filter returns no PR number and the guard exits without posting the archive link.

Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/pr-archive-comment.yml
Line: 41

Comment:
**Environment lookup returns no match**

When a fork run has no event PR number, `gh api --jq` does not expose the shell's `HEAD_SHA` through `env.HEAD_SHA`, so the filter returns no PR number and the guard exits without posting the archive link.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Codex

if [[ ! "$EVENT_PR_NUMBER" =~ ^[0-9]+$ ]]; then
EVENT_PR_NUMBER=$(
gh api "repos/$GITHUB_REPOSITORY/pulls?state=open&per_page=100" --paginate \
--jq '.[] | select(.head.sha == env.HEAD_SHA) | .number' \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Merge SHA cannot match head

For the upstream pull_request workflow, workflow_run.head_sha identifies the synthetic merge commit while .head.sha identifies the PR's actual head commit, so the fallback finds no PR and fork contributors still receive no archive link.

Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/pr-archive-comment.yml
Line: 41

Comment:
**Merge SHA cannot match head**

For the upstream `pull_request` workflow, `workflow_run.head_sha` identifies the synthetic merge commit while `.head.sha` identifies the PR's actual head commit, so the fallback finds no PR and fork contributors still receive no archive link.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Codex

@postoso

postoso commented Aug 16, 2026

Copy link
Copy Markdown
Contributor Author

Both findings look incorrect to me.

Environment lookup returns no match. HEAD_SHA is not a shell variable here, it is set in the job level env: block (line 23), so Actions puts it in the step's process environment and gh inherits it. gh api --jq runs gojq, whose env object reads the process environment. Ran the exact filter against the live API to confirm:

HEAD_SHA=8de9731a8ba7b988243f1c0be78721be2bd17876 \
GITHUB_REPOSITORY=altic-dev/FluidVoice \
gh api "repos/$GITHUB_REPOSITORY/pulls?state=open&per_page=100" --paginate \
  --jq '.[] | select(.head.sha == env.HEAD_SHA) | .number'
387

Merge SHA cannot match head. workflow_run.head_sha is the head commit of the run, not the refs/pull/N/merge commit. Checked against this repo's own PR Archive runs:

gh api "repos/altic-dev/FluidVoice/actions/workflows/314144357/runs?event=pull_request" \
  --jq '.workflow_runs[] | [.id, .head_sha, .head_branch, .head_repository.full_name] | @tsv'
31762824704  8de9731a8ba7b988243f1c0be78721be2bd17876  fix/259-writemode-clipboard  postoso/FluidVoice

That SHA is PR #387's head.sha. It also cannot be a merge commit: head_repository is the fork, and refs/pull/N/merge only exists in the base repo.

No change made.

One adjacent limitation in the fallback worth noting for the record: a head SHA does not uniquely identify an open PR, and two open PRs have briefly shared one in this repo before (#510/#511 for a few seconds). If that ever happens the sed -n '1p' picks the first match, and the existing artifact-name check then rejects a wrong target, so the worst case is the link not getting posted rather than landing on the wrong PR. Happy to harden it with an artifact-name cross-check in the selection itself if you want that in this PR.

@postoso

postoso commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

Since my last comment, the workflow has failed eight more times with the same guard error. The first maps to #867: PR Archive run 31925912425 completed successfully for head 40dd7c5e56ef6a7df96b48b286d2a0ffd2397a8a, and PR Archive Comment run 31926298235 failed seconds later with The completed workflow run is not associated with a pull request.

That case also checks the two Greptile findings directly. The archive run's head_sha is #867's actual fork head commit, not a synthetic merge commit, while its pull_requests array is empty. Running the exact env.HEAD_SHA fallback query with that SHA resolves PR 867. So this reproduces the current failure and shows that the proposed fallback has the values it needs.

This addresses the two Greptile findings. The separate case where a PR leaves the open list before its archive finishes is a different question.

@postoso

postoso commented Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

One more data point that isolates this to fork PRs specifically.

I checked which recent PRs actually received the archive comment:

PR head repo archive comment
#883 altic-dev/FluidVoice (not a fork) yes
#863 Optic00 fork no
#836 YuriNachos fork no
#878 mvanhorn fork no
#387 postoso fork no

Four different contributors' fork PRs get nothing, and the one non-fork PR gets the comment. That lines up with workflow_run.pull_requests coming back empty for forks, so EVENT_PR_NUMBER is unset and the job exits at the guard before it can post. It is not specific to my fork.

Happy to rebase or add a workflow test if either would help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant