| 1 | import type { Options } from 'tinyexec' |
| 2 | import fs from 'node:fs/promises' |
| 3 | import process from 'node:process' |
| 4 | import { setTimeout as sleep } from 'node:timers/promises' |
| 5 | import { x } from 'tinyexec' |
| 6 | |
| 7 | async function retry(label: string, fn: () => Promise<unknown>, attempts = 3) { |
| 8 | for (let attempt = 1; ; attempt++) { |
| 9 | try { |
| 10 | await fn() |
| 11 | return |
| 12 | } |
| 13 | catch (error) { |
| 14 | if (attempt >= attempts) |
| 15 | throw error |
| 16 | const delay = attempt * 15_000 |
| 17 | console.warn(`\n${label} failed (attempt ${attempt}/${attempts}), retrying in ${delay / 1000}s...\n`, error) |
| 18 | await sleep(delay) |
| 19 | } |
| 20 | } |
| 21 | } |
| 22 | |
| 23 | async function publish() { |
| 24 | const root = new URL('..', import.meta.url) |
| 25 | const rawJSON = await fs.readFile(new URL('../package.json', import.meta.url), 'utf-8') |
| 26 | const pkg = JSON.parse(rawJSON) |
| 27 | |
| 28 | if (pkg.version.includes('-')) { |
| 29 | console.warn('Skipping publish VS Code extension because the version contains a pre-release tag.') |
| 30 | return |
| 31 | } |
| 32 | |
| 33 | if (!process.env.VSCE_TOKEN) { |
| 34 | console.error('Missing VSCE_TOKEN') |
| 35 | process.exit(1) |
| 36 | } |
| 37 | if (!process.env.OVSX_TOKEN) { |
| 38 | console.error('Missing OVSX_TOKEN') |
| 39 | process.exit(1) |
| 40 | } |
| 41 | |
| 42 | console.log('Publishing VS Code extension...') |
| 43 | |
| 44 | const options: Partial<Options> = { |
| 45 | nodeOptions: { |
| 46 | cwd: root, |
| 47 | stdio: 'inherit', |
| 48 | }, |
| 49 | throwOnError: true, |
| 50 | } |
| 51 | |
| 52 | await x('npm', ['run', 'build'], options) |
| 53 | console.log('\nPublish to VSCE...\n') |
| 54 | await retry( |
| 55 | 'Publish to VSCE', |
| 56 | async () => { |
| 57 | await x( |
| 58 | 'npx', |
| 59 | ['@vscode/vsce', 'publish', '--no-dependencies', '--skip-duplicate', '-p', process.env.VSCE_TOKEN!], |
| 60 | options, |
| 61 | ) |
| 62 | }, |
| 63 | ) |
| 64 | console.log('\nPublish to OVSE...\n') |
| 65 | await retry( |
| 66 | 'Publish to OVSX', |
| 67 | async () => { |
| 68 | await x( |
| 69 | 'npx', |
| 70 | ['ovsx', 'publish', '--no-dependencies', '--skip-duplicate', '-p', process.env.OVSX_TOKEN!], |
| 71 | options, |
| 72 | ) |
| 73 | }, |
| 74 | ) |
| 75 | } |
| 76 | |
| 77 | publish() |
| 78 |