mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-22 18:01:02 +00:00
query and show commits by branch
This allows the same SHA to have different builds on different branches, each separately viewable. This is useful for expressing a "pipeline" in terms of branches, e.g. a commit starts on branch A and progress through B and C to master, with the build script switching on branch name. Previously viewing each build would arbitrarily choose which branch's commit to show.
This commit is contained in:
parent
2241b5bb81
commit
2d837cc3db
14 changed files with 85 additions and 31 deletions
|
@ -205,9 +205,9 @@ func setupHandlers() {
|
|||
m.Post("/install", handler.ErrorHandler(handler.InstallPost))
|
||||
|
||||
// handlers for repository, commits and build details
|
||||
m.Get("/:host/:owner/:name/commit/:commit/build/:label/out.txt", handler.RepoHandler(handler.BuildOut))
|
||||
m.Get("/:host/:owner/:name/commit/:commit/build/:label", handler.RepoHandler(handler.CommitShow))
|
||||
m.Get("/:host/:owner/:name/commit/:commit", handler.RepoHandler(handler.CommitShow))
|
||||
m.Get("/:host/:owner/:name/commit/:branch/:commit/build/:label/out.txt", handler.RepoHandler(handler.BuildOut))
|
||||
m.Get("/:host/:owner/:name/commit/:branch/:commit/build/:label", handler.RepoHandler(handler.CommitShow))
|
||||
m.Get("/:host/:owner/:name/commit/:branch/:commit", handler.RepoHandler(handler.CommitShow))
|
||||
m.Get("/:host/:owner/:name/tree", handler.RepoHandler(handler.RepoDashboard))
|
||||
m.Get("/:host/:owner/:name/status.png", handler.ErrorHandler(handler.Badge))
|
||||
m.Get("/:host/:owner/:name/settings", handler.RepoAdminHandler(handler.RepoSettingsForm))
|
||||
|
|
|
@ -38,7 +38,7 @@ FROM commits
|
|||
WHERE id = ?
|
||||
`
|
||||
|
||||
// SQL Queries to retrieve a Commit by name and repo id.
|
||||
// SQL Queries to retrieve a Commit by hash and repo id.
|
||||
const commitFindHashStmt = `
|
||||
SELECT id, repo_id, status, started, finished, duration,
|
||||
hash, branch, pull_request, author, gravatar, timestamp, message, created, updated
|
||||
|
@ -47,6 +47,15 @@ WHERE hash = ? AND repo_id = ?
|
|||
LIMIT 1
|
||||
`
|
||||
|
||||
// SQL Queries to retrieve a Commit by branch, hash, and repo id.
|
||||
const commitFindBranchHashStmt = `
|
||||
SELECT id, repo_id, status, started, finished, duration,
|
||||
hash, branch, pull_request, author, gravatar, timestamp, message, created, updated
|
||||
FROM commits
|
||||
WHERE branch = ? AND hash = ? AND repo_id = ?
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
// SQL Query to retrieve a list of recent commits by user.
|
||||
const userCommitRecentStmt = `
|
||||
SELECT r.slug, r.host, r.owner, r.name,
|
||||
|
@ -101,7 +110,7 @@ WHERE id IN (
|
|||
SELECT MAX(id)
|
||||
FROM commits
|
||||
WHERE repo_id = ?
|
||||
AND branch = ?
|
||||
AND branch = ?
|
||||
GROUP BY branch)
|
||||
LIMIT 1
|
||||
`
|
||||
|
@ -120,6 +129,13 @@ func GetCommitHash(hash string, repo int64) (*Commit, error) {
|
|||
return &commit, err
|
||||
}
|
||||
|
||||
// Returns the Commit on the given branch with the given hash.
|
||||
func GetCommitBranchHash(branch string, hash string, repo int64) (*Commit, error) {
|
||||
commit := Commit{}
|
||||
err := meddler.QueryRow(db, &commit, commitFindBranchHashStmt, branch, hash, repo)
|
||||
return &commit, err
|
||||
}
|
||||
|
||||
// Returns the most recent Commit for the given branch.
|
||||
func GetBranch(repo int64, branch string) (*Commit, error) {
|
||||
commit := Commit{}
|
||||
|
|
|
@ -44,6 +44,32 @@ func TestGetCommit(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGetCommitBranchHash(t *testing.T) {
|
||||
Setup()
|
||||
defer Teardown()
|
||||
|
||||
commit, err := database.GetCommitBranchHash("develop", "5f32ec7b08dfe3a097c1a5316de5b5069fb35ff9", 2)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if commit.ID != 5 {
|
||||
t.Errorf("Exepected ID %d, got %d", 5, commit.ID)
|
||||
}
|
||||
|
||||
if commit.Branch != "develop" {
|
||||
t.Errorf("Exepected Branch %s, got %s", "develop", commit.Branch)
|
||||
}
|
||||
|
||||
if commit.Hash != "5f32ec7b08dfe3a097c1a5316de5b5069fb35ff9" {
|
||||
t.Errorf("Exepected Hash %s, got %s", "5f32ec7b08dfe3a097c1a5316de5b5069fb35ff9", commit.Hash)
|
||||
}
|
||||
|
||||
if commit.Status != "Success" {
|
||||
t.Errorf("Exepected Status %s, got %s", "Success", commit.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCommitHash(t *testing.T) {
|
||||
Setup()
|
||||
defer Teardown()
|
||||
|
|
|
@ -191,12 +191,22 @@ func Setup() {
|
|||
Gravatar: user1.Gravatar,
|
||||
Message: "commit message",
|
||||
}
|
||||
commit5 := Commit{
|
||||
RepoID: repo2.ID,
|
||||
Status: "Success",
|
||||
Hash: "5f32ec7b08dfe3a097c1a5316de5b5069fb35ff9",
|
||||
Branch: "develop",
|
||||
Author: user1.Email,
|
||||
Gravatar: user1.Gravatar,
|
||||
Message: "commit message",
|
||||
}
|
||||
|
||||
// create dummy commit data
|
||||
database.SaveCommit(&commit1)
|
||||
database.SaveCommit(&commit2)
|
||||
database.SaveCommit(&commit3)
|
||||
database.SaveCommit(&commit4)
|
||||
database.SaveCommit(&commit5)
|
||||
|
||||
// create dummy build data
|
||||
database.SaveBuild(&Build{CommitID: commit1.ID, Slug: "node_0.10", Status: "Success", Duration: 60})
|
||||
|
|
|
@ -9,11 +9,12 @@ import (
|
|||
|
||||
// Returns the combined stdout / stderr for an individual Build.
|
||||
func BuildOut(w http.ResponseWriter, r *http.Request, u *User, repo *Repo) error {
|
||||
branch := r.FormValue(":branch")
|
||||
hash := r.FormValue(":commit")
|
||||
labl := r.FormValue(":label")
|
||||
|
||||
// get the commit from the database
|
||||
commit, err := database.GetCommitHash(hash, repo.ID)
|
||||
commit, err := database.GetCommitBranchHash(branch, hash, repo.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -11,11 +11,12 @@ import (
|
|||
|
||||
// Display a specific Commit.
|
||||
func CommitShow(w http.ResponseWriter, r *http.Request, u *User, repo *Repo) error {
|
||||
branch := r.FormValue(":branch")
|
||||
hash := r.FormValue(":commit")
|
||||
labl := r.FormValue(":label")
|
||||
|
||||
// get the commit from the database
|
||||
commit, err := database.GetCommitHash(hash, repo.ID)
|
||||
commit, err := database.GetCommitBranchHash(branch, hash, repo.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -49,7 +50,7 @@ func CommitShow(w http.ResponseWriter, r *http.Request, u *User, repo *Repo) err
|
|||
// generate a token to connect with the websocket
|
||||
// handler and stream output, if the build is running.
|
||||
data.Token = channel.Token(fmt.Sprintf(
|
||||
"%s/%s/%s/commit/%s/builds/%s", repo.Host, repo.Owner, repo.Name, commit.Hash, builds[0].Slug))
|
||||
"%s/%s/%s/commit/%s/%s/builds/%s", repo.Host, repo.Owner, repo.Name, commit.Branch, commit.Hash, builds[0].Slug))
|
||||
|
||||
// render the repository template.
|
||||
return RenderTemplate(w, "repo_commit.html", &data)
|
||||
|
|
|
@ -74,7 +74,7 @@ func (h *HookHandler) Hook(w http.ResponseWriter, r *http.Request) error {
|
|||
|
||||
// Verify that the commit doesn't already exist.
|
||||
// We should never build the same commit twice.
|
||||
_, err = database.GetCommitHash(hook.Head.Id, repo.ID)
|
||||
_, err = database.GetCommitBranchHash(hook.Branch(), hook.Head.Id, repo.ID)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
println("commit already exists")
|
||||
return RenderText(w, http.StatusText(http.StatusBadGateway), http.StatusBadGateway)
|
||||
|
|
|
@ -95,8 +95,8 @@ func (w *worker) execute(task *BuildTask) error {
|
|||
// make sure a channel exists for the repository,
|
||||
// the commit, and the commit output (TODO)
|
||||
reposlug := fmt.Sprintf("%s/%s/%s", task.Repo.Host, task.Repo.Owner, task.Repo.Name)
|
||||
commitslug := fmt.Sprintf("%s/%s/%s/commit/%s", task.Repo.Host, task.Repo.Owner, task.Repo.Name, task.Commit.Hash)
|
||||
consoleslug := fmt.Sprintf("%s/%s/%s/commit/%s/builds/%s", task.Repo.Host, task.Repo.Owner, task.Repo.Name, task.Commit.Hash, task.Build.Slug)
|
||||
commitslug := fmt.Sprintf("%s/%s/%s/commit/%s/%s", task.Repo.Host, task.Repo.Owner, task.Repo.Name, task.Commit.Branch, task.Commit.Hash)
|
||||
consoleslug := fmt.Sprintf("%s/%s/%s/commit/%s/%s/builds/%s", task.Repo.Host, task.Repo.Owner, task.Repo.Name, task.Commit.Branch, task.Commit.Hash, task.Build.Slug)
|
||||
channel.Create(reposlug)
|
||||
channel.Create(commitslug)
|
||||
channel.CreateStream(consoleslug)
|
||||
|
@ -223,7 +223,7 @@ func updateGitHubStatus(repo *Repo, commit *Commit) error {
|
|||
client.ApiUrl = settings.GitHubApiUrl
|
||||
|
||||
var url string
|
||||
url = settings.URL().String() + "/" + repo.Slug + "/commit/" + commit.Hash
|
||||
url = settings.URL().String() + "/" + repo.Slug + "/commit/" + commit.Branch + "/" + commit.Hash
|
||||
|
||||
return client.Repos.CreateStatus(repo.Owner, repo.Name, status, url, message, commit.Hash)
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<table class="commit-table" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 100%; margin: 0; padding: 0;">
|
||||
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;">
|
||||
<th style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; text-align: left; color: #333; margin: 0; padding: 0 30px 0 20px;" align="left">commit:</th>
|
||||
<td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 99%; color: #333; margin: 0; padding: 0;"><a href="{{.Host}}/{{.Repo.Slug}}/commit/{{ .Commit.Hash }}" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; color: #2a6496; font-weight: normal; margin: 0; padding: 0;">{{ .Commit.HashShort }}</a></td>
|
||||
<td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 99%; color: #333; margin: 0; padding: 0;"><a href="{{.Host}}/{{.Repo.Slug}}/commit/{{.Commit.Branch}}/{{ .Commit.Hash }}" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; color: #2a6496; font-weight: normal; margin: 0; padding: 0;">{{ .Commit.HashShort }}</a></td>
|
||||
</tr>
|
||||
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;">
|
||||
<th style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; text-align: left; color: #333; margin: 0; padding: 0 30px 0 20px;" align="left">branch:</th>
|
||||
|
@ -25,4 +25,4 @@
|
|||
<td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 99%; color: #333; margin: 0; padding: 0;">{{ .Commit.Message }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<table class="commit-table" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 100%; margin: 0; padding: 0;">
|
||||
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;">
|
||||
<th style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; text-align: left; color: #333; margin: 0; padding: 0 30px 0 20px;" align="left">commit:</th>
|
||||
<td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 99%; color: #333; margin: 0; padding: 0;"><a href="{{.Host}}/{{.Repo.Slug}}/commit/{{ .Commit.Hash }}" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; color: #2a6496; font-weight: normal; margin: 0; padding: 0;">{{ .Commit.HashShort }}</a></td>
|
||||
<td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; width: 99%; color: #333; margin: 0; padding: 0;"><a href="{{.Host}}/{{.Repo.Slug}}/commit/{{ .Commit.Branch }}/{{ .Commit.Hash }}" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; color: #2a6496; font-weight: normal; margin: 0; padding: 0;">{{ .Commit.HashShort }}</a></td>
|
||||
</tr>
|
||||
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; margin: 0; padding: 0;">
|
||||
<th style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; text-align: left; color: #333; margin: 0; padding: 0 30px 0 20px;" align="left">branch:</th>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<div class="subhead">
|
||||
<div class="container">
|
||||
<ul class="nav nav-tabs pull-right">
|
||||
<li class="active"><a href="/{{.Repo.Slug}}/commit/{{ .Commit.Hash }}">{{ .Commit.HashShort }}</a></li>
|
||||
<li class="active"><a href="/{{.Repo.Slug}}/commit/{{ .Commit.Branch }}/{{ .Commit.Hash }}">{{ .Commit.HashShort }}</a></li>
|
||||
<li><a href="/{{.Repo.Slug}}">Commits</a></li>
|
||||
<li><a href="/{{.Repo.Slug}}/settings">Settings</a></li>
|
||||
</ul> <!-- ./nav -->
|
||||
|
@ -18,7 +18,7 @@
|
|||
|
||||
<div class="container">
|
||||
<div class="alert alert-build-{{ .Build.Status }}">
|
||||
<a href="/{{.Repo.Slug}}/commit/{{.Commit.Hash }}" class="btn btn-{{ .Build.Status }}"></a>
|
||||
<a href="/{{.Repo.Slug}}/{{.Commit.Branch}}/commit/{{ .Commit.Branch }}/{{ .Commit.Hash }}" class="btn btn-{{ .Build.Status }}"></a>
|
||||
{{ if .Commit.PullRequest }}
|
||||
<span>opened pull request <span># {{ .Commit.PullRequest }}</span></span>
|
||||
{{ else }}
|
||||
|
@ -78,7 +78,7 @@
|
|||
});
|
||||
|
||||
{{ else }}
|
||||
$.get("/{{ .Repo.Slug }}/commit/{{ .Commit.Hash }}/build/{{ .Build.Slug }}/out.txt", function( data ) {
|
||||
$.get("/{{ .Repo.Slug }}/commit/{{ .Commit.Branch }}/{{ .Commit.Hash }}/build/{{ .Build.Slug }}/out.txt", function( data ) {
|
||||
var lineFormatter = new Drone.LineFormatter();
|
||||
$( "#stdout" ).html(lineFormatter.format(data));
|
||||
});
|
||||
|
|
|
@ -28,12 +28,12 @@
|
|||
<ul class="commit-list commit-list-alt">
|
||||
{{ range .Commits }}
|
||||
<li>
|
||||
<a href="/{{$repo.Slug}}/commit/{{.Hash}}" class="btn btn-{{.Status}}"></a>
|
||||
<a href="/{{$repo.Slug}}/commit/{{.Branch}}/{{.Hash}}" class="btn btn-{{.Status}}"></a>
|
||||
<h3>
|
||||
<a href="/{{$repo.Slug}}/commit/{{.Hash}}">{{.HashShort}}</a>
|
||||
<a href="/{{$repo.Slug}}/commit/{{.Branch}}/{{.Hash}}">{{.HashShort}}</a>
|
||||
<small class="timeago" title="{{.CreatedString}}"></small>
|
||||
{{ if .PullRequest }}
|
||||
<p>opened pull request <a href="/{{$repo.Slug}}/commit/{{.Hash}}"># {{.PullRequest}}</a></p>
|
||||
<p>opened pull request <a href="/{{$repo.Slug}}/commit/{{.Branch}}/{{.Hash}}"># {{.PullRequest}}</a></p>
|
||||
{{ else }}
|
||||
<p>{{.Message}} </p>
|
||||
{{ end }}
|
||||
|
|
|
@ -45,14 +45,14 @@
|
|||
<ul class="commit-list">
|
||||
{{ range $commit := .Commits }}
|
||||
<li>
|
||||
<a href="/{{$commit.Slug}}/commit/{{$commit.Hash}}" class="btn btn-{{$commit.Status}}"></a>
|
||||
<a href="/{{$commit.Slug}}/commit/{{$commit.Branch}}/{{$commit.Hash}}" class="btn btn-{{$commit.Status}}"></a>
|
||||
<h3>
|
||||
<a href="/{{$commit.Slug}}">{{$commit.Owner}} / {{$commit.Name}}</a>
|
||||
<small class="timeago" title="{{$commit.CreatedString}}"></small>
|
||||
{{ if $commit.PullRequest }}
|
||||
<p>opened pull request <a href="/{{$commit.Slug}}/commit/{{$commit.Hash}}"># {{$commit.PullRequest}}</a></p>
|
||||
<p>opened pull request <a href="/{{$commit.Slug}}/commit/{{$commit.Branch}}/{{$commit.Hash}}"># {{$commit.PullRequest}}</a></p>
|
||||
{{ else }}
|
||||
<p>commit <a href="/{{$commit.Slug}}/commit/{{$commit.Hash}}">{{$commit.HashShort}}</a> to <a href="/{{$commit.Slug}}?branch={{$commit.Branch}}">{{$commit.Branch}}</a> branch</p>
|
||||
<p>commit <a href="/{{$commit.Slug}}/commit/{{$commit.Branch}}/{{$commit.Hash}}">{{$commit.HashShort}}</a> to <a href="/{{$commit.Slug}}?branch={{$commit.Branch}}">{{$commit.Branch}}</a> branch</p>
|
||||
{{ end }}
|
||||
</h3>
|
||||
</li>
|
||||
|
@ -88,7 +88,7 @@
|
|||
<script>
|
||||
if (window.localStorage) {
|
||||
// get the last visited date from local storage
|
||||
var lastVisited = localStorage["lastVisited"];
|
||||
var lastVisited = localStorage["lastVisited"];
|
||||
if (lastVisited == "null" || lastVisited == NaN || !lastVisited) {
|
||||
lastVisited = Date.parse("1970-01-01T00:00:00Z");
|
||||
} else {
|
||||
|
@ -108,4 +108,4 @@
|
|||
});
|
||||
}
|
||||
</script>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
|
|
@ -43,14 +43,14 @@
|
|||
<ul class="commit-list">
|
||||
{{ range $commit := .Commits }}
|
||||
<li>
|
||||
<a href="/{{$commit.Slug}}/commit/{{$commit.Hash}}" class="btn btn-{{$commit.Status}}"></a>
|
||||
<a href="/{{$commit.Slug}}/commit/{{$commit.Branch}}/{{$commit.Hash}}" class="btn btn-{{$commit.Status}}"></a>
|
||||
<h3>
|
||||
<a href="/{{$commit.Slug}}">{{$commit.Owner}} / {{$commit.Name}}</a>
|
||||
<small class="timeago" title="{{$commit.CreatedString}}"></small>
|
||||
{{ if $commit.PullRequest }}
|
||||
<p>opened pull request <a href="/{{$commit.Slug}}/commit/{{$commit.Hash}}"># {{$commit.PullRequest}}</a></p>
|
||||
<p>opened pull request <a href="/{{$commit.Slug}}/commit/{{$commit.Branch}}/{{$commit.Hash}}"># {{$commit.PullRequest}}</a></p>
|
||||
{{ else }}
|
||||
<p>commit <a href="/{{$commit.Slug}}/commit/{{$commit.Hash}}">{{$commit.HashShort}}</a> to <a href="/{{$commit.Slug}}?branch={{$commit.Branch}}">{{$commit.Branch}}</a> branch</p>
|
||||
<p>commit <a href="/{{$commit.Slug}}/commit/{{$commit.Branch}}/{{$commit.Hash}}">{{$commit.HashShort}}</a> to <a href="/{{$commit.Slug}}?branch={{$commit.Branch}}">{{$commit.Branch}}</a> branch</p>
|
||||
{{ end }}
|
||||
</h3>
|
||||
</li>
|
||||
|
@ -86,8 +86,8 @@
|
|||
<script>
|
||||
if (window.localStorage) {
|
||||
// get the last visited date from local storage
|
||||
var lastVisited = localStorage["lastVisited"];
|
||||
|
||||
var lastVisited = localStorage["lastVisited"];
|
||||
|
||||
if (lastVisited == "null" || lastVisited == NaN || !lastVisited) {
|
||||
lastVisited = Date.parse("1970-01-01T00:00:00Z");
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue