Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ jobs:
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
node-version: '22.23.1'
cache: npm
cache-dependency-path: |
package-lock.json
Expand Down Expand Up @@ -371,6 +371,28 @@ jobs:
- name: Check Extension public release gate (host-native Windows)
run: npm run check:extension-release-gate

- name: Build and smoke standalone TUI (host-native Windows)
shell: pwsh
run: |
$version = node -p "require('./kun/package.json').version"
$env:KUN_APP_VERSION = $version
$env:KUN_ARTIFACT_VERSION = $version
$env:KUN_UPDATE_CHANNEL = 'stable'
$env:RELEASE_CHANNEL = 'stable'
npm run build:kun
npm run package:tui -- `
--version $version `
--artifact-version $version `
--tag "v$version" `
--channel stable `
--commit $env:GITHUB_SHA `
--target win32-x64 `
--output dist/tui-pr
npm run smoke:standalone-tui -- `
--artifact "dist/tui-pr/Kun-TUI-$version-win-x64.zip" `
--version $version `
--target win32-x64

- name: Build Windows NSIS installer
run: npm run dist:win

Expand Down
21 changes: 19 additions & 2 deletions scripts/smoke-standalone-tui.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,22 @@ import { mkdtemp, readFile, rm, stat } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { basename, dirname, join, resolve } from 'node:path'
import { pathToFileURL } from 'node:url'
import extractZip from 'extract-zip'

export function createArchiveExtractionInvocation(
artifact,
destination,
pathApi = { basename, dirname }
) {
if (artifact.toLowerCase().endsWith('.zip')) {
return {
kind: 'zip',
artifact,
options: { dir: destination }
}
}
return {
kind: 'tar',
command: 'tar',
args: ['-xf', pathApi.basename(artifact), '-C', destination],
options: {
Expand All @@ -22,15 +31,23 @@ export function createArchiveExtractionInvocation(
}
}

export async function extractArchive(artifact, destination) {
const extraction = createArchiveExtractionInvocation(artifact, destination)
if (extraction.kind === 'zip') {
await extractZip(extraction.artifact, extraction.options)
} else {
execFileSync(extraction.command, extraction.args, extraction.options)
}
}

async function main() {
const flags = readFlags(process.argv.slice(2))
const artifact = resolve(required(flags, 'artifact'))
const expectedVersion = required(flags, 'version')
const expectedTarget = required(flags, 'target')
const temporary = await mkdtemp(join(tmpdir(), 'kun-tui-smoke-'))
try {
const extraction = createArchiveExtractionInvocation(artifact, temporary)
execFileSync(extraction.command, extraction.args, extraction.options)
await extractArchive(artifact, temporary)
const root = join(temporary, 'kun')
const release = JSON.parse(await readFile(join(root, 'release.json'), 'utf8'))
if (release.version !== expectedVersion || release.target !== expectedTarget) {
Expand Down
57 changes: 44 additions & 13 deletions scripts/smoke-standalone-tui.test.mjs
Original file line number Diff line number Diff line change
@@ -1,27 +1,58 @@
import assert from 'node:assert/strict'
import { win32 } from 'node:path'
import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join, posix, win32 } from 'node:path'
import test from 'node:test'
import { createArchiveExtractionInvocation } from './smoke-standalone-tui.mjs'
import {
createArchiveExtractionInvocation,
extractArchive
} from './smoke-standalone-tui.mjs'

test('extracts a Windows TUI archive without passing the drive-qualified path to tar', () => {
const ZIP_FIXTURE = Buffer.from(
'UEsDBBQAAAgIADJT/1zKTlJ0CQAAAAcAAAAJAAAAcHJvYmUudHh0q8os0M3P5gIAUEsBAj8DFAAACAgAMlP/XMpOUnQJAAAABwAAAAkACQAAAAAAAAAAALSBAAAAAHByb2JlLnR4dFVUBQADoAdsalBLBQYAAAAAAQABAEAAAAAwAAAAAAA=',
'base64'
)

test('extracts a Windows TUI ZIP without passing it to tar', () => {
assert.deepEqual(
createArchiveExtractionInvocation(
'D:\\a\\Kun\\Kun\\dist\\Kun-TUI-0.2.32-win-x64.zip',
'C:\\Users\\runner\\Temp\\kun-tui-smoke',
win32
),
{
kind: 'zip',
artifact: 'D:\\a\\Kun\\Kun\\dist\\Kun-TUI-0.2.32-win-x64.zip',
options: { dir: 'C:\\Users\\runner\\Temp\\kun-tui-smoke' }
}
)
})

test('extracts a TUI tarball from its local directory', () => {
assert.deepEqual(
createArchiveExtractionInvocation(
'/release/Kun-TUI-0.2.32-linux-x64.tar.gz',
'/tmp/kun-tui-smoke',
posix
),
{
kind: 'tar',
command: 'tar',
args: [
'-xf',
'Kun-TUI-0.2.32-win-x64.zip',
'-C',
'C:\\Users\\runner\\Temp\\kun-tui-smoke'
],
options: {
cwd: 'D:\\a\\Kun\\Kun\\dist',
stdio: 'inherit'
}
args: ['-xf', 'Kun-TUI-0.2.32-linux-x64.tar.gz', '-C', '/tmp/kun-tui-smoke'],
options: { cwd: '/release', stdio: 'inherit' }
}
)
})

test('extracts ZIP contents through the Node ZIP implementation', async () => {
const temporary = await mkdtemp(join(tmpdir(), 'kun-tui-zip-test-'))
try {
const archive = join(temporary, 'probe.zip')
const destination = join(temporary, 'extracted')
await writeFile(archive, ZIP_FIXTURE)
await extractArchive(archive, destination)
assert.equal(await readFile(join(destination, 'probe.txt'), 'utf8'), 'zip-ok\n')
} finally {
await rm(temporary, { recursive: true, force: true })
}
})
Loading