Configure RhodeCode Extensions

To get the the built in plugins and extensions working the way you want them to, you have to configure them to work with your services. An overview of what needs to be done is:

  • Tweak a Default Plugin to carry out your desired actions once its hook is triggered. There are default actions built in, but you may wish to alter those.
  • Configure a Hook to execute actions for the plugin, when certain actions are carried out with RhodeCode Enterprise.

Tweak a Default Plugin

Each of the default plugins comes with a standard configuration, but you may wish to change those settings. In this example, the Redmine plugin watches for the words defined in the HASH_REGEX variable and takes actions if one of those words is used in conjunction with a #{number}, which matches a ticket number in Redmine. You can configure this to work differently based on the Redmine documentation.

 import re

 HASH_REGEX = re.compile(
     r"(?:fix|fixes|fixing|close|closes|closing)\s*#([0-9]+)\b",
     re.IGNORECASE)


 def link_to_commit(repo_url, commit_id):
     rev_url = '%s/changeset/%s' % (repo_url, commit_id)
     return '"%s":%s' % (commit_id[:6], rev_url)


 def run(*args, **kwargs):
     issues = kwargs['RM_ISSUES']
     if not issues:
         return 0

     # repo extra fields can control this, they should be propagated with
     # extract repo fields
     tracker_url = kwargs.get('redmine_tracker_url') or kwargs['RM_URL']
     project_id = kwargs.get('redmine_project_id') or kwargs['RM_PROJECT']
     api_key = kwargs.get('redmine_api_key') or kwargs['RM_APIKEY']

     if project_id:
         from redmine import Redmine
         remote_redmine = Redmine(tracker_url, key=api_key)
         project = remote_redmine.project.get(project_id)
         repo_url = '%(server_url)s/%(repository)s' % kwargs
         # for each fetched issue id make a redmine api call
         for _id, details in issues.items():
             commits = ', '.join([link_to_commit(repo_url,
                                                 x['raw_id'],)
                                                 for x in details])
             issue = project.issues.get(int(_id))
             if issue:
                 issue.notes = 'Issue resolved by %s' % (commits,)
                 issue.status_id = 3  # Resolved
                 issue.save()

Configure a Hook

To configure the default hooks in the /home/user/.rccontrol/instance-id/rcextensions/__init.py__ file, use the following steps.

  1. Configure the connection details, either in the file or import from a dictionary. For these connection scenarios the following details need to be configured.
  • REDMINE_URL = ‘<redmine-url>’
  • REDMINE_API_KEY = ‘<secret>’
  • SLACK_API_URL = ‘<slack-url>?token=<secret>’
  • SLACK_API_KEY = ‘<secret>’
  1. You will also need to configure other variables, such as the SLACK_ROOM or RM_PROJECT (Redmine Project). These set where the commit message is posted. Various hooks can take different variables and they are documented in the file.
  2. Inside each hook you can then configure it to carry out actions per service. In this example, the push hook is pushing to the Redmine and Slack plugins on each push if the hook criteria are matched.
 def _push_hook(*args, **kwargs):
     kwargs['commit_ids'] = kwargs['pushed_revs']

     call = load_extension('extra_fields.py')
     if call:
         repo_extra_fields = call(**kwargs)
         # now update if we have extra fields, they have precedence
         # this way users can store any configuration inside
         # the database per repo
         for key, data in repo_extra_fields.items():
             kwargs[key] = data['field_value']

     # fetch pushed commits
     call = load_extension('extract_commits.py')
     extracted_commits = {}
     if call:
         extracted_commits = call(**kwargs)
         # store the commits for the next call chain
     kwargs['COMMITS'] = extracted_commits

     # slack !
     call = load_extension('slack.py')
     if call:
         kwargs['INCOMING_WEBHOOK_URL'] = SLACK_API_URL
         kwargs['SLACK_TOKEN'] = SLACK_API_KEY
         kwargs['SLACK_ROOM'] = '#slack-channel'
         kwargs['SLACK_FROM'] = 'Slack-Message-Poster'
         kwargs['SLACK_FROM_ICON_EMOJI'] = ':slack-emoji:'
         call(**kwargs)

     # fetch issues from given commits
     call = load_extension('extract_issues.py')
     issues = {}
     if call:
         issues = call(**kwargs)

     # redmine smart commits
     call = load_extension('redmine_smart_commits.py')
     if call:
         kwargs['RM_URL'] = REDMINE_URL
         kwargs['RM_APIKEY'] = REDMINE_API_KEY
         kwargs['RM_PROJECT'] = None  # uses extra_fields from repo
         kwargs['RM_ISSUES'] = issues
         call(**kwargs)

     return 0
 PUSH_HOOK = _push_hook