Merge pull request '[gitea] week 2024-43 cherry pick (gitea/main -> forgejo)' (#5621) from algernon/wcp/2024-43 into forgejo

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5621
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
This commit is contained in:
Earl Warren 2024-10-22 17:37:03 +00:00
commit c1a08156f8
14 changed files with 167 additions and 85 deletions

View file

@ -69,7 +69,7 @@ func CreateArtifact(ctx context.Context, t *ActionTask, artifactName, artifactPa
OwnerID: t.OwnerID, OwnerID: t.OwnerID,
CommitSHA: t.CommitSHA, CommitSHA: t.CommitSHA,
Status: int64(ArtifactStatusUploadPending), Status: int64(ArtifactStatusUploadPending),
ExpiredUnix: timeutil.TimeStamp(time.Now().Unix() + 3600*24*expiredDays), ExpiredUnix: timeutil.TimeStamp(time.Now().Unix() + timeutil.Day*expiredDays),
} }
if _, err := db.GetEngine(ctx).Insert(artifact); err != nil { if _, err := db.GetEngine(ctx).Insert(artifact); err != nil {
return nil, err return nil, err
@ -78,6 +78,13 @@ func CreateArtifact(ctx context.Context, t *ActionTask, artifactName, artifactPa
} else if err != nil { } else if err != nil {
return nil, err return nil, err
} }
if _, err := db.GetEngine(ctx).ID(artifact.ID).Cols("expired_unix").Update(&ActionArtifact{
ExpiredUnix: timeutil.TimeStamp(time.Now().Unix() + timeutil.Day*expiredDays),
}); err != nil {
return nil, err
}
return artifact, nil return artifact, nil
} }

View file

@ -37,6 +37,7 @@ type PullRequest struct {
ForeignIndex int64 ForeignIndex int64
Context DownloaderContext `yaml:"-"` Context DownloaderContext `yaml:"-"`
EnsuredSafe bool `yaml:"ensured_safe"` EnsuredSafe bool `yaml:"ensured_safe"`
IsDraft bool `yaml:"is_draft"`
} }
func (p *PullRequest) GetLocalIndex() int64 { return p.Number } func (p *PullRequest) GetLocalIndex() int64 { return p.Number }

View file

@ -221,13 +221,14 @@ const (
// IssueCommentPayload represents a payload information of issue comment event. // IssueCommentPayload represents a payload information of issue comment event.
type IssueCommentPayload struct { type IssueCommentPayload struct {
Action HookIssueCommentAction `json:"action"` Action HookIssueCommentAction `json:"action"`
Issue *Issue `json:"issue"` Issue *Issue `json:"issue"`
Comment *Comment `json:"comment"` PullRequest *PullRequest `json:"pull_request,omitempty"`
Changes *ChangesPayload `json:"changes,omitempty"` Comment *Comment `json:"comment"`
Repository *Repository `json:"repository"` Changes *ChangesPayload `json:"changes,omitempty"`
Sender *User `json:"sender"` Repository *Repository `json:"repository"`
IsPull bool `json:"is_pull"` Sender *User `json:"sender"`
IsPull bool `json:"is_pull"`
} }
// JSONPayload implements Payload // JSONPayload implements Payload

5
release-notes/5621.md Normal file
View file

@ -0,0 +1,5 @@
fix: [commit](https://codeberg.org/forgejo/forgejo/commit/f3f386545ee97b91f1aaac4142480e70a443c655) Always update expiration time when creating an artifact, so that artifacts from re-ran jobs do not get lost.
fix: [commit](https://codeberg.org/forgejo/forgejo/commit/c163bf6fb55c922ab0cf552b47475fc8fc8b99d9) Remove the button toolbar when deleting a diff comment.
feat: [commit](https://codeberg.org/forgejo/forgejo/commit/c3741d7fb0114691da73f00ae0ac9dced87e884d) The `requested_reviewers` data is included in more webhook events.
fix: [commit](https://codeberg.org/forgejo/forgejo/commit/e8700cee612f0aa769dc6929772d9b04c6c21807) Run scheduled tasks against the latest commit.
feat: [commit](https://codeberg.org/forgejo/forgejo/commit/89446e60a6e7ec3441f0c480164c09851ae54ce7) Support migrating GitHub/GitLab PR draft status.

View file

@ -41,80 +41,93 @@ func SearchIssues(ctx *context.APIContext) {
// parameters: // parameters:
// - name: state // - name: state
// in: query // in: query
// description: whether issue is open or closed // description: State of the issue
// type: string // type: string
// enum: [open, closed, all]
// default: open
// - name: labels // - name: labels
// in: query // in: query
// description: comma separated list of labels. Fetch only issues that have any of this labels. Non existent labels are discarded // description: Comma-separated list of label names. Fetch only issues that have any of these labels. Non existent labels are discarded.
// type: string // type: string
// - name: milestones // - name: milestones
// in: query // in: query
// description: comma separated list of milestone names. Fetch only issues that have any of this milestones. Non existent are discarded // description: Comma-separated list of milestone names. Fetch only issues that have any of these milestones. Non existent milestones are discarded.
// type: string // type: string
// - name: q // - name: q
// in: query // in: query
// description: search string // description: Search string
// type: string // type: string
// - name: priority_repo_id // - name: priority_repo_id
// in: query // in: query
// description: repository to prioritize in the results // description: Repository ID to prioritize in the results
// type: integer // type: integer
// format: int64 // format: int64
// - name: type // - name: type
// in: query // in: query
// description: filter by type (issues / pulls) if set // description: Filter by issue type
// type: string // type: string
// enum: [issues, pulls]
// - name: since // - name: since
// in: query // in: query
// description: Only show notifications updated after the given time. This is a timestamp in RFC 3339 format // description: Only show issues updated after the given time (RFC 3339 format)
// type: string // type: string
// format: date-time // format: date-time
// required: false
// - name: before // - name: before
// in: query // in: query
// description: Only show notifications updated before the given time. This is a timestamp in RFC 3339 format // description: Only show issues updated before the given time (RFC 3339 format)
// type: string // type: string
// format: date-time // format: date-time
// required: false
// - name: assigned // - name: assigned
// in: query // in: query
// description: filter (issues / pulls) assigned to you, default is false // description: Filter issues or pulls assigned to the authenticated user
// type: boolean // type: boolean
// default: false
// - name: created // - name: created
// in: query // in: query
// description: filter (issues / pulls) created by you, default is false // description: Filter issues or pulls created by the authenticated user
// type: boolean // type: boolean
// default: false
// - name: mentioned // - name: mentioned
// in: query // in: query
// description: filter (issues / pulls) mentioning you, default is false // description: Filter issues or pulls mentioning the authenticated user
// type: boolean // type: boolean
// default: false
// - name: review_requested // - name: review_requested
// in: query // in: query
// description: filter pulls requesting your review, default is false // description: Filter pull requests where the authenticated user's review was requested
// type: boolean // type: boolean
// default: false
// - name: reviewed // - name: reviewed
// in: query // in: query
// description: filter pulls reviewed by you, default is false // description: Filter pull requests reviewed by the authenticated user
// type: boolean // type: boolean
// default: false
// - name: owner // - name: owner
// in: query // in: query
// description: filter by owner // description: Filter by repository owner
// type: string // type: string
// - name: team // - name: team
// in: query // in: query
// description: filter by team (requires organization owner parameter to be provided) // description: Filter by team (requires organization owner parameter)
// type: string // type: string
// - name: page // - name: page
// in: query // in: query
// description: page number of results to return (1-based) // description: Page number of results to return (1-based)
// type: integer // type: integer
// minimum: 1
// default: 1
// - name: limit // - name: limit
// in: query // in: query
// description: page size of results // description: Number of items per page
// type: integer // type: integer
// minimum: 0
// responses: // responses:
// "200": // "200":
// "$ref": "#/responses/IssueList" // "$ref": "#/responses/IssueList"
// "400":
// "$ref": "#/responses/error"
// "422":
// "$ref": "#/responses/validationError"
before, since, err := context.GetQueryBeforeSince(ctx.Base) before, since, err := context.GetQueryBeforeSince(ctx.Base)
if err != nil { if err != nil {

View file

@ -119,11 +119,20 @@ func (input *notifyInput) Notify(ctx context.Context) {
} }
func notify(ctx context.Context, input *notifyInput) error { func notify(ctx context.Context, input *notifyInput) error {
shouldDetectSchedules := input.Event == webhook_module.HookEventPush && input.Ref.BranchName() == input.Repo.DefaultBranch
if input.Doer.IsActions() { if input.Doer.IsActions() {
// avoiding triggering cyclically, for example: // avoiding triggering cyclically, for example:
// a comment of an issue will trigger the runner to add a new comment as reply, // a comment of an issue will trigger the runner to add a new comment as reply,
// and the new comment will trigger the runner again. // and the new comment will trigger the runner again.
log.Debug("ignore executing %v for event %v whose doer is %v", getMethod(ctx), input.Event, input.Doer.Name) log.Debug("ignore executing %v for event %v whose doer is %v", getMethod(ctx), input.Event, input.Doer.Name)
// we should update schedule tasks in this case, because
// 1. schedule tasks cannot be triggered by other events, so cyclic triggering will not occur
// 2. some schedule tasks may update the repo periodically, so the refs of schedule tasks need to be updated
if shouldDetectSchedules {
return DetectAndHandleSchedules(ctx, input.Repo)
}
return nil return nil
} }
if input.Repo.IsEmpty || input.Repo.IsArchived { if input.Repo.IsEmpty || input.Repo.IsArchived {
@ -182,7 +191,6 @@ func notify(ctx context.Context, input *notifyInput) error {
var detectedWorkflows []*actions_module.DetectedWorkflow var detectedWorkflows []*actions_module.DetectedWorkflow
actionsConfig := input.Repo.MustGetUnit(ctx, unit_model.TypeActions).ActionsConfig() actionsConfig := input.Repo.MustGetUnit(ctx, unit_model.TypeActions).ActionsConfig()
shouldDetectSchedules := input.Event == webhook_module.HookEventPush && input.Ref.BranchName() == input.Repo.DefaultBranch
workflows, schedules, err := actions_module.DetectWorkflows(gitRepo, commit, workflows, schedules, err := actions_module.DetectWorkflows(gitRepo, commit,
input.Event, input.Event,
input.Payload, input.Payload,

View file

@ -760,10 +760,15 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*issues_model
pr.Updated = pr.Created pr.Updated = pr.Created
} }
prTitle := pr.Title
if pr.IsDraft && !issues_model.HasWorkInProgressPrefix(pr.Title) {
prTitle = fmt.Sprintf("%s %s", setting.Repository.PullRequest.WorkInProgressPrefixes[0], pr.Title)
}
issue := issues_model.Issue{ issue := issues_model.Issue{
RepoID: g.repo.ID, RepoID: g.repo.ID,
Repo: g.repo, Repo: g.repo,
Title: pr.Title, Title: prTitle,
Index: pr.Number, Index: pr.Number,
Content: pr.Content, Content: pr.Content,
MilestoneID: milestoneID, MilestoneID: milestoneID,

View file

@ -737,6 +737,7 @@ func (g *GithubDownloaderV3) GetPullRequests(page, perPage int) ([]*base.PullReq
PatchURL: pr.GetPatchURL(), // see below for SECURITY related issues here PatchURL: pr.GetPatchURL(), // see below for SECURITY related issues here
Reactions: reactions, Reactions: reactions,
ForeignIndex: int64(*pr.Number), ForeignIndex: int64(*pr.Number),
IsDraft: pr.GetDraft(),
}) })
// SECURITY: Ensure that the PR is safe // SECURITY: Ensure that the PR is safe

View file

@ -723,6 +723,7 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
PatchURL: pr.WebURL + ".patch", PatchURL: pr.WebURL + ".patch",
ForeignIndex: int64(pr.IID), ForeignIndex: int64(pr.IID),
Context: gitlabIssueContext{IsMergeRequest: true}, Context: gitlabIssueContext{IsMergeRequest: true},
IsDraft: pr.Draft,
}) })
// SECURITY: Ensure that the PR is safe // SECURITY: Ensure that the PR is safe

View file

@ -59,7 +59,7 @@ func (m *webhookNotifier) IssueClearLabels(ctx context.Context, doer *user_model
err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequestLabel, &api.PullRequestPayload{ err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequestLabel, &api.PullRequestPayload{
Action: api.HookIssueLabelCleared, Action: api.HookIssueLabelCleared,
Index: issue.Index, Index: issue.Index,
PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil), PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, doer),
Repository: convert.ToRepo(ctx, issue.Repo, permission), Repository: convert.ToRepo(ctx, issue.Repo, permission),
Sender: convert.ToUser(ctx, doer, nil), Sender: convert.ToUser(ctx, doer, nil),
}) })
@ -150,7 +150,7 @@ func (m *webhookNotifier) IssueChangeAssignee(ctx context.Context, doer *user_mo
} }
apiPullRequest := &api.PullRequestPayload{ apiPullRequest := &api.PullRequestPayload{
Index: issue.Index, Index: issue.Index,
PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil), PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, doer),
Repository: convert.ToRepo(ctx, issue.Repo, permission), Repository: convert.ToRepo(ctx, issue.Repo, permission),
Sender: convert.ToUser(ctx, doer, nil), Sender: convert.ToUser(ctx, doer, nil),
} }
@ -201,7 +201,7 @@ func (m *webhookNotifier) IssueChangeTitle(ctx context.Context, doer *user_model
From: oldTitle, From: oldTitle,
}, },
}, },
PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil), PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, doer),
Repository: convert.ToRepo(ctx, issue.Repo, permission), Repository: convert.ToRepo(ctx, issue.Repo, permission),
Sender: convert.ToUser(ctx, doer, nil), Sender: convert.ToUser(ctx, doer, nil),
}) })
@ -236,7 +236,7 @@ func (m *webhookNotifier) IssueChangeStatus(ctx context.Context, doer *user_mode
// Merge pull request calls issue.changeStatus so we need to handle separately. // Merge pull request calls issue.changeStatus so we need to handle separately.
apiPullRequest := &api.PullRequestPayload{ apiPullRequest := &api.PullRequestPayload{
Index: issue.Index, Index: issue.Index,
PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil), PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, doer),
Repository: convert.ToRepo(ctx, issue.Repo, permission), Repository: convert.ToRepo(ctx, issue.Repo, permission),
Sender: convert.ToUser(ctx, doer, nil), Sender: convert.ToUser(ctx, doer, nil),
CommitID: commitID, CommitID: commitID,
@ -307,7 +307,7 @@ func (m *webhookNotifier) NewPullRequest(ctx context.Context, pull *issues_model
if err := PrepareWebhooks(ctx, EventSource{Repository: pull.Issue.Repo}, webhook_module.HookEventPullRequest, &api.PullRequestPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: pull.Issue.Repo}, webhook_module.HookEventPullRequest, &api.PullRequestPayload{
Action: api.HookIssueOpened, Action: api.HookIssueOpened,
Index: pull.Issue.Index, Index: pull.Issue.Index,
PullRequest: convert.ToAPIPullRequest(ctx, pull, nil), PullRequest: convert.ToAPIPullRequest(ctx, pull, pull.Issue.Poster),
Repository: convert.ToRepo(ctx, pull.Issue.Repo, permission), Repository: convert.ToRepo(ctx, pull.Issue.Repo, permission),
Sender: convert.ToUser(ctx, pull.Issue.Poster, nil), Sender: convert.ToUser(ctx, pull.Issue.Poster, nil),
}); err != nil { }); err != nil {
@ -336,7 +336,7 @@ func (m *webhookNotifier) IssueChangeContent(ctx context.Context, doer *user_mod
From: oldContent, From: oldContent,
}, },
}, },
PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil), PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, doer),
Repository: convert.ToRepo(ctx, issue.Repo, permission), Repository: convert.ToRepo(ctx, issue.Repo, permission),
Sender: convert.ToUser(ctx, doer, nil), Sender: convert.ToUser(ctx, doer, nil),
}) })
@ -375,17 +375,20 @@ func (m *webhookNotifier) UpdateComment(ctx context.Context, doer *user_model.Us
} }
var eventType webhook_module.HookEventType var eventType webhook_module.HookEventType
var pullRequest *api.PullRequest
if c.Issue.IsPull { if c.Issue.IsPull {
eventType = webhook_module.HookEventPullRequestComment eventType = webhook_module.HookEventPullRequestComment
pullRequest = convert.ToAPIPullRequest(ctx, c.Issue.PullRequest, doer)
} else { } else {
eventType = webhook_module.HookEventIssueComment eventType = webhook_module.HookEventIssueComment
} }
permission, _ := access_model.GetUserRepoPermission(ctx, c.Issue.Repo, doer) permission, _ := access_model.GetUserRepoPermission(ctx, c.Issue.Repo, doer)
if err := PrepareWebhooks(ctx, EventSource{Repository: c.Issue.Repo}, eventType, &api.IssueCommentPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: c.Issue.Repo}, eventType, &api.IssueCommentPayload{
Action: api.HookIssueCommentEdited, Action: api.HookIssueCommentEdited,
Issue: convert.ToAPIIssue(ctx, doer, c.Issue), Issue: convert.ToAPIIssue(ctx, doer, c.Issue),
Comment: convert.ToAPIComment(ctx, c.Issue.Repo, c), PullRequest: pullRequest,
Comment: convert.ToAPIComment(ctx, c.Issue.Repo, c),
Changes: &api.ChangesPayload{ Changes: &api.ChangesPayload{
Body: &api.ChangesFromPayload{ Body: &api.ChangesFromPayload{
From: oldContent, From: oldContent,
@ -403,20 +406,23 @@ func (m *webhookNotifier) CreateIssueComment(ctx context.Context, doer *user_mod
issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User,
) { ) {
var eventType webhook_module.HookEventType var eventType webhook_module.HookEventType
var pullRequest *api.PullRequest
if issue.IsPull { if issue.IsPull {
eventType = webhook_module.HookEventPullRequestComment eventType = webhook_module.HookEventPullRequestComment
pullRequest = convert.ToAPIPullRequest(ctx, issue.PullRequest, doer)
} else { } else {
eventType = webhook_module.HookEventIssueComment eventType = webhook_module.HookEventIssueComment
} }
permission, _ := access_model.GetUserRepoPermission(ctx, repo, doer) permission, _ := access_model.GetUserRepoPermission(ctx, repo, doer)
if err := PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, eventType, &api.IssueCommentPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, eventType, &api.IssueCommentPayload{
Action: api.HookIssueCommentCreated, Action: api.HookIssueCommentCreated,
Issue: convert.ToAPIIssue(ctx, doer, issue), Issue: convert.ToAPIIssue(ctx, doer, issue),
Comment: convert.ToAPIComment(ctx, repo, comment), PullRequest: pullRequest,
Repository: convert.ToRepo(ctx, repo, permission), Comment: convert.ToAPIComment(ctx, repo, comment),
Sender: convert.ToUser(ctx, doer, nil), Repository: convert.ToRepo(ctx, repo, permission),
IsPull: issue.IsPull, Sender: convert.ToUser(ctx, doer, nil),
IsPull: issue.IsPull,
}); err != nil { }); err != nil {
log.Error("PrepareWebhooks [comment_id: %d]: %v", comment.ID, err) log.Error("PrepareWebhooks [comment_id: %d]: %v", comment.ID, err)
} }
@ -440,20 +446,23 @@ func (m *webhookNotifier) DeleteComment(ctx context.Context, doer *user_model.Us
} }
var eventType webhook_module.HookEventType var eventType webhook_module.HookEventType
var pullRequest *api.PullRequest
if comment.Issue.IsPull { if comment.Issue.IsPull {
eventType = webhook_module.HookEventPullRequestComment eventType = webhook_module.HookEventPullRequestComment
pullRequest = convert.ToAPIPullRequest(ctx, comment.Issue.PullRequest, doer)
} else { } else {
eventType = webhook_module.HookEventIssueComment eventType = webhook_module.HookEventIssueComment
} }
permission, _ := access_model.GetUserRepoPermission(ctx, comment.Issue.Repo, doer) permission, _ := access_model.GetUserRepoPermission(ctx, comment.Issue.Repo, doer)
if err := PrepareWebhooks(ctx, EventSource{Repository: comment.Issue.Repo}, eventType, &api.IssueCommentPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: comment.Issue.Repo}, eventType, &api.IssueCommentPayload{
Action: api.HookIssueCommentDeleted, Action: api.HookIssueCommentDeleted,
Issue: convert.ToAPIIssue(ctx, doer, comment.Issue), Issue: convert.ToAPIIssue(ctx, doer, comment.Issue),
Comment: convert.ToAPIComment(ctx, comment.Issue.Repo, comment), PullRequest: pullRequest,
Repository: convert.ToRepo(ctx, comment.Issue.Repo, permission), Comment: convert.ToAPIComment(ctx, comment.Issue.Repo, comment),
Sender: convert.ToUser(ctx, doer, nil), Repository: convert.ToRepo(ctx, comment.Issue.Repo, permission),
IsPull: comment.Issue.IsPull, Sender: convert.ToUser(ctx, doer, nil),
IsPull: comment.Issue.IsPull,
}); err != nil { }); err != nil {
log.Error("PrepareWebhooks [comment_id: %d]: %v", comment.ID, err) log.Error("PrepareWebhooks [comment_id: %d]: %v", comment.ID, err)
} }
@ -525,7 +534,7 @@ func (m *webhookNotifier) IssueChangeLabels(ctx context.Context, doer *user_mode
err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequestLabel, &api.PullRequestPayload{ err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequestLabel, &api.PullRequestPayload{
Action: api.HookIssueLabelUpdated, Action: api.HookIssueLabelUpdated,
Index: issue.Index, Index: issue.Index,
PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil), PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, doer),
Repository: convert.ToRepo(ctx, issue.Repo, access_model.Permission{AccessMode: perm.AccessModeOwner}), Repository: convert.ToRepo(ctx, issue.Repo, access_model.Permission{AccessMode: perm.AccessModeOwner}),
Sender: convert.ToUser(ctx, doer, nil), Sender: convert.ToUser(ctx, doer, nil),
}) })
@ -567,7 +576,7 @@ func (m *webhookNotifier) IssueChangeMilestone(ctx context.Context, doer *user_m
err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequestMilestone, &api.PullRequestPayload{ err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequestMilestone, &api.PullRequestPayload{
Action: hookAction, Action: hookAction,
Index: issue.Index, Index: issue.Index,
PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil), PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, doer),
Repository: convert.ToRepo(ctx, issue.Repo, permission), Repository: convert.ToRepo(ctx, issue.Repo, permission),
Sender: convert.ToUser(ctx, doer, nil), Sender: convert.ToUser(ctx, doer, nil),
}) })
@ -640,7 +649,7 @@ func (*webhookNotifier) MergePullRequest(ctx context.Context, doer *user_model.U
// Merge pull request calls issue.changeStatus so we need to handle separately. // Merge pull request calls issue.changeStatus so we need to handle separately.
apiPullRequest := &api.PullRequestPayload{ apiPullRequest := &api.PullRequestPayload{
Index: pr.Issue.Index, Index: pr.Issue.Index,
PullRequest: convert.ToAPIPullRequest(ctx, pr, nil), PullRequest: convert.ToAPIPullRequest(ctx, pr, doer),
Repository: convert.ToRepo(ctx, pr.Issue.Repo, permission), Repository: convert.ToRepo(ctx, pr.Issue.Repo, permission),
Sender: convert.ToUser(ctx, doer, nil), Sender: convert.ToUser(ctx, doer, nil),
Action: api.HookIssueClosed, Action: api.HookIssueClosed,
@ -668,7 +677,7 @@ func (m *webhookNotifier) PullRequestChangeTargetBranch(ctx context.Context, doe
From: oldBranch, From: oldBranch,
}, },
}, },
PullRequest: convert.ToAPIPullRequest(ctx, pr, nil), PullRequest: convert.ToAPIPullRequest(ctx, pr, doer),
Repository: convert.ToRepo(ctx, issue.Repo, mode), Repository: convert.ToRepo(ctx, issue.Repo, mode),
Sender: convert.ToUser(ctx, doer, nil), Sender: convert.ToUser(ctx, doer, nil),
}); err != nil { }); err != nil {
@ -703,11 +712,12 @@ func (m *webhookNotifier) PullRequestReview(ctx context.Context, pr *issues_mode
return return
} }
if err := PrepareWebhooks(ctx, EventSource{Repository: review.Issue.Repo}, reviewHookType, &api.PullRequestPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: review.Issue.Repo}, reviewHookType, &api.PullRequestPayload{
Action: api.HookIssueReviewed, Action: api.HookIssueReviewed,
Index: review.Issue.Index, Index: review.Issue.Index,
PullRequest: convert.ToAPIPullRequest(ctx, pr, nil), PullRequest: convert.ToAPIPullRequest(ctx, pr, review.Reviewer),
Repository: convert.ToRepo(ctx, review.Issue.Repo, permission), RequestedReviewer: convert.ToUser(ctx, review.Reviewer, nil),
Sender: convert.ToUser(ctx, review.Reviewer, nil), Repository: convert.ToRepo(ctx, review.Issue.Repo, permission),
Sender: convert.ToUser(ctx, review.Reviewer, nil),
Review: &api.ReviewPayload{ Review: &api.ReviewPayload{
Type: string(reviewHookType), Type: string(reviewHookType),
Content: review.Content, Content: review.Content,
@ -729,7 +739,7 @@ func (m *webhookNotifier) PullRequestReviewRequest(ctx context.Context, doer *us
} }
apiPullRequest := &api.PullRequestPayload{ apiPullRequest := &api.PullRequestPayload{
Index: issue.Index, Index: issue.Index,
PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil), PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, doer),
RequestedReviewer: convert.ToUser(ctx, reviewer, nil), RequestedReviewer: convert.ToUser(ctx, reviewer, nil),
Repository: convert.ToRepo(ctx, issue.Repo, permission), Repository: convert.ToRepo(ctx, issue.Repo, permission),
Sender: convert.ToUser(ctx, doer, nil), Sender: convert.ToUser(ctx, doer, nil),
@ -773,7 +783,7 @@ func (m *webhookNotifier) PullRequestSynchronized(ctx context.Context, doer *use
if err := PrepareWebhooks(ctx, EventSource{Repository: pr.Issue.Repo}, webhook_module.HookEventPullRequestSync, &api.PullRequestPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: pr.Issue.Repo}, webhook_module.HookEventPullRequestSync, &api.PullRequestPayload{
Action: api.HookIssueSynchronized, Action: api.HookIssueSynchronized,
Index: pr.Issue.Index, Index: pr.Issue.Index,
PullRequest: convert.ToAPIPullRequest(ctx, pr, nil), PullRequest: convert.ToAPIPullRequest(ctx, pr, doer),
Repository: convert.ToRepo(ctx, pr.Issue.Repo, access_model.Permission{AccessMode: perm.AccessModeOwner}), Repository: convert.ToRepo(ctx, pr.Issue.Repo, access_model.Permission{AccessMode: perm.AccessModeOwner}),
Sender: convert.ToUser(ctx, doer, nil), Sender: convert.ToUser(ctx, doer, nil),
}); err != nil { }); err != nil {

View file

@ -4196,107 +4196,125 @@
"operationId": "issueSearchIssues", "operationId": "issueSearchIssues",
"parameters": [ "parameters": [
{ {
"enum": [
"open",
"closed",
"all"
],
"type": "string", "type": "string",
"description": "whether issue is open or closed", "default": "open",
"description": "State of the issue",
"name": "state", "name": "state",
"in": "query" "in": "query"
}, },
{ {
"type": "string", "type": "string",
"description": "comma separated list of labels. Fetch only issues that have any of this labels. Non existent labels are discarded", "description": "Comma-separated list of label names. Fetch only issues that have any of these labels. Non existent labels are discarded.",
"name": "labels", "name": "labels",
"in": "query" "in": "query"
}, },
{ {
"type": "string", "type": "string",
"description": "comma separated list of milestone names. Fetch only issues that have any of this milestones. Non existent are discarded", "description": "Comma-separated list of milestone names. Fetch only issues that have any of these milestones. Non existent milestones are discarded.",
"name": "milestones", "name": "milestones",
"in": "query" "in": "query"
}, },
{ {
"type": "string", "type": "string",
"description": "search string", "description": "Search string",
"name": "q", "name": "q",
"in": "query" "in": "query"
}, },
{ {
"type": "integer", "type": "integer",
"format": "int64", "format": "int64",
"description": "repository to prioritize in the results", "description": "Repository ID to prioritize in the results",
"name": "priority_repo_id", "name": "priority_repo_id",
"in": "query" "in": "query"
}, },
{ {
"enum": [
"issues",
"pulls"
],
"type": "string", "type": "string",
"description": "filter by type (issues / pulls) if set", "description": "Filter by issue type",
"name": "type", "name": "type",
"in": "query" "in": "query"
}, },
{ {
"type": "string", "type": "string",
"format": "date-time", "format": "date-time",
"description": "Only show notifications updated after the given time. This is a timestamp in RFC 3339 format", "description": "Only show issues updated after the given time (RFC 3339 format)",
"name": "since", "name": "since",
"in": "query" "in": "query"
}, },
{ {
"type": "string", "type": "string",
"format": "date-time", "format": "date-time",
"description": "Only show notifications updated before the given time. This is a timestamp in RFC 3339 format", "description": "Only show issues updated before the given time (RFC 3339 format)",
"name": "before", "name": "before",
"in": "query" "in": "query"
}, },
{ {
"type": "boolean", "type": "boolean",
"description": "filter (issues / pulls) assigned to you, default is false", "default": false,
"description": "Filter issues or pulls assigned to the authenticated user",
"name": "assigned", "name": "assigned",
"in": "query" "in": "query"
}, },
{ {
"type": "boolean", "type": "boolean",
"description": "filter (issues / pulls) created by you, default is false", "default": false,
"description": "Filter issues or pulls created by the authenticated user",
"name": "created", "name": "created",
"in": "query" "in": "query"
}, },
{ {
"type": "boolean", "type": "boolean",
"description": "filter (issues / pulls) mentioning you, default is false", "default": false,
"description": "Filter issues or pulls mentioning the authenticated user",
"name": "mentioned", "name": "mentioned",
"in": "query" "in": "query"
}, },
{ {
"type": "boolean", "type": "boolean",
"description": "filter pulls requesting your review, default is false", "default": false,
"description": "Filter pull requests where the authenticated user's review was requested",
"name": "review_requested", "name": "review_requested",
"in": "query" "in": "query"
}, },
{ {
"type": "boolean", "type": "boolean",
"description": "filter pulls reviewed by you, default is false", "default": false,
"description": "Filter pull requests reviewed by the authenticated user",
"name": "reviewed", "name": "reviewed",
"in": "query" "in": "query"
}, },
{ {
"type": "string", "type": "string",
"description": "filter by owner", "description": "Filter by repository owner",
"name": "owner", "name": "owner",
"in": "query" "in": "query"
}, },
{ {
"type": "string", "type": "string",
"description": "filter by team (requires organization owner parameter to be provided)", "description": "Filter by team (requires organization owner parameter)",
"name": "team", "name": "team",
"in": "query" "in": "query"
}, },
{ {
"minimum": 1,
"type": "integer", "type": "integer",
"description": "page number of results to return (1-based)", "default": 1,
"description": "Page number of results to return (1-based)",
"name": "page", "name": "page",
"in": "query" "in": "query"
}, },
{ {
"minimum": 0,
"type": "integer", "type": "integer",
"description": "page size of results", "description": "Number of items per page",
"name": "limit", "name": "limit",
"in": "query" "in": "query"
} }
@ -4304,6 +4322,12 @@
"responses": { "responses": {
"200": { "200": {
"$ref": "#/responses/IssueList" "$ref": "#/responses/IssueList"
},
"400": {
"$ref": "#/responses/error"
},
"422": {
"$ref": "#/responses/validationError"
} }
} }
} }

View file

@ -8,7 +8,9 @@ export function initDiffFileTree() {
const fileTreeView = createApp(DiffFileTree); const fileTreeView = createApp(DiffFileTree);
fileTreeView.mount(el); fileTreeView.mount(el);
}
export function initDiffFileList() {
const fileListElement = document.getElementById('diff-file-list'); const fileListElement = document.getElementById('diff-file-list');
if (!fileListElement) return; if (!fileListElement) return;

View file

@ -1,7 +1,7 @@
import $ from 'jquery'; import $ from 'jquery';
import {initCompReactionSelector} from './comp/ReactionSelector.js'; import {initCompReactionSelector} from './comp/ReactionSelector.js';
import {initRepoIssueContentHistory} from './repo-issue-content.js'; import {initRepoIssueContentHistory} from './repo-issue-content.js';
import {initDiffFileTree} from './repo-diff-filetree.js'; import {initDiffFileTree, initDiffFileList} from './repo-diff-filetree.js';
import {initDiffCommitSelect} from './repo-diff-commitselect.js'; import {initDiffCommitSelect} from './repo-diff-commitselect.js';
import {validateTextareaNonEmpty} from './comp/ComboMarkdownEditor.js'; import {validateTextareaNonEmpty} from './comp/ComboMarkdownEditor.js';
import {initViewedCheckboxListenerFor, countAndUpdateViewedFiles, initExpandAndCollapseFilesButton} from './pull-view-file.js'; import {initViewedCheckboxListenerFor, countAndUpdateViewedFiles, initExpandAndCollapseFilesButton} from './pull-view-file.js';
@ -223,6 +223,7 @@ export function initRepoDiffView() {
initRepoDiffConversationForm(); initRepoDiffConversationForm();
if (!$('#diff-file-list').length) return; if (!$('#diff-file-list').length) return;
initDiffFileTree(); initDiffFileTree();
initDiffFileList();
initDiffCommitSelect(); initDiffCommitSelect();
initRepoDiffShowMore(); initRepoDiffShowMore();
initRepoDiffReviewButton(); initRepoDiffReviewButton();

View file

@ -209,14 +209,17 @@ export function initRepoIssueCommentDelete() {
const path = conversationHolder.getAttribute('data-path'); const path = conversationHolder.getAttribute('data-path');
const side = conversationHolder.getAttribute('data-side'); const side = conversationHolder.getAttribute('data-side');
const idx = conversationHolder.getAttribute('data-idx'); const idx = conversationHolder.getAttribute('data-idx');
const lineType = conversationHolder.closest('tr').getAttribute('data-line-type'); const lineType = conversationHolder.closest('tr')?.getAttribute('data-line-type');
if (lineType === 'same') { // the conversation holder could appear either on the "Conversation" page, or the "Files Changed" page
document.querySelector(`[data-path="${path}"] .add-code-comment[data-idx="${idx}"]`).classList.remove('tw-invisible'); // on the Conversation page, there is no parent "tr", so no need to do anything for "add-code-comment"
} else { if (lineType) {
document.querySelector(`[data-path="${path}"] .add-code-comment[data-side="${side}"][data-idx="${idx}"]`).classList.remove('tw-invisible'); if (lineType === 'same') {
document.querySelector(`[data-path="${path}"] .add-code-comment[data-idx="${idx}"]`).classList.remove('tw-invisible');
} else {
document.querySelector(`[data-path="${path}"] .add-code-comment[data-side="${side}"][data-idx="${idx}"]`).classList.remove('tw-invisible');
}
} }
conversationHolder.remove(); conversationHolder.remove();
} }