Skip to content

feat: add release prep workflow#72

Merged
ThomasK33 merged 6 commits into
mainfrom
release-vnvc
Apr 29, 2026
Merged

feat: add release prep workflow#72
ThomasK33 merged 6 commits into
mainfrom
release-vnvc

Conversation

@ThomasK33
Copy link
Copy Markdown
Member

Summary

  • add pinned release-it configuration for release-prep-only version updates
  • add release:prep and release:finalize scripts with release-specific git/package guardrails
  • document the Release Prep Workflow, Release Finalization Step, and Publish Pipeline boundary
  • add integration tests plus a dogfood proof bundle for a disposable-origin release flow

Behavior

  • release:prep requires --version <exact-semver> and --changelog local|ci, creates a local release/<version> branch, updates package version files, stages only allowlisted files, and creates one local commit.
  • release:finalize only works from clean, synced main, derives v${package.json.version}, creates an annotated tag, and pushes only that tag.
  • npm publishing, GitHub Release creation, checksum assets, and final release notes remain owned by the tag-triggered Release workflow.

Validation

  • Phase 0 disposable release-it spike proved version-file-only behavior with commit/tag/push/publish/release disabled.
  • node --check scripts/release-helpers.mjs
  • node --check scripts/release-prep.mjs
  • node --check scripts/release-finalize.mjs
  • npx vitest run --maxWorkers=1 test/integration/release-scripts.test.ts
  • npm run format:check
  • npm run lint
  • npm run typecheck
  • npm run test:unit
  • npm run test:integration
  • npm run test:e2e
  • npm run build
  • npm run smoke:install -- --skip-build
  • mise run workflow-lint
  • Post-rebase: npm run format:check
  • Post-rebase: npx vitest run --maxWorkers=1 test/integration/release-scripts.test.ts

Dogfood proof

  • dogfood/20260429-release-it-prep/transcript.txt
  • dogfood/20260429-release-it-prep/screenshot.png
  • dogfood/20260429-release-it-prep/release-it-prep.webm
  • dogfood/20260429-release-it-prep/release-it-prep.cast
  • dogfood/20260429-release-it-prep/index.md

📋 Implementation Plan

Plan: Introduce release-it for release prep only

Recommendation

Adopt release-it narrowly as the implementation detail behind a project-owned Release Prep Workflow, and do not replace the existing publish pipeline.

The first working slice should add:

npm run release:prep -- --version <exact-semver> --changelog local|ci [--verify]
npm run release:finalize [--verify]

Keep .github/workflows/release.yml as the authoritative tag-triggered Publish Pipeline for CI, deterministic tarball creation, checksum assets, GitHub Release creation, Communique release notes, npm OIDC publishing, and prerelease dist-tag handling.

Evidence and constraints

Repo facts verified by exploration:

  • docs/RELEASE-PROCESS.md currently documents manual release prep with npm version ... --no-git-tag-version, release branches, optional local Communique changelog generation, and manual annotated tag creation after merge.
  • .github/workflows/release.yml validates tag/package version alignment, checks tag ancestry against main, runs mise run ci, creates one verified tarball via scripts/pack-release.mjs, uploads tarball/checksum assets, generates Communique release notes, and publishes to npm through trusted publishing/OIDC.
  • .github/workflows/release-changelog.yml already supports a release PR that either includes a local CHANGELOG.md entry or lets CI generate one with communique generate "v<version>" --changelog --repo coder/agent-tty.
  • package.json has no release-it dependency today and defines existing quality gates (verify, pack:release, smoke:install, etc.).
  • communique.toml configures maintainer-focused release notes and changelog behavior.

Important invariants to preserve:

  • Release tags are v${package.json.version}.
  • Tags must point at commits already merged to main.
  • The release tarball is built once and reused for GitHub assets and npm publishing.
  • npm publishing stays in GitHub Actions via OIDC trusted publishing, not local tokens.
  • Prerelease versions such as 0.1.1-beta.0 continue to publish to the matching npm dist-tag (beta).
  • Release-prep tooling must not create final tags, push branches, create GitHub Releases, or publish npm packages.

Resolved design decisions

  • Use project terms:
    • Release Prep Workflow: local maintainer/agent process that prepares reviewable release changes.
    • Release Finalization Step: post-merge process that creates/pushes the release tag from clean, synced main.
    • Publish Pipeline: tag-triggered GitHub Actions release process.
  • release-it participates only in release prep.
  • release:finalize uses repo-specific guardrails plus plain git tag -a / git push, not release-it.
  • Release prep is non-interactive and scriptable by default.
  • Maintainers run project scripts, not raw release-it commands.
  • First iteration accepts exact --version only; no --increment / --preid yet.
  • First iteration is local-only: no branch push and no PR creation.
  • release:prep creates/switches to release/<version> from a clean, up-to-date main.
  • release:prep creates exactly one local commit with only allowlisted release-prep files.
  • Changelog mode is explicit:
    • --changelog local: run Communique locally and require a clean CHANGELOG.md update.
    • --changelog ci: skip local changelog and require the local commit to contain only version files.
  • release:prep --verify and release:finalize --verify may run full validation, but default scripts only run release-specific invariant checks.
  • Record the boundary in an ADR because it is a deliberate, non-obvious scope decision: adding release-it while not letting it tag/publish.

Implementation plan

Phase 0 — Technical spike: prove release-it is useful here

Before implementing wrappers, verify the pinned release-it version can reliably operate as a version-file-only engine for this repo:

  • exact version input, non-interactive/CI mode,
  • updates package.json and package-lock.json correctly,
  • does not commit,
  • does not tag,
  • does not push,
  • does not publish to npm,
  • does not create GitHub/GitLab releases,
  • does not generate changelog side effects.

Run this spike in a disposable clone/worktree, or reset all version-file changes afterward, and verify the spike does not trigger unintended lifecycle hooks or release side effects.

If release-it cannot do this cleanly, stop and reconsider the implementation boundary before proceeding. The fallback design would keep the same project-owned release:prep / release:finalize interface but use a repo-owned wrapper around npm version <version> --no-git-tag-version for the version-file update.

Phase 1 — Documentation/domain records

  1. Update CONTEXT.md with release workflow language if not already present:
    • Release Prep Workflow
    • Release Finalization Step
    • Publish Pipeline
    • Relationships: prep must not publish tags; finalization follows merged prep; publish starts from the tag.
  2. Add docs/adr/0001-use-release-it-only-for-release-prep.md using the project ADR style.
    • Record that release-it is pinned and prep-only.
    • Record that finalization uses repo-specific checks and plain git.
    • Record that the existing publish pipeline remains authoritative.
  3. Update docs/RELEASE-PROCESS.md to make the new scripts the primary path while retaining manual commands as fallback/troubleshooting.

Phase 2 — Add pinned release-it prep tooling

  1. Add release-it as a pinned devDependency and update package-lock.json.
  2. Add a prep-only release-it config after verifying the exact supported config file name/shape for the installed version.
    • Prefer an explicit repo config such as .release-it.cjs if supported and useful for comments; otherwise use .release-it.json.
    • Disable dangerous actions:
      • no git tag creation,
      • no git push,
      • no npm publish,
      • no GitHub Release creation,
      • no release-it-owned changelog/publish side effects.
    • Allow release-it to perform only the package version update needed by release prep.
  3. Add package scripts:
{
  "release:prep": "node ./scripts/release-prep.mjs",
  "release:finalize": "node ./scripts/release-finalize.mjs"
}

Phase 3 — Implement scripts/release-prep.mjs

Required behavior:

  1. Parse non-interactive args:
    • --version <exact-semver> is required.
    • --changelog local|ci is required.
    • --verify is optional.
  2. Fail fast with assertions / explicit errors when assumptions are false:
    • running in the repo root,
    • current branch is main,
    • working tree is clean,
    • origin/main exists and local HEAD equals origin/main,
    • target version is accepted by npm/release-it semver handling,
    • target version is not equal to the current package version,
    • target version is greater than the current package version according to npm/semver semantics,
    • target version does not contain build metadata (+...) in the first iteration,
    • git commit identity is configured (user.name and user.email) before any changes are made,
    • local release/<version> does not exist,
    • remote origin/release/<version> does not exist.
  3. Create/switch to release/<version>.
  4. Invoke pinned release-it through the project dependency/script path in CI/non-interactive mode so it updates package version files without committing, tagging, pushing, publishing, or creating GitHub releases.
  5. Assert package.json.version equals the requested version.
  6. Assert package-lock.json top-level version and packages[""].version also match when present.
  7. For --changelog local:
    • require ANTHROPIC_API_KEY or OPENAI_API_KEY.
    • require COMMUNIQUE_MODEL when using only OPENAI_API_KEY, matching current workflow behavior.
    • require communique to be available through the expected toolchain/PATH.
    • require GitHub API auth for Communique, either GITHUB_TOKEN or a clearly verified authenticated gh session if Communique supports it locally.
    • on missing prerequisites, fail with the exact fallback command using --changelog ci.
    • run communique generate "v${version}" --changelog --repo coder/agent-tty.
    • require CHANGELOG.md to change.
    • fail if any unexpected file changes.
  8. For --changelog ci:
    • do not run Communique.
    • fail if CHANGELOG.md is changed.
    • allow only version files to change.
  9. Stage only the allowlisted files for the selected changelog mode.
  10. Create exactly one commit:
chore(release): <version>
  1. If --verify is supplied, run mise run ci when mise is available; otherwise run npm run verify.
  2. After any --verify run, assert the working tree is clean again before reporting success.
  3. Print exact next commands for the maintainer:
git push -u origin release/<version>
gh pr create --base main --head release/<version> --title "chore(release): <version>"

Defensive programming notes:

  • Use node:assert/strict for impossible internal states.
  • Use clear user-facing errors for expected invalid inputs or dirty git state.
  • Use execFile/spawn with argv arrays rather than shell command strings for git, release-it, npm, mise, and Communique calls.
  • Compare changed files with an explicit allowlist before staging.
  • Do not use broad git add ..

Phase 4 — Implement scripts/release-finalize.mjs

Required behavior:

  1. Parse args:
    • --verify optional.
  2. Fail fast with assertions / explicit errors:
    • running in repo root,
    • current branch is main,
    • working tree is clean,
    • fetch origin main succeeds,
    • local HEAD equals origin/main,
    • package.json.version is non-empty and valid enough to form a tag,
    • package-lock.json top-level version and packages[""].version match package version when present,
    • package version does not contain build metadata (+...) in the first iteration,
    • git tag identity is configured (user.name and user.email),
    • release tag is exactly v${version},
    • local tag does not already exist,
    • remote tag does not already exist.
  3. If --verify is supplied, run mise run ci when available; otherwise run npm run verify.
  4. After any --verify run, assert the working tree is still clean before creating a tag.
  5. Create an annotated tag with plain git:
git tag -a "v${version}" -m "v${version}"
  1. Push only that tag:
git push origin "v${version}"
  1. Print the expected GitHub Actions follow-up:
    • release workflow should trigger from the pushed tag.
    • maintainer should watch the release workflow and verify npm/GitHub release assets using existing release-process docs.

Phase 5 — Tests

Before coding tests, inspect existing script/integration test style and keep changes minimal.

Recommended automated coverage:

  1. Unit-test reusable helpers if the scripts expose or share small functions for:
    • arg parsing,
    • changed-file allowlist checks,
    • release branch/tag naming,
    • package/package-lock version consistency.
  2. Add integration-style tests with temporary git repos where feasible:
    • release:prep --changelog ci from clean synced main creates release/<version>, updates package files, and creates exactly one commit.
    • release:prep --changelog ci fails if CHANGELOG.md is dirty/changed.
    • release:prep --changelog local fails clearly when credentials are missing.
    • release:prep refuses dirty trees, non-main branches, stale main, existing local branch, and existing remote branch.
    • release:finalize refuses dirty trees, non-main branches, stale main, existing local tag, and existing remote tag.
    • release:finalize succeeds in a disposable repo with a bare origin and pushes exactly v<version>.
  3. If invoking real release-it in tests is too slow or brittle, test wrapper safety logic with a narrow fake/stub boundary and cover real release-it behavior in dogfooding.

Phase 6 — Documentation updates

Update docs/RELEASE-PROCESS.md:

  1. Replace the primary manual npm version ... --no-git-tag-version flow with:
npm run release:prep -- --version <version> --changelog local
  1. Document CI fallback:
npm run release:prep -- --version <version> --changelog ci
  1. Document post-prep manual remote steps:
git push -u origin release/<version>
gh pr create --base main --head release/<version> --title "chore(release): <version>"
  1. Replace manual tag creation as the primary path with:
npm run release:finalize
  1. Keep manual fallback commands in a clearly marked troubleshooting/fallback section.
  2. Make clear that .github/workflows/release.yml still owns packaging, GitHub Release creation, checksum assets, and npm publishing.

Phase 7 — Failure and recovery documentation

Add a concise recovery section to docs/RELEASE-PROCESS.md covering:

  • If release:prep fails after creating release/<version>, inspect the branch, reset/delete it if no wanted work remains, and rerun from clean synced main.
  • If release:finalize pushes a tag but the release workflow fails before any GitHub Release or npm publish, fix the underlying issue on main, delete/recreate the failed tag only if maintainers explicitly decide it is safe, and document the action.
  • If npm publish succeeds, never reuse the same version even if later GitHub Release asset creation or verification fails; repair forward with a new version or complete missing release assets manually according to maintainer policy.
  • If GitHub Release exists but npm publish fails, treat the release state as partial and follow the existing release-process verification/remediation steps before deciding whether to delete assets/tags.

Acceptance criteria

  • A Phase 0 spike proves release-it can update version files without commit/tag/push/publish/release side effects, or the implementation stops to reconsider the version-update engine.
  • release-it is pinned in devDependencies and lockfile changes are committed.
  • Prep-only release-it config cannot create tags, push, publish to npm, or create GitHub Releases.
  • npm run release:prep -- --version <version> --changelog ci creates a local release/<version> branch and one commit touching only package.json / package-lock.json.
  • npm run release:prep -- --version <version> --changelog local requires Communique credentials and commits CHANGELOG.md only when Communique changes it cleanly.
  • npm run release:finalize only works from clean, synced main, creates an annotated v${package.json.version} tag, and pushes only that tag.
  • Existing .github/workflows/release.yml publish behavior is not replaced or weakened.
  • Docs clearly explain prep, finalization, publish boundaries, local changelog vs CI changelog, and manual fallback.
  • Tests cover safety checks and success paths for prep/finalize wrappers, or any untestable pieces are explicitly covered by dogfood proof.

Validation plan

Run the narrowest useful checks during implementation, then broaden before handoff:

npm run format:check
npm run lint
npm run typecheck
npm run test:unit
npm run test:integration

If script integration tests touch full CLI/build behavior or if release docs/tooling changes are broad, run:

mise run ci

Fallback if mise is unavailable:

npm run verify

Also run targeted dry/safe checks in a disposable git repo, not against the real release remote.

Dogfooding / proof bundle

Because this is CLI release automation, dogfooding should happen in a disposable clone with a disposable bare origin, never against the real repository remote.

Suggested dogfood environment:

Dogfood versions must be greater than the current package.json version because release:prep rejects same or lower versions.

  1. Build the local CLI if needed:
npm run build
  1. Create a disposable repo clone and bare origin.
  2. In that disposable repo, run:
npm run release:prep -- --version 999.0.0-dogfood.0 --changelog ci
  1. Verify:
    • current branch is release/999.0.0-dogfood.0,
    • exactly one commit was created,
    • changed files are only allowed version files,
    • printed push/PR commands are correct.
  2. Merge/simulate the release commit onto main in the disposable repo and run:
npm run release:finalize
  1. Verify the disposable bare origin now has exactly refs/tags/v999.0.0-dogfood.0.
  2. If local Communique credentials are available, also dogfood:
npm run release:prep -- --version 999.0.0-dogfood.1 --changelog local

If credentials are unavailable, capture the intentional failure message for missing credentials and rely on automated/stub tests for the clean local changelog path.

Reviewer-facing proof should include:

  • terminal transcript of the disposable release-prep and release-finalize flow,
  • git log --oneline --decorate --graph --all before/after,
  • git diff --name-only HEAD^..HEAD,
  • git ls-remote --tags origin,
  • at least one agent-tty screenshot of the terminal state,
  • a WebM recording exported from agent-tty showing the happy-path dogfood flow.

Use an isolated AGENT_TTY_HOME for dogfood captures so no real ~/.agent-tty state is mutated.

Risks and mitigations

  • Risk: release-it accidentally tags or publishes. Mitigate with prep-only config, wrapper scripts, tests, and docs that never call raw release-it as the maintainer interface.
  • Risk: local changelog generation introduces nondeterminism. Mitigate with explicit --changelog local|ci, hard failure for dirty/unexpected changes, and CI fallback.
  • Risk: finalization tags the wrong commit. Mitigate with clean/synced-main checks and local/remote tag nonexistence checks before plain-git tagging.
  • Risk: release script tests become heavy. Mitigate by extracting small helpers, using temp git repos, and reserving full real-tool proof for dogfooding.
  • Risk: dependency/tooling churn. Mitigate by pinning release-it, reviewing lockfile changes, and running full verification before merge.

Explicit non-goals for the first slice

  • No replacement of .github/workflows/release.yml.
  • No local npm publish.
  • No release-it GitHub Release creation.
  • No release-it final tag creation.
  • No branch push or PR creation from release:prep.
  • No version increment/preid support yet.
  • No automatic promotion from prerelease to stable.

Generated with mux • Model: openai:gpt-5.5 • Thinking: xhigh

@ThomasK33
Copy link
Copy Markdown
Member Author

/coder-agents-review

Copy link
Copy Markdown

@coder-agents-review coder-agents-review Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First-pass review (Netero). This is a mechanical first-pass only; the full review panel has not yet reviewed this PR.

The release-prep/finalize scripts are well-structured: clean separation of helpers, explicit fail-fast assertions, defensive allowlist staging, and a clear boundary between prep tooling and the publish pipeline. The dogfood proof is thorough.

1 P2, 2 P3, 1 Note. The P2 is a test coverage gap in the safety-critical guardrails; the P3s are dead code. Addressing these before the panel review will let the panel focus on design and architecture rather than mechanical issues.

"Code:test ratio is 979:265 (3.7:1, under 5:1), so the gap is in scenario breadth, not volume." (Netero)

🤖 This review was automatically generated with Coder Agents.

Comment thread test/integration/release-scripts.test.ts
Comment thread scripts/release-prep.mjs
Comment thread scripts/release-finalize.mjs Outdated
Comment thread scripts/release-helpers.mjs
@ThomasK33
Copy link
Copy Markdown
Member Author

/coder-agents-review

Copy link
Copy Markdown

@coder-agents-review coder-agents-review Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Panel review (17 reviewers). All R1 findings verified as addressed in 56dc625.

The wrapper scripts are the real value here: branch management, fail-fast assertions, allowlisted staging, clean-tree enforcement, synced-main checks, and tag safety. The design boundary between local prep and CI publishing is well-drawn. The dogfood proof is thorough and reproducible. The test suite is comprehensive after the R1 fixes.

1 P2, 8 P3, 4 P4, 4 Nit. The P2 is a design question about whether release-it earns its 143-package dependency cost. Several P3s are convergent findings from 3+ reviewers.

Interaction note: DEREM-5 (release-it dependency), DEREM-10 (hook injection), and DEREM-19 (version validation at runReleaseIt boundary) are linked. Removing release-it would eliminate DEREM-10 and DEREM-19 and reduce 143 transitive packages.

Additional P4s/Notes not posted as inline comments: DEREM-15 (no spawnSync timeout for agent automation), DEREM-17 (run/assertString/formatCommand duplication across scripts, follows pre-existing codebase pattern), DEREM-19 (runReleaseIt doesn't validate version at function boundary), DEREM-22-24 (naming/constant nits).

"The problem was disconnected manual steps. The solution is the composition scripts. Release-it is a passenger." (Pariston)

🤖 This review was automatically generated with Coder Agents.

Comment thread package.json
Comment thread scripts/release-prep.mjs
Comment thread scripts/release-helpers.mjs
Comment thread scripts/release-helpers.mjs
Comment thread test/integration/release-scripts.test.ts
Comment thread test/integration/release-scripts.test.ts
Comment thread CONTEXT.md Outdated
Comment thread test/integration/release-scripts.test.ts
Comment thread docs/RELEASE-PROCESS.md Outdated
Comment thread scripts/release-helpers.mjs Outdated
@ThomasK33
Copy link
Copy Markdown
Member Author

/coder-agents-review

Copy link
Copy Markdown

@coder-agents-review coder-agents-review Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review (4 reviewers: Bisky, Mafuuu, Kite, Chopper). All 14 R2 findings verified as addressed in 187ba83.

The wrapper scripts are solid: 21 integration tests against real temp repos, every guardrail exercised, fail-fast assertions with specific error messages, defensive allowlist staging, recovery docs for every identified failure mode. The ADR honestly documents the release-it tradeoff including its own exit strategy. Clean decomposition across helpers, prep, and finalize.

1 P3, 2 P4. All are test gaps in an already-strong test suite; no correctness issues remain. The code works correctly across both scripts and all documented failure modes.

"The decomposition between release-helpers, release-prep, and release-finalize is clean. Each module has a single job, the assertion functions compose well, and the test suite covers both success and failure for each guardrail." (Kite)

🤖 This review was automatically generated with Coder Agents.

Comment thread test/integration/release-scripts.test.ts
Comment thread test/integration/release-scripts.test.ts
Comment thread test/integration/release-scripts.test.ts
@ThomasK33
Copy link
Copy Markdown
Member Author

/coder-agents-review

Copy link
Copy Markdown

@coder-agents-review coder-agents-review Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review (3 reviewers: Bisky, Mafuuu, Meruem). All 3 R3 findings verified as addressed in 4be9833.

Twenty-three integration tests against real temp repos. Every guardrail in both scripts has coverage. The verify-failure-blocks-tag safety property is now proven. Git identity rejection is tested with proper env isolation. Annotated vs lightweight tag distinction is verified. The test suite is thorough and genuine.

1 P4 (finalize-side git identity test gap). Meruem notes the shared function contract covers both call sites. The risk of this gap is minimal.

This is the fourth round. 27 findings raised across 4 rounds; 24 fixed, 3 dropped. The PR improved meaningfully at each round. Clean approve.

"Twenty-three tests, all genuine. Every guardrail in release-prep.mjs has coverage. Every guardrail in release-finalize.mjs has coverage except the one above." (Bisky)

🤖 This review was automatically generated with Coder Agents.

Comment thread test/integration/release-scripts.test.ts
@ThomasK33
Copy link
Copy Markdown
Member Author

/coder-agents-review

Copy link
Copy Markdown

@coder-agents-review coder-agents-review Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Final re-review (3 reviewers: Bisky, Mafuuu, Kite). DEREM-28 verified as addressed in 9323634.

29 findings across 5 rounds. 25 author-fixed, 3 dropped, 1 open P4. No correctness issues. Every guardrail in both scripts has test coverage. The test suite is genuine and thorough: 23 integration tests against real temp repos, real git operations, real error assertions.

The remaining P4 is a final polish item: finalize's parseSemver build-metadata guard has no dedicated test (the same function is proven correct through the prep path). The PR is ready to merge.

"Twenty-three tests, each with its own temporary git repo, bare remote, real commits and pushes. Every guard test checks both the error message AND the absence of side effects." (Bisky)

🤖 This review was automatically generated with Coder Agents.

Comment thread test/integration/release-scripts.test.ts
@ThomasK33
Copy link
Copy Markdown
Member Author

/coder-agents-review

Copy link
Copy Markdown

@coder-agents-review coder-agents-review Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean approve (2 reviewers: Bisky, Mafuuu). DEREM-29 verified as addressed in b95d6f9. Zero open findings.

29 findings across 6 rounds. 26 author-fixed, 3 dropped. 0 remaining. Every finding addressed, every fix verified. CI green (pending completion). The review is converged.

"Twenty-five tests, each with its own disposable git repo, real file I/O, real git commands. No mocks in sight. Every guardrail in both release-prep.mjs and release-finalize.mjs has a test that triggers the error, checks the message, and confirms no side effects leaked." (Bisky)

🤖 This review was automatically generated with Coder Agents.

@ThomasK33 ThomasK33 merged commit 2061c91 into main Apr 29, 2026
38 of 46 checks passed
@ThomasK33 ThomasK33 deleted the release-vnvc branch April 29, 2026 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant