Configure SonarQube Developer Edition with branch analysis capabilities and pull request decoration for GitHub and GitLab. Implement automated code quality checks in CI/CD pipelines with comprehensive branch coverage and merge request feedback.
Prerequisites
- SonarQube Developer Edition installed
- PostgreSQL database configured
- GitHub or GitLab repository access
- CI/CD pipeline setup
What this solves
SonarQube branch analysis and pull request decoration provide automated code quality feedback directly in your version control workflows. This setup enables developers to see quality gate results, security vulnerabilities, and code coverage metrics within GitHub pull requests or GitLab merge requests before code reaches the main branch.
Step-by-step configuration
Install SonarQube Developer Edition
Branch analysis requires SonarQube Developer Edition or higher. Download and install the commercial edition with branch analysis capabilities.
cd /opt
sudo wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-10.3.0.82913.zip
sudo unzip sonarqube-10.3.0.82913.zip
sudo mv sonarqube-10.3.0.82913 sonarqube
sudo chown -R sonar:sonar /opt/sonarqube
Configure branch analysis in sonar.properties
Enable branch analysis and configure the branch plugin settings in the SonarQube configuration file.
# Enable branch analysis
sonar.branch.name=main
sonar.branch.target=main
Pull request analysis configuration
sonar.pullrequest.provider=github
sonar.pullrequest.github.repository=your-org/your-repo
sonar.pullrequest.github.endpoint=https://api.github.com/
Database configuration (required for branch data storage)
sonar.jdbc.url=jdbc:postgresql://localhost:5432/sonarqube
sonar.jdbc.username=sonarqube
sonar.jdbc.password=your_secure_password
Web server configuration
sonar.web.host=0.0.0.0
sonar.web.port=9000
sonar.web.javaOpts=-Xmx2048m -Xms1024m
Install and configure branch plugin
The branch analysis functionality is built into Developer Edition. Restart SonarQube to enable the features.
sudo systemctl restart sonarqube
sudo systemctl status sonarqube
Check logs for branch plugin initialization
sudo tail -f /opt/sonarqube/logs/sonar.log
Create GitHub App for pull request decoration
Generate a GitHub App to enable SonarQube to comment on pull requests and update commit statuses.
# Generate private key for GitHub App
openssl genpkey -algorithm RSA -out /opt/sonarqube/conf/github-app-key.pem -pkcs8 -out_len 2048
sudo chown sonar:sonar /opt/sonarqube/conf/github-app-key.pem
sudo chmod 600 /opt/sonarqube/conf/github-app-key.pem
Configure GitHub integration in SonarQube
Set up the GitHub App credentials in SonarQube administration panel for pull request decoration.
Navigate to Administration > Configuration > General Settings > Pull Requests and configure:
- Provider: GitHub
- GitHub App ID: Your app ID from GitHub
- Client ID: Your app client ID
- Client Secret: Your app client secret
- Private Key: Contents of github-app-key.pem
- GitHub URL: https://api.github.com/ (for GitHub.com)
Configure GitLab integration
For GitLab projects, configure the GitLab integration settings in SonarQube.
# GitLab configuration (alternative to GitHub)
sonar.pullrequest.provider=gitlab
sonar.pullrequest.gitlab.url=https://gitlab.com
sonar.pullrequest.gitlab.userToken=your_gitlab_token
Project-specific GitLab settings
sonar.pullrequest.gitlab.projectId=12345
sonar.pullrequest.gitlab.projectUrl=https://gitlab.com/your-group/your-project
Configure webhook for real-time updates
Set up webhooks in your Git provider to trigger SonarQube analysis on pull request events.
# Webhook URL: http://your-sonarqube-server:9000/api/alm_integration/github/provisioning
Content type: application/json
Events: Pull requests, Push
Secret: Configure in SonarQube webhook settings
Create project with branch analysis enabled
Set up a new project in SonarQube with branch analysis and pull request decoration enabled.
# Create project via API
curl -u admin:admin_password -X POST "http://localhost:9000/api/projects/create" \
-d "project=my-project" \
-d "name=My Project" \
-d "mainBranch=main"
Configure project for GitHub integration
curl -u admin:admin_password -X PUT "http://localhost:9000/api/alm_settings/set_github_binding" \
-d "project=my-project" \
-d "almSetting=github-config" \
-d "repository=your-org/your-repo"
Configure CI/CD pipeline for branch analysis
Set up your CI/CD pipeline to run SonarQube analysis with branch and pull request parameters.
name: SonarQube Analysis
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
sonarqube:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: SonarQube Scan
uses: sonarqube-quality-gate-action@master
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
with:
args: >
-Dsonar.projectKey=my-project
-Dsonar.sources=src
-Dsonar.pullrequest.key=${{ github.event.pull_request.number }}
-Dsonar.pullrequest.branch=${{ github.head_ref }}
-Dsonar.pullrequest.base=${{ github.base_ref }}
Configure GitLab CI pipeline
Set up GitLab CI pipeline with SonarQube scanner for merge request analysis.
stages:
- analysis
sonarqube-check:
stage: analysis
image:
name: sonarsource/sonar-scanner-cli:latest
entrypoint: [""]
variables:
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
GIT_DEPTH: "0"
cache:
key: "${CI_JOB_NAME}"
paths:
- .sonar/cache
script:
- sonar-scanner
-Dsonar.projectKey=my-project
-Dsonar.sources=src
-Dsonar.host.url=$SONAR_HOST_URL
-Dsonar.login=$SONAR_TOKEN
-Dsonar.pullrequest.key=$CI_MERGE_REQUEST_IID
-Dsonar.pullrequest.branch=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
-Dsonar.pullrequest.base=$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
only:
- merge_requests
- main
- develop
Configure quality gates for branches
Set up branch-specific quality gates and configure pull request decoration rules.
# Create custom quality gate for pull requests
curl -u admin:admin_password -X POST "http://localhost:9000/api/qualitygates/create" \
-d "name=PR Gate"
Add conditions to quality gate
curl -u admin:admin_password -X POST "http://localhost:9000/api/qualitygates/create_condition" \
-d "gateName=PR Gate" \
-d "metric=new_coverage" \
-d "op=LT" \
-d "error=80"
curl -u admin:admin_password -X POST "http://localhost:9000/api/qualitygates/create_condition" \
-d "gateName=PR Gate" \
-d "metric=new_bugs" \
-d "op=GT" \
-d "error=0"
Enable pull request decoration
Configure SonarQube to automatically decorate pull requests with quality gate results and code coverage.
Navigate to Administration > Configuration > General Settings > Pull Requests and enable:
- Decorate Pull Requests: Yes
- Delete comments on resolved issues: Yes
- Provider-specific webhook secret
Verify your setup
Test the branch analysis and pull request decoration functionality with a sample pull request.
# Check SonarQube branch analysis status
curl -u admin:admin_password "http://localhost:9000/api/project_branches/list?project=my-project"
Verify webhook configuration
curl -u admin:admin_password "http://localhost:9000/api/webhooks/list?project=my-project"
Test GitHub App permissions
curl -H "Authorization: Bearer YOUR_GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/your-org/your-repo/pulls"
Check SonarQube logs for PR decoration
sudo tail -f /opt/sonarqube/logs/web.log | grep -i "pullrequest"
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Branch analysis not available | Community Edition lacks feature | Upgrade to Developer Edition or higher |
| PR decoration not working | Incorrect GitHub App permissions | Ensure app has "Contents: Read" and "Pull requests: Write" permissions |
| Webhook not triggering analysis | Incorrect webhook URL or secret | Verify webhook URL format and secret in both platforms |
| Quality gate not updating PR | Missing pull request parameters | Add sonar.pullrequest.key, branch, and base parameters |
| GitLab merge request decoration missing | Insufficient GitLab token permissions | Use token with api, read_user, and read_repository scopes |
| Branch data not persisting | Database configuration issues | Ensure PostgreSQL connection and sufficient disk space |
Next steps
- Setup SonarQube scanner for multiple programming languages with automated code quality analysis
- Configure SonarQube custom quality gates and security rules for enterprise environments
- Integrate SonarQube with Jenkins pipeline for automated code quality checks
- Set up SonarQube LDAP authentication and user management for enterprise teams
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Configuration
SONARQUBE_VERSION="10.3.0.82913"
SONARQUBE_USER="sonar"
DB_NAME="sonarqube"
DB_USER="sonarqube"
# Usage
usage() {
echo "Usage: $0 <db_password> [domain]"
echo " db_password: PostgreSQL password for SonarQube"
echo " domain: Optional domain name (default: $(hostname -I | awk '{print $1}')"
exit 1
}
# Check arguments
if [[ $# -lt 1 ]]; then
usage
fi
DB_PASSWORD="$1"
DOMAIN="${2:-$(hostname -I | awk '{print $1}')}"
# Cleanup on error
cleanup() {
echo -e "${RED}Installation failed. Cleaning up...${NC}"
systemctl stop sonarqube 2>/dev/null || true
systemctl stop postgresql 2>/dev/null || true
userdel -r $SONARQUBE_USER 2>/dev/null || true
rm -rf /opt/sonarqube 2>/dev/null || true
}
trap cleanup ERR
# Check prerequisites
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}This script must be run as root${NC}"
exit 1
fi
# Auto-detect distro
if [[ -f /etc/os-release ]]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update"
POSTGRES_SERVICE="postgresql"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
POSTGRES_SERVICE="postgresql"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
POSTGRES_SERVICE="postgresql"
;;
*)
echo -e "${RED}Unsupported distro: $ID${NC}"
exit 1
;;
esac
else
echo -e "${RED}Cannot detect OS distribution${NC}"
exit 1
fi
echo -e "${GREEN}[1/10] Updating system packages...${NC}"
$PKG_UPDATE
echo -e "${GREEN}[2/10] Installing prerequisites...${NC}"
if [[ "$PKG_MGR" == "apt" ]]; then
$PKG_INSTALL openjdk-17-jdk postgresql postgresql-contrib unzip wget curl
else
$PKG_INSTALL java-17-openjdk postgresql-server postgresql-contrib unzip wget curl
fi
echo -e "${GREEN}[3/10] Configuring PostgreSQL...${NC}"
if [[ "$PKG_MGR" != "apt" ]]; then
postgresql-setup --initdb
fi
systemctl enable $POSTGRES_SERVICE
systemctl start $POSTGRES_SERVICE
# Create database and user
sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASSWORD';"
sudo -u postgres psql -c "CREATE DATABASE $DB_NAME OWNER $DB_USER;"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;"
echo -e "${GREEN}[4/10] Creating SonarQube user...${NC}"
useradd -r -m -s /bin/bash $SONARQUBE_USER
echo -e "${GREEN}[5/10] Downloading SonarQube Developer Edition...${NC}"
cd /opt
wget -q "https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-${SONARQUBE_VERSION}.zip"
unzip -q "sonarqube-${SONARQUBE_VERSION}.zip"
mv "sonarqube-${SONARQUBE_VERSION}" sonarqube
chown -R $SONARQUBE_USER:$SONARQUBE_USER /opt/sonarqube
rm "sonarqube-${SONARQUBE_VERSION}.zip"
echo -e "${GREEN}[6/10] Configuring SonarQube properties...${NC}"
cat > /opt/sonarqube/conf/sonar.properties << EOF
# Database configuration
sonar.jdbc.username=$DB_USER
sonar.jdbc.password=$DB_PASSWORD
sonar.jdbc.url=jdbc:postgresql://localhost:5432/$DB_NAME
# Web server configuration
sonar.web.host=0.0.0.0
sonar.web.port=9000
sonar.web.javaOpts=-Xmx2048m -Xms1024m
# Branch analysis configuration
sonar.branch.name=main
sonar.branch.target=main
# Elasticsearch configuration
sonar.search.javaOpts=-Xmx1024m -Xms512m
# Path configuration
sonar.path.data=/opt/sonarqube/data
sonar.path.temp=/opt/sonarqube/temp
sonar.path.logs=/opt/sonarqube/logs
EOF
chown $SONARQUBE_USER:$SONARQUBE_USER /opt/sonarqube/conf/sonar.properties
chmod 640 /opt/sonarqube/conf/sonar.properties
echo -e "${GREEN}[7/10] Creating systemd service...${NC}"
cat > /etc/systemd/system/sonarqube.service << EOF
[Unit]
Description=SonarQube service
After=syslog.target network.target
[Service]
Type=forking
ExecStart=/opt/sonarqube/bin/linux-x86-64/sonar.sh start
ExecStop=/opt/sonarqube/bin/linux-x86-64/sonar.sh stop
User=$SONARQUBE_USER
Group=$SONARQUBE_USER
Restart=always
LimitNOFILE=131072
LimitNPROC=8192
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable sonarqube
echo -e "${GREEN}[8/10] Configuring system limits...${NC}"
cat > /etc/security/limits.d/99-sonarqube.conf << EOF
$SONARQUBE_USER - nofile 131072
$SONARQUBE_USER - nproc 8192
EOF
echo "vm.max_map_count=524288" >> /etc/sysctl.conf
echo "fs.file-max=131072" >> /etc/sysctl.conf
sysctl -p
echo -e "${GREEN}[9/10] Configuring firewall...${NC}"
if command -v firewall-cmd &> /dev/null; then
firewall-cmd --permanent --add-port=9000/tcp
firewall-cmd --reload
elif command -v ufw &> /dev/null; then
ufw allow 9000/tcp
fi
if [[ "$PKG_MGR" != "apt" ]] && command -v setsebool &> /dev/null; then
setsebool -P httpd_can_network_connect 1
fi
echo -e "${GREEN}[10/10] Starting SonarQube...${NC}"
systemctl start sonarqube
# Wait for SonarQube to start
echo -e "${YELLOW}Waiting for SonarQube to start...${NC}"
for i in {1..60}; do
if curl -s http://localhost:9000/api/system/status | grep -q "UP"; then
break
fi
sleep 5
done
echo -e "${GREEN}Installation completed successfully!${NC}"
echo
echo -e "${YELLOW}SonarQube is now running at:${NC}"
echo " Local: http://localhost:9000"
echo " Network: http://$DOMAIN:9000"
echo
echo -e "${YELLOW}Default credentials:${NC}"
echo " Username: admin"
echo " Password: admin"
echo
echo -e "${YELLOW}Next steps:${NC}"
echo "1. Change the default admin password"
echo "2. Configure GitHub/GitLab integration in Administration > Configuration"
echo "3. Set up webhooks in your Git provider"
echo "4. Create projects and enable branch analysis"
echo
echo -e "${YELLOW}Logs location:${NC} /opt/sonarqube/logs/"
Review the script before running. Execute with: bash install.sh