Release Script Libraries
Modular, tested, and reusable libraries for the zer0-mistakes release automation system.
Overview
This directory contains focused, single-responsibility libraries that power the release automation. Each library can be used independently or composed together for complex workflows.
Libraries
📦 common.sh - Shared Utilities
Core utilities used by all other libraries.
Functions:
log(),info(),warn(),error()- Colored loggingconfirm()- User confirmation promptsdry_run_exec()- Dry run wrapper for commandsrequire_command(),require_file()- Dependency validationget_repo_root()- Find repository root directory
Usage:
source "$(dirname "$0")/lib/common.sh"
log "Starting process..."
🔍 validation.sh - Environment Validation
Validates environment, dependencies, and prerequisites.
Functions:
validate_git_repo()- Verify git repositoryvalidate_clean_working_dir()- Check for uncommitted changesvalidate_required_files()- Check required files existvalidate_dependencies()- Verify all commands availablevalidate_rubygems_auth()- Check RubyGems credentialsvalidate_environment()- Comprehensive validation
Usage:
source "$(dirname "$0")/lib/validation.sh"
validate_environment false false # skip_publish=false, require_gh=false
📝 version.sh - Version Management
Read, calculate, and update semantic versions.
Functions:
get_current_version()- Read version from version.rbcalculate_new_version()- Calculate new version (major/minor/patch)update_version_files()- Update all version filesvalidate_version_format()- Validate semver formatversion_less_than()- Compare two versions
Usage:
source "$(dirname "$0")/lib/version.sh"
current=$(get_current_version)
new=$(calculate_new_version "$current" "minor")
update_version_files "$new"
📋 changelog.sh - Changelog Generation
Generate changelogs from conventional commits.
Functions:
generate_changelog()- Generate changelog for versioncategorize_commit()- Categorize commit by typeclean_commit_message()- Clean conventional commit prefixesextract_release_notes()- Extract notes for specific version
Commit Categories:
feat:→ Addedfix:→ FixedBREAKING:→ Breaking Changesdocs:,chore:,refactor:→ Changedremove:→ Removedsecurity:→ Security
Usage:
source "$(dirname "$0")/lib/changelog.sh"
generate_changelog "1.2.0" "v1.1.0" "HEAD"
🔄 git.sh - Git Operations
Git commits, tags, and repository operations.
Functions:
get_last_version_tag()- Find last version tagcommit_and_tag()- Create release commit and tagpush_changes()- Push to remote with tagsget_commits_between()- Get commits in rangeget_repo_info()- Extract owner/repo from URL
Usage:
source "$(dirname "$0")/lib/git.sh"
commit_and_tag "1.2.0"
push_changes "origin" "main"
💎 gem.sh - Gem Operations
Build, test, publish, and release gems.
Functions:
build_gem()- Build the gem packagepublish_gem()- Publish to RubyGemscreate_github_release()- Create GitHub releaserun_tests()- Execute test suitegem_version_exists()- Check if version exists on RubyGems
Usage:
source "$(dirname "$0")/lib/gem.sh"
build_gem "1.2.0"
run_tests
publish_gem "1.2.0"
create_github_release "1.2.0"
Testing
Each library has comprehensive unit tests in scripts/test/lib/.
Run All Tests
./scripts/test/lib/run_tests.sh
Run Individual Tests
./scripts/test/lib/test_version.sh
./scripts/test/lib/test_changelog.sh
./scripts/test/lib/test_git.sh
Test Coverage
- ✅ Version calculations and validation
- ✅ Changelog generation and categorization
- ✅ Git operations and tag management
- ✅ Environment validation
- ✅ Gem build and publish workflows
Environment Variables
Control library behavior with environment variables:
# Dry run mode (no actual changes)
DRY_RUN=true
# Non-interactive mode (auto-confirm prompts)
INTERACTIVE=false
# Verbose debug output
VERBOSE=true
Example: Custom Release Script
#!/bin/bash
set -euo pipefail
# Source libraries
LIB_DIR="$(dirname "$0")/lib"
source "$LIB_DIR/common.sh"
source "$LIB_DIR/validation.sh"
source "$LIB_DIR/version.sh"
source "$LIB_DIR/changelog.sh"
source "$LIB_DIR/git.sh"
source "$LIB_DIR/gem.sh"
# Main workflow
main() {
print_header "Custom Release"
# Validate
validate_environment
# Version
local current=$(get_current_version)
local new=$(calculate_new_version "$current" "patch")
update_version_files "$new"
# Changelog
generate_changelog "$new"
# Build & Test
build_gem "$new"
run_tests
# Commit & Tag
commit_and_tag "$new"
# Publish
publish_gem "$new"
create_github_release "$new"
push_changes
success "Release $new complete!"
}
main "$@"
Architecture Benefits
✅ Modularity
Each library has ONE responsibility - easy to understand and modify.
✅ Testability
Small, focused functions can be unit tested independently.
✅ Reusability
Libraries can be used in different scripts or GitHub Actions.
✅ Maintainability
Changes isolated to specific files - less ripple effect.
✅ Clarity
Functions have clear names and single purposes.
Migrating Old Scripts
Old monolithic scripts (gem-publish.sh, release.sh, build.sh) can now be:
- Deprecated with warnings pointing to new libraries
- Replaced with thin wrappers using libraries
- Removed once adoption is confirmed
Example deprecation wrapper:
#!/bin/bash
echo "⚠️ WARNING: This script is deprecated"
echo " Use: ./scripts/release"
exec "$(dirname "$0")/release" "$@"
Contributing
When adding new functionality:
- Choose the right library - or create a new one if needed
- Write tests first - add tests to
test/test_*.sh - Keep functions small - one function, one purpose
- Document thoroughly - update this README
- Test in isolation - each library should work standalone
Questions?
- See
docs/RELEASE_WORKFLOW_IMPROVEMENTS.mdfor the full refactoring plan - Check existing library code for patterns and examples
- Run tests to ensure everything still works
Phase 1 Complete ✅
All libraries extracted with comprehensive test coverage.