auto-release
auto-release is a specialized release skill.
Its responsibility is:
Git history
↓
Find latest release
↓
Analyze commits
↓
Determine release level
↓
Calculate version
↓
Generate/update CHANGELOG.md
↓
Create Git tag
↓
Return release result to symphony-orchestrator
It must not directly invoke:
commit-async;tests-async;readme-async;symphony-orchestrator.
The orchestrator decides what happens next.
Conventional Commits
Use Conventional Commits to determine the release level.
PATCH
A fix commit triggers a patch release:
fix: correct authentication error
Example:
v1.2.3 → v1.2.4
MINOR
A feat commit triggers a minor release:
feat: add OAuth authentication
Example:
v1.2.3 → v1.3.0
MAJOR
A breaking change triggers a major release.
Examples:
feat!: redesign authentication API
or:
feat(api): redesign authentication API
BREAKING CHANGE: the previous authentication endpoint has been removed.
Example:
v1.2.3 → v2.0.0
Release Priority
When multiple commit types exist, use the highest required level:
MAJOR > MINOR > PATCH
Example:
fix: correct login
feat: add OAuth
Result:
MINOR
If:
fix: correct login
feat: add OAuth
feat!: replace authentication API
Result:
MAJOR
Release Detection
Find the latest valid semantic version tag.
Supported format:
vMAJOR.MINOR.PATCH
Examples:
v1.0.0
v1.2.3
v10.4.21
Ignore unrelated tags.
If no valid release tag exists:
v0.0.0
must be used as the baseline.
The first release should therefore become:
v0.0.1
for a patch change or:
v0.1.0
for a feature.
A breaking change from v0.0.0 should produce:
v1.0.0
Commit Analysis
Use Git to retrieve commits since the latest release.
For example:
git log <last-tag>..HEAD
Use structured output when possible.
Analyze:
- commit type;
- scope;
- subject;
- body;
- breaking changes;
- commit hash.
Do not invent release information.
If there are no commits since the latest release:
NO_RELEASE
must be returned.
Changelog
Generate or update:
CHANGELOG.md
Use a readable Markdown structure.
Example:
# Changelog
## v1.4.0
### Features
- add OAuth authentication
- add user session management
### Bug Fixes
- fix login redirect
### Breaking Changes
- replace the authentication API
Use the release version and current date.
Group commits into:
Features
Bug Fixes
Performance
Documentation
Refactoring
Tests
Build
CI
Chores
Breaking Changes
Only include relevant sections.
The changelog must preserve previous releases.
Never overwrite existing historical release information.
Version Calculation
Implement semantic version calculation in Python.
Given:
v1.4.2
PATCH:
v1.4.3
MINOR:
v1.5.0
MAJOR:
v2.0.0
Do not use an external semantic-version package.
Use Python's standard library only.
Tag Creation
After the release information has been determined and the changelog has been updated, create an annotated Git tag:
git tag -a vX.Y.Z -m "Release vX.Y.Z"
Do not overwrite an existing tag.
Before creating the tag, verify:
git rev-parse "vX.Y.Z"
If the tag already exists:
RELEASE_FAILED
must be returned.
Never delete or replace an existing tag automatically.
Git Push
auto-release must not automatically push the tag unless Symphony explicitly requests it.
The default behavior is:
release created locally
↓
return result
↓
symphony-orchestrator decides whether/when to push
Never execute:
git push --force
Never push tags silently.
If Symphony explicitly provides permission to push the release tag, use:
git push origin vX.Y.Z
Otherwise, leave the tag local.
Working Tree Safety
Before modifying CHANGELOG.md, inspect:
git status --short
Do not silently overwrite unrelated user changes.
If CHANGELOG.md already contains uncommitted modifications unrelated to the release:
RELEASE_BLOCKED
must be returned.
Explain that the working tree must be resolved before continuing.
Never use:
git reset --hard
git checkout -- .
git clean -fd
to resolve conflicts.
Commit Responsibility
auto-release must not silently create a commit unless Symphony explicitly requests that behavior.
The preferred Symphony workflow is:
commit-async
↓
tests-async
↓
git push
↓
auto-release
↓
CHANGELOG + tag
↓
readme-async
If the changelog must be committed, return:
CHANGELOG_UPDATED
to symphony-orchestrator.
The orchestrator can then use commit-async to create the documentation commit according to the normal validation rules.
Do not bypass commit-async's approval mechanism.
Symphony Contract
auto-release must return a clear machine-readable result to the orchestrator.
Possible states:
NO_RELEASE
RELEASE_PROPOSED
RELEASE_CREATED
RELEASE_BLOCKED
RELEASE_FAILED
CHANGELOG_UPDATED
TAG_CREATED
A successful release should expose:
release_version
release_level
previous_version
tag
changelog_updated
Example:
RELEASE_CREATED
previous_version: v1.3.2
release_version: v1.4.0
release_level: minor
tag: v1.4.0
changelog_updated: true
Symphony Flow
The expected integration is:
symphony-orchestrator
│
▼
commit-async
│
▼
tests-async
│
┌────┴────┐
│ │
FAIL PASS
│ │
STOP ▼
PUSH
│
▼
auto-release
│
┌──────┴──────┐
│ │
NO_RELEASE RELEASE
│ │
▼ ▼
FINISH CHANGELOG
+
TAG
│
▼
readme-async
If tests-async fails:
STOP
No release must occur.
If no Conventional Commit requires a release:
NO_RELEASE
and Symphony continues to readme-async if appropriate.
Cascade Safety
auto-release must never restart the Symphony pipeline.
It must not call itself.
It must not trigger:
commit-async
tests-async
readme-async
symphony-orchestrator
The orchestrator controls the cascade.
This prevents:
release
↓
README
↓
commit
↓
release
↓
README
↓
...
Installation
Run the installer for your platform:
Linux/macOS:
./auto-release/scripts/install.sh
Windows:
./auto-release/scripts/install.ps1
The installer verifies:
- Git is available
- Current directory is a Git repository
- Python 3 is available
- The release script exists
It does NOT:
- Install npm or Node.js
- Install external Python packages
- Create Git hooks
- Create commits or tags
- Push anything
Usage
Called by symphony-orchestrator after successful tests and push:
python auto-release/scripts/release.py
Returns machine-readable status and release details on stdout.