This repository's default branch is main, but every workflow was still keyed to master, so none of them could ever run: - build-and-test.yml triggered on push/PR to master, so CI never fired and the README's build badge had no status to report. - docker-publish.yml keyed off a successful build-and-test run on master, so it never fired either. Only trigger filters and comments referenced the branch; the tag-vs-branch logic was already branch-agnostic. - make-release.yml actively refused to run, failing with "Regular releases can only be created from the 'master' branch." Also updated the branch names throughout docs/DEVELOPMENT_WORKFLOW.md to match.
7.9 KiB
Development Workflow
This project follows a trunk-based development workflow. This document outlines the branch strategy, development practices, and CI/CD processes.
Branch Strategy
Trunk Branch: main
- Always releasable - The
mainbranch should always be in a deployable state - Protected - Direct pushes should be avoided; use pull requests
- Main integration point - All changes merge into
main - Production-ready - Code on
maincan be released at any time
Short-Lived Branches
All feature work happens in short-lived branches that are merged back to main quickly (typically within days, not weeks).
Branch Types
-
feature/<slug>- New features and enhancements- Examples:
feature/new-player-ui,feature/playlist-import - Use for: Adding new functionality, UI improvements, major enhancements
- Examples:
-
fix/<slug>- Bug fixes- Examples:
fix/youtube-oauth,fix/memory-leak - Use for: Fixing bugs, resolving issues, patching vulnerabilities
- Examples:
-
chore/<slug>- Maintenance tasks- Examples:
chore/update-dependencies,chore/refactor-audio-handler - Use for: Code cleanup, refactoring, dependency updates, documentation
- Examples:
-
deps/<slug>- Dependency experiments- Examples:
deps/youtube-source-pr195,deps/test-jda-6.4 - Use for: Testing dependency updates, experimenting with forks, evaluating new libraries
- Examples:
-
release/<version>- Release stabilization (optional)- Examples:
release/0.6.3,release/0.6.3-rc1 - Use for: Stabilizing a release, release candidates, hotfixes for specific versions
- Note: Only create when you need to stabilize a release. Most releases can go directly from
main
- Examples:
Branch Naming Rules
- Format:
<type>/<descriptive-slug> - Slug requirements:
- Lowercase letters, numbers, and hyphens only
- Descriptive and concise (e.g.,
new-player-ui, notuiornew-feature) - No underscores or special characters
- Examples:
- ✅
feature/new-player-ui - ✅
fix/youtube-oauth-error - ✅
chore/update-maven-plugins - ✅
deps/test-lavaplayer-2.3 - ✅
release/0.6.3 - ❌
feature/newFeature(uppercase) - ❌
fix/bug_123(underscore) - ❌
new-feature(missing type prefix) - ❌
feature/new feature(spaces)
- ✅
Development Process
1. Starting Work
# Create a branch from main
git checkout main
git pull origin main
git checkout -b feature/my-new-feature
# Or for a bug fix
git checkout -b fix/bug-description
2. Making Changes
- Make small, focused commits
- Write clear commit messages
- Keep the branch up-to-date with
main:git checkout main git pull origin main git checkout feature/my-new-feature git rebase main # or git merge main
3. Testing Locally
- Run tests:
mvn verify - Test Docker build:
docker build -t jmusicbot:test . - Verify the bot works as expected
4. Creating a Pull Request
- Push your branch:
git push origin feature/my-new-feature - Create a PR targeting
main - The CI will:
- ✅ Validate branch naming
- ✅ Run tests and build
- ✅ Build Docker image (tagged with branch name)
- Wait for CI to pass and code review
5. Merging
- Once approved and CI passes, merge the PR
- Prefer squash merge to keep history clean
- Delete the branch after merging (GitHub can do this automatically)
CI/CD Workflows
Branch Validation
The validate-branch-naming.yml workflow automatically validates branch names on:
- Pull requests (when opened, updated, or edited)
- Direct pushes to non-main branches
What it checks:
- Branch name matches allowed patterns
- Slug uses only lowercase, numbers, and hyphens
- Proper type prefix is used
Build and Test
The build-and-test.yml workflow runs on:
- Pushes to
mainand all short-lived branches - Pull requests targeting
main
What it does:
- Compiles the project
- Runs unit and integration tests
- Generates code coverage reports
- Uploads coverage to Codecov
Docker Build
The docker-build.yml workflow builds and publishes Docker images on:
- Pushes to
main→ tags as:latestand version (if not SNAPSHOT) - Pushes to short-lived branches → tags as
:<branch-name>(e.g.,:feature-new-player-ui) - Version tags (e.g.,
v0.6.3) → tags as:0.6.3
Image tags:
main:ghcr.io/purnell569/musicbot:latest(+ version tag if applicable)- Feature branch:
ghcr.io/purnell569/musicbot:feature-new-player-ui - Version tag:
ghcr.io/purnell569/musicbot:0.6.3
Best Practices
Keep Branches Short-Lived
- Goal: Merge within days, not weeks
- Why: Reduces merge conflicts, keeps code fresh, enables faster feedback
- If stuck: Break work into smaller PRs
Keep main Releasable
- Never push broken code to
main - Always ensure tests pass before merging
- Use feature flags if needed for incomplete features
- Consider draft PRs for work-in-progress
Small, Focused PRs
- One feature/fix per PR when possible
- Easier to review and understand
- Faster to merge and deploy
- Less risk of conflicts
Regular Integration
- Rebase or merge
maininto your branch regularly - Run tests locally before pushing
- Fix CI failures promptly
Clear Commit Messages
- Format:
<type>: <description> - Types:
feat,fix,chore,docs,refactor,test - Example:
feat: add playlist import from YouTube - Why: Makes history readable and enables automated changelogs
Release Process
Standard Release (from main)
-
Ensure
mainis stable- All tests passing
- No known critical bugs
- Documentation updated
-
Update version in
pom.xml- Set the release version (e.g.,
0.6.3) - Commit:
git commit -m "chore: bump version to 0.6.3"
- Set the release version (e.g.,
-
Create release tag
git tag v0.6.3 git push origin v0.6.3 -
Use "Make Release" workflow (optional)
- Or manually create GitHub release
- Attach JAR file from workflow artifacts
-
Docker image is automatically built from the tag
- Tagged as
ghcr.io/purnell569/musicbot:0.6.3
- Tagged as
Release Branch (for stabilization)
Only use if you need to stabilize a release while continuing development:
-
Create release branch
git checkout -b release/0.6.3 git push origin release/0.6.3 -
Stabilize on release branch
- Fix critical bugs
- Run extensive testing
- Cherry-pick fixes from
mainif needed
-
Tag from release branch
git tag v0.6.3 git push origin v0.6.3 -
Merge back to main (if needed)
- Merge any fixes back to
main - Delete release branch after release
- Merge any fixes back to
FAQ
Q: Can I push directly to main?
A: Not recommended. Use pull requests for all changes to ensure:
- Code review
- CI validation
- Better history tracking
Q: How long should branches live?
A: Ideally less than a week. If work takes longer, consider:
- Breaking into smaller PRs
- Using feature flags
- Creating a release branch if needed
Q: What if I need to experiment?
A: Use deps/<slug> branches for dependency experiments, or create a personal fork for major experiments.
Q: Can I use different branch names?
A: The CI will reject branches that don't match the allowed patterns. This ensures consistency and makes it easier to understand what each branch is for.
Q: What about hotfixes?
A: For urgent production fixes:
- Create
fix/<description>branch frommain - Fix the issue
- Create PR and merge quickly
- Tag a new patch version (e.g.,
v0.6.3→v0.6.4)
Summary
- Trunk:
mainis always releasable - Branches: Short-lived, type-prefixed (
feature/,fix/,chore/,deps/,release/) - Process: Branch → Develop → Test → PR → Merge → Release
- CI: Automatic validation, testing, and Docker builds
- Goal: Fast, safe, continuous integration and deployment