From eaf9bf486a732f9511e3fed7e74a81299a4635cf Mon Sep 17 00:00:00 2001 From: whyour Date: Sat, 22 Aug 2026 15:28:09 +0800 Subject: [PATCH] fix(ci): seed durable package trust in recovery gate --- ...l3-plugin-package-recovery-e2e-fixture.cjs | 58 +++++++++++++++++++ ...gin-package-recovery-e2e-live-contract.cjs | 13 +++++ ...ginPackageRecoveryE2ELiveContract.test.cjs | 10 ++++ 3 files changed, 81 insertions(+) diff --git a/scripts/ql3-plugin-package-recovery-e2e-fixture.cjs b/scripts/ql3-plugin-package-recovery-e2e-fixture.cjs index 111e3783..aa7fa2d2 100644 --- a/scripts/ql3-plugin-package-recovery-e2e-fixture.cjs +++ b/scripts/ql3-plugin-package-recovery-e2e-fixture.cjs @@ -626,6 +626,10 @@ async function runSeed() { loadPostgresConnectionEnvironment, PostgresPluginPackageSecretBindingTransitionRepository, } = ql3Require('@qinglong/cluster-postgres/package-executor'); + const { + assertPostgresPackageManagerSchemaReady, + PostgresPluginPackagePublisherTrustAuthorityRepository, + } = ql3Require('@qinglong/cluster-postgres/package-manager'); const { PostgresPluginPackageInstallRepository } = ql3Require( '@qinglong/cluster-postgres/plugin-package-install', ); @@ -640,6 +644,9 @@ async function runSeed() { const { createPluginPackageSecretBindingTransitionPlan } = ql3Require( '@qinglong/runtime-core/plugin-package-secret-binding-transition-plan', ); + const { createPluginPackagePublisherTrustSnapshot } = ql3Require( + '@qinglong/runtime-core/plugin-package-publisher-trust', + ); const fixture = readFixture(process.env.QL3_E2E_FIXTURE_FILE); const mode = process.env.QL3_E2E_MODE; if (!['seed-initial', 'seed-upgrade', 'commit-transition'].includes(mode)) { @@ -701,6 +708,56 @@ async function runSeed() { } const selected = mode === 'seed-initial' ? fixture.initial : fixture.upgrade; + let publisherTrustStatus = null; + if (mode === 'seed-initial') { + const packageManagerConnection = loadPostgresConnectionEnvironment( + process.env, + { + host: 'QL3_E2E_POSTGRES_HOST', + port: 'QL3_E2E_POSTGRES_PORT', + database: 'QL3_E2E_POSTGRES_DATABASE', + user: 'QL3_E2E_POSTGRES_PACKAGE_MANAGER_USER', + password: 'QL3_E2E_POSTGRES_PACKAGE_MANAGER_PASSWORD', + }, + ); + const packageManagerDatabase = await createPostgresDatabaseOpener({ + role: 'package-manager', + connection: { + ...packageManagerConnection, + tls: { mode: 'disable' }, + }, + pool: { + applicationName: 'qinglong3-plugin-package-e2e-trust-seed', + maxConnections: 1, + connectionTimeoutMs: 15_000, + }, + onPoolError() {}, + })(); + try { + await assertPostgresPackageManagerSchemaReady( + packageManagerDatabase.pool, + ); + const observed = + await new PostgresPluginPackagePublisherTrustAuthorityRepository( + packageManagerDatabase.pool, + ).observeSnapshot({ + authorityId: 'cluster', + snapshot: createPluginPackagePublisherTrustSnapshot( + fixture.trust.keys, + ), + observedBy: 'plugin-recovery-e2e-package-manager', + observedAtMs: selected.lock.createdAtMs, + }); + if (!['created', 'existing'].includes(observed.status)) { + throw new Error( + 'Plugin Package E2E publisher trust authority conflicts with the fixture', + ); + } + publisherTrustStatus = observed.status; + } finally { + await packageManagerDatabase.close(); + } + } const lock = normalizePluginPackageLock(selected.lock); const repository = new PostgresPluginPackageInstallRepository( database.pool, @@ -732,6 +789,7 @@ async function runSeed() { phase: mode === 'seed-initial' ? 'initial' : 'upgrade', status: result.status, state: result.record.state, + publisherTrustStatus, installationId: result.record.installationId, lockDigest: result.record.lockDigest, recordDigest: result.record.recordDigest, diff --git a/scripts/ql3-plugin-package-recovery-e2e-live-contract.cjs b/scripts/ql3-plugin-package-recovery-e2e-live-contract.cjs index ce9e9984..1146d344 100644 --- a/scripts/ql3-plugin-package-recovery-e2e-live-contract.cjs +++ b/scripts/ql3-plugin-package-recovery-e2e-live-contract.cjs @@ -879,6 +879,19 @@ function seedJob(name, mode) { { name: 'QL3_E2E_POSTGRES_HOST', value: POSTGRES_NAME }, { name: 'QL3_E2E_POSTGRES_PORT', value: '5432' }, { name: 'QL3_E2E_POSTGRES_DATABASE', value: 'qinglong' }, + { + name: 'QL3_E2E_POSTGRES_PACKAGE_MANAGER_USER', + value: 'ql3_package_manager', + }, + { + name: 'QL3_E2E_POSTGRES_PACKAGE_MANAGER_PASSWORD', + valueFrom: { + secretKeyRef: { + name: 'ql3-e2e-postgres-auth', + key: 'package-manager-password', + }, + }, + }, { name: 'QL3_E2E_POSTGRES_PACKAGE_EXECUTOR_USER', value: 'ql3_package_executor', diff --git a/test/back/ql3PluginPackageRecoveryE2ELiveContract.test.cjs b/test/back/ql3PluginPackageRecoveryE2ELiveContract.test.cjs index 66610fdd..4cb72caa 100644 --- a/test/back/ql3PluginPackageRecoveryE2ELiveContract.test.cjs +++ b/test/back/ql3PluginPackageRecoveryE2ELiveContract.test.cjs @@ -69,6 +69,16 @@ test('gate runs migration, healthy activation and a durable rejected upgrade', ( ); assert.match(live, /plugin-package-recovery\/base\/recover-job\.yaml/); assert.match(fixture, /PostgresPluginPackageInstallRepository/); + assert.match( + fixture, + /PostgresPluginPackagePublisherTrustAuthorityRepository/, + ); + assert.match(fixture, /createPluginPackagePublisherTrustSnapshot/); + assert.match(fixture, /role: 'package-manager'/); + assert.match(fixture, /authorityId: 'cluster'/); + assert.match(fixture, /publisherTrustStatus/); + assert.match(live, /QL3_E2E_POSTGRES_PACKAGE_MANAGER_USER/); + assert.match(live, /key: 'package-manager-password'/); assert.match( fixture, /PostgresPluginPackageSecretBindingTransitionRepository/,