Skip to content

Commit

Permalink
feat(*): enable passing brigade.json via brig run (#1017)
Browse files Browse the repository at this point in the history
* feat(*): enable passing brigade.json via brig run

Signed-off-by: Vaughn Dice <vadice@microsoft.com>
  • Loading branch information
vdice committed Nov 14, 2019
1 parent 7768af7 commit 33c888d
Show file tree
Hide file tree
Showing 12 changed files with 184 additions and 46 deletions.
3 changes: 2 additions & 1 deletion brig/cmd/brig/commands/build_list_test.go
Expand Up @@ -19,7 +19,7 @@ const (
)

type DefaultBuildData struct {
LogLevel, Event, Commit, Ref string
LogLevel, Event, Commit, Config, Ref string
}

var (
Expand All @@ -38,6 +38,7 @@ var (
LogLevel: "log",
Event: "exec",
Commit: "abc1234",
Config: "brigade.json",
Ref: "master",
}
)
Expand Down
10 changes: 10 additions & 0 deletions brig/cmd/brig/commands/rerun.go
Expand Up @@ -29,6 +29,7 @@ var (
rerunFile string
rerunEvent string
rerunPayload string
rerunConfigFile string
rerunCommitish string
rerunRef string
rerunLogLevel string
Expand All @@ -41,6 +42,7 @@ func init() {
rerun.Flags().StringVarP(&rerunFile, "file", "f", "", "The JavaScript file to execute")
rerun.Flags().StringVarP(&rerunEvent, "event", "e", "", "The name of the event to fire")
rerun.Flags().StringVarP(&rerunPayload, "payload", "p", "", "The path to a payload file")
rerun.Flags().StringVar(&rerunConfigFile, "config", "", "The brigade.json config file")
rerun.Flags().StringVarP(&rerunCommitish, "commit", "c", "", "A VCS (git) commit")
rerun.Flags().StringVarP(&rerunRef, "ref", "r", "", "A VCS (git) version, tag, or branch")
rerun.Flags().BoolVar(&rerunNoProgress, "no-progress", runNoProgress, "Disable progress meter")
Expand Down Expand Up @@ -120,6 +122,14 @@ func getUpdatedBuild(r *script.Runner, bid string) (*brigade.Build, error) {
build.Script = data
}

if rerunConfigFile != "" {
config, err := ioutil.ReadFile(rerunConfigFile)
if err != nil {
return build, err
}
build.Config = config
}

if len(rerunPayload) > 0 {
var err error
if build.Payload, err = ioutil.ReadFile(rerunPayload); err != nil {
Expand Down
3 changes: 3 additions & 0 deletions brig/cmd/brig/commands/rerun_test.go
Expand Up @@ -77,6 +77,7 @@ func TestRerun_getUpdatedBuild(t *testing.T) {
Name string
LogLevel string
Type string
Config string
Commit string
Ref string
}
Expand All @@ -87,13 +88,15 @@ func TestRerun_getUpdatedBuild(t *testing.T) {
LogLevel: defaultStubBuildData.LogLevel,
Type: defaultStubBuildData.Event,
Commit: defaultStubBuildData.Commit,
Config: defaultStubBuildData.Config,
Ref: defaultStubBuildData.Ref,
},
{
Name: "Overrides",
LogLevel: "warn",
Type: "different-event",
Commit: "new-commit",
Config: "new-config",
Ref: "new-ref",
},
}
Expand Down
34 changes: 21 additions & 13 deletions brig/cmd/brig/commands/run.go
Expand Up @@ -14,6 +14,7 @@ import (

var (
runFile string
runConfigFile string
runEvent string
runPayload string
runCommitish string
Expand Down Expand Up @@ -54,6 +55,7 @@ func init() {
run.Flags().StringVarP(&runFile, "file", "f", "", "The JavaScript file to execute")
run.Flags().StringVarP(&runEvent, "event", "e", "exec", "The name of the event to fire")
run.Flags().StringVarP(&runPayload, "payload", "p", "", "The path to a payload file")
run.Flags().StringVar(&runConfigFile, "config", "", "The brigade.json config file")
run.Flags().StringVarP(&runCommitish, "commit", "c", "", "A VCS (git) commit")
run.Flags().StringVarP(&runRef, "ref", "r", defaultRef, "A VCS (git) version, tag, or branch")
run.Flags().BoolVar(&runNoProgress, "no-progress", false, "Disable progress meter")
Expand All @@ -74,20 +76,19 @@ var run = &cobra.Command{
}
proj := args[0]

var scr []byte
if len(runFile) > 0 {
var err error
if scr, err = ioutil.ReadFile(runFile); err != nil {
return err
}
scr, err := readFileParam(runFile)
if err != nil {
return err
}

config, err := readFileParam(runConfigFile)
if err != nil {
return err
}

var payload []byte
if len(runPayload) > 0 {
var err error
if payload, err = ioutil.ReadFile(runPayload); err != nil {
return err
}
payload, err := readFileParam(runPayload)
if err != nil {
return err
}

var destination io.Writer = os.Stdout
Expand All @@ -111,7 +112,7 @@ var run = &cobra.Command{
runner.Background = runBackground
runner.Verbose = globalVerbose

err = runner.SendScript(proj, scr, runEvent, runCommitish, runRef, payload, runLogLevel)
err = runner.SendScript(proj, scr, config, runEvent, runCommitish, runRef, payload, runLogLevel)
if err == nil {
return nil
}
Expand All @@ -128,3 +129,10 @@ var run = &cobra.Command{
return err
},
}

func readFileParam(path string) ([]byte, error) {
if len(path) > 0 {
return ioutil.ReadFile(path)
}
return []byte{}, nil
}
38 changes: 33 additions & 5 deletions brigade-worker/prestart.js
Expand Up @@ -2,19 +2,44 @@ const process = require("process")
const fs = require("fs")
const { execFileSync } = require("child_process")

//checked out in repo
const depsFile = "/vcs/brigade.json"
const configFile = "/brigade.json";
const mountedConfigFile = "/etc/brigade/config";
const vcsConfigFile = "/vcs/brigade.json";

// Config file locations in order of precedence.
const configFiles = [
// data mounted from event secret (e.g. brig run)
mountedConfigFile,

// checked out in repo
vcsConfigFile,
];

function createConfig() {
for (let src of configFiles) {
if (fs.existsSync(src) && fs.readFileSync(src, "utf8") != "") {
// Node's require will complain/fail if the file does not have a .json/.js extension
// Here we create the appropriately named file using the contents from src
fs.writeFileSync(configFile, fs.readFileSync(src, "utf8"));
return;
}
}
}

if (require.main === module) {
addDeps()
}

function addDeps() {
if (!fs.existsSync(depsFile)) {
createConfig();
if (!fs.existsSync(configFile)) {
console.log("prestart: no dependencies file found")
return
}
const deps = require(depsFile).dependencies || {}

// Parse the config file
// Currently, we only look for dependencies
const deps = require(configFile).dependencies || {}

const packages = buildPackageList(deps)
if (packages.length == 0) {
Expand Down Expand Up @@ -48,7 +73,10 @@ function addYarn(packages) {
}

module.exports = {
depsFile,
configFile,
mountedConfigFile,
vcsConfigFile,
createConfig,
addDeps,
buildPackageList,
addYarn,
Expand Down
110 changes: 91 additions & 19 deletions brigade-worker/test/prestart.ts
Expand Up @@ -77,18 +77,83 @@ describe("prestart", function() {
});
});

describe("createConfig", function () {
let
existsSync: sinon.SinonStub,
readFileSync: sinon.SinonStub,
writeFileSync: sinon.SinonStub,
exit: sinon.SinonStub;

beforeEach(function() {
existsSync = sinon.stub();
readFileSync = sinon.stub();
readFileSync.callsFake(() => "{}");
writeFileSync = sinon.stub();

mock("fs", { existsSync, readFileSync, writeFileSync })

prestart = mock.reRequire("../prestart");
});

afterEach(function() {
mock.stopAll();
});

it("no brigade.json", function() {
existsSync.callsFake(() => false);

prestart.createConfig();

sinon.assert.calledTwice(existsSync);
sinon.assert.calledWith(existsSync.firstCall, prestart.mountedConfigFile);
sinon.assert.calledWith(existsSync.secondCall, prestart.vcsConfigFile);
sinon.assert.notCalled(writeFileSync);
});

it("config exists via mounted file", function() {
existsSync.callsFake((...args) => {
return args[0] === prestart.mountedConfigFile;
});

prestart.createConfig();

sinon.assert.calledOnce(existsSync);
sinon.assert.calledWith(existsSync.firstCall, prestart.mountedConfigFile);
sinon.assert.called(writeFileSync);
sinon.assert.calledWithExactly(writeFileSync, prestart.configFile, "{}")
});

it("no brigade.json mounted, but exists in vcs", function() {
existsSync.callsFake((...args) => {
return args[0] === prestart.vcsConfigFile;
});

prestart.createConfig();

sinon.assert.calledTwice(existsSync);
sinon.assert.calledWith(existsSync.firstCall, prestart.mountedConfigFile);
sinon.assert.calledWith(existsSync.secondCall, prestart.vcsConfigFile);
sinon.assert.called(writeFileSync);
sinon.assert.calledWithExactly(writeFileSync, prestart.configFile, "{}")
});
});

describe("addDeps", function () {
let
execFileSync: sinon.SinonStub,
existsSync: sinon.SinonStub,
readFileSync: sinon.SinonStub,
writeFileSync: sinon.SinonStub,
exit: sinon.SinonStub;

beforeEach(function() {
execFileSync = sinon.stub();
mock("child_process", { execFileSync });

existsSync = sinon.stub();
mock("fs", { existsSync })
readFileSync = sinon.stub();
writeFileSync = sinon.stub();
mock("fs", { existsSync, readFileSync, writeFileSync })

exit = sinon.stub();
mock("process", { env: {}, exit });
Expand All @@ -104,43 +169,47 @@ describe("prestart", function() {
(console as any).error.restore();
});

it("no brigade.json", function() {
it("no config file exists", function() {
existsSync.callsFake(() => false);

prestart.addDeps();

sinon.assert.calledOnce(existsSync);
sinon.assert.calledWithExactly(existsSync, prestart.depsFile);
sinon.assert.calledThrice(existsSync);
sinon.assert.calledWith(existsSync.firstCall, prestart.mountedConfigFile);
sinon.assert.calledWith(existsSync.secondCall, prestart.vcsConfigFile);
sinon.assert.calledWith(existsSync.thirdCall, prestart.configFile);
sinon.assert.notCalled(execFileSync);
sinon.assert.notCalled(exit);
});

it("no dependencies object", function() {
mock(prestart.depsFile, {});
mock(prestart.configFile, {});
existsSync.callsFake(() => true);

prestart.addDeps();

sinon.assert.calledOnce(existsSync);
sinon.assert.calledWithExactly(existsSync, prestart.depsFile);
sinon.assert.calledTwice(existsSync);
sinon.assert.calledWith(existsSync.firstCall, prestart.mountedConfigFile);
sinon.assert.calledWith(existsSync.secondCall, prestart.configFile);
sinon.assert.notCalled(execFileSync);
sinon.assert.notCalled(exit);
});

it("empty dependencies", function() {
mock(prestart.depsFile, { dependencies: {}})
mock(prestart.configFile, { dependencies: {}})
existsSync.callsFake(() => true);

prestart.addDeps();

sinon.assert.calledOnce(existsSync);
sinon.assert.calledWithExactly(existsSync, prestart.depsFile);
sinon.assert.calledTwice(existsSync);
sinon.assert.calledWith(existsSync.firstCall, prestart.mountedConfigFile);
sinon.assert.calledWith(existsSync.secondCall, prestart.configFile);
sinon.assert.notCalled(execFileSync);
sinon.assert.notCalled(exit);
});

it("one dependency", function() {
mock(prestart.depsFile, {
mock(prestart.configFile, {
dependencies: {
"is-thirteen": "2.0.0",
},
Expand All @@ -149,16 +218,17 @@ describe("prestart", function() {

prestart.addDeps();

sinon.assert.calledOnce(existsSync);
sinon.assert.calledWithExactly(existsSync, prestart.depsFile);
sinon.assert.calledTwice(existsSync);
sinon.assert.calledWith(existsSync.firstCall, prestart.mountedConfigFile);
sinon.assert.calledWith(existsSync.secondCall, prestart.configFile);
sinon.assert.calledOnce(execFileSync);
sinon.assert.calledWithExactly(
execFileSync, "yarn", ["add", "is-thirteen@2.0.0"]);
sinon.assert.notCalled(exit);
})

it("two dependencies", function() {
mock(prestart.depsFile, {
mock(prestart.configFile, {
dependencies: {
"is-thirteen": "2.0.0",
"lodash": "4.0.0",
Expand All @@ -168,16 +238,17 @@ describe("prestart", function() {

prestart.addDeps();

sinon.assert.calledOnce(existsSync);
sinon.assert.calledWithExactly(existsSync, prestart.depsFile);
sinon.assert.calledTwice(existsSync);
sinon.assert.calledWith(existsSync.firstCall, prestart.mountedConfigFile);
sinon.assert.calledWith(existsSync.secondCall, prestart.configFile);
sinon.assert.calledOnce(execFileSync);
sinon.assert.calledWithExactly(
execFileSync, "yarn", ["add", "is-thirteen@2.0.0", "lodash@4.0.0"]);
sinon.assert.notCalled(exit);
});

it("yarn error", function() {
mock(prestart.depsFile, {
mock(prestart.configFile, {
dependencies: {
"is-thirteen": "2.0.0",
},
Expand All @@ -191,8 +262,9 @@ describe("prestart", function() {

prestart.addDeps();

sinon.assert.calledOnce(existsSync);
sinon.assert.calledWithExactly(existsSync, prestart.depsFile);
sinon.assert.calledTwice(existsSync);
sinon.assert.calledWith(existsSync.firstCall, prestart.mountedConfigFile);
sinon.assert.calledWith(existsSync.secondCall, prestart.configFile);
sinon.assert.calledOnce(execFileSync);
sinon.assert.calledWithExactly(execFileSync, "yarn", ["add", "is-thirteen@2.0.0"]);
sinon.assert.calledOnce(exit);
Expand Down

0 comments on commit 33c888d

Please sign in to comment.