Compare commits

...

848 Commits

Author SHA1 Message Date
petru 43c8d014e8 Modified - [scripts] [configure] [git-lfs] Added conditional Git LFS setup to configure.sh when repository LFS hooks are installed.
release-nightly / nightly-binary (push) Has been cancelled
release-nightly / nightly-container (push) Has been cancelled
release-tag-version / binary (push) Has been cancelled
release-tag-version / container (push) Has been cancelled
- 1 - I updated `.configure.sh` so repositories that already have Git LFS hook scripts in `.git/hooks` now treat `git-lfs` as a required dependency during verification, install the `git-lfs` system package on supported package managers, and run `git lfs install --local` during non-verify setup.

(cherry picked from commit b66ec8c19d)
2026-05-20 00:32:29 +03:00
petru c2a0fe8c51 Modified - [scripts] [smart-build] [darwin] Added macOS amd64/arm64 smart-build support, including SQLite-aware Docker-host handling for containerized workspaces.
- 1 - I updated `smart-build.sh` so its interactive architecture menu now offers `macos-amd64`, `macos-arm64`, and includes both Darwin targets in `All Arch`, while preserving the existing `darwin` artifact naming in `dist/`.
- 2 - I added a dedicated Darwin SQLite build path in `smart-build.sh` that routes macOS `bindata sqlite sqlite_unlock_notify` builds through `make release-darwin`, and I updated `Makefile` to make `release-darwin` configurable through `DARWIN_ARCHS` so helper scripts can request only `darwin-10.12/amd64` or `darwin-10.12/arm64`.
- 3 - I hardened the Darwin SQLite flow in `smart-build.sh` for `code-server`-style containerized workspaces by distinguishing between a missing Docker CLI and an unreachable Docker daemon, by validating that the host Docker daemon can see the same mounted repository `go.mod` path as the current workspace, and by moving the temporary release output under `dist/` instead of `/tmp`.
- 4 - I added `SMART_BUILD_DARWIN_HOST_REPO_PATH` support to `smart-build.sh` so Darwin SQLite builds can be redirected to a host-visible repository mount path when the interactive workspace path inside the container differs from the real host path used by the Docker daemon.

(cherry picked from commit 06e5bd7f46)
2026-05-20 00:30:57 +03:00
petru 379da5c828 Updated CHANGELOG for v1.26.1-by-petru - [docs] [changelog] [github-links] Added explicit GitHub links for the remaining bare PR references in CHANGELOG.md for the v1.26.1-by-petru release notes.
release-nightly / nightly-binary (push) Has been cancelled
release-nightly / nightly-container (push) Has been cancelled
release-tag-version / binary (push) Has been cancelled
release-tag-version / container (push) Has been cancelled
- 1 - I updated the remaining bare `#NNNNN` pull-request references in `CHANGELOG.md` so they now point directly to `https://github.com/go-gitea/gitea/pull/...`, without folding this tag-specific changelog cleanup into the earlier generic changelog-link conversion entry.

(cherry picked from commit 2d228475fc)
2026-05-18 10:23:47 +00:00
silverwind 5772454b31 Stabilize e2e logout propagation test (#37408)
Backport of #37403 to `release/v1.26`.

The `events › logout propagation` e2e test was racing the SSE connection
setup: if page2's SharedWorker had not finished registering its
messenger by the time page1 triggered logout, the event was silently
dropped and page2 stayed on the authenticated page.

Wait 500ms after verifying page2 is signed in, before triggering the
logout from page1, so the SharedWorker has time to register. Comment
points at a cleaner future fix (expose a ready attribute on the page)
that will also work for the planned WebSocket SharedWorker.

---
This PR was written with the help of Claude Opus 4.7

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
(cherry picked from commit 64d12024d65c5f343f4ae89ea9a6f6ed5616ef82)
(cherry picked from commit a6b0bd9755)
2026-05-18 10:03:48 +00:00
Giteabot 4c47020d37 fix: dump with default zip type produces uncompressed zip (#37401) (#37402)
Backport #37401

Fix #37393

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: wxiaoguang <2114189+wxiaoguang@users.noreply.github.com>
(cherry picked from commit 6cc1ee9424c61b234987a7e0b72f8d82ae78f2ff)
(cherry picked from commit 5ad76cda47)
2026-05-18 10:03:40 +00:00
Giteabot c95a092b4c Fix repo init README EOL (#37388) (#37399)
Backport #37388 by @wxiaoguang

Fix #27120

By the way, refactor ReserveLineBreakForTextarea to NormalizeStringEOL

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit 5d7768f34ca7d100823a2ced855c288409478690)
(cherry picked from commit ef0e2ecdc1)
2026-05-18 10:03:31 +00:00
Giteabot bfac06111e Fix org team assignee/reviewer lookups for team member permissions (#37365) (#37391)
Backport #37365 by @pisarz77

Fix team members missing from assignee list when `team_unit.access_mode`
is 0 but the doer is owner.

Fix  #34871

1. Use `GetTeamUserIDsWithAccessToAnyRepoUnit` for repo assignee list
2. Load assignee list for project issues directly
3. Use `GetTeamUserIDsWithAccessToAnyRepoUnit` for repo reviewer list

Signed-off-by: Jakub Pisarczyk <pisarz77@gmail.com>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: pisarz77 <pisarz77@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
(cherry picked from commit 55a6cfe79b57a42b0ae279fa5c7a5f261d7823eb)
(cherry picked from commit 7ed64f3c94)
2026-05-18 10:03:20 +00:00
Giteabot a02e97d52b fix: commit status reporting (#37372) (#37386)
Backport #37372 by @bircni

Fixes the issue that status report always shows waiting to run, when
already running

https://github.com/go-gitea/gitea/issues/36906#issuecomment-4294545813

Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
(cherry picked from commit 1f643072c18bf924ec131e7fc059397704a659fe)
(cherry picked from commit 8ba8b9cde4)
2026-05-18 10:03:11 +00:00
Giteabot fe0ccc2806 Fix button layout shift when collapsing file tree in editor (#37363) (#37375)
Backport #37363 by @bytedream

---
old:

https://github.com/user-attachments/assets/136a9ce8-f229-4583-bf19-75258d085513

new:

https://github.com/user-attachments/assets/21b7c885-00f4-4295-9191-07b66ca58b64

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: bytedream <me@bytedream.dev>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit 028045535689d2c5f0d100f3fb928a7f11df3c84)
(cherry picked from commit f50a9158aa)
2026-05-18 10:03:00 +00:00
Giteabot 792d0dd224 Add URL to Learn more about blocking a user. (#37355) (#37367)
Backport #37355 by @PineBale

Closes #29992

<img width="1308" height="828" alt="1"
src="https://github.com/user-attachments/assets/552c2e0f-8da6-4f71-8660-8e3f5a78ace5"
/>

Co-authored-by: PineBale <272794187+PineBale@users.noreply.github.com>
(cherry picked from commit a8e465e893b6efe0184e68f2e6dfaeb3e60c5678)
(cherry picked from commit 73a4930fc3)
2026-05-18 10:02:47 +00:00
Giteabot 28a8361033 fix: use TriggerEvent instead of Event in workflow runs API response for scheduled runs (#37288) (#37360)
Backport #37288 by @KalashThakare

## Summary

Fixes #37252

The `/api/v1/repos/{owner}/{repo}/actions/runs` endpoint was returning
`event: "push"` for workflow runs triggered by `schedule:` (cron),
instead
of `event: "schedule"`.

## Root Cause

`ActionRun` has two separate fields:
- `Event` — the workflow registration event (e.g. `push`, set when the
workflow file was first pushed)
- `TriggerEvent` — the actual event that triggered the run (e.g.
`schedule`)

`ToActionWorkflowRun` in `services/convert/action.go` was serializing
`run.Event` into the API response instead of `run.TriggerEvent`, causing
scheduled runs to be indistinguishable from push events via the API.

This was already asymmetric — the tasks/jobs API correctly used
`TriggerEvent`.

## Fix

Changed `ToActionWorkflowRun` to use `run.TriggerEvent` for the `event`
field in the API response, consistent with how the jobs API works.

## Before

`event: "push"` returned for all scheduled runs:

<img width="1112" height="191" alt="Screenshot 2026-04-19 115642"
src="https://github.com/user-attachments/assets/c0a169f5-bbd9-4f5d-9474-e4c3795110e4"
/>

## After

`event: "schedule"` correctly returned for scheduled runs:

<img width="890" height="166" alt="Screenshot 2026-04-19 121723"
src="https://github.com/user-attachments/assets/860e99ac-0935-4a43-86a1-7b60f8113480"
/>

## Testing

- Added unit test `TestToActionWorkflowRun_UsesTriggerEvent` in
  `services/convert/action_test.go` that explicitly verifies the API
  returns `TriggerEvent` and not `Event` for a scheduled run.
- Manually verified via the API against a live Gitea instance with a
  `cron: "* * * * *"` workflow.

Co-authored-by: Kalash Thakare ☯︎ <kalashthakare898@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
(cherry picked from commit fc9dfe0e56a84f2eb8e389d364f2da0b9c24d917)
(cherry picked from commit 836d451d6a)
2026-05-18 10:02:33 +00:00
Giteabot fca2db6c11 Add event.schedule context for schedule actions task (#37320) (#37348)
Backport #37320 by @lunny

Fix #35452

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
(cherry picked from commit 0916039c2a54f4a6f2139558792b476edece48a5)
(cherry picked from commit e5d2c03f39)
2026-05-18 10:02:03 +00:00
Giteabot e91a744803 Fix an issue where changing an organization’s visibility caused problems when users had forked its repositories. (#37324) (#37344)
Backport #37324 by @lunny

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: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit 291f6cbd3abfd0ffb6a9d70efb2d943e581ff257)
(cherry picked from commit f31163e6de)
2026-05-18 10:01:50 +00:00
Giteabot e929533398 Use modern "git update-index --cacheinfo" syntax to support more file names (#37338) (#37343)
Backport #37338 by @wxiaoguang

Modern syntax was added in git 2.0

And add more tests

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit f536bcd5084a9fb1864977b90a86e206ca6e6f5d)
(cherry picked from commit a5b92e70ab)
2026-05-18 10:01:42 +00:00
Giteabot f278b9697b Fix URL related escaping for oauth2 (#37334) (#37340)
Backport #37334 by wxiaoguang

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit fc4296a21a1fe55104581fd590b1bcb073bd9f92)
(cherry picked from commit a3e5814a12)
2026-05-18 10:01:31 +00:00
Giteabot 0b4e05fcb3 When the requested arch rpm is missing fall back to noarch (#37236) (#37339)
Backport #37236 by chethenry

This fixes: https://github.com/go-gitea/gitea/issues/37235

It uses the same changeset alpine packages got in:
https://github.com/go-gitea/gitea/issues/26691

Co-authored-by: chethenry <henry@visionlink.org>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit 657ea10cf19c4525836a16e9874d4d0d7fa12b8f)
(cherry picked from commit 4f2bffba44)
2026-05-18 10:01:16 +00:00
Giteabot b67937faf1 fix(oauth): Error on auth sources with spaces (#37327) (#37332)
Backport #37327 by @prettysunflower

Nyallo~

In pull request #36901, a change is made so that the link to
authentication sources is now escaped with the QueryEscape filter.
https://github.com/go-gitea/gitea/pull/36901/changes#diff-34c39c9736a8b62e293c0c0b24c4b5b8c1c792790018c5809f9ff2cbc12b16b1R4

The problem is that [QueryEscape replace spaces with the `+`
character](https://cs.opensource.google/go/go/+/refs/tags/go1.26.2:src/net/url/url.go;l=234;drc=917949cc1d16c652cb09ba369718f45e5d814d8f),
and this is not unescaped when a user tries to log in with an
authentication source that contains a space, which throws an error.

This commit fixes that by unescaping the provider name in the URL.

---

Example of the error, on my instance, when I try to log in with
`prettysunflower's auth`
```
2026/04/21 00:11:41 routers/web/auth/oauth.go:42:SignInOAuth() [E] SignIn: oauth2 source not found, name: "prettysunflower's+auth"
	/go/src/code.gitea.io/gitea/routers/web/auth/oauth.go:42 (0x2cfa5c5)
	/usr/local/go/src/reflect/value.go:586 (0x51e245)
	/usr/local/go/src/reflect/value.go:369 (0x51d0f8)
	/go/src/code.gitea.io/gitea/modules/web/handler.go:181 (0x1a6aaf6)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/src/code.gitea.io/gitea/modules/web/handler.go:188 (0x1a6ab65)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/src/code.gitea.io/gitea/modules/web/handler.go:188 (0x1a6ab65)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/src/code.gitea.io/gitea/modules/web/handler.go:188 (0x1a6ab65)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/src/code.gitea.io/gitea/services/context/context.go:217 (0x2df1b23)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/src/code.gitea.io/gitea/modules/web/handler.go:145 (0x1a6afb5)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/pkg/mod/gitea.com/go-chi/session@v0.0.0-20251124165456-68e0254e989e/session.go:258 (0x197eb82)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/src/code.gitea.io/gitea/modules/web/handler.go:145 (0x1a6afb5)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/pkg/mod/github.com/go-chi/chi/v5@v5.2.5/chain.go:31 (0x1a61d05)
	/go/pkg/mod/github.com/go-chi/chi/v5@v5.2.5/mux.go:479 (0x1a64fae)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/pkg/mod/github.com/go-chi/chi/v5@v5.2.5/mux.go:73 (0x1a628c2)
	/go/pkg/mod/github.com/go-chi/chi/v5@v5.2.5/mux.go:321 (0x1a6421a)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/pkg/mod/github.com/go-chi/chi/v5@v5.2.5/chain.go:31 (0x1a61d05)
	/go/pkg/mod/github.com/go-chi/chi/v5@v5.2.5/mux.go:479 (0x1a64fae)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/pkg/mod/github.com/go-chi/chi/v5@v5.2.5/middleware/get_head.go:37 (0x2c33a67)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/src/code.gitea.io/gitea/modules/web/handler.go:145 (0x1a6afb5)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/pkg/mod/github.com/go-chi/chi/v5@v5.2.5/mux.go:73 (0x1a628c2)
	/go/pkg/mod/github.com/go-chi/chi/v5@v5.2.5/mux.go:321 (0x1a6421a)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/src/code.gitea.io/gitea/routers/common/maintenancemode.go:50 (0x2b752da)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/src/code.gitea.io/gitea/modules/web/handler.go:145 (0x1a6afb5)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/pkg/mod/github.com/go-chi/chi/v5@v5.2.5/chain.go:31 (0x1a61d05)
	/go/pkg/mod/github.com/go-chi/chi/v5@v5.2.5/mux.go:479 (0x1a64fae)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/src/code.gitea.io/gitea/modules/web/routing/logger_manager.go:124 (0x127d1ec)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/src/code.gitea.io/gitea/modules/web/handler.go:145 (0x1a6afb5)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/pkg/mod/github.com/chi-middleware/proxy@v1.1.1/middleware.go:37 (0x2b76acf)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/src/code.gitea.io/gitea/modules/web/handler.go:145 (0x1a6afb5)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/src/code.gitea.io/gitea/routers/common/middleware.go:89 (0x2b78cd6)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/src/code.gitea.io/gitea/modules/web/handler.go:145 (0x1a6afb5)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/src/code.gitea.io/gitea/routers/common/middleware.go:104 (0x2b7890f)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/src/code.gitea.io/gitea/modules/web/handler.go:145 (0x1a6afb5)
	/usr/local/go/src/net/http/server.go:2286 (0x94dc88)
	/go/pkg/mod/github.com/go-chi/chi/v5@v5.2.5/mux.go:90 (0x1a62881)
	/go/src/code.gitea.io/gitea/modules/web/router.go:286 (0x1a6d2a2)
	/go/src/code.gitea.io/gitea/modules/web/router.go:221 (0x1a6cbc6)
	/usr/local/go/src/net/http/server.go:3311 (0x96e36d)
	/usr/local/go/src/net/http/server.go:2073 (0x94bd6f)
	/usr/local/go/src/runtime/asm_amd64.s:1771 (0x49af20)
```

Signed-off-by: prettysunflower <me@prettysunflower.moe>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: prettysunflower <me@prettysunflower.moe>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
(cherry picked from commit ef096b0f9025122957b049b5d1a9c4f27bcc1d78)
(cherry picked from commit b14015efe9)
2026-05-18 10:01:01 +00:00
Giteabot f10391597d Fix actions concurrency groups cross-branch leak (#37311) (#37331)
Backport #37311 by @silverwind

## Problem

Workflow-level concurrency groups were evaluated — and jobs were parsed
— before the run was persisted, so `run.ID` was `0` and `github.run_id`
in the expression context resolved to an empty string. Expressions like:

```yaml
concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  cancel-in-progress: true
```

collapsed to `<workflow>-` on every push event (`head_ref` is empty on
push), so `cancel-in-progress` cancelled in-progress runs across
**unrelated branches**, not just the current one.

Reproduced on a 1.26 instance:
- push to `master` → `ci` run starts
- push to `feature-branch` → the `master` run gets cancelled

GitHub Actions' documented semantic: on push events `github.run_id` is
unique per run, so the group is unique → no cancellation; on PR events
`github.head_ref` is the source branch → cancellation is per-PR.

## Fix

Insert the run **before** parsing jobs or evaluating workflow-level
concurrency, so `run.ID` is populated in time for every expression that
reads `github.run_id` — not just the concurrency group, but also
`run-name`, job names, and `runs-on`.

`jobparser.Parse` now runs inside the `InsertRun` transaction, after
`db.Insert(ctx, run)`. Workflow-level concurrency evaluation runs next
and only mutates `run` in memory. All concurrency-derived fields
(`raw_concurrency`, `concurrency_group`, `concurrency_cancel`) plus
`status` and `title` are persisted in a single final `UpdateRun` at
end-of-transaction — one `INSERT` + one `UPDATE` per run in both the
concurrency and non-concurrency paths (matches pre-branch parity, one
fewer `UpdateRepoRunsNumbers` `COUNT` than the interim state).

`GenerateGiteaContext` now sets `run_id` from `run.ID` unconditionally;
every caller passes a persisted run.

**Verification**: tested end-to-end on a 1.26 deployment. Before the
patch, two successive `ci` pushes (one to master, one to a feature
branch) cross-cancelled each other. After the patch, the same pushes —
in both orders (master→branch, branch→master) — run to completion
simultaneously across 15+ runs with zero cancellations.

**Regression tests** in `services/actions/context_test.go`:
- `TestEvaluateRunConcurrency_RunIDFallback` — unit check that
`EvaluateRunConcurrencyFillModel` resolves `github.run_id` from
`run.ID`.
- `TestPrepareRunAndInsert_ExpressionsSeeRunID` — full-flow check: calls
`PrepareRunAndInsert` with `${{ github.run_id }}` in both `run-name` and
the concurrency group, then asserts the persisted `Title`,
`ConcurrencyGroup`, and `RawConcurrency` contain / survive the run's ID.
Re-ordering `db.Insert` relative to either parse or concurrency eval
fails this test.

## Relation to #37119

[#37119](https://github.com/go-gitea/gitea/pull/37119) also moves
concurrency evaluation into `InsertRun` but keeps it **before**
`db.Insert`, then tries to populate `run_id` only when `run.ID > 0` —
which is still `0` at that call site, so the cross-branch leak would
survive that PR as written. This PR fixes the ordering so that `run.ID`
is actually populated at eval time, and broadens it to cover parse-time
expression interpolation too.

---
This PR was written with the help of Claude Opus 4.7

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
(cherry picked from commit 7bd55deab302d1de482737340954a8be7efb132d)
(cherry picked from commit 433efc6093)
2026-05-18 10:00:54 +00:00
Giteabot 9264ef61d4 Fix bug when accessing user badges (#37321) (#37329)
Backport #37321 by @lunny

Fix #37302

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
(cherry picked from commit e4b7120bc2cc45a928365554fdc83132c0ffdc17)
(cherry picked from commit 255fd3e519)
2026-05-18 10:00:46 +00:00
Giteabot 4ab92b3365 Fix AppFullLink (#37325) (#37328)
Backport #37325 by @lunny

Fix a bug the checkout command line hint become `git fetch -u
https://gitea.combircni/tea`

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
(cherry picked from commit f0fd185f14fdcc13a0ec50f3134515623abbf0a2)
(cherry picked from commit aff9a28fa4)
2026-05-18 10:00:16 +00:00
Giteabot 4de459603c Fix vite manifest update masking build errors (#37279) (#37310)
Backport #37279 by @silverwind

Moves the manifest patching from `closeBundle` to `writeBundle`. Thrown
errors in `writeBundle` work correctly and exit the build.

Signed-off-by: silverwind <me@silverwind.io>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit adfa535dc200f81f6452b22f36d94f1ca8de9606)
(cherry picked from commit 3249dedde1)
2026-05-18 10:00:04 +00:00
wxiaoguang 80ba739abe Fix Mermaid diagrams failing when node labels contain line breaks (#37296) (#37299)
Backport #37296

Co-authored-by: Nicolas <bircni@icloud.com>
(cherry picked from commit e6691b0e8d2948c609fabb95967de1209f3c4520)
(cherry picked from commit e28eec37ea)
2026-05-18 09:59:46 +00:00
Giteabot e8e6177e8a Fix container auth for public instance (#37290) (#37294)
Backport #37290 by wxiaoguang

Fix #37289

Don't tell container client that the instance needs basic auth if the
public access is available.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit 82613a40a02908eca7b256567354931500b94253)
(cherry picked from commit 2de0b4f34d)
2026-05-18 09:59:16 +00:00
Giteabot 62933b0eda Enhance GetActionWorkflow to support fallback references (#37189) (#37283)
Backport #37189 by @bircni

If a workflow is not in default branch the hooks could not be detected

Fixes #37169

Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
(cherry picked from commit ba5117e4e4327c69f1b24dcf5c408279b4e80781)
(cherry picked from commit bff8f3d2e4)
2026-05-18 09:58:04 +00:00
petru bef4b822cd v1.26-custom releases branch - Modified - [docs] [changelog] [github-links] Converted changelog PR references to explicit GitHub pull-request links.
release-tag-version / binary (push) Has been cancelled
release-tag-version / container (push) Has been cancelled
(cherry picked from commit 4dba5de64c)
2026-05-18 09:28:36 +00:00
petru 84bcea290c Fixed - [admin-users] [delete-user] [fetch-action] Made the admin user-table trash action return fetch-compatible delete responses.
- 1 - I updated the `/-/admin/users` delete modal in the user table to submit an explicit inline fetch flag, and I changed the web admin `DeleteUser` handler so that this table-specific fetch flow now returns `JSONRedirect` on success and `JSONError` for expected validation failures, while the classic edit-page delete form keeps its normal redirect behavior; I also added integration coverage for the table delete path.

(cherry picked from commit 849cb3f6ae)
2026-05-18 09:19:07 +00:00
petru 9242cd6655 Fixed - [build] [versioning] Preserved custom tag names in GITEA_VERSION while keeping git describe build metadata.
- 1 - I updated `Makefile` so `GITEA_VERSION` now strips the leading `v`, preserves exact custom tag names such as `1.26.0-by-petru`, and converts only the trailing `-N-gSHA` suffix from `git describe` into `+N-gSHA` for in-between builds like `1.26.0-by-petru+3-g...` and `1.27.0-dev+143-g...`.

(cherry picked from commit adb90b3453)
2026-05-18 09:19:07 +00:00
petru bff70ba3de Modified - [scripts] [smart-build] [artifacts] Renamed smart-build outputs to include the tag/ref and generated per-file SHA-256 checksums.
- 1 - I updated [`.smart-build.sh`](/config/workspace/gitea-dev/gitea/.smart-build.sh) so each build artifact is now written as `gitea-<tag-or-ref>-<os>-<platform><-sqlite>` with the original executable extension preserved, and each output also gets its own adjacent `.sha256` file generated with `sha256sum` or `shasum -a 256`.

(cherry picked from commit c6f2b32f0b)
2026-05-18 09:19:06 +00:00
petru 63b691c29e Fixed - [scripts] [custom-release] [release-target] Stopped release-target sync from requiring the remote release branch when an explicit target tag/ref is configured.
- 1 - I updated [`.maintain-custom-release.sh`](/config/workspace/gitea-dev/gitea/.maintain-custom-release.sh) so `Sync upstream release target commits` validates only the configured `UPSTREAM_RELEASE_TARGET_REF` when one is set, instead of still failing on a missing local `upstream/release/...` remote-tracking branch after successfully fetching a target tag such as `v1.26.1`.

(cherry picked from commit 244a472691)
2026-05-18 09:19:06 +00:00
petru a1052dbf96 Fixed - [admin-users] [terminology] [locale] [en] [ro] Corrected the bootstrap-admin label from GOOD to GOD.
(cherry picked from commit 1f2bb43f46)
2026-05-18 07:10:56 +00:00
silverwind 70e1e99ff7 Upgrade go-git to v5.18.0 (#37269)
Backport of go-git upgrade to v5.18.0 for the v1.26 release branch.

Fixes GHSA-3xc5-wrhm-f963 (credential exposure on HTTP redirects).

---
This PR was written with the help of Claude Opus 4.6

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
(cherry picked from commit eb43da41f58f95aa014a80e333baa44d264d5a38)
2026-05-16 23:05:30 +00:00
wxiaoguang 32c9ac12e6 Frontend iframe renderer framework: 3D models, OpenAPI (#37233) (#37273)
Backport

* #37233
* #37272

---------

Co-authored-by: silverwind <me@silverwind.io>
(cherry picked from commit 1412009d0a58510d0313ed9e8fcc6cba85e21e14)
2026-05-16 23:05:20 +00:00
Giteabot bbcc540c0a pull: Fix CODEOWNERS absolute path matching. (#37244) (#37264)
Backport #37244 by @JoeGruffins

Patterns starting with "/" (e.g. /docs/.*\.md) never matched because git
returns relative paths without a leading slash. Strip the leading "/"
before compiling the regex since the ^...$ anchoring already provides
root-relative semantics.

closes #28107

Co-authored-by: JoeGruffins <34998433+JoeGruffins@users.noreply.github.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit 26a618ac1a773da722dfa13c7647dfdcc1c64355)
2026-05-16 23:05:08 +00:00
wxiaoguang 17ebac5c3c Swift registry metadata: preserve more JSON fields and accept empty metadata (#37254) (#37261)
Backport #37254

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
(cherry picked from commit 145898b3582085e4f54b098d2c65523169bdef0b)
2026-05-16 23:04:56 +00:00
Giteabot 699803d1d7 Fix user ssh key exporting and tests (#37256) (#37258)
Backport #37256 by wxiaoguang

1. Make sure OmitEmail won't panic
2. SSH principal keys are not for signing or authentication

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit b191cf7e7708e122be300f8e88554413680c34e4)
2026-05-16 23:04:45 +00:00
wxiaoguang e97842d0a0 Fix team member avatar size and add tooltip (#37253)
1. Make team member avatar size=32
2. Add tooltip to the avatar

(cherry picked from commit 4adee80f58e5178a65e3cfe9c63eadfd102d2acb)
2026-05-16 23:04:34 +00:00
Giteabot 579558f74a Fix commit title rendering in action run and blame (#37243) (#37251)
Backport #37243 by @silverwind

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
(cherry picked from commit 4de12baf9b8fa1016d4b7c91cbb1104b94287868)
2026-05-16 23:04:27 +00:00
wxiaoguang a3c50ac2cd Add test for "fetch redirect", add CSS value validation for external render (#37207) (#37216)
Backport #37207

(cherry picked from commit 5d852d2d0a89fcffd13148496184e85736a687ad)
2026-05-16 23:04:02 +00:00
Giteabot 3f8775bce5 Fix incorrect concurrency check (#37205) (#37215)
Backport #37205 by @Zettat123

This bug was identified in
https://github.com/go-gitea/gitea/pull/37119/changes#diff-37655a02d5a44d5c0e3e19c75fb58adb47a8e7835cbd619345d5b556292935a7L180

Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
(cherry picked from commit 2aca966c5f02893d4dcd48c133e2c17f1c8bba8d)
2026-05-16 23:03:51 +00:00
petru 1f0d9b3471 First try for Codex AI routine optimisation
(cherry picked from commit f4e7ba76d8)
2026-05-16 22:21:37 +00:00
petru 3b2bf52e62 Added Routing Rules for Tasks (Multi-Model Delegation) for OpenAI Codex.
(cherry picked from commit 59bc832f0a)
2026-05-16 22:21:23 +00:00
petru 7131424da1 Fix - For .maintain-custom-release.sh - Hardened recovery so rollback, restore-point, restore-snapshot, restore-stash, and restore-deletion correctly preserve or clean script-managed refs, maintenance branches, state files, backup branches, and snapshots, including rollback from the original entry branch after a bootstrap-created maintenance branch, cleanup of legacy restore-point leftovers, and removal of the correctly paired backup/maint-* Git Graph marker when a saved snapshot is deleted.
(cherry picked from commit ac76745362)
2026-05-16 22:21:13 +00:00
petru 171850b8f9 Modified - Finalized the custom-release maintenance helper workflow and recovery behavior.
- 1 - I made `bootstrap` a clean branch-creation step from `BASE_TAG`, separated fetch and sync into explicit compare/release-target/custom actions, added `UPSTREAM_RELEASE_TARGET_REF`, and updated the built-in help so the recommended workflow matches the current menu structure.
- 2 - I hardened recovery so rollback, restore-point, restore-snapshot, restore-stash, and restore-deletion correctly preserve or clean script-managed refs, maintenance branches, state files, backup branches, and snapshots, including rollback from the original entry branch after a bootstrap-created maintenance branch, cleanup of legacy restore-point leftovers, and removal of the paired `backup/maint-*` Git Graph marker when a saved snapshot is deleted.
- 3 - I finalized the interactive UX by keeping a self-updating runtime copy in `/tmp`, persisting the last-used settings in `/tmp/.maintain-custom-release.env`, and reorganizing the menu into `Manual Backups >`, `Fetch upstreams >`, `Sync >`, `Rollback >`, and `Restore >` submenus, including `Delete Restore >` with numbered stash and snapshot selection, with numbered selections, `b`/`B` or `Enter` for Back, correct return-to-parent behavior from every submenu, and `0` for Exit.

(cherry picked from commit 5eae94f95a)
2026-05-16 22:21:02 +00:00
petru 4991e019a5 Modified - Finalized the custom-release maintenance helper workflow and recovery behavior.
- 1 - I made `bootstrap` a clean branch-creation step from `BASE_TAG`, separated fetch and sync into explicit compare/release-target/custom actions, added `UPSTREAM_RELEASE_TARGET_REF`, and updated the built-in help so the recommended workflow matches the current menu structure.
- 2 - I hardened recovery so rollback, restore-point, restore-snapshot, and restore-stash correctly preserve or clean script-managed refs, maintenance branches, state files, backup branches, and snapshots, including rollback from the original entry branch after a bootstrap-created maintenance branch and cleanup of legacy restore-point leftovers.
- 3 - I finalized the interactive UX by keeping a self-updating runtime copy in `/tmp`, persisting the last-used settings in `/tmp/.maintain-custom-release.env`, and reorganizing the menu into `Backups >`, `Fetch upstreams >`, `Sync >`, `Rollback >`, and `Restore >` submenus with numbered selections, `b`/`B` or `Enter` for Back, and `0` for Exit.

(cherry picked from commit 3bbe60b6b7)
2026-05-16 22:20:51 +00:00
petru 70ec5f9976 Moved in .maintain-custom-release.sh bootstrap ahead of the explicit fetch actions in the interactive menu, kept it in the menu flow instead of exiting the script, removed automatic fetching from bootstrap and plan, and split both the fetch and sync flows into separate compare-branch and release-target actions while clarifying that custom commits are cherry-picked from oldest to newest.
(cherry picked from commit 1d43078c0b)
2026-05-16 22:20:42 +00:00
petru dae225ec3a Updated [.maintain-custom-release.sh](/config/workspace/gitea-dev/gitea/.maintain-custom-release.sh) so bootstrap now only creates or switches to the maintenance branch from BASE_TAG, without automatically fetching or importing anything.
- Added a persistent `/tmp/.maintain-custom-release.env` settings file so the last used configuration survives script restarts.
- Moved `bootstrap` ahead of the explicit fetch actions in the interactive menu, removed automatic fetching from `bootstrap` and `plan`, and split both the fetch and sync flows into separate compare-branch and release-target actions while clarifying that custom commits are cherry-picked from oldest to newest.

(cherry picked from commit f5718dd509)
2026-05-16 22:20:27 +00:00
petru 729d063f3d Taught the .maintain-custom-release.sh script to maintain and relaunch itself from a runtime copy in /tmp, automatically creating or refreshing that copy from the repo version when needed while still falling back to the existing /tmp copy if the current checkout no longer contains the script, and I split both the fetch and sync flows into separate compare-branch and release-target actions while clarifying that custom commits are cherry-picked from oldest to newest.
(cherry picked from commit f765bfdc05)
2026-05-16 22:20:20 +00:00
petru b46aa97fff Taught the .maintain-custom-release.sh script to maintain and relaunch itself from a runtime copy in /tmp, automatically creating or refreshing that copy from the repo version when needed while still falling back to the existing /tmp copy if the current checkout no longer contains the script, and I split the upstream sync flow into separate sync-upstream-compare and sync-upstream-target actions while clarifying that custom commits are cherry-picked from oldest to newest.
(cherry picked from commit 2c95b1faf4)
2026-05-16 22:20:12 +00:00
petru c401ffb2c4 Added to .maintain-custom-release.sh an explicit UPSTREAM_RELEASE_TARGET_REF setting so the upstream import can stop at a chosen tag such as v1.26.0 instead of always importing to the current head of upstream/release/v1.26, and I also made rollback clean up the original backup/maint-* branch and fetched upstream/* refs so a canceled bootstrap leaves the branch graph closer to its pre-run state.
(cherry picked from commit 2d37281725)
2026-05-16 22:20:05 +00:00
petru 12474983f1 Tightened in .maintain-custom-release.sh the manual restore-point management so list-restore-points now shows only valid restore points that still have their Git Graph marker branch, while delete-restore-point can still remove orphaned restore-point directories even after their associated backup branch has already been deleted manually.
(cherry picked from commit c8bd47f0d9)
2026-05-16 22:19:56 +00:00
petru e38d9eca83 Fixed the script-managed ref discovery itself so restore cleanup now matches refs/remotes/upstream/... and backup/maint-... by prefix instead of a non-matching glob pattern, which was the reason upstream/release/v1.26 could still remain after a restore.
(cherry picked from commit aba98b9361)
2026-05-16 22:19:49 +00:00
petru d1845fa0b3 Added a legacy restore-point fallback so older restore points that predate the script-managed ref snapshot files now explicitly remove current upstream/*, maintenance-branch, backup/maint-*, state-file, and snapshot artifacts instead of leaving them behind after restore.
(cherry picked from commit b31ce595d3)
2026-05-16 22:19:40 +00:00
petru f93d28f277 fixed the restore flows so manual restore points now capture and restore the script-managed refs, state file, and snapshot directories, while successful rollback, restore-snapshot, and restore-point operations automatically clean up their temporary safety backup branches and snapshots when no preserved local stash needs to be kept.
(cherry picked from commit 8f9b67397e)
2026-05-16 22:19:33 +00:00
petru 78f8fb8307 Modified - Simplified bootstrap and tightened rollback cleanup in the custom-release maintenance helper.
(cherry picked from commit f527cf4ce3)
2026-05-16 22:19:22 +00:00
petru 512ecb175f Fix - fixing the interactive configuration prompts so they are shown correctly during Edit configuration.
(cherry picked from commit 209224d0cc)
2026-05-16 22:19:09 +00:00
petru edc292d12c Modified - Extended the custom-release maintenance helper with manual restore points and corrected its fetch behavior.
(cherry picked from commit 363c86ecaf)
2026-05-16 22:19:03 +00:00
petru 400928623b Set script as .update-gitea.sh as executable.
(cherry picked from commit 92c6dad4b9)
2026-05-16 22:18:43 +00:00
petru 249fc8bf0b Added - Added a dedicated safe upstream import helper based on cherry-pick.
Added - Added an interactive custom-release maintenance helper for stable patch lines.

Added - Added a dedicated safe upstream import helper based on `cherry-pick`.
Added - Added an interactive custom-release maintenance helper for stable patch lines.

Added - Added a dedicated safe upstream import helper based on cherry-pick.
Added - Added an interactive custom-release maintenance helper for stable patch lines.

(cherry picked from commit a6a278b551)
2026-05-16 22:18:35 +00:00
petru f608948bf7 Added - Finalized the safe upstream update helper script as .update-gitea.sh.
- 5 - I improved conflict reporting so package.json conflicts show the upstream scripts block, the conflicting commit side, and the current branch working-tree side, and the final dry-run summary now includes the total conflict-step count, the local commits that conflicted, and the unique conflicted files.

(cherry picked from commit 6d0a7ec238)
2026-05-16 22:17:56 +00:00
petru e77ede6a9f Added - Finalized the safe upstream update helper script as .update-gitea.sh.
- 1 - I renamed the updater to `.update-gitea.sh`, documented its purpose and ordered usage steps, and added an interactive menu plus direct commands for `sync`, `dry-run`, `fetch`, `backup`, `status`, `list-backups`, `rollback`, `restore-stash`, and `clean-dry-run`.
- 2 - I hardened real update actions so they verify repository state, enforce or offer safety backups before modifying the branch, stash tracked and untracked local changes, record sync state inside `.git`, and support rollback to the exact saved starting commit or to a selected backup branch while preserving recoverability of local changes.
- 3 - I implemented a reusable dry-run workspace under `.git/.update-gitea-dry-run`, added cleanup for both that workspace and legacy temporary dry-run directories, and made dry-run collect and report all detected rebase conflict steps without modifying the real repository.
- 4 - I improved conflict reporting so package.json conflicts show the upstream scripts block, the conflicting commit side, and the current branch working-tree side, and the final dry-run summary now includes the total conflict-step count, the local commits that conflicted, and the unique conflicted files.

(cherry picked from commit cca877c06e)
2026-05-16 22:17:50 +00:00
petru 52ce12c13f Added - Added optional sensitive-secret import for installer app.ini uploads.
- 1 - I added an explicit installer checkbox for importing sensitive secrets from `app.ini` in `templates/install.tmpl`.
- 2 - I extended the installer form, submit pipeline, and final config writer so the optional import reuses `LFS_JWT_SECRET`, `INTERNAL_TOKEN`, and `oauth2.JWT_SECRET` from the uploaded `app.ini` instead of generating new values, including a submit-time fallback that re-reads the uploaded file if the checkbox was enabled after the first auto-import.
- 3 - I finalized secret resolution for both direct values and `LFS_JWT_SECRET_URI` / `INTERNAL_TOKEN_URI` / `JWT_SECRET_URI` file-based references, and added regression coverage for direct imports, URI-based imports, the real `POST /import_app_ini` flow, and the persisted `app.ini` output.

(cherry picked from commit 512e577c3f)
2026-05-16 22:14:50 +00:00
petru 7070660554 Modified - Enabled shared branding assets by default in the installer.
- 1 - I updated `routers/install/install.go` so `BrandingUseSharedAssets` starts as enabled on the install form, making `Use the same logo files for favicon assets` checked by default.

(cherry picked from commit e69839ed88)
2026-05-16 22:13:22 +00:00
petru b36fd283af Added - added installer locale strings in both options/locale/locale_en-US.json and options/locale/locale_ro-RO.json for the new import UI, success message, and import errors, and the success flash now auto-dismisses after 5 seconds both on initial page load and after the AJAX import injects a new flash message.
(cherry picked from commit b907e4c38c)
2026-05-16 22:13:15 +00:00
petru 9bf972379b Added - Added installer support for importing an existing app.ini.
- 1 - I added an `Import Existing Configuration` section at the top of `templates/install.tmpl` with an `app.ini` upload control that imports automatically as soon as a file is selected, without a separate `Load app.ini` button.
- 2 - I kept the dedicated installer route `POST /import_app_ini` in `routers/install/routes.go`, but the page now posts to it via `fetch` and applies the imported values back into the existing form with `DOMParser`, so the browser is not visibly navigated to `/import_app_ini` and the page scripts are not re-executed.
- 3 - In `routers/install/install.go`, I factored the installer defaults into reusable helpers, added `app.ini` upload parsing with size/error handling, and mapped the imported config into the existing install form fields for database, general server paths, mailer, registration, OpenID, security, and admin policy settings.
- 4 - I added installer locale strings in both `options/locale/locale_en-US.json` and `options/locale/locale_ro-RO.json` for the new import UI, success message, and import errors, and the success flash now auto-dismisses after 5 seconds.
- 5 - I added regression coverage in `routers/install/routes_test.go` for the new upload control and the config-to-form mapping behavior.

(cherry picked from commit 52f3495ca0)
2026-05-16 22:12:38 +00:00
petru 981d9d0d9b Added - Added the password visibility toggle to /user/settings/change_password.
- 1 - I wrapped the forced-change password field in `templates/user/auth/change_passwd_inner.tmpl` with the shared `js-password-toggle-group`, reusing the existing eye-toggle logic and show/hide labels.
- 2 - I wired the confirm-password field into the existing toggle sync behavior so revealing the new password hides the confirm field and keeps it synchronized like the other password-update forms.

(cherry picked from commit 70479ea5a0)
2026-05-16 22:12:26 +00:00
petru 23cff646b5 Modified - Finalized Register behavior for admin-created notification accounts without altering the invitation flow.
- 1 - I extended `POST /user/sign_up` in `routers/web/auth/auth.go` for existing active local accounts created by an admin when `username` and `email` match, while explicitly leaving pending admin invitations on their existing flow.
- 2 - If password is correct, the user is now authenticated into that existing account; when `MustChangePassword` is enabled, the flow redirects directly to `/user/settings/change_password`, otherwise it follows the normal post-auth redirect.
- 3 - If password is incorrect, the flow now redirects to `/user/forgot_password?email=<email>` and shows a warning to use account recovery plus check Spam/Junk.
- 4 - I added the locale key `auth.admin_notify_recover_password_spam_hint` in both `options/locale/locale_en-US.json` and `options/locale/locale_ro-RO.json`.
- 5 - I added regression tests in `routers/web/auth/auth_test.go` for normal sign-in, forced change-password redirect, wrong-password recovery redirect, and a guard that the admin-invitation flow still redirects to `/user/invitation`.

(cherry picked from commit 9ee45b3392)
2026-05-16 22:12:07 +00:00
petru 223d2f3f58 Added - Added optional custom branding uploads to the install page.
- 1 - I finalized the installer `Branding` section with optional uploads for `logo.svg`, `logo.png`, `loading.png`, `favicon.svg`, and `favicon.png`, including clear format/size guidance plus a shared-assets checkbox for using one SVG and one PNG upload for both logo and favicon.
- 2 - I implemented backend validation and persistence for all branding uploads in `routers/install/install.go` (expected type checks, 1 MB limit, square PNG with minimum 64x64) and save accepted overrides under `custom/public/assets/img/`.
- 3 - I completed the runtime behavior so uploaded branding files override built-in assets through layered serving, `logo.svg` is mirrored to `gitea.svg` for legacy lookups, post-install progress prefers a custom `loading.png`, and the shared-assets mode hides favicon fields while relabeling logo fields to `Logo & Favicon SVG/PNG`.
- 4 - I manually updated Romanian locale wording for the final branding texts and labels.

(cherry picked from commit d81fdfc31f)
2026-05-16 21:57:54 +00:00
petru 53a6ca83a5 Added - Added the password visibility toggle and confirm-password behavior to /user/settings/account.
(cherry picked from commit 7dbc4726fa)
2026-05-16 21:57:44 +00:00
petru 03898ed70d Added - Added the password visibility toggle to the install-page database password field.
+ Fix - some new correction Romanian wording and grammar in locale_ro-RO.json.

(cherry picked from commit 3b52932acd)
2026-05-16 21:57:30 +00:00
petru 57a91789c5 Added - Added the password visibility toggle and confirm-password behavior to the install-page super-admin password fields.
+ Fix - some new correction Romanian wording and grammar in locale_ro-RO.json.

(cherry picked from commit 4ff2054a83)
2026-05-16 21:57:03 +00:00
petru 4a2c81d044 Modified - Enabled install-page email notifications by default for fresh setups.
(cherry picked from commit fb34e858c1)
2026-05-16 21:56:05 +00:00
petru 5866b9de18 Added - Added the password visibility toggle to the SMTP password field on the install page.
(cherry picked from commit a59bb9753f)
2026-05-16 21:55:59 +00:00
petru f5e38807f0 Added - Added column-wide Select all controls to the organization team-units permissions table.
+ Fix - some new correction Romanian wording and grammar in locale_ro-RO.json.

(cherry picked from commit ca7092e23c)
2026-05-16 21:55:50 +00:00
petru 8d9ce66c91 Fix - some new correction Romanian wording and grammar in locale_ro-RO.json.
(cherry picked from commit 490e119254)
2026-05-16 21:55:42 +00:00
petru e215adbc70 Modified - Unified the persistent appearance toggles into a single settings group.
(cherry picked from commit 3b121911c1)
2026-05-16 21:55:34 +00:00
petru 76ec1d4552 Modified - Some changes in .gitignore
(cherry picked from commit 354521fbd3)
2026-05-16 21:55:24 +00:00
petru 93d2710d8e Fix - some new correction Romanian wording and grammar in locale_ro-RO.json.
(cherry picked from commit aaaada5129)
2026-05-16 21:55:18 +00:00
petru 23a76e0cc0 Modified - Finalized the manual-only password visibility toggle behavior for login and signup.
(cherry picked from commit cbedf15d3b)
2026-05-16 21:55:11 +00:00
petru 5786d40338 Modified - Added an audio bell for interactive prompts in 'smart-build.sh'.
(cherry picked from commit 1525c9c8ee)
2026-05-16 21:55:05 +00:00
petru c1cc5cf8fd Added - Added pilot partial navigation for the repository Actions sidebar.
(cherry picked from commit 75bc9606d5)
2026-05-16 21:54:37 +00:00
petru eb595cd684 Modified - Applied the shared sticky side-menu behavior to repository Actions pages.
(cherry picked from commit 0f3876c0b1)
2026-05-16 21:54:30 +00:00
petru ffc1c0931c Modified - Applied the shared sticky side-menu behavior to repository settings pages.
(cherry picked from commit 652d3c20da)
2026-05-16 21:54:25 +00:00
petru 5319872a75 Added - Added password visibility toggles to the login and signup forms.
(cherry picked from commit bfb584f161)
2026-05-16 21:54:17 +00:00
petru 1679a81f34 Fix - some new correction Romanian wording and grammar in locale_ro-RO.json.
(cherry picked from commit 01e3eb1306)
2026-05-16 21:54:04 +00:00
petru 8a2b349a66 Modified - Applied the shared sticky side-menu behavior to organization settings pages.
(cherry picked from commit 827a35ce09)
2026-05-16 21:53:57 +00:00
petru 86a695b2d1 Added - Added header-level Select all controls to the shared Actions maximum-permissions table.
(cherry picked from commit 021f12509f)
2026-05-16 21:53:50 +00:00
petru 41908de091 Added - Added column-wide Select all controls to the user access-token permissions table.
(cherry picked from commit ab1135d1c6)
2026-05-16 21:53:40 +00:00
petru ac42a80034 Modified - Highlighted the active submenu entry with the standard active background color.
(cherry picked from commit 8a0d319607)
2026-05-16 21:53:35 +00:00
petru 2abc050929 Modified - Finalized the sticky side-menu bottom-edge behavior by compacting menu items and increasing the viewport reserve.
(cherry picked from commit 06b7bd3ca1)
2026-05-16 21:53:26 +00:00
petru 60f48b91ad Modified - Restored the pre-122 /user/settings layout baseline while keeping the current sticky-menu behavior.
(cherry picked from commit bb77e80bf5)
2026-05-16 21:53:18 +00:00
petru d5c8a106ec Modified - Restored the agreed /user/settings sticky-menu item padding behavior.
(cherry picked from commit 71246d4ee1)
2026-05-16 21:52:35 +00:00
petru 33cb73228e Modified - Preserved the /user/settings left-menu scroll position without the visible reset flicker during navigation.
(cherry picked from commit 3dd2ffc195)
2026-05-16 21:52:15 +00:00
petru 319ecf0bec Modified - Made the Admin Settings menu header sticky while the admin left-menu options scroll.
(cherry picked from commit 5e31019b99)
2026-05-16 21:51:32 +00:00
petru 201a4c3f69 Modified - Made the footer Licenses and API links open in a new browser tab and finalized the sticky User Settings header plus its top green scroll indicator.
(cherry picked from commit cfd1c9ddbb)
2026-05-16 21:40:48 +00:00
petru 4bf723f382 Modified - Preserved the /user/settings left-menu scroll position across settings-page navigation
+ Fix - some new correction Romanian wording and grammar in `locale_ro-RO.json`.

(cherry picked from commit a8a099edea)
2026-05-16 21:40:36 +00:00
petru 9b81fbf2ce Modified - Added a persistent navigation-bar preference in /user/settings/appearance.
(cherry picked from commit 90735ea826)
2026-05-16 21:40:05 +00:00
petru 85149bde8d Modified - Added the persistent sticky side-menu preference and the finalized sidebar behavior for /user/settings and /-/admin.
(cherry picked from commit 351d6b0811)
2026-05-16 21:39:56 +00:00
petru 19d0586b47 Modified - Moved the persistent footer outside the page scroll area
+ some new correction Romanian wording and grammar in `locale_ro-RO.json`.

(cherry picked from commit 61a9e4bd06)
2026-05-16 21:39:19 +00:00
petru 95a23e426a Modified - Reverted the global fixed-footer behavior and replaced it with a persistent per-user footer preference in /user/settings/appearance.
(cherry picked from commit b3a7692ce9)
2026-05-16 21:38:40 +00:00
petru 35dc5df4d9 Modified - Made the admin-created account notification link behave like an invitation by signing the user in through /user/activate
+ Modified - Simplified the admin-created account notification email to show only the personalized activation link.

(cherry picked from commit 10495b7cd1)
2026-05-16 21:25:57 +00:00
petru 741f4c0413 Modified - Made the admin-created account notification link behave like an invitation by signing the user in through /user/activate.
(cherry picked from commit 2ecb570a7d)
2026-05-16 21:25:51 +00:00
petru 15bf8de3a1 Fixed - Corrected the admin-created account password-setup email link to use the public recovery route
+ some new correction Romanian wording and grammar in `locale_ro-RO.json`.

(cherry picked from commit 146013827c)
2026-05-16 21:24:54 +00:00
petru 21e0121676 Modified - Personalized the admin-created account notification email with the creator name and a direct set-password link.
(cherry picked from commit 85620a4f29)
2026-05-16 21:24:41 +00:00
petru ab299063b1 Fixed - Made admin-created user notification and invitation emails use the current page locale
+ ome new correction Romanian wording and grammar in `locale_ro-RO.json`.

(cherry picked from commit 70ef46362e)
2026-05-16 21:24:00 +00:00
petru 57ee21d53e Fixed - Prevented the new-organization modal from inheriting unrelated global success flashes from the underlying page.
+ Some new correction Romanian wording and grammar in `locale_ro-RO.json`.

(cherry picked from commit fc43980a5c)
2026-05-16 21:23:54 +00:00
petru ad36689444 Modified - Reduced the resend button size on the invitation acceptance prompt.
(cherry picked from commit 5f0f52d04f)
2026-05-16 21:23:41 +00:00
petru 37ada5c0d9 Modified - Reduced the resend button size on the invitation acceptance prompt.
(cherry picked from commit 17814a4dda)
2026-05-16 21:23:35 +00:00
petru 6c16930c07 Modified - Some new correction Romanian wording and grammar in locale_ro-RO.json.
(cherry picked from commit 7c7357f314)
2026-05-16 21:23:11 +00:00
petru e20cd8a329 Modified - Some new correction Romanian wording and grammar in locale_ro-RO.json.
(cherry picked from commit f00f80bae7)
2026-05-16 21:23:06 +00:00
petru b82c82ee57 Modified - Fix align new-user check-boxes help text.
(cherry picked from commit d1e10b41a5)
2026-05-16 21:22:58 +00:00
petru 529a6603db Modified - Somes correction Romanian wording and grammar in locale_ro-RO.json
(cherry picked from commit c80f065a09)
2026-05-16 21:22:46 +00:00
petru 659abcfd5f Modified - Converted the organization creation page to a modal-style dialog and preserved the caller page for cancel.
(cherry picked from commit 5338d5f7f6)
2026-05-16 21:22:38 +00:00
petru c06bed2dce Modified - Converted the organization creation page to a modal-style dialog and preserved the caller page for cancel.
(cherry picked from commit ba0da47957)
2026-05-16 21:22:32 +00:00
petru 38fef3bcd7 Updated .codex-history.md
(cherry picked from commit 75a9dbf7d7)
2026-05-16 21:22:21 +00:00
petru 1c133b3454 Modified - Another visual polish of Romanian translation for locale_ro-RO.json.
(cherry picked from commit cc36930cdd)
2026-05-16 21:22:12 +00:00
petru 1bf070ae1d Modified - Visual polish of Romanian translation for locale_ro-RO.json.
(cherry picked from commit cb765b81a7)
2026-05-16 21:22:00 +00:00
petru 38a1b1dffe Modified - Added a first complete Romanian translation pass for locale_ro-RO.json.
(cherry picked from commit 144bc4796f)
2026-05-16 21:21:46 +00:00
petru b10c956c1e Modified - Added official bootstrap support for the Romanian locale.
(cherry picked from commit 414c77278b)
2026-05-16 21:21:26 +00:00
petru a2cf18e98e Modified - Added an install-page language hint balloon anchored to the footer language selector.
(cherry picked from commit 4eaa42bccd)
2026-05-16 21:21:19 +00:00
petru ae7eeaafbb Modified - Aligned the admin new-user invitation help text with the install-page help layout.
(cherry picked from commit f60b2af5a6)
2026-05-16 21:21:12 +00:00
petru dcac42161e Modified - Added a dedicated pending-invitation flow for admin-created invite accounts and pinned the install footer.
(cherry picked from commit f7bc24d4e8)
2026-05-16 21:20:31 +00:00
petru e71c56d8a2 Modified - Disabled forbidden email deletion actions in the admin email list.
(cherry picked from commit f8f988e85e)
2026-05-16 21:20:06 +00:00
petru 35a7f9184c Modified - Added default language selection to the install page initial configuration.
(cherry picked from commit b7e7b32caa)
2026-05-16 21:19:48 +00:00
petru 25c22c5c93 Modified - Unified classic email-confirmation signup with the resend-based pending validation flow.
(cherry picked from commit 4ab8063966)
2026-05-16 21:19:42 +00:00
petru 6be878abca Modified - Moved admin-created account delivery mode selection from install to the admin new-user form.
(cherry picked from commit a6695a6e73)
2026-05-16 21:19:35 +00:00
petru 97121edd6b Modified - Completed install-page admin-managed account modes and aligned locale install sections-v.1
(cherry picked from commit ad0ab4be60)
2026-05-16 21:19:10 +00:00
petru 4c60b2bf00 Modified - v.1-Added install-page Registration Management with coherent mode-driven registration settings.
(cherry picked from commit 19fb194db6)
2026-05-16 21:18:49 +00:00
petru 44276e2eba Type: Modified - Added install-page testing email verification using the entered SMTP settings.
(cherry picked from commit 362d01abbc)
2026-05-16 21:17:09 +00:00
petru b40d828934 Modified - Updated install-page administrator labels to super administrator wording.
(cherry picked from commit d4a1b88385)
2026-05-16 21:16:16 +00:00
petru e3e8edc143 Modified - Updated install-page administrator labels to super administrator wording.
(cherry picked from commit f13470096f)
2026-05-16 21:16:09 +00:00
petru ab0f52ea51 Modified - Added install-time admin management policy choices with direct-grantor and inherited-grantor enforcement.
Modified - Updated the example app.ini documentation for the new administrator management policies.

(cherry picked from commit 1e13af4d6e)
2026-05-16 21:15:38 +00:00
petru 4b7b647c30 Modified - Restored normal self-edit access for super admins and disabled only the admin actions that are truly forbidden.
(cherry picked from commit 43161732e3)
2026-05-16 21:15:20 +00:00
petru 089863052d Modified - Protected GOOD-granted admin accounts and blocked deleting the direct grantor.
(cherry picked from commit 80497e4194)
2026-05-16 21:14:58 +00:00
petru 6484fc06ef Modified - Protected GOOD-granted admin accounts and blocked deleting the direct grantor.
(cherry picked from commit 0cbec16f84)
2026-05-16 21:14:44 +00:00
petru 344ef1fad6 Modified - Protected GOOD-granted admin accounts and blocked deleting the direct grantor.
(cherry picked from commit 22a6945b9d)
2026-05-16 21:14:34 +00:00
petru 63b93a7048 Modified - Kept super administrator Edit and Delete controls visible but disabled for regular admins.
(cherry picked from commit 5da24d2c7b)
2026-05-16 21:13:19 +00:00
petru c7d6f61d9e Fixed - Blocked regular administrators from editing super administrator accounts.
(cherry picked from commit 0fc6f30a30)
2026-05-16 21:12:55 +00:00
petru 384fba3fc3 Fixed - Enabled super administrator bootstrap by default.
(cherry picked from commit 35b9fa65d3)
2026-05-16 21:12:40 +00:00
petru f2fae6095b Added - Added persistent super administrator protection & Enabled super administrator bootstrap by default.
(cherry picked from commit a14158b63a)
2026-05-16 21:11:19 +00:00
petru cab2a9371f Fixed - Hidde Is Administrator reason unless admin rights were revoked.
(cherry picked from commit cff1b46f50)
2026-05-16 21:11:09 +00:00
petru b588b3d2b2 Modified - Added admin actor badge beside the Is Administrator option.
(cherry picked from commit 4aacf3bd20)
2026-05-16 21:10:15 +00:00
petru e40acbea0b Fixed - Disabled critical self-edit account state checkboxes.
(cherry picked from commit 3afb4e8afa)
2026-05-16 21:01:30 +00:00
petru 05318e0933 Added - Added Is Administrator reason and admin-grant badges.
(cherry picked from commit 067a09c2ac)
2026-05-16 21:01:20 +00:00
petru 30f9ff7478 Added - Added restricted-admin badges and reason actor badges.
(cherry picked from commit 396b15372d)
2026-05-16 21:01:09 +00:00
petru 61f9e3bf06 Fixed - Corrected admin status reason behavior and reactivation emails.
(cherry picked from commit b3204f3db6)
2026-05-16 21:00:54 +00:00
petru 3fbd617767 Fixed - Corrected admin status reason behavior and reactivation emails.
(cherry picked from commit 936ccf3738)
2026-05-16 21:00:39 +00:00
petru caff3a8315 Added - Added admin status-change reasons and user email notifications.
(cherry picked from commit 210955465e)
2026-05-16 21:00:27 +00:00
petru b50134da2f Added - Added Disable Sign-In metadata to the admin users list.
(cherry picked from commit 1dcd81b420)
2026-05-16 21:00:11 +00:00
petru 35e79a8393 Modified - Defaulted admin user purge checkboxes to enabled.
(cherry picked from commit a8d9e5e659)
2026-05-16 20:59:59 +00:00
petru d3b5d47e76 Modified - Moved account request review controls to the top of the admin user edit panel.
Fixed - Prevented empty `by` badges in the admin users list.

(cherry picked from commit c7c7af77a1)
2026-05-16 20:59:45 +00:00
petru e2a750824d Modified - Added persistent admin email tooltip to creator badges.
Add: Activated column show a `by <admin>` badge with the stored admin email as a hover tooltip.

(cherry picked from commit a3e09bb819)
2026-05-16 20:59:36 +00:00
petru 2e2756c16a Fixed - Kept creator-admin badges permanently attached to invited accounts.
(cherry picked from commit cd96c721e0)
2026-05-16 20:59:22 +00:00
petru 137243c988 Modified - Added a user creator-admin badges to the admins users list.
(cherry picked from commit cfd7cfa1dc)
2026-05-16 20:59:09 +00:00
petru 12e140bf68 Added - Notified inviting admins when admin-created invitations are accepted.
(cherry picked from commit 8147f7a798)
2026-05-16 20:58:56 +00:00
petru 8557aeca72 Added - Added admin-created account invitation flow when registration is disabled.
(cherry picked from commit 20405fe5e7)
2026-05-16 20:58:37 +00:00
petru fb23ea28bc Modified - Added password confirmation to account recovery.
(cherry picked from commit 25a1d84c2e)
2026-05-16 20:58:26 +00:00
petru a25837d735 Blocked inactive account-request users from getting a signed-in session
(cherry picked from commit f21b6b7a3b)
2026-05-16 20:54:37 +00:00
petru 6e9ea05a4f Added an admin user-list delete account action button
(cherry picked from commit 8b14814199)
2026-05-16 20:34:42 +00:00
petru 296c2a1689 Added inline test email feedback, keep page scroll position & display email delivery status messages.
(cherry picked from commit 62164e3fd8)
2026-05-16 20:34:25 +00:00
petru cfb6f32204 admin registration confirm OK
(cherry picked from commit 1a438e765d)
2026-05-16 20:33:43 +00:00
wxiaoguang e0e7f0c4ed Fix corrupted JSON caused by goccy library (#37214) (#37220)
Backport #37214

The only conflict is go.mod

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
(cherry picked from commit 3b253e06a3)
2026-05-16 20:21:13 +00:00
Giteabot b79074aeb1 Implement logout redirection for reverse proxy auth setups (#36085) (#37171)
Backport #36085 by @eliroca

When authentication is handled externally by a reverse proxy SSO
provider, users can be redirected to an external logout URL or relative
path defined on the reverse proxy.

Co-authored-by: Elisei Roca <eroca@suse.de>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit 7a7376dfc8)
2026-05-16 20:09:44 +00:00
Giteabot 64f52201b1 Fix UI regression (#37218) (#37219)
Backport #37218 by wxiaoguang

Fix  #37213

Also fix the misaligned tags, remove unused classes, etc.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit df0ad4e8c1)
2026-05-16 20:02:15 +00:00
Giteabot af15978c31 fix(api): handle missing base branch in PR commits API (#37193) (#37203)
Backport #37193 by @Mohit25022005

fix(api): handle missing base branch in PR commits API

Closes #36366

Previously, the PR commits API returned a 500 Internal Server Error
when the base branch was missing due to an unhandled git "bad revision"
error.

This change:
- Checks for base branch existence before performing git operations
- Returns 404 when the base branch does not exist
- Prevents git errors from surfacing as 500 responses

This improves API robustness and aligns behavior with expected error
handling.

Tested locally by:
- Creating a pull request
- Deleting the base branch
- Verifying that the API returns 404 instead of 500

Co-authored-by: Mohit Swarnkar <mohitswarnkar13@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
(cherry picked from commit 68f5e40e46)
2026-05-16 20:01:47 +00:00
Giteabot 511f9bfd20 Fix encoding for Matrix Webhooks (#37190) (#37201)
Backport #37190 by @bircni

`url.PathEscape` unnecessarily encodes ! to %21, causing Matrix
homeservers to reject the request with 401. Replace %21 back to ! after
escaping.

Fixes #36012

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit d1be5c3612)
2026-05-16 20:01:40 +00:00
Giteabot 8d921a67ff Always show owner/repo name in compare page dropdowns (#37172) (#37200)
Backport #37172 by @xingxing21

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

The fix is a template-only change in
[templates/repo/diff/compare.tmpl:16-25](vscode-webview://1ca9j6f1e3qtaf59o0cr4ind65ulf8mevvbbbq88int1gg2lncar/templates/repo/diff/compare.tmpl#L16-L25).

Before, the display names were built with conditional logic:

All four variables defaulted to just the owner name (Examples)
$HeadCompareName was only upgraded to owner/repo format in two narrow
cases:
Same org, different repos
A root repo exists with the same owner as the head repo
All other cases (same-repo PRs, cross-org PRs) got owner-only labels
After, all four variables are unconditionally set to owner/repo format
using printf "%s/%s":

```
- {{$BaseCompareName := printf "%s/%s" $.BaseName $.Repository.Name -}}
- {{- $HeadCompareName := printf "%s/%s" $.HeadRepo.OwnerName $.HeadRepo.Name -}}
- {{- $OwnForkCompareName := "" -}}
- {{- if .OwnForkRepo -}}
-	{{- $OwnForkCompareName = printf "%s/%s" .OwnForkRepo.OwnerName .OwnForkRepo.Name -}}
- {{- end -}}
- {{- $RootRepoCompareName := "" -}}
- {{- if .RootRepo -}}
-	{{- $RootRepoCompareName = printf "%s/%s" .RootRepo.OwnerName .RootRepo.Name -}}
- {{- end -}}

+ {{$BaseCompareName := $.Repository.FullName -}}
+ {{$HeadCompareName := $.HeadRepo.FullName -}}
+ {{$OwnForkCompareName := "" -}}
+ {{if $.OwnForkRepo -}}
+	{{$OwnForkCompareName = $.OwnForkRepo.FullName -}}
+ {{end -}}
+ {{$RootRepoCompareName := "" -}}
+ {{if $.RootRepo -}}
+	{{$RootRepoCompareName = $.RootRepo.FullName -}}
+ {{end -}}
```

These variables drive the labels in the base and head branch selector
buttons and their dropdown items. No backend changes were needed —
$.BaseName, $.Repository.Name, $.HeadRepo.OwnerName, and $.HeadRepo.Name
were already available in the template context.

Co-authored-by: Xing Hong <39619359+xingxing21@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit 8687faaf3a)
2026-05-16 20:01:32 +00:00
Giteabot b56db2ff18 fix(api): handle fork-only commits in compare API (#37185) (#37199)
Backport #37185 by @Mohit25022005

Fix 500 error when comparing branches across fork repositories

## Problem

The compare API returns a 500 Internal Server Error when comparing
branches where the head commit exists only in the fork repository.

## Cause

The API was using the base repository's GitRepo and repository context
when converting commits. This fails when the commit does not exist in
the base repository, resulting in a "fatal: bad object" error.

## Solution

Use the head repository and HeadGitRepo when available to ensure commits
are resolved in the correct repository context.

## Result

* Fixes "fatal: bad object" error
* Enables proper comparison between base and fork repositories
* Prevents 500 Internal Server Error

Fixes #37168

Co-authored-by: Mohit Swarnkar <mohitswarnkar13@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit 789a3d3a4d)
2026-05-16 20:00:09 +00:00
Giteabot 367a72ce11 Indicate form field readonly via background, fix RunUser config (#37175, #37180) (#37184)
Backport #37175 by @silverwind

The `Run As Username` field on the install page was a `readonly` input
that looked editable but wasn't, confusing users. Style `readonly`
inputs with a subtle background, matching other frameworks.

<img width="735" height="131" alt="image"
src="https://github.com/user-attachments/assets/cb76ce71-faab-4300-811e-e4c503b59f9a"
/>

Backport #37180

The comment "so just use current one if config says default" is not
right anymore: "git" isn't the "default" value of RunUser (Comment out
app.example.ini #15807). The RunUser's value is from current session's
username.

Fixes #37174

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit b37e098ff0)
2026-05-16 20:00:01 +00:00
Giteabot 4957f351d0 Remove dead CSS rules (#37173) (#37177)
Backport #37173 by @silverwind

Remove CSS rules whose HTML classes/IDs are no longer referenced in any
template, Go source, or JavaScript/TypeScript file:

- `.archived-icon`: removed from templates in c85bb62635
- `.bottom-line`: removed from blame rendering in 9c6aeb47f7
- `.commit-status-link`: removed from templates in f3c4baa84b
- `.instruct-toggle`: removed from templates in 75e85c25c1
- `.runner-new-text`, `#runner-new`: never referenced outside CSS
- `.ap-terminal`: stale, asciinema-player uses `.ap-term`, still not
needed
- `.scrolling.dimmable.dimmed`: dimmer stand-in never adds this class
- `.markup span.align-center/align-right/float-left/float-right`: never
produced by any renderer, sanitizer strips class attributes
- `.markup ul.no-list`, `.markup ol.no-list`: same as above

---
This PR was written with the help of Claude Opus 4.6

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit f9b808a8d2)
2026-05-16 19:59:44 +00:00
Giteabot 43197a9efd Fix flaky TestCatFileBatch/QueryTerminated test (#37159) (#37178)
Backport #37159 by @silverwind

`TestCatFileBatch/QueryTerminated` relied on timing to distinguish
`os.ErrClosed` vs `io.EOF` error paths. Replace `time.Sleep`-based
synchronization with a channel-based hook on pipe close, making both
error paths fully deterministic regardless of CI runner speed.

Ref:
https://github.com/go-gitea/gitea/actions/runs/24193070536/job/70615366804

---
This PR was written with the help of Claude Opus 4.6

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit 0112ec9b34)
2026-05-16 19:59:32 +00:00
Giteabot e334806d4e Add missing //nolint:depguard (#37162) (#37170)
Backport #37162 by @silverwind

When running `golangci-lint` without `GOEXPERIMENT=jsonv2`, a lint error
`import 'encoding/json' is not allowed` is seen.

All other files in the module that import `encodings/json` have
`//nolint` already, so add it.

---
This PR was written with the help of Claude Opus 4.6

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
(cherry picked from commit fc5e0ec877)
2026-05-16 19:59:19 +00:00
silverwind 3759793fa8 Replace rollup-plugin-license with rolldown-license-plugin (#37130) (#37158)
Backport #37130. Only one merge conflict in lockfile.

---
This PR was written with the help of Claude Opus 4.6

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
(cherry picked from commit d0a39bc3a4)
2026-05-16 19:59:03 +00:00
Giteabot 7e79b87136 Report structurally invalid workflows to users (#37116) (#37164)
Backport #37116 by @bircni

`model.ReadWorkflow` succeeds for YAML that is syntactically valid but
fails deeper parsing in `jobparser.Parse` (e.g. blank lines inside `run:
|` blocks cause a SetJob round-trip error). Add
`ValidateWorkflowContent` which runs the full `jobparser.Parse` to catch
these cases, and use it in the file view, the actions workflow list, and
the workflow detection loop so users see the error instead of silently
getting a 500 or a dropped workflow.

Fixes #37115

Signed-off-by: Nicolas <bircni@icloud.com>
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit 4eca71d6d4)
2026-05-16 19:58:52 +00:00
Giteabot 09d8f9bc47 Clean up and improve non-gitea js error filter (#37148) (#37155)
Backport #37148 by @silverwind

1. Filter out errors that contain `chrome-extension://` etc protocols
2. Extract filtering into its own function and test it
3. Fix the `window.config.assetUrlPrefix` mock, guaranteed to end with
`/assets`
4. Remove useless `??` and `?.` for properties that always exist

---
This PR was written with the help of Claude Opus 4.6

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
(cherry picked from commit a2283a0c03)
2026-05-16 19:58:30 +00:00
Giteabot 469daf5924 Bump min go version to 1.26.2 (#37139) (#37143)
Backport #37139 by @silverwind

Update Go from 1.26.1 to 1.26.2 to fix 6 stdlib vulnerabilities:
- GO-2026-4947: `crypto/x509` chain building
- GO-2026-4946: `crypto/x509` policy validation
- GO-2026-4870: `crypto/tls` KeyUpdate DoS
- GO-2026-4869: `archive/tar` unbounded allocation
- GO-2026-4866: `crypto/x509` name constraints bypass
- GO-2026-4865: `html/template` XSS

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
(cherry picked from commit 3e6b9e5312)
2026-05-16 19:57:58 +00:00
petru 7ae0c597f1 feat(auth): add staged account request validation and admin review workflow
(cherry picked from commit b2b024d0b6)
2026-05-16 19:56:37 +00:00
petru 9da2215095 feat(admin): improve new account request notification safeguards
feat(admin): enforce fallback and subscription rules for new account request notifications

(cherry picked from commit 81727dd3e9)
2026-05-16 19:55:55 +00:00
petru f9131d4261 Added administrator notifications for pending account requests-Step1
(cherry picked from commit 97eee0a9a8)
2026-05-16 19:54:13 +00:00
petru 5acdf62b9a Disable last Admin to self delete
(cherry picked from commit c3b9d21472)
2026-05-16 19:53:43 +00:00
petru 0c3f3b85e8 Disable admin users to downgrade
(cherry picked from commit 5c88e0bc76)
2026-05-16 19:41:23 +00:00
petru fdb233150a Added Public/Private Badges & repos Settings links
(cherry picked from commit 4b334df6d4)
2026-05-16 19:39:51 +00:00
petru ffb13c1136 Added menu to smart-build.sh, fixed errors in some files
(cherry picked from commit db1e8b4021)
2026-05-16 19:39:41 +00:00
petru 0716d3fa15 Add some fetch & builing scripts
(cherry picked from commit eb0b9b2dee)
2026-05-16 19:36:28 +00:00
Lunny Xiao 1ad9e996be Changelog for 1.26.0-rc0 (#37134) 2026-04-07 20:33:38 -07:00
wxiaoguang 73e0e44298 Fix various problems (#37129)
* Fix #37128
    * Manually tested with various cases (issue, pr) X (close, reopen)
* Fix #36792
    * Fix the comment
* Fix #36755
    * Add a "sleep 3"
* Follow up #36697
    * Clarify the "attachment uploading" problem and function call

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: TheFox0x7 <thefox0x7@gmail.com>
2026-04-08 01:17:05 +08:00
Rohan Guliani 1b200dc3da Add support for RPM Errata (updateinfo.xml) (#37125)
Resolves https://github.com/go-gitea/gitea/issues/37124

This PR adds support for RPM Errata (security advisories, bugfixes, and
enhancements) to Gitea's built-in RPM registry.

---------

Signed-off-by: Rohan Guliani <rohansguliani@google.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-08 00:39:53 +08:00
Lunny Xiao 290edc1614 upgrade vite (#37126) 2026-04-07 09:16:22 +00:00
Nicolas adf440a3b3 Bugfix: Apply notify/register mail flags during install load (#37120)
`LoadSettingsForInstall` only ran `loadMailerFrom`, not
_loadRegisterMailFrom_ or _loadNotifyMailFrom_, so
Service.RegisterEmailConfirm and Service.EnableNotifyMail were never
read from app.ini on the install page.

Full startup runs those through loadMailsFrom; the install path was a
narrower subset and never included that step—an oversight from when
install-specific loading was added

Fixes #37112
2026-04-07 15:42:56 +08:00
Nicolas fc23bd7b3a Repair duration display for bad stopped timestamps (#37121)
Workflow run, job, task, and step durations could show **negative**
values (e.g. `-50s`) when `Stopped` was missing, zero (epoch), or
**before** `Started` (clock skew, races, reruns). The UI used
`calculateDuration` with no validation.

This change:

- Uses each row`s **Updated** timestamp as a **fallback end time** when
`Stopped` is invalid but the status is terminal, so duration
approximates elapsed time instead of `0s` or a negative.
- Keeps **`ActionRun.Duration()`** clamped to **≥ 0** when
`PreviousDuration` plus the current segment would still be negative
(legacy bad data).

Fixes #34582.

Co-authored-by: Composer <composer@cursor.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-07 02:11:52 +00:00
TheFox0x7 ff777cd2ad Add terraform state registry (#36710)
Adds terraform/opentofu state registry with locking. Implements: https://github.com/go-gitea/gitea/issues/33644. I also checked [encrypted state](https://opentofu.org/docs/language/state/encryption), it works out of the box.

Docs PR: https://gitea.com/gitea/docs/pulls/357

---------

Co-authored-by: Andras Elso <elso.andras@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-06 13:41:17 -07: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
silverwind 423cdd4d94 Improve control char rendering and escape button styling (#37094)
Follow-up to #37078.

- Use Unicode Control Pictures](U+2400-U+2421) to render C0 control characters
- Make it work in diff view too
- Replace escape warning emoji with SVG
- Align escape warning button with code lines

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-06 11:07:33 +00: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
TheFox0x7 ca51b4f875 Move package settings to package instead of being tied to version (#37026)
Unties settings page from package version and adds button to delete the
package version
Settings page now allows for deletion of entire package and it's
versions as opposed to a single version

Adds an API endpoint to delete the entire package with all versions from
registry

fixes: https://github.com/go-gitea/gitea/issues/36904

Co-Authored-By: gemini-3-flash

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-04-06 03:51:51 +08:00
silverwind a8938115d4 Merge some standalone Vite entries into index.js (#37085)
Keep `swagger` and `external-render-helper` as a standalone entries for
external render.

- Move `devtest.ts` to `modules/` as init functions
- Make external renders correctly load its helper JS and Gitea's current theme
- Make external render iframe inherit Gitea's iframe's background color to avoid flicker
- Add e2e tests for external render and OpenAPI iframe

---------

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-05 19:13:34 +00:00
github-actions[bot] 5f443184f3 Update Nix flake (#37110)
Automated changes by the
[update-flake-lock](https://github.com/DeterminateSystems/update-flake-lock)
GitHub Action.

```
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/46db2e0' (2026-03-24)
  → 'github:nixos/nixpkgs/6201e20' (2026-04-01)
```

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-04-05 18:25:27 +00:00
GiteaBot c9669594a8 [skip ci] Updated translations via Crowdin 2026-04-05 00:57:43 +00:00
Lunny Xiao 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
silverwind 3c17daf615 Update setup-uv to v8.0.0 (#37101)
Update to https://github.com/astral-sh/setup-uv/releases/tag/v8.0.0.
Note that version here must be the immutable `v8.0.0`, a mutable `v8`
tag does not exist.
2026-04-04 00:47:15 +02:00
wxiaoguang 2c2d7e6f64 Fix various bugs (#37096)
* Fix #36001
* Fix #35498
* Fix #35395
* Fix #35160
* Fix #35058
* Fix #35445
2026-04-03 20:03:59 +00:00
wxiaoguang f9f9876f2c Clean up AppURL, remove legacy origin-url webcomponent (#37090)
1. `origin-url` was introduced in the past when there was no good
framework support to detect current host url
    * It is not needed anymore
    * Removing it makes the code clearer
2. Separate template helper functions for different templates (web
page/mail)
3. The "AppURL" info is removed from admin config page: it doesn't
really help.
    * We already have various app url checks at many places
2026-04-03 17:56:31 +00:00
silverwind d80640fa5d Add e2e reaction test, improve accessibility, enable parallel testing (#37081)
Add a new e2e test for toggling issue reactions via the reaction picker
dropdown.

Add `aria-label` attributes to improve reaction accessibility:
- Add `aria-label="Reaction"` to the reaction picker dropdown
- Add `role="group"` with `aria-label="Reactions"` to the reactions
container, giving it a semantic identity for screen readers
- Include the reaction key in each reaction button's `aria-label` (e.g.
`+1: user1, user2`) so screen readers announce which reaction a button
represents

E2e test improvements:
- Simplify `randomString` to use `Math.random` instead of `node:crypto`
- Replace `generatePassword` with a static password, remove unused
`clickDropdownItem`
- Enable `fullyParallel: true` and `workers: '50%'` in Playwright config
- Run both chromium and firefox in all environments (not just CI)
- Parallelize `login` and `apiCreateRepo` setup where possible
- Use dedicated test user in `user-settings` test for concurrency safety

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-04-03 17:20:44 +00:00
wxiaoguang 74060bb849 Fix various legacy problems (#37092)
1.  Fix #36439
2. Fix #37089
3. Fix incorrect layout of admin auth oidc page
4. Fix #35866
5. Fix #35800
6. Fix #36243
2026-04-03 12:19:04 +00:00
Rohan Guliani 30c07c20e9 Fix RPM Registry 404 when package name contains 'package' (#37087)
Fixes #37086, fix the bug in MatchPath, and swap the order of
overlapping routes in api.go to make it look better.

---------

Signed-off-by: Rohan Guliani <rohansguliani@google.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-03 06:12:04 +00:00
Zettat123 f70f2c76cb Improve actions notifier for workflow_run (#37088)
Changes:

- Make `GetActionWorkflow` only convert the target workflow
- In `getActionWorkflowEntry`, use `branchName` instead of resolving the
default branch name from `commit.GetBranchName()`
- Add `ref` to `workflow_run` notify input to avoid the empty `ref`
warning

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-04-02 22:41:27 -07:00
wxiaoguang 6eed75af24 Refactor code render and render control chars (#37078)
Fix #37057
2026-04-02 21:10:01 -07:00
wxiaoguang 7b17234945 Fix various problems (#37077)
Quick fix for 1.26.

* Slightly refactor NewComment to fix incorrect responses, remove
incorrect defer (still far from ideal)
* Avoid `const` causes js error in global scope
* Don't process markup contents on user's home activity feed, to avoid
js error due to broken math/mermaid code

* Fix #36582

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-04-03 10:25:45 +08:00
GiteaBot 4fa319b9dc [skip ci] Updated translations via Crowdin 2026-04-03 00:53:56 +00:00
Zettat123 23c662ebb1 Support legacy run/job index-based URLs and refactor migration 326 (#37008)
Follow up #36842

Migration `326` can be prohibitively slow on large instances because it
scans and rewrites all commit status target URLs generated by Gitea
Actions in the database. This PR refactors migration `326` to perform a
partial update instead of rewriting every legacy target URL. The reason
for this partial rewrite is that **smaller legacy run/job indexes are
the most likely to be ambiguous with run/job ID-based URLs** during
runtime resolution, so this change prioritizes that subset while
avoiding the cost of rewriting all legacy records.

To preserve access to old links, this PR introduces
`resolveCurrentRunForView` to handle both ID-based URLs and index-based
URLs:

- For job pages (`/actions/runs/{run}/jobs/{job}`), it first tries to
confirm that the URL is ID-based. It does so by checking whether `{job}`
can be treated as an existing job ID in the repository and whether that
job belongs to `{run}`. If that match cannot be confirmed, it falls back
to treating the URL as legacy `run index + job index`, resolves the
corresponding run and job, and redirects to the correct ID-based URL.
- When both ID-based and index-based interpretations are valid at the
same time, the resolver **prefers the ID-based interpretation by
default**. For example, if a repository contains one run-job pair
(`run_id=3, run_index=2, job_id=4`), and also another run-job pair
(`run_id=1100, run_index=3, job_id=1200, job_index=4`), then
`/actions/runs/3/jobs/4` is ambiguous. In that case, the resolver treats
it as the ID-based URL by default and shows the page for `run_id=3,
job_id=4`. Users can still explicitly force the legacy index-based
interpretation with `?by_index=1`, which would resolve the same URL to
`/actions/runs/1100/jobs/1200`.
- For run summary pages (`/actions/runs/{run}`), it uses a best-effort
strategy: by default it first treats `{run}` as a run ID, and if no such
run exists in the repository, it falls back to treating `{run}` as a
legacy run index and redirects to the ID-based URL. Users can also
explicitly force the legacy interpretation with `?by_index=1`.
- This summary-page compatibility is best-effort, not a strict ambiguity
check. For example, if a repository contains two runs: runA (`id=7,
index=3`) and runB (`id=99, index=7`), then `/actions/runs/7` will
resolve to runA by default, even though the old index-based URL
originally referred to runB.

The table below shows how valid legacy index-based target URLs are
handled before and after migration `326`. Lower-range legacy URLs are
rewritten to ID-based URLs, while higher-range legacy URLs remain
unchanged in the database but are still handled correctly by
`resolveCurrentRunForView` at runtime.

| run_id | run_index | job_id | job_index | old target URL | updated by
migration 326 | current target URL | can be resolved correctly |
|---|---|---|---|---|---|---|---|
| 3 | 2 | 4 | 1 | `/user2/repo2/actions/runs/2/jobs/1` | true |
`/user2/repo2/actions/runs/3/jobs/4` | true |
| 4 | 3 | 8 | 4 | `/user2/repo2/actions/runs/3/jobs/4` | true |
`/user2/repo2/actions/runs/4/jobs/8` | true (without migration 326, this
URL will resolve to run(`id=3`)) |
| 80 | 20 | 170 | 0 | `/user2/repo2/actions/runs/20/jobs/0` | true |
`/user2/repo2/actions/runs/80/jobs/170` | true |
| 1500 | 900 | 1600 | 0 | `/user2/repo2/actions/runs/900/jobs/0` | false
| `/user2/repo2/actions/runs/900/jobs/0` | true |
| 2400 | 1500 | 2600 | 0 | `/user2/repo2/actions/runs/1500/jobs/0` |
false | `/user2/repo2/actions/runs/1500/jobs/0` | true |
| 2400 | 1500 | 2601 | 1 | `/user2/repo2/actions/runs/1500/jobs/1` |
false | `/user2/repo2/actions/runs/1500/jobs/1` | true |

For users who already ran the old migration `326`, this change has no
functional impact. Their historical URLs are already stored in the
ID-based form, and ID-based URLs continue to resolve correctly.

For users who have not run the old migration `326`, only a subset of
legacy target URLs will now be rewritten during upgrade. This avoids the
extreme runtime cost of the previous full migration, while all remaining
legacy target URLs continue to work through the web-layer compatibility
logic.

Many thanks to @wxiaoguang for the suggestions.
2026-04-02 17:23:29 -07:00
Lunny Xiao 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
silverwind 2158cf6e12 Fix NuGet package upload error handling (#37074)
Wrap `zip.NewReader` errors in NuGet `ParsePackageMetaData` and
`ExtractPortablePdb` as `ErrInvalidArgument` so invalid packages return
HTTP 400 (Bad Request) instead of 500 (Internal Server Error).

Add integration test for multipart/form-data NuGet upload path (used by
`dotnet nuget push`) which was previously untested.

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-01 23:54:14 +00:00
silverwind b53f25a30c Desaturate dark theme background colors (#37056)
Desaturate all structural grey colors in the dark theme from blue-grey
(H≈210°, S≈12-15%) to near-monochrome (H=220°, S=6%), using `#1e1f20` as
the page background color.

All colors preserve their original HSL lightness values. Semantic colors
(primary accent, named colors, diff, alerts, badges, brand) are
unchanged.

Motivation: The previous blue tint looked bad (kind of green-ish) on
certain screens and I think a near-monochrome color is more neutral
because its closer to being an inversion of the light theme.

Before and after:

<img width="280" alt="Screenshot 2026-04-02 at 00 18 38"
src="https://github.com/user-attachments/assets/544c71b9-fdaf-4222-822c-c5b87bc5b76d"
/>
<img width="280" alt="image"
src="https://github.com/user-attachments/assets/5d6de5d0-05c6-4a49-a649-063da4d136ce"
/>

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-04-02 01:24:52 +02:00
silverwind 3a9cab034b Update JS dependencies and misc tweaks (#37064)
- Update all JS deps
- Regenerate SVGs
- Add new eslint rules from unicorn
- Update typescript config for 6.0, remove deprecated options in favor
of `strict` with disablements, remove implicit dom libs.
- Set vite log level during `watch-frontend` to `warn` to avoid
confusing URLs or HMR spam from the dev server to keep the log concise.
Overridable via `FRONTEND_DEV_LOG_LEVEL`.

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-04-01 20:15:02 +02:00
Navneet 3ffccb8fe5 Redirect to the only OAuth2 provider when no other login methods and fix various problems (#36901)
Fixes: #36846 

1. When there is only on OAuth2 login method, automatically direct to it
2. Fix legacy problems in code, including:
   * Rename template filename and fix TODO comments
   * Fix legacy variable names
   * Add missing SSPI variable for template
   * Fix unnecessary layout, remove garbage styles
* Only do AppUrl(ROOT_URL) check when it is needed (avoid unnecessary
warnings to end users)

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-01 12:50:57 +00:00
Nicolas ca8c71359c Show workflow link (#37070)
Add the workflow link to the left list.

Superseeds #31906

---------

Signed-off-by: Nicolas <bircni@icloud.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-01 11:42:41 +00:00
silverwind 47a0d88056 Remove leftover webpackChunkName comments from codeeditor (#37062)
Followup to https://github.com/go-gitea/gitea/pull/36764, forgot to
remove this from the vite migration.

---
This PR was written with the help of Claude Opus 4.6

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-03-31 21:31:11 -07:00
silverwind a20e182067 Update Go dependencies (#36781)
Update all non-locked Go dependencies and pin incompatible ones.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-01 11:26:52 +08:00
Nicolas 35b654c9d6 Add webhook name field to improve webhook identification (#37025) (#37040)
Add an optional Name field to webhooks so users can give them
human-readable labels instead of relying only on URLs. The webhook
overview page now displays names when available, or falls back to the
URL for unnamed webhooks.

Fixes #37025

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-01 09:56:20 +08:00
silverwind 0df3213766 Upgrade go-git to v5.17.2 (#37060)
Upgrades `github.com/go-git/go-git/v5` from v5.16.5 to v5.17.2.

Fixes https://github.com/go-gitea/gitea/security/dependabot/188
Fixes https://github.com/go-gitea/gitea/security/dependabot/187

---
This PR was written with the help of Claude Opus 4.6

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-03-31 22:21:24 +00:00
silverwind e2e8509239 Replace Monaco with CodeMirror (#36764)
- Replace monaco-editor with CodeMirror 6
- Add `--color-syntax-*` CSS variables for all syntax token types,
shared by CodeMirror, Chroma and EasyMDE
- Consolidate chroma CSS into a single theme-independent file
(`modules/chroma.css`)
- Syntax colors in the code editor now match the code view and
light/dark themes
- Code editor is now 12px instead of 14px font size to match code view
and GitHub
- Use a global style for kbd elements
- When editing existing files, focus will be on codemirror instead of
filename input.
- Keyboard shortcuts are roughtly the same as VSCode
- Add a "Find" button, useful for mobile
- Add context menu similar to Monaco
- Add a command palette (Ctrl/Cmd+Shift+P or F1) or via button
- Add clickable URLs via Ctrl/Cmd+click
- Add e2e test for the code editor
- Remove `window.codeEditors` global
- The main missing Monaco features are hover types and semantic rename
but these were not fully working because monaco operated only on single
files and only for JS/TS/HTML/CSS/JSON.

| | Monaco (main) | CodeMirror (cm) | Delta |
|---|---|---|---|
| **Build time** | 7.8s | 5.3s | **-32%** |
| **JS output** | 25 MB | 14 MB | **-44%** |
| **CSS output** | 1.2 MB | 1012 KB | **-17%** |
| **Total (no maps)** | 23.3 MB | 12.1 MB | **-48%** |

Fixes: #36311
Fixes: #14776
Fixes: #12171

<img width="1333" height="555" alt="image"
src="https://github.com/user-attachments/assets/f0fe3a28-1ed9-4f22-bf25-2b161501d7ce"
/>

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-03-31 21:50:45 +00:00
Nicolas 4747dd68bd Update Combine method to treat warnings as failures and adjust tests (#37048)
Treat Commit Status Warnings as errors

> The root problem is that the definition of "warning" are different
across systems.
> 
> * Sometimes, "warning" is treated as "acceptable" (Gitea 1.25)
> * Sometimes, "warning" is mapped from "Result.UNSTABLE", which means
"there are test failures" and it is "failure" in Gitea
> 
> **To avoid breaking existing users, the best choice is to revert the
behavior on Gitea side: treat "warning" as "error".**


https://github.com/go-gitea/gitea/issues/37042#issuecomment-4158231611

fixes https://github.com/go-gitea/gitea/issues/37042

---------

Signed-off-by: Nicolas <bircni@icloud.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-31 17:22:18 +00:00
silverwind e15219d810 Raise minimum Node.js version to 22.18.0 (#37058)
Remove the experimental strip types check and `NODE_VARS` mechanism from
the Makefile, as Node.js 22.18.0+ has native TypeScript type stripping
support.

https://nodejs.org/en/blog/release/v22.18.0 was released 8 months ago
and has now trickled into all major Linux distros like Alpine 3.23+.

---
This PR was written with the help of Claude Opus 4.6

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-03-31 16:50:51 +00:00
silverwind d8da91a7f2 Update golangci-lint to v2.11.4 (#37059)
Update golangci-lint from v2.11.2 to v2.11.4 and fix new `modernize`
lint warnings:

- Use `strings.Builder` instead of string concatenation in loop
(`evaluator.go`)
- Use `atomic.Int64` instead of `int64` with atomic free functions
(`logchecker.go`, `timer_test.go`, `integration_test.go`)

---
This PR was written with the help of Claude Opus 4.6

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-03-31 16:22:23 +00:00
silverwind b20b0ed372 Upgrade golang.org/x/image to v0.38.0 (#37054)
Result of `go get -u golang.org/x/image && make tidy`.

Fixes https://github.com/go-gitea/gitea/security/dependabot/186
2026-03-31 15:12:22 +00:00
silverwind f8d14b77eb Increase e2e test timeouts on CI to fix flaky tests (#37053)
Introduce a `GITEA_TEST_E2E_TIMEOUT_FACTOR` env var (3 on CI, 1 locally,
overridable) to scale Playwright e2e timeouts, fixing flaky tests like
`logout propagation` that timed out waiting for SSE event propagation on
slow CI runners.

| Timeout | Before (local) | After (local) | Before (CI) | After (CI) |
|---|---|---|---|---|
| expect | 3000 | 5000 | 6000 | 15000 |
| action | 3000 | 5000 | 6000 | 15000 |
| test | 6000 | 10000 | 12000 | 30000 |
| navigation | 6000 | 10000 | 12000 | 30000 |

---
This PR was written with the help of Claude Opus 4.6

---------

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-03-31 13:59:25 +00:00
wxiaoguang d288b4529b Refactor "org teams" page and help new users to "add member" to an org (#37051)
* Fix #22054
* Replace #34593, #27800
* And refactor legacy code, fix various problems

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-31 21:30:25 +08:00
wxiaoguang 6ca5573718 Refactor issue sidebar and fix various problems (#37045)
Fix various legacy problems, including:

* Don't create default column when viewing an empty project
* Fix layouts for Windows
* Fix (partially) #15509
* Fix (partially) #17705

The sidebar refactoring: it is a clear partial-reloading approach,
brings better user experiences, and it makes "Multiple projects" /
"Project column on issue sidebar" feature easy to be added.

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-31 10:03:52 +08:00
wxiaoguang daf581fa89 Add tests for pull request's content_version in API (#37044)
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-03-30 17:28:45 +00:00
silverwind 9bb0aa1c49 Enable concurrent vitest execution (#36998)
Enable
[`sequence.concurrent`](https://vitest.dev/config/sequence.html#sequence-concurrent)
to run all js tests in parallel. This will help catch potential
concurrency bugs in the future. The "Repository Branch Settings" test
was not concurrency-safe, it was refactored to remove shared mutable
state.

Co-Authored-By: Claude (claude-opus-4-6) <noreply@anthropic.com>

---------

Co-authored-by: Claude (claude-opus-4-6) <noreply@anthropic.com>
2026-03-30 16:17:16 +00:00
silverwind 612ce46cda Fix theme discovery and Vite dev server in dev mode (#37033)
1. In dev mode, discover themes from source files in
`web_src/css/themes/` instead of AssetFS. In prod, use AssetFS only.
Extract shared `collectThemeFiles` helper to deduplicate theme file
handling.
2. Implement `fs.ReadDirFS` on `LayeredFS` to support theme file
discovery.
3. `IsViteDevMode` now performs an HTTP health check against the vite
dev server instead of only checking the port file exists. Result is
cached with a 1-second TTL.
4. Refactor theme caching from mutex to atomic pointer with time-based
invalidation, allowing themes to refresh when vite dev mode state
changes.
5. Move `ViteDevMiddleware` into `ProtocolMiddlewares` so it applies to
both install and web routes.
6. Show a `ViteDevMode` label in the page footer when vite dev server is
active.
7. Add `/__vite_dev_server_check` endpoint to vite dev server for the
health check.
8. Ensure `.vite` directory exists before writing the dev-port file.
9. Minor CSS fixes: footer gap, navbar mobile alignment.

---
This PR was written with the help of Claude Opus 4.6

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-30 14:59:10 +00:00
techknowlogick 539654831a bump snapcraft deps (#37039) 2026-03-30 13:47:41 +00:00
Myers Carpenter c31e0cfc1c Expose content_version for optimistic locking on issue and PR edits (#37035)
- Add `content_version` field to Issue and PullRequest API responses
- Accept optional `content_version` in `PATCH
/repos/{owner}/{repo}/issues/{index}` and `PATCH
/repos/{owner}/{repo}/pulls/{index}` — returns 409 Conflict when stale,
succeeds silently when omitted (backward compatible)
- Pre-check `content_version` before any mutations to prevent partial
writes (e.g. title updated but body rejected)

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-30 13:44:32 +00:00
Myers Carpenter 2633f9677d Correct swagger annotations for enums, status codes, and notification state (#37030)
## ⚠️ BREAKING ⚠️

- delete reaction endpoints is changed to return 204 No Content rather
than 200 with no content.

## Summary

Add swagger:enum annotations and migrate all enum comments from the
deprecated comma-separated format to JSON arrays. Introduce
NotifySubjectStateType with open/closed/merged values. Fix delete
reaction endpoints to return 204 instead of 200.
2026-03-30 08:28:48 +08:00
github-actions[bot] cbea04c1fc Update Nix flake (#37024) 2026-03-29 18:25:18 -04:00
techknowlogick d7070b8513 Bump go and python versions in nix flake (#37031) 2026-03-29 23:02:15 +02:00
silverwind 50a1dc9486 Make task list checkboxes clickable in the preview tab (#37010)
When a checkbox is toggled in the markup preview tab, the change is now
synced back to the editor textarea. Extracted a `toggleTasklistCheckbox`
helper to deduplicate the byte-offset toggle logic.

---------

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-03-29 18:48:40 +00:00
Nicolas da51d5af1a Add support for in_progress event in workflow_run webhook (#36979)
With Gitea 1.25.4 the workflow event for in_progress was not triggered
for Gitea Actions.

Fixes #36906

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 11:12:46 -07:00
wxiaoguang a88449f13f Fix various problems (#37029)
1. Use "margin/padding inline" 
   * Fix  #37027
2. Make DetectWellKnownMimeType fallback to system mime types
3. Make catFileBatchCommunicator close pipes
* Old behavior in 1.25:
https://github.com/go-gitea/gitea/blob/release/v1.25/modules/git/batch_reader.go#L45-L55
   * Try to fix #37028
2026-03-29 17:39:15 +00:00
Nicolas 755d200371 Update AI Contribution Policy (#37022)
I tried to tighten the AI contribution policy and make the expectations
around AI-assisted submissions clearer.

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Giteabot <teabot@gitea.io>
Co-authored-by: silverwind <me@silverwind.io>
2026-03-29 16:57:39 +00:00
silverwind 0ec66b5380 Migrate from webpack to vite (#37002)
Replace webpack with Vite 8 as the frontend bundler. Frontend build is
around 3-4 times faster than before. Will work on all platforms
including riscv64 (via wasm).

`iife.js` is a classic render-blocking script in `<head>` (handles web
components/early DOM setup). `index.js` is loaded as a `type="module"`
script in the footer. All other JS chunks are also module scripts
(supported in all browsers since 2018).

Entry filenames are content-hashed (e.g. `index.C6Z2MRVQ.js`) and
resolved at runtime via the Vite manifest, eliminating the `?v=` cache
busting (which was unreliable in some scenarios like vscode dev build).

Replaces: https://github.com/go-gitea/gitea/pull/36896
Fixes: https://github.com/go-gitea/gitea/issues/17793
Signed-off-by: silverwind <me@silverwind.io>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-29 10:24:30 +00:00
Lunny Xiao 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
Nicolas db7eb4d51b Fix issue label deletion with Actions tokens (#37013)
Use shared repo permission resolution for Actions task users in issue
label remove and clear paths, and add a regression test for deleting
issue labels with a Gitea Actions token.

This fixes issue label deletion when the request is authenticated with a
Gitea Actions token.
Fixes #37011 

The bug was that the delete path re-resolved repository permissions
using the normal user permission helper, which does not handle Actions
task users. As a result, `DELETE
/api/v1/repos/{owner}/{repo}/issues/{index}/labels/{id}` could return
`500` for Actions tokens even though label listing and label addition
worked.

---------

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-03-29 09:21:14 +00:00
Lunny Xiao 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
silverwind 84daa0b8be Update AGENTS.md with additional guidelines (#37018)
Add and modify more instruction for common problems in this codebase and
made the force-push instruction more strict.

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-03-28 16:44:17 -07:00
Ross Golder 487e357ce6 Optimize 'refreshAccesses' to perform update without removing then adding (#35702)
- Optimize refreshAccesses with cross-comparison to minimize DB operations
- Fix db.Find syntax in refreshAccesses optimization
- Add test for refreshAccesses update path and fix db.Find syntax

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-29 00:34:17 +08:00
silverwind 7492251e7e Fix relative-time RangeError (#37021)
`navigator.language` can be `undefined` in headless browsers (e.g.
Playwright Firefox), causing `RangeError: invalid language tag:
"undefined"` in `Intl.DateTimeFormat` within the `relative-time` web
component.

Also adds an e2e test that verifies `relative-time` renders correctly
and a shared `assertNoJsError` helper.

Bug is als present in https://github.com/github/relative-time-element
but (incorrectly) masked there.

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

---------

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-28 13:10:51 +00:00
Nicolas b136a66d12 Restyle Workflow Graph (#36912)
Follow GitHub's style and fine tune colors & layouts.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-03-28 09:41:34 +00:00
silverwind 896e4838cb Update message severity colors, fix navbar double border (#37019)
- Tweak serverity background and border colors
- Use default text color instead of per-severity text colors.
- Replace `saturate` filter with semibold font weight on message headers.
- Fix navbar double border when a notification is present.

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-03-28 09:05:56 +00:00
silverwind 17b802beae Clean up checkbox cursor styles (#37016)
1. Remove non-functional `label:enabled` selector (`:enabled` only works
on [form controls](https://html.spec.whatwg.org/multipage/semantics-other.html#concept-element-disabled), not labels)
2. Remove `cursor: auto` which caused an I-beam text selection cursor on checkbox labels. The default browser styles work find and show regular cursor.
3. Remove `cursor: pointer` on checkbox itself, opinionated and not needed.

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-03-28 08:59:52 +01:00
TheFox0x7 74c40d46ee add missing cron tasks to example ini (#37012)
closes: https://github.com/go-gitea/gitea/issues/37009
docs PR: https://gitea.com/gitea/docs/pulls/371
2026-03-27 16:38:40 -07:00
silverwind de478c4b6f Add e2e tests for server push events (#36879)
Add e2e tests for the three server push features:
- **Notification count**: verifies badge appears when another user
creates an issue
- **Stopwatch**: verifies stopwatch element is rendered when a stopwatch
is active
- **Logout propagation**: verifies logout in one tab triggers redirect
in another

Tests are transport-agnostic in preparation for a future WebSocket
migration.

---------

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-27 11:49:11 +01:00
silverwind b3c6917463 Update JS dependencies (#37001)
- Update all JS dependencies via `make update-js`
- `webpack-cli` 6 to 7: remove `--disable-interpret` from Makefile
- Fix lint: remove unnecessary type args, `toThrowError` to `toThrow`
- Fix duplicate CSS selector detected by `stylelint` 17.6.0
- Change `updates.config.ts` to use `pin`, needed for `tailwindcss`
- Pin `typescript` pending typescript-eslint/typescript-eslint#12123

---------

Co-authored-by: Claude (claude-opus-4-6) <noreply@anthropic.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-03-27 04:39:24 +01:00
GiteaBot 12737883ba [skip ci] Updated translations via Crowdin 2026-03-27 00:53:48 +00:00
Zettat123 8fdd6d1235 Fix missing workflow_run notifications when updating jobs from multiple runs (#36997)
This PR fixes `notifyWorkflowJobStatusUpdate` to send
`WorkflowRunStatusUpdate` for each affected workflow run instead of only
the first run in the input job list.
2026-03-26 19:48:04 +01:00
silverwind d5a89805d9 Improve severity labels in Actions logs and tweak colors (#36993)
Add support for error, warning, notice, and debug log commands with bold
label prefixes and colored backgrounds matching GitHub's style. Parse
both `##[cmd]` and `::cmd args::` formats.

Also improved the severity colors globally and added a devtest page for
these.

---------

Co-authored-by: Claude (claude-opus-4-6) <noreply@anthropic.com>
2026-03-26 10:18:50 +00:00
silverwind 9583e1a65c Linkify URLs in Actions workflow logs (#36986)
Detect URLs in Actions log output and render them as clickable links,
similar to how GitHub Actions handles this. Pre-existing links from
ansi_up's OSC 8 parsing are also kept intact.

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (claude-opus-4-6) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-26 09:48:09 +00:00
GiteaBot ffa626b585 [skip ci] Updated translations via Crowdin 2026-03-26 00:53:31 +00:00
Copilot a3cc34472b Pass ServeHeaderOptions by value instead of pointer, fine tune httplib tests (#36982)
Pass `ServeHeaderOptions` by value instead of pointer across all call
sites — no nil-check semantics are needed and the struct is small enough
that copying is fine.

## Changes

- **`services/context/base.go`**: `SetServeHeaders` and `ServeContent`
accept `ServeHeaderOptions` (value, not pointer); internal unsafe
pointer cast replaced with a clean type conversion
- **`routers/api/packages/helper/helper.go`**: `ServePackageFile`
variadic changed from `...*context.ServeHeaderOptions` to
`...context.ServeHeaderOptions`; internal variable is now a value type
- **All call sites** (13 files): `&context.ServeHeaderOptions{...}` →
`context.ServeHeaderOptions{...}`

Before/after at the definition level:
```go
// Before
func (b *Base) SetServeHeaders(opt *ServeHeaderOptions) { ... }
func (b *Base) ServeContent(r io.ReadSeeker, opts *ServeHeaderOptions) { ... }
func ServePackageFile(..., forceOpts ...*context.ServeHeaderOptions) { ... }

// After
func (b *Base) SetServeHeaders(opts ServeHeaderOptions) { ... }
func (b *Base) ServeContent(r io.ReadSeeker, opts ServeHeaderOptions) { ... }
func ServePackageFile(..., forceOpts ...context.ServeHeaderOptions) { ... }
```

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: wxiaoguang <2114189+wxiaoguang@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-25 16:07:59 -07:00
ChristopherHX bc5c554072 Feature non-zipped actions artifacts (action v7) (#36786)
- content_encoding contains a slash => v4 artifact
- updated proto files to support mime_type and no longer return errors for upload-artifact v7
- json and txt files are now previewed in browser
- normalized content-disposition header creation
- azure blob storage uploads directly in servedirect mode (no proxying data)
- normalize content-disposition headers based on go mime package
  - getting both filename and filename* encoding is done via custom code

Closes #36829

-----

Signed-off-by: ChristopherHX <christopher.homberger@web.de>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-26 00:37:48 +08:00
techknowlogick 435123fe65 Switch cmd/ to use constructor functions. (#36962)
This is a step towards potentially splitting command groups into their
own folders to clean up `cmd/` as one folder for all cli commands.
Returning fresh command instances will also aid in adding tests as you
don't need to concern yourself with the whole command tree being one
mutable variable.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-25 15:53:13 +01:00
silverwind bb1e22bba4 Allow text selection on checkbox labels (#36970)
Remove `user-select: none` from checkbox labels to allow text selection
which is sometimes useful.

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-03-25 07:40:46 +00:00
Nicolas e24c3f7a40 Fix org contact email not clearable once set (#36975)
When the email field was submitted as empty in org settings (web and
API), the previous guard `if form.Email != ""` silently skipped the
update, making it impossible to remove a contact email after it was set.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-25 15:23:11 +08:00
techknowlogick 943ff75233 Require additional user confirmation for making repo private (#36959)
To align with how GitHub requires additional explicit user interaction
to make a repo private, including informing them of implications on what
happens if they do.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-24 20:13:08 +00:00
TheFox0x7 cfd9008891 add valid github scopes (#36977)
test for github supported scopes with test to ensure all of them work
and don't panic

fixes: https://github.com/go-gitea/gitea/issues/36967
2026-03-24 19:16:23 +00:00
Tyrone Yeh c96cc70144 Add class "list-header-filters" to the div for projects (#36889)
closes #36886
2026-03-24 17:23:13 +00:00
silverwind 66b8178e59 Improve AGENTS.md (#36974)
1. Remove header line, useless context bloat
2. Reword all "before commiting" lines because some people may not be
using the agent to commit, only to write changes.
2026-03-24 17:49:29 +01:00
Lunny Xiao c453d09c36 Catch scanner error when possible to avoid bypass (#36963) 2026-03-23 21:08:48 -07:00
GiteaBot c5e196dedb [skip ci] Updated translations via Crowdin 2026-03-24 00:45:32 +00:00
wxiaoguang 63c2b69259 Make PUBLIC_URL_DETECTION default to "auto" (#36955)
Related issues including: #36939 , #35619, #34950 , #34253 , #32554

For users who use reverse-proxy, we have documented the requirements
clearly since long time ago :
https://docs.gitea.com/administration/reverse-proxies
2026-03-23 23:19:08 +00:00
Nicolas 86401fd5fd Fix user settings sidebar showing disabled features on some pages (#36958)
Move UserDisabledFeatures context data into a shared SettingsCtxData
middleware for the /user/settings route group, so it is set consistently
on all pages (including Notifications, Actions, etc.) instead of only on
the handlers that remembered to set it individually.

Fixes #36954
2026-03-23 22:30:48 +00:00
silverwind cf1e4d7c42 Update GitHub Actions to latest major versions (#36964)
Update all Actions to their latest major versions:

- `actions/checkout`: v5 → v6
- `dorny/paths-filter`: v3 → v4
- `pnpm/action-setup`: v4 → v5
- `docker/setup-qemu-action`: v3 → v4
- `docker/setup-buildx-action`: v3 → v4
- `docker/build-push-action`: v6 → v7
- `docker/metadata-action`: v5 → v6
- `docker/login-action`: v3 → v4
- `crazy-max/ghaction-import-gpg`: v6 → v7
- `aws-actions/configure-aws-credentials`: v5 → v6

All updates are Node 24 runtime bumps with no workflow-breaking changes
for our usage.

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-03-23 14:42:36 -07:00
wxiaoguang 4f9f0fc4b8 Fix various trivial problems (#36953)
1. remove `TEST_CONFLICTING_PATCHES_WITH_GIT_APPLY`
* it defaults to false and is unlikely to be useful for most users (see
#22130)
* with new git versions (>= 2.40), "merge-tree" is used,
"checkConflictsByTmpRepo" isn't called, the option does nothing.
2. fix fragile `db.Cell2Int64` (new: `CellToInt`)
3. allow more routes in maintenance mode (e.g.: captcha)
4. fix MockLocale html escaping to make it have the same behavior as
production locale
2026-03-23 18:23:42 +00:00
silverwind 788200de9f Rework checkbox styling, remove input border hover effect (#36870)
- Rework all checkbox styling to be consistent inside and outside
markup.
- Remove `input` border hover effect. Was too subtle and honestly
unneeded, consistent with GitHub.
- Increase `input` border contrast slightly.
- Some small spacing fixes in Markup (nested tasklist and spacing after
checkbox).

<img width="221" height="222" alt="Screenshot 2026-03-09 at 08 18 19"
src="https://github.com/user-attachments/assets/9e66abee-7102-4abe-9b00-e3f9b24ed735"
/>
<img width="226" height="217" alt="Screenshot 2026-03-09 at 08 18 10"
src="https://github.com/user-attachments/assets/33cdac26-4479-41da-9488-e60d70c5c997"
/>
<img width="79" height="218" alt="Screenshot 2026-03-09 at 08 17 32"
src="https://github.com/user-attachments/assets/ae1064a2-2bb3-44e7-a00b-2f4f5aad4241"
/>
<img width="267" height="297" alt="Screenshot 2026-03-09 at 08 17 07"
src="https://github.com/user-attachments/assets/1237fa98-0d94-4023-a87d-190d89c57421"
/>
<img width="558" height="260" alt="Screenshot 2026-03-09 at 08 21 04"
src="https://github.com/user-attachments/assets/1908a794-3394-494c-b2d5-470c00c668d1"
/>

---------

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-03-23 17:41:04 +00:00
silverwind ef88cdb7e7 Add DEFAULT_DELETE_BRANCH_AFTER_MERGE setting (#36917)
Add this config option, applying to new repos:

```ini
[repository.pull-request]
DEFAULT_DELETE_BRANCH_AFTER_MERGE = true
```

Defaults to `false`, preserving current behavior.

---------

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-03-23 17:34:45 +00:00
github-actions[bot] 1edbc21fcc Update Nix flake (#36943)
Automated changes by the
[update-flake-lock](https://github.com/DeterminateSystems/update-flake-lock)
GitHub Action.

```
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/c06b4ae' (2026-03-13)
  → 'github:nixos/nixpkgs/b40629e' (2026-03-18)
```

### Running GitHub Actions on this PR

GitHub Actions will not run workflows on pull requests which are opened
by a GitHub Action.

**To run GitHub Actions workflows on this PR, close and re-open this
pull request.**

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-23 13:28:30 +00:00
silverwind ae0bc0222a Update to eslint 10 (#36925)
- Enable a few more rules, fix issues. The 2 `value` issues are
false-positives.
- Add exact types for `window.pageData` and
`window.notificationSettings`.
- peerDependencyRules for eslint-plugin-github unrestricted, the plugin
works in v10, but does not declare compatibility, pending
https://github.com/github/eslint-plugin-github/issues/680.
- Added
[eslint-plugin-de-morgan](https://github.com/azat-io/eslint-plugin-de-morgan),
no violations.

---------

Signed-off-by: silverwind <me@silverwind.io>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-03-23 07:49:25 +00:00
Nicolas 4ba90207cf Add user badges (#36752)
Implemented #29798

This feature implements list badges, create new badges, view badge, edit
badge and assign badge to users.

- List all badges
![(screenshot)](https://github.com/user-attachments/assets/9dbf243e-c704-49f8-915a-73704e226da9)
- Create new badges
![(screenshot)](https://github.com/user-attachments/assets/8a3fff7e-fe6f-49b0-a7c5-bbba34478019)
- View badge
![(screenshot)](https://github.com/user-attachments/assets/dd7a882b-6e2c-47d2-93e0-05a2698a41e5)
![(screenshot)](https://private-user-images.githubusercontent.com/75789103/558982759-53536300-e189-406b-8b0e-824e1a768b92.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzQxOTMyMjUsIm5iZiI6MTc3NDE5MjkyNSwicGF0aCI6Ii83NTc4OTEwMy81NTg5ODI3NTktNTM1MzYzMDAtZTE4OS00MDZiLThiMGUtODI0ZTFhNzY4YjkyLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjAzMjIlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMzIyVDE1MjIwNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTUxNjQ5ZDUyMGVlNWRmODg1OGUyN2NiOWI3YTAxODhiMjRhM2U1OGQ1NWMwNjQ0MTBmNTRjNTBjYjIzN2ExMWEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.4aAfpFaziiXDG7W2HaNJop0B62-NR4f0Ni9YNjTZq0M)
- Edit badge
![(screenshot)](https://github.com/user-attachments/assets/7124671a-ed97-4c98-ac7d-34863377fa62)
- Add user to badge
![(screenshot)](https://github.com/user-attachments/assets/3438b492-0197-4acb-b9f2-2f9f7c80582e)
2026-03-22 15:49:45 +00:00
bircni aa9aea2c6e Apply as maintainer (#36947)
I'd like to apply as a maintainer.

Thanks to @TheFox0x7 for the suggestion.

Merged PRs:
- #36441
- #36571
- #36603
- #36768
- #36776
- #36783
- #36876
- #36883
- #36924

Ongoing work:
- #36514
- #36752
- #36912
2026-03-22 08:18:42 -07:00
ChristopherHX 0ab612f5ab Refactor storage content-type handling of ServeDirectURL (#36804)
* replace raw url.Values by *storage.ServeDirectOptions
* implement content-type in azblob
* implement content-disposition in azblob
* add tests for content types in response
* http.MethodPut for azure now allows implementing servedirect uploads

---------

Signed-off-by: ChristopherHX <christopher.homberger@web.de>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-21 21:26:13 -07:00
bircni c8545033cc Add summary to action runs view (#36883)
When opening a Actions run without a job in the path (`/actions/runs/{run}`),
show a run summary.

---------

Signed-off-by: Nicolas <bircni@icloud.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-22 01:04:39 +00:00
Excellencedev 45809c8f54 feat: Add configurable permissions for Actions automatic tokens (#36173)
## Overview

This PR introduces granular permission controls for Gitea Actions tokens
(`GITEA_TOKEN`), aligning Gitea's security model with GitHub Actions
standards while maintaining compatibility with Gitea's unique repository
unit system.

It addresses the need for finer access control by allowing
administrators and repository owners to define default token
permissions, set maximum permission ceilings, and control
cross-repository access within organizations.

## Key Features

### 1. Granular Token Permissions

- **Standard Keyword Support**: Implements support for the
`permissions:` keyword in workflow and job YAML files (e.g., `contents:
read`, `issues: write`).
- **Permission Modes**:
- **Permissive**: Default write access for most units (backwards
compatible).
- **Restricted**: Default read-only access for `contents` and
`packages`, with no access to other units.
- ~~**Custom**: Allows defining specific default levels for each unit
type (Code, Issues, PRs, Packages, etc.).~~**EDIT removed UI was
confusing**
- **Clamping Logic**: Workflow-defined permissions are automatically
"clamped" by repository or organization-level maximum settings.
Workflows cannot escalate their own permissions beyond these limits.

### 2. Organization & Repository Settings

- **Settings UI**: Added new settings pages at both Organization and
Repository levels to manage Actions token defaults and maximums.
- **Inheritance**: Repositories can be configured to "Follow
organization-level configuration," simplifying management across large
organizations.
- **Cross-Repository Access**: Added a policy to control whether Actions
workflows can access other repositories or packages within the same
organization. This can be set to "None," "All," or restricted to a
"Selected" list of repositories.

### 3. Security Hardening

- **Fork Pull Request Protection**: Tokens for workflows triggered by
pull requests from forks are strictly enforced as read-only, regardless
of repository settings.
- ~~**Package Access**: Actions tokens can now only access packages
explicitly linked to a repository, with cross-repo access governed by
the organization's security policy.~~ **EDIT removed
https://github.com/go-gitea/gitea/pull/36173#issuecomment-3873675346**
- **Git Hook Integration**: Propagates Actions Task IDs to git hooks to
ensure that pushes performed by Actions tokens respect the specific
permissions granted at runtime.

### 4. Technical Implementation

- **Permission Persistence**: Parsed permissions are calculated at job
creation and stored in the `action_run_job` table. This ensures the
token's authority is deterministic throughout the job's lifecycle.
- **Parsing Priority**: Implemented a priority system in the YAML parser
where the broad `contents` scope is applied first, allowing granular
scopes like `code` or `releases` to override it for precise control.
- **Re-runs**: Permissions are re-evaluated during a job re-run to
incorporate any changes made to repository settings in the interim.

### How to Test

1. **Unit Tests**: Run `go test ./services/actions/...` and `go test
./models/repo/...` to verify parsing logic and permission clamping.
2. **Integration Tests**: Comprehensive tests have been added to
`tests/integration/actions_job_token_test.go` covering:
   - Permissive vs. Restricted mode behavior.
   - YAML `permissions:` keyword evaluation.
   - Organization cross-repo access policies.
- Resource access (Git, API, and Packages) under various permission
configs.
3. **Manual Verification**: 
   - Navigate to **Site/Org/Repo Settings -> Actions -> General**.
- Change "Default Token Permissions" and verify that newly triggered
workflows reflect these changes in their `GITEA_TOKEN` capabilities.
- Attempt a cross-repo API call from an Action and verify the Org policy
is enforced.

## Documentation

Added a PR in gitea's docs for this :
https://gitea.com/gitea/docs/pulls/318

## UI:

<img width="1366" height="619" alt="Screenshot 2026-01-24 174112"
src="https://github.com/user-attachments/assets/bfa29c9a-4ea5-4346-9410-16d491ef3d44"
/>

<img width="1360" height="621" alt="Screenshot 2026-01-24 174048"
src="https://github.com/user-attachments/assets/d5ec46c8-9a13-4874-a6a4-fb379936cef5"
/>

/fixes #24635
/claim #24635

---------

Signed-off-by: Excellencedev <ademiluyisuccessandexcellence@gmail.com>
Signed-off-by: ChristopherHX <christopher.homberger@web.de>
Signed-off-by: silverwind <me@silverwind.io>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: ChristopherHX <christopher.homberger@web.de>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-21 15:39:47 -07:00
bircni b22123ef86 Feature: Add button to re-run failed jobs in Actions (#36924)
Fixes #35997

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-21 21:27:13 +00:00
Mykhailo ee009ebec8 Support dark/light theme images in markdown (#36922)
This PR matches GitHub's behavior more closely on how to render Markdown
images in light/dark mode.
Images with source suffix `#gh-dark-mode-only` / `#gh-light-mode-only`
will only show when the correct theme is requested.
Closes: #35545

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-21 12:44:33 +00:00
Paulo Chen 0e0cf7a813 fix #36463: preserve sort order of exclusive labels from template repo (#36931)
When creating a new repository and copying issue labels from a template,
the explicit sort order of exclusive labels was previously being lost
(resetting to 0). This fix ensures that the original sort order for
exclusive labels (e.g., 1, 2) is properly copied and retained in the
newly created repository.

Fixes #36463

---------

Signed-off-by: Paulo Chen <paulochen@tecnico.ulisboa.pt>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-21 06:54:28 +00:00
Xijiang Yu 068d7a513a fix(upgrade.sh): use HTTPS for GPG key import and restore SELinux context after upgrade (#36930)
## Summary

Two bug fixes for `contrib/upgrade.sh` found during a real-world upgrade
from 1.24.3 to 1.25.5 on Fedora.

---

### Fix 1: GPG key import fails when HKP port 11371 is blocked (closes
#36928)

**Before:**
```bash
gpg --keyserver keys.openpgp.org --recv 7C9E68152594688862D62AF62D9AE806EC1592E2
```
This uses HKP port **11371**, which is blocked by many firewalls. The
upgrade aborts with:
```
gpg: keyserver receive failed: Connection timed out
```

**After:**
```bash
curl -fsSL --connect-timeout 10 \
  "https://keys.openpgp.org/vks/v1/by-fingerprint/7C9E68152594688862D62AF62D9AE806EC1592E2" \
  | gpg --import \
  || gpg --keyserver keyserver.ubuntu.com --recv 7C9E68152594688862D62AF62D9AE806EC1592E2 \
  || gpg --keyserver keys.openpgp.org --recv 7C9E68152594688862D62AF62D9AE806EC1592E2
```
Same `keys.openpgp.org` server, same key — but fetched over **HTTPS port
443** which is universally accessible. Keyservers remain as fallbacks.

---

### Fix 2: Gitea fails to start after upgrade on SELinux systems (closes
#36929)

**Problem:** After `mv`-ing the binary from `$giteahome` to
`/usr/local/bin/gitea`, the file retains the SELinux context of the
source directory. Systemd refuses to execute it, exiting with
`status=203/EXEC`.

**Fix:** Add a `restorecon` call guarded by `command -v` so it is a
no-op on non-SELinux systems:
```bash
command -v restorecon &>/dev/null && restorecon -v "$giteabin" || true
```
Verified: `restorecon -v /usr/local/bin/gitea` immediately restored
service on the affected machine.

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-19 11:12:53 -07:00
GiteaBot 79f96b3e24 [skip ci] Updated translations via Crowdin 2026-03-19 00:50:44 +00:00
wxiaoguang 00060ff73c Make container registry support Apple Container (basic auth) (#36920)
Fix #36907
2026-03-18 23:43:44 +00:00
wxiaoguang 18c65965ab Fix various trivial problems (#36921)
* Fix #36915
* Fix #36919
* Close #36600
* Close #36601
* Fix incorrect oauth2 error message display
2026-03-19 07:13:55 +08:00
GiteaBot d6496c6156 [skip ci] Updated translations via Crowdin 2026-03-18 00:50:32 +00:00
github-actions[bot] 455dd20365 Update Nix flake (#36902)
Automated changes by the
[update-flake-lock](https://github.com/DeterminateSystems/update-flake-lock)
GitHub Action.

```
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/aca4d95' (2026-03-06)
  → 'github:nixos/nixpkgs/c06b4ae' (2026-03-13)
```

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-17 07:50:23 +00:00
silverwind 89cd3737bc Migrate fomantic search and modal CSS to first-party modules (#36869)
Replace the fomantic search.css (520 lines) and modal.css (698 lines)
with minimal first-party modules containing only the rules actually
used. Hardcoded colors are replaced with theme variables, and the
base.css overrides are merged directly into the new modules.

With this change, all original Fomantic CSS is now gone.

**search.css**: 520 → 85 lines
**modal.css**: 698 → 329 lines

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-03-17 07:07:48 +01:00
Nicolas b3b2d111da Feature: Add per-runner “Disable/Pause” (#36776)
This PR adds per-runner disable/enable support for Gitea Actions so a
registered runner can be paused from picking up new jobs without
unregistering.

Disabled runners stay registered and online but are excluded from new
task assignment; running tasks are allowed to finish. Re-enabling
restores pickup, and runner list/get responses now expose disabled
state.

Also added an endpoint for testing
http://localhost:3000/devtest/runner-edit/enable

<img width="1509" height="701" alt="Bildschirmfoto 2026-02-27 um 22 13
24"
src="https://github.com/user-attachments/assets/5328eda9-e59c-46b6-b398-f436e50ee3da"
/>


Fixes: https://github.com/go-gitea/gitea/issues/36767
2026-03-16 10:24:36 -07:00
silverwind 6372cd7c7d Enable native dark mode for swagger-ui (#36899)
Enable swagger-ui's dark mode support added in
https://github.com/swagger-api/swagger-ui/pull/10653. Background colors
match gitea, link colors match swagger-ui.

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-03-14 09:50:23 +01:00
Zettat123 e29d1b79d8 Front port changelog for 1.25.5 (#36892)
Frontport #36885

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-03-13 18:17:53 +01:00
majianhan 877f091305 Fix typos in code comments: doesnt, dont, wont (#36890)
Fix missing apostrophes in contractions across multiple source files.

Changes:
- `doesnt` -> `doesn't` in `routers/api/v1/repo/git_ref.go` (2
occurrences)
- `dont` -> `don't` in `models/activities/notification_list.go`,
`modules/indexer/code/bleve/token/path/path.go`,
`routers/api/v1/repo/release.go`,
`services/migrations/gitea_downloader.go`,
`services/repository/contributors_graph.go`
- `wont` -> `won't` in `routers/api/v1/repo/issue_subscription.go`,
`models/issues/label_test.go`

Ref: #35015 (good first issues - improve English)

---------

Co-authored-by: majianhan <majianhan@kylinos.cn>
Co-authored-by: silverwind <me@silverwind.io>
2026-03-13 09:58:44 -07:00
silverwind 28e09ffc67 Vendor relative-time-element as local web component (#36853)
Replace the `@github/relative-time-element` npm dependency with a
vendored, simplified implementation.

- Support 24h format rendering [PR
329](https://github.com/github/relative-time-element/pull/329)
- Enable `::selection` styling in Firefox [PR
341](https://github.com/github/relative-time-element/pull/341)
- Remove timezone from tooltips (It's always local timezone)
- Clean up previous `title` workaround in tippy
- Remove unused features
- Use native `Intl.DurationFormat` with fallback for older browsers,
remove dead polyfill
- Add MIT license header to vendored file
- Add unit tests
- Add dedicated devtest page for all component variants

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude claude-opus-4-6 20250630 <noreply@anthropic.com>
2026-03-13 10:43:17 +00:00
silverwind 2601f50026 Bound PageSize in ListUnadoptedRepositories (#36884)
Add `SetDefaultValues()` call to ensure PageSize is bounded, preventing
potential excessive memory allocation from unbounded pagination
parameters.

Fixes CodeQL alert
[#188](https://github.com/go-gitea/gitea/security/code-scanning/188).
All other 49 open alerts were false-positives and are dismissed with
appropriate comments.

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-03-13 01:20:58 +00:00
silverwind 538ec6ae6e Fix timeline event layout overflow with long content (#36595)
Fixes: https://github.com/go-gitea/gitea/issues/36580

Bug is caused by abuse of float layout, convert layout to flex to fix
it. There are more float abuses, but this shouldn't cause any other
regressions.

Before:

<img width="939" height="165" alt="Screenshot 2026-02-12 at 06 22 45"
src="https://github.com/user-attachments/assets/3e0aea82-d31e-4f4f-97d1-903b9f34de8d"
/>

After:

<img width="961" height="191" alt="image"
src="https://github.com/user-attachments/assets/b8fa64dc-594f-46a6-87e4-c20475e7d1e8"
/>

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 10:25:09 +02:00
GiteaBot 356f589f0b [skip ci] Updated translations via Crowdin 2026-03-11 00:45:56 +00:00
Zettat123 385994295d Replace index with id in actions routes (#36842)
This PR migrates the web Actions run/job routes from index-based
`runIndex` or `jobIndex` to database IDs.

**⚠️ BREAKING ⚠️**: Existing saved links/bookmarks that use the old
index-based URLs will no longer resolve after this change.

Improvements of this change:
- Previously, `jobIndex` depended on list order, making it hard to
locate a specific job. Using `jobID` provides stable addressing.
- Web routes now align with API, which already use IDs.
- Behavior is closer to GitHub, which exposes run/job IDs in URLs.
- Provides a cleaner base for future features without relying on list
order.
- #36388 this PR improves the support for reusable workflows. If a job
uses a reusable workflow, it may contain multiple child jobs, which
makes relying on job index to locate a job much more complicated

---------

Signed-off-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-10 22:14:48 +01:00
silverwind 6e8f78ae27 Enable eslint concurrency (#36878)
Add `--concurrency 2` to all ESLint invocations in the Makefile. ESLint
v9 supports multi-threaded linting via worker threads.

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-03-10 17:05:52 +00:00
Nicolas 8d06a9425e Update minimum go version to 1.26.1, golangci-lint to 2.11.2, fix test style (#36876)
Hey, I bumped Go to 1.26.1 and fixed a couple of things I ran into while
poking around.

### Changes

- Bump go.mod from 1.26.0 to 1.26.1 (security patch)
- Bump golangci-lint from v2.10.1 to v2.11.2
- Run make tidy, fmt, lint-go

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-03-10 06:26:52 +00:00
silverwind 1dfb32a36f Add render cache for SVG icons (#36863)
Cache the final rendered `template.HTML` output for SVG icons that use
non-default size or class parameters using `sync.Map`.

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-10 05:26:16 +00:00
bytedream 47085f3fa0 Fix incorrect viewed files counter if reverted change was viewed (#36819)
If a file is marked as viewed in a PR and all changes to those file are
reverted afterwards, the file is still stored as viewed in the db, which
causes an incorrect viewed files counter

---

<img width="468" height="139" alt="image"
src="https://github.com/user-attachments/assets/f13bf161-142d-49a9-8425-3884ee7abb84"
/>
2026-03-09 08:23:36 +00:00
GiteaBot eb020a9d27 [skip ci] Updated translations via Crowdin 2026-03-09 00:49:16 +00:00
silverwind a52617b816 Clean up refreshViewedFilesSummary (#36868)
1. Use `textContent` instead of `innerHTML` to fix
https://github.com/go-gitea/gitea/security/code-scanning/170.
2. Clean up surrounding code to remove unnecessary `if` checks on
elements that are guaranteed to exist.

---------

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-03-08 20:49:07 +00:00
Copilot 80c57ec126 Remove util.URLJoin and replace all callers with direct path concatenation (#36867)
`util.URLJoin` was deprecated with unclear semantics (path normalization
via `url.Parse`/`ResolveReference` that surprised callers). This removes
it entirely and replaces all usages with straightforward `"/"` string
concatenation.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: wxiaoguang <2114189+wxiaoguang@users.noreply.github.com>
2026-03-09 02:30:54 +08:00
silverwind 23a5bc5e64 Optimize Docker build with dependency layer caching (#36864)
1. Copy dependency manifests before the full source copy so that
dependency installation gets its own cached layer. When only source code
changes, the dependency layers are reused.
2. Remove the `GOPROXY=direct` override which was bypassing the Go
module proxy, causing build failures when git servers are unreachable.
The Go default (`https://proxy.golang.org,direct`) is now used instead.

---------

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-03-08 15:58:21 +00:00
wxiaoguang 6f8ab6aaaf Fix URLJoin, markup render link reoslving, sign-in/up/linkaccount page common data (#36861)
The logic of "URLJoin" is unclear and it is often abused.

Also:
* Correct the `resolveLinkRelative` behavior
* Fix missing "PathEscape" in `ToTag`
* Fix more FIXMEs, and add new FIXMEs for newly found problems
* Refactor "auth page common template data"
2026-03-08 15:57:37 +00:00
silverwind 0724344a8a Fix CodeQL code scanning alerts (#36858)
Fixes 10 CodeQL code scanning alerts:

- Change `NewPagination`/`SetLinkHeader` to accept `int64` for total
count, clamping internally to fix incorrect-integer-conversion alerts
([#110](https://github.com/go-gitea/gitea/security/code-scanning/110),
[#114](https://github.com/go-gitea/gitea/security/code-scanning/114),
[#115](https://github.com/go-gitea/gitea/security/code-scanning/115),
[#116](https://github.com/go-gitea/gitea/security/code-scanning/116))
- Use `strconv.Atoi()` in `htmlrenderer.go` to avoid int64 intermediate
([#105](https://github.com/go-gitea/gitea/security/code-scanning/105),
[#106](https://github.com/go-gitea/gitea/security/code-scanning/106))
- Clamp regex match indices in `escape_stream.go` to fix
allocation-size-overflow
([#161](https://github.com/go-gitea/gitea/security/code-scanning/161),
[#162](https://github.com/go-gitea/gitea/security/code-scanning/162),
[#163](https://github.com/go-gitea/gitea/security/code-scanning/163))
- Cap slice pre-allocation in `GetIssueDependencies`
([#181](https://github.com/go-gitea/gitea/security/code-scanning/181))

---------

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-08 14:35:50 +00:00
wxiaoguang 3f1ef703d5 Refactor auth middleware (#36848)
Principles: let the caller decide what it needs, but not let the
framework (middleware) guess what it should do.

Then a lot of hacky code can be removed. And some FIXMEs can be fixed.

This PR introduces a new kind of middleware: "PreMiddleware", it will be
executed before all other middlewares on the same routing level, then a
route can declare its options for other middlewares.

By the way, allow the workflow badge to be accessed by Basic or OAuth2
auth.

Fixes: https://github.com/go-gitea/gitea/pull/36830
Fixes: https://github.com/go-gitea/gitea/issues/36859
2026-03-08 17:59:46 +08:00
github-actions[bot] a0996cb229 Update Nix flake (#36857)
Automated changes by the
[update-flake-lock](https://github.com/DeterminateSystems/update-flake-lock)
GitHub Action.

```
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/dd9b079' (2026-02-27)
  → 'github:nixos/nixpkgs/aca4d95' (2026-03-06)
```

### Running GitHub Actions on this PR

GitHub Actions will not run workflows on pull requests which are opened
by a GitHub Action.

**To run GitHub Actions workflows on this PR, close and re-open this
pull request.**

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-08 07:04:28 +00:00
silverwind 6e7bc1e635 Update JS deps (#36850)
Gets rid of all open vulns except
https://github.com/microsoft/monaco-editor/issues/5248. Cursorly tested,
works.

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-03-08 07:29:27 +01:00
silverwind 130e34994f Load mentionValues asynchronously (#36739)
Eliminate a few database queries on all issue and pull request pages by
moving mention autocomplete data to async JSON endpoints fetched
on-demand when the user types `@`.

See https://github.com/go-gitea/gitea/pull/36739#issuecomment-3963184858
for the full table of affected pages.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-07 12:37:37 -08:00
GiteaBot f250138f57 [skip ci] Updated translations via Crowdin 2026-03-07 00:46:12 +00:00
wxiaoguang 2ce71629c3 Fix dbfs error handling (#36844)
Add tests for opening non-existing files.
2026-03-07 00:28:46 +08:00
Lunny Xiao 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
Michael Hoang c710ce34fb Fix non-admins unable to automerge PRs from forks (#36833)
Make `handlePullRequestAutoMerge` correctly check the
permissions of the merging user against pr.BaseRepo.

---------

Co-authored-by: Michael Hoang <enzime@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-03-06 00:03:12 +00: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
Théo LUDWIG 9fe5b70e3e build(deps): update material-icon-theme v5.32.0 (#36832)
Updated https://github.com/material-extensions/vscode-material-icon-theme to
v5.32.0 and ran `make svg && git add --all`
2026-03-05 11:51:26 -08:00
Lunny Xiao 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 Xiao 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
ChristopherHX 867c4af481 Fix artifacts v4 backend upload problems (#36805)
* Use base64.RawURLEncoding to avoid equal sign
  * using the nodejs package they seem to get lost
* Support uploads with unspecified length
* Support uploads with a single named blockid
  * without requiring a blockmap

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-05 16:49:01 +01:00
Lunny Xiao 5d87bb3d45 Add a git grep search timeout (#36809) 2026-03-04 12:11:42 -08:00
Tyrone Yeh 79ae9ea97b fix(repo): unify DEFAULT_SHOW_FULL_NAME output in templates and dropdown (#36597)
The design of DefaultShowFullName has some problems, which make the UI
inconsistent, see the new comment in code

This PR does a clean up for various legacy problems, and clarify some
"user name display" behaviors.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-04 21:23:17 +08:00
Lunny Xiao 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
GiteaBot b874e0d8e5 [skip ci] Updated translations via Crowdin 2026-03-04 00:47:08 +00:00
OptionalValue 484eacb7bf fix: /repos/{owner}/{repo}/actions/{runs,jobs} requiring owner permissions (#36818)
Resolves #36268

The REST endpoints:

`/repos/{owner}/{repo}/actions/runs`
`/repos/{owner}/{repo}/actions/jobs`

currently require repository/organisation owner permissions, even though
in GitHub they only need simple "read" permissions on the repo.
In the web interface this is implemented correctly, where anyone with
"read" permissions can see the list of action runs.

---------

Co-authored-by: Leonard Immel <l.immel@lipowsky.de>
2026-03-03 11:23:27 -08:00
Copilot 93e3be3018 Fix CRAN package version validation to allow more than 4 version components (#36813)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: wxiaoguang <2114189+wxiaoguang@users.noreply.github.com>
2026-03-04 01:56:38 +08:00
silverwind 761b9d439b Fix API not persisting pull request unit config when has_pull_requests is not set (#36718)
The `PATCH /api/v1/repos/{owner}/{repo}` endpoint silently ignores pull
request config fields (like `default_delete_branch_after_merge`,
`allow_squash_merge`, etc.) unless `has_pull_requests: true` is also
included in the request body. This is because the entire PR unit config
block was gated behind `if opts.HasPullRequests != nil`.

This PR restructures the logic so that PR config options are applied
whenever the pull request unit already exists on the repo, without
requiring `has_pull_requests` to be explicitly set. A new unit is only
created when `has_pull_requests: true` is explicitly sent.

Fixes https://github.com/go-gitea/gitea/issues/36466
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-03-02 22:08:53 +00:00
Nicolas 054eb6d8a5 feat: Add Actions API rerun endpoints for runs and jobs (#36768)
This PR adds official REST API endpoints to rerun Gitea Actions workflow
runs and individual jobs:

* POST /api/v1/repos/{owner}/{repo}/actions/runs/{run}/rerun
* POST /api/v1/repos/{owner}/{repo}/actions/runs/{run}/jobs/{job_id}/rerun

It reuses the existing rerun behavior from the web UI and exposes it
through stable API routes.

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-03-02 21:34:06 +00:00
Lunny Xiao 56f23f623a Fix bug when pushing mirror with wiki (#36795)
Fix #36736
2026-03-02 20:58:07 +00:00
Adam Majer 37f6f7f6d4 Pull Request Pusher should be the author of the merge (#36581)
In manual merge detected changes, the pushing user should be the
de-facto author of the merge, not the committer. For ff-only merges, the
author (PR owner) often have nothing to do with the merger. Similarly,
even if a merge commit exists, it does not indicate that the merge
commit author is the merger. This is especially true if the merge commit
is a ff-only merge on a given branch.
    
If pusher is for some reason unavailable, we fall back to the old method
of using committer or owning organization as the author.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-02 20:05:58 +00:00
Lunny Xiao 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 Xiao 716a800f50 Remove API registration-token (#36801)
Replace #36793

---------

Co-authored-by: ChristopherHX <christopher.homberger@web.de>
2026-03-02 10:31:42 -08:00
silverwind 7889b78c87 Add background and run count to actions list page (#36707)
Use flex-container layout and wrap the actions runs list with `ui top
attached header` and `ui attached segment` to add a background. Display
the total workflow run count in the header.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 15:40:49 +00:00
silverwind 08254cf126 Enable docker layer caching for dry-run and nightly container builds (#36738)
Enable Docker BuildKit layer caching for the dry-run and nightly
container build workflows using GHCR registry cache.

- **Dry-run** (`pull-docker-dryrun.yml`): adds `cache-from`, read-only,
PRs can't write cache
- **Nightly** (`release-nightly.yml`): adds `cache-from` and `cache-to`
to both read and write cach

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:18:46 +00:00
silverwind c3b1e7372e Add admin badge to navbar avatar (#36790)
Replace the standalone site admin icon in the navbar with a
Discord-style shield badge on the user avatar.

<img width="278" height="73" alt="image"
src="https://github.com/user-attachments/assets/0b074006-30b9-43c6-8ef2-2120e32e139a"
/>


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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 20:48:47 +00:00
ChristopherHX bc9817b317 WorkflowDispatch api optionally return runid (#36706)
Implements
https://github.blog/changelog/2026-02-19-workflow-dispatch-api-now-returns-run-ids

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-01 11:58:16 -08:00
Lunny Xiao 553277b0be upgrade minimatch (#36760) 2026-03-01 10:56:32 -08:00
Zettat123 5b8c8e724f Add never option to PUBLIC_URL_DETECTION configuration (#36785)
Follow up #34250

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

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-01 18:33:47 +00:00
wxiaoguang 2c624d4deb Refactor avatar package, support default avatar fallback (#36788)
* Fix #34715
2026-03-01 13:32:35 +00:00
wxiaoguang 1592576fa5 Mark unused&immature activitypub as "not implemented" (#36789)
After many years, "activitypub" is still "in progress" and no real
progress for end users. So it is not mature.

Temporarily mark the endpoints as "501 not implemented",
and wait until the whole design is stable and usable.
2026-03-01 12:59:49 +00:00
shafi-VM e3cf360154 Add “Copy Source” to markup comment menu (#36726)
Any user with **read access** to a comment can now copy its raw markdown
source via the `···` context menu — no edit permission required.

Closes #36722.

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 09:11:25 +00:00
github-actions[bot] 3ee7a87c8a Update Nix flake (#36787) 2026-03-01 07:56:23 +00:00
Nikita Vakula 649ebeb120 Implements OIDC RP-Initiated Logout (#36724)
At logout time, if the user authenticated via OIDC, we look up the
provider's `end_session_endpoint` (already discovered by Goth from the
OIDC metadata) and redirect there with `client_id` and
`post_logout_redirect_uri`.

Non-OIDC OAuth2 providers (GitHub, GitLab, etc.) are unaffected — they
fall back to local-only logout.

Fix #14270 

---------

Signed-off-by: Nikita Vakula <nikita.vakula@alpsalpine.com>
Co-authored-by: Nikita Vakula <nikita.vakula@alpsalpine.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-01 06:28:26 +00:00
Jim Paris f02f419173 Fix README symlink resolution in subdirectories like .github (#36775)
Fixes #36774.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-01 05:33:08 +00:00
GiteaBot 48a3a47741 [skip ci] Updated translations via Crowdin 2026-03-01 00:55:03 +00:00
Nicolas dae2d32186 Correct spelling (#36783)
I was testing typos-cli and fixed some misspelled wording here.
All changes are internal — no public API fields, database columns,
locale keys, or migration names are affected.
2026-02-28 11:23:20 -08:00
xiaox 3b250ba04e refactor: replace legacy tw-flex utility classes with flex-text-block/inline (#36778)
## Summary

Replace combinations of `tw-flex tw-items-center` (with optional
`tw-gap-*`) with semantic `flex-text-block` or `flex-text-inline`
classes across 15 template files.

This follows the refactoring direction outlined in #35015 ("Refactor
legacy `tw-flex tw-items-center tw-gap-xx` to `flex-text-block` or
`flex-text-inline`").

## Changes

### Replacement rules applied:
- `tw-flex tw-items-center tw-gap-2` → `flex-text-block` (both have
`gap: 0.5rem`)
- `tw-flex tw-items-center tw-gap-1` → `flex-text-inline` (both have
`gap: 0.25rem`)
- `tw-flex tw-items-center` (no explicit gap) → `flex-text-block` where
the element is block-level and children benefit from the default gap
- `tw-flex tw-items-center` (inline context, e.g. `<a>`, `<span>`) →
`flex-text-inline`

### Files modified (15):
- `templates/admin/config.tmpl` — config page dt elements
- `templates/admin/repo/unadopted.tmpl` — unadopted repo list items
- `templates/base/head_navbar.tmpl` — active stopwatch popup
- `templates/org/header.tmpl` — org header action buttons
- `templates/org/home.tmpl` — member/team count links
- `templates/org/settings/labels.tmpl` — labels page header
- `templates/repo/branch/list.tmpl` — branch list header
- `templates/repo/commits_table.tmpl` — commits table header
- `templates/repo/diff/box.tmpl` — diff detail box
- `templates/repo/diff/new_review.tmpl` — review form header
- `templates/repo/issue/card.tmpl` — issue card unpin button
- `templates/repo/issue/view_content/attachments.tmpl` — attachment file
size
- `templates/repo/migrate/migrate.tmpl` — migration service cards
- `templates/shared/user/org_profile_avatar.tmpl` — org profile header
- `templates/webhook/new.tmpl` — webhook type dropdown text

### What was NOT changed:
- Elements with `tw-justify-between` or `tw-justify-center` (these need
additional classes)
- Elements whose children use explicit margins (`tw-mr-*`, `tw-ml-*`)
that would conflict with the gap from flex-text classes
- Fomantic UI form elements with special layout requirements

## Notes
- This PR was created with AI assistance (Claude). All changes were
reviewed individually to ensure semantic correctness and zero unintended
visual changes.
- No functional changes — purely CSS class refactoring.

Closes: part of #35015

Signed-off-by: xiaox315 <xiaox315@users.noreply.github.com>
Co-authored-by: xiaox315 <xiaox315@users.noreply.github.com>
2026-02-28 14:03:25 +01:00
silverwind 2e00b2f0bb Fix no-content message not rendering after comment edit (#36733)
When non-empty comment content edited is deleted, it would render a
empty comment body:

<img width="355" height="85" alt="image"
src="https://github.com/user-attachments/assets/3ab9d241-2668-435d-a584-afda2a5b7586"
/>

Fix it so it renders the same placeholder HTML that the server sends for
empty content before edits:

<img width="356" height="109" alt="image"
src="https://github.com/user-attachments/assets/3b54ccde-f7ec-466d-a887-418f4a906d05"
/>
2026-02-27 22:23:21 +00:00
yshyuk b24780b3a3 Fix typos and grammar in English locale (#36751)
Fix several English locale issues as suggested in #35015:

- Rename `enterred` to `entered` in locale keys
(`form.enterred_invalid_*`)
  and update all Go source references accordingly
- Fix subject-verb agreement in `oauth2_applications_desc` and
  `oauth2_application_create_description`
- Improve awkward phrasing in `startpage.license_desc`

Only `locale_en-US.json` is modified; other locales are managed by
Crowdin.

Ref #35015

---------

Signed-off-by: yshyuk <dbsrbtkd94@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 17:25:23 +00:00
silverwind 50ec48d9fe Move Fomantic dropdown CSS to custom module (#36530)
Moved fomantic dropdown css to custom module, tested on the dropdown
devtest page, it renders exactly the same as before while using roughly
50% less CSS. The clean up was very conservative, likely more can be
done in the future.

Also, this fixes a bug present on main branch where dropdown border has
incorrect color on hover.

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-27 16:45:10 +00:00
wxiaoguang ae2b19849d Use "Enable Gravatar" but not "Disable" (#36771)
* Fix #35685
* Fix #35627
* Fix #31112


Introduce "fipped" config value type, remove unused setting variables.
Make DisableGravatar=true by defult, remove useless config options from
the "Install" page.

The legacy config options are still kept because they are still the
fallback values for the system config options.

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-27 16:39:26 +00:00
James Robinson fde7f7db28 feat: add branch_count to repository API (#35351) (#36743)
Description
This PR adds a branch_count field to the repository API response.
Currently, clients have to fetch all branches via /branches just to
determine the total number of branches. This addition brings Gitea
closer to parity with GitLab's API and improves efficiency for UI/CLI
clients that need this metric.

Linked Issue
Fixes #35351

Changes
API Structs: Added BranchCount field to Repository struct in
modules/structs/repo.go.

Database Logic: Implemented CountBranches in models/git/branch.go using
XORM for efficient counting.

Service Layer: Updated the ToRepo conversion logic in
services/convert/repository.go to populate the new field during API
serialisation.

Tests: Added a new unit test TestCountBranches in
models/git/branch_test.go to verify counts (including handling of
deleted branches).

Screenshots
<img width="196" height="121" alt="Screenshot 2026-02-24 at 21 41 07"
src="https://github.com/user-attachments/assets/cd023e92-f338-448b-9e49-0a5d54cc96c2"
/>

Testing
Manually verified the output using curl against a local Gitea instance.

Verified that adding a branch increments the count and deleting a branch
(soft-delete) decrements it.

Ran backend linting: make lint-backend (Passed).

Ran specific unit test: go test -v -tags "sqlite sqlite_unlock_notify"
./models/git -run TestCountBranches (Passed).

Co-authored-by: silverwind <me@silverwind.io>
2026-02-27 14:10:01 +00:00
wxiaoguang 619db646f5 Deprecate RenderWithErr (#36769) 2026-02-27 12:38:44 +00:00
silverwind 72e63eef39 Lazy-load some Vue components, fix heatmap chunk loading on every page (#36719)
Lazy-load 3 Vue components that are safe to defer (no pop-in effects).
This reduces `index-domready` from 515 KiB to 502 KiB (-2.5%).

The old `vue3-calendar-heatmap` vendor chunk (264 KiB) that previously
loaded on every page is eliminated entirely — it was mostly duplicate
`tippy.js` and `vue` copies that webpack had split out. The actual
heatmap library is only ~12 KiB minified, now inlined into the
`ActivityHeatmap` async chunk.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-27 05:06:15 +00:00
silverwind b52d745d0a Filter out untracked files from spellchecking (#36756)
The integration tests leave some log files around and they were
triggering the spellchecker:

```
$ make lint-spell
tests/integration/gitea-integration-sqlite/log/gitea.log:316:69: "addres" is a misspelling of "address"
tests/integration/gitea-integration-sqlite/log/gitea.log:794:69: "addres" is a misspelling of "address"
tests/integration/gitea-integration-sqlite/log/gitea.log:1248:69: "addres" is a misspelling of "address"
tests/integration/gitea-integration-sqlite/log/gitea.log:2070:69: "addres" is a misspelling of "address"
```

With this change, untracked and ignored files will no longer be
spellchecked.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 23:06:31 +00:00
silverwind f109b97ddd Fix CSS stacking context issue in actions log (#36749)
`ansi_up` sets `opacity:.7` on faint text which causes a CSS stacking
context to be created that results in all "faint" elements rendering
above the header:

<img width="889" height="102" alt="Screenshot 2026-02-25 at 16 42 57"
src="https://github.com/user-attachments/assets/2602ba88-e7e5-4d09-8f29-4ca6c0297ebc"
/>

Fix it by adding a z-index to the header so it also has its own stacking
context and renders above:

<img width="890" height="94" alt="Screenshot 2026-02-25 at 16 42 41"
src="https://github.com/user-attachments/assets/760f99a8-e230-4022-8213-e88c16831850"
/>
2026-02-26 22:35:21 +00:00
WinterCabbage f9a2a8ae8d Fix milestone/project text overflow in issue sidebar (#36741)
Fixes #36732

Co-authored-by: Giteabot <teabot@gitea.io>
2026-02-26 19:58:10 +00:00
silverwind f7f55a356f Update tool dependencies and fix new lint issues (#36702)
## Summary
- Update golangci-lint v2.9.0 → v2.10.1, misspell v0.7.0 → v0.8.0,
actionlint v1.7.10 → v1.7.11
- Fix 20 new QF1012 staticcheck findings by using `fmt.Fprintf` instead
of `WriteString(fmt.Sprintf(...))`
- Fix SA1019: replace deprecated `ecdsa.PublicKey` field access with
`PublicKey.Bytes()` for JWK encoding, with SEC 1 validation and curve
derived from signing algorithm
- Add unit test for `ToJWK()` covering P-256, P-384, and P-521 curves,
also verifying correct coordinate padding per RFC 7518
- Remove dead staticcheck linter exclusion for "argument x is
overwritten before first use"

## Test plan
- [x] `make lint-go` passes with 0 issues
- [x] `go test ./services/oauth2_provider/ -run
TestECDSASigningKeyToJWK` passes for all curves

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 19:13:19 +00:00
Nicolas 26d83c932a Instance-wide (global) info banner and maintenance mode (#36571)
The banner allows site operators to communicate important announcements
(e.g., maintenance windows, policy updates, service notices) directly
within the UI.

The maintenance mode only allows admin to access the web UI.

* Fix #2345
* Fix #9618

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-26 23:16:11 +08:00
danigm d0f92cb0a1 Add created_by filter to SearchIssues (#36670)
This patch adds the created_by filter to the SearchIssues method.

tea cli has an option to filter by author when listing issues, but it's
not working. The tea command line creates this request for the API when
using the author filter:

```
$ tea issue list -l local --kind pull -A danigm -vvv http://localhost:3000/api/v1/repos/issues/search?created_by=danigm&labels=&limit=30&milestones=&page=1&state=open&type=pulls
```

This patch fixes the API to allow this kind of queries from go-sdk and
tea cli.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-02-26 11:56:02 +00:00
silverwind 0d006290a7 Inline and lazy-load EasyMDE CSS, fix border colors (#36714)
Replace the external easymde.min.css import with an inlined and
lazy-loaded CSS file that uses proper theme variables for border colors.
All EasyMDE/CodeMirror rules are scoped under `.EasyMDEContainer`,
removing the need for !important overrides.

- Fixes easymde borders, these were broken since a while now
- Scope all easymde styles to .EasyMDEContainer
- Inline easymde.min.css and codemirror.css into web_src/css/easymde.css
- Lazy-load the CSS alongside the JS in switchToEasyMDE()
- Fix .editor-toolbar and .CodeMirror border colors to use
--color-input-border matching textarea inputs
- Remove unused gutter, line number, and other unconfigured styles
- Move .editor-loading to codeeditor.css where it belongs

<img width="891" height="518" alt="image"
src="https://github.com/user-attachments/assets/87495de5-7872-4645-90e7-96fe0f782f02"
/>

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-26 10:50:44 +00:00
wxiaoguang 840cf68c3e Fix release draft access check logic (#36720)
1. remove hasRepoWriteScope to avoid abuse
2. clarify "ctx.Written" behavior
3. merge "read-only" tests to slightly improve performance
2026-02-25 20:59:29 +00:00
silverwind 9ae28b6f39 Change image transparency grid to CSS (#36711)
These new colors work much better on dark theme than before (where it
was far too bright).

<img width="731" height="533" alt="image"
src="https://github.com/user-attachments/assets/e2979935-87ac-4d0e-80e1-67fe6cd2d6c7"
/>

<img width="736" height="543" alt="image"
src="https://github.com/user-attachments/assets/96da1292-cc77-49bf-aa51-d48b6c7cf2b4"
/>

---------

Co-authored-by: Giteabot <teabot@gitea.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 20:20:28 +00:00
silverwind 0de8a3d3d8 Avoid opening new tab when downloading actions logs (#36740)
`target="_blank"` causes the browser to flash a new tab when actions
logs are downloaded. Using the
[`download`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/a#download)
attribute fixes this.
2026-02-25 20:08:08 +00: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
Viktor Suprun 577ed107dd Fix SVG height calculation in diff viewer (#36748)
Fixes #36742
2026-02-25 22:54:02 +08:00
wxiaoguang 2176e84ab9 Fix path resolving (#36734) 2026-02-25 01:21:07 +00:00
GiteaBot d19d4da5ce [skip ci] Updated translations via Crowdin 2026-02-25 00:51:54 +00:00
Lunny Xiao 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
wxiaoguang 75efc51e98 Fix incorrect setting loading order (#36735) 2026-02-24 23:46:08 +08:00
Md Ferdous Alam 429ba9c010 Use case-insensitive matching for Git error "Not a valid object name" (#36728)
Fixes #36727

Git is lowercasing the `fatal: Not a valid object name` error message
to follow its CodingGuidelines. This change makes the string matching
case-insensitive so it works with both the current and future Git
versions.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-24 12:25:34 +08:00
Semenets V. Pavel a8505269ca feat: Add workflow dependencies visualization (#36248)
Add workflow dependencies visualization

Related to #26062

This PR adds an interactive visualization component that displays job
dependencies in Gitea Actions workflow runs. It helps users understand
complex pipeline structures at a glance, addressing the difficulty of
comprehending dependency chains in current Gitea UI.

---------

Signed-off-by: Semenets V. Pavel <p.semenets@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-23 21:11:33 +08:00
Micah Kepe 427954ba6e Add keyboard shortcuts for repository file and code search (#36416)
Resolves #36417: Add GitHub-like keyboard shortcuts for repository
navigation:
- Press `T` to focus the "Go to file" search input
- Press `S` to focus the "Search code" input
- Press `Escape` to clear and unfocus search inputs

---------

Signed-off-by: Micah Kepe <micahkepe@gmail.com>
Signed-off-by: silverwind <me@silverwind.io>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-23 17:20:56 +08:00
silverwind 6e7991316c Refactor text utility classes to Tailwind CSS (#36703)
Replace Fomantic/custom CSS text utility classes with their Tailwind
equivalents:

- `.text.<color>` compound classes → `tw-text-<color>` classes
- `.text.small` (`font-size: 0.75em`) → `tw-text-xs` (11px)
- `.text.truncate` (`overflow-x: hidden; text-overflow: ellipsis;
white-space: nowrap; display: inline-block`) → `tw-inline-block
tw-truncate`

Remove the now-unused CSS rules from `base.css` and `dashboard.css`.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 22:56:33 +00:00
Lunny Xiao 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
Lunny Xiao 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
Lunny Xiao 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
silverwind 5f8e19fcef Move X_FRAME_OPTIONS setting from cors to security section (#30256)
## Summary

- Move `cors.X_FRAME_OPTIONS` to `security.X_FRAME_OPTIONS` (old
location still works with a deprecation warning)
- Support `"unset"` as a special value to remove the `X-Frame-Options`
header entirely
- Remove `X-Frame-Options` header from API responses (only set for
web/HTML responses)

## Migration

If you had customized `cors.X_FRAME_OPTIONS`, move it to the
`[security]` section. The old location is deprecated and will be removed
in a future release.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-22 20:26:46 +00:00
silverwind fed2d81e88 Update JS and PY deps (#36708)
`colord` reordered in package.json, otherwise just maintenance updates.
2026-02-22 19:56:45 +00:00
Lunny Xiao 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 Xiao 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
Yuriy Khlynovskiy d9ac0636d0 Add icon to buttons "Close with Comment", "Close Pull Request", "Close Issue" (#36654)
Newbies often use the "Close with Comments" button instead of deleting
their comment. Icon should prevent mis-clicks.

---------

Co-authored-by: Yuriy.Khlynovskiy <yuriy.khlynovskiy@incomsystem.ru>
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 13:12:07 +00:00
TheFox0x7 eb59b1a24a various fixes (#36697)
fixes bad address concat causing malformed address
Introduces new config options to for release attachments and number of
files to avoid sharing limits for PR/issue attachments and release ones

Fixes: https://github.com/go-gitea/gitea/issues/31638
Fixes: https://github.com/go-gitea/gitea/issues/35812
Doc update: https://gitea.com/gitea/docs/pulls/348
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-22 08:01:43 +01:00
silverwind bb41bca739 Add AI Contribution Policy to CONTRIBUTING.md (#36651)
Based on my recent experience of both using AI tools and reviewing
AI-generated pull requests. Partially based on
https://typescript-eslint.io/contributing/ai-policy/.

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: TheFox0x7 <thefox0x7@gmail.com>
2026-02-20 20:46:40 -08: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
silverwind 18e0746b7b Rework e2e tests (#36634)
- Replace the e2e tests initialization with a simple bash script,
removing the previous Go harness.
- `make test-e2e` is the single entry point. It always starts a fully
isolated ephemeral Gitea instance with its own temp directory, SQLite
database, and config — no interference with the developer's running
instance.
- A separate `gitea-e2e` binary is built via `EXECUTABLE_E2E` using
`TEST_TAGS` (auto-includes sqlite with `CGO_ENABLED=1`), keeping the
developer's regular `gitea` binary untouched.
- No more split into database-specific e2e tests. Test timeouts are
strict, can be relaxed later if needed.
- Simplified and streamlined the playwright config and test files.
- Remove all output generation of playwright and all references to
visual testing.
- Tests run on Chrome locally, Chrome + Firefox on CI.
- Simplified CI workflow — visible separate steps for frontend, backend,
and test execution.
- All exported env vars use `GITEA_TEST_E2E_*` prefix.
- Use `GITEA_TEST_E2E_FLAGS` to pass flags to playwright, e.g.
`GITEA_TEST_E2E_FLAGS="--ui" make test-e2e` for UI mode or
`GITEA_TEST_E2E_FLAGS="--headed" make test-e2e` for headed mode.
- Use `GITEA_TEST_E2E_DEBUG=1 make test-e2e` to show Gitea server
output.

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 16:26:47 -08:00
Lunny Xiao 86d102494b Remove unused functions (#36672)
Follow #36643
2026-02-20 22:49:02 +00:00
Lunny Xiao bcd253a310 Add migration http transport for push/sync mirror lfs (#36665) 2026-02-20 22:19:12 +00:00
Lunny Xiao 5ad87616c9 Fix track time issue id (#36664) 2026-02-20 21:48:54 +00:00
silverwind aedc564308 Refactor inline style attributes (#36652)
This is the result of a full-repo review to look for `style` attributes
that can be replaced with tailwind or other methods. I will manually
validate later.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-20 13:14:29 -08:00
github-actions[bot] bbea5e6c2d Update Nix flake (#36679)
Automated changes by the
[update-flake-lock](https://github.com/DeterminateSystems/update-flake-lock)
GitHub Action.

```
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/0b4defa' (2025-10-09)
  → 'github:nixos/nixpkgs/0182a36' (2026-02-17)
```

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-20 10:45:55 -08:00
Lunny Xiao d59df34a7d Upgrade gogit to 5.16.5 (#36680) 2026-02-20 18:01:50 +00:00
Jörg Thalheim 3830d488d5 actions: report commit status for pull_request_review events (#36589)
Workflows triggered by pull_request_review events (approved, rejected,
comment) complete successfully but never create a commit status on the
PR. This makes them invisible in the merge checks UI, breaking any CI
gate that re-evaluates on review submission.

The commit status handler's switch statement was missing the three
review event types, so they fell through to the default case which
returned empty strings. Additionally, review events use
PullRequestPayload but IsPullRequest() returns false for them (Event()
returns "pull_request_approved" etc. instead of "pull_request"), so
GetPullRequestEventPayload() refuses to parse their payload.

Signed-off-by: Jörg Thalheim <joerg@thalheim.io>
Co-authored-by: silverwind <me@silverwind.io>
2026-02-20 16:12:22 +00:00
silverwind 91dc737a35 Replace tinycolor2 with colord (#36673)
[`colord`](https://github.com/omgovich/colord) is significantly smaller
than [`tinycolor2`](https://github.com/bgrins/TinyColor) (~4KB vs ~29KB
minified) and ships its own TypeScript types, removing the need for
`@types/tinycolor2`.

Behaviour is exactly the same for our use cases. By using `.alpha(1)` we
force the function to always output 6-digit hex format (it would output
8-digit for non-opaque colors).

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 15:43:01 +00:00
silverwind 87f7291909 Make security-check informational only (#36681)
Change `security-check` not break the build which is a major
inconvenience as it breaks CI on all PRs.

https://github.com/go-gitea/gitea/security/dependabot already provides a
clean overview of outstanding security issues in dependencies and I'm
using it all the time to find and update vulnerable dependencies.
2026-02-20 16:40:07 +01:00
silverwind 5e9b9b33d1 Clean up Makefile, tests and legacy code (#36638)
This simplifies the Makefile by removing the whole-file wrapping that
creates a tempdir introduced by
https://github.com/go-gitea/gitea/pull/11126. REPO_TEST_DIR is removed
as well.

Also clean up a lot of legacy code: unnecessary XSS test, incorrect test
env init, unused "_old_uid" hack, etc

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-19 01:23:32 +00:00
silverwind 147bdfce0d Add actions.WORKFLOW_DIRS setting (#36619)
Fixes: https://github.com/go-gitea/gitea/issues/36612

This new setting controls which workflow directories are searched. The
default value matches the previous hardcoded behaviour.

This allows users for example to exclude `.github/workflows` from being
picked up by Actions in mirrored repositories by setting `WORKFLOW_DIRS
= .gitea/workflows`.

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 01:31:01 +01:00
silverwind b9d323c3d8 Replace google/go-licenses with custom generation (#36575)
Rewrite `build/generate-go-licenses.go` to use `go list -m -json all`
and read license files directly from the Go module cache instead of
relying on the buggy `google/go-licenses` tool.

This removes the need for CGO, GOOS=linux, and the intermediate temp
directory, while being like 100 times faster than before:

```
$ rm assets/go-licenses.json && time make assets/go-licenses.json
go run build/generate-go-licenses.go assets/go-licenses.json
make assets/go-licenses.json  0.21s user 0.22s system 173% cpu 0.247 total

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 04:13:26 +00:00
silverwind 2cb8f6a9a5 Remove redundant linter rules (#36658)
Clean up linter configs, removing redundant rules or dead disables. One
new rule enabled, no violations. Many revive rules had same or better
rules in staticcheck or govet.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-02-18 03:38:18 +00:00
Zettat123 72ab59efdb Fix TestActionsCollaborativeOwner (#36657)
In #32562, I incorrectly assigned mismatched `repo_id` values to the
`action_run` and `action_run_job` fixtures used in
`TestActionsCollaborativeOwner`. The changes introduced in #36173 will
cause the test to fail. This PR removes the incorrect fixtures and
switches to using mock workflows to test the relevant functionality.
2026-02-17 23:32:26 +00:00
Lunny Xiao 1ac4ad358a Use prev/next pagination for user profile activities page to speed up (#36642)
From my local test, it has 156,941 pages

Before
<img width="336" height="29" alt="image"
src="https://github.com/user-attachments/assets/a02dee98-03b3-486e-9039-0743340f44df"
/>

After
<img width="681" height="38" alt="image"
src="https://github.com/user-attachments/assets/384ab534-e3a7-424e-9bdd-5e6fba02b621"
/>
2026-02-17 23:01:41 +00:00
silverwind e79112170c Add "Run" prefix for unnamed action steps (#36624)
Steps defined with `run:` or `uses:` without an explicit `name:` now
display with a "Run <cmd>" prefix in the Actions log UI, matching GitHub
Actions behavior.

<img width="311" height="236" alt="image"
src="https://github.com/user-attachments/assets/9fde83f5-c43a-4732-ac55-0f4e1fbc1314"
/>

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-17 22:28:55 +00:00
silverwind 63266ba036 Fix theme loading in development (#36605)
Fixes: https://github.com/go-gitea/gitea/issues/36543

When running `make watch`, the backend may start before webpack finishes
building CSS theme files. Since themes were loaded once via sync.Once,
they would never reload, breaking the theme selector and showing a
persistent error on the admin page.

In dev mode, themes are now reloaded from disk on each access so they
become available as soon as webpack finishes. Production behavior is
unchanged where themes are loaded once and cached via sync.Once.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-17 21:46:42 +00:00
Lunny Xiao b970cc02c7 Remove i18n backport tool at the moment because of translation format changed (#36643)
Starting with v1.26, Gitea uses a JSON configuration file format instead
of the INI format used in v1.25 and earlier versions.

Because of this fundamental format change, a clean translation backport
to the v1.25 branch (or earlier release branches) is not feasible.The
recommended approach is:
- Wait until the release/v1.26 branch is created after the official
v1.26 release.
- Then introduce a new JSON-based configuration (or
migration/compatibility layer) on top of that branch.
2026-02-17 20:31:48 +00:00
Lunny Xiao 318cb85037 Fix bug the protected branch rule name is conflicted with renamed branch name (#36650)
Fix #36464
2026-02-17 20:01:56 +00:00
silverwind ddacefa5d6 Update JS deps (#36656)
Fixes a [security issue in
mermaid](https://github.com/mermaid-js/mermaid/issues/7345), tested
mermaid and asciinema.
2026-02-17 19:35:37 +01:00
silverwind d6be18e870 Load heatmap data asynchronously (#36622)
Fixes: https://github.com/go-gitea/gitea/issues/21045

- Move heatmap data loading from synchronous server-side rendering to
async client-side fetch via dedicated JSON endpoints
- Dashboard and user profile pages no longer block on the expensive
heatmap DB query during HTML generation
- Use compact `[[timestamp,count]]` JSON format instead of
`[{"timestamp":N,"contributions":N}]` to reduce payload size
- Public API (`/api/v1/users/{username}/heatmap`) remains unchanged
- Heatmap rendering is unchanged, still shows a spinner as before, which
will now spin a litte bit longer.

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-17 14:03:55 +00:00
silverwind 883af8d42d Fix multi-arch Docker build SIGILL by splitting frontend stage (#36646)
## Summary
- Split Dockerfile and Dockerfile.rootless into a two-stage build:
frontend assets are built on the native platform (`$BUILDPLATFORM`) then
copied to the per-architecture backend build stage
- This avoids running esbuild/webpack under QEMU emulation which causes
SIGILL (Invalid machine instruction) on arm64/riscv64
- Frontend assets (JS/CSS/fonts) are platform-independent so they only
need to be built once
- The `build-env` stage no longer needs `nodejs`/`pnpm` since it only
builds the Go backend

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: TheFox0x7 <thefox0x7@gmail.com>
2026-02-17 08:25:07 +00:00
silverwind 1b874d1403 Use first commit title for multi-commit PRs and fix auto-focus title field (#36606)
Fixes: https://github.com/go-gitea/gitea/issues/34865

1. When opening a PR from a branch with multiple commits, use the first
(oldest) commit's title as the default title instead of the branch name
2. Fix autofocus on PR title input field

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-17 09:06:27 +01:00
silverwind cfc60b2142 Use relative-time to render absolute dates (#36238)
`<relative-time>` can render absolute dates when passed
[`threshold="P0Y"`](https://github.com/github/relative-time-element#threshold-string-default-p30d)
and `prefix=""`, so remove the previously used `<absolute-date>` element
in its favor.

Devtest before:

<img width="324" height="210" alt="Screenshot 2025-12-23 at 20 22 44"
src="https://github.com/user-attachments/assets/cf78e0e7-f480-415f-98d5-09b25f9d5a8b"
/>

Devtest after:

<img width="274" height="184" alt="Screenshot 2025-12-23 at 20 22 49"
src="https://github.com/user-attachments/assets/5e7d25f6-eea1-4a8c-ba71-02b570804b95"
/>

Repo activity (rendering unchanged):

<img width="1023" height="67" alt="image"
src="https://github.com/user-attachments/assets/2c4fd6cb-14ab-43c6-ae4b-f86946b28288"
/>

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-16 10:58:04 +00:00
silverwind 0e99932530 Only turn links to current instance into hash links (#36237)
Given the following markdown:

```
http://localhost:3500/silverwind/symlink-test/commit/a832c723cd116df44cce6271c4a89afa4d8ec670
http://localhost:3500/silverwind/remap-css/commit/19fe6cdf81f7ec50b8cac2d6c28fe7c42c1ffe14
http://github.com/silverwind/symlink-test/commit/a832c723cd116df44cce6271c4a89afa4d8ec670
```

Previously, all links would turn into hash link, even ones to external
sites:

<img width="849" height="89" alt="Screenshot 2025-12-23 at 19 19 13"
src="https://github.com/user-attachments/assets/2ad35a18-4542-40a4-a838-7ab8ac8bc047"
/>

After this change, only links to the current instance, as identified by
`setting.AppURL` are turned into hash links:

<img width="850" height="87" alt="Screenshot 2025-12-23 at 19 18 56"
src="https://github.com/user-attachments/assets/2c49a5b2-426c-4a82-a610-9b9da8dcfff9"
/>

There is still one notable [difference with
GitHub](https://github.com/silverwind/symlink-test/issues/20#issuecomment-3687535938)
where the second link should render like `user/repo@<hash>`, not
`<hash>` as currently, I would like to fix that here as well.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 10:27:49 +00:00
silverwind a0160694b9 Enable nilnil linter for new code (#36591)
Fixes: https://github.com/go-gitea/gitea/issues/36152

Enable the `nilnil` linter while adding `//nolint` comments to existing
violations. This will ensure no new issues enter the code base while we
can fix existing issues gradually.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 09:57:18 +00:00
Alessandro Ferrari d9d66d04d0 fix: duplicate startup warnings in admin panel (#36641)
Fixes #36630

## Problem

`StartupProblems` warnings (from `deprecatedSetting` and other
`LogStartupProblem` calls) appear twice in the admin panel at `/-/admin`
and `/-/admin/self_check`.

`LoadCommonSettings()` is called twice during web server startup:
1. Early init via `cmd/main.go` → `InitWorkPathAndCommonConfig` →
`LoadCommonSettings()`
2. Web server startup via `cmd/web.go` → `serveInstalled` →
`LoadCommonSettings()`

The second call re-initializes the config provider first
(`InitCfgProvider`), but `StartupProblems` and `configuredPaths` are
never cleared between loads, so every warning gets appended twice.

## Fix

Clear `StartupProblems` and `configuredPaths` at the start of
`LoadCommonSettings()` so only the final load's warnings are retained.

This approach was chosen over clearing in `InitCfgProvider` because:
- Warnings are produced during settings load, not provider init
- Some callers set `CfgProvider` directly without calling
`InitCfgProvider`
- It avoids coupling correctness to a specific call ordering

## Screenshots

**Result** (single warning as expected):
<img width="1429" height="195" alt="Screenshot From 2026-02-16 01-27-01"
src="https://github.com/user-attachments/assets/d45313a2-f981-480b-9ffc-cbced7e40bb8"
/>

## testing

[x] Added `TestLoadCommonSettingsClearsStartupProblems` — verifies no
duplicate messages after consecutive loads
[x] Added `TestLoadCommonSettingsClearsConfiguredPaths` — verifies path
overlap map is identical after consecutive loads
[x] All existing `modules/setting` tests pass
[x] Manually verified in admin panel with deprecated `[oauth2].ENABLE`
setting

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-16 08:13:04 +00:00
silverwind 8fdda2dd83 Fix linguist-detectable attribute being ignored for configuration files (#36640)
Fixes: go-gitea/gitea#36637. `linguist-detectable` must be able to
override the config classification.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 03:32:46 +00:00
wxiaoguang 258754f299 Fix chroma lexer mapping (#36629)
Fix some edge cases for ".hcl" and ".v" files, and add more tests
2026-02-16 02:11:02 +00:00
TheFox0x7 08d9845635 use proper subaddress (#36639) 2026-02-16 01:42:22 +00:00
GiteaBot 4ca4217b3d [skip ci] Updated translations via Crowdin 2026-02-16 00:50:05 +00:00
silverwind 2896dac536 Fix state desync in ComboMarkdownEditor (#36625)
Fixes https://github.com/go-gitea/gitea/issues/24253

When a tasklist checkbox is clicked, the tasklist code [updates
`.raw-content` with latest server
data](https://github.com/go-gitea/gitea/blob/7a8fe9eb370c6f3f5ec6eae2e1ebba5ac77b1f25/web_src/js/markup/tasklist.ts#L73)
in the DOM after POSTing.

Then when "Edit" is clicked the ComboMarkdownEditor is shown with a
stale value from the previous edit session.

The fix makes it always read from `.raw-content`, no server
syncronization necessary because the value in `.raw-content` is the
latest from the server.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-16 00:49:03 +00:00
silverwind 88752bc159 Exclude cancelled runs from failure-only email notifications (#36569)
The default configuration of `failure-only` added in
https://github.com/go-gitea/gitea/pull/34982 included sending mails for
cancelled runs which is not what one would expect from a option named
like that because a cancelled run is not a failure.

This change makes it omit mails for cancelled runs:

| Run Status | `failure-only` before | `failure-only` after |
|------------|-----------------------|----------------------|
| Success    | no                    | no                   |
| Failure    | mail                  | mail                 |
| Cancelled  | mail                  | no                   |

The first commit in this PR is the fix, and there are a few more
refactor commits afterwards.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 23:47:02 +00:00
Beda Schmid 692ef9eca6 Update the Unlicense copy to latest version (#36636)
It appears that an older version of the Unlicensed was used (at the
least, `http` url was referenced therein over `https` which is used in
the original)

Original formatting also has been preserved.

Signed-off-by: Beda Schmid <beda@tukutoi.com>
2026-02-15 22:17:05 +00:00
silverwind 838bb1d379 Fix minor UI issues in runner edit page (#36590)
Before:

<img width="991" height="132" alt="Screenshot 2026-02-11 at 16 39 46"
src="https://github.com/user-attachments/assets/c104aeb8-83be-46d2-bfea-34a8df527d05"
/>
<img width="132" height="122" alt="Screenshot 2026-02-11 at 16 42 57"
src="https://github.com/user-attachments/assets/bc56ea3d-9e5a-47d4-9d90-ca09949641ba"
/>


After:

<img width="986" height="140" alt="Screenshot 2026-02-11 at 16 39 32"
src="https://github.com/user-attachments/assets/99560be8-f01c-4d8a-8763-b8017d3a3742"
/>
<img width="137" height="128" alt="Screenshot 2026-02-11 at 16 42 49"
src="https://github.com/user-attachments/assets/2a6dcdc4-16bb-45fb-a831-c4edc35c3654"
/>

---------

Signed-off-by: silverwind <me@silverwind.io>
2026-02-15 20:33:04 +00:00
silverwind 26bb175d69 Persist actions log time display settings in localStorage (#36623)
Persist the two boolean settings in the actions log into `localStorage`
so that they are remembered across page reloads.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 19:41:59 +00:00
GiteaBot a6282c98d7 [skip ci] Updated translations via Crowdin 2026-02-15 00:52:30 +00:00
techknowlogick 2cdf86e184 automate updating nix flakes (#35641) 2026-02-14 19:00:36 +01:00
silverwind 1d4b8486f0 Update AGENTS.md instructions (#36627) 2026-02-14 18:11:13 +01:00
TheFox0x7 4805151f56 use user id in noreply emails (#36550)
This implements id based hidden emails in format of
`user+id@NoReplyAddress`

resolves: https://github.com/go-gitea/gitea/issues/33471

---

The change is not breaking however it is recommended for users to move
to this newer type of no reply address

---------

Co-authored-by: Lauris B <lauris@nix.lv>
2026-02-14 17:51:03 +01:00
Tyrone Yeh 7a8fe9eb37 feat(db): Improve BuildCaseInsensitiveLike with lowercase (#36598)
Improve BuildCaseInsensitiveLike with lowercase, users are more likely
to input lowercase letters, so lowercase letters are used.

---------

Signed-off-by: Tyrone Yeh <siryeh@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-14 07:40:59 +00:00
GiteaBot ce61d6d99d [skip ci] Updated translations via Crowdin 2026-02-14 00:47:43 +00:00
Nicolas afcd11c77f BUG: Fix workflow run jobs API returning null steps (#36603)
## Problem

`GET /api/v1/repos/{owner}/{repo}/actions/runs/{runId}/jobs` was always
returning `steps: null` for each job.

## Cause

In `convert.ToActionWorkflowJob`, when the job had a `TaskID` we loaded
the task with `db.GetByID` but never loaded `task.Steps`.
`ActionTask.Steps` is not stored in the task row (`xorm:"-"`); it comes
from `action_task_step` and is only filled by `task.LoadAttributes()` /
`GetTaskStepsByTaskID()`. So the conversion loop over `task.Steps`
always saw nil and produced no steps in the API response.

## Solution

After resolving the task (by ID when the caller passes `nil`), we now
load its steps with `GetTaskStepsByTaskID(ctx, task.ID)` and set
`task.Steps` before building the API steps slice. No other behavior is
changed.

## Testing

- New integration test `TestAPIListWorkflowRunJobsReturnsSteps`: calls
the runs/{runId}/jobs endpoint, inserts a task step for a fixture job,
and asserts that the response includes non-null, non-empty `steps` with
the expected step data.
- `make test-sqlite#TestAPIListWorkflowRunJobsReturnsSteps` passes with
this fix.

---------

Co-authored-by: Manav <mdave0905@gmail.com>
2026-02-13 08:16:43 +00:00
wxiaoguang 0d8bd7720d Refactor highlight and diff (#36599)
1. fix a performance regression when using line-by-line highlighting
* the root cause is that chroma's `lexers.Get` is slow and a lexer cache
is missing during recent changes
2. clarify the chroma lexer detection behavior
* now we fully manage our logic to detect lexer, and handle overriding
problems, everything is fully under control
3. clarify "code analyze" behavior, now only 2 usages:
* only use file name and language to detect lexer (very fast), mainly
for "diff" page which contains a lot of files
* if no lexer is detected by file name and language, use code content to
detect again (slow), mainly for "view file" or "blame" page, which can
get best result
4. fix git diff bug, it caused "broken pipe" error for large diff files
2026-02-13 00:15:46 +00:00
Lunny Xiao d69b786097 Fix bug when do LFS GC (#36500)
Fix #36448

Removed unnecessary parameters from the LFS GC process and switched to
an ORDER BY id ASC strategy with a last-ID cursor to avoid missing or
duplicating meta object IDs.

---------

Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-12 15:27:19 -08:00
josetduarte f76f5207a7 feature to be able to filter project boards by milestones (#36321)
This pull request adds milestone filtering support to both repository
and organization project boards. Users can now filter project issues by
milestone, similar to how they filter by label or assignee. The
implementation includes backend changes to fetch and filter milestones,
as well as frontend updates to display a milestone filter dropdown in
the project board UI.

**Milestone filtering support:**

* Added support for filtering project board issues by milestone in both
repository and organization contexts, including handling for "no
milestone" and "all milestones" options. (`routers/web/repo/projects.go`
[[1]](diffhunk://#diff-5cba331a1ddf1eea017178cfefaaff9ad72a4b05797fb84bf508b0939aae2972R316-R330)
[[2]](diffhunk://#diff-5cba331a1ddf1eea017178cfefaaff9ad72a4b05797fb84bf508b0939aae2972R421-R441);
`routers/web/org/projects.go`
[[3]](diffhunk://#diff-f4279417070a8e33829c338abeb42877500377f490abb1495ae6357d50b6a765R344-R357)
[[4]](diffhunk://#diff-f4279417070a8e33829c338abeb42877500377f490abb1495ae6357d50b6a765R433-R485)
* Updated the project board template to include a milestone filter
dropdown, displaying open and closed milestones and integrating with the
query string for filtering. (`templates/projects/view.tmpl`
[[1]](diffhunk://#diff-e2c7e14d247ce381c352263a8fa639b8341690ff85f6dbebfa166ee3306542feL8-R8)
[[2]](diffhunk://#diff-e2c7e14d247ce381c352263a8fa639b8341690ff85f6dbebfa166ee3306542feR19-R58)

Solves Issue #35224

---------

Signed-off-by: josetduarte <6619440+josetduarte@users.noreply.github.com>
Co-authored-by: joseduarte <joseduarte@aidhound.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-12 22:09:32 +00:00
silverwind 4b36f01bf4 Update emoji data for Unicode 16 (#36596)
Use emoji data from https://github.com/github/gemoji/pull/303 because
`github/gemoji` is unmaintained.

`assets/emoji.json` is now pretty-printed so that future diffs will
actually be readable. This causes no isses as the only place where it is
used is in frontend which imports it via `with {type: 'json'}` where
whitespace is irrelevant.

<img width="205" height="75" alt="image"
src="https://github.com/user-attachments/assets/96e335b8-acf6-4996-ace4-824c0870a7d3"
/>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 21:39:36 +00:00
silverwind d582c9c8c0 Adapt monaco error matching pattern to recent webpack config change (#36533)
Signed-off-by: silverwind <me@silverwind.io>
2026-02-12 20:59:13 +00:00
Lunny Xiao 8d26ea9373 Fix a bug user could change another user's primary email (#36586) 2026-02-12 21:34:38 +01:00
Tyrone Yeh 514f322dcf fix(repo-editor): disable Monaco editContext to avoid bugs with lost focus (#36585)
Currently, pressing the space key in the Monaco editor scrolls the page
instead of inserting a space
if the editor is focused. This PR stops the space key event from
propagating to parent elements,
which prevents unwanted page scrolling while still allowing Monaco to
handle space input normally.

Changes:
 - disable Monaco editContext

No changes to default editor behavior are needed; Monaco automatically
inserts the space character.

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: silverwind <me@silverwind.io>
2026-02-12 18:39:24 +00:00
wxiaoguang 2876800cb2 Fine tune diff highlighting (#36592) 2026-02-12 07:01:36 +00:00
silverwind 47b387921a Add code editor setting dropdowns (#36534)
Adds three `<select>` controls on top right for indent style, indent
size, and line wrap to the code editor (`_edit`), diff patch editor
(`_diffpatch`) and git hook editor (`/settings/hooks/git/pre-receive`).

The git hooks editor is restyled to wrap the content in a box. Also
included is a bugfix for the git hooks editor where monaco was not
initialized correctly.

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-12 03:55:46 +08:00
silverwind 45ee571693 Update to go 1.26.0 and golangci-lint 2.9.0 (#36588) 2026-02-11 18:37:13 +01:00
wxiaoguang 3754e9dd12 Improve diff highlighting (#36583) 2026-02-11 03:52:17 +00:00
wxiaoguang fd89ceef79 Fix markup code block layout (#36578) 2026-02-11 03:22:33 +00:00
silverwind 018a88590c Remove striped tables in UI (#36509)
We've been cutting down on the "striped" tables (where rows are using
alternate row background colors). This completely removes them as I
think such a design looks outdated.

The removal of selectors starting with `.ui[class*="very
basic"].table:not(.striped)` is needed because of a specificity issue in
the CSS where table cells would otherwise render with incorrect padding.

Example of one affected table:

<img width="1027" height="224" alt="image"
src="https://github.com/user-attachments/assets/2f3006ca-99a1-4655-afdb-b7cd9e5f19c7"
/>
2026-02-11 01:58:56 +00:00
silverwind c17280149f Fix vertical alignment of .commit-sign-badge children (#36570)
Before: Avatar and lock icon was slightly misaligned vertically and span
was `20px` high:

<img width="271" height="69" alt="Screenshot 2026-02-09 at 14 38 45"
src="https://github.com/user-attachments/assets/e7e7ff6b-3087-4baa-95b5-18dc54c595d7"
/>

After: Fixed alignment and span is `16px`, same as avatar:

<img width="270" height="65" alt="Screenshot 2026-02-09 at 14 39 30"
src="https://github.com/user-attachments/assets/fe31a23e-c6d8-49d3-92a3-237628da1269"
/>
2026-02-11 01:01:26 +00:00
Lunny Xiao 18ccee0f2f Fix mirror sync parser and fix mirror messages (#36504)
Fix #36474 

It also fixed a bug when sync deleted branches.
2026-02-11 00:16:05 +00:00
silverwind 2d70d37bff Update JS and PY deps (#36576)
eslint v10 is excluded from updates because the plugins are not compatible yet.
2026-02-10 15:39:17 +00:00
wxiaoguang 5e5703694d Add viewer controller for mermaid (zoom, drag) (#36557)
Fix #25803

Now the rendered mermaid chart can be dragged or zoomed.

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 06:36:31 +00:00
silverwind 09a88fb17e Misc typescript tweaks (#36523)
Some minor refactors, disable one obsolete lint rule, fix another. The
tribute type issue is not fully fixed and I'm pretty sure it must be an
error in their types.
2026-02-10 05:09:56 +00:00
wxiaoguang 8cc8150922 Use full-file highlighting for diff sections (#36561)
* Fix #35252
* Fix #35999
* Improve diff rendering, don't add unnecessary "added"/"removed" tags for a full-line change
* Also fix a "space trimming" bug in #36539 and add tests
* Use chroma "SQL" lexer instead of "MySQL" to workaround a bug (35999)
2026-02-10 03:29:28 +00:00
Tyrone Yeh 269bc1b112 fix(diff): reprocess htmx content after loading more files (#36568)
The "Show more files" button replaces `#diff-incomplete` with newly
loaded diff file boxes.
The inserted HTML may contain htmx attributes, but they are not
processed after insertion.

### Solution
Wrap the incomplete diff placeholder with a temporary wrapper so we can
call `htmx.process()` on the newly inserted content.
After processing, unwrap the wrapper to keep the DOM structure
unchanged.

### Testing
- Open a large PR diff page where `Diff.IsIncomplete` is true
- Click "Show more files"
- Verify newly loaded file boxes behave correctly (htmx-related features
work as expected)

<img width="927" height="278" alt="image"
src="https://github.com/user-attachments/assets/54f2b4f2-c0e1-483c-9e26-79a2838e98ee"
/>

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-10 01:20:20 +00:00
GiteaBot f73e45b4ba [skip ci] Updated translations via Crowdin 2026-02-10 00:55:46 +00:00
silverwind cf7e49ecdd Add wrap to runner label list (#36565) 2026-02-09 22:39:06 +00:00
yshyuk 94437eadd9 fix: add dnf5 command for Fedora in RPM package instructions (#36527)
Add support for Fedora 41+ which uses dnf5 with different command syntax
for adding repositories.

- **dnf4 (RHEL/Rocky):** `dnf config-manager --add-repo <URL>`
- **dnf5 (Fedora 41+):** `dnf config-manager addrepo
--from-repofile=<URL>`

Closes #35330
2026-02-09 16:14:02 +00:00
Sebastian Ertz 36ced5dc8c Enable pagination on GiteaDownloader.getIssueReactions() (#36549)
And update code.gitea.io/sdk/gitea to v0.23.2

---------

Co-authored-by: Giteabot <teabot@gitea.io>
2026-02-09 15:49:05 +01:00
ChristopherHX 34b34d2328 Refactor merge conan and container auth preserve actions taskID (#36560)
* Remove duplicated code
* Allow further ActionsUser package permission checks

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-09 03:04:56 +00:00
Tyrone Yeh c401cda108 Fix assignee sidebar links and empty placeholder after #32465 refactor (#36559)
Follow-up to #32465: Fix the assignee sidebar after the selector
refactor.


Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-08 21:00:18 +00:00
wxiaoguang 08b7a30867 Fix various version parsing problems (#36553)
1. handle non-release git verions (not semver)
2. fix rubygems version "0" handling (only ">=" can be omitted)
3. lazy compile the regexp to improve performance
4. make test data maintainable, use origin source code instead of compressed binary
2026-02-08 20:25:30 +00:00
wxiaoguang 2ff4f4a909 Fix highlight diff result (#36539)
Fix #36536

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-08 16:48:52 +00:00
ChristopherHX f65df2a69b Refactor Nuget Auth to reuse Basic Auth Token Validation (#36558)
* Implicitly handle Actions Task Token for Nuget Api Keys
* Support same tokens as Basic Auth in Nuget Api Key Header

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-08 14:43:05 +00:00
Sebastian Ertz daf0483ef2 Update go dependencies (#36548) 2026-02-08 12:01:37 +00:00
Hypo ef529de0ac Prevent navigation keys from triggering actions during IME composition (#36540)
Fixes  #36532 

Refined the Enter key trigger logic in the repository filter to prevent
actions during IME composition.

By checking the e.isComposing property, the filter now correctly
distinguishes between "confirming an IME candidate" and "submitting the
search." This prevents premature search triggers when users press Enter
to select Chinese/Japanese characters.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-08 14:39:09 +08:00
wxiaoguang a60201a071 Fix various mermaid bugs (#36547)
* Fix #36515
* Fix #23076
* Remove unnecessary `mermaid.parse`
* Fix data race when using `data-render-done`
* Remove unnecessary `Promise.all`
* Fix duplicate `load` event and duplicate SVG node rendering
* Remove unnecessary `IntersectionObserver`
* Add `bindFunctions` call, the old comment seems not true
2026-02-08 12:21:11 +08:00
silverwind 49e6d5f6d6 Add elk layout support to mermaid (#36486)
Fixes: https://github.com/go-gitea/gitea/issues/34769

This allows the user to opt-in to using `elk` layouts using either YAML
frontmatter or `%%{ init` directives inside the markup code block. The
default layout is not changed.

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-07 02:22:57 +00:00
Louis e2104a1dd5 Allow configuring default PR base branch (fixes #36412) (#36425)
This adds a per-repository default PR base branch and wires it through
PR entry points. It updates compare links and recently pushed branch
prompts to respect the configured base branch, and prevents auto-merge
cleanup from deleting the configured base branch on same-repo PRs.

## Behavior changes
- New PR compare links on repo home/issue list and branch list honor the
configured default PR base branch.
- The "recently pushed new branches" prompt now compares against the
configured base branch.
- Auto-merge branch cleanup skips deleting the configured base branch
(same-repo PRs only).

---------

Signed-off-by: Louis <116039387+tototomate123@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-02-07 01:34:29 +00:00
GiteaBot 0dacd956fb [skip ci] Updated translations via Crowdin 2026-02-07 00:45:30 +00:00
silverwind 915b44810d Color command/error logs in Actions log (#36538)
Support `[command]` and `##[error]` log command

------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-06 23:05:32 +08:00
TheFox0x7 403a73dca0 Add paging headers (#36521)
Adds support for paging in admin/hooks api endpoint

fixes: https://github.com/go-gitea/gitea/issues/36516

---------

Co-authored-by: techknowlogick <techknowlogick@gitea.com>
Co-authored-by: techknowlogick <matti@mdranta.net>
2026-02-06 13:12:05 +00:00
Tyrone Yeh ef9c19691d Fix issues filter dropdown showing empty label scope section (#36535)
The issues filter dropdown always rendered the label scope divider and
header, even when .ExclusiveLabelScopes was empty.

This PR wraps the label scope section with a conditional so the
divider/header and scope entries are only displayed when scopes exist.

Before

The dropdown showed a divider and “Label” header even when there were no
exclusive label scopes available.
<img width="521" height="569" alt="image"
src="https://github.com/user-attachments/assets/9766df6b-c11b-46f3-aabc-9fa5f4ca767d"
/>

After

The label scope section is hidden entirely when .ExclusiveLabelScopes is
empty, keeping the dropdown clean and consistent.
<img width="329" height="485" alt="image"
src="https://github.com/user-attachments/assets/e9586e57-2be5-43ea-8a13-9b87c951be6f"
/>

Notes

UI-only change, no behavior change to filtering logic.
2026-02-06 08:33:42 +00:00
Pascal Zimmermann 50fdd2d49a [SECURITY] fix: Adjust the toolchain version (#36537)
# Summary:

- Adjust the toolchain version to fix the security issues


```log
Vulnerability #1: GO-2026-4337
    Unexpected session resumption in crypto/tls
  More info: https://pkg.go.dev/vuln/GO-2026-4337
  Standard library
    Found in: crypto/tls@go1.25.6
    Fixed in: crypto/tls@go1.25.7
    Example traces found:
```

Signed-off-by: Pascal Zimmermann <pascal.zimmermann@theiotstudio.com>
2026-02-06 00:27:53 +01:00
Copilot fca94bcdd7 Hide add-matcher and remove-matcher from actions job logs (#36520)
Hides `::add-matcher::`, `##[add-matcher]` and `::remove-matcher` in job
step logs. These are used to configure regex matchers to detect lines
that should trigger annotation comments on the UI, currently unsupported
by Gitea and these have no relevance to the user.

---------

Signed-off-by: silverwind <me@silverwind.io>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-05 19:11:44 +08:00
Copilot 000d7c1ccb Improve timeline entries for WIP prefix changes in pull requests (#36518)
Add new timeline event types when the WIP prefix is added or removed,
replacing the previous ugly title change messages.

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

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-05 05:57:08 +00:00
Noel Jackson 65d93d819b fix(packages/container): data race when uploading container blobs concurrently (#36524)
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-04 00:08:20 +08:00
GiteaBot 288d1f526a [skip ci] Updated translations via Crowdin 2026-02-02 00:49:41 +00:00
Copilot 7883f6dde9 Remove and forbid @ts-expect-error (#36513)
Removes `@ts-expect-error` in the code base and forbids it.

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: silverwind <115237+silverwind@users.noreply.github.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-02 01:00:34 +08:00
Nicolas c2dea22926 Add resolve/unresolve review comment API endpoints (#36441)
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-01 12:28:28 +00:00
Copilot 584d8ef75f Fix incorrect vendored detections (#36508)
Fixes: https://github.com/go-gitea/gitea/issues/22618

`go-enry`'s `IsVendor` function marks git paths (`.gitignore`,
`.gitattributes`, `.gitmodules`), github/gitea paths (`.github/`,
`.gitea/`) as "vendored" for GitHub Linguist language statistics. This
causes these files to incorrectly display the "Vendored" tag in diff
views.

Override `go-enry`'s detection for these specific cases while preserving
its behavior for actual vendor directories.

---------

Signed-off-by: silverwind <me@silverwind.io>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: silverwind <115237+silverwind@users.noreply.github.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-02-01 10:35:51 +00:00
silverwind 9d96039027 Bump alpine to 3.23, add platforms to docker-dryrun (#36379)
- Bump alpine to 3.23 following
https://github.com/go-gitea/gitea/pull/36185 and
https://github.com/go-gitea/gitea/pull/36202.
- Enable all architectures in `docker-dryrun`.
- Tweak actions conditions to be more precise.

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: techknowlogick <techknowlogick@gitea.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-02-01 09:36:43 +00:00
Copilot 072de7d8cd Unify repo names in system notices (#36491)
Fixes: https://github.com/go-gitea/gitea/issues/36211

This PR fixes ensures that all system notices consistently include
repository names in the format `"Action description (owner/repo): error
message"`.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: silverwind <115237+silverwind@users.noreply.github.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-02-01 17:06:57 +08:00
Lunny Xiao e377da989f Allow scroll propagation outside code editor (#36502)
Fix #28479

When scrolling inside the editor and the editor has already reached the
end of its scroll area, the browser does not continue scrolling. This is
inconvenient because users must move the cursor out of the editor to
scroll the page further.

This PR enables automatic switching between the editor’s scroll and the
browser’s scroll, allowing seamless continuous scrolling.
2026-02-01 06:03:38 +00:00
wxiaoguang 7ad9bf4523 Refactor ActionsTaskID (#36503) 2026-01-31 22:01:08 -08:00
silverwind 7292ae1ed5 Update JS deps, remove knip, misc tweaks (#36499)
- Update all JS deps
- Enable a few more stylelint stylistic rules and fix issues
- Remove knip, it raised another false-positive, this tool is not worth
it when you have to babysit it like that
- Exclude @eslint/json from updating as it requires unreleased eslint 10
([ref](https://github.com/eslint/json/issues/207))
- Update labeler config for new eslint filenames
- Adjust `make help` output
- Add type checking in `stylelint.config.ts`
2026-01-31 20:58:23 +08:00
GiteaBot 8c9247e717 [skip ci] Updated translations via Crowdin 2026-01-31 00:45:54 +00:00
Copilot 0acaad1919 Fix editorconfig not respected in PR Conversation view (#36492)
Fixes: https://github.com/go-gitea/gitea/issues/24991
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: silverwind <115237+silverwind@users.noreply.github.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-01-30 21:41:43 +00:00
Copilot 8feabe4160 Add FOLDER_ICON_THEME configuration option (#36496)
Fixes: https://github.com/go-gitea/gitea/issues/35182
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: silverwind <115237+silverwind@users.noreply.github.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-01-30 20:48:56 +00:00
silverwind a16ca3c57c Don't create self-references in merged PRs (#36490)
Fixes: https://github.com/go-gitea/gitea/issues/36488
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-01-30 20:12:24 +00:00
silverwind 2d1306291b Use reserved .test TLD for unit tests (#36498)
`smtp.mydomain.test` is a real domain that resolves to something and
which is being connected to while running tests. Instead, use
[.test](https://en.wikipedia.org/wiki/.test) which is guaranteed to
never be registered on the internet, so all connections to it will fail
with NXDOMAIN dns error.
2026-01-30 19:42:32 +00:00
Lunny Xiao 208cbd5a6f Fix bug when list pull request commits (#36485)
Fix #36483 

In git log/rev-list, the "..." syntax represents the symmetric
difference between two references, which is different from the meaning
of "..." in git diff (where it implies diffing from the merge base).

For listing PR commits, we must use `merge-base..head` to include only
the commits introduced by the head branch. Otherwise, commits newly
pushed to the base branch would also be included, which is incorrect.
2026-01-30 18:46:34 +00:00
silverwind de829c7821 Update some go dependencies (#36489)
I verified the `.env.local` syntax added in
https://github.com/alecthomas/chroma/pull/1197 works as expected.
2026-01-30 11:25:30 +01:00
wxiaoguang 07ada3666b chore: add comments for "api/healthz", clean up test env (#36481)
GITEA_UNIT_TESTS_LOG_SQL is renamed to GITEA_TEST_LOG_SQL
2026-01-30 10:23:38 +08:00
Pascal Zimmermann 1adf8b3773 [SECURITY] Toolchain Update to Go 1.25.6 (#36480)
## Overview
This PR updates the Go toolchain version from `1.25.5` to `1.25.6` for
the Gitea project.

## Changes

### Toolchain Update
- **Go Toolchain**: Updated from `go1.25.5` to `go1.25.6`

This is a minor toolchain version bump that ensures the project uses the
latest patch release of Go 1.25.

## Security Improvements

While this PR primarily addresses the toolchain update, the project
maintains a strong security posture through:

### Current Security Measures
```log
Vulnerability #1: GO-2026-4342                                                                                                                                                                                                      
    Excessive CPU consumption when building archive index in archive/zip
  More info: https://pkg.go.dev/vuln/GO-2026-4342
  Standard library
    Found in: archive/zip@go1.25.5
    Fixed in: archive/zip@go1.25.6
    Example traces found:
      #1: modules/packages/nuget/metadata.go:217:25: nuget.ParseNuspecMetaData calls zip.Reader.Open                                                                                                                                

Vulnerability #2: GO-2026-4341
    Memory exhaustion in query parameter parsing in net/url
  More info: https://pkg.go.dev/vuln/GO-2026-4341
  Standard library
    Found in: net/url@go1.25.5
    Fixed in: net/url@go1.25.6
    Example traces found:
      #1: modules/storage/minio.go:284:34: storage.MinioStorage.URL calls url.ParseQuery                                                                                                                                            
      #2: routers/api/v1/repo/action.go:1640:29: repo.DownloadArtifactRaw calls url.URL.Query

Vulnerability #3: GO-2026-4340
    Handshake messages may be processed at the incorrect encryption level in
    crypto/tls
  More info: https://pkg.go.dev/vuln/GO-2026-4340
  Standard library
    Found in: crypto/tls@go1.25.5
    Fixed in: crypto/tls@go1.25.6
    Example traces found:
      #1: services/auth/source/ldap/source_search.go:129:25: ldap.dial calls ldap.Conn.StartTLS, which calls tls.Conn.Handshake                                                                                                     
      #2: modules/graceful/server.go:156:14: graceful.Server.Serve calls http.Server.Serve, which eventually calls tls.Conn.HandshakeContext
      #3: modules/lfs/content_store.go:132:27: lfs.hashingReader.Read calls tls.Conn.Read
      #4: modules/proxyprotocol/conn.go:91:21: proxyprotocol.Conn.Write calls tls.Conn.Write
      #5: modules/session/virtual.go:168:39: session.VirtualStore.Release calls couchbase.CouchbaseProvider.Exist, which eventually calls tls.Dial
      #6: services/auth/source/ldap/source_search.go:120:22: ldap.dial calls ldap.DialTLS, which calls tls.DialWithDialer
      #7: services/migrations/gogs.go:114:34: migrations.client calls http.Transport.RoundTrip, which eventually calls tls.Dialer.DialContext
```

## Breaking Changes
None expected. This is a minor toolchain patch update.
2026-01-29 07:23:11 +01:00
GiteaBot 67b457dd00 [skip ci] Updated translations via Crowdin 2026-01-29 00:46:17 +00:00
silverwind d7dff61cbc Render merged pull request title as such in dashboard feed (#36479)
Before:

<img width="513" height="55" alt="Screenshot 2026-01-28 at 17 24 50"
src="https://github.com/user-attachments/assets/ef28d87a-9a52-4762-9ddc-c3934f5cfc7a"
/>

After:

<img width="509" height="64" alt="Screenshot 2026-01-28 at 17 24 39"
src="https://github.com/user-attachments/assets/bc55c828-7813-47be-bef8-23eeb51bd513"
/>
2026-01-29 01:40:07 +01:00
Sebastian Ertz b500b7cfed Correct spacing between username and bot label (#36473) 2026-01-28 16:22:37 +01:00
Lunny Xiao bf8d11bb21 Fix oauth2 s256 (#36462) 2026-01-28 06:42:07 +01:00
silverwind 224b7881d9 Forbid localStorage access in eslint (#36461)
Followup to
https://github.com/go-gitea/gitea/commit/59f812bc1cc52f15d66d1b233f11e43339c09cec,
enforce using our localStorage wrapper in eslint.

Also did a few tweaks in the eslint config, like removing the incomplete
list of globals, this is a non-issue with typescript.

---------

Signed-off-by: silverwind <me@silverwind.io>
2026-01-27 19:59:51 +00:00
Lunny Xiao 1463426a27 Use merge tree to detect conflicts when possible (#36400)
In Git 2.38, the `merge-tree` command introduced the `--write-tree`
option, which works directly on bare repositories. In Git 2.40, a new parameter `--merge-base` introduced so we require Git 2.40 to use the merge tree feature.

This option produces the merged tree object ID, allowing us to perform
diffs between commits without creating a temporary repository. By
avoiding the overhead of setting up and tearing down temporary repos,
this approach delivers a notable performance improvement.

It also fixes a possible situation that conflict files might be empty
but it's a conflict status according to
https://git-scm.com/docs/git-merge-tree#_mistakes_to_avoid

Replace #35542

---------

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-01-27 11:57:20 -08:00
GiteaBot 125257eacf [skip ci] Updated translations via Crowdin 2026-01-27 00:42:45 +00:00
silverwind 59f812bc1c Fix and enhance comment editor monospace toggle (#36181)
Fixes: https://github.com/go-gitea/gitea/issues/36175

1. Correctly apply setting on textareas spawned by comment edit
3. When changing the setting, apply it to all textareas on the current page

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-26 14:19:47 +00:00
wxiaoguang 4c8f6dfa4e Support rendering OpenAPI spec (#36449)
Fix #20852
2026-01-26 10:34:38 +08:00
Moritz Jörg 89bfddc5c2 Normalize guessed languages for code highlighting (#36450)
For when Enry correctly recognized the language, but returns the
language name in a way that isn't recognized by chroma.

Resolves https://github.com/go-gitea/gitea/issues/22443

---------

Co-authored-by: Moritz Jörg <moritz.jorg@oceanbox.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-25 14:02:16 +00:00
silverwind 12a81d38c1 Add knip linter (#36442)
This adds [knip](https://github.com/webpro-nl/knip), a tool to find
unused files, dependencies and exports in JS. Fixed all discovered
issues.

1. knip apparently has some issue resolving imports from `d.ts` to `.ts`
so I worked around it by moving the two affected types to where they are
used.
2. I don't know why `modules/fomantic/dropdown.ts` had a new typescript
error, but I fixed it.
3. Use named export for `EsbuildPlugin`, I think this was added
recently.
2026-01-24 12:52:13 +00:00
wxiaoguang ddc9d29713 Fix various bugs (#36446)
* Fix #36409
* Fix #36322
* Fix #30101
* Fix #36317

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-24 11:30:47 +00:00
silverwind a608b9e1e3 Update tool dependencies (#36445)
Updates all dependencies in `Makefile`. The go fix was done
automatically, I just altered the variable name.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-24 09:58:28 +01:00
silverwind 5925433fe6 Update JS dependencies, adjust webpack config, misc fixes (#36431)
1. Upgrade to [jQuery
4.0](https://blog.jquery.com/2026/01/17/jquery-4-0-0/). Two of the
removed APIs are in use by fomantic, but there are [polyfills
present](https://github.com/go-gitea/gitea/blob/a3a3e581aa387969ce6410ab54c4775e9023ec40/web_src/fomantic/build/components/dropdown.js#L15-L17)
so it continues to work.
2. Remove manual naming of webpack chunks. I was running into below
webpack error and I see no reason for this manual chunk naming which is
prone to naming collisions. Also, the webpack build now shows all output
assets. This change will result in longer asset filenames, but webpack
should now be able to guarentee that the names are without collisions.
    ````
    ERROR in SplitChunksPlugin
    Cache group "defaultVendors" conflicts with existing chunk.
Both have the same name "--------" and existing chunk is not a parent of
the selected modules.
Use a different name for the cache group or make sure that the existing
chunk is a parent (e. g. via dependOn).
    HINT: You can omit "name" to automatically create a name.
BREAKING CHANGE: webpack < 5 used to allow to use an entrypoint as
splitChunk. This is no longer allowed when the entrypoint is not a
parent of the selected modules.
Remove this entrypoint and add modules to cache group's 'test' instead.
If you need modules to be evaluated on startup, add them to the existing
entrypoints (make them arrays). See migration guide of more info.
3. Fix test issue related to `p > div` which is invalid as per HTML spec
because `div` is not [phrasing
content](https://html.spec.whatwg.org/multipage/dom.html#phrasing-content-2)
and therefor can not be a descendant of `p`. This is related to
https://github.com/capricorn86/happy-dom/pull/2007.
4. Add webpack globals
5. Remove obsolete docs glob
6. fix security issue for `seroval` package
7. disable [vitest isolate](https://vitest.dev/config/isolate.html) for
30% faster JS tests, which are all pure.
2026-01-24 07:35:46 +00:00
lif 4ed43c2a32 fix: Improve image captcha contrast for dark mode (#36265)
## Summary
This PR fixes #36255

The image captcha was using random colors which often resulted in poor
contrast against dark backgrounds, making it difficult or impossible for
users to read in dark mode.

## Changes
- Added a custom color palette to the image captcha configuration in
`services/context/captcha.go`
- The palette uses high-contrast colors (bright red, blue, green,
yellow, purple, and dark blue-gray) that provide good visibility in both
light and dark themes
- This improves accessibility and user experience without changing any
existing functionality

## Testing
- Builds successfully
- All existing tests pass
- The color palette is properly supported by the upstream
`gitea.com/go-chi/captcha` library

---
Generated with Claude Code

---------

Signed-off-by: majiayu000 <1835304752@qq.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-01-24 05:41:51 +00:00
wxiaoguang 9de659437e Refactor template render (#36438) 2026-01-24 05:11:49 +00:00
silverwind 47717d4435 Add documentation for markdown anchor post-processing (#36443)
See discussion in https://github.com/go-gitea/gitea/pull/36284.

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-24 05:31:57 +01:00
Heath Dutton🕴️ 0f78b99998 Fix markup heading parsing, fix emphasis parsing (#36284)
Fixes #36106, fix #17958

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-23 20:24:58 +00:00
Lunny Xiao cfd7218395 Front port changelog for 1.25.4 (#36432)
Co-authored-by: techknowlogick <techknowlogick@gitea.com>
2026-01-23 15:31:01 +00:00
Zettat123 52c3a7d3ce Bugfix: Potential incorrect runID in run status update (#36437)
`jobs[0]` may not belong to the run for `runID`.

Co-authored-by: Giteabot <teabot@gitea.io>
2026-01-23 11:11:56 +00:00
Kemal Zebari 56c5d5e819 Restrict branch naming when new change matches with protection rules (#36405)
Resolves #36381 by only allowing admins to perform branch renames that
match to branch protection rules.

---------

Co-authored-by: Giteabot <teabot@gitea.io>
2026-01-23 11:42:24 +01:00
wxiaoguang e42a1dbb6b Refactor GetRepoRawDiffForFile to avoid unnecessary pipe or goroutine (#36434) 2026-01-23 02:10:11 +00:00
silverwind 5f91c51fa5 Remove node-check and go-check, support node prerelease versions (#36382)
1. Remove those checks for the sake of build performance and because go
and node will fail anyways if their versions are incorrect.
3. Support pre-release Node version for determining NODE_VARS.
2. Update to the chinese READMEs to mention `pnpm` which is already
present in english README.

---------

Co-authored-by: techknowlogick <techknowlogick@gitea.com>
Co-authored-by: Giteabot <teabot@gitea.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-22 09:30:02 +01:00
wxiaoguang 3a09d7aa8d Refactor git command stdio pipe (#36422)
Most potential deadlock problems should have been fixed, and new code is
unlikely to cause new problems with the new design.

Also raise the minimum Git version required to 2.6.0 (released in 2015)
2026-01-22 06:04:26 +00:00
Thomas Beutlich 2a56c4ec3b Fix spelling (#36399)
Signed-off-by: Thomas Beutlich <115483027+thbeu@users.noreply.github.com>
2026-01-22 02:52:39 +00:00
wxiaoguang 85c7901404 Fix issue filter menu layout (#36426)
Fix #36420
2026-01-22 02:22:20 +00:00
luo jiyin 6a5f9e12f9 Fix typos: unknow -> unknown, pktLineTypeUnknow -> pktLineTypeUnknown (#36419) 2026-01-22 01:17:06 +00:00
GiteaBot a3a3e581aa [skip ci] Updated translations via Crowdin 2026-01-22 00:41:46 +00:00
Tyrone Yeh 58cd8244ba Fix markdown newline handling during IME composition (#36421)
### Summary

Fix incorrect newline handling in markdown editor when using IME input.

### Details

While composing text with an IME, pressing Enter should not trigger
markdown indentation logic.
This change skips indentation handling during composition by checking
`e.isComposing`.

This prevents unexpected line breaks and formatting issues for CJK
users.
2026-01-22 00:24:37 +00:00
Sebastian Ertz 111c822a30 Update chroma to v2.23.0 (#36423) 2026-01-21 23:55:24 +00:00
Bart van der Braak 2f377e8552 Update material-icon-theme to v5.31.0 (#36427) 2026-01-22 00:25:14 +01:00
Lunny Xiao d46021a83a Allow foreachref parse max tokens from 4*64KB to 4MB (#36414)
Fix #36408

---------

Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-21 04:18:57 +00:00
wxiaoguang 9ea91e036f Refactor git command context & pipeline (#36406)
Less and simpler code, fewer bugs
2026-01-21 01:35:14 +00:00
Lunny Xiao f6db180a80 Fix missing repository id when migrating release attachments (#36389)
This PR fixes missed repo_id on the migration of attachments to Gitea.
It also provides a doctor check to fix the dirty data on the database.
2026-01-20 10:05:51 -08:00
GiteaBot 987d82b038 [skip ci] Updated translations via Crowdin 2026-01-20 00:39:58 +00:00
wxiaoguang 72be55f7d3 Refactor git command stderr handling (#36402)
And clean up legacy fragile & incorrect logic
2026-01-18 15:10:33 -08:00
Lunny Xiao fafd1db19e Some refactors about GetMergeBase (#36186)
Maybe fix #32018

- Use `gitrepo.GetMergeBase` method instead of other two
implementations.
- Add `FetchRemoteCommit` so that we don't need to add many `remote` to
the git repository to avoid possible git lock conflicts. A lock will
start when invoke the function, it will be invoked when cross-repository
comparing. The head repository will fetch the base repository's base
commit id. In most situations, it should lock the fork repositories so
that it should not become a bottleneck.
- Improve `GetCompareInfo` to remove unnecessarily adding remote.
- Remove unnecessary parameters of `SignMerge`.
2026-01-17 11:22:09 -08:00
wxiaoguang 149f7a6f1f Refactor git command stdio pipe (#36393)
And remove the incorrect `ensureValidGitRepository`
2026-01-17 18:11:46 +00:00
yy 7a2aac406d fix: typos in comments (#36394) 2026-01-17 17:03:25 +00:00
TheFox0x7 906ad802cf add support for archive-upload rpc (#36391)
Add support for fetching archives with `git archive --remote <repo-url>`

closes: https://github.com/go-gitea/gitea/issues/23425

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-17 15:17:00 +00:00
Lunny Xiao 393c854f7b Hide delete directory button for mirror or archive repository and disable the menu item if user have no permission (#36384) 2026-01-16 22:25:24 +02:00
Gregorius Bima Kharisma Wicaksana 65422fde4d Fix CODEOWNERS review request attribution using comment metadata (#36348)
Fixes #36333

## Problem

When CODEOWNERS automatically assigns reviewers to a pull request, the
timeline incorrectly shows the PR author as the one who requested the
review (e.g., "PR_AUTHOR requested review from CODE_OWNER"). This is
misleading since the action was triggered automatically by CODEOWNERS
rules, not by the PR author.

## Solution

Store CODEOWNERS attribution in comment metadata instead of changing the
doer user:
- Add `SpecialDoerName` field to `CommentMetaData` struct (value:
`"CODEOWNERS"` for CODEOWNERS-triggered requests)
- Pass `isCodeOwners=true` to `AddReviewRequest` and
`AddTeamReviewRequest` functions
- Template can check this metadata to show appropriate attribution
message

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-16 14:52:57 +00:00
silverwind 49edbbbc2e Update JS and PY deps (#36383)
- Update JS and PY dependencies
- Workaround https://github.com/stylelint/stylelint/issues/8893 by
moving the stylint config file to JS
- Regenerate SVGs
- Bump to python 3.14 in devcontainer and actions
- Verified `@github/text-expander-element`
- Removed obsolete type stub
2026-01-16 11:00:16 +00:00
TheFox0x7 69c5921d71 Add ability to download subpath archive (#36371)
closes: https://github.com/go-gitea/gitea/issues/4478

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-16 09:31:12 +00:00
Lunny Xiao 67e75f30a8 Fix bug on notification read (#36339)
When a user has been revoked permission to access a repository, the
related notification could still be visited. But the repository's
information should not be leaked any more.
2026-01-15 21:11:13 -08:00
Zeno 3f46de8265 Add chunked transfer encoding support for LFS uploads (#36380)
Enable chunked transfer encoding for Git LFS uploads by adding
Transfer-Encoding: chunked header to upload action responses. This
prevents large file uploads (100+ MB) from being blocked by reverse
proxies like Cloudflare that buffer non-chunked requests.

Fix https://github.com/go-gitea/gitea/issues/22233

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-16 07:15:18 +08:00
silverwind 4a9ac53862 Migrate to import.meta.env and clean up types and eslint (#36362)
`import.meta.env` is supported in both vitest and webpack [as of
recent](https://github.com/webpack/webpack/pull/19996), so replace all
previous use of `process.env` with it. Current usage is limited to test
files, I've also verified it works in actual frontend code.

`webpack/module` is added to typescript types which includes the
definition for `import.meta.env`. I've also made the eslint globals more
precise. Finally, `__webpack_public_path__` is removed from our type
definitions because `webpack/module` also provides it.
2026-01-15 11:01:23 +00:00
silverwind 915a2cd86f Rename CSS variables and improve colorblind themes (#36353)
Followup https://github.com/go-gitea/gitea/pull/36215, rename the
variables for consistency with existing vars and change green to value
of `--color-blue` in the relevant color blind themes:

<img width="1305" height="303" alt="image"
src="https://github.com/user-attachments/assets/3d131ab7-99ab-4b03-93ab-715ce0030b08"
/>


The blue coloring also matched GitHub:

<img width="1313" height="393" alt="image"
src="https://github.com/user-attachments/assets/f97e35b2-4ff4-49b0-841f-ffd49a02e03d"
/>

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-01-15 06:18:33 +00:00
Michael Hoang 8e9fb4d14c Indicate when only optional checks failed (#36367)
Currently it's not clear that you can merge a PR when only optional
checks failed:

<img width="922" height="447" alt="Screenshot 2026-01-14 at 4 08 17 pm"
src="https://github.com/user-attachments/assets/e11670c7-5ab9-42d7-af09-2d8a8fd532d3"
/>

This PR changes the text to say "Some optional checks failed" when only
optional checks failed:

<img width="922" height="443" alt="Screenshot 2026-01-14 at 3 59 08 pm"
src="https://github.com/user-attachments/assets/9ea69b13-38d6-4cfc-b4f7-952eff58e546"
/>

When a required check fails it'll still say "Some checks failed":

<img width="928" height="343" alt="Screenshot 2026-01-14 at 3 59 20 pm"
src="https://github.com/user-attachments/assets/d3764a95-9737-4482-851e-d3406b1e4d76"
/>

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-14 14:25:14 -08:00
Lunny Xiao 14e8c9b767 Release attachments must belong to the intended repo (#36347) 2026-01-14 11:37:53 -08:00
Lunny Xiao 7b5de594cd Fix permission check on org project operations (#36318) 2026-01-14 17:29:33 +00:00
Lunny Xiao 07ac29da32 Fix bug when compare in the pull request (#36363)
The pull request comparison should not use `direct compare`.
2026-01-14 16:56:23 +00:00
Lunny Xiao 8a98ac2213 clean watches when make a repository private and check permission when send release emails (#36319) 2026-01-14 16:11:22 +00:00
wxiaoguang 1c1a7b8492 Fix incorrect text content detection (#36364)
Fix #36325
2026-01-14 23:35:52 +08:00
Lunny Xiao 95ea2df00a Add more check for stopwatch read or list (#36340) 2026-01-13 13:13:39 +00:00
Lunny Xiao ed5720af2a Fix openid setting check (#36346) 2026-01-13 12:44:29 +00:00
DHANUSH VANARASA e95c30eb80 Docs: minor punctuation improvement in CONTRIBUTING.md (#36291) 2026-01-13 13:13:57 +01:00
silverwind 2859b0602a Update JS deps (#36354)
- Update all JS deps
- Regenerate SVGs
- Enable new lint rules and fix issues
- Tested affected dependencies
2026-01-13 04:06:58 +00:00
TheFox0x7 040fc93046 fill missing has_code in repository api (#36338)
fixes: https://github.com/go-gitea/gitea/issues/36332

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-01-12 22:52:44 +00:00
wxiaoguang 7a23e247e6 Fix notifications pagination query parameters (#36351)
Fix #36350
2026-01-12 22:17:42 +00:00
Lunny Xiao c8b5a1ddf7 Fix cancel auto merge bug (#36341) 2026-01-12 13:47:06 -08:00
dependabot[bot] b1b5897795 Bump appleboy/git-push-action from 1.0.0 to 1.2.0 (#36306)
Bumps
[appleboy/git-push-action](https://github.com/appleboy/git-push-action)
from 1.0.0 to 1.2.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/appleboy/git-push-action/releases">appleboy/git-push-action's
releases</a>.</em></p>
<blockquote>
<h2>v1.2.0</h2>
<h2>Changelog</h2>
<h3>Features</h3>
<ul>
<li>2722561d2c158e67f0e4b908bda83937e53bbdd4: feat: add options for
insecure SSL and SSH version selection (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
</ul>
<h3>Others</h3>
<ul>
<li>2c87d5bacd46972f72523394e67af39825081037: style: standardize YAML
quoting and update input descriptions (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>66a962f89a56024b2a36de61fe65ba6b9994be15: fix: rename drone-git-push
env vars and update default version (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
</ul>
<h3>Enhancements</h3>
<ul>
<li>e37f17de403a8b0b59184d852be6b7a7e017d376: chore: mark all
directories as safe in global git configuration (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
</ul>
<h3>Refactor</h3>
<ul>
<li>7bdda76242d8f6b40576a039a2d2233c43b7661e: refactor: refactor GitHub
Action to use Bash instead of Docker (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
<li>4873de66e7bed19267cc8cd66959005c42d41cc7: refactor: simplify stdout
capturing by removing legacy logic (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
</ul>
<h3>Build process updates</h3>
<ul>
<li>d1c361f2d2e128593b5dfeb3c2d9a5c6a1af7128: ci: run Docker actions as
nobody and inject GITHUB_WORKSPACE (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
<li>fdf995de1284df95f38a3d99275eb38537eb05a4: ci: simplify Docker action
environment variable configuration (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
<li>8e938ac7df8937d595e4c4fcf345139339a34819: ci: update
GITHUB_WORKSPACE to use /github/home path (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
</ul>
<h3>Documentation updates</h3>
<ul>
<li>3b2c8661652360dbf1afe1b319a49dbb739c39f1: docs: migrate to composite
GitHub Action and standardize env vars (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
</ul>
<h2>v1.1.0</h2>
<h2>Changelog</h2>
<h3>Features</h3>
<ul>
<li>28a54bbef16233cbea6f9fe39f318a4f055cd749: feat: add mirror input
support to GitHub Action configuration (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>a63ac675f748ad297929b6d9688f94939fbe3dea: fix: fix spelling of
'force' option in git push actions (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
</ul>
<h3>Enhancements</h3>
<ul>
<li>ee39884535468c8b6f101c0980aec38a61bc6c8b: chore(readme): refactor
codebase and update dependencies (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
<li>94fb0c0d87ba52affdcb2daf8505a0e7f086f205: chore: bump drone-git-push
base image to version 1.2.0 (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
<li>a939634b19fa88f0d4c853f4b604a4df5549911d: chore: pin Drone Git Push
image to a specific version (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
</ul>
<h3>Build process updates</h3>
<ul>
<li>0a16d15bfdca306c84a299db735f248e9d408bb3: ci: improve CI workflow
for semantic version releases (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
<li>1807bf9a1b801f99799e4e2a64ca1c6b11301fc3: ci: automate maintenance
and enhance repository security (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
<li>f39abba130277d16a141588c1b4c194a8f0b4636: build: run container as
non-root user for enhanced security (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
<li>ed86ac596a332db5353062d7cbdf24d61554f5f1: ci: update CI workflows to
trigger on main branch (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
<li>cd8de7f6c86b1390f0108011580b6c9845b9f5df: build: eliminate
&quot;nobody&quot; user references from Dockerfile (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
<li>7465fee0c6ac1466048408a99c52598be9abf00f: ci: update CI workflow to
use newer actions/checkout version (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
<li>b9d4e07212dd711b7e57352e5b6172038ab20f6e: build: simplify Docker
build by removing entrypoint.sh chmod step (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
<li>14d3003b72ea485bf8707bfbef4926eca78cc341: build: upgrade CI pipeline
to latest drone-git-push base image (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
</ul>
<h3>Documentation updates</h3>
<ul>
<li>378ab1be62cfbae4111d3bbbec417d5b2e97134d: docs: clarify and
standardize input and action descriptions (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
<li>4c679526c0d1910c6e058a82fdde978d5cd8c0c2: docs: revamp documentation
with expanded features and usage examples (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
<li>61f29e5108e85fa252a0556c08ec87f0c425f1b2: docs: document GitHub
Action integration and Claude Code guidelines (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
<li>a7ef8abff3f71345b67dc056ac3d7b2d006efa42: docs: add Trivy security
scan badge to documentation (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/appleboy/git-push-action/commit/3b2c8661652360dbf1afe1b319a49dbb739c39f1"><code>3b2c866</code></a>
docs: migrate to composite GitHub Action and standardize env vars</li>
<li><a
href="https://github.com/appleboy/git-push-action/commit/4873de66e7bed19267cc8cd66959005c42d41cc7"><code>4873de6</code></a>
refactor: simplify stdout capturing by removing legacy logic</li>
<li><a
href="https://github.com/appleboy/git-push-action/commit/2c87d5bacd46972f72523394e67af39825081037"><code>2c87d5b</code></a>
style: standardize YAML quoting and update input descriptions</li>
<li><a
href="https://github.com/appleboy/git-push-action/commit/2722561d2c158e67f0e4b908bda83937e53bbdd4"><code>2722561</code></a>
feat: add options for insecure SSL and SSH version selection</li>
<li><a
href="https://github.com/appleboy/git-push-action/commit/66a962f89a56024b2a36de61fe65ba6b9994be15"><code>66a962f</code></a>
fix: rename drone-git-push env vars and update default version</li>
<li><a
href="https://github.com/appleboy/git-push-action/commit/7bdda76242d8f6b40576a039a2d2233c43b7661e"><code>7bdda76</code></a>
refactor: refactor GitHub Action to use Bash instead of Docker</li>
<li><a
href="https://github.com/appleboy/git-push-action/commit/8e938ac7df8937d595e4c4fcf345139339a34819"><code>8e938ac</code></a>
ci: update GITHUB_WORKSPACE to use /github/home path</li>
<li><a
href="https://github.com/appleboy/git-push-action/commit/e37f17de403a8b0b59184d852be6b7a7e017d376"><code>e37f17d</code></a>
chore: mark all directories as safe in global git configuration</li>
<li><a
href="https://github.com/appleboy/git-push-action/commit/fdf995de1284df95f38a3d99275eb38537eb05a4"><code>fdf995d</code></a>
ci: simplify Docker action environment variable configuration</li>
<li><a
href="https://github.com/appleboy/git-push-action/commit/d1c361f2d2e128593b5dfeb3c2d9a5c6a1af7128"><code>d1c361f</code></a>
ci: run Docker actions as nobody and inject GITHUB_WORKSPACE</li>
<li>Additional commits viewable in <a
href="https://github.com/appleboy/git-push-action/compare/v1.0.0...v1.2.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=appleboy/git-push-action&package-manager=github_actions&previous-version=1.0.0&new-version=1.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-12 17:47:41 +00:00
silverwind 1d399bb1d1 Improve diff file headers (#36215)
- reduce file name font size from 15px to 14px
- fix labels and buttons being cut off when their size is constrained
- change labels from monospace to sans-serif font
- move diff stats to right and change them from sum of changes to +/-
- change filemode to label and change text to match other labels

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-12 20:29:35 +08:00
Lunny Xiao fbea2c68e8 Fix delete attachment check (#36320) 2026-01-12 08:16:59 +00:00
GiteaBot 48d5adb39c [skip ci] Updated translations via Crowdin 2026-01-12 00:42:33 +00:00
Lunny Xiao da036f3f35 LFS locks must belong to the intended repo (#36344) 2026-01-11 12:57:58 +02:00
Sebastian Ertz 8319d8f381 Update chroma to v2.22.0 (#36342)
https://github.com/alecthomas/chroma/releases/tag/v2.22.0
2026-01-10 20:12:59 +00:00
Sebastian Ertz 18c393419f Update goldmark to v1.7.16 (#36343)
https://github.com/yuin/goldmark/releases/tag/v1.7.16
2026-01-10 11:42:02 -08:00
wxiaoguang eec8ee056c Fix some trivial problems (#36336)
1. correctly parse git protocol's "OldCommit NewCommit RefName" line, it
should be explicitly split by space
2. add missing "return" in CreatePullRequest
3. add comments for "/user.keys" and "/user.gpg" outputs
4. trim space for the "commit status context name" to follow the same
behavior of git_model.NewCommitStatus
2026-01-09 20:58:21 +02:00
wxiaoguang f6d3c70818 Fix diff view style handling (#36324)
Fix #36323
2026-01-09 04:37:16 +00:00
wxiaoguang e226720cff Refactor cat-file batch operations and support --batch-command approach (#35775)
Replace #34651 and address more problems including fix framework bugs and changing to QueryInfo and QueryContent calls.

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-01-08 13:37:36 -08:00
bytedream ee9d8893a7 Fix file-tree ui error when adding files to repo without commits (#36312)
When visiting the new file & upload file pages on a repo that has no
commits, the request for file-tree files fails.

---

<img width="1173" height="728" alt="Screenshot_20260106_175938"
src="https://github.com/user-attachments/assets/69e0ee0d-24af-4f5f-be7e-d64c03b5a5cb"
/>
<img width="349" height="95" alt="image"
src="https://github.com/user-attachments/assets/6e0b5252-95f2-4094-8d11-e0c5262f525b"
/>

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-08 12:04:51 -08:00
Gregorius Bima Kharisma Wicaksana f9d3983de2 fix: generate IDs for HTML headings without id attribute (#36233)
This PR fixes #27383 where HTML headings like `<h1>Title</h1>` in
markdown files would have empty permalink anchors

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-06 05:09:44 +00:00
Daniel Mach 1d01286f4c Add 'allow_maintainer_edit' API option for creating a pull request (#36283)
WebUI has a checkbox for enabling maintainer edits you can check right
away when creating a new pull request.
Also, it is possible to set `allow_maintainer_edit` in an existing pull
request via API.
This change enables the option while creating a new pull request via
API.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-06 01:00:26 +08:00
Joakim Olsson 1ee7f8e966 fix: prevent panic when GitLab release has more links than sources (#36295)
The code incorrectly assumed rel.Assets.Links and rel.Assets.Sources
arrays have equal length. This causes index out of bounds panic when
migrating GitLab releases with more links than sources, which is common
with GoReleaser-generated releases.

Fixes #36292

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-05 21:48:12 +08:00
Lunny Xiao 426bb491c0 Move assign project when creating pull request to the same database transaction (#36244) 2026-01-04 16:45:36 +00:00
GiteaBot 78ad28d052 [skip ci] Updated translations via Crowdin 2026-01-04 00:45:02 +00:00
Lunny Xiao af95cbc0de Fix stats bug when syncing release (#36285) 2026-01-03 10:55:37 -08:00
wxiaoguang b79dbfa990 Fix link/origin referrer and login redirect (#36279)
Fix #35998

1. Fix `<a rel>` :
    * "_blank" already means "noopener"
* "noreferrer" is already provided by page's `<meta name="referrer">`
2. Fix "redirect_to" mechisam
* Use "referer" header to determine the redirect link for a successful
login
3. Simplify code and merge duplicate logic
2026-01-03 11:43:04 +08:00
wxiaoguang 6fb3547417 Always honor user's choice for "delete branch after merge" (#36281)
Fix #36280
2026-01-03 10:36:21 +08:00
luo jiyin d2baa8103f refactor(pprof): use explicit mux instead of DefaultServeMux (#36276)
- Replace blank import of `net/http/pprof` with explicit import
- Create dedicated `http.ServeMux` for pprof server
- Register pprof handlers explicitly

---------

Signed-off-by: luojiyin <luojiyin@hotmail.com>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-02 08:06:06 +00:00
Lunny Xiao 8373f7deb3 improve the compare page (#36261)
- The compare page head title should be `compare` but not `new pull
request`.
- Use `UnstableGuessRefByShortName` instead of duplicated functions
calls.
- Direct-compare, tags, commits compare will not display `New Pull
Request` button any more.

The new screenshot
<img width="1459" height="391" alt="image"
src="https://github.com/user-attachments/assets/64e9b070-9c0b-41d1-b4b8-233b96270e1b"
/>

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-01 10:32:19 -08:00
luo jiyin 98981eb749 mailer: pass request context to generateAdditionalHeadersForIssue (#36274)
Fixes #36273

Use the caller-provided context when building X-Gitea-Issue-Link,
instead of `context.TODO()`.
2026-01-01 04:28:25 +00:00
Max P. 91d871611e feat(debian): use explicit, stronger defaults for newly generated repo signing keys (#36236)
Make Debian repository signing key generation use explicit stronger defaults
and embed the creation time in the OpenPGP comment for newly created keys.

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-01-01 02:36:14 +00:00
wxiaoguang 094104bc91 Make "commit statuses" API accept slashes in "ref" (#36264)
Fix #36253

Support slashes in `{ref}` (follow GitHub's behavior)
2026-01-01 09:56:07 +08:00
Lunny Xiao 1771569300 Some refactor for repo path (#36251)
- Use `gitrepo.IsRepositoryExist` instead of `util.IsExit` or
`util.IsDir`
- Use `gitrepo.OpenRepository` instead of `git.OpenRepository`
- Use `gitrepo.DeleteRepository` instead of `util.RemoveAll`
- Use `gitrepo.RenameRepository` instead of `util.Rename`
2025-12-29 18:49:54 +00:00
Lunny Xiao 0ad94dfc70 Move catfile batch to a sub package of git module (#36232) 2025-12-29 10:19:42 -08:00
alphazeba d0cb198c89 fix: prevent 100% width radio buttons (#36262)
as part of [Remove fomantic form
module](https://github.com/go-gitea/gitea/commit/eddf8759926911c465b249de5f6d68c052a539e0#diff-c34b74004deb63fb4f8a8549ef9d822b9839db0b69ae2c0cdacc05ce3d5d5682)
radio buttons get caught in crossfire and recieve `width: 100%` this is
particularly noticeable on the `user/settings/applications` page which
has many radio buttons.

This continues using an opt out `input:not([type="checkbox"],
[type="radio"])` to prevent this.

Signed-off-by: alphazeba <33792307+alphazeba@users.noreply.github.com>
2025-12-29 09:51:10 +02:00
GiteaBot 85dd16b3fc [skip ci] Updated translations via Crowdin 2025-12-29 00:43:22 +00:00
Lunny Xiao c7b3cdf7b1 Use gitrepo's push function (#36245)
extract from #36186
2025-12-28 13:24:28 +02:00
Gregorius Bima Kharisma Wicaksana 83527d3f8a Support closing keywords with URL references (#36221)
## Summary

This PR adds support for closing keywords (`closes`, `fixes`, `reopens`,
etc.) with full URL references in markdown links.

**Before:**
- `closes #123`  works
- `closes org/repo#123`  works  
- `Closes [this issue](https://gitea.io/user/repo/issues/123)`  didn't
work
- `Fixes [#456](https://gitea.io/org/project/issues/456)`  didn't work

**After:**
All of the above now work correctly.

## Problem

When users reference issues using full URLs in markdown links (e.g.,
`Closes [this issue](https://gitea.io/user/repo/issues/123)`), the
closing keywords were not detected. This was because the URL processing
code explicitly stated:

```go
// Note: closing/reopening keywords not supported with URLs
```

Both methods of writing the reference render the same in the UI, so
users expected the closing keywords to behave the same.

## Solution

The fix works by:
1. Passing the original (unstripped) content to
`findAllIssueReferencesBytes`
2. When processing URL links from markdown, finding the URL position in
the original content
3. For markdown links `[text](url)`, finding the opening bracket `[`
position
4. Using that position to detect closing keywords before the link

## Testing

Added test cases for:
- `Closes [this issue](url)` - single URL with closing keyword
- `This fixes [#456](url)` - keyword in middle of text
- `Reopens [PR](url)` - reopen keyword with pull request URL
- Multiple URLs where only one has a closing keyword

All existing tests continue to pass.

Fixes #27549
2025-12-27 09:05:24 -08:00
Ivan Tkatchev 19e1997ee2 Add an option to automatically verify SSH keys from LDAP (#35927)
This pull request adds an option to automatically verify SSH keys from
LDAP authentication sources.

This allows a correct authentication and verification workflow for
LDAP-enabled organizations; under normal circumstances SSH keys in LDAP
are not managed by users manually.
2025-12-27 12:33:08 +00:00
Lunny Xiao 00cc84e37c remove nolint (#36252) 2025-12-26 22:55:30 -08:00
sollyu 64fcf847ce Use the requested host for LFS links (#36242)
Use the dynamically parsed host in the request for LFS links, but not
use the hard-coded AppURL.

Make LFS server support multi-domain or run Gitea behind a reverse-proxy
with different ROOT_URL.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-12-26 04:48:20 +00:00
Lunny Xiao ff3d68b98a Fix panic when get editor config file (#36241)
Fix #36239
2025-12-25 19:26:23 -08:00
Lunny Xiao 776e406363 Refactor compare router param parse (#36105)
---------

Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-12-25 17:51:30 -08:00
GiteaBot fbbed8c4c4 [skip ci] Updated translations via Crowdin 2025-12-25 21:37:43 +00:00
Lunny Xiao 324dcf6f64 Use flatten translation keys (#36225)
Crowdin does not remove empty lines in nested JSON translation files.
Therefore, we use flattened translation keys instead. We have also
updated the key-loading logic to ensure that empty values are not
applied during translation.

---------

Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: TheFox0x7 <thefox0x7@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2025-12-25 12:51:33 -08:00
silverwind 42d294941c Replace CSRF cookie with CrossOriginProtection (#36183)
Removes the CSRF cookie in favor of
[`CrossOriginProtection`](https://pkg.go.dev/net/http#CrossOriginProtection)
which relies purely on HTTP headers.

Fixes: https://github.com/go-gitea/gitea/issues/11188
Fixes: https://github.com/go-gitea/gitea/issues/30333
Helps: https://github.com/go-gitea/gitea/issues/35107

TODOs:

- [x] Fix tests
- [ ] Ideally add tests to validates the protection

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-12-25 12:33:34 +02:00
silverwind eddf875992 Remove fomantic form module (#36222)
- Replace fomantic form CSS with custom module
- Moved code in `form.css` to `modules/form.css`, removed around 70% of
the previous module.
- Moved captcha styles previously in `form.css` to its own file.

There is probably more unused CSS, like form error state colors which to
my knowledge is not used anywhere, but I'm not sure about that one so I
kept it.

One notable change is the removal of `type` combinator here, which
lowers the selector specificity and I noticed one issue where selector
`.ui.search > .prompt` was winning, so I added a workaround for that
until the `search` module can be removed as well.

```css
.ui.form .fields.error .field input:not([type])
.ui.form .fields.error .field input[type="date"]
```

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2025-12-23 18:21:47 +01:00
Max P. 957151937f Fix panic in blame view when a file has only a single commit (#36230)
This PR fixes a panic in the repository blame view that occurs when
rendering files whose blame history consists of only a single commit.
2025-12-23 14:26:29 +08:00
DaanSelen 04607f7d4a fix: spelling error in migrate-storage cmd utility (#36226)
Added closing quote which looks to be forgotten

Signed-off-by: DaanSelen <80752476+DaanSelen@users.noreply.github.com>
2025-12-22 10:55:41 +00:00
silverwind 60de6cefed Fix WebAuthn error checking (#36219)
Fixes: https://github.com/go-gitea/gitea/issues/36216

Now `detectWebAuthnSupport` returns the error type and lets the caller
decide whether they call `webAuthnError` and show the error. It no
longer shows the error during page load when the user has not even
interacted with the feature.

The bug affects all users on HTTP, so I think a quick fix release for
this might be good.
2025-12-21 18:24:41 +00:00
GiteaBot 5151e30fb7 [skip ci] Updated translations via Crowdin 2025-12-21 17:09:57 +00:00
Gregorius Bima Kharisma Wicaksana b6ffe0e4e9 refactor: extract helper functions from SearchIssues (#36158)
## Summary

This PR refactors the `SearchIssues` function in
`routers/api/v1/repo/issue.go` by extracting common logic into reusable
helper functions:

- `parseIssueIsClosed()`: Parses the "state" query parameter and returns
the corresponding `isClosed` option
- `parseIssueIsPull()`: Parses the "type" query parameter and returns
the corresponding `isPull` option
- `buildSearchIssuesRepoIDs()`: Builds the list of repository IDs for
issue search based on query parameters

### Benefits:
- Improved code readability
- Smaller, more focused functions
- Easier to test individual components
- Potential for reuse in other handlers

### Changes:
- Extracted 3 helper functions from the ~292 line `SearchIssues`
function
- No functional changes - behavior remains the same
- Proper error handling preserved

## Test plan
- [ ] Verify existing API tests pass
- [ ] Manual testing of `/repos/issues/search` endpoint

Ref: #35015

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-12-20 17:57:41 -08:00
GiteaBot bf0b377879 [skip ci] Updated translations via Crowdin 2025-12-21 00:42:41 +00:00
Lunny Xiao 0a3a9fb068 Revert "[skip ci] Updated translations via Crowdin"
This reverts commit d3656ebd95.
2025-12-20 09:15:26 -08:00
Scion 495fee4555 Closed milestones with no issues now show as 100% completed (#36220)
Closed milestones with 0 issues currently display as having 0%
completion. This makes sense if the milestone is still open, but if the
milestone is closed it seems like that it should show 100% completeness
instead.

Before:
<img width="1708" height="252" alt="image"
src="https://github.com/user-attachments/assets/0b58c78f-0609-44ee-8d58-bd67534c6164"
/>
After:
<img width="1716" height="263" alt="image"
src="https://github.com/user-attachments/assets/3fb0044f-d76c-4888-9d60-640f2ca5fec6"
/>
2025-12-20 16:16:20 +00:00
bytedream 05c3b84f84 Show edit page confirmation dialog on tree view file change (#36130)
Currently, when editing or deleting a file and the edit/commit form has
changes, navigating the file tree will discard all changes without any
warning. This PR prevents partial reloading when the edit form has
unsaved changes, which will trigger a browser native warning dialog.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-12-20 02:29:39 +01:00
Peter Verraedt b4c9057f92 Fix regression in writing authorized principals (#36213)
Add additional logic with tests to restore the
previous behaviour when writing the principals file.

Fixes: #36212

---------

Signed-off-by: Peter Verraedt <peter.verraedt@kuleuven.be>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-12-20 01:24:59 +00:00
GiteaBot d3656ebd95 [skip ci] Updated translations via Crowdin 2025-12-20 00:37:17 +00:00
Lunny Xiao ffea9a27c3 Convert locale files from ini to json format (#35489)
Migrate from the current INI format to JSON for translations. JSON is
widely supported, including by platforms such as Crowdin and Weblate.
2025-12-19 09:50:48 -08:00
dependabot[bot] 9764ae87d2 Bump crowdin/github-action from 1 to 2 (#36204)
Bumps [crowdin/github-action](https://github.com/crowdin/github-action)
from 1 to 2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/crowdin/github-action/releases">crowdin/github-action's
releases</a>.</em></p>
<blockquote>
<h2>v2.0.0</h2>
<h2>What's Changed</h2>
<h3>Features</h3>
<ul>
<li>Now the Action uses the new <a
href="https://crowdin.github.io/crowdin-cli/blog/2024/05/28/cli-v4">CLI
v4</a></li>
</ul>
<h3>Deprecations</h3>
<p>Removed deprecated options:</p>
<ul>
<li><code>add_crowdin_branch</code></li>
<li><code>new_branch_title</code></li>
<li><code>new_branch_export_pattern</code></li>
<li><code>new_branch_priority</code></li>
<li><code>delete_crowdin_branch</code></li>
</ul>
<p>Instead, use the <code>command: branch add &lt;name&gt;</code> to
create a new branch.</p>
<ul>
<li><code>identity</code> - this option doesn't make much sense in the
context of the GitHub action, where environment variables are a de facto
standard for credentials loading.</li>
</ul>
<hr />
<p><strong>Full Changelog</strong>: <a
href="https://github.com/crowdin/github-action/compare/v1.20.4...v2.0.0">https://github.com/crowdin/github-action/compare/v1.20.4...v2.0.0</a></p>
<h2>v1.20.4</h2>
<h2>What's Changed</h2>
<ul>
<li>CLI <a
href="https://github.com/crowdin/crowdin-cli/releases/tag/3.19.4">3.19.4</a>
by <a
href="https://github.com/andrii-bodnar"><code>@​andrii-bodnar</code></a></li>
<li>ci: upgrade actions by <a
href="https://github.com/andrii-bodnar"><code>@​andrii-bodnar</code></a>
in <a
href="https://redirect.github.com/crowdin/github-action/pull/226">crowdin/github-action#226</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/crowdin/github-action/compare/v1.20.3...v1.20.4">https://github.com/crowdin/github-action/compare/v1.20.3...v1.20.4</a></p>
<h2>v1.20.3</h2>
<h2>What's Changed</h2>
<ul>
<li>CLI <a
href="https://github.com/crowdin/crowdin-cli/releases/tag/3.19.3">3.19.3</a>
by <a
href="https://github.com/andrii-bodnar"><code>@​andrii-bodnar</code></a></li>
<li>chore: deprecate the 'identity' option by <a
href="https://github.com/andrii-bodnar"><code>@​andrii-bodnar</code></a>
in <a
href="https://redirect.github.com/crowdin/github-action/pull/224">crowdin/github-action#224</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/crowdin/github-action/compare/v1.20.2...v1.20.3">https://github.com/crowdin/github-action/compare/v1.20.2...v1.20.3</a></p>
<h2>v1.20.2</h2>
<h2>What's Changed</h2>
<ul>
<li>CLI <a
href="https://github.com/crowdin/crowdin-cli/releases/tag/3.19.2">3.19.2</a>
by <a
href="https://github.com/andrii-bodnar"><code>@​andrii-bodnar</code></a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/crowdin/github-action/compare/v1.20.1...v1.20.2">https://github.com/crowdin/github-action/compare/v1.20.1...v1.20.2</a></p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/crowdin/github-action/commit/60debf382ee245b21794321190ad0501db89d8c1"><code>60debf3</code></a>
docs: add example for source files caching between workflow runs (<a
href="https://redirect.github.com/crowdin/github-action/issues/298">#298</a>)</li>
<li><a
href="https://github.com/crowdin/github-action/commit/96b44e6697270c9ebc7098e62ad3799326a17a97"><code>96b44e6</code></a>
chore: CLI 4.12.0</li>
<li><a
href="https://github.com/crowdin/github-action/commit/08713f00a50548bfe39b37e8f44afb53e7a802d4"><code>08713f0</code></a>
feat: add pull_request_created output to track PR status (<a
href="https://redirect.github.com/crowdin/github-action/issues/294">#294</a>)</li>
<li><a
href="https://github.com/crowdin/github-action/commit/fb221ac1c83fae63a04d1b3149abfd44ac3dd76f"><code>fb221ac</code></a>
fix: bundle download with branch param conflict (<a
href="https://redirect.github.com/crowdin/github-action/issues/291">#291</a>)</li>
<li><a
href="https://github.com/crowdin/github-action/commit/0749939f635900a2521aa6aac7a3766642b2dc71"><code>0749939</code></a>
chore: CLI 4.11.0</li>
<li><a
href="https://github.com/crowdin/github-action/commit/9787f4fcb6a8450929673f1e8db841e8a5c35a2f"><code>9787f4f</code></a>
chore: CLI 4.10.0</li>
<li><a
href="https://github.com/crowdin/github-action/commit/590c05e09a29f392b203faf4d6aa8e0cd32c7835"><code>590c05e</code></a>
chore: CLI 4.9.1</li>
<li><a
href="https://github.com/crowdin/github-action/commit/9fd07c1c5b36b15f082d1d860dc399f16f849bd7"><code>9fd07c1</code></a>
chore: CLI 4.9.0</li>
<li><a
href="https://github.com/crowdin/github-action/commit/297234bae049541aa48ed268e5de00dee4efa4b4"><code>297234b</code></a>
chore: CLI 4.8.0</li>
<li><a
href="https://github.com/crowdin/github-action/commit/37201e27eec38a4393c7367e103d4063739eca84"><code>37201e2</code></a>
docs: AI Localization improvements (<a
href="https://redirect.github.com/crowdin/github-action/issues/283">#283</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/crowdin/github-action/compare/v1...v2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=crowdin/github-action&package-manager=github_actions&previous-version=1&new-version=2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: silverwind <me@silverwind.io>
2025-12-19 13:49:30 +00:00
dependabot[bot] 684a541799 Bump appleboy/git-push-action from 0.0.3 to 1.0.0 (#36194)
Bumps
[appleboy/git-push-action](https://github.com/appleboy/git-push-action)
from 0.0.3 to 1.0.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/appleboy/git-push-action/releases">appleboy/git-push-action's
releases</a>.</em></p>
<blockquote>
<h2>v1.0.0</h2>
<h2>Changelog</h2>
<h3>Enhancements</h3>
<ul>
<li>50ae8aaf06c6fc08b3d13da3aa03deb50d970125: chore(docker): improve
overall system performance and API integration (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
</ul>
<h3>Build process updates</h3>
<ul>
<li>feea2e25baaa5ea24a9689a8af03f229ec1dd1a2: ci: improve testing
workflow and API usage (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
<li>5d65d1094eb0415898554ba83c4f3196778f9a85: ci: improve testing
workflow and API usage (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
<li>b31dd8d6e7ba1e80a96a4772d8c4290fe7bac0ce: build: update base image
in Dockerfile (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
<li>fc585cfea49d10c08f8009f674c05961a0934647: ci(goreleaser): implement
automated release process with GoReleaser (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
<li>b1e5e3d76ccb4afd43bc0859672a6f9113fa0458: ci(test): optimize CI
workflow and test configurations (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
</ul>
<h3>Documentation updates</h3>
<ul>
<li>8f1f45876617e5d74085a38164c421be39f099b3: docs(readme): refactor
codebase and improve test coverage (<a
href="https://github.com/appleboy"><code>@​appleboy</code></a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/appleboy/git-push-action/commit/b1e5e3d76ccb4afd43bc0859672a6f9113fa0458"><code>b1e5e3d</code></a>
ci(test): optimize CI workflow and test configurations</li>
<li><a
href="https://github.com/appleboy/git-push-action/commit/8f1f45876617e5d74085a38164c421be39f099b3"><code>8f1f458</code></a>
docs(readme): refactor codebase and improve test coverage</li>
<li><a
href="https://github.com/appleboy/git-push-action/commit/fc585cfea49d10c08f8009f674c05961a0934647"><code>fc585cf</code></a>
ci(goreleaser): implement automated release process with GoReleaser</li>
<li><a
href="https://github.com/appleboy/git-push-action/commit/50ae8aaf06c6fc08b3d13da3aa03deb50d970125"><code>50ae8aa</code></a>
chore(docker): improve overall system performance and API
integration</li>
<li><a
href="https://github.com/appleboy/git-push-action/commit/b31dd8d6e7ba1e80a96a4772d8c4290fe7bac0ce"><code>b31dd8d</code></a>
build: update base image in Dockerfile</li>
<li><a
href="https://github.com/appleboy/git-push-action/commit/5d65d1094eb0415898554ba83c4f3196778f9a85"><code>5d65d10</code></a>
ci: improve testing workflow and API usage</li>
<li><a
href="https://github.com/appleboy/git-push-action/commit/feea2e25baaa5ea24a9689a8af03f229ec1dd1a2"><code>feea2e2</code></a>
ci: improve testing workflow and API usage</li>
<li>See full diff in <a
href="https://github.com/appleboy/git-push-action/compare/v0.0.3...v1.0.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=appleboy/git-push-action&package-manager=github_actions&previous-version=0.0.3&new-version=1.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-19 11:28:11 +00:00
silverwind 8f672cea4a Fix labeler config for stylelint (#36199)
Followup to rename in
https://github.com/go-gitea/gitea/commit/b8f1c9f048c23cff5cd5516b14242d3d3afb618d#diff-cb3b3f608024ee0bd45ea10b08ca6d3fcf40523a3d40182a438937231d8b8072.
2025-12-19 09:47:03 +00:00
silverwind e06040efd8 Add modifies/dependencies label to dependabot (#36206)
`actions/labeler` can not detect dependency updates in actions because
it works on file level, so we need to let dependabot set this label.
2025-12-19 08:49:26 +00:00
silverwind 16aa0fcc98 Add date to "No Contributions" tooltip (#36190)
Fixes https://github.com/go-gitea/gitea/issues/36188 via
https://github.com/silverwind/vue3-calendar-heatmap/commit/52bbfd7a15bb3ebbedcaae4d1f792dc3e4acc221.

Before:

<img width="183" height="92" alt="Screenshot 2025-12-18 at 16 50 18"
src="https://github.com/user-attachments/assets/f06ca7d6-a141-499f-b6da-e46064a44846"
/>

After:

<img width="292" height="78" alt="Screenshot 2025-12-18 at 17 08 36"
src="https://github.com/user-attachments/assets/b80f7391-7960-44ad-8184-ffab4c9a4ea7"
/>

If there will be more changes in the future, we should vendor this
module.

Co-authored-by: Giteabot <teabot@gitea.io>
2025-12-19 09:48:53 +01:00
silverwind 0043ae0139 Revert "Bump alpine to 3.23 (#36185)" (#36202)
Unbreak the release pipelines. The issue is caused by
https://gitlab.alpinelinux.org/alpine/aports/-/issues/17775 which
supposedly fixed in 3.23.2 and our build did use that version from what
I see, but maybe it's not fixed yet for `riscv`. We should try this
upgrade again later.
2025-12-18 23:18:01 -08:00
silverwind b915e6908c Add JSON linting (#36192)
Uses https://github.com/eslint/json to lint all JSON and JSONC files in the repo.
2025-12-19 06:27:21 +00:00
silverwind 36aa39fffe Bump setup-node to v6, re-enable cache (#36207) 2025-12-19 02:07:34 +00:00
GiteaBot 0a9c09879d [skip ci] Updated translations via Crowdin 2025-12-19 00:39:05 +00:00
Sebastian Ertz a9a4457dc3 Update chroma to v2.21.1 (#36201)
https://github.com/alecthomas/chroma/releases/tag/v2.21.1
2025-12-18 23:26:18 +00:00
silverwind 51e1ab5d7d Disable dependabot automatic labels (#36203)
Disable dependabot's [automatic
labels](https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference#labels--),
we have `actions/labeler` to do this job. After this is merged, I will
delete the labels `dependencies` and `github_actions` that dependabot
had created.
2025-12-18 23:56:08 +01:00
dependabot[bot] 5fa40bacea Bump astral-sh/setup-uv from 6 to 7 (#36198)
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 6
to 7.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/setup-uv/releases">astral-sh/setup-uv's
releases</a>.</em></p>
<blockquote>
<h2>v7.0.0 🌈 node24 and a lot of bugfixes</h2>
<h2>Changes</h2>
<p>This release comes with a load of bug fixes and a speed up. Because
of switching from node20 to node24 it is also a breaking change. If you
are running on GitHub hosted runners this will just work, if you are
using self-hosted runners make sure, that your runners are up to date.
If you followed the normal installation instructions your self-hosted
runner will keep itself updated.</p>
<p>This release also removes the deprecated input
<code>server-url</code> which was used to download uv releases from a
different server.
The <a
href="https://github.com/astral-sh/setup-uv?tab=readme-ov-file#manifest-file">manifest-file</a>
input supersedes that functionality by adding a flexible way to define
available versions and where they should be downloaded from.</p>
<h3>Fixes</h3>
<ul>
<li>The action now respects when the environment variable
<code>UV_CACHE_DIR</code> is already set and does not overwrite it. It
now also finds <a
href="https://docs.astral.sh/uv/reference/settings/#cache-dir">cache-dir</a>
settings in config files if you set them.</li>
<li>Some users encountered problems that <a
href="https://github.com/astral-sh/setup-uv?tab=readme-ov-file#disable-cache-pruning">cache
pruning</a> took forever because they had some <code>uv</code> processes
running in the background. Starting with uv version <code>0.8.24</code>
this action uses <code>uv cache prune --ci --force</code> to ignore the
running processes</li>
<li>If you just want to install uv but not have it available in path,
this action now respects <code>UV_NO_MODIFY_PATH</code></li>
<li>Some other actions also set the env var <code>UV_CACHE_DIR</code>.
This action can now deal with that but as this could lead to unwanted
behavior in some edgecases a warning is now displayed.</li>
</ul>
<h3>Improvements</h3>
<p>If you are using minimum version specifiers for the version of uv to
install for example</p>
<pre lang="toml"><code>[tool.uv]
required-version = &quot;&gt;=0.8.17&quot;
</code></pre>
<p>This action now detects that and directly uses the latest version.
Previously it would download all available releases from the uv repo
to determine the highest matching candidate for the version specifier,
which took much more time.</p>
<p>If you are using other specifiers like <code>0.8.x</code> this action
still needs to download all available releases because the specifier
defines an upper bound (not 0.9.0 or later) and &quot;latest&quot; would
possibly not satisfy that.</p>
<h2>🚨 Breaking changes</h2>
<ul>
<li>Use node24 instead of node20 <a
href="https://github.com/eifinger"><code>@​eifinger</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/608">#608</a>)</li>
<li>Remove deprecated input server-url <a
href="https://github.com/eifinger"><code>@​eifinger</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/607">#607</a>)</li>
</ul>
<h2>🐛 Bug fixes</h2>
<ul>
<li>Respect UV_CACHE_DIR and cache-dir <a
href="https://github.com/eifinger"><code>@​eifinger</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/612">#612</a>)</li>
<li>Use --force when pruning cache <a
href="https://github.com/eifinger"><code>@​eifinger</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/611">#611</a>)</li>
<li>Respect UV_NO_MODIFY_PATH <a
href="https://github.com/eifinger"><code>@​eifinger</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/603">#603</a>)</li>
<li>Warn when <code>UV_CACHE_DIR</code> has changed <a
href="https://github.com/jamesbraza"><code>@​jamesbraza</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/601">#601</a>)</li>
</ul>
<h2>🚀 Enhancements</h2>
<ul>
<li>Shortcut to latest version for minimum version specifier <a
href="https://github.com/eifinger"><code>@​eifinger</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/598">#598</a>)</li>
</ul>
<h2>🧰 Maintenance</h2>
<ul>
<li>Bump dependencies <a
href="https://github.com/eifinger"><code>@​eifinger</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/613">#613</a>)</li>
<li>Fix test-uv-no-modify-path <a
href="https://github.com/eifinger"><code>@​eifinger</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/604">#604</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/681c641aba71e4a1c380be3ab5e12ad51f415867"><code>681c641</code></a>
Bump actions/checkout from 5.0.0 to 6.0.1 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/712">#712</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/2e85713bb0ad1bd68b79183f00fe093dccd19930"><code>2e85713</code></a>
Bump actions/setup-node from 6.0.0 to 6.1.0 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/715">#715</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/58b6d7b303576a48786c1bbb6959b7875a3a84ec"><code>58b6d7b</code></a>
fix: add OS version to cache key to prevent binary incompatibility (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/716">#716</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/e8b52af86e46cb518daf4b47877e582bc9e37b8b"><code>e8b52af</code></a>
chore: update known checksums for 0.9.17 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/714">#714</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/ed21f2f24f8dd64503750218de024bcf64c7250a"><code>ed21f2f</code></a>
Bump peter-evans/create-pull-request from 7.0.8 to 7.0.9 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/695">#695</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/93202d8fbe8ed7d8099f4773a9684b037e0b6205"><code>93202d8</code></a>
bump dependencies (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/709">#709</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/5ce090076db3f5a2ed5bbd4a75c9123c727ff2af"><code>5ce0900</code></a>
set biome files.maxSize to 2MiB (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/708">#708</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/4180991cd97ec5ff7a3147ba70d3cc188015b467"><code>4180991</code></a>
allow cache-local-path w/o enable-cache (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/707">#707</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/0439606c8e2f1191835c4446afb6e4ac29363801"><code>0439606</code></a>
Bump github/codeql-action from 4.30.9 to 4.31.6 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/698">#698</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/7dd56c18e98cbf9546ad0ca8108ab326f681708a"><code>7dd56c1</code></a>
chore: update known checksums for 0.9.16 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/706">#706</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/astral-sh/setup-uv/compare/v6...v7">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=astral-sh/setup-uv&package-manager=github_actions&previous-version=6&new-version=7)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2025-12-18 22:41:25 +00:00
Lunny Xiao 6d0fe5ed39 Front port changelog (#36193)
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: silverwind <me@silverwind.io>
2025-12-18 14:05:49 -08:00
dependabot[bot] dcad5d8879 Bump dev-hanz-ops/install-gh-cli-action from 0.1.0 to 0.2.1 (#36195)
Bumps
[dev-hanz-ops/install-gh-cli-action](https://github.com/dev-hanz-ops/install-gh-cli-action)
from 0.1.0 to 0.2.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/dev-hanz-ops/install-gh-cli-action/releases">dev-hanz-ops/install-gh-cli-action's
releases</a>.</em></p>
<blockquote>
<h2>v0.2.1 - arm64 support</h2>
<ul>
<li>support arm64 architecture - <a
href="https://redirect.github.com/dev-hanz-ops/install-gh-cli-action/pull/10">dev-hanz-ops/install-gh-cli-action#10</a>
(by <a
href="https://github.com/whatthefinemanual"><code>@​whatthefinemanual</code></a>)</li>
</ul>
<h2>v0.2.0 - update to node20</h2>
<ul>
<li><a
href="https://github.com/dev-hanz-ops/install-gh-cli-action/commit/8fff9050dae2d81b38f94500d8b74ad1d1d47410">https://github.com/dev-hanz-ops/install-gh-cli-action/commit/8fff9050dae2d81b38f94500d8b74ad1d1d47410</a>
(update to node20)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/dev-hanz-ops/install-gh-cli-action/commit/af38ce09b1ec248aeb08eea2b16bbecea9e059f8"><code>af38ce0</code></a>
run build</li>
<li><a
href="https://github.com/dev-hanz-ops/install-gh-cli-action/commit/eef2976cedc1da9b4b4eafcdf96655455d55ac73"><code>eef2976</code></a>
feature: Add multi architecture support (<a
href="https://redirect.github.com/dev-hanz-ops/install-gh-cli-action/issues/10">#10</a>)</li>
<li><a
href="https://github.com/dev-hanz-ops/install-gh-cli-action/commit/2d19dc38f3a568abbd2a42dae05be5b83202f332"><code>2d19dc3</code></a>
docs: update recomended action version (<a
href="https://redirect.github.com/dev-hanz-ops/install-gh-cli-action/issues/8">#8</a>)</li>
<li><a
href="https://github.com/dev-hanz-ops/install-gh-cli-action/commit/8fff9050dae2d81b38f94500d8b74ad1d1d47410"><code>8fff905</code></a>
update to node 20</li>
<li><a
href="https://github.com/dev-hanz-ops/install-gh-cli-action/commit/67bfd0539397d168c77ba70eac2647fef7f1f020"><code>67bfd05</code></a>
README: only linux amd64</li>
<li><a
href="https://github.com/dev-hanz-ops/install-gh-cli-action/commit/44745680363a7ba976f907c6d1b697a9fc311cf7"><code>4474568</code></a>
Update readme with working example (<a
href="https://redirect.github.com/dev-hanz-ops/install-gh-cli-action/issues/3">#3</a>)</li>
<li>See full diff in <a
href="https://github.com/dev-hanz-ops/install-gh-cli-action/compare/v0.1.0...v0.2.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dev-hanz-ops/install-gh-cli-action&package-manager=github_actions&previous-version=0.1.0&new-version=0.2.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-18 21:37:06 +00:00
dependabot[bot] 5f5a87f015 Bump aws-actions/configure-aws-credentials from 4 to 5 (#36196)
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

Rebasing might not happen immediately, so don't worry if this takes some
time.

Note: if you make any changes to this PR yourself, they will take
precedence over the rebase.

---

[//]: # (dependabot-end)

Bumps
[aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials)
from 4 to 5.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/aws-actions/configure-aws-credentials/releases">aws-actions/configure-aws-credentials's
releases</a>.</em></p>
<blockquote>
<h2>v5.0.0</h2>
<h2><a
href="https://github.com/aws-actions/configure-aws-credentials/compare/v4.3.1...v5.0.0">5.0.0</a>
(2025-09-03)</h2>
<h3>⚠ BREAKING CHANGES</h3>
<ul>
<li>Cleanup input handling. Changes invalid boolean input behavior (see
<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1445">#1445</a>)</li>
</ul>
<h3>Features</h3>
<ul>
<li>add skip OIDC option (<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1458">#1458</a>)
(<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/8c45f6b08196feb86cfdbe431541d5571d9ab2c2">8c45f6b</a>)</li>
<li>Cleanup input handling. Changes invalid boolean input behavior (see
<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1445">#1445</a>)
(<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/74b3e27aa80db064b5bb8c04b22fc607e817acf7">74b3e27</a>)</li>
<li>support account id allowlist (<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1456">#1456</a>)
(<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/c4be498953fc1da2707a50ce4b761a53af3d02af">c4be498</a>)</li>
</ul>
<h2>v4.3.1</h2>
<h2><a
href="https://github.com/aws-actions/configure-aws-credentials/compare/v4.3.0...v4.3.1">4.3.1</a>
(2025-08-04)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>update readme to 4.3.1 (<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1424">#1424</a>)
(<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/be2e7ad815e27b890489a89ce2717b0f9e26b56e">be2e7ad</a>)</li>
</ul>
<h2>v4.3.0</h2>
<h2><a
href="https://github.com/aws-actions/configure-aws-credentials/compare/v4.3.0...v4.3.0">4.3.0</a>
(2025-08-04)</h2>
<p>NOTE: This release tag originally pointed to
59b441846ad109fa4a1549b73ef4e149c4bfb53b, but a critical bug was
discovered shortly after publishing. We updated this tag to
d0834ad3a60a024346910e522a81b0002bd37fea to prevent anyone using the
4.3.0 tag from encountering the bug, and we published 4.3.1 to allow
workflows to auto update correctly.</p>
<h3>Features</h3>
<ul>
<li>dependency update and feature cleanup (<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1414">#1414</a>)
(<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/59489ba544930000b7b67412c167f5fe816568cf">59489ba</a>),
closes <a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1062">#1062</a>
<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1191">#1191</a></li>
<li>Optional environment variable output (<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/c3b3ce61b02510937ff02916a4eb153874bc5085">c3b3ce6</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>docs:</strong> readme samples versioning (<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/5b3c89504689ea1ea2b6000b23a6a2aac463662a">5b3c895</a>)</li>
<li>the wrong example region for China partition in README (<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/37fe9a740bcb30ee8cccd96feb90666c937311f2">37fe9a7</a>)</li>
<li>properly set proxy environment variable (<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/cbea70821e4ab985ad3be0e5a93390523e257cde">cbea708</a>)</li>
</ul>
<h3>Miscellaneous Chores</h3>
<ul>
<li>release 4.3.0 (<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/3f7c2187213bafaa1ea60a850b27082cbf55dda0">3f7c218</a>)</li>
</ul>
<h2>v4.2.1</h2>
<h2><a
href="https://github.com/aws-actions/configure-aws-credentials/compare/v4.2.0...v4.2.1">4.2.1</a>
(2025-05-14)</h2>
<h3>Bug Fixes</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/aws-actions/configure-aws-credentials/blob/main/CHANGELOG.md">aws-actions/configure-aws-credentials's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/aws-actions/configure-aws-credentials/compare/v5.1.0...v5.1.1">5.1.1</a>
(2025-11-24)</h2>
<h3>Miscellaneous Chores</h3>
<ul>
<li>release 5.1.1 (<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/56d6a583f00f6bad6d19d91d53a7bc3b8143d0e9">56d6a58</a>)</li>
</ul>
<h2><a
href="https://github.com/aws-actions/configure-aws-credentials/compare/v5.0.0...v5.1.0">5.1.0</a>
(2025-10-06)</h2>
<h3>Features</h3>
<ul>
<li>Add global timeout support (<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1487">#1487</a>)
(<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/1584b8b0e2062557287c28fbe9b8920df434e866">1584b8b</a>)</li>
<li>add no-proxy support (<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1482">#1482</a>)
(<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/dde9b22a8e889a0821997a21a2c5a38020ee8de3">dde9b22</a>)</li>
<li>Improve debug logging in retry logic (<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1485">#1485</a>)
(<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/97ef425d73aa532439f54f90d0e83101a186c5a6">97ef425</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>properly expose getProxyForUrl (introduced in <a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1482">#1482</a>)
(<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1486">#1486</a>)
(<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/cea42985ac88b42678fbc84c18066a7f07f05176">cea4298</a>)</li>
</ul>
<h2><a
href="https://github.com/aws-actions/configure-aws-credentials/compare/v4.3.1...v5.0.0">5.0.0</a>
(2025-09-03)</h2>
<h3>⚠ BREAKING CHANGES</h3>
<ul>
<li>Cleanup input handling. Changes invalid boolean input behavior (see
<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1445">#1445</a>)</li>
</ul>
<h3>Features</h3>
<ul>
<li>add skip OIDC option (<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1458">#1458</a>)
(<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/8c45f6b08196feb86cfdbe431541d5571d9ab2c2">8c45f6b</a>)</li>
<li>Cleanup input handling. Changes invalid boolean input behavior (see
<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1445">#1445</a>)
(<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/74b3e27aa80db064b5bb8c04b22fc607e817acf7">74b3e27</a>)</li>
<li>support account id allowlist (<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1456">#1456</a>)
(<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/c4be498953fc1da2707a50ce4b761a53af3d02af">c4be498</a>)</li>
</ul>
<h2><a
href="https://github.com/aws-actions/configure-aws-credentials/compare/v4.3.0...v4.3.1">4.3.1</a>
(2025-08-04)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>update readme to 4.3.1 (<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1424">#1424</a>)
(<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/be2e7ad815e27b890489a89ce2717b0f9e26b56e">be2e7ad</a>)</li>
</ul>
<h2><a
href="https://github.com/aws-actions/configure-aws-credentials/compare/v4.2.1...v4.3.0">4.3.0</a>
(2025-08-04)</h2>
<h3>Features</h3>
<ul>
<li>depenency update and feature cleanup (<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1414">#1414</a>)
(<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/59489ba544930000b7b67412c167f5fe816568cf">59489ba</a>),
closes <a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1062">#1062</a>
<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1191">#1191</a></li>
<li>Optional environment variable output (<a
href="https://github.com/aws-actions/configure-aws-credentials/commit/c3b3ce61b02510937ff02916a4eb153874bc5085">c3b3ce6</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/aws-actions/configure-aws-credentials/commit/61815dcd50bd041e203e49132bacad1fd04d2708"><code>61815dc</code></a>
chore(main): release 5.1.1 (<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1564">#1564</a>)</li>
<li><a
href="https://github.com/aws-actions/configure-aws-credentials/commit/56d6a583f00f6bad6d19d91d53a7bc3b8143d0e9"><code>56d6a58</code></a>
chore: release 5.1.1</li>
<li><a
href="https://github.com/aws-actions/configure-aws-credentials/commit/4a54c24244cf4f82abd7d44e7b2024258a8aa041"><code>4a54c24</code></a>
chore(deps-dev): bump glob from 10.4.5 to 10.5.0 (<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1563">#1563</a>)</li>
<li><a
href="https://github.com/aws-actions/configure-aws-credentials/commit/b2793c943d45120be0c78ffc4b01aa0d2bf23e4b"><code>b2793c9</code></a>
chore(deps-dev): bump <code>@​types/node</code> from 24.10.0 to 24.10.1
(<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1559">#1559</a>)</li>
<li><a
href="https://github.com/aws-actions/configure-aws-credentials/commit/8c230bf21db64d397027b569a312fd242776d171"><code>8c230bf</code></a>
chore: Update dist</li>
<li><a
href="https://github.com/aws-actions/configure-aws-credentials/commit/f7a5b07d5348b1ac9f4d78d7547c96dfdd088440"><code>f7a5b07</code></a>
chore(deps): bump <code>@​aws-sdk/client-sts</code> from 3.928.0 to
3.933.0 (<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1558">#1558</a>)</li>
<li><a
href="https://github.com/aws-actions/configure-aws-credentials/commit/730fc043828321961a659b198613a80b17bf755c"><code>730fc04</code></a>
chore(deps-dev): bump <code>@​biomejs/biome</code> from 2.3.4 to 2.3.6
(<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1555">#1555</a>)</li>
<li><a
href="https://github.com/aws-actions/configure-aws-credentials/commit/bc0dd36aec59e4fbdcedc61cb65d225ee2fa3bb6"><code>bc0dd36</code></a>
chore(deps-dev): bump memfs from 4.50.0 to 4.51.0 (<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1556">#1556</a>)</li>
<li><a
href="https://github.com/aws-actions/configure-aws-credentials/commit/f2964c7281262753f549b15ae39f1cbbb033b9e4"><code>f2964c7</code></a>
chore: Update dist</li>
<li><a
href="https://github.com/aws-actions/configure-aws-credentials/commit/cf464951bec7e2a7af23fa7107563810acd70a4f"><code>cf46495</code></a>
chore(deps): bump <code>@​aws-sdk/client-sts</code> from 3.922.0 to
3.928.0 (<a
href="https://redirect.github.com/aws-actions/configure-aws-credentials/issues/1548">#1548</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/aws-actions/configure-aws-credentials/compare/v4...v5">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=aws-actions/configure-aws-credentials&package-manager=github_actions&previous-version=4&new-version=5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-18 20:59:23 +00:00
dependabot[bot] aca6726607 Bump docker/build-push-action from 5 to 6 (#36197)
Bumps
[docker/build-push-action](https://github.com/docker/build-push-action)
from 5 to 6.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/docker/build-push-action/releases">docker/build-push-action's
releases</a>.</em></p>
<blockquote>
<h2>v6.0.0</h2>
<ul>
<li>Export build record and generate <a
href="https://docs.docker.com/build/ci/github-actions/build-summary/">build
summary</a> by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/build-push-action/pull/1120">docker/build-push-action#1120</a></li>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.24.0 to 0.26.0 in
<a
href="https://redirect.github.com/docker/build-push-action/pull/1132">docker/build-push-action#1132</a>
<a
href="https://redirect.github.com/docker/build-push-action/pull/1136">docker/build-push-action#1136</a>
<a
href="https://redirect.github.com/docker/build-push-action/pull/1138">docker/build-push-action#1138</a></li>
<li>Bump braces from 3.0.2 to 3.0.3 in <a
href="https://redirect.github.com/docker/build-push-action/pull/1137">docker/build-push-action#1137</a></li>
</ul>
<blockquote>
<p>[!NOTE]
This major release adds support for generating <a
href="https://docs.docker.com/build/ci/github-actions/build-summary/">Build
summary</a> and exporting build record for your build. You can disable
this feature by setting <a
href="https://docs.docker.com/build/ci/github-actions/build-summary/#disable-job-summary">
<code>DOCKER_BUILD_SUMMARY: false</code> environment variable in your
workflow</a>.</p>
</blockquote>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/build-push-action/compare/v5.4.0...v6.0.0">https://github.com/docker/build-push-action/compare/v5.4.0...v6.0.0</a></p>
<h2>v5.4.0</h2>
<ul>
<li>Show builder information before building by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/build-push-action/pull/1128">docker/build-push-action#1128</a></li>
<li>Handle attestations correctly with provenance and sbom inputs by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/build-push-action/pull/1086">docker/build-push-action#1086</a></li>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.19.0 to 0.24.0 in
<a
href="https://redirect.github.com/docker/build-push-action/pull/1088">docker/build-push-action#1088</a>
<a
href="https://redirect.github.com/docker/build-push-action/pull/1105">docker/build-push-action#1105</a>
<a
href="https://redirect.github.com/docker/build-push-action/pull/1121">docker/build-push-action#1121</a>
<a
href="https://redirect.github.com/docker/build-push-action/pull/1127">docker/build-push-action#1127</a></li>
<li>Bump undici from 5.28.3 to 5.28.4 in <a
href="https://redirect.github.com/docker/build-push-action/pull/1090">docker/build-push-action#1090</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/build-push-action/compare/v5.3.0...v5.4.0">https://github.com/docker/build-push-action/compare/v5.3.0...v5.4.0</a></p>
<h2>v5.3.0</h2>
<ul>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.18.0 to 0.19.0 in
<a
href="https://redirect.github.com/docker/build-push-action/pull/1080">docker/build-push-action#1080</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/build-push-action/compare/v5.2.0...v5.3.0">https://github.com/docker/build-push-action/compare/v5.2.0...v5.3.0</a></p>
<h2>v5.2.0</h2>
<ul>
<li>Disable quotes detection for <code>outputs</code> input by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/build-push-action/pull/1074">docker/build-push-action#1074</a></li>
<li>Warn about ignored inputs by <a
href="https://github.com/favonia"><code>@​favonia</code></a> in <a
href="https://redirect.github.com/docker/build-push-action/pull/1019">docker/build-push-action#1019</a></li>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.14.0 to 0.18.0 in
<a
href="https://redirect.github.com/docker/build-push-action/pull/1070">docker/build-push-action#1070</a></li>
<li>Bump undici from 5.26.3 to 5.28.3 in <a
href="https://redirect.github.com/docker/build-push-action/pull/1057">docker/build-push-action#1057</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/build-push-action/compare/v5.1.0...v5.2.0">https://github.com/docker/build-push-action/compare/v5.1.0...v5.2.0</a></p>
<h2>v5.1.0</h2>
<ul>
<li>Add <code>annotations</code> input by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/build-push-action/pull/992">docker/build-push-action#992</a></li>
<li>Add <code>secret-envs</code> input by <a
href="https://github.com/elias-lundgren"><code>@​elias-lundgren</code></a>
in <a
href="https://redirect.github.com/docker/build-push-action/pull/980">docker/build-push-action#980</a></li>
<li>Bump <code>@​babel/traverse</code> from 7.17.3 to 7.23.2 in <a
href="https://redirect.github.com/docker/build-push-action/pull/991">docker/build-push-action#991</a></li>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.13.0-rc.1 to
0.14.0 in <a
href="https://redirect.github.com/docker/build-push-action/pull/990">docker/build-push-action#990</a>
<a
href="https://redirect.github.com/docker/build-push-action/pull/1006">docker/build-push-action#1006</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/build-push-action/compare/v5.0.0...v5.1.0">https://github.com/docker/build-push-action/compare/v5.0.0...v5.1.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/docker/build-push-action/commit/263435318d21b8e681c14492fe198d362a7d2c83"><code>2634353</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1381">#1381</a>
from docker/dependabot/npm_and_yarn/docker/actions-t...</li>
<li><a
href="https://github.com/docker/build-push-action/commit/c0432d2e016ab17a336cee48256683e74d5c4c9e"><code>c0432d2</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/build-push-action/commit/0bb1f27d6b9fc90993f41febd9b53ee89397d3f8"><code>0bb1f27</code></a>
set builder driver and endpoint attributes for dbc summary support</li>
<li><a
href="https://github.com/docker/build-push-action/commit/5f9dbf956c8481ecf630d0e53941d9d3afaa53bb"><code>5f9dbf9</code></a>
chore(deps): Bump <code>@​docker/actions-toolkit</code> from 0.61.0 to
0.62.1</li>
<li><a
href="https://github.com/docker/build-push-action/commit/0788c444d8b4d67580213712e34a148cae3a6c4e"><code>0788c44</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1375">#1375</a>
from crazy-max/remove-gcr</li>
<li><a
href="https://github.com/docker/build-push-action/commit/aa179ca4f405fed7a76dad90a23bd02d6f2a8d2d"><code>aa179ca</code></a>
e2e: remove GCR</li>
<li><a
href="https://github.com/docker/build-push-action/commit/1dc73863535b631f98b2378be8619f83b136f4a0"><code>1dc7386</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1364">#1364</a>
from crazy-max/history-export-cmd</li>
<li><a
href="https://github.com/docker/build-push-action/commit/9c9803f36437c54a2bf7b2c9a4a9011c2a812d71"><code>9c9803f</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/build-push-action/commit/db1f6c46e8d64f89ec10010e409681bcf7951c05"><code>db1f6c4</code></a>
DOCKER_BUILD_EXPORT_LEGACY env var to opt-in for legacy export</li>
<li><a
href="https://github.com/docker/build-push-action/commit/721e8c79de660781840d3a69a11e39e1e836ef8e"><code>721e8c7</code></a>
Bump <code>@​docker/actions-toolkit</code> from 0.59.0 to 0.61.0</li>
<li>Additional commits viewable in <a
href="https://github.com/docker/build-push-action/compare/v5...v6">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=docker/build-push-action&package-manager=github_actions&previous-version=5&new-version=6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-18 20:09:24 +00:00
silverwind e0214ab841 Enable dependabot for actions (#36191)
Enable dependabot for actions only. These should always be safe to
update as long as CI passes and some of them are lagging behind.
2025-12-18 20:12:29 +01:00
silverwind b671d507e3 Bump alpine to 3.23 (#36185) 2025-12-18 00:11:59 -05:00
Lunny Xiao 3e566172f5 Use gitRepo as parameter instead of repopath when invoking sign functions (#36162)
Co-authored-by: Giteabot <teabot@gitea.io>
2025-12-17 21:55:08 +00:00
Lunny Xiao efd5dd4f0b Fix bug when creating pull request (#36166)
Extract from #36105 

Fix #36116
Fix #35912
Fix #20906
2025-12-17 21:21:04 +00:00
silverwind 1e22bd712f Bump golangci-lint to 2.7.2, enable modernize stringsbuilder (#36180)
Fixes were done automatically by `make lint-go-fix`. These modernize
fixes are very readable.

Co-authored-by: Giteabot <teabot@gitea.io>
2025-12-17 20:50:53 +00:00
Lunny Xiao ebf9b4dc6b Use a migration test instead of a wrong test which populated the meta test repositories and fix a migration bug (#36160)
The test `TestGiteaUploadUpdateGitForPullRequest` modified the shared
meta test repositories directly, so this PR removes that test and
replaces it with an integration test that migrates a real repository
from gitea.com into a local test instance.

This PR also fixes a bug where pull-request migrations were not
correctly syncing head branches to the database.
2025-12-17 12:00:07 -08:00
silverwind ad49b7bf31 Update JS deps and eslint enhancements (#36147)
- Update all JS deps
- Tested affected `dependencies`
- Replace eslint `unstable_native_nodejs_ts_config` with optional `jiti`
dependency. This will be more compatible with editor integrations that
may not pass this flag.
- Enable additional eslint rules, no new issues
- Move `typescript` to `devDependencies` because `make frontend` works
without it
2025-12-17 17:35:33 +00:00
silverwind 852bf5e2a5 Add git.DIFF_RENAME_SIMILARITY_THRESHOLD option (#36164)
Make the threshold value passed to `git diff --find-renames` configurable
2025-12-17 10:02:32 +00:00
wxiaoguang eaa47c3e09 Fix OrgAssignment opts (#36174)
Fix #36084
2025-12-17 17:19:22 +08:00
Dawid Góra 0e916c67cc Automatic generation of release notes (#35977)
Similar to GitHub, release notes can now be generated automatically.
The generator is server-side and gathers the merged PRs and contributors
and returns the corresponding Markdown text.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-12-17 02:01:19 +00:00
Sebastian Ertz 14911d4293 Update chroma to v2.21.0 (#36171)
https://github.com/alecthomas/chroma/releases/tag/v2.21.0
2025-12-17 01:07:44 +00:00
GiteaBot d19db18ee7 [skip ci] Updated translations via Crowdin 2025-12-17 00:37:08 +00:00
Lunny Xiao 4c67aac23b Move blame to gitrepo (#36161) 2025-12-16 16:14:14 -08:00
silverwind 84b74d7c3e Enable bodyclose linter (#36168)
Enabe
[`bodyclose`](https://golangci-lint.run/docs/linters/configuration/#bodyclose).
The only issue in non-test code (`services/migrations/dump.go`) was a
false-positive and I think there are a number of undetected cases, but I
guess it's still better than not having it.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2025-12-16 14:08:43 +01:00
TheFox0x7 3bb0770160 fix nilnil in onedev downloader (#36154)
onedev migration never used the migration transport, it now uses it the
same way gogs one does

---

cuts 3 nilnils for https://github.com/go-gitea/gitea/issues/36152
2025-12-16 02:16:58 +00:00
a1012112796 822ee60bae fix webAuthn insecure error view (#36165)
as you seen, in cureent status `initUserAuthWebAuthn` will prcheck
`window.isSecureContext`, if not ok, will hide the `passkey` btton and
return directly. I think it's not right, first, not show any error
message looks not a good ui, and it's looks will make an empty container
was show if the registion button was disabled also (maybe f-i-x #36115),
then initUserAuthWebAuthn has `window.isSecureContext` check also which
looks duplcate ref:

https://github.com/go-gitea/gitea/blob/26602fd2070886a1e7e0545f11f5541a38396003/web_src/js/features/user-auth-webauthn.ts#L202-L206

so I'd like move hideElem(elSignInPasskeyBtn); to
`detectWebAuthnSupport` failed routs to make it simple and show insecure
error corectly.

![联想截图_20251215184757](https://github.com/user-attachments/assets/0eff43a0-18a6-4978-aa27-b4574fcf2601)

Signed-off-by: a1012112796 <1012112796@qq.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2025-12-15 21:03:52 +01:00
Lunny Xiao da087270ff Some small refactors (#36163) 2025-12-15 11:55:44 -08:00
Lunny Xiao 26602fd207 Remove undocumented support of signing key in the repository git configuration file (#36143)
Per-repository signing keys have never been officially supported, as
they would require users to modify the repository’s config file.

At this point, it is clear that only global signing keys (GPG or SSH)
should be allowed. If we want to introduce per-repository signing keys
in the future, it will require a complete design proposal.

The endpoint will not be removed for repository special signing key, but
it will reference the global signing key.

---------

Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: delvh <dev.lh@web.de>
2025-12-14 17:34:45 +00:00
silverwind ff70ed6c67 Enable gocheckcompilerdirectives linter (#36156)
Enable
[`gocheckcompilerdirectives`](https://github.com/leighmcculloch/gocheckcompilerdirectives)
to validate compiler directives, no current violation.
2025-12-14 13:35:19 +00:00
wxiaoguang 7190519fb3 Fix code highlighting on blame page (#36157)
1. Full file highlighting (fix the legacy todo "we should instead
highlight the whole file at once")
    * Fix #24383
2. Correctly covert file content encoding
3. Remove dead code, split large for-loop into small functions/blocks to
make code maintainable
2025-12-14 12:40:55 +02:00
Lunny Xiao 1f5237e0d7 Check user visibility when redirecting to a renamed user (#36148)
Fix #34169
2025-12-14 03:14:18 +01:00
Lunny Xiao 29057ea55f Fix bug when viewing the commit diff page with non-ANSI files (#36149)
Fix #35504

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-12-13 21:54:03 +08:00
silverwind ac8308b5cb Refactor FileTreeItem type (#36137) 2025-12-13 13:03:51 +00:00
wxiaoguang 1e72b15639 Fix various bugs (#36139)
* Fix #35768
* Fix #36064
* Fix #36051
* Fix cherry-pick panic
2025-12-12 18:56:05 +00:00
silverwind 3102c04c1e Fix issue close timeline icon (#36138)
Previously there was a icon mismatch between a issue's label and the
timeline close event icon
2025-12-12 18:12:35 +00:00
silverwind 3e57ba5b36 Add permissions tofiles-changed jobs (#36142)
Followup to https://github.com/go-gitea/gitea/pull/36140.
`files-changed` is a job that imports another workflow via `uses`
statement but CodeQL still complains about lack of permissions on these
jobs, so add it. This will fix the remaining [3 CodeQL
issues](https://github.com/go-gitea/gitea/security/code-scanning?query=is%3Aopen+branch%3Amain+permissions).
2025-12-12 18:38:59 +01:00
silverwind 4c06c98dda Add explicit permissions to all actions workflows (#36140)
Explicitely specify all workflow
[`permissions`](https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#permissions).
This will fix [26 CodeQL
alerts](https://github.com/go-gitea/gitea/security/code-scanning?query=permissions+is%3Aopen+branch%3Amain+).
2025-12-12 16:48:29 +00:00
silverwind 87b855bd15 Bump actions/checkout to v6 (#36136)
https://github.com/actions/checkout#checkout-v6

Result of `perl -p -i -e
's#actions\/checkout\@v5#actions/checkout\@v6#g' .github/workflows/*`
2025-12-12 16:44:53 +01:00
Lunny Xiao 906adff0c1 Hide RSS icon when viewing a file not under a branch (#36135)
Fix #35855

Co-authored-by: Giteabot <teabot@gitea.io>
2025-12-12 10:26:15 +01:00
silverwind 4cbcb91b7b Fix SVG size calulation, only use style attribute (#36133)
Fixes: https://github.com/go-gitea/gitea/issues/35863

The old code had a conflict between using HTML attributes vs. style
properties where the style was overriding the previously set HTML
attributes:

```html
<img width="300" height="277.02439470988946" style="width: 275px; height: 0px;">
```

I made it so in all cases only `style` properties are used and the
previous width/height values are now set via `style`. Also I did a
number of much-needed typescript improvements to the file.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-12-12 09:39:02 +02:00
junoberryferry bfbc38f40c Add sorting/filtering to admin user search API endpoint (#36112) 2025-12-12 05:12:06 +01:00
Lunny Xiao d2a372fc59 Move some functions to gitrepo package to reduce RepoPath reference directly (#36126) 2025-12-12 01:15:40 +01:00
wxiaoguang f25409fab8 Make Golang correctly delete temp files during uploading (#36128)
Fix #36127
2025-12-11 19:59:42 +01:00
GiteaBot 01351cc6c7 [skip ci] Updated translations via Crowdin 2025-12-11 00:39:32 +00:00
Lunny Xiao a440116a16 Support updating branch via API (#35951)
Resolve #35368
2025-12-10 19:23:26 +00:00
Lunny Xiao 24b81ac8b9 Use gitrepo's clone and push when possible (#36093)
1 Move `IsRepositoryModelOrDirExist` and `CheckCreateRepository` to
service layer
2 Use `gitrepo.Pushxxx` instead of `git.Push` when possible
3 use `gitrepo.Clonexxx` instead of `gitrepo.Clone` when possible
2025-12-10 09:41:01 -08:00
wxiaoguang 1c69fdccdd Improve math rendering (#36124)
Fix #36108
Fix #36107
2025-12-10 15:49:24 +00:00
silverwind ed698d1a61 Add matching pair insertion to markdown textarea (#36121)
1. Our textarea already has some editor-like feature like tab
indentation, so I thought why not also add insertion of matching closing
quotes/brackets over selected text. This does that.
2. `textareaInsertText` is replaced with `replaceTextareaSelection`
which does the same but create a new edit history entry in the textarea
so CTRL-Z works. The button that inserts tables into the textarea can
now also be reverted via CTRL-Z, which was not possible before.
2025-12-10 07:30:50 +00:00
Ger Schinkel d83a071db9 Changed a small typo in an error message and code comments. (#36117) 2025-12-09 10:14:05 -05:00
Lunny Xiao 69700f9cdd Fix possible bug when migrating issues/pull requests (#33487)
When migrating issues or pull requests from a big repository, some
issue/pull request maybe deleted when migrating. So that there will be
duplicated issues/pull requests because we are get information with
pagination. This PR introduced a map to record all migrated issue pull
request index when migrating to avoid the failure because of duplicated
records.
2025-12-07 23:09:10 -08:00
a1012112796 98ef79d73a allow action user have read permission in public repo like other user (#36095)
related #28187

---------

Signed-off-by: a1012112796 <1012112796@qq.com>
2025-12-07 10:07:04 -08:00
GiteaBot b41ccb0627 [skip ci] Updated translations via Crowdin 2025-12-07 00:42:24 +00:00
silverwind c287a8cdb5 Disable matchBrackets in monaco (#36089)
This one may be a bit opinionated but I prefer my editors to be clean of
distractions and these bracket highlights look too much like a cursor on
quick glance imho.

Before:
<img width="345" height="67" alt="Screenshot 2025-12-04 at 20 26 14"
src="https://github.com/user-attachments/assets/10b2ea19-4468-401b-9425-1caa1b64afe4"
/>

After:
<img width="319" height="69" alt="Screenshot 2025-12-04 at 20 26 25"
src="https://github.com/user-attachments/assets/edbd3291-965d-421f-85cf-8d927b2a323a"
/>
2025-12-05 07:06:13 +00:00
silverwind ca8c4ebecd Update JS deps (#36091)
Result of `make update-js svg && git add --all`. Tested Mermaid.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2025-12-05 06:30:59 +01:00
Bryan Mutai 6675ddc117 fix: Exclude code expansion arrows when DiffBlobExcerptData is not available. (#36060)
Resolves #35994 

Do not render code expansion arrows when `DiffBlobExcerptData` is not
available (code file preview, pull conversation diff comment).

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-12-04 20:07:22 -08:00
silverwind 5fdc84841a Add strikethrough button to markdown editor (#36087)
Fixes: https://github.com/go-gitea/gitea/issues/36086


![strike](https://github.com/user-attachments/assets/984e36db-6fa8-4054-9794-aa54bc642354)
2025-12-05 01:21:24 +00:00
Lunny Xiao 64960a18f9 Move commit related functions to gitrepo package (#35600) 2025-12-05 00:20:23 +00:00
Lunny Xiao cb5082f8fe Fix the bug when ssh clone with redirect user or repository (#36039)
Fix #36026 

The redirect should be checked when original user/repo doesn't exist.
2025-12-04 19:17:49 +00:00
a1012112796 ee365f5100 fix some file icon ui (#36078)
fix #36071

looks that's because if an svg in hiden env, it's color added by
`fill="url(#a)"` will become not usefull. by ai helping, I think moving
it out of page by position is a good solution. fell free creat a new
pull request if you have a better soluton. Thanks.
<img width="2198" height="1120" alt="image"
src="https://github.com/user-attachments/assets/bbf7c171-0b7f-412a-a1bc-aea3f1629636"
/>

---------

Signed-off-by: a1012112796 <1012112796@qq.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-12-04 19:47:23 +01:00
silverwind b49dd8e32f update golangci-lint to v2.7.0 (#36079)
- Update and autofix most issues
- Corrected variable names to `cutOk`
- Impossible condition in `services/migrations/onedev_test.go` removed
- `modules/setting/config_env.go:128:3` looks like a false-positive,
added nolint
2025-12-04 09:06:44 +00:00
Lunny Xiao ee6e371e44 Use Golang net/smtp instead of gomail's smtp to send email (#36055)
Replace #36032
Fix #36030

This PR use `net/smtp` instead of gomail's smtp. Now
github.com/wneessen/go-mail will be used only for generating email
message body.

---------

Co-authored-by: Giteabot <teabot@gitea.io>
2025-12-04 08:35:53 +00:00
Lunny Xiao e30a130b9a Fix edit user email bug in API (#36068)
Follow #36058 for API edit user bug when editing email.

- The Admin Edit User API includes a breaking change. Previously, when
updating a user with an email from an unallowed domain, the request
would succeed but return a warning in the response headers. Now, the
request will fail and return an error in the response body instead.
- Removed `AdminAddOrSetPrimaryEmailAddress` because it will not be used
any where.

Fix https://github.com/go-gitea/gitea/pull/36058#issuecomment-3600005186

---------

Co-authored-by: Giteabot <teabot@gitea.io>
2025-12-04 09:05:13 +01:00
GiteaBot 97cb4409fb [skip ci] Updated translations via Crowdin 2025-12-04 00:38:21 +00:00
silverwind 46d7adefe0 Enable TypeScript strictNullChecks (#35843)
A big step towards enabling strict mode in Typescript.

There was definitely a good share of potential bugs while refactoring
this. When in doubt, I opted to keep the potentially broken behaviour.
Notably, the `DOMEvent` type is gone, it was broken and we're better of
with type assertions on `e.target`.

---------

Signed-off-by: silverwind <me@silverwind.io>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-12-03 02:13:16 +00:00
silverwind 9f268edd2f Update go toolchain to 1.25.5 (#36074)
Fixes: https://pkg.go.dev/vuln/GO-2025-4155
2025-12-03 00:26:07 +01:00
6543 ca4b21c305 Revert "adopt changes" (was intendet for #33356)
This reverts commit a04a16dc2b.
2025-12-02 21:51:00 +01:00
6543 a04a16dc2b adopt changes 2025-12-02 21:37:14 +01:00
GiteaBot 1e777f92c7 [skip ci] Updated translations via Crowdin 2025-12-02 00:38:36 +00:00
Lunny Xiao 5340db4dbe Fix bug when updating user email (#36058)
Fix #20390 

We should use `ReplacePrimaryEmailAddress` instead of
`AdminAddOrSetPrimaryEmailAddress` when modify user's email from admin
panel. And also we need a database transaction to keep deletion and
insertion succeed at the same time.
2025-12-01 23:50:10 +00:00
Bryan Mutai 7d6861ac54 Add "Go to file", "Delete Directory" to repo file list page (#35911)
/claim #35898
Resolves #35898 

### Summary of key changes:

1. Add file name search/Go to file functionality to repo button row.
2. Add backend functionality to delete directory
3. Add context menu for directories with functionality to copy path & delete a directory
4. Move Add/Upload file dropdown to right for parity with Github UI
5. Add tree view to the edit/upload UI

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-11-30 11:58:15 +08:00
silverwind b54af8811e Replace lint-go-gopls with additional govet linters (#36028)
Many (but not all) analyzers ran by `gopls check` are available in
`golangci-lint` as part of default-disabled `govet` linters, so I think
it's best we remove this manual linting step and let `golangci-lint`
handle it. I hand-picked two available linters that were previously
linted using gopls and this list is not exhaustive.

This will reduce CI time by about 3 minutes.
2025-11-29 14:13:22 +00:00
Zettat123 f4e38e6367 Fix Actions pull_request.paths being triggered incorrectly by rebase (#36045)
Partially fix #34710 

The bug described in #34710 can be divided into two parts: `push.paths`
and `pull_request.paths`. This PR fixes the issue related to
`pull_request.paths`. The root cause is that the check for whether the
workflow can be triggered happens **before** updating the PR’s merge
base. This causes the file-change detection to use the old merge base.
Therefore, we need to update the merge base first and then check whether
the workflow can be triggered.
2025-11-28 19:33:52 +00:00
hamkido a36951aef6 Fix error handling in mailer and wiki services (#36041)
- Updated error message in `incoming.go` to remove unnecessary wrapping
of the error.
- Corrected typo in error message in `wiki.go` for clarity.

---------

Co-authored-by: Giteabot <teabot@gitea.io>
2025-11-28 00:36:27 +00:00
silverwind 9668913d76 Update JS deps, fix deprecations (#36040)
- Update JS deps
- Regenerate SVGs
- Fix air `bin` deprecation
- Fix `monaco.languages.typescript` deprecation
- Remove `eslint-plugin-no-use-extend-native`, it's unnecessary with
typescript
- Enable new `@typescript-eslint` rules
- Disable `@typescript-eslint/no-redundant-type-constituents`, this rule
has bugs when not running under `strictNullChecks` (pending in
https://github.com/go-gitea/gitea/pull/35843).
2025-11-27 23:58:10 +00:00
bytedream ede7f1a069 Fix incorrect viewed files counter if file has changed (#36009)
File changes since last review didn't decrease the viewed files counter

---
<img width="440" height="178" alt="image"
src="https://github.com/user-attachments/assets/da34fcf4-452f-4f71-8da2-97edbfc31fdd"
/>

Also reported here ->
https://github.com/go-gitea/gitea/issues/35803#issuecomment-3567850285

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2025-11-27 14:02:03 +00:00
GiteaBot 1816c7f9c1 [skip ci] Updated translations via Crowdin 2025-11-27 00:36:53 +00:00
silverwind 66707bc3ea Fix actions lint (#36029)
actionlint since https://github.com/rhysd/actionlint/releases/tag/v1.7.9
detects constant conditions and this workflow was being disabled in
https://github.com/go-gitea/gitea/commit/58d2a87c6c4431873340cb7c00fa43670d4418aa
by such a condition which made the lint fail:


https://github.com/go-gitea/gitea/actions/runs/19673752806/job/56349128912?pr=36028

Instead, remove the whole workflow file. I'm sure we can re-create it if
the need arises.

Also, I locked the actionlint dependency to prevent similar surprises in
the future.
2025-11-26 10:13:37 -08:00
wxiaoguang 000c06d41b Fix oauth2 session gob register (#36017)
`gob.Register` must be called before Sessioner

Fix #36016
2025-11-26 23:25:34 +08:00
wxiaoguang abe2755f7a Fix container registry error handling (#36021)
1. the `if` check in `handleCreateManifestResult` didn't handler err correctly
2. add more error details for debugging
2025-11-25 12:13:30 +08:00
Andrew Melnick 688430e3ce Allow admins to rename non-local users (#35970)
Presently, attempting to rename a non-local (e.g. Oauth2 or LDAP) user
results in an error, even if the requester is an administrator. As far
as I can tell, this is a security feature, not architectural in nature,
as automatic account linking could be used to take control of another
user's account. This is not a concern for an administrator, who we
should trust to know what they are doing.

This patch allows admins, and only admins, to rename non-local users.

Fixes https://github.com/go-gitea/gitea/issues/18308 (sort of)

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-11-23 20:59:55 +00:00
wxiaoguang 87d5a8507d Add "site admin" back to profile menu (#36010)
Fix #35904
2025-11-23 22:29:58 +02:00
Zettat123 ed977d9702 Use GitHub-style commit message for squash merge (#35987) 2025-11-22 09:20:45 -08:00
Lunny Xiao 62d750eadb Fix various permission & login related bugs (#36002)
Permission & protection check:

- Fix Delete Release permission check
- Fix Update Pull Request with rebase branch protection check
- Fix Issue Dependency permission check
- Fix Delete Comment History ID check

Information leaking:

- Show unified message for non-existing user and invalid password
    - Fix #35984
- Don't expose release draft to non-writer users.
- Make API returns signature's email address instead of the user
profile's.

Auth & Login:

- Avoid GCM OAuth2 attempt when OAuth2 is disabled
    - Fix #35510

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-11-22 07:16:08 +00:00
Lunny Xiao a60a8c6966 Allow empty commit when merging pull request with squash style (#35989)
Before this PR, when merging an empty PR with squash style will result
in 500.

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-11-22 06:02:25 +00:00
GiteaBot 4c51acb26b [skip ci] Updated translations via Crowdin 2025-11-21 00:37:11 +00:00
Sandro Santilli 543e3bf7e9 Mention proc-receive in text for dashboard.resync_all_hooks func (#35991) 2025-11-20 19:27:08 -05:00
silverwind 1baca49870 Update JS deps (#35978)
Update JS deps, regenerate SVGs, fixed lint issues and did cursory
testing of UI.
2025-11-20 21:53:44 +00:00
Gary Wang afc25c5145 wiki: reuse selectable style for wiki (#35990)
This patch amends https://github.com/go-gitea/gitea/pull/27507.

Since https://github.com/go-gitea/gitea/pull/35072, `selectable` css
class can be used for providing hover effect for tables. This patch let
the wiki page be able to make use of that css class, and we can safely
remove the custom css for this purpose.

Behavior is not changed.

----

Side note: I made this patch locally months ago but completely forget to
submit it as a PR 😂
2025-11-20 21:23:14 +00:00
dependabot[bot] 98eb2b0aba Bump golang.org/x/crypto from 0.43.0 to 0.45.0 (#35985)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from
0.43.0 to 0.45.0.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/golang/crypto/commit/4e0068c0098be10d7025c99ab7c50ce454c1f0f9"><code>4e0068c</code></a>
go.mod: update golang.org/x dependencies</li>
<li><a
href="https://github.com/golang/crypto/commit/e79546e28b85ea53dd37afe1c4102746ef553b9c"><code>e79546e</code></a>
ssh: curb GSSAPI DoS risk by limiting number of specified OIDs</li>
<li><a
href="https://github.com/golang/crypto/commit/f91f7a7c31bf90b39c1de895ad116a2bacc88748"><code>f91f7a7</code></a>
ssh/agent: prevent panic on malformed constraint</li>
<li><a
href="https://github.com/golang/crypto/commit/2df4153a0311bdfea44376e0eb6ef2faefb0275b"><code>2df4153</code></a>
acme/autocert: let automatic renewal work with short lifetime certs</li>
<li><a
href="https://github.com/golang/crypto/commit/bcf6a849efcf4702fa5172cb0998b46c3da1e989"><code>bcf6a84</code></a>
acme: pass context to request</li>
<li><a
href="https://github.com/golang/crypto/commit/b4f2b62076abeee4e43fb59544dac565715fbf1e"><code>b4f2b62</code></a>
ssh: fix error message on unsupported cipher</li>
<li><a
href="https://github.com/golang/crypto/commit/79ec3a51fcc7fbd2691d56155d578225ccc542e2"><code>79ec3a5</code></a>
ssh: allow to bind to a hostname in remote forwarding</li>
<li><a
href="https://github.com/golang/crypto/commit/122a78f140d9d3303ed3261bc374bbbca149140f"><code>122a78f</code></a>
go.mod: update golang.org/x dependencies</li>
<li><a
href="https://github.com/golang/crypto/commit/c0531f9c34514ad5c5551e2d6ce569ca673a8afd"><code>c0531f9</code></a>
all: eliminate vet diagnostics</li>
<li><a
href="https://github.com/golang/crypto/commit/0997000b45e3a40598272081bcad03ffd21b8adb"><code>0997000</code></a>
all: fix some comments</li>
<li>Additional commits viewable in <a
href="https://github.com/golang/crypto/compare/v0.43.0...v0.45.0">compare
view</a></li>
</ul>
</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-19 20:10:35 -08:00
GiteaBot adece922f1 [skip ci] Updated translations via Crowdin 2025-11-20 00:36:24 +00:00
silverwind 1da1e644ed Misc CSS fixes (#35888)
Fixes: https://github.com/go-gitea/gitea/issues/35913
Fixes: https://github.com/go-gitea/gitea/issues/35942

Contains a number of minor CSS fixes.

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-11-19 03:02:41 +00:00
wxiaoguang e1372e5bc1 Make composer registry support tar.gz and tar.bz2 and fix bugs (#35958)
Fix #35957
2025-11-18 23:15:50 +00:00
DrMaxNix de69e7f16a Change project default column icon to 'star' (#35967)
Consistently use a `star` icon to highlight the default column of a
project.
The icon is both shown while viewing the project, as well as while
changing the default status of this column.

<img width="1065" height="370" alt="image"
src="https://github.com/user-attachments/assets/1ca5773d-8eec-4b90-ad0b-22b1f4bd4cfd"
/>
2025-11-18 10:55:27 +02:00
wxiaoguang 0fb3be7f0e Fix diff blob excerpt expansion (#35922)
And add comments and tests
2025-11-14 04:50:48 +00:00
Daniel Mach d6dc531d4b Add GITEA_PR_INDEX env variable to githooks (#35938)
`GITEA_PR_ID` is already part of the env variables available in the
githooks, but it contains a database ID instead of commonly used index
that is part of `owner/repo!index`
2025-11-14 04:21:05 +00:00
wxiaoguang 358de23a50 Fix container push tag overwriting (#35936)
Fix #35853
2025-11-14 03:49:57 +00:00
Lunny Xiao 018156079b Upgrade deps golang.org/x/crypto (#35952) 2025-11-14 03:19:51 +00:00
wxiaoguang 1f3558b65c Fix corrupted external render content (#35946)
Fix #35944
2025-11-14 08:31:11 +08:00
wxiaoguang b95fd7e13e Don't show unnecessary error message to end users for DeleteBranchAfterMerge (#35937) 2025-11-13 07:03:13 +08:00
wxiaoguang 372d24b84b Limit reading bytes instead of ReadAll (#35928) 2025-11-12 19:44:49 +08:00
鲁汀 2223be2cc4 Support blue yellow colorblind theme (#35910)
This icon is from GitHub:

<img width="350" height="350" alt="image"
src="https://github.com/user-attachments/assets/c3f31901-5359-4b7f-ae68-eddcec63df53"
/>

---------

Signed-off-by: 鲁汀 <131967983+lutinglt@users.noreply.github.com>
Co-authored-by: lutinglt <lutinglt@users.noreply.github.com>
2025-11-11 18:21:15 +00:00
wxiaoguang 9affb513a8 Load jQuery as early as possible to support custom scripts (#35926)
Fix #35923
2025-11-12 00:11:46 +08:00
wxiaoguang e31f224ad2 Make OAuth2 issuer configurable (#35915)
The new (correct) behavior breaks the old (incorrect) logins.

Add a config option to support legacy "issuer".

Fix #35830
2025-11-10 23:45:01 +08:00
lifegpc 1c8c56503f Allow to display embed images/pdfs when SERVE_DIRECT was enabled on MinIO storage (#35882)
Releated issue: https://github.com/go-gitea/gitea/issues/30487

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-11-09 21:31:25 -08:00
Mithilesh Gupta 60314cb688 Add proper page title for project pages (#35773)
Fix #35763

Co-authored-by: Mithilesh Gupta <guptamithilesh@protonmail.com>
2025-11-09 21:54:34 +00:00
Alberty Pascal c4c4cf5687 Use correct form field for allowed force push users in branch protection API (#35894)
Test was wrong and preventing update of force push allow users list by
the API

Resolves #35893

Signed-off-by: Alberty Pascal <github@albertyorban.be>
2025-11-09 21:23:46 +00:00
wxiaoguang 050c9485df Fix team member access check (#35899)
Fix #35499
2025-11-09 03:13:31 +00:00
techknowlogick 919348665b Add ability for local makefile with personal customizations that wouldnt affect remote repo (#35836)
This would allow developers to keep a local file that'd add personal
makefile targets for niche convenience customization without having to
have the git workspace polluted with uncommitted changes.

---------

Signed-off-by: techknowlogick <techknowlogick@gitea.com>
2025-11-08 20:23:55 +00:00
silverwind c12bc4aa30 Add toolchain directive to go.mod (#35901)
From [docs](https://go.dev/doc/toolchain#config):

> The go line declares the minimum required Go version for using the
module or workspace. For compatibility reasons, if the go line is
omitted from a go.mod file, the module is considered to have an implicit
go 1.16 line, and if the go line is omitted from a go.work file, the
workspace is considered to have an implicit go 1.18 line.

> The toolchain line declares a suggested toolchain to use with the
module or workspace. As described in “[Go toolchain
selection](https://go.dev/doc/toolchain#select)” below, the go command
may run this specific toolchain when operating in that module or
workspace if the default toolchain’s version is less than the suggested
toolchain’s version. If the toolchain line is omitted, the module or
workspace is considered to have an implicit toolchain goV line, where V
is the Go version from the go line.

This is better than setting `go` to the latest version which may break
builds when that go version is unavailable, for example with
`GOTOOLCHAIN=local` in the official go docker images.
2025-11-08 19:48:16 +00:00
鲁汀 367a289b29 Display source code downloads last for release attachments (#35897) 2025-11-08 16:08:59 +00:00
Luohao Wang bfaddbcd0d Fix conda null depend issue (#35900)
Fix #35895
2025-11-08 23:29:17 +08:00
wxiaoguang 0ce7d66368 Fix avatar upload error handling (#35887)
Fix #35884
2025-11-07 09:44:09 +08:00
silverwind b2feeddf42 Move gitea-vet to use go tool (#35878)
Add it as a [tool
dependency](https://go.dev/doc/modules/managing-dependencies#tools),
eliminating the need for `build.go`.
2025-11-06 21:09:31 +01:00
silverwind eef9406c6b Contribution heatmap improvements (#35876)
1. Set a fixed height on the element, preventing the content after the
element from shifting on page load. This uses CSS [container query
length
units](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_containment/Container_queries#container_query_length_units)
as I saw no other way because of the non-linear scaling of the element.
2. Move the "total-contributions" text into the existing vue slot,
eliminating the need for absolute positioning.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-11-06 09:23:48 +01:00
silverwind aaa8033ee9 Update to go 1.25.4 (#35877)
https://tip.golang.org/doc/devel/release#go1.25.4
2025-11-06 07:04:38 +01:00
silverwind 23a37b4b77 Remove padding override on .ui .sha.label (#35864)
Since upgrading to v1.25, I noticed the SHA labels have slightly
different padding than before. I can't pinpoint exactly which change it
was. Fix it by removing the padding override on `.ui .sha.label` and
make the one on`.ui.label` (`2px 6px`) take effect which matches 1.24
rendering.

Before:

<img width="135" height="172" alt="image"
src="https://github.com/user-attachments/assets/2781a854-be08-4a11-bde0-d3699b2b7454"
/>

After:

<img width="139" height="162" alt="image"
src="https://github.com/user-attachments/assets/5c864fa3-c1f9-4452-ae58-5411dd445865"
/>
2025-11-06 01:32:39 +00:00
Divyun Raje Vaid 61e5cc173e fix(api/repo/contents): set the dates to now when not specified by the caller (#35861)
Since 1.25.0, the dates get set to `2001-01-01T00:00:00Z`, when not
specified by the caller.

Fixes #35860

Co-authored-by: Giteabot <teabot@gitea.io>
2025-11-05 18:52:24 +00:00
silverwind 84d7496b9d Remove fix Make targets (#35868)
Since `modernize` is now included in `golangci-lint` since
https://github.com/go-gitea/gitea/commit/850012bf5c0807908771d3cb155afaebf2742cc8,
it makes not sense to have this as a separate make target anymore.
2025-11-05 18:20:20 +00:00
wxiaoguang 525265c1a8 Refactor ls-tree and git path related problems (#35858)
Fix #35852, the root problem is that the "name" field is heavily abused
(since #6816, and no way to get a clear fix)

There are still a lot of legacy problems in old code.

Co-authored-by: Giteabot <teabot@gitea.io>
2025-11-05 17:48:38 +00:00
silverwind d0ca2f6bc3 Fix pull description code label background (#35865)
Fix visual regression from https://github.com/go-gitea/gitea/pull/35567:

Before:

<img width="612" height="33" alt="image"
src="https://github.com/user-attachments/assets/aee4017c-b8b9-4ac2-9809-9d3eb3fda56c"
/>

After:

<img width="613" height="32" alt="image"
src="https://github.com/user-attachments/assets/ee6624da-b417-4e3b-8773-88c77c2cd672"
/>
2025-11-05 19:18:26 +02:00
wxiaoguang a0f492d9f4 Make ACME email optional (#35849)
Fix a regression from #33668

Fix #35847
2025-11-04 18:17:50 +00:00
Lunny Xiao 206f4c88b1 Remove wrong code (#35846)
Follow #35821
Fix https://github.com/go-gitea/gitea/pull/35844#issuecomment-3483521045

The reviewed file numbers and progress have been set from backend so
that we don't need to update the numbers when clicking `load more`.
2025-11-04 17:46:17 +00:00
Cory Sanin 851db77256 Fix Arch repo pacman.conf snippet (#35825)
Current template uses the owner followed by the instance URL as the repo
name. Technically this can work if the repo happens to be named the
exact same way. But if, for example, you follow [the
docs](https://docs.gitea.com/usage/packages/arch/#publish-a-package),
you'll end up with a package in `core` while the pacman conf refers to a
non-existent repo `testuser.gitea.example.com`. Whatever is in the
square brackets get substituted in for `$repo`, so we do not want
anything except the exact repo name there.

And since it's now referring to the repo and not the owner, I've updated
the pacman conf to show all repositories.

---------

Co-authored-by: Giteabot <teabot@gitea.io>
2025-11-04 18:07:04 +01:00
Naxdy 2be51d0b27 Port away from flake-utils (#35675)
`flake-utils` is currently only used for outputting system-specific dev
shells. This can actually be achieved only using functionality already
present within `nixpkgs`, thus there is no need for an extra dependency.

Additionally, we move to use the `packages` and `env` args for `mkShell`
to more clearly outline what they are used for.

---

Further reading:
https://determinate.systems/blog/best-practices-for-nix-at-work/#avoid-flake-helper-libraries-if-possible

As a side note, using `with` to import large scopes is [discouraged by
official Nix
resources](https://nix.dev/guides/best-practices#with-scopes), so an
alternative approach to list installed packages could be something like
this:

```nix
packages =
  (builtins.attrValues {
    inherit (pkgs)
      # generic
      git
      git-lfs
      gnumake
      gnused
      gnutar
      gzip
      zip

      # frontend
      cairo
      pixman
      pkg-config

      # linting
      uv

      # backend
      gofumpt
      sqlite
      ;

    inherit
      # frontend
      nodejs
      pnpm

      # linting
      python3

      # backend
      go
      ;
  })
  ++ linuxOnlyInputs;
```

But I saw this as too pedantic to include in the initial PR.

Co-authored-by: 6543 <6543@obermui.de>
2025-11-04 16:28:59 +00:00
silverwind 850012bf5c Update golangci-lint to v2.6.0 (#35801)
https://github.com/golangci/golangci-lint/releases/tag/v2.6.0

- `modernize` linter is enabled, this is the same as `gopls modernize`
- ~~`perfsprint` linter is disabled because it conflicts with
`modernize` (maybe there is a middle ground)~~
- gocritic `deprecatedComment` is disabled as it conflicts with
`go-swagger`
2025-11-04 03:03:06 +00:00
Zettat123 bb1f52347a Add a doctor command to fix inconsistent run status (#35840)
#35783 fixes an actions rerun bug. Due to this bug, some runs may be
incorrectly marked as `StatusWaiting` even though all the jobs are in
done status. These runs cannot be run or cancelled. This PR adds a new
doctor command to fix the inconsistent run status.

```
gitea doctor check --run fix-actions-unfinished-run-status --fix
```

Thanks to @ChristopherHX  for the test.
2025-11-04 03:32:26 +01:00
Lunny Xiao de26c8acce Fix viewed files number is not right if not all files loaded (#35821)
Fix #35803

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: silverwind <me@silverwind.io>
2025-11-03 13:34:52 -08:00
Lunny Xiao d9c0f86de8 Fix incorrect pull request counter (#35819)
Fix #35781, #27472

The PR will not correct the wrong numbers automatically. 

There is a cron task `check_repo_stats` which will be run when Gitea
start or midnight. It will correct the numbers.
2025-11-03 20:52:13 +00:00
silverwind 37208fef7e Fix a number of strictNullChecks-related issues (#35795)
In preparation to work on enabling
https://www.typescriptlang.org/tsconfig/#strictNullChecks, I fixed all
the issues outside of `web_src` that came up when the option was
enabled. There was also one lint issue in web_src that apparently only
came up with the option enabled, so I fixed that as well.

`isTruthy` is introduced because Typescript has a bug regarding
`filter(Boolean)` which they are seemingly unwilling to fix.

---------

Signed-off-by: silverwind <me@silverwind.io>
2025-11-03 20:17:06 +00:00
techknowlogick aa7ec64a54 ignore .worktrees as a "special folder" (#35835)
following the approach from nixpkgs that ignore the .worktrees folder,
we could also do the same, this would allow worktrees to be worked on in
the same folder as the primary branch.

ref:
https://github.com/NixOS/nixpkgs/commit/b6420c7bca86997ad66218dcf4fb902efc7ac4f6
2025-11-03 20:57:30 +01:00
Lunny Xiao 17a6a2bab1 upgrade go mail to 0.7.2 and fix the bug (#35833)
patch from
https://github.com/wneessen/go-mail/issues/504#issuecomment-3477890515.
Thanks to @wneessen
2025-11-03 11:32:45 -08:00
TheFox0x7 685c8c314f Add cache to container build (#35697)
add mount cache directives to container builds, which speeds up local
builds bypassing node and go package download entirely on second build
and caching go compilation.
drop job level split on regular/rootless, which allows to reuse the
previously made stage for rootless, skipping duplicate builds in CI.

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2025-11-02 09:42:25 +00:00
Lunny Xiao 5cb453c01b Revert gomail to v0.7.0 to fix sending mail failed (#35816)
Revert gomail to the last work version to fix #35794

There is a problem between go mail v0.7.1 to prevent sending email work.
https://github.com/wneessen/go-mail/compare/v0.7.0...v0.7.1
2025-11-02 09:07:32 +00:00
鲁汀 f2d7931b70 Fix circular spin animation direction (#35785)
Wait for the status icon to rotate clockwise instead of counterclockwise

before:
![GIF 2025-10-30
10-50-07](https://github.com/user-attachments/assets/3771b0bf-44e4-45a0-bde5-1b2b3dd8ba2a)

after:
![GIF 2025-10-30
10-50-43](https://github.com/user-attachments/assets/c45307fe-39a4-4e60-b48e-9d922c407565)

---------

Signed-off-by: 鲁汀 <131967983+lutinglt@users.noreply.github.com>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: lutinglt <lutinglt@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-11-02 08:30:13 +00:00
Lunny Xiao b3e5b96111 Fix clone mixed bug (#35810)
Fix #35807
2025-11-02 00:52:59 -07:00
GiteaBot 1dac4d13f3 [skip ci] Updated translations via Crowdin 2025-11-02 00:39:27 +00:00
Lunny Xiao b148bef471 Remove unnecessary function parameter (#35765) 2025-10-31 21:56:08 -07:00
wxiaoguang de70cd3853 Fix cli "Before" handling (#35797)
Regression of #34973

Fix #35796
2025-10-31 18:12:03 +00:00
Mithilesh Gupta ef90befef1 Add test for ExtendCommentTreePathLength migration and fix bugs (#35791)
Co-authored-by: Mithilesh Gupta <guptamithilesh@protonmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-31 08:49:26 +08:00
silverwind c3472dd395 Fix file extension on gogs.png (#35793)
During https://github.com/go-gitea/gitea/issues/35790, it was noticed
that this PNG image had the wrong file extension. I also verified
`dingtalk.ico` and that one is actually an `.ico`.
2025-10-30 18:25:53 +01:00
silverwind 8b290b87e9 Improve and fix markup code preview rendering (#35777)
1. Add the color on the link to the referenced file, which is the more
likely thing the user wants to click
2. Use monospace font on the SHA
3. Tweak text colors
4. Change SHA link to go to the commit instead of the repo root with
commit filter set
5. Added the repo name to the file link text
6. Fix broken line numbering rendering
2025-10-30 05:15:42 +00:00
Zettat123 3ab8ae5807 Fix actions rerun bug (#35783)
Related issues: #35780, #35782 

Rerunning a job or a run is only allowed when the job is done and the
run is done.

Related PR: #34970
2025-10-30 01:08:59 +00:00
GiteaBot 73e229eb42 [skip ci] Updated translations via Crowdin 2025-10-30 00:37:08 +00:00
techknowlogick 98ff7d0773 add pnpm to Snapcraft (#35778) 2025-10-29 19:34:40 +01:00
Zettat123 8aa1179ce4 Fix actions schedule update issue (#35767)
Fix #34472

Add integration tests for actions schedule update.
2025-10-29 16:04:40 +00:00
bytedream 39c08ce4c1 Update tab title when navigating file tree (#35757)
Fix #35749.

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2025-10-29 13:38:09 +00:00
silverwind fe25997157 Enable vue/require-typed-ref eslint rule (#35764)
Enable https://eslint.vuejs.org/rules/require-typed-ref 
and fix discovered issues.
2025-10-29 17:42:06 +08:00
Lunny Xiao 95b18eb781 Remove unnecessary code and fix comments (#35761)
Follow #35459, #32562

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-28 18:03:57 +00:00
silverwind d69eede59b Update JS dependencies (#35759)
- Update all JS dependencies
- Added new unicorn rules
- `updates` now also supports updating `packageManager` and `engines`,
and I see no reason not to do that, so I think we can try keeping these
updated as well. If something in the build breaks because of this, I
will revert and exclude `pnpm` from updating further, but as far as I
understand, only corepack respects this field and pnpm itself does not
care about it.
- Regenerate SVGs.
2025-10-28 17:32:11 +00:00
silverwind 91839ca01a Move codeformat folder to tools (#35758)
Followup to https://github.com/go-gitea/gitea/pull/35734.

- Move `codeformat` folder to `tools`
- Add `tools` to `GO_DIRS`
- Move `misspellings.csv` to `assets` so we can lint the whole `tools`
directory without filter shenanigans.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-28 11:23:50 +00:00
wxiaoguang 6b5563c54a Support selecting theme on the footer (#35741)
Fixes: https://github.com/go-gitea/gitea/pull/27576
2025-10-28 18:25:00 +08:00
wxiaoguang cddff73bbd Fix "ref-issue" handling in markup (#35739)
This is a follow up for #35662, and also fix #31181, help #30275, fix #31161
2025-10-27 22:45:07 +08:00
GiteaBot 87d670c96b [skip ci] Updated translations via Crowdin 2025-10-27 00:39:11 +00:00
wxiaoguang 2f309b844c Revert #18491, fix oauth2 client link account (#35745)
Fix #35744 by reverting #18491

* "OpenID" options don't mean "OAuth2Client" options
* "OAuth2(server)" options don't mean "OAuth2Client" options
2025-10-26 21:26:38 +00:00
Lunny Xiao bc50431e8b Upgrade go mail to 0.7.2 (#35748) 2025-10-26 09:52:01 -04:00
GiteaBot 2a6af15448 [skip ci] Updated translations via Crowdin 2025-10-26 00:38:59 +00:00
Zettat123 c9beb0b01f Support actions and reusable workflows from private repos (#32562)
Resolve https://gitea.com/gitea/act_runner/issues/102

This PR allows administrators of a private repository to specify some
collaborative owners. The repositories of collaborative owners will be
allowed to access this repository's actions and workflows.

Settings for private repos:


![image](https://github.com/user-attachments/assets/e591c877-f94d-48fb-82f3-3b051f21557e)

---

This PR also moves "Enable Actions" setting to `Actions > General` page

<img width="960" alt="image"
src="https://github.com/user-attachments/assets/49337ec2-afb1-4a67-8516-5c9ef0ce05d4"
/>

<img width="960" alt="image"
src="https://github.com/user-attachments/assets/f58ee6d5-17f9-4180-8760-a78e859f1c37"
/>

---------

Signed-off-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: ChristopherHX <christopher.homberger@web.de>
2025-10-25 17:37:33 +00:00
Lunny Xiao 5454fdacd4 Use git model to detect whether branch exist instead of gitrepo method (#35459) 2025-10-25 10:08:25 -07:00
Lunny Xiao 304d836a61 Fix shutdown waitgroup panic (#35676)
This PR fixes a panic issue in the WaitGroup that occurs when Gitea is
shut down using Ctrl+C.
It ensures that all active connection pointers in the server are
properly tracked and forcibly closed when the hammer shutdown is
invoked.
The process remains graceful — the normal shutdown sequence runs before
the hammer is triggered, and existing connections are given a timeout
period to complete gracefully.

This PR also fixes `no logger writer` problem. Now the log close will
only be invoked when the command exit.

- Fixes #35468
- Fixes #35551
- Fixes #35559
- Replace #35578

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-25 00:02:58 -07:00
wxiaoguang cb72c901b3 Intorduce "config edit-ini" sub command to help maintaining INI config file (#35735)
Ref: #32669. Helps addressing
https://gitea.com/gitea/helm-chart/issues/356.
2025-10-25 10:54:55 +08:00
Zettat123 0d740a6a72 Improve online runner check (#35722)
This PR moves "no online runner" warning to the runs list. 

A job's `runs-on` may contain expressions like `runs-on: [self-hosted,
"${{ inputs.chosen-os }}"]` so the value of `runs-on` may be different
in each run. We cannot check it through the workflow file.

<details>
  <summary>Screenshots</summary>

Before:

<img width="960" alt="3d2a91746271d8b1f12c8f7d20eba550"
src="https://github.com/user-attachments/assets/7a972c50-db97-49d2-b12b-c1a439732a11"
/>

After:

<img width="960" alt="image"
src="https://github.com/user-attachments/assets/fc076e0e-bd08-4afe-99b9-c0eb0fd2c7e7"
/>
</details>

This PR also splits `prepareWorkflowDispatchTemplate` function into 2
functions:
- `prepareWorkflowTemplate` get and check all of the workflows
- `prepareWorkflowDispatchTemplate` only prepare workflow dispatch
config for `workflow_dispatch` workflows.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-24 12:02:52 -07:00
wxiaoguang 9a73a1fb83 Make "update file" API can create a new file when SHA is not set (#35738)
Fix #19008, use GitHub's behavior (empty SHA to create a new file)
2025-10-24 12:46:54 +08:00
Lunny Xiao 397d666432 Fix review request webhook bug (#35339) (#35723)
Frontport #35339
Fix #35327
2025-10-23 20:08:21 -07:00
silverwind e03a68c48b Misc tool tweaks (#35734)
Some minor tooling tweaks:

- Ignore .venv in golangci-lint
- Move go tools to tools directory (e.g. everything that is not "build")
- Enable reportUnusedInlineConfigs in eslint, no current violations
- Apply modernize fix in code-batch-process, modernize cli did
apparently not catch it because of the `go:build ignore` tag.
2025-10-23 09:07:39 +00:00
silverwind cab35ff17a Update dependencies (#35733)
- Update all JS, Python and Makefile dependencies
- Fixed two new go lint issues
- Tested the affected JS dependencies.
2025-10-23 08:35:48 +00:00
wxiaoguang 522c466e24 Make external iframe render work (#35730)
Fix #35729, #17635, #21098
2025-10-23 08:01:38 +00:00
silverwind 8085c75356 Remove mermaid margin workaround (#35732)
https://github.com/mermaid-js/mermaid/issues/4907 was fixed with mermaid
v11, so we no longer need to ship this workaround. The test case works
as expected:

<img width="244" height="58" alt="image"
src="https://github.com/user-attachments/assets/439616e9-4883-47fb-bf18-21ca86cb5da6"
/>
2025-10-23 06:43:52 +02:00
wxiaoguang 195fc715ff Fix external render (#35727)
Fix #35725

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-22 23:41:38 +00:00
ChristopherHX 08b9776970 Refactor Actions Token Access (#35688)
* use a single function to do Action Tokens Permission checks
* allows easier customization
* add basic tests
* lfs file locks should work now

---------

Signed-off-by: ChristopherHX <christopher.homberger@web.de>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-22 11:12:31 +00:00
Kemal Zebari a9f2ea720b Honor delete branch on merge repo setting when using merge API (#35488)
Fix #35463.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-22 05:06:56 +00:00
wxiaoguang 5f0697243c Don't block site admin's operation if SECRET_KEY is lost (#35721)
Related: #24573
2025-10-22 12:35:56 +08:00
GiteaBot c28aab6714 [skip ci] Updated translations via Crowdin 2025-10-22 00:36:55 +00:00
a1012112796 a4e23b81d3 fix attachment file size limit in server backend (#35519)
fix #35512

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-21 15:07:11 +00:00
wxiaoguang 3917d27467 Make restricted users can access public repositories (#35693)
Fix #35690

Change the "restricted user" behavior introduced by #6274. Now
restricted user can also access public repositories when sign-in is not
required.

For required sign-in, the behavior isn't changed.
2025-10-21 15:30:24 +08:00
wxiaoguang a2eea2fb2e Fix various trivial problems (#35714) 2025-10-21 13:19:29 +08:00
wxiaoguang b2ee5be52e Refactor legacy code (#35708)
And by the way, remove the legacy TODO, split large functions into small
ones, and add more tests
2025-10-20 11:43:08 -07:00
Zettat123 897e48dde3 Add quick approve button on PR page (#35678)
This PR adds a quick approve button on PR page to allow reviewers to
approve all pending checks. Only users with write permission to the 
Actions unit can approve.

---------

Signed-off-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-20 18:46:37 +08:00
wxiaoguang 66ee8f3553 Avoid emoji mismatch and allow to only enable chosen emojis (#35692)
Fix #23635
2025-10-19 13:06:45 -07:00
Bryan Mutai c30d74d0f9 feat(diff): Enable commenting on expanded lines in PR diffs (#35662)
Fixes #32257 
/claim #32257

Implemented commenting on unchanged lines in Pull Request diffs, lines
are accessed by expanding the diff preview. Comments also appear in the
"Files Changed" tab on the unchanged lines where they were placed.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-19 18:19:12 +08:00
wxiaoguang 2d36a0c9ff Fix various bugs (#35684)
1. Fix incorrect column in `applySubscribedCondition`, add a test
2. Fix debian version parsing, add more tests fix #35695
3. Fix log level for HTTP errors, fix #35651
4. Fix abused "panic" handler in API `Migrate`
5. Fix the redirection from PR to issue, add a test
6. Fix Actions variable & secret name validation, add more tests
    * envNameCIRegexMatch is unnecessary, removed
    * validating in "delete" function doesn't make sense, removed
7. Fix incorrect link in release email

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: delvh <dev.lh@web.de>
2025-10-19 00:37:50 +08:00
ChristopherHX 322cb048e7 Fix workflow run event status while rerunning a failed job (#35689)
The event reported a completion status instead of requested, therefore
sent an email
2025-10-18 03:31:34 +00:00
Lunny Xiao a7eceb57a9 Use gitrepo.Repository instead of wikipath (#35398)
Now the wikipath will not be referenced directly.
2025-10-17 20:00:44 -07:00
GiteaBot ebd88af075 [skip ci] Updated translations via Crowdin 2025-10-17 00:34:59 +00:00
silverwind 5bf7cf788d Bump actions/labeler to v6 (#35681)
https://github.com/actions/labeler/releases/tag/v6.0.0
2025-10-16 19:00:41 +02:00
Surya Purohit bf8ecf7c93 Use LFS object size instead of blob size when viewing a LFS file (#35679)
shows the main LFS filesize instead of the pointer filesize when viewing
a file

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-16 17:42:54 +08:00
dependabot[bot] 990201dc93 Bump happy-dom from 20.0.0 to 20.0.2 (#35677)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-15 19:07:40 -04:00
wxiaoguang c55a017225 Fix missing Close when error occurs and abused connection pool (#35658)
Fix #35649

* Use upstream `git-lfs-transfer`
* The Close should be called when error occurs (bug fix)
* The connection pool should be shared (bug fix)
* Add more tests to cover "LFS over SSH download"
2025-10-15 09:47:12 +00:00
Lunny Xiao 1bdb0b71b1 Upgrade to go 1.25.3 (#35656) 2025-10-15 10:09:32 +02:00
wxiaoguang 9ae2e9e76f Always create Actions logs stepsContainer (#35654) 2025-10-15 04:07:58 +00:00
Lunny Xiao 16fc3323b9 Fix a bug missed return (#35655) 2025-10-14 20:12:07 -07:00
Lunny Xiao 731d803d19 Creating push comments before invoke pull request checking (#35647)
This PR moved the creation of pushing comments before pull request
mergeable checking. So that when the pull request status changed, the
comments should have been created.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-14 19:19:27 +00:00
silverwind 96102c69e7 Bump setup-go to v6 (#35660) 2025-10-14 14:28:05 -04:00
GiteaBot 22b92e30ca [skip ci] Updated translations via Crowdin 2025-10-13 00:37:21 +00:00
silverwind 49a0a11f55 Update JS deps, misc tweaks (#35643)
- Update all JS dependencies
- Enable eslint `no-useless-assignment` and fix 2 discovered issues
- Replace `gitea-vscode` svg with new `octicon-vscode`
- Remove now-unused `@ts-expect-error` comments
- Change Monaco wrapping behaviour to match the wrapping in code view:
no wrapping indent and break on any character.
2025-10-12 21:07:15 +00:00
silverwind 912515e63a Bump actions/checkout to v5 (#35644) 2025-10-12 18:01:42 +00:00
techknowlogick f9a4b2753c nix flake update (#35639) 2025-10-12 15:59:00 +00:00
ChristopherHX 2401812b76 Cleanup ActionRun creation (#35624)
Closes #35622

---------

Signed-off-by: ChristopherHX <christopher.homberger@web.de>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-12 12:23:37 +00:00
techknowlogick 3d264ba636 bump archives&rar dep (#35637) 2025-10-12 05:48:19 +02:00
Lunny Xiao 662a44d924 Fix merge panic (#35606)
To prevent potential bugs, the logic in #35543 makes `gitcmd.Command`
panic when attempting to override stdout or stderr. Instead of using
`PrepareCmd`, this PR now uses the WithXXX methods directly to avoid the
panic.

Fix #35603
2025-10-12 04:24:00 +02:00
dependabot[bot] 24a595c3fc Bump happy-dom from 19.0.2 to 20.0.0 (#35625) 2025-10-12 01:52:03 +00:00
ChristopherHX 25c4eb1659 Refactor ActionRunJob parsing into a reusable function (#35623)
Use a helper method around the jobparser for parsing a single job
structure from an ActionRunJob

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-11 12:58:36 -07:00
鲁汀 b029ad431b Fix code tag style problem and LFS view bug (#35628)
Fix #35567

---------

Signed-off-by: 鲁汀 <131967983+lutinglt@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-12 02:38:42 +08:00
Zettat123 40f71bcd4c Support Actions concurrency syntax (#32751)
Fix #24769
Fix #32662
Fix #33260

Depends on https://gitea.com/gitea/act/pulls/124

-
https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#concurrency

## ⚠️ BREAKING ⚠️

This PR removes the auto-cancellation feature added by #25716. Users
need to manually add `concurrency` to workflows to control concurrent
workflows or jobs.

---------

Signed-off-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: Christopher Homberger <christopher.homberger@web.de>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-10 18:58:55 +00:00
鲁汀 327d0a7fdd The status icon of the Action step is consistent with GitHub (#35618)
Before:
running:
<img width="45" height="34" alt="image"
src="https://github.com/user-attachments/assets/e2508f98-2f1f-4b7e-a80c-30b406f42531"
/>
waiting:
<img width="44" height="33" alt="image"
src="https://github.com/user-attachments/assets/e7c8164e-fdc3-4546-b088-31166544edb0"
/>

---
After:
running:
<img width="49" height="43" alt="image"
src="https://github.com/user-attachments/assets/b5a9b245-a995-458a-af23-d1723daa3692"
/>
waiting:
<img width="42" height="44" alt="image"
src="https://github.com/user-attachments/assets/ff72551e-cfb5-4665-af52-938ef0cf8f1c"
/>

`gitea-running.svg` is not an icon from the @ primer/octicon library,
extracted from the Github page. Github did not assign a clear class name
to this icon

---------

Signed-off-by: 鲁汀 <131967983+lutinglt@users.noreply.github.com>
Co-authored-by: lutinglt <lutinglt@users.noreply.github.com>
2025-10-10 11:25:03 -07:00
silverwind 165a3ead52 Mock external service in hcaptcha TestCaptcha (#35604)
The test calls out to a web service which may be down or unreachable as
seen in the linked issue. It's better for tests to not have such
external dependencies to make them absolutely stable.

Fixes: https://github.com/go-gitea/gitea/issues/35571
2025-10-10 06:21:45 +02:00
Lunny Xiao 9f664ab330 Fix inputing review comment will remove reviewer (#35591)
Fix #34617
2025-10-09 19:55:14 -07:00
GiteaBot 94d99c9c3c [skip ci] Updated translations via Crowdin 2025-10-10 00:34:09 +00:00
Surya Purohit b8e5e2a93e Fix diffpatch API endpoint (#35610)
Fix the swagger documentation for the `diffpatch` API endpoint,
and fix the wrong API path caused by a refactoring change.

Closes #35602

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-10 00:39:14 +08:00
da Kai 0bc129481d Print PR-Title into tooltip for actions (#35579)
This PR updates the tooltip for Pull-Request triggered runs to show the
PR title instead of the PR number.

---
I dont remember PR numbers, so having the title in the tooltip makes it
much easier to recognize the right one 😊

Current
<img width="290" height="88" alt="Screenshot 2025-10-03 231547"
src="https://github.com/user-attachments/assets/dd8d264d-933f-4fb1-a945-82b172f95861"
/>

After
<img width="301" height="91" alt="Screenshot 2025-10-03 224628"
src="https://github.com/user-attachments/assets/74c9809a-c09a-4804-bb27-79058a99238b"
/>

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-09 10:01:47 +02:00
shashank-netapp 03fce8f3d0 Fixing issue #35530: Password Leak in Log Messages (#35584)
The Gitea codebase was logging `Elasticsearch` and `Meilisearch`
connection strings directly to log files without sanitizing them. Since
connection strings often contain credentials in the format
`protocol://username:password@host:port`, this resulted in passwords
being exposed in plain text in log output.

Fix:
- wrapped all instances of setting.Indexer.RepoConnStr and
setting.Indexer.IssueConnStr with the `util.SanitizeCredentialURLs()`
function before logging them.

Fixes: #35530

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2025-10-07 09:26:47 -07:00
Lunny Xiao 69f5ee970c Move some functions to gitrepo package (#35543)
Refactor Git command functions to use WithXXX methods instead of
exposing RunOpts.
This change simplifies reuse across gitrepo and improves consistency,
encapsulation, and maintainability of command options.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-07 17:06:51 +08:00
Rob Gonnella c9e7fde8b3 feat: adds option to force update new branch in contents routes (#35592)
Allows users to specify a "force" option in API /contents routes when
modifying files in a new branch. When "force" is true, and the branch
already exists, a force push will occur provided the branch does not
have a branch protection rule that disables force pushing.

This is useful as a way to manage a branch remotely through only the
API. For example in an automated release tool you can pull commits,
analyze, and update a release PR branch all remotely without needing to
clone or perform any local git operations.

Resolve #35538

---------

Co-authored-by: Rob Gonnella <rob.gonnella@papayapay.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-06 21:23:14 -07:00
Lunny Xiao ad2ff67343 Move archive function to repo_model and gitrepo (#35514) 2025-10-06 15:01:26 -07:00
Zettat123 cdc0733047 Use inputs context when parsing workflows (#35590)
Depends on [gitea/act#143](https://gitea.com/gitea/act/pulls/143)

The [`inputs`
context](https://docs.github.com/en/actions/reference/workflows-and-actions/contexts#inputs-context)
is used when parsing workflows so that `run-name` like `run-name: Deploy
to ${{ inputs.deploy_target }}` can be parsed correctly.
2025-10-06 06:09:27 +02:00
Shafi Ahmed 0a0baeb3b0 fix: auto-expand and auto-scroll for actions logs (#35570) (#35583)
Implements reliable auto-expand and auto-scroll behavior for the Actions
logs view.

* Expands running or unfinished steps automatically.
* Smoothly scrolls to the latest log line during execution.
* Controlled via existing “Always auto-scroll” and “Expand running
steps” options.

Fixes #35570.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-05 10:31:06 +08:00
GiteaBot 851d8f9f7c [skip ci] Updated translations via Crowdin 2025-10-05 00:38:21 +00:00
GiteaBot 4e7a97dea0 [skip ci] Updated translations via Crowdin 2025-10-04 00:32:04 +00:00
Lunny Xiao e1c2fef593 Fix creating pull request failure when the target branch name is the same as some tag (#35552)
Use full reference name in the git command to avoid ambiguity.

Fix #35470
2025-10-03 22:54:37 +00:00
silverwind 6589326e96 Use bundled version of spectral (#35573)
To reduce the risk of npm supply chain attacks and to speed up
dependency installation, I've
[bundled](https://github.com/silverwind/spectral-cli-bundle) the
spectral package into a zero-dependency module. The upstream package is
pretty dead currently, so I expect to keep up with their updates.

The package
[exports](https://github.com/silverwind/spectral-cli-bundle/blob/de05948c53a0a6f9690cdf65d35c3fc3324a583c/package.json#L9)
a `spectral` bin script, so `pnpm exec spectral` continues to work
as-is.

In total, this removes 86 dependencies from the npm dependency tree.
2025-10-03 22:25:09 +00:00
Lunny Xiao 17c8aa6587 Add rebase push display wrong comments bug (#35560)
Fix #35518

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-03 15:16:17 -07:00
wxiaoguang 71360a94cb Address some CodeQL security concerns (#35572)
Although there is no real security problem
2025-10-04 01:21:26 +08:00
Kausthubh J Rao c4532101a4 fix(webhook): prevent tag events from bypassing branch filters targets #35449 (#35567)
Tag creation/deletion was triggering push webhooks even when branch
filters were configured, causing unintended pipeline executions.

This change modifies the branch filter logic to check the full ref
name directly instead of first determining if it's a "branch" event.

Fixes: Tag events now properly respect branch filters
- Add getPayloadRef() function to extract full ref names
- Update PrepareWebhook() to use direct ref matching
- Prevents refs/tags/* from matching refs/heads/* filters

Closes #35449

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2025-10-03 08:51:57 +02:00
Aleksandr Denisovich efc48c36ff Added button to copy file name in PR files (#35509)
The merge request file viewer has a button for copying the file path,
but it is not always convenient. Often, you only want to copy the file
name, which is currently not possible. This change request adds this
capability.

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: a.kiselev <a.kiselev@reglab.ru>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-10-02 18:08:11 +00:00
silverwind 340aed3982 Update JS and PY deps (#35565)
Updated all dependencies and did a quick test of the UI.
2025-10-02 08:45:56 +02:00
silverwind b907b9fb1a Enable a few more tsconfig options (#35553)
Enable a few more useful options in tsconfig. `noImplicitReturns` had
two cases which I've fixed. Also, partially sort the file.
2025-09-30 21:43:41 -07:00
dependabot[bot] c5d74e5869 Bump github.com/wneessen/go-mail from 0.6.2 to 0.7.1 (#35557) 2025-10-01 00:14:53 +00:00
Steven Noonan c5332fdc55 add more routes to the "expensive" list (#35547)
Signed-off-by: Steven Noonan <steven@uplinklabs.net>
2025-09-29 17:33:28 +08:00
wxiaoguang 0f668145e9 Drop json-iterator dependency (#35544) 2025-09-28 22:30:28 +08:00
6543 fbe80e6df2 Add proper error message if session provider can not be created (#35520)
the middleware that creates the session provider just panics if on
creation the config is wrong.
this is not catched and so you just get an cryptic stacktrace with no
point where to look at (as user).

## Before

```
2025/09/16 03:56:37 ...xer/stats/indexer.go:87:populateRepoIndexer() [I] Done (re)populating the repo stats indexer with existing repositories
2025/09/16 03:56:37 modules/ssh/ssh.go:387:Listen() [I] Adding SSH host key: /var/lib/gitea/data/ssh/gitea.rsa
2025/09/16 03:56:37 modules/ssh/init.go:26:Init() [I] SSH server started on :1234. Cipher list ([chacha20-poly1305@openssh.com aes128-ctr aes192-ctr aes256-ctr aes128-gcm@openssh.com aes256-gcm@openssh.com]), key exchange algorithms ([curve25519-sha256 ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521 diffie-hellman-group14-sha256 diffie-hellman-group14-sha1]), MACs ([hmac-sha2-256-etm@openssh.com hmac-sha2-256 hmac-sha1])
2025/09/16 03:56:37 ...s/graceful/server.go:50:NewServer() [I] Starting new SSH server: tcp::1234 on PID: 83337
2025/09/16 03:56:38 cmd/web.go:231:func1() [F] PANIC: dial tcp 127.0.0.1:6379: connect: connection refused
gitea.com/go-chi/session@v0.0.0-20240316035857-16768d98ec96/session.go:239 (0x1cdb908)
code.gitea.io/gitea/routers/common/middleware.go:108 (0x2547f5a)
code.gitea.io/gitea/routers/web/web.go:270 (0x278b8e9)
code.gitea.io/gitea/routers/init.go:185 (0x2850d89)
code.gitea.io/gitea/cmd/web.go:211 (0x295c5ad)
code.gitea.io/gitea/cmd/web.go:262 (0x295cacb)
code.gitea.io/gitea/cmd/main.go:111 (0x2953422)
github.com/urfave/cli/v2@v2.27.2/command.go:276 (0x1cc3dfd)
github.com/urfave/cli/v2@v2.27.2/command.go:269 (0x1cc4084)
github.com/urfave/cli/v2@v2.27.2/app.go:333 (0x1cc086a)
github.com/urfave/cli/v2@v2.27.2/app.go:307 (0x2953f18)
code.gitea.io/gitea/cmd/main.go:172 (0x2953efc)
code.gitea.io/gitea/main.go:46 (0x2998498)
runtime/proc.go:283 (0x4471ca)
runtime/asm_amd64.s:1700 (0x484a20)
```

## After

```
2025/09/22 22:52:35 .../templates/htmlrenderer.go:118:initHTMLRenderer() [D] Creating static HTML Renderer
2025/09/22 22:52:35 routers/web/web.go:273:Routes() [F] common.Sessioner failed: failed to create session middleware: dial tcp 127.0.0.1:6379: connect: connection refused
```

---------

Signed-off-by: 6543 <6543@obermui.de>
2025-09-28 12:24:19 +00:00
junoberryferry 151ef80e28 use experimental go json v2 library (#35392)
details: https://pkg.go.dev/encoding/json/v2

---------

Co-authored-by: techknowlogick <matti@mdranta.net>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-09-28 08:03:36 +00:00
Lunny Xiao 8106d95577 Use global lock instead of status pool for cron lock (#35507) 2025-09-27 10:11:52 -07:00
Lunny Xiao 1f32170060 Move some functions to gitrepo package (#35503) 2025-09-26 10:14:20 -07:00
Lunny Xiao 7bf2972379 Move GetDiverging functions to gitrepo (#35524)
Extracted from #35469

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-09-26 15:15:42 +00:00
GiteaBot 8ad2a538da [skip ci] Updated translations via Crowdin 2025-09-26 00:34:11 +00:00
Fabien Benetou 53dfbbb2ee Update issue.go with labels documentation (labels content, not ids) (#35522)
For https://github.com/go-gitea/gitea/issues/35521

---------

Signed-off-by: Fabien Benetou <fabien-services@benetou.fr>
2025-09-25 16:56:49 +00:00
wxiaoguang d83676c97a Fix markup init after issue comment editing (#35536)
Fix #35533
2025-09-25 09:29:32 -07:00
2300 changed files with 196398 additions and 136936 deletions
+358
View File
@@ -0,0 +1,358 @@
.
./types.d.ts
./docker
./docker/manifest.rootless.tmpl
./docker/root
./docker/manifest.tmpl
./docker/README.md
./docker/rootless
./BSDmakefile
./tests
./tests/integration
./tests/gitea-lfs-meta
./tests/mysql.ini.tmpl
./tests/e2e
./tests/testdata
./tests/fuzz
./tests/test_utils.go
./tests/sqlite.ini.tmpl
./tests/gitea-repositories-meta
./tests/pgsql.ini.tmpl
./tests/mssql.ini.tmpl
./eslint.json.config.ts
./LICENSE
./models
./models/repo.go
./models/avatars
./models/system
./models/auth
./models/migrations
./models/pull
./models/main_test.go
./models/fixtures
./models/asymkey
./models/packages
./models/unittest
./models/admin
./models/repo
./models/activities
./models/unit
./models/db
./models/dbfs
./models/shared
./models/webhook
./models/secret
./models/perm
./models/user
./models/renderhelper
./models/actions
./models/git
./models/organization
./models/issues
./models/repo_test.go
./models/project
./eslint.config.ts
./flake.lock
./tools
./tools/generate-svg-vscode-extensions.json
./tools/test-e2e.sh
./tools/code-batch-process.go
./tools/gocovmerge.go
./tools/lint-templates-svg.ts
./tools/generate-images.ts
./tools/codeformat
./tools/generate-svg.ts
./tools/test-echo.go
./tools/watch.sh
./vitest.config.ts
./CHANGELOG.md
./+x
./CODE_OF_CONDUCT.md
./CLAUDE.md
./README.zh-tw.md
./web_src
./web_src/svg
./web_src/fomantic
./web_src/js
./web_src/css
./CHANGELOG-archived.md
./custom
./custom/conf
./contrib
./contrib/systemd
./contrib/init
./contrib/update_dependencies.sh
./contrib/fhs-compliant-script
./contrib/launchd
./contrib/backport
./contrib/README
./contrib/legal
./contrib/supervisor
./contrib/options
./contrib/upgrade.sh
./contrib/ide
./contrib/gitea-monitoring-mixin
./templates
./templates/package
./templates/post-install.tmpl
./templates/status
./templates/devtest
./templates/projects
./templates/base
./templates/org
./templates/swagger
./templates/custom
./templates/admin
./templates/repo
./templates/shared
./templates/webhook
./templates/api
./templates/home.tmpl
./templates/install.tmpl
./templates/user
./templates/explore
./templates/mail
./update-gitea.sh
./flake.nix
./DCO
./MAINTAINERS
./routers
./routers/common
./routers/install
./routers/web
./routers/private
./routers/init.go
./routers/api
./routers/utils
./pnpm
./package.json
./snap
./snap/snapcraft.yaml
./services
./services/uinotification
./services/convert
./services/secrets
./services/wiki
./services/auth
./services/migrations
./services/pull
./services/projects
./services/repository
./services/markup
./services/oauth2_provider
./services/asymkey
./services/org
./services/task
./services/packages
./services/mailer
./services/forms
./services/issue
./services/webtheme
./services/attachment
./services/mirror
./services/versioned_migration
./services/agit
./services/context
./services/release
./services/doctor
./services/gitdiff
./services/webhook
./services/automerge
./services/contexttest
./services/cron
./services/user
./services/automergequeue
./services/feed
./services/actions
./services/git
./services/lfs
./services/notify
./services/indexer
./services/externalaccount
./go.mod
./assets
./assets/misspellings.csv
./assets/logo.svg
./assets/emoji.json
./assets/go-licenses.json
./assets/favicon.svg
./smart-build.sh
./Dockerfile.rootless
./build
./build/generate-go-licenses.go
./build/update-locales.sh
./build/generate-emoji.go
./build/generate-bindata.go
./build/generate-gitignores.go
./build/test-env-check.sh
./build/test-env-prepare.sh
./pyproject.toml
./updates.config.ts
./tsconfig.json
./pnpm-lock.yaml
./crowdin.yml
./SECURITY.md
./options
./options/locale
./options/gitignore
./options/fileicon
./options/label
./options/license
./options/readme
./docs
./docs/guideline-frontend.md
./docs/release-management.md
./docs/guideline-backend.md
./docs/community-governance.md
./playwright.config.ts
./cmd
./cmd/manager_logging.go
./cmd/admin_auth_ldap_test.go
./cmd/web_acme.go
./cmd/admin_user_delete.go
./cmd/admin_user_must_change_password_test.go
./cmd/admin_user_create.go
./cmd/admin_regenerate.go
./cmd/generate.go
./cmd/admin_auth.go
./cmd/dump.go
./cmd/admin_user_must_change_password.go
./cmd/doctor_test.go
./cmd/migrate.go
./cmd/admin_auth_oauth.go
./cmd/main_test.go
./cmd/actions.go
./cmd/cmd_test.go
./cmd/cert_test.go
./cmd/migrate_storage_test.go
./cmd/web_graceful.go
./cmd/doctor.go
./cmd/admin_user_delete_test.go
./cmd/embedded.go
./cmd/manager.go
./cmd/config.go
./cmd/admin_user_change_password.go
./cmd/cert.go
./cmd/hook_test.go
./cmd/web.go
./cmd/hook.go
./cmd/admin_auth_ldap.go
./cmd/admin_user_list.go
./cmd/admin_user_change_password_test.go
./cmd/admin_auth_smtp_test.go
./cmd/web_https.go
./cmd/docs.go
./cmd/admin_user_create_test.go
./cmd/migrate_storage.go
./cmd/admin_auth_oauth_test.go
./cmd/serv.go
./cmd/admin_user_generate_access_token.go
./cmd/admin.go
./cmd/config_test.go
./cmd/doctor_convert.go
./cmd/main.go
./cmd/dump_repo.go
./cmd/keys.go
./cmd/admin_user.go
./cmd/admin_auth_smtp.go
./cmd/restore_repo.go
./cmd/mailer.go
./cmd/cmd.go
./AGENTS.md
./README.zh-cn.md
./Dockerfile
./tailwind.config.ts
./Makefile
./README.md
./main.go
./go.sum
./uv.lock
./stylelint.config.js
./CONTRIBUTING.md
./modules
./modules/reqctx
./modules/public
./modules/references
./modules/httplib
./modules/hcaptcha
./modules/generate
./modules/tailmsg
./modules/turnstile
./modules/system
./modules/badge
./modules/eventsource
./modules/htmlutil
./modules/setting
./modules/fileicon
./modules/auth
./modules/migration
./modules/svg
./modules/repository
./modules/markup
./modules/typesniffer
./modules/test
./modules/web
./modules/pprof
./modules/validation
./modules/base
./modules/tempdir
./modules/zstd
./modules/gitrepo
./modules/packages
./modules/testlogger
./modules/process
./modules/templates
./modules/label
./modules/issue
./modules/dump
./modules/metrics
./modules/assetfs
./modules/nosql
./modules/avatar
./modules/updatechecker
./modules/private
./modules/cache
./modules/regexplru
./modules/gtprof
./modules/log
./modules/commitstatus
./modules/session
./modules/highlight
./modules/csv
./modules/proxy
./modules/queue
./modules/uri
./modules/httpcache
./modules/lfstransfer
./modules/options
./modules/webhook
./modules/secret
./modules/json
./modules/globallock
./modules/emoji
./modules/charset
./modules/recaptcha
./modules/user
./modules/paginator
./modules/proxyprotocol
./modules/actions
./modules/optional
./modules/structs
./modules/ssh
./modules/timeutil
./modules/glob
./modules/git
./modules/lfs
./modules/mcaptcha
./modules/util
./modules/sitemap
./modules/graceful
./modules/storage
./modules/cachegroup
./modules/hostmatcher
./modules/container
./modules/translation
./modules/indexer
./modules/analyze
./vite.config.ts
./main_timezones.go
+1 -1
View File
@@ -4,7 +4,7 @@ tmp_dir = ".air"
[build]
pre_cmd = ["killall -9 gitea 2>/dev/null || true"] # kill off potential zombie processes from previous runs
cmd = "make --no-print-directory backend"
bin = "gitea"
entrypoint = ["./gitea"]
delay = 2000
include_ext = ["go", "tmpl"]
include_file = ["main.go"]
+64
View File
@@ -0,0 +1,64 @@
# Gitea Codex Context
This file is Codex's persistent operating context for this repository.
Related orientation documents:
- Full project change log: `./.codex-history.md`
- Persistent implementation map: `./.codex-project-map.md`
- Raw structural baseline: `./.ai-structure.md`
## Recommended Read Order
1. `./.codex-context.md`
2. `./.codex-project-map.md`
3. The concrete files involved in the current task
4. `./.codex-history.md` only through targeted search, tags, or the latest relevant entries
## High-Value Project Anchors
- App entry point and default version wiring: `main.go`
- Web command and server startup: `cmd/web.go`
- Installed-instance initialization and route mounting: `routers/init.go`
- Main web router: `routers/web/web.go`
- Authentication handlers: `routers/web/auth/`
- Request context, session, template data, and response helpers: `services/context/`
- Domain business logic: `services/`
- Persistence, DB infrastructure, and migrations: `models/`, `models/db/`, `models/migrations/`
- Server-side UI templates: `templates/`
- Browser-side JS/CSS/frontend: `web_src/`
For detailed request flow, auth flow, extension points, and task-oriented entry points, use `./.codex-project-map.md` instead of duplicating them here.
## Persistent Workflow Rules
- Update `./.codex-history.md` after real project code changes.
- Do not add Codex-only preference or memory edits to `./.codex-history.md`.
- Do not reread unchanged context files within the same session unless the current task explicitly depends on them.
- Prefer targeted search in `./.codex-history.md` by keyword, tag, or subsystem before reading larger ranges.
- When the user asks for `revert`:
- first show the latest 10 commits as a numbered list with short descriptions;
- wait for the user's numeric choice before doing anything;
- if the target change is not committed, explain that the safe path is `git restore`, not `git revert`.
- Revert flows must stay non-destructive by default; prefer `git revert` for committed changes and avoid destructive reset-style actions unless the user explicitly asks for them.
## Persistent `.codex-history.md` Rules
- Numeric IDs are reserved only for real project code changes.
- IDs start at `0` and increase sequentially by `1`.
- Use the format `N - [YYYY-MM-DD HH:MM:SS]`.
- Store the real repository-derived application version, without a `Version:` label.
- Keep only the final consolidated result of a task; do not keep intermediate attempts or failed correction steps.
- Append to the same task only while the changes are consecutive follow-ups to the same problem.
- If unrelated tasks happened in between, record the new work as a new task even if it returns to the same area.
## Persistent Communication Preferences
- After finishing a task, respond briefly and directly unless there are blockers or problems.
- Re-check the rules in this file before and after making changes.
## Current Working Notes
- `main.go` defaults `setting.AppVer` to `development`; derive the real build/version string from the repository when writing `./.codex-history.md`.
- The repository is predictably split across `cmd/`, `routers/`, `services/`, `models/`, `templates/`, and `web_src/`, so changes should normally stay localized to one or two layers plus their tests.
- For custom release maintenance and repo-sync tasks, consult `./.codex-script-notes.md` before reanalyzing the large helper scripts.
- New UI-visible functionality in this fork often also requires locale updates, so UI tasks and related history searches should usually consider `options/locale/`, especially `locale_en-US.json` and any actively maintained translated locale files.
+812
View File
@@ -0,0 +1,812 @@
Project Change ID[date-time] - application-version - Type - Summary:
History search guidance:
- Prefer targeted search by task tag, subsystem keyword, or file/path before reading long ranges.
- Entries are tagged inline as `[tag] [tag]` to support targeted search and filtering.
0 - [2026-04-16 02:46:18] - v.1.27.0-dev-38-g4b334df6d4 - Type: Modified - [repo-ui] [visibility] [badges] Added explicit repository visibility badges to match the requested GitHub-style presentation more closely.
- 1 - I modified `templates/repo/header.tmpl` so the repository page header now always shows a visibility badge on the right side: `Private`, `Internal`, or `Public`.
- 2 - I modified `templates/shared/repo/list.tmpl` so each repository entry in shared repository lists also shows an explicit visibility badge for `Private`, `Internal`, or `Public`.
- 3 - I added the `Public` label for repositories that previously had no explicit visibility badge, while preserving the existing archived, template, and sha256 labels.
- 4 - I reused existing translation keys and existing badge styling so the change stays visually consistent with the current Gitea UI.
1 - [2026-04-16 03:31:29] - v.1.27.0-dev-38-g4b334df6d4 - Type: Modified - [repo-ui] [visibility] [badges] [repo-settings] Refined repository visibility badges with semantic colors, owner-aware navigation, and broader coverage in repository settings views.
- 1 - I modified `templates/shared/repo/list.tmpl` so `Public` now uses a basic green badge and `Private` now uses a basic red badge, while `Internal` remains neutral.
- 2 - I modified `templates/repo/header.tmpl` so the repository header uses the same color-coded visibility badges and keeps the mobile icon behavior unchanged.
- 3 - I added owner-aware navigation for the `Public` and `Private` badges so they link to the repository `Settings` page only when the signed-in user is the repository owner.
- 4 - I modified `templates/user/settings/repos.tmpl` so the same visibility badge now appears next to repository names in `/user/settings/repos`, in both list variants rendered by that page.
- 5 - I preserved the existing archived, template, fork, mirror, and object-format indicators so only the requested visibility presentation changed.
2 - [2026-04-16 03:45:08] - v.1.27.0-dev-38-g4b334df6d4 - Type: Fixed - [user-settings] Corrected a template rendering error in /user/settings/repos caused by dereferencing a missing Owner object.
- 1 - I fixed `templates/user/settings/repos.tmpl` so the internal-visibility check now guards against a nil `Owner` before accessing `Owner.Visibility`.
- 2 - I applied the null-safe visibility guard in both repository list variants rendered by `/user/settings/repos`.
- 3 - I preserved the new green/red visibility badge styling and owner-aware settings links while removing the nil-pointer render failure.
3 - [2026-04-16 04:53:24] - v.1.27.0-dev-38-g4b334df6d4 - Type: Modified - [admin-users] Hid the admin privilege toggle when an administrator edits their own account from the admin user edit page.
- 1 - I modified `templates/admin/user/edit.tmpl` so the `Is Administrator` checkbox is no longer rendered when the edited user ID matches the signed-in admin ID.
- 2 - I preserved the existing checkbox behavior for editing other users, so administrators can still grant or revoke admin rights for other accounts.
- 3 - I kept the change limited to the admin edit UI without altering unrelated fields or backend update logic.
4 - [2026-04-16 03:11:08] - v.1.27.0-dev-38-g4b334df6d4 - Type: Modified - [admin-users] [account-deletion] Disabled the self-account deletion option only for the last administrator and aligned the backend rule with that behavior.
- 1 - I modified `templates/user/settings/account.tmpl` so the `Delete Your Account` action is disabled and shows the last-admin warning when the signed-in user is the only remaining admin.
- 2 - I modified `routers/web/user/setting/account.go` so the account settings page now receives an `IsLastAdminUser` flag used by the template.
- 3 - I updated the self-delete backend flow so it blocks account deletion only when the signed-in user is the last admin, instead of blocking every admin unconditionally.
5 - [2026-04-16 03:26:40] - v.1.27.0-dev-38-g4b334df6d4 - Type: Fixed - [admin-users] [account-deletion] Adjusted the shared last-admin detection to count only active administrators so account deletion and admin demotion rules behave correctly in real instances.
- 1 - I modified `models/user/user.go` so `IsLastAdminUser` now treats only active admins as candidates when deciding whether a user is the last admin.
- 2 - This aligns the shared last-admin protection used by account deletion and admin privilege update flows with practical instance behavior.
- 3 - The existing `/user/settings/account` UI and backend guards now work against the refined active-admin definition without additional template changes.
6 - [2026-04-16 03:43:20] - v.1.27.0-dev-38-g4b334df6d4 - Type: Modified - [user-settings] [admin-users] [account-deletion] [ui] Updated the Delete Your Account panel for the last-admin case so it shows a direct warning message and hides the deletion controls.
- 1 - I modified `templates/user/settings/account.tmpl` so the panel now shows `You cannot remove the last admin. There must be at least one admin.` while keeping the existing alert icon.
- 2 - I hid the `Password` field for the last-admin case.
- 3 - I hid the `Confirm Deletion` button for the last-admin case while preserving the normal delete flow for other users.
7 - [2026-04-16 17:37:53] - v.1.27.0-dev-40-gc3b9d21472 - Type: Added - [auth] [account-requests] [mailer] [locale] [en] Added administrator notifications for pending account requests and delayed the user activation email until manual approval.
- 1 - I added a new `email_notification.new_account_requests` user setting in `models/user/setting_options.go`, with an admin-default enabled preference and helper functions to read the preference consistently.
- 2 - I modified `routers/web/user/setting/notifications.go`, `routers/web/web.go`, and `templates/user/settings/notifications.tmpl` so administrators now get a `New account request notifications` checkbox in `/user/settings/notifications`, and the last active admin cannot disable it.
- 3 - I modified `routers/web/auth/auth.go`, `services/mailer/mail_user.go`, `templates/mail/user/auth/new_account_request.tmpl`, and `options/locale/locale_en-US.json` so manual account requests now send notification emails to opted-in active admins with a direct review link.
- 4 - I modified `routers/web/admin/users.go` so when an administrator activates a manually approved account while registration email confirmation is disabled, the applicant receives the standard account activation email at that approval moment.
8 - [2026-04-16 18:59:58] - v.1.27.0-dev-41-g97eee0a9a8 - Type: Fixed - [account-requests] [locale] [en] Corrected the new account request notification rule so at least one active administrator must remain subscribed.
- 1 - I modified `models/user/setting_options.go` to count active administrators who still have new account request notifications enabled and to detect when the current admin is the last enabled recipient.
- 2 - I modified `routers/web/user/setting/notifications.go` so the backend now blocks disabling the preference only when the signed-in admin is the last enabled notification recipient, instead of checking whether they are merely the last admin user.
- 3 - I modified `templates/user/settings/notifications.tmpl` so the checkbox and submit button are disabled only for the last enabled notification recipient.
- 4 - I updated `options/locale/locale_en-US.json` so the warning message now states the real rule clearly: at least one admin must keep these notifications enabled.
9 - [2026-04-16 20:53:32] - v.1.27.0-dev-41-g97eee0a9a8 - Type: Added - [account-requests] Added automatic notification fallback when deleting the only admin who still receives new account request notifications.
- 1 - I added `ShouldEnableNewAccountRequestNotificationsFallback` in `models/user/setting_options.go` so the code can detect when the deleted user is the last active admin with this notification enabled and the acting admin is currently unsubscribed.
- 2 - I modified `routers/web/admin/users.go` so, after a successful admin-driven user deletion, the acting admin is automatically subscribed to new account request notifications when they deleted the last subscribed admin.
- 3 - I modified `routers/api/v1/admin/user.go` so the same automatic fallback also applies to admin deletions performed through the API, keeping the behavior consistent across both deletion entry points.
10 - [2026-04-16 23:02:55] - v.1.27.0-dev-42-g81727dd3e9 - Type: Added - [account-requests] [mailer] [locale] [en] Implemented a staged new account request workflow with email validation, admin review, request statuses, and automatic expiry cleanup.
- 1 - I added `models/user/account_request.go` to store and manage account request states, validation expiry, retry counting, approval or rejection metadata, validation code generation, and expired pending-request cleanup.
- 2 - I modified `routers/web/auth/auth.go`, added `routers/web/auth/account_request.go`, and updated `templates/user/auth/signup_inner.tmpl` so registration now creates pending account requests, resends validation mail when appropriate, blocks repeated unconfirmed attempts after five tries, and moves validated requests into administrator review instead of activating them immediately.
- 3 - I modified `routers/web/admin/users.go`, added `routers/web/admin/account_request.go`, updated `routers/web/web.go`, and updated `templates/admin/user/edit.tmpl` so administrators can see the account request status for a user and explicitly activate, reject, or unblock requests from the admin user edit page.
- 4 - I modified `services/mailer/mail_user.go`, added the new account request mail templates, updated `options/locale/locale_en-US.json`, and modified `services/user/user.go` with `services/cron/tasks_extended.go` so the workflow now sends dedicated validation, approval, and rejection emails, preserves rejected or blocked accounts from inactive-user cleanup, and automatically deletes only expired requests that never completed email validation.
11 - [2026-04-16 23:18:45] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [account-requests] [locale] [en] Added the missing admin dashboard translation entries for the expired account request cleanup cron task.
- 1 - I modified `options/locale/locale_en-US.json` to add `admin.dashboard.delete_expired_account_requests` so the new cron task can be rendered correctly in the admin dashboard task list.
- 2 - I added `admin.dashboard.delete_expired_account_requests.started` alongside it so the matching task start message is also available and the cron task follows the same translation pattern as the existing dashboard tasks.
- 3 - I verified the locale file remains valid JSON after the change.
12 - [2026-04-17 00:05:29] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [account-requests] [mailer] [signup] Hardened the account request validation email flow so manual approval registrations do not silently skip or hide validation mail failures.
- 1 - I modified `routers/web/auth/auth.go` so the `RegisterManualConfirm` path now runs before the generic activation shortcut for normal self-registrations, while still preserving the first-user bootstrap exception.
- 2 - I modified `services/mailer/mail_user.go` so account request validation, approval, and rejection emails now return explicit errors when their templates cannot be rendered instead of failing silently.
- 3 - I modified `routers/web/auth/account_request.go` and `routers/web/admin/account_request.go` so resend and unblock flows now surface validation-email rendering failures immediately, while approval and rejection actions log mail errors without rolling back the already completed admin decision.
- 4 - I verified the updated flow builds cleanly after formatting with compile-only Go tests on the touched packages.
13 - [2026-04-17 00:53:04] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [account-requests] [mailer] Reworked the first-user bootstrap path so manual confirmation sends the validation email instead of bypassing the new account request flow.
- 1 - I modified `routers/web/auth/auth.go` so the automatic first-user admin bootstrap now only bypasses email handling when manual confirmation is disabled, while manual-confirm registrations still go through the validation email path.
- 2 - I modified `routers/web/auth/account_request.go` so when the validated account is the only user in the instance, the system activates it directly and grants admin rights immediately instead of sending it into an impossible admin-review deadlock.
- 3 - I preserved the normal staged workflow for all non-bootstrap registrations, so other users still go from email validation to pending admin review as before.
- 4 - I formatted the code and verified the touched packages with compile-only Go tests after the bootstrap flow change.
14 - [2026-04-17 01:14:35] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Added - [account-requests] [admin-users] [mailer] [locale] [en] Added an admin-side validation email send indicator with success or failure icon and attempt timestamp.
- 1 - I modified `models/user/account_request.go` to persist the last validation email attempt status and timestamp for each account request.
- 2 - I modified `routers/web/auth/auth.go`, `routers/web/auth/account_request.go`, and `routers/web/admin/account_request.go` so initial send, resend, and unblock flows now record whether the validation email send function returned success or error.
- 3 - I modified `routers/web/admin/account_request.go` and `templates/admin/user/edit.tmpl` so the account request panel in the admin user edit page now shows a `✔` or `❌` together with the last validation email attempt timestamp.
- 4 - I updated `options/locale/locale_en-US.json`, validated the JSON file, formatted the code, and verified the touched packages with compile-only Go tests.
15 - [2026-04-17 06:26:17] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [account-requests] [mailer] [ui] [signup] Extended the validation email attempt indicator so it is visible in the user-facing registration flow as well as in the admin account request panel.
- 1 - I modified `routers/web/auth/account_request.go` and `routers/web/auth/auth.go` so the last validation email attempt status and timestamp are loaded into the user-facing signup retry and activation prompt pages.
- 2 - I modified `templates/user/auth/signup_inner.tmpl` so the `✔` or `❌` indicator and timestamp now appear next to the pending request message and beside the `Resend` button area.
- 3 - I modified `templates/user/auth/activate_prompt.tmpl` so the same indicator and timestamp now appear after the initial validation email attempt triggered by account creation.
- 4 - I adjusted `templates/admin/user/edit.tmpl` so the admin panel also shows the indicator when there is mail-attempt data even if the current account request status line is otherwise absent.
16 - [2026-04-17 07:05:39] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [account-requests] [mailer] Switched the account request validation email to a real synchronous send path and added logging for silent mail queue enqueue failures.
- 1 - I modified `services/mailer/mail_user.go` so `SendAccountRequestValidationMail` now uses a synchronous sender path instead of only enqueueing the message asynchronously.
- 2 - I modified `services/mailer/mailer.go` to add `SendImmediately`, which uses the initialized configured sender directly and returns the real SMTP or sendmail error back to the caller.
- 3 - I modified `services/mailer/mailer.go` so `SendAsync` now logs queue initialization and enqueue failures instead of silently discarding them.
- 4 - This makes the new-user validation mail behave much closer to `SendTestMail`, which was already using direct sending and was one likely reason test emails succeeded while queued validation emails still appeared to disappear.
17 - [2026-04-17 08:20:46] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [auth] [mailer] Switched the remaining user-facing activation emails to synchronous delivery and stopped showing success when the actual send fails.
- 1 - I modified `services/mailer/mail_user.go` so `SendActivateAccountMail` and `SendActivateEmailMail` now return real errors and use direct synchronous sending instead of only queueing the message.
- 2 - I modified `services/mailer/mail_user.go` so account request approval and rejection emails sent to the user now use the same synchronous delivery path for consistent behavior.
- 3 - I modified `routers/web/auth/auth.go` and `routers/web/user/setting/account.go` so signup and email-confirmation flows stop reporting success when the mail send to the user fails.
- 4 - I modified `routers/web/admin/users.go` so administrator-triggered account activation now logs and warns when the activation email to the user could not be sent.
18 - [2026-04-17 18:54:53] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [auth] [account-requests] [signup] [locale] [en] Refined the account request resend UX so pending users can retry from both activation and signup pages without losing their entered registration data.
- 1 - I modified `templates/user/auth/activate_prompt.tmpl` so the activation page now shows a separate `Did not receive the email?` prompt, a standalone `Resend` button under the mail status indicator, and a Spam/Junk reminder.
- 2 - I modified `templates/user/auth/signup_inner.tmpl` so the pending-registration panel now uses plain prompt text plus a dedicated `Resend` button instead of the combined button label, while also preserving the signup form values through the resend action.
- 3 - I modified `models/user/account_request.go` and `routers/web/auth/account_request.go` so account request validation emails now track up to five resend actions and automatically hide the resend button after that limit is reached.
- 4 - I modified `routers/web/auth/auth.go` and `options/locale/locale_en-US.json` so the activation prompt receives the same resend controls immediately after registration and the new texts are available consistently across both user-facing flows.
19 - [2026-04-17 22:10:39] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [auth] [account-requests] [mailer] [signup] Prevented invalid signup email input from triggering an internal server error in the account request pre-check flow.
- 1 - I modified `models/user/account_request.go` so `GetUserByAnyEmail` now trims and validates the email address before querying, reusing the normal email validation behavior instead of treating malformed input like a server-side lookup problem.
- 2 - I modified `routers/web/auth/account_request.go` so the signup pre-check now treats invalid or unsupported email formats as normal invalid input and lets the standard registration validation flow handle the user-facing error message.
- 3 - I modified `routers/web/auth/account_request.go` so the resend endpoint also treats malformed email input as unavailable instead of escalating it into a 500 error.
20 - [2026-04-17 23:13:17] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [mailer] [signup] [locale] [en] Rolled back newly created self-registration accounts when the initial confirmation email cannot actually be sent.
- 1 - I modified `routers/web/auth/auth.go` so `createAndHandleCreatedUser` now passes the template and form context into the post-create flow, allowing failed registration emails to return a normal form error instead of a 500 page.
- 2 - I modified `routers/web/auth/auth.go` so the initial account-request validation mail and the initial standard activation mail both delete the newly created user if sending fails, preventing orphaned accounts from being left in the database.
- 3 - I added a dedicated `auth.confirmation_mail_failed` user-facing message in `options/locale/locale_en-US.json` so registration now tells the user that the account was not created because the confirmation email could not be sent.
- 4 - I preserved the existing resend behavior for already created inactive users, so the rollback applies only to the first mail send during new self-registration.
21 - [2026-04-26 22:55:56] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [scripts] [smart-build] Updated the smart build script for PNPM 10 and the repository frontend build flow.
- 1 - I modified `smart-build.sh` to remove the unsupported `--ignore-engines` PNPM option from dependency installation.
- 2 - I changed the frontend rebuild step to call `make frontend`, matching the Gitea Makefile target instead of calling a missing `pnpm run build` script.
- 3 - I fixed the architecture menu echo line so `Initialization checks` is no longer appended as stray shell text.
22 - [2026-04-26 23:01:28] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [scripts] [smart-build] Made the smart build script find the local Go toolchain before running backend builds.
- 1 - I modified `smart-build.sh` to prepend `/usr/local/go/bin` to `PATH` when the local Go binary exists.
- 2 - I added an early Go availability check so the script stops with a clear message before invoking `make build` if Go is not installed or visible.
- 3 - I added explicit failure handling for dependency installation and frontend asset builds so the script does not continue after a failed prerequisite step.
23 - [2026-04-26 23:20:08] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [scripts] [smart-build] [bindata] Added a smart build menu option for SQLite-enabled bindata builds.
- 1 - I modified `smart-build.sh` to add a build-tag selection menu with the existing `bindata` build and a new `bindata sqlite sqlite_unlock_notify` option.
- 2 - I changed the backend build command to use the selected tag set instead of always passing `TAGS="bindata"`.
- 3 - I made SQLite builds enable CGO and write artifacts with a `-sqlite` suffix so they are distinguishable from default bindata builds.
24 - [2026-04-27 00:18:15] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [account-requests] [auth] Made account request validation links robust after account data changes.
- 1 - I modified `models/user/account_request.go` so account request validation codes can be stored as hashes and later accepted as a fallback when the stateless code can no longer be recalculated from current user data.
- 2 - I modified the registration, resend, and admin unblock flows to generate one validation code, send that exact code by email, and store its hash only after the email send succeeds.
- 3 - I cleared stored validation-code hashes when account requests are reset, validated, or approved so old validation links cannot keep working after the request leaves email validation.
- 4 - I added focused tests for account request code verification and `/user/activate` handling, including the case where user data changes after the validation email is sent.
25 - [2026-04-27 00:49:34] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [account-requests] [signup] [auth] Corrected pending account request detection for validation links and repeated registration attempts.
- 1 - I modified account request status detection so inactive users with validation markers are treated as pending email validation even if `account_request.status` is missing.
- 2 - I added a dedicated account-request time-limit code purpose while keeping compatibility with older account-request links, preventing normal activation links from being intercepted by the account request path.
- 3 - I moved the pending account request pre-check before generic signup form errors so repeated registration attempts show the pending-request message and resend option instead of `The username is already taken`.
- 4 - I updated the pending signup message to include the email address that received the validation email and added focused tests for missing-status validation, classic activation separation, and repeated registration.
26 - [2026-04-27 01:10:03] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [account-requests] Restored the admin account request review flow link to the page with approval controls.
- 1 - I modified `services/mailer/mail_user.go` so new account request notification emails now link directly to `/-/admin/users/{id}/edit`, where the `Activate Request` and `Reject` controls are rendered.
- 2 - I added a focused mailer test to ensure future account request notifications keep pointing to the admin edit page instead of the read-only user view page.
27 - [2026-04-27 01:47:34] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [admin-users] [account-deletion] Hid admin-side account deletion controls for the last active administrator.
- 1 - I modified `routers/web/admin/users.go` so the admin user edit page receives `IsLastAdminUser` for the edited user.
- 2 - I modified `templates/admin/user/edit.tmpl` so `Delete User Account` is replaced by the existing last-admin warning when the edited user is the only active admin.
- 3 - I hid the admin delete confirmation modal for the last-admin case while preserving the backend `DeleteUser` last-admin guard as the final protection.
28 - [2026-04-27 02:06:06] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [admin-users] [account-deletion] Kept last-admin account deletion actions visible but disabled.
- 1 - I modified `templates/admin/user/edit.tmpl` so `Delete User Account` remains visible as a disabled button for the last active admin while showing the existing last-admin warning.
- 2 - I modified `templates/user/settings/account.tmpl` so the self-delete confirmation button remains visible as disabled for the last active admin while showing the same warning.
- 3 - I kept delete confirmation modals unavailable for the disabled last-admin actions so blocked actions cannot be submitted from the UI.
29 - [2026-04-27 09:12:11] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [admin-users] Adjusted last-admin delete warning placement and spacing.
- 1 - I modified `templates/admin/user/edit.tmpl` so the last-admin warning appears above the disabled `Delete User Account` button with vertical spacing.
- 2 - I modified `templates/user/settings/account.tmpl` so the disabled self-delete confirmation button has spacing below the warning message.
30 - [2026-04-27 09:28:16] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [admin-users] [ui] Restored admin edit action button alignment while keeping the last-admin warning above them.
- 1 - I modified `templates/admin/user/edit.tmpl` so the last-admin warning appears above the action button row.
- 2 - I kept `Update Profile` and the disabled `Delete User Account` button in the same button row and original order.
31 - [2026-04-27 10:07:15] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [account-requests] Adjusted account request resend button sizing and delivery-state feedback.
- 1 - I modified the pending signup and activation prompt templates so the resend button is smaller, blue by default, and spaced away from the spam-folder hint.
- 2 - I added resend result state rendering so successful sends turn the button green for five seconds and failed sends keep it red.
- 3 - I changed the resend handler to re-render the current account-request page with a failed send message instead of showing a server-error page when email delivery fails.
32 - [2026-04-27 14:41:33] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Added - [scripts] [build-env] Added a build environment configuration script.
- 1 - I added `configure.sh` to install and verify the system packages, Go version, Node version, pnpm version, and frontend dependencies required by this Gitea tree.
- 2 - I made the script read the required Go, Node, and pnpm versions from `go.mod` and `package.json`, while still allowing environment overrides.
- 3 - I added an optional `--with-cross-cgo` mode that installs/configures the heavier cross-CGO toolchains needed for SQLite builds targeting linux/armv7 and windows/amd64.
33 - [2026-04-27 14:51:16] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [scripts] [build-env] Added an interactive run menu to the build environment configuration script.
- 1 - I modified `configure.sh` so running it without arguments in an interactive terminal shows a description of what the script installs and verifies.
- 2 - I added a run menu with Normal, With cross cgo, Verify only, and Quit options.
- 3 - I added a `--menu` flag so the same interactive menu can be requested explicitly while keeping the existing command-line options for automated runs.
34 - [2026-04-27 14:59:01] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [scripts] [build-env] Made interactive environment verification report missing requirements without failing the menu run.
- 1 - I modified `configure.sh` so the interactive `Verify only` menu option lists all detected missing commands and configuration issues instead of stopping at the first missing requirement.
- 2 - I kept the direct `./configure.sh --verify-only` mode strict for automated checks, returning a failure when requirements are missing.
- 3 - I adjusted the final interactive verification message so it recommends rerunning the menu with Normal or With cross cgo instead of suggesting a build when requirements are still missing.
35 - [2026-04-27 15:20:01] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [scripts] [build-env] Translated the build environment configuration script text to English.
- 1 - I modified `configure.sh` so the interactive description is written in English.
- 2 - I translated the interactive menu option descriptions to English while keeping the existing script behavior unchanged.
36 - [2026-04-27 19:28:55] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [mailer] [mailer-ui] Moved test email feedback inline and aligned mail action button states.
- 1 - I modified `routers/web/admin/config.go` so the test email result redirects back to the config page with local test-mail state instead of using the global flash alert.
- 2 - I modified `templates/admin/config.tmpl` so the test email result appears beside the `Send` button, with the button using primary, green, or red state colors.
- 3 - I changed the account request `Resend` button default state from `blue` to `primary` so it uses the same visible blue styling as the rest of the Gitea UI.
37 - [2026-04-27 19:56:31] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [mailer] [mailer-ui] [scripts] [bindata] Forced mail action button colors and refreshed local template bindata.
- 1 - I modified the admin test mail and account request resend templates so their default, success, and failure colors are set directly with Gitea theme variables.
- 2 - I updated the success timeout scripts to restore the direct primary-color styling after five seconds.
- 3 - I regenerated the local ignored `modules/templates/bindata.dat` file so local bindata builds can include the updated templates.
38 - [2026-04-27 20:05:18] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [scripts] [smart-build] [bindata] Added bindata freshness checks to the smart build script.
- 1 - I modified `smart-build.sh` so bindata builds check the generated templates, options, public, and migration schema bindata files before compilation.
- 2 - I made the script regenerate any missing or stale bindata file with `go generate -tags bindata` before running `make build`.
- 3 - I kept the regeneration step neutral from cross-build environment variables by clearing `GOOS`, `GOARCH`, `CGO_ENABLED`, and `CC` for the go generate command.
39 - [2026-04-27 20:35:07] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [mailer] [mailer-ui] [admin-config] [ui] [sticky-layout] Preserved scroll position after sending a test email from the admin config page.
- 1 - I modified `templates/admin/config.tmpl` so the test email form records the current scroll position before submit.
- 2 - I modified `routers/web/admin/config.go` so the test email redirect carries the saved scroll position and returns to the local test-email anchor.
- 3 - I regenerated the local ignored `modules/templates/bindata.dat` file so bindata builds can include the scroll-preserving template update.
40 - [2026-04-27 21:03:25] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [mailer] [mailer-ui] [admin-config] [ui] Removed page reload and scroll movement from the admin test email action.
- 1 - I modified `templates/admin/config.tmpl` so the `Send Testing Email` form submits through `fetch` and updates the inline message without changing the page URL or scroll position.
- 2 - I modified `routers/web/admin/config.go` so inline test email requests return JSON state and message data instead of redirecting.
- 3 - I regenerated the local ignored `modules/templates/bindata.dat` file so bindata builds can include the no-jump test email behavior.
41 - [2026-04-27 21:14:20] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [mailer] [mailer-ui] [admin-config] Shortened admin test email delivery error messages.
- 1 - I modified `routers/web/admin/config.go` so `Send Testing Email` displays a concise SMTP failure reason instead of the full command chain.
- 2 - I added normalization for common mail errors such as user unknown, mailbox unavailable, relay access denied, and authentication failure.
- 3 - I added a focused unit test for the short test mail error formatter.
42 - [2026-04-27 21:47:26] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Added - [admin-users] [account-deletion] Added an admin user-list delete account action.
- 1 - I modified `templates/admin/user/list.tmpl` so each user row now shows a red trash icon beside the existing User Details and Edit actions.
- 2 - I added a shared delete-account confirmation modal on the user management list, including the existing purge option and delete-account warning text.
- 3 - I regenerated the local ignored `modules/templates/bindata.dat` file so bindata builds can include the new list action.
43 - [2026-04-27 22:17:13] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [admin-users] Matched the admin user-list delete action to the edit-page delete state.
- 1 - I modified `routers/web/explore/user.go` so user search pages can receive optional per-user extra data before rendering.
- 2 - I modified `routers/web/admin/users.go` so the admin user list marks rows where the user is the last active administrator using the same condition as the edit page.
- 3 - I modified `templates/admin/user/list.tmpl` so the trash icon is disabled with the existing last-admin warning tooltip whenever the edit-page `Delete User Account` button would be disabled.
44 - [2026-04-28 09:12:49] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [auth] [account-requests] Blocked inactive account-request users from getting a signed-in session.
- 1 - I modified the password sign-in flow so inactive account-request users are stopped before session, 2FA, or remember-cookie creation and are shown the activation prompt instead.
- 2 - I added account-request login prompts for pending email validation, pending admin review, rejected, and blocked states, while keeping the resend button available only for pending email validation.
- 3 - I modified existing inactive signed sessions on web pages to be signed out before rendering the activation/account-request prompt so the account menu and Sign Out action are not shown.
- 4 - I added targeted auth tests for pending email validation and pending admin review login attempts, including username and email login for the validation case.
- 5 - I regenerated the local ignored `modules/options/bindata.dat` file so bindata builds can include the new login prompt locale string.
45 - [2026-04-28 16:01:28] - v1.27.0-dev-47-gf21b6b7a3b - Type: Modified - [auth] [recovery] Added password confirmation to account recovery.
- 1 - I modified `templates/user/auth/reset_passwd.tmpl` so the account recovery reset form includes a required `Confirm Password` field.
- 2 - I modified `routers/web/auth/password.go` so reset submissions reject mismatched passwords before two-factor checks or password updates.
- 3 - I added a focused auth test for mismatched recovery password confirmation and regenerated the local ignored `modules/templates/bindata.dat` file for bindata builds.
46 - [2026-04-28 19:05:06] - v1.27.0-dev-48-g25a1d84c2e - Type: Fixed - [auth] [recovery] Used the reset-password lifetime for account recovery codes.
- 1 - I modified `models/user/user.go` so reset-password time-limit codes are generated and verified with `RESET_PASSWD_CODE_LIVE_MINUTES` instead of `ACTIVE_CODE_LIVE_MINUTES`.
- 2 - I kept activation, email activation, and account-request time-limit codes on the existing active-code lifetime.
- 3 - I added a focused user-model test that proves reset-password codes remain valid when only `RESET_PASSWD_CODE_LIVE_MINUTES` allows them.
47 - [2026-04-28 20:31:34] - v1.27.0-dev-48-g25a1d84c2e - Type: Added - [admin-invite] [admin-created-user] [signup] Added admin-created account invitation flow when registration is disabled.
- 1 - I modified admin user creation so `DISABLE_REGISTRATION = true` creates inactive, sign-in-prohibited accounts and checks `Send User Registration Notification` by default when mail is configured.
- 2 - I added a 24-hour admin invitation token and email template that lets the invited user accept the account, activate the email, and clear `Disable Sign-In`.
- 3 - I added targeted tests for invitation token lifetime, invitation acceptance, and disabled-registration admin account creation defaults, then regenerated local ignored template and options bindata.
48 - [2026-04-28 21:56:08] - v1.27.0-dev-48-g25a1d84c2e - Type: Modified - [scripts] [smart-build] Added smart-build load profile options.
- 1 - I modified `smart-build.sh` so it asks for a build load profile before dependency checks, frontend build, bindata generation, and Go compilation.
- 2 - I added Moderate and Low Resource profiles that set `GOMAXPROCS`, `MAKEFLAGS=-j1`, and a conservative Node memory limit to reduce CPU and RAM pressure.
- 3 - I kept the Normal profile available for the existing unrestricted build behavior.
49 - [2026-04-28 23:00:25] - v1.27.0-dev-49-g20405fe5e7 - Type: Added - [admin-invite] Notified inviting admins when admin-created invitations are accepted.
- 1 - I stored the creator admin ID on disabled-registration admin-created invitation accounts so the invitation acceptance flow knows who to notify.
- 2 - I added an invitation-accepted email template and mailer function that sends the accepting user's details back to the admin who created the account.
- 3 - I updated targeted admin/auth tests and regenerated local ignored template and options bindata for the new email template and locale strings.
50 - [2026-04-28 23:52:04] - v1.27.0-dev-50-g8147f7a798 - Type: Modified - [admin-created-user] [admin-users] [badges] Added creator-admin badges to the admin users list.
- 1 - I modified the admin user list data loader so users created through the disabled-registration invitation flow include the admin creator name.
- 2 - I modified `templates/admin/user/list.tmpl` so the Created column shows a `by <admin>` mini badge next to the creation date when creator data exists.
- 3 - I added a focused admin list test for the creator-admin mapping and regenerated local ignored template bindata.
51 - [2026-04-29 01:55:04] - v1.27.0-dev-51-gcfd7cfa1dc - Type: Fixed - [admin-invite] [admin-created-user] [badges] Kept creator-admin badges permanently attached to invited accounts.
- 1 - I modified the admin invitation acceptance notification flow so it no longer deletes the stored creator-admin ID.
- 2 - I updated the invitation acceptance test to assert the creator-admin marker remains after the user accepts the invitation.
52 - [2026-04-29 02:04:41] - v1.27.0-dev-52-gcd96c721e0 - Type: Modified - [admin-created-user] [badges] [mailer] Added persistent admin email tooltip to creator badges.
- 1 - I modified admin-created invitation account storage so it permanently saves the creator admin ID, username, and email address.
- 2 - I modified the admin users list creator badge so it shows `by <admin>` and exposes the stored admin email as a hover tooltip.
- 3 - I updated the focused admin list tests to prove the badge data still renders from stored name/email even without looking up the admin account, then regenerated local ignored template bindata.
53 - [2026-04-29 02:30:55] - v1.27.0-dev-52-gcd96c721e0 - Type: Modified - [auth] [admin-created-user] [badges] Added admin activation badges and first-admin GOD badge.
- 1 - I modified the admin users list so the Activated column can show a `by <admin>` badge with the stored admin email as a hover tooltip.
- 2 - I stored admin activation ID, username, and email address when account requests are approved or inactive users are manually activated by an admin.
- 3 - I added the special `by GOD` Created-column badge for the first admin account, updated focused admin list tests, and regenerated local ignored template bindata.
54 - [2026-04-29 08:25:36] - v1.27.0-dev-53-ga3e09bb819 - Type: Fixed - [admin-users] [badges] Prevented empty `by` badges in the admin users list.
- 1 - I changed the admin users list badge maps to use pointer values so missing entries render as empty instead of truthy zero-value structs.
- 2 - I guarded the Created and Activated badge rendering so badges only appear when a display name exists.
- 3 - I reran the focused admin badge tests and regenerated local ignored template bindata.
55 - [2026-04-29 09:02:42] - v1.27.0-dev-53-ga3e09bb819 - Type: Modified - [account-requests] [admin-users] [ui] Moved account request review controls to the top of the admin user edit panel.
- 1 - I moved the account request status message to the top of the admin user edit segment, immediately under the panel header.
- 2 - I moved the Activate/Reject/Unblock request controls above the profile edit form so admins can review pending accounts without scrolling down.
- 3 - I regenerated local ignored template bindata for the updated admin user edit template.
56 - [2026-04-29 09:32:09] - v1.27.0-dev-54-gc7c7af77a1 - Type: Modified - [admin-users] Defaulted admin user purge checkboxes to enabled.
- 1 - I set the Purge User checkbox to checked by default in the admin user edit delete modal.
- 2 - I set the Purge User checkbox to checked by default in the admin users list delete modal.
- 3 - I regenerated local ignored template bindata for the updated admin templates.
57 - [2026-04-29 09:53:08] - v1.27.0-dev-55-ga8d9e5e659 - Type: Added - [auth] [admin-users] [account-status] Added Disable Sign-In metadata to the admin users list.
- 1 - I added persistent admin metadata for Disable Sign-In actions, including timestamp, admin ID, admin name, and admin email.
- 2 - I added a Disable Sign-In column to the admin users list that displays the block date and `by <admin>` badge with email tooltip.
- 3 - I stored the same metadata when admin-created invitation accounts start disabled, when an admin disables sign-in from the edit form, and when an account request is rejected.
58 - [2026-04-29 10:09:41] - v1.27.0-dev-55-ga8d9e5e659 - Type: Modified - [auth] [admin-users] [account-status] Added inactive marker to the Disable Sign-In admin users column.
- 1 - I changed the Disable Sign-In column so users without sign-in disabled show the same `octicon-x` marker style as the other status columns.
- 2 - I kept the block date and `by <admin>` badge for users that do have Disable Sign-In metadata.
- 3 - I regenerated local ignored template bindata for the updated admin users list template.
59 - [2026-04-29 14:49:39] - v1.27.0-dev-56-g1dcd81b420 - Type: Added - [admin-users] [account-status] [mailer] Added admin status-change reasons and user email notifications.
- 1 - I added reason fields under the admin edit checkboxes for account activation, Disable Sign-In, and restricted status.
- 2 - I require a reason when an admin newly deactivates an account, enables Disable Sign-In, or enables restricted mode, then email the user with the action, admin name, and reason.
- 3 - I added the status-change email template, locale strings, regenerated local ignored template/options bindata, and reran the focused admin tests.
60 - [2026-04-29 19:01:39] - v1.27.0-dev-57-g210955465e - Type: Fixed - [auth] [account-status] [mailer] Corrected admin status reason behavior and reactivation emails.
- 1 - I changed the admin edit form so reason fields belong to the existing checkboxes and only appear for the restrictive state of each checkbox.
- 2 - I persisted the deactivation, Disable Sign-In, and restricted reasons in user settings so later administrators can see the saved reason.
- 3 - I changed status-change emails to describe the actual account effect, added notifications when restrictions are lifted, and stopped sending the old activation email on admin reactivation.
61 - [2026-04-29 19:56:22] - v1.27.0-dev-59-gb3204f3db6 - Type: Added - [admin-users] [badges] Added restricted-admin badges and reason actor badges.
- 1 - I added persistent admin metadata for Restricted actions, including timestamp, admin ID, admin name, and admin email.
- 2 - I changed the admin users list Restricted column so newly restricted users show the restriction date and `by <admin>` badge with email tooltip.
- 3 - I added `by <admin>` badges next to the saved Reason labels in the admin user edit panel for deactivation, Disable Sign-In, and Restricted reasons.
62 - [2026-04-29 21:00:30] - v1.27.0-dev-60-g396b15372d - Type: Added - [admin-users] [badges] Added Is Administrator reason and admin-grant badges.
- 1 - I added persistent metadata for granting administrator privileges, including timestamp, admin ID, admin name, admin email, and reason.
- 2 - I changed the admin users list so administrator accounts with grant metadata show an `Admin by <admin>` badge with email tooltip.
- 3 - I added the Is Administrator reason field, reason actor badge, grant/revoke email notifications, regenerated local ignored bindata, and added focused admin grant tests.
63 - [2026-04-29 21:30:55] - v1.27.0-dev-60-g396b15372d - Type: Fixed - [admin-users] Made Is Administrator reasons apply only when admin rights are revoked.
- 1 - I changed the Is Administrator reason field so it appears only when the checkbox is unchecked.
- 2 - I stopped requiring or sending a reason when administrator privileges are granted and changed that email to a congratulatory promotion message.
- 3 - I kept the reason on administrator privilege removal, regenerated template/options bindata, and reran the focused admin grant tests.
64 - [2026-04-29 22:03:18] - v1.27.0-dev-61-g067a09c2ac - Type: Fixed - [admin-users] Disabled critical self-edit account state checkboxes.
- 1 - I disabled User Account Is Activated and Is Restricted when an administrator edits their own account, matching the existing self-edit protection for Disable Sign-In.
- 2 - I hardened the admin user update handler so manually submitted self-edit forms cannot change the current admin's active, restricted, or prohibit-login state.
- 3 - I regenerated local ignored template bindata and verified the admin package compilation with reduced build pressure.
65 - [2026-04-29 22:37:56] - v1.27.0-dev-62-g3afb4e8afa - Type: Added - [auth] [scripts] Added Codex ChatGPT login helper script.
- 1 - I added `.codex_gpt_login`, an interactive helper for completing the local Codex ChatGPT auth callback in code-server environments.
- 2 - The script accepts either a raw received code or a full URL/query containing `code=...`, calls the local callback endpoint, extracts `id_token`, and completes the `/success` request.
- 3 - I made the script executable and verified its shell syntax with `bash -n`.
66 - [2026-04-29 22:55:08] - v1.27.0-dev-62-g3afb4e8afa - Type: Modified - [admin-users] [badges] Added admin actor badge beside the Is Administrator option.
- 1 - I updated the admin user edit panel so the Is Administrator checkbox label shows `by <admin>` when administrator grant metadata exists.
- 2 - I reused the stored admin email as the badge hover tooltip and regenerated local ignored template bindata.
67 - [2026-04-30 00:30:40] - v1.27.0-dev-63-g4aacf3bd20 - Type: Fixed - [admin-users] Hid Is Administrator reason unless admin rights were revoked.
- 1 - I changed the Is Administrator reason field so normal non-admin users do not see it just because the checkbox is unchecked.
- 2 - The reason field now appears only when a saved admin-revocation reason exists or when an existing administrator is being unchecked during the current edit.
- 3 - I regenerated local ignored template bindata and verified whitespace with `git diff --check`.
68 - [2026-04-30 01:44:17] - v1.27.0-dev-64-gcff1b46f50 - Type: Added - [admin-users] [super-admin] Added persistent super administrator protection.
- 1 - I added `SUPER_ADMIN_ENABLED` and `ADMIN_MANAGEMENT_POLICY` configuration options for administrator permission management.
- 2 - I stored the super administrator role and grant/revoke metadata in persistent user settings, with automatic `by GOD` bootstrap for the first active admin.
- 3 - I protected administrator and super administrator changes so regular admins cannot alter existing admins unless the selected policy allows a regular-user promotion.
- 4 - I added super administrator badges, reason tracking, and status-change emails, then regenerated template and options bindata.
69 - [2026-04-30 02:20:26] - v1.27.0-dev-64-gcff1b46f50 - Type: Fixed - [admin-users] [super-admin] Enabled super administrator bootstrap by default.
- 1 - I changed `SUPER_ADMIN_ENABLED` to default to `true` so existing installations without the new app.ini key bootstrap the first active administrator automatically.
- 2 - I updated the app.ini example to document the enabled default and kept `SUPER_ADMIN_ENABLED = false` available as the explicit opt-out.
- 3 - I made the super administrator list badge fall back to `by GOD` for the bootstrapped first administrator and regenerated options bindata.
70 - [2026-04-30 04:08:23] - v1.27.0-dev-66-g35b9fa65d3 - Type: Fixed - [admin-users] [super-admin] Blocked regular administrators from editing super administrator accounts.
- 1 - I modified `routers/web/admin/users.go` so non-super-admins are redirected away from super-admin edit actions, including profile edits and avatar changes.
- 2 - I modified `routers/api/v1/admin/user.go` so the admin user edit API now returns forbidden when a regular admin targets a super admin.
- 3 - I modified `templates/admin/user/list.tmpl` and `templates/admin/user/view.tmpl` so edit actions are hidden for super-admin accounts when the acting admin is not also a super admin.
- 4 - I added `TestAdminCannotEditSuperAdminUser` in `tests/integration/admin_user_test.go` to cover the denied web-edit flow.
71 - [2026-04-30 04:19:14] - v1.27.0-dev-67-g0fc6f30a30 - Type: Modified - [admin-users] [super-admin] Kept super administrator Edit and Delete controls visible but disabled for regular admins.
- 1 - I modified `templates/admin/user/list.tmpl` so super-admin rows still show the `Edit` and `Delete` icons for regular admins, but as disabled muted controls with the super-admin-required tooltip.
- 2 - I modified `templates/admin/user/view.tmpl` so the `Edit` button remains visible on the super-admin user details page for regular admins, but in a disabled state.
72 - [2026-04-30 04:58:16] - v1.27.0-dev-68-g5da24d2c7b - Type: Modified - [admin-users] [admin-policy] Protected GOD-granted admin accounts and blocked deleting the direct grantor.
- 1 - I added `models/user/admin_grant.go` with helpers to read admin and super-admin grantor metadata, detect `by GOD` bootstrap grants, and check whether a target user is the direct grantor of another admin.
- 2 - I modified `routers/web/admin/users.go` so GOD-granted accounts cannot be edited or deleted through admin actions, and regular admins may delete other admin accounts except their direct grantor and protected super-admin cases.
- 3 - I modified `routers/api/v1/admin/user.go` so the admin API now enforces the same GOD-protection and direct-grantor deletion rule.
- 4 - I added locale messages for the new admin restrictions and added focused integration coverage for deleting another admin versus the direct grantor, plus GOD-protected admin API edits.
73 - [2026-04-30 16:51:42] - v1.27.0-dev-71-g80497e4194 - Type: Modified - [admin-users] Restored normal self-edit access for super admins and disabled only the admin actions that are truly forbidden.
- 1 - I modified `routers/web/admin/users.go` so a GOD-granted or super-admin user can still edit their own ordinary account fields, while forbidden cross-user edits remain blocked and table action states are computed per target user.
- 2 - I modified `routers/api/v1/admin/user.go` so GOD-protection no longer blocks a user from editing their own account through the admin API.
- 3 - I modified `templates/admin/user/list.tmpl`, `templates/admin/user/view.tmpl`, and `templates/admin/user/edit.tmpl` so `Edit` stays enabled for allowed self-edits, while forbidden `Edit` and `Delete` actions are shown disabled with the specific reason tooltip or warning message.
74 - [2026-04-30 20:11:48] - v1.27.0-dev-72-g43161732e3 - Type: Modified - [installer] [locale] [en] Added install-time admin management policy choices with direct-grantor and inherited-grantor enforcement.
- 1 - I modified `modules/setting/admin.go`, `services/forms/user_form.go`, `routers/install/install.go`, `templates/install.tmpl`, and `options/locale/locale_en-US.json` so installation now exposes three administrator-management policies: `super_admin_only`, `grantor_only`, and `grantor_inheritance`, while normalizing the old legacy policy names.
- 2 - I modified `models/user/admin_grant.go` so the code can resolve the effective admin grantor by walking the admin-grant chain until it finds an active administrator who still has sign-in enabled.
- 3 - I modified `routers/web/admin/users.go` so regular admins can edit or delete only the administrator accounts allowed by the selected policy, while keeping super-admin protections, GOD protections, self-edit exceptions, and disabled forbidden actions intact in the admin UI.
- 4 - I modified `routers/api/v1/admin/user.go` so the admin API now applies the same grantor-based restrictions for editing and deleting administrator accounts.
- 5 - I added focused integration coverage in `tests/integration/admin_user_test.go` and `tests/integration/api_admin_test.go` for direct-grantor edits, inherited-grantor edits, and API denial for unrelated admins.
75 - [2026-04-30 20:37:01] - v1.27.0-dev-72-g43161732e3 - Type: Modified - [installer] [app-ini-import] [admin-policy] Updated the example app.ini documentation for the new administrator management policies.
- 1 - I modified `custom/conf/app.example.ini` so the `ADMIN_MANAGEMENT_POLICY` comments now document `super_admin_only`, `grantor_only`, and `grantor_inheritance`, and changed the documented default to `grantor_only`.
76 - [2026-04-30 22:03:50] - v1.27.0-dev-73-g1e13af4d6e - Type: Modified - [admin-users] [super-admin] [installer] [locale] [en] Updated install-page administrator labels to super administrator wording.
- 1 - I modified `options/locale/locale_en-US.json` so the install-page administrator account title, description, and username label now refer to the super administrator role.
- 2 - I renamed the install-page policy label from `Administrator Management Policy` to `Administration Management Policy`.
77 - [2026-04-30 23:05:46] - v1.27.0-dev-75-gd4a1b88385 - Type: Modified - [mailer] [installer] [locale] [en] Added install-page testing email verification using the entered SMTP settings.
- 1 - I modified `routers/install/routes.go`, `routers/install/install.go`, and `templates/install.tmpl` so the install page now has an inline `Send Testing Email` action that posts the current SMTP form values to a dedicated install endpoint.
- 2 - I modified `services/mailer/mail.go` and `routers/web/admin/config.go` so compact test-mail error formatting is shared and install can send a test message with a temporary mailer configuration instead of relying on saved global settings.
- 3 - I modified `options/locale/locale_en-US.json` for the install-page test-mail labels and regenerated template and options bindata after verifying the affected Go packages compile.
78 - [2026-04-30 23:25:10] - v1.27.0-dev-75-gd4a1b88385 - Type: Modified - [mailer] [mailer-ui] [installer] Repositioned install-page Send Testing Email under SMTP Password.
- 1 - I modified `templates/install.tmpl` so the `Send Testing Email` row now appears immediately below the `SMTP Password` field inside `Email Settings`.
- 2 - I kept the existing selectors, inline message area, and button behavior unchanged while preserving the remaining field order.
- 3 - I regenerated template bindata and rechecked the install package compile path after the layout-only change.
79 - [2026-04-30 23:48:41] - v1.27.0-dev-75-gd4a1b88385 - Type: Fixed - [mailer] [mailer-ui] [installer] Aligned install-page Send Testing Email with the standard inline form grid.
- 1 - I modified `templates/install.tmpl` so the `Send Testing Email` input, button, and message now render inside the same `right-content` column used by the other install-page inline fields.
- 2 - I kept the existing selectors and behavior unchanged and only corrected the layout alignment relative to `SMTP Password`.
80 - [2026-05-01 00:36:35] - v1.27.0-dev-75-gd4a1b88385 - Type: Fixed - [mailer] [mailer-ui] [installer] [ui] Matched install-page Send Testing Email row to the target inline layout.
- 1 - I modified `templates/install.tmpl` so the `Send Testing Email` controls now use an inline wrapper with the same 60 percent content width as the standard install-form inputs instead of the block-style `right-content` helper.
- 2 - I kept the existing selectors and behavior unchanged and only corrected the horizontal alignment to match the target SMTP Password row layout.
81 - [2026-05-01 00:56:45] - v1.27.0-dev-75-gd4a1b88385 - Type: Modified - [mailer] [mailer-ui] [installer] [ui] Brightened install-page Send Testing Email status message colors.
- 1 - I modified `templates/install.tmpl` so the inline status message now uses `var(--color-green)` for success and `var(--color-red)` for failure instead of the softer Tailwind utility classes.
- 2 - I kept the existing button behavior unchanged and only adjusted the message text color handling in the install-page JavaScript.
82 - [2026-05-01 13:09:43] - v1.27.0-dev-76-g362d01abbc - Type: Modified - [installer] [signup] [locale] [en] Added install-page Registration Management with coherent mode-driven registration settings.
- 1 - I modified `templates/install.tmpl`, `services/forms/user_form.go`, and `routers/install/install.go` so the install page now exposes a dedicated `Registration Management` section with radio-button registration modes plus dependent local and external sub-options.
- 2 - I mapped the new UI to the existing service settings by deriving `DISABLE_REGISTRATION`, `ALLOW_ONLY_INTERNAL_REGISTRATION`, `ALLOW_ONLY_EXTERNAL_REGISTRATION`, `REGISTER_EMAIL_CONFIRM`, and `REGISTER_MANUAL_CONFIRM` consistently from the selected mode and sub-options.
- 3 - I updated `web_src/js/features/install.ts` and `options/locale/locale_en-US.json` so contradictory options are hidden or disabled in the browser, added the new English labels and descriptions, and regenerated template and options bindata.
83 - [2026-05-01 18:14:40] - v1.27.0-dev-77-g19fb194db6 - Type: Modified - [installer] [locale] [en] Completed install-page admin-managed account modes and aligned locale install sections.
- 1 - I modified `modules/setting/service.go`, `custom/conf/app.example.ini`, `services/forms/user_form.go`, `routers/install/install.go`, `templates/install.tmpl`, and `web_src/js/features/install.ts` so `Registration Management` now includes administrator-managed local versus invitation-based account provisioning, plus a helper for `Enable Email Notifications`.
- 2 - I updated `routers/web/admin/users.go` and `routers/api/v1/admin/user.go` so disabled-registration account creation follows the configured administrator-created account mode, stores creator metadata for admin-created users, and sends either invitation mail or standard registration notification accordingly.
- 3 - I aligned every `options/locale/locale_*.json` install section to the new key set and en-US fallback order, regenerated template and options bindata, and verified the affected install, admin web, and admin API packages.
84 - [2026-05-02 00:16:23] - v1.27.0-dev-78-gad0ab4be60 - Type: Modified - [admin-created-user] [admin-users] [installer] [locale] [en] Moved admin-created account delivery mode selection from install to the admin new-user form.
- 1 - I updated `templates/install.tmpl` and `web_src/js/features/install.ts` to remove the install-page `Administrator-managed accounts only` sub-mode choice so registration mode no longer decides how `/admin/users/new` delivers newly created accounts.
- 2 - I extended `services/forms/admin.go`, `templates/admin/user/new.tmpl`, `web_src/js/features/admin/common.ts`, and `routers/web/admin/users.go` so `/admin/users/new` now offers mutually exclusive `Send User Registration Notification` and `Send User Registration Invitation` checkboxes, defaults the invitation checkbox when mail is available, preserves checkbox state on form re-render, and sends the matching email flow.
- 3 - I adjusted `routers/web/admin/users_test.go`, added the new `admin.users.send_register_invite` locale key across `options/locale/locale_*.json`, regenerated template and options bindata, and re-verified the focused admin user flow.
85 - [2026-05-02 01:52:40] - v1.27.0-dev-79-ga6695a6e73 - Type: Modified - [auth] [mailer] [signup] [locale] [en] Unified classic email-confirmation signup with the resend-based pending validation flow.
- 1 - I updated `routers/web/auth/auth.go` and `routers/web/auth/account_request.go` so classic `REGISTER_EMAIL_CONFIRM` signups now render the same resend-capable activation prompt after account creation, redirect repeated signups with the same unconfirmed email to the resend-capable pending state instead of `The username is already taken`, and show the same resend-capable prompt when an unconfirmed user attempts to sign in.
- 2 - I added classic activation resend state tracking in `models/user/account_request.go`, re-used the existing resend UI data contract for both signup and activation prompts, and extended `/user/sign_up/resend` to handle classic email-confirmation accounts with a five-resend limit.
- 3 - I added focused auth tests in `routers/web/auth/auth_test.go`, aligned all `options/locale/locale_*.json` files with the new confirmation-mail keys, regenerated options bindata, and re-verified the affected auth package.
86 - [2026-05-02 02:20:53] - v1.27.0-dev-80-g4ab8063966 - Type: Modified - [installer] [locale] [en] Added default language selection to the install page initial configuration.
- 1 - I extended `services/forms/user_form.go`, `routers/install/install.go`, and `templates/install.tmpl` so `General Settings` now includes a `Default Language` selector backed by the existing `AllLangs` list and validated against configured locales.
- 2 - I wired install submission to persist the selection by reordering `[i18n] LANGS` so the chosen language becomes the first fallback/default locale, while keeping the remaining languages available.
- 3 - I added focused install tests in `routers/install/routes_test.go`, aligned all `options/locale/locale_*.json` files with the new install language keys, regenerated template and options bindata, and re-verified the install package.
87 - [2026-05-02 02:36:07] - v1.27.0-dev-80-g4ab8063966 - Type: Modified - [mailer] Disabled forbidden email deletion actions in the admin email list.
- 1 - I extended `routers/web/admin/emails.go` so each listed email now carries explicit delete permission state and, for primary addresses, the existing `admin.emails.delete_primary_email_error` reason for the disabled UI.
- 2 - I updated `templates/admin/emails/list.tmpl` so the trash icon remains clickable only for deletable addresses and renders as a muted disabled control with a tooltip when deletion is forbidden, such as for a primary email address.
- 3 - I kept the existing backend deletion guard in place, regenerated template bindata, and re-verified the affected admin package plus whitespace consistency.
88 - [2026-05-02 03:12:25] - v1.27.0-dev-82-gf8f988e85e - Type: Modified - [admin-invite] [installer] [sticky-layout] [locale] [en] Added a dedicated pending-invitation flow for admin-created invite accounts and pinned the install footer.
- 1 - I updated `templates/admin/user/new.tmpl`, `routers/web/admin/users.go`, `routers/api/v1/admin/user.go`, `models/user/account_request.go`, and `services/mailer/mail_user.go` so admin-created invitation accounts remain inactive without forcing `Disable Sign-In`, carry explicit pending-invitation state, and show helper text for the notification versus invitation options.
- 2 - I added the dedicated invitation prompt and resend flow through `templates/user/auth/invite_prompt.tmpl`, `routers/web/auth/auth.go`, `routers/web/auth/account_request.go`, and `routers/web/web.go`, including sign-in redirection for pending invitations, backward-compatible handling for legacy prohibited invite accounts, and resend tracking for invitation emails.
- 3 - I updated `templates/base/footer_content.tmpl`, `web_src/css/install.css`, and all `options/locale/locale_*.json` files so the install footer stays continuously visible on the install page, the new invitation strings are available across locales, template and option bindata were regenerated, and the affected auth/admin/API packages were re-verified.
89 - [2026-05-02 04:05:54] - v1.27.0-dev-83-gf7bc24d4e8 - Type: Modified - [admin-invite] [installer] [ui] Aligned the admin new-user invitation help text with the install-page help layout.
- 1 - I updated `templates/admin/user/new.tmpl` so the `Send User Registration Notification` and `Send User Registration Invitation` rows now use a dedicated right-side content wrapper instead of rendering the help text directly under the checkbox.
- 2 - I extended `web_src/css/admin.css` with scoped layout rules for `.admin-user-mail-option` so the help text sits under the checkbox content in the same visual column style used on the install page, including responsive behavior for narrow screens.
- 3 - I regenerated template bindata after the markup change and re-verified whitespace consistency for the affected files.
90 - [2026-05-02 12:11:50] - v1.27.0-dev-84-gf60b2af5a6 - Type: Modified - [installer] [locale] [en] [ui] [sticky-layout] Added an install-page language hint balloon anchored to the footer language selector.
- 1 - I updated `templates/base/footer_content.tmpl` and `templates/install.tmpl` so the install page now renders a green `Choose a language` hint balloon tied to the footer language selector and dismisses it on the first page click.
- 2 - I extended `web_src/css/install.css` with fixed-position balloon styling and responsive placement above the install footer so the hint remains visible without overlapping the footer controls.
- 3 - I added the new `install.language_balloon` locale key to `options/locale/locale_en-US.json`, aligned all `options/locale/locale_*.json` files to include it, and re-generated the template and options bindata assets.
91 - [2026-05-02 12:28:12] - v1.27.0-dev-84-gf60b2af5a6 - Type: Fixed - [installer] [locale] [ui] [sticky-layout] Delayed the install-page language hint balloon initialization until the footer exists in the DOM.
- 1 - I updated `templates/install.tmpl` so the `Choose a language` balloon now initializes on `DOMContentLoaded` instead of running before the footer language selector has been parsed.
- 2 - I kept the existing dismiss-on-first-click behavior unchanged and only fixed the timing issue that prevented the balloon from appearing at first page load.
- 3 - I regenerated the template bindata assets and re-verified whitespace consistency after the template-only fix.
92 - [2026-05-02 13:31:45] - v1.27.0-dev-85-g4eaa42bccd - Type: Modified - [locale] [en] [ro] Added official bootstrap support for the Romanian locale.
- 1 - I updated `modules/setting/i18n.go` so `ro-RO` is now part of the built-in language list with the display name `Română`.
- 2 - I updated `custom/conf/app.example.ini` so the example `[i18n] LANGS` and `NAMES` lists now include `ro-RO` and `Română`.
- 3 - I added `options/locale/locale_ro-RO.json` as an initial bootstrap locale copied from `locale_en-US.json`, so the Romanian locale can be selected and loaded cleanly before the dedicated translation pass.
93 - [2026-05-02 14:41:58] - v1.27.0-dev-86-g414c77278b - Type: Modified - [locale] [en] [ro] Added a first complete Romanian translation pass for `locale_ro-RO.json`.
- 1 - I translated `options/locale/locale_ro-RO.json` from the current `locale_en-US.json` structure, preserving placeholders and HTML fragments, then applied targeted manual overrides for the install, auth, mail, and admin account-management flows customized in this fork.
- 2 - I normalized key Git and administration terms in Romanian and fixed token-protection artifacts that surfaced during the automated translation pass, including the affected `WebAuthn`, `OpenID`, `CAPTCHA`, `Gitea`, milestone completeness, delete-warning, and GPG warning strings.
- 3 - I regenerated `modules/options/bindata.dat` so the updated Romanian locale is embedded in the build output.
94 - [2026-05-05 02:30:50] - v1.27.0-dev-86-g414c77278b - Type: Modified - [locale] [ro] Refined Romanian UI wording in `locale_ro-RO.json`.
- 1 - I adjusted Romanian phrasing across the translated locale to improve readability and consistency in general UI strings.
- 2 - I normalized terminology for navigation, repository, authentication, and administration labels to better match the existing Gitea interface.
- 3 - I kept placeholders, HTML fragments, and technical tokens intact while polishing the translated text.
95 - [2026-05-06 03:15:10] - v1.27.0-dev-86-g414c77278b - Type: Modified - [locale] [ro] Corrected Romanian wording and grammar in `locale_ro-RO.json`.
- 1 - I fixed a small set of Romanian phrasing and grammar issues identified after the previous translation polish pass.
- 2 - I kept the scope limited to wording corrections without changing the locale structure or translation coverage.
- 3 - I preserved existing placeholders, HTML fragments, and technical tokens while applying the text fixes.
96 - [2026-05-06 00:47:16] - v1.27.0-dev-90-g75a9dbf7d7 - Type: Modified - [org-ui] [ui] Restyled the organization creation panel and added a cancel action.
- 1 - I updated `templates/org/create.tmpl` so `/org/create` now renders inside a settings-style attached header and segment panel instead of the older standalone form block.
- 2 - I kept the existing organization creation fields intact, but changed the action row to a right-aligned button group with a new `Cancel` button beside `Create Organization`.
- 3 - I updated `routers/web/org/org.go` to provide a `CancelLink` back to `/user/settings/organization`, regenerated template bindata, and re-verified the `routers/web/org` package.
97 - [2026-05-06 01:08:23] - v1.27.0-dev-90-g75a9dbf7d7 - Type: Modified - [org-ui] [modal] Converted the organization creation page to a modal-style dialog and preserved the caller page for cancel.
- 1 - I updated `templates/org/create.tmpl` so `/org/create` now renders as a visible `ui small modal` dialog with header, content, and actions matching the visual structure used by the Actions secrets and variables modals.
- 2 - I extended `web_src/css/org.css` with page-scoped layout rules that center the active modal on the standalone page while keeping the styling limited to `page-content.organization.new.org`.
- 3 - I updated `routers/web/org/org.go` so `Cancel` now returns to a safe current-site `redirect_to` target or same-site referrer instead of always forcing `/user/settings/organization`, regenerated template bindata, and re-verified the `routers/web/org` package.
98 - [2026-05-06 02:02:33] - v1.27.0-dev-91-gba0da47957 - Type: Added - [codex-docs] Added persistent Codex project-orientation documents for fast task handoff and recovery.
- 1 - I added `.codex-project-map.md` as a durable project guide that captures the web request flow, authentication architecture, practical extension points, and a restart procedure for new tasks.
- 2 - I modified `.codex-context.md` so it now points explicitly to `.codex-project-map.md` and documents the recommended read order for resuming work after a blocked session.
- 3 - I refreshed the repository-derived version reference in `.codex-context.md` so future history updates can use the current application version format consistently.
99 - [2026-05-06 02:18:58] - v1.27.0-dev-91-gba0da47957 - Type: Modified - [org-ui] [modal] [ui] Reworked organization creation into a real overlay modal on top of the organization settings page and made outside clicks close it.
- 1 - I modified `templates/user/settings/organization.tmpl` so the `New Organization` action now opens the create dialog with the standard `show-modal` flow while keeping the organization settings page visible in the background.
- 2 - I converted `templates/org/create.tmpl` into a reusable modal partial and updated `routers/web/org/org.go` so `/org/create` now renders the same organization settings page with that modal auto-opened, preserving `CancelLink` for close and validation-error flows.
- 3 - I simplified `web_src/css/org.css` to keep only the create-modal helper text styling and removed the previous fake standalone modal layout that replaced the background page.
100 - [2026-05-06 10:13:49] - v1.27.0-dev-91-gba0da47957 - Type: Fixed - [org-ui] [ui] Corrected the organization settings cancel-link build regression.
- 1 - I fixed `routers/web/user/setting/profile.go` so it uses the `ctx.Req.RequestURI` field instead of calling it like a function.
- 2 - This removes the compile error in `code.gitea.io/gitea/routers/web/user/setting` that was blocking the Windows build after the organization-create modal refactor.
101 - [2026-05-06 10:54:10] - v1.27.0-dev-91-gba0da47957 - Type: Modified - [org-ui] [modal] Made the new-organization modal open in place from the UI and reset its default values consistently.
- 1 - I moved the reusable `create-org-modal` inclusion to `templates/base/footer.tmpl` so signed-in users who can create organizations have the modal available on normal pages without navigating away first.
- 2 - I updated the `New Organization` triggers in `templates/base/head_navbar.tmpl`, `templates/user/dashboard/navbar.tmpl`, `templates/admin/org/list.tmpl`, and `templates/user/settings/organization.tmpl` to use `show-modal` with `/org/create` as a non-JavaScript fallback, preserving the current page and scroll position when JavaScript is enabled.
- 3 - I added explicit reset attributes for organization name, `redirect_to`, visibility radios, and the `repo_admin_change_team_access` checkbox so the modal opened from `/user/settings/organization` now uses the same defaults as the one opened from the global create menu.
102 - [2026-05-06 10:55:13] - v1.27.0-dev-91-gba0da47957 - Type: Modified - [org-ui] [modal] Extended the in-place new-organization modal behavior to the dashboard organization list component.
- 1 - I modified `web_src/js/components/DashboardRepoList.vue` so the `New Organization` trigger in the organizations dashboard tab now also uses the shared `show-modal` flow instead of forcing navigation when JavaScript is enabled.
- 2 - I kept `/org/create` as the fallback `href` in the component so the non-JavaScript path remains available.
103 - [2026-05-06 18:03:33] - v1.27.0-dev-91-gba0da47957 - Type: Modified - [locale] [ro] Somes correction Romanian wording and grammar in `locale_ro-RO.json`.
104 - [2026-05-06 18:19:21] - v1.27.0-dev-91-gba0da47957 - Type: Modified - [ui] Fix align new-user check-boxes help text.
105 - [2026-05-06 18:47:44] - v1.27.0-dev-91-gba0da47957 - Type: Modified - [locale] [ro] Some new correction Romanian wording and grammar in `locale_ro-RO.json`.
106 - [2026-05-06 15:54:50] - v1.27.0-dev-96-g7c7357f314 - Type: Modified - [admin-invite] [auth] Reduced the resend button size on the invitation acceptance prompt.
- 1 - I modified `templates/user/auth/invite_prompt.tmpl` so the `Resend` button on `/user/invitation?email=...` now uses the smaller `ui mini button` size instead of `ui tiny button`.
- 2 - I kept the existing inline resend states, colors, and success reset behavior unchanged.
107 - [2026-05-06 18:57:49] - v1.27.0-dev-98-g5f0f52d04f - Type: Fixed - [org-ui] [modal] Prevented the new-organization modal from inheriting unrelated global success flashes from the underlying page.
- 1 - I modified `templates/org/create.tmpl` so the modal now renders only its local error flash instead of the full `base/alert` block.
- 2 - This keeps `/org/create` validation errors visible in the modal while preventing inherited success, info, or warning flash messages from the background page from appearing inside it.
108 - [2026-05-06 21:07:26] - v1.27.0-dev-99-gfc43980a5c - Type: Fixed - [admin-invite] [admin-created-user] [mailer] [locale] Made admin-created user notification and invitation emails use the current page locale.
- 1 - I modified `services/mailer/mail_user.go` to add locale-aware variants for registration-notify and admin-invite emails, while preserving the existing user-language fallback helpers for other call sites.
- 2 - I modified `routers/web/admin/users.go` and `routers/api/v1/admin/user.go` so admin-created account emails now use `ctx.Locale` from the current request instead of always rendering in the new account's empty or default language.
109 - [2026-05-06 22:11:33] - v1.27.0-dev-100-g70ef46362e - Type: Modified - [admin-created-user] [mailer] [locale] [en] [ro] Personalized the admin-created account notification email with the creator name and a direct set-password link.
- 1 - I modified `services/mailer/mail_user.go` so the registration notification email now accepts the admin user, generates a time-limited `reset_password` token URL for the new account, and passes both values into the mail template.
- 2 - I modified `routers/web/admin/users.go` and `routers/api/v1/admin/user.go` so the admin-created account notification now includes `ctx.Doer` when sending the non-invite email variant.
- 3 - I modified `templates/mail/user/auth/register_notify.tmpl`, `options/locale/locale_en-US.json`, and `options/locale/locale_ro-RO.json` so the email explicitly states that the administrator created the account and instructs the recipient to use a personal password-setup link before signing in.
110 - [2026-05-06 22:11:33] - v1.27.0-dev-100-g70ef46362e - Type: Fixed - [admin-created-user] [mailer] Corrected the admin-created account password-setup email link to use the public recovery route.
- 1 - I modified `services/mailer/mail_user.go` so the personalized password-setup link now targets `/user/recover_account?code=...`, which is the actual public route mounted for password reset token handling.
- 2 - This fixes the 404 triggered by the previous `/user/reset_password?code=...` link, because the router exposes `auth.ResetPasswd` on `/user/recover_account` instead.
111 - [2026-05-06 23:43:34] - v1.27.0-dev-102-g146013827c - Type: Modified - [admin-invite] [admin-created-user] Made the admin-created account notification link behave like an invitation by signing the user in through `/user/activate`.
- 1 - I modified `models/user/user.go` to add a dedicated `TimeLimitCodeAdminAccess` purpose that reuses the password-reset lifetime but remains separate from reset-password and invite tokens.
- 2 - I modified `services/mailer/mail_user.go` so the `Send User Registration Notification` email now points to `/user/activate?code=...` with the new admin-access token instead of sending the recipient through the recovery form flow.
- 3 - I modified `routers/web/auth/auth.go` so `auth.Activate` and `auth.ActivatePost` can consume the new token, rotate `Rands`, create the session, refresh locale, update last-login metadata, and then rely on the existing `MustChangePassword` redirect to land the user on `/user/settings/change_password`.
- 4 - I added `TestActivateAdminAccessSignsInAndInvalidatesCode` in `routers/web/auth/auth_test.go` to cover the new direct-access flow and confirm the token is invalidated after first use.
112 - [2026-05-06 23:43:34] - v1.27.0-dev-102-g146013827c - Type: Modified - [auth] [admin-created-user] [mailer] Simplified the admin-created account notification email to show only the personalized activation link.
- 1 - I modified `templates/mail/user/auth/register_notify.tmpl` so the mail no longer shows the generic `/user/login` URL and instead displays the personalized admin-access link directly under the username.
- 2 - I removed the trailing explanatory paragraph below that link to avoid repeating the same password-setup action twice in the same email.
113 - [2026-05-07 01:01:44] - v1.27.0-dev-104-g10495b7cd1 - Type: Modified - [user-settings] [sticky-layout] [appearance] [locale] [en] [ro] Reverted the global fixed-footer behavior and replaced it with a persistent per-user footer preference in `/user/settings/appearance`.
- 1 - I modified `templates/user/settings/appearance.tmpl`, `routers/web/user/setting/profile.go`, and `routers/web/web.go` to add a new footer section with a checkbox that saves whether the footer should stay visible at the bottom of the viewport for the current user.
- 2 - I modified `models/user/setting_options.go`, `routers/common/pagetmpl.go`, `templates/base/head.tmpl`, `modules/web/middleware/cookie.go`, `web_src/css/base.css`, and `web_src/css/home.css` so the preference is stored in `user_settings`, propagated into the page layout, and applied only when the `show-persistent-footer` body class is enabled.
- 3 - I modified `options/locale/locale_en-US.json`, `options/locale/locale_ro-RO.json`, and `models/user/setting_test.go` to add the new UI strings and a focused test covering the new persisted setting key.
114 - [2026-05-07 09:30:56] - v1.27.0-dev-105-gb3a7692ce9 - Type: Modified - [ui] [sticky-layout] Moved the persistent footer outside the page scroll area.
- 1 - I modified `web_src/css/base.css` so pages with `show-persistent-footer` stop scrolling the whole `body` and instead scroll the `.full.height` content container, keeping the footer in its own fixed viewport slot.
- 2 - I modified `web_src/css/home.css` so the persistent footer no longer overlays the page with `position: fixed`, but stays permanently visible as a non-scrolling sibling below the main content area.
115 - [2026-05-07 09:54:43] - v1.27.0-dev-106-g61a9e4bd06 - Type: Modified - [user-settings] [sticky-layout] [locale] [en] [ro] Added the persistent sticky side-menu preference and the finalized sidebar behavior for `/user/settings` and `/-/admin`.
- 1 - I modified `models/user/setting_options.go`, `routers/common/pagetmpl.go`, `templates/base/head.tmpl`, `routers/web/user/setting/profile.go`, `routers/web/web.go`, `templates/user/settings/appearance.tmpl`, `options/locale/locale_en-US.json`, `options/locale/locale_ro-RO.json`, and `models/user/setting_test.go` to add the persisted `ui.sticky_side_menus` preference, expose it to templates as `ShowStickySideMenus`, save it from `/user/settings/appearance`, document it in the UI, and cover it with a focused test.
- 2 - I modified `templates/user/settings/actions_general.tmpl` so `/user/settings/actions/general` passes the expected `pageClass` and participates in the same sticky-sidebar behavior as the other settings subpages.
- 3 - I modified `web_src/css/modules/flexcontainer.css` so, when the preference is enabled, the shared left menus on `/user/settings` and `/-/admin` use the current sticky layout: sticky positioning on the inner menu, `top: var(--page-spacing)`, footer-aware `max-height` handling for both persistent and non-persistent footer modes, hidden desktop scrollbars, green overflow hints, local menu scrolling, and the current `/user/settings` item padding.
- 4 - I modified `web_src/js/features/common-page.ts` so the sticky side menus update their overflow-hint classes dynamically as their scroll position, size, or expanded sections change.
116 - [2026-05-07 20:41:28] - v1.27.0-dev-106-g61a9e4bd06 - Type: Modified - [user-settings] [sticky-layout] [appearance] [locale] [en] [ro] Added a persistent navigation-bar preference in `/user/settings/appearance`.
- 1 - I modified `models/user/setting_options.go`, `models/user/setting_test.go`, `routers/common/pagetmpl.go`, `routers/web/user/setting/profile.go`, `routers/web/web.go`, `templates/base/head.tmpl`, `templates/user/settings/appearance.tmpl`, `options/locale/locale_en-US.json`, and `options/locale/locale_ro-RO.json` to add the persisted `ui.persistent_navbar` preference, expose it to templates as `ShowPersistentNavbar`, save it from `/user/settings/appearance`, and document it in the UI.
- 2 - I modified `web_src/css/modules/navbar.css` so the main `#navbar` becomes sticky at the top of the viewport when the new preference is enabled.
- 3 - I modified `web_src/css/modules/flexcontainer.css` so sticky side menus take the persistent navbar height into account on desktop, preventing the left menus from sliding underneath the navbar when both preferences are enabled.
117 - [2026-05-07 20:49:16] - v1.27.0-dev-106-g61a9e4bd06 - Type: Modified - [user-settings] [ui] [sticky-layout] Preserved the `/user/settings` left-menu scroll position across settings-page navigation.
- 1 - I modified `web_src/js/features/common-page.ts` so the sticky `/user/settings` menu saves its current `scrollTop` to `sessionStorage` while scrolling and immediately before clicking a menu link.
- 2 - I also made the same code restore that saved scroll position after the next settings page renders, keeping the left menu at the same viewport position when navigating between items and subitems.
118 - [2026-05-07 20:57:42] - v1.27.0-dev-106-g61a9e4bd06 - Type: Modified - [ui] [sticky-layout] Made the footer `Licenses` and `API` links open in a new browser tab and finalized the sticky `User Settings` header plus its top green scroll indicator.
- 1 - I modified `templates/base/footer_content.tmpl` so both footer links now use `target="_blank"` with `rel="noreferrer"`.
- 2 - I modified `web_src/css/modules/flexcontainer.css` so the `.header.item` at the top of the `/user/settings` sticky side menu now uses `position: sticky` inside the menu itself, with its own background and bottom separator.
- 3 - I modified `web_src/css/modules/flexcontainer.css` so, after making the `User Settings` header sticky, the top overflow hint is rendered on the bottom edge of that header and its gradient is drawn by a dedicated `::after` element extending into the scrollable area, while the menu container keeps only the bottom hint when both are active.
119 - [2026-05-07 21:14:11] - v1.27.0-dev-106-g61a9e4bd06 - Type: Modified - [ui] [sticky-layout] Made the `Admin Settings` menu header sticky while the admin left-menu options scroll.
- 1 - I modified `web_src/css/modules/flexcontainer.css` so the `.header.item` at the top of the `/-/admin` sticky side menu now uses the same sticky header treatment as `/user/settings`, with its own background and bottom separator.
- 2 - I modified `web_src/css/modules/flexcontainer.css` so the top green overflow indicator for `/-/admin` is also rendered on the bottom edge of the sticky header, with the gradient drawn by the same dedicated `::after` element used in `/user/settings`.
120 - [2026-05-07 21:31:18] - v1.27.0-dev-106-g61a9e4bd06 - Type: Modified - [user-settings] [ui] [sticky-layout] Preserved the `/user/settings` left-menu scroll position without the visible reset flicker during navigation.
- 1 - I modified `templates/user/settings/navbar.tmpl` to add a small inline restore hook around the menu markup, so a saved `scrollTop` is applied from `sessionStorage` before the menu becomes visible on the next settings page.
- 2 - I modified `web_src/css/modules/flexcontainer.css` so, while that inline restore is in progress, only the `/user/settings` left menu is temporarily hidden, preventing the brief flash of the menu reset at the top.
- 3 - I kept `web_src/js/features/common-page.ts` focused on saving the menu scroll position and refreshing the scroll indicators, removing the now-redundant late restore path from the global initializer.
121 - [2026-05-07 21:41:44] - v1.27.0-dev-106-g61a9e4bd06 - Type: Modified - [user-settings] [sticky-layout] Restored the agreed `/user/settings` sticky-menu item padding behavior.
- 1 - I also updated the same CSS so the `/user/settings` menu padding is applied at the item level inside `.ui.vertical.menu`, using `0.9em 1.14285714em` instead of relying on a menu-level spacing adjustment.
122 - [2026-05-07 22:11:06] - v1.27.0-dev-106-g61a9e4bd06 - Type: Modified - [user-settings] [ui] [sticky-layout] Restored the pre-`122` `/user/settings` layout baseline while keeping the current sticky-menu behavior.
- 1 - I modified `templates/user/settings/layout_head.tmpl` to return the settings page wrapper from `ui container fluid padded flex-container` to `ui container flex-container`.
- 2 - I restored the `/user/settings` menu to the same single scroll container structure used before, removing the ineffective inner-body split and keeping the inline restore hook in `templates/user/settings/navbar.tmpl`.
- 3 - I modified `web_src/css/modules/flexcontainer.css` so the `/user/settings` left menu remains temporarily hidden only during the inline scroll restore, keeps the `/user/settings`-only 24px non-persistent-footer bottom padding on the left navigation column, and supports the small `--sticky-side-menu-correction` transform without affecting admin pages.
- 4 - I kept the matching logic in `web_src/js/features/common-page.ts`, so the `/user/settings` menu still restores its saved scroll position after navigation, refreshes the green overflow indicators, and applies the modest runtime correction only when the sticky menu drifts slightly above its configured top offset.
123 - [2026-05-09 12:47:10] - v1.27.0-dev-114-gbb77e80bf5 - Type: Modified - [sticky-layout] Finalized the sticky side-menu bottom-edge behavior by compacting menu items and increasing the viewport reserve.
- 1 - I modified `web_src/css/modules/menu.css` so shared menu items now use `padding: 0.75em 1.14285714em`, reducing vertical item height across the sticky left menus.
- 2 - I modified `web_src/css/modules/flexcontainer.css` so the sticky side menus in both `/user/settings` and `/-/admin` now reserve `40px` instead of `24px` at the bottom of their `max-height` calculation for the non-persistent-footer case.
- 3 - This combination keeps the sticky menus from jumping upward at the bottom of the page scroll while preserving the current sticky headers, scroll hints, and `/user/settings` scroll-position restore behavior.
124 - [2026-05-09 15:31:52] - v1.27.0-dev-115-g06b7bd3ca1 - Type: Modified - [sticky-layout] Highlighted the active submenu entry with the standard active background color.
- 1 - I modified `web_src/css/modules/menu.css` so `.ui.vertical.menu .item .menu .active.item` now uses `background-color: var(--color-active)` instead of `transparent`.
- 2 - I kept the existing medium font weight and text color unchanged, so only the active submenu background treatment changed.
125 - [2026-05-09 15:56:47] - v1.27.0-dev-116-g8a0d319607 - Type: Added - [permissions-table] [locale] [en] [ro] Added column-wide Select all controls to the user access-token permissions table.
- 1 - I modified `templates/user/settings/applications.tmpl` to add a `Select all` row above the token-scope category rows, with per-column `All` radio buttons for No access, Read, and Write.
- 2 - I added `web_src/js/features/access-token-settings.ts` and registered it in `web_src/js/index.ts` so selecting one of those top-row radios automatically applies the matching permission choice to every category row in the same column.
- 3 - I added the `settings.select_all` locale string in both `options/locale/locale_en-US.json` and `options/locale/locale_ro-RO.json` for the new control row label.
- 4 - I extended the same `web_src/js/features/access-token-settings.ts` logic so each top-row `All` radio now becomes active only when every category row in its column is selected, becomes inactive when the column is no longer fully selected, and can still be reselected to apply that column choice to all rows again.
- 5 - I corrected the select-all synchronization fallback so no top-row radio stays selected when no permission column is fully matched, instead of incorrectly defaulting back to the `No access` column.
126 - [2026-05-09 17:16:12] - v1.27.0-dev-117-gab1135d1c6 - Type: Added - [permissions-table] Added header-level Select all controls to the shared Actions maximum-permissions table.
- 1 - I modified `templates/shared/actions/permissions_table.tmpl` to add a second header row with `Select all` on the left and per-column `All` radio controls for None, Read, and Write.
- 2 - I extended `web_src/js/features/common-actions-permissions.ts` so those header radios apply the chosen permission to every row in the table and stay synchronized bidirectionally with the current per-row selections.
- 3 - Because the change is implemented in the shared Actions permissions partial and its existing initializer, the same behavior now applies consistently to `/user/settings/actions/general` and the other pages that reuse that table.
127 - [2026-05-09 17:34:41] - v1.27.0-dev-118-g021f12509f - Type: Modified - [org-ui] [sticky-layout] Applied the shared sticky side-menu behavior to organization settings pages.
- 1 - I modified `web_src/css/modules/flexcontainer.css` so the same sticky left-menu layout, hidden scrollbar styling, sticky header behavior, and green overflow indicators used by user settings and admin pages now also apply to `.page-content.organization.settings`.
- 2 - I modified `web_src/js/features/common-page.ts` so organization settings menus participate in the shared sticky-menu overflow indicator logic.
- 3 - I modified `templates/org/settings/actions_general.tmpl` to pass `pageClass: "organization settings actions"` into the shared organization settings layout, so the Actions General page also matches the shared organization settings selectors.
128 - [2026-05-09 18:46:07] - v1.27.0-dev-120-g01e3eb1306 - Type: Added - [auth] [password-ui] [signup] [locale] [en] [ro] Added password visibility toggles to the login and signup forms.
- 1 - I modified `templates/user/auth/signin_inner.tmpl` to add an eye button beside the `/user/login` password field.
- 2 - I modified `templates/user/auth/signup_inner.tmpl` to add the same eye button beside the `/user/sign_up` password field and marked the `Confirm Password` field for toggle-aware behavior.
- 3 - I added `web_src/js/features/password-visibility.ts` and registered it in `web_src/js/index.ts` so the eye button toggles between hidden and visible password states.
- 4 - In the signup form, when password visibility is enabled, the script now hides the `Confirm Password` field, removes its `required` state, and keeps its value synchronized with the main password field; when visibility is disabled again, the field is shown and required again.
- 5 - I added `auth.show_password` and `auth.hide_password` locale strings in both `options/locale/locale_en-US.json` and `options/locale/locale_ro-RO.json` for the button tooltip and accessibility label.
- 6 - I corrected the login and signup password-toggle button templates so their `data-hide-label` attributes close the Go template expression properly, removing the template parsing error that prevented startup.
- 7 - I added `octicon-eye-closed` to `web_src/js/svg.ts`, fixing the runtime JavaScript error raised when the password toggle switched from the visible-eye icon to the hidden-eye icon.
129 - [2026-05-09 19:36:18] - v1.27.0-dev-121-gbfb584f161 - Type: Modified - [sticky-layout] [repo-settings] Applied the shared sticky side-menu behavior to repository settings pages.
- 1 - I modified `web_src/css/modules/flexcontainer.css` so the same sticky left-menu layout, hidden scrollbar styling, sticky header behavior, and green overflow indicators used by user settings, organization settings, and admin pages now also apply to `.page-content.repository.settings`.
- 2 - I modified `web_src/js/features/common-page.ts` so repository settings menus participate in the shared sticky-menu overflow indicator logic.
130 - [2026-05-09 20:07:36] - v1.27.0-dev-122-g652d3c20da - Type: Modified - [sticky-layout] [repo-actions] Applied the shared sticky side-menu behavior to repository Actions pages.
- 1 - I modified `templates/repo/actions/list.tmpl` to mark the workflow sidebar menu with a dedicated hook class for the shared sticky-menu initializer.
- 2 - I modified `web_src/css/modules/flexcontainer.css` so the same sticky left-menu layout, hidden scrollbar styling, and green overflow indicators now also apply to `.page-content.repository.actions`.
- 3 - I modified `web_src/js/features/common-page.ts` so the repository Actions sidebar participates in the shared sticky-menu overflow indicator logic.
- 4 - I refined the same CSS for repository Actions so the top green scroll hint is drawn directly on the menu container, because that sidebar has no `.header.item` for the shared header-based top-gradient treatment.
- 5 - I extended `templates/repo/actions/list.tmpl` with the same inline `sessionStorage` restore hook pattern used by `/user/settings`, so the repository Actions sidebar can restore its scroll position before becoming visible.
- 6 - I modified `web_src/css/modules/flexcontainer.css` so the repository Actions sidebar is temporarily hidden only during that inline restore step, preventing the visible reset flicker.
- 7 - I extended `web_src/js/features/common-page.ts` so the repository Actions sidebar now saves its own scroll position on scroll and before navigation clicks, using the dedicated `sticky-side-menu-scroll:repo-actions` session key.
131 - [2026-05-09 20:54:41] - v1.27.0-dev-123-g0f3876c0b1 - Type: Added - [repo-actions] Added pilot partial navigation for the repository Actions sidebar.
- 1 - I added `web_src/js/features/repo-actions-sidebar.ts` and registered it in `web_src/js/index.ts` to intercept plain left-click navigation on `/<user>/<repo>/actions` sidebar workflow links.
- 2 - The new client-side flow fetches the target page, replaces only the Actions page `.ui.container` content, updates `document.title`, and pushes the new URL into browser history instead of reloading the full page.
- 3 - The same logic also handles browser back/forward through `popstate`, keeping the pilot partial navigation limited to repository Actions pages.
- 4 - I extended the same pilot so, after each partial `.ui.container` swap, the repository Actions sidebar re-runs the shared sticky-menu indicator initializer on the new DOM, restoring the green overflow hints that disappeared after the first in-page navigation.
132 - [2026-05-09 21:10:27] - v1.27.0-dev-123-g0f3876c0b1 - Type: Modified - [scripts] [smart-build] Added an audio bell for interactive prompts in `smart-build.sh`.
- 1 - I added a small `notify_human_interaction()` helper to `smart-build.sh` that emits a terminal bell only when the script is running on an interactive terminal.
- 2 - I call that helper immediately before the build-load, architecture, and build-tags interactive menus, so the user gets an audible prompt exactly when human input is needed.
- 3 - I extended the same helper so VS Code and code-server terminals also get a high-visibility fallback banner when browser-controlled terminal bells do not produce an audible sound.
- 4 - I extended the same helper again to send a Linux desktop notification through `notify-send` before each interactive menu, while keeping the existing audio and terminal fallbacks for environments where no notification daemon is available.
133 - [2026-05-09 22:32:57] - v1.27.0-dev-125-g1525c9c8ee - Type: Modified - [auth] [password-ui] [signup] Finalized the manual-only password visibility toggle behavior for login and signup.
- 1 - I removed the static eye button from the login and signup templates and now create it from `web_src/js/features/password-visibility.ts` only when the current password value qualifies for manual reveal.
- 2 - The final reveal rules are now strict: prefilled or browser-autofilled passwords never show the eye, appending characters to an already non-empty password still keeps it hidden, and the eye appears only after a trusted manual empty-to-non-empty entry or a full manual replacement of a selected existing value.
- 3 - Once the eye has legitimately appeared, it stays visible through continued typing until the password is cleared again, preserves focus plus caret/selection on click, and keeps the signup confirm-password field synchronized while reveal mode is active.
- 4 - I converted the toggle into an overlaid control inside the password field, hid the browser-native reveal buttons, and kept the final transparent eye-button background styling that was adjusted manually in `web_src/css/user.css`.
134 - [2026-05-09 23:58:22] - v1.27.0-dev-125-g1525c9c8ee - Type: Modified - [build-artifacts] Ignored the local frontend hash artifact.
- 1 - I added `/.frontend.hash` to `.gitignore` so local frontend rebuild hash churn no longer appears in the repository working tree.
- 2 - I removed `.frontend.hash` from Git tracking with `git rm --cached`, so the ignore rule now fully suppresses future local hash churn instead of only affecting newly untracked copies.
135 - [2026-05-10 00:06:54] - v1.27.0-dev-125-g1525c9c8ee - Type: Modified - [user-settings] [appearance] Unified the persistent appearance toggles into a single settings group.
- 1 - I merged the top navigation bar, side menus, and footer persistence controls in `templates/user/settings/appearance.tmpl` into one shared `Persistent layout` section with a single Save button.
- 2 - I added `UpdatePersistentLayout` in `routers/web/user/setting/profile.go` and routed `/user/settings/appearance/layout` to save all three preferences in one request while preserving the footer cookie update.
- 3 - I added the `settings.persistent_layout` and `settings.persistent_layout_desc` locale strings and finalized the section markup so the shared description sits in its own `.field` container and each per-option help paragraph is separated with a `<br>` after the checkbox row.
136 - [2026-05-10 18:40:36] - v1.27.0-dev-125-g1525c9c8ee - Type: Added - [org-ui] [permissions-table] Added column-wide Select all controls to the organization team-units permissions table.
- 1 - I extended `templates/org/team/new.tmpl` so the team-units permissions table in `org/<team_name>/teams/new` gets the same header-level Select row used by the Actions permissions table, with `All` radios for none, read, and write.
- 2 - I extended `web_src/js/features/org-team.ts` to synchronize those header radios bidirectionally with the per-unit permission rows, while correctly ignoring globally disabled read/write cells when applying or computing a column-wide selection.
137 - [2026-05-10 19:02:14] - v1.27.0-dev-125-g1525c9c8ee - Type: Added - [installer] [password-ui] Added the password visibility toggle to the SMTP password field on the install page.
- 1 - I wrapped the `smtp_passwd` input in `templates/install.tmpl` with the same `js-password-toggle-group` used by login and signup, reusing the existing password-visibility initializer and show/hide labels so the install-page SMTP password field gets the same eye toggle behavior.
138 - [2026-05-10 19:08:32] - v1.27.0-dev-125-g1525c9c8ee - Type: Modified - [mailer] [installer] Enabled install-page email notifications by default for fresh setups.
- 1 - I updated `routers/install/install.go` so the install form defaults `mail_notify` to enabled when there is no existing mailer configuration and notify-mail was still unset, while preserving an explicit existing configuration during reinstall/edit scenarios.
139 - [2026-05-10 19:15:41] - v1.27.0-dev-125-g1525c9c8ee - Type: Added - [installer] [password-ui] Added the password visibility toggle and confirm-password behavior to the install-page super-admin password fields.
- 1 - I wrapped the install-page `admin_passwd` field in the same `js-password-toggle-group` used by signup and login, so the super-admin password now gets the same eye toggle UI and manual-entry reveal behavior.
- 2 - I wired the install-page `admin_confirm_passwd` field into the existing confirm-password flow, so revealing the admin password hides the confirm field and keeps it synchronized just like the signup form.
- 3 - I refined `web_src/js/features/password-visibility.ts` so confirm-field synchronization is opt-in per toggle group via explicit selectors, preventing the install-page SMTP password toggle from accidentally targeting the super-admin confirm field in the same form.
- 4 - I adjusted `web_src/css/install.css` so install-page password fields that use the overlaid eye wrapper keep the same 60% inline-field width as the original plain inputs instead of shrinking or stretching when the wrapper is present.
140 - [2026-05-10 19:22:04] - v1.27.0-dev-125-g1525c9c8ee - Type: Added - [installer] [password-ui] Added the password visibility toggle to the install-page database password field.
- 1 - I wrapped `db_passwd` in `templates/install.tmpl` with the same `js-password-toggle-group` used by the other install-page password fields, so the database password now gets the same eye control without changing its inline width or reusing any confirm-password logic.
141 - [2026-05-10 19:27:48] - v1.27.0-dev-125-g1525c9c8ee - Type: Added - [user-settings] [password-ui] Added the password visibility toggle and confirm-password behavior to `/user/settings/account`.
- 1 - I wrapped the `settings.new_password` field in `templates/user/settings/account.tmpl` with the shared `js-password-toggle-group`, reusing the existing eye-toggle logic and show/hide labels.
- 2 - I wired the `settings.retype_new_password` field into the existing confirm-password flow through dedicated selectors, so revealing the new password hides the confirm field and keeps it synchronized the same way as signup and the install-page super-admin password form.
142 - [2026-05-10 19:43:11] - v1.27.0-dev-125-g1525c9c8ee - Type: Added - [installer] [branding] Added optional custom branding uploads to the install page.
- 1 - I finalized the installer `Branding` section with optional uploads for `logo.svg`, `logo.png`, `loading.png`, `favicon.svg`, and `favicon.png`, including clear format/size guidance plus a shared-assets checkbox for using one SVG and one PNG upload for both logo and favicon.
- 2 - I implemented backend validation and persistence for all branding uploads in `routers/install/install.go` (expected type checks, 1 MB limit, square PNG with minimum 64x64) and save accepted overrides under `custom/public/assets/img/`.
- 3 - I completed the runtime behavior so uploaded branding files override built-in assets through layered serving, `logo.svg` is mirrored to `gitea.svg` for legacy lookups, post-install progress prefers a custom `loading.png`, and the shared-assets mode hides favicon fields while relabeling logo fields to `Logo & Favicon SVG/PNG`.
- 4 - I manually updated Romanian locale wording for the final branding texts and labels.
143 - [2026-05-12 00:02:10] - v1.27.0-dev-125-g1525c9c8ee - Type: Modified - [auth] [signup] [admin-created-user] [locale] [en] [ro] Finalized Register behavior for admin-created notification accounts without altering the invitation flow.
- 1 - I extended `POST /user/sign_up` in `routers/web/auth/auth.go` for existing active local accounts created by an admin when `username` and `email` match, while explicitly leaving pending admin invitations on their existing flow.
- 2 - If password is correct, the user is now authenticated into that existing account; when `MustChangePassword` is enabled, the flow redirects directly to `/user/settings/change_password`, otherwise it follows the normal post-auth redirect.
- 3 - If password is incorrect, the flow now redirects to `/user/forgot_password?email=<email>` and shows a warning to use account recovery plus check Spam/Junk.
- 4 - I added the locale key `auth.admin_notify_recover_password_spam_hint` in both `options/locale/locale_en-US.json` and `options/locale/locale_ro-RO.json`.
- 5 - I added regression tests in `routers/web/auth/auth_test.go` for normal sign-in, forced change-password redirect, wrong-password recovery redirect, and a guard that the admin-invitation flow still redirects to `/user/invitation`.
144 - [2026-05-12 00:47:20] - v1.27.0-dev-125-g1525c9c8ee - Type: Added - [user-settings] [password-ui] Added the password visibility toggle to `/user/settings/change_password`.
- 1 - I wrapped the forced-change password field in `templates/user/auth/change_passwd_inner.tmpl` with the shared `js-password-toggle-group`, reusing the existing eye-toggle logic and show/hide labels.
- 2 - I wired the confirm-password field into the existing toggle sync behavior so revealing the new password hides the confirm field and keeps it synchronized like the other password-update forms.
145 - [2026-05-12 01:16:50] - v1.27.0-dev-125-g1525c9c8ee - Type: Added - [installer] [app-ini-import] [locale] [en] [ro] Added installer support for importing an existing `app.ini`.
- 1 - I added an `Import Existing Configuration` section at the top of `templates/install.tmpl` with an `app.ini` upload control that imports automatically as soon as a file is selected, without a separate `Load app.ini` button.
- 2 - I kept the dedicated installer route `POST /import_app_ini` in `routers/install/routes.go`, but the page now posts to it via `fetch` and applies the imported values back into the existing form with `DOMParser`, so the browser is not visibly navigated to `/import_app_ini` and the page scripts are not re-executed.
- 3 - In `routers/install/install.go`, I factored the installer defaults into reusable helpers, added `app.ini` upload parsing with size/error handling, and mapped the imported config into the existing install form fields for database, general server paths, mailer, registration, OpenID, security, and admin policy settings.
- 4 - I added installer locale strings in both `options/locale/locale_en-US.json` and `options/locale/locale_ro-RO.json` for the new import UI, success message, and import errors, and the success flash now auto-dismisses after 5 seconds both on initial page load and after the AJAX import injects a new flash message.
- 5 - I added regression coverage in `routers/install/routes_test.go` for the new upload control and the config-to-form mapping behavior.
146 - [2026-05-12 01:30:10] - v1.27.0-dev-125-g1525c9c8ee - Type: Modified - [installer] [branding] Enabled shared branding assets by default in the installer.
- 1 - I updated `routers/install/install.go` so `BrandingUseSharedAssets` starts as enabled on the install form, making `Use the same logo files for favicon assets` checked by default.
147 - [2026-05-12 01:43:10] - v1.27.0-dev-125-g1525c9c8ee - Type: Added - [installer] [app-ini-import] [secrets] Added optional sensitive-secret import for installer `app.ini` uploads.
- 1 - I added an explicit installer checkbox for importing sensitive secrets from `app.ini` in `templates/install.tmpl`.
- 2 - I extended the installer form, submit pipeline, and final config writer so the optional import reuses `LFS_JWT_SECRET`, `INTERNAL_TOKEN`, and `oauth2.JWT_SECRET` from the uploaded `app.ini` instead of generating new values, including a submit-time fallback that re-reads the uploaded file if the checkbox was enabled after the first auto-import.
- 3 - I finalized secret resolution for both direct values and `LFS_JWT_SECRET_URI` / `INTERNAL_TOKEN_URI` / `JWT_SECRET_URI` file-based references, and added regression coverage for direct imports, URI-based imports, the real `POST /import_app_ini` flow, and the persisted `app.ini` output.
148 - [2026-05-12 22:44:38] - v1.27.0-dev-143-g512e577c3f - Type: Added - [scripts] [repo-sync] [rollback] Finalized the safe upstream update helper script as `.update-gitea.sh`.
- 1 - I renamed the updater to `.update-gitea.sh`, documented its purpose and ordered usage steps, including the explicit "dry-run has conflicts" path before any real sync, and added an interactive menu plus direct commands for `sync`, `dry-run`, `fetch`, `backup`, `status`, `list-backups`, `rollback`, `restore-stash`, `restore-snapshot`, and `clean-dry-run`.
- 2 - I hardened real update actions so they verify repository state, create or offer safety backup branches, retain the original pre-sync stash for rollback, and record the active restore metadata inside `.git`.
- 3 - I added exact worktree snapshots under `.git/.update-gitea-snapshots`, showed the latest/saved snapshot paths in `status`, and made `rollback` plus `restore-snapshot` restore the saved starting commit, the original local changes, and the exact worktree contents including untracked and ignored files while preserving a fresh safety snapshot of the state being replaced.
- 4 - I implemented a reusable dry-run workspace under `.git/.update-gitea-dry-run`, added cleanup for both that workspace and legacy temporary dry-run directories, and made dry-run collect and report all detected rebase conflict steps without modifying the real repository.
- 5 - I improved conflict reporting so package.json conflicts show the upstream scripts block, the conflicting commit side, and the current branch working-tree side, and the final dry-run summary now includes the total conflict-step count, the local commits that conflicted, and the unique conflicted files.
149 - [2026-05-13 00:05:18] - v1.27.0-dev-143-g512e577c3f - Type: Added - [scripts] [repo-sync] [cherry-pick] Added a dedicated safe upstream import helper based on `cherry-pick`.
- 1 - I added [`.import-upstream-cherry-pick.sh`](/config/workspace/gitea-dev/gitea/.import-upstream-cherry-pick.sh) as a separate helper that fetches upstream, lists importable upstream-only commits, and imports either selected commits or an inclusive upstream range through `git cherry-pick -x` so the imported commits keep a visible reference to the original upstream hashes.
- 2 - I gave the script the same safety model as the updater flow by creating a fresh backup branch, an exact worktree snapshot, and a saved tracked/untracked stash before every real import action, while recording the active restore metadata in `.git/.import-upstream-cherry-pick-state`.
- 3 - I added safe recovery commands for `continue`, `rollback`, `restore-stash`, and `restore-snapshot`, so interrupted or unwanted imports can be resumed or reverted back to the saved starting commit and exact worktree state, including untracked and ignored files.
- 4 - I added both command-line usage and an interactive menu for fetch, list, import, import-range, continue, backup, rollback, restore, and status workflows.
150 - [2026-05-13 00:18:42] - v1.27.0-dev-143-g512e577c3f - Type: Added - [scripts] [custom-release] [interactive] Added an interactive custom-release maintenance helper for stable patch lines.
- 1 - I added [`.maintain-custom-release.sh`](/config/workspace/gitea-dev/gitea/.maintain-custom-release.sh) to maintain a persistent custom branch such as `release/v1.26-custom`, starting from a base tag like `v1.26.0-rc0`, importing the missing upstream commits from the real upstream minor release branch such as `release/v1.26`, and then importing only the custom commits from a chosen local source branch.
- 2 - I made the helper interactive with a menu plus a guided `configure` step, so the base tag, upstream release branch, maintenance branch, custom source branch, upstream compare branch, and custom tag suffix can all be adjusted from prompts instead of only through environment variables, and I added automatic fallback from mistyped patch-style branch names like `release/v1.26.0` to the real upstream branch `release/v1.26` when it exists.
- 3 - I gave the script the same safety model as the other local Git helpers by creating a fresh backup branch, an exact worktree snapshot, and a saved tracked/untracked stash before every real import action, while also storing pending cherry-pick state so interrupted sequences can be continued.
- 4 - I added recovery commands for `continue`, `rollback`, `restore-stash`, and `restore-snapshot`, and a `tag` command that creates annotated custom release tags such as `v1.26.0-custom` on the maintained custom release branch.
151 - [2026-05-13 00:34:10] - v1.27.0-dev-143-g512e577c3f - Type: Modified - [scripts] [repo-sync] [fetch] Narrowed local upstream fetch scope and cleaned unused upstream tracking refs.
- 1 - I updated [`.update-gitea.sh`](/config/workspace/gitea-dev/gitea/.update-gitea.sh) and [`.import-upstream-cherry-pick.sh`](/config/workspace/gitea-dev/gitea/.import-upstream-cherry-pick.sh) so they fetch only the explicitly requested upstream branch instead of all upstream branches.
- 2 - I updated [`.maintain-custom-release.sh`](/config/workspace/gitea-dev/gitea/.maintain-custom-release.sh) so it fetches only the configured upstream release branch, the configured compare branch, and tags, while also normalizing mistaken patch-style release branch names like `release/v1.26.0` to the real upstream branch `release/v1.26`.
- 3 - I narrowed the local `remote.upstream.fetch` refspec to `upstream/main` and `upstream/release/v1.26`, then removed the other local `upstream/*` remote-tracking refs so Git Graph no longer shows the unused upstream branches by default.
152 - [2026-05-13 20:23:40] - v1.27.0-dev-143-g512e577c3f - Type: Modified - [scripts] [custom-release] [restore-points] Extended the custom-release maintenance helper with manual restore points and corrected its fetch and interactive configuration behavior.
- 1 - I updated [`.maintain-custom-release.sh`](/config/workspace/gitea-dev/gitea/.maintain-custom-release.sh) so it no longer auto-fetches upstream tags during release-branch synchronization, preventing patch tags like `v1.26.1` from being pulled in just because the release branch history was fetched.
- 2 - I added manual restore-point management commands for `create-restore-point`, `list-restore-points`, `restore-point`, and `delete-restore-point`, each backed by an exact worktree snapshot plus an associated backup branch stored under `.git/.maintain-custom-release-restore-points`.
- 3 - I integrated the new restore-point workflow into the interactive menu, the `help` text, and `status`, including support for restoring by full path or by the final restore-point directory name, automatically using the latest restore point for the current branch when no target is provided, recognizing the older manual restore points already stored under `.git/.manual-restore-points`, and fixing the interactive configuration prompts so they are shown correctly during `Edit configuration`.
153 - [2026-05-13 21:51:32] - v1.27.0-dev-143-g512e577c3f - Type: Modified - [scripts] [custom-release] [rollback] Finalized the custom-release maintenance helper workflow and recovery behavior.
- 1 - I made `bootstrap` a clean branch-creation step from `BASE_TAG`, separated fetch and sync into explicit compare/release-target/custom actions, added `UPSTREAM_RELEASE_TARGET_REF`, and updated the built-in help so the recommended workflow matches the current menu structure.
- 2 - I hardened recovery so rollback, restore-point, restore-snapshot, restore-stash, and restore-deletion correctly preserve or clean script-managed refs, maintenance branches, state files, backup branches, and snapshots, including rollback from the original entry branch after a bootstrap-created maintenance branch, cleanup of legacy restore-point leftovers, and removal of the correctly paired `backup/maint-*` Git Graph marker when a saved snapshot is deleted.
- 3 - I finalized the interactive UX by keeping a self-updating runtime copy in `/tmp`, persisting the last-used settings in `/tmp/.maintain-custom-release.env`, and reorganizing the menu into `Manual Backups >`, `Fetch upstreams >`, `Sync >`, `Rollback >`, and `Restore >` submenus, including `Delete Restore >` with numbered stash and snapshot selection, with numbered selections, `b`/`B` or `Enter` for Back, correct return-to-parent behavior from every submenu, and `0` for Exit.
154 - [2026-05-17 00:18:43] - v1.26.0-rc0-154-gfc98a14014 - Type: Fixed - [admin-users] [terminology] [locale] [en] [ro] Corrected the bootstrap-admin label from `GOOD` to `GOD`.
- 1 - I renamed the bootstrap admin actor label and the related immutable-account locale key from `good` to `god` in the admin grant helpers and admin users UI flow.
- 2 - I updated the admin API and admin-panel restriction messages, tests, and both English and Romanian locale strings so bootstrap-protected accounts are consistently labeled as `GOD`-granted.
- 3 - I updated the matching historical task descriptions in `.codex-history.md` so the earlier admin-policy entries now use the corrected `GOD` terminology.
155 - [2026-05-17 15:35:49] - v1.26.0-by-petru - Type: Fixed - [scripts] [custom-release] [release-target] Stopped release-target sync from requiring the remote release branch when an explicit target tag/ref is configured.
- 1 - I updated [`.maintain-custom-release.sh`](/config/workspace/gitea-dev/gitea/.maintain-custom-release.sh) so `Sync upstream release target commits` validates only the configured `UPSTREAM_RELEASE_TARGET_REF` when one is set, instead of still failing on a missing local `upstream/release/...` remote-tracking branch after successfully fetching a target tag such as `v1.26.1`.
156 - [2026-05-17 18:14:08] - v1.26.0-by-petru-24-gadb90b3453 - Type: Modified - [scripts] [smart-build] [artifacts] Renamed smart-build outputs to include the tag/ref and generated per-file SHA-256 checksums.
- 1 - I updated [`.smart-build.sh`](/config/workspace/gitea-dev/gitea/.smart-build.sh) so each build artifact is now written as `gitea-<tag-or-ref>-<os>-<platform><-sqlite>` with the original executable extension preserved, and each output also gets its own adjacent `.sha256` file generated with `sha256sum` or `shasum -a 256`.
157 - [2026-05-17 17:32:10] - v1.26.0-by-petru-23-g2d228475fc - Type: Fixed - [build] [versioning] Preserved custom tag names in `GITEA_VERSION` while keeping `git describe` build metadata.
- 1 - I updated `Makefile` so `GITEA_VERSION` now strips the leading `v`, preserves exact custom tag names such as `1.26.0-by-petru`, and converts only the trailing `-N-gSHA` suffix from `git describe` into `+N-gSHA` for in-between builds like `1.26.0-by-petru+3-g...` and `1.27.0-dev+143-g...`.
158 - [2026-05-17 22:20:35] - v1.26.0-by-petru - Type: Fixed - [admin-users] [delete-user] [fetch-action] Made the admin user-table trash action return fetch-compatible delete responses.
- 1 - I updated the `/-/admin/users` delete modal in the user table to submit an explicit inline fetch flag, and I changed the web admin `DeleteUser` handler so that this table-specific fetch flow now returns `JSONRedirect` on success and `JSONError` for expected validation failures, while the classic edit-page delete form keeps its normal redirect behavior; I also added integration coverage for the table delete path.
159 - [2026-05-17 00:21:37] - v1.26.0-by-petru - Type: Modified - [docs] [changelog] [github-links] Documented the custom `1.26.0-by petru & codex` release in `CHANGELOG.md`.
- 1 - I added the custom release reference and the dedicated `CUSTOM by petru & codex` release-notes block in `CHANGELOG.md`, summarizing the project-specific features and behavior changes shipped on top of upstream `1.26.0`.
- 2 - I updated `CHANGELOG.md` and `CHANGELOG-archived.md` so plain standalone references of the form `(#NNNNN)` and compound ampersand groups such as `(#NNNNN & #MMMMM)` now point directly to `https://github.com/
159 - [2026-05-17 17:13:47] - v1.26.0-by-petru - Type: Modified - [update] Added v1.26.1 original Gitea commits
160 - [2026-05-17 17:13:47] - v1.26.1-by-petru - Type: Modified - [docs] [changelog] [github-links] Added explicit GitHub links for the remaining bare PR references in `CHANGELOG.md` for the `v1.26.1-by-petru` release notes.
- 1 - I updated the remaining bare `#NNNNN` pull-request references in `CHANGELOG.md` so they now point directly to `https://github.com/go-gitea/gitea/pull/...`, without folding this tag-specific changelog cleanup into the earlier generic changelog-link conversion entry.
161 - [2026-05-19 21:31:45] - v1.27.0-dev-172-g3a6684178a - Type: Modified - [scripts] [smart-build] [darwin] Added macOS amd64/arm64 smart-build support, including SQLite-aware Docker-host handling for containerized workspaces.
- 1 - I updated `smart-build.sh` so its interactive architecture menu now offers `macos-amd64`, `macos-arm64`, and includes both Darwin targets in `All Arch`, while preserving the existing `darwin` artifact naming in `dist/`.
- 2 - I added a dedicated Darwin SQLite build path in `smart-build.sh` that routes macOS `bindata sqlite sqlite_unlock_notify` builds through `make release-darwin`, and I updated `Makefile` to make `release-darwin` configurable through `DARWIN_ARCHS` so helper scripts can request only `darwin-10.12/amd64` or `darwin-10.12/arm64`.
- 3 - I hardened the Darwin SQLite flow in `smart-build.sh` for `code-server`-style containerized workspaces by distinguishing between a missing Docker CLI and an unreachable Docker daemon, by validating that the host Docker daemon can see the same mounted repository `go.mod` path as the current workspace, and by moving the temporary release output under `dist/` instead of `/tmp`.
- 4 - I added `SMART_BUILD_DARWIN_HOST_REPO_PATH` support to `smart-build.sh` so Darwin SQLite builds can be redirected to a host-visible repository mount path when the interactive workspace path inside the container differs from the real host path used by the Docker daemon.
161 - [2026-05-19 23:43:29] - v1.27.0-dev-172-g06e5bd7f46 - Type: Modified - [scripts] [configure] [git-lfs] Added conditional Git LFS setup to `configure.sh` when repository LFS hooks are installed.
- 1 - I updated `.configure.sh` so repositories that already have Git LFS hook scripts in `.git/hooks` now treat `git-lfs` as a required dependency during verification, install the `git-lfs` system package on supported package managers, and run `git lfs install --local` during non-verify setup.
+337
View File
@@ -0,0 +1,337 @@
# Gitea Project Map for Codex
This file is the persistent implementation map for fast project orientation.
Use it after `./.codex-context.md` when a task needs architecture, flow, or extension-point context.
## 1. Fast Entry Points Index
- auth -> `routers/web/auth/`, `templates/user/auth/`, `services/auth/`
- installer -> `routers/install/`, `templates/install.tmpl`, `options/locale/`
- user settings UI -> `routers/web/user/setting/`, `templates/user/settings/`, `web_src/js/features/`, `web_src/css/modules/`
- sticky menus / persistent layout UI -> `templates/*/navbar*.tmpl`, `web_src/css/modules/menu.css`, `web_src/css/modules/flexcontainer.css`, `web_src/js/features/common-page.ts`
- repo settings / actions UI -> `routers/web/repo/`, `templates/repo/`, `templates/repo/settings/`
- admin UI -> `routers/web/admin/`, `templates/admin/`
- mail / notifications -> `services/mailer/`, `templates/mail/`, `routers/web/admin/`, `routers/web/auth/`
- custom release maintenance and repo-sync helpers -> `./.maintain-custom-release.sh`, `./.update-gitea.sh`, `./.import-upstream-cherry-pick.sh`, `./.codex-script-notes.md`
## 2. Repository Map
- Executable entry point: `main.go`
- CLI lifecycle and command startup: `cmd/`
- Installed-instance initialization and route-tree mounting: `routers/init.go`
- Web SSR routes: `routers/web/`
- API routes: `routers/api/`
- Request context, session, template data, response helpers: `services/context/`
- Business logic: `services/`
- Persistence and domain models: `models/`
- Cross-cutting infrastructure: `modules/`
- Server-side templates: `templates/`
- Browser-side frontend: `web_src/`
## 3. Bootstrap and Request Flow
### 2.1 Application Bootstrap
1. `main.go`
- Sets `setting.AppVer`, `setting.AppBuiltWith`, and `setting.AppStartTime`.
- Starts the CLI app through `cmd.NewMainApp(...)` and `cmd.RunMainApp(...)`.
2. `cmd/web.go`
- `newWebCommand()` defines the `web` command.
- `runWeb(...)` prepares graceful shutdown.
- `serveInstalled(...)` calls `routers.InitWebInstalled(...)` and then `routers.NormalRoutes()`.
3. `routers/init.go`
- `InitWebInstalled(...)` initializes Git, settings, storage, cache, DB, models, auth, indexers, webhooks, SSH, Actions, and cron.
- `NormalRoutes()` mounts:
- `/` -> `routers/web.Routes()`
- `/api/v1` -> public API
- `/api/internal` -> private API
- optional package and Actions API areas when enabled
### 2.2 Web Request Pipeline
1. `routers/web/web.go:Routes()`
- Builds the main web router.
- Exposes static assets, avatars, `robots.txt`, `metrics`, and `healthz`.
2. Core middleware
- `common.MustInitSessioner()` prepares the session.
- `context.Contexter()` builds the web context and template data.
- `newWebAuthMiddleware()` resolves optional or required authentication.
3. `services/context/`
- `NewBaseContext(...)` creates the base request context.
- `NewWebContext(...)` attaches `Doer`, `Repo`, `Org`, `Session`, `Flash`, and `PageData`.
- `Contexter()` injects global template and page data such as:
- `Link`
- `PageData`
- flash cookie
- `SystemConfig`
- shared template state
4. Auth and access validation
- `verifyAuthWithOptions(...)` enforces:
- `SignInRequired`
- `SignOutRequired`
- `AdminRequired`
- cross-origin rules
- inactive-user and forced-password-change constraints
5. Domain handler
- The request reaches `routers/web/...` or `routers/api/...`.
- Handlers should stay thin and delegate to `services/...`.
6. Business logic and persistence
- `services/...` orchestrate business rules.
- `models/...` read or write the DB and represent domain state.
- `modules/...` provide reusable infrastructure such as git, storage, cache, markup, logging, web helpers, SSH, and indexing.
7. Response
- Web:
- templates from `templates/...`
- optional page JS data for `web_src/js/...`
- API:
- JSON or file responses through helpers in `services/context/`
## 4. Authentication Map
### 3.1 Where Auth Routes Live
Auth routes are mainly declared in `routers/web/web.go`, especially around:
- `/user/login`
- `/user/sign_up`
- `/user/two_factor/...`
- `/user/webauthn/...`
- `/user/openid/...`
- `/login/oauth/...`
- `/user/settings/security/...`
- `/user/settings/applications/oauth2/...`
### 3.2 Key Auth Files
- `routers/web/auth/auth.go`
- classic login
- signup
- remember-cookie login
- post-login redirect
- branching toward 2FA or WebAuthn
- `routers/web/auth/password.go`
- forgot password
- reset password
- forced password change
- `routers/web/auth/2fa.go`
- TOTP
- scratch codes
- `routers/web/auth/webauthn.go`
- passkeys
- WebAuthn challenge/assertion flow
- `routers/web/auth/openid.go`
- OpenID sign-in
- connect
- register
- `routers/web/auth/oauth.go`
- OAuth2 / OIDC provider login start and callback
- link account
- auto-registration
- provider-data sync triggers
- `routers/web/auth/oauth_signin_sync.go`
- post-login provider-data synchronization
- `routers/web/auth/oauth2_provider.go`
- Gitea as an OAuth2 / OIDC provider
- authorize, access token, userinfo, introspection, JWKS
- `routers/web/auth/linkaccount.go`
- external-account linking to a local account
### 3.3 Classic Web Login Flow
1. Browser requests `/user/login`.
2. `context.Contexter()` prepares context and page data.
3. `newWebAuthMiddleware()` attempts authentication through available strategies:
- OAuth2 header/bearer where allowed
- Basic auth where allowed
- reverse-proxy auth if enabled
- session
- SSPI on Windows if enabled
4. `auth.SignIn` renders the page.
5. `POST /user/login` enters `auth.SignInPost`.
6. On success, the flow may:
- branch to 2FA
- branch to WebAuthn
- create a remember cookie
- redirect to `redirect_to` or the default target
7. Inactive, blocked, or forced-password-change users are stopped by auth logic or `verifyAuthWithOptions(...)`.
### 3.4 Auth Services and UI
- `services/auth/` contains reusable auth strategies such as:
- `Basic`
- `OAuth2`
- `Session`
- `ReverseProxy`
- `SSPI`
- Auth UI lives in `templates/user/auth/`
- Relevant browser-side auth code includes:
- `web_src/js/features/user-auth-webauthn.ts`
- `web_src/js/features/captcha.ts`
### 3.5 Where to Extend Auth
- New auth UI step:
- `routers/web/auth/...`
- `templates/user/auth/...`
- optional `web_src/js/features/...`
- New authentication rule or source:
- `services/auth/...`
- optionally `models/auth/...`
- integrate through `newWebAuthMiddleware()`
- New OAuth2/OIDC provider endpoint:
- `routers/web/auth/oauth2_provider.go`
- `services/oauth2_provider/...`
## 5. Change Entry Points
### 4.1 New Web Route
- Add handler in `routers/web/<domain>/`
- Register in `routers/web/web.go`
- If it has UI:
- template in `templates/...`
- optional JS/CSS in `web_src/...`
### 4.2 New API Route
- Add handler in `routers/api/v1/...` or the proper API subtree
- Mount through `routers/init.go` or the existing API router
- Use `services/context/` helpers for validation and response consistency
### 4.3 New Business Rule
- Orchestration in `services/<domain>/`
- Persistence in `models/<domain>/`
- Keep routing logic thin
### 4.4 New Template Data
- Put page-specific data in handlers or domain middleware
- Put global data there only if it is truly cross-cutting
- For data consumed by page JS, use `ctx.PageData`
### 4.5 New SSR Screen or UI Change
- Template in `templates/...`
- If client-side interaction is needed:
- logic in `web_src/js/features/...`
- styles in `web_src/css/...`
### 4.6 Global Navigation and Template Hooks
- Main top navigation:
- `templates/base/head_navbar.tmpl`
- Extra global links without rewriting the standard navbar:
- `templates/custom/`
- `custom/extra_links` hook in `templates/base/head_navbar.tmpl`
- Repository header and main repo tabs:
- `templates/repo/header.tmpl`
- Extra repo tabs without rewriting the standard header:
- `custom/extra_tabs` hook in `templates/repo/header.tmpl`
- Repo submenu areas:
- `templates/repo/navbar.tmpl`
- `templates/repo/sub_menu.tmpl`
### 4.7 User, Org, Repo, and Admin Areas
- Repo:
- `routers/web/repo/`
- `services/repository/`, `services/pull/`, `services/issue/`, `services/git/`
- `templates/repo/`
- User:
- `routers/web/user/`
- `routers/web/user/setting/`
- `services/user/`
- `templates/user/`
- `templates/user/settings/`
- Org:
- `routers/web/org/`
- `services/org/`
- `templates/org/`
- `templates/org/settings/`
- Admin:
- `routers/web/admin/`
- support often spans `models/`, `services/`, and `modules/setting/`
- `templates/admin/`
## 6. Frequent Task Shortcuts
- Login / signup / account recovery:
- `routers/web/auth/`
- `templates/user/auth/`
- `services/auth/`
- `models/auth/`
- `models/user/`
- User settings / security / applications:
- `routers/web/user/setting/`
- `templates/user/settings/`
- Repository header / tabs / page chrome:
- `templates/repo/header.tmpl`
- `templates/repo/navbar.tmpl`
- `templates/repo/sub_menu.tmpl`
- Top navigation / global links:
- `templates/base/head_navbar.tmpl`
- `templates/custom/`
- Packages:
- `routers/api/packages/`
- `services/packages/`
- `models/packages/`
- Actions:
- `routers/api/actions/`
- `routers/web/repo/actions/`
- `services/actions/`
- `models/actions/`
## 7. Technology and Validation Notes
- Backend: Go
- Server-side rendering: Go `.tmpl` templates
- Frontend: TypeScript
- Vue components exist in the repo
- Styling: CSS, Tailwind CSS, Fomantic UI
- Frontend verification tooling: Vitest, Playwright, ESLint, Stylelint
For area-specific validation:
- Go:
- `make fmt`
- `make lint-go`
- targeted Go tests
- TypeScript / frontend:
- `make lint-js`
- `make test-frontend` or targeted frontend tests when needed
- `go.mod` changes:
- `make tidy`
- targeted frontend tests when needed
- `go.mod` changes:
- `make tidy`
+62
View File
@@ -0,0 +1,62 @@
# Codex Script Notes
This file is a fast-reference companion for the large local helper scripts.
## `.maintain-custom-release.sh`
Purpose:
- maintain a custom stable branch such as `release/v1.26-custom`
- start from `BASE_TAG`
- fetch and sync upstream compare / release-target refs explicitly
- cherry-pick selected custom work from a local source branch
Current interaction model:
- interactive menu with submenus:
- `Manual Backups >`
- `Fetch upstreams >`
- `Sync >`
- `Rollback >`
- `Restore >`
- submenu navigation:
- `Enter` or `b` / `B` => Back
- `0` => Exit
Persistent runtime state:
- runtime copy: `/tmp/.maintain-custom-release.sh`
- persisted settings: `/tmp/.maintain-custom-release.env`
- restore points: `.git/.maintain-custom-release-restore-points/`
- snapshots: `.git/.maintain-custom-release-snapshots/`
- active state file: `.git/.maintain-custom-release-state`
Recommended order:
1. `Bootstrap maintenance branch`
2. `Fetch upstream/main compare ref`
3. `Fetch upstream release target ref`
4. `Show import plan`
5. `Sync` actions as needed
Important behavior:
- `bootstrap` should only create/switch the maintenance branch from `BASE_TAG`; it should not fetch automatically
- `rollback` should remove bootstrap-created maintenance branches and clean script-managed refs/artifacts
- deleting a saved exact snapshot should also remove its paired `backup/maint-*` Git Graph marker
## `.update-gitea.sh`
Purpose:
- safe upstream sync helper for the working tree
- create safety backups before real sync actions
- provide `dry-run`, `rollback`, `restore-stash`, and `restore-snapshot`
Key safety expectations:
- `dry-run` must not modify the real repository
- real sync actions must preserve enough state for exact rollback
## `.import-upstream-cherry-pick.sh`
Purpose:
- import upstream commits through `git cherry-pick -x`
- support commit-by-commit or range-based import
Key safety expectations:
- save backup branch, snapshot, and stash before real import actions
- support `continue`, `rollback`, `restore-stash`, and `restore-snapshot`
+61
View File
@@ -0,0 +1,61 @@
#!/usr/bin/env bash
set -euo pipefail
CALLBACK_URL="http://127.0.0.1:1455/auth/callback"
SUCCESS_URL="http://localhost:1455/success"
die() {
printf 'ERROR: %s\n' "$*" >&2
exit 1
}
extract_code() {
local input="$1"
case "$input" in
*code=*)
input="${input#*code=}"
input="${input%%&*}"
input="${input%%#*}"
;;
esac
printf '%s' "$input"
}
extract_id_token() {
local response_file="$1"
sed -n 's/.*id_token=\([^&[:space:]"'"'"'<>]*\).*/\1/p' "$response_file" |
tr -d '\r' |
head -n 1
}
printf 'Codex ChatGPT login helper\n'
printf 'Paste the received code, full callback URL, or query string containing code=...\n'
printf 'Received key: '
IFS= read -r received_key
[ -n "$received_key" ] || die "empty received key"
code="$(extract_code "$received_key")"
[ -n "$code" ] || die "could not extract code"
response_file="$(mktemp)"
trap 'rm -f "$response_file"' EXIT
printf '\nCalling Codex auth callback...\n'
curl -sv -H "Host: localhost" --get --data-urlencode "code=$code" "$CALLBACK_URL" >"$response_file" 2>&1 || {
cat "$response_file" >&2
die "callback request failed"
}
id_token="$(extract_id_token "$response_file")"
[ -n "$id_token" ] || {
cat "$response_file" >&2
die "could not find id_token in callback response"
}
printf 'id_token received. Completing login...\n'
curl -sv --get --data-urlencode "id_token=$id_token" "$SUCCESS_URL"
printf '\nDone.\n'
Executable
+722
View File
@@ -0,0 +1,722 @@
#!/usr/bin/env bash
set -Eeuo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
repo_go_version() {
sed -n 's/^go //p' "$SCRIPT_DIR/go.mod" 2>/dev/null | head -n 1
}
repo_node_version() {
sed -n 's/.*"node": ">= *\([^"]*\)".*/\1/p' "$SCRIPT_DIR/package.json" 2>/dev/null | head -n 1
}
repo_pnpm_version() {
sed -n 's/.*"packageManager": "pnpm@\([^"]*\)".*/\1/p' "$SCRIPT_DIR/package.json" 2>/dev/null | head -n 1
}
GO_VERSION="${GO_VERSION:-$(repo_go_version)}"
GO_VERSION="${GO_VERSION:-1.26.2}"
NODE_VERSION="${NODE_VERSION:-$(repo_node_version)}"
NODE_VERSION="${NODE_VERSION:-22.18.0}"
PNPM_VERSION="${PNPM_VERSION:-$(repo_pnpm_version)}"
PNPM_VERSION="${PNPM_VERSION:-10.33.0}"
NVM_VERSION="${NVM_VERSION:-v0.40.3}"
INSTALL_SYSTEM=1
INSTALL_GO=1
INSTALL_NODE=1
INSTALL_FRONTEND_DEPS=1
VERIFY_ONLY=0
WITH_CROSS_CGO=0
SHOW_MENU=0
VERIFY_REPORT_ONLY=0
VERIFY_HAD_ISSUES=0
usage() {
cat <<EOF
Usage: ./configure.sh [options]
Installs and configures the local build requirements for this Gitea tree.
Options:
--with-cross-cgo Also install/configure cross-CGO toolchains for
sqlite builds targeting linux/armv7 and windows/amd64.
This is useful for "All Arch" + sqlite builds, but it
downloads noticeably larger packages.
--skip-system Do not install system packages.
--skip-go Do not install Go.
--skip-node Do not install NVM/Node/pnpm.
--skip-frontend-deps Do not run pnpm install --frozen-lockfile.
--verify-only Only check the current environment.
--menu Show the interactive run menu.
-h, --help Show this help.
Environment overrides:
GO_VERSION=$GO_VERSION
NODE_VERSION=$NODE_VERSION
PNPM_VERSION=$PNPM_VERSION
NVM_VERSION=$NVM_VERSION
EOF
}
show_description() {
cat <<EOF
Gitea build environment setup
This script prepares the local machine for the Gitea build used in this tree.
It can install or verify:
- the required system build packages, including gcc, make, git, pkg-config,
and the SQLite/PAM libraries;
- git-lfs when this repository has Git LFS hooks installed;
- Go $GO_VERSION, as required by go.mod;
- Node $NODE_VERSION and pnpm $PNPM_VERSION, as required by package.json;
- frontend dependencies with pnpm install --frozen-lockfile;
- optional cross-CGO compilers for SQLite builds targeting linux/armv7
and windows/amd64.
For automated runs, you can keep using CLI options, for example:
./configure.sh --verify-only
./configure.sh --with-cross-cgo
EOF
}
interactive_menu() {
show_description
cat <<EOF
Select install mode:
1) Normal mode
2) With cross cgo
3) Verify only
4) Quit
EOF
# Install the standard requirements: system packages, Go, Node, pnpm, and frontend deps.
# Normal mode plus cross-CGO toolchains for multi-arch SQLite builds.
# Install nothing; only check the current environment.
while true; do
printf 'Choose option [1-4]: '
if ! read -r choice; then
die "No menu option selected."
fi
case "$choice" in
1)
printf 'Selected: Normal\n'
return
;;
2)
WITH_CROSS_CGO=1
printf 'Selected: With cross cgo\n'
return
;;
3)
VERIFY_ONLY=1
INSTALL_SYSTEM=0
INSTALL_GO=0
INSTALL_NODE=0
INSTALL_FRONTEND_DEPS=0
VERIFY_REPORT_ONLY=1
printf 'Selected: Verify only\n'
return
;;
4)
printf 'Canceled.\n'
exit 0
;;
*)
printf 'Invalid option: %s\n' "$choice"
;;
esac
done
}
log() {
printf '\n==> %s\n' "$*"
}
warn() {
printf 'WARNING: %s\n' "$*" >&2
}
die() {
printf 'ERROR: %s\n' "$*" >&2
exit 1
}
command_exists() {
command -v "$1" >/dev/null 2>&1
}
repo_has_git_lfs_hooks() {
local hook
for hook in pre-push post-checkout post-commit post-merge; do
[ -f "$SCRIPT_DIR/.git/hooks/$hook" ] || continue
if grep -q 'git-lfs' "$SCRIPT_DIR/.git/hooks/$hook"; then
return 0
fi
done
return 1
}
repo_requires_git_lfs() {
repo_has_git_lfs_hooks
}
run_as_root() {
if [ "$(id -u)" -eq 0 ]; then
"$@"
elif command_exists sudo; then
sudo "$@"
else
die "This step needs root privileges. Install sudo or run the script as root."
fi
}
fetch_to() {
local url="$1"
local output="$2"
if command_exists curl; then
curl -fL --retry 3 --retry-delay 2 -o "$output" "$url"
elif command_exists wget; then
wget -O "$output" "$url"
else
die "curl or wget is required to download $url"
fi
}
version_ge() {
local actual="$1"
local required="$2"
[ "$(printf '%s\n%s\n' "$required" "$actual" | sort -V | head -n 1)" = "$required" ]
}
append_profile_line() {
local file="$1"
local line="$2"
touch "$file"
if ! grep -qxF "$line" "$file"; then
printf '\n%s\n' "$line" >>"$file"
fi
}
ensure_go_path() {
activate_go_path
append_profile_line "$HOME/.profile" 'export PATH="/usr/local/go/bin:$HOME/go/bin:$PATH"'
append_profile_line "$HOME/.bashrc" 'export PATH="/usr/local/go/bin:$HOME/go/bin:$PATH"'
}
activate_go_path() {
export PATH="/usr/local/go/bin:$HOME/go/bin:$PATH"
}
install_system_packages() {
log "Installing system packages"
if command_exists apt-get; then
local -a packages=(
bash
build-essential
ca-certificates
coreutils
curl
findutils
gawk
git
gzip
libpam0g-dev
libsqlite3-dev
make
openssh-client
perl
pkg-config
python3
sed
sqlite3
tar
unzip
wget
xz-utils
zip
)
repo_requires_git_lfs && packages+=(git-lfs)
if [ "$WITH_CROSS_CGO" -eq 1 ]; then
packages+=(
gcc-arm-linux-gnueabihf
g++-arm-linux-gnueabihf
gcc-mingw-w64-x86-64
g++-mingw-w64-x86-64
)
fi
run_as_root apt-get update
run_as_root env DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}"
return
fi
if command_exists dnf; then
local -a packages=(
bash
ca-certificates
coreutils
curl
findutils
gawk
gcc
gcc-c++
git
gzip
make
openssh-clients
pam-devel
perl-core
pkgconf-pkg-config
python3
sed
sqlite
sqlite-devel
tar
unzip
wget
xz
zip
)
repo_requires_git_lfs && packages+=(git-lfs)
run_as_root dnf install -y "${packages[@]}"
[ "$WITH_CROSS_CGO" -eq 0 ] || warn "Cross-CGO package setup is only automated for apt-based systems."
return
fi
if command_exists yum; then
local -a packages=(
bash
ca-certificates
coreutils
curl
findutils
gawk
gcc
gcc-c++
git
gzip
make
openssh-clients
pam-devel
perl
pkgconfig
python3
sed
sqlite
sqlite-devel
tar
unzip
wget
xz
zip
)
repo_requires_git_lfs && packages+=(git-lfs)
run_as_root yum install -y "${packages[@]}"
[ "$WITH_CROSS_CGO" -eq 0 ] || warn "Cross-CGO package setup is only automated for apt-based systems."
return
fi
if command_exists pacman; then
local -a packages=(
base-devel
bash
ca-certificates
coreutils
curl
findutils
gawk
git
gzip
make
openssh
pam
perl
pkgconf
python
sed
sqlite
tar
unzip
wget
xz
zip
)
repo_requires_git_lfs && packages+=(git-lfs)
run_as_root pacman -Sy --needed --noconfirm "${packages[@]}"
[ "$WITH_CROSS_CGO" -eq 0 ] || warn "Cross-CGO package setup is only automated for apt-based systems."
return
fi
if command_exists zypper; then
local -a packages=(
bash
ca-certificates
coreutils
curl
findutils
gawk
gcc
gcc-c++
git
gzip
make
openssh
pam-devel
perl
pkg-config
python3
sed
sqlite3
sqlite3-devel
tar
unzip
wget
xz
zip
)
repo_requires_git_lfs && packages+=(git-lfs)
run_as_root zypper install -y "${packages[@]}"
[ "$WITH_CROSS_CGO" -eq 0 ] || warn "Cross-CGO package setup is only automated for apt-based systems."
return
fi
die "Unsupported package manager. Install git, make, gcc/g++, pkg-config, sqlite3 headers, curl/wget, tar, unzip, xz, python3, and then rerun with --skip-system."
}
go_download_arch() {
case "$(uname -m)" in
x86_64 | amd64)
printf 'amd64'
;;
aarch64 | arm64)
printf 'arm64'
;;
i386 | i686)
printf '386'
;;
armv6l | armv7l)
printf 'armv6l'
;;
*)
die "Unsupported CPU architecture for automatic Go install: $(uname -m)"
;;
esac
}
current_go_version() {
if command_exists go; then
go version | awk '{print $3}' | sed 's/^go//'
fi
}
install_go() {
log "Configuring Go $GO_VERSION"
ensure_go_path
if [ "$(current_go_version)" = "$GO_VERSION" ]; then
printf 'Go %s is already installed.\n' "$GO_VERSION"
return
fi
local arch
arch="$(go_download_arch)"
local archive="/tmp/go${GO_VERSION}.linux-${arch}.tar.gz"
local url="https://go.dev/dl/go${GO_VERSION}.linux-${arch}.tar.gz"
fetch_to "$url" "$archive"
run_as_root rm -rf /usr/local/go
run_as_root tar -C /usr/local -xzf "$archive"
ensure_go_path
[ "$(current_go_version)" = "$GO_VERSION" ] || die "Go install finished, but go version is not $GO_VERSION."
}
load_nvm() {
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
# shellcheck disable=SC1091
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
}
install_nvm() {
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
if [ -s "$NVM_DIR/nvm.sh" ]; then
load_nvm
return
fi
log "Installing NVM $NVM_VERSION"
local installer="/tmp/nvm-install-${NVM_VERSION}.sh"
fetch_to "https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_VERSION}/install.sh" "$installer"
bash "$installer"
load_nvm
command_exists nvm || die "NVM could not be loaded after installation."
}
current_node_version() {
if command_exists node; then
node -p 'process.versions.node'
fi
}
current_pnpm_version() {
if command_exists pnpm; then
pnpm --version
fi
}
install_node_and_pnpm() {
log "Configuring Node $NODE_VERSION and pnpm $PNPM_VERSION"
install_nvm
nvm install "$NODE_VERSION"
nvm alias default "$NODE_VERSION" >/dev/null
nvm use "$NODE_VERSION" >/dev/null
hash -r
if command_exists corepack; then
corepack enable
corepack prepare "pnpm@${PNPM_VERSION}" --activate
hash -r
fi
if ! command_exists pnpm || ! version_ge "$(current_pnpm_version)" "$PNPM_VERSION"; then
npm install -g "pnpm@${PNPM_VERSION}"
hash -r
fi
if ! version_ge "$(current_node_version)" "$NODE_VERSION"; then
die "Node $(current_node_version) is older than required $NODE_VERSION."
fi
if ! version_ge "$(current_pnpm_version)" "$PNPM_VERSION"; then
die "pnpm $(current_pnpm_version) is older than required $PNPM_VERSION."
fi
}
install_frontend_deps() {
log "Installing frontend dependencies"
cd "$SCRIPT_DIR"
pnpm install --frozen-lockfile
}
configure_git_lfs() {
repo_requires_git_lfs || return
log "Configuring Git LFS"
command_exists git-lfs || die "git-lfs is required for this repository but is not installed."
cd "$SCRIPT_DIR"
git lfs install --local >/dev/null
}
configure_cross_cgo() {
[ "$WITH_CROSS_CGO" -eq 1 ] || return
log "Configuring Makefile.local for cross-CGO sqlite builds"
cd "$SCRIPT_DIR"
if [ -f Makefile.local ] && grep -qF '# BEGIN configure.sh cross-cgo' Makefile.local; then
printf 'Makefile.local already contains configure.sh cross-CGO settings.\n'
return
fi
cat >>Makefile.local <<'EOF'
# BEGIN configure.sh cross-cgo
ifeq ($(GOOS)/$(GOARCH),windows/amd64)
CC := x86_64-w64-mingw32-gcc
CXX := x86_64-w64-mingw32-g++
export CC
export CXX
endif
ifeq ($(GOOS)/$(GOARCH)/$(GOARM),linux/arm/7)
CC := arm-linux-gnueabihf-gcc
CXX := arm-linux-gnueabihf-g++
export CC
export CXX
endif
# END configure.sh cross-cgo
EOF
}
verify_environment() {
log "Verifying build environment"
activate_go_path
load_nvm || true
hash -r
local -a missing=()
local -a problems=()
local command_name
for command_name in git make go node pnpm gcc pkg-config; do
if ! command_exists "$command_name"; then
missing+=("$command_name")
fi
done
if repo_requires_git_lfs && ! command_exists git-lfs; then
missing+=("git-lfs")
fi
if command_exists go; then
local found_go
found_go="$(current_go_version)"
[ "$found_go" = "$GO_VERSION" ] || problems+=("Go $found_go found, but $GO_VERSION is required.")
fi
if command_exists node; then
local found_node
found_node="$(current_node_version)"
version_ge "$found_node" "$NODE_VERSION" || problems+=("Node $found_node found, but >= $NODE_VERSION is required.")
fi
if command_exists pnpm; then
local found_pnpm
found_pnpm="$(current_pnpm_version)"
version_ge "$found_pnpm" "$PNPM_VERSION" || problems+=("pnpm $found_pnpm found, but >= $PNPM_VERSION is required.")
fi
cd "$SCRIPT_DIR"
if command_exists make && ! make help >/dev/null; then
problems+=("make help failed.")
fi
if [ "$WITH_CROSS_CGO" -eq 1 ]; then
for command_name in arm-linux-gnueabihf-gcc x86_64-w64-mingw32-gcc; do
if ! command_exists "$command_name"; then
missing+=("$command_name")
fi
done
fi
if [ ! -d "$SCRIPT_DIR/node_modules" ]; then
problems+=("node_modules is missing; frontend dependencies are not installed.")
fi
if [ "${#missing[@]}" -gt 0 ] || [ "${#problems[@]}" -gt 0 ]; then
VERIFY_HAD_ISSUES=1
if [ "${#missing[@]}" -gt 0 ]; then
printf '\nMissing commands:\n'
for command_name in "${missing[@]}"; do
printf ' - %s\n' "$command_name"
done
fi
if [ "${#problems[@]}" -gt 0 ]; then
printf '\nConfiguration issues:\n'
local problem
for problem in "${problems[@]}"; do
printf ' - %s\n' "$problem"
done
fi
printf '\nTo fix the standard build environment, run ./configure.sh and choose 1) Normal.\n'
printf 'For sqlite multi-arch builds, choose 2) With cross cgo.\n'
if [ "$VERIFY_REPORT_ONLY" -eq 1 ]; then
printf '\nVerify only completed; no changes were made.\n'
return 0
fi
return 1
fi
printf 'Go: %s\n' "$(go version)"
printf 'Node: %s\n' "$(node --version)"
printf 'pnpm: %s\n' "$(pnpm --version)"
printf 'gcc: %s\n' "$(gcc --version | head -n 1)"
if repo_requires_git_lfs; then
printf 'git-lfs: %s\n' "$(git lfs version)"
fi
if [ -d "$SCRIPT_DIR/node_modules" ]; then
printf 'node_modules: present\n'
else
printf 'node_modules: missing; run ./configure.sh or pnpm install --frozen-lockfile\n'
fi
}
if [ "$#" -eq 0 ] && [ -t 0 ]; then
SHOW_MENU=1
fi
while [ "$#" -gt 0 ]; do
case "$1" in
--with-cross-cgo)
WITH_CROSS_CGO=1
;;
--skip-system)
INSTALL_SYSTEM=0
;;
--skip-go)
INSTALL_GO=0
;;
--skip-node)
INSTALL_NODE=0
;;
--skip-frontend-deps)
INSTALL_FRONTEND_DEPS=0
;;
--verify-only)
VERIFY_ONLY=1
INSTALL_SYSTEM=0
INSTALL_GO=0
INSTALL_NODE=0
INSTALL_FRONTEND_DEPS=0
;;
--menu)
SHOW_MENU=1
;;
-h | --help)
usage
exit 0
;;
*)
usage
die "Unknown option: $1"
;;
esac
shift
done
if [ "$SHOW_MENU" -eq 1 ]; then
interactive_menu
fi
if [ "$(id -u)" -eq 0 ]; then
warn "You are running as root. NVM/Node will be configured for root, not for your normal user."
fi
if [ "$VERIFY_ONLY" -eq 0 ]; then
[ "$INSTALL_SYSTEM" -eq 0 ] || install_system_packages
configure_git_lfs
[ "$INSTALL_GO" -eq 0 ] || install_go
[ "$INSTALL_NODE" -eq 0 ] || install_node_and_pnpm
configure_cross_cgo
[ "$INSTALL_FRONTEND_DEPS" -eq 0 ] || install_frontend_deps
fi
verify_environment
if [ "$VERIFY_HAD_ISSUES" -eq 1 ]; then
cat <<EOF
Done. Missing requirements were reported above and no changes were made.
Run ./configure.sh again and choose:
1) Normal
For sqlite builds across all smart-build architectures, choose:
2) With cross cgo
EOF
else
cat <<EOF
Done.
Recommended next steps:
./smart-build.sh
For sqlite builds across all smart-build architectures, prepare the heavier
cross-CGO tools with:
./configure.sh --with-cross-cgo
EOF
fi
+1 -2
View File
@@ -13,14 +13,13 @@
"ghcr.io/devcontainers/features/git-lfs:1.2.5": {},
"ghcr.io/jsburckhardt/devcontainer-features/uv:1": {},
"ghcr.io/devcontainers/features/python:1": {
"version": "3.13"
"version": "3.14"
},
"ghcr.io/warrenbuckley/codespace-features/sqlite:1": {}
},
"customizations": {
"vscode": {
"settings": {},
// same extensions as Gitpod, should match /.gitpod.yml
"extensions": [
"editorconfig.editorconfig",
"dbaeumer.vscode-eslint",
+3
View File
@@ -74,6 +74,9 @@ cpu.out
/VERSION
/.air
/.go-licenses
/Dockerfile
/Dockerfile.rootless
/.venv
# Files and folders that were previously generated
/public/assets/img/webpack
+4
View File
@@ -25,6 +25,10 @@ insert_final_newline = false
[templates/user/auth/oidc_wellknown.tmpl]
indent_style = space
[templates/shared/actions/runner_badge_*.tmpl]
# editconfig lint requires these XML-like files to have charset defined, but the files don't have.
charset = unset
[Makefile]
indent_style = tab
+1
View File
@@ -0,0 +1 @@
34a58393847d8354e1a401512d0e56138e53bcae
+1
View File
@@ -8,3 +8,4 @@
/vendor/** -text -eol linguist-vendored
/web_src/js/vendor/** -text -eol linguist-vendored
Dockerfile.* linguist-language=Dockerfile
Makefile.* linguist-language=Makefile
+10
View File
@@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: github-actions
labels: [modifies/dependencies]
directory: /
schedule:
interval: daily
cooldown:
default-days: 5
+3 -5
View File
@@ -43,15 +43,13 @@ modifies/internal:
- ".editorconfig"
- ".eslintrc.cjs"
- ".golangci.yml"
- ".gitpod.yml"
- ".markdownlint.yaml"
- ".spectral.yaml"
- "stylelint.config.js"
- "stylelint.config.*"
- ".yamllint.yaml"
- ".github/**"
- ".gitea/**"
- ".devcontainer/**"
- "build.go"
- "build/**"
- "contrib/**"
@@ -85,9 +83,9 @@ docs-update-needed:
topic/code-linting:
- changed-files:
- any-glob-to-any-file:
- ".eslintrc.cjs"
- ".golangci.yml"
- ".markdownlint.yaml"
- ".spectral.yaml"
- ".yamllint.yaml"
- "stylelint.config.js"
- "eslint*.config.*"
- "stylelint.config.*"
+22
View File
@@ -0,0 +1,22 @@
name: cron-flake-updater
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * 0' # runs weekly on Sunday at 00:00
jobs:
nix-flake-update:
permissions:
contents: write
issues: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: DeterminateSystems/determinate-nix-action@v3
- uses: DeterminateSystems/update-flake-lock@main
with:
pr-title: "Update Nix flake"
pr-labels: |
dependencies
+5 -3
View File
@@ -9,16 +9,18 @@ jobs:
cron-licenses:
runs-on: ubuntu-latest
if: github.repository == 'go-gitea/gitea'
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
check-latest: true
- run: make generate-gitignore
timeout-minutes: 40
- name: push translations to repo
uses: appleboy/git-push-action@v0.0.3
uses: appleboy/git-push-action@v1.2.0
with:
author_email: "teabot@gitea.io"
author_name: GiteaBot
+5 -3
View File
@@ -9,9 +9,11 @@ jobs:
crowdin-pull:
runs-on: ubuntu-latest
if: github.repository == 'go-gitea/gitea'
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- uses: crowdin/github-action@v1
- uses: actions/checkout@v6
- uses: crowdin/github-action@v2
with:
upload_sources: true
upload_translations: false
@@ -27,7 +29,7 @@ jobs:
- name: update locales
run: ./build/update-locales.sh
- name: push translations to repo
uses: appleboy/git-push-action@v0.0.3
uses: appleboy/git-push-action@v1.2.0
with:
author_email: "teabot@gitea.io"
author_name: GiteaBot
+12 -3
View File
@@ -19,11 +19,15 @@ on:
value: ${{ jobs.detect.outputs.swagger }}
yaml:
value: ${{ jobs.detect.outputs.yaml }}
json:
value: ${{ jobs.detect.outputs.json }}
jobs:
detect:
runs-on: ubuntu-latest
timeout-minutes: 3
permissions:
contents: read
outputs:
backend: ${{ steps.changes.outputs.backend }}
frontend: ${{ steps.changes.outputs.frontend }}
@@ -33,9 +37,10 @@ jobs:
docker: ${{ steps.changes.outputs.docker }}
swagger: ${{ steps.changes.outputs.swagger }}
yaml: ${{ steps.changes.outputs.yaml }}
json: ${{ steps.changes.outputs.json }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
- uses: actions/checkout@v6
- uses: dorny/paths-filter@v4
id: changes
with:
filters: |
@@ -48,7 +53,7 @@ jobs:
- "Makefile"
- ".golangci.yml"
- ".editorconfig"
- "options/locale/locale_en-US.ini"
- "options/locale/locale_en-US.json"
frontend:
- "*.js"
@@ -80,6 +85,7 @@ jobs:
- "uv.lock"
docker:
- ".github/workflows/pull-docker-dryrun.yml"
- "Dockerfile"
- "Dockerfile.rootless"
- "docker/**"
@@ -98,3 +104,6 @@ jobs:
- "**/*.yaml"
- ".yamllint.yaml"
- "pyproject.toml"
json:
- "**/*.json"
+80 -31
View File
@@ -10,14 +10,18 @@ concurrency:
jobs:
files-changed:
uses: ./.github/workflows/files-changed.yml
permissions:
contents: read
lint-backend:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
check-latest: true
@@ -30,14 +34,18 @@ jobs:
if: needs.files-changed.outputs.templates == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v6
- run: uv python install 3.12
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v5
- uses: actions/checkout@v6
- uses: astral-sh/setup-uv@v8.0.0
- run: uv python install 3.14
- uses: pnpm/action-setup@v5
- uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- run: make deps-py
- run: make deps-frontend
- run: make lint-templates
@@ -46,23 +54,44 @@ jobs:
if: needs.files-changed.outputs.yaml == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v6
- run: uv python install 3.12
- uses: actions/checkout@v6
- uses: astral-sh/setup-uv@v8.0.0
- run: uv python install 3.14
- run: make deps-py
- run: make lint-yaml
lint-json:
if: needs.files-changed.outputs.json == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v5
- uses: actions/setup-node@v5
with:
node-version: 24
- run: make deps-frontend
- run: make lint-json
lint-swagger:
if: needs.files-changed.outputs.swagger == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v5
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v5
- uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- run: make deps-frontend
- run: make lint-swagger
@@ -70,9 +99,11 @@ jobs:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.frontend == 'true' || needs.files-changed.outputs.actions == 'true' || needs.files-changed.outputs.docs == 'true' || needs.files-changed.outputs.templates == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
check-latest: true
@@ -82,9 +113,11 @@ jobs:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
check-latest: true
@@ -99,9 +132,11 @@ jobs:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
check-latest: true
@@ -114,9 +149,11 @@ jobs:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
check-latest: true
@@ -127,12 +164,16 @@ jobs:
if: needs.files-changed.outputs.frontend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v5
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v5
- uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- run: make deps-frontend
- run: make lint-frontend
- run: make checks-frontend
@@ -143,9 +184,11 @@ jobs:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
check-latest: true
@@ -175,12 +218,16 @@ jobs:
if: needs.files-changed.outputs.docs == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v5
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v5
- uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- run: make deps-frontend
- run: make lint-md
@@ -188,9 +235,11 @@ jobs:
if: needs.files-changed.outputs.actions == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
check-latest: true
+25 -17
View File
@@ -10,11 +10,15 @@ concurrency:
jobs:
files-changed:
uses: ./.github/workflows/files-changed.yml
permissions:
contents: read
test-pgsql:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
services:
pgsql:
image: postgres:14
@@ -38,8 +42,8 @@ jobs:
ports:
- "9000:9000"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
check-latest: true
@@ -59,37 +63,39 @@ jobs:
RACE_ENABLED: true
TEST_TAGS: gogit
TEST_LDAP: 1
USE_REPO_TEST_DIR: 1
test-sqlite:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
check-latest: true
- run: make deps-backend
- run: make backend
- run: GOEXPERIMENT='' make backend
env:
TAGS: bindata gogit sqlite sqlite_unlock_notify
- name: run migration tests
run: make test-sqlite-migration
- name: run tests
run: make test-sqlite
run: GOEXPERIMENT='' make test-sqlite
timeout-minutes: 50
env:
TAGS: bindata gogit sqlite sqlite_unlock_notify
RACE_ENABLED: true
TEST_TAGS: gogit sqlite sqlite_unlock_notify
USE_REPO_TEST_DIR: 1
test-unit:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
services:
elasticsearch:
image: elasticsearch:7.5.0
@@ -124,8 +130,8 @@ jobs:
ports:
- 10000:10000
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
check-latest: true
@@ -142,7 +148,7 @@ jobs:
RACE_ENABLED: true
GITHUB_READ_TOKEN: ${{ secrets.GITHUB_READ_TOKEN }}
- name: unit-tests-gogit
run: make unit-test-coverage test-check
run: GOEXPERIMENT='' make unit-test-coverage test-check
env:
TAGS: bindata gogit
RACE_ENABLED: true
@@ -152,6 +158,8 @@ jobs:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
services:
mysql:
# the bitnami mysql image has more options than the official one, it's easier to customize
@@ -177,8 +185,8 @@ jobs:
- "587:587"
- "993:993"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
check-latest: true
@@ -196,13 +204,14 @@ jobs:
env:
TAGS: bindata
RACE_ENABLED: true
USE_REPO_TEST_DIR: 1
TEST_INDEXER_CODE_ES_URL: "http://elastic:changeme@elasticsearch:9200"
test-mssql:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
services:
mssql:
image: mcr.microsoft.com/mssql/server:2019-latest
@@ -217,8 +226,8 @@ jobs:
ports:
- 10000:10000
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
check-latest: true
@@ -234,4 +243,3 @@ jobs:
timeout-minutes: 50
env:
TAGS: bindata
USE_REPO_TEST_DIR: 1
+19 -14
View File
@@ -10,26 +10,31 @@ concurrency:
jobs:
files-changed:
uses: ./.github/workflows/files-changed.yml
permissions:
contents: read
regular:
if: needs.files-changed.outputs.docker == 'true' || needs.files-changed.outputs.actions == 'true'
container:
if: needs.files-changed.outputs.docker == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v5
- uses: actions/checkout@v6
- uses: docker/setup-qemu-action@v4
- uses: docker/setup-buildx-action@v4
- name: Build regular container image
uses: docker/build-push-action@v7
with:
context: .
platforms: linux/amd64,linux/arm64,linux/riscv64
push: false
tags: gitea/gitea:linux-amd64
rootless:
if: needs.files-changed.outputs.docker == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
steps:
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v5
cache-from: type=registry,ref=ghcr.io/go-gitea/gitea:buildcache-rootful
- name: Build rootless container image
uses: docker/build-push-action@v7
with:
context: .
push: false
platforms: linux/amd64,linux/arm64,linux/riscv64
file: Dockerfile.rootless
tags: gitea/gitea:linux-amd64
cache-from: type=registry,ref=ghcr.io/go-gitea/gitea:buildcache-rootless
+20 -12
View File
@@ -10,26 +10,34 @@ concurrency:
jobs:
files-changed:
uses: ./.github/workflows/files-changed.yml
permissions:
contents: read
test-e2e:
# the "test-e2e" won't pass, and it seems that there is no useful test, so skip
# if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.frontend == 'true' || needs.files-changed.outputs.actions == 'true'
if: false
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.frontend == 'true'
needs: files-changed
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
check-latest: true
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v5
- uses: pnpm/action-setup@v5
- uses: actions/setup-node@v6
with:
node-version: 24
- run: make deps-frontend frontend deps-backend
- run: pnpm exec playwright install --with-deps
- run: make test-e2e-sqlite
timeout-minutes: 40
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- run: make deps-frontend
- run: make frontend
- run: make deps-backend
- run: make gitea-e2e
- run: make playwright
- run: make test-e2e
timeout-minutes: 10
env:
USE_REPO_TEST_DIR: 1
FORCE_COLOR: 1
GITEA_TEST_E2E_DEBUG: 1
+1 -1
View File
@@ -15,6 +15,6 @@ jobs:
contents: read
pull-requests: write
steps:
- uses: actions/labeler@v5
- uses: actions/labeler@v6
with:
sync-labels: true
+53 -61
View File
@@ -11,19 +11,23 @@ concurrency:
jobs:
nightly-binary:
runs-on: namespace-profile-gitea-release-binary
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: actions/setup-go@v5
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
check-latest: true
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v5
- uses: pnpm/action-setup@v5
- uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- run: make deps-frontend deps-backend
# xgo build
- run: make release
@@ -31,7 +35,7 @@ jobs:
TAGS: bindata sqlite sqlite_unlock_notify
- name: import gpg key
id: import_gpg
uses: crazy-max/ghaction-import-gpg@v6
uses: crazy-max/ghaction-import-gpg@v7
with:
gpg_private_key: ${{ secrets.GPGSIGN_KEY }}
passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }}
@@ -48,7 +52,7 @@ jobs:
echo "Cleaned name is ${REF_NAME}"
echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT"
- name: configure aws
uses: aws-actions/configure-aws-credentials@v4
uses: aws-actions/configure-aws-credentials@v6
with:
aws-region: ${{ secrets.AWS_REGION }}
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
@@ -56,88 +60,76 @@ jobs:
- name: upload binaries to s3
run: |
aws s3 sync dist/release s3://${{ secrets.AWS_S3_BUCKET }}/gitea/${{ steps.clean_name.outputs.branch }} --no-progress
nightly-docker-rootful:
nightly-container:
runs-on: namespace-profile-gitea-release-docker
permissions:
contents: read
packages: write # to publish to ghcr.io
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/setup-qemu-action@v4
- uses: docker/setup-buildx-action@v4
- name: Get cleaned branch name
id: clean_name
run: |
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//')
echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT"
- uses: docker/metadata-action@v6
id: meta
with:
images: |-
gitea/gitea
ghcr.io/go-gitea/gitea
tags: |
type=raw,value=${{ steps.clean_name.outputs.branch }}
annotations: |
org.opencontainers.image.authors="maintainers@gitea.io"
- uses: docker/metadata-action@v6
id: meta_rootless
with:
images: |-
gitea/gitea
ghcr.io/go-gitea/gitea
# each tag below will have the suffix of -rootless
flavor: |
suffix=-rootless
tags: |
type=raw,value=${{ steps.clean_name.outputs.branch }}
annotations: |
org.opencontainers.image.authors="maintainers@gitea.io"
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GHCR using PAT
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: fetch go modules
run: make vendor
- name: build rootful docker image
uses: docker/build-push-action@v5
- name: build regular docker image
uses: docker/build-push-action@v7
with:
context: .
platforms: linux/amd64,linux/arm64,linux/riscv64
push: true
tags: |-
gitea/gitea:${{ steps.clean_name.outputs.branch }}
ghcr.io/go-gitea/gitea:${{ steps.clean_name.outputs.branch }}
nightly-docker-rootless:
runs-on: namespace-profile-gitea-release-docker
permissions:
packages: write # to publish to ghcr.io
steps:
- uses: actions/checkout@v4
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- name: Get cleaned branch name
id: clean_name
run: |
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//')
echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT"
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GHCR using PAT
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: fetch go modules
run: make vendor
tags: ${{ steps.meta.outputs.tags }}
annotations: ${{ steps.meta.outputs.annotations }}
cache-from: type=registry,ref=ghcr.io/go-gitea/gitea:buildcache-rootful
cache-to: type=registry,ref=ghcr.io/go-gitea/gitea:buildcache-rootful,mode=max
- name: build rootless docker image
uses: docker/build-push-action@v5
uses: docker/build-push-action@v7
with:
context: .
platforms: linux/amd64,linux/arm64
platforms: linux/amd64,linux/arm64,linux/riscv64
push: true
file: Dockerfile.rootless
tags: |-
gitea/gitea:${{ steps.clean_name.outputs.branch }}-rootless
ghcr.io/go-gitea/gitea:${{ steps.clean_name.outputs.branch }}-rootless
tags: ${{ steps.meta_rootless.outputs.tags }}
annotations: ${{ steps.meta_rootless.outputs.annotations }}
cache-from: type=registry,ref=ghcr.io/go-gitea/gitea:buildcache-rootless
cache-to: type=registry,ref=ghcr.io/go-gitea/gitea:buildcache-rootless,mode=max
+38 -50
View File
@@ -12,19 +12,23 @@ concurrency:
jobs:
binary:
runs-on: namespace-profile-gitea-release-binary
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: actions/setup-go@v5
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
check-latest: true
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v5
- uses: pnpm/action-setup@v5
- uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- run: make deps-frontend deps-backend
# xgo build
- run: make release
@@ -32,7 +36,7 @@ jobs:
TAGS: bindata sqlite sqlite_unlock_notify
- name: import gpg key
id: import_gpg
uses: crazy-max/ghaction-import-gpg@v6
uses: crazy-max/ghaction-import-gpg@v7
with:
gpg_private_key: ${{ secrets.GPGSIGN_KEY }}
passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }}
@@ -49,7 +53,7 @@ jobs:
echo "Cleaned name is ${REF_NAME}"
echo "branch=${REF_NAME}" >> "$GITHUB_OUTPUT"
- name: configure aws
uses: aws-actions/configure-aws-credentials@v4
uses: aws-actions/configure-aws-credentials@v6
with:
aws-region: ${{ secrets.AWS_REGION }}
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
@@ -58,7 +62,7 @@ jobs:
run: |
aws s3 sync dist/release s3://${{ secrets.AWS_S3_BUCKET }}/gitea/${{ steps.clean_name.outputs.branch }} --no-progress
- name: Install GH CLI
uses: dev-hanz-ops/install-gh-cli-action@v0.1.0
uses: dev-hanz-ops/install-gh-cli-action@v0.2.1
with:
gh-cli-version: 2.39.1
- name: create github release
@@ -66,18 +70,20 @@ jobs:
gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --draft --notes-from-tag dist/release/*
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
docker-rootful:
container:
runs-on: namespace-profile-gitea-release-docker
permissions:
contents: read
packages: write # to publish to ghcr.io
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/metadata-action@v5
- uses: docker/setup-qemu-action@v4
- uses: docker/setup-buildx-action@v4
- uses: docker/metadata-action@v6
id: meta
with:
images: |-
@@ -88,38 +94,10 @@ jobs:
# 1.2.3-rc0
tags: |
type=semver,pattern={{version}}
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GHCR using PAT
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: build rootful docker image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64,linux/riscv64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
docker-rootless:
runs-on: namespace-profile-gitea-release-docker
permissions:
packages: write # to publish to ghcr.io
steps:
- uses: actions/checkout@v4
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/metadata-action@v5
id: meta
annotations: |
org.opencontainers.image.authors="maintainers@gitea.io"
- uses: docker/metadata-action@v6
id: meta_rootless
with:
images: |-
gitea/gitea
@@ -131,23 +109,33 @@ jobs:
# 1.2.3-rc0
tags: |
type=semver,pattern={{version}}
annotations: |
org.opencontainers.image.authors="maintainers@gitea.io"
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GHCR using PAT
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: build rootless docker image
uses: docker/build-push-action@v5
- name: build regular container image
uses: docker/build-push-action@v7
with:
context: .
platforms: linux/amd64,linux/arm64,linux/riscv64
push: true
tags: ${{ steps.meta.outputs.tags }}
annotations: ${{ steps.meta.outputs.annotations }}
- name: build rootless container image
uses: docker/build-push-action@v7
with:
context: .
platforms: linux/amd64,linux/arm64,linux/riscv64
push: true
file: Dockerfile.rootless
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
tags: ${{ steps.meta_rootless.outputs.tags }}
annotations: ${{ steps.meta_rootless.outputs.annotations }}
+37 -48
View File
@@ -15,20 +15,23 @@ jobs:
binary:
runs-on: namespace-profile-gitea-release-binary
permissions:
contents: read
packages: write # to publish to ghcr.io
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: actions/setup-go@v5
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
check-latest: true
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v5
- uses: pnpm/action-setup@v5
- uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- run: make deps-frontend deps-backend
# xgo build
- run: make release
@@ -36,7 +39,7 @@ jobs:
TAGS: bindata sqlite sqlite_unlock_notify
- name: import gpg key
id: import_gpg
uses: crazy-max/ghaction-import-gpg@v6
uses: crazy-max/ghaction-import-gpg@v7
with:
gpg_private_key: ${{ secrets.GPGSIGN_KEY }}
passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }}
@@ -53,7 +56,7 @@ jobs:
echo "Cleaned name is ${REF_NAME}"
echo "branch=${REF_NAME}" >> "$GITHUB_OUTPUT"
- name: configure aws
uses: aws-actions/configure-aws-credentials@v4
uses: aws-actions/configure-aws-credentials@v6
with:
aws-region: ${{ secrets.AWS_REGION }}
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
@@ -62,7 +65,7 @@ jobs:
run: |
aws s3 sync dist/release s3://${{ secrets.AWS_S3_BUCKET }}/gitea/${{ steps.clean_name.outputs.branch }} --no-progress
- name: Install GH CLI
uses: dev-hanz-ops/install-gh-cli-action@v0.1.0
uses: dev-hanz-ops/install-gh-cli-action@v0.2.1
with:
gh-cli-version: 2.39.1
- name: create github release
@@ -70,18 +73,20 @@ jobs:
gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --notes-from-tag dist/release/*
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
docker-rootful:
container:
runs-on: namespace-profile-gitea-release-docker
permissions:
contents: read
packages: write # to publish to ghcr.io
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/metadata-action@v5
- uses: docker/setup-qemu-action@v4
- uses: docker/setup-buildx-action@v4
- uses: docker/metadata-action@v6
id: meta
with:
images: |-
@@ -96,36 +101,10 @@ jobs:
type=semver,pattern={{version}}
type=semver,pattern={{major}}
type=semver,pattern={{major}}.{{minor}}
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GHCR using PAT
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: build rootful docker image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64,linux/riscv64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
docker-rootless:
runs-on: namespace-profile-gitea-release-docker
steps:
- uses: actions/checkout@v4
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/metadata-action@v5
id: meta
annotations: |
org.opencontainers.image.authors="maintainers@gitea.io"
- uses: docker/metadata-action@v6
id: meta_rootless
with:
images: |-
gitea/gitea
@@ -142,23 +121,33 @@ jobs:
type=semver,pattern={{version}}
type=semver,pattern={{major}}
type=semver,pattern={{major}}.{{minor}}
annotations: |
org.opencontainers.image.authors="maintainers@gitea.io"
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GHCR using PAT
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: build rootless docker image
uses: docker/build-push-action@v5
- name: build regular container image
uses: docker/build-push-action@v7
with:
context: .
platforms: linux/amd64,linux/arm64,linux/riscv64
push: true
tags: ${{ steps.meta.outputs.tags }}
annotations: ${{ steps.meta.outputs.annotations }}
- name: build rootless container image
uses: docker/build-push-action@v7
with:
context: .
platforms: linux/amd64,linux/arm64,linux/riscv64
push: true
file: Dockerfile.rootless
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
tags: ${{ steps.meta_rootless.outputs.tags }}
annotations: ${{ steps.meta_rootless.outputs.annotations }}
+18 -10
View File
@@ -25,6 +25,9 @@ __debug_bin*
# Visual Studio
/.vs/
# mise version managment tool
mise.toml
*.cgo1.go
*.cgo2.c
_cgo_defun.c
@@ -52,6 +55,7 @@ cpu.out
*.log.*.gz
/gitea
/gitea-e2e
/gitea-vet
/debug
/integrations.test
@@ -64,13 +68,9 @@ cpu.out
/indexers
/log
/public/assets/img/avatar
/tests/e2e-output
/tests/integration/gitea-integration-*
/tests/integration/indexers-*
/tests/e2e/gitea-e2e-*
/tests/e2e/indexers-*
/tests/e2e/reports
/tests/e2e/test-artifacts
/tests/e2e/test-snapshots
/tests/*.ini
/tests/**/*.git/**/*.sample
/node_modules
@@ -79,6 +79,7 @@ cpu.out
/yarn-error.log
/npm-debug.log*
/.pnpm-store
/public/assets/.vite
/public/assets/js
/public/assets/css
/public/assets/fonts
@@ -86,10 +87,7 @@ cpu.out
/vendor
/VERSION
/.air
/.go-licenses
# Files and folders that were previously generated
/public/assets/img/webpack
# Snapcraft
/gitea_a*.txt
@@ -115,10 +113,20 @@ prime/
/.claude/
/.cursorrules
/.cursor/
# /.configure.sh
# /configure.sh
/.frontend.hash
# /.smart-build.sh
# /smart-build.sh
# /.update-gitea.sh
# /update-gitea.sh
/.goosehints
/.windsurfrules
/.github/copilot-instructions.md
/AGENT.md
/CLAUDE.md
/llms.txt
# Ignore worktrees when working on multiple branches
.worktrees/
# A Makefile for custom make targets
Makefile.local
-51
View File
@@ -1,51 +0,0 @@
tasks:
- name: Setup
init: |
cp -r contrib/ide/vscode .vscode
make deps
make build
command: |
gp sync-done setup
exit 0
- name: Run backend
command: |
gp sync-await setup
# Get the URL and extract the domain
url=$(gp url 3000)
domain=$(echo $url | awk -F[/:] '{print $4}')
if [ -f custom/conf/app.ini ]; then
sed -i "s|^ROOT_URL =.*|ROOT_URL = ${url}/|" custom/conf/app.ini
sed -i "s|^DOMAIN =.*|DOMAIN = ${domain}|" custom/conf/app.ini
sed -i "s|^SSH_DOMAIN =.*|SSH_DOMAIN = ${domain}|" custom/conf/app.ini
sed -i "s|^NO_REPLY_ADDRESS =.*|SSH_DOMAIN = noreply.${domain}|" custom/conf/app.ini
else
mkdir -p custom/conf/
echo -e "[server]\nROOT_URL = ${url}/" > custom/conf/app.ini
echo -e "\n[database]\nDB_TYPE = sqlite3\nPATH = $GITPOD_REPO_ROOT/data/gitea.db" >> custom/conf/app.ini
fi
export TAGS="sqlite sqlite_unlock_notify"
make watch-backend
- name: Run frontend
command: |
gp sync-await setup
make watch-frontend
openMode: split-right
vscode:
extensions:
- editorconfig.editorconfig
- dbaeumer.vscode-eslint
- golang.go
- stylelint.vscode-stylelint
- DavidAnson.vscode-markdownlint
- Vue.volar
- ms-azuretools.vscode-docker
- vitest.explorer
- cweijan.vscode-database-client2
- GitHub.vscode-pull-request-github
ports:
- name: Gitea
port: 3000
+15 -19
View File
@@ -6,15 +6,19 @@ linters:
default: none
enable:
- bidichk
- bodyclose
- depguard
- dupl
- errcheck
- forbidigo
- gocheckcompilerdirectives
- gocritic
- govet
- ineffassign
- mirror
- modernize
- nakedret
- nilnil
- nolintlint
- perfsprint
- revive
@@ -45,6 +49,8 @@ linters:
desc: do not use the ini package, use gitea's config system instead
- pkg: gitea.com/go-chi/cache
desc: do not use the go-chi cache package, use gitea's cache system
- pkg: github.com/pkg/errors
desc: use builtin errors package instead
nolintlint:
allow-unused: false
require-explanation: true
@@ -55,38 +61,28 @@ linters:
disabled-checks:
- ifElseChain
- singleCaseSwitch # Every time this occurred in the code, there was no other way.
- deprecatedComment # conflicts with go-swagger comments
revive:
severity: error
rules:
- name: atomic
- name: bare-return
- name: blank-imports
- name: constant-logical-expr
- name: context-as-argument
- name: context-keys-type
- name: dot-imports
- name: duplicated-imports
- name: empty-lines
- name: error-naming
- name: error-return
- name: error-strings
- name: errorf
- name: exported
- name: identical-branches
- name: if-return
- name: increment-decrement
- name: indent-error-flow
- name: modifies-value-receiver
- name: package-comments
- name: range
- name: receiver-naming
- name: redefines-builtin-id
- name: string-of-int
- name: superfluous-else
- name: time-naming
- name: unconditional-recursion
- name: unexported-return
- name: unreachable-code
- name: var-declaration
- name: var-naming
arguments:
@@ -107,6 +103,12 @@ linters:
- require-error
usetesting:
os-temp-dir: true
perfsprint:
concat-loop: false
govet:
enable:
- nilness
- unusedwrite
exclusions:
generated: lax
presets:
@@ -118,16 +120,12 @@ linters:
- linters:
- dupl
- errcheck
- gocyclo
- gosec
- staticcheck
- unparam
path: _test\.go
- linters:
- dupl
- errcheck
- gocyclo
- gosec
path: models/migrations/v
- linters:
- forbidigo
@@ -139,12 +137,8 @@ linters:
- gocritic
text: (?i)`ID' should not be capitalized
- linters:
- deadcode
- unused
text: (?i)swagger
- linters:
- staticcheck
text: (?i)argument x is overwritten before first use
- linters:
- gocritic
text: '(?i)commentFormatting: put a space between `//` and comment text'
@@ -153,6 +147,7 @@ linters:
text: '(?i)exitAfterDefer:'
paths:
- node_modules
- .venv
- public
- web_src
- third_party$
@@ -172,6 +167,7 @@ formatters:
generated: lax
paths:
- node_modules
- .venv
- public
- web_src
- third_party$
+894
View File
@@ -0,0 +1,894 @@
#!/usr/bin/env bash
set -euo pipefail
# This script safely imports selected upstream commits onto the current local
# branch through cherry-pick.
# It:
# 1. checks that no conflicting git operation is already in progress;
# 2. ensures the upstream remote exists and points to the official repository;
# 3. lists upstream commits whose changes are not yet present on the current
# branch;
# 4. creates a safety backup branch and an exact worktree snapshot;
# 5. stashes tracked and untracked local changes before the import;
# 6. cherry-picks the selected upstream commits with `-x` so the original
# upstream commit hash remains visible in the imported commit message;
# 7. restores the stashed local changes only after the import completes.
# If a conflict happens, the backup branch, the exact snapshot, and the saved
# stash are all kept so the original state can be restored safely.
BRANCH="${BRANCH:-main}"
REMOTE_NAME="${REMOTE_NAME:-upstream}"
REMOTE_URL="${REMOTE_URL:-https://github.com/go-gitea/gitea.git}"
REPO_ROOT=""
GIT_DIR=""
STATE_FILE=""
SNAPSHOT_ROOT=""
CURRENT_BRANCH=""
BACKUP_BRANCH=""
STASH_REF=""
STASH_HASH=""
STATE_BRANCH=""
STATE_BACKUP_BRANCH=""
STATE_STASH_HASH=""
STATE_REMOTE_NAME=""
STATE_REMOTE_URL=""
STATE_TARGET_BRANCH=""
STATE_START_HEAD=""
STATE_SNAPSHOT_PATH=""
STATE_IMPORT_COMMITS=""
STATE_STATUS=""
STATE_UPDATED_AT=""
say() {
printf '%s\n' "$*"
}
die() {
say "ERROR: $*" >&2
exit 1
}
show_usage() {
cat <<EOF
Usage: $(basename "$0") [command]
Available commands:
fetch
Fetch the latest upstream changes only.
list
Show upstream commits whose changes are not yet present on the current branch.
import <commit> [commit...]
Cherry-pick one or more selected upstream commits with \`-x\`.
import-range <from-commit> <to-commit>
Cherry-pick an inclusive upstream commit range in upstream order.
continue
Continue an interrupted cherry-pick and restore the saved local stash once the import finishes.
backup
Create a safety backup branch from the current HEAD only.
rollback [backup-branch|snapshot-dir]
Restore the saved pre-import state, or an explicit backup branch / snapshot.
restore-stash
Re-apply the saved pre-import local stash from the last recorded import state.
restore-snapshot [snapshot-dir]
Restore the exact saved repository snapshot from the last recorded real action, or from a specific snapshot directory.
status
Show the current repository, branch, remote, local-change state, and saved import metadata.
help
Show this help text.
If no command is provided and the script is run from a terminal, an interactive
menu is shown.
Recommended order:
1. Run: ./.import-upstream-cherry-pick.sh status
2. Run: ./.import-upstream-cherry-pick.sh list
3. Choose the exact upstream commits you want to import.
4. Run: ./.import-upstream-cherry-pick.sh import <commit...>
or: ./.import-upstream-cherry-pick.sh import-range <from> <to>
5. If cherry-pick stops with conflicts:
- either resolve them and continue with: ./.import-upstream-cherry-pick.sh continue
- or return safely with: ./.import-upstream-cherry-pick.sh rollback
6. If restoring local changes after the import causes conflicts:
- either resolve them manually
- or return safely with: ./.import-upstream-cherry-pick.sh rollback
7. Use: ./.import-upstream-cherry-pick.sh restore-snapshot
when you want to restore the exact saved repository state, including
untracked and ignored files that existed at snapshot time.
EOF
}
ensure_git_repo() {
local raw_git_dir
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)" || die "This script must be run inside a git repository."
raw_git_dir="$(git rev-parse --git-dir)"
case "$raw_git_dir" in
/*) GIT_DIR="$raw_git_dir" ;;
*) GIT_DIR="$REPO_ROOT/$raw_git_dir" ;;
esac
STATE_FILE="$GIT_DIR/.import-upstream-cherry-pick-state"
SNAPSHOT_ROOT="$GIT_DIR/.import-upstream-cherry-pick-snapshots"
}
write_state() {
{
printf 'STATE_BRANCH=%q\n' "$STATE_BRANCH"
printf 'STATE_BACKUP_BRANCH=%q\n' "$STATE_BACKUP_BRANCH"
printf 'STATE_STASH_HASH=%q\n' "$STATE_STASH_HASH"
printf 'STATE_REMOTE_NAME=%q\n' "$STATE_REMOTE_NAME"
printf 'STATE_REMOTE_URL=%q\n' "$STATE_REMOTE_URL"
printf 'STATE_TARGET_BRANCH=%q\n' "$STATE_TARGET_BRANCH"
printf 'STATE_START_HEAD=%q\n' "$STATE_START_HEAD"
printf 'STATE_SNAPSHOT_PATH=%q\n' "$STATE_SNAPSHOT_PATH"
printf 'STATE_IMPORT_COMMITS=%q\n' "$STATE_IMPORT_COMMITS"
printf 'STATE_STATUS=%q\n' "$STATE_STATUS"
printf 'STATE_UPDATED_AT=%q\n' "$(date +%Y-%m-%dT%H:%M:%S)"
} >"$STATE_FILE"
}
load_state() {
ensure_git_repo
[ -f "$STATE_FILE" ] || return 1
# shellcheck disable=SC1090
. "$STATE_FILE"
return 0
}
worktree_has_local_changes() {
! git diff --quiet || ! git diff --cached --quiet || [ -n "$(git ls-files --others --exclude-standard)" ]
}
has_cherry_pick_in_progress() {
[ -e "$(git rev-parse --git-path CHERRY_PICK_HEAD)" ]
}
sanitize_ref_name() {
printf '%s\n' "${1//\//-}"
}
ensure_rsync_available() {
command -v rsync >/dev/null 2>&1 || die "rsync is required for exact repository snapshots."
}
snapshot_repo_dir() {
printf '%s\n' "$1/repo"
}
is_valid_snapshot_dir() {
[ -d "$1" ] && [ -d "$(snapshot_repo_dir "$1")" ]
}
snapshot_metadata_value() {
local snapshot_dir="$1" key="$2"
[ -f "$snapshot_dir/metadata.txt" ] || return 1
sed -n "s/^${key}=//p" "$snapshot_dir/metadata.txt" | head -n 1
}
create_worktree_snapshot_for_reason() {
local reason="$1" safe_branch_name timestamp snapshot_dir snapshot_dir_repo
ensure_rsync_available
safe_branch_name="$(sanitize_ref_name "$CURRENT_BRANCH")"
timestamp="$(date +%Y%m%d-%H%M%S)"
snapshot_dir="$SNAPSHOT_ROOT/$safe_branch_name/${timestamp}-${reason}"
snapshot_dir_repo="$(snapshot_repo_dir "$snapshot_dir")"
mkdir -p "$snapshot_dir_repo"
rsync --archive --delete --exclude='.git' "$REPO_ROOT"/ "$snapshot_dir_repo"/
{
printf 'branch=%s\n' "$CURRENT_BRANCH"
printf 'head=%s\n' "$(git rev-parse HEAD)"
printf 'created_at=%s\n' "$(date +%Y-%m-%dT%H:%M:%S)"
printf 'reason=%s\n' "$reason"
} >"$snapshot_dir/metadata.txt"
printf '%s\n' "$snapshot_dir"
}
restore_worktree_snapshot() {
local snapshot_dir="$1" snapshot_dir_repo
ensure_rsync_available
is_valid_snapshot_dir "$snapshot_dir" || die "Snapshot directory '$snapshot_dir' is not valid."
snapshot_dir_repo="$(snapshot_repo_dir "$snapshot_dir")"
rsync --archive --delete --exclude='.git' "$snapshot_dir_repo"/ "$REPO_ROOT"/
}
find_latest_snapshot_for_current() {
local safe_branch_name snapshot_branch_dir
safe_branch_name="$(sanitize_ref_name "$CURRENT_BRANCH")"
snapshot_branch_dir="$SNAPSHOT_ROOT/$safe_branch_name"
[ -d "$snapshot_branch_dir" ] || return 1
find "$snapshot_branch_dir" -mindepth 1 -maxdepth 1 -type d | sort -r | head -n 1
}
ensure_no_noncherrypick_git_operation_in_progress() {
local git_path
for git_path in MERGE_HEAD REVERT_HEAD BISECT_LOG rebase-merge rebase-apply; do
if [ -e "$(git rev-parse --git-path "$git_path")" ]; then
die "A git operation is already in progress ($git_path). Finish it before running this script."
fi
done
}
ensure_no_git_operation_in_progress() {
local git_path
for git_path in CHERRY_PICK_HEAD MERGE_HEAD REVERT_HEAD BISECT_LOG rebase-merge rebase-apply; do
if [ -e "$(git rev-parse --git-path "$git_path")" ]; then
die "A git operation is already in progress ($git_path). Finish it before running this script."
fi
done
if [ -n "$(git diff --name-only --diff-filter=U)" ]; then
die "There are unmerged files in the working tree. Resolve them first."
fi
}
ensure_current_branch() {
CURRENT_BRANCH="$(git symbolic-ref --quiet --short HEAD || true)"
[ -n "$CURRENT_BRANCH" ] || die "Detached HEAD is not supported. Check out a branch first."
}
ensure_current_branch_with_state_fallback() {
CURRENT_BRANCH="$(git symbolic-ref --quiet --short HEAD || true)"
if [ -n "$CURRENT_BRANCH" ]; then
return
fi
if load_state && [ -n "${STATE_BRANCH:-}" ]; then
CURRENT_BRANCH="$STATE_BRANCH"
return
fi
die "Detached HEAD is not supported here and no saved branch state was found."
}
ensure_upstream_remote() {
local current_remote_url
if current_remote_url="$(git remote get-url "$REMOTE_NAME" 2>/dev/null)"; then
if [ "$current_remote_url" != "$REMOTE_URL" ]; then
die "Remote '$REMOTE_NAME' points to '$current_remote_url', expected '$REMOTE_URL'."
fi
return
fi
say "Adding remote '$REMOTE_NAME'..."
git remote add "$REMOTE_NAME" "$REMOTE_URL"
}
create_backup_branch_for_reason() {
local reason="$1" safe_branch_name timestamp branch_name
safe_branch_name="$(sanitize_ref_name "$CURRENT_BRANCH")"
timestamp="$(date +%Y%m%d-%H%M%S)"
branch_name="backup/cherry-pick-${safe_branch_name}-${reason}-${timestamp}"
git branch "$branch_name" HEAD >/dev/null
printf '%s\n' "$branch_name"
}
find_latest_backup_branch_for_current() {
local safe_branch_name
safe_branch_name="$(sanitize_ref_name "$CURRENT_BRANCH")"
git for-each-ref --sort=-creatordate --format='%(refname:short)' "refs/heads/backup/cherry-pick-${safe_branch_name}-*" | head -n 1
}
prepare_safety_before_real_action() {
local backup_reason="$1"
STATE_START_HEAD="$(git rev-parse HEAD)"
BACKUP_BRANCH="$(create_backup_branch_for_reason "$backup_reason")"
STATE_SNAPSHOT_PATH="$(create_worktree_snapshot_for_reason "$backup_reason")"
say "Safety backup branch created: $BACKUP_BRANCH"
say "Exact worktree snapshot created: $STATE_SNAPSHOT_PATH"
}
stash_current_changes() {
local stash_prefix="$1" timestamp stash_name
STASH_REF=""
STASH_HASH=""
if ! worktree_has_local_changes; then
say "No local tracked/untracked changes to stash."
return
fi
timestamp="$(date +%Y%m%d-%H%M%S)"
stash_name="${stash_prefix}-$(sanitize_ref_name "$CURRENT_BRANCH")-${timestamp}"
say "Stashing local tracked and untracked changes..."
git stash push --include-untracked --message "$stash_name" >/dev/null
STASH_REF="$(git stash list -1 --format='%gd')"
[ -n "$STASH_REF" ] || die "Failed to locate the created stash entry."
STASH_HASH="$(git rev-parse "$STASH_REF")"
[ -n "$STASH_HASH" ] || die "Failed to resolve the created stash hash."
say "Local changes saved in $STASH_REF"
}
fetch_upstream() {
say "Fetching latest changes from $REMOTE_NAME/$BRANCH..."
git fetch --prune "$REMOTE_NAME" "+refs/heads/$BRANCH:refs/remotes/$REMOTE_NAME/$BRANCH"
git show-ref --verify --quiet "refs/remotes/$REMOTE_NAME/$BRANCH" || die "Remote branch '$REMOTE_NAME/$BRANCH' was not found."
}
update_state() {
STATE_BRANCH="$CURRENT_BRANCH"
STATE_BACKUP_BRANCH="$BACKUP_BRANCH"
STATE_STASH_HASH="$STASH_HASH"
STATE_REMOTE_NAME="$REMOTE_NAME"
STATE_REMOTE_URL="$REMOTE_URL"
STATE_TARGET_BRANCH="$BRANCH"
write_state
}
find_stash_ref_by_hash() {
local target_hash="$1" hash ref
while read -r hash ref; do
if [ "$hash" = "$target_hash" ]; then
printf '%s\n' "$ref"
return 0
fi
done < <(git stash list --format='%H %gd')
return 1
}
drop_stash_by_hash_if_present() {
local target_hash="$1" stash_ref
[ -n "$target_hash" ] || return 0
if stash_ref="$(find_stash_ref_by_hash "$target_hash")"; then
git stash drop "$stash_ref" >/dev/null
fi
}
restore_stash() {
local keep_saved_copy="${1:-0}" restore_target
if [ -z "$STASH_HASH" ] && [ -z "$STASH_REF" ]; then
return
fi
restore_target="${STASH_HASH:-$STASH_REF}"
say "Restoring stashed local changes from $restore_target..."
if git stash apply --index "$restore_target"; then
STASH_REF=""
if [ "$keep_saved_copy" -eq 0 ]; then
drop_stash_by_hash_if_present "$STASH_HASH"
STASH_HASH=""
STATE_STASH_HASH=""
else
STATE_STASH_HASH="${STASH_HASH:-$restore_target}"
fi
STATE_STATUS="completed"
update_state
if [ "$keep_saved_copy" -eq 0 ]; then
say "Local changes restored successfully."
else
say "Local changes restored successfully. The original stash was kept for rollback safety."
fi
return
fi
STATE_STATUS="restore_conflict"
update_state
say "Conflicts occurred while restoring local changes."
say "Backup branch kept at: $BACKUP_BRANCH"
say "Stash kept at: $restore_target"
say "Resolve the conflicts manually, or return safely with: ./.import-upstream-cherry-pick.sh rollback"
exit 1
}
ordered_available_upstream_commits() {
local available_commit_shas="" commit
available_commit_shas="$(git cherry -v HEAD "$REMOTE_NAME/$BRANCH" | awk '$1=="+"{print $2}')"
[ -n "$available_commit_shas" ] || return 0
while IFS= read -r commit; do
[ -n "$commit" ] || continue
if printf '%s\n' "$available_commit_shas" | grep -Fxq "$commit"; then
printf '%s\n' "$commit"
fi
done < <(git rev-list --reverse HEAD.."$REMOTE_NAME/$BRANCH")
}
commit_is_available_for_import() {
local commit="$1"
ordered_available_upstream_commits | grep -Fxq "$commit"
}
resolve_import_commit() {
local commit="$1"
git rev-parse --verify "${commit}^{commit}" 2>/dev/null || die "Commit '$commit' could not be resolved."
}
validate_importable_commit() {
local commit="$1"
git merge-base --is-ancestor "$commit" "$REMOTE_NAME/$BRANCH" || die "Commit '$commit' is not reachable from $REMOTE_NAME/$BRANCH."
commit_is_available_for_import "$commit" || die "Commit '$commit' is not currently available for import into '$CURRENT_BRANCH'."
}
show_available_commits() {
local found_any=0 commit
while IFS= read -r commit; do
[ -n "$commit" ] || continue
found_any=1
git show --no-patch --date=short --format=' - %h | %ad | %s' "$commit"
done < <(ordered_available_upstream_commits)
if [ "$found_any" -eq 0 ]; then
say "No upstream commits are currently available for cherry-pick import."
fi
}
run_status() {
local stash_count latest_backup latest_snapshot
ensure_git_repo
ensure_current_branch_with_state_fallback
ensure_upstream_remote
stash_count="$(git stash list | wc -l | tr -d ' ')"
latest_backup="$(find_latest_backup_branch_for_current || true)"
latest_snapshot="$(find_latest_snapshot_for_current || true)"
say "Repository: $(git rev-parse --show-toplevel)"
say "Current branch: $CURRENT_BRANCH"
say "Upstream remote: $REMOTE_NAME -> $REMOTE_URL"
say "Working tree:"
if ! worktree_has_local_changes; then
say " clean"
else
git status --short
fi
say "Stash entries: $stash_count"
say "Latest backup for current branch: ${latest_backup:-none}"
say "Latest snapshot for current branch: ${latest_snapshot:-none}"
if load_state; then
say "Saved import state: $STATE_STATUS"
say "Saved backup branch: ${STATE_BACKUP_BRANCH:-none}"
say "Saved starting commit: ${STATE_START_HEAD:-none}"
say "Saved exact snapshot: ${STATE_SNAPSHOT_PATH:-none}"
say "Saved original stash: ${STATE_STASH_HASH:-none}"
say "Saved import commits: ${STATE_IMPORT_COMMITS:-none}"
else
say "Saved import state: none"
fi
}
run_fetch_only() {
ensure_git_repo
ensure_no_git_operation_in_progress
ensure_current_branch
ensure_upstream_remote
fetch_upstream
say "Latest changes fetched from $REMOTE_NAME/$BRANCH."
}
run_list() {
ensure_git_repo
ensure_no_git_operation_in_progress
ensure_current_branch
ensure_upstream_remote
fetch_upstream
show_available_commits
}
run_backup_only() {
ensure_git_repo
ensure_no_git_operation_in_progress
ensure_current_branch
ensure_upstream_remote
BACKUP_BRANCH="$(create_backup_branch_for_reason "manual-backup")"
say "Safety backup branch created: $BACKUP_BRANCH"
}
run_import_commits() {
local requested_commits=("$@") commit resolved_commit
local -a selected_commits=()
[ "${#requested_commits[@]}" -gt 0 ] || die "Provide at least one upstream commit to import."
ensure_git_repo
ensure_no_git_operation_in_progress
ensure_current_branch
ensure_upstream_remote
fetch_upstream
for commit in "${requested_commits[@]}"; do
resolved_commit="$(resolve_import_commit "$commit")"
validate_importable_commit "$resolved_commit"
selected_commits+=("$resolved_commit")
done
STATE_IMPORT_COMMITS="${selected_commits[*]}"
prepare_safety_before_real_action "before-cherry-pick-import"
stash_current_changes "pre-cherry-pick-import"
STATE_STATUS="prepared"
update_state
for commit in "${selected_commits[@]}"; do
say "Cherry-picking upstream commit: $(git show --no-patch --format='%h %s' "$commit")"
if ! git cherry-pick -x "$commit"; then
STATE_STATUS="cherry_pick_conflict"
update_state
say "Cherry-pick stopped because of conflicts."
say "Conflicting upstream commit: $(git show --no-patch --format='%h %s' CHERRY_PICK_HEAD)"
say "Resolve conflicts and continue with: ./.import-upstream-cherry-pick.sh continue"
say "Or return safely with: ./.import-upstream-cherry-pick.sh rollback"
exit 1
fi
done
restore_stash 1
say "Imported ${#selected_commits[@]} upstream commit(s) by cherry-pick."
say "Safety backup branch available at: $BACKUP_BRANCH"
say "Safety snapshot available at: $STATE_SNAPSHOT_PATH"
if [ -n "$STATE_STASH_HASH" ]; then
say "Original pre-import stash retained for rollback at: $STATE_STASH_HASH"
fi
}
run_import_range() {
local from_commit="${1:-}" to_commit="${2:-}" from_resolved to_resolved commit
local -a selected_commits=()
[ -n "$from_commit" ] || die "Provide the start commit for import-range."
[ -n "$to_commit" ] || die "Provide the end commit for import-range."
ensure_git_repo
ensure_no_git_operation_in_progress
ensure_current_branch
ensure_upstream_remote
fetch_upstream
from_resolved="$(resolve_import_commit "$from_commit")"
to_resolved="$(resolve_import_commit "$to_commit")"
git merge-base --is-ancestor "$from_resolved" "$REMOTE_NAME/$BRANCH" || die "Start commit '$from_commit' is not reachable from $REMOTE_NAME/$BRANCH."
git merge-base --is-ancestor "$to_resolved" "$REMOTE_NAME/$BRANCH" || die "End commit '$to_commit' is not reachable from $REMOTE_NAME/$BRANCH."
git merge-base --is-ancestor "$from_resolved" "$to_resolved" || die "Start commit '$from_commit' must be an ancestor of end commit '$to_commit' on $REMOTE_NAME/$BRANCH."
while IFS= read -r commit; do
[ -n "$commit" ] || continue
if commit_is_available_for_import "$commit"; then
selected_commits+=("$commit")
fi
done < <(git rev-list --reverse "${from_resolved}^..${to_resolved}")
[ "${#selected_commits[@]}" -gt 0 ] || die "No importable commits were found in the requested range."
run_import_commits "${selected_commits[@]}"
}
run_continue() {
ensure_git_repo
ensure_current_branch_with_state_fallback
ensure_upstream_remote
load_state || die "No saved cherry-pick state was found."
[ "$CURRENT_BRANCH" = "${STATE_BRANCH:-$CURRENT_BRANCH}" ] || die "Saved cherry-pick state belongs to branch '$STATE_BRANCH'. Check out that branch first."
has_cherry_pick_in_progress || die "There is no in-progress cherry-pick to continue."
say "Continuing cherry-pick..."
GIT_EDITOR=: git cherry-pick --continue
if has_cherry_pick_in_progress; then
STATE_STATUS="cherry_pick_conflict"
update_state
say "Cherry-pick hit another conflict."
say "Current conflicting upstream commit: $(git show --no-patch --format='%h %s' CHERRY_PICK_HEAD)"
say "Resolve conflicts and run: ./.import-upstream-cherry-pick.sh continue"
say "Or return safely with: ./.import-upstream-cherry-pick.sh rollback"
exit 1
fi
STASH_HASH="${STATE_STASH_HASH:-}"
STASH_REF=""
BACKUP_BRANCH="${STATE_BACKUP_BRANCH:-}"
restore_stash 1
say "Cherry-pick import completed."
}
run_restore_saved_stash() {
ensure_git_repo
ensure_no_git_operation_in_progress
ensure_current_branch_with_state_fallback
load_state || die "No saved import state was found."
[ "$CURRENT_BRANCH" = "${STATE_BRANCH:-$CURRENT_BRANCH}" ] || die "Saved import state belongs to branch '$STATE_BRANCH'. Check out that branch first."
[ -n "${STATE_STASH_HASH:-}" ] || die "There is no saved pre-import stash to restore."
if worktree_has_local_changes; then
die "The working tree is not clean. Commit, stash, or discard current changes before restoring the saved stash."
fi
prepare_safety_before_real_action "before-restore-stash"
STASH_HASH="$STATE_STASH_HASH"
STASH_REF=""
restore_stash 1
say "Saved pre-import local changes restored."
}
run_rollback() {
local explicit_target="${1:-}" reset_target="" reset_snapshot=""
local original_restore_stash_hash="" original_restore_start_head=""
local rollback_safety_snapshot="" rollback_safety_backup="" rollback_safety_start_head=""
local preserve_stash_hash=""
ensure_git_repo
ensure_no_noncherrypick_git_operation_in_progress
load_state || true
ensure_current_branch_with_state_fallback
ensure_upstream_remote
if [ -n "$explicit_target" ] && is_valid_snapshot_dir "$explicit_target"; then
reset_snapshot="$explicit_target"
elif [ -n "$explicit_target" ]; then
git show-ref --verify --quiet "refs/heads/$explicit_target" || die "Backup branch '$explicit_target' does not exist."
reset_target="$explicit_target"
else
if [ -n "${STATE_BRANCH:-}" ] && [ "$CURRENT_BRANCH" != "$STATE_BRANCH" ]; then
die "Saved import state belongs to branch '$STATE_BRANCH'. Check out that branch or pass an explicit backup branch or snapshot."
fi
if [ -n "${STATE_SNAPSHOT_PATH:-}" ] && is_valid_snapshot_dir "$STATE_SNAPSHOT_PATH"; then
reset_snapshot="$STATE_SNAPSHOT_PATH"
fi
if [ -n "${STATE_START_HEAD:-}" ]; then
reset_target="$STATE_START_HEAD"
elif [ -n "${STATE_BACKUP_BRANCH:-}" ]; then
reset_target="$STATE_BACKUP_BRANCH"
else
reset_target="$(find_latest_backup_branch_for_current || true)"
fi
fi
if [ -z "$reset_target" ] && [ -n "$reset_snapshot" ]; then
reset_target="$(snapshot_metadata_value "$reset_snapshot" head || true)"
fi
[ -n "$reset_target" ] || [ -n "$reset_snapshot" ] || die "No saved rollback target was found."
original_restore_stash_hash="${STATE_STASH_HASH:-}"
original_restore_start_head="${STATE_START_HEAD:-}"
if [ -z "$original_restore_start_head" ] && [ -n "$reset_snapshot" ]; then
original_restore_start_head="$(snapshot_metadata_value "$reset_snapshot" head || true)"
fi
if has_cherry_pick_in_progress; then
say "Aborting in-progress cherry-pick before rollback..."
git cherry-pick --abort || die "Failed to abort the in-progress cherry-pick."
fi
if [ -n "$(git diff --name-only --diff-filter=U)" ]; then
die "There are still unmerged files in the working tree. Resolve or discard them before rollback."
fi
prepare_safety_before_real_action "before-rollback"
rollback_safety_backup="$BACKUP_BRANCH"
rollback_safety_snapshot="$STATE_SNAPSHOT_PATH"
rollback_safety_start_head="$STATE_START_HEAD"
preserve_stash_hash=""
if worktree_has_local_changes; then
stash_current_changes "pre-rollback-preserve"
preserve_stash_hash="$STASH_HASH"
fi
if [ -n "$reset_target" ]; then
say "Resetting '$CURRENT_BRANCH' to '$reset_target'..."
git reset --hard "$reset_target" >/dev/null
fi
if [ -n "$original_restore_stash_hash" ]; then
STASH_HASH="$original_restore_stash_hash"
STASH_REF=""
BACKUP_BRANCH="$rollback_safety_backup"
say "Restoring original pre-import local changes..."
restore_stash 1
fi
if [ -n "$reset_snapshot" ]; then
say "Restoring exact worktree snapshot from: $reset_snapshot"
restore_worktree_snapshot "$reset_snapshot"
fi
STATE_BRANCH="$CURRENT_BRANCH"
STATE_BACKUP_BRANCH="$rollback_safety_backup"
STATE_STASH_HASH="$preserve_stash_hash"
STATE_REMOTE_NAME="$REMOTE_NAME"
STATE_REMOTE_URL="$REMOTE_URL"
STATE_TARGET_BRANCH="$BRANCH"
STATE_START_HEAD="$rollback_safety_start_head"
STATE_SNAPSHOT_PATH="$rollback_safety_snapshot"
STATE_IMPORT_COMMITS=""
STATE_STATUS="rollback_completed"
write_state
say "Rollback completed."
say "Restored starting commit: ${original_restore_start_head:-$reset_target}"
if [ -n "$reset_snapshot" ]; then
say "Restored snapshot: $reset_snapshot"
fi
say "Safety backup of the pre-rollback state kept at: $rollback_safety_backup"
say "Safety snapshot of the pre-rollback state kept at: $rollback_safety_snapshot"
if [ -n "$preserve_stash_hash" ]; then
say "Safety stash of the pre-rollback local changes kept at: $preserve_stash_hash"
fi
}
run_restore_snapshot() {
local target_snapshot="${1:-}" restore_safety_backup="" restore_safety_snapshot=""
local restore_safety_start_head="" restore_start_head="" preserve_stash_hash=""
ensure_git_repo
ensure_no_noncherrypick_git_operation_in_progress
load_state || die "No saved import state was found."
ensure_current_branch_with_state_fallback
ensure_upstream_remote
if [ -z "$target_snapshot" ]; then
target_snapshot="${STATE_SNAPSHOT_PATH:-}"
fi
is_valid_snapshot_dir "$target_snapshot" || die "No valid saved snapshot was found to restore."
restore_start_head="${STATE_START_HEAD:-}"
if [ -z "$restore_start_head" ]; then
restore_start_head="$(snapshot_metadata_value "$target_snapshot" head || true)"
fi
[ -n "$restore_start_head" ] || die "No saved starting commit was found for the snapshot restore."
if has_cherry_pick_in_progress; then
say "Aborting in-progress cherry-pick before snapshot restore..."
git cherry-pick --abort || die "Failed to abort the in-progress cherry-pick."
fi
if [ -n "$(git diff --name-only --diff-filter=U)" ]; then
die "There are still unmerged files in the working tree. Resolve or discard them before restoring the snapshot."
fi
prepare_safety_before_real_action "before-restore-snapshot"
restore_safety_backup="$BACKUP_BRANCH"
restore_safety_snapshot="$STATE_SNAPSHOT_PATH"
restore_safety_start_head="$STATE_START_HEAD"
if worktree_has_local_changes; then
stash_current_changes "pre-restore-snapshot-preserve"
preserve_stash_hash="$STASH_HASH"
fi
say "Resetting '$CURRENT_BRANCH' to '$restore_start_head' before snapshot restore..."
git reset --hard "$restore_start_head" >/dev/null
if [ -n "${STATE_STASH_HASH:-}" ]; then
STASH_HASH="$STATE_STASH_HASH"
STASH_REF=""
BACKUP_BRANCH="$restore_safety_backup"
say "Restoring saved pre-import local changes..."
restore_stash 1
fi
say "Restoring exact worktree snapshot from: $target_snapshot"
restore_worktree_snapshot "$target_snapshot"
STATE_BRANCH="$CURRENT_BRANCH"
STATE_BACKUP_BRANCH="$restore_safety_backup"
STATE_STASH_HASH="$preserve_stash_hash"
STATE_REMOTE_NAME="$REMOTE_NAME"
STATE_REMOTE_URL="$REMOTE_URL"
STATE_TARGET_BRANCH="$BRANCH"
STATE_START_HEAD="$restore_safety_start_head"
STATE_SNAPSHOT_PATH="$restore_safety_snapshot"
STATE_IMPORT_COMMITS=""
STATE_STATUS="snapshot_restored"
write_state
say "Snapshot restore completed."
say "Safety backup of the pre-restore state kept at: $restore_safety_backup"
say "Safety snapshot of the pre-restore state kept at: $restore_safety_snapshot"
if [ -n "$preserve_stash_hash" ]; then
say "Safety stash of the pre-restore local changes kept at: $preserve_stash_hash"
fi
}
show_menu() {
local choice import_commits range_from range_to snapshot_target rollback_target
while true; do
cat <<EOF
Available actions:
1) Fetch upstream only
2) List available upstream commits
3) Import selected commit(s)
4) Import an inclusive commit range
5) Continue in-progress cherry-pick
6) Rollback last import
7) Restore saved stash
8) Restore exact snapshot
9) Create backup branch only
10) Show repository status
11) Help
0) Exit
EOF
printf 'Choose an action: '
read -r choice
case "$choice" in
1) run_fetch_only ;;
2) run_list ;;
3)
printf 'Enter upstream commit hash(es), separated by spaces: '
read -r -a import_commits
run_import_commits "${import_commits[@]}"
return
;;
4)
printf 'Enter the start commit hash: '
read -r range_from
printf 'Enter the end commit hash: '
read -r range_to
run_import_range "$range_from" "$range_to"
return
;;
5)
run_continue
return
;;
6)
printf 'Optional backup branch or snapshot path (leave empty for saved state): '
read -r rollback_target
run_rollback "$rollback_target"
return
;;
7)
run_restore_saved_stash
return
;;
8)
printf 'Optional snapshot path (leave empty for saved state): '
read -r snapshot_target
run_restore_snapshot "$snapshot_target"
return
;;
9) run_backup_only ;;
10) run_status ;;
11) show_usage ;;
0) exit 0 ;;
*) say "Invalid menu selection: $choice" ;;
esac
done
}
main() {
case "${1:-menu}" in
fetch) run_fetch_only ;;
list) run_list ;;
import)
shift
run_import_commits "$@"
;;
import-range) run_import_range "${2:-}" "${3:-}" ;;
continue) run_continue ;;
backup) run_backup_only ;;
rollback) run_rollback "${2:-}" ;;
restore-stash) run_restore_saved_stash ;;
restore-snapshot) run_restore_snapshot "${2:-}" ;;
status) run_status ;;
help|-h|--help) show_usage ;;
menu)
if [ -t 0 ] && [ -t 1 ]; then
show_menu
else
show_usage
fi
;;
*)
die "Unknown command: $1. Run with 'help' to see available options."
;;
esac
}
main "$@"
+2440
View File
File diff suppressed because it is too large Load Diff
+435
View File
@@ -0,0 +1,435 @@
#!/bin/bash
# Folosește instalarea Go standard dacă există, chiar dacă nu este în PATH.
if [ -x "/usr/local/go/bin/go" ]; then
export PATH="/usr/local/go/bin:$PATH"
fi
# Încarcă NVM dacă este disponibil
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# Forțează folosirea versiunii 22
nvm use 22 > /dev/null 2>&1 || echo "⚠️ NVM nu a putut activa Node 22 automatically."
resolve_build_ref() {
git describe --tags --exact-match 2>/dev/null || git describe --tags --always
}
require_docker_for_darwin_sqlite() {
if ! command -v docker > /dev/null 2>&1; then
echo "❌ Docker is required for macOS SQLite cross-builds."
echo " Install the Docker CLI in this environment, or use the non-SQLite macOS build option."
echo " If you are running inside a code-server container, also mount the host Docker socket."
exit 1
fi
if ! docker info > /dev/null 2>&1; then
echo "❌ Docker is installed but the daemon is not reachable."
echo " Start Docker, or expose the host Docker daemon to this container."
echo " For a code-server container, mount /var/run/docker.sock from the host."
if [ -n "${DOCKER_HOST:-}" ]; then
echo " Current DOCKER_HOST: ${DOCKER_HOST}"
else
echo " Current DOCKER_HOST is unset."
fi
exit 1
fi
}
resolve_xgo_image() {
local xgo_version
xgo_version="$(awk '$1 == "XGO_VERSION" { print $3; exit }' Makefile 2>/dev/null)"
if [ -z "$xgo_version" ]; then
xgo_version="go-1.25.x"
fi
printf 'ghcr.io/techknowlogick/xgo:%s' "$xgo_version"
}
resolve_darwin_sqlite_repo_root() {
local override_path
override_path="${SMART_BUILD_DARWIN_HOST_REPO_PATH:-}"
if [ -z "$override_path" ]; then
pwd -P
return
fi
if [ ! -d "$override_path" ] || [ ! -f "$override_path/go.mod" ]; then
echo "❌ SMART_BUILD_DARWIN_HOST_REPO_PATH is set, but the path is not usable in this container:"
echo " $override_path"
echo " Mount the host repository path into the container at the same absolute path, then retry."
exit 1
fi
printf '%s' "$override_path"
}
validate_repo_bind_mount_for_darwin_sqlite() {
local repo_path="$1"
local xgo_image
xgo_image="$(resolve_xgo_image)"
if ! docker run --rm -v "$repo_path":/probe:ro --entrypoint sh "$xgo_image" -lc 'test -f /probe/go.mod'; then
echo "❌ Docker can reach the daemon, but the daemon cannot mount this repository path correctly:"
echo " $repo_path"
echo " The xgo container only sees an empty or different host path, so /source/go.mod is missing there."
echo " If smart-build runs inside a code-server container with the host Docker socket,"
echo " the repository must be mounted from a host bind path that exists at the same absolute path."
exit 1
fi
}
write_sha256_file() {
local artifact_path="$1"
local artifact_dir artifact_name
artifact_dir="$(dirname "$artifact_path")"
artifact_name="$(basename "$artifact_path")"
if command -v sha256sum > /dev/null 2>&1; then
(
cd "$artifact_dir" || exit 1
sha256sum "$artifact_name" > "$artifact_name.sha256"
)
return
fi
if command -v shasum > /dev/null 2>&1; then
(
cd "$artifact_dir" || exit 1
shasum -a 256 "$artifact_name" > "$artifact_name.sha256"
)
return
fi
echo "❌ Neither sha256sum nor shasum is available for checksum generation."
exit 1
}
# --- 1. VERIFICARE INTEGRITATE ȘI CURĂȚARE CACHE INIȚIALĂ ---
echo "🔍 Initialization checks..."
if ! command -v go > /dev/null 2>&1; then
echo "❌ Go nu este disponibil în PATH. Instalează Go 1.26.2 sau adaugă binarul go în PATH."
exit 1
fi
notify_human_interaction() {
local bell_oga="/usr/share/sounds/freedesktop/stereo/bell.oga"
local bell_wav="/usr/share/sounds/alsa/Front_Center.wav"
local in_vscode_terminal=0
local notification_sent=0
if [ "${TERM_PROGRAM:-}" = "vscode" ] || [ -n "${VSCODE_IPC_HOOK_CLI:-}" ] || [ -n "${VSCODE_GIT_IPC_HANDLE:-}" ]; then
in_vscode_terminal=1
fi
if command -v notify-send > /dev/null 2>&1; then
notify-send "Gitea smart-build" "Human input required in smart-build.sh" > /dev/null 2>&1 && notification_sent=1
fi
if command -v canberra-gtk-play > /dev/null 2>&1; then
canberra-gtk-play -i bell > /dev/null 2>&1 && return
fi
if [ -f "$bell_oga" ] && command -v paplay > /dev/null 2>&1; then
paplay "$bell_oga" > /dev/null 2>&1 && return
fi
if [ -f "$bell_wav" ] && command -v aplay > /dev/null 2>&1; then
aplay -q "$bell_wav" > /dev/null 2>&1 && return
fi
if [ -f "$bell_wav" ] && command -v play > /dev/null 2>&1; then
play -q "$bell_wav" > /dev/null 2>&1 && return
fi
if [ -t 1 ]; then
printf '\a'
fi
if [ "$notification_sent" -eq 0 ] && [ "$in_vscode_terminal" -eq 1 ]; then
printf '\033[1;33m%s\033[0m\n' ">>> Human input required below <<<"
fi
}
apply_moderate_build_limits() {
local go_procs="$1"
local node_memory="$2"
export GOMAXPROCS="$go_procs"
export MAKEFLAGS="-j1"
if [[ "$NODE_OPTIONS" != *"--max-old-space-size="* ]]; then
export NODE_OPTIONS="${NODE_OPTIONS:+$NODE_OPTIONS }--max-old-space-size=$node_memory"
fi
}
echo ""
echo "⚙️ Select Build Load Profile:"
echo " Normal keeps the default build behavior."
echo " Moderate limits parallel jobs and keeps CPU/RAM usage lower."
echo " Low Resource is slower, but safest for weaker machines."
notify_human_interaction
load_options=("Normal" "Moderate (GOMAXPROCS=2, make -j1)" "Low Resource (GOMAXPROCS=1, make -j1)" "Quit")
select opt in "${load_options[@]}"
do
case $opt in
"Normal")
echo "✅ Selected: Normal build profile."
break
;;
"Moderate (GOMAXPROCS=2, make -j1)")
apply_moderate_build_limits 2 2048
echo "✅ Selected: Moderate build profile."
echo " GOMAXPROCS=$GOMAXPROCS MAKEFLAGS=\"$MAKEFLAGS\" NODE_OPTIONS=\"$NODE_OPTIONS\""
break
;;
"Low Resource (GOMAXPROCS=1, make -j1)")
apply_moderate_build_limits 1 2048
echo "✅ Selected: Low Resource build profile."
echo " GOMAXPROCS=$GOMAXPROCS MAKEFLAGS=\"$MAKEFLAGS\" NODE_OPTIONS=\"$NODE_OPTIONS\""
break
;;
"Quit")
exit 0
;;
*) echo "Opțiune invalidă $REPLY";;
esac
done
# Dacă compilarea anterioară a fost întreruptă, ștergem binarul parțial
if [ -f "gitea" ] || [ -f "gitea.exe" ]; then
echo "🧹 Garbages found. Cleanning..."
rm -f gitea gitea.exe
fi
# Verificăm dacă node_modules există. Dacă nu, forțăm pnpm install
if [ ! -d "node_modules" ]; then
echo "⚠️ node_modules missing. Instaling..."
if ! pnpm install --frozen-lockfile; then
echo "❌ Fail to install frontend dependencies."
exit 1
fi
fi
# --- 2. LOGICĂ FRONTEND (CHECKSUM) ---
CHECKSUM_FILE=".frontend.hash"
CURRENT_HASH=$(find web_src package.json tailwind.config.js -type f -print0 2>/dev/null | xargs -0 sha1sum | sha1sum | awk '{print $1}')
if [ -f "$CHECKSUM_FILE" ] && [ "$CURRENT_HASH" == "$(cat $CHECKSUM_FILE)" ]; then
echo "✅ Frontend is unchanged."
else
echo "🚀 Code changes detected. Running frontend build..."
if ! make frontend; then
echo "❌ Fail to build frontend assets."
exit 1
fi
echo "$CURRENT_HASH" > "$CHECKSUM_FILE"
fi
# --- 3. MENIU INTERACTIV PENTRU ARHITECTURĂ ---
echo ""
echo "🎯 Select Arch to build:"
notify_human_interaction
arch_options=("linux-amd64" "linux-armv7" "windows-amd64" "macos-amd64" "macos-arm64" "All Arch" "Quit")
select opt in "${arch_options[@]}"
do
case $opt in
"linux-amd64")
TARGETS=("linux/amd64")
break
;;
"linux-armv7")
TARGETS=("linux/arm/7")
break
;;
"windows-amd64")
TARGETS=("windows/amd64")
break
;;
"macos-amd64")
TARGETS=("darwin/amd64")
break
;;
"macos-arm64")
TARGETS=("darwin/arm64")
break
;;
"All Arch")
TARGETS=("linux/amd64" "linux/arm/7" "windows/amd64" "darwin/amd64" "darwin/arm64")
break
;;
"Quit")
exit 0
;;
*) echo "Opțiune invalidă $REPLY";;
esac
done
echo ""
echo "🏷️ Select Build Tags:"
notify_human_interaction
tag_options=("bindata" "bindata sqlite sqlite_unlock_notify" "Quit")
select opt in "${tag_options[@]}"
do
case $opt in
"bindata")
BUILD_TAGS="bindata"
break
;;
"bindata sqlite sqlite_unlock_notify")
BUILD_TAGS="bindata sqlite sqlite_unlock_notify"
BUILD_VARIANT="sqlite"
break
;;
"Quit")
exit 0
;;
*) echo "Opțiune invalidă $REPLY";;
esac
done
if [ -z "$BUILD_VARIANT" ]; then
BUILD_VARIANT="default"
fi
BUILD_REF="$(resolve_build_ref)"
BUILD_REF="${BUILD_REF//\//-}"
echo "🏷️ Build tag/reference: $BUILD_REF"
bindata_needs_update() {
local source_dir="$1"
local bindata_file="$2"
if [ ! -f "$bindata_file" ]; then
return 0
fi
find "$source_dir" -type f -newer "$bindata_file" -print -quit 2>/dev/null | grep -q .
}
ensure_bindata_asset() {
local label="$1"
local source_dir="$2"
local go_package="$3"
local bindata_file="$4"
if bindata_needs_update "$source_dir" "$bindata_file"; then
echo "♻️ Regenerating $label bindata..."
if ! CC= GOOS= GOARCH= CGO_ENABLED=0 go generate -tags bindata "$go_package"; then
echo "❌ Failed to regenerate $label bindata."
exit 1
fi
else
echo "$label bindata is up to date."
fi
}
ensure_bindata_assets() {
if [[ " $BUILD_TAGS " != *" bindata "* ]]; then
return
fi
echo "🔎 Checking embedded bindata assets..."
ensure_bindata_asset "templates" "templates" "./modules/templates" "modules/templates/bindata.dat"
ensure_bindata_asset "options" "options" "./modules/options" "modules/options/bindata.dat"
ensure_bindata_asset "public" "public" "./modules/public" "modules/public/bindata.dat"
ensure_bindata_asset "migration schemas" "modules/migration/schemas" "./modules/migration" "modules/migration/bindata.dat"
}
ensure_bindata_assets
build_darwin_sqlite_target() {
local arch="$1"
local output="$2"
local repo_root temp_dist built_file output_abs
local built_files=()
require_docker_for_darwin_sqlite
repo_root="$(resolve_darwin_sqlite_repo_root)"
validate_repo_bind_mount_for_darwin_sqlite "$repo_root"
output_abs="$(pwd -P)/$output"
temp_dist="$repo_root/dist/.smart-build-darwin-${arch}-$$"
rm -rf "$temp_dist"
if ! mkdir -p "$temp_dist"; then
echo "❌ Failed to create a temporary macOS release directory in dist/."
exit 1
fi
echo "📦 Building for darwin/$arch with TAGS=\"$BUILD_TAGS\" via release-darwin..."
if ! make -C "$repo_root" release-darwin TAGS="$BUILD_TAGS" DARWIN_ARCHS="darwin-10.12/$arch" DIST="$temp_dist"; then
rm -rf "$temp_dist"
echo "❌ Fail to build for darwin/$arch with SQLite"
exit 1
fi
mapfile -t built_files < <(find "$temp_dist/binaries" -maxdepth 1 -type f | sort)
if [ "${#built_files[@]}" -ne 1 ]; then
rm -rf "$temp_dist"
echo "❌ Unexpected macOS artifact count for darwin/$arch: ${#built_files[@]}"
exit 1
fi
built_file="${built_files[0]}"
mv "$built_file" "$output_abs"
rm -rf "$temp_dist"
write_sha256_file "$output_abs"
echo "✅ Created: $output_abs"
echo "✅ Created: $output_abs.sha256"
}
build_standard_target() {
local os="$1"
local arch="$2"
local arm_ver="$3"
local output="$4"
local ext="$5"
export GOOS=$os
export GOARCH=$arch
export GOARM=$arm_ver
export CGO_ENABLED=0
if [ "$BUILD_VARIANT" == "sqlite" ]; then
export CGO_ENABLED=1
fi
if make build TAGS="$BUILD_TAGS"; then
mv "gitea$ext" "$output"
write_sha256_file "$output"
echo "✅ Created: $output"
echo "✅ Created: $output.sha256"
else
echo "❌ Fail to build for $os/$arch${arm_ver:+/v$arm_ver}"
exit 1
fi
}
# --- 4. COMPILARE ---
mkdir -p dist
for TARGET in "${TARGETS[@]}"; do
IFS="/" read -r OS ARCH ARM_VER <<< "$TARGET"
EXT="" && [ "$OS" == "windows" ] && EXT=".exe"
PLATFORM="$ARCH" && [ ! -z "$ARM_VER" ] && PLATFORM="armv$ARM_VER"
VARIANT_SUFFIX="" && [ "$BUILD_VARIANT" == "sqlite" ] && VARIANT_SUFFIX="-sqlite"
OUTPUT="dist/gitea-$BUILD_REF-$OS-$PLATFORM$VARIANT_SUFFIX$EXT"
if [ "$OS" == "darwin" ] && [ "$BUILD_VARIANT" == "sqlite" ]; then
build_darwin_sqlite_target "$ARCH" "$OUTPUT"
else
echo "📦 Building for $OS/$ARCH ${ARM_VER:+(v$ARM_VER) }with TAGS=\"$BUILD_TAGS\"..."
build_standard_target "$OS" "$ARCH" "$ARM_VER" "$OUTPUT" "$EXT"
fi
unset GOOS GOARCH GOARM CGO_ENABLED
done
echo "✨ Buid finished. Get file(s) from /dist"
go clean -cache # || true
+1091
View File
File diff suppressed because it is too large Load Diff
+1 -3
View File
@@ -21,9 +21,7 @@ rules:
comments-indentation:
level: error
document-start:
level: error
present: false
document-start: disable
document-end:
present: false
+36
View File
@@ -0,0 +1,36 @@
## Core Repository Rules
- Use `make help` to find available development targets
- Run `make fmt` to format `.go` files, and run `make lint-go` to lint them
- Run `make lint-js` to lint `.ts` files
- Run `make tidy` after any `go.mod` changes
- Add the current year into the copyright header of new `.go` files
- Ensure no trailing whitespace in edited files
- Never force-push, amend, or squash unless asked. Use new commits and normal push for pull request updates
- Preserve existing code comments, do not remove or rewrite comments that are still relevant
- In TypeScript, use `!` (non-null assertion) instead of `?.`/`??` when a value is known to always exist
- Include authorship attribution in issue and pull request comments
- Add `Co-Authored-By` lines to all commits, indicating name and model used
## Execution Rules (Token Optimization)
- DO NOT read full files unless they are explicitly targeted with `@filename`, referenced from instruction `*.md` files, or required to complete the user's task.
- Assume the workspace structure described in `./.codex-context.md` and `./.codex-project-map.md` is the current baseline unless the user indicates otherwise.
- DO NOT read `./.codex-history.md` end-to-end by default; search by keyword, subsystem, tag, or read only the latest relevant entries first.
## Project Context
- Read and follow `./.codex-context.md` as the persistent repository context before starting work and when validating final changes.
- Use `./.codex-project-map.md` for the persistent structural and architectural map of the repository.
## Routing Rules for Tasks (Multi-Model Delegation)
Apply these routing preferences when the environment supports model selection. If the preferred model is unavailable, use the closest available model and note the fallback.
Priority for mixed tasks:
Architecture & Orchestration > Go & Database Coding > Frontend & Template Tasks > DevOps & Terminal Execution
1. Architecture & Orchestration Tasks: Prefer `gpt-5.4` (Reasoning: High/Extra High). Use for complex requirement breakdown, solution design, and validation of large structural updates.
2. Go & Database Coding Tasks: Prefer `gpt-5.3-codex` (Reasoning: Medium). This includes writing HTTP handlers, database queries, internal Go business logic, and server-side integration work.
3. Frontend & Template Tasks: Prefer `gpt-5.3-codex` (Reasoning: Medium). This includes `templates/`, `web_src/`, CSS, and TypeScript changes.
4. DevOps & Terminal Commands: Prefer `gpt-5.4-mini` (Reasoning: Low). Use for `pnpm`, `git`, `go mod`, `npm`, `make`, or `bash` execution flows and shell-oriented maintenance tasks.
+4496 -4496
View File
File diff suppressed because it is too large Load Diff
+5293 -4361
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -0,0 +1 @@
@AGENTS.md
+35 -11
View File
@@ -4,6 +4,7 @@
- [Contribution Guidelines](#contribution-guidelines)
- [Introduction](#introduction)
- [AI Contribution Policy](#ai-contribution-policy)
- [Issues](#issues)
- [How to report issues](#how-to-report-issues)
- [Types of issues](#types-of-issues)
@@ -67,6 +68,21 @@ Sensitive security-related issues should be reported to [security@gitea.io](mail
For configuring IDEs for Gitea development, see the [contributed IDE configurations](contrib/ide/).
## AI Contribution Policy
Contributions made with the assistance of AI tools are welcome, but contributors must use them responsibly and disclose that use clearly.
1. Review AI-generated code closely before marking a pull request ready for review.
2. Manually test the changes and add appropriate automated tests where feasible.
3. Only use AI to assist in contributions that you understand well enough to explain, defend, and revise yourself during review.
4. Disclose AI-assisted content clearly.
5. Do not use AI to reply to questions about your issue or pull request. The questions are for you, not an AI model.
6. AI may be used to help draft issues and pull requests, but contributors remain responsible for the accuracy, completeness, and intent of what they submit.
Maintainers reserve the right to close pull requests and issues that do not disclose AI assistance, that appear to be low-quality AI-generated content, or where the contributor cannot explain or defend the proposed changes themselves.
We welcome new contributors, but cannot sustain the effort of supporting contributors who primarily defer to AI rather than engaging substantively with the review process.
## Issues
### How to report issues
@@ -80,7 +96,7 @@ The more detailed and specific you are, the faster we can fix the issue. \
It is really helpful if you can reproduce your problem on a site running on the latest commits, i.e. <https://demo.gitea.com>, as perhaps your problem has already been fixed on a current version. \
Please follow the guidelines described in [How to Report Bugs Effectively](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html) for your report.
Please be kind, remember that Gitea comes at no cost to you, and you're getting free help.
Please be kindremember that Gitea comes at no cost to you, and you're getting free help.
### Types of issues
@@ -166,24 +182,32 @@ Here's how to run the test suite:
- code lint
| | |
| :-------------------- | :---------------------------------------------------------------- |
| | |
| :-------------------- | :--------------------------------------------------------------------------- |
|``make lint`` | lint everything (not needed if you only change the front- **or** backend) |
|``make lint-frontend`` | lint frontend files |
|``make lint-backend`` | lint backend files |
|``make lint-frontend`` | lint frontend files |
|``make lint-backend`` | lint backend files |
- run tests (we suggest running them on Linux)
| Command | Action | |
| :------------------------------------- | :----------------------------------------------- | ------------ |
|``make test[\#SpecificTestName]`` | run unit test(s) | |
|``make test-sqlite[\#SpecificTestName]``| run [integration](tests/integration) test(s) for SQLite |[More details](tests/integration/README.md) |
|``make test-e2e-sqlite[\#SpecificTestName]``| run [end-to-end](tests/e2e) test(s) for SQLite |[More details](tests/e2e/README.md) |
| Command | Action | |
| :------------------------------------------ | :------------------------------------------------------- | ------------------------------------------- |
|``make test[\#SpecificTestName]`` | run unit test(s) | |
|``make test-sqlite[\#SpecificTestName]`` | run [integration](tests/integration) test(s) for SQLite | [More details](tests/integration/README.md) |
|``make test-e2e`` | run [end-to-end](tests/e2e) test(s) using Playwright | |
- E2E test environment variables
| Variable | Description |
| :-------------------------------- | :---------------------------------------------------------- |
| ``GITEA_TEST_E2E_DEBUG`` | When set, show Gitea server output |
| ``GITEA_TEST_E2E_FLAGS`` | Additional flags passed to Playwright, for example ``--ui`` |
| ``GITEA_TEST_E2E_TIMEOUT_FACTOR`` | Timeout multiplier (default: 3 on CI, 1 locally) |
## Translation
All translation work happens on [Crowdin](https://translate.gitea.com).
The only translation that is maintained in this repository is [the English translation](https://github.com/go-gitea/gitea/blob/main/options/locale/locale_en-US.ini).
The only translation that is maintained in this repository is [the English translation](https://github.com/go-gitea/gitea/blob/main/options/locale/locale_en-US.json).
It is synced regularly with Crowdin. \
Other locales on main branch **should not** be updated manually as they will be overwritten with each sync. \
Once a language has reached a **satisfactory percentage** of translated keys (~25%), it will be synced back into this repo and included in the next released version.
+31 -30
View File
@@ -1,8 +1,15 @@
# Build stage
FROM docker.io/library/golang:1.25-alpine3.22 AS build-env
# syntax=docker/dockerfile:1
# Build frontend on the native platform to avoid QEMU-related issues with nodejs ecosystem
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.26-alpine3.23 AS frontend-build
RUN apk --no-cache add build-base git nodejs pnpm
WORKDIR /src
COPY package.json pnpm-lock.yaml .npmrc ./
RUN --mount=type=cache,target=/root/.local/share/pnpm/store pnpm install --frozen-lockfile
COPY --exclude=.git/ . .
RUN make frontend
ARG GOPROXY
ENV GOPROXY=${GOPROXY:-direct}
# Build backend for each target platform
FROM docker.io/library/golang:1.26-alpine3.23 AS build-env
ARG GITEA_VERSION
ARG TAGS="sqlite sqlite_unlock_notify"
@@ -12,37 +19,32 @@ ARG CGO_EXTRA_CFLAGS
# Build deps
RUN apk --no-cache add \
build-base \
git \
nodejs \
npm \
&& npm install -g pnpm@10 \
&& rm -rf /var/cache/apk/*
git
# Setup repo
COPY . ${GOPATH}/src/code.gitea.io/gitea
WORKDIR ${GOPATH}/src/code.gitea.io/gitea
COPY go.mod go.sum ./
RUN go mod download
# Use COPY instead of bind mount as read-only one breaks makefile state tracking and read-write one needs binary to be moved as it's discarded.
# ".git" directory is mounted separately later only for version data extraction.
COPY --exclude=.git/ . .
COPY --from=frontend-build /src/public/assets public/assets
# Checkout version if set
RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
&& make clean-all build
# Build gitea, .git mount is required for version data
RUN --mount=type=cache,target="/root/.cache/go-build" \
--mount=type=bind,source=".git/",target=".git/" \
make backend
# Begin env-to-ini build
RUN go build contrib/environment-to-ini/environment-to-ini.go
# Copy local files
COPY docker/root /tmp/local
# Set permissions
# Set permissions for builds that made under windows which strips the executable bit from file
RUN chmod 755 /tmp/local/usr/bin/entrypoint \
/tmp/local/usr/local/bin/gitea \
/tmp/local/usr/local/bin/* \
/tmp/local/etc/s6/gitea/* \
/tmp/local/etc/s6/openssh/* \
/tmp/local/etc/s6/.s6-svscan/* \
/go/src/code.gitea.io/gitea/gitea \
/go/src/code.gitea.io/gitea/environment-to-ini
/go/src/code.gitea.io/gitea/gitea
FROM docker.io/library/alpine:3.22
LABEL maintainer="maintainers@gitea.io"
FROM docker.io/library/alpine:3.23 AS gitea
EXPOSE 22 3000
@@ -57,8 +59,7 @@ RUN apk --no-cache add \
s6 \
sqlite \
su-exec \
gnupg \
&& rm -rf /var/cache/apk/*
gnupg
RUN addgroup \
-S -g 1000 \
@@ -72,14 +73,14 @@ RUN addgroup \
git && \
echo "git:*" | chpasswd -e
COPY --from=build-env /tmp/local /
COPY --from=build-env /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
ENV USER=git
ENV GITEA_CUSTOM=/data/gitea
VOLUME ["/data"]
# HINT: HEALTH-CHECK-ENDPOINT: don't use HEALTHCHECK, search this hint keyword for more information
ENTRYPOINT ["/usr/bin/entrypoint"]
CMD ["/usr/bin/s6-svscan", "/etc/s6"]
COPY --from=build-env /tmp/local /
COPY --from=build-env /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
COPY --from=build-env /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini
+28 -30
View File
@@ -1,46 +1,45 @@
# Build stage
FROM docker.io/library/golang:1.25-alpine3.22 AS build-env
# syntax=docker/dockerfile:1
# Build frontend on the native platform to avoid QEMU-related issues with nodejs ecosystem
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.26-alpine3.23 AS frontend-build
RUN apk --no-cache add build-base git nodejs pnpm
WORKDIR /src
COPY package.json pnpm-lock.yaml .npmrc ./
RUN --mount=type=cache,target=/root/.local/share/pnpm/store pnpm install --frozen-lockfile
COPY --exclude=.git/ . .
RUN make frontend
ARG GOPROXY
ENV GOPROXY=${GOPROXY:-direct}
# Build backend for each target platform
FROM docker.io/library/golang:1.26-alpine3.23 AS build-env
ARG GITEA_VERSION
ARG TAGS="sqlite sqlite_unlock_notify"
ENV TAGS="bindata timetzdata $TAGS"
ARG CGO_EXTRA_CFLAGS
#Build deps
# Build deps
RUN apk --no-cache add \
build-base \
git \
nodejs \
npm \
&& npm install -g pnpm@10 \
&& rm -rf /var/cache/apk/*
git
# Setup repo
COPY . ${GOPATH}/src/code.gitea.io/gitea
WORKDIR ${GOPATH}/src/code.gitea.io/gitea
COPY go.mod go.sum ./
RUN go mod download
# See the comments in Dockerfile
COPY --exclude=.git/ . .
COPY --from=frontend-build /src/public/assets public/assets
# Checkout version if set
RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
&& make clean-all build
# Build gitea, .git mount is required for version data
RUN --mount=type=cache,target="/root/.cache/go-build" \
--mount=type=bind,source=".git/",target=".git/" \
make backend
# Begin env-to-ini build
RUN go build contrib/environment-to-ini/environment-to-ini.go
# Copy local files
COPY docker/rootless /tmp/local
# Set permissions
RUN chmod 755 /tmp/local/usr/local/bin/docker-entrypoint.sh \
/tmp/local/usr/local/bin/docker-setup.sh \
/tmp/local/usr/local/bin/gitea \
/go/src/code.gitea.io/gitea/gitea \
/go/src/code.gitea.io/gitea/environment-to-ini
# Set permissions for builds that made under windows which strips the executable bit from file
RUN chmod 755 /tmp/local/usr/local/bin/* \
/go/src/code.gitea.io/gitea/gitea
FROM docker.io/library/alpine:3.22
LABEL maintainer="maintainers@gitea.io"
FROM docker.io/library/alpine:3.23 AS gitea-rootless
EXPOSE 2222 3000
@@ -52,8 +51,7 @@ RUN apk --no-cache add \
git \
curl \
gnupg \
openssh-keygen \
&& rm -rf /var/cache/apk/*
openssh-keygen
RUN addgroup \
-S -g 1000 \
@@ -71,7 +69,6 @@ RUN chown git:git /var/lib/gitea /etc/gitea
COPY --from=build-env /tmp/local /
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini
# git:git
USER 1000:1000
@@ -86,5 +83,6 @@ ENV HOME="/var/lib/gitea/git"
VOLUME ["/var/lib/gitea", "/etc/gitea"]
WORKDIR /var/lib/gitea
# HINT: HEALTH-CHECK-ENDPOINT: don't use HEALTHCHECK, search this hint keyword for more information
ENTRYPOINT ["/usr/bin/dumb-init", "--", "/usr/local/bin/docker-entrypoint.sh"]
CMD []
+1
View File
@@ -64,3 +64,4 @@ metiftikci <metiftikci@hotmail.com> (@metiftikci)
Christopher Homberger <christopher.homberger@web.de> (@ChristopherHX)
Tobias Balle-Petersen <tobiasbp@gmail.com> (@tobiasbp)
TheFox <thefox0x7@gmail.com> (@TheFox0x7)
Nicolas <bircni@icloud.com> (@bircni)
+135 -253
View File
@@ -1,22 +1,9 @@
ifeq ($(USE_REPO_TEST_DIR),1)
# This rule replaces the whole Makefile when we're trying to use /tmp repository temporary files
location = $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
self := $(location)
%:
@tmpdir=`mktemp --tmpdir -d` ; \
echo Using temporary directory $$tmpdir for test repositories ; \
USE_REPO_TEST_DIR= $(MAKE) -f $(self) --no-print-directory REPO_TEST_DIR=$$tmpdir/ $@ ; \
STATUS=$$? ; rm -r "$$tmpdir" ; exit $$STATUS
else
# This is the "normal" part of the Makefile
DIST := dist
DIST_DIRS := $(DIST)/binaries $(DIST)/release
IMPORT := code.gitea.io/gitea
# By default use go's 1.25 experimental json v2 library when building
# TODO: remove when no longer experimental
export GOEXPERIMENT ?= jsonv2
GO ?= go
SHASUM ?= shasum -a 256
@@ -27,17 +14,14 @@ XGO_VERSION := go-1.25.x
AIR_PACKAGE ?= github.com/air-verse/air@v1
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.9.1
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.4.0
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.9.2
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.11.4
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.15
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/misspell@v0.7.0
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@717e3cb29becaaf00e56953556c6d80f8a01b286
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/misspell@v0.8.0
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.33.1
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1
ACTIONLINT_PACKAGE ?= github.com/rhysd/actionlint/cmd/actionlint@v1
GOPLS_PACKAGE ?= golang.org/x/tools/gopls@v0.20.0
GOPLS_MODERNIZE_PACKAGE ?= golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@v0.20.0
ACTIONLINT_PACKAGE ?= github.com/rhysd/actionlint/cmd/actionlint@v1.7.11
DOCKER_IMAGE ?= gitea/gitea
DOCKER_TAG ?= latest
@@ -69,9 +53,11 @@ endif
ifeq ($(IS_WINDOWS),yes)
GOFLAGS := -v -buildmode=exe
EXECUTABLE ?= gitea.exe
EXECUTABLE_E2E ?= gitea-e2e.exe
else
GOFLAGS := -v
EXECUTABLE ?= gitea
EXECUTABLE_E2E ?= gitea-e2e
endif
ifeq ($(shell sed --version 2>/dev/null | grep -q GNU && echo gnu),gnu)
@@ -82,7 +68,6 @@ endif
EXTRA_GOFLAGS ?=
MAKE_VERSION := $(shell "$(MAKE)" -v | cat | head -n 1)
MAKE_EVIDENCE_DIR := .make_evidence
GOTESTFLAGS ?=
@@ -96,15 +81,6 @@ STORED_VERSION_FILE := VERSION
GITHUB_REF_TYPE ?= branch
GITHUB_REF_NAME ?= $(shell git rev-parse --abbrev-ref HEAD)
# Enable typescript support in Node.js before 22.18
# TODO: Remove this once we can raise the minimum Node.js version to 22.18 (alpine >= 3.23)
NODE_VERSION := $(shell printf "%03d%03d%03d" $(shell node -v 2>/dev/null | cut -c2- | tr '.' ' '))
ifeq ($(shell test "$(NODE_VERSION)" -lt "022018000"; echo $$?),0)
NODE_VARS := NODE_OPTIONS="--experimental-strip-types"
else
NODE_VARS :=
endif
ifneq ($(GITHUB_REF_TYPE),branch)
VERSION ?= $(subst v,,$(GITHUB_REF_NAME))
GITEA_VERSION ?= $(VERSION)
@@ -119,7 +95,7 @@ else
ifneq ($(STORED_VERSION),)
GITEA_VERSION ?= $(STORED_VERSION)
else
GITEA_VERSION ?= $(shell git describe --tags --always | sed 's/-/+/' | sed 's/^v//')
GITEA_VERSION ?= $(shell git describe --tags --always | sed -E 's/^v//; s/^(.*)-([0-9]+-g[0-9a-f]+)$$/\1+\2/')
endif
endif
@@ -128,17 +104,19 @@ ifeq ($(VERSION),main)
VERSION := main-nightly
endif
LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)"
LDFLAGS := $(LDFLAGS) -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)"
LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64,linux/riscv64
DARWIN_ARCHS ?= darwin-10.12/amd64,darwin-10.12/arm64
GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/migrations/...) code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration code.gitea.io/gitea/tests/e2e,$(shell $(GO) list ./... | grep -v /vendor/))
GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/migrations/...) code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration,$(shell $(GO) list ./... | grep -v /vendor/))
MIGRATE_TEST_PACKAGES ?= $(shell $(GO) list code.gitea.io/gitea/models/migrations/...)
WEBPACK_SOURCES := $(shell find web_src/js web_src/css -type f)
WEBPACK_CONFIGS := webpack.config.ts tailwind.config.ts
WEBPACK_DEST := public/assets/js/index.js public/assets/css/index.css
WEBPACK_DEST_ENTRIES := public/assets/js public/assets/css public/assets/fonts
FRONTEND_SOURCES := $(shell find web_src/js web_src/css -type f)
FRONTEND_CONFIGS := vite.config.ts tailwind.config.ts
FRONTEND_DEST := public/assets/.vite/manifest.json
FRONTEND_DEST_ENTRIES := public/assets/js public/assets/css public/assets/fonts public/assets/.vite
FRONTEND_DEV_LOG_LEVEL ?= warn
BINDATA_DEST_WILDCARD := modules/migration/bindata.* modules/public/bindata.* modules/options/bindata.* modules/templates/bindata.*
@@ -148,7 +126,6 @@ SVG_DEST_DIR := public/assets/img/svg
AIR_TMP_DIR := .air
GO_LICENSE_TMP_DIR := .go-licenses
GO_LICENSE_FILE := assets/go-licenses.json
TAGS ?=
@@ -157,24 +134,21 @@ TAGS_EVIDENCE := $(MAKE_EVIDENCE_DIR)/tags
TEST_TAGS ?= $(TAGS_SPLIT) sqlite sqlite_unlock_notify
TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(DIST) $(MAKE_EVIDENCE_DIR) $(AIR_TMP_DIR) $(GO_LICENSE_TMP_DIR)
TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(DIST) $(MAKE_EVIDENCE_DIR) $(AIR_TMP_DIR)
GO_DIRS := build cmd models modules routers services tests
GO_DIRS := build cmd models modules routers services tests tools
WEB_DIRS := web_src/js web_src/css
ESLINT_FILES := web_src/js tools *.ts tests/e2e
STYLELINT_FILES := web_src/css web_src/js/components/*.vue
SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) templates options/locale/locale_en-US.ini .github $(filter-out CHANGELOG.md, $(wildcard *.go *.md *.yml *.yaml *.toml)) $(filter-out tools/misspellings.csv, $(wildcard tools/*))
EDITORCONFIG_FILES := templates .github/workflows options/locale/locale_en-US.ini
SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) templates options/locale/locale_en-US.json .github $(filter-out CHANGELOG.md, $(wildcard *.go *.md *.yml *.yaml *.toml))
EDITORCONFIG_FILES := templates .github/workflows options/locale/locale_en-US.json
GO_SOURCES := $(wildcard *.go)
GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go")
GO_SOURCES += $(GENERATED_GO_DEST)
# Force installation of playwright dependencies by setting this flag
ifdef DEPS_PLAYWRIGHT
PLAYWRIGHT_FLAGS += --with-deps
endif
ESLINT_CONCURRENCY ?= 2
SWAGGER_SPEC := templates/swagger/v1_json.tmpl
SWAGGER_SPEC_INPUT := templates/swagger/v1_input.json
@@ -195,26 +169,20 @@ TEST_MSSQL_DBNAME ?= gitea
TEST_MSSQL_USERNAME ?= sa
TEST_MSSQL_PASSWORD ?= MwantsaSecurePassword1
# Include local Makefile
# Makefile.local is listed in .gitignore
sinclude Makefile.local
.PHONY: all
all: build
.PHONY: help
help: Makefile ## print Makefile help information.
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m[TARGETS] default target: build\033[0m\n\n\033[35mTargets:\033[0m\n"} /^[0-9A-Za-z._-]+:.*?##/ { printf " \033[36m%-45s\033[0m %s\n", $$1, $$2 }' Makefile #$(MAKEFILE_LIST)
@printf " \033[36m%-46s\033[0m %s\n" "test-e2e[#TestSpecificName]" "test end to end using playwright"
@printf " \033[36m%-46s\033[0m %s\n" "test-e2e" "test end to end using playwright"
@printf " \033[36m%-46s\033[0m %s\n" "test[#TestSpecificName]" "run unit test"
@printf " \033[36m%-46s\033[0m %s\n" "test-sqlite[#TestSpecificName]" "run integration test for sqlite"
.PHONY: go-check
go-check:
$(eval MIN_GO_VERSION_STR := $(shell grep -Eo '^go\s+[0-9]+\.[0-9]+' go.mod | cut -d' ' -f2))
$(eval MIN_GO_VERSION := $(shell printf "%03d%03d" $(shell echo '$(MIN_GO_VERSION_STR)' | tr '.' ' ')))
$(eval GO_VERSION := $(shell printf "%03d%03d" $(shell $(GO) version | grep -Eo '[0-9]+\.[0-9]+' | tr '.' ' ');))
@if [ "$(GO_VERSION)" -lt "$(MIN_GO_VERSION)" ]; then \
echo "Gitea requires Go $(MIN_GO_VERSION_STR) or greater to build. You can get it at https://go.dev/dl/"; \
exit 1; \
fi
.PHONY: git-check
git-check:
@if git lfs >/dev/null 2>&1 ; then : ; else \
@@ -222,39 +190,24 @@ git-check:
exit 1; \
fi
.PHONY: node-check
node-check:
$(eval MIN_NODE_VERSION_STR := $(shell grep -Eo '"node":.*[0-9.]+"' package.json | sed -n 's/.*[^0-9.]\([0-9.]*\)"/\1/p'))
$(eval MIN_NODE_VERSION := $(shell printf "%03d%03d%03d" $(shell echo '$(MIN_NODE_VERSION_STR)' | tr '.' ' ')))
$(eval PNPM_MISSING := $(shell hash pnpm > /dev/null 2>&1 || echo 1))
@if [ "$(NODE_VERSION)" -lt "$(MIN_NODE_VERSION)" ]; then \
echo "Gitea requires Node.js $(MIN_NODE_VERSION_STR) or greater to build. You can get it at https://nodejs.org/en/download/"; \
exit 1; \
fi
@if [ "$(PNPM_MISSING)" = "1" ]; then \
echo "Gitea requires pnpm to build. You can install it at https://pnpm.io/installation"; \
exit 1; \
fi
.PHONY: clean-all
clean-all: clean ## delete backend, frontend and integration files
rm -rf $(WEBPACK_DEST_ENTRIES) node_modules
rm -rf $(FRONTEND_DEST_ENTRIES) node_modules
.PHONY: clean
clean: ## delete backend and integration files
rm -rf $(EXECUTABLE) $(DIST) $(BINDATA_DEST_WILDCARD) \
rm -rf $(EXECUTABLE) $(EXECUTABLE_E2E) $(DIST) $(BINDATA_DEST_WILDCARD) \
integrations*.test \
e2e*.test \
tests/integration/gitea-integration-* \
tests/integration/indexers-* \
tests/mysql.ini tests/pgsql.ini tests/mssql.ini man/ \
tests/sqlite.ini tests/mysql.ini tests/pgsql.ini tests/mssql.ini man/ \
tests/e2e/gitea-e2e-*/ \
tests/e2e/indexers-*/ \
tests/e2e/reports/ tests/e2e/test-artifacts/ tests/e2e/test-snapshots/
.PHONY: fmt
fmt: ## format the Go and template code
@GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}'
@GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run tools/code-batch-process.go gitea-fmt -w '{file-list}'
$(eval TEMPLATES := $(shell find templates -type f -name '*.tmpl'))
@# strip whitespace after '{{' or '(' and before '}}' or ')' unless there is only
@# whitespace before it
@@ -272,19 +225,6 @@ fmt-check: fmt
exit 1; \
fi
.PHONY: fix
fix: ## apply automated fixes to Go code
$(GO) run $(GOPLS_MODERNIZE_PACKAGE) -fix ./...
.PHONY: fix-check
fix-check: fix
@diff=$$(git diff --color=always $(GO_SOURCES)); \
if [ -n "$$diff" ]; then \
echo "Please run 'make fix' and commit the result:"; \
printf "%s" "$${diff}"; \
exit 1; \
fi
.PHONY: $(TAGS_EVIDENCE)
$(TAGS_EVIDENCE):
@mkdir -p $(MAKE_EVIDENCE_DIR)
@@ -324,7 +264,7 @@ checks: checks-frontend checks-backend ## run various consistency checks
checks-frontend: lockfile-check svg-check ## check frontend files
.PHONY: checks-backend
checks-backend: tidy-check swagger-check fmt-check fix-check swagger-validate security-check ## check backend files
checks-backend: tidy-check swagger-check fmt-check swagger-validate security-check ## check backend files
.PHONY: lint
lint: lint-frontend lint-backend lint-spell ## lint everything
@@ -339,44 +279,48 @@ lint-frontend: lint-js lint-css ## lint frontend files
lint-frontend-fix: lint-js-fix lint-css-fix ## lint frontend files and fix issues
.PHONY: lint-backend
lint-backend: lint-go lint-go-gitea-vet lint-go-gopls lint-editorconfig ## lint backend files
lint-backend: lint-go lint-go-gitea-vet lint-editorconfig ## lint backend files
.PHONY: lint-backend-fix
lint-backend-fix: lint-go-fix lint-go-gitea-vet lint-editorconfig ## lint backend files and fix issues
.PHONY: lint-js
lint-js: node_modules ## lint js files
$(NODE_VARS) pnpm exec eslint --color --max-warnings=0 --flag unstable_native_nodejs_ts_config $(ESLINT_FILES)
$(NODE_VARS) pnpm exec vue-tsc
lint-js: node_modules ## lint js and ts files
pnpm exec eslint --color --max-warnings=0 --concurrency $(ESLINT_CONCURRENCY) $(ESLINT_FILES)
pnpm exec vue-tsc
.PHONY: lint-js-fix
lint-js-fix: node_modules ## lint js files and fix issues
$(NODE_VARS) pnpm exec eslint --color --max-warnings=0 --flag unstable_native_nodejs_ts_config $(ESLINT_FILES) --fix
$(NODE_VARS) pnpm exec vue-tsc
lint-js-fix: node_modules ## lint js and ts files and fix issues
pnpm exec eslint --color --max-warnings=0 --concurrency $(ESLINT_CONCURRENCY) $(ESLINT_FILES) --fix
pnpm exec vue-tsc
.PHONY: lint-css
lint-css: node_modules ## lint css files
$(NODE_VARS) pnpm exec stylelint --color --max-warnings=0 $(STYLELINT_FILES)
pnpm exec stylelint --color --max-warnings=0 $(STYLELINT_FILES)
.PHONY: lint-css-fix
lint-css-fix: node_modules ## lint css files and fix issues
$(NODE_VARS) pnpm exec stylelint --color --max-warnings=0 $(STYLELINT_FILES) --fix
pnpm exec stylelint --color --max-warnings=0 $(STYLELINT_FILES) --fix
.PHONY: lint-swagger
lint-swagger: node_modules ## lint swagger files
$(NODE_VARS) pnpm exec spectral lint -q -F hint $(SWAGGER_SPEC)
pnpm exec spectral lint -q -F hint $(SWAGGER_SPEC)
.PHONY: lint-md
lint-md: node_modules ## lint markdown files
$(NODE_VARS) pnpm exec markdownlint *.md
pnpm exec markdownlint *.md
.PHONY: lint-md-fix
lint-md-fix: node_modules ## lint markdown files and fix issues
pnpm exec markdownlint --fix *.md
.PHONY: lint-spell
lint-spell: ## lint spelling
@go run $(MISSPELL_PACKAGE) -dict tools/misspellings.csv -error $(SPELLCHECK_FILES)
@git ls-files $(SPELLCHECK_FILES) | xargs go run $(MISSPELL_PACKAGE) -dict assets/misspellings.csv -error
.PHONY: lint-spell-fix
lint-spell-fix: ## lint spelling and fix issues
@go run $(MISSPELL_PACKAGE) -dict tools/misspellings.csv -w $(SPELLCHECK_FILES)
@git ls-files $(SPELLCHECK_FILES) | xargs go run $(MISSPELL_PACKAGE) -dict assets/misspellings.csv -w
.PHONY: lint-go
lint-go: ## lint go files
@@ -396,13 +340,7 @@ lint-go-windows:
.PHONY: lint-go-gitea-vet
lint-go-gitea-vet: ## lint go files with gitea-vet
@echo "Running gitea-vet..."
@GOOS= GOARCH= $(GO) build code.gitea.io/gitea-vet
@$(GO) vet -vettool=gitea-vet ./...
.PHONY: lint-go-gopls
lint-go-gopls: ## lint go files with gopls
@echo "Running gopls check..."
@GO=$(GO) GOPLS_PACKAGE=$(GOPLS_PACKAGE) tools/lint-go-gopls.sh $(GO_SOURCES)
@$(GO) vet -vettool="$(shell GOOS= GOARCH= go tool -n gitea-vet)" ./...
.PHONY: lint-editorconfig
lint-editorconfig:
@@ -422,17 +360,24 @@ lint-templates: .venv node_modules ## lint template files
lint-yaml: .venv ## lint yaml files
@uv run --frozen yamllint -s .
.PHONY: lint-json
lint-json: node_modules ## lint json files
pnpm exec eslint -c eslint.json.config.ts --color --max-warnings=0 --concurrency $(ESLINT_CONCURRENCY)
.PHONY: lint-json-fix
lint-json-fix: node_modules ## lint and fix json files
pnpm exec eslint -c eslint.json.config.ts --color --max-warnings=0 --concurrency $(ESLINT_CONCURRENCY) --fix
.PHONY: watch
watch: ## watch everything and continuously rebuild
@bash tools/watch.sh
.PHONY: watch-frontend
watch-frontend: node-check node_modules ## watch frontend files and continuously rebuild
@rm -rf $(WEBPACK_DEST_ENTRIES)
NODE_ENV=development $(NODE_VARS) pnpm exec webpack --watch --progress --disable-interpret
watch-frontend: node_modules ## start vite dev server for frontend
NODE_ENV=development pnpm exec vite --logLevel $(FRONTEND_DEV_LOG_LEVEL)
.PHONY: watch-backend
watch-backend: go-check ## watch backend files and continuously rebuild
watch-backend: ## watch backend files and continuously rebuild
GITEA_RUN_MODE=dev $(GO) run $(AIR_PACKAGE) -c .air.toml
.PHONY: test
@@ -445,7 +390,7 @@ test-backend: ## test backend files
.PHONY: test-frontend
test-frontend: node_modules ## test frontend files
$(NODE_VARS) pnpm exec vitest
pnpm exec vitest
.PHONY: test-check
test-check:
@@ -468,7 +413,7 @@ test\#%:
coverage:
grep '^\(mode: .*\)\|\(.*:[0-9]\+\.[0-9]\+,[0-9]\+\.[0-9]\+ [0-9]\+ [0-9]\+\)$$' coverage.out > coverage-bodged.out
grep '^\(mode: .*\)\|\(.*:[0-9]\+\.[0-9]\+,[0-9]\+\.[0-9]\+ [0-9]\+ [0-9]\+\)$$' integration.coverage.out > integration.coverage-bodged.out
$(GO) run build/gocovmerge.go integration.coverage-bodged.out coverage-bodged.out > coverage.all
$(GO) run tools/gocovmerge.go integration.coverage-bodged.out coverage-bodged.out > coverage.all
.PHONY: unit-test-coverage
unit-test-coverage:
@@ -498,25 +443,20 @@ tidy-check: tidy
go-licenses: $(GO_LICENSE_FILE) ## regenerate go licenses
$(GO_LICENSE_FILE): go.mod go.sum
@rm -rf $(GO_LICENSE_FILE)
$(GO) install $(GO_LICENSES_PACKAGE)
-GOOS=linux CGO_ENABLED=1 go-licenses save . --force --save_path=$(GO_LICENSE_TMP_DIR) 2>/dev/null
$(GO) run build/generate-go-licenses.go $(GO_LICENSE_TMP_DIR) $(GO_LICENSE_FILE)
@rm -rf $(GO_LICENSE_TMP_DIR)
GO=$(GO) $(GO) run build/generate-go-licenses.go $(GO_LICENSE_FILE)
generate-ini-sqlite:
sed -e 's|{{REPO_TEST_DIR}}|${REPO_TEST_DIR}|g' \
sed -e 's|{{WORK_PATH}}|$(CURDIR)/tests/$(or $(TEST_TYPE),integration)/gitea-$(or $(TEST_TYPE),integration)-sqlite|g' \
-e 's|{{TEST_LOGGER}}|$(or $(TEST_LOGGER),test$(COMMA)file)|g' \
-e 's|{{TEST_TYPE}}|$(or $(TEST_TYPE),integration)|g' \
tests/sqlite.ini.tmpl > tests/sqlite.ini
.PHONY: test-sqlite
test-sqlite: integrations.sqlite.test generate-ini-sqlite
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./integrations.sqlite.test
GITEA_TEST_CONF=tests/sqlite.ini ./integrations.sqlite.test
.PHONY: test-sqlite\#%
test-sqlite\#%: integrations.sqlite.test generate-ini-sqlite
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./integrations.sqlite.test -test.run $(subst .,/,$*)
GITEA_TEST_CONF=tests/sqlite.ini ./integrations.sqlite.test -test.run $(subst .,/,$*)
.PHONY: test-sqlite-migration
test-sqlite-migration: migrations.sqlite.test migrations.individual.sqlite.test
@@ -526,18 +466,17 @@ generate-ini-mysql:
-e 's|{{TEST_MYSQL_DBNAME}}|${TEST_MYSQL_DBNAME}|g' \
-e 's|{{TEST_MYSQL_USERNAME}}|${TEST_MYSQL_USERNAME}|g' \
-e 's|{{TEST_MYSQL_PASSWORD}}|${TEST_MYSQL_PASSWORD}|g' \
-e 's|{{REPO_TEST_DIR}}|${REPO_TEST_DIR}|g' \
-e 's|{{WORK_PATH}}|$(CURDIR)/tests/$(or $(TEST_TYPE),integration)/gitea-$(or $(TEST_TYPE),integration)-mysql|g' \
-e 's|{{TEST_LOGGER}}|$(or $(TEST_LOGGER),test$(COMMA)file)|g' \
-e 's|{{TEST_TYPE}}|$(or $(TEST_TYPE),integration)|g' \
tests/mysql.ini.tmpl > tests/mysql.ini
.PHONY: test-mysql
test-mysql: integrations.mysql.test generate-ini-mysql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./integrations.mysql.test
GITEA_TEST_CONF=tests/mysql.ini ./integrations.mysql.test
.PHONY: test-mysql\#%
test-mysql\#%: integrations.mysql.test generate-ini-mysql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./integrations.mysql.test -test.run $(subst .,/,$*)
GITEA_TEST_CONF=tests/mysql.ini ./integrations.mysql.test -test.run $(subst .,/,$*)
.PHONY: test-mysql-migration
test-mysql-migration: migrations.mysql.test migrations.individual.mysql.test
@@ -549,18 +488,17 @@ generate-ini-pgsql:
-e 's|{{TEST_PGSQL_PASSWORD}}|${TEST_PGSQL_PASSWORD}|g' \
-e 's|{{TEST_PGSQL_SCHEMA}}|${TEST_PGSQL_SCHEMA}|g' \
-e 's|{{TEST_MINIO_ENDPOINT}}|${TEST_MINIO_ENDPOINT}|g' \
-e 's|{{REPO_TEST_DIR}}|${REPO_TEST_DIR}|g' \
-e 's|{{WORK_PATH}}|$(CURDIR)/tests/$(or $(TEST_TYPE),integration)/gitea-$(or $(TEST_TYPE),integration)-pgsql|g' \
-e 's|{{TEST_LOGGER}}|$(or $(TEST_LOGGER),test$(COMMA)file)|g' \
-e 's|{{TEST_TYPE}}|$(or $(TEST_TYPE),integration)|g' \
tests/pgsql.ini.tmpl > tests/pgsql.ini
.PHONY: test-pgsql
test-pgsql: integrations.pgsql.test generate-ini-pgsql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./integrations.pgsql.test
GITEA_TEST_CONF=tests/pgsql.ini ./integrations.pgsql.test
.PHONY: test-pgsql\#%
test-pgsql\#%: integrations.pgsql.test generate-ini-pgsql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./integrations.pgsql.test -test.run $(subst .,/,$*)
GITEA_TEST_CONF=tests/pgsql.ini ./integrations.pgsql.test -test.run $(subst .,/,$*)
.PHONY: test-pgsql-migration
test-pgsql-migration: migrations.pgsql.test migrations.individual.pgsql.test
@@ -570,89 +508,53 @@ generate-ini-mssql:
-e 's|{{TEST_MSSQL_DBNAME}}|${TEST_MSSQL_DBNAME}|g' \
-e 's|{{TEST_MSSQL_USERNAME}}|${TEST_MSSQL_USERNAME}|g' \
-e 's|{{TEST_MSSQL_PASSWORD}}|${TEST_MSSQL_PASSWORD}|g' \
-e 's|{{REPO_TEST_DIR}}|${REPO_TEST_DIR}|g' \
-e 's|{{WORK_PATH}}|$(CURDIR)/tests/$(or $(TEST_TYPE),integration)/gitea-$(or $(TEST_TYPE),integration)-mssql|g' \
-e 's|{{TEST_LOGGER}}|$(or $(TEST_LOGGER),test$(COMMA)file)|g' \
-e 's|{{TEST_TYPE}}|$(or $(TEST_TYPE),integration)|g' \
tests/mssql.ini.tmpl > tests/mssql.ini
.PHONY: test-mssql
test-mssql: integrations.mssql.test generate-ini-mssql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./integrations.mssql.test
GITEA_TEST_CONF=tests/mssql.ini ./integrations.mssql.test
.PHONY: test-mssql\#%
test-mssql\#%: integrations.mssql.test generate-ini-mssql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./integrations.mssql.test -test.run $(subst .,/,$*)
GITEA_TEST_CONF=tests/mssql.ini ./integrations.mssql.test -test.run $(subst .,/,$*)
.PHONY: test-mssql-migration
test-mssql-migration: migrations.mssql.test migrations.individual.mssql.test
.PHONY: playwright
playwright: deps-frontend
$(NODE_VARS) pnpm exec playwright install $(PLAYWRIGHT_FLAGS)
.PHONY: test-e2e%
test-e2e%: TEST_TYPE ?= e2e
# Clear display env variable. Otherwise, chromium tests can fail.
DISPLAY=
@# on GitHub Actions VMs, playwright's system deps are pre-installed
@pnpm exec playwright install $(if $(GITHUB_ACTIONS),,--with-deps) chromium firefox $(PLAYWRIGHT_FLAGS)
.PHONY: test-e2e
test-e2e: test-e2e-sqlite
.PHONY: test-e2e-sqlite
test-e2e-sqlite: playwright e2e.sqlite.test generate-ini-sqlite
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./e2e.sqlite.test
.PHONY: test-e2e-sqlite\#%
test-e2e-sqlite\#%: playwright e2e.sqlite.test generate-ini-sqlite
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./e2e.sqlite.test -test.run TestE2e/$*
.PHONY: test-e2e-mysql
test-e2e-mysql: playwright e2e.mysql.test generate-ini-mysql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./e2e.mysql.test
.PHONY: test-e2e-mysql\#%
test-e2e-mysql\#%: playwright e2e.mysql.test generate-ini-mysql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./e2e.mysql.test -test.run TestE2e/$*
.PHONY: test-e2e-pgsql
test-e2e-pgsql: playwright e2e.pgsql.test generate-ini-pgsql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./e2e.pgsql.test
.PHONY: test-e2e-pgsql\#%
test-e2e-pgsql\#%: playwright e2e.pgsql.test generate-ini-pgsql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./e2e.pgsql.test -test.run TestE2e/$*
.PHONY: test-e2e-mssql
test-e2e-mssql: playwright e2e.mssql.test generate-ini-mssql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./e2e.mssql.test
.PHONY: test-e2e-mssql\#%
test-e2e-mssql\#%: playwright e2e.mssql.test generate-ini-mssql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./e2e.mssql.test -test.run TestE2e/$*
test-e2e: playwright $(EXECUTABLE_E2E)
@EXECUTABLE=$(EXECUTABLE_E2E) ./tools/test-e2e.sh $(GITEA_TEST_E2E_FLAGS)
.PHONY: bench-sqlite
bench-sqlite: integrations.sqlite.test generate-ini-sqlite
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./integrations.sqlite.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench .
GITEA_TEST_CONF=tests/sqlite.ini ./integrations.sqlite.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench .
.PHONY: bench-mysql
bench-mysql: integrations.mysql.test generate-ini-mysql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./integrations.mysql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench .
GITEA_TEST_CONF=tests/mysql.ini ./integrations.mysql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench .
.PHONY: bench-mssql
bench-mssql: integrations.mssql.test generate-ini-mssql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./integrations.mssql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench .
GITEA_TEST_CONF=tests/mssql.ini ./integrations.mssql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench .
.PHONY: bench-pgsql
bench-pgsql: integrations.pgsql.test generate-ini-pgsql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./integrations.pgsql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench .
GITEA_TEST_CONF=tests/pgsql.ini ./integrations.pgsql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench .
.PHONY: integration-test-coverage
integration-test-coverage: integrations.cover.test generate-ini-mysql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./integrations.cover.test -test.coverprofile=integration.coverage.out
GITEA_TEST_CONF=tests/mysql.ini ./integrations.cover.test -test.coverprofile=integration.coverage.out
.PHONY: integration-test-coverage-sqlite
integration-test-coverage-sqlite: integrations.cover.sqlite.test generate-ini-sqlite
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./integrations.cover.sqlite.test -test.coverprofile=integration.coverage.out
GITEA_TEST_CONF=tests/sqlite.ini ./integrations.cover.sqlite.test -test.coverprofile=integration.coverage.out
integrations.mysql.test: git-check $(GO_SOURCES)
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.mysql.test
@@ -675,66 +577,54 @@ integrations.cover.sqlite.test: git-check $(GO_SOURCES)
.PHONY: migrations.mysql.test
migrations.mysql.test: $(GO_SOURCES) generate-ini-mysql
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.mysql.test
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./migrations.mysql.test
GITEA_TEST_CONF=tests/mysql.ini ./migrations.mysql.test
.PHONY: migrations.pgsql.test
migrations.pgsql.test: $(GO_SOURCES) generate-ini-pgsql
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.pgsql.test
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./migrations.pgsql.test
GITEA_TEST_CONF=tests/pgsql.ini ./migrations.pgsql.test
.PHONY: migrations.mssql.test
migrations.mssql.test: $(GO_SOURCES) generate-ini-mssql
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.mssql.test
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./migrations.mssql.test
GITEA_TEST_CONF=tests/mssql.ini ./migrations.mssql.test
.PHONY: migrations.sqlite.test
migrations.sqlite.test: $(GO_SOURCES) generate-ini-sqlite
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.sqlite.test -tags '$(TEST_TAGS)'
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./migrations.sqlite.test
GITEA_TEST_CONF=tests/sqlite.ini ./migrations.sqlite.test
.PHONY: migrations.individual.mysql.test
migrations.individual.mysql.test: $(GO_SOURCES)
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES)
migrations.individual.mysql.test: $(GO_SOURCES) generate-ini-mysql
GITEA_TEST_CONF=tests/mysql.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES)
.PHONY: migrations.individual.sqlite.test\#%
migrations.individual.sqlite.test\#%: $(GO_SOURCES) generate-ini-sqlite
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$*
GITEA_TEST_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$*
.PHONY: migrations.individual.pgsql.test
migrations.individual.pgsql.test: $(GO_SOURCES)
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES)
migrations.individual.pgsql.test: $(GO_SOURCES) generate-ini-pgsql
GITEA_TEST_CONF=tests/pgsql.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES)
.PHONY: migrations.individual.pgsql.test\#%
migrations.individual.pgsql.test\#%: $(GO_SOURCES) generate-ini-pgsql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$*
GITEA_TEST_CONF=tests/pgsql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$*
.PHONY: migrations.individual.mssql.test
migrations.individual.mssql.test: $(GO_SOURCES) generate-ini-mssql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES)
GITEA_TEST_CONF=tests/mssql.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES)
.PHONY: migrations.individual.mssql.test\#%
migrations.individual.mssql.test\#%: $(GO_SOURCES) generate-ini-mssql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$*
GITEA_TEST_CONF=tests/mssql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$*
.PHONY: migrations.individual.sqlite.test
migrations.individual.sqlite.test: $(GO_SOURCES) generate-ini-sqlite
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES)
GITEA_TEST_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES)
.PHONY: migrations.individual.sqlite.test\#%
migrations.individual.sqlite.test\#%: $(GO_SOURCES) generate-ini-sqlite
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$*
e2e.mysql.test: $(GO_SOURCES)
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.mysql.test
e2e.pgsql.test: $(GO_SOURCES)
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.pgsql.test
e2e.mssql.test: $(GO_SOURCES)
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.mssql.test
e2e.sqlite.test: $(GO_SOURCES)
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.sqlite.test -tags '$(TEST_TAGS)'
GITEA_TEST_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$*
.PHONY: check
check: test
@@ -747,10 +637,10 @@ install: $(wildcard *.go)
build: frontend backend ## build everything
.PHONY: frontend
frontend: $(WEBPACK_DEST) ## build frontend files
frontend: $(FRONTEND_DEST) ## build frontend files
.PHONY: backend
backend: go-check generate-backend $(EXECUTABLE) ## build backend files
backend: generate-backend $(EXECUTABLE) ## build backend files
# We generate the backend before the frontend in case we in future we want to generate things in the frontend from generated files in backend
.PHONY: generate
@@ -766,14 +656,17 @@ generate-go: $(TAGS_PREREQ)
.PHONY: security-check
security-check:
go run $(GOVULNCHECK_PACKAGE) -show color ./...
GOEXPERIMENT= go run $(GOVULNCHECK_PACKAGE) -show color ./... || true
$(EXECUTABLE): $(GO_SOURCES) $(TAGS_PREREQ)
ifneq ($(and $(STATIC),$(findstring pam,$(TAGS))),)
$(error pam support set via TAGS doesn't support static builds)
$(error pam support set via TAGS does not support static builds)
endif
CGO_ENABLED="$(CGO_ENABLED)" CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(EXTLDFLAGS) $(LDFLAGS)' -o $@
$(EXECUTABLE_E2E): $(GO_SOURCES) $(FRONTEND_DEST)
CGO_ENABLED=1 $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TEST_TAGS)' -ldflags '-s -w $(EXTLDFLAGS) $(LDFLAGS)' -o $@
.PHONY: release
release: frontend generate release-windows release-linux release-darwin release-freebsd release-copy release-compress vendor release-sources release-check
@@ -793,7 +686,7 @@ release-linux: | $(DIST_DIRS)
.PHONY: release-darwin
release-darwin: | $(DIST_DIRS)
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-s -w $(LDFLAGS)' -targets 'darwin-10.12/amd64,darwin-10.12/arm64' -out gitea-$(VERSION) .
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-s -w $(LDFLAGS)' -targets '$(DARWIN_ARCHS)' -out gitea-$(VERSION) .
.PHONY: release-freebsd
release-freebsd: | $(DIST_DIRS)
@@ -844,15 +737,12 @@ deps-tools: ## install tool dependencies
$(GO) install $(MISSPELL_PACKAGE) & \
$(GO) install $(SWAGGER_PACKAGE) & \
$(GO) install $(XGO_PACKAGE) & \
$(GO) install $(GO_LICENSES_PACKAGE) & \
$(GO) install $(GOVULNCHECK_PACKAGE) & \
$(GO) install $(ACTIONLINT_PACKAGE) & \
$(GO) install $(GOPLS_PACKAGE) & \
$(GO) install $(GOPLS_MODERNIZE_PACKAGE) & \
wait
node_modules: pnpm-lock.yaml
$(NODE_VARS) pnpm install --frozen-lockfile
pnpm install --frozen-lockfile
@touch node_modules
.venv: uv.lock
@@ -860,36 +750,41 @@ node_modules: pnpm-lock.yaml
@touch .venv
.PHONY: update
update: update-js update-py ## update js and py dependencies
update: update-go update-js update-py ## update dependencies
.PHONY: update-go
update-go: ## update go dependencies
$(GO) get -u ./...
$(MAKE) tidy
.PHONY: update-js
update-js: node-check | node_modules ## update js dependencies
$(NODE_VARS) pnpm exec updates -u -f package.json
update-js: node_modules ## update js dependencies
pnpm exec updates -u -f package.json
rm -rf node_modules pnpm-lock.yaml
$(NODE_VARS) pnpm install
$(NODE_VARS) pnpm exec nolyfill install
$(NODE_VARS) pnpm install
pnpm install
pnpm exec nolyfill install
pnpm install
@touch node_modules
.PHONY: update-py
update-py: node-check | node_modules ## update py dependencies
$(NODE_VARS) pnpm exec updates -u -f pyproject.toml
update-py: node_modules ## update py dependencies
pnpm exec updates -u -f pyproject.toml
rm -rf .venv uv.lock
uv sync
@touch .venv
.PHONY: webpack
webpack: $(WEBPACK_DEST) ## build webpack files
.PHONY: vite
vite: $(FRONTEND_DEST) ## build vite files
$(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) pnpm-lock.yaml
@$(MAKE) -s node-check node_modules
@rm -rf $(WEBPACK_DEST_ENTRIES)
@echo "Running webpack..."
@BROWSERSLIST_IGNORE_OLD_DATA=true $(NODE_VARS) pnpm exec webpack --disable-interpret
@touch $(WEBPACK_DEST)
$(FRONTEND_DEST): $(FRONTEND_SOURCES) $(FRONTEND_CONFIGS) pnpm-lock.yaml
@$(MAKE) -s node_modules
@rm -rf $(FRONTEND_DEST_ENTRIES)
@echo "Running vite build..."
@pnpm exec vite build
@touch $(FRONTEND_DEST)
.PHONY: svg
svg: node-check | node_modules ## build svg files
svg: node_modules ## build svg files
rm -rf $(SVG_DEST_DIR)
node tools/generate-svg.ts
@@ -905,7 +800,7 @@ svg-check: svg
.PHONY: lockfile-check
lockfile-check:
$(NODE_VARS) pnpm install --frozen-lockfile
pnpm install --frozen-lockfile
@diff=$$(git diff --color=always pnpm-lock.yaml); \
if [ -n "$$diff" ]; then \
echo "pnpm-lock.yaml is inconsistent with package.json"; \
@@ -914,16 +809,6 @@ lockfile-check:
exit 1; \
fi
.PHONY: update-translations
update-translations:
mkdir -p ./translations
cd ./translations && curl -L https://crowdin.com/download/project/gitea.zip > gitea.zip && unzip gitea.zip
rm ./translations/gitea.zip
$(SED_INPLACE) -e 's/="/=/g' -e 's/"$$//g' ./translations/*.ini
$(SED_INPLACE) -e 's/\\"/"/g' ./translations/*.ini
mv ./translations/*.ini ./options/locale/
rmdir ./translations
.PHONY: generate-gitignore
generate-gitignore: ## update gitignore files
$(GO) run build/generate-gitignores.go
@@ -945,9 +830,6 @@ docker:
docker build --disable-content-trust=false -t $(DOCKER_REF) .
# support also build args docker build --build-arg GITEA_VERSION=v1.2.3 --build-arg TAGS="bindata sqlite sqlite_unlock_notify" .
# This endif closes the if at the top of the file
endif
# Disable parallel execution because it would break some targets that don't
# specify exact dependencies like 'backend' which does currently not depend
# on 'frontend' to enable Node.js-less builds from source tarballs.
-1
View File
@@ -8,7 +8,6 @@
[![](https://www.codetriage.com/go-gitea/gitea/badges/users.svg)](https://www.codetriage.com/go-gitea/gitea "Help Contribute to Open Source")
[![](https://opencollective.com/gitea/tiers/backers/badge.svg?label=backers&color=brightgreen)](https://opencollective.com/gitea "Become a backer/sponsor of gitea")
[![](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT "License: MIT")
[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod&color=green)](https://gitpod.io/#https://github.com/go-gitea/gitea)
[![](https://badges.crowdin.net/gitea/localized.svg)](https://translate.gitea.com "Crowdin")
[繁體中文](./README.zh-tw.md) | [简体中文](./README.zh-cn.md)
+1 -2
View File
@@ -8,7 +8,6 @@
[![](https://www.codetriage.com/go-gitea/gitea/badges/users.svg)](https://www.codetriage.com/go-gitea/gitea "Help Contribute to Open Source")
[![](https://opencollective.com/gitea/tiers/backers/badge.svg?label=backers&color=brightgreen)](https://opencollective.com/gitea "Become a backer/sponsor of gitea")
[![](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT "License: MIT")
[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod&color=green)](https://gitpod.io/#https://github.com/go-gitea/gitea)
[![](https://badges.crowdin.net/gitea/localized.svg)](https://translate.gitea.com "Crowdin")
[English](./README.md) | [繁體中文](./README.zh-tw.md)
@@ -46,7 +45,7 @@
`build` 目标分为两个子目标:
- `make backend` 需要 [Go Stable](https://go.dev/dl/),所需版本在 [go.mod](/go.mod) 中定义。
- `make frontend` 需要 [Node.js LTS](https://nodejs.org/en/download/) 或更高版本。
- `make frontend` 需要 [Node.js LTS](https://nodejs.org/en/download/) 或更高版本以及 [pnpm](https://pnpm.io/installation)
需要互联网连接来下载 go 和 npm 模块。从包含预构建前端文件的官方源代码压缩包构建时,不会触发 `frontend` 目标,因此可以在没有 Node.js 的情况下构建。
+1 -2
View File
@@ -8,7 +8,6 @@
[![](https://www.codetriage.com/go-gitea/gitea/badges/users.svg)](https://www.codetriage.com/go-gitea/gitea "Help Contribute to Open Source")
[![](https://opencollective.com/gitea/tiers/backers/badge.svg?label=backers&color=brightgreen)](https://opencollective.com/gitea "Become a backer/sponsor of gitea")
[![](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT "License: MIT")
[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod&color=green)](https://gitpod.io/#https://github.com/go-gitea/gitea)
[![](https://badges.crowdin.net/gitea/localized.svg)](https://translate.gitea.com "Crowdin")
[English](./README.md) | [简体中文](./README.zh-cn.md)
@@ -46,7 +45,7 @@
`build` 目標分為兩個子目標:
- `make backend` 需要 [Go Stable](https://go.dev/dl/),所需版本在 [go.mod](/go.mod) 中定義。
- `make frontend` 需要 [Node.js LTS](https://nodejs.org/en/download/) 或更高版本。
- `make frontend` 需要 [Node.js LTS](https://nodejs.org/en/download/) 或更高版本以及 [pnpm](https://pnpm.io/installation)
需要互聯網連接來下載 go 和 npm 模塊。從包含預構建前端文件的官方源代碼壓縮包構建時,不會觸發 `frontend` 目標,因此可以在沒有 Node.js 的情況下構建。
+11483 -1
View File
File diff suppressed because one or more lines are too long
+162 -142
View File
File diff suppressed because one or more lines are too long
-14
View File
@@ -1,14 +0,0 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
//go:build vendor
package main
// Libraries that are included to vendor utilities used during Makefile build.
// These libraries will not be included in a normal compilation.
import (
// for vet
_ "code.gitea.io/gitea-vet"
)
-115
View File
@@ -1,115 +0,0 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
//go:build ignore
package main
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/setting"
)
func main() {
if len(os.Args) != 2 {
println("usage: backport-locales <to-ref>")
println("eg: backport-locales release/v1.19")
os.Exit(1)
}
mustNoErr := func(err error) {
if err != nil {
panic(err)
}
}
collectInis := func(ref string) map[string]setting.ConfigProvider {
inis := map[string]setting.ConfigProvider{}
err := filepath.WalkDir("options/locale", func(path string, d os.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() || !strings.HasSuffix(d.Name(), ".ini") {
return nil
}
cfg, err := setting.NewConfigProviderForLocale(path)
mustNoErr(err)
inis[path] = cfg
fmt.Printf("collecting: %s @ %s\n", path, ref)
return nil
})
mustNoErr(err)
return inis
}
// collect new locales from current working directory
inisNew := collectInis("HEAD")
// switch to the target ref, and collect the old locales
cmd := exec.Command("git", "checkout", os.Args[1])
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
mustNoErr(cmd.Run())
inisOld := collectInis(os.Args[1])
// use old en-US as the base, and copy the new translations to the old locales
enUsOld := inisOld["options/locale/locale_en-US.ini"]
brokenWarned := make(container.Set[string])
for path, iniOld := range inisOld {
if iniOld == enUsOld {
continue
}
iniNew := inisNew[path]
if iniNew == nil {
continue
}
for _, secEnUS := range enUsOld.Sections() {
secOld := iniOld.Section(secEnUS.Name())
secNew := iniNew.Section(secEnUS.Name())
for _, keyEnUs := range secEnUS.Keys() {
if secNew.HasKey(keyEnUs.Name()) {
oldStr := secOld.Key(keyEnUs.Name()).String()
newStr := secNew.Key(keyEnUs.Name()).String()
broken := oldStr != "" && strings.Count(oldStr, "%") != strings.Count(newStr, "%")
broken = broken || strings.Contains(oldStr, "\n") || strings.Contains(oldStr, "\n")
if broken {
brokenWarned.Add(secOld.Name() + "." + keyEnUs.Name())
fmt.Println("----")
fmt.Printf("WARNING: skip broken locale: %s , [%s] %s\n", path, secEnUS.Name(), keyEnUs.Name())
fmt.Printf("\told: %s\n", strings.ReplaceAll(oldStr, "\n", "\\n"))
fmt.Printf("\tnew: %s\n", strings.ReplaceAll(newStr, "\n", "\\n"))
continue
}
secOld.Key(keyEnUs.Name()).SetValue(newStr)
}
}
}
mustNoErr(iniOld.SaveTo(path))
}
fmt.Println("========")
for path, iniNew := range inisNew {
for _, sec := range iniNew.Sections() {
for _, key := range sec.Keys() {
str := sec.Key(key.Name()).String()
broken := strings.Contains(str, "\n")
broken = broken || strings.HasPrefix(str, "`") != strings.HasSuffix(str, "`")
broken = broken || strings.HasPrefix(str, "\"`")
broken = broken || strings.HasPrefix(str, "`\"")
broken = broken || strings.Count(str, `"`)%2 == 1
broken = broken || strings.Count(str, "`")%2 == 1
if broken && !brokenWarned.Contains(sec.Name()+"."+key.Name()) {
fmt.Printf("WARNING: found broken locale: %s , [%s] %s\n", path, sec.Name(), key.Name())
fmt.Printf("\tstr: %s\n", strings.ReplaceAll(str, "\n", "\\n"))
fmt.Println("----")
}
}
}
}
}
+4 -4
View File
@@ -24,8 +24,8 @@ import (
)
const (
gemojiURL = "https://raw.githubusercontent.com/github/gemoji/master/db/emoji.json"
maxUnicodeVersion = 15
gemojiURL = "https://raw.githubusercontent.com/rhysd/gemoji/537ff2d7e0496e9964824f7f73ec7ece88c9765a/db/emoji.json"
maxUnicodeVersion = 16
)
var flagOut = flag.String("o", "modules/emoji/emoji_data.go", "out")
@@ -149,8 +149,8 @@ func generate() ([]byte, error) {
}
// write a JSON file to use with tribute (write before adding skin tones since we can't support them there yet)
file, _ := json.Marshal(data)
_ = os.WriteFile("assets/emoji.json", file, 0o644)
file, _ := json.MarshalIndent(data, "", " ")
_ = os.WriteFile("assets/emoji.json", append(file, '\n'), 0o644)
// Add skin tones to emoji that support it
var (
+180 -59
View File
@@ -8,99 +8,220 @@ package main
import (
"encoding/json"
"fmt"
"io/fs"
"os"
"path"
"os/exec"
"path/filepath"
"regexp"
"slices"
"sort"
"strings"
"code.gitea.io/gitea/modules/container"
)
// regexp is based on go-license, excluding README and NOTICE
// https://github.com/google/go-licenses/blob/master/licenses/find.go
// also defined in vite.config.ts
var licenseRe = regexp.MustCompile(`^(?i)((UN)?LICEN(S|C)E|COPYING).*$`)
// primaryLicenseRe matches exact primary license filenames without suffixes.
// When a directory has both primary and variant files (e.g. LICENSE and
// LICENSE.docs), only the primary files are kept.
var primaryLicenseRe = regexp.MustCompile(`^(?i)(LICEN[SC]E|COPYING)$`)
// ignoredNames are LicenseEntry.Name values to exclude from the output.
var ignoredNames = map[string]bool{
"code.gitea.io/gitea": true,
"code.gitea.io/gitea/options/license": true,
}
var excludedExt = map[string]bool{
".gitignore": true,
".go": true,
".mod": true,
".sum": true,
".toml": true,
".yaml": true,
".yml": true,
}
type ModuleInfo struct {
Path string
Dir string
PkgDirs []string // directories of packages imported from this module
}
type LicenseEntry struct {
Name string `json:"name"`
Path string `json:"path"`
LicenseText string `json:"licenseText"`
}
func main() {
if len(os.Args) != 3 {
fmt.Println("usage: go run generate-go-licenses.go <base-dir> <out-json-file>")
// getModules returns all dependency modules with their local directory paths
// and the package directories used from each module.
func getModules(goCmd string) []ModuleInfo {
cmd := exec.Command(goCmd, "list", "-deps", "-f",
"{{if .Module}}{{.Module.Path}}\t{{.Module.Dir}}\t{{.Dir}}{{end}}", "./...")
cmd.Stderr = os.Stderr
// Use GOOS=linux with CGO to ensure we capture all platform-specific
// dependencies, matching the CI environment.
cmd.Env = append(os.Environ(), "GOOS=linux", "GOARCH=amd64", "CGO_ENABLED=1")
output, err := cmd.Output()
if err != nil {
fmt.Fprintf(os.Stderr, "failed to run 'go list -deps': %v\n", err)
os.Exit(1)
}
base, out := os.Args[1], os.Args[2]
// Add ext for excluded files because license_test.go will be included for some reason.
// And there are more files that should be excluded, check with:
//
// go run github.com/google/go-licenses@v1.6.0 save . --force --save_path=.go-licenses 2>/dev/null
// find .go-licenses -type f | while read FILE; do echo "${$(basename $FILE)##*.}"; done | sort -u
// AUTHORS
// COPYING
// LICENSE
// Makefile
// NOTICE
// gitignore
// go
// md
// mod
// sum
// toml
// txt
// yml
//
// It could be removed once we have a better regex.
excludedExt := container.SetOf(".gitignore", ".go", ".mod", ".sum", ".toml", ".yml")
var paths []string
err := filepath.WalkDir(base, func(path string, entry fs.DirEntry, err error) error {
if err != nil {
return err
var modules []ModuleInfo
seen := make(map[string]int) // module path -> index in modules
for _, line := range strings.Split(string(output), "\n") {
line = strings.TrimSpace(line)
if line == "" {
continue
}
if entry.IsDir() || !licenseRe.MatchString(entry.Name()) || excludedExt.Contains(filepath.Ext(entry.Name())) {
return nil
parts := strings.Split(line, "\t")
if len(parts) != 3 {
continue
}
paths = append(paths, path)
return nil
})
if err != nil {
panic(err)
modPath, modDir, pkgDir := parts[0], parts[1], parts[2]
if idx, ok := seen[modPath]; ok {
modules[idx].PkgDirs = append(modules[idx].PkgDirs, pkgDir)
} else {
seen[modPath] = len(modules)
modules = append(modules, ModuleInfo{
Path: modPath,
Dir: modDir,
PkgDirs: []string{pkgDir},
})
}
}
return modules
}
// findLicenseFiles scans a module's root directory and its used package
// directories for license files. It also walks up from each package directory
// to the module root, scanning intermediate directories. Subdirectory licenses
// are only included if their text differs from the root license(s).
func findLicenseFiles(mod ModuleInfo) []LicenseEntry {
var entries []LicenseEntry
seenTexts := make(map[string]bool)
// First, collect root-level license files.
entries = append(entries, scanDirForLicenses(mod.Dir, mod.Path, "")...)
for _, e := range entries {
seenTexts[e.LicenseText] = true
}
sort.Strings(paths)
// Then check each package directory and all intermediate parent directories
// up to the module root for license files with unique text.
seenDirs := map[string]bool{mod.Dir: true}
for _, pkgDir := range mod.PkgDirs {
for dir := pkgDir; dir != mod.Dir && strings.HasPrefix(dir, mod.Dir); dir = filepath.Dir(dir) {
if seenDirs[dir] {
continue
}
seenDirs[dir] = true
for _, e := range scanDirForLicenses(dir, mod.Path, mod.Dir) {
if !seenTexts[e.LicenseText] {
seenTexts[e.LicenseText] = true
entries = append(entries, e)
}
}
}
}
return entries
}
// scanDirForLicenses reads a single directory for license files and returns entries.
// If moduleRoot is non-empty, paths are made relative to it.
func scanDirForLicenses(dir, modulePath, moduleRoot string) []LicenseEntry {
dirEntries, err := os.ReadDir(dir)
if err != nil {
return nil
}
var entries []LicenseEntry
for _, filePath := range paths {
licenseText, err := os.ReadFile(filePath)
if err != nil {
panic(err)
for _, entry := range dirEntries {
if entry.IsDir() {
continue
}
pkgPath := filepath.ToSlash(filePath)
pkgPath = strings.TrimPrefix(pkgPath, base+"/")
pkgName := path.Dir(pkgPath)
// There might be a bug somewhere in go-licenses that sometimes interprets the
// root package as "." and sometimes as "code.gitea.io/gitea". Workaround by
// removing both of them for the sake of stable output.
if pkgName == "." || pkgName == "code.gitea.io/gitea" {
name := entry.Name()
if !licenseRe.MatchString(name) {
continue
}
if excludedExt[strings.ToLower(filepath.Ext(name))] {
continue
}
content, err := os.ReadFile(filepath.Join(dir, name))
if err != nil {
continue
}
entryName := modulePath
entryPath := modulePath + "/" + name
if moduleRoot != "" {
rel, _ := filepath.Rel(moduleRoot, dir)
if rel != "." {
relSlash := filepath.ToSlash(rel)
entryName = modulePath + "/" + relSlash
entryPath = modulePath + "/" + relSlash + "/" + name
}
}
entries = append(entries, LicenseEntry{
Name: pkgName,
Path: pkgPath,
LicenseText: string(licenseText),
Name: entryName,
Path: entryPath,
LicenseText: string(content),
})
}
// When multiple license files exist, prefer primary files (e.g. LICENSE)
// over variants with suffixes (e.g. LICENSE.docs, LICENSE-2.0.txt).
// If no primary file exists, keep only the first variant.
if len(entries) > 1 {
var primary []LicenseEntry
for _, e := range entries {
fileName := e.Path[strings.LastIndex(e.Path, "/")+1:]
if primaryLicenseRe.MatchString(fileName) {
primary = append(primary, e)
}
}
if len(primary) > 0 {
return primary
}
return entries[:1]
}
return entries
}
func main() {
if len(os.Args) != 2 {
fmt.Println("usage: go run generate-go-licenses.go <out-json-file>")
os.Exit(1)
}
out := os.Args[1]
goCmd := "go"
if env := os.Getenv("GO"); env != "" {
goCmd = env
}
modules := getModules(goCmd)
var entries []LicenseEntry
for _, mod := range modules {
entries = append(entries, findLicenseFiles(mod)...)
}
entries = slices.DeleteFunc(entries, func(e LicenseEntry) bool {
return ignoredNames[e.Name]
})
sort.Slice(entries, func(i, j int) bool {
return entries[i].Path < entries[j].Path
})
jsonBytes, err := json.MarshalIndent(entries, "", " ")
if err != nil {
panic(err)
+7 -37
View File
@@ -1,52 +1,22 @@
#!/bin/sh
# this script runs in alpine image which only has `sh` shell
set +e
if sed --version 2>/dev/null | grep -q GNU; then
SED_INPLACE="sed -i"
else
SED_INPLACE="sed -i ''"
fi
set -e
if [ ! -f ./options/locale/locale_en-US.ini ]; then
if [ ! -f ./options/locale/locale_en-US.json ]; then
echo "please run this script in the root directory of the project"
exit 1
fi
mv ./options/locale/locale_en-US.ini ./options/
# the "ini" library for locale has many quirks, its behavior is different from Crowdin.
# see i18n_test.go for more details
# this script helps to unquote the Crowdin outputs for the quirky ini library
# * find all `key="...\"..."` lines
# * remove the leading quote
# * remove the trailing quote
# * unescape the quotes
# * eg: key="...\"..." => key=..."...
$SED_INPLACE -r -e '/^[-.A-Za-z0-9_]+[ ]*=[ ]*".*"$/ {
s/^([-.A-Za-z0-9_]+)[ ]*=[ ]*"/\1=/
s/"$//
s/\\"/"/g
}' ./options/locale/*.ini
# * if the escaped line is incomplete like `key="...` or `key=..."`, quote it with backticks
# * eg: key="... => key=`"...`
# * eg: key=..." => key=`..."`
$SED_INPLACE -r -e 's/^([-.A-Za-z0-9_]+)[ ]*=[ ]*(".*[^"])$/\1=`\2`/' ./options/locale/*.ini
$SED_INPLACE -r -e 's/^([-.A-Za-z0-9_]+)[ ]*=[ ]*([^"].*")$/\1=`\2`/' ./options/locale/*.ini
mv ./options/locale/locale_en-US.json ./options/
# Remove translation under 25% of en_us
baselines=$(wc -l "./options/locale_en-US.ini" | cut -d" " -f1)
baselines=$(cat "./options/locale_en-US.json" | wc -l)
baselines=$((baselines / 4))
for filename in ./options/locale/*.ini; do
lines=$(wc -l "$filename" | cut -d" " -f1)
if [ $lines -lt $baselines ]; then
for filename in ./options/locale/*.json; do
lines=$(cat "$filename" | wc -l)
if [ "$lines" -lt "$baselines" ]; then
echo "Removing $filename: $lines/$baselines"
rm "$filename"
fi
done
mv ./options/locale_en-US.ini ./options/locale/
mv ./options/locale_en-US.json ./options/locale/
+7 -6
View File
@@ -13,17 +13,18 @@ import (
"github.com/urfave/cli/v3"
)
var (
// CmdActions represents the available actions sub-commands.
CmdActions = &cli.Command{
func newActionsCommand() *cli.Command {
return &cli.Command{
Name: "actions",
Usage: "Manage Gitea Actions",
Commands: []*cli.Command{
subcmdActionsGenRunnerToken,
newActionsGenerateRunnerTokenCommand(),
},
}
}
subcmdActionsGenRunnerToken = &cli.Command{
func newActionsGenerateRunnerTokenCommand() *cli.Command {
return &cli.Command{
Name: "generate-runner-token",
Usage: "Generate a new token for a runner to use to register with the server",
Action: runGenerateActionsRunnerToken,
@@ -37,7 +38,7 @@ var (
},
},
}
)
}
func runGenerateActionsRunnerToken(ctx context.Context, c *cli.Command) error {
setting.MustInstalled()
+27 -20
View File
@@ -18,36 +18,41 @@ import (
"github.com/urfave/cli/v3"
)
var (
// CmdAdmin represents the available admin sub-command.
CmdAdmin = &cli.Command{
func newAdminCommand() *cli.Command {
return &cli.Command{
Name: "admin",
Usage: "Perform common administrative operations",
Commands: []*cli.Command{
subcmdUser,
subcmdRepoSyncReleases,
subcmdRegenerate,
subcmdAuth,
subcmdSendMail,
newUserCommand(),
newRepoSyncReleasesCommand(),
newRegenerateCommand(),
newAuthCommand(),
newSendMailCommand(),
},
}
}
subcmdRepoSyncReleases = &cli.Command{
func newRepoSyncReleasesCommand() *cli.Command {
return &cli.Command{
Name: "repo-sync-releases",
Usage: "Synchronize repository releases with tags",
Action: runRepoSyncReleases,
}
}
subcmdRegenerate = &cli.Command{
func newRegenerateCommand() *cli.Command {
return &cli.Command{
Name: "regenerate",
Usage: "Regenerate specific files",
Commands: []*cli.Command{
microcmdRegenHooks,
microcmdRegenKeys,
newRegenerateHooksCommand(),
newRegenerateKeysCommand(),
},
}
}
subcmdAuth = &cli.Command{
func newAuthCommand() *cli.Command {
return &cli.Command{
Name: "auth",
Usage: "Modify external auth providers",
Commands: []*cli.Command{
@@ -59,12 +64,14 @@ var (
microcmdAuthUpdateLdapSimpleAuth(),
microcmdAuthAddSMTP(),
microcmdAuthUpdateSMTP(),
microcmdAuthList,
microcmdAuthDelete,
newAuthListCommand(),
newAuthDeleteCommand(),
},
}
}
subcmdSendMail = &cli.Command{
func newSendMailCommand() *cli.Command {
return &cli.Command{
Name: "sendmail",
Usage: "Send a message to all users",
Action: runSendMail,
@@ -86,7 +93,7 @@ var (
},
},
}
)
}
func idFlag() *cli.Int64Flag {
return &cli.Int64Flag{
@@ -121,7 +128,7 @@ func runRepoSyncReleases(ctx context.Context, _ *cli.Command) error {
}
log.Trace("Processing next %d repos of %d", len(repos), count)
for _, repo := range repos {
log.Trace("Synchronizing repo %s with path %s", repo.FullName(), repo.RepoPath())
log.Trace("Synchronizing repo %s with path %s", repo.FullName(), repo.RelativePath())
gitRepo, err := gitrepo.OpenRepository(ctx, repo)
if err != nil {
log.Warn("OpenRepository: %v", err)
@@ -134,7 +141,7 @@ func runRepoSyncReleases(ctx context.Context, _ *cli.Command) error {
}
log.Trace(" currentNumReleases is %d, running SyncReleasesWithTags", oldnum)
if err = repo_module.SyncReleasesWithTags(ctx, repo, gitRepo); err != nil {
if _, err = repo_module.SyncReleasesWithTags(ctx, repo, gitRepo); err != nil {
log.Warn(" SyncReleasesWithTags: %v", err)
gitRepo.Close()
continue
@@ -147,7 +154,7 @@ func runRepoSyncReleases(ctx context.Context, _ *cli.Command) error {
continue
}
log.Trace(" repo %s releases synchronized to tags: from %d to %d",
log.Trace("repo %s releases synchronized to tags: from %d to %d",
repo.FullName(), oldnum, count)
gitRepo.Close()
}
+7 -4
View File
@@ -17,14 +17,17 @@ import (
"github.com/urfave/cli/v3"
)
var (
microcmdAuthDelete = &cli.Command{
func newAuthDeleteCommand() *cli.Command {
return &cli.Command{
Name: "delete",
Usage: "Delete specific auth source",
Flags: []cli.Flag{idFlag()},
Action: runDeleteAuth,
}
microcmdAuthList = &cli.Command{
}
func newAuthListCommand() *cli.Command {
return &cli.Command{
Name: "list",
Usage: "List auth sources",
Action: runListAuth,
@@ -55,7 +58,7 @@ var (
},
},
}
)
}
func runListAuth(ctx context.Context, c *cli.Command) error {
if err := initDB(ctx); err != nil {
+7
View File
@@ -94,6 +94,10 @@ func commonLdapCLIFlags() []cli.Flag {
Name: "public-ssh-key-attribute",
Usage: "The attribute of the users LDAP record containing the users public ssh key.",
},
&cli.BoolFlag{
Name: "ssh-keys-are-verified",
Usage: "Set to true to automatically flag SSH keys in LDAP as verified.",
},
&cli.BoolFlag{
Name: "skip-local-2fa",
Usage: "Set to true to skip local 2fa for users authenticated by this source",
@@ -294,6 +298,9 @@ func parseLdapConfig(c *cli.Command, config *ldap.Source) error {
if c.IsSet("public-ssh-key-attribute") {
config.AttributeSSHPublicKey = c.String("public-ssh-key-attribute")
}
if c.IsSet("ssh-keys-are-verified") {
config.SSHKeysAreVerified = c.Bool("ssh-keys-are-verified")
}
if c.IsSet("avatar-attribute") {
config.AttributeAvatar = c.String("avatar-attribute")
}
+2 -2
View File
@@ -233,7 +233,7 @@ func TestAddLdapBindDn(t *testing.T) {
},
getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) {
assert.FailNow(t, "getAuthSourceByID called", "case %d: should not call getAuthSourceByID", n)
return nil, nil
return nil, nil //nolint:nilnil // mock function covering improper behavior
},
}
@@ -463,7 +463,7 @@ func TestAddLdapSimpleAuth(t *testing.T) {
},
getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) {
assert.FailNow(t, "getAuthSourceById called", "case %d: should not call getAuthSourceByID", n)
return nil, nil
return nil, nil //nolint:nilnil // mock function covering improper behavior
},
}
+6 -4
View File
@@ -13,19 +13,21 @@ import (
"github.com/urfave/cli/v3"
)
var (
microcmdRegenHooks = &cli.Command{
func newRegenerateHooksCommand() *cli.Command {
return &cli.Command{
Name: "hooks",
Usage: "Regenerate git-hooks",
Action: runRegenerateHooks,
}
}
microcmdRegenKeys = &cli.Command{
func newRegenerateKeysCommand() *cli.Command {
return &cli.Command{
Name: "keys",
Usage: "Regenerate authorized_keys file",
Action: runRegenerateKeys,
}
)
}
func runRegenerateHooks(ctx context.Context, _ *cli.Command) error {
if err := initDB(ctx); err != nil {
+13 -11
View File
@@ -7,15 +7,17 @@ import (
"github.com/urfave/cli/v3"
)
var subcmdUser = &cli.Command{
Name: "user",
Usage: "Modify users",
Commands: []*cli.Command{
microcmdUserCreate(),
microcmdUserList,
microcmdUserChangePassword(),
microcmdUserDelete(),
microcmdUserGenerateAccessToken,
microcmdUserMustChangePassword(),
},
func newUserCommand() *cli.Command {
return &cli.Command{
Name: "user",
Usage: "Modify users",
Commands: []*cli.Command{
microcmdUserCreate(),
newUserListCommand(),
microcmdUserChangePassword(),
microcmdUserDelete(),
newUserGenerateAccessTokenCommand(),
microcmdUserMustChangePassword(),
},
}
}
+1
View File
@@ -151,6 +151,7 @@ func runCreateUser(ctx context.Context, c *cli.Command) error {
if err != nil {
return err
}
// codeql[disable-next-line=go/clear-text-logging]
fmt.Printf("generated random password is '%s'\n", password)
} else if userType == user_model.UserTypeIndividual {
return errors.New("must set either password or random-password flag")
+27 -25
View File
@@ -14,32 +14,34 @@ import (
"github.com/urfave/cli/v3"
)
var microcmdUserGenerateAccessToken = &cli.Command{
Name: "generate-access-token",
Usage: "Generate an access token for a specific user",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "username",
Aliases: []string{"u"},
Usage: "Username",
func newUserGenerateAccessTokenCommand() *cli.Command {
return &cli.Command{
Name: "generate-access-token",
Usage: "Generate an access token for a specific user",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "username",
Aliases: []string{"u"},
Usage: "Username",
},
&cli.StringFlag{
Name: "token-name",
Aliases: []string{"t"},
Usage: "Token name",
Value: "gitea-admin",
},
&cli.BoolFlag{
Name: "raw",
Usage: "Display only the token value",
},
&cli.StringFlag{
Name: "scopes",
Value: "all",
Usage: `Comma separated list of scopes to apply to access token, examples: "all", "public-only,read:issue", "write:repository,write:user"`,
},
},
&cli.StringFlag{
Name: "token-name",
Aliases: []string{"t"},
Usage: "Token name",
Value: "gitea-admin",
},
&cli.BoolFlag{
Name: "raw",
Usage: "Display only the token value",
},
&cli.StringFlag{
Name: "scopes",
Value: "all",
Usage: `Comma separated list of scopes to apply to access token, examples: "all", "public-only,read:issue", "write:repository,write:user"`,
},
},
Action: runGenerateAccessToken,
Action: runGenerateAccessToken,
}
}
func runGenerateAccessToken(ctx context.Context, c *cli.Command) error {
+11 -9
View File
@@ -14,16 +14,18 @@ import (
"github.com/urfave/cli/v3"
)
var microcmdUserList = &cli.Command{
Name: "list",
Usage: "List users",
Action: runListUsers,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "admin",
Usage: "List only admin users",
func newUserListCommand() *cli.Command {
return &cli.Command{
Name: "list",
Usage: "List users",
Action: runListUsers,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "admin",
Usage: "List only admin users",
},
},
},
}
}
func runListUsers(ctx context.Context, c *cli.Command) error {
+1
View File
@@ -58,6 +58,7 @@ func runMustChangePassword(ctx context.Context, c *cli.Command) error {
return err
}
// codeql[disable-next-line=go/clear-text-logging]
fmt.Printf("Updated %d users setting MustChangePassword to %t\n", n, mustChangePassword)
return nil
}
+6
View File
@@ -121,6 +121,12 @@ func globalBool(c *cli.Command, name string) bool {
// Any log appears in git stdout pipe will break the git protocol, eg: client can't push and hangs forever.
func PrepareConsoleLoggerLevel(defaultLevel log.Level) func(context.Context, *cli.Command) (context.Context, error) {
return func(ctx context.Context, c *cli.Command) (context.Context, error) {
if setting.InstallLock {
// During config loading, there might also be logs (for example: deprecation warnings).
// It must make sure that console logger is set up before config is loaded.
log.Error("Config is loaded before console logger is setup, it will cause bugs. Please fix it.")
return nil, errors.New("console logger must be setup before config is loaded")
}
level := defaultLevel
if globalBool(c, "quiet") {
level = log.FATAL
+156
View File
@@ -0,0 +1,156 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"context"
"errors"
"fmt"
"os"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli/v3"
)
func cmdConfig() *cli.Command {
subcmdConfigEditIni := &cli.Command{
Name: "edit-ini",
Usage: "Load an existing INI file, apply environment variables, keep specified keys, and output to a new INI file.",
Description: `
Help users to edit the Gitea configuration INI file.
# Keep Specified Keys
If you need to re-create the configuration file with only a subset of keys,
you can provide an INI template file for the kept keys and use the "--config-keep-keys" flag.
For example, if a helm chart needs to reset the settings and only keep SECRET_KEY,
it can use a template file (only keys take effect, values are ignored):
[security]
SECRET_KEY=
$ ./gitea config edit-ini --config app-old.ini --config-keep-keys app-keys.ini --out app-new.ini
# Map Environment Variables to INI Configuration
Environment variables of the form "GITEA__section_name__KEY_NAME"
will be mapped to the ini section "[section_name]" and the key
"KEY_NAME" with the value as provided.
Environment variables of the form "GITEA__section_name__KEY_NAME__FILE"
will be mapped to the ini section "[section_name]" and the key
"KEY_NAME" with the value loaded from the specified file.
Environment variable keys can only contain characters "0-9A-Z_",
if a section or key name contains dot ".", it needs to be escaped as _0x2E_.
For example, to apply this config:
[git.config]
foo.bar=val
$ export GITEA__git_0x2E_config__foo_0x2E_bar=val
# Put All Together
$ ./gitea config edit-ini --config app.ini --config-keep-keys app-keys.ini --apply-env {--in-place|--out app-new.ini}
`,
Flags: []cli.Flag{
// "--config" flag is provided by global flags, and this flag is also used by "environment-to-ini" script wrapper
// "--in-place" is also used by "environment-to-ini" script wrapper for its old behavior: always overwrite the existing config file
&cli.BoolFlag{
Name: "in-place",
Usage: "Output to the same config file as input. This flag will be ignored if --out is set.",
},
&cli.StringFlag{
Name: "config-keep-keys",
Usage: "An INI template file containing keys for keeping. Only the keys defined in the INI template will be kept from old config. If not set, all keys will be kept.",
},
&cli.BoolFlag{
Name: "apply-env",
Usage: "Apply all GITEA__* variables from the environment to the config.",
},
&cli.StringFlag{
Name: "out",
Usage: "Destination config file to write to.",
},
},
Action: runConfigEditIni,
}
return &cli.Command{
Name: "config",
Usage: "Manage Gitea configuration",
Commands: []*cli.Command{
subcmdConfigEditIni,
},
}
}
func runConfigEditIni(_ context.Context, c *cli.Command) error {
// the config system may change the environment variables, so get a copy first, to be used later
env := append([]string{}, os.Environ()...)
// don't use the guessed setting.CustomConf, instead, require the user to provide --config explicitly
if !c.IsSet("config") {
return errors.New("flag is required but not set: --config")
}
configFileIn := c.String("config")
cfgIn, err := setting.NewConfigProviderFromFile(configFileIn)
if err != nil {
return fmt.Errorf("failed to load config file %q: %v", configFileIn, err)
}
// determine output config file: use "--out" flag or use "--in-place" flag to overwrite input file
inPlace := c.Bool("in-place")
configFileOut := c.String("out")
if configFileOut == "" {
if !inPlace {
return errors.New("either --in-place or --out must be specified")
}
configFileOut = configFileIn // in-place edit
}
needWriteOut := configFileOut != configFileIn
cfgOut := cfgIn
configKeepKeys := c.String("config-keep-keys")
if configKeepKeys != "" {
needWriteOut = true
cfgOut, err = setting.NewConfigProviderFromFile(configKeepKeys)
if err != nil {
return fmt.Errorf("failed to load config-keep-keys template file %q: %v", configKeepKeys, err)
}
for _, secOut := range cfgOut.Sections() {
for _, keyOut := range secOut.Keys() {
secIn := cfgIn.Section(secOut.Name())
keyIn := setting.ConfigSectionKey(secIn, keyOut.Name())
if keyIn != nil {
keyOut.SetValue(keyIn.String())
} else {
secOut.DeleteKey(keyOut.Name())
}
}
if len(secOut.Keys()) == 0 {
cfgOut.DeleteSection(secOut.Name())
}
}
}
if c.Bool("apply-env") {
if setting.EnvironmentToConfig(cfgOut, env) {
needWriteOut = true
}
}
if needWriteOut {
err = cfgOut.SaveTo(configFileOut)
if err != nil {
return err
}
}
return nil
}
+85
View File
@@ -0,0 +1,85 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"os"
"testing"
"github.com/stretchr/testify/require"
)
func TestConfigEdit(t *testing.T) {
tmpDir := t.TempDir()
configOld := tmpDir + "/app-old.ini"
configTemplate := tmpDir + "/app-template.ini"
_ = os.WriteFile(configOld, []byte(`
[sec]
k1=v1
k2=v2
`), os.ModePerm)
_ = os.WriteFile(configTemplate, []byte(`
[sec]
k1=in-template
[sec2]
k3=v3
`), os.ModePerm)
t.Setenv("GITEA__EnV__KeY", "val")
t.Run("OutputToNewWithEnv", func(t *testing.T) {
configNew := tmpDir + "/app-new.ini"
err := NewMainApp(AppVersion{}).Run(t.Context(), []string{
"./gitea", "--config", configOld,
"config", "edit-ini",
"--apply-env",
"--config-keep-keys", configTemplate,
"--out", configNew,
})
require.NoError(t, err)
// "k1" old value is kept because its key is in the template
// "k2" is removed because it isn't in the template
// "k3" isn't in new config because it isn't in the old config
// [env] is applied from environment variable
data, _ := os.ReadFile(configNew)
require.Equal(t, `[sec]
k1 = v1
[env]
KeY = val
`, string(data))
})
t.Run("OutputToExisting(environment-to-ini)", func(t *testing.T) {
// the legacy "environment-to-ini" (now a wrapper script) behavior:
// if no "--out", then "--in-place" must be used to overwrite the existing "--config" file
err := NewMainApp(AppVersion{}).Run(t.Context(), []string{
"./gitea", "config", "edit-ini",
"--apply-env",
"--config", configOld,
})
require.ErrorContains(t, err, "either --in-place or --out must be specified")
// simulate the "environment-to-ini" behavior with "--in-place"
err = NewMainApp(AppVersion{}).Run(t.Context(), []string{
"./gitea", "config", "edit-ini",
"--in-place",
"--apply-env",
"--config", configOld,
})
require.NoError(t, err)
data, _ := os.ReadFile(configOld)
require.Equal(t, `[sec]
k1 = v1
k2 = v2
[env]
KeY = val
`, string(data))
})
}
+17 -16
View File
@@ -13,23 +13,24 @@ import (
"github.com/urfave/cli/v3"
)
// CmdDocs represents the available docs sub-command.
var CmdDocs = &cli.Command{
Name: "docs",
Usage: "Output CLI documentation",
Description: "A command to output Gitea's CLI documentation, optionally to a file.",
Action: runDocs,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "man",
Usage: "Output man pages instead",
func newDocsCommand() *cli.Command {
return &cli.Command{
Name: "docs",
Usage: "Output CLI documentation",
Description: "A command to output Gitea's CLI documentation, optionally to a file.",
Action: runDocs,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "man",
Usage: "Output man pages instead",
},
&cli.StringFlag{
Name: "output",
Aliases: []string{"o"},
Usage: "Path to output to instead of stdout (will overwrite if exists)",
},
},
&cli.StringFlag{
Name: "output",
Aliases: []string{"o"},
Usage: "Path to output to instead of stdout (will overwrite if exists)",
},
},
}
}
func runDocs(_ context.Context, cmd *cli.Command) error {
+61 -57
View File
@@ -24,73 +24,77 @@ import (
"xorm.io/xorm"
)
// CmdDoctor represents the available doctor sub-command.
var CmdDoctor = &cli.Command{
Name: "doctor",
Usage: "Diagnose and optionally fix problems, convert or re-create database tables",
Description: "A command to diagnose problems with the current Gitea instance according to the given configuration. Some problems can optionally be fixed by modifying the database or data storage.",
Commands: []*cli.Command{
cmdDoctorCheck,
cmdRecreateTable,
cmdDoctorConvert,
},
func newDoctorCommand() *cli.Command {
return &cli.Command{
Name: "doctor",
Usage: "Diagnose and optionally fix problems, convert or re-create database tables",
Description: "A command to diagnose problems with the current Gitea instance according to the given configuration. Some problems can optionally be fixed by modifying the database or data storage.",
Commands: []*cli.Command{
newDoctorCheckCommand(),
newRecreateTableCommand(),
newDoctorConvertCommand(),
},
}
}
var cmdDoctorCheck = &cli.Command{
Name: "check",
Usage: "Diagnose and optionally fix problems",
Description: "A command to diagnose problems with the current Gitea instance according to the given configuration. Some problems can optionally be fixed by modifying the database or data storage.",
Action: runDoctorCheck,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "list",
Usage: "List the available checks",
func newDoctorCheckCommand() *cli.Command {
return &cli.Command{
Name: "check",
Usage: "Diagnose and optionally fix problems",
Description: "A command to diagnose problems with the current Gitea instance according to the given configuration. Some problems can optionally be fixed by modifying the database or data storage.",
Action: runDoctorCheck,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "list",
Usage: "List the available checks",
},
&cli.BoolFlag{
Name: "default",
Usage: "Run the default checks (if neither --run or --all is set, this is the default behaviour)",
},
&cli.StringSliceFlag{
Name: "run",
Usage: "Run the provided checks - (if --default is set, the default checks will also run)",
},
&cli.BoolFlag{
Name: "all",
Usage: "Run all the available checks",
},
&cli.BoolFlag{
Name: "fix",
Usage: "Automatically fix what we can",
},
&cli.StringFlag{
Name: "log-file",
Usage: `Name of the log file (no verbose log output by default). Set to "-" to output to stdout`,
},
&cli.BoolFlag{
Name: "color",
Aliases: []string{"H"},
Usage: "Use color for outputted information",
},
},
&cli.BoolFlag{
Name: "default",
Usage: "Run the default checks (if neither --run or --all is set, this is the default behaviour)",
},
&cli.StringSliceFlag{
Name: "run",
Usage: "Run the provided checks - (if --default is set, the default checks will also run)",
},
&cli.BoolFlag{
Name: "all",
Usage: "Run all the available checks",
},
&cli.BoolFlag{
Name: "fix",
Usage: "Automatically fix what we can",
},
&cli.StringFlag{
Name: "log-file",
Usage: `Name of the log file (no verbose log output by default). Set to "-" to output to stdout`,
},
&cli.BoolFlag{
Name: "color",
Aliases: []string{"H"},
Usage: "Use color for outputted information",
},
},
}
}
var cmdRecreateTable = &cli.Command{
Name: "recreate-table",
Usage: "Recreate tables from XORM definitions and copy the data.",
ArgsUsage: "[TABLE]... : (TABLEs to recreate - leave blank for all)",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "debug",
Usage: "Print SQL commands sent",
func newRecreateTableCommand() *cli.Command {
return &cli.Command{
Name: "recreate-table",
Usage: "Recreate tables from XORM definitions and copy the data.",
ArgsUsage: "[TABLE]... : (TABLEs to recreate - leave blank for all)",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "debug",
Usage: "Print SQL commands sent",
},
},
},
Description: `The database definitions Gitea uses change across versions, sometimes changing default values and leaving old unused columns.
Description: `The database definitions Gitea uses change across versions, sometimes changing default values and leaving old unused columns.
This command will cause Xorm to recreate tables, copying over the data and deleting the old table.
You should back-up your database before doing this and ensure that your database is up-to-date first.`,
Action: runRecreateTable,
Action: runRecreateTable,
}
}
func runRecreateTable(ctx context.Context, cmd *cli.Command) error {
+7 -6
View File
@@ -14,12 +14,13 @@ import (
"github.com/urfave/cli/v3"
)
// cmdDoctorConvert represents the available convert sub-command.
var cmdDoctorConvert = &cli.Command{
Name: "convert",
Usage: "Convert the database",
Description: "A command to convert an existing MySQL database from utf8 to utf8mb4 or MSSQL database from varchar to nvarchar",
Action: runDoctorConvert,
func newDoctorConvertCommand() *cli.Command {
return &cli.Command{
Name: "convert",
Usage: "Convert the database",
Description: "A command to convert an existing MySQL database from utf8 to utf8mb4 or MSSQL database from varchar to nvarchar",
Action: runDoctorConvert,
}
}
func runDoctorConvert(ctx context.Context, cmd *cli.Command) error {
+1 -1
View File
@@ -23,7 +23,7 @@ func TestDoctorRun(t *testing.T) {
SkipDatabaseInitialization: true,
})
app := &cli.Command{
Commands: []*cli.Command{cmdDoctorCheck},
Commands: []*cli.Command{newDoctorCheckCommand()},
}
err := app.Run(t.Context(), []string{"./gitea", "check", "--run", "test-check"})
assert.NoError(t, err)
+72 -71
View File
@@ -23,78 +23,79 @@ import (
"github.com/urfave/cli/v3"
)
// CmdDump represents the available dump sub-command.
var CmdDump = &cli.Command{
Name: "dump",
Usage: "Dump Gitea files and database",
Description: `Dump compresses all related files and database into zip file. It can be used for backup and capture Gitea server image to send to maintainer`,
Action: runDump,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "file",
Aliases: []string{"f"},
Usage: `Name of the dump file which will be created, default to "gitea-dump-{time}.zip". Supply '-' for stdout. See type for available types.`,
func newDumpCommand() *cli.Command {
return &cli.Command{
Name: "dump",
Usage: "Dump Gitea files and database",
Description: `Dump compresses all related files and database into zip file. It can be used for backup and capture Gitea server image to send to maintainer`,
Action: runDump,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "file",
Aliases: []string{"f"},
Usage: `Name of the dump file which will be created, default to "gitea-dump-{time}.zip". Supply '-' for stdout. See type for available types.`,
},
&cli.BoolFlag{
Name: "verbose",
Aliases: []string{"V"},
Usage: "Show process details",
},
&cli.BoolFlag{
Name: "quiet",
Aliases: []string{"q"},
Usage: "Only display warnings and errors",
},
&cli.StringFlag{
Name: "tempdir",
Aliases: []string{"t"},
Value: os.TempDir(),
Usage: "Temporary dir path",
},
&cli.StringFlag{
Name: "database",
Aliases: []string{"d"},
Usage: "Specify the database SQL syntax: sqlite3, mysql, mssql, postgres",
},
&cli.BoolFlag{
Name: "skip-repository",
Aliases: []string{"R"},
Usage: "Skip the repository dumping",
},
&cli.BoolFlag{
Name: "skip-log",
Aliases: []string{"L"},
Usage: "Skip the log dumping",
},
&cli.BoolFlag{
Name: "skip-custom-dir",
Usage: "Skip custom directory",
},
&cli.BoolFlag{
Name: "skip-lfs-data",
Usage: "Skip LFS data",
},
&cli.BoolFlag{
Name: "skip-attachment-data",
Usage: "Skip attachment data",
},
&cli.BoolFlag{
Name: "skip-package-data",
Usage: "Skip package data",
},
&cli.BoolFlag{
Name: "skip-index",
Usage: "Skip bleve index data",
},
&cli.BoolFlag{
Name: "skip-db",
Usage: "Skip database",
},
&cli.StringFlag{
Name: "type",
Usage: `Dump output format, default to "zip", supported types: ` + strings.Join(dump.SupportedOutputTypes, ", "),
},
},
&cli.BoolFlag{
Name: "verbose",
Aliases: []string{"V"},
Usage: "Show process details",
},
&cli.BoolFlag{
Name: "quiet",
Aliases: []string{"q"},
Usage: "Only display warnings and errors",
},
&cli.StringFlag{
Name: "tempdir",
Aliases: []string{"t"},
Value: os.TempDir(),
Usage: "Temporary dir path",
},
&cli.StringFlag{
Name: "database",
Aliases: []string{"d"},
Usage: "Specify the database SQL syntax: sqlite3, mysql, mssql, postgres",
},
&cli.BoolFlag{
Name: "skip-repository",
Aliases: []string{"R"},
Usage: "Skip the repository dumping",
},
&cli.BoolFlag{
Name: "skip-log",
Aliases: []string{"L"},
Usage: "Skip the log dumping",
},
&cli.BoolFlag{
Name: "skip-custom-dir",
Usage: "Skip custom directory",
},
&cli.BoolFlag{
Name: "skip-lfs-data",
Usage: "Skip LFS data",
},
&cli.BoolFlag{
Name: "skip-attachment-data",
Usage: "Skip attachment data",
},
&cli.BoolFlag{
Name: "skip-package-data",
Usage: "Skip package data",
},
&cli.BoolFlag{
Name: "skip-index",
Usage: "Skip bleve index data",
},
&cli.BoolFlag{
Name: "skip-db",
Usage: "Skip database",
},
&cli.StringFlag{
Name: "type",
Usage: `Dump output format, default to "zip", supported types: ` + strings.Join(dump.SupportedOutputTypes, ", "),
},
},
}
}
func fatal(format string, args ...any) {
+54 -53
View File
@@ -22,61 +22,62 @@ import (
"github.com/urfave/cli/v3"
)
// CmdDumpRepository represents the available dump repository sub-command.
var CmdDumpRepository = &cli.Command{
Name: "dump-repo",
Usage: "Dump the repository from git/github/gitea/gitlab",
Description: "This is a command for dumping the repository data.",
Action: runDumpRepository,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "git_service",
Value: "",
Usage: "Git service, git, github, gitea, gitlab. If clone_addr could be recognized, this could be ignored.",
},
&cli.StringFlag{
Name: "repo_dir",
Aliases: []string{"r"},
Value: "./data",
Usage: "Repository dir path to store the data",
},
&cli.StringFlag{
Name: "clone_addr",
Value: "",
Usage: "The URL will be clone, currently could be a git/github/gitea/gitlab http/https URL",
},
&cli.StringFlag{
Name: "auth_username",
Value: "",
Usage: "The username to visit the clone_addr",
},
&cli.StringFlag{
Name: "auth_password",
Value: "",
Usage: "The password to visit the clone_addr",
},
&cli.StringFlag{
Name: "auth_token",
Value: "",
Usage: "The personal token to visit the clone_addr",
},
&cli.StringFlag{
Name: "owner_name",
Value: "",
Usage: "The data will be stored on a directory with owner name if not empty",
},
&cli.StringFlag{
Name: "repo_name",
Value: "",
Usage: "The data will be stored on a directory with repository name if not empty",
},
&cli.StringFlag{
Name: "units",
Value: "",
Usage: `Which items will be migrated, one or more units should be separated as comma.
func newDumpRepositoryCommand() *cli.Command {
return &cli.Command{
Name: "dump-repo",
Usage: "Dump the repository from git/github/gitea/gitlab",
Description: "This is a command for dumping the repository data.",
Action: runDumpRepository,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "git_service",
Value: "",
Usage: "Git service, git, github, gitea, gitlab. If clone_addr could be recognized, this could be ignored.",
},
&cli.StringFlag{
Name: "repo_dir",
Aliases: []string{"r"},
Value: "./data",
Usage: "Repository dir path to store the data",
},
&cli.StringFlag{
Name: "clone_addr",
Value: "",
Usage: "The URL will be clone, currently could be a git/github/gitea/gitlab http/https URL",
},
&cli.StringFlag{
Name: "auth_username",
Value: "",
Usage: "The username to visit the clone_addr",
},
&cli.StringFlag{
Name: "auth_password",
Value: "",
Usage: "The password to visit the clone_addr",
},
&cli.StringFlag{
Name: "auth_token",
Value: "",
Usage: "The personal token to visit the clone_addr",
},
&cli.StringFlag{
Name: "owner_name",
Value: "",
Usage: "The data will be stored on a directory with owner name if not empty",
},
&cli.StringFlag{
Name: "repo_name",
Value: "",
Usage: "The data will be stored on a directory with repository name if not empty",
},
&cli.StringFlag{
Name: "units",
Value: "",
Usage: `Which items will be migrated, one or more units should be separated as comma.
wiki, issues, labels, releases, release_assets, milestones, pull_requests, comments are allowed. Empty means all units.`,
},
},
},
}
}
func runDumpRepository(ctx context.Context, cmd *cli.Command) error {
+17 -12
View File
@@ -23,20 +23,23 @@ import (
"github.com/urfave/cli/v3"
)
// CmdEmbedded represents the available extract sub-command.
var (
CmdEmbedded = &cli.Command{
var matchedAssetFiles []assetFile
func newEmbeddedCommand() *cli.Command {
return &cli.Command{
Name: "embedded",
Usage: "Extract embedded resources",
Description: "A command for extracting embedded resources, like templates and images",
Commands: []*cli.Command{
subcmdList,
subcmdView,
subcmdExtract,
newEmbeddedListCommand(),
newEmbeddedViewCommand(),
newEmbeddedExtractCommand(),
},
}
}
subcmdList = &cli.Command{
func newEmbeddedListCommand() *cli.Command {
return &cli.Command{
Name: "list",
Usage: "List files matching the given pattern",
Action: runList,
@@ -48,8 +51,10 @@ var (
},
},
}
}
subcmdView = &cli.Command{
func newEmbeddedViewCommand() *cli.Command {
return &cli.Command{
Name: "view",
Usage: "View a file matching the given pattern",
Action: runView,
@@ -61,8 +66,10 @@ var (
},
},
}
}
subcmdExtract = &cli.Command{
func newEmbeddedExtractCommand() *cli.Command {
return &cli.Command{
Name: "extract",
Usage: "Extract resources",
Action: runExtract,
@@ -91,9 +98,7 @@ var (
},
},
}
matchedAssetFiles []assetFile
)
}
type assetFile struct {
fs *assetfs.LayeredFS
+21 -17
View File
@@ -15,45 +15,52 @@ import (
"github.com/urfave/cli/v3"
)
var (
// CmdGenerate represents the available generate sub-command.
CmdGenerate = &cli.Command{
func newGenerateCommand() *cli.Command {
return &cli.Command{
Name: "generate",
Usage: "Generate Gitea's secrets/keys/tokens",
Commands: []*cli.Command{
subcmdSecret,
newGenerateSecretCommand(),
},
}
}
subcmdSecret = &cli.Command{
func newGenerateSecretCommand() *cli.Command {
return &cli.Command{
Name: "secret",
Usage: "Generate a secret token",
Commands: []*cli.Command{
microcmdGenerateInternalToken,
microcmdGenerateLfsJwtSecret,
microcmdGenerateSecretKey,
newGenerateInternalTokenCommand(),
newGenerateLfsJWTSecretCommand(),
newGenerateSecretKeyCommand(),
},
}
}
microcmdGenerateInternalToken = &cli.Command{
func newGenerateInternalTokenCommand() *cli.Command {
return &cli.Command{
Name: "INTERNAL_TOKEN",
Usage: "Generate a new INTERNAL_TOKEN",
Action: runGenerateInternalToken,
}
}
microcmdGenerateLfsJwtSecret = &cli.Command{
func newGenerateLfsJWTSecretCommand() *cli.Command {
return &cli.Command{
Name: "JWT_SECRET",
Aliases: []string{"LFS_JWT_SECRET"},
Usage: "Generate a new JWT_SECRET",
Action: runGenerateLfsJwtSecret,
}
}
microcmdGenerateSecretKey = &cli.Command{
func newGenerateSecretKeyCommand() *cli.Command {
return &cli.Command{
Name: "SECRET_KEY",
Usage: "Generate a new SECRET_KEY",
Action: runGenerateSecretKey,
}
)
}
func runGenerateInternalToken(_ context.Context, c *cli.Command) error {
internalToken, err := generate.NewInternalToken()
@@ -71,11 +78,7 @@ func runGenerateInternalToken(_ context.Context, c *cli.Command) error {
}
func runGenerateLfsJwtSecret(_ context.Context, c *cli.Command) error {
_, jwtSecretBase64, err := generate.NewJwtSecretWithBase64()
if err != nil {
return err
}
_, jwtSecretBase64 := generate.NewJwtSecretWithBase64()
fmt.Printf("%s", jwtSecretBase64)
if isatty.IsTerminal(os.Stdout.Fd()) {
@@ -91,6 +94,7 @@ func runGenerateSecretKey(_ context.Context, c *cli.Command) error {
return err
}
// codeql[disable-next-line=go/clear-text-logging]
fmt.Printf("%s", secretKey)
if isatty.IsTerminal(os.Stdout.Fd()) {
+56 -32
View File
@@ -28,23 +28,24 @@ const (
hookBatchSize = 500
)
var (
// CmdHook represents the available hooks sub-command.
CmdHook = &cli.Command{
func newHookCommand() *cli.Command {
return &cli.Command{
Name: "hook",
Usage: "(internal) Should only be called by Git",
Hidden: true, // internal commands shouldn't be visible
Description: "Delegate commands to corresponding Git hooks",
Before: PrepareConsoleLoggerLevel(log.FATAL),
Commands: []*cli.Command{
subcmdHookPreReceive,
subcmdHookUpdate,
subcmdHookPostReceive,
subcmdHookProcReceive,
newHookPreReceiveCommand(),
newHookUpdateCommand(),
newHookPostReceiveCommand(),
newHookProcReceiveCommand(),
},
}
}
subcmdHookPreReceive = &cli.Command{
func newHookPreReceiveCommand() *cli.Command {
return &cli.Command{
Name: "pre-receive",
Usage: "Delegate pre-receive Git hook",
Description: "This command should only be called by Git",
@@ -55,7 +56,10 @@ var (
},
},
}
subcmdHookUpdate = &cli.Command{
}
func newHookUpdateCommand() *cli.Command {
return &cli.Command{
Name: "update",
Usage: "Delegate update Git hook",
Description: "This command should only be called by Git",
@@ -66,7 +70,10 @@ var (
},
},
}
subcmdHookPostReceive = &cli.Command{
}
func newHookPostReceiveCommand() *cli.Command {
return &cli.Command{
Name: "post-receive",
Usage: "Delegate post-receive Git hook",
Description: "This command should only be called by Git",
@@ -77,8 +84,11 @@ var (
},
},
}
// Note: new hook since git 2.29
subcmdHookProcReceive = &cli.Command{
}
// Note: new hook since git 2.29
func newHookProcReceiveCommand() *cli.Command {
return &cli.Command{
Name: "proc-receive",
Usage: "Delegate proc-receive Git hook",
Description: "This command should only be called by Git",
@@ -89,7 +99,7 @@ var (
},
},
}
)
}
type delayWriter struct {
internal io.Writer
@@ -163,6 +173,14 @@ func (n *nilWriter) WriteString(s string) (int, error) {
return len(s), nil
}
func parseGitHookCommitRefLine(line string) (oldCommitID, newCommitID string, refFullName git.RefName, ok bool) {
fields := strings.Split(line, " ")
if len(fields) != 3 {
return "", "", "", false
}
return fields[0], fields[1], git.RefName(fields[2]), true
}
func runHookPreReceive(ctx context.Context, c *cli.Command) error {
if isInternal, _ := strconv.ParseBool(os.Getenv(repo_module.EnvIsInternal)); isInternal {
return nil
@@ -186,7 +204,7 @@ Gitea or set your environment appropriately.`, "")
userID, _ := strconv.ParseInt(os.Getenv(repo_module.EnvPusherID), 10, 64)
prID, _ := strconv.ParseInt(os.Getenv(repo_module.EnvPRID), 10, 64)
deployKeyID, _ := strconv.ParseInt(os.Getenv(repo_module.EnvDeployKeyID), 10, 64)
actionPerm, _ := strconv.ParseInt(os.Getenv(repo_module.EnvActionPerm), 10, 64)
actionsTaskID, _ := strconv.ParseInt(os.Getenv(repo_module.EnvActionsTaskID), 10, 64)
hookOptions := private.HookOptions{
UserID: userID,
@@ -196,7 +214,8 @@ Gitea or set your environment appropriately.`, "")
GitPushOptions: pushOptions(),
PullRequestID: prID,
DeployKeyID: deployKeyID,
ActionPerm: int(actionPerm),
ActionsTaskID: actionsTaskID,
IsWiki: isWiki,
}
scanner := bufio.NewScanner(os.Stdin)
@@ -228,14 +247,11 @@ Gitea or set your environment appropriately.`, "")
continue
}
fields := bytes.Fields(scanner.Bytes())
if len(fields) != 3 {
oldCommitID, newCommitID, refFullName, ok := parseGitHookCommitRefLine(scanner.Text())
if !ok {
continue
}
oldCommitID := string(fields[0])
newCommitID := string(fields[1])
refFullName := git.RefName(fields[2])
total++
lastline++
@@ -270,6 +286,9 @@ Gitea or set your environment appropriately.`, "")
lastline = 0
}
}
if err := scanner.Err(); err != nil {
return fail(ctx, "Hook failed: stdin read error", "scanner error: %v", err)
}
if count > 0 {
hookOptions.OldCommitIDs = oldCommitIDs[:count]
@@ -313,7 +332,7 @@ func runHookPostReceive(ctx context.Context, c *cli.Command) error {
setup(ctx, c.Bool("debug"))
// First of all run update-server-info no matter what
if _, _, err := gitcmd.NewCommand("update-server-info").RunStdString(ctx, nil); err != nil {
if err := gitcmd.NewCommand("update-server-info").RunWithStderr(ctx); err != nil {
return fmt.Errorf("failed to call 'git update-server-info': %w", err)
}
@@ -361,6 +380,7 @@ Gitea or set your environment appropriately.`, "")
GitPushOptions: pushOptions(),
PullRequestID: prID,
PushTrigger: repo_module.PushTrigger(os.Getenv(repo_module.EnvPushTrigger)),
IsWiki: isWiki,
}
oldCommitIDs := make([]string, hookBatchSize)
newCommitIDs := make([]string, hookBatchSize)
@@ -378,16 +398,13 @@ Gitea or set your environment appropriately.`, "")
continue
}
fields := bytes.Fields(scanner.Bytes())
if len(fields) != 3 {
var ok bool
oldCommitIDs[count], newCommitIDs[count], refFullNames[count], ok = parseGitHookCommitRefLine(scanner.Text())
if !ok {
continue
}
fmt.Fprintf(out, ".")
oldCommitIDs[count] = string(fields[0])
newCommitIDs[count] = string(fields[1])
refFullNames[count] = git.RefName(fields[2])
commitID, _ := git.NewIDFromString(newCommitIDs[count])
if refFullNames[count] == git.BranchPrefix+"master" && !commitID.IsZero() && count == total {
masterPushed = true
@@ -411,6 +428,11 @@ Gitea or set your environment appropriately.`, "")
count = 0
}
}
if err := scanner.Err(); err != nil {
_ = dWriter.Close()
hookPrintResults(results)
return fail(ctx, "Hook failed: stdin read error", "scanner error: %v", err)
}
if count == 0 {
if wasEmpty && masterPushed {
@@ -511,6 +533,7 @@ Gitea or set your environment appropriately.`, "")
reader := bufio.NewReader(os.Stdin)
repoUser := os.Getenv(repo_module.EnvRepoUsername)
isWiki, _ := strconv.ParseBool(os.Getenv(repo_module.EnvRepoIsWiki))
repoName := os.Getenv(repo_module.EnvRepoName)
pusherID, _ := strconv.ParseInt(os.Getenv(repo_module.EnvPusherID), 10, 64)
pusherName := os.Getenv(repo_module.EnvPusherName)
@@ -588,14 +611,15 @@ Gitea or set your environment appropriately.`, "")
UserName: pusherName,
UserID: pusherID,
GitPushOptions: make(map[string]string),
IsWiki: isWiki,
}
hookOptions.OldCommitIDs = make([]string, 0, hookBatchSize)
hookOptions.NewCommitIDs = make([]string, 0, hookBatchSize)
hookOptions.RefFullNames = make([]git.RefName, 0, hookBatchSize)
for {
// note: pktLineTypeUnknow means pktLineTypeFlush and pktLineTypeData all allowed
rs, err = readPktLine(ctx, reader, pktLineTypeUnknow)
// note: pktLineTypeUnknown means pktLineTypeFlush and pktLineTypeData all allowed
rs, err = readPktLine(ctx, reader, pktLineTypeUnknown)
if err != nil {
return err
}
@@ -614,7 +638,7 @@ Gitea or set your environment appropriately.`, "")
if hasPushOptions {
for {
rs, err = readPktLine(ctx, reader, pktLineTypeUnknow)
rs, err = readPktLine(ctx, reader, pktLineTypeUnknown)
if err != nil {
return err
}
@@ -711,8 +735,8 @@ Gitea or set your environment appropriately.`, "")
type pktLineType int64
const (
// UnKnow type
pktLineTypeUnknow pktLineType = 0
// Unknown type
pktLineTypeUnknown pktLineType = 0
// flush-pkt "0000"
pktLineTypeFlush pktLineType = iota
// data line
+14
View File
@@ -39,3 +39,17 @@ func TestPktLine(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, []byte("0007a\nb"), w.Bytes())
}
func TestParseGitHookCommitRefLine(t *testing.T) {
oldCommitID, newCommitID, refName, ok := parseGitHookCommitRefLine("a b c")
assert.True(t, ok)
assert.Equal(t, "a", oldCommitID)
assert.Equal(t, "b", newCommitID)
assert.Equal(t, "c", string(refName))
_, _, _, ok = parseGitHookCommitRefLine("a\tb\tc")
assert.False(t, ok)
_, _, _, ok = parseGitHookCommitRefLine("a b")
assert.False(t, ok)
}
+35 -33
View File
@@ -15,40 +15,42 @@ import (
"github.com/urfave/cli/v3"
)
// CmdKeys represents the available keys sub-command
var CmdKeys = &cli.Command{
Name: "keys",
Usage: "(internal) Should only be called by SSH server",
Hidden: true, // internal commands shouldn't not be visible
Description: "Queries the Gitea database to get the authorized command for a given ssh key fingerprint",
Before: PrepareConsoleLoggerLevel(log.FATAL),
Action: runKeys,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "expected",
Aliases: []string{"e"},
Value: "git",
Usage: "Expected user for whom provide key commands",
// NewKeysCommand returns the internal SSH key lookup sub-command.
func NewKeysCommand() *cli.Command {
return &cli.Command{
Name: "keys",
Usage: "(internal) Should only be called by SSH server",
Hidden: true, // internal commands shouldn't be visible
Description: "Queries the Gitea database to get the authorized command for a given ssh key fingerprint",
Before: PrepareConsoleLoggerLevel(log.FATAL),
Action: runKeys,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "expected",
Aliases: []string{"e"},
Value: "git",
Usage: "Expected user for whom provide key commands",
},
&cli.StringFlag{
Name: "username",
Aliases: []string{"u"},
Value: "",
Usage: "Username trying to log in by SSH",
},
&cli.StringFlag{
Name: "type",
Aliases: []string{"t"},
Value: "",
Usage: "Type of the SSH key provided to the SSH Server (requires content to be provided too)",
},
&cli.StringFlag{
Name: "content",
Aliases: []string{"k"},
Value: "",
Usage: "Base64 encoded content of the SSH key provided to the SSH Server (requires type to be provided too)",
},
},
&cli.StringFlag{
Name: "username",
Aliases: []string{"u"},
Value: "",
Usage: "Username trying to log in by SSH",
},
&cli.StringFlag{
Name: "type",
Aliases: []string{"t"},
Value: "",
Usage: "Type of the SSH key provided to the SSH Server (requires content to be provided too)",
},
&cli.StringFlag{
Name: "content",
Aliases: []string{"k"},
Value: "",
Usage: "Base64 encoded content of the SSH key provided to the SSH Server (requires type to be provided too)",
},
},
}
}
func runKeys(ctx context.Context, c *cli.Command) error {
+2 -2
View File
@@ -17,10 +17,10 @@ func runSendMail(ctx context.Context, c *cli.Command) error {
setting.MustInstalled()
subject := c.String("title")
confirmSkiped := c.Bool("force")
confirmSkipped := c.Bool("force")
body := c.String("content")
if !confirmSkiped {
if !confirmSkipped {
if len(body) == 0 {
fmt.Print("warning: Content is empty")
}
+27 -21
View File
@@ -50,11 +50,15 @@ DEFAULT CONFIGURATION:
func prepareSubcommandWithGlobalFlags(originCmd *cli.Command) {
originBefore := originCmd.Before
originCmd.Before = func(ctx context.Context, cmd *cli.Command) (context.Context, error) {
prepareWorkPathAndCustomConf(cmd)
originCmd.Before = func(ctxOrig context.Context, cmd *cli.Command) (ctx context.Context, err error) {
ctx = ctxOrig
if originBefore != nil {
return originBefore(ctx, cmd)
ctx, err = originBefore(ctx, cmd)
if err != nil {
return ctx, err
}
}
prepareWorkPathAndCustomConf(cmd)
return ctx, nil
}
}
@@ -108,34 +112,36 @@ func NewMainApp(appVer AppVersion) *cli.Command {
Usage: "Set custom path (defaults to '{WorkPath}/custom')",
},
}
webCmd := newWebCommand()
// these sub-commands need to use a config file
subCmdWithConfig := []*cli.Command{
CmdWeb,
CmdServ,
CmdHook,
CmdKeys,
CmdDump,
CmdAdmin,
CmdMigrate,
CmdDoctor,
CmdManager,
CmdEmbedded,
CmdMigrateStorage,
CmdDumpRepository,
CmdRestoreRepository,
CmdActions,
webCmd,
newServCommand(),
newHookCommand(),
NewKeysCommand(),
newDumpCommand(),
newAdminCommand(),
newMigrateCommand(),
newDoctorCommand(),
newManagerCommand(),
newEmbeddedCommand(),
newMigrateStorageCommand(),
newDumpRepositoryCommand(),
newRestoreRepositoryCommand(),
newActionsCommand(),
}
// these sub-commands do not need the config file, and they do not depend on any path or environment variable.
subCmdStandalone := []*cli.Command{
cmdConfig(),
cmdCert(),
CmdGenerate,
CmdDocs,
newGenerateCommand(),
newDocsCommand(),
}
// TODO: we should eventually drop the default command,
// but not sure whether it would break Windows users who used to double-click the EXE to run.
app.DefaultCommand = CmdWeb.Name
app.DefaultCommand = webCmd.Name
app.Before = PrepareConsoleLoggerLevel(log.INFO)
for i := range subCmdWithConfig {
@@ -144,7 +150,7 @@ func NewMainApp(appVer AppVersion) *cli.Command {
app.Commands = append(app.Commands, subCmdWithConfig...)
app.Commands = append(app.Commands, subCmdStandalone...)
setting.InitGiteaEnvVars()
setting.UnsetUnnecessaryEnvVars()
return app
}
+42 -12
View File
@@ -15,6 +15,7 @@ import (
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/modules/util"
"github.com/stretchr/testify/assert"
"github.com/urfave/cli/v3"
@@ -28,11 +29,11 @@ func makePathOutput(workPath, customPath, customConf string) string {
return fmt.Sprintf("WorkPath=%s\nCustomPath=%s\nCustomConf=%s", workPath, customPath, customConf)
}
func newTestApp(testCmdAction cli.ActionFunc) *cli.Command {
func newTestApp(testCmd cli.Command) *cli.Command {
app := NewMainApp(AppVersion{})
testCmd := &cli.Command{Name: "test-cmd", Action: testCmdAction}
prepareSubcommandWithGlobalFlags(testCmd)
app.Commands = append(app.Commands, testCmd)
testCmd.Name = util.IfZero(testCmd.Name, "test-cmd")
prepareSubcommandWithGlobalFlags(&testCmd)
app.Commands = append(app.Commands, &testCmd)
app.DefaultCommand = testCmd.Name
return app
}
@@ -156,9 +157,12 @@ func TestCliCmd(t *testing.T) {
for _, c := range cases {
t.Run(c.cmd, func(t *testing.T) {
app := newTestApp(func(ctx context.Context, cmd *cli.Command) error {
_, _ = fmt.Fprint(cmd.Root().Writer, makePathOutput(setting.AppWorkPath, setting.CustomPath, setting.CustomConf))
return nil
defer test.MockVariableValue(&setting.InstallLock, false)()
app := newTestApp(cli.Command{
Action: func(ctx context.Context, cmd *cli.Command) error {
_, _ = fmt.Fprint(cmd.Root().Writer, makePathOutput(setting.AppWorkPath, setting.CustomPath, setting.CustomConf))
return nil
},
})
for k, v := range c.env {
t.Setenv(k, v)
@@ -167,37 +171,63 @@ func TestCliCmd(t *testing.T) {
r, err := runTestApp(app, args...)
assert.NoError(t, err, c.cmd)
assert.NotEmpty(t, c.exp, c.cmd)
assert.Contains(t, r.Stdout, c.exp, c.cmd)
if !assert.Contains(t, r.Stdout, c.exp, c.cmd) {
t.Log("Full output:\n" + r.Stdout)
t.Log("Expected:\n" + c.exp)
}
})
}
}
func TestCliCmdError(t *testing.T) {
app := newTestApp(func(ctx context.Context, cmd *cli.Command) error { return errors.New("normal error") })
app := newTestApp(cli.Command{Action: func(ctx context.Context, cmd *cli.Command) error { return errors.New("normal error") }})
r, err := runTestApp(app, "./gitea", "test-cmd")
assert.Error(t, err)
assert.Equal(t, 1, r.ExitCode)
assert.Empty(t, r.Stdout)
assert.Equal(t, "Command error: normal error\n", r.Stderr)
app = newTestApp(func(ctx context.Context, cmd *cli.Command) error { return cli.Exit("exit error", 2) })
app = newTestApp(cli.Command{Action: func(ctx context.Context, cmd *cli.Command) error { return cli.Exit("exit error", 2) }})
r, err = runTestApp(app, "./gitea", "test-cmd")
assert.Error(t, err)
assert.Equal(t, 2, r.ExitCode)
assert.Empty(t, r.Stdout)
assert.Equal(t, "exit error\n", r.Stderr)
app = newTestApp(func(ctx context.Context, cmd *cli.Command) error { return nil })
app = newTestApp(cli.Command{Action: func(ctx context.Context, cmd *cli.Command) error { return nil }})
r, err = runTestApp(app, "./gitea", "test-cmd", "--no-such")
assert.Error(t, err)
assert.Equal(t, 1, r.ExitCode)
assert.Empty(t, r.Stdout)
assert.Equal(t, "Incorrect Usage: flag provided but not defined: -no-such\n\n", r.Stderr)
app = newTestApp(func(ctx context.Context, cmd *cli.Command) error { return nil })
app = newTestApp(cli.Command{Action: func(ctx context.Context, cmd *cli.Command) error { return nil }})
r, err = runTestApp(app, "./gitea", "test-cmd")
assert.NoError(t, err)
assert.Equal(t, -1, r.ExitCode) // the cli.OsExiter is not called
assert.Empty(t, r.Stdout)
assert.Empty(t, r.Stderr)
}
func TestCliCmdBefore(t *testing.T) {
ctxNew := context.WithValue(context.Background(), any("key"), "value")
configValues := map[string]string{}
setting.CustomConf = "/tmp/any.ini"
var actionCtx context.Context
app := newTestApp(cli.Command{
Before: func(context.Context, *cli.Command) (context.Context, error) {
configValues["before"] = setting.CustomConf
return ctxNew, nil
},
Action: func(ctx context.Context, cmd *cli.Command) error {
configValues["action"] = setting.CustomConf
actionCtx = ctx
return nil
},
})
_, err := runTestApp(app, "./gitea", "--config", "/dev/null", "test-cmd")
assert.NoError(t, err)
assert.Equal(t, ctxNew, actionCtx)
assert.Equal(t, "/tmp/any.ini", configValues["before"], "BeforeFunc must be called before preparing config")
assert.Equal(t, "/dev/null", configValues["action"])
}
+29 -15
View File
@@ -13,22 +13,24 @@ import (
"github.com/urfave/cli/v3"
)
var (
// CmdManager represents the manager command
CmdManager = &cli.Command{
func newManagerCommand() *cli.Command {
return &cli.Command{
Name: "manager",
Usage: "Manage the running gitea process",
Description: "This is a command for managing the running gitea process",
Commands: []*cli.Command{
subcmdShutdown,
subcmdRestart,
subcmdReloadTemplates,
subcmdFlushQueues,
subcmdLogging,
subCmdProcesses,
newShutdownCommand(),
newRestartCommand(),
newReloadTemplatesCommand(),
newFlushQueuesCommand(),
newLoggingCommand(),
newProcessesCommand(),
},
}
subcmdShutdown = &cli.Command{
}
func newShutdownCommand() *cli.Command {
return &cli.Command{
Name: "shutdown",
Usage: "Gracefully shutdown the running process",
Flags: []cli.Flag{
@@ -38,7 +40,10 @@ var (
},
Action: runShutdown,
}
subcmdRestart = &cli.Command{
}
func newRestartCommand() *cli.Command {
return &cli.Command{
Name: "restart",
Usage: "Gracefully restart the running process - (not implemented for windows servers)",
Flags: []cli.Flag{
@@ -48,7 +53,10 @@ var (
},
Action: runRestart,
}
subcmdReloadTemplates = &cli.Command{
}
func newReloadTemplatesCommand() *cli.Command {
return &cli.Command{
Name: "reload-templates",
Usage: "Reload template files in the running process",
Flags: []cli.Flag{
@@ -58,7 +66,10 @@ var (
},
Action: runReloadTemplates,
}
subcmdFlushQueues = &cli.Command{
}
func newFlushQueuesCommand() *cli.Command {
return &cli.Command{
Name: "flush-queues",
Usage: "Flush queues in the running process",
Action: runFlushQueues,
@@ -77,7 +88,10 @@ var (
},
},
}
subCmdProcesses = &cli.Command{
}
func newProcessesCommand() *cli.Command {
return &cli.Command{
Name: "processes",
Usage: "Display running processes within the current process",
Action: runProcesses,
@@ -107,7 +121,7 @@ var (
},
},
}
)
}
func runShutdown(ctx context.Context, c *cli.Command) error {
setup(ctx, c.Bool("debug"))
+8 -6
View File
@@ -15,8 +15,8 @@ import (
"github.com/urfave/cli/v3"
)
var (
defaultLoggingFlags = []cli.Flag{
func defaultLoggingFlags() []cli.Flag {
return []cli.Flag{
&cli.StringFlag{
Name: "logger",
Usage: `Logger name - will default to "default"`,
@@ -57,8 +57,10 @@ var (
Name: "debug",
},
}
}
subcmdLogging = &cli.Command{
func newLoggingCommand() *cli.Command {
return &cli.Command{
Name: "logging",
Usage: "Adjust logging commands",
Commands: []*cli.Command{
@@ -109,7 +111,7 @@ var (
{
Name: "file",
Usage: "Add a file logger",
Flags: append(defaultLoggingFlags, []cli.Flag{
Flags: append(defaultLoggingFlags(), []cli.Flag{
&cli.StringFlag{
Name: "filename",
Aliases: []string{"f"},
@@ -150,7 +152,7 @@ var (
}, {
Name: "conn",
Usage: "Add a net conn logger",
Flags: append(defaultLoggingFlags, []cli.Flag{
Flags: append(defaultLoggingFlags(), []cli.Flag{
&cli.BoolFlag{
Name: "reconnect-on-message",
Aliases: []string{"R"},
@@ -191,7 +193,7 @@ var (
},
},
}
)
}
func runRemoveLogger(ctx context.Context, c *cli.Command) error {
setup(ctx, c.Bool("debug"))
+7 -6
View File
@@ -14,12 +14,13 @@ import (
"github.com/urfave/cli/v3"
)
// CmdMigrate represents the available migrate sub-command.
var CmdMigrate = &cli.Command{
Name: "migrate",
Usage: "Migrate the database",
Description: `This is a command for migrating the database, so that you can run "gitea admin create user" before starting the server.`,
Action: runMigrate,
func newMigrateCommand() *cli.Command {
return &cli.Command{
Name: "migrate",
Usage: "Migrate the database",
Description: `This is a command for migrating the database, so that you can run "gitea admin create user" before starting the server.`,
Action: runMigrate,
}
}
func runMigrate(ctx context.Context, c *cli.Command) error {
+101 -100
View File
@@ -25,107 +25,108 @@ import (
"github.com/urfave/cli/v3"
)
// CmdMigrateStorage represents the available migrate storage sub-command.
var CmdMigrateStorage = &cli.Command{
Name: "migrate-storage",
Usage: "Migrate the storage",
Description: "Copies stored files from storage configured in app.ini to parameter-configured storage",
Action: runMigrateStorage,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "type",
Aliases: []string{"t"},
Value: "",
Usage: "Type of stored files to copy. Allowed types: 'attachments', 'lfs', 'avatars', 'repo-avatars', 'repo-archivers', 'packages', 'actions-log', 'actions-artifacts",
func newMigrateStorageCommand() *cli.Command {
return &cli.Command{
Name: "migrate-storage",
Usage: "Migrate the storage",
Description: "Copies stored files from storage configured in app.ini to parameter-configured storage",
Action: runMigrateStorage,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "type",
Aliases: []string{"t"},
Value: "",
Usage: "Type of stored files to copy. Allowed types: 'attachments', 'lfs', 'avatars', 'repo-avatars', 'repo-archivers', 'packages', 'actions-log', 'actions-artifacts'",
},
&cli.StringFlag{
Name: "storage",
Aliases: []string{"s"},
Value: "",
Usage: "New storage type: local (default), minio or azureblob",
},
&cli.StringFlag{
Name: "path",
Aliases: []string{"p"},
Value: "",
Usage: "New storage placement if store is local (leave blank for default)",
},
// Minio Storage special configurations
&cli.StringFlag{
Name: "minio-endpoint",
Value: "",
Usage: "Minio storage endpoint",
},
&cli.StringFlag{
Name: "minio-access-key-id",
Value: "",
Usage: "Minio storage accessKeyID",
},
&cli.StringFlag{
Name: "minio-secret-access-key",
Value: "",
Usage: "Minio storage secretAccessKey",
},
&cli.StringFlag{
Name: "minio-bucket",
Value: "",
Usage: "Minio storage bucket",
},
&cli.StringFlag{
Name: "minio-location",
Value: "",
Usage: "Minio storage location to create bucket",
},
&cli.StringFlag{
Name: "minio-base-path",
Value: "",
Usage: "Minio storage base path on the bucket",
},
&cli.BoolFlag{
Name: "minio-use-ssl",
Usage: "Enable SSL for minio",
},
&cli.BoolFlag{
Name: "minio-insecure-skip-verify",
Usage: "Skip SSL verification",
},
&cli.StringFlag{
Name: "minio-checksum-algorithm",
Value: "",
Usage: "Minio checksum algorithm (default/md5)",
},
&cli.StringFlag{
Name: "minio-bucket-lookup-type",
Value: "",
Usage: "Minio bucket lookup type",
},
// Azure Blob Storage special configurations
&cli.StringFlag{
Name: "azureblob-endpoint",
Value: "",
Usage: "Azure Blob storage endpoint",
},
&cli.StringFlag{
Name: "azureblob-account-name",
Value: "",
Usage: "Azure Blob storage account name",
},
&cli.StringFlag{
Name: "azureblob-account-key",
Value: "",
Usage: "Azure Blob storage account key",
},
&cli.StringFlag{
Name: "azureblob-container",
Value: "",
Usage: "Azure Blob storage container",
},
&cli.StringFlag{
Name: "azureblob-base-path",
Value: "",
Usage: "Azure Blob storage base path",
},
},
&cli.StringFlag{
Name: "storage",
Aliases: []string{"s"},
Value: "",
Usage: "New storage type: local (default), minio or azureblob",
},
&cli.StringFlag{
Name: "path",
Aliases: []string{"p"},
Value: "",
Usage: "New storage placement if store is local (leave blank for default)",
},
// Minio Storage special configurations
&cli.StringFlag{
Name: "minio-endpoint",
Value: "",
Usage: "Minio storage endpoint",
},
&cli.StringFlag{
Name: "minio-access-key-id",
Value: "",
Usage: "Minio storage accessKeyID",
},
&cli.StringFlag{
Name: "minio-secret-access-key",
Value: "",
Usage: "Minio storage secretAccessKey",
},
&cli.StringFlag{
Name: "minio-bucket",
Value: "",
Usage: "Minio storage bucket",
},
&cli.StringFlag{
Name: "minio-location",
Value: "",
Usage: "Minio storage location to create bucket",
},
&cli.StringFlag{
Name: "minio-base-path",
Value: "",
Usage: "Minio storage base path on the bucket",
},
&cli.BoolFlag{
Name: "minio-use-ssl",
Usage: "Enable SSL for minio",
},
&cli.BoolFlag{
Name: "minio-insecure-skip-verify",
Usage: "Skip SSL verification",
},
&cli.StringFlag{
Name: "minio-checksum-algorithm",
Value: "",
Usage: "Minio checksum algorithm (default/md5)",
},
&cli.StringFlag{
Name: "minio-bucket-lookup-type",
Value: "",
Usage: "Minio bucket lookup type",
},
// Azure Blob Storage special configurations
&cli.StringFlag{
Name: "azureblob-endpoint",
Value: "",
Usage: "Azure Blob storage endpoint",
},
&cli.StringFlag{
Name: "azureblob-account-name",
Value: "",
Usage: "Azure Blob storage account name",
},
&cli.StringFlag{
Name: "azureblob-account-key",
Value: "",
Usage: "Azure Blob storage account key",
},
&cli.StringFlag{
Name: "azureblob-container",
Value: "",
Usage: "Azure Blob storage container",
},
&cli.StringFlag{
Name: "azureblob-base-path",
Value: "",
Usage: "Azure Blob storage base path",
},
},
}
}
func migrateAttachments(ctx context.Context, dstStorage storage.ObjectStorage) error {
+33 -32
View File
@@ -13,40 +13,41 @@ import (
"github.com/urfave/cli/v3"
)
// CmdRestoreRepository represents the available restore a repository sub-command.
var CmdRestoreRepository = &cli.Command{
Name: "restore-repo",
Usage: "Restore the repository from disk",
Description: "This is a command for restoring the repository data.",
Action: runRestoreRepository,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "repo_dir",
Aliases: []string{"r"},
Value: "./data",
Usage: "Repository dir path to restore from",
},
&cli.StringFlag{
Name: "owner_name",
Value: "",
Usage: "Restore destination owner name",
},
&cli.StringFlag{
Name: "repo_name",
Value: "",
Usage: "Restore destination repository name",
},
&cli.StringFlag{
Name: "units",
Value: "",
Usage: `Which items will be restored, one or more units should be separated as comma.
func newRestoreRepositoryCommand() *cli.Command {
return &cli.Command{
Name: "restore-repo",
Usage: "Restore the repository from disk",
Description: "This is a command for restoring the repository data.",
Action: runRestoreRepository,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "repo_dir",
Aliases: []string{"r"},
Value: "./data",
Usage: "Repository dir path to restore from",
},
&cli.StringFlag{
Name: "owner_name",
Value: "",
Usage: "Restore destination owner name",
},
&cli.StringFlag{
Name: "repo_name",
Value: "",
Usage: "Restore destination repository name",
},
&cli.StringFlag{
Name: "units",
Value: "",
Usage: `Which items will be restored, one or more units should be separated as comma.
wiki, issues, labels, releases, release_assets, milestones, pull_requests, comments are allowed. Empty means all units.`,
},
&cli.BoolFlag{
Name: "validation",
Usage: "Sanity check the content of the files before trying to load them",
},
},
&cli.BoolFlag{
Name: "validation",
Usage: "Sanity check the content of the files before trying to load them",
},
},
}
}
func runRestoreRepository(ctx context.Context, c *cli.Command) error {
+26 -46
View File
@@ -13,13 +13,12 @@ import (
"path/filepath"
"strconv"
"strings"
"time"
"unicode"
asymkey_model "code.gitea.io/gitea/models/asymkey"
git_model "code.gitea.io/gitea/models/git"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/repo"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/json"
@@ -32,27 +31,27 @@ import (
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/services/lfs"
"github.com/golang-jwt/jwt/v5"
"github.com/kballard/go-shellquote"
"github.com/urfave/cli/v3"
)
// CmdServ represents the available serv sub-command.
var CmdServ = &cli.Command{
Name: "serv",
Usage: "(internal) Should only be called by SSH shell",
Description: "Serv provides access auth for repositories",
Hidden: true, // Internal commands shouldn't be visible in help
Before: PrepareConsoleLoggerLevel(log.FATAL),
Action: runServ,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "enable-pprof",
func newServCommand() *cli.Command {
return &cli.Command{
Name: "serv",
Usage: "(internal) Should only be called by SSH shell",
Description: "Serv provides access auth for repositories",
Hidden: true, // Internal commands shouldn't be visible in help
Before: PrepareConsoleLoggerLevel(log.FATAL),
Action: runServ,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "enable-pprof",
},
&cli.BoolFlag{
Name: "debug",
},
},
&cli.BoolFlag{
Name: "debug",
},
},
}
}
func setup(ctx context.Context, debug bool) {
@@ -133,27 +132,6 @@ func getAccessMode(verb, lfsVerb string) perm.AccessMode {
return perm.AccessModeNone
}
func getLFSAuthToken(ctx context.Context, lfsVerb string, results *private.ServCommandResults) (string, error) {
now := time.Now()
claims := lfs.Claims{
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(now.Add(setting.LFS.HTTPAuthExpiry)),
NotBefore: jwt.NewNumericDate(now),
},
RepoID: results.RepoID,
Op: lfsVerb,
UserID: results.UserID,
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// Sign and get the complete encoded token as a string using the secret
tokenString, err := token.SignedString(setting.LFS.JWTSecretBytes)
if err != nil {
return "", fail(ctx, "Failed to sign JWT Token", "Failed to sign JWT token: %v", err)
}
return "Bearer " + tokenString, nil
}
func runServ(ctx context.Context, c *cli.Command) error {
// FIXME: This needs to internationalised
setup(ctx, c.Bool("debug"))
@@ -230,7 +208,7 @@ func runServ(ctx context.Context, c *cli.Command) error {
username := repoPathFields[0]
reponame := strings.TrimSuffix(repoPathFields[1], ".git") // “the-repo-name" or "the-repo-name.wiki"
if !repo.IsValidSSHAccessRepoName(reponame) {
if !repo_model.IsValidSSHAccessRepoName(reponame) {
return fail(ctx, "Invalid repo name", "Invalid repo name: %s", reponame)
}
@@ -276,14 +254,16 @@ func runServ(ctx context.Context, c *cli.Command) error {
return fail(ctx, extra.UserMsg, "ServCommand failed: %s", extra.Error)
}
// LowerCase and trim the repoPath as that's how they are stored.
// This should be done after splitting the repoPath into username and reponame
// so that username and reponame are not affected.
repoPath = strings.ToLower(results.OwnerName + "/" + results.RepoName + ".git")
// because the original repoPath maybe redirected, we need to use the returned actual repository information
if results.IsWiki {
repoPath = repo_model.RelativeWikiPath(results.OwnerName, results.RepoName)
} else {
repoPath = repo_model.RelativePath(results.OwnerName, results.RepoName)
}
// LFS SSH protocol
if verb == git.CmdVerbLfsTransfer {
token, err := getLFSAuthToken(ctx, lfsVerb, results)
token, err := lfs.GetLFSAuthTokenWithBearer(lfs.AuthTokenOptions{Op: lfsVerb, UserID: results.UserID, RepoID: results.RepoID})
if err != nil {
return err
}
@@ -294,7 +274,7 @@ func runServ(ctx context.Context, c *cli.Command) error {
if verb == git.CmdVerbLfsAuthenticate {
url := fmt.Sprintf("%s%s/%s.git/info/lfs", setting.AppURL, url.PathEscape(results.OwnerName), url.PathEscape(results.RepoName))
token, err := getLFSAuthToken(ctx, lfsVerb, results)
token, err := lfs.GetLFSAuthTokenWithBearer(lfs.AuthTokenOptions{Op: lfsVerb, UserID: results.UserID, RepoID: results.RepoID})
if err != nil {
return err
}
+50 -49
View File
@@ -8,14 +8,13 @@ import (
"fmt"
"net"
"net/http"
"net/http/pprof"
"os"
"path/filepath"
"strconv"
"strings"
"time"
_ "net/http/pprof" // Used for debugging if enabled and a web server is running
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/gtprof"
@@ -23,6 +22,7 @@ import (
"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/public"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/routers"
"code.gitea.io/gitea/routers/install"
@@ -34,42 +34,43 @@ import (
// PIDFile could be set from build tag
var PIDFile = "/run/gitea.pid"
// CmdWeb represents the available web sub-command.
var CmdWeb = &cli.Command{
Name: "web",
Usage: "Start Gitea web server",
Description: `Gitea web server is the only thing you need to run,
func newWebCommand() *cli.Command {
return &cli.Command{
Name: "web",
Usage: "Start Gitea web server",
Description: `Gitea web server is the only thing you need to run,
and it takes care of all the other things for you`,
Before: PrepareConsoleLoggerLevel(log.INFO),
Action: runWeb,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "port",
Aliases: []string{"p"},
Value: "3000",
Usage: "Temporary port number to prevent conflict",
Before: PrepareConsoleLoggerLevel(log.INFO),
Action: runWeb,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "port",
Aliases: []string{"p"},
Value: "3000",
Usage: "Temporary port number to prevent conflict",
},
&cli.StringFlag{
Name: "install-port",
Value: "3000",
Usage: "Temporary port number to run the install page on to prevent conflict",
},
&cli.StringFlag{
Name: "pid",
Aliases: []string{"P"},
Value: PIDFile,
Usage: "Custom pid file path",
},
&cli.BoolFlag{
Name: "quiet",
Aliases: []string{"q"},
Usage: "Only display Fatal logging errors until logging is set-up",
},
&cli.BoolFlag{
Name: "verbose",
Usage: "Set initial logging to TRACE level until logging is properly set-up",
},
},
&cli.StringFlag{
Name: "install-port",
Value: "3000",
Usage: "Temporary port number to run the install page on to prevent conflict",
},
&cli.StringFlag{
Name: "pid",
Aliases: []string{"P"},
Value: PIDFile,
Usage: "Custom pid file path",
},
&cli.BoolFlag{
Name: "quiet",
Aliases: []string{"q"},
Usage: "Only display Fatal logging errors until logging is set-up",
},
&cli.BoolFlag{
Name: "verbose",
Usage: "Set initial logging to TRACE level until logging is properly set-up",
},
},
}
}
func runHTTPRedirector() {
@@ -156,7 +157,6 @@ func serveInstall(cmd *cli.Command) error {
case <-graceful.GetManager().IsShutdown():
<-graceful.GetManager().Done()
log.Info("PID: %d Gitea Web Finished", os.Getpid())
log.GetManager().Close()
return err
default:
}
@@ -164,8 +164,6 @@ func serveInstall(cmd *cli.Command) error {
}
func serveInstalled(c *cli.Command) error {
setting.InitCfgProvider(setting.CustomConf)
setting.LoadCommonSettings()
setting.MustInstalled()
showWebStartupMessage("Prepare to run web server")
@@ -231,27 +229,26 @@ func serveInstalled(c *cli.Command) error {
err := listen(webRoutes, true)
<-graceful.GetManager().Done()
log.Info("PID: %d Gitea Web Finished", os.Getpid())
log.GetManager().Close()
return err
}
func servePprof() {
// FIXME: it shouldn't use the global DefaultServeMux, and it should use a proper context
http.DefaultServeMux.Handle("/debug/fgprof", fgprof.Handler())
mux := http.NewServeMux()
mux.HandleFunc("/debug/pprof/", pprof.Index)
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
mux.Handle("/debug/fgprof", fgprof.Handler())
// FIXME: it should use a proper context
_, _, finished := process.GetManager().AddTypedContext(context.TODO(), "Web: PProf Server", process.SystemProcessType, true)
// The pprof server is for debug purpose only, it shouldn't be exposed on public network. At the moment, it's not worth introducing a configurable option for it.
log.Info("Starting pprof server on localhost:6060")
log.Info("Stopped pprof server: %v", http.ListenAndServe("localhost:6060", nil))
log.Info("Stopped pprof server: %v", http.ListenAndServe("localhost:6060", mux))
finished()
}
func runWeb(ctx context.Context, cmd *cli.Command) error {
defer func() {
if panicked := recover(); panicked != nil {
log.Fatal("PANIC: %v\n%s", panicked, log.Stack(2))
}
}()
if subCmdName, valid := isValidDefaultSubCommand(cmd); !valid {
return fmt.Errorf("unknown command: %s", subCmdName)
}
@@ -271,6 +268,10 @@ func runWeb(ctx context.Context, cmd *cli.Command) error {
createPIDFile(cmd.String("pid"))
}
// init the HTML renderer and load templates, if error happens, it will report the error immediately and exit with error log
// in dev mode, it won't exit, but watch the template files for changes
_ = templates.PageRenderer()
if !setting.InstallLock {
if err := serveInstall(cmd); err != nil {
return err
+3 -2
View File
@@ -7,6 +7,7 @@ import (
"crypto/x509"
"encoding/pem"
"fmt"
"net"
"net/http"
"os"
"strconv"
@@ -124,8 +125,8 @@ func runACME(listenAddr string, m http.Handler) error {
defer finished()
log.Info("Running Let's Encrypt handler on %s", setting.HTTPAddr+":"+setting.PortToRedirect)
// all traffic coming into HTTP will be redirect to HTTPS automatically (LE HTTP-01 validation happens here)
err := runHTTP("tcp", setting.HTTPAddr+":"+setting.PortToRedirect, "Let's Encrypt HTTP Challenge", myACME.HTTPChallengeHandler(http.HandlerFunc(runLetsEncryptFallbackHandler)), setting.RedirectorUseProxyProtocol)
// all traffic coming into HTTP will be redirected to HTTPS automatically (LE HTTP-01 validation happens here)
err := runHTTP("tcp", net.JoinHostPort(setting.HTTPAddr, setting.PortToRedirect), "Let's Encrypt HTTP Challenge", myACME.HTTPChallengeHandler(http.HandlerFunc(runLetsEncryptFallbackHandler)), setting.RedirectorUseProxyProtocol)
if err != nil {
log.Fatal("Failed to start the Let's Encrypt handler on port %s: %v", setting.PortToRedirect, err)
}
+1 -1
View File
@@ -16,7 +16,7 @@ import (
"strconv"
"strings"
"github.com/google/go-github/v74/github"
"github.com/google/go-github/v84/github"
"github.com/urfave/cli/v3"
"gopkg.in/yaml.v3"
)
-47
View File
@@ -1,47 +0,0 @@
Environment To Ini
==================
Multiple docker users have requested that the Gitea docker is changed
to permit arbitrary configuration via environment variables.
Gitea needs to use an ini file for configuration because the running
environment that starts the docker may not be the same as that used
by the hooks. An ini file also gives a good default and means that
users do not have to completely provide a full environment.
With those caveats above, this command provides a generic way of
converting suitably structured environment variables into any ini
value.
To use the command is very simple just run it and the default gitea
app.ini will be rewritten to take account of the variables provided,
however there are various options to give slightly different
behavior and these can be interrogated with the `-h` option.
The environment variables should be of the form:
GITEA__SECTION_NAME__KEY_NAME
Note, SECTION_NAME in the notation above is case-insensitive.
Environment variables are usually restricted to a reduced character
set "0-9A-Z_" - in order to allow the setting of sections with
characters outside of that set, they should be escaped as following:
"_0X2E_" for "." and "_0X2D_" for "-". The entire section and key names
can be escaped as a UTF8 byte string if necessary. E.g. to configure:
"""
...
[log.console]
COLORIZE=false
STDERR=true
...
"""
You would set the environment variables: "GITEA__LOG_0x2E_CONSOLE__COLORIZE=false"
and "GITEA__LOG_0x2E_CONSOLE__STDERR=false". Other examples can be found
on the configuration cheat sheet.
To build locally, run:
go build contrib/environment-to-ini/environment-to-ini.go
@@ -1,112 +0,0 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package main
import (
"context"
"os"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli/v3"
)
func main() {
app := cli.Command{}
app.Name = "environment-to-ini"
app.Usage = "Use provided environment to update configuration ini"
app.Description = `As a helper to allow docker users to update the gitea configuration
through the environment, this command allows environment variables to
be mapped to values in the ini.
Environment variables of the form "GITEA__SECTION_NAME__KEY_NAME"
will be mapped to the ini section "[section_name]" and the key
"KEY_NAME" with the value as provided.
Environment variables of the form "GITEA__SECTION_NAME__KEY_NAME__FILE"
will be mapped to the ini section "[section_name]" and the key
"KEY_NAME" with the value loaded from the specified file.
Environment variables are usually restricted to a reduced character
set "0-9A-Z_" - in order to allow the setting of sections with
characters outside of that set, they should be escaped as following:
"_0X2E_" for ".". The entire section and key names can be escaped as
a UTF8 byte string if necessary. E.g. to configure:
"""
...
[log.console]
COLORIZE=false
STDERR=true
...
"""
You would set the environment variables: "GITEA__LOG_0x2E_CONSOLE__COLORIZE=false"
and "GITEA__LOG_0x2E_CONSOLE__STDERR=false". Other examples can be found
on the configuration cheat sheet.`
app.Flags = []cli.Flag{
&cli.StringFlag{
Name: "custom-path",
Aliases: []string{"C"},
Value: setting.CustomPath,
Usage: "Custom path file path",
},
&cli.StringFlag{
Name: "config",
Aliases: []string{"c"},
Value: setting.CustomConf,
Usage: "Custom configuration file path",
},
&cli.StringFlag{
Name: "work-path",
Aliases: []string{"w"},
Value: setting.AppWorkPath,
Usage: "Set the gitea working path",
},
&cli.StringFlag{
Name: "out",
Aliases: []string{"o"},
Value: "",
Usage: "Destination file to write to",
},
}
app.Action = runEnvironmentToIni
err := app.Run(context.Background(), os.Args)
if err != nil {
log.Fatal("Failed to run app with %s: %v", os.Args, err)
}
}
func runEnvironmentToIni(_ context.Context, c *cli.Command) error {
// the config system may change the environment variables, so get a copy first, to be used later
env := append([]string{}, os.Environ()...)
setting.InitWorkPathAndCfgProvider(os.Getenv, setting.ArgWorkPathAndCustomConf{
WorkPath: c.String("work-path"),
CustomPath: c.String("custom-path"),
CustomConf: c.String("config"),
})
cfg, err := setting.NewConfigProviderFromFile(setting.CustomConf)
if err != nil {
log.Fatal("Failed to load custom conf '%s': %v", setting.CustomConf, err)
}
changed := setting.EnvironmentToConfig(cfg, env)
// try to save the config file
destination := c.String("out")
if len(destination) == 0 {
destination = setting.CustomConf
}
if destination != setting.CustomConf || changed {
log.Info("Settings saved to: %q", destination)
err = cfg.SaveTo(destination)
if err != nil {
return err
}
}
return nil
}
+5 -1
View File
@@ -108,7 +108,9 @@ curl --connect-timeout 10 --silent --show-error --fail --location -O "$binurl{,.
sha256sum -c "${binname}.xz.sha256"
if [[ -z "${ignore_gpg:-}" ]]; then
require gpg
gpg --keyserver keys.openpgp.org --recv 7C9E68152594688862D62AF62D9AE806EC1592E2
# try to use curl first, it uses standard tcp 443 port and works better behind strict firewall rules
curl -fsSL --connect-timeout 10 "https://keys.openpgp.org/vks/v1/by-fingerprint/7C9E68152594688862D62AF62D9AE806EC1592E2" | gpg --import \
|| gpg --keyserver keys.openpgp.org --recv 7C9E68152594688862D62AF62D9AE806EC1592E2
gpg --verify "${binname}.xz.asc" "${binname}.xz" || { echo 'Signature does not match'; exit 1; }
fi
rm "${binname}".xz.{sha256,asc}
@@ -127,6 +129,8 @@ echo "Creating backup in $giteahome"
giteacmd dump $backupopts
echo "Updating binary at $giteabin"
cp -f "$giteabin" "$giteabin.bak" && mv -f "$binname" "$giteabin"
# Restore SELinux context if applicable (e.g. RHEL/Fedora)
command -v restorecon &>/dev/null && restorecon -v "$giteabin" || true
$service_start
$service_status
+3 -3
View File
@@ -4,9 +4,9 @@ base_path: "."
base_url: "https://api.crowdin.com"
preserve_hierarchy: true
files:
- source: "/options/locale/locale_en-US.ini"
translation: "/options/locale/locale_%locale%.ini"
type: "ini"
- source: "/options/locale/locale_en-US.json"
translation: "/options/locale/locale_%locale%.json"
type: "json"
skip_untranslated_strings: true
export_only_approved: true
update_option: "update_as_unapproved"
+187 -40
View File
@@ -41,10 +41,10 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; App name that shows in every page title
APP_NAME = ; Gitea: Git with a cup of tea
;APP_NAME = Gitea: Git with a cup of tea
;;
;; RUN_USER will automatically detect the current user - but you can set it here change it if you run locally
RUN_USER = ; git
;RUN_USER =
;;
;; Application run mode, affects performance and debugging: "dev" or "prod", default is "prod"
;; Mode "dev" makes Gitea easier to develop and debug, values other than "dev" are treated as "prod" which is for production use.
@@ -69,12 +69,12 @@ RUN_USER = ; git
;; Most users should set it to the real website URL of their Gitea instance when there is a reverse proxy.
;ROOT_URL =
;;
;; Controls how to detect the public URL.
;; Although it defaults to "legacy" (to avoid breaking existing users), most instances should use the "auto" behavior,
;; Controls how to detect the public URL. Most instances should use the "auto" behavior,
;; especially when the Gitea instance needs to be accessed in a container network.
;; * legacy: detect the public URL from "Host" header if "X-Forwarded-Proto" header exists, otherwise use "ROOT_URL".
;; * auto: always use "Host" header, and also use "X-Forwarded-Proto" header if it exists. If no "Host" header, use "ROOT_URL".
;PUBLIC_URL_DETECTION = legacy
;; * legacy: (default <= 1.25) detect the public URL from "Host" header if "X-Forwarded-Proto" header exists, otherwise use "ROOT_URL".
;; * auto: (default >= 1.26) always use "Host" header, and also use "X-Forwarded-Proto" header if it exists. If no "Host" header, use "ROOT_URL".
;; * never: always use "ROOT_URL", never detect from request headers.
;PUBLIC_URL_DETECTION = auto
;;
;; For development purpose only. It makes Gitea handle sub-path ("/sub-path/owner/repo/...") directly when debugging without a reverse proxy.
;; DO NOT USE IT IN PRODUCTION!!!
@@ -175,14 +175,15 @@ RUN_USER = ; git
;; The port number the builtin SSH server should listen on, defaults to SSH_PORT
;SSH_LISTEN_PORT =
;;
;; Root path of SSH directory, default is '~/.ssh', but you have to use '/home/git/.ssh'.
;; Root path of SSH user directory for the system's standalone SSH server if Gitea is not using its builtin SSH server.
;; Default is the '.ssh' directory in the run user's home directory.
;SSH_ROOT_PATH =
;;
;; Gitea will create a authorized_keys file by default when it is not using the internal ssh server
;; Gitea will create an authorized_keys file by default when it is not using the builtin SSH server
;; If you intend to use the AuthorizedKeysCommand functionality then you should turn this off.
;SSH_CREATE_AUTHORIZED_KEYS_FILE = true
;;
;; Gitea will create a authorized_principals file by default when it is not using the internal ssh server
;; Gitea will create an authorized_principals file by default when it is not using the builtin SSH server
;; If you intend to use the AuthorizedPrincipalsCommand functionality then you should turn this off.
;SSH_CREATE_AUTHORIZED_PRINCIPALS_FILE = true
;;
@@ -238,9 +239,6 @@ RUN_USER = ; git
;; Indicate whether to check minimum key size with corresponding type
;MINIMUM_KEY_SIZE_CHECK = false
;;
;; Disable CDN even in "prod" mode
;OFFLINE_MODE = true
;;
;; TLS Settings: Either ACME or manual
;; (Other common TLS configuration are found before)
;ENABLE_ACME = false
@@ -463,6 +461,11 @@ INTERNAL_TOKEN =
;; Name of cookie used to store authentication information.
;COOKIE_REMEMBER_NAME = gitea_incredible
;;
;; URL or path that Gitea should redirect users to *after* performing its own logout.
;; Use this, if needed, when authentication is handled by a reverse proxy or SSO.
;; For example: "/my-sso/logout?return=/my-sso/home"
;REVERSE_PROXY_LOGOUT_REDIRECT =
;;
;; Reverse proxy authentication header name of user name, email, and full name
;REVERSE_PROXY_AUTHENTICATION_USER = X-WEBAUTH-USER
;REVERSE_PROXY_AUTHENTICATION_EMAIL = X-WEBAUTH-EMAIL
@@ -503,9 +506,6 @@ INTERNAL_TOKEN =
;; Password Hash algorithm, either "argon2", "pbkdf2", "scrypt" or "bcrypt"
;PASSWORD_HASH_ALGO = pbkdf2
;;
;; Set false to allow JavaScript to read CSRF cookie
;CSRF_COOKIE_HTTP_ONLY = true
;;
;; Validate against https://haveibeenpwned.com/Passwords to see if a password has been exposed
;PASSWORD_CHECK_PWN = false
;;
@@ -524,6 +524,9 @@ INTERNAL_TOKEN =
;; Set the two-factor auth behavior.
;; Set to "enforced", to force users to enroll into Two-Factor Authentication, users without 2FA have no access to repositories via API or web.
;TWO_FACTOR_AUTH =
;;
;; The value of the X-Frame-Options HTTP header for HTML responses. Use "unset" to remove the header.
;X_FRAME_OPTIONS = SAMEORIGIN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -567,6 +570,11 @@ ENABLED = true
;; Alternative location to specify OAuth2 authentication secret. You cannot specify both this and JWT_SECRET, and must pick one
;JWT_SECRET_URI = file:/etc/gitea/oauth2_jwt_secret
;;
;; The "issuer" claim identifies the principal that issued the JWT.
;; Gitea 1.25 makes it default to "ROOT_URL without the last slash" to follow the standard.
;; If you have old logins from before 1.25, you may want to set it to the old (non-standard) value "ROOT_URL with the last slash".
;JWT_CLAIM_ISSUER =
;;
;; Lifetime of an OAuth2 access token in seconds
;ACCESS_TOKEN_EXPIRATION_TIME = 3600
;;
@@ -728,15 +736,15 @@ LEVEL = Info
;DISABLE_CORE_PROTECT_NTFS=false
;; Disable the usage of using partial clones for git.
;DISABLE_PARTIAL_CLONE = false
;; Set the similarity threshold passed to git commands via `--find-renames=<threshold>`.
;; Default is 50%, the same as git. Must be a integer percentage between 0% and 100%.
;DIFF_RENAME_SIMILARITY_THRESHOLD = 50%
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Git Operation timeout in seconds
;[git.timeout]
;DEFAULT = 360
;MIGRATE = 600
;MIRROR = 300
;CLONE = 300
;PULL = 300
;GC = 60
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -775,6 +783,11 @@ LEVEL = Info
;; Disallow registration, only allow admins to create accounts.
;DISABLE_REGISTRATION = false
;;
;; When DISABLE_REGISTRATION is true, choose how administrator-created accounts are provisioned.
;; - local: create active local accounts immediately
;; - invite: create inactive accounts that require the emailed invitation link before sign-in is enabled
;ADMIN_CREATED_ACCOUNT_MODE = invite
;;
;; Allow registration only using gitea itself, it works only when DISABLE_REGISTRATION is false
;ALLOW_ONLY_INTERNAL_REGISTRATION = false
;;
@@ -1150,15 +1163,15 @@ LEVEL = Info
;; Add co-authored-by and co-committed-by trailers if committer does not match author
;ADD_CO_COMMITTER_TRAILERS = true
;;
;; In addition to testing patches using the three-way merge method, re-test conflicting patches with git apply
;TEST_CONFLICTING_PATCHES_WITH_GIT_APPLY = false
;;
;; Retarget child pull requests to the parent pull request branch target on merge of parent pull request. It only works on merged PRs where the head and base branch target the same repo.
;RETARGET_CHILDREN_ON_MERGE = true
;;
;; Delay mergeable check until page view or API access, for pull requests that have not been updated in the specified days when their base branches get updated.
;; Use "-1" to always check all pull requests (old behavior). Use "0" to always delay the checks.
;DELAY_CHECK_FOR_INACTIVE_DAYS = 7
;;
;; Set the default value for "Delete pull request branch after merge by default" for new repositories
;DEFAULT_DELETE_BRANCH_AFTER_MERGE = false
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1176,9 +1189,17 @@ LEVEL = Info
;[repository.release]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
;; Comma-separated list of allowed release attachment file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
;ALLOWED_TYPES =
;;
;; Number of releases that are displayed on release page
;DEFAULT_PAGING_NUM = 10
;;
;; Max size of each release attachment file in megabytes. Defaults to 2GB
;FILE_MAX_SIZE = 2048
;;
;; Max number of release attachment files per upload. Defaults to 5
;MAX_FILES = 5
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1280,9 +1301,6 @@ LEVEL = Info
;;
;; headers to permit
;HEADERS = Content-Type,User-Agent
;;
;; set X-FRAME-OPTIONS header
;X_FRAME_OPTIONS = SAMEORIGIN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1327,9 +1345,12 @@ LEVEL = Info
;; Leave it empty to allow users to select any theme from "{CustomPath}/public/assets/css/theme-*.css"
;THEMES =
;;
;; The icons for file list (basic/material), this is a temporary option which will be replaced by a user setting in the future.
;; The icon theme for files (basic/material)
;FILE_ICON_THEME = material
;;
;; The icon theme for folders (basic/material)
;FOLDER_ICON_THEME = basic
;;
;; All available reactions users can choose on issues/prs and comments.
;; Values can be emoji alias (:smile:) or a unicode emoji.
;; For custom reactions, add a tightly cropped square image to public/assets/img/emoji/reaction_name.png
@@ -1343,6 +1364,10 @@ LEVEL = Info
;; Dont mistake it for Reactions.
;CUSTOM_EMOJIS = gitea, codeberg, gitlab, git, github, gogs
;;
;; Comma separated list of enabled emojis, for example: smile, thumbsup, thumbsdown
;; Leave it empty to enable all emojis.
;ENABLED_EMOJIS =
;;
;; Whether the full name of the users should be shown where possible. If the full name isn't set, the username will be used.
;DEFAULT_SHOW_FULL_NAME = false
;;
@@ -1593,6 +1618,16 @@ LEVEL = Info
;;
;; Default configuration for email notifications for users (user configurable). Options: enabled, onmention, disabled
;DEFAULT_EMAIL_NOTIFICATIONS = enabled
;;
;; Enable the persistent Super Administrator role for protecting administrator management.
;SUPER_ADMIN_ENABLED = true
;;
;; Controls who can change administrator and super administrator permissions.
;; Options:
;; - super_admin_only: only super administrators can modify or delete administrator accounts and manage all administrator privilege changes.
;; - grantor_only: administrators can promote regular users to administrator and later manage only the administrator accounts they directly promoted.
;; - grantor_inheritance: like grantor_only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible administrator is found.
;ADMIN_MANAGEMENT_POLICY = grantor_only
;; Disabled features for users could be "deletion", "manage_ssh_keys", "manage_gpg_keys", "manage_mfa", "manage_credentials" more features can be disabled in future
;; - deletion: a user cannot delete their own account
;; - manage_ssh_keys: a user cannot configure ssh keys
@@ -1966,12 +2001,12 @@ LEVEL = Info
;; or a custom avatar source, like: http://cn.gravatar.com/avatar/
;GRAVATAR_SOURCE = gravatar
;;
;; This value will always be true in offline mode.
;; Deprecated, see Web UI Admin Panel -> Config -> Settings
;DISABLE_GRAVATAR = false
;;
;; Federated avatar lookup uses DNS to discover avatar associated
;; with emails, see https://www.libravatar.org
;; This value will always be false in offline mode or when Gravatar is disabled.
;; Deprecated, see Web UI Admin Panel -> Config -> Settings
;ENABLE_FEDERATED_AVATAR = false
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1980,16 +2015,18 @@ LEVEL = Info
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Whether issue and pull request attachments are enabled. Defaults to `true`
;; Whether issue, pull-request and release attachments are enabled. Defaults to `true`
;; ALLOWED_TYPES/MAX_SIZE/MAX_FILES in this section only affect issue and pull-request attachments, not release attachments.
;; Release attachment has its own config options in [repository.release] section.
;ENABLED = true
;;
;; Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
;; Comma-separated list of allowed issue/pull-request attachment file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
;ALLOWED_TYPES = .avif,.cpuprofile,.csv,.dmp,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.json,.jsonc,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.webp,.xls,.xlsx,.zip
;;
;; Max size of each file. Defaults to 2048MB
;MAX_SIZE = 2048
;; Max size of each issue/pull-request attachment file. Defaults to 100MB
;MAX_SIZE = 100
;;
;; Max number of files per upload. Defaults to 5
;; Max number of issue/pull-request attachment files per upload. Defaults to 5
;MAX_FILES = 5
;;
;; Storage type for attachments, `local` for local disk or `minio` for s3 compatible
@@ -2262,6 +2299,22 @@ LEVEL = Info
;; Unreferenced blobs created more than OLDER_THAN ago are subject to deletion
;OLDER_THAN = 24h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Synchronize repository licenses
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[cron.sync_repo_licenses]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Whether to enable the job
;ENABLED = false
;; Whether to always run at least once at start up time (if ENABLED)
;RUN_AT_START = false
;; Whether to emit notice on successful execution too
;NOTICE_ON_SUCCESS = false
;; Time interval for job to run
;SCHEDULE = @annually
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2325,7 +2378,19 @@ LEVEL = Info
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Resynchronize pre-receive, update and post-receive hooks of all repositories.
;; Update the '.ssh/authorized_principals' file
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[cron.resync_all_sshprincipals]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ENABLED = false
;RUN_AT_START = false
;NOTICE_ON_SUCCESS = false
;SCHEDULE = @every 72h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Resynchronize git hooks of all repositories (pre-receive, update, post-receive, proc-receive, ...)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[cron.resync_all_hooks]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2431,6 +2496,70 @@ LEVEL = Info
;Check at least this proportion of LFSMetaObjects per repo. (This may cause all stale LFSMetaObjects to be checked.)
;PROPORTION_TO_CHECK_PER_REPO = 0.6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Rebuild issue index
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[cron.rebuild_issue_indexer]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ENABLED = false
;RUN_AT_START = false
;NO_SUCCESS_NOTICE = false
;SCHEDULE = @annually
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Actions cron tasks
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Stop running tasks which haven't been updated for a long time
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[cron.stop_zombie_tasks]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ENABLED = true
;RUN_AT_START = true
;NO_SUCCESS_NOTICE = false
;SCHEDULE = @every 5m
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Stop running tasks which have running status and continuous updates but don't end for a long time
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[cron.stop_endless_tasks]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ENABLED = true
;RUN_AT_START = true
;NO_SUCCESS_NOTICE = false
;SCHEDULE = @every 30m
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Cancel jobs which haven't been picked up for a long time
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[cron.cancel_abandoned_jobs]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ENABLED = true
;RUN_AT_START = false
;NO_SUCCESS_NOTICE = false
;SCHEDULE = @every 6h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Start cron based actions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[cron.start_schedule_tasks]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ENABLED = true
;RUN_AT_START = false
;NO_SUCCESS_NOTICE = false
;SCHEDULE = @every 1m
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[mirror]
@@ -2471,16 +2600,17 @@ LEVEL = Info
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; The first locale will be used as the default if user browser's language doesn't match any locale in the list.
;LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pt-PT,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sv-SE,ko-KR,el-GR,fa-IR,hu-HU,id-ID,ml-IN
;NAMES = English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,Français,Nederlands,Latviešu,Русский,Українська,日本語,Español,Português do Brasil,Português de Portugal,Polski,Български,Italiano,Suomi,Türkçe,Čeština,Српски,Svenska,한국어,Ελληνικά,فارسی,Magyar nyelv,Bahasa Indonesia,മലയാളം
;LANGS = en-US,ro-RO,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pt-PT,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sv-SE,ko-KR,el-GR,fa-IR,hu-HU,id-ID,ml-IN
;NAMES = English,Română,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,Français,Nederlands,Latviešu,Русский,Українська,日本語,Español,Português do Brasil,Português de Portugal,Polski,Български,Italiano,Suomi,Türkçe,Čeština,Српски,Svenska,한국어,Ελληνικά,فارسی,Magyar nyelv,Bahasa Indonesia,മലയാളം
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[highlight.mapping]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Extension mapping to highlight class
;; e.g. .toml=ini
;; Extension mapping to highlight class, for example:
;; .toml = ini
;; .my-js = JavaScript
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2536,7 +2666,19 @@ LEVEL = Info
;; * sanitized: Sanitize the content and render it inside current page, default to only allow a few HTML tags and attributes. Customized sanitizer rules can be defined in [markup.sanitizer.*] .
;; * no-sanitizer: Disable the sanitizer and render the content inside current page. It's **insecure** and may lead to XSS attack if the content contains malicious code.
;; * iframe: Render the content in a separate standalone page and embed it into current page by iframe. The iframe is in sandbox mode with same-origin disabled, and the JS code are safely isolated from parent page.
;RENDER_CONTENT_MODE=sanitized
;RENDER_CONTENT_MODE = sanitized
;; The sandbox applied to the iframe and Content-Security-Policy header when RENDER_CONTENT_MODE is `iframe`.
;; It defaults to a safe set of "allow-*" restrictions (space separated).
;; You can also set it by your requirements or use "disabled" to disable the sandbox completely.
;; When set it, make sure there is no security risk:
;; * PDF-only content: generally safe to use "disabled", and it needs to be "disabled" because PDF only renders with no sandbox.
;; * HTML content with JS: if the "RENDER_COMMAND" can guarantee there is no XSS, then it is safe, otherwise, you need to fine tune the "allow-*" restrictions.
;RENDER_CONTENT_SANDBOX =
;; Whether post-process the rendered HTML content, including:
;; resolve relative links and image sources, recognizing issue/commit references, escaping invisible characters,
;; mentioning users, rendering permlink code blocks, replacing emoji shorthands, etc.
;; By default, this is true when RENDER_CONTENT_MODE is `sanitized`, otherwise false.
;NEED_POST_PROCESS = false
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2671,6 +2813,8 @@ LEVEL = Info
;LIMIT_SIZE_SWIFT = -1
;; Maximum size of a Vagrant upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
;LIMIT_SIZE_VAGRANT = -1
;; Maximum size of a Terraform state upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
;LIMIT_SIZE_TERRAFORM_STATE = -1
;; Enable RPM re-signing by default. (It will overwrite the old signature ,using v4 format, not compatible with CentOS 6 or older)
;DEFAULT_RPM_SIGN_ENABLED = false
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2836,6 +2980,9 @@ LEVEL = Info
;ABANDONED_JOB_TIMEOUT = 24h
;; Strings committers can place inside a commit message or PR title to skip executing the corresponding actions workflow
;SKIP_WORKFLOW_STRINGS = [skip ci],[ci skip],[no ci],[skip actions],[actions skip]
;; Comma-separated list of workflow directories, the first one to exist
;; in a repo is used to find Actions workflow files
;WORKFLOW_DIRS = .gitea/workflows,.github/workflows
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+6
View File
@@ -1,2 +1,8 @@
#!/bin/bash
# $1 = exit code of the run script, $2 = signal
if [ "$1" -ne 0 ]; then
# avoid immediately restarting the sshd service, which may cause CPU 100% if the error (permission, configuration) is not fixed
echo "openssh failed with exit code $1 - waiting a short delay before attempting a restart"
sleep 3
fi
exit 0
@@ -0,0 +1,2 @@
#!/bin/bash
exec /app/gitea/gitea config edit-ini --in-place --apply-env "$@"
@@ -0,0 +1,2 @@
#!/bin/bash
exec /app/gitea/gitea config edit-ini --in-place --apply-env "$@"

Some files were not shown because too many files have changed in this diff Show More