2017-02-23 03:40:44 +00:00
|
|
|
|
// Copyright 2017 The Gitea Authors. All rights reserved.
|
2022-11-27 18:20:29 +00:00
|
|
|
|
// SPDX-License-Identifier: MIT
|
2017-02-23 03:40:44 +00:00
|
|
|
|
|
|
|
|
|
package cmd
|
|
|
|
|
|
|
|
|
|
import (
|
2017-02-25 14:54:40 +00:00
|
|
|
|
"bufio"
|
|
|
|
|
"bytes"
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
"context"
|
2017-02-23 03:40:44 +00:00
|
|
|
|
"fmt"
|
2020-01-12 08:46:03 +00:00
|
|
|
|
"io"
|
2017-02-23 03:40:44 +00:00
|
|
|
|
"os"
|
2017-02-25 14:54:40 +00:00
|
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
2020-01-12 08:46:03 +00:00
|
|
|
|
"time"
|
2017-02-23 03:40:44 +00:00
|
|
|
|
|
2019-03-27 09:33:00 +00:00
|
|
|
|
"code.gitea.io/gitea/modules/git"
|
2023-06-28 06:02:06 +00:00
|
|
|
|
"code.gitea.io/gitea/modules/log"
|
2017-05-04 05:42:02 +00:00
|
|
|
|
"code.gitea.io/gitea/modules/private"
|
2022-05-08 16:46:32 +00:00
|
|
|
|
repo_module "code.gitea.io/gitea/modules/repository"
|
2019-11-14 22:39:48 +00:00
|
|
|
|
"code.gitea.io/gitea/modules/setting"
|
2017-02-23 03:40:44 +00:00
|
|
|
|
|
2023-07-21 09:28:19 +00:00
|
|
|
|
"github.com/urfave/cli/v2"
|
2017-02-23 03:40:44 +00:00
|
|
|
|
)
|
|
|
|
|
|
2019-12-26 11:29:45 +00:00
|
|
|
|
const (
|
|
|
|
|
hookBatchSize = 30
|
|
|
|
|
)
|
|
|
|
|
|
2017-02-23 03:40:44 +00:00
|
|
|
|
var (
|
|
|
|
|
// CmdHook represents the available hooks sub-command.
|
2023-07-21 09:28:19 +00:00
|
|
|
|
CmdHook = &cli.Command{
|
2017-02-23 03:40:44 +00:00
|
|
|
|
Name: "hook",
|
2023-12-15 15:49:01 +00:00
|
|
|
|
Usage: "(internal) Should only be called by Git",
|
|
|
|
|
Description: "Delegate commands to corresponding Git hooks",
|
2023-06-28 06:02:06 +00:00
|
|
|
|
Before: PrepareConsoleLoggerLevel(log.FATAL),
|
2023-07-21 09:28:19 +00:00
|
|
|
|
Subcommands: []*cli.Command{
|
2017-02-23 03:40:44 +00:00
|
|
|
|
subcmdHookPreReceive,
|
2018-01-12 22:16:49 +00:00
|
|
|
|
subcmdHookUpdate,
|
2017-02-23 03:40:44 +00:00
|
|
|
|
subcmdHookPostReceive,
|
2021-07-28 09:42:56 +00:00
|
|
|
|
subcmdHookProcReceive,
|
2017-02-23 03:40:44 +00:00
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-21 09:28:19 +00:00
|
|
|
|
subcmdHookPreReceive = &cli.Command{
|
2017-02-23 03:40:44 +00:00
|
|
|
|
Name: "pre-receive",
|
|
|
|
|
Usage: "Delegate pre-receive Git hook",
|
|
|
|
|
Description: "This command should only be called by Git",
|
|
|
|
|
Action: runHookPreReceive,
|
2020-05-29 03:04:44 +00:00
|
|
|
|
Flags: []cli.Flag{
|
2023-07-21 09:28:19 +00:00
|
|
|
|
&cli.BoolFlag{
|
2020-05-29 03:04:44 +00:00
|
|
|
|
Name: "debug",
|
|
|
|
|
},
|
|
|
|
|
},
|
2017-02-23 03:40:44 +00:00
|
|
|
|
}
|
2023-07-21 09:28:19 +00:00
|
|
|
|
subcmdHookUpdate = &cli.Command{
|
2017-02-23 03:40:44 +00:00
|
|
|
|
Name: "update",
|
|
|
|
|
Usage: "Delegate update Git hook",
|
|
|
|
|
Description: "This command should only be called by Git",
|
|
|
|
|
Action: runHookUpdate,
|
2020-05-29 03:04:44 +00:00
|
|
|
|
Flags: []cli.Flag{
|
2023-07-21 09:28:19 +00:00
|
|
|
|
&cli.BoolFlag{
|
2020-05-29 03:04:44 +00:00
|
|
|
|
Name: "debug",
|
|
|
|
|
},
|
|
|
|
|
},
|
2017-02-23 03:40:44 +00:00
|
|
|
|
}
|
2023-07-21 09:28:19 +00:00
|
|
|
|
subcmdHookPostReceive = &cli.Command{
|
2017-02-23 03:40:44 +00:00
|
|
|
|
Name: "post-receive",
|
|
|
|
|
Usage: "Delegate post-receive Git hook",
|
|
|
|
|
Description: "This command should only be called by Git",
|
|
|
|
|
Action: runHookPostReceive,
|
2020-05-29 03:04:44 +00:00
|
|
|
|
Flags: []cli.Flag{
|
2023-07-21 09:28:19 +00:00
|
|
|
|
&cli.BoolFlag{
|
2020-05-29 03:04:44 +00:00
|
|
|
|
Name: "debug",
|
|
|
|
|
},
|
|
|
|
|
},
|
2017-02-23 03:40:44 +00:00
|
|
|
|
}
|
2021-07-28 09:42:56 +00:00
|
|
|
|
// Note: new hook since git 2.29
|
2023-07-21 09:28:19 +00:00
|
|
|
|
subcmdHookProcReceive = &cli.Command{
|
2021-07-28 09:42:56 +00:00
|
|
|
|
Name: "proc-receive",
|
|
|
|
|
Usage: "Delegate proc-receive Git hook",
|
|
|
|
|
Description: "This command should only be called by Git",
|
|
|
|
|
Action: runHookProcReceive,
|
|
|
|
|
Flags: []cli.Flag{
|
2023-07-21 09:28:19 +00:00
|
|
|
|
&cli.BoolFlag{
|
2021-07-28 09:42:56 +00:00
|
|
|
|
Name: "debug",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
2017-02-23 03:40:44 +00:00
|
|
|
|
)
|
|
|
|
|
|
2020-01-12 08:46:03 +00:00
|
|
|
|
type delayWriter struct {
|
|
|
|
|
internal io.Writer
|
|
|
|
|
buf *bytes.Buffer
|
|
|
|
|
timer *time.Timer
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newDelayWriter(internal io.Writer, delay time.Duration) *delayWriter {
|
|
|
|
|
timer := time.NewTimer(delay)
|
|
|
|
|
return &delayWriter{
|
|
|
|
|
internal: internal,
|
|
|
|
|
buf: &bytes.Buffer{},
|
|
|
|
|
timer: timer,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d *delayWriter) Write(p []byte) (n int, err error) {
|
|
|
|
|
if d.buf != nil {
|
|
|
|
|
select {
|
|
|
|
|
case <-d.timer.C:
|
|
|
|
|
_, err := d.internal.Write(d.buf.Bytes())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
d.buf = nil
|
|
|
|
|
return d.internal.Write(p)
|
|
|
|
|
default:
|
|
|
|
|
return d.buf.Write(p)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return d.internal.Write(p)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d *delayWriter) WriteString(s string) (n int, err error) {
|
|
|
|
|
if d.buf != nil {
|
|
|
|
|
select {
|
|
|
|
|
case <-d.timer.C:
|
|
|
|
|
_, err := d.internal.Write(d.buf.Bytes())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
d.buf = nil
|
|
|
|
|
return d.internal.Write([]byte(s))
|
|
|
|
|
default:
|
|
|
|
|
return d.buf.WriteString(s)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return d.internal.Write([]byte(s))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d *delayWriter) Close() error {
|
2024-04-03 12:06:39 +00:00
|
|
|
|
if d.timer.Stop() {
|
|
|
|
|
d.buf = nil
|
2020-01-12 08:46:03 +00:00
|
|
|
|
}
|
2024-04-03 12:06:39 +00:00
|
|
|
|
if d.buf == nil {
|
2020-01-12 08:46:03 +00:00
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
_, err := d.internal.Write(d.buf.Bytes())
|
|
|
|
|
d.buf = nil
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type nilWriter struct{}
|
|
|
|
|
|
|
|
|
|
func (n *nilWriter) Write(p []byte) (int, error) {
|
|
|
|
|
return len(p), nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (n *nilWriter) WriteString(s string) (int, error) {
|
|
|
|
|
return len(s), nil
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-23 03:40:44 +00:00
|
|
|
|
func runHookPreReceive(c *cli.Context) error {
|
2022-05-08 16:46:32 +00:00
|
|
|
|
if isInternal, _ := strconv.ParseBool(os.Getenv(repo_module.EnvIsInternal)); isInternal {
|
2019-12-27 21:15:04 +00:00
|
|
|
|
return nil
|
|
|
|
|
}
|
2021-07-14 14:43:13 +00:00
|
|
|
|
ctx, cancel := installSignals()
|
|
|
|
|
defer cancel()
|
2019-12-27 21:15:04 +00:00
|
|
|
|
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
setup(ctx, c.Bool("debug"))
|
2019-12-27 21:15:04 +00:00
|
|
|
|
|
2017-02-23 03:40:44 +00:00
|
|
|
|
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
2019-11-14 22:39:48 +00:00
|
|
|
|
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
2023-01-09 13:01:00 +00:00
|
|
|
|
return fail(ctx, `Rejecting changes as Forgejo environment not set.
|
2019-11-14 22:39:48 +00:00
|
|
|
|
If you are pushing over SSH you must push with a key managed by
|
2023-01-09 13:01:00 +00:00
|
|
|
|
Forgejo or set your environment appropriately.`, "")
|
2019-11-14 22:39:48 +00:00
|
|
|
|
}
|
2021-07-14 14:43:13 +00:00
|
|
|
|
return nil
|
2017-02-23 03:40:44 +00:00
|
|
|
|
}
|
2017-02-25 14:54:40 +00:00
|
|
|
|
|
2021-07-08 11:38:13 +00:00
|
|
|
|
// the environment is set by serv command
|
2022-05-08 16:46:32 +00:00
|
|
|
|
isWiki, _ := strconv.ParseBool(os.Getenv(repo_module.EnvRepoIsWiki))
|
|
|
|
|
username := os.Getenv(repo_module.EnvRepoUsername)
|
|
|
|
|
reponame := os.Getenv(repo_module.EnvRepoName)
|
|
|
|
|
userID, _ := strconv.ParseInt(os.Getenv(repo_module.EnvPusherID), 10, 64)
|
|
|
|
|
prID, _ := strconv.ParseInt(os.Getenv(repo_module.EnvPRID), 10, 64)
|
|
|
|
|
deployKeyID, _ := strconv.ParseInt(os.Getenv(repo_module.EnvDeployKeyID), 10, 64)
|
Implement actions (#21937)
Close #13539.
Co-authored by: @lunny @appleboy @fuxiaohei and others.
Related projects:
- https://gitea.com/gitea/actions-proto-def
- https://gitea.com/gitea/actions-proto-go
- https://gitea.com/gitea/act
- https://gitea.com/gitea/act_runner
### Summary
The target of this PR is to bring a basic implementation of "Actions",
an internal CI/CD system of Gitea. That means even though it has been
merged, the state of the feature is **EXPERIMENTAL**, and please note
that:
- It is disabled by default;
- It shouldn't be used in a production environment currently;
- It shouldn't be used in a public Gitea instance currently;
- Breaking changes may be made before it's stable.
**Please comment on #13539 if you have any different product design
ideas**, all decisions reached there will be adopted here. But in this
PR, we don't talk about **naming, feature-creep or alternatives**.
### ⚠️ Breaking
`gitea-actions` will become a reserved user name. If a user with the
name already exists in the database, it is recommended to rename it.
### Some important reviews
- What is `DEFAULT_ACTIONS_URL` in `app.ini` for?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1055954954
- Why the api for runners is not under the normal `/api/v1` prefix?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1061173592
- Why DBFS?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1061301178
- Why ignore events triggered by `gitea-actions` bot?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1063254103
- Why there's no permission control for actions?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1090229868
### What it looks like
<details>
#### Manage runners
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205870657-c72f590e-2e08-4cd4-be7f-2e0abb299bbf.png">
#### List runs
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205872794-50fde990-2b45-48c1-a178-908e4ec5b627.png">
#### View logs
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205872501-9b7b9000-9542-4991-8f55-18ccdada77c3.png">
</details>
### How to try it
<details>
#### 1. Start Gitea
Clone this branch and [install from
source](https://docs.gitea.io/en-us/install-from-source).
Add additional configurations in `app.ini` to enable Actions:
```ini
[actions]
ENABLED = true
```
Start it.
If all is well, you'll see the management page of runners:
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205877365-8e30a780-9b10-4154-b3e8-ee6c3cb35a59.png">
#### 2. Start runner
Clone the [act_runner](https://gitea.com/gitea/act_runner), and follow
the
[README](https://gitea.com/gitea/act_runner/src/branch/main/README.md)
to start it.
If all is well, you'll see a new runner has been added:
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205878000-216f5937-e696-470d-b66c-8473987d91c3.png">
#### 3. Enable actions for a repo
Create a new repo or open an existing one, check the `Actions` checkbox
in settings and submit.
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205879705-53e09208-73c0-4b3e-a123-2dcf9aba4b9c.png">
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205879383-23f3d08f-1a85-41dd-a8b3-54e2ee6453e8.png">
If all is well, you'll see a new tab "Actions":
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205881648-a8072d8c-5803-4d76-b8a8-9b2fb49516c1.png">
#### 4. Upload workflow files
Upload some workflow files to `.gitea/workflows/xxx.yaml`, you can
follow the [quickstart](https://docs.github.com/en/actions/quickstart)
of GitHub Actions. Yes, Gitea Actions is compatible with GitHub Actions
in most cases, you can use the same demo:
```yaml
name: GitHub Actions Demo
run-name: ${{ github.actor }} is testing out GitHub Actions 🚀
on: [push]
jobs:
Explore-GitHub-Actions:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- name: Check out repository code
uses: actions/checkout@v3
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
- name: List files in the repository
run: |
ls ${{ github.workspace }}
- run: echo "🍏 This job's status is ${{ job.status }}."
```
If all is well, you'll see a new run in `Actions` tab:
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205884473-79a874bc-171b-4aaf-acd5-0241a45c3b53.png">
#### 5. Check the logs of jobs
Click a run and you'll see the logs:
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205884800-994b0374-67f7-48ff-be9a-4c53f3141547.png">
#### 6. Go on
You can try more examples in [the
documents](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions)
of GitHub Actions, then you might find a lot of bugs.
Come on, PRs are welcome.
</details>
See also: [Feature Preview: Gitea
Actions](https://blog.gitea.io/2022/12/feature-preview-gitea-actions/)
---------
Co-authored-by: a1012112796 <1012112796@qq.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: ChristopherHX <christopher.homberger@web.de>
Co-authored-by: John Olheiser <john.olheiser@gmail.com>
2023-01-31 01:45:19 +00:00
|
|
|
|
actionPerm, _ := strconv.ParseInt(os.Getenv(repo_module.EnvActionPerm), 10, 64)
|
2017-02-25 14:54:40 +00:00
|
|
|
|
|
2019-12-26 11:29:45 +00:00
|
|
|
|
hookOptions := private.HookOptions{
|
|
|
|
|
UserID: userID,
|
|
|
|
|
GitAlternativeObjectDirectories: os.Getenv(private.GitAlternativeObjectDirectories),
|
|
|
|
|
GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
|
|
|
|
|
GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
|
2020-08-23 16:02:35 +00:00
|
|
|
|
GitPushOptions: pushOptions(),
|
2021-06-23 19:38:19 +00:00
|
|
|
|
PullRequestID: prID,
|
2022-03-22 09:29:07 +00:00
|
|
|
|
DeployKeyID: deployKeyID,
|
Implement actions (#21937)
Close #13539.
Co-authored by: @lunny @appleboy @fuxiaohei and others.
Related projects:
- https://gitea.com/gitea/actions-proto-def
- https://gitea.com/gitea/actions-proto-go
- https://gitea.com/gitea/act
- https://gitea.com/gitea/act_runner
### Summary
The target of this PR is to bring a basic implementation of "Actions",
an internal CI/CD system of Gitea. That means even though it has been
merged, the state of the feature is **EXPERIMENTAL**, and please note
that:
- It is disabled by default;
- It shouldn't be used in a production environment currently;
- It shouldn't be used in a public Gitea instance currently;
- Breaking changes may be made before it's stable.
**Please comment on #13539 if you have any different product design
ideas**, all decisions reached there will be adopted here. But in this
PR, we don't talk about **naming, feature-creep or alternatives**.
### ⚠️ Breaking
`gitea-actions` will become a reserved user name. If a user with the
name already exists in the database, it is recommended to rename it.
### Some important reviews
- What is `DEFAULT_ACTIONS_URL` in `app.ini` for?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1055954954
- Why the api for runners is not under the normal `/api/v1` prefix?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1061173592
- Why DBFS?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1061301178
- Why ignore events triggered by `gitea-actions` bot?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1063254103
- Why there's no permission control for actions?
- https://github.com/go-gitea/gitea/pull/21937#discussion_r1090229868
### What it looks like
<details>
#### Manage runners
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205870657-c72f590e-2e08-4cd4-be7f-2e0abb299bbf.png">
#### List runs
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205872794-50fde990-2b45-48c1-a178-908e4ec5b627.png">
#### View logs
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205872501-9b7b9000-9542-4991-8f55-18ccdada77c3.png">
</details>
### How to try it
<details>
#### 1. Start Gitea
Clone this branch and [install from
source](https://docs.gitea.io/en-us/install-from-source).
Add additional configurations in `app.ini` to enable Actions:
```ini
[actions]
ENABLED = true
```
Start it.
If all is well, you'll see the management page of runners:
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205877365-8e30a780-9b10-4154-b3e8-ee6c3cb35a59.png">
#### 2. Start runner
Clone the [act_runner](https://gitea.com/gitea/act_runner), and follow
the
[README](https://gitea.com/gitea/act_runner/src/branch/main/README.md)
to start it.
If all is well, you'll see a new runner has been added:
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205878000-216f5937-e696-470d-b66c-8473987d91c3.png">
#### 3. Enable actions for a repo
Create a new repo or open an existing one, check the `Actions` checkbox
in settings and submit.
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205879705-53e09208-73c0-4b3e-a123-2dcf9aba4b9c.png">
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205879383-23f3d08f-1a85-41dd-a8b3-54e2ee6453e8.png">
If all is well, you'll see a new tab "Actions":
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205881648-a8072d8c-5803-4d76-b8a8-9b2fb49516c1.png">
#### 4. Upload workflow files
Upload some workflow files to `.gitea/workflows/xxx.yaml`, you can
follow the [quickstart](https://docs.github.com/en/actions/quickstart)
of GitHub Actions. Yes, Gitea Actions is compatible with GitHub Actions
in most cases, you can use the same demo:
```yaml
name: GitHub Actions Demo
run-name: ${{ github.actor }} is testing out GitHub Actions 🚀
on: [push]
jobs:
Explore-GitHub-Actions:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- name: Check out repository code
uses: actions/checkout@v3
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
- name: List files in the repository
run: |
ls ${{ github.workspace }}
- run: echo "🍏 This job's status is ${{ job.status }}."
```
If all is well, you'll see a new run in `Actions` tab:
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205884473-79a874bc-171b-4aaf-acd5-0241a45c3b53.png">
#### 5. Check the logs of jobs
Click a run and you'll see the logs:
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/205884800-994b0374-67f7-48ff-be9a-4c53f3141547.png">
#### 6. Go on
You can try more examples in [the
documents](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions)
of GitHub Actions, then you might find a lot of bugs.
Come on, PRs are welcome.
</details>
See also: [Feature Preview: Gitea
Actions](https://blog.gitea.io/2022/12/feature-preview-gitea-actions/)
---------
Co-authored-by: a1012112796 <1012112796@qq.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: ChristopherHX <christopher.homberger@web.de>
Co-authored-by: John Olheiser <john.olheiser@gmail.com>
2023-01-31 01:45:19 +00:00
|
|
|
|
ActionPerm: int(actionPerm),
|
2019-12-26 11:29:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-02-25 14:54:40 +00:00
|
|
|
|
scanner := bufio.NewScanner(os.Stdin)
|
|
|
|
|
|
2019-12-26 11:29:45 +00:00
|
|
|
|
oldCommitIDs := make([]string, hookBatchSize)
|
|
|
|
|
newCommitIDs := make([]string, hookBatchSize)
|
2023-05-26 01:04:48 +00:00
|
|
|
|
refFullNames := make([]git.RefName, hookBatchSize)
|
2019-12-26 11:29:45 +00:00
|
|
|
|
count := 0
|
|
|
|
|
total := 0
|
|
|
|
|
lastline := 0
|
|
|
|
|
|
2020-01-12 08:46:03 +00:00
|
|
|
|
var out io.Writer
|
|
|
|
|
out = &nilWriter{}
|
|
|
|
|
if setting.Git.VerbosePush {
|
|
|
|
|
if setting.Git.VerbosePushDelay > 0 {
|
|
|
|
|
dWriter := newDelayWriter(os.Stdout, setting.Git.VerbosePushDelay)
|
|
|
|
|
defer dWriter.Close()
|
|
|
|
|
out = dWriter
|
|
|
|
|
} else {
|
|
|
|
|
out = os.Stdout
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-26 16:21:54 +00:00
|
|
|
|
supportProcReceive := false
|
2021-07-28 09:42:56 +00:00
|
|
|
|
if git.CheckGitVersionAtLeast("2.29") == nil {
|
2022-11-26 16:21:54 +00:00
|
|
|
|
supportProcReceive = true
|
2021-07-28 09:42:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-12-26 11:29:45 +00:00
|
|
|
|
for scanner.Scan() {
|
2017-02-25 14:54:40 +00:00
|
|
|
|
// TODO: support news feeds for wiki
|
|
|
|
|
if isWiki {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fields := bytes.Fields(scanner.Bytes())
|
|
|
|
|
if len(fields) != 3 {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-14 08:16:22 +00:00
|
|
|
|
oldCommitID := string(fields[0])
|
2017-02-25 14:54:40 +00:00
|
|
|
|
newCommitID := string(fields[1])
|
2023-05-26 01:04:48 +00:00
|
|
|
|
refFullName := git.RefName(fields[2])
|
2019-12-26 11:29:45 +00:00
|
|
|
|
total++
|
|
|
|
|
lastline++
|
2017-02-25 14:54:40 +00:00
|
|
|
|
|
2021-06-25 14:28:55 +00:00
|
|
|
|
// If the ref is a branch or tag, check if it's protected
|
2022-11-26 16:21:54 +00:00
|
|
|
|
// if supportProcReceive all ref should be checked because
|
2021-07-28 09:42:56 +00:00
|
|
|
|
// permission check was delayed
|
2023-05-26 01:04:48 +00:00
|
|
|
|
if supportProcReceive || refFullName.IsBranch() || refFullName.IsTag() {
|
2019-12-26 11:29:45 +00:00
|
|
|
|
oldCommitIDs[count] = oldCommitID
|
|
|
|
|
newCommitIDs[count] = newCommitID
|
|
|
|
|
refFullNames[count] = refFullName
|
|
|
|
|
count++
|
2020-01-12 08:46:03 +00:00
|
|
|
|
fmt.Fprintf(out, "*")
|
2019-12-26 11:29:45 +00:00
|
|
|
|
|
|
|
|
|
if count >= hookBatchSize {
|
2021-06-25 14:28:55 +00:00
|
|
|
|
fmt.Fprintf(out, " Checking %d references\n", count)
|
2019-12-26 11:29:45 +00:00
|
|
|
|
|
|
|
|
|
hookOptions.OldCommitIDs = oldCommitIDs
|
|
|
|
|
hookOptions.NewCommitIDs = newCommitIDs
|
|
|
|
|
hookOptions.RefFullNames = refFullNames
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
extra := private.HookPreReceive(ctx, username, reponame, hookOptions)
|
|
|
|
|
if extra.HasError() {
|
|
|
|
|
return fail(ctx, extra.UserMsg, "HookPreReceive(batch) failed: %v", extra.Error)
|
2019-12-26 11:29:45 +00:00
|
|
|
|
}
|
|
|
|
|
count = 0
|
|
|
|
|
lastline = 0
|
2017-03-01 15:01:03 +00:00
|
|
|
|
}
|
2019-12-26 11:29:45 +00:00
|
|
|
|
} else {
|
2020-01-12 08:46:03 +00:00
|
|
|
|
fmt.Fprintf(out, ".")
|
2019-12-26 11:29:45 +00:00
|
|
|
|
}
|
|
|
|
|
if lastline >= hookBatchSize {
|
2020-01-12 08:46:03 +00:00
|
|
|
|
fmt.Fprintf(out, "\n")
|
2019-12-26 11:29:45 +00:00
|
|
|
|
lastline = 0
|
2017-02-25 14:54:40 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-26 11:29:45 +00:00
|
|
|
|
if count > 0 {
|
|
|
|
|
hookOptions.OldCommitIDs = oldCommitIDs[:count]
|
|
|
|
|
hookOptions.NewCommitIDs = newCommitIDs[:count]
|
|
|
|
|
hookOptions.RefFullNames = refFullNames[:count]
|
|
|
|
|
|
2021-06-25 14:28:55 +00:00
|
|
|
|
fmt.Fprintf(out, " Checking %d references\n", count)
|
2019-12-26 11:29:45 +00:00
|
|
|
|
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
extra := private.HookPreReceive(ctx, username, reponame, hookOptions)
|
|
|
|
|
if extra.HasError() {
|
|
|
|
|
return fail(ctx, extra.UserMsg, "HookPreReceive(last) failed: %v", extra.Error)
|
2019-12-26 11:29:45 +00:00
|
|
|
|
}
|
|
|
|
|
} else if lastline > 0 {
|
2020-01-12 08:46:03 +00:00
|
|
|
|
fmt.Fprintf(out, "\n")
|
2019-12-26 11:29:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-01-12 08:46:03 +00:00
|
|
|
|
fmt.Fprintf(out, "Checked %d references in total\n", total)
|
2017-02-23 03:40:44 +00:00
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 22:28:10 +00:00
|
|
|
|
// runHookUpdate process the update hook: https://git-scm.com/docs/githooks#update
|
2017-02-23 03:40:44 +00:00
|
|
|
|
func runHookUpdate(c *cli.Context) error {
|
2024-03-26 22:28:10 +00:00
|
|
|
|
// Now if we're an internal don't do anything else
|
|
|
|
|
if isInternal, _ := strconv.ParseBool(os.Getenv(repo_module.EnvIsInternal)); isInternal {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ctx, cancel := installSignals()
|
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
|
|
// The last three arguments given to the hook are in order: reference name, old commit ID and new commit ID.
|
|
|
|
|
args := os.Args[len(os.Args)-3:]
|
|
|
|
|
refFullName := git.RefName(args[0])
|
|
|
|
|
newCommitID := args[2]
|
|
|
|
|
|
|
|
|
|
// Only process pull references.
|
|
|
|
|
if !refFullName.IsPull() {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Deletion of the ref means that the new commit ID is only composed of '0'.
|
|
|
|
|
if strings.ContainsFunc(newCommitID, func(e rune) bool { return e != '0' }) {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return fail(ctx, fmt.Sprintf("The deletion of %s is skipped as it's an internal reference.", refFullName), "")
|
2017-02-23 03:40:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func runHookPostReceive(c *cli.Context) error {
|
2021-07-14 14:43:13 +00:00
|
|
|
|
ctx, cancel := installSignals()
|
|
|
|
|
defer cancel()
|
|
|
|
|
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
setup(ctx, c.Bool("debug"))
|
2022-06-16 15:47:44 +00:00
|
|
|
|
|
2020-10-13 16:24:06 +00:00
|
|
|
|
// First of all run update-server-info no matter what
|
2022-04-01 02:55:30 +00:00
|
|
|
|
if _, _, err := git.NewCommand(ctx, "update-server-info").RunStdString(nil); err != nil {
|
2022-10-24 19:29:17 +00:00
|
|
|
|
return fmt.Errorf("Failed to call 'git update-server-info': %w", err)
|
2020-10-13 16:24:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Now if we're an internal don't do anything else
|
2022-05-08 16:46:32 +00:00
|
|
|
|
if isInternal, _ := strconv.ParseBool(os.Getenv(repo_module.EnvIsInternal)); isInternal {
|
2019-12-27 21:15:04 +00:00
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-23 03:40:44 +00:00
|
|
|
|
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
2019-11-14 22:39:48 +00:00
|
|
|
|
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
2023-01-09 13:01:00 +00:00
|
|
|
|
return fail(ctx, `Rejecting changes as Forgejo environment not set.
|
2019-11-14 22:39:48 +00:00
|
|
|
|
If you are pushing over SSH you must push with a key managed by
|
2023-01-09 13:01:00 +00:00
|
|
|
|
Forgejo or set your environment appropriately.`, "")
|
2019-11-14 22:39:48 +00:00
|
|
|
|
}
|
2021-07-14 14:43:13 +00:00
|
|
|
|
return nil
|
2017-02-23 03:40:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-01-12 08:46:03 +00:00
|
|
|
|
var out io.Writer
|
|
|
|
|
out = &nilWriter{}
|
|
|
|
|
if setting.Git.VerbosePush {
|
|
|
|
|
if setting.Git.VerbosePushDelay > 0 {
|
2024-04-02 23:17:25 +00:00
|
|
|
|
dWriter := newDelayWriter(os.Stdout, setting.Git.VerbosePushDelay)
|
2020-01-12 08:46:03 +00:00
|
|
|
|
defer dWriter.Close()
|
|
|
|
|
out = dWriter
|
|
|
|
|
} else {
|
|
|
|
|
out = os.Stdout
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-08 11:38:13 +00:00
|
|
|
|
// the environment is set by serv command
|
2022-05-08 16:46:32 +00:00
|
|
|
|
repoUser := os.Getenv(repo_module.EnvRepoUsername)
|
|
|
|
|
isWiki, _ := strconv.ParseBool(os.Getenv(repo_module.EnvRepoIsWiki))
|
|
|
|
|
repoName := os.Getenv(repo_module.EnvRepoName)
|
|
|
|
|
pusherID, _ := strconv.ParseInt(os.Getenv(repo_module.EnvPusherID), 10, 64)
|
|
|
|
|
pusherName := os.Getenv(repo_module.EnvPusherName)
|
2017-02-25 14:54:40 +00:00
|
|
|
|
|
2019-12-26 11:29:45 +00:00
|
|
|
|
hookOptions := private.HookOptions{
|
|
|
|
|
UserName: pusherName,
|
|
|
|
|
UserID: pusherID,
|
|
|
|
|
GitAlternativeObjectDirectories: os.Getenv(private.GitAlternativeObjectDirectories),
|
|
|
|
|
GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
|
|
|
|
|
GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
|
2020-08-23 16:02:35 +00:00
|
|
|
|
GitPushOptions: pushOptions(),
|
2019-12-26 11:29:45 +00:00
|
|
|
|
}
|
|
|
|
|
oldCommitIDs := make([]string, hookBatchSize)
|
|
|
|
|
newCommitIDs := make([]string, hookBatchSize)
|
2023-05-26 01:04:48 +00:00
|
|
|
|
refFullNames := make([]git.RefName, hookBatchSize)
|
2019-12-26 11:29:45 +00:00
|
|
|
|
count := 0
|
|
|
|
|
total := 0
|
|
|
|
|
wasEmpty := false
|
|
|
|
|
masterPushed := false
|
|
|
|
|
results := make([]private.HookPostReceiveBranchResult, 0)
|
|
|
|
|
|
2017-02-25 14:54:40 +00:00
|
|
|
|
scanner := bufio.NewScanner(os.Stdin)
|
|
|
|
|
for scanner.Scan() {
|
|
|
|
|
// TODO: support news feeds for wiki
|
|
|
|
|
if isWiki {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fields := bytes.Fields(scanner.Bytes())
|
|
|
|
|
if len(fields) != 3 {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-12 08:46:03 +00:00
|
|
|
|
fmt.Fprintf(out, ".")
|
2019-12-26 11:29:45 +00:00
|
|
|
|
oldCommitIDs[count] = string(fields[0])
|
|
|
|
|
newCommitIDs[count] = string(fields[1])
|
2023-05-26 01:04:48 +00:00
|
|
|
|
refFullNames[count] = git.RefName(fields[2])
|
2023-12-13 21:02:00 +00:00
|
|
|
|
|
2023-12-19 07:20:47 +00:00
|
|
|
|
commitID, _ := git.NewIDFromString(newCommitIDs[count])
|
2023-12-13 21:02:00 +00:00
|
|
|
|
if refFullNames[count] == git.BranchPrefix+"master" && !commitID.IsZero() && count == total {
|
2019-12-26 11:29:45 +00:00
|
|
|
|
masterPushed = true
|
|
|
|
|
}
|
|
|
|
|
count++
|
|
|
|
|
total++
|
|
|
|
|
|
|
|
|
|
if count >= hookBatchSize {
|
2020-01-12 08:46:03 +00:00
|
|
|
|
fmt.Fprintf(out, " Processing %d references\n", count)
|
2019-12-26 11:29:45 +00:00
|
|
|
|
hookOptions.OldCommitIDs = oldCommitIDs
|
|
|
|
|
hookOptions.NewCommitIDs = newCommitIDs
|
|
|
|
|
hookOptions.RefFullNames = refFullNames
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
resp, extra := private.HookPostReceive(ctx, repoUser, repoName, hookOptions)
|
|
|
|
|
if extra.HasError() {
|
2019-12-26 11:29:45 +00:00
|
|
|
|
hookPrintResults(results)
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
return fail(ctx, extra.UserMsg, "HookPostReceive failed: %v", extra.Error)
|
2019-12-26 11:29:45 +00:00
|
|
|
|
}
|
|
|
|
|
wasEmpty = wasEmpty || resp.RepoWasEmpty
|
|
|
|
|
results = append(results, resp.Results...)
|
|
|
|
|
count = 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if count == 0 {
|
|
|
|
|
if wasEmpty && masterPushed {
|
|
|
|
|
// We need to tell the repo to reset the default branch to master
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
extra := private.SetDefaultBranch(ctx, repoUser, repoName, "master")
|
|
|
|
|
if extra.HasError() {
|
|
|
|
|
return fail(ctx, extra.UserMsg, "SetDefaultBranch failed: %v", extra.Error)
|
2019-12-26 11:29:45 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-01-12 08:46:03 +00:00
|
|
|
|
fmt.Fprintf(out, "Processed %d references in total\n", total)
|
2019-12-26 11:29:45 +00:00
|
|
|
|
|
|
|
|
|
hookPrintResults(results)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2017-02-25 14:54:40 +00:00
|
|
|
|
|
2019-12-26 11:29:45 +00:00
|
|
|
|
hookOptions.OldCommitIDs = oldCommitIDs[:count]
|
|
|
|
|
hookOptions.NewCommitIDs = newCommitIDs[:count]
|
|
|
|
|
hookOptions.RefFullNames = refFullNames[:count]
|
2018-10-20 06:59:06 +00:00
|
|
|
|
|
2020-01-12 08:46:03 +00:00
|
|
|
|
fmt.Fprintf(out, " Processing %d references\n", count)
|
2019-12-26 11:29:45 +00:00
|
|
|
|
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
resp, extra := private.HookPostReceive(ctx, repoUser, repoName, hookOptions)
|
2019-12-26 11:29:45 +00:00
|
|
|
|
if resp == nil {
|
|
|
|
|
hookPrintResults(results)
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
return fail(ctx, extra.UserMsg, "HookPostReceive failed: %v", extra.Error)
|
2019-12-26 11:29:45 +00:00
|
|
|
|
}
|
|
|
|
|
wasEmpty = wasEmpty || resp.RepoWasEmpty
|
|
|
|
|
results = append(results, resp.Results...)
|
|
|
|
|
|
2020-01-12 08:46:03 +00:00
|
|
|
|
fmt.Fprintf(out, "Processed %d references in total\n", total)
|
2019-12-26 11:29:45 +00:00
|
|
|
|
|
|
|
|
|
if wasEmpty && masterPushed {
|
|
|
|
|
// We need to tell the repo to reset the default branch to master
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
extra := private.SetDefaultBranch(ctx, repoUser, repoName, "master")
|
|
|
|
|
if extra.HasError() {
|
|
|
|
|
return fail(ctx, extra.UserMsg, "SetDefaultBranch failed: %v", extra.Error)
|
2019-06-01 15:00:21 +00:00
|
|
|
|
}
|
2019-12-26 11:29:45 +00:00
|
|
|
|
}
|
2018-10-20 06:59:06 +00:00
|
|
|
|
|
2024-04-02 23:17:25 +00:00
|
|
|
|
hookPrintResults(results)
|
2019-12-26 11:29:45 +00:00
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func hookPrintResults(results []private.HookPostReceiveBranchResult) {
|
|
|
|
|
for _, res := range results {
|
|
|
|
|
if !res.Message {
|
2019-06-01 15:00:21 +00:00
|
|
|
|
continue
|
2018-10-20 06:59:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-01 15:00:21 +00:00
|
|
|
|
fmt.Fprintln(os.Stderr, "")
|
2019-12-26 11:29:45 +00:00
|
|
|
|
if res.Create {
|
|
|
|
|
fmt.Fprintf(os.Stderr, "Create a new pull request for '%s':\n", res.Branch)
|
|
|
|
|
fmt.Fprintf(os.Stderr, " %s\n", res.URL)
|
2019-06-01 15:00:21 +00:00
|
|
|
|
} else {
|
|
|
|
|
fmt.Fprint(os.Stderr, "Visit the existing pull request:\n")
|
2019-12-26 11:29:45 +00:00
|
|
|
|
fmt.Fprintf(os.Stderr, " %s\n", res.URL)
|
2019-06-01 15:00:21 +00:00
|
|
|
|
}
|
|
|
|
|
fmt.Fprintln(os.Stderr, "")
|
2019-12-26 11:29:45 +00:00
|
|
|
|
os.Stderr.Sync()
|
2017-02-25 14:54:40 +00:00
|
|
|
|
}
|
2017-02-23 03:40:44 +00:00
|
|
|
|
}
|
2020-08-23 16:02:35 +00:00
|
|
|
|
|
|
|
|
|
func pushOptions() map[string]string {
|
|
|
|
|
opts := make(map[string]string)
|
|
|
|
|
if pushCount, err := strconv.Atoi(os.Getenv(private.GitPushOptionCount)); err == nil {
|
|
|
|
|
for idx := 0; idx < pushCount; idx++ {
|
|
|
|
|
opt := os.Getenv(fmt.Sprintf("GIT_PUSH_OPTION_%d", idx))
|
2024-04-03 00:41:57 +00:00
|
|
|
|
key, value, found := strings.Cut(opt, "=")
|
|
|
|
|
if !found {
|
|
|
|
|
value = "true"
|
2020-08-23 16:02:35 +00:00
|
|
|
|
}
|
2024-04-03 00:41:57 +00:00
|
|
|
|
opts[key] = value
|
2020-08-23 16:02:35 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return opts
|
|
|
|
|
}
|
2021-07-28 09:42:56 +00:00
|
|
|
|
|
|
|
|
|
func runHookProcReceive(c *cli.Context) error {
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
ctx, cancel := installSignals()
|
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
|
|
setup(ctx, c.Bool("debug"))
|
2021-07-28 09:42:56 +00:00
|
|
|
|
|
|
|
|
|
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
|
|
|
|
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
2023-01-09 13:01:00 +00:00
|
|
|
|
return fail(ctx, `Rejecting changes as Forgejo environment not set.
|
2021-07-28 09:42:56 +00:00
|
|
|
|
If you are pushing over SSH you must push with a key managed by
|
2023-01-09 13:01:00 +00:00
|
|
|
|
Forgejo or set your environment appropriately.`, "")
|
2021-07-28 09:42:56 +00:00
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if git.CheckGitVersionAtLeast("2.29") != nil {
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
return fail(ctx, "No proc-receive support", "current git version doesn't support proc-receive.")
|
2021-07-28 09:42:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reader := bufio.NewReader(os.Stdin)
|
2022-05-08 16:46:32 +00:00
|
|
|
|
repoUser := os.Getenv(repo_module.EnvRepoUsername)
|
|
|
|
|
repoName := os.Getenv(repo_module.EnvRepoName)
|
|
|
|
|
pusherID, _ := strconv.ParseInt(os.Getenv(repo_module.EnvPusherID), 10, 64)
|
|
|
|
|
pusherName := os.Getenv(repo_module.EnvPusherName)
|
2021-07-28 09:42:56 +00:00
|
|
|
|
|
|
|
|
|
// 1. Version and features negotiation.
|
|
|
|
|
// S: PKT-LINE(version=1\0push-options atomic...) / PKT-LINE(version=1\n)
|
|
|
|
|
// S: flush-pkt
|
|
|
|
|
// H: PKT-LINE(version=1\0push-options...)
|
|
|
|
|
// H: flush-pkt
|
|
|
|
|
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
rs, err := readPktLine(ctx, reader, pktLineTypeData)
|
2021-07-28 09:42:56 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const VersionHead string = "version=1"
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
hasPushOptions bool
|
|
|
|
|
response = []byte(VersionHead)
|
|
|
|
|
requestOptions []string
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
index := bytes.IndexByte(rs.Data, byte(0))
|
|
|
|
|
if index >= len(rs.Data) {
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
return fail(ctx, "Protocol: format error", "pkt-line: format error "+fmt.Sprint(rs.Data))
|
2021-07-28 09:42:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if index < 0 {
|
|
|
|
|
if len(rs.Data) == 10 && rs.Data[9] == '\n' {
|
|
|
|
|
index = 9
|
|
|
|
|
} else {
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
return fail(ctx, "Protocol: format error", "pkt-line: format error "+fmt.Sprint(rs.Data))
|
2021-07-28 09:42:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if string(rs.Data[0:index]) != VersionHead {
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
return fail(ctx, "Protocol: version error", "Received unsupported version: %s", string(rs.Data[0:index]))
|
2021-07-28 09:42:56 +00:00
|
|
|
|
}
|
|
|
|
|
requestOptions = strings.Split(string(rs.Data[index+1:]), " ")
|
|
|
|
|
|
|
|
|
|
for _, option := range requestOptions {
|
|
|
|
|
if strings.HasPrefix(option, "push-options") {
|
|
|
|
|
response = append(response, byte(0))
|
|
|
|
|
response = append(response, []byte("push-options")...)
|
|
|
|
|
hasPushOptions = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
response = append(response, '\n')
|
|
|
|
|
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
_, err = readPktLine(ctx, reader, pktLineTypeFlush)
|
2021-07-28 09:42:56 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
err = writeDataPktLine(ctx, os.Stdout, response)
|
2021-07-28 09:42:56 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
err = writeFlushPktLine(ctx, os.Stdout)
|
2021-07-28 09:42:56 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2. receive commands from server.
|
|
|
|
|
// S: PKT-LINE(<old-oid> <new-oid> <ref>)
|
|
|
|
|
// S: ... ...
|
|
|
|
|
// S: flush-pkt
|
|
|
|
|
// # [receive push-options]
|
|
|
|
|
// S: PKT-LINE(push-option)
|
|
|
|
|
// S: ... ...
|
|
|
|
|
// S: flush-pkt
|
|
|
|
|
hookOptions := private.HookOptions{
|
|
|
|
|
UserName: pusherName,
|
|
|
|
|
UserID: pusherID,
|
|
|
|
|
}
|
|
|
|
|
hookOptions.OldCommitIDs = make([]string, 0, hookBatchSize)
|
|
|
|
|
hookOptions.NewCommitIDs = make([]string, 0, hookBatchSize)
|
2023-05-26 01:04:48 +00:00
|
|
|
|
hookOptions.RefFullNames = make([]git.RefName, 0, hookBatchSize)
|
2021-07-28 09:42:56 +00:00
|
|
|
|
|
|
|
|
|
for {
|
|
|
|
|
// note: pktLineTypeUnknow means pktLineTypeFlush and pktLineTypeData all allowed
|
2024-03-28 23:20:21 +00:00
|
|
|
|
rs, err = readPktLine(ctx, reader, pktLineTypeUnknown)
|
2021-07-28 09:42:56 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if rs.Type == pktLineTypeFlush {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
t := strings.SplitN(string(rs.Data), " ", 3)
|
|
|
|
|
if len(t) != 3 {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
hookOptions.OldCommitIDs = append(hookOptions.OldCommitIDs, t[0])
|
|
|
|
|
hookOptions.NewCommitIDs = append(hookOptions.NewCommitIDs, t[1])
|
2023-05-26 01:04:48 +00:00
|
|
|
|
hookOptions.RefFullNames = append(hookOptions.RefFullNames, git.RefName(t[2]))
|
2021-07-28 09:42:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hookOptions.GitPushOptions = make(map[string]string)
|
|
|
|
|
|
|
|
|
|
if hasPushOptions {
|
|
|
|
|
for {
|
2024-03-28 23:20:21 +00:00
|
|
|
|
rs, err = readPktLine(ctx, reader, pktLineTypeUnknown)
|
2021-07-28 09:42:56 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if rs.Type == pktLineTypeFlush {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-03 00:41:57 +00:00
|
|
|
|
key, value, found := strings.Cut(string(rs.Data), "=")
|
|
|
|
|
if !found {
|
|
|
|
|
value = "true"
|
2021-07-28 09:42:56 +00:00
|
|
|
|
}
|
2024-04-03 00:41:57 +00:00
|
|
|
|
hookOptions.GitPushOptions[key] = value
|
2021-07-28 09:42:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 3. run hook
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
resp, extra := private.HookProcReceive(ctx, repoUser, repoName, hookOptions)
|
|
|
|
|
if extra.HasError() {
|
|
|
|
|
return fail(ctx, extra.UserMsg, "HookProcReceive failed: %v", extra.Error)
|
2021-07-28 09:42:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 4. response result to service
|
|
|
|
|
// # a. OK, but has an alternate reference. The alternate reference name
|
|
|
|
|
// # and other status can be given in option directives.
|
|
|
|
|
// H: PKT-LINE(ok <ref>)
|
|
|
|
|
// H: PKT-LINE(option refname <refname>)
|
|
|
|
|
// H: PKT-LINE(option old-oid <old-oid>)
|
|
|
|
|
// H: PKT-LINE(option new-oid <new-oid>)
|
|
|
|
|
// H: PKT-LINE(option forced-update)
|
|
|
|
|
// H: ... ...
|
|
|
|
|
// H: flush-pkt
|
|
|
|
|
// # b. NO, I reject it.
|
|
|
|
|
// H: PKT-LINE(ng <ref> <reason>)
|
|
|
|
|
// # c. Fall through, let 'receive-pack' to execute it.
|
|
|
|
|
// H: PKT-LINE(ok <ref>)
|
|
|
|
|
// H: PKT-LINE(option fall-through)
|
|
|
|
|
|
|
|
|
|
for _, rs := range resp.Results {
|
|
|
|
|
if len(rs.Err) > 0 {
|
2023-05-26 01:04:48 +00:00
|
|
|
|
err = writeDataPktLine(ctx, os.Stdout, []byte("ng "+rs.OriginalRef.String()+" "+rs.Err))
|
2021-07-28 09:42:56 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if rs.IsNotMatched {
|
2023-05-26 01:04:48 +00:00
|
|
|
|
err = writeDataPktLine(ctx, os.Stdout, []byte("ok "+rs.OriginalRef.String()))
|
2021-07-28 09:42:56 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
err = writeDataPktLine(ctx, os.Stdout, []byte("option fall-through"))
|
2021-07-28 09:42:56 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
err = writeDataPktLine(ctx, os.Stdout, []byte("ok "+rs.OriginalRef))
|
2021-07-28 09:42:56 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
err = writeDataPktLine(ctx, os.Stdout, []byte("option refname "+rs.Ref))
|
2021-07-28 09:42:56 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2023-12-19 07:20:47 +00:00
|
|
|
|
commitID, _ := git.NewIDFromString(rs.OldOID)
|
2023-12-13 21:02:00 +00:00
|
|
|
|
if !commitID.IsZero() {
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
err = writeDataPktLine(ctx, os.Stdout, []byte("option old-oid "+rs.OldOID))
|
2021-07-28 09:42:56 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
err = writeDataPktLine(ctx, os.Stdout, []byte("option new-oid "+rs.NewOID))
|
2021-07-28 09:42:56 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if rs.IsForcePush {
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
err = writeDataPktLine(ctx, os.Stdout, []byte("option forced-update"))
|
2021-07-28 09:42:56 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
err = writeFlushPktLine(ctx, os.Stdout)
|
2021-07-28 09:42:56 +00:00
|
|
|
|
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// git PKT-Line api
|
|
|
|
|
// pktLineType message type of pkt-line
|
|
|
|
|
type pktLineType int64
|
|
|
|
|
|
|
|
|
|
const (
|
2024-03-28 23:20:21 +00:00
|
|
|
|
// Unknown type
|
|
|
|
|
pktLineTypeUnknown pktLineType = 0
|
2021-07-28 09:42:56 +00:00
|
|
|
|
// flush-pkt "0000"
|
|
|
|
|
pktLineTypeFlush pktLineType = iota
|
|
|
|
|
// data line
|
|
|
|
|
pktLineTypeData
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// gitPktLine pkt-line api
|
|
|
|
|
type gitPktLine struct {
|
|
|
|
|
Type pktLineType
|
|
|
|
|
Length uint64
|
|
|
|
|
Data []byte
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-28 23:20:21 +00:00
|
|
|
|
// Reads an Pkt-Line from `in`. If requestType is not unknown, it will a
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
func readPktLine(ctx context.Context, in *bufio.Reader, requestType pktLineType) (*gitPktLine, error) {
|
2024-03-28 23:20:21 +00:00
|
|
|
|
// Read length prefix
|
2021-07-28 09:42:56 +00:00
|
|
|
|
lengthBytes := make([]byte, 4)
|
2024-03-28 23:20:21 +00:00
|
|
|
|
if n, err := in.Read(lengthBytes); n != 4 || err != nil {
|
|
|
|
|
return nil, fail(ctx, "Protocol: stdin error", "Pkt-Line: read stdin failed : %v", err)
|
2021-07-28 09:42:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-28 23:20:21 +00:00
|
|
|
|
var err error
|
|
|
|
|
r := &gitPktLine{}
|
2021-07-28 09:42:56 +00:00
|
|
|
|
r.Length, err = strconv.ParseUint(string(lengthBytes), 16, 32)
|
|
|
|
|
if err != nil {
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
return nil, fail(ctx, "Protocol: format parse error", "Pkt-Line format is wrong :%v", err)
|
2021-07-28 09:42:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if r.Length == 0 {
|
|
|
|
|
if requestType == pktLineTypeData {
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
return nil, fail(ctx, "Protocol: format data error", "Pkt-Line format is wrong")
|
2021-07-28 09:42:56 +00:00
|
|
|
|
}
|
|
|
|
|
r.Type = pktLineTypeFlush
|
|
|
|
|
return r, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if r.Length <= 4 || r.Length > 65520 || requestType == pktLineTypeFlush {
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
return nil, fail(ctx, "Protocol: format length error", "Pkt-Line format is wrong")
|
2021-07-28 09:42:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r.Data = make([]byte, r.Length-4)
|
2024-03-28 23:20:21 +00:00
|
|
|
|
if n, err := io.ReadFull(in, r.Data); uint64(n) != r.Length-4 || err != nil {
|
|
|
|
|
return nil, fail(ctx, "Protocol: stdin error", "Pkt-Line: read stdin failed : %v", err)
|
2021-07-28 09:42:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r.Type = pktLineTypeData
|
|
|
|
|
|
|
|
|
|
return r, nil
|
|
|
|
|
}
|
|
|
|
|
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
func writeFlushPktLine(ctx context.Context, out io.Writer) error {
|
2021-07-28 09:42:56 +00:00
|
|
|
|
l, err := out.Write([]byte("0000"))
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
if err != nil || l != 4 {
|
|
|
|
|
return fail(ctx, "Protocol: write error", "Pkt-Line response failed: %v", err)
|
2021-07-28 09:42:56 +00:00
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-28 23:20:21 +00:00
|
|
|
|
// Write an Pkt-Line based on `data` to `out` according to the specifcation.
|
|
|
|
|
// https://git-scm.com/docs/protocol-common
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
func writeDataPktLine(ctx context.Context, out io.Writer, data []byte) error {
|
2024-03-28 23:20:21 +00:00
|
|
|
|
// Implementations SHOULD NOT send an empty pkt-line ("0004").
|
|
|
|
|
if len(data) == 0 {
|
|
|
|
|
return fail(ctx, "Protocol: write error", "Not allowed to write empty Pkt-Line")
|
2021-07-28 09:42:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
length := uint64(len(data) + 4)
|
|
|
|
|
|
2024-03-28 23:20:21 +00:00
|
|
|
|
// The maximum length of a pkt-line’s data component is 65516 bytes.
|
|
|
|
|
// Implementations MUST NOT send pkt-line whose length exceeds 65520 (65516 bytes of payload + 4 bytes of length data).
|
|
|
|
|
if length > 65520 {
|
|
|
|
|
return fail(ctx, "Protocol: write error", "Pkt-Line exceeds maximum of 65520 bytes")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lr, err := fmt.Fprintf(out, "%04x", length)
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
if err != nil || lr != 4 {
|
|
|
|
|
return fail(ctx, "Protocol: write error", "Pkt-Line response failed: %v", err)
|
2021-07-28 09:42:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lr, err = out.Write(data)
|
Refactor internal API for git commands, use meaningful messages instead of "Internal Server Error" (#23687)
# Why this PR comes
At first, I'd like to help users like #23636 (there are a lot)
The unclear "Internal Server Error" is quite anonying, scare users,
frustrate contributors, nobody knows what happens.
So, it's always good to provide meaningful messages to end users (of
course, do not leak sensitive information).
When I started working on the "response message to end users", I found
that the related code has a lot of technical debt. A lot of copy&paste
code, unclear fields and usages.
So I think it's good to make everything clear.
# Tech Backgrounds
Gitea has many sub-commands, some are used by admins, some are used by
SSH servers or Git Hooks. Many sub-commands use "internal API" to
communicate with Gitea web server.
Before, Gitea server always use `StatusCode + Json "err" field` to
return messages.
* The CLI sub-commands: they expect to show all error related messages
to site admin
* The Serv/Hook sub-commands (for git clients): they could only show
safe messages to end users, the error log could only be recorded by
"SSHLog" to Gitea web server.
In the old design, it assumes that:
* If the StatusCode is 500 (in some functions), then the "err" field is
error log, shouldn't be exposed to git client.
* If the StatusCode is 40x, then the "err" field could be exposed. And
some functions always read the "err" no matter what the StatusCode is.
The old code is not strict, and it's difficult to distinguish the
messages clearly and then output them correctly.
# This PR
To help to remove duplicate code and make everything clear, this PR
introduces `ResponseExtra` and `requestJSONResp`.
* `ResponseExtra` is a struct which contains "extra" information of a
internal API response, including StatusCode, UserMsg, Error
* `requestJSONResp` is a generic function which can be used for all
cases to help to simplify the calls.
* Remove all `map["err"]`, always use `private.Response{Err}` to
construct error messages.
* User messages and error messages are separated clearly, the `fail` and
`handleCliResponseExtra` will output correct messages.
* Replace all `Internal Server Error` messages with meaningful (still
safe) messages.
This PR saves more than 300 lines, while makes the git client messages
more clear.
Many gitea-serv/git-hook related essential functions are covered by
tests.
---------
Co-authored-by: delvh <dev.lh@web.de>
2023-03-29 06:32:26 +00:00
|
|
|
|
if err != nil || int(length-4) != lr {
|
|
|
|
|
return fail(ctx, "Protocol: write error", "Pkt-Line response failed: %v", err)
|
2021-07-28 09:42:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|