Commit Graph

2051 Commits

Author SHA1 Message Date
Lunny Xiao
0b9623e188 fix: Fix the panic when ssh remote lfs endpoint parsing failure (#38026) (#38158)
Fix #38016
Backport #38026
2026-06-18 11:34:58 +03:00
bircni
99f8b3d9a1 fix: Various security fixes (#38103) (#38151)
Backport #38103

- Enforce org visibility on organization label read endpoints (private
org labels no longer leak to non-members).
- Block fork sync (`merge-upstream`) when the base repo is no longer
readable (stops pulling commits after a parent goes private).
- Remove `REVERSE_PROXY_LIMIT` / `REVERSE_PROXY_TRUSTED_PROXIES` from
the Docker `app.ini` templates (the `= *` default allowed
`X-WEBAUTH-USER` impersonation; reverse-proxy auth is now opt-in and
admin-configured).
- Enforce single-use TOTP passcodes across web login, password-reset,
and Basic-Auth `X-Gitea-OTP` (fixes a TOCTOU race and a stateless
replay).
- Re-check branch write permission for every ref in a push (the
pre-receive hook cached the first ref's result, letting a per-branch
maintainer-edit grant escalate to full repo write).

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-06-17 20:49:59 +00:00
Lunny Xiao
f6e2ca4388 fix(auth): ignore stale OIDC external login links to organizations (#37875) (#38141)
Backport #37875

This fixes an OIDC sign-in edge case where a stale `external_login_user`
record can still point to an organization or a deleted user.

In that situation, Gitea may keep resolving the external login to the
wrong account during sign-in. For affected instances, this matches the
behavior reported in #36439 and #37812, where a user signing in with
OIDC/Entra ID could appear as an organization, or hit a 404 after that
organization was removed.

- validate the user resolved from `external_login_user` during
OAuth2/OIDC login
- ignore stale links when the linked user no longer exists
- ignore stale links when the linked user is not an individual user
- remove the stale external login row so the sign-in flow can relink the
external account to the correct user

- Fixes #37812
- Related to #36439

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.8) <noreply@anthropic.com>
Co-authored-by: bircni <bircni@icloud.com>
2026-06-17 20:19:24 +00:00
bircni
5facdcc7fd fix: Various sec fixes (#38108) (#38147)
Backport #38108

- Enforce repository token scope on RSS/Atom feed endpoints so a PAT
without repo scope can no longer read private repo commit data.
- Block HTTP redirects during repository migration clones to prevent
SSRF reaching internal addresses via an attacker-controlled redirect.
- Redact the notification subject after repo access is revoked so
private issue/PR metadata is no longer leaked through the notification
API.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-06-17 21:43:22 +02:00
Giteabot
3bebddedc0 fix: git cmd (#38084) (#38087)
Backport #38084

fix #37370

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-06-12 21:28:13 +08:00
Giteabot
e107498f3b fix(actions)!: require merged PR to bypass fork PR approval gate (#38010) (#38041)
Backport #38010 by @bircni

`ifNeedApproval` in `services/actions/notifier_helper.go` decided
whether a
fork PR's workflow run had to wait for maintainer approval. The bypass
clause
counted any prior `approved_by > 0` run for `(repo_id,
trigger_user_id)`, so
the very first Approve-and-run click on a contributor's fork PR
permanently
trusted that user for every future fork PR in the same repository —
including
PRs whose only change is the workflow YAML itself.

Approving a workflow *run* is not the same as merging *code*. This
change
aligns the gate with GitHub Actions' first-time-contributor model: trust
is
granted only after the user has had a pull request merged in the repo.

## Behavior change

- **Before**: one approval = permanent trust for that user in that repo.
- **After**: every fork PR is gated until the contributor has at least
one
  merged PR in the repo.

Existing already-approved runs and merged PRs continue to work; only the
trust criterion for *future* fork PRs changes. Maintainers who rely on
the
implicit "approve once" trust will see the approval banner reappear
until
they merge a PR from that contributor.

---------

Signed-off-by: bircni <bircni@icloud.com>
Co-authored-by: bircni <bircni@icloud.com>
2026-06-09 15:53:42 +02:00
Giteabot
3b705738ab fix: bound CODEOWNERS regex match time (#38011) (#38025)
Backport #38011 by @bircni

User-supplied CODEOWNERS patterns were compiled without a match timeout,
so a crafted pattern (e.g. (a+)+) against a crafted file path could
backtrack for tens of seconds inside the PR creation transaction and
exhaust the database connection pool. Set MatchTimeout on each compiled
rule; the caller already treats match errors as non-matches.

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-06-07 16:40:34 +00:00
Dawid Góra
603c8ece00 fix(releases): generate notes for initial tag (#37697) (#37986)
Backport #37697

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

Automatic release notes for the first release in a repository were empty
when there was no previous tag.

Before this change, the release notes generator used the tag name to
build the changelog link, but reused that state for pull request
collection. When `PreviousTag` was empty, the PR collection logic did
not scan a useful commit range, so merged pull requests were omitted
from the generated notes.

This pull request fixes that by decoupling the internal PR collection
range from the rendered changelog link:
- when a previous tag exists, behavior stays unchanged
- when no previous tag exists, release notes collect merged pull
requests from the full reachable history up to the target tag
- the displayed full changelog link for the first release still uses the
existing `/commits/tag/{tag}` format

Tests were updated to cover:
- generating notes for a repository with no previous tags
- including merged pull requests before the first tag
- preserving existing behavior when a previous tag exists

<!--
Before submitting:
- Target the `main` branch; release branches are for backports only.
- Use a Conventional Commits title, e.g. `fix(repo): handle empty branch
names`.
- Read the contributing guidelines:
https://github.com/go-gitea/gitea/blob/main/CONTRIBUTING.md
- Documentation changes go to https://gitea.com/gitea/docs

Describe your change below and link any issue it fixes.
-->

Co-authored-by: OpenAI GPT-5.5 <openai-gpt-5.5@users.noreply.github.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-06-05 19:13:16 +00:00
Giteabot
8bf445e86a fix(actions): reject workflow_dispatch for workflows without that trigger (#37660) (#37895)
Backport #37660 by @jorgeortiz85

## Summary

Fixes #37528

This PR makes the workflow dispatch API reject workflows that do not
declare `workflow_dispatch`. Previously, `POST
/repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches` could
create an `ActionRun` for a workflow that only declared another event
such as `push`.

The service now validates that the target workflow has a
`workflow_dispatch` trigger before inserting the run. The API maps that
validation failure to `422 Unprocessable Entity`, matching existing
validation failures in this handler.

The regression test creates a push-only workflow, dispatches it through
the public API, asserts the `workflow_dispatch` validation message, and
verifies that no run was inserted.

## Testing

- `go test ./services/actions`
- `TAGS="sqlite sqlite_unlock_notify" make
test-integration#TestWorkflowDispatchPublicApiRequiresWorkflowDispatchTrigger`
- `TAGS="sqlite sqlite_unlock_notify" make
test-integration#TestWorkflowDispatchPublicApi`

## Disclosure

Developed with assistance from OpenAI Codex.

Co-authored-by: Jorge Ortiz <jorge.ortiz@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-29 05:09:08 +02:00
Lunny Xiao
a34eac5ef4 fix: Unify public-only token filtering in API queries and repo access checks (#37118) (#37773)
backport #37118 

This PR closes remaining `public-only` token gaps in the API by making
the restriction apply consistently across repository, organization,
activity, notification, and authenticated `/api/v1/user/...` routes.

Previously, `public-only` tokens were still able to:
- receive private results from some list/search/self endpoints,
- access repository data through ID-based lookups,
- and reach several authenticated self routes that should remain
unavailable for public-only access.

This change treats `public-only` as a cross-cutting visibility boundary:
- list/search endpoints now filter private resources consistently,
- repository lookups enforce the same restriction even when addressed
indirectly,
- and self routes that inherently expose or mutate private account state
now reject `public-only` tokens.

---
Generated by a coding agent with Codex 5.2

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-19 15:38:51 +00:00
Giteabot
1b70a4451a fix: add natural sort to sortTreeViewNodes (#37772) (#37777)
Backport #37772

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Lavamini Inc <jianwangqau@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-19 09:53:45 +00:00
Giteabot
bc29cd0d3d fix: package creation unique conflict (#37774) (#37776)
Backport #37774

fix #30973

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-05-19 08:58:09 +00:00
Giteabot
58597cc30a fix: Allow direct commits for unprotected files with push restrictions (#37657) (#37756)
Backport #37657 by @bircni

Fixes an issue where users could not commit changes on a file which is
unprotected.

Fixes #37655

Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 06:11:19 +00:00
Giteabot
2965b0c08a fix(web): enforce token scopes on raw, media, and attachment downloads (#37698) (#37733) 2026-05-16 18:18:44 +02:00
Giteabot
519b8d6d88 fix(security): enforce wiki git writes and LFS token access at request time (#37695) (#37714)
Backport #37695 by @lunny

This PR fixes two permission-checking gaps in Git and LFS request
handling.

## What it changes

- keep wiki Git HTTP pushes on the normal write-permission path, even
when proc-receive support is enabled
- revalidate LFS bearer token requests against the current user state
and current repository permissions before allowing access
- add regression coverage for unauthorized wiki HTTP pushes
- add LFS tests for blocked users, revoked repository access, read-only
upload attempts, and valid write access

## Why

- wiki repositories should not inherit the relaxed refs/for handling
used for normal code repositories
- LFS authorization tokens should not remain usable after a user is
disabled or loses repository access

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-05-16 06:58:28 +00:00
Zettat123
7b82ded82a fix(actions): deadlock between PrepareRunAndInsert and UpdateTaskByState (#37692) (#37718) 2026-05-16 07:02:14 +02:00
wxiaoguang
1d5163133b fix(repo): /generate must sync the branch table for the new repo (#37693) (#37712)
Backport #37693
2026-05-16 01:54:48 +08:00
Giteabot
0e53c41694 feat(api): encrypt AWS creds (#37679) (#37713)
Backport #37679 by @Exgene

## Description

As mentioned in #37654 `AWSAccessKeyID` and `AWSSecretAccessKey` are not
encrypted and stored as is.

## Update

Follow the existing `AuthToken` flow of setting the `Encrypted` fields,
`Decrypting` them later and `Clearing` them at the end.

Closes #37654

Signed-off-by: Kausthubh J Rao <105716675+Exgene@users.noreply.github.com>
Co-authored-by: Kausthubh J Rao <105716675+Exgene@users.noreply.github.com>
Co-authored-by: Lauris B <lauris@nix.lv>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-05-15 15:58:19 +02:00
Nicolas
a55be951e3 Compare dropdown fails when selecting branch with no common merge-base (#37470) (#37472)
## Summary

- handle compare requests where base and head refs have no common merge
base without returning 500
- keep the compare branch selectors usable and show a clear warning
message
- add regression coverage for unrelated-history compare selection and
merge-base error detection

Fixes #37469 



Manuel Backport of: https://github.com/go-gitea/gitea/pull/37470

---------

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-05-08 19:08:36 +00:00
Giteabot
65f3feaa84 fix: treat email addresses case-insensitively (#37600) (#37611) 2026-05-08 18:32:25 +00:00
Giteabot
677ab982bf fix(git): Fix smart http request scope bug (#37583) (#37605)
Backport #37583 by @lunny

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-05-08 09:14:41 -07:00
Giteabot
e10da87ebe fix(actions): report individual step status in workflow job API response (#37592) (#37598)
Backport #37592 by @bircni

When a workflow job failed, the API response reported all steps as
failed — even steps that had completed successfully before the failing
step. `ToActionWorkflowJob` was calling `ToActionsStatus(job.Status)`
for every step instead of `ToActionsStatus(step.Status)`, so the job's
overall conclusion was propagated to each step.

Each `ActionTaskStep` has its own `Status` field that tracks the actual
outcome of that step independently of the job result.

Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-05-08 00:14:45 +02:00
wxiaoguang
3004c45607 fix: Invalid UTF-8 commit messages in JSON API responses (#37542) (#37585)
Backport #37542

Co-authored-by: Nicolas <bircni@icloud.com>

---------

Co-authored-by: Nicolas <bircni@icloud.com>
2026-05-07 16:22:09 +00:00
Giteabot
7d77631881 fix: use consistent GetUser family functions (#37553) (#37589)
Backport #37553

fixes adding collaborative owners in Actions settings when the user or
organization name contains capital letters.

Fixes #37548

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-05-07 15:43:45 +00:00
Giteabot
b79529015e Don't unblock run-level-concurrency-blocked runs in the resolver (#37461) (#37538)
Backport #37461 by @silverwind

Fixes #37446.

The job-status resolver in `checkJobsOfCurrentRunAttempt` only
considered `needs` and job-level concurrency when transitioning jobs out
of `Blocked`. When something drove the resolver against a run blocked
solely by workflow-level concurrency — for example, a sibling run in the
same group entering the queue and triggering `EmitJobsIfReadyByRun` —
the run's job silently became `Waiting` while another run still held the
concurrency group, and the runner could pick it up, defeating the
concurrency guarantee.

The fix bails out of the resolver when the run's latest attempt is still
blocked by run-level concurrency. `checkRunConcurrency` re-evaluates
when the holding run finishes.

Covered by a unit test
(`Test_checkJobsOfCurrentRunAttempt_RunLevelConcurrencyKeepsJobsBlocked`
in `services/actions/job_emitter_test.go`) that sets up a Running holder
attempt and a Blocked sibling attempt in the same concurrency group
directly in the DB, calls `checkJobsOfCurrentRunAttempt`, and asserts
the blocked job stays `Blocked`. Fails on master, passes with the fix.

---
This PR was written with the help of Claude Opus 4.7

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-05-04 13:37:20 -07:00
Giteabot
dd78d87dcd fix: merge autodetect can't close other PRs but only the last one when multiple PRs are pushed at once (#37512) (#37516)
Backport #37512

Fixes #37510.

Co-authored-by: Jason Learst <jason@jasonlearst.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-05-03 01:15:56 -07:00
Giteabot
e2b211f291 Fix update branch protection order (#37508) (#37513)
Backport #37508 
Regression of changed behavior or Golang JSON v2 package

Fix #37506

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-05-02 19:10:50 +00:00
Giteabot
8a49e9d346 Fix mCaptcha broken after Vite migration (#37492) (#37509) 2026-05-02 18:20:52 +02:00
Nicolas
b88bad2a01 Fix basic auth bug (#37503)
Backport for #37486
2026-05-02 10:58:40 +00:00
Giteabot
4ee74d7699 FIX: URL sanitization to handle schemeless credentials (#37440) (#37471)
Backport #37440 by @bircni

Fixes #37435

Co-authored-by: Nicolas <bircni@icloud.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-28 21:35:18 +00:00
Giteabot
c4a1ff7d16 Fix scheduled action panic with null event payload (#37459) (#37466)
Backport #37459 by cyphercodes

This fixes the scheduled action panic when an event payload is JSON
`null` by initializing the payload map before adding `schedule`. It also
adds regression coverage for the null-payload case.

Fixes #37447.

Co-authored-by: Rayan Salhab <r.salhab@aiyexpertsolutions.com>
Co-authored-by: cyphercodes <cyphercodes@users.noreply.github.com>
Co-authored-by: Hermes Agent (GPT-5.5) <hermes-agent@users.noreply.github.com>
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-28 05:07:26 +00:00
wxiaoguang
fb3c1b031d Add CurrentURL template variable back (#37444) (#37449)
Backport #37444
2026-04-27 21:05:24 +08:00
wxiaoguang
cff6eb5661 Make GetPossibleUserByID can handle deleted user (#37430) (#37431)
Backport #37430
2026-04-27 00:33:09 +08:00
Giteabot
5d7768f34c Fix repo init README EOL (#37388) (#37399)
Backport #37388 by @wxiaoguang

Fix #27120

By the way, refactor ReserveLineBreakForTextarea to NormalizeStringEOL

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-23 23:33:25 +00:00
Giteabot
55a6cfe79b Fix org team assignee/reviewer lookups for team member permissions (#37365) (#37391)
Backport #37365 by @pisarz77

Fix team members missing from assignee list when `team_unit.access_mode`
is 0 but the doer is owner.

Fix  #34871

1. Use `GetTeamUserIDsWithAccessToAnyRepoUnit` for repo assignee list
2. Load assignee list for project issues directly
3. Use `GetTeamUserIDsWithAccessToAnyRepoUnit` for repo reviewer list

Signed-off-by: Jakub Pisarczyk <pisarz77@gmail.com>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: pisarz77 <pisarz77@gmail.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-23 21:15:53 +02:00
Giteabot
1f643072c1 fix: commit status reporting (#37372) (#37386)
Backport #37372 by @bircni

Fixes the issue that status report always shows waiting to run, when
already running

https://github.com/go-gitea/gitea/issues/36906#issuecomment-4294545813

Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-23 16:43:32 +02:00
Giteabot
fc9dfe0e56 fix: use TriggerEvent instead of Event in workflow runs API response for scheduled runs (#37288) (#37360)
Backport #37288 by @KalashThakare

## Summary

Fixes #37252

The `/api/v1/repos/{owner}/{repo}/actions/runs` endpoint was returning
`event: "push"` for workflow runs triggered by `schedule:` (cron),
instead
of `event: "schedule"`.

## Root Cause

`ActionRun` has two separate fields:
- `Event` — the workflow registration event (e.g. `push`, set when the
workflow file was first pushed)
- `TriggerEvent` — the actual event that triggered the run (e.g.
`schedule`)

`ToActionWorkflowRun` in `services/convert/action.go` was serializing
`run.Event` into the API response instead of `run.TriggerEvent`, causing
scheduled runs to be indistinguishable from push events via the API.

This was already asymmetric — the tasks/jobs API correctly used
`TriggerEvent`.

## Fix

Changed `ToActionWorkflowRun` to use `run.TriggerEvent` for the `event`
field in the API response, consistent with how the jobs API works.

## Before

`event: "push"` returned for all scheduled runs:

<img width="1112" height="191" alt="Screenshot 2026-04-19 115642"
src="https://github.com/user-attachments/assets/c0a169f5-bbd9-4f5d-9474-e4c3795110e4"
/>

## After

`event: "schedule"` correctly returned for scheduled runs:

<img width="890" height="166" alt="Screenshot 2026-04-19 121723"
src="https://github.com/user-attachments/assets/860e99ac-0935-4a43-86a1-7b60f8113480"
/>


## Testing

- Added unit test `TestToActionWorkflowRun_UsesTriggerEvent` in
  `services/convert/action_test.go` that explicitly verifies the API
  returns `TriggerEvent` and not `Event` for a scheduled run.
- Manually verified via the API against a live Gitea instance with a
  `cron: "* * * * *"` workflow.

Co-authored-by: Kalash Thakare ☯︎ <kalashthakare898@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-04-22 18:39:10 +02:00
Giteabot
0916039c2a Add event.schedule context for schedule actions task (#37320) (#37348)
Backport #37320 by @lunny

Fix #35452

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-21 21:45:12 +00:00
Giteabot
291f6cbd3a Fix an issue where changing an organization’s visibility caused problems when users had forked its repositories. (#37324) (#37344)
Backport #37324 by @lunny

A quick fix #37317

---

The current behavior for forks when an organization or repository is
changed to private differs from GitHub.

On GitHub, when a parent repository becomes private, the fork
relationship is removed, which keeps the behavior simple and avoids
visibility conflicts.

I think we need a similar solution to handle cases where the parent
repository becomes private while a fork remains public and the fork
relationship is still preserved.

Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-21 19:22:35 +00:00
Giteabot
f536bcd508 Use modern "git update-index --cacheinfo" syntax to support more file names (#37338) (#37343)
Backport #37338 by @wxiaoguang

Modern syntax was added in git 2.0

And add more tests

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-21 18:41:40 +00:00
Giteabot
fc4296a21a Fix URL related escaping for oauth2 (#37334) (#37340)
Backport #37334 by wxiaoguang

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-21 17:11:19 +00:00
Giteabot
7bd55deab3 Fix actions concurrency groups cross-branch leak (#37311) (#37331)
Backport #37311 by @silverwind

## Problem

Workflow-level concurrency groups were evaluated — and jobs were parsed
— before the run was persisted, so `run.ID` was `0` and `github.run_id`
in the expression context resolved to an empty string. Expressions like:

```yaml
concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  cancel-in-progress: true
```

collapsed to `<workflow>-` on every push event (`head_ref` is empty on
push), so `cancel-in-progress` cancelled in-progress runs across
**unrelated branches**, not just the current one.

Reproduced on a 1.26 instance:
- push to `master` → `ci` run starts
- push to `feature-branch` → the `master` run gets cancelled

GitHub Actions' documented semantic: on push events `github.run_id` is
unique per run, so the group is unique → no cancellation; on PR events
`github.head_ref` is the source branch → cancellation is per-PR.

## Fix

Insert the run **before** parsing jobs or evaluating workflow-level
concurrency, so `run.ID` is populated in time for every expression that
reads `github.run_id` — not just the concurrency group, but also
`run-name`, job names, and `runs-on`.

`jobparser.Parse` now runs inside the `InsertRun` transaction, after
`db.Insert(ctx, run)`. Workflow-level concurrency evaluation runs next
and only mutates `run` in memory. All concurrency-derived fields
(`raw_concurrency`, `concurrency_group`, `concurrency_cancel`) plus
`status` and `title` are persisted in a single final `UpdateRun` at
end-of-transaction — one `INSERT` + one `UPDATE` per run in both the
concurrency and non-concurrency paths (matches pre-branch parity, one
fewer `UpdateRepoRunsNumbers` `COUNT` than the interim state).

`GenerateGiteaContext` now sets `run_id` from `run.ID` unconditionally;
every caller passes a persisted run.

**Verification**: tested end-to-end on a 1.26 deployment. Before the
patch, two successive `ci` pushes (one to master, one to a feature
branch) cross-cancelled each other. After the patch, the same pushes —
in both orders (master→branch, branch→master) — run to completion
simultaneously across 15+ runs with zero cancellations.

**Regression tests** in `services/actions/context_test.go`:
- `TestEvaluateRunConcurrency_RunIDFallback` — unit check that
`EvaluateRunConcurrencyFillModel` resolves `github.run_id` from
`run.ID`.
- `TestPrepareRunAndInsert_ExpressionsSeeRunID` — full-flow check: calls
`PrepareRunAndInsert` with `${{ github.run_id }}` in both `run-name` and
the concurrency group, then asserts the persisted `Title`,
`ConcurrencyGroup`, and `RawConcurrency` contain / survive the run's ID.
Re-ordering `db.Insert` relative to either parse or concurrency eval
fails this test.

## Relation to #37119

[#37119](https://github.com/go-gitea/gitea/pull/37119) also moves
concurrency evaluation into `InsertRun` but keeps it **before**
`db.Insert`, then tries to populate `run_id` only when `run.ID > 0` —
which is still `0` at that call site, so the cross-branch leak would
survive that PR as written. This PR fixes the ordering so that `run.ID`
is actually populated at eval time, and broadens it to cover parse-time
expression interpolation too.

---
This PR was written with the help of Claude Opus 4.7

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-21 10:04:01 +02:00
Giteabot
f0fd185f14 Fix AppFullLink (#37325) (#37328)
Backport #37325 by @lunny

Fix a bug the checkout command line hint become `git fetch -u
https://gitea.combircni/tea`

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-04-21 02:04:01 +00:00
Giteabot
ba5117e4e4 Enhance GetActionWorkflow to support fallback references (#37189) (#37283)
Backport #37189 by @bircni

If a workflow is not in default branch the hooks could not be detected

Fixes #37169

Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 21:13:54 +00:00
Giteabot
2aca966c5f Fix incorrect concurrency check (#37205) (#37215)
Backport #37205 by @Zettat123

This bug was identified in
https://github.com/go-gitea/gitea/pull/37119/changes#diff-37655a02d5a44d5c0e3e19c75fb58adb47a8e7835cbd619345d5b556292935a7L180

Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-04-14 17:58:31 +00:00
wxiaoguang
3b253e06a3 Fix corrupted JSON caused by goccy library (#37214) (#37220)
Backport #37214

The only conflict is go.mod

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-04-14 17:24:39 +00: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
Rohan Guliani
1b200dc3da Add support for RPM Errata (updateinfo.xml) (#37125)
Resolves https://github.com/go-gitea/gitea/issues/37124

This PR adds support for RPM Errata (security advisories, bugfixes, and
enhancements) to Gitea's built-in RPM registry.

---------

Signed-off-by: Rohan Guliani <rohansguliani@google.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-08 00:39:53 +08:00
TheFox0x7
ff777cd2ad Add terraform state registry (#36710)
Adds terraform/opentofu state registry with locking. Implements: https://github.com/go-gitea/gitea/issues/33644. I also checked [encrypted state](https://opentofu.org/docs/language/state/encryption), it works out of the box.

Docs PR: https://gitea.com/gitea/docs/pulls/357

---------

Co-authored-by: Andras Elso <elso.andras@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-06 13:41:17 -07: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