Publishing Workflow#
APX implements a tag-in-app → PR-to-canonical publishing workflow that preserves team autonomy while ensuring governance and consistency. Generated code uses canonical import paths throughout the development lifecycle, enabling seamless transitions from local overlays to published modules.
Overview#
The publishing workflow connects app repo development to canonical repo releases:
apx lint
apx breaking
apx version suggest
git tag proto/domain/api/v1/v1.2.3
git push --follow-tags
apx publish \
--canonical-repo=...
Validates changes
Creates subdirectory tag
Publishes packages
Publishing Strategies#
APX uses git subtree for publishing:
Git Subtree Publishing#
Preserves commit history in canonical repo
Maintains authorship and timestamps for full traceability
Better for debugging and understanding API evolution
Transparent process with complete audit trail
Industry standard git tooling
Subdirectory Tagging#
APX uses subdirectory tags to version individual APIs:
# App repo tags (triggers CI)
proto/payments/ledger/v1/v1.2.3
proto/users/profile/v1/v1.0.1
# Canonical repo tags (created by CI)
proto/payments/ledger/v1.2.3
proto/users/profile/v1.0.1
Tag Format Rules#
Schema format prefix:
proto/,openapi/,avro/, etc.Domain organization:
domain/service/groupingVersion directory:
/v1/,/v2/for major versionsSemantic version:
/v1.2.3following semver
Validation Pipeline#
Every publish goes through comprehensive validation:
Schema linting
Breaking change detection
Policy compliance
Version suggestion validation
Re-validate all changes
Verify SemVer compliance
Check CODEOWNERS approval
Create official tags
Proto: buf lint, buf breaking
OpenAPI: spectral, oasdiff
Avro: compatibility rules
JSON Schema: diff analysis
Ban service annotations (gorm, etc.)
Approved generators only
Breaking change justification
Security vulnerability scans
Example Publishing Flow#
1. Prepare for Release#
# Validate locally
apx fetch # ensure latest toolchain
apx lint # check schema quality
apx breaking # verify compatibility
apx version suggest # get recommended version bump
# Expected output:
# Suggested version: v1.2.3 (PATCH - backwards compatible bug fixes)
2. Tag in App Repository#
# Create and push tag (matches suggested version)
git tag proto/payments/ledger/v1/v1.2.3
git push --follow-tags
# This triggers app CI to run apx publish
3. App CI Automation#
App CI runs the publish command:
apx publish \
--module-path=internal/apis/proto/payments/ledger/v1 \
--canonical-repo=github.com/myorg/apis \
--pr-title="Release payments/ledger v1.2.3" \
--pr-body="Auto-generated release from app repo"
4. Canonical Repository PR#
The PR contains:
Schema files in correct canonical structure
go.mod with proper module path (if not present locally)
CHANGELOG.md with breaking changes summary
Validation reports from lint/breaking checks
5. Canonical CI Processing#
On PR merge, canonical CI:
Re-validates all changes
Verifies SemVer matches content
Creates subdirectory tag:
proto/payments/ledger/v1.2.3Publishes packages (Maven, wheels, OCI, etc.)
Updates catalog for discovery
Error Handling#
Common publishing errors and solutions:
Version Mismatch#
Error: Tagged version v1.2.3 doesn't match suggested v1.3.0
Solution: Update tag to match breaking changes, or justify version choice
Breaking Changes Without Major Bump#
Error: Breaking changes detected but only minor version bump requested
Solution: Use major version bump or provide breaking change waiver
Policy Violations#
Error: Detected banned annotation: (gorm.column)
Solution: Remove service-specific annotations from shared schemas
Merge Conflicts#
Error: Cannot merge subtree - conflicts in canonical repo
Solution: Resolve conflicts manually by updating your branch or coordinating with the canonical repo maintainers
Best Practices#
Pre-Publish Checklist#
Run full validation locally
Coordinate with downstream consumers
Document breaking changes
Test generated code
Verify CODEOWNERS approval
Tagging Best Practices#
Tag after merge to main branch
Use annotated tags with release notes
Follow semver strictly
Coordinate major versions across teams
Emergency Releases#
For urgent fixes:
Create hotfix branch from last release
Apply minimal changes
Tag patch version
Expedite canonical CI if needed