mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-12-24 10:07:21 +02:00
add rebuild button for users who have admin access to the repo
This commit is contained in:
parent
913332d965
commit
fbdb330d5c
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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,6 +34,11 @@ 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
|
||||
@ -40,7 +46,8 @@ func CommitShow(w http.ResponseWriter, r *http.Request, u *User, repo *Repo) err
|
||||
Build *Build
|
||||
Builds []*Build
|
||||
Token string
|
||||
}{u, repo, commit, builds[0], builds, ""}
|
||||
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
|
||||
}
|
||||
|
@ -142,12 +142,10 @@ 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 {
|
||||
if admin, _ := database.IsRepoAdmin(user, repo); admin == false {
|
||||
RenderNotFound(w)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err = h(w, r, user, repo); err != nil {
|
||||
log.Print(err)
|
||||
|
@ -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">
|
||||
|
Loading…
Reference in New Issue
Block a user