Compare commits

..

6 Commits

Author SHA1 Message Date
Giteabot
a926994bfe
Re-add accidentally removed hacking-on-gitea.zh-cn.md (#23297) (#23305) 2023-03-04 20:09:58 -05:00
Giteabot
83903535e3
Fix code wrap for unbroken lines (#23268) (#23293)
Backport #23268

## The Problem

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

## Before


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

## After


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

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

Just like what has been done when pushing manually:

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

Before:

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

After:

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

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

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

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

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

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

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

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

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

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

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

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

`path.Dir` in

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

Fixes #23151

Co-authored-by: yp05327 <576951401@qq.com>
Co-authored-by: Jason Song <i@wolfogre.com>
Co-authored-by: John Olheiser <john.olheiser@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2023-03-04 00:38:11 -05:00
16 changed files with 128 additions and 20 deletions

View File

@ -0,0 +1,43 @@
---
date: "2016-12-01T16:00:00+02:00"
title: "加入 Gitea 开源"
slug: "hacking-on-gitea"
weight: 10
toc: false
draft: false
menu:
sidebar:
parent: "developers"
name: "加入 Gitea 开源"
weight: 10
identifier: "hacking-on-gitea"
---
# Hacking on Gitea
首先你需要一些运行环境,这和 [从源代码安装]({{< relref "doc/installation/from-source.zh-cn.md" >}}) 相同,如果你还没有设置好,可以先阅读那个章节。
如果你想为 Gitea 贡献代码,你需要 Fork 这个项目并且以 `master` 为开发分支。Gitea 使用 Govendor
来管理依赖,因此所有依赖项都被工具自动 copy 在 vendor 子目录下。用下面的命令来下载源码:
```
go get -d code.gitea.io/gitea
```
然后你可以在 Github 上 fork [Gitea 项目](https://github.com/go-gitea/gitea),之后可以通过下面的命令进入源码目录:
```
cd $GOPATH/src/code.gitea.io/gitea
```
要创建 pull requests 你还需要在源码中新增一个 remote 指向你 Fork 的地址,直接推送到 origin 的话会告诉你没有写权限:
```
git remote rename origin upstream
git remote add origin git@github.com:<USERNAME>/gitea.git
git fetch --all --prune
```
然后你就可以开始开发了。你可以看一下 `Makefile` 的内容。`make test` 可以运行测试程序, `make build` 将生成一个 `gitea` 可运行文件在根目录。如果你的提交比较复杂,尽量多写一些单元测试代码。
好了,到这里你已经设置好了所有的开发 Gitea 所需的环境。欢迎成为 Gitea 的 Contributor。

View File

@ -25,7 +25,7 @@
fork_id: 0 fork_id: 0
is_template: false is_template: false
template_id: 0 template_id: 0
size: 6708 size: 7028
is_fsck_enabled: true is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false close_issues_via_commit_in_any_branch: false

View File

@ -277,11 +277,18 @@ func (repo *Repository) GetPatch(base, head string, w io.Writer) error {
// GetFilesChangedBetween returns a list of all files that have been changed between the given commits // GetFilesChangedBetween returns a list of all files that have been changed between the given commits
func (repo *Repository) GetFilesChangedBetween(base, head string) ([]string, error) { func (repo *Repository) GetFilesChangedBetween(base, head string) ([]string, error) {
stdout, _, err := NewCommand(repo.Ctx, "diff", "--name-only").AddDynamicArguments(base + ".." + head).RunStdString(&RunOpts{Dir: repo.Path}) stdout, _, err := NewCommand(repo.Ctx, "diff", "--name-only", "-z").AddDynamicArguments(base + ".." + head).RunStdString(&RunOpts{Dir: repo.Path})
if err != nil { if err != nil {
return nil, err return nil, err
} }
return strings.Split(stdout, "\n"), err split := strings.Split(stdout, "\000")
// Because Git will always emit filenames with a terminal NUL ignore the last entry in the split - which will always be empty.
if len(split) > 0 {
split = split[:len(split)-1]
}
return split, err
} }
// GetDiffFromMergeBase generates and return patch data from merge base to head // GetDiffFromMergeBase generates and return patch data from merge base to head

View File

@ -150,7 +150,7 @@ func (s *Service) UpdateTask(
} }
if err := actions_service.CreateCommitStatus(ctx, task.Job); err != nil { if err := actions_service.CreateCommitStatus(ctx, task.Job); err != nil {
log.Error("Update commit status failed: %v", err) log.Error("Update commit status for job %v failed: %v", task.Job.ID, err)
// go on // go on
} }

View File

@ -15,6 +15,7 @@ import (
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/actions" "code.gitea.io/gitea/modules/actions"
context_module "code.gitea.io/gitea/modules/context" context_module "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web"
@ -207,15 +208,18 @@ func Rerun(ctx *context_module.Context) {
job.Stopped = 0 job.Stopped = 0
if err := db.WithTx(ctx, func(ctx context.Context) error { if err := db.WithTx(ctx, func(ctx context.Context) error {
if _, err := actions_model.UpdateRunJob(ctx, job, builder.Eq{"status": status}, "task_id", "status", "started", "stopped"); err != nil { _, err := actions_model.UpdateRunJob(ctx, job, builder.Eq{"status": status}, "task_id", "status", "started", "stopped")
return err return err
}
return actions_service.CreateCommitStatus(ctx, job)
}); err != nil { }); err != nil {
ctx.Error(http.StatusInternalServerError, err.Error()) ctx.Error(http.StatusInternalServerError, err.Error())
return return
} }
if err := actions_service.CreateCommitStatus(ctx, job); err != nil {
log.Error("Update commit status for job %v failed: %v", job.ID, err)
// go on
}
ctx.JSON(http.StatusOK, struct{}{}) ctx.JSON(http.StatusOK, struct{}{})
} }
@ -248,9 +252,6 @@ func Cancel(ctx *context_module.Context) {
if err := actions_model.StopTask(ctx, job.TaskID, actions_model.StatusCancelled); err != nil { if err := actions_model.StopTask(ctx, job.TaskID, actions_model.StatusCancelled); err != nil {
return err return err
} }
if err := actions_service.CreateCommitStatus(ctx, job); err != nil {
return err
}
} }
return nil return nil
}); err != nil { }); err != nil {
@ -258,6 +259,13 @@ func Cancel(ctx *context_module.Context) {
return return
} }
for _, job := range jobs {
if err := actions_service.CreateCommitStatus(ctx, job); err != nil {
log.Error("Update commit status for job %v failed: %v", job.ID, err)
// go on
}
}
ctx.JSON(http.StatusOK, struct{}{}) ctx.JSON(http.StatusOK, struct{}{})
} }

View File

@ -186,7 +186,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
return return
} }
renderReadmeFile(ctx, readmeFile, treeLink) renderReadmeFile(ctx, readmeFile, fmt.Sprintf("%s/%s", treeLink, readmeFile.name))
} }
// localizedExtensions prepends the provided language code with and without a // localizedExtensions prepends the provided language code with and without a

View File

@ -43,6 +43,7 @@ func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error {
return fmt.Errorf("find tasks: %w", err) return fmt.Errorf("find tasks: %w", err)
} }
jobs := make([]*actions_model.ActionRunJob, 0, len(tasks))
for _, task := range tasks { for _, task := range tasks {
if err := db.WithTx(ctx, func(ctx context.Context) error { if err := db.WithTx(ctx, func(ctx context.Context) error {
if err := actions_model.StopTask(ctx, task.ID, actions_model.StatusFailure); err != nil { if err := actions_model.StopTask(ctx, task.ID, actions_model.StatusFailure); err != nil {
@ -51,7 +52,8 @@ func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error {
if err := task.LoadJob(ctx); err != nil { if err := task.LoadJob(ctx); err != nil {
return err return err
} }
return CreateCommitStatus(ctx, task.Job) jobs = append(jobs, task.Job)
return nil
}); err != nil { }); err != nil {
log.Warn("Cannot stop task %v: %v", task.ID, err) log.Warn("Cannot stop task %v: %v", task.ID, err)
// go on // go on
@ -61,6 +63,14 @@ func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error {
remove() remove()
} }
} }
for _, job := range jobs {
if err := CreateCommitStatus(ctx, job); err != nil {
log.Error("Update commit status for job %v failed: %v", job.ID, err)
// go on
}
}
return nil return nil
} }
@ -80,14 +90,16 @@ func CancelAbandonedJobs(ctx context.Context) error {
job.Status = actions_model.StatusCancelled job.Status = actions_model.StatusCancelled
job.Stopped = now job.Stopped = now
if err := db.WithTx(ctx, func(ctx context.Context) error { if err := db.WithTx(ctx, func(ctx context.Context) error {
if _, err := actions_model.UpdateRunJob(ctx, job, nil, "status", "stopped"); err != nil { _, err := actions_model.UpdateRunJob(ctx, job, nil, "status", "stopped")
return err return err
}
return CreateCommitStatus(ctx, job)
}); err != nil { }); err != nil {
log.Warn("cancel abandoned job %v: %v", job.ID, err) log.Warn("cancel abandoned job %v: %v", job.ID, err)
// go on // go on
} }
if err := CreateCommitStatus(ctx, job); err != nil {
log.Error("Update commit status for job %v failed: %v", job.ID, err)
// go on
}
} }
return nil return nil

View File

@ -30,6 +30,16 @@ func CreateCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er
return fmt.Errorf("GetPushEventPayload: %w", err) return fmt.Errorf("GetPushEventPayload: %w", err)
} }
// Since the payload comes from json data, we should check if it's broken, or it will cause panic
switch {
case payload.Repo == nil:
return fmt.Errorf("repo is missing in event payload")
case payload.Pusher == nil:
return fmt.Errorf("pusher is missing in event payload")
case payload.HeadCommit == nil:
return fmt.Errorf("head commit is missing in event payload")
}
creator, err := user_model.GetUserByID(ctx, payload.Pusher.ID) creator, err := user_model.GetUserByID(ctx, payload.Pusher.ID)
if err != nil { if err != nil {
return fmt.Errorf("GetUserByID: %w", err) return fmt.Errorf("GetUserByID: %w", err)

View File

@ -180,7 +180,8 @@ func notify(ctx context.Context, input *notifyInput) error {
} else { } else {
for _, job := range jobs { for _, job := range jobs {
if err := CreateCommitStatus(ctx, job); err != nil { if err := CreateCommitStatus(ctx, job); err != nil {
log.Error("CreateCommitStatus: %v", err) log.Error("Update commit status for job %v failed: %v", job.ID, err)
// go on
} }
} }
} }

View File

@ -499,6 +499,13 @@ func SyncPullMirror(ctx context.Context, repoID int64) bool {
theCommits.Commits = theCommits.Commits[:setting.UI.FeedMaxCommitNum] theCommits.Commits = theCommits.Commits[:setting.UI.FeedMaxCommitNum]
} }
if newCommit, err := gitRepo.GetCommit(newCommitID); err != nil {
log.Error("SyncMirrors [repo: %-v]: unable to get commit %s: %v", m.Repo, newCommitID, err)
continue
} else {
theCommits.HeadCommit = repo_module.CommitToPushCommit(newCommit)
}
theCommits.CompareURL = m.Repo.ComposeCompareURL(oldCommitID, newCommitID) theCommits.CompareURL = m.Repo.ComposeCompareURL(oldCommitID, newCommitID)
notification.NotifySyncPushCommits(ctx, m.Repo.MustOwner(ctx), m.Repo, &repo_module.PushUpdateOptions{ notification.NotifySyncPushCommits(ctx, m.Repo.MustOwner(ctx), m.Repo, &repo_module.PushUpdateOptions{

View File

@ -0,0 +1 @@
78fb907e3a3309eae4fe8fef030874cebbf1cd5e

View File

@ -256,3 +256,23 @@ func TestViewRepoDirectory(t *testing.T) {
assert.Zero(t, repoTopics.Length()) assert.Zero(t, repoTopics.Length())
assert.Zero(t, repoSummary.Length()) assert.Zero(t, repoSummary.Length())
} }
func TestMarkDownImage(t *testing.T) {
defer tests.PrepareTestEnv(t)()
session := loginUser(t, "user2")
req := NewRequest(t, "GET", "/user2/repo1/src/branch/home-md-img-check")
resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
_, exists := htmlDoc.doc.Find(`img[src="/user2/repo1/media/branch/home-md-img-check/test-fake-img.jpg"]`).Attr("src")
assert.True(t, exists, "Repo home page markdown image link check failed")
req = NewRequest(t, "GET", "/user2/repo1/src/branch/home-md-img-check/README.md")
resp = session.MakeRequest(t, req, http.StatusOK)
htmlDoc = NewHTMLParser(t, resp.Body)
_, exists = htmlDoc.doc.Find(`img[src="/user2/repo1/media/branch/home-md-img-check/test-fake-img.jpg"]`).Attr("src")
assert.True(t, exists, "Repo src page markdown image link check failed")
}

View File

@ -2121,8 +2121,7 @@ a.ui.label:hover {
font: 12px var(--fonts-monospace); font: 12px var(--fonts-monospace);
white-space: pre-wrap; white-space: pre-wrap;
word-break: break-all; word-break: break-all;
overflow-wrap: break-word; overflow-wrap: anywhere;
word-wrap: break-word;
} }
.blame .code-inner { .blame .code-inner {