1247 Commits

Author SHA1 Message Date
will.anderson bb6faa4c5d feat(webhook): add workflow_step webhook events for step-level CI notifications
Adds HookEventWorkflowStep event type that fires on every step state
transition (queued -> in_progress -> completed). Follows the same
pattern as the existing workflow_job events.

- New WorkflowStepPayload struct with run/job/step context
- WorkflowStepStatusUpdate notifier interface + dispatch
- Step state change detection in UpdateTask runner endpoint
- Fix: register workflow_step in updateHookEvents API mapping
- Full test coverage mirroring workflow_job tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 17:47:14 -05:00
silverwind 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
Kalash Thakare ☯︎ ee803ad05d fix(actions): validate workflow param to prevent 500 error (#37546)
Fix #37523
2026-05-05 16:19:52 +00:00
wxiaoguang 6ba907d89c Fix various problems (#37547)
1. Fix ugly commit form "warning" message
2. Use JSONError for "Update PR Branch" response 
3. Remove useless "timeline" class
4. Make timeline review default to "comment" to avoid icon missing
5. Align PR's "command line instructions" UI
6. Simply "Update PR branch" button logic

And then some TODOs are fixed.

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
2026-05-05 15:54:07 +00:00
wxiaoguang a90d5dd131 Refactor pull request view (7) (#37524)
Almost done

`pull_merge_box.tmpl` only has about 80 lines now, and (almost) all
variable accesses are strictly typed.

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-04 20:13:38 +00:00
wxiaoguang dd17521808 Refactor pull request view (6) (#37522)
Clean up legacy logic.

* Use backend logic to choose PR timeline icon color
* Always use the Vue form to merge, remove the "StillCanManualMerge" logic
2026-05-04 14:15:33 +08:00
wxiaoguang a2a5ef8d0e Fix update branch protection order (#37508)
Regression of changed behavior or Golang JSON v2 package

Fix #37506
2026-05-02 16:32:36 +00:00
pomidorry 02b1b8a549 Add mirror auth updates to repo edit API and settings (#37468)
## Summary

This PR adds support for updating pull mirror authentication via the
repository edit API and UI.

It introduces new mirror authentication fields in _EditRepoOption_,
updates the API logic to safely handle partial credential updates, and
fixes the web settings flow so that the existing remote username is
preserved when only the password is changed.

### What changed
- added _auth_username_, _auth_password_, and _auth_token_ to
EditRepoOption
- updated the repository edit API to apply mirror auth changes via
_updateMirror_
- preserved existing username/password when only part of the auth
payload is provided
- used oauth2 as the default username when _auth_token_ is provided
- kept stored mirror URLs sanitized in DB and API responses
- updated Swagger schema for the new API fields
- added API integration tests for password-only and token-only updates
- added a web settings test to ensure username preservation on partial
updates

## Why

Some use cases require automated synchronization of pull mirrors, for
example in CI/CD pipelines or integrations with external systems.

At the same time, many organizations enforce security policies that
require periodic token rotation (e.g., monthly).

Currently, mirror credentials can only be updated via the UI, which
makes automation difficult.

## This change enables:

- automated token rotation
- avoiding manual updates via the UI
- easier integration with secret management systems
## Testing
- added integration coverage for mirror auth updates via _PATCH
/api/v1/repos/{owner}/{repo}_
- added web settings tests for password-only updates preserving the
existing username

## Result
Ability to automate auth update
<img width="2400" height="1245" alt="1"
src="https://github.com/user-attachments/assets/67fd5cca-9cb3-4536-b0e2-4d09b8ebff0f"
/>
<img width="962" height="932" alt="image"
src="https://github.com/user-attachments/assets/5d548f5d-aadf-4807-ba52-9c29df93a4cc"
/>

Generative AI was used to help with making this PR.
##
2026-05-01 11:00:03 +00:00
Icy Avocado 81692ceafa Allow multiple projects per issue and pull requests (#36784)
Add ability to add and remove multiple projects per issue
and pull request.

Resolve #12974

---------

Signed-off-by: Icy Avocado <avocado@ovacoda.com>
Co-authored-by: Tyrone Yeh <siryeh@gmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: OpenCode (gpt-5.2-codex) <opencode@openai.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-30 22:38:05 +08:00
wxiaoguang 2b2ec6af85 Refactor compare diff/pull page (1) (#37481)
1. Rename CompareInfo.MergeBase to CompareBase, it is not merge base
2. Remove unused template variables `ctx.Data["Username"]` and
`ctx.Data["Reponame"]`
3. Decouple some template variable accesses, use typed struct

---------

Co-authored-by: Nicolas <bircni@icloud.com>
2026-04-29 18:32:46 +00:00
wxiaoguang 9262803621 Fix allow maintainer edit permission check (#37479) 2026-04-29 15:37:33 +00:00
0xGREG 0ba862cb97 Add DEFAULT_TITLE_SOURCE setting for pull request title default behavior (#37465)
Adds a new `DEFAULT_TITLE_SOURCE` option under
`[repository.pull-request]` with three values:

- `first-commit` (default): uses the oldest commit summary, current
behavior since v1.26
- `auto`: normalizes branch name as title for multi-commit PRs (just
like GitHub), use commit summary for single-commit PRs

Closes: #37463
Co-authored-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: Giteabot <teabot@gitea.io>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-04-28 21:33:20 +00:00
Nicolas deec2b0929 Fix compare dropdown for branches without common history (#37470) 2026-04-28 23:03:50 +02:00
wxiaoguang 8bf51da65f Refactor pull request view (4) (#37451)
Use JSON attribute instead of inline script

---------

Co-authored-by: Nicolas <bircni@icloud.com>
2026-04-28 04:36:39 +00:00
wxiaoguang c6ffbfe0d2 Rename CurrentRefPath to CurrentRefSubURL (#37453)
Fix a TODO

Co-authored-by: Nicolas <bircni@icloud.com>
2026-04-28 00:34:17 +00:00
silverwind 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
Copilot 45b4fffae4 refactor: use named Permission field in Repository struct instead of anonymous embedding (#37441)
The `Repository` struct in `services/context/repo.go` embedded
`access_model.Permission` anonymously, causing all permission methods to
be promoted directly onto `Repository`. This made it unclear at call
sites whether a method belonged to `Repository` itself or to its
embedded `Permission`.

### Changes

- **`services/context/repo.go`**: Replace anonymous
`access_model.Permission` with named field `Permission
access_model.Permission`
- **49 files** updated to route permission method calls through the
named field:

```go
// Before
ctx.Repo.IsAdmin()
ctx.Repo.CanWrite(unit.TypeCode)
ctx.Repo.CanReadIssuesOrPulls(isPull)
slices.ContainsFunc(unitTypes, ctx.Repo.CanWrite)

// After
ctx.Repo.Permission.IsAdmin()
ctx.Repo.Permission.CanWrite(unit.TypeCode)
ctx.Repo.Permission.CanReadIssuesOrPulls(isPull)
slices.ContainsFunc(unitTypes, ctx.Repo.Permission.CanWrite)
```

Methods defined directly on `*Repository` (`CanWriteToBranch`,
`CanCreateBranch`, etc.) are unchanged.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: wxiaoguang <2114189+wxiaoguang@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-04-26 20:18:28 +00:00
wxiaoguang 55c9b936cb Refactor pull request view (3) (#37439)
Move some complex logic to backend

Rename `pr.CanAutoMerge` to `pr.IsStatusMergeable`
2026-04-26 19:03:41 +00:00
wxiaoguang 068b59aa97 Make GetPossibleUserByID can handle deleted user (#37430)
Make sure deleted user won't cause 500 error, simplify the caller's code
2026-04-26 16:57:53 +00:00
wxiaoguang b3ed4cde9a Refactor pull request view (2) (#37428)
Follow up #37380

Some code is moved to the place whether it should be.
2026-04-26 13:58:48 +00:00
wxiaoguang 1483291a87 Refactor pull request view (1) (#37380)
Refactor preparePullViewPullInfo and related functions, split them into
small ones:

* preparePullViewPullInfo creates PullRequestViewInfo struct
* if the PR is merged: prepareView**Merged**PullInfo
* if the PR is open: prepareView**Open**PullInfo

In prepareViewMergedPullInfo and preparePullViewFillInfo: call
preparePullView**FillInfo** consistnently

preparePullViewFillInfo calls preparePullViewFill**CompareInfo** and
preparePullViewFill**CommitStatusInfo**
2026-04-24 10:24:41 +00:00
Nikita Vakula 3b2fd9791c Allow fast-forward-only merge when signed commits are required (#37335)
Fast-forward-only creates no Gitea commit, so skip the "can Gitea sign"
precheck for it. Pre-check head-commit verification for styles that
preserve user commits on the target (merge, fast-forward-only) so a PR
with unsigned commits surfaces a localized error instead of a 500 at the
pre-receive hook. The dropdown still shows every configured style; the
avatar and signing warning toggle per selection via
data-pull-merge-style.

Fixes #12272 

**Note**: Admin force-merge does not bypass the new head-commits check.
This matches the existing `isSignedIfRequired` behavior.

Signed-off-by: Nikita Vakula <programmistov.programmist@gmail.com>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-24 00:04:32 +00:00
Zettat123 899ede1d55 Introduce ActionRunAttempt to represent each execution of a run (#37119)
This PR introduces a new `ActionRunAttempt` model and makes Actions
execution attempt-scoped.

**Main Changes**

- Each workflow run trigger generates a new `ActionRunAttempt`. The
triggered jobs are then associated with this new `ActionRunAttempt`
record.
- Each rerun now creates:
  - a new `ActionRunAttempt` record for the workflow run
- a full new set of `ActionRunJob` records for the new
`ActionRunAttempt`
- For jobs that need to be rerun, the new job records are created as
runnable jobs in the new attempt.
- For jobs that do not need to be rerun, new job records are still
created in the new attempt, but they reuse the result of the previous
attempt instead of executing again.
- Introduce `rerunPlan` to manage each rerun and refactored rerun flow
into a two-phase plan-based model:
  - `buildRerunPlan`
  - `execRerunPlan`
- `RerunFailedWorkflowRun` and `RerunFailed` no longer directly derives
all jobs that need to be rerun; this step is now handled by
`buildRerunPlan`.
- Converted artifacts from run-scoped to attempt-scoped:
  - uploads are now associated with `RunAttemptID`
  - listing, download, and deletion resolve against the current attempt
- Added attempt-aware web Actions views:
- the default run page shows the latest attempt
(`/actions/runs/{run_id}`)
- previous attempt pages show jobs and artifacts for that attempt
(`/actions/runs/{run_id}/attempts/{attempt_num}`)
- New APIs:
  - `/repos/{owner}/{repo}/actions/runs/{run}/attempts/{attempt}`
  - `/repos/{owner}/{repo}/actions/runs/{run}/attempts/{attempt}/jobs`
- New configuration `MAX_RERUN_ATTEMPTS`
  - https://gitea.com/gitea/docs/pulls/383

**Compatibility**

- Existing legacy runs use `LatestAttemptID = 0` and legacy jobs use
`RunAttemptID = 0`. Therefore, these fields can be used to identify
legacy runs and jobs and provide backward compatibility.
- If a legacy run is rerun, an `ActionRunAttempt` with `attempt=1` will
be created to represent the original execution. Then a new
`ActionRunAttempt` with `attempt=2` will be created for the real rerun.
- Existing artifact records are not backfilled; legacy artifacts
continue to use `RunAttemptID = 0`.

**Improvements**

- It is now easier to inspect and download logs from previous attempts.
-
[`run_attempt`](https://docs.github.com/en/actions/reference/workflows-and-actions/contexts#github-context)
semantics are now aligned with GitHub.
- > A unique number for each attempt of a particular workflow run in a
repository. This number begins at 1 for the workflow run's first
attempt, and increments with each re-run.
- Rerun behavior is now clearer and more explicit.
- Instead of mutating the status of previous jobs in place, each rerun
creates a new attempt with a full new set of job records.
- Artifacts produced by different reruns can now be listed separately.

Signed-off-by: Zettat123 <zettat123@gmail.com>
Co-authored-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: Giteabot <teabot@gitea.io>
2026-04-23 23:33:41 +00:00
wxiaoguang 83bdfc2a57 Support for Custom URI Schemes in OAuth2 Redirect URIs (#37356)
Fix #34349

By the way, remove `(ctx *APIContext) HasAPIError() ` and `(ctx
*APIContext) GetErrMsg()` because they do nothing, the error handling
has been done in API's middeware

The existing OAuth2 tests were not quite right, refactored them together
2026-04-22 21:33:27 +00:00
Copilot df8aa2f804 Remove IsValidExternalURL/IsAPIURL and use IsValidURL at call sites (#37364)
This PR simplifies URL validation by removing `IsValidExternalURL` and
`IsAPIURL` from `modules/validation/helpers.go` and switching repository
settings/API callers to `IsValidURL`.
It also aligns tracker-format validation and tests with the new helper
surface.

- **Validation helpers**
  - Removed `IsValidExternalURL` and `IsAPIURL`.
  - Updated `IsValidExternalTrackerURLFormat` to depend on `IsValidURL`.

- **Caller updates**
- Replaced `validation.IsValidExternalURL(...)` with
`validation.IsValidURL(...)` in:
    - `routers/web/repo/setting/setting.go`
    - `routers/api/v1/repo/repo.go`

- **Tests**
  - Removed tests dedicated to `IsValidExternalURL`.
- Updated tracker-format test expectations to match `IsValidURL`-based
behavior.

```go
// before
if !validation.IsValidExternalURL(form.ExternalTrackerURL) { ... }

// after
if !validation.IsValidURL(form.ExternalTrackerURL) { ... }
```

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: wxiaoguang <2114189+wxiaoguang@users.noreply.github.com>
2026-04-22 09:23:27 -07:00
PineBale ca44b5fca8 Add form-fetch-action to some forms, fix "fetch action" resp bug (#37305)
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-20 18:58:44 +00:00
PineBale 99cd709bd6 Fix Repository transferring page (#37277)
While editing frontend, I found some inconsistencies while testing
transferring repositories:

- No button for accepting/rejecting/cancelling the transfer of an empty
repository.
- The `redirect_to` in `templates/repo/header.tmpl` is useless.
- There's no redirection when there's an error from `handleActionError`
in `routers/web/repo/repo.go`. Therefore, instead of flash message, a
blank page will be displayed.

This pr adds some commits to resolve all these issues.

Update: see the new changes
https://github.com/go-gitea/gitea/pull/37277#issuecomment-4276150232

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-04-19 17:57:51 +00:00
Myers Carpenter 2f5b5a9e9c Add project column picker to issue and pull request sidebar (#37037)
Why? You are working on a ticket, it's ready to be moved to the QA
column in your project. Currently you have to go to the project, find
the issue card, then move it. With this change you can move the issue's
column on the issue page.

When an issue or pull request belongs to a project board, a dropdown
appears in the sidebar to move it between columns without opening the
board view. Read-only users see the current column name instead.

* Fix #13520
* Replace #30617

This was written using Claude Code and Opus. 

Closed:

<img width="1346" height="507" alt="image"
src="https://github.com/user-attachments/assets/7c1ea7ee-b71c-40af-bb14-aeb1d2beff73"
/>

Open:
<img width="1315" height="577" alt="image"
src="https://github.com/user-attachments/assets/4d64b065-44c2-42c7-8d20-84b5caea589a"
/>

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-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>
Co-authored-by: Cursor <cursor@cursor.com>
2026-04-19 12:53:02 +00:00
Nicolas 16bdae53c8 Workflow Artifact Info Hover (#37100)
Add expiry metadata to action artifacts in the run view and show it on hover.

---------

Signed-off-by: Nicolas <bircni@icloud.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-19 07:37:50 +00:00
silverwind 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
silverwind 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
Copilot 4a2bba9aed Remove error returns from crypto random helpers and callers (#37240)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: wxiaoguang <2114189+wxiaoguang@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <115237+silverwind@users.noreply.github.com>
2026-04-17 00:59:26 +08:00
wxiaoguang 17f62bfec5 Refactor "htmx" to "fetch action" (#37208)
The only remaining (hard) part is "templates/repo/editor/edit.tmpl", see the FIXME

By the way:

* Make "user unfollow" use basic color but not red color, indeed it is not dangerous
* Fix "org folllow" layout (use block gap instead of inline gap)
2026-04-14 18:38:07 +00:00
wxiaoguang 6bcb666a9d Refactor htmx and fetch-action related code (#37186)
This is the first step (the hardest part):

* repo file list last commit message lazy load
* admin server status monitor
* watch/unwatch (normal page, watchers page)
* star/unstar (normal page, watchers page)
* project view, delete column
* workflow dispatch, switch the branch
* commit page: load branches and tags referencing this commit

The legacy "data-redirect" attribute is removed, it only makes the page
reload (sometimes using an incorrect link).

Also did cleanup for some devtest pages.
2026-04-13 18:53:55 +00:00
Nicolas 6eae04241d Fix encoding for Matrix Webhooks (#37190)
`url.PathEscape` unnecessarily encodes ! to %21, causing Matrix
homeservers to reject the request with 401. Replace %21 back to ! after
escaping.

Fixes #36012

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-13 18:10:43 +00:00
wxiaoguang 8fcbdf05b0 Refactor flash message and remove SanitizeHTML template func (#37179)
1. Fix the "flash message" layout problem for different cases
* I am sure most of the users should have ever seen the ugly
center-aligned error message with multiple lines.
2. Fix inconsistent "Details" flash message EOL handling, sometimes
`\n`, sometimes `<br>`
   * Now, always use "\n" and use `<pre>` to render
3. Remove SanitizeHTML template func because it is not useful and can be
easily abused.
* But it is still kept for mail templates, for example:
https://github.com/go-gitea/gitea/issues/36049
4. Clarify PostProcessCommitMessage's behavior and add FIXME comment

By the way: cleaned up some devtest pages, move embedded style block to
CSS file
2026-04-12 10:17:25 +08:00
Nicolas 980a8995bc Report structurally invalid workflows to users (#37116)
`model.ReadWorkflow` succeeds for YAML that is syntactically valid but
fails deeper parsing in `jobparser.Parse` (e.g. blank lines inside `run:
|` blocks cause a SetJob round-trip error). Add
`ValidateWorkflowContent` which runs the full `jobparser.Parse` to catch
these cases, and use it in the file view, the actions workflow list, and
the workflow detection loop so users see the error instead of silently
getting a 500 or a dropped workflow.

Fixes #37115
Signed-off-by: Nicolas <bircni@icloud.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-09 15:03:32 +02:00
wxiaoguang 73e0e44298 Fix various problems (#37129)
* Fix #37128
    * Manually tested with various cases (issue, pr) X (close, reopen)
* Fix #36792
    * Fix the comment
* Fix #36755
    * Add a "sleep 3"
* Follow up #36697
    * Clarify the "attachment uploading" problem and function call

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: TheFox0x7 <thefox0x7@gmail.com>
2026-04-08 01:17:05 +08:00
silverwind 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
silverwind 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
wxiaoguang 74060bb849 Fix various legacy problems (#37092)
1.  Fix #36439
2. Fix #37089
3. Fix incorrect layout of admin auth oidc page
4. Fix #35866
5. Fix #35800
6. Fix #36243
2026-04-03 12:19:04 +00:00
wxiaoguang 6eed75af24 Refactor code render and render control chars (#37078)
Fix #37057
2026-04-02 21:10:01 -07:00
wxiaoguang 7b17234945 Fix various problems (#37077)
Quick fix for 1.26.

* Slightly refactor NewComment to fix incorrect responses, remove
incorrect defer (still far from ideal)
* Avoid `const` causes js error in global scope
* Don't process markup contents on user's home activity feed, to avoid
js error due to broken math/mermaid code

* Fix #36582

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-04-03 10:25:45 +08:00
Zettat123 23c662ebb1 Support legacy run/job index-based URLs and refactor migration 326 (#37008)
Follow up #36842

Migration `326` can be prohibitively slow on large instances because it
scans and rewrites all commit status target URLs generated by Gitea
Actions in the database. This PR refactors migration `326` to perform a
partial update instead of rewriting every legacy target URL. The reason
for this partial rewrite is that **smaller legacy run/job indexes are
the most likely to be ambiguous with run/job ID-based URLs** during
runtime resolution, so this change prioritizes that subset while
avoiding the cost of rewriting all legacy records.

To preserve access to old links, this PR introduces
`resolveCurrentRunForView` to handle both ID-based URLs and index-based
URLs:

- For job pages (`/actions/runs/{run}/jobs/{job}`), it first tries to
confirm that the URL is ID-based. It does so by checking whether `{job}`
can be treated as an existing job ID in the repository and whether that
job belongs to `{run}`. If that match cannot be confirmed, it falls back
to treating the URL as legacy `run index + job index`, resolves the
corresponding run and job, and redirects to the correct ID-based URL.
- When both ID-based and index-based interpretations are valid at the
same time, the resolver **prefers the ID-based interpretation by
default**. For example, if a repository contains one run-job pair
(`run_id=3, run_index=2, job_id=4`), and also another run-job pair
(`run_id=1100, run_index=3, job_id=1200, job_index=4`), then
`/actions/runs/3/jobs/4` is ambiguous. In that case, the resolver treats
it as the ID-based URL by default and shows the page for `run_id=3,
job_id=4`. Users can still explicitly force the legacy index-based
interpretation with `?by_index=1`, which would resolve the same URL to
`/actions/runs/1100/jobs/1200`.
- For run summary pages (`/actions/runs/{run}`), it uses a best-effort
strategy: by default it first treats `{run}` as a run ID, and if no such
run exists in the repository, it falls back to treating `{run}` as a
legacy run index and redirects to the ID-based URL. Users can also
explicitly force the legacy interpretation with `?by_index=1`.
- This summary-page compatibility is best-effort, not a strict ambiguity
check. For example, if a repository contains two runs: runA (`id=7,
index=3`) and runB (`id=99, index=7`), then `/actions/runs/7` will
resolve to runA by default, even though the old index-based URL
originally referred to runB.

The table below shows how valid legacy index-based target URLs are
handled before and after migration `326`. Lower-range legacy URLs are
rewritten to ID-based URLs, while higher-range legacy URLs remain
unchanged in the database but are still handled correctly by
`resolveCurrentRunForView` at runtime.

| run_id | run_index | job_id | job_index | old target URL | updated by
migration 326 | current target URL | can be resolved correctly |
|---|---|---|---|---|---|---|---|
| 3 | 2 | 4 | 1 | `/user2/repo2/actions/runs/2/jobs/1` | true |
`/user2/repo2/actions/runs/3/jobs/4` | true |
| 4 | 3 | 8 | 4 | `/user2/repo2/actions/runs/3/jobs/4` | true |
`/user2/repo2/actions/runs/4/jobs/8` | true (without migration 326, this
URL will resolve to run(`id=3`)) |
| 80 | 20 | 170 | 0 | `/user2/repo2/actions/runs/20/jobs/0` | true |
`/user2/repo2/actions/runs/80/jobs/170` | true |
| 1500 | 900 | 1600 | 0 | `/user2/repo2/actions/runs/900/jobs/0` | false
| `/user2/repo2/actions/runs/900/jobs/0` | true |
| 2400 | 1500 | 2600 | 0 | `/user2/repo2/actions/runs/1500/jobs/0` |
false | `/user2/repo2/actions/runs/1500/jobs/0` | true |
| 2400 | 1500 | 2601 | 1 | `/user2/repo2/actions/runs/1500/jobs/1` |
false | `/user2/repo2/actions/runs/1500/jobs/1` | true |

For users who already ran the old migration `326`, this change has no
functional impact. Their historical URLs are already stored in the
ID-based form, and ID-based URLs continue to resolve correctly.

For users who have not run the old migration `326`, only a subset of
legacy target URLs will now be rewritten during upgrade. This avoids the
extreme runtime cost of the previous full migration, while all remaining
legacy target URLs continue to work through the web-layer compatibility
logic.

Many thanks to @wxiaoguang for the suggestions.
2026-04-02 17:23:29 -07:00
Nicolas 35b654c9d6 Add webhook name field to improve webhook identification (#37025) (#37040)
Add an optional Name field to webhooks so users can give them
human-readable labels instead of relying only on URLs. The webhook
overview page now displays names when available, or falls back to the
URL for unnamed webhooks.

Fixes #37025

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-01 09:56:20 +08:00
silverwind 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
wxiaoguang 6ca5573718 Refactor issue sidebar and fix various problems (#37045)
Fix various legacy problems, including:

* Don't create default column when viewing an empty project
* Fix layouts for Windows
* Fix (partially) #15509
* Fix (partially) #17705

The sidebar refactoring: it is a clear partial-reloading approach,
brings better user experiences, and it makes "Multiple projects" /
"Project column on issue sidebar" feature easy to be added.

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-31 10:03:52 +08:00
Nicolas db7eb4d51b Fix issue label deletion with Actions tokens (#37013)
Use shared repo permission resolution for Actions task users in issue
label remove and clear paths, and add a regression test for deleting
issue labels with a Gitea Actions token.

This fixes issue label deletion when the request is authenticated with a
Gitea Actions token.
Fixes #37011 

The bug was that the delete path re-resolved repository permissions
using the normal user permission helper, which does not handle Actions
task users. As a result, `DELETE
/api/v1/repos/{owner}/{repo}/issues/{index}/labels/{id}` could return
`500` for Actions tokens even though label listing and label addition
worked.

---------

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-03-29 09:21:14 +00:00
Nicolas b136a66d12 Restyle Workflow Graph (#36912)
Follow GitHub's style and fine tune colors & layouts.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-03-28 09:41:34 +00:00
ChristopherHX bc5c554072 Feature non-zipped actions artifacts (action v7) (#36786)
- content_encoding contains a slash => v4 artifact
- updated proto files to support mime_type and no longer return errors for upload-artifact v7
- json and txt files are now previewed in browser
- normalized content-disposition header creation
- azure blob storage uploads directly in servedirect mode (no proxying data)
- normalize content-disposition headers based on go mime package
  - getting both filename and filename* encoding is done via custom code

Closes #36829

-----

Signed-off-by: ChristopherHX <christopher.homberger@web.de>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-03-26 00:37:48 +08:00