From 74705053938c5e07bda432e97e983ed962e365a1 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Fri, 20 Sep 2024 10:17:24 -0700 Subject: [PATCH] Expose release plan markdown summary function (#287) --- ...ose-markdown-summary-2024-8-20-17-11-16.md | 8 ++++ .github/workflows/prepare-release-pr.yml | 2 +- ...elease-branch.js => prepare-release-pr.ts} | 11 +++-- eng/tsconfig.json | 7 ++++ .../chronus/src/cli/commands/show-status.ts | 41 ++----------------- packages/chronus/src/index.ts | 1 + packages/chronus/src/release-plan/current.ts | 13 ++++++ packages/chronus/src/release-plan/index.ts | 2 + packages/chronus/src/release-plan/markdown.ts | 32 +++++++++++++++ 9 files changed, 75 insertions(+), 42 deletions(-) create mode 100644 .chronus/changes/expose-markdown-summary-2024-8-20-17-11-16.md rename eng/{prepare-release-branch.js => prepare-release-pr.ts} (82%) create mode 100644 eng/tsconfig.json create mode 100644 packages/chronus/src/release-plan/current.ts create mode 100644 packages/chronus/src/release-plan/markdown.ts diff --git a/.chronus/changes/expose-markdown-summary-2024-8-20-17-11-16.md b/.chronus/changes/expose-markdown-summary-2024-8-20-17-11-16.md new file mode 100644 index 00000000..314fa713 --- /dev/null +++ b/.chronus/changes/expose-markdown-summary-2024-8-20-17-11-16.md @@ -0,0 +1,8 @@ +--- +# Change versionKind to one of: breaking, feature, fix, internal +changeKind: feature +packages: + - "@chronus/chronus" +--- + +[API] Expose function to get markdown summary of release plan diff --git a/.github/workflows/prepare-release-pr.yml b/.github/workflows/prepare-release-pr.yml index f471097f..e2266ec8 100644 --- a/.github/workflows/prepare-release-pr.yml +++ b/.github/workflows/prepare-release-pr.yml @@ -28,6 +28,6 @@ jobs: name: Build - name: Create release branch - run: node ./eng/prepare-release-branch.js + run: pnpm tsx ./eng/prepare-release-pr.ts env: GITHUB_TOKEN: ${{secrets.CUSTOM_GITHUB_TOKEN}} diff --git a/eng/prepare-release-branch.js b/eng/prepare-release-pr.ts similarity index 82% rename from eng/prepare-release-branch.js rename to eng/prepare-release-pr.ts index 157a369b..f846a172 100644 --- a/eng/prepare-release-branch.js +++ b/eng/prepare-release-pr.ts @@ -1,12 +1,17 @@ /* eslint-disable no-console */ -/* eslint-disable no-undef */ // @ts-check import { context, getOctokit } from "@actions/github"; import { execSync } from "child_process"; -import { showStatusAsMarkdown } from "../packages/chronus/dist/cli/commands/show-status.js"; +import { + NodeChronusHost, + renderReleasePlanAsMarkdown, + resolveCurrentReleasePlan, +} from "../packages/chronus/src/index.js"; +import {} from "../packages/chronus/src/release-plan/current.js"; const branchName = "publish/auto-release"; -const changeStatus = await showStatusAsMarkdown(process.cwd()); +const plan = await resolveCurrentReleasePlan(NodeChronusHost, process.cwd()); +const changeStatus = await renderReleasePlanAsMarkdown(plan); execSync(`pnpm change version`, { stdio: "inherit" }); const stdout = execSync(`git status --porcelain`).toString(); diff --git a/eng/tsconfig.json b/eng/tsconfig.json new file mode 100644 index 00000000..0f479d4e --- /dev/null +++ b/eng/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "noEmit": true + }, + "include": ["./**/*.ts", "../packages/chronus/src/index.ts"] +} diff --git a/packages/chronus/src/cli/commands/show-status.ts b/packages/chronus/src/cli/commands/show-status.ts index c42ad7be..6fce6865 100644 --- a/packages/chronus/src/cli/commands/show-status.ts +++ b/packages/chronus/src/cli/commands/show-status.ts @@ -1,9 +1,8 @@ import pc from "picocolors"; -import type { ReleaseAction, ReleasePlan } from "../../release-plan/types.js"; +import { resolveCurrentReleasePlan } from "../../release-plan/current.js"; +import type { ReleaseAction } from "../../release-plan/types.js"; import type { VersionType } from "../../types.js"; import { NodeChronusHost } from "../../utils/node-host.js"; -import { loadChronusWorkspace } from "../../workspace/load.js"; -import { resolveReleasePlan, type BumpVersionOptions } from "./bump-versions.js"; export interface ShowStatusOptions { readonly ignorePolicies?: boolean; @@ -15,7 +14,7 @@ function log(...args: any[]) { console.log(...args); } export async function showStatus(cwd: string, options: ShowStatusOptions): Promise { - const releasePlan = await resolveCurrentReleasePlan(cwd, options); + const releasePlan = await resolveCurrentReleasePlan(NodeChronusHost, cwd, options); let max = 50; for (const action of releasePlan.actions) { @@ -49,37 +48,3 @@ function logType(actions: ReleaseAction[], type: VersionType, pad: number, color } } } - -async function resolveCurrentReleasePlan(cwd: string, options?: BumpVersionOptions): Promise { - const host = NodeChronusHost; - const workspace = await loadChronusWorkspace(host, cwd); - return await resolveReleasePlan(host, workspace, options); -} - -export async function showStatusAsMarkdown(cwd: string): Promise { - const releasePlan = await resolveCurrentReleasePlan(cwd); - return [ - "", - "## Change summary:", - "", - ...typeAsMarkdown(releasePlan.actions, "major"), - "", - ...typeAsMarkdown(releasePlan.actions, "minor"), - "", - ...typeAsMarkdown(releasePlan.actions, "patch"), - "", - ].join("\n"); -} - -function typeAsMarkdown(actions: ReleaseAction[], type: VersionType): string[] { - const bold = (x: string) => `**${x}**`; - const filteredActions = actions.filter((x) => x.type === type); - if (filteredActions.length === 0) { - return [`### ${"No"} packages to be bumped at ${bold(type)}`]; - } else { - return [ - `### ${filteredActions.length} packages to be bumped at ${bold(type)}:`, - ...filteredActions.map((action) => `- ${action.packageName} \`${action.oldVersion}\` → \`${action.newVersion}\``), - ]; - } -} diff --git a/packages/chronus/src/index.ts b/packages/chronus/src/index.ts index ffcb3551..6cdb7ee7 100644 --- a/packages/chronus/src/index.ts +++ b/packages/chronus/src/index.ts @@ -1,5 +1,6 @@ export type { AreaStatus, ChangeArea, ChangeStatus, PackageStatus } from "./change/find.js"; export { getWorkspaceStatus } from "./change/get-workspace-status.js"; +export { renderReleasePlanAsMarkdown, resolveCurrentReleasePlan } from "./release-plan/index.js"; export { NodeChronusHost } from "./utils/node-host.js"; export { loadChronusWorkspace } from "./workspace/index.js"; export type { ChronusWorkspace } from "./workspace/types.js"; diff --git a/packages/chronus/src/release-plan/current.ts b/packages/chronus/src/release-plan/current.ts new file mode 100644 index 00000000..5e05e28f --- /dev/null +++ b/packages/chronus/src/release-plan/current.ts @@ -0,0 +1,13 @@ +import { type BumpVersionOptions, resolveReleasePlan } from "../cli/commands/bump-versions.js"; +import type { ChronusHost } from "../utils/host.js"; +import { loadChronusWorkspace } from "../workspace/load.js"; +import type { ReleasePlan } from "./types.js"; + +export async function resolveCurrentReleasePlan( + host: ChronusHost, + cwd: string, + options?: BumpVersionOptions, +): Promise { + const workspace = await loadChronusWorkspace(host, cwd); + return await resolveReleasePlan(host, workspace, options); +} diff --git a/packages/chronus/src/release-plan/index.ts b/packages/chronus/src/release-plan/index.ts index e2eb4104..ae179da3 100644 --- a/packages/chronus/src/release-plan/index.ts +++ b/packages/chronus/src/release-plan/index.ts @@ -1,2 +1,4 @@ export { assembleReleasePlan } from "./assemble-release-plan.js"; +export { resolveCurrentReleasePlan } from "./current.js"; +export { renderReleasePlanAsMarkdown } from "./markdown.js"; export type * from "./types.js"; diff --git a/packages/chronus/src/release-plan/markdown.ts b/packages/chronus/src/release-plan/markdown.ts new file mode 100644 index 00000000..8d8b29f4 --- /dev/null +++ b/packages/chronus/src/release-plan/markdown.ts @@ -0,0 +1,32 @@ +import type { VersionType } from "../types.js"; +import type { ReleaseAction, ReleasePlan } from "./types.js"; + +/** + * Render a markdown summary of the given release plan + */ +export async function renderReleasePlanAsMarkdown(releasePlan: ReleasePlan): Promise { + return [ + "", + "## Change summary:", + "", + ...typeAsMarkdown(releasePlan.actions, "major"), + "", + ...typeAsMarkdown(releasePlan.actions, "minor"), + "", + ...typeAsMarkdown(releasePlan.actions, "patch"), + "", + ].join("\n"); +} + +function typeAsMarkdown(actions: ReleaseAction[], type: VersionType): string[] { + const bold = (x: string) => `**${x}**`; + const filteredActions = actions.filter((x) => x.type === type); + if (filteredActions.length === 0) { + return [`### ${"No"} packages to be bumped at ${bold(type)}`]; + } else { + return [ + `### ${filteredActions.length} packages to be bumped at ${bold(type)}:`, + ...filteredActions.map((action) => `- ${action.packageName} \`${action.oldVersion}\` → \`${action.newVersion}\``), + ]; + } +}