Compare commits

..

73 Commits

Author SHA1 Message Date
Giteabot d141dc729c fix: delete repo-scoped rows of seven more tables when deleting a repository (#38534) (#38618)
Backport #38534 by @luuuc

Fixes #38494

`DeleteRepositoryDirectly` left rows behind in seven registered tables
carrying a repo-scoped key: `action_variable`, `action_run_attempt`,
`action_tasks_version`, `renamed_branch`, `commit_status_summary`,
`commit_status_index` and `repo_transfer`. Repository IDs are `pk
autoincr` and never reissued, so the orphaned rows were unreachable, but
they accumulated forever (unbounded table growth, referential
inconsistency; not a security issue, see the issue discussion).

This adds all seven to the `deleteBeans` cascade, each placed next to
its sibling bean
(`CommitStatus`/`CommitStatusIndex`/`CommitStatusSummary`,
`Branch`/`RenamedBranch`, `Secret`/`ActionVariable`,
`ActionRun`/`ActionRunAttempt`). `repo_transfer` goes through the same
cascade rather than `DeleteRepositoryTransfer` so teardown stays one
mechanism; the existing reaper remains for the transfer flows.

The test inserts one row per previously-orphaned table (the fixture
files ask test cases to prepare their own data), deletes the repository,
and asserts each table is purged. Without the fix it fails on all seven
tables.

As discussed in the issue, this is the first of the two suggested steps;
the reflection-driven enforcement sweep over registered repo-keyed
models (with an explicit exemption list, e.g. head-repo PRs) can follow
in a separate PR.

PS: this was found while benchmarking
[Sense](https://github.com/luuuc/sense) against the gitea codebase (the
cross-reference method is described in the issue).

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Signed-off-by: Luc <luuuc@users.noreply.github.com>
Co-authored-by: Luc <luuuc@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-24 21:25:31 +02:00
Giteabot 27fed5a83a fix(webhook): remove slack channel name check (#38608) (#38612)
Backport #38608 by @chlee1001

Users should know what they are doing, don't check everything,
especially for that we don't understand.

Fixes #23840

Co-authored-by: Chaehyeon Lee <chlee1001@naver.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-24 08:09:05 +00:00
Giteabot 6cdd02bdad fix: download dropdown menu clipped on the branches page (#38604) (#38609)
Backport #38604

Fixes #38603

Co-authored-by: Richard Mahn <richmahn@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-24 12:47:37 +08:00
Giteabot cc4ee6387b fix(oauth2): enforce mandatory 2FA policy on OAuth2 authorize/grant endpoints (#38591) (#38606)
Backport #38591

Co-authored-by: Mitrahsoft <bala.c@mitrahsoft.in>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-23 20:13:13 -07:00
Giteabot 4780cffe08 fix(project): prevent database mutations on invalid MoveIssues payload (#38600) (#38602)
Backport #38600

Signed-off-by: Sudhanshu Singh <sudhanshuwriterblc@gmail.com>
Co-authored-by: Shudhanshu Singh <sudhanshuwriterblc@gmail.com>
2026-07-23 16:14:57 +00:00
Giteabot 483fb19b37 fix(actions): make SingleWorkflow.Marshal round-trip multi-line run blocks (stop silent job stranding) (#38520) (#38599)
Backport #38520 by @darklight147

## Problem
Jobs that call a reusable workflow (`uses:`) whose steps contain a `run:
|` block that **starts with blank lines** never start — the child jobs
stay `Blocked` forever, the run never finishes, and nothing is shown to
the user (the error is only logged at DEBUG). The reusable is valid YAML
and worked on 1.26.

## Root cause
`jobparser` serializes each expanded job via `SingleWorkflow.SetJob()`,
which uses `yaml.NewEncoder(...).SetIndent(2)`, but
`SingleWorkflow.Marshal()` used `yaml.Marshal`, whose default
indentation is **4**. Re-emitting a multi-line literal block scalar at a
different indentation makes the encoder write a wrong explicit
indentation indicator (`run: |4`) whose declared indent doesn't match
the actual content indent. The stored `workflow_payload` is then
unparseable:

```
run: |4


                while ...
```

`jobparser.Parse` / `model.ReadWorkflow` (both go.yaml.in/yaml/v4)
reject it: `did not find expected key`. This surfaces in
`services/actions/job_emitter.go` `resolve()` →
`updateConcurrencyEvaluationForJobWithNeeds` → `ParseJob`, where the
error is swallowed at `log.Debug` and the job is left `Blocked`.

Encoding at indent 4 triggers the bad indicator; indent 2 does not —
matching the value already used by `SetJob`.

## Fix
Encode `SingleWorkflow.Marshal()` with `SetIndent(2)` so both encoders
agree and the serialized single workflow round-trips. Adds a regression
test (`Parse → Marshal → Parse` on a `run:` block with leading blank
lines) that fails before the change with `did not find expected key`.

## Notes
- This is the correctness fix. Related: #37116 added
`ValidateWorkflowContent` to *report* such content for top-level
workflows, but the reusable-expansion/concurrency-eval path is not
covered and strands silently — this fix removes the failure mode
entirely.
- Consider a follow-up to elevate the swallowed error in
`job_emitter.resolve()` from `log.Debug` to a user-visible job failure
(there is an existing `// TODO`).

Signed-off-by: quasimodo <mohamed.belkamel@intelcia.com>
Co-authored-by: Mohamed Belkamel <39389636+darklight147@users.noreply.github.com>
Co-authored-by: quasimodo <mohamed.belkamel@intelcia.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
2026-07-23 14:23:32 +00:00
Giteabot 560535a97f fix(api): align Swagger schemas for UserSettings and TopicListResponse (#38590) (#38592)
Backport #38590

Signed-off-by: Sudhanshu Singh <sudhanshuwriterblc@gmail.com>
Co-authored-by: Shudhanshu Singh <sudhanshuwriterblc@gmail.com>
2026-07-23 07:27:47 +00:00
Giteabot 62c61aa8ce fix(file-tree): handle submodule links and missing view container (#38033) (#38589)
Backport #38033

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: yszl666 <941131649@qq.com>
Co-authored-by: dzf <douzf@sparkspacetech.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-23 10:17:34 +08:00
Giteabot 337fa5a950 fix(actions): fail unexpandable reusable workflow callers and decouple the job emitter's cross-run processing (#38565) (#38587)
Backport #38565 by @Zettat123

## Changes

### 1. Handle reusable workflow expansion failures

If a reusable workflow caller job is invalid (e.g. uses a workflow with
syntax error), the job emitter should mark it as failed instead of
retrying.

Related:
https://github.com/go-gitea/gitea/pull/38518#discussion_r3608882095

### 2. No longer process concurrent run inline

**Before**: If a run(R1)'s status change unlocks another blocked run(R2)
via concurrency group, the job emitter will process R2 in R1's
transaction.

**Current**: No longer process R2 inline and emit the ID of R2 to let
another pass process it.

Co-authored-by: Zettat123 <zettat123@gmail.com>
2026-07-22 23:35:28 +02:00
Giteabot ad84c14d53 fix: keep serving valid ACME cert when renewal fails at startup (#38554) (#38583)
Backport #38554 by @Otto-Deviant1904

Fix #38519

When `ENABLE_ACME` renew fails during startup (e.g. CA unreachable),
`ManageSync` currently aborts even if a still-valid certificate is on
disk, so HTTPS never comes up.

If `CacheManagedCertificate` finds a non-expired cert, log the manage
error, continue with that cert, and kick `ManageAsync` for background
retries. First-time install / expired-or-missing cert still fails
closed.

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Harsh Satyajit Thakur <f20240223@goa.bits-pilani.ac.in>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-22 19:59:56 +00:00
Giteabot 65ea4079ce fix: branch protection user list (#38570) (#38584)
Backport #38570 by @wxiaoguang

fix #38569, also fix the UI

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-22 21:36:12 +02:00
Giteabot 1cf54fed70 fix(pulls): respect diff.orderFile in diff file tree (#38566) (#38578)
Backport #38566 by @eliroca

Co-authored-by: Elisei Roca <eroca@suse.de>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-22 18:14:16 +00:00
Giteabot 1ae686696e fix(issue): make issue action (issue list batch operation) elements have correct attributes (#38575) (#38580)
Backport #38575 by @SudhanshuMatrix

The "Clear projects" action in the issue list batch operations doesn't
work. When users select multiple issues and choose to clear their
project assignments, the operation fails because:

1. The frontend sends a project ID of `0` to represent "no project"
2. The backend passes this invalid ID directly to
`IssueAssignOrRemoveProject` without filtering
3. The backend tries to look up a project with ID `0`, which doesn't
exist, resulting in a `project 0 not found` error
4. Selected issues remain assigned to their projects instead of being
removed

Fixes #38571 

## Root Cause

The issue is a regression from the multi-project feature (#36784). The
frontend was using `data-element-id="0"` to represent "clear" actions,
but the backend doesn't filter out this invalid ID before validation.

## Solution

### Template Changes (`templates/repo/issue/filter_actions.tmpl`)
- Changed `data-element-id="0"` to `data-element-id=""` for the "Clear
projects" action (line 78)
- Changed `data-element-id="0"` to `data-element-id=""` for the "Clear
milestone" action (line 47)
- Removed the duplicate "no select" assignee option that was using
`data-element-id="0"` (lines 116-118)

### Frontend Logic Changes (`web_src/js/features/repo-issue-list.ts`)
- Made `elementId` a `const` instead of `let` (line 60) to prevent
mutations
- Removed the workaround code that was trying to handle
`data-element-id="0"` for assignees (lines 65-69)
- Updated comment from "for toggle" to "for label toggle" for clarity
(line 71)

Signed-off-by: Sudhanshu Singh <sudhanshuwriterblc@gmail.com>
Co-authored-by: Shudhanshu Singh <sudhanshuwriterblc@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-22 17:33:43 +00:00
Giteabot e2f0358368 enhance: improve diff contrast in light and dark themes (#37477) (#38574)
Backport #37477 by @cyphercodes

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

Adjust the diff stat counter and syntax colors in both light and dark
themes to github-like colors that meet a >= 5:1 contrast floor (>= 7:1
for syntax names on diff rows), and make the counters semibold.

Signed-off-by: cyphercodes <cyphercodes@users.noreply.github.com>
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@nousresearch.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Hermes Agent <hermes@noreply.local>
Co-authored-by: silverwind <me@silverwind.io>
2026-07-22 12:07:42 +00:00
Giteabot d88bbfd0db fix(actions): support matrix when evaluating workflow if expression (#38474) (#38557)
Backport #38474 by @Zettat123

Partially fixes #38466

Added `matrix` to the evaluator for `if` expressions

Signed-off-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: bircni <bircni@icloud.com>
2026-07-21 13:28:58 +00:00
Giteabot 5e494f9cad fix(actions): align status icon span for Safari rendering (#38558) (#38562)
Backport #38558

Fixes #38553

Co-authored-by: okxint <130782884+okxint@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-21 18:43:11 +08:00
wxiaoguang 9731ad7c3c fix: revert git clone http redirection forbidden (#38530) (#38545)
backport #38530
2026-07-20 17:21:17 +02:00
Giteabot 148d528814 fix: clean up orphaned user-keyed tables in deleteUser (#38511) (#38514) 2026-07-20 08:41:59 +00:00
Giteabot 1af5277aba fix(actions): coerce workflow_dispatch boolean inputs to native types (#38472) (#38521)
Backport #38472 by @bircni

A `workflow_dispatch` job that has `needs:` **and** an `if:` comparing a
boolean
input against a boolean literal never runs — it stays `Blocked` forever
even
though its needs succeed. Minimal repro:

```yaml
on:
  workflow_dispatch:
    inputs:
      deploy:
        type: boolean
        default: true
jobs:
  build:
    runs-on: ubuntu-latest
    steps: [{ run: echo build }]
  deploy:
    needs: build
    if: ${{ inputs.deploy == true }}   # never true on Gitea
    runs-on: ubuntu-latest
    steps: [{ run: echo deploy }]
```

On GitHub this runs; on Gitea `deploy` is stuck. Jobs **without**
`needs` are
unaffected, which makes it look like a matrix/`needs` bug — it isn't.

## Root cause

`workflow_dispatch` stores boolean inputs as the strings
`"true"`/`"false"`
(`ctx.FormBool` → `strconv.FormatBool` in the web path, plain strings in
the API
path). Since #37478 (shipped in **v1.27.0**), `evaluateJobIf` runs
**server-side**
as part of the job-emitter resolver passes. For a `needs`-gated job the
server
therefore evaluates `inputs.deploy == true` with `inputs.deploy` being
the string
`"true"`; comparing a string to a boolean coerces to `NaN == 1` →
`false`, so the
job is never dispatched.

Jobs without `needs` skip this server-side gate and are evaluated by the
runner,
which coerces the string to a real bool — that's why they keep working,
and why
the same input yields opposite results in the two paths.

## Fix

Normalize `type: boolean` dispatch inputs to native JSON booleans in the
shared
`DispatchActionWorkflow` path, so it covers both the web and API entry
points in
one place. The coerced value flows into both the run's `EventPayload`
(read back
by the server-side `if` evaluation and by the runner) and the
creation-time
parse, so all consumers agree.

This matches GitHub, whose `inputs` context "preserves Boolean values as
Booleans
instead of converting them to strings", and mirrors the native JSON
types Gitea
already sends for `workflow_call`. Only booleans are coerced; other
input types
are left untouched, and a value that is already a bool (JSON API
request) passes
through.

Note: this makes dispatch payloads carry native booleans, which the
runner
consumes correctly as of gitea/runner#1087 (it accepts a native bool and
keeps
the string fallback) — the same expectation `workflow_call` already
relies on.

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

Co-authored-by: bircni <bircni@icloud.com>
2026-07-18 23:49:43 +02:00
Giteabot 6d41731184 fix: make the merge box button red if some checks fail (#38508) (#38516)
Backport #38508

fix #38506

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-18 04:10:50 -07:00
Eyüp Can Akman cfc9f4c685 fix(pull): sign the commit when updating a branch by merge (#38441) (#38499)
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
Backport #38441
2026-07-17 11:05:05 +00:00
Giteabot 895d848ff4 fix: make commit message merge correctly (#38490) (#38502)
Backport #38490

fix #38487

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: bircni <bircni@icloud.com>
2026-07-17 08:09:01 +00:00
Giteabot 7199547218 fix(actions): explain why a blocked or waiting job has not started (#38476) (#38498)
Backport #38476 by @bircni

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.

Co-authored-by: bircni <bircni@icloud.com>
2026-07-16 21:45:11 +00:00
Giteabot 7cb4201f8e fix(actions): make cancelled() work in job if evaluation (#38495) (#38497)
Backport #38495 by @Zettat123

Fix #38485

#37478 moved `if` evaluation from runner to server. But `NewInterpeter`
always provides a nil `JobContext` for the evaluator, which makes
[`cancelled()`](https://gitea.com/gitea/runner/src/commit/ad967330a8788c9b8ab723abbc1a86d53c3bc5e6/act/exprparser/functions.go#L299)
panic on `Job.Status` because `Job` is a nil pointer.

Co-authored-by: Zettat123 <zettat123@gmail.com>
2026-07-16 20:54:26 +00:00
Giteabot 5f017302bf fix(actions): show retention info on hover for expired artifacts (#38477) (#38493)
Backport #38477 by @bircni

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: bircni <bircni@icloud.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-16 17:01:56 +00:00
Giteabot 59c619660c fix(actions): group reusable-workflow matrix legs in the workflow graph (#38475) (#38492)
Backport #38475

Co-authored-by: bircni <bircni@icloud.com>
2026-07-16 15:58:06 +00:00
Giteabot 8599289459 fix: full file highlighting for git diff with CR char (#38484) (#38491)
Backport #38484

fix #38481

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-16 06:11:20 -07:00
Giteabot da9f0a3726 fix(packages): serve noarch Alpine index for any requested architecture (#38479) (#38486)
Backport #38479 by @gaurav0107

Fixes #38456

## Problem
The Alpine package registry serves one `APKINDEX.tar.gz` per
architecture. When a repository contains only `noarch` packages (no
architecture-specific packages), only the `noarch` index is built.
Because `apk` substitutes `$ARCH` with the host architecture and
requests e.g. `x86_64/APKINDEX.tar.gz`, such a repository returned HTTP
404 and was unusable, matching the report in #38456.

## Fix
`GetRepositoryFile` now falls back to the `noarch` index when the
requested architecture has no index of its own, mirroring the fallback
already present in the sibling `DownloadPackageFile` handler. `noarch`
packages are installable on every architecture, so serving them for any
requested architecture is correct. The index-build side is unchanged;
only the serving path gains the fallback, so mixed repositories (which
already merge `noarch` into each per-architecture index) are unaffected.

## AI assistance disclosure
This change was implemented with the help of an AI coding assistant,
which gitea's CONTRIBUTING.md explicitly welcomes when disclosed. I have
reviewed the change, understand it, and can explain and defend it.

## Tests
Added a `NoArchOnly` subtest to `TestPackageAlpine` that publishes only
a `noarch` package to a fresh repository and asserts that `GET
.../x86_64/APKINDEX.tar.gz` now returns `200` (previously `404`) and
that the served index lists the noarch package. Verified locally with
`go build`/`go vet` on the changed package and a compile of the
integration test package (`go test -c`); the full integration run relies
on CI.

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Gaurav Dubey <gauravdubey0107@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-16 12:28:39 +02:00
Giteabot 08fd59959e fix: 500 error when updating user visibility (#38480) (#38483)
Backport #38480 by @Zettat123

## How to reproduce this bug

1. Create a user with `visibility=public`
2. Update `ALLOWED_USER_VISIBILITY_MODES` setting to `limited, private`
3. Modify any field other than "User visibility" (e.g. "Full Name")
4. UI shows 500 error

## Fix

Only update the visibility field when it actually changes.

Co-authored-by: Zettat123 <zettat123@gmail.com>
2026-07-16 11:10:54 +02:00
Giteabot d60215c2a2 fix(actions): make job list item fully clickable (#38462) (#38471)
Backport #38462 by @SudhanshuMatrix

Clicking the empty space to the right of a job in the Actions sidebar
didn't switch jobs: the interactive `<a>`/`<button>` used `display:
contents` and so generated no clickable box.

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

Drop the wrapper `div` and `display: contents`, moving the `.item` and
layout styles directly onto the `<a>`/`<button>` so the whole row is
clickable. Reusable-caller `<button>` rows also get `width: 100%` and
`line-height: inherit` to match the `<a>` rows.

Co-authored-by: Shudhanshu Singh <sudhanshuwriterblc@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-07-15 17:18:05 +00:00
wxiaoguang bf594690db fix: mail template for push event (#38467) (#38468)
Backport #38467
2026-07-15 18:57:03 +02:00
Giteabot 5cb7ec9304 fix: make "test push webhook" always work (#38425) (#38455)
Backport #38425

* fix #38309
* fix #26238
* fix #37886

Co-authored-by: Harsh Satyajit Thakur <f20240223@goa.bits-pilani.ac.in>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-15 05:51:44 +00:00
Giteabot 6e86c4cde8 fix(actions): prevent bulk actions from affecting all runners (#38453) (#38457)
Backport #38453

Co-authored-by: xkm <fzc_study@163.com>
2026-07-14 20:06:17 -07:00
Giteabot c32af046a2 fix(org): align follow button and wrap description (#38448) (#38454)
Backport #38448

Co-authored-by: Shudhanshu Singh <sudhanshuwriterblc@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-15 10:12:39 +08:00
Giteabot a98468da30 fix(actions): populate github.event for scheduled runs (#38446) (#38452)
Backport #38446 by @silverwind

Scheduled runs stored a `null` event payload, so
`github.event.repository`/`sender`/`organization` were empty in
scheduled workflows. Every other event carries them, and so does GitHub
Actions. `CreateScheduleTask` now synthesizes them.

Co-authored-by: silverwind <me@silverwind.io>
2026-07-14 19:32:08 +02:00
bircni b969123b7f chore: don't auto refresh the merge box when user has interacted with it (#38436)
Backport #38435

Otherwise, the user just isn't able to use "auto merge" form
2026-07-13 02:54:47 -07:00
bircni c6627af968 docs: update changelog for 1.27.0 (#38427) 2026-07-13 06:31:20 +02:00
Giteabot de4b8277e9 fix: various security fixes (#38406) (#38426)
Backport #38406 by @bircni

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: bircni <bircni@icloud.com>
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:41:58 +00:00
Giteabot acbc75e2bd fix(util): reject invalid characters between time-estimate units (#38416) (#38423)
Backport #38416 by @TowyTowy

### What / why

`TimeEstimateParse` (used by the issue time-estimate form) only checked
that the first token starts at the beginning of the string and the last
token ends at its end, but never checked the gaps between consecutive
tokens. Non-whitespace garbage embedded between two valid units was
silently dropped and the string accepted with a wrong value instead of
being reported as invalid.

Examples that were wrongly accepted before this change:

- `1h 2x 3m` → 3780s (parsed as 1h3m)
- `1h_2m`    → 3720s
- `1h,1m`    → 3660s

All three now return an "invalid time string" error, while valid inputs
such as `1h 1m 1s` and `1h1m1s` keep working.

### How

Reject any non-whitespace content between two matched units.

Signed-off-by: TowyTowy <towy@airreps.link>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: TowyTowy <85077986+TowyTowy@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-12 09:59:28 -07:00
Giteabot c3325be816 fix: represent a deleted assignee team as a Ghost team (#38413) (#38419)
Backport #38413

Fixes #35472.

Co-authored-by: Harsh Satyajit Thakur <f20240223@goa.bits-pilani.ac.in>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-12 13:06:24 +00:00
Giteabot d4250bafd9 fix(turnstile): route CAPTCHA verification through the configured proxy (#38412) (#38420)
Backport #38412

Fixes #38217

Co-authored-by: Lovepreet Singh <lovepreet.singh61182@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-12 05:39:14 -07:00
Giteabot 6815d1646c fix: refresh pull request merge box when the commit status is pending (#38410) (#38411)
Backport #38410

Before: the merge box is only refreshed when the PR is being
conflict-checked.

After: also refresh the merge box when the commit status is pending
(e.g.: Action task is running)

By the way, slightly increase the refresh interval to 5s

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-12 07:15:25 +08:00
Giteabot 8ba4d4ebec fix: actions task state concurrent update (#38405) (#38409)
Backport #38405

fix #38333

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-11 16:51:32 +02:00
Giteabot b2794f96b9 fix(actions): keep workflow run trailing on one row with long branch names (#38382) (#38403)
Backport #38382 by @bircni

The flex-list refactor (#37505) raised the shared `.item-trailing`
selector's specificity, so its `flex-wrap: wrap` started overriding the
run list's intended `flex-wrap: nowrap` — a long branch name pushed the
trailing content past its fixed 280px width and wrapped the kebab menu
onto its own line.

Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-10 22:08:24 +00:00
Giteabot b6aa2b61c6 fix(web): use locale-aware date formatting for contribution calendar tooltips (#38398) (#38401)
Backport #38398 by @SudhanshuMatrix

The contribution calendar manually constructed localized date strings
instead of using the browser's locale-aware date formatting. Replace
this with `toLocaleDateString()` to correctly format dates for all
locales and calendar systems, including non-Gregorian calendars.

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

### Before and After Comparison (Persian `fa-IR`)

Before (Buggy) 
 
<img width="1246" height="651" alt="image"
src="https://github.com/user-attachments/assets/670698e6-dd4a-4c7e-b7fb-23849090d1b9"
/>
 
After (Fixed) 
<img width="1246" height="651" alt="image"
src="https://github.com/user-attachments/assets/9b65c647-876e-475b-98d1-614ef316fd6f"
/>

Co-authored-by: Shudhanshu Singh <sudhanshuwriterblc@gmail.com>
2026-07-10 21:28:54 +00:00
Giteabot 74ad781db9 fix(pull): re-evaluate review official flag on target branch change (#38319) (#38402)
Backport #38319 by @bircni

The `official` flag of a pull request review is computed against the
target branch's protection rules at submit time and stored on the review
record. `ChangeTargetBranch` updated the base branch but never
re-evaluated it, so an `official` approval obtained against an
unprotected branch could be retargeted onto a protected branch and
satisfy its required approvals, bypassing the branch protection.

This re-evaluates the `official` flag of the latest approve/reject
reviews against the new base branch whenever the target branch changes.

Co-authored-by: bircni <bircni@icloud.com>
2026-07-10 19:42:00 +00:00
Giteabot ed493f0684 fix(security): harden access checks and migration validation (#38324) (#38400) 2026-07-10 20:14:38 +02:00
Giteabot af7ba2edef fix: enforce public-only token scope and harden push options / locale parsing (#38323) (#38399)
Backport #38323 by @bircni

Three independent security hardening fixes, each with a regression test:

- **Locale DoS:** the `Locale` middleware passed the raw
`Accept-Language` header to `ParseAcceptLanguage`, whose guard only
counts `-` while the scanner aliases `_` to `-` — a large `_`-separated
header on an unauthenticated request burned CPU. The header is now
length-bounded before parsing.
- **Public-only token scope:** `GET /teams/{id}/repos`,
`.../repos/{org}/{repo}`, `/teams/{id}/activities/feeds`, and
`/users/{username}/orgs/{org}/permissions` still returned private
repo/activity/permission data to a public-only token. They now filter
via `TokenCanAccessRepo` / `ApplyPublicOnly` and reject non-public org
permissions.
- **Push-option visibility:** `repo.private` / `repo.template` push
options were applied to any existing repo, letting an owner/admin
silently flip visibility bypassing audit, webhooks, and notifications.
They are now honored only on push-to-create.

Co-authored-by: bircni <bircni@icloud.com>
2026-07-10 19:07:04 +02:00
Giteabot 8b4252e7f6 fix: co-author detection (#38392) (#38397)
Backport #38392

Fix #38384

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-10 11:15:20 +00:00
Giteabot 500a09e044 fix(api): stop leaking private repo metadata after access revocation (#38321) (#38390)
Backport #38321 by @bircni

The `/user/starred` and `/user/subscriptions` endpoints returned private
repositories a user had starred/watched even after their access to those
repositories was revoked, still exposing the repository name,
description and visibility (including later metadata changes).

Private repositories in the starred/watched queries are now gated on the
actor's current access via `AccessibleRepositoryCondition`, so users who
no longer have access no longer receive the metadata. Public
repositories and public-only tokens are unaffected.

Co-authored-by: bircni <bircni@icloud.com>
2026-07-10 07:40:02 +00:00
Giteabot bfebc4b0e1 fix: incorrect co-author detection on commit page (#38386) (#38387)
Backport #38386 by @bircni


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

Co-authored-by: bircni <bircni@icloud.com>
2026-07-09 18:29:28 -07:00
Giteabot d9534e7bfa fix(lfs): require proof of possession for cross-repo objects (#38322) (#38389)
Backport #38322 by @bircni

The LFS batch and upload handlers linked an object that already existed
in the content store but was not linked to the current repo whenever the
token's user could access it in another repo. Deploy-key tokens carry
the repo owner's identity, so a single-repo write deploy key could link
and then download objects from any repo the owner can see.

This drops the cross-repo access check: the batch handler now makes the
client upload (hash-verified) any object not yet linked to the repo, and
the upload handler skips proof of possession only when the object is
already linked to the current repo.

Co-authored-by: bircni <bircni@icloud.com>
2026-07-09 22:18:07 +00:00
Giteabot 532828cc82 enhance(actions): only create filtered-out workflow commit status for required contexts (#38371) (#38385)
Backport #38371 by @Zettat123

Follow #38237

#38237 posts "skipped" commit statuses for every workflow that is not
triggered due to a filter (e.g. `paths` or `branches`) mismatch.
However, for non-required workflows, creating "skipped" commit statuses
for them would generate a lot of noise.

To address this issue, this PR adds a check before creating commit
status:

- For the context that matches any required status check patterns, a
"skipped" commit status will be created. The `Required` label can inform
users that this status check is required, but has been skipped because
of a filter mismatch.

<img width="800" alt="image"
src="https://github.com/user-attachments/assets/264fd716-413c-457d-a5a6-6717175d3807"
/>

- For a non-required context, nothing will be created.

NOTE: Reducing noise is a best-effort approach and isn't entirely
accurate. When creating commit statuses, it is impossible to predict
which branch protection rule will take effect. Therefore, we have to
compare the commit status context against the required patterns from all
rules. If any rule matches, the context is considered "required".
 
Closes https://github.com/go-gitea/gitea/issues/38351

Co-authored-by: Zettat123 <zettat123@gmail.com>
2026-07-09 15:58:46 +00:00
Giteabot 8cf988f0a6 fix(ui): restore commits table column widths (#38379) (#38383)
Backport #38379 by @silverwind

https://github.com/go-gitea/gitea/pull/37594 widened the author column
from `three wide` to `four wide`, leaving a large empty gap around the
SHA column in the common single-author case. The old author cell was
capped at 180px, so the wider column only adds whitespace: avatar-stack
names ellipsize at 240px each, and wider multi-author rows still expand
naturally in the auto-layout table. Restore the pre-existing
`three`/`eight` widths.

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: bircni <bircni@icloud.com>
2026-07-09 17:07:20 +02:00
Giteabot 04a26f40a0 test(e2e): fix race in pdf file render test (#38380) (#38381)
Backport #38380 by @silverwind

`data-render-name` is set before the plugin's async render runs, so
measuring the container height right after the attribute appears can
observe the pre-render 48px height when the `pdfobject` chunk loads
slowly (flaked in CI). Poll for the height instead, like the asciicast
test in the same file does.

Co-authored-by: silverwind <me@silverwind.io>
2026-07-09 13:57:50 +00:00
Giteabot fc4eac390a fix: golang html template url escaping (#38363) (#38369)
Backport #38363

fix #38362

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-08 12:10:26 +08:00
Giteabot 64d559a8e6 perf(actions): debounce runner heartbeat writes and throttle task picks (#38281) (#38368)
Backport #38281 by @bircni

3 reductions in the DB load generated by many runners polling `FetchTask`:

**1. Debounce runner heartbeat writes**
Every poll wrote `last_online`, and every `UpdateTask`/`UpdateLog` wrote
`last_active` — while a runner streams logs that is many writes per
second per runner. These are now persisted only when stale enough to
actually affect the active/offline status (`ShouldPersistLastOnline` /
`ShouldPersistLastActive`), using the existing columns.

**2. Throttle concurrent task picks**
A new in-process semaphore (`MAX_CONCURRENT_TASK_PICKS`) bounds how many
runners run the task-assignment transaction at once, so a fleet polling
together cannot stampede the query. Throttled polls retry on their next
poll without advancing the runner's tasks version.

**3. Paginate the task-pick query**
`CreateTaskForRunner` previously loaded every waiting job in the
runner's scope into memory on each poll (no `LIMIT`). Now it pages
through the waiting backlog oldest-first with `LIMIT`, claiming the
first label-matching job.

Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
2026-07-07 16:27:00 -07:00
Giteabot 03372836ab fix(mirror): disable HTTP redirects on pull mirror sync (#38320) (#38367)
Backport #38320 by @bircni

Pull mirror sync ran `git fetch` / `remote update` / `remote prune`
without disabling HTTP redirects. A mirror remote that later starts
redirecting to an otherwise-blocked or internal address could be used as
an SSRF/exfiltration vector on scheduled syncs, bypassing the
allow/block validation applied at migration time.

This sets `http.followRedirects=false` on all three remote-contacting
commands in the pull mirror path, matching the existing guard already
present on the clone path.

Co-authored-by: bircni <bircni@icloud.com>
2026-07-07 17:59:33 +00:00
Giteabot 1af1e06ac4 fix: minio init check (#38355) (#38361)
Backport #38355

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-07 14:41:57 +02:00
Giteabot e07a5de53f fix: org project view assignee list (#38357) (#38360)
Backport #38357

fix #38129

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-07 07:07:30 +00:00
Giteabot d4d81af583 fix(actions): release claimed task if context is cancelled during FetchTask (#38343) (#38347) 2026-07-06 07:38:47 +02:00
Giteabot 6cd2c647ec test: compare key file contents instead of FileInfo in TestInitKeys (#38330) (#38331)
Backport #38330 by @Zettat123

`TestInitKeys` verified whether a host key file was regenerated by
comparing `os.FileInfo` before and after a `InitDefaultHostKeys` call.
On systems where the OS clock / filesystem timestamp granularity is
coarse, both writes land in the same tick and get an identical mtime.
The resulting `FileInfo` is then byte-for-byte equal even though the key
was actually regenerated, so `assert.NotEqual` fails.

Since a regenerated key always produces different random bytes,
comparing the content can reliably detect regeneration.

Co-authored-by: Zettat123 <zettat123@gmail.com>
2026-07-04 20:52:52 +00:00
Giteabot 37c8604105 fix(release): validate web attachment renames against allowed types (#38314) (#38328)
Backport #38314 by @lunny

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.

- validate edited release attachment names in
`release_service.UpdateRelease`
- reject forbidden attachment renames using
  `setting.Repository.Release.AllowedTypes`
- re-render the web release edit page with a validation error instead of
  returning an internal server error
- add regression coverage for both the service layer and the web flow

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-04 17:45:11 +02:00
Giteabot a9814e789c fix(actions): make runner list pagination order deterministic (#38313) (#38327)
Backport #38313 by @bircni

The runner-listing API endpoints (`admin`, `org`, `user`, `repo`, and
`shared`) return runners in a non-deterministic order across pages. When
paging through runners, some runners from page 1 could reappear on page
2 (and others get skipped entirely).

The cause is in `FindRunnerOptions.ToOrders()`. Most sort modes order by
a **non-unique** column only:

- default / `online` / `offline` → `last_online`
- `alphabetically` / `reversealphabetically` → `name`

When multiple runners tie on the sort key (e.g. every offline runner
shares `last_online = 0`, or two runners have the same name), the
database is free to return the tied rows in any order between separate
queries. Combined with `LIMIT`/`OFFSET` pagination, this means the same
runner can land on more than one page.

## Fix

Append the unique primary key `id` as a stable tiebreaker to each
non-unique sort order:

The `newest`/`oldest` modes already sort by the unique `id`, so they are
left unchanged.

Co-authored-by: bircni <bircni@icloud.com>
2026-07-03 20:59:33 +00:00
Giteabot ab10e37acf fix(release): gate draft release attachments on web download endpoints (#38318) (#38325)
Backport #38318 by @bircni

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.

This extends `ServeAttachment` to require write access to releases when
the attachment belongs to a draft release, mirroring the existing
API-side `canAccessReleaseDraft` gate. A regression test is included.

Co-authored-by: bircni <bircni@icloud.com>
2026-07-03 20:34:37 +02:00
Giteabot f7bc6b89c1 fix: Improve since/until when counting commits for X-Total-Count (#38243) (#38304)
Backport #38243 by @puni9869

Follow up for https://github.com/go-gitea/gitea/pull/38204.

Signed-off-by: puni9869 <80308335+puni9869@users.noreply.github.com>
Co-authored-by: puni9869 <80308335+puni9869@users.noreply.github.com>
2026-07-02 10:07:29 +00:00
Giteabot fabc5e6fcb fix(actions): prevent chevron overlap with log text when timestamps are enabled (#38227) (#38307)
Backport #38227 by @SudhanshuMatrix

### Description
This PR resolves a UI alignment bug in the Gitea Actions log viewer
where the expand/collapse disclosure chevron overlaps with the log text
(specifically the timestamp) when timestamps are enabled.

### Cause
When log timestamps are enabled, the timestamp element
(`.log-time-stamp`) is rendered as the first element next to the line
number. Because it only had a default `10px` left margin, it positioned
itself exactly where the group's expand/collapse chevron is located,
causing them to overlap.

Fixes #38222.

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Shudhanshu Singh <sudhanshuwriterblc@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-07-02 11:22:26 +02:00
Giteabot a016d678db fix(workflows): branch protection status checks fail when workflow uses on: paths filter (#38237) (#38302) 2026-07-01 20:10:11 +00:00
Giteabot b6e409badd fix(oauth2): persist linkAccountData during auto-link 2FA flow (#38274) (#38295)
Backport #38274 by @afahey03

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.

Created the test, `TestOAuth2AutoLinkWithTwoFactor`, which verifies that
automatic account linking completes after the user passes local 2FA when
an OIDC identity matches an existing account.

DISCLAIMER: I used AI to create the test

Closes #38171

Co-authored-by: Aidan Fahey <afahey2003@yahoo.com>
Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-01 13:18:37 +02:00
Giteabot 2734504cfc fix(actions): allow Actions bot to push to protected branches (#38284) (#38293)
Backport #38284 by @bircni

Fixes #38278

## Problem

When branch protection matches the branch an Actions workflow pushes to,
the runner's `git push` is rejected — even though the workflow token has
`contents: write` and the same push performed with a PAT (write access)
succeeds. Disabling protection or changing the pattern so it no longer
matches makes the push work.

## Root cause

In `preReceiveBranch` (`routers/private/hook_pre_receive.go`), the "can
the doer push to this protected branch" check resolves the pusher with
`user_model.GetUserByID(ctx, ctx.opts.UserID)`. For an Actions push the
user ID is `-2` (the virtual `ActionsUserID`), which has no database
row, so the lookup fails. Even past that, `CanUserPush` →
`HasAccessUnit`/whitelist membership cannot evaluate a virtual user and
returns `false`. As a result the Actions bot was rejected on every
matching protected branch, despite the earlier `assertCanWriteRef`
already confirming the token's code-write via
`GetActionsUserRepoPermission`.

This was inconsistent: a PAT with identical write access passed the
exact same check.

## Fix

Evaluate the Actions bot against its already-computed token permission
instead of a user lookup, mirroring the existing
`IsUserMergeWhitelisted` pattern:

- Add `CanActionsUserPush` / `CanActionsUserForcePush` on
`ProtectedBranch`, which take the precomputed `access_model.Permission`.
- Allow the push when push is enabled, **no** push whitelist is
enforced, and the token has code-write.
- Keep the bot blocked when a whitelist is enforced — it cannot be added
to one, so it must use a pull request. This preserves the whitelist as a
real security boundary.

Force-push, signed-commit and protected-file-path checks are untouched.

Signed-off-by: bircni <bircni@icloud.com>
Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-07-01 11:46:17 +02:00
Giteabot eee7967b81 fix(actions): include all aggregable run statuses in status filter (#38280) (#38287)
Backport #38280 by @bircni

The **Status** filter dropdown on the repository Actions run list does
not let you filter for **Blocked** runs (nor **Cancelled** or
**Skipped**). These statuses are missing from the dropdown even though a
run can legitimately end up in any of them.

A run's status is computed by `aggregateJobStatus`, which can return
`Blocked`, `Cancelled` and `Skipped`. Because the filter dropdown only
offered Success, Failure, Waiting, Running and Cancelling, runs in those
other states existed but were impossible to filter for.

Co-authored-by: bircni <bircni@icloud.com>
2026-07-01 10:12:11 +02:00
Giteabot 1df8f91691 fix(archiver): use serializable repo-archive queue payload (#38273) (#38283)
Backport #38273 by @Vinod-OAI

After upgrading from 1.25.x to 1.26.x, `repo-archive` workers can fail
to unmarshal queued items:

```
Failed to unmarshal item from queue "repo-archive":
json: unable to unmarshal into Go convert.Conversion within "/Repo/Units/0/Config":
cannot derive concrete type for nil interface with finite type set
```

`ArchiveRequest` started embedding `*repo_model.Repository` in 1.26,
which does not round-trip through the JSON queue.

This change stores a minimal `archiveQueueItem` (`RepoID`, `Type`,
`CommitID`, `Paths`) in `repo-archive` and loads the repository in the
worker. `UnmarshalJSON` accepts legacy payloads that used `RepoID` or
embedded `Repo.id`.

Fixes #38272

<!--
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: Vinod-OAI <venkat.vinod@observe.ai>
Co-authored-by: bircni <bircni@icloud.com>
2026-06-30 19:17:29 +02:00
bircni 4654e7eccd docs: Changelog for 1.27.0-rc0 (#38247)
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-06-29 21:06:07 +02:00
1044 changed files with 8830 additions and 9624 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ include_file = ["main.go"]
include_dir = ["cmd", "models", "modules", "options", "routers", "services"]
exclude_dir = [
"models/fixtures",
"modelmigration/fixtures",
"models/migrations/fixtures",
"modules/avatar/identicon/testdata",
"modules/avatar/testdata",
"modules/git/tests",
+4 -4
View File
@@ -9,10 +9,10 @@ inputs:
runs:
using: composite
steps:
- uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0
- uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
- uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Build regular image
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: .
platforms: ${{ inputs.platform }}
@@ -20,7 +20,7 @@ runs:
file: Dockerfile
cache-from: type=registry,ref=ghcr.io/go-gitea/gitea:buildcache-rootful
- name: Build rootless image
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: .
platforms: ${{ inputs.platform }}
+6 -6
View File
@@ -16,34 +16,34 @@ runs:
using: composite
steps:
- if: ${{ github.workflow == 'cache-seeder' }}
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/go/pkg/mod
key: gomod-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('go.sum') }}
- if: ${{ github.workflow != 'cache-seeder' }}
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/go/pkg/mod
key: gomod-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('go.sum') }}
restore-keys: gomod-${{ runner.os }}-${{ runner.arch }}
- if: ${{ github.workflow == 'cache-seeder' && inputs.lint-cache != 'true' }}
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.cache/go-build
key: gobuild-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('go.sum') }}
- if: ${{ github.workflow != 'cache-seeder' || inputs.lint-cache == 'true' }}
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.cache/go-build
key: gobuild-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('go.sum') }}
restore-keys: gobuild-${{ runner.os }}-${{ runner.arch }}
- if: ${{ inputs.lint-cache == 'true' && github.workflow == 'cache-seeder' }}
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.cache/golangci-lint
key: golint-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('go.sum', '.golangci.yml') }}
- if: ${{ inputs.lint-cache == 'true' && github.workflow != 'cache-seeder' }}
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.cache/golangci-lint
key: golint-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('go.sum', '.golangci.yml') }}
+4 -4
View File
@@ -11,12 +11,12 @@ runs:
steps:
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
- if: ${{ inputs.cache == 'true' }}
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 26
node-version: 24
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- if: ${{ inputs.cache != 'true' }}
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 26
node-version: 24
+2 -2
View File
@@ -21,12 +21,12 @@ jobs:
timeout-minutes: 30
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
- uses: renovatebot/github-action@22e0a16091fc706b04affe6ae53d5e3358ac4023 # v46.1.19
- uses: renovatebot/github-action@6d859fc95779be83a0335ca704879b47e5d79641 # v46.1.16
with:
renovate-version: ${{ env.RENOVATE_VERSION }}
configurationFile: renovate.json5
token: ${{ secrets.RENOVATE_TOKEN }}
env:
RENOVATE_BINARY_SOURCE: install # auto-install go/node toolchains needed by post-upgrade tasks.
RENOVATE_ALLOWED_POST_UPGRADE_COMMANDS: '["^make (tidy|svg|generate-codemirror-languages)$"]'
RENOVATE_ALLOWED_POST_UPGRADE_COMMANDS: '["^make (tidy|svg)$"]'
RENOVATE_REPOSITORIES: '["go-gitea/gitea"]'
+1 -1
View File
@@ -50,7 +50,7 @@ jobs:
shell: ${{ steps.changes.outputs.shell }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
- uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2
- uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
id: changes
with:
filters: |
+1 -1
View File
@@ -42,7 +42,7 @@ jobs:
- run: make lint-spell
- if: needs.files-changed.outputs.templates == 'true' || needs.files-changed.outputs.yaml == 'true' || needs.files-changed.outputs.actions == 'true'
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
python-version: 3.14
- if: needs.files-changed.outputs.templates == 'true' || needs.files-changed.outputs.yaml == 'true'
+3 -3
View File
@@ -131,7 +131,7 @@ jobs:
ports:
- "7700:7700"
redis:
image: redis:latest@sha256:5d2c689b4b55fc3fab4b0cc8aaa950f85b508c76c1e0f35a90d8f411d55a8b2b
image: redis:latest@sha256:c904002d182255b6db3cbe3a1e8ce6c187d15390c39500b59fc07181aabff7bf
options: >- # wait until redis has started
--health-cmd "redis-cli ping"
--health-interval 5s
@@ -147,7 +147,7 @@ jobs:
ports:
- "9000:9000"
devstoreaccount1.azurite.local: # https://github.com/Azure/Azurite/issues/1583
image: mcr.microsoft.com/azure-storage/azurite:latest@sha256:7aee5546ecffb850634c5f67ed87f59dba02a0eb24b7c7e01f5bd9148bd5edd9
image: mcr.microsoft.com/azure-storage/azurite:latest@sha256:dae2a5f96553962901304b94e72ef87e299d0825e4b679673bcc527a25076fe4
ports:
- 10000:10000
steps:
@@ -237,7 +237,7 @@ jobs:
ports:
- "1433:1433"
devstoreaccount1.azurite.local: # https://github.com/Azure/Azurite/issues/1583
image: mcr.microsoft.com/azure-storage/azurite:latest@sha256:7aee5546ecffb850634c5f67ed87f59dba02a0eb24b7c7e01f5bd9148bd5edd9
image: mcr.microsoft.com/azure-storage/azurite:latest@sha256:dae2a5f96553962901304b94e72ef87e299d0825e4b679673bcc527a25076fe4
ports:
- 10000:10000
steps:
+3 -4
View File
@@ -17,7 +17,7 @@ jobs:
contents: read
pull-requests: write
steps:
- uses: actions/labeler@b8dd2d9be0f68b860e7dae5dae7d772984eacd6d # v6.2.0
- uses: actions/labeler@f27b608878404679385c85cfa523b85ccb86e213 # v6.1.0
with:
sync-labels: true
@@ -33,9 +33,9 @@ jobs:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
with:
ref: ${{ github.event.pull_request.base.sha }}
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 26
node-version: 24
# Labels are only synced after the title lints, so an invalid title never reaches the label diff.
- run: node ./tools/ci-tools.ts lint-pr-title
env:
@@ -43,6 +43,5 @@ jobs:
- run: node ./tools/ci-tools.ts set-pr-labels
env:
PR_TITLE: ${{ github.event.pull_request.title }}
PR_TITLE_BEFORE: ${{ github.event.changes.title.from }}
PR_NUMBER: ${{ github.event.pull_request.number }}
GITHUB_TOKEN: ${{ github.token }}
+27 -22
View File
@@ -6,35 +6,40 @@ on:
- main
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
build-and-publish:
strategy:
fail-fast: false
matrix:
runner: [ubuntu-24.04, ubuntu-24.04-arm]
runs-on: ${{ matrix.runner }}
runs-on: ubuntu-latest
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
with:
fetch-depth: 0
- uses: snapcore/action-build@3bdaa03e1ba6bf59a65f84a751d943d549a54e79 # v1.3.0
id: build
# retry snapcraft uploads which can be flaky
- name: Publish snap
- name: Install snapcraft
run: sudo snap install snapcraft --classic
- name: Authenticate snapcraft
shell: bash
run: snapcraft login --with <(printf '%s' "$SNAPCRAFT_STORE_CREDENTIALS")
- name: Remote build
run: |
for attempt in 1 2 3 4 5; do
snapcraft upload "${{ steps.build.outputs.snap }}" --release latest/edge && exit 0
echo "::warning::snap upload attempt $attempt failed, retrying in 15s"
sleep 15
snapcraft remote-build \
--launchpad-accept-public-upload \
--build-for=amd64,arm64,armhf
- name: List built snaps
run: find . -maxdepth 1 -type f -name '*.snap' -print
- name: Upload and release snapcraft nightly build
run: |
set -euo pipefail
for snap in ./*.snap; do
echo "Uploading $snap to edge"
snapcraft upload --release="latest/edge" "$snap"
done
exit 1
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
+15 -10
View File
@@ -23,7 +23,12 @@ jobs:
with:
go-version-file: go.mod
check-latest: true
- uses: ./.github/actions/node-setup
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 24
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- run: make deps-frontend deps-backend
# xgo build
- run: make release
@@ -56,7 +61,7 @@ jobs:
echo "Cleaned name is ${REF_NAME}"
echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT"
- name: configure aws
uses: aws-actions/configure-aws-credentials@517a711dbcd0e402f90c77e7e2f81e849156e31d # v6.2.2
uses: aws-actions/configure-aws-credentials@e7f100cf4c008499ea8adda475de1042d6975c7b # v6.2.0
with:
aws-region: ${{ secrets.AWS_REGION }}
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
@@ -78,8 +83,8 @@ jobs:
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0
- uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
- uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Get cleaned branch name
id: clean_name
env:
@@ -87,7 +92,7 @@ jobs:
run: |
REF_NAME=$(echo "$REF" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//')
echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT"
- uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
- uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
id: meta
with:
images: |-
@@ -97,7 +102,7 @@ jobs:
type=raw,value=${{ steps.clean_name.outputs.branch }}
annotations: |
org.opencontainers.image.authors="maintainers@gitea.io"
- uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
- uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
id: meta_rootless
with:
images: |-
@@ -111,18 +116,18 @@ jobs:
annotations: |
org.opencontainers.image.authors="maintainers@gitea.io"
- name: Login to Docker Hub
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GHCR using PAT
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: build regular docker image
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: .
platforms: linux/amd64,linux/arm64,linux/riscv64
@@ -132,7 +137,7 @@ jobs:
cache-from: type=registry,ref=ghcr.io/go-gitea/gitea:buildcache-rootful
cache-to: type=registry,ref=ghcr.io/go-gitea/gitea:buildcache-rootful,mode=max
- name: build rootless docker image
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: .
platforms: linux/amd64,linux/arm64,linux/riscv64
+15 -10
View File
@@ -24,7 +24,12 @@ jobs:
with:
go-version-file: go.mod
check-latest: true
- uses: ./.github/actions/node-setup
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 24
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- run: make deps-frontend deps-backend
# xgo build
- run: make release
@@ -57,7 +62,7 @@ jobs:
echo "Cleaned name is ${REF_NAME}"
echo "branch=${REF_NAME}" >> "$GITHUB_OUTPUT"
- name: configure aws
uses: aws-actions/configure-aws-credentials@517a711dbcd0e402f90c77e7e2f81e849156e31d # v6.2.2
uses: aws-actions/configure-aws-credentials@e7f100cf4c008499ea8adda475de1042d6975c7b # v6.2.0
with:
aws-region: ${{ secrets.AWS_REGION }}
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
@@ -89,9 +94,9 @@ jobs:
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0
- uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
- uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
- uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
id: meta
with:
images: |-
@@ -104,7 +109,7 @@ jobs:
type=semver,pattern={{version}}
annotations: |
org.opencontainers.image.authors="maintainers@gitea.io"
- uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
- uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
id: meta_rootless
with:
images: |-
@@ -120,18 +125,18 @@ jobs:
annotations: |
org.opencontainers.image.authors="maintainers@gitea.io"
- name: Login to Docker Hub
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GHCR using PAT
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: build regular container image
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: .
platforms: linux/amd64,linux/arm64,linux/riscv64
@@ -139,7 +144,7 @@ jobs:
tags: ${{ steps.meta.outputs.tags }}
annotations: ${{ steps.meta.outputs.annotations }}
- name: build rootless container image
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: .
platforms: linux/amd64,linux/arm64,linux/riscv64
+15 -10
View File
@@ -27,7 +27,12 @@ jobs:
with:
go-version-file: go.mod
check-latest: true
- uses: ./.github/actions/node-setup
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 24
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- run: make deps-frontend deps-backend
# xgo build
- run: make release
@@ -60,7 +65,7 @@ jobs:
echo "Cleaned name is ${REF_NAME}"
echo "branch=${REF_NAME}" >> "$GITHUB_OUTPUT"
- name: configure aws
uses: aws-actions/configure-aws-credentials@517a711dbcd0e402f90c77e7e2f81e849156e31d # v6.2.2
uses: aws-actions/configure-aws-credentials@e7f100cf4c008499ea8adda475de1042d6975c7b # v6.2.0
with:
aws-region: ${{ secrets.AWS_REGION }}
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
@@ -92,9 +97,9 @@ jobs:
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0
- uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
- uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
- uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
id: meta
with:
images: |-
@@ -111,7 +116,7 @@ jobs:
type=semver,pattern={{major}}.{{minor}}
annotations: |
org.opencontainers.image.authors="maintainers@gitea.io"
- uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
- uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
id: meta_rootless
with:
images: |-
@@ -132,18 +137,18 @@ jobs:
annotations: |
org.opencontainers.image.authors="maintainers@gitea.io"
- name: Login to Docker Hub
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GHCR using PAT
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: build regular container image
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: .
platforms: linux/amd64,linux/arm64,linux/riscv64
@@ -151,7 +156,7 @@ jobs:
tags: ${{ steps.meta.outputs.tags }}
annotations: ${{ steps.meta.outputs.annotations }}
- name: build rootless container image
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: .
platforms: linux/amd64,linux/arm64,linux/riscv64
+6 -5
View File
@@ -53,12 +53,12 @@ linters:
desc: use builtin errors package instead
migrations:
files:
- '**/modelmigration/**/*.go'
- '**/models/migrations/**/*.go'
deny:
- pkg: gitea.dev/models
desc: "migrations must not depend on the models package. HINT: MIGRATION-STRUCT-FROZEN"
- pkg: gitea.dev/models$
desc: migrations must not depend on the models package
- pkg: gitea.dev/modules/structs
desc: "migrations must not depend on modules/structs. HINT: MIGRATION-STRUCT-FROZEN"
desc: migrations must not depend on modules/structs (API structures change over time)
nolintlint:
allow-unused: false
require-explanation: true
@@ -134,7 +134,8 @@ linters:
path: _test\.go
- linters:
- dupl
path: modelmigration/v
- errcheck
path: models/migrations/v
- linters:
- forbidigo
path: cmd
+1 -2
View File
@@ -12,8 +12,7 @@
- Preserve existing code comments, do not remove or rewrite comments that are still relevant
- Keep comments short, prefer same-line, explain why, never narrate code
- Prefer unit tests over integration tests when logic is testable in isolation
- Aim for sub-2s local runtime per integration test and sub-4s per e2e test
- Prefer using semantic selectors in e2e tests
- Aim for sub-2s local runtime for integration and e2e tests
- In TypeScript, use `!` (non-null assertion) instead of `?.`/`??` when a value is known to always exist
- For CSS layout, prefer `flex-*` helpers over per-child `tw-ml-*` / `tw-mr-*` margins; fall back to `tw-*` utilities when specificity requires `!important`
- Include authorship attribution in issue and pull request comments
+22 -22
View File
@@ -18,6 +18,7 @@ been added to each release, please refer to the [blog](https://blog.gitea.com).
* Fix(api): stop leaking private repo metadata after access revocation (#38321) (#38390)
* Fix(lfs): require proof of possession for cross-repo objects (#38322) (#38389)
* Fix(mirror): disable HTTP redirects on pull mirror sync (#38320) (#38367)
* Fix: golang html template url escaping (#38363) (#38369)
* Fix(release): validate web attachment renames against allowed types (#38314) (#38328)
* Fix(release): gate draft release attachments on web download endpoints (#38318) (#38325)
* Fix(deps): update module github.com/go-git/go-git/v5 to v5.19.1 [security] (#37786)
@@ -25,7 +26,6 @@ been added to each release, please refer to the [blog](https://blog.gitea.com).
* Fix(api): don't expose private org membership via public_members (#38145)
* Fix(actions): deny fork-PR cross-repo access via collaborative owner (#38214)
* Fix(migrations): prevent path traversal in repository restore (#38215)
* Feat(security): set X-Content-Type-Options: nosniff by default (#37354)
* FEATURES
* Feat(actions): add workflow status badge modal (#38196)
@@ -34,12 +34,12 @@ been added to each release, please refer to the [blog](https://blog.gitea.com).
* Feat(actions): implement `jobs.<job_id>.continue-on-error` (#38100)
* Feat(actions): show run status on browser tab favicon (#38071)
* Feat(api): add token introspection and self-deletion endpoint (#37995)
* Feat(api): add q parameter to list branches API for server-side filtering (#37982)
* Feat(repo): split repository creation limit into user and org scopes (#37872)
* Feat(actions): bulk delete, disable and enable runners in admin UI (#37869)
* Feat(actions): List workflows that were executed once but got removed from the default branch (#37835)
* Feat(org): add team visibility so org members can discover teams (#37680)
* Feat: add raw diff/patch endpoint for repository comparisons (#37632)
* Feat(oauth): Support AWS Cognito OAuth2 provider (#37607)
* Feat: Add avatar stacks (#37594)
* Feat(actions): add job summaries (GITHUB_STEP_SUMMARY) (#37500)
* Feat(web): Add Jupyter Notebook (.ipynb) Rendering Support (#37433)
@@ -47,13 +47,9 @@ been added to each release, please refer to the [blog](https://blog.gitea.com).
* Feat(orgs): Add search bar for organization members tab page (#37347)
* Feat(api): Add assignees APIs (#37330)
* Feat(api): Add GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs (#37196)
* Introduce `ActionRunAttempt` to represent each execution of a run (#37119)
* Serve OpenAPI 3.0 spec at /openapi.v1.json (#37038)
* Add project column picker to issue and pull request sidebar (#37037)
* Allow multiple projects per issue and pull requests (#36784)
* Add bulk repository deletion for organizations (#36763)
* Add API endpoint to reply to pull request review comments (#36683)
* Feat: Add bypass allowlist for branch protection (#36514)
* Feat(ui): add "follow rename" to file commit history list (#34994)
* Feat(ssh): auto generate additional ssh keys (#33974)
@@ -61,32 +57,29 @@ been added to each release, please refer to the [blog](https://blog.gitea.com).
* Enhance(actions): only create filtered-out workflow commit status for required contexts (#38371) (#38385)
* Enhance: allow builtin default git config options to be overridden (#38172)
* Enhance: allow MathML core elements (#38034)
* Feat(api): add q parameter to list branches API for server-side filtering (#37982)
* Enhance(markup): improve issue title rendering (#37908)
* Enhance(actions): set descriptive browser tab title on run view (#37870)
* Enhance: Migrate remaining gopkg.in/yaml.v3 usages to go.yaml.in/yaml/v4 (#37866)
* Enhance(actions): show workflow name from YAML instead of filename (#37833)
* Feat(actions): add before/after to PR synchronize event payload (#37827)
* Enhance(actions): add branch filters to run list (#37826)
* Enhance(actions): Make Summary UI more beautiful with more infos (#37824)
* Feat: add copy button to action step header, improve other copy buttons (#37744)
* Feat(web): also display PR counts in repo list (#37739)
* Fix(icon): use repo-forked icon to display forks count (#37731)
* Feat(api): add sort and order query parameters to job list endpoints (#37672)
* Feat(api): add last_sync to repository API (#37566)
* Enhance: Adjust Workflow Graph styling (#37497)
* Improve code editor text selection and clean up lint enablement (#37474)
* Add mirror auth updates to repo edit API and settings (#37468)
* Replace `olivere/elastic` with REST API client, add OpenSearch support (#37411)
* Feat: Add default PR branch update style setting (#37410)
* Fix inconsistent disabled styling on logged-out repo header buttons (#37406)
* Allow fast-forward-only merge when signed commits are required (#37335)
* Enhance styling in actions page (#37323)
* Add `ExternalIDClaim` option for OAuth2 OIDC auth source (#37229)
* Fix: improve actions status icons and texts (#37206)
* Make Markdown fenced code block work with more syntaxes (#37154)
* Fix: Sort action run jobs by JobID and Name with matrix examples (#37046)
* Add pagination and search box to org teams list (#37245)
* Workflow Artifact Info Hover (#37100)
* Feat(editor): broaden language detection in web code editor (#37619)
* Add API endpoint to reply to pull request review comments (#36683)
* PERFORMANCE
* Perf(actions): debounce runner heartbeat writes and throttle task picks (#38281) (#38368)
@@ -106,7 +99,6 @@ been added to each release, please refer to the [blog](https://blog.gitea.com).
* Fix: co-author detection (#38392) (#38397)
* Fix: incorrect co-author detection on commit page (#38386) (#38387)
* Fix(ui): restore commits table column widths (#38379) (#38383)
* Fix: golang html template url escaping (#38363) (#38369)
* Fix: minio init check (#38355) (#38361)
* Fix: org project view assignee list (#38357) (#38360)
* Fix(actions): release claimed task if context is cancelled during `FetchTask` (#38343) (#38347)
@@ -173,7 +165,6 @@ been added to each release, please refer to the [blog](https://blog.gitea.com).
* Feat: execute post run cleanup when workflow is cancelled (#37275)
* Fix `relative-time` error and improve global error handler (#37241)
* Refactor flash message and remove SanitizeHTML template func (#37179)
* Fix Repository transferring page (#37277)
* TESTING
* Test(e2e): fix race in pdf file render test (#38380) (#38381)
@@ -187,10 +178,8 @@ been added to each release, please refer to the [blog](https://blog.gitea.com).
* Ci: shard tests and reduce redundant work (#37618)
* Test(e2e): run playwright via container (#37300)
* Remove external service dependencies in migration tests (#36866)
* Refactor: only reset a database table when the table's data was changed (#37573)
* BUILD
* Refactor: use modernc sqlite driver as default (#37562)
* Fix(actions): authenticate snapcraft before nightly remote build (#38252)
* Ci: cap Elasticsearch heap in db-tests (#37816)
* Build(snap): publish nightly version to snapcraft via actions (#37814)
@@ -200,21 +189,24 @@ been added to each release, please refer to the [blog](https://blog.gitea.com).
* Chore: clean up "contrib" dir (#37690)
* Fix: snap build (main branch) (#37685)
* Ci: Also lint json5 files (#37659)
* Feat(editor): broaden language detection in web code editor (#37619)
* Build: update pnpm to v11 (#37591)
* Refactor(deps): migrate from `nektos/act` fork to `gitea/runner` (#37557)
* Refactor: lint bare `fill`/`stroke` colors, add vars for git graph color series (#37543)
* Update go js py dependencies (#37525)
* Ci: lint PR titles with commitlint (#37498)
* Chore: upgrade Go version in devcontainer image to 1.26 (#37374)
* Update GitHub Actions to latest major versions (#37313)
* Update go js dependencies (#37312)
* Fail vite build on rolldown warnings via NODE_ENV=test (#37270)
* Remove htmx (#37224)
* Replace custom Go formatter with `golangci-lint fmt` (#37194)
* Refactor htmx and fetch-action related code (#37186)
* Integrate renovate bot for all dependency updates (#37050)
* Build(sign): move to sigstore (#38250)
* DOCS
* Docs: update changelog for 1.26.3 & 1.26.4 (#38178)
* Update 1.26.1 changelog in main (#37442)
* Docs: fix duplicated word in foreachref doc comment (#38161)
* Docs: Clarify criteria for becoming a merger (#38113)
* Docs: Publish TOC Election Result 2026 (#38111)
@@ -222,15 +214,11 @@ been added to each release, please refer to the [blog](https://blog.gitea.com).
* Docs: add development setup guide (#37960)
* MISC
* Refactor: lint bare `fill`/`stroke` colors, add vars for git graph color series (#37543)
* Remove htmx (#37224)
* Refactor htmx and fetch-action related code (#37186)
* Revert(sign): restore gpg (#38251)
* Refactor: replace legacy `delete-button` with `link-action` (#38143)
* Refactor(actions): read runner capabilities from proto field (#38068)
* Refactor(api): clarify APIError message usage and fix legacy lint error (#38012)
* Refactor: Use db.Get[] instead of db.GetEngine(ctx).Get(bean) to avoid zero value fetching wrong database record (#37977)
* Enhance: Migrate remaining gopkg.in/yaml.v3 usages to go.yaml.in/yaml/v4 (#37866)
* Fix(deps): update go dependencies (#37851)
* Ci: Fix sync PR labels from the conventional-commit title (#37784) (#37825)
* Ci: tweak `files-changed`, add `free-disk-space` (#37819)
@@ -252,6 +240,7 @@ been added to each release, please refer to the [blog](https://blog.gitea.com).
* Chore(deps): update action dependencies (#37751)
* Fix(markup): wrap indented code blocks for the code-copy button (#37748)
* Chore(db): introduce db.Session and db.EngineMigration interfaces (#37746)
* Feat(web): also display PR counts in repo list (#37739)
* Refactor(glob): use strings.Builder for regexp compilation (#37730)
* Chore(doctor): remove four obsolete doctor check implementations (#37728)
* Refactor(org): simplify owner-team org repo creation logic (#37727)
@@ -269,9 +258,12 @@ been added to each release, please refer to the [blog](https://blog.gitea.com).
* Fix(deps): update npm dependencies (#37636)
* Refactor(log): replace log.Critical with log.Error (#37624)
* Build(deps): bump fast-uri from 3.1.0 to 3.1.2 (#37616)
* Feat(oauth): Support AWS Cognito OAuth2 provider (#37607)
* Chore(deps): update action dependencies (#37603)
* Ci: allow `chore` type in PR title lint (#37575)
* Refactor: only reset a database table when the table's data was changed (#37573)
* Ci: increase renovate frequency and fix RENOVATE_ALLOWED_POST_UPGRADE_COMMANDS (#37565)
* Refactor: use modernc sqlite driver as default (#37562)
* Docs: fix 4 typos in CHANGELOG.md (#37549)
* Fix(deps): update go dependencies (#37541)
* Chore(deps): update action dependencies (#37540)
@@ -280,22 +272,26 @@ been added to each release, please refer to the [blog](https://blog.gitea.com).
* Refactor "flex-list" to "flex-divided-list" (#37505)
* Refactor compare diff/pull page (1) (#37481)
* Refactor pull request view (4) (#37451)
* Update 1.26.1 changelog in main (#37442)
* Refactor: use named `Permission` field in `Repository` struct instead of anonymous embedding (#37441)
* Replace `olivere/elastic` with REST API client, add OpenSearch support (#37411)
* Refactor: serve site manifest via `/assets/site-manifest.json` endpoint (#37405)
* Remove IsValidExternalURL/IsAPIURL and use IsValidURL at call sites (#37364)
* Update `Block a user` form (#37359)
* Move review request functions to a standalone file (#37358)
* Feat(security): set X-Content-Type-Options: nosniff by default (#37354)
* Enable strict TypeScript, add `errorMessage` helper (#37292)
* Refactor frontend `tw-justify-between` layouts to `flex-left-right` (#37291)
* Update Nix flake (#37284)
* Fix Repository transferring page (#37277)
* Remove `SubmitEvent` polyfill (#37276)
* Remove dead code identified by `deadcode` tool (#37271)
* Upgrade go-git to v5.18.0 (#37268)
* Don't add useless labels which will bother changelog generation (#37267)
* Move heatmap to first-party code (#37262)
* Tests/integration: simplify code (#37249)
* Add pagination and search box to org teams list (#37245)
* Remove error returns from crypto random helpers and callers (#37240)
* Add `ExternalIDClaim` option for OAuth2 OIDC auth source (#37229)
* Refactor: simplify ParseCatFileTreeLine and catBatchParseTreeEntries (#37210)
* Refactor "htmx" to "fetch action" (#37208)
* Update go js py dependencies (#37204)
@@ -305,7 +301,11 @@ been added to each release, please refer to the [blog](https://blog.gitea.com).
* Update javascript dependencies (#37142)
* Update go dependencies (#37141)
* Frontport changelog of v1.26.0-rc0 (#37138)
* Introduce `ActionRunAttempt` to represent each execution of a run (#37119)
* Workflow Artifact Info Hover (#37100)
* Extend issue context popup beyond markdown content (#36908)
* Add bulk repository deletion for organizations (#36763)
* Feat: Add bypass allowlist for branch protection (#36514)
## [1.26.4](https://github.com/go-gitea/gitea/releases/tag/1.26.4) - 2026-06-21
+1 -1
View File
@@ -111,7 +111,7 @@ If further discussion is needed, we encourage you to open a new issue instead an
## Building Gitea
See [docs/build-setup.md](docs/build-setup.md) for prerequisites and [docs/development.md](docs/development.md)
See [docs/setup.md](docs/setup.md) for prerequisites and [docs/development.md](docs/development.md)
for building Gitea and the development workflow.
## Styleguide
+1
View File
@@ -41,6 +41,7 @@ Jimmy Praet <jimmy.praet@telenet.be> (@jpraet)
Leon Hofmeister <dev.lh@web.de> (@delvh)
Wim <wim@42.be> (@42wim)
Jason Song <i@wolfogre.com> (@wolfogre)
Yarden Shoham <git@yardenshoham.com> (@yardenshoham)
Yu Tian <zettat123@gmail.com> (@Zettat123)
Dong Ge <gedong_1994@163.com> (@sillyguodong)
Xinyi Gong <hestergong@gmail.com> (@HesterG)
+14 -24
View File
@@ -12,13 +12,13 @@ COMMA := ,
XGO_VERSION := go-1.26.x
AIR_PACKAGE ?= github.com/air-verse/air@v1.65.3 # renovate: datasource=go
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3.8.0 # renovate: datasource=go
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3.7.0 # renovate: datasource=go
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.2 # renovate: datasource=go
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.15 # renovate: datasource=go
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/misspell@v0.8.0 # renovate: datasource=go
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.35.0 # renovate: datasource=go
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.34.1 # renovate: datasource=go
XGO_PACKAGE ?= src.techknowlogick.com/xgo@v1.9.0 # renovate: datasource=go
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1.6.0 # renovate: datasource=go
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1.4.0 # renovate: datasource=go
ACTIONLINT_PACKAGE ?= github.com/rhysd/actionlint/cmd/actionlint@v1.7.12 # renovate: datasource=go
SHELLCHECK_IMAGE ?= docker.io/koalaman/shellcheck:v0.11.0@sha256:61862eba1fcf09a484ebcc6feea46f1782532571a34ed51fedf90dd25f925a8d # renovate: datasource=docker
@@ -113,8 +113,8 @@ LDFLAGS := $(LDFLAGS) -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)"
LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64,linux/riscv64
GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list gitea.dev/modelmigration/...) gitea.dev/tests/integration/migration-test gitea.dev/tests gitea.dev/tests/integration,$(shell $(GO) list ./... | grep -v /vendor/))
MIGRATE_TEST_PACKAGES ?= $(shell $(GO) list gitea.dev/modelmigration/...)
GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list gitea.dev/models/migrations/...) gitea.dev/tests/integration/migration-test gitea.dev/tests gitea.dev/tests/integration,$(shell $(GO) list ./... | grep -v /vendor/))
MIGRATE_TEST_PACKAGES ?= $(shell $(GO) list gitea.dev/models/migrations/...)
FRONTEND_SOURCES := $(shell find web_src/js web_src/css -type f)
FRONTEND_CONFIGS := vite.config.ts tailwind.config.ts
@@ -148,7 +148,6 @@ GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go")
GO_SOURCES += $(GENERATED_GO_DEST)
ESLINT_CONCURRENCY ?= 2
ESLINT_ARGS := --color --max-warnings=0 --concurrency $(ESLINT_CONCURRENCY)
SWAGGER_SPEC := templates/swagger/v1_json.tmpl
SWAGGER_SPEC_INPUT := templates/swagger/v1_input.json
@@ -232,9 +231,7 @@ endif
generate-swagger: $(SWAGGER_SPEC) $(OPENAPI3_SPEC) ## generate the swagger spec from code comments
$(SWAGGER_SPEC): $(GO_SOURCES) $(SWAGGER_SPEC_INPUT)
@output="$$($(GO) run $(SWAGGER_PACKAGE) generate spec --enable-allof-compounding --skip-enum-desc --exclude "$(SWAGGER_EXCLUDE)" --input "$(SWAGGER_SPEC_INPUT)" --output './$(SWAGGER_SPEC)' 2>&1)" || { printf '%s\n' "$$output" >&2; exit 1; }; \
warnings="$$(printf '%s\n' "$$output" | grep -v '^go: ')"; \
if [ -n "$$warnings" ]; then printf '%s\n' "$$warnings" >&2; exit 1; fi
$(GO) run $(SWAGGER_PACKAGE) generate spec --exclude "$(SWAGGER_EXCLUDE)" --input "$(SWAGGER_SPEC_INPUT)" --output './$(SWAGGER_SPEC)'
.PHONY: swagger-check
swagger-check: generate-swagger
@@ -249,11 +246,9 @@ swagger-check: generate-swagger
swagger-validate: ## check if the swagger spec is valid
@# swagger "validate" requires that the "basePath" must start with a slash, but we are using Golang template "{{...}}"
@$(SED_INPLACE) -E -e 's|"basePath":( *)"(.*)"|"basePath":\1"/\2"|g' './$(SWAGGER_SPEC)' # add a prefix slash to basePath
@output="$$($(GO) run $(SWAGGER_PACKAGE) validate './$(SWAGGER_SPEC)' 2>&1)"; status=$$?; \
$(SED_INPLACE) -E -e 's|"basePath":( *)"/(.*)"|"basePath":\1"\2"|g' './$(SWAGGER_SPEC)'; \
printf '%s\n' "$$output" | grep -v '^go: '; \
[ $$status -eq 0 ] || exit $$status; \
case "$$output" in *WARNING:*) exit 1;; esac
@# FIXME: there are some warnings
$(GO) run $(SWAGGER_PACKAGE) validate './$(SWAGGER_SPEC)'
@$(SED_INPLACE) -E -e 's|"basePath":( *)"/(.*)"|"basePath":\1"\2"|g' './$(SWAGGER_SPEC)' # remove the prefix slash from basePath
.PHONY: generate-openapi3
generate-openapi3: $(OPENAPI3_SPEC) ## generate the OpenAPI 3.0 spec from the Swagger 2.0 spec
@@ -299,12 +294,12 @@ lint-backend-fix: lint-go-fix lint-editorconfig ## lint backend files and fix is
.PHONY: lint-js
lint-js: node_modules ## lint js and ts files
pnpm exec eslint $(ESLINT_ARGS) $(ESLINT_FILES)
pnpm exec eslint --color --max-warnings=0 --concurrency $(ESLINT_CONCURRENCY) $(ESLINT_FILES)
pnpm exec vue-tsc
.PHONY: lint-js-fix
lint-js-fix: node_modules ## lint js and ts files and fix issues
pnpm exec eslint $(ESLINT_ARGS) $(ESLINT_FILES) --fix
pnpm exec eslint --color --max-warnings=0 --concurrency $(ESLINT_CONCURRENCY) $(ESLINT_FILES) --fix
pnpm exec vue-tsc
.PHONY: lint-css
@@ -368,11 +363,11 @@ lint-yaml: .venv ## lint yaml files
.PHONY: lint-json
lint-json: node_modules ## lint json files
pnpm exec eslint -c eslint.json.config.ts $(ESLINT_ARGS)
pnpm exec eslint -c eslint.json.config.ts --color --max-warnings=0 --concurrency $(ESLINT_CONCURRENCY)
.PHONY: lint-json-fix
lint-json-fix: node_modules ## lint and fix json files
pnpm exec eslint -c eslint.json.config.ts $(ESLINT_ARGS) --fix
pnpm exec eslint -c eslint.json.config.ts --color --max-warnings=0 --concurrency $(ESLINT_CONCURRENCY) --fix
.PHONY: watch
watch: ## watch everything and continuously rebuild
@@ -426,12 +421,7 @@ unit-test-coverage:
.PHONY: tidy
tidy: ## run go mod tidy
$(eval MIN_GO_VERSION := $(shell grep -Eo '^go\s+[0-9]+\.[0-9.]+' go.mod | cut -d' ' -f2))
$(eval GO_TOOLCHAIN := $(shell grep -Eo '^toolchain\s+go[0-9.]+' go.mod | cut -d' ' -f2))
$(GO) mod tidy -compat=$(MIN_GO_VERSION)
@# workaround https://github.com/golang/go/issues/75331: restore toolchain if tidy dropped it
@if [ -n "$(GO_TOOLCHAIN)" ] && ! grep -qE '^toolchain\s' go.mod; then \
$(GO) mod edit -toolchain=$(GO_TOOLCHAIN); \
fi
@$(MAKE) --no-print-directory $(GO_LICENSE_FILE)
vendor: go.mod go.sum
@@ -483,7 +473,7 @@ migrations.individual.test:
.PHONY: migrations.individual.test\#%
migrations.individual.test\#%:
$(GO) test $(GOTEST_FLAGS) -tags '$(TAGS)' gitea.dev/modelmigration/$*
$(GO) test $(GOTEST_FLAGS) -tags '$(TAGS)' gitea.dev/models/migrations/$*
.PHONY: playwright
playwright: deps-frontend
+28 -37
View File
@@ -6,19 +6,9 @@ If you discover a security issue, please bring it to their attention right away!
Previous vulnerabilities are listed at https://about.gitea.com/security.
## Supported Versions
Security fixes follow our [support policy](docs/release-management.md#end-of-life-eol): only the most recent major release and the `main` branch receive them.
Reports must be filed against a supported version. Before reporting, verify that the issue reproduces on a supported version; any report that only affects an unsupported version will be closed as out of scope.
## Reporting a Vulnerability
Please **DO NOT** file a public issue. Instead, report the vulnerability privately by opening a [GitHub security advisory](https://github.com/go-gitea/gitea/security/advisories/new), or optionally by sending your report to `security@gitea.io`.
If reporting via GitHub, open an advisory per found issue. You can group the found issues if they relate to a single area (same feature, same fault present in multiple routes) but do not group unrelated reports into one as it makes it much harder to assess and track for duplicates.
Do not use LLM to write the reports. It's meant for people to read so take your time and use your own words to write it. If you have used LLM to find the bug, be transparent about it and verify that it is not hallucination before submitting the report.
If your report turns out to be a duplicate, you will be credited in the original report.
Please **DO NOT** file a public issue, instead send your report privately to `security@gitea.io`.
## Protecting Security Information
@@ -29,7 +19,7 @@ The PGP key is valid until July 4, 2026.
```
Key ID: 6FCD2D5B
Key Type: RSA
Expires: 7/23/2027
Expires: 7/4/2026
Key Size: 4096/4096
Fingerprint: 3DE0 3D1E 144A 7F06 9359 99DC AAFD 2381 6FCD 2D5B
```
@@ -52,18 +42,18 @@ lzpAjnN9/KLtQroutrm+Ft0mdjDiJUeFVl1cOHDhoyfCsQh62HumoyZoZvqzQd6e
AbN11nq6aViMe2Q3je1AbiBnRnQSHxt1Tc8X4IshO3MQK1Sk7oPI6LA5oQARAQAB
tCJHaXRlYSBTZWN1cml0eSA8c2VjdXJpdHlAZ2l0ZWEuaW8+iQJXBBMBCABBAhsD
BQsJCAcCAiICBhUKCQgLAgQWAgMBAh4HAheAFiEEPeA9HhRKfwaTWZncqv0jgW/N
LVsFAmpi3IkFCQmOqAsACgkQqv0jgW/NLVsgyxAAuTyj4+PImOFr7ZkEJcseWUy+
gWQrJDagj+Ks2SKGneVroJ63q5Vngx44b7JNabauKel4IJJCScLdwA7k0DKFHPOM
rUS6aavW5+961CMQxJ13vWz7qxLxhI4FXle255xFSXgOo9T1W7+wtm/wtze8+sws
8XKAVBZGuVI1/KzVpE6bWxpIIYK79DC07NWGDAZzMbuO92TFHBRblXsicPWExBjC
/oFmT70YMcA0wOwU/YKYMg2eK2XYUr5+uYX6FnP7iUhDj1vZmwkF33Cj9v9D3Hv9
NzAquj97uLht4wL2sqsIgZd4Vc37uipPDFaddzTb/lon7lPbJPMLObcd4HjSTkIo
nEMM0wdOQZU7mIIgRM9o3mr/gyVigl3uARmUKaP9PhBaOGTjkni0nrv90hSHBHeu
ayM76vl2tzAB2KpDxHIHbI2SEdytV28l/rxWrsbk2kG7s7QB6VKiThTatYevh1kg
6Ujgl2xNSntG6t6PWjQ65OMSq5Iiwe7RfOZkNmPRGP/rbzMbgWXB3iCR2gVQvsxA
ctYdDZdUYAeQ5g6xSKJBloygDQdLzk9m0hqNUyl6gxhRNRw69hqp9E4mxFF3L1Gi
Z2LspLX1ZZWMh0bp0AniWzZuzLuNI0KYhlok6fnshjidJ1qYM/lbz5eJTYWxoJZW
rczn8gB3+MZbULc/iiO5Ag0EYrVn/gEQALrFLQjCR3GjuHSindz0rd3Fnx/t7Sen
LVsFAmhoHmkFCQeT6esACgkQqv0jgW/NLVuFLRAAmjBQSKRAgs2bFIEj7HLAbDp4
f+XkdH+GsT3jRPOZ9QZgmtM+TfoE4yNgIVfOl+s4RdjM/W4QzqZuPQ55hbEHd056
cJmm7B+6GsHFcdrPmh65sOCEIyh4+t45dUfeWpFsDPqm9j1UHXAJQIpB8vDEVAPH
t+3wLCk8GMPJs1o5tIyMmaO23ngvkwn8eG7KgY+rp2PzObrb5g7ppci0ILzILkrp
HVjZsEfUWRgSVF7LuU5ppqDKrlcqwUpQq6n3kGMZcLrCp6ACKP04TBmTfUxNwdL7
I0N7apI2Pbct9T1Gv/lYAUFWyU2c3gh/EBLbO6BukaLOFRQHrtNfdJV/YnMPlcXr
LUJjK9K4eAH9DsrZqrisz/LthsC2BaNIN3KRMTk5YTYgmIh8GXzSgihORmtDFELC
RroID3pTuS0zjXh+wpY9GuPTh7UW23p42Daxca4fAT4k5EclvDRUrL21xMopPMiL
HuNdELz4FVchRTy05PjzKVyjVInDNojE2KUxnjxZDzYJ6aT/g+coD5yfntYm8BEj
+ZzL0ndZES54hzKLpv7zwBQwFzam68clZYmDPILOPTflQDfpGEWmJK4undFU5obz
ZsQRz0R3ulspChATbZxO0d5LX2obLpKO9X3b5VoO1KF+R8Vjw1Y0KxrNZ6rIcfqH
Z50QVQKSe9dm08K0ON+5Ag0EYrVn/gEQALrFLQjCR3GjuHSindz0rd3Fnx/t7Sen
T+p07yCSSoSlmnJHCQmwh4vfg1blyz0zZ4vkIhtpHsEgc+ZAG+WQXSsJ2iRz+eSN
GwoOQl4XC3n+QWkc1ws+btr48+6UqXIQU+F8TPQyx/PIgi2nZXJB7f5+mjCqsk46
XvH4nTr4kJjuqMSR/++wvre2qNQRa/q/dTsK0OaN/mJsdX6Oi+aGNaQJUhIG7F+E
@@ -75,20 +65,21 @@ s+GsP9I3cmWWQcKYxWHtE8xTXnNCVPFZQj2nwhJzae8ypfOtulBRA3dUKWGKuDH/
axFENhUsT397aOU3qkP/od4a64JyNIEo4CTTSPVeWd7njsGqli2U3A4xL2CcyYvt
D/MWcMBGEoLSNTswwKdom4FaJpn5KThnK/T0bQcmJblJhoCtppXisbexZnCpuS0x
Zdlm2T14KJ3LABEBAAGJAjwEGAEIACYCGwwWIQQ94D0eFEp/BpNZmdyq/SOBb80t
WwUCamLcngUJCY6oIAAKCRCq/SOBb80tWxilD/41xF1pwD2lGqjWLmlXcd0Ok5xm
67TSGiKiFZUgI3ftkRVlqmeJqjVmRjpc2dLfCuVBzlaP0Oyv5Jn+2CPqgmWIk5tw
pqlxqmsXiIZ9Uv2wWItxrXIwQ6DHc1qcIOu7feTnt1HVhxp2GqlXl3tA/+MTTDmn
4rqrHffI7ps9eCbK/SfSuoQk3+x/x4GPqWDbsNw1E9dDjPPhsKfdwzZ6dFR2Yhzu
2U0GDc2aeBA0Gjy6VFBj1ksmGxQCL3TqtGEHOonoPpTIjmDd35Xq6BSu119onOQS
THZ7+3JQRpizBVrIklKf33UOikZy9WHuffFddP46m8qC2Alh1aB7xcD8K3P9gzd5
OJO9Zr8JR+rvi8eOsCHvJqGhe0JMMf9bgXKjQ1tMTDTe6r0Jnw7HbkDghjpj9xG7
GYmDB0CL4kP5nAZ1OPfIasIu3Llhcy6mS52ECw0X6PNwUINwBn7F6EKAiciw8/OS
CXoGJDI5alwNhh+3DL4oBH1aq1lnmxmhFNpwpRDvtbRGmZeeASTeC4LMAtqP85Er
8W9ulIgQ4Ub8QuoxvE5hzWEB1QUkJgozI8vO4DoGlrsz7P8cPzrOT7WqUfUPTYE6
oZEfEYDSj1IZHnPYPS+yLBJMJ/Lc1h8OCetmbJZx4QWaX3Fgar7Zks8FfJQOTN6i
HnOlrsaMDYNyO76uBQ==
=4kVJ
WwUCaGgeJAUJB5PppgAKCRCq/SOBb80tW/NWEACB6Jrf0gWlk7e+hNCdnbM0ZVWU
f2sHNFfXxxsdhpcDgKbNHtkZb8nZgv8AX+5fTtUwMVa3vKcdw30xFiIM5N7cCIPV
vg/5z5BtfEaitnabEUG2iiVDIy8IHXIcK10rX+7BosA3QDl2PsiBHwyi5G13lRk8
zGTSNDuOalug33h5/lr2dPigamkq74Aoy29q8Rjad6GfWHipL2bFimgtY+Zdi0BH
NLk4EJXxj1SgVx5dtkQzWJReBA5M+FQ4QYQZBO+f4TDoOLmjui152uhkoLBQbGAa
WWJFTVxm0bG5MXloEL3gA8DfU7XDwuW/sHJC5pBko8RpQViooOhckMepZV3Y83DK
bwLYa3JmPgj2rEv4993dvrJbQhpGd082HOxOsllCs8pgNq1SnXpWYfcGTgGKC3ts
U8YZUUJUQ7mi2L8Tv3ix20c9EiGmA30JAmA8eZTC3cWup91ZkkVBFRml2czTXajd
RWZ6GbHV5503ueDQcB8yBVgF3CSixs67+dGSbD3p86OqGrjAcJzM5TFbNKcnGLdE
kGbZpNwAISy750lXzXKmyrh5RTCeTOQerbwCMBvHZO+HAevA/LXDTw2OAiSIQlP5
sYA4sFYLQ30OAkgJcmdp/pSgVj/erNtSN07ClrOpDb/uFpQymO6K2h0Pst3feNVK
9M2VbqL9C51z/wyHLg==
=SfZA
-----END PGP PUBLIC KEY BLOCK-----
```
Security reports are greatly appreciated and we will publicly thank you for it, although we keep your name confidential if you request it.
-8
View File
@@ -436,7 +436,6 @@
"jsonl",
"mcmeta",
"sarif",
"slnlaunch",
"tact",
"tfstate",
"topojson",
@@ -692,17 +691,10 @@
"extensions": [
"ini",
"cnf",
"container",
"dof",
"lektorproject",
"mount",
"network",
"prefs",
"properties",
"service",
"socket",
"target",
"timer",
"url",
"conf"
],
+17 -2
View File
File diff suppressed because one or more lines are too long
+3 -2
View File
@@ -11,6 +11,7 @@ import (
"gitea.dev/models/db"
repo_model "gitea.dev/models/repo"
"gitea.dev/modules/git"
"gitea.dev/modules/gitrepo"
"gitea.dev/modules/log"
repo_module "gitea.dev/modules/repository"
@@ -127,8 +128,8 @@ func runRepoSyncReleases(ctx context.Context, _ *cli.Command) error {
}
log.Trace("Processing next %d repos of %d", len(repos), count)
for _, repo := range repos {
log.Trace("Synchronizing repo %s", repo.FullName())
gitRepo, err := git.OpenRepository(repo)
log.Trace("Synchronizing repo %s with path %s", repo.FullName(), repo.RelativePath())
gitRepo, err := gitrepo.OpenRepository(ctx, repo)
if err != nil {
log.Warn("OpenRepository: %v", err)
continue
-1
View File
@@ -18,7 +18,6 @@ func newUserCommand() *cli.Command {
microcmdUserDelete(),
newUserGenerateAccessTokenCommand(),
microcmdUserMustChangePassword(),
microcmdUserDisableTwoFactor(),
},
}
}
-72
View File
@@ -1,72 +0,0 @@
// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"context"
"errors"
"fmt"
"strings"
auth_model "gitea.dev/models/auth"
user_model "gitea.dev/models/user"
"gitea.dev/modules/setting"
"github.com/urfave/cli/v3"
)
func microcmdUserDisableTwoFactor() *cli.Command {
return &cli.Command{
Name: "disable-2fa",
Usage: "Disable two-factor authentication for a user",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "username",
Aliases: []string{"u"},
Usage: "Username of the user to disable 2FA for",
},
&cli.Int64Flag{
Name: "id",
Usage: "ID of the user to disable 2FA for",
},
},
Action: runDisableTwoFactor,
}
}
func runDisableTwoFactor(ctx context.Context, c *cli.Command) error {
if !c.IsSet("id") && !c.IsSet("username") {
return errors.New("either --id or --username must be provided")
}
if !setting.IsInTesting {
if err := initDB(ctx); err != nil {
return err
}
}
var user *user_model.User
var err error
if c.IsSet("id") {
user, err = user_model.GetUserByID(ctx, c.Int64("id"))
} else {
user, err = user_model.GetUserByName(ctx, c.String("username"))
}
if err != nil {
return err
}
// When both selectors are given, make sure they refer to the same user.
if c.IsSet("id") && c.IsSet("username") && user.LowerName != strings.ToLower(strings.TrimSpace(c.String("username"))) {
return fmt.Errorf("the user with id %d is %q, which does not match the provided username %q", user.ID, user.Name, c.String("username"))
}
totp, webAuthn, err := auth_model.DisableTwoFactor(ctx, user.ID)
if err != nil {
return err
}
fmt.Printf("Disabled 2FA for user %q (removed %d TOTP and %d WebAuthn credential(s))\n", user.Name, totp, webAuthn)
return nil
}
-119
View File
@@ -1,119 +0,0 @@
// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"io"
"strconv"
"testing"
auth_model "gitea.dev/models/auth"
"gitea.dev/models/db"
"gitea.dev/models/unittest"
user_model "gitea.dev/models/user"
"github.com/go-webauthn/webauthn/webauthn"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestDisableTwoFactorCommand(t *testing.T) {
ctx := t.Context()
defer func() {
require.NoError(t, db.TruncateBeans(t.Context(), &user_model.User{}, &auth_model.TwoFactor{}, &auth_model.WebAuthnCredential{}))
}()
t.Run("disable TOTP and WebAuthn", func(t *testing.T) {
require.NoError(t, microcmdUserCreate().Run(ctx, []string{"create", "--username", "tfuser", "--email", "tfuser@gitea.local", "--random-password"}))
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: "tfuser"})
// Enroll TOTP.
tf := &auth_model.TwoFactor{UID: user.ID}
require.NoError(t, tf.SetSecret("test-secret"))
_, err := tf.GenerateScratchToken()
require.NoError(t, err)
require.NoError(t, auth_model.NewTwoFactor(ctx, tf))
// Register a WebAuthn credential.
_, err = auth_model.CreateCredential(ctx, user.ID, "test-key", &webauthn.Credential{ID: []byte("test-cred-id")})
require.NoError(t, err)
has, err := auth_model.HasTwoFactorOrWebAuthn(ctx, user.ID)
require.NoError(t, err)
require.True(t, has)
require.NoError(t, microcmdUserDisableTwoFactor().Run(ctx, []string{"disable-2fa", "--username", "tfuser"}))
// Both factors must be gone afterwards.
has, err = auth_model.HasTwoFactorOrWebAuthn(ctx, user.ID)
require.NoError(t, err)
assert.False(t, has)
})
t.Run("disable by id", func(t *testing.T) {
require.NoError(t, microcmdUserCreate().Run(ctx, []string{"create", "--username", "iduser", "--email", "iduser@gitea.local", "--random-password"}))
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: "iduser"})
tf := &auth_model.TwoFactor{UID: user.ID}
require.NoError(t, tf.SetSecret("test-secret"))
require.NoError(t, auth_model.NewTwoFactor(ctx, tf))
require.NoError(t, microcmdUserDisableTwoFactor().Run(ctx, []string{"disable-2fa", "--id", strconv.FormatInt(user.ID, 10)}))
has, err := auth_model.HasTwoFactorOrWebAuthn(ctx, user.ID)
require.NoError(t, err)
assert.False(t, has)
})
t.Run("no enrollment is a no-op", func(t *testing.T) {
require.NoError(t, microcmdUserCreate().Run(ctx, []string{"create", "--username", "plainuser", "--email", "plainuser@gitea.local", "--random-password"}))
require.NoError(t, microcmdUserDisableTwoFactor().Run(ctx, []string{"disable-2fa", "--username", "plainuser"}))
})
t.Run("id and username must match when both given", func(t *testing.T) {
require.NoError(t, microcmdUserCreate().Run(ctx, []string{"create", "--username", "matchuser", "--email", "matchuser@gitea.local", "--random-password"}))
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: "matchuser"})
id := strconv.FormatInt(user.ID, 10)
// Matching id + username is accepted.
require.NoError(t, microcmdUserDisableTwoFactor().Run(ctx, []string{"disable-2fa", "--id", id, "--username", "matchuser"}))
// Mismatched id + username is rejected.
cmd := microcmdUserDisableTwoFactor()
cmd.Writer, cmd.ErrWriter = io.Discard, io.Discard
err := cmd.Run(ctx, []string{"disable-2fa", "--id", id, "--username", "someotheruser"})
require.Error(t, err)
require.Contains(t, err.Error(), "does not match the provided username")
})
t.Run("failure cases", func(t *testing.T) {
testCases := []struct {
name string
args []string
expectedErr string
}{
{
name: "user does not exist",
args: []string{"disable-2fa", "--username", "nonexistentuser"},
expectedErr: "user does not exist",
},
{
name: "neither id nor username",
args: []string{"disable-2fa"},
expectedErr: "either --id or --username must be provided",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
cmd := microcmdUserDisableTwoFactor()
cmd.Writer, cmd.ErrWriter = io.Discard, io.Discard
err := cmd.Run(ctx, tc.args)
require.Error(t, err)
require.Contains(t, err.Error(), tc.expectedErr)
})
}
})
}
+4 -4
View File
@@ -12,9 +12,9 @@ import (
"strings"
"text/tabwriter"
"gitea.dev/modelmigration"
"gitea.dev/modelmigration/base"
"gitea.dev/models/db"
"gitea.dev/models/migrations"
migrate_base "gitea.dev/models/migrations/base"
"gitea.dev/modules/container"
"gitea.dev/modules/log"
"gitea.dev/modules/setting"
@@ -129,10 +129,10 @@ func runRecreateTable(ctx context.Context, cmd *cli.Command) error {
if err != nil {
return err
}
recreateTables := base.RecreateTables(beans...)
recreateTables := migrate_base.RecreateTables(beans...)
return db.InitEngineWithMigration(context.Background(), func(ctx context.Context, x db.EngineMigration) error {
if err := modelmigration.EnsureUpToDate(ctx, x); err != nil {
if err := migrations.EnsureUpToDate(ctx, x); err != nil {
return err
}
return recreateTables(x)
+1 -1
View File
@@ -198,7 +198,7 @@ func runDump(ctx context.Context, cmd *cli.Command) error {
}
defer func() {
_ = dbDump.Close()
if err := os.Remove(dbDump.Name()); err != nil {
if err := util.Remove(dbDump.Name()); err != nil {
log.Warn("Unable to remove temporary file: %s: Error: %v", dbDump.Name(), err)
}
}()
+2 -1
View File
@@ -18,6 +18,7 @@ import (
"gitea.dev/modules/public"
"gitea.dev/modules/setting"
"gitea.dev/modules/templates"
"gitea.dev/modules/util"
"github.com/urfave/cli/v3"
)
@@ -254,7 +255,7 @@ func extractAsset(d string, a assetFile, overwrite, rename bool) error {
} else if !fi.Mode().IsRegular() {
return fmt.Errorf("%s already exists, but it's not a regular file", dest)
} else if rename {
if err := os.Rename(dest, dest+".bak"); err != nil {
if err := util.Rename(dest, dest+".bak"); err != nil {
return fmt.Errorf("error creating backup for %s: %w", dest, err)
}
// Attempt to respect file permissions mask (even if user:group will be set anew)
+36 -27
View File
@@ -201,27 +201,35 @@ func runServ(ctx context.Context, c *cli.Command) error {
return fail(ctx, "Too few arguments", "Too few arguments in cmd: %s", cmd)
}
var reqOwnerName, reqRepoName string
{
var ok bool
reqRepoPath := strings.TrimPrefix(sshCmdArgs[1], "/")
reqOwnerName, reqRepoName, ok = strings.Cut(reqRepoPath, "/")
if !ok {
return fail(ctx, "Invalid repository path", "Invalid repository path: %v", reqRepoPath)
}
reqRepoName = strings.TrimSuffix(reqRepoName, ".git") // "the-repo-name" or "the-repo-name.wiki"
repoPath := strings.TrimPrefix(sshCmdArgs[1], "/")
repoPathFields := strings.SplitN(repoPath, "/", 2)
if len(repoPathFields) != 2 {
return fail(ctx, "Invalid repository path", "Invalid repository path: %v", repoPath)
}
if !repo_model.IsValidSSHAccessRepoName(reqRepoName) {
return fail(ctx, "Invalid repo name", "Invalid repo name: %s", reqRepoName)
username := repoPathFields[0]
reponame := strings.TrimSuffix(repoPathFields[1], ".git") // “the-repo-name" or "the-repo-name.wiki"
if !repo_model.IsValidSSHAccessRepoName(reponame) {
return fail(ctx, "Invalid repo name", "Invalid repo name: %s", reponame)
}
if c.Bool("enable-pprof") {
stopProfiler, err := pprof.DumpPprofForUsername(setting.PprofDataPath, reqOwnerName)
if err != nil {
return fail(ctx, "Unable to start pprof profiler", "Unable to start pprof profile: %v", err)
if err := os.MkdirAll(setting.PprofDataPath, os.ModePerm); err != nil {
return fail(ctx, "Error while trying to create PPROF_DATA_PATH", "Error while trying to create PPROF_DATA_PATH: %v", err)
}
defer stopProfiler()
stopCPUProfiler, err := pprof.DumpCPUProfileForUsername(setting.PprofDataPath, username)
if err != nil {
return fail(ctx, "Unable to start CPU profiler", "Unable to start CPU profile: %v", err)
}
defer func() {
stopCPUProfiler()
err := pprof.DumpMemProfileForUsername(setting.PprofDataPath, username)
if err != nil {
_ = fail(ctx, "Unable to dump Mem profile", "Unable to dump Mem Profile: %v", err)
}
}()
}
verb, lfsVerb := sshCmdArgs[0], ""
@@ -246,29 +254,30 @@ func runServ(ctx context.Context, c *cli.Command) error {
return fail(ctx, "Unknown git command", "Unknown git command %s %s", verb, lfsVerb)
}
results, extra := private.ServCommand(ctx, keyID, reqOwnerName, reqRepoName, requestedMode, verb, lfsVerb)
results, extra := private.ServCommand(ctx, keyID, username, reponame, requestedMode, verb, lfsVerb)
if extra.HasError() {
return fail(ctx, extra.UserMsg, "ServCommand failed: %s", extra.Error)
}
// because the original repoPath maybe redirected, we need to use the returned actual repository information
if results.IsWiki {
repoPath = repo_model.RelativeWikiPath(results.OwnerName, results.RepoName)
} else {
repoPath = repo_model.RelativePath(results.OwnerName, results.RepoName)
}
// LFS SSH protocol
if verb == git.CmdVerbLfsTransfer {
if results.IsWiki {
return fail(ctx, "LFS Transfer is not supported for wikis", "")
}
token, err := lfs.GetLFSAuthTokenWithBearer(lfs.AuthTokenOptions{Op: lfsVerb, UserID: results.UserID, RepoID: results.RepoID})
if err != nil {
return err
}
return lfstransfer.Main(ctx, results.OwnerName, results.RepoName, lfsVerb, token)
return lfstransfer.Main(ctx, repoPath, lfsVerb, token)
}
// LFS token authentication
if verb == git.CmdVerbLfsAuthenticate {
if results.IsWiki {
return fail(ctx, "LFS Authenticate is not supported for wikis", "")
}
lfsTokenHref := fmt.Sprintf("%s%s/%s.git/info/lfs", setting.AppURL, url.PathEscape(results.OwnerName), url.PathEscape(results.RepoName))
url := fmt.Sprintf("%s%s/%s.git/info/lfs", setting.AppURL, url.PathEscape(results.OwnerName), url.PathEscape(results.RepoName))
token, err := lfs.GetLFSAuthTokenWithBearer(lfs.AuthTokenOptions{Op: lfsVerb, UserID: results.UserID, RepoID: results.RepoID})
if err != nil {
@@ -277,7 +286,7 @@ func runServ(ctx context.Context, c *cli.Command) error {
tokenAuthentication := &git_model.LFSTokenResponse{
Header: make(map[string]string),
Href: lfsTokenHref,
Href: url,
}
tokenAuthentication.Header["Authorization"] = token
@@ -298,12 +307,12 @@ func runServ(ctx context.Context, c *cli.Command) error {
verbFields := strings.SplitN(verb, "-", 2)
if len(verbFields) == 2 {
// use git binary with the sub-command part: "C:\...\bin\git.exe", "upload-pack", ...
command = exec.CommandContext(ctx, gitcmd.GitExecutable, verbFields[1], results.RepoStoragePath)
command = exec.CommandContext(ctx, gitcmd.GitExecutable, verbFields[1], repoPath)
}
}
if command == nil {
// by default, use the verb (it has been checked above by allowedCommands)
command = exec.CommandContext(ctx, gitBinVerb, results.RepoStoragePath)
command = exec.CommandContext(ctx, gitBinVerb, repoPath)
}
process.SetSysProcAttribute(command)
+7 -21
View File
@@ -1198,7 +1198,6 @@ LEVEL = Info
;; Default source for the pull request title when opening a new PR.
;; "first-commit" uses the oldest commit's summary.
;; "auto" uses commit's summary if the PR only has one commit, normalizes the branch name if multiple commits.
;; "branch-name" always uses the PR's branch name.
;DEFAULT_TITLE_SOURCE = auto
;;
;; Delay mergeable check until page view or API access, for pull requests that have not been updated in the specified days when their base branches get updated.
@@ -1603,19 +1602,6 @@ LEVEL = Info
;; If you'd like to enable it, you can set it to a value between 0 and 2.
;TYPE_BLEVE_MAX_FUZZINESS = 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[redis]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Shared redis connection, used as the default for every redis-backed subsystem
;; (cache, session, queue, global lock, etc.) whose own connection string is left empty.
;; A per-subsystem connection value always takes precedence over this shared default.
;; When left empty, each subsystem keeps its previous behavior (no shared default).
;; e.g. `redis://127.0.0.1:6379/0` (or `redis+cluster://127.0.0.1:6379/0` for a Redis cluster)
;CONN_STR =
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[queue]
@@ -1641,10 +1627,10 @@ LEVEL = Info
;; Batch size to send for batched queues
;BATCH_LENGTH = 20
;;
;; Connection string for redis queues this will store the redis (or Redis cluster) connection string.
;; When `TYPE` is `persistable-channel`, this provides a directory for the underlying leveldb
;; or additional options of the form `leveldb://path/to/db?option=value&....`, and will override `DATADIR`.
;; When `TYPE` is `redis` and this is left empty, it falls back to the shared [redis] CONN_STR.
;CONN_STR =
;CONN_STR = "redis://127.0.0.1:6379/0"
;;
;; Provides the suffix of the default redis/disk queue name - specific queues can be overridden within in their [queue.name] sections.
;QUEUE_NAME = "_queue"
@@ -1942,7 +1928,7 @@ LEVEL = Info
;INTERVAL = 60
;;
;; For "redis" and "memcache", connection host address
;; redis: default to shared [redis] CONN_STR
;; redis: `redis://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s` (or `redis+cluster://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s` for a Redis cluster)
;; memcache: `127.0.0.1:11211`
;; twoqueue: `{"size":50000,"recent_ratio":0.25,"ghost_ratio":0.5}` or `50000`
;HOST =
@@ -1978,10 +1964,10 @@ LEVEL = Info
;;
;; Provider config options
;; memory: doesn't have any config yet
;; file: session file path, e.g. `data/sessions`, relative paths will be made absolute against _`AppWorkPath`_.
;; redis: default to [redis] CONN_STR
;; file: session file path, e.g. `data/sessions`
;; redis: `redis://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s` (or `redis+cluster://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s` for a Redis cluster)
;; mysql: go-sql-driver/mysql dsn config string, e.g. `root:password@/session_table`
;PROVIDER_CONFIG =
;PROVIDER_CONFIG = data/sessions ; Relative paths will be made absolute against _`AppWorkPath`_.
;;
;; Session cookie name
;COOKIE_NAME = i_like_gitea
@@ -3040,5 +3026,5 @@ LEVEL = Info
;[global_lock]
;; Lock service type, could be memory or redis
;SERVICE_TYPE = memory
;; Ignored for the "memory" type. For "redis", default to [redis] CONN_STR.
;; Ignored for the "memory" type. For "redis" use something like `redis://127.0.0.1:6379/0`
;SERVICE_CONN_STR =
+4 -4
View File
@@ -53,10 +53,10 @@ For packagers who need to use paths like `/etc/gitea/app.ini`,
they should define these values at build time for `make build` by environment variable like
`LDFLAGS='-X "module.Var1=Value1" -X "module.Var2=Value2"' TAGS="bindata" make build`.
- _`CustomConf`_: `-X "gitea.dev/modules/setting.CustomConf=/etc/gitea/app.ini"`
- _`AppWorkPath`_: `-X "gitea.dev/modules/setting.AppWorkPath=/var/lib/gitea"`
- _`CustomPath`_: `-X "gitea.dev/modules/setting.CustomPath=/var/lib/gitea/custom"`
- Default PID file location: `-X "gitea.dev/cmd.PIDFile=/run/gitea.pid"`
- _`CustomConf`_: `-X "code.gitea.io/gitea/modules/setting.CustomConf=/etc/gitea/app.ini"`
- _`AppWorkPath`_: `-X "code.gitea.io/gitea/modules/setting.AppWorkPath=/var/lib/gitea"`
- _`CustomPath`_: `-X "code.gitea.io/gitea/modules/setting.CustomPath=/var/lib/gitea/custom"`
- Default PID file location: `-X "code.gitea.io/gitea/cmd.PIDFile=/run/gitea.pid"`
Add as many of the strings with their preceding `-X` to the `LDFLAGS` variable and run `make build`
with the appropriate `TAGS` as above.
+6 -20
View File
@@ -95,15 +95,8 @@ However, if there are no objections from maintainers, the PR can be merged with
### Commit messages
Mergers are required to rewrite the PR title and the first comment (the summary) when necessary so the squash commit message is clear.
Usually the Pull Request description and commit message body should not be empty, unless the title is already clear enough or the description would be a copy of the comments in code.
The final commit message:
- should match the code changes.
- should only keep true co-authors, false-positive co-authors should be removed.
- should not hedge: replace phrases like `hopefully, <x> won't happen anymore` with definite wording.
- should not contain hidden information like `<!-- -->` or extra information after the description's divider `----`.
- should not contain unrelated contents (e.g.: Release Notes, Configuration, etc.) from a Renovate update PR.
The final commit message should not hedge: replace phrases like `hopefully, <x> won't happen anymore` with definite wording.
#### PR Co-authors
@@ -165,16 +158,9 @@ Any account with write access (including bots and TOC members) **must** use [2FA
Mergers are the maintainers who carry out the final merge of approved PRs. Their responsibilities, described throughout this guide, are:
- Merging PRs from the [merge queue](#getting-prs-merged) in order, once a PR has `lgtm/done`, no open discussions, and no merge conflicts.
- Rewriting the PR title and description prior to the merge, making the [commit message](#commit-messages) clear.\
In particular, mergers should edit the PR description.\
Mergers should **not** edit the actual commit message except to remove unnecessary information. Because of that, even if users are looking at the PR, they can understand what changed.
- Rewriting the PR title and summary so the squash [commit message](#commit-messages) is clear, removing false-positive co-authors while keeping every true co-author.
- Assigning the correct labels (including `type/…`) needed for changelog and backport decisions.
- Agreeing, together with the owners, on when a release is ready (see [release management](release-management.md)).
- Merging a PR also means the PR looks good to the merger and is approved by the merger.
If a merger violates these merge guides more than 3 times in the past 365 days
(e.g.: merge with unresolved reviews without TOC decision to ignore the review, merge with garbage commit messages),
they may lose their merging privileges for at least three months.
#### Becoming a merger
@@ -214,20 +200,20 @@ random.seed("Gitea TOC <YEAR> Election")
random.choice([<CANDIDATE_1>, <CANDIDATE_2>, ...])
```
The result of this script needs then to be published in the TOC election issue to ensure transparency of the process.
The result of this script needs then to be published in the TOC election issue to ensure transparency of the process.
### Current TOC members
- 2026-06-14 ~ 2026-12-31
- Company
- [Yu Tian](https://gitea.com/Zettat123) <zettat123@gmail.com>
- [Jason Song](https://gitea.com/wolfogre) <i@wolfogre.com>
- [Lunny Xiao](https://gitea.com/lunny) <xiaolunwen@gmail.com>
- [Matti Ranta](https://gitea.com/techknowlogick) <techknowlogick@gitea.com>
- Community
- [bircni](https://gitea.com/bircni) <bircni@icloud.com>
- [delvh](https://gitea.com/delvh) <dev.lh@web.de>
- [TheFox0x7](https://gitea.com/TheFox0x7) <thefox0x7@gmail.com>
### Previous TOC/owners members
@@ -241,7 +227,7 @@ Here's the history of the owners and the time they served:
- [Andrew Thornton](https://gitea.com/zeripath) - [2020](https://github.com/go-gitea/gitea/issues/9230), [2021](https://github.com/go-gitea/gitea/issues/13801), [2022](https://github.com/go-gitea/gitea/issues/17872), 2023
- [6543](https://gitea.com/6543) - 2023, 2025
- [John Olheiser](https://gitea.com/jolheiser) - 2023, 2024
- [Jason Song](https://gitea.com/wolfogre) - 2023, 2025
- [Jason Song](https://gitea.com/wolfogre) - 2023
## Governance Compensation
+1 -1
View File
@@ -109,7 +109,7 @@ which lives in the [documentation repository](https://gitea.com/gitea/docs).
## Database migrations
If you make breaking changes to a database-persisted struct under `models/`, add a
new migration in `modelmigration/`. See [testing.md](testing.md#migration-tests)
new migration in `models/migrations/`. See [testing.md](testing.md#migration-tests)
for running the migration tests.
## Testing
+1 -1
View File
@@ -23,7 +23,7 @@ The backend is split into top-level packages, each with a focused responsibility
dependencies to a minimum
- `models/db`: core database operations
- `models/fixtures`: sample data used by tests
- `modelmigration`: schema migration scripts
- `models/migrations`: schema migration scripts
- `modules`: standalone functionality with few dependencies
- `modules/setting`: configuration handling
- `modules/git`: interaction with the Git command line
+1 -1
View File
@@ -136,7 +136,7 @@ Useful environment variables:
## Migration tests
If you change a database-persisted struct under `models/` you will usually need a
new migration in `modelmigration`. Run the migration tests with:
new migration in `models/migrations/`. Run the migration tests with:
```bash
make test-migration
+48 -33
View File
@@ -1,8 +1,11 @@
import arrayFunc from 'eslint-plugin-array-func';
import comments from '@eslint-community/eslint-plugin-eslint-comments';
import deMorgan from 'eslint-plugin-de-morgan';
import globals from 'globals';
import importPlugin from 'eslint-plugin-import-x';
import playwright from 'eslint-plugin-playwright';
import regexp from 'eslint-plugin-regexp';
import sonarjs from 'eslint-plugin-sonarjs';
import stylistic from '@stylistic/eslint-plugin';
import typescriptParser from '@typescript-eslint/parser';
import typescriptPlugin from 'typescript-eslint';
@@ -12,6 +15,7 @@ import vue from 'eslint-plugin-vue';
import vueScopedCss from 'eslint-plugin-vue-scoped-css';
import wc from 'eslint-plugin-wc';
import {defineConfig, globalIgnores} from 'eslint/config';
import type {ESLint} from 'eslint';
import unescapedHtmlLiteral from './tools/eslint-rules/unescaped-html-literal.ts';
@@ -60,9 +64,12 @@ export default defineConfig([
'@eslint-community/eslint-comments': comments,
'@stylistic': stylistic,
'@typescript-eslint': typescriptPlugin.plugin,
'array-func': arrayFunc,
'de-morgan': deMorgan,
'gitea': {rules: {'unescaped-html-literal': unescapedHtmlLiteral}},
'import-x': importPlugin,
'import-x': importPlugin as unknown as ESLint.Plugin, // https://github.com/un-ts/eslint-plugin-import-x/issues/203
regexp,
sonarjs,
unicorn,
wc,
},
@@ -271,6 +278,12 @@ export default defineConfig([
'@typescript-eslint/unified-signatures': [2],
'accessor-pairs': [2],
'array-callback-return': [2, {checkForEach: true}],
'array-func/avoid-reverse': [2],
'array-func/from-map': [2],
'array-func/no-unnecessary-this-arg': [2],
'array-func/prefer-array-from': [2],
'array-func/prefer-flat-map': [0], // handled by unicorn/prefer-array-flat-map
'array-func/prefer-flat': [0], // handled by unicorn/prefer-array-flat
'arrow-body-style': [0],
'block-scoped-var': [2],
'camelcase': [0],
@@ -281,6 +294,8 @@ export default defineConfig([
'consistent-this': [0],
'constructor-super': [2],
'curly': [0],
'de-morgan/no-negated-conjunction': [2],
'de-morgan/no-negated-disjunction': [2],
'default-case-last': [2],
'default-case': [0],
'default-param-last': [0],
@@ -568,7 +583,7 @@ export default defineConfig([
'no-useless-constructor': [2],
'no-useless-escape': [2],
'no-useless-rename': [2],
'no-useless-return': [2],
'no-useless-return': [0], // handled by sonarjs/no-redundant-jump
'no-var': [2],
'no-void': [2],
'no-warning-comments': [0],
@@ -674,6 +689,37 @@ export default defineConfig([
'require-await': [0], // handled by @typescript-eslint/require-await
'require-unicode-regexp': [0],
'require-yield': [2],
'sonarjs/cognitive-complexity': [0],
'sonarjs/elseif-without-else': [0],
'sonarjs/max-switch-cases': [0],
'sonarjs/no-all-duplicated-branches': [2],
'sonarjs/no-collapsible-if': [0],
'sonarjs/no-collection-size-mischeck': [2],
'sonarjs/no-duplicate-string': [0],
'sonarjs/no-duplicated-branches': [0],
'sonarjs/no-element-overwrite': [2],
'sonarjs/no-empty-collection': [2],
'sonarjs/no-extra-arguments': [2],
'sonarjs/no-gratuitous-expressions': [2],
'sonarjs/no-identical-conditions': [0], // handled by no-dupe-else-if
'sonarjs/no-identical-expressions': [2],
'sonarjs/no-identical-functions': [2, 5],
'sonarjs/no-ignored-return': [2],
'sonarjs/no-inverted-boolean-check': [2],
'sonarjs/no-nested-switch': [0],
'sonarjs/no-nested-template-literals': [0],
'sonarjs/no-redundant-boolean': [2],
'sonarjs/no-redundant-jump': [2],
'sonarjs/no-same-line-conditional': [2],
'sonarjs/no-small-switch': [0],
'sonarjs/no-unused-collection': [2],
'sonarjs/no-use-of-empty-return-value': [2],
'sonarjs/no-useless-catch': [0], // handled by no-useless-catch
'sonarjs/non-existent-operator': [2],
'sonarjs/prefer-immediate-return': [0],
'sonarjs/prefer-object-literal': [0],
'sonarjs/prefer-single-boolean-return': [0],
'sonarjs/prefer-while': [2],
'sort-imports': [0],
'sort-keys': [0],
'sort-vars': [0],
@@ -699,7 +745,6 @@ export default defineConfig([
'unicorn/consistent-json-file-read': [2],
'unicorn/consistent-optional-chaining': [2],
'unicorn/consistent-template-literal-escape': [2],
'unicorn/consistent-tuple-labels': [2],
'unicorn/custom-error-definition': [0],
'unicorn/default-export-style': [2],
'unicorn/dom-node-dataset': [2, {preferAttributes: true}],
@@ -733,7 +778,6 @@ export default defineConfig([
'unicorn/no-array-sort-for-min-max': [2],
'unicorn/no-array-splice': [0],
'unicorn/no-asterisk-prefix-in-documentation-comments': [0],
'unicorn/no-async-promise-finally': [2],
'unicorn/no-await-expression-member': [0],
'unicorn/no-await-in-promise-methods': [2],
'unicorn/no-blob-to-file': [2],
@@ -770,18 +814,14 @@ export default defineConfig([
'unicorn/no-invalid-fetch-options': [2],
'unicorn/no-invalid-file-input-accept': [2],
'unicorn/no-invalid-remove-event-listener': [2],
'unicorn/no-invalid-well-known-symbol-methods': [2],
'unicorn/no-keyword-prefix': [0],
'unicorn/no-late-current-target-access': [2],
'unicorn/no-late-event-control': [2],
'unicorn/no-lonely-if': [2],
'unicorn/no-loop-iterable-mutation': [2],
'unicorn/no-magic-array-flat-depth': [0],
'unicorn/no-manually-wrapped-comments': [0], // too opinionated
'unicorn/no-mismatched-map-key': [2],
'unicorn/no-misrefactored-assignment': [2],
'unicorn/no-missing-local-resource': [0], // only applies to html/css/markdown languages
'unicorn/no-multiple-promise-resolver-calls': [2],
'unicorn/no-named-default': [2],
'unicorn/no-negated-array-predicate': [2],
'unicorn/no-negated-comparison': [2],
@@ -800,7 +840,6 @@ export default defineConfig([
'unicorn/no-redundant-comparison': [2],
'unicorn/no-return-array-push': [2],
'unicorn/no-selector-as-dom-name': [2],
'unicorn/no-shorthand-property-overrides': [0], // only applies to css language
'unicorn/no-single-promise-in-promise-methods': [2],
'unicorn/no-static-only-class': [2],
'unicorn/no-subtraction-comparison': [2],
@@ -809,22 +848,18 @@ export default defineConfig([
'unicorn/no-this-outside-of-class': [0], // gitea uses `this` in non-class functions
'unicorn/no-top-level-assignment-in-function': [0],
'unicorn/no-top-level-side-effects': [0],
'unicorn/no-transition-all': [2],
'unicorn/no-typeof-undefined': [2],
'unicorn/no-uncalled-method': [2],
'unicorn/no-undeclared-class-members': [2],
'unicorn/no-unnecessary-array-flat-depth': [2],
'unicorn/no-unnecessary-array-flat-map': [2],
'unicorn/no-unnecessary-array-splice-count': [2],
'unicorn/no-unnecessary-await': [2],
'unicorn/no-unnecessary-boolean-comparison': [2],
'unicorn/no-unnecessary-fetch-options': [0],
'unicorn/no-unnecessary-global-this': [0],
'unicorn/no-unnecessary-nested-ternary': [2],
'unicorn/no-unnecessary-polyfills': [2],
'unicorn/no-unnecessary-slice-end': [2],
'unicorn/no-unnecessary-splice': [2],
'unicorn/no-unnecessary-string-trim': [2],
'unicorn/no-unreadable-array-destructuring': [0],
'unicorn/no-unreadable-for-of-expression': [0],
'unicorn/no-unreadable-iife': [0],
@@ -832,7 +867,6 @@ export default defineConfig([
'unicorn/no-unreadable-object-destructuring': [0],
'unicorn/no-unsafe-buffer-conversion': [2],
'unicorn/no-unsafe-dom-html': [0],
'unicorn/no-unsafe-promise-all-settled-values': [2],
'unicorn/no-unsafe-property-key': [0],
'unicorn/no-unsafe-string-replacement': [0],
'unicorn/no-unused-array-method-return': [2],
@@ -852,7 +886,6 @@ export default defineConfig([
'unicorn/no-useless-logical-operand': [2],
'unicorn/no-useless-override': [2],
'unicorn/no-useless-promise-resolve-reject': [2],
'unicorn/no-useless-re-export': [2],
'unicorn/no-useless-recursion': [0],
'unicorn/no-useless-spread': [2],
'unicorn/no-useless-switch-case': [2],
@@ -863,17 +896,13 @@ export default defineConfig([
'unicorn/number-literal-case': [0],
'unicorn/numeric-separators-style': [0],
'unicorn/operator-assignment': [2],
'unicorn/prefer-abort-signal-any': [2],
'unicorn/prefer-abort-signal-timeout': [2],
'unicorn/prefer-add-event-listener': [2],
'unicorn/prefer-add-event-listener-options': [2],
'unicorn/prefer-aggregate-error': [2],
'unicorn/prefer-array-find': [0], // handled by @typescript-eslint/prefer-find
'unicorn/prefer-array-flat': [2],
'unicorn/prefer-array-flat-map': [2],
'unicorn/prefer-array-from-async': [2],
'unicorn/prefer-array-from-map': [2],
'unicorn/prefer-array-from-range': [2],
'unicorn/prefer-array-index-of': [2],
'unicorn/prefer-array-iterable-methods': [2],
'unicorn/prefer-array-last-methods': [2],
@@ -883,7 +912,6 @@ export default defineConfig([
'unicorn/prefer-await': [2],
'unicorn/prefer-bigint-literals': [2],
'unicorn/prefer-blob-reading-methods': [2],
'unicorn/prefer-block-statement-over-iife': [2],
'unicorn/prefer-boolean-return': [2],
'unicorn/prefer-class-fields': [2],
'unicorn/prefer-classlist-toggle': [2],
@@ -896,19 +924,15 @@ export default defineConfig([
'unicorn/prefer-dom-node-append': [2],
'unicorn/prefer-dom-node-html-methods': [0],
'unicorn/prefer-dom-node-remove': [2],
'unicorn/prefer-dom-node-replace-children': [2],
'unicorn/prefer-dom-node-text-content': [2],
'unicorn/prefer-early-return': [0],
'unicorn/prefer-else-if': [2],
'unicorn/prefer-error-is-error': [0],
'unicorn/prefer-event-target': [2],
'unicorn/prefer-explicit-viewport-units': [0], // only applies to css language
'unicorn/prefer-export-from': [0],
'unicorn/prefer-flat-math-min-max': [2],
'unicorn/prefer-get-or-insert-computed': [2],
'unicorn/prefer-global-number-constants': [2],
'unicorn/prefer-global-this': [0],
'unicorn/prefer-group-by': [2],
'unicorn/prefer-has-check': [2],
'unicorn/prefer-hoisting-branch-code': [2],
'unicorn/prefer-https': [0], // false-positives on namespace and schema URIs
@@ -918,7 +942,6 @@ export default defineConfig([
'unicorn/prefer-includes-over-repeated-comparisons': [0], // too opinionated
'unicorn/prefer-iterable-in-constructor': [2],
'unicorn/prefer-iterator-concat': [0], // too opinionated
'unicorn/prefer-iterator-helpers': [2],
'unicorn/prefer-iterator-to-array': [2],
'unicorn/prefer-iterator-to-array-at-end': [2],
'unicorn/prefer-keyboard-event-key': [2],
@@ -943,11 +966,9 @@ export default defineConfig([
'unicorn/prefer-object-destructuring-defaults': [2],
'unicorn/prefer-object-from-entries': [2],
'unicorn/prefer-object-iterable-methods': [2],
'unicorn/prefer-observer-apis': [2],
'unicorn/prefer-optional-catch-binding': [2],
'unicorn/prefer-path2d': [2],
'unicorn/prefer-private-class-fields': [0],
'unicorn/prefer-promise-try': [2],
'unicorn/prefer-promise-with-resolvers': [2],
'unicorn/prefer-prototype-methods': [0],
'unicorn/prefer-query-selector': [2],
@@ -958,12 +979,10 @@ export default defineConfig([
'unicorn/prefer-response-static-json': [2],
'unicorn/prefer-scoped-selector': [0],
'unicorn/prefer-set-has': [0],
'unicorn/prefer-set-methods': [0],
'unicorn/prefer-set-size': [2],
'unicorn/prefer-short-arrow-method': [2],
'unicorn/prefer-simple-condition-first': [0],
'unicorn/prefer-simple-sort-comparator': [2],
'unicorn/prefer-simplified-conditions': [2],
'unicorn/prefer-single-array-predicate': [2],
'unicorn/prefer-single-call': [2],
'unicorn/prefer-single-object-destructuring': [2],
@@ -983,8 +1002,6 @@ export default defineConfig([
'unicorn/prefer-switch': [0],
'unicorn/prefer-temporal': [0],
'unicorn/prefer-ternary': [0],
'unicorn/prefer-then-catch': [2],
'unicorn/prefer-toggle-attribute': [2],
'unicorn/prefer-top-level-await': [0],
'unicorn/prefer-type-error': [0],
'unicorn/prefer-type-literal-last': [0],
@@ -993,14 +1010,12 @@ export default defineConfig([
'unicorn/prefer-unicode-code-point-escapes': [0],
'unicorn/prefer-url-can-parse': [2],
'unicorn/prefer-url-href': [2],
'unicorn/prefer-url-search-parameters': [2],
'unicorn/prefer-while-loop-condition': [2],
'unicorn/prevent-abbreviations': [0],
'unicorn/relative-url-style': [2],
'unicorn/require-array-join-separator': [2],
'unicorn/require-array-sort-compare': [0],
'unicorn/require-css-escape': [2],
'unicorn/require-frontmatter-fields': [0], // only applies to markdown language
'unicorn/require-module-attributes': [2],
'unicorn/require-module-specifiers': [0],
'unicorn/require-number-to-fixed-digits-argument': [2],
+3 -4
View File
@@ -3,10 +3,9 @@ import json from '@eslint/json';
export default defineConfig([
globalIgnores([
'public',
'custom/public',
'data',
'.venv',
'**/.venv',
'**/node_modules',
'**/public',
]),
{
files: ['**/*.json'],
Generated
+3 -3
View File
@@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1782723713,
"narHash": "sha256-oPXCU/SSUokcGaJREHibG1CBX3+s/W7orDWQOZDsEeQ=",
"lastModified": 1776877367,
"narHash": "sha256-EHq1/OX139R1RvBzOJ0aMRT3xnWyqtHBRUBuO1gFzjI=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "b5aa0fbd538984f6e3d201be0005b4463d8b09f8",
"rev": "0726a0ecb6d4e08f6adced58726b95db924cef57",
"type": "github"
},
"original": {
+1 -1
View File
@@ -34,7 +34,7 @@
# only bump toolchain versions here
go = pkgs.go_1_26;
nodejs = pkgs.nodejs_26;
nodejs = pkgs.nodejs_24;
python3 = pkgs.python314;
pnpm = pkgs.pnpm_10;
+40 -39
View File
@@ -1,20 +1,19 @@
module gitea.dev
go 1.26.0
toolchain go1.26.5
go 1.26.4
require (
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570
connectrpc.com/connect v1.20.0
gitea.com/gitea/runner v1.0.8
gitea.com/go-chi/binding v0.0.0-20260414111559-654cea7ac60a
gitea.com/go-chi/cache v0.2.1
gitea.com/go-chi/captcha v0.0.0-20240315150714-fb487f629098
gitea.com/go-chi/session v0.0.0-20260708011333-ebced8a7a2d6
gitea.com/go-chi/session v0.0.0-20251124165456-68e0254e989e
gitea.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96
gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4
gitea.dev/actions-proto-go v0.6.0
gitea.dev/sdk v1.2.0
gitea.dev/sdk v1.1.0
github.com/42wim/httpsig v1.2.4
github.com/42wim/sshsig v0.0.0-20260317195500-b9f38cf0d432
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.22.0
@@ -25,16 +24,16 @@ require (
github.com/PuerkitoBio/goquery v1.12.0
github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.10.0
github.com/alecthomas/chroma/v2 v2.27.0
github.com/aws/aws-sdk-go-v2/credentials v1.19.29
github.com/aws/aws-sdk-go-v2/service/codecommit v1.35.1
github.com/aws/aws-sdk-go-v2/credentials v1.19.24
github.com/aws/aws-sdk-go-v2/service/codecommit v1.34.4
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb
github.com/blevesearch/bleve/v2 v2.6.0
github.com/bohde/codel v0.2.0
github.com/buildkite/terminal-to-html/v3 v3.17.1
github.com/buildkite/terminal-to-html/v3 v3.16.8
github.com/caddyserver/certmagic v0.25.4
github.com/charmbracelet/git-lfs-transfer v0.1.1-0.20260309112543-12416315a635
github.com/chi-middleware/proxy v1.1.1
github.com/dlclark/regexp2/v2 v2.5.0
github.com/dlclark/regexp2/v2 v2.2.2
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707
github.com/dustin/go-humanize v1.0.1
github.com/editorconfig/editorconfig-core-go/v2 v2.6.4
@@ -43,24 +42,24 @@ require (
github.com/ethantkoenig/rupture v1.0.1
github.com/felixge/fgprof v0.9.5
github.com/fsnotify/fsnotify v1.10.1
github.com/getkin/kin-openapi v0.142.0
github.com/getkin/kin-openapi v0.140.0
github.com/gliderlabs/ssh v0.3.8
github.com/go-chi/chi/v5 v5.3.1
github.com/go-chi/chi/v5 v5.3.0
github.com/go-chi/cors v1.2.2
github.com/go-co-op/gocron/v2 v2.22.0
github.com/go-co-op/gocron/v2 v2.21.2
github.com/go-enry/go-enry/v2 v2.9.6
github.com/go-git/go-billy/v5 v5.9.0
github.com/go-git/go-git/v5 v5.19.1
github.com/go-ldap/ldap/v3 v3.4.13
github.com/go-redsync/redsync/v4 v4.17.0
github.com/go-redsync/redsync/v4 v4.16.0
github.com/go-sql-driver/mysql v1.10.0
github.com/go-webauthn/webauthn v0.17.4
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
github.com/golang-jwt/jwt/v5 v5.3.1
github.com/google/go-github/v89 v89.0.0
github.com/google/go-github/v88 v88.0.0
github.com/google/licenseclassifier/v2 v2.0.0
github.com/google/pprof v0.0.0-20260709232956-b9395ee17fa0
github.com/google/pprof v0.0.0-20260604005048-7023385849c0
github.com/google/uuid v1.6.0
github.com/gorilla/feeds v1.2.0
github.com/gorilla/sessions v1.4.0
@@ -69,17 +68,17 @@ require (
github.com/huandu/xstrings v1.5.0
github.com/jhillyerd/enmime/v2 v2.4.1
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/klauspost/compress v1.19.0
github.com/klauspost/cpuid/v2 v2.4.0
github.com/klauspost/compress v1.18.6
github.com/klauspost/cpuid/v2 v2.3.0
github.com/lib/pq v1.12.3
github.com/markbates/goth v1.82.0
github.com/mattn/go-isatty v0.0.22
github.com/mattn/go-sqlite3 v1.14.48
github.com/mattn/go-sqlite3 v1.14.47
github.com/meilisearch/meilisearch-go v0.36.3
github.com/mholt/archives v0.1.5
github.com/microcosm-cc/bluemonday v1.0.27
github.com/microsoft/go-mssqldb v1.10.0
github.com/minio/minio-go/v7 v7.2.1
github.com/minio/minio-go/v7 v7.2.0
github.com/msteinert/pam/v2 v2.1.0
github.com/niklasfasching/go-org v1.9.1
github.com/opencontainers/go-digest v1.0.0
@@ -97,29 +96,29 @@ require (
github.com/tstranex/u2f v1.0.0
github.com/ulikunitz/xz v0.5.15
github.com/urfave/cli-docs/v3 v3.1.0
github.com/urfave/cli/v3 v3.10.1
github.com/wneessen/go-mail v0.8.1
github.com/urfave/cli/v3 v3.10.0
github.com/wneessen/go-mail v0.7.3
github.com/yohcop/openid-go v1.0.1
github.com/yuin/goldmark v1.8.4
github.com/yuin/goldmark v1.8.2
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
gitlab.com/gitlab-org/api/client-go/v2 v2.48.1
gitlab.com/gitlab-org/api/client-go/v2 v2.42.0
go.yaml.in/yaml/v4 v4.0.0-rc.5
golang.org/x/crypto v0.54.0
golang.org/x/image v0.44.0
golang.org/x/mod v0.38.0
golang.org/x/net v0.57.0
golang.org/x/crypto v0.53.0
golang.org/x/image v0.43.0
golang.org/x/mod v0.37.0
golang.org/x/net v0.56.0
golang.org/x/oauth2 v0.36.0
golang.org/x/sync v0.22.0
golang.org/x/sys v0.47.0
golang.org/x/text v0.40.0
google.golang.org/grpc v1.82.1
golang.org/x/sync v0.21.0
golang.org/x/sys v0.46.0
golang.org/x/text v0.38.0
google.golang.org/grpc v1.81.1
google.golang.org/protobuf v1.36.11
gopkg.in/ini.v1 v1.67.3
modernc.org/sqlite v1.53.0
mvdan.cc/xurls/v2 v2.6.0
strk.kbt.io/projects/go/libravatar v0.0.0-20260301104140-add494e31dab
xorm.io/builder v0.3.13
xorm.io/xorm v1.4.1
xorm.io/xorm v1.3.11
)
require (
@@ -134,10 +133,10 @@ require (
github.com/andybalholm/brotli v1.2.1 // indirect
github.com/andybalholm/cascadia v1.3.4 // indirect
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
github.com/aws/aws-sdk-go-v2 v1.42.1 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.30 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.30 // indirect
github.com/aws/smithy-go v1.27.3 // indirect
github.com/aws/aws-sdk-go-v2 v1.42.0 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.29 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.29 // indirect
github.com/aws/smithy-go v1.27.2 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bits-and-blooms/bitset v1.24.5 // indirect
@@ -200,7 +199,9 @@ require (
github.com/gorilla/css v1.0.1 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
github.com/inbucket/html2text v1.0.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
@@ -227,8 +228,8 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/nwaples/rardecode/v2 v2.2.3 // indirect
github.com/oasdiff/yaml v0.1.1 // indirect
github.com/oasdiff/yaml3 v0.0.14 // indirect
github.com/oasdiff/yaml v0.1.0 // indirect
github.com/oasdiff/yaml3 v0.0.13 // indirect
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect
github.com/olekukonko/errors v1.3.0 // indirect
github.com/olekukonko/ll v0.1.8 // indirect
@@ -268,7 +269,7 @@ require (
go.yaml.in/yaml/v3 v3.0.4 // indirect
go4.org v0.0.0-20260112195520-a5071408f32f // indirect
golang.org/x/time v0.15.0 // indirect
golang.org/x/tools v0.47.0 // indirect
golang.org/x/tools v0.45.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
+87 -78
View File
@@ -2,6 +2,8 @@ cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdB
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
code.pfad.fr/check v1.1.0 h1:GWvjdzhSEgHvEHe2uJujDcpmZoySKuHQNrZMfzfO0bE=
code.pfad.fr/check v1.1.0/go.mod h1:NiUH13DtYsb7xp5wll0U4SXx7KhXQVCtRgdC96IPfoM=
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570 h1:TXbikPqa7YRtfU9vS6QJBg77pUvbEb6StRdZO8t1bEY=
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570/go.mod h1:IIAjsijsd8q1isWX8MACefDEgTQslQ4stk2AeeTt3kM=
connectrpc.com/connect v1.20.0 h1:6TNDAB+WeNd2uolWNlYczB5E0KNNaVMNUEx8JEUsPmQ=
connectrpc.com/connect v1.20.0/go.mod h1:A2ygJrukXwWy32vkCAAHNVguZrqZ+jeZ9rGRnGR4dN4=
dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
@@ -16,8 +18,8 @@ gitea.com/go-chi/cache v0.2.1 h1:bfAPkvXlbcZxPCpcmDVCWoHgiBSBmZN/QosnZvEC0+g=
gitea.com/go-chi/cache v0.2.1/go.mod h1:Qic0HZ8hOHW62ETGbonpwz8WYypj9NieU9659wFUJ8Q=
gitea.com/go-chi/captcha v0.0.0-20240315150714-fb487f629098 h1:p2ki+WK0cIeNQuqjR98IP2KZQKRzJJiV7aTeMAFwaWo=
gitea.com/go-chi/captcha v0.0.0-20240315150714-fb487f629098/go.mod h1:LjzIOHlRemuUyO7WR12fmm18VZIlCAaOt9L3yKw40pk=
gitea.com/go-chi/session v0.0.0-20260708011333-ebced8a7a2d6 h1:YWzVGeC/8SZThrJS48ZmQYLkzssdeABxHPhbdnxPDIU=
gitea.com/go-chi/session v0.0.0-20260708011333-ebced8a7a2d6/go.mod h1:KDvcfMUoXfATPHs2mbMoXFTXT45/FAFAS39waz9tPk0=
gitea.com/go-chi/session v0.0.0-20251124165456-68e0254e989e h1:4bugwPyGMLvblEm3pZ8fZProSPVxE4l0UXF2Kv6IJoY=
gitea.com/go-chi/session v0.0.0-20251124165456-68e0254e989e/go.mod h1:KDvcfMUoXfATPHs2mbMoXFTXT45/FAFAS39waz9tPk0=
gitea.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 h1:+wWBi6Qfruqu7xJgjOIrKVQGiLUZdpKYCZewJ4clqhw=
gitea.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96/go.mod h1:VyMQP6ue6MKHM8UsOXfNfuMKD0oSAWZdXVcpHIN2yaY=
gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4 h1:IFT+hup2xejHqdhS7keYWioqfmxdnfblFDTGoOwcZ+o=
@@ -26,8 +28,8 @@ gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGq
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
gitea.dev/actions-proto-go v0.6.0 h1:gjllYQ5vmwlkqOeofTQu5qKTZpmf7kWsafoHvoPCSzY=
gitea.dev/actions-proto-go v0.6.0/go.mod h1:p4RX+D9oqiEEzzkPMXscw2CmaGuYFPWFc6xIOmDNDqs=
gitea.dev/sdk v1.2.0 h1:avRtJl/nKCGispgSalo9czoZM9Rto1awnE0caNAoXGo=
gitea.dev/sdk v1.2.0/go.mod h1:rfh5oNdIK24cbCREwIn1tqWKQW+IICXFGWJyebuOAOE=
gitea.dev/sdk v1.1.0 h1:wLlz03WkLEiXa2bQpO1JQBTlYf7tQI2neYtZK1kU+TE=
gitea.dev/sdk v1.1.0/go.mod h1:Zfl+EZXdsGGCLkryDfsmvYrQo6GKMl4U3BJA8Beu+cs=
github.com/42wim/httpsig v1.2.4 h1:mI5bH0nm4xn7K18fo1K3okNDRq8CCJ0KbBYWyA6r8lU=
github.com/42wim/httpsig v1.2.4/go.mod h1:yKsYfSyTBEohkPik224QPFylmzEBtda/kjyIAJjh3ps=
github.com/42wim/sshsig v0.0.0-20260317195500-b9f38cf0d432 h1:3Fcz1QzlS7Jv4FT2KI3cHNSZL+KPN3dXxurn9f3YL/Y=
@@ -90,18 +92,18 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuW
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/aws/aws-sdk-go-v2 v1.42.1 h1:9eOTgu1z/dVtYpNZ3/8/XbbaX0x/BqE3HUzAzs6K0ek=
github.com/aws/aws-sdk-go-v2 v1.42.1/go.mod h1:5pKeft2eJj+gElQ38Jqg4ibCqh+/AK33/0X3hip7IjM=
github.com/aws/aws-sdk-go-v2/credentials v1.19.29 h1:WHZGssHH887cO0ox07SIQZsFx3MKD4ps6w0xUEmnKYQ=
github.com/aws/aws-sdk-go-v2/credentials v1.19.29/go.mod h1:Mhl0xR6zjguiuj00XRx2wMx22sAltk7oya39sT7fdg8=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.30 h1:xM/Is9cKMHa8Jj8zkvWhvrFkZsXJV9E+BB4g0HW0duQ=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.30/go.mod h1:WueJeNDZvK1fMYEWJIkcivBfEzUkTpBhzlrUKKY8EuA=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.30 h1:jn46zC9LdsVR/ZpMIJqMqb8hHv31BlLx3ulVqNspUOk=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.30/go.mod h1:1hTMsAgbdS/AtUi4bw8+gUuh1pceo+eXRLfpSuSQj3M=
github.com/aws/aws-sdk-go-v2/service/codecommit v1.35.1 h1:mQBm+SScIS/K5OeGnBH8mGu4oAKneaa/nS9GpfQaIFM=
github.com/aws/aws-sdk-go-v2/service/codecommit v1.35.1/go.mod h1:uH156Pb0jnMXuCSD9irU0Qz6UNhYUF2qbowFqIwyLQ8=
github.com/aws/smithy-go v1.27.3 h1:F3Zb497UhhskkfpJmfkXswyo+t0sh9OTBnIHjogWbVY=
github.com/aws/smithy-go v1.27.3/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
github.com/aws/aws-sdk-go-v2 v1.42.0 h1:XvXMJTkFQtpBKIWZnmr9ZEOc2InWM2yldjXEJ/bymhA=
github.com/aws/aws-sdk-go-v2 v1.42.0/go.mod h1:27+ACypSLljLAEKsCYOmrjKh83vuTRkuAe9Uv/3A4bg=
github.com/aws/aws-sdk-go-v2/credentials v1.19.24 h1:2hQqYCV9yqyePQ9o6dCrZc/zO8U3TwPr9mIKlZnPu/I=
github.com/aws/aws-sdk-go-v2/credentials v1.19.24/go.mod h1:IDwpACtwqHLISdzfwUUNq4P9DsB/h5BLg4FwJPNfqFY=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.29 h1:f3vKqSo13fhTYb+JEcXwXefZQE26I1FB5eTSniU67ko=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.29/go.mod h1:MzoLFUArKGpGD+ukmPiTPG1X5x4o6M2kq4v2dr1FiEc=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.29 h1:RdwIf/CuUsvJX3RgJagbOyotl/cxoLY4xviKuE7p2GY=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.29/go.mod h1:71wt8W2EgswdZy9Mf9KNnzxZ3TiZlv4caKghPktDOkA=
github.com/aws/aws-sdk-go-v2/service/codecommit v1.34.4 h1:Uu+wqrOXozYYvaxcNIqjFsMTjoIJIZDN3R0f70ZIjyQ=
github.com/aws/aws-sdk-go-v2/service/codecommit v1.34.4/go.mod h1:pYrBdL1tMTZO7PaKRsa1cTUB8HtQh3fFM3zJHGhTQcE=
github.com/aws/smithy-go v1.27.2 h1:y9NPmSE6am6LjEFPfqHqG/jJk7AauQvhCJONKh7kpzk=
github.com/aws/smithy-go v1.27.2/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -183,8 +185,8 @@ github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/buildkite/terminal-to-html/v3 v3.17.1 h1:gs9WhKUwxK27YHf3hijj4tG4wuDLfCANYbRPd5ltMdI=
github.com/buildkite/terminal-to-html/v3 v3.17.1/go.mod h1:0pv+Z75FC+NvIju2o+Cw+YHIDkueeudIoeyfVm8i8GQ=
github.com/buildkite/terminal-to-html/v3 v3.16.8 h1:QN/daUob6cmK8GcdKnwn9+YTlPr1vNj+oeAIiJK6fPc=
github.com/buildkite/terminal-to-html/v3 v3.16.8/go.mod h1:+k1KVKROZocrTLsEQ9PEf9A+8+X8uaVV5iO1ZIOwKYM=
github.com/caddyserver/certmagic v0.25.4 h1:8eIXh0HC3MsGnNo8One+BCxMGTbe5zb/oz+2KsxBFQg=
github.com/caddyserver/certmagic v0.25.4/go.mod h1:YVs43D5+H/Dckt4bTga1KSO/xYfFBfVZainGDywYPAA=
github.com/caddyserver/zerossl v0.1.5 h1:dkvOjBAEEtY6LIGAHei7sw2UgqSD6TrWweXpV7lvEvE=
@@ -238,8 +240,8 @@ github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55k
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dlclark/regexp2 v1.12.0 h1:0j4c5qQmnC6XOWNjP3PIXURXN2gWx76rd3KvgdPkCz8=
github.com/dlclark/regexp2 v1.12.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dlclark/regexp2/v2 v2.5.0 h1:liNiWIPCvCh5HBcYfsjd+P16AG79fwd6T1Toy2gOtEA=
github.com/dlclark/regexp2/v2 v2.5.0/go.mod h1:avUrQvPaLz2DrFNHJF0taWAFFX2C1GMSSoeiqFjcBmU=
github.com/dlclark/regexp2/v2 v2.2.2 h1:MYWvNYw8okuqNhwTYO587EZMiDruVa2vhV6fsGpfya0=
github.com/dlclark/regexp2/v2 v2.2.2/go.mod h1:avUrQvPaLz2DrFNHJF0taWAFFX2C1GMSSoeiqFjcBmU=
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 h1:2tV76y6Q9BB+NEBasnqvs7e49aEBFI8ejC89PSnWH+4=
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s=
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
@@ -272,8 +274,8 @@ github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx5
github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo=
github.com/fxamacker/cbor/v2 v2.9.2 h1:X4Ksno9+x3cz0TZv69ec1hxP/+tymuR8PXQJyDwfh78=
github.com/fxamacker/cbor/v2 v2.9.2/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/getkin/kin-openapi v0.142.0 h1:izj0vBdFprMhitfzaX8sTqztsEQyvwhssBoB6n8NO7w=
github.com/getkin/kin-openapi v0.142.0/go.mod h1:3BH9M9XDe/y9M5DSvEocVYAYq1w0qrhJHjC/vZi0AaY=
github.com/getkin/kin-openapi v0.140.0 h1:JFn675aXRFjyiZKa/BFWploGldQlI0gobp4J5k0EZ2g=
github.com/getkin/kin-openapi v0.140.0/go.mod h1:lISrB64F0CPcuDJ3LdtPTMJBY8VENjR9wJBdrcT6J3g=
github.com/git-lfs/pktline v0.0.0-20230103162542-ca444d533ef1 h1:mtDjlmloH7ytdblogrMz1/8Hqua1y8B4ID+bh3rvod0=
github.com/git-lfs/pktline v0.0.0-20230103162542-ca444d533ef1/go.mod h1:fenKRzpXDjNpsIBhuhUzvjCKlDjKam0boRAenTE0Q6A=
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
@@ -283,12 +285,12 @@ github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1T
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 h1:BP4M0CvQ4S3TGls2FvczZtj5Re/2ZzkV9VwqPHH/3Bo=
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/chi/v5 v5.3.1 h1:3j4HZLGZQ3JpMCrPJF/Jl3mYJfWLKBfNJ6quurUGCf8=
github.com/go-chi/chi/v5 v5.3.1/go.mod h1:R+tYY2hNuVUUjxoPtqUdgBqevM9s9njzkTLutVsOCto=
github.com/go-chi/chi/v5 v5.3.0 h1:halUjDxhshgXHMrao5bB8eNBXo/rnzwr8m5m36glehM=
github.com/go-chi/chi/v5 v5.3.0/go.mod h1:R+tYY2hNuVUUjxoPtqUdgBqevM9s9njzkTLutVsOCto=
github.com/go-chi/cors v1.2.2 h1:Jmey33TE+b+rB7fT8MUy1u0I4L+NARQlK6LhzKPSyQE=
github.com/go-chi/cors v1.2.2/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-co-op/gocron/v2 v2.22.0 h1:uEuH2F7k7VoESb1BYSaffuuV+T0kkpzsC0aXk7/z79I=
github.com/go-co-op/gocron/v2 v2.22.0/go.mod h1:hiH/U9RMhTi1BBZJmef9s3KC9QwhpBF6PFrvUKaXY9M=
github.com/go-co-op/gocron/v2 v2.21.2 h1:bD8/YwkojYHgXFr3iEulL148KBdTbKVxUZzFKpXcdbY=
github.com/go-co-op/gocron/v2 v2.21.2/go.mod h1:5lEiCKk1oVJV39Zg7/YG10OnaVrDAV5GGR6O0663k6U=
github.com/go-enry/go-enry/v2 v2.9.6 h1:np63eOtMV56zfYDHnFVgpEVOk8fr2kmylcMnAZUDbSs=
github.com/go-enry/go-enry/v2 v2.9.6/go.mod h1:9yrj4ES1YrbNb1Wb7/PWYr2bpaCXUGRt0uafN0ISyG8=
github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
@@ -317,8 +319,8 @@ github.com/go-redis/redis/v7 v7.4.1 h1:PASvf36gyUpr2zdOUS/9Zqc80GbM+9BDyiJSJDDOr
github.com/go-redis/redis/v7 v7.4.1/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/go-redsync/redsync/v4 v4.17.0 h1:FFJ+uxZs44y4Sq10//IFKic9T94AYl+u3Sog98AHzBo=
github.com/go-redsync/redsync/v4 v4.17.0/go.mod h1:CKVA6qwT07S/916i+Yd9h1/8YFQhCCpPYTQhvvYytJo=
github.com/go-redsync/redsync/v4 v4.16.0 h1:bNcOzeHH9d3s6pghU9NJFMPrQa41f5Nx3L4YKr3BdEU=
github.com/go-redsync/redsync/v4 v4.16.0/go.mod h1:V4gagqgyASWBZuwx4xGzu72aZNb/6Mo05byUa3mVmKQ=
github.com/go-sql-driver/mysql v1.10.0 h1:Q+1LV8DkHJvSYAdR83XzuhDaTykuDx0l6fkXxoWCWfw=
github.com/go-sql-driver/mysql v1.10.0/go.mod h1:M+cqaI7+xxXGG9swrdeUIoPG3Y3KCkF0pZej+SK+nWk=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
@@ -374,8 +376,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/go-github/v89 v89.0.0 h1:35bEK5XoEcF3PZrlVbl9XN63f5BcJRA/UGkxeC9xPg0=
github.com/google/go-github/v89 v89.0.0/go.mod h1:QLcbU0ipeAqQuR5KSg8c2lql4Qk1EwJ2dWz/0rP4Nho=
github.com/google/go-github/v88 v88.0.0 h1:dZA9IKkPK1eXZj4ypngnpRj5FwdpTv4whix2PrQMP7M=
github.com/google/go-github/v88 v88.0.0/go.mod h1:rufTDgn2N45wjhukLTyxmvc9nilSp3mr3Rgtt6b1MPw=
github.com/google/go-querystring v1.2.0 h1:yhqkPbu2/OH+V9BfpCVPZkNmUXhb2gBxJArfhIxNtP0=
github.com/google/go-querystring v1.2.0/go.mod h1:8IFJqpSRITyJ8QhQ13bmbeMBDfmeEJZD5A0egEOmkqU=
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
@@ -388,8 +390,8 @@ github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
github.com/google/licenseclassifier/v2 v2.0.0 h1:1Y57HHILNf4m0ABuMVb6xk4vAJYEUO0gDxNpog0pyeA=
github.com/google/licenseclassifier/v2 v2.0.0/go.mod h1:cOjbdH0kyC9R22sdQbYsFkto4NGCAc+ZSwbeThazEtM=
github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
github.com/google/pprof v0.0.0-20260709232956-b9395ee17fa0 h1:du0WGc8xSKq/++e0cglxhS/mXVqsR7+c7jLEi5Vqduw=
github.com/google/pprof v0.0.0-20260709232956-b9395ee17fa0/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
github.com/google/pprof v0.0.0-20260604005048-7023385849c0 h1:h1QTMDl6q9wDvDCJVpKQSjgleGFYnd2fOxmg2K+6BGE=
github.com/google/pprof v0.0.0-20260604005048-7023385849c0/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
@@ -411,10 +413,17 @@ github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pw
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzqQ=
github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik=
github.com/graph-gophers/graphql-go v1.10.2 h1:HXu6Wu5klCH4ALn1fQHVI20cjEIa4wftavHIgbLA4Fo=
github.com/graph-gophers/graphql-go v1.10.2/go.mod h1:AsADheC4CCFwd8n1/QbkduTlHgYYMsRgtPihYVAlEsk=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48=
github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw=
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
@@ -462,12 +471,12 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:C
github.com/kevinburke/ssh_config v1.6.0 h1:J1FBfmuVosPHf5GRdltRLhPJtJpTlMdKTBjRgTaQBFY=
github.com/kevinburke/ssh_config v1.6.0/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.19.0 h1:sXLILfc9jV2QYWkzFOPWStmcUVH2RHEB1JCdY2oVvCQ=
github.com/klauspost/compress v1.19.0/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao=
github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.4.0 h1:S6Hrbc7+ywsr0r+RLapfGBHfyefhCTwEh3A0tV913Dw=
github.com/klauspost/cpuid/v2 v2.4.0/go.mod h1:19jmZ9mjzoF//ddRSUsv0zfBTJWh3QJh9FNxZTMrGxU=
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
github.com/klauspost/crc32 v1.3.0 h1:sSmTt3gUt81RP655XGZPElI0PelVTZ6YwCRnPSupoFM=
github.com/klauspost/crc32 v1.3.0/go.mod h1:D7kQaZhnkX/Y0tstFGf8VUzv2UofNGqCjnC3zdHB0Hw=
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
@@ -505,8 +514,8 @@ github.com/mattn/go-runewidth v0.0.24 h1:cpokDiIn0MGnhdHwuWnJBITySJ20QyNGnY2kR/a
github.com/mattn/go-runewidth v0.0.24/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/mattn/go-shellwords v1.0.13 h1:DC0OMEpGjm6LfNFU4ckYcvbQKyp2vE8atyFGXNtDcf4=
github.com/mattn/go-shellwords v1.0.13/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/mattn/go-sqlite3 v1.14.48 h1:7XHIgl0a8HwOaiK4E47ozLkST78rR9+OtNGx27D/TFs=
github.com/mattn/go-sqlite3 v1.14.48/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w=
github.com/mattn/go-sqlite3 v1.14.47 h1:jOBI62gS7nKeZv+as1oGEy0+1qISgXwH/QBlR6KbfIo=
github.com/mattn/go-sqlite3 v1.14.47/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w=
github.com/meilisearch/meilisearch-go v0.36.3 h1:Yx1aTY5jDgtbStPVkhJTDoLnZTy5sejQSPyjfNMy6e4=
github.com/meilisearch/meilisearch-go v0.36.3/go.mod h1:hWcR0MuWLSzHfbz9GGzIr3s9rnXLm1jqkmHkJPbUSvM=
github.com/mholt/acmez/v3 v3.1.6 h1:eGVQNObP0pBN4sxqrXeg7MYqTOWyoiYpQqITVWlrevk=
@@ -525,8 +534,8 @@ github.com/minio/crc64nvme v1.1.1 h1:8dwx/Pz49suywbO+auHCBpCtlW1OfpcLN7wYgVR6wAI
github.com/minio/crc64nvme v1.1.1/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
github.com/minio/minio-go/v7 v7.2.1 h1:PfBfwvKB/MmqyN8Vb1G9voWisaM9OrLv+WwOvMwS9Dw=
github.com/minio/minio-go/v7 v7.2.1/go.mod h1:EU9hENAStx/xXduNdrGO5e4X5vk19NtgB+RIPjZO8o0=
github.com/minio/minio-go/v7 v7.2.0 h1:RCJM0R1XOsRs+A3x3UCaf3ZYbByDaLjFeAi+YCQEPhs=
github.com/minio/minio-go/v7 v7.2.0/go.mod h1:EU9hENAStx/xXduNdrGO5e4X5vk19NtgB+RIPjZO8o0=
github.com/minio/minlz v1.1.1 h1:OGmft1V6AnI/Wme332U6bhG54nxEan+VFgkD7lat4KM=
github.com/minio/minlz v1.1.1/go.mod h1:qT0aEB35q79LLornSzeDH75LBf3aH1MV+jB5w9Wasec=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
@@ -554,10 +563,10 @@ github.com/nwaples/rardecode/v2 v2.2.3/go.mod h1:7uz379lSxPe6j9nvzxUZ+n7mnJNgjsR
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oasdiff/yaml v0.1.1 h1:6nHx+pn9gBRM6YpBlFZFQGCCd1nuvqOBtTD3KKTgGxY=
github.com/oasdiff/yaml v0.1.1/go.mod h1:EYJNoyktvWMJ0Hmhx+6qTaqMOsalUaRGT8Sj1hNcegU=
github.com/oasdiff/yaml3 v0.0.14 h1:aLJee3hxBK2H5wdXd9iPcIXb93Nty1Ge0pT171eHtkw=
github.com/oasdiff/yaml3 v0.0.14/go.mod h1:csto2xfDjYccdUn/yw/bPjj/cYTdp6HtFA0J4TWG+gg=
github.com/oasdiff/yaml v0.1.0 h1:0bqZjfKc/8S9urj4JuwepX41WX9EoA6ifhU3SV06cXg=
github.com/oasdiff/yaml v0.1.0/go.mod h1:kOlRmMdL2X3vucLCEQO5u61SU22RysnfXvcttrZA1O0=
github.com/oasdiff/yaml3 v0.0.13 h1:06svmvOHOVBqF81+sY2EUScvUI/iS/vl2VIeUUxZQwg=
github.com/oasdiff/yaml3 v0.0.13/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o=
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 h1:zrbMGy9YXpIeTnGj4EljqMiZsIcE09mmF8XsD5AYOJc=
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6/go.mod h1:rEKTHC9roVVicUIfZK7DYrdIoM0EOr8mK1Hj5s3JjH0=
github.com/olekukonko/errors v1.3.0 h1:teJvgLGUEqMzBUms+Dj3/3szNqCG/Jdw9iDbum8fR6U=
@@ -611,10 +620,10 @@ github.com/quasoft/websspi v1.1.2/go.mod h1:HmVdl939dQ0WIXZhyik+ARdI03M6bQzaSEKc
github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/redis/go-redis/v9 v9.21.0 h1:FPBE4hhbAke+TLmcY3WkpbDffJEomdqPn3HYiqAtL9E=
github.com/redis/go-redis/v9 v9.21.0/go.mod h1:v/M13XI1PVCDcm01VtPFOADfZtHf8YW3baQf57KlIkA=
github.com/redis/rueidis v1.0.76 h1:RdDWuvlYBSp+bTrBvaXqJnNEL3VVzsnjo+0psPFgLc4=
github.com/redis/rueidis v1.0.76/go.mod h1:UsfHPSbomB6QAVMk4iiFkzRy0nh9o7scDGa+SitvBY4=
github.com/redis/rueidis/rueidiscompat v1.0.76 h1:7LikbiqCQqCsZXeZ+akgZMnjIV/J0VHih9PIX4gGZC4=
github.com/redis/rueidis/rueidiscompat v1.0.76/go.mod h1:UatQQLVj4QMIsZtpvRWY28qm6r2d72idhcS+C/RM+Zg=
github.com/redis/rueidis v1.0.71 h1:pODtnAR5GAB7j4ekhldZ29HKOxe4Hph0GTDGk1ayEQY=
github.com/redis/rueidis v1.0.71/go.mod h1:lfdcZzJ1oKGKL37vh9fO3ymwt+0TdjkkUCJxbgpmcgQ=
github.com/redis/rueidis/rueidiscompat v1.0.71 h1:wNZ//kEjMZgBM0KCk7ncOX8KmAgROU2kDdDNpwheG4w=
github.com/redis/rueidis/rueidiscompat v1.0.71/go.mod h1:esmCLJvaRzZoKlgB82G1bY7Iky5TnO9Rz+NlhbEccFI=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rhysd/actionlint v1.7.12 h1:vQ4GeJN86C0QH+gTUQcs8McmK62OLT3kmakPMtEWYnY=
@@ -700,11 +709,11 @@ github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs=
github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
github.com/urfave/cli-docs/v3 v3.1.0 h1:Sa5xm19IpE5gpm6tZzXdfjdFxn67PnEsE4dpXF7vsKw=
github.com/urfave/cli-docs/v3 v3.1.0/go.mod h1:59d+5Hz1h6GSGJ10cvcEkbIe3j233t4XDqI72UIx7to=
github.com/urfave/cli/v3 v3.10.1 h1:7Kx9H50hrHbRbyxgO1KP6/BcbiGRz0uYh5YyQ30JEEY=
github.com/urfave/cli/v3 v3.10.1/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso=
github.com/urfave/cli/v3 v3.10.0 h1:0aU8yOObVDMkM13Cj4G+zb4P0PdeJMec65f81Ak1ioM=
github.com/urfave/cli/v3 v3.10.0/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso=
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/wneessen/go-mail v0.8.1 h1:tVcncj02/QySVFw3zr/kXOzZcuFQqBNT6K+Rbgm/pcM=
github.com/wneessen/go-mail v0.8.1/go.mod h1:dWZ61zadzCIyvB4y1/YzC5O7MrbbzBfPkARmbosdf8w=
github.com/wneessen/go-mail v0.7.3 h1:g3DravXC5SMlVdboFrQA8Jx95A8sOzoBeS5F+vzNRK0=
github.com/wneessen/go-mail v0.7.3/go.mod h1:QGhBX0yNbc1J+Mkjcu7z2rpj4B4l+BmDY8gYznPC9sk=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
@@ -719,8 +728,8 @@ github.com/yohcop/openid-go v1.0.1/go.mod h1:b/AvD03P0KHj4yuihb+VtLD6bYYgsy0zqBz
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.8.4 h1:oat/nd3U6NeQqFEL3xpEJq7d7c86NI+DbSNGAs4xnjA=
github.com/yuin/goldmark v1.8.4/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
github.com/yuin/goldmark v1.8.2 h1:kEGpgqJXdgbkhcOgBxkC0X0PmoPG1ZyoZ117rDVp4zE=
github.com/yuin/goldmark v1.8.2/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc h1:+IAOyRda+RLrxa1WC7umKOZRsGq4QrFFMYApOeHzQwQ=
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I=
github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
@@ -731,8 +740,8 @@ github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs=
github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s=
gitlab.com/gitlab-org/api/client-go/v2 v2.48.1 h1:k5N2hjc67pMkq3h0K2HyVSb7PkMyUTlW5kHQLrK3aQY=
gitlab.com/gitlab-org/api/client-go/v2 v2.48.1/go.mod h1:WEdEVDbr2ZtYfpw95r5XWZeGcr1mVsJZk57aeXWsSVU=
gitlab.com/gitlab-org/api/client-go/v2 v2.42.0 h1:Bq5YIYgUJVbt4Hbh7ibBwNR4SNEafsyDVhIXl7dXDdg=
gitlab.com/gitlab-org/api/client-go/v2 v2.42.0/go.mod h1:SKUbKSS59KPt6WeGNJoYF8HDaf/rFMUSITlftj/HkLg=
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/bbolt v1.4.3 h1:dEadXpI6G79deX5prL3QRNP6JB8UxVkqo4UPnHaNXJo=
go.etcd.io/bbolt v1.4.3/go.mod h1:tKQlpPaYCVFctUIgFKFnAlvbmB3tpy1vkTnDWohtc0E=
@@ -767,12 +776,12 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw=
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk=
golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM=
golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80=
golang.org/x/image v0.44.0 h1:+tDekMZED9+LrtB3G5xzRggpVh9CARjZqROla3R3R+I=
golang.org/x/image v0.44.0/go.mod h1:V8K3KE9KKKE+pLpQDOeN18w9oacNSvy1tDOirTu4xtY=
golang.org/x/image v0.43.0 h1:FLxcP4ec2350nTfOC8ysKtqYSIFbk/QGjw1ZHNP4tsY=
golang.org/x/image v0.43.0/go.mod h1:rrpelvGFt+kLPAjPM4HeWPgrl0FtafueU//e5N0qk/Q=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -781,8 +790,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk=
golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40=
golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ=
golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -798,8 +807,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec=
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -813,8 +822,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -845,8 +854,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -856,8 +865,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -868,8 +877,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY=
golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE=
golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4=
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -881,16 +890,16 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q=
golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA=
golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8=
golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad h1:45WmJvIV6C2+O/jjLkPUH+F3aOj/1miDoU2DD0+NWbg=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE=
google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ=
google.golang.org/grpc v1.81.1/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -955,5 +964,5 @@ strk.kbt.io/projects/go/libravatar v0.0.0-20260301104140-add494e31dab h1:3IZDVyI
strk.kbt.io/projects/go/libravatar v0.0.0-20260301104140-add494e31dab/go.mod h1:FJGmPh3vz9jSos1L/F91iAgnC/aejc0wIIrF2ZwJxdY=
xorm.io/builder v0.3.13 h1:a3jmiVVL19psGeXx8GIurTp7p0IIgqeDmwhcR6BAOAo=
xorm.io/builder v0.3.13/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
xorm.io/xorm v1.4.1 h1:m7QlNd0eBGb31IV4Q/ow0Du83rtdC1CiwlvJZGvYde8=
xorm.io/xorm v1.4.1/go.mod h1:cs0ePc8O4a0jD78cNvD+0VFwhqotTvLQZv372QsDw7Q=
xorm.io/xorm v1.3.11 h1:i4tlVUASogb0ZZFJHA7dZqoRU2pUpUsutnNdaOlFyMI=
xorm.io/xorm v1.3.11/go.mod h1:cs0ePc8O4a0jD78cNvD+0VFwhqotTvLQZv372QsDw7Q=
-25
View File
@@ -1,25 +0,0 @@
// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package base
import (
"gitea.dev/models/db" //nolint:depguard // allow to access db in migration
"gitea.dev/modules/git/gitrepo"
)
// HINT: MIGRATION-STRUCT-FROZEN: the structs used in migrations should not be affected by the changes happen in the future,
// because the details can be different in different releases.
// e.g. if one migration uses "User" model, it works in the early releases,
// then one day, when the User model changes, the existing migration will break because it will use the new (incorrect) User model,
// it should only use the old User model.
//
// Related: "models", "modules/structs", git repo directory layout on the disk, etc.
//
// If changes happen, the old migrations need to use a snapshot struct/function (copy the code and freeze)
type ResourceIndex = db.ResourceIndex
func LocalCodeGitRepo(ownerName, repoName string) gitrepo.RepositoryFacade {
return gitrepo.CodeRepoByName(ownerName, repoName)
}
-22
View File
@@ -1,22 +0,0 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_17
import (
"gitea.dev/modelmigration/base"
"gitea.dev/modules/timeutil"
)
func AddReviewViewedFiles(x base.EngineMigration) error {
type ReviewState struct {
ID int64 `xorm:"pk autoincr"`
UserID int64 `xorm:"NOT NULL UNIQUE(pull_commit_user)"`
PullID int64 `xorm:"NOT NULL INDEX UNIQUE(pull_commit_user) DEFAULT 0"`
CommitSHA string `xorm:"NOT NULL VARCHAR(40) UNIQUE(pull_commit_user)"`
UpdatedFiles map[string]uint8 `xorm:"NOT NULL LONGTEXT JSON"`
UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
}
return x.Sync(new(ReviewState))
}
-6
View File
@@ -277,12 +277,6 @@ func GetRunByRepoAndID(ctx context.Context, repoID, runID int64) (*ActionRun, er
return &run, nil
}
func GetRunsByRepoAndID(ctx context.Context, repoID int64, runIDs []int64) ([]*ActionRun, error) {
var runs []*ActionRun
err := db.GetEngine(ctx).In("id", runIDs).Where("repo_id=?", repoID).Find(&runs)
return runs, err
}
func GetRunByRepoAndIndex(ctx context.Context, repoID, runIndex int64) (*ActionRun, error) {
run, has, err := db.Get[ActionRun](ctx, builder.Eq{"repo_id": repoID, "`index`": runIndex})
if err != nil {
+5 -4
View File
@@ -14,6 +14,7 @@ import (
repo_model "gitea.dev/models/repo"
user_model "gitea.dev/models/user"
"gitea.dev/modules/git"
"gitea.dev/modules/gitrepo"
"xorm.io/builder"
)
@@ -66,13 +67,13 @@ func GetActivityStats(ctx context.Context, repo *repo_model.Repository, timeFrom
return nil, fmt.Errorf("FillUnresolvedIssues: %w", err)
}
if code {
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo)
gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
if err != nil {
return nil, fmt.Errorf("OpenRepository: %w", err)
}
defer closer.Close()
code, err := gitRepo.GetCodeActivityStats(ctx, timeFrom, repo.DefaultBranch)
code, err := gitRepo.GetCodeActivityStats(timeFrom, repo.DefaultBranch)
if err != nil {
return nil, fmt.Errorf("FillFromGit: %w", err)
}
@@ -83,13 +84,13 @@ func GetActivityStats(ctx context.Context, repo *repo_model.Repository, timeFrom
// GetActivityStatsTopAuthors returns top author stats for git commits for all branches
func GetActivityStatsTopAuthors(ctx context.Context, repo *repo_model.Repository, timeFrom time.Time, count int) ([]*ActivityAuthorData, error) {
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo)
gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
if err != nil {
return nil, fmt.Errorf("OpenRepository: %w", err)
}
defer closer.Close()
code, err := gitRepo.GetCodeActivityStats(ctx, timeFrom, "")
code, err := gitRepo.GetCodeActivityStats(timeFrom, "")
if err != nil {
return nil, fmt.Errorf("FillFromGit: %w", err)
}
-15
View File
@@ -195,18 +195,3 @@ func HasTwoFactorOrWebAuthn(ctx context.Context, id int64) (bool, error) {
}
return HasWebAuthnRegistrationsByUID(ctx, id)
}
// DisableTwoFactor removes every two-factor method of the given user atomically,
// returning the number of TOTP records and WebAuthn credentials removed.
// It is a no-op for a user that has no 2FA enrolled.
func DisableTwoFactor(ctx context.Context, uid int64) (totp, webAuthn int64, err error) {
err = db.WithTx(ctx, func(ctx context.Context) error {
var e error
if totp, e = db.GetEngine(ctx).Where("uid = ?", uid).Delete(&TwoFactor{}); e != nil {
return e
}
webAuthn, e = db.GetEngine(ctx).Where("user_id = ?", uid).Delete(&WebAuthnCredential{})
return e
})
return totp, webAuthn, err
}
-35
View File
@@ -10,7 +10,6 @@ import (
auth_model "gitea.dev/models/auth"
"gitea.dev/models/unittest"
"github.com/go-webauthn/webauthn/webauthn"
"github.com/pquerna/otp/totp"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -46,37 +45,3 @@ func TestTwoFactorValidateAndConsumeTOTP(t *testing.T) {
require.NoError(t, err)
assert.False(t, ok)
}
func TestDisableTwoFactor(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
ctx := t.Context()
const uid = 1000 // a uid with no user/2FA fixtures
// Enroll TOTP and register a WebAuthn credential.
tfa := &auth_model.TwoFactor{UID: uid}
require.NoError(t, tfa.SetSecret("test-secret"))
require.NoError(t, auth_model.NewTwoFactor(ctx, tfa))
_, err := auth_model.CreateCredential(ctx, uid, "test-key", &webauthn.Credential{ID: []byte("test-cred-id")})
require.NoError(t, err)
has, err := auth_model.HasTwoFactorOrWebAuthn(ctx, uid)
require.NoError(t, err)
require.True(t, has)
// Both records are removed and counted separately.
totp, webAuthn, err := auth_model.DisableTwoFactor(ctx, uid)
require.NoError(t, err)
assert.EqualValues(t, 1, totp)
assert.EqualValues(t, 1, webAuthn)
has, err = auth_model.HasTwoFactorOrWebAuthn(ctx, uid)
require.NoError(t, err)
assert.False(t, has)
// A second call on a user without 2FA is a no-op.
totp, webAuthn, err = auth_model.DisableTwoFactor(ctx, uid)
require.NoError(t, err)
assert.EqualValues(t, 0, totp)
assert.EqualValues(t, 0, webAuthn)
}
-4
View File
@@ -116,10 +116,6 @@ func RegisterModel(bean any, initFunc ...func() error) {
}
}
func ResetModels() {
registeredModels, registeredInitFuncs = nil, nil
}
// SyncAllTables sync the schemas of all tables, is required by unit test code
func SyncAllTables() error {
_, err := xormEngine.StoreEngine("InnoDB").SyncWithOptions(xorm.SyncOptions{
+3 -3
View File
@@ -15,7 +15,7 @@ import (
"gitea.dev/models/unittest"
user_model "gitea.dev/models/user"
"gitea.dev/modules/commitstatus"
"gitea.dev/modules/git"
"gitea.dev/modules/gitrepo"
"github.com/stretchr/testify/assert"
)
@@ -186,11 +186,11 @@ func TestFindRepoRecentCommitStatusContexts(t *testing.T) {
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
gitRepo, err := git.OpenRepository(repo2)
gitRepo, err := gitrepo.OpenRepository(t.Context(), repo2)
assert.NoError(t, err)
defer gitRepo.Close()
commit, err := gitRepo.GetBranchCommit(t.Context(), repo2.DefaultBranch)
commit, err := gitRepo.GetBranchCommit(repo2.DefaultBranch)
assert.NoError(t, err)
defer func() {
-15
View File
@@ -1,15 +0,0 @@
// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package models
import (
"context"
"gitea.dev/models/unit"
)
// Init initialize model
func Init(ctx context.Context) error {
return unit.LoadUnitConfig()
}
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package repostats
package models
import (
"testing"
@@ -11,23 +11,17 @@ import (
"regexp"
"strings"
"gitea.dev/models/db" //nolint:depguard // allow to access db in migration
"gitea.dev/models/db"
"gitea.dev/modules/log"
"gitea.dev/modules/setting"
"xorm.io/builder"
"xorm.io/xorm/schemas"
)
type (
EngineMigration = db.EngineMigration
Session = db.Session
)
// RecreateTables will recreate the tables for the provided beans using the newly provided bean definition and move all data to that new table
// WARNING: YOU MUST PROVIDE THE FULL BEAN DEFINITION
func RecreateTables(beans ...any) func(EngineMigration) error {
return func(x EngineMigration) error {
func RecreateTables(beans ...any) func(db.EngineMigration) error {
return func(x db.EngineMigration) error {
sess := x.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
@@ -47,7 +41,7 @@ func RecreateTables(beans ...any) func(EngineMigration) error {
// RecreateTable will recreate the table using the newly provided bean definition and move all data to that new table
// WARNING: YOU MUST PROVIDE THE FULL BEAN DEFINITION
// WARNING: YOU MUST COMMIT THE SESSION AT THE END
func RecreateTable(sess Session, bean any) error {
func RecreateTable(sess db.Session, bean any) error {
// TODO: This will not work if there are foreign keys
tableName := sess.Engine().TableName(bean)
@@ -310,7 +304,7 @@ func RecreateTable(sess Session, bean any) error {
}
// WARNING: YOU MUST COMMIT THE SESSION AT THE END
func DropTableColumns(sess Session, tableName string, columnNames ...string) (err error) {
func DropTableColumns(sess db.Session, tableName string, columnNames ...string) (err error) {
if tableName == "" || len(columnNames) == 0 {
return nil
}
@@ -480,7 +474,7 @@ func DropTableColumns(sess Session, tableName string, columnNames ...string) (er
}
// ModifyColumn will modify column's type or other property. SQLITE is not supported
func ModifyColumn(x EngineMigration, tableName string, col *schemas.Column) error {
func ModifyColumn(x db.EngineMigration, tableName string, col *schemas.Column) error {
var indexes map[string]*schemas.Index
var err error
// MSSQL have to remove index at first, otherwise alter column will fail
@@ -514,7 +508,3 @@ func ModifyColumn(x EngineMigration, tableName string, col *schemas.Column) erro
}
return nil
}
func Iterate[Bean any](ctx context.Context, cond builder.Cond, f func(ctx context.Context, bean *Bean) error) error {
return db.Iterate(ctx, cond, f)
}
@@ -1,13 +1,12 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package base_test
package base
import (
"testing"
"gitea.dev/modelmigration/base"
"gitea.dev/modelmigration/migrationtest"
"gitea.dev/models/migrations/migrationtest"
"gitea.dev/modules/timeutil"
"xorm.io/xorm/names"
@@ -56,7 +55,7 @@ func Test_DropTableColumns(t *testing.T) {
t.Errorf("unable to begin transaction: %v", err)
return
}
if err := base.DropTableColumns(sess, "drop_test", columns[i:]...); err != nil {
if err := DropTableColumns(sess, "drop_test", columns[i:]...); err != nil {
sess.Close()
t.Errorf("Unable to drop columns[%d:]: %s from drop_test: %v", i, columns[i:], err)
return
@@ -83,7 +82,7 @@ func Test_DropTableColumns(t *testing.T) {
t.Errorf("unable to begin transaction: %v", err)
return
}
if err := base.DropTableColumns(sess, "drop_test", dropcols...); err != nil {
if err := DropTableColumns(sess, "drop_test", dropcols...); err != nil {
sess.Close()
t.Errorf("Unable to drop columns: %s from drop_test: %v", dropcols, err)
return
@@ -2,36 +2,36 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package modelmigration
package migrations
import (
"context"
"errors"
"fmt"
"gitea.dev/modelmigration/base"
"gitea.dev/modelmigration/v1_10"
"gitea.dev/modelmigration/v1_11"
"gitea.dev/modelmigration/v1_12"
"gitea.dev/modelmigration/v1_13"
"gitea.dev/modelmigration/v1_14"
"gitea.dev/modelmigration/v1_15"
"gitea.dev/modelmigration/v1_16"
"gitea.dev/modelmigration/v1_17"
"gitea.dev/modelmigration/v1_18"
"gitea.dev/modelmigration/v1_19"
"gitea.dev/modelmigration/v1_20"
"gitea.dev/modelmigration/v1_21"
"gitea.dev/modelmigration/v1_22"
"gitea.dev/modelmigration/v1_23"
"gitea.dev/modelmigration/v1_24"
"gitea.dev/modelmigration/v1_25"
"gitea.dev/modelmigration/v1_26"
"gitea.dev/modelmigration/v1_27"
"gitea.dev/modelmigration/v1_6"
"gitea.dev/modelmigration/v1_7"
"gitea.dev/modelmigration/v1_8"
"gitea.dev/modelmigration/v1_9"
"gitea.dev/models/db"
"gitea.dev/models/migrations/v1_10"
"gitea.dev/models/migrations/v1_11"
"gitea.dev/models/migrations/v1_12"
"gitea.dev/models/migrations/v1_13"
"gitea.dev/models/migrations/v1_14"
"gitea.dev/models/migrations/v1_15"
"gitea.dev/models/migrations/v1_16"
"gitea.dev/models/migrations/v1_17"
"gitea.dev/models/migrations/v1_18"
"gitea.dev/models/migrations/v1_19"
"gitea.dev/models/migrations/v1_20"
"gitea.dev/models/migrations/v1_21"
"gitea.dev/models/migrations/v1_22"
"gitea.dev/models/migrations/v1_23"
"gitea.dev/models/migrations/v1_24"
"gitea.dev/models/migrations/v1_25"
"gitea.dev/models/migrations/v1_26"
"gitea.dev/models/migrations/v1_27"
"gitea.dev/models/migrations/v1_6"
"gitea.dev/models/migrations/v1_7"
"gitea.dev/models/migrations/v1_8"
"gitea.dev/models/migrations/v1_9"
"gitea.dev/modules/git"
"gitea.dev/modules/log"
"gitea.dev/modules/setting"
@@ -44,23 +44,23 @@ const minDBVersion = 70 // Gitea 1.5.3
type migration struct {
idNumber int64 // DB version is "the last migration's idNumber" + 1
description string
migrate func(context.Context, base.EngineMigration) error
migrate func(context.Context, db.EngineMigration) error
}
// newMigration creates a new migration
func newMigration[T func(base.EngineMigration) error | func(context.Context, base.EngineMigration) error](idNumber int64, desc string, fn T) *migration {
func newMigration[T func(db.EngineMigration) error | func(context.Context, db.EngineMigration) error](idNumber int64, desc string, fn T) *migration {
m := &migration{idNumber: idNumber, description: desc}
var ok bool
if m.migrate, ok = any(fn).(func(context.Context, base.EngineMigration) error); !ok {
m.migrate = func(ctx context.Context, x base.EngineMigration) error {
return any(fn).(func(base.EngineMigration) error)(x)
if m.migrate, ok = any(fn).(func(context.Context, db.EngineMigration) error); !ok {
m.migrate = func(ctx context.Context, x db.EngineMigration) error {
return any(fn).(func(db.EngineMigration) error)(x)
}
}
return m
}
// Migrate executes the migration
func (m *migration) Migrate(ctx context.Context, x base.EngineMigration) error {
func (m *migration) Migrate(ctx context.Context, x db.EngineMigration) error {
return m.migrate(ctx, x)
}
@@ -71,7 +71,7 @@ type Version struct {
}
// Use noopMigration when there is a migration that has been no-oped
var noopMigration = func(_ base.EngineMigration) error { return nil }
var noopMigration = func(_ db.EngineMigration) error { return nil }
var preparedMigrations []*migration
@@ -420,13 +420,12 @@ func prepareMigrationTasks() []*migration {
newMigration(340, "Add ContinueOnError column to ActionRunJob", v1_27.AddContinueOnErrorToActionRunJob),
newMigration(341, "Convert legacy MSSQL DATETIME columns to DATETIME2", v1_27.FixLegacyMSSQLDateTimeColumns),
newMigration(342, "Add scoped workflows schema", v1_27.AddScopedWorkflowsSchema),
// Gitea 1.27.0 ends at migration ID number 342 (database version 343)
}
return preparedMigrations
}
// GetCurrentDBVersion returns the current db version
func GetCurrentDBVersion(x base.EngineMigration) (int64, error) {
func GetCurrentDBVersion(x db.EngineMigration) (int64, error) {
if err := x.Sync(new(Version)); err != nil {
return -1, fmt.Errorf("sync: %w", err)
}
@@ -459,7 +458,7 @@ func ExpectedDBVersion() int64 {
}
// EnsureUpToDate will check if the db is at the correct version
func EnsureUpToDate(ctx context.Context, x base.EngineMigration) error {
func EnsureUpToDate(ctx context.Context, x db.EngineMigration) error {
currentDB, err := GetCurrentDBVersion(x)
if err != nil {
return err
@@ -491,7 +490,7 @@ func migrationIDNumberToDBVersion(idNumber int64) int64 {
}
// Migrate database to current version
func Migrate(ctx context.Context, x base.EngineMigration) error {
func Migrate(ctx context.Context, x db.EngineMigration) error {
migrations := prepareMigrationTasks()
maxDBVer := calcDBVersion(migrations)
@@ -1,7 +1,7 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package modelmigration
package migrations
import (
"testing"
@@ -8,9 +8,8 @@ import (
"path/filepath"
"testing"
"gitea.dev/modelmigration/base"
"gitea.dev/models/db" //nolint:depguard // allow to access db in migration tests
"gitea.dev/models/unittest" //nolint:depguard // allow to access db in migration tests
"gitea.dev/models/db"
"gitea.dev/models/unittest"
"gitea.dev/modules/git"
"gitea.dev/modules/setting"
"gitea.dev/modules/testlogger"
@@ -23,8 +22,8 @@ import (
// PrepareTestEnv prepares the test environment and reset the database. The skip parameter should usually be 0.
// Provide models to be sync'd with the database - in particular any models you expect fixtures to be loaded from.
//
// fixtures in `modelmigration/fixtures/<TestName>` will be loaded automatically
func PrepareTestEnv(t *testing.T, skip int, syncModels ...any) (base.EngineMigration, func()) {
// fixtures in `models/migrations/fixtures/<TestName>` will be loaded automatically
func PrepareTestEnv(t *testing.T, skip int, syncModels ...any) (db.EngineMigration, func()) {
t.Helper()
ourSkip := 2
ourSkip += skip
@@ -58,18 +57,14 @@ func PrepareTestEnv(t *testing.T, skip int, syncModels ...any) (base.EngineMigra
}
}
db.ResetModels()
if len(syncModels) > 0 {
for _, syncModel := range syncModels {
db.RegisterModel(syncModel)
}
if err := x.Sync(syncModels...); err != nil {
t.Errorf("error during sync: %v", err)
return x, deferFn
}
}
fixturesDir := filepath.Join(giteaRoot, "modelmigration/fixtures", t.Name())
fixturesDir := filepath.Join(giteaRoot, "models", "migrations", "fixtures", t.Name())
if _, err := os.Stat(fixturesDir); err == nil {
t.Logf("initializing fixtures from: %s", fixturesDir)
@@ -93,7 +88,7 @@ func PrepareTestEnv(t *testing.T, skip int, syncModels ...any) (base.EngineMigra
return x, deferFn
}
func LoadTableSchemasMap(t *testing.T, x base.EngineMigration) map[string]*schemas.Table {
func LoadTableSchemasMap(t *testing.T, x db.EngineMigration) map[string]*schemas.Table {
tables, err := x.DBMetas()
require.NoError(t, err)
tableMap := make(map[string]*schemas.Table)

Some files were not shown because too many files have changed in this diff Show More