- Introduce a “Bypass Protection Allowlist” on branch rules
(users/teams) alongside admins, with BlockAdminMergeOverride
still respected.
- Surface the allowlist in API (create/edit options, structs) and
settings UI; merge box now shows the red button +
message for bypass-capable users.
- Apply bypass logic to merge checks and pre-receive so allowlisted
users can override unmet approvals/status checks/
protected files when force-merging.
- Add migration for new columns, locale strings, and unit tests (bypass
helper; queue test tweak).
<img width="1069" height="218" alt="image"
src="https://github.com/user-attachments/assets/0b61bc2a-a27f-47f3-a923-613688008e65"
/>
Fixes#36476
---------
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Giteabot <teabot@gitea.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Codex GPT-5.3 <codex@openai.com>
Co-authored-by: GPT-5.2 <noreply@openai.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Adds `sort` and `order` query parameters to all action job list API
endpoints (`/admin/actions/jobs`, `/repos/{owner}/{repo}/actions/jobs`,
`/repos/{owner}/{repo}/actions/runs/{run}/jobs`, `/user/actions/jobs`),
following the existing `OrderByMap` pattern used by repo/user search
endpoints.
- Default is `id` / `asc` (backwards compatible — matches previous DB
natural order)
- Only `id` sort field for now; the map is extensible for future fields
- Returns 422 for invalid sort/order values
- `ToOrders()` returns empty string when `OrderBy` is unset, so internal
callers (webhook dispatch, concurrency checks) are unaffected
Closes: #37666
Supersedes: #37667
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: silverwind <me@silverwind.io>
## Summary
When comparing branches with **no common merge base** (e.g. unrelated
histories or orphan branches), `PageIsComparePull` is false and
`CommitCount` is zero. The compare template still showed
`repo.commits.nothing_to_compare`, which in German reads like the
branches are identical—even though the flash already explains there is
no merge base.
## Changes
- **`templates/repo/diff/compare.tmpl`**: Only render the grey “nothing
to compare” segment when `CompareInfo.CompareBase` is set.
<img width="1962" height="564"
src="https://github.com/user-attachments/assets/adc3b4a0-6f03-45da-b297-e15e5ad0aa79"
/>
Fixes#37642
---------
Signed-off-by: Nicolas <bircni@icloud.com>
- Replace fomantic `search` code with minimal first-party code
- Added a small fix to vertically align search box and search button
- Manually tested all search forms.
- Add `errorName` helper, similar to `errorMessage`.
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
This PR adds a new repository API field, `mirror_last_sync_at`, to
expose the timestamp of the last successful pull mirror sync.
Unlike `mirror_updated`, this field does not affect mirror scheduling
and is updated only after a successful pull sync. Failed sync attempts
leave the value unchanged.
What changed
- added `mirror_last_sync_at` to the repository API response
- updated pull mirror sync flow to persist the timestamp only on
successful sync
- kept `mirror_updated` behavior unchanged for queue/scheduling purposes
`mirror_updated` is currently tied to mirror queue behavior, so it
cannot safely represent the last successful sync time. The new field
makes that state explicit for API consumers without changing scheduling
semantics.
---------
Signed-off-by: pomidorry <106489913+Pomidorry@users.noreply.github.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>
Co-authored-by: Giteabot <teabot@gitea.io>
Action runs, jobs and steps have 8 statuses but the UI only showed 5
(from the commit status api) for the latter two. Align all 8 to GitHub
as closely as possible:
- waiting — `octicon-circle` (hollow circle), gray
- blocked — `octicon-blocked` (slashed circle), yellow
- running — `gitea-running` (rotating spinner), yellow
- cancelled — `octicon-stop` (gray), was `octicon-x` (red)
Descriptions also aligned with GitHub:
- "Has started running" → "In progress"
- "Has been cancelled" → "Cancelled after {dur}"
- "Has been skipped" → "Skipped"
Fixes: https://github.com/go-gitea/gitea/issues/32228
---------
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
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>
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>
Purpose:
1. Make the whole code base have unified "item" layout
2. Clarify our "list" styles: "flex-relaxed-list", "flex-divided-list"
3. Prepare to replace legacy "ui relaxed list"
* https://github.com/go-gitea/gitea/pull/37445#discussion_r3144458865
4. Prepare for refactoring the "pull merge box", it needs the
"flex-divided-list"
* related to "Refactor pull request view (*)" like #37451
5. Fix legacy abuses of "flex-list", e.g.: repo home sidebar
After the Webpack-to-Vite migration (#37002), mCaptcha stopped working
entirely on the registration page, throwing an error:
`TypeError: setting getter-only property "INPUT_NAME"`
This fix stops trying to mutate the read-only INPUT_NAME export. Instead
it probes for the Widget constructor at module.default (direct) or
module.default.default (CJS-wrapped), constructs the widget, and then
renames the hidden input element it creates to m-captcha-response which
is the field name Gitea's backend reads from the submitted form.
Generative AI was used to help with making this PR.
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
Clean up legacy copied&pasted code, introduce the unique "database
connection" function. Move migration testing helper function
PrepareTestEnv to a separate package.
By the way, remove "shadow connection secrets" tricks: showing
connection string on UI is useless
---------
Co-authored-by: Nicolas <bircni@icloud.com>
## 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.
##
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>
Add a build-time conversion step that transforms the existing Swagger
2.0 spec into an OpenAPI 3.0 spec. The OAS3 spec is served alongside the
existing Swagger 2.0 spec, enabling API clients that require OAS3 to
generate code directly from Gitea's API.
This is not to be an answer to how gitea handles OAS3 long term,
but a way to use what we have to move a step forward.
---------
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
After using CSP nonce, the "onerror" doesn't work anymore. Change it to
use a global variable to detect
Also help users like #37379 to catch errors more easily.
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
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>
- fix markup attention block regressions on 2 colors
- added new color "priority" color for important severity in markup
- all message-box style, and error form elements use monochrome text
- tweaked and improved action logs colors
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Clean up the fomantic helpers that nothing inside fomantic depends on.
Manually tested all functionality.
---------
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
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>
Extend the issue context popup beyond markdown. Any link rendered with
the `ref-issue` class now gets the popup, which covers commit titles and
issue titles everywhere they appear (repo home, commits list, blame,
branches, graph, PR commits, issue/PR pages, compare, …). For surfaces
that synthesize links without markdown autolinking (dashboard activity
feed, pulse page, commit merged-PR line), opt in by adding
`data-ref-issue-container` on a parent (or `ref-issue` on the link).
- Use `html_url` from the backend payload instead of synthesizing links
client-side
- Fetch outside the component, stateless, with a per-URL cache
- Small hover delay so passing over a link doesn't fire a request
- Drop the loading state (shifted layout)
- Make both links in the tooltip work; prevent nested tooltips
- Fix feed title `<a>` width so the tooltip only shows on link hover
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
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
Use the new "form-fetch-action" for better user experience, and use
JSONError to show error messages.
---------
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Follow up #37327. See the comments.
* Root problem: the design of OAuth2 providers is a mess, the display
name is used as provider's name and used in the URL directly
* The regressions:
* When trying to fix https://github.com/go-gitea/gitea/issues/36409 , it
introduced inconsistent URL escaping for the "path" part.
* This fix: always use "path escaping" for the path part, add more tests
to cover all escaping cases.
Now, frontend "pathEscape" and "pathEscapeSegments" generate exactly the
same result as backend.
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>
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>