Skip to content

Commit 56b6199

Browse files
authored
ci: gate showcase output in all five ports and regen stale output (#449)
* fix: regen showcase for value-object null omission and gate all ports in the full CI run * no-mistakes(document): Updated CONTRIBUTING.md full-run lane list for the new all-ports showcase gate. Left AGENTS.md unchanged: it omits the new gate but is not wrong, and it is a human-owned memory file.
1 parent 1d2b009 commit 56b6199

7 files changed

Lines changed: 45 additions & 8 deletions

File tree

‎CONTRIBUTING.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ a PR, so nothing red leaves your machine:
8383
```bash
8484
scripts/ci-local.sh # full parity: hygiene.yml's leak-scan, all-port
8585
# conformance, the java reactor, the drift/mutation
86-
# gates, + integration-tests.yml's docker suite
86+
# gates, the showcase current in all five ports, +
87+
# integration-tests.yml's docker suite
8788
scripts/ci-local.sh --quick # hygiene.yml in full + the TypeScript half of
8889
# conformance.yml; skips the C#/Java/Kotlin/Python
8990
# ports, the java reactor and the docker suite

‎examples/showcase/.metaobjects/.gen-state/.hashes.json‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
{
22
"generated/csharp/AppDbContext.g.cs": "314c6078030ba151687430b37e6b6ea936238bb5df02df238e4acce2f95a430d",
33
"generated/csharp/Subscriber.g.cs": "3ca160941378fbb8b6ad6acf080ff85573f463931e21b8756873a4476e5dd163",
4-
"generated/csharp/SubscriberBlurbPayload.g.cs": "6b1ce5b5a4018c647586d86125718c4764ae5d6eeb94e9545e8006a7ec2b2b6f",
4+
"generated/csharp/SubscriberBlurbPayload.g.cs": "30ae31959c0cd98ba4ab12b2e827fa48f3bf59a05aa34974ebc4a1fe930378be",
55
"generated/csharp/SubscriberFilterAllowlist.g.cs": "7428d47f6ccb64bb315266ee0564fa3803736623a34ab491435c042848c5d472",
66
"generated/csharp/SubscriberNames.g.cs": "91f6eba78657b31fceef7021c6ca6bd799524dcb5120acbc8fcbe18786787174",
7-
"generated/csharp/SubscriberRoutes.g.cs": "a14815f7870e309102d57a0227555191b3f32a4012e04fb213ef17abe12ab3f4",
7+
"generated/csharp/SubscriberRoutes.g.cs": "e98387adf0d9fd5c2743409e5820d72400373ca6a758176cba76112fa1efc02a",
88
"generated/python/Subscriber.py": "9dd4c0acea47f99d1daf79930f9de2e400f30780ebce6c63f023be528a72b762",
99
"generated/python/SubscriberBlurbPayload.py": "a5ef8a08e63efbe0f73e39a21a368cff5150c68cc8beeea6e8aab0c755f8bbdd",
1010
"generated/python/__init__.py": "daa04cec586768866d0996c779f62073e6773fe63750ff668327991fac2fd0f5",
1111
"generated/python/subscriber_filter_allowlist.py": "b0414cc95ff3982c80a0e1a06839f090c0b423e41f5a94275df93426cea09df5",
1212
"generated/python/subscriber_names.py": "269637a02bf9b46f55658b58cb42f83196c03a877e1e2101337847fd406c1561",
13-
"generated/python/subscriber_router.py": "734f9c91aa1ea475ac8014e9f5db47fe54c8f5e35a25d1ae64c1dc3276ad2546",
13+
"generated/python/subscriber_router.py": "9c2393da6c055bd7a76b81cbc1492fccc44bae257cab5755830ab58f59f522c7",
1414
"generated/ts/Subscriber.queries.ts": "9f1a459c57fafc98bf074b4443b506d4a1e7023ed188f293021ae89c298d4562",
1515
"generated/ts/Subscriber.routes.ts": "147d32ae658f985e024c3de6e8894ca7359f767eeaa765cec70756802e3bd300",
1616
"generated/ts/Subscriber.ts": "a78c17f915222ee108290c28468313d77f77b5cff438f485324409302e389a96",

‎examples/showcase/generated/csharp/SubscriberBlurbPayload.g.cs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public class SubscriberBlurbPayload
1313
{
1414
public enum SubscriberBlurbPayloadStatus { active, paused, cancelled }
1515
[JsonPropertyName("name")]
16+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
1617
public string? Name { get; set; }
1718
[JsonPropertyName("status")]
1819
public SubscriberBlurbPayloadStatus Status { get; set; }

‎examples/showcase/generated/java/acme/SubscriberBlurbPayload.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package acme;
22

33
import jakarta.validation.constraints.*;
4+
import com.fasterxml.jackson.annotation.JsonInclude;
45

56
/** GENERATED — value object SubscriberBlurbPayload. Do not hand-edit; regenerated from metadata. */
7+
@JsonInclude(JsonInclude.Include.NON_NULL)
68
public record SubscriberBlurbPayload(
79
String name,
810
@NotNull Status status

‎examples/showcase/generated/kotlin/acme/SubscriberBlurbPayload.kt‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package acme
22

3+
import com.fasterxml.jackson.`annotation`.JsonInclude
34
import jakarta.validation.constraints.NotNull
45
import kotlin.String
56
import kotlin.jvm.JvmStatic
67

78
/**
89
* GENERATED — do not hand-edit. Regenerated from metadata.
910
*/
11+
@JsonInclude(JsonInclude.Include.NON_NULL)
1012
public data class SubscriberBlurbPayload(
1113
public val name: String? = null,
1214
@field:NotNull

‎examples/showcase/generated/python/subscriber_router.py‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ class _SortClause(BaseModel):
7575
_DECIMAL_LIMITS: dict[str, tuple[int, int]] = {}
7676

7777

78+
_NESTED_DECIMALS: dict[str, Any] = {}
79+
80+
7881
async def _json_body(request: Request) -> dict[str, Any] | None:
7982
"""GENERATED — the request body as a JSON object (non-integer numbers are exact `Decimal`s), or None."""
8083
try:
@@ -182,7 +185,9 @@ def create_subscriber(
182185
): # the body was not a JSON object: the cross-port 400, not FastAPI's 422
183186
return JSONResponse(status_code=400, content={"error": "validation"})
184187
try:
185-
dto = coerce_decimal_fields(dto, _DECIMAL_FIELDS, _DECIMAL_LIMITS)
188+
dto = coerce_decimal_fields(
189+
dto, _DECIMAL_FIELDS, _DECIMAL_LIMITS, _NESTED_DECIMALS
190+
)
186191
except ValueError:
187192
return JSONResponse(status_code=400, content={"error": "validation"})
188193
# FR-036: run the generated field constraints (length / pattern /
@@ -215,7 +220,9 @@ def update_subscriber(
215220
): # the body was not a JSON object: the cross-port 400, not FastAPI's 422
216221
return JSONResponse(status_code=400, content={"error": "validation"})
217222
try:
218-
dto = coerce_decimal_fields(dto, _DECIMAL_FIELDS, _DECIMAL_LIMITS)
223+
dto = coerce_decimal_fields(
224+
dto, _DECIMAL_FIELDS, _DECIMAL_LIMITS, _NESTED_DECIMALS
225+
)
219226
except ValueError:
220227
return JSONResponse(status_code=400, content={"error": "validation"})
221228
# FR-035 PATCH-2: an explicit null on a @required field is a 400 —

‎scripts/ci-local.sh‎

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,10 +399,22 @@ gate_no_api_prefix() { bun scripts/check-no-api-prefix.ts; }
399399
#
400400
# Deliberately does NOT run the other four ports: that shells out to mvn/dotnet/uv,
401401
# and this lane is `step_if bun` — guarded on bun alone and included in `--quick`, the
402-
# documented pre-PR command. The release preflight runs `--check --all-ports`, which
403-
# refuses to leave a port out.
402+
# documented pre-PR command. The other four ports are checked by `gate_showcase_all_ports`
403+
# in the heavy tier of the flagless run, and again by the release preflight
404+
# (`--check --all-ports`); both refuse to leave a port out.
404405
gate_site_payload() { bun_install && bun test scripts/site && bun scripts/build-site-payload.ts --check; }
405406

407+
# ── the showcase is current in EVERY port, not just ts+sql ────────────────────
408+
# `gate_site_payload` can only afford `--bun-only`, so a change to the python, csharp,
409+
# java or kotlin emitter left the committed showcase stale while the full run stayed
410+
# green, and the first thing to notice was the release preflight (`--check --all-ports`)
411+
# refusing the release cut (#447/#448 value-object null omission). No single CI lane has
412+
# mvn, dotnet and uv together, so this runs in the flagless full run only, which is the
413+
# one place all three coexist; it is absent from `--quick` (bun-only by design) and from
414+
# every `--only` lane. It needs the workspace built (`gate_ts_build_typecheck` earlier in
415+
# the same run) for the reason given above `gate_site_payload`.
416+
gate_showcase_all_ports() { bun_install && bun scripts/regen-showcase.ts --check --all-ports; }
417+
406418
# ── the published metamodel reference tracks the registry ─────────────────────
407419
# site-reference/ is rendered HTML the site COPIES at deploy — the deploy has no install
408420
# step for this repo, so the rendering happens here and the release tag carries the pages.
@@ -924,6 +936,18 @@ else
924936
if want python; then step_if uv "conformance: python" gate_conf_python; fi
925937
if want_any java java-fast; then step_if mvn "conformance: kotlin" gate_conf_kotlin; fi
926938
if want_any java java-slow; then step_if mvn "java-reactor (install)" gate_java_reactor; fi
939+
# Needs all three toolchains at once, which no single --only lane has: flagless run only.
940+
if [ -z "$ONLY" ] && [ "$INTEG_ONLY" -eq 0 ]; then
941+
if have mvn && have dotnet && have uv; then
942+
step "showcase current in all ports" gate_showcase_all_ports
943+
elif [ "$STRICT" -eq 1 ]; then
944+
echo ""; echo " ✖ showcase current in all ports — needs mvn, dotnet and uv (strict-toolchains)" >&2
945+
FAIL+=("showcase current in all ports (missing toolchain, strict)")
946+
else
947+
echo ""; echo "── ⊘ showcase current in all ports — SKIPPED (needs mvn, dotnet and uv) ──" >&2
948+
SKIP+=("showcase current in all ports (needs mvn+dotnet+uv)")
949+
fi
950+
fi
927951
# Docker integration — full suite when no --only, per-port otherwise.
928952
# --no-integration drops this whole half; --integration-only keeps ONLY it, which is
929953
# why it asks in_lane / in_lane_any (selection) where the checks above ask want.

0 commit comments

Comments
 (0)