@intentius/chant-lexicon-forgejo 0.124.13 → 0.124.15
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/components/ci-jobs.d.ts +38 -0
- package/dist/components/ci-jobs.d.ts.map +1 -0
- package/dist/components/generate-op-pipeline.d.ts +1 -1
- package/dist/components/generate-op-pipeline.d.ts.map +1 -1
- package/dist/components/generate-op-waves-pipeline.d.ts +1 -1
- package/dist/components/generate-op-waves-pipeline.d.ts.map +1 -1
- package/dist/components/generate-pipeline.d.ts +1 -1
- package/dist/components/generate-pipeline.d.ts.map +1 -1
- package/dist/integrity.json +2 -2
- package/dist/manifest.json +1 -1
- package/package.json +3 -3
- package/src/components/ci-jobs.ts +80 -0
- package/src/components/generate-op-pipeline.ts +6 -49
- package/src/components/generate-op-waves-pipeline.ts +12 -57
- package/src/components/generate-pipeline.ts +2 -6
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Forgejo dialect of the three generated pipelines (#3765). Each forgejo
|
|
3
|
+
* generator builds github's document and hands it here: action refs and
|
|
4
|
+
* runner labels rewritten ({@link transformWorkflowObject}), `permissions:`
|
|
5
|
+
* dropped (the runner reads none), and a job's `environment:` dropped with a
|
|
6
|
+
* header note naming it, since Forgejo Actions has no environments.
|
|
7
|
+
*/
|
|
8
|
+
import type { GithubOpPipelineDoc } from "@intentius/chant-lexicon-github/components/generate-op-pipeline";
|
|
9
|
+
import { type ForgejoDialectOptions } from "../dialect.js";
|
|
10
|
+
/** Apply the Forgejo dialect to one section of a pipeline doc. */
|
|
11
|
+
export declare function forgejoize(value: Record<string, unknown>, dialect: ForgejoDialectOptions): Record<string, unknown>;
|
|
12
|
+
/**
|
|
13
|
+
* Strip each job's `environment:` (#2257). Forgejo Actions has no
|
|
14
|
+
* environments, so the key would read as a deployment gate and hold nothing
|
|
15
|
+
* back. Dropped here rather than in the dialect's own `DROPPED_KEYS`, so it
|
|
16
|
+
* touches the generated pipelines alone and leaves every other document the
|
|
17
|
+
* dialect transforms as it is.
|
|
18
|
+
*/
|
|
19
|
+
export declare function withoutEnvironment(jobsDoc: Record<string, unknown>): Record<string, unknown>;
|
|
20
|
+
/** The header of an Op's workflow whose environment gate did not survive the crossing. */
|
|
21
|
+
export declare function droppedEnvironmentHeader(environmentName: string): string[];
|
|
22
|
+
/** The header of an Op waves workflow, naming each wave whose environment was dropped as `wave -> environment`. */
|
|
23
|
+
export declare function droppedWaveEnvironmentsHeader(dropped: readonly string[]): string[];
|
|
24
|
+
/**
|
|
25
|
+
* The token a Forgejo job uses for what the job token cannot do, such as
|
|
26
|
+
* dispatching a workflow: the `CHANT_FORGE_TOKEN` secret, a token with the
|
|
27
|
+
* `write:repository` scope.
|
|
28
|
+
*/
|
|
29
|
+
export declare const FORGE_TOKEN_ENV: {
|
|
30
|
+
CHANT_FORGE_TOKEN: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* A github workflow document under the Forgejo dialect: every section
|
|
34
|
+
* transformed, each job's `environment:` dropped, `permissions:` emptied, and
|
|
35
|
+
* `header` above it when given.
|
|
36
|
+
*/
|
|
37
|
+
export declare function forgejoWorkflowDoc(doc: GithubOpPipelineDoc, dialect: ForgejoDialectOptions, header?: string[]): GithubOpPipelineDoc;
|
|
38
|
+
//# sourceMappingURL=ci-jobs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci-jobs.d.ts","sourceRoot":"","sources":["../../src/components/ci-jobs.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iEAAiE,CAAC;AAC3G,OAAO,EAA2B,KAAK,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEjF,kEAAkE;AAClE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAElH;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQ5F;AAED,0FAA0F;AAC1F,wBAAgB,wBAAwB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ1E;AAED,mHAAmH;AACnH,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAOlF;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe;IAAK,iBAAiB;CAAqC,CAAC;AAExF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,mBAAmB,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,mBAAmB,CAYnI"}
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
* sibling Op's job receives.
|
|
87
87
|
*/
|
|
88
88
|
import type { ComponentPipelineOptions, OpPipelineResult, ScheduledOpSpec } from "@intentius/chant/lexicon";
|
|
89
|
-
import {
|
|
89
|
+
import type { ForgejoDialectOptions } from "../dialect.js";
|
|
90
90
|
/**
|
|
91
91
|
* Synthesize one `.forgejo/workflows/*.yml` per scheduled Op. Reuses github's
|
|
92
92
|
* trigger/job structure ({@link buildGithubOpPipelineDocs}) — its `setup`-step
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-op-pipeline.d.ts","sourceRoot":"","sources":["../../src/components/generate-op-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsFG;
|
|
1
|
+
{"version":3,"file":"generate-op-pipeline.d.ts","sourceRoot":"","sources":["../../src/components/generate-op-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsFG;AAMH,OAAO,KAAK,EACV,wBAAwB,EACxB,gBAAgB,EAChB,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGxD;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,eAAe,EAAE,EACtB,OAAO,GAAE,wBAA6B,EACtC,cAAc,GAAE,qBAA0B,GACzC,gBAAgB,CAmBlB"}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import type { OpWavesSpec } from "@intentius/chant/op/op-waves";
|
|
19
19
|
import type { OpWavesPipelineOptions, OpWavesPipelineResult } from "@intentius/chant/lexicon";
|
|
20
|
-
import {
|
|
20
|
+
import type { ForgejoDialectOptions } from "../dialect.js";
|
|
21
21
|
/** Render an Op waves spec as one Forgejo Actions workflow, `<name>.yml`. */
|
|
22
22
|
export declare function generateForgejoOpWavesPipeline(spec: OpWavesSpec, options: OpWavesPipelineOptions, dialectOptions?: ForgejoDialectOptions): OpWavesPipelineResult;
|
|
23
23
|
//# sourceMappingURL=generate-op-waves-pipeline.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-op-waves-pipeline.d.ts","sourceRoot":"","sources":["../../src/components/generate-op-waves-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC9F,OAAO,
|
|
1
|
+
{"version":3,"file":"generate-op-waves-pipeline.d.ts","sourceRoot":"","sources":["../../src/components/generate-op-waves-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC9F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGxD,6EAA6E;AAC7E,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,sBAAsB,EAC/B,cAAc,GAAE,qBAA0B,GACzC,qBAAqB,CAgBvB"}
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
*/
|
|
26
26
|
import type { DriverComponent } from "@intentius/chant/components/driver";
|
|
27
27
|
import type { ComponentPipelineOptions, ComponentPipelineResult } from "@intentius/chant/lexicon";
|
|
28
|
-
import {
|
|
28
|
+
import type { ForgejoDialectOptions } from "../dialect.js";
|
|
29
29
|
/**
|
|
30
30
|
* Synthesize a `.forgejo/workflows/*.yml` pipeline from a set of components.
|
|
31
31
|
* Reuses github's job/`needs:`/artifact structure ({@link buildGithubPipelineDoc}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-pipeline.d.ts","sourceRoot":"","sources":["../../src/components/generate-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAOH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,KAAK,EACV,wBAAwB,EACxB,uBAAuB,EACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,
|
|
1
|
+
{"version":3,"file":"generate-pipeline.d.ts","sourceRoot":"","sources":["../../src/components/generate-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAOH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,KAAK,EACV,wBAAwB,EACxB,uBAAuB,EACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGxD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,eAAe,EAAE,EAC7B,OAAO,GAAE,wBAA6B,EACtC,cAAc,GAAE,qBAA0B,GACzC,uBAAuB,CAsBzB"}
|
package/dist/integrity.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "sha256",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
4
|
+
"manifest.json": "ee4a8346762f955023d0dec3fd0db793b88d4a9a47f8343fd70d671bc747261e",
|
|
5
5
|
"meta.json": "44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",
|
|
6
6
|
"types/index.d.ts": "66204549b2a864ab5489e3f02c1878e73ab4b3c9d938cfb480b66f71543a43de",
|
|
7
7
|
"rules/delegate-to-github.ts": "1060cda40f4b73d6cca3ba3fa13b80b4886147d4034c88584c2d80c5510dbe5e",
|
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
"rules/wfj011.ts": "fcb8bf6685d744af20ad804ce929488257995c74b9a3353b2eacae3768d1c83e",
|
|
10
10
|
"skills/chant-forgejo.md": "f28d7fb69fb1cfd992496ef41fda0ea5ccd54a29b84ea1c501a44f6a3992c4d5"
|
|
11
11
|
},
|
|
12
|
-
"composite": "
|
|
12
|
+
"composite": "571a078b5d84f95c5d8c19aabee54d82895f4e1fd01f9eec855a0b84b7971bb6"
|
|
13
13
|
}
|
package/dist/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant-lexicon-forgejo",
|
|
3
|
-
"version": "0.124.
|
|
3
|
+
"version": "0.124.15",
|
|
4
4
|
"description": "Forgejo / Codeberg / Gitea Actions lexicon for chant — a thin GitHub Actions dialect",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://intentius.io/chant",
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
56
|
"zod": "^4.3.6",
|
|
57
|
-
"@intentius/chant": "^0.124.
|
|
58
|
-
"@intentius/chant-lexicon-github": "^0.124.
|
|
57
|
+
"@intentius/chant": "^0.124.15",
|
|
58
|
+
"@intentius/chant-lexicon-github": "^0.124.15"
|
|
59
59
|
},
|
|
60
60
|
"scripts": {
|
|
61
61
|
"generate": "tsx src/codegen/generate-cli.ts",
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Forgejo dialect of the three generated pipelines (#3765). Each forgejo
|
|
3
|
+
* generator builds github's document and hands it here: action refs and
|
|
4
|
+
* runner labels rewritten ({@link transformWorkflowObject}), `permissions:`
|
|
5
|
+
* dropped (the runner reads none), and a job's `environment:` dropped with a
|
|
6
|
+
* header note naming it, since Forgejo Actions has no environments.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { githubSecret } from "@intentius/chant/ci-jobs";
|
|
10
|
+
import type { GithubOpPipelineDoc } from "@intentius/chant-lexicon-github/components/generate-op-pipeline";
|
|
11
|
+
import { transformWorkflowObject, type ForgejoDialectOptions } from "../dialect";
|
|
12
|
+
|
|
13
|
+
/** Apply the Forgejo dialect to one section of a pipeline doc. */
|
|
14
|
+
export function forgejoize(value: Record<string, unknown>, dialect: ForgejoDialectOptions): Record<string, unknown> {
|
|
15
|
+
return transformWorkflowObject(value, dialect).value as Record<string, unknown>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Strip each job's `environment:` (#2257). Forgejo Actions has no
|
|
20
|
+
* environments, so the key would read as a deployment gate and hold nothing
|
|
21
|
+
* back. Dropped here rather than in the dialect's own `DROPPED_KEYS`, so it
|
|
22
|
+
* touches the generated pipelines alone and leaves every other document the
|
|
23
|
+
* dialect transforms as it is.
|
|
24
|
+
*/
|
|
25
|
+
export function withoutEnvironment(jobsDoc: Record<string, unknown>): Record<string, unknown> {
|
|
26
|
+
return Object.fromEntries(
|
|
27
|
+
Object.entries(jobsDoc).map(([jobName, job]) => {
|
|
28
|
+
if (typeof job !== "object" || job === null || !("environment" in job)) return [jobName, job];
|
|
29
|
+
const { environment: _dropped, ...rest } = job as Record<string, unknown>;
|
|
30
|
+
return [jobName, rest];
|
|
31
|
+
}),
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** The header of an Op's workflow whose environment gate did not survive the crossing. */
|
|
36
|
+
export function droppedEnvironmentHeader(environmentName: string): string[] {
|
|
37
|
+
return [
|
|
38
|
+
`# chant dropped \`environment: ${environmentName}\` from this workflow: Forgejo Actions has no`,
|
|
39
|
+
"# environments, so there is no protection rule, required reviewer or wait timer for the key to",
|
|
40
|
+
"# name. This job is not held back by anything on the forge. What still stops the apply is chant's",
|
|
41
|
+
"# own gate: the run records a pending fact on the chant/lifecycle branch and ends, and `chant",
|
|
42
|
+
"# approve <op> <gate>` is what lets the next run through.",
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** The header of an Op waves workflow, naming each wave whose environment was dropped as `wave -> environment`. */
|
|
47
|
+
export function droppedWaveEnvironmentsHeader(dropped: readonly string[]): string[] {
|
|
48
|
+
return [
|
|
49
|
+
`# chant dropped the environment of each of these waves: ${dropped.join(", ")}.`,
|
|
50
|
+
"# Forgejo Actions has no environments, so nothing on the forge holds these jobs.",
|
|
51
|
+
"# Each wave's own chant gate does: it records a pending fact on chant/lifecycle",
|
|
52
|
+
"# and the wave exits 3 until `chant approve` approves its set digest.",
|
|
53
|
+
];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The token a Forgejo job uses for what the job token cannot do, such as
|
|
58
|
+
* dispatching a workflow: the `CHANT_FORGE_TOKEN` secret, a token with the
|
|
59
|
+
* `write:repository` scope.
|
|
60
|
+
*/
|
|
61
|
+
export const FORGE_TOKEN_ENV = { CHANT_FORGE_TOKEN: githubSecret("CHANT_FORGE_TOKEN") };
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* A github workflow document under the Forgejo dialect: every section
|
|
65
|
+
* transformed, each job's `environment:` dropped, `permissions:` emptied, and
|
|
66
|
+
* `header` above it when given.
|
|
67
|
+
*/
|
|
68
|
+
export function forgejoWorkflowDoc(doc: GithubOpPipelineDoc, dialect: ForgejoDialectOptions, header?: string[]): GithubOpPipelineDoc {
|
|
69
|
+
return {
|
|
70
|
+
...(header ? { header } : {}),
|
|
71
|
+
// Forgejo Actions reads `name:` as GitHub does (#2601).
|
|
72
|
+
...(doc.name ? { name: doc.name } : {}),
|
|
73
|
+
on: forgejoize(doc.on, dialect),
|
|
74
|
+
...(doc.env ? { env: forgejoize(doc.env, dialect) } : {}),
|
|
75
|
+
concurrency: forgejoize(doc.concurrency, dialect),
|
|
76
|
+
permissions: {},
|
|
77
|
+
jobsDoc: forgejoize(withoutEnvironment(doc.jobsDoc), dialect),
|
|
78
|
+
...(doc.gatedNoticeDoc ? { gatedNoticeDoc: forgejoize(doc.gatedNoticeDoc, dialect) } : {}),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
@@ -89,47 +89,14 @@
|
|
|
89
89
|
import {
|
|
90
90
|
buildGithubOpPipelineDocs,
|
|
91
91
|
emitOpPipelineYAML,
|
|
92
|
-
type GithubOpPipelineDoc,
|
|
93
92
|
} from "@intentius/chant-lexicon-github/components/generate-op-pipeline";
|
|
94
93
|
import type {
|
|
95
94
|
ComponentPipelineOptions,
|
|
96
95
|
OpPipelineResult,
|
|
97
96
|
ScheduledOpSpec,
|
|
98
97
|
} from "@intentius/chant/lexicon";
|
|
99
|
-
import {
|
|
100
|
-
|
|
101
|
-
/** Apply the Forgejo dialect to one section of a pipeline doc. */
|
|
102
|
-
function forgejoize(value: Record<string, unknown>, dialect: ForgejoDialectOptions): Record<string, unknown> {
|
|
103
|
-
return transformWorkflowObject(value, dialect).value as Record<string, unknown>;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Strip the job-level `environment:` github emitted (#2257). Forgejo Actions
|
|
108
|
-
* has no environments, so the key would read as a deployment gate and hold
|
|
109
|
-
* nothing back. Dropped from the rebuilt doc rather than from the dialect's
|
|
110
|
-
* own `DROPPED_KEYS`, so this touches the Op generator alone and leaves every
|
|
111
|
-
* other document the dialect transforms exactly as it emits today.
|
|
112
|
-
*/
|
|
113
|
-
function withoutEnvironment(jobsDoc: Record<string, unknown>): Record<string, unknown> {
|
|
114
|
-
return Object.fromEntries(
|
|
115
|
-
Object.entries(jobsDoc).map(([jobName, job]) => {
|
|
116
|
-
if (typeof job !== "object" || job === null || !("environment" in job)) return [jobName, job];
|
|
117
|
-
const { environment: _dropped, ...rest } = job as Record<string, unknown>;
|
|
118
|
-
return [jobName, rest];
|
|
119
|
-
}),
|
|
120
|
-
);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/** Say in the generated file which environment gate did not survive the crossing. */
|
|
124
|
-
function droppedEnvironmentHeader(environmentName: string): string[] {
|
|
125
|
-
return [
|
|
126
|
-
`# chant dropped \`environment: ${environmentName}\` from this workflow: Forgejo Actions has no`,
|
|
127
|
-
"# environments, so there is no protection rule, required reviewer or wait timer for the key to",
|
|
128
|
-
"# name. This job is not held back by anything on the forge. What still stops the apply is chant's",
|
|
129
|
-
"# own gate: the run records a pending fact on the chant/lifecycle branch and ends, and `chant",
|
|
130
|
-
"# approve <op> <gate>` is what lets the next run through.",
|
|
131
|
-
];
|
|
132
|
-
}
|
|
98
|
+
import type { ForgejoDialectOptions } from "../dialect";
|
|
99
|
+
import { droppedEnvironmentHeader, forgejoWorkflowDoc } from "./ci-jobs";
|
|
133
100
|
|
|
134
101
|
/**
|
|
135
102
|
* Synthesize one `.forgejo/workflows/*.yml` per scheduled Op. Reuses github's
|
|
@@ -156,20 +123,10 @@ export function generateForgejoOpPipeline(
|
|
|
156
123
|
// read its Op's own `environment` off the input by position.
|
|
157
124
|
files: files.map(({ name, doc }, index) => {
|
|
158
125
|
const environment = ops[index].environment;
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
...(doc.name ? { name: doc.name } : {}),
|
|
164
|
-
on: forgejoize(doc.on, dialectOptions),
|
|
165
|
-
...(doc.env ? { env: forgejoize(doc.env, dialectOptions) } : {}),
|
|
166
|
-
concurrency: forgejoize(doc.concurrency, dialectOptions),
|
|
167
|
-
permissions: {},
|
|
168
|
-
jobsDoc: forgejoize(withoutEnvironment(doc.jobsDoc), dialectOptions),
|
|
169
|
-
// The gate-notice job (#3773), dialect applied like the Op's own job.
|
|
170
|
-
...(doc.gatedNoticeDoc ? { gatedNoticeDoc: forgejoize(doc.gatedNoticeDoc, dialectOptions) } : {}),
|
|
171
|
-
};
|
|
172
|
-
return { name, yaml: emitOpPipelineYAML(forgejoDoc) };
|
|
126
|
+
// The Op's name carries over, and the gate-notice job (#3773) takes the
|
|
127
|
+
// dialect like the Op's own job.
|
|
128
|
+
const header = environment ? droppedEnvironmentHeader(environment.name) : undefined;
|
|
129
|
+
return { name, yaml: emitOpPipelineYAML(forgejoWorkflowDoc(doc, dialectOptions, header)) };
|
|
173
130
|
}),
|
|
174
131
|
jobs,
|
|
175
132
|
};
|
|
@@ -17,14 +17,11 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import { buildGithubOpWavesDoc } from "@intentius/chant-lexicon-github/components/generate-op-waves-pipeline";
|
|
20
|
-
import { emitOpPipelineYAML
|
|
20
|
+
import { emitOpPipelineYAML } from "@intentius/chant-lexicon-github/components/generate-op-pipeline";
|
|
21
21
|
import type { OpWavesSpec } from "@intentius/chant/op/op-waves";
|
|
22
22
|
import type { OpWavesPipelineOptions, OpWavesPipelineResult } from "@intentius/chant/lexicon";
|
|
23
|
-
import {
|
|
24
|
-
|
|
25
|
-
function forgejoize(value: Record<string, unknown>, dialect: ForgejoDialectOptions): Record<string, unknown> {
|
|
26
|
-
return transformWorkflowObject(value, dialect).value as Record<string, unknown>;
|
|
27
|
-
}
|
|
23
|
+
import type { ForgejoDialectOptions } from "../dialect";
|
|
24
|
+
import { droppedWaveEnvironmentsHeader, FORGE_TOKEN_ENV, forgejoWorkflowDoc } from "./ci-jobs";
|
|
28
25
|
|
|
29
26
|
/** Render an Op waves spec as one Forgejo Actions workflow, `<name>.yml`. */
|
|
30
27
|
export function generateForgejoOpWavesPipeline(
|
|
@@ -33,60 +30,18 @@ export function generateForgejoOpWavesPipeline(
|
|
|
33
30
|
dialectOptions: ForgejoDialectOptions = {},
|
|
34
31
|
): OpWavesPipelineResult {
|
|
35
32
|
const { doc, jobs, resumeDoc, plansDoc } = buildGithubOpWavesDoc(spec, options);
|
|
36
|
-
const jobsDoc = Object.fromEntries(
|
|
37
|
-
Object.entries(doc.jobsDoc).map(([name, job]) => {
|
|
38
|
-
const { environment: _dropped, ...rest } = job as Record<string, unknown>;
|
|
39
|
-
return [name, rest];
|
|
40
|
-
}),
|
|
41
|
-
);
|
|
42
33
|
const dropped = spec.waves.filter((w) => w.environment).map((w) => `${w.name} -> ${w.environment!.name}`);
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
? {
|
|
46
|
-
header: [
|
|
47
|
-
`# chant dropped the environment of each of these waves: ${dropped.join(", ")}.`,
|
|
48
|
-
"# Forgejo Actions has no environments, so nothing on the forge holds these jobs.",
|
|
49
|
-
"# Each wave's own chant gate does: it records a pending fact on chant/lifecycle",
|
|
50
|
-
"# and the wave exits 3 until `chant approve` approves its set digest.",
|
|
51
|
-
],
|
|
52
|
-
}
|
|
53
|
-
: {}),
|
|
54
|
-
name: doc.name,
|
|
55
|
-
on: forgejoize(doc.on, dialectOptions),
|
|
56
|
-
...(doc.env ? { env: forgejoize(doc.env, dialectOptions) } : {}),
|
|
57
|
-
concurrency: forgejoize(doc.concurrency, dialectOptions),
|
|
58
|
-
permissions: {},
|
|
59
|
-
jobsDoc: forgejoize(jobsDoc, dialectOptions),
|
|
60
|
-
};
|
|
61
|
-
const files = [{ name: `${spec.name}.yml`, yaml: emitOpPipelineYAML(forgejoDoc) }];
|
|
34
|
+
const header = dropped.length > 0 ? droppedWaveEnvironmentsHeader(dropped) : undefined;
|
|
35
|
+
const files = [{ name: `${spec.name}.yml`, yaml: emitOpPipelineYAML(forgejoWorkflowDoc(doc, dialectOptions, header)) }];
|
|
62
36
|
if (resumeDoc) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
37
|
+
// Forgejo has no API to re-run a run, so resume dispatches the workflow
|
|
38
|
+
// again, with a token that may.
|
|
39
|
+
const resume = forgejoWorkflowDoc(resumeDoc, dialectOptions);
|
|
40
|
+
for (const job of Object.values(resume.jobsDoc) as Array<{ steps: Array<Record<string, unknown>> }>) {
|
|
41
|
+
for (const step of job.steps) if (step.env) step.env = { ...FORGE_TOKEN_ENV };
|
|
66
42
|
}
|
|
67
|
-
files.push({
|
|
68
|
-
name: `${spec.name}-resume.yml`,
|
|
69
|
-
yaml: emitOpPipelineYAML({
|
|
70
|
-
name: resumeDoc.name!,
|
|
71
|
-
on: forgejoize(resumeDoc.on, dialectOptions),
|
|
72
|
-
concurrency: forgejoize(resumeDoc.concurrency, dialectOptions),
|
|
73
|
-
permissions: {},
|
|
74
|
-
jobsDoc: resumeJobs,
|
|
75
|
-
}),
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
if (plansDoc) {
|
|
79
|
-
files.push({
|
|
80
|
-
name: `${spec.name}-plans.yml`,
|
|
81
|
-
yaml: emitOpPipelineYAML({
|
|
82
|
-
name: plansDoc.name!,
|
|
83
|
-
on: forgejoize(plansDoc.on, dialectOptions),
|
|
84
|
-
...(plansDoc.env ? { env: forgejoize(plansDoc.env, dialectOptions) } : {}),
|
|
85
|
-
concurrency: forgejoize(plansDoc.concurrency, dialectOptions),
|
|
86
|
-
permissions: {},
|
|
87
|
-
jobsDoc: forgejoize(plansDoc.jobsDoc, dialectOptions),
|
|
88
|
-
}),
|
|
89
|
-
});
|
|
43
|
+
files.push({ name: `${spec.name}-resume.yml`, yaml: emitOpPipelineYAML(resume) });
|
|
90
44
|
}
|
|
45
|
+
if (plansDoc) files.push({ name: `${spec.name}-plans.yml`, yaml: emitOpPipelineYAML(forgejoWorkflowDoc(plansDoc, dialectOptions)) });
|
|
91
46
|
return { files, jobs };
|
|
92
47
|
}
|
|
@@ -34,12 +34,8 @@ import type {
|
|
|
34
34
|
ComponentPipelineOptions,
|
|
35
35
|
ComponentPipelineResult,
|
|
36
36
|
} from "@intentius/chant/lexicon";
|
|
37
|
-
import {
|
|
38
|
-
|
|
39
|
-
/** Apply the Forgejo dialect to one section of the pipeline doc. */
|
|
40
|
-
function forgejoize(value: Record<string, unknown>, dialect: ForgejoDialectOptions): Record<string, unknown> {
|
|
41
|
-
return transformWorkflowObject(value, dialect).value as Record<string, unknown>;
|
|
42
|
-
}
|
|
37
|
+
import type { ForgejoDialectOptions } from "../dialect";
|
|
38
|
+
import { forgejoize } from "./ci-jobs";
|
|
43
39
|
|
|
44
40
|
/**
|
|
45
41
|
* Synthesize a `.forgejo/workflows/*.yml` pipeline from a set of components.
|