add rebuild button for users who have admin access to the repo

This commit is contained in:
Michael Nutt 2014-05-22 23:52:03 -04:00
parent 913332d965
commit fbdb330d5c
7 changed files with 127 additions and 18 deletions

View file

@ -870,6 +870,14 @@ pre {
font-size: 22px !IMPORTANT;
line-height: 32px !IMPORTANT;
}
.alert.alert-build-Success .actions,
.alert.alert-build-Error .actions,
.alert.alert-build-Failure .actions,
.alert.alert-build-Pending .actions,
.alert.alert-build-Started .actions {
float: right;
margin-top: -2px;
}
.build-details {
background: #FFF;
margin-bottom: 40px;

View file

@ -1021,6 +1021,11 @@ pre {
line-height: 32px !IMPORTANT;
}
}
.actions {
float: right;
margin-top: -2px;
}
}
.build-details {
@ -1285,5 +1290,3 @@ pre {
background: #999;
cursor: pointer;
}

View file

@ -136,6 +136,7 @@ func setupHandlers() {
github = handler.NewGithubHandler(queue)
gitlab = handler.NewGitlabHandler(queue)
bitbucket = handler.NewBitbucketHandler(queue)
rebuild = handler.NewCommitRebuildHandler(queue)
)
m := pat.New()
@ -226,7 +227,9 @@ func setupHandlers() {
// handlers for repository, commits and build details
m.Get("/:host/:owner/:name/commit/:commit/build/:label/out.txt", handler.RepoHandler(handler.BuildOut))
m.Post("/:host/:owner/:name/commit/:commit/build/:label/rebuild", handler.RepoAdminHandler(rebuild.CommitRebuild))
m.Get("/:host/:owner/:name/commit/:commit/build/:label", handler.RepoHandler(handler.CommitShow))
m.Post("/:host/:owner/:name/commit/:commit/rebuild", handler.RepoAdminHandler(rebuild.CommitRebuild))
m.Get("/:host/:owner/:name/commit/:commit", handler.RepoHandler(handler.CommitShow))
m.Get("/:host/:owner/:name/tree", handler.RepoHandler(handler.RepoDashboard))
m.Get("/:host/:owner/:name/status.svg", handler.ErrorHandler(handler.Badge))

View file

@ -90,3 +90,18 @@ func ListReposTeam(id int64) ([]*Repo, error) {
err := meddler.QueryAll(db, &repos, repoTeamStmt, id)
return repos, err
}
// Checks whether a user is admin of a repo
// Returns true if user owns repo or is on team that owns repo
// Returns true if the user is an admin member of the team.
func IsRepoAdmin(user *User, repo *Repo) (bool, error) {
if user == nil {
return false, nil
}
if user.ID == repo.UserID {
return true, nil
}
return IsMemberAdmin(user.ID, repo.TeamID)
}

View file

@ -8,6 +8,7 @@ import (
"github.com/drone/drone/pkg/channel"
"github.com/drone/drone/pkg/database"
. "github.com/drone/drone/pkg/model"
"github.com/drone/drone/pkg/queue"
)
// Display a specific Commit.
@ -33,14 +34,20 @@ func CommitShow(w http.ResponseWriter, r *http.Request, u *User, repo *Repo) err
return err
}
admin, err := database.IsRepoAdmin(u, repo)
if err != nil {
return err
}
data := struct {
User *User
Repo *Repo
Commit *Commit
Build *Build
Builds []*Build
Token string
}{u, repo, commit, builds[0], builds, ""}
User *User
Repo *Repo
Commit *Commit
Build *Build
Builds []*Build
Token string
IsAdmin bool
}{u, repo, commit, builds[0], builds, "", admin}
// get the specific build requested by the user. instead
// of a database round trip, we can just loop through the
@ -94,3 +101,66 @@ func saveFailedBuild(commit *Commit, msg string) error {
return nil
}
type CommitRebuildHandler struct {
queue *queue.Queue
}
func NewCommitRebuildHandler(queue *queue.Queue) *CommitRebuildHandler {
return &CommitRebuildHandler{
queue: queue,
}
}
// CommitRebuild re-queues a previously built commit. It finds the existing
// commit and build and injects them back into the queue. If the commit
// doesn't exist or has no builds, or if a build label has been passed but
// can't be located, it prints an error. Otherwise, it adds the build/commit
// to the queue and redirects back to the commit page.
func (h *CommitRebuildHandler) CommitRebuild(w http.ResponseWriter, r *http.Request, u *User, repo *Repo) error {
hash := r.FormValue(":commit")
labl := r.FormValue(":label")
host := r.FormValue(":host")
// get the commit from the database
commit, err := database.GetCommitHash(hash, repo.ID)
if err != nil {
return err
}
// get the builds from the database. a commit can have
// multiple sub-builds (or matrix builds)
builds, err := database.ListBuilds(commit.ID)
if err != nil {
return err
}
build := builds[0]
if labl != "" {
// get the specific build requested by the user. instead
// of a database round trip, we can just loop through the
// list and extract the requested build.
build = nil
for _, b := range builds {
if b.Slug == labl {
build = b
break
}
}
}
if build == nil {
return fmt.Errorf("Could not find build: %s", labl)
}
h.queue.Add(&queue.BuildTask{Repo: repo, Commit: commit, Build: build})
if labl != "" {
http.Redirect(w, r, fmt.Sprintf("/%s/%s/%s/commit/%s/build/%s", host, repo.Owner, repo.Name, hash, labl), http.StatusSeeOther)
} else {
http.Redirect(w, r, fmt.Sprintf("/%s/%s/%s/commit/%s", host, repo.Owner, repo.Name, hash), http.StatusSeeOther)
}
return nil
}

View file

@ -142,11 +142,9 @@ func (h RepoAdminHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// The User must own the repository OR be a member
// of the Team that owns the repository.
if user.ID != repo.UserID {
if admin, _ := database.IsMemberAdmin(user.ID, repo.TeamID); admin == false {
RenderNotFound(w)
return
}
if admin, _ := database.IsRepoAdmin(user, repo); admin == false {
RenderNotFound(w)
return
}
if err = h(w, r, user, repo); err != nil {

View file

@ -24,6 +24,18 @@
{{ else }}
<span>commit <span>{{ .Commit.HashShort }}</span> to <span>{{.Commit.Branch}}</span> branch</span>
{{ end }}
<div class="actions">
{{ if .IsAdmin }}
{{ if not .Build.IsRunning }}
<form action="/{{.Repo.Slug}}/commit/{{.Commit.Hash}}/rebuild"
method="POST">
<input class="btn btn-default" type="submit" value="Rebuild"/>
</form>
{{ end }}
{{ end }}
</div>
</div>
<div class="build-details container affix-top" data-spy="affix" data-offset-top="248">
<div class="build-summary">