With listr
one can define a set of tasks to run:
const execa = require("execa");
const Listr = require("listr");
const tasks = new Listr([
{
title: "Git",
task: () => {
return new Listr([
{
title: "Checking git status",
task: () => execa.stdout("git', ['status', '--porcelain"]).then(result => {
if (result !== "") {
throw new Error("Unclean working tree. Commit or stash changes first.");
}
})
},
{
title: "Checking remote history",
task: () => execa.stdout("git", ["rev-list", "--count", "--left-only", "@{u}...HEAD"]).then(result => {
if (result !== "0") {
throw new Error("Remote history differ. Please pull changes.");
}
})
}
], {concurrent: true});
}
},
{
title: "Install package dependencies",
task: () => execa("npm", ["install"])
},
{
title: "Run tests",
task: () => execa("npm", ["test"])
},
{
title: "Publish package",
task: () => execa("npm", ["publish"])
}
]);
tasks.run().catch(err => {
console.error(err);
});
It’s also possible to dynamically skip a task in the series, and to run tasks concurrently.
A standalone binary to pass in a .json
file with tasks would nicely compliment this.