Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/draft-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ jobs:
echo "<!-- version-banner -->"
echo "> [!WARNING]"
echo "> The manifests still declare \`$VERSION\`, which is already released."
echo "> Bump every manifest before publishing this draft (release spec §2)."
echo "> Run \`deno task bump <version>\` and merge the bump before publishing"
echo "> this draft (release spec §2)."
echo "<!-- /version-banner -->"
echo
cat /tmp/clean.md
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ jobs:
{
echo "> [!CAUTION]"
echo "> This release did not build: the manifests do not declare \`${TAG#v}\`."
echo "> Delete this release and its tag, bump every manifest, and release again"
echo "> (release spec §2)."
echo "> Delete this release and its tag, run \`deno task bump ${TAG#v}\`, merge"
echo "> the bump, and release again (release spec §2)."
echo
cat /tmp/body.md
} > /tmp/new.md
Expand Down
1 change: 1 addition & 0 deletions .reviews/components/ReleaseSpecWarning.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ list when a file is added or removed.
- .github/release-drafter.yml
- scripts/gen-publish-workflow.md
- scripts/build-npm.ts
- scripts/bump-version.ts

</Capture>

Expand Down
1 change: 1 addition & 0 deletions deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"xmd": "deno run --allow-all cli/src/cli.ts",
"build": "deno compile --node-modules-dir=none --exclude-unused-npm --allow-all --include packages/code-review-agent --output dist/xmd cli/src/cli.ts",
"gen:publish-workflow": "deno run --allow-all cli/src/cli.ts run scripts/gen-publish-workflow.md",
"bump": "deno run -A scripts/bump-version.ts",
"test": "deno test --allow-all core/tests/ durable-streams/tests/ packages/code-review-agent/tests/",
"check": "deno check core/mod.ts",
"lint": "npx oxlint -c .oxlintrc.json core/src/ cli/src/ durable-streams/ runtime/ && npx oxfmt --check core/src/ cli/src/ durable-streams/ runtime/ test-support/",
Expand Down
64 changes: 64 additions & 0 deletions scripts/bump-version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* Bump every @executablemd workspace manifest to a new version.
*
* Usage:
* deno task bump <version>
*
* Stamps the `version` field of each member's deno.json and package.json —
* the manifests are the single version source (release spec §2). Commit,
* merge, then publish the draft release as v<version>.
*/

import { exit, main } from "effection";
import { readTextFile, writeTextFile } from "@effectionx/fs";
import { z } from "npm:zod@^4";

const SCOPE = "@executablemd/";

const RootSchema = z.object({ workspace: z.array(z.string()) });
const NamedSchema = z.object({ name: z.string() });

await main(function* (args) {
const raw = args[0];
if (!raw) {
console.error("usage: deno task bump <version>");
yield* exit(1);
return;
}
const version = raw.replace(/^v/, "");
if (!/^\d+\.\d+\.\d+([-.][0-9A-Za-z.-]+)?$/.test(version)) {
console.error(`"${raw}" is not a semver version`);
yield* exit(1);
return;
}

const repoRoot = new URL("../", import.meta.url);
const root = RootSchema.parse(JSON.parse(yield* readTextFile(new URL("deno.json", repoRoot))));

for (const dir of root.workspace) {
let denoText: string;
try {
denoText = yield* readTextFile(new URL(`${dir}/deno.json`, repoRoot));
} catch {
continue;
}
const named = NamedSchema.safeParse(JSON.parse(denoText));
if (!named.success || !named.data.name.startsWith(SCOPE)) {
continue;
}
for (const manifest of ["deno.json", "package.json"]) {
const url = new URL(`${dir}/${manifest}`, repoRoot);
const text = yield* readTextFile(url);
const updated = text.replace(/"version": "[^"]+"/, `"version": "${version}"`);
if (updated === text) {
console.error(`no version field found in ${dir}/${manifest}`);
yield* exit(1);
return;
}
yield* writeTextFile(url, updated);
console.log(`bumped ${dir}/${manifest} -> ${version}`);
}
}

console.log(`done — commit, merge, then publish the draft release as v${version}`);
});
5 changes: 3 additions & 2 deletions specs/release-process-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ are the single source. The npm version derives from the tag, and both
workflows refuse a tag the manifests do not declare, so the two cannot
diverge.

To cut a release: bump the version in every manifest, merge to `main`, then
create the `vX.Y.Z` tag.
To cut a release: run `deno task bump <version>` (stamps every manifest),
merge to `main`, then publish the draft release — its tag follows the
manifests (§3).

## 3. Workflows

Expand Down
Loading