I'm using the action toolkit to re-write an action of mine, and I'm having a hard time getting it to complete the processes within it. The action essentially deploys to a GitHub pages branch, and requires running a number of git commands. For this I've used @actions/exec and wrapped it in a function so I can more easily set the cwd. You can see an example of this below:
import { exec } from "@actions/exec";
export async function execute(cmd: string, cwd: string): Promise<String> {
return new Promise((resolve, reject) => {
exec(cmd, [], {
cwd,
listeners: {
stdout: (data: Buffer) => {
resolve(data.toString().trim());
},
stderr: (data: Buffer) => {
reject(data.toString().trim());
}
}
});
});
}
The problem I'm having is that my function doesn't seem to finish executing the commands before exiting. You can see a log here (it's the Build & Deploy step).
it seems to only get to the second command and then passes and I'm not entirely sure why. You can see the code for this here: https://github.com/JamesIves/github-pages-deploy-action/blob/rewrite/src/git.ts#L26-L28
The entrypoint which runs this looks like this, and you'll see in the logs that the Deployment Successful message never shows.
import * as core from "@actions/core";
import { init, deploy } from "./git";
async function run() {
try {
// Initializes the action.
const action = await init();
await deploy(action);
} catch (error) {
core.setFailed(error.message);
} finally {
console.log("Deployment Successful");
}
}
run();
Is there an issue with how I'm awaiting these commands? It feels like I'm making a rookie mistake.
Hey @JamesIves,
I think you need to await the exec inside your execute function, since it's async.
Possibly something like:
export async function execute(cmd: string, cwd: string): Promise<String> {
return new Promise(async (resolve, reject) => {
await exec(cmd, [], {
cwd,
listeners: {
stdout: (data: Buffer) => {
resolve(data.toString().trim());
},
stderr: (data: Buffer) => {
reject(data.toString().trim());
}
}
});
});
}
or
export async function execute(cmd: string, cwd: string): Promise<String> {
let myOutput = '';
let myError = '';
await exec(cmd, [], {
cwd,
listeners: {
stdout: (data: Buffer) => {
myOutput += data.toString().trim();
},
stderr: (data: Buffer) => {
myError += data.toString().trim();
}
}
});
if (myError) {
throw new Error(myError);
}
return myOutput;
}
Based on https://github.com/actions/toolkit/tree/master/packages/exec#outputoptions
Let me know if that helps!
Also, why are you wrapping exec with your own execute function? simply await exec.
I think Josh answered.
Yes, sorry I forgot to reply. @joshmgross solution worked for me.
Thanks for confirming.