feat(release,build,tests): add automated multi-platform release pipeline and align runtime, model, and test updates

This commit is contained in:
2026-03-20 13:56:43 +00:00
parent 4d561b3874
commit b05c53f967
25 changed files with 3747 additions and 941 deletions

View File

@@ -1,17 +1,37 @@
/**
* Test configuration for Stack.Gallery Registry tests
* Uses @push.rocks/qenv to read from .nogit/env.json
*/
import { Qenv } from '@push.rocks/qenv';
const testQenv = new Qenv('./', '.nogit/', false);
const mongoUrl = await testQenv.getEnvVarOnDemand('MONGODB_URL')
|| 'mongodb://testadmin:testpass@localhost:27117/test-registry?authSource=admin';
const mongoName = await testQenv.getEnvVarOnDemand('MONGODB_NAME')
|| 'test-registry';
const s3Endpoint = await testQenv.getEnvVarOnDemand('S3_ENDPOINT') || 'localhost';
const s3Port = await testQenv.getEnvVarOnDemand('S3_PORT') || '9100';
const s3AccessKey = await testQenv.getEnvVarOnDemand('S3_ACCESSKEY') || 'testadmin';
const s3SecretKey = await testQenv.getEnvVarOnDemand('S3_SECRETKEY') || 'testpassword';
const s3Bucket = await testQenv.getEnvVarOnDemand('S3_BUCKET') || 'test-registry';
const s3UseSsl = await testQenv.getEnvVarOnDemand('S3_USESSL');
const s3Protocol = s3UseSsl === 'true' ? 'https' : 'http';
const s3EndpointUrl = `${s3Protocol}://${s3Endpoint}:${s3Port}`;
export const testConfig = {
mongodb: {
url: 'mongodb://testadmin:testpass@localhost:27117/test-registry?authSource=admin',
name: 'test-registry',
url: mongoUrl,
name: mongoName,
},
s3: {
endpoint: 'http://localhost:9100',
accessKey: 'testadmin',
secretKey: 'testpassword',
bucket: 'test-registry',
endpoint: s3EndpointUrl,
accessKey: s3AccessKey,
secretKey: s3SecretKey,
bucket: s3Bucket,
region: 'us-east-1',
},
jwt: {
@@ -35,26 +55,8 @@ export const testConfig = {
};
/**
* Get test config with environment variable overrides
* Get test config (kept for backward compatibility)
*/
export function getTestConfig() {
return {
...testConfig,
mongodb: {
...testConfig.mongodb,
url: Deno.env.get('TEST_MONGODB_URL') || testConfig.mongodb.url,
name: Deno.env.get('TEST_MONGODB_NAME') || testConfig.mongodb.name,
},
s3: {
...testConfig.s3,
endpoint: Deno.env.get('TEST_S3_ENDPOINT') || testConfig.s3.endpoint,
accessKey: Deno.env.get('TEST_S3_ACCESS_KEY') || testConfig.s3.accessKey,
secretKey: Deno.env.get('TEST_S3_SECRET_KEY') || testConfig.s3.secretKey,
bucket: Deno.env.get('TEST_S3_BUCKET') || testConfig.s3.bucket,
},
registry: {
...testConfig.registry,
url: Deno.env.get('TEST_REGISTRY_URL') || testConfig.registry.url,
},
};
return testConfig;
}

View File

@@ -46,10 +46,9 @@ describe('Package Model', () => {
return {
version,
publishedAt: new Date(),
publishedBy: testUserId,
publishedById: testUserId,
size: 1024,
checksum: `sha256-${crypto.randomUUID()}`,
checksumAlgorithm: 'sha256',
digest: `sha256:${crypto.randomUUID()}`,
downloads: 0,
metadata: {},
};
@@ -124,7 +123,7 @@ describe('Package Model', () => {
await createPackage('find-this');
await createPackage('other');
const results = await Package.search('search');
const results = await Package.searchPackages('search');
assertEquals(results.length, 1);
assertEquals(results[0].name, 'search-me');
});
@@ -134,14 +133,14 @@ describe('Package Model', () => {
pkg.description = 'A unique description for testing';
await pkg.save();
const results = await Package.search('unique description');
const results = await Package.searchPackages('unique description');
assertEquals(results.length, 1);
});
it('should filter by protocol', async () => {
await createPackage('npm-pkg');
const results = await Package.search('npm', { protocol: 'oci' });
const results = await Package.searchPackages('npm', { protocol: 'oci' });
assertEquals(results.length, 0);
});
@@ -150,10 +149,10 @@ describe('Package Model', () => {
await createPackage('page2');
await createPackage('page3');
const firstPage = await Package.search('page', { limit: 2, offset: 0 });
const firstPage = await Package.searchPackages('page', { limit: 2, offset: 0 });
assertEquals(firstPage.length, 2);
const secondPage = await Package.search('page', { limit: 2, offset: 2 });
const secondPage = await Package.searchPackages('page', { limit: 2, offset: 2 });
assertEquals(secondPage.length, 1);
});
});

View File

@@ -104,8 +104,8 @@ describe('TokenService', () => {
const validation = await tokenService.validateToken(rawToken, '127.0.0.1');
assertExists(validation);
assertEquals(validation.userId, testUserId);
assertEquals(validation.protocols.includes('npm'), true);
assertEquals(validation.token!.userId, testUserId);
assertEquals(validation.token!.protocols.includes('npm'), true);
});
it('should reject invalid token format', async () => {