On June 29, eight separate projects across the portfolio were tagged v0.0.1.
Seen from the outside, this looks like a flurry of product launches. In reality,
it is a single infrastructure event: the shared automated release pipeline
finally came online across the entire codebase.
Up until this window, tagging was manual, ad hoc, or non-existent for most repositories. Releases were cut by hand when someone remembered to do so. The Phase 3 release initiative changed that by standardizing a reusable auto-release workflow across the portfolio.
The operational cadence across each repository followed an identical pattern.
First, inline CI job definitions were replaced with centralized composite
actions (node-build-test, shared-workflows). Second, existing VERSION
files were normalized down to 0.0.0. This intentional reset ensured that the
first automated pipeline run had a deterministic starting anchor rather than
inheriting unverified legacy numbers. Once merged, the release bots fired in
sequence, generating v0.0.1 tags and package publishes across
ADP-Orchestration-UI, telemetry-api, ai-memory-coherence, AIService,
DnDCompanion, IDEExtension, MCPServer, and repo-intel.
The rollout was not entirely uneventful. In DnDCompanion.Api, the schema
publish workflow ran into an immediate wall (#41). The runner container,
running Alpine Linux with musl libc, hung dead during npm publish due to an
unhandled fcntl64 file-locking mismatch. Moving the schema publish step into
a standard glibc Node container resolved the hang. Furthermore, because a
failed release attempt can leave behind intermediate build state, PR #42 added
an idempotency guard to the publish step so subsequent runner retries would not
fail when an artifact or tag had already registered upstream.
Simultaneously, substantive tooling updates landed along with the new pipelines.
MCPServer brought the Brave web search tool into its catalog (#23), enabling
agentic search workflows, while dnd-companion-web aligned its GraphQL codegen
pipeline with the newly published schemas.
Having version zero established everywhere meant the portfolio finally had a coherent baseline. Every downstream consumer could finally declare dependencies against verifiable semantic versions rather than floating git branches.
Lessons learned
- Anchor the baseline version file before turning on release automation.
Deploying an auto-release workflow into a repository with an ambiguous or
drifted
VERSIONfile results in unpredictable tags. Explicitly pinning0.0.0as the baseline commit guarantees the automation starts cleanly atv0.0.1. - Avoid Alpine or musl-based runner environments for npm package publishing.
Subtle libc differences—such as
fcntl64file locking under musl—can cause npm CLI commands to deadlock silently inside containerized runners. Stick to standard glibc Node base images for publishing steps. - Guard release publish steps with idempotency checks. If a release workflow fails halfway through its jobs (such as after tagging git but before uploading an artifact), re-running the job must tolerate already-existing tags and package versions without erroring out.