Skip to content

publish --input drops per-package tags and baseline tags from the version output #675

Closed

Description

@goosewobbler

Problem

The standalone publish command validates its input with a Zod VersionOutputSchema (packages/publish/src/stages/input.ts). Zod's z.object strips keys it doesn't declare, and the schema declares only part of VersionOutput:

  • updates[]: packageName, newVersion, filePath
  • top level: dryRun, updates, changelogs, commitMessage, tags

Everything else releasekit version writes is silently removed before the pipeline sees it. Two of the dropped fields change what publish does:

  • updates[].tag. runPipeline switches to per-package mode only when an update carries a tag (pipeline/index.ts:66, perPackageMode = input.updates.some((u) => !!u.tag)), and that mode pushes each package's own tag (:149-150). With the tags stripped, publish --input never uses per-package mode.
  • baselineTags. The git-commit stage creates and pushes [...input.tags, ...(input.baselineTags ?? [])] (stages/git-commit.ts:61, also pipeline/index.ts:84). With the field stripped, baseline tags from baselineTagTemplate are never created, so later version and changelog runs can't find the previous release on the source branch once its consumer tag has been moved. This repo's own config sets baselineTagTemplate.

The other dropped fields (strategy, sharedEntries, isRoot, group, previousVersion, role, channel, …) aren't read by publish today, but they disappear the same way.

Who's affected

Only the standalone path: releasekit publish --input <file> or stdin, which is the version → notes → publish chain docs/cli.md documents (#616 makes that chain the documented way to run the stages separately). parseInput has no other caller. releasekit release and standing-pr publish hand the version output to runPipeline in memory (packages/release/src/steps.ts), so they keep these fields.

Nothing errors: the publish succeeds with the wrong tags.

Proposal

  • Declare the fields publish reads (updates[].tag, baselineTags) and stop stripping the rest: .passthrough() (or z.looseObject) on both objects, so new optional VersionOutput fields survive without a schema change. Per the AGENTS.md invariant, new VersionOutput fields are optional and consumers must tolerate their absence, so passthrough matches the contract.
  • A test that round-trips a real releasekit version output through parseInput and checks the result equals the input, so the schema can't fall behind the type again.
  • Settle this before notes: validate version-output input instead of casting it #620, which plans to reuse this schema in notes and would spread the same loss there.

Found while reviewing #616.

Activity

  1. added this to the 0.42.0 milestone on Oct 22, 2026
  2. added a commit that references this issue on Oct 22, 2026
    30ad59e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    type:bugSomething isn't working

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions