Skip to content

Commit 82c1bbb

Browse files
authored
fix(action): better handle errors and output in process invoke (#26)
* chore(action): Clean up the README examples a bit * fix(action): handle errors and outputs in the action js shim * fix: write graphql call errors to stderr instead of stdout * feat(action): add support for dry-run / --dry-run
1 parent 6cb6ab6 commit 82c1bbb

File tree

6 files changed

+61
-11
lines changed

6 files changed

+61
-11
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ mutation.
1212
When this API is used with a GitHub App token, the resulting commit will be signed and verified by
1313
GitHub on behalf of the application.
1414

15+
*NOTE:* One limitation of creating commits using the GraphQL API is that it does not expose any
16+
mechanism to set or change file modes. It merely takes the file contents, base64 encoded. This means
17+
that if you rely on `commit-headless` to push binary files (or executable scripts), the file in the
18+
resulting commit will not retain that executable bit.
19+
1520
[mutation]: https://docs.github.com/en/graphql/reference/mutations#createcommitonbranch
1621
[action-branch]: https://github.com/DataDog/commit-headless/tree/action
1722

action-template/README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,14 @@ If your workflow creates multiple commits and you want to push all of them, you
2727
git add bot.txt && git commit -m"bot commit 2"
2828
2929
# List both commit hashes in reverse order, space separated
30-
echo "commits=\"$(git log "${{ github.sha }}".. --format='%H%x00' | tr '\n' ' ')\"" >> $GITHUB_OUTPUT
30+
echo "commits=\"$(git log "${{ github.sha }}".. --format='%H' | tr '\n' ' ')\"" >> $GITHUB_OUTPUT
31+
32+
# If you just have a single commit, you can do something like:
33+
# echo "commit=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
34+
# and then use it in the action via:
35+
# with:
36+
# ...
37+
# commits: ${{ steps.create-commits.outputs.commit }}
3138
3239
- name: Push commits
3340
uses: DataDog/commit-headless@action/v%%VERSION%%

action-template/action.js

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,19 @@ function main() {
2424

2525
const cmd = `${__dirname}/${binary}`
2626

27+
try {
28+
fs.chmodSync(cmd, 0o755);
29+
} catch (err) {
30+
console.error(`Error making binary executable: ${err.message}`);
31+
}
32+
2733
const env = { ...process.env };
2834
env.HEADLESS_TOKEN = process.env.INPUT_TOKEN;
2935

3036
const command = process.env.INPUT_COMMAND;
3137

3238
if (!["commit", "push"].includes(command)) {
33-
console.error(`Unknown command ${command}. Must be one of "commit" or "push".`);
39+
console.error(`Unknown command '${command}'. Must be one of "commit" or "push".`);
3440
process.exit(1);
3541
}
3642

@@ -45,6 +51,14 @@ function main() {
4551
args.push("--branch-from", branchFrom);
4652
}
4753

54+
const dryrun = process.env["INPUT_DRY-RUN"] || "false"
55+
if(!["true", "false"].includes(dryrun.toLowerCase())) {
56+
console.error(`Invalid value for dry-run (${dryrun}). Must be one of true or false.`);
57+
process.exit(1);
58+
}
59+
60+
if(dryrun.toLowerCase() === "true") { args.push("--dry-run") }
61+
4862
if (command === "push") {
4963
args.push(...process.env.INPUT_COMMITS.split(/\s+/));
5064
} else {
@@ -66,6 +80,7 @@ function main() {
6680

6781
const child = childProcess.spawnSync(cmd, args, {
6882
env: env,
83+
// ignore stdin, capture stdout, stream stderr to the parent
6984
stdio: ['ignore', 'pipe', 'inherit'],
7085
})
7186

@@ -77,13 +92,33 @@ function main() {
7792

7893
const delim = `delim_${crypto.randomUUID()}`;
7994
fs.appendFileSync(process.env.GITHUB_OUTPUT, `pushed_ref<<${delim}${os.EOL}${out}${os.EOL}${delim}`, { encoding: "utf8" });
95+
process.exit(0);
96+
}
97+
} else {
98+
console.error(`Child process exited uncleanly with signal ${child.signal || "unknown" }`);
99+
if(child.error) {
100+
console.error(` error: ${child.error}`);
80101
}
102+
exitCode = 128;
103+
}
81104

82-
process.exit(exitCode)
105+
if(child.stdout) {
106+
// commit-headless should never print anything to stdout *except* the pushed reference, but just
107+
// in case we'll print whatever happens here
108+
console.log("Child process output:");
109+
console.log(child.stdout.toString().trim());
110+
console.log();
83111
}
84-
process.exit(1)
112+
113+
process.exit(exitCode);
114+
85115
}
86116

87117
if (require.main === module) {
88-
main()
118+
try {
119+
main()
120+
} catch (exc) {
121+
console.error(`Unhandled exception running action, got: ${exc.message}`);
122+
process.exit(1);
123+
}
89124
}

action-template/action.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ inputs:
2424
command:
2525
description: 'Command to run. One of "commit" or "push"'
2626
required: true
27+
dry-run:
28+
description: 'Stop processing just before actually making changes to the remote. Note that the pushed_ref output will be a zeroed commit hash.'
29+
default: false
2730
commits:
2831
description: 'For push, the list of commit hashes to push, oldest first'
2932
files:

github.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,12 @@ func (c *Client) PushChange(ctx context.Context, headCommit string, change Chang
251251
}
252252

253253
if len(payload.Errors) != 0 {
254-
fmt.Printf("There were %d errors returned when creating the commit.\n", len(payload.Errors))
255-
fmt.Println("Input:")
256-
fmt.Println(string(queryJSON))
257-
for i, e := range payload.Errors {
258-
fmt.Printf("Error %d: %s\n", i+1, e.Message)
254+
log("There were %d errors returned when creating the commit.\n", len(payload.Errors))
255+
for _, e := range payload.Errors {
256+
log(" - %s\n", e.Message)
259257
}
258+
259+
log("\nInput data, for reference: %s", string(queryJSON))
260260
return "", errors.New("graphql response")
261261
}
262262

version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
package main
22

3-
const VERSION = "0.5.0"
3+
const VERSION = "0.5.1"

0 commit comments

Comments
 (0)