Fix regression from https://github.com/go-gitea/gitea/pull/38610
`perfect-debounce` allowed only one request in flight; `debounce` does
not, so a slow older request can resolve after a newer one and leave a
stale suggestion menu. Superseded requests are now aborted.
Fixes#38494
`DeleteRepositoryDirectly` left rows behind in seven registered tables
carrying a repo-scoped key: `action_variable`, `action_run_attempt`,
`action_tasks_version`, `renamed_branch`, `commit_status_summary`,
`commit_status_index` and `repo_transfer`. Repository IDs are `pk
autoincr` and never reissued, so the orphaned rows were unreachable, but
they accumulated forever (unbounded table growth, referential
inconsistency; not a security issue, see the issue discussion).
This adds all seven to the `deleteBeans` cascade, each placed next to
its sibling bean
(`CommitStatus`/`CommitStatusIndex`/`CommitStatusSummary`,
`Branch`/`RenamedBranch`, `Secret`/`ActionVariable`,
`ActionRun`/`ActionRunAttempt`). `repo_transfer` goes through the same
cascade rather than `DeleteRepositoryTransfer` so teardown stays one
mechanism; the existing reaper remains for the transfer flows.
The test inserts one row per previously-orphaned table (the fixture
files ask test cases to prepare their own data), deletes the repository,
and asserts each table is purged. Without the fix it fails on all seven
tables.
---------
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Signed-off-by: Luc <luuuc@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Adds `web_src/js/utils/func.ts` with `debounce` and `throttle`, dropping
`throttle-debounce` and `perfect-debounce` dependencies. Both were
needed before: the former has no promise-returning debounce, which
`TextExpander` requires, and the latter no `throttle`.
Signature follows lodash and es-toolkit: `(func, wait, {leading,
trailing})` plus `cancel`, so argument order flips at the migrated call
sites.
Adds a shared `[redis]` config section with a single `CONN_STR` key that
acts as the default Redis connection for every redis-backed subsystem
whose own connection string is empty: `[cache].HOST`,
`[session].PROVIDER_CONFIG`, `[queue].CONN_STR` and
`[global_lock].SERVICE_CONN_STR`.
Precedence: per-subsystem value > shared `[redis].CONN_STR` > existing
built-in defaults. Fully backward compatible: when `[redis]` is not set,
every code path behaves exactly as before.
Motivation: today an admin with one Redis instance has to repeat the
same connection string in up to four places (five once WebSocket lands).
Requested by @wxiaoguang in [this review
discussion](https://github.com/go-gitea/gitea/pull/36965#discussion_r3613306976)
as a prerequisite for #36965. This follows the pattern used by GitLab
and Mastodon: one global Redis definition, per-subsystem overrides fall
back to it.
Since #12385 all identical connection strings already share one client
via `nosql.Manager`, so pointing all subsystems at `[redis].CONN_STR`
naturally converges onto a single shared connection pool.
Covered by table-driven unit tests per subsystem (fallback applies, own
value wins, absent `[redis]` = unchanged behavior). A config-cheat-sheet
update for gitea/docs will follow once this is merged.
---------
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: TheFox0x7 <thefox0x7@gmail.com>
Users should know what they are doing, don't check everything,
especially for that we don't understand.
Fixes#23840
---------
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Derives topic labels from the PR title scope: `enhance(actions): ...`
gets `topic/gitea-actions`. Scopes map to `topic/<scope>`, with aliases
for names that differ (`oauth` → `topic/authentication`).
Labels stay in sync with the title, while ones applied by hand are left
alone. Scopes with no matching label on the repo are ignored, so no new
labels get created.
---------
Co-authored-by: Giteabot <teabot@gitea.io>
- avoid layout shift on actions log view page load
- retain header border when actions log is scrolled
- when copying step output, only copy with timestamp when timestamp
display is enabled (useful for example when step output is plain json
and copying with timestamp would make that json unparsable).
Remember the scroll offset when the merge box reloads. This is a crude
patch now, a proper fix would be a fully vue-rendered template with a
json payload from backend, which is much more work. Idiomorph was also
considered but deemed unviable.
Rename functions "util.Remove" (remove.go) to "util.RemoveWithRetry"
(file_retry.go) and add comments to clarify their behaviors, also add
tests.
Refactor callers: when no concurrent access (cmd cli, migration, app
init, test), use "os.Xxx" directly.
More details are in `modules/util/file_retry.go`
By the way, clean up OS (windows) detection, make FileURLToPath test
always run
## Problem
Jobs that call a reusable workflow (`uses:`) whose steps contain a `run:
|` block that **starts with blank lines** never start — the child jobs
stay `Blocked` forever, the run never finishes, and nothing is shown to
the user (the error is only logged at DEBUG). The reusable is valid YAML
and worked on 1.26.
## Root cause
`jobparser` serializes each expanded job via `SingleWorkflow.SetJob()`,
which uses `yaml.NewEncoder(...).SetIndent(2)`, but
`SingleWorkflow.Marshal()` used `yaml.Marshal`, whose default
indentation is **4**. Re-emitting a multi-line literal block scalar at a
different indentation makes the encoder write a wrong explicit
indentation indicator (`run: |4`) whose declared indent doesn't match
the actual content indent. The stored `workflow_payload` is then
unparseable:
```
run: |4
while ...
```
`jobparser.Parse` / `model.ReadWorkflow` (both go.yaml.in/yaml/v4)
reject it: `did not find expected key`. This surfaces in
`services/actions/job_emitter.go` `resolve()` →
`updateConcurrencyEvaluationForJobWithNeeds` → `ParseJob`, where the
error is swallowed at `log.Debug` and the job is left `Blocked`.
Encoding at indent 4 triggers the bad indicator; indent 2 does not —
matching the value already used by `SetJob`.
## Fix
Encode `SingleWorkflow.Marshal()` with `SetIndent(2)` so both encoders
agree and the serialized single workflow round-trips. Adds a regression
test (`Parse → Marshal → Parse` on a `run:` block with leading blank
lines) that fails before the change with `did not find expected key`.
---------
Signed-off-by: quasimodo <mohamed.belkamel@intelcia.com>
Co-authored-by: quasimodo <mohamed.belkamel@intelcia.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
Batch operations in the issues list (labels, milestones, projects,
assignees, etc.) could fail silently because `updateIssuesMeta` caught
and suppressed fetch errors internally. The caller would then proceed to
reload the page, clearing all selected issue checkboxes and giving the
impression that the operation had succeeded.
- Remove updateIssuesMeta and use our "fetch-action" framework to handle errors and page reloading
- Refactor backend code to use ctx.JSONError
---------
Signed-off-by: Sudhanshu Singh <sudhanshuwriterblc@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Adds browser-level coverage for the pull request merge box, which
currently had no tests. Exercises the full merge flow: open the PR,
expand the merge form, submit, and assert the merged state.
Extracted from https://github.com/go-gitea/gitea/pull/36759.
Also updated AGENTS.md with instructions for e2e tests.
---------
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Giteabot <teabot@gitea.io>
Corrects the Swagger/OpenAPI schemas for `/user/settings` and
`/topics/search` to match the actual JSON objects returned by the API.
Signed-off-by: Sudhanshu Singh <sudhanshuwriterblc@gmail.com>
## Changes
### 1. Handle reusable workflow expansion failures
If a reusable workflow caller job is invalid (e.g. uses a workflow with
syntax error), the job emitter should mark it as failed instead of
retrying.
Related:
https://github.com/go-gitea/gitea/pull/38518#discussion_r3608882095
### 2. No longer process concurrent run inline
**Before**: If a run(R1)'s status change unlocks another blocked run(R2)
via concurrency group, the job emitter will process R2 in R1's
transaction.
**Current**: No longer process R2 inline and emit the ID of R2 to let
another pass process it.
This PR adds support for file exclusion into `.gitea/template`
Docs: https://gitea.com/gitea/docs/pulls/470
### Usage
Template owners add a `.gitea/template` file to their template
repository:
```
# Files to include for variable expansion
*.go
text/*.txt
**/modules/*
# Files/directories to exclude from the generated repo
[exclude]
vendor/*
node_modules/
src/build/
```
Resolves#37202
---------
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Replace the single-use `uint8-to-base64` dependency with native
`btoa`/`atob`. The implementation is exactly identical.
---------
Signed-off-by: silverwind <me@silverwind.io>
Fix#38519
When `ENABLE_ACME` renew fails during startup (e.g. CA unreachable),
`ManageSync` currently aborts even if a still-valid certificate is on
disk, so HTTPS never comes up.
If `CacheManagedCertificate` finds a non-expired cert, log the manage
error, continue with that cert, and kick `ManageAsync` for background
retries. First-time install / expired-or-missing cert still fails
closed.
---------
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
- split the go version in `go.mod` into `go` and `toolchain` again
- add a workaround for https://github.com/golang/go/issues/75331 so
`make tidy` never drops `toolchain`
- configure renovate to bump `go` on minor releases and `toolchain` on
every release
- go and toolchain bumps land in a separate, fast-tracked PR, as both
carry security fixes
Replaces: https://github.com/go-gitea/gitea/pull/37846
The "Clear projects" action in the issue list batch operations doesn't
work. When users select multiple issues and choose to clear their
project assignments, the operation fails because:
1. The frontend sends a project ID of `0` to represent "no project"
2. The backend passes this invalid ID directly to
`IssueAssignOrRemoveProject` without filtering
3. The backend tries to look up a project with ID `0`, which doesn't
exist, resulting in a `project 0 not found` error
4. Selected issues remain assigned to their projects instead of being
removed
Fixes#38571
## Root Cause
The issue is a regression from the multi-project feature (#36784). The
frontend was using `data-element-id="0"` to represent "clear" actions,
but the backend doesn't filter out this invalid ID before validation.
## Solution
### Template Changes (`templates/repo/issue/filter_actions.tmpl`)
- Changed `data-element-id="0"` to `data-element-id=""` for the "Clear
projects" action (line 78)
- Changed `data-element-id="0"` to `data-element-id=""` for the "Clear
milestone" action (line 47)
- Removed the duplicate "no select" assignee option that was using
`data-element-id="0"` (lines 116-118)
### Frontend Logic Changes (`web_src/js/features/repo-issue-list.ts`)
- Made `elementId` a `const` instead of `let` (line 60) to prevent
mutations
- Removed the workaround code that was trying to handle
`data-element-id="0"` for assignees (lines 65-69)
- Updated comment from "for toggle" to "for label toggle" for clarity
(line 71)
---------
Signed-off-by: Sudhanshu Singh <sudhanshuwriterblc@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
by the way, remove some unnecessary "models" imports from model
migration package, fix migration test model init bug
(modelmigration/migrationtest/tests.go)
Fixes#38553
The `<span>` wrapping the SVG in `ActionStatusIcon.vue` had no explicit
display or alignment styles. Safari computes baseline alignment for
inline spans differently from Chrome/Firefox, causing the icon to shift
vertically in the action matrix build status list.
**Fix:** make it inline-flex
---------
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This PR adjusts the repository README discovery logic to mirror GitHub's
priority order, while retaining support for Gitea's specific `.gitea/`
directory.
Previously, Gitea would prioritize a `README.md` at the root of the
repository over any READMEs in `.gitea/` or `.github/`. With this
change, well-known subdirectories are evaluated first when viewing the
repository root.
**New Priority Order:**
1. `.gitea/README.md`
2. `.github/README.md`
3. `/README.md` (root directory)
4. `docs/README.md`
This allows repository maintainers to use `.github/README.md` (or
`.gitea/README.md`) as the repository homepage without having to remove
or rename generic root `/README.md` files required by package managers
(like NPM, Crates.io, Docker, etc.).
---------
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
The "path" details should be hidden to other packages
By the way, fix a resource leaking in gogit's CommitNodeIndex
(the file was not closed in CacheCommit)
before: gitrepo vs git packages
after: git package fully handle all git operations
by the way, use `WithRepo(repo)` instead of `WithDir(repo.Path)` to hide
path details.
benefits:
1. remove all unnecessary wrappers, developers no need to struggle with
"which package should be used"
2. simplify code, RepositoryFacade can (will) be used everywhere, all
"path" details are (will be) hidden
Group updates from all managers into a single `dependencies` group so
monday produces one combined PR instead of one per manager, matching
what is regularly done manually to reduce CI waiting time. The `gomod`
and `npm` rules remain for their `postUpgradeTasks`, which run once on
the combined branch.
Also replace the all-day monday schedule with the `schedule:weekly`
preset (monday 0-4 UTC) so updates whose `minimumReleaseAge` lapses
later in the day wait for the next weekly batch instead of raising a new
PR the same day, as happened in
https://github.com/go-gitea/gitea/pull/38546. `vulnerabilityAlerts` and
the go toolchain rule bypass the schedule as before.
The test raced the server-side SSE channel registration: a logout
emitted before registration is silently dropped ([example
flake](https://github.com/go-gitea/gitea/actions/runs/29699349255/job/88225654080)).
The 500ms wait from https://github.com/go-gitea/gitea/pull/37403 only
made this unlikely.
The server now registers the channel before sending the initial response
bytes, so an open connection implies registration. The shared worker
forwards the built-in `open` event (replaying it to late-attaching ports
via `EventSource.readyState`), the page exposes it as a
`data-user-events-connected` attribute, and the test waits for that
attribute instead of a fixed timeout.
- update eslint and related dependencies, `eslint-plugin-unicorn` to v72
with new rules enabled
- remove `eslint-plugin-sonarjs` (mostly obsolete or slow rules)
- extract shared eslint args into `ESLINT_ARGS` make variable
- rewrite ignore patterns in `eslint.json.config.ts` as explicit
root-relative paths: add `data` (local server data failed `lint-json`),
drop `node_modules` (ignored by default)
- fix a broken link in `CONTRIBUTING.md` (discovered during markdown
linting with eslint, but decided to not add that yet)
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>