mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-08-21 22:55:16 +00:00
157 lines
6.1 KiB
JavaScript
157 lines
6.1 KiB
JavaScript
/**
|
|
* @license
|
|
* Copyright 2026 Qwen Team
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import { readFileSync } from 'node:fs';
|
|
import { describe, expect, it } from 'vitest';
|
|
import { getWorkflowJob, getWorkflowStep } from './workflow-helpers.js';
|
|
|
|
const releaseWorkflow = readFileSync(
|
|
'.github/workflows/desktop-release.yml',
|
|
'utf8',
|
|
);
|
|
const syncWorkflow = readFileSync(
|
|
'.github/workflows/sync-desktop-to-oss.yml',
|
|
'utf8',
|
|
);
|
|
const tauriConfig = JSON.parse(
|
|
readFileSync('packages/desktop-shell/src-tauri/tauri.conf.json', 'utf8'),
|
|
);
|
|
|
|
describe('Desktop OSS mirror workflow', () => {
|
|
it('mirrors only published stable Desktop releases', () => {
|
|
expect(syncWorkflow).not.toContain('pull_request:');
|
|
expect(releaseWorkflow).toContain(
|
|
"desktop-release-${{ inputs.dry_run && inputs.version || 'publish' }}",
|
|
);
|
|
const prepare = getWorkflowStep(
|
|
getWorkflowJob(releaseWorkflow, 'prepare'),
|
|
'Resolve version',
|
|
);
|
|
expect(prepare).toContain("IS_DRAFT: '${{ inputs.draft }}'");
|
|
expect(prepare).toContain("IS_DRY_RUN: '${{ inputs.dry_run }}'");
|
|
expect(prepare).toContain("IS_PRERELEASE: '${{ inputs.prerelease }}'");
|
|
expect(prepare).toContain(
|
|
'Published stable Desktop versions must use X.Y.Z',
|
|
);
|
|
expect(prepare).toContain(
|
|
'Desktop prereleases must use a SemVer prerelease suffix',
|
|
);
|
|
|
|
const syncOss = getWorkflowJob(releaseWorkflow, 'sync-oss');
|
|
expect(syncOss).toContain(
|
|
"if: \"${{ github.event_name == 'workflow_dispatch' && inputs.dry_run == false && inputs.draft == false && inputs.prerelease == false && github.repository == 'QwenLM/qwen-code' }}\"",
|
|
);
|
|
expect(syncOss).toContain("- 'publish'");
|
|
expect(syncOss).toContain("source: 'artifact'");
|
|
expect(syncOss).not.toContain('secrets: inherit');
|
|
});
|
|
|
|
it('passes only the OSS credentials into the reusable workflow', () => {
|
|
expect(releaseWorkflow).toContain("permissions:\n contents: 'read'");
|
|
const syncOss = getWorkflowJob(releaseWorkflow, 'sync-oss');
|
|
expect(syncOss).toContain(
|
|
"permissions:\n actions: 'read'\n contents: 'read'",
|
|
);
|
|
for (const secret of [
|
|
'ALIYUN_OSS_ACCESS_KEY_ID',
|
|
'ALIYUN_OSS_ACCESS_KEY_SECRET',
|
|
]) {
|
|
expect(syncWorkflow).toContain(`${secret}:\n required: true`);
|
|
expect(syncOss).toContain(`${secret}: '\${{ secrets.${secret} }}'`);
|
|
}
|
|
});
|
|
|
|
it('publishes verified versioned assets before advancing the OSS feed', () => {
|
|
const sync = getWorkflowJob(syncWorkflow, 'sync');
|
|
const prepare = getWorkflowStep(sync, 'Verify and prepare mirror assets');
|
|
expect(prepare).toContain(
|
|
'--base-url "${ALIYUN_OSS_PUBLIC_BASE_URL}/desktop/v${VERSION}"',
|
|
);
|
|
expect(prepare).toContain('sha256sum -- * > SHA256SUMS.txt');
|
|
|
|
const upload = getWorkflowStep(
|
|
sync,
|
|
'Upload versioned assets to Aliyun OSS',
|
|
);
|
|
expect(upload).toContain('--prefix "desktop/v${VERSION}"');
|
|
|
|
const latest = getWorkflowStep(
|
|
sync,
|
|
'Publish latest manifest to Aliyun OSS',
|
|
);
|
|
expect(latest).toContain("--prefix 'desktop/latest'");
|
|
expect(latest).toContain('dist/desktop/desktop-latest.json');
|
|
expect(latest).not.toContain('.dmg');
|
|
|
|
const verifyIndex = sync.indexOf(
|
|
"name: 'Verify versioned assets on Aliyun OSS'",
|
|
);
|
|
expect(verifyIndex).toBeGreaterThan(0);
|
|
expect(verifyIndex).toBeLessThan(
|
|
sync.indexOf("name: 'Publish latest manifest to Aliyun OSS'"),
|
|
);
|
|
expect(
|
|
getWorkflowStep(sync, 'Verify versioned assets on Aliyun OSS'),
|
|
).toContain('sha256sum -c SHA256SUMS.txt');
|
|
expect(
|
|
getWorkflowStep(sync, 'Verify latest manifest on Aliyun OSS'),
|
|
).toContain('cmp ');
|
|
});
|
|
|
|
it('advances the OSS feed only for the current GitHub stable version', () => {
|
|
const publish = getWorkflowJob(releaseWorkflow, 'publish');
|
|
const updateFeed = getWorkflowStep(publish, 'Update stable updater feed');
|
|
expect(updateFeed).toContain('sort -V');
|
|
expect(updateFeed).toContain(
|
|
'Desktop $RELEASE_VERSION will not replace newer stable feed $current',
|
|
);
|
|
|
|
const sync = getWorkflowJob(syncWorkflow, 'sync');
|
|
const check = getWorkflowStep(
|
|
sync,
|
|
'Check whether release matches GitHub stable feed',
|
|
);
|
|
expect(check).toContain("gh release download 'desktop-latest'");
|
|
expect(check).toContain("SOURCE: '${{ steps.release.outputs.source }}'");
|
|
expect(check).toContain('elif [ "$SOURCE" = \'artifact\' ]; then');
|
|
expect(check).toContain('sort -V');
|
|
expect(check).toContain('GitHub stable feed is already newer at $actual');
|
|
expect(check).toContain(
|
|
'GitHub stable feed is $actual after publishing Desktop $expected',
|
|
);
|
|
expect(check).toContain('echo \'matches=true\' >> "$GITHUB_OUTPUT"');
|
|
expect(check).toContain('echo \'matches=false\' >> "$GITHUB_OUTPUT"');
|
|
expect(check).toContain(
|
|
'expected="$(jq -r \'.version\' dist/desktop/desktop-latest.json)"',
|
|
);
|
|
expect(check).toContain(
|
|
'actual="$(jq -r \'.version\' "$directory/desktop-latest.json")"',
|
|
);
|
|
expect(
|
|
getWorkflowStep(sync, 'Publish latest manifest to Aliyun OSS'),
|
|
).toContain('if: "${{ steps.latest.outputs.matches == \'true\' }}"');
|
|
expect(
|
|
getWorkflowStep(sync, 'Verify latest manifest on Aliyun OSS'),
|
|
).toContain('if: "${{ steps.latest.outputs.matches == \'true\' }}"');
|
|
});
|
|
|
|
it('sync workflow validates stable-only releases in the reusable job', () => {
|
|
expect(syncWorkflow).not.toContain('pull_request:');
|
|
const sync = getWorkflowJob(syncWorkflow, 'sync');
|
|
const resolve = getWorkflowStep(sync, 'Resolve release');
|
|
expect(resolve).toContain('^[0-9]+\\.[0-9]+\\.[0-9]+$');
|
|
expect(resolve).toContain("!= 'artifact'");
|
|
expect(resolve).toContain("!= 'release'");
|
|
expect(getWorkflowStep(sync, 'Download GitHub release assets')).toContain(
|
|
'.isDraft == false and .isPrerelease == false',
|
|
);
|
|
});
|
|
|
|
it('keeps the workflow default aligned with the shipped updater endpoint', () => {
|
|
const firstEndpoint = tauriConfig.plugins.updater.endpoints[0];
|
|
expect(syncWorkflow).toContain(new URL(firstEndpoint).origin);
|
|
});
|
|
});
|