mirror of
https://github.com/langgenius/dify.git
synced 2026-06-16 22:11:09 +08:00
88 lines
3.5 KiB
TypeScript
88 lines
3.5 KiB
TypeScript
import { spawnSync } from 'node:child_process'
|
|
import { fileURLToPath } from 'node:url'
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
const SCRIPT = fileURLToPath(new URL('./release-r2-publish.sh', import.meta.url))
|
|
|
|
// Stub `aws` + `curl` + `node` as shell functions that just log action verbs to
|
|
// $ORDER_LOG, then run the publish `main` and assert the order of operations.
|
|
function runPublish(): { code: number, order: string[], stderr: string } {
|
|
const stub = [
|
|
'ORDER_LOG="$(mktemp)"',
|
|
'aws() {',
|
|
' case "$*" in',
|
|
' *"list-objects-v2"*) echo list-survivors >>"$ORDER_LOG" ;;',
|
|
' *" cp "*"/index.json"*) echo put-index >>"$ORDER_LOG" ;;',
|
|
' *" cp "*"/manifest.json"*) echo put-manifest >>"$ORDER_LOG" ;;',
|
|
' *" sync "*) echo sync-binaries >>"$ORDER_LOG" ;;',
|
|
' *"head-object"*) echo head-verify >>"$ORDER_LOG" ;;',
|
|
' *) : ;;',
|
|
' esac',
|
|
'}',
|
|
'curl() { echo "{}"; }',
|
|
'node() {',
|
|
' case "$*" in',
|
|
' *release-naming.mjs*targets*)',
|
|
' printf \'bun-linux-x64\\tlinux-x64\\t0\\nbun-linux-arm64\\tlinux-arm64\\t0\\nbun-darwin-x64\\tdarwin-x64\\t0\\nbun-darwin-arm64\\tdarwin-arm64\\t0\\nbun-windows-x64\\twindows-x64\\t1\\n\' ;;',
|
|
' *release-naming.mjs*\' asset \'*) printf \'difyctl-vX\\n\' ;;',
|
|
' *release-r2-edge.mjs*\' index \'*) echo \'{}\' ;;',
|
|
' *release-r2-edge.mjs*\' manifest \'*) echo \'{}\' ;;',
|
|
' *) : ;;',
|
|
' esac',
|
|
'}',
|
|
].join('\n')
|
|
const program = [
|
|
stub,
|
|
`. "${SCRIPT}"`,
|
|
'publish_main edge 0.1.0-edge.2fd7b82',
|
|
'cat "$ORDER_LOG"',
|
|
].join('\n')
|
|
// bash, NOT sh: the script uses BASH_SOURCE + process substitution.
|
|
const r = spawnSync('bash', ['-c', program], {
|
|
encoding: 'utf8',
|
|
env: {
|
|
...process.env,
|
|
RELEASE_PUBLISH_LIB: '1',
|
|
DIFYCTL_R2_S3_ENDPOINT: 'https://endpoint.example',
|
|
DIFYCTL_R2_BUCKET: 'cli-dev',
|
|
DIFYCTL_R2_PUBLIC_BASE: 'https://pub.example.r2.dev',
|
|
DIST_DIR: '/tmp',
|
|
},
|
|
})
|
|
return { code: r.status ?? 1, order: (r.stdout ?? '').trim().split('\n').filter(Boolean), stderr: r.stderr ?? '' }
|
|
}
|
|
|
|
describe('release-r2-publish order', () => {
|
|
it('uploads binaries, verifies, lists survivors, then index, then manifest', () => {
|
|
const { code, order } = runPublish()
|
|
expect(code).toBe(0)
|
|
expect(order.indexOf('sync-binaries')).toBeLessThan(order.indexOf('head-verify'))
|
|
expect(order.indexOf('head-verify')).toBeLessThan(order.indexOf('list-survivors'))
|
|
expect(order.indexOf('list-survivors')).toBeLessThan(order.indexOf('put-index'))
|
|
expect(order.indexOf('put-index')).toBeLessThan(order.indexOf('put-manifest'))
|
|
// pointer is never pruned here — deletion is owned by the R2 lifecycle rule
|
|
expect(order).not.toContain('prune')
|
|
})
|
|
|
|
it('exits non-zero when no targets resolve (head-verify safety gate)', () => {
|
|
const stub = [
|
|
'aws() { :; }',
|
|
'curl() { echo "{}"; }',
|
|
'node() { case "$*" in *release-naming.mjs*targets*) : ;; *) echo "{}" ;; esac; }',
|
|
].join('\n')
|
|
const program = [stub, `. "${SCRIPT}"`, 'publish_main edge 0.1.0-edge.2fd7b82'].join('\n')
|
|
const r = spawnSync('bash', ['-c', program], {
|
|
encoding: 'utf8',
|
|
env: {
|
|
...process.env,
|
|
RELEASE_PUBLISH_LIB: '1',
|
|
DIFYCTL_R2_S3_ENDPOINT: 'https://endpoint.example',
|
|
DIFYCTL_R2_BUCKET: 'cli-dev',
|
|
DIFYCTL_R2_PUBLIC_BASE: 'https://pub.example.r2.dev',
|
|
DIST_DIR: '/tmp',
|
|
},
|
|
})
|
|
expect(r.status).not.toBe(0)
|
|
})
|
|
})
|