Enable Dark Mode!
how-to-set-up-github-webhooks-for-automatic-odoo-updates.jpg
By: Najiya Rafi

How to Set Up GitHub Webhooks for Automatic Odoo Updates

Technical Odoo 19 Odoo Enterprises Odoo Community

Manual implementation of changes on the Odoo 19 server can become repetitive very soon.

  1. Typical flow for that process:
  2. Code pushed on GitHub by developer.
  3. Connection to the server.
  4. Fetching the latest code.
  5. Odoo restarts.
  6. Module upgrade.
  7. Verification of the deployment.

In the case of a small project, this can be fine. However, as the development frequency goes up, manual execution of such a process brings some downtime and possible errors.

A much more efficient way would be to have GitHub inform about pushed code automatically on the Odoo server.

That is what GitHub Webhooks are for.

What is a Github Webhook?

GitHub webhook offers an easy means of sending notifications to other servers every time there is a change or any event in your git repository.

From this blog post, we are going to set up a webhook flow for Odoo 19.

We can develop a module for github webhook and offer a github push that triggers our Odoo webhook, and our code will result in a pop-up notification from the Odoo browser.

The reason why our odoo instance is running locally at:

http://localhost:8019

GitHub cannot directly access this address because localhost is only accessible from the local machine.

To allow GitHub to send webhook requests to our local Odoo server, we need to create a temporary public URL that forwards requests to the local Odoo instance.

For this, we can use either ngrok or Cloudflare Tunnel (cloudflared).

I have used cloudfared for now.

Install cloudflared and in the terminal provide the command.

cloudflared tunnel --url http://localhost:8019

This provides a public URL such as

https://replacement-task-gamecube-relations.trycloudflare.com/github/webhook (refer the image)

How to Set Up GitHub Webhooks for Automatic Odoo Updates-cybrosys

We can then configure the GitHub webhook using this link.

Configure Github Webhook

To configure the webhook, open the GitHub repository and go to the settings of the repo your custom code is linked to.

How to Set Up GitHub Webhooks for Automatic Odoo Updates-cybrosys

Click on webhooks.

How to Set Up GitHub Webhooks for Automatic Odoo Updates-cybrosys

Click on 'Add webhook'.

How to Set Up GitHub Webhooks for Automatic Odoo Updates-cybrosys

Here, you can provide the necessary details and create a webhook.

In the Payload URL field, enter the public URL generated by ngrok or Cloudflare, followed by the Odoo webhook route:

https://replacement-task-gamecube-relations.trycloudflare.com/github/webhook

Set the Content type to:

application/json

You can also add a secret which is used to verify that the webhook request actually came from GitHub and has not been modified.

You can generate a random number as a secret and place it in both places:

  1. GitHub Webhook > Secret
  2. Odoo server environment > GITHUB_WEBHOOK_SECRET

In the case of vs code, we can provide the GITHUB_WEBHOOK_SECRET in the launch.json.

How to Set Up GitHub Webhooks for Automatic Odoo Updates-cybrosys

In the case of pycharm, go to:

Run > Edit Configurations

Select the configuration you use to start Odoo.

How to Set Up GitHub Webhooks for Automatic Odoo Updates-cybrosys

Click save and restart odoo.

This is important because environment variables are loaded when the Odoo process starts.

Paste this secret in the webhook configuration and click on ‘add webhook’

How to Set Up GitHub Webhooks for Automatic Odoo Updates-cybrosys

Now, let's create the webhook module.

How to Set Up GitHub Webhooks for Automatic Odoo Updates-cybrosys

Controllers > webhook.py

Import hashlib
import hmac
import json
import os
from odoo import api, http, SUPERUSER_ID
from odoo.http import request
from odoo.modules.registry import Registry

class GitHubWebhookController(http.Controller):
   @http.route(
       "/github/webhook",
       type="http",
       auth="none",
       methods=["POST"],
       csrf=False,
   )
   def github_webhook(self, **kwargs):
       # Get webhook secret
       secret = os.environ.get("GITHUB_WEBHOOK_SECRET")
       if not secret:
           return http.Response(
               "Webhook secret is not configured",
               status=500,
           )
       # Get raw GitHub payload
       payload = request.httprequest.get_data()
       # Get GitHub signature
       signature = request.httprequest.headers.get(
           "X-Hub-Signature-256"
       )
       if not signature:
           return http.Response(
               "Missing signature",
               status=401,
           )
       # Calculate expected signature
       expected_signature = (
           "sha256="
           + hmac.new(
               secret.encode(),
               payload,
               hashlib.sha256,
           ).hexdigest()
       )
       # Verify signature
       if not hmac.compare_digest(
           signature,
           expected_signature,
       ):
           return http.Response(
               "Invalid signature",
               status=401,
           )
       # Check GitHub event
       event = request.httprequest.headers.get(
           "X-GitHub-Event"
       )
       if event != "push":
           return http.Response(
               "Ignored event",
               status=200,
           )
       # Parse JSON payload
       try:
           data = json.loads(payload)
       except json.JSONDecodeError:
           return http.Response(
               "Invalid JSON",
               status=400,
           )
       # Check branch
       ref = data.get("ref", "")
       if ref != "refs/heads/blogs-n-apps":
           return http.Response(
               "Ignored branch",
               status=200,
           )
       # Get commit information
       commit = data.get("head_commit") or {}
       commit_id = commit.get("id", "")[:8]
       commit_message = commit.get(
           "message",
           "",
       )
       author = (
           commit.get("author", {}).get("name")
           or "Unknown"
       )
       # ---------------------------------------------------------
       # Connect explicitly to the Odoo database
       # ---------------------------------------------------------
       db_name = "blog-test"
       with Registry(db_name).cursor() as cr:
           env = api.Environment(
               cr,
               SUPERUSER_ID,
               {},
           )
           # Find all internal users
           users = env["res.users"].search([
               ("share", "=", False),
           ])
           # Notification message
           message = (
               f"New code was pushed to blogs-n-apps.\n"
               f"Commit: {commit_id}\n"
               f"Author: {author}\n"
               f"Message: {commit_message}"
           )
           # Send notification to each internal user
           for user in users:
               if not user.partner_id:
                   continue
               env["bus.bus"]._sendone(
                   user.partner_id,
                   "simple_notification",
                   {
                       "type": "info",
                       "title": "GitHub Update",
                       "message": message,
                       "sticky": False,
                   },
               )
           # Commit the transaction
           cr.commit()
       return http.Response(
           "Notification sent",
           status=200,
       )

In the manifest.py.

   "name": "GitHub Webhook",
   "version": "19.0.1.0.0",
   "category": "Tools",
   "depends": [
       "base",
       "web",
       "bus",
   ],
   "installable": True,
   "application": False,
}

You can now install the module in Odoo. It will be available under the Apps section, but it will not appear as an app icon or as a visible application tile on the Apps dashboard (since we intended that way).

Now, whenever we push to GitHub, a pop-up notification will appear in Odoo.

How to Set Up GitHub Webhooks for Automatic Odoo Updates-cybrosys

By connecting GitHub Webhooks with Odoo, we can receive real-time notifications whenever code is pushed to a specific branch. Using a secure webhook secret and a public tunnel such as Cloudflare Tunnel or ngrok, the local Odoo server can receive GitHub events and display them as notifications to users. This provides a simple foundation for future GitHub–Odoo automation.

To read more about How to Create Webhooks in Odoo 19, refer to our blog, How to Create Webhooks in Odoo 19.


Frequently Asked Questions

Why do we need ngrok or Cloudflare Tunnel?

GitHub needs a publicly accessible URL to send webhook requests. Since Odoo is running locally, ngrok or Cloudflare Tunnel provides a temporary public URL that forwards requests to the local Odoo server.

Why is a webhook secret required?

The secret allows Odoo to verify that the webhook request came from GitHub. Odoo compares the signature generated by GitHub with its own signature before processing the request.

Can the webhook listen to only one GitHub branch?

Yes. The webhook can check the branch name and process notifications only for a specific branch, such as blogs-n-apps.

What happens when code is pushed to the configured branch?

GitHub sends a webhook request to Odoo. Odoo verifies the request, reads the commit details, and sends a real-time notification to the logged-in Odoo users.

Does this setup automatically update the Odoo code?

No. The current implementation only sends a notification when a push occurs. It does not pull the latest code, upgrade modules, or restart Odoo automatically.

If you need any assistance in odoo, we are online, please chat with us.



0
Comments



Leave a comment



WhatsApp