@intentius/chant-lexicon-forgejo 0.124.27 → 0.124.28

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/actions.d.ts CHANGED
@@ -24,10 +24,23 @@ export declare const DEFAULT_ACTIONS_ROOT = "https://code.forgejo.org";
24
24
  export type ActionTarget = {
25
25
  kind: "mirror";
26
26
  repo: string;
27
+ /**
28
+ * The newest major version that runs on a Forgejo runner, when an older
29
+ * one is needed: a ref asking for a later major is rewritten to this one.
30
+ */
31
+ newest?: string;
27
32
  } | {
28
33
  kind: "url";
29
34
  url: string;
30
35
  };
36
+ /**
37
+ * `upload-artifact` and `download-artifact` v4 and later use `@actions/artifact`
38
+ * v2, which refuses to run on GitHub Enterprise Server, and a Forgejo runner
39
+ * presents itself to an action as one: the step fails with "@actions/artifact
40
+ * v2.0.0+, upload-artifact@v4+ and download-artifact@v4+ are not currently
41
+ * supported on GHES" (#4008). v3 talks to the artifact service Forgejo serves.
42
+ */
43
+ export declare const FORGEJO_ARTIFACT_VERSION = "v3";
31
44
  /** Built-in mapping of GitHub action `owner/repo` → Forgejo-resolvable target. */
32
45
  export declare const KNOWN_ACTIONS: Record<string, ActionTarget>;
33
46
  export interface ActionResolveOptions {
@@ -1 +1 @@
1
- {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,6BAA6B,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3F,kFAAkF;AAClF,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAkBtD,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACnC,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,mBAAmB;IAClC,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAaD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,GAAG,mBAAmB,CA2BrG"}
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,6BAA6B,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GACpB;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GACD;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C,kFAAkF;AAClF,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAkBtD,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACnC,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,mBAAmB;IAClC,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAaD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,GAAG,mBAAmB,CA4BrG"}
@@ -1 +1 @@
1
- {"version":3,"file":"dialect.d.ts","sourceRoot":"","sources":["../src/dialect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,OAAO,EAAsC,KAAK,UAAU,EAAE,MAAM,6BAA6B,CAAC;AA4ClG;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKxD,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACpC,mFAAmF;IACnF,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,sEAAsE;IACtE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAClC,iEAAiE;IACjE,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAwFD,MAAM,WAAW,qBAAqB;IACpC,qEAAqE;IACrE,KAAK,EAAE,OAAO,CAAC;IACf,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE,qBAA0B,GAClC,qBAAqB,CAKvB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EACjC,OAAO,GAAE,qBAA0B,GAClC,oBAAoB,CAWtB"}
1
+ {"version":3,"file":"dialect.d.ts","sourceRoot":"","sources":["../src/dialect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,OAAO,EAAsC,KAAK,UAAU,EAAE,MAAM,6BAA6B,CAAC;AA4ClG;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKxD,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACpC,mFAAmF;IACnF,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,sEAAsE;IACtE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAClC,iEAAiE;IACjE,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AA4GD,MAAM,WAAW,qBAAqB;IACpC,qEAAqE;IACrE,KAAK,EAAE,OAAO,CAAC;IACf,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE,qBAA0B,GAClC,qBAAqB,CAKvB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EACjC,OAAO,GAAE,qBAA0B,GAClC,oBAAoB,CAWtB"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "algorithm": "sha256",
3
3
  "artifacts": {
4
- "manifest.json": "03614474340b227ee29e077bd5ba73ea6d197dc7048b3c668420d94176a1c3d4",
4
+ "manifest.json": "46e2c8c8be7c7056342dd04f39489292a7b68af45e73087dbbf70ef968420c05",
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": "d22822447c0e75457838451a166f817efdb3f22bf77b63ce476e3e50496f2d0b"
12
+ "composite": "2ce8fb0d3c767dc7b1a80d6f4280549d2eda2b8e4582067eca557eb29c394d8c"
13
13
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forgejo",
3
- "version": "0.124.27",
3
+ "version": "0.124.28",
4
4
  "chantVersion": ">=0.1.0",
5
5
  "namespace": "Forgejo",
6
6
  "intrinsics": [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant-lexicon-forgejo",
3
- "version": "0.124.27",
3
+ "version": "0.124.28",
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.27",
58
- "@intentius/chant-lexicon-github": "^0.124.27"
57
+ "@intentius/chant": "^0.124.28",
58
+ "@intentius/chant-lexicon-github": "^0.124.28"
59
59
  },
60
60
  "scripts": {
61
61
  "generate": "tsx src/codegen/generate-cli.ts",
@@ -9,20 +9,27 @@ describe("resolveActionRef — mapped actions", () => {
9
9
  });
10
10
 
11
11
  test("rewrites the common actions/* set", () => {
12
- for (const name of [
13
- "actions/setup-node",
14
- "actions/setup-go",
15
- "actions/setup-python",
16
- "actions/cache",
17
- "actions/upload-artifact",
18
- "actions/download-artifact",
19
- ]) {
12
+ for (const name of ["actions/setup-node", "actions/setup-go", "actions/setup-python", "actions/cache"]) {
20
13
  const { rewritten, warning } = resolveActionRef(`${name}@v4`);
21
14
  expect(rewritten).toBe(`${DEFAULT_ACTIONS_ROOT}/${name}@v4`);
22
15
  expect(warning).toBeUndefined();
23
16
  }
24
17
  });
25
18
 
19
+ test("moves upload-artifact and download-artifact v4 and later to v3, which runs on a Forgejo runner (#4008)", () => {
20
+ for (const name of ["actions/upload-artifact", "actions/download-artifact"]) {
21
+ for (const v of ["v4", "v4.6.2", "v5"]) {
22
+ const { rewritten, warning } = resolveActionRef(`${name}@${v}`);
23
+ expect(rewritten).toBe(`${DEFAULT_ACTIONS_ROOT}/${name}@v3`);
24
+ expect(warning).toBeUndefined();
25
+ }
26
+ // v3 and earlier, a SHA and a branch are the author's to choose.
27
+ for (const v of ["v3", "v2.3.1", "0123456789abcdef0123456789abcdef01234567", "main"]) {
28
+ expect(resolveActionRef(`${name}@${v}`).rewritten).toBe(`${DEFAULT_ACTIONS_ROOT}/${name}@${v}`);
29
+ }
30
+ }
31
+ });
32
+
26
33
  test("pins docker/* to a full GitHub URL, independent of the actions root", () => {
27
34
  const { rewritten, warning } = resolveActionRef("docker/build-push-action@v5", {
28
35
  actionsRoot: "https://example.test",
package/src/actions.ts CHANGED
@@ -23,7 +23,26 @@ export const DEFAULT_ACTIONS_ROOT = "https://code.forgejo.org";
23
23
  * - `url`: an absolute base URL — independent of the actions root (used for
24
24
  * actions not carried by the Forgejo mirror, e.g. `docker/*`).
25
25
  */
26
- export type ActionTarget = { kind: "mirror"; repo: string } | { kind: "url"; url: string };
26
+ export type ActionTarget =
27
+ | {
28
+ kind: "mirror";
29
+ repo: string;
30
+ /**
31
+ * The newest major version that runs on a Forgejo runner, when an older
32
+ * one is needed: a ref asking for a later major is rewritten to this one.
33
+ */
34
+ newest?: string;
35
+ }
36
+ | { kind: "url"; url: string };
37
+
38
+ /**
39
+ * `upload-artifact` and `download-artifact` v4 and later use `@actions/artifact`
40
+ * v2, which refuses to run on GitHub Enterprise Server, and a Forgejo runner
41
+ * presents itself to an action as one: the step fails with "@actions/artifact
42
+ * v2.0.0+, upload-artifact@v4+ and download-artifact@v4+ are not currently
43
+ * supported on GHES" (#4008). v3 talks to the artifact service Forgejo serves.
44
+ */
45
+ export const FORGEJO_ARTIFACT_VERSION = "v3";
27
46
 
28
47
  /** Built-in mapping of GitHub action `owner/repo` → Forgejo-resolvable target. */
29
48
  export const KNOWN_ACTIONS: Record<string, ActionTarget> = {
@@ -35,8 +54,8 @@ export const KNOWN_ACTIONS: Record<string, ActionTarget> = {
35
54
  "actions/setup-java": { kind: "mirror", repo: "actions/setup-java" },
36
55
  "actions/setup-dotnet": { kind: "mirror", repo: "actions/setup-dotnet" },
37
56
  "actions/cache": { kind: "mirror", repo: "actions/cache" },
38
- "actions/upload-artifact": { kind: "mirror", repo: "actions/upload-artifact" },
39
- "actions/download-artifact": { kind: "mirror", repo: "actions/download-artifact" },
57
+ "actions/upload-artifact": { kind: "mirror", repo: "actions/upload-artifact", newest: FORGEJO_ARTIFACT_VERSION },
58
+ "actions/download-artifact": { kind: "mirror", repo: "actions/download-artifact", newest: FORGEJO_ARTIFACT_VERSION },
40
59
  // docker/* — not on the Forgejo mirror; pin to the full GitHub URL, which
41
60
  // Forgejo runners can fetch directly.
42
61
  "docker/build-push-action": { kind: "url", url: "https://github.com/docker/build-push-action" },
@@ -99,10 +118,22 @@ export function resolveActionRef(ref: string, options: ActionResolveOptions = {}
99
118
 
100
119
  const base = target.kind === "mirror" ? `${root}/${target.repo}` : target.url;
101
120
  const withSubpath = subpath ? `${base}/${subpath}` : base;
102
- const rewritten = version ? `${withSubpath}@${version}` : withSubpath;
121
+ const pinned = target.kind === "mirror" && target.newest && laterMajor(version, target.newest) ? target.newest : version;
122
+ const rewritten = pinned ? `${withSubpath}@${pinned}` : withSubpath;
103
123
  return { rewritten };
104
124
  }
105
125
 
126
+ /** Whether `version` (`v4`, `v4.1.0`) names a later major than `newest` (`v3`). A SHA or branch never does. */
127
+ function laterMajor(version: string, newest: string): boolean {
128
+ const major = (v: string): number | undefined => {
129
+ const m = /^v?(\d+)(?:\.\d+)*$/.exec(v);
130
+ return m ? Number(m[1]) : undefined;
131
+ };
132
+ const a = major(version);
133
+ const b = major(newest);
134
+ return a !== undefined && b !== undefined && a > b;
135
+ }
136
+
106
137
  function unresolvedWarning(ref: string): string {
107
138
  return (
108
139
  `forgejo: unresolved action ref '${ref}' — it has no built-in mapping and won't ` +
@@ -29,12 +29,11 @@ jobs:
29
29
  run: chant components pr-plan --base "$BASE_SHA" --pr "$PR_NUMBER" --env prod --gate pr-apply --output .chant/pr --forge forgejo
30
30
  - name: Keep the plan report
31
31
  if: always()
32
- uses: https://code.forgejo.org/actions/upload-artifact@v4
32
+ uses: https://code.forgejo.org/actions/upload-artifact@v3
33
33
  with:
34
34
  name: chant-pr-plan
35
35
  path: .chant/pr
36
36
  if-no-files-found: ignore
37
- include-hidden-files: true
38
37
  apply:
39
38
  if: github.event_name == 'push'
40
39
  runs-on: docker
@@ -66,9 +65,8 @@ jobs:
66
65
  key: chant-apply-prod-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
67
66
  - name: Keep the apply report
68
67
  if: always()
69
- uses: https://code.forgejo.org/actions/upload-artifact@v4
68
+ uses: https://code.forgejo.org/actions/upload-artifact@v3
70
69
  with:
71
70
  name: chant-pr-apply
72
71
  path: .chant/pr
73
72
  if-no-files-found: ignore
74
- include-hidden-files: true
@@ -33,13 +33,11 @@ jobs:
33
33
  run: chant run wave --spec waves.json --wave 2 --decide
34
34
  - name: Keep wave 2's decision
35
35
  if: always()
36
- uses: https://code.forgejo.org/actions/upload-artifact@v4
36
+ uses: https://code.forgejo.org/actions/upload-artifact@v3
37
37
  with:
38
38
  name: migrations-wave-2-decision
39
39
  path: .chant/op-waves/migrations/wave-2.json
40
40
  if-no-files-found: ignore
41
- include-hidden-files: true
42
- overwrite: true
43
41
  wave-2-prod-us:
44
42
  runs-on:
45
43
  - self-hosted
@@ -57,7 +55,7 @@ jobs:
57
55
  with:
58
56
  fetch-depth: 0
59
57
  - name: Download wave 2's decision
60
- uses: https://code.forgejo.org/actions/download-artifact@v4
58
+ uses: https://code.forgejo.org/actions/download-artifact@v3
61
59
  with:
62
60
  name: migrations-wave-2-decision
63
61
  path: .chant/op-waves/migrations
@@ -73,7 +71,7 @@ jobs:
73
71
  with:
74
72
  fetch-depth: 0
75
73
  - name: Download wave 2's decision
76
- uses: https://code.forgejo.org/actions/download-artifact@v4
74
+ uses: https://code.forgejo.org/actions/download-artifact@v3
77
75
  with:
78
76
  name: migrations-wave-2-decision
79
77
  path: .chant/op-waves/migrations
@@ -12,6 +12,7 @@ import { tmpdir } from "node:os";
12
12
  import { join } from "node:path";
13
13
  import { describe, expect, test } from "vitest";
14
14
  import type { DriverComponent } from "@intentius/chant/components/driver";
15
+ import { generateGithubPipeline } from "@intentius/chant-lexicon-github/components/generate-pipeline";
15
16
  import { generateForgejoPipeline } from "./generate-pipeline";
16
17
 
17
18
  const ESTATE: DriverComponent[] = [
@@ -51,6 +52,18 @@ describe("the Forgejo pull-request workflow", () => {
51
52
  expect(result.yaml).toContain("--forge forgejo --require-review --resume .chant/pr-resume/pr-apply.json");
52
53
  });
53
54
 
55
+ test("keeps its reports with upload-artifact v3, the version a Forgejo runner runs, while GitHub keeps v4 (#4008)", () => {
56
+ // v4 refuses a runner that reads as GitHub Enterprise Server, as Forgejo's does.
57
+ expect(result.yaml.match(/uses: https:\/\/code\.forgejo\.org\/actions\/upload-artifact@v3$/gm)).toHaveLength(2);
58
+ expect(result.yaml).not.toMatch(/(upload|download)-artifact@v4/);
59
+ // v3 uploads hidden files with no input asking for it, so .chant/pr is still kept.
60
+ expect(result.yaml).not.toContain("include-hidden-files");
61
+ expect(result.yaml).toContain("path: .chant/pr");
62
+ const github = generateGithubPipeline(ESTATE, { env: "prod", prLoop: {} }).yaml;
63
+ expect(github.match(/uses: actions\/upload-artifact@v4$/gm)).toHaveLength(2);
64
+ expect(github).toContain("include-hidden-files: true");
65
+ });
66
+
54
67
  test.skipIf(!hasActionlint())("passes actionlint, less the runner label and actions by URL", () => {
55
68
  const dir = mkdtempSync(join(tmpdir(), "chant-actionlint-"));
56
69
  try {
package/src/dialect.ts CHANGED
@@ -166,9 +166,29 @@ function transformValue(value: unknown, ctx: TransformCtx): unknown {
166
166
  }
167
167
  result[key] = transformValue(v, ctx);
168
168
  }
169
+ dropV4OnlyArtifactInputs(result);
169
170
  return result;
170
171
  }
171
172
 
173
+ /**
174
+ * The inputs only `upload-artifact` v4 has, which a step moved to v3
175
+ * (`FORGEJO_ARTIFACT_VERSION`, #4008) loses. v3 always uploads hidden files,
176
+ * so dropping `include-hidden-files` keeps what the step uploads; and a v3
177
+ * artifact is not immutable, so a second upload under one name needs no
178
+ * `overwrite`.
179
+ */
180
+ const V4_ONLY_UPLOAD_INPUTS = new Set(["include-hidden-files", "overwrite"]);
181
+
182
+ /** Drop {@link V4_ONLY_UPLOAD_INPUTS} from a step that uses `upload-artifact@v3`. */
183
+ function dropV4OnlyArtifactInputs(step: Record<string, unknown>): void {
184
+ const uses = step.uses;
185
+ const withs = step.with;
186
+ if (typeof uses !== "string" || !/\/actions\/upload-artifact@v3$/.test(uses)) return;
187
+ if (withs === null || typeof withs !== "object" || Array.isArray(withs)) return;
188
+ const kept = Object.fromEntries(Object.entries(withs as Record<string, unknown>).filter(([k]) => !V4_ONLY_UPLOAD_INPUTS.has(toKebabCase(k))));
189
+ step.with = kept;
190
+ }
191
+
172
192
  /** Shallow-clone a Declarable, replacing its `props` with a transformed copy. */
173
193
  function cloneDeclarable(entity: Declarable, ctx: TransformCtx): Declarable {
174
194
  const descriptors = Object.getOwnPropertyDescriptors(entity);