From 0fbd7d7692035b92e35d0414d849e71c80a47122 Mon Sep 17 00:00:00 2001 From: monsieurleberre Date: Thu, 2 Jul 2026 19:44:36 +0200 Subject: [PATCH 1/2] fix: align OCI smoke-test counters assertions with generation-ordinal schema The release-counters store now writes {store_version, codegen_generations: {: }} but the bundle smoke test still asserted the retired flat per-package revision schema, failing every RID at tag time (run 28597012818). --- .github/workflows/build-oci-codegen-cs.yaml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-oci-codegen-cs.yaml b/.github/workflows/build-oci-codegen-cs.yaml index 9db04d5..d55cfca 100644 --- a/.github/workflows/build-oci-codegen-cs.yaml +++ b/.github/workflows/build-oci-codegen-cs.yaml @@ -282,19 +282,25 @@ jobs: echo "::error::--release-counters did not write ${COUNTERS}" exit 1 fi - entry_count="$(jq 'length' "${COUNTERS}")" - if [ "${entry_count}" != "1" ]; then - echo "::error::expected exactly one release-counter entry, got ${entry_count}" + store_version="$(jq -r '.store_version' "${COUNTERS}")" + if [ "${store_version}" != "1" ]; then + echo "::error::expected release-counters store_version 1, got ${store_version}" jq . "${COUNTERS}" >&2 exit 1 fi - revision="$(jq -r 'to_entries[0].value.revision' "${COUNTERS}")" - if [ "${revision}" != "0" ]; then - echo "::error::expected first-emission revision 0, got ${revision}" + generation_count="$(jq '.codegen_generations | length' "${COUNTERS}")" + if [ "${generation_count}" != "1" ]; then + echo "::error::expected exactly one codegen-generation entry, got ${generation_count}" jq . "${COUNTERS}" >&2 exit 1 fi - echo "Release-counter OK — first emission recorded revision 0" + ordinal="$(jq -r '.codegen_generations | to_entries[0].value' "${COUNTERS}")" + if [ "${ordinal}" != "0" ]; then + echo "::error::expected first-emission generation ordinal 0, got ${ordinal}" + jq . "${COUNTERS}" >&2 + exit 1 + fi + echo "Release-counter OK — first emission recorded generation ordinal 0" csproj="$(find "${OUT}" -type f -name '*.csproj' -print -quit)" if [ -z "${csproj}" ]; then From b1ce390444291737f386a6e274ebc58c01d9439f Mon Sep 17 00:00:00 2001 From: monsieurleberre Date: Thu, 2 Jul 2026 23:02:36 +0200 Subject: [PATCH 2/2] fix: harden counters assertions against malformed input Require the counters file to be a non-empty valid JSON object, assert codegen_generations is an object before counting entries, compare store_version and the generation ordinal numerically, and move every jq extraction into a guarded condition so set -e cannot skip the ::error:: annotations. Mirrors daml-codegen-csharp-internal PR #496 (c1a7850), validated there and merged. --- .github/workflows/build-oci-codegen-cs.yaml | 29 +++++++++++++-------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build-oci-codegen-cs.yaml b/.github/workflows/build-oci-codegen-cs.yaml index d55cfca..d0de9b4 100644 --- a/.github/workflows/build-oci-codegen-cs.yaml +++ b/.github/workflows/build-oci-codegen-cs.yaml @@ -278,25 +278,32 @@ jobs: fi echo "Smoke test OK — first generated file: ${first_cs}" - if [ ! -f "${COUNTERS}" ]; then - echo "::error::--release-counters did not write ${COUNTERS}" + if [ ! -s "${COUNTERS}" ]; then + echo "::error::--release-counters did not write a non-empty ${COUNTERS}" exit 1 fi - store_version="$(jq -r '.store_version' "${COUNTERS}")" - if [ "${store_version}" != "1" ]; then - echo "::error::expected release-counters store_version 1, got ${store_version}" + if ! jq -e 'type == "object"' "${COUNTERS}" > /dev/null; then + echo "::error::release-counters file is not a valid JSON object: ${COUNTERS}" + cat "${COUNTERS}" >&2 + exit 1 + fi + if ! jq -e '.store_version == 1' "${COUNTERS}" > /dev/null; then + echo "::error::expected release-counters store_version 1, got $(jq -c '.store_version' "${COUNTERS}")" + jq . "${COUNTERS}" >&2 + exit 1 + fi + if ! jq -e '.codegen_generations | type == "object"' "${COUNTERS}" > /dev/null; then + echo "::error::expected codegen_generations to be an object, got $(jq -r '.codegen_generations | type' "${COUNTERS}")" jq . "${COUNTERS}" >&2 exit 1 fi - generation_count="$(jq '.codegen_generations | length' "${COUNTERS}")" - if [ "${generation_count}" != "1" ]; then - echo "::error::expected exactly one codegen-generation entry, got ${generation_count}" + if ! jq -e '.codegen_generations | length == 1' "${COUNTERS}" > /dev/null; then + echo "::error::expected exactly one codegen-generation entry, got $(jq '.codegen_generations | length' "${COUNTERS}")" jq . "${COUNTERS}" >&2 exit 1 fi - ordinal="$(jq -r '.codegen_generations | to_entries[0].value' "${COUNTERS}")" - if [ "${ordinal}" != "0" ]; then - echo "::error::expected first-emission generation ordinal 0, got ${ordinal}" + if ! jq -e '.codegen_generations | to_entries[0].value == 0' "${COUNTERS}" > /dev/null; then + echo "::error::expected first-emission generation ordinal 0, got $(jq -c '.codegen_generations | to_entries[0].value' "${COUNTERS}")" jq . "${COUNTERS}" >&2 exit 1 fi