Compare commits

..

135 commits

Author SHA1 Message Date
Renovate Bot
5ec1f7f363 Update module github.com/redis/go-redis/v9 to v9.7.3 (v10.0/forgejo) (#7284)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7284
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
Co-committed-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
2025-03-21 10:04:58 +00:00
Earl Warren
fc5a303b70 [v10.0/forgejo] i18n: update of translations from Codeberg Translate (#7277)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7277
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2025-03-20 21:59:32 +00:00
0ko
8a7dc4ea06 [v10.0/forgejo] i18n: update of translations from Codeberg Translate
Translation updates that are applicable to v10 strings were picked from this commit: 5a7af0dae2

Changes to strings that are only present in the v11 branch were not picked.

Below is a list of co-authors of the ported commit. It may contain co-authors who's changes were not picked due to being v11-only.

Co-authored-by: 0ko <0ko@noreply.codeberg.org>
Co-authored-by: Baempaieo <baempaieo@noreply.codeberg.org>
Co-authored-by: Codeberg Translate <translate@codeberg.org>
Co-authored-by: Edgarsons <edgarsons@noreply.codeberg.org>
Co-authored-by: EssGeeEich <essgeeeich@noreply.codeberg.org>
Co-authored-by: Juno Takano <jutty@noreply.codeberg.org>
Co-authored-by: Zughy <zughy@noreply.codeberg.org>
Co-authored-by: banaanihillo <banaanihillo@noreply.codeberg.org>
Co-authored-by: httpsterio <httpsterio@noreply.codeberg.org>
Co-authored-by: ozgur <ozgur@noreply.codeberg.org>
Co-authored-by: tacaly <frederick@tacaly.com>
2025-03-20 20:39:26 +05:00
0ko
4b3135a859 [v10.0/forgejo] i18n: update of translations from Codeberg Translate
Translation updates that are applicable to v10 strings were picked from this commit: 1132fde45f

Changes to strings that are only present in the v11 branch were not picked.

Below is a list of co-authors of the ported commit. It may contain co-authors who's changes were not picked due to being v11-only.

Co-authored-by: 0ko <0ko@noreply.codeberg.org>
Co-authored-by: Adolfo Jayme Barrientos <fito@noreply.codeberg.org>
Co-authored-by: Anonymous <anonymous@noreply.codeberg.org>
Co-authored-by: Atalanttore <atalanttore@noreply.codeberg.org>
Co-authored-by: Benedikt Straub <benedikt-straub@web.de>
Co-authored-by: Codeberg Translate <translate@codeberg.org>
Co-authored-by: Dirk <dirk@noreply.codeberg.org>
Co-authored-by: Edgarsons <edgarsons@noreply.codeberg.org>
Co-authored-by: Fjuro <fjuro@noreply.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-authored-by: Kita Ikuyo <kitakita@disroot.org>
Co-authored-by: Outbreak2096 <outbreak2096@noreply.codeberg.org>
Co-authored-by: SomeTr <sometr@noreply.codeberg.org>
Co-authored-by: justbispo <justbispo@noreply.codeberg.org>
Co-authored-by: nykula <nykula@noreply.codeberg.org>
Co-authored-by: tacaly <frederick@tacaly.com>
Co-authored-by: xtex <xtexchooser@duck.com>
2025-03-20 20:37:45 +05:00
0ko
c082731211 [v10.0/forgejo] i18n: update of translations from Codeberg Translate
Translation updates that are applicable to v10 strings were picked from this commit: b2d01fdde6

Changes to strings that are only present in the v11 branch were not picked.

Below is a list of co-authors of the ported commit. It may contain co-authors who's changes were not picked due to being v11-only.

Co-authored-by: lordwektabyte <lordwektabyte@users.noreply.translate.codeberg.org>
Co-authored-by: Marti <marti@noreply.codeberg.org>
Co-authored-by: 0ko <0ko@noreply.codeberg.org>
Co-authored-by: alanmena <alanmena@noreply.codeberg.org>
Co-authored-by: Juno Takano <jutty@noreply.codeberg.org>
Co-authored-by: Benedikt Straub <benedikt-straub@web.de>
Co-authored-by: Edgarsons <edgarsons@noreply.codeberg.org>
Co-authored-by: Wuzzy <wuzzy@disroot.org>
Co-authored-by: justbispo <justbispo@noreply.codeberg.org>
Co-authored-by: Kita Ikuyo <kitakita@disroot.org>
Co-authored-by: Fjuro <fjuro@noreply.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-authored-by: kwoot <kwoot@noreply.codeberg.org>
Co-authored-by: SomeTr <sometr@noreply.codeberg.org>
Co-authored-by: monty24 <monty24@noreply.codeberg.org>
Co-authored-by: Sampo Harjula <sahtor@noreply.codeberg.org>
Co-authored-by: tacaly <frederick@tacaly.com>
Co-authored-by: artnay <artnay@noreply.codeberg.org>
Co-authored-by: Outbreak2096 <outbreak2096@noreply.codeberg.org>
2025-03-20 20:36:26 +05:00
Gusted
c1e9fd738b fix: consider issues in repository accessible via access table (#7270)
- Consider the following scenario: a private repository in an organization with a team that has no specific access to that repository. Members of that team are still able to visit the repository because of entries in the `access` table.
- Consider this specific scenario for the gathering of issues for project tables.
- Unit test added
- Resolves forgejo/forgejo#7217
- Ref: forgejo/forgejo#6843

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7270
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
(cherry picked from commit 72ee7f3b00)
2025-03-19 16:46:20 +00:00
forgejo-backport-action
400bd08cfe [v10.0/forgejo] fix: discard v25 secrets migrations errors instead of failing (#7255)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/7251

Failing the migration when a corrupted record is found is problematic because there is no transaction and the database may need to be restored from a backup to attempt the migration again, after deleting the corrupted records.

Each documented case of failed migration was resolved by removing the corrupted records. There is no instance of a failed migration that was caused by non corrupted record.

In the unlikely event of a false negative where a two_factor record is discarded although it is in use, the only consequence is that the user will have to enroll again. Detailed logs are displayed so the Forgejo admin can file a bug report if that happens.

Refs: https://codeberg.org/forgejo/forgejo/issues/6637

<!--start release-notes-assistant-->

## Release notes
<!--URL:https://codeberg.org/forgejo/forgejo-->
- Bug fixes
  - [PR](https://codeberg.org/forgejo/forgejo/pulls/7251): <!--number 7251 --><!--line 0 --><!--description V2hlbiBtaWdyYXRpbmcgZnJvbSBhIEZvcmdlam8gdmVyc2lvbiBsb3dlciB0aGFuIHYxMCwgdGhlIFRPVFAgc2VjcmV0cyBmb3VuZCB0byBiZSBjb3JydXB0ZWQgYXJlIG5vdyB0cmFuc3BhcmVudGx5IHJlbW92ZWQgZnJvbSB0aGUgZGF0YWJhc2UgaW5zdGVhZCBvZiBmYWlsaW5nIHRoZSBtaWdyYXRpb24uIFRPVFAgaXMgbm8gbG9uZ2VyIHJlcXVpcmVkIHRvIGxvZ2luIHdpdGggdGhlIGFzc29jaWF0ZWQgdXNlcnMuIFRoZXkgc2hvdWxkIGJlIGluZm9ybWVkIGJlY2F1c2UgdGhleSB3aWxsIG5lZWQgdG8gdmlzaXQgdGhlaXIgc2VjdXJpdHkgc2V0dGluZ3MgYW5kIGNvbmZpZ3VyZSBUT1RQIGFnYWluLiBObyBvdGhlciBhY3Rpb24gaXMgcmVxdWlyZWQu-->When migrating from a Forgejo version lower than v10, the TOTP secrets found to be corrupted are now transparently removed from the database instead of failing the migration. TOTP is no longer required to login with the associated users. They should be informed because they will need to visit their security settings and configure TOTP again. No other action is required.<!--description-->
<!--end release-notes-assistant-->

Co-authored-by: Earl Warren <contact@earl-warren.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7255
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-03-17 17:55:32 +00:00
forgejo-backport-action
e7d103319e [v10.0/forgejo] fix(api): typo in API description for repoSearch (#7202)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/7199

Corrected miss-spelled description for the `is_private` field on `repoSearch`, in which 'public' was spelled as 'pubic'.

Co-authored-by: luxzi <lesson085@gmail.com>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7202
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-03-11 14:03:19 +00:00
forgejo-backport-action
0c0155daf7 [v10.0/forgejo] fix: no notification for replies to pending comments (#7178)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/7167

- Replies to pending review comments no longer generate a notification, this was caused by an incomplete determination if the comment was part of the pending review or not.
- The logic was reworked to do the following if it's part of a pending review: It is not a single review and if it's a reply then the comment it is replying to is part of a pending review.
- Added integration test.
- Resolves forgejo/forgejo#7151

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7178
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-03-09 16:06:01 +00:00
forgejo-backport-action
40f1e0b1ff [v10.0/forgejo] fix: revert issue rendering for <a> element (#7177)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/7171

- Issue title rendering can lead to nested `<a>` which is incorrect. So
revert a portion of forgejo/forgejo#6715.
- Integration test adjusted
- Resolves forgejo/forgejo#7076

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7177
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-03-09 15:50:23 +00:00
forgejo-backport-action
c2158b2a1f [v10.0/forgejo] fix: consider public issues for project boards (#7144)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/7143

- The security patch of forgejo/forgejo#6843 fixed the issue where project boards loaded all issues without considering if the doer actually had permission to view that issue. Within that patch the call to `Issues` was modified to include this permission checking.
- The query being generated was not entirely correct. Issues in public repositories weren't considered correctly (partly the fault of not setting `AllPublic` unconditionally) in the cause an authenticated user loaded the project.
- This is now fixed by setting `AllPublic` unconditionally and subsequently fixing the `Issue` function to ensure that the combination of setting `AllPublic` and `User` generates the correct query, by combining the permission check and issues in public repositories as one `AND` query.
- Added unit testing.
- Added integration testing.
- Resolves Codeberg/Community#1809
- Regression of https://codeberg.org/forgejo/forgejo/pulls/6843

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7144
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-03-07 00:51:07 +00:00
Renovate Bot
6e0f449fb9 Update module golang.org/x/crypto to v0.35.0 (v10.0/forgejo) (#7072)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7072
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
Co-committed-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
2025-03-02 17:09:15 +00:00
forgejo-backport-action
a830b4de6b [v10.0/forgejo] chore(ci): ensure the manually cached Go can be run (#7079)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/7078

```
go version go1.24.0 linux/amd64
go env
drwx------ 1 root root 4096 Feb 28 15:52 /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.0.linux-amd64/../../../../..
drwxr-xr-x 4 root root 4096 Feb 28 15:52 /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.0.linux-amd64/../../../..
drwxr-xr-x 4 root root 4096 Feb 28 15:52 /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.0.linux-amd64/../../..
drwxr-xr-x 4 root root 4096 Feb 28 15:52 /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.0.linux-amd64/../..
drwxr-xr-x 3 root root 4096 Feb 28 15:52 /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.0.linux-amd64/..
dr-xr-xr-x 6 root root 4096 Feb 28 15:52 /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.0.linux-amd64
-r-xr-xr-x 1 root root 14314681 Feb 28 15:52 /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.0.linux-amd64/bin/go
-r-xr-xr-x 1 root root 14314681 Feb 28 15:52 /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.0.linux-amd64/bin/go
bash: line 1: /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.0.linux-amd64/bin/go: Permission denied
bash: line 1: /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.0.linux-amd64/bin/go: Permission denied
mkdir: cannot create directory ‘’: No such file or directory
mkdir: cannot create directory ‘’: No such file or directory
```

Refs: https://codeberg.org/forgejo/forgejo/actions/runs/61591#jobstep-3-22
Co-authored-by: Earl Warren <contact@earl-warren.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7079
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-02-28 16:21:28 +00:00
Earl Warren
6fcb8f646f [v10.0/forgejo] chore(ci): Get Go binary from GOROOT instead of hardcoded path (#7073)
Backport: https://codeberg.org/forgejo/forgejo/pulls/6590
Co-authored-by: fnetX <otto@codeberg.org>
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7073
Reviewed-by: Otto <otto@codeberg.org>
2025-02-28 15:36:13 +00:00
0ko
c7bd6f4a3d [v10.0/forgejo] i18n: update of translations from multiple sources (#7067)
Translation updates that are applicable to v10 strings were picked from these commits:
* 94e782038d
* 75b9bd82e8
* 7296f11288
* 535408143a

Changes to strings that are only present in the v11 branch were not picked.

New locales ga-IE and ro were not picked because they're not used even in the v11 branch yet and languages are usually to be added in major versions.

This commit contains chanes backported from Gitea, but attribution is not possible due to it being missing in the origin repo commits in the first place. You might have luck finding transators responsible for these changes in Gitea project on Crowdin: https://crowdin.com/project/gitea.

Changes from Gitea are up to commit fc1b383da9/options/locale

Below is a list of co-authors of the ported commits. It may contain co-authors who's changes were not picked due to being v11-only.

Co-authored-by: 0ko <0ko@users.noreply.translate.codeberg.org>
Co-authored-by: adriand <adriand@users.noreply.translate.codeberg.org>
Co-authored-by: amearb <amearb@users.noreply.translate.codeberg.org>
Co-authored-by: Anonymous <anonymous@users.noreply.translate.codeberg.org>
Co-authored-by: anze <anze@users.noreply.translate.codeberg.org>
Co-authored-by: artnay <artnay@users.noreply.translate.codeberg.org>
Co-authored-by: be4zad <be4zad@users.noreply.translate.codeberg.org>
Co-authored-by: Benedikt Straub <benedikt-straub@web.de>
Co-authored-by: Coral Pink <coralpink@users.noreply.translate.codeberg.org>
Co-authored-by: Dirk <dirk@users.noreply.translate.codeberg.org>
Co-authored-by: DKMellow <dkmellow@users.noreply.translate.codeberg.org>
Co-authored-by: earl-warren <earl-warren@users.noreply.translate.codeberg.org>
Co-authored-by: Edgarsons <edgarsons@users.noreply.translate.codeberg.org>
Co-authored-by: Fjuro <fjuro@users.noreply.translate.codeberg.org>
Co-authored-by: gedankenstuecke <gedankenstuecke@users.noreply.translate.codeberg.org>
Co-authored-by: Gitea translators on Crowdin <teabot@gitea.io>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-authored-by: hugoalh <hugoalh@users.noreply.translate.codeberg.org>
Co-authored-by: IndieHum <indiehum@users.noreply.translate.codeberg.org>
Co-authored-by: Juno Takano <jutty@users.noreply.translate.codeberg.org>
Co-authored-by: kbruen <kbruen@users.noreply.translate.codeberg.org>
Co-authored-by: Kenneth Bruen <kbruen@users.noreply.translate.codeberg.org>
Co-authored-by: Kenneth Bruen <kenny@kbruen.ro>
Co-authored-by: Kita Ikuyo <searinminecraft@courvix.com>
Co-authored-by: laegnur <laegnur@users.noreply.translate.codeberg.org>
Co-authored-by: Laxystem <laxystem@users.noreply.translate.codeberg.org>
Co-authored-by: Laxystem <the@laxla.quest>
Co-authored-by: Lzebulon <lzebulon@users.noreply.translate.codeberg.org>
Co-authored-by: marat2509 <marat2509@users.noreply.translate.codeberg.org>
Co-authored-by: noiro <noiro@users.noreply.translate.codeberg.org>
Co-authored-by: nykula <nykula@users.noreply.translate.codeberg.org>
Co-authored-by: otf31 <otf31@users.noreply.translate.codeberg.org>
Co-authored-by: Outbreak2096 <outbreak2096@users.noreply.translate.codeberg.org>
Co-authored-by: Panagiotis \"Ivory\" Vasilopoulos <git@n0toose.net>
Co-authored-by: RealEnder <realender@users.noreply.translate.codeberg.org>
Co-authored-by: Ricky-Tigg <ricky-tigg@users.noreply.translate.codeberg.org>
Co-authored-by: SomeTr <sometr@users.noreply.translate.codeberg.org>
Co-authored-by: tacaly <frederick@tacaly.com>
Co-authored-by: Wuzzy <wuzzy@disroot.org>
Co-authored-by: xtex <xtexchooser@duck.com>
Co-authored-by: yeager <yeager@users.noreply.translate.codeberg.org>
Co-authored-by: yorunin <yorunin@users.noreply.translate.codeberg.org>
Co-authored-by: Zughy <zughy@users.noreply.translate.codeberg.org>

<!--start release-notes-assistant-->

## Release notes
<!--URL:https://codeberg.org/forgejo/forgejo-->
- Localization
  - [PR](https://codeberg.org/forgejo/forgejo/pulls/7067): <!--number 7067 --><!--line 0 --><!--description aTE4bjogdXBkYXRlIG9mIHRyYW5zbGF0aW9ucyBmcm9tIG11bHRpcGxlIHNvdXJjZXM=-->i18n: update of translations from multiple sources<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7067
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: 0ko <0ko@noreply.codeberg.org>
Co-committed-by: 0ko <0ko@noreply.codeberg.org>
2025-02-28 05:19:31 +00:00
Renovate Bot
2e76237e26 Update https://data.forgejo.org/forgejo/forgejo-build-publish action to v5.3.4 (v10.0/forgejo) (#7052)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [https://data.forgejo.org/forgejo/forgejo-build-publish](https://data.forgejo.org/forgejo/forgejo-build-publish) | action | patch | `v5.3.1` -> `v5.3.4` |

---

> ⚠️ **Warning**
>
> Some dependencies could not be looked up. Check the Dependency Dashboard for more information.

---

### Release Notes

<details>
<summary>forgejo/forgejo-build-publish (https://data.forgejo.org/forgejo/forgejo-build-publish)</summary>

### [`v5.3.4`](https://code.forgejo.org/forgejo/forgejo-build-publish/compare/v5.3.3...v5.3.4)

[Compare Source](https://data.forgejo.org/forgejo/forgejo-build-publish/compare/v5.3.3...v5.3.4)

### [`v5.3.3`](https://code.forgejo.org/forgejo/forgejo-build-publish/compare/v5.3.2...v5.3.3)

[Compare Source](https://data.forgejo.org/forgejo/forgejo-build-publish/compare/v5.3.2...v5.3.3)

### [`v5.3.2`](https://code.forgejo.org/forgejo/forgejo-build-publish/compare/v5.3.1...v5.3.2)

[Compare Source](https://data.forgejo.org/forgejo/forgejo-build-publish/compare/v5.3.1...v5.3.2)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - "* 0-3 * * *" (UTC).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNzguMSIsInVwZGF0ZWRJblZlciI6IjM5LjE3OC4xIiwidGFyZ2V0QnJhbmNoIjoidjEwLjAvZm9yZ2VqbyIsImxhYmVscyI6WyJkZXBlbmRlbmN5LXVwZ3JhZGUiLCJ0ZXN0L25vdC1uZWVkZWQiXX0=-->

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7052
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
Co-committed-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
2025-02-24 10:51:56 +00:00
Earl Warren
a6a1b11670 [v10.0/forgejo] fix(release): the rootless image version label is not set (#7046)
Backport: https://codeberg.org/forgejo/forgejo/pulls/7038

There is a test for that but it was a false positive.

Refs: https://code.forgejo.org/forgejo/forgejo-build-publish/pulls/27
(cherry picked from commit 078ca85d87)

```
Conflicts:
	Dockerfile.rootless
  trivial context conflict
```

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7046
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-committed-by: Earl Warren <contact@earl-warren.org>
2025-02-24 09:07:14 +00:00
Renovate Bot
b2c3f99901 Update dependency go to v1.23.6 (v10.0/forgejo) (#6812)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [go](https://go.dev/) ([source](https://github.com/golang/go)) | toolchain | patch | `1.23.5` -> `1.23.6` |

---

> ⚠️ **Warning**
>
> Some dependencies could not be looked up. Check the Dependency Dashboard for more information.

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - "* 0-3 * * *" (UTC).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNTguMiIsInVwZGF0ZWRJblZlciI6IjM5LjE1OC4yIiwidGFyZ2V0QnJhbmNoIjoidjEwLjAvZm9yZ2VqbyIsImxhYmVscyI6WyJkZXBlbmRlbmN5LXVwZ3JhZGUiLCJ0ZXN0L25vdC1uZWVkZWQiXX0=-->

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6812
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
Co-committed-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
2025-02-23 08:29:21 +00:00
forgejo-backport-action
52fb476fb1 [v10.0/forgejo] fix: do not allow SSH url for migration (#7018)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/7004

- Add a new function `IsPushMirrorURLAllowed` that will allow `ssh://` url and make the existing `IsMigrateURLAllowed` not allow such URLs anymore.
- Resolves forgejo/forgejo#6960
- Existing integration tests make sure that SSH urls are still allowed for the push mirror feature and added unit test to ensure that `IsMigrateURLAllowed` no longer allows SSH urls.

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7018
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-02-21 11:46:08 +00:00
forgejo-backport-action
3eacbfead9 [v10.0/forgejo] fix: return 404 for empty repositories (#7014)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/7003

Some endpoints (`/api/v1/repos/*/*/raw`, `/api/v1/repos/*/*/media`, ...;
anything that uses both `context.ReferencesGitRepo()` and
`context.RepoRefForAPI` really) returned a 500 when the repository was
completely empty. This resulted in some confusion in
https://github.com/datalad/datalad-usage-dashboard/issues/47 because the
same request for a non-existent file in a repository could sometimes
generate a 404 and sometimes a 500, depending on if the git repository
is initialized at all or not.

Returning a 404 seems more appropriate here, since this isn't an
unexpected internal error, but just another way of not finding the
requested data.

Co-authored-by: Matthias Riße <m.risse@fz-juelich.de>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7014
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-02-20 22:26:30 +00:00
forgejo-backport-action
932afb2036 [v10.0/forgejo] fix: delay deleting authorization token (#6976)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6937

- 1ce33aa38d extended the LTA table with a purpose column so it could be extended to other tokens. However some are single-use tokens and should be deleted after use.
- This did not result in a good UX for activating user as they needed to also fill in their passwords and in the case that the password was incorrect the token would no longer be usable.
- This patch modifies the code to allow for a little delay before deleting authorization tokens to do additional verification such as the password check. This cannot be done before the authorization token check as that the authorization token determines who the user is.
- Resolves forgejo/forgejo#6912
- Adjusted existing unit test.

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6976
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-02-19 07:06:01 +00:00
forgejo-backport-action
cc8a05f693 [v10.0/forgejo] fix: native parsing of ssh certificate key (#6954)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6953

- In the case of parsing an public SSH certificate key, use the underlying key type instead of the certificate type. This means `ed25519-cert-v01` would be seen as `ed25519` type and thus correctly parsed. Certificates do not
change the keysize or otherwise parsing of the key.
- Add unit test.

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6954
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-02-15 17:28:48 +00:00
forgejo-backport-action
0fe56e6059 [v10.0/forgejo] fix: disable forgotten password for external signin only (#6930)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6680

- Make it such that `[service].ENABLE_INTERNAL_SIGNIN = false` disables the forgotten password prompt on the login page.

Co-authored-by: davrot <davrot@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6930
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-02-14 13:37:46 +00:00
forgejo-backport-action
4802c33acb [v10.0/forgejo] fix: show internal login prompt for account linking (#6929)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6920

Fixes #6878.

Co-authored-by: Matthias Riße <m.risse@fz-juelich.de>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6929
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-02-14 13:25:46 +00:00
forgejo-backport-action
c56bbddf62 [v10.0/forgejo] enable ssh mirrors in rootless images (#6915)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6896

This mini-PR fixes mirror feature on docker rootless images, as discussed in #6894.

Thank you, regards

## Testing

- 24h After the PR is merged
- Visit https://v11.next.forgejo.org and create a ssh based mirror

Co-authored-by: Alessandro Ogier <alessandro.ogier@gmail.com>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6915
Reviewed-by: Otto <otto@codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-02-13 00:56:48 +00:00
forgejo-backport-action
a7ae98ff93 [v10.0/forgejo] fix(ui): hide extra PR property labels on title edit (#6905)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6898

* hide labels [AGit](https://codeberg.org/forgejo/forgejo/pulls/2444) and [Editable](https://codeberg.org/forgejo/forgejo/pulls/6863) on title edit mode: they make layout broken and are not really needed at edit state
* make the code slightly less boring

Co-authored-by: 0ko <0ko@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6905
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-02-12 09:05:43 +00:00
forgejo-backport-action
0aa872c4e3 [v10.0/forgejo] fix: always set stripped slashes on http request (#6884)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6866

- The middleware that takes care of normalizing `//user2/////repo1` to `/user2/repo1` would only set the normalized value to the Chi (Forgejo's http router) `RoutePath` field, so Chi would correctly do the routing. However not all components in Forgejo (like Forgejo's `context` module) rely on Chi to get this updated path and some still rely on the value of `(http.Request).URL.Path`, so always set the normalized value to the http request.
- Adjusted unit test.
- Resolves forgejo/forgejo#6822
- The related issue was caused by
751a3da979/services/context/context.go (L115)
using the value of the http request on not that was set in the Chi context.

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6884
Reviewed-by: Otto <otto@codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-02-10 20:00:25 +00:00
forgejo-backport-action
ee49a62bed [v10.0/forgejo] fix(ui): hide 'New migration' button on org pages with migrations disabled (#6850) (#6860)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6851

When migrations are disabled via `[repository].DISABLE_MIGRATIONS = true`, on organisation pages next to the 'New repository' button, the 'New migration' button is still shown.

This is caused by a logic error in the templates: instead of checking for disabled migrations, it checks for disabled pull mirrors. This patch fixes that to use `DisableMigrations` instead of `DisableNewPullMirrors`.

Signed-off-by: Daniel Baumann <daniel@debian.org>
Co-authored-by: Daniel Baumann <daniel@debian.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6860
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-02-08 15:45:58 +00:00
forgejo-backport-action
89c4c9c477 [v10.0/forgejo] fix: render link in heading correctly in TOC (#6859)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6853

- When you use a link in a heading such as `# [Text](link)` (instead of the conventional `# Text`) the TOC should only show `Text` and not `[Text](link)`.
- Use the `mdutil.Text` to only get the text from actual text nodes and not the text that was provided in the markdown input.
- Regression of e2fddcf681
- Resolves forgejo/forgejo#6847
- Added integration test.

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6859
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-02-08 14:33:01 +00:00
forgejo-backport-action
bdb78d42b6 [v10.0/forgejo] ui: update language stats layout and click behavior (#6854)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6700

Fix regression of https://codeberg.org/forgejo/forgejo/pulls/6344. It was reported by @Beowulf.

JS toggle [used](49c5102b40/templates/repo/sub_menu.tmpl (L38)) a selector which was broken by that PR, which caused the legend to appear separately instead of replacing the primary repo info.

## Changes

* use clear IDs `language-stats-bar` and `language-stats-legend`
* add simple e2e test

Instead of restoring the previous behavior, I moved the legend under the stats bar. To me it didn't make a lot of sense in the first place to replace the information in the primary bar with with completely different information. It did not save much space either.

Co-authored-by: 0ko <0ko@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6854
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-02-08 13:52:03 +00:00
Earl Warren
6ef900899e fix(sec): Forgejo Actions web routes (#6839)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6839
2025-02-08 06:21:18 +00:00
Earl Warren
a9f0bb9f68 fix(sec): permission check for project issue (#6838)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6838
2025-02-08 06:20:29 +00:00
Gusted
3b4f1b3469
fix(sec): add tests for private issues on projects
- Add integration and unit tests to ensure that private issues on
projects are not shown in any way, shape or form when the doer has no
access to it.

(cherry picked from commit 55dcc1d06cb12ddb750a0289fbb6e212f93957a8)
2025-02-08 06:06:06 +00:00
Gusted
77fc232e5b
fix(sec): permission check for project issue
- Do an access check when loading issues for a project column, currently
this is not done and exposes the title, labels and existence of a
private issue that the viewer of the project board may not have access
to.
- The number of issues cannot be calculated in a efficient manner
and stored in the database because their number may vary depending on
the visibility of the repositories participating in the project. The
previous implementation used the pre-calculated numbers stored in each
project, which did not reflect that potential variation.
- The code is derived from https://github.com/go-gitea/gitea/pull/22865

(cherry picked from commit 2193afaeb9954a5778f5a47aafd0e6fbbf48d000)
2025-02-08 06:06:03 +00:00
Gusted
5a7d70658d
fix(sec): web route test edit and delete variable
Exhaustively test each combination of deleting and updating a action
action variable via the web route.
2025-02-08 06:04:14 +00:00
Gusted
5046a10aec
fix(sec): add tests for web route delete runner
Exhaustively test each combination of deleting and updating a action
runner via the web route. Although updating an action runner was not
impacted, its good to have a test nonetheless.
2025-02-08 06:04:14 +00:00
Gusted
77db7655e0
fix(sec): web route update and delete runner variables
The web route to update and delete variables of runners did not check if
the ID that was given belonged to the context it was requested in, this
made it possible to update and delete every existing runner variable of
a instance for any authenticated user.

The code has been reworked to always take into account the context of
the request (owner and repository ID).
2025-02-08 06:04:14 +00:00
Gusted
c324910c31
fix(sec): web route delete runner
The web route to delete action runners did not check if the ID that was
given belonged to the context it was requested in, this made it possible
to delete every existing runner of a instance by a authenticated user.

The code was reworked to ensure that the caller of the delete
runner function retrieved the runner by ID and then checks if it belongs
to the context it was requested in, although this is not an optimal
solution it is consistent with the context checking of other code for
runners.
2025-02-08 06:04:14 +00:00
0ko
57ad0b868d [v10.0/forgejo] i18n: update of translations from Codeberg Translate (#6834)
Backport: https://codeberg.org/forgejo/forgejo/pulls/6745

Feel free to leave merge to me. My strategy is to use squash-merge, but copy the description of the actual commit into squash description, so attribution is preserved.

https://codeberg.org/forgejo/forgejo/pulls/6745 was quite large, so I decided it will be ok to backport just one PR before a new release.

<!--start release-notes-assistant-->

## Release notes
<!--URL:https://codeberg.org/forgejo/forgejo-->
- Localization
  - [PR](https://codeberg.org/forgejo/forgejo/pulls/6834): <!--number 6834 --><!--line 0 --><!--description aTE4bjogdXBkYXRlIG9mIHRyYW5zbGF0aW9ucyBmcm9tIENvZGViZXJnIFRyYW5zbGF0ZQ==-->i18n: update of translations from Codeberg Translate<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6834
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: 0ko <0ko@noreply.codeberg.org>
Co-committed-by: 0ko <0ko@noreply.codeberg.org>
2025-02-08 00:01:24 +00:00
forgejo-backport-action
34d2a8531c [v10.0/forgejo] fix(ui): display verified icon for default gpg key (#6833)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6803

## Description
Thank you for this amazing project!

I recently noticed that the icon next to the GPG key reference appears to be incorrect for commits signed by the default GPG key:

| Default GPG Key  | User GPG Key  |
|---------|---------|
| ![image](/attachments/ff27597a-d38c-48fc-8284-e16d4fd3ea2d) | ![image](/attachments/3c8c5540-dd29-45c9-a9f0-dc3b69677ef3) |

Looking into the commit history of the template file, I noticed that Forgejo-signed commits originally had a distinct icon:
[gitea-unlock-cog](b918609acc) --> [octicon-shield-lock](12ddc48c5c) --> octicon-unverified (current)

Since `octicon-unverified` is also used when a commit cannot be verified (.Verification.Warning), I find it misleading for successfully signed commits. This PR changes the icon to the verified variant for better clarity.

### Tests

1. Set up automatic commit signing by Forgejo ([guide](https://forgejo.org/docs/latest/admin/signing/#automatic-signing))
2. Trigger automatic commit signing in any of the following scenarios:
    - Repository Initialisation (should be the easiest)
    - Wiki Changes
    - CRUD actions using the editor or the API
    - Merges from Pull Requests
3. Open the commit signed by Forgejo
4. Verify that the icon next to the GPG key id is `octicon-verified`:
![image](/attachments/7b4eb81c-d33c-4daf-84dd-9f99ebb0b99d)

### Documentation

- [x] I did not document these changes and I do not expect someone else to do it.

### Release notes

- [x] I want the title to show in the release notes with a link to this pull request.

<!--start release-notes-assistant-->

## Release notes
<!--URL:https://codeberg.org/forgejo/forgejo-->
- User Interface bug fixes
  - [PR](https://codeberg.org/forgejo/forgejo/pulls/6803): <!--number 6803 --><!--line 0 --><!--description Zml4KHVpKTogZGlzcGxheSB2ZXJpZmllZCBpY29uIGZvciBkZWZhdWx0IGdwZyBrZXk=-->fix(ui): display verified icon for default gpg key<!--description-->
<!--end release-notes-assistant-->

Co-authored-by: shgew <shgew@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6833
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Reviewed-by: Beowulf <beowulf@beocode.eu>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-02-07 13:16:23 +00:00
forgejo-backport-action
d260013a51 [v10.0/forgejo] fix: avoid y-axis clipping for branch name (#6832)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6817

- `gt-ellipsis` is set on elements to avoid overflowing its text contents and in the case of overflowing it would show an ellipsis. To force it to not overflow `overflow: hidden` is set, however this also hides the overflow on the y-axis, `overflow-x: hidden` has the same behavior.
- To avoid avoid the branch name from being clipped, add a very small amount of padding on the y-axis. This is a workaround and not a proper solution. There does not seem a good cross-platform solution available to fix this in a proper way.
- Resolves forgejo/forgejo#6811

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6832
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-02-07 10:46:08 +00:00
forgejo-backport-action
3168330425 [v10.0/forgejo] chore(i18n): lint errors (#6809)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6808

settings.hidden_comment_types_description: Rodzaje komentarzy zaznaczone tutaj nie będą wyświetlały się na stronach zgłoszeń. Zaznaczenie "Etykieta" na przykład usunie wszystkie komentarze "<użytkownik> dodał/usunął <etykieta>".
repo.settings.add_web_hook_desc: Zintegruj <a target="_black" rel="noreferrer" href="https://TO-BE-REPLACED.COM">%s</a> ze swoim repozytorium.

Add user & label in Polish.

Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6809
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-02-06 12:37:53 +00:00
forgejo-backport-action
2491bbfa69 [v10.0/forgejo] ci: fix go version check (#6810)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6646

Allow ci go version to be higher than the tool chain. This will fix the current build issues on forgejo branch

Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6810
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-02-06 08:15:36 +00:00
forgejo-backport-action
ac01c7a384 [v10.0/forgejo] fix: make author search case insenstive (#6783)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6782

- Make the author search in the issues and pull request list case
insenstive.
- Background: Forgejo mandates that all columns are case senstive and
only SQLite ignores this for ASCII characters with the `LIKE` operator
any other database will indeed do case senstive searching. Codeberg
recently made all columns case senstive, hence why this issue now surfaces.
- Added integration test.
- Resolves forgejo/forgejo#6744

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6783
Reviewed-by: Beowulf <beowulf@beocode.eu>
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-02-04 17:06:20 +00:00
forgejo-backport-action
b615d41457 [v10.0/forgejo] fix(ui): add triangle down octicon to code search options dropdown (#6770)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6620

This adds the triangle down oction to the code search options dropdown to match the other search option dropdowns (issue, pull).

Co-authored-by: Beowulf <beowulf@beocode.eu>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6770
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Reviewed-by: Otto <otto@codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-02-03 08:35:41 +00:00
0ko
184bdef340 [v10.0/forgejo] i18n: backport of translation updates 6565 and 6665 (#6764)
Translation updates that are applicable to v10 strings were picked from these commits:
* dac7d5e73b
* 7678386138

Changes to strings that are only present in the v11 branch were not picked.

Below is a list of co-authors of the ported commits. It may contain co-authors who's changes were not picked due to being v11-only.

Co-authored-by: 0ko <0ko@users.noreply.translate.codeberg.org>
Co-authored-by: artnay <artnay@users.noreply.translate.codeberg.org>
Co-authored-by: Atul_Eterno <atul_eterno@users.noreply.translate.codeberg.org>
Co-authored-by: Dirk <dirk@users.noreply.translate.codeberg.org>
Co-authored-by: earl-warren <earl-warren@users.noreply.translate.codeberg.org>
Co-authored-by: Edgarsons <edgarsons@users.noreply.translate.codeberg.org>
Co-authored-by: Fjuro <fjuro@alius.cz>
Co-authored-by: Fjuro <fjuro@users.noreply.translate.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-authored-by: Ikuyo Mita <searinminecraft@outlook.ph>
Co-authored-by: jedik <jedik@users.noreply.translate.codeberg.org>
Co-authored-by: Juno Takano <jutty@users.noreply.translate.codeberg.org>
Co-authored-by: justbispo <justbispo@users.noreply.translate.codeberg.org>
Co-authored-by: killawabbit <killawabbit@users.noreply.translate.codeberg.org>
Co-authored-by: Kita Ikuyo <searinminecraft@courvix.com>
Co-authored-by: mahlzahn <mahlzahn@posteo.de>
Co-authored-by: Miguel P.L <miguel_pl@users.noreply.translate.codeberg.org>
Co-authored-by: Outbreak2096 <outbreak2096@users.noreply.translate.codeberg.org>
Co-authored-by: Ricky-Tigg <ricky-tigg@users.noreply.translate.codeberg.org>
Co-authored-by: SomeTr <sometr@users.noreply.translate.codeberg.org>
Co-authored-by: tacaly <frederick@tacaly.com>
Co-authored-by: Wuzzy <wuzzy@disroot.org>
Co-authored-by: xtex <xtexchooser@duck.com>

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6764
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2025-02-02 18:38:07 +00:00
forgejo-backport-action
27276ff26e [v10.0/forgejo] fix: set explore pages to configurable default sort (#6749)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6708

- Currently, the explore/organizations page always defaults to using "newest" as its sort. Instead, use the pre-existing config option (`setting.UI.ExploreDefaultSort`) so server administrators can change the default sort order.

## Checklist

The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).

### Tests

(Sorry, not sure how to add a test for this change)

- I added test coverage for Go changes...
  - [ ] in their respective `*_test.go` for unit tests.
  - [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.

### Documentation

- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.

### Release notes

I don't mind either way.

- [ ] I do not want this change to show in the release notes.
- [x] I want the title to show in the release notes with a link to this pull request.
- [ ] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title.

Co-authored-by: John Moon <john.moon@vts-i.com>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6749
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-31 11:12:01 +00:00
forgejo-backport-action
1b00bf2d26 [v10.0/forgejo] fix: Remove autofocus on the dashboard repository search box (#6748)
- No longer autofocus on the searchbox for the repository list that is on the dashboard. There is no justification for doing so.
- Fixes #6653
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-31 10:40:23 +00:00
forgejo-backport-action
69bc17ea35 [v10.0/forgejo] fix inline file preview for files with encoded URL, fix #5069 (#6739)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6525

### Screenshot
#### Before
See #5069.
#### After
![image](/attachments/d57c2ff8-d29e-41b8-9280-c884ac43f12e)
### Tests

- I added test coverage for Go changes...
  - [x] in their respective `*_test.go` for unit tests.
  - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I added test coverage for JavaScript changes...
  - [ ] in `web_src/js/*.test.js` if it can be unit tested.
  - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)).
- Manual testing: see https://codeberg.org/forgejo/forgejo/pulls/6525#issuecomment-2578814. Thanks @earl-warren.

### Documentation

- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.

### Release notes

- [ ] I do not want this change to show in the release notes.
- [ ] I want the title to show in the release notes with a link to this pull request.
- [ ] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title.

Co-authored-by: Robert Wolff <mahlzahn@posteo.de>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6739
Reviewed-by: Robert Wolff <mahlzahn@posteo.de>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-30 11:49:16 +00:00
forgejo-backport-action
0db9a24a4b [v10.0/forgejo] fix: check for webauthn in 2fa user search (#6730)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6726

- Check for webauthn credentials in the user search when the two factor
filter is enabled.
- Resolves forgejo/forgejo#6524

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6730
Reviewed-by: Otto <otto@codeberg.org>
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-29 19:28:12 +00:00
forgejo-backport-action
4016f2890d [v10.0/forgejo] fix: disallow blame on directories (#6720)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6716

- Don't allow the blame operation on directories.
- Added integration test.
- Resolves forgejo/forgejo#6533

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6720
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-29 09:34:03 +00:00
forgejo-backport-action
c198cb6e65 [v10.0/forgejo] fix(i18n): add forgotten translatable string (#6718)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6701

- Regression of 75ce1e2ac1

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6718
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-29 08:28:25 +00:00
forgejo-backport-action
114d8975b5 [v10.0/forgejo] fix: render issue titles consistently (#6717)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6715

- Render the issue titles in dashboard feed in consistent manner, by using the existing `RenderIssueTitle`.
- Added integration tests (not exhaustive for all comment types, but exhaustive enough for the current code where some comment types are grouped together).
- Resolves forgejo/forgejo#6705

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6717
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-29 08:24:37 +00:00
Michael Kriese
7ee19b4c6c chore: consistent docker image and action references (#6704)
backport of #6703
- replace `code.forgejo.org` ->`data.forgejo.org` on docker images
- add `https://data.forgejo.org/` to actions where missing

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6704
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
Co-committed-by: Michael Kriese <michael.kriese@visualon.de>
2025-01-28 15:46:07 +00:00
Renovate Bot
faa263d54a Update dependency katex to v0.16.21 [SECURITY] (v10.0/forgejo) (#6694)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [katex](https://katex.org) ([source](https://github.com/KaTeX/KaTeX)) | dependencies | patch | [`0.16.18` -> `0.16.21`](https://renovatebot.com/diffs/npm/katex/0.16.18/0.16.21) |

---

> ⚠️ **Warning**
>
> Some dependencies could not be looked up. Check the Dependency Dashboard for more information.

---

### KaTeX \htmlData does not validate attribute names
[CVE-2025-23207](https://nvd.nist.gov/vuln/detail/CVE-2025-23207) / [GHSA-cg87-wmx4-v546](https://github.com/advisories/GHSA-cg87-wmx4-v546)

<details>
<summary>More information</summary>

#### Details
##### Impact
KaTeX users who render untrusted mathematical expressions with `renderToString` could encounter malicious input using `\htmlData` that runs arbitrary JavaScript, or generate invalid HTML.

##### Patches
Upgrade to KaTeX v0.16.21 to remove this vulnerability.

##### Workarounds
- Avoid use of or turn off the `trust` option, or set it to forbid `\htmlData` commands.
- Forbid inputs containing the substring `"\\htmlData"`.
- Sanitize HTML output from KaTeX.

##### Details
`\htmlData` did not validate its attribute name argument, allowing it to generate invalid or malicious HTML that runs scripts.

##### For more information
If you have any questions or comments about this advisory:

- Open an issue or security advisory in the [KaTeX repository](https://github.com/KaTeX/KaTeX/)
- Email us at [katex-security@mit.edu](mailto:katex-security@mit.edu)

#### Severity
- CVSS Score: 6.3 / 10 (Medium)
- Vector String: `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L`

#### References
- [https://github.com/KaTeX/KaTeX/security/advisories/GHSA-cg87-wmx4-v546](https://github.com/KaTeX/KaTeX/security/advisories/GHSA-cg87-wmx4-v546)
- [https://nvd.nist.gov/vuln/detail/CVE-2025-23207](https://nvd.nist.gov/vuln/detail/CVE-2025-23207)
- [ff289955e8)
- [https://github.com/KaTeX/KaTeX](https://github.com/KaTeX/KaTeX)

This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-cg87-wmx4-v546) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)).
</details>

---

### Release Notes

<details>
<summary>KaTeX/KaTeX (katex)</summary>

### [`v0.16.21`](https://github.com/KaTeX/KaTeX/blob/HEAD/CHANGELOG.md#01621-2025-01-17)

[Compare Source](https://github.com/KaTeX/KaTeX/compare/v0.16.20...v0.16.21)

##### Bug Fixes

-   escape \htmlData attribute name ([57914ad](57914ad91e))

### [`v0.16.20`](https://github.com/KaTeX/KaTeX/blob/HEAD/CHANGELOG.md#01620-2025-01-12)

[Compare Source](https://github.com/KaTeX/KaTeX/compare/v0.16.19...v0.16.20)

##### Bug Fixes

-   \providecommand does not overwrite existing macro ([#&#8203;4000](https://github.com/KaTeX/KaTeX/issues/4000)) ([6d30fe4](6d30fe47b0)), closes [#&#8203;3928](https://github.com/KaTeX/KaTeX/issues/3928)

### [`v0.16.19`](https://github.com/KaTeX/KaTeX/blob/HEAD/CHANGELOG.md#01619-2024-12-29)

[Compare Source](https://github.com/KaTeX/KaTeX/compare/v0.16.18...v0.16.19)

##### Bug Fixes

-   **types:** improve `strict` function type ([#&#8203;4009](https://github.com/KaTeX/KaTeX/issues/4009)) ([4228b4e](4228b4eb52))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "" (UTC), Automerge - "* 0-3 * * *" (UTC).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xMzYuMCIsInVwZGF0ZWRJblZlciI6IjM5LjEzNi4xIiwidGFyZ2V0QnJhbmNoIjoidjEwLjAvZm9yZ2VqbyIsImxhYmVscyI6WyJkZXBlbmRlbmN5LXVwZ3JhZGUiLCJ0ZXN0L25vdC1uZWVkZWQiXX0=-->

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6694
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
Co-committed-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
2025-01-28 11:34:32 +00:00
forgejo-backport-action
0ecf28f37f [v10.0/forgejo] Fix inline file preview for rendered files (#6685)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6572

### What?

This fixes the inline file preview for rendered files (e.g., markdown). [Here, a live issue in v11](https://v11.next.forgejo.org/mahlzahn/test-inline-file-preview/issues/1) and [the same in v7 (with even more bugs)](https://v7.next.forgejo.org/mahlzahn/test-inline-file-preview/issues/1).

It fixes
1. the inline preview for possibly rendered files, when the link is specified with `?display=source`. This happens, e.g., if you are watching a (e.g., markdown) file in source and then want to link some of its lines.
2. the link to the source file inside the inline preview for possible rendered files (currently it links to the rendered version and then the `#L…` cannot point to the correct lines). This is done by always adding `?display=source` to the link.

### Screenshots
<details><summary>

#### Before

</summary>

![image](/attachments/898f82d5-d116-465a-89e2-ed83da189762)

</details>
<details><summary>

#### After

</summary>

![image](/attachments/41058620-47f3-4f6a-b427-66ef33c1a07f)

</details>

### Tests

- I added test coverage for Go changes...
  - [x] in their respective `*_test.go` for unit tests.
  - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I added test coverage for JavaScript changes...
  - [ ] in `web_src/js/*.test.js` if it can be unit tested.
  - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)).

I think that this minor edit does not need special tests. Some backend tests have been updated to reflect the addition of URL parameters.

#### Manual testing
- create a repository with a file that can be rendered with couple of lines inside, e.g., a markdown README.md
- go to the source of this file (e.g., `…/src/branch/main/README.md`)
- click on the `<> View Source` button (or add `?display=source` to the URL)
- click on one of the lines, then on the three dots, then on ”Reference in a new issue“
- continue creating the issue

### Documentation

- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.

### Release notes

- [ ] I do not want this change to show in the release notes.
- [ ] I want the title to show in the release notes with a link to this pull request.
- [ ] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title.

Co-authored-by: Robert Wolff <mahlzahn@posteo.de>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6685
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-25 11:38:02 +00:00
forgejo-backport-action
d10034f4d8 [v10.0/forgejo] fix: add non allowed domain translation (#6684)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6677

- Was added in 2559c80bec and accidentally removed in 5a16c9d9c0.
- Reworded for clarity.
- Resolves #6661

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6684
Reviewed-by: Otto <otto@codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-25 01:15:27 +00:00
forgejo-backport-action
553fc3cc42 [v10.0/forgejo] fix: load settings for valid user and email check (#6678)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6674

- The doctor commands to check the validity of existing usernames and
email addresses depend on functionality that have configurable behavior
depending on the values of the `[service]` settings, so load them when
running the doctor command.
- Resolves #6664
- No unit test due to the architecture of doctor commands.

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6678
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-24 12:25:00 +00:00
Earl Warren
6d7bf7369d [v10.0/forgejo] chore(security): update security.txt with new expiration date (#6668)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6668
2025-01-23 17:28:46 +00:00
Earl Warren
eb83b05430 chore(security): update security.txt with new expiration date
Same as https://forgejo.org/.well-known/security.txt

(cherry picked from commit 955f99b6a4)
2025-01-23 16:20:44 +00:00
forgejo-backport-action
61e345cd36 [v10.0/forgejo] fix: teach the doctor about orphaned two_factor rows (#6651)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6639

If a row in the two_factor table references a non existent user, it may contain a secret that has an invalid format. Such an orphaned row is never used and should be removed.

Improve the error message to suggest using the doctor to remove it.

Fixes: https://codeberg.org/forgejo/forgejo/issues/6637

## Testing

- make TAGS='sqlite sqlite_unlock_notify' watch
- make TAGS='sqlite  sqlite_unlock_notify' forgejo
- sqlite3 data/gitea.db 'INSERT INTO two_factor VALUES( 0, 500, "", "", "", "", 0, 0)'
- ./forgejo doctor check --run check-db-consistency
  ```
   [1] Check consistency of database
    - [W] Found 1 Orphaned TwoFactor without existing User
   OK

   All done (checks: 1).
   ```
-  ./forgejo doctor check --run check-db-consistency --fix
   ```
   [1] Check consistency of database
    - [I] Deleted 1 Orphaned TwoFactor without existing User
   OK

   All done (checks: 1).
   ```

## Checklist

The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).

### Tests

- I added test coverage for Go changes...
  - [ ] in their respective `*_test.go` for unit tests.
  - [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I added test coverage for JavaScript changes...
  - [ ] in `web_src/js/*.test.js` if it can be unit tested.
  - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)).

### Documentation

- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.

### Release notes

- [ ] I do not want this change to show in the release notes.
- [x] I want the title to show in the release notes with a link to this pull request.
- [ ] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title.

<!--start release-notes-assistant-->

## Release notes
<!--URL:https://codeberg.org/forgejo/forgejo-->
- Bug fixes
  - [PR](https://codeberg.org/forgejo/forgejo/pulls/6651): <!--number 6651 --><!--line 0 --><!--description Zml4OiB0ZWFjaCB0aGUgZG9jdG9yIGFib3V0IG9ycGhhbmVkIHR3b19mYWN0b3Igcm93cw==-->fix: teach the doctor about orphaned two_factor rows<!--description-->
<!--end release-notes-assistant-->

Co-authored-by: Earl Warren <contact@earl-warren.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6651
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-22 07:47:34 +00:00
forgejo-backport-action
5c5e1c87ba [v10.0/forgejo] fix: listing tokens must not require basic auth (#6643)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6633

When the change is reverted, the test fails as follows:

```sh
=== TestAPIGetTokens (tests/integration/api_token_test.go:34)
--- FAIL: TestAPIGetTokens (0.17s)
    testlogger.go:405: 2025/01/20 14:05:22 ...les/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /home/earl-warren/software/forgejo/tests/gitea-lfs-meta
    testlogger.go:405: 2025/01/20 14:05:22 ...eb/routing/logger.go:102:func1() [I] router: completed GET /api/v1/users/user2/tokens for test-mock:12345, 200 OK in 2.5ms @ user/app.go:24(user.ListAccessTokens)
    testlogger.go:405: 2025/01/20 14:05:22 ...eb/routing/logger.go:102:func1() [I] router: completed POST /api/v1/users/user1/tokens for test-mock:12345, 201 Created in 4.7ms @ user/app.go:75(user.CreateAccessToken)
    testlogger.go:405: 2025/01/20 14:05:22 ...eb/routing/logger.go:102:func1() [I] router: completed GET /api/v1/users/user2/tokens for test-mock:12345, 401 Unauthorized in 4.9ms @ v1/api.go:413(v1.Routes.func2.5.1.reqBasicOrRevProxyAuth.6)
    api_token_test.go:46:
        	Error Trace:	/home/earl-warren/software/forgejo/tests/integration/integration_test.go:556
        	            				/home/earl-warren/software/forgejo/tests/integration/api_token_test.go:46
        	Error:      	Not equal:
        	            	expected: 200
        	            	actual  : 401
        	Test:       	TestAPIGetTokens
        	Messages:   	Request: GET /api/v1/users/user2/tokens
    api_token_test.go:46: Response:  {"message":"auth required","url":"http://localhost:3003/api/swagger"}

    testlogger.go:405: 2025/01/20 14:05:22 ...eb/routing/logger.go:102:func1() [I] router: completed DELETE /api/v1/users/user1/tokens/94 for test-mock:12345, 204 No Content in 1.4ms @ user/app.go:145(user.DeleteAccessToken)
```

## Checklist

The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).

### Tests

- I added test coverage for Go changes...
  - [ ] in their respective `*_test.go` for unit tests.
  - [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I added test coverage for JavaScript changes...
  - [ ] in `web_src/js/*.test.js` if it can be unit tested.
  - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)).

### Documentation

- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.

### Release notes

- [x] I do not want this change to show in the release notes.
- [ ] I want the title to show in the release notes with a link to this pull request.
- [ ] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title.

<!--start release-notes-assistant-->

## Release notes
<!--URL:https://codeberg.org/forgejo/forgejo-->
- Bug fixes
  - [PR](https://codeberg.org/forgejo/forgejo/pulls/6633): <!--number 6633 --><!--line 0 --><!--description bGlzdGluZyB0b2tlbnMgbXVzdCBub3QgcmVxdWlyZSBiYXNpYyBhdXRo-->listing tokens must not require basic auth<!--description-->
<!--end release-notes-assistant-->

Co-authored-by: Earl Warren <contact@earl-warren.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6643
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-21 10:40:00 +00:00
Renovate Bot
7546c4acf3 Update dependency go to v1.23.5 (v10.0/forgejo) (#6644)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [go](https://go.dev/) ([source](https://github.com/golang/go)) | toolchain | patch | `1.23.4` -> `1.23.5` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - "* 0-3 * * *" (UTC).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xMDYuMCIsInVwZGF0ZWRJblZlciI6IjM5LjEwNi4wIiwidGFyZ2V0QnJhbmNoIjoidjEwLjAvZm9yZ2VqbyIsImxhYmVscyI6WyJkZXBlbmRlbmN5LXVwZ3JhZGUiLCJ0ZXN0L25vdC1uZWVkZWQiXX0=-->

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6644
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
Co-committed-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
2025-01-21 09:32:40 +00:00
Otto
25e81d05f0 [v10.0/forgejo] Fix mention and emoji expansion & Improve leaving list completion (#6632)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6632
Reviewed-by: Beowulf <beowulf@beocode.eu>
2025-01-20 20:34:31 +00:00
forgejo-backport-action
054537989f [v10.0/forgejo] fix(ui): prevent overflow of branch selector in commit graph (#6636)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6617

Fix that the branch selector in the commit graph can overflow

| Previous | Now |
| :----: | :----: |
| ![grafik](/attachments/ab303490-2abc-46d8-8715-0750886fd111) | ![grafik](/attachments/63f919a9-bcc2-4969-8c8c-d265c1917e07) |
| ![grafik](/attachments/c0e6636f-52eb-4bf0-bf07-0139ec407e33) | ![grafik](/attachments/752aef87-9250-4bf6-b74a-5a1813394dbe) |
| ![grafik](/attachments/e61842dd-29c1-4517-86db-f068de9ff6e8) | ![grafik](/attachments/bf251b43-80fa-4e1a-9fbe-fd27e5f8d195) |

Fixes #6615

Co-authored-by: Beowulf <beowulf@beocode.eu>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6636
Reviewed-by: Otto <otto@codeberg.org>
Reviewed-by: Beowulf <beowulf@beocode.eu>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-20 20:28:39 +00:00
Beowulf
348e0e1fac Leave list/quote expanison with double enter
When editing a list or similar syntax elements, pressing enter starts a
new line with the line introducer (e.g. `- ` for a plain list).
But currently it's uncomfortable when someone wants to leave the list.
Pressing enter again simply adds more and more lines with the prefix.

With this change the list is terminated if enter is pressed on a line
which contains the introducer but nothing else. This behavior is known
from other markdown editors like the on used by GitLab or GitHub.

Additionally I changed the regex for detecting a prefix.
- Why: With the change you can add a single whitespace at the end if you
  want to keep an "empty" line. So if you want to write:
  ```
  - First
  -
  - Third
  ```
  You just need to add a whitespace in the second line to prevent that
  the prefix will be removed.
- Changes in detail:
  - ordered bullet list prefix detection:
    nothing changed
  - todo list and unordered list prefix detection:
    have been split up:
    - todo list: Changed that only 1 to 4 whitespaces can be between the
      list char (`-`,`*`,`+`) and the checkbox (`[ ]`,`[x]`) - Why? If
      more then 4 spaces are between the list char and the checkbox,
      this is no longer detected as a prefix for a todo item based on
      the markdown standard. Due to the amount of spaces it is instead
      parsed as code.
    - unordered list: The prefix now needs to have exactly one space
      after the list char (`-`,`*`,`+`). More spaces will not be taken
      into account for detecting the prefix.
  - quote prefix detection:
    nothing changed

The current e2e-tests where simplified and duplicated tests where
removed. Test cases for the new functionality where added.

(cherry picked from commit 7ea62c5ce4)
2025-01-20 12:52:20 +00:00
Beowulf
627634a76e Prevent prefix continuation if currently a text expander popup is open
This fixes that mentions and emoji autocompletion was broken in e.g. a
list, because the list handling take presidency over the text expansion.

(cherry picked from commit 276ef10dd5)
2025-01-20 12:52:20 +00:00
forgejo-backport-action
28db11f2e7 [v10.0/forgejo] fix(ui): hide git note add button for commit if commit already has a note (#6614)
Backport: https://codeberg.org/forgejo/forgejo/pulls/6613

Regression from f5c0570533

Co-authored-by: Beowulf <beowulf@beocode.eu>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6614
Reviewed-by: Beowulf <beowulf@beocode.eu>
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-18 19:43:08 +00:00
forgejo-backport-action
6d0bf55f05 [v10.0/forgejo] fix: Reset content of comment edit field on cancel (#6601)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6595

Currently, the content of the text field is not reset when you cancel editing. This change resets the content of the text field when editing is canceled.

If this is not done and you click on cancel and then on edit again, you can no longer return to the initial content without completely reloading the page.

Co-authored-by: Beowulf <beowulf@beocode.eu>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6601
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Reviewed-by: Beowulf <beowulf@beocode.eu>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-17 20:48:35 +00:00
forgejo-backport-action
2d1e163913 [v10.0/forgejo] fix: reduce noise for the v303 migration (#6594)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6591

Using SELECT `%s` FROM `%s` WHERE 0 = 1 to assert the existence of a column is simple but noisy: it shows errors in the migrations that are confusing for Forgejo admins because they are not actual errors.

Use introspection instead, which is more complicated but leads to the same result.

Add a test that ensures it works as expected, for all database types. Although the migration is run for all database types, it does not account for various scenarios and is never tested in the case a column does not exist.

Refs: https://codeberg.org/forgejo/forgejo/issues/6583

Co-authored-by: Earl Warren <contact@earl-warren.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6594
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-17 08:15:16 +00:00
forgejo-backport-action
26b7c6b86a [v10.0/forgejo] tests(e2e): Various fixes to visual testing (#6587)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6569

Co-authored-by: Otto Richter <git@otto.splvs.net>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6587
Reviewed-by: Otto <otto@codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-17 01:07:22 +00:00
forgejo-backport-action
05056b8aa2 [v10.0/forgejo] Refactor e2e tests to simplify authentication setup (#6585)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6400

Replaced manual login and context loading across tests with Playwright's `test.use` configuration for user authentication. This simplifies test setup, improves readability, and reduces repetition.

#6362 first part

## Checklist

The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).

### Tests

- I added test coverage for Go changes...
  - [ ] in their respective `*_test.go` for unit tests.
  - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I added test coverage for JavaScript changes...
  - [ ] in `web_src/js/*.test.js` if it can be unit tested.
  - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)).

### Documentation

- [x] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [ ] I did not document these changes and I do not expect someone else to do it.

### Release notes

- [x] I do not want this change to show in the release notes.
- [ ] I want the title to show in the release notes with a link to this pull request.
- [ ] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title.

Co-authored-by: Julian Schlarb <julian.schlarb@denktmit.de>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6585
Reviewed-by: Otto <otto@codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-16 13:37:06 +00:00
forgejo-backport-action
39843ee2b3 [v10.0/forgejo] fix: avoid Gitea migration warnings (take 2) (#6578)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6577

274bc480b4 introduced a regression in https://codeberg.org/forgejo/forgejo/pulls/6343

Trying to remove fields that have already been removed by

dd1523c72e/models/forgejo_migrations/v14.go

Is a noop for SQLite and went undetected by the upgrade tests.

Fixes: https://codeberg.org/forgejo/forgejo/issues/6575
Co-authored-by: Earl Warren <contact@earl-warren.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6578
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-15 22:48:56 +00:00
Earl Warren
3b7ed0cda2 [v10.0/forgejo] chore(ci): upgrade forgejo-build-publish/build@v5.3.1 (#6574)
**Backport**: https://codeberg.org/forgejo/forgejo/pulls/6573

So that it does not use docker.io

(cherry picked from commit 69ce414f7e)

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6574
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-committed-by: Earl Warren <contact@earl-warren.org>
2025-01-15 21:36:53 +00:00
Renovate Bot
2b1e74a76f Update module github.com/alecthomas/chroma/v2 to v2.15.0 (v10.0/forgejo) (#6553)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [github.com/alecthomas/chroma/v2](https://github.com/alecthomas/chroma) | require | minor | `v2.14.0` -> `v2.15.0` |

---

### Release Notes

<details>
<summary>alecthomas/chroma (github.com/alecthomas/chroma/v2)</summary>

### [`v2.15.0`](https://github.com/alecthomas/chroma/releases/tag/v2.15.0)

[Compare Source](https://github.com/alecthomas/chroma/compare/v2.14.0...v2.15.0)

#### What's Changed

-   AQL: Add builtin functions introduced in v3.12 by [@&#8203;Simran-B](https://github.com/Simran-B) in https://github.com/alecthomas/chroma/pull/968
-   chore(styles): add evergarden inspired style by [@&#8203;comfysage](https://github.com/comfysage) in https://github.com/alecthomas/chroma/pull/970
-   chore(deps): update dependency svu to v2 by [@&#8203;renovate](https://github.com/renovate) in https://github.com/alecthomas/chroma/pull/971
-   chore(deps): update dependency watchexec to v2 by [@&#8203;renovate](https://github.com/renovate) in https://github.com/alecthomas/chroma/pull/962
-   chore(deps): update all non-major dependencies by [@&#8203;renovate](https://github.com/renovate) in https://github.com/alecthomas/chroma/pull/955
-   styles: Fix Gleam alias by [@&#8203;jmooring](https://github.com/jmooring) in https://github.com/alecthomas/chroma/pull/973
-   chore(deps): update all non-major dependencies by [@&#8203;renovate](https://github.com/renovate) in https://github.com/alecthomas/chroma/pull/974
-   chore(deps): update dependency python3 to v3.12.3 by [@&#8203;renovate](https://github.com/renovate) in https://github.com/alecthomas/chroma/pull/976
-   added the nordic theme via chroma/styles/nordic.xml by [@&#8203;avih7531](https://github.com/avih7531) in https://github.com/alecthomas/chroma/pull/977
-   Update the Materialize lexer by [@&#8203;arusahni](https://github.com/arusahni) in https://github.com/alecthomas/chroma/pull/978
-   feat(lexers/hare): add done keyword by [@&#8203;wackbyte](https://github.com/wackbyte) in https://github.com/alecthomas/chroma/pull/979
-   pygments2chroma: escape regex.words by [@&#8203;oliverpool](https://github.com/oliverpool) in https://github.com/alecthomas/chroma/pull/982
-   chore(deps): update all non-major dependencies by [@&#8203;renovate](https://github.com/renovate) in https://github.com/alecthomas/chroma/pull/981
-   Add JSONata Lexer by [@&#8203;DevDimov](https://github.com/DevDimov) in https://github.com/alecthomas/chroma/pull/983
-   Go lexer: single line comment without consuming endline, disable EnsureNL by [@&#8203;msorc](https://github.com/msorc) in https://github.com/alecthomas/chroma/pull/984
-   Update the Materialize lexer by [@&#8203;arusahni](https://github.com/arusahni) in https://github.com/alecthomas/chroma/pull/987
-   chore(deps): update all non-major dependencies by [@&#8203;renovate](https://github.com/renovate) in https://github.com/alecthomas/chroma/pull/985
-   Add Gleam to README by [@&#8203;Nicd](https://github.com/Nicd) in https://github.com/alecthomas/chroma/pull/990
-   Port Minecraft lexers from Pygments by [@&#8203;kofuk](https://github.com/kofuk) in https://github.com/alecthomas/chroma/pull/992
-   Don't output extra whitespace in YAML multiline by [@&#8203;Gusted](https://github.com/Gusted) in https://github.com/alecthomas/chroma/pull/993
-   chore(deps): update all non-major dependencies by [@&#8203;renovate](https://github.com/renovate) in https://github.com/alecthomas/chroma/pull/991
-   add beef syntax and tests by [@&#8203;Booklordofthedings](https://github.com/Booklordofthedings) in https://github.com/alecthomas/chroma/pull/995
-   Update GitHub light color palette by [@&#8203;konradreiche](https://github.com/konradreiche) in https://github.com/alecthomas/chroma/pull/998
-   chore(deps): update module github.com/alecthomas/kong to v1 by [@&#8203;renovate](https://github.com/renovate) in https://github.com/alecthomas/chroma/pull/999
-   Update the Materialize lexer by [@&#8203;arusahni](https://github.com/arusahni) in https://github.com/alecthomas/chroma/pull/1001
-   Update TypeScript lexer to allow nested generics by [@&#8203;fredrare](https://github.com/fredrare) in https://github.com/alecthomas/chroma/pull/1002
-   Pager friendly terminal formatting by [@&#8203;walles](https://github.com/walles) in https://github.com/alecthomas/chroma/pull/1006
-   chore(deps): update all non-major dependencies by [@&#8203;renovate](https://github.com/renovate) in https://github.com/alecthomas/chroma/pull/997
-   Add Typst Lexer by [@&#8203;oliverpool](https://github.com/oliverpool) in https://github.com/alecthomas/chroma/pull/1007
-   Add Jsonnet Lexer by [@&#8203;jolheiser](https://github.com/jolheiser) in https://github.com/alecthomas/chroma/pull/1011
-   fix: add underscore parsing in numbers for haskell by [@&#8203;Gusted](https://github.com/Gusted) in https://github.com/alecthomas/chroma/pull/1020
-   Add CSV lexer by [@&#8203;walles](https://github.com/walles) in https://github.com/alecthomas/chroma/pull/1005
-   fix(typescript): highlight string literal type parameters by [@&#8203;SKalt](https://github.com/SKalt) in https://github.com/alecthomas/chroma/pull/1010
-   add any as a builtin type for go by [@&#8203;quartercastle](https://github.com/quartercastle) in https://github.com/alecthomas/chroma/pull/1021
-   chore(deps): update all non-major dependencies by [@&#8203;renovate](https://github.com/renovate) in https://github.com/alecthomas/chroma/pull/1013
-   Remove whitespace tokenizing rule in markdown lexer by [@&#8203;cloudchamb3r](https://github.com/cloudchamb3r) in https://github.com/alecthomas/chroma/pull/1008
-   feat(JSON): support `.jsonc` extension by [@&#8203;CarterLi](https://github.com/CarterLi) in https://github.com/alecthomas/chroma/pull/1022
-   Add Eclipse ATL language (https://eclipse.dev/atl/) by [@&#8203;dwagelaar](https://github.com/dwagelaar) in https://github.com/alecthomas/chroma/pull/1024
-   Import NSIS Lexer from Pygments by [@&#8203;JakobDev](https://github.com/JakobDev) in https://github.com/alecthomas/chroma/pull/1026
-   chore(deps): update module github.com/alecthomas/kong to v1.5.1 by [@&#8203;renovate](https://github.com/renovate) in https://github.com/alecthomas/chroma/pull/1025
-   fix(nix): nix lexor missing '=' operator by [@&#8203;FlyingStitchman](https://github.com/FlyingStitchman) in https://github.com/alecthomas/chroma/pull/1031
-   Add WebVTT lexer ([#&#8203;707](https://github.com/alecthomas/chroma/issues/707)) by [@&#8203;dschuessler](https://github.com/dschuessler) in https://github.com/alecthomas/chroma/pull/1032

#### New Contributors

-   [@&#8203;comfysage](https://github.com/comfysage) made their first contribution in https://github.com/alecthomas/chroma/pull/970
-   [@&#8203;avih7531](https://github.com/avih7531) made their first contribution in https://github.com/alecthomas/chroma/pull/977
-   [@&#8203;wackbyte](https://github.com/wackbyte) made their first contribution in https://github.com/alecthomas/chroma/pull/979
-   [@&#8203;oliverpool](https://github.com/oliverpool) made their first contribution in https://github.com/alecthomas/chroma/pull/982
-   [@&#8203;DevDimov](https://github.com/DevDimov) made their first contribution in https://github.com/alecthomas/chroma/pull/983
-   [@&#8203;msorc](https://github.com/msorc) made their first contribution in https://github.com/alecthomas/chroma/pull/984
-   [@&#8203;Nicd](https://github.com/Nicd) made their first contribution in https://github.com/alecthomas/chroma/pull/990
-   [@&#8203;Booklordofthedings](https://github.com/Booklordofthedings) made their first contribution in https://github.com/alecthomas/chroma/pull/995
-   [@&#8203;konradreiche](https://github.com/konradreiche) made their first contribution in https://github.com/alecthomas/chroma/pull/998
-   [@&#8203;fredrare](https://github.com/fredrare) made their first contribution in https://github.com/alecthomas/chroma/pull/1002
-   [@&#8203;SKalt](https://github.com/SKalt) made their first contribution in https://github.com/alecthomas/chroma/pull/1010
-   [@&#8203;quartercastle](https://github.com/quartercastle) made their first contribution in https://github.com/alecthomas/chroma/pull/1021
-   [@&#8203;cloudchamb3r](https://github.com/cloudchamb3r) made their first contribution in https://github.com/alecthomas/chroma/pull/1008
-   [@&#8203;CarterLi](https://github.com/CarterLi) made their first contribution in https://github.com/alecthomas/chroma/pull/1022
-   [@&#8203;dwagelaar](https://github.com/dwagelaar) made their first contribution in https://github.com/alecthomas/chroma/pull/1024
-   [@&#8203;FlyingStitchman](https://github.com/FlyingStitchman) made their first contribution in https://github.com/alecthomas/chroma/pull/1031
-   [@&#8203;dschuessler](https://github.com/dschuessler) made their first contribution in https://github.com/alecthomas/chroma/pull/1032

**Full Changelog**: https://github.com/alecthomas/chroma/compare/v2.14.0...v2.15.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - "* 0-3 * * *" (UTC).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xMDYuMCIsInVwZGF0ZWRJblZlciI6IjM5LjEwNi4wIiwidGFyZ2V0QnJhbmNoIjoidjEwLjAvZm9yZ2VqbyIsImxhYmVscyI6WyJkZXBlbmRlbmN5LXVwZ3JhZGUiLCJ0ZXN0L25vdC1uZWVkZWQiXX0=-->

Co-authored-by: viceice <michael.kriese@gmx.de>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6553
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
Co-committed-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
2025-01-14 21:40:06 +00:00
0ko
c439e26c33 i18n: update of translations from Codeberg Translate (#6566)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6566
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2025-01-14 07:48:07 +00:00
0ko
317559fdd9 i18n: update of translations from Codeberg Translate
Backport: https://codeberg.org/forgejo/forgejo/issues/6515

Co-authored-by: 0ko <0ko@users.noreply.translate.codeberg.org>
Co-authored-by: Edgarsons <edgarsons@users.noreply.translate.codeberg.org>
Co-authored-by: div72 <div72@users.noreply.translate.codeberg.org>
Co-authored-by: tkbremnes <tkbremnes@users.noreply.translate.codeberg.org>
Co-authored-by: artnay <artnay@users.noreply.translate.codeberg.org>
Co-authored-by: Outbreak2096 <outbreak2096@users.noreply.translate.codeberg.org>
Co-authored-by: Protestant <protestant@users.noreply.translate.codeberg.org>
Co-authored-by: micash <micash@users.noreply.translate.codeberg.org>
Co-authored-by: Ikuyo Mita <ikuyo@users.noreply.translate.codeberg.org>
Co-authored-by: tacaly <frederick@tacaly.com>
Co-authored-by: burakozaydin <burakozaydin@users.noreply.translate.codeberg.org>
Co-authored-by: kdh8219 <kdh8219@monamo.dev>
Co-authored-by: Juno Takano <jutty@users.noreply.translate.codeberg.org>
Co-authored-by: earl-warren <earl-warren@users.noreply.translate.codeberg.org>
Co-authored-by: justbispo <justbispo@users.noreply.translate.codeberg.org>

(semi-automatically picked from commit d717c78ea0)
2025-01-14 11:57:02 +05:00
forgejo-backport-action
b88cd0c111 [v10.0/forgejo] port(gitea#31954): Add lock for parallel maven upload (#6517)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6513

Backport #31851
Fix #30171

---

Fixes https://github.com/go-gitea/gitea/issues/30171, this is also a
issue in Forgejo. Backport the implementation that uses the existing
sync module which does not work for multiple instances which is
perfectly fine for Forgejo for now.

(cherry picked from commit 9c990ac043a0167dc59f1c822988ed2316f7c1df)

Co-authored-by: Gusted <gusted@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6517
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-09 18:10:54 +00:00
0ko
5326183693 [v10.0/forgejo] i18n: update of translations from Codeberg Translate (#6514)
Backport: https://codeberg.org/forgejo/forgejo/pulls/6451

Co-authored-by: earl-warren <earl-warren@users.noreply.translate.codeberg.org>
Co-authored-by: Edgarsons <edgarsons@users.noreply.translate.codeberg.org>
Co-authored-by: 0ko <0ko@users.noreply.translate.codeberg.org>
Co-authored-by: div72 <div72@users.noreply.translate.codeberg.org>
Co-authored-by: Outbreak2096 <outbreak2096@users.noreply.translate.codeberg.org>
Co-authored-by: Salif Mehmed <mail@salif.eu>
Co-authored-by: tacaly <frederick@tacaly.com>
Co-authored-by: revi <yewon@revi.email>
Co-authored-by: lordwektabyte <lordwektabyte@users.noreply.translate.codeberg.org>
Co-authored-by: xtex <xtexchooser@duck.com>
Co-authored-by: artnay <artnay@users.noreply.translate.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-authored-by: Juno Takano <jutty@users.noreply.translate.codeberg.org>
Co-authored-by: justbispo <justbispo@users.noreply.translate.codeberg.org>
Co-authored-by: Atalanttore <atalanttore@users.noreply.translate.codeberg.org>
Co-authored-by: SomeTr <sometr@users.noreply.translate.codeberg.org>
Co-authored-by: Benedikt Straub <benedikt-straub@web.de>
Co-authored-by: Fjuro <fjuro@alius.cz>
Co-authored-by: banaanihillo <banaanihillo@users.noreply.translate.codeberg.org>
Co-authored-by: emansije <emansije@users.noreply.translate.codeberg.org>
Co-authored-by: Caesar Schinas <caesar@caesarschinas.com>
Co-authored-by: Marti <marti@users.noreply.translate.codeberg.org>
Co-authored-by: mahlzahn <mahlzahn@posteo.de>

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6514
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2025-01-09 08:57:11 +00:00
Earl Warren
5b6e0ca99c [v10.0/forgejo] fix: upgrade gof3 package and driver (#6493)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6493
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2025-01-07 21:31:55 +00:00
Earl Warren
90730e83ba fix: upgrade gof3 version
(cherry picked from commit 7189da15f2)
2025-01-07 20:52:48 +00:00
limiting-factor
775770ad81 fix: f3: label color must start with #
(cherry picked from commit 604c21ffd7)
2025-01-07 20:52:48 +00:00
limiting-factor
4eb7e0fe08 fix: f3: update milestone is_closed & deadline_unix
(cherry picked from commit 63204e8edf)
2025-01-07 20:52:48 +00:00
limiting-factor
597d806753 fix: f3: update issue is_locked
(cherry picked from commit 946b77115e)
2025-01-07 20:52:48 +00:00
limiting-factor
2b6a4137d5 fix: f3: update issue labels
(cherry picked from commit 168c1d806b)
2025-01-07 20:52:48 +00:00
limiting-factor
35266133d8 fix: f3: update issue assignees
The ID must be obtained from the repository ID and the index,
otherwise it is zero and the assignees are not updated.

(cherry picked from commit d8f71b513c)
2025-01-07 20:52:48 +00:00
limiting-factor
dab3121c65 fix: f3: support modify milestone
(cherry picked from commit 16564fd9e8)
2025-01-07 20:52:48 +00:00
Renovate Bot
3ce1a6562d Update module github.com/go-git/go-git/v5 to v5.13.1 (v10.0/forgejo) (#6496)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) | require | minor | `v5.11.0` -> `v5.13.1` |

---

### Release Notes

<details>
<summary>go-git/go-git (github.com/go-git/go-git/v5)</summary>

### [`v5.13.1`](https://github.com/go-git/go-git/releases/tag/v5.13.1)

[Compare Source](https://github.com/go-git/go-git/compare/v5.13.0...v5.13.1)

#### What's Changed

-   build: bump github.com/go-git/go-billy/v5 from 5.6.0 to 5.6.1 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1327
-   build: bump github.com/elazarl/goproxy from 1.2.1 to 1.2.2 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1329
-   build: bump github.com/elazarl/goproxy from 1.2.2 to 1.2.3 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1340
-   Revert "plumbing: transport/ssh, Add support for SSH [@&#8203;cert-authority](https://github.com/cert-authority)." by [@&#8203;pjbgf](https://github.com/pjbgf) in [#&#8203;1346](https://github.com/go-git/go-git/issues/1346)

**Full Changelog**: https://github.com/go-git/go-git/compare/v5.13.0...v5.13.1

### [`v5.13.0`](https://github.com/go-git/go-git/releases/tag/v5.13.0)

[Compare Source](https://github.com/go-git/go-git/compare/v5.12.0...v5.13.0)

#### What's Changed

-   build: bump github.com/go-git/go-git/v5 from 5.11.0 to 5.12.0 in /cli/go-git by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1065
-   build: bump golang.org/x/net from 0.22.0 to 0.23.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1068
-   build: bump golang.org/x/net from 0.23.0 to 0.24.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1071
-   Properly support skipping of non-mandatory extensions  by [@&#8203;codablock](https://github.com/codablock) in https://github.com/go-git/go-git/pull/1066
-   git: Refine some codes in test and non-test. by [@&#8203;onee-only](https://github.com/onee-only) in https://github.com/go-git/go-git/pull/1077
-   plumbing: protocol/packp, client-side filter capability support by [@&#8203;edigaryev](https://github.com/edigaryev) in https://github.com/go-git/go-git/pull/1000
-   build: bump golang.org/x/net from 0.22.0 to 0.23.0 in /cli/go-git by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1078
-   plumbing: fix sideband demux on flush by [@&#8203;aymanbagabas](https://github.com/aymanbagabas) in https://github.com/go-git/go-git/pull/1084
-   storage: dotgit, head reference usually comes first by [@&#8203;aymanbagabas](https://github.com/aymanbagabas) in https://github.com/go-git/go-git/pull/1085
-   build: bump golang.org/x/text from 0.14.0 to 0.15.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1091
-   build: bump golang.org/x/crypto from 0.22.0 to 0.23.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1094
-   build: bump golang.org/x/net from 0.24.0 to 0.25.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1093
-   git: Added an example for Repository.Branches by [@&#8203;johnmatthiggins](https://github.com/johnmatthiggins) in https://github.com/go-git/go-git/pull/1088
-   git: worktree_commit, Modify checking empty commit. Fixes [#&#8203;723](https://github.com/go-git/go-git/issues/723) by [@&#8203;onee-only](https://github.com/onee-only) in https://github.com/go-git/go-git/pull/1050
-   plumbing: transport/http, Wrap http errors to return reason. Fixes [#&#8203;1097](https://github.com/go-git/go-git/issues/1097) by [@&#8203;ggambetti](https://github.com/ggambetti) in https://github.com/go-git/go-git/pull/1100
-   build: bump golang.org/x/sys from 0.20.0 to 0.21.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1106
-   build: bump golang.org/x/text from 0.15.0 to 0.16.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1107
-   Bumps Go versions and go-billy by [@&#8203;pjbgf](https://github.com/pjbgf) in https://github.com/go-git/go-git/pull/1056
-   \_examples: Fixed a dead link COMPATIBILITY.md by [@&#8203;gecko655](https://github.com/gecko655) in https://github.com/go-git/go-git/pull/1109
-   build: bump github.com/jessevdk/go-flags from 1.5.0 to 1.6.1 in /cli/go-git by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1115
-   build: bump github.com/elazarl/goproxy from v0.0.0-20230808193330-2592e75ae04a to v0.0.0-20240618083138-03be62527ccb by [@&#8203;hbelmiro](https://github.com/hbelmiro) in https://github.com/go-git/go-git/pull/1124
-   build: bump golang.org/x/net from 0.25.0 to 0.26.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1104
-   Add option approximating `git clean -x` flag. by [@&#8203;msuozzo](https://github.com/msuozzo) in https://github.com/go-git/go-git/pull/995
-   Revert "Add option approximating `git clean -x` flag." by [@&#8203;pjbgf](https://github.com/pjbgf) in https://github.com/go-git/go-git/pull/1129
-   Fix reference updated concurrently error for the filesystem storer by [@&#8203;Javier-varez](https://github.com/Javier-varez) in https://github.com/go-git/go-git/pull/1116
-   build: bump golang.org/x/net from 0.26.0 to 0.27.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1134
-   utils: merkletrie, Align error message with upstream by [@&#8203;pjbgf](https://github.com/pjbgf) in https://github.com/go-git/go-git/pull/1142
-   plumbing: transport/file, Change paths to absolute by [@&#8203;pjbgf](https://github.com/pjbgf) in https://github.com/go-git/go-git/pull/1141
-   plumbing: gitignore, Fix loading of ignored .gitignore files. by [@&#8203;Achilleshiel](https://github.com/Achilleshiel) in https://github.com/go-git/go-git/pull/1114
-   build: bump github.com/skeema/knownhosts from 1.2.2 to 1.3.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1147
-   plumbing: transport/ssh, Add support for SSH [@&#8203;cert-authority](https://github.com/cert-authority). by [@&#8203;Javier-varez](https://github.com/Javier-varez) in https://github.com/go-git/go-git/pull/1157
-   build: run example tests during CI workflow by [@&#8203;crazybolillo](https://github.com/crazybolillo) in https://github.com/go-git/go-git/pull/1030
-   storage: filesystem, Fix object cache not working due to uninitialised objects being put into cache by [@&#8203;SatelliteMind](https://github.com/SatelliteMind) in https://github.com/go-git/go-git/pull/1138
-   git: Fix fetching missing commits by [@&#8203;AriehSchneier](https://github.com/AriehSchneier) in https://github.com/go-git/go-git/pull/1032
-   plumbing: format/packfile, remove duplicate checks in findMatch() by [@&#8203;edigaryev](https://github.com/edigaryev) in https://github.com/go-git/go-git/pull/1152
-   git: worktree, Fix file reported as `Untracked` while it is committed by [@&#8203;rodrigocam](https://github.com/rodrigocam) in https://github.com/go-git/go-git/pull/1023
-   build: bump golang.org/x/sys from 0.22.0 to 0.23.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1160
-   plumbing: filemode, Remove check for setting size of .git/index file  by [@&#8203;nicholasSUSE](https://github.com/nicholasSUSE) in https://github.com/go-git/go-git/pull/1159
-   build: bump golang.org/x/net from 0.27.0 to 0.28.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1163
-   Fix some lint warning and increase stalebot to 180 days by [@&#8203;pjbgf](https://github.com/pjbgf) in https://github.com/go-git/go-git/pull/1128
-   adjust path extracted from file: url on Windows by [@&#8203;tomqwpl](https://github.com/tomqwpl) in https://github.com/go-git/go-git/pull/416
-   build: bump golang.org/x/sys from 0.23.0 to 0.24.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1164
-   Add RestoreStaged to Worktree that mimics the behaviour of git restore --staged <file>... by [@&#8203;ben-tbotlabs](https://github.com/ben-tbotlabs) in https://github.com/go-git/go-git/pull/493
-   plumbing: signature, support the same x509 signature formats as git by [@&#8203;yoavamit](https://github.com/yoavamit) in https://github.com/go-git/go-git/pull/1169
-   fix: allow discovery of non bare repos in fsLoader by [@&#8203;jakobmoellerdev](https://github.com/jakobmoellerdev) in https://github.com/go-git/go-git/pull/1170
-   build: bump golang.org/x/sys from 0.24.0 to 0.25.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1178
-   build: bump golang.org/x/text from 0.17.0 to 0.18.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1179
-   build: bump golang.org/x/net from 0.28.0 to 0.29.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1184
-   Consume push URLs when they are provided by [@&#8203;mcepl](https://github.com/mcepl) in https://github.com/go-git/go-git/pull/1191
-   \*: use gocheck's MkDir instead of TempDir for tests. Fixes [#&#8203;807](https://github.com/go-git/go-git/issues/807) by [@&#8203;uragirii](https://github.com/uragirii) in https://github.com/go-git/go-git/pull/1194
-   build: bump golang.org/x/net from 0.29.0 to 0.30.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1200
-   worktree: .git/index not correctly generated when running on Windows by [@&#8203;BeChris](https://github.com/BeChris) in https://github.com/go-git/go-git/pull/1198
-   git: worktree, Fix sparse reset. Fixes [#&#8203;90](https://github.com/go-git/go-git/issues/90) by [@&#8203;onee-only](https://github.com/onee-only) in https://github.com/go-git/go-git/pull/1101
-   git: worktree, Pass context on updateSubmodules. Fixes [#&#8203;1098](https://github.com/go-git/go-git/issues/1098) by [@&#8203;onee-only](https://github.com/onee-only) in https://github.com/go-git/go-git/pull/1154
-   build: bump github.com/go-git/go-billy/v5 from 5.5.1-0.20240427054813-8453aa90c6ec to 5.6.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1211
-   Update contributing guidelines by [@&#8203;pjbgf](https://github.com/pjbgf) in https://github.com/go-git/go-git/pull/1217
-   build: bump github.com/ProtonMail/go-crypto from 1.0.0 to 1.1.1 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1222
-   build: bump golang.org/x/sys from 0.26.0 to 0.27.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1223
-   build: bump golang.org/x/crypto from 0.28.0 to 0.29.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1221
-   build: bump github.com/ProtonMail/go-crypto from 1.1.1 to 1.1.2 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1226
-   build: bump github.com/stretchr/testify from 1.9.0 to 1.10.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1232
-   build: bump github.com/ProtonMail/go-crypto from 1.1.2 to 1.1.3 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1231
-   build: General improvements around fuzzing by [@&#8203;pjbgf](https://github.com/pjbgf) in https://github.com/go-git/go-git/pull/1229
-   build: bump golang.org/x/net from 0.30.0 to 0.32.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1241
-   build: group dependabot updates for golang.org by [@&#8203;AriehSchneier](https://github.com/AriehSchneier) in https://github.com/go-git/go-git/pull/1243
-   build: bump github/codeql-action from 2.22.11 to 3.27.6 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1244
-   build: bump golang.org/x/crypto from 0.21.0 to 0.31.0 in /cli/go-git by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1246
-   build: bump golang.org/x/crypto from 0.30.0 to 0.31.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1247
-   build: bump github.com/gliderlabs/ssh from 0.3.7 to 0.3.8 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1248
-   add comment preventing people from creating invalid trees by [@&#8203;petar](https://github.com/petar) in https://github.com/go-git/go-git/pull/732
-   build: bump github/codeql-action from 3.27.6 to 3.27.9 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1250
-   plumbing: Properly encode index version 4 by [@&#8203;BeChris](https://github.com/BeChris) in https://github.com/go-git/go-git/pull/1251
-   Fix typos by [@&#8203;deining](https://github.com/deining) in https://github.com/go-git/go-git/pull/1148
-   Fix reset files in subfolders by [@&#8203;linglo](https://github.com/linglo) in https://github.com/go-git/go-git/pull/1177
-   git: update switch cases by [@&#8203;hezhizhen](https://github.com/hezhizhen) in https://github.com/go-git/go-git/pull/1182
-   build: bump golang.org/x/net from 0.32.0 to 0.33.0 in the golang-org group by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1256
-   fix(1212): Fix invalid reference name error while cloning branches containing /- by [@&#8203;varmakarthik12](https://github.com/varmakarthik12) in https://github.com/go-git/go-git/pull/1257
-   pktline : accept upercase hexadecimal value as pktline length information by [@&#8203;BeChris](https://github.com/BeChris) in https://github.com/go-git/go-git/pull/1220
-   build: bump github/codeql-action from 3.27.9 to 3.28.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1260
-   build: bump github.com/elazarl/goproxy from 0.0.0-20240618083138-03be62527ccb to 1.2.1 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/go-git/go-git/pull/1262
-   git: worktree_commit, sanitize author and commiter name and email before creating the commit object. Fixes [#&#8203;680](https://github.com/go-git/go-git/issues/680) by [@&#8203;BeChris](https://github.com/BeChris) in https://github.com/go-git/go-git/pull/1261

#### New Contributors

-   [@&#8203;johnmatthiggins](https://github.com/johnmatthiggins) made their first contribution in https://github.com/go-git/go-git/pull/1088
-   [@&#8203;ggambetti](https://github.com/ggambetti) made their first contribution in https://github.com/go-git/go-git/pull/1100
-   [@&#8203;gecko655](https://github.com/gecko655) made their first contribution in https://github.com/go-git/go-git/pull/1109
-   [@&#8203;hbelmiro](https://github.com/hbelmiro) made their first contribution in https://github.com/go-git/go-git/pull/1124
-   [@&#8203;msuozzo](https://github.com/msuozzo) made their first contribution in https://github.com/go-git/go-git/pull/995
-   [@&#8203;Javier-varez](https://github.com/Javier-varez) made their first contribution in https://github.com/go-git/go-git/pull/1116
-   [@&#8203;Achilleshiel](https://github.com/Achilleshiel) made their first contribution in https://github.com/go-git/go-git/pull/1114
-   [@&#8203;crazybolillo](https://github.com/crazybolillo) made their first contribution in https://github.com/go-git/go-git/pull/1030
-   [@&#8203;SatelliteMind](https://github.com/SatelliteMind) made their first contribution in https://github.com/go-git/go-git/pull/1138
-   [@&#8203;rodrigocam](https://github.com/rodrigocam) made their first contribution in https://github.com/go-git/go-git/pull/1023
-   [@&#8203;nicholasSUSE](https://github.com/nicholasSUSE) made their first contribution in https://github.com/go-git/go-git/pull/1159
-   [@&#8203;tomqwpl](https://github.com/tomqwpl) made their first contribution in https://github.com/go-git/go-git/pull/416
-   [@&#8203;ben-tbotlabs](https://github.com/ben-tbotlabs) made their first contribution in https://github.com/go-git/go-git/pull/493
-   [@&#8203;yoavamit](https://github.com/yoavamit) made their first contribution in https://github.com/go-git/go-git/pull/1169
-   [@&#8203;uragirii](https://github.com/uragirii) made their first contribution in https://github.com/go-git/go-git/pull/1194
-   [@&#8203;petar](https://github.com/petar) made their first contribution in https://github.com/go-git/go-git/pull/732
-   [@&#8203;deining](https://github.com/deining) made their first contribution in https://github.com/go-git/go-git/pull/1148
-   [@&#8203;linglo](https://github.com/linglo) made their first contribution in https://github.com/go-git/go-git/pull/1177
-   [@&#8203;varmakarthik12](https://github.com/varmakarthik12) made their first contribution in https://github.com/go-git/go-git/pull/1257

**Full Changelog**: https://github.com/go-git/go-git/compare/v5.12.0...v5.13.0

### [`v5.12.0`](https://github.com/go-git/go-git/releases/tag/v5.12.0)

[Compare Source](https://github.com/go-git/go-git/compare/v5.11.0...v5.12.0)

#### What's Changed

-   git: Worktree.AddWithOptions: add skipStatus option when providing a specific path by [@&#8203;moranCohen26](https://github.com/moranCohen26) in https://github.com/go-git/go-git/pull/994
-   git: Signer: fix usage of crypto.Signer interface by [@&#8203;wlynch](https://github.com/wlynch) in https://github.com/go-git/go-git/pull/1029
-   git: Remote, fetch, adds the prune option. by [@&#8203;juliens](https://github.com/juliens) in https://github.com/go-git/go-git/pull/366
-   git: Add crypto.Signer option to CommitOptions. by [@&#8203;wlynch](https://github.com/wlynch) in https://github.com/go-git/go-git/pull/996
-   git: Worktree checkout tag hash id ([#&#8203;959](https://github.com/go-git/go-git/issues/959)) by [@&#8203;aymanbagabas](https://github.com/aymanbagabas) in https://github.com/go-git/go-git/pull/966
-   git: Worktree, Don't panic on empty or root path when checking if it is valid by [@&#8203;tim775](https://github.com/tim775) in https://github.com/go-git/go-git/pull/1042
-   git: Add commit validation for Reset by [@&#8203;pjbgf](https://github.com/pjbgf) in https://github.com/go-git/go-git/pull/1048
-   git: worktree_commit, Fix amend commit to apply changes. Fixes [#&#8203;1024](https://github.com/go-git/go-git/issues/1024) by [@&#8203;onee-only](https://github.com/onee-only) in https://github.com/go-git/go-git/pull/1045
-   git: Implement Merge function with initial `FastForwardMerge` support by [@&#8203;pjbgf](https://github.com/pjbgf) in https://github.com/go-git/go-git/pull/1044
-   plumbing: object, Make first commit visible on logs filtered with filename. Fixes [#&#8203;191](https://github.com/go-git/go-git/issues/191) by [@&#8203;onee-only](https://github.com/onee-only) in https://github.com/go-git/go-git/pull/1036
-   plumbing: no panic in printStats function. Fixes [#&#8203;177](https://github.com/go-git/go-git/issues/177) by [@&#8203;nodivbyzero](https://github.com/nodivbyzero) in https://github.com/go-git/go-git/pull/971
-   plumbing: object, Optimize logging with file. by [@&#8203;onee-only](https://github.com/onee-only) in https://github.com/go-git/go-git/pull/1046
-   plumbing: object, check legitimacy in (\*Tree).Encode by [@&#8203;niukuo](https://github.com/niukuo) in https://github.com/go-git/go-git/pull/967
-   plumbing: format/gitattributes, close file in ReadAttributesFile by [@&#8203;prskr](https://github.com/prskr) in https://github.com/go-git/go-git/pull/1018
-   plumbing: check setAuth error. Fixes [#&#8203;185](https://github.com/go-git/go-git/issues/185) by [@&#8203;nodivbyzero](https://github.com/nodivbyzero) in https://github.com/go-git/go-git/pull/969
-   plumbing: object, fix variable  defaultUtf8CommitMessageEncoding name spell error by [@&#8203;Jerry-yz](https://github.com/Jerry-yz) in https://github.com/go-git/go-git/pull/987
-   utils: merkletrie, calculate filesystem node's hash lazily. by [@&#8203;candid82](https://github.com/candid82) in https://github.com/go-git/go-git/pull/825
-   utils: update comment in node.go's Hash() by [@&#8203;codablock](https://github.com/codablock) in https://github.com/go-git/go-git/pull/992
-   \_example: fix 404 link and added ssh-agent clone link by [@&#8203;grinish21](https://github.com/grinish21) in https://github.com/go-git/go-git/pull/1022
-   \_example: checkout-branch example by [@&#8203;dlambda](https://github.com/dlambda) in https://github.com/go-git/go-git/pull/446
-   \_example: example for git clone using ssh-agent by [@&#8203;pjbgf](https://github.com/pjbgf) in https://github.com/go-git/go-git/pull/998

#### New Contributors

-   [@&#8203;candid82](https://github.com/candid82) made their first contribution in https://github.com/go-git/go-git/pull/825
-   [@&#8203;codablock](https://github.com/codablock) made their first contribution in https://github.com/go-git/go-git/pull/992
-   [@&#8203;Jerry-yz](https://github.com/Jerry-yz) made their first contribution in https://github.com/go-git/go-git/pull/987
-   [@&#8203;wlynch](https://github.com/wlynch) made their first contribution in https://github.com/go-git/go-git/pull/996
-   [@&#8203;moranCohen26](https://github.com/moranCohen26) made their first contribution in https://github.com/go-git/go-git/pull/994
-   [@&#8203;grinish21](https://github.com/grinish21) made their first contribution in https://github.com/go-git/go-git/pull/1022
-   [@&#8203;prskr](https://github.com/prskr) made their first contribution in https://github.com/go-git/go-git/pull/1018
-   [@&#8203;dlambda](https://github.com/dlambda) made their first contribution in https://github.com/go-git/go-git/pull/446
-   [@&#8203;juliens](https://github.com/juliens) made their first contribution in https://github.com/go-git/go-git/pull/366
-   [@&#8203;onee-only](https://github.com/onee-only) made their first contribution in https://github.com/go-git/go-git/pull/1036
-   [@&#8203;tim775](https://github.com/tim775) made their first contribution in https://github.com/go-git/go-git/pull/1042
-   [@&#8203;niukuo](https://github.com/niukuo) made their first contribution in https://github.com/go-git/go-git/pull/967
-   [@&#8203;avoidalone](https://github.com/avoidalone) made their first contribution in https://github.com/go-git/go-git/pull/1047

**Full Changelog**: https://github.com/go-git/go-git/compare/v5.11.0...v5.12.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - "* 0-3 * * *" (UTC).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS45Mi4wIiwidXBkYXRlZEluVmVyIjoiMzkuOTIuMCIsInRhcmdldEJyYW5jaCI6InYxMC4wL2Zvcmdlam8iLCJsYWJlbHMiOlsiZGVwZW5kZW5jeS11cGdyYWRlIiwidGVzdC9ub3QtbmVlZGVkIl19-->

Co-authored-by: Earl Warren <contact@earl-warren.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6496
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
Co-committed-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
2025-01-07 20:51:15 +00:00
forgejo-backport-action
3b5f162fe6 [v10.0/forgejo] chore: remove illegal git usage (#6492)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6488

This is no longer possible in future go-git versions, so lets hardcode it

Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6492
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-07 19:01:32 +00:00
forgejo-backport-action
f63e5a1cff [v10.0/forgejo] fix(ui): show oauth divider on signup page (#6465)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6463

Fix a minor UI bug introduced in https://codeberg.org/forgejo/forgejo/pulls/6112.

The condition `if .EnableInternalSignIn` was added to display of the divider, but it is only available when `oauth_container.tmpl` is called from signIn page, it is not relevant to signUp page.

Co-authored-by: 0ko <0ko@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6465
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2025-01-04 10:35:37 +00:00
Earl Warren
25640f201e Merge pull request '[v10.0/forgejo] i18n: update of translations from Codeberg Translate' (#6450) from bp-v10.0/forgejo-a33fe60 into v10.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6450
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2025-01-02 08:24:15 +00:00
Codeberg Translate
ef205915cc i18n: update of translations from Codeberg Translate (#6378)
Co-authored-by: tacaly <frederick@tacaly.com>
Co-authored-by: Fjuro <fjuro@alius.cz>
Co-authored-by: artnay <artnay@users.noreply.translate.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-authored-by: 0ko <0ko@users.noreply.translate.codeberg.org>
Co-authored-by: Edgarsons <edgarsons@users.noreply.translate.codeberg.org>
Co-authored-by: Benedikt Straub <benedikt-straub@web.de>
Co-authored-by: Atalanttore <atalanttore@users.noreply.translate.codeberg.org>
Co-authored-by: Wuzzy <wuzzy@disroot.org>
Co-authored-by: Juno Takano <jutty@users.noreply.translate.codeberg.org>
Co-authored-by: Dirk <dirk@users.noreply.translate.codeberg.org>
Co-authored-by: thodorisl <thodorisl@users.noreply.translate.codeberg.org>
Co-authored-by: jasonb <jasonb@users.noreply.translate.codeberg.org>
Co-authored-by: SomeTr <sometr@users.noreply.translate.codeberg.org>
Co-authored-by: Outbreak2096 <outbreak2096@users.noreply.translate.codeberg.org>
Co-authored-by: xtex <xtexchooser@duck.com>
Co-authored-by: Salif Mehmed <mail@salif.eu>
Co-authored-by: s-light <s-light@users.noreply.translate.codeberg.org>
Co-authored-by: earl-warren <earl-warren@users.noreply.translate.codeberg.org>
Co-authored-by: Kita Ikuyo <searinminecraft@courvix.com>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6378
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Codeberg Translate <translate@noreply.codeberg.org>
Co-committed-by: Codeberg Translate <translate@noreply.codeberg.org>
(cherry picked from commit a33fe60bbe)
2025-01-02 07:47:56 +00:00
Gusted
81d351ce5f Merge pull request '[v10.0/forgejo] feat: Add summary card for repos and releases' (#6448) from JakobDev/forgejo:cardback into v10.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6448
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2025-01-02 05:44:05 +00:00
Gusted
cd08097bbb Merge pull request '[v10.0/forgejo] Fix editing pr review' (#6444) from bp-v10.0/forgejo-13b6caa into v10.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6444
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2025-01-02 00:55:10 +00:00
JakobDev
13496203bc
[v10.0/forgejo] feat: Add summary card for repos and releases 2025-01-01 22:00:26 +01:00
JakobDev
8f47560bf7 Fix editing pr review
(cherry picked from commit 13b6caa608)
2025-01-01 17:54:01 +00:00
0ko
9e6c3f226c Merge pull request '[v10.0/forgejo] fix(code search): empty mode dropdown when keyword is empty' (#6442) from bp-v10.0/forgejo-c53d219 into v10.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6442
Reviewed-by: Shiny Nematoda <snematoda@noreply.codeberg.org>
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
2025-01-01 13:36:24 +00:00
Shiny Nematoda
c7c7f69f82 fix(code search): empty mode dropdown when keyword is empty
(cherry picked from commit c53d21965a)
2025-01-01 13:04:56 +00:00
Gusted
86a09562fd Merge pull request '[v10.0/forgejo] fix(ui): use primary color for button in table modal' (#6430) from bp-v10.0/forgejo-a302506 into v10.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6430
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-12-31 15:18:37 +00:00
0ko
ce5c3e32c1 fix(ui): use primary color for button in table modal (#6427)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6427
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
(cherry picked from commit a302506095)
2024-12-31 09:39:52 +00:00
Earl Warren
fa9f6e0cdd Merge pull request '[v10.0/forgejo] Fix edit cancel button' (#6426) from bp-v10.0/forgejo-29c59c9 into v10.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6426
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-12-31 07:30:26 +00:00
JakobDev
172a48be8a Fix edit cancel button
(cherry picked from commit 29c59c96bd)
2024-12-31 02:11:08 +00:00
Earl Warren
4a25a3e154 Merge pull request '[v10.0/forgejo] Rework user profile settings' (#6423) from bp-v10.0/forgejo-2885ea8 into v10.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6423
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-12-30 21:20:51 +00:00
Earl Warren
6266715486 Merge pull request '[v10.0/forgejo] Fix issue/comment menus' (#6424) from bp-v10.0/forgejo-c67d63d into v10.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6424
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-12-30 21:19:38 +00:00
Otto Richter
3496c819da Fix issue/comment menus
Closes https://codeberg.org/forgejo/forgejo/issues/1120

- Adds labels to reaction and context menu.
- Fixes taborder in markdown combobox buttons. They are now only one
  "tab" stop and can be navigated with arrow buttons and in the right
order (previously, it would skip the table button).
- Generates more verbose output for the reactio selectors to provide
  content for users who cannot identify the meaning of these buttons
visually. Explicit aria-labels are now preferred over auto-generated
ones.

(cherry picked from commit c67d63d88a)
2024-12-30 20:29:28 +00:00
Otto Richter
4f8d96a6de Rework user profile settings
Accessibility:

- improved semantic layout
- Fixes unlabelled input for custom pronouns. CC @hazy
- Adds labels to dropdowns.
- Shortens certain texts for less verbose screen reader outputs and
  people with slow reading speed.
- Turned optional username rename helper text with low contrast into
  "normal" help text.

UI/UX:

- Removes section about primary email which is no longer managed in the
  profile section.
- Fixes section about primary email not displaying in user settings when notifications are
  not available.
- Removes primary email display, because it is not actually a form
  element here. (Alternatively, we could display it and link to the
account settings for managing the email)

(cherry picked from commit 2885ea8da2)
2024-12-30 20:29:15 +00:00
Earl Warren
8d353ad258 Merge pull request '[v10.0/forgejo] chore(branding): strip metadata information from the footer' (#6420) from bp-v10.0/forgejo-2c81893 into v10.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6420
2024-12-30 16:43:10 +00:00
Earl Warren
865d4f538b chore(branding): strip metadata information from the footer
When the Forgejo version is displayed in the footer, the metadata
should not be displayed. It was once an indication that Forgejo
includes all of Gitea. But since the hard fork the codebase diverged
and this is no longer accurate.

The metadata is still displayed in the API, admin panels or headers
for the sake of backward compatibility.

Refs: https://codeberg.org/forgejo/discussions/issues/244
(cherry picked from commit 2c81893c76)
2024-12-30 15:30:02 +00:00
Gusted
ecbbaabfc8 Merge pull request '[v10.0/forgejo] fix: use DateUtils for blocked users list' (#6418) from bp-v10.0/forgejo-57f7253 into v10.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6418
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-12-30 12:55:05 +00:00
Gusted
38f058a5f0 fix: use DateUtils for blocked users list
- Should've been fixed with #5796 but seems I've overlooked.

(cherry picked from commit 57f7253610)
2024-12-30 10:54:38 +00:00
Earl Warren
1a64ae1dc4 Merge pull request '[v10.0/forgejo] [gitea] week 2024-53 cherry pick (gitea/main -> forgejo)' (#6416) from bp-v10.0/forgejo-0efd713-2ffa9a5-92ac337-b18dcd6-37f0561 into v10.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6416
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-12-30 08:59:18 +00:00
Earl Warren
a8cc73fe87 Improve Actions test (#32883) (followup)
(cherry picked from commit 37f05617a5)
2024-12-30 08:26:54 +00:00
Zettat123
7a84081755 Improve Actions test (#32883)
This PR adds a mock runner to test more actions features.

(cherry picked from commit df98452c0de9d01338f00aa5d85757623523b1fc)
(cherry picked from commit b18dcd69f2)
2024-12-30 08:26:54 +00:00
Zettat123
2ac9b16297 Support org labels when adding labels by label names (#32988)
Fix #32891

(cherry picked from commit 44b4fb21a4e99f327303f66cc7e48f7ca7ba09e1)
(cherry picked from commit 92ac337263)
2024-12-30 08:26:54 +00:00
Lunny Xiao
2bcbfbc5d4 demilestone should not include milestone (#32923)
Fix #32887

(cherry picked from commit f44712f22bc7bfce049c64c27f60453ff1e41a5c)

Conflicts:
	services/issue/milestone_test.go
  trivial conflicts (require vs assert)
(cherry picked from commit 2ffa9a5e6e)
2024-12-30 08:26:54 +00:00
katsu
4999de50c3 fix trailing comma not matched in the case of alphanumeric issue (#32945)
Fix #32428.

Patch the regex to match `,`besides `.` `"` `'` `:` and space.

(cherry picked from commit fb75151fb14e866cab8d893c588f5673902b278b)
(cherry picked from commit 0efd7130f0)
2024-12-30 08:26:54 +00:00
Earl Warren
eb00a80efc Merge pull request '[v10.0/forgejo] Rework new repo dialog' (#6399) from bp-v10.0/forgejo-471e5b1-8159915-4cde569-8d32ca3-8d829a9 into v10.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6399
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
2024-12-29 20:49:03 +00:00
Earl Warren
c7c22aae8c Merge pull request '[v10.0/forgejo] fix: xorm needs to be lowercase otherwise it is ignored' (#6406) from bp-v10.0/forgejo-b03ecf5 into v10.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6406
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2024-12-29 20:09:11 +00:00
Gusted
0eab84d02e Merge pull request '[v10.0/forgejo] feat: When comparing in repos, mention that pull request creation requires sign-in' (#6398) from bp-v10.0/forgejo-dd4a110 into v10.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6398
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
2024-12-29 18:40:10 +00:00
Earl Warren
e71fd7d28d fix: xorm needs to be lowercase otherwise it is ignored
Fixes: https://codeberg.org/forgejo/forgejo/issues/6389
(cherry picked from commit b03ecf584c)
2024-12-29 18:27:08 +00:00
Gusted
055348430e Merge pull request '[v10.0/forgejo] Cosmetic changes and fixes around repo homepage' (#6402) from bp-v10.0/forgejo-02c34f9 into v10.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6402
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
2024-12-29 18:27:01 +00:00
0ko
440be42baf ui: cosmetic changes and fixes around repo homepage
(cherry picked from commit 02c34f9908)
2024-12-29 14:47:11 +00:00
Otto Richter
f1b98d16c7 tests(e2e): Test new repo dialog and behaviour
- screenshots and basic accessibility scan of collapsed and expanded sections
  - the dropdowns do not pass the accessibility checks, but I haven't found an easy fix
  - I manually confirmed the dropdown behaviour via orca and firefox, though

(cherry picked from commit 8d829a97b2)
2024-12-29 13:23:30 +00:00
Otto Richter
662b385596 New repo: Rework initialization
- only show settings when ticked
- only offer README selection when there are multiple options

(cherry picked from commit 8d32ca32c2)
2024-12-29 13:23:30 +00:00
Otto Richter
023aaef2b9 New repo: Rework advanced and template sections
- make sections collapsible
- only offer object format selection when there is an actual choice

(cherry picked from commit 4cde56906e)
2024-12-29 13:23:30 +00:00
Otto Richter
cb745a771a New repo: Rework basic settings
- separate template
- ensure correct labelling of elements
- drop additional required indicators for field that already have
  browser semantics (the icon has colour contrast issues anyway),
especially as the first dropdown cannot be left empty

(cherry picked from commit 81599155e8)
2024-12-29 13:23:30 +00:00
Otto Richter
38d2933cc1 New repo: Clean up and improve CSS
- drop custom layout rules for this page
- move form-related content to form.css
- extend new form CSS to add gap between labels and input fields

(cherry picked from commit 471e5b1975)
2024-12-29 13:23:30 +00:00
Litchi Pi
5a0c79e6b4 template: repo: compare: display a warning if the user is not logged in
Signed-off-by: Litchi Pi <litchi.pi@proton.me>
(cherry picked from commit dd4a1107ed)
2024-12-29 12:52:49 +00:00
Earl Warren
424f85304e Merge pull request '[v10.0/forgejo] Fix overflow in git notes' (#6392) from bp-v10.0/forgejo-dcdeb23 into v10.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6392
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-12-28 21:17:42 +00:00
JakobDev
382db9e8de Fix overflow in git notes
(cherry picked from commit dcdeb23cc3)
2024-12-28 20:44:10 +00:00
Earl Warren
0ff66fa3bb Merge pull request 'Revert "Update dependency idiomorph to v0.4.0"' (#6382) from gusted/forgejo-idiomorph-rever-v10 into v10.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6382
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-12-27 06:43:17 +00:00
Gusted
d5c5724f44
Revert "Update dependency idiomorph to v0.4.0"
This reverts commit f9aaefd107.

I've not not yet been able to determine what commit caused it, but 0.4.0
is broken for Forgejo's usecase it's not morphing and instead
replacing (it seems) elements when there's no need to.

(cherry picked from commit 64deec434a)
2024-12-27 03:04:25 +01:00
forgejo-backport-action
1da56f0eb8 [v10.0/forgejo] i18n: update of translations from Codeberg Translate (#6377)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/6331

Translations update from [Codeberg Translate](https://translate.codeberg.org) for [Forgejo/forgejo](https://translate.codeberg.org/projects/forgejo/forgejo/).

Current translation status:

![Weblate translation status](https://translate.codeberg.org/widget/forgejo/forgejo/horizontal-auto.svg)

<!--start release-notes-assistant-->

## Release notes
<!--URL:https://codeberg.org/forgejo/forgejo-->
- Localization
  - [PR](https://codeberg.org/forgejo/forgejo/pulls/6331): <!--number 6331 --><!--line 0 --><!--description aTE4bjogdXBkYXRlIG9mIHRyYW5zbGF0aW9ucyBmcm9tIENvZGViZXJnIFRyYW5zbGF0ZQ==-->i18n: update of translations from Codeberg Translate<!--description-->
<!--end release-notes-assistant-->

Co-authored-by: Codeberg Translate <translate@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6377
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
2024-12-26 09:57:35 +00:00
Earl Warren
6a78a71172 Merge pull request '[v10.0/forgejo] chore(i18n): user/label translations in danish/latvian' (#6376) from bp-v10.0/forgejo-5eb0877 into v10.0/forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6376
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-12-26 09:14:28 +00:00
Earl Warren
f6c442c2fe chore(i18n): user/label translations in danish/latvian
Refs: https://codeberg.org/forgejo/forgejo/pulls/6331
(cherry picked from commit 5eb0877381)
2024-12-26 08:58:09 +00:00
2968 changed files with 39761 additions and 74984 deletions

View file

@ -1,7 +1,7 @@
forgejo.org/cmd
code.gitea.io/gitea/cmd
NoMainListener
forgejo.org/cmd/forgejo
code.gitea.io/gitea/cmd/forgejo
ContextSetNoInit
ContextSetNoExit
ContextSetStderr
@ -9,118 +9,128 @@ forgejo.org/cmd/forgejo
ContextSetStdout
ContextSetStdin
forgejo.org/models
code.gitea.io/gitea/models
IsErrUpdateTaskNotExist
ErrUpdateTaskNotExist.Error
ErrUpdateTaskNotExist.Unwrap
IsErrSHANotFound
IsErrMergeDivergingFastForwardOnly
forgejo.org/models/activities
GetActivityByID
NewFederatedUserActivity
CreateUserActivity
GetFollowingFeeds
FederatedUserActivity.loadActor
code.gitea.io/gitea/models/actions
ScheduleList.GetUserIDs
ScheduleList.GetRepoIDs
ScheduleList.LoadTriggerUser
ScheduleList.LoadRepos
forgejo.org/models/auth
code.gitea.io/gitea/models/asymkey
ErrGPGKeyAccessDenied.Error
ErrGPGKeyAccessDenied.Unwrap
HasDeployKey
code.gitea.io/gitea/models/auth
GetSourceByName
WebAuthnCredentials
forgejo.org/models/db
code.gitea.io/gitea/models/db
TruncateBeans
InTransaction
DumpTables
GetTableNames
forgejo.org/models/dbfs
code.gitea.io/gitea/models/dbfs
file.renameTo
Create
Rename
forgejo.org/models/forgejo/semver
code.gitea.io/gitea/models/forgefed
GetFederationHost
code.gitea.io/gitea/models/forgejo/semver
GetVersion
SetVersionString
SetVersion
forgejo.org/models/git
code.gitea.io/gitea/models/git
RemoveDeletedBranchByID
forgejo.org/models/issues
code.gitea.io/gitea/models/issues
IsErrUnknownDependencyType
ErrNewIssueInsert.Error
IsErrIssueWasClosed
ChangeMilestoneStatus
forgejo.org/models/organization
code.gitea.io/gitea/models/organization
GetTeamNamesByID
UpdateTeamUnits
SearchMembersOptions.ToConds
UsersInTeamsCount
forgejo.org/models/perm/access
code.gitea.io/gitea/models/perm/access
GetRepoWriters
forgejo.org/models/repo
code.gitea.io/gitea/models/project
UpdateColumnSorting
ChangeProjectStatus
code.gitea.io/gitea/models/repo
DeleteAttachmentsByIssue
FindReposMapByIDs
IsErrTopicNotExist
ErrTopicNotExist.Error
ErrTopicNotExist.Unwrap
GetTopicByName
WatchRepoMode
forgejo.org/models/user
code.gitea.io/gitea/models/user
ErrUserInactive.Error
ErrUserInactive.Unwrap
IsErrExternalLoginUserAlreadyExist
IsErrExternalLoginUserNotExist
NewFederatedUser
NewFederatedUserFollower
IsErrUserSettingIsNotExist
GetUserAllSettings
DeleteUserSetting
GetFederatedUser
GetFederatedUserByUserID
GetFollowersForUser
AddFollower
RemoveFollower
IsFollowingAp
GetUserEmailsByNames
GetUserNamesByIDs
forgejo.org/modules/activitypub
code.gitea.io/gitea/modules/activitypub
NewContext
Context.APClientFactory
forgejo.org/modules/assetfs
code.gitea.io/gitea/modules/assetfs
Bindata
forgejo.org/modules/auth/password/hash
code.gitea.io/gitea/modules/auth/password/hash
DummyHasher.HashWithSaltBytes
NewDummyHasher
forgejo.org/modules/auth/password/pwn
code.gitea.io/gitea/modules/auth/password/pwn
WithHTTP
forgejo.org/modules/base
code.gitea.io/gitea/modules/base
SetupGiteaRoot
forgejo.org/modules/cache
code.gitea.io/gitea/modules/cache
GetInt
WithNoCacheContext
RemoveContextData
forgejo.org/modules/emoji
code.gitea.io/gitea/modules/charset
BreakWriter.Write
code.gitea.io/gitea/modules/emoji
ReplaceCodes
forgejo.org/modules/eventsource
code.gitea.io/gitea/modules/eventsource
Event.String
forgejo.org/modules/forgefed
NewForgeFollowFromAp
NewForgeFollow
ForgeFollow.MarshalJSON
ForgeFollow.UnmarshalJSON
ForgeFollow.Validate
NewForgeUndoLike
ForgeUndoLike.UnmarshalJSON
ForgeUndoLike.Validate
NewForgeUserActivityFromAp
NewForgeUserActivity
ForgeUserActivity.Validate
NewPersonIDFromModel
code.gitea.io/gitea/modules/forgefed
GetItemByType
JSONUnmarshalerFn
NotEmpty
NewForgeUserActivityNoteFromAp
newNote
ForgeUserActivityNote.Validate
ToRepository
OnRepository
forgejo.org/modules/git
code.gitea.io/gitea/modules/git
AllowLFSFiltersArgs
AddChanges
AddChangesWithArgs
@ -128,57 +138,71 @@ forgejo.org/modules/git
CommitChangesWithArgs
SetUpdateHook
openRepositoryWithDefaultContext
IsTagExist
ToEntryMode
LimitedReaderCloser.Read
LimitedReaderCloser.Close
forgejo.org/modules/gitrepo
code.gitea.io/gitea/modules/gitgraph
Parser.Reset
code.gitea.io/gitea/modules/gitrepo
GetBranchCommitID
GetWikiDefaultBranch
forgejo.org/modules/graceful
code.gitea.io/gitea/modules/graceful
Manager.TerminateContext
Manager.Err
Manager.Value
Manager.Deadline
forgejo.org/modules/hcaptcha
code.gitea.io/gitea/modules/hcaptcha
WithHTTP
forgejo.org/modules/hostmatcher
code.gitea.io/gitea/modules/hostmatcher
HostMatchList.AppendPattern
forgejo.org/modules/json
code.gitea.io/gitea/modules/json
StdJSON.Marshal
StdJSON.Unmarshal
StdJSON.NewEncoder
StdJSON.NewDecoder
StdJSON.Indent
forgejo.org/modules/log
NewEventWriterBuffer
forgejo.org/modules/markup
code.gitea.io/gitea/modules/markup
GetRendererByType
RenderString
IsMarkupFile
forgejo.org/modules/markup/console
code.gitea.io/gitea/modules/markup/console
Render
RenderString
forgejo.org/modules/markup/markdown
code.gitea.io/gitea/modules/markup/markdown
IsDetails
IsSummary
IsTaskCheckBoxListItem
IsIcon
RenderRawString
forgejo.org/modules/markup/mdstripper
code.gitea.io/gitea/modules/markup/markdown/math
WithInlineDollarParser
WithBlockDollarParser
code.gitea.io/gitea/modules/markup/mdstripper
stripRenderer.AddOptions
StripMarkdown
forgejo.org/modules/markup/orgmode
code.gitea.io/gitea/modules/markup/orgmode
RenderString
forgejo.org/modules/process
code.gitea.io/gitea/modules/private
ActionsRunnerRegister
code.gitea.io/gitea/modules/process
Manager.ExecTimeout
forgejo.org/modules/queue
code.gitea.io/gitea/modules/queue
newBaseChannelSimple
newBaseChannelUnique
newBaseRedisSimple
@ -187,76 +211,89 @@ forgejo.org/modules/queue
testStateRecorder.Reset
newWorkerPoolQueueForTest
forgejo.org/modules/queue/lqinternal
code.gitea.io/gitea/modules/queue/lqinternal
QueueItemIDBytes
QueueItemKeyBytes
ListLevelQueueKeys
forgejo.org/modules/setting
code.gitea.io/gitea/modules/setting
NewConfigProviderFromData
GitConfigType.GetOption
InitLoggersForTest
forgejo.org/modules/sync
code.gitea.io/gitea/modules/storage
ErrInvalidConfiguration.Error
IsErrInvalidConfiguration
code.gitea.io/gitea/modules/structs
ParseCreateHook
ParsePushHook
code.gitea.io/gitea/modules/sync
StatusTable.Start
StatusTable.IsRunning
forgejo.org/modules/timeutil
code.gitea.io/gitea/modules/timeutil
GetExecutableModTime
MockSet
MockUnset
forgejo.org/modules/translation
code.gitea.io/gitea/modules/translation
MockLocale.Language
MockLocale.TrString
MockLocale.Tr
MockLocale.TrN
MockLocale.TrPluralString
MockLocale.TrPluralStringAllForms
MockLocale.TrSize
MockLocale.HasKey
MockLocale.PrettyNumber
forgejo.org/modules/translation/localeiter
IterateMessagesContent
forgejo.org/modules/util
code.gitea.io/gitea/modules/util
OptionalArg
forgejo.org/modules/util/filebuffer
code.gitea.io/gitea/modules/util/filebuffer
CreateFromReader
forgejo.org/modules/validation
code.gitea.io/gitea/modules/validation
IsErrNotValid
ValidateIDExists
forgejo.org/modules/web
code.gitea.io/gitea/modules/web
RouteMock
RouteMockReset
forgejo.org/modules/zstd
code.gitea.io/gitea/modules/web/middleware
DeleteLocaleCookie
code.gitea.io/gitea/modules/zstd
NewWriter
Writer.Write
Writer.Close
forgejo.org/routers/web/org
code.gitea.io/gitea/routers/web
NotFound
code.gitea.io/gitea/routers/web/org
MustEnableProjects
forgejo.org/services/context
code.gitea.io/gitea/services/context
GetPrivateContext
forgejo.org/services/federation
Init
code.gitea.io/gitea/services/convert
ToSecret
forgejo.org/services/repository
code.gitea.io/gitea/services/forms
DeadlineForm.Validate
code.gitea.io/gitea/services/pull
IsCommitStatusContextSuccess
code.gitea.io/gitea/services/repository
IsErrForkAlreadyExist
forgejo.org/services/repository/files
code.gitea.io/gitea/services/repository/files
ContentType.String
GetFileResponseFromCommit
TemporaryUploadRepository.GetLastCommit
TemporaryUploadRepository.GetLastCommitByRef
forgejo.org/services/repository/gitgraph
Parser.Reset
forgejo.org/services/webhook
code.gitea.io/gitea/services/webhook
NewNotifier

View file

@ -1,12 +1,16 @@
{
"name": "Gitea DevContainer",
"image": "mcr.microsoft.com/devcontainers/go:1.24-bullseye",
"image": "mcr.microsoft.com/devcontainers/go:1.23-bullseye",
"features": {
// installs nodejs into container
"ghcr.io/devcontainers/features/node:1": {
"version": "22"
"version": "20"
},
"ghcr.io/devcontainers/features/git-lfs:1.2.3": {},
"ghcr.io/devcontainers-contrib/features/poetry:2": {},
"ghcr.io/devcontainers/features/python:1": {
"version": "3.12"
},
"ghcr.io/devcontainers/features/git-lfs:1.2.5": {},
"ghcr.io/warrenbuckley/codespace-features/sqlite:1": {}
},
"customizations": {

View file

@ -34,12 +34,15 @@ _testmain.go
*coverage.out
coverage.all
coverage/
cpu.out
/modules/migration/bindata.go
/modules/migration/bindata.go.hash
/modules/options/bindata.go
/modules/options/bindata.go.hash
/modules/public/bindata.go
/modules/public/bindata.go.hash
/modules/templates/bindata.go
/modules/templates/bindata.go.hash
*.db

View file

@ -12,9 +12,6 @@ insert_final_newline = true
[{*.{go,tmpl,html},Makefile,go.mod}]
indent_style = tab
[go.*]
indent_style = tab
[templates/custom/*.tmpl]
insert_final_newline = false
@ -29,8 +26,3 @@ insert_final_newline = false
[options/locale/locale_*.ini]
insert_final_newline = false
# Weblate JSON output defaults to four spaces
[options/locale_next/locale_*.json]
indent_style = space
indent_size = 4

View file

@ -6,7 +6,7 @@ body:
- type: markdown
attributes:
value: |
**NOTE: If your issue is a security concern, please email <security@forgejo.org> ([security.txt](https://forgejo.org/.well-known/security.txt)) instead of opening a public issue.**
**NOTE: If your issue is a security concern, please email <security@forgejo.org> (GPG: `A4676E79`) instead of opening a public issue.**
- type: markdown
attributes:
value: |

View file

@ -6,7 +6,7 @@ body:
- type: markdown
attributes:
value: |
**NOTE: If your issue is a security concern, please email <security@forgejo.org> ([security.txt](https://forgejo.org/.well-known/security.txt)) instead of opening a public issue.**
**NOTE: If your issue is a security concern, please email <security@forgejo.org> (GPG: `A4676E79`) instead of opening a public issue.**
- type: markdown
attributes:
value: |

View file

@ -1,4 +1,4 @@
FROM data.forgejo.org/oci/alpine:3.22
FROM data.forgejo.org/oci/alpine:3.20
ARG RELEASE_VERSION=unkown
LABEL maintainer="contact@forgejo.org" \
org.opencontainers.image.version="${RELEASE_VERSION}"

View file

@ -1,3 +1,3 @@
module forgejo.org
module code.gitea.io/gitea
go 1.23.3

View file

@ -18,7 +18,7 @@ runs:
- name: install packages
run: |
apt-get update -qq
apt-get -q install --allow-downgrades -qq -y ${PACKAGES}
apt-get -q install -qq -y ${PACKAGES}
env:
PACKAGES: ${{inputs.packages}}
- name: remove temporary package list to prevent using it in other steps

View file

@ -1,22 +0,0 @@
#
# Install the minimal version of Git supported by Forgejo
#
runs:
using: "composite"
steps:
- name: install git and git-lfs
run: |
set -x
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
apt-get -q install -y -qq curl ca-certificates
curl -sS -o /tmp/git-man.deb http://archive.ubuntu.com/ubuntu/pool/main/g/git/git-man_2.34.1-1ubuntu1_all.deb
curl -sS -o /tmp/git.deb https://archive.ubuntu.com/ubuntu/pool/main/g/git/git_2.34.1-1ubuntu1_amd64.deb
curl -sS -o /tmp/git-lfs.deb https://archive.ubuntu.com/ubuntu/pool/universe/g/git-lfs/git-lfs_3.0.2-1_amd64.deb
apt-get -q install --allow-downgrades -y -qq /tmp/git-man.deb
apt-get -q install --allow-downgrades -y -qq /tmp/git.deb
apt-get -q install --allow-downgrades -y -qq /tmp/git-lfs.deb

View file

@ -40,14 +40,14 @@ jobs:
)
runs-on: docker
container:
image: 'data.forgejo.org/oci/node:22-bookworm'
image: 'data.forgejo.org/oci/node:20-bookworm'
steps:
- name: event info
run: |
cat <<'EOF'
${{ toJSON(github) }}
EOF
- uses: https://data.forgejo.org/actions/git-backporting@v4.8.5
- uses: https://data.forgejo.org/actions/git-backporting@v4.8.4
with:
target-branch-pattern: "^backport/(?<target>(v.*))$"
strategy: ort

View file

@ -45,7 +45,7 @@ jobs:
- uses: https://data.forgejo.org/actions/setup-node@v4
with:
node-version: 22
node-version: 20
- uses: https://data.forgejo.org/actions/setup-go@v5
with:
@ -164,7 +164,7 @@ jobs:
- name: build container & release
if: ${{ secrets.TOKEN != '' }}
uses: https://data.forgejo.org/forgejo/forgejo-build-publish/build@v5.3.5
uses: https://data.forgejo.org/forgejo/forgejo-build-publish/build@v5.3.4
with:
forgejo: "${{ env.GITHUB_SERVER_URL }}"
owner: "${{ env.GITHUB_REPOSITORY_OWNER }}"
@ -183,7 +183,7 @@ jobs:
- name: build rootless container
if: ${{ secrets.TOKEN != '' }}
uses: https://data.forgejo.org/forgejo/forgejo-build-publish/build@v5.3.5
uses: https://data.forgejo.org/forgejo/forgejo-build-publish/build@v5.3.4
with:
forgejo: "${{ env.GITHUB_SERVER_URL }}"
owner: "${{ env.GITHUB_REPOSITORY_OWNER }}"

View file

@ -35,7 +35,7 @@ jobs:
)
runs-on: docker
container:
image: data.forgejo.org/oci/node:22-bookworm
image: data.forgejo.org/oci/node:20-bookworm
steps:
- uses: https://data.forgejo.org/actions/checkout@v4
with:

View file

@ -9,7 +9,7 @@ jobs:
if: vars.ROLE == 'forgejo-integration'
runs-on: docker
container:
image: 'data.forgejo.org/oci/node:22-bookworm'
image: 'data.forgejo.org/oci/node:20-bookworm'
steps:
- name: apt install curl jq

View file

@ -16,7 +16,7 @@ jobs:
if: vars.ROLE == 'forgejo-coding'
runs-on: docker
container:
image: 'data.forgejo.org/oci/node:22-bookworm'
image: 'data.forgejo.org/oci/node:20-bookworm'
steps:
- name: Debug output
run: |
@ -31,7 +31,7 @@ jobs:
|| contains(toJSON(github.event.pull_request.labels), 'test/manual')
)
run: |
echo "A team member must set the label to either 'present', 'not-needed' or 'manual'."
echo "Test label must be set to either 'present', 'not-needed' or 'manual'."
exit 1
- name: Missing manual test instructions
if: >

View file

@ -11,7 +11,7 @@ jobs:
if: ${{ secrets.MIRROR_TOKEN != '' }}
runs-on: docker
container:
image: 'data.forgejo.org/oci/node:22-bookworm'
image: 'data.forgejo.org/oci/node:20-bookworm'
steps:
- name: git push {v*/,}forgejo
run: |

View file

@ -2,8 +2,6 @@
#
# See also https://forgejo.org/docs/next/contributor/release/#stable-release-process
#
# TOKEN_NEXT_DIGEST is a token with write repository access to https://invisible.forgejo.org/infrastructure/next-digest issued by https://invisible.forgejo.org/forgejo-next-digest
#
# https://codeberg.org/forgejo-experimental/forgejo
#
# Copies a release from codeberg.org/forgejo-integration to codeberg.org/forgejo-experimental
@ -16,7 +14,7 @@
# vars.DOER: forgejo-experimental-ci
# secrets.TOKEN: <generated from codeberg.org/forgejo-experimental-ci>
#
# http://invisible.forgejo.org/forgejo/forgejo
# http://private.forgejo.org/forgejo/forgejo
#
# Copies & sign a release from codeberg.org/forgejo-integration to codeberg.org/forgejo
#
@ -44,7 +42,7 @@ jobs:
- uses: https://data.forgejo.org/actions/checkout@v4
- name: copy & sign
uses: https://data.forgejo.org/forgejo/forgejo-build-publish/publish@v5.3.5
uses: https://data.forgejo.org/forgejo/forgejo-build-publish/publish@v5.3.4
with:
from-forgejo: ${{ vars.FORGEJO }}
to-forgejo: ${{ vars.FORGEJO }}
@ -63,14 +61,14 @@ jobs:
- name: get trigger mirror issue
id: mirror
uses: https://data.forgejo.org/infrastructure/issue-action/get@v1.3.0
uses: https://data.forgejo.org/infrastructure/issue-action/get@v1.1.0
with:
forgejo: https://code.forgejo.org
repository: forgejo/forgejo
labels: mirror-trigger
- name: trigger the mirror
uses: https://data.forgejo.org/infrastructure/issue-action/set@v1.3.0
uses: https://data.forgejo.org/infrastructure/issue-action/set@v1.1.0
with:
forgejo: https://code.forgejo.org
repository: forgejo/forgejo
@ -82,7 +80,7 @@ jobs:
- name: upgrade v*.next.forgejo.org
uses: https://data.forgejo.org/infrastructure/next-digest@v1.1.0
with:
url: https://placeholder:${{ secrets.TOKEN_NEXT_DIGEST }}@invisible.forgejo.org/infrastructure/next-digest
url: https://placeholder:${{ secrets.TOKEN_NEXT_DIGEST }}@code.forgejo.org/infrastructure/next-digest
ref_name: '${{ github.ref_name }}'
image: 'codeberg.org/forgejo-experimental/forgejo'
tag_suffix: '-rootless'

View file

@ -4,15 +4,12 @@ on:
schedule:
- cron: '@daily'
env:
RNA_VERSION: v1.2.5 # renovate: datasource=gitea-releases depName=forgejo/release-notes-assistant registryUrl=https://code.forgejo.org
jobs:
release-notes:
if: vars.ROLE == 'forgejo-coding'
runs-on: docker
container:
image: 'data.forgejo.org/oci/node:22-bookworm'
image: 'data.forgejo.org/oci/node:20-bookworm'
steps:
- uses: https://data.forgejo.org/actions/checkout@v4
@ -32,5 +29,5 @@ jobs:
set -x
curl -sS $GITHUB_SERVER_URL/api/v1/repos/$GITHUB_REPOSITORY/milestones?state=open | jq -r '.[] | .title' | while read forgejo version ; do
milestone="$forgejo $version"
go run code.forgejo.org/forgejo/release-notes-assistant@$RNA_VERSION --config .release-notes-assistant.yaml --storage milestone --storage-location "$milestone" --forgejo-url $GITHUB_SERVER_URL --repository $GITHUB_REPOSITORY --token ${{ secrets.RELEASE_NOTES_ASSISTANT_TOKEN }} release $version
go run code.forgejo.org/forgejo/release-notes-assistant@v1.1.1 --config .release-notes-assistant.yaml --storage milestone --storage-location "$milestone" --forgejo-url $GITHUB_SERVER_URL --repository $GITHUB_REPOSITORY --token ${{ secrets.RELEASE_NOTES_ASSISTANT_TOKEN }} release $version
done

View file

@ -7,15 +7,12 @@ on:
- synchronize
- labeled
env:
RNA_VERSION: v1.2.5 # renovate: datasource=gitea-releases depName=forgejo/release-notes-assistant registryUrl=https://code.forgejo.org
jobs:
release-notes:
if: ( vars.ROLE == 'forgejo-coding' ) && contains(github.event.pull_request.labels.*.name, 'worth a release-note')
runs-on: docker
container:
image: 'data.forgejo.org/oci/node:22-bookworm'
image: 'data.forgejo.org/oci/node:20-bookworm'
steps:
- uses: https://data.forgejo.org/actions/checkout@v4
@ -41,4 +38,4 @@ jobs:
- name: release-notes-assistant preview
run: |
go run code.forgejo.org/forgejo/release-notes-assistant@$RNA_VERSION --config .release-notes-assistant.yaml --storage pr --storage-location ${{ github.event.pull_request.number }} --forgejo-url $GITHUB_SERVER_URL --repository $GITHUB_REPOSITORY --token ${{ secrets.RELEASE_NOTES_ASSISTANT_TOKEN }} preview ${{ github.event.pull_request.number }}
go run code.forgejo.org/forgejo/release-notes-assistant@v1.1.1 --config .release-notes-assistant.yaml --storage pr --storage-location ${{ github.event.pull_request.number }} --forgejo-url $GITHUB_SERVER_URL --repository $GITHUB_REPOSITORY --token ${{ secrets.RELEASE_NOTES_ASSISTANT_TOKEN }} preview ${{ github.event.pull_request.number }}

View file

@ -18,9 +18,6 @@ on:
env:
RENOVATE_DRY_RUN: ${{ (github.event_name != 'schedule' && github.ref_name != github.event.repository.default_branch) && 'full' || '' }}
RENOVATE_REPOSITORIES: ${{ github.repository }}
# fix because 10.0.0-58-7e1df53+gitea-1.22.0 < 10.0.0 for semver
# and codeberg api returns such versions from `git describe --tags`
# RENOVATE_X_PLATFORM_VERSION: 10.0.0+gitea-1.22.0 currently not needed
jobs:
renovate:
@ -28,7 +25,7 @@ jobs:
runs-on: docker
container:
image: data.forgejo.org/renovate/renovate:41.17.2
image: data.forgejo.org/forgejo-contrib/renovate:39.69.2
steps:
- name: Load renovate repo cache

View file

@ -1,65 +0,0 @@
#
# Additional integration tests designed to run once a day when
# `mirror.yml` pushes to https://codeberg.org/forgejo-integration/forgejo
# and send a notification via email should they fail.
#
# For debug purposes:
#
# - uncomment [on].pull_request
# - swap 'forgejo-integration' and 'forgejo-coding'
# - open a pull request at https://codeberg.org/forgejo/forgejo and fix things
# - swap 'forgejo-integration' and 'forgejo-coding'
# - comment [on].pull_request
#
name: testing-integration
on:
# pull_request:
push:
tags: 'v[0-9]+.[0-9]+.*'
branches:
- 'forgejo'
- 'v*/forgejo'
jobs:
test-unit:
# if: vars.ROLE == 'forgejo-coding'
if: vars.ROLE == 'forgejo-integration'
runs-on: docker
container:
image: 'data.forgejo.org/oci/node:22-bookworm'
options: --tmpfs /tmp:exec,noatime
steps:
- uses: https://data.forgejo.org/actions/checkout@v4
- uses: ./.forgejo/workflows-composite/setup-env
- name: install git 2.34.1 and git-lfs 3.0.2
uses: ./.forgejo/workflows-composite/install-minimum-git-version
- uses: ./.forgejo/workflows-composite/build-backend
- run: |
su forgejo -c 'make test-backend test-check'
timeout-minutes: 120
env:
RACE_ENABLED: 'true'
TAGS: bindata
test-sqlite:
# if: vars.ROLE == 'forgejo-coding'
if: vars.ROLE == 'forgejo-integration'
runs-on: docker
container:
image: 'data.forgejo.org/oci/node:22-bookworm'
options: --tmpfs /tmp:exec,noatime
steps:
- uses: https://data.forgejo.org/actions/checkout@v4
- uses: ./.forgejo/workflows-composite/setup-env
- name: install git 2.34.1 and git-lfs 3.0.2
uses: ./.forgejo/workflows-composite/install-minimum-git-version
- uses: ./.forgejo/workflows-composite/build-backend
- run: |
su forgejo -c 'make test-sqlite-migration test-sqlite'
timeout-minutes: 120
env:
TAGS: sqlite sqlite_unlock_notify
RACE_ENABLED: true
TEST_TAGS: sqlite sqlite_unlock_notify
USE_REPO_TEST_DIR: 1

View file

@ -13,7 +13,7 @@ jobs:
if: vars.ROLE == 'forgejo-coding' || vars.ROLE == 'forgejo-testing'
runs-on: docker
container:
image: 'data.forgejo.org/oci/node:22-bookworm'
image: 'data.forgejo.org/oci/node:20-bookworm'
options: --tmpfs /tmp:exec,noatime
steps:
- name: event info
@ -24,13 +24,13 @@ jobs:
- uses: https://data.forgejo.org/actions/checkout@v4
- uses: ./.forgejo/workflows-composite/setup-env
- run: su forgejo -c 'make deps-backend deps-tools'
- run: su forgejo -c 'make --always-make -j$(nproc) lint-backend tidy-check swagger-check lint-swagger fmt-check swagger-validate' # ensure the "go-licenses" make target runs
- run: su forgejo -c 'make --always-make -j$(nproc) lint-backend tidy-check swagger-check fmt-check swagger-validate' # ensure the "go-licenses" make target runs
- uses: ./.forgejo/workflows-composite/build-backend
frontend-checks:
if: vars.ROLE == 'forgejo-coding' || vars.ROLE == 'forgejo-testing'
runs-on: docker
container:
image: 'data.forgejo.org/oci/node:22-bookworm'
image: 'data.forgejo.org/oci/node:20-bookworm'
options: --tmpfs /tmp:exec,noatime
steps:
- uses: https://data.forgejo.org/actions/checkout@v4
@ -55,7 +55,7 @@ jobs:
runs-on: docker
needs: [backend-checks, frontend-checks]
container:
image: 'data.forgejo.org/oci/node:22-bookworm'
image: 'data.forgejo.org/oci/node:20-bookworm'
options: --tmpfs /tmp:exec,noatime
services:
elasticsearch:
@ -91,7 +91,6 @@ jobs:
RACE_ENABLED: 'true'
TAGS: bindata
TEST_ELASTICSEARCH_URL: http://elasticsearch:9200
TEST_MINIO_ENDPOINT: minio:9000
test-e2e:
if: vars.ROLE == 'forgejo-coding' || vars.ROLE == 'forgejo-testing'
runs-on: docker
@ -115,14 +114,9 @@ jobs:
run: |
su forgejo -c 'make deps-frontend frontend'
- uses: ./.forgejo/workflows-composite/build-backend
- name: Decide to run all tests
id: run-all
if: contains(github.event.pull_request.labels.*.name, 'run-all-playwright-tests') || contains(github.event.pull_request.title, 'playwright')
run: |
echo "all=1" >> "$GITHUB_OUTPUT"
- name: Get changed files
id: changed-files
uses: https://data.forgejo.org/tj-actions/changed-files@v46
uses: https://data.forgejo.org/tj-actions/changed-files@v45
with:
separator: '\n'
- run: |
@ -132,7 +126,6 @@ jobs:
USE_REPO_TEST_DIR: 1
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
CHANGED_FILES: ${{steps.changed-files.outputs.all_changed_files}}
RUN_ALL: ${{steps.run-all.all}}
- name: Upload test artifacts on failure
if: failure()
uses: https://data.forgejo.org/forgejo/upload-artifact@v4
@ -145,7 +138,7 @@ jobs:
runs-on: docker
needs: [backend-checks, frontend-checks, test-unit]
container:
image: 'data.forgejo.org/oci/node:22-bookworm'
image: 'data.forgejo.org/oci/node:20-bookworm'
options: --tmpfs /tmp:exec,noatime
name: ${{ format('test-remote-cacher ({0})', matrix.cacher.name) }}
strategy:
@ -187,7 +180,7 @@ jobs:
runs-on: docker
needs: [backend-checks, frontend-checks]
container:
image: 'data.forgejo.org/oci/node:22-bookworm'
image: 'data.forgejo.org/oci/node:20-bookworm'
options: --tmpfs /tmp:exec,noatime
services:
mysql:
@ -218,7 +211,7 @@ jobs:
runs-on: docker
needs: [backend-checks, frontend-checks]
container:
image: 'data.forgejo.org/oci/node:22-bookworm'
image: 'data.forgejo.org/oci/node:20-bookworm'
options: --tmpfs /tmp:exec,noatime
services:
minio:
@ -230,7 +223,7 @@ jobs:
ldap:
image: data.forgejo.org/oci/test-openldap:latest
pgsql:
image: data.forgejo.org/oci/bitnami/postgresql:16
image: data.forgejo.org/oci/bitnami/postgresql:15
env:
POSTGRESQL_DATABASE: test
POSTGRESQL_PASSWORD: postgres
@ -257,7 +250,7 @@ jobs:
runs-on: docker
needs: [backend-checks, frontend-checks]
container:
image: 'data.forgejo.org/oci/node:22-bookworm'
image: 'data.forgejo.org/oci/node:20-bookworm'
options: --tmpfs /tmp:exec,noatime
steps:
- uses: https://data.forgejo.org/actions/checkout@v4
@ -285,7 +278,7 @@ jobs:
- test-remote-cacher
- test-unit
container:
image: 'data.forgejo.org/oci/node:22-bookworm'
image: 'data.forgejo.org/oci/node:20-bookworm'
options: --tmpfs /tmp:exec,noatime
steps:
- uses: https://data.forgejo.org/actions/checkout@v4

2
.gitignore vendored
View file

@ -37,7 +37,6 @@ _testmain.go
*coverage.out
coverage.all
coverage/
cpu.out
/modules/migration/bindata.go
@ -57,7 +56,6 @@ cpu.out
/gitea-vet
/debug
/integrations.test
/forgejo
/bin
/dist

View file

@ -1,9 +1,7 @@
version: "2"
output:
sort-order:
- file
linters:
default: none
enable-all: false
disable-all: true
fast: false
enable:
- bidichk
- depguard
@ -11,37 +9,37 @@ linters:
- errcheck
- forbidigo
- gocritic
- gofmt
- gofumpt
- gosimple
- govet
- ineffassign
- nakedret
- nolintlint
- revive
- staticcheck
- stylecheck
- tenv
- testifylint
- typecheck
- unconvert
- unparam
- unused
- usetesting
- unparam
- wastedassign
settings:
depguard:
rules:
main:
deny:
- pkg: encoding/json
desc: use gitea's modules/json instead of encoding/json
- pkg: github.com/unknwon/com
desc: use gitea's util and replacements
- pkg: io/ioutil
desc: use os or io instead
- pkg: golang.org/x/exp
desc: it's experimental and unreliable
- pkg: forgejo.org/modules/git/internal
desc: do not use the internal package, use AddXxx function instead
- pkg: gopkg.in/ini.v1
desc: do not use the ini package, use gitea's config system instead
- pkg: github.com/minio/sha256-simd
desc: use crypto/sha256 instead, see https://codeberg.org/forgejo/forgejo/pulls/1528
run:
timeout: 10m
output:
sort-results: true
sort-order: [file]
show-stats: true
linters-settings:
stylecheck:
checks: ["all", "-ST1005", "-ST1003"]
nakedret:
max-func-lines: 0
gocritic:
disabled-checks:
- ifElseChain
@ -81,85 +79,72 @@ linters:
- name: var-naming
- name: redefines-builtin-id
disabled: true
staticcheck:
checks:
- all
gofumpt:
extra-rules: true
depguard:
rules:
main:
deny:
- pkg: encoding/json
desc: use gitea's modules/json instead of encoding/json
- pkg: github.com/unknwon/com
desc: use gitea's util and replacements
- pkg: io/ioutil
desc: use os or io instead
- pkg: golang.org/x/exp
desc: it's experimental and unreliable
- pkg: code.gitea.io/gitea/modules/git/internal
desc: do not use the internal package, use AddXxx function instead
- pkg: gopkg.in/ini.v1
desc: do not use the ini package, use gitea's config system instead
- pkg: github.com/minio/sha256-simd
desc: use crypto/sha256 instead, see https://codeberg.org/forgejo/forgejo/pulls/1528
testifylint:
disable:
- go-require
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
rules:
- linters:
- nolintlint
path: models/db/sql_postgres_with_schema.go
- linters:
- dupl
- errcheck
- gocyclo
- gosec
- staticcheck
- unparam
path: _test\.go
- linters:
- dupl
- errcheck
- gocyclo
- gosec
path: models/migrations/v
- linters:
- forbidigo
path: cmd
- linters:
- dupl
text: (?i)webhook
- linters:
- gocritic
text: (?i)`ID' should not be capitalized
- linters:
- deadcode
- unused
text: (?i)swagger
- linters:
- staticcheck
text: (?i)argument x is overwritten before first use
- linters:
- gocritic
text: '(?i)commentFormatting: put a space between `//` and comment text'
- linters:
- gocritic
text: '(?i)exitAfterDefer:'
- linters:
- staticcheck
text: "(ST1005|ST1003|QF1001):"
paths:
- node_modules
- public
- web_src
- third_party$
- builtin$
- examples$
issues:
max-issues-per-linter: 0
max-same-issues: 0
formatters:
enable:
- gofmt
- gofumpt
settings:
gofumpt:
extra-rules: true
exclusions:
generated: lax
paths:
- node_modules
- public
- web_src
- third_party$
- builtin$
- examples$
exclude-dirs: [node_modules, public, web_src]
exclude-case-sensitive: true
exclude-rules:
- path: models/db/sql_postgres_with_schema.go
linters:
- nolintlint
- path: _test\.go
linters:
- gocyclo
- errcheck
- dupl
- gosec
- unparam
- staticcheck
- path: models/migrations/v
linters:
- gocyclo
- errcheck
- dupl
- gosec
- path: cmd
linters:
- forbidigo
- text: "webhook"
linters:
- dupl
- text: "`ID' should not be capitalized"
linters:
- gocritic
- text: "swagger"
linters:
- unused
- deadcode
- text: "argument x is overwritten before first use"
linters:
- staticcheck
- text: "commentFormatting: put a space between `//` and comment text"
linters:
- gocritic
- text: "exitAfterDefer:"
linters:
- gocritic

View file

@ -36,6 +36,10 @@ GARGS = "--no-print-directory"
JARG = -j$(.MAKE.JOBS)
.endif
# bmake prefers out-of-source builds and tries to cd into ./obj (among others)
# where possible. GNU Make doesn't, so override that value.
.OBJDIR: ./
# The GNU convention is to use the lowercased `prefix` variable/macro to
# specify the installation directory. Humor them.
GPREFIX =
@ -44,12 +48,11 @@ GPREFIX =
.endif
.BEGIN: .SILENT
which $(GMAKE) >/dev/null || (printf "Error: GNU Make is required!\n\n" 1>&2 && false)
which $(GMAKE) || (printf "Error: GNU Make is required!\n\n" 1>&2 && false)
.PHONY: EMPTY
EMPTY: .SILENT
$(GMAKE) $(GPREFIX) $(GARGS) $(JARG)
.PHONY: FRC
$(.TARGETS): FRC
$(GMAKE) $(GPREFIX) $(GARGS) $(.TARGETS:S,.DONE,,) $(JARG)
.PHONY: $(.TARGETS)
$(.TARGETS): .SILENT
$(GMAKE) $(GPREFIX) $(GARGS) $(JARG) $@
.DONE .DEFAULT: .SILENT
$(GMAKE) $(GPREFIX) $(GARGS) $(.TARGETS:S,.DONE,,) $(JARG)

View file

@ -9,11 +9,10 @@
# Files related to frontend development.
# Javascript and CSS code.
web_src/.* @beowulf @gusted
web_src/css/.* @0ko
web_src/.* @caesar @crystal @gusted
# HTML templates used by the backend.
templates/.* @beowulf @gusted
templates/.* @caesar @crystal @gusted
## the issue sidebar was touched by fnetx
templates/repo/issue/view_content/sidebar.* @fnetx
@ -34,9 +33,8 @@ models/.* @gusted
# for code that lives in here.
routers/.* @gusted
# Let locale changes be checked by the translation team.
options/locale/.* @0ko
options/locale_next/.* @0ko
# Let new strings be checked by the translation team.
options/locale/locale_en-US.ini @0ko
# Personal interest
.*/webhook.* @oliverpool

View file

@ -1,9 +1,9 @@
FROM --platform=$BUILDPLATFORM data.forgejo.org/oci/xx AS xx
FROM --platform=$BUILDPLATFORM data.forgejo.org/oci/golang:1.24-alpine3.22 AS build-env
FROM --platform=$BUILDPLATFORM data.forgejo.org/oci/golang:1.23-alpine3.20 as build-env
ARG GOPROXY
ENV GOPROXY=${GOPROXY:-https://proxy.golang.org,direct}
ENV GOPROXY=${GOPROXY:-direct}
ARG RELEASE_VERSION
ARG TAGS="sqlite sqlite_unlock_notify"
@ -30,13 +30,13 @@ RUN cp /*-alpine-linux-musl*/lib/ld-musl-*.so.1 /lib || true
RUN apk --no-cache add build-base git nodejs npm
COPY . ${GOPATH}/src/forgejo.org
WORKDIR ${GOPATH}/src/forgejo.org
COPY . ${GOPATH}/src/code.gitea.io/gitea
WORKDIR ${GOPATH}/src/code.gitea.io/gitea
RUN make clean-no-bindata
RUN make clean
RUN make frontend
RUN go build contrib/environment-to-ini/environment-to-ini.go && xx-verify environment-to-ini
RUN LDFLAGS="-buildid=" make FORGEJO_GENERATE_SKIP_HASH=true RELEASE_VERSION=$RELEASE_VERSION GOFLAGS="-trimpath" go-check generate-backend static-executable && xx-verify gitea
RUN LDFLAGS="-buildid=" make RELEASE_VERSION=$RELEASE_VERSION GOFLAGS="-trimpath" go-check generate-backend static-executable && xx-verify gitea
# Copy local files
COPY docker/root /tmp/local
@ -47,11 +47,11 @@ RUN chmod 755 /tmp/local/usr/bin/entrypoint \
/tmp/local/etc/s6/gitea/* \
/tmp/local/etc/s6/openssh/* \
/tmp/local/etc/s6/.s6-svscan/* \
/go/src/forgejo.org/gitea \
/go/src/forgejo.org/environment-to-ini
RUN chmod 644 /go/src/forgejo.org/contrib/autocompletion/bash_autocomplete
/go/src/code.gitea.io/gitea/gitea \
/go/src/code.gitea.io/gitea/environment-to-ini
RUN chmod 644 /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete
FROM data.forgejo.org/oci/alpine:3.22
FROM data.forgejo.org/oci/alpine:3.20
ARG RELEASE_VERSION
LABEL maintainer="contact@forgejo.org" \
org.opencontainers.image.authors="Forgejo" \
@ -98,11 +98,11 @@ ENV GITEA_CUSTOM=/data/gitea
VOLUME ["/data"]
ENTRYPOINT ["/usr/bin/entrypoint"]
CMD ["/usr/bin/s6-svscan", "/etc/s6"]
CMD ["/bin/s6-svscan", "/etc/s6"]
COPY --from=build-env /tmp/local /
RUN cd /usr/local/bin ; ln -s gitea forgejo
COPY --from=build-env /go/src/forgejo.org/gitea /app/gitea/gitea
COPY --from=build-env /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
RUN ln -s /app/gitea/gitea /app/gitea/forgejo-cli
COPY --from=build-env /go/src/forgejo.org/environment-to-ini /usr/local/bin/environment-to-ini
COPY --from=build-env /go/src/forgejo.org/contrib/autocompletion/bash_autocomplete /etc/profile.d/gitea_bash_autocomplete.sh
COPY --from=build-env /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini
COPY --from=build-env /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete /etc/profile.d/gitea_bash_autocomplete.sh

View file

@ -1,9 +1,9 @@
FROM --platform=$BUILDPLATFORM data.forgejo.org/oci/xx AS xx
FROM --platform=$BUILDPLATFORM data.forgejo.org/oci/golang:1.24-alpine3.22 AS build-env
FROM --platform=$BUILDPLATFORM data.forgejo.org/oci/golang:1.23-alpine3.20 as build-env
ARG GOPROXY
ENV GOPROXY=${GOPROXY:-https://proxy.golang.org,direct}
ENV GOPROXY=${GOPROXY:-direct}
ARG RELEASE_VERSION
ARG TAGS="sqlite sqlite_unlock_notify"
@ -30,13 +30,13 @@ RUN cp /*-alpine-linux-musl*/lib/ld-musl-*.so.1 /lib || true
RUN apk --no-cache add build-base git nodejs npm
COPY . ${GOPATH}/src/forgejo.org
WORKDIR ${GOPATH}/src/forgejo.org
COPY . ${GOPATH}/src/code.gitea.io/gitea
WORKDIR ${GOPATH}/src/code.gitea.io/gitea
RUN make clean-no-bindata
RUN make clean
RUN make frontend
RUN go build contrib/environment-to-ini/environment-to-ini.go && xx-verify environment-to-ini
RUN make FORGEJO_GENERATE_SKIP_HASH=true RELEASE_VERSION=$RELEASE_VERSION go-check generate-backend static-executable && xx-verify gitea
RUN make RELEASE_VERSION=$RELEASE_VERSION go-check generate-backend static-executable && xx-verify gitea
# Copy local files
COPY docker/rootless /tmp/local
@ -45,11 +45,11 @@ COPY docker/rootless /tmp/local
RUN chmod 755 /tmp/local/usr/local/bin/docker-entrypoint.sh \
/tmp/local/usr/local/bin/docker-setup.sh \
/tmp/local/usr/local/bin/gitea \
/go/src/forgejo.org/gitea \
/go/src/forgejo.org/environment-to-ini
RUN chmod 644 /go/src/forgejo.org/contrib/autocompletion/bash_autocomplete
/go/src/code.gitea.io/gitea/gitea \
/go/src/code.gitea.io/gitea/environment-to-ini
RUN chmod 644 /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete
FROM data.forgejo.org/oci/alpine:3.22
FROM data.forgejo.org/oci/alpine:3.20
ARG RELEASE_VERSION
LABEL maintainer="contact@forgejo.org" \
org.opencontainers.image.authors="Forgejo" \
@ -91,10 +91,10 @@ RUN chown git:git /var/lib/gitea /etc/gitea
COPY --from=build-env /tmp/local /
RUN cd /usr/local/bin ; ln -s gitea forgejo
COPY --from=build-env --chown=root:root /go/src/forgejo.org/gitea /app/gitea/gitea
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
RUN ln -s /app/gitea/gitea /app/gitea/forgejo-cli
COPY --from=build-env --chown=root:root /go/src/forgejo.org/environment-to-ini /usr/local/bin/environment-to-ini
COPY --from=build-env /go/src/forgejo.org/contrib/autocompletion/bash_autocomplete /etc/profile.d/gitea_bash_autocomplete.sh
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini
COPY --from=build-env /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete /etc/profile.d/gitea_bash_autocomplete.sh
#git:git
USER 1000:1000

230
Makefile
View file

@ -16,7 +16,7 @@ else
DIST := dist
DIST_DIRS := $(DIST)/binaries $(DIST)/release
IMPORT := forgejo.org
IMPORT := code.gitea.io/gitea
GO ?= $(shell go env GOROOT)/bin/go
SHASUM ?= shasum -a 256
@ -37,17 +37,19 @@ endif
XGO_VERSION := go-1.21.x
AIR_PACKAGE ?= github.com/air-verse/air@v1 # renovate: datasource=go
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3.3.0 # renovate: datasource=go
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.8.0 # renovate: datasource=go
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.6 # renovate: datasource=go
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3.0.3 # renovate: datasource=go
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.7.0 # renovate: datasource=go
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.2 # renovate: datasource=go
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11 # renovate: datasource=go
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/misspell@v0.6.0 # renovate: datasource=go
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.31.0 # renovate: datasource=go
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.6.0 # renovate: datasource=go
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 # renovate: datasource=go
DEADCODE_PACKAGE ?= golang.org/x/tools/cmd/deadcode@v0.34.0 # renovate: datasource=go
GOMOCK_PACKAGE ?= go.uber.org/mock/mockgen@v0.5.2 # renovate: datasource=go
RENOVATE_NPM_PACKAGE ?= renovate@41.17.2 # renovate: datasource=docker packageName=data.forgejo.org/renovate/renovate
DEADCODE_PACKAGE ?= golang.org/x/tools/cmd/deadcode@v0.28.0 # renovate: datasource=go
GOMOCK_PACKAGE ?= go.uber.org/mock/mockgen@v0.4.0 # renovate: datasource=go
GOPLS_PACKAGE ?= golang.org/x/tools/gopls@v0.17.0 # renovate: datasource=go
RENOVATE_NPM_PACKAGE ?= renovate@39.82.1 # renovate: datasource=docker packageName=code.forgejo.org/forgejo-contrib/renovate
# https://github.com/disposable-email-domains/disposable-email-domains/commits/main/
DISPOSABLE_EMAILS_SHA ?= 0c27e671231d27cf66370034d7f6818037416989 # renovate: ...
@ -57,8 +59,20 @@ ifeq ($(HAS_GO), yes)
CGO_CFLAGS ?= $(shell $(GO) env CGO_CFLAGS) $(CGO_EXTRA_CFLAGS)
endif
ifeq ($(GOOS),windows)
IS_WINDOWS := yes
else ifeq ($(patsubst Windows%,Windows,$(OS)),Windows)
ifeq ($(GOOS),)
IS_WINDOWS := yes
endif
endif
ifeq ($(IS_WINDOWS),yes)
GOFLAGS := -v -buildmode=exe
EXECUTABLE ?= gitea.exe
else
GOFLAGS := -v
EXECUTABLE ?= gitea
endif
ifeq ($(shell sed --version 2>/dev/null | grep -q GNU && echo gnu),gnu)
SED_INPLACE := sed -i
@ -90,36 +104,38 @@ else
FORGEJO_VERSION_API ?= $(GITEA_VERSION)+${GITEA_COMPATIBILITY}
else
# drop the "g" prefix prepended by git describe to the commit hash
FORGEJO_VERSION ?= $(shell git describe --exclude '*-test' --tags --always 2>/dev/null | sed 's/^v//' | sed 's/\-g/-/')
ifneq ($(FORGEJO_VERSION),)
ifeq ($(findstring $(GITEA_COMPATIBILITY),$(FORGEJO_VERSION)),)
FORGEJO_VERSION := $(FORGEJO_VERSION)+$(GITEA_COMPATIBILITY)
endif
endif
FORGEJO_VERSION ?= $(shell git describe --exclude '*-test' --tags --always | sed 's/^v//' | sed 's/\-g/-/')+${GITEA_COMPATIBILITY}
endif
endif
FORGEJO_VERSION_MAJOR=$(shell echo $(FORGEJO_VERSION) | sed -e 's/\..*//')
FORGEJO_VERSION_MINOR=$(shell echo $(FORGEJO_VERSION) | sed -E -e 's/^([0-9]+\.[0-9]+).*/\1/')
show-version-full:
@echo ${FORGEJO_VERSION}
show-version-major:
@echo ${FORGEJO_VERSION_MAJOR}
show-version-minor:
@echo ${FORGEJO_VERSION_MINOR}
RELEASE_VERSION ?= ${FORGEJO_VERSION}
VERSION ?= ${RELEASE_VERSION}
FORGEJO_VERSION_API ?= ${FORGEJO_VERSION}
# Strip binaries by default to reduce size, allow overriding for debugging
STRIP ?= 1
ifeq ($(STRIP),1)
LDFLAGS := $(LDFLAGS) -s -w
endif
show-version-api:
@echo ${FORGEJO_VERSION_API}
LDFLAGS := $(LDFLAGS) -X "main.ReleaseVersion=$(RELEASE_VERSION)" -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(FORGEJO_VERSION)" -X "main.Tags=$(TAGS)" -X "main.ForgejoVersion=$(FORGEJO_VERSION_API)"
LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64
ifeq ($(HAS_GO), yes)
GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list forgejo.org/models/migrations/...) $(shell $(GO) list forgejo.org/models/forgejo_migrations/...) forgejo.org/tests/integration/migration-test forgejo.org/tests forgejo.org/tests/integration forgejo.org/tests/e2e,$(shell $(GO) list ./...))
GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/migrations/...) $(shell $(GO) list code.gitea.io/gitea/models/forgejo_migrations/...) code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration code.gitea.io/gitea/tests/e2e,$(shell $(GO) list ./...))
endif
REMOTE_CACHER_MODULES ?= cache nosql session queue
GO_TEST_REMOTE_CACHER_PACKAGES ?= $(addprefix forgejo.org/modules/,$(REMOTE_CACHER_MODULES))
GO_TEST_REMOTE_CACHER_PACKAGES ?= $(addprefix code.gitea.io/gitea/modules/,$(REMOTE_CACHER_MODULES))
FOMANTIC_WORK_DIR := web_src/fomantic
@ -128,7 +144,7 @@ WEBPACK_CONFIGS := webpack.config.js tailwind.config.js
WEBPACK_DEST := public/assets/js/index.js public/assets/css/index.css
WEBPACK_DEST_ENTRIES := public/assets/js public/assets/css public/assets/fonts
BINDATA_DEST := modules/migration/bindata.go modules/public/bindata.go modules/options/bindata.go modules/templates/bindata.go
BINDATA_DEST := modules/public/bindata.go modules/options/bindata.go modules/templates/bindata.go
BINDATA_HASH := $(addsuffix .hash,$(BINDATA_DEST))
GENERATED_GO_DEST := modules/charset/invisible_gen.go modules/charset/ambiguous_gen.go
@ -152,7 +168,7 @@ GO_DIRS := build cmd models modules routers services tests
WEB_DIRS := web_src/js web_src/css
STYLELINT_FILES := web_src/css web_src/js/components/*.vue
SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) docs/content templates options/locale/locale_en-US.ini .github $(wildcard *.go *.js *.ts *.vue *.md *.yml *.yaml)
SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) docs/content templates options/locale/locale_en-US.ini .github $(wildcard *.go *.js *.ts *.vue *.md *.yml *.yaml *.toml)
GO_SOURCES := $(wildcard *.go)
GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go" ! -path modules/options/bindata.go ! -path modules/public/bindata.go ! -path modules/templates/bindata.go)
@ -160,7 +176,7 @@ GO_SOURCES += $(GENERATED_GO_DEST)
GO_SOURCES_NO_BINDATA := $(GO_SOURCES)
ifeq ($(HAS_GO), yes)
MIGRATION_PACKAGES := $(shell $(GO) list forgejo.org/models/migrations/... forgejo.org/models/forgejo_migrations/...)
MIGRATION_PACKAGES := $(shell $(GO) list code.gitea.io/gitea/models/migrations/... code.gitea.io/gitea/models/forgejo_migrations/...)
endif
ifeq ($(filter $(TAGS_SPLIT),bindata),bindata)
@ -212,22 +228,31 @@ help:
@echo " - deps-frontend install frontend dependencies"
@echo " - deps-backend install backend dependencies"
@echo " - deps-tools install tool dependencies"
@echo " - deps-py install python dependencies"
@echo " - lint lint everything"
@echo " - lint-fix lint everything and fix issues"
@echo " - lint-frontend lint frontend files"
@echo " - lint-frontend-fix lint frontend files and fix issues"
@echo " - lint-backend lint backend files"
@echo " - lint-backend-fix lint backend files and fix issues"
@echo " - lint-codespell lint typos"
@echo " - lint-codespell-fix lint typos and fix them automatically"
@echo " - lint-codespell-fix-i lint typos and fix them interactively"
@echo " - lint-go lint go files"
@echo " - lint-go-fix lint go files and fix issues"
@echo " - lint-go-vet lint go files with vet"
@echo " - lint-go-gopls lint go files with gopls"
@echo " - lint-js lint js files"
@echo " - lint-js-fix lint js files and fix issues"
@echo " - lint-css lint css files"
@echo " - lint-css-fix lint css files and fix issues"
@echo " - lint-md lint markdown files"
@echo " - lint-swagger lint swagger files"
@echo " - lint-templates lint template files"
@echo " - lint-renovate lint renovate files"
@echo " - lint-yaml lint yaml files"
@echo " - lint-spell lint spelling"
@echo " - lint-spell-fix lint spelling and fix issues"
@echo " - checks run various consistency checks"
@echo " - checks-frontend check frontend files"
@echo " - checks-backend check backend files"
@ -258,30 +283,6 @@ help:
@echo " - test-sqlite[\#TestSpecificName] run integration test for sqlite"
@echo " - reproduce-build\#version build a reproducible binary for the specified release version"
.PHONY: verify-version
verify-version:
ifeq ($(FORGEJO_VERSION),)
@echo "Error: Could not determine FORGEJO_VERSION; version file $(STORED_VERSION_FILE) not present and no suitable git tag found"
@echo 'In most cases this likely means you forgot to fetch git tags, you can fix this by executing `git fetch --tags`. If this is not possible and this is part of a custom build process, then you can set a specific version by writing it to $(STORED_VERSION_FILE) (This must be a semver compatible version).'
@false
endif
.PHONY: show-version-full
show-version-full: verify-version
@echo ${FORGEJO_VERSION}
.PHONY: show-version-major
show-version-major: verify-version
@echo ${FORGEJO_VERSION_MAJOR}
.PHONY: show-version-minor
show-version-minor: verify-version
@echo ${FORGEJO_VERSION_MINOR}
.PHONY: show-version-api
show-version-api: verify-version
@echo ${FORGEJO_VERSION_API}
###
# Check system and environment requirements
###
@ -323,12 +324,8 @@ clean-all: clean
rm -rf $(WEBPACK_DEST_ENTRIES) node_modules
.PHONY: clean
clean: clean-no-bindata
rm -rf $(BINDATA_DEST) $(BINDATA_HASH)
.PHONY: clean-no-bindata
clean-no-bindata:
rm -rf $(EXECUTABLE) $(DIST) \
clean:
rm -rf $(EXECUTABLE) $(DIST) $(BINDATA_DEST) $(BINDATA_HASH) \
integrations*.test \
e2e*.test \
tests/integration/gitea-integration-* \
@ -411,10 +408,10 @@ checks-frontend: lockfile-check svg-check
checks-backend: tidy-check swagger-check fmt-check swagger-validate security-check
.PHONY: lint
lint: lint-frontend lint-backend
lint: lint-frontend lint-backend lint-spell
.PHONY: lint-fix
lint-fix: lint-frontend-fix lint-backend-fix
lint-fix: lint-frontend-fix lint-backend-fix lint-spell-fix
.PHONY: lint-frontend
lint-frontend: lint-js lint-css
@ -423,11 +420,23 @@ lint-frontend: lint-js lint-css
lint-frontend-fix: lint-js-fix lint-css-fix
.PHONY: lint-backend
lint-backend: lint-go lint-go-vet lint-editorconfig lint-renovate lint-locale lint-locale-usage lint-disposable-emails
lint-backend: lint-go lint-go-vet lint-editorconfig lint-renovate lint-locale lint-disposable-emails
.PHONY: lint-backend-fix
lint-backend-fix: lint-go-fix lint-go-vet lint-editorconfig lint-disposable-emails-fix
.PHONY: lint-codespell
lint-codespell:
codespell
.PHONY: lint-codespell-fix
lint-codespell-fix:
codespell -w
.PHONY: lint-codespell-fix-i
lint-codespell-fix-i:
codespell -w -i 3 -C 2
.PHONY: lint-js
lint-js: node_modules
npx eslint --color --max-warnings=0
@ -450,23 +459,27 @@ lint-swagger: node_modules
.PHONY: lint-renovate
lint-renovate: node_modules
npx --yes --package $(RENOVATE_NPM_PACKAGE) -- renovate-config-validator > .lint-renovate 2>&1 || true
@if grep --quiet --extended-regexp -e '^( ERROR:)' .lint-renovate ; then cat .lint-renovate ; rm .lint-renovate ; exit 1 ; fi
npx --yes --package $(RENOVATE_NPM_PACKAGE) -- renovate-config-validator --strict > .lint-renovate 2>&1 || true
@if grep --quiet --extended-regexp -e '^( WARN:|ERROR:)' .lint-renovate ; then cat .lint-renovate ; rm .lint-renovate ; exit 1 ; fi
@rm .lint-renovate
.PHONY: lint-locale
lint-locale:
$(GO) run build/lint-locale/lint-locale.go
.PHONY: lint-locale-usage
lint-locale-usage:
$(GO) run build/lint-locale-usage/lint-locale-usage.go
$(GO) run build/lint-locale.go
.PHONY: lint-md
lint-md: node_modules
npx markdownlint docs *.md
RUN_DEADCODE = $(GO) run $(DEADCODE_PACKAGE) -generated=false -f='{{println .Path}}{{range .Funcs}}{{printf "\t%s\n" .Name}}{{end}}{{println}}' -test forgejo.org
.PHONY: lint-spell
lint-spell: lint-codespell
@go run $(MISSPELL_PACKAGE) -error $(SPELLCHECK_FILES)
.PHONY: lint-spell-fix
lint-spell-fix: lint-codespell-fix
@go run $(MISSPELL_PACKAGE) -w $(SPELLCHECK_FILES)
RUN_DEADCODE = $(GO) run $(DEADCODE_PACKAGE) -generated=false -f='{{println .Path}}{{range .Funcs}}{{printf "\t%s\n" .Name}}{{end}}{{println}}' -test code.gitea.io/gitea
.PHONY: lint-go
lint-go:
@ -480,11 +493,23 @@ lint-go-fix:
$(GO) run $(GOLANGCI_LINT_PACKAGE) run $(GOLANGCI_LINT_ARGS) --fix
$(RUN_DEADCODE) > .deadcode-out
# workaround step for the lint-go-windows CI task because 'go run' can not
# have distinct GOOS/GOARCH for its build and run steps
.PHONY: lint-go-windows
lint-go-windows:
@GOOS= GOARCH= $(GO) install $(GOLANGCI_LINT_PACKAGE)
golangci-lint run
.PHONY: lint-go-vet
lint-go-vet:
@echo "Running go vet..."
@$(GO) vet ./...
.PHONY: lint-go-gopls
lint-go-gopls:
@echo "Running gopls check..."
@GO=$(GO) GOPLS_PACKAGE=$(GOPLS_PACKAGE) tools/lint-go-gopls.sh $(GO_SOURCES_NO_BINDATA)
.PHONY: lint-editorconfig
lint-editorconfig:
$(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) templates .forgejo/workflows
@ -497,9 +522,18 @@ lint-disposable-emails:
lint-disposable-emails-fix:
$(GO) run build/generate-disposable-email.go -r $(DISPOSABLE_EMAILS_SHA)
.PHONY: lint-templates
lint-templates: .venv node_modules
@node tools/lint-templates-svg.js
@poetry run djlint $(shell find templates -type f -iname '*.tmpl')
.PHONY: lint-yaml
lint-yaml: .venv
@poetry run yamllint .
.PHONY: security-check
security-check:
go run $(GOVULNCHECK_PACKAGE) -show color ./...
go run $(GOVULNCHECK_PACKAGE) ./...
###
# Development and testing targets
@ -553,7 +587,7 @@ test-check:
.PHONY: test\#%
test\#%:
@echo "Running go test with $(GOTESTFLAGS) -tags '$(TEST_TAGS)'..."
@echo "Running go test with -tags '$(TEST_TAGS)'..."
@$(GOTEST) $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -run $(subst .,/,$*) $(GO_TEST_PACKAGES)
.PHONY: coverage
@ -586,7 +620,7 @@ tidy-check: tidy
go-licenses: $(GO_LICENSE_FILE)
$(GO_LICENSE_FILE): go.mod go.sum
-$(GO) run $(GO_LICENSES_PACKAGE) save . --force --ignore forgejo.org --save_path=$(GO_LICENSE_TMP_DIR) 2>/dev/null
-$(GO) run $(GO_LICENSES_PACKAGE) save . --force --ignore code.gitea.io/gitea --save_path=$(GO_LICENSE_TMP_DIR) 2>/dev/null
$(GO) run build/generate-go-licenses.go $(GO_LICENSE_TMP_DIR) $(GO_LICENSE_FILE)
@rm -rf $(GO_LICENSE_TMP_DIR)
@ -716,33 +750,33 @@ integration-test-coverage-sqlite: integrations.cover.sqlite.test generate-ini-sq
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./integrations.cover.sqlite.test -test.coverprofile=integration.coverage.out
integrations.mysql.test: git-check $(GO_SOURCES)
$(GOTEST) $(GOTESTFLAGS) -c forgejo.org/tests/integration -o integrations.mysql.test
$(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.mysql.test
integrations.pgsql.test: git-check $(GO_SOURCES)
$(GOTEST) $(GOTESTFLAGS) -c forgejo.org/tests/integration -o integrations.pgsql.test
$(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.pgsql.test
integrations.sqlite.test: git-check $(GO_SOURCES)
$(GOTEST) $(GOTESTFLAGS) -c forgejo.org/tests/integration -o integrations.sqlite.test -tags '$(TEST_TAGS)'
$(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.sqlite.test -tags '$(TEST_TAGS)'
integrations.cover.test: git-check $(GO_SOURCES)
$(GOTEST) $(GOTESTFLAGS) -c forgejo.org/tests/integration -coverpkg $(shell echo $(GO_TEST_PACKAGES) | tr ' ' ',') -o integrations.cover.test
$(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -coverpkg $(shell echo $(GO_TEST_PACKAGES) | tr ' ' ',') -o integrations.cover.test
integrations.cover.sqlite.test: git-check $(GO_SOURCES)
$(GOTEST) $(GOTESTFLAGS) -c forgejo.org/tests/integration -coverpkg $(shell echo $(GO_TEST_PACKAGES) | tr ' ' ',') -o integrations.cover.sqlite.test -tags '$(TEST_TAGS)'
$(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -coverpkg $(shell echo $(GO_TEST_PACKAGES) | tr ' ' ',') -o integrations.cover.sqlite.test -tags '$(TEST_TAGS)'
.PHONY: migrations.mysql.test
migrations.mysql.test: $(GO_SOURCES) generate-ini-mysql
$(GOTEST) $(GOTESTFLAGS) -c forgejo.org/tests/integration/migration-test -o migrations.mysql.test
$(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.mysql.test
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini $(GOTESTCOMPILEDRUNPREFIX) ./migrations.mysql.test $(GOTESTCOMPILEDRUNSUFFIX)
.PHONY: migrations.pgsql.test
migrations.pgsql.test: $(GO_SOURCES) generate-ini-pgsql
$(GOTEST) $(GOTESTFLAGS) -c forgejo.org/tests/integration/migration-test -o migrations.pgsql.test
$(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.pgsql.test
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GOTESTCOMPILEDRUNPREFIX) ./migrations.pgsql.test $(GOTESTCOMPILEDRUNSUFFIX)
.PHONY: migrations.sqlite.test
migrations.sqlite.test: $(GO_SOURCES) generate-ini-sqlite
$(GOTEST) $(GOTESTFLAGS) -c forgejo.org/tests/integration/migration-test -o migrations.sqlite.test -tags '$(TEST_TAGS)'
$(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.sqlite.test -tags '$(TEST_TAGS)'
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GOTESTCOMPILEDRUNPREFIX) ./migrations.sqlite.test $(GOTESTCOMPILEDRUNSUFFIX)
.PHONY: migrations.individual.mysql.test
@ -753,7 +787,7 @@ migrations.individual.mysql.test: $(GO_SOURCES)
.PHONY: migrations.individual.sqlite.test\#%
migrations.individual.sqlite.test\#%: $(GO_SOURCES) generate-ini-sqlite
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GOTEST) $(GOTESTFLAGS) -tags '$(TEST_TAGS)' forgejo.org/models/migrations/$*
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GOTEST) $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$*
.PHONY: migrations.individual.pgsql.test
migrations.individual.pgsql.test: $(GO_SOURCES)
@ -763,7 +797,7 @@ migrations.individual.pgsql.test: $(GO_SOURCES)
.PHONY: migrations.individual.pgsql.test\#%
migrations.individual.pgsql.test\#%: $(GO_SOURCES) generate-ini-pgsql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GOTEST) $(GOTESTFLAGS) -tags '$(TEST_TAGS)' forgejo.org/models/migrations/$*
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GOTEST) $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$*
.PHONY: migrations.individual.sqlite.test
migrations.individual.sqlite.test: $(GO_SOURCES) generate-ini-sqlite
@ -773,16 +807,16 @@ migrations.individual.sqlite.test: $(GO_SOURCES) generate-ini-sqlite
.PHONY: migrations.individual.sqlite.test\#%
migrations.individual.sqlite.test\#%: $(GO_SOURCES) generate-ini-sqlite
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GOTEST) $(GOTESTFLAGS) -tags '$(TEST_TAGS)' forgejo.org/models/migrations/$*
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GOTEST) $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$*
e2e.mysql.test: $(GO_SOURCES)
$(GOTEST) $(GOTESTFLAGS) -c forgejo.org/tests/e2e -o e2e.mysql.test
$(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.mysql.test
e2e.pgsql.test: $(GO_SOURCES)
$(GOTEST) $(GOTESTFLAGS) -c forgejo.org/tests/e2e -o e2e.pgsql.test
$(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.pgsql.test
e2e.sqlite.test: $(GO_SOURCES)
$(GOTEST) $(GOTESTFLAGS) -c forgejo.org/tests/e2e -o e2e.sqlite.test -tags '$(TEST_TAGS)'
$(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.sqlite.test -tags '$(TEST_TAGS)'
.PHONY: check
check: test
@ -792,8 +826,8 @@ check: test
###
.PHONY: install $(TAGS_PREREQ)
install: $(wildcard *.go) | verify-version
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) install -v -tags '$(TAGS)' -ldflags '$(LDFLAGS)'
install: $(wildcard *.go)
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) install -v -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)'
.PHONY: build
build: frontend backend
@ -820,14 +854,14 @@ generate-go: $(TAGS_PREREQ)
merge-locales:
@echo "NOT NEEDED: THIS IS A NOOP AS OF Forgejo 7.0 BUT KEPT FOR BACKWARD COMPATIBILITY"
$(EXECUTABLE): $(GO_SOURCES) $(TAGS_PREREQ) | verify-version
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)' -o $@
$(EXECUTABLE): $(GO_SOURCES) $(TAGS_PREREQ)
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
forgejo: $(EXECUTABLE)
ln -f $(EXECUTABLE) forgejo
static-executable: $(GO_SOURCES) $(TAGS_PREREQ) | verify-version
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -o $(EXECUTABLE)
static-executable: $(GO_SOURCES) $(TAGS_PREREQ)
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags 'netgo osusergo $(TAGS)' -ldflags '-s -w -linkmode external -extldflags "-static" $(LDFLAGS)' -o $(EXECUTABLE)
.PHONY: release
release: frontend generate release-linux release-copy release-compress vendor release-sources release-check
@ -838,19 +872,23 @@ sources-tarbal: frontend generate vendor release-sources release-check
$(DIST_DIRS):
mkdir -p $(DIST_DIRS)
.PHONY: release-windows
release-windows: | $(DIST_DIRS)
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) .
.PHONY: release-linux
release-linux: | $(DIST_DIRS) verify-version
release-linux: | $(DIST_DIRS)
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets '$(LINUX_ARCHS)' -out forgejo-$(VERSION) .
ifeq ($(CI),true)
cp /build/* $(DIST)/binaries
endif
.PHONY: release-darwin
release-darwin: | $(DIST_DIRS) verify-version
release-darwin: | $(DIST_DIRS)
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin-10.12/amd64,darwin-10.12/arm64' -out gitea-$(VERSION) .
.PHONY: release-freebsd
release-freebsd: | $(DIST_DIRS) verify-version
release-freebsd: | $(DIST_DIRS)
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'freebsd/amd64' -out gitea-$(VERSION) .
.PHONY: release-copy
@ -904,7 +942,10 @@ reproduce-build\#%:
###
.PHONY: deps
deps: deps-frontend deps-backend deps-tools
deps: deps-frontend deps-backend deps-tools deps-py
.PHONY: deps-py
deps-py: .venv
.PHONY: deps-frontend
deps-frontend: node_modules
@ -920,11 +961,13 @@ deps-tools:
$(GO) install $(GOFUMPT_PACKAGE)
$(GO) install $(GOLANGCI_LINT_PACKAGE)
$(GO) install $(GXZ_PACKAGE)
$(GO) install $(MISSPELL_PACKAGE)
$(GO) install $(SWAGGER_PACKAGE)
$(GO) install $(XGO_PACKAGE)
$(GO) install $(GO_LICENSES_PACKAGE)
$(GO) install $(GOVULNCHECK_PACKAGE)
$(GO) install $(GOMOCK_PACKAGE)
$(GO) install $(GOPLS_PACKAGE)
node_modules: package-lock.json
npm install --no-save
@ -984,11 +1027,12 @@ generate-gitignore:
.PHONY: generate-gomock
generate-gomock:
$(GO) run $(GOMOCK_PACKAGE) -package mock -destination ./modules/queue/mock/redisuniversalclient.go forgejo.org/modules/nosql RedisClient
$(GO) run $(GOMOCK_PACKAGE) -package mock -destination ./modules/queue/mock/redisuniversalclient.go code.gitea.io/gitea/modules/nosql RedisClient
.PHONY: generate-images
generate-images: | node_modules
node tools/generate-images.js
npm install --no-save fabric@6 imagemin-zopfli@7
node tools/generate-images.js $(TAGS)
.PHONY: generate-manpage
generate-manpage:

View file

@ -15,6 +15,11 @@ Our promise: **Independent Free/Libre Software forever!**
## What does Forgejo offer?
<!-- If you want to know what Forgejo is like,
you can check out public instances,
e.g. [Codeberg.org](https://codeberg.org).
-->
If you like any of the following, Forgejo is literally meant for you:
- Lightweight: Forgejo can easily be hosted on nearly **every machine**.

View file

@ -1590,7 +1590,7 @@ this situation, [follow the instructions in the companion blog post](https://for
The most prominent ones are described here, others can be found in the list of commits included in the release as described above.
* [Fix links to pull request reviews sent via mail](https://codeberg.org/forgejo/forgejo/commit/88e179d5ef8ee41f71d068195685ff098b38ca31). The pull request link was correct but it did not go the review and stayed at the beginning of the page
* [Fix links to pull request reviews sent via mail](https://codeberg.org/forgejo/forgejo/commit/88e179d5ef8ee41f71d068195685ff098b38ca31). The pull request link was correct but it did not go the the review and stayed at the beginning of the page
* [Recognize OGG as an audio format](https://codeberg.org/forgejo/forgejo/commit/622ec5c79f299c32ac2667a1aa7b4bf5d7c2d6cf)
* [Consistently show the last time a cron job was run in the admin panel](https://codeberg.org/forgejo/forgejo/commit/5f769ef20)
* [Fix NuGet registry v2 & v3 API search endpoints](https://codeberg.org/forgejo/forgejo/commit/471138829b0c24fe8c621dbb866ae8bb45ebc674)
@ -1609,7 +1609,7 @@ this situation, [follow the instructions in the companion blog post](https://for
* [Fix pull request check list when there are more than 30](https://codeberg.org/forgejo/forgejo/commit/e226b9646)
* [Fix attachment clipboard copy on insecure origin](https://codeberg.org/forgejo/forgejo/commit/12ac84c26)
* [Fix the profile README rendering](https://codeberg.org/forgejo/forgejo/commit/84c3b60a4) that [was inconsistent with other markdown files renderings](https://codeberg.org/forgejo/forgejo/issues/833)
* [Fix API leaking the user email when the caller is not authenticated](https://codeberg.org/forgejo/forgejo/commit/d89003cc1)
* [Fix API leaking the user email when the caller is not authentified](https://codeberg.org/forgejo/forgejo/commit/d89003cc1)
## 1.20.2-0
@ -1667,7 +1667,7 @@ $ git -C forgejo log --oneline --no-merges origin/v1.19/forgejo..origin/v1.20/fo
The semantic version was updated to `5.0.0+0-gitea-1.20.1` because it contains breaking changes.
- **Breaking:**
- [Scoped access tokens](https://codeberg.org/forgejo/forgejo/commit/18de83b2a3fc120922096b7348d6375094ae1532) or (Personal Access Tokens), were refactored and although existing tokens are still valid, they may have a different scope than before. To ensure that no tokens have a larger scope than expected they must be removed and recreated.
- If your `app.ini` has one of the following `[indexer].ISSUE_INDEXER_QUEUE_TYPE`, `[indexer].ISSUE_INDEXER_QUEUE_BATCH_NUMBER`, `[indexer].`, `[indexer].ISSUE_INDEXER_QUEUE_DIR`, `[indexer].ISSUE_INDEXER_QUEUE_CONN_STR`, `[indexer].UPDATE_BUFFER_LEN`, `[mailer].SEND_BUFFER_LEN`, `[repository].PULL_REQUEST_QUEUE_LENGTH` or `[repository].MIRROR_QUEUE_LENGTH`, Forgejo will abort immediately. Unless you know exactly what you're doing, you must comment them out so the default values are used.
- If your `app.ini` has one of the the following `[indexer].ISSUE_INDEXER_QUEUE_TYPE`, `[indexer].ISSUE_INDEXER_QUEUE_BATCH_NUMBER`, `[indexer].`, `[indexer].ISSUE_INDEXER_QUEUE_DIR`, `[indexer].ISSUE_INDEXER_QUEUE_CONN_STR`, `[indexer].UPDATE_BUFFER_LEN`, `[mailer].SEND_BUFFER_LEN`, `[repository].PULL_REQUEST_QUEUE_LENGTH` or `[repository].MIRROR_QUEUE_LENGTH`, Forgejo will abort immediately. Unless you know exactly what you're doing, you must comment them out so the default values are used.
- The `-p` option of `environment-to-ini` is [no longer supported](https://codeberg.org/forgejo/forgejo/commit/fa0b5b14c2faa6a5f76bb2e7bc9241a5e4354189)
- The ".png" suffix for [user and organizations is now reserved](https://codeberg.org/forgejo/forgejo/commit/2b91841cd3e1213ff3e4ed4209d6a4be89c2fa79)
- The section `[git.reflog]` is [now obsolete and its keys have been moved](https://codeberg.org/forgejo/forgejo/commit/2f149c5c9db97f20fbbc65e32d1f3133048b11a2) to the following replacements:
@ -1761,7 +1761,7 @@ $ git -C forgejo log --oneline --no-merges origin/v1.19/forgejo..origin/v1.20/fo
- [The repository migration can be canceled](https://codeberg.org/forgejo/forgejo/commit/f6e029e6c7849d4361abf7f1d749b5d528364ac4)
- [Add button on the diff header to copy the file name](https://codeberg.org/forgejo/forgejo/commit/c5ede35124c8d5280219c24049bb0ad7da9f02ed)
- [Add --quiet option to the dump CLI](https://codeberg.org/forgejo/forgejo/commit/cb1536471bcef4d78a3fe5cbd738b9f60fabbcc2)
- [Support searching for an issue with its number in the list of issues](https://codeberg.org/forgejo/forgejo/commit/1144b1d129de530b2c07dfdfaf55de383cd82212)
- [Support searching for an issue with its number in the the list of issues](https://codeberg.org/forgejo/forgejo/commit/1144b1d129de530b2c07dfdfaf55de383cd82212)
- [Improve the list of notifications](https://codeberg.org/forgejo/forgejo/commit/f7ede92f82f7f3ec7bb31a1249f9524e5b728f34)
- [When editing a file in the web UI, allow for a preview whenever possible](https://codeberg.org/forgejo/forgejo/commit/ac64c8297444ade63a2a364c4afb7e6c1de5a75f)
- [Make release download URLs human readable](https://codeberg.org/forgejo/forgejo/commit/42919ccb7cd32ab67d0878baf2bac6cd007899a8)
@ -1798,7 +1798,7 @@ $ git -C forgejo log --oneline --no-merges origin/v1.19/forgejo..origin/v1.20/fo
- [Add API for gitignore templates](https://codeberg.org/forgejo/forgejo/commit/36a5d4c2f3b5670e5e921034cd5d25817534a6d4)
- [Add API to upuload a file to an empty repository](https://codeberg.org/forgejo/forgejo/commit/cf465b472166ccf6d3e001e3043e4bf43e16e6b3)
- [Allow for --not when listing the commits of a repo](https://codeberg.org/forgejo/forgejo/commit/f766b002938b5c81e343c81fda3c0669fa09809f)
- [Add `files` and `verification` parameters to improve performances when listing the commits of a repo](https://codeberg.org/forgejo/forgejo/commit/1dd83dbb917d55bd253001646d6743f247a4d98b)
- [Add `files` and `verification` parameters to improve performances when listing the commits of a a repo](https://codeberg.org/forgejo/forgejo/commit/1dd83dbb917d55bd253001646d6743f247a4d98b)
- [Allow for listing a single commit in a repository](https://codeberg.org/forgejo/forgejo/commit/5930ab5fdf7a970fcca3cd50b44cf1cacb615a54)
- [Create a branch directly from commit on the create branch API](https://codeberg.org/forgejo/forgejo/commit/cd9a13ebb47d32f46b38439a524e3b2e0c619490)
- [Add API for Label templates](https://codeberg.org/forgejo/forgejo/commit/25dc1556cd70b567a4920beb002a0addfbfd6ef2)

117
assets/go-licenses.json generated

File diff suppressed because one or more lines are too long

14
build.go Normal file
View file

@ -0,0 +1,14 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
//go:build vendor
package main
// Libraries that are included to vendor utilities used during build.
// These libraries will not be included in a normal compilation.
import (
// for embed
_ "github.com/shurcooL/vfsgen"
)

View file

@ -12,8 +12,8 @@ import (
"path/filepath"
"strings"
"forgejo.org/modules/container"
"forgejo.org/modules/setting"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/setting"
)
func main() {

View file

@ -15,7 +15,7 @@ import (
"strconv"
"strings"
"forgejo.org/build/codeformat"
"code.gitea.io/gitea/build/codeformat"
)
// Windows has a limitation for command line arguments, the size can not exceed 32KB.

View file

@ -14,7 +14,7 @@ import (
var importPackageGroupOrders = map[string]int{
"": 1, // internal
"forgejo.org/": 2,
"code.gitea.io/gitea/": 2,
}
var errInvalidCommentBetweenImports = errors.New("comments between imported packages are invalid, please move comments to the end of the package line")

View file

@ -58,8 +58,8 @@ import (
"code.gitea.io/other/package"
"forgejo.org/modules/setting"
"forgejo.org/modules/util"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"xorm.io/the/package"
@ -82,8 +82,8 @@ import (
_ "image/jpeg" // for processing jpeg images
_ "image/png" // for processing png images
"forgejo.org/modules/setting"
"forgejo.org/modules/util"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/other/package"
"github.com/issue9/identicon"

View file

@ -1,6 +1,5 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// Copyright 2025 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-License-Identifier: MIT
//go:build ignore
@ -8,40 +7,30 @@ package main
import (
"bytes"
"crypto/sha256"
"crypto/sha1"
"fmt"
"io"
"io/fs"
"log"
"net/http"
"os"
"path"
"path/filepath"
"strconv"
"text/template"
"github.com/klauspost/compress/zstd"
"github.com/shurcooL/vfsgen"
)
func fileExists(filename string) bool {
_, err := os.Stat(filename)
if err == nil {
return true
}
if os.IsNotExist(err) {
return false
}
panic(err)
}
func needsUpdate(dir, filename string) (bool, []byte) {
needRegen := !fileExists(filename)
needRegen := false
_, err := os.Stat(filename)
if err != nil {
needRegen = true
}
oldHash, err := os.ReadFile(filename + ".hash")
if err != nil {
oldHash = []byte{}
}
hasher := sha256.New()
hasher := sha1.New()
err = filepath.WalkDir(dir, func(path string, d os.DirEntry, err error) error {
if err != nil {
@ -62,7 +51,7 @@ func needsUpdate(dir, filename string) (bool, []byte) {
newHash := hasher.Sum([]byte{})
if !bytes.Equal(oldHash, newHash) {
if bytes.Compare(oldHash, newHash) != 0 {
return true, newHash
}
@ -80,280 +69,24 @@ func main() {
useGlobalModTime, _ = strconv.ParseBool(os.Args[4])
}
if os.Getenv("FORGEJO_GENERATE_SKIP_HASH") == "true" && fileExists(filename) {
fmt.Printf("bindata %s already exists and FORGEJO_GENERATE_SKIP_HASH=true\n", packageName)
return
}
update, newHash := needsUpdate(dir, filename)
if !update {
fmt.Printf("bindata %s already exists and the checksum is a match\n", packageName)
fmt.Printf("bindata for %s already up-to-date\n", packageName)
return
}
fmt.Printf("generating bindata for %s\n", packageName)
root, err := os.OpenRoot(dir)
var fsTemplates http.FileSystem = http.Dir(dir)
err := vfsgen.Generate(fsTemplates, vfsgen.Options{
PackageName: packageName,
BuildTags: "bindata",
VariableName: "Assets",
Filename: filename,
UseGlobalModTime: useGlobalModTime,
})
if err != nil {
log.Fatal(err)
}
out, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0o644)
if err != nil {
log.Fatal(err)
}
defer out.Close()
if err := generate(root.FS(), packageName, useGlobalModTime, out); err != nil {
log.Fatal(err)
log.Fatalf("%v\n", err)
}
_ = os.WriteFile(filename+".hash", newHash, 0o666)
}
type file struct {
Path string
Name string
UncompressedSize int
CompressedData []byte
UncompressedData []byte
}
type direntry struct {
Name string
IsDir bool
}
func generate(fsRoot fs.FS, packageName string, globalTime bool, output io.Writer) error {
enc, err := zstd.NewWriter(nil, zstd.WithEncoderLevel(zstd.SpeedBestCompression))
if err != nil {
return err
}
files := []file{}
dirs := map[string][]direntry{}
if err := fs.WalkDir(fsRoot, ".", func(filePath string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
entries, err := fs.ReadDir(fsRoot, filePath)
if err != nil {
return err
}
dirEntries := make([]direntry, 0, len(entries))
for _, entry := range entries {
dirEntries = append(dirEntries, direntry{Name: entry.Name(), IsDir: entry.IsDir()})
}
dirs[filePath] = dirEntries
return nil
}
src, err := fs.ReadFile(fsRoot, filePath)
if err != nil {
return err
}
dst := enc.EncodeAll(src, nil)
if len(dst) < len(src) {
files = append(files, file{
Path: filePath,
Name: path.Base(filePath),
UncompressedSize: len(src),
CompressedData: dst,
})
} else {
files = append(files, file{
Path: filePath,
Name: path.Base(filePath),
UncompressedData: src,
})
}
return nil
}); err != nil {
return err
}
return generatedTmpl.Execute(output, map[string]any{
"Packagename": packageName,
"GlobalTime": globalTime,
"Files": files,
"Dirs": dirs,
})
}
var generatedTmpl = template.Must(template.New("").Parse(`// Code generated by efs-gen. DO NOT EDIT.
//go:build bindata
package {{.Packagename}}
import (
"bytes"
"time"
"io"
"io/fs"
"github.com/klauspost/compress/zstd"
)
type normalFile struct {
name string
content []byte
}
type compressedFile struct {
name string
uncompressedSize int64
data []byte
}
var files = map[string]any{
{{- range .Files}}
"{{.Path}}": {{if .CompressedData}}compressedFile{"{{.Name}}", {{.UncompressedSize}}, []byte({{printf "%+q" .CompressedData}})}{{else}}normalFile{"{{.Name}}", []byte({{printf "%+q" .UncompressedData}})}{{end}},
{{- end}}
}
var dirs = map[string][]fs.DirEntry{
{{- range $key, $entry := .Dirs}}
"{{$key}}": {
{{- range $entry}}
direntry{"{{.Name}}", {{.IsDir}}},
{{- end}}
},
{{- end}}
}
type assets struct{}
var Assets = assets{}
func (a assets) Open(name string) (fs.File, error) {
f, ok := files[name]
if !ok {
return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist}
}
switch f := f.(type) {
case normalFile:
return file{name: f.name, size: int64(len(f.content)), data: bytes.NewReader(f.content)}, nil
case compressedFile:
r, _ := zstd.NewReader(bytes.NewReader(f.data))
return &compressFile{name: f.name, size: f.uncompressedSize, data: r, content: f.data}, nil
default:
panic("unknown file type")
}
}
func (a assets) ReadDir(name string) ([]fs.DirEntry, error) {
d, ok := dirs[name]
if !ok {
return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist}
}
return d, nil
}
type file struct {
name string
size int64
data io.ReadSeeker
}
var _ io.ReadSeeker = (*file)(nil)
func (f file) Stat() (fs.FileInfo, error) {
return fileinfo{name: f.name, size: f.size}, nil
}
func (f file) Read(p []byte) (int, error) {
return f.data.Read(p)
}
func (f file) Seek(offset int64, whence int) (int64, error) {
return f.data.Seek(offset, whence)
}
func (f file) Close() error { return nil }
type compressFile struct {
name string
size int64
data *zstd.Decoder
content []byte
zstdPos int64
seekPos int64
}
var _ io.ReadSeeker = (*compressFile)(nil)
func (f *compressFile) Stat() (fs.FileInfo, error) {
return fileinfo{name: f.name, size: f.size}, nil
}
func (f *compressFile) Read(p []byte) (int, error) {
if f.zstdPos > f.seekPos {
if err := f.data.Reset(bytes.NewReader(f.content)); err != nil {
return 0, err
}
f.zstdPos = 0
}
if f.zstdPos < f.seekPos {
if _, err := io.CopyN(io.Discard, f.data, f.seekPos - f.zstdPos); err != nil {
return 0, err
}
f.zstdPos = f.seekPos
}
n, err := f.data.Read(p)
f.zstdPos += int64(n)
f.seekPos = f.zstdPos
return n, err
}
func (f *compressFile) Seek(offset int64, whence int) (int64, error) {
switch whence {
case io.SeekStart:
f.seekPos = 0 + offset
case io.SeekCurrent:
f.seekPos += offset
case io.SeekEnd:
f.seekPos = f.size + offset
}
return f.seekPos, nil
}
func (f *compressFile) Close() error {
f.data.Close()
return nil
}
func (f *compressFile) ZstdBytes() []byte { return f.content }
type fileinfo struct {
name string
size int64
}
func (f fileinfo) Name() string { return f.name }
func (f fileinfo) Size() int64 { return f.size }
func (f fileinfo) Mode() fs.FileMode { return 0o444 }
func (f fileinfo) ModTime() time.Time { return {{if .GlobalTime}}GlobalModTime(f.name){{else}}time.Unix(0, 0){{end}} }
func (f fileinfo) IsDir() bool { return false }
func (f fileinfo) Sys() any { return nil }
type direntry struct {
name string
isDir bool
}
func (d direntry) Name() string { return d.name }
func (d direntry) IsDir() bool { return d.isDir }
func (d direntry) Type() fs.FileMode {
if d.isDir {
return 0o755 | fs.ModeDir
}
return 0o444
}
func (direntry) Info() (fs.FileInfo, error) { return nil, fs.ErrNotExist }
`))

View file

@ -20,7 +20,7 @@ import (
"strings"
"unicode/utf8"
"forgejo.org/modules/json"
"code.gitea.io/gitea/modules/json"
)
const (

View file

@ -15,7 +15,7 @@ import (
"path/filepath"
"strings"
"forgejo.org/modules/util"
"code.gitea.io/gitea/modules/util"
)
func main() {

View file

@ -16,7 +16,7 @@ import (
"sort"
"strings"
"forgejo.org/modules/container"
"code.gitea.io/gitea/modules/container"
)
// regexp is based on go-license, excluding README and NOTICE
@ -102,9 +102,9 @@ func main() {
pkgName := path.Dir(pkgPath)
// There might be a bug somewhere in go-licenses that sometimes interprets the
// root package as "." and sometimes as "forgejo.org". Workaround by
// root package as "." and sometimes as "code.gitea.io/gitea". Workaround by
// removing both of them for the sake of stable output.
if pkgName == "." || pkgName == "forgejo.org" {
if pkgName == "." || pkgName == "code.gitea.io/gitea" {
continue
}

View file

@ -15,7 +15,7 @@ import (
"path/filepath"
"strings"
"forgejo.org/modules/util"
"code.gitea.io/gitea/modules/util"
)
func main() {

View file

@ -1,383 +0,0 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// Copyright 2025 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package main
import (
"fmt"
"go/ast"
goParser "go/parser"
"go/token"
"io/fs"
"os"
"path/filepath"
"strconv"
"strings"
"text/template"
tmplParser "text/template/parse"
"forgejo.org/modules/container"
fjTemplates "forgejo.org/modules/templates"
"forgejo.org/modules/translation/localeiter"
"forgejo.org/modules/util"
)
// this works by first gathering all valid source string IDs from `en-US` reference files
// and then checking if all used source strings are actually defined
type LocatedError struct {
Location string
Kind string
Err error
}
func (e LocatedError) Error() string {
var sb strings.Builder
sb.WriteString(e.Location)
sb.WriteString(":\t")
if e.Kind != "" {
sb.WriteString(e.Kind)
sb.WriteString(": ")
}
sb.WriteString("ERROR: ")
sb.WriteString(e.Err.Error())
return sb.String()
}
func InitLocaleTrFunctions() map[string][]uint {
ret := make(map[string][]uint)
f0 := []uint{0}
ret["Tr"] = f0
ret["TrString"] = f0
ret["TrHTML"] = f0
ret["TrPluralString"] = []uint{1}
ret["TrN"] = []uint{1, 2}
return ret
}
type Handler struct {
OnMsgid func(fset *token.FileSet, pos token.Pos, msgid string)
OnUnexpectedInvoke func(fset *token.FileSet, pos token.Pos, funcname string, argc int)
LocaleTrFunctions map[string][]uint
}
// the `Handle*File` functions follow the following calling convention:
// * `fname` is the name of the input file
// * `src` is either `nil` (then the function invokes `ReadFile` to read the file)
// or the contents of the file as {`[]byte`, or a `string`}
func (handler Handler) HandleGoFile(fname string, src any) error {
fset := token.NewFileSet()
node, err := goParser.ParseFile(fset, fname, src, goParser.SkipObjectResolution)
if err != nil {
return LocatedError{
Location: fname,
Kind: "Go parser",
Err: err,
}
}
ast.Inspect(node, func(n ast.Node) bool {
// search for function calls of the form `anything.Tr(any-string-lit, ...)`
call, ok := n.(*ast.CallExpr)
if !ok || len(call.Args) < 1 {
return true
}
funSel, ok := call.Fun.(*ast.SelectorExpr)
if !ok {
return true
}
ltf, ok := handler.LocaleTrFunctions[funSel.Sel.Name]
if !ok {
return true
}
var gotUnexpectedInvoke *int
for _, argNum := range ltf {
if len(call.Args) >= int(argNum+1) {
argLit, ok := call.Args[int(argNum)].(*ast.BasicLit)
if !ok || argLit.Kind != token.STRING {
continue
}
// extract string content
arg, err := strconv.Unquote(argLit.Value)
if err == nil {
// found interesting strings
handler.OnMsgid(fset, argLit.ValuePos, arg)
}
} else {
argc := len(call.Args)
gotUnexpectedInvoke = &argc
}
}
if gotUnexpectedInvoke != nil {
handler.OnUnexpectedInvoke(fset, funSel.Sel.NamePos, funSel.Sel.Name, *gotUnexpectedInvoke)
}
return true
})
return nil
}
// derived from source: modules/templates/scopedtmpl/scopedtmpl.go, L169-L213
func (handler Handler) handleTemplateNode(fset *token.FileSet, node tmplParser.Node) {
switch node.Type() {
case tmplParser.NodeAction:
handler.handleTemplatePipeNode(fset, node.(*tmplParser.ActionNode).Pipe)
case tmplParser.NodeList:
nodeList := node.(*tmplParser.ListNode)
handler.handleTemplateFileNodes(fset, nodeList.Nodes)
case tmplParser.NodePipe:
handler.handleTemplatePipeNode(fset, node.(*tmplParser.PipeNode))
case tmplParser.NodeTemplate:
handler.handleTemplatePipeNode(fset, node.(*tmplParser.TemplateNode).Pipe)
case tmplParser.NodeIf:
nodeIf := node.(*tmplParser.IfNode)
handler.handleTemplateBranchNode(fset, nodeIf.BranchNode)
case tmplParser.NodeRange:
nodeRange := node.(*tmplParser.RangeNode)
handler.handleTemplateBranchNode(fset, nodeRange.BranchNode)
case tmplParser.NodeWith:
nodeWith := node.(*tmplParser.WithNode)
handler.handleTemplateBranchNode(fset, nodeWith.BranchNode)
case tmplParser.NodeCommand:
nodeCommand := node.(*tmplParser.CommandNode)
handler.handleTemplateFileNodes(fset, nodeCommand.Args)
if len(nodeCommand.Args) < 2 {
return
}
nodeChain, ok := nodeCommand.Args[0].(*tmplParser.ChainNode)
if !ok {
return
}
nodeIdent, ok := nodeChain.Node.(*tmplParser.IdentifierNode)
if !ok || nodeIdent.Ident != "ctx" || len(nodeChain.Field) != 2 || nodeChain.Field[0] != "Locale" {
return
}
ltf, ok := handler.LocaleTrFunctions[nodeChain.Field[1]]
if !ok {
return
}
var gotUnexpectedInvoke *int
for _, argNum := range ltf {
if len(nodeCommand.Args) >= int(argNum+2) {
nodeString, ok := nodeCommand.Args[int(argNum+1)].(*tmplParser.StringNode)
if ok {
// found interesting strings
// the column numbers are a bit "off", but much better than nothing
handler.OnMsgid(fset, token.Pos(nodeString.Pos), nodeString.Text)
}
} else {
argc := len(nodeCommand.Args) - 1
gotUnexpectedInvoke = &argc
}
}
if gotUnexpectedInvoke != nil {
handler.OnUnexpectedInvoke(fset, token.Pos(nodeChain.Pos), nodeChain.Field[1], *gotUnexpectedInvoke)
}
default:
}
}
func (handler Handler) handleTemplatePipeNode(fset *token.FileSet, pipeNode *tmplParser.PipeNode) {
if pipeNode == nil {
return
}
// NOTE: we can't pass `pipeNode.Cmds` to handleTemplateFileNodes due to incompatible argument types
for _, node := range pipeNode.Cmds {
handler.handleTemplateNode(fset, node)
}
}
func (handler Handler) handleTemplateBranchNode(fset *token.FileSet, branchNode tmplParser.BranchNode) {
handler.handleTemplatePipeNode(fset, branchNode.Pipe)
handler.handleTemplateFileNodes(fset, branchNode.List.Nodes)
if branchNode.ElseList != nil {
handler.handleTemplateFileNodes(fset, branchNode.ElseList.Nodes)
}
}
func (handler Handler) handleTemplateFileNodes(fset *token.FileSet, nodes []tmplParser.Node) {
for _, node := range nodes {
handler.handleTemplateNode(fset, node)
}
}
func (handler Handler) HandleTemplateFile(fname string, src any) error {
var tmplContent []byte
switch src2 := src.(type) {
case nil:
var err error
tmplContent, err = os.ReadFile(fname)
if err != nil {
return LocatedError{
Location: fname,
Kind: "ReadFile",
Err: err,
}
}
case []byte:
tmplContent = src2
case string:
// SAFETY: we do not modify tmplContent below
tmplContent = util.UnsafeStringToBytes(src2)
default:
panic("invalid type for 'src'")
}
fset := token.NewFileSet()
fset.AddFile(fname, 1, len(tmplContent)).SetLinesForContent(tmplContent)
// SAFETY: we do not modify tmplContent2 below
tmplContent2 := util.UnsafeBytesToString(tmplContent)
tmpl := template.New(fname)
tmpl.Funcs(fjTemplates.NewFuncMap())
tmplParsed, err := tmpl.Parse(tmplContent2)
if err != nil {
return LocatedError{
Location: fname,
Kind: "Template parser",
Err: err,
}
}
handler.handleTemplateFileNodes(fset, tmplParsed.Root.Nodes)
return nil
}
// This command assumes that we get started from the project root directory
//
// Possible command line flags:
//
// --allow-missing-msgids don't return an error code if missing message IDs are found
//
// EXIT CODES:
//
// 0 success, no issues found
// 1 unable to walk directory tree
// 2 unable to parse locale ini/json files
// 3 unable to parse go or text/template files
// 4 found missing message IDs
//
//nolint:forbidigo
func main() {
allowMissingMsgids := false
for _, arg := range os.Args[1:] {
if arg == "--allow-missing-msgids" {
allowMissingMsgids = true
}
}
onError := func(err error) {
if err == nil {
return
}
fmt.Println(err.Error())
os.Exit(3)
}
msgids := make(container.Set[string])
localeFile := filepath.Join(filepath.Join("options", "locale"), "locale_en-US.ini")
localeContent, err := os.ReadFile(localeFile)
if err != nil {
fmt.Printf("%s:\tERROR: %s\n", localeFile, err.Error())
os.Exit(2)
}
if err = localeiter.IterateMessagesContent(localeContent, func(trKey, trValue string) error {
msgids[trKey] = struct{}{}
return nil
}); err != nil {
fmt.Printf("%s:\tERROR: %s\n", localeFile, err.Error())
os.Exit(2)
}
localeFile = filepath.Join(filepath.Join("options", "locale_next"), "locale_en-US.json")
localeContent, err = os.ReadFile(localeFile)
if err != nil {
fmt.Printf("%s:\tERROR: %s\n", localeFile, err.Error())
os.Exit(2)
}
if err := localeiter.IterateMessagesNextContent(localeContent, func(trKey, pluralForm, trValue string) error {
// ignore plural form
msgids[trKey] = struct{}{}
return nil
}); err != nil {
fmt.Printf("%s:\tERROR: %s\n", localeFile, err.Error())
os.Exit(2)
}
gotAnyMsgidError := false
handler := Handler{
OnMsgid: func(fset *token.FileSet, pos token.Pos, msgid string) {
if !msgids.Contains(msgid) {
gotAnyMsgidError = true
fmt.Printf("%s:\tmissing msgid: %s\n", fset.Position(pos).String(), msgid)
}
},
OnUnexpectedInvoke: func(fset *token.FileSet, pos token.Pos, funcname string, argc int) {
gotAnyMsgidError = true
fmt.Printf("%s:\tunexpected invocation of %s with %d arguments\n", fset.Position(pos).String(), funcname, argc)
},
LocaleTrFunctions: InitLocaleTrFunctions(),
}
if err := filepath.WalkDir(".", func(fpath string, d fs.DirEntry, err error) error {
if err != nil {
if os.IsNotExist(err) {
return nil
}
return err
}
name := d.Name()
if d.IsDir() {
if name == "docker" || name == ".git" || name == "node_modules" {
return fs.SkipDir
}
} else if name == "bindata.go" || fpath == "modules/translation/i18n/i18n_test.go" {
// skip false positives
} else if strings.HasSuffix(name, ".go") {
onError(handler.HandleGoFile(fpath, nil))
} else if strings.HasSuffix(name, ".tmpl") {
if strings.HasPrefix(fpath, "tests") && strings.HasSuffix(name, ".ini.tmpl") {
// skip false positives
} else {
onError(handler.HandleTemplateFile(fpath, nil))
}
}
return nil
}); err != nil {
fmt.Printf("walkdir ERROR: %s\n", err.Error())
os.Exit(1)
}
if !allowMissingMsgids && gotAnyMsgidError {
os.Exit(4)
}
}

View file

@ -1,50 +0,0 @@
// Copyright 2025 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package main
import (
"go/token"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func buildHandler(ret *[]string) Handler {
return Handler{
OnMsgid: func(fset *token.FileSet, pos token.Pos, msgid string) {
*ret = append(*ret, msgid)
},
OnUnexpectedInvoke: func(fset *token.FileSet, pos token.Pos, funcname string, argc int) {},
LocaleTrFunctions: InitLocaleTrFunctions(),
}
}
func HandleGoFileWrapped(t *testing.T, fname, src string) []string {
var ret []string
handler := buildHandler(&ret)
require.NoError(t, handler.HandleGoFile(fname, src))
return ret
}
func HandleTemplateFileWrapped(t *testing.T, fname, src string) []string {
var ret []string
handler := buildHandler(&ret)
require.NoError(t, handler.HandleTemplateFile(fname, src))
return ret
}
func TestUsagesParser(t *testing.T) {
t.Run("go, simple", func(t *testing.T) {
assert.Equal(t,
[]string{"what.an.example"},
HandleGoFileWrapped(t, "<g1>", "package main\nfunc Render(ctx *context.Context) string { return ctx.Tr(\"what.an.example\"); }\n"))
})
t.Run("template, simple", func(t *testing.T) {
assert.Equal(t,
[]string{"what.an.example"},
HandleTemplateFileWrapped(t, "<t1>", "{{ ctx.Locale.Tr \"what.an.example\" }}\n"))
})
}

View file

@ -14,10 +14,9 @@ import (
"slices"
"strings"
"forgejo.org/modules/translation/localeiter"
"github.com/microcosm-cc/bluemonday"
"github.com/sergi/go-diff/diffmatchpatch"
"gopkg.in/ini.v1" //nolint:depguard
)
var (
@ -27,8 +26,6 @@ var (
// Matches href="", href="#", href="%s", href="#%s", href="%[1]s" and href="#%[1]s".
placeHolderRegex = regexp.MustCompile(`href="#?(%s|%\[\d\]s)?"`)
dmp = diffmatchpatch.New()
)
func initBlueMondayPolicy() {
@ -52,7 +49,7 @@ func initBlueMondayPolicy() {
policy.AllowAttrs("id").Matching(positionalPlaceholderRe).OnElements("code")
// Allowed elements with no attributes. Must be a recognized tagname.
policy.AllowElements("strong", "br", "b", "strike", "code", "i", "kbd")
policy.AllowElements("strong", "br", "b", "strike", "code", "i")
// TODO: Remove <c> in `actions.workflow.dispatch.trigger_found`.
policy.AllowNoAttrs().OnElements("c")
@ -82,48 +79,41 @@ func preprocessTranslationValue(value string) string {
return value
}
func checkValue(trKey, value string) []string {
keyValue := preprocessTranslationValue(value)
func checkLocaleContent(localeContent []byte) []string {
// Same configuration as Forgejo uses.
cfg := ini.Empty(ini.LoadOptions{
IgnoreContinuation: true,
})
cfg.NameMapper = ini.SnackCase
if html.UnescapeString(policy.Sanitize(keyValue)) == keyValue {
return nil
if err := cfg.Append(localeContent); err != nil {
panic(err)
}
dmp := diffmatchpatch.New()
errors := []string{}
for _, section := range cfg.Sections() {
for _, key := range section.Keys() {
var trKey string
if section.Name() == "" || section.Name() == "DEFAULT" || section.Name() == "common" {
trKey = key.Name()
} else {
trKey = section.Name() + "." + key.Name()
}
keyValue := preprocessTranslationValue(key.Value())
if html.UnescapeString(policy.Sanitize(keyValue)) != keyValue {
// Create a nice diff of the difference.
diffs := dmp.DiffMain(keyValue, html.UnescapeString(policy.Sanitize(keyValue)), false)
diffs = dmp.DiffCleanupSemantic(diffs)
diffs = dmp.DiffCleanupEfficiency(diffs)
return []string{trKey + ": " + dmp.DiffPrettyText(diffs)}
errors = append(errors, trKey+": "+dmp.DiffPrettyText(diffs))
}
func checkLocaleContent(localeContent []byte) []string {
errors := []string{}
if err := localeiter.IterateMessagesContent(localeContent, func(trKey, trValue string) error {
errors = append(errors, checkValue(trKey, trValue)...)
return nil
}); err != nil {
panic(err)
}
return errors
}
func checkLocaleNextContent(localeContent []byte) []string {
errors := []string{}
if err := localeiter.IterateMessagesNextContent(localeContent, func(trKey, pluralForm, trValue string) error {
fullKey := trKey
if pluralForm != "" {
fullKey = trKey + "." + pluralForm
}
errors = append(errors, checkValue(fullKey, trValue)...)
return nil
}); err != nil {
panic(err)
}
return errors
}
@ -137,7 +127,6 @@ func main() {
panic(err)
}
// Safety check that we are not reading the wrong directory.
if !slices.ContainsFunc(localeFiles, func(e fs.DirEntry) bool { return strings.HasSuffix(e.Name(), ".ini") }) {
fmt.Println("No locale files found")
os.Exit(1)
@ -151,7 +140,6 @@ func main() {
localeContent, err := os.ReadFile(filepath.Join(localeDir, localeFile.Name()))
if err != nil {
fmt.Println(localeFile.Name())
panic(err)
}
@ -163,33 +151,5 @@ func main() {
}
}
// Check the locale next.
localeDir = filepath.Join("options", "locale_next")
localeFiles, err = os.ReadDir(localeDir)
if err != nil {
panic(err)
}
// Safety check that we are not reading the wrong directory.
if !slices.ContainsFunc(localeFiles, func(e fs.DirEntry) bool { return strings.HasSuffix(e.Name(), ".json") }) {
fmt.Println("No locale_next files found")
os.Exit(1)
}
for _, localeFile := range localeFiles {
localeContent, err := os.ReadFile(filepath.Join(localeDir, localeFile.Name()))
if err != nil {
fmt.Println(localeFile.Name())
panic(err)
}
if err := checkLocaleNextContent(localeContent); len(err) > 0 {
fmt.Println(localeFile.Name())
fmt.Println(strings.Join(err, "\n"))
fmt.Println()
exitCode = 1
}
}
os.Exit(exitCode)
}

View file

@ -1,107 +0,0 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package main
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestLocalizationPolicy(t *testing.T) {
initBlueMondayPolicy()
initRemoveTags()
t.Run("Remove tags", func(t *testing.T) {
assert.Empty(t, checkLocaleContent([]byte(`hidden_comment_types_description = Comment types checked here will not be shown inside issue pages. Checking "Label" for example removes all "<user> added/removed <label>" comments.`)))
assert.Equal(t, []string{"key: \x1b[31m<not-an-allowed-key>\x1b[0m REPLACED-TAG"}, checkLocaleContent([]byte(`key = "<not-an-allowed-key> <label>"`)))
assert.Equal(t, []string{"key: \x1b[31m<user@example.com>\x1b[0m REPLACED-TAG"}, checkLocaleContent([]byte(`key = "<user@example.com> <email@example.com>"`)))
assert.Equal(t, []string{"key: \x1b[31m<tag>\x1b[0m REPLACED-TAG \x1b[31m</tag>\x1b[0m"}, checkLocaleContent([]byte(`key = "<tag> <email@example.com> </tag>"`)))
})
t.Run("Specific exception", func(t *testing.T) {
assert.Empty(t, checkLocaleContent([]byte(`workflow.dispatch.trigger_found = This workflow has a <c>workflow_dispatch</c> event trigger.`)))
assert.Empty(t, checkLocaleContent([]byte(`pulls.title_desc_one = wants to merge %[1]d commit from <code>%[2]s</code> into <code id="%[4]s">%[3]s</code>`)))
assert.Empty(t, checkLocaleContent([]byte(`editor.commit_directly_to_this_branch = Commit directly to the <strong class="%[2]s">%[1]s</strong> branch.`)))
assert.Equal(t, []string{"workflow.dispatch.trigger_found: This workflow has a \x1b[31m<d>\x1b[0mworkflow_dispatch\x1b[31m</d>\x1b[0m event trigger."}, checkLocaleContent([]byte(`workflow.dispatch.trigger_found = This workflow has a <d>workflow_dispatch</d> event trigger.`)))
assert.Equal(t, []string{"key: <code\x1b[31m id=\"branch_targe\"\x1b[0m>%[3]s</code>"}, checkLocaleContent([]byte(`key = <code id="branch_targe">%[3]s</code>`)))
assert.Equal(t, []string{"key: <a\x1b[31m class=\"ui sh\"\x1b[0m href=\"https://TO-BE-REPLACED.COM\">"}, checkLocaleContent([]byte(`key = <a class="ui sh" href="%[3]s">`)))
assert.Equal(t, []string{"key: <a\x1b[31m class=\"js-click-me\"\x1b[0m href=\"https://TO-BE-REPLACED.COM\">"}, checkLocaleContent([]byte(`key = <a class="js-click-me" href="%[3]s">`)))
assert.Equal(t, []string{"key: <strong\x1b[31m class=\"branch-target\"\x1b[0m>%[1]s</strong>"}, checkLocaleContent([]byte(`key = <strong class="branch-target">%[1]s</strong>`)))
})
t.Run("General safe tags", func(t *testing.T) {
assert.Empty(t, checkLocaleContent([]byte("error404 = The page you are trying to reach either <strong>does not exist</strong> or <strong>you are not authorized</strong> to view it.")))
assert.Empty(t, checkLocaleContent([]byte("teams.specific_repositories_helper = Members will only have access to repositories explicitly added to the team. Selecting this <strong>will not</strong> automatically remove repositories already added with <i>All repositories</i>.")))
assert.Empty(t, checkLocaleContent([]byte("sqlite_helper = File path for the SQLite3 database.<br>Enter an absolute path if you run Forgejo as a service.")))
assert.Empty(t, checkLocaleContent([]byte("hi_user_x = Hi <b>%s</b>,")))
assert.Empty(t, checkLocaleContent([]byte("key = Press <kbd>Shift</kbd>")))
assert.Equal(t, []string{"error404: The page you are trying to reach either <strong\x1b[31m title='aaa'\x1b[0m>does not exist</strong> or <strong>you are not authorized</strong> to view it."}, checkLocaleContent([]byte("error404 = The page you are trying to reach either <strong title='aaa'>does not exist</strong> or <strong>you are not authorized</strong> to view it.")))
})
t.Run("<a>", func(t *testing.T) {
assert.Empty(t, checkLocaleContent([]byte(`admin.new_user.text = Please <a href="%s">click here</a> to manage this user from the admin panel.`)))
assert.Empty(t, checkLocaleContent([]byte(`access_token_desc = Selected token permissions limit authorization only to the corresponding <a href="%[1]s" target="_blank">API</a> routes. Read the <a href="%[2]s" target="_blank">documentation</a> for more information.`)))
assert.Empty(t, checkLocaleContent([]byte(`webauthn_desc = Security keys are hardware devices containing cryptographic keys. They can be used for two-factor authentication. Security keys must support the <a rel="noreferrer" target="_blank" href="%s">WebAuthn Authenticator</a> standard.`)))
assert.Empty(t, checkLocaleContent([]byte("issues.closed_at = `closed this issue <a id=\"%[1]s\" href=\"#%[1]s\">%[2]s</a>`")))
assert.Equal(t, []string{"key: \x1b[31m<a href=\"https://example.com\">\x1b[0m"}, checkLocaleContent([]byte(`key = <a href="https://example.com">`)))
assert.Equal(t, []string{"key: \x1b[31m<a href=\"javascript:alert('1')\">\x1b[0m"}, checkLocaleContent([]byte(`key = <a href="javascript:alert('1')">`)))
assert.Equal(t, []string{"key: <a href=\"https://TO-BE-REPLACED.COM\"\x1b[31m download\x1b[0m>"}, checkLocaleContent([]byte(`key = <a href="%s" download>`)))
assert.Equal(t, []string{"key: <a href=\"https://TO-BE-REPLACED.COM\"\x1b[31m target=\"_self\"\x1b[0m>"}, checkLocaleContent([]byte(`key = <a href="%s" target="_self">`)))
assert.Equal(t, []string{"key: \x1b[31m<a href=\"https://example.com/%s\">\x1b[0m"}, checkLocaleContent([]byte(`key = <a href="https://example.com/%s">`)))
assert.Equal(t, []string{"key: \x1b[31m<a href=\"https://example.com/?q=%s\">\x1b[0m"}, checkLocaleContent([]byte(`key = <a href="https://example.com/?q=%s">`)))
assert.Equal(t, []string{"key: \x1b[31m<a href=\"%s/open-redirect\">\x1b[0m"}, checkLocaleContent([]byte(`key = <a href="%s/open-redirect">`)))
assert.Equal(t, []string{"key: \x1b[31m<a href=\"%s?q=open-redirect\">\x1b[0m"}, checkLocaleContent([]byte(`key = <a href="%s?q=open-redirect">`)))
})
t.Run("Escaped HTML characters", func(t *testing.T) {
assert.Empty(t, checkLocaleContent([]byte("activity.git_stats_push_to_branch = `إلى %s و\"`")))
assert.Equal(t, []string{"key: و\x1b[31m&nbsp;\x1b[0m\x1b[32m\u00a0\x1b[0m"}, checkLocaleContent([]byte(`key = و&nbsp;`)))
})
}
func TestNextLocalizationPolicy(t *testing.T) {
initBlueMondayPolicy()
initRemoveTags()
t.Run("Nested locales", func(t *testing.T) {
assert.Empty(t, checkLocaleNextContent([]byte(`{
"settings": {
"hidden_comment_types_description": "Comment types checked here will not be shown inside issue pages. Checking \"Label\" for example removes all \"<user> added/removed <label>\" comments."
}
}`)))
assert.Equal(t, []string{"settings.hidden_comment_types_description: \"\x1b[31m<not-an-allowed-key>\x1b[0m REPLACED-TAG\""}, checkLocaleNextContent([]byte(`{
"settings": {
"hidden_comment_types_description": "\"<not-an-allowed-key> <label>\""
}
}`)))
})
t.Run("Flat locales", func(t *testing.T) {
assert.Empty(t, checkLocaleNextContent([]byte(`{
"settings.hidden_comment_types_description": "Comment types checked here will not be shown inside issue pages. Checking \"Label\" for example removes all \"<user> added/removed <label>\" comments."
}`)))
assert.Equal(t, []string{"settings.hidden_comment_types_description: \"\x1b[31m<not-an-allowed-key>\x1b[0m REPLACED-TAG\""}, checkLocaleNextContent([]byte(`{
"settings.hidden_comment_types_description": "\"<not-an-allowed-key> <label>\""
}`)))
})
t.Run("Plural form", func(t *testing.T) {
assert.Equal(t, []string{"repo.pulls.title_desc: key = \x1b[31m<a href=\"https://example.com\">\x1b[0m"}, checkLocaleNextContent([]byte(`{"repo.pulls.title_desc": {
"few": "key = <a href=\"%s\">",
"other": "key = <a href=\"https://example.com\">"
}}`)))
assert.Equal(t, []string{"repo.pulls.title_desc.few: key = \x1b[31m<a href=\"https://example.com\">\x1b[0m"}, checkLocaleNextContent([]byte(`{"repo.pulls.title_desc": {
"few": "key = <a href=\"https://example.com\">",
"other": "key = <a href=\"%s\">"
}}`)))
})
}

65
build/lint-locale_test.go Normal file
View file

@ -0,0 +1,65 @@
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package main
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestLocalizationPolicy(t *testing.T) {
initBlueMondayPolicy()
initRemoveTags()
t.Run("Remove tags", func(t *testing.T) {
assert.Empty(t, checkLocaleContent([]byte(`hidden_comment_types_description = Comment types checked here will not be shown inside issue pages. Checking "Label" for example removes all "<user> added/removed <label>" comments.`)))
assert.EqualValues(t, []string{"key: \x1b[31m<not-an-allowed-key>\x1b[0m REPLACED-TAG"}, checkLocaleContent([]byte(`key = "<not-an-allowed-key> <label>"`)))
assert.EqualValues(t, []string{"key: \x1b[31m<user@example.com>\x1b[0m REPLACED-TAG"}, checkLocaleContent([]byte(`key = "<user@example.com> <email@example.com>"`)))
assert.EqualValues(t, []string{"key: \x1b[31m<tag>\x1b[0m REPLACED-TAG \x1b[31m</tag>\x1b[0m"}, checkLocaleContent([]byte(`key = "<tag> <email@example.com> </tag>"`)))
})
t.Run("Specific exception", func(t *testing.T) {
assert.Empty(t, checkLocaleContent([]byte(`workflow.dispatch.trigger_found = This workflow has a <c>workflow_dispatch</c> event trigger.`)))
assert.Empty(t, checkLocaleContent([]byte(`pulls.title_desc_one = wants to merge %[1]d commit from <code>%[2]s</code> into <code id="%[4]s">%[3]s</code>`)))
assert.Empty(t, checkLocaleContent([]byte(`editor.commit_directly_to_this_branch = Commit directly to the <strong class="%[2]s">%[1]s</strong> branch.`)))
assert.EqualValues(t, []string{"workflow.dispatch.trigger_found: This workflow has a \x1b[31m<d>\x1b[0mworkflow_dispatch\x1b[31m</d>\x1b[0m event trigger."}, checkLocaleContent([]byte(`workflow.dispatch.trigger_found = This workflow has a <d>workflow_dispatch</d> event trigger.`)))
assert.EqualValues(t, []string{"key: <code\x1b[31m id=\"branch_targe\"\x1b[0m>%[3]s</code>"}, checkLocaleContent([]byte(`key = <code id="branch_targe">%[3]s</code>`)))
assert.EqualValues(t, []string{"key: <a\x1b[31m class=\"ui sh\"\x1b[0m href=\"https://TO-BE-REPLACED.COM\">"}, checkLocaleContent([]byte(`key = <a class="ui sh" href="%[3]s">`)))
assert.EqualValues(t, []string{"key: <a\x1b[31m class=\"js-click-me\"\x1b[0m href=\"https://TO-BE-REPLACED.COM\">"}, checkLocaleContent([]byte(`key = <a class="js-click-me" href="%[3]s">`)))
assert.EqualValues(t, []string{"key: <strong\x1b[31m class=\"branch-target\"\x1b[0m>%[1]s</strong>"}, checkLocaleContent([]byte(`key = <strong class="branch-target">%[1]s</strong>`)))
})
t.Run("General safe tags", func(t *testing.T) {
assert.Empty(t, checkLocaleContent([]byte("error404 = The page you are trying to reach either <strong>does not exist</strong> or <strong>you are not authorized</strong> to view it.")))
assert.Empty(t, checkLocaleContent([]byte("teams.specific_repositories_helper = Members will only have access to repositories explicitly added to the team. Selecting this <strong>will not</strong> automatically remove repositories already added with <i>All repositories</i>.")))
assert.Empty(t, checkLocaleContent([]byte("sqlite_helper = File path for the SQLite3 database.<br>Enter an absolute path if you run Forgejo as a service.")))
assert.Empty(t, checkLocaleContent([]byte("hi_user_x = Hi <b>%s</b>,")))
assert.EqualValues(t, []string{"error404: The page you are trying to reach either <strong\x1b[31m title='aaa'\x1b[0m>does not exist</strong> or <strong>you are not authorized</strong> to view it."}, checkLocaleContent([]byte("error404 = The page you are trying to reach either <strong title='aaa'>does not exist</strong> or <strong>you are not authorized</strong> to view it.")))
})
t.Run("<a>", func(t *testing.T) {
assert.Empty(t, checkLocaleContent([]byte(`admin.new_user.text = Please <a href="%s">click here</a> to manage this user from the admin panel.`)))
assert.Empty(t, checkLocaleContent([]byte(`access_token_desc = Selected token permissions limit authorization only to the corresponding <a href="%[1]s" target="_blank">API</a> routes. Read the <a href="%[2]s" target="_blank">documentation</a> for more information.`)))
assert.Empty(t, checkLocaleContent([]byte(`webauthn_desc = Security keys are hardware devices containing cryptographic keys. They can be used for two-factor authentication. Security keys must support the <a rel="noreferrer" target="_blank" href="%s">WebAuthn Authenticator</a> standard.`)))
assert.Empty(t, checkLocaleContent([]byte("issues.closed_at = `closed this issue <a id=\"%[1]s\" href=\"#%[1]s\">%[2]s</a>`")))
assert.EqualValues(t, []string{"key: \x1b[31m<a href=\"https://example.com\">\x1b[0m"}, checkLocaleContent([]byte(`key = <a href="https://example.com">`)))
assert.EqualValues(t, []string{"key: \x1b[31m<a href=\"javascript:alert('1')\">\x1b[0m"}, checkLocaleContent([]byte(`key = <a href="javascript:alert('1')">`)))
assert.EqualValues(t, []string{"key: <a href=\"https://TO-BE-REPLACED.COM\"\x1b[31m download\x1b[0m>"}, checkLocaleContent([]byte(`key = <a href="%s" download>`)))
assert.EqualValues(t, []string{"key: <a href=\"https://TO-BE-REPLACED.COM\"\x1b[31m target=\"_self\"\x1b[0m>"}, checkLocaleContent([]byte(`key = <a href="%s" target="_self">`)))
assert.EqualValues(t, []string{"key: \x1b[31m<a href=\"https://example.com/%s\">\x1b[0m"}, checkLocaleContent([]byte(`key = <a href="https://example.com/%s">`)))
assert.EqualValues(t, []string{"key: \x1b[31m<a href=\"https://example.com/?q=%s\">\x1b[0m"}, checkLocaleContent([]byte(`key = <a href="https://example.com/?q=%s">`)))
assert.EqualValues(t, []string{"key: \x1b[31m<a href=\"%s/open-redirect\">\x1b[0m"}, checkLocaleContent([]byte(`key = <a href="%s/open-redirect">`)))
assert.EqualValues(t, []string{"key: \x1b[31m<a href=\"%s?q=open-redirect\">\x1b[0m"}, checkLocaleContent([]byte(`key = <a href="%s?q=open-redirect">`)))
})
t.Run("Escaped HTML characters", func(t *testing.T) {
assert.Empty(t, checkLocaleContent([]byte("activity.git_stats_push_to_branch = `إلى %s و\"`")))
assert.EqualValues(t, []string{"key: و\x1b[31m&nbsp\x1b[0m\x1b[32m\u00a0\x1b[0m"}, checkLocaleContent([]byte(`key = و&nbsp;`)))
})
}

52
build/update-locales.sh Executable file
View file

@ -0,0 +1,52 @@
#!/bin/sh
# this script runs in alpine image which only has `sh` shell
set +e
if sed --version 2>/dev/null | grep -q GNU; then
SED_INPLACE="sed -i"
else
SED_INPLACE="sed -i ''"
fi
set -e
if [ ! -f ./options/locale/locale_en-US.ini ]; then
echo "please run this script in the root directory of the project"
exit 1
fi
mv ./options/locale/locale_en-US.ini ./options/
# the "ini" library for locale has many quirks, its behavior is different from Crowdin.
# see i18n_test.go for more details
# this script helps to unquote the Crowdin outputs for the quirky ini library
# * find all `key="...\"..."` lines
# * remove the leading quote
# * remove the trailing quote
# * unescape the quotes
# * eg: key="...\"..." => key=..."...
$SED_INPLACE -r -e '/^[-.A-Za-z0-9_]+[ ]*=[ ]*".*"$/ {
s/^([-.A-Za-z0-9_]+)[ ]*=[ ]*"/\1=/
s/"$//
s/\\"/"/g
}' ./options/locale/*.ini
# * if the escaped line is incomplete like `key="...` or `key=..."`, quote it with backticks
# * eg: key="... => key=`"...`
# * eg: key=..." => key=`..."`
$SED_INPLACE -r -e 's/^([-.A-Za-z0-9_]+)[ ]*=[ ]*(".*[^"])$/\1=`\2`/' ./options/locale/*.ini
$SED_INPLACE -r -e 's/^([-.A-Za-z0-9_]+)[ ]*=[ ]*([^"].*")$/\1=`\2`/' ./options/locale/*.ini
# Remove translation under 25% of en_us
baselines=$(wc -l "./options/locale_en-US.ini" | cut -d" " -f1)
baselines=$((baselines / 4))
for filename in ./options/locale/*.ini; do
lines=$(wc -l "$filename" | cut -d" " -f1)
if [ $lines -lt $baselines ]; then
echo "Removing $filename: $lines/$baselines"
rm "$filename"
fi
done
mv ./options/locale_en-US.ini ./options/locale/

View file

@ -4,28 +4,25 @@
package cmd
import (
"context"
"fmt"
"forgejo.org/modules/private"
"forgejo.org/modules/setting"
"code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
var (
// CmdActions represents the available actions sub-commands.
func cmdActions() *cli.Command {
return &cli.Command{
CmdActions = &cli.Command{
Name: "actions",
Usage: "Manage Forgejo Actions",
Commands: []*cli.Command{
subcmdActionsGenRunnerToken(),
Subcommands: []*cli.Command{
subcmdActionsGenRunnerToken,
},
}
}
func subcmdActionsGenRunnerToken() *cli.Command {
return &cli.Command{
subcmdActionsGenRunnerToken = &cli.Command{
Name: "generate-runner-token",
Usage: "Generate a new token for a runner to use to register with the server",
Action: runGenerateActionsRunnerToken,
@ -39,10 +36,10 @@ func subcmdActionsGenRunnerToken() *cli.Command {
},
},
}
}
)
func runGenerateActionsRunnerToken(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runGenerateActionsRunnerToken(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setting.MustInstalled()

View file

@ -8,71 +8,63 @@ import (
"context"
"fmt"
"forgejo.org/models/db"
repo_model "forgejo.org/models/repo"
"forgejo.org/modules/git"
"forgejo.org/modules/gitrepo"
"forgejo.org/modules/log"
repo_module "forgejo.org/modules/repository"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
var (
// CmdAdmin represents the available admin sub-command.
func cmdAdmin() *cli.Command {
return &cli.Command{
CmdAdmin = &cli.Command{
Name: "admin",
Usage: "Perform common administrative operations",
Commands: []*cli.Command{
subcmdUser(),
subcmdRepoSyncReleases(),
subcmdRegenerate(),
subcmdAuth(),
subcmdSendMail(),
Subcommands: []*cli.Command{
subcmdUser,
subcmdRepoSyncReleases,
subcmdRegenerate,
subcmdAuth,
subcmdSendMail,
},
}
}
func subcmdRepoSyncReleases() *cli.Command {
return &cli.Command{
subcmdRepoSyncReleases = &cli.Command{
Name: "repo-sync-releases",
Usage: "Synchronize repository releases with tags",
Action: runRepoSyncReleases,
}
}
func subcmdRegenerate() *cli.Command {
return &cli.Command{
subcmdRegenerate = &cli.Command{
Name: "regenerate",
Usage: "Regenerate specific files",
Commands: []*cli.Command{
Subcommands: []*cli.Command{
microcmdRegenHooks,
microcmdRegenKeys,
},
}
}
func subcmdAuth() *cli.Command {
return &cli.Command{
subcmdAuth = &cli.Command{
Name: "auth",
Usage: "Modify external auth providers",
Commands: []*cli.Command{
microcmdAuthAddOauth(),
microcmdAuthUpdateOauth(),
microcmdAuthAddLdapBindDn(),
microcmdAuthUpdateLdapBindDn(),
microcmdAuthAddLdapSimpleAuth(),
microcmdAuthUpdateLdapSimpleAuth(),
microcmdAuthAddSMTP(),
microcmdAuthUpdateSMTP(),
microcmdAuthList(),
microcmdAuthDelete(),
Subcommands: []*cli.Command{
microcmdAuthAddOauth,
microcmdAuthUpdateOauth,
microcmdAuthAddLdapBindDn,
microcmdAuthUpdateLdapBindDn,
microcmdAuthAddLdapSimpleAuth,
microcmdAuthUpdateLdapSimpleAuth,
microcmdAuthAddSMTP,
microcmdAuthUpdateSMTP,
microcmdAuthList,
microcmdAuthDelete,
},
}
}
func subcmdSendMail() *cli.Command {
return &cli.Command{
subcmdSendMail = &cli.Command{
Name: "sendmail",
Usage: "Send a message to all users",
Action: runSendMail,
@ -94,17 +86,15 @@ func subcmdSendMail() *cli.Command {
},
},
}
}
func idFlag() *cli.Int64Flag {
return &cli.Int64Flag{
idFlag = &cli.Int64Flag{
Name: "id",
Usage: "ID of authentication source",
}
}
)
func runRepoSyncReleases(ctx context.Context, _ *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runRepoSyncReleases(_ *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {

View file

@ -4,30 +4,26 @@
package cmd
import (
"context"
"errors"
"fmt"
"os"
"text/tabwriter"
auth_model "forgejo.org/models/auth"
"forgejo.org/models/db"
auth_service "forgejo.org/services/auth"
auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
auth_service "code.gitea.io/gitea/services/auth"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
func microcmdAuthDelete() *cli.Command {
return &cli.Command{
var (
microcmdAuthDelete = &cli.Command{
Name: "delete",
Usage: "Delete specific auth source",
Flags: []cli.Flag{idFlag()},
Flags: []cli.Flag{idFlag},
Action: runDeleteAuth,
}
}
func microcmdAuthList() *cli.Command {
return &cli.Command{
microcmdAuthList = &cli.Command{
Name: "list",
Usage: "List auth sources",
Action: runListAuth,
@ -58,10 +54,10 @@ func microcmdAuthList() *cli.Command {
},
},
}
}
)
func runListAuth(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runListAuth(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
@ -85,7 +81,7 @@ func runListAuth(ctx context.Context, c *cli.Command) error {
// loop through each source and print
w := tabwriter.NewWriter(os.Stdout, c.Int("min-width"), c.Int("tab-width"), c.Int("padding"), padChar, flags)
fmt.Fprint(w, "ID\tName\tType\tEnabled\n")
fmt.Fprintf(w, "ID\tName\tType\tEnabled\n")
for _, source := range authSources {
fmt.Fprintf(w, "%d\t%s\t%s\t%t\n", source.ID, source.Name, source.Type.String(), source.IsActive)
}
@ -94,12 +90,12 @@ func runListAuth(ctx context.Context, c *cli.Command) error {
return nil
}
func runDeleteAuth(ctx context.Context, c *cli.Command) error {
func runDeleteAuth(c *cli.Context) error {
if !c.IsSet("id") {
return errors.New("--id flag is missing")
}
ctx, cancel := installSignals(ctx)
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {

View file

@ -8,10 +8,10 @@ import (
"fmt"
"strings"
"forgejo.org/models/auth"
"forgejo.org/services/auth/source/ldap"
"code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/services/auth/source/ldap"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
type (
@ -23,8 +23,8 @@ type (
}
)
func commonLdapCLIFlags() []cli.Flag {
return []cli.Flag{
var (
commonLdapCLIFlags = []cli.Flag{
&cli.StringFlag{
Name: "name",
Usage: "Authentication name.",
@ -102,10 +102,8 @@ func commonLdapCLIFlags() []cli.Flag {
Usage: "The attribute of the users LDAP record containing the users avatar.",
},
}
}
func ldapBindDnCLIFlags() []cli.Flag {
return append(commonLdapCLIFlags(),
ldapBindDnCLIFlags = append(commonLdapCLIFlags,
&cli.StringFlag{
Name: "bind-dn",
Usage: "The DN to bind to the LDAP server with when searching for the user.",
@ -130,59 +128,49 @@ func ldapBindDnCLIFlags() []cli.Flag {
Name: "page-size",
Usage: "Search page size.",
})
}
func ldapSimpleAuthCLIFlags() []cli.Flag {
return append(commonLdapCLIFlags(),
ldapSimpleAuthCLIFlags = append(commonLdapCLIFlags,
&cli.StringFlag{
Name: "user-dn",
Usage: "The user's DN.",
})
}
func microcmdAuthAddLdapBindDn() *cli.Command {
return &cli.Command{
microcmdAuthAddLdapBindDn = &cli.Command{
Name: "add-ldap",
Usage: "Add new LDAP (via Bind DN) authentication source",
Action: func(ctx context.Context, cli *cli.Command) error {
return newAuthService().addLdapBindDn(ctx, cli)
Action: func(c *cli.Context) error {
return newAuthService().addLdapBindDn(c)
},
Flags: ldapBindDnCLIFlags(),
}
Flags: ldapBindDnCLIFlags,
}
func microcmdAuthUpdateLdapBindDn() *cli.Command {
return &cli.Command{
microcmdAuthUpdateLdapBindDn = &cli.Command{
Name: "update-ldap",
Usage: "Update existing LDAP (via Bind DN) authentication source",
Action: func(ctx context.Context, cli *cli.Command) error {
return newAuthService().updateLdapBindDn(ctx, cli)
Action: func(c *cli.Context) error {
return newAuthService().updateLdapBindDn(c)
},
Flags: append([]cli.Flag{idFlag()}, ldapBindDnCLIFlags()...),
}
Flags: append([]cli.Flag{idFlag}, ldapBindDnCLIFlags...),
}
func microcmdAuthAddLdapSimpleAuth() *cli.Command {
return &cli.Command{
microcmdAuthAddLdapSimpleAuth = &cli.Command{
Name: "add-ldap-simple",
Usage: "Add new LDAP (simple auth) authentication source",
Action: func(ctx context.Context, cli *cli.Command) error {
return newAuthService().addLdapSimpleAuth(ctx, cli)
Action: func(c *cli.Context) error {
return newAuthService().addLdapSimpleAuth(c)
},
Flags: ldapSimpleAuthCLIFlags(),
}
Flags: ldapSimpleAuthCLIFlags,
}
func microcmdAuthUpdateLdapSimpleAuth() *cli.Command {
return &cli.Command{
microcmdAuthUpdateLdapSimpleAuth = &cli.Command{
Name: "update-ldap-simple",
Usage: "Update existing LDAP (simple auth) authentication source",
Action: func(ctx context.Context, cli *cli.Command) error {
return newAuthService().updateLdapSimpleAuth(ctx, cli)
Action: func(c *cli.Context) error {
return newAuthService().updateLdapSimpleAuth(c)
},
Flags: append([]cli.Flag{idFlag()}, ldapSimpleAuthCLIFlags()...),
}
Flags: append([]cli.Flag{idFlag}, ldapSimpleAuthCLIFlags...),
}
)
// newAuthService creates a service with default functions.
func newAuthService() *authService {
@ -195,7 +183,7 @@ func newAuthService() *authService {
}
// parseAuthSource assigns values on authSource according to command line flags.
func parseAuthSource(c *cli.Command, authSource *auth.Source) {
func parseAuthSource(c *cli.Context, authSource *auth.Source) {
if c.IsSet("name") {
authSource.Name = c.String("name")
}
@ -214,7 +202,7 @@ func parseAuthSource(c *cli.Command, authSource *auth.Source) {
}
// parseLdapConfig assigns values on config according to command line flags.
func parseLdapConfig(c *cli.Command, config *ldap.Source) error {
func parseLdapConfig(c *cli.Context, config *ldap.Source) error {
if c.IsSet("name") {
config.Name = c.String("name")
}
@ -301,7 +289,7 @@ func findLdapSecurityProtocolByName(name string) (ldap.SecurityProtocol, bool) {
// getAuthSource gets the login source by its id defined in the command line flags.
// It returns an error if the id is not set, does not match any source or if the source is not of expected type.
func (a *authService) getAuthSource(ctx context.Context, c *cli.Command, authType auth.Type) (*auth.Source, error) {
func (a *authService) getAuthSource(ctx context.Context, c *cli.Context, authType auth.Type) (*auth.Source, error) {
if err := argsSet(c, "id"); err != nil {
return nil, err
}
@ -319,12 +307,12 @@ func (a *authService) getAuthSource(ctx context.Context, c *cli.Command, authTyp
}
// addLdapBindDn adds a new LDAP via Bind DN authentication source.
func (a *authService) addLdapBindDn(ctx context.Context, c *cli.Command) error {
func (a *authService) addLdapBindDn(c *cli.Context) error {
if err := argsSet(c, "name", "security-protocol", "host", "port", "user-search-base", "user-filter", "email-attribute"); err != nil {
return err
}
ctx, cancel := installSignals(ctx)
ctx, cancel := installSignals()
defer cancel()
if err := a.initDB(ctx); err != nil {
@ -348,8 +336,8 @@ func (a *authService) addLdapBindDn(ctx context.Context, c *cli.Command) error {
}
// updateLdapBindDn updates a new LDAP via Bind DN authentication source.
func (a *authService) updateLdapBindDn(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func (a *authService) updateLdapBindDn(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := a.initDB(ctx); err != nil {
@ -370,12 +358,12 @@ func (a *authService) updateLdapBindDn(ctx context.Context, c *cli.Command) erro
}
// addLdapSimpleAuth adds a new LDAP (simple auth) authentication source.
func (a *authService) addLdapSimpleAuth(ctx context.Context, c *cli.Command) error {
func (a *authService) addLdapSimpleAuth(c *cli.Context) error {
if err := argsSet(c, "name", "security-protocol", "host", "port", "user-dn", "user-filter", "email-attribute"); err != nil {
return err
}
ctx, cancel := installSignals(ctx)
ctx, cancel := installSignals()
defer cancel()
if err := a.initDB(ctx); err != nil {
@ -399,8 +387,8 @@ func (a *authService) addLdapSimpleAuth(ctx context.Context, c *cli.Command) err
}
// updateLdapSimpleAuth updates a new LDAP (simple auth) authentication source.
func (a *authService) updateLdapSimpleAuth(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func (a *authService) updateLdapSimpleAuth(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := a.initDB(ctx); err != nil {

View file

@ -7,18 +7,19 @@ import (
"context"
"testing"
"forgejo.org/models/auth"
"forgejo.org/modules/test"
"forgejo.org/services/auth/source/ldap"
"code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/services/auth/source/ldap"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
func TestAddLdapBindDn(t *testing.T) {
// Mock cli functions to do not exit on error
defer test.MockVariableValue(&cli.OsExiter, func(code int) {})()
osExiter := cli.OsExiter
defer func() { cli.OsExiter = osExiter }()
cli.OsExiter = func(code int) {}
// Test cases
cases := []struct {
@ -215,22 +216,22 @@ func TestAddLdapBindDn(t *testing.T) {
return nil
},
updateAuthSource: func(ctx context.Context, authSource *auth.Source) error {
assert.FailNow(t, "should not call updateAuthSource", "case: %d", n)
assert.FailNow(t, "case %d: should not call updateAuthSource", n)
return nil
},
getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) {
assert.FailNow(t, "should not call getAuthSourceByID", "case: %d", n)
assert.FailNow(t, "case %d: should not call getAuthSourceByID", n)
return nil, nil
},
}
// Create a copy of command to test
app := cli.Command{}
app.Flags = microcmdAuthAddLdapBindDn().Flags
app := cli.NewApp()
app.Flags = microcmdAuthAddLdapBindDn.Flags
app.Action = service.addLdapBindDn
// Run it
err := app.Run(t.Context(), c.args)
err := app.Run(c.args)
if c.errMsg != "" {
assert.EqualError(t, err, c.errMsg, "case %d: error should match", n)
} else {
@ -242,7 +243,9 @@ func TestAddLdapBindDn(t *testing.T) {
func TestAddLdapSimpleAuth(t *testing.T) {
// Mock cli functions to do not exit on error
defer test.MockVariableValue(&cli.OsExiter, func(code int) {})()
osExiter := cli.OsExiter
defer func() { cli.OsExiter = osExiter }()
cli.OsExiter = func(code int) {}
// Test cases
cases := []struct {
@ -444,22 +447,22 @@ func TestAddLdapSimpleAuth(t *testing.T) {
return nil
},
updateAuthSource: func(ctx context.Context, authSource *auth.Source) error {
assert.FailNow(t, "should not call updateAuthSource", "case: %d", n)
assert.FailNow(t, "case %d: should not call updateAuthSource", n)
return nil
},
getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) {
assert.FailNow(t, "should not call getAuthSourceByID", "case: %d", n)
assert.FailNow(t, "case %d: should not call getAuthSourceByID", n)
return nil, nil
},
}
// Create a copy of command to test
app := cli.Command{}
app.Flags = microcmdAuthAddLdapSimpleAuth().Flags
app := cli.NewApp()
app.Flags = microcmdAuthAddLdapSimpleAuth.Flags
app.Action = service.addLdapSimpleAuth
// Run it
err := app.Run(t.Context(), c.args)
err := app.Run(c.args)
if c.errMsg != "" {
assert.EqualError(t, err, c.errMsg, "case %d: error should match", n)
} else {
@ -471,7 +474,9 @@ func TestAddLdapSimpleAuth(t *testing.T) {
func TestUpdateLdapBindDn(t *testing.T) {
// Mock cli functions to do not exit on error
defer test.MockVariableValue(&cli.OsExiter, func(code int) {})()
osExiter := cli.OsExiter
defer func() { cli.OsExiter = osExiter }()
cli.OsExiter = func(code int) {}
// Test cases
cases := []struct {
@ -893,7 +898,7 @@ func TestUpdateLdapBindDn(t *testing.T) {
return nil
},
createAuthSource: func(ctx context.Context, authSource *auth.Source) error {
assert.FailNow(t, "should not call createAuthSource", "case: %d", n)
assert.FailNow(t, "case %d: should not call createAuthSource", n)
return nil
},
updateAuthSource: func(ctx context.Context, authSource *auth.Source) error {
@ -915,12 +920,12 @@ func TestUpdateLdapBindDn(t *testing.T) {
}
// Create a copy of command to test
app := cli.Command{}
app.Flags = microcmdAuthUpdateLdapBindDn().Flags
app := cli.NewApp()
app.Flags = microcmdAuthUpdateLdapBindDn.Flags
app.Action = service.updateLdapBindDn
// Run it
err := app.Run(t.Context(), c.args)
err := app.Run(c.args)
if c.errMsg != "" {
assert.EqualError(t, err, c.errMsg, "case %d: error should match", n)
} else {
@ -932,7 +937,9 @@ func TestUpdateLdapBindDn(t *testing.T) {
func TestUpdateLdapSimpleAuth(t *testing.T) {
// Mock cli functions to do not exit on error
defer test.MockVariableValue(&cli.OsExiter, func(code int) {})()
osExiter := cli.OsExiter
defer func() { cli.OsExiter = osExiter }()
cli.OsExiter = func(code int) {}
// Test cases
cases := []struct {
@ -1281,7 +1288,7 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
return nil
},
createAuthSource: func(ctx context.Context, authSource *auth.Source) error {
assert.FailNow(t, "should not call createAuthSource", "case: %d", n)
assert.FailNow(t, "case %d: should not call createAuthSource", n)
return nil
},
updateAuthSource: func(ctx context.Context, authSource *auth.Source) error {
@ -1303,12 +1310,12 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
}
// Create a copy of command to test
app := cli.Command{}
app.Flags = microcmdAuthUpdateLdapSimpleAuth().Flags
app := cli.NewApp()
app.Flags = microcmdAuthUpdateLdapSimpleAuth.Flags
app.Action = service.updateLdapSimpleAuth
// Run it
err := app.Run(t.Context(), c.args)
err := app.Run(c.args)
if c.errMsg != "" {
assert.EqualError(t, err, c.errMsg, "case %d: error should match", n)
} else {

View file

@ -4,19 +4,18 @@
package cmd
import (
"context"
"errors"
"fmt"
"net/url"
auth_model "forgejo.org/models/auth"
"forgejo.org/services/auth/source/oauth2"
auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/services/auth/source/oauth2"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
func oauthCLIFlags() []cli.Flag {
return []cli.Flag{
var (
oauthCLIFlags = []cli.Flag{
&cli.StringFlag{
Name: "name",
Value: "",
@ -121,27 +120,23 @@ func oauthCLIFlags() []cli.Flag {
Usage: "Activate automatic team membership removal depending on groups",
},
}
}
func microcmdAuthAddOauth() *cli.Command {
return &cli.Command{
microcmdAuthAddOauth = &cli.Command{
Name: "add-oauth",
Usage: "Add new Oauth authentication source",
Action: runAddOauth,
Flags: oauthCLIFlags(),
}
Flags: oauthCLIFlags,
}
func microcmdAuthUpdateOauth() *cli.Command {
return &cli.Command{
microcmdAuthUpdateOauth = &cli.Command{
Name: "update-oauth",
Usage: "Update existing Oauth authentication source",
Action: runUpdateOauth,
Flags: append(oauthCLIFlags()[:1], append([]cli.Flag{idFlag()}, oauthCLIFlags()[1:]...)...),
}
Flags: append(oauthCLIFlags[:1], append([]cli.Flag{idFlag}, oauthCLIFlags[1:]...)...),
}
)
func parseOAuth2Config(_ context.Context, c *cli.Command) *oauth2.Source {
func parseOAuth2Config(c *cli.Context) *oauth2.Source {
var customURLMapping *oauth2.CustomURLMapping
if c.IsSet("use-custom-urls") {
customURLMapping = &oauth2.CustomURLMapping{
@ -173,15 +168,15 @@ func parseOAuth2Config(_ context.Context, c *cli.Command) *oauth2.Source {
}
}
func runAddOauth(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runAddOauth(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
config := parseOAuth2Config(ctx, c)
config := parseOAuth2Config(c)
if config.Provider == "openidConnect" {
discoveryURL, err := url.Parse(config.OpenIDConnectAutoDiscoveryURL)
if err != nil || (discoveryURL.Scheme != "http" && discoveryURL.Scheme != "https") {
@ -197,12 +192,12 @@ func runAddOauth(ctx context.Context, c *cli.Command) error {
})
}
func runUpdateOauth(ctx context.Context, c *cli.Command) error {
func runUpdateOauth(c *cli.Context) error {
if !c.IsSet("id") {
return errors.New("--id flag is missing")
}
ctx, cancel := installSignals(ctx)
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {

View file

@ -4,19 +4,18 @@
package cmd
import (
"context"
"errors"
"strings"
auth_model "forgejo.org/models/auth"
"forgejo.org/modules/util"
"forgejo.org/services/auth/source/smtp"
auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/auth/source/smtp"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
func smtpCLIFlags() []cli.Flag {
return []cli.Flag{
var (
smtpCLIFlags = []cli.Flag{
&cli.StringFlag{
Name: "name",
Value: "",
@ -72,27 +71,23 @@ func smtpCLIFlags() []cli.Flag {
Value: true,
},
}
}
func microcmdAuthAddSMTP() *cli.Command {
return &cli.Command{
microcmdAuthAddSMTP = &cli.Command{
Name: "add-smtp",
Usage: "Add new SMTP authentication source",
Action: runAddSMTP,
Flags: smtpCLIFlags(),
}
Flags: smtpCLIFlags,
}
func microcmdAuthUpdateSMTP() *cli.Command {
return &cli.Command{
microcmdAuthUpdateSMTP = &cli.Command{
Name: "update-smtp",
Usage: "Update existing SMTP authentication source",
Action: runUpdateSMTP,
Flags: append(smtpCLIFlags()[:1], append([]cli.Flag{idFlag()}, smtpCLIFlags()[1:]...)...),
}
Flags: append(smtpCLIFlags[:1], append([]cli.Flag{idFlag}, smtpCLIFlags[1:]...)...),
}
)
func parseSMTPConfig(c *cli.Command, conf *smtp.Source) error {
func parseSMTPConfig(c *cli.Context, conf *smtp.Source) error {
if c.IsSet("auth-type") {
conf.Auth = c.String("auth-type")
validAuthTypes := []string{"PLAIN", "LOGIN", "CRAM-MD5"}
@ -128,8 +123,8 @@ func parseSMTPConfig(c *cli.Command, conf *smtp.Source) error {
return nil
}
func runAddSMTP(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runAddSMTP(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
@ -168,12 +163,12 @@ func runAddSMTP(ctx context.Context, c *cli.Command) error {
})
}
func runUpdateSMTP(ctx context.Context, c *cli.Command) error {
func runUpdateSMTP(c *cli.Context) error {
if !c.IsSet("id") {
return errors.New("--id flag is missing")
}
ctx, cancel := installSignals(ctx)
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {

View file

@ -4,13 +4,11 @@
package cmd
import (
"context"
asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/modules/graceful"
repo_service "code.gitea.io/gitea/services/repository"
asymkey_model "forgejo.org/models/asymkey"
"forgejo.org/modules/graceful"
repo_service "forgejo.org/services/repository"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
var (
@ -27,8 +25,8 @@ var (
}
)
func runRegenerateHooks(ctx context.Context, _ *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runRegenerateHooks(_ *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
@ -37,8 +35,8 @@ func runRegenerateHooks(ctx context.Context, _ *cli.Command) error {
return repo_service.SyncRepositoryHooks(graceful.GetManager().ShutdownContext())
}
func runRegenerateKeys(ctx context.Context, _ *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runRegenerateKeys(_ *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {

View file

@ -4,21 +4,18 @@
package cmd
import (
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
func subcmdUser() *cli.Command {
return &cli.Command{
var subcmdUser = &cli.Command{
Name: "user",
Usage: "Modify users",
Commands: []*cli.Command{
microcmdUserCreate(),
microcmdUserList(),
microcmdUserChangePassword(),
microcmdUserDelete(),
microcmdUserGenerateAccessToken(),
microcmdUserMustChangePassword(),
microcmdUserResetMFA(),
Subcommands: []*cli.Command{
microcmdUserCreate,
microcmdUserList,
microcmdUserChangePassword,
microcmdUserDelete,
microcmdUserGenerateAccessToken,
microcmdUserMustChangePassword,
},
}
}

View file

@ -4,21 +4,19 @@
package cmd
import (
"context"
"errors"
"fmt"
user_model "forgejo.org/models/user"
"forgejo.org/modules/auth/password"
"forgejo.org/modules/optional"
"forgejo.org/modules/setting"
user_service "forgejo.org/services/user"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/auth/password"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/setting"
user_service "code.gitea.io/gitea/services/user"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
func microcmdUserChangePassword() *cli.Command {
return &cli.Command{
var microcmdUserChangePassword = &cli.Command{
Name: "change-password",
Usage: "Change a user's password",
Action: runChangePassword,
@ -42,14 +40,13 @@ func microcmdUserChangePassword() *cli.Command {
},
},
}
}
func runChangePassword(ctx context.Context, c *cli.Command) error {
func runChangePassword(c *cli.Context) error {
if err := argsSet(c, "username", "password"); err != nil {
return err
}
ctx, cancel := installSignals(ctx)
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {

View file

@ -4,23 +4,20 @@
package cmd
import (
"context"
"errors"
"fmt"
"strings"
auth_model "forgejo.org/models/auth"
"forgejo.org/models/db"
user_model "forgejo.org/models/user"
pwd "forgejo.org/modules/auth/password"
"forgejo.org/modules/optional"
"forgejo.org/modules/setting"
auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user"
pwd "code.gitea.io/gitea/modules/auth/password"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
func microcmdUserCreate() *cli.Command {
return &cli.Command{
var microcmdUserCreate = &cli.Command{
Name: "create",
Usage: "Create a new user in database",
Action: runCreateUser,
@ -53,6 +50,7 @@ func microcmdUserCreate() *cli.Command {
Name: "must-change-password",
Usage: "Set this option to false to prevent forcing the user to change their password after initial login",
Value: true,
DisableDefaultText: true,
},
&cli.IntFlag{
Name: "random-password-length",
@ -63,33 +61,14 @@ func microcmdUserCreate() *cli.Command {
Name: "access-token",
Usage: "Generate access token for the user",
},
&cli.StringFlag{
Name: "access-token-name",
Usage: `Name of the generated access token`,
Value: "gitea-admin",
},
&cli.StringFlag{
Name: "access-token-scopes",
Usage: `Scopes of the generated access token, comma separated. Examples: "all", "public-only,read:issue", "write:repository,write:user"`,
Value: "all",
},
&cli.BoolFlag{
Name: "restricted",
Usage: "Make a restricted user account",
},
&cli.StringFlag{
Name: "fullname",
Usage: `The full, human-readable name of the user`,
},
},
}
}
func runCreateUser(ctx context.Context, c *cli.Command) error {
// this command highly depends on the many setting options (create org, visibility, etc.), so it must have a full setting load first
// duplicate setting loading should be safe at the moment, but it should be refactored & improved in the future.
setting.LoadSettings()
func runCreateUser(c *cli.Context) error {
if err := argsSet(c, "email"); err != nil {
return err
}
@ -110,10 +89,10 @@ func runCreateUser(ctx context.Context, c *cli.Command) error {
username = c.String("username")
} else {
username = c.String("name")
_, _ = fmt.Fprint(c.Root().ErrWriter, "--name flag is deprecated. Use --username instead.\n")
_, _ = fmt.Fprintf(c.App.ErrWriter, "--name flag is deprecated. Use --username instead.\n")
}
ctx, cancel := installSignals(ctx)
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
@ -167,7 +146,6 @@ func runCreateUser(ctx context.Context, c *cli.Command) error {
IsAdmin: isAdmin,
MustChangePassword: mustChangePassword,
Visibility: visibility,
FullName: c.String("fullname"),
}
overwriteDefault := &user_model.CreateUserOverwriteOptions{
@ -175,40 +153,23 @@ func runCreateUser(ctx context.Context, c *cli.Command) error {
IsRestricted: restricted,
}
var accessTokenName string
var accessTokenScope auth_model.AccessTokenScope
if c.IsSet("access-token") {
accessTokenName = strings.TrimSpace(c.String("access-token-name"))
if accessTokenName == "" {
return errors.New("access-token-name cannot be empty")
}
var err error
accessTokenScope, err = auth_model.AccessTokenScope(c.String("access-token-scopes")).Normalize()
if err != nil {
return fmt.Errorf("invalid access token scope provided: %w", err)
}
if !accessTokenScope.HasPermissionScope() {
return errors.New("access token does not have any permission")
}
} else if c.IsSet("access-token-name") || c.IsSet("access-token-scopes") {
return errors.New("access-token-name and access-token-scopes flags are only valid when access-token flag is set")
}
// arguments should be prepared before creating the user & access token, in case there is anything wrong
// create the user
if err := user_model.CreateUser(ctx, u, overwriteDefault); err != nil {
return fmt.Errorf("CreateUser: %w", err)
}
fmt.Printf("New user '%s' has been successfully created!\n", username)
// create the access token
if accessTokenScope != "" {
t := &auth_model.AccessToken{Name: accessTokenName, UID: u.ID, Scope: accessTokenScope}
if c.Bool("access-token") {
t := &auth_model.AccessToken{
Name: "gitea-admin",
UID: u.ID,
}
if err := auth_model.NewAccessToken(ctx, t); err != nil {
return err
}
fmt.Printf("Access token was successfully created... %s\n", t.Token)
}
fmt.Printf("New user '%s' has been successfully created!\n", username)
return nil
}

View file

@ -4,20 +4,18 @@
package cmd
import (
"context"
"errors"
"fmt"
"strings"
user_model "forgejo.org/models/user"
"forgejo.org/modules/storage"
user_service "forgejo.org/services/user"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/storage"
user_service "code.gitea.io/gitea/services/user"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
func microcmdUserDelete() *cli.Command {
return &cli.Command{
var microcmdUserDelete = &cli.Command{
Name: "delete",
Usage: "Delete specific user by id, name or email",
Flags: []cli.Flag{
@ -42,14 +40,13 @@ func microcmdUserDelete() *cli.Command {
},
Action: runDeleteUser,
}
}
func runDeleteUser(ctx context.Context, c *cli.Command) error {
func runDeleteUser(c *cli.Context) error {
if !c.IsSet("id") && !c.IsSet("username") && !c.IsSet("email") {
return errors.New("You must provide the id, username or email of a user to delete")
}
ctx, cancel := installSignals(ctx)
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {

View file

@ -4,18 +4,16 @@
package cmd
import (
"context"
"errors"
"fmt"
auth_model "forgejo.org/models/auth"
user_model "forgejo.org/models/user"
auth_model "code.gitea.io/gitea/models/auth"
user_model "code.gitea.io/gitea/models/user"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
func microcmdUserGenerateAccessToken() *cli.Command {
return &cli.Command{
var microcmdUserGenerateAccessToken = &cli.Command{
Name: "generate-access-token",
Usage: "Generate an access token for a specific user",
Flags: []cli.Flag{
@ -36,20 +34,19 @@ func microcmdUserGenerateAccessToken() *cli.Command {
},
&cli.StringFlag{
Name: "scopes",
Value: "all",
Usage: `Comma separated list of scopes to apply to access token, examples: "all", "public-only,read:issue", "write:repository,write:user"`,
Value: "",
Usage: "Comma separated list of scopes to apply to access token",
},
},
Action: runGenerateAccessToken,
}
}
func runGenerateAccessToken(ctx context.Context, c *cli.Command) error {
func runGenerateAccessToken(c *cli.Context) error {
if !c.IsSet("username") {
return errors.New("you must provide a username to generate a token for")
return errors.New("You must provide a username to generate a token for")
}
ctx, cancel := installSignals(ctx)
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
@ -80,9 +77,6 @@ func runGenerateAccessToken(ctx context.Context, c *cli.Command) error {
if err != nil {
return fmt.Errorf("invalid access token scope provided: %w", err)
}
if !accessTokenScope.HasPermissionScope() {
return errors.New("access token does not have any permission")
}
t.Scope = accessTokenScope
// create the token

View file

@ -4,18 +4,16 @@
package cmd
import (
"context"
"fmt"
"os"
"text/tabwriter"
user_model "forgejo.org/models/user"
user_model "code.gitea.io/gitea/models/user"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
func microcmdUserList() *cli.Command {
return &cli.Command{
var microcmdUserList = &cli.Command{
Name: "list",
Usage: "List users",
Action: runListUsers,
@ -26,10 +24,9 @@ func microcmdUserList() *cli.Command {
},
},
}
}
func runListUsers(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runListUsers(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
@ -44,7 +41,7 @@ func runListUsers(ctx context.Context, c *cli.Command) error {
w := tabwriter.NewWriter(os.Stdout, 5, 0, 1, ' ', 0)
if c.IsSet("admin") {
fmt.Fprint(w, "ID\tUsername\tEmail\tIsActive\n")
fmt.Fprintf(w, "ID\tUsername\tEmail\tIsActive\n")
for _, u := range users {
if u.IsAdmin {
fmt.Fprintf(w, "%d\t%s\t%s\t%t\n", u.ID, u.Name, u.Email, u.IsActive)
@ -52,7 +49,7 @@ func runListUsers(ctx context.Context, c *cli.Command) error {
}
} else {
twofa := user_model.UserList(users).GetTwoFaStatus(ctx)
fmt.Fprint(w, "ID\tUsername\tEmail\tIsActive\tIsAdmin\t2FA\n")
fmt.Fprintf(w, "ID\tUsername\tEmail\tIsActive\tIsAdmin\t2FA\n")
for _, u := range users {
fmt.Fprintf(w, "%d\t%s\t%s\t%t\t%t\t%t\n", u.ID, u.Name, u.Email, u.IsActive, u.IsAdmin, twofa[u.ID])
}

View file

@ -4,17 +4,15 @@
package cmd
import (
"context"
"errors"
"fmt"
user_model "forgejo.org/models/user"
user_model "code.gitea.io/gitea/models/user"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
func microcmdUserMustChangePassword() *cli.Command {
return &cli.Command{
var microcmdUserMustChangePassword = &cli.Command{
Name: "must-change-password",
Usage: "Set the must change password flag for the provided users or all users",
Action: runMustChangePassword,
@ -35,10 +33,9 @@ func microcmdUserMustChangePassword() *cli.Command {
},
},
}
}
func runMustChangePassword(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runMustChangePassword(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if c.NArg() == 0 && !c.IsSet("all") {

View file

@ -1,73 +0,0 @@
// Copyright 2025 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"context"
"fmt"
auth_model "forgejo.org/models/auth"
user_model "forgejo.org/models/user"
"github.com/urfave/cli/v3"
)
func microcmdUserResetMFA() *cli.Command {
return &cli.Command{
Name: "reset-mfa",
Usage: "Remove all two-factor authentication configurations for a user",
Action: runResetMFA,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "username",
Aliases: []string{"u"},
Value: "",
Usage: "The user to update",
},
},
}
}
func runResetMFA(ctx context.Context, c *cli.Command) error {
if err := argsSet(c, "username"); err != nil {
return err
}
ctx, cancel := installSignals(ctx)
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
user, err := user_model.GetUserByName(ctx, c.String("username"))
if err != nil {
return err
}
webAuthnList, err := auth_model.GetWebAuthnCredentialsByUID(ctx, user.ID)
if err != nil {
return err
}
for _, credential := range webAuthnList {
if _, err := auth_model.DeleteCredential(ctx, credential.ID, user.ID); err != nil {
return err
}
}
tfaModes, err := auth_model.GetTwoFactorByUID(ctx, user.ID)
if err == nil && tfaModes != nil {
if err := auth_model.DeleteTwoFactorByID(ctx, tfaModes.ID, user.ID); err != nil {
return err
}
} else {
if _, is := err.(auth_model.ErrTwoFactorNotEnrolled); !is {
return err
}
}
fmt.Printf("%s's two-factor authentication settings have been removed!\n", user.Name)
return nil
}

View file

@ -6,7 +6,6 @@
package cmd
import (
"context"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
@ -21,12 +20,11 @@ import (
"strings"
"time"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
// CmdCert represents the available cert sub-command.
func cmdCert() *cli.Command {
return &cli.Command{
var CmdCert = &cli.Command{
Name: "cert",
Usage: "Generate self-signed certificate",
Description: `Generate a self-signed X.509 certificate for a TLS server.
@ -64,7 +62,6 @@ Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`,
},
},
}
}
func publicKey(priv any) any {
switch k := priv.(type) {
@ -92,7 +89,7 @@ func pemBlockForKey(priv any) *pem.Block {
}
}
func runCert(ctx context.Context, c *cli.Command) error {
func runCert(c *cli.Context) error {
if err := argsSet(c, "host"); err != nil {
return err
}

View file

@ -15,28 +15,26 @@ import (
"strings"
"syscall"
"forgejo.org/models/db"
"forgejo.org/modules/log"
"forgejo.org/modules/setting"
"forgejo.org/modules/util"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
// argsSet checks that all the required arguments are set. args is a list of
// arguments that must be set in the passed Context.
func argsSet(c *cli.Command, args ...string) error {
func argsSet(c *cli.Context, args ...string) error {
for _, a := range args {
if !c.IsSet(a) {
return errors.New(a + " is not set")
}
if s, ok := c.Value(a).(string); ok {
if util.IsEmptyString(s) {
if util.IsEmptyString(c.String(a)) {
return errors.New(a + " is required")
}
}
}
return nil
}
@ -75,8 +73,8 @@ If this is the intended configuration file complete the [database] section.`, se
return nil
}
func installSignals(ctx context.Context) (context.Context, context.CancelFunc) {
ctx, cancel := context.WithCancel(ctx)
func installSignals() (context.Context, context.CancelFunc) {
ctx, cancel := context.WithCancel(context.Background())
go func() {
// install notify
signalChannel := make(chan os.Signal, 1)
@ -111,7 +109,7 @@ func setupConsoleLogger(level log.Level, colorize bool, out io.Writer) {
log.GetManager().GetLogger(log.DEFAULT).ReplaceAllWriters(writer)
}
func globalBool(c *cli.Command, name string) bool {
func globalBool(c *cli.Context, name string) bool {
for _, ctx := range c.Lineage() {
if ctx.Bool(name) {
return true
@ -122,16 +120,16 @@ func globalBool(c *cli.Command, name string) bool {
// PrepareConsoleLoggerLevel by default, use INFO level for console logger, but some sub-commands (for git/ssh protocol) shouldn't output any log to stdout.
// Any log appears in git stdout pipe will break the git protocol, eg: client can't push and hangs forever.
func PrepareConsoleLoggerLevel(defaultLevel log.Level) func(ctx context.Context, cli *cli.Command) (context.Context, error) {
return func(ctx context.Context, cli *cli.Command) (context.Context, error) {
func PrepareConsoleLoggerLevel(defaultLevel log.Level) func(*cli.Context) error {
return func(c *cli.Context) error {
level := defaultLevel
if globalBool(cli, "quiet") {
if globalBool(c, "quiet") {
level = log.FATAL
}
if globalBool(cli, "debug") || globalBool(cli, "verbose") {
if globalBool(c, "debug") || globalBool(c, "verbose") {
level = log.TRACE
}
log.SetConsoleLogger(log.DEFAULT, "console-default", level)
return ctx, nil
return nil
}
}

65
cmd/docs.go Normal file
View file

@ -0,0 +1,65 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"fmt"
"os"
"strings"
"github.com/urfave/cli/v2"
)
// CmdDocs represents the available docs sub-command.
var CmdDocs = &cli.Command{
Name: "docs",
Usage: "Output CLI documentation",
Description: "A command to output Forgejo's CLI documentation, optionally to a file.",
Action: runDocs,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "man",
Usage: "Output man pages instead",
},
&cli.StringFlag{
Name: "output",
Aliases: []string{"o"},
Usage: "Path to output to instead of stdout (will overwrite if exists)",
},
},
}
func runDocs(ctx *cli.Context) error {
docs, err := ctx.App.ToMarkdown()
if ctx.Bool("man") {
docs, err = ctx.App.ToMan()
}
if err != nil {
return err
}
if !ctx.Bool("man") {
// Clean up markdown. The following bug was fixed in v2, but is present in v1.
// It affects markdown output (even though the issue is referring to man pages)
// https://github.com/urfave/cli/issues/1040
firstHashtagIndex := strings.Index(docs, "#")
if firstHashtagIndex > 0 {
docs = docs[firstHashtagIndex:]
}
}
out := os.Stdout
if ctx.String("output") != "" {
fi, err := os.Create(ctx.String("output"))
if err != nil {
return err
}
defer fi.Close()
out = fi
}
_, err = fmt.Fprintln(out, docs)
return err
}

View file

@ -4,7 +4,6 @@
package cmd
import (
"context"
"fmt"
golog "log"
"os"
@ -12,34 +11,32 @@ import (
"strings"
"text/tabwriter"
"forgejo.org/models/db"
"forgejo.org/models/migrations"
migrate_base "forgejo.org/models/migrations/base"
"forgejo.org/modules/container"
"forgejo.org/modules/log"
"forgejo.org/modules/setting"
"forgejo.org/services/doctor"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/migrations"
migrate_base "code.gitea.io/gitea/models/migrations/base"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/services/doctor"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
"xorm.io/xorm"
)
// CmdDoctor represents the available doctor sub-command.
func cmdDoctor() *cli.Command {
return &cli.Command{
var CmdDoctor = &cli.Command{
Name: "doctor",
Usage: "Diagnose and optionally fix problems, convert or re-create database tables",
Description: "A command to diagnose problems with the current Forgejo instance according to the given configuration. Some problems can optionally be fixed by modifying the database or data storage.",
Commands: []*cli.Command{
cmdDoctorCheck(),
cmdRecreateTable(),
cmdDoctorConvert(),
Subcommands: []*cli.Command{
cmdDoctorCheck,
cmdRecreateTable,
cmdDoctorConvert,
},
}
}
func cmdDoctorCheck() *cli.Command {
return &cli.Command{
var cmdDoctorCheck = &cli.Command{
Name: "check",
Usage: "Diagnose and optionally fix problems",
Description: "A command to diagnose problems with the current Forgejo instance according to the given configuration. Some problems can optionally be fixed by modifying the database or data storage.",
@ -76,10 +73,8 @@ func cmdDoctorCheck() *cli.Command {
},
},
}
}
func cmdRecreateTable() *cli.Command {
return &cli.Command{
var cmdRecreateTable = &cli.Command{
Name: "recreate-table",
Usage: "Recreate tables from XORM definitions and copy the data.",
ArgsUsage: "[TABLE]... : (TABLEs to recreate - leave blank for all)",
@ -96,10 +91,9 @@ This command will cause Xorm to recreate tables, copying over the data and delet
You should back-up your database before doing this and ensure that your database is up-to-date first.`,
Action: runRecreateTable,
}
}
func runRecreateTable(stdCtx context.Context, ctx *cli.Command) error {
stdCtx, cancel := installSignals(stdCtx)
func runRecreateTable(ctx *cli.Context) error {
stdCtx, cancel := installSignals()
defer cancel()
// Redirect the default golog to here
@ -126,7 +120,7 @@ func runRecreateTable(stdCtx context.Context, ctx *cli.Command) error {
args := ctx.Args()
names := make([]string, 0, ctx.NArg())
for i := range ctx.NArg() {
for i := 0; i < ctx.NArg(); i++ {
names = append(names, args.Get(i))
}
@ -136,31 +130,24 @@ func runRecreateTable(stdCtx context.Context, ctx *cli.Command) error {
}
recreateTables := migrate_base.RecreateTables(beans...)
return db.InitEngineWithMigration(stdCtx, func(x db.Engine) error {
engine, err := db.GetMasterEngine(x)
if err != nil {
return db.InitEngineWithMigration(stdCtx, func(x *xorm.Engine) error {
if err := migrations.EnsureUpToDate(x); err != nil {
return err
}
if err := migrations.EnsureUpToDate(engine); err != nil {
return err
}
return recreateTables(engine)
return recreateTables(x)
})
}
func setupDoctorDefaultLogger(ctx *cli.Command, colorize bool) {
func setupDoctorDefaultLogger(ctx *cli.Context, colorize bool) {
// Silence the default loggers
setupConsoleLogger(log.FATAL, log.CanColorStderr, os.Stderr)
logFile := ctx.String("log-file")
switch logFile {
case "":
if logFile == "" {
return // if no doctor log-file is set, do not show any log from default logger
case "-":
} else if logFile == "-" {
setupConsoleLogger(log.TRACE, colorize, os.Stdout)
default:
} else {
logFile, _ = filepath.Abs(logFile)
writeMode := log.WriterMode{Level: log.TRACE, WriterOption: log.WriterFileOption{FileName: logFile}}
writer, err := log.NewEventWriter("console-to-file", "file", writeMode)
@ -172,8 +159,8 @@ func setupDoctorDefaultLogger(ctx *cli.Command, colorize bool) {
}
}
func runDoctorCheck(stdCtx context.Context, ctx *cli.Command) error {
stdCtx, cancel := installSignals(stdCtx)
func runDoctorCheck(ctx *cli.Context) error {
stdCtx, cancel := installSignals()
defer cancel()
colorize := log.CanColorStdout

View file

@ -4,28 +4,25 @@
package cmd
import (
"context"
"fmt"
"forgejo.org/models/db"
"forgejo.org/modules/log"
"forgejo.org/modules/setting"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
// cmdDoctorConvert represents the available convert sub-command.
func cmdDoctorConvert() *cli.Command {
return &cli.Command{
var cmdDoctorConvert = &cli.Command{
Name: "convert",
Usage: "Convert the database",
Description: "A command to convert an existing MySQL database from utf8 to utf8mb4",
Action: runDoctorConvert,
}
}
func runDoctorConvert(stdCtx context.Context, ctx *cli.Command) error {
stdCtx, cancel := installSignals(stdCtx)
func runDoctorConvert(ctx *cli.Context) error {
stdCtx, cancel := installSignals()
defer cancel()
if err := initDB(stdCtx); err != nil {

View file

@ -7,11 +7,11 @@ import (
"context"
"testing"
"forgejo.org/modules/log"
"forgejo.org/services/doctor"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/services/doctor"
"github.com/stretchr/testify/require"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
func TestDoctorRun(t *testing.T) {
@ -22,12 +22,12 @@ func TestDoctorRun(t *testing.T) {
SkipDatabaseInitialization: true,
})
app := cli.Command{}
app.Commands = []*cli.Command{cmdDoctorCheck()}
err := app.Run(t.Context(), []string{"./gitea", "check", "--run", "test-check"})
app := cli.NewApp()
app.Commands = []*cli.Command{cmdDoctorCheck}
err := app.Run([]string{"./gitea", "check", "--run", "test-check"})
require.NoError(t, err)
err = app.Run(t.Context(), []string{"./gitea", "check", "--run", "no-such"})
err = app.Run([]string{"./gitea", "check", "--run", "no-such"})
require.ErrorContains(t, err, `unknown checks: "no-such"`)
err = app.Run(t.Context(), []string{"./gitea", "check", "--run", "test-check,no-such"})
err = app.Run([]string{"./gitea", "check", "--run", "test-check,no-such"})
require.ErrorContains(t, err, `unknown checks: "no-such"`)
}

View file

@ -5,8 +5,6 @@
package cmd
import (
"context"
"errors"
"fmt"
"io"
"os"
@ -15,16 +13,16 @@ import (
"strings"
"time"
"forgejo.org/models/db"
"forgejo.org/modules/json"
"forgejo.org/modules/log"
"forgejo.org/modules/setting"
"forgejo.org/modules/storage"
"forgejo.org/modules/util"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage"
"code.gitea.io/gitea/modules/util"
"code.forgejo.org/go-chi/session"
"github.com/mholt/archiver/v3"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
func addReader(w archiver.Writer, r io.ReadCloser, info os.FileInfo, customName string, verbose bool) error {
@ -85,10 +83,6 @@ func (o *outputType) Set(value string) error {
return fmt.Errorf("allowed values are %s", o.Join())
}
func (o *outputType) Get() any {
return o.String()
}
func (o outputType) String() string {
if o.selected == "" {
return o.Default
@ -102,8 +96,7 @@ var outputTypeEnum = &outputType{
}
// CmdDump represents the available dump sub-command.
func cmdDump() *cli.Command {
return &cli.Command{
var CmdDump = &cli.Command{
Name: "dump",
Usage: "Dump Forgejo files and database",
Description: `Dump compresses all related files and database into zip file.
@ -129,6 +122,7 @@ It can be used for backup and capture Forgejo server image to send to maintainer
&cli.StringFlag{
Name: "tempdir",
Aliases: []string{"t"},
Value: os.TempDir(),
Usage: "Temporary dir path",
},
&cli.StringFlag{
@ -139,12 +133,12 @@ It can be used for backup and capture Forgejo server image to send to maintainer
&cli.BoolFlag{
Name: "skip-repository",
Aliases: []string{"R"},
Usage: "Skip repositories",
Usage: "Skip the repository dumping",
},
&cli.BoolFlag{
Name: "skip-log",
Aliases: []string{"L"},
Usage: "Skip logs",
Usage: "Skip the log dumping",
},
&cli.BoolFlag{
Name: "skip-custom-dir",
@ -166,10 +160,6 @@ It can be used for backup and capture Forgejo server image to send to maintainer
Name: "skip-index",
Usage: "Skip bleve index data",
},
&cli.BoolFlag{
Name: "skip-repo-archives",
Usage: "Skip repository archives",
},
&cli.GenericFlag{
Name: "type",
Value: outputTypeEnum,
@ -177,14 +167,13 @@ It can be used for backup and capture Forgejo server image to send to maintainer
},
},
}
}
func fatal(format string, args ...any) {
fmt.Fprintf(os.Stderr, format+"\n", args...)
log.Fatal(format, args...)
}
func runDump(stdCtx context.Context, ctx *cli.Command) error {
func runDump(ctx *cli.Context) error {
var file *os.File
fileName := ctx.String("file")
outType := ctx.String("type")
@ -220,16 +209,16 @@ func runDump(stdCtx context.Context, ctx *cli.Command) error {
if !setting.InstallLock {
log.Error("Is '%s' really the right config path?\n", setting.CustomConf)
return errors.New("forgejo is not initialized")
return fmt.Errorf("forgejo is not initialized")
}
setting.LoadSettings() // cannot access session settings otherwise
verbose := ctx.Bool("verbose")
if verbose && ctx.Bool("quiet") {
return errors.New("--quiet and --verbose cannot both be set")
return fmt.Errorf("--quiet and --verbose cannot both be set")
}
stdCtx, cancel := installSignals(stdCtx)
stdCtx, cancel := installSignals()
defer cancel()
err := db.InitEngine(stdCtx)
@ -244,7 +233,7 @@ func runDump(stdCtx context.Context, ctx *cli.Command) error {
if file == nil {
file, err = os.Create(fileName)
if err != nil {
fatal("Failed to open %s: %v", fileName, err)
fatal("Unable to open %s: %v", fileName, err)
}
}
defer file.Close()
@ -261,7 +250,7 @@ func runDump(stdCtx context.Context, ctx *cli.Command) error {
iface, err = archiver.ByExtension(fileName)
}
if err != nil {
fatal("Failed to get archiver for extension: %v", err)
fatal("Unable to get archiver for extension: %v", err)
}
w, _ := iface.(archiver.Writer)
@ -271,7 +260,7 @@ func runDump(stdCtx context.Context, ctx *cli.Command) error {
defer w.Close()
if ctx.IsSet("skip-repository") && ctx.Bool("skip-repository") {
log.Info("Skipping local repositories")
log.Info("Skip dumping local repositories")
} else {
log.Info("Dumping local repositories... %s", setting.RepoRootPath)
if err := addRecursiveExclude(w, "repos", setting.RepoRootPath, []string{absFileName}, verbose); err != nil {
@ -279,9 +268,9 @@ func runDump(stdCtx context.Context, ctx *cli.Command) error {
}
if ctx.IsSet("skip-lfs-data") && ctx.Bool("skip-lfs-data") {
log.Info("Skipping LFS data")
log.Info("Skip dumping LFS data")
} else if !setting.LFS.StartServer {
log.Info("LFS not enabled - skipping")
log.Info("LFS isn't enabled. Skip dumping LFS data")
} else if err := storage.LFS.IterateObjects("", func(objPath string, object storage.Object) error {
info, err := object.Stat()
if err != nil {
@ -295,31 +284,18 @@ func runDump(stdCtx context.Context, ctx *cli.Command) error {
}
tmpDir := ctx.String("tempdir")
if tmpDir == "" {
tmpDir, err = os.MkdirTemp("", "forgejo-dump-*")
if err != nil {
fatal("Failed to create temporary directory: %v", err)
}
defer func() {
if err := util.Remove(tmpDir); err != nil {
log.Warn("Failed to remove temporary directory: %s: Error: %v", tmpDir, err)
}
}()
}
if _, err := os.Stat(tmpDir); os.IsNotExist(err) {
fatal("Path does not exist: %s", tmpDir)
}
dbDump, err := os.CreateTemp(tmpDir, "forgejo-db.sql")
if err != nil {
fatal("Failed to create temporary file: %v", err)
fatal("Failed to create tmp file: %v", err)
}
defer func() {
_ = dbDump.Close()
if err := util.Remove(dbDump.Name()); err != nil {
log.Warn("Failed to remove temporary database file: %s: Error: %v", dbDump.Name(), err)
log.Warn("Unable to remove temporary file: %s: Error: %v", dbDump.Name(), err)
}
}()
@ -355,16 +331,16 @@ func runDump(stdCtx context.Context, ctx *cli.Command) error {
fatal("Failed to include custom: %v", err)
}
} else {
log.Info("Custom dir %s is inside data dir %s, skipping", setting.CustomPath, setting.AppDataPath)
log.Info("Custom dir %s is inside data dir %s, skipped", setting.CustomPath, setting.AppDataPath)
}
} else {
log.Info("Custom dir %s does not exist, skipping", setting.CustomPath)
log.Info("Custom dir %s doesn't exist, skipped", setting.CustomPath)
}
}
isExist, err := util.IsExist(setting.AppDataPath)
if err != nil {
log.Error("Failed to check if %s exists: %v", setting.AppDataPath, err)
log.Error("Unable to check if %s exists. Error: %v", setting.AppDataPath, err)
}
if isExist {
log.Info("Packing data directory...%s", setting.AppDataPath)
@ -379,16 +355,10 @@ func runDump(stdCtx context.Context, ctx *cli.Command) error {
}
if ctx.IsSet("skip-index") && ctx.Bool("skip-index") {
log.Info("Skipping bleve index data")
excludes = append(excludes, setting.Indexer.RepoPath)
excludes = append(excludes, setting.Indexer.IssuePath)
}
if ctx.IsSet("skip-repo-archives") && ctx.Bool("skip-repo-archives") {
log.Info("Skipping repository archives data")
excludes = append(excludes, setting.RepoArchive.Storage.Path)
}
excludes = append(excludes, setting.RepoRootPath)
excludes = append(excludes, setting.LFS.Storage.Path)
excludes = append(excludes, setting.Attachment.Storage.Path)
@ -401,7 +371,7 @@ func runDump(stdCtx context.Context, ctx *cli.Command) error {
}
if ctx.IsSet("skip-attachment-data") && ctx.Bool("skip-attachment-data") {
log.Info("Skipping attachment data")
log.Info("Skip dumping attachment data")
} else if err := storage.Attachments.IterateObjects("", func(objPath string, object storage.Object) error {
info, err := object.Stat()
if err != nil {
@ -414,9 +384,9 @@ func runDump(stdCtx context.Context, ctx *cli.Command) error {
}
if ctx.IsSet("skip-package-data") && ctx.Bool("skip-package-data") {
log.Info("Skipping package data")
log.Info("Skip dumping package data")
} else if !setting.Packages.Enabled {
log.Info("Package registry not enabled - skipping")
log.Info("Packages isn't enabled. Skip dumping package data")
} else if err := storage.Packages.IterateObjects("", func(objPath string, object storage.Object) error {
info, err := object.Stat()
if err != nil {
@ -432,11 +402,11 @@ func runDump(stdCtx context.Context, ctx *cli.Command) error {
// ensuring that it's clear the dump is skipped whether the directory's initialized
// yet or not.
if ctx.IsSet("skip-log") && ctx.Bool("skip-log") {
log.Info("Skipping log files")
log.Info("Skip dumping log files")
} else {
isExist, err := util.IsExist(setting.Log.RootPath)
if err != nil {
log.Error("Failed to check if %s exists: %v", setting.Log.RootPath, err)
log.Error("Unable to check if %s exists. Error: %v", setting.Log.RootPath, err)
}
if isExist {
if err := addRecursiveExclude(w, "log", setting.Log.RootPath, []string{absFileName}, verbose); err != nil {
@ -486,7 +456,7 @@ func addRecursiveExclude(w archiver.Writer, insidePath, absPath string, excludeA
currentInsidePath := path.Join(insidePath, file.Name())
if util.SliceContainsString(excludeAbsPath, currentAbsPath) {
log.Debug("Skipping %q (matched an excluded path)", currentAbsPath)
log.Debug("Skipping %q because matched an excluded path.", currentAbsPath)
continue
}

View file

@ -10,21 +10,20 @@ import (
"os"
"strings"
"forgejo.org/modules/git"
"forgejo.org/modules/log"
base "forgejo.org/modules/migration"
"forgejo.org/modules/setting"
"forgejo.org/modules/structs"
"forgejo.org/modules/util"
"forgejo.org/services/convert"
"forgejo.org/services/migrations"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
base "code.gitea.io/gitea/modules/migration"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/convert"
"code.gitea.io/gitea/services/migrations"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
// CmdDumpRepository represents the available dump repository sub-command.
func cmdDumpRepository() *cli.Command {
return &cli.Command{
var CmdDumpRepository = &cli.Command{
Name: "dump-repo",
Usage: "Dump the repository from git/github/gitea/gitlab",
Description: "This is a command for dumping the repository data.",
@ -79,15 +78,9 @@ wiki, issues, labels, releases, release_assets, milestones, pull_requests, comme
},
},
}
}
func runDumpRepository(stdCtx context.Context, ctx *cli.Command) error {
setupConsoleLogger(log.INFO, log.CanColorStderr, os.Stderr)
// setting.DisableLoggerInit()
setting.LoadSettings() // cannot access skip_tls_verify settings otherwise
stdCtx, cancel := installSignals(stdCtx)
func runDumpRepository(ctx *cli.Context) error {
stdCtx, cancel := installSignals()
defer cancel()
if err := initDB(stdCtx); err != nil {

View file

@ -4,41 +4,38 @@
package cmd
import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"forgejo.org/modules/assetfs"
"forgejo.org/modules/log"
"forgejo.org/modules/options"
"forgejo.org/modules/public"
"forgejo.org/modules/setting"
"forgejo.org/modules/templates"
"forgejo.org/modules/util"
"code.gitea.io/gitea/modules/assetfs"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/options"
"code.gitea.io/gitea/modules/public"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/util"
"github.com/gobwas/glob"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
// CmdEmbedded represents the available extract sub-command.
func cmdEmbedded() *cli.Command {
return &cli.Command{
var (
CmdEmbedded = &cli.Command{
Name: "embedded",
Usage: "Extract embedded resources",
Description: "A command for extracting embedded resources, like templates and images",
Commands: []*cli.Command{
subcmdList(),
subcmdView(),
subcmdExtract(),
Subcommands: []*cli.Command{
subcmdList,
subcmdView,
subcmdExtract,
},
}
}
func subcmdList() *cli.Command {
return &cli.Command{
subcmdList = &cli.Command{
Name: "list",
Usage: "List files matching the given pattern",
Action: runList,
@ -50,10 +47,8 @@ func subcmdList() *cli.Command {
},
},
}
}
func subcmdView() *cli.Command {
return &cli.Command{
subcmdView = &cli.Command{
Name: "view",
Usage: "View a file matching the given pattern",
Action: runView,
@ -65,10 +60,8 @@ func subcmdView() *cli.Command {
},
},
}
}
func subcmdExtract() *cli.Command {
return &cli.Command{
subcmdExtract = &cli.Command{
Name: "extract",
Usage: "Extract resources",
Action: runExtract,
@ -97,9 +90,9 @@ func subcmdExtract() *cli.Command {
},
},
}
}
var matchedAssetFiles []assetFile
matchedAssetFiles []assetFile
)
type assetFile struct {
fs *assetfs.LayeredFS
@ -107,7 +100,7 @@ type assetFile struct {
path string
}
func initEmbeddedExtractor(_ context.Context, c *cli.Command) error {
func initEmbeddedExtractor(c *cli.Context) error {
setupConsoleLogger(log.ERROR, log.CanColorStderr, os.Stderr)
patterns, err := compileCollectPatterns(c.Args().Slice())
@ -122,32 +115,32 @@ func initEmbeddedExtractor(_ context.Context, c *cli.Command) error {
return nil
}
func runList(ctx context.Context, c *cli.Command) error {
if err := runListDo(ctx, c); err != nil {
func runList(c *cli.Context) error {
if err := runListDo(c); err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
return err
}
return nil
}
func runView(ctx context.Context, c *cli.Command) error {
if err := runViewDo(ctx, c); err != nil {
func runView(c *cli.Context) error {
if err := runViewDo(c); err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
return err
}
return nil
}
func runExtract(ctx context.Context, c *cli.Command) error {
if err := runExtractDo(ctx, c); err != nil {
func runExtract(c *cli.Context) error {
if err := runExtractDo(c); err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
return err
}
return nil
}
func runListDo(ctx context.Context, c *cli.Command) error {
if err := initEmbeddedExtractor(ctx, c); err != nil {
func runListDo(c *cli.Context) error {
if err := initEmbeddedExtractor(c); err != nil {
return err
}
@ -158,8 +151,8 @@ func runListDo(ctx context.Context, c *cli.Command) error {
return nil
}
func runViewDo(ctx context.Context, c *cli.Command) error {
if err := initEmbeddedExtractor(ctx, c); err != nil {
func runViewDo(c *cli.Context) error {
if err := initEmbeddedExtractor(c); err != nil {
return err
}
@ -181,8 +174,8 @@ func runViewDo(ctx context.Context, c *cli.Command) error {
return nil
}
func runExtractDo(ctx context.Context, c *cli.Command) error {
if err := initEmbeddedExtractor(ctx, c); err != nil {
func runExtractDo(c *cli.Context) error {
if err := initEmbeddedExtractor(c); err != nil {
return err
}
@ -278,7 +271,7 @@ func extractAsset(d string, a assetFile, overwrite, rename bool) error {
return nil
}
func collectAssetFilesByPattern(c *cli.Command, globs []glob.Glob, path string, layer *assetfs.Layer) {
func collectAssetFilesByPattern(c *cli.Context, globs []glob.Glob, path string, layer *assetfs.Layer) {
fs := assetfs.Layered(layer)
files, err := fs.ListAllFiles(".", true)
if err != nil {

View file

@ -6,25 +6,24 @@ package forgejo
import (
"context"
"encoding/hex"
"errors"
"fmt"
"io"
"os"
"strings"
actions_model "forgejo.org/models/actions"
"forgejo.org/modules/private"
"forgejo.org/modules/setting"
private_routers "forgejo.org/routers/private"
actions_model "code.gitea.io/gitea/models/actions"
"code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/setting"
private_routers "code.gitea.io/gitea/routers/private"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
func CmdActions(ctx context.Context) *cli.Command {
return &cli.Command{
Name: "actions",
Usage: "Commands for managing Forgejo Actions",
Commands: []*cli.Command{
Subcommands: []*cli.Command{
SubcmdActionsGenerateRunnerToken(ctx),
SubcmdActionsGenerateRunnerSecret(ctx),
SubcmdActionsRegister(ctx),
@ -37,7 +36,7 @@ func SubcmdActionsGenerateRunnerToken(ctx context.Context) *cli.Command {
Name: "generate-runner-token",
Usage: "Generate a new token for a runner to use to register with the server",
Before: prepareWorkPathAndCustomConf(ctx),
Action: RunGenerateActionsRunnerToken,
Action: func(cliCtx *cli.Context) error { return RunGenerateActionsRunnerToken(ctx, cliCtx) },
Flags: []cli.Flag{
&cli.StringFlag{
Name: "scope",
@ -53,7 +52,7 @@ func SubcmdActionsGenerateRunnerSecret(ctx context.Context) *cli.Command {
return &cli.Command{
Name: "generate-secret",
Usage: "Generate a secret suitable for input to the register subcommand",
Action: RunGenerateSecret,
Action: func(cliCtx *cli.Context) error { return RunGenerateSecret(ctx, cliCtx) },
}
}
@ -62,7 +61,7 @@ func SubcmdActionsRegister(ctx context.Context) *cli.Command {
Name: "register",
Usage: "Idempotent registration of a runner using a shared secret",
Before: prepareWorkPathAndCustomConf(ctx),
Action: RunRegister,
Action: func(cliCtx *cli.Context) error { return RunRegister(ctx, cliCtx) },
Flags: []cli.Flag{
&cli.StringFlag{
Name: "secret",
@ -106,26 +105,26 @@ func SubcmdActionsRegister(ctx context.Context) *cli.Command {
}
}
func readSecret(ctx context.Context, cli *cli.Command) (string, error) {
if cli.IsSet("secret") {
return cli.String("secret"), nil
func readSecret(ctx context.Context, cliCtx *cli.Context) (string, error) {
if cliCtx.IsSet("secret") {
return cliCtx.String("secret"), nil
}
if cli.IsSet("secret-stdin") {
if cliCtx.IsSet("secret-stdin") {
buf, err := io.ReadAll(ContextGetStdin(ctx))
if err != nil {
return "", err
}
return string(buf), nil
}
if cli.IsSet("secret-file") {
path := cli.String("secret-file")
if cliCtx.IsSet("secret-file") {
path := cliCtx.String("secret-file")
buf, err := os.ReadFile(path)
if err != nil {
return "", err
}
return string(buf), nil
}
return "", errors.New("at least one of the --secret, --secret-stdin, --secret-file options is required")
return "", fmt.Errorf("at least one of the --secret, --secret-stdin, --secret-file options is required")
}
func validateSecret(secret string) error {
@ -139,18 +138,18 @@ func validateSecret(secret string) error {
return nil
}
func getLabels(cli *cli.Command) (*[]string, error) {
if !cli.Bool("keep-labels") {
lblValue := strings.Split(cli.String("labels"), ",")
func getLabels(cliCtx *cli.Context) (*[]string, error) {
if !cliCtx.Bool("keep-labels") {
lblValue := strings.Split(cliCtx.String("labels"), ",")
return &lblValue, nil
}
if cli.String("labels") != "" {
return nil, errors.New("--labels and --keep-labels should not be used together")
if cliCtx.String("labels") != "" {
return nil, fmt.Errorf("--labels and --keep-labels should not be used together")
}
return nil, nil
}
func RunRegister(ctx context.Context, cli *cli.Command) error {
func RunRegister(ctx context.Context, cliCtx *cli.Context) error {
var cancel context.CancelFunc
if !ContextGetNoInit(ctx) {
ctx, cancel = installSignals(ctx)
@ -162,17 +161,17 @@ func RunRegister(ctx context.Context, cli *cli.Command) error {
}
setting.MustInstalled()
secret, err := readSecret(ctx, cli)
secret, err := readSecret(ctx, cliCtx)
if err != nil {
return err
}
if err := validateSecret(secret); err != nil {
return err
}
scope := cli.String("scope")
name := cli.String("name")
version := cli.String("version")
labels, err := getLabels(cli)
scope := cliCtx.String("scope")
name := cliCtx.String("name")
version := cliCtx.String("version")
labels, err := getLabels(cliCtx)
if err != nil {
return err
}
@ -210,7 +209,7 @@ func RunRegister(ctx context.Context, cli *cli.Command) error {
return nil
}
func RunGenerateSecret(ctx context.Context, cli *cli.Command) error {
func RunGenerateSecret(ctx context.Context, cliCtx *cli.Context) error {
runner := actions_model.ActionRunner{}
if err := runner.GenerateToken(); err != nil {
return err
@ -221,7 +220,7 @@ func RunGenerateSecret(ctx context.Context, cli *cli.Command) error {
return nil
}
func RunGenerateActionsRunnerToken(ctx context.Context, cli *cli.Command) error {
func RunGenerateActionsRunnerToken(ctx context.Context, cliCtx *cli.Context) error {
if !ContextGetNoInit(ctx) {
var cancel context.CancelFunc
ctx, cancel = installSignals(ctx)
@ -230,7 +229,7 @@ func RunGenerateActionsRunnerToken(ctx context.Context, cli *cli.Command) error
setting.MustInstalled()
scope := cli.String("scope")
scope := cliCtx.String("scope")
respText, extra := private.GenerateActionsRunnerToken(ctx, scope)
if extra.HasError() {

View file

@ -4,13 +4,14 @@
package forgejo
import (
"context"
"fmt"
"testing"
"code.gitea.io/gitea/services/context"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
func TestActions_getLabels(t *testing.T) {
@ -53,21 +54,21 @@ func TestActions_getLabels(t *testing.T) {
},
}
flags := SubcmdActionsRegister(t.Context()).Flags
flags := SubcmdActionsRegister(context.Context{}).Flags
for _, c := range cases {
t.Run(fmt.Sprintf("args: %v", c.args), func(t *testing.T) {
// Create a copy of command to test
var result *resultType
app := cli.Command{}
app := cli.NewApp()
app.Flags = flags
app.Action = func(_ context.Context, ctx *cli.Command) error {
app.Action = func(ctx *cli.Context) error {
labels, err := getLabels(ctx)
result = &resultType{labels, err}
return nil
}
// Run it
_ = app.Run(t.Context(), c.args)
_ = app.Run(c.args)
// Test the results
require.NotNil(t, result)

View file

@ -8,19 +8,19 @@ import (
"context"
"errors"
"forgejo.org/models"
"forgejo.org/modules/git"
"forgejo.org/modules/log"
"forgejo.org/modules/setting"
"forgejo.org/modules/storage"
"forgejo.org/services/f3/util"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage"
"code.gitea.io/gitea/services/f3/util"
_ "forgejo.org/services/f3/driver" // register the driver
_ "code.gitea.io/gitea/services/f3/driver" // register the driver
f3_cmd "code.forgejo.org/f3/gof3/v3/cmd"
f3_logger "code.forgejo.org/f3/gof3/v3/logger"
f3_util "code.forgejo.org/f3/gof3/v3/util"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
func CmdF3(ctx context.Context) *cli.Command {
@ -28,21 +28,21 @@ func CmdF3(ctx context.Context) *cli.Command {
return &cli.Command{
Name: "f3",
Usage: "F3",
Commands: []*cli.Command{
Subcommands: []*cli.Command{
SubcmdF3Mirror(ctx),
},
}
}
func SubcmdF3Mirror(ctx context.Context) *cli.Command {
mirrorCmd := f3_cmd.CreateCmdMirror()
mirrorCmd := f3_cmd.CreateCmdMirror(ctx)
mirrorCmd.Before = prepareWorkPathAndCustomConf(ctx)
f3Action := mirrorCmd.Action
mirrorCmd.Action = func(ctx context.Context, cli *cli.Command) error { return runMirror(ctx, cli, f3Action) }
mirrorCmd.Action = func(c *cli.Context) error { return runMirror(ctx, c, f3Action) }
return mirrorCmd
}
func runMirror(ctx context.Context, c *cli.Command, action cli.ActionFunc) error {
func runMirror(ctx context.Context, c *cli.Context, action cli.ActionFunc) error {
setting.LoadF3Setting()
if !setting.F3.Enabled {
return errors.New("F3 is disabled, it is not ready to be used and is only present for development purposes")
@ -69,7 +69,7 @@ func runMirror(ctx context.Context, c *cli.Command, action cli.ActionFunc) error
}
}
err := action(ctx, c)
err := action(c)
if panicError, ok := err.(f3_util.PanicError); ok {
log.Debug("F3 Stack trace\n%s", panicError.Stack())
}

View file

@ -11,12 +11,12 @@ import (
"os/signal"
"syscall"
"forgejo.org/models/db"
"forgejo.org/modules/log"
"forgejo.org/modules/private"
"forgejo.org/modules/setting"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
type key int
@ -34,7 +34,7 @@ func CmdForgejo(ctx context.Context) *cli.Command {
Name: "forgejo-cli",
Usage: "Forgejo CLI",
Flags: []cli.Flag{},
Commands: []*cli.Command{
Subcommands: []*cli.Command{
CmdActions(ctx),
CmdF3(ctx),
},
@ -147,12 +147,12 @@ func handleCliResponseExtra(ctx context.Context, extra private.ResponseExtra) er
return cli.Exit(extra.Error, 1)
}
func prepareWorkPathAndCustomConf(ctx context.Context) func(ctx context.Context, cli *cli.Command) (context.Context, error) {
return func(ctx context.Context, cli *cli.Command) (context.Context, error) {
func prepareWorkPathAndCustomConf(ctx context.Context) func(c *cli.Context) error {
return func(c *cli.Context) error {
if !ContextGetNoInit(ctx) {
var args setting.ArgWorkPathAndCustomConf
// from children to parent, check the global flags
for _, curCtx := range cli.Lineage() {
for _, curCtx := range c.Lineage() {
if curCtx.IsSet("work-path") && args.WorkPath == "" {
args.WorkPath = curCtx.String("work-path")
}
@ -165,6 +165,6 @@ func prepareWorkPathAndCustomConf(ctx context.Context) func(ctx context.Context,
}
setting.InitWorkPathAndCommonConfig(os.Getenv, args)
}
return ctx, nil
return nil
}
}

View file

@ -5,65 +5,56 @@
package cmd
import (
"context"
"fmt"
"os"
"forgejo.org/modules/generate"
"code.gitea.io/gitea/modules/generate"
"github.com/mattn/go-isatty"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
var (
// CmdGenerate represents the available generate sub-command.
func cmdGenerate() *cli.Command {
return &cli.Command{
CmdGenerate = &cli.Command{
Name: "generate",
Usage: "Generate Gitea's secrets/keys/tokens",
Commands: []*cli.Command{
subcmdSecret(),
Subcommands: []*cli.Command{
subcmdSecret,
},
}
}
func subcmdSecret() *cli.Command {
return &cli.Command{
subcmdSecret = &cli.Command{
Name: "secret",
Usage: "Generate a secret token",
Commands: []*cli.Command{
microcmdGenerateInternalToken(),
microcmdGenerateLfsJwtSecret(),
microcmdGenerateSecretKey(),
Subcommands: []*cli.Command{
microcmdGenerateInternalToken,
microcmdGenerateLfsJwtSecret,
microcmdGenerateSecretKey,
},
}
}
func microcmdGenerateInternalToken() *cli.Command {
return &cli.Command{
microcmdGenerateInternalToken = &cli.Command{
Name: "INTERNAL_TOKEN",
Usage: "Generate a new INTERNAL_TOKEN",
Action: runGenerateInternalToken,
}
}
func microcmdGenerateLfsJwtSecret() *cli.Command {
return &cli.Command{
microcmdGenerateLfsJwtSecret = &cli.Command{
Name: "JWT_SECRET",
Aliases: []string{"LFS_JWT_SECRET"},
Usage: "Generate a new JWT_SECRET",
Action: runGenerateLfsJwtSecret,
}
}
func microcmdGenerateSecretKey() *cli.Command {
return &cli.Command{
microcmdGenerateSecretKey = &cli.Command{
Name: "SECRET_KEY",
Usage: "Generate a new SECRET_KEY",
Action: runGenerateSecretKey,
}
}
)
func runGenerateInternalToken(ctx context.Context, c *cli.Command) error {
func runGenerateInternalToken(c *cli.Context) error {
internalToken, err := generate.NewInternalToken()
if err != nil {
return err
@ -72,25 +63,28 @@ func runGenerateInternalToken(ctx context.Context, c *cli.Command) error {
fmt.Printf("%s", internalToken)
if isatty.IsTerminal(os.Stdout.Fd()) {
fmt.Println()
fmt.Printf("\n")
}
return nil
}
func runGenerateLfsJwtSecret(ctx context.Context, c *cli.Command) error {
_, jwtSecretBase64 := generate.NewJwtSecret()
func runGenerateLfsJwtSecret(c *cli.Context) error {
_, jwtSecretBase64, err := generate.NewJwtSecret()
if err != nil {
return err
}
fmt.Printf("%s", jwtSecretBase64)
if isatty.IsTerminal(os.Stdout.Fd()) {
fmt.Print("\n")
fmt.Printf("\n")
}
return nil
}
func runGenerateSecretKey(ctx context.Context, c *cli.Command) error {
func runGenerateSecretKey(c *cli.Context) error {
secretKey, err := generate.NewSecretKey()
if err != nil {
return err
@ -99,7 +93,7 @@ func runGenerateSecretKey(ctx context.Context, c *cli.Command) error {
fmt.Printf("%s", secretKey)
if isatty.IsTerminal(os.Stdout.Fd()) {
fmt.Print("\n")
fmt.Printf("\n")
}
return nil

View file

@ -14,38 +14,36 @@ import (
"strings"
"time"
"forgejo.org/modules/git"
"forgejo.org/modules/git/pushoptions"
"forgejo.org/modules/log"
"forgejo.org/modules/private"
repo_module "forgejo.org/modules/repository"
"forgejo.org/modules/setting"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/git/pushoptions"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/private"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
const (
hookBatchSize = 30
)
var (
// CmdHook represents the available hooks sub-command.
func cmdHook() *cli.Command {
return &cli.Command{
CmdHook = &cli.Command{
Name: "hook",
Usage: "(internal) Should only be called by Git",
Description: "Delegate commands to corresponding Git hooks",
Before: PrepareConsoleLoggerLevel(log.FATAL),
Commands: []*cli.Command{
subcmdHookPreReceive(),
subcmdHookUpdate(),
subcmdHookPostReceive(),
subcmdHookProcReceive(),
Subcommands: []*cli.Command{
subcmdHookPreReceive,
subcmdHookUpdate,
subcmdHookPostReceive,
subcmdHookProcReceive,
},
}
}
func subcmdHookPreReceive() *cli.Command {
return &cli.Command{
subcmdHookPreReceive = &cli.Command{
Name: "pre-receive",
Usage: "Delegate pre-receive Git hook",
Description: "This command should only be called by Git",
@ -56,10 +54,7 @@ func subcmdHookPreReceive() *cli.Command {
},
},
}
}
func subcmdHookUpdate() *cli.Command {
return &cli.Command{
subcmdHookUpdate = &cli.Command{
Name: "update",
Usage: "Delegate update Git hook",
Description: "This command should only be called by Git",
@ -70,10 +65,7 @@ func subcmdHookUpdate() *cli.Command {
},
},
}
}
func subcmdHookPostReceive() *cli.Command {
return &cli.Command{
subcmdHookPostReceive = &cli.Command{
Name: "post-receive",
Usage: "Delegate post-receive Git hook",
Description: "This command should only be called by Git",
@ -84,11 +76,8 @@ func subcmdHookPostReceive() *cli.Command {
},
},
}
}
// Note: new hook since git 2.29
func subcmdHookProcReceive() *cli.Command {
return &cli.Command{
subcmdHookProcReceive = &cli.Command{
Name: "proc-receive",
Usage: "Delegate proc-receive Git hook",
Description: "This command should only be called by Git",
@ -99,7 +88,7 @@ func subcmdHookProcReceive() *cli.Command {
},
},
}
}
)
type delayWriter struct {
internal io.Writer
@ -172,14 +161,14 @@ func (n *nilWriter) WriteString(s string) (int, error) {
return len(s), nil
}
func runHookPreReceive(ctx context.Context, c *cli.Command) error {
func runHookPreReceive(c *cli.Context) error {
if isInternal, _ := strconv.ParseBool(os.Getenv(repo_module.EnvIsInternal)); isInternal {
return nil
}
ctx, cancel := installSignals(ctx)
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"), true)
setup(ctx, c.Bool("debug"))
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
@ -231,6 +220,11 @@ Forgejo or set your environment appropriately.`, "")
}
}
supportProcReceive := false
if git.CheckGitVersionAtLeast("2.29") == nil {
supportProcReceive = true
}
for scanner.Scan() {
// TODO: support news feeds for wiki
if isWiki {
@ -248,12 +242,15 @@ Forgejo or set your environment appropriately.`, "")
total++
lastline++
// All references should be checked because permission check was delayed.
// If the ref is a branch or tag, check if it's protected
// if supportProcReceive all ref should be checked because
// permission check was delayed
if supportProcReceive || refFullName.IsBranch() || refFullName.IsTag() {
oldCommitIDs[count] = oldCommitID
newCommitIDs[count] = newCommitID
refFullNames[count] = refFullName
count++
fmt.Fprint(out, "*")
fmt.Fprintf(out, "*")
if count >= hookBatchSize {
fmt.Fprintf(out, " Checking %d references\n", count)
@ -268,8 +265,11 @@ Forgejo or set your environment appropriately.`, "")
count = 0
lastline = 0
}
} else {
fmt.Fprintf(out, ".")
}
if lastline >= hookBatchSize {
fmt.Fprint(out, "\n")
fmt.Fprintf(out, "\n")
lastline = 0
}
}
@ -286,7 +286,7 @@ Forgejo or set your environment appropriately.`, "")
return fail(ctx, extra.UserMsg, "HookPreReceive(last) failed: %v", extra.Error)
}
} else if lastline > 0 {
fmt.Fprint(out, "\n")
fmt.Fprintf(out, "\n")
}
fmt.Fprintf(out, "Checked %d references in total\n", total)
@ -294,13 +294,13 @@ Forgejo or set your environment appropriately.`, "")
}
// runHookUpdate process the update hook: https://git-scm.com/docs/githooks#update
func runHookUpdate(ctx context.Context, c *cli.Command) error {
func runHookUpdate(c *cli.Context) error {
// Now if we're an internal don't do anything else
if isInternal, _ := strconv.ParseBool(os.Getenv(repo_module.EnvIsInternal)); isInternal {
return nil
}
ctx, cancel := installSignals(ctx)
ctx, cancel := installSignals()
defer cancel()
if c.NArg() != 3 {
@ -326,11 +326,11 @@ func runHookUpdate(ctx context.Context, c *cli.Command) error {
return fail(ctx, fmt.Sprintf("The modification of %s is skipped as it's an internal reference.", refFullName), "")
}
func runHookPostReceive(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runHookPostReceive(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"), true)
setup(ctx, c.Bool("debug"))
// First of all run update-server-info no matter what
if _, _, err := git.NewCommand(ctx, "update-server-info").RunStdString(nil); err != nil {
@ -402,7 +402,7 @@ Forgejo or set your environment appropriately.`, "")
continue
}
fmt.Fprint(out, ".")
fmt.Fprintf(out, ".")
oldCommitIDs[count] = string(fields[0])
newCommitIDs[count] = string(fields[1])
refFullNames[count] = git.RefName(fields[2])
@ -490,11 +490,11 @@ func hookPrintResults(results []private.HookPostReceiveBranchResult) {
}
}
func runHookProcReceive(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runHookProcReceive(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"), true)
setup(ctx, c.Bool("debug"))
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
@ -505,6 +505,10 @@ Forgejo or set your environment appropriately.`, "")
return nil
}
if git.CheckGitVersionAtLeast("2.29") != nil {
return fail(ctx, "No proc-receive support", "current git version doesn't support proc-receive.")
}
reader := bufio.NewReader(os.Stdin)
repoUser := os.Getenv(repo_module.EnvRepoUsername)
repoName := os.Getenv(repo_module.EnvRepoName)

View file

@ -6,6 +6,7 @@ package cmd
import (
"bufio"
"bytes"
"context"
"io"
"net/http"
"net/http/httptest"
@ -14,12 +15,12 @@ import (
"testing"
"time"
"forgejo.org/modules/setting"
"forgejo.org/modules/test"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
// Capture what's being written into a standard file descriptor.
@ -41,7 +42,7 @@ func captureOutput(t *testing.T, stdFD *os.File) (finish func() (output string))
}
func TestPktLine(t *testing.T) {
ctx := t.Context()
ctx := context.Background()
t.Run("Read", func(t *testing.T) {
s := strings.NewReader("0000")
@ -134,14 +135,14 @@ func TestDelayWriter(t *testing.T) {
defer ts.Close()
defer test.MockVariableValue(&setting.LocalURL, ts.URL+"/")()
app := cli.Command{}
app.Commands = []*cli.Command{subcmdHookPreReceive()}
app := cli.NewApp()
app.Commands = []*cli.Command{subcmdHookPreReceive}
t.Run("Should delay", func(t *testing.T) {
defer test.MockVariableValue(&setting.Git.VerbosePushDelay, time.Millisecond*500)()
finish := captureOutput(t, os.Stdout)
err = app.Run(t.Context(), []string{"./forgejo", "pre-receive"})
err = app.Run([]string{"./forgejo", "pre-receive"})
require.NoError(t, err)
out := finish()
@ -153,7 +154,7 @@ func TestDelayWriter(t *testing.T) {
defer test.MockVariableValue(&setting.Git.VerbosePushDelay, time.Second*5)()
finish := captureOutput(t, os.Stdout)
err = app.Run(t.Context(), []string{"./forgejo", "pre-receive"})
err = app.Run([]string{"./forgejo", "pre-receive"})
require.NoError(t, err)
out := finish()
@ -163,15 +164,15 @@ func TestDelayWriter(t *testing.T) {
}
func TestRunHookUpdate(t *testing.T) {
app := cli.Command{}
app.Commands = []*cli.Command{subcmdHookUpdate()}
app := cli.NewApp()
app.Commands = []*cli.Command{subcmdHookUpdate}
t.Run("Removal of internal reference", func(t *testing.T) {
defer test.MockVariableValue(&cli.OsExiter, func(code int) {})()
defer test.MockVariableValue(&setting.IsProd, false)()
finish := captureOutput(t, os.Stderr)
err := app.Run(t.Context(), []string{"./forgejo", "update", "refs/pull/1/head", "0a51ae26bc73c47e2f754560c40904cf14ed51a9", "0000000000000000000000000000000000000000"})
err := app.Run([]string{"./forgejo", "update", "refs/pull/1/head", "0a51ae26bc73c47e2f754560c40904cf14ed51a9", "0000000000000000000000000000000000000000"})
out := finish()
require.Error(t, err)
@ -183,7 +184,7 @@ func TestRunHookUpdate(t *testing.T) {
defer test.MockVariableValue(&setting.IsProd, false)()
finish := captureOutput(t, os.Stderr)
err := app.Run(t.Context(), []string{"./forgejo", "update", "refs/pull/1/head", "0a51ae26bc73c47e2f754560c40904cf14ed51a9", "0000000000000000000000000000000000000001"})
err := app.Run([]string{"./forgejo", "update", "refs/pull/1/head", "0a51ae26bc73c47e2f754560c40904cf14ed51a9", "0000000000000000000000000000000000000001"})
out := finish()
require.Error(t, err)
@ -191,12 +192,12 @@ func TestRunHookUpdate(t *testing.T) {
})
t.Run("Removal of branch", func(t *testing.T) {
err := app.Run(t.Context(), []string{"./forgejo", "update", "refs/head/main", "0a51ae26bc73c47e2f754560c40904cf14ed51a9", "0000000000000000000000000000000000000000"})
err := app.Run([]string{"./forgejo", "update", "refs/head/main", "0a51ae26bc73c47e2f754560c40904cf14ed51a9", "0000000000000000000000000000000000000000"})
require.NoError(t, err)
})
t.Run("Not enough arguments", func(t *testing.T) {
err := app.Run(t.Context(), []string{"./forgejo", "update"})
err := app.Run([]string{"./forgejo", "update"})
require.NoError(t, err)
})
}

View file

@ -4,20 +4,18 @@
package cmd
import (
"context"
"errors"
"fmt"
"strings"
"forgejo.org/modules/log"
"forgejo.org/modules/private"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/private"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
// CmdKeys represents the available keys sub-command
func cmdKeys() *cli.Command {
return &cli.Command{
var CmdKeys = &cli.Command{
Name: "keys",
Usage: "(internal) Should only be called by SSH server",
Description: "Queries the Forgejo database to get the authorized command for a given ssh key fingerprint",
@ -50,9 +48,8 @@ func cmdKeys() *cli.Command {
},
},
}
}
func runKeys(ctx context.Context, c *cli.Command) error {
func runKeys(c *cli.Context) error {
if !c.IsSet("username") {
return errors.New("No username provided")
}
@ -71,16 +68,16 @@ func runKeys(ctx context.Context, c *cli.Command) error {
return errors.New("No key type and content provided")
}
ctx, cancel := installSignals(ctx)
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"), true)
setup(ctx, c.Bool("debug"))
authorizedString, extra := private.AuthorizedPublicKeyByContent(ctx, content)
// do not use handleCliResponseExtra or cli.NewExitError, if it exists immediately, it breaks some tests like Test_CmdKeys
if extra.Error != nil {
return extra.Error
}
_, _ = fmt.Fprintln(c.Root().Writer, strings.TrimSpace(authorizedString.Text))
_, _ = fmt.Fprintln(c.App.Writer, strings.TrimSpace(authorizedString.Text))
return nil
}

View file

@ -4,17 +4,16 @@
package cmd
import (
"context"
"fmt"
"forgejo.org/modules/private"
"forgejo.org/modules/setting"
"code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
func runSendMail(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runSendMail(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setting.MustInstalled()

View file

@ -10,11 +10,11 @@ import (
"path/filepath"
"strings"
"forgejo.org/cmd/forgejo"
"forgejo.org/modules/log"
"forgejo.org/modules/setting"
"code.gitea.io/gitea/cmd/forgejo"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
// cmdHelp is our own help subcommand with more information
@ -25,18 +25,18 @@ func cmdHelp() *cli.Command {
Aliases: []string{"h"},
Usage: "Shows a list of commands or help for one command",
ArgsUsage: "[command]",
Action: func(ctx context.Context, c *cli.Command) (err error) {
lineage := c.Lineage() // The order is from child to parent: help, doctor, Forgejo
Action: func(c *cli.Context) (err error) {
lineage := c.Lineage() // The order is from child to parent: help, doctor, Gitea, {Command:nil}
targetCmdIdx := 0
if c.Name == "help" {
if c.Command.Name == "help" {
targetCmdIdx = 1
}
if targetCmdIdx+1 < len(lineage) {
err = cli.ShowCommandHelp(ctx, lineage[targetCmdIdx+1], lineage[targetCmdIdx].Name)
if lineage[targetCmdIdx+1].Command != nil {
err = cli.ShowCommandHelp(lineage[targetCmdIdx+1], lineage[targetCmdIdx].Command.Name)
} else {
err = cli.ShowAppHelp(c)
}
_, _ = fmt.Fprintf(c.Root().Writer, `
_, _ = fmt.Fprintf(c.App.Writer, `
DEFAULT CONFIGURATION:
AppPath: %s
WorkPath: %s
@ -77,25 +77,25 @@ func appGlobalFlags() []cli.Flag {
}
}
func prepareSubcommandWithConfig(command *cli.Command, globalFlags func() []cli.Flag) {
command.Flags = append(globalFlags(), command.Flags...)
func prepareSubcommandWithConfig(command *cli.Command, globalFlags []cli.Flag) {
command.Flags = append(append([]cli.Flag{}, globalFlags...), command.Flags...)
command.Action = prepareWorkPathAndCustomConf(command.Action)
command.HideHelp = true
if command.Name != "help" {
command.Commands = append(command.Commands, cmdHelp())
command.Subcommands = append(command.Subcommands, cmdHelp())
}
for i := range command.Commands {
prepareSubcommandWithConfig(command.Commands[i], globalFlags)
for i := range command.Subcommands {
prepareSubcommandWithConfig(command.Subcommands[i], globalFlags)
}
}
// prepareWorkPathAndCustomConf wraps the Action to prepare the work path and custom config
// It can't use "Before", because each level's sub-command's Before will be called one by one, so the "init" would be done multiple times
func prepareWorkPathAndCustomConf(action cli.ActionFunc) func(_ context.Context, _ *cli.Command) error {
return func(ctx context.Context, cli *cli.Command) error {
func prepareWorkPathAndCustomConf(action cli.ActionFunc) func(ctx *cli.Context) error {
return func(ctx *cli.Context) error {
var args setting.ArgWorkPathAndCustomConf
// from children to parent, check the global flags
for _, curCtx := range cli.Lineage() {
for _, curCtx := range ctx.Lineage() {
if curCtx.IsSet("work-path") && args.WorkPath == "" {
args.WorkPath = curCtx.String("work-path")
}
@ -107,24 +107,24 @@ func prepareWorkPathAndCustomConf(action cli.ActionFunc) func(_ context.Context,
}
}
setting.InitWorkPathAndCommonConfig(os.Getenv, args)
if cli.Bool("help") || action == nil {
if ctx.Bool("help") || action == nil {
// the default behavior of "urfave/cli": "nil action" means "show help"
return cmdHelp().Action(ctx, cli)
return cmdHelp().Action(ctx)
}
return action(ctx, cli)
return action(ctx)
}
}
func NewMainApp(version, versionExtra string) *cli.Command {
func NewMainApp(version, versionExtra string) *cli.App {
path, err := os.Executable()
if err != nil {
panic(err)
}
executable := filepath.Base(path)
subCmdsStandalone := make([]*cli.Command, 0, 10)
subCmdWithConfig := make([]*cli.Command, 0, 10)
globalFlags := func() []cli.Flag { return []cli.Flag{} }
var subCmdsStandalone []*cli.Command = make([]*cli.Command, 0, 10)
var subCmdWithConfig []*cli.Command = make([]*cli.Command, 0, 10)
var globalFlags []cli.Flag = make([]cli.Flag, 0, 10)
//
// If the executable is forgejo-cli, provide a Forgejo specific CLI
@ -133,16 +133,14 @@ func NewMainApp(version, versionExtra string) *cli.Command {
if executable == "forgejo-cli" {
subCmdsStandalone = append(subCmdsStandalone, forgejo.CmdActions(context.Background()))
subCmdWithConfig = append(subCmdWithConfig, forgejo.CmdF3(context.Background()))
globalFlags = func() []cli.Flag {
return []cli.Flag{
globalFlags = append(globalFlags, []cli.Flag{
&cli.BoolFlag{
Name: "quiet",
},
&cli.BoolFlag{
Name: "verbose",
},
}
}
}...)
} else {
//
// Otherwise provide a Gitea compatible CLI which includes Forgejo
@ -151,54 +149,55 @@ func NewMainApp(version, versionExtra string) *cli.Command {
// binary and rename it to forgejo if they want.
//
subCmdsStandalone = append(subCmdsStandalone, forgejo.CmdForgejo(context.Background()))
subCmdWithConfig = append(subCmdWithConfig, cmdActions())
subCmdWithConfig = append(subCmdWithConfig, CmdActions)
}
return innerNewMainApp(version, versionExtra, subCmdsStandalone, subCmdWithConfig, globalFlags)
}
func innerNewMainApp(version, versionExtra string, subCmdsStandaloneArgs, subCmdWithConfigArgs []*cli.Command, globalFlagsArgs func() []cli.Flag) *cli.Command {
app := &cli.Command{}
app.Name = "forgejo"
func innerNewMainApp(version, versionExtra string, subCmdsStandaloneArgs, subCmdWithConfigArgs []*cli.Command, globalFlagsArgs []cli.Flag) *cli.App {
app := cli.NewApp()
app.HelpName = "forgejo"
app.Name = "Forgejo"
app.Usage = "Beyond coding. We forge."
app.Description = `By default, forgejo will start serving using the web-server with no argument, which can alternatively be run by running the subcommand "web".`
app.Version = version + versionExtra
app.EnableShellCompletion = true
app.EnableBashCompletion = true
// these sub-commands need to use config file
subCmdWithConfig := []*cli.Command{
cmdHelp(), // the "help" sub-command was used to show the more information for "work path" and "custom config"
cmdWeb(),
cmdServ(),
cmdHook(),
cmdKeys(),
cmdDump(),
cmdAdmin(),
cmdMigrate(),
cmdDoctor(),
cmdManager(),
cmdEmbedded(),
cmdMigrateStorage(),
cmdDumpRepository(),
cmdRestoreRepository(),
CmdWeb,
CmdServ,
CmdHook,
CmdKeys,
CmdDump,
CmdAdmin,
CmdMigrate,
CmdDoctor,
CmdManager,
CmdEmbedded,
CmdMigrateStorage,
CmdDumpRepository,
CmdRestoreRepository,
}
subCmdWithConfig = append(subCmdWithConfig, subCmdWithConfigArgs...)
// these sub-commands do not need the config file, and they do not depend on any path or environment variable.
subCmdStandalone := []*cli.Command{
cmdCert(),
cmdGenerate(),
CmdCert,
CmdGenerate,
CmdDocs,
}
subCmdStandalone = append(subCmdStandalone, subCmdsStandaloneArgs...)
app.DefaultCommand = cmdWeb().Name
app.DefaultCommand = CmdWeb.Name
globalFlags := func() []cli.Flag {
return append(appGlobalFlags(), globalFlagsArgs()...)
}
globalFlags := appGlobalFlags()
globalFlags = append(globalFlags, globalFlagsArgs...)
app.Flags = append(app.Flags, cli.VersionFlag)
app.Flags = append(app.Flags, globalFlags()...)
app.Flags = append(app.Flags, globalFlags...)
app.HideHelp = true // use our own help action to show helps (with more information like default config)
app.Before = PrepareConsoleLoggerLevel(log.INFO)
for i := range subCmdWithConfig {
@ -207,12 +206,11 @@ func innerNewMainApp(version, versionExtra string, subCmdsStandaloneArgs, subCmd
app.Commands = append(app.Commands, subCmdWithConfig...)
app.Commands = append(app.Commands, subCmdStandalone...)
setting.InitGiteaEnvVars()
return app
}
func RunMainApp(app *cli.Command, args ...string) error {
err := app.Run(context.Background(), args)
func RunMainApp(app *cli.App, args ...string) error {
err := app.Run(args)
if err == nil {
return nil
}
@ -221,7 +219,7 @@ func RunMainApp(app *cli.Command, args ...string) error {
cli.OsExiter(1)
return err
}
_, _ = fmt.Fprintf(app.Root().ErrWriter, "Command error: %v\n", err)
_, _ = fmt.Fprintf(app.ErrWriter, "Command error: %v\n", err)
cli.OsExiter(1)
return err
}

View file

@ -4,21 +4,20 @@
package cmd
import (
"context"
"errors"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"testing"
"forgejo.org/models/unittest"
"forgejo.org/modules/setting"
"forgejo.org/modules/test"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
func TestMain(m *testing.M) {
@ -29,10 +28,10 @@ func makePathOutput(workPath, customPath, customConf string) string {
return fmt.Sprintf("WorkPath=%s\nCustomPath=%s\nCustomConf=%s", workPath, customPath, customConf)
}
func newTestApp(testCmdAction func(_ context.Context, ctx *cli.Command) error) *cli.Command {
func newTestApp(testCmdAction func(ctx *cli.Context) error) *cli.App {
app := NewMainApp("version", "version-extra")
testCmd := &cli.Command{Name: "test-cmd", Action: testCmdAction}
prepareSubcommandWithConfig(testCmd, appGlobalFlags)
prepareSubcommandWithConfig(testCmd, appGlobalFlags())
app.Commands = append(app.Commands, testCmd)
app.DefaultCommand = testCmd.Name
return app
@ -44,7 +43,7 @@ type runResult struct {
ExitCode int
}
func runTestApp(app *cli.Command, args ...string) (runResult, error) {
func runTestApp(app *cli.App, args ...string) (runResult, error) {
outBuf := new(strings.Builder)
errBuf := new(strings.Builder)
app.Writer = outBuf
@ -67,6 +66,7 @@ func TestCliCmd(t *testing.T) {
defaultCustomConf := filepath.Join(defaultCustomPath, "conf/app.ini")
cli.CommandHelpTemplate = "(command help template)"
cli.AppHelpTemplate = "(app help template)"
cli.SubcommandHelpTemplate = "(subcommand help template)"
cases := []struct {
@ -110,55 +110,70 @@ func TestCliCmd(t *testing.T) {
},
}
for _, c := range cases {
t.Run(c.cmd, func(t *testing.T) {
defer test.MockProtect(&setting.AppWorkPath)()
defer test.MockProtect(&setting.CustomPath)()
defer test.MockProtect(&setting.CustomConf)()
app := newTestApp(func(_ context.Context, ctx *cli.Command) error {
_, _ = fmt.Fprint(ctx.Root().Writer, makePathOutput(setting.AppWorkPath, setting.CustomPath, setting.CustomConf))
app := newTestApp(func(ctx *cli.Context) error {
_, _ = fmt.Fprint(ctx.App.Writer, makePathOutput(setting.AppWorkPath, setting.CustomPath, setting.CustomConf))
return nil
})
var envBackup []string
for _, s := range os.Environ() {
if strings.HasPrefix(s, "GITEA_") && strings.Contains(s, "=") {
envBackup = append(envBackup, s)
}
}
clearGiteaEnv := func() {
for _, s := range os.Environ() {
if strings.HasPrefix(s, "GITEA_") {
_ = os.Unsetenv(s)
}
}
}
defer func() {
clearGiteaEnv()
for _, s := range envBackup {
k, v, _ := strings.Cut(s, "=")
_ = os.Setenv(k, v)
}
}()
for _, c := range cases {
clearGiteaEnv()
for k, v := range c.env {
t.Setenv(k, v)
_ = os.Setenv(k, v)
}
args := strings.Split(c.cmd, " ") // for test only, "split" is good enough
r, err := runTestApp(app, args...)
require.NoError(t, err, c.cmd)
assert.NotEmpty(t, c.exp, c.cmd)
assert.Contains(t, r.Stdout, c.exp, c.cmd+"\n"+r.Stdout)
})
assert.Contains(t, r.Stdout, c.exp, c.cmd)
}
}
func TestCliCmdError(t *testing.T) {
app := newTestApp(func(_ context.Context, ctx *cli.Command) error { return errors.New("normal error") })
app := newTestApp(func(ctx *cli.Context) error { return fmt.Errorf("normal error") })
r, err := runTestApp(app, "./gitea", "test-cmd")
require.Error(t, err)
assert.Equal(t, 1, r.ExitCode)
assert.Empty(t, r.Stdout)
assert.Equal(t, "", r.Stdout)
assert.Equal(t, "Command error: normal error\n", r.Stderr)
app = newTestApp(func(_ context.Context, ctx *cli.Command) error { return cli.Exit("exit error", 2) })
app = newTestApp(func(ctx *cli.Context) error { return cli.Exit("exit error", 2) })
r, err = runTestApp(app, "./gitea", "test-cmd")
require.Error(t, err)
assert.Equal(t, 2, r.ExitCode)
assert.Empty(t, r.Stdout)
assert.Equal(t, "", r.Stdout)
assert.Equal(t, "exit error\n", r.Stderr)
app = newTestApp(func(_ context.Context, ctx *cli.Command) error { return nil })
app = newTestApp(func(ctx *cli.Context) error { return nil })
r, err = runTestApp(app, "./gitea", "test-cmd", "--no-such")
require.Error(t, err)
assert.Equal(t, 1, r.ExitCode)
assert.Equal(t, "Incorrect Usage: flag provided but not defined: -no-such\n\n", r.Stderr)
assert.Empty(t, r.Stdout)
assert.Equal(t, "Incorrect Usage: flag provided but not defined: -no-such\n\n", r.Stdout)
assert.Equal(t, "", r.Stderr) // the cli package's strange behavior, the error message is not in stderr ....
app = newTestApp(func(_ context.Context, ctx *cli.Command) error { return nil })
app = newTestApp(func(ctx *cli.Context) error { return nil })
r, err = runTestApp(app, "./gitea", "test-cmd")
require.NoError(t, err)
assert.Equal(t, -1, r.ExitCode) // the cli.OsExiter is not called
assert.Empty(t, r.Stdout)
assert.Empty(t, r.Stderr)
assert.Equal(t, "", r.Stdout)
assert.Equal(t, "", r.Stderr)
}

View file

@ -4,34 +4,30 @@
package cmd
import (
"context"
"os"
"time"
"forgejo.org/modules/private"
"code.gitea.io/gitea/modules/private"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
var (
// CmdManager represents the manager command
func cmdManager() *cli.Command {
return &cli.Command{
CmdManager = &cli.Command{
Name: "manager",
Usage: "Manage the running forgejo process",
Description: "This is a command for managing the running forgejo process",
Commands: []*cli.Command{
subcmdShutdown(),
subcmdRestart(),
subcmdReloadTemplates(),
subcmdFlushQueues(),
subcmdLogging(),
subCmdProcesses(),
Subcommands: []*cli.Command{
subcmdShutdown,
subcmdRestart,
subcmdReloadTemplates,
subcmdFlushQueues,
subcmdLogging,
subCmdProcesses,
},
}
}
func subcmdShutdown() *cli.Command {
return &cli.Command{
subcmdShutdown = &cli.Command{
Name: "shutdown",
Usage: "Gracefully shutdown the running process",
Flags: []cli.Flag{
@ -41,10 +37,7 @@ func subcmdShutdown() *cli.Command {
},
Action: runShutdown,
}
}
func subcmdRestart() *cli.Command {
return &cli.Command{
subcmdRestart = &cli.Command{
Name: "restart",
Usage: "Gracefully restart the running process - (not implemented for windows servers)",
Flags: []cli.Flag{
@ -54,10 +47,7 @@ func subcmdRestart() *cli.Command {
},
Action: runRestart,
}
}
func subcmdReloadTemplates() *cli.Command {
return &cli.Command{
subcmdReloadTemplates = &cli.Command{
Name: "reload-templates",
Usage: "Reload template files in the running process",
Flags: []cli.Flag{
@ -67,10 +57,7 @@ func subcmdReloadTemplates() *cli.Command {
},
Action: runReloadTemplates,
}
}
func subcmdFlushQueues() *cli.Command {
return &cli.Command{
subcmdFlushQueues = &cli.Command{
Name: "flush-queues",
Usage: "Flush queues in the running process",
Action: runFlushQueues,
@ -89,10 +76,7 @@ func subcmdFlushQueues() *cli.Command {
},
},
}
}
func subCmdProcesses() *cli.Command {
return &cli.Command{
subCmdProcesses = &cli.Command{
Name: "processes",
Usage: "Display running processes within the current process",
Action: runProcesses,
@ -122,49 +106,49 @@ func subCmdProcesses() *cli.Command {
},
},
}
}
)
func runShutdown(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runShutdown(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"), false)
setup(ctx, c.Bool("debug"))
extra := private.Shutdown(ctx)
return handleCliResponseExtra(extra)
}
func runRestart(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runRestart(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"), false)
setup(ctx, c.Bool("debug"))
extra := private.Restart(ctx)
return handleCliResponseExtra(extra)
}
func runReloadTemplates(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runReloadTemplates(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"), false)
setup(ctx, c.Bool("debug"))
extra := private.ReloadTemplates(ctx)
return handleCliResponseExtra(extra)
}
func runFlushQueues(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runFlushQueues(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"), false)
setup(ctx, c.Bool("debug"))
extra := private.FlushQueues(ctx, c.Duration("timeout"), c.Bool("non-blocking"))
return handleCliResponseExtra(extra)
}
func runProcesses(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runProcesses(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"), false)
setup(ctx, c.Bool("debug"))
extra := private.Processes(ctx, os.Stdout, c.Bool("flat"), c.Bool("no-system"), c.Bool("stacktraces"), c.Bool("json"), c.String("cancel"))
return handleCliResponseExtra(extra)
}

View file

@ -4,19 +4,18 @@
package cmd
import (
"context"
"errors"
"fmt"
"os"
"forgejo.org/modules/log"
"forgejo.org/modules/private"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/private"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
func defaultLoggingFlags() []cli.Flag {
return []cli.Flag{
var (
defaultLoggingFlags = []cli.Flag{
&cli.StringFlag{
Name: "logger",
Usage: `Logger name - will default to "default"`,
@ -57,13 +56,11 @@ func defaultLoggingFlags() []cli.Flag {
Name: "debug",
},
}
}
func subcmdLogging() *cli.Command {
return &cli.Command{
subcmdLogging = &cli.Command{
Name: "logging",
Usage: "Adjust logging commands",
Commands: []*cli.Command{
Subcommands: []*cli.Command{
{
Name: "pause",
Usage: "Pause logging (Forgejo will buffer logs up to a certain point and will drop them after that point)",
@ -107,11 +104,11 @@ func subcmdLogging() *cli.Command {
}, {
Name: "add",
Usage: "Add a logger",
Commands: []*cli.Command{
Subcommands: []*cli.Command{
{
Name: "file",
Usage: "Add a file logger",
Flags: append(defaultLoggingFlags(), []cli.Flag{
Flags: append(defaultLoggingFlags, []cli.Flag{
&cli.StringFlag{
Name: "filename",
Aliases: []string{"f"},
@ -155,7 +152,7 @@ func subcmdLogging() *cli.Command {
}, {
Name: "conn",
Usage: "Add a net conn logger",
Flags: append(defaultLoggingFlags(), []cli.Flag{
Flags: append(defaultLoggingFlags, []cli.Flag{
&cli.BoolFlag{
Name: "reconnect-on-message",
Aliases: []string{"R"},
@ -196,13 +193,13 @@ func subcmdLogging() *cli.Command {
},
},
}
}
)
func runRemoveLogger(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runRemoveLogger(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"), false)
setup(ctx, c.Bool("debug"))
logger := c.String("logger")
if len(logger) == 0 {
logger = log.DEFAULT
@ -213,11 +210,11 @@ func runRemoveLogger(ctx context.Context, c *cli.Command) error {
return handleCliResponseExtra(extra)
}
func runAddConnLogger(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runAddConnLogger(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"), false)
setup(ctx, c.Bool("debug"))
vals := map[string]any{}
mode := "conn"
vals["net"] = "tcp"
@ -240,14 +237,14 @@ func runAddConnLogger(ctx context.Context, c *cli.Command) error {
if c.IsSet("reconnect-on-message") {
vals["reconnectOnMsg"] = c.Bool("reconnect-on-message")
}
return commonAddLogger(ctx, c, mode, vals)
return commonAddLogger(c, mode, vals)
}
func runAddFileLogger(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runAddFileLogger(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"), false)
setup(ctx, c.Bool("debug"))
vals := map[string]any{}
mode := "file"
if c.IsSet("filename") {
@ -273,10 +270,10 @@ func runAddFileLogger(ctx context.Context, c *cli.Command) error {
if c.IsSet("compression-level") {
vals["compressionLevel"] = c.Int("compression-level")
}
return commonAddLogger(ctx, c, mode, vals)
return commonAddLogger(c, mode, vals)
}
func commonAddLogger(ctx context.Context, c *cli.Command, mode string, vals map[string]any) error {
func commonAddLogger(c *cli.Context, mode string, vals map[string]any) error {
if len(c.String("level")) > 0 {
vals["level"] = log.LevelFromString(c.String("level")).String()
}
@ -303,47 +300,47 @@ func commonAddLogger(ctx context.Context, c *cli.Command, mode string, vals map[
if c.IsSet("writer") {
writer = c.String("writer")
}
ctx, cancel := installSignals(ctx)
ctx, cancel := installSignals()
defer cancel()
extra := private.AddLogger(ctx, logger, writer, mode, vals)
return handleCliResponseExtra(extra)
}
func runPauseLogging(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runPauseLogging(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"), false)
setup(ctx, c.Bool("debug"))
userMsg := private.PauseLogging(ctx)
_, _ = fmt.Fprintln(os.Stdout, userMsg)
return nil
}
func runResumeLogging(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runResumeLogging(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"), false)
setup(ctx, c.Bool("debug"))
userMsg := private.ResumeLogging(ctx)
_, _ = fmt.Fprintln(os.Stdout, userMsg)
return nil
}
func runReleaseReopenLogging(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runReleaseReopenLogging(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"), false)
setup(ctx, c.Bool("debug"))
userMsg := private.ReleaseReopenLogging(ctx)
_, _ = fmt.Fprintln(os.Stdout, userMsg)
return nil
}
func runSetLogSQL(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runSetLogSQL(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"), false)
setup(ctx, c.Bool("debug"))
extra := private.SetLogSQL(ctx, !c.Bool("off"))
return handleCliResponseExtra(extra)

View file

@ -6,26 +6,24 @@ package cmd
import (
"context"
"forgejo.org/models/db"
"forgejo.org/models/migrations"
"forgejo.org/modules/log"
"forgejo.org/modules/setting"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/migrations"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
// CmdMigrate represents the available migrate sub-command.
func cmdMigrate() *cli.Command {
return &cli.Command{
var CmdMigrate = &cli.Command{
Name: "migrate",
Usage: "Migrate the database",
Description: "This is a command for migrating the database, so that you can run 'forgejo admin user create' before starting the server.",
Action: runMigrate,
}
}
func runMigrate(stdCtx context.Context, ctx *cli.Command) error {
stdCtx, cancel := installSignals(stdCtx)
func runMigrate(ctx *cli.Context) error {
stdCtx, cancel := installSignals()
defer cancel()
if err := initDB(stdCtx); err != nil {
@ -38,13 +36,7 @@ func runMigrate(stdCtx context.Context, ctx *cli.Command) error {
log.Info("Log path: %s", setting.Log.RootPath)
log.Info("Configuration file: %s", setting.CustomConf)
if err := db.InitEngineWithMigration(context.Background(), func(dbEngine db.Engine) error {
masterEngine, err := db.GetMasterEngine(dbEngine)
if err != nil {
return err
}
return migrations.Migrate(masterEngine)
}); err != nil {
if err := db.InitEngineWithMigration(context.Background(), migrations.Migrate); err != nil {
log.Fatal("Failed to initialize ORM engine: %v", err)
return err
}

View file

@ -10,25 +10,23 @@ import (
"io/fs"
"strings"
actions_model "forgejo.org/models/actions"
"forgejo.org/models/db"
git_model "forgejo.org/models/git"
"forgejo.org/models/migrations"
packages_model "forgejo.org/models/packages"
repo_model "forgejo.org/models/repo"
user_model "forgejo.org/models/user"
"forgejo.org/modules/log"
packages_module "forgejo.org/modules/packages"
"forgejo.org/modules/setting"
"forgejo.org/modules/storage"
actions_model "code.gitea.io/gitea/models/actions"
"code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git"
"code.gitea.io/gitea/models/migrations"
packages_model "code.gitea.io/gitea/models/packages"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log"
packages_module "code.gitea.io/gitea/modules/packages"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage"
"github.com/urfave/cli/v3"
"xorm.io/xorm"
"github.com/urfave/cli/v2"
)
// CmdMigrateStorage represents the available migrate storage sub-command.
func cmdMigrateStorage() *cli.Command {
return &cli.Command{
var CmdMigrateStorage = &cli.Command{
Name: "migrate-storage",
Usage: "Migrate the storage",
Description: "Copies stored files from storage configured in app.ini to parameter-configured storage",
@ -97,7 +95,6 @@ func cmdMigrateStorage() *cli.Command {
},
},
}
}
func migrateAttachments(ctx context.Context, dstStorage storage.ObjectStorage) error {
return db.Iterate(ctx, nil, func(ctx context.Context, attach *repo_model.Attachment) error {
@ -184,8 +181,8 @@ func migrateActionsArtifacts(ctx context.Context, dstStorage storage.ObjectStora
})
}
func runMigrateStorage(stdCtx context.Context, ctx *cli.Command) error {
stdCtx, cancel := installSignals(stdCtx)
func runMigrateStorage(ctx *cli.Context) error {
stdCtx, cancel := installSignals()
defer cancel()
if err := initDB(stdCtx); err != nil {
@ -198,9 +195,7 @@ func runMigrateStorage(stdCtx context.Context, ctx *cli.Command) error {
log.Info("Log path: %s", setting.Log.RootPath)
log.Info("Configuration file: %s", setting.CustomConf)
if err := db.InitEngineWithMigration(context.Background(), func(e db.Engine) error {
return migrations.Migrate(e.(*xorm.Engine))
}); err != nil {
if err := db.InitEngineWithMigration(context.Background(), migrations.Migrate); err != nil {
log.Fatal("Failed to initialize ORM engine: %v", err)
return err
}

View file

@ -4,21 +4,22 @@
package cmd
import (
"context"
"io"
"os"
"strings"
"testing"
"forgejo.org/models/actions"
"forgejo.org/models/db"
"forgejo.org/models/packages"
"forgejo.org/models/unittest"
user_model "forgejo.org/models/user"
packages_module "forgejo.org/modules/packages"
"forgejo.org/modules/setting"
"forgejo.org/modules/storage"
"forgejo.org/modules/test"
packages_service "forgejo.org/services/packages"
"code.gitea.io/gitea/models/actions"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/packages"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
packages_module "code.gitea.io/gitea/modules/packages"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage"
"code.gitea.io/gitea/modules/test"
packages_service "code.gitea.io/gitea/services/packages"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -30,7 +31,7 @@ func createLocalStorage(t *testing.T) (storage.ObjectStorage, string) {
p := t.TempDir()
storage, err := storage.NewLocalStorage(
t.Context(),
context.Background(),
&setting.Storage{
Path: p,
})
@ -71,7 +72,7 @@ func TestMigratePackages(t *testing.T) {
assert.NotNil(t, v)
assert.NotNil(t, f)
ctx := t.Context()
ctx := context.Background()
dstStorage, p := createLocalStorage(t)
@ -81,8 +82,8 @@ func TestMigratePackages(t *testing.T) {
entries, err := os.ReadDir(p)
require.NoError(t, err)
assert.Len(t, entries, 2)
assert.Equal(t, "01", entries[0].Name())
assert.Equal(t, "tmp", entries[1].Name())
assert.EqualValues(t, "01", entries[0].Name())
assert.EqualValues(t, "tmp", entries[1].Name())
}
func TestMigrateActionsArtifacts(t *testing.T) {

View file

@ -4,18 +4,16 @@
package cmd
import (
"context"
"strings"
"forgejo.org/modules/private"
"forgejo.org/modules/setting"
"code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
// CmdRestoreRepository represents the available restore a repository sub-command.
func cmdRestoreRepository() *cli.Command {
return &cli.Command{
var CmdRestoreRepository = &cli.Command{
Name: "restore-repo",
Usage: "Restore the repository from disk",
Description: "This is a command for restoring the repository data.",
@ -49,10 +47,9 @@ wiki, issues, labels, releases, release_assets, milestones, pull_requests, comme
},
},
}
}
func runRestoreRepository(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runRestoreRepository(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setting.MustInstalled()

View file

@ -18,22 +18,22 @@ import (
"time"
"unicode"
asymkey_model "forgejo.org/models/asymkey"
git_model "forgejo.org/models/git"
"forgejo.org/models/perm"
"forgejo.org/modules/git"
"forgejo.org/modules/json"
"forgejo.org/modules/log"
"forgejo.org/modules/pprof"
"forgejo.org/modules/private"
"forgejo.org/modules/process"
repo_module "forgejo.org/modules/repository"
"forgejo.org/modules/setting"
"forgejo.org/services/lfs"
asymkey_model "code.gitea.io/gitea/models/asymkey"
git_model "code.gitea.io/gitea/models/git"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/pprof"
"code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/process"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/services/lfs"
"github.com/golang-jwt/jwt/v5"
"github.com/kballard/go-shellquote"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
const (
@ -41,8 +41,7 @@ const (
)
// CmdServ represents the available serv sub-command.
func cmdServ() *cli.Command {
return &cli.Command{
var CmdServ = &cli.Command{
Name: "serv",
Usage: "(internal) Should only be called by SSH shell",
Description: "Serv provides access auth for repositories",
@ -57,26 +56,22 @@ func cmdServ() *cli.Command {
},
},
}
}
func setup(ctx context.Context, debug, gitNeeded bool) {
func setup(ctx context.Context, debug bool) {
if debug {
setupConsoleLogger(log.TRACE, false, os.Stderr)
} else {
setupConsoleLogger(log.FATAL, false, os.Stderr)
}
setting.MustInstalled()
// Sanity check to ensure path is not relative, see: https://github.com/go-gitea/gitea/pull/19317
if _, err := os.Stat(setting.RepoRootPath); err != nil {
_ = fail(ctx, "Unable to access repository path", "Unable to access repository path %q, err: %v", setting.RepoRootPath, err)
return
}
if gitNeeded {
if err := git.InitSimple(context.Background()); err != nil {
_ = fail(ctx, "Failed to init git", "Failed to init git, err: %v", err)
}
}
}
var (
allowedCommands = map[string]perm.AccessMode{
@ -133,12 +128,12 @@ func handleCliResponseExtra(extra private.ResponseExtra) error {
return nil
}
func runServ(ctx context.Context, c *cli.Command) error {
ctx, cancel := installSignals(ctx)
func runServ(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
// FIXME: This needs to internationalised
setup(ctx, c.Bool("debug"), true)
setup(ctx, c.Bool("debug"))
if setting.SSH.Disabled {
fmt.Println("Forgejo: SSH has been disabled")
@ -193,11 +188,13 @@ func runServ(ctx context.Context, c *cli.Command) error {
}
if len(words) < 2 {
if git.CheckGitVersionAtLeast("2.29") == nil {
// for AGit Flow
if cmd == "ssh_info" {
fmt.Print(`{"type":"agit","version":1}`)
fmt.Print(`{"type":"gitea","version":1}`)
return nil
}
}
return fail(ctx, "Too few arguments", "Too few arguments in cmd: %s", cmd)
}
@ -256,12 +253,11 @@ func runServ(ctx context.Context, c *cli.Command) error {
}
if verb == lfsAuthenticateVerb {
switch lfsVerb {
case "upload":
if lfsVerb == "upload" {
requestedMode = perm.AccessModeWrite
case "download":
} else if lfsVerb == "download" {
requestedMode = perm.AccessModeRead
default:
} else {
return fail(ctx, "Unknown LFS verb", "Unknown lfs verb %s", lfsVerb)
}
}

View file

@ -12,29 +12,27 @@ import (
"path/filepath"
"strconv"
"strings"
"time"
_ "net/http/pprof" // Used for debugging if enabled and a web server is running
"forgejo.org/modules/container"
"forgejo.org/modules/graceful"
"forgejo.org/modules/log"
"forgejo.org/modules/process"
"forgejo.org/modules/public"
"forgejo.org/modules/setting"
"forgejo.org/routers"
"forgejo.org/routers/install"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/public"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/routers"
"code.gitea.io/gitea/routers/install"
"github.com/felixge/fgprof"
"github.com/urfave/cli/v3"
"github.com/urfave/cli/v2"
)
// PIDFile could be set from build tag
var PIDFile = "/run/gitea.pid"
// CmdWeb represents the available web sub-command.
func cmdWeb() *cli.Command {
return &cli.Command{
var CmdWeb = &cli.Command{
Name: "web",
Usage: "Start the Forgejo web server",
Description: `The Forgejo web server is the only thing you need to run,
@ -70,7 +68,6 @@ and it takes care of all the other things for you`,
},
},
}
}
func runHTTPRedirector() {
_, _, finished := process.GetManager().AddTypedContext(graceful.GetManager().HammerContext(), "Web: HTTP Redirector", process.SystemProcessType, true)
@ -118,19 +115,9 @@ func showWebStartupMessage(msg string) {
log.Info("* CustomPath: %s", setting.CustomPath)
log.Info("* ConfigFile: %s", setting.CustomConf)
log.Info("%s", msg) // show startup message
if setting.CORSConfig.Enabled {
log.Info("CORS Service Enabled")
}
if setting.DefaultUILocation != time.Local {
log.Info("Default UI Location is %v", setting.DefaultUILocation.String())
}
if setting.MailService != nil {
log.Info("Mail Service Enabled: RegisterEmailConfirm=%v, Service.EnableNotifyMail=%v", setting.Service.RegisterEmailConfirm, setting.Service.EnableNotifyMail)
}
}
func serveInstall(_ context.Context, ctx *cli.Command) error {
func serveInstall(ctx *cli.Context) error {
showWebStartupMessage("Prepare to run install page")
routers.InitWebInstallPage(graceful.GetManager().HammerContext())
@ -163,7 +150,7 @@ func serveInstall(_ context.Context, ctx *cli.Command) error {
return nil
}
func serveInstalled(_ context.Context, ctx *cli.Command) error {
func serveInstalled(ctx *cli.Context) error {
setting.InitCfgProvider(setting.CustomConf)
setting.LoadCommonSettings()
setting.MustInstalled()
@ -197,9 +184,12 @@ func serveInstalled(_ context.Context, ctx *cli.Command) error {
publicFilesSet.Remove(".well-known")
publicFilesSet.Remove("assets")
publicFilesSet.Remove("robots.txt")
for fn := range publicFilesSet.Seq() {
for _, fn := range publicFilesSet.Values() {
log.Error("Found legacy public asset %q in CustomPath. Please move it to %s/public/assets/%s", fn, setting.CustomPath, fn)
}
if _, err := os.Stat(filepath.Join(setting.CustomPath, "robots.txt")); err == nil {
log.Error(`Found legacy public asset "robots.txt" in CustomPath. Please move it to %s/public/robots.txt`, setting.CustomPath)
}
routers.InitWebInstalled(graceful.GetManager().HammerContext())
@ -235,7 +225,7 @@ func servePprof() {
finished()
}
func runWeb(ctx context.Context, cli *cli.Command) error {
func runWeb(ctx *cli.Context) error {
defer func() {
if panicked := recover(); panicked != nil {
log.Fatal("PANIC: %v\n%s", panicked, log.Stack(2))
@ -253,12 +243,12 @@ func runWeb(ctx context.Context, cli *cli.Command) error {
}
// Set pid file setting
if cli.IsSet("pid") {
createPIDFile(cli.String("pid"))
if ctx.IsSet("pid") {
createPIDFile(ctx.String("pid"))
}
if !setting.InstallLock {
if err := serveInstall(ctx, cli); err != nil {
if err := serveInstall(ctx); err != nil {
return err
}
} else {
@ -269,7 +259,7 @@ func runWeb(ctx context.Context, cli *cli.Command) error {
go servePprof()
}
return serveInstalled(ctx, cli)
return serveInstalled(ctx)
}
func setPort(port string) error {

View file

@ -12,10 +12,10 @@ import (
"strconv"
"strings"
"forgejo.org/modules/graceful"
"forgejo.org/modules/log"
"forgejo.org/modules/process"
"forgejo.org/modules/setting"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/setting"
"github.com/caddyserver/certmagic"
)
@ -54,8 +54,8 @@ func runACME(listenAddr string, m http.Handler) error {
altTLSALPNPort = p
}
certmagic.Default.Storage = &certmagic.FileStorage{Path: setting.AcmeLiveDirectory}
magic := certmagic.NewDefault()
magic.Storage = &certmagic.FileStorage{Path: setting.AcmeLiveDirectory}
// Try to use private CA root if provided, otherwise defaults to system's trust
var certPool *x509.CertPool
if setting.AcmeCARoot != "" {
@ -65,8 +65,7 @@ func runACME(listenAddr string, m http.Handler) error {
log.Warn("Failed to parse CA Root certificate, using default CA trust: %v", err)
}
}
certmagic.DefaultACME = certmagic.ACMEIssuer{
myACME := certmagic.NewACMEIssuer(magic, certmagic.ACMEIssuer{
CA: setting.AcmeURL,
TrustedRoots: certPool,
Email: setting.AcmeEmail,
@ -76,11 +75,7 @@ func runACME(listenAddr string, m http.Handler) error {
ListenHost: setting.HTTPAddr,
AltTLSALPNPort: altTLSALPNPort,
AltHTTPPort: altHTTPPort,
}
magic := certmagic.NewDefault()
myACME := certmagic.NewACMEIssuer(magic, certmagic.DefaultACME)
})
magic.Issuers = []certmagic.Issuer{myACME}

View file

@ -9,9 +9,9 @@ import (
"net/http/fcgi"
"strings"
"forgejo.org/modules/graceful"
"forgejo.org/modules/log"
"forgejo.org/modules/setting"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
)
func runHTTP(network, listenAddr, name string, m http.Handler, useProxyProtocol bool) error {

View file

@ -9,9 +9,9 @@ import (
"os"
"strings"
"forgejo.org/modules/graceful"
"forgejo.org/modules/log"
"forgejo.org/modules/setting"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/klauspost/cpuid/v2"
)

View file

@ -1,3 +1,4 @@
#! /bin/bash
# Heavily inspired by https://github.com/urfave/cli
_cli_bash_autocomplete() {
@ -6,9 +7,9 @@ _cli_bash_autocomplete() {
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
if [[ "$cur" == "-"* ]]; then
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} ${cur} --generate-shell-completion )
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} ${cur} --generate-bash-completion )
else
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-shell-completion )
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion )
fi
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0

View file

@ -9,9 +9,9 @@ _cli_zsh_autocomplete() {
local cur
cur=${words[-1]}
if [[ "$cur" == "-"* ]]; then
opts=("${(@f)$(_CLI_ZSH_AUTOCOMPLETE_HACK=1 ${words[@]:0:#words[@]-1} ${cur} --generate-shell-completion)}")
opts=("${(@f)$(_CLI_ZSH_AUTOCOMPLETE_HACK=1 ${words[@]:0:#words[@]-1} ${cur} --generate-bash-completion)}")
else
opts=("${(@f)$(_CLI_ZSH_AUTOCOMPLETE_HACK=1 ${words[@]:0:#words[@]-1} --generate-shell-completion)}")
opts=("${(@f)$(_CLI_ZSH_AUTOCOMPLETE_HACK=1 ${words[@]:0:#words[@]-1} --generate-bash-completion)}")
fi
if [[ "${opts[1]}" != "" ]]; then

41
contrib/backport/README Normal file
View file

@ -0,0 +1,41 @@
`backport`
==========
`backport` is a command to help create backports of PRs. It backports a
provided PR from main on to a released version.
It will create a backport branch, cherry-pick the PR's merge commit, adjust
the commit message and then push this back up to your fork's remote.
The default version will read from `docs/config.yml`. You can override this
using the option `--version`.
The upstream branches will be fetched, using the remote `origin`. This can
be overridden using `--upstream`, and fetching can be avoided using
`--no-fetch`.
By default the branch created will be called `backport-$PR-$VERSION`. You
can override this using the option `--backport-branch`. This branch will
be created from `--release-branch` which is `release/$(VERSION)`
by default and will be pulled from `$(UPSTREAM)`.
The merge-commit as determined by the github API will be used as the SHA to
cherry-pick. You can override this using `--cherry-pick`.
The commit message will be amended to add the `Backport` header.
`--no-amend-message` can be set to stop this from happening.
If cherry-pick is successful the backported branch will be pushed up to your
fork using your remote. These will be determined using `git remote -v`. You
can set your fork name using `--fork-user` and your remote name using
`--remote`. You can avoid pushing using `--no-push`.
If the push is successful, `xdg-open` will be called to open a backport url.
You can stop this using `--no-xdg-open`.
Installation
============
```bash
go install contrib/backport/backport.go
```

View file

@ -0,0 +1,474 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
//nolint:forbidigo
package main
import (
"context"
"fmt"
"log"
"net/http"
"os"
"os/exec"
"os/signal"
"path"
"strconv"
"strings"
"syscall"
"github.com/google/go-github/v64/github"
"github.com/urfave/cli/v2"
"gopkg.in/yaml.v3"
)
const defaultVersion = "v1.18" // to backport to
func main() {
app := cli.NewApp()
app.Name = "backport"
app.Usage = "Backport provided PR-number on to the current or previous released version"
app.Description = `Backport will look-up the PR in Gitea's git log and attempt to cherry-pick it on the current version`
app.ArgsUsage = "<PR-to-backport>"
app.Flags = []cli.Flag{
&cli.StringFlag{
Name: "version",
Usage: "Version branch to backport on to",
},
&cli.StringFlag{
Name: "upstream",
Value: "origin",
Usage: "Upstream remote for the Gitea upstream",
},
&cli.StringFlag{
Name: "release-branch",
Value: "",
Usage: "Release branch to backport on. Will default to release/<version>",
},
&cli.StringFlag{
Name: "cherry-pick",
Usage: "SHA to cherry-pick as backport",
},
&cli.StringFlag{
Name: "backport-branch",
Usage: "Backport branch to backport on to (default: backport-<pr>-<version>",
},
&cli.StringFlag{
Name: "remote",
Value: "",
Usage: "Remote for your fork of the Gitea upstream",
},
&cli.StringFlag{
Name: "fork-user",
Value: "",
Usage: "Forked user name on Github",
},
&cli.BoolFlag{
Name: "no-fetch",
Usage: "Set this flag to prevent fetch of remote branches",
},
&cli.BoolFlag{
Name: "no-amend-message",
Usage: "Set this flag to prevent automatic amendment of the commit message",
},
&cli.BoolFlag{
Name: "no-push",
Usage: "Set this flag to prevent pushing the backport up to your fork",
},
&cli.BoolFlag{
Name: "no-xdg-open",
Usage: "Set this flag to not use xdg-open to open the PR URL",
},
&cli.BoolFlag{
Name: "continue",
Usage: "Set this flag to continue from a git cherry-pick that has broken",
},
}
cli.AppHelpTemplate = `NAME:
{{.Name}} - {{.Usage}}
USAGE:
{{.HelpName}} {{if .VisibleFlags}}[options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}
{{if len .Authors}}
AUTHOR:
{{range .Authors}}{{ . }}{{end}}
{{end}}{{if .Commands}}
OPTIONS:
{{range .VisibleFlags}}{{.}}
{{end}}{{end}}
`
app.Action = runBackport
if err := app.Run(os.Args); err != nil {
fmt.Fprintf(os.Stderr, "Unable to backport: %v\n", err)
}
}
func runBackport(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
continuing := c.Bool("continue")
var pr string
version := c.String("version")
if version == "" && continuing {
// determine version from current branch name
var err error
pr, version, err = readCurrentBranch(ctx)
if err != nil {
return err
}
}
if version == "" {
version = readVersion()
}
if version == "" {
version = defaultVersion
}
upstream := c.String("upstream")
if upstream == "" {
upstream = "origin"
}
forkUser := c.String("fork-user")
remote := c.String("remote")
if remote == "" && !c.Bool("--no-push") {
var err error
remote, forkUser, err = determineRemote(ctx, forkUser)
if err != nil {
return err
}
}
upstreamReleaseBranch := c.String("release-branch")
if upstreamReleaseBranch == "" {
upstreamReleaseBranch = path.Join("release", version)
}
localReleaseBranch := path.Join(upstream, upstreamReleaseBranch)
args := c.Args().Slice()
if len(args) == 0 && pr == "" {
return fmt.Errorf("no PR number provided\nProvide a PR number to backport")
} else if len(args) != 1 && pr == "" {
return fmt.Errorf("multiple PRs provided %v\nOnly a single PR can be backported at a time", args)
}
if pr == "" {
pr = args[0]
}
backportBranch := c.String("backport-branch")
if backportBranch == "" {
backportBranch = "backport-" + pr + "-" + version
}
fmt.Printf("* Backporting %s to %s as %s\n", pr, localReleaseBranch, backportBranch)
sha := c.String("cherry-pick")
if sha == "" {
var err error
sha, err = determineSHAforPR(ctx, pr)
if err != nil {
return err
}
}
if sha == "" {
return fmt.Errorf("unable to determine sha for cherry-pick of %s", pr)
}
if !c.Bool("no-fetch") {
if err := fetchRemoteAndMain(ctx, upstream, upstreamReleaseBranch); err != nil {
return err
}
}
if !continuing {
if err := checkoutBackportBranch(ctx, backportBranch, localReleaseBranch); err != nil {
return err
}
}
if err := cherrypick(ctx, sha); err != nil {
return err
}
if !c.Bool("no-amend-message") {
if err := amendCommit(ctx, pr); err != nil {
return err
}
}
if !c.Bool("no-push") {
url := "https://github.com/go-gitea/gitea/compare/" + upstreamReleaseBranch + "..." + forkUser + ":" + backportBranch
if err := gitPushUp(ctx, remote, backportBranch); err != nil {
return err
}
if !c.Bool("no-xdg-open") {
if err := xdgOpen(ctx, url); err != nil {
return err
}
} else {
fmt.Printf("* Navigate to %s to open PR\n", url)
}
}
return nil
}
func xdgOpen(ctx context.Context, url string) error {
fmt.Printf("* `xdg-open %s`\n", url)
out, err := exec.CommandContext(ctx, "xdg-open", url).Output()
if err != nil {
fmt.Fprintf(os.Stderr, "%s", string(out))
return fmt.Errorf("unable to xdg-open to %s: %w", url, err)
}
return nil
}
func gitPushUp(ctx context.Context, remote, backportBranch string) error {
fmt.Printf("* `git push -u %s %s`\n", remote, backportBranch)
out, err := exec.CommandContext(ctx, "git", "push", "-u", remote, backportBranch).Output()
if err != nil {
fmt.Fprintf(os.Stderr, "%s", string(out))
return fmt.Errorf("unable to push up to %s: %w", remote, err)
}
return nil
}
func amendCommit(ctx context.Context, pr string) error {
fmt.Printf("* Amending commit to prepend `Backport #%s` to body\n", pr)
out, err := exec.CommandContext(ctx, "git", "log", "-1", "--pretty=format:%B").Output()
if err != nil {
fmt.Fprintf(os.Stderr, "%s", string(out))
return fmt.Errorf("unable to get last log message: %w", err)
}
parts := strings.SplitN(string(out), "\n", 2)
if len(parts) != 2 {
return fmt.Errorf("unable to interpret log message:\n%s", string(out))
}
subject, body := parts[0], parts[1]
if !strings.HasSuffix(subject, " (#"+pr+")") {
subject = subject + " (#" + pr + ")"
}
out, err = exec.CommandContext(ctx, "git", "commit", "--amend", "-m", subject+"\n\nBackport #"+pr+"\n"+body).Output()
if err != nil {
fmt.Fprintf(os.Stderr, "%s", string(out))
return fmt.Errorf("unable to amend last log message: %w", err)
}
return nil
}
func cherrypick(ctx context.Context, sha string) error {
// Check if a CHERRY_PICK_HEAD exists
if _, err := os.Stat(".git/CHERRY_PICK_HEAD"); err == nil {
// Assume that we are in the middle of cherry-pick - continue it
fmt.Println("* Attempting git cherry-pick --continue")
out, err := exec.CommandContext(ctx, "git", "cherry-pick", "--continue").Output()
if err != nil {
fmt.Fprintf(os.Stderr, "git cherry-pick --continue failed:\n%s\n", string(out))
return fmt.Errorf("unable to continue cherry-pick: %w", err)
}
return nil
}
fmt.Printf("* Attempting git cherry-pick %s\n", sha)
out, err := exec.CommandContext(ctx, "git", "cherry-pick", sha).Output()
if err != nil {
fmt.Fprintf(os.Stderr, "git cherry-pick %s failed:\n%s\n", sha, string(out))
return fmt.Errorf("git cherry-pick %s failed: %w", sha, err)
}
return nil
}
func checkoutBackportBranch(ctx context.Context, backportBranch, releaseBranch string) error {
out, err := exec.CommandContext(ctx, "git", "branch", "--show-current").Output()
if err != nil {
return fmt.Errorf("unable to check current branch %w", err)
}
currentBranch := strings.TrimSpace(string(out))
fmt.Printf("* Current branch is %s\n", currentBranch)
if currentBranch == backportBranch {
fmt.Printf("* Current branch is %s - not checking out\n", currentBranch)
return nil
}
if _, err := exec.CommandContext(ctx, "git", "rev-list", "-1", backportBranch).Output(); err == nil {
fmt.Printf("* Branch %s already exists. Checking it out...\n", backportBranch)
return exec.CommandContext(ctx, "git", "checkout", "-f", backportBranch).Run()
}
fmt.Printf("* `git checkout -b %s %s`\n", backportBranch, releaseBranch)
return exec.CommandContext(ctx, "git", "checkout", "-b", backportBranch, releaseBranch).Run()
}
func fetchRemoteAndMain(ctx context.Context, remote, releaseBranch string) error {
fmt.Printf("* `git fetch %s main`\n", remote)
out, err := exec.CommandContext(ctx, "git", "fetch", remote, "main").Output()
if err != nil {
fmt.Println(string(out))
return fmt.Errorf("unable to fetch %s from %s: %w", "main", remote, err)
}
fmt.Println(string(out))
fmt.Printf("* `git fetch %s %s`\n", remote, releaseBranch)
out, err = exec.CommandContext(ctx, "git", "fetch", remote, releaseBranch).Output()
if err != nil {
fmt.Println(string(out))
return fmt.Errorf("unable to fetch %s from %s: %w", releaseBranch, remote, err)
}
fmt.Println(string(out))
return nil
}
func determineRemote(ctx context.Context, forkUser string) (string, string, error) {
out, err := exec.CommandContext(ctx, "git", "remote", "-v").Output()
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to list git remotes:\n%s\n", string(out))
return "", "", fmt.Errorf("unable to determine forked remote: %w", err)
}
lines := strings.Split(string(out), "\n")
for _, line := range lines {
fields := strings.Split(line, "\t")
name, remote := fields[0], fields[1]
// only look at pushers
if !strings.HasSuffix(remote, " (push)") {
continue
}
// only look at github.com pushes
if !strings.Contains(remote, "github.com") {
continue
}
// ignore go-gitea/gitea
if strings.Contains(remote, "go-gitea/gitea") {
continue
}
if !strings.Contains(remote, forkUser) {
continue
}
if strings.HasPrefix(remote, "git@github.com:") {
forkUser = strings.TrimPrefix(remote, "git@github.com:")
} else if strings.HasPrefix(remote, "https://github.com/") {
forkUser = strings.TrimPrefix(remote, "https://github.com/")
} else if strings.HasPrefix(remote, "https://www.github.com/") {
forkUser = strings.TrimPrefix(remote, "https://www.github.com/")
} else if forkUser == "" {
return "", "", fmt.Errorf("unable to extract forkUser from remote %s: %s", name, remote)
}
idx := strings.Index(forkUser, "/")
if idx >= 0 {
forkUser = forkUser[:idx]
}
return name, forkUser, nil
}
return "", "", fmt.Errorf("unable to find appropriate remote in:\n%s", string(out))
}
func readCurrentBranch(ctx context.Context) (pr, version string, err error) {
out, err := exec.CommandContext(ctx, "git", "branch", "--show-current").Output()
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to read current git branch:\n%s\n", string(out))
return "", "", fmt.Errorf("unable to read current git branch: %w", err)
}
parts := strings.Split(strings.TrimSpace(string(out)), "-")
if len(parts) != 3 || parts[0] != "backport" {
fmt.Fprintf(os.Stderr, "Unable to continue from git branch:\n%s\n", string(out))
return "", "", fmt.Errorf("unable to continue from git branch:\n%s", string(out))
}
return parts[1], parts[2], nil
}
func readVersion() string {
bs, err := os.ReadFile("docs/config.yaml")
if err != nil {
if err == os.ErrNotExist {
log.Println("`docs/config.yaml` not present")
return ""
}
fmt.Fprintf(os.Stderr, "Unable to read `docs/config.yaml`: %v\n", err)
return ""
}
type params struct {
Version string
}
type docConfig struct {
Params params
}
dc := &docConfig{}
if err := yaml.Unmarshal(bs, dc); err != nil {
fmt.Fprintf(os.Stderr, "Unable to read `docs/config.yaml`: %v\n", err)
return ""
}
if dc.Params.Version == "" {
fmt.Fprintf(os.Stderr, "No version in `docs/config.yaml`")
return ""
}
version := dc.Params.Version
if version[0] != 'v' {
version = "v" + version
}
split := strings.SplitN(version, ".", 3)
return strings.Join(split[:2], ".")
}
func determineSHAforPR(ctx context.Context, prStr string) (string, error) {
prNum, err := strconv.Atoi(prStr)
if err != nil {
return "", err
}
client := github.NewClient(http.DefaultClient)
pr, _, err := client.PullRequests.Get(ctx, "go-gitea", "gitea", prNum)
if err != nil {
return "", err
}
if pr.Merged == nil || !*pr.Merged {
return "", fmt.Errorf("PR #%d is not yet merged - cannot determine sha to backport", prNum)
}
if pr.MergeCommitSHA != nil {
return *pr.MergeCommitSHA, nil
}
return "", nil
}
func installSignals() (context.Context, context.CancelFunc) {
ctx, cancel := context.WithCancel(context.Background())
go func() {
// install notify
signalChannel := make(chan os.Signal, 1)
signal.Notify(
signalChannel,
syscall.SIGINT,
syscall.SIGTERM,
)
select {
case <-signalChannel:
case <-ctx.Done():
}
cancel()
signal.Reset()
}()
return ctx, cancel
}

View file

@ -1,35 +1,34 @@
Environment To Ini
==================
This tool allows defining Forgejo's entire configuration via environment
variables, mostly geared towards usage in Docker.
Multiple docker users have requested that the Gitea docker is changed
to permit arbitrary configuration via environment variables.
Forgejo needs to use an INI file for configuration because the running
environment that starts the container may not be the same as the one used
by the hooks. An INI file also gives a good default and means that
users do not have to provide the entire set of environment variables.
Gitea needs to use an ini file for configuration because the running
environment that starts the docker may not be the same as that used
by the hooks. An ini file also gives a good default and means that
users do not have to completely provide a full environment.
With those caveats above, this command provides a generic way of
converting suitably structured environment variables into any ini
value.
When run, `environment-to-ini` will write the config files based on the
environment variables provided.
Check with the `-h` flag for several options to alter this behaviour.
To use the command is very simple just run it and the default gitea
app.ini will be rewritten to take account of the variables provided,
however there are various options to give slightly different
behavior and these can be interrogated with the `-h` option.
Environment variables of the form "FORGEJO__SECTION_NAME__KEY_NAME"
will be mapped to the ini section "[section_name]" and the key
"KEY_NAME" with the value as provided.
The environment variables should be of the form:
Environment variables of the form "FORGEJO__SECTION_NAME__KEY_NAME__FILE"
will be mapped to the ini section "[section_name]" and the key
"KEY_NAME" with the value loaded from the specified file.
GITEA__SECTION_NAME__KEY_NAME
Note, SECTION_NAME in the notation above is case-insensitive.
Environment variables are usually restricted to a reduced character
set "0-9A-Z_" - in order to allow the setting of sections with
characters outside of that set, they should be escaped as following:
"_0X2E_" for ".". The entire section and key names can be escaped as
a UTF8 byte string if necessary. E.g. to configure:
"_0X2E_" for "." and "_0X2D_" for "-". The entire section and key names
can be escaped as a UTF8 byte string if necessary. E.g. to configure:
"""
...
@ -39,8 +38,8 @@ a UTF8 byte string if necessary. E.g. to configure:
...
"""
You would set the environment variables: "FORGEJO__LOG_0x2E_CONSOLE__COLORIZE=false"
and "FORGEJO__LOG_0x2E_CONSOLE__STDERR=false". Other examples can be found
You would set the environment variables: "GITEA__LOG_0x2E_CONSOLE__COLORIZE=false"
and "GITEA__LOG_0x2E_CONSOLE__STDERR=false". Other examples can be found
on the configuration cheat sheet.
To build locally, run:

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