Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added versioning awareness support #305

Merged
merged 4 commits into from Jan 10, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions how-to/customize-workspace/CHANGELOG.md
Expand Up @@ -17,6 +17,7 @@
- Added opinionated support for fdc3.open (see [How To Add Open Support To Your App](./docs/how-to-add-open-support-to-your-app.md))
- Updated example auth to give an example of how workspace can present entitled based data by letting you pick from two users and each user has a role (developer or sales) and the developer role has an apps feed that consists of developer related apps and has menu options that help developers (inspect view, window, platform etc) where as the sales role keeps the demo apps but filters out developer related menu options and apps. **npm run secondclient** will run the demo.
- Moved the create app definition action logic from the app definition module (which has been deleted) into a developer action module which also has inspect menu actions.
- Added ability to specify a minimum and/or maximum version for something your platform depends on (see [How To Add Version Support](./docs/how-to-add-versioning-support.md))

## v9.2

Expand Down
Expand Up @@ -81,5 +81,5 @@ export async function init(
});
}
}
return next(settings.platformProvider);
return next(settings?.platformProvider);
}
77 changes: 59 additions & 18 deletions how-to/customize-workspace/client/src/framework/bootstrapper.ts
@@ -1,4 +1,4 @@
import type { HomeRegistration } from "@openfin/workspace";
import type { HomeRegistration, RegistrationMetaInfo } from "@openfin/workspace";
import { getCurrentSync } from "@openfin/workspace-platform";
import * as authProvider from "./auth";
import { isAuthenticationEnabled } from "./auth";
Expand All @@ -12,7 +12,7 @@ import { getDefaultHelpers } from "./modules";
import { getSettings } from "./settings";
import type { ModuleHelpers } from "./shapes";
import type { BootstrapComponents, BootstrapOptions } from "./shapes/bootstrap-shapes";

import * as versionProvider from "./version";
import {
deregister as deregisterDock,
minimize as minimizeDock,
Expand Down Expand Up @@ -41,6 +41,7 @@ import {
const logger = createLogger("Bootstrapper");

let bootstrapOptions: BootstrapOptions;
let deregistered = false;

export async function init(): Promise<boolean> {
// you can kick off your bootstrapping process here where you may decide to prompt for authentication,
Expand All @@ -58,10 +59,16 @@ export async function init(): Promise<boolean> {

const registeredComponents: BootstrapComponents[] = [];
let homeRegistration: HomeRegistration;
let workspaceMetaInfo: RegistrationMetaInfo;
let notificationMetaInfo: RegistrationMetaInfo;

if (bootstrapOptions.home) {
// only register search logic once workspace is running
homeRegistration = await registerHome();
workspaceMetaInfo = {
workspaceVersion: homeRegistration.workspaceVersion,
clientAPIVersion: homeRegistration.clientAPIVersion
};
registeredComponents.push("home");
registerAction("show-home", async () => {
await showHome();
Expand All @@ -74,7 +81,7 @@ export async function init(): Promise<boolean> {
await registerIntegration(settings.integrationProvider, helpers, homeRegistration);

if (bootstrapOptions.store) {
await registerStore();
workspaceMetaInfo = await registerStore();
registeredComponents.push("store");
registerAction("show-store", async () => {
await showStore();
Expand All @@ -85,7 +92,7 @@ export async function init(): Promise<boolean> {
}

if (bootstrapOptions.dock) {
await registerDock(bootstrapOptions);
workspaceMetaInfo = await registerDock(bootstrapOptions);
registeredComponents.push("dock");
registerAction("show-dock", async () => {
await showDock();
Expand All @@ -96,7 +103,7 @@ export async function init(): Promise<boolean> {
}

if (bootstrapOptions.notifications) {
await registerNotifications();
notificationMetaInfo = await registerNotifications();
registerAction("show-notifications", async () => {
await showNotifications();
});
Expand All @@ -105,6 +112,33 @@ export async function init(): Promise<boolean> {
});
}

if (workspaceMetaInfo !== undefined) {
// we match the versions of workspace related packages
versionProvider.setVersion("WorkspacePlatformClient", workspaceMetaInfo.clientAPIVersion);
versionProvider.setVersion("WorkspaceClient", workspaceMetaInfo.clientAPIVersion);
versionProvider.setVersion("Workspace", workspaceMetaInfo.workspaceVersion);
}

if (notificationMetaInfo !== undefined) {
versionProvider.setVersion("NotificationCenter", notificationMetaInfo.workspaceVersion);
}

if (!versionProvider.isSupported()) {
const warningWindow = versionProvider.getVersionWindowConfiguration();
if (warningWindow !== undefined) {
logger.info(
"Unable to meet minimum version requirements and a warning window has been provided. Bootstrapping process has been stopped."
);
await deregister();
const openWarningWindow = await fin.Window.create(warningWindow);
await openWarningWindow.setAsForeground();
return false;
}
} else {
const versionInfo = await versionProvider.getVersionInfo();
logger.info("Bootstrapped with following versions.", versionInfo);
}

// Remove any entries from autoShow that have not been registered
bootstrapOptions.autoShow = bootstrapOptions.autoShow.filter(
(component) => registeredComponents.includes(component) || component === "none"
Expand Down Expand Up @@ -149,19 +183,7 @@ export async function init(): Promise<boolean> {

const providerWindow = fin.Window.getCurrentSync();
await providerWindow.once("close-requested", async (event) => {
await deregisterIntegration();
if (bootstrapOptions.dock) {
await deregisterDock();
}
if (bootstrapOptions.store) {
await deregisterStore();
}
if (bootstrapOptions.home) {
await deregisterHome();
}
if (bootstrapOptions.notifications) {
await deregisterNotifications();
}
await deregister();
await fin.Platform.getCurrentSync().quit();
});

Expand All @@ -177,3 +199,22 @@ export async function init(): Promise<boolean> {

return true;
}

async function deregister() {
if (!deregistered) {
await deregisterIntegration();
if (bootstrapOptions.dock) {
await deregisterDock();
}
if (bootstrapOptions.store) {
await deregisterStore();
}
if (bootstrapOptions.home) {
await deregisterHome();
}
if (bootstrapOptions.notifications) {
await deregisterNotifications();
}
deregistered = true;
}
}
2 changes: 2 additions & 0 deletions how-to/customize-workspace/client/src/framework/modules.ts
Expand Up @@ -13,6 +13,7 @@ import type {
} from "./shapes/module-shapes";
import { getCurrentColorSchemeMode, getCurrentPalette, getCurrentThemeId } from "./themes";
import { randomUUID } from "./uuid";
import { getVersionInfo } from "./version";

const logger = createLogger("Modules");
const sessionId = randomUUID();
Expand Down Expand Up @@ -205,6 +206,7 @@ export function getDefaultHelpers(settings: CustomSettings): ModuleHelpers {
getCurrentThemeId,
getCurrentPalette,
getCurrentColorSchemeMode,
getVersionInfo,
subscribeLifecycleEvent,
unsubscribeLifecycleEvent
};
Expand Down
Expand Up @@ -16,6 +16,7 @@ import type { CustomSettings, ModuleHelpers } from "../shapes";
import type { PlatformProviderOptions } from "../shapes/platform-shapes";
import { deregister as deregisterShare, register as registerShare, isShareEnabled } from "../share";
import { getThemes, notifyColorScheme, supportsColorSchemes } from "../themes";
import * as versionProvider from "../version";
import { getDefaultWindowOptions } from "./browser";
import { interopOverride } from "./interopbroker";
import { overrideCallback } from "./platform-override";
Expand All @@ -38,6 +39,14 @@ async function setupPlatform(_?: PlatformProviderOptions): Promise<boolean> {

logger.info("Initializing Core Services");

await versionProvider.init(settings?.versionProvider);

const runtimeVersion = await fin.System.getVersion();
const rvmInfo = await fin.System.getRvmInfo();
versionProvider.setVersion("Runtime", runtimeVersion);
versionProvider.setVersion("RVM", rvmInfo.version);
versionProvider.setVersion("PlatformClient", VERSION);

await endpointProvider.init(settings?.endpointProvider, helpers);
await connectionProvider.init(settings?.connectionProvider);
await analyticsProvider.init(settings?.analyticsProvider, helpers);
Expand Down Expand Up @@ -82,6 +91,8 @@ async function setupPlatform(_?: PlatformProviderOptions): Promise<boolean> {
return true;
}

export const VERSION = "10.3.0";

export async function init(): Promise<boolean> {
const isValid = await initAuthFlow(setupPlatform, logger, true);
if (!isValid) {
Expand Down
Expand Up @@ -2,6 +2,7 @@ import type { CustomPaletteSet } from "@openfin/workspace/common/src/api/theming
import type { LifecycleEvents, LifecycleHandler } from "./lifecycle-shapes";
import type { LoggerCreator } from "./logger-shapes";
import type { ColorSchemeMode } from "./theme-shapes";
import type { VersionInfo } from "./version-shapes";

/**
* List of modules.
Expand Down Expand Up @@ -87,6 +88,11 @@ export interface ModuleHelpers {
*/
getCurrentColorSchemeMode(): Promise<ColorSchemeMode>;

/**
* Get the version information related to the platform you are running in.
*/
getVersionInfo(): Promise<VersionInfo>;

/**
* Subscribe to lifecycle events.
* @param lifecycleEvent The event to subscribe to.
Expand Down
Expand Up @@ -18,6 +18,7 @@ import type { NotificationProviderOptions } from "./notification-shapes";
import type { PlatformProviderOptions } from "./platform-shapes";
import type { StorefrontProviderOptions } from "./store-shapes";
import type { ThemeProviderOptions } from "./theme-shapes";
import type { VersionProviderOptions } from "./version-shapes";

export interface CustomSettings {
$schema?: string;
Expand All @@ -41,4 +42,5 @@ export interface CustomSettings {
conditionsProvider?: ConditionsProviderOptions;
lifecycleProvider?: LifecycleProviderOptions;
analyticsProvider?: AnalyticsProviderOptions;
versionProvider?: VersionProviderOptions;
}
@@ -0,0 +1,64 @@
export interface VersionInfo {
/** The version of the the instance of this platform if provided */
app?: string;
/** The version of the code of this platform */
platformClient?: string;
/** The version of the workspace platform client code */
workspacePlatformClient?: string;
/** The version of the workspace client code */
workspaceClient?: string;
/** The version of the workspace components this platform is currently connected to */
workspace?: string;
/** The version of the notification center that this platform instance has connected to */
notificationCenter?: string;
/** The version of the runtime this platform instance is running against */
runtime?: string;
/** The version of the rvm that was used to launch this platform */
rvm?: string;
}

export interface VersionProviderOptions {
/** The version of the the instance of this platform */
appVersion?: string;

/** You can specify if the platform should stop initializing if the version is less than any of the specified minimum versions */
minimumVersion?: MinimumVersion;

/** You can specify if the platform should stop initializing if the version is more than any of the specified maximum versions */
maximumVersion?: MinimumVersion;
johnman marked this conversation as resolved.
Show resolved Hide resolved

/**
* If the minimum version is not met and a window is configured then:
* - any workspace component registrations will be un-registered
* - the configured window will be shown and passed the current version and minimum version as customData
* Otherwise the platform will continue to load and the version information will be passed onto loaded modules
* through the getVersionInfo function exposed through the passed helper.
*/
versionWindow?: unknown;
}

export interface VersionWindowCustomData {
/** The collection version information */
versionInfo: VersionInfo;
/** The configured minimum limits */
minVersion: MinimumVersion;
/** The configured maximum limits */
maxVersion: MaximumVersion;
/** The version type that failed the minimum requirements */
minFail: string[];
/** The version type that failed the maximum requirements */
maxFail: string[];
}

export type VersionType =
| "PlatformClient"
| "WorkspacePlatformClient"
| "WorkspaceClient"
| "Workspace"
| "NotificationCenter"
| "Runtime"
| "RVM";

export type MinimumVersion = Omit<VersionInfo, "app">;

export type MaximumVersion = Omit<VersionInfo, "app">;