Browse Source

add exec script

master
AJ ONeal 4 years ago
parent
commit
cad179977c
  1. 1
      AUTHORS
  2. 4
      LICENSE
  3. 36
      README.md
  4. 18
      example.sh
  5. 1
      internal/options/options.go
  6. 32
      internal/webhooks/github/github.go
  7. 5
      internal/webhooks/webhooks.go
  8. 78
      main.go

1
AUTHORS

@ -1 +1,2 @@
Ryan Burnette <ryan.burnette@gmail.com> (https://ryanburnette.com)
AJ ONeal <aj@therootcompany.com> (https://therootcompany.com)

4
LICENSE

@ -1 +1,3 @@
Copyright 2020 AJ ONeal. All rights reserved.
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.

36
README.md

@ -2,6 +2,32 @@
**git-deploy** is an app for handling continuous deployment of static websites.
## Usage
```bash
echo 'GITHUB_SECRET=xxxxxxx' >> .env
./git-deploy init
./git-deploy run --listen :3000 --serve-path ./overrides --exec ./path/to/script.sh
```
To manage `git credentials`
see [The Vanilla DevOps Git Credentials Cheatsheet][1]
[1]: https://coolaj86.com/articles/vanilla-devops-git-credentials-cheatsheet/
## Git Info
The exec script will receive the parent environment as well as
```bash
GIT_DEPLOY_JOB_ID=xxxxxx
GIT_REF_NAME=master
GIT_REF_TYPE=branch
GIT_REPO_OWNER=example
GIT_REPO_NAME=example
GIT_CLONE_URL=https://github.com/example/example
```
## Build
```bash
@ -18,10 +44,6 @@ go generate -mod=vendor ./...
go build -mod=vendor .
```
```bash
./git-deploy run --listen :3000 --serve-path ./overrides
```
## Add Webhooks
To add a webhook you'll first need a secret
@ -104,4 +126,8 @@ crypto
## License
Copyright 2020. All rights reserved.
Copyright 2020 The git-deploy Authors
This Source Code Form is subject to the terms of the Mozilla Public \
License, v. 2.0. If a copy of the MPL was not distributed with this \
file, You can obtain one at https://mozilla.org/MPL/2.0/.

18
example.sh

@ -0,0 +1,18 @@
#!/bin/bash
for x in $@; do
echo "$x"
done
my_envs='GIT_REF_NAME
GIT_REF_TYPE
GIT_REPO_OWNER
GIT_REPO_NAME
GIT_CLONE_URL'
echo 'Doing "work" ...'
sleep 5
for x in $my_envs; do
echo "$x=${!x}"
done

1
internal/options/options.go

@ -11,6 +11,7 @@ type ServerConfig struct {
TrustProxy bool
Compress bool
ServePath string
Exec string
}
var ServerFlags *flag.FlagSet

32
internal/webhooks/github/github.go

@ -6,6 +6,7 @@ import (
"log"
"net/http"
"os"
"strings"
"git.ryanburnette.com/ryanburnette/git-deploy/internal/options"
"git.ryanburnette.com/ryanburnette/git-deploy/internal/webhooks"
@ -63,16 +64,33 @@ func InitWebhook(providername string, secret *string, envname string) func() {
switch e := event.(type) {
case *github.PushEvent:
// this is a commit push, do something with it
var branch string
var tag string
ref := e.GetRef() // *e.Ref
branch := ref[len("refs/heads/"):]
parts := strings.Split(ref, "/")
refType := parts[1]
prefixLen := len("refs/") + len(refType) + len("/")
refName := ref[prefixLen:]
switch refType {
case "tags":
refType = "tag"
tag = refName
case "heads":
refType = "branch"
branch = refName
}
webhooks.Hook(webhooks.Ref{
Rev: e.GetAfter(), // *e.After
Ref: ref,
Branch: branch,
Repo: e.GetRepo().GetName(), // *e.Repo.Name
Org: e.GetRepo().GetOrganization(), // *e.Repo.Organization
HTTPSURL: e.GetRepo().GetCloneURL(),
SSHURL: e.GetRepo().GetSSHURL(),
Rev: e.GetAfter(), // *e.After
Ref: ref,
RefType: refType,
RefName: refName,
Branch: branch,
Tag: tag,
Repo: e.GetRepo().GetName(), // *e.Repo.Name
Owner: e.GetRepo().GetOwner().GetLogin(),
})
/*
case *github.PullRequestEvent:

5
internal/webhooks/webhooks.go

@ -17,9 +17,12 @@ type Ref struct {
SSHURL string
Rev string
Ref string
RefType string // tags, heads
RefName string
Branch string
Tag string
Owner string
Repo string
Org string
}
var Providers = make(map[string]func())

78
main.go

@ -2,10 +2,13 @@ package main
import (
"compress/flate"
"encoding/base64"
"flag"
"fmt"
"log"
"net/http"
"os"
"os/exec"
"time"
"git.ryanburnette.com/ryanburnette/git-deploy/assets"
@ -37,6 +40,14 @@ func ver() {
fmt.Printf("%s v%s %s (%s)\n", name, version, commit[:7], date)
}
type job struct {
ID string // {HTTPSURL}#{BRANCH}
Cmd *exec.Cmd
Ref webhooks.Ref
}
var jobs = make(map[string]*job)
var runOpts *options.ServerConfig
var runFlags *flag.FlagSet
var initFlags *flag.FlagSet
@ -48,7 +59,12 @@ func init() {
runFlags.StringVar(&runOpts.Addr, "listen", ":3000", "the address and port on which to listen")
runFlags.BoolVar(&runOpts.TrustProxy, "trust-proxy", false, "trust X-Forwarded-For header")
runFlags.BoolVar(&runOpts.Compress, "compress", true, "enable compression for text,html,js,css,etc")
runFlags.StringVar(&runOpts.ServePath, "serve-path", "", "path to serve, falls back to built-in web app")
runFlags.StringVar(
&runOpts.ServePath, "serve-path", "",
"path to serve, falls back to built-in web app")
runFlags.StringVar(
&runOpts.Exec, "exec", "",
"path to bash script to run with git info as arguments")
}
func main() {
@ -80,6 +96,11 @@ func main() {
initFlags.Parse(args[2:])
case "run":
runFlags.Parse(args[2:])
if "" == runOpts.Exec {
fmt.Printf("--exec <path/to/script.sh> is a required flag")
os.Exit(1)
return
}
webhooks.MustRegisterAll()
serve()
default:
@ -141,9 +162,58 @@ func serve() {
for {
hook := webhooks.Accept()
// TODO os.Exec
fmt.Println(hook.Org)
fmt.Println(hook.Repo)
fmt.Println(hook.Branch)
fmt.Printf("%#v\n", hook)
jobID := base64.URLEncoding.EncodeToString([]byte(
fmt.Sprintf("%s#%s", hook.HTTPSURL, hook.RefName),
))
args := []string{
runOpts.Exec,
jobID,
hook.RefName,
hook.RefType,
hook.Owner,
hook.Repo,
hook.HTTPSURL,
}
cmd := exec.Command("bash", args...)
env := os.Environ()
envs := []string{
"GIT_DEPLOY_JOB_ID=" + jobID,
"GIT_REF_NAME=" + hook.RefName,
"GIT_REF_TYPE=" + hook.RefType,
"GIT_REPO_OWNER=" + hook.Owner,
"GIT_REPO_NAME=" + hook.Repo,
"GIT_CLONE_URL=" + hook.HTTPSURL,
}
cmd.Env = append(env, envs...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if _, exists := jobs[jobID]; exists {
// TODO put job in backlog
log.Printf("git-deploy job already started for %s#%s\n", hook.HTTPSURL, hook.RefName)
return
}
if err := cmd.Start(); nil != err {
log.Printf("git-deploy exec error: %s\n", err)
return
}
jobs[jobID] = &job{
ID: jobID,
Cmd: cmd,
Ref: hook,
}
go func() {
log.Printf("git-deploy job for %s#%s started\n", hook.HTTPSURL, hook.RefName)
cmd.Wait()
delete(jobs, jobID)
log.Printf("git-deploy job for %s#%s finished\n", hook.HTTPSURL, hook.RefName)
}()
}
}()

Loading…
Cancel
Save