From 1b30282a1fa99edce58a96a36affc10986bb7270 Mon Sep 17 00:00:00 2001 From: Santiago Date: Wed, 20 May 2026 06:34:12 -0300 Subject: [PATCH 1/7] feat(codegen): port client-lib plugin to TII v1beta0 The .trix/client-lib plugin still rendered against the legacy bindgen-v1alpha2 data shape, so every transaction was silently dropped against a v1beta0 TII. Rewrites the templates to consume tii.transactions / tii.profiles / tii.environment, emits protocol identity constants and an embedded profile surface wired into the Client, and adds a render-fixture test that builds the generated package. Co-Authored-By: Claude Opus 4.7 (1M context) --- .trix/client-lib/go.mod.hbs | 6 +- .trix/client-lib/protocol.go.hbs | 141 +++++++++++++++++-------------- sdk/codegen_test.go | 81 ++++++++++++++++++ 3 files changed, 160 insertions(+), 68 deletions(-) create mode 100644 sdk/codegen_test.go diff --git a/.trix/client-lib/go.mod.hbs b/.trix/client-lib/go.mod.hbs index dbc1394..353a0a0 100644 --- a/.trix/client-lib/go.mod.hbs +++ b/.trix/client-lib/go.mod.hbs @@ -1,7 +1,5 @@ -module {{protocolName}} +module {{tii.protocol.name}} go 1.24.2 -require github.com/tx3-lang/go-sdk/sdk v0.0.3 - -require github.com/google/uuid v1.6.0 // indirect +require github.com/tx3-lang/go-sdk/sdk v0.11.0 diff --git a/.trix/client-lib/protocol.go.hbs b/.trix/client-lib/protocol.go.hbs index 6c3b195..6295901 100644 --- a/.trix/client-lib/protocol.go.hbs +++ b/.trix/client-lib/protocol.go.hbs @@ -1,98 +1,111 @@ -// This file is auto-generated. +// This file is auto-generated by trix codegen. +// Target TII version: {{tii.tii.version}} package protocol import ( - "encoding/hex" + "context" "encoding/json" + "fmt" - "github.com/tx3-lang/go-sdk/sdk/trp" + "github.com/tx3-lang/go-sdk/sdk/core" + "github.com/tx3-lang/go-sdk/sdk/trp" ) -const DefaultTRPEndpoint = "{{trpEndpoint}}" +// Protocol identity, embedded from the TII at codegen time. +const ( + ProtocolName = "{{tii.protocol.name}}" + ProtocolVersion = "{{tii.protocol.version}}" + TargetTIIVersion = "{{tii.tii.version}}" +) -var DefaultHeaders = map[string]string{ -{{#each headers}} - "{{@key}}": "{{this}}", -{{/each}} -} +{{#if tii.environment}} +// EnvironmentSchema is the JSON Schema of the protocol environment, embedded +// verbatim from the TII. +const EnvironmentSchema = `{{{json tii.environment}}}` -var DefaultEnvArgs = map[string]string{ -{{#each envArgs}} - "{{@key}}": "{{this}}", -{{/each}} +{{/if}} +// Profile holds the environment values and party addresses for a named TII profile. +type Profile struct { + Environment core.EnvMap `json:"environment"` + Parties map[string]string `json:"parties"` } +const profilesJSON = `{{{json tii.profiles}}}` -type Bytes []byte -func (h Bytes) MarshalJSON() ([]byte, error) { - hexStr := "0x" + hex.EncodeToString(h) - return json.Marshal(hexStr) -} - -{{#each transactions}} -// {{pascalCase params_name}} defines the parameters for the {{pascalCase name}} transaction -type {{pascalCase params_name}} struct { -{{#each parameters}} - {{pascalCase name}} {{typeFor type_name "go"}} `json:"{{snakeCase name}}"` // {{type_name}} +// Profiles enumerates the profiles embedded from the TII, keyed by name. +var Profiles = func() map[string]Profile { + var parsed map[string]Profile + if err := json.Unmarshal([]byte(profilesJSON), &parsed); err != nil { + panic("codegen: invalid embedded profiles: " + err.Error()) + } + return parsed +}() + +{{#each tii.transactions}} +// {{pascalCase @key}}Params holds the arguments for the {{@key}} transaction. +type {{pascalCase @key}}Params struct { +{{#each params.properties}} + {{pascalCase @key}} {{schemaTypeFor this "go"}} `json:"{{@key}}"` {{/each}} } -// {{constantCase constant_name}} contains the TIR content for the {{pascalCase name}} transaction -var {{constantCase constant_name}} = trp.TirInfo{ - Content: "{{ir_bytes}}", - Encoding: "hex", - Version: "{{ir_version}}", +// {{constantCase @key}}_TIR is the embedded TIR envelope for the {{@key}} transaction. +var {{constantCase @key}}_TIR = core.TirEnvelope{ + Content: "{{tir.content}}", + Encoding: "{{tir.encoding}}", + Version: "{{tir.version}}", } {{/each}} -// Client provides methods to interact with the tx3 protocol +// Client is a thin protocol facade over the TRP client. type Client struct { - client *trp.Client + trp *trp.Client + profile *Profile } -// NewClient creates a new Client with the given options +// NewClient creates a Client over the given TRP client options. func NewClient(options trp.ClientOptions) *Client { - return &Client{ - client: trp.NewClient(options), - } + return &Client{trp: trp.NewClient(options)} } -// NewClientWithDefaults creates a new Client with default options -func NewClientWithDefaults() *Client { - options := trp.ClientOptions{ - Endpoint: DefaultTRPEndpoint, - Headers: DefaultHeaders, - EnvArgs: make(map[string]interface{}), +// WithProfile selects an embedded profile by name. Its environment values and +// party addresses are applied to every subsequent transaction. It panics if +// name is not a profile declared by the protocol. +func (c *Client) WithProfile(name string) *Client { + profile, ok := Profiles[name] + if !ok { + panic(fmt.Sprintf("unknown profile %q", name)) } + c.profile = &profile + return c +} - // Convert string env args to interface{} - for k, v := range DefaultEnvArgs { - options.EnvArgs[k] = v +func (c *Client) resolve(ctx context.Context, tir core.TirEnvelope, args core.ArgMap) (*trp.TxEnvelope, error) { + params := trp.ResolveParams{Tir: tir, Args: args} + if c.profile != nil { + params.Env = c.profile.Environment + for name, address := range c.profile.Parties { + if _, set := args[name]; !set { + args[name] = address + } + } } - - return NewClient(options) + return c.trp.Resolve(ctx, params) } -{{#each transactions}} -// {{pascalCase function_name}} resolves the {{pascalCase name}} transaction with the given parameters -func (c *Client) {{pascalCase function_name}}(args {{pascalCase params_name}}) (*trp.TxEnvelope, error) { - return c.client.Resolve(trp.ProtoTxRequest{ - Tir: {{constantCase constant_name}}, - Args: args, - }) -} +{{#each tii.transactions}} +// {{pascalCase @key}} resolves the {{@key}} transaction. +func (c *Client) {{pascalCase @key}}(ctx context.Context, args {{pascalCase @key}}Params) (*trp.TxEnvelope, error) { + return c.resolve(ctx, {{constantCase @key}}_TIR, core.ArgMap{ +{{#each params.properties}} + "{{@key}}": args.{{pascalCase @key}}, {{/each}} - -// Submit sends a signed transaction to the network -func (c *Client) Submit(tx trp.TxEnvelope, witnesses []trp.WitnessInput) (*trp.SubmitResponse, error) { - return c.client.Submit(tx, witnesses) + }) } -// Instance of the singleton client -var DefaultClient *Client - -// init function runs automatically when the package is imported -func init() { - DefaultClient = NewClientWithDefaults() +{{/each}} +// Submit sends a signed transaction to the network. +func (c *Client) Submit(ctx context.Context, params trp.SubmitParams) (*trp.SubmitResponse, error) { + return c.trp.Submit(ctx, params) } diff --git a/sdk/codegen_test.go b/sdk/codegen_test.go new file mode 100644 index 0000000..f07661c --- /dev/null +++ b/sdk/codegen_test.go @@ -0,0 +1,81 @@ +package tx3sdk_test + +import ( + "os" + "os/exec" + "path/filepath" + "testing" +) + +// resolveTx3c locates the tx3c binary: TX3_TX3C_PATH first, then $PATH. +func resolveTx3c(t *testing.T) string { + t.Helper() + if p := os.Getenv("TX3_TX3C_PATH"); p != "" { + if info, err := os.Stat(p); err == nil && !info.IsDir() { + return p + } + } + if p, err := exec.LookPath("tx3c"); err == nil { + return p + } + t.Fatal("tx3c not found; set TX3_TX3C_PATH or install tx3c") + return "" +} + +// TestCodegenClientLib renders the .trix/client-lib plugin against the shared +// transfer fixture and builds the result. A successful render that produces +// uncompilable bindings is a failure. +func TestCodegenClientLib(t *testing.T) { + sdkDir, err := os.Getwd() + if err != nil { + t.Fatalf("getwd: %v", err) + } + repoRoot := filepath.Dir(sdkDir) + templateDir := filepath.Join(repoRoot, ".trix", "client-lib") + tiiPath := filepath.Join(sdkDir, "testdata", "transfer.tii") + + if _, err := os.Stat(tiiPath); err != nil { + t.Fatalf("missing TII fixture: %v", err) + } + if _, err := os.Stat(templateDir); err != nil { + t.Fatalf("missing template directory: %v", err) + } + + outDir := t.TempDir() + + render := exec.Command(resolveTx3c(t), "codegen", + "--tii", tiiPath, + "--template", templateDir, + "--output", outDir, + ) + if out, err := render.CombinedOutput(); err != nil { + t.Fatalf("tx3c codegen failed: %v\n%s", err, out) + } + + for _, name := range []string{"protocol.go", "go.mod"} { + if _, err := os.Stat(filepath.Join(outDir, name)); err != nil { + t.Fatalf("expected generated file %s: %v", name, err) + } + } + + // Build the rendered package against this repo's SDK rather than a + // published release. + goMod := "module codegentest\n\ngo 1.24.2\n\n" + + "require github.com/tx3-lang/go-sdk/sdk v0.0.0\n\n" + + "replace github.com/tx3-lang/go-sdk/sdk => " + sdkDir + "\n" + if err := os.WriteFile(filepath.Join(outDir, "go.mod"), []byte(goMod), 0o644); err != nil { + t.Fatalf("write go.mod: %v", err) + } + if sum, err := os.ReadFile(filepath.Join(sdkDir, "go.sum")); err == nil { + if err := os.WriteFile(filepath.Join(outDir, "go.sum"), sum, 0o644); err != nil { + t.Fatalf("write go.sum: %v", err) + } + } + + build := exec.Command("go", "build", "./...") + build.Dir = outDir + build.Env = append(os.Environ(), "GOFLAGS=-mod=mod") + if out, err := build.CombinedOutput(); err != nil { + t.Fatalf("go build of generated package failed: %v\n%s", err, out) + } +} From 79b680e64caa836e418d153652c6b15c816adacf Mon Sep 17 00:00:00 2001 From: Santiago Date: Wed, 20 May 2026 06:43:26 -0300 Subject: [PATCH 2/7] ci: install tx3 toolchain in the unit job for the codegen test The codegen render-fixture test shells out to `tx3c`; the unit job did not have it on PATH. Adds the tx3-lang/actions/setup step. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 89f38c6..53765fe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,6 +26,9 @@ jobs: cache: true cache-dependency-path: sdk/go.sum + - name: Setup tx3 toolchain + uses: tx3-lang/actions/setup@v1 + - name: Run unit tests working-directory: ./sdk run: go test ./... -count=1 From f1a887bbcabaf0787cd621b77e26eb0c152df73b Mon Sep 17 00:00:00 2001 From: Santiago Date: Wed, 20 May 2026 06:51:52 -0300 Subject: [PATCH 3/7] ci: pin tx3 toolchain to the beta channel The codegen render-fixture test needs the `json` renderer helper, which ships in the beta channel ahead of stable. Tracks beta until the helper reaches the stable toolchain. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 53765fe..e2d937c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,6 +28,8 @@ jobs: - name: Setup tx3 toolchain uses: tx3-lang/actions/setup@v1 + with: + channel: beta - name: Run unit tests working-directory: ./sdk From a0bdcc9739d82f24c9f7ac7513c9323ba5e4007b Mon Sep 17 00:00:00 2001 From: Santiago Date: Wed, 20 May 2026 07:12:57 -0300 Subject: [PATCH 4/7] test(codegen): move render-fixture test to a dedicated CI job The render-fixture test exercises the .trix/client-lib templates and tx3c, not the SDK runtime, so it does not belong in the unit job. Gates it behind the `codegen` build tag, runs it in a new `codegen` CI job, and adds smoke assertions over the generated public surface. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/ci.yml | 23 +++++++++++++++++++++-- sdk/codegen_test.go | 29 +++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e2d937c..477a4b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,25 @@ jobs: name: unit runs-on: ubuntu-latest timeout-minutes: 15 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: 1.24.2 + cache: true + cache-dependency-path: sdk/go.sum + + - name: Run unit tests + working-directory: ./sdk + run: go test ./... -count=1 + + codegen: + name: codegen + runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout repository uses: actions/checkout@v4 @@ -31,9 +50,9 @@ jobs: with: channel: beta - - name: Run unit tests + - name: Run codegen render-fixture test working-directory: ./sdk - run: go test ./... -count=1 + run: go test -tags=codegen -run TestCodegenClientLib ./... -count=1 e2e: name: e2e diff --git a/sdk/codegen_test.go b/sdk/codegen_test.go index f07661c..4c31941 100644 --- a/sdk/codegen_test.go +++ b/sdk/codegen_test.go @@ -1,9 +1,15 @@ +//go:build codegen + +// This test exercises the .trix/client-lib codegen plugin (Handlebars +// templates + tx3c), not the SDK runtime. It is gated behind the `codegen` +// build tag so it runs only in the dedicated codegen CI job. package tx3sdk_test import ( "os" "os/exec" "path/filepath" + "strings" "testing" ) @@ -23,8 +29,9 @@ func resolveTx3c(t *testing.T) string { } // TestCodegenClientLib renders the .trix/client-lib plugin against the shared -// transfer fixture and builds the result. A successful render that produces -// uncompilable bindings is a failure. +// transfer fixture, asserts the expected public surface is present, and builds +// the result. A successful render that produces uncompilable or empty bindings +// is a failure. func TestCodegenClientLib(t *testing.T) { sdkDir, err := os.Getwd() if err != nil { @@ -58,6 +65,24 @@ func TestCodegenClientLib(t *testing.T) { } } + // Smoke-test the generated surface: the template must emit protocol + // identity, the per-transaction types, and the profile surface. + src, err := os.ReadFile(filepath.Join(outDir, "protocol.go")) + if err != nil { + t.Fatalf("read generated protocol.go: %v", err) + } + for _, want := range []string{ + "TargetTIIVersion", + "type TransferParams struct", + "TRANSFER_TIR", + "func (c *Client) Transfer(", + "var Profiles", + } { + if !strings.Contains(string(src), want) { + t.Errorf("generated protocol.go missing expected symbol: %s", want) + } + } + // Build the rendered package against this repo's SDK rather than a // published release. goMod := "module codegentest\n\ngo 1.24.2\n\n" + From 923e8c0ebe062a1222757ed9c23bb213ab4d9ffa Mon Sep 17 00:00:00 2001 From: Santiago Date: Wed, 20 May 2026 07:26:13 -0300 Subject: [PATCH 5/7] test(codegen): drive codegen check from CI, not the SDK test suite The render-fixture check exercises the .trix/client-lib templates and tx3c, not the SDK runtime, so it should not be SDK test code. Removes the Go test and replaces it with a CI-owned shell script that the `codegen` job runs: it invokes `tx3c codegen` directly, smoke-checks the generated surface, and builds the output against this repo's SDK. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/scripts/codegen-check.sh | 43 +++++++++++++ .github/workflows/ci.yml | 5 +- sdk/codegen_test.go | 106 ------------------------------- 3 files changed, 45 insertions(+), 109 deletions(-) create mode 100644 .github/scripts/codegen-check.sh delete mode 100644 sdk/codegen_test.go diff --git a/.github/scripts/codegen-check.sh b/.github/scripts/codegen-check.sh new file mode 100644 index 0000000..06258bb --- /dev/null +++ b/.github/scripts/codegen-check.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +# +# CI artifact — not part of the SDK. +# +# Renders the .trix/client-lib codegen plugin against the shared transfer +# fixture and verifies the result. The subject under test is the Handlebars +# templates + tx3c integration, not the SDK runtime. +# +# Steps: invoke `tx3c codegen`, assert the expected files exist, smoke-check +# the generated surface, and compile the output against this repo's SDK. +# +# Requires `tx3c` and `go` on PATH. +set -euo pipefail + +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +gen="$(mktemp -d)" +trap 'rm -rf "$gen"' EXIT + +tx3c codegen \ + --tii "$repo_root/sdk/testdata/transfer.tii" \ + --template "$repo_root/.trix/client-lib" \ + --output "$gen" + +for f in protocol.go go.mod; do + test -f "$gen/$f" || { echo "missing generated file: $f"; exit 1; } +done + +for sym in \ + 'TargetTIIVersion' \ + 'type TransferParams struct' \ + 'TRANSFER_TIR' \ + 'func (c *Client) Transfer(' \ + 'var Profiles'; do + grep -qF "$sym" "$gen/protocol.go" || { echo "generated protocol.go missing: $sym"; exit 1; } +done + +# Build the rendered package against this repo's SDK, not a published release. +printf 'module codegentest\n\ngo 1.24.2\n\nrequire github.com/tx3-lang/go-sdk/sdk v0.0.0\n\nreplace github.com/tx3-lang/go-sdk/sdk => %s/sdk\n' \ + "$repo_root" > "$gen/go.mod" +cp "$repo_root/sdk/go.sum" "$gen/go.sum" +( cd "$gen" && GOFLAGS=-mod=mod go build ./... ) + +echo "codegen check passed" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 477a4b2..3b20587 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,9 +50,8 @@ jobs: with: channel: beta - - name: Run codegen render-fixture test - working-directory: ./sdk - run: go test -tags=codegen -run TestCodegenClientLib ./... -count=1 + - name: Render and verify codegen plugin + run: bash .github/scripts/codegen-check.sh e2e: name: e2e diff --git a/sdk/codegen_test.go b/sdk/codegen_test.go deleted file mode 100644 index 4c31941..0000000 --- a/sdk/codegen_test.go +++ /dev/null @@ -1,106 +0,0 @@ -//go:build codegen - -// This test exercises the .trix/client-lib codegen plugin (Handlebars -// templates + tx3c), not the SDK runtime. It is gated behind the `codegen` -// build tag so it runs only in the dedicated codegen CI job. -package tx3sdk_test - -import ( - "os" - "os/exec" - "path/filepath" - "strings" - "testing" -) - -// resolveTx3c locates the tx3c binary: TX3_TX3C_PATH first, then $PATH. -func resolveTx3c(t *testing.T) string { - t.Helper() - if p := os.Getenv("TX3_TX3C_PATH"); p != "" { - if info, err := os.Stat(p); err == nil && !info.IsDir() { - return p - } - } - if p, err := exec.LookPath("tx3c"); err == nil { - return p - } - t.Fatal("tx3c not found; set TX3_TX3C_PATH or install tx3c") - return "" -} - -// TestCodegenClientLib renders the .trix/client-lib plugin against the shared -// transfer fixture, asserts the expected public surface is present, and builds -// the result. A successful render that produces uncompilable or empty bindings -// is a failure. -func TestCodegenClientLib(t *testing.T) { - sdkDir, err := os.Getwd() - if err != nil { - t.Fatalf("getwd: %v", err) - } - repoRoot := filepath.Dir(sdkDir) - templateDir := filepath.Join(repoRoot, ".trix", "client-lib") - tiiPath := filepath.Join(sdkDir, "testdata", "transfer.tii") - - if _, err := os.Stat(tiiPath); err != nil { - t.Fatalf("missing TII fixture: %v", err) - } - if _, err := os.Stat(templateDir); err != nil { - t.Fatalf("missing template directory: %v", err) - } - - outDir := t.TempDir() - - render := exec.Command(resolveTx3c(t), "codegen", - "--tii", tiiPath, - "--template", templateDir, - "--output", outDir, - ) - if out, err := render.CombinedOutput(); err != nil { - t.Fatalf("tx3c codegen failed: %v\n%s", err, out) - } - - for _, name := range []string{"protocol.go", "go.mod"} { - if _, err := os.Stat(filepath.Join(outDir, name)); err != nil { - t.Fatalf("expected generated file %s: %v", name, err) - } - } - - // Smoke-test the generated surface: the template must emit protocol - // identity, the per-transaction types, and the profile surface. - src, err := os.ReadFile(filepath.Join(outDir, "protocol.go")) - if err != nil { - t.Fatalf("read generated protocol.go: %v", err) - } - for _, want := range []string{ - "TargetTIIVersion", - "type TransferParams struct", - "TRANSFER_TIR", - "func (c *Client) Transfer(", - "var Profiles", - } { - if !strings.Contains(string(src), want) { - t.Errorf("generated protocol.go missing expected symbol: %s", want) - } - } - - // Build the rendered package against this repo's SDK rather than a - // published release. - goMod := "module codegentest\n\ngo 1.24.2\n\n" + - "require github.com/tx3-lang/go-sdk/sdk v0.0.0\n\n" + - "replace github.com/tx3-lang/go-sdk/sdk => " + sdkDir + "\n" - if err := os.WriteFile(filepath.Join(outDir, "go.mod"), []byte(goMod), 0o644); err != nil { - t.Fatalf("write go.mod: %v", err) - } - if sum, err := os.ReadFile(filepath.Join(sdkDir, "go.sum")); err == nil { - if err := os.WriteFile(filepath.Join(outDir, "go.sum"), sum, 0o644); err != nil { - t.Fatalf("write go.sum: %v", err) - } - } - - build := exec.Command("go", "build", "./...") - build.Dir = outDir - build.Env = append(os.Environ(), "GOFLAGS=-mod=mod") - if out, err := build.CombinedOutput(); err != nil { - t.Fatalf("go build of generated package failed: %v\n%s", err, out) - } -} From 6adbe16de7060a28f390db28a78f3f12e3612535 Mon Sep 17 00:00:00 2001 From: Santiago Date: Wed, 20 May 2026 07:46:08 -0300 Subject: [PATCH 6/7] test(codegen): verify against the published SDK, not in-repo source The codegen check must replicate what a consumer gets: the rendered output resolves the published runtime SDK at the version its generated manifest pins. Drops the patch / replace / paths / editable-install overrides that bound the check to in-repo SDK source. This also exercises the version pin in the generated manifest itself. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/scripts/codegen-check.sh | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/.github/scripts/codegen-check.sh b/.github/scripts/codegen-check.sh index 06258bb..dbe61ed 100644 --- a/.github/scripts/codegen-check.sh +++ b/.github/scripts/codegen-check.sh @@ -3,11 +3,9 @@ # CI artifact — not part of the SDK. # # Renders the .trix/client-lib codegen plugin against the shared transfer -# fixture and verifies the result. The subject under test is the Handlebars -# templates + tx3c integration, not the SDK runtime. -# -# Steps: invoke `tx3c codegen`, assert the expected files exist, smoke-check -# the generated surface, and compile the output against this repo's SDK. +# fixture and verifies the result the way a consumer would: the rendered module +# resolves the published go-sdk at the version its generated go.mod pins — no +# replace directives. # # Requires `tx3c` and `go` on PATH. set -euo pipefail @@ -34,10 +32,6 @@ for sym in \ grep -qF "$sym" "$gen/protocol.go" || { echo "generated protocol.go missing: $sym"; exit 1; } done -# Build the rendered package against this repo's SDK, not a published release. -printf 'module codegentest\n\ngo 1.24.2\n\nrequire github.com/tx3-lang/go-sdk/sdk v0.0.0\n\nreplace github.com/tx3-lang/go-sdk/sdk => %s/sdk\n' \ - "$repo_root" > "$gen/go.mod" -cp "$repo_root/sdk/go.sum" "$gen/go.sum" -( cd "$gen" && GOFLAGS=-mod=mod go build ./... ) +( cd "$gen" && go mod tidy && go build ./... ) echo "codegen check passed" From 6985a0107f52a4b1b11e223405e7c45dfbc3bb3e Mon Sep 17 00:00:00 2001 From: Santiago Date: Wed, 20 May 2026 08:00:14 -0300 Subject: [PATCH 7/7] ci: track the stable tx3 channel for the codegen check Reverts the codegen job's toolchain setup to the default stable channel. The check stays red until a tx3c release carrying the codegen `json` helper reaches stable. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3b20587..242871a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,8 +47,6 @@ jobs: - name: Setup tx3 toolchain uses: tx3-lang/actions/setup@v1 - with: - channel: beta - name: Render and verify codegen plugin run: bash .github/scripts/codegen-check.sh