Compare commits

..

321 Commits

Author SHA1 Message Date
Giteabot 37bf5e761a
Fix bug when change user name (#25637) (#25645)
Backport #25637 by @lunny

Fix #25621

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-07-03 17:00:44 -04:00
silverwind 45d8d63621
Remove -v from vulncheck (#23953) (#25654)
Backport https://github.com/go-gitea/gitea/pull/23953 to 1.19 to fix the
branch build:

https://drone.gitea.io/go-gitea/gitea/75155/1/9

Co-authored-by: John Olheiser <john.olheiser@gmail.com>
2023-07-03 16:16:23 -04:00
Giteabot b4bfaf7d4d
Add link to support page for commercial support (#25293) (#25299)
Backport #25293 by @techknowlogick

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2023-06-16 14:19:26 +08:00
Jonathan Tran 1650a26eb5
Fix task list checkbox toggle to work with YAML front matter (#25184) (#25236)
Backport https://github.com/go-gitea/gitea/pull/25184 by @jtran
Closes #25225.

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

`data-source-position` of checkboxes in a task list was incorrect
whenever there was YAML front matter. This would result in issue content
or PR descriptions getting corrupted with random `x` or space characters
when a user checked or unchecked a task.
2023-06-13 20:22:59 +02:00
Giteabot a9ebf911fa
Hide limited users if viewed by anonymous ghost (#25214) (#25224)
Backport #25214 by @KN4CK3R

The ghost user leads to inclusion of limited users/orgs in
`BuildCanSeeUserCondition`.

Co-authored-by: KN4CK3R <admin@oldschoolhack.me>
2023-06-13 03:26:47 -04:00
Giteabot de6ac4bf2a
Add `WithPullRequest` for `actionsNotifier` (#25144) (#25196)
Backport #25144 by @Zettat123

Fix #25093

If
[`WithPullRequest`](679b1f7949/services/actions/notifier_helper.go (L90-L96))
is not called, the `Ref` in
[`notifyInput`](679b1f7949/services/actions/notifier_helper.go (L55-L65))
will be empty, so the workflows in the head branch will not be found and
triggered.

Co-authored-by: Zettat123 <zettat123@gmail.com>
2023-06-11 17:29:25 +08:00
Lauris BH a9030052a7
Fix open redirect check for more cases (#25143) (#25155)
Backport https://github.com/go-gitea/gitea/pull/25143

If redirect_to parameter has set value starting with \\example.com
redirect will be created with header Location: /\\example.com that will
redirect to example.com domain.
2023-06-08 13:03:15 -04:00
HesterG ed78711e46
Fix broken links in documents v1.19 (#25142)
Partially port #24630
2023-06-08 16:45:29 +08:00
HesterG c23ab427e1
Change branch name from master to main in some documents' links (#25126) (#25139)
Backport #25126

As title. And needs to backport to 1.19
2023-06-08 04:31:55 -04:00
sillyguodong e3cdb050fa
add zh-cn for `Upgrade from old Gitea` in v1.19 (#25022)
as title

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-06-06 11:39:53 -04:00
techknowlogick 8df6713a6e
update labels link to correct location in 1.19 docs (#25105) 2023-06-06 11:29:16 -04:00
Giteabot 3ef97932d5
Fix parallelly generating index failure with Mysql (#24567) (#25081)
Backport #24567 by @lunny

- Fix possible parallel creating commit status index problem and
creating issues/pull request index problem work with Mysql5/Mysql8
- Add parallel tests
- Reenable TestRepoCommitsStatusParallel on CI

Fix #22109

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-06-05 11:05:52 -04:00
Giteabot 15adec19e7
improve permission documentation (#23942) (#25078) 2023-06-05 18:04:59 +08:00
Giteabot 8e94b715cc
GitLab migration: Sanitize response for reaction list (#25054) (#25059)
Backport #25054 by @6543

Co-authored-by: 6543 <6543@obermui.de>
2023-06-02 17:13:33 -04:00
HesterG b2ec116c60
Add oauth Chinese document for v1.19 (#25020) 2023-06-02 10:52:53 -04:00
HesterG edfa2c5b78
Port Chinese document for localization to v1.19 (#25021) 2023-06-02 10:49:33 -04:00
Giteabot 73ae6b21d1
Fix users cannot visit issue attachment bug (#25019) (#25027)
Backport #25019 by @lunny

Caused by #24362

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: John Olheiser <john.olheiser@gmail.com>
2023-06-01 19:22:26 +02:00
silverwind b83e4f295d
Run markdownlint on drone, fix lint issue (#25040)
It currently does not run on 1.19 branch, resulting in lint error having
landed in https://github.com/go-gitea/gitea/pull/25016.
2023-06-01 10:34:40 -05:00
sillyguodong 95bf09fca0
Add chinese documentations for Packages (#24914) (#25016)
backport: #24914
2023-05-31 15:55:01 +08:00
sillyguodong 3b5cc02345
Add chinese documentations for installation (#24904) (#25015)
backport #24904
2023-05-31 14:17:19 +08:00
HesterG 37b73b3337
Add Chinese docs for help, contribution and development (#24925) (#25011)
Backport #24925, partially backport #24934
(`docs/content/doc/help/faq.zh-cn.md` file)

Part of backport has already done by #24942

Also backport #24881 to avoid "deadlock"

---------

Co-authored-by: Zettat123 <zettat123@gmail.com>
2023-05-31 14:12:37 +08:00
HesterG d2c9fb02dd
Unify doc links to use paths relative to doc folder (#24979) (#25000)
Backport #24979 

Changes:

1. Use uniform links types relative to doc folder (start with `doc/`)
2. According to [docusaurus
links](https://docusaurus.io/docs/markdown-features/links), if `<a>` is
used, the `href` is resolved as URL location, but not file location. So
need to use `[text]({{< relref "path" >}})` instead.
2023-05-30 18:08:32 +08:00
HesterG cdeb55f6e5
Remove unnecessary content on docs (#24976) (#25001)
Backport #24976
2023-05-30 17:21:03 +08:00
Giteabot 0ef7b66018
Update from-binary.en-us.md (#24975) (#24999)
Backport #24975 by @team-epk

Fixed link to the creating a systemd service in Ubuntu document.
2023-05-30 14:01:06 +08:00
sillyguodong 826b7b979c
Fix missing reference prefix of commits when sync mirror repository (#24994)
replace #24868
just a patch to fix #24824 in v1.19.4
The reference name of commits when synchronizing should also has prefix
like refs/heads/<branch-name>.
2023-05-30 13:12:21 +08:00
Amos (LFlare) Ng 7dc46ffbaa
Match unqualified references when syncing pulls as well (#23070)
It seems that `opts.RefFullName` may occassionally be set
to just the branch name, without the `refs/heads/` prefixing.
2023-05-29 11:32:32 +02:00
Giteabot 3a7e0953c1
`zh-cn` translation for usage docs (#24897) (#24977)
Backport #24897 by @Zettat123

- [x] agit-support
- [x] clone-filter
- [x] incoming-email
- [x] labels
- [x] linked-references
- [x] merge-message-templates
- [x] permissions
- [x] profile-readme
- [x] protected-tags
- [x] push
- [x] repo-mirror
- [x] secrets
- [x] template-repositories
- [x] webhooks

Co-authored-by: Zettat123 <zettat123@gmail.com>
2023-05-29 11:53:11 +08:00
Giteabot 9da84a36eb
simple docs fixes: 'pull request' page (en-us & zh-tw) link path to 'issue-pull-request-templates' (#24961) (#24970)
Backport #24961 by @jonkeim

Co-authored-by: Jon Keim <jon@windless.org>
Co-authored-by: silverwind <me@silverwind.io>
2023-05-28 21:51:53 -04:00
Giteabot 8a6a1143a4
Remove reference to caddy v1 in docs (#24962) (#24964)
Backport #24962 by @techknowlogick

caddy v1 is loong eol. v2 should be used.

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2023-05-28 05:34:50 -04:00
HesterG b4cd1028d9
Fix doc for 1.19 backend guideline (#24942)
Port the file change in
https://github.com/go-gitea/gitea/pull/24925/files from `main` to
`v1.19` to fix docs
2023-05-26 17:22:38 +08:00
Giteabot d1af0a3e4c
Merge two translation contributing documents (#23939) (#24933)
Backport #23939 by @lunny

This PR also adjusts the weights.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: delvh <dev.lh@web.de>
2023-05-25 12:07:25 -04:00
wxiaoguang a83d597989
Merge different languages for language stats (#24900) (#24921)
Backport #24900

Fix #24896

If users set different languages by `linguist-language`, the `stats` map
could be: `java: 100, Java: 200`.

Language stats are stored as case-insensitive in database and there is a
unique key.

So, the different language names should be merged to one unique name:
`Java: 300`
2023-05-25 07:12:21 +02:00
Paweł Bogusławski c5dee8823c
Hiding Secrets options when Actions feature is disabled (#24792)
`Secrets` options should be hidden if `Actions` feature is disabled.

This fixes in release/v1.19. In main probably fixed in
63a401ac40 (didn't check).

Fixes: 659055138b
Author-Change-Id: IB#1134011

Signed-off-by: Pawel Boguslawski <pawel.boguslawski@ib.pl>
2023-05-24 18:01:11 +08:00
Giteabot 275abd6593
Only validate changed columns when update user (#24867) (#24903)
Backport #24867 by @lunny

Fix #23211
Replace #23496

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-05-24 04:24:02 -04:00
wxiaoguang d19d5bc5b8
Make DeleteIssue use correct context (#24885)
Fix #24884 , the `ctx.Repo.GitRepo` might be nil.
2023-05-23 13:11:19 -04:00
Lunny Xiao e7757aa4be
Remove unnecessary prefix usage (#24888)
Since now all articles have a class, the `Usage:` is unnecessary. This
PR will remove them.
2023-05-24 00:34:31 +08:00
silverwind e81d38b0f6
Set `--font-weight-bold` to 600 (#24840)
Backport of https://github.com/go-gitea/gitea/pull/24827 to 1.19, just
the font weight reduction.
2023-05-22 10:56:41 +08:00
Giteabot f29c52a169
Return `404` in the API if the requested webhooks were not found (#24823) (#24830)
Backport #24823 by @sonjek

Should resolve first point of the issue
https://github.com/go-gitea/gitea/issues/24574

Co-authored-by: Yevhen Pavlov <yevhen.pavlov.ua@gmail.com>
2023-05-21 14:05:58 -04:00
Giteabot 04f9ab1aa9
Fix topics deleted via API not being deleted in org page (#24825) (#24829)
Backport #24825 by @yardenshoham

The topics are saved in the repo_topic table with a repoID key. They are
also saved directly in the repository table.

Before this PR, only `AddTopic` and `SaveTopics` made sure the `topics`
field in the repository field was synced with the repo_topic table.

This PR makes sure `GenerateTopics` and `DeleteTopic` also sync the
`topics` in the repository table.

`RemoveTopicsFromRepo` doesn't need to sync the data as it is only used
to delete a repository.

- Fixes #24820
2023-05-21 20:48:54 +08:00
Giteabot b369ed579d
Fix Actions being enabled accidentally (#24802) (#24810)
Backport #24802 by @wolfogre

Regression of #24536. If the user doesn't explicitly disable Actions, it
will be enabled.

1. Gitea will call `loadRepositoryFrom` before `loadActionsFrom`.

25d4f95df2/modules/setting/setting.go (L234-L237)
2. In `loadRepositoryFrom`,
`rootCfg.Section("actions").Key("ENABLED").MustBool(true)` will set
`actions.ENABLED` with `true`.

25d4f95df2/modules/setting/repository.go (L313-L315)
3. In `loadActionsFrom`, `rootCfg.Section("actions")` will get a section
with Actions enabled.

25d4f95df2/modules/setting/actions.go (L23-L26)


Although the cause of the problem was using `true` by copy-paste
mistake, it also surprised me that
**`rootCfg.Section("actions").Key("ENABLED").MustBool(true)` doesn't
only read, but also write.**

Co-authored-by: Jason Song <i@wolfogre.com>
2023-05-19 15:17:48 +02:00
wxiaoguang 64cc691b7f
Fix safari cookie session bug (#24772)
Partically backport #24330

Related: #24176

Maybe fix #24770
2023-05-18 09:10:23 +08:00
Giteabot 1bad05da3d
Fix missed table name on iterate lfs meta objects (#24768) (#24774)
Backport #24768 by @lunny

Fix #24763

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-05-17 20:35:20 +02:00
Giteabot 57f520e7e5
Make mailer SMTP check have timed context (#24751) (#24759)
Backport #24751 by @wxiaoguang

Make mailer SMTP check have timed context

Otherwise Gitea may block for long time if the DNS request blocks.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-05-17 06:08:39 -04:00
Giteabot e4f200e616
Respect original content when creating secrets (#24745) (#24746)
Backport #24745 by @wolfogre

Fix #24721.

Follow what GitHub does:
- Don't trim spaces for secrets.
- Newline should be `\n` instead of `\r\n`.

Did some tests with:

```yaml
name: secrets
on: push
jobs:
  show_secrets:
    runs-on: ubuntu-latest
    steps:
      - name: Dump secrets context
        run: echo '${{ toJSON(secrets) }}' | base64
```

`AAAAAA`:
```text
   AAAAAA
AAAAAA


```
`BBBBBB`:
```text



BBBBBB
BBBBBB   
```


On GitHub:

<img width="675" alt="image"
src="https://github.com/go-gitea/gitea/assets/9418365/0ec60652-c2a3-47bb-9f9d-7e81665355a8">


On Gitea (before):

<img width="673" alt="image"
src="https://github.com/go-gitea/gitea/assets/9418365/cce818bf-5edc-4656-86e1-2c81c304cdb2">

On Gitea (after):

<img width="673" alt="image"
src="https://github.com/go-gitea/gitea/assets/9418365/0b3b15af-4d48-4bab-a334-4738a1b0eb4a">

Co-authored-by: Jason Song <i@wolfogre.com>
2023-05-16 03:33:47 -04:00
wxiaoguang 6ecd2e782f
Fix Pull Mirror out-of-sync bugs (#24732) (#24733)
Backport #24732 

Bug-fix only
2023-05-15 20:30:21 +02:00
Giteabot 2fea93b2d3
Fix run list broken when trigger user deleted (#24706) (#24709)
Backport #24706 by @lunny

Fix #24682

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-05-14 04:55:58 -04:00
Giteabot 0ee51a5221
Add test for api team organization (#24699) (#24702)
Backport #24699 by @lunny

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-05-13 18:08:53 -04:00
Giteabot da1c38dd47
Fix `organization` field being `null` in `GET /api/v1/teams/{id}` (#24694) (#24696)
Backport #24694 by @yardenshoham

Enabled the organization loading flag.

- Fixes #20399 

# Before
```json
{
  ...
  "description": "",
  "organization": null,
  "includes_all_repositories": true,
  "permission": "owner",
  ...
}
```

# After
```json
{
  ...
  "description": "",
  "organization": {
    "id": 2,
    "name": "bigorg",
    "full_name": "",
    "avatar_url": "https://3000-yardenshoham-gitea-3gfrlc9gn4h.ws-us96b.gitpod.io/avatars/e2649b0c016d9102664a7d4349503eb9",
    "description": "",
    "website": "",
    "location": "",
    "visibility": "public",
    "repo_admin_change_team_access": true,
    "username": "bigorg"
  },
  "includes_all_repositories": true,
  "permission": "owner",
  ...
}
```

Signed-off-by: Yarden Shoham <git@yardenshoham.com>
Co-authored-by: Yarden Shoham <git@yardenshoham.com>
2023-05-13 21:01:54 +02:00
Giteabot aa984f21fa
Fix docs documenting invalid `@every` for `OLDER_THAN` cron settings (#24695) (#24698)
Backport #24695 by @yardenshoham

Looks like a copy-paste leftover

- Fixes #20868

Co-authored-by: Yarden Shoham <git@yardenshoham.com>
2023-05-13 23:47:56 +08:00
Giteabot 8f722012f6
Fix issues list page multiple selection update milestones (#24660) (#24663)
Backport #24660 by @lunny

Fix #24651

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-05-12 14:58:46 -04:00
oliverpool cb7ba8969d
fix: release page for empty or non-existing target (#24659)
Backport #24470

Fixes #24145

---

To solve the bug, I added a "computed" `TargetBehind` field to the
`Release` model, which indicates the target branch of a release. This is
particularly useful if the target branch was deleted in the meantime (or
is empty).

I also did a micro-optimization in `calReleaseNumCommitsBehind`. Instead
of checking that a branch exists and then call `GetBranchCommit`, I
immediately call `GetBranchCommit` and handle the `git.ErrNotExist`
error.

This optimization is covered by the added unit test.

_contributed in the context of @forgejo_
2023-05-12 14:14:41 -04:00
Giteabot 7eaf7aacde
Do not select line numbers when selecting text from the action run logs (#24594) (#24596)
Backport #24594 by @yardenshoham

- Fixes #24578

# Before

![image](https://user-images.githubusercontent.com/20454870/236873942-26e97f28-6595-4be9-88fa-158870eda253.png)

# After

![image](https://user-images.githubusercontent.com/20454870/236874171-8f0182a5-e953-4740-b875-f3542dee8325.png)

Signed-off-by: Yarden Shoham <git@yardenshoham.com>
Co-authored-by: Yarden Shoham <git@yardenshoham.com>
2023-05-08 15:56:53 -04:00
Giteabot b390b439e1
Fix close org projects (#24588) (#24591)
Backport #24588 by @yp05327

A part of #22865
We can not close org projects now. This PR will fix it.

Co-authored-by: yp05327 <576951401@qq.com>
2023-05-08 20:50:27 +02:00
Giteabot 306b7b5d1d
Refresh the refernce of the closed PR when reopening (#24231) (#24587)
Backport #24231 by @sillyguodong

Close #24213 
Replace #23830

#### Cause

- Before, in order to making PR can get latest commit after reopening,
the `ref`(${REPO_PATH}/refs/pull/${PR_INDEX}/head) of evrey closed PR
will be updated when pushing commits to the `head branch` of the closed
PR.

#### Changes

- For closed PR , won't perform these behavior: insert`comment`, push
`notification` (UI and email), exectue
[pushToBaseRepo](7422503341/services/pull/pull.go (L409))
function and trigger `action` any more when pushing to the `head branch`
of the closed PR.
- Refresh the reference of the PR when reopening the closed PR (**even
if the head branch has been deleted before**). Make the reference of PR
consistent with the `head branch`.

Co-authored-by: sillyguodong <33891828+sillyguodong@users.noreply.github.com>
2023-05-08 12:48:06 +02:00
wxiaoguang 4498a26222
Improve decryption failure message (#24573) (#24575)
Backport #24573

Help some users like #16832 #1851

There are many users reporting similar problem: if the SECRET_KEY
mismatches, some operations (like 2FA login) only reports unclear 500
error and unclear "base64 decode error" log (some maintainers ever spent
a lot of time on debugging such problem)

The SECRET_KEY was not well-designed and it is also a kind of technical
debt. Since it couldn't be fixed easily, it's good to add clearer error
messages, then at least users could know what the real problem is.
2023-05-07 22:12:32 +08:00
Giteabot 6f57be0025
Makefile: Use portable !, not GNUish -not, with find(1). (#24565) (#24572)
Backport #24565 by @riastradh

fix https://github.com/go-gitea/gitea/issues/24564

Co-authored-by: Taylor R Campbell <campbell+gitea@mumble.net>
2023-05-07 19:30:13 +08:00
Giteabot 257287954c
Fix the permission of team's `Actions` unit issue (#24536) (#24545)
Backport #24536 by @sillyguodong

close #24449

The unit of `Actions` should be contorlled not only by
`repository.DISABLED_REPO_UNITS` but also by `actions.ENABLED`
in the `app.ini`.
Previously, the permission of the team's `Actions` unit was not
controlled by `actions.Enabled`. So, even if the user sets
`actions.Enabled` to false, he can still select the permission of the
`Actions` unit for the team.

This PR makes the permissions of the team's `Actions` unit also
controlled by `actions.Enabled`. Just append`TypeActions` into
`DisabledRepoUnits` slice when initializing if `actions.Enabled` is
false.


### Changes:

If `Actions` is set disbaled in `app.ini`, like below:
```yaml
[actions]
ENABLED = false
```

1. If user try to create/edit a team, will prompt user that `Actions` is
disbaled.
 

![image](https://user-images.githubusercontent.com/33891828/236370415-961082b2-82d2-4d9e-8025-83872ad08cbb.png)

2. `actions` is not displayed in the sidebar on the team details page


![image](https://user-images.githubusercontent.com/33891828/236371817-f39f9bc9-5926-4b88-b5e6-d93617fcfb07.png)

Co-authored-by: sillyguodong <33891828+sillyguodong@users.noreply.github.com>
2023-05-05 15:07:02 +02:00
Lunny Xiao 7a74957c19
Fix new wiki page mirror (#24518)
backport #24395

---------

Co-authored-by: Giteabot <teabot@gitea.io>
2023-05-04 16:30:47 -04:00
Lunny Xiao f979569a3d
Bump go.etcd.io/bbolt and blevesearch deps (#23062) (#24519)
Backport #23062
Backport #24515
Fix #23617 

This notably brings support for GOARCH=loong64, among other fixes.
This PR also fix bleve search architecture problem.

---------

Signed-off-by: WANG Xuerui <xen0n@gentoo.org>
Co-authored-by: WÁNG Xuěruì <1175567+xen0n@users.noreply.github.com>
Co-authored-by: zeripath <art27@cantab.net>
2023-05-04 12:41:36 +02:00
techknowlogick 8ceb78caad
Changelog for 1.19.3 (#24495)
Co-authored-by: Yarden Shoham <git@yardenshoham.com>
Co-authored-by: John Olheiser <john.olheiser@gmail.com>
2023-05-03 11:14:50 -04:00
Giteabot 4dccac3dbf
Fix api error message if fork exists (#24487) (#24493)
Backport #24487 by @fnetX

On the @Forgejo instance of Codeberg, we discovered that forking a repo
which is already forked now returns a 500 Internal Server Error, which
is unexpected. This is an attempt at fixing this.

The error message in the log:
~~~
2023/05/02 08:36:30 .../api/v1/repo/fork.go:147:CreateFork() [E]
[6450cb8e-113] ForkRepository: repository is already forked by user
[uname: ...., repo path: .../..., fork path: .../...]
~~~

The service that is used for forking returns a custom error message
which is not checked against.

About the order of options:
The case that the fork already exists should be more common, followed by
the case that a repo with the same name already exists for other
reasons. The case that the global repo limit is hit is probably not the
likeliest.

---------

Co-authored-by: Otto Richter (fnetX) <git@fralix.ovh>
2023-05-03 08:15:56 -04:00
Giteabot 73e70f3c44 Enable whitespace rendering on selection in Monaco (#24444) (#24485)
Backport #24444 by @silverwind

Remove the
[renderWhitespace](https://microsoft.github.io/monaco-editor/docs.html#interfaces/editor.IEditorOptions.html#renderWhitespace)
override, so the default value of `selection` takes over and makes
whitespace visible on selection.

<img width="128" alt="Screenshot 2023-04-30 at 19 09 41"
src="https://user-images.githubusercontent.com/115237/235366707-d598268d-03cc-4839-a195-c460bddae99b.png">

Co-authored-by: silverwind <me@silverwind.io>
2023-05-02 23:29:38 -04:00
techknowlogick 499257d81e
nightly tag 2023-05-01 14:17:52 -04:00
wxiaoguang 84fa30e3d5
Remove less/_repository.less (#24467) 2023-05-01 10:37:49 -04:00
silverwind f1a0b64109
Skip known flaky `queue` tests on CI environment (#24443)
Backport of https://github.com/go-gitea/gitea/pull/24419 to 1.19.
2023-04-30 15:25:42 -04:00
techknowlogick bfdbc626cb
nightly tag for docker images 2023-04-30 13:42:37 -04:00
Giteabot 3abbf5fc21
Improve milestone filter on issues page (#22423) (#24440)
Backport #22423 by @lunny

Now we have `All milestones`, `No milestones`, `Open milestones` and
`Closed milestones`.
Fix #11924
Fix #22411 

<img width="1166" alt="image"
src="https://user-images.githubusercontent.com/81045/212243375-95eea035-a972-44b8-8088-53db614cb07e.png">

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-04-30 19:01:12 +02:00
wxiaoguang d9d3f5234e
Fix incorrect CurrentUser check for docker rootless (#24435)
Many users report that 1.19 has a regression bug: the rootless image
can't start if the UID is not 1000.

https://github.com/go-gitea/gitea/issues/23632#issuecomment-1524589213


https://discourse.gitea.io/t/gitea-doesnt-start-after-update-to-1-19/6920/9


The problem is that the IsRunUserMatchCurrentUser logic is fragile, the
"SSH" config is not ready when it executes.

This PR is just a quick fix for 1.19. For 1.20, we need a clear and
stable solution.
2023-04-29 23:47:04 -04:00
Giteabot 7d7ba76c08
Fix user-cards format (#24428) (#24431)
Backport #24428 by @KN4CK3R

Fixes #24418

Co-authored-by: KN4CK3R <admin@oldschoolhack.me>
2023-04-29 22:05:34 -04:00
Giteabot e76b3f72b2
getting the tag list does not require being signed in (#24413) (#24416)
Backport #24413 by @earl-warren

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

Co-authored-by: Earl Warren <109468362+earl-warren@users.noreply.github.com>
2023-04-29 09:43:37 +02:00
John Olheiser 4bc6bfb476
Changelog 1.19.2 (#24365)
Add changelog for 1.19.2

Signed-off-by: jolheiser <john.olheiser@gmail.com>
2023-04-28 07:39:52 +08:00
Giteabot 5999349ce7
Fix auth check bug (#24382) (#24387)
Backport #24382 by @lunny

Fix https://github.com/go-gitea/gitea/pull/24362/files#r1179095324

`getAuthenticatedMeta` has checked them, these code are duplicated one.
And the first invokation has a wrong permission check. `DownloadHandle`
should require read permission but not write.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-04-27 17:49:50 -05:00
Zettat123 e301e26d7a
Add tags list for repos whose release setting is disabled (#23465) (#24369)
Backport #23465

Close #23427 

Co-Author: @wxiaoguang 

If a repo's release setting is enabled, the logic has't changed.
Clicking the "Tags" button will jump to `/{user}/{repo}/tags` and
`templates/repo/release/list.tmpl` template will be used.

<img
src="https://user-images.githubusercontent.com/15528715/224939362-bd8974fd-08b0-4f79-a114-3389d15847ca.png"
width="600px" />

If the release setting is disabled, clicking the "Tags" button will
still jump to `/{user}/{repo}/tags` but a new template
`templates/repo/tag/list.tmpl` will be used.

<img
src="https://user-images.githubusercontent.com/15528715/233834564-74741e49-f4e9-47c8-ac12-e306642798dc.png"
width="600px" />

Since both templates above need to render the tags list, I moved the
tags list to a shared template located in
`templates/repo/tag/table.tmpl`.
2023-04-27 12:40:36 +08:00
Giteabot d2efd2bf73
Require repo scope for PATs for private repos and basic authentication (#24362) (#24364)
Backport #24362 by @jolheiser

> The scoped token PR just checked all API routes but in fact, some web
routes like `LFS`, git `HTTP`, container, and attachments supports basic
auth. This PR added scoped token check for them.

Signed-off-by: jolheiser <john.olheiser@gmail.com>
Co-authored-by: John Olheiser <john.olheiser@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-04-26 20:57:51 -04:00
yp05327 89297c9355
Fix no edit/close/delete button in org repo project view page (#24349)
Backport #24301
2023-04-26 07:38:41 -04:00
Giteabot d2328c4051
Fix Monaco IOS keyboard button (#24341) (#24347)
Backport #24341 by @silverwind

Fix https://github.com/go-gitea/gitea/issues/16188. Turns out the
element was completely misaligned by fomantic styles. Add most of the
original styles in `!important` form to fix.

Tapping the button doesn't do anything useful in Simulator.app, but I
guess it's still better to not outright hide it in case it has a
possiblity to work.

<img width="121" alt="image"
src="https://user-images.githubusercontent.com/115237/234379685-4e67f8cd-7e91-4bcc-8e17-9d5b2ebed6cd.png">

Co-authored-by: silverwind <me@silverwind.io>
2023-04-26 05:42:00 -04:00
Giteabot af5d66b341
Fix wrong error info in RepoRefForAPI (#24344) (#24351)
Backport #24344 by @yp05327

Co-authored-by: yp05327 <576951401@qq.com>
2023-04-26 11:07:51 +02:00
Giteabot 912a418920
Fix broken clone script on an empty archived repo (#24339) (#24348)
Backport #24339 by @yardenshoham

I made it render the script even if the repo is archived

- Fixes #24324

Signed-off-by: Yarden Shoham <git@yardenshoham.com>
Co-authored-by: Yarden Shoham <git@yardenshoham.com>
2023-04-26 10:13:16 +02:00
Giteabot cc7a4f17e0
Don't set meta `theme-color` by default (#24340) (#24346)
Backport #24340 by @silverwind

Fixes https://github.com/go-gitea/gitea/issues/24321. By not setting
this meta tag, Safari will use body color for chrome and out-of-viewport
areas, which looks much better then static mismatching green.

As per
[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta/name/theme-color)
it's really only Apple browsers who still support this tag, most others
have dropped support.
 
Before:
<img width="347" alt="Screenshot 2023-04-25 at 19 59 13"
src="https://user-images.githubusercontent.com/115237/234363180-0fe667ef-5469-4f5f-b31a-c9d73aff10ac.png">

After:
<img width="361" alt="Screenshot 2023-04-25 at 20 00 00"
src="https://user-images.githubusercontent.com/115237/234363185-e2d2b62f-0133-4316-944d-b614ffb84eb0.png">

Co-authored-by: silverwind <me@silverwind.io>
2023-04-26 01:33:15 -04:00
wxiaoguang 5f82011b7c
Add --font-weight-bold and set previous bold to 601 (#24307) (#24331)
Backport #24307

Fix #24305

According to MDN, "bold" starts from 700, some fonts do not provide
"bolding" for weight 600

Manually backport, no CSS conflict.
2023-04-25 19:51:54 -04:00
Giteabot 1bbbeb24ef
Respect the REGISTER_MANUAL_CONFIRM setting when registering via OIDC (#24035) (#24333)
Backport #24035 by @garymoon

This change prevents Gitea from bypassing the manual approval process
for newly registered users when OIDC is used.

- Resolves https://github.com/go-gitea/gitea/issues/23392

Signed-off-by: Gary Moon <gary@garymoon.net>
Co-authored-by: Gary Moon <garymoon@users.noreply.github.com>
2023-04-25 15:25:08 -04:00
Giteabot 1254a8271e
Wrap too long push mirror addresses (#21120) (#24334)
Backport #21120 by @JakobDev

I noticed that it is possible to break the push mirror list by entering
a too long URL. This should fix it.

| Before         | After     | 
|--------------|-----------|

|![Before](https://user-images.githubusercontent.com/15185051/189294585-333965d1-0f0f-48e2-96d5-e04b84b55ae3.png)|![After](https://user-images.githubusercontent.com/15185051/189294619-301e271c-b89b-4bc0-9c11-9536bd0302be.png)|

Co-authored-by: JakobDev <jakobdev@gmx.de>
2023-04-25 12:47:26 -04:00
Giteabot ef3e3afc05
Fix typo in API route (#24310) (#24332)
Backport #24310 by @silverwind

Continuation of https://github.com/go-gitea/gitea/pull/23995

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: bilogic <946010+bilogic@users.noreply.github.com>
2023-04-25 10:57:33 -04:00
Giteabot b1094ff28c
Remove org users who belong to no teams (#24247) (#24313)
Backport #24247 by @yp05327

Fix #24128

Co-authored-by: yp05327 <576951401@qq.com>
Co-authored-by: silverwind <me@silverwind.io>
2023-04-24 22:50:32 -04:00
Giteabot 8044d87c18
Unify nightly naming across binaries and docker images (#24116) (#24308)
Backport #24116 by @techknowlogick

Proposal found here: https://github.com/go-gitea/gitea/issues/23654

TODO: make non-breaking (can we publish docker image using dev and
nightly prefix? at same time). if anyone has advice please comment :)

If this PR is merged, then I can add redirects to the downloads site.

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2023-04-24 12:23:01 -04:00
Giteabot 1b8e36587e
Upgrade act (#24298) (#24300)
Backport #24298 by @Zettat123

Upgrade act to version `v0.243.4`

- Support `configuration variables`
([#43](https://gitea.com/gitea/act/pulls/43))
- Support specifying command for `services` containers
([#50](https://gitea.com/gitea/act/pulls/50))

Co-authored-by: Zettat123 <zettat123@gmail.com>
2023-04-24 10:18:47 +02:00
Giteabot a2f52f3561
Fix bug when deleting wiki with no code write permission (#24274) (#24295)
Backport #24274 by @lunny

Fix #24125

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2023-04-23 20:20:45 -04:00
Giteabot 65de747b13
Handle canceled workflow as a warning instead of a fail (#24282) (#24292)
Backport #24282 by @wolfogre

Follow what Drone CI does:


![image](https://user-images.githubusercontent.com/9418365/233829853-d1c30a30-10cc-4b97-a134-793a79d46d85.png)

Co-authored-by: Jason Song <i@wolfogre.com>
2023-04-23 15:44:45 -04:00
Giteabot 7e86dffc35
Load reviewer for comments when dismissing a review (#24281) (#24288) 2023-04-23 12:44:57 -04:00
Giteabot 7297cceda7
Only delete secrets belonging to its owner (#24284) (#24286)
Backport #24284 by @KN4CK3R

Co-authored-by: KN4CK3R <admin@oldschoolhack.me>
2023-04-23 16:36:20 +02:00
oliverpool 077160b838
fix calReleaseNumCommitsBehind (#24148) (#24197)
Backport #24148

`repoCtx.CommitsCount` is not reliably the commit count of the default
branch (Repository.GetCommitsCount depends on what is currently
displayed).

_contributed in the context of @forgejo_

---------

Co-authored-by: Giteabot <teabot@gitea.io>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2023-04-22 12:30:24 -04:00
wxiaoguang da4448421e
Fix footer display (#24251) (#24269)
Backport #24251

Fix #24249

Diff with ignoring spaces:
https://github.com/go-gitea/gitea/pull/24269/files?diff=split&w=1


Manually tested


![image](https://user-images.githubusercontent.com/2114189/233766806-18eb18ad-0c4d-44f7-b0fc-b40466c64445.png)

Co-authored-by: Lauris BH <lauris@nix.lv>
2023-04-22 04:21:56 -04:00
yp05327 5ccb626cda
Fix owner team access mode value in team_unit table (#24224)
Partly backport #23675

Co-authored-by: Giteabot <teabot@gitea.io>
2023-04-22 08:53:03 +02:00
Giteabot b00f7c3c54
Fix access token issue on some public endpoints (#24194) (#24259)
Backport #24194 by @harryzcy

- [x] Identify endpoints that should be public
- [x] Update integration tests

Fix #24159

Co-authored-by: harryzcy <harry@harryzheng.com>
2023-04-21 14:59:17 -04:00
Giteabot 51fd730147
Show commit history for closed/merged PRs (#24238) (#24261)
Backport #24238 by @wxiaoguang

Close #24237

Before:

<details>


![image](https://user-images.githubusercontent.com/2114189/233424875-a69c6dad-df4a-483e-b796-36c6459af2d6.png)

</details>

After:


![image](https://user-images.githubusercontent.com/2114189/233424712-60a296de-017b-49a8-89b2-5925ff452646.png)

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-04-21 14:15:00 -04:00
Giteabot 7117355169
Fix label color, fix divider in dropdown (#24215) (#24244)
Backport #24215 by @silverwind

Two small CSS fixes:

1. Fix basic primary label hover:

Before:
<img width="172" alt="Screenshot 2023-04-19 at 20 00 32"
src="https://user-images.githubusercontent.com/115237/233161903-eec2de54-1a58-44ac-a6ef-2d77157317f6.png">

After:
<img width="179" alt="Screenshot 2023-04-19 at 20 05 29"
src="https://user-images.githubusercontent.com/115237/233162028-995404ac-5852-4d03-821f-6eb4a918a9e3.png">

2. Fix border color of divider in dropdown and remove margin so it looks
better with hover effect, as discussed in
https://github.com/go-gitea/gitea/pull/24143:

<img width="205" alt="Screenshot 2023-04-19 at 20 03 24"
src="https://user-images.githubusercontent.com/115237/233162102-3f4a4142-9634-4c95-acf0-be57072ce7eb.png">
<img width="311" alt="Screenshot 2023-04-19 at 20 03 55"
src="https://user-images.githubusercontent.com/115237/233162109-faa616f6-02e4-43d3-95fa-66787a7f914c.png">

Co-authored-by: silverwind <me@silverwind.io>
2023-04-20 22:28:55 -05:00
wxiaoguang d5f2c9d74d
Fix issue attachment handling (#24202) (#24221)
Backport #24202

Close #24195

Fix the bug:

1. The old code doesn't handle `removedfile` event correctly
2. The old code doesn't provide attachments for type=CommentTypeReview

---------

Co-authored-by: silverwind <me@silverwind.io>
2023-04-20 04:21:10 -04:00
yp05327 95c2cb4b79
Add run status in action view page (#24223)
Backport #23212
2023-04-20 09:24:50 +02:00
Giteabot 7d717e22a8
Vertical widths of containers removed (#24184) (#24211)
Backport #24184 by @krzysztofjeziorny

A vertical overflow appears in Firefox 112/MacOS 12.6 when the system
setting for scrollbars is to "Always" show them.

Here, the fixed 100vw container widths are removed, which removes the
overflow. It is, however, only simulated in Developer Tools in latest
Firefox and Chromium, so please test on a Gitea installation.

Co-authored-by: Krzysztof Jeziorny <872730+krzysztofjeziorny@users.noreply.github.com>
2023-04-20 09:02:38 +08:00
Giteabot dc66ceadac
Don't list root repository on compare page if pulls not allowed (#24183) (#24210)
Backport #24183 by @lunny

Fix #24165

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-04-19 19:07:47 -04:00
Giteabot 8cd5483e8a
Fix template error in pull request with deleted head repo (#24192) (#24216)
Backport #24192 by @brechtvl

Rendering of Allow Edits from Maintainers did not check if the head repo
exists, while other parts of the page handle it gracefully.

Co-authored-by: Brecht Van Lommel <brecht@blender.org>
2023-04-19 17:20:19 -04:00
Giteabot 2e6e5bc9c9
Fix incorrect CORS default values (#24206) (#24217)
Backport #24206 by @wxiaoguang

Document: 

```
;ALLOW_DOMAIN = *
;METHODS = GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS
```

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-04-19 16:23:25 -04:00
Giteabot f134229bf2
Use correct locale key for forks page (#24172) (#24175)
Backport #24172 by @jolheiser


4014200021/options/locale/locale_en-US.ini (L873)

4014200021/options/locale/locale_en-US.ini (L943)

Co-authored-by: John Olheiser <john.olheiser@gmail.com>
2023-04-17 17:21:53 -04:00
Giteabot 3d3c740636
Fix Org edit page bugs: renaming detection, maxlength (#24161) (#24171)
Backport #24161 by @wxiaoguang

## Before

* The renaming detection is wrong (eg: pasting a new name into the input
doesn't trigger the detection)
* The renaming prompt layout is not good
* Some MaxSize/maxlength rules is missing


Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-04-17 12:20:47 -04:00
Giteabot c4f569b9a5
Support converting varchar to nvarchar for mssql database (#24105) (#24168)
Backport #24105 by @lunny

In #12269, all string fields of struct will generate a NVARCHAR column
in database, but for those Gitea instances installed before that PR,
users have to convert columns themselves.

In this PR, we update the `./gitea admin convert` commands to support
both MySQL and MSSQL database converting. Previously, it only supported
converting `utf8 -> utf8mb4` for MySQL.
Now, it will check the database types.
If it's MSSQL, it will convert `VARCHAR -> NVARCHAR` as well.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-04-17 10:10:15 -04:00
wxiaoguang 03b6e7900b
Use 1.18's aria role for dropdown menus (#24144) (#24155)
Backport #24144

Co-authored-by: silverwind <me@silverwind.io>
2023-04-17 07:02:09 -04:00
Patrick Schratz 463e144d97
Update redis library to support redis v7 (#24114) (#24156)
backports #24114

---------

Co-authored-by: techknowlogick <hello@techknowlogick.com>
2023-04-17 02:34:59 -04:00
wxiaoguang 2b32f8b95f
Sort repo topic labels by name (#24123) (#24153)
Backport #24123
Close #24077

Manually backported and tested.

<img width="330" alt="image"
src="https://user-images.githubusercontent.com/2114189/232283645-92cc85dd-ba16-44a9-a7ef-5712b9d285e9.png">
2023-04-17 09:00:19 +08:00
wxiaoguang 94fbd44bac
Set EasyMDE heading font-size to the same size as the resulting markdown (#24151) (#24152)
Backport #24151

Fix #23816

<img width="519" alt="image"
src="https://user-images.githubusercontent.com/2114189/232283304-21f56e82-d80e-4199-9b14-74699d80cd20.png">
2023-04-16 17:34:19 -04:00
Giteabot 494e373292
Fix 2-dot direct compare to use the right base commit (#24133) (#24150)
Backport #24133 by @jtran

For 2-dot direct compare, we should use the base commit in the title and
templates, as is used elsewhere, not the common ancestor which is used
for 3-dot compare. I believe that this change should have been included
in #22949.

Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2023-04-16 13:17:13 +02:00
sillyguodong 10f93995e9
Highlight selected file in the PR file tree (#23947) (#24126)
backport #23947 by @yusifeng 

before

![before](https://user-images.githubusercontent.com/36984894/230327904-6e712ca2-f777-4cad-99f3-53bc20008180.gif)

after

![after](https://user-images.githubusercontent.com/36984894/230327966-6e5dd971-f0df-427a-a80b-6a9b6db6065d.gif)

Co-authored-by: yusifeng <36984894+yusifeng@users.noreply.github.com>
2023-04-14 17:54:22 +08:00
Giteabot 67a73dd05f
Fix incorrect server error content in RunnersList (#24118) (#24121)
Backport #24118 by @yp05327

Co-authored-by: yp05327 <576951401@qq.com>
2023-04-14 12:52:21 +08:00
Zettat123 893c97dd71
Fix mismatch between hook events and github event types (#24048) (#24091)
Backport https://github.com/go-gitea/gitea/pull/24048

Some workflow trigger events can have multiple activity types, such as
`issues` and `pull_request`, and user can specify which types can
trigger the workflow. See GitHub documentation:
https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows

Now some hook events cannot match the workflow trigger events correctly
because we don't check the activity types. For example,
`pull_request_label` is an individual hook event. But there isn't a
`pull_request_label` workflow trigger event, we can only use
`pull_request` event's `label` activity type. If we don't check the
activity types, the workflows without the `label` activity type may be
triggered by the `pull_request_label` event by mistake. We need to
improve the match logic.

- [x] [`issues`
](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#issues)
- [x]
[`issue_comment`](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#issue_comment)
- [x]
[`pull_request`](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request)
- [x]
[`pull_request_review`](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_review)
- [x]
[`pull_request_review_comment`](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_review_comment)
- [x]
[`release`](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#release)
- [x]
[`registry_package`](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#registry_package)
2023-04-13 15:19:41 +08:00
6543 447fa6715c
Changelog v1.19.1 (#24079) 2023-04-13 03:38:06 +02:00
wxiaoguang 2398a23562
Backport locales to 1.19 (#24083)
Backport locales

Generated by `go run build/backport-locales.go release/v1.19`
2023-04-12 17:07:43 -04:00
Giteabot 93c7611c32
Improve LFS error logs (#24072) (#24082)
Backport #24072 by @wxiaoguang

The error logs were not clear.

Help (but not fix) #24053

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-04-12 16:23:57 -04:00
Giteabot 607801ec41
Update the value of the `diffEnd` when click `Show More` btn in the DiffFileTree (#24069) (#24078)
Backport #24069 by @sillyguodong

In the component `DiffFileTree`,if don't update the value of the
`diffEnd` in the callback of ajax request, click `Show More` btn will
always return the same response, duplicate files are appended to the
file list.

Before:

https://user-images.githubusercontent.com/33891828/231371188-82d169af-10bb-47e2-8aca-83ced2597f2d.mov

After:

https://user-images.githubusercontent.com/33891828/231369805-39a5a4d0-662c-4f08-bc5a-7d31e8782453.mov

Co-authored-by: sillyguodong <33891828+sillyguodong@users.noreply.github.com>
2023-04-12 15:27:53 -04:00
wxiaoguang 16d2cf05ab
Fix custom mailer template on Windows (#24081)
Fix #24075
Fix #23873

From the log:

```
2023/04/02 19:41:46 .../templates/mailer.go:68:1() [T] Adding mailer template for \issue\default from "C:\gitea\custom\templates\mail\issue\default.tmpl"
```

That `assetName ` on Windows is wrong. Gitea only uses slash `/`.
2023-04-12 12:16:40 -04:00
wxiaoguang d562b419b6
Make label templates have consistent behavior and priority (#23749) (#24071)
Backport #23749

Fix https://github.com/go-gitea/gitea/issues/23715

Backported manually and tested manually.
2023-04-12 16:05:10 +02:00
Hester Gong 5482602ba8
Add cardtype to org/user level project on creation, edit and view (#24043) (#24066)
Backport #24043 

Part of #23318

The way to fix the missing cardtype for user/org level projects in this
PR is to port the cardtype related part from #22112 to org/user level
projects' template and router functions.

Before:
<img width="1135" alt="截屏2023-04-11 13 55 49"
src="https://user-images.githubusercontent.com/17645053/231069068-ba897129-ae90-4aa0-9b0f-468bf5c65375.png">

<img width="1131" alt="截屏2023-04-11 13 55 59"
src="https://user-images.githubusercontent.com/17645053/231069084-279f6681-5a10-42da-b5a8-2b0ba47c7078.png">


After:
Create
<img width="835" alt="截屏2023-04-11 13 27 16"
src="https://user-images.githubusercontent.com/17645053/231064445-0d6e12bd-5725-48db-a102-80e7472757c2.png">

Edit
<img width="852" alt="截屏2023-04-11 13 27 05"
src="https://user-images.githubusercontent.com/17645053/231064503-c70525cd-1038-43ec-8d93-8b8d95d183d4.png">

View
<img width="1329" alt="截屏2023-04-11 13 26 56"
src="https://user-images.githubusercontent.com/17645053/231064529-26023c85-698b-4b2e-af02-45f9820c77ec.png">

---------

Co-authored-by: silverwind <me@silverwind.io>
2023-04-12 08:23:05 -04:00
Giteabot 37d3e0ec33
Fix accidental overwriting of LDAP team memberships (#24050) (#24065)
Backport #24050 by @sillyguodong

In the `for` loop, the value of `membershipsToAdd[org]` and
`membershipsToRemove[org]` is a slice that should be appended instead of
overwritten.
Due to the current overwrite, the LDAP group sync only matches the last
group at the moment.

## Example reproduction
- an LDAP user is both a member of
`cn=admin_staff,ou=people,dc=planetexpress,dc=com` and
`cn=ship_crew,ou=people,dc=planetexpress,dc=com`.
- configuration of `Map LDAP groups to Organization teams ` in
`Authentication Sources`:
```json
{
    "cn=admin_staff,ou=people,dc=planetexpress,dc=com":{
        "test_organization":[
            "admin_staff",
            "test_add"
        ]
    },
    "cn=ship_crew,ou=people,dc=planetexpress,dc=com":{
        "test_organization":[
            "ship_crew"
        ]
}
```
- start `Synchronize external user data` task in the `Dashboard`.
- the user was only added for the team `test_organization.ship_crew`

Co-authored-by: sillyguodong <33891828+sillyguodong@users.noreply.github.com>
2023-04-12 07:22:02 -04:00
Denys Konovalov 29724f31c5
Refactor commit status for Actions jobs (#23786) (#24060)
Backport #23786

Refactor commit status for Actions jobs (#23786)

Highlights:
- Treat `StatusSkipped` as `CommitStatusSuccess` instead of
`CommitStatusFailure`, so it fixed #23599.
- Use the bot user `gitea-actions` instead of the trigger as the creator
of commit status.
- New format `<run_name> / <job_name> / (<event>)` for the context of
commit status to avoid conflicts.
- Add descriptions for commit status.
- Add the missing calls to `CreateCommitStatus`.
- Refactor `CreateCommitStatus` to make it easier to use.

Co-authored-by: Jason Song <i@wolfogre.com>
2023-04-11 22:37:34 -04:00
Giteabot 580da8f353
Fix branch protection priority (#24045) (#24061)
Backport #24045 by @lunny

Fix #24044

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-04-11 21:07:38 +02:00
Giteabot 8644993699
Update documentation to explain which projects allow Gitea to host static pages (#23993) (#24058)
Backport #23993 by @6543

close  #23521

Signed-off-by: 6543 <6543@obermui.de>
Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: a1012112796 <1012112796@qq.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-04-11 18:43:35 +02:00
Jason Song f55fe989a4
Use actions job link as commit status URL instead of run link (#24023) (#24032)
Backport #24023.

A commit status is bound to a job, not a run.
2023-04-10 08:46:36 -05:00
Giteabot 27dbe97542
Add actions support to package auth verification (#23729) (#24028)
Backport #23729 by @yp05327

Partly fixes https://github.com/go-gitea/gitea/issues/23642

Error info:

![image](https://user-images.githubusercontent.com/18380374/227827027-4280a368-ec9e-49e0-bb93-6b496ada7cd9.png)
ActionsUser (userID -2) is used to login in to docker in action jobs.

Due to we have no permission policy settings of ActionsUser now,
ActionsUser can only access public registry by this quick fix.

Co-authored-by: yp05327 <576951401@qq.com>
2023-04-10 10:36:21 +02:00
Giteabot abf0386e2e
Fix protected branch for API (#24013) (#24027)
Backport #24013 by @lunny

Fix #23998

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-04-10 14:48:02 +08:00
Giteabot 2b10eebed8
Show errors for KaTeX and mermaid on the preview tab (#24009) (#24019)
Backport #24009 by @silverwind

There is a conflicting fomantic rule that hid the error messages inside
the markdown preview tab for things like mermaid or katex. Overruled it
to always show these errors.

<img width="774" alt="image"
src="https://user-images.githubusercontent.com/115237/230738528-322814c1-8994-495e-b901-bbb79b924ccb.png">

Co-authored-by: silverwind <me@silverwind.io>
2023-04-09 08:48:28 -04:00
Giteabot 695738fb31
Show protected branch rule names again (#23907) (#24018)
Backport #23907 by @HesterG

`!important`s for one of the primary label selectors are removed by
#23774, so the repository branch protection settings ui will not have
the demanding css. This PR modifies `.ui.primary.label` to fix it.

Before:
<img width="1408" alt="飞书20230404-115410"
src="https://user-images.githubusercontent.com/17645053/229683221-ef9c7d5c-68a8-42b0-ba19-ef2d5dfce5f9.png">

After:
<img width="1419" alt="截屏2023-04-04 11 56 32"
src="https://user-images.githubusercontent.com/17645053/229683469-70cfc92d-d7ef-4323-a7f5-2247810fabce.png">

Co-authored-by: Hester Gong <hestergong@gmail.com>
Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-04-09 14:06:16 +02:00
Giteabot cfde557e23
fix: do not escape space between PyPI repository url and package name… (#23981) (#24008)
Backport #23981 by @Gunzinger

…; add trailing slash to PyPI repository URL (in accordance to PEP-503)

This should solve Issue #23980, by moving the space in front of the
package name and the package name out of the `gitea-origin-url` block.
It also adds a trailing slash to the PyPI repository URL in accordance
to [Python PEP-503](https://peps.python.org/pep-0503/).

Co-authored-by: Daniel Gunzinger <daniel.gunzinger@gmail.com>
2023-04-08 23:13:43 +02:00
Giteabot 3dbc63777f
Adjust sticky pr header to cover background (#23956) (#23999)
Backport #23956 by @silverwind

Very minor CSS tweak: Adjust sticky PR header to cover the box-shadow of
selected files.

Before:
<img width="1250" alt="Screenshot 2023-04-06 at 22 54 59"
src="https://user-images.githubusercontent.com/115237/230492218-4d71da48-a362-4c52-a7f7-01daf4ffa458.png">

After:
<img width="1255" alt="Screenshot 2023-04-06 at 22 54 46"
src="https://user-images.githubusercontent.com/115237/230492227-c7142210-e535-4da8-b610-37d33dcbb549.png">

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-04-08 18:36:11 +02:00
Giteabot 4aabd8e823
Set `ref` to fully-formed of the tag when trigger event is `release` (#23944) (#23989)
Backport #23944 by @sillyguodong

Fix #23943
When trigger event is `release`, ref should be like
`refs/tags/<tag_name>` instead of `CommitID`

Co-authored-by: sillyguodong <33891828+sillyguodong@users.noreply.github.com>
2023-04-08 20:43:46 +08:00
Giteabot 6a5b8eb7b6
Fix redirect bug when creating issue from a project (#23971) (#23997)
Backport #23971 by @lunny

Fix #23966

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-04-08 12:38:56 +02:00
Giteabot a00e473341
Remove `Repository.getFilesChanged` to fix Actions `paths` and `paths-ignore` filter (#23920) (#23969)
Backport #23920 by @ChristopherHX

Remove the misbehaving function and call
Repository.GetFilesChangedBetween instead.

Fixes #23919

---

~~_TODO_ test this~~ `Repository.getFilesChanged` seems to be only used
by Gitea Actions, but a similar function already exists

**Update** I tested this change and the issue is gone.

Co-authored-by: ChristopherHX <christopher.homberger@web.de>
2023-04-08 16:16:21 +08:00
Giteabot 4019a6d4b2
Discolor pull request tab labels (#23950) (#23987)
Backport #23950 by @silverwind

https://github.com/go-gitea/gitea/pull/22687 has discolored the repo tab
labels. This does the same for PR tabs for consistency. Value `0` is
still rendered like before.

Before:
<img width="502" alt="Screenshot 2023-04-06 at 19 35 24"
src="https://user-images.githubusercontent.com/115237/230454329-db6244ff-7d7e-4a2f-9240-f618a1c57f8c.png">

After:
<img width="497" alt="Screenshot 2023-04-06 at 19 35 07"
src="https://user-images.githubusercontent.com/115237/230454321-a0be6551-8c31-45e4-a1fb-ffc0d85d87bf.png">
<img width="497" alt="Screenshot 2023-04-06 at 19 38 37"
src="https://user-images.githubusercontent.com/115237/230454570-2fe2aa67-dfa7-4b2e-8c04-8dd40e6e99fc.png">

Co-authored-by: silverwind <me@silverwind.io>
2023-04-07 22:32:42 -04:00
Jason Song 0487e39f82
Treat PRs with agit flow as fork PRs when triggering actions. (#23884) (#23967)
Backport #23884.

There is no fork concept in agit flow, anyone with read permission can
push `refs/for/<target-branch>/<topic-branch>` to the repo. So we should
treat it as a fork pull request because it may be from an untrusted
user.
2023-04-07 17:43:12 -04:00
Giteabot 3a7cb1a83b
Use Get/Set instead of Rename when Regenerate session id (#23975) (#23983)
Backport #23975 by @wxiaoguang

Do not use Rename here, because the old sid and new sid may be in
different redis cluster slot.

Fix #23869

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-04-07 14:21:20 -05:00
Giteabot f317186aa6
Do not crash when parsing an invalid workflow file (#23972) (#23976)
Backport #23972 by @wolfogre

Fix #23658.

Related to https://gitea.com/gitea/act/pulls/39

Co-authored-by: Jason Song <i@wolfogre.com>
2023-04-07 09:55:59 -04:00
Giteabot 5b7df68555
Ensure RSS icon is present on all repo tabs (#23904) (#23973)
Backport #23904 by @silverwind

Previously, not all repo tabs had shown the RSS icon in the repo header
because the context data was not being set. Added this context data in a
new function.

Before:

<img width="806" alt="image"
src="https://user-images.githubusercontent.com/115237/229639615-9cc00e75-3a26-4ff4-a6f2-316c1fccc596.png">

After:

<img width="815" alt="Screenshot 2023-04-04 at 00 16 17"
src="https://user-images.githubusercontent.com/115237/229639201-2e1c015b-1f13-46d4-aa14-e7a82fab3982.png">

Co-authored-by: silverwind <me@silverwind.io>
2023-04-07 14:55:30 +02:00
Giteabot 833a4b1775
Hardcode path to docker images (#23955) (#23968)
Backport #23955 by @techknowlogick

Fix #23954

This allows for building on platforms that don't have docker hub as the
default container registry.

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2023-04-07 14:54:28 +02:00
Giteabot 1b8ecd179b
Title can be empty when creating tag only (#23917) (#23961)
Backport #23917 by @Zettat123

Fixes #23809

Make the title not required. If the title is empty when creating release
(not tag), an error message will be displayed.

![image](https://user-images.githubusercontent.com/15528715/229761056-c52e338b-5f25-4d7d-bb44-2cb0304abcee.png)

Co-authored-by: Zettat123 <zettat123@gmail.com>
2023-04-07 20:13:57 +08:00
6543 085b56302c
Support "." char as user name for User/Orgs in RSS/ATOM/GPG/KEYS path ... (#23874) (#23878)
Backport #23874
2023-04-07 18:10:17 +08:00
Lunny Xiao 5066b208de
Merge `push to create`, `open PR from push`, and `push options` docs articles into one (#23744) (#23959)
backport #23744
2023-04-07 15:49:26 +08:00
wxiaoguang ac658bb92c
Backport locales to 1.19 (#23960)
This time the backport is done by `backport-locales.go` automatically,
no manual fix.

However, there are some new broken translations in 1.20 (main branch),
so we must fix our ini package next time, then the broken could be
resolved fundmentally.
2023-04-07 15:29:54 +08:00
Giteabot 001d3fb820
Delete deleted release attachments immediately from storage (#23913) (#23958)
Backport #23913 by @lunny

Previously, deleted release attachments were kept forever on the
external storage.
Note: It may be very slow now if there are many attachments to be
deleted on this release.

Fix #23728

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-04-06 18:38:34 -04:00
silverwind 8092251133
Left-align review comments (#23937)
Small extract from https://github.com/go-gitea/gitea/pull/23553 for
1.19:

Before:
<img width="1190" alt="Screenshot 2023-04-05 at 21 47 55"
src="https://user-images.githubusercontent.com/115237/230190330-3cee8904-8558-43ea-b9d3-424d807d0b73.png">

After:
<img width="1181" alt="Screenshot 2023-04-05 at 21 47 38"
src="https://user-images.githubusercontent.com/115237/230190315-c1c3cae5-1bc3-4c2d-bd3d-c119fa01be82.png">
2023-04-06 09:45:45 +02:00
Giteabot 55239cbab7
Fix image border-radius (#23886) (#23930)
Backport #23886 by @wxiaoguang

1. Instead of polluting the `border-radius` style globally, each "img"
usage should declare their own styles.
2. There were some bugs in code, I believe the `.img` selector was done
by mistake.

After:


![image](https://user-images.githubusercontent.com/2114189/229415742-161b018f-14c3-471d-bcf7-34f83e5c2d89.png)


![image](https://user-images.githubusercontent.com/2114189/229415789-829d364a-76da-47a5-8c61-398cc990873c.png)

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-04-05 17:07:44 +02:00
Giteabot df74ee0376
Scroll collapsed file into view (#23702) (#23929)
Backport #23702 by @jpraet

Fixes #23701, #23515.

Alternate approach to #23604 using CSS scroll-margin-top, which is also
taken into account for direct links to files in a diff:

* On the PR diff, this currently shows the previous file first:
https://try.gitea.io/jpraet/test/pulls/13/files#diff-b94d08b409f9d05fb65b6cccaf7b3e4ecc7cc333
* On the commit diff, the first line of the linked file is currently
under the sticky header:
1a19e6b14e (diff-b94d08b409f9d05fb65b6cccaf7b3e4ecc7cc333)

Co-authored-by: Jimmy Praet <jimmy.praet@ksz-bcss.fgov.be>
2023-04-05 13:49:22 +03:00
Giteabot 8d88f148d7
docs: make the required backticks in email password more explicit (#23923) (#23926)
Backport #23923 by @teauxfu

updated the example config to make the needed backticks around the
password more obvious

Co-authored-by: alex <alexmw777@gmail.com>
2023-04-04 15:06:54 -04:00
Giteabot 7bfab90a8f
docs: fix typo (#23924) (#23925)
Backport #23924 by @teauxfu

fixes a minor typo in the email templates page

Co-authored-by: alex <alexmw777@gmail.com>
2023-04-04 18:13:09 +02:00
Lunny Xiao 1a8da2e08f
Update docs markdown file weight to make it clear (#23909) (#23921)
backport #23909
2023-04-04 11:27:38 -04:00
Giteabot 7c180ff8eb
Fix code view (diff) broken layout (#23096) (#23918)
Backport #23096 by @wxiaoguang

Close #22911

I think it's ready for review now, feel free to test it, welcome to help
to improve.

### Before


![image](https://user-images.githubusercontent.com/2114189/220958734-06871615-b498-4143-8449-3d443f08ffaa.png)

### After


![image](https://user-images.githubusercontent.com/2114189/220958621-0dce2728-57b8-4a1f-ac5d-48c7c2d42f5c.png)

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-04-04 16:02:29 +02:00
Giteabot c34f7cdb1a
Use ghost user if package creator does not exist (#23822) (#23915)
Backport #23822 by @KN4CK3R

Fixes #23818

Co-authored-by: KN4CK3R <admin@oldschoolhack.me>
2023-04-04 20:37:28 +08:00
Giteabot fd0baf637d
Org pages style fixes (#23901) (#23914)
Backport #23901 by @silverwind

Few fixes/enhancements around org pages:

Use flexbox for member and repo lists and tweak rendering of tabs and
list:

<img width="765" alt="Screenshot 2023-04-03 at 22 54 24"
src="https://user-images.githubusercontent.com/115237/229625716-92a834c3-9121-4729-8b9b-3a3973cf9a91.png">
<img width="771" alt="Screenshot 2023-04-03 at 22 55 15"
src="https://user-images.githubusercontent.com/115237/229625719-acc08ce8-4489-44a6-a9b9-e36755c55b1d.png">

Vertically center remove/leave buttons, add link to avatar:

<img width="1223" alt="Screenshot 2023-04-03 at 21 51 20"
src="https://user-images.githubusercontent.com/115237/229612616-b662b795-e754-41a1-a77a-381c267e6104.png">

Co-authored-by: silverwind <me@silverwind.io>
2023-04-04 19:05:41 +08:00
Giteabot dff3ce089d
User/Org Feed render description as per web (#23887) (#23906)
Backport #23887 by @6543

User descriptions should be rendered so that links and other markup
appear correct in RSS feeds.

test will be added by #23874

Co-authored-by: 6543 <6543@obermui.de>
2023-04-04 00:44:50 -04:00
Giteabot 9836b7db7b
Use User.ID instead of User.Name in ActivityPub API for Person IRI (#23823) (#23905)
Backport #23823 by @wxiaoguang

Thanks to @trwnh

Close #23802

The ActivityPub id is an HTTPS URI that should remain constant, even if
the user changes their name.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-04-03 22:41:57 -05:00
Giteabot d752f0d7d0
Add git dashes separator to some "log" and "diff" commands (#23606) (#23720)
Backport #23606 by @wxiaoguang

Reference:
https://github.com/go-gitea/gitea/issues/22578#issuecomment-1444180053

Credits to @tdesveaux , thank you very much for catching the problem. If
you'd like to open a PR, feel free to replace this one.

Git reports fatal errors for ambiguous arguments:

```
fatal: ambiguous argument 'refs/a...refs/b': unknown revision or path not in the working tree.
        Use '--' to separate paths from revisions, like this:
        'git <command> [<revision>...] -- [<file>...]'
```

So the `--` separator is necessary in some cases.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-04-03 21:43:51 -04:00
Giteabot 669c76c0fd
Fix `cases.Title` crash for concurrency (#23885) (#23903)
Backport #23885 by @wxiaoguang

Regression of #19676 and #21814

Fix #23872

`cases.Title` is not thread-safe, it has internal state, so it can't be
used as a global shared variable.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-04-04 01:26:14 +02:00
Giteabot ac57ec5c47
Fix user profile description rendering (#23882) (#23902)
Backport #23882 by @wxiaoguang

Found an UI problem when testing #23874

The `ul li` styles were polluted.

Before:


![image](https://user-images.githubusercontent.com/2114189/229409756-22438268-ee36-4e4a-a20b-04ee8ee4a79d.png)


After:


![image](https://user-images.githubusercontent.com/2114189/229409809-25cea715-b6f1-4346-9bb4-3fbb58fcca65.png)

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-04-03 16:00:24 -05:00
Giteabot f6dab64412
Convert .Source.SkipVerify to $cfg.SkipVerify (#23839) (#23899)
Backport #23839 by @yp05327

`Source` doesn't have `SkipVerify`, it is defined in `cfg`

Co-authored-by: yp05327 <576951401@qq.com>
2023-04-03 13:02:28 -04:00
Giteabot 847f0bb9f3
Fix review box viewport overflow issue (#23800) (#23898)
Backport #23800 by @silverwind

Fix regression that came likely from
https://github.com/go-gitea/gitea/pull/23271:

Long lines of text currently cause the review box's CodeMirror element
to resize which apparently is not recognized by [popper's resize
detection](https://popper.js.org/docs/v2/modifiers/event-listeners/) and
which causes the element to go partially out of viewport until a reflow
happens:


![wrap](https://user-images.githubusercontent.com/115237/228673260-f8ffe89e-5724-4fb9-b93f-30b146c4c436.gif)

Fix this by setting the element to a static width derived from viewport
width and remove the previously clumsy media queries.

Co-authored-by: silverwind <me@silverwind.io>
2023-04-03 12:11:08 -04:00
Giteabot 1886bd6a01
Rename actions unit to `repo.actions` and add docs for it (#23733) (#23881)
Backport #23733 by @wolfogre

I neglected that the `NameKey` of `Unit` is not only for translation,
but also configuration. So it should be `repo.actions` to maintain
consistency.

## ⚠️ BREAKING ⚠️

If users already use `actions.actions` in `DISABLED_REPO_UNITS` or
`DEFAULT_REPO_UNITS`, it will be treated as an invalid unit key.

Co-authored-by: Jason Song <i@wolfogre.com>
2023-04-03 12:54:36 +02:00
wxiaoguang 7e07f5c4dc
Backport some locales to 1.19 (#23880)
There are still broken locales (eg: #23866), so this backport is still done manually.
2023-04-03 03:21:42 -04:00
Jason Song 799536db46
Fix checks for `needs` in Actions (#23789) (#23831)
Backport #23789.

Fix:
- https://gitea.com/gitea/act_runner/issues/77
- https://gitea.com/gitea/act_runner/issues/81

Before:
<img width="1489" alt="image"

src="https://user-images.githubusercontent.com/9418365/228501567-f752cf87-a7ed-42c6-8f3d-ba741795c1fe.png">

Highlights:
- Upgrade act to make things doable, related to
  - https://gitea.com/gitea/act/pulls/32
  - https://gitea.com/gitea/act/pulls/33
  - https://gitea.com/gitea/act/pulls/35
- Make `needs` works
- Sort jobs in the original order in the workflow files
2023-04-03 13:24:45 +08:00
Giteabot c68650a7fb
Prefill input values in oauth settings as intended (#23829) (#23871)
Backport #23829 by @yp05327

Co-authored-by: yp05327 <576951401@qq.com>
2023-04-03 04:33:12 +02:00
Giteabot fe7caa05cc
Check `IsActionsToken` for LFS authentication (#23841) (#23875)
Backport #23841 by @Zettat123

Close #23824 

Actions cannot fetch LFS objects from private repos because we don't
check if the user is the `ActionUser`.

Co-authored-by: Zettat123 <zettat123@gmail.com>
2023-04-02 21:30:33 +01:00
Giteabot 026167f854
Remove assertion debug code for show/hide refactoring (#23576) (#23868)
Backport #23576 by @wxiaoguang

When doing the refactoring:

* #22950

I added some debug mode code (assertShown) to help to catch bugs, it did
catch some bugs like:

* #23074

If it has been proved that there is no more bugs, this assertion could
be removed easily and clearly.

Feel free to decide when to remove it (feel free to convert it from
Draft to Ready for Review).
2023-04-02 16:20:06 +08:00
Giteabot 8abfbe2165
Fix JS error when changing PR's target branch (#23862) (#23864)
Backport #23862 by @wxiaoguang

Caught by @justusbunsi 

An old bug from #6488

In `pullrequest_targetbranch_change`, the `data` might be empty, because
`UpdatePullRequestTarget` may respond `http.StatusNoContent`.

And the old code's `$branchTarget.text(data.base_branch);` doesn't make
sense, because in the end, the page will be always reloaded.

So, just remove the `$branchTarget.text(data.base_branch);`, everything
should be fine.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-04-01 21:15:46 -04:00
Giteabot 16bfe983c2
Fix 500 error if there is a name conflict when edit authentication source (#23832) (#23852)
Backport #23832 by @yp05327

Co-authored-by: yp05327 <576951401@qq.com>
2023-03-31 12:53:25 -04:00
Giteabot 503af4b807
CSS color tweaks (#23828) (#23842)
Backport #23828 by @silverwind

Change grey shades in arc-green to match the theme more:

<img width="661" alt="Screenshot 2023-03-30 at 21 42 34"
src="https://user-images.githubusercontent.com/115237/228957952-8e099e56-6923-4aa6-8ce9-3c1cd898b73e.png">

Adjusted grey shade in light theme:

<img width="652" alt="image"
src="https://user-images.githubusercontent.com/115237/228963876-3bde6181-8397-4dc2-be72-33982e6c7acb.png">

Increase contrast in arc-green, change background to slightly darker
shade, change forgeground to slightly brighter colors:

<img width="283" alt="Screenshot 2023-03-30 at 22 33 20"
src="https://user-images.githubusercontent.com/115237/228957957-272c24a5-dd0b-427a-b6b7-e62836bdd73c.png">

Increase contrast of grey text in light theme as well by making them
darker:

<img width="273" alt="Screenshot 2023-03-30 at 22 33 35"
src="https://user-images.githubusercontent.com/115237/228957959-283139c7-6fa7-4b68-9fdd-16c668ad1301.png">

Add color rule for border multiple select items:

<img width="183" alt="Screenshot 2023-03-30 at 22 29 31"
src="https://user-images.githubusercontent.com/115237/228957954-6b5a752d-bbb0-4519-ab35-d02c0804d955.png">
<img width="181" alt="Screenshot 2023-03-30 at 22 29 46"
src="https://user-images.githubusercontent.com/115237/228957956-fca9790a-d6c9-4f31-8d1b-d183ab3ac669.png">

Added color rule for red `*` on required form fields:

<img width="97" alt="image"
src="https://user-images.githubusercontent.com/115237/228958760-517ad9ef-565d-4349-b734-9b559ab42429.png">

Co-authored-by: silverwind <me@silverwind.io>
2023-03-31 17:24:09 +08:00
Giteabot 8b3dd7de5d
Fix incorrect visibility dropdown list in add/edit user page (#23804) (#23833)
Backport #23804 by @yp05327

Visibility dropdown list will not work in add/edit user page when error
occurred

Co-authored-by: yp05327 <576951401@qq.com>
2023-03-31 16:25:21 +08:00
Giteabot a04535e212
[Patch] Fix closed PR also triggers Webhooks and actions (#23782) (#23834)
Backport #23782 by @sillyguodong

Fix #23707 
Cause by #23189
This PR is a quick fix that, when pushing commits to closed PR, webhook
and actions also be triggered.

Co-authored-by: sillyguodong <33891828+sillyguodong@users.noreply.github.com>
2023-03-31 14:29:23 +08:00
wxiaoguang a1460333dc
Fix "Updating branch by merge" bug in "update_branch_by_merge.tmpl" (#23790) (#23825)
Backport #23790

Fix regression of #22683

Pass all variables into sub-template.

Close #23787
2023-03-31 12:15:51 +08:00
wxiaoguang d15f20b2d2
Add ONLY_SHOW_RELEVANT_REPOS back, fix explore page bug, make code more strict (#23766) (#23791)
Follow #21962

After I eat my own dogfood, I would say that
ONLY_SHOW_RELEVANT_REPOS=false is necessary for many private/enterprise
instances, because many private repositories do not have
"description/topic", users just want to search by their names.

This PR also adds `PageIsExploreRepositories` check, to make code more
strict, because the `search` template is shared for different purpose.

And during the test, I found a bug that the "Search" button didn't
respect the "relevant" parameter, so this PR fixes the bug by the way
together.
2023-03-30 09:09:22 -05:00
sillyguodong 863da7d5a1
Fix cancel button in the page of project edit not work (#23655) (#23813)
Backport #23655

Before, in project edit page, the cancel button is not work.


https://user-images.githubusercontent.com/33891828/227182731-6478e29f-0e52-48c4-beb0-6a7d1dda6a1d.mov

1. The wrong classname `cancel` was added to the `<a>` tag. That
classname caused the default click event of `<a>` tag to be cancelled.
Because we have the following settings in the global. So I remove the
classname `cancel`.


9be90a5875/web_src/js/features/common-global.js (L325-L327)

2. Another change is that page will redirect to the previous page.


https://user-images.githubusercontent.com/33891828/227187326-c653c6d6-9715-440f-a732-ba0a6f012c81.mov
2023-03-30 11:15:50 +02:00
wxiaoguang 1cad923b36
Backport locales (with manual fix) (#23808)
Backport locales (with manual fix)
2023-03-30 14:58:57 +08:00
Jason Song edb6ba28f1
Add missing translation for `actions.runners.reset_registration_token_success` (#23732) (#23781)
Backport #23732.

Used at


4011821c94/routers/web/shared/actions/runners.go (L157)
2023-03-29 22:05:26 -04:00
Giteabot 494721cc90
Don't apply the group filter when listing LDAP group membership if it is empty (#23745) (#23788)
Backport #23745 by @zeripath

When running listLdapGroupMemberships check if the groupFilter is empty
before using it to list memberships.

Fix #23615

Signed-off-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: zeripath <art27@cantab.net>
2023-03-29 15:00:12 -04:00
Giteabot d27e693ecf
Add CSS rules for basic colored labels (#23774) (#23777)
Backport #23774 by @silverwind

Before:

<img width="164" alt="Screenshot 2023-03-28 at 23 35 46"
src="https://user-images.githubusercontent.com/115237/228372437-663111b9-7285-4fa2-9125-fb5e1cad21d7.png">

After:
<img width="166" alt="Screenshot 2023-03-28 at 23 35 54"
src="https://user-images.githubusercontent.com/115237/228372441-49430517-6b2d-4389-b11c-c30a724f6de7.png">

Also I removed the `!important` on the primary label as it's very likely
unnecessary with the amount of specificity the selector already has.

Co-authored-by: silverwind <me@silverwind.io>
2023-03-29 14:15:00 -04:00
Zettat123 81a995cd84
Fix project card preview select and template select (#23684) (#23731)
Backport #23684 
Now user cannot set Card Previews when creating a new project.

Before:


https://user-images.githubusercontent.com/15528715/227488883-29bbd636-8b98-45b3-b2f8-de5206b045dc.mp4

After:


https://user-images.githubusercontent.com/15528715/227488976-3447f252-805a-4f18-ae0e-1cddd921dcc3.mp4
2023-03-29 14:52:50 +08:00
Giteabot d977e7ec10
Add creation time in tag list page (#23693) (#23773)
Backport #23693 by @balki

Fixes #21699

Co-authored-by: Balki <189196+balki@users.noreply.github.com>
2023-03-28 18:00:07 -04:00
wxiaoguang b73d1ac1eb
Make minio package support legacy MD5 checksum (#23768) (#23770)
Backport #23768 (no source code conflict, only some unrelated
docs/test-ini conflicts)

Some storages like:

 * https://developers.cloudflare.com/r2/api/s3/api/
 * https://www.backblaze.com/b2/docs/s3_compatible_api.html

They do not support "x-amz-checksum-algorithm" header

But minio recently uses that header with CRC32C by default. So we have
to tell minio to use legacy MD5 checksum.
2023-03-29 00:02:13 +08:00
Giteabot 428d26d4a8
fix br display for packages curls (#23737) (#23764)
Backport #23737 by @HesterG

Before:
<img width="1403" alt="截屏2023-03-27 15 48 23"
src="https://user-images.githubusercontent.com/17645053/227875392-399debf7-db75-4d9a-9436-409f75447c65.png">
This happens because the `<br>` matches this
[rule](e6e602fd8d/web_src/css/markup/content.css (L428)),
which is not necessary here (This is introduced by #22861, did a quick
check, and this is the only place used `<br>` inside `<code>` from the
PR):
```css
.markup code br,
.markup tt br {
  display: none;
}
```

After:
<img width="1398" alt="截屏2023-03-27 15 46 50"
src="https://user-images.githubusercontent.com/17645053/227875244-b7fba432-b32c-42f7-9517-4e05bb2e64ea.png">

Co-authored-by: Hester Gong <hestergong@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-03-28 07:31:42 +01:00
Giteabot a254c26df9
Fix issue due date edit toggle bug (#23723) (#23758)
Backport #23723 by @wxiaoguang

Use `toggleElem` instead of jQuery's `fadeToggle`, which can't be caught
by eslint jquery plugin.

Hopefully this could be the last bug for the jQuery show/hide
refactoring.

Need to backport.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-03-27 21:13:11 -05:00
Giteabot 1fed0e1adc
Fix profile page email display, respect settings (#23747) (#23756)
Backport #23747 by @wxiaoguang

Always respect the `setting.UI.ShowUserEmail` and `KeepEmailPrivate`
setting.

* It doesn't make sense to show user's own E-mail to themself.
* Always hide the E-mail if KeepEmailPrivate=true, then the user could
know how their profile page looks like for others.
* Revert the `setting.UI.ShowUserEmail` change from #4981 . This setting
is used to control the E-mail display, not only for the user list page.

ps: the incorrect `<div .../>` tag on the profile page has been fixed by
#23748 together, so this PR becomes simpler.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-03-28 07:55:20 +08:00
zeripath 88a652fa92
Improve commit graph page UI alignment (#23751) (#23754)
Backport #23751

Fix the UI alignment by the way (adding some `gt-mr-xx`)

Before:


![image](https://user-images.githubusercontent.com/2114189/228034794-7a6ac8d6-01fa-4dd2-97d4-0df0368f8ee0.png)

After:


![image](https://user-images.githubusercontent.com/2114189/228034938-64edeadf-7c99-4e74-b658-0ca62b72d596.png)

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-03-27 17:27:08 -04:00
Giteabot 35039b8563
Use GitHub Actions compatible globbing for `branches`, `tag`, `path` filter (#22804) (#23740)
Backport #22804 by @ChristopherHX

Replaces the current globbing library with a
https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet
compatible one.

This adds support for
- `paths-ignore`, `tags-ignore` and `branches-ignore` filters.
- negative patterns in `paths`, `tags` and `branches` filters
- using both `tags` and `paths` filter on the push event

Original PR https://gitea.com/gitea/act/pulls/13.
nektos/act PR https://github.com/nektos/act/pull/1618 for the
workflowpattern package (It can take some months for it to appear in
https://gitea.com/gitea/act)

Related to https://github.com/go-gitea/gitea/issues/13539

Co-authored-by: ChristopherHX <christopher.homberger@web.de>
2023-03-27 14:01:46 -04:00
Giteabot 62afc0a727
Redirect to project again after editing it (#23326) (#23739)
Backport #23326 by @yp05327

A part of https://github.com/go-gitea/gitea/pull/22865

We have edit buttons in projects list page and project view page.
But after user edit a project, it will always redirect to the projects
list page.

Co-authored-by: yp05327 <576951401@qq.com>
2023-03-27 21:42:47 +08:00
Zettat123 b6a2323981
Check LFS/Packages settings in dump and doctor command (#23631) (#23730)
Backport #23631 
Close #23622

As described in the issue, disabling the LFS/Package settings will cause
errors when running `gitea dump` or `gitea doctor`. We need to check the
settings and the related operations should be skipped if the settings
are disabled.
2023-03-27 16:28:22 +08:00
Giteabot f23b587fe7
Describe Gitea's purpose more accurately (#23698) (#23710) 2023-03-26 17:33:32 +08:00
Giteabot 305cac291d
Remove row clicking from notification table (#22695) (#23706)
Backport #22695 by @jolheiser

Resolves #22692

Signed-off-by: jolheiser <john.olheiser@gmail.com>
Co-authored-by: John Olheiser <john.olheiser@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-03-26 01:21:40 +02:00
Giteabot 6705b215db
Fix incorrect `HookEventType` of pull request review comments (#23650) (#23678)
Backport #23650 by @Zettat123

`HookEventType` of pull request review comments should be
`HookEventPullRequestReviewComment` but some event types are
`HookEventPullRequestComment` now.

Co-authored-by: Zettat123 <zettat123@gmail.com>
2023-03-24 20:56:15 -04:00
Giteabot a9b4aa4cc4
Create commit status when event is `pull_request_sync` (#23683) (#23691)
Backport #23683 by @sillyguodong

Fix: #23674
If the type of `hook_event` is `pull_request_sync`, also need to insert
a record of `commit_status` into DB.
Because `pull_request` event and `pull_request_sync` event have the same
payload, so the code is reusable.

Screenshot:

![image](https://user-images.githubusercontent.com/33891828/227465436-1b436807-d0b2-4a2b-8890-09d96c7f666d.png)

Co-authored-by: sillyguodong <33891828+sillyguodong@users.noreply.github.com>
2023-03-24 17:40:24 -04:00
Giteabot 1faa39b44c
Drop migration for ForeignReference (#23605) (#23666)
Backport #23605 by @wolfogre

Fix
https://github.com/go-gitea/gitea/issues/21086#issuecomment-1476560381

Related to #21721

Co-authored-by: Jason Song <i@wolfogre.com>
2023-03-24 16:57:00 -04:00
wxiaoguang 780f71c4ca
Fix incorrect `show-modal` and `show-panel` class (#23660) (#23663)
Backport #23660

That's incorrect code caused by Copy&Paste.

`show-modal` / `show-panel` are used by JS to show something, but these
links have `href`, they should navigate to new page.

Close #23657
2023-03-24 16:18:27 -04:00
Giteabot 484cb22f14
Fix incorrect package doc link (#23679) (#23689)
Backport #23679 by @yp05327

package doc link is changed in
https://github.com/go-gitea/gitea/pull/23629

Co-authored-by: yp05327 <576951401@qq.com>
2023-03-24 14:43:02 -04:00
wxiaoguang 2a70473af7
Backport locales to 1.19 (#23634)
Generated by #23633
2023-03-24 12:17:30 +08:00
Giteabot a28863bff7
Fix codeblocks in the cheat sheet (#23664) (#23669)
Backport #23664 by @SuperSandro2000

Conflicts fixed by Andrew Thornton <art27@cantab.net>

Co-authored-by: Sandro <sandro.jaeckel@gmail.com>
Co-authored-by: Andrew Thornton <art27@cantab.net>
2023-03-23 16:50:56 -04:00
Lunny Xiao 162f2841d0
Rename develop -> development, contribute -> contributing, administer -> administration (#23662)
backport #23629 

To make versioned documentation less surprising, 1.19 should have the
same technology.
2023-03-23 15:44:09 -05:00
Giteabot e7a5429d7a
Improve workflow event triggers (#23613) (#23648) 2023-03-23 16:34:05 +08:00
silverwind 622d21691c
Fix diff tree height and adjust target file style (#23616)
Extract from https://github.com/go-gitea/gitea/pull/23553, just the
parts that fix the diff tree height and the change to the file `:target`
style.

Fixes: https://github.com/go-gitea/gitea/issues/23593
2023-03-22 15:32:27 -05:00
wxiaoguang 774b37b9f8
Introduce path Clean/Join helper functions, partially backport&refactor (#23495) (#23607)
Backport #23495, partially backport&refactor

The `modules/options` files are just copied from 1.20 to 1.19
2023-03-22 19:56:20 +08:00
Giteabot 9dfdfe2389
Remove conflicting CSS rules on notifications, improve notifications table (#23565) (#23621)
Backport #23565 by @silverwind

Dropdowns on `/notifications/subscriptions` before and after:

<img width="157" alt="Screenshot 2023-03-18 at 20 37 12"
src="https://user-images.githubusercontent.com/115237/226133906-e4ad6a0a-de24-4324-8e1d-94081d23fe85.png">
<img width="152" alt="Screenshot 2023-03-18 at 20 41 29"
src="https://user-images.githubusercontent.com/115237/226134038-c3946c32-a424-4b92-ad15-890e1036cafe.png">

These selectors are meant to target the notification list which I
improved:

<img width="1145" alt="Screenshot 2023-03-19 at 01 52 11"
src="https://user-images.githubusercontent.com/115237/226147907-1c35736a-4bc9-4698-9813-21a20a1d2106.png">
<img width="1148" alt="Screenshot 2023-03-19 at 01 54 17"
src="https://user-images.githubusercontent.com/115237/226147920-626dbd84-11d3-48db-a177-6d808e3212c0.png">
2023-03-21 17:04:01 -04:00
Giteabot 4439a68911
Fix pagination on `/notifications/watching` (#23564) (#23603)
Backport #23564 by @silverwind

The `q` parameter was not rendered in pagination links because
`context.Pagination:AddParam` checks for existance of the parameter in
`ctx.Data` where it was absent. Added the parameter there to fix it.

Co-authored-by: silverwind <me@silverwind.io>
2023-03-21 16:10:47 -04:00
Giteabot 782c376c8b
fix submodule is nil panic (#23588) (#23601)
Backport #23588 by @viletyy

#23587  
submodule path is nil 
It is panic a nil error

Co-authored-by: 来自村里的小螃蟹 <yystopf@163.com>
2023-03-21 09:39:40 +08:00
Giteabot a3b917151c
Improve template error reporting (#23396) (#23600)
Backport #23396 by @zeripath

There are multiple duplicate reports of errors during template rendering
due to broken custom templates.

Unfortunately the error returned here is somewhat difficult for users to
understand and it doesn't return the context of the error.

This PR attempts to parse the error returned by the template renderer to
add in some further context including the filename of the template AND
the preceding lines within that template file.

Ref #23274

Signed-off-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: zeripath <art27@cantab.net>
2023-03-20 17:53:45 -04:00
wxiaoguang 0732ba32ee
Polyfill the window.customElements (#23592) (#23595)
Backport #23592

Close #23590

It seems that some browsers don't support customElements
2023-03-20 19:52:05 +01:00
Giteabot 726d6a5077
Add CHANGELOG for 1.19.0 (#23583) (#23586)
Backport #23583 by @delvh

Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: techknowlogick <matti@mdranta.net>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-20 16:34:28 +08:00
yp05327 b33cae7a3a
Fix backport #23336 (#23584) 2023-03-20 15:37:20 +08:00
wxiaoguang 854fcb1434
Fix dropdown icon misalignment when using fomantic icon (#23558) (#23577)
Backport #23558

There are still many dropdowns using fomantic icon. For example: new
issue with issue template.

Avoid polluting the fomantic styles.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-20 10:44:15 +08:00
Giteabot 4730ed18f1
Add `.patch` to `attachment.ALLOWED_TYPES` (#23580) (#23582)
Backport #23580 by @silverwind

Updated this default to GitHub's latest, adding the `.patch` file
extension to allowed types.

Co-authored-by: silverwind <me@silverwind.io>
2023-03-19 16:48:44 -04:00
Giteabot 937996c74c
Match api migration behavior to web behavior (#23552) (#23573)
Backport #23552 by @atomaka

When attempting to migrate a repository via the API endpoint comments
are always included. This can create a problem if your source repository
has issues or pull requests but you do not want to import them into
Gitea that displays as something like:

> Error 500: We were unable to perform the request due to server-side
problems. 'comment references non existent IssueIndex 4

There are only two ways to resolve this:
1. Migrate using the web interface
2. Migrate using the API including at issues or pull requests.

This PR matches the behavior of the API migration router to the web
migration router.

Co-authored-by: Andrew Tomaka <atomaka@atomaka.com>
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-19 15:30:02 +08:00
Giteabot 3f253b3f5a
Fix some broken css (#23560) (#23567)
Backport #23560 by @wxiaoguang

1. The "close" inside "modal" are likely broken for long time
    * There is no var called `--body-color`
    * There is no `fullscreen modal`
* The `.ui.modal > .close.inside` doesn't seem to match most icons. It
only matches a few like "fork-repo-modal" or "adopt repo". Other places
are just buggy code copied again and again.
2. Convert the legacy `&:hover` LESS syntax to CSS syntax

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: delvh <leon@kske.dev>
2023-03-18 21:37:16 -04:00
Giteabot f5a98b0f5b
Fix sticky header in diff view (#23554) (#23568)
Backport #23554 by @silverwind

Ressurection of #23549.

Fix regression
https://github.com/go-gitea/gitea/pull/23513#issuecomment-1474356817
from #23271.
The previous sticky CSS did assume the content is always 2 rows, but
since that PR, it's single-row above 993px width.
Adjust the sticky offset to match and add a small tweak that hides
content behind the `border-radius`.

Single row:
<img width="1264" alt="Screenshot 2023-03-17 at 21 33 05"
src="https://user-images.githubusercontent.com/115237/226034050-a04b131d-fd3f-45c0-bc72-413738a59825.png">

Double row:
<img width="1243" alt="Screenshot 2023-03-17 at 21 32 53"
src="https://user-images.githubusercontent.com/115237/226034163-2f1c6aa9-fc72-432f-bc46-9a7119da8677.png">

Co-authored-by: silverwind <me@silverwind.io>
2023-03-19 01:29:16 +01:00
Giteabot 1a97a84023
Fix JS error on compare page (#23551) (#23566)
Backport #23551 by @silverwind

Fix regression from https://github.com/go-gitea/gitea/pull/23271. This
code apparently runs on the compare page where there is no review button
so check for existance of both button and content.

<img width="1226" alt="Screenshot 2023-03-17 at 21 42 47"
src="https://user-images.githubusercontent.com/115237/226040001-ec097edd-d926-4c80-9962-526f9b7eff19.png">

Fixes #23562

Co-authored-by: silverwind <me@silverwind.io>
2023-03-18 16:48:13 -05:00
wxiaoguang 420d015b76
Fix `aria.js` bugs: incorrect role element problem, mobile focus problem, tippy problem (#23450) (#23486)
Before: the `aria.js` is still buggy in some cases.

After: tested with AppleVoice, Android TalkBack (I tested it with 1.19
again)

* Fix incorrect dropdown init code
* Fix incorrect role element (the menu role should be on the `$menu`
element, but not on the `$focusable`)
* Fix the focus-show-click-hide problem on mobile. Now the language menu
works as expected
* Fix incorrect dropdown template function setting
* Clarify the logic in aria.js
* Fix incorrect tippy `setProps` after `destroy`
* Improve comments
* Implement the layout proposed by #19861
2023-03-18 17:14:19 +01:00
Giteabot 22911a1ece
Imrove scroll behavior to hash issuecomment(scroll position, auto expand if file is folded, and on refreshing) (#23513) (#23540)
Backport #23513 by @HesterG

Close #23466
Right now on pull request "files Changed" tab, if a file is viewed, when
the comments' links are visited, the comment will not be shown as the
file is folded after viewed. This PR is to improve the behavior, to make
the comment seen even the related file is folded, like on github.

And right now scroll position will be remembered and hence it won’t
scroll to hashed comment after refreshing, this PR also adjust the
scroll position remembering behavior: When there is hash comment in url,
do not remember the scroll position.

Before:


https://user-images.githubusercontent.com/17645053/225512079-6cf79581-9346-44cf-95d6-06919642e6a8.mov


After:


https://user-images.githubusercontent.com/17645053/225523753-3f6728f2-977b-4ed0-a65c-63dcef2ace80.mov


Update - long comment's behavior after using `scrollTop ` (Comment div
scroll to the position which is 30px below the diff header, or 30px
below top on conversation tab):


https://user-images.githubusercontent.com/17645053/225614460-0602c1a6-229c-41f4-84d2-334e78251486.mov

Co-authored-by: Hester Gong <hestergong@gmail.com>
2023-03-17 22:59:18 -04:00
Giteabot 4b763d8d37
Fix diff detail buttons wrapping, use tippy for review box (#23271) (#23546)
Backport #23271 by @silverwind

Fix visual regression introduced by
https://github.com/go-gitea/gitea/pull/22986.

Before:
<img width="1277" alt="image"
src="https://user-images.githubusercontent.com/115237/222792814-d70c2173-0c7c-4db2-8839-95be63cdc8ee.png">
<img width="649" alt="image"
src="https://user-images.githubusercontent.com/115237/222792989-9b1f5e12-becd-40cc-b02c-e9f59a8e72a4.png">

After: 
<img width="1274" alt="image"
src="https://user-images.githubusercontent.com/115237/222792769-e7a9702f-4b6a-46c4-9385-da103ed4dff0.png">
<img width="565" alt="image"
src="https://user-images.githubusercontent.com/115237/222793084-6de6482b-11dc-4d38-b514-15884d20e140.png">

Co-authored-by: silverwind <me@silverwind.io>
2023-03-17 14:52:04 -04:00
wxiaoguang 1254fc668a
Fix review comment context menu clipped bug (#23523) (#23543)
Backport #23523, Close #23517

There is no "dropdown menu" for image/csv view, so we could only add the
"overflow-x: scroll" to the image/csv view.

Co-authored-by: KN4CK3R <admin@oldschoolhack.me>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2023-03-17 14:00:17 -04:00
wxiaoguang 09824025f7
Refactor merge/update git command calls (#23366) (#23544)
Backport #23366

* Remove unnecessary ToTrustedCmdArgs calls
* The `signArg` couldn't be empty, it's either `-S{keyID}` or
`--no-gpg-sign`.
2023-03-17 12:16:22 -04:00
Giteabot bd1a915bdb
Use octicon-verified for gpg signatures (#23529) (#23536)
Backport #23529 by @silverwind

Before:
<img width="292" alt="Screenshot 2023-03-16 at 23 40 47"
src="https://user-images.githubusercontent.com/115237/225768871-43e11ced-e340-4c88-b756-25f9f7076fd2.png">
<img width="288" alt="Screenshot 2023-03-16 at 23 51 05"
src="https://user-images.githubusercontent.com/115237/225770071-b51f3ed6-ef14-421b-a5bc-6a26e808d404.png">


After:
<img width="291" alt="Screenshot 2023-03-16 at 23 40 37"
src="https://user-images.githubusercontent.com/115237/225768864-ea4956c7-8c57-4148-9d89-c818991a7538.png">
<img width="281" alt="image"
src="https://user-images.githubusercontent.com/115237/225769978-0b9c6c52-9a13-4c23-b13e-8a8a692abf43.png">

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: KN4CK3R <admin@oldschoolhack.me>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-17 11:39:31 -04:00
Giteabot cab7044772
Increase horizontal page padding (#23507) (#23537)
Backport #23507 by @silverwind

Add a bit more empty space on left and right side of page content for a
more pleasant viewing experience. Also tweaked the mobile navbar to
match.

Before:
<img width="1276" alt="Screenshot 2023-03-16 at 00 58 23"
src="https://user-images.githubusercontent.com/115237/225473942-f544106f-1b61-456a-99fb-3ba136cabc8d.png">

After:
<img width="1270" alt="Screenshot 2023-03-16 at 00 58 37"
src="https://user-images.githubusercontent.com/115237/225473959-8b555359-a08d-48e1-9476-2710aabb1166.png">

Mobile Navbar:
<img width="673" alt="Screenshot 2023-03-16 at 01 05 12"
src="https://user-images.githubusercontent.com/115237/225473966-adccef2b-4d34-44ed-8c75-d4ca46d96cf3.png">

Co-authored-by: silverwind <me@silverwind.io>
2023-03-17 21:01:47 +08:00
Giteabot 68c9f1abd8
Use `<nav>` instead of `<div>` in the global navbar (#23125) (#23533)
Backport #23125 by @delvh

Furthermore improved/deleted some comments in the template.
The appearance did not change.

Co-authored-by: delvh <leon@kske.dev>
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-17 01:28:17 -04:00
Zettat123 301de3ab6b
Handle missing `README` in create repos API (#23387) (#23510)
Backport #23387 
Close #22934

In `/user/repos` API (and other APIs related to creating repos), user
can specify a readme template for auto init. At present, if the
specified template does not exist, a `500` will be returned . This PR
improved the logic and will return a `400` instead of `500`.

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2023-03-16 21:04:52 -04:00
silverwind 8f8bd3c0cb
Replace Less with CSS (#23508)
Backport https://github.com/go-gitea/gitea/pull/23481,
https://github.com/go-gitea/gitea/pull/23504 and
https://github.com/go-gitea/gitea/pull/23520 to 1.19, just so we have an
easier time with future backports.

Seems to work on a basic level. There was a merge conflict in
`RepoActionView.vue`, otherwise it merged cleanly.

---------

Co-authored-by: John Olheiser <john.olheiser@gmail.com>
Co-authored-by: Lauris BH <lauris@nix.lv>
2023-03-16 21:04:39 -04:00
Giteabot 23a6fa9421
Make time tooltips interactive (#23526) (#23527)
Backport #23526 by @silverwind

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

<img width="379" alt="Screenshot 2023-03-16 at 20 23 10"
src="https://user-images.githubusercontent.com/115237/225731294-4c6e4f44-bdcc-4c8c-86e2-49f7c03b377d.png">

Co-authored-by: silverwind <me@silverwind.io>
2023-03-16 16:23:11 -05:00
Jason Song b7c2f48ebf
Update act (#23512) (#23518)
Backport #23512.

Update replace:
```diff
- replace github.com/nektos/act => gitea.com/gitea/act v0.234.2-0.20230131074955-e46ede1b1744
+ replace github.com/nektos/act => gitea.com/gitea/act v0.243.1
```

Update require:
```diff
-	github.com/nektos/act v0.0.0
+	github.com/nektos/act v0.2.43
```

Actually, `v0.2.43` doesn't work, it will be replaced by `gitea/act`, so
it's OK to put any version here. But `gitea/act` is based on
`nektos/act`, so keeping the right upstream version will make security
dependabot help.

BTW, the [security
report](https://github.com/go-gitea/gitea/security/dependabot/20) is
false positive, we don't use the artifact server in act, see #22738.
2023-03-16 09:33:11 -05:00
Giteabot 70e31b4aa0
Update path to docs theme file (#23502) (#23505)
Backport #23502 by @techknowlogick

The branch name for the theme was updated to main

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2023-03-15 16:04:27 -05:00
Giteabot d73846f0b4
Disable sending email after push a commit to a closed PR (#23462) (#23492)
Backport #23462 by @sillyguodong

Close #23440
Cause by #23189
In #23189, we should insert a comment record into db when pushing a
commit to the PR, even if the PR is closed.
But should skip sending any notification in this case.

Co-authored-by: sillyguodong <33891828+sillyguodong@users.noreply.github.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: KN4CK3R <admin@oldschoolhack.me>
2023-03-15 11:20:51 +01:00
Giteabot 527bbf67e8
Fix 'View File' button in code search (#23478) (#23483)
Backport #23478 by @silverwind

- Right-align 'View File' button
- Add 'role' attribute to button link

Before:
<img width="1148" alt="Screenshot 2023-03-14 at 22 02 16"
src="https://user-images.githubusercontent.com/115237/225135954-f06153ec-c222-441e-98ba-0177afff3a7a.png">

After:
<img width="1150" alt="Screenshot 2023-03-14 at 22 02 33"
src="https://user-images.githubusercontent.com/115237/225135966-323cb695-05ef-4b83-a8ef-05f2b1887090.png">

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: KN4CK3R <admin@oldschoolhack.me>
2023-03-15 10:34:05 +01:00
Giteabot 5feb31f219
Bump webpack from 5.75.0 to 5.76.0 (#23484) (#23487)
Backport #23484 by @dependabot[bot]

Bumps [webpack](https://github.com/webpack/webpack) from 5.75.0 to
5.76.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/webpack/webpack/releases">webpack's
releases</a>.</em></p>
<blockquote>
<h2>v5.76.0</h2>
<h2>Bugfixes</h2>
<ul>
<li>Avoid cross-realm object access by <a
href="https://github.com/Jack-Works"><code>@​Jack-Works</code></a> in <a
href="https://redirect.github.com/webpack/webpack/pull/16500">webpack/webpack#16500</a></li>
<li>Improve hash performance via conditional initialization by <a
href="https://github.com/lvivski"><code>@​lvivski</code></a> in <a
href="https://redirect.github.com/webpack/webpack/pull/16491">webpack/webpack#16491</a></li>
<li>Serialize <code>generatedCode</code> info to fix bug in asset module
cache restoration by <a
href="https://github.com/ryanwilsonperkin"><code>@​ryanwilsonperkin</code></a>
in <a
href="https://redirect.github.com/webpack/webpack/pull/16703">webpack/webpack#16703</a></li>
<li>Improve performance of <code>hashRegExp</code> lookup by <a
href="https://github.com/ryanwilsonperkin"><code>@​ryanwilsonperkin</code></a>
in <a
href="https://redirect.github.com/webpack/webpack/pull/16759">webpack/webpack#16759</a></li>
</ul>
<h2>Features</h2>
<ul>
<li>add <code>target</code> to <code>LoaderContext</code> type by <a
href="https://github.com/askoufis"><code>@​askoufis</code></a> in <a
href="https://redirect.github.com/webpack/webpack/pull/16781">webpack/webpack#16781</a></li>
</ul>
<h2>Security</h2>
<ul>
<li><a
href="https://github.com/advisories/GHSA-3rfm-jhwj-7488">CVE-2022-37603</a>
fixed by <a
href="https://github.com/akhilgkrishnan"><code>@​akhilgkrishnan</code></a>
in <a
href="https://redirect.github.com/webpack/webpack/pull/16446">webpack/webpack#16446</a></li>
</ul>
<h2>Repo Changes</h2>
<ul>
<li>Fix HTML5 logo in README by <a
href="https://github.com/jakebailey"><code>@​jakebailey</code></a> in <a
href="https://redirect.github.com/webpack/webpack/pull/16614">webpack/webpack#16614</a></li>
<li>Replace TypeScript logo in README by <a
href="https://github.com/jakebailey"><code>@​jakebailey</code></a> in <a
href="https://redirect.github.com/webpack/webpack/pull/16613">webpack/webpack#16613</a></li>
<li>Update actions/cache dependencies by <a
href="https://github.com/piwysocki"><code>@​piwysocki</code></a> in <a
href="https://redirect.github.com/webpack/webpack/pull/16493">webpack/webpack#16493</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/Jack-Works"><code>@​Jack-Works</code></a> made
their first contribution in <a
href="https://redirect.github.com/webpack/webpack/pull/16500">webpack/webpack#16500</a></li>
<li><a href="https://github.com/lvivski"><code>@​lvivski</code></a> made
their first contribution in <a
href="https://redirect.github.com/webpack/webpack/pull/16491">webpack/webpack#16491</a></li>
<li><a
href="https://github.com/jakebailey"><code>@​jakebailey</code></a> made
their first contribution in <a
href="https://redirect.github.com/webpack/webpack/pull/16614">webpack/webpack#16614</a></li>
<li><a
href="https://github.com/akhilgkrishnan"><code>@​akhilgkrishnan</code></a>
made their first contribution in <a
href="https://redirect.github.com/webpack/webpack/pull/16446">webpack/webpack#16446</a></li>
<li><a
href="https://github.com/ryanwilsonperkin"><code>@​ryanwilsonperkin</code></a>
made their first contribution in <a
href="https://redirect.github.com/webpack/webpack/pull/16703">webpack/webpack#16703</a></li>
<li><a href="https://github.com/piwysocki"><code>@​piwysocki</code></a>
made their first contribution in <a
href="https://redirect.github.com/webpack/webpack/pull/16493">webpack/webpack#16493</a></li>
<li><a href="https://github.com/askoufis"><code>@​askoufis</code></a>
made their first contribution in <a
href="https://redirect.github.com/webpack/webpack/pull/16781">webpack/webpack#16781</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/webpack/webpack/compare/v5.75.0...v5.76.0">https://github.com/webpack/webpack/compare/v5.75.0...v5.76.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="97b1718720"><code>97b1718</code></a>
Merge pull request <a
href="https://redirect.github.com/webpack/webpack/issues/16781">#16781</a>
from askoufis/loader-context-target-type</li>
<li><a
href="b84efe6224"><code>b84efe6</code></a>
Merge pull request <a
href="https://redirect.github.com/webpack/webpack/issues/16759">#16759</a>
from ryanwilsonperkin/real-content-hash-regex-perf</li>
<li><a
href="c98e9e0014"><code>c98e9e0</code></a>
Merge pull request <a
href="https://redirect.github.com/webpack/webpack/issues/16493">#16493</a>
from piwysocki/patch-1</li>
<li><a
href="5f34acfbc0"><code>5f34acf</code></a>
feat: Add <code>target</code> to <code>LoaderContext</code> type</li>
<li><a
href="b7fc4d876d"><code>b7fc4d8</code></a>
Merge pull request <a
href="https://redirect.github.com/webpack/webpack/issues/16703">#16703</a>
from ryanwilsonperkin/ryanwilsonperkin/fix-16160</li>
<li><a
href="63ea82da4d"><code>63ea82d</code></a>
Merge branch 'webpack:main' into patch-1</li>
<li><a
href="4ba225225b"><code>4ba2252</code></a>
Merge pull request <a
href="https://redirect.github.com/webpack/webpack/issues/16446">#16446</a>
from akhilgkrishnan/patch-1</li>
<li><a
href="1acd6350be"><code>1acd635</code></a>
Merge pull request <a
href="https://redirect.github.com/webpack/webpack/issues/16613">#16613</a>
from jakebailey/ts-logo</li>
<li><a
href="302eb37fe1"><code>302eb37</code></a>
Merge pull request <a
href="https://redirect.github.com/webpack/webpack/issues/16614">#16614</a>
from jakebailey/html5-logo</li>
<li><a
href="cfdb1dfe59"><code>cfdb1df</code></a>
Improve performance of hashRegExp lookup</li>
<li>Additional commits viewable in <a
href="https://github.com/webpack/webpack/compare/v5.75.0...v5.76.0">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~evilebottnawi">evilebottnawi</a>, a new
releaser for webpack since your current version.</p>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=webpack&package-manager=npm_and_yarn&previous-version=5.75.0&new-version=5.76.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
- `@dependabot use these labels` will set the current labels as the
default for future PRs for this repo and language
- `@dependabot use these reviewers` will set the current reviewers as
the default for future PRs for this repo and language
- `@dependabot use these assignees` will set the current assignees as
the default for future PRs for this repo and language
- `@dependabot use this milestone` will set the current milestone as the
default for future PRs for this repo and language

You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/go-gitea/gitea/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-15 14:21:59 +08:00
Giteabot 31efbafbe3
Convert GitHub event on actions and fix some pull_request events. (#23037) (#23471)
Backport #23037 by @lunny

Follow #22680

Partially Fix #22958, on pull_request, `opened`, `reopened`,
`synchronize` supported, `edited` hasn't been supported yet because
Gitea doesn't trigger that events.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: yp05327 <576951401@qq.com>
2023-03-15 10:43:10 +08:00
Giteabot 28af02eea0
Fix due date being wrong on issue list (#23475) (#23477)
Backport #23475 by @yardenshoham

Exactly like #22302 but in the issue list page

Co-authored-by: Yarden Shoham <hrsi88@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-15 09:40:43 +08:00
Giteabot c698a6fc5d
Scoped label display and documentation tweaks (#23430) (#23433)
Backport #23430 by @brechtvl

* Fix scoped label left and right part breaking across lines.
* Remove slanted divider in scoped label display, make it straight.
After using this for a while, this feels more visually noisy than
helpful.
* Reduce contrast between scope and item to reduce probability of
unreadable text on background.
* Change documentation to remove mention of non-exclusive scoped labels.

Co-authored-by: Brecht Van Lommel <brecht@blender.org>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: John Olheiser <john.olheiser@gmail.com>
2023-03-15 07:58:38 +08:00
Giteabot e5a51eca45
Remove wrongly added column on migration test fixtures (#23456) (#23470)
Backport #23456 by @lunny

Fix https://drone.gitea.io/go-gitea/gitea/69418/3/8
Migration fixtures are in `models/migrations/fixtures`, every folder
will be used only by the test with the same name.
For `Test_DeleteOrphanedIssueLabels`, the fixture should keep consistent
as the database structure at that time. So the newly added `exclusive`
is not right. Just revert the change in
https://github.com/go-gitea/gitea/pull/22585/files#diff-f8db9cbbaa10bf7b27eb726884454db821a4b4f8cb9a0d50435555908761bbcb

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2023-03-14 16:09:52 -04:00
Giteabot 8536dc4b73
Make branches list page operations remember current page (#23420) (#23460)
Backport #23420 by @wxiaoguang

Close #23411

Always pass "page" query parameter to backend, and make backend respect
it.

The `ctx.FormInt("limit")` is never used, so removed.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Jason Song <i@wolfogre.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-14 20:51:14 +08:00
techknowlogick 0a0f46f299 test_env: hardcode major go version in use (#23464) 2023-03-14 04:12:14 -04:00
Giteabot 1543ac9c8d
Fix missing commit status in PR which from forked repo (#23351) (#23453)
Backport #23351 by @sillyguodong

close: #23347

### Reference and Inference
According to Github REST API
[doc](https://docs.github.com/en/rest/commits/statuses?apiVersion=2022-11-28#list-commit-statuses-for-a-reference):
1. The `Drone CI` that can create some commit status by
[API](https://docs.github.com/en/rest/commits/statuses?apiVersion=2022-11-28#create-a-commit-status)
is enabled in `go-gitea/gitea`. So I tried to call the API to get a
commit status list of a PR which is commited to upstream
repo(`go-gitea/gitea`). As a result, the API returned a array of commit
status.

![image](https://user-images.githubusercontent.com/33891828/223913371-313d047a-5e2e-484c-b13e-dcd38748703e.png)
2. Then I tried to call the API to get commit status list of the
reference which of the `SHA` is the same as step 1 in the repo which is
forked from `go-gitea/gitea`. But I got a empty array.

![image](https://user-images.githubusercontent.com/33891828/223930827-17a64d3c-f466-4980-897c-77fe386c4d3b.png)

So, I believe it that:
1. The commit status is not shared between upstream repo and forked
repo.
2. The coomit status is bound to a repo that performs actions. (Gitea's
logic is the same)

### Cause
During debugging, I found it that commit status are not stored in the DB
as expected.
So, I located the following code:

8cadd51bf2/services/actions/commit_status.go (L18-L26)
When I create a PR, the type of `event` is `pull request`, not `push`.
So the code return function directly.

### Screenshot

![image](https://user-images.githubusercontent.com/33891828/223939339-dadf539c-1fdd-40c4-96e9-2e4fa733f531.png)

![image](https://user-images.githubusercontent.com/33891828/223939519-edb02bf0-2478-4ea5-9366-be85468f02db.png)

![image](https://user-images.githubusercontent.com/33891828/223939557-ec6f1375-5536-400e-8987-fb7d2fd452fa.png)

### Other 
In this PR, I also fix the problem of missing icon which represents
running in PRs list.

![image](https://user-images.githubusercontent.com/33891828/223939898-2a0339e4-713f-4c7b-9d99-2250a43f3457.png)

![image](https://user-images.githubusercontent.com/33891828/223939979-037a975f-5ced-480c-bac7-0ee00ebfff4b.png)

Co-authored-by: sillyguodong <33891828+sillyguodong@users.noreply.github.com>
2023-03-14 08:11:31 +08:00
Giteabot c3c0710412
Purge API comment (#23451) (#23452)
Backport #23451 by @jolheiser

This PR just adds the `purge` query parameter to the swagger docs for
admin user delete.

I considered using the same verbiage we have in the UI, but that seemed
more verbose than descriptions we use elsewhere in swagger. I'm fine if
that's preferred, though, just let me know. 🙂

Signed-off-by: jolheiser <john.olheiser@gmail.com>
Co-authored-by: John Olheiser <john.olheiser@gmail.com>
2023-03-13 15:46:18 -05:00
Giteabot fa33919e24
Support reflogs (#22451) (#23438)
Backport #22451 by @philip-peterson

This PR adds support for reflogs on all repositories. It does this by
adding a global configuration entry.

Implements #14865

Signed-off-by: Philip Peterson <philip.c.peterson@gmail.com>
Co-authored-by: Philip Peterson <philip-peterson@users.noreply.github.com>
2023-03-13 12:20:10 +00:00
Giteabot b1162495af
Fix actions frontend bugs (pagination, long name alignment) and small simplify (#23370) (#23436)
Backport #23370 by @HesterG

1 Right now on actions page, the action list will not be aligned if
commit message is long. In this PR, the changes are:
- The branch tag is moved to bottom row
- Width percentage is given to make them aligned
- Show "..." if commit is longer than two lines.
- Align the status icon with the commit message with baseline

 Before:
<img width="1068" alt="截屏2023-03-08 12 23 22"
src="https://user-images.githubusercontent.com/17645053/223628534-6b9472cb-29f5-40a3-9714-c5152553049e.png">
  
 After:
<img width="756" alt="截屏2023-03-08 13 34 28"
src="https://user-images.githubusercontent.com/17645053/223628571-da94698b-0e0a-43e3-ae82-34d8c780e5ba.png">


2 Right now the actions list's pagination is not working properly
because Param is not passed to pagination template, in this PR Param
Strings are passed to the pager

Before:
<img width="1176" alt="截屏2023-03-08 12 23 50"
src="https://user-images.githubusercontent.com/17645053/223629207-8b67ce74-2342-4259-bc81-036e37752716.png">

After:
<img width="1343" alt="截屏2023-03-08 13 11 54"
src="https://user-images.githubusercontent.com/17645053/223629321-4f538f8a-45dc-4d6f-ae60-2c82680ae3e7.png">

3 A small simplify in `RepoActionView.vue` .

Co-authored-by: Hester Gong <hestergong@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-13 09:09:00 +02:00
Giteabot 41655ee878
Show edit/close/delete button on organization wide repositories (#23388) (#23429)
Backport #23388 by @yp05327

A part of https://github.com/go-gitea/gitea/pull/22865

Co-authored-by: yp05327 <576951401@qq.com>
2023-03-12 15:17:25 +01:00
Giteabot 0d9b44c0e3
Preserve file size when creating attachments (#23406) (#23426)
Backport #23406 by @baez90

When creating attachments (issue, release, repo) the file size (being
part of the multipart file header) is passed through the chain of
creating an attachment to ensure the MinIO client can stream the file
directly instead of having to read it to memory completely at first.

Fixes #23393

Co-authored-by: Peter <peter.kurfer@googlemail.com>
Co-authored-by: KN4CK3R <admin@oldschoolhack.me>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2023-03-12 12:45:39 +01:00
Giteabot e87f36e885
Use buildkit for docker builds (#23415) (#23424) 2023-03-11 17:11:23 -05:00
Giteabot b301cb17a3
Fix and move "Use this template" button (#23398) (#23408)
Backport #23398

Before:
<img width="1157" alt="Screenshot 2023-03-09 at 23 21 25"
src="https://user-images.githubusercontent.com/115237/224174168-869966cc-fa59-4231-b449-23bd9db12862.png">

After:
<img width="1145" alt="Screenshot 2023-03-09 at 23 24 34"
src="https://user-images.githubusercontent.com/115237/224174173-7f5b9c22-44c4-4eed-990c-da49d749eb0e.png">

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2023-03-11 01:41:04 +08:00
Giteabot e259daeff8
Add missing tabs to org projects page (#22705) (#23412)
Backport #22705 by @yp05327

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

Context Data `IsOrganizationMember` and `IsOrganizationOwner` is used to
control the visibility of `people` and `team` tab.

2871ea0809/templates/org/menu.tmpl (L19-L40)

And because of the reuse of user projects page, User Context is changed
to Organization Context. But the value of `IsOrganizationMember` and
`IsOrganizationOwner` are not being given.

I reused func `HandleOrgAssignment` to add them to the ctx, but may have
some unnecessary variables, idk whether it is ok.

I found there is a missing `PageIsViewProjects` at create project page.

Co-authored-by: yp05327 <576951401@qq.com>
2023-03-10 10:08:28 -06:00
Giteabot edb618c136
Handle OpenID discovery URL errors a little nicer when creating/editing sources (#23397) (#23403)
Backport #23397

When there is an error creating a new openIDConnect authentication
source try to handle the error a little better.

Close #23283

Signed-off-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: zeripath <art27@cantab.net>
2023-03-10 08:29:28 -06:00
Giteabot 43cf04c031
Fix broken Chroma CSS styles (#23174) (#23402)
Backport #23174

The CSS styles in Gitea themes are out-of-sync of Chroma's styles.

This PR introduces a `chroma-style-diff.go` tool to compare the diff.
The missing CSS styles have been added manually. They are left as empty
to reduce arguments because there was no color for them before.

And this PR fixes #22348, with just 2 lines changed: `.chroma .kt & .n`,
these colors are taken from GitHub.

It's good enough for #22348


![image](https://user-images.githubusercontent.com/2114189/221551941-0d27d11d-e71e-498f-8e88-92b558fe4a18.png)

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2023-03-10 19:45:07 +08:00
Giteabot e9991b1f06
Refactor and tidy-up the merge/update branch code (#22568) (#23365)
Backport #22568

The merge and update branch code was previously a little tangled and had
some very long functions. The functions were not very clear in their
reasoning and there were deficiencies in their logging and at least one
bug in the handling of LFS for update by rebase.

This PR substantially refactors this code and splits things out to into
separate functions. It also attempts to tidy up the calls by wrapping
things in "context"s. There are also attempts to improve logging when
there are errors.

Signed-off-by: Andrew Thornton <art27@cantab.net>

Signed-off-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: zeripath <art27@cantab.net>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Co-authored-by: delvh <dev.lh@web.de>
2023-03-09 22:15:39 -05:00
Giteabot 975785dd42
Rename `canWriteUnit` to `canWriteProjects` (#23386) (#23399)
Backport #23386

A part of https://github.com/go-gitea/gitea/pull/22865

Co-authored-by: yp05327 <576951401@qq.com>
2023-03-09 21:21:12 -05:00
Giteabot e269e8901f
Fix incorrect NotFound conditions in org/projects.go (#23384) (#23395)
Backport #23384

A part of https://github.com/go-gitea/gitea/pull/22865

user/org project's `RepoID` is always 0, we need to check `OwnerID`

Co-authored-by: yp05327 <576951401@qq.com>
2023-03-09 13:56:31 -06:00
Giteabot 87c31c2ffe
Set `X-Gitea-Debug` header once (#23361) (#23381) 2023-03-09 06:33:05 +08:00
Giteabot 54c674c936
Fix panic when getting notes by ref (#23372) (#23377)
Backport #23372

Fix #23357 .

Now the `/repos/{owner}/{repo}/git/notes/{sha}` API supports getting
notes by a ref or sha
(https://try.gitea.io/api/swagger#/repository/repoGetNote). But the
`GetNote` func can only accept commit ID.

a12f575737/modules/git/notes_nogogit.go (L18)

So we need to convert the query parameter to commit ID before calling
`GetNote`.

Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2023-03-08 15:17:31 -05:00
delvh 2ba58fab22
Pass context to avatar for projects view (#23359) (#23378)
Backport of #23359.

Previously, a 500 response was returned when

- an issue had assignees
- the issue was assigned to a project
- you tried to view this project
2023-03-08 11:57:09 -06:00
wxiaoguang cd7bd8568c
Fix incorrect display for comment context menu (#23343) (#23344)
Backport #23343

Fix a regression of #23014: the `a` couldn't be used here because
Fomantic UI has style conflicts: `.ui.comments .comment .actions a {
display: inline-block; }`

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-08 23:18:53 +08:00
Giteabot cf80f829b4
Do not recognize text files as audio (#23355) (#23368)
Backport #23355

Close #17108

This PR uses a trick (removing the ID3 tag) to detect the content again
to to see whether the content is text type.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-08 16:03:05 +08:00
Giteabot ed25e094ab
Fix adding of empty class name (#23352) (#23360)
Backport #23352

This PR is to fix the error shown below. The reason is because
[`class-name`
prop](https://github.com/go-gitea/gitea/blob/main/web_src/js/components/ActionRunStatus.vue#L6)
given to `svg` component has a space, and classList cannot add empty
string.



https://user-images.githubusercontent.com/17645053/223346720-c7f9de43-5e69-4ecf-93c0-90bf04090693.mov

Co-authored-by: Hester Gong <hestergong@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-07 17:15:19 -05:00
Giteabot 10df304b2f
Fix various ImageDiff/SVG bugs (#23312) (#23358)
Backport #23312

Replace #23310, Close #19733

And fix various UI problems, including regressions from #22959 #22950
and more.


## SVG Detection

The old regexp may mismatch non-SVG files. This PR adds new tests for
those cases.

## UI Changes

### Before


![image](https://user-images.githubusercontent.com/2114189/222967716-f6ad8721-f46a-4a3f-9eb0-a89e488d3436.png)


![image](https://user-images.githubusercontent.com/2114189/222967780-8af8981a-e69d-4304-9dc4-0235582fa4f4.png)


### After


![image](https://user-images.githubusercontent.com/2114189/222967575-c21c23d4-0200-4e09-aac3-57895e853000.png)


![image](https://user-images.githubusercontent.com/2114189/222967585-8b8da262-bc96-441a-9851-8d3845f2659d.png)


![image](https://user-images.githubusercontent.com/2114189/222967595-58d9bea5-6df4-41fa-bf8a-86704117959d.png)


![image](https://user-images.githubusercontent.com/2114189/222967608-38757c1a-b8bd-4ebf-b7a8-3b30edb7f303.png)


![image](https://user-images.githubusercontent.com/2114189/222967623-9849a339-6fae-4484-8fa5-939e2fdacbf5.png)


![image](https://user-images.githubusercontent.com/2114189/222967633-4383d7dd-62ba-47a3-8c10-86f7ca7757ae.png)

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-07 15:38:13 +02:00
Giteabot ecae62837c
Refactor `setting.Database.UseXXX` to methods (#23354) (#23356)
Backport #23354

Replace #23350.

Refactor `setting.Database.UseMySQL` to
`setting.Database.Type.IsMySQL()`.

To avoid mismatching between `Type` and `UseXXX`.

This refactor can fix the bug mentioned in #23350, so it should be
backported.

Co-authored-by: Jason Song <i@wolfogre.com>
2023-03-07 20:11:44 +08:00
sillyguodong e8e871b44e
Fix cannot reopen after pushing commits to a closed PR (#23189) (#23324)
Backport: #23189 
Close: #22784

1. On GH, we can reopen a PR which was closed before after pushing
commits. After reopening PR, we can see the commits that were pushed
after closing PR in the time line. So the case of
[issue](https://github.com/go-gitea/gitea/issues/22784) is a bug which
needs to be fixed.

2. After closing a PR and pushing commits, `headBranchSha` is not equal
to `sha`(which is the last commit ID string of reference). If the
judgement exists, the button of reopen will not display. So, skip the
judgement if the status of PR is closed.

![image](https://user-images.githubusercontent.com/33891828/222037529-651fccf9-0bba-433e-b2f0-79c17e0cc812.png)

3. Even if PR is already close, we should still insert comment record
into DB when we push commits.
So we should still call  function `CreatePushPullComment()`.

067b0c2664/services/pull/pull.go (L260-L282)
So, I add a switch(`includeClosed`) to the
`GetUnmergedPullRequestsByHeadInfo` func to control whether the status
of PR must be open. In this case, by setting `includeClosed` to `true`,
we can query the closed PR.

![image](https://user-images.githubusercontent.com/33891828/222621045-bb80987c-10c5-4eac-aa0c-1fb9c6aefb51.png)

4. In the loop of comments, I use the`latestCloseCommentID` variable to
record the last occurrence of the close comment.
In the go template, if the status of PR is closed, the comments whose
type is `CommentTypePullRequestPush(29)` after `latestCloseCommentID`
won't be rendered.


![image](https://user-images.githubusercontent.com/33891828/222058913-c91cf3e3-819b-40c5-8015-654b31eeccff.png)
e.g.
1). The initial status of the PR is opened.


![image](https://user-images.githubusercontent.com/33891828/222453617-33c5093e-f712-4cd6-8489-9f87e2075869.png)
2). Then I click the button of `Close`. PR is closed now.


![image](https://user-images.githubusercontent.com/33891828/222453694-25c588a9-c121-4897-9ae5-0b13cf33d20b.png)
3). I try to push a commit to this PR, even though its current status is
closed.


![image](https://user-images.githubusercontent.com/33891828/222453916-361678fb-7321-410d-9e37-5a26e8095638.png)
But in comments list, this commit do not display.This is as expected :)


![image](https://user-images.githubusercontent.com/33891828/222454169-7617a791-78d2-404e-be5e-77d555f93313.png)
4). Click the `Reopen` button, the commit which is pushed after closing
PR display now.


![image](https://user-images.githubusercontent.com/33891828/222454533-897893b6-b96e-4701-b5cb-b1800f382b8f.png)

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-07 18:47:23 +08:00
Giteabot 6be6c19daf
Fix PR view misalignment caused by long name file (#23321) (#23335)
Backport #23321

Close #23248

The UI after this PR:

https://user-images.githubusercontent.com/17645053/223009758-7f0c9f12-d346-4cb2-a605-729fddce732f.mov

Co-authored-by: Hester Gong <hestergong@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-07 11:11:55 +08:00
Giteabot 61f91bdc7e
Update documentation for the new YAML label file format (#23020) (#23341)
Backport #23020

update documentation to include an overview of the yaml label template
that is part of PR #22976

Signed-off-by: Jon Roadley-Battin <jon.roadleybattin@gmail.com>

Co-authored-by: JonRB <4564448+eeyrjmr@users.noreply.github.com>
Co-authored-by: Yarden Shoham <hrsi88@gmail.com>
Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: John Olheiser <john.olheiser@gmail.com>
Co-authored-by: delvh <dev.lh@web.de>
2023-03-06 17:52:29 -06:00
Giteabot 8ab50be000
Remove unnecessary space on link (#23334) (#23340)
Backport #23334

The action run title has a blank. This PR removes it.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2023-03-06 16:35:51 -05:00
Giteabot dfab6e2d1c
Fix incorrect redirect link of delete org project (#23327) (#23339)
Backport #23327

A part of https://github.com/go-gitea/gitea/pull/22865/commits

The old code will cause 500 error.

Co-authored-by: yp05327 <576951401@qq.com>
Co-authored-by: John Olheiser <john.olheiser@gmail.com>
2023-03-06 16:05:42 -05:00
Giteabot 2f7bbdf8c9
Fix incorrect project links and use symlink icon for org-wide projects (#23325) (#23336)
Backport #23325

Fix displaying same projects icons between user/repo projects.
And fix incorrect projects links.
A part of https://github.com/go-gitea/gitea/pull/22865.


![image](https://user-images.githubusercontent.com/18380374/223044279-7b620ff1-d88a-4146-97e6-531bbf269761.png)

![image](https://user-images.githubusercontent.com/18380374/223044390-42911e3f-1f6b-439f-8441-4f3ebf99ea13.png)

![image](https://user-images.githubusercontent.com/18380374/223044437-5cad5391-0f95-4c8b-b0a3-32e263e2854f.png)

Co-authored-by: yp05327 <576951401@qq.com>
2023-03-06 13:48:04 -06:00
Giteabot af4767df5c
Scoped labels: don't require holding alt key to remove (#23303) (#23331)
Backport #23303

Alt doesn't work on all browsers, the simplest solution for v1.19 is to
just not require it and toggle the label by just clicking.

Part of #22974

Co-authored-by: Brecht Van Lommel <brecht@blender.org>
2023-03-06 12:59:53 -06:00
Giteabot 233a399706
Fix broken code editor diff preview (#23307) (#23320)
Backport #23307

Close #23265, the code editor diff preview has been broken for long
time.

* Fix the regression for `data-line-num`
    * `.code-diff` is necessary to show the line number
* Fix the regression for #12434
* The diff:
[12434](https://github.com/go-gitea/gitea/pull/12434/files?diff=unified&w=1)
    * It hides the Type(4) (aka HunkHeader)  for unexpected cases.


Diff with ignoring whitespaces:
https://github.com/go-gitea/gitea/pull/23307/files?diff=unified&w=1

Before: see the issue #23265

After:


![image](https://user-images.githubusercontent.com/2114189/222942810-286dc9af-0b39-4e9d-8585-8c299b881241.png)

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-03-06 12:05:35 -06:00
Giteabot dcf1717793
Add context when rendering labels or emojis (#23281) (#23319)
Backport #23281

This branch continues the work of #23092 and attempts to rid the
codebase of any `nil` contexts when using a `RenderContext`.

Anything that renders markdown or does post processing may call
`markup.sha1CurrentPatternProcessor()`, and this runs
`git.OpenRepository()`, which needs a context. It will panic if the
context is `nil`. This branch attempts to _always_ include a context
when creating a `RenderContext` to prevent future crashes.

Co-authored-by: Jonathan Tran <jon@allspice.io>
2023-03-06 10:32:40 -06:00
Giteabot b1e68f39e7
Properly flush unique queues on startup (#23154) (#23201)
Backport #23154

There have been a number of reports of PRs being blocked whilst being
checked which have been difficult to debug. In investigating #23050 I
have realised that whilst the Warn there is somewhat of a miscall there
was a real bug in the way that the LevelUniqueQueue was being restored
on start-up of the PersistableChannelUniqueQueue.

Next there is a conflict in the setting of the internal leveldb queue
name - This wasn't being set so it was being overridden by other unique
queues.

This PR fixes these bugs and adds a testcase.

Thanks to @brechtvl  for noticing the second issue.

Fix #23050
and others

Signed-off-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: zeripath <art27@cantab.net>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Co-authored-by: delvh <leon@kske.dev>
2023-03-06 22:35:07 +08:00
Giteabot ee3d9330a8
Update hacking-on-gitea-zh_cn documentation (#23315) (#23323)
Backport #23315

This PR fix outdated hacking-on-gitea-zh_cn documentation.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Jason Song <i@wolfogre.com>
2023-03-06 18:44:02 +08:00
Giteabot d1d15306d1
Change interactiveBorder to fix popup preview (#23169) (#23314)
Backport #23169

Close #23073. 
Used the solution as reference to the reply:
https://github.com/go-gitea/gitea/issues/23073#issuecomment-1440124609
Here made the change inside the `contextpopup.js` because this is where
the popup component is created and tippy configuration is given.

Co-authored-by: Hester Gong <hestergong@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-06 16:45:43 +08:00
Giteabot e3b1ebbbfe
Scoped labels: set aria-disabled on muted Exclusive option for a11y (#23306) (#23311)
Backport #23306

It is convenient to be able to toggle off this option after removing /
from the name. This ensures the muted state is communicated to blind
users even when the input is not fully disabled.

Part of #22974

Co-authored-by: Brecht Van Lommel <brecht@blender.org>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-05 23:05:11 +08:00
Giteabot 17ae7e335e
Add basic documentation for labels, including scoped labels (#23304) (#23309)
Backport #23304

Part of #22974

Co-authored-by: Brecht Van Lommel <brecht@blender.org>
Co-authored-by: delvh <dev.lh@web.de>
2023-03-05 20:38:46 +08:00
Giteabot 1edb57eda9
Fix various bugs for "install" page (#23194) (#23286)
Backport #23194

## TLDR

* Fix the broken page / broken image problem when click "Install"
* Fix the Password Hash Algorithm display problem for #22942
* Close #20089
* Close #23183
* Close #23184

## Details

### The broken page / broken image problem when clicking on "Install"
(Redirect failed after install - #23184)

Before: when clicking on "install", all new requests will fail, because the
server has been restarted. Users just see a broken page with broken
images, sometimes the server is not ready but the user would have been
redirect to "/user/login" page, then the users see a new broken page
(connection refused or something wrong ...)


After: only check InstallLock=true for necessary handlers, and sleep for
a while before restarting the server, then the browser has enough time
to load the "post-install" page. And there is a script to check whether
"/user/login" is ready, the user will only be redirected to the login
page when the server is ready.

### During new instance setup fill 'Gitea Base URL' with
window.location.origin - #20089

If the "app_url" input contains `localhost` (the default value from
config), use current window's location href as the `app_url` (aka
ROOT_URL)


### Fix the Password Hash Algorithm display problem for "Provide the
ability to set password hash algorithm parameters #22942"

Before: the UI shows `pbkdf2$50000$50`

<details>


![image](https://user-images.githubusercontent.com/2114189/221917143-e1e54798-1698-4fee-a18d-00c48081fc39.png)

</details>

After: the UI shows `pbkdf2`

<details>


![image](https://user-images.githubusercontent.com/2114189/221916999-97a15be8-2ebb-4a01-bf93-dac18e354fcc.png)

</details>



### GET data: net::ERR_INVALID_URL #23183

Cause by empty `data:` in `<link rel="manifest"
href="data:{{.ManifestData}}">`

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Jason Song <i@wolfogre.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2023-03-05 11:59:58 +01:00
Giteabot a2a9b0f977
Support sanitising the URL by removing extra slashes in the URL (#21333) (#23300)
Backport #21333

Changes in this PR :

Strips incoming request URL of additional slashes (/). For example an
input like

`https://git.data.coop//halfd/new-website.git` is translated to
`https://git.data.coop/halfd/new-website.git`

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

Fix #23242

Co-authored-by: Sandeep Bhat <sandyethadka@gmail.com>
Co-authored-by: zeripath <art27@cantab.net>
Co-authored-by: Jason Song <i@wolfogre.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: delvh <leon@kske.dev>
2023-03-05 02:14:12 -05:00
Giteabot ff96f804b6
update to mermaid v10 (#23178) (#23299)
Backport #23178

fix #23153

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: delvh <leon@kske.dev>
2023-03-05 02:13:50 -05:00
Giteabot a926994bfe
Re-add accidentally removed `hacking-on-gitea.zh-cn.md` (#23297) (#23305) 2023-03-04 20:09:58 -05:00
Giteabot 83903535e3
Fix code wrap for unbroken lines (#23268) (#23293)
Backport #23268

## The Problem

`overflow-wrap: break-word` doesn't work well for unbroken lines. Use
`overflow-wrap: anywhere` instead, and remove legacy alias `word-wrap`

## Before


![image](https://user-images.githubusercontent.com/2114189222743939-5f38d9e4-18d8-4ae0-8078-4b3a59195a30.png)

## After


![image](https://user-images.githubusercontent.com/2114189/222743833-0e0cfdbb-7b2e-420d-99f9-b1b45dde521a.png)

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2023-03-04 20:55:12 +01:00
Giteabot 8142408d3a
Fill head commit to in payload when notifying push commits for mirroring (#23215) (#23292)
Backport #23215

Just like what has been done when pushing manually:

7a5af25592/services/repository/push.go (L225-L226)

Before:

<img width="448" alt="image"
src="https://user-images.githubusercontent.com/9418365/222100123-cd4839d1-2d4d-45f7-7a0-0cbc73162b44.png">

After:

<img width="448" alt="image"
src="https://user-images.githubusercontent.com/9418365/222100225-3c5bb65-7ab9-41e2-8e39-9d84c23c352d.png">

Co-authored-by: Jason Song <i@wolfogre.com>
Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-04 19:02:50 +01:00
Giteabot a4158d1904
Avoid panic caused by broken payload when creating commit status (#23216) (#23294)
Backport #23216

When creating commit status for Actons jobs, a payload with nil
`HeadCommit` will cause panic.

Reported at:
https://gitea.com/gitea/act_runner/issues/28#issuecomment-732166

Although the `HeadCommit` probably can not be nil after #23215,
`CreateCommitStatus` should protect itself, to avoid being broken in the
future.

In addition, it's enough to print error log instead of returning err
when `CreateCommitStatus` failed.

Co-authored-by: Jason Song <i@wolfogre.com>
Co-authored-by: delvh <dev.lh@web.de>
2023-03-04 14:23:49 +00:00
Giteabot 781019216c
Fix GetFilesChangedBetween if the file name may be escaped (#23272) (#23279)
Backport #23272

The code for GetFilesChangedBetween uses `git diff --name-only
base..head` to get the names of files changed between base and head
however this forgets that git will escape certain values.

This PR simply switches to use `-z` which has the `NUL` character as the
separator.

Ref https://github.com/go-gitea/gitea/pull/22568#discussion_r1123138096

Signed-off-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: zeripath <art27@cantab.net>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2023-03-04 00:38:31 -05:00
Giteabot 1322cd7a58
Use correct README link to render the README (#23152) (#23264)
Backport #23152

`renderReadmeFile` needs `readmeTreelink` as parameter but gets
`treeLink`.
The values of them look like as following:
`treeLink`:  `/{OwnerName}/{RepoName}/src/branch/{BranchName}`
`readmeTreelink`:
`/{OwnerName}/{RepoName}/src/branch/{BranchName}/{ReadmeFileName}`

`path.Dir` in

8540fc45b1/routers/web/repo/view.go (L316)
should convert `readmeTreelink` into
`/{OwnerName}/{RepoName}/src/branch/{BranchName}` instead of the current
`/{OwnerName}/{RepoName}/src/branch`.

Fixes #23151

Co-authored-by: yp05327 <576951401@qq.com>
Co-authored-by: Jason Song <i@wolfogre.com>
Co-authored-by: John Olheiser <john.olheiser@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2023-03-04 00:38:11 -05:00
Giteabot 464bbd747e
Fix commit retrieval by tag (#21804) (#23266)
Backport #21804

It is not correct to return tag data when commit data is requested, so
remove the hacky code that overwrote parts of a commit with parts of a
tag.

This fixes commit retrieval by tag for both the latest commit in the UI
and the commit info on tag webhook events.

Fixes: https://github.com/go-gitea/gitea/issues/21687
Replaces: https://github.com/go-gitea/gitea/pull/21693

<img width="324" alt="Screenshot 2022-11-13 at 15 26 37"
src="https://user-images.githubusercontent.com/115237/201526975-736c6ea7-ad6a-467a-a823-9a63d6ecb718.png">

<img width="789" alt="image"
src="https://user-images.githubusercontent.com/115237/201526876-90a13ffc-1e5c-4d76-911b-f1ae51e8eaab.png">

Co-authored-by: silverwind <me@silverwind.io>
2023-03-03 13:42:46 -06:00
Giteabot 574182e1eb
Revert relative links to absolute links in mail templates (#23267) (#23269)
Backport #23267

Follow #21986 , fix regression.

The mail templates should always use `AppURL` (the full absolute URL)

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-03-03 17:41:00 +00:00
Giteabot ef8209a953
Use async await to fix empty quote reply at first time (#23168) (#23256)
Backport #23168

The reason why quote reply is empty is when quote reply is clicked, it
triggers the click function on `.comment-form-reply` button, and when
the first time this function is triggered, easyMDE for the reply has not
yet initialized, so that click handler of `.quote-reply` button in
`repo-legacy.js` got an `undefined` as easyMDE, and the following lines
which put quoted reply into the easyMDE is not executed.
The workaround in this PR is to pass the replied content to
'.comment-form-reply' button if easyMDE is not yet initialized (quote
reply first clicked) and put the replied content into it the after
easyMDE is created.
Now quote reply on first click:


https://user-images.githubusercontent.com/17645053/221452823-fc699d50-1649-4af1-952e-f04fc8d2978e.mov

<br />


Update:
The above change is not appropriate as stated in the
[comment](https://github.com/go-gitea/gitea/pull/23168#issuecomment-1445562284)
Use await instead

Close #22075.
Close #23247.

Co-authored-by: HesterG <hestergong@gmail.com>
2023-03-02 16:36:21 -06:00
Giteabot 9309098eab
Fix switched citation format (#23250) (#23253)
Backport #23250

Due to switched input parameters, the citation texts for Bibtex and Apa
were switched.
This pull request fixes #23244

Co-authored-by: Blender Defender <contact.blenderdefender@gmail.com>
2023-03-02 14:05:10 -06:00
Giteabot 790a79b04c
Fix missed `.hide` class (#23208) (#23237)
Backport #23208

https://github.com/go-gitea/gitea/pull/22950 removed `hide` class, and
use `gt-hidden`
But there are some missed `hide`....

Co-authored-by: yp05327 <576951401@qq.com>
2023-03-02 11:45:42 -06:00
Giteabot f8a40dafb9
Allow `<video>` in MarkDown (#22892) (#23236)
Backport #22892

As you can imagine, for the Blender development process it is rather
nice to be able to include videos in issues, pull requests, etc.

This PR allows the `<video>` HTML tag to be used in MarkDown, with the
`src`, `autoplay`, and `controls` attributes.

## Help Needed

To have this fully functional, personally I feel the following things
are still missing, and would appreciate some help from the Gitea team.

### Styling

Some CSS is needed, but I couldn't figure out which of the LESS files
would work. I tried `web_src/less/markup/content.less` and
`web_src/less/_base.less`, but after running `make` the changes weren't
seen in the frontend.

This I would consider a minimal set of CSS rules to be applied:

```css
video {
  max-width: 100%;
  max-height: 100vh;
}
```

### Default Attributes

It would be fantastic if Gitea could add some default attributes to the
`<video>` tag. Basically `controls` should always be there, as there is
no point in disallowing scrolling through videos, looping them, etc.

### Integration with the attachments system

Another thing that could be added, but probably should be done in a
separate PR, is the integration with the attachments system. Dragging in
a video should attach it, then generate the appropriate MarkDown/HTML.

Co-authored-by: Sybren <122987084+drsybren@users.noreply.github.com>
2023-03-02 11:49:05 -05:00
Giteabot 9843a0b741
Close the temp file when dumping database to make the temp file can be deleted on Windows (#23249) (#23251)
Backport #23249

There was no `dbDump.Close()` before, Windows doesn't like to delete
opened files.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-03-02 11:47:07 -05:00
Giteabot 085a4debd5
Fix incorrect checkbox behaviors in the dashboard repolist's filter (#23147) (#23205)
Backport #23147

Co-author: yp05327 , this PR is based on yp05327's #22813.

The problems of the old DashboardRepoList / repolist.tmpl: 

* It mixes many different frameworks together
* It "just works", bug on bug
* It uses many anti-pattern of Vue

This PR:

* Fix bugs and close #22800
* Decouple the "checkbox" elements from Fomantic UI (only use CSS
styles)
* Simplify the HTML layout
* Simplify JS logic
* Make it easier to refactor the DashboardRepoList into a pure Vue
component in the future.

### Screenshots

#### Default

![image](https://user-images.githubusercontent.com/2114189/221355768-a3eb5b23-85b4-4e3d-b906-844d8b15539d.png)

####  Click "Archived" to make it checked

![image](https://user-images.githubusercontent.com/2114189/221355777-9a104ddf-52a7-4504-869a-43a73827d802.png)

####  Click "Archived" to make it intermediate

![image](https://user-images.githubusercontent.com/2114189/221355802-0f67a073-67ad-4e92-84a6-558c432103a5.png)

####  Click "Archived" to make it unchecked

![image](https://user-images.githubusercontent.com/2114189/221355810-acf1d9d8-ccce-47fe-a02e-70cf4e666331.png)

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: yp05327 <576951401@qq.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-02 15:12:33 +08:00
Giteabot 4c1e24864f
Order pull request conflict checking by recently updated, for each push (#23220) (#23225)
Backport #23220

When a change is pushed to the default branch and many pull requests are
open for that branch, conflict checking can take some time.

Previously it would go from oldest to newest pull request. Now
prioritize pull requests that are likely being actively worked on or
prepared for merging.

This only changes the order within one push to one repository, but the
change is trivial and can already be quite helpful for smaller Gitea
instances where a few repositories have most pull requests. A global
order would require deeper changes to queues.

Co-authored-by: Brecht Van Lommel <brecht@blender.org>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-03-02 13:12:41 +08:00
Giteabot 5d5f907e7f
Add loading yaml label template files (#22976) (#23232)
Backport #22976

Extract from #11669 and enhancement to #22585 to support exclusive
scoped labels in label templates

* Move label template functionality to label module
* Fix handling of color codes
* Add Advanced label template

Co-authored-by: Lauris BH <lauris@nix.lv>
2023-03-01 21:57:34 -05:00
Giteabot 39178b5756
Do not create commit graph for temporary repos (#23219) (#23229)
Backport #23219

When fetching remotes for conflict checking, skip unnecessary and
potentially slow writing of commit graphs.

In a test with the Blender repository, this reduces conflict checking
time for one pull request from about 2s to 0.1s.

Co-authored-by: Brecht Van Lommel <brecht@blender.org>
2023-03-02 01:53:41 +02:00
Giteabot 3d8412dd51
Use the correct selector to hide the checkmark of selected labels on clear (#23224) (#23228)
Backport #23224

Regression of #10107
(https://github.com/go-gitea/gitea/pull/10107/files#diff-a15e36f2f9c13339f7fdd38bc2887db2ff2945cb8434464318ab9105fcc846bdR460)

Fix #22222


Before: the "clear" action couldn't remove these check marks.


![image](https://user-images.githubusercontent.com/2114189/222212998-c9f33459-b71d-4e80-8588-2935f3b7050c.png)


After: the "clear" action can remove these  check marks.


![image](https://user-images.githubusercontent.com/2114189/222213048-2be98ed0-cac0-4e27-b72c-1dd0ac2637d5.png)

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-03-01 15:59:36 -05:00
Yarden Shoham ff7057a46d
Change button text for commenting and closing an issue at the same time (#23135) (#23182)
Backport #23135

Close  #10468

Without SimpleMDE/EasyMDE, using Simple Textarea, the button text could
be changed when content changes.

After introducing SimpleMDE/EasyMDE, there is no code for updating the
button text.



![image](https://user-images.githubusercontent.com/2114189/221334034-8d556cd5-1136-4ba0-8faa-a65ffadd7fb7.png)

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-02-28 17:54:24 -05:00
wxiaoguang bb8ef28913
Fix Fomantic UI's `touchstart` fastclick, always use `click` for click events (#23065) (#23195)
Backport #23065

Using `touchstart` for `click` events is a black magic for mobile
browsers (Google: `fastclick`).

However, it causes many UX problems if the fastclick is used without
careful design.

Fomantic UI uses this fastclick for its `dimmer` and `dropdown`, it
makes mobile users feel strange when they "touch" the dropdown menu.


This PR uses a simple patch to fix that behavior. Then the Fomantic
dropdown only uses `click` for click events.

This PR is simple enough and won't cause hidden bugs even if the patch
doesn't work. In the future, if there are more patches for Fomantic UI,
the patches could be placed in a directory like
`web_src/fomantic/patches/001-fix-click-touchstart`, etc.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-02-28 17:53:45 -05:00
Giteabot 13918ad344
Pass `--global` when calling `git config --get`, for consistency with `git config --set` (#23157) (#23199)
Backport #23157

This arose out of #22451; it seems we are checking using non-global
settings to see if a config value is set, in order to decide whether to
call another global(-indeed) configuration command. This PR changes it
so that both the check and the set are for global configuration.

Co-authored-by: Philip Peterson <philip-peterson@users.noreply.github.com>
2023-02-28 17:53:15 -05:00
Giteabot 7528ce60e7
Make `gitea serv` respect git binary home (#23138) (#23197)
Backport #23138

Close #23137

The old code is too old (8-9 years ago)

Let's try to execute the git commands from git bin home directly.

The verb has been checked above, it could only be:
* git-upload-pack
* git-upload-archive
* git-receive-pack
* git-lfs-authenticate

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-02-28 16:46:23 -06:00
Yarden Shoham 6c6a7e7d97
Avoid too long names for actions (#23162) (#23190)
Backport #23162

The name of the job or step comes from the workflow file, while the name
of the runner comes from its registration. If the strings used for these
names are too long, they could cause db issues.

Co-authored-by: Jason Song <i@wolfogre.com>
2023-02-28 13:42:40 +01:00
Yarden Shoham 111c509287
Add InsecureSkipVerify to Minio Client for Storage (#23166) (#23177)
Backport #23166

Allows using Minio with untrusted certificates

Closes #23128

Signed-off-by: Yarden Shoham <hrsi88@gmail.com>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2023-02-28 00:29:17 +02:00
Yarden Shoham 9d7ef0ad63
Add word-break to sidebar-item-link (#23146) (#23180)
Backport #23146

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

![image](https://user-images.githubusercontent.com/18380374/221351117-1e4b8922-04ca-4717-8e3b-c338a61bc062.png)

Co-authored-by: yp05327 <576951401@qq.com>
Co-authored-by: delvh <leon@kske.dev>
2023-02-27 15:59:36 -05:00
Yarden Shoham 9aae54c81f
Remove useless comment in #23114 (#23173) (#23175)
Backport #23173

The `isAdmin` param is no longer used so the comment should be removed.

d27d36f2f4/routers/web/explore/repo.go (L36-L37)

Co-authored-by: Zettat123 <zettat123@gmail.com>
2023-02-27 22:43:15 +08:00
Yarden Shoham 1bc4ffc337
Return 404 instead of 403 if user can not access the repo (#23155) (#23158)
Backport #23155

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

Before:

![image](https://user-images.githubusercontent.com/18380374/221390802-2317c6bc-d163-4def-b68b-6bb297143fe2.png)

After:

![image](https://user-images.githubusercontent.com/18380374/221390823-87490351-39c3-4a40-b1d2-11fc5b85fa24.png)

Co-authored-by: yp05327 <576951401@qq.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-02-26 20:20:44 +08:00
Yarden Shoham 27879bc45e
Fix DBConsistency checks on MSSQL (#23132) (#23134)
Backport #23132

Unfortunately xorm's `builder.Select(...).From(...)` does not escape the
table names. This is mostly not a problem but is a problem with the
`user` table.

This PR simply escapes the user table. No other uses of `From("user")`
where found in the codebase so I think this should be all that is
needed.

Fix #23064

Signed-off-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: zeripath <art27@cantab.net>
2023-02-25 23:25:58 +08:00
Yarden Shoham a3694b6989
Fix secrets overview page missing from docs sidebar (#23143) (#23145)
Backport #23143

There was a warning while building the docs: `Building sites … WARN
2023/02/25 08:56:37
"/workspace/gitea/docs/content/doc/secrets/overview.en-us.md:1:1":
duplicate menu entry with identifier "overview" in menu "sidebar"`.

### Before

![image](https://user-images.githubusercontent.com/20454870/221348741-55cef254-f2ac-4507-9a66-818b406c668f.png)

### After

![image](https://user-images.githubusercontent.com/20454870/221348757-42066303-e1b7-43fe-9c4f-e05182fbabdd.png)

Signed-off-by: Yarden Shoham <hrsi88@gmail.com>
2023-02-25 13:30:32 +02:00
Yarden Shoham 28625fba5b
Redirect to the commit page after applying patch (#23056) (#23127)
Backport #23056

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

Co-authored-by: yp05327 <576951401@qq.com>
2023-02-24 22:43:26 -05:00
Yarden Shoham 7c3196ceac
Avoid warning for system setting when start up (#23054) (#23116)
Backport #23054

Partially fix #23050

After #22294 merged, it always has a warning log like `cannot get
context cache` when starting up. This should not affect any real life
but it's annoying. This PR will fix the problem. That means when
starting up, getting the system settings will not try from the cache but
will read from the database directly.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Lauris BH <lauris@nix.lv>
2023-02-24 16:46:11 -05:00
Yarden Shoham 80c1264f4b
Show empty repos in Admin Repository Management page (#23114) (#23130)
Backport #23114

The **Admin Repository Management** page and the **Explore Repository**
page both use the `RenderRepoSearch` function. In this function, the
`OnlyShowRelevant` search option is `true` when querying repositories
for admin page.


edf98a2dc3/routers/web/explore/repo.go (L99-L115)

Refer to
[#19361](https://github.com/go-gitea/gitea/pull/19361/files#diff-8058dfb85557010e0592d586675ec62ce406af7068e6311f39c160deac37f149R497),
the repositories with `is_empty=true` will be hidden if
`OnlyShowRelevant` is `true`.

Administrators should be able to see all repositories. So
`OnlyShowRelevant` shouldn't be set to `true` .

Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: Andrew Thornton <art27@cantab.net>
2023-02-24 20:17:21 +00:00
silverwind f0340c28f1
Change style to improve whitespaces trimming inside inline markdown code (#23093) (#23120)
Backport #23093

Given mardown source
```
x ` a` y
x `a ` y
x ` a ` y
```

Render

<img width="1421" alt="2023-02-23 15 33 14"

src="https://user-images.githubusercontent.com/17645053/220844280-a304c788-ac79-4a26-a55a-0db00f2fb3f3.png">

Fixes #23080.

Co-authored-by: HesterG <hestergong@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-02-24 17:05:36 +00:00
Yarden Shoham 5beb29ad35
Fix height for sticky head on large screen on PR page (#23111) (#23123)
Backport #23111

Right now on the PR 'File Change' Tab, the file title header sticky to
the top on large screens has wrong height, resulting in wrong ui
behavior when scrolling down. This PR is to fix this.

Before:

<img width="964" alt="截屏2023-02-24 17 12 29"
src="https://user-images.githubusercontent.com/17645053/221140409-025c4a84-6bbe-4b5b-a13f-bd2b79063522.png">

After:
<img width="1430" alt="截屏2023-02-24 21 10 12"
src="https://user-images.githubusercontent.com/17645053/221186750-0344d652-4610-4a90-a4c0-7f6269f950d6.png">

Co-authored-by: HesterG <hestergong@gmail.com>
2023-02-24 14:47:48 +00:00
Yarden Shoham 27e307142b
Fix db.Find bug (#23115) (#23119)
Backport #23115

Caused by #20821 

Fix #23110
2023-02-24 14:05:36 +00:00
Yarden Shoham e02e752f68
Fix nil context in RenderMarkdownToHtml (#23092) (#23108)
Backport #23092

Fix #23082.

This bug is caused by a nil context in
https://github.com/go-gitea/gitea/issues/23082#issuecomment-1441276546 .

Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-02-24 21:17:03 +08:00
Yarden Shoham 5ddf67a9c2
Make issue meta dropdown support Enter, confirm before reloading (#23014) (#23102)
Backport #23014

As the title. Label/assignee share the same code.

* Close #22607
* Close #20727

Also:

* partially fix for #21742, now the comment reaction and menu work with
keyboard.
* partially fix for #17705, in most cases the comment won't be lost.
* partially fix for #21539
* partially fix for #20347
* partially fix for #7329

### The `Enter` support

Before, if user presses Enter, the dropdown just disappears and nothing
happens or the window reloads.

After, Enter can be used to select/deselect labels, and press Esc to
hide the dropdown to update the labels (still no way to cancel ....
maybe you can do a Cmd+R or F5 to refresh the window to discard the
changes .....)


This is only a quick patch, the UX is still not perfect, but it's much
better than before.


### The `confirm` before reloading

And more fixes for the `reload` problem, the new behaviors:

* If nothing changes (just show/hide the dropdown), then the page won't
be reloaded.
* If there are draft comments, show a confirm dialog before reloading,
to avoid losing comments.

That's the best effect can be done at the moment, unless completely
refactor these dropdown related code.

Screenshot of the confirm dialog:

<details>


![image](https://user-images.githubusercontent.com/2114189/220538288-e2da8459-6a4e-43cb-8596-74057f8a03a2.png)

</details>

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Brecht Van Lommel <brecht@blender.org>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-02-24 17:40:36 +08:00
Yarden Shoham 4d3e2b23b8
Fix SyncOnCommit always return false in API of push_mirrors (#23088) (#23100)
Backport #23088

Fix: #22990

---
Before, the return value of the api is always false,regrardless of
whether the entry of `sync_on_commit` is true or false.
I have confirmed that the value of `sync_on_commit` dropped into the
database is correct.
So, I think it is enough to make some small changes.

Co-authored-by: sillyguodong <33891828+sillyguodong@users.noreply.github.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-02-24 14:36:25 +08:00
Yarden Shoham ddf61373f6
Add wrapper to author to avoid long name ui problem (#23030) (#23098)
Backport #23030

This PR is a possible solution for issue #22866. Main change is to add a
`author-wrapper` class around author name, like the wrapper added to
message. The `max-width` is set to 200px on PC, and 100px on mobile
device for now. Which will work like below:

<img width="1183" alt="2023-02-21 11 57 53"
src="https://user-images.githubusercontent.com/17645053/220244146-3d47c512-33b6-4ed8-938e-de0a8bc26ffb.png">

<img width="417" alt="2023-02-21 11 58 43"
src="https://user-images.githubusercontent.com/17645053/220244154-1ea0476b-9d1c-473a-9917-d3216860f9a9.png">

And `title` is added to the wrapper like it did in message wrapper. So
the full author name will show on hover.

Co-authored-by: HesterG <hestergong@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-02-24 10:45:18 +08:00
Yarden Shoham b4ed3f07e4
Fix commit name in Apply Patch page (#23086) (#23099)
Backport #23086

Fixes
https://github.com/go-gitea/gitea/issues/22621#issuecomment-1439309200

Co-authored-by: yp05327 <576951401@qq.com>
2023-02-24 08:47:35 +08:00
HesterG ced94f2e0d
Add accessibility to the menu on the navbar (#23059) (#23095)
Backport #23059

This PR is trying to add accessibility to the menu as mentioned in
#23053 so the menu can be accessed using keyboard (A quick demo is added
below), with a reference to
[PR2612](https://github.com/go-gitea/gitea/pull/22612). The goal is to
make the menu accessible merely using keyboard like shown below. And
this PR might need confirmation from developers using screen readers.
2023-02-23 20:56:03 +08:00
Yarden Shoham aff432b197
Nest metadata in refactoring docs (#23087) (#23091)
Backport #23087

Whitespace was missing from refactoring docs metadata.

backport label applied so it is included in versioned docs.

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2023-02-23 03:39:30 -05:00
Yarden Shoham 0ac3be1482
Improve accessibility for issue comments (#22612) (#23083)
Backport #22612

### Preamble

Gitea is an extremely great and smart solution perfectly suitable for
smaller systems and self-hosted Git-powered setups. However, there is a
group of people who have indredible difficulties in using Gitea,
rendering it useless in many cases. Those people are blind developers
using [screen readers](https://en.wikipedia.org/wiki/Screen_reader).
Unfortunately, the frontend framework is super convoluted, and Go
templates don’t allow accessibility improvements in a straightforward
way. As a blind developer myself, I'm trying to start fixing smaller
accessibility quirks with intention to go deeper and eventually, alone
or not, make Gitea at least mostly accessible for screen reader users.

### What This Fix Does

My blind fellows and me navigate webpages not very similarly to how a
sighted person does it. For instance, we love semantic HTML markup like
headings, lists, tables etc. because our screen readers allow us to jump
by those landmarks with a single keypress.
Currently in Gitea issue comments are not marked up with headings. I'm
trying to fix this by adding an appropriate
[ARIA](https://www.w3.org/WAI/standards-guidelines/aria/) role for
comment header and also by enclosing the comment itself in a semantical
article element.

Co-authored-by: Andre Polykanine <ap@oire.me>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: John Olheiser <john.olheiser@gmail.com>
2023-02-23 16:32:15 +08:00
Yarden Shoham 75eaf99076
Wrap unless-check in docker manifests (#23079) (#23081)
Backport #23079

Should fix the following:
> failed to render template: Evaluation error: Helper 'unless' called
with wrong number of arguments, needed 2 but got 3

https://go.dev/play/p/h7bt7MWKTcv

Signed-off-by: jolheiser <john.olheiser@gmail.com>
Co-authored-by: John Olheiser <john.olheiser@gmail.com>
2023-02-23 01:34:47 +01:00
wxiaoguang e67d60d336
Fix some more hidden problems (#23074) (#23075)
Backport #23074
2023-02-22 15:26:48 +00:00
4906 changed files with 272558 additions and 196699 deletions

View File

@ -2,12 +2,9 @@ root = "."
tmp_dir = ".air"
[build]
cmd = "make --no-print-directory backend"
cmd = "make backend"
bin = "gitea"
delay = 1000
include_ext = ["go", "tmpl"]
include_file = ["main.go"]
include_dir = ["cmd", "models", "modules", "options", "routers", "services"]
exclude_dir = ["modules/git/tests", "services/gitdiff/testdata", "modules/avatar/testdata", "models/fixtures", "models/migrations/fixtures", "modules/migration/file_format_testdata", "modules/avatar/identicon/testdata"]
include_dir = ["cmd", "models", "modules", "options", "routers", "services"]
exclude_regex = ["_test.go$", "_gen.go$"]
stop_on_error = true

View File

@ -13,42 +13,46 @@ groups:
-
name: BREAKING
labels:
- pr/breaking
- kind/breaking
-
name: SECURITY
labels:
- topic/security
- kind/security
-
name: FEATURES
labels:
- type/feature
- kind/feature
-
name: API
labels:
- modifies/api
- kind/api
-
name: ENHANCEMENTS
labels:
- type/enhancement
- type/refactoring
- topic/ui
- kind/enhancement
- kind/refactor
- kind/ui
-
name: BUGFIXES
labels:
- type/bug
- kind/bug
-
name: TESTING
labels:
- type/testing
- kind/testing
-
name: TRANSLATION
labels:
- kind/translation
-
name: BUILD
labels:
- topic/build
- topic/code-linting
- kind/build
- kind/lint
-
name: DOCS
labels:
- type/docs
- kind/docs
-
name: MISC
default: true

View File

@ -1,40 +0,0 @@
{
"name": "Gitea DevContainer",
"image": "mcr.microsoft.com/devcontainers/go:1.22-bullseye",
"features": {
// installs nodejs into container
"ghcr.io/devcontainers/features/node:1": {
"version":"20"
},
"ghcr.io/devcontainers/features/git-lfs:1.1.0": {},
"ghcr.io/devcontainers-contrib/features/poetry:2": {},
"ghcr.io/devcontainers/features/python:1": {
"version": "3.12"
}
},
"customizations": {
"vscode": {
"settings": {},
// same extensions as Gitpod, should match /.gitpod.yml
"extensions": [
"editorconfig.editorconfig",
"dbaeumer.vscode-eslint",
"golang.go",
"stylelint.vscode-stylelint",
"DavidAnson.vscode-markdownlint",
"Vue.volar",
"ms-azuretools.vscode-docker",
"zixuanchen.vitest-explorer",
"qwtel.sqlite-viewer",
"GitHub.vscode-pull-request-github"
]
}
},
"portsAttributes": {
"3000": {
"label": "Gitea Web",
"onAutoForward": "notify"
}
},
"postCreateCommand": "make deps"
}

View File

@ -75,10 +75,11 @@ cpu.out
/yarn.lock
/yarn-error.log
/npm-debug.log*
/public/assets/js
/public/assets/css
/public/assets/fonts
/public/assets/img/webpack
/public/js
/public/serviceworker.js
/public/css
/public/fonts
/public/img/webpack
/vendor
/web_src/fomantic/node_modules
/web_src/fomantic/build/*

1749
.drone.yml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -9,193 +9,55 @@ parserOptions:
ecmaVersion: latest
plugins:
- "@eslint-community/eslint-plugin-eslint-comments"
- "@stylistic/eslint-plugin-js"
- eslint-plugin-array-func
- eslint-plugin-github
- eslint-plugin-i
- eslint-plugin-jquery
- eslint-plugin-no-jquery
- eslint-plugin-no-use-extend-native
- eslint-plugin-regexp
- eslint-plugin-sonarjs
- eslint-plugin-unicorn
- eslint-plugin-vitest
- eslint-plugin-vitest-globals
- eslint-plugin-wc
- eslint-plugin-import
- eslint-plugin-jquery
- eslint-plugin-sonarjs
env:
es2024: true
es2022: true
node: true
globals:
__webpack_public_path__: true
overrides:
- files: ["web_src/**/*"]
globals:
__webpack_public_path__: true
process: false # https://github.com/webpack/webpack/issues/15833
- files: ["web_src/**/*", "docs/**/*"]
- files: ["web_src/**/*.js", "docs/**/*.js"]
env:
browser: true
node: false
- files: ["web_src/**/*worker.*"]
- files: ["web_src/**/*worker.js"]
env:
worker: true
rules:
no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, status, statusbar, stop, toolbar, top]
- files: ["build/generate-images.js"]
rules:
i/no-unresolved: [0]
i/no-extraneous-dependencies: [0]
- files: ["*.config.*"]
import/no-unresolved: [0]
import/no-extraneous-dependencies: [0]
- files: ["*.config.js"]
rules:
i/no-unused-modules: [0]
- files: ["**/*.test.*", "web_src/js/test/setup.js"]
env:
vitest-globals/env: true
rules:
vitest/consistent-test-filename: [0]
vitest/consistent-test-it: [0]
vitest/expect-expect: [0]
vitest/max-expects: [0]
vitest/max-nested-describe: [0]
vitest/no-alias-methods: [0]
vitest/no-commented-out-tests: [0]
vitest/no-conditional-expect: [0]
vitest/no-conditional-in-test: [0]
vitest/no-conditional-tests: [0]
vitest/no-disabled-tests: [0]
vitest/no-done-callback: [0]
vitest/no-duplicate-hooks: [0]
vitest/no-focused-tests: [0]
vitest/no-hooks: [0]
vitest/no-identical-title: [2]
vitest/no-interpolation-in-snapshots: [0]
vitest/no-large-snapshots: [0]
vitest/no-mocks-import: [0]
vitest/no-restricted-matchers: [0]
vitest/no-restricted-vi-methods: [0]
vitest/no-standalone-expect: [0]
vitest/no-test-prefixes: [0]
vitest/no-test-return-statement: [0]
vitest/prefer-called-with: [0]
vitest/prefer-comparison-matcher: [0]
vitest/prefer-each: [0]
vitest/prefer-equality-matcher: [0]
vitest/prefer-expect-resolves: [0]
vitest/prefer-hooks-in-order: [0]
vitest/prefer-hooks-on-top: [2]
vitest/prefer-lowercase-title: [0]
vitest/prefer-mock-promise-shorthand: [0]
vitest/prefer-snapshot-hint: [0]
vitest/prefer-spy-on: [0]
vitest/prefer-strict-equal: [0]
vitest/prefer-to-be: [0]
vitest/prefer-to-be-falsy: [0]
vitest/prefer-to-be-object: [0]
vitest/prefer-to-be-truthy: [0]
vitest/prefer-to-contain: [0]
vitest/prefer-to-have-length: [0]
vitest/prefer-todo: [0]
vitest/require-hook: [0]
vitest/require-to-throw-message: [0]
vitest/require-top-level-describe: [0]
vitest/valid-describe-callback: [2]
vitest/valid-expect: [2]
vitest/valid-title: [2]
- files: ["web_src/js/modules/fetch.js", "web_src/js/standalone/**/*"]
rules:
no-restricted-syntax: [2, WithStatement, ForInStatement, LabeledStatement, SequenceExpression]
import/no-unused-modules: [0]
rules:
"@eslint-community/eslint-comments/disable-enable-pair": [2]
"@eslint-community/eslint-comments/no-aggregating-enable": [2]
"@eslint-community/eslint-comments/no-duplicate-disable": [2]
"@eslint-community/eslint-comments/no-restricted-disable": [0]
"@eslint-community/eslint-comments/no-unlimited-disable": [2]
"@eslint-community/eslint-comments/no-unused-disable": [2]
"@eslint-community/eslint-comments/no-unused-enable": [2]
"@eslint-community/eslint-comments/no-use": [0]
"@eslint-community/eslint-comments/require-description": [0]
"@stylistic/js/array-bracket-newline": [0]
"@stylistic/js/array-bracket-spacing": [2, never]
"@stylistic/js/array-element-newline": [0]
"@stylistic/js/arrow-parens": [2, always]
"@stylistic/js/arrow-spacing": [2, {before: true, after: true}]
"@stylistic/js/block-spacing": [0]
"@stylistic/js/brace-style": [2, 1tbs, {allowSingleLine: true}]
"@stylistic/js/comma-dangle": [2, only-multiline]
"@stylistic/js/comma-spacing": [2, {before: false, after: true}]
"@stylistic/js/comma-style": [2, last]
"@stylistic/js/computed-property-spacing": [2, never]
"@stylistic/js/dot-location": [2, property]
"@stylistic/js/eol-last": [2]
"@stylistic/js/function-call-spacing": [2, never]
"@stylistic/js/function-call-argument-newline": [0]
"@stylistic/js/function-paren-newline": [0]
"@stylistic/js/generator-star-spacing": [0]
"@stylistic/js/implicit-arrow-linebreak": [0]
"@stylistic/js/indent": [2, 2, {ignoreComments: true, SwitchCase: 1}]
"@stylistic/js/key-spacing": [2]
"@stylistic/js/keyword-spacing": [2]
"@stylistic/js/linebreak-style": [2, unix]
"@stylistic/js/lines-around-comment": [0]
"@stylistic/js/lines-between-class-members": [0]
"@stylistic/js/max-len": [0]
"@stylistic/js/max-statements-per-line": [0]
"@stylistic/js/multiline-ternary": [0]
"@stylistic/js/new-parens": [2]
"@stylistic/js/newline-per-chained-call": [0]
"@stylistic/js/no-confusing-arrow": [0]
"@stylistic/js/no-extra-parens": [0]
"@stylistic/js/no-extra-semi": [2]
"@stylistic/js/no-floating-decimal": [0]
"@stylistic/js/no-mixed-operators": [0]
"@stylistic/js/no-mixed-spaces-and-tabs": [2]
"@stylistic/js/no-multi-spaces": [2, {ignoreEOLComments: true, exceptions: {Property: true}}]
"@stylistic/js/no-multiple-empty-lines": [2, {max: 1, maxEOF: 0, maxBOF: 0}]
"@stylistic/js/no-tabs": [2]
"@stylistic/js/no-trailing-spaces": [2]
"@stylistic/js/no-whitespace-before-property": [2]
"@stylistic/js/nonblock-statement-body-position": [2]
"@stylistic/js/object-curly-newline": [0]
"@stylistic/js/object-curly-spacing": [2, never]
"@stylistic/js/object-property-newline": [0]
"@stylistic/js/one-var-declaration-per-line": [0]
"@stylistic/js/operator-linebreak": [2, after]
"@stylistic/js/padded-blocks": [2, never]
"@stylistic/js/padding-line-between-statements": [0]
"@stylistic/js/quote-props": [0]
"@stylistic/js/quotes": [2, single, {avoidEscape: true, allowTemplateLiterals: true}]
"@stylistic/js/rest-spread-spacing": [2, never]
"@stylistic/js/semi": [2, always, {omitLastInOneLineBlock: true}]
"@stylistic/js/semi-spacing": [2, {before: false, after: true}]
"@stylistic/js/semi-style": [2, last]
"@stylistic/js/space-before-blocks": [2, always]
"@stylistic/js/space-before-function-paren": [0]
"@stylistic/js/space-in-parens": [2, never]
"@stylistic/js/space-infix-ops": [2]
"@stylistic/js/space-unary-ops": [2]
"@stylistic/js/spaced-comment": [2, always]
"@stylistic/js/switch-colon-spacing": [2]
"@stylistic/js/template-curly-spacing": [2, never]
"@stylistic/js/template-tag-spacing": [2, never]
"@stylistic/js/wrap-iife": [2, inside]
"@stylistic/js/wrap-regex": [0]
"@stylistic/js/yield-star-spacing": [2, after]
accessor-pairs: [2]
array-bracket-newline: [0]
array-bracket-spacing: [2, never]
array-callback-return: [2, {checkForEach: true}]
array-func/avoid-reverse: [2]
array-func/from-map: [2]
array-func/no-unnecessary-this-arg: [2]
array-func/prefer-array-from: [2]
array-func/prefer-flat-map: [0] # handled by unicorn/prefer-array-flat-map
array-func/prefer-flat: [0] # handled by unicorn/prefer-array-flat
array-element-newline: [0]
arrow-body-style: [0]
arrow-parens: [2, always]
arrow-spacing: [2, {before: true, after: true}]
block-scoped-var: [2]
brace-style: [2, 1tbs, {allowSingleLine: true}]
camelcase: [0]
capitalized-comments: [0]
class-methods-use-this: [0]
comma-dangle: [2, only-multiline]
comma-spacing: [2, {before: false, after: true}]
comma-style: [2, last]
complexity: [0]
computed-property-spacing: [2, never]
consistent-return: [0]
consistent-this: [0]
constructor-super: [2]
@ -203,84 +65,69 @@ rules:
default-case-last: [2]
default-case: [0]
default-param-last: [0]
dot-location: [2, property]
dot-notation: [0]
eol-last: [2]
eqeqeq: [2]
for-direction: [2]
func-call-spacing: [2, never]
func-name-matching: [2]
func-names: [0]
func-style: [0]
function-call-argument-newline: [0]
function-paren-newline: [0]
generator-star-spacing: [0]
getter-return: [2]
github/a11y-aria-label-is-well-formatted: [0]
github/a11y-no-title-attribute: [0]
github/a11y-no-visually-hidden-interactive-element: [0]
github/a11y-role-supports-aria-props: [0]
github/a11y-svg-has-accessible-name: [0]
github/array-foreach: [0]
github/async-currenttarget: [2]
github/async-preventdefault: [2]
github/authenticity-token: [0]
github/get-attribute: [0]
github/js-class-name: [0]
github/no-blur: [0]
github/no-d-none: [0]
github/no-dataset: [2]
github/no-dynamic-script-tag: [2]
github/no-implicit-buggy-globals: [2]
github/no-inner-html: [0]
github/no-innerText: [2]
github/no-then: [2]
github/no-useless-passive: [2]
github/prefer-observers: [2]
github/require-passive-events: [2]
github/unescaped-html-literal: [0]
grouped-accessor-pairs: [2]
guard-for-in: [0]
id-blacklist: [0]
id-length: [0]
id-match: [0]
i/consistent-type-specifier-style: [0]
i/default: [0]
i/dynamic-import-chunkname: [0]
i/export: [2]
i/exports-last: [0]
i/extensions: [2, always, {ignorePackages: true}]
i/first: [2]
i/group-exports: [0]
i/max-dependencies: [0]
i/named: [2]
i/namespace: [0]
i/newline-after-import: [0]
i/no-absolute-path: [0]
i/no-amd: [2]
i/no-anonymous-default-export: [0]
i/no-commonjs: [2]
i/no-cycle: [2, {ignoreExternal: true, maxDepth: 1}]
i/no-default-export: [0]
i/no-deprecated: [0]
i/no-dynamic-require: [0]
i/no-empty-named-blocks: [2]
i/no-extraneous-dependencies: [2]
i/no-import-module-exports: [0]
i/no-internal-modules: [0]
i/no-mutable-exports: [0]
i/no-named-as-default-member: [0]
i/no-named-as-default: [2]
i/no-named-default: [0]
i/no-named-export: [0]
i/no-namespace: [0]
i/no-nodejs-modules: [0]
i/no-relative-packages: [0]
i/no-relative-parent-imports: [0]
i/no-restricted-paths: [0]
i/no-self-import: [2]
i/no-unassigned-import: [0]
i/no-unresolved: [2, {commonjs: true, ignore: ["\\?.+$", ^vitest/]}]
i/no-unused-modules: [2, {unusedExports: true}]
i/no-useless-path-segments: [2, {commonjs: true}]
i/no-webpack-loader-syntax: [2]
i/order: [0]
i/prefer-default-export: [0]
i/unambiguous: [0]
implicit-arrow-linebreak: [0]
import/consistent-type-specifier-style: [0]
import/default: [0]
import/dynamic-import-chunkname: [0]
import/export: [2]
import/exports-last: [0]
import/extensions: [2, always, {ignorePackages: true}]
import/first: [2]
import/group-exports: [0]
import/max-dependencies: [0]
import/named: [2]
import/namespace: [0]
import/newline-after-import: [0]
import/no-absolute-path: [0]
import/no-amd: [0]
import/no-anonymous-default-export: [0]
import/no-commonjs: [0]
import/no-cycle: [2, {ignoreExternal: true, maxDepth: 1}]
import/no-default-export: [0]
import/no-deprecated: [0]
import/no-dynamic-require: [0]
import/no-empty-named-blocks: [2]
import/no-extraneous-dependencies: [2]
import/no-import-module-exports: [0]
import/no-internal-modules: [0]
import/no-mutable-exports: [0]
import/no-named-as-default-member: [0]
import/no-named-as-default: [2]
import/no-named-default: [0]
import/no-named-export: [0]
import/no-namespace: [0]
import/no-nodejs-modules: [0]
import/no-relative-packages: [0]
import/no-relative-parent-imports: [0]
import/no-restricted-paths: [0]
import/no-self-import: [2]
import/no-unassigned-import: [0]
import/no-unresolved: [2, {commonjs: true, ignore: ["\\?.+$"]}]
import/no-unused-modules: [2, {unusedExports: true}]
import/no-useless-path-segments: [2, {commonjs: true}]
import/no-webpack-loader-syntax: [2]
import/order: [0]
import/prefer-default-export: [0]
import/unambiguous: [0]
indent: [2, 2, {SwitchCase: 1}]
init-declarations: [0]
jquery/no-ajax-events: [2]
jquery/no-ajax: [0]
@ -296,7 +143,7 @@ rules:
jquery/no-delegate: [2]
jquery/no-each: [0]
jquery/no-extend: [2]
jquery/no-fade: [2]
jquery/no-fade: [0]
jquery/no-filter: [0]
jquery/no-find: [0]
jquery/no-global-eval: [2]
@ -309,7 +156,7 @@ rules:
jquery/no-is-function: [2]
jquery/no-is: [0]
jquery/no-load: [2]
jquery/no-map: [2]
jquery/no-map: [0]
jquery/no-merge: [2]
jquery/no-param: [2]
jquery/no-parent: [0]
@ -317,7 +164,7 @@ rules:
jquery/no-parse-html: [2]
jquery/no-prop: [0]
jquery/no-proxy: [2]
jquery/no-ready: [2]
jquery/no-ready: [0]
jquery/no-serialize: [2]
jquery/no-show: [2]
jquery/no-size: [2]
@ -331,17 +178,27 @@ rules:
jquery/no-val: [0]
jquery/no-when: [2]
jquery/no-wrap: [2]
key-spacing: [2]
keyword-spacing: [2]
line-comment-position: [0]
linebreak-style: [2, unix]
lines-around-comment: [0]
lines-between-class-members: [0]
logical-assignment-operators: [0]
max-classes-per-file: [0]
max-depth: [0]
max-len: [0]
max-lines-per-function: [0]
max-lines: [0]
max-nested-callbacks: [0]
max-params: [0]
max-statements-per-line: [0]
max-statements: [0]
multiline-comment-style: [2, separate-lines]
multiline-ternary: [0]
new-cap: [0]
new-parens: [2]
newline-per-chained-call: [0]
no-alert: [0]
no-array-constructor: [2]
no-async-promise-executor: [0]
@ -353,6 +210,7 @@ rules:
no-class-assign: [2]
no-compare-neg-zero: [2]
no-cond-assign: [2, except-parens]
no-confusing-arrow: [0]
no-console: [1, {allow: [debug, info, warn, error]}]
no-const-assign: [2]
no-constant-binary-expression: [2]
@ -382,7 +240,10 @@ rules:
no-extra-bind: [2]
no-extra-boolean-cast: [2]
no-extra-label: [0]
no-extra-parens: [0]
no-extra-semi: [2]
no-fallthrough: [2]
no-floating-decimal: [0]
no-func-assign: [2]
no-global-assign: [2]
no-implicit-coercion: [2]
@ -395,99 +256,6 @@ rules:
no-invalid-this: [0]
no-irregular-whitespace: [2]
no-iterator: [2]
no-jquery/no-ajax-events: [2]
no-jquery/no-ajax: [0]
no-jquery/no-and-self: [2]
no-jquery/no-animate-toggle: [2]
no-jquery/no-animate: [2]
no-jquery/no-append-html: [0]
no-jquery/no-attr: [0]
no-jquery/no-bind: [2]
no-jquery/no-box-model: [2]
no-jquery/no-browser: [2]
no-jquery/no-camel-case: [2]
no-jquery/no-class-state: [0]
no-jquery/no-class: [0]
no-jquery/no-clone: [2]
no-jquery/no-closest: [0]
no-jquery/no-constructor-attributes: [2]
no-jquery/no-contains: [2]
no-jquery/no-context-prop: [2]
no-jquery/no-css: [0]
no-jquery/no-data: [0]
no-jquery/no-deferred: [2]
no-jquery/no-delegate: [2]
no-jquery/no-each-collection: [0]
no-jquery/no-each-util: [0]
no-jquery/no-each: [0]
no-jquery/no-error-shorthand: [2]
no-jquery/no-error: [2]
no-jquery/no-escape-selector: [2]
no-jquery/no-event-shorthand: [2]
no-jquery/no-extend: [2]
no-jquery/no-fade: [2]
no-jquery/no-filter: [0]
no-jquery/no-find-collection: [0]
no-jquery/no-find-util: [2]
no-jquery/no-find: [0]
no-jquery/no-fx-interval: [2]
no-jquery/no-global-eval: [2]
no-jquery/no-global-selector: [0]
no-jquery/no-grep: [2]
no-jquery/no-has: [2]
no-jquery/no-hold-ready: [2]
no-jquery/no-html: [0]
no-jquery/no-in-array: [2]
no-jquery/no-is-array: [2]
no-jquery/no-is-empty-object: [2]
no-jquery/no-is-function: [2]
no-jquery/no-is-numeric: [2]
no-jquery/no-is-plain-object: [2]
no-jquery/no-is-window: [2]
no-jquery/no-is: [0]
no-jquery/no-jquery-constructor: [0]
no-jquery/no-live: [2]
no-jquery/no-load-shorthand: [2]
no-jquery/no-load: [2]
no-jquery/no-map-collection: [0]
no-jquery/no-map-util: [2]
no-jquery/no-map: [2]
no-jquery/no-merge: [2]
no-jquery/no-node-name: [2]
no-jquery/no-noop: [2]
no-jquery/no-now: [2]
no-jquery/no-on-ready: [2]
no-jquery/no-other-methods: [0]
no-jquery/no-other-utils: [2]
no-jquery/no-param: [2]
no-jquery/no-parent: [0]
no-jquery/no-parents: [0]
no-jquery/no-parse-html-literal: [0]
no-jquery/no-parse-html: [2]
no-jquery/no-parse-json: [2]
no-jquery/no-parse-xml: [2]
no-jquery/no-prop: [0]
no-jquery/no-proxy: [2]
no-jquery/no-ready-shorthand: [2]
no-jquery/no-ready: [2]
no-jquery/no-selector-prop: [2]
no-jquery/no-serialize: [2]
no-jquery/no-size: [2]
no-jquery/no-sizzle: [0]
no-jquery/no-slide: [2]
no-jquery/no-sub: [2]
no-jquery/no-support: [2]
no-jquery/no-text: [0]
no-jquery/no-trigger: [0]
no-jquery/no-trim: [2]
no-jquery/no-type: [2]
no-jquery/no-unique: [2]
no-jquery/no-unload-shorthand: [2]
no-jquery/no-val: [0]
no-jquery/no-visibility: [2]
no-jquery/no-when: [2]
no-jquery/no-wrap: [2]
no-jquery/variable-pattern: [0]
no-label-var: [2]
no-labels: [0] # handled by no-restricted-syntax
no-lone-blocks: [2]
@ -496,7 +264,10 @@ rules:
no-loss-of-precision: [2]
no-magic-numbers: [0]
no-misleading-character-class: [2]
no-mixed-operators: [0]
no-mixed-spaces-and-tabs: [2]
no-multi-assign: [0]
no-multi-spaces: [2, {ignoreEOLComments: true, exceptions: {Property: true}}]
no-multi-str: [2]
no-negated-condition: [0]
no-nested-ternary: [0]
@ -520,8 +291,9 @@ rules:
no-restricted-exports: [0]
no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, location, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, self, status, statusbar, stop, toolbar, top, __dirname, __filename]
no-restricted-imports: [0]
no-restricted-syntax: [2, WithStatement, ForInStatement, LabeledStatement, SequenceExpression, {selector: "CallExpression[callee.name='fetch']", message: "use modules/fetch.js instead"}]
no-restricted-syntax: [2, WithStatement, ForInStatement, LabeledStatement]
no-return-assign: [0]
no-return-await: [0]
no-script-url: [2]
no-self-assign: [2, {props: true}]
no-self-compare: [2]
@ -530,10 +302,12 @@ rules:
no-shadow-restricted-names: [2]
no-shadow: [0]
no-sparse-arrays: [2]
no-tabs: [2]
no-template-curly-in-string: [2]
no-ternary: [0]
no-this-before-super: [2]
no-throw-literal: [2]
no-trailing-spaces: [2]
no-undef-init: [2]
no-undef: [2, {typeof: true}]
no-undefined: [0]
@ -550,7 +324,6 @@ rules:
no-unused-private-class-members: [2]
no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_, ignoreRestSiblings: false}]
no-use-before-define: [2, {functions: false, classes: true, variables: true, allowNamedExports: true}]
no-use-extend-native/no-use-extend-native: [2]
no-useless-backreference: [2]
no-useless-call: [2]
no-useless-catch: [2]
@ -563,109 +336,42 @@ rules:
no-var: [2]
no-void: [2]
no-warning-comments: [0]
no-whitespace-before-property: [2]
no-with: [0] # handled by no-restricted-syntax
nonblock-statement-body-position: [2]
object-curly-newline: [0]
object-curly-spacing: [2, never]
object-shorthand: [2, always]
one-var-declaration-per-line: [0]
one-var: [0]
operator-assignment: [2, always]
operator-linebreak: [2, after]
padded-blocks: [2, never]
padding-line-between-statements: [0]
prefer-arrow-callback: [2, {allowNamedFunctions: true, allowUnboundThis: true}]
prefer-const: [2, {destructuring: all, ignoreReadBeforeAssign: true}]
prefer-destructuring: [0]
prefer-exponentiation-operator: [2]
prefer-named-capture-group: [0]
prefer-numeric-literals: [2]
prefer-object-has-own: [2]
prefer-object-has-own: [0]
prefer-object-spread: [2]
prefer-promise-reject-errors: [2, {allowEmptyReject: false}]
prefer-regex-literals: [2]
prefer-rest-params: [2]
prefer-spread: [2]
prefer-template: [2]
quote-props: [0]
quotes: [2, single, {avoidEscape: true, allowTemplateLiterals: true}]
radix: [2, as-needed]
regexp/confusing-quantifier: [2]
regexp/control-character-escape: [2]
regexp/hexadecimal-escape: [0]
regexp/letter-case: [0]
regexp/match-any: [2]
regexp/negation: [2]
regexp/no-contradiction-with-assertion: [0]
regexp/no-control-character: [0]
regexp/no-dupe-characters-character-class: [2]
regexp/no-dupe-disjunctions: [2]
regexp/no-empty-alternative: [2]
regexp/no-empty-capturing-group: [2]
regexp/no-empty-character-class: [0]
regexp/no-empty-group: [2]
regexp/no-empty-lookarounds-assertion: [2]
regexp/no-empty-string-literal: [2]
regexp/no-escape-backspace: [2]
regexp/no-extra-lookaround-assertions: [0]
regexp/no-invalid-regexp: [2]
regexp/no-invisible-character: [2]
regexp/no-lazy-ends: [2]
regexp/no-legacy-features: [2]
regexp/no-misleading-capturing-group: [0]
regexp/no-misleading-unicode-character: [0]
regexp/no-missing-g-flag: [2]
regexp/no-non-standard-flag: [2]
regexp/no-obscure-range: [2]
regexp/no-octal: [2]
regexp/no-optional-assertion: [2]
regexp/no-potentially-useless-backreference: [2]
regexp/no-standalone-backslash: [2]
regexp/no-super-linear-backtracking: [0]
regexp/no-super-linear-move: [0]
regexp/no-trivially-nested-assertion: [2]
regexp/no-trivially-nested-quantifier: [2]
regexp/no-unused-capturing-group: [0]
regexp/no-useless-assertions: [2]
regexp/no-useless-backreference: [2]
regexp/no-useless-character-class: [2]
regexp/no-useless-dollar-replacements: [2]
regexp/no-useless-escape: [2]
regexp/no-useless-flag: [2]
regexp/no-useless-lazy: [2]
regexp/no-useless-non-capturing-group: [2]
regexp/no-useless-quantifier: [2]
regexp/no-useless-range: [2]
regexp/no-useless-set-operand: [2]
regexp/no-useless-string-literal: [2]
regexp/no-useless-two-nums-quantifier: [2]
regexp/no-zero-quantifier: [2]
regexp/optimal-lookaround-quantifier: [2]
regexp/optimal-quantifier-concatenation: [0]
regexp/prefer-character-class: [0]
regexp/prefer-d: [0]
regexp/prefer-escape-replacement-dollar-char: [0]
regexp/prefer-lookaround: [0]
regexp/prefer-named-backreference: [0]
regexp/prefer-named-capture-group: [0]
regexp/prefer-named-replacement: [0]
regexp/prefer-plus-quantifier: [2]
regexp/prefer-predefined-assertion: [2]
regexp/prefer-quantifier: [0]
regexp/prefer-question-quantifier: [2]
regexp/prefer-range: [2]
regexp/prefer-regexp-exec: [2]
regexp/prefer-regexp-test: [2]
regexp/prefer-result-array-groups: [0]
regexp/prefer-set-operation: [2]
regexp/prefer-star-quantifier: [2]
regexp/prefer-unicode-codepoint-escapes: [2]
regexp/prefer-w: [0]
regexp/require-unicode-regexp: [0]
regexp/simplify-set-operations: [2]
regexp/sort-alternatives: [0]
regexp/sort-character-class-elements: [0]
regexp/sort-flags: [0]
regexp/strict: [2]
regexp/unicode-escape: [0]
regexp/use-ignore-case: [0]
require-atomic-updates: [0]
require-await: [0]
require-unicode-regexp: [0]
require-yield: [2]
rest-spread-spacing: [2, never]
semi-spacing: [2, {before: false, after: true}]
semi-style: [2, last]
semi: [2, always, {omitLastInOneLineBlock: true}]
sonarjs/cognitive-complexity: [0]
sonarjs/elseif-without-else: [0]
sonarjs/max-switch-cases: [0]
@ -687,7 +393,7 @@ rules:
sonarjs/no-nested-template-literals: [0]
sonarjs/no-one-iteration-loop: [2]
sonarjs/no-redundant-boolean: [2]
sonarjs/no-redundant-jump: [2]
sonarjs/no-redundant-jump: [0]
sonarjs/no-same-line-conditional: [2]
sonarjs/no-small-switch: [0]
sonarjs/no-unused-collection: [2]
@ -701,8 +407,16 @@ rules:
sort-imports: [0]
sort-keys: [0]
sort-vars: [0]
space-before-blocks: [2, always]
space-in-parens: [2, never]
space-infix-ops: [2]
space-unary-ops: [2]
spaced-comment: [2, always]
strict: [0]
switch-colon-spacing: [2]
symbol-description: [2]
template-curly-spacing: [2, never]
template-tag-spacing: [2, never]
unicode-bom: [2, never]
unicorn/better-regex: [0]
unicorn/catch-error-name: [0]
@ -719,18 +433,17 @@ rules:
unicorn/import-style: [0]
unicorn/new-for-builtins: [2]
unicorn/no-abusive-eslint-disable: [0]
unicorn/no-array-callback-reference: [0]
unicorn/no-array-for-each: [2]
unicorn/no-array-instanceof: [0]
unicorn/no-array-method-this-argument: [2]
unicorn/no-array-push-push: [2]
unicorn/no-array-reduce: [2]
unicorn/no-await-expression-member: [0]
unicorn/no-console-spaces: [0]
unicorn/no-document-cookie: [2]
unicorn/no-empty-file: [2]
unicorn/no-fn-reference-in-iterator: [0]
unicorn/no-for-loop: [0]
unicorn/no-hex-escape: [0]
unicorn/no-instanceof-array: [0]
unicorn/no-invalid-remove-event-listener: [2]
unicorn/no-keyword-prefix: [0]
unicorn/no-lonely-if: [2]
@ -741,14 +454,15 @@ rules:
unicorn/no-null: [0]
unicorn/no-object-as-default-parameter: [0]
unicorn/no-process-exit: [0]
unicorn/no-reduce: [2]
unicorn/no-static-only-class: [2]
unicorn/no-thenable: [2]
unicorn/no-this-assignment: [2]
unicorn/no-typeof-undefined: [2]
unicorn/no-unnecessary-await: [2]
unicorn/no-unnecessary-polyfills: [2]
unicorn/no-unreadable-array-destructuring: [0]
unicorn/no-unreadable-iife: [2]
unicorn/no-unsafe-regex: [0]
unicorn/no-unused-properties: [2]
unicorn/no-useless-fallback-in-spread: [2]
unicorn/no-useless-length-check: [2]
@ -766,19 +480,15 @@ rules:
unicorn/prefer-array-index-of: [2]
unicorn/prefer-array-some: [2]
unicorn/prefer-at: [0]
unicorn/prefer-blob-reading-methods: [2]
unicorn/prefer-code-point: [0]
unicorn/prefer-dataset: [2]
unicorn/prefer-date-now: [2]
unicorn/prefer-default-parameters: [0]
unicorn/prefer-dom-node-append: [2]
unicorn/prefer-dom-node-dataset: [0]
unicorn/prefer-dom-node-remove: [2]
unicorn/prefer-dom-node-text-content: [2]
unicorn/prefer-event-key: [2]
unicorn/prefer-event-target: [2]
unicorn/prefer-export-from: [0]
unicorn/prefer-export-from: [2]
unicorn/prefer-includes: [2]
unicorn/prefer-json-parse-buffer: [0]
unicorn/prefer-keyboard-event-key: [2]
unicorn/prefer-logical-operator-over-ternary: [2]
unicorn/prefer-math-trunc: [2]
unicorn/prefer-modern-dom-apis: [0]
@ -786,7 +496,9 @@ rules:
unicorn/prefer-module: [2]
unicorn/prefer-native-coercion-functions: [2]
unicorn/prefer-negative-index: [2]
unicorn/prefer-node-append: [0]
unicorn/prefer-node-protocol: [2]
unicorn/prefer-node-remove: [0]
unicorn/prefer-number-properties: [0]
unicorn/prefer-object-from-entries: [2]
unicorn/prefer-object-has-own: [0]
@ -795,17 +507,17 @@ rules:
unicorn/prefer-query-selector: [0]
unicorn/prefer-reflect-apply: [0]
unicorn/prefer-regexp-test: [2]
unicorn/prefer-replace-all: [0]
unicorn/prefer-set-has: [0]
unicorn/prefer-set-size: [2]
unicorn/prefer-spread: [0]
unicorn/prefer-string-replace-all: [0]
unicorn/prefer-starts-ends-with: [2]
unicorn/prefer-string-slice: [0]
unicorn/prefer-string-starts-ends-with: [2]
unicorn/prefer-string-trim-start-end: [2]
unicorn/prefer-switch: [0]
unicorn/prefer-ternary: [0]
unicorn/prefer-text-content: [2]
unicorn/prefer-top-level-await: [0]
unicorn/prefer-trim-start-end: [2]
unicorn/prefer-type-error: [0]
unicorn/prevent-abbreviations: [0]
unicorn/relative-url-style: [2]
@ -820,26 +532,7 @@ rules:
use-isnan: [2]
valid-typeof: [2, {requireStringLiterals: true}]
vars-on-top: [0]
wc/attach-shadow-constructor: [2]
wc/define-tag-after-class-definition: [0]
wc/expose-class-on-global: [0]
wc/file-name-matches-element: [2]
wc/guard-define-call: [0]
wc/guard-super-call: [2]
wc/max-elements-per-file: [0]
wc/no-child-traversal-in-attributechangedcallback: [2]
wc/no-child-traversal-in-connectedcallback: [2]
wc/no-closed-shadow-root: [2]
wc/no-constructor-attributes: [2]
wc/no-constructor-params: [2]
wc/no-constructor: [2]
wc/no-customized-built-in-elements: [2]
wc/no-exports-with-element: [0]
wc/no-invalid-element-name: [2]
wc/no-invalid-extends: [2]
wc/no-method-prefixed-with-on: [2]
wc/no-self-class: [2]
wc/no-typos: [2]
wc/require-listener-teardown: [2]
wc/tag-name-matches-class: [2]
wrap-iife: [2, inside]
wrap-regex: [0]
yield-star-spacing: [2, after]
yoda: [2, never]

4
.gitattributes vendored
View File

@ -1,10 +1,8 @@
* text=auto eol=lf
*.tmpl linguist-language=Handlebars
/assets/*.json linguist-generated
/public/assets/img/svg/*.svg linguist-generated
/templates/swagger/v1_json.tmpl linguist-generated
/public/vendor/** -text -eol linguist-vendored
/vendor/** -text -eol linguist-vendored
/web_src/fomantic/build/** linguist-generated
/web_src/fomantic/_site/globals/site.variables linguist-language=Less
/web_src/js/vendor/** -text -eol linguist-vendored
Dockerfile.* linguist-language=Dockerfile

View File

@ -5,7 +5,7 @@
2. Please ask questions or configuration/deploy problems on our Discord
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
3. Please take a moment to check that your issue doesn't already exist.
4. Make sure it's not mentioned in the FAQ (https://docs.gitea.com/help/faq)
4. Make sure it's not mentioned in the FAQ (https://docs.gitea.io/en-us/faq)
5. Please give all relevant information below for bug reports, because
incomplete details will be handled as an invalid report.
-->
@ -26,7 +26,7 @@
- [ ] No
- Log gist:
<!-- It really is important to provide pertinent logs -->
<!-- Please read https://docs.gitea.com/administration/logging-config#collecting-logs-for-help -->
<!-- Please read https://docs.gitea.io/en-us/logging-configuration/#debugging-problems -->
<!-- In addition, if your problem relates to git commands set `RUN_MODE=dev` at the top of app.ini -->
## Description

1
.github/FUNDING.yml vendored
View File

@ -1 +1,2 @@
open_collective: gitea
custom: https://www.bountysource.com/teams/gitea

View File

@ -1,91 +1,94 @@
name: Bug Report
description: Found something you weren't expecting? Report it here!
labels: ["type/bug"]
labels: kind/bug
body:
- type: markdown
attributes:
value: |
NOTE: If your issue is a security concern, please send an email to security@gitea.io instead of opening a public issue.
- type: markdown
attributes:
value: |
1. Please speak English, this is the language all maintainers can speak and write.
2. Please ask questions or configuration/deploy problems on our Discord
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
3. Make sure you are using the latest release and
take a moment to check that your issue hasn't been reported before.
4. Make sure it's not mentioned in the FAQ (https://docs.gitea.com/help/faq)
5. It's really important to provide pertinent details and logs (https://docs.gitea.com/help/support),
incomplete details will be handled as an invalid report.
- type: textarea
id: description
attributes:
label: Description
description: |
Please provide a description of your issue here, with a URL if you were able to reproduce the issue (see below)
If you are using a proxy or a CDN (e.g. Cloudflare) in front of Gitea, please disable the proxy/CDN fully and access Gitea directly to confirm the issue still persists without those services.
- type: input
id: gitea-ver
attributes:
label: Gitea Version
description: Gitea version (or commit reference) of your instance
validations:
required: true
- type: dropdown
id: can-reproduce
attributes:
label: Can you reproduce the bug on the Gitea demo site?
description: |
If so, please provide a URL in the Description field
URL of Gitea demo: https://try.gitea.io
options:
- "Yes"
- "No"
validations:
required: true
- type: markdown
attributes:
value: |
It's really important to provide pertinent logs
Please read https://docs.gitea.com/administration/logging-config#collecting-logs-for-help
In addition, if your problem relates to git commands set `RUN_MODE=dev` at the top of app.ini
- type: input
id: logs
attributes:
label: Log Gist
description: Please provide a gist URL of your logs, with any sensitive information (e.g. API keys) removed/hidden
- type: textarea
id: screenshots
attributes:
label: Screenshots
description: If this issue involves the Web Interface, please provide one or more screenshots
- type: input
id: git-ver
attributes:
label: Git Version
description: The version of git running on the server
- type: input
id: os-ver
attributes:
label: Operating System
description: The operating system you are using to run Gitea
- type: textarea
id: run-info
attributes:
label: How are you running Gitea?
description: |
Please include information on whether you built Gitea yourself, used one of our downloads, are using https://try.gitea.io or are using some other package
Please also tell us how you are running Gitea, e.g. if it is being run from docker, a command-line, systemd etc.
If you are using a package or systemd tell us what distribution you are using
validations:
required: true
- type: dropdown
id: database
attributes:
label: Database
description: What database system are you running?
options:
- PostgreSQL
- MySQL/MariaDB
- MSSQL
- SQLite
- type: markdown
attributes:
value: |
NOTE: If your issue is a security concern, please send an email to security@gitea.io instead of opening a public issue.
- type: markdown
attributes:
value: |
1. Please speak English, this is the language all maintainers can speak and write.
2. Please ask questions or configuration/deploy problems on our Discord
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
3. Make sure you are using the latest release and
take a moment to check that your issue hasn't been reported before.
4. Make sure it's not mentioned in the FAQ (https://docs.gitea.io/en-us/faq)
5. Please give all relevant information below for bug reports, because
incomplete details will be handled as an invalid report.
6. In particular it's really important to provide pertinent logs. You must give us DEBUG level logs.
Please read https://docs.gitea.io/en-us/logging-configuration/#debugging-problems
In addition, if your problem relates to git commands set `RUN_MODE=dev` at the top of app.ini
- type: textarea
id: description
attributes:
label: Description
description: |
Please provide a description of your issue here, with a URL if you were able to reproduce the issue (see below)
If you are using a proxy or a CDN (e.g. Cloudflare) in front of Gitea, please disable the proxy/CDN fully and access Gitea directly to confirm the issue still persists without those services.
- type: input
id: gitea-ver
attributes:
label: Gitea Version
description: Gitea version (or commit reference) of your instance
validations:
required: true
- type: dropdown
id: can-reproduce
attributes:
label: Can you reproduce the bug on the Gitea demo site?
description: |
If so, please provide a URL in the Description field
URL of Gitea demo: https://try.gitea.io
options:
- "Yes"
- "No"
validations:
required: true
- type: markdown
attributes:
value: |
It's really important to provide pertinent logs
Please read https://docs.gitea.io/en-us/logging-configuration/#debugging-problems
In addition, if your problem relates to git commands set `RUN_MODE=dev` at the top of app.ini
- type: input
id: logs
attributes:
label: Log Gist
description: Please provide a gist URL of your logs, with any sensitive information (e.g. API keys) removed/hidden
- type: textarea
id: screenshots
attributes:
label: Screenshots
description: If this issue involves the Web Interface, please provide one or more screenshots
- type: input
id: git-ver
attributes:
label: Git Version
description: The version of git running on the server
- type: input
id: os-ver
attributes:
label: Operating System
description: The operating system you are using to run Gitea
- type: textarea
id: run-info
attributes:
label: How are you running Gitea?
description: |
Please include information on whether you built Gitea yourself, used one of our downloads, are using https://try.gitea.io or are using some other package
Please also tell us how you are running Gitea, e.g. if it is being run from docker, a command-line, systemd etc.
If you are using a package or systemd tell us what distribution you are using
validations:
required: true
- type: dropdown
id: database
attributes:
label: Database
description: What database system are you running?
options:
- PostgreSQL
- MySQL
- MSSQL
- SQLite

View File

@ -8,9 +8,9 @@ contact_links:
about: Please ask questions and discuss configuration or deployment problems here.
- name: Discourse Forum
url: https://discourse.gitea.io
about: Questions and configuration or deployment problems can also be discussed on our forum.
about: Questions and configuration or deployment problems can also be discussed on our forum.
- name: Frequently Asked Questions
url: https://docs.gitea.com/help/faq
url: https://docs.gitea.io/en-us/faq
about: Please check if your question isn't mentioned here.
- name: Crowdin Translations
url: https://crowdin.com/project/gitea

View File

@ -1,24 +1,24 @@
name: Feature Request
description: Got an idea for a feature that Gitea doesn't have currently? Submit your idea here!
labels: ["type/proposal"]
labels: ["kind/feature", "kind/proposal"]
body:
- type: markdown
attributes:
value: |
1. Please speak English, this is the language all maintainers can speak and write.
2. Please ask questions or configuration/deploy problems on our Discord
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
3. Please take a moment to check that your feature hasn't already been suggested.
- type: textarea
id: description
attributes:
label: Feature Description
placeholder: |
I think it would be great if Gitea had...
validations:
required: true
- type: textarea
id: screenshots
attributes:
label: Screenshots
description: If you can, provide screenshots of an implementation on another site e.g. GitHub
- type: markdown
attributes:
value: |
1. Please speak English, this is the language all maintainers can speak and write.
2. Please ask questions or configuration/deploy problems on our Discord
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
3. Please take a moment to check that your feature hasn't already been suggested.
- type: textarea
id: description
attributes:
label: Feature Description
placeholder: |
I think it would be great if Gitea had...
validations:
required: true
- type: textarea
id: screenshots
attributes:
label: Screenshots
description: If you can, provide screenshots of an implementation on another site e.g. GitHub

View File

@ -1,66 +1,66 @@
name: Web Interface Bug Report
description: Something doesn't look quite as it should? Report it here!
labels: ["type/bug", "topic/ui"]
labels: ["kind/bug", "kind/ui"]
body:
- type: markdown
attributes:
value: |
NOTE: If your issue is a security concern, please send an email to security@gitea.io instead of opening a public issue.
- type: markdown
attributes:
value: |
1. Please speak English, this is the language all maintainers can speak and write.
2. Please ask questions or configuration/deploy problems on our Discord
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
3. Please take a moment to check that your issue doesn't already exist.
4. Make sure it's not mentioned in the FAQ (https://docs.gitea.com/help/faq)
5. Please give all relevant information below for bug reports, because
incomplete details will be handled as an invalid report.
6. In particular it's really important to provide pertinent logs. If you are certain that this is a javascript
error, show us the javascript console. If the error appears to relate to Gitea the server you must also give us
DEBUG level logs. (See https://docs.gitea.com/administration/logging-config#collecting-logs-for-help)
- type: textarea
id: description
attributes:
label: Description
description: |
Please provide a description of your issue here, with a URL if you were able to reproduce the issue (see below)
If using a proxy or a CDN (e.g. CloudFlare) in front of gitea, please disable the proxy/CDN fully and connect to gitea directly to confirm the issue still persists without those services.
- type: textarea
id: screenshots
attributes:
label: Screenshots
description: Please provide at least 1 screenshot showing the issue.
validations:
required: true
- type: input
id: gitea-ver
attributes:
label: Gitea Version
description: Gitea version (or commit reference) your instance is running
validations:
required: true
- type: dropdown
id: can-reproduce
attributes:
label: Can you reproduce the bug on the Gitea demo site?
description: |
If so, please provide a URL in the Description field
URL of Gitea demo: https://try.gitea.io
options:
- "Yes"
- "No"
validations:
required: true
- type: input
id: os-ver
attributes:
label: Operating System
description: The operating system you are using to access Gitea
- type: input
id: browser-ver
attributes:
label: Browser Version
description: The browser and version that you are using to access Gitea
validations:
required: true
- type: markdown
attributes:
value: |
NOTE: If your issue is a security concern, please send an email to security@gitea.io instead of opening a public issue.
- type: markdown
attributes:
value: |
1. Please speak English, this is the language all maintainers can speak and write.
2. Please ask questions or configuration/deploy problems on our Discord
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
3. Please take a moment to check that your issue doesn't already exist.
4. Make sure it's not mentioned in the FAQ (https://docs.gitea.io/en-us/faq)
5. Please give all relevant information below for bug reports, because
incomplete details will be handled as an invalid report.
6. In particular it's really important to provide pertinent logs. If you are certain that this is a javascript
error, show us the javascript console. If the error appears to relate to Gitea the server you must also give us
DEBUG level logs. (See https://docs.gitea.io/en-us/logging-configuration/#debugging-problems)
- type: textarea
id: description
attributes:
label: Description
description: |
Please provide a description of your issue here, with a URL if you were able to reproduce the issue (see below)
If using a proxy or a CDN (e.g. CloudFlare) in front of gitea, please disable the proxy/CDN fully and connect to gitea directly to confirm the issue still persists without those services.
- type: textarea
id: screenshots
attributes:
label: Screenshots
description: Please provide at least 1 screenshot showing the issue.
validations:
required: true
- type: input
id: gitea-ver
attributes:
label: Gitea Version
description: Gitea version (or commit reference) your instance is running
validations:
required: true
- type: dropdown
id: can-reproduce
attributes:
label: Can you reproduce the bug on the Gitea demo site?
description: |
If so, please provide a URL in the Description field
URL of Gitea demo: https://try.gitea.io
options:
- "Yes"
- "No"
validations:
required: true
- type: input
id: os-ver
attributes:
label: Operating System
description: The operating system you are using to access Gitea
- type: input
id: browser-ver
attributes:
label: Browser Version
description: The browser and version that you are using to access Gitea
validations:
required: true

View File

@ -1,5 +0,0 @@
self-hosted-runner:
labels:
- actuated-4cpu-8gb
- actuated-4cpu-16gb
- nscloud

84
.github/labeler.yml vendored
View File

@ -1,84 +0,0 @@
modifies/docs:
- changed-files:
- any-glob-to-any-file:
- "**/*.md"
- "docs/**"
modifies/frontend:
- changed-files:
- any-glob-to-any-file:
- "web_src/**"
- "tailwind.config.js"
- "webpack.config.js"
modifies/templates:
- changed-files:
- all-globs-to-any-file:
- "templates/**"
- "!templates/swagger/v1_json.tmpl"
modifies/api:
- changed-files:
- any-glob-to-any-file:
- "routers/api/**"
- "templates/swagger/v1_json.tmpl"
modifies/cli:
- changed-files:
- any-glob-to-any-file:
- "cmd/**"
modifies/translation:
- changed-files:
- any-glob-to-any-file:
- "options/locale/*.ini"
modifies/migrations:
- changed-files:
- any-glob-to-any-file:
- "models/migrations/**"
modifies/internal:
- changed-files:
- any-glob-to-any-file:
- ".air.toml"
- "Makefile"
- "Dockerfile"
- "Dockerfile.rootless"
- ".dockerignore"
- "docker/**"
- ".editorconfig"
- ".eslintrc.yaml"
- ".golangci.yml"
- ".gitpod.yml"
- ".markdownlint.yaml"
- ".spectral.yaml"
- ".stylelintrc.yaml"
- ".yamllint.yaml"
- ".github/**"
- ".gitea/"
- ".devcontainer/**"
- "build.go"
- "build/**"
- "contrib/**"
modifies/dependencies:
- changed-files:
- any-glob-to-any-file:
- "package.json"
- "package-lock.json"
- "poetry.toml"
- "poetry.lock"
- "go.mod"
- "go.sum"
- "pyproject.toml"
modifies/go:
- changed-files:
- any-glob-to-any-file:
- "**/*.go"
modifies/js:
- changed-files:
- any-glob-to-any-file:
- "**/*.js"

23
.github/lock.yml vendored Normal file
View File

@ -0,0 +1,23 @@
# Configuration for Lock Threads - https://github.com/dessant/lock-threads-app
# Number of days of inactivity before a closed issue or pull request is locked
daysUntilLock: 60
# Skip issues and pull requests created before a given timestamp. Timestamp must
# follow ISO 8601 (`YYYY-MM-DD`). `false` is disabled
skipCreatedBefore: false
# Issues and pull requests with these labels will be ignored.
exemptLabels: []
# Label to add before locking, such as `outdated`. `false` is disabled
lockLabel: false
# Comment to post before locking.
lockComment: >
This thread has been automatically locked since there has not been
any recent activity after it was closed. Please open a new issue for
related bugs and link to relevant comments in this thread.
# Assign `resolved` as the reason for locking. Set to `false` to disable
setLockReason: true

54
.github/stale.yml vendored Normal file
View File

@ -0,0 +1,54 @@
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 60
# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
daysUntilClose: 14
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
exemptLabels:
- status/blocked
- kind/security
- lgtm/done
- reviewed/confirmed
- priority/critical
- kind/proposal
# Set to true to ignore issues in a project (defaults to false)
exemptProjects: false
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: false
# Label to use when marking as stale
staleLabel: stale
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had recent activity.
I am here to help clear issues left open even if solved or waiting for more insight.
This issue will be closed if no further activity occurs during the next 2 weeks.
If the issue is still valid just add a comment to keep it alive.
Thank you for your contributions.
# Comment to post when closing a stale Issue or Pull Request.
closeComment: >
This issue has been automatically closed because of inactivity.
You can re-open it if needed.
# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 1
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
pulls:
daysUntilStale: 60
daysUntilClose: 60
markComment: >
This pull request has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs during the next 2 months. Thank you
for your contributions.
closeComment: >
This pull request has been automatically closed because of inactivity.
You can re-open it if needed.

View File

@ -1,29 +0,0 @@
name: cron-licenses
on:
schedule:
- cron: "7 0 * * 1" # every Monday at 00:07 UTC
workflow_dispatch:
jobs:
cron-licenses:
runs-on: ubuntu-latest
if: github.repository == 'go-gitea/gitea'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- run: make generate-license generate-gitignore
timeout-minutes: 40
- name: push translations to repo
uses: appleboy/git-push-action@v0.0.3
with:
author_email: "teabot@gitea.io"
author_name: GiteaBot
branch: main
commit: true
commit_message: "[skip ci] Updated licenses and gitignores"
remote: "git@github.com:go-gitea/gitea.git"
ssh_key: ${{ secrets.DEPLOY_KEY }}

View File

@ -1,23 +0,0 @@
name: cron-lock
on:
schedule:
- cron: "0 0 * * *" # every day at 00:00 UTC
workflow_dispatch:
permissions:
issues: write
pull-requests: write
concurrency:
group: lock
jobs:
action:
runs-on: ubuntu-latest
if: github.repository == 'go-gitea/gitea'
steps:
- uses: dessant/lock-threads@v5
with:
issue-inactive-days: 10
pr-inactive-days: 7

View File

@ -1,49 +0,0 @@
name: cron-translations
on:
schedule:
- cron: "7 0 * * *" # every day at 00:07 UTC
workflow_dispatch:
jobs:
crowdin-pull:
runs-on: ubuntu-latest
if: github.repository == 'go-gitea/gitea'
steps:
- uses: actions/checkout@v4
- name: download from crowdin
uses: docker://jonasfranz/crowdin
env:
CROWDIN_KEY: ${{ secrets.CROWDIN_KEY }}
PLUGIN_DOWNLOAD: true
PLUGIN_EXPORT_DIR: options/locale/
PLUGIN_IGNORE_BRANCH: true
PLUGIN_PROJECT_IDENTIFIER: gitea
- name: update locales
run: ./build/update-locales.sh
- name: push translations to repo
uses: appleboy/git-push-action@v0.0.3
with:
author_email: "teabot@gitea.io"
author_name: GiteaBot
branch: main
commit: true
commit_message: "[skip ci] Updated translations via Crowdin"
remote: "git@github.com:go-gitea/gitea.git"
ssh_key: ${{ secrets.DEPLOY_KEY }}
crowdin-push:
runs-on: ubuntu-latest
if: github.repository == 'go-gitea/gitea'
steps:
- uses: actions/checkout@v4
- name: push translations to crowdin
uses: docker://jonasfranz/crowdin
env:
CROWDIN_KEY: ${{ secrets.CROWDIN_KEY }}
PLUGIN_UPLOAD: true
PLUGIN_EXPORT_DIR: options/locale/
PLUGIN_IGNORE_BRANCH: true
PLUGIN_PROJECT_IDENTIFIER: gitea
PLUGIN_FILES: |
locale_en-US.ini: options/locale/locale_en-US.ini
PLUGIN_BRANCH: main

View File

@ -1,25 +0,0 @@
name: disk-clean
on:
workflow_call:
jobs:
triage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
with:
# this might remove tools that are actually needed,
# if set to "true" but frees about 6 GB
tool-cache: false
# all of these default to true, but feel free to set to
# "false" if necessary for your workflow
android: true
dotnet: true
haskell: true
large-packages: false
docker-images: false
swap-storage: true

View File

@ -1,98 +0,0 @@
name: files-changed
on:
workflow_call:
outputs:
backend:
value: ${{ jobs.detect.outputs.backend }}
frontend:
value: ${{ jobs.detect.outputs.frontend }}
docs:
value: ${{ jobs.detect.outputs.docs }}
actions:
value: ${{ jobs.detect.outputs.actions }}
templates:
value: ${{ jobs.detect.outputs.templates }}
docker:
value: ${{ jobs.detect.outputs.docker }}
swagger:
value: ${{ jobs.detect.outputs.swagger }}
yaml:
value: ${{ jobs.detect.outputs.yaml }}
jobs:
detect:
runs-on: ubuntu-latest
timeout-minutes: 3
outputs:
backend: ${{ steps.changes.outputs.backend }}
frontend: ${{ steps.changes.outputs.frontend }}
docs: ${{ steps.changes.outputs.docs }}
actions: ${{ steps.changes.outputs.actions }}
templates: ${{ steps.changes.outputs.templates }}
docker: ${{ steps.changes.outputs.docker }}
swagger: ${{ steps.changes.outputs.swagger }}
yaml: ${{ steps.changes.outputs.yaml }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: changes
with:
filters: |
backend:
- "**/*.go"
- "templates/**/*.tmpl"
- "assets/emoji.json"
- "go.mod"
- "go.sum"
- "Makefile"
- ".golangci.yml"
- ".editorconfig"
- "options/locale/locale_en-US.ini"
frontend:
- "**/*.js"
- "web_src/**"
- "assets/emoji.json"
- "package.json"
- "package-lock.json"
- "Makefile"
- ".eslintrc.yaml"
- ".stylelintrc.yaml"
- ".npmrc"
docs:
- "**/*.md"
- "docs/**"
- ".markdownlint.yaml"
- "package.json"
- "package-lock.json"
actions:
- ".github/workflows/*"
- "Makefile"
templates:
- "templates/**/*.tmpl"
- "pyproject.toml"
- "poetry.lock"
docker:
- "Dockerfile"
- "Dockerfile.rootless"
- "docker/**"
- "Makefile"
swagger:
- "templates/swagger/v1_json.tmpl"
- "Makefile"
- "package.json"
- "package-lock.json"
- ".spectral.yaml"
yaml:
- "**/*.yml"
- "**/*.yaml"
- ".yamllint.yaml"
- "pyproject.toml"
- "poetry.lock"

View File

@ -1,194 +0,0 @@
name: compliance
on:
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
files-changed:
uses: ./.github/workflows/files-changed.yml
lint-backend:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- run: make deps-backend deps-tools
- run: make lint-backend
env:
TAGS: bindata sqlite sqlite_unlock_notify
lint-templates:
if: needs.files-changed.outputs.templates == 'true'
needs: files-changed
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install poetry
- run: make deps-py
- run: make lint-templates
lint-yaml:
if: needs.files-changed.outputs.yaml == 'true'
needs: files-changed
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install poetry
- run: make deps-py
- run: make lint-yaml
lint-swagger:
if: needs.files-changed.outputs.swagger == 'true'
needs: files-changed
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: make deps-frontend
- run: make lint-swagger
lint-spell:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.frontend == 'true' || needs.files-changed.outputs.actions == 'true' || needs.files-changed.outputs.docs == 'true' || needs.files-changed.outputs.templates == 'true'
needs: files-changed
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- run: make lint-spell
lint-go-windows:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- run: make deps-backend deps-tools
- run: make lint-go-windows lint-go-vet
env:
TAGS: bindata sqlite sqlite_unlock_notify
GOOS: windows
GOARCH: amd64
lint-go-gogit:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- run: make deps-backend deps-tools
- run: make lint-go
env:
TAGS: bindata gogit sqlite sqlite_unlock_notify
checks-backend:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- run: make deps-backend deps-tools
- run: make --always-make checks-backend # ensure the "go-licenses" make target runs
frontend:
if: needs.files-changed.outputs.frontend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: make deps-frontend
- run: make lint-frontend
- run: make checks-frontend
- run: make test-frontend
- run: make frontend
backend:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
# no frontend build here as backend should be able to build
# even without any frontend files
- run: make deps-backend
- run: go build -o gitea_no_gcc # test if build succeeds without the sqlite tag
- name: build-backend-arm64
run: make backend # test cross compile
env:
GOOS: linux
GOARCH: arm64
TAGS: bindata gogit
- name: build-backend-windows
run: go build -o gitea_windows
env:
GOOS: windows
GOARCH: amd64
TAGS: bindata gogit
- name: build-backend-386
run: go build -o gitea_linux_386 # test if compatible with 32 bit
env:
GOOS: linux
GOARCH: 386
docs:
if: needs.files-changed.outputs.docs == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: make deps-frontend
- run: make lint-md
- run: make docs
actions:
if: needs.files-changed.outputs.actions == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- run: make lint-actions

View File

@ -1,225 +0,0 @@
name: db-tests
on:
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
files-changed:
uses: ./.github/workflows/files-changed.yml
test-pgsql:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
services:
pgsql:
image: postgres:12
env:
POSTGRES_DB: test
POSTGRES_PASSWORD: postgres
ports:
- "5432:5432"
ldap:
image: gitea/test-openldap:latest
ports:
- "389:389"
- "636:636"
minio:
# as github actions doesn't support "entrypoint", we need to use a non-official image
# that has a custom entrypoint set to "minio server /data"
image: bitnami/minio:2023.8.31
env:
MINIO_ROOT_USER: 123456
MINIO_ROOT_PASSWORD: 12345678
ports:
- "9000:9000"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- name: Add hosts to /etc/hosts
run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 pgsql ldap minio" | sudo tee -a /etc/hosts'
- run: make deps-backend
- run: make backend
env:
TAGS: bindata
- name: run migration tests
run: make test-pgsql-migration
- name: run tests
run: make test-pgsql
timeout-minutes: 50
env:
TAGS: bindata gogit
RACE_ENABLED: true
TEST_TAGS: gogit
TEST_LDAP: 1
USE_REPO_TEST_DIR: 1
test-sqlite:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- run: make deps-backend
- run: make backend
env:
TAGS: bindata gogit sqlite sqlite_unlock_notify
- name: run migration tests
run: make test-sqlite-migration
- name: run tests
run: make test-sqlite
timeout-minutes: 50
env:
TAGS: bindata gogit sqlite sqlite_unlock_notify
RACE_ENABLED: true
TEST_TAGS: gogit sqlite sqlite_unlock_notify
USE_REPO_TEST_DIR: 1
test-unit:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
services:
elasticsearch:
image: elasticsearch:7.5.0
env:
discovery.type: single-node
ports:
- "9200:9200"
meilisearch:
image: getmeili/meilisearch:v1.2.0
env:
MEILI_ENV: development # disable auth
ports:
- "7700:7700"
redis:
image: redis
options: >- # wait until redis has started
--health-cmd "redis-cli ping"
--health-interval 5s
--health-timeout 3s
--health-retries 10
ports:
- 6379:6379
minio:
image: bitnami/minio:2021.3.17
env:
MINIO_ACCESS_KEY: 123456
MINIO_SECRET_KEY: 12345678
ports:
- "9000:9000"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- name: Add hosts to /etc/hosts
run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 mysql elasticsearch meilisearch smtpimap" | sudo tee -a /etc/hosts'
- run: make deps-backend
- run: make backend
env:
TAGS: bindata
- name: unit-tests
run: make unit-test-coverage test-check
env:
TAGS: bindata
RACE_ENABLED: true
GITHUB_READ_TOKEN: ${{ secrets.GITHUB_READ_TOKEN }}
- name: unit-tests-gogit
run: make unit-test-coverage test-check
env:
TAGS: bindata gogit
RACE_ENABLED: true
GITHUB_READ_TOKEN: ${{ secrets.GITHUB_READ_TOKEN }}
test-mysql:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
services:
mysql:
image: mysql:8.0
env:
MYSQL_ALLOW_EMPTY_PASSWORD: true
MYSQL_DATABASE: testgitea
ports:
- "3306:3306"
elasticsearch:
image: elasticsearch:7.5.0
env:
discovery.type: single-node
ports:
- "9200:9200"
smtpimap:
image: tabascoterrier/docker-imap-devel:latest
ports:
- "25:25"
- "143:143"
- "587:587"
- "993:993"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- name: Add hosts to /etc/hosts
run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 mysql elasticsearch smtpimap" | sudo tee -a /etc/hosts'
- run: make deps-backend
- run: make backend
env:
TAGS: bindata
- name: run migration tests
run: make test-mysql-migration
- name: run tests
run: make integration-test-coverage
env:
TAGS: bindata
RACE_ENABLED: true
USE_REPO_TEST_DIR: 1
TEST_INDEXER_CODE_ES_URL: "http://elastic:changeme@elasticsearch:9200"
test-mssql:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
services:
mssql:
image: mcr.microsoft.com/mssql/server:2017-latest
env:
ACCEPT_EULA: Y
MSSQL_PID: Standard
SA_PASSWORD: MwantsaSecurePassword1
ports:
- "1433:1433"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- name: Add hosts to /etc/hosts
run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 mssql" | sudo tee -a /etc/hosts'
- run: make deps-backend
- run: make backend
env:
TAGS: bindata
- run: make test-mssql-migration
- name: run tests
run: make test-mssql
timeout-minutes: 50
env:
TAGS: bindata
USE_REPO_TEST_DIR: 1

View File

@ -1,35 +0,0 @@
name: docker-dryrun
on:
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
files-changed:
uses: ./.github/workflows/files-changed.yml
regular:
if: needs.files-changed.outputs.docker == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
steps:
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v5
with:
push: false
tags: gitea/gitea:linux-amd64
rootless:
if: needs.files-changed.outputs.docker == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
steps:
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v5
with:
push: false
file: Dockerfile.rootless
tags: gitea/gitea:linux-amd64

View File

@ -1,32 +0,0 @@
name: e2e-tests
on:
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
files-changed:
uses: ./.github/workflows/files-changed.yml
test-e2e:
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.frontend == 'true' || needs.files-changed.outputs.actions == 'true'
needs: files-changed
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- uses: actions/setup-node@v4
with:
node-version: 20
- run: make deps-frontend frontend deps-backend
- run: npx playwright install --with-deps
- run: make test-e2e-sqlite
timeout-minutes: 40
env:
USE_REPO_TEST_DIR: 1

View File

@ -1,20 +0,0 @@
name: labeler
on:
pull_request_target:
types: [opened, synchronize, reopened]
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
labeler:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/labeler@v5
with:
sync-labels: true

View File

@ -1,134 +0,0 @@
name: release-nightly
on:
push:
branches: [main, release/v*]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
disk-clean:
uses: ./.github/workflows/disk-clean.yml
nightly-binary:
runs-on: nscloud
steps:
- uses: actions/checkout@v4
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- uses: actions/setup-node@v4
with:
node-version: 20
- run: make deps-frontend deps-backend
# xgo build
- run: make release
env:
TAGS: bindata sqlite sqlite_unlock_notify
- name: import gpg key
id: import_gpg
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPGSIGN_KEY }}
passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }}
- name: sign binaries
run: |
for f in dist/release/*; do
echo '${{ secrets.GPGSIGN_PASSPHRASE }}' | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --yes --detach-sign -u ${{ steps.import_gpg.outputs.fingerprint }} --output "$f.asc" "$f"
done
# clean branch name to get the folder name in S3
- name: Get cleaned branch name
id: clean_name
run: |
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//')
echo "Cleaned name is ${REF_NAME}"
echo "branch=${REF_NAME}" >> "$GITHUB_OUTPUT"
- name: configure aws
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ secrets.AWS_REGION }}
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: upload binaries to s3
run: |
aws s3 sync dist/release s3://${{ secrets.AWS_S3_BUCKET }}/gitea/${{ steps.clean_name.outputs.branch }} --no-progress
nightly-docker-rootful:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- name: Get cleaned branch name
id: clean_name
run: |
# if main then say nightly otherwise cleanup name
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
echo "branch=nightly" >> "$GITHUB_OUTPUT"
exit 0
fi
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//')
echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT"
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: fetch go modules
run: make vendor
- name: build rootful docker image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: gitea/gitea:${{ steps.clean_name.outputs.branch }}
nightly-docker-rootless:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- name: Get cleaned branch name
id: clean_name
run: |
# if main then say nightly otherwise cleanup name
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
echo "branch=nightly" >> "$GITHUB_OUTPUT"
exit 0
fi
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//')
echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT"
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: fetch go modules
run: make vendor
- name: build rootless docker image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
file: Dockerfile.rootless
tags: gitea/gitea:${{ steps.clean_name.outputs.branch }}-rootless

View File

@ -1,132 +0,0 @@
name: release-tag-rc
on:
push:
tags:
- "v1*-rc*"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
jobs:
binary:
runs-on: nscloud
steps:
- uses: actions/checkout@v4
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- uses: actions/setup-node@v4
with:
node-version: 20
- run: make deps-frontend deps-backend
# xgo build
- run: make release
env:
TAGS: bindata sqlite sqlite_unlock_notify
- name: import gpg key
id: import_gpg
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPGSIGN_KEY }}
passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }}
- name: sign binaries
run: |
for f in dist/release/*; do
echo '${{ secrets.GPGSIGN_PASSPHRASE }}' | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --yes --detach-sign -u ${{ steps.import_gpg.outputs.fingerprint }} --output "$f.asc" "$f"
done
# clean branch name to get the folder name in S3
- name: Get cleaned branch name
id: clean_name
run: |
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\/v//' -e 's/release\/v//')
echo "Cleaned name is ${REF_NAME}"
echo "branch=${REF_NAME}" >> "$GITHUB_OUTPUT"
- name: configure aws
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ secrets.AWS_REGION }}
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: upload binaries to s3
run: |
aws s3 sync dist/release s3://${{ secrets.AWS_S3_BUCKET }}/gitea/${{ steps.clean_name.outputs.branch }} --no-progress
- name: Install GH CLI
uses: dev-hanz-ops/install-gh-cli-action@v0.1.0
with:
gh-cli-version: 2.39.1
- name: create github release
run: |
gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --draft --notes-from-tag dist/release/*
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
docker-rootful:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/metadata-action@v5
id: meta
with:
images: gitea/gitea
flavor: |
latest=false
# 1.2.3-rc0
tags: |
type=semver,pattern={{version}}
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: build rootful docker image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
docker-rootless:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/metadata-action@v5
id: meta
with:
images: gitea/gitea
# each tag below will have the suffix of -rootless
flavor: |
latest=false
suffix=-rootless
# 1.2.3-rc0
tags: |
type=semver,pattern={{version}}
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: build rootless docker image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
file: Dockerfile.rootless
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View File

@ -1,143 +0,0 @@
name: release-tag-version
on:
push:
tags:
- "v1.*"
- "!v1*-rc*"
- "!v1*-dev"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
jobs:
binary:
runs-on: nscloud
steps:
- uses: actions/checkout@v4
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
- uses: actions/setup-node@v4
with:
node-version: 20
- run: make deps-frontend deps-backend
# xgo build
- run: make release
env:
TAGS: bindata sqlite sqlite_unlock_notify
- name: import gpg key
id: import_gpg
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPGSIGN_KEY }}
passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }}
- name: sign binaries
run: |
for f in dist/release/*; do
echo '${{ secrets.GPGSIGN_PASSPHRASE }}' | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --yes --detach-sign -u ${{ steps.import_gpg.outputs.fingerprint }} --output "$f.asc" "$f"
done
# clean branch name to get the folder name in S3
- name: Get cleaned branch name
id: clean_name
run: |
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\/v//' -e 's/release\/v//')
echo "Cleaned name is ${REF_NAME}"
echo "branch=${REF_NAME}" >> "$GITHUB_OUTPUT"
- name: configure aws
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ secrets.AWS_REGION }}
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: upload binaries to s3
run: |
aws s3 sync dist/release s3://${{ secrets.AWS_S3_BUCKET }}/gitea/${{ steps.clean_name.outputs.branch }} --no-progress
- name: Install GH CLI
uses: dev-hanz-ops/install-gh-cli-action@v0.1.0
with:
gh-cli-version: 2.39.1
- name: create github release
run: |
gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --notes-from-tag dist/release/*
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
docker-rootful:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/metadata-action@v5
id: meta
with:
images: gitea/gitea
# this will generate tags in the following format:
# latest
# 1
# 1.2
# 1.2.3
tags: |
type=semver,pattern={{major}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{version}}
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: build rootful docker image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
docker-rootless:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
- run: git fetch --unshallow --quiet --tags --force
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/metadata-action@v5
id: meta
with:
images: gitea/gitea
# each tag below will have the suffix of -rootless
flavor: |
suffix=-rootless,onlatest=true
# this will generate tags in the following format (with -rootless suffix added):
# latest
# 1
# 1.2
# 1.2.3
tags: |
type=semver,pattern={{major}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{version}}
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: build rootless docker image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
file: Dockerfile.rootless
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

23
.gitignore vendored
View File

@ -11,11 +11,14 @@ _test
.idea
# Goland's output filename can not be set manually
/go_build_*
/gitea_*
# MS VSCode
.vscode
__debug_bin*
__debug_bin
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
@ -44,7 +47,6 @@ cpu.out
*.db
*.log
*.log.*.gz
/gitea
/gitea-vet
@ -54,6 +56,8 @@ cpu.out
/bin
/dist
/custom/*
!/custom/conf
/custom/conf/*
!/custom/conf/app.example.ini
/data
/indexers
@ -67,17 +71,15 @@ cpu.out
/tests/e2e/test-artifacts
/tests/e2e/test-snapshots
/tests/*.ini
/tests/**/*.git/**/*.sample
/node_modules
/.venv
/yarn.lock
/yarn-error.log
/npm-debug.log*
/public/assets/js
/public/assets/css
/public/assets/fonts
/public/assets/licenses.txt
/public/assets/img/webpack
/public/js
/public/serviceworker.js
/public/css
/public/fonts
/public/img/webpack
/vendor
/web_src/fomantic/node_modules
/web_src/fomantic/build/*
@ -96,7 +98,6 @@ cpu.out
/.go-licenses
# Snapcraft
/gitea_a*.txt
snap/.snapcraft/
parts/
stage/

View File

@ -10,21 +10,9 @@ tasks:
- name: Run backend
command: |
gp sync-await setup
# Get the URL and extract the domain
url=$(gp url 3000)
domain=$(echo $url | awk -F[/:] '{print $4}')
if [ -f custom/conf/app.ini ]; then
sed -i "s|^ROOT_URL =.*|ROOT_URL = ${url}/|" custom/conf/app.ini
sed -i "s|^DOMAIN =.*|DOMAIN = ${domain}|" custom/conf/app.ini
sed -i "s|^SSH_DOMAIN =.*|SSH_DOMAIN = ${domain}|" custom/conf/app.ini
sed -i "s|^NO_REPLY_ADDRESS =.*|SSH_DOMAIN = noreply.${domain}|" custom/conf/app.ini
else
mkdir -p custom/conf/
echo -e "[server]\nROOT_URL = ${url}/" > custom/conf/app.ini
echo -e "\n[database]\nDB_TYPE = sqlite3\nPATH = $GITPOD_REPO_ROOT/data/gitea.db" >> custom/conf/app.ini
fi
mkdir -p custom/conf/
echo -e "[server]\nROOT_URL=$(gp url 3000)/" > custom/conf/app.ini
echo -e "\n[database]\nDB_TYPE = sqlite3\nPATH = $GITPOD_REPO_ROOT/data/gitea.db" >> custom/conf/app.ini
export TAGS="sqlite sqlite_unlock_notify"
make watch-backend
- name: Run frontend
@ -32,6 +20,10 @@ tasks:
gp sync-await setup
make watch-frontend
openMode: split-right
- name: Run docs
before: sudo bash -c "$(grep 'https://github.com/gohugoio/hugo/releases/download' Makefile | tr -d '\')" # install hugo
command: cd docs && make clean update && hugo server -D -F --baseUrl $(gp url 1313) --liveReloadPort=443 --appendPort=false --bind=0.0.0.0
openMode: split-right
vscode:
extensions:
@ -40,12 +32,13 @@ vscode:
- golang.go
- stylelint.vscode-stylelint
- DavidAnson.vscode-markdownlint
- Vue.volar
- johnsoncodehk.volar
- ms-azuretools.vscode-docker
- zixuanchen.vitest-explorer
- qwtel.sqlite-viewer
- GitHub.vscode-pull-request-github
- alexcvzz.vscode-sqlite
ports:
- name: Gitea
port: 3000
- name: Docs
port: 1313

View File

@ -5,7 +5,6 @@ linters:
- depguard
- dupl
- errcheck
- forbidigo
- gocritic
# - gocyclo # The cyclomatic complexety of a lot of functions is too high, we should refactor those another time.
- gofmt
@ -23,12 +22,13 @@ linters:
- unconvert
- unused
# - varcheck # deprecated - https://github.com/golangci/golangci-lint/issues/1841
- wastedassign
# - wastedassign # disabled - https://github.com/golangci/golangci-lint/issues/2649
enable-all: false
disable-all: true
fast: false
run:
go: "1.20"
timeout: 10m
skip-dirs:
- node_modules
@ -74,22 +74,17 @@ linters-settings:
- name: modifies-value-receiver
gofumpt:
extra-rules: true
lang-version: "1.20"
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
list-type: denylist
# Check the list against standard lib.
include-go-root: true
packages-with-error-message:
- encoding/json: "use gitea's modules/json instead of encoding/json"
- github.com/unknwon/com: "use gitea's util and replacements"
- io/ioutil: "use os or io instead"
- golang.org/x/exp: "it's experimental and unreliable."
- code.gitea.io/gitea/modules/git/internal: "do not use the internal package, use AddXxx function instead"
issues:
max-issues-per-linter: 0
@ -110,25 +105,73 @@ issues:
- errcheck
- dupl
- gosec
- path: cmd
linters:
- forbidigo
- linters:
- dupl
text: "webhook"
- linters:
- gocritic
text: "`ID' should not be capitalized"
- path: modules/templates/helper.go
linters:
- gocritic
- linters:
- unused
- deadcode
text: "swagger"
- path: contrib/pr/checkout.go
linters:
- errcheck
- path: models/issue.go
linters:
- errcheck
- path: models/migrations/
linters:
- errcheck
- path: modules/log/
linters:
- errcheck
- path: routers/api/v1/repo/issue_subscription.go
linters:
- dupl
- path: routers/repo/view.go
linters:
- dupl
- path: models/migrations/
linters:
- unused
- linters:
- staticcheck
text: "argument x is overwritten before first use"
- path: modules/httplib/httplib.go
linters:
- staticcheck
# Enabling this would require refactoring the methods and how they are called.
- path: models/issue_comment_list.go
linters:
- dupl
- path: models/update.go
linters:
- unused
- path: cmd/dump.go
linters:
- dupl
- path: services/webhook/webhook.go
linters:
- structcheck
- text: "commentFormatting: put a space between `//` and comment text"
linters:
- gocritic
- text: "exitAfterDefer:"
linters:
- gocritic
- path: modules/graceful/manager_windows.go
linters:
- staticcheck
text: "svc.IsAnInteractiveSession is deprecated: Use IsWindowsService instead."
- path: models/user/openid.go
linters:
- golint
- path: models/user/badge.go
linters:
- revive
text: "exported: type name will be used as user.UserBadge by other packages, and that stutters; consider calling this Badge"

View File

@ -1,9 +1,8 @@
*.min.css
*.min.js
/assets/*.json
/modules/options/bindata.go
/modules/public/bindata.go
/modules/templates/bindata.go
/public/vendor/plugins
/vendor
/public/assets
node_modules

3
.lgtm Normal file
View File

@ -0,0 +1,3 @@
pattern = "(?)LGTM"
self_approval_off = true
ignore_maintainers_file = true

View File

@ -1,15 +1,18 @@
commands-show-output: false
fenced-code-language: false
first-line-h1: false
heading-increment: false
header-increment: false
line-length: {code_blocks: false, tables: false, stern: true, line_length: -1}
no-alt-text: false
no-bare-urls: false
no-emphasis-as-heading: false
no-blanks-blockquote: false
no-duplicate-header: {allow_different_nesting: true}
no-emphasis-as-header: false
no-empty-links: false
no-hard-tabs: {code_blocks: false}
no-inline-html: false
no-space-in-code: false
no-space-in-emphasis: false
no-trailing-punctuation: false
no-trailing-spaces: {br_spaces: 0}
single-h1: false

1
.npmrc
View File

@ -3,4 +3,3 @@ fund=false
update-notifier=false
package-lock=true
save-exact=true
lockfile-version=3

View File

@ -1,105 +1,24 @@
plugins:
- stylelint-declaration-strict-value
- stylelint-declaration-block-no-ignored-properties
- "@stylistic/stylelint-plugin"
ignoreFiles:
- "**/*.go"
overrides:
- files: ["**/chroma/*", "**/codemirror/*", "**/standalone/*", "**/console.css", "font_i18n.css"]
- files: ["**/chroma/*", "**/codemirror/*", "**/standalone/*", "**/console/*"]
rules:
scale-unlimited/declaration-strict-value: null
- files: ["**/chroma/*", "**/codemirror/*"]
rules:
block-no-empty: null
- files: ["**/*.vue"]
customSyntax: postcss-html
rules:
"@stylistic/at-rule-name-case": null
"@stylistic/at-rule-name-newline-after": null
"@stylistic/at-rule-name-space-after": null
"@stylistic/at-rule-semicolon-newline-after": null
"@stylistic/at-rule-semicolon-space-before": null
"@stylistic/block-closing-brace-empty-line-before": null
"@stylistic/block-closing-brace-newline-after": null
"@stylistic/block-closing-brace-newline-before": null
"@stylistic/block-closing-brace-space-after": null
"@stylistic/block-closing-brace-space-before": null
"@stylistic/block-opening-brace-newline-after": null
"@stylistic/block-opening-brace-newline-before": null
"@stylistic/block-opening-brace-space-after": null
"@stylistic/block-opening-brace-space-before": null
"@stylistic/color-hex-case": lower
"@stylistic/declaration-bang-space-after": never
"@stylistic/declaration-bang-space-before": null
"@stylistic/declaration-block-semicolon-newline-after": null
"@stylistic/declaration-block-semicolon-newline-before": null
"@stylistic/declaration-block-semicolon-space-after": null
"@stylistic/declaration-block-semicolon-space-before": never
"@stylistic/declaration-block-trailing-semicolon": null
"@stylistic/declaration-colon-newline-after": null
"@stylistic/declaration-colon-space-after": null
"@stylistic/declaration-colon-space-before": never
"@stylistic/function-comma-newline-after": null
"@stylistic/function-comma-newline-before": null
"@stylistic/function-comma-space-after": null
"@stylistic/function-comma-space-before": null
"@stylistic/function-max-empty-lines": 0
"@stylistic/function-parentheses-newline-inside": never-multi-line
"@stylistic/function-parentheses-space-inside": null
"@stylistic/function-whitespace-after": null
"@stylistic/indentation": 2
"@stylistic/linebreaks": null
"@stylistic/max-empty-lines": 1
"@stylistic/max-line-length": null
"@stylistic/media-feature-colon-space-after": null
"@stylistic/media-feature-colon-space-before": never
"@stylistic/media-feature-name-case": null
"@stylistic/media-feature-parentheses-space-inside": null
"@stylistic/media-feature-range-operator-space-after": always
"@stylistic/media-feature-range-operator-space-before": always
"@stylistic/media-query-list-comma-newline-after": null
"@stylistic/media-query-list-comma-newline-before": null
"@stylistic/media-query-list-comma-space-after": null
"@stylistic/media-query-list-comma-space-before": null
"@stylistic/named-grid-areas-alignment": null
"@stylistic/no-empty-first-line": null
"@stylistic/no-eol-whitespace": true
"@stylistic/no-extra-semicolons": true
"@stylistic/no-missing-end-of-source-newline": null
"@stylistic/number-leading-zero": null
"@stylistic/number-no-trailing-zeros": null
"@stylistic/property-case": lower
"@stylistic/selector-attribute-brackets-space-inside": null
"@stylistic/selector-attribute-operator-space-after": null
"@stylistic/selector-attribute-operator-space-before": null
"@stylistic/selector-combinator-space-after": null
"@stylistic/selector-combinator-space-before": null
"@stylistic/selector-descendant-combinator-no-non-space": null
"@stylistic/selector-list-comma-newline-after": null
"@stylistic/selector-list-comma-newline-before": null
"@stylistic/selector-list-comma-space-after": always-single-line
"@stylistic/selector-list-comma-space-before": never-single-line
"@stylistic/selector-max-empty-lines": 0
"@stylistic/selector-pseudo-class-case": lower
"@stylistic/selector-pseudo-class-parentheses-space-inside": never
"@stylistic/selector-pseudo-element-case": lower
"@stylistic/string-quotes": double
"@stylistic/unicode-bom": null
"@stylistic/unit-case": lower
"@stylistic/value-list-comma-newline-after": null
"@stylistic/value-list-comma-newline-before": null
"@stylistic/value-list-comma-space-after": null
"@stylistic/value-list-comma-space-before": null
"@stylistic/value-list-max-empty-lines": 0
alpha-value-notation: null
annotation-no-unknown: true
at-rule-allowed-list: null
at-rule-disallowed-list: null
at-rule-empty-line-before: null
at-rule-no-unknown: [true, {ignoreAtRules: [tailwind]}]
at-rule-no-unknown: true
at-rule-no-vendor-prefix: true
at-rule-property-required-list: null
block-no-empty: true
@ -127,7 +46,7 @@ rules:
declaration-no-important: null
declaration-property-max-values: null
declaration-property-unit-allowed-list: null
declaration-property-unit-disallowed-list: {line-height: [em]}
declaration-property-unit-disallowed-list: null
declaration-property-value-allowed-list: null
declaration-property-value-disallowed-list: null
declaration-property-value-no-unknown: true
@ -151,7 +70,7 @@ rules:
keyframe-declaration-no-important: true
keyframe-selector-notation: null
keyframes-name-pattern: null
length-zero-no-unit: [true, ignore: [custom-properties], ignoreFunctions: [var]]
length-zero-no-unit: true
max-nesting-depth: null
media-feature-name-allowed-list: null
media-feature-name-disallowed-list: null
@ -159,9 +78,7 @@ rules:
media-feature-name-no-vendor-prefix: true
media-feature-name-unit-allowed-list: null
media-feature-name-value-allowed-list: null
media-feature-name-value-no-unknown: true
media-feature-range-notation: null
media-query-no-invalid: true
named-grid-areas-no-invalid: true
no-descending-specificity: null
no-duplicate-at-import-rules: true
@ -171,16 +88,14 @@ rules:
no-invalid-position-at-import-rule: null
no-irregular-whitespace: true
no-unknown-animations: null
no-unknown-custom-properties: null
number-max-precision: null
plugin/declaration-block-no-ignored-properties: true
property-allowed-list: null
property-disallowed-list: null
property-no-unknown: true
property-no-vendor-prefix: null
rule-empty-line-before: null
rule-selector-property-disallowed-list: null
scale-unlimited/declaration-strict-value: [[/color$/, font-weight], {ignoreValues: /^(inherit|transparent|unset|initial|currentcolor|none)$/, ignoreFunctions: false, disableFix: true, expandShorthand: true}]
scale-unlimited/declaration-strict-value: [color, {ignoreValues: /^(inherit|transparent|unset|initial|currentcolor)$/}]
selector-attribute-name-disallowed-list: null
selector-attribute-operator-allowed-list: null
selector-attribute-operator-disallowed-list: null

View File

@ -1,44 +0,0 @@
extends: default
rules:
braces:
min-spaces-inside: 0
max-spaces-inside: 1
min-spaces-inside-empty: 0
max-spaces-inside-empty: 0
brackets:
min-spaces-inside: 0
max-spaces-inside: 1
min-spaces-inside-empty: 0
max-spaces-inside-empty: 0
comments:
require-starting-space: true
ignore-shebangs: true
min-spaces-from-content: 1
comments-indentation:
level: error
document-start:
level: error
present: false
document-end:
present: false
empty-lines:
max: 1
indentation:
spaces: 2
line-length: disable
truthy:
allowed-values: ["true", "false", "on", "off"]
ignore: |
.venv
node_modules

View File

@ -1,7 +1,6 @@
# GNU makefile proxy script for BSD make
#
# Written and maintained by Mahmoud Al-Qudsi <mqudsi@neosmart.net>
# Copyright NeoSmart Technologies <https://neosmart.net/> 2014-2019
# Copyright NeoSmart Technologies <https://neosmart.net/> 2014-2018
# Obtain updates from <https://github.com/neosmart/gmake-proxy>
#
# Redistribution and use in source and binary forms, with or without
@ -27,32 +26,26 @@
JARG =
GMAKE = "gmake"
# When gmake is called from another make instance, -w is automatically added
# which causes extraneous messages about directory changes to be emitted.
# Running with --no-print-directory silences these messages.
#When gmake is called from another make instance, -w is automatically added
#which causes extraneous messages about directory changes to be emitted.
#--no-print-directory silences these messages.
GARGS = "--no-print-directory"
.if "$(.MAKE.JOBS)" != ""
JARG = -j$(.MAKE.JOBS)
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.
#by default bmake will cd into ./obj first
.OBJDIR: ./
# The GNU convention is to use the lowercased `prefix` variable/macro to
# specify the installation directory. Humor them.
GPREFIX =
.if defined(PREFIX) && ! defined(prefix)
GPREFIX = 'prefix = "$(PREFIX)"'
.endif
.BEGIN: .SILENT
which $(GMAKE) || (printf "Error: GNU Make is required!\n\n" 1>&2 && false)
.PHONY: FRC
$(.TARGETS): FRC
$(GMAKE) $(GPREFIX) $(GARGS) $(.TARGETS:S,.DONE,,) $(JARG)
$(GMAKE) $(GARGS) $(.TARGETS:S,.DONE,,) $(JARG)
.DONE .DEFAULT: .SILENT
$(GMAKE) $(GPREFIX) $(GARGS) $(.TARGETS:S,.DONE,,) $(JARG)
$(GMAKE) $(GARGS) $(.TARGETS:S,.DONE,,) $(JARG)
.ERROR: .SILENT
if ! which $(GMAKE) > /dev/null; then \
echo "GNU Make is required!"; \
fi

File diff suppressed because it is too large Load Diff

View File

@ -1,96 +0,0 @@
# Gitea Community Code of Conduct
## About
Online communities include people from many different backgrounds. The Gitea contributors are committed to providing a friendly, safe and welcoming environment for all, regardless of gender identity and expression, sexual orientation, disabilities, neurodiversity, physical appearance, body size, ethnicity, nationality, race, age, religion, or similar personal characteristics.
The first goal of the Code of Conduct is to specify a baseline standard of behavior so that people with different social values and communication styles can talk about Gitea effectively, productively, and respectfully.
The second goal is to provide a mechanism for resolving conflicts in the community when they arise.
The third goal of the Code of Conduct is to make our community welcoming to people from different backgrounds. Diversity is critical to the project; for Gitea to be successful, it needs contributors and users from all backgrounds.
We believe that healthy debate and disagreement are essential to a healthy project and community. However, it is never ok to be disrespectful. We value diverse opinions, but we value respectful behavior more.
## Community values
These are the values to which people in the Gitea community should aspire.
- **Be friendly and welcoming.**
- **Be patient.**
- Remember that people have varying communication styles and that not everyone is using their native language. (Meaning and tone can be lost in translation.)
- **Be thoughtful.**
- Productive communication requires effort. Think about how your words will be interpreted.
- Remember that sometimes it is best to refrain entirely from commenting.
- **Be respectful.**
- In particular, respect differences of opinion.
- **Be charitable.**
- Interpret the arguments of others in good faith, do not seek to disagree.
- When we do disagree, try to understand why.
- **Be constructive.**
- Avoid derailing: stay on topic; if you want to talk about something else, start a new conversation.
- Avoid unconstructive criticism: don't merely decry the current state of affairs; offer—or at least solicit—suggestions as to how things may be improved.
- Avoid snarking (pithy, unproductive, sniping comments)
- Avoid discussing potentially offensive or sensitive issues; this all too often leads to unnecessary conflict.
- Avoid microaggressions (brief and commonplace verbal, behavioral and environmental indignities that communicate hostile, derogatory or negative slights and insults to a person or group).
- **Be responsible.**
- What you say and do matters. Take responsibility for your words and actions, including their consequences, whether intended or otherwise.
People are complicated. You should expect to be misunderstood and to misunderstand others; when this inevitably occurs, resist the urge to be defensive or assign blame. Try not to take offense where no offense was intended. Give people the benefit of the doubt. Even if the intent was to provoke, do not rise to it. It is the responsibility of all parties to de-escalate conflict when it arises.
## Code of Conduct
### Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
### Our Standards
Examples of behavior that contributes to creating a positive environment include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery and unwelcome sexual attention or advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others private information, such as a physical or electronic address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting
### Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject: comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, as well as to ban (temporarily or permanently) any contributor for behaviors that they deem inappropriate, threatening, offensive, or harmful.
### Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
This Code of Conduct also applies outside the project spaces when the Project Stewards have a reasonable belief that an individuals behavior may have a negative impact on the project or its community.
### Conflict Resolution
We do not believe that all conflict is bad; healthy debate and disagreement often yield positive results. However, it is never okay to be disrespectful or to engage in behavior that violates the projects code of conduct.
If you see someone violating the code of conduct, you are encouraged to address the behavior directly with those involved. Many issues can be resolved quickly and easily, and this gives people more control over the outcome of their dispute. If you are unable to resolve the matter for any reason, or if the behavior is threatening or harassing, report it. We are dedicated to providing an environment where participants feel welcome and safe.
Reports should be directed to the Gitea Project Stewards at conduct@gitea.com. It is the Project Stewards duty to receive and address reported violations of the code of conduct. They will then work with a committee consisting of representatives from the technical-oversight-committee.
We will investigate every complaint, but you may not receive a direct response. We will use our discretion in determining when and how to follow up on reported incidents, which may range from not taking action to permanent expulsion from the project and project-sponsored spaces. Under normal circumstances, we will notify the accused of the report and provide them an opportunity to discuss it before any action is taken. If there is a consensus between maintainers that such an endeavor would be useless (i.e. in case of an obvious spammer), we reserve the right to take action without notifying the accused first. The identity of the reporter will be omitted from the details of the report supplied to the accused. In potentially harmful situations, such as ongoing harassment or threats to anyones safety, we may take action without notice.
### Attribution
This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
## Summary
- Treat everyone with respect and kindness.
- Be thoughtful in how you communicate.
- Dont be destructive or inflammatory.
- If you encounter an issue, please mail conduct@gitea.com.

View File

@ -1,166 +1,75 @@
# Contribution Guidelines
<details><summary>Table of Contents</summary>
## Table of Contents
- [Contribution Guidelines](#contribution-guidelines)
- [Table of Contents](#table-of-contents)
- [Introduction](#introduction)
- [Issues](#issues)
- [How to report issues](#how-to-report-issues)
- [Types of issues](#types-of-issues)
- [Discuss your design before the implementation](#discuss-your-design-before-the-implementation)
- [Issue locking](#issue-locking)
- [Building Gitea](#building-gitea)
- [Dependencies](#dependencies)
- [Backend](#backend)
- [Frontend](#frontend)
- [Design guideline](#design-guideline)
- [Styleguide](#styleguide)
- [Copyright](#copyright)
- [Testing](#testing)
- [Bug reports](#bug-reports)
- [Discuss your design](#discuss-your-design)
- [Testing redux](#testing-redux)
- [Vendoring](#vendoring)
- [Translation](#translation)
- [Building Gitea](#building-gitea)
- [Code review](#code-review)
- [Pull request format](#pull-request-format)
- [PR title and summary](#pr-title-and-summary)
- [Milestone](#milestone)
- [Labels](#labels)
- [Breaking PRs](#breaking-prs)
- [What is a breaking PR?](#what-is-a-breaking-pr)
- [How to handle breaking PRs?](#how-to-handle-breaking-prs)
- [Maintaining open PRs](#maintaining-open-prs)
- [Getting PRs merged](#getting-prs-merged)
- [Final call](#final-call)
- [Commit messages](#commit-messages)
- [PR Co-authors](#pr-co-authors)
- [PRs targeting `main`](#prs-targeting-main)
- [Backport PRs](#backport-prs)
- [Documentation](#documentation)
- [Styleguide](#styleguide)
- [Design guideline](#design-guideline)
- [API v1](#api-v1)
- [GitHub API compatibility](#github-api-compatibility)
- [Adding/Maintaining API routes](#addingmaintaining-api-routes)
- [When to use what HTTP method](#when-to-use-what-http-method)
- [Requirements for API routes](#requirements-for-api-routes)
- [Backports and Frontports](#backports-and-frontports)
- [What is backported?](#what-is-backported)
- [How to backport?](#how-to-backport)
- [Format of backport PRs](#format-of-backport-prs)
- [Frontports](#frontports)
- [Developer Certificate of Origin (DCO)](#developer-certificate-of-origin-dco)
- [Release Cycle](#release-cycle)
- [Maintainers](#maintainers)
- [Technical Oversight Committee (TOC)](#technical-oversight-committee-toc)
- [TOC election process](#toc-election-process)
- [Current TOC members](#current-toc-members)
- [Previous TOC/owners members](#previous-tocowners-members)
- [Governance Compensation](#governance-compensation)
- [TOC \& Working groups](#toc--working-groups)
- [Roadmap](#roadmap)
- [Owners](#owners)
- [Versions](#versions)
- [Releasing Gitea](#releasing-gitea)
</details>
- [Copyright](#copyright)
## Introduction
This document explains how to contribute changes to the Gitea project. \
It assumes you have followed the [installation instructions](https://docs.gitea.com/category/installation). \
Sensitive security-related issues should be reported to [security@gitea.io](mailto:security@gitea.io).
This document explains how to contribute changes to the Gitea project.
It assumes you have followed the
[installation instructions](https://docs.gitea.io/en-us/).
Sensitive security-related issues should be reported to
[security@gitea.io](mailto:security@gitea.io).
For configuring IDEs for Gitea development, see the [contributed IDE configurations](contrib/ide/).
For configuring IDE or code editor to develop Gitea see [IDE and code editor configuration](contrib/ide/)
## Issues
## Bug reports
### How to report issues
Please search the issues on the issue tracker with a variety of keywords
to ensure your bug is not already reported.
Please search the issues on the issue tracker with a variety of related keywords to ensure that your issue has not already been reported.
If unique, [open an issue](https://github.com/go-gitea/gitea/issues/new)
and answer the questions so we can understand and reproduce the
problematic behavior.
If your issue has not been reported yet, [open an issue](https://github.com/go-gitea/gitea/issues/new)
and answer the questions so we can understand and reproduce the problematic behavior. \
Please write clear and concise instructions so that we can reproduce the behavior — even if it seems obvious. \
The more detailed and specific you are, the faster we can fix the issue. \
It is really helpful if you can reproduce your problem on a site running on the latest commits, i.e. <https://try.gitea.io>, as perhaps your problem has already been fixed on a current version. \
Please follow the guidelines described in [How to Report Bugs Effectively](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html) for your report.
To show us that the issue you are having is in Gitea itself, please
write clear, concise instructions so we can reproduce the behavior—
even if it seems obvious. The more detailed and specific you are,
the faster we can fix the issue. Check out [How to Report Bugs
Effectively](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html).
Please be kind, remember that Gitea comes at no cost to you, and you're getting free help.
Please be kind, remember that Gitea comes at no cost to you, and you're
getting free help.
### Types of issues
## Discuss your design
Typically, issues fall in one of the following categories:
The project welcomes submissions. If you want to change or add something,
please let everyone know what you're working on—[file an issue](https://github.com/go-gitea/gitea/issues/new)!
Significant changes must go through the change proposal process
before they can be accepted. To create a proposal, file an issue with
your proposed changes documented, and make sure to note in the title
of the issue that it is a proposal.
- `bug`: Something in the frontend or backend behaves unexpectedly
- `security issue`: bug that has serious implications such as leaking another users data. Please do not file such issues on the public tracker and send a mail to security@gitea.io instead
- `feature`: Completely new functionality. You should describe this feature in enough detail that anyone who reads the issue can understand how it is supposed to be implemented
- `enhancement`: An existing feature should get an upgrade
- `refactoring`: Parts of the code base don't conform with other parts and should be changed to improve Gitea's maintainability
This process gives everyone a chance to validate the design, helps
prevent duplication of effort, and ensures that the idea fits inside
the goals for the project and tools. It also checks that the design is
sound before code is written; the code review tool is not the place for
high-level discussions.
### Discuss your design before the implementation
## Testing redux
We welcome submissions. \
If you want to change or add something, please let everyone know what you're working on — [file an issue](https://github.com/go-gitea/gitea/issues/new) or comment on an existing one before starting your work!
Significant changes such as new features must go through the change proposal process before they can be accepted. \
This is mainly to save yourself the trouble of implementing it, only to find out that your proposed implementation has some potential problems. \
Furthermore, this process gives everyone a chance to validate the design, helps prevent duplication of effort, and ensures that the idea fits inside
the goals for the project and tools.
Pull requests should not be the place for architecture discussions.
### Issue locking
Commenting on closed or merged issues/PRs is strongly discouraged.
Such comments will likely be overlooked as some maintainers may not view notifications on closed issues, thinking that the item is resolved.
As such, commenting on closed/merged issues/PRs may be disabled prior to the scheduled auto-locking if a discussion starts or if unrelated comments are posted.
If further discussion is needed, we encourage you to open a new issue instead and we recommend linking to the issue/PR in question for context.
## Building Gitea
See the [development setup instructions](https://docs.gitea.com/development/hacking-on-gitea).
## Dependencies
### Backend
Go dependencies are managed using [Go Modules](https://go.dev/cmd/go/#hdr-Module_maintenance). \
You can find more details in the [go mod documentation](https://go.dev/ref/mod) and the [Go Modules Wiki](https://github.com/golang/go/wiki/Modules).
Pull requests should only modify `go.mod` and `go.sum` where it is related to your change, be it a bugfix or a new feature. \
Apart from that, these files should only be modified by Pull Requests whose only purpose is to update dependencies.
The `go.mod`, `go.sum` update needs to be justified as part of the PR description,
and must be verified by the reviewers and/or merger to always reference
an existing upstream commit.
### Frontend
For the frontend, we use [npm](https://www.npmjs.com/).
The same restrictions apply for frontend dependencies as for backend dependencies, with the exceptions that the files for it are `package.json` and `package-lock.json`, and that new versions must always reference an existing version.
## Design guideline
Depending on your change, please read the
- [backend development guideline](https://docs.gitea.com/contributing/guidelines-backend)
- [frontend development guideline](https://docs.gitea.com/contributing/guidelines-frontend)
- [refactoring guideline](https://docs.gitea.com/contributing/guidelines-refactoring)
## Styleguide
You should always run `make fmt` before committing to conform to Gitea's styleguide.
## Copyright
New code files that you contribute should use the standard copyright header:
```
// Copyright <current year> The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
```
Afterwards, copyright should only be modified when the copyright author changes.
## Testing
Before submitting a pull request, run all tests to make sure your changes don't cause a regression elsewhere.
Before submitting a pull request, run all the tests for the whole tree
to make sure your changes don't cause regression elsewhere.
Here's how to run the test suite:
@ -168,320 +77,257 @@ Here's how to run the test suite:
| | |
| :-------------------- | :---------------------------------------------------------------- |
|``make lint`` | lint everything (not needed if you only change the front- **or** backend) |
|``make lint`` | lint everything (not suggest if you only change one type code) |
|``make lint-frontend`` | lint frontend files |
|``make lint-backend`` | lint backend files |
- run tests (we suggest running them on Linux)
- run test code (Suggest run in Linux)
| Command | Action | |
| :------------------------------------- | :----------------------------------------------- | ------------ |
|``make test[\#SpecificTestName]`` | run unit test(s) | |
|``make test-sqlite[\#SpecificTestName]``| run [integration](tests/integration) test(s) for SQLite |[More details](tests/integration/README.md) |
|``make test-e2e-sqlite[\#SpecificTestName]``| run [end-to-end](tests/e2e) test(s) for SQLite |[More details](tests/e2e/README.md) |
| | |
| :------------------------------------- | :----------------------------------------------- |
|``make test[\#TestSpecificName]`` | run unit test |
|``make test-sqlite[\#TestSpecificName]``| run [integration](tests/integration) test for SQLite |
|[More details about integration tests](tests/integration/README.md) |
|``make test-e2e-sqlite[\#TestSpecificFileName]``| run [end-to-end](tests/e2e) test for SQLite |
|[More details about e2e tests](tests/e2e/README.md) |
## Vendoring
We manage dependencies via [Go Modules](https://golang.org/cmd/go/#hdr-Module_maintenance), more details: [go mod](https://go.dev/ref/mod).
Pull requests should only include `go.mod`, `go.sum` updates if they are part of
the same change, be it a bugfix or a feature addition.
The `go.mod`, `go.sum` update needs to be justified as part of the PR description,
and must be verified by the reviewers and/or merger to always reference
an existing upstream commit.
You can find more information on how to get started with it on the [Modules Wiki](https://github.com/golang/go/wiki/Modules).
## Translation
All translation work happens on [Crowdin](https://crowdin.com/project/gitea).
The only translation that is maintained in this repository is [the English translation](https://github.com/go-gitea/gitea/blob/main/options/locale/locale_en-US.ini).
It is synced regularly with Crowdin. \
Other locales on main branch **should not** be updated manually as they will be overwritten with each sync. \
Once a language has reached a **satisfactory percentage** of translated keys (~25%), it will be synced back into this repo and included in the next released version.
We do all translation work inside [Crowdin](https://crowdin.com/project/gitea).
The only translation that is maintained in this Git repository is
[`en_US.ini`](https://github.com/go-gitea/gitea/blob/main/options/locale/locale_en-US.ini)
and is synced regularly to Crowdin. Once a translation has reached
A SATISFACTORY PERCENTAGE it will be synced back into this repo and
included in the next released version.
The tool `go run build/backport-locale.go` can be used to backport locales from the main branch to release branches that were missed.
## Building Gitea
See the [hacking instructions](https://docs.gitea.io/en-us/hacking-on-gitea/).
## Code review
### Pull request format
Changes to Gitea must be reviewed before they are accepted—no matter who
makes the change, even if they are an owner or a maintainer. We use GitHub's
pull request workflow to do that. And, we also use [LGTM](http://lgtm.co)
to ensure every PR is reviewed by at least 2 maintainers.
Please try to make your pull request easy to review for us. \
For that, please read the [*Best Practices for Faster Reviews*](https://github.com/kubernetes/community/blob/261cb0fd089b64002c91e8eddceebf032462ccd6/contributors/guide/pull-requests.md#best-practices-for-faster-reviews) guide. \
It has lots of useful tips for any project you may want to contribute to. \
Please try to make your pull request easy to review for us. And, please read
the *[How to get faster PR reviews](https://github.com/kubernetes/community/blob/261cb0fd089b64002c91e8eddceebf032462ccd6/contributors/guide/pull-requests.md#best-practices-for-faster-reviews)* guide;
it has lots of useful tips for any project you may want to contribute.
Some of the key points:
- Make small pull requests. \
The smaller, the faster to review and the more likely it will be merged soon.
- Don't make changes unrelated to your PR. \
Maybe there are typos on some comments, maybe refactoring would be welcome on a function... \
but if that is not related to your PR, please make *another* PR for that.
- Split big pull requests into multiple small ones. \
An incremental change will be faster to review than a huge PR.
- Allow edits by maintainers. This way, the maintainers will take care of merging the PR later on instead of you.
- Make small pull requests. The smaller, the faster to review and the
more likely it will be merged soon.
- Don't make changes unrelated to your PR. Maybe there are typos on
some comments, maybe refactoring would be welcome on a function... but
if that is not related to your PR, please make *another* PR for that.
- Split big pull requests into multiple small ones. An incremental change
will be faster to review than a huge PR.
- Use the first comment as a summary explainer of your PR and you should keep this up-to-date as the PR evolves.
### PR title and summary
If your PR could cause a breaking change you must add a BREAKING section to this comment e.g.:
In the PR title, describe the problem you are fixing, not how you are fixing it. \
Use the first comment as a summary of your PR. \
In the PR summary, you can describe exactly how you are fixing this problem.
Keep this summary up-to-date as the PR evolves. \
If your PR changes the UI, you must add **after** screenshots in the PR summary. \
If you are not implementing a new feature, you should also post **before** screenshots for comparison.
If you are implementing a new feature, your PR will only be merged if your screenshots are up to date.\
Furthermore, feature PRs will only be merged if their summary contains a clear usage description (understandable for users) and testing description (understandable for reviewers).
You should strive to combine both into a single description.
Another requirement for merging PRs is that the PR is labeled correctly.\
However, this is not your job as a contributor, but the job of the person merging your PR.\
If you think that your PR was labeled incorrectly, or notice that it was merged without labels, please let us know.
If your PR closes some issues, you must note that in a way that both GitHub and Gitea understand, i.e. by appending a paragraph like
```text
Fixes/Closes/Resolves #<ISSUE_NR_X>.
Fixes/Closes/Resolves #<ISSUE_NR_Y>.
```
to your summary. \
Each issue that will be closed must stand on a separate line.
### Milestone
A PR should only be assigned to a milestone if it will likely be merged into the given version. \
As a rule of thumb, assume that a PR will stay open for an additional month for every 100 added lines. \
PRs without a milestone may not be merged.
### Labels
Almost all labels used inside Gitea can be classified as one of the following:
- `modifies/…`: Determines which parts of the codebase are affected. These labels will be set through the CI.
- `topic/…`: Determines the conceptual component of Gitea that is affected, i.e. issues, projects, or authentication. At best, PRs should only target one component but there might be overlap. Must be set manually.
- `type/…`: Determines the type of an issue or PR (feature, refactoring, docs, bug, …). If GitHub supported scoped labels, these labels would be exclusive, so you should set **exactly** one, not more or less (every PR should fall into one of the provided categories, and only one).
- `issue/…` / `pr/…`: Labels that are specific to issues or PRs respectively and that are only necessary in a given context, i.e. `issue/not-a-bug` or `pr/need-2-approvals`
Every PR should be labeled correctly with every label that applies.
There are also some labels that will be managed automatically.\
In particular, these are
- the amount of pending required approvals
- has all `backport`s or needs a manual backport
### Breaking PRs
#### What is a breaking PR?
A PR is breaking if it meets one of the following criteria:
- It changes API output in an incompatible way for existing users
- It removes a setting that an admin could previously set (i.e. via `app.ini`)
- An admin must do something manually to restore the old behavior
In particular, this means that adding new settings is not breaking.\
Changing the default value of a setting or replacing the setting with another one is breaking, however.
#### How to handle breaking PRs?
If your PR has a breaking change, you must add two things to the summary of your PR:
1. A reasoning why this breaking change is necessary
2. A `BREAKING` section explaining in simple terms (understandable for a typical user) how this PR affects users and how to mitigate these changes. This section can look for example like
```md
## :warning: BREAKING :warning:
```
Breaking PRs will not be merged as long as not both of these requirements are met.
To explain how this could affect users and how to mitigate these changes.
### Maintaining open PRs
Once code review starts on your PR, do not rebase nor squash your branch as it makes it
difficult to review the new changes. Only if there is a need, sync your branch by merging
the base branch into yours. Don't worry about merge commits messing up your tree as
the final merge process squashes all commits into one, with the visible commit message (first
line) being the PR title + PR index and description being the PR's first comment.
The moment you create a non-draft PR or the moment you convert a draft PR to a non-draft PR is the moment code review starts for it. \
Once that happens, do not rebase or squash your branch anymore as it makes it difficult to review the new changes. \
Merge the base branch into your branch only when you really need to, i.e. because of conflicting changes in the mean time. \
This reduces unnecessary CI runs. \
Don't worry about merge commits messing up your commit history as every PR will be squash merged. \
This means that all changes are joined into a single new commit whose message is as described below.
Once your PR gets the `lgtm/done` label, don't worry about keeping it up-to-date or breaking
builds (unless there's a merge conflict or a request is made by a maintainer to make
modifications). It is the maintainer team's responsibility from this point to get it merged.
### Getting PRs merged
## Styleguide
Changes to Gitea must be reviewed before they are accepted — no matter who
makes the change, even if they are an owner or a maintainer. \
The only exception are critical bugs that prevent Gitea from being compiled or started. \
Specifically, we require two approvals from maintainers for every PR. \
Once this criteria has been met, your PR receives the `lgtm/done` label. \
From this point on, your only responsibility is to fix merge conflicts or respond to/implement requests by maintainers. \
It is the responsibility of the maintainers from this point to get your PR merged.
For imports you should use the following format (*without* the comments)
If a PR has the `lgtm/done` label and there are no open discussions or merge conflicts anymore, any maintainer can add the `reviewed/wait-merge` label. \
This label means that the PR is part of the merge queue and will be merged as soon as possible. \
The merge queue will be cleared in the order of the list below:
```go
import (
// stdlib
"fmt"
"math"
<https://github.com/go-gitea/gitea/pulls?q=is%3Apr+label%3Areviewed%2Fwait-merge+sort%3Acreated-asc+is%3Aopen>
// local packages
"code.gitea.io/gitea/models"
"code.gitea.io/sdk/gitea"
Gitea uses it's own tool, the <https://github.com/GiteaBot/gitea-backporter> to automate parts of the review process. \
This tool does the things listed below automatically:
- create a backport PR if needed once the initial PR was merged
- remove the PR from the merge queue after the PR merged
- keep the oldest branch in the merge queue up to date with merges
### Final call
If a PR has been ignored for more than 7 days with no comments or reviews, and the author or any maintainer believes it will not survive a long wait (such as a refactoring PR), they can send "final call" to the TOC by mentioning them in a comment.
After another 7 days, if there is still zero approval, this is considered a polite refusal, and the PR will be closed to avoid wasting further time. Therefore, the "final call" has a cost, and should be used cautiously.
However, if there are no objections from maintainers, the PR can be merged with only one approval from the TOC (not the author).
### Commit messages
Mergers are able and required to rewrite the PR title and summary (the first comment of a PR) so that it can produce an easily understandable commit message if necessary. \
The final commit message should no longer contain any uncertainty such as `hopefully, <x> won't happen anymore`. Replace uncertainty with certainty.
#### PR Co-authors
A person counts as a PR co-author the moment they (co-)authored a commit that is not simply a `Merge base branch into branch` commit. \
Mergers are required to remove such "false-positive" co-authors when writing the commit message. \
The true co-authors must remain in the commit message.
#### PRs targeting `main`
The commit message of PRs targeting `main` is always
```bash
$PR_TITLE ($PR_INDEX)
$REWRITTEN_PR_SUMMARY
// external packages
"github.com/foo/bar"
"gopkg.io/baz.v1"
)
```
#### Backport PRs
## Design guideline
The commit message of backport PRs is always
To maintain understandable code and avoid circular dependencies it is important to have a good structure of the code. The Gitea code is divided into the following parts:
```bash
$PR_TITLE ($INITIAL_PR_INDEX) ($BACKPORT_PR_INDEX)
$REWRITTEN_PR_SUMMARY
```
- **models:** Contains the data structures used by xorm to construct database tables. It also contains supporting functions to query and update the database. Dependencies to other code in Gitea should be avoided although some modules might be needed (for example for logging).
- **models/fixtures:** Sample model data used in integration tests.
- **models/migrations:** Handling of database migrations between versions. PRs that changes a database structure shall also have a migration step.
- **modules:** Different modules to handle specific functionality in Gitea. Shall only depend on other modules but not other packages (models, services).
- **public:** Frontend files (javascript, images, css, etc.)
- **routers:** Handling of server requests. As it uses other Gitea packages to serve the request, other packages (models, modules or services) shall not depend on routers.
- **services:** Support functions for common routing operations. Uses models and modules to handle the request.
- **templates:** Golang templates for generating the html output.
- **tests/e2e:** End to end tests
- **tests/integration:** Integration tests
- **tests/gitea-repositories-meta:** Sample repos used in integration tests. Adding a new repo requires editing `models/fixtures/repositories.yml` and `models/fixtures/repo_unit.yml` to match.
- **tests/gitea-lfs-meta:** Sample LFS objects used in integration tests. Adding a new object requires editing `models/fixtures/lfs_meta_object.yml` to match.
- **vendor:** External code that Gitea depends on.
## Documentation
If you add a new feature or change an existing aspect of Gitea, the documentation for that feature must be created or updated in the same PR.
If you add a new feature or change an existing aspect of Gitea, the documentation for that feature must be created or updated.
## API v1
The API is documented by [swagger](http://try.gitea.io/api/swagger) and is based on [the GitHub API](https://docs.github.com/en/rest).
The API is documented by [swagger](http://try.gitea.io/api/swagger) and is based on [GitHub API v3](https://developer.github.com/v3/).
### GitHub API compatibility
Thus, Gitea´s API should use the same endpoints and fields as GitHub´s API as far as possible, unless there are good reasons to deviate.
Gitea's API should use the same endpoints and fields as the GitHub API as far as possible, unless there are good reasons to deviate. \
If Gitea provides functionality that GitHub does not, a new endpoint can be created. \
If information is provided by Gitea that is not provided by the GitHub API, a new field can be used that doesn't collide with any GitHub fields. \
Updating an existing API should not remove existing fields unless there is a really good reason to do so. \
The same applies to status responses. If you notice a problem, feel free to leave a comment in the code for future refactoring to API v2 (which is currently not planned).
If Gitea provides functionality that GitHub does not, a new endpoint can be created.
### Adding/Maintaining API routes
If information is provided by Gitea that is not provided by the GitHub API, a new field can be used that doesn't collide with any GitHub fields.
All expected results (errors, success, fail messages) must be documented ([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/repo/issue.go#L319-L327)). \
All JSON input types must be defined as a struct in [modules/structs/](modules/structs/) ([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/modules/structs/issue.go#L76-L91)) \
and referenced in [routers/api/v1/swagger/options.go](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/swagger/options.go). \
They can then be used like [this example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/repo/issue.go#L318). \
All JSON responses must be defined as a struct in [modules/structs/](modules/structs/) ([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/modules/structs/issue.go#L36-L68)) \
and referenced in its category in [routers/api/v1/swagger/](routers/api/v1/swagger/) ([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/swagger/issue.go#L11-L16)) \
They can be used like [this example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/repo/issue.go#L277-L279).
Updating an existing API should not remove existing fields unless there is a really good reason to do so.
### When to use what HTTP method
The same applies to status responses. If you notice a problem, feel free to leave a comment in the code for future refactoring to APIv2 (which is currently not planned).
All expected results (errors, success, fail messages) should be documented
([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/repo/issue.go#L319-L327)).
All JSON input types must be defined as a struct in [modules/structs/](modules/structs/)
([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/modules/structs/issue.go#L76-L91))
and referenced in
[routers/api/v1/swagger/options.go](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/swagger/options.go).
They can then be used like the following:
([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/repo/issue.go#L318)).
All JSON responses must be defined as a struct in [modules/structs/](modules/structs/)
([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/modules/structs/issue.go#L36-L68))
and referenced in its category in [routers/api/v1/swagger/](routers/api/v1/swagger/)
([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/swagger/issue.go#L11-L16))
They can be used like the following:
([example](https://github.com/go-gitea/gitea/blob/c620eb5b2d0d874da68ebd734d3864c5224f71f7/routers/api/v1/repo/issue.go#L277-L279))
In general, HTTP methods are chosen as follows:
- **GET** endpoints return the requested object(s) and status **OK (200)**
- **DELETE** endpoints return the status **No Content (204)** and no content either
- **POST** endpoints are used to **create** new objects (e.g. a User) and return the status **Created (201)** and the created object
- **PUT** endpoints are used to **add/assign** existing Objects (e.g. a user to a team) and return the status **No Content (204)** and no content either
- **PATCH** endpoints are used to **edit/change** an existing object and return the changed object and the status **OK (200)**
- **GET** endpoints return requested object and status **OK (200)**
- **DELETE** endpoints return status **No Content (204)**
- **POST** endpoints return status **Created (201)**, used to **create** new objects (e.g. a User)
- **PUT** endpoints return status **No Content (204)**, used to **add/assign** existing Objects (e.g. User) to something (e.g. Org-Team)
- **PATCH** endpoints return changed object and status **OK (200)**, used to **edit/change** an existing object
### Requirements for API routes
An endpoint which changes/edits an object expects all fields to be optional (except ones to identify the object, which are required).
All parameters of endpoints changing/editing an object must be optional (except the ones to identify the object, which are required).
Endpoints returning lists must
### Endpoints returning lists should
- support pagination (`page` & `limit` options in query)
- set `X-Total-Count` header via **SetTotalCountHeader** ([example](https://github.com/go-gitea/gitea/blob/7aae98cc5d4113f1e9918b7ee7dd09f67c189e3e/routers/api/v1/repo/issue.go#L444))
## Backports and Frontports
### What is backported?
Occasionally backports of PRs are required.
We backport PRs given the following circumstances:
1. Feature freeze is active, but `<version>-rc0` has not been released yet. Here, we backport as much as possible. <!-- TODO: Is that our definition with the new backport bot? -->
2. `rc0` has been released. Here, we only backport bug- and security-fixes, and small enhancements. Large PRs such as refactors are not backported anymore. <!-- TODO: Is that our definition with the new backport bot? -->
3. We never backport new features.
4. We never backport breaking changes except when
1. The breaking change has no effect on the vast majority of users
2. The component triggering the breaking change is marked as experimental
### How to backport?
In the past, it was necessary to manually backport your PRs. \
Now, that's not a requirement anymore as our [backport bot](https://github.com/GiteaBot) tries to create backports automatically once the PR is merged when the PR
- does not have the label `backport/manual`
- has the label `backport/<version>`
The `backport/manual` label signifies either that you want to backport the change yourself, or that there were conflicts when backporting, thus you **must** do it yourself.
### Format of backport PRs
The title of backport PRs should be
The backported PR title should be:
```
<original PR title> (#<original pr number>)
Title of backported PR (#ORIGINAL_PR_NUMBER)
```
The first two lines of the summary of the backporting PR should be
The first two lines of the summary of the backporting PR should be:
```
Backport #<original pr number>
Backport #ORIGINAL_PR_NUMBER
```
with the rest of the summary and labels matching the original PR.
with the rest of the summary matching the original PR. Similarly for frontports
### Frontports
---
Frontports behave exactly as described above for backports.
A command to help create backports can be found in `contrib/backport` and can be installed (from inside the gitea repo root directory) using:
```bash
go install contrib/backport/backport.go
```
## Developer Certificate of Origin (DCO)
We consider the act of contributing to the code by submitting a Pull Request as the "Sign off" or agreement to the certifications and terms of the [DCO](DCO) and [MIT license](LICENSE). \
No further action is required. \
You can also decide to sign off your commits by adding the following line at the end of your commit messages:
We consider the act of contributing to the code by submitting a Pull
Request as the "Sign off" or agreement to the certifications and terms
of the [DCO](DCO) and [MIT license](LICENSE). No further action is required.
Additionally you could add a line at the end of your commit message.
```
Signed-off-by: Joe Smith <joe.smith@email.com>
```
If you set the `user.name` and `user.email` Git config options, you can add the line to the end of your commits automatically with `git commit -s`.
If you set your `user.name` and `user.email` Git configs, you can add the
line to the end of your commit automatically with `git commit -s`.
We assume in good faith that the information you provide is legally binding.
## Release Cycle
We adopted a release schedule to streamline the process of working on, finishing, and issuing releases. \
The overall goal is to make a major release every three or four months, which breaks down into two or three months of general development followed by one month of testing and polishing known as the release freeze. \
All the feature pull requests should be
merged before feature freeze. All feature pull requests haven't been merged before this feature freeze will be moved to next milestone, please notice our feature freeze announcement on discord. And, during the frozen period, a corresponding
We adopted a release schedule to streamline the process of working
on, finishing, and issuing releases. The overall goal is to make a
minor release every three or four months, which breaks down into two or three months of
general development followed by one month of testing and polishing
known as the release freeze. All the feature pull requests should be
merged before feature freeze. And, during the frozen period, a corresponding
release branch is open for fixes backported from main branch. Release candidates
are made during this period for user testing to
obtain a final version that is maintained in this branch.
Major release cycles are seasonal. They always begin on the 25th and end on
the 24th (i.e., the 25th of December to March 24th).
During a development cycle, we may also publish any necessary minor releases
for the previous version. For example, if the latest, published release is
v1.2, then minor changes for the previous release—e.g., v1.1.0 -> v1.1.1—are
still possible.
The previous release gets fixes for:
- Security issues
- Critical bugs
- Regressions
- Build issues
- Necessary enhancements (including necessary UI/UX fixes)
The backported fixes should avoid breaking downgrade between minor releases as much as possible.
## Maintainers
To make sure every PR is checked, we have [maintainers](MAINTAINERS). \
Every PR **must** be reviewed by at least two maintainers (or owners) before it can get merged. \
For refactoring PRs after a week and documentation only PRs, the approval of only one maintainer is enough. \
A maintainer should be a contributor of Gitea and contributed at least
To make sure every PR is checked, we have [team
maintainers](MAINTAINERS). Every PR **MUST** be reviewed by at least
two maintainers (or owners) before it can get merged. A maintainer
should be a contributor of Gitea (or Gogs) and contributed at least
4 accepted PRs. A contributor should apply as a maintainer in the
[Discord](https://discord.gg/Gitea) `#develop` channel. The team maintainers may invite the contributor. A maintainer
[Discord](https://discord.gg/NsatcWJ) #develop channel. The owners
or the team maintainers may invite the contributor. A maintainer
should spend some time on code reviews. If a maintainer has no
time to do that, they should apply to leave the maintainers team
and we will give them the honor of being a member of the [advisors
@ -495,91 +341,69 @@ if possible provide GPG signed commits.
https://help.github.com/articles/securing-your-account-with-two-factor-authentication-2fa/
https://help.github.com/articles/signing-commits-with-gpg/
Furthermore, any account with write access (like bots and TOC members) **must** use 2FA.
## Owners
Since Gitea is a pure community organization without any company support,
to keep the development healthy we will elect three owners every year. All
contributors may vote to elect up to three candidates, one of which will
be the main owner, and the other two the assistant owners. When the new
owners have been elected, the old owners will give up ownership to the
newly elected owners. If an owner is unable to do so, the other owners
will assist in ceding ownership to the newly elected owners.
For security reasons, Owners or any account with write access (like a bot)
must use 2FA.
https://help.github.com/articles/securing-your-account-with-two-factor-authentication-2fa/
## Technical Oversight Committee (TOC)
After the election, the new owners should proactively agree
with our [CONTRIBUTING](CONTRIBUTING.md) requirements in the
[Discord](https://discord.gg/NsatcWJ) #general channel. Below are the
words to speak:
At the start of 2023, the `Owners` team was dissolved. Instead, the governance charter proposed a technical oversight committee (TOC) which expands the ownership team of the Gitea project from three elected positions to six positions. Three positions are elected as it has been over the past years, and the other three consist of appointed members from the Gitea company.
https://blog.gitea.com/quarterly-23q1/
```
I'm honored to having been elected an owner of Gitea, I agree with
[CONTRIBUTING](CONTRIBUTING.md). I will spend part of my time on Gitea
and lead the development of Gitea.
```
### TOC election process
To honor the past owners, here's the history of the owners and the time
they served:
Any maintainer is eligible to be part of the community TOC if they are not associated with the Gitea company.
A maintainer can either nominate themselves, or can be nominated by other maintainers to be a candidate for the TOC election.
If you are nominated by someone else, you must first accept your nomination before the vote starts to be a candidate.
- 2022-01-01 ~ 2022-12-31 - https://github.com/go-gitea/gitea/issues/17872
- [Lunny Xiao](https://gitea.com/lunny) <xiaolunwen@gmail.com>
- [Matti Ranta](https://gitea.com/techknowlogick) <techknowlogick@gitea.io>
- [Andrew Thornton](https://gitea.com/zeripath) <art27@cantab.net>
The TOC is elected for one year, the TOC election happens yearly.
After the announcement of the results of the TOC election, elected members have two weeks time to confirm or refuse the seat.
If an elected member does not answer within this timeframe, they are automatically assumed to refuse the seat.
Refusals result in the person with the next highest vote getting the same choice.
As long as seats are empty in the TOC, members of the previous TOC can fill them until an elected member accepts the seat.
- 2021-01-01 ~ 2021-12-31 - https://github.com/go-gitea/gitea/issues/13801
- [Lunny Xiao](https://gitea.com/lunny) <xiaolunwen@gmail.com>
- [Lauris Bukšis-Haberkorns](https://gitea.com/lafriks) <lauris@nix.lv>
- [Matti Ranta](https://gitea.com/techknowlogick) <techknowlogick@gitea.io>
If an elected member that accepts the seat does not have 2FA configured yet, they will be temporarily counted as `answer pending` until they manage to configure 2FA, thus leaving their seat empty for this duration.
- 2020-01-01 ~ 2020-12-31 - https://github.com/go-gitea/gitea/issues/9230
- [Lunny Xiao](https://gitea.com/lunny) <xiaolunwen@gmail.com>
- [Lauris Bukšis-Haberkorns](https://gitea.com/lafriks) <lauris@nix.lv>
- [Matti Ranta](https://gitea.com/techknowlogick) <techknowlogick@gitea.io>
### Current TOC members
- 2019-01-01 ~ 2019-12-31 - https://github.com/go-gitea/gitea/issues/5572
- [Lunny Xiao](https://github.com/lunny) <xiaolunwen@gmail.com>
- [Lauris Bukšis-Haberkorns](https://github.com/lafriks) <lauris@nix.lv>
- [Matti Ranta](https://github.com/techknowlogick) <techknowlogick@gitea.io>
- 2024-01-01 ~ 2024-12-31
- Company
- [Jason Song](https://gitea.com/wolfogre) <i@wolfogre.com>
- [Lunny Xiao](https://gitea.com/lunny) <xiaolunwen@gmail.com>
- [Matti Ranta](https://gitea.com/techknowlogick) <techknowlogick@gitea.com>
- Community
- [6543](https://gitea.com/6543) <6543@obermui.de>
- [delvh](https://gitea.com/delvh) <dev.lh@web.de>
- [John Olheiser](https://gitea.com/jolheiser) <john.olheiser@gmail.com>
- 2018-01-01 ~ 2018-12-31 - https://github.com/go-gitea/gitea/issues/3255
- [Lunny Xiao](https://github.com/lunny) <xiaolunwen@gmail.com>
- [Lauris Bukšis-Haberkorns](https://github.com/lafriks) <lauris@nix.lv>
- [Kim Carlbäcker](https://github.com/bkcsoft) <kim.carlbacker@gmail.com>
### Previous TOC/owners members
Here's the history of the owners and the time they served:
- [Lunny Xiao](https://gitea.com/lunny) - 2016, 2017, [2018](https://github.com/go-gitea/gitea/issues/3255), [2019](https://github.com/go-gitea/gitea/issues/5572), [2020](https://github.com/go-gitea/gitea/issues/9230), [2021](https://github.com/go-gitea/gitea/issues/13801), [2022](https://github.com/go-gitea/gitea/issues/17872), 2023
- [Kim Carlbäcker](https://github.com/bkcsoft) - 2016, 2017
- [Thomas Boerger](https://gitea.com/tboerger) - 2016, 2017
- [Lauris Bukšis-Haberkorns](https://gitea.com/lafriks) - [2018](https://github.com/go-gitea/gitea/issues/3255), [2019](https://github.com/go-gitea/gitea/issues/5572), [2020](https://github.com/go-gitea/gitea/issues/9230), [2021](https://github.com/go-gitea/gitea/issues/13801)
- [Matti Ranta](https://gitea.com/techknowlogick) - [2019](https://github.com/go-gitea/gitea/issues/5572), [2020](https://github.com/go-gitea/gitea/issues/9230), [2021](https://github.com/go-gitea/gitea/issues/13801), [2022](https://github.com/go-gitea/gitea/issues/17872), 2023
- [Andrew Thornton](https://gitea.com/zeripath) - [2020](https://github.com/go-gitea/gitea/issues/9230), [2021](https://github.com/go-gitea/gitea/issues/13801), [2022](https://github.com/go-gitea/gitea/issues/17872), 2023
- [6543](https://gitea.com/6543) - 2023
- [John Olheiser](https://gitea.com/jolheiser) - 2023
- [Jason Song](https://gitea.com/wolfogre) - 2023
## Governance Compensation
Each member of the community elected TOC will be granted $500 each month as compensation for their work.
Furthermore, any community release manager for a specific release or LTS will be compensated $500 for the delivery of said release.
These funds will come from community sources like the OpenCollective rather than directly from the company.
Only non-company members are eligible for this compensation, and if a member of the community TOC takes the responsibility of release manager, they would only be compensated for their TOC duties.
Gitea Ltd employees are not eligible to receive any funds from the OpenCollective unless it is reimbursement for a purchase made for the Gitea project itself.
## TOC & Working groups
With Gitea covering many projects outside of the main repository, several groups will be created to help focus on specific areas instead of requiring maintainers to be a jack-of-all-trades. Maintainers are of course more than welcome to be part of multiple groups should they wish to contribute in multiple places.
The currently proposed groups are:
- **Core Group**: maintain the primary Gitea repository
- **Integration Group**: maintain the Gitea ecosystem's related tools, including go-sdk/tea/changelog/bots etc.
- **Documentation Group**: maintain related documents and repositories
- **Translation Group**: coordinate with translators and maintain translations
- **Security Group**: managed by TOC directly, members are decided by TOC, maintains security patches/responsible for security items
## Roadmap
Each year a roadmap will be discussed with the entire Gitea maintainers team, and feedback will be solicited from various stakeholders.
TOC members need to review the roadmap every year and work together on the direction of the project.
When a vote is required for a proposal or other change, the vote of community elected TOC members count slightly more than the vote of company elected TOC members. With this approach, we both avoid ties and ensure that changes align with the mission statement and community opinion.
You can visit our roadmap on the wiki.
- 2016-11-04 ~ 2017-12-31
- [Lunny Xiao](https://github.com/lunny) <xiaolunwen@gmail.com>
- [Thomas Boerger](https://github.com/tboerger) <thomas@webhippie.de>
- [Kim Carlbäcker](https://github.com/bkcsoft) <kim.carlbacker@gmail.com>
## Versions
Gitea has the `main` branch as a tip branch and has version branches
such as `release/v1.19`. `release/v1.19` is a release branch and we will
tag `v1.19.0` for binary download. If `v1.19.0` has bugs, we will accept
pull requests on the `release/v1.19` branch and publish a `v1.19.1` tag,
such as `release/v0.9`. `release/v0.9` is a release branch and we will
tag `v0.9.0` for binary download. If `v0.9.0` has bugs, we will accept
pull requests on the `release/v0.9` branch and publish a `v0.9.1` tag,
after bringing the bug fix also to the main branch.
Since the `main` branch is a tip version, if you wish to use Gitea
@ -599,7 +423,21 @@ be reviewed by two maintainers and must pass the automatic tests.
- And then push the tag as `git push origin v$vmaj.$vmin.$`. Drone CI will automatically create a release and upload all the compiled binary. (But currently it doesn't add the release notes automatically. Maybe we should fix that.)
- If needed send a frontport PR for the changelog to branch `main` and update the version in `docs/config.yaml` to refer to the new version.
- Send PR to [blog repository](https://gitea.com/gitea/blog) announcing the release.
- Verify all release assets were correctly published through CI on dl.gitea.com and GitHub releases. Once ACKed:
- bump the version of https://dl.gitea.com/gitea/version.json
- Verify all release assets were correctly published through CI on dl.gitea.io and GitHub releases. Once ACKed:
- bump the version of https://dl.gitea.io/gitea/version.json
- merge the blog post PR
- announce the release in discord `#announcements`
## Copyright
Code that you contribute should use the standard copyright header:
```
// Copyright <year> The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
```
Files in the repository contain copyright from the year they are added
to the year they are last changed. If the copyright author is changed,
just paste the header below the old one.

View File

@ -1,5 +1,5 @@
# Build stage
FROM docker.io/library/golang:1.22-alpine3.19 AS build-env
#Build stage
FROM docker.io/library/golang:1.20-alpine3.17 AS build-env
ARG GOPROXY
ENV GOPROXY ${GOPROXY:-direct}
@ -9,39 +9,21 @@ ARG TAGS="sqlite sqlite_unlock_notify"
ENV TAGS "bindata timetzdata $TAGS"
ARG CGO_EXTRA_CFLAGS
# Build deps
RUN apk --no-cache add \
build-base \
git \
nodejs \
npm \
&& rm -rf /var/cache/apk/*
#Build deps
RUN apk --no-cache add build-base git nodejs npm
# Setup repo
#Setup repo
COPY . ${GOPATH}/src/code.gitea.io/gitea
WORKDIR ${GOPATH}/src/code.gitea.io/gitea
# Checkout version if set
#Checkout version if set
RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
&& make clean-all build
# Begin env-to-ini build
RUN go build contrib/environment-to-ini/environment-to-ini.go
# Copy local files
COPY docker/root /tmp/local
# Set permissions
RUN chmod 755 /tmp/local/usr/bin/entrypoint \
/tmp/local/usr/local/bin/gitea \
/tmp/local/etc/s6/gitea/* \
/tmp/local/etc/s6/openssh/* \
/tmp/local/etc/s6/.s6-svscan/* \
/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 docker.io/library/alpine:3.19
FROM docker.io/library/alpine:3.17
LABEL maintainer="maintainers@gitea.io"
EXPOSE 22 3000
@ -57,8 +39,7 @@ RUN apk --no-cache add \
s6 \
sqlite \
su-exec \
gnupg \
&& rm -rf /var/cache/apk/*
gnupg
RUN addgroup \
-S -g 1000 \
@ -80,7 +61,10 @@ VOLUME ["/data"]
ENTRYPOINT ["/usr/bin/entrypoint"]
CMD ["/bin/s6-svscan", "/etc/s6"]
COPY --from=build-env /tmp/local /
COPY docker/root /
COPY --from=build-env /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
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
RUN chmod 755 /usr/bin/entrypoint /app/gitea/gitea /usr/local/bin/gitea /usr/local/bin/environment-to-ini
RUN chmod 755 /etc/s6/gitea/* /etc/s6/openssh/* /etc/s6/.s6-svscan/*
RUN chmod 644 /etc/profile.d/gitea_bash_autocomplete.sh

View File

@ -1,5 +1,5 @@
# Build stage
FROM docker.io/library/golang:1.22-alpine3.19 AS build-env
#Build stage
FROM docker.io/library/golang:1.20-alpine3.17 AS build-env
ARG GOPROXY
ENV GOPROXY ${GOPROXY:-direct}
@ -10,36 +10,20 @@ ENV TAGS "bindata timetzdata $TAGS"
ARG CGO_EXTRA_CFLAGS
#Build deps
RUN apk --no-cache add \
build-base \
git \
nodejs \
npm \
&& rm -rf /var/cache/apk/*
RUN apk --no-cache add build-base git nodejs npm
# Setup repo
#Setup repo
COPY . ${GOPATH}/src/code.gitea.io/gitea
WORKDIR ${GOPATH}/src/code.gitea.io/gitea
# Checkout version if set
#Checkout version if set
RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
&& make clean-all build
# Begin env-to-ini build
RUN go build contrib/environment-to-ini/environment-to-ini.go
# Copy local files
COPY docker/rootless /tmp/local
# Set permissions
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/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 docker.io/library/alpine:3.19
FROM docker.io/library/alpine:3.17
LABEL maintainer="maintainers@gitea.io"
EXPOSE 2222 3000
@ -51,8 +35,7 @@ RUN apk --no-cache add \
gettext \
git \
curl \
gnupg \
&& rm -rf /var/cache/apk/*
gnupg
RUN addgroup \
-S -g 1000 \
@ -68,19 +51,21 @@ RUN addgroup \
RUN mkdir -p /var/lib/gitea /etc/gitea
RUN chown git:git /var/lib/gitea /etc/gitea
COPY --from=build-env /tmp/local /
COPY docker/rootless /
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
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
RUN chmod 755 /usr/local/bin/docker-entrypoint.sh /usr/local/bin/docker-setup.sh /app/gitea/gitea /usr/local/bin/gitea /usr/local/bin/environment-to-ini
RUN chmod 644 /etc/profile.d/gitea_bash_autocomplete.sh
# git:git
#git:git
USER 1000:1000
ENV GITEA_WORK_DIR /var/lib/gitea
ENV GITEA_CUSTOM /var/lib/gitea/custom
ENV GITEA_TEMP /tmp/gitea
ENV TMPDIR /tmp/gitea
# TODO add to docs the ability to define the ini to load (useful to test and revert a config)
#TODO add to docs the ability to define the ini to load (useful to test and revert a config)
ENV GITEA_APP_INI /etc/gitea/app.ini
ENV HOME "/var/lib/gitea/git"
VOLUME ["/var/lib/gitea", "/etc/gitea"]
@ -88,3 +73,4 @@ WORKDIR /var/lib/gitea
ENTRYPOINT ["/usr/bin/dumb-init", "--", "/usr/local/bin/docker-entrypoint.sh"]
CMD []

View File

@ -5,6 +5,7 @@ Kees de Vries <bouwko@gmail.com> (@Bwko)
Kim Carlbäcker <kim.carlbacker@gmail.com> (@bkcsoft)
LefsFlare <nobody@nobody.tld> (@LefsFlarey)
Lunny Xiao <xiaolunwen@gmail.com> (@lunny)
Matthias Loibl <mail@matthiasloibl.com> (@metalmatze)
Rachid Zarouali <nobody@nobody.tld> (@xinity)
Rémy Boulanouar <admin@dblk.org> (@DblK)
Sandro Santilli <strk@kbt.io> (@strk)
@ -41,22 +42,11 @@ Patrick Schratz <patrick.schratz@gmail.com> (@pat-s)
Janis Estelmann <admin@oldschoolhack.me> (@KN4CK3R)
Steven Kriegler <sk.bunsenbrenner@gmail.com> (@justusbunsi)
Jimmy Praet <jimmy.praet@telenet.be> (@jpraet)
Leon Hofmeister <dev.lh@web.de> (@delvh)
Leon Hofmeister <dev.lh@web.de> (@delvh)
Wim <wim@42.be> (@42wim)
Xinyu Zhou <i@sourcehut.net> (@xin-u)
Jason Song <i@wolfogre.com> (@wolfogre)
Yarden Shoham <git@yardenshoham.com> (@yardenshoham)
Yarden Shoham <hrsi88@gmail.com> (@yardenshoham)
Yu Tian <zettat123@gmail.com> (@Zettat123)
Eddie Yang <576951401@qq.com> (@yp05327)
Dong Ge <gedong_1994@163.com> (@sillyguodong)
Xinyi Gong <hestergong@gmail.com> (@HesterG)
wxiaoguang <wxiaoguang@gmail.com> (@wxiaoguang)
Gary Moon <gary@garymoon.net> (@garymoon)
Philip Peterson <philip.c.peterson@gmail.com> (@philip-peterson)
Denys Konovalov <kontakt@denyskon.de> (@denyskon)
Punit Inani <punitinani1@gmail.com> (@puni9869)
CaiCandong <1290147055@qq.com> (@caicandong)
Rui Chen <rui@chenrui.dev> (@chenrui333)
Nanguan Lin <nanguanlin6@gmail.com> (@lng2020)
kerwin612 <kerwin612@qq.com> (@kerwin612)
Gary Wang <git@blumia.net> (@BLumia)
Tim-Niclas Oelschläger <zokki.softwareschmiede@gmail.com> (@zokkis)
Dong Ge <gedong_1994@163.com> (@sillyguodong)

390
Makefile
View File

@ -20,28 +20,28 @@ IMPORT := code.gitea.io/gitea
GO ?= go
SHASUM ?= shasum -a 256
HAS_GO := $(shell hash $(GO) > /dev/null 2>&1 && echo yes)
HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" )
COMMA := ,
XGO_VERSION := go-1.22.x
XGO_VERSION := go-1.20.x
AIR_PACKAGE ?= github.com/cosmtrek/air@v1.49.0
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/cmd/editorconfig-checker@2.7.0
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.6.0
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.56.1
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/misspell@v0.4.1
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@db51e79a0e37c572d8b59ae0c58bf2bbbbe53285
AIR_PACKAGE ?= github.com/cosmtrek/air@v1.40.4
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/cmd/editorconfig-checker@2.6.0
ERRCHECK_PACKAGE ?= github.com/kisielk/errcheck@v1.6.2
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.4.0
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.51.0
GXZ_PAGAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.10
MISSPELL_PACKAGE ?= github.com/client9/misspell/cmd/misspell@v0.3.4
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.30.3
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.6.0
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1.0.3
ACTIONLINT_PACKAGE ?= github.com/rhysd/actionlint/cmd/actionlint@v1.6.26
GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.5.0
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@latest
DOCKER_IMAGE ?= gitea/gitea
DOCKER_TAG ?= latest
DOCKER_REF := $(DOCKER_IMAGE):$(DOCKER_TAG)
ifeq ($(HAS_GO), yes)
ifeq ($(HAS_GO), GO)
GOPATH ?= $(shell $(GO) env GOPATH)
export PATH := $(GOPATH)/bin:$(PATH)
@ -49,14 +49,10 @@ 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)
ifeq ($(OS), Windows_NT)
GOFLAGS := -v -buildmode=exe
EXECUTABLE ?= gitea.exe
else ifeq ($(OS), Windows)
GOFLAGS := -v -buildmode=exe
EXECUTABLE ?= gitea.exe
else
@ -72,7 +68,7 @@ endif
EXTRA_GOFLAGS ?=
MAKE_VERSION := $(shell "$(MAKE)" -v | cat | head -n 1)
MAKE_VERSION := $(shell "$(MAKE)" -v | head -n 1)
MAKE_EVIDENCE_DIR := .make_evidence
ifeq ($(RACE_ENABLED),true)
@ -83,15 +79,12 @@ endif
STORED_VERSION_FILE := VERSION
HUGO_VERSION ?= 0.111.3
GITHUB_REF_TYPE ?= branch
GITHUB_REF_NAME ?= $(shell git rev-parse --abbrev-ref HEAD)
ifneq ($(GITHUB_REF_TYPE),branch)
VERSION ?= $(subst v,,$(GITHUB_REF_NAME))
ifneq ($(DRONE_TAG),)
VERSION ?= $(subst v,,$(DRONE_TAG))
GITEA_VERSION ?= $(VERSION)
else
ifneq ($(GITHUB_REF_NAME),)
VERSION ?= $(subst release/v,,$(GITHUB_REF_NAME))
ifneq ($(DRONE_BRANCH),)
VERSION ?= $(subst release/v,,$(DRONE_BRANCH))
else
VERSION ?= main
endif
@ -115,21 +108,20 @@ LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64
GO_PACKAGES ?= $(filter-out 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 ./... | grep -v /vendor/))
GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/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 ./... | grep -v /vendor/))
MIGRATE_TEST_PACKAGES ?= $(shell $(GO) list code.gitea.io/gitea/models/migrations/...)
FOMANTIC_WORK_DIR := web_src/fomantic
WEBPACK_SOURCES := $(shell find web_src/js web_src/css -type f)
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 public/assets/img/webpack
WEBPACK_CONFIGS := webpack.config.js
WEBPACK_DEST := public/js/index.js public/css/index.css
WEBPACK_DEST_ENTRIES := public/js public/css public/fonts public/img/webpack public/serviceworker.js
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
SVG_DEST_DIR := public/assets/img/svg
SVG_DEST_DIR := public/img/svg
AIR_TMP_DIR := .air
@ -144,12 +136,9 @@ TEST_TAGS ?= sqlite sqlite_unlock_notify
TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(FOMANTIC_WORK_DIR)/node_modules $(DIST) $(MAKE_EVIDENCE_DIR) $(AIR_TMP_DIR) $(GO_LICENSE_TMP_DIR)
GO_DIRS := build cmd models modules routers services tests
GO_DIRS := cmd tests models modules routers build services tools
WEB_DIRS := web_src/js web_src/css
SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) docs/content templates options/locale/locale_en-US.ini .github
EDITORCONFIG_FILES := templates .github/workflows options/locale/locale_en-US.ini
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)
GO_SOURCES += $(GENERATED_GO_DEST)
@ -166,8 +155,8 @@ ifdef DEPS_PLAYWRIGHT
endif
SWAGGER_SPEC := templates/swagger/v1_json.tmpl
SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl \| JSEscape}}/api/v1"|g
SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape}}/api/v1"|"basePath": "/api/v1"|g
SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|g
SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|"basePath": "/api/v1"|g
SWAGGER_EXCLUDE := code.gitea.io/sdk
SWAGGER_NEWLINE_COMMAND := -e '$$a\'
@ -175,6 +164,10 @@ TEST_MYSQL_HOST ?= mysql:3306
TEST_MYSQL_DBNAME ?= testgitea
TEST_MYSQL_USERNAME ?= root
TEST_MYSQL_PASSWORD ?=
TEST_MYSQL8_HOST ?= mysql8:3306
TEST_MYSQL8_DBNAME ?= testgitea
TEST_MYSQL8_USERNAME ?= root
TEST_MYSQL8_PASSWORD ?=
TEST_PGSQL_HOST ?= pgsql:5432
TEST_PGSQL_DBNAME ?= testgitea
TEST_PGSQL_USERNAME ?= postgres
@ -203,28 +196,9 @@ help:
@echo " - deps install dependencies"
@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-actions lint action workflow files"
@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-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-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-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"
@ -232,9 +206,6 @@ help:
@echo " - test-frontend test frontend files"
@echo " - test-backend test backend files"
@echo " - test-e2e[\#TestSpecificName] test end to end using playwright"
@echo " - update update js and py dependencies"
@echo " - update-js update js dependencies"
@echo " - update-py update py dependencies"
@echo " - webpack build webpack files"
@echo " - svg build svg files"
@echo " - fomantic build fomantic files"
@ -245,10 +216,13 @@ help:
@echo " - generate-manpage generate manpage"
@echo " - generate-swagger generate the swagger spec from code comments"
@echo " - swagger-validate check if the swagger spec is valid"
@echo " - golangci-lint run golangci-lint linter"
@echo " - go-licenses regenerate go licenses"
@echo " - vet examines Go source code and reports suspicious constructs"
@echo " - tidy run go mod tidy"
@echo " - test[\#TestSpecificName] run unit test"
@echo " - test-sqlite[\#TestSpecificName] run integration test for sqlite"
@echo " - pr#<index> build and start gitea from a PR with integration test data loaded"
.PHONY: go-check
go-check:
@ -284,36 +258,43 @@ clean-all: clean
.PHONY: clean
clean:
$(GO) clean -i ./...
rm -rf $(EXECUTABLE) $(DIST) $(BINDATA_DEST) $(BINDATA_HASH) \
integrations*.test \
e2e*.test \
tests/integration/gitea-integration-* \
tests/integration/indexers-* \
tests/mysql.ini tests/pgsql.ini tests/mssql.ini man/ \
tests/e2e/gitea-e2e-*/ \
tests/e2e/indexers-*/ \
tests/e2e/reports/ tests/e2e/test-artifacts/ tests/e2e/test-snapshots/
tests/integration/gitea-integration-pgsql/ tests/integration/gitea-integration-mysql/ tests/integration/gitea-integration-mysql8/ tests/integration/gitea-integration-sqlite/ \
tests/integration/gitea-integration-mssql/ tests/integration/indexers-mysql/ tests/integration/indexers-mysql8/ tests/integration/indexers-pgsql tests/integration/indexers-sqlite \
tests/integration/indexers-mssql tests/mysql.ini tests/mysql8.ini tests/pgsql.ini tests/mssql.ini man/ \
tests/e2e/gitea-e2e-pgsql/ tests/e2e/gitea-e2e-mysql/ tests/e2e/gitea-e2e-mysql8/ tests/e2e/gitea-e2e-sqlite/ \
tests/e2e/gitea-e2e-mssql/ tests/e2e/indexers-mysql/ tests/e2e/indexers-mysql8/ tests/e2e/indexers-pgsql/ tests/e2e/indexers-sqlite/ \
tests/e2e/indexers-mssql/ tests/e2e/reports/ tests/e2e/test-artifacts/ tests/e2e/test-snapshots/
.PHONY: fmt
fmt:
GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}'
$(eval TEMPLATES := $(shell find templates -type f -name '*.tmpl'))
@# strip whitespace after '{{' or '(' and before '}}' or ')' unless there is only
@# whitespace before it
@$(SED_INPLACE) \
-e 's/{{[ ]\{1,\}/{{/g' -e '/^[ ]\{1,\}}}/! s/[ ]\{1,\}}}/}}/g' \
-e 's/([ ]\{1,\}/(/g' -e '/^[ ]\{1,\})/! s/[ ]\{1,\})/)/g' \
$(TEMPLATES)
@# strip whitespace after '{{' and before `}}` unless there is only whitespace before it
@$(SED_INPLACE) -e 's/{{[ ]\{1,\}/{{/g' -e '/^[ ]\{1,\}}}/! s/[ ]\{1,\}}}/}}/g' $(TEMPLATES)
.PHONY: fmt-check
fmt-check: fmt
@diff=$$(git diff --color=always $(GO_SOURCES) templates $(WEB_DIRS)); \
@diff=$$(git diff $(GO_SOURCES) templates $(WEB_DIRS)); \
if [ -n "$$diff" ]; then \
echo "Please run 'make fmt' and commit the result:"; \
echo "$${diff}"; \
exit 1; \
fi
.PHONY: misspell-check
misspell-check:
go run $(MISSPELL_PACKAGE) -error $(GO_DIRS) $(WEB_DIRS)
.PHONY: vet
vet:
@echo "Running go vet..."
@GOOS= GOARCH= $(GO) build code.gitea.io/gitea-vet
@$(GO) vet -vettool=gitea-vet $(GO_PACKAGES)
.PHONY: $(TAGS_EVIDENCE)
$(TAGS_EVIDENCE):
@mkdir -p $(MAKE_EVIDENCE_DIR)
@ -333,7 +314,7 @@ $(SWAGGER_SPEC): $(GO_SOURCES_NO_BINDATA)
.PHONY: swagger-check
swagger-check: generate-swagger
@diff=$$(git diff --color=always '$(SWAGGER_SPEC)'); \
@diff=$$(git diff '$(SWAGGER_SPEC)'); \
if [ -n "$$diff" ]; then \
echo "Please run 'make generate-swagger' and commit the result:"; \
echo "$${diff}"; \
@ -346,6 +327,11 @@ swagger-validate:
$(GO) run $(SWAGGER_PACKAGE) validate './$(SWAGGER_SPEC)'
$(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)'
.PHONY: errcheck
errcheck:
@echo "Running errcheck..."
$(GO) run $(ERRCHECK_PACKAGE) $(GO_PACKAGES)
.PHONY: checks
checks: checks-frontend checks-backend
@ -353,102 +339,28 @@ checks: checks-frontend checks-backend
checks-frontend: lockfile-check svg-check
.PHONY: checks-backend
checks-backend: tidy-check swagger-check fmt-check swagger-validate security-check
checks-backend: tidy-check swagger-check fmt-check misspell-check swagger-validate security-check
.PHONY: lint
lint: lint-frontend lint-backend lint-spell
.PHONY: lint-fix
lint-fix: lint-frontend-fix lint-backend-fix lint-spell-fix
lint: lint-frontend lint-backend
.PHONY: lint-frontend
lint-frontend: lint-js lint-css
.PHONY: lint-frontend-fix
lint-frontend-fix: lint-js-fix lint-css-fix
.PHONY: lint-backend
lint-backend: lint-go lint-go-vet lint-editorconfig
.PHONY: lint-backend-fix
lint-backend-fix: lint-go-fix lint-go-vet lint-editorconfig
.PHONY: lint-js
lint-js: node_modules
npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js tests/e2e
.PHONY: lint-js-fix
lint-js-fix: node_modules
npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js tests/e2e --fix
.PHONY: lint-css
lint-css: node_modules
npx stylelint --color --max-warnings=0 web_src/css web_src/js/components/*.vue
.PHONY: lint-css-fix
lint-css-fix: node_modules
npx stylelint --color --max-warnings=0 web_src/css web_src/js/components/*.vue --fix
.PHONY: lint-swagger
lint-swagger: node_modules
lint-frontend: node_modules
npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js docs/assets/js tests/e2e
npx stylelint --color --max-warnings=0 web_src/css
npx spectral lint -q -F hint $(SWAGGER_SPEC)
.PHONY: lint-md
lint-md: node_modules
npx markdownlint docs *.md
.PHONY: lint-spell
lint-spell:
@go run $(MISSPELL_PACKAGE) -error $(SPELLCHECK_FILES)
.PHONY: lint-spell-fix
lint-spell-fix:
@go run $(MISSPELL_PACKAGE) -w $(SPELLCHECK_FILES)
.PHONY: lint-go
lint-go:
$(GO) run $(GOLANGCI_LINT_PACKAGE) run
.PHONY: lint-go-fix
lint-go-fix:
$(GO) run $(GOLANGCI_LINT_PACKAGE) run --fix
# 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..."
@GOOS= GOARCH= $(GO) build code.gitea.io/gitea-vet
@$(GO) vet -vettool=gitea-vet $(GO_PACKAGES)
.PHONY: lint-editorconfig
lint-editorconfig:
@$(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) $(EDITORCONFIG_FILES)
.PHONY: lint-actions
lint-actions:
$(GO) run $(ACTIONLINT_PACKAGE)
.PHONY: lint-templates
lint-templates: .venv
@poetry run djlint $(shell find templates -type f -iname '*.tmpl')
.PHONY: lint-yaml
lint-yaml: .venv
@poetry run yamllint .
.PHONY: lint-backend
lint-backend: golangci-lint vet editorconfig-checker
.PHONY: watch
watch:
@bash build/watch.sh
bash tools/watch.sh
.PHONY: watch-frontend
watch-frontend: node-check node_modules
@rm -rf $(WEBPACK_DEST_ENTRIES)
rm -rf $(WEBPACK_DEST_ENTRIES)
NODE_ENV=development npx webpack --watch --progress
.PHONY: watch-backend
@ -507,7 +419,7 @@ vendor: go.mod go.sum
.PHONY: tidy-check
tidy-check: tidy
@diff=$$(git diff --color=always go.mod go.sum $(GO_LICENSE_FILE)); \
@diff=$$(git diff go.mod go.sum $(GO_LICENSE_FILE)); \
if [ -n "$$diff" ]; then \
echo "Please run 'make tidy' and commit the result:"; \
echo "$${diff}"; \
@ -560,6 +472,27 @@ test-mysql\#%: integrations.mysql.test generate-ini-mysql
.PHONY: test-mysql-migration
test-mysql-migration: migrations.mysql.test migrations.individual.mysql.test
generate-ini-mysql8:
sed -e 's|{{TEST_MYSQL8_HOST}}|${TEST_MYSQL8_HOST}|g' \
-e 's|{{TEST_MYSQL8_DBNAME}}|${TEST_MYSQL8_DBNAME}|g' \
-e 's|{{TEST_MYSQL8_USERNAME}}|${TEST_MYSQL8_USERNAME}|g' \
-e 's|{{TEST_MYSQL8_PASSWORD}}|${TEST_MYSQL8_PASSWORD}|g' \
-e 's|{{REPO_TEST_DIR}}|${REPO_TEST_DIR}|g' \
-e 's|{{TEST_LOGGER}}|$(or $(TEST_LOGGER),test$(COMMA)file)|g' \
-e 's|{{TEST_TYPE}}|$(or $(TEST_TYPE),integration)|g' \
tests/mysql8.ini.tmpl > tests/mysql8.ini
.PHONY: test-mysql8
test-mysql8: integrations.mysql8.test generate-ini-mysql8
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./integrations.mysql8.test
.PHONY: test-mysql8\#%
test-mysql8\#%: integrations.mysql8.test generate-ini-mysql8
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./integrations.mysql8.test -test.run $(subst .,/,$*)
.PHONY: test-mysql8-migration
test-mysql8-migration: migrations.mysql8.test migrations.individual.mysql8.test
generate-ini-pgsql:
sed -e 's|{{TEST_PGSQL_HOST}}|${TEST_PGSQL_HOST}|g' \
-e 's|{{TEST_PGSQL_DBNAME}}|${TEST_PGSQL_DBNAME}|g' \
@ -604,7 +537,8 @@ test-mssql\#%: integrations.mssql.test generate-ini-mssql
test-mssql-migration: migrations.mssql.test migrations.individual.mssql.test
.PHONY: playwright
playwright: deps-frontend
playwright: $(PLAYWRIGHT_DIR)
npm install --no-save @playwright/test
npx playwright install $(PLAYWRIGHT_FLAGS)
.PHONY: test-e2e%
@ -631,6 +565,14 @@ test-e2e-mysql: playwright e2e.mysql.test generate-ini-mysql
test-e2e-mysql\#%: playwright e2e.mysql.test generate-ini-mysql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./e2e.mysql.test -test.run TestE2e/$*
.PHONY: test-e2e-mysql8
test-e2e-mysql8: playwright e2e.mysql8.test generate-ini-mysql8
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./e2e.mysql8.test
.PHONY: test-e2e-mysql8\#%
test-e2e-mysql8\#%: playwright e2e.mysql8.test generate-ini-mysql8
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./e2e.mysql8.test -test.run TestE2e/$*
.PHONY: test-e2e-pgsql
test-e2e-pgsql: playwright e2e.pgsql.test generate-ini-pgsql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./e2e.pgsql.test
@ -674,6 +616,9 @@ integration-test-coverage-sqlite: integrations.cover.sqlite.test generate-ini-sq
integrations.mysql.test: git-check $(GO_SOURCES)
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.mysql.test
integrations.mysql8.test: git-check $(GO_SOURCES)
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.mysql8.test
integrations.pgsql.test: git-check $(GO_SOURCES)
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.pgsql.test
@ -694,6 +639,11 @@ migrations.mysql.test: $(GO_SOURCES) generate-ini-mysql
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.mysql.test
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./migrations.mysql.test
.PHONY: migrations.mysql8.test
migrations.mysql8.test: $(GO_SOURCES) generate-ini-mysql8
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.mysql8.test
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./migrations.mysql8.test
.PHONY: migrations.pgsql.test
migrations.pgsql.test: $(GO_SOURCES) generate-ini-pgsql
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.pgsql.test
@ -711,23 +661,36 @@ migrations.sqlite.test: $(GO_SOURCES) generate-ini-sqlite
.PHONY: migrations.individual.mysql.test
migrations.individual.mysql.test: $(GO_SOURCES)
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES)
for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/...); do \
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg; \
done
.PHONY: migrations.individual.sqlite.test\#%
.PHONY: migrations.individual.mysql8.test
migrations.individual.mysql8.test: $(GO_SOURCES)
for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/...); do \
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg; \
done
.PHONY: migrations.individual.mysql8.test\#%
migrations.individual.sqlite.test\#%: $(GO_SOURCES) generate-ini-sqlite
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$*
.PHONY: migrations.individual.pgsql.test
migrations.individual.pgsql.test: $(GO_SOURCES)
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES)
for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/...); do \
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg; \
done
.PHONY: migrations.individual.pgsql.test\#%
migrations.individual.pgsql.test\#%: $(GO_SOURCES) generate-ini-pgsql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$*
.PHONY: migrations.individual.mssql.test
migrations.individual.mssql.test: $(GO_SOURCES) generate-ini-mssql
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES)
for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/...); do \
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg -test.failfast; \
done
.PHONY: migrations.individual.mssql.test\#%
migrations.individual.mssql.test\#%: $(GO_SOURCES) generate-ini-mssql
@ -735,7 +698,9 @@ migrations.individual.mssql.test\#%: $(GO_SOURCES) generate-ini-mssql
.PHONY: migrations.individual.sqlite.test
migrations.individual.sqlite.test: $(GO_SOURCES) generate-ini-sqlite
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -p 1 $(MIGRATE_TEST_PACKAGES)
for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/...); do \
GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg; \
done
.PHONY: migrations.individual.sqlite.test\#%
migrations.individual.sqlite.test\#%: $(GO_SOURCES) generate-ini-sqlite
@ -744,6 +709,9 @@ migrations.individual.sqlite.test\#%: $(GO_SOURCES) generate-ini-sqlite
e2e.mysql.test: $(GO_SOURCES)
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.mysql.test
e2e.mysql8.test: $(GO_SOURCES)
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.mysql8.test
e2e.pgsql.test: $(GO_SOURCES)
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.pgsql.test
@ -800,18 +768,30 @@ release-windows: | $(DIST_DIRS)
ifeq (,$(findstring gogit,$(TAGS)))
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'osusergo gogit $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION)-gogit .
endif
ifeq ($(CI),true)
cp /build/* $(DIST)/binaries
endif
.PHONY: release-linux
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 gitea-$(VERSION) .
ifeq ($(CI),true)
cp /build/* $(DIST)/binaries
endif
.PHONY: release-darwin
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) .
ifeq ($(CI),true)
cp /build/* $(DIST)/binaries
endif
.PHONY: release-freebsd
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) .
ifeq ($(CI),true)
cp /build/* $(DIST)/binaries
endif
.PHONY: release-copy
release-copy: | $(DIST_DIRS)
@ -823,7 +803,7 @@ release-check: | $(DIST_DIRS)
.PHONY: release-compress
release-compress: | $(DIST_DIRS)
cd $(DIST)/release/; for file in `find . -type f -name "*"`; do echo "compressing $${file}" && $(GO) run $(GXZ_PACKAGE) -k -9 $${file}; done;
cd $(DIST)/release/; for file in `find . -type f -name "*"`; do echo "compressing $${file}" && $(GO) run $(GXZ_PAGAGE) -k -9 $${file}; done;
.PHONY: release-sources
release-sources: | $(DIST_DIRS)
@ -837,13 +817,17 @@ release-sources: | $(DIST_DIRS)
.PHONY: release-docs
release-docs: | $(DIST_DIRS) docs
tar -czf $(DIST)/release/gitea-docs-$(VERSION).tar.gz -C ./docs .
tar -czf $(DIST)/release/gitea-docs-$(VERSION).tar.gz -C ./docs/public .
.PHONY: docs
docs:
@hash hugo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
curl -sL https://github.com/gohugoio/hugo/releases/download/v$(HUGO_VERSION)/hugo_$(HUGO_VERSION)_Linux-64bit.tar.gz | tar zxf - -C /tmp && mv /tmp/hugo /usr/bin/hugo && chmod +x /usr/bin/hugo; \
fi
cd docs; make trans-copy clean build-offline;
.PHONY: deps
deps: deps-frontend deps-backend deps-tools deps-py
.PHONY: deps-py
deps-py: .venv
deps: deps-frontend deps-backend
.PHONY: deps-frontend
deps-frontend: node_modules
@ -851,53 +835,35 @@ deps-frontend: node_modules
.PHONY: deps-backend
deps-backend:
$(GO) mod download
.PHONY: deps-tools
deps-tools:
$(GO) install $(AIR_PACKAGE)
$(GO) install $(EDITORCONFIG_CHECKER_PACKAGE)
$(GO) install $(ERRCHECK_PACKAGE)
$(GO) install $(GOFUMPT_PACKAGE)
$(GO) install $(GOLANGCI_LINT_PACKAGE)
$(GO) install $(GXZ_PACKAGE)
$(GO) install $(GXZ_PAGAGE)
$(GO) install $(MISSPELL_PACKAGE)
$(GO) install $(SWAGGER_PACKAGE)
$(GO) install $(XGO_PACKAGE)
$(GO) install $(GO_LICENSES_PACKAGE)
$(GO) install $(GOVULNCHECK_PACKAGE)
$(GO) install $(ACTIONLINT_PACKAGE)
node_modules: package-lock.json
npm install --no-save
@touch node_modules
.venv: poetry.lock
poetry install --no-root
@touch .venv
.PHONY: update
update: update-js update-py
.PHONY: update-js
update-js: node-check | node_modules
npx updates -u -f package.json
.PHONY: npm-update
npm-update: node-check | node_modules
npx updates -cu
rm -rf node_modules package-lock.json
npm install --package-lock
@touch node_modules
.PHONY: update-py
update-py: node-check | node_modules
npx updates -u -f pyproject.toml
rm -rf .venv poetry.lock
poetry install --no-root
@touch .venv
.PHONY: fomantic
fomantic:
rm -rf $(FOMANTIC_WORK_DIR)/build
cd $(FOMANTIC_WORK_DIR) && npm install --no-save
cp -f $(FOMANTIC_WORK_DIR)/theme.config.less $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/theme.config
cp -rf $(FOMANTIC_WORK_DIR)/_site $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/
$(SED_INPLACE) -e 's/ overrideBrowserslist\r/ overrideBrowserslist: ["defaults"]\r/g' $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/tasks/config/tasks.js
cd $(FOMANTIC_WORK_DIR) && npx gulp -f node_modules/fomantic-ui/gulpfile.js build
# fomantic uses "touchstart" as click event for some browsers, it's not ideal, so we force fomantic to always use "click" as click event
$(SED_INPLACE) -e 's/clickEvent[ \t]*=/clickEvent = "click", unstableClickEvent =/g' $(FOMANTIC_WORK_DIR)/build/semantic.js
@ -921,7 +887,7 @@ svg: node-check | node_modules
.PHONY: svg-check
svg-check: svg
@git add $(SVG_DEST_DIR)
@diff=$$(git diff --color=always --cached $(SVG_DEST_DIR)); \
@diff=$$(git diff --cached $(SVG_DEST_DIR)); \
if [ -n "$$diff" ]; then \
echo "Please run 'make svg' and 'git add $(SVG_DEST_DIR)' and commit the result:"; \
echo "$${diff}"; \
@ -931,7 +897,7 @@ svg-check: svg
.PHONY: lockfile-check
lockfile-check:
npm install --package-lock-only
@diff=$$(git diff --color=always package-lock.json); \
@diff=$$(git diff package-lock.json); \
if [ -n "$$diff" ]; then \
echo "package-lock.json is inconsistent with package.json"; \
echo "Please run 'npm install --package-lock-only' and commit the result:"; \
@ -959,7 +925,7 @@ generate-gitignore:
.PHONY: generate-images
generate-images: | node_modules
npm install --no-save fabric@6.0.0-beta19 imagemin-zopfli@7
npm install --no-save --no-package-lock fabric@5 imagemin-zopfli@7
node build/generate-images.js $(TAGS)
.PHONY: generate-manpage
@ -970,15 +936,33 @@ generate-manpage:
@gzip -9 man/man1/gitea.1 && echo man/man1/gitea.1.gz created
@#TODO A small script that formats config-cheat-sheet.en-us.md nicely for use as a config man page
.PHONY: pr\#%
pr\#%: clean-all
$(GO) run contrib/pr/checkout.go $*
.PHONY: golangci-lint
golangci-lint:
$(GO) run $(GOLANGCI_LINT_PACKAGE) run
# workaround step for the lint-backend-windows CI task because 'go run' can not
# have distinct GOOS/GOARCH for its build and run steps
.PHONY: golangci-lint-windows
golangci-lint-windows:
@GOOS= GOARCH= $(GO) install $(GOLANGCI_LINT_PACKAGE)
golangci-lint run
.PHONY: editorconfig-checker
editorconfig-checker:
$(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) templates
.PHONY: docker
docker:
docker build --disable-content-trust=false -t $(DOCKER_REF) .
# support also build args docker build --build-arg GITEA_VERSION=v1.2.3 --build-arg TAGS="bindata sqlite sqlite_unlock_notify" .
.PHONY: docker-build
docker-build:
docker run -ti --rm -v "$(CURDIR):/srv/app/src/code.gitea.io/gitea" -w /srv/app/src/code.gitea.io/gitea -e TAGS="bindata $(TAGS)" LDFLAGS="$(LDFLAGS)" CGO_EXTRA_CFLAGS="$(CGO_EXTRA_CFLAGS)" webhippie/golang:edge make clean build
# This endif closes the if at the top of the file
endif
# Disable parallel execution because it would break some targets that don't
# specify exact dependencies like 'backend' which does currently not depend
# on 'frontend' to enable Node.js-less builds from source tarballs.
.NOTPARALLEL:

View File

@ -1,16 +1,16 @@
<p align="center">
<a href="https://gitea.io/">
<img alt="Gitea" src="https://raw.githubusercontent.com/go-gitea/gitea/main/public/assets/img/gitea.svg" width="220"/>
<img alt="Gitea" src="https://raw.githubusercontent.com/go-gitea/gitea/main/public/img/gitea.svg" width="220"/>
</a>
</p>
<h1 align="center">Gitea - Git with a cup of tea</h1>
<p align="center">
<a href="https://github.com/go-gitea/gitea/actions/workflows/release-nightly.yml?query=branch%3Amain" title="Release Nightly">
<img src="https://github.com/go-gitea/gitea/actions/workflows/release-nightly.yml/badge.svg?branch=main">
<a href="https://drone.gitea.io/go-gitea/gitea" title="Build Status">
<img src="https://drone.gitea.io/api/badges/go-gitea/gitea/status.svg?ref=refs/heads/main">
</a>
<a href="https://discord.gg/Gitea" title="Join the Discord chat at https://discord.gg/Gitea">
<img src="https://img.shields.io/discord/322538954119184384.svg?logo=discord&logoColor=white&label=Discord&color=5865F2">
<img src="https://img.shields.io/discord/322538954119184384.svg">
</a>
<a href="https://app.codecov.io/gh/go-gitea/gitea" title="Codecov">
<img src="https://codecov.io/gh/go-gitea/gitea/branch/main/graph/badge.svg">
@ -45,6 +45,9 @@
<a href="https://www.tickgit.com/browse?repo=github.com/go-gitea/gitea&branch=main" title="TODOs">
<img src="https://badgen.net/https/api.tickgit.com/badgen/github.com/go-gitea/gitea/main">
</a>
<a href="https://app.bountysource.com/teams/gitea" title="Bountysource">
<img src="https://img.shields.io/bountysource/team/gitea/activity">
</a>
</p>
<p align="center">
@ -59,16 +62,11 @@ painless way of setting up a self-hosted Git service.
As Gitea is written in Go, it works across **all** the platforms and
architectures that are supported by Go, including Linux, macOS, and
Windows on x86, amd64, ARM and PowerPC architectures.
You can try it out using [the online demo](https://try.gitea.io/).
This project has been
[forked](https://blog.gitea.com/welcome-to-gitea/) from
[forked](https://blog.gitea.io/2016/12/welcome-to-gitea/) from
[Gogs](https://gogs.io) since November of 2016, but a lot has changed.
For online demonstrations, you can visit [try.gitea.io](https://try.gitea.io).
For accessing free Gitea service (with a limited number of repositories), you can visit [gitea.com](https://gitea.com/user/login).
To quickly deploy your own dedicated Gitea instance on Gitea Cloud, you can start a free trial at [cloud.gitea.com](https://cloud.gitea.com).
## Building
From the root of the source tree, run:
@ -81,28 +79,30 @@ or if SQLite support is required:
The `build` target is split into two sub-targets:
- `make backend` which requires [Go Stable](https://go.dev/dl/), the required version is defined in [go.mod](/go.mod).
- `make frontend` which requires [Node.js LTS](https://nodejs.org/en/download/) or greater.
- `make backend` which requires [Go Stable](https://go.dev/dl/), required version is defined in [go.mod](/go.mod).
- `make frontend` which requires [Node.js LTS](https://nodejs.org/en/download/) or greater and Internet connectivity to download npm dependencies.
Internet connectivity is required to download the go and npm modules. When building from the official source tarballs which include pre-built frontend files, the `frontend` target will not be triggered, making it possible to build without Node.js.
When building from the official source tarballs which include pre-built frontend files, the `frontend` target will not be triggered, making it possible to build without Node.js and Internet connectivity.
More info: https://docs.gitea.com/installation/install-from-source
Parallelism (`make -j <num>`) is not supported.
More info: https://docs.gitea.io/en-us/install-from-source/
## Using
./gitea web
> [!NOTE]
> If you're interested in using our APIs, we have experimental support with [documentation](https://try.gitea.io/api/swagger).
NOTE: If you're interested in using our APIs, we have experimental
support with [documentation](https://try.gitea.io/api/swagger).
## Contributing
Expected workflow is: Fork -> Patch -> Push -> Pull Request
> [!NOTE]
>
> 1. **YOU MUST READ THE [CONTRIBUTORS GUIDE](CONTRIBUTING.md) BEFORE STARTING TO WORK ON A PULL REQUEST.**
> 2. If you have found a vulnerability in the project, please write privately to **security@gitea.io**. Thanks!
NOTES:
1. **YOU MUST READ THE [CONTRIBUTORS GUIDE](CONTRIBUTING.md) BEFORE STARTING TO WORK ON A PULL REQUEST.**
2. If you have found a vulnerability in the project, please write privately to **security@gitea.io**. Thanks!
## Translating
@ -110,17 +110,19 @@ Translations are done through Crowdin. If you want to translate to a new languag
You can also just create an issue for adding a language or ask on discord on the #translation channel. If you need context or find some translation issues, you can leave a comment on the string or ask on Discord. For general translation questions there is a section in the docs. Currently a bit empty but we hope to fill it as questions pop up.
https://docs.gitea.com/contributing/localization
https://docs.gitea.io/en-us/translation-guidelines/
[![Crowdin](https://badges.crowdin.net/gitea/localized.svg)](https://crowdin.com/project/gitea)
## Further information
For more information and instructions about how to install Gitea, please look at our [documentation](https://docs.gitea.com/).
For more information and instructions about how to install Gitea, please look at our [documentation](https://docs.gitea.io/en-us/).
If you have questions that are not covered by the documentation, you can get in contact with us on our [Discord server](https://discord.gg/Gitea) or create a post in the [discourse forum](https://discourse.gitea.io/).
We maintain a list of Gitea-related projects at [gitea/awesome-gitea](https://gitea.com/gitea/awesome-gitea).
The Hugo-based documentation theme is hosted at [gitea/theme](https://gitea.com/gitea/theme).
The official Gitea CLI is developed at [gitea/tea](https://gitea.com/gitea/tea).
## Authors
@ -149,6 +151,7 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
<a href="https://opencollective.com/gitea/sponsor/7/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/7/avatar.svg"></a>
<a href="https://opencollective.com/gitea/sponsor/8/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/gitea/sponsor/9/website" target="_blank"><img src="https://opencollective.com/gitea/sponsor/9/avatar.svg"></a>
<a href="https://cynkra.com/" target="_blank"><img src="https://images.opencollective.com/cynkra/logo/square/64/192.png"></a>
## FAQ
@ -170,8 +173,8 @@ for the full license text.
Looking for an overview of the interface? Check it out!
|![Dashboard](https://dl.gitea.com/screenshots/home_timeline.png)|![User Profile](https://dl.gitea.com/screenshots/user_profile.png)|![Global Issues](https://dl.gitea.com/screenshots/global_issues.png)|
|![Dashboard](https://dl.gitea.io/screenshots/home_timeline.png)|![User Profile](https://dl.gitea.io/screenshots/user_profile.png)|![Global Issues](https://dl.gitea.io/screenshots/global_issues.png)|
|:---:|:---:|:---:|
|![Branches](https://dl.gitea.com/screenshots/branches.png)|![Web Editor](https://dl.gitea.com/screenshots/web_editor.png)|![Activity](https://dl.gitea.com/screenshots/activity.png)|
|![New Migration](https://dl.gitea.com/screenshots/migration.png)|![Migrating](https://dl.gitea.com/screenshots/migration.gif)|![Pull Request View](https://image.ibb.co/e02dSb/6.png)|
|![Pull Request Dark](https://dl.gitea.com/screenshots/pull_requests_dark.png)|![Diff Review Dark](https://dl.gitea.com/screenshots/review_dark.png)|![Diff Dark](https://dl.gitea.com/screenshots/diff_dark.png)|
|![Branches](https://dl.gitea.io/screenshots/branches.png)|![Web Editor](https://dl.gitea.io/screenshots/web_editor.png)|![Activity](https://dl.gitea.io/screenshots/activity.png)|
|![New Migration](https://dl.gitea.io/screenshots/migration.png)|![Migrating](https://dl.gitea.io/screenshots/migration.gif)|![Pull Request View](https://image.ibb.co/e02dSb/6.png)
![Pull Request Dark](https://dl.gitea.io/screenshots/pull_requests_dark.png)|![Diff Review Dark](https://dl.gitea.io/screenshots/review_dark.png)|![Diff Dark](https://dl.gitea.io/screenshots/diff_dark.png)|

View File

@ -1,13 +1,13 @@
<p align="center">
<a href="https://gitea.io/">
<img alt="Gitea" src="https://raw.githubusercontent.com/go-gitea/gitea/main/public/assets/img/gitea.svg" width="220"/>
<img alt="Gitea" src="https://raw.githubusercontent.com/go-gitea/gitea/main/public/img/gitea.svg" width="220"/>
</a>
</p>
<h1 align="center">Gitea - Git with a cup of tea</h1>
<p align="center">
<a href="https://github.com/go-gitea/gitea/actions/workflows/release-nightly.yml?query=branch%3Amain" title="Release Nightly">
<img src="https://github.com/go-gitea/gitea/actions/workflows/release-nightly.yml/badge.svg?branch=main">
<a href="https://drone.gitea.io/go-gitea/gitea" title="Build Status">
<img src="https://drone.gitea.io/api/badges/go-gitea/gitea/status.svg?ref=refs/heads/main">
</a>
<a href="https://discord.gg/Gitea" title="Join the Discord chat at https://discord.gg/Gitea">
<img src="https://img.shields.io/discord/322538954119184384.svg">
@ -45,6 +45,9 @@
<a href="https://www.tickgit.com/browse?repo=github.com/go-gitea/gitea&branch=main" title="TODOs">
<img src="https://badgen.net/https/api.tickgit.com/badgen/github.com/go-gitea/gitea/main">
</a>
<a href="https://app.bountysource.com/teams/gitea" title="Bountysource">
<img src="https://img.shields.io/bountysource/team/gitea/activity">
</a>
</p>
<p align="center">
@ -55,11 +58,7 @@
Gitea 的首要目标是创建一个极易安装,运行非常快速,安装和使用体验良好的自建 Git 服务。我们采用 Go 作为后端语言,这使我们只要生成一个可执行程序即可。并且他还支持跨平台,支持 Linux, macOS 和 Windows 以及各种架构,除了 x86amd64还包括 ARM 和 PowerPC。
如果你想试用在线演示,请访问 [try.gitea.io](https://try.gitea.io/)。
如果你想使用免费的 Gitea 服务(有仓库数量限制),请访问 [gitea.com](https://gitea.com/user/login)。
如果你想在 Gitea Cloud 上快速部署你自己独享的 Gitea 实例,请访问 [cloud.gitea.com](https://cloud.gitea.com) 开始免费试用。
如果您想试用一下,请访问 [在线Demo](https://try.gitea.io/)
## 提示
@ -69,7 +68,7 @@ Gitea 的首要目标是创建一个极易安装,运行非常快速,安装
## 文档
关于如何安装请访问我们的 [文档站](https://docs.gitea.com/zh-cn/category/installation),如果没有找到对应的文档,你也可以通过 [Discord - 英文](https://discord.gg/gitea) 和 QQ群 328432459 来和我们交流。
关于如何安装请访问我们的 [文档站](https://docs.gitea.io/zh-cn/),如果没有找到对应的文档,你也可以通过 [Discord - 英文](https://discord.gg/gitea) 和 QQ群 328432459 来和我们交流。
## 贡献流程
@ -92,8 +91,8 @@ Fork -> Patch -> Push -> Pull Request
## 截图
|![Dashboard](https://dl.gitea.com/screenshots/home_timeline.png)|![User Profile](https://dl.gitea.com/screenshots/user_profile.png)|![Global Issues](https://dl.gitea.com/screenshots/global_issues.png)|
|![Dashboard](https://dl.gitea.io/screenshots/home_timeline.png)|![User Profile](https://dl.gitea.io/screenshots/user_profile.png)|![Global Issues](https://dl.gitea.io/screenshots/global_issues.png)|
|:---:|:---:|:---:|
|![Branches](https://dl.gitea.com/screenshots/branches.png)|![Web Editor](https://dl.gitea.com/screenshots/web_editor.png)|![Activity](https://dl.gitea.com/screenshots/activity.png)|
|![New Migration](https://dl.gitea.com/screenshots/migration.png)|![Migrating](https://dl.gitea.com/screenshots/migration.gif)|![Pull Request View](https://image.ibb.co/e02dSb/6.png)|
|![Pull Request Dark](https://dl.gitea.com/screenshots/pull_requests_dark.png)|![Diff Review Dark](https://dl.gitea.com/screenshots/review_dark.png)|![Diff Dark](https://dl.gitea.com/screenshots/diff_dark.png)|
|![Branches](https://dl.gitea.io/screenshots/branches.png)|![Web Editor](https://dl.gitea.io/screenshots/web_editor.png)|![Activity](https://dl.gitea.io/screenshots/activity.png)|
|![New Migration](https://dl.gitea.io/screenshots/migration.png)|![Migrating](https://dl.gitea.io/screenshots/migration.gif)|![Pull Request View](https://image.ibb.co/e02dSb/6.png)
![Pull Request Dark](https://dl.gitea.io/screenshots/pull_requests_dark.png)|![Diff Review Dark](https://dl.gitea.io/screenshots/review_dark.png)|![Diff Dark](https://dl.gitea.io/screenshots/diff_dark.png)|

View File

@ -4,15 +4,13 @@ The Gitea maintainers take security seriously.
If you discover a security issue, please bring it to their attention right away!
Previous vulnerabilities are listed at https://about.gitea.com/security.
## Reporting a Vulnerability
Please **DO NOT** file a public issue, instead send your report privately to `security@gitea.io`.
## Protecting Security Information
Due to the sensitive nature of security information, you can use the below GPG public key to encrypt your mail body.
Due to the sensitive nature of security information, you can use below GPG public key encrypt your mail body.
The PGP key is valid until June 24, 2024.

2
assets/emoji.json generated

File diff suppressed because one or more lines are too long

203
assets/go-licenses.json generated

File diff suppressed because one or more lines are too long

View File

@ -1,115 +0,0 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
//go:build ignore
package main
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/setting"
)
func main() {
if len(os.Args) != 2 {
println("usage: backport-locales <to-ref>")
println("eg: backport-locales release/v1.19")
os.Exit(1)
}
mustNoErr := func(err error) {
if err != nil {
panic(err)
}
}
collectInis := func(ref string) map[string]setting.ConfigProvider {
inis := map[string]setting.ConfigProvider{}
err := filepath.WalkDir("options/locale", func(path string, d os.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() || !strings.HasSuffix(d.Name(), ".ini") {
return nil
}
cfg, err := setting.NewConfigProviderForLocale(path)
mustNoErr(err)
inis[path] = cfg
fmt.Printf("collecting: %s @ %s\n", path, ref)
return nil
})
mustNoErr(err)
return inis
}
// collect new locales from current working directory
inisNew := collectInis("HEAD")
// switch to the target ref, and collect the old locales
cmd := exec.Command("git", "checkout", os.Args[1])
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
mustNoErr(cmd.Run())
inisOld := collectInis(os.Args[1])
// use old en-US as the base, and copy the new translations to the old locales
enUsOld := inisOld["options/locale/locale_en-US.ini"]
brokenWarned := make(container.Set[string])
for path, iniOld := range inisOld {
if iniOld == enUsOld {
continue
}
iniNew := inisNew[path]
if iniNew == nil {
continue
}
for _, secEnUS := range enUsOld.Sections() {
secOld := iniOld.Section(secEnUS.Name())
secNew := iniNew.Section(secEnUS.Name())
for _, keyEnUs := range secEnUS.Keys() {
if secNew.HasKey(keyEnUs.Name()) {
oldStr := secOld.Key(keyEnUs.Name()).String()
newStr := secNew.Key(keyEnUs.Name()).String()
broken := oldStr != "" && strings.Count(oldStr, "%") != strings.Count(newStr, "%")
broken = broken || strings.Contains(oldStr, "\n") || strings.Contains(oldStr, "\n")
if broken {
brokenWarned.Add(secOld.Name() + "." + keyEnUs.Name())
fmt.Println("----")
fmt.Printf("WARNING: skip broken locale: %s , [%s] %s\n", path, secEnUS.Name(), keyEnUs.Name())
fmt.Printf("\told: %s\n", strings.ReplaceAll(oldStr, "\n", "\\n"))
fmt.Printf("\tnew: %s\n", strings.ReplaceAll(newStr, "\n", "\\n"))
continue
}
secOld.Key(keyEnUs.Name()).SetValue(newStr)
}
}
}
mustNoErr(iniOld.SaveTo(path))
}
fmt.Println("========")
for path, iniNew := range inisNew {
for _, sec := range iniNew.Sections() {
for _, key := range sec.Keys() {
str := sec.Key(key.Name()).String()
broken := strings.Contains(str, "\n")
broken = broken || strings.HasPrefix(str, "`") != strings.HasSuffix(str, "`")
broken = broken || strings.HasPrefix(str, "\"`")
broken = broken || strings.HasPrefix(str, "`\"")
broken = broken || strings.Count(str, `"`)%2 == 1
broken = broken || strings.Count(str, "`")%2 == 1
if broken && !brokenWarned.Contains(sec.Name()+"."+key.Name()) {
fmt.Printf("WARNING: found broken locale: %s , [%s] %s\n", path, sec.Name(), key.Name())
fmt.Printf("\tstr: %s\n", strings.ReplaceAll(str, "\n", "\\n"))
fmt.Println("----")
}
}
}
}
}

View File

@ -25,7 +25,7 @@ import (
var optionLogVerbose bool
func logVerbose(msg string, args ...any) {
func logVerbose(msg string, args ...interface{}) {
if optionLogVerbose {
log.Printf(msg, args...)
}
@ -65,6 +65,7 @@ func newFileCollector(fileFilter string, batchSize int) (*fileCollector, error)
"modules",
"routers",
"services",
"tools",
}
co.includePatterns = append(co.includePatterns, regexp.MustCompile(`.*\.go$`))

View File

@ -25,7 +25,7 @@ import (
const (
gemojiURL = "https://raw.githubusercontent.com/github/gemoji/master/db/emoji.json"
maxUnicodeVersion = 15
maxUnicodeVersion = 14
)
var flagOut = flag.String("o", "modules/emoji/emoji_data.go", "out")
@ -60,13 +60,13 @@ func main() {
// generate data
buf, err := generate()
if err != nil {
log.Fatalf("generate err: %v", err)
log.Fatal(err)
}
// write
err = os.WriteFile(*flagOut, buf, 0o644)
if err != nil {
log.Fatalf("WriteFile err: %v", err)
log.Fatal(err)
}
}

View File

@ -7,16 +7,13 @@ package main
import (
"encoding/json"
"fmt"
"io/fs"
"os"
"path"
goPath "path"
"path/filepath"
"regexp"
"sort"
"strings"
"code.gitea.io/gitea/modules/container"
)
// regexp is based on go-license, excluding README and NOTICE
@ -30,41 +27,14 @@ type LicenseEntry struct {
}
func main() {
if len(os.Args) != 3 {
fmt.Println("usage: go run generate-go-licenses.go <base-dir> <out-json-file>")
os.Exit(1)
}
base, out := os.Args[1], os.Args[2]
// Add ext for excluded files because license_test.go will be included for some reason.
// And there are more files that should be excluded, check with:
//
// go run github.com/google/go-licenses@v1.6.0 save . --force --save_path=.go-licenses 2>/dev/null
// find .go-licenses -type f | while read FILE; do echo "${$(basename $FILE)##*.}"; done | sort -u
// AUTHORS
// COPYING
// LICENSE
// Makefile
// NOTICE
// gitignore
// go
// md
// mod
// sum
// toml
// txt
// yml
//
// It could be removed once we have a better regex.
excludedExt := container.SetOf(".gitignore", ".go", ".mod", ".sum", ".toml", ".yml")
var paths []string
paths := []string{}
err := filepath.WalkDir(base, func(path string, entry fs.DirEntry, err error) error {
if err != nil {
return err
}
if entry.IsDir() || !licenseRe.MatchString(entry.Name()) || excludedExt.Contains(filepath.Ext(entry.Name())) {
if entry.IsDir() || !licenseRe.MatchString(entry.Name()) {
return nil
}
paths = append(paths, path)
@ -76,27 +46,28 @@ func main() {
sort.Strings(paths)
var entries []LicenseEntry
for _, filePath := range paths {
licenseText, err := os.ReadFile(filePath)
entries := []LicenseEntry{}
for _, path := range paths {
path := filepath.ToSlash(path)
licenseText, err := os.ReadFile(path)
if err != nil {
panic(err)
}
pkgPath := filepath.ToSlash(filePath)
pkgPath = strings.TrimPrefix(pkgPath, base+"/")
pkgName := path.Dir(pkgPath)
path = strings.Replace(path, base+"/", "", 1)
name := goPath.Dir(path)
// There might be a bug somewhere in go-licenses that sometimes interprets the
// 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 == "code.gitea.io/gitea" {
if name == "." || name == "code.gitea.io/gitea" {
continue
}
entries = append(entries, LicenseEntry{
Name: pkgName,
Path: pkgPath,
Name: name,
Path: path,
LicenseText: string(licenseText),
})
}
@ -106,11 +77,6 @@ func main() {
panic(err)
}
// Ensure file has a final newline
if jsonBytes[len(jsonBytes)-1] != '\n' {
jsonBytes = append(jsonBytes, '\n')
}
err = os.WriteFile(out, jsonBytes, 0o644)
if err != nil {
panic(err)

View File

@ -1,13 +1,20 @@
#!/usr/bin/env node
import imageminZopfli from 'imagemin-zopfli';
import {optimize} from 'svgo';
import {loadSVGFromString, Canvas, Rect, util} from 'fabric/node';
import {fabric} from 'fabric';
import {readFile, writeFile} from 'node:fs/promises';
import {argv, exit} from 'node:process';
function doExit(err) {
function exit(err) {
if (err) console.error(err);
exit(err ? 1 : 0);
process.exit(err ? 1 : 0);
}
function loadSvg(svg) {
return new Promise((resolve) => {
fabric.loadSVGFromString(svg, (objects, options) => {
resolve({objects, options});
});
});
}
async function generate(svg, path, {size, bg}) {
@ -28,14 +35,14 @@ async function generate(svg, path, {size, bg}) {
return;
}
const {objects, options} = await loadSVGFromString(svg);
const canvas = new Canvas();
const {objects, options} = await loadSvg(svg);
const canvas = new fabric.Canvas();
canvas.setDimensions({width: size, height: size});
const ctx = canvas.getContext('2d');
ctx.scale(options.width ? (size / options.width) : 1, options.height ? (size / options.height) : 1);
if (bg) {
canvas.add(new Rect({
canvas.add(new fabric.Rect({
left: 0,
top: 0,
height: size * (1 / (size / options.height)),
@ -44,7 +51,7 @@ async function generate(svg, path, {size, bg}) {
}));
}
canvas.add(util.groupSVGElements(objects, options));
canvas.add(fabric.util.groupSVGElements(objects, options));
canvas.renderAll();
let png = Buffer.from([]);
@ -57,23 +64,19 @@ async function generate(svg, path, {size, bg}) {
}
async function main() {
const gitea = argv.slice(2).includes('gitea');
const gitea = process.argv.slice(2).includes('gitea');
const logoSvg = await readFile(new URL('../assets/logo.svg', import.meta.url), 'utf8');
const faviconSvg = await readFile(new URL('../assets/favicon.svg', import.meta.url), 'utf8');
await Promise.all([
generate(logoSvg, '../public/assets/img/logo.svg', {size: 32}),
generate(logoSvg, '../public/assets/img/logo.png', {size: 512}),
generate(faviconSvg, '../public/assets/img/favicon.svg', {size: 32}),
generate(faviconSvg, '../public/assets/img/favicon.png', {size: 180}),
generate(logoSvg, '../public/assets/img/avatar_default.png', {size: 200}),
generate(logoSvg, '../public/assets/img/apple-touch-icon.png', {size: 180, bg: true}),
gitea && generate(logoSvg, '../public/assets/img/gitea.svg', {size: 32}),
generate(logoSvg, '../public/img/logo.svg', {size: 32}),
generate(logoSvg, '../public/img/logo.png', {size: 512}),
generate(faviconSvg, '../public/img/favicon.svg', {size: 32}),
generate(faviconSvg, '../public/img/favicon.png', {size: 180}),
generate(logoSvg, '../public/img/avatar_default.png', {size: 200}),
generate(logoSvg, '../public/img/apple-touch-icon.png', {size: 180, bg: true}),
gitea && generate(logoSvg, '../public/img/gitea.svg', {size: 32}),
]);
}
try {
doExit(await main());
} catch (err) {
doExit(err);
}
main().then(exit).catch(exit);

View File

@ -4,16 +4,15 @@ import {optimize} from 'svgo';
import {parse} from 'node:path';
import {readFile, writeFile, mkdir} from 'node:fs/promises';
import {fileURLToPath} from 'node:url';
import {exit} from 'node:process';
const glob = (pattern) => fastGlob.sync(pattern, {
cwd: fileURLToPath(new URL('..', import.meta.url)),
absolute: true,
});
function doExit(err) {
function exit(err) {
if (err) console.error(err);
exit(err ? 1 : 0);
process.exit(err ? 1 : 0);
}
async function processFile(file, {prefix, fullName} = {}) {
@ -26,26 +25,18 @@ async function processFile(file, {prefix, fullName} = {}) {
if (prefix === 'octicon') name = name.replace(/-[0-9]+$/, ''); // chop of '-16' on octicons
}
// Set the `xmlns` attribute so that the files are displayable in standalone documents
// The svg backend module will strip the attribute during startup for inline display
const {data} = optimize(await readFile(file, 'utf8'), {
plugins: [
{name: 'preset-default'},
{name: 'removeXMLNS'},
{name: 'removeDimensions'},
{name: 'prefixIds', params: {prefix: () => name}},
{name: 'addClassesToSVGElement', params: {classNames: ['svg', name]}},
{
name: 'addAttributesToSVGElement', params: {
attributes: [
{'xmlns': 'http://www.w3.org/2000/svg'},
{'width': '16'}, {'height': '16'}, {'aria-hidden': 'true'},
]
}
},
{name: 'addAttributesToSVGElement', params: {attributes: [{'width': '16'}, {'height': '16'}, {'aria-hidden': 'true'}]}},
],
});
await writeFile(fileURLToPath(new URL(`../public/assets/img/svg/${name}.svg`, import.meta.url)), data);
await writeFile(fileURLToPath(new URL(`../public/img/svg/${name}.svg`, import.meta.url)), data);
}
function processFiles(pattern, opts) {
@ -54,18 +45,14 @@ function processFiles(pattern, opts) {
async function main() {
try {
await mkdir(fileURLToPath(new URL('../public/assets/img/svg', import.meta.url)), {recursive: true});
await mkdir(fileURLToPath(new URL('../public/img/svg', import.meta.url)), {recursive: true});
} catch {}
await Promise.all([
...processFiles('node_modules/@primer/octicons/build/svg/*-16.svg', {prefix: 'octicon'}),
...processFiles('web_src/svg/*.svg'),
...processFiles('public/assets/img/gitea.svg', {fullName: 'gitea-gitea'}),
...processFiles('public/img/gitea.svg', {fullName: 'gitea-gitea'}),
]);
}
try {
doExit(await main());
} catch (err) {
doExit(err);
}
main().then(exit).catch(exit);

View File

@ -1,20 +0,0 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
//go:build ignore
package main
import (
"fmt"
"io"
"os"
)
func main() {
_, err := io.Copy(os.Stdout, os.Stdin)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v", err)
os.Exit(1)
}
}

View File

@ -1,43 +1,14 @@
#!/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/"$//
# Make sure to only change lines that have the translation enclosed between quotes
sed -i -r -e '/^[a-zA-Z0-9_.-]+[ ]*=[ ]*".*"$/ {
s/^([a-zA-Z0-9_.-]+)[ ]*="/\1=/
s/\\"/"/g
s/"$//
}' ./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))

View File

@ -1,8 +0,0 @@
#!/bin/bash
set -euo pipefail
make --no-print-directory watch-frontend &
make --no-print-directory watch-backend &
trap 'kill $(jobs -p)' EXIT
wait

View File

@ -1,55 +0,0 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"fmt"
"code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli/v2"
)
var (
// CmdActions represents the available actions sub-commands.
CmdActions = &cli.Command{
Name: "actions",
Usage: "Manage Gitea Actions",
Subcommands: []*cli.Command{
subcmdActionsGenRunnerToken,
},
}
subcmdActionsGenRunnerToken = &cli.Command{
Name: "generate-runner-token",
Usage: "Generate a new token for a runner to use to register with the server",
Action: runGenerateActionsRunnerToken,
Aliases: []string{"grt"},
Flags: []cli.Flag{
&cli.StringFlag{
Name: "scope",
Aliases: []string{"s"},
Value: "",
Usage: "{owner}[/{repo}] - leave empty for a global runner",
},
},
}
)
func runGenerateActionsRunnerToken(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setting.MustInstalled()
scope := c.String("scope")
respText, extra := private.GenerateActionsRunnerToken(ctx, scope)
if extra.HasError() {
return handleCliResponseExtra(extra)
}
_, _ = fmt.Printf("%s\n", respText.Text)
return nil
}

View File

@ -5,25 +5,36 @@
package cmd
import (
"context"
"errors"
"fmt"
"net/url"
"os"
"strings"
"text/tabwriter"
asymkey_model "code.gitea.io/gitea/models/asymkey"
auth_model "code.gitea.io/gitea/models/auth"
"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/graceful"
"code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/util"
auth_service "code.gitea.io/gitea/services/auth"
"code.gitea.io/gitea/services/auth/source/oauth2"
"code.gitea.io/gitea/services/auth/source/smtp"
repo_service "code.gitea.io/gitea/services/repository"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
var (
// CmdAdmin represents the available admin sub-command.
CmdAdmin = &cli.Command{
CmdAdmin = cli.Command{
Name: "admin",
Usage: "Perform common administrative operations",
Subcommands: []*cli.Command{
Usage: "Command line interface to perform common administrative operations",
Subcommands: []cli.Command{
subcmdUser,
subcmdRepoSyncReleases,
subcmdRegenerate,
@ -32,31 +43,43 @@ var (
},
}
subcmdRepoSyncReleases = &cli.Command{
subcmdRepoSyncReleases = cli.Command{
Name: "repo-sync-releases",
Usage: "Synchronize repository releases with tags",
Action: runRepoSyncReleases,
}
subcmdRegenerate = &cli.Command{
subcmdRegenerate = cli.Command{
Name: "regenerate",
Usage: "Regenerate specific files",
Subcommands: []*cli.Command{
Subcommands: []cli.Command{
microcmdRegenHooks,
microcmdRegenKeys,
},
}
subcmdAuth = &cli.Command{
microcmdRegenHooks = cli.Command{
Name: "hooks",
Usage: "Regenerate git-hooks",
Action: runRegenerateHooks,
}
microcmdRegenKeys = cli.Command{
Name: "keys",
Usage: "Regenerate authorized_keys file",
Action: runRegenerateKeys,
}
subcmdAuth = cli.Command{
Name: "auth",
Usage: "Modify external auth providers",
Subcommands: []*cli.Command{
Subcommands: []cli.Command{
microcmdAuthAddOauth,
microcmdAuthUpdateOauth,
microcmdAuthAddLdapBindDn,
microcmdAuthUpdateLdapBindDn,
microcmdAuthAddLdapSimpleAuth,
microcmdAuthUpdateLdapSimpleAuth,
cmdAuthAddLdapBindDn,
cmdAuthUpdateLdapBindDn,
cmdAuthAddLdapSimpleAuth,
cmdAuthUpdateLdapSimpleAuth,
microcmdAuthAddSMTP,
microcmdAuthUpdateSMTP,
microcmdAuthList,
@ -64,33 +87,257 @@ var (
},
}
subcmdSendMail = &cli.Command{
Name: "sendmail",
Usage: "Send a message to all users",
Action: runSendMail,
microcmdAuthList = cli.Command{
Name: "list",
Usage: "List auth sources",
Action: runListAuth,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "title",
Usage: `a title of a message`,
Value: "",
cli.IntFlag{
Name: "min-width",
Usage: "Minimal cell width including any padding for the formatted table",
Value: 0,
},
&cli.StringFlag{
Name: "content",
Usage: "a content of a message",
Value: "",
cli.IntFlag{
Name: "tab-width",
Usage: "width of tab characters in formatted table (equivalent number of spaces)",
Value: 8,
},
&cli.BoolFlag{
Name: "force",
Aliases: []string{"f"},
Usage: "A flag to bypass a confirmation step",
cli.IntFlag{
Name: "padding",
Usage: "padding added to a cell before computing its width",
Value: 1,
},
cli.StringFlag{
Name: "pad-char",
Usage: `ASCII char used for padding if padchar == '\\t', the Writer will assume that the width of a '\\t' in the formatted output is tabwidth, and cells are left-aligned independent of align_left (for correct-looking results, tabwidth must correspond to the tab width in the viewer displaying the result)`,
Value: "\t",
},
cli.BoolFlag{
Name: "vertical-bars",
Usage: "Set to true to print vertical bars between columns",
},
},
}
idFlag = &cli.Int64Flag{
idFlag = cli.Int64Flag{
Name: "id",
Usage: "ID of authentication source",
}
microcmdAuthDelete = cli.Command{
Name: "delete",
Usage: "Delete specific auth source",
Flags: []cli.Flag{idFlag},
Action: runDeleteAuth,
}
oauthCLIFlags = []cli.Flag{
cli.StringFlag{
Name: "name",
Value: "",
Usage: "Application Name",
},
cli.StringFlag{
Name: "provider",
Value: "",
Usage: "OAuth2 Provider",
},
cli.StringFlag{
Name: "key",
Value: "",
Usage: "Client ID (Key)",
},
cli.StringFlag{
Name: "secret",
Value: "",
Usage: "Client Secret",
},
cli.StringFlag{
Name: "auto-discover-url",
Value: "",
Usage: "OpenID Connect Auto Discovery URL (only required when using OpenID Connect as provider)",
},
cli.StringFlag{
Name: "use-custom-urls",
Value: "false",
Usage: "Use custom URLs for GitLab/GitHub OAuth endpoints",
},
cli.StringFlag{
Name: "custom-tenant-id",
Value: "",
Usage: "Use custom Tenant ID for OAuth endpoints",
},
cli.StringFlag{
Name: "custom-auth-url",
Value: "",
Usage: "Use a custom Authorization URL (option for GitLab/GitHub)",
},
cli.StringFlag{
Name: "custom-token-url",
Value: "",
Usage: "Use a custom Token URL (option for GitLab/GitHub)",
},
cli.StringFlag{
Name: "custom-profile-url",
Value: "",
Usage: "Use a custom Profile URL (option for GitLab/GitHub)",
},
cli.StringFlag{
Name: "custom-email-url",
Value: "",
Usage: "Use a custom Email URL (option for GitHub)",
},
cli.StringFlag{
Name: "icon-url",
Value: "",
Usage: "Custom icon URL for OAuth2 login source",
},
cli.BoolFlag{
Name: "skip-local-2fa",
Usage: "Set to true to skip local 2fa for users authenticated by this source",
},
cli.StringSliceFlag{
Name: "scopes",
Value: nil,
Usage: "Scopes to request when to authenticate against this OAuth2 source",
},
cli.StringFlag{
Name: "required-claim-name",
Value: "",
Usage: "Claim name that has to be set to allow users to login with this source",
},
cli.StringFlag{
Name: "required-claim-value",
Value: "",
Usage: "Claim value that has to be set to allow users to login with this source",
},
cli.StringFlag{
Name: "group-claim-name",
Value: "",
Usage: "Claim name providing group names for this source",
},
cli.StringFlag{
Name: "admin-group",
Value: "",
Usage: "Group Claim value for administrator users",
},
cli.StringFlag{
Name: "restricted-group",
Value: "",
Usage: "Group Claim value for restricted users",
},
cli.StringFlag{
Name: "group-team-map",
Value: "",
Usage: "JSON mapping between groups and org teams",
},
cli.BoolFlag{
Name: "group-team-map-removal",
Usage: "Activate automatic team membership removal depending on groups",
},
}
microcmdAuthUpdateOauth = cli.Command{
Name: "update-oauth",
Usage: "Update existing Oauth authentication source",
Action: runUpdateOauth,
Flags: append(oauthCLIFlags[:1], append([]cli.Flag{idFlag}, oauthCLIFlags[1:]...)...),
}
microcmdAuthAddOauth = cli.Command{
Name: "add-oauth",
Usage: "Add new Oauth authentication source",
Action: runAddOauth,
Flags: oauthCLIFlags,
}
subcmdSendMail = cli.Command{
Name: "sendmail",
Usage: "Send a message to all users",
Action: runSendMail,
Flags: []cli.Flag{
cli.StringFlag{
Name: "title",
Usage: `a title of a message`,
Value: "",
},
cli.StringFlag{
Name: "content",
Usage: "a content of a message",
Value: "",
},
cli.BoolFlag{
Name: "force,f",
Usage: "A flag to bypass a confirmation step",
},
},
}
smtpCLIFlags = []cli.Flag{
cli.StringFlag{
Name: "name",
Value: "",
Usage: "Application Name",
},
cli.StringFlag{
Name: "auth-type",
Value: "PLAIN",
Usage: "SMTP Authentication Type (PLAIN/LOGIN/CRAM-MD5) default PLAIN",
},
cli.StringFlag{
Name: "host",
Value: "",
Usage: "SMTP Host",
},
cli.IntFlag{
Name: "port",
Usage: "SMTP Port",
},
cli.BoolTFlag{
Name: "force-smtps",
Usage: "SMTPS is always used on port 465. Set this to force SMTPS on other ports.",
},
cli.BoolTFlag{
Name: "skip-verify",
Usage: "Skip TLS verify.",
},
cli.StringFlag{
Name: "helo-hostname",
Value: "",
Usage: "Hostname sent with HELO. Leave blank to send current hostname",
},
cli.BoolTFlag{
Name: "disable-helo",
Usage: "Disable SMTP helo.",
},
cli.StringFlag{
Name: "allowed-domains",
Value: "",
Usage: "Leave empty to allow all domains. Separate multiple domains with a comma (',')",
},
cli.BoolTFlag{
Name: "skip-local-2fa",
Usage: "Skip 2FA to log on.",
},
cli.BoolTFlag{
Name: "active",
Usage: "This Authentication Source is Activated.",
},
}
microcmdAuthAddSMTP = cli.Command{
Name: "add-smtp",
Usage: "Add new SMTP authentication source",
Action: runAddSMTP,
Flags: smtpCLIFlags,
}
microcmdAuthUpdateSMTP = cli.Command{
Name: "update-smtp",
Usage: "Update existing SMTP authentication source",
Action: runUpdateSMTP,
Flags: append(smtpCLIFlags[:1], append([]cli.Flag{idFlag}, smtpCLIFlags[1:]...)...),
}
)
func runRepoSyncReleases(_ *cli.Context) error {
@ -101,10 +348,6 @@ func runRepoSyncReleases(_ *cli.Context) error {
return err
}
if err := git.InitSimple(ctx); err != nil {
return err
}
log.Trace("Synchronizing repository releases (this may take a while)")
for page := 1; ; page++ {
repos, count, err := repo_model.SearchRepositoryByName(ctx, &repo_model.SearchRepoOptions{
@ -123,25 +366,25 @@ func runRepoSyncReleases(_ *cli.Context) error {
log.Trace("Processing next %d repos of %d", len(repos), count)
for _, repo := range repos {
log.Trace("Synchronizing repo %s with path %s", repo.FullName(), repo.RepoPath())
gitRepo, err := gitrepo.OpenRepository(ctx, repo)
gitRepo, err := git.OpenRepository(ctx, repo.RepoPath())
if err != nil {
log.Warn("OpenRepository: %v", err)
continue
}
oldnum, err := getReleaseCount(ctx, repo.ID)
oldnum, err := getReleaseCount(repo.ID)
if err != nil {
log.Warn(" GetReleaseCountByRepoID: %v", err)
}
log.Trace(" currentNumReleases is %d, running SyncReleasesWithTags", oldnum)
if err = repo_module.SyncReleasesWithTags(ctx, repo, gitRepo); err != nil {
if err = repo_module.SyncReleasesWithTags(repo, gitRepo); err != nil {
log.Warn(" SyncReleasesWithTags: %v", err)
gitRepo.Close()
continue
}
count, err = getReleaseCount(ctx, repo.ID)
count, err = getReleaseCount(repo.ID)
if err != nil {
log.Warn(" GetReleaseCountByRepoID: %v", err)
gitRepo.Close()
@ -157,12 +400,360 @@ func runRepoSyncReleases(_ *cli.Context) error {
return nil
}
func getReleaseCount(ctx context.Context, id int64) (int64, error) {
return db.Count[repo_model.Release](
ctx,
func getReleaseCount(id int64) (int64, error) {
return repo_model.GetReleaseCountByRepoID(
db.DefaultContext,
id,
repo_model.FindReleasesOptions{
RepoID: id,
IncludeTags: true,
},
)
}
func runRegenerateHooks(_ *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
return repo_service.SyncRepositoryHooks(graceful.GetManager().ShutdownContext())
}
func runRegenerateKeys(_ *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
return asymkey_model.RewriteAllPublicKeys()
}
func parseOAuth2Config(c *cli.Context) *oauth2.Source {
var customURLMapping *oauth2.CustomURLMapping
if c.IsSet("use-custom-urls") {
customURLMapping = &oauth2.CustomURLMapping{
TokenURL: c.String("custom-token-url"),
AuthURL: c.String("custom-auth-url"),
ProfileURL: c.String("custom-profile-url"),
EmailURL: c.String("custom-email-url"),
Tenant: c.String("custom-tenant-id"),
}
} else {
customURLMapping = nil
}
return &oauth2.Source{
Provider: c.String("provider"),
ClientID: c.String("key"),
ClientSecret: c.String("secret"),
OpenIDConnectAutoDiscoveryURL: c.String("auto-discover-url"),
CustomURLMapping: customURLMapping,
IconURL: c.String("icon-url"),
SkipLocalTwoFA: c.Bool("skip-local-2fa"),
Scopes: c.StringSlice("scopes"),
RequiredClaimName: c.String("required-claim-name"),
RequiredClaimValue: c.String("required-claim-value"),
GroupClaimName: c.String("group-claim-name"),
AdminGroup: c.String("admin-group"),
RestrictedGroup: c.String("restricted-group"),
GroupTeamMap: c.String("group-team-map"),
GroupTeamMapRemoval: c.Bool("group-team-map-removal"),
}
}
func runAddOauth(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
config := parseOAuth2Config(c)
if config.Provider == "openidConnect" {
discoveryURL, err := url.Parse(config.OpenIDConnectAutoDiscoveryURL)
if err != nil || (discoveryURL.Scheme != "http" && discoveryURL.Scheme != "https") {
return fmt.Errorf("invalid Auto Discovery URL: %s (this must be a valid URL starting with http:// or https://)", config.OpenIDConnectAutoDiscoveryURL)
}
}
return auth_model.CreateSource(&auth_model.Source{
Type: auth_model.OAuth2,
Name: c.String("name"),
IsActive: true,
Cfg: config,
})
}
func runUpdateOauth(c *cli.Context) error {
if !c.IsSet("id") {
return fmt.Errorf("--id flag is missing")
}
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
source, err := auth_model.GetSourceByID(c.Int64("id"))
if err != nil {
return err
}
oAuth2Config := source.Cfg.(*oauth2.Source)
if c.IsSet("name") {
source.Name = c.String("name")
}
if c.IsSet("provider") {
oAuth2Config.Provider = c.String("provider")
}
if c.IsSet("key") {
oAuth2Config.ClientID = c.String("key")
}
if c.IsSet("secret") {
oAuth2Config.ClientSecret = c.String("secret")
}
if c.IsSet("auto-discover-url") {
oAuth2Config.OpenIDConnectAutoDiscoveryURL = c.String("auto-discover-url")
}
if c.IsSet("icon-url") {
oAuth2Config.IconURL = c.String("icon-url")
}
if c.IsSet("scopes") {
oAuth2Config.Scopes = c.StringSlice("scopes")
}
if c.IsSet("required-claim-name") {
oAuth2Config.RequiredClaimName = c.String("required-claim-name")
}
if c.IsSet("required-claim-value") {
oAuth2Config.RequiredClaimValue = c.String("required-claim-value")
}
if c.IsSet("group-claim-name") {
oAuth2Config.GroupClaimName = c.String("group-claim-name")
}
if c.IsSet("admin-group") {
oAuth2Config.AdminGroup = c.String("admin-group")
}
if c.IsSet("restricted-group") {
oAuth2Config.RestrictedGroup = c.String("restricted-group")
}
if c.IsSet("group-team-map") {
oAuth2Config.GroupTeamMap = c.String("group-team-map")
}
if c.IsSet("group-team-map-removal") {
oAuth2Config.GroupTeamMapRemoval = c.Bool("group-team-map-removal")
}
// update custom URL mapping
customURLMapping := &oauth2.CustomURLMapping{}
if oAuth2Config.CustomURLMapping != nil {
customURLMapping.TokenURL = oAuth2Config.CustomURLMapping.TokenURL
customURLMapping.AuthURL = oAuth2Config.CustomURLMapping.AuthURL
customURLMapping.ProfileURL = oAuth2Config.CustomURLMapping.ProfileURL
customURLMapping.EmailURL = oAuth2Config.CustomURLMapping.EmailURL
customURLMapping.Tenant = oAuth2Config.CustomURLMapping.Tenant
}
if c.IsSet("use-custom-urls") && c.IsSet("custom-token-url") {
customURLMapping.TokenURL = c.String("custom-token-url")
}
if c.IsSet("use-custom-urls") && c.IsSet("custom-auth-url") {
customURLMapping.AuthURL = c.String("custom-auth-url")
}
if c.IsSet("use-custom-urls") && c.IsSet("custom-profile-url") {
customURLMapping.ProfileURL = c.String("custom-profile-url")
}
if c.IsSet("use-custom-urls") && c.IsSet("custom-email-url") {
customURLMapping.EmailURL = c.String("custom-email-url")
}
if c.IsSet("use-custom-urls") && c.IsSet("custom-tenant-id") {
customURLMapping.Tenant = c.String("custom-tenant-id")
}
oAuth2Config.CustomURLMapping = customURLMapping
source.Cfg = oAuth2Config
return auth_model.UpdateSource(source)
}
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"}
if !util.SliceContainsString(validAuthTypes, strings.ToUpper(c.String("auth-type"))) {
return errors.New("Auth must be one of PLAIN/LOGIN/CRAM-MD5")
}
conf.Auth = c.String("auth-type")
}
if c.IsSet("host") {
conf.Host = c.String("host")
}
if c.IsSet("port") {
conf.Port = c.Int("port")
}
if c.IsSet("allowed-domains") {
conf.AllowedDomains = c.String("allowed-domains")
}
if c.IsSet("force-smtps") {
conf.ForceSMTPS = c.BoolT("force-smtps")
}
if c.IsSet("skip-verify") {
conf.SkipVerify = c.BoolT("skip-verify")
}
if c.IsSet("helo-hostname") {
conf.HeloHostname = c.String("helo-hostname")
}
if c.IsSet("disable-helo") {
conf.DisableHelo = c.BoolT("disable-helo")
}
if c.IsSet("skip-local-2fa") {
conf.SkipLocalTwoFA = c.BoolT("skip-local-2fa")
}
return nil
}
func runAddSMTP(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
if !c.IsSet("name") || len(c.String("name")) == 0 {
return errors.New("name must be set")
}
if !c.IsSet("host") || len(c.String("host")) == 0 {
return errors.New("host must be set")
}
if !c.IsSet("port") {
return errors.New("port must be set")
}
active := true
if c.IsSet("active") {
active = c.BoolT("active")
}
var smtpConfig smtp.Source
if err := parseSMTPConfig(c, &smtpConfig); err != nil {
return err
}
// If not set default to PLAIN
if len(smtpConfig.Auth) == 0 {
smtpConfig.Auth = "PLAIN"
}
return auth_model.CreateSource(&auth_model.Source{
Type: auth_model.SMTP,
Name: c.String("name"),
IsActive: active,
Cfg: &smtpConfig,
})
}
func runUpdateSMTP(c *cli.Context) error {
if !c.IsSet("id") {
return fmt.Errorf("--id flag is missing")
}
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
source, err := auth_model.GetSourceByID(c.Int64("id"))
if err != nil {
return err
}
smtpConfig := source.Cfg.(*smtp.Source)
if err := parseSMTPConfig(c, smtpConfig); err != nil {
return err
}
if c.IsSet("name") {
source.Name = c.String("name")
}
if c.IsSet("active") {
source.IsActive = c.BoolT("active")
}
source.Cfg = smtpConfig
return auth_model.UpdateSource(source)
}
func runListAuth(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
authSources, err := auth_model.Sources()
if err != nil {
return err
}
flags := tabwriter.AlignRight
if c.Bool("vertical-bars") {
flags |= tabwriter.Debug
}
padChar := byte('\t')
if len(c.String("pad-char")) > 0 {
padChar = c.String("pad-char")[0]
}
// 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.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)
}
w.Flush()
return nil
}
func runDeleteAuth(c *cli.Context) error {
if !c.IsSet("id") {
return fmt.Errorf("--id flag is missing")
}
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
source, err := auth_model.GetSourceByID(c.Int64("id"))
if err != nil {
return err
}
return auth_service.DeleteSource(source)
}

View File

@ -1,110 +0,0 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"fmt"
"os"
"text/tabwriter"
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/v2"
)
var (
microcmdAuthDelete = &cli.Command{
Name: "delete",
Usage: "Delete specific auth source",
Flags: []cli.Flag{idFlag},
Action: runDeleteAuth,
}
microcmdAuthList = &cli.Command{
Name: "list",
Usage: "List auth sources",
Action: runListAuth,
Flags: []cli.Flag{
&cli.IntFlag{
Name: "min-width",
Usage: "Minimal cell width including any padding for the formatted table",
Value: 0,
},
&cli.IntFlag{
Name: "tab-width",
Usage: "width of tab characters in formatted table (equivalent number of spaces)",
Value: 8,
},
&cli.IntFlag{
Name: "padding",
Usage: "padding added to a cell before computing its width",
Value: 1,
},
&cli.StringFlag{
Name: "pad-char",
Usage: `ASCII char used for padding if padchar == '\\t', the Writer will assume that the width of a '\\t' in the formatted output is tabwidth, and cells are left-aligned independent of align_left (for correct-looking results, tabwidth must correspond to the tab width in the viewer displaying the result)`,
Value: "\t",
},
&cli.BoolFlag{
Name: "vertical-bars",
Usage: "Set to true to print vertical bars between columns",
},
},
}
)
func runListAuth(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
authSources, err := db.Find[auth_model.Source](ctx, auth_model.FindSourcesOptions{})
if err != nil {
return err
}
flags := tabwriter.AlignRight
if c.Bool("vertical-bars") {
flags |= tabwriter.Debug
}
padChar := byte('\t')
if len(c.String("pad-char")) > 0 {
padChar = c.String("pad-char")[0]
}
// 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.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)
}
w.Flush()
return nil
}
func runDeleteAuth(c *cli.Context) error {
if !c.IsSet("id") {
return fmt.Errorf("--id flag is missing")
}
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
source, err := auth_model.GetSourceByID(ctx, c.Int64("id"))
if err != nil {
return err
}
return auth_service.DeleteSource(ctx, source)
}

View File

@ -11,131 +11,131 @@ import (
"code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/services/auth/source/ldap"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
type (
authService struct {
initDB func(ctx context.Context) error
createAuthSource func(context.Context, *auth.Source) error
updateAuthSource func(context.Context, *auth.Source) error
getAuthSourceByID func(ctx context.Context, id int64) (*auth.Source, error)
createAuthSource func(*auth.Source) error
updateAuthSource func(*auth.Source) error
getAuthSourceByID func(id int64) (*auth.Source, error)
}
)
var (
commonLdapCLIFlags = []cli.Flag{
&cli.StringFlag{
cli.StringFlag{
Name: "name",
Usage: "Authentication name.",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "not-active",
Usage: "Deactivate the authentication source.",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "active",
Usage: "Activate the authentication source.",
},
&cli.StringFlag{
cli.StringFlag{
Name: "security-protocol",
Usage: "Security protocol name.",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "skip-tls-verify",
Usage: "Disable TLS verification.",
},
&cli.StringFlag{
cli.StringFlag{
Name: "host",
Usage: "The address where the LDAP server can be reached.",
},
&cli.IntFlag{
cli.IntFlag{
Name: "port",
Usage: "The port to use when connecting to the LDAP server.",
},
&cli.StringFlag{
cli.StringFlag{
Name: "user-search-base",
Usage: "The LDAP base at which user accounts will be searched for.",
},
&cli.StringFlag{
cli.StringFlag{
Name: "user-filter",
Usage: "An LDAP filter declaring how to find the user record that is attempting to authenticate.",
},
&cli.StringFlag{
cli.StringFlag{
Name: "admin-filter",
Usage: "An LDAP filter specifying if a user should be given administrator privileges.",
},
&cli.StringFlag{
cli.StringFlag{
Name: "restricted-filter",
Usage: "An LDAP filter specifying if a user should be given restricted status.",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "allow-deactivate-all",
Usage: "Allow empty search results to deactivate all users.",
},
&cli.StringFlag{
cli.StringFlag{
Name: "username-attribute",
Usage: "The attribute of the users LDAP record containing the user name.",
},
&cli.StringFlag{
cli.StringFlag{
Name: "firstname-attribute",
Usage: "The attribute of the users LDAP record containing the users first name.",
},
&cli.StringFlag{
cli.StringFlag{
Name: "surname-attribute",
Usage: "The attribute of the users LDAP record containing the users surname.",
},
&cli.StringFlag{
cli.StringFlag{
Name: "email-attribute",
Usage: "The attribute of the users LDAP record containing the users email address.",
},
&cli.StringFlag{
cli.StringFlag{
Name: "public-ssh-key-attribute",
Usage: "The attribute of the users LDAP record containing the users public ssh key.",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "skip-local-2fa",
Usage: "Set to true to skip local 2fa for users authenticated by this source",
},
&cli.StringFlag{
cli.StringFlag{
Name: "avatar-attribute",
Usage: "The attribute of the users LDAP record containing the users avatar.",
},
}
ldapBindDnCLIFlags = append(commonLdapCLIFlags,
&cli.StringFlag{
cli.StringFlag{
Name: "bind-dn",
Usage: "The DN to bind to the LDAP server with when searching for the user.",
},
&cli.StringFlag{
cli.StringFlag{
Name: "bind-password",
Usage: "The password for the Bind DN, if any.",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "attributes-in-bind",
Usage: "Fetch attributes in bind DN context.",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "synchronize-users",
Usage: "Enable user synchronization.",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "disable-synchronize-users",
Usage: "Disable user synchronization.",
},
&cli.UintFlag{
cli.UintFlag{
Name: "page-size",
Usage: "Search page size.",
})
ldapSimpleAuthCLIFlags = append(commonLdapCLIFlags,
&cli.StringFlag{
cli.StringFlag{
Name: "user-dn",
Usage: "The user's DN.",
Usage: "The users DN.",
})
microcmdAuthAddLdapBindDn = &cli.Command{
cmdAuthAddLdapBindDn = cli.Command{
Name: "add-ldap",
Usage: "Add new LDAP (via Bind DN) authentication source",
Action: func(c *cli.Context) error {
@ -144,7 +144,7 @@ var (
Flags: ldapBindDnCLIFlags,
}
microcmdAuthUpdateLdapBindDn = &cli.Command{
cmdAuthUpdateLdapBindDn = cli.Command{
Name: "update-ldap",
Usage: "Update existing LDAP (via Bind DN) authentication source",
Action: func(c *cli.Context) error {
@ -153,7 +153,7 @@ var (
Flags: append([]cli.Flag{idFlag}, ldapBindDnCLIFlags...),
}
microcmdAuthAddLdapSimpleAuth = &cli.Command{
cmdAuthAddLdapSimpleAuth = cli.Command{
Name: "add-ldap-simple",
Usage: "Add new LDAP (simple auth) authentication source",
Action: func(c *cli.Context) error {
@ -162,7 +162,7 @@ var (
Flags: ldapSimpleAuthCLIFlags,
}
microcmdAuthUpdateLdapSimpleAuth = &cli.Command{
cmdAuthUpdateLdapSimpleAuth = cli.Command{
Name: "update-ldap-simple",
Usage: "Update existing LDAP (simple auth) authentication source",
Action: func(c *cli.Context) error {
@ -289,12 +289,12 @@ 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.Context, authType auth.Type) (*auth.Source, error) {
func (a *authService) getAuthSource(c *cli.Context, authType auth.Type) (*auth.Source, error) {
if err := argsSet(c, "id"); err != nil {
return nil, err
}
authSource, err := a.getAuthSourceByID(ctx, c.Int64("id"))
authSource, err := a.getAuthSourceByID(c.Int64("id"))
if err != nil {
return nil, err
}
@ -332,7 +332,7 @@ func (a *authService) addLdapBindDn(c *cli.Context) error {
return err
}
return a.createAuthSource(ctx, authSource)
return a.createAuthSource(authSource)
}
// updateLdapBindDn updates a new LDAP via Bind DN authentication source.
@ -344,7 +344,7 @@ func (a *authService) updateLdapBindDn(c *cli.Context) error {
return err
}
authSource, err := a.getAuthSource(ctx, c, auth.LDAP)
authSource, err := a.getAuthSource(c, auth.LDAP)
if err != nil {
return err
}
@ -354,7 +354,7 @@ func (a *authService) updateLdapBindDn(c *cli.Context) error {
return err
}
return a.updateAuthSource(ctx, authSource)
return a.updateAuthSource(authSource)
}
// addLdapSimpleAuth adds a new LDAP (simple auth) authentication source.
@ -383,7 +383,7 @@ func (a *authService) addLdapSimpleAuth(c *cli.Context) error {
return err
}
return a.createAuthSource(ctx, authSource)
return a.createAuthSource(authSource)
}
// updateLdapBindDn updates a new LDAP (simple auth) authentication source.
@ -395,7 +395,7 @@ func (a *authService) updateLdapSimpleAuth(c *cli.Context) error {
return err
}
authSource, err := a.getAuthSource(ctx, c, auth.DLDAP)
authSource, err := a.getAuthSource(c, auth.DLDAP)
if err != nil {
return err
}
@ -405,5 +405,5 @@ func (a *authService) updateLdapSimpleAuth(c *cli.Context) error {
return err
}
return a.updateAuthSource(ctx, authSource)
return a.updateAuthSource(authSource)
}

View File

@ -11,7 +11,7 @@ import (
"code.gitea.io/gitea/services/auth/source/ldap"
"github.com/stretchr/testify/assert"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
func TestAddLdapBindDn(t *testing.T) {
@ -210,15 +210,15 @@ func TestAddLdapBindDn(t *testing.T) {
initDB: func(context.Context) error {
return nil
},
createAuthSource: func(ctx context.Context, authSource *auth.Source) error {
createAuthSource: func(authSource *auth.Source) error {
createdAuthSource = authSource
return nil
},
updateAuthSource: func(ctx context.Context, authSource *auth.Source) error {
updateAuthSource: func(authSource *auth.Source) error {
assert.FailNow(t, "case %d: should not call updateAuthSource", n)
return nil
},
getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) {
getAuthSourceByID: func(id int64) (*auth.Source, error) {
assert.FailNow(t, "case %d: should not call getAuthSourceByID", n)
return nil, nil
},
@ -226,7 +226,7 @@ func TestAddLdapBindDn(t *testing.T) {
// Create a copy of command to test
app := cli.NewApp()
app.Flags = microcmdAuthAddLdapBindDn.Flags
app.Flags = cmdAuthAddLdapBindDn.Flags
app.Action = service.addLdapBindDn
// Run it
@ -441,15 +441,15 @@ func TestAddLdapSimpleAuth(t *testing.T) {
initDB: func(context.Context) error {
return nil
},
createAuthSource: func(ctx context.Context, authSource *auth.Source) error {
createAuthSource: func(authSource *auth.Source) error {
createdAuthSource = authSource
return nil
},
updateAuthSource: func(ctx context.Context, authSource *auth.Source) error {
updateAuthSource: func(authSource *auth.Source) error {
assert.FailNow(t, "case %d: should not call updateAuthSource", n)
return nil
},
getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) {
getAuthSourceByID: func(id int64) (*auth.Source, error) {
assert.FailNow(t, "case %d: should not call getAuthSourceByID", n)
return nil, nil
},
@ -457,7 +457,7 @@ func TestAddLdapSimpleAuth(t *testing.T) {
// Create a copy of command to test
app := cli.NewApp()
app.Flags = microcmdAuthAddLdapSimpleAuth.Flags
app.Flags = cmdAuthAddLdapSimpleAuth.Flags
app.Action = service.addLdapSimpleAuth
// Run it
@ -896,15 +896,15 @@ func TestUpdateLdapBindDn(t *testing.T) {
initDB: func(context.Context) error {
return nil
},
createAuthSource: func(ctx context.Context, authSource *auth.Source) error {
createAuthSource: func(authSource *auth.Source) error {
assert.FailNow(t, "case %d: should not call createAuthSource", n)
return nil
},
updateAuthSource: func(ctx context.Context, authSource *auth.Source) error {
updateAuthSource: func(authSource *auth.Source) error {
updatedAuthSource = authSource
return nil
},
getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) {
getAuthSourceByID: func(id int64) (*auth.Source, error) {
if c.id != 0 {
assert.Equal(t, c.id, id, "case %d: wrong id", n)
}
@ -920,7 +920,7 @@ func TestUpdateLdapBindDn(t *testing.T) {
// Create a copy of command to test
app := cli.NewApp()
app.Flags = microcmdAuthUpdateLdapBindDn.Flags
app.Flags = cmdAuthUpdateLdapBindDn.Flags
app.Action = service.updateLdapBindDn
// Run it
@ -1286,15 +1286,15 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
initDB: func(context.Context) error {
return nil
},
createAuthSource: func(ctx context.Context, authSource *auth.Source) error {
createAuthSource: func(authSource *auth.Source) error {
assert.FailNow(t, "case %d: should not call createAuthSource", n)
return nil
},
updateAuthSource: func(ctx context.Context, authSource *auth.Source) error {
updateAuthSource: func(authSource *auth.Source) error {
updatedAuthSource = authSource
return nil
},
getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) {
getAuthSourceByID: func(id int64) (*auth.Source, error) {
if c.id != 0 {
assert.Equal(t, c.id, id, "case %d: wrong id", n)
}
@ -1310,7 +1310,7 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
// Create a copy of command to test
app := cli.NewApp()
app.Flags = microcmdAuthUpdateLdapSimpleAuth.Flags
app.Flags = cmdAuthUpdateLdapSimpleAuth.Flags
app.Action = service.updateLdapSimpleAuth
// Run it

View File

@ -1,298 +0,0 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"fmt"
"net/url"
auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/services/auth/source/oauth2"
"github.com/urfave/cli/v2"
)
var (
oauthCLIFlags = []cli.Flag{
&cli.StringFlag{
Name: "name",
Value: "",
Usage: "Application Name",
},
&cli.StringFlag{
Name: "provider",
Value: "",
Usage: "OAuth2 Provider",
},
&cli.StringFlag{
Name: "key",
Value: "",
Usage: "Client ID (Key)",
},
&cli.StringFlag{
Name: "secret",
Value: "",
Usage: "Client Secret",
},
&cli.StringFlag{
Name: "auto-discover-url",
Value: "",
Usage: "OpenID Connect Auto Discovery URL (only required when using OpenID Connect as provider)",
},
&cli.StringFlag{
Name: "use-custom-urls",
Value: "false",
Usage: "Use custom URLs for GitLab/GitHub OAuth endpoints",
},
&cli.StringFlag{
Name: "custom-tenant-id",
Value: "",
Usage: "Use custom Tenant ID for OAuth endpoints",
},
&cli.StringFlag{
Name: "custom-auth-url",
Value: "",
Usage: "Use a custom Authorization URL (option for GitLab/GitHub)",
},
&cli.StringFlag{
Name: "custom-token-url",
Value: "",
Usage: "Use a custom Token URL (option for GitLab/GitHub)",
},
&cli.StringFlag{
Name: "custom-profile-url",
Value: "",
Usage: "Use a custom Profile URL (option for GitLab/GitHub)",
},
&cli.StringFlag{
Name: "custom-email-url",
Value: "",
Usage: "Use a custom Email URL (option for GitHub)",
},
&cli.StringFlag{
Name: "icon-url",
Value: "",
Usage: "Custom icon URL for OAuth2 login source",
},
&cli.BoolFlag{
Name: "skip-local-2fa",
Usage: "Set to true to skip local 2fa for users authenticated by this source",
},
&cli.StringSliceFlag{
Name: "scopes",
Value: nil,
Usage: "Scopes to request when to authenticate against this OAuth2 source",
},
&cli.StringFlag{
Name: "required-claim-name",
Value: "",
Usage: "Claim name that has to be set to allow users to login with this source",
},
&cli.StringFlag{
Name: "required-claim-value",
Value: "",
Usage: "Claim value that has to be set to allow users to login with this source",
},
&cli.StringFlag{
Name: "group-claim-name",
Value: "",
Usage: "Claim name providing group names for this source",
},
&cli.StringFlag{
Name: "admin-group",
Value: "",
Usage: "Group Claim value for administrator users",
},
&cli.StringFlag{
Name: "restricted-group",
Value: "",
Usage: "Group Claim value for restricted users",
},
&cli.StringFlag{
Name: "group-team-map",
Value: "",
Usage: "JSON mapping between groups and org teams",
},
&cli.BoolFlag{
Name: "group-team-map-removal",
Usage: "Activate automatic team membership removal depending on groups",
},
}
microcmdAuthAddOauth = &cli.Command{
Name: "add-oauth",
Usage: "Add new Oauth authentication source",
Action: runAddOauth,
Flags: oauthCLIFlags,
}
microcmdAuthUpdateOauth = &cli.Command{
Name: "update-oauth",
Usage: "Update existing Oauth authentication source",
Action: runUpdateOauth,
Flags: append(oauthCLIFlags[:1], append([]cli.Flag{idFlag}, oauthCLIFlags[1:]...)...),
}
)
func parseOAuth2Config(c *cli.Context) *oauth2.Source {
var customURLMapping *oauth2.CustomURLMapping
if c.IsSet("use-custom-urls") {
customURLMapping = &oauth2.CustomURLMapping{
TokenURL: c.String("custom-token-url"),
AuthURL: c.String("custom-auth-url"),
ProfileURL: c.String("custom-profile-url"),
EmailURL: c.String("custom-email-url"),
Tenant: c.String("custom-tenant-id"),
}
} else {
customURLMapping = nil
}
return &oauth2.Source{
Provider: c.String("provider"),
ClientID: c.String("key"),
ClientSecret: c.String("secret"),
OpenIDConnectAutoDiscoveryURL: c.String("auto-discover-url"),
CustomURLMapping: customURLMapping,
IconURL: c.String("icon-url"),
SkipLocalTwoFA: c.Bool("skip-local-2fa"),
Scopes: c.StringSlice("scopes"),
RequiredClaimName: c.String("required-claim-name"),
RequiredClaimValue: c.String("required-claim-value"),
GroupClaimName: c.String("group-claim-name"),
AdminGroup: c.String("admin-group"),
RestrictedGroup: c.String("restricted-group"),
GroupTeamMap: c.String("group-team-map"),
GroupTeamMapRemoval: c.Bool("group-team-map-removal"),
}
}
func runAddOauth(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
config := parseOAuth2Config(c)
if config.Provider == "openidConnect" {
discoveryURL, err := url.Parse(config.OpenIDConnectAutoDiscoveryURL)
if err != nil || (discoveryURL.Scheme != "http" && discoveryURL.Scheme != "https") {
return fmt.Errorf("invalid Auto Discovery URL: %s (this must be a valid URL starting with http:// or https://)", config.OpenIDConnectAutoDiscoveryURL)
}
}
return auth_model.CreateSource(ctx, &auth_model.Source{
Type: auth_model.OAuth2,
Name: c.String("name"),
IsActive: true,
Cfg: config,
})
}
func runUpdateOauth(c *cli.Context) error {
if !c.IsSet("id") {
return fmt.Errorf("--id flag is missing")
}
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
source, err := auth_model.GetSourceByID(ctx, c.Int64("id"))
if err != nil {
return err
}
oAuth2Config := source.Cfg.(*oauth2.Source)
if c.IsSet("name") {
source.Name = c.String("name")
}
if c.IsSet("provider") {
oAuth2Config.Provider = c.String("provider")
}
if c.IsSet("key") {
oAuth2Config.ClientID = c.String("key")
}
if c.IsSet("secret") {
oAuth2Config.ClientSecret = c.String("secret")
}
if c.IsSet("auto-discover-url") {
oAuth2Config.OpenIDConnectAutoDiscoveryURL = c.String("auto-discover-url")
}
if c.IsSet("icon-url") {
oAuth2Config.IconURL = c.String("icon-url")
}
if c.IsSet("scopes") {
oAuth2Config.Scopes = c.StringSlice("scopes")
}
if c.IsSet("required-claim-name") {
oAuth2Config.RequiredClaimName = c.String("required-claim-name")
}
if c.IsSet("required-claim-value") {
oAuth2Config.RequiredClaimValue = c.String("required-claim-value")
}
if c.IsSet("group-claim-name") {
oAuth2Config.GroupClaimName = c.String("group-claim-name")
}
if c.IsSet("admin-group") {
oAuth2Config.AdminGroup = c.String("admin-group")
}
if c.IsSet("restricted-group") {
oAuth2Config.RestrictedGroup = c.String("restricted-group")
}
if c.IsSet("group-team-map") {
oAuth2Config.GroupTeamMap = c.String("group-team-map")
}
if c.IsSet("group-team-map-removal") {
oAuth2Config.GroupTeamMapRemoval = c.Bool("group-team-map-removal")
}
// update custom URL mapping
customURLMapping := &oauth2.CustomURLMapping{}
if oAuth2Config.CustomURLMapping != nil {
customURLMapping.TokenURL = oAuth2Config.CustomURLMapping.TokenURL
customURLMapping.AuthURL = oAuth2Config.CustomURLMapping.AuthURL
customURLMapping.ProfileURL = oAuth2Config.CustomURLMapping.ProfileURL
customURLMapping.EmailURL = oAuth2Config.CustomURLMapping.EmailURL
customURLMapping.Tenant = oAuth2Config.CustomURLMapping.Tenant
}
if c.IsSet("use-custom-urls") && c.IsSet("custom-token-url") {
customURLMapping.TokenURL = c.String("custom-token-url")
}
if c.IsSet("use-custom-urls") && c.IsSet("custom-auth-url") {
customURLMapping.AuthURL = c.String("custom-auth-url")
}
if c.IsSet("use-custom-urls") && c.IsSet("custom-profile-url") {
customURLMapping.ProfileURL = c.String("custom-profile-url")
}
if c.IsSet("use-custom-urls") && c.IsSet("custom-email-url") {
customURLMapping.EmailURL = c.String("custom-email-url")
}
if c.IsSet("use-custom-urls") && c.IsSet("custom-tenant-id") {
customURLMapping.Tenant = c.String("custom-tenant-id")
}
oAuth2Config.CustomURLMapping = customURLMapping
source.Cfg = oAuth2Config
return auth_model.UpdateSource(ctx, source)
}

View File

@ -1,201 +0,0 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"errors"
"fmt"
"strings"
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/v2"
)
var (
smtpCLIFlags = []cli.Flag{
&cli.StringFlag{
Name: "name",
Value: "",
Usage: "Application Name",
},
&cli.StringFlag{
Name: "auth-type",
Value: "PLAIN",
Usage: "SMTP Authentication Type (PLAIN/LOGIN/CRAM-MD5) default PLAIN",
},
&cli.StringFlag{
Name: "host",
Value: "",
Usage: "SMTP Host",
},
&cli.IntFlag{
Name: "port",
Usage: "SMTP Port",
},
&cli.BoolFlag{
Name: "force-smtps",
Usage: "SMTPS is always used on port 465. Set this to force SMTPS on other ports.",
Value: true,
},
&cli.BoolFlag{
Name: "skip-verify",
Usage: "Skip TLS verify.",
Value: true,
},
&cli.StringFlag{
Name: "helo-hostname",
Value: "",
Usage: "Hostname sent with HELO. Leave blank to send current hostname",
},
&cli.BoolFlag{
Name: "disable-helo",
Usage: "Disable SMTP helo.",
Value: true,
},
&cli.StringFlag{
Name: "allowed-domains",
Value: "",
Usage: "Leave empty to allow all domains. Separate multiple domains with a comma (',')",
},
&cli.BoolFlag{
Name: "skip-local-2fa",
Usage: "Skip 2FA to log on.",
Value: true,
},
&cli.BoolFlag{
Name: "active",
Usage: "This Authentication Source is Activated.",
Value: true,
},
}
microcmdAuthAddSMTP = &cli.Command{
Name: "add-smtp",
Usage: "Add new SMTP authentication source",
Action: runAddSMTP,
Flags: smtpCLIFlags,
}
microcmdAuthUpdateSMTP = &cli.Command{
Name: "update-smtp",
Usage: "Update existing SMTP authentication source",
Action: runUpdateSMTP,
Flags: append(smtpCLIFlags[:1], append([]cli.Flag{idFlag}, smtpCLIFlags[1:]...)...),
}
)
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"}
if !util.SliceContainsString(validAuthTypes, strings.ToUpper(c.String("auth-type"))) {
return errors.New("Auth must be one of PLAIN/LOGIN/CRAM-MD5")
}
conf.Auth = c.String("auth-type")
}
if c.IsSet("host") {
conf.Host = c.String("host")
}
if c.IsSet("port") {
conf.Port = c.Int("port")
}
if c.IsSet("allowed-domains") {
conf.AllowedDomains = c.String("allowed-domains")
}
if c.IsSet("force-smtps") {
conf.ForceSMTPS = c.Bool("force-smtps")
}
if c.IsSet("skip-verify") {
conf.SkipVerify = c.Bool("skip-verify")
}
if c.IsSet("helo-hostname") {
conf.HeloHostname = c.String("helo-hostname")
}
if c.IsSet("disable-helo") {
conf.DisableHelo = c.Bool("disable-helo")
}
if c.IsSet("skip-local-2fa") {
conf.SkipLocalTwoFA = c.Bool("skip-local-2fa")
}
return nil
}
func runAddSMTP(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
if !c.IsSet("name") || len(c.String("name")) == 0 {
return errors.New("name must be set")
}
if !c.IsSet("host") || len(c.String("host")) == 0 {
return errors.New("host must be set")
}
if !c.IsSet("port") {
return errors.New("port must be set")
}
active := true
if c.IsSet("active") {
active = c.Bool("active")
}
var smtpConfig smtp.Source
if err := parseSMTPConfig(c, &smtpConfig); err != nil {
return err
}
// If not set default to PLAIN
if len(smtpConfig.Auth) == 0 {
smtpConfig.Auth = "PLAIN"
}
return auth_model.CreateSource(ctx, &auth_model.Source{
Type: auth_model.SMTP,
Name: c.String("name"),
IsActive: active,
Cfg: &smtpConfig,
})
}
func runUpdateSMTP(c *cli.Context) error {
if !c.IsSet("id") {
return fmt.Errorf("--id flag is missing")
}
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
source, err := auth_model.GetSourceByID(ctx, c.Int64("id"))
if err != nil {
return err
}
smtpConfig := source.Cfg.(*smtp.Source)
if err := parseSMTPConfig(c, smtpConfig); err != nil {
return err
}
if c.IsSet("name") {
source.Name = c.String("name")
}
if c.IsSet("active") {
source.IsActive = c.Bool("active")
}
source.Cfg = smtpConfig
return auth_model.UpdateSource(ctx, source)
}

View File

@ -1,46 +0,0 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"code.gitea.io/gitea/modules/graceful"
asymkey_service "code.gitea.io/gitea/services/asymkey"
repo_service "code.gitea.io/gitea/services/repository"
"github.com/urfave/cli/v2"
)
var (
microcmdRegenHooks = &cli.Command{
Name: "hooks",
Usage: "Regenerate git-hooks",
Action: runRegenerateHooks,
}
microcmdRegenKeys = &cli.Command{
Name: "keys",
Usage: "Regenerate authorized_keys file",
Action: runRegenerateKeys,
}
)
func runRegenerateHooks(_ *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
return repo_service.SyncRepositoryHooks(graceful.GetManager().ShutdownContext())
}
func runRegenerateKeys(_ *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
if err := initDB(ctx); err != nil {
return err
}
return asymkey_service.RewriteAllPublicKeys(ctx)
}

View File

@ -4,13 +4,13 @@
package cmd
import (
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
var subcmdUser = &cli.Command{
var subcmdUser = cli.Command{
Name: "user",
Usage: "Modify users",
Subcommands: []*cli.Command{
Subcommands: []cli.Command{
microcmdUserCreate,
microcmdUserList,
microcmdUserChangePassword,

View File

@ -4,38 +4,31 @@
package cmd
import (
"context"
"errors"
"fmt"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/auth/password"
"code.gitea.io/gitea/modules/optional"
pwd "code.gitea.io/gitea/modules/auth/password"
"code.gitea.io/gitea/modules/setting"
user_service "code.gitea.io/gitea/services/user"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
var microcmdUserChangePassword = &cli.Command{
var microcmdUserChangePassword = cli.Command{
Name: "change-password",
Usage: "Change a user's password",
Action: runChangePassword,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "username",
Aliases: []string{"u"},
Value: "",
Usage: "The user to change password for",
cli.StringFlag{
Name: "username,u",
Value: "",
Usage: "The user to change password for",
},
&cli.StringFlag{
Name: "password",
Aliases: []string{"p"},
Value: "",
Usage: "New password to set for user",
},
&cli.BoolFlag{
Name: "must-change-password",
Usage: "User must change password",
cli.StringFlag{
Name: "password,p",
Value: "",
Usage: "New password to set for user",
},
},
}
@ -51,32 +44,31 @@ func runChangePassword(c *cli.Context) error {
if err := initDB(ctx); err != nil {
return err
}
if len(c.String("password")) < setting.MinPasswordLength {
return fmt.Errorf("Password is not long enough. Needs to be at least %d", setting.MinPasswordLength)
}
user, err := user_model.GetUserByName(ctx, c.String("username"))
if !pwd.IsComplexEnough(c.String("password")) {
return errors.New("Password does not meet complexity requirements")
}
pwned, err := pwd.IsPwned(context.Background(), c.String("password"))
if err != nil {
return err
}
var mustChangePassword optional.Option[bool]
if c.IsSet("must-change-password") {
mustChangePassword = optional.Some(c.Bool("must-change-password"))
if pwned {
return errors.New("The password you chose is on a list of stolen passwords previously exposed in public data breaches. Please try again with a different password.\nFor more details, see https://haveibeenpwned.com/Passwords")
}
uname := c.String("username")
user, err := user_model.GetUserByName(ctx, uname)
if err != nil {
return err
}
if err = user.SetPassword(c.String("password")); err != nil {
return err
}
opts := &user_service.UpdateAuthOptions{
Password: optional.Some(c.String("password")),
MustChangePassword: mustChangePassword,
}
if err := user_service.UpdateAuth(ctx, user, opts); err != nil {
switch {
case errors.Is(err, password.ErrMinLength):
return fmt.Errorf("Password is not long enough. Needs to be at least %d", setting.MinPasswordLength)
case errors.Is(err, password.ErrComplexity):
return errors.New("Password does not meet complexity requirements")
case errors.Is(err, password.ErrIsPwned):
return errors.New("The password you chose is on a list of stolen passwords previously exposed in public data breaches. Please try again with a different password.\nFor more details, see https://haveibeenpwned.com/Passwords")
default:
return err
}
if err = user_model.UpdateUserCols(ctx, user, "passwd", "passwd_hash_algo", "salt"); err != nil {
return err
}
fmt.Printf("%s's password has been successfully updated!\n", user.Name)

View File

@ -6,59 +6,60 @@ package cmd
import (
"errors"
"fmt"
"os"
auth_model "code.gitea.io/gitea/models/auth"
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"
"code.gitea.io/gitea/modules/util"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
var microcmdUserCreate = &cli.Command{
var microcmdUserCreate = cli.Command{
Name: "create",
Usage: "Create a new user in database",
Action: runCreateUser,
Flags: []cli.Flag{
&cli.StringFlag{
cli.StringFlag{
Name: "name",
Usage: "Username. DEPRECATED: use username instead",
},
&cli.StringFlag{
cli.StringFlag{
Name: "username",
Usage: "Username",
},
&cli.StringFlag{
cli.StringFlag{
Name: "password",
Usage: "User password",
},
&cli.StringFlag{
cli.StringFlag{
Name: "email",
Usage: "User email address",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "admin",
Usage: "User is an admin",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "random-password",
Usage: "Generate a random password for the user",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "must-change-password",
Usage: "Set this option to false to prevent forcing the user to change their password after initial login, (Default: true)",
},
&cli.IntFlag{
cli.IntFlag{
Name: "random-password-length",
Usage: "Length of the random password to be generated",
Value: 12,
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "access-token",
Usage: "Generate access token for the user",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "restricted",
Usage: "Make a restricted user account",
},
@ -86,7 +87,7 @@ func runCreateUser(c *cli.Context) error {
username = c.String("username")
} else {
username = c.String("name")
_, _ = fmt.Fprintf(c.App.ErrWriter, "--name flag is deprecated. Use --username instead.\n")
fmt.Fprintf(os.Stderr, "--name flag is deprecated. Use --username instead.\n")
}
ctx, cancel := installSignals()
@ -115,7 +116,7 @@ func runCreateUser(c *cli.Context) error {
// If this is the first user being created.
// Take it as the admin and don't force a password update.
if n := user_model.CountUsers(ctx, nil); n == 0 {
if n := user_model.CountUsers(nil); n == 0 {
changePassword = false
}
@ -123,10 +124,10 @@ func runCreateUser(c *cli.Context) error {
changePassword = c.Bool("must-change-password")
}
restricted := optional.None[bool]()
restricted := util.OptionalBoolNone
if c.IsSet("restricted") {
restricted = optional.Some(c.Bool("restricted"))
restricted = util.OptionalBoolOf(c.Bool("restricted"))
}
// default user visibility in app.ini
@ -142,11 +143,11 @@ func runCreateUser(c *cli.Context) error {
}
overwriteDefault := &user_model.CreateUserOverwriteOptions{
IsActive: optional.Some(true),
IsActive: util.OptionalBoolTrue,
IsRestricted: restricted,
}
if err := user_model.CreateUser(ctx, u, overwriteDefault); err != nil {
if err := user_model.CreateUser(u, overwriteDefault); err != nil {
return fmt.Errorf("CreateUser: %w", err)
}
@ -156,7 +157,7 @@ func runCreateUser(c *cli.Context) error {
UID: u.ID,
}
if err := auth_model.NewAccessToken(ctx, t); err != nil {
if err := auth_model.NewAccessToken(t); err != nil {
return err
}

View File

@ -11,28 +11,26 @@ import (
"code.gitea.io/gitea/modules/storage"
user_service "code.gitea.io/gitea/services/user"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
var microcmdUserDelete = &cli.Command{
var microcmdUserDelete = cli.Command{
Name: "delete",
Usage: "Delete specific user by id, name or email",
Flags: []cli.Flag{
&cli.Int64Flag{
cli.Int64Flag{
Name: "id",
Usage: "ID of user of the user to delete",
},
&cli.StringFlag{
Name: "username",
Aliases: []string{"u"},
Usage: "Username of the user to delete",
cli.StringFlag{
Name: "username,u",
Usage: "Username of the user to delete",
},
&cli.StringFlag{
Name: "email",
Aliases: []string{"e"},
Usage: "Email of the user to delete",
cli.StringFlag{
Name: "email,e",
Usage: "Email of the user to delete",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "purge",
Usage: "Purge user, all their repositories, organizations and comments",
},

View File

@ -9,29 +9,27 @@ import (
auth_model "code.gitea.io/gitea/models/auth"
user_model "code.gitea.io/gitea/models/user"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
var microcmdUserGenerateAccessToken = &cli.Command{
var microcmdUserGenerateAccessToken = cli.Command{
Name: "generate-access-token",
Usage: "Generate an access token for a specific user",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "username",
Aliases: []string{"u"},
Usage: "Username",
cli.StringFlag{
Name: "username,u",
Usage: "Username",
},
&cli.StringFlag{
Name: "token-name",
Aliases: []string{"t"},
Usage: "Token name",
Value: "gitea-admin",
cli.StringFlag{
Name: "token-name,t",
Usage: "Token name",
Value: "gitea-admin",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "raw",
Usage: "Display only the token value",
},
&cli.StringFlag{
cli.StringFlag{
Name: "scopes",
Value: "",
Usage: "Comma separated list of scopes to apply to access token",
@ -57,29 +55,18 @@ func runGenerateAccessToken(c *cli.Context) error {
return err
}
// construct token with name and user so we can make sure it is unique
t := &auth_model.AccessToken{
Name: c.String("token-name"),
UID: user.ID,
}
exist, err := auth_model.AccessTokenByNameExists(ctx, t)
accessTokenScope, err := auth_model.AccessTokenScope(c.String("scopes")).Normalize()
if err != nil {
return err
}
if exist {
return fmt.Errorf("access token name has been used already")
t := &auth_model.AccessToken{
Name: c.String("token-name"),
UID: user.ID,
Scope: accessTokenScope,
}
// make sure the scopes are valid
accessTokenScope, err := auth_model.AccessTokenScope(c.String("scopes")).Normalize()
if err != nil {
return fmt.Errorf("invalid access token scope provided: %w", err)
}
t.Scope = accessTokenScope
// create the token
if err := auth_model.NewAccessToken(ctx, t); err != nil {
if err := auth_model.NewAccessToken(t); err != nil {
return err
}

View File

@ -10,15 +10,15 @@ import (
user_model "code.gitea.io/gitea/models/user"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
var microcmdUserList = &cli.Command{
var microcmdUserList = cli.Command{
Name: "list",
Usage: "List users",
Action: runListUsers,
Flags: []cli.Flag{
&cli.BoolFlag{
cli.BoolFlag{
Name: "admin",
Usage: "List only admin users",
},
@ -33,7 +33,7 @@ func runListUsers(c *cli.Context) error {
return err
}
users, err := user_model.GetAllUsers(ctx)
users, err := user_model.GetAllUsers()
if err != nil {
return err
}
@ -48,7 +48,7 @@ func runListUsers(c *cli.Context) error {
}
}
} else {
twofa := user_model.UserList(users).GetTwoFaStatus(ctx)
twofa := user_model.UserList(users).GetTwoFaStatus()
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

@ -9,25 +9,23 @@ import (
user_model "code.gitea.io/gitea/models/user"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
var microcmdUserMustChangePassword = &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,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "all",
Aliases: []string{"A"},
Usage: "All users must change password, except those explicitly excluded with --exclude",
cli.BoolFlag{
Name: "all,A",
Usage: "All users must change password, except those explicitly excluded with --exclude",
},
&cli.StringSliceFlag{
Name: "exclude",
Aliases: []string{"e"},
Usage: "Do not change the must-change-password flag for these users",
cli.StringSliceFlag{
Name: "exclude,e",
Usage: "Do not change the must-change-password flag for these users",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "unset",
Usage: "Instead of setting the must-change-password flag, unset it",
},
@ -50,7 +48,7 @@ func runMustChangePassword(c *cli.Context) error {
return err
}
n, err := user_model.SetMustChangePassword(ctx, all, mustChangePassword, c.Args().Slice(), exclude)
n, err := user_model.SetMustChangePassword(ctx, all, mustChangePassword, c.Args(), exclude)
if err != nil {
return err
}

View File

@ -20,50 +20,50 @@ import (
"strings"
"time"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
// CmdCert represents the available cert sub-command.
var CmdCert = &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.
Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`,
Action: runCert,
Flags: []cli.Flag{
&cli.StringFlag{
cli.StringFlag{
Name: "host",
Value: "",
Usage: "Comma-separated hostnames and IPs to generate a certificate for",
},
&cli.StringFlag{
cli.StringFlag{
Name: "ecdsa-curve",
Value: "",
Usage: "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521",
},
&cli.IntFlag{
cli.IntFlag{
Name: "rsa-bits",
Value: 3072,
Value: 2048,
Usage: "Size of RSA key to generate. Ignored if --ecdsa-curve is set",
},
&cli.StringFlag{
cli.StringFlag{
Name: "start-date",
Value: "",
Usage: "Creation date formatted as Jan 1 15:04:05 2011",
},
&cli.DurationFlag{
cli.DurationFlag{
Name: "duration",
Value: 365 * 24 * time.Hour,
Usage: "Duration that certificate is valid for",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "ca",
Usage: "whether this cert should be its own Certificate Authority",
},
},
}
func publicKey(priv any) any {
func publicKey(priv interface{}) interface{} {
switch k := priv.(type) {
case *rsa.PrivateKey:
return &k.PublicKey
@ -74,7 +74,7 @@ func publicKey(priv any) any {
}
}
func pemBlockForKey(priv any) *pem.Block {
func pemBlockForKey(priv interface{}) *pem.Block {
switch k := priv.(type) {
case *rsa.PrivateKey:
return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}
@ -94,7 +94,7 @@ func runCert(c *cli.Context) error {
return err
}
var priv any
var priv interface{}
var err error
switch c.String("ecdsa-curve") {
case "":

View File

@ -9,7 +9,6 @@ import (
"context"
"errors"
"fmt"
"io"
"os"
"os/signal"
"strings"
@ -20,7 +19,7 @@ import (
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
// argsSet checks that all the required arguments are set. args is a list of
@ -58,9 +57,10 @@ func confirm() (bool, error) {
}
func initDB(ctx context.Context) error {
setting.MustInstalled()
setting.InitProviderFromExistingFile()
setting.LoadCommonSettings()
setting.LoadDBSetting()
setting.InitSQLLoggersForCli(log.INFO)
setting.InitSQLLog(false)
if setting.Database.Type == "" {
log.Fatal(`Database settings are missing from the configuration file: %q.
@ -94,42 +94,3 @@ func installSignals() (context.Context, context.CancelFunc) {
return ctx, cancel
}
func setupConsoleLogger(level log.Level, colorize bool, out io.Writer) {
if out != os.Stdout && out != os.Stderr {
panic("setupConsoleLogger can only be used with os.Stdout or os.Stderr")
}
writeMode := log.WriterMode{
Level: level,
Colorize: colorize,
WriterOption: log.WriterConsoleOption{Stderr: out == os.Stderr},
}
writer := log.NewEventWriterConsole("console-default", writeMode)
log.GetManager().GetLogger(log.DEFAULT).ReplaceAllWriters(writer)
}
func globalBool(c *cli.Context, name string) bool {
for _, ctx := range c.Lineage() {
if ctx.Bool(name) {
return true
}
}
return false
}
// 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(*cli.Context) error {
return func(c *cli.Context) error {
level := defaultLevel
if globalBool(c, "quiet") {
level = log.FATAL
}
if globalBool(c, "debug") || globalBool(c, "verbose") {
level = log.TRACE
}
log.SetConsoleLogger(log.DEFAULT, "console-default", level)
return nil
}
}

56
cmd/convert.go Normal file
View File

@ -0,0 +1,56 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"fmt"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli"
)
// CmdConvert represents the available convert sub-command.
var CmdConvert = cli.Command{
Name: "convert",
Usage: "Convert the database",
Description: "A command to convert an existing MySQL database from utf8 to utf8mb4 or MSSQL database from varchar to nvarchar",
Action: runConvert,
}
func runConvert(ctx *cli.Context) error {
stdCtx, cancel := installSignals()
defer cancel()
if err := initDB(stdCtx); err != nil {
return err
}
log.Info("AppPath: %s", setting.AppPath)
log.Info("AppWorkPath: %s", setting.AppWorkPath)
log.Info("Custom path: %s", setting.CustomPath)
log.Info("Log path: %s", setting.Log.RootPath)
log.Info("Configuration file: %s", setting.CustomConf)
switch {
case setting.Database.Type.IsMySQL():
if err := db.ConvertUtf8ToUtf8mb4(); err != nil {
log.Fatal("Failed to convert database from utf8 to utf8mb4: %v", err)
return err
}
fmt.Println("Converted successfully, please confirm your database's character set is now utf8mb4")
case setting.Database.Type.IsMSSQL():
if err := db.ConvertVarcharToNVarchar(); err != nil {
log.Fatal("Failed to convert database from varchar to nvarchar: %v", err)
return err
}
fmt.Println("Converted successfully, please confirm your database's all columns character is NVARCHAR now")
default:
fmt.Println("This command can only be used with a MySQL or MSSQL database")
}
return nil
}

View File

@ -8,11 +8,11 @@ import (
"os"
"strings"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
// CmdDocs represents the available docs sub-command.
var CmdDocs = &cli.Command{
var CmdDocs = cli.Command{
Name: "docs",
Usage: "Output CLI documentation",
Description: "A command to output Gitea's CLI documentation, optionally to a file.",
@ -23,9 +23,8 @@ var CmdDocs = &cli.Command{
Usage: "Output man pages instead",
},
&cli.StringFlag{
Name: "output",
Aliases: []string{"o"},
Usage: "Path to output to instead of stdout (will overwrite if exists)",
Name: "output, o",
Usage: "Path to output to instead of stdout (will overwrite if exists)",
},
},
}

View File

@ -4,82 +4,71 @@
package cmd
import (
"errors"
"fmt"
golog "log"
"os"
"path/filepath"
"strings"
"text/tabwriter"
"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/doctor"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/services/doctor"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
"xorm.io/xorm"
)
// CmdDoctor represents the available doctor sub-command.
var CmdDoctor = &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 Gitea instance according to the given configuration. Some problems can optionally be fixed by modifying the database or data storage.",
Subcommands: []*cli.Command{
cmdDoctorCheck,
cmdRecreateTable,
cmdDoctorConvert,
},
}
var cmdDoctorCheck = &cli.Command{
Name: "check",
Usage: "Diagnose and optionally fix problems",
Description: "A command to diagnose problems with the current Gitea instance according to the given configuration. Some problems can optionally be fixed by modifying the database or data storage.",
Action: runDoctorCheck,
Action: runDoctor,
Flags: []cli.Flag{
&cli.BoolFlag{
cli.BoolFlag{
Name: "list",
Usage: "List the available checks",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "default",
Usage: "Run the default checks (if neither --run or --all is set, this is the default behaviour)",
},
&cli.StringSliceFlag{
cli.StringSliceFlag{
Name: "run",
Usage: "Run the provided checks - (if --default is set, the default checks will also run)",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "all",
Usage: "Run all the available checks",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "fix",
Usage: "Automatically fix what we can",
},
&cli.StringFlag{
cli.StringFlag{
Name: "log-file",
Usage: `Name of the log file (no verbose log output by default). Set to "-" to output to stdout`,
Usage: `Name of the log file (default: "doctor.log"). Set to "-" to output to stdout, set to "" to disable`,
},
&cli.BoolFlag{
Name: "color",
Aliases: []string{"H"},
Usage: "Use color for outputted information",
cli.BoolFlag{
Name: "color, H",
Usage: "Use color for outputted information",
},
},
Subcommands: []cli.Command{
cmdRecreateTable,
},
}
var cmdRecreateTable = &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)",
Flags: []cli.Flag{
&cli.BoolFlag{
cli.BoolFlag{
Name: "debug",
Usage: "Print SQL commands sent",
},
@ -93,25 +82,24 @@ You should back-up your database before doing this and ensure that your database
}
func runRecreateTable(ctx *cli.Context) error {
stdCtx, cancel := installSignals()
defer cancel()
// Redirect the default golog to here
golog.SetFlags(0)
golog.SetPrefix("")
golog.SetOutput(log.LoggerToWriter(log.GetLogger(log.DEFAULT).Info))
golog.SetOutput(log.NewLoggerAsWriter("INFO", log.GetLogger(log.DEFAULT)))
debug := ctx.Bool("debug")
setting.MustInstalled()
setting.InitProviderFromExistingFile()
setting.LoadCommonSettings()
setting.LoadDBSetting()
if debug {
setting.InitSQLLoggersForCli(log.DEBUG)
} else {
setting.InitSQLLoggersForCli(log.INFO)
}
setting.Log.EnableXORMLog = ctx.Bool("debug")
setting.Database.LogSQL = ctx.Bool("debug")
// FIXME: don't use CfgProvider directly
setting.CfgProvider.Section("log").Key("XORM").SetValue(",")
setting.InitSQLLog(!ctx.Bool("debug"))
stdCtx, cancel := installSignals()
defer cancel()
setting.Database.LogSQL = debug
if err := db.InitEngine(stdCtx); err != nil {
fmt.Println(err)
fmt.Println("Check if you are using the right config file. You can use a --config directive to specify one.")
@ -138,47 +126,71 @@ func runRecreateTable(ctx *cli.Context) error {
})
}
func setupDoctorDefaultLogger(ctx *cli.Context, colorize bool) {
// Silence the default loggers
setupConsoleLogger(log.FATAL, log.CanColorStderr, os.Stderr)
func setDoctorLogger(ctx *cli.Context) {
logFile := ctx.String("log-file")
if logFile == "" {
return // if no doctor log-file is set, do not show any log from default logger
} else if logFile == "-" {
setupConsoleLogger(log.TRACE, colorize, os.Stdout)
} 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)
if err != nil {
log.FallbackErrorf("unable to create file log writer: %v", err)
if !ctx.IsSet("log-file") {
logFile = "doctor.log"
}
colorize := log.CanColorStdout
if ctx.IsSet("color") {
colorize = ctx.Bool("color")
}
if len(logFile) == 0 {
log.NewLogger(1000, "doctor", "console", fmt.Sprintf(`{"level":"NONE","stacktracelevel":"NONE","colorize":%t}`, colorize))
return
}
defer func() {
recovered := recover()
if recovered == nil {
return
}
log.GetManager().GetLogger(log.DEFAULT).ReplaceAllWriters(writer)
err, ok := recovered.(error)
if !ok {
panic(recovered)
}
if errors.Is(err, os.ErrPermission) {
fmt.Fprintf(os.Stderr, "ERROR: Unable to write logs to provided file due to permissions error: %s\n %v\n", logFile, err)
} else {
fmt.Fprintf(os.Stderr, "ERROR: Unable to write logs to provided file: %s\n %v\n", logFile, err)
}
fmt.Fprintf(os.Stderr, "WARN: Logging will be disabled\n Use `--log-file` to configure log file location\n")
log.NewLogger(1000, "doctor", "console", fmt.Sprintf(`{"level":"NONE","stacktracelevel":"NONE","colorize":%t}`, colorize))
}()
if logFile == "-" {
log.NewLogger(1000, "doctor", "console", fmt.Sprintf(`{"level":"trace","stacktracelevel":"NONE","colorize":%t}`, colorize))
} else {
log.NewLogger(1000, "doctor", "file", fmt.Sprintf(`{"filename":%q,"level":"trace","stacktracelevel":"NONE"}`, logFile))
}
}
func runDoctorCheck(ctx *cli.Context) error {
func runDoctor(ctx *cli.Context) error {
stdCtx, cancel := installSignals()
defer cancel()
// Silence the default loggers
log.DelNamedLogger("console")
log.DelNamedLogger(log.DEFAULT)
// Now setup our own
setDoctorLogger(ctx)
colorize := log.CanColorStdout
if ctx.IsSet("color") {
colorize = ctx.Bool("color")
}
setupDoctorDefaultLogger(ctx, colorize)
// Finally redirect the default golang's log to here
// Finally redirect the default golog to here
golog.SetFlags(0)
golog.SetPrefix("")
golog.SetOutput(log.LoggerToWriter(log.GetLogger(log.DEFAULT).Info))
golog.SetOutput(log.NewLoggerAsWriter("INFO", log.GetLogger(log.DEFAULT)))
if ctx.IsSet("list") {
w := tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', 0)
_, _ = w.Write([]byte("Default\tName\tTitle\n"))
doctor.SortChecks(doctor.Checks)
for _, check := range doctor.Checks {
if check.IsDefault {
_, _ = w.Write([]byte{'*'})
@ -194,19 +206,25 @@ func runDoctorCheck(ctx *cli.Context) error {
var checks []*doctor.Check
if ctx.Bool("all") {
checks = make([]*doctor.Check, len(doctor.Checks))
copy(checks, doctor.Checks)
checks = doctor.Checks
} else if ctx.IsSet("run") {
addDefault := ctx.Bool("default")
runNamesSet := container.SetOf(ctx.StringSlice("run")...)
for _, check := range doctor.Checks {
if (addDefault && check.IsDefault) || runNamesSet.Contains(check.Name) {
checks = append(checks, check)
runNamesSet.Remove(check.Name)
}
names := ctx.StringSlice("run")
for i, name := range names {
names[i] = strings.ToLower(strings.TrimSpace(name))
}
if len(runNamesSet) > 0 {
return fmt.Errorf("unknown checks: %q", strings.Join(runNamesSet.Values(), ","))
for _, check := range doctor.Checks {
if addDefault && check.IsDefault {
checks = append(checks, check)
continue
}
for _, name := range names {
if name == check.Name {
checks = append(checks, check)
break
}
}
}
} else {
for _, check := range doctor.Checks {
@ -215,5 +233,18 @@ func runDoctorCheck(ctx *cli.Context) error {
}
}
}
return doctor.RunChecks(stdCtx, colorize, ctx.Bool("fix"), checks)
// Now we can set up our own logger to return information about what the doctor is doing
if err := log.NewNamedLogger("doctorouter",
0,
"console",
"console",
fmt.Sprintf(`{"level":"INFO","stacktracelevel":"NONE","colorize":%t,"flags":-1}`, colorize)); err != nil {
fmt.Println(err)
return err
}
logger := log.GetLogger("doctorouter")
defer logger.Close()
return doctor.RunChecks(stdCtx, logger, ctx.Bool("fix"), checks)
}

View File

@ -1,56 +0,0 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"fmt"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli/v2"
)
// cmdDoctorConvert represents the available convert sub-command.
var cmdDoctorConvert = &cli.Command{
Name: "convert",
Usage: "Convert the database",
Description: "A command to convert an existing MySQL database from utf8 to utf8mb4 or MSSQL database from varchar to nvarchar",
Action: runDoctorConvert,
}
func runDoctorConvert(ctx *cli.Context) error {
stdCtx, cancel := installSignals()
defer cancel()
if err := initDB(stdCtx); err != nil {
return err
}
log.Info("AppPath: %s", setting.AppPath)
log.Info("AppWorkPath: %s", setting.AppWorkPath)
log.Info("Custom path: %s", setting.CustomPath)
log.Info("Log path: %s", setting.Log.RootPath)
log.Info("Configuration file: %s", setting.CustomConf)
switch {
case setting.Database.Type.IsMySQL():
if err := db.ConvertDatabaseTable(); err != nil {
log.Fatal("Failed to convert database & table: %v", err)
return err
}
fmt.Println("Converted successfully, please confirm your database's character set is now utf8mb4")
case setting.Database.Type.IsMSSQL():
if err := db.ConvertVarcharToNVarchar(); err != nil {
log.Fatal("Failed to convert database from varchar to nvarchar: %v", err)
return err
}
fmt.Println("Converted successfully, please confirm your database's all columns character is NVARCHAR now")
default:
fmt.Println("This command can only be used with a MySQL or MSSQL database")
}
return nil
}

View File

@ -1,33 +0,0 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"context"
"testing"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/services/doctor"
"github.com/stretchr/testify/assert"
"github.com/urfave/cli/v2"
)
func TestDoctorRun(t *testing.T) {
doctor.Register(&doctor.Check{
Title: "Test Check",
Name: "test-check",
Run: func(ctx context.Context, logger log.Logger, autofix bool) error { return nil },
SkipDatabaseInitialization: true,
})
app := cli.NewApp()
app.Commands = []*cli.Command{cmdDoctorCheck}
err := app.Run([]string{"./gitea", "check", "--run", "test-check"})
assert.NoError(t, err)
err = app.Run([]string{"./gitea", "check", "--run", "no-such"})
assert.ErrorContains(t, err, `unknown checks: "no-such"`)
err = app.Run([]string{"./gitea", "check", "--run", "test-check,no-such"})
assert.ErrorContains(t, err, `unknown checks: "no-such"`)
}

View File

@ -22,7 +22,7 @@ import (
"gitea.com/go-chi/session"
"github.com/mholt/archiver/v3"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
func addReader(w archiver.Writer, r io.ReadCloser, info os.FileInfo, customName string, verbose bool) error {
@ -96,71 +96,60 @@ var outputTypeEnum = &outputType{
}
// CmdDump represents the available dump sub-command.
var CmdDump = &cli.Command{
var CmdDump = cli.Command{
Name: "dump",
Usage: "Dump Gitea files and database",
Description: `Dump compresses all related files and database into zip file.
It can be used for backup and capture Gitea server image to send to maintainer`,
Action: runDump,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "file",
Aliases: []string{"f"},
Value: fmt.Sprintf("gitea-dump-%d.zip", time.Now().Unix()),
Usage: "Name of the dump file which will be created. Supply '-' for stdout. See type for available types.",
cli.StringFlag{
Name: "file, f",
Value: fmt.Sprintf("gitea-dump-%d.zip", time.Now().Unix()),
Usage: "Name of the dump file which will be created. Supply '-' for stdout. See type for available types.",
},
&cli.BoolFlag{
Name: "verbose",
Aliases: []string{"V"},
Usage: "Show process details",
cli.BoolFlag{
Name: "verbose, V",
Usage: "Show process details",
},
&cli.BoolFlag{
Name: "quiet",
Aliases: []string{"q"},
Usage: "Only display warnings and errors",
cli.StringFlag{
Name: "tempdir, t",
Value: os.TempDir(),
Usage: "Temporary dir path",
},
&cli.StringFlag{
Name: "tempdir",
Aliases: []string{"t"},
Value: os.TempDir(),
Usage: "Temporary dir path",
cli.StringFlag{
Name: "database, d",
Usage: "Specify the database SQL syntax",
},
&cli.StringFlag{
Name: "database",
Aliases: []string{"d"},
Usage: "Specify the database SQL syntax: sqlite3, mysql, mssql, postgres",
cli.BoolFlag{
Name: "skip-repository, R",
Usage: "Skip the repository dumping",
},
&cli.BoolFlag{
Name: "skip-repository",
Aliases: []string{"R"},
Usage: "Skip the repository dumping",
cli.BoolFlag{
Name: "skip-log, L",
Usage: "Skip the log dumping",
},
&cli.BoolFlag{
Name: "skip-log",
Aliases: []string{"L"},
Usage: "Skip the log dumping",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "skip-custom-dir",
Usage: "Skip custom directory",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "skip-lfs-data",
Usage: "Skip LFS data",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "skip-attachment-data",
Usage: "Skip attachment data",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "skip-package-data",
Usage: "Skip package data",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "skip-index",
Usage: "Skip bleve index data",
},
&cli.GenericFlag{
cli.GenericFlag{
Name: "type",
Value: outputTypeEnum,
Usage: fmt.Sprintf("Dump output format: %s", outputTypeEnum.Join()),
@ -168,7 +157,7 @@ It can be used for backup and capture Gitea server image to send to maintainer`,
},
}
func fatal(format string, args ...any) {
func fatal(format string, args ...interface{}) {
fmt.Fprintf(os.Stderr, format+"\n", args...)
log.Fatal(format, args...)
}
@ -179,7 +168,10 @@ func runDump(ctx *cli.Context) error {
outType := ctx.String("type")
if fileName == "-" {
file = os.Stdout
setupConsoleLogger(log.FATAL, log.CanColorStderr, os.Stderr)
err := log.DelLogger("console")
if err != nil {
fatal("Deleting default logger failed. Can not write to stdout: %v", err)
}
} else {
for _, suffix := range outputTypeEnum.Enum {
if strings.HasSuffix(fileName, "."+suffix) {
@ -189,7 +181,8 @@ func runDump(ctx *cli.Context) error {
}
fileName += "." + outType
}
setting.MustInstalled()
setting.InitProviderFromExistingFile()
setting.LoadCommonSettings()
// make sure we are logging to the console no matter what the configuration tells us do to
// FIXME: don't use CfgProvider directly
@ -199,25 +192,12 @@ func runDump(ctx *cli.Context) error {
if _, err := setting.CfgProvider.Section("log.console").NewKey("STDERR", "true"); err != nil {
fatal("Setting console logger to stderr failed: %v", err)
}
// Set loglevel to Warn if quiet-mode is requested
if ctx.Bool("quiet") {
if _, err := setting.CfgProvider.Section("log.console").NewKey("LEVEL", "Warn"); err != nil {
fatal("Setting console log-level failed: %v", err)
}
}
if !setting.InstallLock {
log.Error("Is '%s' really the right config path?\n", setting.CustomConf)
return fmt.Errorf("gitea is not initialized")
}
setting.LoadSettings() // cannot access session settings otherwise
verbose := ctx.Bool("verbose")
if verbose && ctx.Bool("quiet") {
return fmt.Errorf("--quiet and --verbose cannot both be set")
}
stdCtx, cancel := installSignals()
defer cancel()
@ -243,7 +223,8 @@ func runDump(ctx *cli.Context) error {
return err
}
var iface any
verbose := ctx.Bool("verbose")
var iface interface{}
if fileName == "-" {
iface, err = archiver.ByExtension(fmt.Sprintf(".%s", outType))
} else {
@ -271,7 +252,7 @@ func runDump(ctx *cli.Context) error {
log.Info("Skip dumping LFS data")
} else if !setting.LFS.StartServer {
log.Info("LFS isn't enabled. Skip dumping LFS data")
} else if err := storage.LFS.IterateObjects("", func(objPath string, object storage.Object) error {
} else if err := storage.LFS.IterateObjects(func(objPath string, object storage.Object) error {
info, err := object.Stat()
if err != nil {
return err
@ -360,9 +341,9 @@ func runDump(ctx *cli.Context) error {
}
excludes = append(excludes, setting.RepoRootPath)
excludes = append(excludes, setting.LFS.Storage.Path)
excludes = append(excludes, setting.Attachment.Storage.Path)
excludes = append(excludes, setting.Packages.Storage.Path)
excludes = append(excludes, setting.LFS.Path)
excludes = append(excludes, setting.Attachment.Path)
excludes = append(excludes, setting.Packages.Path)
excludes = append(excludes, setting.Log.RootPath)
excludes = append(excludes, absFileName)
if err := addRecursiveExclude(w, "data", setting.AppDataPath, excludes, verbose); err != nil {
@ -372,7 +353,7 @@ func runDump(ctx *cli.Context) error {
if ctx.IsSet("skip-attachment-data") && ctx.Bool("skip-attachment-data") {
log.Info("Skip dumping attachment data")
} else if err := storage.Attachments.IterateObjects("", func(objPath string, object storage.Object) error {
} else if err := storage.Attachments.IterateObjects(func(objPath string, object storage.Object) error {
info, err := object.Stat()
if err != nil {
return err
@ -387,7 +368,7 @@ func runDump(ctx *cli.Context) error {
log.Info("Skip dumping package data")
} else if !setting.Packages.Enabled {
log.Info("Packages isn't enabled. Skip dumping package data")
} else if err := storage.Packages.IterateObjects("", func(objPath string, object storage.Object) error {
} else if err := storage.Packages.IterateObjects(func(objPath string, object storage.Object) error {
info, err := object.Stat()
if err != nil {
return err
@ -452,7 +433,7 @@ func addRecursiveExclude(w archiver.Writer, insidePath, absPath string, excludeA
return err
}
for _, file := range files {
currentAbsPath := filepath.Join(absPath, file.Name())
currentAbsPath := path.Join(absPath, file.Name())
currentInsidePath := path.Join(insidePath, file.Name())
if file.IsDir() {
if !util.SliceContainsString(excludeAbsPath, currentAbsPath) {

View File

@ -19,58 +19,57 @@ import (
"code.gitea.io/gitea/services/convert"
"code.gitea.io/gitea/services/migrations"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
// CmdDumpRepository represents the available dump repository sub-command.
var CmdDumpRepository = &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.",
Action: runDumpRepository,
Flags: []cli.Flag{
&cli.StringFlag{
cli.StringFlag{
Name: "git_service",
Value: "",
Usage: "Git service, git, github, gitea, gitlab. If clone_addr could be recognized, this could be ignored.",
},
&cli.StringFlag{
Name: "repo_dir",
Aliases: []string{"r"},
Value: "./data",
Usage: "Repository dir path to store the data",
cli.StringFlag{
Name: "repo_dir, r",
Value: "./data",
Usage: "Repository dir path to store the data",
},
&cli.StringFlag{
cli.StringFlag{
Name: "clone_addr",
Value: "",
Usage: "The URL will be clone, currently could be a git/github/gitea/gitlab http/https URL",
},
&cli.StringFlag{
cli.StringFlag{
Name: "auth_username",
Value: "",
Usage: "The username to visit the clone_addr",
},
&cli.StringFlag{
cli.StringFlag{
Name: "auth_password",
Value: "",
Usage: "The password to visit the clone_addr",
},
&cli.StringFlag{
cli.StringFlag{
Name: "auth_token",
Value: "",
Usage: "The personal token to visit the clone_addr",
},
&cli.StringFlag{
cli.StringFlag{
Name: "owner_name",
Value: "",
Usage: "The data will be stored on a directory with owner name if not empty",
},
&cli.StringFlag{
cli.StringFlag{
Name: "repo_name",
Value: "",
Usage: "The data will be stored on a directory with repository name if not empty",
},
&cli.StringFlag{
cli.StringFlag{
Name: "units",
Value: "",
Usage: `Which items will be migrated, one or more units should be separated as comma.

View File

@ -1,6 +1,8 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
//go:build bindata
package cmd
import (
@ -8,9 +10,9 @@ import (
"fmt"
"os"
"path/filepath"
"sort"
"strings"
"code.gitea.io/gitea/modules/assetfs"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/options"
"code.gitea.io/gitea/modules/public"
@ -19,98 +21,118 @@ import (
"code.gitea.io/gitea/modules/util"
"github.com/gobwas/glob"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
// CmdEmbedded represents the available extract sub-command.
// Cmdembedded represents the available extract sub-command.
var (
CmdEmbedded = &cli.Command{
Cmdembedded = cli.Command{
Name: "embedded",
Usage: "Extract embedded resources",
Description: "A command for extracting embedded resources, like templates and images",
Subcommands: []*cli.Command{
Subcommands: []cli.Command{
subcmdList,
subcmdView,
subcmdExtract,
},
}
subcmdList = &cli.Command{
subcmdList = cli.Command{
Name: "list",
Usage: "List files matching the given pattern",
Action: runList,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "include-vendored",
Aliases: []string{"vendor"},
Usage: "Include files under public/vendor as well",
cli.BoolFlag{
Name: "include-vendored,vendor",
Usage: "Include files under public/vendor as well",
},
},
}
subcmdView = &cli.Command{
subcmdView = cli.Command{
Name: "view",
Usage: "View a file matching the given pattern",
Action: runView,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "include-vendored",
Aliases: []string{"vendor"},
Usage: "Include files under public/vendor as well",
cli.BoolFlag{
Name: "include-vendored,vendor",
Usage: "Include files under public/vendor as well",
},
},
}
subcmdExtract = &cli.Command{
subcmdExtract = cli.Command{
Name: "extract",
Usage: "Extract resources",
Action: runExtract,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "include-vendored",
Aliases: []string{"vendor"},
Usage: "Include files under public/vendor as well",
cli.BoolFlag{
Name: "include-vendored,vendor",
Usage: "Include files under public/vendor as well",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "overwrite",
Usage: "Overwrite files if they already exist",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "rename",
Usage: "Rename files as {name}.bak if they already exist (overwrites previous .bak)",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "custom",
Usage: "Extract to the 'custom' directory as per app.ini",
},
&cli.StringFlag{
Name: "destination",
Aliases: []string{"dest-dir"},
Usage: "Extract to the specified directory",
cli.StringFlag{
Name: "destination,dest-dir",
Usage: "Extract to the specified directory",
},
},
}
matchedAssetFiles []assetFile
sections map[string]*section
assets []asset
)
type assetFile struct {
fs *assetfs.LayeredFS
name string
path string
type section struct {
Path string
Names func() []string
IsDir func(string) (bool, error)
Asset func(string) ([]byte, error)
}
type asset struct {
Section *section
Name string
Path string
}
func initEmbeddedExtractor(c *cli.Context) error {
setupConsoleLogger(log.ERROR, log.CanColorStderr, os.Stderr)
// Silence the console logger
log.DelNamedLogger("console")
log.DelNamedLogger(log.DEFAULT)
patterns, err := compileCollectPatterns(c.Args().Slice())
// Read configuration file
setting.InitProviderAllowEmpty()
setting.LoadCommonSettings()
pats, err := getPatterns(c.Args())
if err != nil {
return err
}
sections := make(map[string]*section, 3)
collectAssetFilesByPattern(c, patterns, "options", options.BuiltinAssets())
collectAssetFilesByPattern(c, patterns, "public", public.BuiltinAssets())
collectAssetFilesByPattern(c, patterns, "templates", templates.BuiltinAssets())
sections["public"] = &section{Path: "public", Names: public.AssetNames, IsDir: public.AssetIsDir, Asset: public.Asset}
sections["options"] = &section{Path: "options", Names: options.AssetNames, IsDir: options.AssetIsDir, Asset: options.Asset}
sections["templates"] = &section{Path: "templates", Names: templates.BuiltinAssetNames, IsDir: templates.BuiltinAssetIsDir, Asset: templates.BuiltinAsset}
for _, sec := range sections {
assets = append(assets, buildAssetList(sec, pats, c)...)
}
// Sort assets
sort.SliceStable(assets, func(i, j int) bool {
return assets[i].Path < assets[j].Path
})
return nil
}
@ -144,8 +166,8 @@ func runListDo(c *cli.Context) error {
return err
}
for _, a := range matchedAssetFiles {
fmt.Println(a.path)
for _, a := range assets {
fmt.Println(a.Path)
}
return nil
@ -156,19 +178,19 @@ func runViewDo(c *cli.Context) error {
return err
}
if len(matchedAssetFiles) == 0 {
return fmt.Errorf("no files matched the given pattern")
} else if len(matchedAssetFiles) > 1 {
return fmt.Errorf("too many files matched the given pattern, try to be more specific")
if len(assets) == 0 {
return fmt.Errorf("No files matched the given pattern")
} else if len(assets) > 1 {
return fmt.Errorf("Too many files matched the given pattern; try to be more specific")
}
data, err := matchedAssetFiles[0].fs.ReadFile(matchedAssetFiles[0].name)
data, err := assets[0].Section.Asset(assets[0].Name)
if err != nil {
return fmt.Errorf("%s: %w", matchedAssetFiles[0].path, err)
return fmt.Errorf("%s: %w", assets[0].Path, err)
}
if _, err = os.Stdout.Write(data); err != nil {
return fmt.Errorf("%s: %w", matchedAssetFiles[0].path, err)
return fmt.Errorf("%s: %w", assets[0].Path, err)
}
return nil
@ -179,8 +201,8 @@ func runExtractDo(c *cli.Context) error {
return err
}
if c.NArg() == 0 {
return fmt.Errorf("a list of pattern of files to extract is mandatory (e.g. '**' for all)")
if len(c.Args()) == 0 {
return fmt.Errorf("A list of pattern of files to extract is mandatory (e.g. '**' for all)")
}
destdir := "."
@ -205,7 +227,7 @@ func runExtractDo(c *cli.Context) error {
if err != nil {
return fmt.Errorf("%s: %s", destdir, err)
} else if !fi.IsDir() {
return fmt.Errorf("destination %q is not a directory", destdir)
return fmt.Errorf("%s is not a directory.", destdir)
}
fmt.Printf("Extracting to %s:\n", destdir)
@ -213,23 +235,23 @@ func runExtractDo(c *cli.Context) error {
overwrite := c.Bool("overwrite")
rename := c.Bool("rename")
for _, a := range matchedAssetFiles {
for _, a := range assets {
if err := extractAsset(destdir, a, overwrite, rename); err != nil {
// Non-fatal error
fmt.Fprintf(os.Stderr, "%s: %v", a.path, err)
fmt.Fprintf(os.Stderr, "%s: %v", a.Path, err)
}
}
return nil
}
func extractAsset(d string, a assetFile, overwrite, rename bool) error {
dest := filepath.Join(d, filepath.FromSlash(a.path))
func extractAsset(d string, a asset, overwrite, rename bool) error {
dest := filepath.Join(d, filepath.FromSlash(a.Path))
dir := filepath.Dir(dest)
data, err := a.fs.ReadFile(a.name)
data, err := a.Section.Asset(a.Name)
if err != nil {
return fmt.Errorf("%s: %w", a.path, err)
return fmt.Errorf("%s: %w", a.Path, err)
}
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
@ -250,7 +272,7 @@ func extractAsset(d string, a assetFile, overwrite, rename bool) error {
return fmt.Errorf("%s already exists, but it's not a regular file", dest)
} else if rename {
if err := util.Rename(dest, dest+".bak"); err != nil {
return fmt.Errorf("error creating backup for %s: %w", dest, err)
return fmt.Errorf("Error creating backup for %s: %w", dest, err)
}
// Attempt to respect file permissions mask (even if user:group will be set anew)
perms = fi.Mode()
@ -271,30 +293,32 @@ func extractAsset(d string, a assetFile, overwrite, rename bool) error {
return nil
}
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 {
log.Error("Error listing files in %q: %v", path, err)
return
}
for _, name := range files {
if path == "public" &&
strings.HasPrefix(name, "vendor/") &&
!c.Bool("include-vendored") {
continue
}
matchName := path + "/" + name
for _, g := range globs {
if g.Match(matchName) {
matchedAssetFiles = append(matchedAssetFiles, assetFile{fs: fs, name: name, path: path + "/" + name})
break
func buildAssetList(sec *section, globs []glob.Glob, c *cli.Context) []asset {
results := make([]asset, 0, 64)
for _, name := range sec.Names() {
if isdir, err := sec.IsDir(name); !isdir && err == nil {
if sec.Path == "public" &&
strings.HasPrefix(name, "vendor/") &&
!c.Bool("include-vendored") {
continue
}
matchName := sec.Path + "/" + name
for _, g := range globs {
if g.Match(matchName) {
results = append(results, asset{
Section: sec,
Name: name,
Path: sec.Path + "/" + name,
})
break
}
}
}
}
return results
}
func compileCollectPatterns(args []string) ([]glob.Glob, error) {
func getPatterns(args []string) ([]glob.Glob, error) {
if len(args) == 0 {
args = []string{"**"}
}
@ -302,7 +326,7 @@ func compileCollectPatterns(args []string) ([]glob.Glob, error) {
for i := range args {
if g, err := glob.Compile(args[i], '/'); err != nil {
return nil, fmt.Errorf("'%s': Invalid glob pattern: %w", args[i], err)
} else { //nolint:revive
} else {
pat[i] = g
}
}

29
cmd/embedded_stub.go Normal file
View File

@ -0,0 +1,29 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
//go:build !bindata
package cmd
import (
"fmt"
"os"
"github.com/urfave/cli"
)
// Cmdembedded represents the available extract sub-command.
var (
Cmdembedded = cli.Command{
Name: "embedded",
Usage: "Extract embedded resources",
Description: "A command for extracting embedded resources, like templates and images",
Action: extractorNotImplemented,
}
)
func extractorNotImplemented(c *cli.Context) error {
err := fmt.Errorf("Sorry: the 'embedded' subcommand is not available in builds without bindata")
fmt.Fprintf(os.Stderr, "%s\n", err)
return err
}

View File

@ -11,43 +11,43 @@ import (
"code.gitea.io/gitea/modules/generate"
"github.com/mattn/go-isatty"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
var (
// CmdGenerate represents the available generate sub-command.
CmdGenerate = &cli.Command{
CmdGenerate = cli.Command{
Name: "generate",
Usage: "Generate Gitea's secrets/keys/tokens",
Subcommands: []*cli.Command{
Usage: "Command line interface for running generators",
Subcommands: []cli.Command{
subcmdSecret,
},
}
subcmdSecret = &cli.Command{
subcmdSecret = cli.Command{
Name: "secret",
Usage: "Generate a secret token",
Subcommands: []*cli.Command{
Subcommands: []cli.Command{
microcmdGenerateInternalToken,
microcmdGenerateLfsJwtSecret,
microcmdGenerateSecretKey,
},
}
microcmdGenerateInternalToken = &cli.Command{
microcmdGenerateInternalToken = cli.Command{
Name: "INTERNAL_TOKEN",
Usage: "Generate a new INTERNAL_TOKEN",
Action: runGenerateInternalToken,
}
microcmdGenerateLfsJwtSecret = &cli.Command{
microcmdGenerateLfsJwtSecret = cli.Command{
Name: "JWT_SECRET",
Aliases: []string{"LFS_JWT_SECRET"},
Usage: "Generate a new JWT_SECRET",
Action: runGenerateLfsJwtSecret,
}
microcmdGenerateSecretKey = &cli.Command{
microcmdGenerateSecretKey = cli.Command{
Name: "SECRET_KEY",
Usage: "Generate a new SECRET_KEY",
Action: runGenerateSecretKey,
@ -70,12 +70,12 @@ func runGenerateInternalToken(c *cli.Context) error {
}
func runGenerateLfsJwtSecret(c *cli.Context) error {
_, jwtSecretBase64, err := generate.NewJwtSecretWithBase64()
JWTSecretBase64, err := generate.NewJwtSecretBase64()
if err != nil {
return err
}
fmt.Printf("%s", jwtSecretBase64)
fmt.Printf("%s", JWTSecretBase64)
if isatty.IsTerminal(os.Stdout.Fd()) {
fmt.Printf("\n")

View File

@ -6,21 +6,21 @@ package cmd
import (
"bufio"
"bytes"
"context"
"fmt"
"io"
"net/http"
"os"
"strconv"
"strings"
"time"
"code.gitea.io/gitea/modules/git"
"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"
"code.gitea.io/gitea/modules/util"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
const (
@ -29,12 +29,11 @@ const (
var (
// CmdHook represents the available hooks sub-command.
CmdHook = &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),
Subcommands: []*cli.Command{
Usage: "Delegate commands to corresponding Git hooks",
Description: "This should only be called by Git",
Subcommands: []cli.Command{
subcmdHookPreReceive,
subcmdHookUpdate,
subcmdHookPostReceive,
@ -42,47 +41,47 @@ var (
},
}
subcmdHookPreReceive = &cli.Command{
subcmdHookPreReceive = cli.Command{
Name: "pre-receive",
Usage: "Delegate pre-receive Git hook",
Description: "This command should only be called by Git",
Action: runHookPreReceive,
Flags: []cli.Flag{
&cli.BoolFlag{
cli.BoolFlag{
Name: "debug",
},
},
}
subcmdHookUpdate = &cli.Command{
subcmdHookUpdate = cli.Command{
Name: "update",
Usage: "Delegate update Git hook",
Description: "This command should only be called by Git",
Action: runHookUpdate,
Flags: []cli.Flag{
&cli.BoolFlag{
cli.BoolFlag{
Name: "debug",
},
},
}
subcmdHookPostReceive = &cli.Command{
subcmdHookPostReceive = cli.Command{
Name: "post-receive",
Usage: "Delegate post-receive Git hook",
Description: "This command should only be called by Git",
Action: runHookPostReceive,
Flags: []cli.Flag{
&cli.BoolFlag{
cli.BoolFlag{
Name: "debug",
},
},
}
// Note: new hook since git 2.29
subcmdHookProcReceive = &cli.Command{
subcmdHookProcReceive = cli.Command{
Name: "proc-receive",
Usage: "Delegate proc-receive Git hook",
Description: "This command should only be called by Git",
Action: runHookProcReceive,
Flags: []cli.Flag{
&cli.BoolFlag{
cli.BoolFlag{
Name: "debug",
},
},
@ -142,7 +141,7 @@ func (d *delayWriter) Close() error {
if d == nil {
return nil
}
stopped := d.timer.Stop()
stopped := util.StopTimer(d.timer)
if stopped || d.buf == nil {
return nil
}
@ -168,11 +167,11 @@ func runHookPreReceive(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"))
setup("hooks/pre-receive.log", c.Bool("debug"))
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
return fail(ctx, `Rejecting changes as Gitea environment not set.
return fail(`Rejecting changes as Gitea environment not set.
If you are pushing over SSH you must push with a key managed by
Gitea or set your environment appropriately.`, "")
}
@ -203,7 +202,7 @@ Gitea or set your environment appropriately.`, "")
oldCommitIDs := make([]string, hookBatchSize)
newCommitIDs := make([]string, hookBatchSize)
refFullNames := make([]git.RefName, hookBatchSize)
refFullNames := make([]string, hookBatchSize)
count := 0
total := 0
lastline := 0
@ -238,14 +237,14 @@ Gitea or set your environment appropriately.`, "")
oldCommitID := string(fields[0])
newCommitID := string(fields[1])
refFullName := git.RefName(fields[2])
refFullName := string(fields[2])
total++
lastline++
// 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() {
if supportProcReceive || strings.HasPrefix(refFullName, git.BranchPrefix) || strings.HasPrefix(refFullName, git.TagPrefix) {
oldCommitIDs[count] = oldCommitID
newCommitIDs[count] = newCommitID
refFullNames[count] = refFullName
@ -258,9 +257,14 @@ Gitea or set your environment appropriately.`, "")
hookOptions.OldCommitIDs = oldCommitIDs
hookOptions.NewCommitIDs = newCommitIDs
hookOptions.RefFullNames = refFullNames
extra := private.HookPreReceive(ctx, username, reponame, hookOptions)
if extra.HasError() {
return fail(ctx, extra.UserMsg, "HookPreReceive(batch) failed: %v", extra.Error)
statusCode, msg := private.HookPreReceive(ctx, username, reponame, hookOptions)
switch statusCode {
case http.StatusOK:
// no-op
case http.StatusInternalServerError:
return fail("Internal Server Error", msg)
default:
return fail(msg, "")
}
count = 0
lastline = 0
@ -281,9 +285,12 @@ Gitea or set your environment appropriately.`, "")
fmt.Fprintf(out, " Checking %d references\n", count)
extra := private.HookPreReceive(ctx, username, reponame, hookOptions)
if extra.HasError() {
return fail(ctx, extra.UserMsg, "HookPreReceive(last) failed: %v", extra.Error)
statusCode, msg := private.HookPreReceive(ctx, username, reponame, hookOptions)
switch statusCode {
case http.StatusInternalServerError:
return fail("Internal Server Error", msg)
case http.StatusForbidden:
return fail(msg, "")
}
} else if lastline > 0 {
fmt.Fprintf(out, "\n")
@ -302,7 +309,7 @@ func runHookPostReceive(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"))
setup("hooks/post-receive.log", 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 {
@ -316,7 +323,7 @@ func runHookPostReceive(c *cli.Context) error {
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
return fail(ctx, `Rejecting changes as Gitea environment not set.
return fail(`Rejecting changes as Gitea environment not set.
If you are pushing over SSH you must push with a key managed by
Gitea or set your environment appropriately.`, "")
}
@ -353,7 +360,7 @@ Gitea or set your environment appropriately.`, "")
}
oldCommitIDs := make([]string, hookBatchSize)
newCommitIDs := make([]string, hookBatchSize)
refFullNames := make([]git.RefName, hookBatchSize)
refFullNames := make([]string, hookBatchSize)
count := 0
total := 0
wasEmpty := false
@ -375,10 +382,8 @@ Gitea or set your environment appropriately.`, "")
fmt.Fprintf(out, ".")
oldCommitIDs[count] = string(fields[0])
newCommitIDs[count] = string(fields[1])
refFullNames[count] = git.RefName(fields[2])
commitID, _ := git.NewIDFromString(newCommitIDs[count])
if refFullNames[count] == git.BranchPrefix+"master" && !commitID.IsZero() && count == total {
refFullNames[count] = string(fields[2])
if refFullNames[count] == git.BranchPrefix+"master" && newCommitIDs[count] != git.EmptySHA && count == total {
masterPushed = true
}
count++
@ -389,11 +394,11 @@ Gitea or set your environment appropriately.`, "")
hookOptions.OldCommitIDs = oldCommitIDs
hookOptions.NewCommitIDs = newCommitIDs
hookOptions.RefFullNames = refFullNames
resp, extra := private.HookPostReceive(ctx, repoUser, repoName, hookOptions)
if extra.HasError() {
resp, err := private.HookPostReceive(ctx, repoUser, repoName, hookOptions)
if resp == nil {
_ = dWriter.Close()
hookPrintResults(results)
return fail(ctx, extra.UserMsg, "HookPostReceive failed: %v", extra.Error)
return fail("Internal Server Error", err)
}
wasEmpty = wasEmpty || resp.RepoWasEmpty
results = append(results, resp.Results...)
@ -404,9 +409,9 @@ Gitea or set your environment appropriately.`, "")
if count == 0 {
if wasEmpty && masterPushed {
// We need to tell the repo to reset the default branch to master
extra := private.SetDefaultBranch(ctx, repoUser, repoName, "master")
if extra.HasError() {
return fail(ctx, extra.UserMsg, "SetDefaultBranch failed: %v", extra.Error)
err := private.SetDefaultBranch(ctx, repoUser, repoName, "master")
if err != nil {
return fail("Internal Server Error", "SetDefaultBranch failed with Error: %v", err)
}
}
fmt.Fprintf(out, "Processed %d references in total\n", total)
@ -422,11 +427,11 @@ Gitea or set your environment appropriately.`, "")
fmt.Fprintf(out, " Processing %d references\n", count)
resp, extra := private.HookPostReceive(ctx, repoUser, repoName, hookOptions)
resp, err := private.HookPostReceive(ctx, repoUser, repoName, hookOptions)
if resp == nil {
_ = dWriter.Close()
hookPrintResults(results)
return fail(ctx, extra.UserMsg, "HookPostReceive failed: %v", extra.Error)
return fail("Internal Server Error", err)
}
wasEmpty = wasEmpty || resp.RepoWasEmpty
results = append(results, resp.Results...)
@ -435,9 +440,9 @@ Gitea or set your environment appropriately.`, "")
if wasEmpty && masterPushed {
// We need to tell the repo to reset the default branch to master
extra := private.SetDefaultBranch(ctx, repoUser, repoName, "master")
if extra.HasError() {
return fail(ctx, extra.UserMsg, "SetDefaultBranch failed: %v", extra.Error)
err := private.SetDefaultBranch(ctx, repoUser, repoName, "master")
if err != nil {
return fail("Internal Server Error", "SetDefaultBranch failed with Error: %v", err)
}
}
_ = dWriter.Close()
@ -480,22 +485,22 @@ func pushOptions() map[string]string {
}
func runHookProcReceive(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"))
setup("hooks/proc-receive.log", c.Bool("debug"))
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
return fail(ctx, `Rejecting changes as Gitea environment not set.
return fail(`Rejecting changes as Gitea environment not set.
If you are pushing over SSH you must push with a key managed by
Gitea or set your environment appropriately.`, "")
}
return nil
}
ctx, cancel := installSignals()
defer cancel()
if git.CheckGitVersionAtLeast("2.29") != nil {
return fail(ctx, "No proc-receive support", "current git version doesn't support proc-receive.")
return fail("Internal Server Error", "git not support proc-receive.")
}
reader := bufio.NewReader(os.Stdin)
@ -510,7 +515,7 @@ Gitea or set your environment appropriately.`, "")
// H: PKT-LINE(version=1\0push-options...)
// H: flush-pkt
rs, err := readPktLine(ctx, reader, pktLineTypeData)
rs, err := readPktLine(reader, pktLineTypeData)
if err != nil {
return err
}
@ -525,19 +530,19 @@ Gitea or set your environment appropriately.`, "")
index := bytes.IndexByte(rs.Data, byte(0))
if index >= len(rs.Data) {
return fail(ctx, "Protocol: format error", "pkt-line: format error "+fmt.Sprint(rs.Data))
return fail("Internal Server Error", "pkt-line: format error "+fmt.Sprint(rs.Data))
}
if index < 0 {
if len(rs.Data) == 10 && rs.Data[9] == '\n' {
index = 9
} else {
return fail(ctx, "Protocol: format error", "pkt-line: format error "+fmt.Sprint(rs.Data))
return fail("Internal Server Error", "pkt-line: format error "+fmt.Sprint(rs.Data))
}
}
if string(rs.Data[0:index]) != VersionHead {
return fail(ctx, "Protocol: version error", "Received unsupported version: %s", string(rs.Data[0:index]))
return fail("Internal Server Error", "Received unsupported version: %s", string(rs.Data[0:index]))
}
requestOptions = strings.Split(string(rs.Data[index+1:]), " ")
@ -550,17 +555,17 @@ Gitea or set your environment appropriately.`, "")
}
response = append(response, '\n')
_, err = readPktLine(ctx, reader, pktLineTypeFlush)
_, err = readPktLine(reader, pktLineTypeFlush)
if err != nil {
return err
}
err = writeDataPktLine(ctx, os.Stdout, response)
err = writeDataPktLine(os.Stdout, response)
if err != nil {
return err
}
err = writeFlushPktLine(ctx, os.Stdout)
err = writeFlushPktLine(os.Stdout)
if err != nil {
return err
}
@ -579,11 +584,11 @@ Gitea or set your environment appropriately.`, "")
}
hookOptions.OldCommitIDs = make([]string, 0, hookBatchSize)
hookOptions.NewCommitIDs = make([]string, 0, hookBatchSize)
hookOptions.RefFullNames = make([]git.RefName, 0, hookBatchSize)
hookOptions.RefFullNames = make([]string, 0, hookBatchSize)
for {
// note: pktLineTypeUnknow means pktLineTypeFlush and pktLineTypeData all allowed
rs, err = readPktLine(ctx, reader, pktLineTypeUnknow)
rs, err = readPktLine(reader, pktLineTypeUnknow)
if err != nil {
return err
}
@ -597,14 +602,14 @@ Gitea or set your environment appropriately.`, "")
}
hookOptions.OldCommitIDs = append(hookOptions.OldCommitIDs, t[0])
hookOptions.NewCommitIDs = append(hookOptions.NewCommitIDs, t[1])
hookOptions.RefFullNames = append(hookOptions.RefFullNames, git.RefName(t[2]))
hookOptions.RefFullNames = append(hookOptions.RefFullNames, t[2])
}
hookOptions.GitPushOptions = make(map[string]string)
if hasPushOptions {
for {
rs, err = readPktLine(ctx, reader, pktLineTypeUnknow)
rs, err = readPktLine(reader, pktLineTypeUnknow)
if err != nil {
return err
}
@ -621,9 +626,9 @@ Gitea or set your environment appropriately.`, "")
}
// 3. run hook
resp, extra := private.HookProcReceive(ctx, repoUser, repoName, hookOptions)
if extra.HasError() {
return fail(ctx, extra.UserMsg, "HookProcReceive failed: %v", extra.Error)
resp, err := private.HookProcReceive(ctx, repoUser, repoName, hookOptions)
if err != nil {
return fail("Internal Server Error", "run proc-receive hook failed :%v", err)
}
// 4. response result to service
@ -644,7 +649,7 @@ Gitea or set your environment appropriately.`, "")
for _, rs := range resp.Results {
if len(rs.Err) > 0 {
err = writeDataPktLine(ctx, os.Stdout, []byte("ng "+rs.OriginalRef.String()+" "+rs.Err))
err = writeDataPktLine(os.Stdout, []byte("ng "+rs.OriginalRef+" "+rs.Err))
if err != nil {
return err
}
@ -652,44 +657,43 @@ Gitea or set your environment appropriately.`, "")
}
if rs.IsNotMatched {
err = writeDataPktLine(ctx, os.Stdout, []byte("ok "+rs.OriginalRef.String()))
err = writeDataPktLine(os.Stdout, []byte("ok "+rs.OriginalRef))
if err != nil {
return err
}
err = writeDataPktLine(ctx, os.Stdout, []byte("option fall-through"))
err = writeDataPktLine(os.Stdout, []byte("option fall-through"))
if err != nil {
return err
}
continue
}
err = writeDataPktLine(ctx, os.Stdout, []byte("ok "+rs.OriginalRef))
err = writeDataPktLine(os.Stdout, []byte("ok "+rs.OriginalRef))
if err != nil {
return err
}
err = writeDataPktLine(ctx, os.Stdout, []byte("option refname "+rs.Ref))
err = writeDataPktLine(os.Stdout, []byte("option refname "+rs.Ref))
if err != nil {
return err
}
commitID, _ := git.NewIDFromString(rs.OldOID)
if !commitID.IsZero() {
err = writeDataPktLine(ctx, os.Stdout, []byte("option old-oid "+rs.OldOID))
if rs.OldOID != git.EmptySHA {
err = writeDataPktLine(os.Stdout, []byte("option old-oid "+rs.OldOID))
if err != nil {
return err
}
}
err = writeDataPktLine(ctx, os.Stdout, []byte("option new-oid "+rs.NewOID))
err = writeDataPktLine(os.Stdout, []byte("option new-oid "+rs.NewOID))
if err != nil {
return err
}
if rs.IsForcePush {
err = writeDataPktLine(ctx, os.Stdout, []byte("option forced-update"))
err = writeDataPktLine(os.Stdout, []byte("option forced-update"))
if err != nil {
return err
}
}
}
err = writeFlushPktLine(ctx, os.Stdout)
err = writeFlushPktLine(os.Stdout)
return err
}
@ -714,7 +718,7 @@ type gitPktLine struct {
Data []byte
}
func readPktLine(ctx context.Context, in *bufio.Reader, requestType pktLineType) (*gitPktLine, error) {
func readPktLine(in *bufio.Reader, requestType pktLineType) (*gitPktLine, error) {
var (
err error
r *gitPktLine
@ -725,33 +729,33 @@ func readPktLine(ctx context.Context, in *bufio.Reader, requestType pktLineType)
for i := 0; i < 4; i++ {
lengthBytes[i], err = in.ReadByte()
if err != nil {
return nil, fail(ctx, "Protocol: stdin error", "Pkt-Line: read stdin failed : %v", err)
return nil, fail("Internal Server Error", "Pkt-Line: read stdin failed : %v", err)
}
}
r = new(gitPktLine)
r.Length, err = strconv.ParseUint(string(lengthBytes), 16, 32)
if err != nil {
return nil, fail(ctx, "Protocol: format parse error", "Pkt-Line format is wrong :%v", err)
return nil, fail("Internal Server Error", "Pkt-Line format is wrong :%v", err)
}
if r.Length == 0 {
if requestType == pktLineTypeData {
return nil, fail(ctx, "Protocol: format data error", "Pkt-Line format is wrong")
return nil, fail("Internal Server Error", "Pkt-Line format is wrong")
}
r.Type = pktLineTypeFlush
return r, nil
}
if r.Length <= 4 || r.Length > 65520 || requestType == pktLineTypeFlush {
return nil, fail(ctx, "Protocol: format length error", "Pkt-Line format is wrong")
return nil, fail("Internal Server Error", "Pkt-Line format is wrong")
}
r.Data = make([]byte, r.Length-4)
for i := range r.Data {
r.Data[i], err = in.ReadByte()
if err != nil {
return nil, fail(ctx, "Protocol: data error", "Pkt-Line: read stdin failed : %v", err)
return nil, fail("Internal Server Error", "Pkt-Line: read stdin failed : %v", err)
}
}
@ -760,15 +764,19 @@ func readPktLine(ctx context.Context, in *bufio.Reader, requestType pktLineType)
return r, nil
}
func writeFlushPktLine(ctx context.Context, out io.Writer) error {
func writeFlushPktLine(out io.Writer) error {
l, err := out.Write([]byte("0000"))
if err != nil || l != 4 {
return fail(ctx, "Protocol: write error", "Pkt-Line response failed: %v", err)
if err != nil {
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
}
if l != 4 {
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
}
return nil
}
func writeDataPktLine(ctx context.Context, out io.Writer, data []byte) error {
func writeDataPktLine(out io.Writer, data []byte) error {
hexchar := []byte("0123456789abcdef")
hex := func(n uint64) byte {
return hexchar[(n)&15]
@ -782,13 +790,19 @@ func writeDataPktLine(ctx context.Context, out io.Writer, data []byte) error {
tmp[3] = hex(length)
lr, err := out.Write(tmp)
if err != nil || lr != 4 {
return fail(ctx, "Protocol: write error", "Pkt-Line response failed: %v", err)
if err != nil {
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
}
if lr != 4 {
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
}
lr, err = out.Write(data)
if err != nil || int(length-4) != lr {
return fail(ctx, "Protocol: write error", "Pkt-Line response failed: %v", err)
if err != nil {
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
}
if int(length-4) != lr {
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
}
return nil

View File

@ -6,7 +6,6 @@ package cmd
import (
"bufio"
"bytes"
"context"
"strings"
"testing"
@ -15,28 +14,27 @@ import (
func TestPktLine(t *testing.T) {
// test read
ctx := context.Background()
s := strings.NewReader("0000")
r := bufio.NewReader(s)
result, err := readPktLine(ctx, r, pktLineTypeFlush)
result, err := readPktLine(r, pktLineTypeFlush)
assert.NoError(t, err)
assert.Equal(t, pktLineTypeFlush, result.Type)
s = strings.NewReader("0006a\n")
r = bufio.NewReader(s)
result, err = readPktLine(ctx, r, pktLineTypeData)
result, err = readPktLine(r, pktLineTypeData)
assert.NoError(t, err)
assert.Equal(t, pktLineTypeData, result.Type)
assert.Equal(t, []byte("a\n"), result.Data)
// test write
w := bytes.NewBuffer([]byte{})
err = writeFlushPktLine(ctx, w)
err = writeFlushPktLine(w)
assert.NoError(t, err)
assert.Equal(t, []byte("0000"), w.Bytes())
w.Reset()
err = writeDataPktLine(ctx, w, []byte("a\nb"))
err = writeDataPktLine(w, []byte("a\nb"))
assert.NoError(t, err)
assert.Equal(t, []byte("0007a\nb"), w.Bytes())
}

View File

@ -8,43 +8,36 @@ import (
"fmt"
"strings"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/private"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
// CmdKeys represents the available keys sub-command
var CmdKeys = &cli.Command{
Name: "keys",
Usage: "(internal) Should only be called by SSH server",
Description: "Queries the Gitea database to get the authorized command for a given ssh key fingerprint",
Before: PrepareConsoleLoggerLevel(log.FATAL),
Action: runKeys,
var CmdKeys = cli.Command{
Name: "keys",
Usage: "This command queries the Gitea database to get the authorized command for a given ssh key fingerprint",
Action: runKeys,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "expected",
Aliases: []string{"e"},
Value: "git",
Usage: "Expected user for whom provide key commands",
cli.StringFlag{
Name: "expected, e",
Value: "git",
Usage: "Expected user for whom provide key commands",
},
&cli.StringFlag{
Name: "username",
Aliases: []string{"u"},
Value: "",
Usage: "Username trying to log in by SSH",
cli.StringFlag{
Name: "username, u",
Value: "",
Usage: "Username trying to log in by SSH",
},
&cli.StringFlag{
Name: "type",
Aliases: []string{"t"},
Value: "",
Usage: "Type of the SSH key provided to the SSH Server (requires content to be provided too)",
cli.StringFlag{
Name: "type, t",
Value: "",
Usage: "Type of the SSH key provided to the SSH Server (requires content to be provided too)",
},
&cli.StringFlag{
Name: "content",
Aliases: []string{"k"},
Value: "",
Usage: "Base64 encoded content of the SSH key provided to the SSH Server (requires type to be provided too)",
cli.StringFlag{
Name: "content, k",
Value: "",
Usage: "Base64 encoded content of the SSH key provided to the SSH Server (requires type to be provided too)",
},
},
}
@ -71,13 +64,12 @@ func runKeys(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"))
setup("keys.log", false)
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
authorizedString, err := private.AuthorizedPublicKeyByContent(ctx, content)
if err != nil {
return err
}
_, _ = fmt.Fprintln(c.App.Writer, strings.TrimSpace(authorizedString.Text))
fmt.Println(strings.TrimSpace(authorizedString))
return nil
}

View File

@ -5,18 +5,20 @@ package cmd
import (
"fmt"
"net/http"
"code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
func runSendMail(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setting.MustInstalled()
setting.InitProviderFromExistingFile()
setting.LoadCommonSettings()
if err := argsSet(c, "title"); err != nil {
return err
@ -41,10 +43,13 @@ func runSendMail(c *cli.Context) error {
}
}
respText, extra := private.SendEmail(ctx, subject, body, nil)
if extra.HasError() {
return handleCliResponseExtra(extra)
status, message := private.SendEmail(ctx, subject, body, nil)
if status != http.StatusOK {
fmt.Printf("error: %s\n", message)
return nil
}
_, _ = fmt.Printf("Sent %s email(s) to all users\n", respText.Text)
fmt.Printf("Success: %s\n", message)
return nil
}

View File

@ -1,179 +0,0 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"fmt"
"os"
"strings"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli/v2"
)
// cmdHelp is our own help subcommand with more information
// Keep in mind that the "./gitea help"(subcommand) is different from "./gitea --help"(flag), the flag doesn't parse the config or output "DEFAULT CONFIGURATION:" information
func cmdHelp() *cli.Command {
c := &cli.Command{
Name: "help",
Aliases: []string{"h"},
Usage: "Shows a list of commands or help for one command",
ArgsUsage: "[command]",
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.Command.Name == "help" {
targetCmdIdx = 1
}
if lineage[targetCmdIdx+1].Command != nil {
err = cli.ShowCommandHelp(lineage[targetCmdIdx+1], lineage[targetCmdIdx].Command.Name)
} else {
err = cli.ShowAppHelp(c)
}
_, _ = fmt.Fprintf(c.App.Writer, `
DEFAULT CONFIGURATION:
AppPath: %s
WorkPath: %s
CustomPath: %s
ConfigFile: %s
`, setting.AppPath, setting.AppWorkPath, setting.CustomPath, setting.CustomConf)
return err
},
}
return c
}
func appGlobalFlags() []cli.Flag {
return []cli.Flag{
// make the builtin flags at the top
cli.HelpFlag,
// shared configuration flags, they are for global and for each sub-command at the same time
// eg: such command is valid: "./gitea --config /tmp/app.ini web --config /tmp/app.ini", while it's discouraged indeed
// keep in mind that the short flags like "-C", "-c" and "-w" are globally polluted, they can't be used for sub-commands anymore.
&cli.StringFlag{
Name: "custom-path",
Aliases: []string{"C"},
Usage: "Set custom path (defaults to '{WorkPath}/custom')",
},
&cli.StringFlag{
Name: "config",
Aliases: []string{"c"},
Value: setting.CustomConf,
Usage: "Set custom config file (defaults to '{WorkPath}/custom/conf/app.ini')",
},
&cli.StringFlag{
Name: "work-path",
Aliases: []string{"w"},
Usage: "Set Gitea's working path (defaults to the Gitea's binary directory)",
},
}
}
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.Subcommands = append(command.Subcommands, cmdHelp())
}
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(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 ctx.Lineage() {
if curCtx.IsSet("work-path") && args.WorkPath == "" {
args.WorkPath = curCtx.String("work-path")
}
if curCtx.IsSet("custom-path") && args.CustomPath == "" {
args.CustomPath = curCtx.String("custom-path")
}
if curCtx.IsSet("config") && args.CustomConf == "" {
args.CustomConf = curCtx.String("config")
}
}
setting.InitWorkPathAndCommonConfig(os.Getenv, args)
if ctx.Bool("help") || action == nil {
// the default behavior of "urfave/cli": "nil action" means "show help"
return cmdHelp().Action(ctx)
}
return action(ctx)
}
}
func NewMainApp(version, versionExtra string) *cli.App {
app := cli.NewApp()
app.Name = "Gitea"
app.HelpName = "gitea"
app.Usage = "A painless self-hosted Git service"
app.Description = `Gitea program contains "web" and other subcommands. If no subcommand is given, it starts the web server by default. Use "web" subcommand for more web server arguments, use other subcommands for other purposes.`
app.Version = version + versionExtra
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,
CmdActions,
}
// 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,
CmdDocs,
}
app.DefaultCommand = CmdWeb.Name
globalFlags := appGlobalFlags()
app.Flags = append(app.Flags, cli.VersionFlag)
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 {
prepareSubcommandWithConfig(subCmdWithConfig[i], globalFlags)
}
app.Commands = append(app.Commands, subCmdWithConfig...)
app.Commands = append(app.Commands, subCmdStandalone...)
return app
}
func RunMainApp(app *cli.App, args ...string) error {
err := app.Run(args)
if err == nil {
return nil
}
if strings.HasPrefix(err.Error(), "flag provided but not defined:") {
// the cli package should already have output the error message, so just exit
cli.OsExiter(1)
return err
}
_, _ = fmt.Fprintf(app.ErrWriter, "Command error: %v\n", err)
cli.OsExiter(1)
return err
}

View File

@ -4,175 +4,19 @@
package cmd
import (
"fmt"
"io"
"os"
"path/filepath"
"strings"
"testing"
"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/urfave/cli/v2"
)
func init() {
setting.SetCustomPathAndConf("", "", "")
setting.InitProviderAndLoadCommonSettingsForTest()
}
func TestMain(m *testing.M) {
unittest.MainTest(m)
}
func makePathOutput(workPath, customPath, customConf string) string {
return fmt.Sprintf("WorkPath=%s\nCustomPath=%s\nCustomConf=%s", workPath, customPath, customConf)
}
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())
app.Commands = append(app.Commands, testCmd)
app.DefaultCommand = testCmd.Name
return app
}
type runResult struct {
Stdout string
Stderr string
ExitCode int
}
func runTestApp(app *cli.App, args ...string) (runResult, error) {
outBuf := new(strings.Builder)
errBuf := new(strings.Builder)
app.Writer = outBuf
app.ErrWriter = errBuf
exitCode := -1
defer test.MockVariableValue(&cli.ErrWriter, app.ErrWriter)()
defer test.MockVariableValue(&cli.OsExiter, func(code int) {
if exitCode == -1 {
exitCode = code // save the exit code once and then reset the writer (to simulate the exit)
app.Writer, app.ErrWriter, cli.ErrWriter = io.Discard, io.Discard, io.Discard
}
})()
err := RunMainApp(app, args...)
return runResult{outBuf.String(), errBuf.String(), exitCode}, err
}
func TestCliCmd(t *testing.T) {
defaultWorkPath := filepath.Dir(setting.AppPath)
defaultCustomPath := filepath.Join(defaultWorkPath, "custom")
defaultCustomConf := filepath.Join(defaultCustomPath, "conf/app.ini")
cli.CommandHelpTemplate = "(command help template)"
cli.AppHelpTemplate = "(app help template)"
cli.SubcommandHelpTemplate = "(subcommand help template)"
cases := []struct {
env map[string]string
cmd string
exp string
}{
// main command help
{
cmd: "./gitea help",
exp: "DEFAULT CONFIGURATION:",
},
// parse paths
{
cmd: "./gitea test-cmd",
exp: makePathOutput(defaultWorkPath, defaultCustomPath, defaultCustomConf),
},
{
cmd: "./gitea -c /tmp/app.ini test-cmd",
exp: makePathOutput(defaultWorkPath, defaultCustomPath, "/tmp/app.ini"),
},
{
cmd: "./gitea test-cmd -c /tmp/app.ini",
exp: makePathOutput(defaultWorkPath, defaultCustomPath, "/tmp/app.ini"),
},
{
env: map[string]string{"GITEA_WORK_DIR": "/tmp"},
cmd: "./gitea test-cmd",
exp: makePathOutput("/tmp", "/tmp/custom", "/tmp/custom/conf/app.ini"),
},
{
env: map[string]string{"GITEA_WORK_DIR": "/tmp"},
cmd: "./gitea test-cmd --work-path /tmp/other",
exp: makePathOutput("/tmp/other", "/tmp/other/custom", "/tmp/other/custom/conf/app.ini"),
},
{
env: map[string]string{"GITEA_WORK_DIR": "/tmp"},
cmd: "./gitea test-cmd --config /tmp/app-other.ini",
exp: makePathOutput("/tmp", "/tmp/custom", "/tmp/app-other.ini"),
},
}
app := newTestApp(func(ctx *cli.Context) error {
_, _ = fmt.Fprint(ctx.App.Writer, makePathOutput(setting.AppWorkPath, setting.CustomPath, setting.CustomConf))
return nil
unittest.MainTest(m, &unittest.TestOptions{
GiteaRootPath: "..",
})
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 {
_ = os.Setenv(k, v)
}
args := strings.Split(c.cmd, " ") // for test only, "split" is good enough
r, err := runTestApp(app, args...)
assert.NoError(t, err, c.cmd)
assert.NotEmpty(t, c.exp, c.cmd)
assert.Contains(t, r.Stdout, c.exp, c.cmd)
}
}
func TestCliCmdError(t *testing.T) {
app := newTestApp(func(ctx *cli.Context) error { return fmt.Errorf("normal error") })
r, err := runTestApp(app, "./gitea", "test-cmd")
assert.Error(t, err)
assert.Equal(t, 1, r.ExitCode)
assert.Equal(t, "", r.Stdout)
assert.Equal(t, "Command error: normal error\n", r.Stderr)
app = newTestApp(func(ctx *cli.Context) error { return cli.Exit("exit error", 2) })
r, err = runTestApp(app, "./gitea", "test-cmd")
assert.Error(t, err)
assert.Equal(t, 2, r.ExitCode)
assert.Equal(t, "", r.Stdout)
assert.Equal(t, "exit error\n", r.Stderr)
app = newTestApp(func(ctx *cli.Context) error { return nil })
r, err = runTestApp(app, "./gitea", "test-cmd", "--no-such")
assert.Error(t, err)
assert.Equal(t, 1, r.ExitCode)
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(ctx *cli.Context) error { return nil })
r, err = runTestApp(app, "./gitea", "test-cmd")
assert.NoError(t, err)
assert.Equal(t, -1, r.ExitCode) // the cli.OsExiter is not called
assert.Equal(t, "", r.Stdout)
assert.Equal(t, "", r.Stderr)
}

View File

@ -4,103 +4,94 @@
package cmd
import (
"fmt"
"net/http"
"os"
"time"
"code.gitea.io/gitea/modules/private"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
var (
// CmdManager represents the manager command
CmdManager = &cli.Command{
CmdManager = cli.Command{
Name: "manager",
Usage: "Manage the running gitea process",
Description: "This is a command for managing the running gitea process",
Subcommands: []*cli.Command{
Subcommands: []cli.Command{
subcmdShutdown,
subcmdRestart,
subcmdReloadTemplates,
subcmdFlushQueues,
subcmdLogging,
subCmdProcesses,
},
}
subcmdShutdown = &cli.Command{
subcmdShutdown = cli.Command{
Name: "shutdown",
Usage: "Gracefully shutdown the running process",
Flags: []cli.Flag{
&cli.BoolFlag{
cli.BoolFlag{
Name: "debug",
},
},
Action: runShutdown,
}
subcmdRestart = &cli.Command{
subcmdRestart = cli.Command{
Name: "restart",
Usage: "Gracefully restart the running process - (not implemented for windows servers)",
Flags: []cli.Flag{
&cli.BoolFlag{
cli.BoolFlag{
Name: "debug",
},
},
Action: runRestart,
}
subcmdReloadTemplates = &cli.Command{
Name: "reload-templates",
Usage: "Reload template files in the running process",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "debug",
},
},
Action: runReloadTemplates,
}
subcmdFlushQueues = &cli.Command{
subcmdFlushQueues = cli.Command{
Name: "flush-queues",
Usage: "Flush queues in the running process",
Action: runFlushQueues,
Flags: []cli.Flag{
&cli.DurationFlag{
cli.DurationFlag{
Name: "timeout",
Value: 60 * time.Second,
Usage: "Timeout for the flushing process",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "non-blocking",
Usage: "Set to true to not wait for flush to complete before returning",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "debug",
},
},
}
subCmdProcesses = &cli.Command{
subCmdProcesses = cli.Command{
Name: "processes",
Usage: "Display running processes within the current process",
Action: runProcesses,
Flags: []cli.Flag{
&cli.BoolFlag{
cli.BoolFlag{
Name: "debug",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "flat",
Usage: "Show processes as flat table rather than as tree",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "no-system",
Usage: "Do not show system processes",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "stacktraces",
Usage: "Show stacktraces",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "json",
Usage: "Output as json",
},
&cli.StringFlag{
cli.StringFlag{
Name: "cancel",
Usage: "Process PID to cancel. (Only available for non-system processes.)",
},
@ -112,43 +103,57 @@ func runShutdown(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"))
extra := private.Shutdown(ctx)
return handleCliResponseExtra(extra)
setup("manager", c.Bool("debug"))
statusCode, msg := private.Shutdown(ctx)
switch statusCode {
case http.StatusInternalServerError:
return fail("InternalServerError", msg)
}
fmt.Fprintln(os.Stdout, msg)
return nil
}
func runRestart(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"))
extra := private.Restart(ctx)
return handleCliResponseExtra(extra)
}
setup("manager", c.Bool("debug"))
statusCode, msg := private.Restart(ctx)
switch statusCode {
case http.StatusInternalServerError:
return fail("InternalServerError", msg)
}
func runReloadTemplates(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"))
extra := private.ReloadTemplates(ctx)
return handleCliResponseExtra(extra)
fmt.Fprintln(os.Stdout, msg)
return nil
}
func runFlushQueues(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"))
extra := private.FlushQueues(ctx, c.Duration("timeout"), c.Bool("non-blocking"))
return handleCliResponseExtra(extra)
setup("manager", c.Bool("debug"))
statusCode, msg := private.FlushQueues(ctx, c.Duration("timeout"), c.Bool("non-blocking"))
switch statusCode {
case http.StatusInternalServerError:
return fail("InternalServerError", msg)
}
fmt.Fprintln(os.Stdout, msg)
return nil
}
func runProcesses(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
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)
setup("manager", c.Bool("debug"))
statusCode, msg := private.Processes(ctx, os.Stdout, c.Bool("flat"), c.Bool("no-system"), c.Bool("stacktraces"), c.Bool("json"), c.String("cancel"))
switch statusCode {
case http.StatusInternalServerError:
return fail("InternalServerError", msg)
}
return nil
}

View File

@ -5,66 +5,55 @@ package cmd
import (
"fmt"
"net/http"
"os"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/private"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
var (
defaultLoggingFlags = []cli.Flag{
&cli.StringFlag{
Name: "logger",
Usage: `Logger name - will default to "default"`,
},
&cli.StringFlag{
Name: "writer",
Usage: "Name of the log writer - will default to mode",
},
&cli.StringFlag{
Name: "level",
cli.StringFlag{
Name: "group, g",
Usage: "Group to add logger to - will default to \"default\"",
}, cli.StringFlag{
Name: "name, n",
Usage: "Name of the new logger - will default to mode",
}, cli.StringFlag{
Name: "level, l",
Usage: "Logging level for the new logger",
},
&cli.StringFlag{
Name: "stacktrace-level",
Aliases: []string{"L"},
Usage: "Stacktrace logging level",
},
&cli.StringFlag{
Name: "flags",
Aliases: []string{"F"},
Usage: "Flags for the logger",
},
&cli.StringFlag{
Name: "expression",
Aliases: []string{"e"},
Usage: "Matching expression for the logger",
},
&cli.StringFlag{
Name: "prefix",
Aliases: []string{"p"},
Usage: "Prefix for the logger",
},
&cli.BoolFlag{
}, cli.StringFlag{
Name: "stacktrace-level, L",
Usage: "Stacktrace logging level",
}, cli.StringFlag{
Name: "flags, F",
Usage: "Flags for the logger",
}, cli.StringFlag{
Name: "expression, e",
Usage: "Matching expression for the logger",
}, cli.StringFlag{
Name: "prefix, p",
Usage: "Prefix for the logger",
}, cli.BoolFlag{
Name: "color",
Usage: "Use color in the logs",
},
&cli.BoolFlag{
}, cli.BoolFlag{
Name: "debug",
},
}
subcmdLogging = &cli.Command{
subcmdLogging = cli.Command{
Name: "logging",
Usage: "Adjust logging commands",
Subcommands: []*cli.Command{
Subcommands: []cli.Command{
{
Name: "pause",
Usage: "Pause logging (Gitea will buffer logs up to a certain point and will drop them after that point)",
Flags: []cli.Flag{
&cli.BoolFlag{
cli.BoolFlag{
Name: "debug",
},
},
@ -73,7 +62,7 @@ var (
Name: "resume",
Usage: "Resume logging",
Flags: []cli.Flag{
&cli.BoolFlag{
cli.BoolFlag{
Name: "debug",
},
},
@ -82,7 +71,7 @@ var (
Name: "release-and-reopen",
Usage: "Cause Gitea to release and re-open files used for logging",
Flags: []cli.Flag{
&cli.BoolFlag{
cli.BoolFlag{
Name: "debug",
},
},
@ -92,59 +81,52 @@ var (
Usage: "Remove a logger",
ArgsUsage: "[name] Name of logger to remove",
Flags: []cli.Flag{
&cli.BoolFlag{
cli.BoolFlag{
Name: "debug",
}, &cli.StringFlag{
Name: "logger",
Usage: `Logger name - will default to "default"`,
}, cli.StringFlag{
Name: "group, g",
Usage: "Group to add logger to - will default to \"default\"",
},
},
Action: runRemoveLogger,
}, {
Name: "add",
Usage: "Add a logger",
Subcommands: []*cli.Command{
Subcommands: []cli.Command{
{
Name: "console",
Usage: "Add a console logger",
Flags: append(defaultLoggingFlags,
cli.BoolFlag{
Name: "stderr",
Usage: "Output console logs to stderr - only relevant for console",
}),
Action: runAddConsoleLogger,
}, {
Name: "file",
Usage: "Add a file logger",
Flags: append(defaultLoggingFlags, []cli.Flag{
&cli.StringFlag{
Name: "filename",
Aliases: []string{"f"},
Usage: "Filename for the logger - this must be set.",
},
&cli.BoolFlag{
Name: "rotate",
Aliases: []string{"r"},
Usage: "Rotate logs",
Value: true,
},
&cli.Int64Flag{
Name: "max-size",
Aliases: []string{"s"},
Usage: "Maximum size in bytes before rotation",
},
&cli.BoolFlag{
Name: "daily",
Aliases: []string{"d"},
Usage: "Rotate logs daily",
Value: true,
},
&cli.IntFlag{
Name: "max-days",
Aliases: []string{"D"},
Usage: "Maximum number of daily logs to keep",
},
&cli.BoolFlag{
Name: "compress",
Aliases: []string{"z"},
Usage: "Compress rotated logs",
Value: true,
},
&cli.IntFlag{
Name: "compression-level",
Aliases: []string{"Z"},
Usage: "Compression level to use",
cli.StringFlag{
Name: "filename, f",
Usage: "Filename for the logger - this must be set.",
}, cli.BoolTFlag{
Name: "rotate, r",
Usage: "Rotate logs",
}, cli.Int64Flag{
Name: "max-size, s",
Usage: "Maximum size in bytes before rotation",
}, cli.BoolTFlag{
Name: "daily, d",
Usage: "Rotate logs daily",
}, cli.IntFlag{
Name: "max-days, D",
Usage: "Maximum number of daily logs to keep",
}, cli.BoolTFlag{
Name: "compress, z",
Usage: "Compress rotated logs",
}, cli.IntFlag{
Name: "compression-level, Z",
Usage: "Compression level to use",
},
}...),
Action: runAddFileLogger,
@ -152,38 +134,52 @@ var (
Name: "conn",
Usage: "Add a net conn logger",
Flags: append(defaultLoggingFlags, []cli.Flag{
&cli.BoolFlag{
Name: "reconnect-on-message",
Aliases: []string{"R"},
Usage: "Reconnect to host for every message",
},
&cli.BoolFlag{
Name: "reconnect",
Aliases: []string{"r"},
Usage: "Reconnect to host when connection is dropped",
},
&cli.StringFlag{
Name: "protocol",
Aliases: []string{"P"},
Usage: "Set protocol to use: tcp, unix, or udp (defaults to tcp)",
},
&cli.StringFlag{
Name: "address",
Aliases: []string{"a"},
Usage: "Host address and port to connect to (defaults to :7020)",
cli.BoolFlag{
Name: "reconnect-on-message, R",
Usage: "Reconnect to host for every message",
}, cli.BoolFlag{
Name: "reconnect, r",
Usage: "Reconnect to host when connection is dropped",
}, cli.StringFlag{
Name: "protocol, P",
Usage: "Set protocol to use: tcp, unix, or udp (defaults to tcp)",
}, cli.StringFlag{
Name: "address, a",
Usage: "Host address and port to connect to (defaults to :7020)",
},
}...),
Action: runAddConnLogger,
}, {
Name: "smtp",
Usage: "Add an SMTP logger",
Flags: append(defaultLoggingFlags, []cli.Flag{
cli.StringFlag{
Name: "username, u",
Usage: "Mail server username",
}, cli.StringFlag{
Name: "password, P",
Usage: "Mail server password",
}, cli.StringFlag{
Name: "host, H",
Usage: "Mail server host (defaults to: 127.0.0.1:25)",
}, cli.StringSliceFlag{
Name: "send-to, s",
Usage: "Email address(es) to send to",
}, cli.StringFlag{
Name: "subject, S",
Usage: "Subject header of sent emails",
},
}...),
Action: runAddSMTPLogger,
},
},
}, {
Name: "log-sql",
Usage: "Set LogSQL",
Flags: []cli.Flag{
&cli.BoolFlag{
cli.BoolFlag{
Name: "debug",
},
&cli.BoolFlag{
}, cli.BoolFlag{
Name: "off",
Usage: "Switch off SQL logging",
},
@ -195,26 +191,59 @@ var (
)
func runRemoveLogger(c *cli.Context) error {
setup("manager", c.Bool("debug"))
group := c.String("group")
if len(group) == 0 {
group = log.DEFAULT
}
name := c.Args().First()
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"))
logger := c.String("logger")
if len(logger) == 0 {
logger = log.DEFAULT
statusCode, msg := private.RemoveLogger(ctx, group, name)
switch statusCode {
case http.StatusInternalServerError:
return fail("InternalServerError", msg)
}
writer := c.Args().First()
extra := private.RemoveLogger(ctx, logger, writer)
return handleCliResponseExtra(extra)
fmt.Fprintln(os.Stdout, msg)
return nil
}
func runAddSMTPLogger(c *cli.Context) error {
setup("manager", c.Bool("debug"))
vals := map[string]interface{}{}
mode := "smtp"
if c.IsSet("host") {
vals["host"] = c.String("host")
} else {
vals["host"] = "127.0.0.1:25"
}
if c.IsSet("username") {
vals["username"] = c.String("username")
}
if c.IsSet("password") {
vals["password"] = c.String("password")
}
if !c.IsSet("send-to") {
return fmt.Errorf("Some recipients must be provided")
}
vals["sendTos"] = c.StringSlice("send-to")
if c.IsSet("subject") {
vals["subject"] = c.String("subject")
} else {
vals["subject"] = "Diagnostic message from Gitea"
}
return commonAddLogger(c, mode, vals)
}
func runAddConnLogger(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"))
vals := map[string]any{}
setup("manager", c.Bool("debug"))
vals := map[string]interface{}{}
mode := "conn"
vals["net"] = "tcp"
if c.IsSet("protocol") {
@ -240,11 +269,8 @@ func runAddConnLogger(c *cli.Context) error {
}
func runAddFileLogger(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"))
vals := map[string]any{}
setup("manager", c.Bool("debug"))
vals := map[string]interface{}{}
mode := "file"
if c.IsSet("filename") {
vals["filename"] = c.String("filename")
@ -272,12 +298,22 @@ func runAddFileLogger(c *cli.Context) error {
return commonAddLogger(c, mode, vals)
}
func commonAddLogger(c *cli.Context, mode string, vals map[string]any) error {
func runAddConsoleLogger(c *cli.Context) error {
setup("manager", c.Bool("debug"))
vals := map[string]interface{}{}
mode := "console"
if c.IsSet("stderr") && c.Bool("stderr") {
vals["stderr"] = c.Bool("stderr")
}
return commonAddLogger(c, mode, vals)
}
func commonAddLogger(c *cli.Context, mode string, vals map[string]interface{}) error {
if len(c.String("level")) > 0 {
vals["level"] = log.LevelFromString(c.String("level")).String()
vals["level"] = log.FromString(c.String("level")).String()
}
if len(c.String("stacktrace-level")) > 0 {
vals["stacktraceLevel"] = log.LevelFromString(c.String("stacktrace-level")).String()
vals["stacktraceLevel"] = log.FromString(c.String("stacktrace-level")).String()
}
if len(c.String("expression")) > 0 {
vals["expression"] = c.String("expression")
@ -291,28 +327,39 @@ func commonAddLogger(c *cli.Context, mode string, vals map[string]any) error {
if c.IsSet("color") {
vals["colorize"] = c.Bool("color")
}
logger := log.DEFAULT
if c.IsSet("logger") {
logger = c.String("logger")
group := "default"
if c.IsSet("group") {
group = c.String("group")
}
writer := mode
if c.IsSet("writer") {
writer = c.String("writer")
name := mode
if c.IsSet("name") {
name = c.String("name")
}
ctx, cancel := installSignals()
defer cancel()
extra := private.AddLogger(ctx, logger, writer, mode, vals)
return handleCliResponseExtra(extra)
statusCode, msg := private.AddLogger(ctx, group, name, mode, vals)
switch statusCode {
case http.StatusInternalServerError:
return fail("InternalServerError", msg)
}
fmt.Fprintln(os.Stdout, msg)
return nil
}
func runPauseLogging(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"))
userMsg := private.PauseLogging(ctx)
_, _ = fmt.Fprintln(os.Stdout, userMsg)
setup("manager", c.Bool("debug"))
statusCode, msg := private.PauseLogging(ctx)
switch statusCode {
case http.StatusInternalServerError:
return fail("InternalServerError", msg)
}
fmt.Fprintln(os.Stdout, msg)
return nil
}
@ -320,9 +367,14 @@ func runResumeLogging(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"))
userMsg := private.ResumeLogging(ctx)
_, _ = fmt.Fprintln(os.Stdout, userMsg)
setup("manager", c.Bool("debug"))
statusCode, msg := private.ResumeLogging(ctx)
switch statusCode {
case http.StatusInternalServerError:
return fail("InternalServerError", msg)
}
fmt.Fprintln(os.Stdout, msg)
return nil
}
@ -330,17 +382,28 @@ func runReleaseReopenLogging(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"))
userMsg := private.ReleaseReopenLogging(ctx)
_, _ = fmt.Fprintln(os.Stdout, userMsg)
setup("manager", c.Bool("debug"))
statusCode, msg := private.ReleaseReopenLogging(ctx)
switch statusCode {
case http.StatusInternalServerError:
return fail("InternalServerError", msg)
}
fmt.Fprintln(os.Stdout, msg)
return nil
}
func runSetLogSQL(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"))
setup("manager", c.Bool("debug"))
extra := private.SetLogSQL(ctx, !c.Bool("off"))
return handleCliResponseExtra(extra)
statusCode, msg := private.SetLogSQL(ctx, !c.Bool("off"))
switch statusCode {
case http.StatusInternalServerError:
return fail("InternalServerError", msg)
}
fmt.Fprintln(os.Stdout, msg)
return nil
}

View File

@ -11,11 +11,11 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
// CmdMigrate represents the available migrate sub-command.
var CmdMigrate = &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 gitea admin create-user before starting the server.",

View File

@ -8,7 +8,6 @@ import (
"fmt"
"strings"
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"
@ -20,73 +19,70 @@ import (
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
// CmdMigrateStorage represents the available migrate storage sub-command.
var CmdMigrateStorage = &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",
Action: runMigrateStorage,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "type",
Aliases: []string{"t"},
Value: "",
Usage: "Type of stored files to copy. Allowed types: 'attachments', 'lfs', 'avatars', 'repo-avatars', 'repo-archivers', 'packages', 'actions-log'",
cli.StringFlag{
Name: "type, t",
Value: "",
Usage: "Type of stored files to copy. Allowed types: 'attachments', 'lfs', 'avatars', 'repo-avatars', 'repo-archivers', 'packages'",
},
&cli.StringFlag{
Name: "storage",
Aliases: []string{"s"},
Value: "",
Usage: "New storage type: local (default) or minio",
cli.StringFlag{
Name: "storage, s",
Value: "",
Usage: "New storage type: local (default) or minio",
},
&cli.StringFlag{
Name: "path",
Aliases: []string{"p"},
Value: "",
Usage: "New storage placement if store is local (leave blank for default)",
cli.StringFlag{
Name: "path, p",
Value: "",
Usage: "New storage placement if store is local (leave blank for default)",
},
&cli.StringFlag{
cli.StringFlag{
Name: "minio-endpoint",
Value: "",
Usage: "Minio storage endpoint",
},
&cli.StringFlag{
cli.StringFlag{
Name: "minio-access-key-id",
Value: "",
Usage: "Minio storage accessKeyID",
},
&cli.StringFlag{
cli.StringFlag{
Name: "minio-secret-access-key",
Value: "",
Usage: "Minio storage secretAccessKey",
},
&cli.StringFlag{
cli.StringFlag{
Name: "minio-bucket",
Value: "",
Usage: "Minio storage bucket",
},
&cli.StringFlag{
cli.StringFlag{
Name: "minio-location",
Value: "",
Usage: "Minio storage location to create bucket",
},
&cli.StringFlag{
cli.StringFlag{
Name: "minio-base-path",
Value: "",
Usage: "Minio storage base path on the bucket",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "minio-use-ssl",
Usage: "Enable SSL for minio",
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "minio-insecure-skip-verify",
Usage: "Skip SSL verification",
},
&cli.StringFlag{
cli.StringFlag{
Name: "minio-checksum-algorithm",
Value: "",
Usage: "Minio checksum algorithm (default/md5)",
@ -110,9 +106,6 @@ func migrateLFS(ctx context.Context, dstStorage storage.ObjectStorage) error {
func migrateAvatars(ctx context.Context, dstStorage storage.ObjectStorage) error {
return db.Iterate(ctx, nil, func(ctx context.Context, user *user_model.User) error {
if user.CustomAvatarRelativePath() == "" {
return nil
}
_, err := storage.Copy(dstStorage, user.CustomAvatarRelativePath(), storage.Avatars, user.CustomAvatarRelativePath())
return err
})
@ -120,9 +113,6 @@ func migrateAvatars(ctx context.Context, dstStorage storage.ObjectStorage) error
func migrateRepoAvatars(ctx context.Context, dstStorage storage.ObjectStorage) error {
return db.Iterate(ctx, nil, func(ctx context.Context, repo *repo_model.Repository) error {
if repo.CustomAvatarRelativePath() == "" {
return nil
}
_, err := storage.Copy(dstStorage, repo.CustomAvatarRelativePath(), storage.RepoAvatars, repo.CustomAvatarRelativePath())
return err
})
@ -144,22 +134,6 @@ func migratePackages(ctx context.Context, dstStorage storage.ObjectStorage) erro
})
}
func migrateActionsLog(ctx context.Context, dstStorage storage.ObjectStorage) error {
return db.Iterate(ctx, nil, func(ctx context.Context, task *actions_model.ActionTask) error {
if task.LogExpired {
// the log has been cleared
return nil
}
if !task.LogInStorage {
// running tasks store logs in DBFS
return nil
}
p := task.LogFilename
_, err := storage.Copy(dstStorage, p, storage.Actions, p)
return err
})
}
func runMigrateStorage(ctx *cli.Context) error {
stdCtx, cancel := installSignals()
defer cancel()
@ -188,32 +162,30 @@ func runMigrateStorage(ctx *cli.Context) error {
switch strings.ToLower(ctx.String("storage")) {
case "":
fallthrough
case string(setting.LocalStorageType):
case string(storage.LocalStorageType):
p := ctx.String("path")
if p == "" {
log.Fatal("Path must be given when storage is local")
log.Fatal("Path must be given when storage is loal")
return nil
}
dstStorage, err = storage.NewLocalStorage(
stdCtx,
&setting.Storage{
storage.LocalStorageConfig{
Path: p,
})
case string(setting.MinioStorageType):
case string(storage.MinioStorageType):
dstStorage, err = storage.NewMinioStorage(
stdCtx,
&setting.Storage{
MinioConfig: setting.MinioStorageConfig{
Endpoint: ctx.String("minio-endpoint"),
AccessKeyID: ctx.String("minio-access-key-id"),
SecretAccessKey: ctx.String("minio-secret-access-key"),
Bucket: ctx.String("minio-bucket"),
Location: ctx.String("minio-location"),
BasePath: ctx.String("minio-base-path"),
UseSSL: ctx.Bool("minio-use-ssl"),
InsecureSkipVerify: ctx.Bool("minio-insecure-skip-verify"),
ChecksumAlgorithm: ctx.String("minio-checksum-algorithm"),
},
storage.MinioStorageConfig{
Endpoint: ctx.String("minio-endpoint"),
AccessKeyID: ctx.String("minio-access-key-id"),
SecretAccessKey: ctx.String("minio-secret-access-key"),
Bucket: ctx.String("minio-bucket"),
Location: ctx.String("minio-location"),
BasePath: ctx.String("minio-base-path"),
UseSSL: ctx.Bool("minio-use-ssl"),
InsecureSkipVerify: ctx.Bool("minio-insecure-skip-verify"),
ChecksumAlgorithm: ctx.String("minio-checksum-algorithm"),
})
default:
return fmt.Errorf("unsupported storage type: %s", ctx.String("storage"))
@ -229,7 +201,6 @@ func runMigrateStorage(ctx *cli.Context) error {
"repo-avatars": migrateRepoAvatars,
"repo-archivers": migrateRepoArchivers,
"packages": migratePackages,
"actions-log": migrateActionsLog,
}
tp := strings.ToLower(ctx.String("type"))

View File

@ -9,12 +9,10 @@ import (
"strings"
"testing"
"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"
packages_service "code.gitea.io/gitea/services/packages"
@ -27,11 +25,11 @@ func TestMigratePackages(t *testing.T) {
creator := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
content := "package main\n\nfunc main() {\nfmt.Println(\"hi\")\n}\n"
buf, err := packages_module.CreateHashedBufferFromReaderWithSize(strings.NewReader(content), 1024)
buf, err := packages_module.CreateHashedBufferFromReader(strings.NewReader(content), 1024)
assert.NoError(t, err)
defer buf.Close()
v, f, err := packages_service.CreatePackageAndAddFile(db.DefaultContext, &packages_service.PackageCreationInfo{
v, f, err := packages_service.CreatePackageAndAddFile(&packages_service.PackageCreationInfo{
PackageInfo: packages_service.PackageInfo{
Owner: creator,
PackageType: packages.TypeGeneric,
@ -59,7 +57,7 @@ func TestMigratePackages(t *testing.T) {
dstStorage, err := storage.NewLocalStorage(
ctx,
&setting.Storage{
storage.LocalStorageConfig{
Path: p,
})
assert.NoError(t, err)
@ -69,7 +67,7 @@ func TestMigratePackages(t *testing.T) {
entries, err := os.ReadDir(p)
assert.NoError(t, err)
assert.Len(t, entries, 2)
assert.EqualValues(t, 2, len(entries))
assert.EqualValues(t, "01", entries[0].Name())
assert.EqualValues(t, "tmp", entries[1].Name())
}

View File

@ -4,44 +4,46 @@
package cmd
import (
"errors"
"net/http"
"strings"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/setting"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
// CmdRestoreRepository represents the available restore a repository sub-command.
var CmdRestoreRepository = &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.",
Action: runRestoreRepository,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "repo_dir",
Aliases: []string{"r"},
Value: "./data",
Usage: "Repository dir path to restore from",
cli.StringFlag{
Name: "repo_dir, r",
Value: "./data",
Usage: "Repository dir path to restore from",
},
&cli.StringFlag{
cli.StringFlag{
Name: "owner_name",
Value: "",
Usage: "Restore destination owner name",
},
&cli.StringFlag{
cli.StringFlag{
Name: "repo_name",
Value: "",
Usage: "Restore destination repository name",
},
&cli.StringFlag{
cli.StringFlag{
Name: "units",
Value: "",
Usage: `Which items will be restored, one or more units should be separated as comma.
wiki, issues, labels, releases, release_assets, milestones, pull_requests, comments are allowed. Empty means all units.`,
},
&cli.BoolFlag{
cli.BoolFlag{
Name: "validation",
Usage: "Sanity check the content of the files before trying to load them",
},
@ -52,12 +54,13 @@ func runRestoreRepository(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setting.MustInstalled()
setting.InitProviderFromExistingFile()
setting.LoadCommonSettings()
var units []string
if s := c.String("units"); s != "" {
units = strings.Split(s, ",")
}
extra := private.RestoreRepo(
statusCode, errStr := private.RestoreRepo(
ctx,
c.String("repo_dir"),
c.String("owner_name"),
@ -65,5 +68,10 @@ func runRestoreRepository(c *cli.Context) error {
units,
c.Bool("validation"),
)
return handleCliResponseExtra(extra)
if statusCode == http.StatusOK {
return nil
}
log.Fatal("Failed to restore repository: %v", errStr)
return errors.New(errStr)
}

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