@factorialco/gat 3.5.0 → 3.10.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Factorial
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,7 @@
1
+ <p align="center">
2
+ <img src="gat.png" width="200" />
3
+ </p>
4
+
1
5
  # gat ![Build](https://github.com/factorialco/gat/actions/workflows/build.yml/badge.svg?branch=main) [![npm version](https://badge.fury.io/js/@factorialco%2Fgat.svg)](https://badge.fury.io/js/@factorialco%2Fgat)
2
6
 
3
7
  The `gat` project is a tool to **write your GitHub Actions workflows using TypeScript**.
@@ -24,7 +28,7 @@ The `gat` CLI assumes that you have a `index.ts` file inside `.github/templates`
24
28
  // .github/templates/index.ts
25
29
  import { Workflow } from "@factorialco/gat";
26
30
 
27
- new Workflow("My first workflow")
31
+ await new Workflow("My first workflow")
28
32
  .on("push")
29
33
  .addJob("test", {
30
34
  steps: [
@@ -39,10 +43,10 @@ new Workflow("My first workflow")
39
43
  },
40
44
  ],
41
45
  })
42
- .compile("my-first-workflow.yml");
46
+ .compile({ filePath: "my-first-workflow.yml" });
43
47
  ```
44
48
 
45
- Notice that you need to call the `compile()` method at the end, passing the file name of the generated Github Actions workflow.
49
+ Notice that you need to call the `compile()` method at the end, passing an options object with the `filePath` of the generated GitHub Actions workflow.
46
50
 
47
51
  ### Compiling your templates
48
52
 
@@ -75,11 +79,47 @@ Notice that the job includes a few assumptions like the `runs-on` and `timeout-m
75
79
 
76
80
  ### Create your own workflow class
77
81
 
78
- TODO
82
+ You can create factory functions that return pre-configured `Workflow` instances with shared settings. This avoids duplication across your templates:
83
+
84
+ ```ts
85
+ // .github/templates/helpers.ts
86
+ import { Workflow } from "@factorialco/gat";
87
+
88
+ export function createWorkflow(name: string) {
89
+ return new Workflow(name)
90
+ .setEnv("NODE_ENV", "production")
91
+ .on("push", { branches: ["main"] });
92
+ }
93
+ ```
94
+
95
+ Then use it in your templates:
96
+
97
+ ```ts
98
+ // .github/templates/index.ts
99
+ import { createWorkflow } from "./helpers";
100
+
101
+ await createWorkflow("Test")
102
+ .addJob("test", {
103
+ steps: [{ run: "npm test" }],
104
+ })
105
+ .compile({ filePath: "test.yml" });
106
+
107
+ await createWorkflow("Lint")
108
+ .addJob("lint", {
109
+ steps: [{ run: "npm run lint" }],
110
+ })
111
+ .compile({ filePath: "lint.yml" });
112
+ ```
113
+
114
+ This way all your workflows share the same environment variables, triggers, and any other defaults you configure in the factory function.
79
115
 
80
116
  ## Contributing
81
117
 
82
- TODO
118
+ 1. Fork the repository and clone it locally
119
+ 2. Install dependencies: `npm install`
120
+ 3. Run the tests: `npm test`
121
+ 4. Make your changes and ensure tests pass
122
+ 5. Submit a pull request
83
123
 
84
124
  ## License
85
125
 
package/dist/job.d.ts CHANGED
@@ -8,6 +8,7 @@ export interface Matrix {
8
8
  options: Array<string | number | boolean>;
9
9
  }>;
10
10
  extra?: Array<Record<string, string | number | boolean>>;
11
+ maxParallel?: number;
11
12
  }
12
13
  export interface Service {
13
14
  image: string;
@@ -23,11 +23,13 @@ export declare class Workflow<JobStep extends Step = Step, Runner extends Runner
23
23
  defaultOptions: DefaultOptions | null;
24
24
  env: EnvVar[];
25
25
  concurrencyGroup?: ConcurrencyGroup | null;
26
+ runName?: string;
26
27
  constructor(name: string);
27
28
  on<T extends EventName>(name: T, options?: EventOptions<T>): this;
28
29
  addDefaults(options: DefaultOptions): this;
29
30
  addJob<T extends string>(name: StringWithNoSpaces<T>, options: StepsJobOptions<JobStep, Runner, JobName> | UsesJobOptions<JobName>): Workflow<JobStep, Runner, JobName | T>;
30
31
  setEnv(name: string, value: string): this;
32
+ setRunName(runName: string): this;
31
33
  setConcurrencyGroup(concurrencyGroup: ConcurrencyGroup | null): this;
32
34
  defaultRunner(): string;
33
35
  compile(compileOptions?: WorkflowCompileOptions): Promise<string | void>;
package/dist/workflow.js CHANGED
@@ -41,6 +41,10 @@ class Workflow {
41
41
  this.env = [...this.env, { name, value }];
42
42
  return this;
43
43
  }
44
+ setRunName(runName) {
45
+ this.runName = runName;
46
+ return this;
47
+ }
44
48
  setConcurrencyGroup(concurrencyGroup) {
45
49
  this.concurrencyGroup = concurrencyGroup;
46
50
  return this;
@@ -51,6 +55,7 @@ class Workflow {
51
55
  async compile(compileOptions = {}) {
52
56
  const result = {
53
57
  name: this.name,
58
+ "run-name": this.runName,
54
59
  on: Object.fromEntries(this.events.map(({ name, options }) => [
55
60
  name,
56
61
  options ? options : null,
@@ -107,6 +112,9 @@ class Workflow {
107
112
  strategy: matrix
108
113
  ? {
109
114
  "fail-fast": false,
115
+ "max-parallel": typeof matrix !== "string" && matrix.maxParallel != null
116
+ ? matrix.maxParallel
117
+ : undefined,
110
118
  matrix: typeof matrix === "string"
111
119
  ? matrix
112
120
  : {
@@ -126,6 +126,26 @@ const workflow_1 = require("./workflow");
126
126
  });
127
127
  (0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
128
128
  });
129
+ (0, vitest_1.it)("allows a job matrix with max-parallel", async () => {
130
+ const workflow = new workflow_1.Workflow("Matrix with max parallel");
131
+ workflow.on("push").addJob("job1", {
132
+ matrix: {
133
+ elements: [
134
+ {
135
+ id: "food",
136
+ options: ["🍕", "🍔", "🌮"],
137
+ },
138
+ ],
139
+ maxParallel: 2,
140
+ },
141
+ steps: [
142
+ {
143
+ run: "echo ${{ matrix.food }}",
144
+ },
145
+ ],
146
+ });
147
+ (0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
148
+ });
129
149
  (0, vitest_1.it)("allows uses steps", async () => {
130
150
  const workflow = new workflow_1.Workflow("Uses steps");
131
151
  workflow
@@ -291,6 +311,19 @@ exit 0`,
291
311
  },
292
312
  })).toMatchSnapshot();
293
313
  });
314
+ (0, vitest_1.it)("supports a workflow-level run name", async () => {
315
+ const workflow = new workflow_1.Workflow("With run name")
316
+ .setRunName("Preview ${{ inputs.domain }} #${{ inputs.environmentIndex }}")
317
+ .on("workflow_dispatch", {
318
+ inputs: {
319
+ domain: { description: "A domain", required: true },
320
+ },
321
+ })
322
+ .addJob("job1", {
323
+ steps: [{ name: "Do something", run: "exit 0" }],
324
+ });
325
+ (0, vitest_1.expect)(await workflow.compile()).toMatchSnapshot();
326
+ });
294
327
  (0, vitest_1.it)("allows setting environment on a job", async () => {
295
328
  const workflow = new workflow_1.Workflow("Job Environment");
296
329
  workflow.on("push").addJob("job1", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@factorialco/gat",
3
- "version": "3.5.0",
3
+ "version": "3.10.1",
4
4
  "description": "Write your GitHub Actions workflows using TypeScript",
5
5
  "bin": {
6
6
  "gat": "dist/cli.js"
@@ -22,7 +22,7 @@
22
22
  "format:check": "prettier --check ."
23
23
  },
24
24
  "author": "David Morcillo <david.morcillo@factorial.co>",
25
- "license": "ISC",
25
+ "license": "MIT",
26
26
  "devDependencies": {
27
27
  "@swc/core": "^1.3.14",
28
28
  "@types/js-yaml": "^4.0.5",