This document provides comprehensive guidance on git workflows and CI/CD integration for the dotCMS project. It covers git best practices, GitHub Actions CI/CD pipeline, and development workflow patterns.
- Main Branch:
main- Production-ready code - Feature Branches:
issue-{issue_number}-{description}- New features and bug fixes linked to GitHub issues - Release Branches:
release/x.y.z- LTS release preparation - Hotfix Branches:
hotfix/description- Critical production fixes
All feature branches MUST follow this pattern:
issue-{issue_number}-{short-description}
Examples:
issue-32668-need-to-optimize-and-shrink-claudemdissue-25620-alert-when-api-keys-about-to-expireissue-32238-content-typesissue-32333-update-folder-ids
Rules:
- Always start with
issue-prefix - Use the GitHub issue number (without #)
- Add descriptive suffix with hyphens (no spaces)
- Keep descriptions concise but meaningful
Commit messages can be descriptive and developer-friendly:
# Individual commits - use whatever is helpful for development
git commit -m "Add user authentication logic"
git commit -m "Fix null pointer exception in login"
git commit -m "Update tests for new auth flow"
git commit -m "Address PR feedback - simplify validation"PR titles MUST follow conventional commit format since PRs are squashed:
# PR title format (becomes the squashed commit message)
feat(auth): add user authentication endpoint
fix(api): resolve null pointer exception in login validation
docs(readme): update installation instructions
test(auth): add comprehensive authentication test coverage
refactor(service): improve user service error handling
chore(deps): update dependency versionsWhy this matters:
- PRs are squashed into single commits on merge
- The PR title becomes the final commit message in main branch
- Individual commit messages are only visible during development
- PR title should summarize the entire change set
-
Create Feature Branch:
git checkout -b issue-12345-add-user-authentication
-
Regular Commits:
git add . git commit -m "Add user authentication logic" # Individual commits can be informal and descriptive
-
Push and Create PR:
git push origin issue-12345-add-user-authentication # Create PR via GitHub UI -
PR Review Process:
- Automated CI/CD validation
- Code review requirements
- Security and quality checks
- Documentation updates
The dotCMS project uses a sophisticated pre-commit hook system that ensures code quality and consistency before commits are made. The system includes both Maven-based and Husky-based hooks.
#!/usr/bin/env bash
echo "Running Maven pre-commit hook"
./mvnw generate-resources -Pauto-formatThis hook:
- Runs Maven resource generation with auto-formatting
- Ensures generated files are up-to-date
- Applies consistent formatting across the codebase
The frontend uses a comprehensive Husky-based pre-commit hook that:
- SDKMAN Integration: Ensures correct Java version via
.sdkmanrc - Node Version Management: Uses
.nvmrcfor Node.js version consistency - Yarn Installation: Manages dependencies and lockfile updates
- Maven Analysis: Determines if Maven compile is needed based on staged files
- OpenAPI Generation: Automatically regenerates OpenAPI specs when REST endpoints change
- Conditional Execution: Skips unnecessary builds for performance
- ESLint: Runs
nx affected -t lintwith automatic fixing - Prettier: Runs
nx format:writefor consistent code formatting - Dependency Updates: Automatically updates
yarn.lockwhenpackage.jsonchanges
- Generated Files: Automatically stages generated files (OpenAPI specs, compiled assets)
- Backup System: Creates backups of untracked files during processing
- Cleanup: Removes temporary files and restores workspace state
- ENOBUFS Auto-Fix: Automatically handles Node.js buffer issues
- Cache Management: Resets Nx cache when needed
- Graceful Degradation: Continues processing even if non-critical steps fail
- Java Environment: Sets up correct Java version via SDKMAN
- Maven Compile: Runs if REST API files are modified
- OpenAPI Update: Regenerates and stages OpenAPI specifications
- Resource Generation: Ensures all generated resources are current
- Node Environment: Sets up correct Node.js and Yarn versions
- Dependency Check: Validates and updates
yarn.lock - Linting: Runs ESLint with auto-fix on affected files
- Formatting: Applies Prettier formatting to all code
- SDK Build: Builds SDK-UVE components if affected
- Full Environment Setup: Configures both Java and Node environments
- Maven Processing: Handles backend compilation and resource generation
- Frontend Processing: Runs full frontend quality checks
- File Coordination: Ensures all generated files are properly staged
- SDKMAN: For Java version management
- Node.js: Project-specific version in
installs/node - Yarn: Project-specific version in
installs/node/yarn
.git/hooks/pre-commit: Main Maven hookcore-web/.husky/pre-commit: Frontend hook.sdkmanrc: Java version specificationcore-web/.nvmrc: Node.js version specification
In exceptional cases, pre-commit hooks can be bypassed:
git commit --no-verify -m "commit message"--no-verify for emergency fixes. All bypassed commits must be fixed in follow-up commits.
- SDKMAN Not Found: Install SDKMAN from https://github.com/dotCMS/dotcms-utilities
- Node Version Mismatch: Run
nvm usein project root - Yarn Lock Conflicts: Run
yarn installto update lockfile - ENOBUFS Errors: Hook auto-fixes, but manual
yarn nx resetmay be needed
# Reset environment
cd core-web
yarn nx reset
yarn install
# Run checks manually
yarn nx affected -t lint --fix=true
yarn nx format:writePR Created → PR Workflow → Merge Queue → Trunk → Nightly → LTS (manual)
↓
All workflows → Post-Workflow Reporting
- Trigger: Pull requests to main/master
- Purpose: Comprehensive PR validation
- Security: No secrets in PR context (zero-trust)
- Features:
- Conditional execution based on file changes
- Unit, integration, and E2E tests
- Semgrep security analysis
- PR status notifications
- Trigger: Merge group checks requested
- Purpose: Final validation before merge
- Features:
- Comprehensive test suite
- Artifact generation for reuse
- Flaky test detection
- Trigger: Push to main branch
- Purpose: Post-merge processing
- Features:
- Artifact reuse from merge queue
- CLI native binary building
- Deployment to trunk environment
- SDK library publishing
- Trigger: Scheduled cron job
- Purpose: Extended testing
- Features:
- Extended test suites
- Nightly environment deployment
- Performance benchmarking
- Trigger: Manual dispatch only
- Purpose: Long-term support releases
- Features:
- On-demand release preparation
- Comprehensive validation
- Special release artifacts
- Initialize Phase: Change detection and build planning
- Build Phase: Maven builds and artifact generation
- Test Phase: Test orchestration (JVM, CLI, frontend, integration, E2E)
- Semgrep Phase: Security and code quality analysis
- Deployment Phase: Environment deployments
- Finalize Phase: Status aggregation
Configuration: .github/filters.yaml
The system uses YAML anchors and references to avoid duplication:
# Example: Backend filter with anchor
backend: &backend
- 'dotCMS/!(src/main/webapp/html/)**'
- 'dotcms-integration/**'
- 'pom.xml'
- *full_build_test # References full_build_test anchor
# Example: Frontend filter
frontend: &frontend
- 'core-web/**'
- *full_build_testKey Filters:
backend: Java code, Maven files, integration testsfrontend: Angular code, CSS/JS filescli: CLI tools and related backend changesfull_build_test: Infrastructure files that require full rebuilds
- NO secrets in PR workflows (zero-trust model)
- Validate all user inputs using environment variables
- Use minimal explicit permissions
- Pin actions to specific versions (never @master)
# ❌ NEVER: Secrets in PR workflows
on: pull_request
secrets:
ANY_SECRET: ${{ secrets.ANY_SECRET }} # SECURITY VIOLATION
# ✅ ALWAYS: Environment variables for user input
env:
USER_INPUT: ${{ github.event.issue.title }}
run: |
if [[ "$USER_INPUT" =~ ^[a-zA-Z0-9\ \-\_]+$ ]]; then
echo "Valid: $USER_INPUT"
fi
# ✅ ALWAYS: Explicit minimal permissions
permissions:
contents: read
packages: write # Only if neededWhen working on backend Java code:
- Follow Java Standards: See Java Standards
- Test Triggering: Changes to
/dotCMS/src/main/java/**trigger backend tests - Build Commands:
# Fast build for development ./mvnw install -pl :dotcms-core -DskipTests # Full build with tests ./mvnw clean install
When working on Angular frontend code:
- Follow Angular Standards: See Angular Standards
- Test Triggering: Changes to
/core-web/**trigger frontend tests - Build Commands:
# Development server cd core-web && nx run dotcms-ui:serve # Run tests cd core-web && nx run dotcms-ui:test
For changes affecting both backend and frontend:
- Review API Contracts: See API Contracts
- Comprehensive Testing: Both backend and frontend tests will run
- Integration Testing: E2E tests validate full workflows
- JVM Unit Tests: Fast Java unit tests
- CLI Tests: Command-line interface testing
- Frontend Tests: Angular component tests
- Integration Tests: Database and API integration
- E2E Tests: End-to-end user workflows
- PR Context: Limited tests based on changes
- Merge Queue: Comprehensive test suite
- Trunk: Configurable with artifact reuse
- Nightly: Extended test suites
# Check syntax
yamllint .github/workflows/your-workflow.yml
# Verify file location
ls -la .github/workflows/
# Test trigger conditions
# Create test PR or push to monitored branch# Debug change detection
- name: Debug Change Detection
run: |
echo "Backend changes: ${{ needs.initialize.outputs.backend }}"
echo "Frontend changes: ${{ needs.initialize.outputs.frontend }}"
echo "Build required: ${{ needs.initialize.outputs.build }}"Fix by updating .github/filters.yaml:
backend: &backend
- 'dotCMS/!(src/main/webapp/html/)**'
- 'your-new-path/**' # Add missing paths
- *full_build_test# Check Java version
cat .sdkmanrc
# Verify Maven dependencies
./mvnw dependency:tree
# Check for conflicts
./mvnw dependency:analyze- Maven Dependencies: Cached between builds
- Node Modules: Cached for frontend builds
- Build Artifacts: Reused across workflow stages
- Test Matrix: Multiple Java versions and configurations
- Independent Jobs: Run in parallel where possible
- Change Detection: Skip unnecessary work
- Real-time Status: Slack notifications via
#guild-dev-pipeline - Failure Analysis: Detailed error reporting
- Performance Metrics: Build time and test execution tracking
- Primary:
#guild-dev-pipelineSlack channel - GitHub Issues: Technical issues and bug reports
- Documentation: Comprehensive guides in
/docs
- Use reusable workflow components
- Follow security patterns (no secrets in PR context)
- Implement intelligent change detection
- Test changes thoroughly before deployment
- Document workflow purpose and features
- Create duplicate workflows for same trigger
- Add secrets to PR workflows
- Modify legacy workflows unnecessarily
- Use hardcoded values (use variables)
- Implement build logic directly in main workflows
# Create feature branch (REQUIRED pattern)
git checkout -b issue-12345-short-description
# Commit with descriptive message (informal is fine)
git commit -m "Add authentication logic and tests"
# Push and create PR
git push origin issue-12345-short-description# Fast backend build
./mvnw install -pl :dotcms-core -DskipTests
# Frontend development
cd core-web && nx run dotcms-ui:serve
# Full build with tests
./mvnw clean install# Check dependency tree
./mvnw dependency:tree
# Find conflicts
./mvnw dependency:tree -Dverbose
# Analyze dependencies
./mvnw dependency:analyzeThis workflow integrates with the main dotCMS development patterns:
- Security: Follows Security Principles
- Java: Uses Java Standards
- Angular: Uses Angular Standards
- Maven: Uses Maven Build System
- Testing: Follows Testing Patterns
- Workflow Files:
.github/workflows/ - Custom Actions:
.github/actions/core-cicd/ - Change Detection:
.github/filters.yaml - Documentation:
docs/core/GIT_WORKFLOWS.md - Support Channel:
#guild-dev-pipelineSlack