feat(deploy): register n8n publisher replace v2

This commit is contained in:
Codex
2026-07-21 13:39:15 +03:00
parent 92d292ce87
commit 9bebd2f504
4 changed files with 54 additions and 28 deletions
@@ -23,17 +23,17 @@ BUILDER_PATH = SCRIPT_DIR / "build-engine-n8n-private-extension-artifact.mjs"
STAGE_ARTIFACT = (
PLATFORM_ROOT
/ "infra/deploy-artifacts"
/ "nodedc-n8n-private-extension-n8n-nodes-ndc-provider-rotating-access-20260718-006.tgz"
/ "nodedc-n8n-private-extension-n8n-nodes-ndc-geozone-replace-20260720-017.tgz"
)
PREDECESSOR_ARTIFACT = (
PLATFORM_ROOT
/ "infra/deploy-artifacts"
/ "nodedc-engine-n8n-private-extension-20260717-005.tgz"
/ "nodedc-engine-n8n-private-extension-20260718-008.tgz"
)
TRANSITION_ID = "20260718-008"
SEALED_RELEASE_ID = "0.1.4-59dc9f7882721d6a"
SEALED_PACKAGE_SHA256 = "59dc9f7882721d6a5e2ae84ffa6aa8cd9bc5432f5904d24e70e363573ed2757f"
PREDECESSOR_RELEASE_ID = "0.1.3-3354149b5245e39a"
TRANSITION_ID = "20260721-005"
SEALED_RELEASE_ID = "0.1.5-3c8ae53f010d7c88"
SEALED_PACKAGE_SHA256 = "3c8ae53f010d7c88b6e90cb8fc4929e7d0880089ad8c3a9edb876ce034786743"
PREDECESSOR_RELEASE_ID = "0.1.4-59dc9f7882721d6a"
BUILDER_ENGINE_PATHS = (
"nodedc-source/server/assets/n8n/schema/v2.3.2/nodes.catalog.json",
"nodedc-source/server/assets/n8n/schema/v2.3.2/credentials.catalog.json",
@@ -54,7 +54,7 @@ EXPECTED_CREDENTIALS = [
"ndcFoundryBindingApi",
"ndcProviderRotatingAccessApi",
]
PREDECESSOR_CREDENTIALS = EXPECTED_CREDENTIALS[:3]
PREDECESSOR_CREDENTIALS = EXPECTED_CREDENTIALS
PRIVATE_EXTENSION_CANON_FUNCTION_SHA256 = {
"expected_engine_n8n_compose_override": "8ee93f3e7c407f5557c711119236449a440d73a7fcac1bbfa50a09e6a13c1cff",
"engine_n8n_package_loader_probe_script": "2b3b3c96fad6e5e48ebea74426b21bc7eea6b6fe0e786b537da3366d18aedd9b",
@@ -176,7 +176,8 @@ class EngineN8nPrivateExtensionTest(unittest.TestCase):
cases = (
([], "transition_id_required"),
(["20260718-007"], "transition_id_already_issued"),
(["engine-n8n-private-extension-20260718-008"], "transition_id_invalid"),
(["20260718-008"], "transition_id_already_issued"),
(["engine-n8n-private-extension-20260721-005"], "transition_id_invalid"),
(["20260230-004"], "transition_id_invalid"),
(["20260717-000"], "transition_id_invalid"),
([TRANSITION_ID, "unexpected-second-id"], "transition_id_argument_count_invalid"),
@@ -245,6 +246,11 @@ class EngineN8nPrivateExtensionTest(unittest.TestCase):
self.assertEqual([item["name"] for item in private_credentials], EXPECTED_CREDENTIALS)
self.assertTrue(all("usableAsTool" not in item for item in private_nodes))
self.assertEqual((len(nodes), len(credentials)), (437, 389))
publisher = next(item for item in private_nodes if item["name"].endswith(".ndcDataProductPublish"))
self.assertEqual(publisher["version"], [1, 2])
publish_mode = next(item for item in publisher["properties"] if item["name"] == "publishMode")
self.assertEqual([item["value"] for item in publish_mode["options"]], ["upsert", "replace"])
self.assertEqual(publish_mode["displayOptions"]["show"]["@version"], [2])
def test_rollback_catalog_restores_verified_predecessor_release(self):
with tempfile.TemporaryDirectory() as directory:
@@ -267,7 +273,7 @@ class EngineN8nPrivateExtensionTest(unittest.TestCase):
[item.get("name") for item in credentials if item.get("name") in PREDECESSOR_CREDENTIALS],
PREDECESSOR_CREDENTIALS,
)
self.assertEqual((len(nodes), len(credentials)), (437, 388))
self.assertEqual((len(nodes), len(credentials)), (437, 389))
def test_compose_override_is_runner_derived_and_offline(self):
with tempfile.TemporaryDirectory() as directory:
@@ -282,7 +288,7 @@ class EngineN8nPrivateExtensionTest(unittest.TestCase):
self.assertEqual(override, RUNNER.expected_engine_n8n_compose_override(descriptor))
self.assertEqual(
hashlib.sha256(override.encode("utf-8")).hexdigest(),
"d6d1249e93b5bed5e697715b6b773c7efa4ac234f12eab57d868407e6bb5390e",
"304377edf7d0e184fa4156475df74b7a807a47e4472c8d8e13102639eb9e9d0b",
)
self.assertIn("pull_policy: never", override)
self.assertIn("N8N_USER_FOLDER: /home/node", override)
@@ -574,7 +580,7 @@ class EngineN8nPrivateExtensionTest(unittest.TestCase):
def test_sealed_release_exact_set_includes_implicit_directories(self):
release_relative = Path(
"payload/releases/n8n-nodes-ndc/0.1.4-59dc9f7882721d6a"
"payload/releases/n8n-nodes-ndc/0.1.5-3c8ae53f010d7c88"
)
with tempfile.TemporaryDirectory() as directory:
work = Path(directory)