Commit Graph

5513 Commits

Author SHA1 Message Date
Giteabot 5f017302bf fix(actions): show retention info on hover for expired artifacts (#38477) (#38493)
Backport #38477 by @bircni

The artifact info hover tooltip (#37100) only worked for live artifacts.
Hovering an expired/deleted artifact showed nothing, and even on live
artifacts the retention date was missing on real runs.

Two root causes:

1. **Expired artifacts had no tooltip.** In the run view sidebar,
expired artifacts render in a separate branch that omitted
`data-tooltip-content` entirely, so there was nothing to hover.
2. **`ExpiresUnix` was no longer sent.** The `ActionRunAttempt` refactor
(#37119) dropped `ExpiresUnix` from `fillViewRunResponseArtifacts`, so
real runs always returned `0` and the tooltip fell back to size-only.
Only the devtest mock still populated it, which masked the regression.

Artifacts without a recorded expiry (`expiresUnix <= 0`) still degrade
gracefully to a size-only tooltip. Both states can be previewed on the
`/devtest/mock/*` actions run page.

Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-16 17:01:56 +00:00
Giteabot 59c619660c fix(actions): group reusable-workflow matrix legs in the workflow graph (#38475) (#38492)
Backport #38475

Co-authored-by: bircni <bircni@icloud.com>
2026-07-16 15:58:06 +00:00
Giteabot da9f0a3726 fix(packages): serve noarch Alpine index for any requested architecture (#38479) (#38486)
Backport #38479 by @gaurav0107

Fixes #38456

## Problem
The Alpine package registry serves one `APKINDEX.tar.gz` per
architecture. When a repository contains only `noarch` packages (no
architecture-specific packages), only the `noarch` index is built.
Because `apk` substitutes `$ARCH` with the host architecture and
requests e.g. `x86_64/APKINDEX.tar.gz`, such a repository returned HTTP
404 and was unusable, matching the report in #38456.

## Fix
`GetRepositoryFile` now falls back to the `noarch` index when the
requested architecture has no index of its own, mirroring the fallback
already present in the sibling `DownloadPackageFile` handler. `noarch`
packages are installable on every architecture, so serving them for any
requested architecture is correct. The index-build side is unchanged;
only the serving path gains the fallback, so mixed repositories (which
already merge `noarch` into each per-architecture index) are unaffected.

## AI assistance disclosure
This change was implemented with the help of an AI coding assistant,
which gitea's CONTRIBUTING.md explicitly welcomes when disclosed. I have
reviewed the change, understand it, and can explain and defend it.

## Tests
Added a `NoArchOnly` subtest to `TestPackageAlpine` that publishes only
a `noarch` package to a fresh repository and asserts that `GET
.../x86_64/APKINDEX.tar.gz` now returns `200` (previously `404`) and
that the served index lists the noarch package. Verified locally with
`go build`/`go vet` on the changed package and a compile of the
integration test package (`go test -c`); the full integration run relies
on CI.

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Gaurav Dubey <gauravdubey0107@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-16 12:28:39 +02:00
Giteabot 5cb7ec9304 fix: make "test push webhook" always work (#38425) (#38455)
Backport #38425

* fix #38309
* fix #26238
* fix #37886

Co-authored-by: Harsh Satyajit Thakur <f20240223@goa.bits-pilani.ac.in>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-15 05:51:44 +00:00
Giteabot 6e86c4cde8 fix(actions): prevent bulk actions from affecting all runners (#38453) (#38457)
Backport #38453

Co-authored-by: xkm <fzc_study@163.com>
2026-07-14 20:06:17 -07:00
Giteabot de4b8277e9 fix: various security fixes (#38406) (#38426)
Backport #38406 by @bircni

Addresses a batch of privately reported security issues, grouped by
area:

- **SSRF** - migration PR-patch/asset fetches, OAuth2 avatar & OpenID
discovery, pull-mirror URL re-validation, and the outbound proxy path.
- **Access-token scope** - prevent scope escalation on token creation;
keep public-only tokens confined (feeds, packages, Actions listings,
star/watch lists, limited/private owners).
- **Access control / disclosure** - go-get default-branch leak, webhook
authorization-header leak, watch clearing on private transitions,
label/attachment scoping.
- **Denial of service** - input bounds for npm dist-tags, Debian control
files, Arch file lists, and SSH keys.

### 📌 Attention for site admins

Not breaking - existing configs keep working - but two changes are worth
a look:

- **New SSRF protection** Outbound requests (migrations, OAuth2 avatars,
OpenID discovery, pull mirrors, proxy path) are now validated against
the allow/block host lists. If your instance legitimately reaches
internal hosts, you may need to add them to
`[security].ALLOWED_HOST_LIST` (and the relevant `ALLOW_LOCALNETWORKS`
settings).
- **Deprecation** `[webhook].ALLOWED_HOST_LIST` is deprecated and will
be removed in a future release. Use `[security].ALLOWED_HOST_LIST`
instead; the old key still works for now.

Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: TheFox0x7 <thefox0x7@gmail.com>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
2026-07-12 17:41:58 +00:00
Giteabot 6815d1646c fix: refresh pull request merge box when the commit status is pending (#38410) (#38411)
Backport #38410

Before: the merge box is only refreshed when the PR is being
conflict-checked.

After: also refresh the merge box when the commit status is pending
(e.g.: Action task is running)

By the way, slightly increase the refresh interval to 5s

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-12 07:15:25 +08:00
Giteabot ed493f0684 fix(security): harden access checks and migration validation (#38324) (#38400) 2026-07-10 20:14:38 +02:00
Giteabot af7ba2edef fix: enforce public-only token scope and harden push options / locale parsing (#38323) (#38399)
Backport #38323 by @bircni

Three independent security hardening fixes, each with a regression test:

- **Locale DoS:** the `Locale` middleware passed the raw
`Accept-Language` header to `ParseAcceptLanguage`, whose guard only
counts `-` while the scanner aliases `_` to `-` — a large `_`-separated
header on an unauthenticated request burned CPU. The header is now
length-bounded before parsing.
- **Public-only token scope:** `GET /teams/{id}/repos`,
`.../repos/{org}/{repo}`, `/teams/{id}/activities/feeds`, and
`/users/{username}/orgs/{org}/permissions` still returned private
repo/activity/permission data to a public-only token. They now filter
via `TokenCanAccessRepo` / `ApplyPublicOnly` and reject non-public org
permissions.
- **Push-option visibility:** `repo.private` / `repo.template` push
options were applied to any existing repo, letting an owner/admin
silently flip visibility bypassing audit, webhooks, and notifications.
They are now honored only on push-to-create.

Co-authored-by: bircni <bircni@icloud.com>
2026-07-10 19:07:04 +02:00
Giteabot 500a09e044 fix(api): stop leaking private repo metadata after access revocation (#38321) (#38390)
Backport #38321 by @bircni

The `/user/starred` and `/user/subscriptions` endpoints returned private
repositories a user had starred/watched even after their access to those
repositories was revoked, still exposing the repository name,
description and visibility (including later metadata changes).

Private repositories in the starred/watched queries are now gated on the
actor's current access via `AccessibleRepositoryCondition`, so users who
no longer have access no longer receive the metadata. Public
repositories and public-only tokens are unaffected.

Co-authored-by: bircni <bircni@icloud.com>
2026-07-10 07:40:02 +00:00
Giteabot bfebc4b0e1 fix: incorrect co-author detection on commit page (#38386) (#38387)
Backport #38386 by @bircni


The commit page built its "co-authored by" list from
`AllParticipantIdentities()[1:]`, which only drops the author and leaves
the committer in the list even though the committer is already shown
separately as "committed by". This caused the committer to be wrongly
rendered as a co-author (issue #38384): a commit authored by
`silverwind`, committed by `bircni`, with a `Co-authored-by: silverwind`
trailer displayed "co-authored by bircni" instead of the actual trailer
identity. This adds a `Commit.CoAuthorIdentities()` method that excludes
both the author and the committer, uses it on the commit page, and
covers the fix with a regression test.

Closes #38384

Co-authored-by: bircni <bircni@icloud.com>
2026-07-09 18:29:28 -07:00
Giteabot 64d559a8e6 perf(actions): debounce runner heartbeat writes and throttle task picks (#38281) (#38368)
Backport #38281 by @bircni

3 reductions in the DB load generated by many runners polling `FetchTask`:

**1. Debounce runner heartbeat writes**
Every poll wrote `last_online`, and every `UpdateTask`/`UpdateLog` wrote
`last_active` — while a runner streams logs that is many writes per
second per runner. These are now persisted only when stale enough to
actually affect the active/offline status (`ShouldPersistLastOnline` /
`ShouldPersistLastActive`), using the existing columns.

**2. Throttle concurrent task picks**
A new in-process semaphore (`MAX_CONCURRENT_TASK_PICKS`) bounds how many
runners run the task-assignment transaction at once, so a fleet polling
together cannot stampede the query. Throttled polls retry on their next
poll without advancing the runner's tasks version.

**3. Paginate the task-pick query**
`CreateTaskForRunner` previously loaded every waiting job in the
runner's scope into memory on each poll (no `LIMIT`). Now it pages
through the waiting backlog oldest-first with `LIMIT`, claiming the
first label-matching job.

Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
2026-07-07 16:27:00 -07:00
Giteabot e07a5de53f fix: org project view assignee list (#38357) (#38360)
Backport #38357

fix #38129

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-07 07:07:30 +00:00
Giteabot 37c8604105 fix(release): validate web attachment renames against allowed types (#38314) (#38328)
Backport #38314 by @lunny

This fixes the web release edit flow so renamed release attachments are
validated against `[repository.release] ALLOWED_TYPES`.

Previously, the API attachment edit endpoint already enforced release
attachment type restrictions, but the web release edit form passed
`attachment-edit-*` values into `release_service.UpdateRelease`, which
updated attachment names directly without validating the new filename
against `setting.Repository.Release.AllowedTypes`.

As a result, a user with repository write access could rename an
existing release attachment to a disallowed extension through the web
UI.

- validate edited release attachment names in
`release_service.UpdateRelease`
- reject forbidden attachment renames using
  `setting.Repository.Release.AllowedTypes`
- re-render the web release edit page with a validation error instead of
  returning an internal server error
- add regression coverage for both the service layer and the web flow

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-04 17:45:11 +02:00
Giteabot ab10e37acf fix(release): gate draft release attachments on web download endpoints (#38318) (#38325)
Backport #38318 by @bircni

Draft-release access control was enforced only on the API release
endpoints (`/api/v1/repos/{owner}/{repo}/releases/...`) but not on the
UUID-based web attachment endpoints (`/attachments/{uuid}`,
`/{owner}/{repo}/attachments/{uuid}`,
`/{owner}/{repo}/releases/attachments/{uuid}`).

Anyone who obtained an attachment UUID — including unauthenticated
callers — could download files belonging to a hidden draft release,
since `ServeAttachment` only checked repo-level read permission and
never the release's draft state.

This extends `ServeAttachment` to require write access to releases when
the attachment belongs to a draft release, mirroring the existing
API-side `canAccessReleaseDraft` gate. A regression test is included.

Co-authored-by: bircni <bircni@icloud.com>
2026-07-03 20:34:37 +02:00
Giteabot f7bc6b89c1 fix: Improve since/until when counting commits for X-Total-Count (#38243) (#38304)
Backport #38243 by @puni9869

Follow up for https://github.com/go-gitea/gitea/pull/38204.

Signed-off-by: puni9869 <80308335+puni9869@users.noreply.github.com>
Co-authored-by: puni9869 <80308335+puni9869@users.noreply.github.com>
2026-07-02 10:07:29 +00:00
Giteabot b6e409badd fix(oauth2): persist linkAccountData during auto-link 2FA flow (#38274) (#38295)
Backport #38274 by @afahey03

Fixes HTTP 500 when OIDC auto account linking (`ACCOUNT_LINKING=auto`)
requires local 2FA. `oauth2LinkAccount` set `linkAccount` in the session
before redirecting to 2FA but did not persist `linkAccountData`, so
`TwoFactorPost` failed with `not in LinkAccount session`. The manual
linking flow already stored both, this aligns auto-link with that
behavior.

Created the test, `TestOAuth2AutoLinkWithTwoFactor`, which verifies that
automatic account linking completes after the user passes local 2FA when
an OIDC identity matches an existing account.

DISCLAIMER: I used AI to create the test

Closes #38171

Co-authored-by: Aidan Fahey <afahey2003@yahoo.com>
Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-01 13:18:37 +02:00
Giteabot 2734504cfc fix(actions): allow Actions bot to push to protected branches (#38284) (#38293)
Backport #38284 by @bircni

Fixes #38278

## Problem

When branch protection matches the branch an Actions workflow pushes to,
the runner's `git push` is rejected — even though the workflow token has
`contents: write` and the same push performed with a PAT (write access)
succeeds. Disabling protection or changing the pattern so it no longer
matches makes the push work.

## Root cause

In `preReceiveBranch` (`routers/private/hook_pre_receive.go`), the "can
the doer push to this protected branch" check resolves the pusher with
`user_model.GetUserByID(ctx, ctx.opts.UserID)`. For an Actions push the
user ID is `-2` (the virtual `ActionsUserID`), which has no database
row, so the lookup fails. Even past that, `CanUserPush` →
`HasAccessUnit`/whitelist membership cannot evaluate a virtual user and
returns `false`. As a result the Actions bot was rejected on every
matching protected branch, despite the earlier `assertCanWriteRef`
already confirming the token's code-write via
`GetActionsUserRepoPermission`.

This was inconsistent: a PAT with identical write access passed the
exact same check.

## Fix

Evaluate the Actions bot against its already-computed token permission
instead of a user lookup, mirroring the existing
`IsUserMergeWhitelisted` pattern:

- Add `CanActionsUserPush` / `CanActionsUserForcePush` on
`ProtectedBranch`, which take the precomputed `access_model.Permission`.
- Allow the push when push is enabled, **no** push whitelist is
enforced, and the token has code-write.
- Keep the bot blocked when a whitelist is enforced — it cannot be added
to one, so it must use a pull request. This preserves the whitelist as a
real security boundary.

Force-push, signed-commit and protected-file-path checks are untouched.

Signed-off-by: bircni <bircni@icloud.com>
Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-01 11:46:17 +02:00
metsw24-max 0c67849e68 fix(packages): validate debian distribution and component names (#38116)
**Newline injection into the Debian Release and Packages indices**

The `distribution` and `component` come straight from the request path
and are written line by line into the generated `Release` and `Packages`
files (the `Suite`/`Codename`/`Components` lines and the `Filename:
pool/<distribution>/<component>/...` line), but `UploadPackageFile` only
checked they were non-empty. `ctx.PathParam` url-decodes the segment, so
an encoded newline such as `main%0AInjected-Field: x` is accepted,
stored and then re-emitted for that distribution, which lets an
authenticated uploader forge extra fields in the index apt consumes.
Restricted both values to a conservative name pattern in the handler,
since that is the layer that accepts them; this should also keep the
pool paths well formed.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-06-29 06:50:22 +00:00
bircni 1c718da16c fix(api): support HEAD requests on all API GET endpoints (#38245)
Fixes #38226

## Summary

Add `chi_middleware.GetHead` as the first `BeforeRouting` middleware on
the API router. This makes every API `GET` endpoint automatically handle
`HEAD` requests, as required by RFC 9110 §9.3.2.

Previously, `HEAD` requests to endpoints like `GET
/repos/{owner}/{repo}/git/commits/{sha}` returned `405 Method Not
Allowed`.

The web router already used this same middleware (see
`routers/web/web.go:261`), so this aligns API behaviour with the web
router.

## Changes

- `routers/api/v1/api.go`: add `chi_middleware.GetHead` middleware to
the API router
- `tests/integration/api_repo_git_commits_test.go`: add
`TestAPIReposGitCommitsHEAD` verifying HEAD returns 200 on a valid ref
and 404 (not 405) on a missing ref
2026-06-28 12:14:39 +00:00
Lunny Xiao 5b9251150c fix(actions): address workflow status badge review feedback (#38241)
Follow
https://github.com/go-gitea/gitea/pull/38196#discussion_r3487219492

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: bircni <bircni@icloud.com>
2026-06-28 10:53:01 +00:00
Zettat123 f46c9a9769 feat(actions): support owner-level and global scoped workflows (#38154)
## Summary

This PR adds **scoped workflows** to Gitea Actions. Workflows defined
centrally in a "source" repository that automatically run on every
repository in scope: an organization's repositories, or (for instance
admins) every repository on the instance. Each scoped run executes in
the consuming repository's own context (its runners, secrets, and
branch) while its content is read from the source repository, so an org
or instance can mandate shared CI across many repositories without
copying workflow files into each one.

An owner or instance admin registers source repositories on a settings
page and can mark individual workflows as **required**. A required
scoped workflow cannot be opted out by a consuming repository and gates
its pull-request merges; an optional one can be disabled per repository.
Scoped workflows live under a dedicated `SCOPED_WORKFLOW_DIRS` (default
`.gitea/scoped_workflows`), kept separate from regular `WORKFLOW_DIRS`.

## Main changes

### Configuration 
New `SCOPED_WORKFLOW_DIRS` setting, validated to not overlap with
`WORKFLOW_DIRS`. Default: `.gitea/scoped_workflows`

### Data model & migration
- New `action_scoped_workflow_source` table mapping a registering owner
(`owner_id`, where `0` = instance-level) to a source repository, with a
per-workflow `WorkflowConfigs` map.
- `ActionRun` gains `WorkflowRepoID` / `WorkflowCommitSHA` (the pinned
content source) and an `IsScopedRun` flag.

###  Detection & run creation
On consumer events, scoped workflows from the effective sources (the
owner's own sources plus instance-level ones) are matched and turned
into runs that execute in the consumer's context, with content pinned to
the source repo's default-branch commit.

`on: workflow_run` and `on: schedule` are currently not supported.

###  Opt-out
A consuming repository can disable an optional scoped workflow (tracked
separately from regular `DisabledWorkflows`); required scoped workflows
can never be disabled, opted out, or bypassed.

###  Commit status 
A scoped run's status context format is `"<source repo full name>:
<workflow display name> / <job> (<event>)"`
(for example: `my-org/scoped-workflows: db-tests / test-sqlite
(pull_request)`),
keeping it distinct from a same-named repo-level workflow and from other
sources.

###  Required status checks
Admins mark workflows required and supply status-check patterns.
`EffectiveRequiredContexts` appends those patterns to the branch
protection's required contexts and they are matched
must-present-and-pass. If the status checks from scoped workflows fail,
the PR cannot be merged.

NOTE: scoped workflows' required status checks patterns can protect any
target branch that has a protection rule, even though the rule's "Status
Check" is disabled. A target branch with no protection rule cannot be
protected.

<details>
  <summary>Screenshots</summary>

<img width="1400" alt="image"
src="https://github.com/user-attachments/assets/a5d1db33-15ec-487e-93be-2bc04b4e6643"
/>

</details>


###  Reusable workflows (`uses:`)
A scoped workflow's local `uses: ./...` resolves against the source
repository. `uses:` directory validation honors the
instance-configurable `WORKFLOW_DIRS` and `SCOPED_WORKFLOW_DIRS`
(previously hardcoded to `.gitea`/`.github/workflows`).

###  Manual dispatch
`workflow_dispatch` is supported for scoped workflows (web and API),
resolving inputs/content from the source repo.

###  Performance
A process-local LRU cache keyed by source repo ID for the per-source
workflow parse, so instance-level and owner-level sources don't open the
source repo and parse workflow files on every event.

### UI
Org / user / admin pages to register and remove sources, search
repositories, and mark workflows required with their status-check
patterns. The repository Actions sidebar groups scoped workflows by
source with owner/instance labels and required/disabled badges.

<details>
  <summary>Screenshots</summary>

Scoped workflows setting page:

<img width="1600" alt="image"
src="https://github.com/user-attachments/assets/9d19f667-97a5-4935-92b2-e53f105e3642"
/>


Consumer repo's Actions runs list:

<img width="1600" alt="image"
src="https://github.com/user-attachments/assets/a77241f9-0aa9-41aa-ba73-12a9a688cb64"
/>

- `Owner`: this is a owner-level scoped workflows source repo
- `Global`: this is a global scoped workflows source repo
- `Required`: this scoped workflow is required, repo admin cannot
disable it

</details>

---

Docs: https://gitea.com/gitea/docs/pulls/447

---------

Co-authored-by: bircni <bircni@icloud.com>
2026-06-28 09:31:35 +00:00
Lunny Xiao c9920b7bd0 fix(oauth): restrict introspection to the token's client (#38042)
Bind OAuth token introspection responses to the authenticated client.
Return an inactive response when the token grant belongs to a different
OAuth application to avoid leaking token metadata across clients.

Add integration coverage for cross-client introspection attempts against
both access tokens and refresh tokens.

Assisted-by: GPT-5.4
2026-06-28 08:06:33 +00:00
guanzi008 9540292596 feat(actions): add workflow status badge modal (#38196)
- Add a Create Status Badge button for selected Actions workflows.
- Show badge URL, Markdown, and HTML snippets backed by the existing
workflow badge route.

## Screenshots
<img width="553" height="470" alt="dyn-a5d565ab915b9ffb6c02ac68113494b0"
src="https://github.com/user-attachments/assets/43b4ceb9-bbd1-4024-b058-d85ec8325e88"
/>
<img width="349" height="156" alt="grafik"
src="https://github.com/user-attachments/assets/6eaec62d-ffb0-45c0-b63d-866a41a66005"
/>



Fixes https://github.com/go-gitea/gitea/issues/31462

---------

Signed-off-by: guanzi008 <245205080@qq.com>
Co-authored-by: bircni <bircni@icloud.com>
2026-06-28 01:36:45 +02:00
Lunny Xiao cbe1b703dc refactor: Use db.Get[] instead of db.GetEngine(ctx).Get(bean) to avoid zero value fetching wrong database record (#37977)
This PR replaces a set of struct-based `Get` lookups with explicit
`db.Get` / `db.Exist` conditions in places where zero-value fields can
lead to ambiguous matches or incorrect records being returned.

The main goal is to make read paths deterministic and avoid accidentally
matching the wrong row when only part of a struct is populated.

### What changed

- replace many `db.GetEngine(ctx).Get(bean)` calls with explicit
`builder.Eq` conditions across models such as actions, admin tasks,
issues, pull requests, repositories, users, packages, redirects,
watches, stars, and follows
- use quoted column names where needed for reserved fields like `index`,
`type`, and `name`
- add dedicated user lookup helpers for:
  - primary email
  - OAuth login source / login name
- update sign-in and OAuth-related flows to use explicit individual-user
lookups instead of partially populated `User` structs
- tighten package property and Terraform lock lookups to avoid ambiguous
reads and updates
- keep existing fallback behavior where needed, while removing reliance
on zero-value struct matching

### User-facing impact

These changes primarily affect authentication and account lookup paths:

- email/username sign-in now re-fetches users through explicit keys
- OAuth2 auto-linking now resolves users by name or primary email
explicitly
- OAuth2 login/sync now looks up users by login source, login type, and
login name explicitly
- non-individual accounts are no longer implicitly matched through
partial user lookups in these flows

This should reduce the risk of incorrect account matches and make query
behavior more predictable across the codebase.

---------

Co-authored-by: bircni <bircni@icloud.com>
2026-06-27 10:24:02 -07:00
bircni 122ebcf0a8 fix(api): deny private org member enumeration via /members (#38213) 2026-06-26 18:35:13 +00:00
Eyüp Can Akman ef927f9fa3 feat(api): support ref suffixes in compare (#38148)
Compare API requests with a `^` or `~N` revision suffix (for example
`compare/main...feature^`) were rejected with `400 Unsupported
comparison syntax: ref with suffix`. The fix resolves the suffix to a
commit before comparing, so `base...head^` and `~N` work on either side,
the same as git.

Only `^`/`~N` navigation is resolved. Pull request creation still
requires plain branch refs, and the web compare page keeps rejecting
suffixes since its branch selectors need separate UI work.

Closes #33943
2026-06-24 05:38:02 +00:00
bircni 649cb6ff3e fix(actions): show run index in run view and fix summary graph height (#38165)
- Display the per-repository run number as `#N` next to the run title in
the run view, matching the runs list and GitHub
- Add the run `Index` to the run view API response (and the devtest
mock) to support that
- Restore the summary panel's `flex: 1` so the workflow graph fills the
right-column height even when a run has no job summaries
- Keep the job-summary section content-sized so it doesn't compete with
the graph for height
- Gate the devtest mock job summaries to a subset of runs so the devtest
page also exercises the no-summary layout

<img width="521" height="232" alt="image"
src="https://github.com/user-attachments/assets/a1f2f20b-65bd-4d98-ba6a-b8135580a6de"
/>
2026-06-22 06:16:09 +00:00
bircni 685b62c60f fix(api): don't expose private org membership via public_members (#38145) 2026-06-22 05:50:02 +02:00
bircni 180af33f86 perf: Various performance regression fixes (#38078)
Fixes five N+1 / O(n) query patterns found across common user paths.
Each uses a bulk query that already existed elsewhere in the codebase.

| Location | Problem | Introduced in |
| -------------------------------- |
-------------------------------------------------------------------------------------------------------------------------------
| ------------- |
| `IssueList.LoadIsRead` | `.In("issue_id")` missing its arg — xorm
generates `WHERE 0=1`, so `IsRead` is **never** set; every issue always
appears unread | #29515 |
| `ParseCommitsWithStatus` | `GetLatestCommitStatus` called once per
commit (O(n) queries on commit list / PR commits tab) | #33605 |
| `getReleaseInfos` (release list) | `GetLatestCommitStatus` called once
per release for CI badges | #29149 |
| User milestone dashboard | O(n×m) nested loop matching milestones to
repos | #26300 |
| `findCodeComments` (PR diff) | `LoadResolveDoer` + `LoadReactions`
called per inline comment — up to ~150 queries on a PR with 50 comments
| #20821 |

---------

Co-authored-by: Lauris B <lauris@nix.lv>
2026-06-21 14:34:07 +00:00
fwag 9c82394315 fix: Fix issue target branch selection for non-collaborators (#36916)
This PR fixes a bug in the UI that prevented non-collaborator users (the
issue poster or creator) from setting the target branch (ref) of an
issue. The backend API already supports this, but the UI was rigidly
disabling the dropdown based only on collaborator status.

Changes:
- Enable the branch selector for the issue poster and during new issue
creation.
- Fix a typo (.IsIssueWriter -> .IsIssuePoster) that was preventing the
reference update URL from being correctly set for posters.
2026-06-18 12:24:37 +00:00
silverwind de83393487 refactor: replace legacy delete-button with link-action (#38143)
Removes the legacy `delete-button` handler (`initGlobalDeleteButton`)
and migrates all remaining usages to `link-action` and `show-modal` /
`form-fetch-action`.

Two handlers are adjusted for the new request shape: webauthn key delete
reads `id` from the query, and account deletion returns `JSONError` on
validation failure.

A E2E test ist added to cover one of the use cases.

Suggested in
https://github.com/go-gitea/gitea/pull/38046#discussion_r3414936737.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: bircni <bircni@icloud.com>
2026-06-18 12:02:11 +00:00
bircni 68692e19d4 fix: Various security fixes (#38103)
- Enforce org visibility on organization label read endpoints (private
org labels no longer leak to non-members).
- Block fork sync (`merge-upstream`) when the base repo is no longer
readable (stops pulling commits after a parent goes private).
- Remove `REVERSE_PROXY_LIMIT` / `REVERSE_PROXY_TRUSTED_PROXIES` from
the Docker `app.ini` templates (the `= *` default allowed
`X-WEBAUTH-USER` impersonation; reverse-proxy auth is now opt-in and
admin-configured).
- Enforce single-use TOTP passcodes across web login, password-reset,
and Basic-Auth `X-Gitea-OTP` (fixes a TOCTOU race and a stateless
replay).
- Re-check branch write permission for every ref in a push (the
pre-receive hook cached the first ref's result, letting a per-branch
maintainer-edit grant escalate to full repo write).

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-06-17 16:06:51 +00:00
bircni 9e84deb969 fix: Various sec fixes 2 (#38108)
- Enforce repository token scope on RSS/Atom feed endpoints so a PAT
without repo scope can no longer read private repo commit data.
- Block HTTP redirects during repository migration clones to prevent
SSRF reaching internal addresses via an attacker-controlled redirect.
- Redact the notification subject after repo access is revoked so
private issue/PR metadata is no longer leaked through the notification
API.

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-06-17 06:50:25 +02:00
Rafail Giavrimis 052feee34a feat: add raw diff/patch endpoint for repository comparisons (#37632)
## Summary

Adds `GET
/repos/{owner}/{repo}/compare/{basehead}.{diffType:diff|patch}`,
mirroring the existing `/git/commits/{sha}.{diffType}` endpoint but for
comparisons between two arbitrary refs.

The new endpoint streams a raw unified diff or `git format-patch` output
between any two refs:

GET /repos/{owner}/{repo}/compare/main...feature.diff
GET /repos/{owner}/{repo}/compare/v1.0..v1.1.patch
GET /repos/{owner}/{repo}/compare/abc1234...def5678.diff

Resolves #5561, #13416 and #17165.

AI was used while creating this PR. Automated tests were added as per
the contribution policy.

---------

Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 09:37:15 -07:00
bircni 55250407dd feat(org): add team visibility so org members can discover teams (#37680)
Closes #37670.

Today, org members in Gitea only see teams they're a member of. In
larger orgs that hurts onboarding and discoverability — there's no way
to look up which team owns what without asking around. GitHub solves
this with a per-team visibility setting; this PR brings the same model
to Gitea.

## What changes

- Every team gets a `visibility` setting:
- `private` *(default)* — only team members and org owners can see the
team. Same as today's behavior.
- `limited` — listable by any member of the organization. Members and
the repos the team has access to are visible too. Non-org-members still
see nothing.
  - `public` — listable by any signed-in user.
- The Owners team visibility is fixed and cannot be changed via
settings.
- Existing teams default to `private`, so this is a no-op for anyone who
doesn't change anything.

## API

- `Team`, `CreateTeamOption`, `EditTeamOption` all gain a `visibility`
field (string enum: `private` | `limited` | `public`).
- `GET /orgs/{org}/teams` and `/orgs/{org}/teams/search` now apply the
same visibility rules as the web UI:
  - site admins and org owners still see every team
- other org members see their own teams plus any `limited` or `public`
team
  - `private` teams are no longer leaked through these endpoints
- Swagger/OpenAPI specs regenerated.

## UI

View from admin2 (not an owner):
<img width="1669" height="726"
src="https://github.com/user-attachments/assets/daf4bccb-644b-4426-b178-71963aeaf73b"
/>

View from admin (owner):

<img width="2559" height="863"
src="https://github.com/user-attachments/assets/4f22cebc-e9df-4fd2-8ed4-724d31fadb7a"
/>

---------

Signed-off-by: bircni <bircni@icloud.com>
Co-authored-by: TheFox0x7 <thefox0x7@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-06-14 19:07:25 +00:00
wxiaoguang 47d48eb208 chore: fix form string abuse (#38106) 2026-06-14 18:26:22 +00:00
TheFox0x7 c6167d1ff5 feat(api): add token introspection and self-deletion endpoint (#37995)
Adds a /api/v1/token endpoint that allows tokens to introspect and
delete themselves.
partially fixes: https://github.com/go-gitea/gitea/issues/33583

Assisted-by: Mistral Vibe:mistral-medium-3.5

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-06-14 20:05:18 +02:00
Pycub c7af379672 fix(api): nil pointer panic when filtering tracked times by a non-existent user (#38112)
## Problem

`GET /repos/{owner}/{repo}/times` and `GET
/repos/{owner}/{repo}/issues/{index}/times` crash with a nil pointer
dereference when the `user` query filter names a user that does not
exist.

## Root cause

In `ListTrackedTimes` and `ListTrackedTimesByRepository`, the
`IsErrUserNotExist` branch sends the 404 but is missing a `return`, so
execution falls through to `opts.UserID = user.ID` with a nil `user`.

---------

Co-authored-by: bircni <bircni@icloud.com>
2026-06-14 17:23:48 +02:00
wxiaoguang 1b3b4bdd03 fix: git push hook post receive (#38089)
* fix incorrect delayWriter call (there is already a defer call)
* split HookPostReceive into small functions
* fix incorrect HookPostReceiveResult response for errors
* fix incorrect AddRepoToLicenseUpdaterQueue call
* make sure repo home and branches page can work without default branch
* make sure default branch is always synchronized between database and
git repo, and fix FIXME
2026-06-13 04:43:25 +00:00
bircni 9608cc212d fix: allow git clone of private repos with anonymous code access (#38074)
Fixes #38062.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-06-13 12:02:02 +08:00
wxiaoguang f5a97b7518 fix: git cmd (#38084) 2026-06-12 07:35:59 +02:00
wxiaoguang 4f4a0a79ac fix: csp regressions (#38047)
fix #37257 , all details are in the comments
2026-06-12 08:36:05 +08:00
bircni 5a24438698 chore: various trivial fixes (#38070)
Follow-up to #37987, addressing the unresolved review comments on the
org members search form.

And fix more trivial problems together (see the commit titles)

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-06-11 17:33:21 +00:00
bn-zr fefb6f3219 feat(api): Add GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs (#37196)
- Add GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs
endpoint, matching the
https://docs.github.com/en/rest/actions/workflow-runs?apiVersion=2026-03-10#list-workflow-runs-for-a-workflow

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: bircni <bircni@icloud.com>
2026-06-11 17:12:30 +00:00
bircni bc2fbe77b1 refactor(actions): read runner capabilities from proto field (#38068)
[actions-proto-go v0.6.0](https://gitea.com/gitea/actions-proto-go) adds
a
`capabilities` field to `RegisterRequest` and `DeclareRequest`. This
lets a
runner advertise the transitional `cancelling` capability directly in
the proto
message instead of through the out-of-band mechanism we used while the
proto
bump was pending.

This PR:

- Bumps `gitea.dev/actions-proto-go` to `v0.6.0`.
- Drops the forward-compat `capabilityGetter` type-assertion shim and
the
`runnerRequestHasCancellingCapability` helper, reading
`GetCapabilities()`
  directly (now part of the `declareRequest` interface).
- Removes the "capability state unknown → preserve existing value"
branch.

## Why the behaviour change is correct

The shim and the `(hasSupport, known)` two-value return only existed
because the
old proto had no `capabilities` field, so we couldn't tell "runner
doesn't
support it" from "we can't see the field." With v0.6.0 the field is
always
present. Since proto3 repeated fields have no presence, "no capabilities
sent"
now unambiguously means the runner does not advertise the capability, so
a
runner that omits `cancelling` is correctly recorded as
`HasCancellingSupport =
false`.

There is no regression: prior to this bump Gitea was on `v0.5.0`, where
the
type assertion always failed and `HasCancellingSupport` was therefore
never set
from requests — so no runner relied on the preserved-unknown path.

## Compatibility

The change is wire-compatible in both directions of version skew,
because the
new field uses a previously unused field number (8 on `RegisterRequest`,
3 on
`DeclareRequest`) and the transport uses the binary protobuf codec:

- **Old runner → new Gitea:** the runner omits the field; it decodes to
an empty
capability list. Registration/declaration succeed; the runner simply
doesn't
  get the cancelling feature.
- **New runner → old Gitea:** the runner sends the field; the old
server's
  generated code doesn't know the field number and silently ignores it.
  Registration/declaration succeed.

The feature only activates once both server and runner are on `v0.6.0`.
2026-06-11 09:18:31 +00:00
wxiaoguang 442f5e7d06 chore: fine tune pull request merge box and commit status item (#38060) 2026-06-10 22:44:21 +00:00
Eugenio Paolantonio fa89785d33 feat(api): add Link header in ListForks (#38052)
Fixes #38051.

Disclosure: writing of the integration test was AI assisted.

---------

Signed-off-by: Eugenio Paolantonio <eugenio.paolantonio@suse.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-06-10 17:34:10 +00:00
Giteabot 5fe77ad309 fix(deps): update go dependencies (#37967)
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [gitea.com/gitea/runner](https://gitea.com/gitea/runner) | `v1.0.5` →
`v1.0.6` |
![age](https://developer.mend.io/api/mc/badges/age/go/gitea.com%2fgitea%2frunner/v1.0.6?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/go/gitea.com%2fgitea%2frunner/v1.0.5/v1.0.6?slim=true)
|
|
[github.com/aws/aws-sdk-go-v2/credentials](https://redirect.github.com/aws/aws-sdk-go-v2)
| `v1.19.16` → `v1.19.17` |
![age](https://developer.mend.io/api/mc/badges/age/go/github.com%2faws%2faws-sdk-go-v2%2fcredentials/v1.19.17?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/go/github.com%2faws%2faws-sdk-go-v2%2fcredentials/v1.19.16/v1.19.17?slim=true)
|
|
[github.com/getkin/kin-openapi](https://redirect.github.com/getkin/kin-openapi)
| `v0.138.0` → `v0.139.0` |
![age](https://developer.mend.io/api/mc/badges/age/go/github.com%2fgetkin%2fkin-openapi/v0.139.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/go/github.com%2fgetkin%2fkin-openapi/v0.138.0/v0.139.0?slim=true)
|
| [github.com/go-chi/chi/v5](https://redirect.github.com/go-chi/chi) |
`v5.2.5` → `v5.3.0` |
![age](https://developer.mend.io/api/mc/badges/age/go/github.com%2fgo-chi%2fchi%2fv5/v5.3.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/go/github.com%2fgo-chi%2fchi%2fv5/v5.2.5/v5.3.0?slim=true)
|
|
[github.com/go-webauthn/webauthn](https://redirect.github.com/go-webauthn/webauthn)
| `v0.17.3` → `v0.17.4` |
![age](https://developer.mend.io/api/mc/badges/age/go/github.com%2fgo-webauthn%2fwebauthn/v0.17.4?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/go/github.com%2fgo-webauthn%2fwebauthn/v0.17.3/v0.17.4?slim=true)
|
|
[github.com/minio/minio-go/v7](https://redirect.github.com/minio/minio-go)
| `v7.1.0` → `v7.2.0` |
![age](https://developer.mend.io/api/mc/badges/age/go/github.com%2fminio%2fminio-go%2fv7/v7.2.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/go/github.com%2fminio%2fminio-go%2fv7/v7.1.0/v7.2.0?slim=true)
|
|
[gitlab.com/gitlab-org/api/client-go/v2](https://gitlab.com/gitlab-org/api/client-go)
| `v2.30.0` → `v2.34.0` |
![age](https://developer.mend.io/api/mc/badges/age/go/gitlab.com%2fgitlab-org%2fapi%2fclient-go%2fv2/v2.34.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/go/gitlab.com%2fgitlab-org%2fapi%2fclient-go%2fv2/v2.30.0/v2.34.0?slim=true)
|

---

### Release Notes

<details>
<summary>gitea/runner (gitea.com/gitea/runner)</summary>

### [`v1.0.6`](https://gitea.com/gitea/runner/releases/tag/v1.0.6)

[Compare Source](https://gitea.com/gitea/runner/compare/v1.0.5...v1.0.6)

#### Changelog

- fix(deps): update module github.com/opencontainers/selinux to v1.15.0
([#&#8203;990](https://redirect.github.com/gitea/runner/issues/990))
- chore: pin Docker base images to explicit versions
([#&#8203;992](https://redirect.github.com/gitea/runner/issues/992))
- chore(deps): update actions/setup-node action to v6
([#&#8203;991](https://redirect.github.com/gitea/runner/issues/991))
- test: make TestRunEvent integration suite runnable locally
([#&#8203;987](https://redirect.github.com/gitea/runner/issues/987))
- ci: add PR title linting against Conventional Commits
([#&#8203;988](https://redirect.github.com/gitea/runner/issues/988))
- fix: clean up job network and container when container start fails
([#&#8203;986](https://redirect.github.com/gitea/runner/issues/986))

</details>

<details>
<summary>getkin/kin-openapi (github.com/getkin/kin-openapi)</summary>

###
[`v0.139.0`](https://redirect.github.com/getkin/kin-openapi/releases/tag/v0.139.0)

[Compare
Source](https://redirect.github.com/getkin/kin-openapi/compare/v0.138.0...v0.139.0)

#### What's Changed

- feat(openapi3): batch-convert long-tail RequiredFieldError sites by
[@&#8203;reuvenharrison](https://redirect.github.com/reuvenharrison) in
[#&#8203;1170](https://redirect.github.com/getkin/kin-openapi/pull/1170)
- feat(openapi3): typed validation error clusters (combined:
[#&#8203;1171](https://redirect.github.com/getkin/kin-openapi/issues/1171)-[#&#8203;1179](https://redirect.github.com/getkin/kin-openapi/issues/1179))
by [@&#8203;reuvenharrison](https://redirect.github.com/reuvenharrison)
in
[#&#8203;1180](https://redirect.github.com/getkin/kin-openapi/pull/1180)
- openapi3gen: skip component export for anonymous types by
[@&#8203;0-don](https://redirect.github.com/0-don) in
[#&#8203;1163](https://redirect.github.com/getkin/kin-openapi/pull/1163)
- feat: migrate to oasdiff/yaml v0.1.0 single Unmarshal API + enable
DisableTimestamps by
[@&#8203;reuvenharrison](https://redirect.github.com/reuvenharrison) in
[#&#8203;1181](https://redirect.github.com/getkin/kin-openapi/pull/1181)
- openapi3: typed context errors for Validate() wrapper chain by
[@&#8203;reuvenharrison](https://redirect.github.com/reuvenharrison) in
[#&#8203;1183](https://redirect.github.com/getkin/kin-openapi/pull/1183)
- openapi3: track Origin on the document root (T) by
[@&#8203;reuvenharrison](https://redirect.github.com/reuvenharrison) in
[#&#8203;1184](https://redirect.github.com/getkin/kin-openapi/pull/1184)
- openapi3: tests flakiness corrected by
[@&#8203;fenollp](https://redirect.github.com/fenollp) in
[#&#8203;1159](https://redirect.github.com/getkin/kin-openapi/pull/1159)
- openapi3: aggregate independent validation errors via EnableMultiError
by [@&#8203;reuvenharrison](https://redirect.github.com/reuvenharrison)
in
[#&#8203;1185](https://redirect.github.com/getkin/kin-openapi/pull/1185)
- openapi3: fix validation of duplicated path templates by
[@&#8203;reuvenharrison](https://redirect.github.com/reuvenharrison) in
[#&#8203;1189](https://redirect.github.com/getkin/kin-openapi/pull/1189)
- openapi3: type the remaining bare-error validation sites by
[@&#8203;reuvenharrison](https://redirect.github.com/reuvenharrison) in
[#&#8203;1187](https://redirect.github.com/getkin/kin-openapi/pull/1187)

**Full Changelog**:
<https://github.com/getkin/kin-openapi/compare/v0.138.0...v0.139.0>

</details>

<details>
<summary>go-chi/chi (github.com/go-chi/chi/v5)</summary>

###
[`v5.3.0`](https://redirect.github.com/go-chi/chi/releases/tag/v5.3.0)

[Compare
Source](https://redirect.github.com/go-chi/chi/compare/v5.2.5...v5.3.0)

#### What's Changed

- Use strings.ReplaceAll where applicable by
[@&#8203;JRaspass](https://redirect.github.com/JRaspass) in
[#&#8203;1046](https://redirect.github.com/go-chi/chi/pull/1046)
- Propagate inline middlewares across mounted subrouters by
[@&#8203;LukasJenicek](https://redirect.github.com/LukasJenicek) in
[#&#8203;1049](https://redirect.github.com/go-chi/chi/pull/1049)
- add go 1.26 to ci by
[@&#8203;pkieltyka](https://redirect.github.com/pkieltyka) in
[#&#8203;1052](https://redirect.github.com/go-chi/chi/pull/1052)
- Remove last uses of io/ioutil by
[@&#8203;JRaspass](https://redirect.github.com/JRaspass) in
[#&#8203;1054](https://redirect.github.com/go-chi/chi/pull/1054)
- Simplify chi.walk with slices.Concat by
[@&#8203;JRaspass](https://redirect.github.com/JRaspass) in
[#&#8203;1053](https://redirect.github.com/go-chi/chi/pull/1053)
- Apply the stringscutprefix modernizer by
[@&#8203;JRaspass](https://redirect.github.com/JRaspass) in
[#&#8203;1051](https://redirect.github.com/go-chi/chi/pull/1051)
- Bump minimum Go to 1.23, always use request.Pattern by
[@&#8203;JRaspass](https://redirect.github.com/JRaspass) in
[#&#8203;1048](https://redirect.github.com/go-chi/chi/pull/1048)
- middleware: fix httpFancyWriter.ReadFrom double-counting bytes with
Tee by [@&#8203;alliasgher](https://redirect.github.com/alliasgher) in
[#&#8203;1085](https://redirect.github.com/go-chi/chi/pull/1085)
- Fix typo in Route doc comment by
[@&#8203;gouwazi](https://redirect.github.com/gouwazi) in
[#&#8203;1073](https://redirect.github.com/go-chi/chi/pull/1073)
- fix: set Request.Pattern from RoutePattern() by
[@&#8203;leno23](https://redirect.github.com/leno23) in
[#&#8203;1097](https://redirect.github.com/go-chi/chi/pull/1097)
- feat: middleware.ClientIP, a replacement for middleware.RealIP by
[@&#8203;VojtechVitek](https://redirect.github.com/VojtechVitek) in
[#&#8203;967](https://redirect.github.com/go-chi/chi/pull/967)

#### New Contributors

- [@&#8203;LukasJenicek](https://redirect.github.com/LukasJenicek) made
their first contribution in
[#&#8203;1049](https://redirect.github.com/go-chi/chi/pull/1049)
- [@&#8203;alliasgher](https://redirect.github.com/alliasgher) made
their first contribution in
[#&#8203;1085](https://redirect.github.com/go-chi/chi/pull/1085)
- [@&#8203;gouwazi](https://redirect.github.com/gouwazi) made their
first contribution in
[#&#8203;1073](https://redirect.github.com/go-chi/chi/pull/1073)
- [@&#8203;leno23](https://redirect.github.com/leno23) made their first
contribution in
[#&#8203;1097](https://redirect.github.com/go-chi/chi/pull/1097)

#### SECURITY: middleware.ClientIP, a replacement for middleware.RealIP

[@&#8203;VojtechVitek](https://redirect.github.com/VojtechVitek)
submitted PR
[#&#8203;967](https://redirect.github.com/go-chi/chi/issues/967), which
introduces middleware.ClientIP — a replacement for middleware.RealIP
that closes the three open spoofing advisories:

-
[GHSA-9g5q-2w5x-hmxf](https://redirect.github.com/go-chi/chi/security/advisories/GHSA-9g5q-2w5x-hmxf)
— IP spoofing via XFF in `RemoteAddr` resolution (convto)
-
[GHSA-rjr7-jggh-pgcp](https://redirect.github.com/go-chi/chi/security/advisories/GHSA-rjr7-jggh-pgcp)
— RealIP allows IP spoofing via unvalidated XFF (rezmoss)
-
[GHSA-3fxj-6jh8-hvhx](https://redirect.github.com/go-chi/chi/security/advisories/GHSA-3fxj-6jh8-hvhx)
— IP spoofing in `middleware.RealIP` (Saku0512, Critical / 9.3)

It also addresses issues outlined at:

- [#&#8203;708](https://redirect.github.com/go-chi/chi/issues/708)
- <https://adam-p.ca/blog/2022/03/x-forwarded-for/>
- [#&#8203;711](https://redirect.github.com/go-chi/chi/issues/711)
- [#&#8203;453](https://redirect.github.com/go-chi/chi/issues/453)
- [#&#8203;908](https://redirect.github.com/go-chi/chi/pull/908)

`middleware.RealIP` is deprecated in this PR with pointers to the new
API.

The deprecation only adds a `// Deprecated:` doc comment; the function
keeps working for backward compatibility.

##### Why a new middleware (not "fix RealIP in place")

`RealIP` has two unfixable design choices: it mutates `r.RemoteAddr`,
and it tries to be a one-size-fits-all default by walking a hard-coded
list of headers any client can supply. Per [adam-p's "The perils of the
'real' client IP"](https://adam-p.ca/blog/2022/03/x-forwarded-for/)
(which calls chi out by name on this), there is no safe default — the
user must pick their trust source explicitly.

##### The new API

Four middlewares, two accessors. Pick exactly one middleware based on
your
infrastructure, read the result with one of the two accessors:

```go
// One of the four. There is no safe default — pick exactly one.
func ClientIPFromHeader(trustedHeader string) func(http.Handler) http.Handler
func ClientIPFromXFF(trustedIPPrefixes ...string) func(http.Handler) http.Handler
func ClientIPFromXFFTrustedProxies(numTrustedProxies int) func(http.Handler) http.Handler
func ClientIPFromRemoteAddr(h http.Handler) http.Handler

// Read the result.
func GetClientIP(ctx context.Context) string         // for logs, rate-limit keys
func GetClientIPAddr(ctx context.Context) netip.Addr // for typed work
```

#### Example usage:

```go
// Pick a single ClientIP middleware based on your deployment
  
// Cloudflare.
r.Use(middleware.ClientIPFromHeader("CF-Connecting-IP"))

// Nginx with ngx_http_realip_module.
r.Use(middleware.ClientIPFromHeader("X-Real-IP"))

// Apache with mod_remoteip.
r.Use(middleware.ClientIPFromHeader("X-Client-IP"))

// AWS CloudFront, or any proxy fleet with known CIDRs.
r.Use(middleware.ClientIPFromXFF(
    "13.32.0.0/15",   // CloudFront IPv4
    "52.46.0.0/18",   // CloudFront IPv4
    "2600:9000::/28", // CloudFront IPv6
))

// Behind exactly 2 trusted proxies with dynamic IPs (autoscaling pools,
// ephemeral containers, dynamic CDN edges).
r.Use(middleware.ClientIPFromXFFTrustedProxies(2))

// Server directly on the public internet, no proxy in front.
r.Use(middleware.ClientIPFromRemoteAddr)
```

And in your handler or downstream middleware:

```go
clientIP := middleware.GetClientIP(r.Context())
// log it, use it as a rate-limit key, etc.
```

***

Thanks to [@&#8203;adam-p](https://redirect.github.com/adam-p),
[@&#8203;c2h5oh](https://redirect.github.com/c2h5oh),
[@&#8203;rezmoss](https://redirect.github.com/rezmoss),
[@&#8203;Saku0512](https://redirect.github.com/Saku0512),
[@&#8203;convto](https://redirect.github.com/convto),
[@&#8203;Dirbaio](https://redirect.github.com/Dirbaio),
[@&#8203;jawnsy](https://redirect.github.com/jawnsy),
[@&#8203;lrstanley](https://redirect.github.com/lrstanley),
[@&#8203;mfridman](https://redirect.github.com/mfridman),
[@&#8203;n33pm](https://redirect.github.com/n33pm),
[@&#8203;pkieltyka](https://redirect.github.com/pkieltyka) for the prior
discussions, detailed reviews, advisory reports, and test contributions
that shaped this PR.

**Full Changelog**:
<https://github.com/go-chi/chi/compare/v5.2.5...v5.3.0>

</details>

<details>
<summary>go-webauthn/webauthn
(github.com/go-webauthn/webauthn)</summary>

###
[`v0.17.4`](https://redirect.github.com/go-webauthn/webauthn/blob/HEAD/CHANGELOG.md#v0174-2026-05-22)

[Compare
Source](https://redirect.github.com/go-webauthn/webauthn/compare/v0.17.3...v0.17.4)

##### Dependency Updates

This release just contains updates to dependencies.

</details>

<details>
<summary>minio/minio-go (github.com/minio/minio-go/v7)</summary>

###
[`v7.2.0`](https://redirect.github.com/minio/minio-go/releases/tag/v7.2.0)

[Compare
Source](https://redirect.github.com/minio/minio-go/compare/v7.1.0...v7.2.0)

#### What's Changed

- Use go tool for ci-lint check by
[@&#8203;klauspost](https://redirect.github.com/klauspost) in
[#&#8203;2229](https://redirect.github.com/minio/minio-go/pull/2229)
- Rename github.com/go-ini/ini to gopkg.in/ini.v1 by
[@&#8203;ramondeklein](https://redirect.github.com/ramondeklein) in
[#&#8203;2232](https://redirect.github.com/minio/minio-go/pull/2232)
- Add RDMA / NVIDIA GPU Direct Storage support by
[@&#8203;harshavardhana](https://redirect.github.com/harshavardhana) in
[#&#8203;2233](https://redirect.github.com/minio/minio-go/pull/2233)

**Full Changelog**:
<https://github.com/minio/minio-go/compare/v7.1.0...v7.2.0>

</details>

<details>
<summary>gitlab-org/api/client-go
(gitlab.com/gitlab-org/api/client-go/v2)</summary>

###
[`v2.34.0`](https://gitlab.com/gitlab-org/api/client-go/tags/v2.34.0)

[Compare
Source](https://gitlab.com/gitlab-org/api/client-go/compare/v2.33.0...v2.34.0)

#### 2.34.0

##### 🚀 Features

- Extend DeploymentDeployablePipeline with web_url
([!2902](https://gitlab.com/gitlab-org/api/client-go/-/merge_requests/2902))
by [Jan Berge Sommerdahl](https://gitlab.com/sommerdahl)

##### 🔄 Other Changes

- chore(deps): update docker docker tag to v29.5.1
([!2903](https://gitlab.com/gitlab-org/api/client-go/-/merge_requests/2903))
by [GitLab Dependency
Bot](https://gitlab.com/gitlab-dependency-update-bot)

###
[2.34.0](https://gitlab.com/gitlab-org/api/client-go/compare/v2.33.0...v2.34.0)
(2026-05-27)

###
[`v2.33.0`](https://gitlab.com/gitlab-org/api/client-go/tags/v2.33.0)

[Compare
Source](https://gitlab.com/gitlab-org/api/client-go/compare/v2.32.0...v2.33.0)

#### 2.33.0

##### 🚀 Features

- feat(work-items): add ListWorkItemTypes to WorkItemsService
([!2864](https://gitlab.com/gitlab-org/api/client-go/-/merge_requests/2864))
by [Emmanuel 326](https://gitlab.com/Emmanuel326)

##### 🔄 Other Changes

- chore(deps): update module cel.dev/expr to v0.25.2
([!2881](https://gitlab.com/gitlab-org/api/client-go/-/merge_requests/2881))
by [GitLab Dependency
Bot](https://gitlab.com/gitlab-dependency-update-bot)

###
[2.33.0](https://gitlab.com/gitlab-org/api/client-go/compare/v2.32.0...v2.33.0)
(2026-05-27)
##### Features

* **work-items:** add ListWorkItemTypes to WorkItemsService
([e71cb99](https://gitlab.com/gitlab-org/api/client-go/commit/e71cb994482aa882eb8eb9fc4140ca1e4aac25ab))

###
[`v2.32.0`](https://gitlab.com/gitlab-org/api/client-go/tags/v2.32.0)

[Compare
Source](https://gitlab.com/gitlab-org/api/client-go/compare/v2.31.0...v2.32.0)

#### 2.32.0

##### 🚀 Features

- feat(ci-job-cancel): force cancel
([!2872](https://gitlab.com/gitlab-org/api/client-go/-/merge_requests/2872))
by [Filip Aleksic](https://gitlab.com/faleksic)

###
[2.32.0](https://gitlab.com/gitlab-org/api/client-go/compare/v2.31.0...v2.32.0)
(2026-05-23)
##### Features

* **ci-job-cancel:** force cancel
([aa46bd1](https://gitlab.com/gitlab-org/api/client-go/commit/aa46bd18428834eebdb42622f2523c64686021e8))

###
[`v2.31.0`](https://gitlab.com/gitlab-org/api/client-go/tags/v2.31.0)

[Compare
Source](https://gitlab.com/gitlab-org/api/client-go/compare/v2.30.0...v2.31.0)

#### 2.31.0

##### 🚀 Features

- Adds project service accounts API
([!2899](https://gitlab.com/gitlab-org/api/client-go/-/merge_requests/2899))
by [Jimmy Spagnola](https://gitlab.com/jspagnola)
- feat(gitlaboauth2): support ephemeral ports in CallbackServer
([!2877](https://gitlab.com/gitlab-org/api/client-go/-/merge_requests/2877))
by [Raphael Rösch](https://gitlab.com/raphael.roesch)

###
[2.31.0](https://gitlab.com/gitlab-org/api/client-go/compare/v2.30.0...v2.31.0)
(2026-05-22)
##### Features

* **gitlaboauth2:** support ephemeral ports in CallbackServer
([c8c388d](https://gitlab.com/gitlab-org/api/client-go/commit/c8c388d56663a8f2e27b4c74f1323d3671a6bbaf))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Only on Monday (`* * * * 1`)
- Automerge
  - At any time (no schedule defined)

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

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

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

---

This PR has been generated by [Mend
Renovate](https://redirect.github.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNDEuNSIsInVwZGF0ZWRJblZlciI6IjQzLjE0MS41IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-06-09 10:41:54 +00:00
Lunny Xiao 49a0d19fa3 feat(api): Add assignees APIs (#37330)
Follow
https://docs.github.com/en/enterprise-server@3.20/rest/issues/assignees?apiVersion=2022-11-28

Fix #33576 

And it also fixed some possible dead-lock problem.

---------

Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
2026-06-09 06:12:09 +00:00