@intentius/chant-lexicon-gitlab 0.0.18 → 0.0.24
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/integrity.json +4 -4
- package/dist/manifest.json +1 -1
- package/dist/skills/{gitlab-ci-patterns.md → chant-gitlab-patterns.md} +1 -1
- package/dist/skills/chant-gitlab.md +10 -10
- package/package.json +20 -2
- package/src/composites/composites.test.ts +93 -0
- package/src/composites/docker-build.ts +8 -3
- package/src/composites/node-pipeline.ts +14 -7
- package/src/composites/python-pipeline.ts +14 -7
- package/src/composites/review-app.ts +11 -5
- package/src/plugin.ts +87 -671
- package/src/skills/{gitlab-ci-patterns.md → chant-gitlab-patterns.md} +1 -1
- package/src/skills/chant-gitlab.md +502 -0
package/dist/integrity.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "xxhash64",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
4
|
+
"manifest.json": "5879275be7cad0fa",
|
|
5
5
|
"meta.json": "c663c6c63748a9d0",
|
|
6
6
|
"types/index.d.ts": "64e65524615be023",
|
|
7
7
|
"rules/missing-stage.ts": "6d5379e74209a735",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"rules/wgl027.ts": "ea7928f37607a583",
|
|
29
29
|
"rules/wgl014.ts": "6248a852888e8028",
|
|
30
30
|
"rules/yaml-helpers.ts": "3e414c7affe56728",
|
|
31
|
-
"skills/chant-gitlab.md": "
|
|
32
|
-
"skills/gitlab-
|
|
31
|
+
"skills/chant-gitlab.md": "fe29add147305b7e",
|
|
32
|
+
"skills/chant-gitlab-patterns.md": "efb54bd8ea52071b"
|
|
33
33
|
},
|
|
34
|
-
"composite": "
|
|
34
|
+
"composite": "58a5f51312595838"
|
|
35
35
|
}
|
package/dist/manifest.json
CHANGED
|
@@ -8,7 +8,7 @@ user-invocable: true
|
|
|
8
8
|
|
|
9
9
|
## How chant and GitLab CI relate
|
|
10
10
|
|
|
11
|
-
chant is a **synthesis
|
|
11
|
+
chant is a **synthesis compiler** — it compiles TypeScript source files into `.gitlab-ci.yml` (YAML). `chant build` does not call GitLab APIs; synthesis is pure and deterministic. Your job as an agent is to bridge synthesis and deployment:
|
|
12
12
|
|
|
13
13
|
- Use **chant** for: build, lint, diff (local YAML comparison)
|
|
14
14
|
- Use **git + GitLab API** for: push, merge requests, pipeline monitoring, job logs, rollback, and all deployment operations
|
|
@@ -244,7 +244,7 @@ new Job({
|
|
|
244
244
|
|
|
245
245
|
### Environment promotion
|
|
246
246
|
|
|
247
|
-
Deploy through environments in order: dev
|
|
247
|
+
Deploy through environments in order: dev -> staging -> production. Use `rules:` and `when: manual` to gate promotions.
|
|
248
248
|
|
|
249
249
|
### Rollback to a previous deployment
|
|
250
250
|
|
|
@@ -356,11 +356,11 @@ rules:
|
|
|
356
356
|
|
|
357
357
|
### Merged results pipelines
|
|
358
358
|
|
|
359
|
-
Enable in project settings
|
|
359
|
+
Enable in project settings -> CI/CD -> General pipelines -> "Merged results pipelines". These test the result of merging your branch into the target — catching integration issues before merge.
|
|
360
360
|
|
|
361
361
|
### Merge trains
|
|
362
362
|
|
|
363
|
-
Merge trains queue MRs and test each one merged on top of the previous. Enable in project settings
|
|
363
|
+
Merge trains queue MRs and test each one merged on top of the previous. Enable in project settings -> Merge requests -> "Merge trains". Requires merged results pipelines.
|
|
364
364
|
|
|
365
365
|
## Troubleshooting decision tree
|
|
366
366
|
|
|
@@ -373,11 +373,11 @@ curl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
|
|
|
373
373
|
|
|
374
374
|
### Step 2: Branch on status
|
|
375
375
|
|
|
376
|
-
- **`running` / `pending` / `created`**
|
|
377
|
-
- **`failed`**
|
|
378
|
-
- **`success`**
|
|
379
|
-
- **`canceled`**
|
|
380
|
-
- **`skipped`**
|
|
376
|
+
- **`running` / `pending` / `created`** -> Wait. Do not take action while the pipeline is in progress.
|
|
377
|
+
- **`failed`** -> Read the failed job logs (Step 3).
|
|
378
|
+
- **`success`** -> Pipeline is healthy. If behavior is wrong, check job scripts and configuration.
|
|
379
|
+
- **`canceled`** -> Re-run if needed: `curl --request POST ... /pipelines/$PIPELINE_ID/retry`
|
|
380
|
+
- **`skipped`** -> All jobs were filtered out by `rules:`. Check rule conditions.
|
|
381
381
|
|
|
382
382
|
### Step 3: Read failed job logs
|
|
383
383
|
|
|
@@ -413,7 +413,7 @@ curl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
|
|
|
413
413
|
|
|
414
414
|
Variables are resolved in this order (highest priority first):
|
|
415
415
|
1. Job-level `variables:`
|
|
416
|
-
2. Project CI/CD variables (Settings
|
|
416
|
+
2. Project CI/CD variables (Settings -> CI/CD -> Variables)
|
|
417
417
|
3. Group CI/CD variables
|
|
418
418
|
4. Instance CI/CD variables
|
|
419
419
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant-lexicon-gitlab",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.24",
|
|
4
|
+
"description": "GitLab CI lexicon for chant — declarative IaC in TypeScript",
|
|
4
5
|
"license": "Apache-2.0",
|
|
6
|
+
"homepage": "https://intentius.io/chant",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/intentius/chant.git",
|
|
10
|
+
"directory": "lexicons/gitlab"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/intentius/chant/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"infrastructure-as-code",
|
|
17
|
+
"iac",
|
|
18
|
+
"typescript",
|
|
19
|
+
"gitlab",
|
|
20
|
+
"gitlab-ci",
|
|
21
|
+
"chant"
|
|
22
|
+
],
|
|
5
23
|
"type": "module",
|
|
6
24
|
"files": [
|
|
7
25
|
"src/",
|
|
@@ -25,7 +43,7 @@
|
|
|
25
43
|
"prepack": "bun run generate && bun run bundle && bun run validate"
|
|
26
44
|
},
|
|
27
45
|
"dependencies": {
|
|
28
|
-
"@intentius/chant": "0.0.
|
|
46
|
+
"@intentius/chant": "0.0.22"
|
|
29
47
|
},
|
|
30
48
|
"devDependencies": {
|
|
31
49
|
"typescript": "^5.9.3"
|
|
@@ -138,6 +138,16 @@ describe("DockerBuild", () => {
|
|
|
138
138
|
const props = (instance.build as any).props;
|
|
139
139
|
expect(props.rules).toBeUndefined();
|
|
140
140
|
});
|
|
141
|
+
|
|
142
|
+
test("per-member defaults override build job", () => {
|
|
143
|
+
const instance = DockerBuild({
|
|
144
|
+
defaults: {
|
|
145
|
+
build: { tags: ["docker-runner"] },
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
const props = (instance.build as any).props;
|
|
149
|
+
expect(props.tags).toEqual(["docker-runner"]);
|
|
150
|
+
});
|
|
141
151
|
});
|
|
142
152
|
|
|
143
153
|
// ---------------------------------------------------------------------------
|
|
@@ -287,6 +297,36 @@ describe("NodePipeline", () => {
|
|
|
287
297
|
const artProps = (props.artifacts as any).props;
|
|
288
298
|
expect(artProps.when).toBe("always");
|
|
289
299
|
});
|
|
300
|
+
|
|
301
|
+
test("per-member defaults override build job", () => {
|
|
302
|
+
const instance = NodePipeline({
|
|
303
|
+
defaults: {
|
|
304
|
+
build: { tags: ["node-runner"] },
|
|
305
|
+
},
|
|
306
|
+
});
|
|
307
|
+
const props = (instance.build as any).props;
|
|
308
|
+
expect(props.tags).toEqual(["node-runner"]);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
test("per-member defaults override test job", () => {
|
|
312
|
+
const instance = NodePipeline({
|
|
313
|
+
defaults: {
|
|
314
|
+
test: { allow_failure: true },
|
|
315
|
+
},
|
|
316
|
+
});
|
|
317
|
+
const props = (instance.test as any).props;
|
|
318
|
+
expect(props.allow_failure).toBe(true);
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
test("per-member defaults override defaults member", () => {
|
|
322
|
+
const instance = NodePipeline({
|
|
323
|
+
defaults: {
|
|
324
|
+
defaults: { interruptible: true },
|
|
325
|
+
},
|
|
326
|
+
});
|
|
327
|
+
const props = (instance.defaults as any).props;
|
|
328
|
+
expect(props.interruptible).toBe(true);
|
|
329
|
+
});
|
|
290
330
|
});
|
|
291
331
|
|
|
292
332
|
// ---------------------------------------------------------------------------
|
|
@@ -451,6 +491,37 @@ describe("PythonPipeline", () => {
|
|
|
451
491
|
const cacheProps = (defaultProps.cache[0] as any).props;
|
|
452
492
|
expect(cacheProps.policy).toBe("pull-push");
|
|
453
493
|
});
|
|
494
|
+
|
|
495
|
+
test("per-member defaults override test job", () => {
|
|
496
|
+
const instance = PythonPipeline({
|
|
497
|
+
defaults: {
|
|
498
|
+
test: { tags: ["python-runner"] },
|
|
499
|
+
},
|
|
500
|
+
});
|
|
501
|
+
const props = (instance.test as any).props;
|
|
502
|
+
expect(props.tags).toEqual(["python-runner"]);
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
test("per-member defaults override lint job", () => {
|
|
506
|
+
const instance = PythonPipeline({
|
|
507
|
+
defaults: {
|
|
508
|
+
lint: { allow_failure: true },
|
|
509
|
+
},
|
|
510
|
+
});
|
|
511
|
+
const members = instance.members as any;
|
|
512
|
+
const props = (members.lint as any).props;
|
|
513
|
+
expect(props.allow_failure).toBe(true);
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
test("per-member defaults override defaults member", () => {
|
|
517
|
+
const instance = PythonPipeline({
|
|
518
|
+
defaults: {
|
|
519
|
+
defaults: { interruptible: true },
|
|
520
|
+
},
|
|
521
|
+
});
|
|
522
|
+
const props = (instance.defaults as any).props;
|
|
523
|
+
expect(props.interruptible).toBe(true);
|
|
524
|
+
});
|
|
454
525
|
});
|
|
455
526
|
|
|
456
527
|
// ---------------------------------------------------------------------------
|
|
@@ -609,4 +680,26 @@ describe("ReviewApp", () => {
|
|
|
609
680
|
const envProps = (props.environment as any).props;
|
|
610
681
|
expect(envProps.url).toContain("$CI_ENVIRONMENT_SLUG");
|
|
611
682
|
});
|
|
683
|
+
|
|
684
|
+
test("per-member defaults override deploy job", () => {
|
|
685
|
+
const instance = ReviewApp({
|
|
686
|
+
...baseProps,
|
|
687
|
+
defaults: {
|
|
688
|
+
deploy: { tags: ["deploy-runner"] },
|
|
689
|
+
},
|
|
690
|
+
});
|
|
691
|
+
const props = (instance.deploy as any).props;
|
|
692
|
+
expect(props.tags).toEqual(["deploy-runner"]);
|
|
693
|
+
});
|
|
694
|
+
|
|
695
|
+
test("per-member defaults override stop job", () => {
|
|
696
|
+
const instance = ReviewApp({
|
|
697
|
+
...baseProps,
|
|
698
|
+
defaults: {
|
|
699
|
+
stop: { allow_failure: true },
|
|
700
|
+
},
|
|
701
|
+
});
|
|
702
|
+
const props = (instance.stop as any).props;
|
|
703
|
+
expect(props.allow_failure).toBe(true);
|
|
704
|
+
});
|
|
612
705
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Composite } from "@intentius/chant";
|
|
1
|
+
import { Composite, mergeDefaults } from "@intentius/chant";
|
|
2
2
|
import { Job, Image, Service, Rule } from "../generated";
|
|
3
3
|
import { CI } from "../variables";
|
|
4
4
|
|
|
@@ -23,6 +23,10 @@ export interface DockerBuildProps {
|
|
|
23
23
|
rules?: InstanceType<typeof Rule>[];
|
|
24
24
|
/** Docker version. Default: "27" */
|
|
25
25
|
dockerVersion?: string;
|
|
26
|
+
/** Per-member defaults for customizing the build job. */
|
|
27
|
+
defaults?: {
|
|
28
|
+
build?: Partial<ConstructorParameters<typeof Job>[0]>;
|
|
29
|
+
};
|
|
26
30
|
}
|
|
27
31
|
|
|
28
32
|
export const DockerBuild = Composite<DockerBuildProps>((props) => {
|
|
@@ -37,6 +41,7 @@ export const DockerBuild = Composite<DockerBuildProps>((props) => {
|
|
|
37
41
|
buildArgs,
|
|
38
42
|
rules,
|
|
39
43
|
dockerVersion = "27",
|
|
44
|
+
defaults: defs,
|
|
40
45
|
} = props;
|
|
41
46
|
|
|
42
47
|
const buildArgFlags = buildArgs
|
|
@@ -63,7 +68,7 @@ export const DockerBuild = Composite<DockerBuildProps>((props) => {
|
|
|
63
68
|
);
|
|
64
69
|
}
|
|
65
70
|
|
|
66
|
-
const build = new Job({
|
|
71
|
+
const build = new Job(mergeDefaults({
|
|
67
72
|
stage,
|
|
68
73
|
image: new Image({ name: `docker:${dockerVersion}-cli` }),
|
|
69
74
|
services: [new Service({ name: `docker:${dockerVersion}-dind`, alias: "docker" })],
|
|
@@ -75,7 +80,7 @@ export const DockerBuild = Composite<DockerBuildProps>((props) => {
|
|
|
75
80
|
],
|
|
76
81
|
script,
|
|
77
82
|
...(rules ? { rules } : {}),
|
|
78
|
-
});
|
|
83
|
+
}, defs?.build));
|
|
79
84
|
|
|
80
85
|
return { build };
|
|
81
86
|
}, "DockerBuild");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Composite, withDefaults } from "@intentius/chant";
|
|
1
|
+
import { Composite, mergeDefaults, withDefaults } from "@intentius/chant";
|
|
2
2
|
import { Job, Default, Image, Cache, Artifacts } from "../generated";
|
|
3
3
|
import { CI } from "../variables";
|
|
4
4
|
|
|
@@ -17,6 +17,12 @@ export interface NodePipelineProps {
|
|
|
17
17
|
artifactExpiry?: string;
|
|
18
18
|
/** Override auto-detected install command */
|
|
19
19
|
installCommand?: string;
|
|
20
|
+
/** Per-member defaults for customizing the generated resources. */
|
|
21
|
+
defaults?: {
|
|
22
|
+
defaults?: Partial<ConstructorParameters<typeof Default>[0]>;
|
|
23
|
+
build?: Partial<ConstructorParameters<typeof Job>[0]>;
|
|
24
|
+
test?: Partial<ConstructorParameters<typeof Job>[0]>;
|
|
25
|
+
};
|
|
20
26
|
}
|
|
21
27
|
|
|
22
28
|
const cacheConfig = {
|
|
@@ -52,6 +58,7 @@ export const NodePipeline = Composite<NodePipelineProps>((props) => {
|
|
|
52
58
|
buildArtifactPaths = ["dist/"],
|
|
53
59
|
artifactExpiry = "1 hour",
|
|
54
60
|
installCommand,
|
|
61
|
+
defaults: defs,
|
|
55
62
|
} = props;
|
|
56
63
|
|
|
57
64
|
const pm = cacheConfig[packageManager];
|
|
@@ -68,13 +75,13 @@ export const NodePipeline = Composite<NodePipelineProps>((props) => {
|
|
|
68
75
|
|
|
69
76
|
const variables = Object.keys(pm.envVars).length > 0 ? pm.envVars : undefined;
|
|
70
77
|
|
|
71
|
-
const defaults = new Default({
|
|
78
|
+
const defaults = new Default(mergeDefaults({
|
|
72
79
|
image: nodeImage,
|
|
73
80
|
cache: [cache],
|
|
74
81
|
...(variables ? {} : {}),
|
|
75
|
-
});
|
|
82
|
+
}, defs?.defaults));
|
|
76
83
|
|
|
77
|
-
const build = new Job({
|
|
84
|
+
const build = new Job(mergeDefaults({
|
|
78
85
|
stage: "build",
|
|
79
86
|
script: [install, `${run} ${buildScript}`],
|
|
80
87
|
artifacts: new Artifacts({
|
|
@@ -82,9 +89,9 @@ export const NodePipeline = Composite<NodePipelineProps>((props) => {
|
|
|
82
89
|
expire_in: artifactExpiry,
|
|
83
90
|
}),
|
|
84
91
|
...(variables ? { variables } : {}),
|
|
85
|
-
});
|
|
92
|
+
}, defs?.build));
|
|
86
93
|
|
|
87
|
-
const test = new Job({
|
|
94
|
+
const test = new Job(mergeDefaults({
|
|
88
95
|
stage: "test",
|
|
89
96
|
script: [install, `${run} ${testScript}`],
|
|
90
97
|
artifacts: new Artifacts({
|
|
@@ -92,7 +99,7 @@ export const NodePipeline = Composite<NodePipelineProps>((props) => {
|
|
|
92
99
|
when: "always",
|
|
93
100
|
}),
|
|
94
101
|
...(variables ? { variables } : {}),
|
|
95
|
-
});
|
|
102
|
+
}, defs?.test));
|
|
96
103
|
|
|
97
104
|
return { defaults, build, test };
|
|
98
105
|
}, "NodePipeline");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Composite } from "@intentius/chant";
|
|
1
|
+
import { Composite, mergeDefaults } from "@intentius/chant";
|
|
2
2
|
import { Job, Default, Image, Cache, Artifacts } from "../generated";
|
|
3
3
|
import { CI } from "../variables";
|
|
4
4
|
|
|
@@ -13,6 +13,12 @@ export interface PythonPipelineProps {
|
|
|
13
13
|
requirementsFile?: string;
|
|
14
14
|
/** Use poetry instead of pip. Default: false */
|
|
15
15
|
usePoetry?: boolean;
|
|
16
|
+
/** Per-member defaults for customizing the generated resources. */
|
|
17
|
+
defaults?: {
|
|
18
|
+
defaults?: Partial<ConstructorParameters<typeof Default>[0]>;
|
|
19
|
+
test?: Partial<ConstructorParameters<typeof Job>[0]>;
|
|
20
|
+
lint?: Partial<ConstructorParameters<typeof Job>[0]>;
|
|
21
|
+
};
|
|
16
22
|
}
|
|
17
23
|
|
|
18
24
|
export const PythonPipeline = Composite<PythonPipelineProps>((props) => {
|
|
@@ -22,6 +28,7 @@ export const PythonPipeline = Composite<PythonPipelineProps>((props) => {
|
|
|
22
28
|
lintCommand = "ruff check .",
|
|
23
29
|
requirementsFile = "requirements.txt",
|
|
24
30
|
usePoetry = false,
|
|
31
|
+
defaults: defs,
|
|
25
32
|
} = props;
|
|
26
33
|
|
|
27
34
|
const pythonImage = new Image({ name: `python:${pythonVersion}-slim` });
|
|
@@ -42,13 +49,13 @@ export const PythonPipeline = Composite<PythonPipelineProps>((props) => {
|
|
|
42
49
|
|
|
43
50
|
const activateStep = usePoetry ? "source .venv/bin/activate" : "source .venv/bin/activate";
|
|
44
51
|
|
|
45
|
-
const defaults = new Default({
|
|
52
|
+
const defaults = new Default(mergeDefaults({
|
|
46
53
|
image: pythonImage,
|
|
47
54
|
cache: [cache],
|
|
48
55
|
before_script: [...installSteps],
|
|
49
|
-
});
|
|
56
|
+
}, defs?.defaults));
|
|
50
57
|
|
|
51
|
-
const test = new Job({
|
|
58
|
+
const test = new Job(mergeDefaults({
|
|
52
59
|
stage: "test",
|
|
53
60
|
variables: { PIP_CACHE_DIR: `${CI.ProjectDir}/.pip-cache` },
|
|
54
61
|
script: [activateStep, testCommand],
|
|
@@ -56,15 +63,15 @@ export const PythonPipeline = Composite<PythonPipelineProps>((props) => {
|
|
|
56
63
|
reports: { junit: "report.xml" },
|
|
57
64
|
when: "always",
|
|
58
65
|
}),
|
|
59
|
-
});
|
|
66
|
+
}, defs?.test));
|
|
60
67
|
|
|
61
68
|
const lint =
|
|
62
69
|
lintCommand !== null
|
|
63
|
-
? new Job({
|
|
70
|
+
? new Job(mergeDefaults({
|
|
64
71
|
stage: "test",
|
|
65
72
|
variables: { PIP_CACHE_DIR: `${CI.ProjectDir}/.pip-cache` },
|
|
66
73
|
script: [activateStep, lintCommand],
|
|
67
|
-
})
|
|
74
|
+
}, defs?.lint))
|
|
68
75
|
: undefined;
|
|
69
76
|
|
|
70
77
|
if (lint) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Composite } from "@intentius/chant";
|
|
1
|
+
import { Composite, mergeDefaults } from "@intentius/chant";
|
|
2
2
|
import { Job, Image, Environment, Rule } from "../generated";
|
|
3
3
|
import { CI } from "../variables";
|
|
4
4
|
|
|
@@ -17,6 +17,11 @@ export interface ReviewAppProps {
|
|
|
17
17
|
image?: InstanceType<typeof Image>;
|
|
18
18
|
/** Job stage. Default: "deploy" */
|
|
19
19
|
stage?: string;
|
|
20
|
+
/** Per-member defaults for customizing the deploy and stop jobs. */
|
|
21
|
+
defaults?: {
|
|
22
|
+
deploy?: Partial<ConstructorParameters<typeof Job>[0]>;
|
|
23
|
+
stop?: Partial<ConstructorParameters<typeof Job>[0]>;
|
|
24
|
+
};
|
|
20
25
|
}
|
|
21
26
|
|
|
22
27
|
export const ReviewApp = Composite<ReviewAppProps>((props) => {
|
|
@@ -28,6 +33,7 @@ export const ReviewApp = Composite<ReviewAppProps>((props) => {
|
|
|
28
33
|
autoStopIn = "1 week",
|
|
29
34
|
image,
|
|
30
35
|
stage = "deploy",
|
|
36
|
+
defaults: defs,
|
|
31
37
|
} = props;
|
|
32
38
|
|
|
33
39
|
const stopJobName = `${name}-stop`;
|
|
@@ -35,7 +41,7 @@ export const ReviewApp = Composite<ReviewAppProps>((props) => {
|
|
|
35
41
|
const deployScriptArr = Array.isArray(deployScript) ? deployScript : [deployScript];
|
|
36
42
|
const stopScriptArr = Array.isArray(stopScript) ? stopScript : [stopScript];
|
|
37
43
|
|
|
38
|
-
const deploy = new Job({
|
|
44
|
+
const deploy = new Job(mergeDefaults({
|
|
39
45
|
stage,
|
|
40
46
|
...(image ? { image } : {}),
|
|
41
47
|
environment: new Environment({
|
|
@@ -46,9 +52,9 @@ export const ReviewApp = Composite<ReviewAppProps>((props) => {
|
|
|
46
52
|
}),
|
|
47
53
|
rules: [new Rule({ if: CI.MergeRequestIid })],
|
|
48
54
|
script: deployScriptArr,
|
|
49
|
-
});
|
|
55
|
+
}, defs?.deploy));
|
|
50
56
|
|
|
51
|
-
const stop = new Job({
|
|
57
|
+
const stop = new Job(mergeDefaults({
|
|
52
58
|
stage,
|
|
53
59
|
...(image ? { image } : {}),
|
|
54
60
|
environment: new Environment({
|
|
@@ -57,7 +63,7 @@ export const ReviewApp = Composite<ReviewAppProps>((props) => {
|
|
|
57
63
|
}),
|
|
58
64
|
rules: [new Rule({ if: CI.MergeRequestIid, when: "manual" })],
|
|
59
65
|
script: stopScriptArr,
|
|
60
|
-
});
|
|
66
|
+
}, defs?.stop));
|
|
61
67
|
|
|
62
68
|
return { deploy, stop };
|
|
63
69
|
}, "ReviewApp");
|