added endpoints for deep links

This commit is contained in:
Brad Rydzewski 2019-09-20 18:17:32 -07:00
parent aaa02ba1a0
commit a3b7511d9c
11 changed files with 87 additions and 88 deletions

View file

@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- endpoint to list builds by branch, by [@bradrydzewski](https://github.com/bradrydzewski). [#1495](https://github.com/drone/drone/issues/1495).
- ignore skip comments when cron event, by [@bradrydzewski](https://github.com/bradrydzewski). [#2835](https://github.com/drone/drone/issues/2835).
- support for admission extensions, by [@bradrydzewski](https://github.com/bradrydzewski). [#2043](https://github.com/drone/drone/issues/2043).
- endpoint to provide link to git resources, by [@bradrydzewski](https://github.com/bradrydzewski). [#1495](https://github.com/drone/drone/issues/1495).
### Fixed
- fixed issue with missing cron job name in user interface, by [@bradrydzewski](https://github.com/bradrydzewski).

View file

@ -80,7 +80,6 @@ func InitializeApplication(config2 config.Config) (application, error) {
runner := provideRunner(buildManager, secretService, registryService, config2)
hookService := provideHookService(client, renewer, config2)
licenseService := license.NewService(userStore, repositoryStore, buildStore, coreLicense)
coreLinker := linker.New(client)
permStore := perm.New(db)
repositoryService := provideRepositoryService(client, renewer, config2)
session, err := provideSession(userStore, config2)
@ -89,14 +88,15 @@ func InitializeApplication(config2 config.Config) (application, error) {
}
batcher := batch.New(db)
syncer := provideSyncer(repositoryService, repositoryStore, userStore, batcher, config2)
server := api.New(buildStore, commitService, cronStore, corePubsub, globalSecretStore, hookService, logStore, coreLicense, licenseService, coreLinker, permStore, repositoryStore, repositoryService, scheduler, secretStore, stageStore, stepStore, statusService, session, logStream, syncer, system, triggerer, userStore, webhookSender)
server := api.New(buildStore, commitService, cronStore, corePubsub, globalSecretStore, hookService, logStore, coreLicense, licenseService, permStore, repositoryStore, repositoryService, scheduler, secretStore, stageStore, stepStore, statusService, session, logStream, syncer, system, triggerer, userStore, webhookSender)
organizationService := orgs.New(client, renewer)
userService := user.New(client)
admissionService := provideAdmissionPlugin(client, organizationService, userService, config2)
hookParser := parser.New(client)
coreLinker := linker.New(client)
middleware := provideLogin(config2)
options := provideServerOptions(config2)
webServer := web.New(admissionService, buildStore, client, hookParser, coreLicense, licenseService, middleware, repositoryStore, session, syncer, triggerer, userStore, userService, webhookSender, options, system)
webServer := web.New(admissionService, buildStore, client, hookParser, coreLicense, licenseService, coreLinker, middleware, repositoryStore, session, syncer, triggerer, userStore, userService, webhookSender, options, system)
mainRpcHandlerV1 := provideRPC(buildManager, config2)
mainRpcHandlerV2 := provideRPC2(buildManager, config2)
mainHealthzHandler := provideHealthz()

View file

@ -19,5 +19,5 @@ import "context"
// Linker provides a deep link to to a git resource in the
// source control management system for a given build.
type Linker interface {
Link(ctx context.Context, repo *Repository, build *Build) (string, error)
Link(ctx context.Context, repo, ref, sha string) (string, error)
}

2
go.mod
View file

@ -24,7 +24,7 @@ require (
github.com/drone/envsubst v1.0.1
github.com/drone/go-license v1.0.2
github.com/drone/go-login v1.0.4-0.20190311170324-2a4df4f242a2
github.com/drone/go-scm v1.6.1-0.20190920225054-0d1ea63283ad
github.com/drone/go-scm v1.6.1-0.20190921005131-635e46e88c20
github.com/drone/signal v1.0.0
github.com/dustin/go-humanize v1.0.0
github.com/ghodss/yaml v1.0.0

2
go.sum
View file

@ -151,6 +151,8 @@ github.com/drone/go-scm v1.5.1-0.20190826160521-fda52b1e0829/go.mod h1:YT4FxQ3U/
github.com/drone/go-scm v1.6.0 h1:PZZWLeSHHwdc6zbSQpg9n0CNoRB+8DAINzX9X/wJifY=
github.com/drone/go-scm v1.6.1-0.20190920225054-0d1ea63283ad h1:rVQW27ofuahCt6Vur7h8oV+fi7JW8yxCiw6PzQmqEFw=
github.com/drone/go-scm v1.6.1-0.20190920225054-0d1ea63283ad/go.mod h1:YT4FxQ3U/ltdCrBJR9B0tRpJ1bYA/PM3NyaLE/rYIvw=
github.com/drone/go-scm v1.6.1-0.20190921005131-635e46e88c20 h1:/Ler+K1NlugcNoBPBLMCcWoN73rnPf+Fscdugb8KWYU=
github.com/drone/go-scm v1.6.1-0.20190921005131-635e46e88c20/go.mod h1:YT4FxQ3U/ltdCrBJR9B0tRpJ1bYA/PM3NyaLE/rYIvw=
github.com/drone/signal v1.0.0 h1:NrnM2M/4yAuU/tXs6RP1a1ZfxnaHwYkd0kJurA1p6uI=
github.com/drone/signal v1.0.0/go.mod h1:S8t92eFT0g4WUgEc/LxG+LCuiskpMNsG0ajAMGnyZpc=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=

View file

@ -27,7 +27,6 @@ import (
"github.com/drone/drone/handler/api/queue"
"github.com/drone/drone/handler/api/repos"
"github.com/drone/drone/handler/api/repos/builds"
"github.com/drone/drone/handler/api/repos/builds/link"
"github.com/drone/drone/handler/api/repos/builds/logs"
"github.com/drone/drone/handler/api/repos/builds/stages"
"github.com/drone/drone/handler/api/repos/collabs"
@ -66,7 +65,6 @@ func New(
logs core.LogStore,
license *core.License,
licenses core.LicenseService,
linker core.Linker,
perms core.PermStore,
repos core.RepositoryStore,
repoz core.RepositoryService,
@ -93,7 +91,6 @@ func New(
Logs: logs,
License: license,
Licenses: licenses,
Linker: linker,
Perms: perms,
Repos: repos,
Repoz: repoz,
@ -123,7 +120,6 @@ type Server struct {
Logs core.LogStore
License *core.License
Licenses core.LicenseService
Linker core.Linker
Perms core.PermStore
Repos core.RepositoryStore
Repoz core.RepositoryService
@ -179,7 +175,6 @@ func (s Server) Handler() http.Handler {
r.Get("/latest", builds.HandleLast(s.Repos, s.Builds, s.Stages))
r.Get("/{number}", builds.HandleFind(s.Repos, s.Builds, s.Stages))
r.Get("/{number}/link", link.HandleLink(s.Repos, s.Builds, s.Linker))
r.Get("/{number}/logs/{stage}/{step}", logs.HandleFind(s.Repos, s.Builds, s.Stages, s.Steps, s.Logs))
r.With(

View file

@ -1,74 +0,0 @@
// Copyright 2019 Drone IO, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package link
import (
"net/http"
"strconv"
"github.com/drone/drone/core"
"github.com/drone/drone/handler/api/render"
"github.com/go-chi/chi"
)
// payload wraps the link and returns to the
// client as a valid json object.
type payload struct {
Link string `json:"link"`
}
// HandleLink returns an http.HandlerFunc that redirects the
// user to the git resource in the remote source control
// management system.
func HandleLink(
repos core.RepositoryStore,
builds core.BuildStore,
linker core.Linker,
) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var (
ctx = r.Context()
namespace = chi.URLParam(r, "owner")
name = chi.URLParam(r, "name")
)
number, err := strconv.ParseInt(chi.URLParam(r, "number"), 10, 64)
if err != nil {
render.BadRequest(w, err)
return
}
repo, err := repos.FindName(ctx, namespace, name)
if err != nil {
render.NotFound(w, err)
return
}
build, err := builds.FindNumber(ctx, repo.ID, number)
if err != nil {
render.NotFound(w, err)
return
}
to, err := linker.Link(ctx, repo, build)
if err != nil {
render.NotFound(w, err)
return
}
if r.FormValue("redirect") == "true" {
http.Redirect(w, r, to, http.StatusSeeOther)
return
}
v := &payload{to}
render.JSON(w, v, http.StatusOK)
}
}

68
handler/web/link/link.go Normal file
View file

@ -0,0 +1,68 @@
// Copyright 2019 Drone IO, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package link
import (
"net/http"
"github.com/drone/drone/core"
"github.com/drone/go-scm/scm"
"github.com/go-chi/chi"
)
// HandleCommit returns an http.HandlerFunc that redirects the
// user to the git resource in the remote source control
// management system.
func HandleCommit(linker core.Linker) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var (
ctx = r.Context()
namespace = chi.URLParam(r, "namespace")
name = chi.URLParam(r, "name")
commit = chi.URLParam(r, "commit")
ref = r.FormValue("ref")
)
repo := scm.Join(namespace, name)
to, err := linker.Link(ctx, repo, ref, commit)
if err != nil {
http.Error(w, "Not Found", http.StatusNotFound)
return
}
http.Redirect(w, r, to, http.StatusSeeOther)
}
}
// HandleTree returns an http.HandlerFunc that redirects the
// user to the git resource in the remote source control
// management system.
func HandleTree(linker core.Linker) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var (
ctx = r.Context()
namespace = chi.URLParam(r, "namespace")
name = chi.URLParam(r, "name")
ref = chi.URLParam(r, "*")
commit = r.FormValue("sha")
)
repo := scm.Join(namespace, name)
to, err := linker.Link(ctx, repo, ref, commit)
if err != nil {
http.Error(w, "Not Found", http.StatusNotFound)
return
}
http.Redirect(w, r, to, http.StatusSeeOther)
}
}

View file

@ -20,6 +20,7 @@ import (
"github.com/drone/drone-ui/dist"
"github.com/drone/drone/core"
"github.com/drone/drone/handler/web/landingpage"
"github.com/drone/drone/handler/web/link"
"github.com/drone/drone/logger"
"github.com/drone/go-login/login"
"github.com/drone/go-scm/scm"
@ -36,6 +37,7 @@ func New(
hooks core.HookParser,
license *core.License,
licenses core.LicenseService,
linker core.Linker,
login login.Middleware,
repos core.RepositoryStore,
session core.Session,
@ -54,6 +56,7 @@ func New(
Hooks: hooks,
License: license,
Licenses: licenses,
Linker: linker,
Login: login,
Repos: repos,
Session: session,
@ -75,6 +78,7 @@ type Server struct {
Hooks core.HookParser
License *core.License
Licenses core.LicenseService
Linker core.Linker
Login login.Middleware
Repos core.RepositoryStore
Session core.Session
@ -101,6 +105,9 @@ func (s Server) Handler() http.Handler {
r.Post("/", HandleHook(s.Repos, s.Builds, s.Triggerer, s.Hooks))
})
r.Get("/link/{namespace}/{name}/tree/*", link.HandleTree(s.Linker))
r.Get("/link/{namespace}/{name}/src/*", link.HandleTree(s.Linker))
r.Get("/link/{namespace}/{name}/commit/{commit}", link.HandleCommit(s.Linker))
r.Get("/version", HandleVersion)
r.Get("/varz", HandleVarz(s.Client, s.License))

View file

@ -32,9 +32,9 @@ type service struct {
client *scm.Client
}
func (s *service) Link(ctx context.Context, repo *core.Repository, build *core.Build) (string, error) {
return s.client.Linker.Resource(ctx, repo.Slug, scm.Reference{
Path: build.Ref,
Sha: build.After,
func (s *service) Link(ctx context.Context, repo, ref, sha string) (string, error) {
return s.client.Linker.Resource(ctx, repo, scm.Reference{
Path: ref,
Sha: sha,
})
}