feat(cli): show changelog entries before running upgrades
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
# Changelog
|
||||
|
||||
## 2026-04-16 - 5.11.0 - feat(cli)
|
||||
show changelog entries before running upgrades
|
||||
|
||||
- fetch and render changelog entries between the installed and latest versions during the upgrade flow
|
||||
- add upgrade changelog parsing helper with tests for version filtering and grouped version ranges
|
||||
- document that the upgrade command displays release notes before installing
|
||||
|
||||
## 2026-04-16 - 5.10.0 - feat(cli,snmp)
|
||||
fix APC runtime unit defaults and add interactive action editing
|
||||
|
||||
|
||||
@@ -65,5 +65,8 @@
|
||||
"packageManager": "pnpm@10.18.1+sha512.77a884a165cbba2d8d1c19e3b4880eee6d2fcabd0d879121e282196b80042351d5eb3ca0935fa599da1dc51265cc68816ad2bddd2a2de5ea9fdf92adbec7cd34",
|
||||
"devDependencies": {
|
||||
"@git.zone/tsdeno": "^1.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@push.rocks/smartchangelog": "^0.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+390
-894
File diff suppressed because it is too large
Load Diff
@@ -787,6 +787,10 @@ Any UPS supported by [NUT (Network UPS Tools)](https://networkupstools.org/) —
|
||||
sudo nupst upgrade
|
||||
```
|
||||
|
||||
The built-in upgrade command checks the latest published release, fetches `changelog.md` from
|
||||
`main`, and shows the release notes for the versions between your installed version and the target
|
||||
version before running the installer.
|
||||
|
||||
### Re-run Installer
|
||||
|
||||
```bash
|
||||
|
||||
@@ -42,6 +42,7 @@ import { createInitialUpsStatus } from '../ts/ups-status.ts';
|
||||
import { MigrationV4_2ToV4_3 } from '../ts/migrations/migration-v4.2-to-v4.3.ts';
|
||||
import { MigrationV4_3ToV4_4 } from '../ts/migrations/migration-v4.3-to-v4.4.ts';
|
||||
import { ActionHandler } from '../ts/cli/action-handler.ts';
|
||||
import { renderUpgradeChangelog } from '../ts/upgrade-changelog.ts';
|
||||
|
||||
import * as qenv from 'npm:@push.rocks/qenv@^6.0.0';
|
||||
const testQenv = new qenv.Qenv('./', '.nogit/');
|
||||
@@ -817,6 +818,39 @@ Deno.test('convertRuntimeValueToMinutes: APC and explicit overrides convert corr
|
||||
assertEquals(convertRuntimeValueToMinutes({ upsModel: 'apc', runtimeUnit: 'minutes' }, 12), 12);
|
||||
});
|
||||
|
||||
Deno.test('renderUpgradeChangelog: renders only versions between current and latest', () => {
|
||||
const changelogMarkdown = `# Changelog
|
||||
|
||||
## 2026-04-16 - 5.10.0 - feat(cli,snmp)
|
||||
fix APC runtime unit defaults and add interactive action editing
|
||||
|
||||
- correct APC runtime handling
|
||||
|
||||
## 2026-04-16 - 5.8.0 - feat(systemd)
|
||||
improve service status reporting with structured systemctl data
|
||||
|
||||
- switch status collection to systemctl show
|
||||
`;
|
||||
|
||||
const rendered = renderUpgradeChangelog(changelogMarkdown, '5.8.0', '5.10.0');
|
||||
assert(rendered.includes('5.10.0 - feat(cli,snmp)'));
|
||||
assert(rendered.includes('fix APC runtime unit defaults and add interactive action editing'));
|
||||
assert(!rendered.includes('5.8.0 - feat(systemd)'));
|
||||
});
|
||||
|
||||
Deno.test('renderUpgradeChangelog: includes grouped version ranges when they intersect', () => {
|
||||
const changelogMarkdown = `# Changelog
|
||||
|
||||
## 2020-06-01 - 4.0.3-4.0.5 - core
|
||||
Grouped maintenance releases with repeated core update work.
|
||||
|
||||
- 4.0.5 introduced a breaking change by switching core packaging behavior toward ESM compatibility
|
||||
`;
|
||||
|
||||
const rendered = renderUpgradeChangelog(changelogMarkdown, '4.0.4', '4.0.5');
|
||||
assert(rendered.includes('4.0.3-4.0.5 - core'));
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Migration Tests
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@serve.zone/nupst',
|
||||
version: '5.10.0',
|
||||
version: '5.11.0',
|
||||
description: 'Network UPS Shutdown Tool - Monitor SNMP-enabled UPS devices and orchestrate graceful system shutdowns during power emergencies'
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import process from 'node:process';
|
||||
import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
import { execSync } from 'node:child_process';
|
||||
import { execFileSync, execSync } from 'node:child_process';
|
||||
import { Nupst } from '../nupst.ts';
|
||||
import { logger } from '../logger.ts';
|
||||
import { theme } from '../colors.ts';
|
||||
import { PAUSE } from '../constants.ts';
|
||||
import type { IPauseState } from '../pause-state.ts';
|
||||
import * as helpers from '../helpers/index.ts';
|
||||
import { renderUpgradeChangelog } from '../upgrade-changelog.ts';
|
||||
|
||||
/**
|
||||
* Class for handling service-related CLI commands
|
||||
@@ -270,7 +271,7 @@ export class ServiceHandler {
|
||||
|
||||
// Fetch latest version from Gitea API
|
||||
const apiUrl = 'https://code.foss.global/api/v1/repos/serve.zone/nupst/releases/latest';
|
||||
const response = execSync(`curl -sSL ${apiUrl}`).toString();
|
||||
const response = this.fetchRemoteText(apiUrl);
|
||||
const release = JSON.parse(response);
|
||||
const latestVersion = release.tag_name; // e.g., "v4.0.7"
|
||||
|
||||
@@ -294,6 +295,7 @@ export class ServiceHandler {
|
||||
}
|
||||
|
||||
logger.info(`New version available: ${latestVersion}`);
|
||||
this.showUpgradeChangelog(normalizedCurrent, normalizedLatest);
|
||||
logger.dim('Downloading and installing...');
|
||||
console.log('');
|
||||
|
||||
@@ -321,6 +323,40 @@ export class ServiceHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private fetchRemoteText(url: string): string {
|
||||
return execFileSync('curl', ['-fsSL', url], {
|
||||
encoding: 'utf8',
|
||||
});
|
||||
}
|
||||
|
||||
private showUpgradeChangelog(currentVersion: string, latestVersion: string): void {
|
||||
const changelogUrl = 'https://code.foss.global/serve.zone/nupst/raw/branch/main/changelog.md';
|
||||
|
||||
try {
|
||||
const changelogMarkdown = this.fetchRemoteText(changelogUrl);
|
||||
const renderedChanges = renderUpgradeChangelog(
|
||||
changelogMarkdown,
|
||||
currentVersion,
|
||||
latestVersion,
|
||||
);
|
||||
|
||||
if (!renderedChanges) {
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info(`What's changed:`);
|
||||
logger.log('');
|
||||
for (const line of renderedChanges.split('\n')) {
|
||||
logger.log(line);
|
||||
}
|
||||
logger.log('');
|
||||
} catch (error) {
|
||||
logger.warn('Could not load changelog for this upgrade. Continuing anyway.');
|
||||
logger.dim(`${error instanceof Error ? error.message : String(error)}`);
|
||||
logger.log('');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Completely uninstall NUPST from the system
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { SmartChangelog } from 'npm:@push.rocks/smartchangelog@^0.1.0';
|
||||
|
||||
export const renderUpgradeChangelog = (
|
||||
changelogMarkdown: string,
|
||||
currentVersion: string,
|
||||
latestVersion: string,
|
||||
): string => {
|
||||
const changelog = SmartChangelog.fromMarkdown(changelogMarkdown);
|
||||
const entries = changelog.getEntriesBetween(currentVersion, latestVersion);
|
||||
|
||||
if (entries.length === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return entries.map((entry) => entry.toCliString()).join('\n\n');
|
||||
};
|
||||
Reference in New Issue
Block a user