mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-04 04:14:01 +01:00 
			
		
		
		
	Merge branch 'go-gitea:main' into main
This commit is contained in:
		
						commit
						016c2f3025
					
				@ -171,6 +171,7 @@ func (run *ActionRun) IsSchedule() bool {
 | 
			
		||||
 | 
			
		||||
func updateRepoRunsNumbers(ctx context.Context, repo *repo_model.Repository) error {
 | 
			
		||||
	_, err := db.GetEngine(ctx).ID(repo.ID).
 | 
			
		||||
		NoAutoTime().
 | 
			
		||||
		SetExpr("num_action_runs",
 | 
			
		||||
			builder.Select("count(*)").From("action_run").
 | 
			
		||||
				Where(builder.Eq{"repo_id": repo.ID}),
 | 
			
		||||
 | 
			
		||||
@ -249,7 +249,7 @@ func CreatePendingRepositoryTransfer(ctx context.Context, doer, newOwner *user_m
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		repo.Status = RepositoryPendingTransfer
 | 
			
		||||
		if err := UpdateRepositoryCols(ctx, repo, "status"); err != nil {
 | 
			
		||||
		if err := UpdateRepositoryColsNoAutoTime(ctx, repo, "status"); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,7 @@ func UpdateRepositoryOwnerNames(ctx context.Context, ownerID int64, ownerName st
 | 
			
		||||
	}
 | 
			
		||||
	defer committer.Close()
 | 
			
		||||
 | 
			
		||||
	if _, err := db.GetEngine(ctx).Where("owner_id = ?", ownerID).Cols("owner_name").Update(&Repository{
 | 
			
		||||
	if _, err := db.GetEngine(ctx).Where("owner_id = ?", ownerID).Cols("owner_name").NoAutoTime().Update(&Repository{
 | 
			
		||||
		OwnerName: ownerName,
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
@ -40,8 +40,8 @@ func UpdateRepositoryUpdatedTime(ctx context.Context, repoID int64, updateTime t
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UpdateRepositoryCols updates repository's columns
 | 
			
		||||
func UpdateRepositoryCols(ctx context.Context, repo *Repository, cols ...string) error {
 | 
			
		||||
// UpdateRepositoryColsWithAutoTime updates repository's columns
 | 
			
		||||
func UpdateRepositoryColsWithAutoTime(ctx context.Context, repo *Repository, cols ...string) error {
 | 
			
		||||
	_, err := db.GetEngine(ctx).ID(repo.ID).Cols(cols...).Update(repo)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -117,6 +117,7 @@ files=文件
 | 
			
		||||
 | 
			
		||||
error=错误
 | 
			
		||||
error404=您正尝试访问的页面 <strong>不存在</strong> 或 <strong>您尚未被授权</strong> 查看该页面。
 | 
			
		||||
error503=服务器无法完成您的请求,请稍后重试。
 | 
			
		||||
go_back=返回
 | 
			
		||||
invalid_data=无效数据: %v
 | 
			
		||||
 | 
			
		||||
@ -129,6 +130,7 @@ pin=固定
 | 
			
		||||
unpin=取消置顶
 | 
			
		||||
 | 
			
		||||
artifacts=制品
 | 
			
		||||
expired=已过期
 | 
			
		||||
confirm_delete_artifact=您确定要删除制品'%s'吗?
 | 
			
		||||
 | 
			
		||||
archived=已归档
 | 
			
		||||
@ -449,6 +451,7 @@ use_scratch_code=使用验证口令
 | 
			
		||||
twofa_scratch_used=你已经使用了你的验证口令。你将会转到两步验证设置页面以便移除你的注册设备或者重新生成新的验证口令。
 | 
			
		||||
twofa_passcode_incorrect=你的验证码不正确。如果你丢失了你的设备,请使用你的验证口令。
 | 
			
		||||
twofa_scratch_token_incorrect=你的验证口令不正确。
 | 
			
		||||
twofa_required=您必须设置两步验证来访问仓库,或者尝试重新登录。
 | 
			
		||||
login_userpass=登录
 | 
			
		||||
login_openid=OpenID
 | 
			
		||||
oauth_signup_tab=注册帐号
 | 
			
		||||
@ -1524,7 +1527,7 @@ issues.move_to_column_of_project=`将此对象移至 %s 的 %s 中在 %s 上`
 | 
			
		||||
issues.change_milestone_at=`%[3]s 修改了里程碑从 <b>%[1]s</b> 到 <b>%[2]s</b>`
 | 
			
		||||
issues.change_project_at=于 %[3]s 将此从项目 <b>%[1]s</b> 移到 <b>%[2]s</b>
 | 
			
		||||
issues.remove_milestone_at=`%[2]s 删除了里程碑 <b>%[1]s</b>`
 | 
			
		||||
issues.remove_project_at=`从 <b>%s</b> 项目 %s 中删除`
 | 
			
		||||
issues.remove_project_at=`于  %[2]s 将此工单从项目 <b>%[1]s</b> 中删除`
 | 
			
		||||
issues.deleted_milestone=(已删除)
 | 
			
		||||
issues.deleted_project=`(已删除)`
 | 
			
		||||
issues.self_assign_at=`于 %s 指派给自己`
 | 
			
		||||
@ -1877,6 +1880,7 @@ pulls.add_prefix=添加 <strong>%s</strong> 前缀
 | 
			
		||||
pulls.remove_prefix=删除 <strong>%s</strong> 前缀
 | 
			
		||||
pulls.data_broken=此合并请求因为派生仓库信息缺失而中断。
 | 
			
		||||
pulls.files_conflicted=此合并请求有变更与目标分支冲突。
 | 
			
		||||
pulls.is_checking=正在进行合并冲突检测 ...
 | 
			
		||||
pulls.is_ancestor=此分支已经包含在目标分支中,没有什么可以合并。
 | 
			
		||||
pulls.is_empty=此分支上的更改已经在目标分支上。这将是一个空提交。
 | 
			
		||||
pulls.required_status_check_failed=一些必要的检查没有成功
 | 
			
		||||
@ -3724,7 +3728,11 @@ creation.name_placeholder=不区分大小写,字母数字或下划线不能以
 | 
			
		||||
creation.value_placeholder=输入任何内容,开头和结尾的空白都会被省略
 | 
			
		||||
creation.description_placeholder=输入简短描述(可选)。
 | 
			
		||||
 | 
			
		||||
save_success=密钥 '%s' 保存成功。
 | 
			
		||||
save_failed=密钥保存失败。
 | 
			
		||||
 | 
			
		||||
add_secret=添加密钥
 | 
			
		||||
edit_secret=编辑密钥
 | 
			
		||||
deletion=删除密钥
 | 
			
		||||
deletion.description=删除密钥是永久性的,无法撤消。继续吗?
 | 
			
		||||
deletion.success=此Secret已被删除。
 | 
			
		||||
@ -3841,6 +3849,8 @@ deleted.display_name=已删除项目
 | 
			
		||||
type-1.display_name=个人项目
 | 
			
		||||
type-2.display_name=仓库项目
 | 
			
		||||
type-3.display_name=组织项目
 | 
			
		||||
enter_fullscreen=全屏
 | 
			
		||||
exit_fullscreen=退出全屏
 | 
			
		||||
 | 
			
		||||
[git.filemode]
 | 
			
		||||
changed_filemode=%[1]s -> %[2]s
 | 
			
		||||
 | 
			
		||||
@ -895,6 +895,15 @@ func EditIssue(ctx *context.APIContext) {
 | 
			
		||||
		issue.MilestoneID != *form.Milestone {
 | 
			
		||||
		oldMilestoneID := issue.MilestoneID
 | 
			
		||||
		issue.MilestoneID = *form.Milestone
 | 
			
		||||
		if issue.MilestoneID > 0 {
 | 
			
		||||
			issue.Milestone, err = issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, *form.Milestone)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				ctx.APIErrorInternal(err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			issue.Milestone = nil
 | 
			
		||||
		}
 | 
			
		||||
		if err = issue_service.ChangeMilestoneAssign(ctx, issue, ctx.Doer, oldMilestoneID); err != nil {
 | 
			
		||||
			ctx.APIErrorInternal(err)
 | 
			
		||||
			return
 | 
			
		||||
 | 
			
		||||
@ -609,15 +609,17 @@ func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	oldContent := comment.Content
 | 
			
		||||
	comment.Content = form.Body
 | 
			
		||||
	if err := issue_service.UpdateComment(ctx, comment, comment.ContentVersion, ctx.Doer, oldContent); err != nil {
 | 
			
		||||
		if errors.Is(err, user_model.ErrBlockedUser) {
 | 
			
		||||
			ctx.APIError(http.StatusForbidden, err)
 | 
			
		||||
		} else {
 | 
			
		||||
			ctx.APIErrorInternal(err)
 | 
			
		||||
	if form.Body != comment.Content {
 | 
			
		||||
		oldContent := comment.Content
 | 
			
		||||
		comment.Content = form.Body
 | 
			
		||||
		if err := issue_service.UpdateComment(ctx, comment, comment.ContentVersion, ctx.Doer, oldContent); err != nil {
 | 
			
		||||
			if errors.Is(err, user_model.ErrBlockedUser) {
 | 
			
		||||
				ctx.APIError(http.StatusForbidden, err)
 | 
			
		||||
			} else {
 | 
			
		||||
				ctx.APIErrorInternal(err)
 | 
			
		||||
			}
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ctx.JSON(http.StatusOK, convert.ToAPIComment(ctx, ctx.Repo.Repository, comment))
 | 
			
		||||
 | 
			
		||||
@ -706,6 +706,11 @@ func EditPullRequest(ctx *context.APIContext) {
 | 
			
		||||
		issue.MilestoneID != form.Milestone {
 | 
			
		||||
		oldMilestoneID := issue.MilestoneID
 | 
			
		||||
		issue.MilestoneID = form.Milestone
 | 
			
		||||
		issue.Milestone, err = issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, form.Milestone)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			ctx.APIErrorInternal(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		if err = issue_service.ChangeMilestoneAssign(ctx, issue, ctx.Doer, oldMilestoneID); err != nil {
 | 
			
		||||
			ctx.APIErrorInternal(err)
 | 
			
		||||
			return
 | 
			
		||||
 | 
			
		||||
@ -220,7 +220,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if len(cols) > 0 {
 | 
			
		||||
			if err := repo_model.UpdateRepositoryCols(ctx, repo, cols...); err != nil {
 | 
			
		||||
			if err := repo_model.UpdateRepositoryColsNoAutoTime(ctx, repo, cols...); err != nil {
 | 
			
		||||
				log.Error("Failed to Update: %s/%s Error: %v", ownerName, repoName, err)
 | 
			
		||||
				ctx.JSON(http.StatusInternalServerError, private.HookPostReceiveResult{
 | 
			
		||||
					Err: fmt.Sprintf("Failed to Update: %s/%s Error: %v", ownerName, repoName, err),
 | 
			
		||||
 | 
			
		||||
@ -376,12 +376,6 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ctx.Repo.Repository.IsEmpty {
 | 
			
		||||
		if isEmpty, err := ctx.Repo.GitRepo.IsEmpty(); err == nil && !isEmpty {
 | 
			
		||||
			_ = repo_model.UpdateRepositoryCols(ctx, &repo_model.Repository{ID: ctx.Repo.Repository.ID, IsEmpty: false}, "is_empty")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	redirectForCommitChoice(ctx, form.CommitChoice, branchName, form.TreePath)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -790,7 +784,7 @@ func UploadFilePost(ctx *context.Context) {
 | 
			
		||||
 | 
			
		||||
	if ctx.Repo.Repository.IsEmpty {
 | 
			
		||||
		if isEmpty, err := ctx.Repo.GitRepo.IsEmpty(); err == nil && !isEmpty {
 | 
			
		||||
			_ = repo_model.UpdateRepositoryCols(ctx, &repo_model.Repository{ID: ctx.Repo.Repository.ID, IsEmpty: false}, "is_empty")
 | 
			
		||||
			_ = repo_model.UpdateRepositoryColsWithAutoTime(ctx, &repo_model.Repository{ID: ctx.Repo.Repository.ID, IsEmpty: false}, "is_empty")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -418,6 +418,16 @@ func UpdateIssueMilestone(ctx *context.Context) {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		issue.MilestoneID = milestoneID
 | 
			
		||||
		if milestoneID > 0 {
 | 
			
		||||
			var err error
 | 
			
		||||
			issue.Milestone, err = issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, milestoneID)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				ctx.ServerError("GetMilestoneByRepoID", err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			issue.Milestone = nil
 | 
			
		||||
		}
 | 
			
		||||
		if err := issue_service.ChangeMilestoneAssign(ctx, issue, ctx.Doer, oldMilestoneID); err != nil {
 | 
			
		||||
			ctx.ServerError("ChangeMilestoneAssign", err)
 | 
			
		||||
			return
 | 
			
		||||
 | 
			
		||||
@ -239,23 +239,30 @@ func UpdateCommentContent(ctx *context.Context) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	oldContent := comment.Content
 | 
			
		||||
	newContent := ctx.FormString("content")
 | 
			
		||||
	contentVersion := ctx.FormInt("content_version")
 | 
			
		||||
 | 
			
		||||
	// allow to save empty content
 | 
			
		||||
	comment.Content = newContent
 | 
			
		||||
	if err = issue_service.UpdateComment(ctx, comment, contentVersion, ctx.Doer, oldContent); err != nil {
 | 
			
		||||
		if errors.Is(err, user_model.ErrBlockedUser) {
 | 
			
		||||
			ctx.JSONError(ctx.Tr("repo.issues.comment.blocked_user"))
 | 
			
		||||
		} else if errors.Is(err, issues_model.ErrCommentAlreadyChanged) {
 | 
			
		||||
			ctx.JSONError(ctx.Tr("repo.comments.edit.already_changed"))
 | 
			
		||||
		} else {
 | 
			
		||||
			ctx.ServerError("UpdateComment", err)
 | 
			
		||||
		}
 | 
			
		||||
	if contentVersion != comment.ContentVersion {
 | 
			
		||||
		ctx.JSONError(ctx.Tr("repo.comments.edit.already_changed"))
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if newContent != comment.Content {
 | 
			
		||||
		// allow to save empty content
 | 
			
		||||
		oldContent := comment.Content
 | 
			
		||||
		comment.Content = newContent
 | 
			
		||||
 | 
			
		||||
		if err = issue_service.UpdateComment(ctx, comment, contentVersion, ctx.Doer, oldContent); err != nil {
 | 
			
		||||
			if errors.Is(err, user_model.ErrBlockedUser) {
 | 
			
		||||
				ctx.JSONError(ctx.Tr("repo.issues.comment.blocked_user"))
 | 
			
		||||
			} else if errors.Is(err, issues_model.ErrCommentAlreadyChanged) {
 | 
			
		||||
				ctx.JSONError(ctx.Tr("repo.comments.edit.already_changed"))
 | 
			
		||||
			} else {
 | 
			
		||||
				ctx.ServerError("UpdateComment", err)
 | 
			
		||||
			}
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := comment.LoadAttachments(ctx); err != nil {
 | 
			
		||||
		ctx.ServerError("LoadAttachments", err)
 | 
			
		||||
		return
 | 
			
		||||
 | 
			
		||||
@ -109,7 +109,7 @@ func findWikiRepoCommit(ctx *context.Context) (*git.Repository, *git.Commit, err
 | 
			
		||||
			return wikiGitRepo, nil, errBranch
 | 
			
		||||
		}
 | 
			
		||||
		// update the default branch in the database
 | 
			
		||||
		errDb := repo_model.UpdateRepositoryCols(ctx, &repo_model.Repository{ID: ctx.Repo.Repository.ID, DefaultWikiBranch: gitRepoDefaultBranch}, "default_wiki_branch")
 | 
			
		||||
		errDb := repo_model.UpdateRepositoryColsNoAutoTime(ctx, &repo_model.Repository{ID: ctx.Repo.Repository.ID, DefaultWikiBranch: gitRepoDefaultBranch}, "default_wiki_branch")
 | 
			
		||||
		if errDb != nil {
 | 
			
		||||
			return wikiGitRepo, nil, errDb
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -245,7 +245,7 @@ func TestDefaultWikiBranch(t *testing.T) {
 | 
			
		||||
	assert.NoError(t, wiki_service.ChangeDefaultWikiBranch(db.DefaultContext, repoWithNoWiki, "main"))
 | 
			
		||||
 | 
			
		||||
	// repo with wiki
 | 
			
		||||
	assert.NoError(t, repo_model.UpdateRepositoryCols(db.DefaultContext, &repo_model.Repository{ID: 1, DefaultWikiBranch: "wrong-branch"}))
 | 
			
		||||
	assert.NoError(t, repo_model.UpdateRepositoryColsNoAutoTime(db.DefaultContext, &repo_model.Repository{ID: 1, DefaultWikiBranch: "wrong-branch"}))
 | 
			
		||||
 | 
			
		||||
	ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki")
 | 
			
		||||
	ctx.SetPathParam("*", "Home")
 | 
			
		||||
 | 
			
		||||
@ -148,7 +148,7 @@ func (g *GiteaLocalUploader) CreateRepo(ctx context.Context, repo *base.Reposito
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	g.repo.ObjectFormatName = objectFormat.Name()
 | 
			
		||||
	return repo_model.UpdateRepositoryCols(ctx, g.repo, "object_format_name")
 | 
			
		||||
	return repo_model.UpdateRepositoryColsNoAutoTime(ctx, g.repo, "object_format_name")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Close closes this uploader
 | 
			
		||||
@ -975,7 +975,7 @@ func (g *GiteaLocalUploader) Finish(ctx context.Context) error {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g.repo.Status = repo_model.RepositoryReady
 | 
			
		||||
	return repo_model.UpdateRepositoryCols(ctx, g.repo, "status")
 | 
			
		||||
	return repo_model.UpdateRepositoryColsWithAutoTime(ctx, g.repo, "status")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (g *GiteaLocalUploader) remapUser(ctx context.Context, source user_model.ExternalUserMigrated, target user_model.ExternalUserRemappable) error {
 | 
			
		||||
 | 
			
		||||
@ -71,7 +71,7 @@ func UpdateAddress(ctx context.Context, m *repo_model.Mirror, addr string) error
 | 
			
		||||
	// erase authentication before storing in database
 | 
			
		||||
	u.User = nil
 | 
			
		||||
	m.Repo.OriginalURL = u.String()
 | 
			
		||||
	return repo_model.UpdateRepositoryCols(ctx, m.Repo, "original_url")
 | 
			
		||||
	return repo_model.UpdateRepositoryColsNoAutoTime(ctx, m.Repo, "original_url")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// mirrorSyncResult contains information of a updated reference.
 | 
			
		||||
@ -653,7 +653,7 @@ func checkAndUpdateEmptyRepository(ctx context.Context, m *repo_model.Mirror, re
 | 
			
		||||
		}
 | 
			
		||||
		m.Repo.IsEmpty = false
 | 
			
		||||
		// Update the is empty and default_branch columns
 | 
			
		||||
		if err := repo_model.UpdateRepositoryCols(ctx, m.Repo, "default_branch", "is_empty"); err != nil {
 | 
			
		||||
		if err := repo_model.UpdateRepositoryColsWithAutoTime(ctx, m.Repo, "default_branch", "is_empty"); err != nil {
 | 
			
		||||
			log.Error("Failed to update default branch of repository %-v. Error: %v", m.Repo, err)
 | 
			
		||||
			desc := fmt.Sprintf("Failed to update default branch of repository '%s': %v", m.Repo.RepoPath(), err)
 | 
			
		||||
			if err = system_model.CreateRepositoryNotice(desc); err != nil {
 | 
			
		||||
 | 
			
		||||
@ -100,7 +100,7 @@ func AdoptRepository(ctx context.Context, doer, owner *user_model.User, opts Cre
 | 
			
		||||
 | 
			
		||||
	// 4 - update repository status
 | 
			
		||||
	repo.Status = repo_model.RepositoryReady
 | 
			
		||||
	if err = repo_model.UpdateRepositoryCols(ctx, repo, "status"); err != nil {
 | 
			
		||||
	if err = repo_model.UpdateRepositoryColsWithAutoTime(ctx, repo, "status"); err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("UpdateRepositoryCols: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -40,7 +40,7 @@ func UploadAvatar(ctx context.Context, repo *repo_model.Repository, data []byte)
 | 
			
		||||
	// Users can upload the same image to other repo - prefix it with ID
 | 
			
		||||
	// Then repo will be removed - only it avatar file will be removed
 | 
			
		||||
	repo.Avatar = newAvatar
 | 
			
		||||
	if err := repo_model.UpdateRepositoryCols(ctx, repo, "avatar"); err != nil {
 | 
			
		||||
	if err := repo_model.UpdateRepositoryColsNoAutoTime(ctx, repo, "avatar"); err != nil {
 | 
			
		||||
		return fmt.Errorf("UploadAvatar: Update repository avatar: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -77,7 +77,7 @@ func DeleteAvatar(ctx context.Context, repo *repo_model.Repository) error {
 | 
			
		||||
	defer committer.Close()
 | 
			
		||||
 | 
			
		||||
	repo.Avatar = ""
 | 
			
		||||
	if err := repo_model.UpdateRepositoryCols(ctx, repo, "avatar"); err != nil {
 | 
			
		||||
	if err := repo_model.UpdateRepositoryColsNoAutoTime(ctx, repo, "avatar"); err != nil {
 | 
			
		||||
		return fmt.Errorf("DeleteAvatar: Update repository avatar: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -112,5 +112,5 @@ func generateAvatar(ctx context.Context, templateRepo, generateRepo *repo_model.
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return repo_model.UpdateRepositoryCols(ctx, generateRepo, "avatar")
 | 
			
		||||
	return repo_model.UpdateRepositoryColsNoAutoTime(ctx, generateRepo, "avatar")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -321,7 +321,7 @@ func CreateRepositoryDirectly(ctx context.Context, doer, owner *user_model.User,
 | 
			
		||||
	// 7 - update repository status to be ready
 | 
			
		||||
	if needsUpdateToReady {
 | 
			
		||||
		repo.Status = repo_model.RepositoryReady
 | 
			
		||||
		if err = repo_model.UpdateRepositoryCols(ctx, repo, "status"); err != nil {
 | 
			
		||||
		if err = repo_model.UpdateRepositoryColsWithAutoTime(ctx, repo, "status"); err != nil {
 | 
			
		||||
			return nil, fmt.Errorf("UpdateRepositoryCols: %w", err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -306,7 +306,7 @@ func ChangeRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use
 | 
			
		||||
 | 
			
		||||
	if repo.IsEmpty {
 | 
			
		||||
		if isEmpty, err := gitRepo.IsEmpty(); err == nil && !isEmpty {
 | 
			
		||||
			_ = repo_model.UpdateRepositoryCols(ctx, &repo_model.Repository{ID: repo.ID, IsEmpty: false, DefaultBranch: opts.NewBranch}, "is_empty", "default_branch")
 | 
			
		||||
			_ = repo_model.UpdateRepositoryColsWithAutoTime(ctx, &repo_model.Repository{ID: repo.ID, IsEmpty: false, DefaultBranch: opts.NewBranch}, "is_empty", "default_branch")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -198,7 +198,7 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork
 | 
			
		||||
 | 
			
		||||
	// 8 - update repository status to be ready
 | 
			
		||||
	repo.Status = repo_model.RepositoryReady
 | 
			
		||||
	if err = repo_model.UpdateRepositoryCols(ctx, repo, "status"); err != nil {
 | 
			
		||||
	if err = repo_model.UpdateRepositoryColsWithAutoTime(ctx, repo, "status"); err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("UpdateRepositoryCols: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -283,7 +283,7 @@ func pushNewBranch(ctx context.Context, repo *repo_model.Repository, pusher *use
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// Update the is empty and default_branch columns
 | 
			
		||||
		if err := repo_model.UpdateRepositoryCols(ctx, repo, "default_branch", "is_empty"); err != nil {
 | 
			
		||||
		if err := repo_model.UpdateRepositoryColsWithAutoTime(ctx, repo, "default_branch", "is_empty"); err != nil {
 | 
			
		||||
			return nil, fmt.Errorf("UpdateRepositoryCols: %w", err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -205,7 +205,7 @@ func updateRepository(ctx context.Context, repo *repo_model.Repository, visibili
 | 
			
		||||
 | 
			
		||||
	e := db.GetEngine(ctx)
 | 
			
		||||
 | 
			
		||||
	if _, err = e.ID(repo.ID).AllCols().Update(repo); err != nil {
 | 
			
		||||
	if _, err = e.ID(repo.ID).NoAutoTime().AllCols().Update(repo); err != nil {
 | 
			
		||||
		return fmt.Errorf("update: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -184,7 +184,7 @@ func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templ
 | 
			
		||||
 | 
			
		||||
	// 6 - update repository status to be ready
 | 
			
		||||
	generateRepo.Status = repo_model.RepositoryReady
 | 
			
		||||
	if err = repo_model.UpdateRepositoryCols(ctx, generateRepo, "status"); err != nil {
 | 
			
		||||
	if err = repo_model.UpdateRepositoryColsWithAutoTime(ctx, generateRepo, "status"); err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("UpdateRepositoryCols: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -160,7 +160,7 @@ func transferOwnership(ctx context.Context, doer *user_model.User, newOwnerName
 | 
			
		||||
	repo.OwnerName = newOwner.Name
 | 
			
		||||
 | 
			
		||||
	// Update repository.
 | 
			
		||||
	if err := repo_model.UpdateRepositoryCols(ctx, repo, "owner_id", "owner_name"); err != nil {
 | 
			
		||||
	if err := repo_model.UpdateRepositoryColsNoAutoTime(ctx, repo, "owner_id", "owner_name"); err != nil {
 | 
			
		||||
		return fmt.Errorf("update owner: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -304,7 +304,7 @@ func transferOwnership(ctx context.Context, doer *user_model.User, newOwnerName
 | 
			
		||||
		return fmt.Errorf("deleteRepositoryTransfer: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	repo.Status = repo_model.RepositoryReady
 | 
			
		||||
	if err := repo_model.UpdateRepositoryCols(ctx, repo, "status"); err != nil {
 | 
			
		||||
	if err := repo_model.UpdateRepositoryColsNoAutoTime(ctx, repo, "status"); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -495,7 +495,7 @@ func RejectRepositoryTransfer(ctx context.Context, repo *repo_model.Repository,
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		repo.Status = repo_model.RepositoryReady
 | 
			
		||||
		if err := repo_model.UpdateRepositoryCols(ctx, repo, "status"); err != nil {
 | 
			
		||||
		if err := repo_model.UpdateRepositoryColsNoAutoTime(ctx, repo, "status"); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -543,7 +543,7 @@ func CancelRepositoryTransfer(ctx context.Context, repoTransfer *repo_model.Repo
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		repoTransfer.Repo.Status = repo_model.RepositoryReady
 | 
			
		||||
		if err := repo_model.UpdateRepositoryCols(ctx, repoTransfer.Repo, "status"); err != nil {
 | 
			
		||||
		if err := repo_model.UpdateRepositoryColsNoAutoTime(ctx, repoTransfer.Repo, "status"); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -365,7 +365,7 @@ func ChangeDefaultWikiBranch(ctx context.Context, repo *repo_model.Repository, n
 | 
			
		||||
	}
 | 
			
		||||
	return db.WithTx(ctx, func(ctx context.Context) error {
 | 
			
		||||
		repo.DefaultWikiBranch = newBranch
 | 
			
		||||
		if err := repo_model.UpdateRepositoryCols(ctx, repo, "default_wiki_branch"); err != nil {
 | 
			
		||||
		if err := repo_model.UpdateRepositoryColsNoAutoTime(ctx, repo, "default_wiki_branch"); err != nil {
 | 
			
		||||
			return fmt.Errorf("unable to update database: %w", err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -184,6 +184,15 @@ func testIssueAddComment(t *testing.T, session *TestSession, issueURL, content,
 | 
			
		||||
	return int64(id)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func testIssueChangeMilestone(t *testing.T, session *TestSession, repoLink string, issueID, milestoneID int64) {
 | 
			
		||||
	req := NewRequestWithValues(t, "POST", fmt.Sprintf(repoLink+"/issues/milestone?issue_ids=%d", issueID), map[string]string{
 | 
			
		||||
		"_csrf": GetUserCSRFToken(t, session),
 | 
			
		||||
		"id":    strconv.FormatInt(milestoneID, 10),
 | 
			
		||||
	})
 | 
			
		||||
	resp := session.MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
	assert.Equal(t, `{"ok":true}`, strings.TrimSpace(resp.Body.String()))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestNewIssue(t *testing.T) {
 | 
			
		||||
	defer tests.PrepareTestEnv(t)()
 | 
			
		||||
	session := loginUser(t, "user2")
 | 
			
		||||
 | 
			
		||||
@ -56,16 +56,21 @@ func TestNewWebHookLink(t *testing.T) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func testAPICreateWebhookForRepo(t *testing.T, session *TestSession, userName, repoName, url, event string) {
 | 
			
		||||
func testAPICreateWebhookForRepo(t *testing.T, session *TestSession, userName, repoName, url, event string, branchFilter ...string) {
 | 
			
		||||
	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAll)
 | 
			
		||||
	var branchFilterString string
 | 
			
		||||
	if len(branchFilter) > 0 {
 | 
			
		||||
		branchFilterString = branchFilter[0]
 | 
			
		||||
	}
 | 
			
		||||
	req := NewRequestWithJSON(t, "POST", "/api/v1/repos/"+userName+"/"+repoName+"/hooks", api.CreateHookOption{
 | 
			
		||||
		Type: "gitea",
 | 
			
		||||
		Config: api.CreateHookOptionConfig{
 | 
			
		||||
			"content_type": "json",
 | 
			
		||||
			"url":          url,
 | 
			
		||||
		},
 | 
			
		||||
		Events: []string{event},
 | 
			
		||||
		Active: true,
 | 
			
		||||
		Events:       []string{event},
 | 
			
		||||
		Active:       true,
 | 
			
		||||
		BranchFilter: branchFilterString,
 | 
			
		||||
	}).AddTokenAuth(token)
 | 
			
		||||
	MakeRequest(t, req, http.StatusCreated)
 | 
			
		||||
}
 | 
			
		||||
@ -241,19 +246,68 @@ func Test_WebhookIssueComment(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
		testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "issue_comment")
 | 
			
		||||
 | 
			
		||||
		// 2. trigger the webhook
 | 
			
		||||
		issueURL := testNewIssue(t, session, "user2", "repo1", "Title2", "Description2")
 | 
			
		||||
		testIssueAddComment(t, session, issueURL, "issue title2 comment1", "")
 | 
			
		||||
		t.Run("create comment", func(t *testing.T) {
 | 
			
		||||
			// 2. trigger the webhook
 | 
			
		||||
			issueURL := testNewIssue(t, session, "user2", "repo1", "Title2", "Description2")
 | 
			
		||||
			testIssueAddComment(t, session, issueURL, "issue title2 comment1", "")
 | 
			
		||||
 | 
			
		||||
		// 3. validate the webhook is triggered
 | 
			
		||||
		assert.Equal(t, "issue_comment", triggeredEvent)
 | 
			
		||||
		assert.Len(t, payloads, 1)
 | 
			
		||||
		assert.EqualValues(t, "created", payloads[0].Action)
 | 
			
		||||
		assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name)
 | 
			
		||||
		assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName)
 | 
			
		||||
		assert.Equal(t, "Title2", payloads[0].Issue.Title)
 | 
			
		||||
		assert.Equal(t, "Description2", payloads[0].Issue.Body)
 | 
			
		||||
		assert.Equal(t, "issue title2 comment1", payloads[0].Comment.Body)
 | 
			
		||||
			// 3. validate the webhook is triggered
 | 
			
		||||
			assert.Equal(t, "issue_comment", triggeredEvent)
 | 
			
		||||
			assert.Len(t, payloads, 1)
 | 
			
		||||
			assert.EqualValues(t, "created", payloads[0].Action)
 | 
			
		||||
			assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name)
 | 
			
		||||
			assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName)
 | 
			
		||||
			assert.Equal(t, "Title2", payloads[0].Issue.Title)
 | 
			
		||||
			assert.Equal(t, "Description2", payloads[0].Issue.Body)
 | 
			
		||||
			assert.Equal(t, "issue title2 comment1", payloads[0].Comment.Body)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		t.Run("update comment", func(t *testing.T) {
 | 
			
		||||
			payloads = make([]api.IssueCommentPayload, 0, 2)
 | 
			
		||||
			triggeredEvent = ""
 | 
			
		||||
 | 
			
		||||
			// 2. trigger the webhook
 | 
			
		||||
			issueURL := testNewIssue(t, session, "user2", "repo1", "Title3", "Description3")
 | 
			
		||||
			commentID := testIssueAddComment(t, session, issueURL, "issue title3 comment1", "")
 | 
			
		||||
			modifiedContent := "issue title2 comment1 - modified"
 | 
			
		||||
			req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/comments/%d", "user2", "repo1", commentID), map[string]string{
 | 
			
		||||
				"_csrf":   GetUserCSRFToken(t, session),
 | 
			
		||||
				"content": modifiedContent,
 | 
			
		||||
			})
 | 
			
		||||
			session.MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
 | 
			
		||||
			// 3. validate the webhook is triggered
 | 
			
		||||
			assert.Equal(t, "issue_comment", triggeredEvent)
 | 
			
		||||
			assert.Len(t, payloads, 2)
 | 
			
		||||
			assert.EqualValues(t, "edited", payloads[1].Action)
 | 
			
		||||
			assert.Equal(t, "repo1", payloads[1].Issue.Repo.Name)
 | 
			
		||||
			assert.Equal(t, "user2/repo1", payloads[1].Issue.Repo.FullName)
 | 
			
		||||
			assert.Equal(t, "Title3", payloads[1].Issue.Title)
 | 
			
		||||
			assert.Equal(t, "Description3", payloads[1].Issue.Body)
 | 
			
		||||
			assert.Equal(t, modifiedContent, payloads[1].Comment.Body)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		t.Run("Update comment with no content change", func(t *testing.T) {
 | 
			
		||||
			payloads = make([]api.IssueCommentPayload, 0, 2)
 | 
			
		||||
			triggeredEvent = ""
 | 
			
		||||
			commentContent := "issue title3 comment1"
 | 
			
		||||
 | 
			
		||||
			// 2. trigger the webhook
 | 
			
		||||
			issueURL := testNewIssue(t, session, "user2", "repo1", "Title3", "Description3")
 | 
			
		||||
			commentID := testIssueAddComment(t, session, issueURL, commentContent, "")
 | 
			
		||||
 | 
			
		||||
			payloads = make([]api.IssueCommentPayload, 0, 2)
 | 
			
		||||
			triggeredEvent = ""
 | 
			
		||||
			req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/comments/%d", "user2", "repo1", commentID), map[string]string{
 | 
			
		||||
				"_csrf":   GetUserCSRFToken(t, session),
 | 
			
		||||
				"content": commentContent,
 | 
			
		||||
			})
 | 
			
		||||
			session.MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
 | 
			
		||||
			// 3. validate the webhook is not triggered because no content change
 | 
			
		||||
			assert.Empty(t, triggeredEvent)
 | 
			
		||||
			assert.Empty(t, payloads)
 | 
			
		||||
		})
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -322,6 +376,45 @@ func Test_WebhookPush(t *testing.T) {
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Test_WebhookPushDevBranch(t *testing.T) {
 | 
			
		||||
	var payloads []api.PushPayload
 | 
			
		||||
	var triggeredEvent string
 | 
			
		||||
	provider := newMockWebhookProvider(func(r *http.Request) {
 | 
			
		||||
		content, _ := io.ReadAll(r.Body)
 | 
			
		||||
		var payload api.PushPayload
 | 
			
		||||
		err := json.Unmarshal(content, &payload)
 | 
			
		||||
		assert.NoError(t, err)
 | 
			
		||||
		payloads = append(payloads, payload)
 | 
			
		||||
		triggeredEvent = "push"
 | 
			
		||||
	}, http.StatusOK)
 | 
			
		||||
	defer provider.Close()
 | 
			
		||||
 | 
			
		||||
	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
 | 
			
		||||
		// 1. create a new webhook with special webhook for repo1
 | 
			
		||||
		session := loginUser(t, "user2")
 | 
			
		||||
 | 
			
		||||
		// only for dev branch
 | 
			
		||||
		testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "push", "develop")
 | 
			
		||||
 | 
			
		||||
		// 2. this should not trigger the webhook
 | 
			
		||||
		testCreateFile(t, session, "user2", "repo1", "master", "test_webhook_push.md", "# a test file for webhook push")
 | 
			
		||||
		assert.Empty(t, triggeredEvent)
 | 
			
		||||
		assert.Empty(t, payloads)
 | 
			
		||||
 | 
			
		||||
		// 3. trigger the webhook
 | 
			
		||||
		testCreateFile(t, session, "user2", "repo1", "develop", "test_webhook_push.md", "# a test file for webhook push")
 | 
			
		||||
 | 
			
		||||
		// 4. validate the webhook is triggered
 | 
			
		||||
		assert.Equal(t, "push", triggeredEvent)
 | 
			
		||||
		assert.Len(t, payloads, 1)
 | 
			
		||||
		assert.Equal(t, "repo1", payloads[0].Repo.Name)
 | 
			
		||||
		assert.Equal(t, "develop", payloads[0].Branch())
 | 
			
		||||
		assert.Equal(t, "user2/repo1", payloads[0].Repo.FullName)
 | 
			
		||||
		assert.Len(t, payloads[0].Commits, 1)
 | 
			
		||||
		assert.Equal(t, []string{"test_webhook_push.md"}, payloads[0].Commits[0].Added)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Test_WebhookIssue(t *testing.T) {
 | 
			
		||||
	var payloads []api.IssuePayload
 | 
			
		||||
	var triggeredEvent string
 | 
			
		||||
@ -355,6 +448,78 @@ func Test_WebhookIssue(t *testing.T) {
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Test_WebhookIssueMilestone(t *testing.T) {
 | 
			
		||||
	var payloads []api.IssuePayload
 | 
			
		||||
	var triggeredEvent string
 | 
			
		||||
	provider := newMockWebhookProvider(func(r *http.Request) {
 | 
			
		||||
		content, _ := io.ReadAll(r.Body)
 | 
			
		||||
		var payload api.IssuePayload
 | 
			
		||||
		err := json.Unmarshal(content, &payload)
 | 
			
		||||
		assert.NoError(t, err)
 | 
			
		||||
		payloads = append(payloads, payload)
 | 
			
		||||
		triggeredEvent = "issues"
 | 
			
		||||
	}, http.StatusOK)
 | 
			
		||||
	defer provider.Close()
 | 
			
		||||
 | 
			
		||||
	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
 | 
			
		||||
		// create a new webhook with special webhook for repo1
 | 
			
		||||
		session := loginUser(t, "user2")
 | 
			
		||||
		repo1 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 1})
 | 
			
		||||
		testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "issue_milestone")
 | 
			
		||||
 | 
			
		||||
		t.Run("assign a milestone", func(t *testing.T) {
 | 
			
		||||
			// trigger the webhook
 | 
			
		||||
			testIssueChangeMilestone(t, session, repo1.Link(), 1, 1)
 | 
			
		||||
 | 
			
		||||
			// validate the webhook is triggered
 | 
			
		||||
			assert.Equal(t, "issues", triggeredEvent)
 | 
			
		||||
			assert.Len(t, payloads, 1)
 | 
			
		||||
			assert.Equal(t, "milestoned", string(payloads[0].Action))
 | 
			
		||||
			assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name)
 | 
			
		||||
			assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName)
 | 
			
		||||
			assert.Equal(t, "issue1", payloads[0].Issue.Title)
 | 
			
		||||
			assert.Equal(t, "content for the first issue", payloads[0].Issue.Body)
 | 
			
		||||
			assert.EqualValues(t, 1, payloads[0].Issue.Milestone.ID)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		t.Run("change a milestong", func(t *testing.T) {
 | 
			
		||||
			// trigger the webhook again
 | 
			
		||||
			triggeredEvent = ""
 | 
			
		||||
			payloads = make([]api.IssuePayload, 0, 1)
 | 
			
		||||
			// change milestone to 2
 | 
			
		||||
			testIssueChangeMilestone(t, session, repo1.Link(), 1, 2)
 | 
			
		||||
 | 
			
		||||
			// validate the webhook is triggered
 | 
			
		||||
			assert.Equal(t, "issues", triggeredEvent)
 | 
			
		||||
			assert.Len(t, payloads, 1)
 | 
			
		||||
			assert.Equal(t, "milestoned", string(payloads[0].Action))
 | 
			
		||||
			assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name)
 | 
			
		||||
			assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName)
 | 
			
		||||
			assert.Equal(t, "issue1", payloads[0].Issue.Title)
 | 
			
		||||
			assert.Equal(t, "content for the first issue", payloads[0].Issue.Body)
 | 
			
		||||
			assert.EqualValues(t, 2, payloads[0].Issue.Milestone.ID)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		t.Run("remove a milestone", func(t *testing.T) {
 | 
			
		||||
			// trigger the webhook again
 | 
			
		||||
			triggeredEvent = ""
 | 
			
		||||
			payloads = make([]api.IssuePayload, 0, 1)
 | 
			
		||||
			// change milestone to 0
 | 
			
		||||
			testIssueChangeMilestone(t, session, repo1.Link(), 1, 0)
 | 
			
		||||
 | 
			
		||||
			// validate the webhook is triggered
 | 
			
		||||
			assert.Equal(t, "issues", triggeredEvent)
 | 
			
		||||
			assert.Len(t, payloads, 1)
 | 
			
		||||
			assert.Equal(t, "demilestoned", string(payloads[0].Action))
 | 
			
		||||
			assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name)
 | 
			
		||||
			assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName)
 | 
			
		||||
			assert.Equal(t, "issue1", payloads[0].Issue.Title)
 | 
			
		||||
			assert.Equal(t, "content for the first issue", payloads[0].Issue.Body)
 | 
			
		||||
			assert.Nil(t, payloads[0].Issue.Milestone)
 | 
			
		||||
		})
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Test_WebhookPullRequest(t *testing.T) {
 | 
			
		||||
	var payloads []api.PullRequestPayload
 | 
			
		||||
	var triggeredEvent string
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user