From 2e36ee9c725df05a732146ca45a68bde82066ea9 Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Sat, 13 Apr 2019 01:52:31 -0700 Subject: [PATCH] WIP endpoint to create build from branch, sha --- cmd/drone-server/wire_gen.go | 2 +- handler/api/api.go | 5 + handler/api/repos/builds/create.go | 121 ++++++++++++++++++++++++ handler/api/repos/builds/create_test.go | 5 + version/version.go | 2 +- 5 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 handler/api/repos/builds/create.go create mode 100644 handler/api/repos/builds/create_test.go diff --git a/cmd/drone-server/wire_gen.go b/cmd/drone-server/wire_gen.go index 40507b2d..dfba4ee7 100644 --- a/cmd/drone-server/wire_gen.go +++ b/cmd/drone-server/wire_gen.go @@ -82,7 +82,7 @@ func InitializeApplication(config2 config.Config) (application, error) { session := provideSession(userStore, config2) batcher := batch.New(db) syncer := provideSyncer(repositoryService, repositoryStore, userStore, batcher, config2) - server := api.New(buildStore, cronStore, corePubsub, hookService, logStore, coreLicense, licenseService, permStore, repositoryStore, repositoryService, scheduler, secretStore, stageStore, stepStore, statusService, session, logStream, syncer, system, triggerer, userStore, webhookSender) + server := api.New(buildStore, commitService, cronStore, corePubsub, 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) diff --git a/handler/api/api.go b/handler/api/api.go index f0de24c0..dbef3e7d 100644 --- a/handler/api/api.go +++ b/handler/api/api.go @@ -55,6 +55,7 @@ var corsOpts = cors.Options{ func New( builds core.BuildStore, + commits core.CommitService, cron core.CronStore, events core.Pubsub, hooks core.HookService, @@ -80,6 +81,7 @@ func New( return Server{ Builds: builds, Cron: cron, + Commits: commits, Events: events, Hooks: hooks, Logs: logs, @@ -107,6 +109,7 @@ func New( type Server struct { Builds core.BuildStore Cron core.CronStore + Commits core.CommitService Events core.Pubsub Hooks core.HookService Logs core.LogStore @@ -163,6 +166,8 @@ func (s Server) Handler() http.Handler { r.Route("/builds", func(r chi.Router) { r.Get("/", builds.HandleList(s.Repos, s.Builds)) + // TODO(bradrydzewski) temporarily disabled until we finalize the endpoint. + // r.Post("/", builds.HandleCreate(s.Repos, s.Commits, s.Triggerer)) 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}/logs/{stage}/{step}", logs.HandleFind(s.Repos, s.Builds, s.Stages, s.Steps, s.Logs)) diff --git a/handler/api/repos/builds/create.go b/handler/api/repos/builds/create.go new file mode 100644 index 00000000..fb7dc3a0 --- /dev/null +++ b/handler/api/repos/builds/create.go @@ -0,0 +1,121 @@ +// 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 builds + +import ( + "encoding/json" + "net/http" + + "github.com/drone/drone/core" + "github.com/drone/drone/handler/api/render" + "github.com/drone/drone/handler/api/request" + "github.com/drone/go-scm/scm" + + "github.com/go-chi/chi" +) + +type createBuild struct { + Params map[string]string `json:"params"` + Commit *string `json:"commit"` + Branch *string `json:"branch"` + Ref *string `json:"ref"` +} + +// HandleCreate returns an http.HandlerFunc that processes http +// requests to create a build for the specified commit. +func HandleCreate( + repos core.RepositoryStore, + commits core.CommitService, + triggerer core.Triggerer, +) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var ( + ctx = r.Context() + namespace = chi.URLParam(r, "owner") + name = chi.URLParam(r, "name") + user, _ = request.UserFrom(ctx) + ) + in := new(createBuild) + err := json.NewDecoder(r.Body).Decode(in) + if err != nil { + render.BadRequest(w, err) + return + } + if in.Ref == nil || in.Branch == nil { + render.BadRequestf(w, "Missing branch or ref") + return + } + if in.Params == nil { + // cannot remember if parameters must be non-nil, + // so we set the value to prevent a possible + // downstream nil pointer. just being overly cautious ... + in.Params = map[string]string{} + } + repo, err := repos.FindName(ctx, namespace, name) + if err != nil { + render.NotFound(w, err) + return + } + var commit *core.Commit + if in.Commit == nil { + commit, err = commits.Find(ctx, user, repo.Slug, *in.Commit) + } else if in.Ref != nil { + commit, err = commits.FindRef(ctx, user, repo.Slug, *in.Ref) + } else if in.Branch != nil { + ref := scm.ExpandRef(*in.Branch, "refs/heads") + commit, err = commits.FindRef(ctx, user, repo.Slug, ref) + } + if err != nil { + render.NotFound(w, err) + return + } + + hook := &core.Hook{ + Trigger: user.Login, + Event: core.EventPush, + Link: commit.Link, + Timestamp: commit.Author.Date, + Title: "", // we expect this to be empty. + Message: commit.Message, + Before: "", // we expect this to be empty. + After: commit.Sha, + Ref: "", // set below + Source: "", // set below + Target: "", // set below + Author: commit.Author.Login, + AuthorName: commit.Author.Name, + AuthorEmail: commit.Author.Email, + AuthorAvatar: commit.Author.Avatar, + Sender: "", // todo: what value should we use? + Params: in.Params, + } + if in.Branch != nil { + hook.Source = *in.Branch + hook.Target = *in.Branch + } + if in.Ref != nil { + branch := scm.TrimRef(*in.Ref) + hook.Source = branch + hook.Target = branch + } + + result, err := triggerer.Trigger(r.Context(), repo, hook) + if err != nil { + render.InternalError(w, err) + } else { + render.JSON(w, result, 200) + } + } +} diff --git a/handler/api/repos/builds/create_test.go b/handler/api/repos/builds/create_test.go new file mode 100644 index 00000000..49523703 --- /dev/null +++ b/handler/api/repos/builds/create_test.go @@ -0,0 +1,5 @@ +// Copyright 2019 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by the Drone Non-Commercial License +// that can be found in the LICENSE file. + +package builds diff --git a/version/version.go b/version/version.go index 986d9420..2bbf06db 100644 --- a/version/version.go +++ b/version/version.go @@ -27,7 +27,7 @@ var ( // VersionMinor is for functionality in a backwards-compatible manner. VersionMinor int64 // VersionPatch is for backwards-compatible bug fixes. - VersionPatch int64 + VersionPatch int64 = 1 // VersionPre indicates prerelease. VersionPre = "" // VersionDev indicates development branch. Releases will be empty string.