Skip to content

Commit b51866c

Browse files
feat: Running locally (#20)
* feat: Running locally It can be useful to run a build outside of CI. So, this action can also be installed locally to kick off a CodeBuild project from your git sandbox. * fix test * fixes Remove unneded rev-parse. I can just use the branch name since I make one just for this… Also, comments and re-work the remote search. Since remote is user input this should be a little safer. * Update README.md Co-Authored-By: Matt Bullock <[email protected]> * Update README.md Co-Authored-By: Matt Bullock <[email protected]> * better words for readme * display errors * Update README.md Co-Authored-By: Matt Bullock <[email protected]> Co-authored-by: Matt Bullock <[email protected]>
1 parent e5cd667 commit b51866c

File tree

7 files changed

+541
-119
lines changed

7 files changed

+541
-119
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,28 @@ this will overwrite them.
164164
event-name: ${{ github.event_name }}
165165
```
166166

167+
### Running Locally
168+
169+
It can be useful to run a build outside of CI.
170+
So, this action can also be installed locally
171+
to kick off a CodeBuild project from your git sandbox.
172+
You could push your changes to an open PR,
173+
but if you only want to test one project this may be faster.
174+
In order to use this tool,
175+
you must first `git checkout` the commit that you want to test.
176+
177+
```
178+
npx @aws-actions/codebuild-run-build -p ProjectName -r remoteName
179+
```
180+
181+
This will use whatever commit you have checked out
182+
and push to a temporary branch in the specified remote.
183+
Then kick off the build
184+
and delete the remote branch when complete.
185+
186+
You can also install the project globally or locally
187+
and execute it that way.
188+
167189
## Implementation Notes
168190
169191
### What we did

code-build.js

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,26 @@ const aws = require("aws-sdk");
77
const assert = require("assert");
88

99
module.exports = {
10-
buildProject,
11-
_buildProject,
10+
runBuild,
11+
build,
1212
waitForBuildEndTime,
1313
inputs2Parameters,
14+
githubInputs,
1415
buildSdk,
1516
logName
1617
};
1718

18-
function buildProject() {
19+
function runBuild() {
1920
// get a codeBuild instance from the SDK
2021
const sdk = buildSdk();
2122

2223
// Get input options for startBuild
23-
const params = inputs2Parameters();
24+
const params = inputs2Parameters(githubInputs());
2425

25-
return _buildProject(sdk, params);
26+
return build(sdk, params);
2627
}
2728

28-
async function _buildProject(sdk, params) {
29+
async function build(sdk, params) {
2930
// Start the build
3031
const start = await sdk.codeBuild.startBuild(params).promise();
3132

@@ -67,28 +68,49 @@ async function waitForBuildEndTime(sdk, { id, logs }, nextToken) {
6768
return waitForBuildEndTime(sdk, current, nextForwardToken);
6869
}
6970

70-
function inputs2Parameters() {
71+
function githubInputs() {
7172
const projectName = core.getInput("project-name", { required: true });
72-
73+
const { owner, repo } = github.context.repo;
7374
// The github.context.sha is evaluated on import.
7475
// This makes it hard to test.
7576
// So I use the raw ENV
7677
const sourceVersion = process.env[`GITHUB_SHA`];
77-
const sourceTypeOverride = "GITHUB";
78-
const { owner, repo } = github.context.repo;
79-
const sourceLocationOverride = `https://github.com/${owner}/${repo}.git`;
80-
8178
const buildspecOverride =
8279
core.getInput("buildspec-override", { required: false }) || undefined;
8380

84-
const envVars = core
81+
const envPassthrough = core
8582
.getInput("env-passthrough", { required: false })
8683
.split(",")
84+
.map(i => i.trim())
85+
.filter(i => i !== "");
8786

88-
.map(i => i.trim());
87+
return {
88+
projectName,
89+
owner,
90+
repo,
91+
sourceVersion,
92+
buildspecOverride,
93+
envPassthrough
94+
};
95+
}
96+
97+
function inputs2Parameters(inputs) {
98+
const {
99+
projectName,
100+
owner,
101+
repo,
102+
sourceVersion,
103+
buildspecOverride,
104+
envPassthrough = []
105+
} = inputs;
106+
107+
const sourceTypeOverride = "GITHUB";
108+
const sourceLocationOverride = `https://github.com/${owner}/${repo}.git`;
89109

90110
const environmentVariablesOverride = Object.entries(process.env)
91-
.filter(([key]) => key.startsWith("GITHUB_") || envVars.includes(key))
111+
.filter(
112+
([key]) => key.startsWith("GITHUB_") || envPassthrough.includes(key)
113+
)
92114
.map(([name, value]) => ({ name, value, type: "PLAINTEXT" }));
93115

94116
// The idempotencyToken is intentionally not set.

index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
const core = require("@actions/core");
5-
const { buildProject } = require("./code-build");
5+
const { runBuild } = require("./code-build");
66
const assert = require("assert");
77

88
/* istanbul ignore next */
@@ -14,7 +14,7 @@ module.exports = run;
1414

1515
async function run() {
1616
try {
17-
const build = await buildProject();
17+
const build = await runBuild();
1818
core.setOutput("aws-build-id", build.id);
1919

2020
// Signal the outcome

local.js

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#!/usr/bin/env node
2+
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
const uuid = require("uuid/v4");
6+
const cp = require("child_process");
7+
const cb = require("./code-build");
8+
const assert = require("assert");
9+
const yargs = require("yargs");
10+
11+
const { projectName, buildspecOverride, envPassthrough, remote } = yargs
12+
.option("project-name", {
13+
alias: "p",
14+
describe: "AWS CodeBuild Project Name",
15+
demandOption: true,
16+
type: "string"
17+
})
18+
.option("buildspec-override", {
19+
alias: "b",
20+
describe: "Path to buildspec file",
21+
type: "string"
22+
})
23+
.option("env-passthrough", {
24+
alias: "e",
25+
describe: "List of environment variables to send to CodeBuild",
26+
type: "array"
27+
})
28+
.option("remote", {
29+
alias: "r",
30+
describe: "remote name to publish to",
31+
default: "origin",
32+
type: "string"
33+
}).argv;
34+
35+
const BRANCH_NAME = uuid();
36+
37+
const params = cb.inputs2Parameters({
38+
projectName,
39+
...githubInfo(remote),
40+
sourceVersion: BRANCH_NAME,
41+
buildspecOverride,
42+
envPassthrough
43+
});
44+
45+
const sdk = cb.buildSdk();
46+
47+
pushBranch(remote, BRANCH_NAME);
48+
49+
cb.build(sdk, params)
50+
.then(() => deleteBranch(remote, BRANCH_NAME))
51+
.catch(err => {
52+
deleteBranch(remote, BRANCH_NAME);
53+
throw err;
54+
});
55+
56+
function pushBranch(remote, branchName) {
57+
cp.execSync(`git push ${remote} HEAD:${branchName}`);
58+
}
59+
60+
function deleteBranch(remote, branchName) {
61+
cp.execSync(`git push ${remote} :${branchName}`);
62+
}
63+
64+
function githubInfo(remote) {
65+
const gitHubSSH = "[email protected]:";
66+
/* Expecting to match something like:
67+
* 'fork [email protected]:seebees/aws-codebuild-run-build.git (push)'
68+
* Which is the output of `git remote -v`
69+
*/
70+
const remoteMatch = /^fork.*\(push\)$/;
71+
/* Not doing a grep because then I have to pass user input to the shell.
72+
* This way I don't have to worry about sanitizing and injection and all that jazz.
73+
* Further, when I _do_ pass the remote into the shell to push to it,
74+
* given that I find it in the remote list,
75+
* I feel confident that there are no shinanaigans.
76+
*/
77+
const [gitRemote] = cp
78+
.execSync("git remote -v")
79+
.toString()
80+
.split("\n")
81+
.filter(line => line.trim().match(remoteMatch));
82+
assert(gitRemote, `No remote found named ${remote}`);
83+
const [, url] = gitRemote.split(/[\t ]/);
84+
assert(url.startsWith(gitHubSSH), `Unsupported format: ${url}`);
85+
const [owner, repo] = url.slice(gitHubSSH.length, -4).split("/");
86+
return { owner, repo };
87+
}

0 commit comments

Comments
 (0)