Add a build-time conversion step that transforms the existing Swagger
2.0 spec into an OpenAPI 3.0 spec. The OAS3 spec is served alongside the
existing Swagger 2.0 spec, enabling API clients that require OAS3 to
generate code directly from Gitea's API.
This is not to be an answer to how gitea handles OAS3 long term,
but a way to use what we have to move a step forward.
---------
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Avoid per-item DB queries in ListRuns, ListJobs, and ListActionTasks by
batch-loading trigger users, repositories, and task attributes before
the conversion loop. Remove ReferencesGitRepo from the /actions route
group since no task/run endpoints use it.
Added tests for these endpoints as well.
---------
Signed-off-by: wxiaoguang <wxiaoguang@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>
Adds a new `DEFAULT_TITLE_SOURCE` option under
`[repository.pull-request]` with three values:
- `first-commit` (default): uses the oldest commit summary, current
behavior since v1.26
- `auto`: normalizes branch name as title for multi-commit PRs (just
like GitHub), use commit summary for single-commit PRs
Closes: #37463
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
Co-authored-by: Nicolas <bircni@icloud.com>
This fixes the scheduled action panic when an event payload is JSON
`null` by initializing the payload map before adding `schedule`. It also
adds regression coverage for the null-payload case.
Fixes#37447.
Testing:
- `go test -tags 'sqlite sqlite_unlock_notify' ./services/actions -run
'^TestWithScheduleInEventPayload$' -count=1`
- Local note: this agent ran the command as root with a temporary
`GITEA_TEST_CONF=custom/conf/app-test-root.ini` file that only set
`I_AM_BEING_UNSAFE_RUNNING_AS_ROOT = true`.
Authorship: cyphercodes; AI assistance disclosed: Hermes Agent
(GPT-5.5).
---------
Co-authored-by: cyphercodes <cyphercodes@users.noreply.github.com>
Co-authored-by: Hermes Agent (GPT-5.5) <hermes-agent@users.noreply.github.com>
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Giteabot <teabot@gitea.io>
After using CSP nonce, the "onerror" doesn't work anymore. Change it to
use a global variable to detect
Also help users like #37379 to catch errors more easily.
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Make the watch, star, and fork buttons in the repo header consistent for
logged-out users:
- Apply the same look to all three buttons (number labels
included), instead of only the action button being grayed.
- Clicking any of them while logged out now leads to the login page
(with a redirect back) instead of being inert.
- Split the per-button markup out of `header.tmpl` into a dedicated
`templates/repo/header/` folder (`fork.tmpl`, `star.tmpl`,
`watch.tmpl`).
---------
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Adds a dedicated endpoint for replying to pull request review comments,
```
POST /repos/{owner}/{repo}/pulls/{index}/comments/{id}/replies
{ "body": "..." }
```
The reply is threaded under the same review as the parent comment.
Ref: https://gitea.com/gitea/gitea-mcp/issues/129
Fixes: https://github.com/go-gitea/gitea/issues/37419
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
- hide() also cancels the pending debounced search so a fetch scheduled
before blur/Escape/outside-click does not fire afterwards and re-show
the dropdown on a field the user has already left
- use urlQueryEscape for the {query} substitution to keep escaping
symmetric with the Go backend (matches Go's url.QueryEscape: space → +,
strict RFC 3986 for !'()*); both decoders still accept %20
Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
- collapse the render/keydown/select helpers (replaceChildren with mapped
array, inline ArrowUp/Down branch, drop the move() helper)
- abort the in-flight fetch from hide() so Escape/blur/outside-click
cancel the request, and gate the post-await render on
ctrl.signal.aborted to suppress responses that settle after hide()
- rename idx → index
- restore the leading comment in web_src/css/modules/search.css that an
earlier commit on this branch dropped
Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
After clicking the search result, the test now also clicks Add
Collaborator and asserts the username appears in the page body
(i.e., in the collaborator list after the redirect), proving the
chosen result drives the form submission end-to-end.
Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
- attachSearchBox(el, url, parse) replaces the await-style chooseFromApi
- The component handles input update + change-event dispatch on
selection, so callers don't loop or write back the value themselves
- Each caller is now a single statement; response shape is conveyed via
the parse callback's parameter annotation (T inferred)
Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
The `Repository` struct in `services/context/repo.go` embedded
`access_model.Permission` anonymously, causing all permission methods to
be promoted directly onto `Repository`. This made it unclear at call
sites whether a method belonged to `Repository` itself or to its
embedded `Permission`.
### Changes
- **`services/context/repo.go`**: Replace anonymous
`access_model.Permission` with named field `Permission
access_model.Permission`
- **49 files** updated to route permission method calls through the
named field:
```go
// Before
ctx.Repo.IsAdmin()
ctx.Repo.CanWrite(unit.TypeCode)
ctx.Repo.CanReadIssuesOrPulls(isPull)
slices.ContainsFunc(unitTypes, ctx.Repo.CanWrite)
// After
ctx.Repo.Permission.IsAdmin()
ctx.Repo.Permission.CanWrite(unit.TypeCode)
ctx.Repo.Permission.CanReadIssuesOrPulls(isPull)
slices.ContainsFunc(unitTypes, ctx.Repo.Permission.CanWrite)
```
Methods defined directly on `*Repository` (`CanWriteToBranch`,
`CanCreateBranch`, etc.) are unchanged.
---------
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>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
- chooseFromApi is now generic over the response shape; each caller
declares a typed *SearchResponse, removing four `any` annotations
- e2e test prefix: rc- → repo-collab- for legibility in the test DB
- web_src/css/modules/search.css: drop the stale leading comment
Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
Move web_src/js/modules/fomantic/search.ts to web_src/js/modules/search.ts
(no Fomantic dependency anymore). Replace the imperative
initSearchBox(el, opts) with chooseFromApi(el, url, parse) that returns
a Promise<SearchResult> resolving with the user's chosen item; callers
loop with `while (box.isConnected) { const pick = await ...; ... }` and
own writing back to whatever input/state they manage.
Cleanup is via a single AbortController whose signal is passed to all
listeners; the in-flight fetch has its own controller so a new keystroke
can cancel just the request without tearing down listeners.
Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
Three boxes (repo/user/team) all share the same first-party module, so
one happy-path test on the user box is sufficient as a regression
gate. Drops the org/team helpers in tests/e2e/utils.ts that only those
extra tests motivated.
Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
Drops the 1565-line vendored Fomantic UI search jQuery plugin in favor
of a small first-party TypeScript module covering the three call sites
(repo, user, and team autocomplete). Adds an e2e regression suite that
exercises each search box.
Also fixes input/button vertical alignment in the four forms that wrap
a search box: the fomantic-era `tw-align-middle` workaround is replaced
by `flex-text-block` on the form, which is the codebase's standard
flex helper for this layout.
Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
Replaces Dependabot with Renovate. The new setup:
- One PR per ecosystem (GitHub Actions, Go modules + Makefile go-tool
pins, npm, Python via uv, Nix flake), opened weekly on Mondays with a
5-day release-age cooldown. Vulnerability PRs ship next-day via daily
cron + Renovate's `vulnerabilityAlerts` schedule bypass.
- All `uses:` action refs SHA-pinned with patch-level version comments
(same format as #36971, which this supersedes);
`helpers:pinGitHubActionDigests` keeps future bumps in that format.
- `renovatebot/github-action` runtime image pinned via the
upstream-recommended `RENOVATE_VERSION` env + magic comment +
`customManagers:githubActionsVersions` preset, so Renovate keeps the pin
updated.
- Custom regex manager tracks the `*_PACKAGE ?= <import-path>@<version>`
lines in `Makefile` (golangci-lint, swagger, actionlint, etc.) and
groups them into the same Go PR via `matchDatasources: ["go"]`.
- Post-upgrade tasks regenerate `assets/go-licenses.json` (`make tidy`)
and the SVG sprite (`make svg`), gated by an env-level command
allowlist.
- Replaces the standalone `cron-flake-updater` workflow — Renovate's nix
manager tracks `flake.nix` inputs and produces the same `flake.lock`
bump PRs on the regular weekly schedule.
- npm and gomod-replace pins live in `renovate.json5` only;
`updates@17.16.3` reads them from there too, so the standalone
`updates.config.ts` is gone and one source of truth covers both tools.
Fixes: https://github.com/go-gitea/gitea/issues/33386
Signed-off-by: silverwind <me@silverwind.io>
Signed-off-by: TheFox0x7 <thefox0x7@gmail.com>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: TheFox0x7 <thefox0x7@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: Giteabot <teabot@gitea.io>
Cache includes go, lint and unittests. Integration tests with their
standalone binaries are uncacheable with their current architecture.
Every Go job uses a new composite action (`.github/actions/go-cache`)
that restores and saves the Go module cache, a shared build cache, and
the golangci-lint cache. A `cache-seeder` workflow runs on `push: main`
to pre-populate those slots; PRs read them via GitHub's default-branch
fallback, so the common case is warm from the first commit.
Also dropped `-coverprofile` from `test-unit` (it silently disabled Go's
test result cache), and `-race` from `test-pgsql` and `test-mysql` (kept
on `test-unit` and `test-sqlite`).
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
`make test-sqlite#TestName` was much too slow, suggest `go test`. Also
added a similar instruction for js tests.
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
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/4bd9165' (2026-04-14)
→ 'github:nixos/nixpkgs/0726a0e' (2026-04-22)
```
### 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>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
- fix markup attention block regressions on 2 colors
- added new color "priority" color for important severity in markup
- all message-box style, and error form elements use monochrome text
- tweaked and improved action logs colors
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
The `events › logout propagation` e2e test ([example
flake](https://github.com/go-gitea/gitea/actions/runs/24878089698/job/72839454932))
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
---------
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Slightly reduce the page size for every request, and don't need to use `href="data:`
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
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>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Refactor preparePullViewPullInfo and related functions, split them into
small ones:
* preparePullViewPullInfo creates PullRequestViewInfo struct
* if the PR is merged: prepareView**Merged**PullInfo
* if the PR is open: prepareView**Open**PullInfo
In prepareViewMergedPullInfo and preparePullViewFillInfo: call
preparePullView**FillInfo** consistnently
preparePullViewFillInfo calls preparePullViewFill**CompareInfo** and
preparePullViewFill**CommitStatusInfo**
Adds points to `AGENTS.md` how to run single tests because AIs get these
wrong too often (either they trigger the whole suite or run into other
errors).
---
This PR was written with the help of Claude Opus 4.7
---------
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Removes CSS rules that have zero usages across templates, Go source,
JS/TS/Vue, and `options/`. Each selector was cross-checked for runtime
additions (Fomantic JS, library classes) before removal.
A few rules with no current usages are kept as symmetric pairs of
heavily-used classes likely to be needed:
- `.ui.bottom.attached.header` / `.ui.bottom.attached.message` — pair
with the widely-used `top.attached` variants
- `.ui.warning.header` / `.ui.warning.segment` — warning-themed variants
of error-themed classes that are kept
- `.btn.small` — size variant alongside the kept `.btn.tiny`
---
This PR was written with the help of Claude Opus 4.7
---------
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>