Push Hook Issues

Trying to get the push hooks working in rcextensions with git repositories. Essentially on every push to any repository we want to run a hook script that does a git checkout using the repository name to update the staging server. So we made the below changes to rcextensions/init.py:

  @register('PUSH_HOOK')
  @verify_kwargs(
  ['_load_extension', 'server_url', 'config', 'scm', 'username',
   'ip', 'action', 'repository', 'repo_store_path', 'pushed_revs'])
  def _push_hook(*args, **kwargs):
  """
  POST PUSH HOOK, this function will be executed after each push it's
  executed after the build-in hook that RhodeCode uses for logging pushes
  kwargs available:

  :param server_url: url of instance that triggered this hook
  :param config: path to .ini config used
  :param scm: type of VS 'git' or 'hg'
  :param username: name of user who pushed
  :param ip: ip of who pushed
  :param action: push
  :param repository: repository name
  :param repo_store_path: full path to where repositories are stored
  :param pushed_revs: list of pushed commit ids
  """
  call = load_extension('post_push.py')
  if call:
    call(**kwargs)

  return 0
PUSH_HOOK = _push_hook

Here’s our post_push.py script (it essentially just grabs the repository name and does a git checkout so we can preview the changes live on a staging server on push):

# -*- coding: utf-8 -*-
"""
us in hooks::

  call = load_extension('post_push.py')
  if call:
    # returns a dictionary with serialized extra field as a value
    post_push = call(**kwargs)

"""

import os, shutil
from subprocess import call

def run(*args, **kwargs):
  from rhodecode.model.db import Repository
  # use temp name then the main one propagated
  repo_name = kwargs.pop('REPOSITORY', None) or kwargs['repository']


  # Create repository website directory if it does not exist
  DIR_NAME = "/var/www/"+repo_name
  if not os.path.isdir(DIR_NAME):
    os.mkdir(DIR_NAME)

  # Checkout newest revision
  call(["git", "--work-tree="+DIR_NAME, "--git-dir=/var/repos/"+repo_name, "checkout", "-f"])

  # Try to create the dev FQDN (i.e. inject .dev after projectname/period)
  insertloc = repo_name.find(".")
  if insertloc > 0:
    dev_repo_name = repo_name[:insertloc]+".dev"+repo_name[insertloc:]

    # Create dev repository website directory if it does not exist
    DEV_DIR_NAME = "/var/www/"+dev_repo_name
    if not os.path.isdir(DEV_DIR_NAME):
      os.mkdir(DEV_DIR_NAME)

    # Checkout newest dev revision
    call(["git", "--work-tree="+DEV_DIR_NAME, "--git-dir=/var/repos/"+repo_name, "checkout", "develop", "-f"])

  return 0

The problem is that it doesn’t seem to run all the time. Sometimes it works for some repositories but silently doesn’t do anything for others. We’re running “git push origin master” from the client when we want it to do the update. We’ve double-checked permissions and everything there looks good. Nothing in the log files seems to indicate anything either…

Any ideas?

Thanks!

-rob

Hi Rob,

What version of RhodeCode are you using ? Please upgrade if not using 4.6.X version.

I think it can be related to some of hooks in repos are outdated, in such case
please run remap&rescann from admin selecting both checkboxes, this will ensure all repos have proper git-hooks (that execute those inside rcextensions)

  • Alternatively you can use the integration web-hook that runs a HTTP call instead of rcextensions.

Thanks Marcin. The remap and rescan fixed the problem and now the hooks appear to be running. Feel free to include the hook code above into the documentation on hooks - I bet others would find it useful. Appreciate all the hard work you do on RhodeCode!

Hi Rob, happy that it fixed.

Btw, just as a tip, you can use repository extra_fields to potentially save additional attrbiutes, such as dev_repo_name, in case that comes in handy.

I’ll fetch such example, or even maybe we make it a plugin called checkout_repo or something like that, i think it’s common case.