@factorialco/gat 2.5.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +17 -21
- package/dist/event.d.ts +40 -0
- package/dist/event.js +2 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -2
- package/dist/job.d.ts +42 -0
- package/dist/job.js +2 -1
- package/dist/step.d.ts +18 -0
- package/dist/step.js +5 -1
- package/dist/workflow.d.ts +31 -0
- package/dist/workflow.js +104 -116
- package/dist/workflow.spec.d.ts +1 -0
- package/dist/workflow.spec.js +70 -77
- package/package.json +11 -13
package/dist/cli.d.ts
ADDED
package/dist/cli.js
CHANGED
|
@@ -1,32 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
return
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
5
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const child_process_1 = require("child_process");
|
|
10
|
+
const commander_1 = require("commander");
|
|
11
|
+
const util_1 = require("util");
|
|
12
|
+
const execPromise = (0, util_1.promisify)(child_process_1.exec);
|
|
13
|
+
const folder = path_1.default.join(process.cwd(), ".github", "templates");
|
|
14
|
+
const cli = new commander_1.Command();
|
|
19
15
|
cli
|
|
20
16
|
.version("2.0.0")
|
|
21
17
|
.description("Write your GitHub Actions workflows using TypeScript");
|
|
22
18
|
cli
|
|
23
19
|
.command("build")
|
|
24
20
|
.description("Transpile all Gat templates into GitHub Actions workflows.")
|
|
25
|
-
.action(() =>
|
|
26
|
-
if (!
|
|
27
|
-
|
|
21
|
+
.action(async () => {
|
|
22
|
+
if (!fs_1.default.existsSync(path_1.default.join(folder, "..", "workflows"))) {
|
|
23
|
+
fs_1.default.mkdirSync(path_1.default.join(folder, "..", "workflows"));
|
|
28
24
|
}
|
|
29
|
-
|
|
25
|
+
await execPromise(`npx tsx ${path_1.default.join(folder, "index.ts")}`);
|
|
30
26
|
process.exit(0);
|
|
31
|
-
})
|
|
27
|
+
});
|
|
32
28
|
cli.parse(process.argv);
|
package/dist/event.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type EventName = "push" | "pull_request" | "pull_request_review" | "workflow_run" | "workflow_dispatch" | "schedule" | "pull_request_target" | "repository_dispatch";
|
|
2
|
+
export type EventOptions<T extends EventName> = T extends "push" ? PushEventOptions : T extends "pull_request" ? PullRequestEventOptions : T extends "pull_request_review" ? PullRequestReviewEventOptions : T extends "workflow_run" ? WorkflowRunEventOptions : T extends "workflow_dispatch" ? WorkflowDispatchEventOptions : T extends "schedule" ? ScheduleEventOptions : T extends "repository_dispatch" ? RepositoryDispatchEventOptions : never;
|
|
3
|
+
interface PushEventOptions {
|
|
4
|
+
branches?: string[];
|
|
5
|
+
paths?: string[];
|
|
6
|
+
}
|
|
7
|
+
interface PullRequestEventOptions {
|
|
8
|
+
branches?: string[];
|
|
9
|
+
paths?: string[];
|
|
10
|
+
types?: Array<"opened" | "closed" | "reopened" | "synchronize" | "labeled" | "unlabeled">;
|
|
11
|
+
}
|
|
12
|
+
interface PullRequestReviewEventOptions {
|
|
13
|
+
types?: Array<"submitted">;
|
|
14
|
+
}
|
|
15
|
+
interface WorkflowRunEventOptions {
|
|
16
|
+
workflows?: string[];
|
|
17
|
+
types?: Array<"completed">;
|
|
18
|
+
branches?: string[];
|
|
19
|
+
}
|
|
20
|
+
interface WorkflowDispatchInput {
|
|
21
|
+
description: string;
|
|
22
|
+
required?: boolean;
|
|
23
|
+
type?: "choice" | "boolean" | "string";
|
|
24
|
+
options?: string[];
|
|
25
|
+
default?: string | boolean;
|
|
26
|
+
}
|
|
27
|
+
interface WorkflowDispatchEventOptions {
|
|
28
|
+
inputs?: Record<string, WorkflowDispatchInput>;
|
|
29
|
+
}
|
|
30
|
+
type ScheduleEventOptions = Array<{
|
|
31
|
+
cron: string;
|
|
32
|
+
}>;
|
|
33
|
+
interface RepositoryDispatchEventOptions {
|
|
34
|
+
types: string[];
|
|
35
|
+
}
|
|
36
|
+
export interface Event {
|
|
37
|
+
name: EventName;
|
|
38
|
+
options?: EventOptions<EventName>;
|
|
39
|
+
}
|
|
40
|
+
export {};
|
package/dist/event.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Workflow } from "./workflow";
|
|
2
|
+
import { type ConcurrencyGroup, type JobOptions, type Matrix, type Service } from "./job";
|
|
3
|
+
import { type RunStep, type UseStep, type BaseStep } from "./step";
|
|
4
|
+
export { Workflow, RunStep, UseStep, BaseStep, ConcurrencyGroup, JobOptions, Matrix, Service, };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Workflow = void 0;
|
|
4
|
+
const workflow_1 = require("./workflow");
|
|
5
|
+
Object.defineProperty(exports, "Workflow", { enumerable: true, get: function () { return workflow_1.Workflow; } });
|
package/dist/job.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface ConcurrencyGroup {
|
|
2
|
+
groupSuffix: string;
|
|
3
|
+
cancelPrevious: boolean;
|
|
4
|
+
}
|
|
5
|
+
export interface Matrix {
|
|
6
|
+
elements: Array<{
|
|
7
|
+
id: string;
|
|
8
|
+
options: Array<string | number | boolean>;
|
|
9
|
+
}>;
|
|
10
|
+
extra?: Array<Record<string, string | number | boolean>>;
|
|
11
|
+
}
|
|
12
|
+
export interface Service {
|
|
13
|
+
image: string;
|
|
14
|
+
credentials?: {
|
|
15
|
+
username: string;
|
|
16
|
+
password: string;
|
|
17
|
+
};
|
|
18
|
+
env?: Record<string, string>;
|
|
19
|
+
ports: string[];
|
|
20
|
+
options?: string;
|
|
21
|
+
volumes?: string[];
|
|
22
|
+
}
|
|
23
|
+
export interface JobOptions<Step, RunnerDefinition, Name> {
|
|
24
|
+
prettyName?: string;
|
|
25
|
+
permissions?: object;
|
|
26
|
+
ifExpression?: string;
|
|
27
|
+
runsOn?: RunnerDefinition;
|
|
28
|
+
timeout?: number;
|
|
29
|
+
dependsOn?: Array<Name>;
|
|
30
|
+
services?: Record<string, Service>;
|
|
31
|
+
env?: Record<string, string>;
|
|
32
|
+
concurrency?: ConcurrencyGroup;
|
|
33
|
+
matrix?: Matrix | string;
|
|
34
|
+
steps: Step[];
|
|
35
|
+
outputs?: Record<string, string>;
|
|
36
|
+
workingDirectory?: string;
|
|
37
|
+
}
|
|
38
|
+
export type StringWithNoSpaces<T> = T extends `${string} ${string}` ? never : T extends ` ${string}` ? never : T extends `${string} ` ? never : T;
|
|
39
|
+
export interface Job<Step, RunnerDefinition, Name> {
|
|
40
|
+
name: string;
|
|
41
|
+
options: JobOptions<Step, RunnerDefinition, Name>;
|
|
42
|
+
}
|
package/dist/job.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
package/dist/step.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface BaseStep {
|
|
2
|
+
id?: string;
|
|
3
|
+
name?: string;
|
|
4
|
+
env?: Record<string, string>;
|
|
5
|
+
ifExpression?: string;
|
|
6
|
+
workingDirectory?: string;
|
|
7
|
+
continueOnError?: boolean;
|
|
8
|
+
timeout?: number;
|
|
9
|
+
}
|
|
10
|
+
export type Step = RunStep | UseStep;
|
|
11
|
+
export interface RunStep extends BaseStep {
|
|
12
|
+
run: string;
|
|
13
|
+
}
|
|
14
|
+
export interface UseStep extends BaseStep {
|
|
15
|
+
uses: string;
|
|
16
|
+
with?: Record<string, string | number | boolean>;
|
|
17
|
+
}
|
|
18
|
+
export declare const isUseStep: (step: Step) => step is UseStep;
|
package/dist/step.js
CHANGED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ConcurrencyGroup, Job, JobOptions, StringWithNoSpaces } from "./job";
|
|
2
|
+
import type { Event, EventName, EventOptions } from "./event";
|
|
3
|
+
import { type Step } from "./step";
|
|
4
|
+
interface DefaultOptions {
|
|
5
|
+
workingDirectory: string;
|
|
6
|
+
}
|
|
7
|
+
interface EnvVar {
|
|
8
|
+
name: string;
|
|
9
|
+
value: string;
|
|
10
|
+
}
|
|
11
|
+
export type RunnerDefinition = string | {
|
|
12
|
+
group: string;
|
|
13
|
+
labels?: string[];
|
|
14
|
+
} | ["self-hosted", string];
|
|
15
|
+
export declare class Workflow<JobStep extends Step = Step, Runner extends RunnerDefinition = RunnerDefinition, JobName = never> {
|
|
16
|
+
name: string;
|
|
17
|
+
events: Event[];
|
|
18
|
+
jobs: Array<Job<JobStep, Runner, JobName>>;
|
|
19
|
+
defaultOptions: DefaultOptions | null;
|
|
20
|
+
env: EnvVar[];
|
|
21
|
+
concurrencyGroup?: ConcurrencyGroup;
|
|
22
|
+
constructor(name: string);
|
|
23
|
+
on<T extends EventName>(name: T, options?: EventOptions<T>): this;
|
|
24
|
+
addDefaults(options: DefaultOptions): this;
|
|
25
|
+
addJob<T extends string>(name: StringWithNoSpaces<T>, options: JobOptions<JobStep, Runner, JobName>): Workflow<JobStep, Runner, JobName | T>;
|
|
26
|
+
setEnv(name: string, value: string): this;
|
|
27
|
+
setConcurrencyGroup(concurrencyGroup: ConcurrencyGroup): this;
|
|
28
|
+
defaultRunner(): string;
|
|
29
|
+
compile(filepath?: string): Promise<string | void>;
|
|
30
|
+
}
|
|
31
|
+
export {};
|
package/dist/workflow.js
CHANGED
|
@@ -1,35 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
return
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
4
|
};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
};
|
|
21
|
-
import { dump } from "js-yaml";
|
|
22
|
-
import kebabCase from "lodash/kebabCase";
|
|
23
|
-
import fs from "fs";
|
|
24
|
-
import path from "path";
|
|
25
|
-
import { promisify } from "util";
|
|
26
|
-
import axios from "axios";
|
|
27
|
-
import { isUseStep } from "./step";
|
|
28
|
-
const writeFilePromise = promisify(fs.writeFile);
|
|
29
|
-
const DEFAULT_RUNNERS = ["ubuntu-22.04"];
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Workflow = void 0;
|
|
7
|
+
const js_yaml_1 = require("js-yaml");
|
|
8
|
+
const kebabCase_1 = __importDefault(require("lodash/kebabCase"));
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const util_1 = require("util");
|
|
12
|
+
const axios_1 = __importDefault(require("axios"));
|
|
13
|
+
const step_1 = require("./step");
|
|
14
|
+
const writeFilePromise = (0, util_1.promisify)(fs_1.default.writeFile);
|
|
30
15
|
const chainAttackCache = {};
|
|
31
|
-
const supplyChainAttack = (step, enabled = false) =>
|
|
32
|
-
if (!isUseStep(step))
|
|
16
|
+
const supplyChainAttack = async (step, enabled = false) => {
|
|
17
|
+
if (!(0, step_1.isUseStep)(step))
|
|
33
18
|
return;
|
|
34
19
|
if (!enabled)
|
|
35
20
|
return step.uses;
|
|
@@ -42,7 +27,7 @@ const supplyChainAttack = (step, enabled = false) => __awaiter(void 0, void 0, v
|
|
|
42
27
|
if (!match)
|
|
43
28
|
return uses;
|
|
44
29
|
const { repository, version } = match.groups;
|
|
45
|
-
const response =
|
|
30
|
+
const response = await axios_1.default.get(`https://api.github.com/repos/${repository}/tags`);
|
|
46
31
|
const tags = response.data;
|
|
47
32
|
const tag = tags.find((tag) => tag.name === version);
|
|
48
33
|
if (!tag)
|
|
@@ -50,8 +35,8 @@ const supplyChainAttack = (step, enabled = false) => __awaiter(void 0, void 0, v
|
|
|
50
35
|
const result = `${repository}@${tag.commit.sha}`;
|
|
51
36
|
chainAttackCache[uses] = result;
|
|
52
37
|
return result;
|
|
53
|
-
}
|
|
54
|
-
|
|
38
|
+
};
|
|
39
|
+
class Workflow {
|
|
55
40
|
constructor(name) {
|
|
56
41
|
this.name = name;
|
|
57
42
|
this.events = [];
|
|
@@ -82,89 +67,92 @@ export class Workflow {
|
|
|
82
67
|
defaultRunner() {
|
|
83
68
|
return "ubuntu-22.04";
|
|
84
69
|
}
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
"
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
70
|
+
async compile(filepath) {
|
|
71
|
+
const result = {
|
|
72
|
+
name: this.name,
|
|
73
|
+
on: Object.fromEntries(this.events.map(({ name, options }) => [
|
|
74
|
+
name,
|
|
75
|
+
options ? options : null,
|
|
76
|
+
])),
|
|
77
|
+
concurrency: this.concurrencyGroup
|
|
78
|
+
? {
|
|
79
|
+
group: this.concurrencyGroup.groupSuffix,
|
|
80
|
+
"cancel-in-progress": this.concurrencyGroup.cancelPrevious,
|
|
81
|
+
}
|
|
82
|
+
: undefined,
|
|
83
|
+
defaults: this.defaultOptions
|
|
84
|
+
? {
|
|
85
|
+
run: {
|
|
86
|
+
"working-directory": this.defaultOptions.workingDirectory,
|
|
87
|
+
},
|
|
88
|
+
}
|
|
89
|
+
: undefined,
|
|
90
|
+
env: this.env.length > 0
|
|
91
|
+
? Object.fromEntries(this.env.map(({ name, value }) => [name, value]))
|
|
92
|
+
: undefined,
|
|
93
|
+
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, }, }) => [
|
|
94
|
+
name,
|
|
95
|
+
{
|
|
96
|
+
name: prettyName,
|
|
97
|
+
permissions,
|
|
98
|
+
if: ifExpression,
|
|
99
|
+
"runs-on": runsOn ?? this.defaultRunner(),
|
|
100
|
+
"timeout-minutes": timeout ?? 15,
|
|
101
|
+
needs: dependsOn,
|
|
102
|
+
services,
|
|
103
|
+
concurrency: concurrency
|
|
104
|
+
? {
|
|
105
|
+
group: `${(0, kebabCase_1.default)(this.name)}-${name}-${concurrency.groupSuffix}`,
|
|
106
|
+
"cancel-in-progress": concurrency.cancelPrevious,
|
|
107
|
+
}
|
|
108
|
+
: undefined,
|
|
109
|
+
strategy: matrix
|
|
110
|
+
? {
|
|
111
|
+
"fail-fast": false,
|
|
112
|
+
matrix: typeof matrix === "string"
|
|
113
|
+
? matrix
|
|
114
|
+
: {
|
|
115
|
+
...Object.fromEntries(matrix.elements.map(({ id, options }) => [
|
|
116
|
+
id,
|
|
117
|
+
options,
|
|
118
|
+
])),
|
|
119
|
+
include: matrix.extra,
|
|
120
|
+
},
|
|
121
|
+
}
|
|
122
|
+
: undefined,
|
|
123
|
+
env,
|
|
124
|
+
defaults: workingDirectory
|
|
125
|
+
? {
|
|
126
|
+
run: {
|
|
127
|
+
"working-directory": workingDirectory,
|
|
128
|
+
},
|
|
129
|
+
}
|
|
130
|
+
: undefined,
|
|
131
|
+
steps: await Promise.all(steps.map(async (step) => {
|
|
132
|
+
const { id, name, ifExpression, workingDirectory, continueOnError, timeout, ...options } = step;
|
|
133
|
+
return {
|
|
134
|
+
id,
|
|
135
|
+
name,
|
|
120
136
|
if: ifExpression,
|
|
121
|
-
"
|
|
122
|
-
"
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
: undefined,
|
|
142
|
-
env,
|
|
143
|
-
defaults: workingDirectory
|
|
144
|
-
? {
|
|
145
|
-
run: {
|
|
146
|
-
"working-directory": workingDirectory,
|
|
147
|
-
},
|
|
148
|
-
}
|
|
149
|
-
: undefined,
|
|
150
|
-
steps: yield Promise.all(steps.map((step) => __awaiter(this, void 0, void 0, function* () {
|
|
151
|
-
const { id, name, ifExpression, workingDirectory, continueOnError, timeout } = step, options = __rest(step, ["id", "name", "ifExpression", "workingDirectory", "continueOnError", "timeout"]);
|
|
152
|
-
return Object.assign(Object.assign({ id,
|
|
153
|
-
name, if: ifExpression, "continue-on-error": continueOnError, "working-directory": workingDirectory, "timeout-minutes": timeout }, options), { uses: yield supplyChainAttack(step) });
|
|
154
|
-
}))),
|
|
155
|
-
outputs,
|
|
156
|
-
},
|
|
157
|
-
];
|
|
158
|
-
})))),
|
|
159
|
-
};
|
|
160
|
-
const compiled = `# Workflow automatically generated by gat\n# DO NOT CHANGE THIS FILE MANUALLY\n\n${dump(result, {
|
|
161
|
-
noRefs: true,
|
|
162
|
-
lineWidth: 200,
|
|
163
|
-
noCompatMode: true,
|
|
164
|
-
})}`;
|
|
165
|
-
if (!filepath)
|
|
166
|
-
return compiled;
|
|
167
|
-
return writeFilePromise(path.join(process.cwd(), ".github", "workflows", filepath), compiled);
|
|
168
|
-
});
|
|
137
|
+
"continue-on-error": continueOnError,
|
|
138
|
+
"working-directory": workingDirectory,
|
|
139
|
+
"timeout-minutes": timeout,
|
|
140
|
+
...options,
|
|
141
|
+
uses: await supplyChainAttack(step),
|
|
142
|
+
};
|
|
143
|
+
})),
|
|
144
|
+
outputs,
|
|
145
|
+
},
|
|
146
|
+
]))),
|
|
147
|
+
};
|
|
148
|
+
const compiled = `# Workflow automatically generated by gat\n# DO NOT CHANGE THIS FILE MANUALLY\n\n${(0, js_yaml_1.dump)(result, {
|
|
149
|
+
noRefs: true,
|
|
150
|
+
lineWidth: 200,
|
|
151
|
+
noCompatMode: true,
|
|
152
|
+
})}`;
|
|
153
|
+
if (!filepath)
|
|
154
|
+
return compiled;
|
|
155
|
+
return writeFilePromise(path_1.default.join(process.cwd(), ".github", "workflows", filepath), compiled);
|
|
169
156
|
}
|
|
170
157
|
}
|
|
158
|
+
exports.Workflow = Workflow;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/workflow.spec.js
CHANGED
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
import { describe, it, expect } from "vitest";
|
|
11
|
-
import { Workflow } from "./workflow";
|
|
12
|
-
describe("Workflow", () => {
|
|
13
|
-
it("generates a simple workflow", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
14
|
-
const workflow = new Workflow("Simple");
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const workflow_1 = require("./workflow");
|
|
5
|
+
(0, vitest_1.describe)("Workflow", () => {
|
|
6
|
+
(0, vitest_1.it)("generates a simple workflow", async () => {
|
|
7
|
+
const workflow = new workflow_1.Workflow("Simple");
|
|
15
8
|
workflow
|
|
16
9
|
.on("pull_request", { types: ["opened"] })
|
|
17
10
|
.addJob("job1", {
|
|
@@ -21,20 +14,20 @@ describe("Workflow", () => {
|
|
|
21
14
|
steps: [{ name: "Do something else", run: "exit 0" }],
|
|
22
15
|
dependsOn: ["job1"],
|
|
23
16
|
});
|
|
24
|
-
expect(
|
|
25
|
-
})
|
|
26
|
-
it("allows multiple events", () =>
|
|
27
|
-
const workflow = new Workflow("Multiple events");
|
|
17
|
+
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
|
|
18
|
+
});
|
|
19
|
+
(0, vitest_1.it)("allows multiple events", async () => {
|
|
20
|
+
const workflow = new workflow_1.Workflow("Multiple events");
|
|
28
21
|
workflow
|
|
29
22
|
.on("push", { branches: ["main"] })
|
|
30
23
|
.on("pull_request", { types: ["opened"] })
|
|
31
24
|
.addJob("job1", {
|
|
32
25
|
steps: [{ name: "Do something", run: "exit 0" }],
|
|
33
26
|
});
|
|
34
|
-
expect(
|
|
35
|
-
})
|
|
36
|
-
it("allows declaring default options", () =>
|
|
37
|
-
const workflow = new Workflow("Default options");
|
|
27
|
+
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
|
|
28
|
+
});
|
|
29
|
+
(0, vitest_1.it)("allows declaring default options", async () => {
|
|
30
|
+
const workflow = new workflow_1.Workflow("Default options");
|
|
38
31
|
workflow
|
|
39
32
|
.on("push", { branches: ["main"] })
|
|
40
33
|
.addDefaults({
|
|
@@ -43,10 +36,10 @@ describe("Workflow", () => {
|
|
|
43
36
|
.addJob("job1", {
|
|
44
37
|
steps: [{ name: "Do something", run: "exit 0" }],
|
|
45
38
|
});
|
|
46
|
-
expect(
|
|
47
|
-
})
|
|
48
|
-
it("allows declaring environment variables", () =>
|
|
49
|
-
const workflow = new Workflow("With Environment variables");
|
|
39
|
+
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
|
|
40
|
+
});
|
|
41
|
+
(0, vitest_1.it)("allows declaring environment variables", async () => {
|
|
42
|
+
const workflow = new workflow_1.Workflow("With Environment variables");
|
|
50
43
|
workflow
|
|
51
44
|
.on("push")
|
|
52
45
|
.setEnv("NODE_VERSION", "16")
|
|
@@ -59,10 +52,10 @@ describe("Workflow", () => {
|
|
|
59
52
|
},
|
|
60
53
|
],
|
|
61
54
|
});
|
|
62
|
-
expect(
|
|
63
|
-
})
|
|
64
|
-
it("allows using a concurrency group", () =>
|
|
65
|
-
const workflow = new Workflow("Concurrency group");
|
|
55
|
+
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
|
|
56
|
+
});
|
|
57
|
+
(0, vitest_1.it)("allows using a concurrency group", async () => {
|
|
58
|
+
const workflow = new workflow_1.Workflow("Concurrency group");
|
|
66
59
|
workflow.on("push").addJob("job1", {
|
|
67
60
|
concurrency: {
|
|
68
61
|
groupSuffix: "foo",
|
|
@@ -74,10 +67,10 @@ describe("Workflow", () => {
|
|
|
74
67
|
},
|
|
75
68
|
],
|
|
76
69
|
});
|
|
77
|
-
expect(
|
|
78
|
-
})
|
|
79
|
-
it("allows using outputs", () =>
|
|
80
|
-
const workflow = new Workflow("Using outputs");
|
|
70
|
+
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
|
|
71
|
+
});
|
|
72
|
+
(0, vitest_1.it)("allows using outputs", async () => {
|
|
73
|
+
const workflow = new workflow_1.Workflow("Using outputs");
|
|
81
74
|
workflow.on("push").addJob("job1", {
|
|
82
75
|
steps: [
|
|
83
76
|
{
|
|
@@ -89,10 +82,10 @@ describe("Workflow", () => {
|
|
|
89
82
|
"random-number": "${{ steps.random-number.outputs.random-number }}",
|
|
90
83
|
},
|
|
91
84
|
});
|
|
92
|
-
expect(
|
|
93
|
-
})
|
|
94
|
-
it("allows conditional jobs", () =>
|
|
95
|
-
const workflow = new Workflow("Conditional job");
|
|
85
|
+
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
|
|
86
|
+
});
|
|
87
|
+
(0, vitest_1.it)("allows conditional jobs", async () => {
|
|
88
|
+
const workflow = new workflow_1.Workflow("Conditional job");
|
|
96
89
|
workflow.on("push").addJob("job1", {
|
|
97
90
|
ifExpression: "${{ github.ref != 'refs/heads/main' }}",
|
|
98
91
|
steps: [
|
|
@@ -101,10 +94,10 @@ describe("Workflow", () => {
|
|
|
101
94
|
},
|
|
102
95
|
],
|
|
103
96
|
});
|
|
104
|
-
expect(
|
|
105
|
-
})
|
|
106
|
-
it("allows a job matrix", () =>
|
|
107
|
-
const workflow = new Workflow("Conditional job");
|
|
97
|
+
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
|
|
98
|
+
});
|
|
99
|
+
(0, vitest_1.it)("allows a job matrix", async () => {
|
|
100
|
+
const workflow = new workflow_1.Workflow("Conditional job");
|
|
108
101
|
workflow.on("push").addJob("job1", {
|
|
109
102
|
matrix: {
|
|
110
103
|
elements: [
|
|
@@ -131,10 +124,10 @@ describe("Workflow", () => {
|
|
|
131
124
|
},
|
|
132
125
|
],
|
|
133
126
|
});
|
|
134
|
-
expect(
|
|
135
|
-
})
|
|
136
|
-
it("allows uses steps", () =>
|
|
137
|
-
const workflow = new Workflow("Uses steps");
|
|
127
|
+
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
|
|
128
|
+
});
|
|
129
|
+
(0, vitest_1.it)("allows uses steps", async () => {
|
|
130
|
+
const workflow = new workflow_1.Workflow("Uses steps");
|
|
138
131
|
workflow
|
|
139
132
|
.on("push")
|
|
140
133
|
.setEnv("NODE_VERSION", "16")
|
|
@@ -149,12 +142,12 @@ describe("Workflow", () => {
|
|
|
149
142
|
},
|
|
150
143
|
],
|
|
151
144
|
});
|
|
152
|
-
expect(
|
|
153
|
-
})
|
|
154
|
-
it("allows custom types in a workflow", () =>
|
|
155
|
-
const workflow = new Workflow("With custom types");
|
|
145
|
+
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
|
|
146
|
+
});
|
|
147
|
+
(0, vitest_1.it)("allows custom types in a workflow", async () => {
|
|
148
|
+
const workflow = new workflow_1.Workflow("With custom types");
|
|
156
149
|
workflow.on("push").addJob("job1", {
|
|
157
|
-
runsOn: "standard-runner",
|
|
150
|
+
runsOn: ["self-hosted", "standard-runner"],
|
|
158
151
|
steps: [
|
|
159
152
|
{
|
|
160
153
|
run: "echo 'Do something'",
|
|
@@ -167,10 +160,10 @@ describe("Workflow", () => {
|
|
|
167
160
|
},
|
|
168
161
|
],
|
|
169
162
|
});
|
|
170
|
-
expect(
|
|
171
|
-
})
|
|
172
|
-
it("support workflow dispatch event", () =>
|
|
173
|
-
const workflow = new Workflow("Workflow dispatch");
|
|
163
|
+
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
|
|
164
|
+
});
|
|
165
|
+
(0, vitest_1.it)("support workflow dispatch event", async () => {
|
|
166
|
+
const workflow = new workflow_1.Workflow("Workflow dispatch");
|
|
174
167
|
workflow
|
|
175
168
|
.on("workflow_dispatch", {
|
|
176
169
|
inputs: {
|
|
@@ -188,27 +181,27 @@ describe("Workflow", () => {
|
|
|
188
181
|
.addJob("job1", {
|
|
189
182
|
steps: [{ name: "Do something", run: "exit 0" }],
|
|
190
183
|
});
|
|
191
|
-
expect(
|
|
192
|
-
})
|
|
193
|
-
it("supports schedule event", () =>
|
|
194
|
-
const workflow = new Workflow("Schedule")
|
|
184
|
+
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
|
|
185
|
+
});
|
|
186
|
+
(0, vitest_1.it)("supports schedule event", async () => {
|
|
187
|
+
const workflow = new workflow_1.Workflow("Schedule")
|
|
195
188
|
.on("schedule", [{ cron: "0 4 * * 1-5" }])
|
|
196
189
|
.addJob("job1", {
|
|
197
190
|
steps: [{ name: "Do something", run: "exit 0" }],
|
|
198
191
|
});
|
|
199
|
-
expect(
|
|
200
|
-
})
|
|
201
|
-
it("supports a pretty name for the job", () =>
|
|
202
|
-
const workflow = new Workflow("Job with pretty name")
|
|
192
|
+
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
|
|
193
|
+
});
|
|
194
|
+
(0, vitest_1.it)("supports a pretty name for the job", async () => {
|
|
195
|
+
const workflow = new workflow_1.Workflow("Job with pretty name")
|
|
203
196
|
.on("push")
|
|
204
197
|
.addJob("job1", {
|
|
205
198
|
prettyName: "My pretty name",
|
|
206
199
|
steps: [{ name: "Do something", run: "exit 0" }],
|
|
207
200
|
});
|
|
208
|
-
expect(
|
|
209
|
-
})
|
|
210
|
-
it("allows permissions into jobs", () =>
|
|
211
|
-
const workflow = new Workflow("Job with permissions")
|
|
201
|
+
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
|
|
202
|
+
});
|
|
203
|
+
(0, vitest_1.it)("allows permissions into jobs", async () => {
|
|
204
|
+
const workflow = new workflow_1.Workflow("Job with permissions")
|
|
212
205
|
.on("push")
|
|
213
206
|
.addJob("job1", {
|
|
214
207
|
permissions: {
|
|
@@ -217,10 +210,10 @@ describe("Workflow", () => {
|
|
|
217
210
|
},
|
|
218
211
|
steps: [{ name: "Do something", run: "exit 0" }],
|
|
219
212
|
});
|
|
220
|
-
expect(
|
|
221
|
-
})
|
|
222
|
-
it("allows multiline strings", () =>
|
|
223
|
-
const workflow = new Workflow("Multiline strings")
|
|
213
|
+
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
|
|
214
|
+
});
|
|
215
|
+
(0, vitest_1.it)("allows multiline strings", async () => {
|
|
216
|
+
const workflow = new workflow_1.Workflow("Multiline strings")
|
|
224
217
|
.on("push")
|
|
225
218
|
.addJob("job1", {
|
|
226
219
|
steps: [
|
|
@@ -231,10 +224,10 @@ exit 0`,
|
|
|
231
224
|
},
|
|
232
225
|
],
|
|
233
226
|
});
|
|
234
|
-
expect(
|
|
235
|
-
})
|
|
236
|
-
it("allows concurrency groups at workflow level", () =>
|
|
237
|
-
const workflow = new Workflow("Concurrency at workflow level")
|
|
227
|
+
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
|
|
228
|
+
});
|
|
229
|
+
(0, vitest_1.it)("allows concurrency groups at workflow level", async () => {
|
|
230
|
+
const workflow = new workflow_1.Workflow("Concurrency at workflow level")
|
|
238
231
|
.on("push")
|
|
239
232
|
.setConcurrencyGroup({
|
|
240
233
|
groupSuffix: "${{ github.workflow }}-${{ github.ref }}",
|
|
@@ -248,6 +241,6 @@ exit 0`,
|
|
|
248
241
|
},
|
|
249
242
|
],
|
|
250
243
|
});
|
|
251
|
-
expect(
|
|
252
|
-
})
|
|
244
|
+
(0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
|
|
245
|
+
});
|
|
253
246
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@factorialco/gat",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Write your GitHub Actions workflows using TypeScript",
|
|
5
5
|
"bin": {
|
|
6
6
|
"gat": "dist/cli.js"
|
|
@@ -11,16 +11,6 @@
|
|
|
11
11
|
"dist/**/*"
|
|
12
12
|
],
|
|
13
13
|
"types": "dist/index.d.ts",
|
|
14
|
-
"scripts": {
|
|
15
|
-
"build": "tsc",
|
|
16
|
-
"prepare": "npm run build",
|
|
17
|
-
"prepublishOnly": "vitest run",
|
|
18
|
-
"test": "vitest",
|
|
19
|
-
"coverage": "vitest run --coverage",
|
|
20
|
-
"lint": "eslint src/**/*.ts",
|
|
21
|
-
"format": "prettier --write .",
|
|
22
|
-
"format:check": "prettier --check ."
|
|
23
|
-
},
|
|
24
14
|
"author": "David Morcillo <david.morcillo@factorial.co>",
|
|
25
15
|
"license": "ISC",
|
|
26
16
|
"devDependencies": {
|
|
@@ -49,5 +39,13 @@
|
|
|
49
39
|
"bugs": {
|
|
50
40
|
"url": "https://github.com/factorialco/gat/issues"
|
|
51
41
|
},
|
|
52
|
-
"homepage": "https://github.com/factorialco/gat#readme"
|
|
53
|
-
|
|
42
|
+
"homepage": "https://github.com/factorialco/gat#readme",
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsc",
|
|
45
|
+
"test": "vitest",
|
|
46
|
+
"coverage": "vitest run --coverage",
|
|
47
|
+
"lint": "eslint src/**/*.ts",
|
|
48
|
+
"format": "prettier --write .",
|
|
49
|
+
"format:check": "prettier --check ."
|
|
50
|
+
}
|
|
51
|
+
}
|