Skip to content

Commit

Permalink
Fixed an issue that prevented fresh latest versions to be installed a…
Browse files Browse the repository at this point in the history
…fter installing dev versions of the runtime (#629)
  • Loading branch information
Andarist authored Dec 13, 2024
1 parent 9019fef commit 42866f2
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 31 deletions.
5 changes: 5 additions & 0 deletions .changeset/calm-insects-sell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"replayio": patch
---

Fixed an issue that prevented fresh latest versions to be installed after installing dev versions of the runtime
10 changes: 4 additions & 6 deletions packages/replayio/src/commands/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { registerCommand } from "../utils/commander/registerCommand";
import { checkForNpmUpdate } from "../utils/initialization/checkForNpmUpdate";
import { checkForRuntimeUpdate } from "../utils/initialization/checkForRuntimeUpdate";
import { promptForNpmUpdate } from "../utils/initialization/promptForNpmUpdate";
import { installLatestRelease } from "../utils/installation/installLatestRelease";
import { installRelease } from "../utils/installation/installRelease";

registerCommand("update", {
checkForRuntimeUpdate: false,
Expand All @@ -18,14 +18,12 @@ registerCommand("update", {
async function update() {
try {
const [runtimeUpdateCheck, npmUpdateCheck] = await Promise.all([
process.env.RECORD_REPLAY_CHROMIUM_DOWNLOAD_FILE
? { hasUpdate: true }
: checkForRuntimeUpdate(),
checkForRuntimeUpdate(),
checkForNpmUpdate(),
]);

if (runtimeUpdateCheck.hasUpdate && npmUpdateCheck.hasUpdate) {
await installLatestRelease();
await installRelease(runtimeUpdateCheck.toVersion);
await promptForNpmUpdate(npmUpdateCheck, false);
} else if (npmUpdateCheck.hasUpdate) {
console.log(statusSuccess("✔"), "You have the latest version of the Replay Browser");
Expand All @@ -34,7 +32,7 @@ async function update() {
} else if (runtimeUpdateCheck.hasUpdate) {
console.log(statusSuccess("✔"), "You have the latest version of replayio");

await installLatestRelease();
await installRelease(runtimeUpdateCheck.toVersion);
} else {
console.log(
statusSuccess("✔"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,24 @@ const PROMPT_ID = "runtime-update";

export type Version = {
buildId: Release["buildId"];
version: Release["version"];
forkedVersion: Release["version"];
};

export const checkForRuntimeUpdate = createAsyncFunctionWithTracking(
async function checkForRuntimeUpdate(): Promise<UpdateCheck<Version>> {
if (process.env.RECORD_REPLAY_CHROMIUM_DOWNLOAD_FILE) {
const { buildId: currentBuildId } = getCurrentRuntimeMetadata("chromium") ?? {};
const requestedBuildId = process.env.RECORD_REPLAY_CHROMIUM_DOWNLOAD_FILE
// strip extension
.replace(/\..+$/, "");
logDebug("CheckForRuntimeUpdate:CurrentBuild", { currentBuildId, requestedBuildId });
return {
hasUpdate: true,
fromVersion: currentBuildId ? { buildId: currentBuildId, forkedVersion: null } : undefined,
shouldShowPrompt: false,
toVersion: { buildId: requestedBuildId, forkedVersion: "dev" },
};
}
let latestRelease: Release;
let latestBuildId: string;
try {
Expand All @@ -42,7 +55,7 @@ export const checkForRuntimeUpdate = createAsyncFunctionWithTracking(
hasUpdate: true,
fromVersion: undefined,
shouldShowPrompt: true,
toVersion: { buildId: latestBuildId, version: latestRelease.version },
toVersion: { buildId: latestBuildId, forkedVersion: latestRelease.version },
};
}

Expand All @@ -51,19 +64,19 @@ export const checkForRuntimeUpdate = createAsyncFunctionWithTracking(

return {
hasUpdate: currentBuildId !== latestBuildId,
fromVersion: currentBuildId ? { buildId: currentBuildId, version: null } : undefined,
fromVersion: currentBuildId ? { buildId: currentBuildId, forkedVersion: null } : undefined,
shouldShowPrompt: shouldPrompt({
id: PROMPT_ID,
metadata: latestBuildId,
}),
toVersion: { buildId: latestBuildId, version: latestRelease.version },
toVersion: { buildId: latestBuildId, forkedVersion: latestRelease.version },
};
},
"update.runtime.check",
result => ({
hasUpdate: result?.hasUpdate,
newBuildId: result?.hasUpdate ? result?.toVersion.buildId : null,
newRuntimeVersion: result?.hasUpdate ? result?.toVersion.version : null,
newRuntimeVersion: result?.hasUpdate ? result?.toVersion.forkedVersion : null,
shouldShowPrompt: !!(result?.hasUpdate && result?.shouldShowPrompt),
})
);
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { trackEvent } from "@replay-cli/shared/mixpanelClient";
import { emphasize } from "@replay-cli/shared/theme";
import { name as packageName } from "../../../package.json";
import { installLatestRelease } from "../installation/installLatestRelease";
import { installRelease } from "../installation/installRelease";
import { prompt } from "../prompt/prompt";
import { updateCachedPromptData } from "../prompt/updateCachedPromptData";
import { Version } from "./checkForRuntimeUpdate";
import { UpdateCheckResult } from "./types";
import { getLatestRelease } from "../installation/getLatestReleases";

const PROMPT_ID = "runtime-update";

Expand Down Expand Up @@ -44,7 +45,11 @@ export async function promptForRuntimeUpdate(updateCheck: UpdateCheckResult<Vers

if (confirmed) {
try {
await installLatestRelease();
const latestRelease = await getLatestRelease();
await installRelease({
buildId: latestRelease.buildId,
forkedVersion: latestRelease.version,
});
} catch (error) {
// A failed update is not a critical error;
// A failed install will be handled later
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,18 @@ import { get } from "https";
import { join } from "path";
import { logAsyncOperation } from "../async/logAsyncOperation";
import { metadataPath, runtimeMetadata } from "./config";
import { getLatestRelease } from "./getLatestReleases";
import { MetadataJSON } from "./types";

const MAX_DOWNLOAD_ATTEMPTS = 5;

type Result = {
type ReleaseSpec = {
buildId: string;
forkedVersion: string | null;
};

export const installLatestRelease = createAsyncFunctionWithTracking(
async function installLatestRelease(): Promise<Result | undefined> {
logInfo("InstallLatestRelease:Start");
export const installRelease = createAsyncFunctionWithTracking(
async function installRelease(releaseSpec: ReleaseSpec): Promise<ReleaseSpec | undefined> {
logInfo("InstallRelease:Start");
const runtimeBaseDir = getReplayPath("runtimes");
const runtimePath = getReplayPath("runtimes", runtimeMetadata.destinationName);
const downloadFilePath = getReplayPath("runtimes", runtimeMetadata.downloadFileName);
Expand All @@ -39,17 +38,17 @@ export const installLatestRelease = createAsyncFunctionWithTracking(

progress.setPending("Processing downloaded browser archive");

logInfo("InstallLatestRelease:RemovingPreviousInstallation", { runtimePath });
logInfo("InstallRelease:RemovingPreviousInstallation", { runtimePath });
rmSync(runtimePath, { force: true, recursive: true });

ensureDirSync(runtimeBaseDir);

logInfo("InstallLatestRelease:WritingDownloadFile", { downloadFilePath });
logInfo("InstallRelease:WritingDownloadFile", { downloadFilePath });
writeFileSync(downloadFilePath, buffers);

extractBrowserArchive(runtimeBaseDir, runtimePath);

logInfo("InstallLatestRelease:DeletingDownloadedFile", { downloadFilePath });
logInfo("InstallRelease:DeletingDownloadedFile", { downloadFilePath });
unlinkSync(downloadFilePath);

// This seems unnecessary, but we've always done it (and changing it would break legacy CLI compat)
Expand All @@ -62,28 +61,24 @@ export const installLatestRelease = createAsyncFunctionWithTracking(
);
}

const latestRelease = await getLatestRelease();
const latestBuildId = latestRelease.buildId;
const latestVersion = latestRelease.version;

// Write version metadata to disk so we can compare against the latest release and prompt to update
logInfo("InstallLatestRelease:SavingMetadata", { metadataPath });
logInfo("InstallRelease:SavingMetadata", { metadataPath });
writeToCache<MetadataJSON>(metadataPath, {
chromium: {
buildId: latestBuildId,
forkedVersion: latestVersion,
buildId: releaseSpec.buildId,
forkedVersion: releaseSpec.forkedVersion,
installDate: new Date().toISOString(),
},
});

progress.setSuccess("Replay browser has been updated.");

return {
buildId: latestBuildId,
forkedVersion: latestVersion,
buildId: releaseSpec.buildId,
forkedVersion: releaseSpec.forkedVersion,
};
} catch (error) {
logError("InstallLatestRelease:Failed", { error });
logError("InstallRelease:Failed", { error });

progress.setFailed("Something went wrong installing the Replay browser.");
throw error;
Expand Down

0 comments on commit 42866f2

Please sign in to comment.