dify/cli/scripts/release-r2-publish.test.ts
Stephen Zhou a84c2d36a3
style: format with vp fmt (#38803)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-12 15:57:46 +00:00

92 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)
})
})