diff --git a/package-lock.json b/package-lock.json index 9843635caa..00c47a704b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -150,6 +150,7 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -2457,7 +2458,8 @@ "resolved": "https://registry.npmjs.org/@cspell/dict-css/-/dict-css-4.0.18.tgz", "integrity": "sha512-EF77RqROHL+4LhMGW5NTeKqfUd/e4OOv6EDFQ/UQQiFyWuqkEKyEz0NDILxOFxWUEVdjT2GQ2cC7t12B6pESwg==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@cspell/dict-dart": { "version": "2.3.1", @@ -2597,14 +2599,16 @@ "resolved": "https://registry.npmjs.org/@cspell/dict-html/-/dict-html-4.0.12.tgz", "integrity": "sha512-JFffQ1dDVEyJq6tCDWv0r/RqkdSnV43P2F/3jJ9rwLgdsOIXwQbXrz6QDlvQLVvNSnORH9KjDtenFTGDyzfCaA==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@cspell/dict-html-symbol-entities": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@cspell/dict-html-symbol-entities/-/dict-html-symbol-entities-4.0.4.tgz", "integrity": "sha512-afea+0rGPDeOV9gdO06UW183Qg6wRhWVkgCFwiO3bDupAoyXRuvupbb5nUyqSTsLXIKL8u8uXQlJ9pkz07oVXw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@cspell/dict-java": { "version": "5.0.12", @@ -2802,7 +2806,8 @@ "resolved": "https://registry.npmjs.org/@cspell/dict-typescript/-/dict-typescript-3.2.3.tgz", "integrity": "sha512-zXh1wYsNljQZfWWdSPYwQhpwiuW0KPW1dSd8idjMRvSD0aSvWWHoWlrMsmZeRl4qM4QCEAjua8+cjflm41cQBg==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@cspell/dict-vue": { "version": "3.0.5", @@ -5404,6 +5409,7 @@ "integrity": "sha512-z+j7DixNnfpdToYsOutStDgeRzJSMnbj8T1C/oQjB6Aa+kRfNjs/Fn7W6c8bmlt6mfy3FkgeKBRnDjxQow5dow==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@octokit/auth-token": "^5.0.0", "@octokit/graphql": "^8.1.2", @@ -7028,7 +7034,8 @@ "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/json5": { "version": "0.0.29", @@ -7093,6 +7100,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.0.tgz", "integrity": "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==", "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -7294,6 +7302,7 @@ "integrity": "sha512-6m1I5RmHBGTnUGS113G04DMu3CpSdxCAU/UvtjNWL4Nuf3MW9tQhiJqRlHzChIkhy6kZSAQmc+I1bcGjE3yNKg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.46.3", "@typescript-eslint/types": "8.46.3", @@ -7835,6 +7844,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -8696,6 +8706,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001726", "electron-to-chromium": "^1.5.173", @@ -11071,6 +11082,7 @@ "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", @@ -12415,6 +12427,7 @@ "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -12475,6 +12488,7 @@ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, "license": "MIT", + "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -12609,6 +12623,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -18720,6 +18735,7 @@ "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.4.0.tgz", "integrity": "sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==", "license": "MIT", + "peer": true, "engines": { "node": ">= 10.16.0" } @@ -19785,6 +19801,7 @@ "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", "dev": true, "license": "MIT", + "peer": true, "bin": { "marked": "bin/marked.js" }, @@ -22894,6 +22911,7 @@ "dev": true, "inBundle": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -24007,6 +24025,7 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -24991,6 +25010,7 @@ "integrity": "sha512-phCkJ6pjDi9ANdhuF5ElS10GGdAKY6R1Pvt9lT3SFhOwM4T7QZE7MLpBDbNruUx/Q3gFD92/UOFringGipRqZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@semantic-release/commit-analyzer": "^13.0.0-beta.1", "@semantic-release/error": "^4.0.0", @@ -26982,6 +27002,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -27185,6 +27206,7 @@ "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -27468,6 +27490,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -27636,6 +27659,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "dependencies": { "napi-postinstall": "^0.2.4" }, @@ -28131,6 +28155,7 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=10.0.0" }, diff --git a/src/common/k8s.ts b/src/common/k8s.ts index 677e1b6660..33d79e911a 100644 --- a/src/common/k8s.ts +++ b/src/common/k8s.ts @@ -20,6 +20,7 @@ import { resolveAny } from 'dns/promises' import { access, mkdir, writeFile } from 'fs/promises' import { isEmpty, isEqual, map, mapValues } from 'lodash' import { dirname, join } from 'path' +import { Writable } from 'stream' import { parse, stringify } from 'yaml' import { $, cd, sleep } from 'zx' import { ARGOCD_APP_PARAMS, DEPLOYMENT_PASSWORDS_SECRET, DEPLOYMENT_STATUS_CONFIGMAP } from './constants' @@ -28,7 +29,6 @@ import { env } from './envalid' import { hfValues } from './hf' import { parser } from './yargs' import { askYesNo } from './zx-enhance' -import { Writable } from 'stream' export const secretId = `secret/otomi/${DEPLOYMENT_PASSWORDS_SECRET}` @@ -124,8 +124,11 @@ export const getK8sSecret = async (name: string, namespace: string): Promise { info: jest.fn(), error: jest.fn(), } - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + mockTerminal.mockReturnValue(mockDebugger as any) }) @@ -61,7 +61,6 @@ describe('runtimeUpgrade', () => { }) it('should skip runtime upgrade for null deployment state', async () => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument mockGetDeploymentState.mockResolvedValue(null as any) mockGetCurrentVersion.mockResolvedValue('1.0.0') @@ -80,17 +79,17 @@ describe('runtimeUpgrade', () => { await runtimeUpgrade({ when: 'pre' }) - expect(mockDebugger.info).toHaveBeenCalledWith('Current version of otomi: 2.0.0') + expect(mockDebugger.info).toHaveBeenCalledWith('The current version of the Akamai App Platform: 2.0.0') + expect(mockDebugger.info).toHaveBeenCalledWith('Deploying essential manifests') expect(mockDebugger.info).toHaveBeenCalledWith('No runtime upgrade operations detected, skipping') }) it('should use current version when deployment state has no version', async () => { - mockGetDeploymentState.mockResolvedValue({ status: 'deployed' }) - mockGetCurrentVersion.mockResolvedValue('1.0.0') + mockGetDeploymentState.mockResolvedValue({ status: 'deployed', version: '1.0.0' }) await runtimeUpgrade({ when: 'pre' }) - expect(mockDebugger.info).toHaveBeenCalledWith('Current version of otomi: 1.0.0') + expect(mockDebugger.info).toHaveBeenCalledWith('The current version of the Akamai App Platform: 1.0.0') }) }) @@ -231,26 +230,16 @@ describe('runtimeUpgrade', () => { }) describe('filterRuntimeUpgrades', () => { - const sampleUpgrades: RuntimeUpgrades = [ - { version: '1.0.0' }, - { version: '1.5.0' }, - { version: '2.0.0' }, - { version: 'dev' }, - ] + const sampleUpgrades: RuntimeUpgrades = [{ version: '1.0.0' }, { version: '1.5.0' }, { version: '2.0.0' }] it('should filter upgrades newer than current version', () => { const result = filterRuntimeUpgrades('1.2.0', sampleUpgrades) - expect(result).toEqual([{ version: '1.5.0' }, { version: '2.0.0' }, { version: 'dev' }]) - }) - - it('should include dev version regardless of current version', () => { - const result = filterRuntimeUpgrades('99.0.0', sampleUpgrades) - expect(result).toEqual([{ version: 'dev' }]) + expect(result).toEqual([{ version: '1.5.0' }, { version: '2.0.0' }]) }) it('should return empty array when no upgrades are newer', () => { const result = filterRuntimeUpgrades('3.0.0', sampleUpgrades) - expect(result).toEqual([{ version: 'dev' }]) + expect(result).toEqual([]) }) it('should handle prerelease versions correctly', () => { @@ -271,16 +260,16 @@ describe('filterRuntimeUpgrades', () => { it('should not run with prereleases = version', () => { const result = filterRuntimeUpgrades('2.0.0-rc.2', sampleUpgrades) - expect(result).toEqual([{ version: 'dev' }]) + expect(result).toEqual([]) }) it('should not modify valid semantic versions', () => { const result = filterRuntimeUpgrades('1.0.0', sampleUpgrades) - expect(result).toEqual([{ version: '1.5.0' }, { version: '2.0.0' }, { version: 'dev' }]) + expect(result).toEqual([{ version: '1.5.0' }, { version: '2.0.0' }]) }) it('should handle edge case with exact version match', () => { const result = filterRuntimeUpgrades('1.5.0', sampleUpgrades) - expect(result).toEqual([{ version: '2.0.0' }, { version: 'dev' }]) + expect(result).toEqual([{ version: '2.0.0' }]) }) }) diff --git a/src/common/runtime-upgrade.ts b/src/common/runtime-upgrade.ts index 97dcf25858..8f44724b33 100644 --- a/src/common/runtime-upgrade.ts +++ b/src/common/runtime-upgrade.ts @@ -1,10 +1,8 @@ -import { isEmpty } from 'lodash' import semver from 'semver' import { getApplications } from 'src/cmd/apply-as-apps' import { terminal } from './debug' import { getDeploymentState, k8s, waitForArgoCDAppHealthy, waitForArgoCDAppSync } from './k8s' import { RuntimeUpgradeContext, RuntimeUpgrades, runtimeUpgrades } from './runtime-upgrades/runtime-upgrades' -import { getCurrentVersion } from './values' import { deployEssential } from './hf' interface RuntimeUpgradeArgs { @@ -15,10 +13,12 @@ export async function runtimeUpgrade({ when }: RuntimeUpgradeArgs): Promise rUpgrade.version === 'dev' || semver.gt(rUpgrade.version, currentVersion)) + return rUpgrades.filter((rUpgrade) => semver.gt(rUpgrade.version, currentVersion)) }