Replace the fomantic search.css (520 lines) and modal.css (698 lines)
with minimal first-party modules containing only the rules actually
used. Hardcoded colors are replaced with theme variables, and the
base.css overrides are merged directly into the new modules.
With this change, all original Fomantic CSS is now gone.
**search.css**: 520 → 85 lines
**modal.css**: 698 → 329 lines
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Replace the `@github/relative-time-element` npm dependency with a
vendored, simplified implementation.
- Support 24h format rendering [PR
329](https://github.com/github/relative-time-element/pull/329)
- Enable `::selection` styling in Firefox [PR
341](https://github.com/github/relative-time-element/pull/341)
- Remove timezone from tooltips (It's always local timezone)
- Clean up previous `title` workaround in tippy
- Remove unused features
- Use native `Intl.DurationFormat` with fallback for older browsers,
remove dead polyfill
- Add MIT license header to vendored file
- Add unit tests
- Add dedicated devtest page for all component variants
---------
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude claude-opus-4-6 20250630 <noreply@anthropic.com>
Add `SetDefaultValues()` call to ensure PageSize is bounded, preventing
potential excessive memory allocation from unbounded pagination
parameters.
Fixes CodeQL alert
[#188](https://github.com/go-gitea/gitea/security/code-scanning/188).
All other 49 open alerts were false-positives and are dismissed with
appropriate comments.
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Add `--concurrency 2` to all ESLint invocations in the Makefile. ESLint
v9 supports multi-threaded linting via worker threads.
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Cache the final rendered `template.HTML` output for SVG icons that use
non-default size or class parameters using `sync.Map`.
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
1. Copy dependency manifests before the full source copy so that
dependency installation gets its own cached layer. When only source code
changes, the dependency layers are reused.
2. Remove the `GOPROXY=direct` override which was bypassing the Go
module proxy, causing build failures when git servers are unreachable.
The Go default (`https://proxy.golang.org,direct`) is now used instead.
---------
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
The `PATCH /api/v1/repos/{owner}/{repo}` endpoint silently ignores pull
request config fields (like `default_delete_branch_after_merge`,
`allow_squash_merge`, etc.) unless `has_pull_requests: true` is also
included in the request body. This is because the entire PR unit config
block was gated behind `if opts.HasPullRequests != nil`.
This PR restructures the logic so that PR config options are applied
whenever the pull request unit already exists on the repo, without
requiring `has_pull_requests` to be explicitly set. A new unit is only
created when `has_pull_requests: true` is explicitly sent.
Fixes https://github.com/go-gitea/gitea/issues/36466
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
Use flex-container layout and wrap the actions runs list with `ui top
attached header` and `ui attached segment` to add a background. Display
the total workflow run count in the header.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Enable Docker BuildKit layer caching for the dry-run and nightly
container build workflows using GHCR registry cache.
- **Dry-run** (`pull-docker-dryrun.yml`): adds `cache-from`, read-only,
PRs can't write cache
- **Nightly** (`release-nightly.yml`): adds `cache-from` and `cache-to`
to both read and write cach
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Moved fomantic dropdown css to custom module, tested on the dropdown
devtest page, it renders exactly the same as before while using roughly
50% less CSS. The clean up was very conservative, likely more can be
done in the future.
Also, this fixes a bug present on main branch where dropdown border has
incorrect color on hover.
---------
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Lazy-load 3 Vue components that are safe to defer (no pop-in effects).
This reduces `index-domready` from 515 KiB to 502 KiB (-2.5%).
The old `vue3-calendar-heatmap` vendor chunk (264 KiB) that previously
loaded on every page is eliminated entirely — it was mostly duplicate
`tippy.js` and `vue` copies that webpack had split out. The actual
heatmap library is only ~12 KiB minified, now inlined into the
`ActivityHeatmap` async chunk.
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
The integration tests leave some log files around and they were
triggering the spellchecker:
```
$ make lint-spell
tests/integration/gitea-integration-sqlite/log/gitea.log:316:69: "addres" is a misspelling of "address"
tests/integration/gitea-integration-sqlite/log/gitea.log:794:69: "addres" is a misspelling of "address"
tests/integration/gitea-integration-sqlite/log/gitea.log:1248:69: "addres" is a misspelling of "address"
tests/integration/gitea-integration-sqlite/log/gitea.log:2070:69: "addres" is a misspelling of "address"
```
With this change, untracked and ignored files will no longer be
spellchecked.
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
- Update golangci-lint v2.9.0 → v2.10.1, misspell v0.7.0 → v0.8.0,
actionlint v1.7.10 → v1.7.11
- Fix 20 new QF1012 staticcheck findings by using `fmt.Fprintf` instead
of `WriteString(fmt.Sprintf(...))`
- Fix SA1019: replace deprecated `ecdsa.PublicKey` field access with
`PublicKey.Bytes()` for JWK encoding, with SEC 1 validation and curve
derived from signing algorithm
- Add unit test for `ToJWK()` covering P-256, P-384, and P-521 curves,
also verifying correct coordinate padding per RFC 7518
- Remove dead staticcheck linter exclusion for "argument x is
overwritten before first use"
## Test plan
- [x] `make lint-go` passes with 0 issues
- [x] `go test ./services/oauth2_provider/ -run
TestECDSASigningKeyToJWK` passes for all curves
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Replace the external easymde.min.css import with an inlined and
lazy-loaded CSS file that uses proper theme variables for border colors.
All EasyMDE/CodeMirror rules are scoped under `.EasyMDEContainer`,
removing the need for !important overrides.
- Fixes easymde borders, these were broken since a while now
- Scope all easymde styles to .EasyMDEContainer
- Inline easymde.min.css and codemirror.css into web_src/css/easymde.css
- Lazy-load the CSS alongside the JS in switchToEasyMDE()
- Fix .editor-toolbar and .CodeMirror border colors to use
--color-input-border matching textarea inputs
- Remove unused gutter, line number, and other unconfigured styles
- Move .editor-loading to codeeditor.css where it belongs
<img width="891" height="518" alt="image"
src="https://github.com/user-attachments/assets/87495de5-7872-4645-90e7-96fe0f782f02"
/>
---------
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
## Summary
- Move `cors.X_FRAME_OPTIONS` to `security.X_FRAME_OPTIONS` (old
location still works with a deprecation warning)
- Support `"unset"` as a special value to remove the `X-Frame-Options`
header entirely
- Remove `X-Frame-Options` header from API responses (only set for
web/HTML responses)
## Migration
If you had customized `cors.X_FRAME_OPTIONS`, move it to the
`[security]` section. The old location is deprecated and will be removed
in a future release.
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
- Replace the e2e tests initialization with a simple bash script,
removing the previous Go harness.
- `make test-e2e` is the single entry point. It always starts a fully
isolated ephemeral Gitea instance with its own temp directory, SQLite
database, and config — no interference with the developer's running
instance.
- A separate `gitea-e2e` binary is built via `EXECUTABLE_E2E` using
`TEST_TAGS` (auto-includes sqlite with `CGO_ENABLED=1`), keeping the
developer's regular `gitea` binary untouched.
- No more split into database-specific e2e tests. Test timeouts are
strict, can be relaxed later if needed.
- Simplified and streamlined the playwright config and test files.
- Remove all output generation of playwright and all references to
visual testing.
- Tests run on Chrome locally, Chrome + Firefox on CI.
- Simplified CI workflow — visible separate steps for frontend, backend,
and test execution.
- All exported env vars use `GITEA_TEST_E2E_*` prefix.
- Use `GITEA_TEST_E2E_FLAGS` to pass flags to playwright, e.g.
`GITEA_TEST_E2E_FLAGS="--ui" make test-e2e` for UI mode or
`GITEA_TEST_E2E_FLAGS="--headed" make test-e2e` for headed mode.
- Use `GITEA_TEST_E2E_DEBUG=1 make test-e2e` to show Gitea server
output.
---------
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This is the result of a full-repo review to look for `style` attributes
that can be replaced with tailwind or other methods. I will manually
validate later.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
[`colord`](https://github.com/omgovich/colord) is significantly smaller
than [`tinycolor2`](https://github.com/bgrins/TinyColor) (~4KB vs ~29KB
minified) and ships its own TypeScript types, removing the need for
`@types/tinycolor2`.
Behaviour is exactly the same for our use cases. By using `.alpha(1)` we
force the function to always output 6-digit hex format (it would output
8-digit for non-opaque colors).
---------
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Change `security-check` not break the build which is a major
inconvenience as it breaks CI on all PRs.
https://github.com/go-gitea/gitea/security/dependabot already provides a
clean overview of outstanding security issues in dependencies and I'm
using it all the time to find and update vulnerable dependencies.
This simplifies the Makefile by removing the whole-file wrapping that
creates a tempdir introduced by
https://github.com/go-gitea/gitea/pull/11126. REPO_TEST_DIR is removed
as well.
Also clean up a lot of legacy code: unnecessary XSS test, incorrect test
env init, unused "_old_uid" hack, etc
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Fixes: https://github.com/go-gitea/gitea/issues/36612
This new setting controls which workflow directories are searched. The
default value matches the previous hardcoded behaviour.
This allows users for example to exclude `.github/workflows` from being
picked up by Actions in mirrored repositories by setting `WORKFLOW_DIRS
= .gitea/workflows`.
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Rewrite `build/generate-go-licenses.go` to use `go list -m -json all`
and read license files directly from the Go module cache instead of
relying on the buggy `google/go-licenses` tool.
This removes the need for CGO, GOOS=linux, and the intermediate temp
directory, while being like 100 times faster than before:
```
$ rm assets/go-licenses.json && time make assets/go-licenses.json
go run build/generate-go-licenses.go assets/go-licenses.json
make assets/go-licenses.json 0.21s user 0.22s system 173% cpu 0.247 total
---------
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Clean up linter configs, removing redundant rules or dead disables. One
new rule enabled, no violations. Many revive rules had same or better
rules in staticcheck or govet.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Giteabot <teabot@gitea.io>
Fixes: https://github.com/go-gitea/gitea/issues/36543
When running `make watch`, the backend may start before webpack finishes
building CSS theme files. Since themes were loaded once via sync.Once,
they would never reload, breaking the theme selector and showing a
persistent error on the admin page.
In dev mode, themes are now reloaded from disk on each access so they
become available as soon as webpack finishes. Production behavior is
unchanged where themes are loaded once and cached via sync.Once.
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Fixes: https://github.com/go-gitea/gitea/issues/21045
- Move heatmap data loading from synchronous server-side rendering to
async client-side fetch via dedicated JSON endpoints
- Dashboard and user profile pages no longer block on the expensive
heatmap DB query during HTML generation
- Use compact `[[timestamp,count]]` JSON format instead of
`[{"timestamp":N,"contributions":N}]` to reduce payload size
- Public API (`/api/v1/users/{username}/heatmap`) remains unchanged
- Heatmap rendering is unchanged, still shows a spinner as before, which
will now spin a litte bit longer.
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
## Summary
- Split Dockerfile and Dockerfile.rootless into a two-stage build:
frontend assets are built on the native platform (`$BUILDPLATFORM`) then
copied to the per-architecture backend build stage
- This avoids running esbuild/webpack under QEMU emulation which causes
SIGILL (Invalid machine instruction) on arm64/riscv64
- Frontend assets (JS/CSS/fonts) are platform-independent so they only
need to be built once
- The `build-env` stage no longer needs `nodejs`/`pnpm` since it only
builds the Go backend
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: TheFox0x7 <thefox0x7@gmail.com>
Fixes: https://github.com/go-gitea/gitea/issues/36152
Enable the `nilnil` linter while adding `//nolint` comments to existing
violations. This will ensure no new issues enter the code base while we
can fix existing issues gradually.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Fixes: go-gitea/gitea#36637. `linguist-detectable` must be able to
override the config classification.
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
The default configuration of `failure-only` added in
https://github.com/go-gitea/gitea/pull/34982 included sending mails for
cancelled runs which is not what one would expect from a option named
like that because a cancelled run is not a failure.
This change makes it omit mails for cancelled runs:
| Run Status | `failure-only` before | `failure-only` after |
|------------|-----------------------|----------------------|
| Success | no | no |
| Failure | mail | mail |
| Cancelled | mail | no |
The first commit in this PR is the fix, and there are a few more
refactor commits afterwards.
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Persist the two boolean settings in the actions log into `localStorage`
so that they are remembered across page reloads.
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Adds three `<select>` controls on top right for indent style, indent
size, and line wrap to the code editor (`_edit`), diff patch editor
(`_diffpatch`) and git hook editor (`/settings/hooks/git/pre-receive`).
The git hooks editor is restyled to wrap the content in a box. Also
included is a bugfix for the git hooks editor where monaco was not
initialized correctly.
---------
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
We've been cutting down on the "striped" tables (where rows are using
alternate row background colors). This completely removes them as I
think such a design looks outdated.
The removal of selectors starting with `.ui[class*="very
basic"].table:not(.striped)` is needed because of a specificity issue in
the CSS where table cells would otherwise render with incorrect padding.
Example of one affected table:
<img width="1027" height="224" alt="image"
src="https://github.com/user-attachments/assets/2f3006ca-99a1-4655-afdb-b7cd9e5f19c7"
/>
Some minor refactors, disable one obsolete lint rule, fix another. The
tribute type issue is not fully fixed and I'm pretty sure it must be an
error in their types.
Fixes: https://github.com/go-gitea/gitea/issues/34769
This allows the user to opt-in to using `elk` layouts using either YAML
frontmatter or `%%{ init` directives inside the markup code block. The
default layout is not changed.
---------
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
- Update all JS deps
- Enable a few more stylelint stylistic rules and fix issues
- Remove knip, it raised another false-positive, this tool is not worth
it when you have to babysit it like that
- Exclude @eslint/json from updating as it requires unreleased eslint 10
([ref](https://github.com/eslint/json/issues/207))
- Update labeler config for new eslint filenames
- Adjust `make help` output
- Add type checking in `stylelint.config.ts`
`smtp.mydomain.test` is a real domain that resolves to something and
which is being connected to while running tests. Instead, use
[.test](https://en.wikipedia.org/wiki/.test) which is guaranteed to
never be registered on the internet, so all connections to it will fail
with NXDOMAIN dns error.
This adds [knip](https://github.com/webpro-nl/knip), a tool to find
unused files, dependencies and exports in JS. Fixed all discovered
issues.
1. knip apparently has some issue resolving imports from `d.ts` to `.ts`
so I worked around it by moving the two affected types to where they are
used.
2. I don't know why `modules/fomantic/dropdown.ts` had a new typescript
error, but I fixed it.
3. Use named export for `EsbuildPlugin`, I think this was added
recently.
Updates all dependencies in `Makefile`. The go fix was done
automatically, I just altered the variable name.
---------
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
1. Upgrade to [jQuery
4.0](https://blog.jquery.com/2026/01/17/jquery-4-0-0/). Two of the
removed APIs are in use by fomantic, but there are [polyfills
present](https://github.com/go-gitea/gitea/blob/a3a3e581aa387969ce6410ab54c4775e9023ec40/web_src/fomantic/build/components/dropdown.js#L15-L17)
so it continues to work.
2. Remove manual naming of webpack chunks. I was running into below
webpack error and I see no reason for this manual chunk naming which is
prone to naming collisions. Also, the webpack build now shows all output
assets. This change will result in longer asset filenames, but webpack
should now be able to guarentee that the names are without collisions.
````
ERROR in SplitChunksPlugin
Cache group "defaultVendors" conflicts with existing chunk.
Both have the same name "--------" and existing chunk is not a parent of
the selected modules.
Use a different name for the cache group or make sure that the existing
chunk is a parent (e. g. via dependOn).
HINT: You can omit "name" to automatically create a name.
BREAKING CHANGE: webpack < 5 used to allow to use an entrypoint as
splitChunk. This is no longer allowed when the entrypoint is not a
parent of the selected modules.
Remove this entrypoint and add modules to cache group's 'test' instead.
If you need modules to be evaluated on startup, add them to the existing
entrypoints (make them arrays). See migration guide of more info.
3. Fix test issue related to `p > div` which is invalid as per HTML spec
because `div` is not [phrasing
content](https://html.spec.whatwg.org/multipage/dom.html#phrasing-content-2)
and therefor can not be a descendant of `p`. This is related to
https://github.com/capricorn86/happy-dom/pull/2007.
4. Add webpack globals
5. Remove obsolete docs glob
6. fix security issue for `seroval` package
7. disable [vitest isolate](https://vitest.dev/config/isolate.html) for
30% faster JS tests, which are all pure.
1. Remove those checks for the sake of build performance and because go
and node will fail anyways if their versions are incorrect.
3. Support pre-release Node version for determining NODE_VARS.
2. Update to the chinese READMEs to mention `pnpm` which is already
present in english README.
---------
Co-authored-by: techknowlogick <techknowlogick@gitea.com>
Co-authored-by: Giteabot <teabot@gitea.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
- Update JS and PY dependencies
- Workaround https://github.com/stylelint/stylelint/issues/8893 by
moving the stylint config file to JS
- Regenerate SVGs
- Bump to python 3.14 in devcontainer and actions
- Verified `@github/text-expander-element`
- Removed obsolete type stub
`import.meta.env` is supported in both vitest and webpack [as of
recent](https://github.com/webpack/webpack/pull/19996), so replace all
previous use of `process.env` with it. Current usage is limited to test
files, I've also verified it works in actual frontend code.
`webpack/module` is added to typescript types which includes the
definition for `import.meta.env`. I've also made the eslint globals more
precise. Finally, `__webpack_public_path__` is removed from our type
definitions because `webpack/module` also provides it.
- reduce file name font size from 15px to 14px
- fix labels and buttons being cut off when their size is constrained
- change labels from monospace to sans-serif font
- move diff stats to right and change them from sum of changes to +/-
- change filemode to label and change text to match other labels
---------
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
- Replace fomantic form CSS with custom module
- Moved code in `form.css` to `modules/form.css`, removed around 70% of
the previous module.
- Moved captcha styles previously in `form.css` to its own file.
There is probably more unused CSS, like form error state colors which to
my knowledge is not used anywhere, but I'm not sure about that one so I
kept it.
One notable change is the removal of `type` combinator here, which
lowers the selector specificity and I noticed one issue where selector
`.ui.search > .prompt` was winning, so I added a workaround for that
until the `search` module can be removed as well.
```css
.ui.form .fields.error .field input:not([type])
.ui.form .fields.error .field input[type="date"]
```
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
Fixes: https://github.com/go-gitea/gitea/issues/36216
Now `detectWebAuthnSupport` returns the error type and lets the caller
decide whether they call `webAuthnError` and show the error. It no
longer shows the error during page load when the user has not even
interacted with the feature.
The bug affects all users on HTTP, so I think a quick fix release for
this might be good.
Unbreak the release pipelines. The issue is caused by
https://gitlab.alpinelinux.org/alpine/aports/-/issues/17775 which
supposedly fixed in 3.23.2 and our build did use that version from what
I see, but maybe it's not fixed yet for `riscv`. We should try this
upgrade again later.
- Update all JS deps
- Tested affected `dependencies`
- Replace eslint `unstable_native_nodejs_ts_config` with optional `jiti`
dependency. This will be more compatible with editor integrations that
may not pass this flag.
- Enable additional eslint rules, no new issues
- Move `typescript` to `devDependencies` because `make frontend` works
without it