Commit Graph

21459 Commits

Author SHA1 Message Date
bircni 55a5f50961 fix(actions): enforce workflow badge token scope (#39044)
Apply repository token-scope and public-only checks to workflow badges.

---------

Co-authored-by: silverwind <me@silverwind.io>
2026-08-23 06:59:58 +00:00
bircni 204c0bafd3 fix(repo): require organization owners for team access (#39046)
Require organization ownership before changing repository team
associations when team access is restricted.

---------

Co-authored-by: silverwind <me@silverwind.io>
2026-08-23 06:35:55 +00:00
bircni bedd2afb47 fix(org): hide limited organizations from restricted users (#39047)
Do not expose limited organization memberships to restricted viewers.

---------

Co-authored-by: silverwind <me@silverwind.io>
2026-08-22 23:11:04 -07:00
GiteaBot d8f0e7e679 [skip ci] Updated translations via Crowdin 2026-08-23 00:24:38 +00:00
Federico A. Corazza 1fa6465efd feat(actions)!: add RUN_RETENTION_DAYS to delete old action runs (#38855)
Gitea keeps completed Actions runs forever. Artifacts and logs expire on
their own schedule, but the run rows never go away, so `action_run` and
its child tables grow without bound.

Adds `RUN_RETENTION_DAYS` to delete completed runs along with their
jobs, tasks and anything the earlier expiries left behind. It defaults
to 400 days, matching how long GitHub keeps run history browsable. A
dedicated `cleanup_action_runs` cron task performs the cleanup, so
admins can schedule it separately from the nightly artifact and log
sweep.

`0` now means "keep forever" for all three retention settings, where
`LOG_RETENTION_DAYS` and `ARTIFACT_RETENTION_DAYS` previously took it
literally and deleted everything at the next sweep.

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

----

## ⚠️ BREAKING ⚠️

`RUN_RETENTION_DAYS` defaults to 400, so completed runs older than that
are deleted when the cron task next runs at midnight. Set
`RUN_RETENTION_DAYS = 0` before upgrading to keep all runs.

---------

Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-08-22 21:32:59 +00:00
bircni e6af4c341c fix(repo): preserve transfer recipient collaboration (#39042)
Remove temporary recipient access after a transfer ends while preserving
existing collaboration.

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-08-22 19:43:42 +00:00
bircni 9251eeb66b fix(markup): enforce same-repository issue access (#39045)
Enforce Issues and Pull Requests access for references within the
current repository.

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-08-22 19:13:53 +00:00
bircni 5fc3cec87f fix(actions): verify raw artifact signatures first (#39049)
Validate raw-artifact signatures before resolving the requested
artifact.

---------

Co-authored-by: silverwind <me@silverwind.io>
2026-08-22 18:47:55 +00:00
water 51e42d4b11 fix: drop queued job updates for deleted runs instead of requeueing forever (#39037)
When a repository is deleted while one of its Actions runs still has a
pending job update in the emitter queue, `checkJobsByRunID` returns an
error because the run no longer exists. The queue handler in
`jobEmitterQueueHandler` treats every error as unhandled and requeues
the item, creating an infinite retry loop that fills the log with error
messages.

### Changes

1. **`services/actions/job_emitter.go`** — swap the `!exist`/`err` check
order so a database error is reported first, then treat a non-existent
run as handled (nil error). The queue consumer drops the item instead of
requeueing it.

2. **`services/actions/job_emitter_test.go`** — add
`Test_checkJobsByRunID_DeletedRunIsHandled`, which verifies that a
deleted run produces nil (handled, not requeued).

### Related issue

Fixes #39034

---------

Co-authored-by: bircni <bircni@icloud.com>
2026-08-22 13:55:08 +00:00
silverwind 66d6f74cb0 test: speed up tests, fix transaction bug (#39030)
Speed up tests: `make test-backend` 103s to 37s, `make test-integration`
908s to 852s.

Most of it is a detached system notice insert blocking on the SQLite
write lock until the busy timeout expired, and `ExternalServiceHTTP`
re-probing on every call with an untimed `http.Get`.

- fixed one correctness bug with nested transactions: files were deleted
while the outer transaction was open, so a later failure could roll the
database back with the files gone
- git push branch counts were far above the hook batch size
- Fix makefile dependencies so running tests and lint work in fresh
worktrees.

---------

Co-authored-by: Giteabot <teabot@gitea.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-08-22 11:04:35 +00:00
Lunny Xiao 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
bircni 89c7019a3c fix(repo): limit gitignore template selections (#39027)
Bound gitignore template selections at both web and API request
boundaries before repository initialization.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-08-22 10:03:17 +00:00
SEONGHYUN HONG 84b67d50a6 fix(base): correct natural sort of numbers with leading zeros (#38163)
### Description

`NaturalSortCompare` (`modules/base/natural_sort.go`) compares two
numeric run parts by **raw string length**:

```go
if len(part1) != len(part2) {
    return len(part1) - len(part2)
}
```

"Longer digit string = larger number" only holds without leading zeros.
With zero-padded numbers the comparison inverts:

- `file0001` vs `file2` → claims `file0001 > file2`, but `1 < 2`
- `a08` vs `a9` → claims `a08 > a9`, but `8 < 9`

This affects any natural-ordered listing where zero-padded and shorter
unpadded numbers mix (branch/tag/file names, etc.).

### Fix

Strip leading zeros before comparing digit-count magnitude; on equal
magnitude fall back to collation, then to the original length so fewer
leading zeros sort first. Added a small `naturalSortTrimZeros` helper
(keeps one char so `"000"` → `"0"`).

Signed-off-by: Seonghyun Hong <s3onghyun.hong@gmail.com>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-08-22 09:40:49 +00:00
silverwind fa0b39a42b fix(release): separate publication time from the release date (#36761)
`published_at` was an alias for `created_at`, so a release created from
an existing tag reported that tag's commit date as its publication time,
and drafts reported one despite never having been published. It is now
stored separately, set when a release is published and null for drafts.

`created_at` in turn means the date of the commit the release points at,
matching what GitHub documents it to be, and the latest release is
selected by it again. Publishing a release for an old commit no longer
takes over the latest badge, and a tag created in the web UI is dated
the same way as one pushed from the CLI.

Fixes https://github.com/go-gitea/gitea/issues/11206
Fixes https://github.com/go-gitea/gitea/issues/38714
Fixes https://github.com/go-gitea/gitea/issues/31789

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-08-22 08:59:37 +00:00
bircni 6bb6ce678b fix(api): hide limited users from restricted viewers (#39004)
Use the canonical profile-visibility check for user API content and
prevent restricted users from enumerating public repositories owned by
limited users.

This keeps feeds, heatmaps, keys, and issue search consistent with
profile visibility.

---------

Co-authored-by: silverwind <me@silverwind.io>
2026-08-22 08:08:36 +00:00
Lunny Xiao 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
silverwind 2d6fea5bdf enhance: add permalinks to pull request reviews (#38849)
1. Make review threads linkable via `#pullrequestreview-<reviewID>`
2. Improve CSS so username and timestamp go colored on hover.
3. CSS cleanup, remove dead rules, nonexistant class name, make `.suppressed` actually do what it says in the doc above.
2026-08-22 02:13:43 +00:00
bircni 1f349eb1eb fix(migrations): cancel GitLab version probes (#39023)
Bind the GitLab version probe to the migration context so a cancelled
migration does not remain blocked on a remote response.
2026-08-22 01:54:07 +00:00
wxiaoguang d2bc0097bc fix: make local queue PopItem can be notified (#39011) 2026-08-22 01:30:41 +00:00
bircni 5eba4f92ce fix(migrations): bound OneDev version responses (#39024)
Limit OneDev version responses before parsing so a remote server cannot
make a migration retain an unbounded response.
2026-08-22 00:54:20 +00:00
bircni aa96725ae7 fix(packages): limit Swift package manifests (#39025)
Bound the number and aggregate size of Swift manifests retained from an
uploaded archive.
2026-08-22 00:11:29 +00:00
bircni fa4c0b1cf6 fix(packages): limit Maven checksum uploads (#39028)
Bound checksum uploads to the maximum usable digest length before
buffering their content.
2026-08-21 23:41:12 +00:00
bircni 2b81cbbe70 fix(packages): bound Alpine metadata entries (#39026) 2026-08-22 01:17:04 +02:00
bircni ad05aaee80 fix(actions): enforce fork pull request trust boundaries (#39005)
Preserve fork pull request restrictions across review-triggered
workflows, reusable workflow access, job scheduling, and filtered
workflow statuses.

This prevents untrusted fork workflow content from bypassing approval,
accessing private reusable workflows, or satisfying protected status
checks.


_Assisted-by: Codex:GPT-5_
2026-08-21 12:35:28 +00:00
bircni a52e5f53c0 fix(git): restrict hook permissions (#39008)
Create delegate hook files and directories without group or other write
access, including correcting existing hook directories.

_Assisted-by: Codex:GPT-5_
2026-08-21 07:52:23 +00:00
bircni db24633e6d fix(api): enforce repository creation token authorization (#39007)
Reject public-only tokens for repository migrations and require
repository scope for canonical organization repository creation. This
aligns both routes with the existing token authorization boundaries.

_Assisted-by: Codex:GPT-5_
2026-08-21 07:28:23 +00:00
bircni 920b5f1e68 fix(api): enforce public-only scope for compare heads (#39006)
Enforce public-only token scope for repositories resolved as compare
heads.

_Assisted-by: Codex:GPT-5_
2026-08-21 07:06:56 +00:00
bircni 7306d5aff8 fix(repo): hide repositories of hidden owners (#39009)
Exclude public repositories owned by hidden individual accounts from
broad repository listings, while preserving visibility through explicit
access and ownership.

_Assisted-by: Codex:GPT-5_
2026-08-21 06:32:57 +00:00
GiteaBot fcc23af280 [skip ci] Updated translations via Crowdin 2026-08-21 01:49:11 +00:00
Julian Scholle fe567d26c1 fix(actions): allow larger scheduled workflows (#38985)
MySQL stores `action_schedule.content` as `BLOB`, limiting scheduled
workflow definitions to 65,535 bytes. Oversized workflows fail schedule
refresh and can also suppress default-branch push handling.

Store scheduled workflow content as `LONGBLOB`, migrate existing MySQL
columns, and cover the migration by persisting 65,536 bytes.

Fixes https://github.com/go-gitea/gitea/issues/38613
2026-08-21 01:06:44 +02:00
bircni ffd982c7ab fix(actions): show "Complete job" logs when the last step is skipped (#38939)
`FullSteps` only gave the synthetic "Complete job" step the remaining
log range when the last step that had run was also the final step of the
job. A skipped step does not count as having run, so any job ending in a
skipped step left the post step with an empty range: its logs were
stored but never rendered, and the duration showed as `0s`.

Reproducible with any job whose last step is skipped, which is common
for failure notifications:

```yaml
steps:
  - run: echo hello
  - run: echo never
    if: failure()
```

The gate now checks whether the final step is done, which preserves the
behaviour from https://github.com/go-gitea/gitea/pull/29926 of showing
the post step as waiting while steps are still pending.
--> Regression from https://github.com/go-gitea/gitea/pull/29926

---------

Signed-off-by: bircni <bircni@icloud.com>
2026-08-20 19:06:21 +00:00
Lunny Xiao 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
wxiaoguang 943f026844 refactor: deploy key and private route handlers (#38999)
clean up legacy code, fix various bugs:

* add missing "return"
2026-08-20 15:57:17 +00:00
silverwind 61be9fcdfa chore: update eslint and stylelint configs and re-sync modern-normalize (#38982)
- update the vendored `modern-normalize` to v3.0.1
- require descriptions for lint disables in TS and CSS, same as we
already have in Go.
- disable core rules covered by `regexp/*` and `unicorn/*`, and ones
that cannot fire
- stop applying vitest rules to the playwright files in `tests/e2e`
- enable 7 stylelint rules, mostly `no-unknown` and `no-invalid` checks
- drop 2 unnecessary vendor prefixes (safari v17+, chrome v120+)
- look up ids via `querySelector` with `CSS.escape` instead of
`getElementById`
- remove stale doc about `@ts-expect-error`, it's forbidden
- misc dev doc fixes

Every declaration that `modern-normalize` v3 removes was checked against
chromium, webkit and firefox defaults first. The `hr` color and the
`:-moz-focusring` outline are kept as documented deviations, dropping
those does change rendering.

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-08-20 09:57:56 -04:00
wxiaoguang c778c6c920 enhance: use browser's locale to detect week's first day for the contribution map (#38995)
fix #6058

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: silverwind <me@silverwind.io>
2026-08-20 07:10:15 +00:00
bn-zr fa5d876171 fix(actions): Fix how jobs in matrixes are grouped (#38980)
The workflow graph decided which job rows belonged to the same matrix by
parsing display names: it stripped a trailing `" (...)"` off `name` and
grouped rows sharing the prefix. That guesses at a string the user
controls, and it fails both ways. `jobparser` only appends the `
(<combination>)` suffix when `name:` contains no `${{ }}`, so a leg
named `E2E on ${{ matrix.browser }}` never grouped, while two unrelated
jobs `build (fast)` and `build (slow)` folded into one bogus matrix
panel.

Matrix legs already have a real identity: expansion clones one row per
combination, all sharing the workflow's `JobID` and differing only in
`Name`. Group on that instead, so a matrix is whatever the backend says
it is. Matrix expansion state is keyed on the graph node id for the same
reason.

Closes https://github.com/go-gitea/gitea/issues/38975, though that
report's own example already groups on main, since `explicit (${{
matrix.leg }})` interpolates to a name that still ends in a suffix. The
interpolated shapes above are the broken ones.

Assisted-by: Claude Code:claude-opus-5
Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-08-20 05:41:14 +00:00
silverwind 8f7eb9f161 enhance(ui): forced colors mode enhancements (#38991)
Improve various UI elements while in [forced color
mode](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/forced-colors).
2026-08-20 05:11:57 +00:00
silverwind ed4d7ea08d fix: resolve YAML anchors and aliases in Actions workflows (#38984)
Workflows using YAML anchors are rejected as invalid, because a workflow
is split into one document per job and an alias whose anchor lands in
another job's document no longer resolves.

Aliases are now expanded once, right after the workflow is parsed and
before anything reads or splits it, bounded like GitHub's parser so
nested aliases cannot expand without limit. Merge keys stay unsupported,
as they are upstream.

Fixes https://github.com/go-gitea/gitea/issues/38983
Signed-off-by: silverwind <me@silverwind.io>
2026-08-20 05:03:10 +00:00
GiteaBot 89b891b168 [skip ci] Updated translations via Crowdin 2026-08-20 01:44:24 +00:00
Iaroslav 35786a6ca1 fix(lfs): ensure lock listing paginates with a total order (#38850)
`GetLFSLockByRepoID` applies `LIMIT`/`OFFSET` to a query with no `ORDER
BY`. The order of such a query is unspecified (according to the SQL
standard), so the resulting queryset might be inconsistent.

These locks AFAIK are never updated, so in practice the order is
insertion-based, but that's not guaranteed.
2026-08-19 11:54:21 -07:00
silverwind 4e813a262f fix: resolve actions commit status permission per repository (#38977)
Various pages did not display the correct action run list tooltips. Fix
those tooltips like here on the `/pulls` page:

`ctx.Repo.Permission` is the zero value outside a repository route, so
on `/pulls`, `/issues`, `/notifications/subscriptions` and the dashboard
repo list the commit status "Details" link was always stripped. The live
job status is looked up from that target URL, so running checks also
rendered as a static pending dot instead of a spinner.

Resolve the Actions unit permission per repository instead.

Also drops the releases page's gate on *loading* statuses, which hid
external CI results from anyone without Actions read; it now loads them
and hides only the URL, like every other page.

Co-authored-by: bircni <bircni@icloud.com>
2026-08-19 20:09:00 +02:00
Giteabot e355c39e91 chore(deps): update dependency go to v1.26.7 (#38987) 2026-08-19 16:32:52 +00:00
wxiaoguang f261adb53f chore: form binding trim space (#38978)
Use "binding:TrimSpace" instead of fragile IsEmptyString

And fix a bug in locale's `HasKey`: it should also try the default
language if current language doesn't have the translation key, a new
test is added.
2026-08-19 12:50:06 +00:00
APZN c121f02a7e fix: honor environment variables during install (#38974)
Environment variables must be applied to the "install form" config
before the config values are used.

Fixes #38911

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-08-19 15:19:49 +08:00
wxiaoguang 6904f6480c refactor: http request binding (#38971)
Better than before, still not good enough (more work can be done in the
future)

And add the missing error handling in the PrivateContext "bind"
middleware.

By the way, picked some "TrimSpace" changes from "fix: trim whitespace
from SMTP address and port - #38934" (fix #38926)
2026-08-19 14:15:42 +08:00
GiteaBot 6c425fae6e [skip ci] Updated translations via Crowdin 2026-08-19 01:45:26 +00:00
wxiaoguang 5433c23dec enhance(ui): tint toast backgrounds by level (#38919)
Toasts now use the same tinted backgrounds and borders as the flash
messages, replacing the solid full-color style. The first commit reverts
https://github.com/go-gitea/gitea/pull/38842, the second re-applies it
with tinting.

---------

Co-authored-by: silverwind <me@silverwind.io>
2026-08-18 21:13:30 +02:00
silverwind 83af7aa92e ci: improve caching (#38958)
- only `cache-seeder` writes caches, every other workflow restores.
Saves were being rejected once the repo went over its cache budget,
leaving main's caches stale and PR runs building cold
- seed the pnpm store and uv caches next to the go ones, so PRs
warm-start on them rather than installing from scratch
- prune keeps a single generation per key, including across go versions,
where a toolchain bump leaves the previous build cache unusable.
Reclaims ~2.6 GB immediately
- prune runs every 6h instead of daily and trims to 6 GB, since CodeQL
writes ~200 MB per push to main from outside this repo's workflows
- pull requests and release branches no longer write pnpm, uv and binfmt
caches, whose ref-scoped copies are never read again

---------

Signed-off-by: silverwind <me@silverwind.io>
2026-08-18 18:26:03 +00:00
wxiaoguang c95e3f3b00 refactor: private endpoints (#38964)
1. remove dead code (SetDefaultBranch)
2. remove useless and unsafe code (AddLogger)
2026-08-18 08:51:47 +00:00
water c082b9a5ff fix: grant limited-org unit read access to authenticated non-members (#38871)
Fixes #38870

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-08-18 06:58:37 +00:00