Compare commits

...

1 Commits

Author SHA1 Message Date
Jason Rasmussen cbaf11c3d7 feat: pump doc references 2026-06-25 17:59:01 -04:00
4 changed files with 116 additions and 61 deletions
+12 -16
View File
@@ -28,7 +28,7 @@ while getopts 's:m:' flag; do
done
CURRENT_SERVER=$(jq -r '.version' package.json)
if ! NEXT_SERVER=$(pnpm --silent pump "$CURRENT_SERVER" "$SERVER_PUMP"); then
if ! NEXT_SERVER=$(pnpm --silent pump "$SERVER_PUMP"); then
echo "Fatal: failed to pump server version: $NEXT_SERVER" >&2
exit 1
fi
@@ -45,25 +45,21 @@ else
exit 1
fi
echo "Pumping Server: $CURRENT_SERVER => $NEXT_SERVER"
pnpm version "$NEXT_SERVER" --no-git-tag-version --no-git-checks
pnpm version "$NEXT_SERVER" --no-git-tag-version --no-git-checks --prefix server
pnpm version "$NEXT_SERVER" --no-git-tag-version --no-git-checks --prefix packages/cli
pnpm version "$NEXT_SERVER" --no-git-tag-version --no-git-checks --prefix web
pnpm version "$NEXT_SERVER" --no-git-tag-version --no-git-checks --prefix e2e
pnpm version "$NEXT_SERVER" --no-git-tag-version --no-git-checks --prefix packages/sdk
if [ "$CURRENT_SERVER" != "$NEXT_SERVER" ]; then
echo "Pumping Server: $CURRENT_SERVER => $NEXT_SERVER"
# copy version to open-api spec
mise run //:open-api
pnpm version "$NEXT_SERVER" --no-git-tag-version --no-git-checks
pnpm version "$NEXT_SERVER" --no-git-tag-version --no-git-checks --prefix server
pnpm version "$NEXT_SERVER" --no-git-tag-version --no-git-checks --prefix packages/cli
pnpm version "$NEXT_SERVER" --no-git-tag-version --no-git-checks --prefix web
pnpm version "$NEXT_SERVER" --no-git-tag-version --no-git-checks --prefix e2e
pnpm version "$NEXT_SERVER" --no-git-tag-version --no-git-checks --prefix packages/sdk
uv version --directory machine-learning "$NEXT_SERVER"
# copy version to open-api spec
mise run //:open-api
uv version --directory machine-learning "$NEXT_SERVER"
./misc/release/archive-version.js "$NEXT_SERVER"
fi
./misc/release/archive-version.js "$NEXT_SERVER"
if [ "$CURRENT_MOBILE" != "$NEXT_MOBILE" ]; then
echo "Pumping Mobile: $CURRENT_MOBILE => $NEXT_MOBILE"
+22 -5
View File
@@ -1,7 +1,24 @@
import { pump } from './pump.js';
import { pump, PumpInvalidError, PumpUsageError } from './pump.js';
const [versionRaw, type] = process.argv.slice(2);
const { message, exitCode } = pump(versionRaw, type);
const [type] = process.argv.slice(2);
console.log(message);
process.exit(exitCode);
try {
const nextVersion = pump(type);
console.log(nextVersion);
} catch (error) {
if (error instanceof PumpUsageError) {
console.log(
'Usage: ./pump-wrapper.js <minor|patch|premajor|preminor|prepatch|prerelease|release>',
);
process.exit(1);
}
if (error instanceof PumpInvalidError) {
console.log(
`Invalid pump: ${type}. Pumping from ${error.version} to ${error.newVersion} is not allowed.`,
);
process.exit(1);
}
throw error;
}
+77 -26
View File
@@ -1,44 +1,74 @@
import { readFileSync, writeFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import semver, { SemVer } from 'semver';
const printUsage = () => {
return {
message:
'Usage: ./pump_cli.js <semver> <minor|patch|premajor|preminor|prepatch|prerelease|release>',
exitCode: 1,
};
const PROJECT_ROOT = join(dirname(fileURLToPath(import.meta.url)), '../..');
const Files = {
PackageJson: join(PROJECT_ROOT, 'package.json'),
ExampleEnv: join(PROJECT_ROOT, 'docker/example.env'),
Docs: {
Env: join(PROJECT_ROOT, 'docs/docs/install/environment-variables.md'),
Upgrading: join(PROJECT_ROOT, 'docs/docs/install/upgrading.md'),
},
};
const isPrerelease = (version) => version.prerelease.length > 0;
export class PumpUsageError extends Error {}
export class PumpInvalidError extends Error {
constructor(options) {
super(`Invalid pump`);
this.version = options.version;
this.newVersion = options.newVersion;
}
}
/**
* @param {SemVer} version
* @returns {boolean}
* @param {string} type
*/
const inc = (version, type) => `v${semver.inc(version, type, {}, 'rc')}`;
export const pump = (type) => {
const currentVersionRaw = getCurrentVersion();
const nextVersionRaw = getNextVersion(currentVersionRaw, type);
const nextVersion = semver.parse(normalize(nextVersionRaw));
/** @param {string} version */
const normalize = (version) => {
if (version.startsWith('v')) {
version = version.slice(1);
if (nextVersion && type === 'release') {
const major = `v${nextVersion.major}`;
// sync major tag references in docs and example env file
findAndReplace(
Files.ExampleEnv,
/^IMMICH_VERSION=v\d+$/m,
`IMMICH_VERSION=${major}`,
);
findAndReplace(
Files.Docs.Env,
/(`IMMICH_VERSION`.*?)`v\d+`/,
`$1\`${major}\``,
);
findAndReplace(Files.Docs.Upgrading, /:v\d+/, `:${major}`);
}
return version;
return nextVersionRaw;
};
const getCurrentVersion = () =>
JSON.parse(readFileSync(Files.PackageJson, 'utf8')).version;
/**
* @param {string} versionRaw
* @param {string} type
*/
export const pump = (versionRaw, type) => {
export const getNextVersion = (versionRaw, type) => {
if (!versionRaw) {
return printUsage();
throw new PumpUsageError();
}
versionRaw = normalize(versionRaw);
const version = semver.parse(versionRaw);
if (!version) {
return printUsage();
throw new PumpUsageError();
}
let newVersionRaw;
@@ -72,19 +102,19 @@ export const pump = (versionRaw, type) => {
}
default: {
return printUsage();
throw new PumpUsageError();
}
}
if (!newVersionRaw) {
return printUsage();
throw new PumpUsageError();
}
newVersionRaw = normalize(newVersionRaw);
const newVersion = semver.parse(newVersionRaw);
if (!newVersion) {
return printUsage();
throw new PumpUsageError();
}
const invalidUpgrade =
@@ -95,11 +125,32 @@ export const pump = (versionRaw, type) => {
version.patch !== newVersion.patch);
if (!valid || invalidUpgrade) {
return {
message: `Invalid pump: ${type}. Pumping from ${versionRaw} to ${newVersionRaw} is not allowed.`,
exitCode: 1,
};
throw new PumpInvalidError({
type,
version: versionRaw,
newVersion: newVersionRaw,
});
}
return { message: newVersionRaw, exitCode: 0 };
return newVersionRaw;
};
const findAndReplace = (path, pattern, replacement) =>
writeFileSync(path, readFileSync(path, 'utf8').replace(pattern, replacement));
const isPrerelease = (version) => version.prerelease.length > 0;
/**
* @param {SemVer} version
* @returns {boolean}
*/
const inc = (version, type) => `v${semver.inc(version, type, {}, 'rc')}`;
/** @param {string} version */
const normalize = (version) => {
if (version.startsWith('v')) {
version = version.slice(1);
}
return version;
};
+5 -14
View File
@@ -1,7 +1,7 @@
import { describe, expect, it } from 'vitest';
import { pump } from './pump';
import { getNextVersion, PumpInvalidError, PumpUsageError } from './pump';
describe(pump.name, () => {
describe(getNextVersion.name, () => {
describe('usage', () => {
it.each([
[],
@@ -10,10 +10,7 @@ describe(pump.name, () => {
['invalid', 'patch'],
['2.7.5', 'major'],
])('should not accept $0, $1 as inputs', (version, type) => {
expect(pump(version, type)).toEqual({
message: expect.stringContaining('Usage: '),
exitCode: 1,
});
expect(() => getNextVersion(version, type)).toThrow(PumpUsageError);
});
});
@@ -58,10 +55,7 @@ describe(pump.name, () => {
it.each(group.items)(
'should allow a $0 from $1 to $2',
(type, version, next) => {
expect(pump(version, type)).toEqual({
message: next,
exitCode: 0,
});
expect(getNextVersion(version, type)).toEqual(next);
},
);
});
@@ -77,10 +71,7 @@ describe(pump.name, () => {
['prerelease', 'v3.0.0'],
['release', 'v3.0.0'],
])('should not allow a $0 on $1', (type, version) => {
expect(pump(version, type)).toEqual({
message: expect.stringContaining('Invalid pump'),
exitCode: 1,
});
expect(() => getNextVersion(version, type)).toThrow(PumpInvalidError);
});
});
});