diff --git a/server/datastore/commit.go b/server/datastore/commit.go index 802125ef..8a21a961 100644 --- a/server/datastore/commit.go +++ b/server/datastore/commit.go @@ -47,6 +47,10 @@ type Commitstore interface { // KillCommits updates all pending or started commits // in the datastore settings the status to killed. KillCommits() error + + // GetCommitBuildNumber retrieves the monotonically increaing build number + // from the commit's repo + GetBuildNumber(commit *model.Commit) (int64, error) } // GetCommit retrieves a commit from the @@ -112,3 +116,9 @@ func DelCommit(c context.Context, commit *model.Commit) error { func KillCommits(c context.Context) error { return FromContext(c).KillCommits() } + +// GetBuildNumber retrieves the monotonically increaing build number +// from the commit's repo +func GetBuildNumber(c context.Context, commit *model.Commit) (int64, error) { + return FromContext(c).GetBuildNumber(commit) +} diff --git a/server/datastore/database/commit.go b/server/datastore/database/commit.go index a34c2662..d36e02ae 100644 --- a/server/datastore/database/commit.go +++ b/server/datastore/database/commit.go @@ -1,6 +1,7 @@ package database import ( + "fmt" "time" "github.com/drone/drone/shared/model" @@ -103,6 +104,20 @@ func (db *Commitstore) KillCommits() error { return err } +// GetBuildNumber retrieves the build number for a commit. +func (db *Commitstore) GetBuildNumber(commit *model.Commit) (int64, error) { + row := db.QueryRow(rebind(commitGetBuildNumberStmt), commit.ID, commit.RepoID) + if row == nil { + return 0, fmt.Errorf("Unable to get build number for commit %d", commit.ID) + } + var bn int64 + err := row.Scan(&bn) + if err != nil { + return 0, err + } + return bn, nil +} + // Commit table name in database. const commitTable = "commits" @@ -194,3 +209,12 @@ const commitKillStmt = ` UPDATE commits SET commit_status = 'Killed' WHERE commit_status IN ('Started', 'Pending'); ` + +// SQL statement to retrieve the build number for +// a commit +const commitGetBuildNumberStmt = ` +SELECT COUNT(1) +FROM commits +WHERE commit_id <= ? + AND repo_id = ? +` diff --git a/server/worker/docker/docker.go b/server/worker/docker/docker.go index d2a38514..c777d03c 100644 --- a/server/worker/docker/docker.go +++ b/server/worker/docker/docker.go @@ -76,6 +76,7 @@ func (d *Docker) Do(c context.Context, r *worker.Work) { // mark the build as Started and update the database r.Commit.Status = model.StatusStarted r.Commit.Started = time.Now().UTC().Unix() + datastore.PutCommit(c, r.Commit) // notify all listeners that the build is started @@ -109,15 +110,22 @@ func (d *Docker) Do(c context.Context, r *worker.Work) { } } + // TODO: handle error better? + buildNumber, err := datastore.GetBuildNumber(c, r.Commit) + if err != nil { + log.Printf("Unable to fetch build number, Err: %s", err.Error()) + } + path := r.Repo.Host + "/" + r.Repo.Owner + "/" + r.Repo.Name repo := &repo.Repo{ - Name: path, - Path: r.Repo.CloneURL, - Branch: r.Commit.Branch, - Commit: r.Commit.Sha, - PR: r.Commit.PullRequest, - Dir: filepath.Join("/var/cache/drone/src", git.GitPath(script.Git, path)), - Depth: git.GitDepth(script.Git), + Name: path, + Path: r.Repo.CloneURL, + Branch: r.Commit.Branch, + Commit: r.Commit.Sha, + PR: r.Commit.PullRequest, + Dir: filepath.Join("/var/cache/drone/src", git.GitPath(script.Git, path)), + Depth: git.GitDepth(script.Git), + BuildNumber: buildNumber, } priorCommit, _ := datastore.GetCommitPrior(c, r.Commit) diff --git a/shared/build/build.go b/shared/build/build.go index 9fc28420..6dfac69e 100644 --- a/shared/build/build.go +++ b/shared/build/build.go @@ -488,11 +488,12 @@ func (b *Builder) writeBuildScript(dir string) error { f.WriteEnv("DRONE_COMMIT", b.Repo.Commit) f.WriteEnv("DRONE_PR", b.Repo.PR) f.WriteEnv("DRONE_BUILD_DIR", b.Repo.Dir) + f.WriteEnv("DRONE_BUILD_NUMBER", fmt.Sprintf("%d", b.Repo.BuildNumber)) // add environment variables for code coverage // systems, like coveralls. f.WriteEnv("CI_NAME", "DRONE") - f.WriteEnv("CI_BUILD_NUMBER", b.Repo.Commit) + f.WriteEnv("CI_BUILD_NUMBER", fmt.Sprintf("%d", b.Repo.BuildNumber)) f.WriteEnv("CI_BUILD_URL", "") f.WriteEnv("CI_REMOTE", b.Repo.Path) f.WriteEnv("CI_BRANCH", b.Repo.Branch) diff --git a/shared/build/build_test.go b/shared/build/build_test.go index f9930efd..d01dfb79 100644 --- a/shared/build/build_test.go +++ b/shared/build/build_test.go @@ -522,11 +522,12 @@ func TestWriteBuildScript(t *testing.T) { Hosts: []string{"127.0.0.1"}} b.Key = []byte("ssh-rsa AAA...") b.Repo = &repo.Repo{ - Path: "git://github.com/drone/drone.git", - Branch: "master", - Commit: "e7e046b35", - PR: "123", - Dir: "/var/cache/drone/github.com/drone/drone"} + Path: "git://github.com/drone/drone.git", + Branch: "master", + Commit: "e7e046b35", + BuildNumber: 0, + PR: "123", + Dir: "/var/cache/drone/github.com/drone/drone"} b.writeBuildScript(dir) // persist a dummy build script to disk @@ -548,8 +549,9 @@ func TestWriteBuildScript(t *testing.T) { f.WriteEnv("DRONE_COMMIT", "e7e046b35") f.WriteEnv("DRONE_PR", "123") f.WriteEnv("DRONE_BUILD_DIR", "/var/cache/drone/github.com/drone/drone") + f.WriteEnv("DRONE_BUILD_NUMBER", "0") f.WriteEnv("CI_NAME", "DRONE") - f.WriteEnv("CI_BUILD_NUMBER", "e7e046b35") + f.WriteEnv("CI_BUILD_NUMBER", "0") f.WriteEnv("CI_BUILD_URL", "") f.WriteEnv("CI_REMOTE", "git://github.com/drone/drone.git") f.WriteEnv("CI_BRANCH", "master") diff --git a/shared/build/repo/repo.go b/shared/build/repo/repo.go index 82973efa..8f701110 100644 --- a/shared/build/repo/repo.go +++ b/shared/build/repo/repo.go @@ -40,6 +40,9 @@ type Repo struct { // (optional) The depth of the `git clone` command. Depth int + + // The monotonically increasing build number for this repo + BuildNumber int64 } // IsRemote returns true if the Repository is located