mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-10 11:25:56 -05:00
a53194f4b1
files_service.CreateCommitStatus must not explicitly call gitRepo.Close(), it will be called by the closer function. Calling it explicitly will cause the repository to be closed prematurely when obtained from the context, making it unusuable by the caller later on. For instance, as CreateCommitStatus is called indirectly when a workflow exists for the tag to be created, it will make the repositoryn in the context unusable for the tag creation API.
86 lines
3 KiB
Go
86 lines
3 KiB
Go
// Copyright 2019 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package files
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
|
git_model "code.gitea.io/gitea/models/git"
|
|
repo_model "code.gitea.io/gitea/models/repo"
|
|
user_model "code.gitea.io/gitea/models/user"
|
|
"code.gitea.io/gitea/modules/git"
|
|
"code.gitea.io/gitea/modules/structs"
|
|
"code.gitea.io/gitea/services/automerge"
|
|
)
|
|
|
|
// CreateCommitStatus creates a new CommitStatus given a bunch of parameters
|
|
// NOTE: All text-values will be trimmed from whitespaces.
|
|
// Requires: Repo, Creator, SHA
|
|
func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, creator *user_model.User, sha string, status *git_model.CommitStatus) error {
|
|
repoPath := repo.RepoPath()
|
|
|
|
// confirm that commit is exist
|
|
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
|
|
if err != nil {
|
|
return fmt.Errorf("OpenRepository[%s]: %w", repoPath, err)
|
|
}
|
|
defer closer.Close()
|
|
|
|
if commit, err := gitRepo.GetCommit(sha); err != nil {
|
|
return fmt.Errorf("GetCommit[%s]: %w", sha, err)
|
|
} else if len(sha) != git.SHAFullLength {
|
|
// use complete commit sha
|
|
sha = commit.ID.String()
|
|
}
|
|
|
|
if err := git_model.NewCommitStatus(ctx, git_model.NewCommitStatusOptions{
|
|
Repo: repo,
|
|
Creator: creator,
|
|
SHA: sha,
|
|
CommitStatus: status,
|
|
}); err != nil {
|
|
return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %w", repo.ID, creator.ID, sha, err)
|
|
}
|
|
|
|
if status.State.IsSuccess() {
|
|
if err := automerge.MergeScheduledPullRequest(ctx, sha, repo); err != nil {
|
|
return fmt.Errorf("MergeScheduledPullRequest[repo_id: %d, user_id: %d, sha: %s]: %w", repo.ID, creator.ID, sha, err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// CountDivergingCommits determines how many commits a branch is ahead or behind the repository's base branch
|
|
func CountDivergingCommits(ctx context.Context, repo *repo_model.Repository, branch string) (*git.DivergeObject, error) {
|
|
divergence, err := git.GetDivergingCommits(ctx, repo.RepoPath(), repo.DefaultBranch, branch)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &divergence, nil
|
|
}
|
|
|
|
// GetPayloadCommitVerification returns the verification information of a commit
|
|
func GetPayloadCommitVerification(ctx context.Context, commit *git.Commit) *structs.PayloadCommitVerification {
|
|
verification := &structs.PayloadCommitVerification{}
|
|
commitVerification := asymkey_model.ParseCommitWithSignature(ctx, commit)
|
|
if commit.Signature != nil {
|
|
verification.Signature = commit.Signature.Signature
|
|
verification.Payload = commit.Signature.Payload
|
|
}
|
|
if commitVerification.SigningUser != nil {
|
|
verification.Signer = &structs.PayloadUser{
|
|
Name: commitVerification.SigningUser.Name,
|
|
Email: commitVerification.SigningUser.Email,
|
|
}
|
|
}
|
|
verification.Verified = commitVerification.Verified
|
|
verification.Reason = commitVerification.Reason
|
|
if verification.Reason == "" && !verification.Verified {
|
|
verification.Reason = "gpg.error.not_signed_commit"
|
|
}
|
|
return verification
|
|
}
|