Skip to content
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

feat(api): add git.tag support #3200

Merged
merged 11 commits into from Aug 17, 2018
11 changes: 11 additions & 0 deletions engine/api/repositoriesmanager/repositories_manager.go
Expand Up @@ -297,6 +297,17 @@ func (c *vcsClient) Commits(ctx context.Context, fullname, branch, since, until
return commits, nil
}

func (c *vcsClient) CommitsBetweenRefs(ctx context.Context, fullname, base, head string) ([]sdk.VCSCommit, error) {
var commits []sdk.VCSCommit
path := fmt.Sprintf("/vcs/%s/repos/%s/commits?base=%s&head=%s", c.name, fullname, url.QueryEscape(base), url.QueryEscape(head))
if code, err := c.doJSONRequest(context.Background(), "GET", path, nil, &commits); err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

context.Background => ctx

if code != http.StatusNotFound {
return nil, err
}
}
return commits, nil
}

func (c *vcsClient) Commit(ctx context.Context, fullname, hash string) (sdk.VCSCommit, error) {
commit := sdk.VCSCommit{}
path := fmt.Sprintf("/vcs/%s/repos/%s/commits/%s", c.name, fullname, hash)
Expand Down
63 changes: 47 additions & 16 deletions engine/api/workflow/dao_node_run.go
Expand Up @@ -42,6 +42,7 @@ workflow_node_run.triggers_run,
workflow_node_run.vcs_repository,
workflow_node_run.vcs_hash,
workflow_node_run.vcs_branch,
workflow_node_run.vcs_tag,
workflow_node_run.vcs_server,
workflow_node_run.workflow_node_name,
workflow_node_run.header
Expand Down Expand Up @@ -247,6 +248,9 @@ func fromDBNodeRun(rr NodeRun, opts LoadRunOptions) (*sdk.WorkflowNodeRun, error
if rr.VCSBranch.Valid {
r.VCSBranch = rr.VCSBranch.String
}
if rr.VCSTag.Valid {
r.VCSTag = rr.VCSTag.String
}
if rr.VCSServer.Valid {
r.VCSServer = rr.VCSServer.String
}
Expand Down Expand Up @@ -339,6 +343,8 @@ func makeDBNodeRun(n sdk.WorkflowNodeRun) (*NodeRun, error) {
nodeRunDB.VCSHash.String = n.VCSHash
nodeRunDB.VCSBranch.Valid = true
nodeRunDB.VCSBranch.String = n.VCSBranch
nodeRunDB.VCSTag.Valid = true
nodeRunDB.VCSTag.String = n.VCSTag
nodeRunDB.VCSRepository.Valid = true
nodeRunDB.VCSRepository.String = n.VCSRepository

Expand Down Expand Up @@ -476,16 +482,16 @@ func GetNodeRunBuildCommits(ctx context.Context, db gorp.SqlExecutor, store cach
if errclient != nil {
return nil, cur, sdk.WrapError(errclient, "GetNodeRunBuildCommits> Cannot get client")
}

cur.Remote = nodeRun.VCSRepository
cur.Branch = nodeRun.VCSBranch
cur.Hash = nodeRun.VCSHash
cur.Tag = nodeRun.VCSTag

if cur.Remote == "" {
cur.Remote = app.RepositoryFullname
}

if cur.Branch == "" {
if cur.Branch == "" && cur.Tag == "" {
branches, errBr := client.Branches(ctx, cur.Remote)
if errBr != nil {
return nil, cur, sdk.WrapError(errBr, "GetNodeRunBuildCommits> Cannot load branches from vcs api remote %s", cur.Remote)
Expand Down Expand Up @@ -514,7 +520,7 @@ func GetNodeRunBuildCommits(ctx context.Context, db gorp.SqlExecutor, store cach
}

var lastCommit sdk.VCSCommit
if cur.Hash == "" {
if cur.Hash == "" && cur.Tag == "" && cur.Branch != "" {
//If we only have the current branch, search for the branch
br, err := client.Branch(ctx, repo, cur.Branch)
if err != nil {
Expand Down Expand Up @@ -548,24 +554,46 @@ func GetNodeRunBuildCommits(ctx context.Context, db gorp.SqlExecutor, store cach
if prev.Hash != "" && cur.Hash == prev.Hash {
log.Debug("GetNodeRunBuildCommits> there is not difference between the previous build and the current build for node %s", nodeRun.WorkflowNodeName)
} else if prev.Hash != "" {
if cur.Hash == "" {
switch {
case cur.Hash == "" && cur.Tag == "":
br, err := client.Branch(ctx, repo, cur.Branch)
if err != nil {
return nil, cur, sdk.WrapError(err, "GetNodeRunBuildCommits> Cannot get branch %s", cur.Branch)
}
cur.Hash = br.LatestCommit
}
//If we are lucky, return a true diff
commits, err := client.Commits(ctx, repo, cur.Branch, prev.Hash, cur.Hash)
if err != nil {
return nil, cur, sdk.WrapError(err, "GetNodeRunBuildCommits> Cannot get commits")
}
if commits != nil {
res = commits
//If we are lucky, return a true diff
commits, err := client.Commits(ctx, repo, cur.Branch, prev.Hash, cur.Hash)
if err != nil {
return nil, cur, sdk.WrapError(err, "GetNodeRunBuildCommits> Cannot get commits")
}
if commits != nil {
res = commits
}

case cur.Hash == "" && cur.Tag != "":
c, err := client.CommitsBetweenRefs(ctx, repo, prev.Hash, cur.Tag)
if err != nil {
return nil, cur, sdk.WrapError(err, "GetNodeRunBuildCommits> Cannot get commits")
}
if c != nil {
res = c
}
}
} else if prev.Hash == "" {
if lastCommit.Hash != "" {
res = []sdk.VCSCommit{lastCommit}
} else if cur.Tag != "" {
base := prev.Tag
if base == "" {
base = prev.Hash
}
c, err := client.CommitsBetweenRefs(ctx, repo, base, cur.Tag)
if err != nil {
return nil, cur, sdk.WrapError(err, "GetNodeRunBuildCommits> Cannot get commits")
}
if c != nil {
res = c
}
}
} else {
//If we only get current node run hash
Expand Down Expand Up @@ -593,7 +621,7 @@ func PreviousNodeRun(db gorp.SqlExecutor, nr sdk.WorkflowNodeRun, n sdk.Workflow
`, nodeRunFields)
var nodeRun sdk.WorkflowNodeRun
var rr = NodeRun{}
if err := db.SelectOne(&rr, query, n.Name, workflowID, nr.VCSBranch, nr.Number, nr.WorkflowNodeID, nr.ID); err != nil {
if err := db.SelectOne(&rr, query, n.Name, workflowID, nr.VCSBranch, nr.VCSTag, nr.Number, nr.WorkflowNodeID, nr.ID); err != nil {
return nodeRun, sdk.WrapError(err, "PreviousNodeRun> Cannot load previous run on workflow %d node %s", workflowID, n.Name)
}
pNodeRun, errF := fromDBNodeRun(rr, LoadRunOptions{})
Expand All @@ -610,11 +638,11 @@ func PreviousNodeRun(db gorp.SqlExecutor, nr sdk.WorkflowNodeRun, n sdk.Workflow
//If you don't have environment linked set envID to 0 or -1
func PreviousNodeRunVCSInfos(db gorp.SqlExecutor, projectKey string, wf *sdk.Workflow, nodeName string, current sdk.BuildNumberAndHash, appID int64, envID int64) (sdk.BuildNumberAndHash, error) {
var previous sdk.BuildNumberAndHash
var prevHash, prevBranch, prevRepository sql.NullString
var prevHash, prevBranch, prevTag, prevRepository sql.NullString
var previousBuildNumber sql.NullInt64

queryPrevious := `
SELECT workflow_node_run.vcs_branch, workflow_node_run.vcs_hash, workflow_node_run.vcs_repository, workflow_node_run.num
SELECT workflow_node_run.vcs_branch, workflow_node_run.vcs_tag, workflow_node_run.vcs_hash, workflow_node_run.vcs_repository, workflow_node_run.num
FROM workflow_node_run
JOIN workflow_node ON workflow_node.name = workflow_node_run.workflow_node_name AND workflow_node.name = $1 AND workflow_node.workflow_id = $2
JOIN workflow_node_context ON workflow_node_context.workflow_node_id = workflow_node.id
Expand All @@ -630,7 +658,7 @@ func PreviousNodeRunVCSInfos(db gorp.SqlExecutor, projectKey string, wf *sdk.Wor
}
queryPrevious += fmt.Sprintf(" ORDER BY workflow_node_run.num DESC LIMIT 1")

errPrev := db.QueryRow(queryPrevious, argPrevious...).Scan(&prevBranch, &prevHash, &prevRepository, &previousBuildNumber)
errPrev := db.QueryRow(queryPrevious, argPrevious...).Scan(&prevBranch, &prevTag, &prevHash, &prevRepository, &previousBuildNumber)
if errPrev == sql.ErrNoRows {
log.Warning("PreviousNodeRunVCSInfos> no result with previous %d %s , arguments %v", current.BuildNumber, nodeName, argPrevious)
return previous, nil
Expand All @@ -642,6 +670,9 @@ func PreviousNodeRunVCSInfos(db gorp.SqlExecutor, projectKey string, wf *sdk.Wor
if prevBranch.Valid {
previous.Branch = prevBranch.String
}
if prevTag.Valid {
previous.Tag = prevTag.String
}
if prevHash.Valid {
previous.Hash = prevHash.String
}
Expand Down
5 changes: 5 additions & 0 deletions engine/api/workflow/execute_node_run.go
Expand Up @@ -766,6 +766,7 @@ func SyncNodeRunRunJob(ctx context.Context, db gorp.SqlExecutor, nodeRun *sdk.Wo

type vcsInfos struct {
Repository string
Tag string
Branch string
Hash string
Author string
Expand All @@ -783,6 +784,7 @@ func getVCSInfos(ctx context.Context, db gorp.SqlExecutor, store cache.Store, vc
var vcsInfos vcsInfos
vcsInfos.Repository = gitValues[tagGitRepository]
vcsInfos.Branch = gitValues[tagGitBranch]
vcsInfos.Tag = gitValues[tagGitTag]
vcsInfos.Hash = gitValues[tagGitHash]
vcsInfos.Author = gitValues[tagGitAuthor]
vcsInfos.Message = gitValues[tagGitMessage]
Expand Down Expand Up @@ -868,6 +870,9 @@ func getVCSInfos(ctx context.Context, db gorp.SqlExecutor, store cache.Store, vc
vcsInfos.HTTPUrl = repo.HTTPCloneURL

if vcsInfos.Branch == "" && !isChildNode {
if vcsInfos.Tag != "" {
return vcsInfos, nil
}
return vcsInfos, sdk.WrapError(sdk.ErrBranchNameNotProvided, "computeVCSInfos> should not have an empty branch")
}

Expand Down
1 change: 1 addition & 0 deletions engine/api/workflow/gorp_model.go
Expand Up @@ -66,6 +66,7 @@ type NodeRun struct {
TriggersRun sql.NullString `db:"triggers_run"`
VCSRepository sql.NullString `db:"vcs_repository"`
VCSBranch sql.NullString `db:"vcs_branch"`
VCSTag sql.NullString `db:"vcs_tag"`
VCSHash sql.NullString `db:"vcs_hash"`
VCSServer sql.NullString `db:"vcs_server"`
Header sql.NullString `db:"header"`
Expand Down
9 changes: 8 additions & 1 deletion engine/api/workflow/process.go
Expand Up @@ -620,7 +620,12 @@ func processWorkflowNodeRun(ctx context.Context, db gorp.SqlExecutor, store cach
// Tag VCS infos : add in tag only if it does not exist
if !w.TagExists(tagGitRepository) {
w.Tag(tagGitRepository, run.VCSRepository)
w.Tag(tagGitBranch, run.VCSBranch)
if run.VCSBranch != "" {
w.Tag(tagGitBranch, run.VCSBranch)
}
if run.VCSTag != "" {
w.Tag(tagGitTag, run.VCSTag)
}
if len(run.VCSHash) >= 7 {
w.Tag(tagGitHash, run.VCSHash[:7])
} else {
Expand Down Expand Up @@ -720,11 +725,13 @@ func processWorkflowNodeRun(ctx context.Context, db gorp.SqlExecutor, store cach
func setValuesGitInBuildParameters(run *sdk.WorkflowNodeRun, vcsInfos vcsInfos) {
run.VCSRepository = vcsInfos.Repository
run.VCSBranch = vcsInfos.Branch
run.VCSTag = vcsInfos.Tag
run.VCSHash = vcsInfos.Hash
run.VCSServer = vcsInfos.Server

sdk.ParameterAddOrSetValue(&run.BuildParameters, tagGitRepository, sdk.StringParameter, run.VCSRepository)
sdk.ParameterAddOrSetValue(&run.BuildParameters, tagGitBranch, sdk.StringParameter, run.VCSBranch)
sdk.ParameterAddOrSetValue(&run.BuildParameters, tagGitTag, sdk.StringParameter, run.VCSTag)
sdk.ParameterAddOrSetValue(&run.BuildParameters, tagGitHash, sdk.StringParameter, run.VCSHash)
sdk.ParameterAddOrSetValue(&run.BuildParameters, tagGitAuthor, sdk.StringParameter, vcsInfos.Author)
sdk.ParameterAddOrSetValue(&run.BuildParameters, tagGitMessage, sdk.StringParameter, vcsInfos.Message)
Expand Down
3 changes: 3 additions & 0 deletions engine/api/workflow/resync_workflow.go
Expand Up @@ -143,6 +143,9 @@ func ResyncNodeRunsWithCommits(ctx context.Context, db gorp.SqlExecutor, store c
if curVCSInfos.Remote != "" {
tagsUpdated = wr.Tag(tagGitRepository, curVCSInfos.Remote)
}
if curVCSInfos.Tag != "" {
tagsUpdated = wr.Tag(tagGitTag, curVCSInfos.Tag)
}

if tagsUpdated {
if err := UpdateWorkflowRunTags(db, wr); err != nil {
Expand Down
7 changes: 6 additions & 1 deletion engine/api/workflow/workflow_run_event.go
Expand Up @@ -91,7 +91,11 @@ func ResyncCommitStatus(ctx context.Context, db gorp.SqlExecutor, store cache.St
return sdk.WrapError(errClient, "resyncCommitStatus> Cannot get client")
}

statuses, errStatuses := client.ListStatuses(ctx, node.Context.Application.RepositoryFullname, nodeRun.VCSHash)
ref := nodeRun.VCSHash
if nodeRun.VCSTag != "" {
ref = nodeRun.VCSTag
}
statuses, errStatuses := client.ListStatuses(ctx, node.Context.Application.RepositoryFullname, ref)
if errStatuses != nil {
return sdk.WrapError(errStatuses, "resyncCommitStatus> Cannot get statuses")
}
Expand Down Expand Up @@ -191,6 +195,7 @@ func sendVCSEventStatus(ctx context.Context, db gorp.SqlExecutor, store cache.St
Payload: nodeRun.Payload,
SourceNodeRuns: nodeRun.SourceNodeRuns,
Hash: nodeRun.VCSHash,
Tag: nodeRun.VCSTag,
BranchName: nodeRun.VCSBranch,
NodeID: nodeRun.WorkflowNodeID,
RunID: nodeRun.WorkflowRunID,
Expand Down
29 changes: 16 additions & 13 deletions engine/hooks/tasks.go
Expand Up @@ -526,17 +526,19 @@ func executeRepositoryWebHook(t *sdk.TaskExecution) (*sdk.WorkflowNodeRunHookEve
}
payload["git.author"] = pushEvent.HeadCommit.Author.Username
payload["git.author.email"] = pushEvent.HeadCommit.Author.Email
payload["git.branch"] = strings.TrimPrefix(strings.TrimPrefix(pushEvent.Ref, "refs/heads/"), "refs/tags/")

if !strings.HasPrefix(pushEvent.Ref, "refs/tags/") {
payload["git.branch"] = strings.TrimPrefix(pushEvent.Ref, "refs/heads/")
} else {
payload["git.tag"] = strings.TrimPrefix(pushEvent.Ref, "refs/tags/")
}
payload["git.hash.before"] = pushEvent.Before
payload["git.hash"] = pushEvent.After
payload["git.repository"] = pushEvent.Repository.FullName
payload["cds.triggered_by.username"] = pushEvent.HeadCommit.Author.Username
payload["cds.triggered_by.fullname"] = pushEvent.HeadCommit.Author.Name
payload["cds.triggered_by.email"] = pushEvent.HeadCommit.Author.Email

if strings.HasPrefix(pushEvent.Ref, "refs/tags/") {
payload["git.tag"] = strings.TrimPrefix(pushEvent.Ref, "refs/tags/")
}
if len(pushEvent.Commits) > 0 {
payload["git.message"] = pushEvent.Commits[0].Message
}
Expand All @@ -551,7 +553,11 @@ func executeRepositoryWebHook(t *sdk.TaskExecution) (*sdk.WorkflowNodeRunHookEve
}
payload["git.author"] = pushEvent.UserUsername
payload["git.author.email"] = pushEvent.UserEmail
payload["git.branch"] = strings.TrimPrefix(strings.TrimPrefix(pushEvent.Ref, "refs/heads/"), "refs/tags/")
if !strings.HasPrefix(pushEvent.Ref, "refs/tags/") {
payload["git.branch"] = strings.TrimPrefix(pushEvent.Ref, "refs/heads/")
} else {
payload["git.tag"] = strings.TrimPrefix(pushEvent.Ref, "refs/tags/")
}
payload["git.hash.before"] = pushEvent.Before
payload["git.hash"] = pushEvent.After
payload["git.repository"] = pushEvent.Project.PathWithNamespace
Expand All @@ -560,9 +566,6 @@ func executeRepositoryWebHook(t *sdk.TaskExecution) (*sdk.WorkflowNodeRunHookEve
payload["cds.triggered_by.fullname"] = pushEvent.UserName
payload["cds.triggered_by.email"] = pushEvent.UserEmail

if strings.HasPrefix(pushEvent.Ref, "refs/tags/") {
payload["git.tag"] = strings.TrimPrefix(pushEvent.Ref, "refs/tags/")
}
if len(pushEvent.Commits) > 0 {
payload["git.message"] = pushEvent.Commits[0].Message
}
Expand All @@ -578,18 +581,18 @@ func executeRepositoryWebHook(t *sdk.TaskExecution) (*sdk.WorkflowNodeRunHookEve
return nil, nil
}

payload["git.branch"] = strings.TrimPrefix(strings.TrimPrefix(pushEvent.Changes[0].RefID, "refs/heads/"), "refs/tags/")
if !strings.HasPrefix(pushEvent.Changes[0].RefID, "refs/tags/") {
payload["git.branch"] = strings.TrimPrefix(pushEvent.Changes[0].RefID, "refs/heads/")
} else {
payload["git.tag"] = strings.TrimPrefix(pushEvent.Changes[0].RefID, "refs/tags/")
}
payload["git.hash.before"] = pushEvent.Changes[0].FromHash
payload["git.hash"] = pushEvent.Changes[0].ToHash
payload["git.repository"] = fmt.Sprintf("%s/%s", pushEvent.Repository.Project.Key, pushEvent.Repository.Slug)

payload["cds.triggered_by.username"] = pushEvent.Actor.Name
payload["cds.triggered_by.fullname"] = pushEvent.Actor.DisplayName
payload["cds.triggered_by.email"] = pushEvent.Actor.EmailAddress

if strings.HasPrefix(pushEvent.Changes[0].RefID, "refs/tags/") {
payload["git.tag"] = strings.TrimPrefix(pushEvent.Changes[0].RefID, "refs/tags/")
}
default:
log.Warning("executeRepositoryWebHook> Repository manager not found. Cannot read %s", string(t.WebHook.RequestBody))
return nil, fmt.Errorf("Repository manager not found. Cannot read request body")
Expand Down
3 changes: 2 additions & 1 deletion engine/hooks/tasks_test.go
Expand Up @@ -73,7 +73,8 @@ func Test_doWebHookExecutionTagGithub(t *testing.T) {
h, err := s.doWebHookExecution(task)
test.NoError(t, err)

assert.Equal(t, "my-branch", h.Payload["git.branch"])
assert.Equal(t, "", h.Payload["git.branch"])
assert.Equal(t, "my-branch", h.Payload["git.tag"])
assert.Equal(t, "baxterthehacker", h.Payload["git.author"])
assert.Equal(t, "Update README.md", h.Payload["git.message"])
assert.Equal(t, "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", h.Payload["git.hash"])
Expand Down
5 changes: 5 additions & 0 deletions engine/sql/121_run_vcs_tag.sql
@@ -0,0 +1,5 @@
-- +migrate Up
ALTER TABLE workflow_node_run ADD COLUMN vcs_tag TEXT;

-- +migrate Down
ALTER TABLE workflow_node_run DROP COLUMN vcs_tag;