mirror of
https://github.com/immich-app/immich
synced 2026-08-15 13:03:57 +00:00
feat: use version service for docs archive switcher (#30675)
This commit is contained in:
parent
199723261c
commit
0344c61e4c
5 changed files with 6 additions and 399 deletions
|
|
@ -2,6 +2,8 @@ import { useWindowSize } from '@docusaurus/theme-common';
|
||||||
import DropdownNavbarItem from '@theme/NavbarItem/DropdownNavbarItem';
|
import DropdownNavbarItem from '@theme/NavbarItem/DropdownNavbarItem';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
const ARCHIVED_VERSIONS_URL = 'https://version.immich.cloud/v1/docs/versions';
|
||||||
|
|
||||||
export default function VersionSwitcher(): JSX.Element {
|
export default function VersionSwitcher(): JSX.Element {
|
||||||
const [versions, setVersions] = useState([]);
|
const [versions, setVersions] = useState([]);
|
||||||
const [activeLabel, setLabel] = useState('Versions');
|
const [activeLabel, setLabel] = useState('Versions');
|
||||||
|
|
@ -11,12 +13,7 @@ export default function VersionSwitcher(): JSX.Element {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function getVersions() {
|
async function getVersions() {
|
||||||
try {
|
try {
|
||||||
let baseUrl = 'https://docs.immich.app';
|
const response = await fetch(ARCHIVED_VERSIONS_URL);
|
||||||
if (window.location.origin === 'http://localhost:3005') {
|
|
||||||
baseUrl = window.location.origin;
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await fetch(`${baseUrl}/archived-versions.json`);
|
|
||||||
|
|
||||||
const archiveVersions = await response.json();
|
const archiveVersions = await response.json();
|
||||||
|
|
||||||
|
|
|
||||||
1
docs/static/_redirects
vendored
1
docs/static/_redirects
vendored
|
|
@ -1,3 +1,4 @@
|
||||||
|
/archived-versions.json https://version.immich.cloud/v1/docs/versions 307
|
||||||
/ /overview/quick-start 307
|
/ /overview/quick-start 307
|
||||||
/mobile-app-beta-program /features/mobile-app 307
|
/mobile-app-beta-program /features/mobile-app 307
|
||||||
/contribution-guidelines /overview/support-the-project#contributing 307
|
/contribution-guidelines /overview/support-the-project#contributing 307
|
||||||
|
|
|
||||||
265
docs/static/archived-versions.json
vendored
265
docs/static/archived-versions.json
vendored
|
|
@ -1,265 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"label": "v3.1.0",
|
|
||||||
"url": "https://docs.v3.1.0.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v3.0.3",
|
|
||||||
"url": "https://docs.v3.0.3.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v2.7.5",
|
|
||||||
"url": "https://docs.v2.7.5.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v2.6.3",
|
|
||||||
"url": "https://docs.v2.6.3.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v2.5.6",
|
|
||||||
"url": "https://docs.v2.5.6.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v2.4.1",
|
|
||||||
"url": "https://docs.v2.4.1.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v2.3.1",
|
|
||||||
"url": "https://docs.v2.3.1.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v2.2.3",
|
|
||||||
"url": "https://docs.v2.2.3.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v2.1.0",
|
|
||||||
"url": "https://docs.v2.1.0.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v2.0.1",
|
|
||||||
"url": "https://docs.v2.0.1.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.144.1",
|
|
||||||
"url": "https://docs.v1.144.1.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.143.1",
|
|
||||||
"url": "https://docs.v1.143.1.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.142.1",
|
|
||||||
"url": "https://v1.142.1.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.141.1",
|
|
||||||
"url": "https://v1.141.1.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.140.1",
|
|
||||||
"url": "https://v1.140.1.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.139.4",
|
|
||||||
"url": "https://v1.139.4.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.138.1",
|
|
||||||
"url": "https://v1.138.1.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.137.3",
|
|
||||||
"url": "https://v1.137.3.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.136.0",
|
|
||||||
"url": "https://v1.136.0.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.135.3",
|
|
||||||
"url": "https://v1.135.3.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.134.0",
|
|
||||||
"url": "https://v1.134.0.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.133.1",
|
|
||||||
"url": "https://v1.133.1.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.132.3",
|
|
||||||
"url": "https://v1.132.3.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.131.3",
|
|
||||||
"url": "https://v1.131.3.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.130.3",
|
|
||||||
"url": "https://v1.130.3.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.129.0",
|
|
||||||
"url": "https://v1.129.0.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.128.0",
|
|
||||||
"url": "https://v1.128.0.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.127.0",
|
|
||||||
"url": "https://v1.127.0.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.126.1",
|
|
||||||
"url": "https://v1.126.1.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.125.7",
|
|
||||||
"url": "https://v1.125.7.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.124.2",
|
|
||||||
"url": "https://v1.124.2.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.123.0",
|
|
||||||
"url": "https://v1.123.0.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.122.3",
|
|
||||||
"url": "https://v1.122.3.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.121.0",
|
|
||||||
"url": "https://v1.121.0.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.120.2",
|
|
||||||
"url": "https://v1.120.2.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.119.1",
|
|
||||||
"url": "https://v1.119.1.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.118.2",
|
|
||||||
"url": "https://v1.118.2.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.117.0",
|
|
||||||
"url": "https://v1.117.0.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.116.2",
|
|
||||||
"url": "https://v1.116.2.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.115.0",
|
|
||||||
"url": "https://v1.115.0.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.114.0",
|
|
||||||
"url": "https://v1.114.0.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.113.1",
|
|
||||||
"url": "https://v1.113.1.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.112.1",
|
|
||||||
"url": "https://v1.112.1.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.111.0",
|
|
||||||
"url": "https://v1.111.0.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.110.0",
|
|
||||||
"url": "https://v1.110.0.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.109.2",
|
|
||||||
"url": "https://v1.109.2.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.108.0",
|
|
||||||
"url": "https://v1.108.0.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.107.2",
|
|
||||||
"url": "https://v1.107.2.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.106.4",
|
|
||||||
"url": "https://v1.106.4.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.105.1",
|
|
||||||
"url": "https://v1.105.1.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.104.0",
|
|
||||||
"url": "https://v1.104.0.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.103.1",
|
|
||||||
"url": "https://v1.103.1.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.102.3",
|
|
||||||
"url": "https://v1.102.3.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.101.0",
|
|
||||||
"url": "https://v1.101.0.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.100.0",
|
|
||||||
"url": "https://v1.100.0.archive.immich.app",
|
|
||||||
"rootPath": "/docs"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
@ -1,23 +1,10 @@
|
||||||
import semver from 'semver';
|
import semver from 'semver';
|
||||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
import { describe, expect, it } from 'vitest';
|
||||||
import {
|
import { getMobileBuild, getNewVersion, ReleaseError } from './release';
|
||||||
resolveArchivedVersions,
|
|
||||||
ArchivedVersion,
|
|
||||||
getMobileBuild,
|
|
||||||
getNewVersion,
|
|
||||||
ReleaseError,
|
|
||||||
} from './release';
|
|
||||||
|
|
||||||
const mobileBuild = (version: string) =>
|
const mobileBuild = (version: string) =>
|
||||||
getMobileBuild(semver.parse(version) as semver.SemVer);
|
getMobileBuild(semver.parse(version) as semver.SemVer);
|
||||||
|
|
||||||
const archived = (label: string): ArchivedVersion => ({
|
|
||||||
label,
|
|
||||||
url: `https://docs.${label}.archive.immich.app`,
|
|
||||||
});
|
|
||||||
|
|
||||||
const labels = (versions: ArchivedVersion[]) => versions.map((v) => v.label);
|
|
||||||
|
|
||||||
describe(getNewVersion.name, () => {
|
describe(getNewVersion.name, () => {
|
||||||
describe('transitions', () => {
|
describe('transitions', () => {
|
||||||
const valid = [
|
const valid = [
|
||||||
|
|
@ -82,67 +69,6 @@ describe(getNewVersion.name, () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe(resolveArchivedVersions.name, () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
// silence the "Removed ..." progress logging
|
|
||||||
vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should prepend the new version to the front', () => {
|
|
||||||
const result = resolveArchivedVersions([archived('v2.9.0')], '3.0.0');
|
|
||||||
|
|
||||||
expect(result[0]).toEqual({
|
|
||||||
label: 'v3.0.0',
|
|
||||||
url: 'https://docs.v3.0.0.archive.immich.app',
|
|
||||||
});
|
|
||||||
expect(labels(result)).toEqual(['v3.0.0', 'v2.9.0']);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle an empty list', () => {
|
|
||||||
expect(labels(resolveArchivedVersions([], '3.0.0'))).toEqual(['v3.0.0']);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should drop older patch releases of the new version minor', () => {
|
|
||||||
const versions = ['v3.0.4', 'v3.0.3', 'v3.0.2'].map(archived);
|
|
||||||
|
|
||||||
expect(labels(resolveArchivedVersions(versions, '3.0.5'))).toEqual([
|
|
||||||
'v3.0.5',
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should keep the latest patch of each older minor', () => {
|
|
||||||
const versions = ['v3.1.2', 'v3.1.1', 'v3.0.9', 'v2.0.0'].map(archived);
|
|
||||||
|
|
||||||
expect(labels(resolveArchivedVersions(versions, '3.2.0'))).toEqual([
|
|
||||||
'v3.2.0',
|
|
||||||
'v3.1.2',
|
|
||||||
'v3.0.9',
|
|
||||||
'v2.0.0',
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should keep an older minor when bumping a patch', () => {
|
|
||||||
const versions = ['v3.0.4', 'v3.0.3', 'v2.9.1', 'v2.9.0', 'v1.5.0'].map(
|
|
||||||
archived,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(labels(resolveArchivedVersions(versions, '3.0.5'))).toEqual([
|
|
||||||
'v3.0.5',
|
|
||||||
'v2.9.1',
|
|
||||||
'v1.5.0',
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should replace a prerelease with its release', () => {
|
|
||||||
const versions = ['v3.0.0-rc.2', 'v3.0.0-rc.1', 'v2.9.0'].map(archived);
|
|
||||||
|
|
||||||
expect(labels(resolveArchivedVersions(versions, '3.0.0'))).toEqual([
|
|
||||||
'v3.0.0',
|
|
||||||
'v2.9.0',
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe(getMobileBuild.name, () => {
|
describe(getMobileBuild.name, () => {
|
||||||
it('should encode the version', () => {
|
it('should encode the version', () => {
|
||||||
expect(mobileBuild('3.1.0')).toBe(3_010_099);
|
expect(mobileBuild('3.1.0')).toBe(3_010_099);
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ const Files = {
|
||||||
Docs: {
|
Docs: {
|
||||||
Env: join(root, 'docs/docs/install/environment-variables.md'),
|
Env: join(root, 'docs/docs/install/environment-variables.md'),
|
||||||
Upgrading: join(root, 'docs/docs/install/upgrading.md'),
|
Upgrading: join(root, 'docs/docs/install/upgrading.md'),
|
||||||
ArchivedVersions: join(root, 'docs/static/archived-versions.json'),
|
|
||||||
},
|
},
|
||||||
Mobile: {
|
Mobile: {
|
||||||
Pubspec: join(root, 'mobile/pubspec.yaml'),
|
Pubspec: join(root, 'mobile/pubspec.yaml'),
|
||||||
|
|
@ -92,13 +91,6 @@ export const handleRelease = ({ type }: ReleaseOptions) => {
|
||||||
pump(Files.Docs.Upgrading, /:v\d+/, `:${major}`);
|
pump(Files.Docs.Upgrading, /:v\d+/, `:${major}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update archived versions list
|
|
||||||
const archivedFile = new JsonFile<ArchivedVersion[]>(
|
|
||||||
Files.Docs.ArchivedVersions,
|
|
||||||
);
|
|
||||||
const versions = archivedFile.read();
|
|
||||||
archivedFile.write(resolveArchivedVersions(versions, newVersionRaw));
|
|
||||||
|
|
||||||
if (process.env.GITHUB_ENV) {
|
if (process.env.GITHUB_ENV) {
|
||||||
// make available for following steps
|
// make available for following steps
|
||||||
appendFileSync(
|
appendFileSync(
|
||||||
|
|
@ -222,50 +214,6 @@ const pump = (path: string, pattern: RegExp, replacement: string) => {
|
||||||
file.write(update);
|
file.write(update);
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface ArchivedVersion {
|
|
||||||
label: string;
|
|
||||||
url: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const resolveArchivedVersions = (
|
|
||||||
versions: ArchivedVersion[],
|
|
||||||
nextVersion: string,
|
|
||||||
): ArchivedVersion[] => {
|
|
||||||
const newVersion: ArchivedVersion = {
|
|
||||||
label: `v${nextVersion}`,
|
|
||||||
url: `https://docs.v${nextVersion}.archive.immich.app`,
|
|
||||||
};
|
|
||||||
|
|
||||||
let result = versions;
|
|
||||||
let lastVersion = asVersion(newVersion);
|
|
||||||
for (const item of versions) {
|
|
||||||
const version = asVersion(item);
|
|
||||||
// only keep the latest patch version for each minor release
|
|
||||||
if (
|
|
||||||
lastVersion.major === version.major &&
|
|
||||||
lastVersion.minor === version.minor &&
|
|
||||||
lastVersion.patch >= version.patch
|
|
||||||
) {
|
|
||||||
result = result.filter((item) => item.label !== version.label);
|
|
||||||
console.log(
|
|
||||||
`Removed ${version.label} (replaced with ${lastVersion.label})`,
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastVersion = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [newVersion, ...result];
|
|
||||||
};
|
|
||||||
|
|
||||||
const asVersion = (item: ArchivedVersion) => {
|
|
||||||
const { label, url } = item;
|
|
||||||
const [version] = label.substring(1).split('-');
|
|
||||||
const [major, minor, patch] = version.split('.').map(Number);
|
|
||||||
return { major, minor, patch, label, url };
|
|
||||||
};
|
|
||||||
|
|
||||||
const isPrerelease = (version: SemVer) => version.prerelease.length > 0;
|
const isPrerelease = (version: SemVer) => version.prerelease.length > 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue