mirror of
https://github.com/go-gitea/gitea.git
synced 2026-09-24 06:14:37 +02:00
Merge remote-tracking branch 'upstream/main' into limit-repo-size
This commit is contained in:
@@ -64,12 +64,7 @@ func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error {
|
||||
}
|
||||
}
|
||||
|
||||
for _, job := range jobs {
|
||||
if err := CreateCommitStatus(ctx, job); err != nil {
|
||||
log.Error("Update commit status for job %v failed: %v", job.ID, err)
|
||||
// go on
|
||||
}
|
||||
}
|
||||
CreateCommitStatus(ctx, jobs...)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -96,10 +91,7 @@ func CancelAbandonedJobs(ctx context.Context) error {
|
||||
log.Warn("cancel abandoned job %v: %v", job.ID, err)
|
||||
// go on
|
||||
}
|
||||
if err := CreateCommitStatus(ctx, job); err != nil {
|
||||
log.Error("Update commit status for job %v failed: %v", job.ID, err)
|
||||
// go on
|
||||
}
|
||||
CreateCommitStatus(ctx, job)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -6,79 +6,80 @@ package actions
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
actions_model "code.gitea.io/gitea/models/actions"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
git_model "code.gitea.io/gitea/models/git"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
webhook_module "code.gitea.io/gitea/modules/webhook"
|
||||
|
||||
"github.com/nektos/act/pkg/jobparser"
|
||||
)
|
||||
|
||||
func CreateCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) error {
|
||||
// CreateCommitStatus creates a commit status for the given job.
|
||||
// It won't return an error failed, but will log it, because it's not critical.
|
||||
func CreateCommitStatus(ctx context.Context, jobs ...*actions_model.ActionRunJob) {
|
||||
for _, job := range jobs {
|
||||
if err := createCommitStatus(ctx, job); err != nil {
|
||||
log.Error("Failed to create commit status for job %d: %v", job.ID, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func createCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) error {
|
||||
if err := job.LoadAttributes(ctx); err != nil {
|
||||
return fmt.Errorf("load run: %w", err)
|
||||
}
|
||||
|
||||
run := job.Run
|
||||
var (
|
||||
sha string
|
||||
creatorID int64
|
||||
)
|
||||
|
||||
var (
|
||||
sha string
|
||||
event string
|
||||
)
|
||||
switch run.Event {
|
||||
case webhook_module.HookEventPush:
|
||||
event = "push"
|
||||
payload, err := run.GetPushEventPayload()
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetPushEventPayload: %w", err)
|
||||
}
|
||||
|
||||
// Since the payload comes from json data, we should check if it's broken, or it will cause panic
|
||||
switch {
|
||||
case payload.Repo == nil:
|
||||
return fmt.Errorf("repo is missing in event payload")
|
||||
case payload.Pusher == nil:
|
||||
return fmt.Errorf("pusher is missing in event payload")
|
||||
case payload.HeadCommit == nil:
|
||||
if payload.HeadCommit == nil {
|
||||
return fmt.Errorf("head commit is missing in event payload")
|
||||
}
|
||||
|
||||
sha = payload.HeadCommit.ID
|
||||
creatorID = payload.Pusher.ID
|
||||
case webhook_module.HookEventPullRequest, webhook_module.HookEventPullRequestSync:
|
||||
event = "pull_request"
|
||||
payload, err := run.GetPullRequestEventPayload()
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetPullRequestEventPayload: %w", err)
|
||||
}
|
||||
|
||||
switch {
|
||||
case payload.PullRequest == nil:
|
||||
if payload.PullRequest == nil {
|
||||
return fmt.Errorf("pull request is missing in event payload")
|
||||
case payload.PullRequest.Head == nil:
|
||||
} else if payload.PullRequest.Head == nil {
|
||||
return fmt.Errorf("head of pull request is missing in event payload")
|
||||
case payload.PullRequest.Head.Repository == nil:
|
||||
return fmt.Errorf("head repository of pull request is missing in event payload")
|
||||
case payload.PullRequest.Head.Repository.Owner == nil:
|
||||
return fmt.Errorf("owner of head repository of pull request is missing in evnt payload")
|
||||
}
|
||||
|
||||
sha = payload.PullRequest.Head.Sha
|
||||
creatorID = payload.PullRequest.Head.Repository.Owner.ID
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
repo := run.Repo
|
||||
ctxname := job.Name
|
||||
state := toCommitStatus(job.Status)
|
||||
creator, err := user_model.GetUserByID(ctx, creatorID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetUserByID: %w", err)
|
||||
// TODO: store workflow name as a field in ActionRun to avoid parsing
|
||||
runName := path.Base(run.WorkflowID)
|
||||
if wfs, err := jobparser.Parse(job.WorkflowPayload); err == nil && len(wfs) > 0 {
|
||||
runName = wfs[0].Name
|
||||
}
|
||||
ctxname := fmt.Sprintf("%s / %s (%s)", runName, job.Name, event)
|
||||
state := toCommitStatus(job.Status)
|
||||
if statuses, _, err := git_model.GetLatestCommitStatus(ctx, repo.ID, sha, db.ListOptions{}); err == nil {
|
||||
for _, v := range statuses {
|
||||
if v.Context == ctxname {
|
||||
if v.State == state {
|
||||
// no need to update
|
||||
return nil
|
||||
}
|
||||
break
|
||||
@@ -88,16 +89,41 @@ func CreateCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er
|
||||
return fmt.Errorf("GetLatestCommitStatus: %w", err)
|
||||
}
|
||||
|
||||
description := ""
|
||||
switch job.Status {
|
||||
// TODO: if we want support description in different languages, we need to support i18n placeholders in it
|
||||
case actions_model.StatusSuccess:
|
||||
description = fmt.Sprintf("Successful in %s", job.Duration())
|
||||
case actions_model.StatusFailure:
|
||||
description = fmt.Sprintf("Failing after %s", job.Duration())
|
||||
case actions_model.StatusCancelled:
|
||||
description = "Has been cancelled"
|
||||
case actions_model.StatusSkipped:
|
||||
description = "Has been skipped"
|
||||
case actions_model.StatusRunning:
|
||||
description = "Has started running"
|
||||
case actions_model.StatusWaiting:
|
||||
description = "Waiting to run"
|
||||
case actions_model.StatusBlocked:
|
||||
description = "Blocked by required conditions"
|
||||
}
|
||||
|
||||
index, err := getIndexOfJob(ctx, job)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getIndexOfJob: %w", err)
|
||||
}
|
||||
|
||||
creator := user_model.NewActionsUser()
|
||||
if err := git_model.NewCommitStatus(ctx, git_model.NewCommitStatusOptions{
|
||||
Repo: repo,
|
||||
SHA: sha,
|
||||
Creator: creator,
|
||||
CommitStatus: &git_model.CommitStatus{
|
||||
SHA: sha,
|
||||
TargetURL: run.Link(),
|
||||
Description: "",
|
||||
TargetURL: fmt.Sprintf("%s/jobs/%d", run.Link(), index),
|
||||
Description: description,
|
||||
Context: ctxname,
|
||||
CreatorID: creatorID,
|
||||
CreatorID: creator.ID,
|
||||
State: state,
|
||||
},
|
||||
}); err != nil {
|
||||
@@ -109,9 +135,9 @@ func CreateCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er
|
||||
|
||||
func toCommitStatus(status actions_model.Status) api.CommitStatusState {
|
||||
switch status {
|
||||
case actions_model.StatusSuccess:
|
||||
case actions_model.StatusSuccess, actions_model.StatusSkipped:
|
||||
return api.CommitStatusSuccess
|
||||
case actions_model.StatusFailure, actions_model.StatusCancelled, actions_model.StatusSkipped:
|
||||
case actions_model.StatusFailure, actions_model.StatusCancelled:
|
||||
return api.CommitStatusFailure
|
||||
case actions_model.StatusWaiting, actions_model.StatusBlocked:
|
||||
return api.CommitStatusPending
|
||||
@@ -121,3 +147,17 @@ func toCommitStatus(status actions_model.Status) api.CommitStatusState {
|
||||
return api.CommitStatusError
|
||||
}
|
||||
}
|
||||
|
||||
func getIndexOfJob(ctx context.Context, job *actions_model.ActionRunJob) (int, error) {
|
||||
// TODO: store job index as a field in ActionRunJob to avoid this
|
||||
jobs, err := actions_model.GetRunJobsByRunID(ctx, job.RunID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
for i, v := range jobs {
|
||||
if v.ID == job.ID {
|
||||
return i, nil
|
||||
}
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
@@ -45,11 +45,11 @@ func jobEmitterQueueHandle(data ...queue.Data) []queue.Data {
|
||||
}
|
||||
|
||||
func checkJobsOfRun(ctx context.Context, runID int64) error {
|
||||
return db.WithTx(ctx, func(ctx context.Context) error {
|
||||
jobs, _, err := actions_model.FindRunJobs(ctx, actions_model.FindRunJobOptions{RunID: runID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
jobs, _, err := actions_model.FindRunJobs(ctx, actions_model.FindRunJobOptions{RunID: runID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := db.WithTx(ctx, func(ctx context.Context) error {
|
||||
idToJobs := make(map[string][]*actions_model.ActionRunJob, len(jobs))
|
||||
for _, job := range jobs {
|
||||
idToJobs[job.JobID] = append(idToJobs[job.JobID], job)
|
||||
@@ -67,7 +67,11 @@ func checkJobsOfRun(ctx context.Context, runID int64) error {
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
CreateCommitStatus(ctx, jobs...)
|
||||
return nil
|
||||
}
|
||||
|
||||
type jobStatusResolver struct {
|
||||
|
||||
@@ -443,17 +443,17 @@ func (n *actionsNotifier) NotifySyncDeleteRef(ctx context.Context, pusher *user_
|
||||
|
||||
func (n *actionsNotifier) NotifyNewRelease(ctx context.Context, rel *repo_model.Release) {
|
||||
ctx = withMethod(ctx, "NotifyNewRelease")
|
||||
notifyRelease(ctx, rel.Publisher, rel, rel.Sha1, api.HookReleasePublished)
|
||||
notifyRelease(ctx, rel.Publisher, rel, api.HookReleasePublished)
|
||||
}
|
||||
|
||||
func (n *actionsNotifier) NotifyUpdateRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release) {
|
||||
ctx = withMethod(ctx, "NotifyUpdateRelease")
|
||||
notifyRelease(ctx, doer, rel, rel.Sha1, api.HookReleaseUpdated)
|
||||
notifyRelease(ctx, doer, rel, api.HookReleaseUpdated)
|
||||
}
|
||||
|
||||
func (n *actionsNotifier) NotifyDeleteRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release) {
|
||||
ctx = withMethod(ctx, "NotifyDeleteRelease")
|
||||
notifyRelease(ctx, doer, rel, rel.Sha1, api.HookReleaseDeleted)
|
||||
notifyRelease(ctx, doer, rel, api.HookReleaseDeleted)
|
||||
}
|
||||
|
||||
func (n *actionsNotifier) NotifyPackageCreate(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) {
|
||||
|
||||
@@ -127,6 +127,11 @@ func notify(ctx context.Context, input *notifyInput) error {
|
||||
defer gitRepo.Close()
|
||||
|
||||
ref := input.Ref
|
||||
if input.Event == webhook_module.HookEventDelete {
|
||||
// The event is deleting a reference, so it will fail to get the commit for a deleted reference.
|
||||
// Set ref to empty string to fall back to the default branch.
|
||||
ref = ""
|
||||
}
|
||||
if ref == "" {
|
||||
ref = input.Repo.DefaultBranch
|
||||
}
|
||||
@@ -152,6 +157,21 @@ func notify(ctx context.Context, input *notifyInput) error {
|
||||
return fmt.Errorf("json.Marshal: %w", err)
|
||||
}
|
||||
|
||||
isForkPullRequest := false
|
||||
if pr := input.PullRequest; pr != nil {
|
||||
switch pr.Flow {
|
||||
case issues_model.PullRequestFlowGithub:
|
||||
isForkPullRequest = pr.IsFromFork()
|
||||
case issues_model.PullRequestFlowAGit:
|
||||
// There is no fork concept in agit flow, anyone with read permission can push refs/for/<target-branch>/<topic-branch> to the repo.
|
||||
// So we can treat it as a fork pull request because it may be from an untrusted user
|
||||
isForkPullRequest = true
|
||||
default:
|
||||
// unknown flow, assume it's a fork pull request to be safe
|
||||
isForkPullRequest = true
|
||||
}
|
||||
}
|
||||
|
||||
for id, content := range workflows {
|
||||
run := &actions_model.ActionRun{
|
||||
Title: strings.SplitN(commit.CommitMessage, "\n", 2)[0],
|
||||
@@ -161,7 +181,7 @@ func notify(ctx context.Context, input *notifyInput) error {
|
||||
TriggerUserID: input.Doer.ID,
|
||||
Ref: ref,
|
||||
CommitSHA: commit.ID.String(),
|
||||
IsForkPullRequest: input.PullRequest != nil && input.PullRequest.IsFromFork(),
|
||||
IsForkPullRequest: isForkPullRequest,
|
||||
Event: input.Event,
|
||||
EventPayload: string(p),
|
||||
Status: actions_model.StatusWaiting,
|
||||
@@ -185,12 +205,7 @@ func notify(ctx context.Context, input *notifyInput) error {
|
||||
if jobs, _, err := actions_model.FindRunJobs(ctx, actions_model.FindRunJobOptions{RunID: run.ID}); err != nil {
|
||||
log.Error("FindRunJobs: %v", err)
|
||||
} else {
|
||||
for _, job := range jobs {
|
||||
if err := CreateCommitStatus(ctx, job); err != nil {
|
||||
log.Error("Update commit status for job %v failed: %v", job.ID, err)
|
||||
// go on
|
||||
}
|
||||
}
|
||||
CreateCommitStatus(ctx, jobs...)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -201,7 +216,7 @@ func newNotifyInputFromIssue(issue *issues_model.Issue, event webhook_module.Hoo
|
||||
return newNotifyInput(issue.Repo, issue.Poster, event)
|
||||
}
|
||||
|
||||
func notifyRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release, ref string, action api.HookReleaseAction) {
|
||||
func notifyRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release, action api.HookReleaseAction) {
|
||||
if err := rel.LoadAttributes(ctx); err != nil {
|
||||
log.Error("LoadAttributes: %v", err)
|
||||
return
|
||||
@@ -210,7 +225,7 @@ func notifyRelease(ctx context.Context, doer *user_model.User, rel *repo_model.R
|
||||
mode, _ := access_model.AccessLevel(ctx, doer, rel.Repo)
|
||||
|
||||
newNotifyInput(rel.Repo, doer, webhook_module.HookEventRelease).
|
||||
WithRef(ref).
|
||||
WithRef(git.TagPrefix + rel.TagName).
|
||||
WithPayload(&api.ReleasePayload{
|
||||
Action: action,
|
||||
Release: convert.ToRelease(ctx, rel),
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"code.gitea.io/gitea/models/db"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/auth/webauthn"
|
||||
gitea_context "code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/session"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
@@ -91,5 +92,7 @@ func handleSignIn(resp http.ResponseWriter, req *http.Request, sess SessionStore
|
||||
middleware.SetLocaleCookie(resp, user.Language, 0)
|
||||
|
||||
// Clear whatever CSRF has right now, force to generate a new one
|
||||
middleware.DeleteCSRFCookie(resp)
|
||||
if ctx := gitea_context.GetContext(req); ctx != nil {
|
||||
ctx.Csrf.DeleteCookie(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ func (source *Source) listLdapGroupMemberships(l *ldap.Conn, uid string, applyGr
|
||||
}
|
||||
|
||||
var searchFilter string
|
||||
if applyGroupFilter {
|
||||
if applyGroupFilter && groupFilter != "" {
|
||||
searchFilter = fmt.Sprintf("(&(%s)(%s=%s))", groupFilter, source.GroupMemberUID, ldap.EscapeFilter(uid))
|
||||
} else {
|
||||
searchFilter = fmt.Sprintf("(%s=%s)", source.GroupMemberUID, ldap.EscapeFilter(uid))
|
||||
|
||||
@@ -52,11 +52,11 @@ func resolveMappedMemberships(sourceUserGroups container.Set[string], sourceGrou
|
||||
isUserInGroup := sourceUserGroups.Contains(group)
|
||||
if isUserInGroup {
|
||||
for org, teams := range memberships {
|
||||
membershipsToAdd[org] = teams
|
||||
membershipsToAdd[org] = append(membershipsToAdd[org], teams...)
|
||||
}
|
||||
} else {
|
||||
for org, teams := range memberships {
|
||||
membershipsToRemove[org] = teams
|
||||
membershipsToRemove[org] = append(membershipsToRemove[org], teams...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@ import (
|
||||
"code.gitea.io/gitea/models/avatars"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
gitea_context "code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/templates"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/web/middleware"
|
||||
"code.gitea.io/gitea/services/auth/source/sspi"
|
||||
@@ -23,7 +23,6 @@ import (
|
||||
|
||||
gouuid "github.com/google/uuid"
|
||||
"github.com/quasoft/websspi"
|
||||
"github.com/unrolled/render"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -47,9 +46,7 @@ var (
|
||||
// via the built-in SSPI module in Windows for SPNEGO authentication.
|
||||
// On successful authentication returns a valid user object.
|
||||
// Returns nil if authentication fails.
|
||||
type SSPI struct {
|
||||
rnd *render.Render
|
||||
}
|
||||
type SSPI struct{}
|
||||
|
||||
// Init creates a new global websspi.Authenticator object
|
||||
func (s *SSPI) Init(ctx context.Context) error {
|
||||
@@ -59,7 +56,6 @@ func (s *SSPI) Init(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, s.rnd = templates.HTMLRenderer(ctx)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -102,12 +98,9 @@ func (s *SSPI) Verify(req *http.Request, w http.ResponseWriter, store DataStore,
|
||||
}
|
||||
store.GetData()["EnableOpenIDSignIn"] = setting.Service.EnableOpenIDSignIn
|
||||
store.GetData()["EnableSSPI"] = true
|
||||
|
||||
err := s.rnd.HTML(w, http.StatusUnauthorized, string(tplSignIn), templates.BaseVars().Merge(store.GetData()))
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
}
|
||||
|
||||
// in this case, the store is Gitea's web Context
|
||||
// FIXME: it doesn't look good to render the page here, why not redirect?
|
||||
store.(*gitea_context.Context).HTML(http.StatusUnauthorized, tplSignIn)
|
||||
return nil, err
|
||||
}
|
||||
if outToken != "" {
|
||||
|
||||
@@ -29,6 +29,27 @@ func UserAssignmentWeb() func(ctx *context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// UserIDAssignmentAPI returns a middleware to handle context-user assignment for api routes
|
||||
func UserIDAssignmentAPI() func(ctx *context.APIContext) {
|
||||
return func(ctx *context.APIContext) {
|
||||
userID := ctx.ParamsInt64(":user-id")
|
||||
|
||||
if ctx.IsSigned && ctx.Doer.ID == userID {
|
||||
ctx.ContextUser = ctx.Doer
|
||||
} else {
|
||||
var err error
|
||||
ctx.ContextUser, err = user_model.GetUserByID(ctx, userID)
|
||||
if err != nil {
|
||||
if user_model.IsErrUserNotExist(err) {
|
||||
ctx.Error(http.StatusNotFound, "GetUserByID", err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "GetUserByID", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UserAssignmentAPI returns a middleware to handle context-user assignment for api routes
|
||||
func UserAssignmentAPI() func(ctx *context.APIContext) {
|
||||
return func(ctx *context.APIContext) {
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package convert
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
activities_model "code.gitea.io/gitea/models/activities"
|
||||
perm_model "code.gitea.io/gitea/models/perm"
|
||||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
)
|
||||
|
||||
func ToActivity(ctx context.Context, ac *activities_model.Action, doer *user_model.User) *api.Activity {
|
||||
p, err := access_model.GetUserRepoPermission(ctx, ac.Repo, doer)
|
||||
if err != nil {
|
||||
log.Error("GetUserRepoPermission[%d]: %v", ac.RepoID, err)
|
||||
p.AccessMode = perm_model.AccessModeNone
|
||||
}
|
||||
|
||||
result := &api.Activity{
|
||||
ID: ac.ID,
|
||||
UserID: ac.UserID,
|
||||
OpType: ac.OpType.String(),
|
||||
ActUserID: ac.ActUserID,
|
||||
ActUser: ToUser(ctx, ac.ActUser, doer),
|
||||
RepoID: ac.RepoID,
|
||||
Repo: ToRepo(ctx, ac.Repo, p.AccessMode),
|
||||
RefName: ac.RefName,
|
||||
IsPrivate: ac.IsPrivate,
|
||||
Content: ac.Content,
|
||||
Created: ac.CreatedUnix.AsTime(),
|
||||
}
|
||||
|
||||
if ac.Comment != nil {
|
||||
result.CommentID = ac.CommentID
|
||||
result.Comment = ToComment(ctx, ac.Comment)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func ToActivities(ctx context.Context, al activities_model.ActionList, doer *user_model.User) []*api.Activity {
|
||||
result := make([]*api.Activity, 0, len(al))
|
||||
for _, ac := range al {
|
||||
result = append(result, ToActivity(ctx, ac, doer))
|
||||
}
|
||||
return result
|
||||
}
|
||||
+20
-16
@@ -32,21 +32,15 @@ func ToAPIIssue(ctx context.Context, issue *issues_model.Issue) *api.Issue {
|
||||
if err := issue.LoadRepo(ctx); err != nil {
|
||||
return &api.Issue{}
|
||||
}
|
||||
if err := issue.Repo.LoadOwner(ctx); err != nil {
|
||||
return &api.Issue{}
|
||||
}
|
||||
|
||||
apiIssue := &api.Issue{
|
||||
ID: issue.ID,
|
||||
URL: issue.APIURL(),
|
||||
HTMLURL: issue.HTMLURL(),
|
||||
Index: issue.Index,
|
||||
Poster: ToUser(ctx, issue.Poster, nil),
|
||||
Title: issue.Title,
|
||||
Body: issue.Content,
|
||||
Attachments: ToAttachments(issue.Attachments),
|
||||
Ref: issue.Ref,
|
||||
Labels: ToLabelList(issue.Labels, issue.Repo, issue.Repo.Owner),
|
||||
State: issue.State(),
|
||||
IsLocked: issue.IsLocked,
|
||||
Comments: issue.NumComments,
|
||||
@@ -54,11 +48,19 @@ func ToAPIIssue(ctx context.Context, issue *issues_model.Issue) *api.Issue {
|
||||
Updated: issue.UpdatedUnix.AsTime(),
|
||||
}
|
||||
|
||||
apiIssue.Repo = &api.RepositoryMeta{
|
||||
ID: issue.Repo.ID,
|
||||
Name: issue.Repo.Name,
|
||||
Owner: issue.Repo.OwnerName,
|
||||
FullName: issue.Repo.FullName(),
|
||||
if issue.Repo != nil {
|
||||
if err := issue.Repo.LoadOwner(ctx); err != nil {
|
||||
return &api.Issue{}
|
||||
}
|
||||
apiIssue.URL = issue.APIURL()
|
||||
apiIssue.HTMLURL = issue.HTMLURL()
|
||||
apiIssue.Labels = ToLabelList(issue.Labels, issue.Repo, issue.Repo.Owner)
|
||||
apiIssue.Repo = &api.RepositoryMeta{
|
||||
ID: issue.Repo.ID,
|
||||
Name: issue.Repo.Name,
|
||||
Owner: issue.Repo.OwnerName,
|
||||
FullName: issue.Repo.FullName(),
|
||||
}
|
||||
}
|
||||
|
||||
if issue.ClosedUnix != 0 {
|
||||
@@ -85,11 +87,13 @@ func ToAPIIssue(ctx context.Context, issue *issues_model.Issue) *api.Issue {
|
||||
if err := issue.LoadPullRequest(ctx); err != nil {
|
||||
return &api.Issue{}
|
||||
}
|
||||
apiIssue.PullRequest = &api.PullRequestMeta{
|
||||
HasMerged: issue.PullRequest.HasMerged,
|
||||
}
|
||||
if issue.PullRequest.HasMerged {
|
||||
apiIssue.PullRequest.Merged = issue.PullRequest.MergedUnix.AsTimePtr()
|
||||
if issue.PullRequest != nil {
|
||||
apiIssue.PullRequest = &api.PullRequestMeta{
|
||||
HasMerged: issue.PullRequest.HasMerged,
|
||||
}
|
||||
if issue.PullRequest.HasMerged {
|
||||
apiIssue.PullRequest.Merged = issue.PullRequest.MergedUnix.AsTimePtr()
|
||||
}
|
||||
}
|
||||
}
|
||||
if issue.DeadlineUnix != 0 {
|
||||
|
||||
@@ -695,7 +695,7 @@ type UpdateAllowEditsForm struct {
|
||||
type NewReleaseForm struct {
|
||||
TagName string `binding:"Required;GitRefName;MaxSize(255)"`
|
||||
Target string `form:"tag_target" binding:"Required;MaxSize(255)"`
|
||||
Title string `binding:"Required;MaxSize(255)"`
|
||||
Title string `binding:"MaxSize(255)"`
|
||||
Content string
|
||||
Draft string
|
||||
TagOnly string
|
||||
|
||||
+22
-3
@@ -17,6 +17,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
actions_model "code.gitea.io/gitea/models/actions"
|
||||
git_model "code.gitea.io/gitea/models/git"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
@@ -125,7 +126,6 @@ func DownloadHandler(ctx *context.Context) {
|
||||
_, err = content.Seek(fromByte, io.SeekStart)
|
||||
if err != nil {
|
||||
log.Error("Whilst trying to read LFS OID[%s]: Unable to seek to %d Error: %v", meta.Oid, fromByte, err)
|
||||
|
||||
writeStatus(ctx, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@@ -333,10 +333,11 @@ func UploadHandler(ctx *context.Context) {
|
||||
log.Error("Upload does not match LFS MetaObject [%s]. Error: %v", p.Oid, err)
|
||||
writeStatusMessage(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
} else {
|
||||
log.Error("Error whilst uploadOrVerify LFS OID[%s]: %v", p.Oid, err)
|
||||
writeStatus(ctx, http.StatusInternalServerError)
|
||||
}
|
||||
if _, err = git_model.RemoveLFSMetaObjectByOid(ctx, repository.ID, p.Oid); err != nil {
|
||||
log.Error("Error whilst removing metaobject for LFS OID[%s]: %v", p.Oid, err)
|
||||
log.Error("Error whilst removing MetaObject for LFS OID[%s]: %v", p.Oid, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -364,6 +365,7 @@ func VerifyHandler(ctx *context.Context) {
|
||||
|
||||
status := http.StatusOK
|
||||
if err != nil {
|
||||
log.Error("Error whilst verifying LFS OID[%s]: %v", p.Oid, err)
|
||||
status = http.StatusInternalServerError
|
||||
} else if !ok {
|
||||
status = http.StatusNotFound
|
||||
@@ -495,10 +497,27 @@ func authenticate(ctx *context.Context, repository *repo_model.Repository, autho
|
||||
accessMode = perm.AccessModeWrite
|
||||
}
|
||||
|
||||
if ctx.Data["IsActionsToken"] == true {
|
||||
taskID := ctx.Data["ActionsTaskID"].(int64)
|
||||
task, err := actions_model.GetTaskByID(ctx, taskID)
|
||||
if err != nil {
|
||||
log.Error("Unable to GetTaskByID for task[%d] Error: %v", taskID, err)
|
||||
return false
|
||||
}
|
||||
if task.RepoID != repository.ID {
|
||||
return false
|
||||
}
|
||||
|
||||
if task.IsForkPullRequest {
|
||||
return accessMode <= perm.AccessModeRead
|
||||
}
|
||||
return accessMode <= perm.AccessModeWrite
|
||||
}
|
||||
|
||||
// ctx.IsSigned is unnecessary here, this will be checked in perm.CanAccess
|
||||
perm, err := access_model.GetUserRepoPermission(ctx, repository, ctx.Doer)
|
||||
if err != nil {
|
||||
log.Error("Unable to GetUserRepoPermission for user %-v in repo %-v Error: %v", ctx.Doer, repository)
|
||||
log.Error("Unable to GetUserRepoPermission for user %-v in repo %-v Error: %v", ctx.Doer, repository, err)
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ package migrations
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/google/go-github/v45/github"
|
||||
"github.com/google/go-github/v51/github"
|
||||
)
|
||||
|
||||
// ErrRepoNotCreated returns the error that repository not created
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"github.com/google/go-github/v45/github"
|
||||
"github.com/google/go-github/v51/github"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
@@ -259,11 +259,11 @@ func (g *GithubDownloaderV3) GetMilestones() ([]*base.Milestone, error) {
|
||||
milestones = append(milestones, &base.Milestone{
|
||||
Title: m.GetTitle(),
|
||||
Description: m.GetDescription(),
|
||||
Deadline: m.DueOn,
|
||||
Deadline: convertGithubTimestampToTime(m.DueOn),
|
||||
State: state,
|
||||
Created: m.GetCreatedAt(),
|
||||
Updated: m.UpdatedAt,
|
||||
Closed: m.ClosedAt,
|
||||
Created: m.GetCreatedAt().Time,
|
||||
Updated: convertGithubTimestampToTime(m.UpdatedAt),
|
||||
Closed: convertGithubTimestampToTime(m.ClosedAt),
|
||||
})
|
||||
}
|
||||
if len(ms) < perPage {
|
||||
@@ -486,11 +486,11 @@ func (g *GithubDownloaderV3) GetIssues(page, perPage int) ([]*base.Issue, bool,
|
||||
Content: issue.GetBody(),
|
||||
Milestone: issue.GetMilestone().GetTitle(),
|
||||
State: issue.GetState(),
|
||||
Created: issue.GetCreatedAt(),
|
||||
Updated: issue.GetUpdatedAt(),
|
||||
Created: issue.GetCreatedAt().Time,
|
||||
Updated: issue.GetUpdatedAt().Time,
|
||||
Labels: labels,
|
||||
Reactions: reactions,
|
||||
Closed: issue.ClosedAt,
|
||||
Closed: &issue.ClosedAt.Time,
|
||||
IsLocked: issue.GetLocked(),
|
||||
Assignees: assignees,
|
||||
ForeignIndex: int64(*issue.Number),
|
||||
@@ -565,8 +565,8 @@ func (g *GithubDownloaderV3) getComments(commentable base.Commentable) ([]*base.
|
||||
PosterName: comment.GetUser().GetLogin(),
|
||||
PosterEmail: comment.GetUser().GetEmail(),
|
||||
Content: comment.GetBody(),
|
||||
Created: comment.GetCreatedAt(),
|
||||
Updated: comment.GetUpdatedAt(),
|
||||
Created: comment.GetCreatedAt().Time,
|
||||
Updated: comment.GetUpdatedAt().Time,
|
||||
Reactions: reactions,
|
||||
})
|
||||
}
|
||||
@@ -641,8 +641,8 @@ func (g *GithubDownloaderV3) GetAllComments(page, perPage int) ([]*base.Comment,
|
||||
PosterName: comment.GetUser().GetLogin(),
|
||||
PosterEmail: comment.GetUser().GetEmail(),
|
||||
Content: comment.GetBody(),
|
||||
Created: comment.GetCreatedAt(),
|
||||
Updated: comment.GetUpdatedAt(),
|
||||
Created: comment.GetCreatedAt().Time,
|
||||
Updated: comment.GetUpdatedAt().Time,
|
||||
Reactions: reactions,
|
||||
})
|
||||
}
|
||||
@@ -716,13 +716,13 @@ func (g *GithubDownloaderV3) GetPullRequests(page, perPage int) ([]*base.PullReq
|
||||
Content: pr.GetBody(),
|
||||
Milestone: pr.GetMilestone().GetTitle(),
|
||||
State: pr.GetState(),
|
||||
Created: pr.GetCreatedAt(),
|
||||
Updated: pr.GetUpdatedAt(),
|
||||
Closed: pr.ClosedAt,
|
||||
Created: pr.GetCreatedAt().Time,
|
||||
Updated: pr.GetUpdatedAt().Time,
|
||||
Closed: convertGithubTimestampToTime(pr.ClosedAt),
|
||||
Labels: labels,
|
||||
Merged: pr.MergedAt != nil,
|
||||
MergeCommitSHA: pr.GetMergeCommitSHA(),
|
||||
MergedTime: pr.MergedAt,
|
||||
MergedTime: convertGithubTimestampToTime(pr.MergedAt),
|
||||
IsLocked: pr.ActiveLockReason != nil,
|
||||
Head: base.PullRequestBranch{
|
||||
Ref: pr.GetHead().GetRef(),
|
||||
@@ -756,7 +756,7 @@ func convertGithubReview(r *github.PullRequestReview) *base.Review {
|
||||
ReviewerName: r.GetUser().GetLogin(),
|
||||
CommitID: r.GetCommitID(),
|
||||
Content: r.GetBody(),
|
||||
CreatedAt: r.GetSubmittedAt(),
|
||||
CreatedAt: r.GetSubmittedAt().Time,
|
||||
State: r.GetState(),
|
||||
}
|
||||
}
|
||||
@@ -800,8 +800,8 @@ func (g *GithubDownloaderV3) convertGithubReviewComments(cs []*github.PullReques
|
||||
CommitID: c.GetCommitID(),
|
||||
PosterID: c.GetUser().GetID(),
|
||||
Reactions: reactions,
|
||||
CreatedAt: c.GetCreatedAt(),
|
||||
UpdatedAt: c.GetUpdatedAt(),
|
||||
CreatedAt: c.GetCreatedAt().Time,
|
||||
UpdatedAt: c.GetUpdatedAt().Time,
|
||||
})
|
||||
}
|
||||
return rcs, nil
|
||||
@@ -881,3 +881,10 @@ func (g *GithubDownloaderV3) GetReviews(reviewable base.Reviewable) ([]*base.Rev
|
||||
}
|
||||
return allReviews, nil
|
||||
}
|
||||
|
||||
func convertGithubTimestampToTime(t *github.Timestamp) *time.Time {
|
||||
if t == nil {
|
||||
return nil
|
||||
}
|
||||
return &t.Time
|
||||
}
|
||||
|
||||
@@ -294,6 +294,10 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string,
|
||||
}
|
||||
if err == nil {
|
||||
for _, pr := range prs {
|
||||
if pr.Issue.IsClosed {
|
||||
// The closed PR never trigger action or webhook
|
||||
continue
|
||||
}
|
||||
if newCommitID != "" && newCommitID != git.EmptySHA {
|
||||
changed, err := checkIfPRContentChanged(ctx, pr, oldCommitID, newCommitID)
|
||||
if err != nil {
|
||||
|
||||
@@ -227,7 +227,7 @@ func UpdateRelease(doer *user_model.User, gitRepo *git.Repository, rel *repo_mod
|
||||
deletedUUIDs.Add(attach.UUID)
|
||||
}
|
||||
|
||||
if _, err := repo_model.DeleteAttachments(ctx, attachments, false); err != nil {
|
||||
if _, err := repo_model.DeleteAttachments(ctx, attachments, true); err != nil {
|
||||
return fmt.Errorf("DeleteAttachments [uuids: %v]: %w", delAttachmentUUIDs, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,15 +374,20 @@ func pushUpdateAddTags(ctx context.Context, repo *repo_model.Repository, gitRepo
|
||||
rel, has := relMap[lowerTag]
|
||||
|
||||
if !has {
|
||||
parts := strings.SplitN(tag.Message, "\n", 2)
|
||||
note := ""
|
||||
if len(parts) > 1 {
|
||||
note = parts[1]
|
||||
}
|
||||
rel = &repo_model.Release{
|
||||
RepoID: repo.ID,
|
||||
Title: "",
|
||||
Title: parts[0],
|
||||
TagName: tags[i],
|
||||
LowerTagName: lowerTag,
|
||||
Target: "",
|
||||
Sha1: commit.ID.String(),
|
||||
NumCommits: commitsCount,
|
||||
Note: "",
|
||||
Note: note,
|
||||
IsDraft: false,
|
||||
IsPrerelease: false,
|
||||
IsTag: true,
|
||||
|
||||
@@ -81,7 +81,9 @@ func PushCreateRepo(ctx context.Context, authUser, owner *user_model.User, repoN
|
||||
|
||||
// Init start repository service
|
||||
func Init() error {
|
||||
repo_module.LoadRepoConfig()
|
||||
if err := repo_module.LoadRepoConfig(); err != nil {
|
||||
return err
|
||||
}
|
||||
system_model.RemoveAllWithNotice(db.DefaultContext, "Clean up temporary repository uploads", setting.Repository.Upload.TempPath)
|
||||
system_model.RemoveAllWithNotice(db.DefaultContext, "Clean up temporary repositories", repo_module.LocalCopyPath())
|
||||
return initPushQueue()
|
||||
|
||||
Reference in New Issue
Block a user