Skip to content

Commit

Permalink
Merge pull request #4 from factorialco/feature/refactor-compile
Browse files Browse the repository at this point in the history
Refactor how Gat compiles templates
  • Loading branch information
fcsonline authored Nov 3, 2023
2 parents 689c1fc + a4475ed commit f3b2c45
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 78 deletions.
5 changes: 2 additions & 3 deletions .github/templates/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const setupNodeStep: UseStep = {
uses: "actions/setup-node@v3",
};

new Workflow("Build")
export default new Workflow("Build")
.on("push", { branches: ["main"] })
.on("pull_request")
.addJob("build", {
Expand All @@ -30,5 +30,4 @@ new Workflow("Build")
{ name: "Check lint problems", run: "npm run lint" },
{ name: "Check format problems", run: "npm run format:check" },
],
})
.compile();
});
3 changes: 3 additions & 0 deletions .github/templates/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Build from "./build";

Build.compile("build.yml");
1 change: 0 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,3 @@ jobs:
run: npm run lint
- name: Check format problems
run: npm run format:check

4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@factorialco/gat",
"version": "1.5.0",
"version": "2.0.0",
"description": "Write your GitHub Actions workflows using TypeScript",
"bin": {
"gat": "dist/cli.js"
Expand Down
2 changes: 1 addition & 1 deletion src/__snapshots__/workflow.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
// Vitest Snapshot v1

exports[`Workflow > allows a job matrix 1`] = `
"# Workflow automatically generated by gat
Expand Down
67 changes: 8 additions & 59 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,83 +4,32 @@ import path from "path";
import { exec } from "child_process";
import { Command } from "commander";
import { promisify } from "util";
import debounce from "lodash/debounce";

const execPromise = promisify(exec);
const writeFilePromise = promisify(fs.writeFile);
const folder = path.join(process.cwd(), ".github", "templates");

const parseFile = async (templateFile: string) => {
// NOTE: can we improve this using ts-node or typescript programatically?
const { stdout } = await execPromise(
`npx ts-node ${
process.env["GAT_BUILD_FLAGS"] ?? "--swc -T"
} ${templateFile}`
);

await writeFilePromise(
path.join(
process.cwd(),
".github",
"workflows",
templateFile.split("/").at(-1)!.replace(".ts", ".yml")
),
stdout
);
};

const cli = new Command();

cli
.version("1.0.0")
.version("2.0.0")
.description("Write your GitHub Actions workflows using TypeScript");

cli
.command("build")
.description("Transpile all Gat templates into GitHub Actions workflows.")
.argument("[file]", "(Optional) A Gat template file")
.action(async (file) => {
.action(async () => {
if (!fs.existsSync(path.join(folder, "..", "workflows"))) {
fs.mkdirSync(path.join(folder, "..", "workflows"));
}

if (file !== undefined) {
await parseFile(file);
} else {
await Promise.all(
fs.readdirSync(folder).map(async (templateFile) => {
if (!templateFile.match(/^shared$/)) {
await parseFile(`${path.join(folder, templateFile)}`);
}
})
);
}
await execPromise(
`npx ts-node ${process.env["GAT_BUILD_FLAGS"] ?? "--swc -T"} ${path.join(
folder,
"index.ts"
)}`
);

process.exit(0);
});

cli
.command("watch")
.description(
"Watch file changes in your Gat templates folder and transpile them automatically."
)
.action(async () => {
const parseWatchedFile = debounce(async (fileName) => {
const start = process.hrtime.bigint();
process.stdout.write(
`😸 Detected change on file ${fileName}. Transpiling... `
);
await parseFile(path.join(folder, fileName.toString()));
console.log(
`Done in ${(
Number(process.hrtime.bigint() - start) / 1_000_000
).toFixed(2)}ms`
);
}, 1000);
console.log(`😼 Watching file changes on ${folder}...`);
fs.watch(folder).on("change", (_eventName, fileName) => {
parseWatchedFile(fileName);
});
});

cli.parse(process.argv);
4 changes: 2 additions & 2 deletions src/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export type EventName =
| "workflow_dispatch"
| "schedule"
| "pull_request_target"
| "repository_dispatch"
| "repository_dispatch";

export type EventOptions<T extends EventName> = T extends "push"
? PushEventOptions
Expand Down Expand Up @@ -60,7 +60,7 @@ interface WorkflowDispatchEventOptions {
type ScheduleEventOptions = Array<{ cron: string }>;

interface RepositoryDispatchEventOptions {
types: string[]
types: string[];
}

export interface Event {
Expand Down
32 changes: 23 additions & 9 deletions src/workflow.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { dump } from "js-yaml";
import kebabCase from "lodash/kebabCase";
import fs from "fs";
import path from "path";
import { promisify } from "util";

import { ConcurrencyGroup, Job, JobOptions, StringWithNoSpaces } from "./job";
import type { Event, EventName, EventOptions } from "./event";
import { BaseStep, Step } from "./step";

const writeFilePromise = promisify(fs.writeFile);

const DEFAULT_RUNNERS = ["ubuntu-22.04"];

interface DefaultOptions {
Expand Down Expand Up @@ -73,7 +78,7 @@ export class Workflow<
return isSelfHosted ? ["self-hosted", runnerName] : runnerName;
}

compile() {
compile(filepath?: string) {
const result = {
name: this.name,
on: Object.fromEntries(
Expand Down Expand Up @@ -136,12 +141,18 @@ export class Workflow<
strategy: matrix
? {
"fail-fast": false,
matrix: typeof matrix === 'string' ? matrix : {
...Object.fromEntries(
matrix.elements.map(({ id, options }) => [id, options])
),
include: matrix.extra,
},
matrix:
typeof matrix === "string"
? matrix
: {
...Object.fromEntries(
matrix.elements.map(({ id, options }) => [
id,
options,
])
),
include: matrix.extra,
},
}
: undefined,
env,
Expand Down Expand Up @@ -187,8 +198,11 @@ export class Workflow<
}
)}`;

console.log(compiled);
if (!filepath) return compiled;

return compiled;
return writeFilePromise(
path.join(process.cwd(), ".github", "workflows", filepath),
compiled
);
}
}

0 comments on commit f3b2c45

Please sign in to comment.