Skip to content

Commit 7d2bb96

Browse files
author
Roman Melnikov
committed
feat(dev-workflow): PR E — real release pipeline (all defineFunction)
Swaps 4 noop nodes in release.ts for defineFunction implementations: - bump: semver bump via package.json rewrite (patch/minor/major from labels) - changelog: append dated section to CHANGELOG.md at repo root - publish: npm publish in PUBLISH_ORDER (critical path); respects dryRun via plan:true mode that prints instead of executes - cleanup: git tag the release commit (no auto-push — operator pushes) No LLM agents — release mechanics are deterministic. Bumps @ageflow/dev-workflow 0.0.13 → 0.0.14 (private).
1 parent 91b5c80 commit 7d2bb96

4 files changed

Lines changed: 412 additions & 37 deletions

File tree

bun.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/dev-workflow/__tests__/pipelines.test.ts

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
// Smoke tests for the pipeline factories — confirms that `feature`, `bugfix`,
2-
// and `docs` build valid DAGs at definition time with the role prompts
3-
// loaded from disk.
2+
// `docs`, and `release` build valid DAGs at definition time.
43

54
import { describe, expect, it } from "vitest";
65
import { createBugfixPipeline } from "../pipelines/bugfix.js";
76
import { createDocsPipeline } from "../pipelines/docs.js";
87
import { createFeaturePipeline } from "../pipelines/feature.js";
8+
import { createReleasePipeline, semverBump } from "../pipelines/release.js";
99
import type { WorkflowInput } from "../shared/types.js";
1010

1111
const FAKE_INPUT: WorkflowInput = {
@@ -241,3 +241,73 @@ describe("docs pipeline", () => {
241241
expect(publish.dependsOn).toContain("review");
242242
});
243243
});
244+
245+
describe("release pipeline", () => {
246+
it("builds a workflow named release-pipeline with 4 tasks", () => {
247+
const wf = createReleasePipeline(FAKE_INPUT);
248+
expect(wf.name).toBe("release-pipeline");
249+
const keys = Object.keys(wf.tasks).sort();
250+
expect(keys).toEqual(["bump", "changelog", "cleanup", "publish"]);
251+
});
252+
253+
it("all 4 tasks are defineFunction (fn), not agent", () => {
254+
const wf = createReleasePipeline(FAKE_INPUT);
255+
for (const key of ["bump", "changelog", "publish", "cleanup"] as const) {
256+
const task = wf.tasks[key] as { agent?: unknown; fn?: unknown };
257+
expect(task.fn).toBeDefined();
258+
expect(task.agent).toBeUndefined();
259+
}
260+
});
261+
262+
it("bump has no dependsOn", () => {
263+
const wf = createReleasePipeline(FAKE_INPUT);
264+
const bump = wf.tasks.bump as { dependsOn?: readonly string[] };
265+
expect(bump.dependsOn).toBeUndefined();
266+
});
267+
268+
it("changelog dependsOn bump", () => {
269+
const wf = createReleasePipeline(FAKE_INPUT);
270+
const changelog = wf.tasks.changelog as { dependsOn?: readonly string[] };
271+
expect(changelog.dependsOn).toContain("bump");
272+
});
273+
274+
it("publish dependsOn changelog and bump", () => {
275+
const wf = createReleasePipeline(FAKE_INPUT);
276+
const publish = wf.tasks.publish as { dependsOn?: readonly string[] };
277+
expect(publish.dependsOn).toContain("changelog");
278+
expect(publish.dependsOn).toContain("bump");
279+
});
280+
281+
it("cleanup dependsOn publish and bump", () => {
282+
const wf = createReleasePipeline(FAKE_INPUT);
283+
const cleanup = wf.tasks.cleanup as { dependsOn?: readonly string[] };
284+
expect(cleanup.dependsOn).toContain("publish");
285+
expect(cleanup.dependsOn).toContain("bump");
286+
});
287+
});
288+
289+
describe("semverBump", () => {
290+
it("patch: increments patch, leaves major/minor", () => {
291+
expect(semverBump("1.2.3", "patch")).toBe("1.2.4");
292+
expect(semverBump("0.0.0", "patch")).toBe("0.0.1");
293+
expect(semverBump("1.0.0", "patch")).toBe("1.0.1");
294+
});
295+
296+
it("minor: increments minor, resets patch", () => {
297+
expect(semverBump("1.2.3", "minor")).toBe("1.3.0");
298+
expect(semverBump("0.5.9", "minor")).toBe("0.6.0");
299+
expect(semverBump("2.0.0", "minor")).toBe("2.1.0");
300+
});
301+
302+
it("major: increments major, resets minor + patch", () => {
303+
expect(semverBump("1.2.3", "major")).toBe("2.0.0");
304+
expect(semverBump("0.9.9", "major")).toBe("1.0.0");
305+
expect(semverBump("3.4.5", "major")).toBe("4.0.0");
306+
});
307+
308+
it("throws on invalid semver string", () => {
309+
expect(() => semverBump("not-a-version", "patch")).toThrow(
310+
"invalid semver",
311+
);
312+
});
313+
});

packages/dev-workflow/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ageflow/dev-workflow",
3-
"version": "0.0.13",
3+
"version": "0.0.14",
44
"private": true,
55
"type": "module",
66
"scripts": {

0 commit comments

Comments
 (0)