Skip to content

Instantly share code, notes, and snippets.

@ItsWendell
Last active August 25, 2023 08:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ItsWendell/2f2694e28d405862916e24088ca74014 to your computer and use it in GitHub Desktop.
Save ItsWendell/2f2694e28d405862916e24088ca74014 to your computer and use it in GitHub Desktop.
Expo: Runtime Versioning based on pnpm lock
#!/usr/bin/env -S pnpm tsx
import crypto from "crypto";
import fs from "fs";
import path from "path";
import {
createFingerprintAsync,
diffFingerprintChangesAsync,
} from "@expo/fingerprint";
const projectRoot = process.cwd();
const hash = crypto.createHash("sha1");
const run = async () => {
console.log(
"[Runtime Versioning] Checking runtime version in " + projectRoot,
);
const runtimeVersionPath = path.join(projectRoot, "runtime-version.json");
const runtimeVersionJson = fs.readFileSync(runtimeVersionPath, "utf8");
const runtimeVersion = JSON.parse(runtimeVersionJson);
const skipReasons = [
// Skip the package.json scripts because they are not relevant to the runtime
"packageJson:scripts",
// WE don't consider the easBuild script relevant to the runtime
"easBuild",
] as const;
const fingerprint = await createFingerprintAsync(projectRoot, {
hashAlgorithm: "sha1",
});
let sources = fingerprint.sources
// Filter out sources that we don't want to include in the hash
.filter((source) => {
if (!source.hash) {
return false;
}
return !skipReasons.some((reason) => source.reasons.includes(reason));
})
// Sort to make sure the order is consistent
.sort((a, b) => {
if (a.type !== b.type) {
return a.type > b.type ? 1 : -1;
} else if ("filePath" in a && "filePath" in b) {
return a.filePath.toLowerCase() > b.filePath.toLowerCase() ? 1 : -1;
} else if ("id" in a && "id" in b) {
return a.id > b.id ? 1 : -1;
} else {
return 0;
}
});
for (const source of sources) {
if (!source.hash) {
throw new Error(`Source has no hash`);
}
// Push the hash of each source into the hash of the runtime version
await hash.update(source.hash);
}
const isCi = process.env.CI === "true";
const hashHex = hash.digest("hex");
if (runtimeVersion.hash !== hashHex) {
if (isCi) {
console.error(
"[Runtime Versioning] Runtime version is out of date, and won't be updated in CI",
);
process.exitCode = 1;
return;
}
const newFile = {
version: runtimeVersion.version + 1,
hash: hashHex,
sources,
};
fs.writeFileSync(runtimeVersionPath, JSON.stringify(newFile, null, 2));
console.log(
`[Runtime Versioning] Runtime version incremented to ${runtimeVersion.version}`,
);
} else {
console.log(`[Runtime Versioning] Runtime version is up to date`);
}
};
run().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment