mirror of
https://github.com/go-gitea/gitea.git
synced 2025-07-17 00:01:00 -04:00
Compare commits
4 Commits
d6cf261be8
...
2bdc38e592
Author | SHA1 | Date | |
---|---|---|---|
|
2bdc38e592 | ||
|
f155cf60d3 | ||
|
0f5e07f538 | ||
|
368e9e0f1b |
@ -17,16 +17,20 @@ menu:
|
||||
|
||||
# Upgrade from an old Gitea
|
||||
|
||||
To update Gitea, download a newer version, stop the old one, perform a backup, and run the new one.
|
||||
Every time a Gitea instance starts up, it checks whether a database migration should be run.
|
||||
If a database migration is required, Gitea will take some time to complete the upgrade and then serve.
|
||||
Follow below steps to ensure a smooth upgrade to a new Gitea version.
|
||||
|
||||
## Check the Changelog for breaking changes
|
||||
|
||||
To make Gitea better, some breaking changes are unavoidable, especially for big milestone releases.
|
||||
Before upgrade, please read the [Changelog on Gitea blog](https://blog.gitea.io/)
|
||||
Before upgrading, please read the [Changelog on Gitea blog](https://blog.gitea.com/)
|
||||
and check whether the breaking changes affect your Gitea instance.
|
||||
|
||||
## Verify there are no deprecated configuration options
|
||||
|
||||
New versions of Gitea often come with changed configuration syntax or options which are usually displayed for
|
||||
at least one release cycle inside at the top of the Site Administration panel. If these warnings are not
|
||||
resolved, Gitea may refuse to start in the following version.
|
||||
|
||||
## Backup for downgrade
|
||||
|
||||
Gitea keeps compatibility for patch versions whose first two fields are the same (`a.b.x` -> `a.b.y`),
|
||||
@ -60,6 +64,11 @@ Backup steps:
|
||||
If you are using cloud services or filesystems with snapshot feature,
|
||||
a snapshot for the Gitea data volume and related object storage is more convenient.
|
||||
|
||||
After all of steps have been prepared, download the new version, stop the application, perform a backup and
|
||||
then start the new application. On each startup, Gitea verifies that the database is up to date and will automtically
|
||||
perform any necessary migrations. Depending on the size of the database, this can take some additional time on the
|
||||
first launch during which the application will be unavailable.
|
||||
|
||||
## Upgrade with Docker
|
||||
|
||||
* `docker pull` the latest Gitea release.
|
||||
|
@ -15,16 +15,20 @@ menu:
|
||||
|
||||
# 从旧版 Gitea 升级
|
||||
|
||||
想要升级 Gitea,只需要下载新版,停止运行旧版,进行数据备份,然后运行新版就好。
|
||||
每次 Gitea 实例启动时,它都会检查是否要进行数据库迁移。
|
||||
如果需要进行数据库迁移,Gitea 会花一些时间完成升级然后继续服务。
|
||||
在升级之前,您需要做如下的准备工作。
|
||||
|
||||
## 为重大变更检查更新日志
|
||||
|
||||
为了让 Gitea 变得更好,进行重大变更是不可避免的,尤其是一些里程碑更新的发布。
|
||||
在更新前,请 [在 Gitea 博客上阅读更新日志](https://blog.gitea.io/)
|
||||
在更新前,请 [在 Gitea 博客上阅读更新日志](https://blog.gitea.com/)
|
||||
并检查重大变更是否会影响你的 Gitea 实例。
|
||||
|
||||
## 在控制面板中检查过期的配置项
|
||||
|
||||
一些配置项可能会在后续版本中过期,你需要在控制面板中检查他们。如果不解决过期的配置项,
|
||||
Gitea也许会在升级后无法重启。你可以访问 https://docs.gitea.com 获得要升级的版本
|
||||
对应的文档来修改你的配置文件。
|
||||
|
||||
## 降级前的备份
|
||||
|
||||
Gitea 会保留首二位版本号相同的版本的兼容性 (`a.b.x` -> `a.b.y`),
|
||||
@ -56,6 +60,10 @@ Gitea 会保留首二位版本号相同的版本的兼容性 (`a.b.x` -> `a.b.y`
|
||||
如果你在使用云服务或拥有快照功能的文件系统,
|
||||
最好对 Gitea 的数据盘及相关资料存储进行一次快照。
|
||||
|
||||
在所有上述步骤准备妥当之后,要升级 Gitea,只需要下载新版,停止运行旧版,进行数据备份,然后运行新版就好。
|
||||
每次 Gitea 实例启动时,它都会检查是否要进行数据库迁移。
|
||||
如果需要进行数据库迁移,Gitea 会花一些时间完成升级然后继续服务。
|
||||
|
||||
## 从 Docker 升级
|
||||
|
||||
* `docker pull` 拉取 Gitea 的最新发布版。
|
||||
|
@ -531,13 +531,12 @@ func (pr *PullRequest) SetMerged(ctx context.Context) (bool, error) {
|
||||
}
|
||||
|
||||
// NewPullRequest creates new pull request with labels for repository.
|
||||
func NewPullRequest(outerCtx context.Context, repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string, pr *PullRequest) (err error) {
|
||||
ctx, committer, err := db.TxContext(outerCtx)
|
||||
func NewPullRequest(ctx context.Context, repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string, pr *PullRequest) (err error) {
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer committer.Close()
|
||||
ctx.WithContext(outerCtx)
|
||||
|
||||
idx, err := db.GetNextResourceIndex(ctx, "issue_index", repo.ID)
|
||||
if err != nil {
|
||||
|
@ -87,14 +87,14 @@ func TestLoadRequestedReviewers(t *testing.T) {
|
||||
user1, err := user_model.GetUserByID(db.DefaultContext, 1)
|
||||
assert.NoError(t, err)
|
||||
|
||||
comment, err := issues_model.AddReviewRequest(issue, user1, &user_model.User{})
|
||||
comment, err := issues_model.AddReviewRequest(db.DefaultContext, issue, user1, &user_model.User{})
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, comment)
|
||||
|
||||
assert.NoError(t, pull.LoadRequestedReviewers(db.DefaultContext))
|
||||
assert.Len(t, pull.RequestedReviewers, 1)
|
||||
|
||||
comment, err = issues_model.RemoveReviewRequest(issue, user1, &user_model.User{})
|
||||
comment, err = issues_model.RemoveReviewRequest(db.DefaultContext, issue, user1, &user_model.User{})
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, comment)
|
||||
|
||||
|
@ -557,8 +557,8 @@ func InsertReviews(reviews []*Review) error {
|
||||
}
|
||||
|
||||
// AddReviewRequest add a review request from one reviewer
|
||||
func AddReviewRequest(issue *Issue, reviewer, doer *user_model.User) (*Comment, error) {
|
||||
ctx, committer, err := db.TxContext(db.DefaultContext)
|
||||
func AddReviewRequest(ctx context.Context, issue *Issue, reviewer, doer *user_model.User) (*Comment, error) {
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -612,8 +612,8 @@ func AddReviewRequest(issue *Issue, reviewer, doer *user_model.User) (*Comment,
|
||||
}
|
||||
|
||||
// RemoveReviewRequest remove a review request from one reviewer
|
||||
func RemoveReviewRequest(issue *Issue, reviewer, doer *user_model.User) (*Comment, error) {
|
||||
ctx, committer, err := db.TxContext(db.DefaultContext)
|
||||
func RemoveReviewRequest(ctx context.Context, issue *Issue, reviewer, doer *user_model.User) (*Comment, error) {
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -673,8 +673,8 @@ func restoreLatestOfficialReview(ctx context.Context, issueID, reviewerID int64)
|
||||
}
|
||||
|
||||
// AddTeamReviewRequest add a review request from one team
|
||||
func AddTeamReviewRequest(issue *Issue, reviewer *organization.Team, doer *user_model.User) (*Comment, error) {
|
||||
ctx, committer, err := db.TxContext(db.DefaultContext)
|
||||
func AddTeamReviewRequest(ctx context.Context, issue *Issue, reviewer *organization.Team, doer *user_model.User) (*Comment, error) {
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -732,8 +732,8 @@ func AddTeamReviewRequest(issue *Issue, reviewer *organization.Team, doer *user_
|
||||
}
|
||||
|
||||
// RemoveTeamReviewRequest remove a review request from one team
|
||||
func RemoveTeamReviewRequest(issue *Issue, reviewer *organization.Team, doer *user_model.User) (*Comment, error) {
|
||||
ctx, committer, err := db.TxContext(db.DefaultContext)
|
||||
func RemoveTeamReviewRequest(ctx context.Context, issue *Issue, reviewer *organization.Team, doer *user_model.User) (*Comment, error) {
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -2226,7 +2226,7 @@ func UpdateIssueAssignee(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
_, _, err = issue_service.ToggleAssignee(ctx, issue, ctx.Doer, assigneeID)
|
||||
_, _, err = issue_service.ToggleAssigneeWithNotify(ctx, issue, ctx.Doer, assigneeID)
|
||||
if err != nil {
|
||||
ctx.ServerError("ToggleAssignee", err)
|
||||
return
|
||||
|
@ -115,6 +115,7 @@ func Profile(ctx *context.Context) {
|
||||
profileContent, err := markdown.RenderString(&markup.RenderContext{
|
||||
Ctx: ctx,
|
||||
GitRepo: gitRepo,
|
||||
Metas: map[string]string{"mode": "document"},
|
||||
}, bytes)
|
||||
if err != nil {
|
||||
ctx.ServerError("RenderString", err)
|
||||
|
@ -33,7 +33,7 @@ func DeleteNotPassedAssignee(ctx context.Context, issue *issues_model.Issue, doe
|
||||
|
||||
if !found {
|
||||
// This function also does comments and hooks, which is why we call it separately instead of directly removing the assignees here
|
||||
if _, _, err := ToggleAssignee(ctx, issue, doer, assignee.ID); err != nil {
|
||||
if _, _, err := ToggleAssigneeWithNotify(ctx, issue, doer, assignee.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -42,8 +42,8 @@ func DeleteNotPassedAssignee(ctx context.Context, issue *issues_model.Issue, doe
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToggleAssignee changes a user between assigned and not assigned for this issue, and make issue comment for it.
|
||||
func ToggleAssignee(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, assigneeID int64) (removed bool, comment *issues_model.Comment, err error) {
|
||||
// ToggleAssigneeWithNoNotify changes a user between assigned and not assigned for this issue, and make issue comment for it.
|
||||
func ToggleAssigneeWithNotify(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, assigneeID int64) (removed bool, comment *issues_model.Comment, err error) {
|
||||
removed, comment, err = issues_model.ToggleIssueAssignee(ctx, issue, doer, assigneeID)
|
||||
if err != nil {
|
||||
return
|
||||
@ -63,9 +63,9 @@ func ToggleAssignee(ctx context.Context, issue *issues_model.Issue, doer *user_m
|
||||
// ReviewRequest add or remove a review request from a user for this PR, and make comment for it.
|
||||
func ReviewRequest(ctx context.Context, issue *issues_model.Issue, doer, reviewer *user_model.User, isAdd bool) (comment *issues_model.Comment, err error) {
|
||||
if isAdd {
|
||||
comment, err = issues_model.AddReviewRequest(issue, reviewer, doer)
|
||||
comment, err = issues_model.AddReviewRequest(ctx, issue, reviewer, doer)
|
||||
} else {
|
||||
comment, err = issues_model.RemoveReviewRequest(issue, reviewer, doer)
|
||||
comment, err = issues_model.RemoveReviewRequest(ctx, issue, reviewer, doer)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@ -230,9 +230,9 @@ func IsValidTeamReviewRequest(ctx context.Context, reviewer *organization.Team,
|
||||
// TeamReviewRequest add or remove a review request from a team for this PR, and make comment for it.
|
||||
func TeamReviewRequest(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, reviewer *organization.Team, isAdd bool) (comment *issues_model.Comment, err error) {
|
||||
if isAdd {
|
||||
comment, err = issues_model.AddTeamReviewRequest(issue, reviewer, doer)
|
||||
comment, err = issues_model.AddTeamReviewRequest(ctx, issue, reviewer, doer)
|
||||
} else {
|
||||
comment, err = issues_model.RemoveTeamReviewRequest(issue, reviewer, doer)
|
||||
comment, err = issues_model.RemoveTeamReviewRequest(ctx, issue, reviewer, doer)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
@ -27,7 +27,7 @@ func NewIssue(ctx context.Context, repo *repo_model.Repository, issue *issues_mo
|
||||
}
|
||||
|
||||
for _, assigneeID := range assigneeIDs {
|
||||
if err := AddAssigneeIfNotAssigned(ctx, issue, issue.Poster, assigneeID); err != nil {
|
||||
if _, err := AddAssigneeIfNotAssigned(ctx, issue, issue.Poster, assigneeID, true); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -122,7 +122,7 @@ func UpdateAssignees(ctx context.Context, issue *issues_model.Issue, oneAssignee
|
||||
// has access to the repo.
|
||||
for _, assignee := range allNewAssignees {
|
||||
// Extra method to prevent double adding (which would result in removing)
|
||||
err = AddAssigneeIfNotAssigned(ctx, issue, doer, assignee.ID)
|
||||
_, err = AddAssigneeIfNotAssigned(ctx, issue, doer, assignee.ID, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -167,36 +167,36 @@ func DeleteIssue(ctx context.Context, doer *user_model.User, gitRepo *git.Reposi
|
||||
|
||||
// AddAssigneeIfNotAssigned adds an assignee only if he isn't already assigned to the issue.
|
||||
// Also checks for access of assigned user
|
||||
func AddAssigneeIfNotAssigned(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, assigneeID int64) (err error) {
|
||||
func AddAssigneeIfNotAssigned(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, assigneeID int64, notify bool) (comment *issues_model.Comment, err error) {
|
||||
assignee, err := user_model.GetUserByID(ctx, assigneeID)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check if the user is already assigned
|
||||
isAssigned, err := issues_model.IsUserAssignedToIssue(ctx, issue, assignee)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
if isAssigned {
|
||||
// nothing to to
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
valid, err := access_model.CanBeAssigned(ctx, assignee, issue.Repo, issue.IsPull)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
if !valid {
|
||||
return repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: assigneeID, RepoName: issue.Repo.Name}
|
||||
return nil, repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: assigneeID, RepoName: issue.Repo.Name}
|
||||
}
|
||||
|
||||
_, _, err = ToggleAssignee(ctx, issue, doer, assigneeID)
|
||||
if err != nil {
|
||||
return err
|
||||
if notify {
|
||||
_, comment, err = ToggleAssigneeWithNotify(ctx, issue, doer, assigneeID)
|
||||
return comment, err
|
||||
}
|
||||
|
||||
return nil
|
||||
_, comment, err = issues_model.ToggleIssueAssignee(ctx, issue, doer, assigneeID)
|
||||
return comment, err
|
||||
}
|
||||
|
||||
// GetRefEndNamesAndURLs retrieves the ref end names (e.g. refs/heads/branch-name -> branch-name)
|
||||
|
@ -62,14 +62,19 @@ func TestPatch(pr *issues_model.PullRequest) error {
|
||||
ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("TestPatch: %s", pr))
|
||||
defer finished()
|
||||
|
||||
// Clone base repo.
|
||||
prCtx, cancel, err := createTemporaryRepoForPR(ctx, pr)
|
||||
if err != nil {
|
||||
log.Error("createTemporaryRepoForPR %-v: %v", pr, err)
|
||||
if !models.IsErrBranchDoesNotExist(err) {
|
||||
log.Error("CreateTemporaryRepoForPR %-v: %v", pr, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
defer cancel()
|
||||
|
||||
return testPatch(ctx, prCtx, pr)
|
||||
}
|
||||
|
||||
func testPatch(ctx context.Context, prCtx *prContext, pr *issues_model.PullRequest) error {
|
||||
gitRepo, err := git.OpenRepository(ctx, prCtx.tmpBasePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("OpenRepository: %w", err)
|
||||
|
@ -23,7 +23,6 @@ import (
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/notification"
|
||||
"code.gitea.io/gitea/modules/process"
|
||||
repo_module "code.gitea.io/gitea/modules/repository"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/sync"
|
||||
@ -35,73 +34,70 @@ import (
|
||||
var pullWorkingPool = sync.NewExclusivePool()
|
||||
|
||||
// NewPullRequest creates new pull request with labels for repository.
|
||||
func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *issues_model.Issue, labelIDs []int64, uuids []string, pr *issues_model.PullRequest, assigneeIDs []int64) error {
|
||||
if err := TestPatch(pr); err != nil {
|
||||
func NewPullRequest(ctx context.Context, repo *repo_model.Repository, issue *issues_model.Issue, labelIDs []int64, uuids []string, pr *issues_model.PullRequest, assigneeIDs []int64) error {
|
||||
prCtx, cancel, err := createTemporaryRepoForPR(ctx, pr)
|
||||
if err != nil {
|
||||
if !models.IsErrBranchDoesNotExist(err) {
|
||||
log.Error("CreateTemporaryRepoForPR %-v: %v", pr, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
defer cancel()
|
||||
|
||||
if err := testPatch(ctx, prCtx, pr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
divergence, err := GetDiverging(ctx, pr)
|
||||
divergence, err := git.GetDivergingCommits(ctx, prCtx.tmpBasePath, baseBranch, trackingBranch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pr.CommitsAhead = divergence.Ahead
|
||||
pr.CommitsBehind = divergence.Behind
|
||||
|
||||
if err := issues_model.NewPullRequest(ctx, repo, pull, labelIDs, uuids, pr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, assigneeID := range assigneeIDs {
|
||||
if err := issue_service.AddAssigneeIfNotAssigned(ctx, pull, pull.Poster, assigneeID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
pr.Issue = pull
|
||||
pull.PullRequest = pr
|
||||
|
||||
// Now - even if the request context has been cancelled as the PR has been created
|
||||
// in the db and there is no way to cancel that transaction we have to proceed - therefore
|
||||
// create new context and work from there
|
||||
prCtx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("NewPullRequest: %s:%d", repo.FullName(), pr.Index))
|
||||
defer finished()
|
||||
|
||||
if pr.Flow == issues_model.PullRequestFlowGithub {
|
||||
err = PushToBaseRepo(prCtx, pr)
|
||||
} else {
|
||||
err = UpdateRef(prCtx, pr)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mentions, err := issues_model.FindAndUpdateIssueMentions(ctx, pull, pull.Poster, pull.Content)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
notification.NotifyNewPullRequest(prCtx, pr, mentions)
|
||||
if len(pull.Labels) > 0 {
|
||||
notification.NotifyIssueChangeLabels(prCtx, pull.Poster, pull, pull.Labels, nil)
|
||||
}
|
||||
if pull.Milestone != nil {
|
||||
notification.NotifyIssueChangeMilestone(prCtx, pull.Poster, pull, 0)
|
||||
}
|
||||
assigneeCommentMap := make(map[int64]*issues_model.Comment)
|
||||
|
||||
// add first push codes comment
|
||||
baseGitRepo, err := git.OpenRepository(prCtx, pr.BaseRepo.RepoPath())
|
||||
baseGitRepo, err := git.OpenRepository(ctx, pr.BaseRepo.RepoPath())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer baseGitRepo.Close()
|
||||
|
||||
if err := db.WithTx(ctx, func(ctx context.Context) error {
|
||||
if err := issues_model.NewPullRequest(ctx, repo, issue, labelIDs, uuids, pr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, assigneeID := range assigneeIDs {
|
||||
comment, err := issue_service.AddAssigneeIfNotAssigned(ctx, issue, issue.Poster, assigneeID, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
assigneeCommentMap[assigneeID] = comment
|
||||
}
|
||||
|
||||
pr.Issue = issue
|
||||
issue.PullRequest = pr
|
||||
|
||||
if pr.Flow == issues_model.PullRequestFlowGithub {
|
||||
err = PushToBaseRepo(ctx, pr)
|
||||
} else {
|
||||
err = UpdateRef(ctx, pr)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
compareInfo, err := baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(),
|
||||
git.BranchPrefix+pr.BaseBranch, pr.GetGitRefName(), false, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(compareInfo.Commits) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(compareInfo.Commits) > 0 {
|
||||
data := issues_model.PushActionContent{IsForcePush: false}
|
||||
data.CommitIDs = make([]string, 0, len(compareInfo.Commits))
|
||||
for i := len(compareInfo.Commits) - 1; i >= 0; i-- {
|
||||
@ -115,14 +111,47 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *issu
|
||||
|
||||
ops := &issues_model.CreateCommentOptions{
|
||||
Type: issues_model.CommentTypePullRequestPush,
|
||||
Doer: pull.Poster,
|
||||
Doer: issue.Poster,
|
||||
Repo: repo,
|
||||
Issue: pr.Issue,
|
||||
IsForcePush: false,
|
||||
Content: string(dataJSON),
|
||||
}
|
||||
|
||||
_, _ = issue_service.CreateComment(ctx, ops)
|
||||
if _, err = issues_model.CreateComment(ctx, ops); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
// cleanup: this will only remove the reference, the real commit will be clean up when next GC
|
||||
if err1 := baseGitRepo.RemoveReference(pr.GetGitRefName()); err1 != nil {
|
||||
log.Error("RemoveReference: %v", err1)
|
||||
}
|
||||
return err
|
||||
}
|
||||
baseGitRepo.Close() // close immediately to avoid notifications will open the repository again
|
||||
|
||||
mentions, err := issues_model.FindAndUpdateIssueMentions(ctx, issue, issue.Poster, issue.Content)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
notification.NotifyNewPullRequest(ctx, pr, mentions)
|
||||
if len(issue.Labels) > 0 {
|
||||
notification.NotifyIssueChangeLabels(ctx, issue.Poster, issue, issue.Labels, nil)
|
||||
}
|
||||
if issue.Milestone != nil {
|
||||
notification.NotifyIssueChangeMilestone(ctx, issue.Poster, issue, 0)
|
||||
}
|
||||
if len(assigneeIDs) > 0 {
|
||||
for _, assigneeID := range assigneeIDs {
|
||||
assignee, err := user_model.GetUserByID(ctx, assigneeID)
|
||||
if err != nil {
|
||||
return ErrDependenciesLeft
|
||||
}
|
||||
notification.NotifyIssueChangeAssignee(ctx, issue.Poster, issue, assignee, false, assigneeCommentMap[assigneeID])
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -170,12 +170,14 @@
|
||||
<span class="no-select item {{if .HasSelectedLabel}}gt-hidden{{end}}">
|
||||
{{.locale.Tr "repo.issues.new.no_assignees"}}
|
||||
</span>
|
||||
<div class="selected">
|
||||
{{range .Assignees}}
|
||||
<a class="item gt-p-2 muted gt-hidden" id="assignee_{{.ID}}" href="{{$.RepoLink}}/issues?assignee={{.ID}}">
|
||||
{{avatar $.Context . 28 "gt-mr-3 gt-vm"}}{{.GetDisplayName}}
|
||||
</a>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{if and .PageIsComparePull (not (eq .HeadRepo.FullName .BaseCompareRepo.FullName)) .CanWriteToHeadRepo}}
|
||||
<div class="ui divider"></div>
|
||||
<div class="inline field">
|
||||
|
@ -122,7 +122,7 @@
|
||||
}
|
||||
|
||||
#readme_profile {
|
||||
padding: 10px;
|
||||
padding: 1em 2em;
|
||||
border-radius: 0.28571429rem;
|
||||
background: var(--color-card);
|
||||
border: 1px solid var(--color-secondary);
|
||||
|
Loading…
x
Reference in New Issue
Block a user