94 lines · 3.3 KB · TypeScript
RawDownload
#!/usr/bin/env node import * as NodeRuntime from "@effect/platform-node/NodeRuntime";import * as NodeServices from "@effect/platform-node/NodeServices";import { Config, Console, Effect, FileSystem, Option, Path, Schema, SchemaGetter } from "effect";import { Argument, Command, Flag } from "effect/unstable/cli"; export const releasePackageFiles = [  "apps/server/package.json",  "apps/desktop/package.json",  "apps/web/package.json",  "packages/contracts/package.json",] as const; interface UpdateReleasePackageVersionsOptions {  readonly rootDir?: string | undefined;} const PackageJsonSchema = Schema.Record(Schema.String, Schema.Unknown);const PrettyJsonString = SchemaGetter.parseJson<string>().compose(  SchemaGetter.stringifyJson({ space: 2 }),);const PackageJsonPrettyJson = Schema.fromJsonString(PackageJsonSchema).pipe(  Schema.encode({    decode: PrettyJsonString,    encode: PrettyJsonString,  }),);const decodePackageJson = Schema.decodeUnknownEffect(PackageJsonPrettyJson);const encodePackageJson = Schema.encodeSync(PackageJsonPrettyJson); export const updateReleasePackageVersions = Effect.fn("updateReleasePackageVersions")(function* (  version: string,  options: UpdateReleasePackageVersionsOptions = {},) {  const fs = yield* FileSystem.FileSystem;  const path = yield* Path.Path;  const rootDir = path.resolve(options.rootDir ?? process.cwd());  let changed = false;   for (const relativePath of releasePackageFiles) {    const filePath = path.join(rootDir, relativePath);    const packageJson = yield* fs.readFileString(filePath).pipe(Effect.flatMap(decodePackageJson));    if (packageJson.version === version) {      continue;    }     yield* fs.writeFileString(filePath, `${encodePackageJson({ ...packageJson, version })}\n`);    changed = true;  }   return { changed };}); const writeGithubOutput = Effect.fn("writeGithubOutput")(function* (changed: boolean) {  const fs = yield* FileSystem.FileSystem;  const githubOutputPath = yield* Config.nonEmptyString("GITHUB_OUTPUT");  yield* fs.writeFileString(githubOutputPath, `changed=${changed}\n`, { flag: "a" });}); export const updateReleasePackageVersionsCommand = Command.make(  "update-release-package-versions",  {    version: Argument.string("version").pipe(      Argument.withDescription("Release version to write into each releasable package.json."),    ),    root: Flag.string("root").pipe(      Flag.withDescription("Workspace root used to resolve the release package manifests."),      Flag.optional,    ),    githubOutput: Flag.boolean("github-output").pipe(      Flag.withDescription("Append changed=<boolean> to GITHUB_OUTPUT."),      Flag.withDefault(false),    ),  },  ({ version, root, githubOutput }) =>    updateReleasePackageVersions(version, {      rootDir: Option.getOrUndefined(root),    }).pipe(      Effect.tap(({ changed }) =>        changed          ? Effect.void          : Console.log("All package.json versions already match release version."),      ),      Effect.tap(({ changed }) => (githubOutput ? writeGithubOutput(changed) : Effect.void)),    ),).pipe(Command.withDescription("Update release package versions across the workspace.")); if (import.meta.main) {  Command.run(updateReleasePackageVersionsCommand, { version: "0.0.0" }).pipe(    Effect.provide(NodeServices.layer),    NodeRuntime.runMain,  );}