@intentius/chant-lexicon-forgejo 0.49.0 → 0.50.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/components/generate-op-pipeline.d.ts +30 -0
- package/dist/components/generate-op-pipeline.d.ts.map +1 -0
- package/dist/integrity.json +2 -2
- package/dist/manifest.json +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/components/generate-op-pipeline.test.ts +72 -0
- package/src/components/generate-op-pipeline.ts +65 -0
- package/src/plugin.ts +4 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate mode — scheduled Op → Forgejo Actions workflow YAML (#927).
|
|
3
|
+
*
|
|
4
|
+
* The forgejo counterpart to the github Op generator
|
|
5
|
+
* (`@intentius/chant-lexicon-github/components/generate-op-pipeline`, #927),
|
|
6
|
+
* exactly like `./generate-pipeline.ts` is the forgejo counterpart to
|
|
7
|
+
* github's component generator (#969). Reuses github's
|
|
8
|
+
* `buildGithubOpPipelineDocs` to build the same cron-trigger/concurrency/job
|
|
9
|
+
* structure, then applies the Forgejo dialect ({@link transformWorkflowObject})
|
|
10
|
+
* before emitting.
|
|
11
|
+
*
|
|
12
|
+
* One difference from the component generator: Forgejo Actions ignores
|
|
13
|
+
* `permissions:` entirely (the dialect drops it wherever it appears, see
|
|
14
|
+
* ../dialect.ts's `DROPPED_KEYS`), so this omits the section outright rather
|
|
15
|
+
* than emitting a control the runner can't act on. The token a finding-mode
|
|
16
|
+
* needs still rides the trigger step's `env:` (`GH_TOKEN`/`GITHUB_TOKEN`,
|
|
17
|
+
* built by github's generator); actual write access on Forgejo is a property
|
|
18
|
+
* of the runner/token configuration, not the workflow YAML.
|
|
19
|
+
*/
|
|
20
|
+
import type { ComponentPipelineOptions, OpPipelineResult, ScheduledOpSpec } from "@intentius/chant/lexicon";
|
|
21
|
+
import { type ForgejoDialectOptions } from "../dialect.js";
|
|
22
|
+
/**
|
|
23
|
+
* Synthesize one `.forgejo/workflows/*.yml` per scheduled Op. Reuses github's
|
|
24
|
+
* trigger/job structure ({@link buildGithubOpPipelineDocs}), then applies the
|
|
25
|
+
* Forgejo dialect and drops `permissions:` (ignored by the Forgejo runner).
|
|
26
|
+
* Wired into core's Op generate mode via the forgejo lexicon plugin's
|
|
27
|
+
* `generateOpPipeline` (../plugin.ts).
|
|
28
|
+
*/
|
|
29
|
+
export declare function generateForgejoOpPipeline(ops: ScheduledOpSpec[], options?: ComponentPipelineOptions, dialectOptions?: ForgejoDialectOptions): OpPipelineResult;
|
|
30
|
+
//# sourceMappingURL=generate-op-pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-op-pipeline.d.ts","sourceRoot":"","sources":["../../src/components/generate-op-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAOH,OAAO,KAAK,EACV,wBAAwB,EACxB,gBAAgB,EAChB,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAA2B,KAAK,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAOjF;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,eAAe,EAAE,EACtB,OAAO,GAAE,wBAA6B,EACtC,cAAc,GAAE,qBAA0B,GACzC,gBAAgB,CAgBlB"}
|
package/dist/integrity.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "sha256",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
4
|
+
"manifest.json": "f286643dad112fe26479ee4d067f94ff94c45e8d3c5bcbf67c2ad99e62a65d3f",
|
|
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": "a1a560429db736c187e0b34cf8dd9efc6ad771afefcbf6f802d160d3d5274257"
|
|
11
11
|
},
|
|
12
|
-
"composite": "
|
|
12
|
+
"composite": "e450abb18a6de4840867245499c64f4d4b7a7024e6fb6e0180a5ee34f55a5630"
|
|
13
13
|
}
|
package/dist/manifest.json
CHANGED
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAoC,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAoC,MAAM,0BAA0B,CAAC;AAmBhG,eAAO,MAAM,aAAa,EAAE,aAiM3B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant-lexicon-forgejo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.50.0",
|
|
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.
|
|
58
|
-
"@intentius/chant-lexicon-github": "^0.
|
|
57
|
+
"@intentius/chant": "^0.50.0",
|
|
58
|
+
"@intentius/chant-lexicon-github": "^0.50.0"
|
|
59
59
|
},
|
|
60
60
|
"scripts": {
|
|
61
61
|
"generate": "tsx src/codegen/generate-cli.ts",
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for generate mode's scheduled Op → Forgejo Actions workflow YAML
|
|
3
|
+
* synthesis (#927). Mirrors `./generate-pipeline.test.ts`'s style: same
|
|
4
|
+
* trigger/job SHAPE as the github Op generator, plus proof the Forgejo
|
|
5
|
+
* dialect is applied (runner label remapped) and that `permissions:` — a key
|
|
6
|
+
* the Forgejo runner ignores — is dropped rather than emitted.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { describe, test, expect } from "vitest";
|
|
10
|
+
import { parseYAML } from "@intentius/chant/yaml";
|
|
11
|
+
import { generateForgejoOpPipeline } from "./generate-op-pipeline";
|
|
12
|
+
import { generateGithubOpPipeline } from "@intentius/chant-lexicon-github/components/generate-op-pipeline";
|
|
13
|
+
import type { ScheduledOpSpec } from "@intentius/chant/lexicon";
|
|
14
|
+
|
|
15
|
+
interface ParsedJob {
|
|
16
|
+
"runs-on"?: string;
|
|
17
|
+
steps: Array<{ uses?: string; run?: string }>;
|
|
18
|
+
}
|
|
19
|
+
interface ParsedDoc {
|
|
20
|
+
on?: Record<string, unknown>;
|
|
21
|
+
permissions?: Record<string, string>;
|
|
22
|
+
jobs?: Record<string, ParsedJob>;
|
|
23
|
+
}
|
|
24
|
+
function parseFile(yaml: string): ParsedDoc {
|
|
25
|
+
return parseYAML(yaml) as ParsedDoc;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
describe("generateForgejoOpPipeline: structure (github-shaped)", () => {
|
|
29
|
+
test("one file per scheduled Op, each a valid workflow with one job", () => {
|
|
30
|
+
const specs: ScheduledOpSpec[] = [
|
|
31
|
+
{ name: "actions-audit", schedule: "0 6 * * *" },
|
|
32
|
+
{ name: "prod-reconcile", schedule: "0 * * * *", findingMode: "issue" },
|
|
33
|
+
];
|
|
34
|
+
const result = generateForgejoOpPipeline(specs);
|
|
35
|
+
|
|
36
|
+
expect(result.files).toHaveLength(2);
|
|
37
|
+
expect(result.files.map((f) => f.name)).toEqual(["actions-audit.yml", "prod-reconcile.yml"]);
|
|
38
|
+
|
|
39
|
+
const doc = parseFile(result.files[0].yaml);
|
|
40
|
+
expect(doc.on).toEqual({ schedule: [{ cron: "0 6 * * *" }], workflow_dispatch: {} });
|
|
41
|
+
expect(Object.keys(doc.jobs!)).toEqual(["actions-audit"]);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("jobs/schedule/findingMode parity with the github generator (same input, same job list)", () => {
|
|
45
|
+
const specs: ScheduledOpSpec[] = [{ name: "actions-audit", schedule: "0 6 * * *", findingMode: "pull-request" }];
|
|
46
|
+
const fj = generateForgejoOpPipeline(specs);
|
|
47
|
+
const gh = generateGithubOpPipeline(specs);
|
|
48
|
+
expect(fj.jobs).toEqual(gh.jobs);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe("generateForgejoOpPipeline: dialect applied", () => {
|
|
53
|
+
test("runner label ubuntu-latest is remapped to the Forgejo default (docker)", () => {
|
|
54
|
+
const specs: ScheduledOpSpec[] = [{ name: "actions-audit", schedule: "0 6 * * *" }];
|
|
55
|
+
const fjJob = parseFile(generateForgejoOpPipeline(specs).files[0].yaml).jobs!["actions-audit"];
|
|
56
|
+
const ghJob = parseFile(generateGithubOpPipeline(specs).files[0].yaml).jobs!["actions-audit"];
|
|
57
|
+
|
|
58
|
+
expect(fjJob["runs-on"]).toBe("docker");
|
|
59
|
+
expect(ghJob["runs-on"]).toBe("ubuntu-latest");
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("permissions: is dropped — the Forgejo runner ignores it", () => {
|
|
63
|
+
const specs: ScheduledOpSpec[] = [{ name: "prod-reconcile", schedule: "0 * * * *", findingMode: "pull-request" }];
|
|
64
|
+
const fjYaml = generateForgejoOpPipeline(specs).files[0].yaml;
|
|
65
|
+
const ghYaml = generateGithubOpPipeline(specs).files[0].yaml;
|
|
66
|
+
|
|
67
|
+
expect(fjYaml).not.toMatch(/^permissions:/m);
|
|
68
|
+
// The github counterpart, generated from the same spec, does declare it —
|
|
69
|
+
// proving the omission is the dialect, not an accident of the spec.
|
|
70
|
+
expect(ghYaml).toMatch(/^permissions:/m);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate mode — scheduled Op → Forgejo Actions workflow YAML (#927).
|
|
3
|
+
*
|
|
4
|
+
* The forgejo counterpart to the github Op generator
|
|
5
|
+
* (`@intentius/chant-lexicon-github/components/generate-op-pipeline`, #927),
|
|
6
|
+
* exactly like `./generate-pipeline.ts` is the forgejo counterpart to
|
|
7
|
+
* github's component generator (#969). Reuses github's
|
|
8
|
+
* `buildGithubOpPipelineDocs` to build the same cron-trigger/concurrency/job
|
|
9
|
+
* structure, then applies the Forgejo dialect ({@link transformWorkflowObject})
|
|
10
|
+
* before emitting.
|
|
11
|
+
*
|
|
12
|
+
* One difference from the component generator: Forgejo Actions ignores
|
|
13
|
+
* `permissions:` entirely (the dialect drops it wherever it appears, see
|
|
14
|
+
* ../dialect.ts's `DROPPED_KEYS`), so this omits the section outright rather
|
|
15
|
+
* than emitting a control the runner can't act on. The token a finding-mode
|
|
16
|
+
* needs still rides the trigger step's `env:` (`GH_TOKEN`/`GITHUB_TOKEN`,
|
|
17
|
+
* built by github's generator); actual write access on Forgejo is a property
|
|
18
|
+
* of the runner/token configuration, not the workflow YAML.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import {
|
|
22
|
+
buildGithubOpPipelineDocs,
|
|
23
|
+
emitOpPipelineYAML,
|
|
24
|
+
type GithubOpPipelineDoc,
|
|
25
|
+
} from "@intentius/chant-lexicon-github/components/generate-op-pipeline";
|
|
26
|
+
import type {
|
|
27
|
+
ComponentPipelineOptions,
|
|
28
|
+
OpPipelineResult,
|
|
29
|
+
ScheduledOpSpec,
|
|
30
|
+
} from "@intentius/chant/lexicon";
|
|
31
|
+
import { transformWorkflowObject, type ForgejoDialectOptions } from "../dialect";
|
|
32
|
+
|
|
33
|
+
/** Apply the Forgejo dialect to one section of a pipeline doc. */
|
|
34
|
+
function forgejoize(value: Record<string, unknown>, dialect: ForgejoDialectOptions): Record<string, unknown> {
|
|
35
|
+
return transformWorkflowObject(value, dialect).value as Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Synthesize one `.forgejo/workflows/*.yml` per scheduled Op. Reuses github's
|
|
40
|
+
* trigger/job structure ({@link buildGithubOpPipelineDocs}), then applies the
|
|
41
|
+
* Forgejo dialect and drops `permissions:` (ignored by the Forgejo runner).
|
|
42
|
+
* Wired into core's Op generate mode via the forgejo lexicon plugin's
|
|
43
|
+
* `generateOpPipeline` (../plugin.ts).
|
|
44
|
+
*/
|
|
45
|
+
export function generateForgejoOpPipeline(
|
|
46
|
+
ops: ScheduledOpSpec[],
|
|
47
|
+
options: ComponentPipelineOptions = {},
|
|
48
|
+
dialectOptions: ForgejoDialectOptions = {},
|
|
49
|
+
): OpPipelineResult {
|
|
50
|
+
const { files, jobs } = buildGithubOpPipelineDocs(ops, options);
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
files: files.map(({ name, doc }) => {
|
|
54
|
+
const forgejoDoc: GithubOpPipelineDoc = {
|
|
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(doc.jobsDoc, dialectOptions),
|
|
60
|
+
};
|
|
61
|
+
return { name, yaml: emitOpPipelineYAML(forgejoDoc) };
|
|
62
|
+
}),
|
|
63
|
+
jobs,
|
|
64
|
+
};
|
|
65
|
+
}
|
package/src/plugin.ts
CHANGED
|
@@ -18,6 +18,7 @@ import { fileURLToPath } from "url";
|
|
|
18
18
|
import { forgejoSerializer } from "./serializer";
|
|
19
19
|
import { forgejoContextTools } from "./mcp/context-tools";
|
|
20
20
|
import { generateForgejoPipeline } from "./components/generate-pipeline";
|
|
21
|
+
import { generateForgejoOpPipeline } from "./components/generate-op-pipeline";
|
|
21
22
|
import { forgejoLintRules } from "./lint/rules/delegate-to-github";
|
|
22
23
|
import { forgejoCompletions } from "./lsp/completions";
|
|
23
24
|
import { forgejoHover } from "./lsp/hover";
|
|
@@ -37,6 +38,9 @@ export const forgejoPlugin: LexiconPlugin = {
|
|
|
37
38
|
// `uses:` resolution) — see ./components/generate-pipeline.
|
|
38
39
|
generateComponentPipeline: (components, options) => generateForgejoPipeline(components, options),
|
|
39
40
|
|
|
41
|
+
// Generate mode, Op counterpart (#927): scheduled Op → Forgejo Actions workflow.
|
|
42
|
+
generateOpPipeline: (ops, options) => generateForgejoOpPipeline(ops, options),
|
|
43
|
+
|
|
40
44
|
initTemplates(template?: string): InitTemplateSet {
|
|
41
45
|
if (template === "docker-build") {
|
|
42
46
|
return {
|