Commit Graph
1436 Commits
Author SHA1 Message Date
Basavaraj S mandwxiaoguang 467963f0dd fix(issues): require per-item write access for batch issue actions (#40047)
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-30 08:22:37 +00:00
5ee660e437 fix(pull): refuse review comments on locked pull requests (#39960)
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-29 23:57:51 +00:00
Jorgeandwxiaoguang 02c03d69d3 enhance(repo): allow system users in protected tag allowlist (#40038)
Allowlisting gitea-actions lets any workflow of the repository with write access push matching tags, the same trade-off branches already have. Allowing gitea:deploy-key is new for tags.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-28 09:19:35 +00:00
92ad81bb14 fix(feed): require code read access for the repo home branch feed (#39964)
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-28 00:33:35 +00:00
178d33ed4d fix: add missing access checks and size limits (#39942)
Several handlers and parsers skipped checks that their siblings already
perform.

- Reject issue, comment, label, milestone and release mutations in
archived repositories via the API with one guard per route group,
matching the web UI
- Hide timeline references and dependencies pointing at issues the doer
cannot read, in the web UI and the API, including pull requests of the
same repository without pull request access
- Reject workflow runs with more than `MaxJobNumPerRun` jobs, including
inline reusable workflow jobs, and show rejected pushes as invalid
workflow runs
- Bound how much of a Helm chart archive is inflated while looking for
`Chart.yaml`

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-27 21:40:42 +01:00
petervavrinecz a397e92c80 fix(issue): prevent redirect to external tracker when built-in tracker is enabled (#39997)
PR #39354 added support for enabling both internal and external trackers
concurrently and introduced separate navigation buttons.

However, as originally pointed out during code review on #39354
([comment](https://github.com/go-gitea/gitea/pull/39354#discussion_r4047774417)):
> *"With both trackers enabled and the built-in issue unit readable,
this redirect still runs whenever the external URL is nonempty, so
`/issues` never reaches the internal issue list in the new combined
configuration. Only redirect to the external tracker when the caller
cannot read the internal issue unit."*

`MustEnableIssues` in `routers/web/repo/issue.go` was still
unconditionally redirecting whenever `unit.TypeExternalTracker` is
enabled with a non-empty `ExternalTrackerURL`.

### Fix

In `routers/web/repo/issue.go`, only redirect to the external tracker
URL when the caller cannot read the built-in issue unit
(`!ctx.Repo.Permission.CanRead(unit.TypeIssues)`).

Signed-off-by: Vavrinecz Péter <98645804+petervavrinecz@users.noreply.github.com>
2026-10-26 08:12:14 -07:00
Hello-Liarandsilverwind 257c34e003 fix(repo): use the viewed ref's editorconfig in file view, blame and editor (#39973)
The file view, blame and web editor read `.editorconfig` from the
default branch, so branch-specific settings like tab width were ignored.
The file view's middleware ran before the ref was resolved, and blame
never loaded it.

- `GetEditorconfig` reads the current commit, falling back to the
default branch only where no ref is resolved
- `Home` and `RefBlame` load the editorconfig after ref resolution

Fixes: https://github.com/go-gitea/gitea/issues/27413
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: silverwind <me@silverwind.io>
2026-10-25 21:41:06 +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
silverwind 8abda62312 test: consolidate Go tests (#39962)
Consolidate all Go tests. Coverage is identical to before. Go tests are
around 5% faster while being 7% smaller. No non-test code is touched.
2026-10-24 13:48:19 +00:00
Shivansh Gargandsilverwind bcb4559c10 enhance(project): filter project milestones by linked issues (#39958)
The project milestone filter listed every milestone of the repo, or of
all accessible org repos for org projects, including ones with no issue
in the project. That made the dropdown noisy and unhelpful.

Both repo and org projects now list only milestones that have at least
one issue linked to the project, via a new `ProjectID` option on
`FindMilestoneOptions`.

Fixes: https://github.com/go-gitea/gitea/issues/39150
Co-authored-by: silverwind <me@silverwind.io>
2026-10-23 23:00:09 +00:00
Léon Simmons efd69ab1ff docs: fix typos in code comments (#39968)
- `models/asymkey/error.go`: `IsErrGPGKeyIDAlreadyUsed` doc named the
wrong type (`ErrKeyNameAlreadyUsed` → `ErrGPGKeyIDAlreadyUsed`)
- `modules/lfs/http_client.go`: `batchs` → `batches`
- `routers/web/repo/milestone.go`: `edting` → `editing` (x2), `for
change` → `for changing`

Signed-off-by: Léon Avic Simmons <Avicennasis@gmail.com>
2026-10-23 22:41:08 +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
6624d96689 feat(migrations): GraphQL fast path for GitHub migration + rate-limit resilience (#38694)
Adds a batched GraphQL path for GitHub migrations that fetches each
issue or pull request together with its comments, reviews, reactions and
timeline events instead of the REST N+1 pattern, sharply reducing
rate-limit pressure on large repositories.

- GraphQL is used for authenticated migrations with issues or pull
requests and falls back to REST automatically when it fails
- timeline events (close/reopen, lock, rename, label, milestone, merge,
branch deletion, pin, auto-merge) are imported as typed comments showing
their GitHub author
- GitBucket issue migrations no longer stop after the first page,
GitBucket sends no Link header

Fixes: https://github.com/go-gitea/gitea/issues/13243
Fixes: https://github.com/go-gitea/gitea/issues/31856
Signed-off-by: David E. Lovas <david@rexovas.com>
Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-10-23 02:23:28 +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
Shivansh Gargandwxiaoguang 0948aed411 refactor(api): load assignees list correctly (#39917)
Correctly handle empty names, upper&lower cases, duplicate names.

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

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-21 16:15:43 +00:00
silverwind 738ff1d65a refactor(git): replace git stderr matching with exit codes (#39866)
Matching git's stderr text is fragile because it breaks silently when
git rewords a message. Where git offers an exit code or a query with a
defined answer, use that instead, and drop matches that could never
trigger. Follow-up to the discussion in https://github.com/go-gitea/gitea/pull/39857.

- Detect a missing remote by `git remote` exit code 2
- Resolve annotated tags to their tree with cat-file `^{tree}` instead
of spawning `ls-tree` when listing tree entries
- Skip the wiki page lookup when the default branch doesn't exist yet
- Remove unreachable "no merge base" and "unknown revision" checks
2026-10-20 21:00:32 +00:00
fixfonandwxiaoguang 35fa0400e9 fix(pulls): tolerate invalid stored review commit_id (#39849)
Fixes #39848

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-20 11:03:34 -07:00
edd0c0e2ce feat: add release reactions and a GitHub-like reaction bar (#38415)
Adds emoji reactions to releases and moves the reaction picker of
issues, comments and releases into a GitHub-like reaction bar.

- Releases omit 👎 or 😕
- Drafts and tags can't be reacted to
- Moved menu to tippy
- Added keyboard navigation

Fixes: https://github.com/go-gitea/gitea/issues/34268
Fixes: https://github.com/go-gitea/gitea/issues/16676
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-20 15:04:10 +02:00
bircniandsilverwind ba4f8fa246 enhance(pull)!: add per-repository default squash merge commit message (#39816)
Adds a repository setting for the default squash merge commit message
body with GitHub's options `PR_BODY`, `COMMIT_MESSAGES` and `BLANK`,
also settable via `squash_merge_commit_message` in the API. The commit
title stays the pull request title.

1. Breaking: API squash merges without `merge_message_field` now get the
same default message as the web merge box instead of a title-only
commit, which affects clients sending only `Do` like Renovate. An empty
value keeps title-only.
2. Breaking: `[repository.pull-request] DEFAULT_SQUASH_MERGE_MESSAGE`
replaces `POPULATE_SQUASH_COMMENT_WITH_COMMIT_MESSAGES`, which still
works as a deprecated fallback. Repositories store the default when
created or next saved.
3. Deprecated app.ini keys now migrate through one table instead of
per-loader fallbacks, which also fixes the ignored `[mailer] CERT_FILE`
and `KEY_FILE` fallbacks. Deprecation warnings no longer claim a removal
version.

<img width="1891" height="571" alt="grafik"
src="https://github.com/user-attachments/assets/0fdcde13-1f11-4156-b598-d80eb0d04cbe"
/>

---------

Co-authored-by: silverwind <me@silverwind.io>
2026-10-19 09:15:41 +00:00
silverwindandwxiaoguang 5264304a34 refactor: carry the API token on the doer (#39690)
The token a request authenticated with now lives on the doer, so
permission and visibility checks apply its scope from the doer alone.
Replaces https://github.com/go-gitea/gitea/pull/39167, following
https://github.com/go-gitea/gitea/pull/39167#issuecomment-6063839619.

1. Public-only tokens get 404 instead of 403 for hidden users, orgs and
repos, like GitHub.
2. Org ownership, site admin, repo and org creation, generation and
transfer endpoints reject public-only tokens.
3. API pull request responses set `head.repo` to `null` and
`head.repo_id` to `-1` when the caller cannot see the head repository.
4. Public-only tokens see org memberships like anonymous callers, so
concealed members stay hidden.
5. Site admin access in activity feeds, follower lists, org members,
Actions run lists and packages needs a session or an `all`-scoped token.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-19 00:34:01 +00:00
ae17c14cff fix: add missing checks to several handlers and models (#39839)
Several handlers and model helpers skipped checks that their siblings
already perform.

- Only match principal keys when looking up SSH certificate principals
- Return no attachments for an unsaved issue instead of every issue-less
one
- Reject issue and comment attachments when adding release attachments
- Share one permission check for editing, deleting and reacting to issue
content and for comment attachments between the web UI and the API,
refusing them on locked issues for users who can't write
- Reject issue edits, deletion and label changes in archived
repositories via the API
- Apply cross-origin protection to the repository topics endpoint
- Return 404 for the repositories tab of individual users and respect
profile visibility for the heatmap

Fixes: https://github.com/go-gitea/gitea/issues/39226
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: bircni <bircni@icloud.com>
2026-10-18 06:29:49 -07:00
silverwind 1031e34987 test: run integration tests on random ports and speed up slow tests (#39842)
Integration test processes now get their own work directory, config file
and random ports, so several runs can execute in parallel on one
machine. The slowest tests also lose fixed sleeps and needlessly
expensive setup, with their assertions kept.

- Batch PostgreSQL sequence resets, the main per-test fixture cost there
- Cheap hashing params in hash and OAuth2 fixture tests, full-cost
vectors stay
- Single fetch for negative Actions runner assertions instead of 1s
polls
- Queue flushes and backdated timestamps instead of sleeps
- In-memory SQLite test journal, tmpfs for PostgreSQL in CI
- E2E instance writes SSH keys into its work directory instead of
`~/.ssh/authorized_keys`
2026-10-18 12:56:04 +00:00
13ddad6e07 enhance: allow custom watches to bypass on-mention email restriction (#39652)
Users with "Only Email on Mention" can now still receive email for the
events they picked in a custom repository watch, covering issues, pull
requests and releases. The setting is renamed to "Only Email on Mention
and Custom Watches" to make this explicit, matching GitHub's
"Participating, @mentions and custom".

"All activity" watches don't bypass the setting, because they are also
created automatically by `AUTO_WATCH_NEW_REPOS` for repository creators
and team members. To keep picking every event distinct from "All
activity", the custom watch dialog now stores a new `WatchModeCustom`.
Existing custom watches keep working without a migration.

## Screenshots
### Before
<img width="1650" height="675" alt="grafik"
src="https://github.com/user-attachments/assets/ecc56e20-cd05-41e9-a840-607b352c50a8"
/>

### After
<img width="1657" height="671" alt="grafik"
src="https://github.com/user-attachments/assets/a406db94-3ac4-4587-b840-0cd472b135c5"
/>


Addresses https://github.com/openSUSE/openSUSE-git/issues/183
Ref: https://github.com/go-gitea/gitea/issues/35492

---------

Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-10-18 09:23:12 +00:00
Jakub Vránaandwxiaoguang 31626de2a6 enhance(repo): prefill new issue and pull request sidebars from query parameters (#39804)
Links to the new issue and new pull request pages can preselect sidebar
values with the same query parameters as the issue list filters:
`labels`, `milestone`, `project` and `assignee`, each taking
comma-separated IDs, e.g. `compare/main...branch?labels=1,2&assignee=3`.
Previously, pull requests supported none of them and issues only
`milestone` and `project`. On the compare page they also expand the new
pull request form, like `title` and `body`. Query values take precedence
over issue template labels and assignees.

* Fix https://github.com/go-gitea/gitea/issues/27341

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-17 10:58:33 +00:00
3058f5ddf9 perf(actions): batch per-row queries in run, job and cancellation paths (#39723)
Several Actions code paths issued one or more queries per listed row.
They now load in batch, with unchanged output.

- API job list: tasks, steps and runners load in batch
- API run list: latest attempts and their trigger users load in batch
- Repository runs page: the jobs of all active runs load in one query
- Cancelling previous runs and replacing concurrency group entries fetch
their jobs in one query

Per call with 50 rows on SQLite, base vs head:

| Path | Queries | Time |
| --- | --- | --- |
| API job list | 254 → 6 | 12.9 → 1.9 ms |
| API run list | 305 → 207 | 11.7 → 6.2 ms |
| Runs page job loading | 100 → 1 | 6.5 → 0.47 ms |
| `CancelPreviousJobs` | 546 → 496 | ~120 ms, per-job writes dominate |

The remaining run list queries come from per-run repository conversion,
which this PR doesn't change.

---------

Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-10-17 09:47:17 +02:00
b015cd67e2 feat(repo): allow deleting protected branches (#39243)
This adds a Branch Deletion setting with three modes: disabled by
default, anyone with push access, or a restricted user/team/deploy-key
allowlist. The policy applies to Git pushes, API/UI deletion, and
post-merge cleanup; the default branch and the pull request target
branch remain undeletable.

Closes https://github.com/go-gitea/gitea/issues/33305

---------

Co-authored-by: Enoque Duarte <12515551+enoquefcd@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-14 07:19:49 +00:00
wxiaoguang c6e2513570 refactor: migrate protected branch fields into one json column and support system users (#39735)
1. migrate protected branch fields into one json column
2. use the dropdown list for push/force-push user selection, and Actions
user can be added into the list now.
2026-10-13 00:40:21 +00:00
wxiaoguang 0e32b4a362 fix: correct label deletion and release attachment load (#39743) 2026-10-13 01:27:40 +08:00
bircniandwxiaoguang 8a9e8c4e8c fix(actions): harden log cursor, activity type and actor filter handling (#39721)
Fixes a few Actions bugs where user input or nondeterminism caused
failures:

- The job log view indexed task steps with the client-supplied cursor
step without a bounds check, so an out-of-range value panicked and
returned a 500.
- Workflow activity type filters (`types:`) were compiled with
`glob.MustCompile`, so an invalid pattern in a workflow file panicked
during event detection. Invalid patterns now simply don't match.
- Listing workflow runs with an unknown `actor` returned a 500; it now
returns 404.
- The v4 artifact `ListArtifacts` response was built by ranging over a
map, so its order changed between calls. It now follows database order.
- The error from marshalling a workflow job when inserting run jobs was
silently ignored.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-10 19:52:23 +00:00
321d3ec104 refactor(actions): pass secret and variable scope as a struct (#39719)
Secret and variable functions took an adjacent `ownerID, repoID int64`
pair, so swapping the two compiled and only failed at runtime. They now
take a `BelongingScope` value instead.

`BelongingScope` also replaces the "drop OwnerID when RepoID is set"
step that `InsertEncryptedSecret` and `InsertVariable` each implemented
separately

No behaviour change. It also makes adding another scope dimension, such
as the environment ID in https://github.com/go-gitea/gitea/pull/38149, a
one-field change.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
2026-10-10 18:21:28 +00:00
wxiaoguang e60d1c7fc8 refactor: remove NotFoundOrServerError (#39727)
follow up #39722
2026-10-10 16:34:53 +02:00
c30ddc3e14 refactor(actions): small cleanups across models, services and routers (#39722)
Collection of small, behaviour-preserving cleanups in the Actions code.

- Fix log and error prefixes that named non-existent or wrong functions,
and wrap errors with `%w` so `errors.Is` keeps working.
- Remove unused code.
- Rely on `ctx.ServerError` / `ctx.APIErrorAuto`, which already map
`util.ErrNotExist` and friends, instead of equivalent hand-written
switches.
- Load runs referenced by commit statuses with one query instead of one
per run (used on every PR view); the result order is now stable.
- Encode an event's payload once instead of up to three times.
- Share the duplicated runner-token "get or create" logic and the
"notify and emit" call pair.
- Simplify `ToActionArtifact` / `ToActionRunner` signatures.

---------

Signed-off-by: bircni <bircni@icloud.com>
Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-10 12:55:28 +00:00
wxiaoguang cc623c5f2f refactor: clean up git migration forms (#39672)
Only extracted shared code, removed unnecessary code, and use
form-fetch-action to replace RenderWithErrDeprecated, slightly
refactored JS to use data-global-init

Nothing else is changed, although there are still many problems.

Written by AI

Diff with hiding spaces:
https://github.com/go-gitea/gitea/pull/39672/changes?w=1
2026-10-08 10:36:08 +02:00
wxiaoguang 26475404d4 fix: show "merge" form for empty PR (#39640)
fix #39637
2026-10-06 17:28:28 +00:00
Sergio Benitezandwxiaoguang 052f660ba5 fix(web): normalize content for edit history diff and fix comment history dropdown (#39616)
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-06 08:03:06 +00:00
4e2c3e43f2 fix(pull): fetch PR head refs instead of pushing them (#39603)
Creating a PR fetches the head commit into the base repo, then pushes
the same objects into `refs/pull/N/head`. Since git 2.54, background
repacks race that push:

1. The push can be rejected with "unable to migrate objects to permanent
storage", see
https://github.com/go-gitea/gitea/actions/runs/37171442185/job/111345034829.
2. For heads with 100+ new objects, the repack can delete the reused
pack, leaving the PR ref pointing at missing objects.

Fetching the head commit with `FetchRemoteTempCommit` and setting the PR
ref with `UpdateRef` avoids both, as the fetch transfers nothing when
the objects exist. Fork PR refs are now updated like AGit PR refs
already are, without going through receive hooks.

Also syncs the PR ref when a PR is reopened again.
https://github.com/go-gitea/gitea/pull/37077 inverted that condition, so
a reopened PR kept a stale ref.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: bircni <bircni@icloud.com>
2026-10-05 20:31:21 +02:00
silverwindandwxiaoguang 2705abf7f3 perf(citation): optimize CITATION.cff rendering (#39575)
Rendering a CITATION.cff could use memory far out of proportion to the
file, as every YAML alias copies its target into the formatted citation
and the parser copies `%TAG` prefixes into every node. Files past these
limits show no citation, like unparseable ones do today.

- Skip files over 256 KiB, largest real-world file found is 80 KiB
- Skip files with `%TAG` directives
- Skip files whose aliases add more than 64 Ki nodes and value bytes
- Skip self-referencing anchors, except a sequence listing itself

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-10-04 23:50:46 +00:00
Piyush Kumarandsilverwind a9ac8c0afd fix(label): sort labels by open issue count, not total (#39464)
The labels page shows open issue counts, but "Most issues" and "Least
issues" sorted by the total including closed issues, so a label with no
open issues could land in the middle of the list.

- Sort repository and organization labels by their open issue count
- Sort organization labels on a repository's labels page by their open
issues in that repository, which is the count they display

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

---------

Signed-off-by: piyush295 <mr.piyush295@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-10-04 08:48:18 +00:00
silverwind eb4468ff4e enhance!: raise minimum git version to 2.34 (#39565)
Raise the minimum git version to 2.34, the version in Ubuntu 22.04,
Debian 12 and RHEL 8 ship newer, and remove the fallbacks it makes
obsolete.

- Always enable AGit
- Use `diff --skip-to` and `apply -3` unconditionally
- Set the default branch of new repos and wikis via `git init
--initial-branch`
- Detect rebase conflicts via `REBASE_HEAD`
2026-10-04 16:26:14 +08:00
silverwind 2baa5a16f8 enhance(citation): render citations server-side (#39373)
Replace citation-js with a Go port of ruby-cff, which GitHub uses for
"Cite this repository", rendering APA and BibTeX server-side and
dropping about 770KB of JS. Output matches GitHub on 1568 of 1571
real-world files, the rest are improvements over GitHub.

- `CITATION.cff` wins over `CITATION.bib`, matched case-insensitively
and through symlinks
- `CITATION.bib` is offered as-is, without APA

Signed-off-by: silverwind <me@silverwind.io>
2026-10-03 02:28:34 +00:00
wxiaoguang 9b5c87a6b6 fix: trace git command correctly (#39520)
Help  #39410
2026-10-01 10:01:45 +00:00
a71c5c94c5 fix(actions): reject jobs without runs-on (#39480)
Align job and `runs-on` validation with github.com, as implemented by
the parser in https://github.com/actions/runner. A job without `runs-on`
could be claimed by any runner, so a job meant for a container could run
on the host.

- Jobs without `runs-on` fail with `Required property is missing:
runs-on`, called workflows included
- Unknown job keys and callers (`uses:`) mixed with steps-only keys like
`runs-on` are rejected
- Empty, null and nested `runs-on` values are rejected
- A `runs-on` evaluating to such a value fails only that job
- Called workflows are validated at run creation, an invalid one fails
the run as an invalid workflow file
- Zero labels (`runs-on: []` or `{}`) never match a runner, including
jobs queued before upgrading

<img width="960" alt="image"
src="https://github.com/user-attachments/assets/e746ce5a-b711-4e8b-aab8-81336ff53d86"
/>

**Behavior Change:** workflows that omit `runs-on`, use unknown job keys
or mix `uses` with `runs-on` stop running until fixed.

---------

Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-09-30 21:42:07 -06:00
silverwindandbircni 8936303510 fix: add missing checks to several API and web handlers (#39501)
Several handlers skipped checks that their sibling routes or settings already enforce. This brings them in line.

- Push mirror API honors `DISABLE_NEW_PUSH` and checks the caller's permission
- Media API serves small files with the usual content headers
- Issue attachment API ignores comment attachments
- Push-to-create respects `FORCE_PRIVATE`
- Profile feeds and follow actions respect `ENABLE_FEED` and owner visibility
- Tag delete route refuses release tags
- Refresh token grant only accepts refresh tokens
- Gitea migrations bound the source's page size

Co-authored-by: bircni <bircni@icloud.com>
2026-09-30 20:25:14 +02:00
JerryLienandwxiaoguang f365a6b9c8 fix(actions): keep runs order after auto refresh (#39479)
On a repository's Actions tab, runs are sorted newest first on initial
page load. After the first auto refresh (added in #38329, every 3
seconds while runs are active and every 12 seconds otherwise), the same
runs may appear in a different order and move again as their status
changes.

Example with four runs (Gitea 28.0.0, SQLite):

```
page load:     #10 success, #9 failure, #8 success, #7 running
after refresh: #8 success, #10 success, #9 failure, #7 running
```

To reproduce, open the Actions tab of a repository with runs in
different statuses and wait for an auto refresh. On SQLite, the runs may
be regrouped by status, with each group ordered oldest first.

`preparePartialRefreshRuns` reloads the runs currently shown on the page
using `GetRunsByRepoAndID`. That query has no `ORDER BY`, while the
initial page load uses `FindRunOptions.ToOrders` and sorts by index
descending.

With SQLite, the query planner used the `(repo_id, status)` index, so
the returned row order differed from the original page order. Since the
query has no explicit ordering, this behavior is database-dependent. I
have not tested MySQL or PostgreSQL.

This change orders `GetRunsByRepoAndID` by index descending, the same
order `FindRunOptions.ToOrders` uses for the initial page load. The
refresh only reloads the runs already on the page, so they come back in
the original order, with or without filters and on any page.

The other caller of `GetRunsByRepoAndID`, run approval, does not depend
on result ordering.

Testing:

- Added `TestPreparePartialRefreshRunsKeepsRequestedOrder`. Without the
fix, runs 794, 793, 792, 791 are returned as 791, 792, 794, 793; with
the fix, the test passes.
- `go test` passes for `./routers/web/repo/actions/`,
`./models/actions/` and `./services/actions/`.
- `go vet` and `golangci-lint v2.13.2` pass for the changed packages.
- Manually tested by building Gitea 28.0.0 with this patch and running
it on our SQLite instance. The runs list keeps its newest-first order
across auto refreshes. The official 28.0.0 binary reproduces the
reordering.

AI-assisted: drafted with Claude Code (claude-opus-5-5), reviewed by me.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-09-30 09:17:04 +02:00
silverwind 9e7b302bd3 enhance(actions): add pending job status and align job statuses with GitHub (#39376) 2026-09-27 18:30:42 +00:00
bircniandsilverwind f44e64be81 fix(actions): harden fork pull request run approval (#39399)
Fixes several gaps in the approval of fork pull request runs:

1. Approving a run that was cancelled while awaiting approval revived
its cancelled jobs. Such a run is no longer treated as awaiting approval
by the merge box, run page, approve actions and API, and rerunning it
approves it.
2. Approval no longer revives jobs cancelled while the run was pending,
no longer lets two jobs sharing a concurrency group cancel each other,
and re-emits the run so jobs needing a cancelled job get resolved.
3. An unapproved run applies its workflow-level concurrency only once
approved.
4. For workflows from the pull request, both the event actor and the
pull request author must be trusted to skip approval. Workflows from the
default branch, like `issue_comment`, still only check the actor.

---------

Co-authored-by: silverwind <me@silverwind.io>
2026-09-26 22:52:19 +00:00
wxiaoguang ea91028028 fix: PR merge (#39442)
* Revert the behavior introduced by #30805
* Now the PR status is still managed in Gitea's code where the operation
is triggerred but not in post-receive hook
* Fix #39254 and many more related bugs.
    * Fix #39124

```
// MarkAsMerged sets a pull request to merged and closes the corresponding issue
// To make sure the pull request is marked as merged correctly, the caller uses multiple-stage operations:
//  1. Create a temp repo from base, merge the head into the temp repo, and get the merged commit ID and timestamp,
//  2. The merged commit ID and related information are stored into pull request
//  3. Push the merged commit to the base repo
//  4. Call MarkAsMerged to mark the pull request as merged and do post-processing (notification, close issues, etc)
//
// If failure occurs in step 1/2/3: the pull request is still open, the base repo is not changed, the doer can start a new merge.
// If failure occurs in step 4: the pull request can be marked as merged by the merged commit ID stored in it later.
```
2026-09-26 17:38:42 +00:00
silverwind 4eebefbce5 fix: dedupe issue cross-reference timeline entries (#38881)
Removing and re-adding a mention, or changing `closes #1` to a plain
`#1`, added duplicate references to the issue's timeline.

The timeline now renders a single entry per referencing issue or pull
request, positioned at the first mention, like GitHub does.
2026-09-26 11:31:01 +00:00
3875db1974 feat(actions): add build queue view (#38585)
Adds a read-only Actions job queue: running jobs first, then waiting
jobs in the order a runner picks them up. It is shown instance-wide in
the admin Actions section with owner, repository and status filters, and
per repository in the Actions tab. Both lists refresh in place.

Pending work is currently only visible per repository and newest-first,
so nothing shows what is queued, in which order, or what occupies the
runners. Reordering the queue will be proposed separately.

A migration adds indexes for the runner pickup query and
repository-scoped status lookups.

* Fix #34198

<img width="1345" height="451" alt="image"
src="https://github.com/user-attachments/assets/7d52ff76-81b4-44e8-b583-d7d89c9dffcd"
/>
<img width="1809" height="1134" alt="image"
src="https://github.com/user-attachments/assets/4d56c0cb-bae7-4ce2-8f3c-75163b2bc7f4"
/>

---------

Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-09-26 08:01:41 +00:00
5a56e118e4 feat(actions): Add artifact preview in Actions run view (#36754)
Closes https://github.com/go-gitea/gitea/issues/33579.

Adds browser previews for Actions artifacts. Selecting an artifact opens
its file browser; selecting a file renders it in the same tab. The ZIP
download remains available separately.

Previews require sign-in and read access to the run. Text, image and PDF
files are supported; rendered HTML and JavaScript run in a sandboxed
frame and are labeled as automatically generated. The frame loads files
from a signed link that expires after an hour, because its requests
carry no session cookie. `[actions] ARTIFACT_PREVIEW_MAX_SIZE` limits
total previewable artifact size (`0` disables previews; `-1` removes the
limit); individual files also follow `[ui] MAX_DISPLAY_FILE_SIZE`.

<img width="1803" height="913" alt="image"
src="https://github.com/user-attachments/assets/a38fd704-2244-44fa-9181-c695ecbe0276"
/>

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

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
2026-09-26 07:42:36 +00:00