feat: release v0.26 portable i18n and presentation adapters

This commit is contained in:
2026-09-29 13:31:42 +08:00
parent 6a95cad184
commit d1a747c36f
75 changed files with 5681 additions and 52 deletions

View File

@@ -22,7 +22,7 @@ def verify_shared_catalog(cli, temp, env, version):
workspace = temp / "workspace"
(workspace / "internal/apierrors").mkdir(parents=True)
(workspace / "contracts").mkdir()
(workspace / "go.mod").write_text(f"module example.com/releaseWorkspace\n\ngo 1.24.0\nrequire {MODULE} {version}\n")
(workspace / "go.mod").write_text(f"module example.com/releaseWorkspace\n\ngo 1.22.0\nrequire {MODULE} {version}\n")
provider = workspace / "internal/apierrors/catalog.go"
provider.write_text('package apierrors\nimport errors "' + MODULE + '/errors"\n'
'func Catalog() errors.Catalog {return errors.Catalog{DefaultStatus:400,Definitions:map[string]errors.Definition{'
@@ -124,7 +124,7 @@ def main():
checks += ["sharedGoCatalogExport", "documentOnlyErrorSelection", "workspaceCheckNoWrites", "staleCatalogRejected", "twoIndependentServiceBuilds"]
env.update(GO_OMNI_SCAFFOLD_INTEGRATION="1", GO_OMNI_RELEASE_CLI=str(cli), GO_OMNI_RELEASE_VERSION=args.version)
tests = ["TestManagedGeneratedProject", "TestErrorInheritanceConsumer", "TestErrorParamsConsumer", "TestCompatibilityConsumer", "TestBusinessGeneratedProject", "TestPrimitiveArrayConsumer", "TestCopyxThreeEndpointConsumer", "TestGeneratedConfigurationConsumer", "TestGeneratedCORSConsumer"]
tests = ["TestManagedGeneratedProject", "TestErrorInheritanceConsumer", "TestErrorParamsConsumer", "TestCompatibilityConsumer", "TestBusinessGeneratedProject", "TestPrimitiveArrayConsumer", "TestCopyxThreeEndpointConsumer", "TestGeneratedConfigurationConsumer", "TestGeneratedCORSConsumer", "TestI18nGeneratedConsumer"]
print("Running generated consumers against the remote framework, including lifecycle failure cleanup", flush=True)
output = run(["go", "test", "-race", "-count=1", "-json", "-timeout=240s", "./cmd/go-omni/apigen", "-run", "^(" + "|".join(tests) + ")$"], ROOT, env)
events = [json.loads(line) for line in output.splitlines() if line.startswith("{")]
@@ -162,7 +162,11 @@ def main():
"copyx": {"TestCheckTypesAndEmptyCollections", "TestCheckRulesAndConverterBoundaries", "TestCopierCheckConcurrentAndOptionsIsolation"},
"logx": {"TestLoggerTimeZoneIsolation", "TestLoggerTimeZoneValidationAndDST", "TestLoggerTimeZoneConcurrentChildren"},
"cors": {"TestPolicyPreflightAndActual", "TestPolicyValidation", "TestPolicyCredentialsWildcardAndDuplicates", "TestPolicyPreservesHTTPAndSnapshot"},
"app": {"TestAppCORSRoutingAndErrors", "TestAppCORSConfigIsolation", "TestCORSTransports"},
"app": {"TestAppCORSRoutingAndErrors", "TestAppCORSConfigIsolation", "TestCORSTransports", "TestI18nRouteScopesEarlyFailuresAndReplay", "TestI18nExplicitProtocolsAndConcurrentApps", "TestI18nAdapterFailurePreservesBusiness"},
"contract": {"TestBodyPolicyPropagatesOuterLimit", "TestJSONClosingDelimiterPreservesReaderCause"},
"i18n": {"TestIndependentImmutableBundlesAndFallback", "TestResourceAndParameterDiagnostics", "TestStrictLoadingAndExplicitOverlay", "TestPinnedCLDRSamples", "TestBrowserConformance", "TestSourceLocaleCanBeFallbackOnly", "TestTypeScriptConsumer"},
"i18n/httpi18n": {"TestNegotiationAndExplicitResolvers"},
"i18n/errori18n": {"TestCatalogAdapterIsExplicitAndDetached"},
"database": {"TestInTxStagesAndCauses", "TestInTxCommitOutcomeUnknown", "TestInTxCancellationAndOwnership", "TestInTxCancellationRace", "TestInTxSuccessPanicAndConcurrency", "TestInTxPublicErrorCompatibility"},
}.items():
output = run(["go", "test", "-race", "-count=1", "-json", MODULE + "/" + package], starter, env)
@@ -179,6 +183,30 @@ def main():
"remoteCancellationOutcomeUnknown", "remoteTransactionPanicAndConcurrency",
"remoteTransactionPublicErrors", "remoteTransactionExample"]
downloaded = Path(dependency["Dir"])
example = downloaded / "examples/i18n"
resources = ["--config", example / "config.json", "--resource", example / "locales/ui.en.json",
"--resource", example / "locales/ui.zh-Hans.json"]
assert json.loads(run([cli, "i18n", "check", *resources], starter, env)) == []
pack = json.loads(run([cli, "i18n", "export", *resources, "--locale", "zh-Hans", "--namespace", "ui"], starter, env))
assert pack["locale"] == "zh-Hans" and pack["ruleVersion"] == "cldr-46.1"
assert "UNICODE LICENSE" in pack["license"]
assert {doc["namespace"] for doc in pack["documents"]} == {"ui"}
types = run([cli, "i18n", "types", *resources, "--namespace", "ui"], starter, env)
assert "export type Translate" in types and "bigint" in types
extracted = json.loads(run([cli, "i18n", "extract", "--go", example / "main.go"], starter, env))
assert any(ref["namespace"] == "ui" and ref["key"] == "greeting" for ref in extracted["references"])
catalog_path = temp / "catalog.json"
catalog_path.write_text(run(["go", "run", MODULE + "/examples/i18n", "-catalog"], starter, env))
source = json.loads(run([cli, "i18n", "extract", "--catalog", catalog_path, "--locale", "en", "--namespace", "errors"], starter, env))
assert source["messages"]["LIMIT_EXCEEDED"]["params"] == {"max": "integer"}
browser_output = run(["node", "--test", downloaded / "i18n/browser/runtime.test.mjs"], starter, env)
assert "# fail 0" in browser_output
checks += ["remoteI18nRuntimeRace", "remoteI18nGeneratedConsumer", "remoteI18nHTTPBusinessInvariants",
"remoteI18nSourceOnlyFallback", "remoteCLDRSamplesAndBrowserConformance", "remoteTypeScriptConsumer",
"remoteI18nCLIExtractionCheckExportTypes", "remoteI18nNamespaceIsolation",
"remoteBrowserRaceAndFailureRetention", "remoteJSONReaderCausePreservation"]
checks += ["flatFieldComposition", "copyxThreeEndpointConsumer", "explicitNullAndMoneyPolicies", "fieldAdditionWithoutCopyRuleChanges", "middlewareFactoryInjectionAndCleanup", "optionalRepositoryPreservesBusiness"]
checks += ["generatedUnifiedConfig", "jsonYamlXmlAndCustomDecoder", "configValidationBeforeDependencies", "configEnvProvenance", "configExtensionPreserved", "configLoaderDriftCheck"]
@@ -201,6 +229,8 @@ def main():
sources += [str(p.relative_to(ROOT)) for p in (ROOT / "cors").glob("*.go")]
sources += ["app/cors_test.go", "cmd/go-omni/apigen/corsConsumer_test.go", "cmd/go-omni/apigen/testdata/cors/consumer_test.go", "examples/cors/main.go", "examples/cors/config.yaml", "scripts/corsBrowser/main.go"]
sources += ["database/transaction.go", "database/transaction_test.go", "database/transactionResponse_test.go", "database/mysqlConnector_test.go", "examples/transactions/main.go", "examples/transactions/demoDriver.go"]
sources += [str(p.relative_to(ROOT)) for directory in ("i18n", "examples/i18n") for p in (ROOT / directory).rglob("*") if p.is_file()]
sources += ["app/i18n_test.go", "errors/localization.go", "cmd/go-omni/i18n.go", "cmd/go-omni/apigen/i18nVersion.go", "cmd/go-omni/apigen/testdata/i18n/consumer_test.go", "contract/policy_test.go"]
report = {"passed": True, "frameworkVersion": args.version, "frameworkSum": dependency["Sum"],
"freshModuleCache": True, "noLocalReplace": True,
"durationSeconds": round(time.monotonic() - started, 2), "checks": checks,