100 Commits
Author SHA1 Message Date
Lunny Xiaoandsilverwind e867cfbf0d fix(repo): rank exact repository name matches first (#39038)
The quick repository switcher orders results alphabetically, so a
repository whose name exactly matches the query can appear below names
that merely contain it.

- Rank exact repository name matches first when no explicit sort order
is requested
- For "owner/repo" queries, rank the exact pair first, then the owner's
other repositories
- Match the owner of "owner/repo" queries case-insensitively, mixed-case
owners were missed

---------

Co-authored-by: silverwind <me@silverwind.io>
2026-11-11 19:01:43 +00:00
Lunny Xiaoandsilverwind 3561478109 fix(projects): move only the dragged card on project boards (#40182)
The board reported every card of the target column on each drag, and the
server wrote all of them into that column. A stale board in another
browser therefore pulled cards moved by someone else back to their old
column.

The client now sends only the dragged issue and its predecessor, and the
server computes the position in one transaction:

- Only the dragged issue changes column, the others are just renumbered.
- A predecessor that is no longer in the column puts the card at the
end.

Added an e2e test.

Fixes https://github.com/go-gitea/gitea/issues/21243
Fixes https://github.com/go-gitea/gitea/issues/32070
Fixes https://github.com/go-gitea/gitea/issues/13498

---
Assisted-by: Codet:claude

---------

Co-authored-by: silverwind <me@silverwind.io>
2026-11-09 21:39:22 +00:00
Lunny Xiao bccc90d654 fix(api): lock and unlock issues as the signed-in user, not the repository owner (#40291)
`PUT/DELETE /repos/{owner}/{repo}/issues/{index}/lock` passed
`ctx.ContextUser` as the doer of `LockIssue` / `UnlockIssue`. In the
repo routes that is the owner of the repository, so on a repository of
an organization the lock and unlock timeline comments were created by
the organization instead of the user who did it. The web handler already
uses the signed-in user; this uses `ctx.Doer` as well.

Adds a subtest `DoerOnOrganizationRepo` to the existing
`TestAPILockIssue`: a member of an organization locks and unlocks an
issue of an organization repository, and the comments must be posted by
that member.

Found while testing audit logging of the issue lock events downstream.

_Authored by Codet (Claude)._
2026-11-09 18:00:06 +00:00
Lunny Xiaoandsilverwind 1554b6c939 feat!: remove repository adopt feature (#40181)
Remove the "adopt unadopted repositories" feature. Adopting assumes a
fixed repository storage path on disk, which makes the storage path hard
to change. It is mostly used once for migrations, and the [Gitea
importer](https://gitea.com/gitea/importer) covers that after the
repositories are moved out of the repository root. The docs are updated
in https://gitea.com/gitea/docs/pulls/639.

- Remove the admin and user adopt pages, the `/admin/unadopted` API
endpoints and the adopt notifier hook
- Remove the `ALLOW_ADOPTION_OF_UNADOPTED_REPOSITORIES` and
`ALLOW_DELETION_OF_UNADOPTED_REPOSITORIES` settings
- The user "Repositories" settings page only lists the user's
repositories
- Repository files without a database record must now be removed from
disk by the administrator

Assisted-by: Codet:claude

---------

Co-authored-by: silverwind <me@silverwind.io>
2026-11-08 18:38:23 +00:00
Lunny Xiaoandsilverwind 565f1b7d52 fix(migrations): Do not fail Bitbucket Server migration when pull request activities cannot be loaded (#40205)
Bitbucket Server can answer 500 for `/pull-requests/{id}/activities` of
some pull requests. That error aborted the whole repository migration:

`bitbucket server API .../pull-requests/128/activities returned status
500`

Now a 500 is logged as a warning and that pull request's comments,
reviews and merge commit are skipped, cached so the endpoint is not hit
again. Other errors are still returned, so the migration retries them as
before.

---------

Co-authored-by: silverwind <me@silverwind.io>
2026-11-05 07:28:12 +00:00
Lunny Xiaoandsilverwind fca64e7330 perf: reuse request-scoped git repo in pull request conversion (#40208)
Reuse the request-scoped base git repository in `ToAPIPullRequest`,
`ToPayloadPullRequest` and `ToAPIPullRequests` instead of reopening it
for each conversion, so conversions share the request's `cat-file`
process.

- Same-repo PRs reuse the base repository for the head instead of
opening it a second time.
- Drop a redundant second open of the base repository.
- Fork head repositories stay opened per call. A request-cached fork
keeps its `cat-file` running until the request ends, which blocks
deleting the fork on Windows and keeps one process per fork alive in
batch status changes.

---------

Co-authored-by: silverwind <me@silverwind.io>
2026-11-04 17:24:49 +00:00
Lunny Xiaoandsilverwind 40507491f7 perf(pull): load the repository once for all commit statuses (#39930)
Pages showing commit statuses loaded the repository of every status
separately, so a PR with ~75 statuses ran ~75 identical repository
queries per merge box render (about 3.4s in a production trace).
`statusRepoCanReadActions` only loaded the repository inside the
permission cache loader, which never runs once `RepoAssignment` has
published the permission.

- `CommitStatus.loadRepository` resolves through the request context
cache
- `statusRepoCanReadActions` loads the repository before the permission
lookup
- `RepoAssignment` publishes its repository to the context cache next to
the permission
- `GetCommitActionsStatusMap` drops its own repository map

Queries per request with 50 statuses (45 Actions, 5 external) on the
head commit, SQLite:

| Page | Repository queries | Total queries |
|---|---|---|
| PR view | 61 → 11 | 157 → 107 |
| Commit | 6 → 5 | 24 → 23 |
| Branches | 6 → 5 | 33 → 32 |
| Commits | 6 → 5 | 23 → 22 |
| Repo home | 8 → 7 | 35 → 34 |
| `/pulls` | 15 → 15 | 37 → 37 |

---------

Co-authored-by: silverwind <me@silverwind.io>
2026-10-31 17:32:03 +01:00
Lunny Xiaoandsilverwind bd5fbcfb29 feat(migrations): add repository migration from bitbucket.org (#38607)
Adds migration from bitbucket.org as the Cloud variant of the Bitbucket
entry, in the web UI and via `POST /repos/migrate` with
`service=bitbucket`. It migrates the repository and pull requests with
their comments and reviews. Bitbucket Cloud has no releases, and
Atlassian removed its issues and wikis on 2026-08-20
(https://community.atlassian.com/forums/Bitbucket-articles/Announcing-sunset-of-Bitbucket-Issues-and-Wikis/ba-p/3193882).

- Private repositories need an API or access token, which also raises
the rate limit.
- Rate-limited requests back off and retry, Bitbucket sends no
`Retry-After`.
- Tests replay recorded responses, set `BITBUCKET_READ_TOKEN` to
re-record.

Co-authored-by: silverwind <me@silverwind.io>
2026-10-31 14:51:43 +00:00
Lunny Xiaoandwxiaoguang 7361ade2e5 fix(user): answer the follow of a bot user with the profile card (#39980)
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-30 06:35:11 +08:00
b0b31bc593 feat(packages): expose package file properties in the package files API (#40066)
Package files carry type specific properties like `debian.distribution`,
`debian.component`, `rpm.group` or `alpine.branch` that decide where a
file lives in a registry, but the API never returned them. A client
listing `GET /packages/{owner}/{type}/{name}/{version}/files` could not
tell which distribution or component a file belongs to, or tell apart
same-named files in different ones. Tools copying packages between
instances, like https://gitea.com/gitea/importer, need them to re-upload
a file to the same place.

This adds a `properties` map to `PackageFile`, limited to the properties
that locate a file. Internal ones like the rpm, alpine, arch and conda
metadata or the Debian control file stay hidden, as they can be many MiB
per file.

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-29 18:10:36 +00:00
e221551c7b fix: Fix OneDev migration with OneDev 16.8 and newer (#40017)
OneDev 16.8 moved the server version endpoint from
`/~api/version/server` to `/~api/server/version`. Both are tried, the
new one first, and both errors are reported when neither works.

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-10-26 09:48:18 +00:00
Lunny Xiaoandwxiaoguang f10f7e7f91 fix(migrations): only allow local paths for plain git migration (#40006)
Only the plain git migration can clone from a local server path. Other
services (Gitea, GitLab, Gogs, OneDev, GitBucket, Codebase, CodeCommit,
Bitbucket Server) are accessed through their remote API, so a local path
never works, yet their migrate forms advertised "or a local server
path".

- Remove the local path hint from those templates.
- Add `IsMigrateURLAllowedForService` and use it in the web and API
migrate handlers and in `MigrateRepository`, rejecting local paths for
any service other than plain git.
- Add a unit test.

Raised in review of #39913.

_Authored with Codet (AI assistant) on behalf of @lunny._

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-25 21:21:19 +00:00
Lunny Xiaoandbircni a2da5cd7b5 feat(migrations): add migration from Bitbucket Server (Data Center) (#39913)
Add migration from Bitbucket Server (Data Center). It has no issues,
wiki, milestones or releases, so those are not offered.

Migrated: git data with tags and LFS, and pull requests with state,
draft flag, merge commit/base, comments, approvals and inline code
comments including resolved threads. Multi-line ranges become a `Lines
a-b:` text prefix, as Gitea anchors code comments to one line. Auth is
an HTTP access token (personal, project or repository) or
username/password; 429 responses are retried.

Changes outside the downloader:
- `ReviewComment.Resolved`, applied by the uploader.
- The uploader creates a fork PR's head branch from its head commit when
already in the repository, instead of fetching the fork (Bitbucket keeps
it in `refs/pull-requests/<id>/from`; private forks need credentials).

Tested with unit tests, responses recorded from Bitbucket 10.5.1, and an
end-to-end migration. Independent of
https://github.com/go-gitea/gitea/pull/38607 (Bitbucket Cloud); the
service type enum value needs adjusting for whichever lands second.

---------

Co-authored-by: bircni <bircni@icloud.com>
2026-10-23 19:25:29 +00:00
Lunny Xiaoandsilverwind 5129ad5439 perf(actions): cache successful runner token verification (#39934)
Every Actions runner RPC (`FetchTask` polling, `UpdateTask`,
`UpdateLog`, ...) goes through the `withRunner` interceptor, which
verifies the runner token with PBKDF2 (`auth_model.HashToken`, ~2 ms).
In a 60s CPU profile of a production instance with many runners, this
accounted for ~49% of all CPU samples.

- Cache successful verifications in a dedicated LRU of up to 10000
runners, keyed by the stored salt and hash and holding only a SHA-256
digest of the token. A hit costs ~100 ns.
- The runner is still loaded from the DB on every RPC and failures are
never cached, so deleted runners and wrong tokens never pass.
- The shared `auth_model.TokenCache` is not used because its default 20
entries miss on every poll once more runners poll in turn.

---------

Co-authored-by: silverwind <me@silverwind.io>
2026-10-23 03:59:11 +00:00
Lunny Xiao c45af635e4 feat: Allow automatic project actions on events (#30205)
This PR introduces project workflows, allowing users to configure
event-based automations directly from the UI.
Users can define filters and actions for each workflow event, and
duplicate existing events when needed.

### Concepts

Every workflow is composed of `event`, `filters`, and `actions`.

- **Event** - An Event defines when a workflow should be triggered. It
represents specific activities such as an issue being added to the
project, a pull request being merged, or a project column being changed.
- **Filter** - A Filter refines when an event should take effect. It
allows users to specify conditions like issue type, labels, or project
columns to ensure actions only run in targeted scenarios.
- **Action** - An Action defines what happens when the event and filters
match. It performs operations such as adding labels, moving issues
between columns, or changing the issue or pull request state.

### Available Events

Currently, the following eight events are supported:

- On issues/pull requests closed
- On issues/pull requests reopened
- On issues/pull requests was added to the project, including when
created in it
- On issues/pull requests was removed from the project
- On issues/pull requests' column was changed
- On code changes requested
- On code review approved
- On pull request merged

Each event type supports its own set of filters and actions.

### Available Filters

There are four types of filters that can be configured for an event:

- **Apply to** - Specify the target type: `issues only`, `pull requests
only`, or `issues and pull requests`.
- **Labels** - Trigger the event only if the issue or pull request
contains one or more specified labels.
- **Move from column** - Filter events based on the original project
column.
- **Move to column** - Filter events based on the destination project
column.

### Available Actions

There are four types of actions that can be executed when an event is
triggered:

- **Add labels** - Automatically add one or more labels to the issue or
pull request.
- **Remove labels** - Remove one or more specified labels.
- **Move to column** - Move the issue or pull request to a designated
project column.
- **Issue state** - Close or reopen the issue. Pull requests can only be
closed.

### Enable/Disable an event workflow

Each event workflow can be individually enabled or disabled. When
disabled, the workflow will be ignored even if the event occurs. This
feature is useful when you want to temporarily stop certain automated
actions without deleting the workflow configuration. Workflows of closed
projects don't run either.

### Clone an event workflow

When you need multiple workflows for the same event, you can clone an
existing event to create a new one with different filters and actions.
This allows you to customize how the same event behaves under different
conditions, making workflows more flexible and powerful.

### Permissions

Permissions are checked when workflows are managed, not when they run:

- Viewing a project's workflows needs read access to the project
- Managing them needs write access to the project plus write access to
both issues and pull requests of a repository project's repository,
being an owner of an organization project's organization or a site
administrator, or being the user of a user project. Tokens limited to
public repositories can't manage owner-level projects' workflows
- A workflow runs when its event happens to an item of an open project
that can hold the item's repository, unless that repository is archived,
no matter who caused the event, and applies its actions without further
permission checks. Pull requests are never reopened
- Changes show as made by "Project workflow" on behalf of the user who
triggered the event and don't trigger other workflows
- Only users who can read an item can put it on a board or move its card

The management rule is also documented on `CanManageWorkflows` in
`services/projects/workflow.go`.

Fixes:  #14359
Fixes: #26704
Fixes: #27990
Replaces:  #28745
Documentation PR: https://gitea.com/gitea/docs/pulls/308
Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-10-23 01:53:45 +00:00
Lunny Xiao d0c35bcd58 refactor(git): remove unused TreeCommon embedded struct (#39830)
`TreeCommon` only holds `ID` and is embedded solely by `Tree`, with no
other users. Inline the field into `Tree`; `t.ID` access is unchanged.

Assisted-by: Codet:codet
2026-10-18 12:33:19 +00:00
52b18b4903 fix(pull): recover PRs whose recorded merge commit never reached the base repo (#39831)
When pushing the merge commit to the base repo fails (e.g.
non-fast-forward), the merge intent recorded by
https://github.com/go-gitea/gitea/pull/39442 is left behind.
`merged_commit_id` then points to a commit that does not exist in the
base repo, and `git branch --contains` fails with `no such commit`, so
the PR can never be checked or merged again.

- Clear the recorded merge intent if the push fails and the commit is
not on the base branch
- `IsCommitInBranch` now returns false for a missing commit, so
already-stuck PRs recover on the next check

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

_Written with Codet assistance._

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-10-18 09:52:44 +00:00
Lunny Xiao c1ae4ec29e fix(actions): keep folded block scalars intact across serialization (#39787)
Folded (`>`) scalars in workflows gained blank lines and had spaces
turned into newlines every time Gitea re-serialized a job. This bumps
go-yaml to its main branch and drops our workarounds. The runner gets
the same change in https://gitea.com/gitea/runner/pulls/1321.

- go-yaml main fixes the accumulating blank lines
(https://github.com/yaml/go-yaml/pull/366) and the block scalar
indentation indicators (https://github.com/yaml/go-yaml/pull/414), so
`BlockSafeString` and the folded scalar requoting go away
- The job encoder no longer wraps lines, because go-yaml still wraps
more-indented lines of folded scalars and turns a space into a newline
- The fix applies to folded scalars anywhere in a workflow, including
workflow-level `env`

Fixes https://github.com/go-gitea/gitea/issues/39775
Co-authored-by: silverwind <me@silverwind.io>
2026-10-16 22:53:37 +00:00
6dad3ad43d refactor: only update sync status columns when syncing push mirror (#39517)
`UpdatePushMirror` used `AllCols()`, so a sync could overwrite columns
changed concurrently (e.g. `interval`) with stale values. It now updates
only `last_update` and `last_error`, and is renamed to
`UpdatePushMirrorSyncStatus` to match.

Co-authored-by: Giteabot <teabot@gitea.io>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 5) <noreply@anthropic.com>
2026-10-02 19:28:51 +00:00
Lunny Xiaoandwxiaoguang cce2360846 build(release): use native golang toolchain for official release builds (#37828)
Official releases are built by Golang toolchain with CGO disabled.

For packagers who need to cross-compile with CGO, use "build" target
with proper TAGS/LDFLAGS/CGO_CFLAGS to make "$(EXECUTABLE)" target run
the "go build" command.

By the way, drop i386 arch support

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-08-22 10:38:21 +00:00
f7072b0305 feat(api): list all packages for site administrators (#38968)
Add `GET /admin/packages` so site administrators can review packages
across every owner without querying each owner separately.

It returns the same package version representation as `GET
/packages/{owner}` and supports `page`, `limit`, `type`, and `q`
filters.

---
Assisted by Codet(DeepSeek)

---------

Signed-off-by: bircni <bircni@icloud.com>
Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-08-22 09:29:25 +02:00
475e51c7e0 fix: avoid enumerating every public repository in issue search (#38992)
Both issue search endpoints resolve their repository filter with
`SearchRepositoryIDs` and pass the result to the indexer as `RepoIDs`.
They mean
to leave public repositories to the indexer, but
`SearchRepoOptions.AllPublic` is
only read when `OwnerID > 0`, so without an `owner` filter the flag does
nothing
and every public repository is enumerated, without a `LIMIT`, into
`repo_id IN (...)`.

Those IDs are redundant, as `allPublic` is passed to the indexer, which
already
matches every public repository. On a large instance this binds tens of
thousands
of parameters and can fail in the driver, making the endpoint return 500
for every
filter. Admins are worst hit, as `SearchRepositoryCondition` skips their
accessible-repository condition and enumerates the whole table.

Restrict the enumeration to private repositories. The result set is
unchanged, as
the dropped IDs are a subset of what `allPublic` matches.

Both endpoints held copies of this block, so it moves to
`routers/common`.

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-08-20 16:29:54 +00:00
Lunny Xiao 07843086c2 ci: remove AWS S3 uploads from release workflows (#38928)
Release binaries and downloads have been served from Cloudflare R2 for a
while now, so the AWS S3 upload is redundant.

This removes the `configure aws` and `upload binaries to s3` steps from
the nightly, RC and version release workflows. Since
`configure-aws-credentials` no longer runs in those jobs, the
`AWS_REGION: auto` workaround in the R2 step can be dropped as well.

The `AWS_*` secrets for S3 can be removed from the repository settings
afterwards.
2026-08-14 21:50:27 +02:00
Lunny Xiao 3f833fd681 chore: Pre-register a builtin OAuth2 application for the official Gitea mobile app (#38880)
This is a prepare and required step for upcoming Gitea Official Mobile
APP which supports login with OAuth2.

The official Gitea mobile app needs the same mechanism. This adds a
builtin application for it:

| | |
|---|---|
| client ID | `b757811a-05c8-4c76-8d74-a5ee3d2073f2` |
| config name | `gitea-app` |
| display name | `Gitea App` |
| redirect URI | `com.gitea.app://oauth/callback` |

Unlike the existing entries, which are CLIs and can therefore use a
loopback `http://127.0.0.1` redirect, a mobile app authorises through a
system browser session (`ASWebAuthenticationSession` on iOS, Custom Tabs
on Android) that can only receive a custom-scheme callback, hence the
custom scheme here.
2026-08-12 14:34:22 +00:00
2087d4a1a5 refactor: use the shared workflow model from actionslib (#38768)
Pairs with https://gitea.com/gitea/runner/pulls/1143.

Gitea depends on `gitea.com/gitea/runner` for exactly two packages:
`act/model` and `act/exprparser`, the workflow model and the expression
evaluator it needs to parse workflows and to build the task payload the
runner consumes. Pulling the whole runner module in for that is heavy
and puts shared code in the repository of one of the two consumers.

Both packages now live in `gitea.dev/actionslib` (`pkg/model`,
`pkg/exprparser`), the module Gitea and the runner already share for the
runner API, so the dependency on the runner repository is dropped here.

### Changes

- `gitea.com/gitea/runner/act/model` ->
`gitea.dev/actionslib/pkg/model`, `.../act/exprparser` ->
`gitea.dev/actionslib/pkg/exprparser` (22 files, import paths only).
- `routers/api/actions/runner/interceptor.go` takes the `x-runner-uuid`
/ `x-runner-token` names from `gitea.dev/actionslib/pkg/protocol`
instead of repeating the literals the runner also has.
- `go.mod`: `gitea.com/gitea/runner` removed.

---------

Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Zettat123 <zettat123@gmail.com>
2026-08-07 20:56:40 -07:00
Lunny Xiaoandwxiaoguang a34cc4cac4 fix(migration): migration deletion returned json redirection (#38796)
Fix #38596

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-08-07 13:21:20 +00:00
Lunny Xiao 87ed4117c6 docs: Update PGP key expiration date to July 23, 2027 (#38747)
Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-08-02 17:52:16 +00:00
Lunny Xiaoandwxiaoguang 4e4ea75fb9 refactor(diff): drive diff DOM init from the global selector observer (#38740)
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-08-02 13:19:57 +00:00
Lunny Xiao 559aa89ca7 ci: set AWS_REGION for Cloudflare R2 upload steps (#38658)
The `configure-aws-credentials` step earlier in the same job exports
**both** `AWS_DEFAULT_REGION` and `AWS_REGION` into `$GITHUB_ENV`
(verified in `exportRegion()` at the pinned SHA `517a711`), so
`secrets.AWS_REGION` (the real AWS region) stays set for every later
step in that job.

The AWS CLI v2 region resolution order is `--region` > `AWS_REGION` >
`AWS_DEFAULT_REGION`. The R2 step only set `AWS_DEFAULT_REGION: auto`,
so the leaked `AWS_REGION` won and R2 rejected it, since R2 only accepts
`wnam`, `enam`, `weur`, `eeur`, `apac`, `oc` or `auto`.

The failure log shows both `AWS_DEFAULT_REGION: auto` and `AWS_REGION:
***` in the step env, which confirms the leak.

### Fix

Set `AWS_REGION: auto` explicitly in the R2 upload step env of all three
release workflows. Step-level `env:` is applied after
`GITHUB_ENV`-derived variables, so this reliably overrides the leaked
value.

No other variable leaks from `configure-aws-credentials` matter here:
`AWS_SESSION_TOKEN` is only exported when a session token exists, and
these workflows use static access keys without `role-to-assume`;
`AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` are already overridden
in the R2 step.

Consolidating the three duplicated upload steps into a composite action
remains a follow-up, as noted in #38635.
2026-07-27 14:54:03 +00:00
Lunny Xiao 230e7bdf91 chore(build): upload release to Cloudflare R2 (#38635)
The download site’s bandwidth costs are growing rapidly, while
Cloudflare R2 does not charge egress fees. Therefore, we would like to
migrate the download site from S3 to R2.

To ensure a smooth transition, we will keep the existing S3 upload
process temporarily and remove it after the migration is complete.

The upload steps are currently duplicated in three places. They could be
consolidated into a composite action in a separate PR.
2026-07-26 17:22:25 -07:00
Lunny Xiao 580cc26d63 chore: Upgrade xorm to 1.4.1 (#38224)
Fix #22275

Changelog: https://gitea.com/xorm/xorm/compare/v1.3.11..v1.4.1
2026-07-06 17:07:58 +00:00
Lunny Xiaoandwxiaoguang e4ef995f2a fix(release): validate web attachment renames against allowed types (#38314)
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.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-04 15:02:17 +02:00
Lunny Xiaoandsilverwind b34a09be38 build: fix snapcraft release (#38260)
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: silverwind <me@silverwind.io>
2026-06-29 14:35:26 -07:00
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
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
Lunny Xiaoandbircni 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
Lunny Xiaoandbircni e5891263f8 docs: update changelog for 1.26.3 & 1.26.4 (#38178)
Front port changelog for 1.26.3 & 1.26.4

---------

Co-authored-by: bircni <bircni@icloud.com>
2026-06-21 17:13:18 +00:00
Lunny Xiao 64f3796567 fix: Fix the panic when ssh remote lfs endpoint parsing failure (#38026)
Fix #38016
2026-06-18 07:54:16 +02:00
Lunny Xiao 0be7543560 fix(mssql): expand legacy issue and comment long-text columns (#38120)
## Summary

This fixes pull request creation failures on upgraded MSSQL instances
where legacy `issue` and `comment` long-text columns are still limited
to `nvarchar(4000)`.

When a PR is created, Gitea stores a pull request push timeline comment
containing JSON with `commit_ids`. For PRs with many commits, that
payload can exceed 4000 characters and MSSQL rejects the insert with:

> String or binary data would be truncated in table 'comment', column
'content'

This change adds a migration that expands the affected legacy MSSQL
columns to `NVARCHAR(MAX)`.

The previous migration in models/migrations/v1_16/v191.go only applies
to MySQL, not MSSQL.

migration now skips columns already using NVARCHAR(MAX) / VARCHAR(MAX)

Closes #37893

## Changes

- add migration `338` for MSSQL-only long-text expansion
- expand:
  - `issue.content`
  - `comment.content`
  - `comment.patch`
- add an MSSQL regression test that starts from a legacy `VARCHAR(4000)`
schema and verifies inserts larger than 4000 characters succeed after
migration

## Why this approach

The current model already declares these fields as `LONGTEXT`, so the
bug is caused by stale upgraded MSSQL schemas rather than by PR creation
logic itself. Fixing the schema is the smallest and safest change, and
also prevents similar truncation issues for other long issue/comment
content.
2026-06-16 17:40:13 +00:00
Lunny Xiao 134fcced88 ci: trigger giteabot maintenance on main pushes (#38135) 2026-06-16 07:07:32 +00:00
Lunny Xiaoandbircni a77edc7ba4 chore(actions): Add icon for status filter (#38082)
<img width="352" height="391" alt="image"
src="https://github.com/user-attachments/assets/261dd567-49c2-4fc6-a646-5f8641e08192"
/>

---------

Co-authored-by: bircni <bircni@icloud.com>
2026-06-14 19:44:53 +00:00
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
Lunny Xiao 611dfc9496 fix: Fix some wrong code and follow 37347 (#37987) 2026-06-09 07:53:58 +02:00
689ace1ce2 feat(orgs): Add search bar for organization members tab page (#37347)
Resolve #37072 

<img width="1312" height="186" alt="image"
src="https://github.com/user-attachments/assets/3ca9eddb-9230-4b0d-992f-5b19e475e267"
/>

---------

Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: bircni <bircni@icloud.com>
2026-06-01 20:16:04 +00:00
4e5f43896e fix(auth): ignore stale OIDC external login links to organizations (#37875)
## Summary

This fixes an OIDC sign-in edge case where a stale `external_login_user`
record can still point to an organization or a deleted user.

In that situation, Gitea may keep resolving the external login to the
wrong account during sign-in. For affected instances, this matches the
behavior reported in #36439 and #37812, where a user signing in with
OIDC/Entra ID could appear as an organization, or hit a 404 after that
organization was removed.

## What changed

- validate the user resolved from `external_login_user` during
OAuth2/OIDC login
- ignore stale links when the linked user no longer exists
- ignore stale links when the linked user is not an individual user
- remove the stale external login row so the sign-in flow can relink the
external account to the correct user

## Related

- Fixes #37812
- Related to #36439

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.8) <noreply@anthropic.com>
2026-05-30 20:37:09 +00:00
428ee9fcce fix(testing): Fix random failure test (#37887)
Fix the flaky npm package web view test that compared rendered HTML as a
raw string.

Fix
https://github.com/go-gitea/gitea/actions/runs/26524574688/job/78124662707?pr=36564

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-28 17:53:38 +00:00
Lunny Xiao 0a3e7483a4 chore: Move gitea sdk from code.gitea.io/sdk/gitea -> gitea.dev/sdk (#37855)
- Use gitea.dev/sdk instead of code.gitea.io/sdk/gitea
- Use gitea.dev/actions-proto-def instead of
code.gitea.io/actions-proto-def
2026-05-27 16:23:44 -07:00
Lunny Xiao 61b1a39efe chore: Move import path from code.gitea.io/gitea to gitea.dev (#37873) 2026-05-26 15:49:31 -07:00
Lunny Xiaoandsilverwind 8874ba739b fix(build): swagger css import (#37801)
Snap build failure caused by missed swagger ui css file.

```
:: [plugin vite:css] /build/gitea/parts/gitea/build/web_src/css/swagger-standalone.css:undefined:NaN
:: Error: [postcss] ENOENT: no such file or directory, open '../../node_modules/swagger-ui-dist/swagger-ui.css'
```

Co-authored-by: silverwind <me@silverwind.io>
2026-05-21 13:56:34 +00:00
552c29a259 fix(actions): make artifact signature payloads unambiguous (#37707)
This PR hardens artifact URL signing by encoding signature inputs in an
unambiguous binary payload before computing the HMAC.

What it changes:

- replace direct concatenation-style signing inputs with explicit
payload builders
- encode string fields with a length prefix before appending their bytes
- encode integer fields as fixed-width binary values instead of decimal
text
- apply the same hardening to both:
  - Actions Artifact V4 signing in `routers/api/actions/artifactsv4.go`
  - artifact download signing in `routers/api/v1/repo/action.go`
- add regression tests that verify distinct field combinations produce
distinct payloads and signatures

Why:

The previous signing logic built HMAC inputs by appending multiple
fields without a strongly structured representation. That kind of
construction can create ambiguity at field boundaries, where different
parameter combinations may serialize into the same byte stream for
signing.

This change removes that ambiguity by constructing a deterministic
payload format with explicit boundaries between fields.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-05-20 16:34:27 +00:00
Lunny Xiao 304f8a551a chore: Update giteabot to fix failure when backport (#37789) 2026-05-19 20:56:34 -07:00
Lunny Xiao 171df0c9ff fix(permissions): Fix reading permission (#37769) 2026-05-19 09:23:32 +00:00
Lunny XiaoandNicolas a1de9e57c2 ci: split giteabot workflow (#37770)
## What

This PR updates the giteabot workflows to use the newer action version
that supports selecting individual checks, and splits the workflow into
two separate jobs:

- `giteabot backport` runs only the `backport` check on pushes to `main`
- `giteabot` handles the remaining bot tasks on PR-related events,
scheduled runs, and manual dispatch

## Why

Previously, the single workflow handled both backporting and the other
maintenance tasks together.

With the new giteabot action supporting configurable checks, splitting
the workflow makes the triggers clearer and avoids running non-backport
maintenance on every push to `main`.

## Changes

- upgrade `go-gitea/giteabot` to a revision that supports the `checks`
input
- move the `main` branch `push` trigger into a dedicated backport
workflow
- keep non-backport automation in the existing workflow
- add a `workflow_dispatch` input so non-backport checks can be selected
manually when needed

---
Helped by a coding agent with Codex 5.4

---------

Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-18 21:08:57 -07:00
f2a1271f16 fix: Unify public-only token filtering in API queries and repo access checks (#37118)
This PR closes remaining `public-only` token gaps in the API by making
the restriction apply consistently across repository, organization,
activity, notification, and authenticated `/api/v1/user/...` routes.

Previously, `public-only` tokens were still able to:
- receive private results from some list/search/self endpoints,
- access repository data through ID-based lookups,
- and reach several authenticated self routes that should remain
unavailable for public-only access.

This change treats `public-only` as a cross-cutting visibility boundary:
- list/search endpoints now filter private resources consistently,
- repository lookups enforce the same restriction even when addressed
indirectly,
- and self routes that inherently expose or mutate private account state
now reject `public-only` tokens.

---
Generated by a coding agent with Codex 5.2

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-05-18 11:36:42 -07:00
Lunny Xiao c3d9d07702 fix: Add missed token scope checking (#37735)
Follow #37698
2026-05-18 04:52:08 +00:00
2d1eb28083 chore: Use giteabot instead of backporter (#37422)
This PR use a backporter wrap action
https://github.com/go-gitea/giteabot to do backport, adding labels and
etc. The test repository https://github.com/go-gitea/test-giteabot could
confirm backporting works.

---------

Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: techknowlogick <techknowlogick@gitea.com>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-05-18 05:46:52 +02:00
ae69aec295 fix(oauth): strengthen PKCE validation and refresh token replay protection (#37706)
This PR tightens several OAuth validation paths related to PKCE
handling, redirect URI normalization, and refresh-token replay safety.

What it changes:

- switch redirect URI comparison to ASCII-only normalization for
exact-match checks, avoiding Unicode case-folding surprises
- harden PKCE verification by:
  - allowing PKCE omission only when no challenge data was stored
  - rejecting exchanges with a missing verifier when PKCE was used
- rejecting malformed challenge state where a challenge exists without a
valid method
  - comparing derived challenges with constant-time string matching
- make refresh-token invalidation counter updates conditional on the
previously observed counter value, so stale refresh state cannot be
accepted after the grant changes

Why:

These checks close gaps where:
- redirect URI comparisons could rely on broader Unicode normalization
than intended
- malformed or incomplete PKCE state could be treated too permissively
- concurrent or stale refresh-token use could advance the same grant
more than once

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-16 15:17:00 +00:00
33923a4d7c fix(web): enforce token scopes on raw, media, and attachment downloads (#37698)
This PR tightens token-scope enforcement for non-API download endpoints
in the web layer.

What it changes:

- require `read:repository` for repository content downloads served from
web routes such as:
  - `/raw/...`
  - `/media/...`
- enforce attachment-specific scopes in `ServeAttachment`:
  - issue / pull request attachments require `read:issue`
  - release attachments require `read:repository`
- centralize token-scope checks for web handlers with a shared context
helper
- add matrix-style integration coverage for:
  - public and private repository content downloads
  - `blob`, `branch`, `tag`, and `commit` download routes
  - global and repo-scoped attachment routes
  - `public-only` token behavior on public vs private resources

Why:

API tokens and OAuth access tokens can be used on some non-API web
endpoints. Before this change, those endpoints relied on repository
visibility and unit permissions, but did not consistently enforce the
token’s declared scope. That allowed scoped tokens to access resources
beyond their intended category through web download routes.

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-16 14:50:41 +00:00
Lunny Xiao 7e54514316 fix(oauth): bind token exchanges to the original client request (#37704) 2026-05-16 07:03:23 +02:00
Lunny Xiaoandwxiaoguang f9b7b65371 fix(security): enforce wiki git writes and LFS token access at request time (#37695)
This PR fixes two permission-checking gaps in Git and LFS request
handling.

## What it changes

- keep wiki Git HTTP pushes on the normal write-permission path, even
when proc-receive support is enabled
- revalidate LFS bearer token requests against the current user state
and current repository permissions before allowing access
- add regression coverage for unauthorized wiki HTTP pushes
- add LFS tests for blocked users, revoked repository access, read-only
upload attempts, and valid write access

## Why

- wiki repositories should not inherit the relaxed refs/for handling
used for normal code repositories
- LFS authorization tokens should not remain usable after a user is
disabled or loses repository access

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-05-15 08:12:59 +00:00
929962833d fix: snap build (main branch) (#37685)
1. make "pull" and "build" testable and debuggable
2. add more comments for how the build works
3. separate 1.26 and main build tags
4. fix incorrect tag describe (the current `snap info gitea` outputs
version 1.22)

Legacy logic is kept as is although some of them don't seem good (e.g.:
snap version grep, tag finding, etc)

---------

Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-13 17:31:47 -07:00
5d87a70af9 fix(packages): Add label for private and internal package and fix composor package source permission check (#37610)
- Add permission checks for Composer package source links

- Add private/internal visibility labels for packages, similar to
repository visibility labels

<img width="969" height="571" alt="image"
src="https://github.com/user-attachments/assets/8a8ec3a0-bfbd-4dd6-b45b-58eda5db1a2d"
/>

- Add a link to change package visibility

<img width="1309" height="208" alt="image"
src="https://github.com/user-attachments/assets/3fa82b23-4c63-4a5e-b3f0-d37a103231ee"
/>

- Update link package descriptions

<img width="1308" height="265" alt="image"
src="https://github.com/user-attachments/assets/2c80b50e-5ffe-4d96-aedd-aa15964c4e05"
/>

---------

Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-05-11 05:49:46 +00:00
7dc3087acd fix(git): Fix smart http request scope bug (#37583)
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-05-08 08:30:23 +02:00
Lunny Xiao 48cea1fb79 Fix basic auth bug (#37486) 2026-04-30 20:34:43 -07:00
Lunny Xiao aedf4e84f5 Move review request functions to a standalone file (#37358)
Assignee functions should be different from review request functions.
2026-04-23 23:01:04 +00:00
f1644fc5e2 Add event.schedule context for schedule actions task (#37320)
Fix #35452

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-04-21 20:30:21 +00:00
b4f48a64fc Fix an issue where changing an organization’s visibility caused problems when users had forked its repositories. (#37324)
A quick fix #37317

---

The current behavior for forks when an organization or repository is
changed to private differs from GitHub.

On GitHub, when a parent repository becomes private, the fork
relationship is removed, which keeps the behavior simple and avoids
visibility conflicts.

I think we need a similar solution to handle cases where the parent
repository becomes private while a fork remains public and the fork
relationship is still preserved.

---------

Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-04-21 18:47:51 +00:00
Lunny Xiaoandsilverwind 12733d3624 Fix bug when accessing user badges (#37321)
Fix #37302

---------

Co-authored-by: silverwind <me@silverwind.io>
2026-04-21 01:18:12 +00:00
Lunny Xiao 85c09b8f45 Fix AppFullLink (#37325)
Fix a bug the checkout command line hint becomes
`git fetch -u https://gitea.combircni/tea`
2026-04-20 23:57:08 +00:00
Lunny Xiao a17d5ebe16 Don't add useless labels which will bother changelog generation (#37267)
When generating release notes for v1.26, many pull requests haven't been
given correct labels so that I have to do many manual work. I think this
could be avoid to remove these useless modify labels.
2026-04-19 11:34:40 -07:00
Lunny Xiao ea6280da75 release notes for 1.26.0 (#37282)
Frontend from #37266
2026-04-18 13:39:25 -07:00
Lunny Xiao 8bf3c8b79d Frontport changelog of v1.26.0-rc0 (#37138) 2026-04-08 22:43:28 +02:00
Lunny Xiao 290edc1614 upgrade vite (#37126) 2026-04-07 09:16:22 +00:00
Lunny Xiao dc197a0058 Add placeholder content for empty content page (#37114)
- Empty repositories in organization

<img width="877" height="470" alt="image"
src="https://github.com/user-attachments/assets/94dc3992-1ab5-47cc-954a-8c420ec68500"
/>

- Empty projects in organization

<img width="1309" height="358" alt="image"
src="https://github.com/user-attachments/assets/94ef20c5-a6d9-4c39-9457-2a691a98d327"
/>

- Empty code search result in organization and global code search page

<img width="1312" height="345" alt="image"
src="https://github.com/user-attachments/assets/364f2a75-c68f-4302-b3b8-7ba1265622a1"
/>

- Empty worktime in organization

<img width="1301" height="357" alt="image"
src="https://github.com/user-attachments/assets/bb7f2cf8-fb95-463a-94c7-eafa63f56b2b"
/>
2026-04-06 10:31:51 -07:00
Lunny Xiao e47c6135dd Add gpg signing for merge rebase and update by rebase (#36701)
Fix #36685 

--- 

Generated by a coding agent with Codex 5.2 LLM.
2026-04-05 13:37:35 -07:00
f59d1d3cef Fix the wrong push commits in the pull request when force push (#36914)
Fix #36905

The changes focus on force-push PR timeline handling and commit range
calculation:
- Reworked pull-request push comment creation to use a new
`gitrepo.GetCommitIDsBetweenReverse` helper, with special handling for
force pushes (merge-base based range, tolerate missing/invalid old
commits, and keep force-push timeline entries).
- Added `Comment.GetPushActionContent` to parse push comment payloads
and used it to delete only non-force-push push comments during force
pushes.
- Removed the old `Repository.CommitsBetweenNotBase` helper from
`modules/git/repo_commit.go` in favor of the new commit ID range helper.
- Added tests for `GetCommitIDsBetweenReverse` (normal range, `notRef`
filtering, fallback branch usage) and expanded pull comment tests to
cover force-push edge cases.

<img width="989" height="563" alt="image"
src="https://github.com/user-attachments/assets/a01e1bc2-fa8a-4028-8a35-d484e601ff3b"
/>

---------

Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-04 16:27:57 -07:00
686d10b7f0 Fix a bug when forking a repository in an organization (#36950)
`CanCreateOrgRepo` should be checked before forking a repository into this organization.

---------

Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-02 15:04:43 -07:00
Lunny Xiaoandsilverwind 6288c87181 Upgrade yaml (#37015)
Upgrade go.yaml.in/yaml/v4 v4.0.0-rc.2 to go.yaml.in/yaml/v4
v4.0.0-rc.4. Fix some workflow yaml files parse problems.

---------

Co-authored-by: silverwind <me@silverwind.io>
2026-03-29 09:52:00 +00:00
Lunny XiaoandGiteabot a1b0bffd0c Hide delete branch or tag buttons in mirror or archived repositories. (#37006)
Fix #36995

---------

Co-authored-by: Giteabot <teabot@gitea.io>
2026-03-29 10:51:29 +02:00
Lunny Xiao c453d09c36 Catch scanner error when possible to avoid bypass (#36963) 2026-03-23 21:08:48 -07:00
Lunny XiaoandCopilot f3bdcc58af Fix OAuth2 authorization code expiry and reuse handling (#36797)
- set OAuth2 authorization code `ValidUntil` on creation and add expiry
checks during exchange
- return a specific error when codes are invalidated twice to prevent
concurrent reuse
- add unit tests covering validity timestamps, expiration, and double
invalidation

---
Generate by a coding agent with Codex 5.2

---------

Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-06 05:00:44 +00:00
Lunny Xiao 57b5ed3f25 Fix org permission API visibility checks for hidden members and private orgs (#36798)
- fix wrong parameter of HasOrgOrUserVisible in
routers/api/v1/org/org.go
- add integration tests covering the bug fix
- merge permissions API tests

---
Generated by a coding agent with Codex 5.2
2026-03-05 20:32:15 -08:00
Lunny Xiao 9c2c9c5a00 upgrade to github.com/cloudflare/circl 1.6.3, svgo 4.0.1, markdownlint-cli 0.48.0 (#36837) 2026-03-05 13:42:47 -08:00
Lunny Xiao 833304ac15 Fix dump release asset bug (#36799) 2026-03-05 20:30:57 +00:00
99b0bf7324 Fix bug to check whether user can update pull request branch or rebase branch (#36465)
When checking whether a user can update a pull request branch or perform
an update via rebase, a maintainer should inherit the pull request
author’s permissions if Allow maintainer edits is enabled.

---------

Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-05 11:31:34 -08:00
Lunny Xiaoandwxiaoguang 723ce3579f Fix forwarded proto handling for public URL detection (#36810)
Normalize `X-Forwarded-Proto` related headers to accept only `http`/`https`

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-06 00:31:52 +08:00
Lunny Xiao 5d87bb3d45 Add a git grep search timeout (#36809) 2026-03-04 12:11:42 -08:00
Lunny Xiaoandwxiaoguang 315b947740 Harden render iframe open-link handling (#36811)
This PR hardens the handling of the “open-link” action in render iframes
(external rendering iframes). It prevents iframes from triggering unsafe
or unintended redirects or opening new windows via postMessage.

Additionally, it improves iframe height reporting to reduce scrollbar
and height mismatch issues, and adds unit test coverage.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-03 23:15:33 -08:00
Lunny Xiao 56f23f623a Fix bug when pushing mirror with wiki (#36795)
Fix #36736
2026-03-02 20:58:07 +00:00
Lunny Xiaoandwxiaoguang 0e0daa8afe Delete non-exist branch should return 404 (#36694)
Fix #36682

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-02 11:08:16 -08:00
Lunny XiaoandChristopherHX 716a800f50 Remove API registration-token (#36801)
Replace #36793

---------

Co-authored-by: ChristopherHX <christopher.homberger@web.de>
2026-03-02 10:31:42 -08:00
Lunny Xiao 553277b0be upgrade minimatch (#36760) 2026-03-01 10:56:32 -08:00
Lunny Xiao 569c49debe Add validation constraints for repository creation fields (#36671)
Adds validation constraints to repository creation inputs, enforcing
max-length limits for labels/license/readme and enum validation for
trust model and object format. Updates both the API option struct and
the web form struct to keep validation consistent.
2026-02-25 16:28:39 +00:00
ed57c70176 Fix track time list permission check (#36662)
Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-24 20:22:04 +00:00
3db3c058b3 Prevent redirect bypasses via backslash-encoded paths (#36660)
This change tightens relative URL validation to reject raw backslashes
and `%5c` (encoded backslash), since browsers and URL normalizers can
treat backslashes as path separators. That normalization can turn
seemingly relative paths into scheme-relative URLs, creating
open-redirect risk.

Visiting below URL to reproduce the problem.

http://localhost:3000/user/login?redirect_to=/a/../\example.com

http://localhost:3000/user/login?redirect_to=/a/../%5cexample.com

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-22 22:15:03 +00:00
8f15f76dd6 Fix force push time-line commit comments of pull request (#36653)
Fix #36647 
Fix #25827
Fix #25870

---------

Signed-off-by: silverwind <me@silverwind.io>
Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-22 21:30:31 +00:00
1eced4a7c0 Fix get release draft permission check (#36659)
Draft release and it's attachments need a write permission to access.

---------

Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-02-22 20:56:46 +00:00
Lunny XiaoandChristopher Homberger ad9850391d Move jobparser from act repository to Gitea (#36699)
The jobparser sub package in act is only used by Gitea. Move it to Gitea
to make it more easier to maintain.

---------

Co-authored-by: Christopher Homberger <christopher.homberger@web.de>
2026-02-22 19:33:01 +00:00
Lunny Xiaoandsilverwind daf10ff84c Fix push time bug (#36693)
When display or search branch's pushed time, we should use
`updated_unix` rather than `commit_time`.

Fix #36633

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: silverwind <me@silverwind.io>
2026-02-22 17:14:53 +00:00
Lunny Xiao ed587ca71b Add some validation on values provided to USER_DISABLED_FEATURES and EXTERNAL_USER_DISABLED_FEATURES (#36688) 2026-02-21 00:56:43 +00:00