Publishing Guide
View SourceThis document describes how to publish gen_server_virtual_time to Hex.pm and HexDocs.pm, including automated workflows and maintenance procedures.
Table of Contents
Prerequisites
Required Accounts
Hex.pm Account
- Sign up at https://hex.pm/signup
- Generate an API key: https://hex.pm/settings/keys
- Store the key securely (you'll need it for GitHub Actions)
GitHub Account
- Repository must be hosted on GitHub for automated workflows
- Admin access required to configure secrets
Required Tools
- Elixir 1.14+ and OTP 25+
- Git with configured user name and email
- Internet connection for publishing
Local Environment Setup
Authenticate with Hex:
mix hex.user authInstall dependencies:
mix deps.getVerify project builds:
mix compile mix test mix docs
Initial Setup
1. Configure GitHub Secrets
Add the following secrets to your GitHub repository (Settings → Secrets and variables → Actions):
HEX_API_KEY: Your Hex.pm API key
2. Verify mix.exs Configuration
The mix.exs file must include proper package metadata:
defp package do
[
name: "gen_server_virtual_time",
files: ~w(lib .formatter.exs mix.exs README.md LICENSE CHANGELOG.md),
maintainers: ["Your Name"],
licenses: ["MIT"],
links: %{
"GitHub" => @source_url,
"Changelog" => "#{@source_url}/blob/main/CHANGELOG.md"
}
]
end3. Verify Required Files
Ensure these files exist and are up-to-date:
README.md- Project documentationLICENSE- MIT LicenseCHANGELOG.md- Version history.formatter.exs- Code formatting rules
Publishing Process
Option 1: Automated Publishing (Recommended)
This is the recommended approach for production releases.
Prepare the release:
# Run pre-release checks ./scripts/prepare_release.shBump the version:
# For a patch release (0.1.0 → 0.1.1) ./scripts/bump_version.sh patch # For a minor release (0.1.0 → 0.2.0) ./scripts/bump_version.sh minor # For a major release (0.1.0 → 1.0.0) ./scripts/bump_version.sh majorThis script will:
- Update version in
mix.exs - Update
CHANGELOG.mdwith the new version and date - Update version in
README.mdinstallation instructions - Create a git commit with the version bump
- Create a git tag (e.g.,
v0.1.1)
- Update version in
Review the changes:
git show HEADUpdate CHANGELOG.md:
Edit
CHANGELOG.mdand add release notes under the new version section:## [0.1.1] - 2025-10-11 ### Added - New feature X - New feature Y ### Fixed - Bug fix A - Bug fix BCommit CHANGELOG updates (if any):
git add CHANGELOG.md git commit --amend --no-editPush the changes:
git push origin mainPush the tag:
git push origin v0.1.1 # Replace with your versionAutomated Publishing:
Once the tag is pushed, GitHub Actions will automatically:
- Run all tests
- Build documentation
- Publish to Hex.pm
- Publish docs to HexDocs.pm
- Create a GitHub Release
Monitor progress at:
https://github.com/your-username/gen_server_virtual_time/actions
Option 2: Manual Publishing
For testing or emergency releases:
Ensure everything is committed:
git statusRun pre-release checks:
./scripts/prepare_release.shPublish to Hex:
mix hex.publishReview the package contents:
- Check files to be included
- Verify version number
- Review description and metadata
Confirm publishing:
- Type
yand press Enter
- Type
Create and push git tag:
git tag -a v0.1.0 -m "Release version 0.1.0" git push origin v0.1.0
Automated Workflows
CI Workflow (.github/workflows/ci.yml)
Runs on every push to main or develop and on all pull requests.
Jobs:
- Test: Runs tests on multiple Elixir/OTP versions
- Quality: Runs Credo and Dialyzer for code quality
- Docs: Builds documentation to ensure no errors
Matrix Testing:
- Latest stable (Elixir 1.18 / OTP 27)
- Minimum supported (Elixir 1.14 / OTP 25)
Publish Workflow (.github/workflows/publish.yml)
Triggers only when a version tag (e.g., v1.0.0) is pushed.
Steps:
- Checkout code
- Setup Elixir environment
- Install dependencies
- Run tests (safety check)
- Build documentation
- Publish to Hex.pm (automatically publishes docs to HexDocs)
- Create GitHub Release with changelog
Caching Strategy
Both workflows use caching to speed up builds:
- Dependencies (
deps/) - Build artifacts (
_build/) - Dialyzer PLT files (
priv/plts/)
Cache keys are based on OS, Elixir version, OTP version, and mix.lock hash.
Maintenance Tasks
Version Numbering
Follow Semantic Versioning:
- MAJOR (X.0.0): Breaking changes
- MINOR (0.X.0): New features, backward compatible
- PATCH (0.0.X): Bug fixes, backward compatible
Updating Dependencies
Check for updates:
mix hex.outdatedUpdate dependencies:
mix deps.update --allTest thoroughly:
mix testCommit the changes:
git add mix.lock git commit -m "Update dependencies"
Maintaining CHANGELOG.md
Keep CHANGELOG.md updated with all notable changes:
Add entries to [Unreleased]:
- Document changes as you make them
- Use categories: Added, Changed, Deprecated, Removed, Fixed, Security
Release checklist:
- Move [Unreleased] entries to the new version section
- Add the release date
- Update version comparison links at the bottom
Code Quality Checks
Run these locally before pushing:
# Format code
mix format
# Check formatting
mix format --check-formatted
# Run tests
mix test
# Run Credo
mix credo --strict
# Run Dialyzer
mix dialyzer
# Generate documentation
mix docs
Pre-commit Hooks (Optional)
Create .git/hooks/pre-commit:
#!/bin/sh
set -e
echo "Running pre-commit checks..."
# Check formatting
mix format --check-formatted
# Run tests
mix test --trace
echo "✓ All checks passed"
Make it executable:
chmod +x .git/hooks/pre-commit
Troubleshooting
Publishing Fails: "Package name already taken"
The package name is already registered. Either:
- You need to be added as a maintainer
- Choose a different package name in
mix.exs
Publishing Fails: "Authentication failed"
Check your Hex API key:
mix hex.user auth
# Or set HEX_API_KEY environment variable
Documentation Not Appearing on HexDocs
- Documentation is published automatically with
mix hex.publish - Check if docs built successfully:
mix docs - Wait a few minutes for HexDocs to process
- Check HexDocs build status at https://hexdocs.pm/gen_server_virtual_time
GitHub Actions Workflow Fails
Check workflow logs:
- Go to GitHub repository → Actions
- Click on the failed workflow
- Review error messages
Common issues:
HEX_API_KEYsecret not set- Test failures
- Dependency issues
- Network problems
Re-run workflow:
- Click "Re-run jobs" button
- Or delete and recreate the tag:
git tag -d v0.1.0 git push origin :refs/tags/v0.1.0 git tag -a v0.1.0 -m "Release version 0.1.0" git push origin v0.1.0
Version Conflicts
If mix.exs version doesn't match the git tag:
Fix the version in mix.exs:
# Edit mix.exs manually or use: ./scripts/bump_version.sh patch --dry-run # To see what would changeDelete the incorrect tag:
git tag -d v0.1.0 git push origin :refs/tags/v0.1.0Create the correct tag:
git tag -a v0.1.0 -m "Release version 0.1.0" git push origin v0.1.0
Build Fails on Specific Elixir/OTP Version
Test locally with the failing version:
asdf install elixir 1.14.0-otp-25 asdf local elixir 1.14.0-otp-25 mix deps.get mix testFix compatibility issues
Update minimum version requirements in mix.exs if needed
Best Practices
Before Each Release
- ✅ Run
./scripts/prepare_release.sh - ✅ Update CHANGELOG.md with release notes
- ✅ Review diff:
git diff origin/main - ✅ Check CI is passing on main branch
- ✅ Verify documentation looks good:
mix docs && open doc/index.html
After Each Release
- ✅ Verify package on Hex.pm: https://hex.pm/packages/gen_server_virtual_time
- ✅ Verify docs on HexDocs: https://hexdocs.pm/gen_server_virtual_time
- ✅ Check GitHub Release was created
- ✅ Test installation in a new project:
mix new test_project cd test_project # Add {:gen_server_virtual_time, "~> 0.1"} to mix.exs mix deps.get
Security Considerations
Never commit secrets:
- Keep
HEX_API_KEYin GitHub Secrets only - Don't share API keys in logs or code
- Keep
Protect main branch:
- Enable branch protection rules
- Require pull request reviews
- Require CI to pass before merging
Review dependencies regularly:
- Check for security advisories:
mix hex.audit - Keep dependencies updated
- Check for security advisories:
Quick Reference
Version Bump Commands
# Dry run (see what would change)
./scripts/bump_version.sh patch --dry-run
# Patch: 0.1.0 → 0.1.1
./scripts/bump_version.sh patch
# Minor: 0.1.0 → 0.2.0
./scripts/bump_version.sh minor
# Major: 0.1.0 → 1.0.0
./scripts/bump_version.sh major
One-Line Release
./scripts/prepare_release.sh && \
./scripts/bump_version.sh patch && \
git push origin main && \
git push origin --tags
Check Package Status
# View package on Hex.pm
open https://hex.pm/packages/gen_server_virtual_time
# View documentation
open https://hexdocs.pm/gen_server_virtual_time
# Check GitHub Actions
open https://github.com/your-username/gen_server_virtual_time/actions
Additional Resources
- Hex.pm Publishing Documentation
- HexDocs Documentation
- ExDoc Documentation
- Semantic Versioning
- Keep a Changelog
- GitHub Actions Documentation
Support
If you encounter issues not covered in this guide:
- Check existing GitHub Issues
- Search Hex.pm Documentation
- Ask in Elixir Forum
- Create a new issue with details about your problem