diff --git a/.gitignore b/.gitignore index d3beee5..d1eec3e 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,4 @@ _testmain.go *.exe *.test *.prof - +ironsmith diff --git a/README.md b/README.md index d14b043..c7aca22 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Ironsmith is a simple continuous integration (build - > test -> release) tool. You'll setup a project which will need the following information: -1. Script to pull from the repository +1. Script to fetch from the repository * Most of the time this will be a git clone call, but it can be a bash script calling an FTP or whatever * Choose between polling for changes, or triggered builds * Triggered builds will be triggered off of a web hook POST call @@ -37,3 +37,6 @@ Ironsmith will take the information for the defined project above and do the fol 8. Insert the release information and the complete log into the Bolt DB file This tool will (originally at least) have no authentication. I plan on adding it later. + + +To add a new project, add a .json file to the projects/enabled folder. Look at the template.project.json file in the projects folder for an example. diff --git a/main.go b/main.go new file mode 100644 index 0000000..242cc05 --- /dev/null +++ b/main.go @@ -0,0 +1,57 @@ +package main + +import ( + "log" + "os" + "path/filepath" + + "git.townsourced.com/config" +) + +//settings +var ( + projectDir = "./projects" // /etc/ + dataDir = "./data" + address = "http://localhost:8026" + certFile = "" + keyFile = "" +) + +func main() { + settingPaths := config.StandardFileLocations("ironsmith/settings.json") + log.Println("IronSmith will use settings files in the following locations (in order of priority):") + for i := range settingPaths { + log.Println("\t", settingPaths[i]) + } + cfg, err := config.LoadOrCreate(settingPaths...) + if err != nil { + log.Fatalf("Error loading or creating IronSmith settings file: %s", err) + } + + log.Printf("IronSmith is currently using the file %s for settings.\n", cfg.FileName()) + + projectDir = cfg.String("projectDir", projectDir) + dataDir = cfg.String("dataDir", dataDir) + address = cfg.String("address", address) + certFile = cfg.String("certFile", certFile) + keyFile = cfg.String("keyFile", keyFile) + + //prep dirs + err = os.MkdirAll(filepath.Join(projectDir, enabledProjectDir), os.ModeDir) + if err != nil { + log.Fatalf("Error Creating project directory at %s: %s", projectDir, err) + } + + err = os.MkdirAll(dataDir, os.ModeDir) + if err != nil { + log.Fatalf("Error Creating project data directory at %s: %s", dataDir, err) + } + + err = prepTemplateProject() + if err != nil { + log.Fatalf("Error Creating project template file: %s", err) + } + + //load projects + //start server +} diff --git a/project.go b/project.go new file mode 100644 index 0000000..de9585c --- /dev/null +++ b/project.go @@ -0,0 +1,71 @@ +package main + +import ( + "encoding/json" + "os" + "path/filepath" +) + +const enabledProjectDir = "enabled" + +// Project is an ironsmith project that contains how to fetch, build, test, and release a project +type Project struct { + Name string `json:"name"` // name of the project + + Fetch string `json:"fetch"` //Script to fetch the latest project code into the current directory + Build string `json:"build"` //Script to build the latest project code + Test string `json:"test"` //Script to test the latest project code + Release string `json:"release"` //Script to build the release of latest project code + + Version string `json:"version"` //Script to generate the version num of the current build, should be indempotent + + ReleaseFile string `json:"releaseFile"` + PollInterval string `json:"pollInterval"` // if not poll interval is specified, this project is trigger only + TriggerSecret string `json:"triggerSecret"` //secret to be included with a trigger call +} + +const projectTemplateFilename = "template.project.json" + +var projectTemplate = &Project{ + Name: "Template Project", + Fetch: "git clone root@git.townsourced.com:tshannon/ironsmith.git .", + Build: "sh ./ironsmith/build.sh", + Test: "sh ./ironsmith/test.sh", + Release: "sh ./ironsmith/release.sh", + Version: "git describe --tags --long", + + ReleaseFile: `json:"./ironsmith/release.tar.gz"`, + PollInterval: "15m", +} + +func prepTemplateProject() error { + filename := filepath.Join(projectDir, projectTemplateFilename) + _, err := os.Stat(filename) + if os.IsNotExist(err) { + f, err := os.Create(filename) + defer func() { + if cerr := f.Close(); cerr != nil && err == nil { + err = cerr + } + }() + + if err != nil { + return err + } + + data, err := json.MarshalIndent(projectTemplate, "", " ") + if err != nil { + return err + } + + _, err = f.Write(data) + if err != nil { + return err + } + + } else if err != nil { + return err + } + + return nil +}