mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Move push update to post-receive and protected branch check to pre-receive (#1030)
* move all push update to git hook post-receive and protected branch check to git hook pre-receive * add SSH_ORIGINAL_COMMAND check back * remove all unused codes * fix the import
This commit is contained in:
		
							
								
								
									
										135
									
								
								cmd/hook.go
									
									
									
									
									
								
							
							
						
						
									
										135
									
								
								cmd/hook.go
									
									
									
									
									
								
							| @@ -5,11 +5,22 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"bytes" | ||||
| 	"crypto/tls" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
|  | ||||
| 	"code.gitea.io/git" | ||||
| 	"code.gitea.io/gitea/models" | ||||
| 	"code.gitea.io/gitea/modules/base" | ||||
| 	"code.gitea.io/gitea/modules/httplib" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
|  | ||||
| 	"github.com/Unknwon/com" | ||||
| 	"github.com/urfave/cli" | ||||
| ) | ||||
|  | ||||
| @@ -57,10 +68,59 @@ func runHookPreReceive(c *cli.Context) error { | ||||
| 	if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	if err := setup("hooks/pre-receive.log"); err != nil { | ||||
| 		fail("Hook pre-receive init failed", fmt.Sprintf("setup: %v", err)) | ||||
| 	} | ||||
|  | ||||
| 	// the environment setted on serv command | ||||
| 	repoID, _ := strconv.ParseInt(os.Getenv(models.ProtectedBranchRepoID), 10, 64) | ||||
| 	isWiki := (os.Getenv(models.EnvRepoIsWiki) == "true") | ||||
|  | ||||
| 	buf := bytes.NewBuffer(nil) | ||||
| 	scanner := bufio.NewScanner(os.Stdin) | ||||
| 	for scanner.Scan() { | ||||
| 		buf.Write(scanner.Bytes()) | ||||
| 		buf.WriteByte('\n') | ||||
|  | ||||
| 		// TODO: support news feeds for wiki | ||||
| 		if isWiki { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		fields := bytes.Fields(scanner.Bytes()) | ||||
| 		if len(fields) != 3 { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		oldCommitID := string(fields[0]) | ||||
| 		newCommitID := string(fields[1]) | ||||
| 		refFullName := string(fields[2]) | ||||
|  | ||||
| 		branchName := strings.TrimPrefix(refFullName, git.BranchPrefix) | ||||
| 		protectBranch, err := models.GetProtectedBranchBy(repoID, branchName) | ||||
| 		if err != nil { | ||||
| 			log.GitLogger.Fatal(2, "retrieve protected branches information failed") | ||||
| 		} | ||||
|  | ||||
| 		if protectBranch != nil { | ||||
| 			fail(fmt.Sprintf("protected branch %s can not be pushed to", branchName), "") | ||||
| 		} | ||||
|  | ||||
| 		// check and deletion | ||||
| 		if newCommitID == git.EmptySHA { | ||||
| 			fail(fmt.Sprintf("Branch '%s' is protected from deletion", branchName), "") | ||||
| 		} | ||||
|  | ||||
| 		// Check force push | ||||
| 		output, err := git.NewCommand("rev-list", oldCommitID, "^"+newCommitID).Run() | ||||
| 		if err != nil { | ||||
| 			fail("Internal error", "Fail to detect force push: %v", err) | ||||
| 		} else if len(output) > 0 { | ||||
| 			fail(fmt.Sprintf("Branch '%s' is protected from force push", branchName), "") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @@ -73,23 +133,6 @@ func runHookUpdate(c *cli.Context) error { | ||||
| 		fail("Hook update init failed", fmt.Sprintf("setup: %v", err)) | ||||
| 	} | ||||
|  | ||||
| 	args := c.Args() | ||||
| 	if len(args) != 3 { | ||||
| 		fail("Arguments received are not equal to three", "Arguments received are not equal to three") | ||||
| 	} else if len(args[0]) == 0 { | ||||
| 		fail("First argument 'refName' is empty", "First argument 'refName' is empty") | ||||
| 	} | ||||
|  | ||||
| 	uuid := os.Getenv(envUpdateTaskUUID) | ||||
| 	if err := models.AddUpdateTask(&models.UpdateTask{ | ||||
| 		UUID:        uuid, | ||||
| 		RefName:     args[0], | ||||
| 		OldCommitID: args[1], | ||||
| 		NewCommitID: args[2], | ||||
| 	}); err != nil { | ||||
| 		fail("Internal error", "Fail to add update task '%s': %v", uuid, err) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @@ -102,5 +145,63 @@ func runHookPostReceive(c *cli.Context) error { | ||||
| 		fail("Hook post-receive init failed", fmt.Sprintf("setup: %v", err)) | ||||
| 	} | ||||
|  | ||||
| 	// the environment setted on serv command | ||||
| 	repoUser := os.Getenv(models.EnvRepoUsername) | ||||
| 	repoUserSalt := os.Getenv(models.EnvRepoUserSalt) | ||||
| 	isWiki := (os.Getenv(models.EnvRepoIsWiki) == "true") | ||||
| 	repoName := os.Getenv(models.EnvRepoName) | ||||
| 	pusherID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64) | ||||
| 	pusherName := os.Getenv(models.EnvPusherName) | ||||
|  | ||||
| 	buf := bytes.NewBuffer(nil) | ||||
| 	scanner := bufio.NewScanner(os.Stdin) | ||||
| 	for scanner.Scan() { | ||||
| 		buf.Write(scanner.Bytes()) | ||||
| 		buf.WriteByte('\n') | ||||
|  | ||||
| 		// TODO: support news feeds for wiki | ||||
| 		if isWiki { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		fields := bytes.Fields(scanner.Bytes()) | ||||
| 		if len(fields) != 3 { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		oldCommitID := string(fields[0]) | ||||
| 		newCommitID := string(fields[1]) | ||||
| 		refFullName := string(fields[2]) | ||||
|  | ||||
| 		if err := models.PushUpdate(models.PushUpdateOptions{ | ||||
| 			RefFullName:  refFullName, | ||||
| 			OldCommitID:  oldCommitID, | ||||
| 			NewCommitID:  newCommitID, | ||||
| 			PusherID:     pusherID, | ||||
| 			PusherName:   pusherName, | ||||
| 			RepoUserName: repoUser, | ||||
| 			RepoName:     repoName, | ||||
| 		}); err != nil { | ||||
| 			log.GitLogger.Error(2, "Update: %v", err) | ||||
| 		} | ||||
|  | ||||
| 		// Ask for running deliver hook and test pull request tasks. | ||||
| 		reqURL := setting.LocalURL + repoUser + "/" + repoName + "/tasks/trigger?branch=" + | ||||
| 			strings.TrimPrefix(refFullName, git.BranchPrefix) + "&secret=" + base.EncodeMD5(repoUserSalt) + "&pusher=" + com.ToStr(pusherID) | ||||
| 		log.GitLogger.Trace("Trigger task: %s", reqURL) | ||||
|  | ||||
| 		resp, err := httplib.Head(reqURL).SetTLSClientConfig(&tls.Config{ | ||||
| 			InsecureSkipVerify: true, | ||||
| 		}).Response() | ||||
| 		if err == nil { | ||||
| 			resp.Body.Close() | ||||
| 			if resp.StatusCode/100 != 2 { | ||||
| 				log.GitLogger.Error(2, "Failed to trigger task: not 2xx response code") | ||||
| 			} | ||||
| 		} else { | ||||
| 			log.GitLogger.Error(2, "Failed to trigger task: %v", err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user