100 Commits
Author SHA1 Message Date
19d1e1d334 test: enable WAL for sqlite integration tests (#37861)
Enable `SQLITE_JOURNAL_MODE = WAL` for the sqlite integration test
config. With modernc as the default driver, concurrent writers serialize
on SQLite's single write lock and the tail of the queue can exceed the
20s busy timeout under CI load. WAL drains the queue fast enough to stay
inside the timeout (removes rollback's fsync-per-commit and
reader-vs-commit blocking) and covers all sqlite integration tests in
one change.

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

---------

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-06-10 10:32:32 +02:00
a39b2775ed test: speed up two tests (#37905)
Two test-only changes that cut the `-race` backend unit job's critical
path, with no behavior change.

- **`modules/auth/password/hash`** — `TestHashing`/`TestVectors`
exercised the CPU-bound KDFs (scrypt `N=65536`, pbkdf2, bcrypt, argon2)
serially on one core. Marking the subtests `t.Parallel()` fans them
across cores. The hasher registry they read is only mutated by the
non-parallel `Test_registerHasher`, so this is race-free.
- **`services/release`** — `TestRelease_Update`/`TestRelease_createTag`
slept `6x time.Sleep(2s)` only to cross the 1-second `CreatedUnix`
boundary. Replaced with an advancing mocked clock (`timeutil.MockSet`),
making the timestamp assertions deterministic and removing the real
waits.

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

Co-authored-by: Claude (Opus 4.8) <noreply@anthropic.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-05-31 03:33:13 +00:00
d0eba5e961 chore(deps): update urfave/cli/v3 to v3.9.0 (#37863)
Updates `github.com/urfave/cli/v3` to
[v3.9.0](https://github.com/urfave/cli/releases/tag/v3.9.0) and removes
the renovate pin now that
[urfave/cli#2319](https://github.com/urfave/cli/pull/2319) (the `-c`
help flag parsing fix) is merged.

v3.9.0 prepends the default command name to the root command's args,
which broke the old `Root().Args()` check in `isValidDefaultSubCommand`.
It now uses the command's own `Args()`.

Behavior change: `./gitea web <extra-positional-arg>` now errors with
`unknown command` instead of starting the web server and ignoring the
trailing arg. `web` takes no positional args, so this is stricter (and
arguably more correct) input handling. The intended `./gitea bad-cmd`
rejection is unchanged.

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

---------

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-30 20:56:16 +00:00
28096162fa chore(css): remove unneeded CSS vendor prefixes (#37903)
Removes redundant/obsolete WebKit prefixes:

- `-webkit-mask-*` — duplicate the unprefixed `mask-*` siblings already
present; every supported browser handles unprefixed CSS Masking
longhands.
- `-webkit-overflow-scrolling: touch` — a no-op outside iOS Safari <13.

Browser floor (all support unprefixed `mask`): Chrome 120+, Safari
15.4+, Firefox 53+, and PaleMoon/Goanna (verified: unprefixed `mask`
longhands implemented unconditionally in UXP).

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

Co-authored-by: Claude (Opus 4.8) <noreply@anthropic.com>
2026-05-30 20:18:10 +00:00
silverwindandGitHub 82cf75b68a enhance(markup): improve issue title rendering (#37908) 2026-05-30 18:55:26 +02:00
2960d6889c ci: stabilize Elasticsearch tests (#37906)
At a 512m heap the CI Elasticsearch GC-thrashes under the jobs' memory
pressure and goes unresponsive, flaking `test-unit` (ES indexer tests
time out) and `test-mysql` (the ES-backed issue indexer blocks the
per-test queue flush). Raise the heap to 1g and disable ML + the startup
GeoIP download.

Co-authored-by: Claude (Opus 4.8) <noreply@anthropic.com>
2026-05-30 01:08:57 +00:00
dafc9e127a chore: update giteabot to v1.0.3 (#37896)
Bump the pinned `giteabot` action to the
[`v1.0.3`](https://github.com/go-gitea/giteabot/releases/tag/v1.0.3)
release in both `giteabot.yml` and `giteabot-backport.yml`. v1.0.3 moves
label/state queries off the search API on top of the existing retry
logic.

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

Co-authored-by: Claude (Opus 4.8) <noreply@anthropic.com>
2026-05-29 10:10:51 +00:00
52fef74291 fix(frontend): resolve Vite assets by manifest source path (#37836)
In dev mode `/api/swagger` returned HTTP 500 (`Failed to locate local
path for managed asset URI: css/swagger.css`): the backend synthesised
asset keys from the Vite entry name instead of reading the manifest,
which only worked by coincidence and broke once a source file name
diverged from its entry name.

This keys the manifest by its source path (e.g. `web_src/js/index.ts`)
and resolves entries directly — hashed `file` in prod, dev-server source
in dev. A new `AssetCSSLinks` helper renders a JS entry's stylesheet
`<link>` tags from the manifest (the entry's CSS plus the CSS of its
statically-imported chunks).

Fixes: https://github.com/go-gitea/gitea/issues/37830
Fixes: https://github.com/go-gitea/gitea/pull/37832
Fixes: https://github.com/go-gitea/gitea/pull/37876
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: prakhar0x01 <prakharporwal2004@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-05-28 06:14:52 +00:00
3c73da51b9 test: fix flaky issue-comment close test (#37880)
After posting a comment the page reloads via fetch-action. Clicking
"Close Issue" before the form re-initializes triggers a native form
submit, which navigates to the raw JSON redirect response
(`{"redirect":...}`) instead of the issue, so "Reopen Issue" never
appears and the test times out (observed on Firefox in CI).

Wait for the comment button to become disabled — which only happens once
the form re-initializes — before clicking "Close Issue".

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

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-28 05:09:21 +00:00
b4407e36aa fix(actions): ack re-sent UpdateLog finalize idempotently (#37885)
Fixes https://github.com/go-gitea/gitea/issues/37871, full backwards and
forwards compatible with runners.

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-05-28 05:19:46 +02:00
f810e882a4 chore(deps): update chroma, regexp2 v2, replace dimiro1/reply (#37858)
- Update `github.com/alecthomas/chroma/v2` to `v2.25.0`.
- Migrate `github.com/dlclark/regexp2` to `/v2` (incorporates
https://github.com/go-gitea/gitea/pull/37664); drop the renovate pin.
- Replace the unmaintained `github.com/dimiro1/reply` (the last consumer
of `regexp2` v1 in our own code) with a small built-in reply parser for
incoming mail.

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
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>
2026-05-27 23:39:57 +02:00
3223d919b0 test: fix flaky TestResourceIndex and reduce its runtime (#37847)
The modernc SQLite driver (default since
https://github.com/go-gitea/gitea/pull/37562) returns `SQLITE_BUSY` once
the busy timeout is reached, unlike mattn which waited indefinitely.
`TestResourceIndex` fires many concurrent `NewIssue` writers, but SQLite
serializes all writers, so they queue on a single `BEGIN IMMEDIATE`
write lock. Under `-race` (modernc is much slower) the goroutines at the
back of the queue exceeded the hardcoded 5s test timeout, producing
`database is locked (5) (SQLITE_BUSY)`.

Changes:
- Reduce the concurrent inserts from 25 to 10. Since SQLite serializes
writers, the extra goroutines only deepen the busy-lock queue without
adding coverage. 10 still exercises concurrent index allocation while
cutting the test's `-race` runtime ~3x (2.76s to 0.86s locally).
- Share the busy-timeout constant: export `DefaultSQLiteBusyTimeout`
(20s, the production default) and reference it from the test engine
instead of the hardcoded `5000`.

Observed flake:
https://github.com/go-gitea/gitea/actions/runs/26394082930/job/77690496092

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

---------

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-05-26 05:06:54 +00:00
7d8bfb8dc6 test: run TestAPIRepoMigrate offline via a local clone source (#37817)
`TestAPIRepoMigrate` migrated from
`https://github.com/go-gitea/test_repo.git`, so it required internet
access, was slow, and could hit GitHub rate limits.

It now clones a local fixture repo (`user2/repo1`) served by the
`onGiteaRun` test server, split into two subtests:

- `Permitted` (`AllowLocalNetworks=true`) — the success/permission
cases, cloning the local repo.
- `DisallowedHost` (`AllowLocalNetworks=false`) — the private-IP
rejection cases.

The split is needed because those two settings are mutually exclusive.
The clone address is built from the live listener (`u`) so it can't
drift from the bound host/port. The permission matrix and
disallowed-host assertions are unchanged.

Test is now roughly 2.5 times as fast with while asserting the same as
before without a GitHub dependency.

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

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-23 21:04:54 +00:00
502d3c1f9d ci: tweak files-changed, add free-disk-space (#37819)
Reduces CI minutes consumption by narrowing the `files-changed` filters.

- DB matrix (`pgsql`/`mysql`/`mssql`/`unit`) now runs only on real
backend changes. `test-sqlite` stays gated on `actions`, so it remains
the smoke check that validates CI-infra changes (composite-action edits,
workflow edits, renovate action-pin bumps) without spinning up the full
matrix.
- Fix the `templates` filter: the SVG template linter is
`tools/lint-templates-svg.ts`, so the `tools/lint-templates-*.js` glob
matched nothing.
- Add missed paths: `tsconfig.json` and
`tools/generate-svg-vscode-extensions.json` to `frontend`,
`eslint.json.config.ts` to `json`, and
`.github/actions/docker-dryrun/**` to `docker`.

---
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>
2026-05-23 03:09:18 +02:00
a290d81eab ci: cap Elasticsearch heap in db-tests (#37816)
Elasticsearch JVM heap defaults to ~50% of detected host RAM, typically
way too much for our little tests and it starved the other runner
processes from memory.

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-05-22 20:39:10 +00:00
570173b409 ci: add shellcheck linter (#37682)
- Adds `make lint-shell`. uses local `shellcheck` if its version
matches, otherwise runs the pinned image via docker or podman
- `.shellcheckrc` disables the most annoying rules
- Fixes findings across existing scripts

Fixes: #37648
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: TheFox0x7 <thefox0x7@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-22 20:22:04 +00:00
f95c210abe ci: split pgsql shards into plain jobs, dedupe setup actions (#37802)
1. Split the psql matrix jobs into composite actions. Matrix jobs that
can skip do not work with required checks on GitHub because skipped and
unskipped emit different job names (GitHub bug
https://github.com/orgs/community/discussions/9141).
2. Dedupe node and go setup steps into composite actions

Currently test-psql branch protection is disabled, will re-enable when
merging this.

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-22 19:07:35 +00:00
7c12446c1f test(e2e): add comment, release, star, PR and fork tests (#37800)
Adds Playwright e2e coverage for five high-value workflows, each driven
through semantic locators with API-based setup:

- comment on and close an issue
- publish a release
- star and watch a repository
- create a pull request from the compare page
- fork a repository

Also passes `autoInit: false` in existing tests that only exercise
DB-backed units (issues, reactions, milestones, projects, events),
skipping an unused initial commit to speed up their setup and reduce
parallel git contention.

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

---------

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-22 18:52:04 +00:00
b7e95cc48c feat: add copy button to action step header, improve other copy buttons (#37744)
- Adds a copy button to each action step header that copies the step's
rendered log output to clipboard.
- Extract a shared `copyToClipboard(target, content)` helper in
`clipboard.ts` that adds SVG success/failure feedback.
- `is-loading` height for the new helper is sourced from
`--loading-size`.
- Change actions log timestamp format to include seconds.

The indented-markdown code-block fix has moved to #37748.

<img width="244" height="165" alt="copystep"
src="https://github.com/user-attachments/assets/ce286b51-f77b-4d82-b161-ca0aa7ec4fdc"
/>

<img width="187" height="150" alt="copybt"
src="https://github.com/user-attachments/assets/5366b290-b776-496d-8dd4-58d5fa60be92"
/>

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

---
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>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-21 07:39:09 +00:00
2e96e8227f style: misc UI fixes (#37691)
- Action view sidebar: rename `job-brief-item` to
`action-view-sidebar-item`, fix trash icon overflow on long artifact
names, align artifact and workflow hover styles with the jobs list
- Branches: expand new PR button cell to three wide so the button is not
clipped on narrow viewports
- Dashboard feed: add `tw-max-w-full` so long issue titles truncate
- Reactions: tighten label padding

<img width="261" height="65" alt="Screenshot 2026-05-13 at 16 18 33"
src="https://github.com/user-attachments/assets/ecfe8f37-4a65-4839-b8c0-defccc85482c"
/>
<img width="154" height="126" alt="Screenshot 2026-05-13 at 16 19 25"
src="https://github.com/user-attachments/assets/41302134-d1b7-401a-be2d-79173adb6d17"
/>
<img width="405" height="378" alt="Screenshot 2026-05-13 at 16 47 18"
src="https://github.com/user-attachments/assets/e2c5cdd4-f11d-498c-b17e-c74c80c0ddf7"
/>
<img width="206" height="149" alt="Screenshot 2026-05-13 at 16 55 53"
src="https://github.com/user-attachments/assets/7787125d-04b1-4500-b9b8-2637845509d6"
/>
<img width="858" height="135" alt="Screenshot 2026-05-13 at 16 58 41"
src="https://github.com/user-attachments/assets/cb5bdf56-3891-469d-aa77-ea38855958c1"
/>
<img width="434" height="128" alt="Screenshot 2026-05-13 at 17 00 43"
src="https://github.com/user-attachments/assets/60f2c34d-b345-4813-8f6d-a95bf51021b4"
/>



---
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>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-05-21 07:02:05 +00:00
93b8fdcd68 ci: shard tests and reduce redundant work (#37618)
Critical path ~25:42 → ~19:56 (−22%), ~0% CI minutes.

- `test-pgsql` shards 2-way. Branch protection: replace `test-pgsql`
with `test-pgsql-shards (1)` + `test-pgsql-shards (2)`; `test-unit`,
sqlite/mysql/mssql unchanged — pgsql dominates the critical path.
- `test-unit` runs `bindata` then `bindata gogit` sequentially.
cache-seeder pre-warms the race-instrumented test compile cache and the
integration test binary so PR jobs warm-start.
- Cache writes restricted to cache-seeder; PR jobs use
`actions/cache/restore`. Defends against PR cache poisoning and frees
the 10 GB cap from PR churn.
- `go-cache` action: dropped the `cache-name` input. One gobuild cache,
one golangci-lint cache. Seeder lint job restores but doesn't save
gobuild, so only one writer populates it.
- `tools/test-integration.sh` shards the integration binary via
`-test.list`; `TestMain` short-circuits DB init in list mode.

`TestAPILFSNotStarted` / `TestAPILFSLocksNotStarted` switched to
`test.MockVariableValue` — latent `setting.LFS.StartServer` global-state
leak uncovered by sharding.

---
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>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-21 06:58:41 +02:00
silverwindandGitHub 33c60ad7b2 chore: simplify issue and pull request templates (#37799) 2026-05-21 06:26:31 +02:00
621aa67e7d fix(markup): wrap indented code blocks for the code-copy button (#37748)
Indented (4-space) code blocks were emitted by goldmark's default
renderer as plain `<pre><code>` without the `code-block-container`
wrapper that the JS `initMarkupCodeCopy` keys on. As a result, only
fenced code blocks received the copy button. Register
`ast.KindCodeBlock` with a renderer that produces the same wrapper as
the highlighting renderer so both syntaxes get the button.

Extends `TestMarkdownFencedCodeBlock` to assert the wrapper is emitted
for indented blocks (and that HTML inside is escaped).

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-05-19 15:09:56 +02:00
985ca76db0 ci: fix cache-related issues (#37761)
Fixes two recurring CI failures:

1. `cache-seeder.yml` lint-backend missing a `make generate-go` before
linting with `TAGS=bindata`, and `pull-compliance.yml` lint-on-demand
failing its post-step pnpm cache save when no pnpm-using conditional
step runs.
2. Drops `cache: pnpm` from lint-on-demand and adds `make generate-go`
to cache-seeder's lint job.

---
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>
2026-05-18 16:21:46 +00:00
83151e98cc ci: narrow files-changed frontend filter (#37749)
Drop the broad `tools/*.{js,ts}` globs from the `frontend` filter so
edits to CI-only or backend helper scripts in `tools/` stop triggering
frontend and e2e jobs. Only `tools/generate-svg.ts` is kept.

Also renames `tools/lint-pr-title.js` to `.ts` for consistency, drops
the empty root `*.js` glob, fixes stray indentation in the `dockerfile`
filter and adds missing `setup-node`.

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

---------

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-05-18 05:38:40 +00:00
d9149d8a0a fix(migrations): preserve unique constraints in v334 sync (#37743)
The truncated `ActionRunner` struct in
`AddCancellingSupportToActionRunner` declares only the new
`HasCancellingSupport` column. When xorm's `SyncWithOptions` compares it
against the live `action_runner` table, every index/constraint absent
from the local struct is a candidate for removal.

Walking [xorm v1.3.11
sync.go:250-266](https://gitea.com/xorm/xorm/src/tag/v1.3.11/sync.go#L250-L266):

- `IndexType` indices skip the drop when `IgnoreIndices ||
IgnoreDropIndices` — already covered.
- `UniqueType` indices skip the drop only when `IgnoreConstrains` —
**not** set in #37275, so the existing `UNIQUE` on `token_hash` (and any
other uniques) would be dropped on upgrade.

Adding `IgnoreConstrains: true` matches v333's pattern and preserves the
existing unique constraints. Spotted by @wxiaoguang in
https://github.com/go-gitea/gitea/pull/37275#discussion_r3254168680.

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

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-17 16:06:32 +00:00
16189a68c4 refactor: move workflowpattern into modules/actions (#37717)
`act/workflowpattern` in runner is only consumed by Gitea and dead code
there. Move it to this repo. Use `modules/glob` for glob pattern match.

---------

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-05-16 09:42:11 +00:00
02be228ed6 ci: add zizmor to lint-actions (#37720)
Adds [zizmor](https://docs.zizmor.sh/) to `make lint-actions` with
`--min-confidence=medium`. Fixes the remaining findings:

- Pin floating-tag service images in `pull-db-tests.yml` to
`tag@sha256:digest`
- Move `github.ref` / `github.ref_name` (and surrounding secrets/step
outputs for consistency) out of `run:` into `env:`

---
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>
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-05-16 10:38:46 +02:00
b742fa7d6b chore(renovate): enable dockerfile manager (#37719)
Enables Renovate's `dockerfile` manager so the base images in
`Dockerfile` and `Dockerfile.rootless`
(`docker.io/library/golang:1.26-alpine3.23`,
`docker.io/library/alpine:3.23`) get tracked alongside the other
dependencies. Updates are grouped under "docker dependencies" and follow
the existing weekly schedule.

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

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-16 06:40:05 +00:00
ffd5e0698b docs(agents): update AGENTS.md (#37684)
Add two rules to `AGENTS.md` for recurring issues.

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-05-13 08:27:22 +02:00
79f7062d9e fix(actions): run TransferLogs on UpdateLog{Rows:[], NoMore:true} (#37631)
`UpdateLog` short-circuits on `len(Rows)==0` before honoring `NoMore`,
so a final empty `UpdateLog{NoMore:true}` never runs `TransferLogs`. The
task's `dbfs_data` rows are then never moved to log storage and never
deleted.

Fix: let `NoMore=true` with no new rows fall through to `TransferLogs`.
Bail when the runner has outrun the server (`Index > ack`) even with
`NoMore`, since archiving a log with a gap is worse than retrying.
Always call `WriteLogs` so `offset==0` bootstraps an empty DBFS file in
the no-output case (otherwise `TransferLogs` would fail at `dbfs.Open`).

Fixes: https://github.com/go-gitea/gitea/issues/37623
Ref: https://gitea.com/gitea/runner/pulls/952
Ref: https://gitea.com/gitea/runner/pulls/950
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-05-13 05:18:07 +00:00
b29af98a36 ci(renovate): update Go import paths on major bumps (#37641)
Enable `gomodUpdateImportPaths` so Renovate rewrites import paths (e.g.
`foo/v2` → `foo/v3`) across the repo when bumping Go modules across
major versions.

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

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-11 06:35:48 +00:00
5dc9d621fd refactor: replace Fomantic search module with first-party code (#37443)
- Replace fomantic `search` code with minimal first-party code
- Added a small fix to vertically align search box and search button
- Manually tested all search forms.
- Add `errorName` helper, similar to `errorMessage`.

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-05-11 05:25:26 +00:00
a61598884f feat(editor): broaden language detection in web code editor (#37619)
Use
https://github.com/github-linguist/linguist/blob/main/lib/linguist/languages.yml
to substantially improve syntax higlighting in Codemirror. File is
generated on-demand only.

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-05-10 04:51:46 +00:00
ce089f498b fix: improve actions status icons and texts (#37206)
Action runs, jobs and steps have 8 statuses but the UI only showed 5
(from the commit status api) for the latter two. Align all 8 to GitHub
as closely as possible:

  - waiting — `octicon-circle` (hollow circle), gray
  - blocked — `octicon-blocked` (slashed circle), yellow
  - running — `gitea-running` (rotating spinner), yellow
  - cancelled — `octicon-stop` (gray), was `octicon-x` (red)

Descriptions also aligned with GitHub:

  - "Has started running" → "In progress"
  - "Has been cancelled" → "Cancelled after {dur}"
  - "Has been skipped" → "Skipped"

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

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
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: Nicolas <bircni@icloud.com>
2026-05-09 15:24:08 +08:00
a5d81d9ce2 perf: replace goheader linter with custom check (#37599)
Replace the [slow `goheader` linter](https://github.com/denis-tingaikin/go-header/issues/70) with a
custom check.

Local go lint time is down from 247s to 32s. 6 new files that were
previously undetected because of `//go:build ignore` are fixed. The exit
code of the make target preserves the golangci-lint exit code, if
present.

Also refactors and consolidates the linting targets.

Signed-off-by: silverwind <me@silverwind.io>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-05-08 23:39:35 +02:00
479bcdb503 fix(actions): fix blank lines after ::endgroup:: (#37597)
`endLogGroup` was incorrectly appending empty `<div>`s, producing a
useless blank line after every group. Before and after:

<img width="250" alt="Screenshot 2026-05-07 at 22 40 40"
src="https://github.com/user-attachments/assets/8baf0fd0-99c8-4648-bf3f-edc6c4b197ec"
/> <img width="250" alt="Screenshot 2026-05-07 at 22 37 12"
src="https://github.com/user-attachments/assets/c45f28ae-1bbf-4b25-9d7b-281c19421f63"
/>

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-05-08 17:11:01 +00:00
29676adfd3 fix: treat email addresses case-insensitively (#37600)
Fixes #36184 and three more discovered cases.

---
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>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-08 15:14:33 +00:00
82d40296b0 chore(deps): bump tool deps and pin, update golangci-lint (#37574)
1. Pin all makefile go deps to exact version, renovate will bump them in the future
2. Bump all deps and golangci-lint and fix all new issues, most are from modernize

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-05-08 04:49:34 +00:00
b4085c7e3c build: update pnpm to v11 (#37591)
Update to https://github.com/pnpm/pnpm/releases/tag/v11.0.0

- move all pnpm settings to `pnpm-workspace.yaml`, pnpm v11 only reads
that file
- drop redundant or no-op settings
- disable `strictDepBuilds` to avoid having to manually specify deps
with build scripts, this is equivalent to v10 where it will not execute
and warn.
- add workarounds for https://github.com/SukkaW/nolyfill/issues/119
- remove dead eslintrc entry

---
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>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-08 04:17:20 +00:00
bba748e8b5 chore(renovate): detect Makefile tools, enable go bumps (#37595)
- fix detection of Makefile tools and group them separately
- Enable `go.mod` `go` directive bumps, schedule it at any time and
exempt it from the release-age delay

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-05-08 03:44:10 +00:00
6a509da96e refactor: lint bare fill/stroke colors, add vars for git graph color series (#37543)
- make `scale-unlimited/declaration-strict-value` cover fill and stroke
- add new color vars for color series in gitgraph
- move most rule disablement to per-line
- remove dead highlight colors since https://github.com/go-gitea/gitea/pull/34948
- move stylelint config to ts now that the linked issue is fixed

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-05-07 21:18:23 +00:00
e9f82b0ee3 ci: allow chore type in PR title lint (#37575)
Follow-up to #37498, adds `chore` to the allowed PR title types so the
set matches the standard
[`@commitlint/config-conventional`](https://github.com/conventional-changelog/commitlint/tree/868983c18efcb6fa835197cc9b2275545e528ad4/%40commitlint/config-conventional#type-enum).

---
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>
2026-05-07 17:18:10 +00:00
3e69d6adbe refactor: remove obsolete export (#37579)
Leftover from
https://github.com/go-gitea/gitea/commit/2644bb8490e7d6e3be5c4548b02c76eacd196569,
not needed because module no longer does top-level-await.

Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-07 17:12:52 +00:00
ebc058f682 ci: increase renovate frequency and fix RENOVATE_ALLOWED_POST_UPGRADE_COMMANDS (#37565)
1. Sync `RENOVATE_ALLOWED_POST_UPGRADE_COMMANDS` with the recent
`renovate.json5` change (#37537) — the npm group now runs `make svg
nolyfill`, but the workflow allowlist still only matched `^make
(tidy|svg)$`, so the post-upgrade task was being rejected.
2. Bump the cron from daily at 01:00 UTC to hourly at :23, matching the
cadence of Mend's hosted Renovate App. Hourly gives sub-hour
responsiveness to dependency-dashboard checkbox interactions and
PR-close reactions; the `:23` offset avoids the GHA scheduler congestion
at multiples of 15.

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-05-06 18:37:09 +02:00
97211bf0c5 refactor(deps): migrate from nektos/act fork to gitea/runner (#37557)
Migrate to https://gitea.com/gitea/runner/releases/tag/v1.0.0 which
includes the `act` package directory previously referenced by
`nektos/act`.

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-06 05:54:31 +02:00
762154cbd7 fix: Fix nolyfill for renovate (#37537)
Run `nolyfill` as a renovate post-upgrade step alongside `make svg`, so
npm dep bumps keep `pnpm.overrides` in sync.

---
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>
2026-05-04 21:39:20 +00:00
198ef500d2 Don't unblock run-level-concurrency-blocked runs in the resolver (#37461)
Fixes #37446.

The job-status resolver in `checkJobsOfCurrentRunAttempt` only
considered `needs` and job-level concurrency when transitioning jobs out
of `Blocked`. When something drove the resolver against a run blocked
solely by workflow-level concurrency — for example, a sibling run in the
same group entering the queue and triggering `EmitJobsIfReadyByRun` —
the run's job silently became `Waiting` while another run still held the
concurrency group, and the runner could pick it up, defeating the
concurrency guarantee.

The fix bails out of the resolver when the run's latest attempt is still
blocked by run-level concurrency. `checkRunConcurrency` re-evaluates
when the holding run finishes.

Covered by a unit test
(`Test_checkJobsOfCurrentRunAttempt_RunLevelConcurrencyKeepsJobsBlocked`
in `services/actions/job_emitter_test.go`) that sets up a Running holder
attempt and a Blocked sibling attempt in the same concurrency group
directly in the DB, calls `checkJobsOfCurrentRunAttempt`, and asserts
the blocked job stays `Blocked`. Fails on master, passes with the fix.

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

---------

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-05-04 11:10:42 +00:00
abcfa53040 Replace olivere/elastic with REST API client, add OpenSearch support (#37411)
Drops `github.com/olivere/elastic/v7` (unmaintained) and replaces it
with a small in-house wrapper that speaks the Elasticsearch REST API
directly via `net/http`. The subset used by Gitea (`_cluster/health`,
`_bulk`, `_doc`, `_delete_by_query`, `_refresh`, `_search`, `HEAD`/`PUT`
index) is stable across the targeted servers, so no client library is
needed.

**Targets tested**
- Elasticsearch 7, 8, 9
- OpenSearch 1, 2, 3

**Why not `go-elasticsearch`?**
The official client enforces an `X-Elastic-Product` server-identity
check that OpenSearch deliberately fails, which would force shipping a
transport shim to defeat it. Going direct over `net/http` removes that
fight along with several MB of transitive deps (`elastic-transport-go`,
`go.opentelemetry.io/otel{,/metric,/trace}`, `auto/sdk`, `easyjson`,
`intern`, `logr`, `stdr`).

Replaces: #30755
Fixes: https://github.com/go-gitea/gitea/issues/30752

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

---------

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-05-02 00:12:54 +02:00
31cee60cc7 Improve code editor text selection and clean up lint enablement (#37474)
1. Make the content area stretch the box, enabling text selection to
start over empty space.
2. Disable linter for markdown, it can never produce lint errors, this
hides the unnecessary lint gutter on markdown files.
3. Verified all languages linter enablement, all accurate.
4. Refactor `getLinterExtension` to not rely on file extensions.
5. Include jsonc/json5 extensions in regex.

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

---------

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-01 17:41:31 +00:00
d57d06335d Refactor integration tests infrastructure (#37462)
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-29 16:37:38 +00:00
6da8027446 Fix inconsistent disabled styling on logged-out repo header buttons (#37406)
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>
2026-04-27 17:33:10 +00:00
331450b17a Add API endpoint to reply to pull request review comments (#36683)
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>
2026-04-27 08:45:59 +00:00
99cd4f6b22 Integrate renovate bot for all dependency updates (#37050)
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>
2026-04-26 14:25:22 +00:00
ebf30ac4db Optimize CI caches (#37387)
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>
2026-04-26 10:25:35 +00:00
f2a7f6c999 Update AGENTS.md (#37420)
`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>
2026-04-26 12:00:48 +02:00
24b60f8ff9 Fix color regressions, add priority color (#37417)
- 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>
2026-04-25 19:08:10 +02:00
0277e3ebaa Stabilize e2e logout propagation test (#37403)
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>
2026-04-24 15:37:01 +00:00
de99b1fbbf Improve AGENTS.md (#37382)
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>
2026-04-24 09:49:20 +00:00
58a1330078 Remove dead CSS (#37376)
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>
2026-04-24 09:45:16 +00:00
aa0707c679 Add pr-review e2e test and speed up e2e tests (#37345)
- add pr-review e2e test
- speed up most tests by logging in via POST to avoid the login form,
login form is still exercised in a dedicated test
- speed up most tests be removing post-test cleanup, unnecessary because
each repo is created with a unique name
- misc parallelization and api call reduction
- total suite runtime is about the same as before

---------

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-24 08:19:59 +00:00
3816210c05 Drop Fomantic tab, checkbox and form patches (#37377)
Clean up the fomantic helpers that nothing inside fomantic depends on.
Manually tested all functionality.

---------

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-24 16:02:37 +08:00
7947851e57 Remove external service dependencies in migration tests (#36866)
Fix #36859

Replace live third-party API calls in migration tests with a
fixture-based HTTP mock server. Fixtures are committed so tests run
offline by default; live recording is gated per service on an API-token
env var.

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-23 15:18:53 +00:00
12d83cbfa3 Extend issue context popup beyond markdown content (#36908)
Extend the issue context popup beyond markdown. Any link rendered with
the `ref-issue` class now gets the popup, which covers commit titles and
issue titles everywhere they appear (repo home, commits list, blame,
branches, graph, PR commits, issue/PR pages, compare, …). For surfaces
that synthesize links without markdown autolinking (dashboard activity
feed, pulse page, commit merged-PR line), opt in by adding
`data-ref-issue-container` on a parent (or `ref-issue` on the link).

- Use `html_url` from the backend payload instead of synthesizing links
client-side
- Fetch outside the component, stateless, with a per-URL cache
- Small hover delay so passing over a link doesn't fire a request
- Drop the loading state (shifted layout)
- Make both links in the tooltip work; prevent nested tooltips
- Fix feed title `<a>` width so the tooltip only shows on link hover

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-04-23 13:58:31 +00:00
c489db447d Fail vite build on rolldown warnings via NODE_ENV=test (#37270)
Fail the vite build on any rolldown warnings when `NODE_ENV=test` is
set. This gate is set on the CI `make frontend` steps (compliance and
e2e workflows) and on the local `make test-e2e` target, so warnings fail
the build both in CI and when running e2e tests locally. Regular `make
frontend` / production builds are unaffected.

Example output:

```
[plugin test-warning-injector] first synthetic warning
[plugin test-warning-injector] second synthetic warning
transforming...✗ Build failed in 14ms
error during build:
Build failed with 1 error:

[plugin fail-on-warnings]
Error: 2 warnings present
    at PluginContextImpl.buildEnd (vite.config.ts:50:13)
    ...
```

---
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>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-04-21 18:11:07 +00:00
caff989f34 Fix relative-time error and improve global error handler (#37241)
1. Fixes: #37239
2. Enhance global error message to show stack trace on click

---------

Signed-off-by: silverwind <me@silverwind.io>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-21 07:53:19 +00:00
f94b476c45 Fix actions concurrency groups cross-branch leak (#37311)
## 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.

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-21 02:25:36 +00:00
b6ea666fd4 Revert "Add WebKit to e2e test matrix (#37298)" (#37315)
Reverts: #37298
Ref:
https://github.com/go-gitea/gitea/actions/runs/24661464168/job/72108324223?pr=37312

WebKit on Linux has a long history of flakiness in Playwright CI runs,
and the exact "WebKit encountered an internal error" class of failures
has been reported repeatedly and closed without a real fix (typically
stale/no-repro, or worked around by retries):

- https://github.com/microsoft/playwright/issues/34450
- https://github.com/microsoft/playwright/issues/35773
- https://github.com/microsoft/playwright/issues/35870
- https://github.com/microsoft/playwright/issues/35293
- https://github.com/microsoft/playwright/issues/38838

Keeping chromium and firefox in the e2e matrix.

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

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-20 19:49:38 +00:00
1d25bb22f4 Move heatmap to first-party code (#37262)
Replaces `@silverwind/vue3-calendar-heatmap` with an inlined SVG
implementation. Renders pixel-identically to `main`, drops the
`onMounted` legend viewBox workaround, and uses tippy's
`createSingleton` for the hover tooltip. Adds an e2e test for tooltip
display.

This is a prereq for migrating tippy.js to
[floating-ui](https://github.com/floating-ui/floating-ui) to avoid
having two tooltip libs active.

<img width="861" height="168" alt="image"
src="https://github.com/user-attachments/assets/99343cf6-6e09-42c7-a80d-63dbf33cf56a"
/>


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

---------

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-04-20 20:15:45 +02:00
aba87285f0 Remove dead code identified by deadcode tool (#37271)
Ran [`deadcode`](https://pkg.go.dev/golang.org/x/tools/cmd/deadcode)
(`-test ./...`) to find functions, methods and error types unreachable
from any call path (including tests), and removed the truly-dead ones.

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-20 07:52:48 +00:00
f6960096f3 Enable strict TypeScript, add errorMessage helper (#37292)
Enable full TypeScript `strict` mode and fix issues discovered during
this refactor. Introduced a `errorMessage` helper function to cleanly
extract a error messages from the `unknown` type.

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (claude-opus-4-7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-20 07:22:05 +00:00
5a3d8d3224 Fix vite manifest update masking build errors (#37279)
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: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-20 07:10:46 +00:00
6f761219b2 Add WebKit to e2e test matrix (#37298)
Verified locally with 50 runs, averaging 9 seconds per local test suite
run. Total suite took 15s.

`--with-deps` is needed because webkit's dependencies are not
pre-installed on GHA runners (as opposed to firefox/chrome which are
preinstalled).

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

---------

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-04-19 19:09:43 +00:00
b31eef2828 Stabilize issue-project e2e test, increase timeout factor (#37297)
1. stabilize flaky e2e test from
https://github.com/go-gitea/gitea/commit/2f5b5a9e9c32e6042f1f06f1b112a795267d6955
2. increase ci timeout factor to 4 as 3 was not enough
3. add a `e2e` category to files-changed so e2e-test-only changes
trigger ci

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

---------

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-19 17:27:23 +00:00
0824610e39 Remove SubmitEvent polyfill (#37276)
Remove this obsolete polyfill as per
https://github.com/go-gitea/gitea/pull/37270#issuecomment-4273399551.

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-18 20:55:01 +02:00
98202110be Upgrade go-git to v5.18.0 (#37268)
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>
2026-04-18 08:49:40 +00:00
d5831b9385 Frontend iframe renderer framework: 3D models, OpenAPI (#37233)
Introduces a frontend external-render framework that runs renderer
plugins inside an `iframe` (loaded via `srcdoc` to keep the CSP
`sandbox` directive working without origin-related console noise), and
migrates the 3D viewer and OpenAPI/Swagger renderers onto it. PDF and
asciicast paths are refactored to share the same `data-render-name`
mechanism.

Adds e2e coverage for 3D, PDF, asciicast and OpenAPI render paths, plus
a regression for the `RefTypeNameSubURL` double-escape on non-ASCII
branch names.

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-04-17 22:30:17 +00:00
a9108ab6aa Replace custom Go formatter with golangci-lint fmt (#37194)
Use `golangci-lint fmt` to format code, replacing the previous custom
formatter tool. https://github.com/daixiang0/gci is used to order the
imports.

`make fmt` performs ~13% faster while consuming ~57% less cpu while
formatting for me.

`GOFUMPT_PACKAGE` is gone because it's using the builtin package from
golangci-lint.

Co-authored-by: Claude (claude-opus-4-6) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-17 17:45:22 +00:00
dc974715e9 Fix commit title rendering in action run and blame (#37243)
Fixes #37242

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-17 09:18:33 +00:00
ba9258c478 Indicate form field readonly via background (#37175)
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.

Fixes: #37174
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
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-04-11 14:38:56 +00:00
d913fae237 Remove dead CSS rules (#37173)
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: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-11 10:41:56 +00:00
09c2677b21 Fix flaky TestCatFileBatch/QueryTerminated test (#37159)
`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
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-10 17:34:12 +00:00
681c4074e5 Add missing //nolint:depguard (#37162)
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: Claude (Opus 4.6) <noreply@anthropic.com>
2026-04-10 10:39:28 +00:00
04fb6f1c0b Replace rollup-plugin-license with rolldown-license-plugin (#37130)
Replace `rollup-plugin-license` and `wrap-ansi` with
[`rolldown-license-plugin`](https://github.com/silverwind/rolldown-license-plugin),
a zero-dependency plugin with async parallel I/O and built-in word
wrapping.

- Removes `rollup-plugin-license` (pulls in `lodash`, `moment`) and
`wrap-ansi` from the dependency tree
- License build time reduced by ~40% (370ms vs 640ms)
- Added e2e test for `licenses.txt`

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-04-09 09:31:05 +00:00
0914a44a9b Clean up and improve non-gitea js error filter (#37148)
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

Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
2026-04-09 08:36:08 +00:00
d600968aaf Bump min go version to 1.26.2 (#37139)
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: Claude (Opus 4.6) <noreply@anthropic.com>
2026-04-08 17:56:06 +02:00
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
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
silverwindandGitHub 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
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
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
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
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
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
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
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
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
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
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
silverwindandGitHub 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