Skip to content

Commit

Permalink
chore: create crond
Browse files Browse the repository at this point in the history
  • Loading branch information
darlanalves authored Apr 29, 2024
1 parent 5c79cad commit 2e44fb8
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: CICD
on:
- push

jobs:
release:
uses: cloud-cli/workflows/.github/workflows/npm-build-release.yml@main
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,16 @@
# crond

Crontab-like runner

## Usage

- Create `jobs.json` at either `$HOME/jobs.json` or the current folder
- run `crond` from a shell

## Environment variables

| name | description |
|-|-|
| CRON_LOGS_FOLDER | Path to a folder where logs will be placed per job. Default is `/tmp/cronjobs` |
| CRON_JOBS_FILE | Name of the JSON file where jobs are defined. Default is `jobs.json` |
| DEBUG | Set it to get debug logs from `crond` |
97 changes: 97 additions & 0 deletions index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { CronJob } from "cron";
import { exec as sh } from "node:child_process";
import {
createWriteStream,
existsSync,
mkdirSync,
readFileSync,
statSync,
} from "node:fs";
import { join } from "node:path";

const CWD = process.cwd();
const logsFolder = process.env.CRON_LOGS_FOLDER || "/tmp/cronjobs";
const jobsFileName = process.env.CRON_JOBS_FILE || "jobs.json";

function start() {
mkdirSync(join(logsFolder), { recursive: true });
const debug = !!process.env.DEBUG;
const jobs = loadJobs();

for (const job of jobs) {
debug &&
console.log(`[${job.name}] registered with interval "${job.interval}"`);

new CronJob(
job.interval,
function onTick() {
runJobCommands(job);
},
null,
true
);
}
}

const waitFor = (s) =>
new Promise((resolve, reject) => {
s.on("exit", resolve);
s.on("error", reject);
});

async function runJobCommands(job) {
const file = join(logsFolder, job.name + ".log");
const stats = statSync(file);
const log = createWriteStream(file, { start: stats.size, flags: "r+" });

log.write("Starting " + job.name + "\n");

try {
for (const command of job.commands) {
log.write(`[${new Date().toISOString().slice(0, 19)}] ${command}\n`);

const p = sh(command, {
cwd: job.cwd || CWD,
env: process.env,
});

p.stdout.pipe(log);
p.stderr.pipe(log);

await waitFor(p);
}

log.write("\n[OK]\n");
} catch (error) {
log.write("[ERROR] " + String(error) + "\n");
console.error(error);
} finally {
log.close();
}
}

function loadJobs() {
const jobsFile = [
join(CWD, jobsFileName),
join(process.env.HOME || "", jobsFileName),
].find((f) => existsSync(f));

if (!jobsFile) {
console.error(`No jobs found. Create ${jobsFileName} first!`);
process.exit(1);
}

const jobs = [];

try {
const src = JSON.parse(readFileSync(jobsFile, "utf8"));
jobs.push(src.jobs);
} catch (error) {
console.error(`Failed to read ${jobsFileName}: ${String(error)}!`);
process.exit(1);
}

return jobs;
}

start();
12 changes: 12 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "@cloud-cli/crond",
"version": "0.0.0",
"type": "module",
"main": "./index.mjs",
"bin": {
"crond": "./index.mjs"
},
"dependencies": {
"cron": "^3.1.0"
}
}

0 comments on commit 2e44fb8

Please sign in to comment.