Skip to content

fix(actions)!: require merged PR to bypass fork PR approval gate (#38010) - #38041

Merged
silverwind merged 2 commits into
go-gitea:release/v1.26from
GiteaBot:backport-38010-v1.26
Jun 9, 2026
Merged

fix(actions)!: require merged PR to bypass fork PR approval gate (#38010)#38041
silverwind merged 2 commits into
go-gitea:release/v1.26from
GiteaBot:backport-38010-v1.26

Conversation

@GiteaBot

@GiteaBot GiteaBot commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Backport #38010 by @bircni

ifNeedApproval in services/actions/notifier_helper.go decided whether a
fork PR's workflow run had to wait for maintainer approval. The bypass clause
counted any prior approved_by > 0 run for (repo_id, trigger_user_id), so
the very first Approve-and-run click on a contributor's fork PR permanently
trusted that user for every future fork PR in the same repository — including
PRs whose only change is the workflow YAML itself.

Approving a workflow run is not the same as merging code. This change
aligns the gate with GitHub Actions' first-time-contributor model: trust is
granted only after the user has had a pull request merged in the repo.

Behavior change

  • Before: one approval = permanent trust for that user in that repo.
  • After: every fork PR is gated until the contributor has at least one
    merged PR in the repo.

Existing already-approved runs and merged PRs continue to work; only the
trust criterion for future fork PRs changes. Maintainers who rely on the
implicit "approve once" trust will see the approval banner reappear until
they merge a PR from that contributor.

…gitea#38010)

`ifNeedApproval` in `services/actions/notifier_helper.go` decided
whether a
fork PR's workflow run had to wait for maintainer approval. The bypass
clause
counted any prior `approved_by > 0` run for `(repo_id,
trigger_user_id)`, so
the very first Approve-and-run click on a contributor's fork PR
permanently
trusted that user for every future fork PR in the same repository —
including
PRs whose only change is the workflow YAML itself.

Approving a workflow *run* is not the same as merging *code*. This
change
aligns the gate with GitHub Actions' first-time-contributor model: trust
is
granted only after the user has had a pull request merged in the repo.

## Behavior change

- **Before**: one approval = permanent trust for that user in that repo.
- **After**: every fork PR is gated until the contributor has at least
one
  merged PR in the repo.

Existing already-approved runs and merged PRs continue to work; only the
trust criterion for *future* fork PRs changes. Maintainers who rely on
the
implicit "approve once" trust will see the approval banner reappear
until
they merge a PR from that contributor.
@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Jun 8, 2026
@GiteaBot GiteaBot added this to the 1.26.3 milestone Jun 8, 2026
@GiteaBot
GiteaBot requested review from Zettat123 and lunny June 8, 2026 20:07
@github-actions github-actions Bot added the pr/breaking Merging this PR means builds will break. Needs a description what exactly breaks, and how to fix it! label Jun 8, 2026
@GiteaBot GiteaBot added lgtm/need 1 This PR needs approval from one additional maintainer to be merged. and removed lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. labels Jun 8, 2026
Comment thread services/actions/notifier_helper_test.go Outdated
Comment thread services/actions/notifier_helper_test.go Outdated
Comment thread services/actions/notifier_helper_test.go Outdated
Comment thread services/actions/notifier_helper_test.go Outdated
Co-authored-by: bircni <bircni@icloud.com>
Signed-off-by: bircni <bircni@icloud.com>
@GiteaBot GiteaBot added lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. and removed lgtm/need 1 This PR needs approval from one additional maintainer to be merged. labels Jun 8, 2026
@lunny lunny added the reviewed/wait-merge This pull request is part of the merge queue. It will be merged soon. label Jun 9, 2026
@silverwind
silverwind merged commit e107498 into go-gitea:release/v1.26 Jun 9, 2026
35 of 40 checks passed
@GiteaBot GiteaBot removed the reviewed/wait-merge This pull request is part of the merge queue. It will be merged soon. label Jun 9, 2026
eleboucher pushed a commit to eleboucher/apoci that referenced this pull request Jun 21, 2026
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [code.gitea.io/gitea](https://github.com/go-gitea/gitea) | `v1.26.2` → `v1.26.3` | ![age](https://developer.mend.io/api/mc/badges/age/go/code.gitea.io%2fgitea/v1.26.3?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/go/code.gitea.io%2fgitea/v1.26.2/v1.26.3?slim=true) |

---

### Release Notes

<details>
<summary>go-gitea/gitea (code.gitea.io/gitea)</summary>

### [`v1.26.3`](https://github.com/go-gitea/gitea/releases/tag/v1.26.3)

[Compare Source](go-gitea/gitea@v1.26.2...v1.26.3)

- BREAKING

  - fix(actions)!: require merged PR to bypass fork PR approval gate ([#&#8203;38010](go-gitea/gitea#38010)) ([#&#8203;38041](go-gitea/gitea#38041))

- SECURITY
  - fix(hostmatcher): patch incorrect private list ([#&#8203;38170](go-gitea/gitea#38170)) ([#&#8203;38173](go-gitea/gitea#38173))
  - fix: Various security fixes ([#&#8203;38103](go-gitea/gitea#38103)) ([#&#8203;38151](go-gitea/gitea#38151))
  - fix: Various sec fixes ([#&#8203;38108](go-gitea/gitea#38108)) ([#&#8203;38147](go-gitea/gitea#38147))
  - fix: allow git clone of private repos with anonymous code access ([#&#8203;38074](go-gitea/gitea#38074)) ([#&#8203;38146](go-gitea/gitea#38146))
  - fix(auth): ignore stale OIDC external login links to organizations ([#&#8203;37875](go-gitea/gitea#37875)) ([#&#8203;38141](go-gitea/gitea#38141))
  - fix(hostmatcher): block reserved IP ranges from external/private filters ([#&#8203;38039](go-gitea/gitea#38039)) ([#&#8203;38059](go-gitea/gitea#38059))
  - fix(lfs): require Code-unit access for cross-repo LFS object reuse ([#&#8203;38006](go-gitea/gitea#38006)) ([#&#8203;38050](go-gitea/gitea#38050))
  - fix(lfs): reject unknown SSH LFS sub-verbs to prevent auth bypass ([#&#8203;38008](go-gitea/gitea#38008)) ([#&#8203;38015](go-gitea/gitea#38015))
  - fix: bound CODEOWNERS regex match time ([#&#8203;38011](go-gitea/gitea#38011)) ([#&#8203;38025](go-gitea/gitea#38025))
  - fix: bound debian ParseControlFile to a single control stanza ([#&#8203;38044](go-gitea/gitea#38044)) ([#&#8203;38055](go-gitea/gitea#38055))
  - fix(deps): update module golang.org/x/net to v0.55.0 \[security] ([#&#8203;37813](go-gitea/gitea#37813)) ([#&#8203;37829](go-gitea/gitea#37829))

- API
  - feat(api): add Link header in ListForks ([#&#8203;38052](go-gitea/gitea#38052)) ([#&#8203;38063](go-gitea/gitea#38063))

- BUGFIXES
  - fix: Fix the panic when ssh remote lfs endpoint parsing failure ([#&#8203;38026](go-gitea/gitea#38026)) ([#&#8203;38158](go-gitea/gitea#38158))
  - fix(api): nil pointer panic when filtering tracked times by a non-existent user ([#&#8203;38112](go-gitea/gitea#38112)) ([#&#8203;38115](go-gitea/gitea#38115))
  - fix: keep literal "false" value displayed in workflow\_dispatch choice dropdowns ([#&#8203;38080](go-gitea/gitea#38080)) ([#&#8203;38096](go-gitea/gitea#38096))
  - fix: parse HEAD ref ([#&#8203;38119](go-gitea/gitea#38119))
  - fix: git cmd ([#&#8203;38084](go-gitea/gitea#38084)) ([#&#8203;38087](go-gitea/gitea#38087))
  - fix(releases): generate notes for initial tag ([#&#8203;37697](go-gitea/gitea#37697)) ([#&#8203;37986](go-gitea/gitea#37986))
  - fix(actions): return 404 when job log blob is missing ([#&#8203;38003](go-gitea/gitea#38003)) ([#&#8203;38004](go-gitea/gitea#38004))
  - fix(actions): exclude `workflow_call` from workflow trigger detection ([#&#8203;37894](go-gitea/gitea#37894)) ([#&#8203;37899](go-gitea/gitea#37899))
  - fix(actions): keep action run title clickable when commit subject is a URL ([#&#8203;37867](go-gitea/gitea#37867)) ([#&#8203;37898](go-gitea/gitea#37898))
  - fix(actions): reject workflow\_dispatch for workflows without that trigger ([#&#8203;37660](go-gitea/gitea#37660)) ([#&#8203;37895](go-gitea/gitea#37895))
  - fix(actions): ack re-sent `UpdateLog` finalize idempotently ([#&#8203;37885](go-gitea/gitea#37885)) ([#&#8203;37892](go-gitea/gitea#37892))
  - fix: http content file render ([#&#8203;37850](go-gitea/gitea#37850)) ([#&#8203;37856](go-gitea/gitea#37856))
  - fix(issues): clear stale ReviewTypeRequest when submitting pending review ([#&#8203;37809](go-gitea/gitea#37809)) ([#&#8203;37815](go-gitea/gitea#37815))
  - fix: Fix issue target branch selection for non-collaborators ([#&#8203;36916](go-gitea/gitea#36916)) ([#&#8203;38164](go-gitea/gitea#38164))

- BUILD
  - fix(deps): update `@playwright/test` to 1.60.0 ([#&#8203;38144](go-gitea/gitea#38144))
  - ci: add `tools/ci-tools.ts` for the PR labeler workflow ([#&#8203;37831](go-gitea/gitea#37831))
  - fix(build): swagger css import ([#&#8203;37801](go-gitea/gitea#37801)) ([#&#8203;37803](go-gitea/gitea#37803))

Instances on **[Gitea Cloud](https://cloud.gitea.com)** will be automatically upgraded to this version during the specified maintenance window.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJ0eXBlL3BhdGNoIl19-->

Reviewed-on: https://git.erwanleboucher.dev/eleboucher/apoci/pulls/89
eleboucher pushed a commit to eleboucher/apoci that referenced this pull request Jun 22, 2026
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [code.gitea.io/gitea](https://github.com/go-gitea/gitea) | `v1.26.2` → `v1.26.4` | ![age](https://developer.mend.io/api/mc/badges/age/go/code.gitea.io%2fgitea/v1.26.4?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/go/code.gitea.io%2fgitea/v1.26.2/v1.26.4?slim=true) |

---

### Release Notes

<details>
<summary>go-gitea/gitea (code.gitea.io/gitea)</summary>

### [`v1.26.4`](https://github.com/go-gitea/gitea/releases/tag/v1.26.4)

[Compare Source](go-gitea/gitea@v1.26.3...v1.26.4)

- SECURITY
  - fix(auth): do not auto-reactivate disabled users on OAuth2 callback ([#&#8203;38009](go-gitea/gitea#38009)) ([#&#8203;38183](go-gitea/gitea#38183))

- BUGFIXES
  - fix: walk git log context error handling ([#&#8203;38182](go-gitea/gitea#38182)) ([#&#8203;38185](go-gitea/gitea#38185))

Instances on **[Gitea Cloud](https://cloud.gitea.com)** will be automatically upgraded to this version during the specified maintenance window.

### [`v1.26.3`](https://github.com/go-gitea/gitea/releases/tag/v1.26.3)

[Compare Source](go-gitea/gitea@v1.26.2...v1.26.3)

> \[!WARNING]
> **Please upgrade to 1.26.4 directly.** A regression in this release can cause **"context deadline exceeded"** errors when opening any repository's code pages ([#&#8203;38177](go-gitea/gitea#38177)). Please hold off on upgrading until a fix is released.

- BREAKING

  - fix(actions)!: require merged PR to bypass fork PR approval gate ([#&#8203;38010](go-gitea/gitea#38010)) ([#&#8203;38041](go-gitea/gitea#38041))

- SECURITY
  - fix(hostmatcher): patch incorrect private list ([#&#8203;38170](go-gitea/gitea#38170)) ([#&#8203;38173](go-gitea/gitea#38173))
  - fix: Various security fixes ([#&#8203;38103](go-gitea/gitea#38103)) ([#&#8203;38151](go-gitea/gitea#38151))
  - fix: Various sec fixes ([#&#8203;38108](go-gitea/gitea#38108)) ([#&#8203;38147](go-gitea/gitea#38147))
  - fix: allow git clone of private repos with anonymous code access ([#&#8203;38074](go-gitea/gitea#38074)) ([#&#8203;38146](go-gitea/gitea#38146))
  - fix(auth): ignore stale OIDC external login links to organizations ([#&#8203;37875](go-gitea/gitea#37875)) ([#&#8203;38141](go-gitea/gitea#38141))
  - fix(hostmatcher): block reserved IP ranges from external/private filters ([#&#8203;38039](go-gitea/gitea#38039)) ([#&#8203;38059](go-gitea/gitea#38059))
  - fix(lfs): require Code-unit access for cross-repo LFS object reuse ([#&#8203;38006](go-gitea/gitea#38006)) ([#&#8203;38050](go-gitea/gitea#38050))
  - fix(lfs): reject unknown SSH LFS sub-verbs to prevent auth bypass ([#&#8203;38008](go-gitea/gitea#38008)) ([#&#8203;38015](go-gitea/gitea#38015))
  - fix: bound CODEOWNERS regex match time ([#&#8203;38011](go-gitea/gitea#38011)) ([#&#8203;38025](go-gitea/gitea#38025))
  - fix: bound debian ParseControlFile to a single control stanza ([#&#8203;38044](go-gitea/gitea#38044)) ([#&#8203;38055](go-gitea/gitea#38055))
  - fix(deps): update module golang.org/x/net to v0.55.0 \[security] ([#&#8203;37813](go-gitea/gitea#37813)) ([#&#8203;37829](go-gitea/gitea#37829))

- API
  - feat(api): add Link header in ListForks ([#&#8203;38052](go-gitea/gitea#38052)) ([#&#8203;38063](go-gitea/gitea#38063))

- BUGFIXES
  - fix: Fix the panic when ssh remote lfs endpoint parsing failure ([#&#8203;38026](go-gitea/gitea#38026)) ([#&#8203;38158](go-gitea/gitea#38158))
  - fix(api): nil pointer panic when filtering tracked times by a non-existent user ([#&#8203;38112](go-gitea/gitea#38112)) ([#&#8203;38115](go-gitea/gitea#38115))
  - fix: keep literal "false" value displayed in workflow\_dispatch choice dropdowns ([#&#8203;38080](go-gitea/gitea#38080)) ([#&#8203;38096](go-gitea/gitea#38096))
  - fix: parse HEAD ref ([#&#8203;38119](go-gitea/gitea#38119))
  - fix: git cmd ([#&#8203;38084](go-gitea/gitea#38084)) ([#&#8203;38087](go-gitea/gitea#38087))
  - fix(releases): generate notes for initial tag ([#&#8203;37697](go-gitea/gitea#37697)) ([#&#8203;37986](go-gitea/gitea#37986))
  - fix(actions): return 404 when job log blob is missing ([#&#8203;38003](go-gitea/gitea#38003)) ([#&#8203;38004](go-gitea/gitea#38004))
  - fix(actions): exclude `workflow_call` from workflow trigger detection ([#&#8203;37894](go-gitea/gitea#37894)) ([#&#8203;37899](go-gitea/gitea#37899))
  - fix(actions): keep action run title clickable when commit subject is a URL ([#&#8203;37867](go-gitea/gitea#37867)) ([#&#8203;37898](go-gitea/gitea#37898))
  - fix(actions): reject workflow\_dispatch for workflows without that trigger ([#&#8203;37660](go-gitea/gitea#37660)) ([#&#8203;37895](go-gitea/gitea#37895))
  - fix(actions): ack re-sent `UpdateLog` finalize idempotently ([#&#8203;37885](go-gitea/gitea#37885)) ([#&#8203;37892](go-gitea/gitea#37892))
  - fix: http content file render ([#&#8203;37850](go-gitea/gitea#37850)) ([#&#8203;37856](go-gitea/gitea#37856))
  - fix(issues): clear stale ReviewTypeRequest when submitting pending review ([#&#8203;37809](go-gitea/gitea#37809)) ([#&#8203;37815](go-gitea/gitea#37815))
  - fix: Fix issue target branch selection for non-collaborators ([#&#8203;36916](go-gitea/gitea#36916)) ([#&#8203;38164](go-gitea/gitea#38164))

- BUILD
  - fix(deps): update `@playwright/test` to 1.60.0 ([#&#8203;38144](go-gitea/gitea#38144))
  - ci: add `tools/ci-tools.ts` for the PR labeler workflow ([#&#8203;37831](go-gitea/gitea#37831))
  - fix(build): swagger css import ([#&#8203;37801](go-gitea/gitea#37801)) ([#&#8203;37803](go-gitea/gitea#37803))

Instances on **[Gitea Cloud](https://cloud.gitea.com)** will be automatically upgraded to this version during the specified maintenance window.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJ0eXBlL3BhdGNoIl19-->

Reviewed-on: https://git.erwanleboucher.dev/eleboucher/apoci/pulls/95
@go-gitea go-gitea locked as resolved and limited conversation to collaborators Sep 7, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. pr/breaking Merging this PR means builds will break. Needs a description what exactly breaks, and how to fix it! type/bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants