Backport #39818 by @SHIVANSHGARG07
parseProtobufBody read the full Twirp request body via io.ReadAll with
no size limit, allowing an authenticated runner token holder to force
unbounded memory allocation. Cap it at 1 MiB via io.LimitReader,
matching the existing pattern in job_summary.go.
Fixes https://github.com/go-gitea/gitea/issues/39814
Co-authored-by: Shivansh Garg <shivanshgarg587@gmail.com>
Backport #39785 by @bircni
The [Gitea VS Code extension](https://gitea.com/gitea/gitea-vscode)
currently signs in through the builtin `tea` OAuth2 application. Gitea
keeps one grant per user and application, so anyone who has already
signed in with the tea CLI gets `a grant exists with different scope`
when the extension requests its own scopes, and sign-in fails
(gitea/gitea-vscode#24).
This adds a dedicated builtin application for the extension, following
the same mechanism as the existing CLI entries:
| | |
|---|---|
| client ID | `75a9ec3e-42b5-40cb-9144-9ea96ecd56a6` |
| config name | `gitea-vscode` |
| display name | `gitea-vscode` |
| redirect URIs | `http://127.0.0.1`, `https://127.0.0.1` (loopback, any
port) |
It is enabled by default via `[oauth2].DEFAULT_APPLICATIONS`. Instances
that set that option explicitly need to add `gitea-vscode` to use it.
The extension will use this client on Gitea >= 28.2.0 and keep falling
back to `tea` on older servers, so this should be backported to v28.
Co-authored-by: bircni <bircni@icloud.com>
Backport #39807 by @gomitrah
With "Autodetect manual merge" enabled, an empty pull request (one with
no commits of its own, for example opened to discuss a branch) was
closed as manually merged as soon as it was checked. Its head commit is
already an ancestor of the base branch, so the detection took the
"fast-forwarded" path and recorded the head itself as the merge commit,
even though nothing was merged.
Detection now skips a PR whose head commit is its merge base, the same
condition Gitea already uses to show a PR as "already included in the
target branch". Real manual merges are still detected, including when
the base branch and the PR branch are pushed together.
The merge base is refreshed on recheck, so a fast-forward manual merge
whose merge base was already refreshed to the head is not detected
either. This only misses a detection and never closes a PR wrongly;
telling the two apart would need a value stored at PR creation.
Fixes https://github.com/go-gitea/gitea/issues/31947
Co-authored-by: Mitrahsoft <bala.c@mitrahsoft.in>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Backport #39740 by @Zettat123
Cancelling running schedule runs has not worked since
https://github.com/go-gitea/gitea/pull/35767: callers pass a branch name
like `main`, while schedule runs store the full ref like
`refs/heads/main`. Disabling Actions, archiving the repository or
changing the default branch left them running.
Fixing the ref alone would also cancel them on every push to the default
branch, which GitHub does not do, and whenever the Actions setting is
saved, so those paths now only replace the schedules.
Changing or renaming the default branch deleted the schedules without
registering the new branch's ones
(https://github.com/go-gitea/gitea/pull/28691), so they stopped until
the next push, and the API path kept the old ones. Both now switch the
schedules to the new default branch, since scheduled workflows only run
on the default branch.
Only the push case was verified on GitHub, as its scheduled workflows
have rarely been triggering lately.
Co-authored-by: Zettat123 <zettat123@gmail.com>
Backport #39781 by @SudhanshuMatrix
## What
`parseGitDiffTreeLine` (`services/gitdiff/git_diff_tree.go`) read
`BasePath`/`HeadPath` straight from `git diff-tree --raw` output without
undoing git's C-quoting, unlike its sibling `parseLsTreeLine`
(`modules/git/parse.go`), which already does this with
`strconv.Unquote`.
This fix applies the same unquoting to both paths in the diff-tree
parser.
## Why
With the default `core.quotePath=true`, git C-quotes **any path
containing a non-ASCII byte** — not just tabs/newlines/backslashes. That
means any file with a CJK, Cyrillic, accented-Latin, or emoji name gets
octal-escaped, e.g.:
```
:100644 100644 b6fc4c6... 04fea06... M "\346\227\245\346\234\254\350\252\236.txt"
```
(`日本語.txt`, confirmed against real `git diff-tree --raw` output)
`GetDiffTree` backs the file-tree sidebar on the commit, compare, and
pull request diff pages (`routers/web/repo/commit.go`, `compare.go`,
`pull.go`). Without unquoting, any such file shows its mangled, escaped
name instead of the real one, and the wrong path can throw off
jump-to-file and viewed-file-state behavior that key off the path.
Co-authored-by: Shudhanshu Singh <sudhanshuwriterblc@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Backport #39747 by @AliceLafox
* Fixes#39746
* Fixes#35505
The click handlers were bound only to the first `.reference-list-menu`
(branches), so clicking a tag did nothing. Bind them to the items of
both lists.
Co-authored-by: Alisa Lafoks <alice@lafox.net>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Backport #39681 by @silverwind
Gitea changed the `dist.tarball` it advertises for already published
versions twice:
| Gitea | `dist.tarball` path of `@scope/name@1.0.0` |
|---|---|
| 1.27 | `%40scope%2Fname/-/1.0.0/name-1.0.0.tgz` |
| 28.0, https://github.com/go-gitea/gitea/pull/39061 |
`@scope%2Fname/-/1.0.0/name-1.0.0.tgz` |
| 28.1, https://github.com/go-gitea/gitea/pull/39434 |
`@scope/name/-/name-1.0.0.tgz` |
pnpm 11.5.2+ verifies the tarball URLs pinned in its lockfile against
the registry metadata, so frozen installs of lockfiles written against
1.27 fail with `ERR_PNPM_TARBALL_URL_MISMATCH`.
- Versions uploaded before this PR get their 1.27 URL back.
- New versions store their canonical tarball path at upload, so later
URL changes can't reach published versions. The host still follows the
request.
Lockfiles written against 28.0 for scoped packages, or by pnpm 12 with
`@scope:registry` against 28.1, need those pinned `tarball:` entries
removed, as 1.27 lockfiles of the same versions need the other URL.
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: silverwind <me@silverwind.io>
Backport #39721 by @bircni
Fixes a few Actions bugs where user input or nondeterminism caused
failures:
- The job log view indexed task steps with the client-supplied cursor
step without a bounds check, so an out-of-range value panicked and
returned a 500.
- Workflow activity type filters (`types:`) were compiled with
`glob.MustCompile`, so an invalid pattern in a workflow file panicked
during event detection. Invalid patterns now simply don't match.
- Listing workflow runs with an unknown `actor` returned a 500; it now
returns 404.
- The v4 artifact `ListArtifacts` response was built by ranging over a
map, so its order changed between calls. It now follows database order.
- The error from marshalling a workflow job when inserting run jobs was
silently ignored.
Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Backport #39728 by @silverwind
Since https://github.com/go-gitea/gitea/pull/39703, Gitea fails to start
when its gitconfig holds a `gc.reflogExpire` other than `90` (e.g.
`30.days`), because `git config --unset-all` exits 5 when no value
matches. Value patterns were also unanchored regexps, so `90` also
removed `90.days`.
- Match values exactly in `configUnsetAll` and `configAddNonExist`
- Treat "nothing to unset" as success
- Use `--replace-all` in `configSet` so a key with multiple values no
longer fails startup
Co-authored-by: silverwind <me@silverwind.io>
Backport #39706 by @benv666
Fixes#39702
**Root Cause:**
Cancelling a reusable workflow caller wrote it `cancelled` right away,
even while a child was still `cancelling`. When the runner acknowledged,
the caller did not change, so the run was never refreshed and stayed
`cancelling`.
SQLite hid this because the child is cancelled a second time, which
re-aggregates the caller, while MySQL reports no affected rows for that
unchanged update.
**Changes:**
- A caller now takes its status only from its children: it stays
`cancelling` until its last child finishes, and its final status then
refreshes the run.
- Cancelling a run whose jobs are all done only settles the run, which
did not wake the runs waiting for its concurrency group. It now does, so
force-cancelling an already stuck run also frees them.
NOTE: Code was AI-generated, but reviewed and tested by me.
Signed-off-by: BenV <165034+benv666@users.noreply.github.com>
Co-authored-by: BenV <165034+benv666@users.noreply.github.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
Backport #39703 by @silverwind
Gitea's default `gc.reflogExpire = 90` is parsed by git as
`1990-<month>-<day>`, currently `1990-10-09`, so reachable reflog
entries never expired.
Since git 2.54, auto maintenance runs its reflog-expire task in the
foreground of every push, and its trigger ignores reachability, so busy
repos rerun `git reflog expire --all` on every push without pruning
anything, stalling large repos for over a minute.
- Stop setting `gc.reflogExpire` so git's own defaults apply, and remove
the `90` written by earlier versions
- Treat the legacy `[git.reflog] EXPIRATION` as days, as documented
The next push to each repo prunes the accumulated entries once.
Fixes: https://github.com/go-gitea/gitea/issues/39693
Co-authored-by: silverwind <me@silverwind.io>
Backport https://github.com/go-gitea/gitea/pull/39695
`go.sum` conflicted on older x/net `go.mod` hashes that `release/v28`
still lists. `make tidy` resolves it to the same change as on `main`.
Backport #39498 by @SHIVANSHGARG07
The OIDC discovery document at `/.well-known/openid-configuration`
advertised `id_token` in `response_types_supported`, but
`/login/oauth/authorize` only implements the authorization code flow and
rejects any other response_type with `unsupported_response_type`. This
mismatch caused OIDC client libraries that rely on discovery to attempt
the implicit flow and fail silently.
This removes `id_token` from `response_types_supported` so discovery
matches actual server behavior, and adds an integration test asserting
`response_type=id_token` is rejected consistently.
Manually verified: rebuilt Gitea, registered an OAuth2 app, confirmed
`/.well-known/openid-configuration` no longer lists `id_token`, and
confirmed `/login/oauth/authorize?...&response_type=id_token` still
correctly returns `error=unsupported_response_type`.
Fixes#39482.
<!--
Before submitting:
- Target the `main` branch; release branches are for backports only.
- Use a Conventional Commits title, e.g. `fix(repo): handle empty branch
names`.
- Read the contributing guidelines:
https://github.com/go-gitea/gitea/blob/main/CONTRIBUTING.md
- Documentation changes go to https://gitea.com/gitea/docs
Describe your change below and link any issue it fixes.
-->
Co-authored-by: Shivansh Garg <shivanshgarg587@gmail.com>
Backport #39685 by @GiteaBot
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
| [go](https://go.dev/)
([source](https://redirect.github.com/golang/go)) | toolchain | patch |
`1.27.1` → `1.27.2` |
---
### Configuration
📅 **Schedule**: (UTC)
- Branch creation
- At any time (no schedule defined)
- Automerge
- At any time (no schedule defined)
🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.
♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box
---
This PR has been generated by [Mend Renovate
CLI](https://redirect.github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMjEuNCIsInVwZGF0ZWRJblZlciI6IjQ0LjEyMS40IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->
Backport #39657 by @bircni
Release notes: revert commits and the commits they revert are now left
out of the git-cliff changelog. A step before git-cliff finds commits
whose subject starts with "revert", reads the PR numbers on their revert
lines, and writes both SHAs to `.cliffignore`.
Snap: since the move from Launchpad to GitHub Actions, every build was
uploaded to `latest/edge`, including the stable-grade build that
`part-gitea-pull.sh` makes for an unreleased tag. Launchpad used to
release those builds to candidate and stable automatically. Without
that, v28.0.0 had to be promoted by hand and v28.1.0 stayed in edge.
Stable-grade snaps now go to `latest/stable` and `latest/candidate`;
main builds still go to edge. Candidate has to be updated too because
the pull script compares against it.
Signed-off-by: bircni <bircni@icloud.com>
Co-authored-by: bircni <bircni@icloud.com>
Backport #39650 by @Kshot3000
Since the Telegram webhook switched to Bot API rich messages
(https://github.com/go-gitea/gitea/pull/38298), a bare newline in
`rich_message.html` is treated as insignificant whitespace, so
multi-line messages — issue and PR bodies, comments, push commit lists —
arrive in Telegram as a single paragraph. This restores the old layout
by converting line breaks (`\n`, `\r\n`, `\r`) to `<br>` in
`createTelegramPayloadHTML`, after sanitizing, covering every Telegram
payload type at once.
Verified: the new `Line breaks are kept in rich messages` test plus the
updated Push/Issue/IssueComment/PullRequest/Review expectations fail on
unpatched code (literal `\n` in the payload) and pass with the fix; the
full `services/webhook` package passes, gofmt/vet clean.
Fixes https://github.com/go-gitea/gitea/issues/39649
---
Tips welcome: PayPal kyleblake0659@gmail.com · BTC
3GnR7TWBXAB3pPztBWpNF4LMNEX5yX8vZK
Co-authored-by: KShot <kshot9000@gmail.com>
Backport #39663 by @nschloe
Since MathML is allowed in markup (#36352, #38034, #39337), a
display-style `<math display="block">` sits flush against the text below
it: it gets no margin of its own, and markup paragraphs have
`margin-top: 0`. Display math rendered by KaTeX gets 16px above and
below.
This adds `math[display="block"]` to the markup block elements that get
`margin-top: 0; margin-bottom: 16px`, like `p`, `pre` and `table`.
To test, view a Markdown file containing
```markdown
Text before.
<math display="block">
<mi>x</mi><mo>=</mo><mn>1</mn>
</math>
Text after.
```
Before, the equation has 16px above and 0px below; after, 16px on both
sides.
Before:
<img width="1544" height="238" alt="before"
src="https://github.com/user-attachments/assets/318238d9-018c-4945-974c-91bd1b282ff2"
/>
After:
<img width="1544" height="283" alt="after"
src="https://github.com/user-attachments/assets/9afde2be-b5ed-4624-a33f-4933e7fae79b"
/>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Nico Schlömer <nschloe@users.noreply.github.com>
Co-authored-by: silverwind <me@silverwind.io>
Backport #39611 by @Kshot3000
* Fixes#39606
* Fixes#39329
`GetLatestCommitStatusForRepoCommitIDs` built one `OR` condition per
commit SHA. Rendering a commit list of more than ~1000 commits (for
example a large pull request, via `processGitCommits`) therefore failed
on SQLite with `SQL logic error: Expression tree is too large (maximum
depth 1000)`.
The max-index lookup now queries SHAs in chunks of 500 with `IN`, and
the follow-up status fetch runs in chunks of 100 `(index, sha)` pairs,
so the expression depth stays bounded regardless of the commit count.
Results are unchanged.
Verified with a new regression test that calls the function with 2001
SHAs: it fails with the reported error on `main` and passes with this
change. `go test ./models/git/` passes.
—
Fix offered freely; tips welcome: PayPal kyleblake0659@gmail.com · BTC
3GnR7TWBXAB3pPztBWpNF4LMNEX5yX8vZK
Co-authored-by: KShot <kshot9000@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Backport #39613 by @dziulatex
Fixes#39598
When the base branch has "Block merge if the pull request is outdated"
enabled, an AGit pull request that fell behind could never be unblocked:
merging the base branch into the topic and pushing it again to the same
`refs/for/<branch>/<topic>` left the PR "blocked because it's outdated"
forever.
The outdated block reads the stored `commits_behind`. Pushing a branch
refreshes it for GitHub-flow PRs (`AddTestPullRequestTask`), but the
AGit update path in `services/agit` moved `refs/pull/N/head` without
recomputing it, so the value only changed when the base branch was
pushed, which is the event that makes a PR behind again.
The AGit update path now calls `syncCommitDivergence` in
`UpdateRefForAgit`, the same as AGit PR creation (`NewPullRequest`)
already does.
Signed-off-by: dziulatex <paweldziurasoftware@yahoo.com>
Co-authored-by: dziulatex <38464243+dziulatex@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Backport #39612
* Fix#39610
* Regression of #39262
Also, the old code is very fragile: `#branch_target` is from translation
string, so refactored it together
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Backport #39589 by @bircni
When the job emitter itself finishes the last jobs of a called workflow
(e.g. skipped by `if:`), `UpdateRunJob` cascades the caller to done in
the database only. The pass kept the caller unfinished in memory and
nothing re-emitted the run, so jobs that `needs:` the caller stayed
`Pending` and the caller's commit status stayed "In progress".
The pass now reloads such callers so their commit statuses close, and
re-emits the run so their dependents are resolved in the next pass. They
are not resolved in the same pass because their `if:` and `concurrency:`
read the caller from the database, where it is not finished until the
pass writes the children.
* Fixes https://github.com/go-gitea/gitea/issues/39587
* Fixes https://github.com/go-gitea/gitea/issues/39586
Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Backport https://github.com/go-gitea/gitea/pull/39603 by @silverwind
Uses `FetchRemoteCommit`, as v28 has no `FetchRemoteTempCommit`, so no
`--no-write-fetch-head` is involved.
Reverts the backport https://github.com/go-gitea/gitea/pull/39585 before
v28.0.1 ships. The change stays on main for v29.
gitea-runner v4.1.0 recognizes a rejected registration only by the old
`Unknown`-coded `rpc error: code = Unauthenticated desc = unregistered
runner` error. With the new `Unauthenticated` reply, an ephemeral runner
keeps its spent registration file and fails on every restart instead of
registering again. The runner fix is in
https://gitea.com/gitea/runner/pulls/1287, so a patch release shouldn't
change runner behavior before that fix has shipped.
Written by Claude Code.
Backport #39436 by @breken-ai
The `org` render meta is lower-cased (`Repository.composeCommonMetas`
sets `metas["org"] = strings.ToLower(repo.OwnerName)`), but
`mentionProcessor` compares it with the org part of the mention exactly
as typed, while the team part is lower-cased before its lookup. So in a
repository of the org `MyOrg`, `@MyOrg/developers` stays plain text,
although `ResolveIssueMentionsByVisibility` lower-cases the name and
still notifies that team.
This compares the org part case-insensitively and adds a render test for
team mentions.
The code is the same on `release/v1.27`, so it could be backported.
### Verification
- `go test ./modules/markup/ -run TestRender_TeamMention -count=1`: the
`@Org1/Developers` case renders as plain text on current main and as the
team link with this change; `go test ./modules/markup/...` passes.
- `golangci-lint run ./modules/markup/` (v2.13.2): 0 issues.
### AI assistance
This contribution was prepared with AI assistance. The behavior, the
metas and mention-resolution code paths, the patch and the test were
reviewed manually.
> Built by breken, your AI support engineer - breken.ai - this one's on
us.
Co-authored-by: breken <support@brekfuz.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>