From c4c582c883b077f9e36b5a005886df218a354f5b Mon Sep 17 00:00:00 2001 From: David Crespo Date: Wed, 18 Mar 2026 16:38:18 -0500 Subject: [PATCH 1/4] make bump-omicron script prompt for description --- tools/deno/bump-omicron.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tools/deno/bump-omicron.ts b/tools/deno/bump-omicron.ts index fc1335a51..9324212c0 100755 --- a/tools/deno/bump-omicron.ts +++ b/tools/deno/bump-omicron.ts @@ -27,7 +27,6 @@ Usage: Options: -d, --dry-run Dry run, showing changes without creating PR -h, --help Show this help message - -m, --message Add message to PR title: 'Bump web console ()' ` const OMICRON_DIR = path.resolve('../omicron') @@ -159,7 +158,7 @@ async function makeOmicronPR( // wrapped in a function so we can do early returns rather than early // Deno.exits, which mess up the worktree cleanup -async function run(commitIsh: string, dryRun: boolean, messageArg: string | undefined) { +async function run(commitIsh: string, dryRun: boolean) { // Ensure local main matches the remote so we don't bump to a stale commit if (commitIsh === 'main') { const localMain = await $`git rev-parse main`.text() @@ -186,9 +185,7 @@ async function run(commitIsh: string, dryRun: boolean, messageArg: string | unde if (dryRun) return - const message = - messageArg || - (await $.prompt({ message: 'Description? (enter to skip)', noClear: true })) + const message = await $.prompt({ message: 'Description? (enter to skip)', noClear: true }) const prTitle = 'Bump web console' + (message ? ` (${message})` : '') console.info(`\nPR title: ${prTitle}\n`) @@ -211,9 +208,8 @@ async function run(commitIsh: string, dryRun: boolean, messageArg: string | unde // script starts here const args = flags.parse(Deno.args, { - alias: { dryRun: ['d', 'dry-run'], h: 'help', m: 'message' }, + alias: { dryRun: ['d', 'dry-run'], h: 'help' }, boolean: ['dryRun', 'help'], - string: ['message'], }) if (args.help) { @@ -226,4 +222,4 @@ if (!existsSync(OMICRON_DIR)) { } const commitIsh = args._[0]?.toString() || 'main' -await run(commitIsh, args.dryRun, args.message) +await run(commitIsh, args.dryRun) From c60dd96b29a43e3c63a17c9a67f4f92d59f95224 Mon Sep 17 00:00:00 2001 From: David Crespo Date: Wed, 18 Mar 2026 16:54:29 -0500 Subject: [PATCH 2/4] rewrite bump-omicron to use cliffy --- tools/deno/api-diff.ts | 2 +- tools/deno/bump-omicron.ts | 56 +++++++++++++++----------------------- 2 files changed, 23 insertions(+), 35 deletions(-) diff --git a/tools/deno/api-diff.ts b/tools/deno/api-diff.ts index f3e3d3907..35f351928 100755 --- a/tools/deno/api-diff.ts +++ b/tools/deno/api-diff.ts @@ -9,7 +9,7 @@ */ import { exists } from 'https://deno.land/std@0.208.0/fs/mod.ts' import { $ } from 'https://deno.land/x/dax@0.39.1/mod.ts' -import { Command, ValidationError } from 'jsr:@cliffy/command@1.0.0-rc.8' +import { Command, ValidationError } from 'jsr:@cliffy/command@1.0.0' // fzf picker keeps UX quick without requiring people to wire up shell helpers async function pickPr(): Promise { diff --git a/tools/deno/bump-omicron.ts b/tools/deno/bump-omicron.ts index 9324212c0..f5c83301d 100755 --- a/tools/deno/bump-omicron.ts +++ b/tools/deno/bump-omicron.ts @@ -7,28 +7,12 @@ * * Copyright Oxide Computer Company */ -import * as flags from 'https://deno.land/std@0.159.0/flags/mod.ts' import * as path from 'https://deno.land/std@0.159.0/path/mod.ts' import $ from 'https://deno.land/x/dax@0.39.2/mod.ts' +import { Command } from 'jsr:@cliffy/command@1.0.0' +import { Confirm, Input } from 'jsr:@cliffy/prompt@1.0.0' import { existsSync } from 'jsr:@std/fs@1.0' -const HELP = ` -Update tools/console_version in ../omicron to the specified console -commit and create PR in Omicron with that change. We use a git worktree -to avoid touching your Omicron clone. - -Requirements: - - GitHub CLI installed - - Omicron is a sibling dir to console - -Usage: - ./tools/deno/bump-omicron.ts [commit-ish=main] [options] - -Options: - -d, --dry-run Dry run, showing changes without creating PR - -h, --help Show this help message -` - const OMICRON_DIR = path.resolve('../omicron') const GH_MISSING = 'GitHub CLI not found. Please install it and try again.' @@ -185,11 +169,11 @@ async function run(commitIsh: string, dryRun: boolean) { if (dryRun) return - const message = await $.prompt({ message: 'Description? (enter to skip)', noClear: true }) + const message = (await Input.prompt({ message: 'Description? (enter to skip)' })).trim() const prTitle = 'Bump web console' + (message ? ` (${message})` : '') console.info(`\nPR title: ${prTitle}\n`) - const go = await $.confirm({ message: 'Make Omicron PR?', noClear: true }) + const go = await Confirm.prompt({ message: 'Make Omicron PR?' }) if (!go) return if (!$.commandExistsSync('gh')) throw new Error(GH_MISSING) @@ -205,21 +189,25 @@ async function run(commitIsh: string, dryRun: boolean) { await $`git push -f origin tag omicron` } -// script starts here - -const args = flags.parse(Deno.args, { - alias: { dryRun: ['d', 'dry-run'], h: 'help' }, - boolean: ['dryRun', 'help'], -}) - -if (args.help) { - console.info(HELP) - Deno.exit() -} - if (!existsSync(OMICRON_DIR)) { throw new Error(`Omicron repo not found at ${OMICRON_DIR}`) } -const commitIsh = args._[0]?.toString() || 'main' -await run(commitIsh, args.dryRun) +await new Command() + .name('bump-omicron') + .description( + `Update tools/console_version in ../omicron to the specified console +commit and create PR in Omicron with that change. We use a git worktree +to avoid touching your Omicron clone. + +Requirements: + - GitHub CLI installed + - Omicron is a sibling dir to console` + ) + .helpOption('-h, --help', 'Show help') + .option('-d, --dry-run', 'Dry run, showing changes without creating PR') + .arguments('[commit-ish:string]') + .action(async (options, commitIsh?: string) => { + await run(commitIsh ?? 'main', options.dryRun ?? false) + }) + .parse(Deno.args) From 5ba6ff8d944a688a3f938e53f57987b90fd01f93 Mon Sep 17 00:00:00 2001 From: David Crespo Date: Wed, 18 Mar 2026 16:59:13 -0500 Subject: [PATCH 3/4] no need for dry-run if you can just bail --- tools/deno/bump-omicron.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tools/deno/bump-omicron.ts b/tools/deno/bump-omicron.ts index f5c83301d..48feb2901 100755 --- a/tools/deno/bump-omicron.ts +++ b/tools/deno/bump-omicron.ts @@ -142,7 +142,7 @@ async function makeOmicronPR( // wrapped in a function so we can do early returns rather than early // Deno.exits, which mess up the worktree cleanup -async function run(commitIsh: string, dryRun: boolean) { +async function run(commitIsh: string) { // Ensure local main matches the remote so we don't bump to a stale commit if (commitIsh === 'main') { const localMain = await $`git rev-parse main`.text() @@ -167,8 +167,6 @@ async function run(commitIsh: string, dryRun: boolean) { console.info(`\n${changesLink}\n\n${commits}\n`) - if (dryRun) return - const message = (await Input.prompt({ message: 'Description? (enter to skip)' })).trim() const prTitle = 'Bump web console' + (message ? ` (${message})` : '') console.info(`\nPR title: ${prTitle}\n`) @@ -204,10 +202,8 @@ Requirements: - GitHub CLI installed - Omicron is a sibling dir to console` ) - .helpOption('-h, --help', 'Show help') - .option('-d, --dry-run', 'Dry run, showing changes without creating PR') .arguments('[commit-ish:string]') - .action(async (options, commitIsh?: string) => { - await run(commitIsh ?? 'main', options.dryRun ?? false) + .action(async (_options, commitIsh?: string) => { + await run(commitIsh ?? 'main') }) .parse(Deno.args) From 8595c5f0ab56391d643c1bafc38ea2cd0c9ed98e Mon Sep 17 00:00:00 2001 From: David Crespo Date: Wed, 18 Mar 2026 17:12:10 -0500 Subject: [PATCH 4/4] move run into action callback --- tools/deno/bump-omicron.ts | 94 ++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 50 deletions(-) diff --git a/tools/deno/bump-omicron.ts b/tools/deno/bump-omicron.ts index 48feb2901..c7cb4e56e 100755 --- a/tools/deno/bump-omicron.ts +++ b/tools/deno/bump-omicron.ts @@ -140,53 +140,6 @@ async function makeOmicronPR( await $`git branch -D ${branchName}`.cwd(OMICRON_DIR) } -// wrapped in a function so we can do early returns rather than early -// Deno.exits, which mess up the worktree cleanup -async function run(commitIsh: string) { - // Ensure local main matches the remote so we don't bump to a stale commit - if (commitIsh === 'main') { - const localMain = await $`git rev-parse main`.text() - const remoteMain = await $`git ls-remote origin main`.text() - const remoteMainSha = remoteMain.split('\t')[0] - if (localMain !== remoteMainSha) { - throw new Error('Local main does not match remote. Fetch main and try again.') - } - } - - const oldConsoleCommit = await getOldCommit() - const newConsoleCommit = await $`git rev-parse ${commitIsh}`.text() - - if (oldConsoleCommit === newConsoleCommit) { - console.info(`Nothing to update: Omicron already has ${newConsoleCommit} pinned`) - return - } - - const commitRange = `${oldConsoleCommit.slice(0, 8)}...${newConsoleCommit.slice(0, 8)}` - const commits = await $`git log --graph --oneline ${commitRange}`.text() - const changesLink = `https://github.com/oxidecomputer/console/compare/${commitRange}` - - console.info(`\n${changesLink}\n\n${commits}\n`) - - const message = (await Input.prompt({ message: 'Description? (enter to skip)' })).trim() - const prTitle = 'Bump web console' + (message ? ` (${message})` : '') - console.info(`\nPR title: ${prTitle}\n`) - - const go = await Confirm.prompt({ message: 'Make Omicron PR?' }) - if (!go) return - - if (!$.commandExistsSync('gh')) throw new Error(GH_MISSING) - - const consoleDir = Deno.cwd() // save it so we can change back - - await makeOmicronPR(newConsoleCommit, prTitle, changesLink, commits) - - // bump omicron tag in console to current commit - Deno.chdir(consoleDir) - console.info('Bumping omicron tag in console') - await $`git tag -f -a omicron -m 'pinned commit on omicron main' ${commitIsh}` - await $`git push -f origin tag omicron` -} - if (!existsSync(OMICRON_DIR)) { throw new Error(`Omicron repo not found at ${OMICRON_DIR}`) } @@ -202,8 +155,49 @@ Requirements: - GitHub CLI installed - Omicron is a sibling dir to console` ) - .arguments('[commit-ish:string]') - .action(async (_options, commitIsh?: string) => { - await run(commitIsh ?? 'main') + .argument('[commit:string]', 'Console commit (default: main)', { default: 'main' }) + .action(async (_options, commitIsh) => { + // Ensure local main matches the remote so we don't bump to a stale commit + if (commitIsh === 'main') { + const localMain = await $`git rev-parse main`.text() + const remoteMain = await $`git ls-remote origin main`.text() + const remoteMainSha = remoteMain.split('\t')[0] + if (localMain !== remoteMainSha) { + throw new Error('Local main does not match remote. Fetch main and try again.') + } + } + + const oldConsoleCommit = await getOldCommit() + const newConsoleCommit = await $`git rev-parse ${commitIsh}`.text() + + if (oldConsoleCommit === newConsoleCommit) { + console.info(`Nothing to update: Omicron already has ${newConsoleCommit} pinned`) + return + } + + const commitRange = `${oldConsoleCommit.slice(0, 8)}...${newConsoleCommit.slice(0, 8)}` + const commits = await $`git log --graph --oneline ${commitRange}`.text() + const changesLink = `https://github.com/oxidecomputer/console/compare/${commitRange}` + + console.info(`\n${changesLink}\n\n${commits}\n`) + + const message = (await Input.prompt({ message: 'Description? (enter to skip)' })).trim() + const prTitle = 'Bump web console' + (message ? ` (${message})` : '') + console.info(`\nPR title: ${prTitle}\n`) + + const go = await Confirm.prompt({ message: 'Make Omicron PR?' }) + if (!go) return + + if (!$.commandExistsSync('gh')) throw new Error(GH_MISSING) + + const consoleDir = Deno.cwd() // save it so we can change back + + await makeOmicronPR(newConsoleCommit, prTitle, changesLink, commits) + + // bump omicron tag in console to current commit + Deno.chdir(consoleDir) + console.info('Bumping omicron tag in console') + await $`git tag -f -a omicron -m 'pinned commit on omicron main' ${commitIsh}` + await $`git push -f origin tag omicron` }) .parse(Deno.args)