@factorialco/gat 0.0.2 → 0.0.5

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/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  import { Workflow } from "./workflow";
2
- import { RunStep, UseStep, ConcurrencyGroup, JobOptions, Matrix, Service } from "./job";
3
- export { Workflow, RunStep, UseStep, ConcurrencyGroup, JobOptions, Matrix, Service, };
2
+ import { ConcurrencyGroup, JobOptions, Matrix, Service } from "./job";
3
+ import { RunStep, UseStep, BaseStep } from "./step";
4
+ export { Workflow, RunStep, UseStep, BaseStep, ConcurrencyGroup, JobOptions, Matrix, Service, };
package/dist/job.d.ts CHANGED
@@ -1,73 +1,3 @@
1
- declare type Step = RunStep | {
2
- [Name in ActionName]: UseStep<Name>;
3
- }[ActionName];
4
- interface BaseStep {
5
- id?: string;
6
- name?: string;
7
- env?: Record<string, string>;
8
- ifExpression?: string;
9
- workingDirectory?: string;
10
- }
11
- export interface RunStep extends BaseStep {
12
- run: string;
13
- }
14
- declare type ActionName = "actions/checkout@v3" | "actions/setup-node@v3" | "actions/upload-artifact@v3" | "actions/download-artifact@v3" | "ruby/setup-ruby@v1" | "dorny/paths-filter@v2" | "tespkg/actions-cache@v1" | "prewk/s3-cp-action@v2" | "chromaui/action@v1" | "rtCamp/action-slack-notify@v2" | "factorialco/delta-action@v3.0.0" | "factorialco/test-summary-action@v1.2.0";
15
- export interface UseStep<T extends ActionName> extends BaseStep {
16
- uses: T;
17
- with?: StepOptions<T>;
18
- }
19
- declare type StepOptions<T extends ActionName> = T extends "actions/checkout@v3" ? {
20
- ref?: string;
21
- "fetch-depth"?: number;
22
- } : T extends "actions/setup-node@v3" ? {
23
- "node-version": string;
24
- } : T extends "actions/upload-artifact@v3" ? {
25
- name: string;
26
- path: string;
27
- } : T extends "ruby/setup-ruby@v1" ? {
28
- "ruby-version": string;
29
- "cache-version"?: number;
30
- "bundler-cache"?: boolean;
31
- "working-directory"?: string;
32
- } : T extends "dorny/paths-filter@v2" ? {
33
- filters: string;
34
- } : T extends "tespkg/actions-cache@v1" ? {
35
- endpoint: string;
36
- region: string;
37
- bucket: string;
38
- accessKey: string;
39
- secretKey: string;
40
- insecure: string;
41
- "use-fallback": boolean;
42
- path: string;
43
- key: string;
44
- "restore-keys": string;
45
- } : T extends "prewk/s3-cp-action@v2" ? {
46
- source: string;
47
- dest: string;
48
- aws_s3_endpoint: string;
49
- aws_region: string;
50
- aws_access_key_id: string;
51
- aws_secret_access_key: string;
52
- } : T extends "chromaui/action@v1" ? {
53
- workingDir: string;
54
- token: string;
55
- projectToken: string;
56
- exitZeroOnChanges?: boolean;
57
- autoAcceptChanges?: boolean;
58
- } : T extends "factorialco/delta-action@v3.0.0" ? {
59
- engine: "eslint" | "semgrep" | "rubocop";
60
- main: string;
61
- branch: string;
62
- head_ref: string;
63
- forkpoint: string;
64
- monorepo_prefix: "frontend" | "backend";
65
- } : T extends "factorialco/test-summary-action@v1.2.0" ? {
66
- engine: "jest" | "rspec";
67
- reportFile: string;
68
- sha: string;
69
- } : never;
70
- declare type Runner = "standard" | "beefy" | "large" | "release" | "standard-aws" | "beefy-aws" | "large-aws" | "release-aws";
71
1
  export interface ConcurrencyGroup {
72
2
  groupSuffix: string;
73
3
  cancelPrevious: boolean;
@@ -75,9 +5,9 @@ export interface ConcurrencyGroup {
75
5
  export interface Matrix {
76
6
  elements: Array<{
77
7
  id: string;
78
- options: any[];
8
+ options: Array<string | number | boolean>;
79
9
  }>;
80
- extra?: Array<Record<string, any>>;
10
+ extra?: Array<Record<string, string | number | boolean>>;
81
11
  }
82
12
  export interface Service {
83
13
  image: string;
@@ -89,11 +19,11 @@ export interface Service {
89
19
  ports: string[];
90
20
  options?: string;
91
21
  }
92
- export interface JobOptions<JobNames = never> {
22
+ export interface JobOptions<Step, Runner, Name> {
93
23
  ifExpression?: string;
94
24
  runsOn?: Runner;
95
25
  timeout?: number;
96
- dependsOn?: Array<JobNames>;
26
+ dependsOn?: Array<Name>;
97
27
  services?: Record<string, Service>;
98
28
  env?: Record<string, string>;
99
29
  concurrency?: ConcurrencyGroup;
@@ -101,8 +31,7 @@ export interface JobOptions<JobNames = never> {
101
31
  steps: Step[];
102
32
  outputs?: Record<string, string>;
103
33
  }
104
- export interface Job<JobNames> {
34
+ export interface Job<Step, Runner, Name> {
105
35
  name: string;
106
- options: JobOptions<JobNames>;
36
+ options: JobOptions<Step, Runner, Name>;
107
37
  }
108
- export {};
package/dist/step.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ export interface BaseStep {
2
+ id?: string;
3
+ name?: string;
4
+ env?: Record<string, string>;
5
+ ifExpression?: string;
6
+ workingDirectory?: string;
7
+ }
8
+ export declare type Step = RunStep | UseStep;
9
+ export interface RunStep extends BaseStep {
10
+ run: string;
11
+ }
12
+ export interface UseStep extends BaseStep {
13
+ uses: string;
14
+ with?: Record<string, string | number | boolean>;
15
+ }
package/dist/step.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,5 +1,7 @@
1
1
  import { Job, JobOptions } from "./job";
2
2
  import type { Event, EventName, EventOptions } from "./event";
3
+ import { BaseStep, Step } from "./step";
4
+ declare const DEFAULT_RUNNERS: string[];
3
5
  interface DefaultOptions {
4
6
  workingDirectory: string;
5
7
  }
@@ -7,18 +9,19 @@ interface EnvVar {
7
9
  name: string;
8
10
  value: string;
9
11
  }
10
- export declare class Workflow<JobNames = never> {
12
+ export declare class Workflow<JobStep extends BaseStep = Step, Runner = typeof DEFAULT_RUNNERS, JobName = never> {
11
13
  name: string;
12
14
  events: Event[];
13
- jobs: Array<Job<JobNames>>;
15
+ jobs: Array<Job<JobStep, Runner, JobName>>;
14
16
  defaultOptions: DefaultOptions | null;
15
17
  env: EnvVar[];
16
18
  constructor(name: string);
17
19
  on<T extends EventName>(name: T, options?: EventOptions<T>): this;
18
20
  addDefaults(options: DefaultOptions): this;
19
- addJob<JobName extends string>(name: JobName, options: JobOptions<JobNames>): Workflow<JobNames | JobName>;
20
- addMergeGatekeeperJob(dependsOn: Array<JobNames>): this;
21
- setEnv(name: string, value: any): this;
21
+ addJob<T extends string>(name: T, options: JobOptions<JobStep, Runner, JobName>): Workflow<JobStep, Runner, JobName | T>;
22
+ setEnv(name: string, value: string): this;
23
+ defaultRunner(): string;
24
+ private assignRunner;
22
25
  compile(): string;
23
26
  }
24
27
  export {};
package/dist/workflow.js CHANGED
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.Workflow = void 0;
7
7
  const yaml_1 = require("yaml");
8
8
  const kebabCase_1 = __importDefault(require("lodash/kebabCase"));
9
+ const DEFAULT_RUNNERS = ["ubuntu-22.04"];
9
10
  class Workflow {
10
11
  constructor(name) {
11
12
  this.name = name;
@@ -26,31 +27,18 @@ class Workflow {
26
27
  this.jobs = [...this.jobs, { name, options }];
27
28
  return this;
28
29
  }
29
- addMergeGatekeeperJob(dependsOn) {
30
- this.jobs = [
31
- ...this.jobs,
32
- {
33
- name: "merge_gatekeeper",
34
- options: {
35
- ifExpression: "${{ always() }}",
36
- dependsOn,
37
- steps: [
38
- {
39
- workingDirectory: "${{ github.workspace }}",
40
- run: dependsOn
41
- .map((jobName) => `\${{ needs.${jobName}.result == 'success' || needs.${jobName}.result == 'skipped' }}`)
42
- .join(" && "),
43
- },
44
- ],
45
- },
46
- },
47
- ];
48
- return this;
49
- }
50
30
  setEnv(name, value) {
51
31
  this.env = [...this.env, { name, value }];
52
32
  return this;
53
33
  }
34
+ defaultRunner() {
35
+ return "ubuntu-22.04";
36
+ }
37
+ assignRunner(runsOn) {
38
+ const runnerName = runsOn ?? this.defaultRunner();
39
+ const isSelfHosted = !DEFAULT_RUNNERS.includes(runnerName);
40
+ return isSelfHosted ? ["self-hosted", runnerName] : runnerName;
41
+ }
54
42
  compile() {
55
43
  const result = {
56
44
  name: this.name,
@@ -69,7 +57,7 @@ class Workflow {
69
57
  name,
70
58
  {
71
59
  if: ifExpression,
72
- "runs-on": ["self-hosted", `${runsOn ?? "standard-aws"}-runner`],
60
+ "runs-on": this.assignRunner(runsOn),
73
61
  "timeout-minutes": timeout ?? 15,
74
62
  needs: dependsOn,
75
63
  services,
@@ -8,11 +8,9 @@ const workflow_1 = require("./workflow");
8
8
  workflow
9
9
  .on("pull_request", { types: ["opened"] })
10
10
  .addJob("job1", {
11
- runsOn: "standard",
12
11
  steps: [{ name: "Do something", run: "exit 0" }],
13
12
  })
14
13
  .addJob("job2", {
15
- runsOn: "standard",
16
14
  steps: [{ name: "Do something else", run: "exit 0" }],
17
15
  dependsOn: ["job1"],
18
16
  });
@@ -24,7 +22,6 @@ const workflow_1 = require("./workflow");
24
22
  .on("push", { branches: ["main"] })
25
23
  .on("pull_request", { types: ["opened"] })
26
24
  .addJob("job1", {
27
- runsOn: "standard",
28
25
  steps: [{ name: "Do something", run: "exit 0" }],
29
26
  });
30
27
  (0, vitest_1.expect)(workflow.compile()).toMatchSnapshot();
@@ -37,7 +34,6 @@ const workflow_1 = require("./workflow");
37
34
  workingDirectory: "frontend",
38
35
  })
39
36
  .addJob("job1", {
40
- runsOn: "standard",
41
37
  steps: [{ name: "Do something", run: "exit 0" }],
42
38
  });
43
39
  (0, vitest_1.expect)(workflow.compile()).toMatchSnapshot();
@@ -47,9 +43,8 @@ const workflow_1 = require("./workflow");
47
43
  workflow
48
44
  .on("push")
49
45
  .setEnv("NODE_VERSION", "16")
50
- .setEnv("ENABLED", true)
46
+ .setEnv("ENABLED", "true")
51
47
  .addJob("job1", {
52
- runsOn: "standard",
53
48
  steps: [
54
49
  {
55
50
  name: "Do something",
@@ -59,29 +54,9 @@ const workflow_1 = require("./workflow");
59
54
  });
60
55
  (0, vitest_1.expect)(workflow.compile()).toMatchSnapshot();
61
56
  });
62
- (0, vitest_1.it)("allows uses steps", () => {
63
- const workflow = new workflow_1.Workflow("Uses steps");
64
- workflow
65
- .on("push")
66
- .setEnv("NODE_VERSION", "16")
67
- .setEnv("ENABLED", true)
68
- .addJob("job1", {
69
- runsOn: "standard",
70
- steps: [
71
- {
72
- uses: "actions/checkout@v3",
73
- with: {
74
- ref: "main",
75
- },
76
- },
77
- ],
78
- });
79
- (0, vitest_1.expect)(workflow.compile()).toMatchSnapshot();
80
- });
81
57
  (0, vitest_1.it)("allows using a concurrency group", () => {
82
58
  const workflow = new workflow_1.Workflow("Concurrency group");
83
59
  workflow.on("push").addJob("job1", {
84
- runsOn: "standard",
85
60
  concurrency: {
86
61
  groupSuffix: "foo",
87
62
  cancelPrevious: true,
@@ -97,7 +72,6 @@ const workflow_1 = require("./workflow");
97
72
  (0, vitest_1.it)("allows using outputs", () => {
98
73
  const workflow = new workflow_1.Workflow("Using outputs");
99
74
  workflow.on("push").addJob("job1", {
100
- runsOn: "standard",
101
75
  steps: [
102
76
  {
103
77
  id: "random-number",
@@ -152,4 +126,40 @@ const workflow_1 = require("./workflow");
152
126
  });
153
127
  (0, vitest_1.expect)(workflow.compile()).toMatchSnapshot();
154
128
  });
129
+ (0, vitest_1.it)("allows uses steps", () => {
130
+ const workflow = new workflow_1.Workflow("Uses steps");
131
+ workflow
132
+ .on("push")
133
+ .setEnv("NODE_VERSION", "16")
134
+ .setEnv("ENABLED", "true")
135
+ .addJob("job1", {
136
+ steps: [
137
+ {
138
+ uses: "actions/checkout@v3",
139
+ with: {
140
+ ref: "main",
141
+ },
142
+ },
143
+ ],
144
+ });
145
+ (0, vitest_1.expect)(workflow.compile()).toMatchSnapshot();
146
+ });
147
+ (0, vitest_1.it)("allows custom types in a workflow", () => {
148
+ const workflow = new workflow_1.Workflow("With custom types");
149
+ workflow.on("push").addJob("job1", {
150
+ runsOn: "standard-runner",
151
+ steps: [
152
+ {
153
+ run: "echo 'Do something'",
154
+ },
155
+ {
156
+ uses: "custom-action",
157
+ with: {
158
+ foo: "bar",
159
+ },
160
+ },
161
+ ],
162
+ });
163
+ (0, vitest_1.expect)(workflow.compile()).toMatchSnapshot();
164
+ });
155
165
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@factorialco/gat",
3
- "version": "0.0.2",
3
+ "version": "0.0.5",
4
4
  "description": "TODO",
5
5
  "bin": {
6
6
  "gat": "dist/cli.js"
@@ -15,13 +15,21 @@
15
15
  "prepare": "npm run build",
16
16
  "prepublishOnly": "vitest run",
17
17
  "test": "vitest",
18
- "coverage": "vitest run --coverage"
18
+ "coverage": "vitest run --coverage",
19
+ "lint": "eslint src/**/*.ts",
20
+ "format": "prettier --write .",
21
+ "format:check": "prettier --check ."
19
22
  },
20
23
  "author": "David Morcillo <david.morcillo@factorial.co>",
21
24
  "license": "ISC",
22
25
  "devDependencies": {
23
26
  "@types/lodash": "^4.14.184",
27
+ "@typescript-eslint/eslint-plugin": "^5.35.1",
28
+ "@typescript-eslint/parser": "^5.35.1",
24
29
  "commander": "^9.4.0",
30
+ "eslint": "^8.23.0",
31
+ "eslint-config-prettier": "^8.5.0",
32
+ "prettier": "2.7.1",
25
33
  "typescript": "^4.7.4",
26
34
  "vitest": "^0.18.1"
27
35
  },