Skip to content

Drop db operations from hook commands #1514

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 21 additions & 39 deletions cmd/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,18 @@ package cmd
import (
"bufio"
"bytes"
"crypto/tls"
"fmt"
"os"
"path/filepath"
"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/private"
"code.gitea.io/gitea/modules/setting"

"github.com/Unknwon/com"
"github.com/urfave/cli"
)

Expand Down Expand Up @@ -64,6 +62,12 @@ var (
}
)

func hookSetup(logPath string) {
setting.NewContext()
log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath))
models.LoadConfigs()
}

func runHookPreReceive(c *cli.Context) error {
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
return nil
Expand All @@ -75,9 +79,7 @@ func runHookPreReceive(c *cli.Context) error {
setting.CustomConf = c.GlobalString("config")
}

if err := setup("hooks/pre-receive.log"); err != nil {
fail("Hook pre-receive init failed", fmt.Sprintf("setup: %v", err))
}
hookSetup("hooks/pre-receive.log")

// the environment setted on serv command
repoID, _ := strconv.ParseInt(os.Getenv(models.ProtectedBranchRepoID), 10, 64)
Expand Down Expand Up @@ -119,18 +121,20 @@ func runHookPreReceive(c *cli.Context) error {
}*/

branchName := strings.TrimPrefix(refFullName, git.BranchPrefix)
protectBranch, err := models.GetProtectedBranchBy(repoID, branchName)
protectBranch, err := private.GetProtectedBranchBy(repoID, branchName)
if err != nil {
log.GitLogger.Fatal(2, "retrieve protected branches information failed")
}

if protectBranch != nil {
// check and deletion
if newCommitID == git.EmptySHA {
fail(fmt.Sprintf("branch %s is protected from deletion", branchName), "")
} else {
fail(fmt.Sprintf("protected branch %s can not be pushed to", branchName), "")
//fail(fmt.Sprintf("branch %s is protected from force push", branchName), "")
if !protectBranch.CanPush {
// check and deletion
if newCommitID == git.EmptySHA {
fail(fmt.Sprintf("branch %s is protected from deletion", branchName), "")
} else {
fail(fmt.Sprintf("protected branch %s can not be pushed to", branchName), "")
//fail(fmt.Sprintf("branch %s is protected from force push", branchName), "")
}
}
}
}
Expand All @@ -149,9 +153,7 @@ func runHookUpdate(c *cli.Context) error {
setting.CustomConf = c.GlobalString("config")
}

if err := setup("hooks/update.log"); err != nil {
fail("Hook update init failed", fmt.Sprintf("setup: %v", err))
}
hookSetup("hooks/update.log")

return nil
}
Expand All @@ -167,13 +169,10 @@ func runHookPostReceive(c *cli.Context) error {
setting.CustomConf = c.GlobalString("config")
}

if err := setup("hooks/post-receive.log"); err != nil {
fail("Hook post-receive init failed", fmt.Sprintf("setup: %v", err))
}
hookSetup("hooks/post-receive.log")

// 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)
Expand All @@ -199,7 +198,7 @@ func runHookPostReceive(c *cli.Context) error {
newCommitID := string(fields[1])
refFullName := string(fields[2])

if err := models.PushUpdate(models.PushUpdateOptions{
if err := private.PushUpdate(models.PushUpdateOptions{
RefFullName: refFullName,
OldCommitID: oldCommitID,
NewCommitID: newCommitID,
Expand All @@ -210,23 +209,6 @@ func runHookPostReceive(c *cli.Context) error {
}); 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
Expand Down
42 changes: 21 additions & 21 deletions models/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,40 +65,40 @@ type PushUpdateOptions struct {

// PushUpdate must be called for any push actions in order to
// generates necessary push action history feeds.
func PushUpdate(opts PushUpdateOptions) (err error) {
func PushUpdate(opts PushUpdateOptions) (repo *Repository, err error) {
isNewRef := opts.OldCommitID == git.EmptySHA
isDelRef := opts.NewCommitID == git.EmptySHA
if isNewRef && isDelRef {
return fmt.Errorf("Old and new revisions are both %s", git.EmptySHA)
return nil, fmt.Errorf("Old and new revisions are both %s", git.EmptySHA)
}

repoPath := RepoPath(opts.RepoUserName, opts.RepoName)

gitUpdate := exec.Command("git", "update-server-info")
gitUpdate.Dir = repoPath
if err = gitUpdate.Run(); err != nil {
return fmt.Errorf("Failed to call 'git update-server-info': %v", err)
return nil, fmt.Errorf("Failed to call 'git update-server-info': %v", err)
}

if isDelRef {
log.GitLogger.Info("Reference '%s' has been deleted from '%s/%s' by %s",
opts.RefFullName, opts.RepoUserName, opts.RepoName, opts.PusherName)
return nil
owner, err := GetUserByName(opts.RepoUserName)
if err != nil {
return nil, fmt.Errorf("GetUserByName: %v", err)
}

gitRepo, err := git.OpenRepository(repoPath)
repo, err = GetRepositoryByName(owner.ID, opts.RepoName)
if err != nil {
return fmt.Errorf("OpenRepository: %v", err)
return nil, fmt.Errorf("GetRepositoryByName: %v", err)
}

owner, err := GetUserByName(opts.RepoUserName)
if err != nil {
return fmt.Errorf("GetUserByName: %v", err)
if isDelRef {
log.GitLogger.Info("Reference '%s' has been deleted from '%s/%s' by %s",
opts.RefFullName, opts.RepoUserName, opts.RepoName, opts.PusherName)
return repo, nil
}

repo, err := GetRepositoryByName(owner.ID, opts.RepoName)
gitRepo, err := git.OpenRepository(repoPath)
if err != nil {
return fmt.Errorf("GetRepositoryByName: %v", err)
return nil, fmt.Errorf("OpenRepository: %v", err)
}

if err = repo.UpdateSize(); err != nil {
Expand All @@ -116,27 +116,27 @@ func PushUpdate(opts PushUpdateOptions) (err error) {
NewCommitID: opts.NewCommitID,
Commits: &PushCommits{},
}); err != nil {
return fmt.Errorf("CommitRepoAction (tag): %v", err)
return nil, fmt.Errorf("CommitRepoAction (tag): %v", err)
}
return nil
return repo, nil
}

newCommit, err := gitRepo.GetCommit(opts.NewCommitID)
if err != nil {
return fmt.Errorf("gitRepo.GetCommit: %v", err)
return nil, fmt.Errorf("gitRepo.GetCommit: %v", err)
}

// Push new branch.
var l *list.List
if isNewRef {
l, err = newCommit.CommitsBeforeLimit(10)
if err != nil {
return fmt.Errorf("newCommit.CommitsBeforeLimit: %v", err)
return nil, fmt.Errorf("newCommit.CommitsBeforeLimit: %v", err)
}
} else {
l, err = newCommit.CommitsBeforeUntil(opts.OldCommitID)
if err != nil {
return fmt.Errorf("newCommit.CommitsBeforeUntil: %v", err)
return nil, fmt.Errorf("newCommit.CommitsBeforeUntil: %v", err)
}
}

Expand All @@ -149,7 +149,7 @@ func PushUpdate(opts PushUpdateOptions) (err error) {
NewCommitID: opts.NewCommitID,
Commits: ListToPushCommits(l),
}); err != nil {
return fmt.Errorf("CommitRepoAction (branch): %v", err)
return nil, fmt.Errorf("CommitRepoAction (branch): %v", err)
}
return nil
return repo, nil
}
43 changes: 43 additions & 0 deletions modules/private/branch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package private

import (
"crypto/tls"
"encoding/json"
"fmt"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
)

// GetProtectedBranchBy get protected branch information
func GetProtectedBranchBy(repoID int64, branchName string) (*models.ProtectedBranch, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be moved to go-gitea/sdk later on... I'm not gonna ask you to do it now , but we're gonna have to move it at some point.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why should we move it to go-gitea/sdk later? It is an internal SDK.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should still be in the SDK. That way other implementations of gitea serv could re-use this :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that the sdk contain any internal route but we could maybe add it in an other time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact it add /api/v1 to url request (https://github.com/go-gitea/go-sdk/blob/master/gitea/gitea.go#L42) so no internal route.

// Ask for running deliver hook and test pull request tasks.
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/branch/%d/%s", repoID, branchName)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andreynering As you can see here it uses LocalURL which is fine 🙂

log.GitLogger.Trace("GetProtectedBranchBy: %s", reqURL)

resp, err := newRequest(reqURL, "GET").SetTLSClientConfig(&tls.Config{
InsecureSkipVerify: true,
}).Response()
if err != nil {
return nil, err
}

var branch models.ProtectedBranch
if err := json.NewDecoder(resp.Body).Decode(&branch); err != nil {
return nil, err
}

defer resp.Body.Close()

// All 2XX status codes are accepted and others will return an error
if resp.StatusCode/100 != 2 {
return nil, fmt.Errorf("Failed to update public key: %s", decodeJSONError(resp).Err)
}

return &branch, nil
}
4 changes: 4 additions & 0 deletions modules/private/internal.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package private

import (
Expand Down
43 changes: 43 additions & 0 deletions modules/private/push_update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package private

import (
"crypto/tls"
"encoding/json"
"fmt"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
)

// PushUpdate update publick key updates
func PushUpdate(opt models.PushUpdateOptions) error {
// Ask for running deliver hook and test pull request tasks.
reqURL := setting.LocalURL + "api/internal/push/update"
log.GitLogger.Trace("PushUpdate: %s", reqURL)

body, err := json.Marshal(&opt)
if err != nil {
return err
}

resp, err := newRequest(reqURL, "POST").Body(body).SetTLSClientConfig(&tls.Config{
InsecureSkipVerify: true,
}).Response()
if err != nil {
return err
}

defer resp.Body.Close()

// All 2XX status codes are accepted and others will return an error
if resp.StatusCode/100 != 2 {
return fmt.Errorf("Failed to update public key: %s", decodeJSONError(resp).Err)
}

return nil
}
30 changes: 30 additions & 0 deletions routers/private/branch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package private

import (
"code.gitea.io/gitea/models"

macaron "gopkg.in/macaron.v1"
)

// GetProtectedBranchBy get protected branch information
func GetProtectedBranchBy(ctx *macaron.Context) {
repoID := ctx.ParamsInt64(":id")
branchName := ctx.Params(":branch")
protectBranch, err := models.GetProtectedBranchBy(repoID, branchName)
if err != nil {
ctx.JSON(500, map[string]interface{}{
"err": err.Error(),
})
return
} else if protectBranch != nil {
ctx.JSON(200, protectBranch)
} else {
ctx.JSON(200, &models.ProtectedBranch{
CanPush: true,
})
}
}
3 changes: 3 additions & 0 deletions routers/private/internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/setting"

macaron "gopkg.in/macaron.v1"
)

Expand Down Expand Up @@ -40,5 +41,7 @@ func UpdatePublicKey(ctx *macaron.Context) {
func RegisterRoutes(m *macaron.Macaron) {
m.Group("/", func() {
m.Post("/ssh/:id/update", UpdatePublicKey)
m.Post("/push/update", PushUpdate)
m.Get("/branch/:id/:branch", GetProtectedBranchBy)
}, CheckInternalToken)
}
Loading