code.gitea.io/gitea@v1.21.7/services/repository/files/commit.go (about)

     1  // Copyright 2019 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package files
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  
    10  	asymkey_model "code.gitea.io/gitea/models/asymkey"
    11  	git_model "code.gitea.io/gitea/models/git"
    12  	repo_model "code.gitea.io/gitea/models/repo"
    13  	user_model "code.gitea.io/gitea/models/user"
    14  	"code.gitea.io/gitea/modules/git"
    15  	"code.gitea.io/gitea/modules/structs"
    16  	"code.gitea.io/gitea/services/automerge"
    17  )
    18  
    19  // CreateCommitStatus creates a new CommitStatus given a bunch of parameters
    20  // NOTE: All text-values will be trimmed from whitespaces.
    21  // Requires: Repo, Creator, SHA
    22  func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, creator *user_model.User, sha string, status *git_model.CommitStatus) error {
    23  	repoPath := repo.RepoPath()
    24  
    25  	// confirm that commit is exist
    26  	gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
    27  	if err != nil {
    28  		return fmt.Errorf("OpenRepository[%s]: %w", repoPath, err)
    29  	}
    30  	defer closer.Close()
    31  
    32  	if commit, err := gitRepo.GetCommit(sha); err != nil {
    33  		gitRepo.Close()
    34  		return fmt.Errorf("GetCommit[%s]: %w", sha, err)
    35  	} else if len(sha) != git.SHAFullLength {
    36  		// use complete commit sha
    37  		sha = commit.ID.String()
    38  	}
    39  	gitRepo.Close()
    40  
    41  	if err := git_model.NewCommitStatus(ctx, git_model.NewCommitStatusOptions{
    42  		Repo:         repo,
    43  		Creator:      creator,
    44  		SHA:          sha,
    45  		CommitStatus: status,
    46  	}); err != nil {
    47  		return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %w", repo.ID, creator.ID, sha, err)
    48  	}
    49  
    50  	if status.State.IsSuccess() {
    51  		if err := automerge.MergeScheduledPullRequest(ctx, sha, repo); err != nil {
    52  			return fmt.Errorf("MergeScheduledPullRequest[repo_id: %d, user_id: %d, sha: %s]: %w", repo.ID, creator.ID, sha, err)
    53  		}
    54  	}
    55  
    56  	return nil
    57  }
    58  
    59  // CountDivergingCommits determines how many commits a branch is ahead or behind the repository's base branch
    60  func CountDivergingCommits(ctx context.Context, repo *repo_model.Repository, branch string) (*git.DivergeObject, error) {
    61  	divergence, err := git.GetDivergingCommits(ctx, repo.RepoPath(), repo.DefaultBranch, branch)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  	return &divergence, nil
    66  }
    67  
    68  // GetPayloadCommitVerification returns the verification information of a commit
    69  func GetPayloadCommitVerification(ctx context.Context, commit *git.Commit) *structs.PayloadCommitVerification {
    70  	verification := &structs.PayloadCommitVerification{}
    71  	commitVerification := asymkey_model.ParseCommitWithSignature(ctx, commit)
    72  	if commit.Signature != nil {
    73  		verification.Signature = commit.Signature.Signature
    74  		verification.Payload = commit.Signature.Payload
    75  	}
    76  	if commitVerification.SigningUser != nil {
    77  		verification.Signer = &structs.PayloadUser{
    78  			Name:  commitVerification.SigningUser.Name,
    79  			Email: commitVerification.SigningUser.Email,
    80  		}
    81  	}
    82  	verification.Verified = commitVerification.Verified
    83  	verification.Reason = commitVerification.Reason
    84  	if verification.Reason == "" && !verification.Verified {
    85  		verification.Reason = "gpg.error.not_signed_commit"
    86  	}
    87  	return verification
    88  }