Commit Graph

5320 Commits

Author SHA1 Message Date
Shudhanshu Singh
d47f9f37d6 refactor(git): clarify GetBranch behavior to make it only gets an existing branch (#38662)
`GetBranch` silently returned soft-deleted branches, contradicting
`IsBranchExist` and forcing callers to manually check `branch.IsDeleted`
everywhere.

Refactored it to `GetBranchExisting` to have a clear behavior: it only
returns the existing branch.

---------

Signed-off-by: Sudhanshu Singh <sudhanshuwriterblc@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-27 17:45:27 +00:00
Giteabot
94a2c3ec18 chore(deps): update dependencies (#38660)
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: silverwind <me@silverwind.io>
2026-07-27 16:55:27 +00:00
Harsh Satyajit Thakur
e67dd4c818 fix: skip OIDC end-session after password login for OAuth2 users (#38439)
Fixes #38209

OAuth2-linked accounts that sign in via the password form were still
redirected to the provider end_session_endpoint on logout because the
redirect was keyed off account LoginType.

Store the session sign-in method (password vs oauth2) and only use
RP-initiated OIDC logout when this session was authenticated via OAuth2.
Sessions without the new key keep the previous LoginType behavior.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-27 15:35:48 +00:00
mohammad rahimi
13d0f24423 feat: Replace SSE with WebSocket for UI notifications (#36965)
* Closes #36942
* Fixes #19265 

Replaces the SSE-based push channel (`/user/events`) with a WebSocket
endpoint (`/-/ws`).

### What changes

- **New `/-/ws` endpoint** (authenticated). One WebSocket per origin,
shared across tabs via a single `SharedWorker`.
- **Pubsub broker** (`services/pubsub`) for fan-out by topic, behind a
`Broker` interface. `MemoryBroker` is the default (single process); a
Redis backend is available for multi-process setups, configured via
`[websocket].PUBSUB_TYPE` / `PUBSUB_CONN_STR`. The internal Gitea queue
was not usable here because it has FIFO/single-consumer semantics.
- **Push-only event production.** Events are emitted by write-triggered
notifiers — `NotificationCountChange`, `PublishStopwatchesForUser`, and
the logout publisher — wired into the existing `notify.Notifier`
interface. No server-side pollers.
- **Typed pub/sub on the client.** `web_src/js/modules/worker.ts` is a
singleton transport; features subscribe per event type via
`onUserEvent('notification-count', cb)` instead of branching on
`event.data.type`.
- **Wire contract** (`UserEventType` union) is shared between the worker
and consumers via `web_src/js/types.ts`, kept in sync with
`services/websocket/events.go`.
- **Client-side periodic polling fallback** kicks in only when the
WebSocket cannot be established (e.g. proxy blocks WS, browser lacks
module-SharedWorker support).

### What's removed

- `modules/eventsource` (SSE manager, run loop, messenger).
- `/user/events` route and `tests/integration/eventsource_test.go`.
- All server-side polling for stopwatches and notification counts.

### Stopwatch multi-tab fix

The navbar stopwatch icon was previously rendered conditionally on `{{if
$activeStopwatch}}`, so tabs loaded before the timer started had no DOM
element to update. The icon and popup are now always rendered (toggled
with `tw-hidden`), and the start/stop/cancel handlers POST silently so
all open tabs reflect the change in real time.

### Deployment note

WebSocket needs the upgrade headers to pass through a reverse proxy,
e.g. for nginx:

```nginx
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
```

Without them the WebSocket cannot be established, and after 3
consecutive failed opens the shared worker signals `push-unavailable`:
the notification count and stopwatch fall back to periodic polling on
the existing `[ui.notification]` timeouts. Real-time push is lost, the
features keep working. The reverse-proxy docs need the same note (see
the `docs-update-needed` label).

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Epid <rexmrj@gmail.com>
2026-07-27 07:46:00 +00:00
wxiaoguang
a3caf21440 feat: admin impersonates a user (#38614)
* fix #3631
* fix #21599

by the way, refactored the "profile avatar card" to simplify the code.
2026-07-26 17:26:02 +00:00
wxiaoguang
470d34b1de refactor: git patch apply (#38637)
Merge duplicate code and add a unit test

There are already integration test cases in `TestEditor` ->
`WebGitCommitEmail` for these two endpoints.
2026-07-26 16:57:00 +00:00
wxiaoguang
3e6cb7c16b fix: orgmode render include path (#38642)
Co-authored-by: TheFox0x7 <thefox0x7@gmail.com>
2026-07-26 14:22:49 +00:00
silverwind
13406e7aa7 chore: update and relax revive naming rules (#38615)
- enable `skip-initialism-name-checks`, so names like `sessionUid` are
allowed
- replace removed `skip-package-name-checks` option with new
`package-naming` with fitting rules for gitea
- drop dead exclusion paths
2026-07-24 21:47:23 +00:00
mohammad rahimi
1e42317b66 feat(setting): add shared [redis] section as default for redis-backed subsystems (#38550)
Adds a shared `[redis]` config section with a single `CONN_STR` key that
acts as the default Redis connection for every redis-backed subsystem
whose own connection string is empty: `[cache].HOST`,
`[session].PROVIDER_CONFIG`, `[queue].CONN_STR` and
`[global_lock].SERVICE_CONN_STR`.

Precedence: per-subsystem value > shared `[redis].CONN_STR` > existing
built-in defaults. Fully backward compatible: when `[redis]` is not set,
every code path behaves exactly as before.

Motivation: today an admin with one Redis instance has to repeat the
same connection string in up to four places (five once WebSocket lands).
Requested by @wxiaoguang in [this review
discussion](https://github.com/go-gitea/gitea/pull/36965#discussion_r3613306976)
as a prerequisite for #36965. This follows the pattern used by GitLab
and Mastodon: one global Redis definition, per-subsystem overrides fall
back to it.

Since #12385 all identical connection strings already share one client
via `nosql.Manager`, so pointing all subsystems at `[redis].CONN_STR`
naturally converges onto a single shared connection pool.

Covered by table-driven unit tests per subsystem (fallback applies, own
value wins, absent `[redis]` = unchanged behavior). A config-cheat-sheet
update for gitea/docs will follow once this is merged.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: TheFox0x7 <thefox0x7@gmail.com>
2026-07-24 08:11:20 +00:00
silverwind
99ca4bff7d fix: make auth source group sync correctly handle team removal (#37161)
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-24 02:05:38 +00:00
wxiaoguang
7065637e61 refactor: hide git repo path details from more packages (#38601)
Remove `RepoPath` from "models/repo" package, remove `UserPath` from
"models/user" package, use `WithRepo` for more places, fine tune tests.
2026-07-23 17:42:55 +00:00
wxiaoguang
e992b0a7cc refactor: retry file remove/rename when a file is busy and clean up os detection (#38588)
Rename functions "util.Remove" (remove.go) to "util.RemoveWithRetry"
(file_retry.go) and add comments to clarify their behaviors, also add
tests.

Refactor callers: when no concurrent access (cmd cli, migration, app
init, test), use "os.Xxx" directly.

More details are in `modules/util/file_retry.go`

By the way, clean up OS (windows) detection, make FileURLToPath test
always run
2026-07-23 14:31:29 +00:00
Mohamed Belkamel
c4fc4d363b fix(actions): make SingleWorkflow.Marshal round-trip multi-line run blocks (stop silent job stranding) (#38520)
## Problem
Jobs that call a reusable workflow (`uses:`) whose steps contain a `run:
|` block that **starts with blank lines** never start — the child jobs
stay `Blocked` forever, the run never finishes, and nothing is shown to
the user (the error is only logged at DEBUG). The reusable is valid YAML
and worked on 1.26.

## Root cause
`jobparser` serializes each expanded job via `SingleWorkflow.SetJob()`,
which uses `yaml.NewEncoder(...).SetIndent(2)`, but
`SingleWorkflow.Marshal()` used `yaml.Marshal`, whose default
indentation is **4**. Re-emitting a multi-line literal block scalar at a
different indentation makes the encoder write a wrong explicit
indentation indicator (`run: |4`) whose declared indent doesn't match
the actual content indent. The stored `workflow_payload` is then
unparseable:

```
run: |4


                while ...
```

`jobparser.Parse` / `model.ReadWorkflow` (both go.yaml.in/yaml/v4)
reject it: `did not find expected key`. This surfaces in
`services/actions/job_emitter.go` `resolve()` →
`updateConcurrencyEvaluationForJobWithNeeds` → `ParseJob`, where the
error is swallowed at `log.Debug` and the job is left `Blocked`.

Encoding at indent 4 triggers the bad indicator; indent 2 does not —
matching the value already used by `SetJob`.

## Fix
Encode `SingleWorkflow.Marshal()` with `SetIndent(2)` so both encoders
agree and the serialized single workflow round-trips. Adds a regression
test (`Parse → Marshal → Parse` on a `run:` block with leading blank
lines) that fails before the change with `did not find expected key`.

---------

Signed-off-by: quasimodo <mohamed.belkamel@intelcia.com>
Co-authored-by: quasimodo <mohamed.belkamel@intelcia.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
2026-07-23 15:42:21 +02:00
Shudhanshu Singh
ee10ae168c perf(emoji): optimize FindEmojiSubmatchIndex using slice-based Trie (#38573)
This pull request optimizes `FindEmojiSubmatchIndex` in Gitea's emoji
package (`modules/emoji/emoji.go`) by replacing the
`strings.Replacer`-based search with a slice-based trie and a
constant-time starting-byte check (`isStartingByte`).

The new implementation avoids heap allocations during the search and
reduces CPU overhead when rendering Markdown, particularly for plain
text that does not contain emojis.

### Verification

Verified with unit tests:

```sh
go test -count=1 ./modules/emoji/...
```

Benchmarks:

```sh
go test -bench=. -benchmem ./modules/emoji/...
```

### Results

| Benchmark | Before | After |
| ---------- | ------ | ----- |
| `BenchmarkFindEmojiSubmatchIndex` | 168.3 ns/op, 2 allocs/op | 85.78
ns/op, 1 alloc/op |
| `BenchmarkFindEmojiSubmatchIndexNoMatch` | 239.8 ns/op, 1 alloc/op |
105.1 ns/op, 0 allocs/op |
### Benchmark Output

```text
goos: linux
goarch: amd64
pkg: gitea.dev/modules/emoji
cpu: Intel(R) Core(TM) i5-7400 CPU @ 3.00GHz

BenchmarkFindEmojiSubmatchIndex-4              13498539        85.78 ns/op      16 B/op   1 allocs/op
BenchmarkFindEmojiSubmatchIndexNoMatch-4       11220450       105.1 ns/op        0 B/op   0 allocs/op
BenchmarkFindEmojiSubmatchIndexOld-4            6569360       168.3 ns/op      48 B/op   2 allocs/op
BenchmarkFindEmojiSubmatchIndexOldNoMatch-4     5026116       239.8 ns/op      32 B/op   1 allocs/op
```

---------

Signed-off-by: Sudhanshu Singh <sudhanshuwriterblc@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-23 08:29:28 +00:00
Shudhanshu Singh
560edd45e9 fix(api): align Swagger schemas for UserSettings and TopicListResponse (#38590)
Corrects the Swagger/OpenAPI schemas for `/user/settings` and
`/topics/search` to match the actual JSON objects returned by the API.

Signed-off-by: Sudhanshu Singh <sudhanshuwriterblc@gmail.com>
2026-07-23 14:49:52 +08:00
wxiaoguang
1acf93d854 refactor: clean up git repo and model migration packages (#38564)
enable the golangci depguard lint rule: deny "models" and its sub
packages in "modelmigration" package.
2026-07-23 01:22:26 +00:00
Paarth
fa3780268c feat(repo): support file exclusion logic in .gitea/template in template generation (#38064)
This PR adds support for file exclusion into `.gitea/template`

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

### Usage

Template owners add a `.gitea/template` file to their template
repository:

```
# Files to include for variable expansion
*.go
text/*.txt
**/modules/*

# Files/directories to exclude from the generated repo
[exclude]
vendor/*
node_modules/
src/build/
```

Resolves #37202

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-22 20:14:18 +00:00
Elisei Roca
c8df67c0d0 fix(pulls): respect diff.orderFile in diff file tree (#38566)
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-22 15:56:29 +00:00
wxiaoguang
4af9156c36 refactor: implement mcaptcha client and add comments/tests (#38561)
End users still need it, so it's better to make it maintainable with
tests and OOM-safe.

---------

Co-authored-by: silverwind <me@silverwind.io>
2026-07-21 13:41:54 +00:00
wxiaoguang
91eb14c944 refactor: use WithRepo instead of WithDir for most git operations, clean up model migrations (#38555)
by the way, remove some unnecessary "models" imports from model
migration package, fix migration test model init bug
(modelmigration/migrationtest/tests.go)
2026-07-21 12:18:00 +00:00
Zettat123
7cfd421aa8 fix(actions): support matrix when evaluating workflow if expression (#38474)
Partially fixes #38466

Added `matrix` to the evaluator for `if` expressions

---------

Signed-off-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: bircni <bircni@icloud.com>
2026-07-21 06:43:45 +00:00
Shudhanshu Singh
c0f4e5583e feat(repo): prioritize well-known READMEs and optimize discovery (#38532)
This PR adjusts the repository README discovery logic to mirror GitHub's
priority order, while retaining support for Gitea's specific `.gitea/`
directory.

Previously, Gitea would prioritize a `README.md` at the root of the
repository over any READMEs in `.gitea/` or `.github/`. With this
change, well-known subdirectories are evaluated first when viewing the
repository root.

**New Priority Order:**
1. `.gitea/README.md`
2. `.github/README.md`
3. `/README.md` (root directory)
4. `docs/README.md`

This allows repository maintainers to use `.github/README.md` (or
`.gitea/README.md`) as the repository homepage without having to remove
or rename generic root `/README.md` files required by package managers
(like NPM, Crates.io, Docker, etc.).

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-21 11:44:25 +08:00
wxiaoguang
a4526d5a82 refactor: remove Path field from git.Repository (#38552)
The "path" details should be hidden to other packages

By the way, fix a resource leaking in gogit's CommitNodeIndex
(the file was not closed in CacheCommit)
2026-07-20 18:03:28 +00:00
wxiaoguang
9dc04289aa refactor: make git package handle all git operations (#38543)
before: gitrepo vs git packages
after: git package fully handle all git operations

by the way, use `WithRepo(repo)` instead of `WithDir(repo.Path)` to hide
path details.

benefits:

1. remove all unnecessary wrappers, developers no need to struggle with
"which package should be used"
2. simplify code, RepositoryFacade can (will) be used everywhere, all
"path" details are (will be) hidden
2026-07-20 16:07:38 +00:00
wxiaoguang
6525e6df15 fix: revert git clone http redirection forbidden (#38530)
Revert to 1.26 behavior.

Incomplete, HandleGitCmdHTTPRedirection can be improved
2026-07-20 10:04:23 +00:00
wxiaoguang
775e3bdb34 refactor: remove unnecessary git command wrapper functions (#38531)
Removed `gitrepo.RunCmd*` functions, because gitcmd.Command works with
Repository directly.

Move some "local filesystem" related function into "localfs.go"
2026-07-20 03:17:25 +00:00
wxiaoguang
b06002f449 refactor: git repo and relative path handling (#38522)
1. simplify "StorageRepo" code
2. simplify git.OpenRepository code
3. by the way, clean up some unused files in git test fixtures.
2026-07-19 07:32:00 +00:00
YumeMichi
ae176cd649 refactor: clean up fragile diff render templates, use backend typed structs (#38517)
Blob.Size requires a context after the repository context removal
(5b078f72aa).

Actually the template code should just render, it should not depend on
the fragile dynamic calls to backend functions.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-19 11:20:01 +08:00
wxiaoguang
66e3849a70 refactor: correct git repo design and fix some legacy problems (#38512) 2026-07-18 15:28:14 +02:00
wxiaoguang
3027794c44 refactor: fix legacy problems in cmd/serv.go (#38505)
1. use var names "reqOwnerName, reqRepoName", because these values are
from request and should not be really used for path construction
2. simplify enable-pprof logic, don't "log.Fatal"
3. don't make runServe command to guess the repo storage path, instead,
let server return RepoStoragePath
4. don't process lfs verbs when the repo is a wiki
5. construct the request URI path correctly for the lfs transfer backend
(moved to the caller)
6. don't call "owner, err := user_model.GetUserByName", the "owner
rename redirection" has been done before
7. fix incorrect "repo.OwnerName = ownerName", the real owner might have
been "redirected"
8. fix incorrect "inactive owner" check, it should be checked even if
the repo is redirected


Use general error functions to handle responses, error handling code is
hugely simplified.
2026-07-17 22:28:59 +08:00
wxiaoguang
5b078f72aa refactor: remove Ctx field from git.Repository (#38500) 2026-07-17 18:44:31 +08:00
wxiaoguang
2c8e99bbf7 fix: make commit message merge correctly (#38490)
fix #38487

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: bircni <bircni@icloud.com>
2026-07-17 07:44:05 +00:00
Zettat123
2e0aa7ec74 fix(actions): make cancelled() work in job if evaluation (#38495)
Fix #38485

#37478 moved `if` evaluation from runner to server. But `NewInterpeter`
always provides a nil `JobContext` for the evaluator, which makes
[`cancelled()`](ad967330a8/act/exprparser/functions.go (L299))
panic on `Job.Status` because `Job` is a nil pointer.
2026-07-16 22:28:53 +02:00
silverwind
f0d9af3a18 enhance(ui): use OpenAPI 3.0 spec in API viewer, add spec buttons (#38478)
Follow-ups from https://github.com/go-gitea/gitea/pull/37038:

- Render the OpenAPI 3.0 spec in the API viewer, it is richer than the
Swagger 2.0 rendering
- Replace the back link with gitea-styled buttons to view both specs and
return to Gitea, flowing above swagger-ui on viewports where they would
overlap the title
- Key `VisibilityModes` by the string enum type, now named
`VisibilityString`, removing the `string()` casts at API call sites
- Drop the raw visibility strings from the `Service` settings struct in
favor of the typed mode fields, which also removes the org default
visibility row from the admin config page
- Fix two pre-existing issues surfaced in review: an invalid
`DEFAULT_USER_VISIBILITY` was silently accepted as public, and the org
visibility error message showed the enum zero value instead of the
submitted input

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-16 17:38:33 +00:00
wxiaoguang
82edc3da01 refactor: decouple git.Repository(ctx) from git.Commit & git.Tree (#38464)
1. Storing "ctx" in a long-living object is wrong
2. Make the commit & tree cacheable (for the future performance
optimization)
3. Also fix some bad designs like `// FIXME: bad design, this field can
be nil if the commit is from "last commit cache"`

ref:
* #33893
2026-07-15 17:30:01 +00:00
bircni
f69e15afe7 fix: various security fixes (#38406)
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: 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:14:09 +00:00
TowyTowy
d2bd1589fe fix(util): reject invalid characters between time-estimate units (#38416)
### What / why

`TimeEstimateParse` (used by the issue time-estimate form) only checked
that the first token starts at the beginning of the string and the last
token ends at its end, but never checked the gaps between consecutive
tokens. Non-whitespace garbage embedded between two valid units was
silently dropped and the string accepted with a wrong value instead of
being reported as invalid.

Examples that were wrongly accepted before this change:

- `1h 2x 3m` → 3780s (parsed as 1h3m)
- `1h_2m`    → 3720s
- `1h,1m`    → 3660s

All three now return an "invalid time string" error, while valid inputs
such as `1h 1m 1s` and `1h1m1s` keep working.

### How

Reject any non-whitespace content between two matched units.

---------

Signed-off-by: TowyTowy <towy@airreps.link>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-12 13:38:34 +00:00
Lovepreet Singh
65c5a5ff7b fix(turnstile): route CAPTCHA verification through the configured proxy (#38412)
Fixes #38217

## Problem

Turnstile CAPTCHA verification uses `http.DefaultClient`, so the request
to `challenges.cloudflare.com` bypasses Gitea's configured HTTP proxy —
unlike other outbound HTTP clients such as the update checker
(`modules/updatechecker/update_checker.go`) and migrations. In
deployments where egress is only permitted through the configured proxy,
verification fails.

## Fix

Build the client with `proxy.Proxy()` as the transport proxy, mirroring
the update checker:

```go
func httpClient() *http.Client {
	return &http.Client{
		Transport: &http.Transport{
			Proxy: proxy.Proxy(),
		},
	}
}
```

The client is built per call (rather than a package-level var) because
`proxy.Proxy()` reads `setting.Proxy` when invoked; building it at
request time ensures it reflects the loaded settings. When no proxy is
configured, behavior is unchanged (`proxy.Proxy()` returns a no-op /
`http.ProxyFromEnvironment`).

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-12 11:33:14 +00:00
bircni
f452c369ac fix: enforce public-only token scope and harden push options / locale parsing (#38323)
- **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.
2026-07-10 16:39:01 +00:00
wxiaoguang
c5c991b1a4 fix: co-author detection (#38392)
Committer can also be co-author, it should only not be included in the
co-author list if it is not in the "Co-author-by" list.

* Author & Co-author: they changed the code (attribution)
* Committer: they submitted the commit but didn't change the code (e.g.:
maintainer signed a commit)

Fix #38384
2026-07-10 12:52:00 +02:00
bircni
27e33b7ba1 fix: incorrect co-author detection on commit page (#38386)
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
2026-07-09 22:31:14 +02:00
Zettat123
761470c01d enhance(actions): only create filtered-out workflow commit status for required contexts (#38371)
Follow #38237

#38237 posts "skipped" commit statuses for every workflow that is not
triggered due to a filter (e.g. `paths` or `branches`) mismatch.
However, for non-required workflows, creating "skipped" commit statuses
for them would generate a lot of noise.

To address this issue, this PR adds a check before creating commit
status:

- For the context that matches any required status check patterns, a
"skipped" commit status will be created. The `Required` label can inform
users that this status check is required, but has been skipped because
of a filter mismatch.
- For a non-required context, nothing will be created.

NOTE: Reducing noise is a best-effort approach and isn't entirely
accurate. When creating commit statuses, it is impossible to predict
which branch protection rule will take effect. Therefore, we have to
compare the commit status context against the required patterns from all
rules. If any rule matches, the context is considered "required".
2026-07-09 15:34:56 +00:00
Milwad Khosravi
545ed92354 chore(typo): fix grammar in comments, API docs and error messages (#38370) 2026-07-08 23:52:06 +02:00
wxiaoguang
49ef93940a fix: golang html template url escaping (#38363)
fix #38362
2026-07-08 00:16:32 +00:00
bircni
308a6f12ae perf(actions): debounce runner heartbeat writes and throttle task picks (#38281)
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: Zettat123 <zettat123@gmail.com>
2026-07-07 19:16:20 +00:00
wxiaoguang
a74f618ade fix: minio init check (#38355)
Fix the buggy behavior introduced by "S3: log human readable error on connection failure (#26856)"
2026-07-07 07:32:25 +00:00
Copilot
2b89e2ac97 fix(pulls): add branch-name option for DEFAULT_TITLE_SOURCE (#38356)
Adds a new `branch-name` value for the `[repository.pull-request]`
`DEFAULT_TITLE_SOURCE` setting that always uses the normalized branch
name as the PR title, regardless of commit count.

Fix #38317

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-07 07:08:05 +00:00
Zettat123
2c2691b969 test: compare key file contents instead of FileInfo in TestInitKeys (#38330)
`TestInitKeys` verified whether a host key file was regenerated by
comparing `os.FileInfo` before and after a `InitDefaultHostKeys` call.
On systems where the OS clock / filesystem timestamp granularity is
coarse, both writes land in the same tick and get an identical mtime.
The resulting `FileInfo` is then byte-for-byte equal even though the key
was actually regenerated, so `assert.NotEqual` fails.

Since a regenerated key always produces different random bytes,
comparing the content can reliably detect regeneration.
2026-07-04 22:30:12 +02:00
silverwind
638e4bce09 chore: upgrade go-swagger to v0.35.0 and enforce zero swagger warnings (#38299)
Updates `go-swagger` to v0.35.0 and makes swagger generation and
validation warning-free, with the build now failing on any warning
(`go-swagger` itself exits `0` on warnings).

- Generation passes `--enable-allof-compounding` (keeps `$ref` fields
bare, no spec change) and `--skip-enum-desc` (drops the enum description
that duplicates `x-go-enum-desc` and was the only source of `allOf`
noise in the OpenAPI 3.0 output).
- Fixed warnings at the source: dropped `swagger:strfmt` where it
conflicts with `required: true` (`required` kept, `time.Time` still maps
to `date-time`), fixed a malformed `units_map` example, moved the
`parameterBodies` injection hack to `swagger:parameters`, and removed
unused responses.

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

---------

Co-authored-by: bircni <bircni@icloud.com>
2026-07-01 21:07:34 +00:00
puni9869
a031454586 fix: Improve since/until when counting commits for X-Total-Count (#38243)
Follow up for https://github.com/go-gitea/gitea/pull/38204.

---------

Signed-off-by: puni9869 <80308335+puni9869@users.noreply.github.com>
2026-07-01 20:43:46 +00:00