Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@factorialco/gat

Package Overview
Dependencies
Maintainers
3
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@factorialco/gat - npm Package Compare versions

Comparing version 2.2.0 to 2.3.0

39

dist/cli.js
#!/usr/bin/env node
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const child_process_1 = require("child_process");
const commander_1 = require("commander");
const util_1 = require("util");
const execPromise = (0, util_1.promisify)(child_process_1.exec);
const folder = path_1.default.join(process.cwd(), ".github", "templates");
const cli = new commander_1.Command();
import fs from "fs";
import path from "path";
import { exec } from "child_process";
import { Command } from "commander";
import { promisify } from "util";
const execPromise = promisify(exec);
const folder = path.join(process.cwd(), ".github", "templates");
const cli = new Command();
cli

@@ -21,9 +25,10 @@ .version("2.0.0")

.description("Transpile all Gat templates into GitHub Actions workflows.")
.action(async () => {
if (!fs_1.default.existsSync(path_1.default.join(folder, "..", "workflows"))) {
fs_1.default.mkdirSync(path_1.default.join(folder, "..", "workflows"));
.action(() => __awaiter(void 0, void 0, void 0, function* () {
var _a;
if (!fs.existsSync(path.join(folder, "..", "workflows"))) {
fs.mkdirSync(path.join(folder, "..", "workflows"));
}
await execPromise(`npx ts-node ${process.env["GAT_BUILD_FLAGS"] ?? "--swc -T"} ${path_1.default.join(folder, "index.ts")}`);
yield execPromise(`npx ts-node ${(_a = process.env["GAT_BUILD_FLAGS"]) !== null && _a !== void 0 ? _a : "--swc -T"} ${path.join(folder, "index.ts")}`);
process.exit(0);
});
}));
cli.parse(process.argv);

@@ -1,2 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
export {};

@@ -1,5 +0,2 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Workflow = void 0;
const workflow_1 = require("./workflow");
Object.defineProperty(exports, "Workflow", { enumerable: true, get: function () { return workflow_1.Workflow; } });
import { Workflow } from "./workflow";
export { Workflow, };

@@ -1,2 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
export {};

@@ -1,7 +0,3 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isUseStep = void 0;
const isUseStep = (step) => {
export const isUseStep = (step) => {
return step.uses !== undefined;
};
exports.isUseStep = isUseStep;

@@ -1,19 +0,33 @@

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Workflow = void 0;
const js_yaml_1 = require("js-yaml");
const kebabCase_1 = __importDefault(require("lodash/kebabCase"));
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const util_1 = require("util");
const node_fetch_1 = __importDefault(require("node-fetch"));
const step_1 = require("./step");
const writeFilePromise = (0, util_1.promisify)(fs_1.default.writeFile);
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import { dump } from "js-yaml";
import kebabCase from "lodash/kebabCase";
import fs from "fs";
import path from "path";
import { promisify } from "util";
import fetch from 'node-fetch';
import { isUseStep } from "./step";
const writeFilePromise = promisify(fs.writeFile);
const DEFAULT_RUNNERS = ["ubuntu-22.04"];
const chainAttackCache = {};
const supplyChainAttack = async (step) => {
if (!(0, step_1.isUseStep)(step))
const supplyChainAttack = (step) => __awaiter(void 0, void 0, void 0, function* () {
if (!isUseStep(step))
return;

@@ -29,4 +43,4 @@ const uses = step.uses;

const { repository, version } = match.groups;
const response = await (0, node_fetch_1.default)(`https://api.github.com/repos/${repository}/tags`);
const tags = (await response.json());
const response = yield fetch(`https://api.github.com/repos/${repository}/tags`);
const tags = (yield response.json());
const tag = tags.find((tag) => tag.name === version);

@@ -38,4 +52,4 @@ if (!tag)

return result;
};
class Workflow {
});
export class Workflow {
constructor(name) {

@@ -72,94 +86,86 @@ this.name = name;

assignRunner(runsOn) {
const runnerName = runsOn ?? this.defaultRunner();
const runnerName = runsOn !== null && runsOn !== void 0 ? runsOn : this.defaultRunner();
const isSelfHosted = !DEFAULT_RUNNERS.includes(runnerName);
return isSelfHosted ? ["self-hosted", runnerName] : runnerName;
}
async compile(filepath) {
const result = {
name: this.name,
on: Object.fromEntries(this.events.map(({ name, options }) => [
name,
options ? options : null,
])),
concurrency: this.concurrencyGroup
? {
group: this.concurrencyGroup.groupSuffix,
"cancel-in-progress": this.concurrencyGroup.cancelPrevious,
}
: undefined,
defaults: this.defaultOptions
? {
run: {
"working-directory": this.defaultOptions.workingDirectory,
},
}
: undefined,
env: this.env.length > 0
? Object.fromEntries(this.env.map(({ name, value }) => [name, value]))
: undefined,
jobs: Object.fromEntries(await Promise.all(this.jobs.map(async ({ name, options: { prettyName, permissions, ifExpression, runsOn, matrix, env, steps, dependsOn, services, timeout, concurrency, outputs, workingDirectory, }, }) => [
name,
{
name: prettyName,
permissions,
if: ifExpression,
"runs-on": this.assignRunner(runsOn),
"timeout-minutes": timeout ?? 15,
needs: dependsOn,
services,
concurrency: concurrency
? {
group: `${(0, kebabCase_1.default)(this.name)}-${name}-${concurrency.groupSuffix}`,
"cancel-in-progress": concurrency.cancelPrevious,
}
: undefined,
strategy: matrix
? {
"fail-fast": false,
matrix: typeof matrix === "string"
? matrix
: {
...Object.fromEntries(matrix.elements.map(({ id, options }) => [
id,
options,
])),
include: matrix.extra,
},
}
: undefined,
env,
defaults: workingDirectory
? {
run: {
"working-directory": workingDirectory,
},
}
: undefined,
steps: await Promise.all(steps.map(async (step) => {
const { id, name, ifExpression, workingDirectory, continueOnError, timeout, ...options } = step;
return {
id,
name,
compile(filepath) {
return __awaiter(this, void 0, void 0, function* () {
const result = {
name: this.name,
on: Object.fromEntries(this.events.map(({ name, options }) => [
name,
options ? options : null,
])),
concurrency: this.concurrencyGroup
? {
group: this.concurrencyGroup.groupSuffix,
"cancel-in-progress": this.concurrencyGroup.cancelPrevious,
}
: undefined,
defaults: this.defaultOptions
? {
run: {
"working-directory": this.defaultOptions.workingDirectory,
},
}
: undefined,
env: this.env.length > 0
? Object.fromEntries(this.env.map(({ name, value }) => [name, value]))
: undefined,
jobs: Object.fromEntries(yield Promise.all(this.jobs.map(({ name, options: { prettyName, permissions, ifExpression, runsOn, matrix, env, steps, dependsOn, services, timeout, concurrency, outputs, workingDirectory, }, }) => __awaiter(this, void 0, void 0, function* () {
return [
name,
{
name: prettyName,
permissions,
if: ifExpression,
"continue-on-error": continueOnError,
"working-directory": workingDirectory,
"timeout-minutes": timeout,
...options,
uses: await supplyChainAttack(step),
};
})),
outputs,
},
]))),
};
const compiled = `# Workflow automatically generated by gat\n# DO NOT CHANGE THIS FILE MANUALLY\n\n${(0, js_yaml_1.dump)(result, {
noRefs: true,
lineWidth: 200,
noCompatMode: true,
})}`;
if (!filepath)
return compiled;
return writeFilePromise(path_1.default.join(process.cwd(), ".github", "workflows", filepath), compiled);
"runs-on": this.assignRunner(runsOn),
"timeout-minutes": timeout !== null && timeout !== void 0 ? timeout : 15,
needs: dependsOn,
services,
concurrency: concurrency
? {
group: `${kebabCase(this.name)}-${name}-${concurrency.groupSuffix}`,
"cancel-in-progress": concurrency.cancelPrevious,
}
: undefined,
strategy: matrix
? {
"fail-fast": false,
matrix: typeof matrix === "string"
? matrix
: Object.assign(Object.assign({}, Object.fromEntries(matrix.elements.map(({ id, options }) => [
id,
options,
]))), { include: matrix.extra }),
}
: undefined,
env,
defaults: workingDirectory
? {
run: {
"working-directory": workingDirectory,
},
}
: undefined,
steps: yield Promise.all(steps.map((step) => __awaiter(this, void 0, void 0, function* () {
const { id, name, ifExpression, workingDirectory, continueOnError, timeout } = step, options = __rest(step, ["id", "name", "ifExpression", "workingDirectory", "continueOnError", "timeout"]);
return Object.assign(Object.assign({ id,
name, if: ifExpression, "continue-on-error": continueOnError, "working-directory": workingDirectory, "timeout-minutes": timeout }, options), { uses: yield supplyChainAttack(step) });
}))),
outputs,
},
];
})))),
};
const compiled = `# Workflow automatically generated by gat\n# DO NOT CHANGE THIS FILE MANUALLY\n\n${dump(result, {
noRefs: true,
lineWidth: 200,
noCompatMode: true,
})}`;
if (!filepath)
return compiled;
return writeFilePromise(path.join(process.cwd(), ".github", "workflows", filepath), compiled);
});
}
}
exports.Workflow = Workflow;

@@ -1,8 +0,15 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vitest_1 = require("vitest");
const workflow_1 = require("./workflow");
(0, vitest_1.describe)("Workflow", () => {
(0, vitest_1.it)("generates a simple workflow", async () => {
const workflow = new workflow_1.Workflow("Simple");
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { describe, it, expect } from "vitest";
import { Workflow } from "./workflow";
describe("Workflow", () => {
it("generates a simple workflow", () => __awaiter(void 0, void 0, void 0, function* () {
const workflow = new Workflow("Simple");
workflow

@@ -17,6 +24,6 @@ .on("pull_request", { types: ["opened"] })

});
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
});
(0, vitest_1.it)("allows multiple events", async () => {
const workflow = new workflow_1.Workflow("Multiple events");
expect(yield workflow.compile()).toMatchSnapshot();
}));
it("allows multiple events", () => __awaiter(void 0, void 0, void 0, function* () {
const workflow = new Workflow("Multiple events");
workflow

@@ -28,6 +35,6 @@ .on("push", { branches: ["main"] })

});
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
});
(0, vitest_1.it)("allows declaring default options", async () => {
const workflow = new workflow_1.Workflow("Default options");
expect(yield workflow.compile()).toMatchSnapshot();
}));
it("allows declaring default options", () => __awaiter(void 0, void 0, void 0, function* () {
const workflow = new Workflow("Default options");
workflow

@@ -41,6 +48,6 @@ .on("push", { branches: ["main"] })

});
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
});
(0, vitest_1.it)("allows declaring environment variables", async () => {
const workflow = new workflow_1.Workflow("With Environment variables");
expect(yield workflow.compile()).toMatchSnapshot();
}));
it("allows declaring environment variables", () => __awaiter(void 0, void 0, void 0, function* () {
const workflow = new Workflow("With Environment variables");
workflow

@@ -58,6 +65,6 @@ .on("push")

});
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
});
(0, vitest_1.it)("allows using a concurrency group", async () => {
const workflow = new workflow_1.Workflow("Concurrency group");
expect(yield workflow.compile()).toMatchSnapshot();
}));
it("allows using a concurrency group", () => __awaiter(void 0, void 0, void 0, function* () {
const workflow = new Workflow("Concurrency group");
workflow.on("push").addJob("job1", {

@@ -74,6 +81,6 @@ concurrency: {

});
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
});
(0, vitest_1.it)("allows using outputs", async () => {
const workflow = new workflow_1.Workflow("Using outputs");
expect(yield workflow.compile()).toMatchSnapshot();
}));
it("allows using outputs", () => __awaiter(void 0, void 0, void 0, function* () {
const workflow = new Workflow("Using outputs");
workflow.on("push").addJob("job1", {

@@ -90,6 +97,6 @@ steps: [

});
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
});
(0, vitest_1.it)("allows conditional jobs", async () => {
const workflow = new workflow_1.Workflow("Conditional job");
expect(yield workflow.compile()).toMatchSnapshot();
}));
it("allows conditional jobs", () => __awaiter(void 0, void 0, void 0, function* () {
const workflow = new Workflow("Conditional job");
workflow.on("push").addJob("job1", {

@@ -103,6 +110,6 @@ ifExpression: "${{ github.ref != 'refs/heads/main' }}",

});
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
});
(0, vitest_1.it)("allows a job matrix", async () => {
const workflow = new workflow_1.Workflow("Conditional job");
expect(yield workflow.compile()).toMatchSnapshot();
}));
it("allows a job matrix", () => __awaiter(void 0, void 0, void 0, function* () {
const workflow = new Workflow("Conditional job");
workflow.on("push").addJob("job1", {

@@ -134,6 +141,6 @@ matrix: {

});
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
});
(0, vitest_1.it)("allows uses steps", async () => {
const workflow = new workflow_1.Workflow("Uses steps");
expect(yield workflow.compile()).toMatchSnapshot();
}));
it("allows uses steps", () => __awaiter(void 0, void 0, void 0, function* () {
const workflow = new Workflow("Uses steps");
workflow

@@ -153,6 +160,6 @@ .on("push")

});
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
});
(0, vitest_1.it)("allows custom types in a workflow", async () => {
const workflow = new workflow_1.Workflow("With custom types");
expect(yield workflow.compile()).toMatchSnapshot();
}));
it("allows custom types in a workflow", () => __awaiter(void 0, void 0, void 0, function* () {
const workflow = new Workflow("With custom types");
workflow.on("push").addJob("job1", {

@@ -172,6 +179,6 @@ runsOn: "standard-runner",

});
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
});
(0, vitest_1.it)("support workflow dispatch event", async () => {
const workflow = new workflow_1.Workflow("Workflow dispatch");
expect(yield workflow.compile()).toMatchSnapshot();
}));
it("support workflow dispatch event", () => __awaiter(void 0, void 0, void 0, function* () {
const workflow = new Workflow("Workflow dispatch");
workflow

@@ -194,6 +201,6 @@ .on("workflow_dispatch", {

});
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
});
(0, vitest_1.it)("supports schedule event", async () => {
const workflow = new workflow_1.Workflow("Schedule")
expect(yield workflow.compile()).toMatchSnapshot();
}));
it("supports schedule event", () => __awaiter(void 0, void 0, void 0, function* () {
const workflow = new Workflow("Schedule")
.on("schedule", [{ cron: "0 4 * * 1-5" }])

@@ -203,6 +210,6 @@ .addJob("job1", {

});
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
});
(0, vitest_1.it)("supports a pretty name for the job", async () => {
const workflow = new workflow_1.Workflow("Job with pretty name")
expect(yield workflow.compile()).toMatchSnapshot();
}));
it("supports a pretty name for the job", () => __awaiter(void 0, void 0, void 0, function* () {
const workflow = new Workflow("Job with pretty name")
.on("push")

@@ -213,6 +220,6 @@ .addJob("job1", {

});
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
});
(0, vitest_1.it)("allows permissions into jobs", async () => {
const workflow = new workflow_1.Workflow("Job with permissions")
expect(yield workflow.compile()).toMatchSnapshot();
}));
it("allows permissions into jobs", () => __awaiter(void 0, void 0, void 0, function* () {
const workflow = new Workflow("Job with permissions")
.on("push")

@@ -226,6 +233,6 @@ .addJob("job1", {

});
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
});
(0, vitest_1.it)("allows multiline strings", async () => {
const workflow = new workflow_1.Workflow("Multiline strings")
expect(yield workflow.compile()).toMatchSnapshot();
}));
it("allows multiline strings", () => __awaiter(void 0, void 0, void 0, function* () {
const workflow = new Workflow("Multiline strings")
.on("push")

@@ -241,6 +248,6 @@ .addJob("job1", {

});
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
});
(0, vitest_1.it)("allows concurrency groups at workflow level", async () => {
const workflow = new workflow_1.Workflow("Concurrency at workflow level")
expect(yield workflow.compile()).toMatchSnapshot();
}));
it("allows concurrency groups at workflow level", () => __awaiter(void 0, void 0, void 0, function* () {
const workflow = new Workflow("Concurrency at workflow level")
.on("push")

@@ -259,4 +266,4 @@ .setConcurrencyGroup({

});
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
});
expect(yield workflow.compile()).toMatchSnapshot();
}));
});
{
"name": "@factorialco/gat",
"version": "2.2.0",
"version": "2.3.0",
"description": "Write your GitHub Actions workflows using TypeScript",

@@ -8,2 +8,3 @@ "bin": {

},
"type": "module",
"main": "dist/index.js",

@@ -10,0 +11,0 @@ "files": [

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc