Commit Graph

2007 Commits

Author SHA1 Message Date
Shudhanshu Singh d47f9f37d6 refactor(git): clarify GetBranch behavior to make it only gets an existing branch (#38662)
`GetBranch` silently returned soft-deleted branches, contradicting
`IsBranchExist` and forcing callers to manually check `branch.IsDeleted`
everywhere.

Refactored it to `GetBranchExisting` to have a clear behavior: it only
returns the existing branch.

---------

Signed-off-by: Sudhanshu Singh <sudhanshuwriterblc@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-27 17:45:27 +00:00
Harsh Satyajit Thakur e67dd4c818 fix: skip OIDC end-session after password login for OAuth2 users (#38439)
Fixes #38209

OAuth2-linked accounts that sign in via the password form were still
redirected to the provider end_session_endpoint on logout because the
redirect was keyed off account LoginType.

Store the session sign-in method (password vs oauth2) and only use
RP-initiated OIDC logout when this session was authenticated via OAuth2.
Sessions without the new key keep the previous LoginType behavior.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-27 15:35:48 +00:00
mohammad rahimi 13d0f24423 feat: Replace SSE with WebSocket for UI notifications (#36965)
* Closes #36942
* Fixes #19265 

Replaces the SSE-based push channel (`/user/events`) with a WebSocket
endpoint (`/-/ws`).

### What changes

- **New `/-/ws` endpoint** (authenticated). One WebSocket per origin,
shared across tabs via a single `SharedWorker`.
- **Pubsub broker** (`services/pubsub`) for fan-out by topic, behind a
`Broker` interface. `MemoryBroker` is the default (single process); a
Redis backend is available for multi-process setups, configured via
`[websocket].PUBSUB_TYPE` / `PUBSUB_CONN_STR`. The internal Gitea queue
was not usable here because it has FIFO/single-consumer semantics.
- **Push-only event production.** Events are emitted by write-triggered
notifiers — `NotificationCountChange`, `PublishStopwatchesForUser`, and
the logout publisher — wired into the existing `notify.Notifier`
interface. No server-side pollers.
- **Typed pub/sub on the client.** `web_src/js/modules/worker.ts` is a
singleton transport; features subscribe per event type via
`onUserEvent('notification-count', cb)` instead of branching on
`event.data.type`.
- **Wire contract** (`UserEventType` union) is shared between the worker
and consumers via `web_src/js/types.ts`, kept in sync with
`services/websocket/events.go`.
- **Client-side periodic polling fallback** kicks in only when the
WebSocket cannot be established (e.g. proxy blocks WS, browser lacks
module-SharedWorker support).

### What's removed

- `modules/eventsource` (SSE manager, run loop, messenger).
- `/user/events` route and `tests/integration/eventsource_test.go`.
- All server-side polling for stopwatches and notification counts.

### Stopwatch multi-tab fix

The navbar stopwatch icon was previously rendered conditionally on `{{if
$activeStopwatch}}`, so tabs loaded before the timer started had no DOM
element to update. The icon and popup are now always rendered (toggled
with `tw-hidden`), and the start/stop/cancel handlers POST silently so
all open tabs reflect the change in real time.

### Deployment note

WebSocket needs the upgrade headers to pass through a reverse proxy,
e.g. for nginx:

```nginx
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
```

Without them the WebSocket cannot be established, and after 3
consecutive failed opens the shared worker signals `push-unavailable`:
the notification count and stopwatch fall back to periodic polling on
the existing `[ui.notification]` timeouts. Real-time push is lost, the
features keep working. The reverse-proxy docs need the same note (see
the `docs-update-needed` label).

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Epid <rexmrj@gmail.com>
2026-07-27 07:46:00 +00:00
wxiaoguang a3caf21440 feat: admin impersonates a user (#38614)
* fix #3631
* fix #21599

by the way, refactored the "profile avatar card" to simplify the code.
2026-07-26 17:26:02 +00:00
bircni 69f0a10364 fix(actions): correctness and hardening fixes (#38518)
Various fixes to actions

1. **Cap total jobs per run in reusable-workflow expansion** — only
nesting depth was capped, so fan-out + nested reusable workflows could
explode job-row inserts and exhaust the DB from a single push. Now
enforces `MaxJobNumPerRun` in the insert path.
2. **Reject rerun-failed when a run has no failed jobs** — an empty job
list meant "re-run everything", so `rerun-failed` on a green run re-ran
all jobs. Now errors (web + API).
3. **Don't adopt external commit statuses into the legacy hash** — the
pre-#35699 Context-only hash matched API-posted statuses too, collapsing
two same-named workflows into one check. Now limited to Actions-user
rows.
4. **Don't cut post-cancel cleanup short in `StopEndlessTasks`** — the
sweep force-stopped just-cancelled jobs mid-cleanup. Now targets
`StatusRunning` only; stalled cancels stay covered by `StopZombieTasks`.
5. **Avoid redundant run reload in `GenerateGiteaContext`** — resolving
`github.triggering_actor` reloaded the run already passed in. Now loads
only the trigger user via new `ActionRunAttempt.LoadTriggerUser`.

---------

Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-25 16:07:40 +00:00
Shudhanshu Singh fadaf36e95 fix(repo): prevent double-write redirect collisions on dependency errors, fix ui (#38627)
1. fix `AddDependency` and ` RemoveDependency` to respond correctly
2. refactor the form to use "form-fetch-action"
3. fix the issue dependency icon layout regression

---------

Signed-off-by: Sudhanshu Singh <sudhanshuwriterblc@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-25 20:39:36 +08:00
Mitrahsoft 3c66ec4064 fix(oauth2): enforce mandatory 2FA policy on OAuth2 authorize/grant endpoints (#38591)
Fixes #37407 

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-24 01:39:38 +00:00
wxiaoguang 7065637e61 refactor: hide git repo path details from more packages (#38601)
Remove `RepoPath` from "models/repo" package, remove `UserPath` from
"models/user" package, use `WithRepo` for more places, fine tune tests.
2026-07-23 17:42:55 +00:00
Shudhanshu Singh 86a3048247 fix(project): prevent database mutations on invalid MoveIssues payload (#38600)
Add missing "return" after ServerError

Signed-off-by: Sudhanshu Singh <sudhanshuwriterblc@gmail.com>
2026-07-23 08:51:49 -07:00
Shudhanshu Singh 6ac19f6226 fix(issue): display error toast on batch action failures instead of reloading page (#38593)
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>
2026-07-23 09:33:47 +00:00
wxiaoguang 1acf93d854 refactor: clean up git repo and model migration packages (#38564)
enable the golangci depguard lint rule: deny "models" and its sub
packages in "modelmigration" package.
2026-07-23 01:22:26 +00:00
wxiaoguang ae2ff1b467 fix: branch protection user list (#38570)
fix #38569, also fix the UI
2026-07-22 18:48:39 +00:00
wxiaoguang 91eb14c944 refactor: use WithRepo instead of WithDir for most git operations, clean up model migrations (#38555)
by the way, remove some unnecessary "models" imports from model
migration package, fix migration test model init bug
(modelmigration/migrationtest/tests.go)
2026-07-21 12:18:00 +00:00
Shudhanshu Singh c0f4e5583e feat(repo): prioritize well-known READMEs and optimize discovery (#38532)
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>
2026-07-21 11:44:25 +08:00
wxiaoguang a4526d5a82 refactor: remove Path field from git.Repository (#38552)
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)
2026-07-20 18:03:28 +00:00
wxiaoguang 9dc04289aa refactor: make git package handle all git operations (#38543)
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
2026-07-20 16:07:38 +00:00
silverwind f9819dbb74 test(e2e): deterministically wait for event stream in logout propagation test (#38535)
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.
2026-07-20 08:44:53 +00:00
wxiaoguang 775e3bdb34 refactor: remove unnecessary git command wrapper functions (#38531)
Removed `gitrepo.RunCmd*` functions, because gitcmd.Command works with
Repository directly.

Move some "local filesystem" related function into "localfs.go"
2026-07-20 03:17:25 +00:00
wxiaoguang b06002f449 refactor: git repo and relative path handling (#38522)
1. simplify "StorageRepo" code
2. simplify git.OpenRepository code
3. by the way, clean up some unused files in git test fixtures.
2026-07-19 07:32:00 +00:00
YumeMichi ae176cd649 refactor: clean up fragile diff render templates, use backend typed structs (#38517)
Blob.Size requires a context after the repository context removal
(5b078f72aa).

Actually the template code should just render, it should not depend on
the fragile dynamic calls to backend functions.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-19 11:20:01 +08:00
wxiaoguang 66e3849a70 refactor: correct git repo design and fix some legacy problems (#38512) 2026-07-18 15:28:14 +02:00
wxiaoguang 5b078f72aa refactor: remove Ctx field from git.Repository (#38500) 2026-07-17 18:44:31 +08:00
wxiaoguang 2c8e99bbf7 fix: make commit message merge correctly (#38490)
fix #38487

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: bircni <bircni@icloud.com>
2026-07-17 07:44:05 +00:00
TowyTowy 8a3daef525 fix(repo): stop advertising HTTP clone URLs when DISABLE_HTTP_GIT is set (#38378)
Fixes #38339

---------

Signed-off-by: TowyTowy <towy@airreps.link>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-17 05:17:28 +00:00
Eyüp Can Akman a49c893842 fix(pull): sign the commit when updating a branch by merge (#38441)
Updating a branch by merge produced an unsigned commit even when merges
are configured to be signed. Update by rebase was unaffected.

`Update()` builds a fake reverse PR to switch head and base, and it has
no `Index`, so `pr.GetGitHeadRefName()` resolves `refs/pull/0/head`.
Since #36186 `SignMerge` looks that ref up in the base repository
instead of the temporary merge repo. That lookup fails. The caller
dropped the error, so `sign` stayed false.

Sync fork goes through the same fake-PR path.

Pass both sides of the merge to `SignMerge` as refs and evaluate them in
the temp repo, where `base` and `tracking` always exist.

Tests cover a signed and an unsigned update by merge.

Fixes #38066
2026-07-16 21:38:39 +00:00
bircni 9d3f04eb7e fix(actions): explain why a blocked or waiting job has not started (#38476)
When an Actions job is blocked or waiting, the job view only shows the
generic **Blocked** / **Waiting** label. Users have no way to tell *why*
a job is stuck — whether it's waiting on dependencies, waiting for a
runner that doesn't exist, waiting for a runner whose labels don't
match, or simply queued behind busy runners.

## Change

The current-job detail line now surfaces the actual cause:

- **Blocked** → lists the dependency jobs (`needs`) that haven't
finished yet, e.g. *"Waiting for the following jobs to complete:
build."*
- **Waiting**, no online runner → *"No runner is online to pick up this
job."*
- **Waiting**, online runners but none match `runs-on` → *"No matching
online runner with label: X"* (reuses the existing string)
- **Waiting**, a matching runner exists but hasn't claimed the job →
*"Waiting for a matching runner to become available."*

The runner lookup reuses the same available-online-runner query the run
list already performs, and only runs while a selected job is actually
pending. Dependency resolution is scoped to the same parent job and
treats matrix expansions of a `need` as pending until all of them
complete.
2026-07-16 23:10:43 +02:00
silverwind f0d9af3a18 enhance(ui): use OpenAPI 3.0 spec in API viewer, add spec buttons (#38478)
Follow-ups from https://github.com/go-gitea/gitea/pull/37038:

- Render the OpenAPI 3.0 spec in the API viewer, it is richer than the
Swagger 2.0 rendering
- Replace the back link with gitea-styled buttons to view both specs and
return to Gitea, flowing above swagger-ui on viewports where they would
overlap the title
- Key `VisibilityModes` by the string enum type, now named
`VisibilityString`, removing the `string()` casts at API call sites
- Drop the raw visibility strings from the `Service` settings struct in
favor of the typed mode fields, which also removes the org default
visibility row from the admin config page
- Fix two pre-existing issues surfaced in review: an invalid
`DEFAULT_USER_VISIBILITY` was silently accepted as public, and the org
visibility error message showed the enum zero value instead of the
submitted input

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-16 17:38:33 +00:00
bircni 02f82a2054 fix(actions): show retention info on hover for expired artifacts (#38477)
The artifact info hover tooltip (#37100) only worked for live artifacts.
Hovering an expired/deleted artifact showed nothing, and even on live
artifacts the retention date was missing on real runs.

Two root causes:

1. **Expired artifacts had no tooltip.** In the run view sidebar,
expired artifacts render in a separate branch that omitted
`data-tooltip-content` entirely, so there was nothing to hover.
2. **`ExpiresUnix` was no longer sent.** The `ActionRunAttempt` refactor
(#37119) dropped `ExpiresUnix` from `fillViewRunResponseArtifacts`, so
real runs always returned `0` and the tooltip fell back to size-only.
Only the devtest mock still populated it, which masked the regression.

Artifacts without a recorded expiry (`expiresUnix <= 0`) still degrade
gracefully to a size-only tooltip. Both states can be previewed on the
`/devtest/mock/*` actions run page.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-16 15:58:31 +02:00
bircni 1850a108e5 fix(actions): group reusable-workflow matrix legs in the workflow graph (#38475)
Fixes the UI issue reported in #38466: matrix jobs that invoke a
reusable workflow (`build-call (linux)`, `build-call (windows)`, …) were
rendered as separate nodes in the run's workflow graph, while an
equivalent regular matrix
(`build (linux)`, `build (windows)`, …) collapsed neatly into a single
matrix node.

Before: three loose `build-call (...)` boxes next to one grouped `build` box.
After: both matrices collapse into a single node.
2026-07-16 20:58:05 +08:00
wxiaoguang 82edc3da01 refactor: decouple git.Repository(ctx) from git.Commit & git.Tree (#38464)
1. Storing "ctx" in a long-living object is wrong
2. Make the commit & tree cacheable (for the future performance
optimization)
3. Also fix some bad designs like `// FIXME: bad design, this field can
be nil if the commit is from "last commit cache"`

ref:
* #33893
2026-07-15 17:30:01 +00:00
Jeremy Stover 9fa2bff5fd fix(admin): exit dev test queue producer loop when context is cancelled (#38451)
Co-authored-by: Kadajett <jeremy@semfora.ai>
2026-07-15 03:25:50 +00:00
xkm 880ddb5724 fix(actions): prevent bulk actions from affecting all runners (#38453)
Fix the bug in the site-admin runner bulk actions introduced by #37869:
the runner IDs are empty then all runners will be deleted.

Fixes #38449

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-15 02:36:03 +00:00
Harsh Satyajit Thakur b6904c9730 fix: make "test push webhook" always work (#38425)
* fix #38309
* fix #26238
* fix #37886

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-14 18:24:18 +00:00
bircni f69e15afe7 fix: various security fixes (#38406)
Addresses a batch of privately reported security issues, grouped by
area:

- **SSRF** - migration PR-patch/asset fetches, OAuth2 avatar & OpenID
discovery, pull-mirror URL re-validation, and the outbound proxy path.
- **Access-token scope** - prevent scope escalation on token creation;
keep public-only tokens confined (feeds, packages, Actions listings,
star/watch lists, limited/private owners).
- **Access control / disclosure** - go-get default-branch leak, webhook
authorization-header leak, watch clearing on private transitions,
label/attachment scoping.
- **Denial of service** - input bounds for npm dist-tags, Debian control
files, Arch file lists, and SSH keys.

### 📌 Attention for site admins

Not breaking - existing configs keep working - but two changes are worth
a look:

- **New SSRF protection** Outbound requests (migrations, OAuth2 avatars,
OpenID discovery, pull mirrors, proxy path) are now validated against
the allow/block host lists. If your instance legitimately reaches
internal hosts, you may need to add them to
`[security].ALLOWED_HOST_LIST` (and the relevant `ALLOW_LOCALNETWORKS`
settings).
- **Deprecation** `[webhook].ALLOWED_HOST_LIST` is deprecated and will
be removed in a future release. Use `[security].ALLOWED_HOST_LIST`
instead; the old key still works for now.

---------

Co-authored-by: TheFox0x7 <thefox0x7@gmail.com>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
2026-07-12 17:14:09 +00:00
Shudhanshu Singh b998c3c1aa feat(actions): implement adaptive auto-refresh for workflow runs list (#38329)
### Description
This PR implements an optimized, adaptive client-side auto-refresh
mechanism for the Gitea Actions workflow runs list page. It allows users
to see workflow progress updates dynamically without having to reload
the page.

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

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-12 12:14:37 +00:00
wxiaoguang bd5f881c51 fix: refresh pull request merge box when the commit status is pending (#38410) 2026-07-11 19:36:10 +02:00
bircni aab3242f7b fix(security): harden access checks and migration validation (#38324)
Harden access checks for issue dependencies, team repository membership,
notifications, stars, tracked times and repository migrations.
2026-07-10 19:30:43 +02:00
bircni 27e33b7ba1 fix: incorrect co-author detection on commit page (#38386)
The commit page built its "co-authored by" list from
`AllParticipantIdentities()[1:]`, which only drops the author and leaves
the committer in the list even though the committer is already shown
separately as "committed by". This caused the committer to be wrongly
rendered as a co-author (issue #38384): a commit authored by
`silverwind`, committed by `bircni`, with a `Co-authored-by: silverwind`
trailer displayed "co-authored by bircni" instead of the actual trailer
identity. This adds a `Commit.CoAuthorIdentities()` method that excludes
both the author and the committer, uses it on the commit page, and
covers the fix with a regression test.

Closes #38384
2026-07-09 22:31:14 +02:00
Copilot 2b89e2ac97 fix(pulls): add branch-name option for DEFAULT_TITLE_SOURCE (#38356)
Adds a new `branch-name` value for the `[repository.pull-request]`
`DEFAULT_TITLE_SOURCE` setting that always uses the normalized branch
name as the PR title, regardless of commit count.

Fix #38317

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-07 07:08:05 +00:00
wxiaoguang 26bff7f47e fix: org project view assignee list (#38357)
fix #38129
2026-07-07 14:40:12 +08:00
Lunny Xiao e4ef995f2a fix(release): validate web attachment renames against allowed types (#38314)
This fixes the web release edit flow so renamed release attachments are
validated against `[repository.release] ALLOWED_TYPES`.

Previously, the API attachment edit endpoint already enforced release
attachment type restrictions, but the web release edit form passed
`attachment-edit-*` values into `release_service.UpdateRelease`, which
updated attachment names directly without validating the new filename
against `setting.Repository.Release.AllowedTypes`.

As a result, a user with repository write access could rename an
existing release attachment to a disallowed extension through the web
UI.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-04 15:02:17 +02:00
bircni f7fd510224 fix(release): gate draft release attachments on web download endpoints (#38318)
Draft-release access control was enforced only on the API release
endpoints (`/api/v1/repos/{owner}/{repo}/releases/...`) but not on the
UUID-based web attachment endpoints (`/attachments/{uuid}`,
`/{owner}/{repo}/attachments/{uuid}`,
`/{owner}/{repo}/releases/attachments/{uuid}`).

Anyone who obtained an attachment UUID — including unauthenticated
callers — could download files belonging to a hidden draft release,
since `ServeAttachment` only checked repo-level read permission and
never the release's draft state.
2026-07-03 20:07:37 +02:00
Shudhanshu Singh b09920a537 feat(webhook): support Telegram Bot API 10.1 Rich Messages (#38298)
Upgrades Gitea's Telegram webhook integration to support Telegram Bot
API 10.1 (June 2026 release). This enables Gitea webhooks to take
advantage of rich formatted messages (tables, nested blocks, collapsible
details, etc.) by routing them through the /sendRichMessage endpoint
with the new rich_message payload structure.

Old `/sendMessage` webhook URLs are written to `/sendRichMessage`
at runtime to prevent the need for database migrations

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

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-02 15:14:48 +00:00
Zettat123 67a6bd7fc0 feat(auth): add disable-2fa command (#38275)
This PR adds the `gitea admin user disable-2fa` command to disable 2FA
for a user

When the only admin in the instance loses their 2FA credentials, this
command can be used to disable 2FA, allowing them to log in and reset
it.

---------

Co-authored-by: Giteabot <teabot@gitea.io>
2026-07-01 12:33:16 +02:00
Aidan Fahey 77e221ffaf fix(oauth2): persist linkAccountData during auto-link 2FA flow (#38274)
Fixes HTTP 500 when OIDC auto account linking (`ACCOUNT_LINKING=auto`)
requires local 2FA. `oauth2LinkAccount` set `linkAccount` in the session
before redirecting to 2FA but did not persist `linkAccountData`, so
`TwoFactorPost` failed with `not in LinkAccount session`. The manual
linking flow already stored both, this aligns auto-link with that
behavior.

Closes #38171

---------

Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-01 10:03:38 +00:00
Lunny Xiao 5b9251150c fix(actions): address workflow status badge review feedback (#38241)
Follow
https://github.com/go-gitea/gitea/pull/38196#discussion_r3487219492

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: bircni <bircni@icloud.com>
2026-06-28 10:53:01 +00:00
Zettat123 f46c9a9769 feat(actions): support owner-level and global scoped workflows (#38154)
## Summary

This PR adds **scoped workflows** to Gitea Actions. Workflows defined
centrally in a "source" repository that automatically run on every
repository in scope: an organization's repositories, or (for instance
admins) every repository on the instance. Each scoped run executes in
the consuming repository's own context (its runners, secrets, and
branch) while its content is read from the source repository, so an org
or instance can mandate shared CI across many repositories without
copying workflow files into each one.

An owner or instance admin registers source repositories on a settings
page and can mark individual workflows as **required**. A required
scoped workflow cannot be opted out by a consuming repository and gates
its pull-request merges; an optional one can be disabled per repository.
Scoped workflows live under a dedicated `SCOPED_WORKFLOW_DIRS` (default
`.gitea/scoped_workflows`), kept separate from regular `WORKFLOW_DIRS`.

## Main changes

### Configuration 
New `SCOPED_WORKFLOW_DIRS` setting, validated to not overlap with
`WORKFLOW_DIRS`. Default: `.gitea/scoped_workflows`

### Data model & migration
- New `action_scoped_workflow_source` table mapping a registering owner
(`owner_id`, where `0` = instance-level) to a source repository, with a
per-workflow `WorkflowConfigs` map.
- `ActionRun` gains `WorkflowRepoID` / `WorkflowCommitSHA` (the pinned
content source) and an `IsScopedRun` flag.

###  Detection & run creation
On consumer events, scoped workflows from the effective sources (the
owner's own sources plus instance-level ones) are matched and turned
into runs that execute in the consumer's context, with content pinned to
the source repo's default-branch commit.

`on: workflow_run` and `on: schedule` are currently not supported.

###  Opt-out
A consuming repository can disable an optional scoped workflow (tracked
separately from regular `DisabledWorkflows`); required scoped workflows
can never be disabled, opted out, or bypassed.

###  Commit status 
A scoped run's status context format is `"<source repo full name>:
<workflow display name> / <job> (<event>)"`
(for example: `my-org/scoped-workflows: db-tests / test-sqlite
(pull_request)`),
keeping it distinct from a same-named repo-level workflow and from other
sources.

###  Required status checks
Admins mark workflows required and supply status-check patterns.
`EffectiveRequiredContexts` appends those patterns to the branch
protection's required contexts and they are matched
must-present-and-pass. If the status checks from scoped workflows fail,
the PR cannot be merged.

NOTE: scoped workflows' required status checks patterns can protect any
target branch that has a protection rule, even though the rule's "Status
Check" is disabled. A target branch with no protection rule cannot be
protected.

<details>
  <summary>Screenshots</summary>

<img width="1400" alt="image"
src="https://github.com/user-attachments/assets/a5d1db33-15ec-487e-93be-2bc04b4e6643"
/>

</details>


###  Reusable workflows (`uses:`)
A scoped workflow's local `uses: ./...` resolves against the source
repository. `uses:` directory validation honors the
instance-configurable `WORKFLOW_DIRS` and `SCOPED_WORKFLOW_DIRS`
(previously hardcoded to `.gitea`/`.github/workflows`).

###  Manual dispatch
`workflow_dispatch` is supported for scoped workflows (web and API),
resolving inputs/content from the source repo.

###  Performance
A process-local LRU cache keyed by source repo ID for the per-source
workflow parse, so instance-level and owner-level sources don't open the
source repo and parse workflow files on every event.

### UI
Org / user / admin pages to register and remove sources, search
repositories, and mark workflows required with their status-check
patterns. The repository Actions sidebar groups scoped workflows by
source with owner/instance labels and required/disabled badges.

<details>
  <summary>Screenshots</summary>

Scoped workflows setting page:

<img width="1600" alt="image"
src="https://github.com/user-attachments/assets/9d19f667-97a5-4935-92b2-e53f105e3642"
/>


Consumer repo's Actions runs list:

<img width="1600" alt="image"
src="https://github.com/user-attachments/assets/a77241f9-0aa9-41aa-ba73-12a9a688cb64"
/>

- `Owner`: this is a owner-level scoped workflows source repo
- `Global`: this is a global scoped workflows source repo
- `Required`: this scoped workflow is required, repo admin cannot
disable it

</details>

---

Docs: https://gitea.com/gitea/docs/pulls/447

---------

Co-authored-by: bircni <bircni@icloud.com>
2026-06-28 09:31:35 +00:00
Lunny Xiao c9920b7bd0 fix(oauth): restrict introspection to the token's client (#38042)
Bind OAuth token introspection responses to the authenticated client.
Return an inactive response when the token grant belongs to a different
OAuth application to avoid leaking token metadata across clients.

Add integration coverage for cross-client introspection attempts against
both access tokens and refresh tokens.

Assisted-by: GPT-5.4
2026-06-28 08:06:33 +00:00
guanzi008 9540292596 feat(actions): add workflow status badge modal (#38196)
- Add a Create Status Badge button for selected Actions workflows.
- Show badge URL, Markdown, and HTML snippets backed by the existing
workflow badge route.

## Screenshots
<img width="553" height="470" alt="dyn-a5d565ab915b9ffb6c02ac68113494b0"
src="https://github.com/user-attachments/assets/43b4ceb9-bbd1-4024-b058-d85ec8325e88"
/>
<img width="349" height="156" alt="grafik"
src="https://github.com/user-attachments/assets/6eaec62d-ffb0-45c0-b63d-866a41a66005"
/>



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

---------

Signed-off-by: guanzi008 <245205080@qq.com>
Co-authored-by: bircni <bircni@icloud.com>
2026-06-28 01:36:45 +02:00
Lunny Xiao cbe1b703dc refactor: Use db.Get[] instead of db.GetEngine(ctx).Get(bean) to avoid zero value fetching wrong database record (#37977)
This PR replaces a set of struct-based `Get` lookups with explicit
`db.Get` / `db.Exist` conditions in places where zero-value fields can
lead to ambiguous matches or incorrect records being returned.

The main goal is to make read paths deterministic and avoid accidentally
matching the wrong row when only part of a struct is populated.

### What changed

- replace many `db.GetEngine(ctx).Get(bean)` calls with explicit
`builder.Eq` conditions across models such as actions, admin tasks,
issues, pull requests, repositories, users, packages, redirects,
watches, stars, and follows
- use quoted column names where needed for reserved fields like `index`,
`type`, and `name`
- add dedicated user lookup helpers for:
  - primary email
  - OAuth login source / login name
- update sign-in and OAuth-related flows to use explicit individual-user
lookups instead of partially populated `User` structs
- tighten package property and Terraform lock lookups to avoid ambiguous
reads and updates
- keep existing fallback behavior where needed, while removing reliance
on zero-value struct matching

### User-facing impact

These changes primarily affect authentication and account lookup paths:

- email/username sign-in now re-fetches users through explicit keys
- OAuth2 auto-linking now resolves users by name or primary email
explicitly
- OAuth2 login/sync now looks up users by login source, login type, and
login name explicitly
- non-individual accounts are no longer implicitly matched through
partial user lookups in these flows

This should reduce the risk of incorrect account matches and make query
behavior more predictable across the codebase.

---------

Co-authored-by: bircni <bircni@icloud.com>
2026-06-27 10:24:02 -07:00