@intentius/chant-lexicon-docker 0.101.0 → 0.104.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.
@@ -1,7 +1,7 @@
1
- export declare const Service: new (props: Record<string, unknown>, attributes?: Record<string, unknown>) => import("packages/core/src").Declarable & Record<string, string>;
2
- export declare const Volume: new (props: Record<string, unknown>, attributes?: Record<string, unknown>) => import("packages/core/src").Declarable & Record<string, string>;
3
- export declare const Network: new (props: Record<string, unknown>, attributes?: Record<string, unknown>) => import("packages/core/src").Declarable & Record<string, string>;
4
- export declare const DockerConfig: new (props: Record<string, unknown>, attributes?: Record<string, unknown>) => import("packages/core/src").Declarable & Record<string, string>;
5
- export declare const DockerSecret: new (props: Record<string, unknown>, attributes?: Record<string, unknown>) => import("packages/core/src").Declarable & Record<string, string>;
6
- export declare const Dockerfile: new (props: Record<string, unknown>, attributes?: Record<string, unknown>) => import("packages/core/src").Declarable & Record<string, string>;
1
+ export declare const Service: new (props: Record<string, unknown>, attributes?: Record<string, unknown>) => import("@intentius/chant").Declarable & Record<string, string>;
2
+ export declare const Volume: new (props: Record<string, unknown>, attributes?: Record<string, unknown>) => import("@intentius/chant").Declarable & Record<string, string>;
3
+ export declare const Network: new (props: Record<string, unknown>, attributes?: Record<string, unknown>) => import("@intentius/chant").Declarable & Record<string, string>;
4
+ export declare const DockerConfig: new (props: Record<string, unknown>, attributes?: Record<string, unknown>) => import("@intentius/chant").Declarable & Record<string, string>;
5
+ export declare const DockerSecret: new (props: Record<string, unknown>, attributes?: Record<string, unknown>) => import("@intentius/chant").Declarable & Record<string, string>;
6
+ export declare const Dockerfile: new (props: Record<string, unknown>, attributes?: Record<string, unknown>) => import("@intentius/chant").Declarable & Record<string, string>;
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generated/index.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,OAAO,+IAA2D,CAAC;AAChF,eAAO,MAAM,MAAM,+IAA0D,CAAC;AAC9E,eAAO,MAAM,OAAO,+IAA2D,CAAC;AAChF,eAAO,MAAM,YAAY,+IAA0D,CAAC;AACpF,eAAO,MAAM,YAAY,+IAA0D,CAAC;AAEpF,eAAO,MAAM,UAAU,+IAAqD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generated/index.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,OAAO,8IAA2D,CAAC;AAChF,eAAO,MAAM,MAAM,8IAA0D,CAAC;AAC9E,eAAO,MAAM,OAAO,8IAA2D,CAAC;AAChF,eAAO,MAAM,YAAY,8IAA0D,CAAC;AACpF,eAAO,MAAM,YAAY,8IAA0D,CAAC;AAEpF,eAAO,MAAM,UAAU,8IAAqD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/import/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAc,MAAM,gCAAgC,CAAC;AAC7F,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAgD5F;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,cAAc;IACzD,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU;CAOnC;AAED;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,mBAAmB;IACjE,QAAQ,CAAC,EAAE,EAAE,UAAU,GAAG,aAAa,EAAE;CAK1C"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/import/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAc,MAAM,gCAAgC,CAAC;AAC7F,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAgD5F;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,cAAc;IACzD,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAMjC;CACF;AAED;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,mBAAmB;IACjE,QAAQ,CAAC,EAAE,EAAE,UAAU,GAAG,aAAa,EAAE,CAIxC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/import/generator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAoE,MAAM,UAAU,CAAC;AAE3G,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,cAAc;CAuC/C"}
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/import/generator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAoE,MAAM,UAAU,CAAC;AAE3G,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,cAAc,CAsC7C;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/import/parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,KAAK,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAED,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,YAAY,CAAC;AAE7F,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AA0BD;;;GAGG;AACH,qBAAa,YAAY;IACvB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW;CAqEpC;AAED;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY;CA6BnD"}
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/import/parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,KAAK,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAED,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,YAAY,CAAC;AAE7F,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AA0BD;;;GAGG;AACH,qBAAa,YAAY;IACvB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAoElC;CACF;AAED;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,CA4BjD;CACF"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "algorithm": "sha256",
3
3
  "artifacts": {
4
- "manifest.json": "d1dd1b11e3d31c5da985b63fc04b567c81c063af6ac1d4da3d7766c88b740788",
4
+ "manifest.json": "2534a54918f8094a74d73c082e8982de888e4d5ddbe8a20c67a98c23ebe51718",
5
5
  "meta.json": "2996be8fdb14f3f935e1e1441fed8f69af7b6aeeefb14dac96301cc41eba8046",
6
6
  "types/index.d.ts": "7b2e6f784b7dbecbbe7924fa1aec7e2520ac0547069311253a006bc2267a5646",
7
7
  "rules/no-latest-tag.ts": "efd060453d8ca3d5b85c3972906c6650b6f63eb5f67cb6cdb0f16a41cad91228",
@@ -15,5 +15,5 @@
15
15
  "skills/chant-docker.md": "3ff0708e3c76e245f202948949c768464563af2b60cc9aa2ca52f494ef8357f1",
16
16
  "skills/chant-docker-patterns.md": "ad1b0196d8150b2df579a699ff107f604340c799c04f3460ebf65003e287b12a"
17
17
  },
18
- "composite": "e4c7105a3d96f148222aa308477aea6191dbb466263f0abd60b750263ded3b3d"
18
+ "composite": "465db9e38059d51e70fc673584cde22e1536c2e64892b7ea06138b2b945e1ae3"
19
19
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docker",
3
- "version": "0.101.0",
3
+ "version": "0.104.0",
4
4
  "chantVersion": ">=0.1.0",
5
5
  "namespace": "Docker",
6
6
  "intrinsics": [
@@ -1 +1 @@
1
- {"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAoB,UAAU,EAAoB,MAAM,6BAA6B,CAAC;AA+RlG,eAAO,MAAM,gBAAgB,EAAE,UAqE9B,CAAC"}
1
+ {"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAoB,UAAU,EAAoB,MAAM,6BAA6B,CAAC;AA6SlG,eAAO,MAAM,gBAAgB,EAAE,UAqE9B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["../src/variables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,qDAAqD;AACrD,eAAO,MAAM,WAAW;IACtB,gDAAgD;;IAEhD,iCAAiC;;IAEjC,wBAAwB;;IAExB,8BAA8B;;IAE9B,2BAA2B;;CAEnB,CAAC;AAEX,oDAAoD;AACpD,eAAO,MAAM,YAAY;IACvB,kDAAkD;;IAElD,0CAA0C;;IAE1C,sCAAsC;;IAEtC,wCAAwC;;IAExC,8BAA8B;;IAE9B,8BAA8B;;CAEtB,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,CAAC;AACvE,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC"}
1
+ {"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["../src/variables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,qDAAqD;AACrD,eAAO,MAAM,WAAW;IACtB,gDAAgD;aAChD,eAAe,EAAE,iBAAiB;IAClC,iCAAiC;aACjC,WAAW,EAAE,aAAa;IAC1B,wBAAwB;aACxB,iBAAiB,EAAE,mBAAmB;IACtC,8BAA8B;aAC9B,aAAa,EAAE,eAAe;IAC9B,2BAA2B;aAC3B,oBAAoB,EAAE,sBAAsB;CACpC,CAAC;AAEX,oDAAoD;AACpD,eAAO,MAAM,YAAY;IACvB,kDAAkD;aAClD,oBAAoB,EAAE,sBAAsB;IAC5C,0CAA0C;aAC1C,YAAY,EAAE,cAAc;IAC5B,sCAAsC;aACtC,sBAAsB,EAAE,wBAAwB;IAChD,wCAAwC;aACxC,gBAAgB,EAAE,kBAAkB;IACpC,8BAA8B;aAC9B,6BAA6B,EAAE,+BAA+B;IAC9D,8BAA8B;aAC9B,uBAAuB,EAAE,yBAAyB;CAC1C,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,CAAC;AACvE,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant-lexicon-docker",
3
- "version": "0.101.0",
3
+ "version": "0.104.0",
4
4
  "description": "Docker lexicon for chant — declarative IaC in TypeScript",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://intentius.io/chant",
@@ -60,7 +60,7 @@
60
60
  "validate": "tsx src/validate-cli.ts",
61
61
  "docs": "tsx src/codegen/docs-cli.ts",
62
62
  "prepack": "npm run generate && npm run bundle && npm run validate && npm run build",
63
- "build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json && find dist -type f \\( -name \"*.js\" -o -name \"*.js.map\" \\) -delete"
63
+ "build": "../../scripts/tsc7.sh -p tsconfig.build.json && tsc-alias -p tsconfig.build.json && find dist -type f \\( -name \"*.js\" -o -name \"*.js.map\" \\) -delete"
64
64
  },
65
65
  "dependencies": {
66
66
  "@intentius/chant-lexicon-otel": "*"
@@ -70,7 +70,7 @@
70
70
  "typescript": "^5.9.3"
71
71
  },
72
72
  "peerDependencies": {
73
- "@intentius/chant": "^0.101.0",
73
+ "@intentius/chant": "^0.104.0",
74
74
  "typescript": "^5.9.3"
75
75
  }
76
76
  }
@@ -75,7 +75,7 @@ export const DockerOtelCollector = Composite((props: DockerOtelCollectorProps) =
75
75
  image,
76
76
  command: [`--config=${COLLECTOR_CONFIG_PATH}`],
77
77
  configs: [{ source: config, target: COLLECTOR_CONFIG_PATH }],
78
- ...(publishPorts && ports.length > 0 ? { ports: ports.map((p) => `${p.port}:${p.port}`) } : {}),
78
+ ...(publishPorts && ports.length > 0 ? { ports: ports.map((p) => `${p.port}:${p.port}${p.protocol ? "/udp" : ""}`) } : {}),
79
79
  restart,
80
80
  }, defs?.service));
81
81
 
@@ -365,4 +365,15 @@ describe("telemetry attribution", () => {
365
365
  expect(out).not.toContain("OTEL_SERVICE_NAME=api");
366
366
  expect(out).toContain("- OTEL_RESOURCE_ATTRIBUTES=chant.workspace=acme,chant.member=delivery");
367
367
  });
368
+
369
+ test("the resource attributes end with the release reference a deploy fills, once (#3061)", () => {
370
+ expect(run({ image: "nginx:1" }, attrs)).toContain(
371
+ "OTEL_RESOURCE_ATTRIBUTES: chant.workspace=acme,chant.member=delivery,chant.decl=api,deployment.environment.name=prod${CHANT_RELEASE_ATTRIBUTES:-}",
372
+ );
373
+ const own = run({ image: "x", environment: { OTEL_RESOURCE_ATTRIBUTES: "team=pay${CHANT_RELEASE_ATTRIBUTES:-}" } }, { workspace: "acme" });
374
+ expect(own.match(/CHANT_RELEASE_ATTRIBUTES/g)).toHaveLength(1);
375
+ expect(run({ image: "x", environment: ["OTEL_RESOURCE_ATTRIBUTES=team=pay"] }, { workspace: "acme" })).toContain(
376
+ "- OTEL_RESOURCE_ATTRIBUTES=team=pay,chant.workspace=acme,chant.decl=api${CHANT_RELEASE_ATTRIBUTES:-}",
377
+ );
378
+ });
368
379
  });
package/src/serializer.ts CHANGED
@@ -12,11 +12,11 @@
12
12
  import type { Declarable } from "@intentius/chant/declarable";
13
13
  import { isPropertyDeclarable, isResourceDeclarable } from "@intentius/chant/declarable";
14
14
  import type { SerializeContext, Serializer, SerializerResult } from "@intentius/chant/serializer";
15
- import { mergeResourceAttributes, telemetryEnvironment, type TelemetryAttribution } from "@intentius/chant/telemetry-attribution";
15
+ import { mergeResourceAttributes, RELEASE_ATTRIBUTES_VARIABLE, telemetryEnvironment, type TelemetryAttribution } from "@intentius/chant/telemetry-attribution";
16
16
  import type { LexiconOutput } from "@intentius/chant/lexicon-output";
17
17
  import { walkValue, type SerializerVisitor } from "@intentius/chant/serializer-walker";
18
18
  import { INTRINSIC_MARKER } from "@intentius/chant/intrinsic";
19
- import { emitYAML } from "@intentius/chant/yaml";
19
+ import { emitYAMLEntry } from "@intentius/chant/yaml";
20
20
 
21
21
  // ── Helpers ───────────────────────────────────────────────────────
22
22
 
@@ -107,11 +107,25 @@ function imageDigest(image: unknown): string | undefined {
107
107
  return at === -1 ? undefined : image.slice(at + 1);
108
108
  }
109
109
 
110
+ /** Compose's reference to the release attributes a deploy exports (#3061, ws-081), empty when unset. */
111
+ const RELEASE_REF = `\${${RELEASE_ATTRIBUTES_VARIABLE}:-}`;
112
+
113
+ /** A resource-attributes value that ends with the release reference, once. */
114
+ function withReleaseRef(value: string): string {
115
+ return value.includes(RELEASE_REF) ? value : `${value}${RELEASE_REF}`;
116
+ }
117
+
110
118
  /**
111
119
  * Stamp one service's attributes as `OTEL_SERVICE_NAME` and
112
120
  * `OTEL_RESOURCE_ATTRIBUTES` in its environment. A value the service already
113
121
  * sets is kept: its own `OTEL_SERVICE_NAME` wins, and its own resource
114
122
  * attributes keep their keys while the missing ones are appended.
123
+ *
124
+ * `OTEL_RESOURCE_ATTRIBUTES` ends with `${CHANT_RELEASE_ATTRIBUTES:-}`, which
125
+ * Compose fills from the environment of `docker compose up`: a release deploy
126
+ * exports `service.version` and `vcs.ref.head.revision` there (#3061,
127
+ * ws-081), and any other `up` leaves it empty, so this output does not change
128
+ * with a release.
115
129
  */
116
130
  function stampTelemetry(service: Record<string, unknown>, name: string, telemetry: TelemetryAttribution): void {
117
131
  const version = imageDigest(service.image);
@@ -122,9 +136,9 @@ function stampTelemetry(service: Record<string, unknown>, name: string, telemetr
122
136
  const has = (key: string) => entries.findIndex((e) => e === key || e.startsWith(`${key}=`));
123
137
  if (has("OTEL_SERVICE_NAME") === -1) entries.push(`OTEL_SERVICE_NAME=${vars.OTEL_SERVICE_NAME}`);
124
138
  const at = has("OTEL_RESOURCE_ATTRIBUTES");
125
- if (at === -1) entries.push(`OTEL_RESOURCE_ATTRIBUTES=${vars.OTEL_RESOURCE_ATTRIBUTES}`);
139
+ if (at === -1) entries.push(`OTEL_RESOURCE_ATTRIBUTES=${withReleaseRef(vars.OTEL_RESOURCE_ATTRIBUTES)}`);
126
140
  else if (entries[at]!.includes("=")) {
127
- entries[at] = `OTEL_RESOURCE_ATTRIBUTES=${mergeResourceAttributes(entries[at]!.slice(entries[at]!.indexOf("=") + 1), vars.OTEL_RESOURCE_ATTRIBUTES)}`;
141
+ entries[at] = `OTEL_RESOURCE_ATTRIBUTES=${withReleaseRef(mergeResourceAttributes(entries[at]!.slice(entries[at]!.indexOf("=") + 1), vars.OTEL_RESOURCE_ATTRIBUTES))}`;
128
142
  }
129
143
  service.environment = entries;
130
144
  return;
@@ -132,8 +146,8 @@ function stampTelemetry(service: Record<string, unknown>, name: string, telemetr
132
146
  const map: Record<string, unknown> = env && typeof env === "object" ? { ...(env as Record<string, unknown>) } : {};
133
147
  if (!("OTEL_SERVICE_NAME" in map)) map.OTEL_SERVICE_NAME = vars.OTEL_SERVICE_NAME;
134
148
  const own = map.OTEL_RESOURCE_ATTRIBUTES;
135
- if (own === undefined) map.OTEL_RESOURCE_ATTRIBUTES = vars.OTEL_RESOURCE_ATTRIBUTES;
136
- else if (typeof own === "string") map.OTEL_RESOURCE_ATTRIBUTES = mergeResourceAttributes(own, vars.OTEL_RESOURCE_ATTRIBUTES);
149
+ if (own === undefined) map.OTEL_RESOURCE_ATTRIBUTES = withReleaseRef(vars.OTEL_RESOURCE_ATTRIBUTES);
150
+ else if (typeof own === "string") map.OTEL_RESOURCE_ATTRIBUTES = withReleaseRef(mergeResourceAttributes(own, vars.OTEL_RESOURCE_ATTRIBUTES));
137
151
  service.environment = map;
138
152
  }
139
153
 
@@ -236,13 +250,13 @@ function emitComposeDocument(doc: Record<string, unknown>): string {
236
250
  for (const key of ORDER) {
237
251
  if (key in doc && doc[key] !== undefined) {
238
252
  emitted.add(key);
239
- sections.push(`${key}:` + emitYAML(doc[key], 1));
253
+ sections.push(emitYAMLEntry(key, doc[key]));
240
254
  }
241
255
  }
242
256
 
243
257
  for (const [key, value] of Object.entries(doc)) {
244
258
  if (!emitted.has(key) && value !== undefined) {
245
- sections.push(`${key}:` + emitYAML(value, 1));
259
+ sections.push(emitYAMLEntry(key, value));
246
260
  }
247
261
  }
248
262