diff --git a/README.md b/README.md index ea418c59..74f4bf43 100644 --- a/README.md +++ b/README.md @@ -18,40 +18,70 @@ We have optimized the installation process for Ubuntu since that is what we test wget downloads.drone.io/exp/drone.deb sudo dpkg -i drone.deb ``` -https://github.com/drone/drone/milestones/v0.3 -## What Changed +## Setup -This branch introduces major changes, including: +We are in the process of moving configuration out of the UI and into configuration +files and/or environment variables (your choice which). If you prefer configuration files +you can provide Drone with the path to your configuration file: -1. modification to project structure -2. api-driven design -3. interface to abstract github, bitbucket, gitlab code (see /shared/remote) -4. handlers are structures with service providers "injected" -5. github, bitbucket, etc native permissions are used. No more teams or permissions in Drone -6. github, bitbucket, etc authentication is used. No more drone password -7. github, bitbucket, etc repository data is cached upon login (and subsequent logins) -8. angularjs user interface with modified responsive design +```sh +./drone --config=/path/to/drone.conf -## Database Compatibility Issues +``` + +The configuration file is in TOML format: + +```toml +[github] +client="" +secret="" + +[github_enterprise] +client="" +secret="" +api="" +url="" + +[bitbucket] +client="" +secret="" + +[smtp] +host="" +port="" +from="" +user="" +pass="" +``` + +Or you can use environment variables + +```sh +# github configuration +export DRONE_GITHUB_CLIENT="" +export DRONE_GITHUB_secret="" + +# github enterprise configuration +export DRONE_GITHUB_ENTERPRISE_CLIENT="" +export DRONE_GITHUB_ENTERPRISE_SECRET="" +export DRONE_GITHUB_ENTERPRISE_API="" +export DRONE_GITHUB_ENTERPRISE_URL="" + +# bitbucket configuration +export DRONE_BITBUCKET_CLIENT="" +export DRONE_BITBUCKET_SECRET="" + +# email configuration +export DRONE_SMTP_HOST="" +export DRONE_SMTP_PORT="" +export DRONE_SMTP_FROM="" +export DRONE_SMTP_USER="" +export DRONE_SMTP_PASS="" +``` + +## Compatibility Issues **WARNING** There were some fundamental changes to the application and we decided to introduce breaking changes to the dataabase. Migration would have been difficult and time consuming. Drone is an alpha product and therefore backward compatibility is not a primary goal until we hit a stable release. Apologizes for any inconvenience. - -## Filing Bugs - -This is an experimental branch with known bugs and issues, namely: - -* notifications -* github status api updates -* gitlab integration -* smtp settings screen -* github / bitbucket / gitlab settings screen -* mysql support - -Please do not log issues for the above items. We are aware and will fix as soon as possible, as they are holding up the 0.3 release. Pull requests, however, are very welcome :) - -You can track progress of this release here: - -https://github.com/drone/drone/milestones/v0.3 diff --git a/plugin/notify/email/email.go b/plugin/notify/email/email.go index 8bdddfbc..f113101f 100644 --- a/plugin/notify/email/email.go +++ b/plugin/notify/email/email.go @@ -5,9 +5,9 @@ import ( "fmt" "net" "net/smtp" - "os" "strings" + "github.com/drone/config" "github.com/drone/drone/shared/model" ) @@ -28,11 +28,11 @@ const ( ) var ( - DefaultHost = os.Getenv("SMTP_HOST") - DefaultPort = os.Getenv("SMTP_PORT") - DefaultFrom = os.Getenv("SMTP_FROM") - DefaultUser = os.Getenv("SMTP_USER") - DefaultPass = os.Getenv("SMTP_PASS") + DefaultHost = config.String("smtp-host", "") + DefaultPort = config.String("smtp-port", "") + DefaultFrom = config.String("smtp-from", "") + DefaultUser = config.String("smtp-user", "") + DefaultPass = config.String("smtp-pass", "") ) type Email struct { @@ -139,12 +139,12 @@ func (e *Email) send(subject, body string, recipients []string) error { // configuration. If None provided, attempt to // use the global configuration set in the environet // variables. - if len(DefaultHost) != 0 { - e.Host = DefaultHost - e.Port = DefaultPort - e.From = DefaultFrom - e.Username = DefaultUser - e.Password = DefaultPass + if len(*DefaultHost) != 0 { + e.Host = *DefaultHost + e.Port = *DefaultPort + e.From = *DefaultFrom + e.Username = *DefaultUser + e.Password = *DefaultPass } var auth smtp.Auth diff --git a/plugin/notify/github/github.go b/plugin/notify/github/github.go index 844948ce..b37393a7 100644 --- a/plugin/notify/github/github.go +++ b/plugin/notify/github/github.go @@ -3,21 +3,12 @@ package github import ( "fmt" "net/url" - "os" - "strings" "code.google.com/p/goauth2/oauth" "github.com/drone/drone/shared/model" "github.com/google/go-github/github" ) -// TODO (bradrydzewski) explore using the Repo.URL to parse the GitHub -// Entperprise Scheme+Hostname, instead of the environment variable. Is -// there any reason not to use the environment variable? - -// GitHub enterprise URL -var URL = os.Getenv("GITHUB_ENTERPRISE_API") - const ( NotifyDisabled = "disabled" NotifyFalse = "false" @@ -38,6 +29,10 @@ const ( DescError = "oops, something went wrong" ) +const ( + BaseURL = "https://api.github.com/" +) + type GitHub string // Send uses the github status API to update the build @@ -70,6 +65,7 @@ func (g GitHub) Send(context *model.Request) error { ) return send( + context.Repo.URL, context.Repo.Host, context.Repo.Owner, context.Repo.Name, @@ -81,7 +77,7 @@ func (g GitHub) Send(context *model.Request) error { ) } -func send(host, owner, repo, status, desc, target, ref, token string) error { +func send(rawurl, host, owner, repo, status, desc, target, ref, token string) error { transport := &oauth.Transport{ Token: &oauth.Token{AccessToken: token}, } @@ -99,10 +95,7 @@ func send(host, owner, repo, status, desc, target, ref, token string) error { // the base url. Per the documentation, we need to // ensure there is a trailing slash. if host != model.RemoteGithub { - client.BaseURL, _ = url.Parse(URL) - if !strings.HasSuffix(client.BaseURL.Path, "/") { - client.BaseURL.Path = client.BaseURL.Path + "/" - } + client.BaseURL, _ = getEndpoint(rawurl) } _, _, err := client.Repositories.CreateStatus(owner, repo, ref, &data) @@ -151,3 +144,15 @@ func getDesc(status string) string { func getTarget(url, host, owner, repo, branch, commit string) string { return fmt.Sprintf("%s/%s/%s/%s/%s/%s", url, host, owner, repo, branch, commit) } + +// getEndpoint is a helper funcation that parsed the +// repository HTML URL to determine the API URL. It is +// intended for use with GitHub enterprise. +func getEndpoint(rawurl string) (*url.URL, error) { + uri, err := url.Parse(rawurl) + if err != nil { + return nil, err + } + uri.Path = "/api/v3" + return uri, nil +} diff --git a/plugin/remote/bitbucket/register.go b/plugin/remote/bitbucket/register.go index b59b81d9..ae513a87 100644 --- a/plugin/remote/bitbucket/register.go +++ b/plugin/remote/bitbucket/register.go @@ -1,16 +1,24 @@ package bitbucket import ( - "os" - + "github.com/drone/config" "github.com/drone/drone/plugin/remote" ) -func init() { - var cli = os.Getenv("BITBUCKET_CLIENT") - var sec = os.Getenv("BITBUCKET_SECRET") - if len(cli) == 0 || len(sec) == 0 { +var ( + // Bitbucket cloud configuration details + bitbucketClient = config.String("bitbucket-client", "") + bitbucketSecret = config.String("bitbucket-secret", "") +) + +// Registers the Bitbucket plugin using the default +// settings from the config file or environment +// variables. +func Register() { + if len(*bitbucketClient) == 0 || len(*bitbucketSecret) == 0 { return } - remote.Register(NewDefault(cli, sec)) + remote.Register( + NewDefault(*bitbucketClient, *bitbucketSecret), + ) } diff --git a/plugin/remote/github/github.go b/plugin/remote/github/github.go index 944bda2c..8daa165f 100644 --- a/plugin/remote/github/github.go +++ b/plugin/remote/github/github.go @@ -140,7 +140,7 @@ func (r *GitHub) GetRepos(user *model.User) ([]*model.Repo, error) { Owner: *item.Owner.Login, Name: *item.Name, Private: *item.Private, - URL: *item.URL, + URL: *item.HTMLURL, CloneURL: *item.GitURL, GitURL: *item.GitURL, SSHURL: *item.SSHURL, diff --git a/plugin/remote/github/register.go b/plugin/remote/github/register.go index bce7df93..91e10dc5 100644 --- a/plugin/remote/github/register.go +++ b/plugin/remote/github/register.go @@ -1,41 +1,54 @@ package github import ( - "os" - + "github.com/drone/config" "github.com/drone/drone/plugin/remote" ) -func init() { - init_github() - init_github_enterprise() +var ( + // GitHub cloud configuration details + githubClient = config.String("github-client", "") + githubSecret = config.String("github-secret", "") + + // GitHub Enterprise configuration details + githubEnterpriseURL = config.String("github-enterprise-url", "") + githubEnterpriseAPI = config.String("github-enterprise-api", "") + githubEnterpriseClient = config.String("github-enterprise-client", "") + githubEnterpriseSecret = config.String("github-enterprise-secret", "") +) + +// Registers the GitHub plugins using the default +// settings from the config file or environment +// variables. +func Register() { + registerGitHub() + registerGitHubEnterprise() } // registers the GitHub (github.com) plugin -func init_github() { - var cli = os.Getenv("GITHUB_CLIENT") - var sec = os.Getenv("GITHUB_SECRET") - if len(cli) == 0 || - len(sec) == 0 { +func registerGitHub() { + if len(*githubClient) == 0 || len(*githubSecret) == 0 { return } - var github = NewDefault(cli, sec) - remote.Register(github) + remote.Register( + NewDefault(*githubClient, *githubSecret), + ) } // registers the GitHub Enterprise plugin -func init_github_enterprise() { - var url = os.Getenv("GITHUB_ENTERPRISE_URL") - var api = os.Getenv("GITHUB_ENTERPRISE_API") - var cli = os.Getenv("GITHUB_ENTERPRISE_CLIENT") - var sec = os.Getenv("GITHUB_ENTERPRISE_SECRET") - - if len(url) == 0 || - len(api) == 0 || - len(cli) == 0 || - len(sec) == 0 { +func registerGitHubEnterprise() { + if len(*githubEnterpriseURL) == 0 || + len(*githubEnterpriseAPI) == 0 || + len(*githubEnterpriseClient) == 0 || + len(*githubEnterpriseSecret) == 0 { return } - var github = New(url, api, cli, sec) - remote.Register(github) + remote.Register( + New( + *githubEnterpriseURL, + *githubEnterpriseAPI, + *githubEnterpriseClient, + *githubEnterpriseSecret, + ), + ) } diff --git a/plugin/remote/gitlab/register.go b/plugin/remote/gitlab/register.go index 4e2e36a8..eaac2467 100644 --- a/plugin/remote/gitlab/register.go +++ b/plugin/remote/gitlab/register.go @@ -1,16 +1,22 @@ package gitlab import ( - "os" - + "github.com/drone/config" "github.com/drone/drone/plugin/remote" ) -// registers the Gitlab plugin -func init() { - var url = os.Getenv("GITLAB_URL") - if len(url) == 0 { +var ( + gitlabURL = config.String("gitlab-url", "") +) + +// Registers the Gitlab plugin using the default +// settings from the config file or environment +// variables. +func Register() { + if len(*gitlabURL) == 0 { return } - remote.Register(New(url)) + remote.Register( + New(*gitlabURL), + ) } diff --git a/server/main.go b/server/main.go index 4aaf738b..6a78748d 100644 --- a/server/main.go +++ b/server/main.go @@ -7,6 +7,7 @@ import ( "runtime" "strings" + "github.com/drone/config" "github.com/drone/drone/server/database" "github.com/drone/drone/server/database/schema" "github.com/drone/drone/server/handler" @@ -22,9 +23,9 @@ import ( _ "github.com/mattn/go-sqlite3" "github.com/russross/meddler" - _ "github.com/drone/drone/plugin/remote/bitbucket" - _ "github.com/drone/drone/plugin/remote/github" - _ "github.com/drone/drone/plugin/remote/gitlab" + "github.com/drone/drone/plugin/remote/bitbucket" + "github.com/drone/drone/plugin/remote/github" + "github.com/drone/drone/plugin/remote/gitlab" ) var ( @@ -49,12 +50,16 @@ var ( // Number of concurrent build workers to run // default to number of CPUs on machine workers int + + conf string + prefix string ) func main() { - log.SetPriority(log.LOG_NOTICE) + flag.StringVar(&conf, "config", "", "") + flag.StringVar(&prefix, "prefix", "DRONE_", "") flag.StringVar(&port, "port", ":8080", "") flag.StringVar(&driver, "driver", "sqlite3", "") flag.StringVar(&datasource, "datasource", "drone.sqlite", "") @@ -63,6 +68,14 @@ func main() { flag.IntVar(&workers, "workers", runtime.NumCPU(), "") flag.Parse() + config.SetPrefix(prefix) + config.Parse(conf) + + // setup the remote services + bitbucket.Register() + github.Register() + gitlab.Register() + // setup the database meddler.Default = meddler.SQLite db, _ := sql.Open(driver, datasource) @@ -147,23 +160,3 @@ func main() { panic(http.ListenAndServe(port, nil)) } } - -func init() { - -} - -func init_flags() { - -} - -func init_database() { - -} - -func init_workers() { - -} - -func init_handlers() { - -}