137 lines
3.6 KiB
JavaScript
137 lines
3.6 KiB
JavaScript
import { mkdtempSync, readFileSync, rmSync } from 'node:fs'
|
|
import { tmpdir } from 'node:os'
|
|
import { join } from 'node:path'
|
|
import { describe, expect, it, vi } from 'vitest'
|
|
import {
|
|
isReleaseCutDraft,
|
|
publishCompleteDraftReleases,
|
|
writeGithubOutputs
|
|
} from './publish-complete-draft-releases.mjs'
|
|
|
|
function jsonResponse(body, init = {}) {
|
|
return {
|
|
ok: init.ok ?? true,
|
|
status: init.status ?? 200,
|
|
statusText: init.statusText ?? 'OK',
|
|
json: vi.fn(async () => body),
|
|
text: vi.fn(async () => (typeof body === 'string' ? body : JSON.stringify(body)))
|
|
}
|
|
}
|
|
|
|
describe('isReleaseCutDraft', () => {
|
|
it('only accepts bot-authored desktop draft releases', () => {
|
|
expect(
|
|
isReleaseCutDraft({
|
|
draft: true,
|
|
tag_name: 'v1.4.2-rc.7',
|
|
author: { login: 'github-actions[bot]' }
|
|
})
|
|
).toBe(true)
|
|
expect(
|
|
isReleaseCutDraft({
|
|
draft: true,
|
|
tag_name: 'mobile-v0.0.7',
|
|
author: { login: 'github-actions[bot]' }
|
|
})
|
|
).toBe(false)
|
|
expect(
|
|
isReleaseCutDraft({
|
|
draft: true,
|
|
tag_name: 'v1.4.2',
|
|
author: { login: 'github-actions[bot]' }
|
|
})
|
|
).toBe(false)
|
|
expect(
|
|
isReleaseCutDraft({
|
|
draft: false,
|
|
tag_name: 'v1.4.2',
|
|
author: { login: 'github-actions[bot]' }
|
|
})
|
|
).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('publishCompleteDraftReleases', () => {
|
|
it('publishes complete release-cut drafts and skips incomplete ones', async () => {
|
|
const fetchImpl = vi
|
|
.fn()
|
|
.mockResolvedValueOnce(
|
|
jsonResponse([
|
|
{
|
|
id: 7,
|
|
draft: true,
|
|
tag_name: 'v1.4.2-rc.7',
|
|
created_at: '2026-05-15T07:31:19Z',
|
|
author: { login: 'github-actions[bot]' }
|
|
},
|
|
{
|
|
id: 8,
|
|
draft: true,
|
|
tag_name: 'v1.4.2-rc.8',
|
|
created_at: '2026-05-15T10:51:57Z',
|
|
author: { login: 'github-actions[bot]' }
|
|
}
|
|
])
|
|
)
|
|
.mockResolvedValueOnce(jsonResponse({ tag_name: 'v1.4.2-rc.7', draft: false }))
|
|
const verifyReleaseAssets = vi.fn(async ({ tag }) => {
|
|
if (tag === 'v1.4.2-rc.8') {
|
|
throw new Error('Release v1.4.2-rc.8 is missing required assets.')
|
|
}
|
|
})
|
|
const log = vi.fn()
|
|
|
|
const result = await publishCompleteDraftReleases({
|
|
repo: 'stablyai/orca',
|
|
token: 'token',
|
|
fetchImpl,
|
|
verifyReleaseAssets,
|
|
log
|
|
})
|
|
|
|
expect(result).toEqual({
|
|
published: ['v1.4.2-rc.7'],
|
|
skipped: [
|
|
{
|
|
tag: 'v1.4.2-rc.8',
|
|
reason: 'Release v1.4.2-rc.8 is missing required assets.'
|
|
}
|
|
]
|
|
})
|
|
expect(fetchImpl).toHaveBeenLastCalledWith(
|
|
'https://api.github.com/repos/stablyai/orca/releases/7',
|
|
expect.objectContaining({
|
|
method: 'PATCH',
|
|
body: JSON.stringify({ draft: false, prerelease: true })
|
|
})
|
|
)
|
|
})
|
|
})
|
|
|
|
describe('writeGithubOutputs', () => {
|
|
it('writes count outputs for workflow conditions', () => {
|
|
const dir = mkdtempSync(join(tmpdir(), 'orca-release-outputs-'))
|
|
const outputPath = join(dir, 'output')
|
|
try {
|
|
writeGithubOutputs(
|
|
{
|
|
published: ['v1.4.2-rc.7'],
|
|
skipped: [{ tag: 'v1.4.2-rc.8', reason: 'missing assets' }]
|
|
},
|
|
outputPath
|
|
)
|
|
|
|
expect(readFileSync(outputPath, 'utf8')).toBe(
|
|
`${[
|
|
'published_count=1',
|
|
'skipped_count=1',
|
|
'published_tags=v1.4.2-rc.7',
|
|
'skipped_tags=v1.4.2-rc.8'
|
|
].join('\n')}\n`
|
|
)
|
|
} finally {
|
|
rmSync(dir, { recursive: true, force: true })
|
|
}
|
|
})
|
|
})
|