Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ mutation.
When this API is used with a GitHub App token, the resulting commit will be signed and verified by
GitHub on behalf of the application.

*NOTE:* One limitation of creating commits using the GraphQL API is that it does not expose any
mechanism to set or change file modes. It merely takes the file contents, base64 encoded. This means
that if you rely on `commit-headless` to push binary files (or executable scripts), the file in the
resulting commit will not retain that executable bit.

[mutation]: https://docs.github.com/en/graphql/reference/mutations#createcommitonbranch
[action-branch]: https://github.com/DataDog/commit-headless/tree/action

Expand Down
9 changes: 8 additions & 1 deletion action-template/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,14 @@ If your workflow creates multiple commits and you want to push all of them, you
git add bot.txt && git commit -m"bot commit 2"

# List both commit hashes in reverse order, space separated
echo "commits=\"$(git log "${{ github.sha }}".. --format='%H%x00' | tr '\n' ' ')\"" >> $GITHUB_OUTPUT
echo "commits=\"$(git log "${{ github.sha }}".. --format='%H' | tr '\n' ' ')\"" >> $GITHUB_OUTPUT

# If you just have a single commit, you can do something like:
# echo "commit=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
# and then use it in the action via:
# with:
# ...
# commits: ${{ steps.create-commits.outputs.commit }}

- name: Push commits
uses: DataDog/commit-headless@action/v%%VERSION%%
Expand Down
43 changes: 39 additions & 4 deletions action-template/action.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,19 @@ function main() {

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

try {
fs.chmodSync(cmd, 0o755);
} catch (err) {
console.error(`Error making binary executable: ${err.message}`);
}

const env = { ...process.env };
env.HEADLESS_TOKEN = process.env.INPUT_TOKEN;

const command = process.env.INPUT_COMMAND;

if (!["commit", "push"].includes(command)) {
console.error(`Unknown command ${command}. Must be one of "commit" or "push".`);
console.error(`Unknown command '${command}'. Must be one of "commit" or "push".`);
process.exit(1);
}

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

const dryrun = process.env["INPUT_DRY-RUN"] || "false"
if(!["true", "false"].includes(dryrun.toLowerCase())) {
console.error(`Invalid value for dry-run (${dryrun}). Must be one of true or false.`);
process.exit(1);
}

if(dryrun.toLowerCase() === "true") { args.push("--dry-run") }

if (command === "push") {
args.push(...process.env.INPUT_COMMITS.split(/\s+/));
} else {
Expand All @@ -66,6 +80,7 @@ function main() {

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

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

const delim = `delim_${crypto.randomUUID()}`;
fs.appendFileSync(process.env.GITHUB_OUTPUT, `pushed_ref<<${delim}${os.EOL}${out}${os.EOL}${delim}`, { encoding: "utf8" });
process.exit(0);
}
} else {
console.error(`Child process exited uncleanly with signal ${child.signal || "unknown" }`);
if(child.error) {
console.error(` error: ${child.error}`);
}
exitCode = 128;
}

process.exit(exitCode)
if(child.stdout) {
// commit-headless should never print anything to stdout *except* the pushed reference, but just
// in case we'll print whatever happens here
console.log("Child process output:");
console.log(child.stdout.toString().trim());
console.log();
}
process.exit(1)

process.exit(exitCode);

}

if (require.main === module) {
main()
try {
main()
} catch (exc) {
console.error(`Unhandled exception running action, got: ${exc.message}`);
process.exit(1);
}
}
3 changes: 3 additions & 0 deletions action-template/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ inputs:
command:
description: 'Command to run. One of "commit" or "push"'
required: true
dry-run:
description: 'Stop processing just before actually making changes to the remote. Note that the pushed_ref output will be a zeroed commit hash.'
default: false
commits:
description: 'For push, the list of commit hashes to push, oldest first'
files:
Expand Down
10 changes: 5 additions & 5 deletions github.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,12 +251,12 @@ func (c *Client) PushChange(ctx context.Context, headCommit string, change Chang
}

if len(payload.Errors) != 0 {
fmt.Printf("There were %d errors returned when creating the commit.\n", len(payload.Errors))
fmt.Println("Input:")
fmt.Println(string(queryJSON))
for i, e := range payload.Errors {
fmt.Printf("Error %d: %s\n", i+1, e.Message)
log("There were %d errors returned when creating the commit.\n", len(payload.Errors))
for _, e := range payload.Errors {
log(" - %s\n", e.Message)
}

log("\nInput data, for reference: %s", string(queryJSON))
return "", errors.New("graphql response")
}

Expand Down
2 changes: 1 addition & 1 deletion version.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package main

const VERSION = "0.5.0"
const VERSION = "0.5.1"