GitHub Webhooks - Java

Snippet Git

Java Spring Boot implementation for GitHub webhooks with signature verification and deployment

What is this? Official Docs

Event notification system that triggers HTTP callbacks when repository events occur on GitHub.

What is GitHub Webhooks?

GitHub Webhooks allow you to receive real-time HTTP notifications when events occur in your repositories. This guide shows Java Spring Boot implementation with HMAC signature verification for secure automated deployments.


☕ Java - Basic Handler

Spring Boot REST controller for handling GitHub webhooks.

@RestController
public class WebhookController {
    private static final String SECRET = "your_secret";

    @PostMapping("/webhook")
    public String handle(HttpServletRequest req) throws IOException {
        String payload = readPayload(req);
        String signature = req.getHeader("X-Hub-Signature-256");

        if (!verifySignature(signature, payload)) {
            return "Invalid signature";
        }

        String event = req.getHeader("X-GitHub-Event");
        if ("push".equals(event)) {
            runDeployScript();
        }
        return "OK";
    }
}

📖 Java - Read Payload

Read the request body for signature verification.

private String readPayload(HttpServletRequest request) throws IOException {
    StringBuilder payload = new StringBuilder();
    try (BufferedReader reader = request.getReader()) {
        String line;
        while ((line = reader.readLine()) != null) {
            payload.append(line);
        }
    }
    return payload.toString();
}

🔐 Java - Verify Signature

Verify GitHub webhook signature using HMAC SHA-256.

private boolean verifySignature(String signature, String payload) {
    if (signature == null) return false;

    String expected = "sha256=" +
        Hex.encodeHexString(HmacUtils.hmacSha256(SECRET, payload));

    return expected.equals(signature);
}

Dependencies:

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
</dependency>

🚀 Java - Deploy Script

Execute deployment script when webhook is received.

private void runDeployScript() {
    try {
        ProcessBuilder pb = new ProcessBuilder(
            "/bin/bash", "/path/to/deploy.sh"
        );
        pb.start();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

✅ Java - Complete Example

Full working Spring Boot webhook handler.

import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.HmacUtils;
import java.io.BufferedReader;
import java.io.IOException;

@RestController
public class GithubWebhookController {

    private static final String SECRET = "YOUR_WEBHOOK_SECRET";

    @PostMapping("/webhook")
    public String handleWebhook(HttpServletRequest request) throws IOException {

        // Read payload
        StringBuilder payload = new StringBuilder();
        try (BufferedReader reader = request.getReader()) {
            String line;
            while ((line = reader.readLine()) != null) {
                payload.append(line);
            }
        }

        // Verify signature (X-Hub-Signature-256)
        String signature = request.getHeader("X-Hub-Signature-256");
        if (!verifySignature(signature, payload.toString())) {
            return "Invalid signature";
        }

        String event = request.getHeader("X-GitHub-Event");

        if ("push".equals(event)) {
            // Execute deployment script or command
            runDeployScript();
        }

        return "OK";
    }

    private boolean verifySignature(String signature, String payload) {
        if (signature == null) return false;

        String expected = "sha256=" +
                Hex.encodeHexString(HmacUtils.hmacSha256(SECRET, payload));

        return expected.equals(signature);
    }

    private void runDeployScript() {
        try {
            ProcessBuilder pb = new ProcessBuilder(
                "/bin/bash", "/path/to/deploy.sh"
            );
            pb.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

▶️ Run Application

Run the Spring Boot application.

# Run via JAR
java -jar target/yourapp.jar

Production Options:

  • Tomcat
  • Docker
  • systemd service

📦 Maven Dependencies

Add required dependencies to pom.xml.

<dependencies>
    <!-- Spring Boot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Apache Commons Codec for HMAC -->
    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
    </dependency>
</dependencies>

⚙️ Application Properties

Configure server port in application.properties.

server.port=8080

🐳 Docker Deployment

Containerize the Spring Boot webhook handler.

FROM openjdk:17-slim
COPY target/webhook-handler.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]

Build and run:

docker build -t github-webhook .
docker run -p 8080:8080 -e SECRET=your_secret github-webhook

🔧 Systemd Service

Run as a systemd service on Linux.

Create /etc/systemd/system/github-webhook.service:

[Unit]
Description=GitHub Webhook Handler
After=network.target

[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/webhook
ExecStart=/usr/bin/java -jar /opt/webhook/app.jar
Restart=on-failure

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl enable github-webhook
sudo systemctl start github-webhook