Is there a way to enable the 'Reject Force Push' hook for every repository in Stash?

SA November 11, 2013

I would like to be able to set the 'Reject Force Push' hook enabled for every repository we currently have, and also to have it set as the default for all repositories created in the future.

Is this possible, or would I need to do it manually in each existing project?

5 answers

1 accepted

1 vote
Answer accepted
SA November 12, 2013

Thanks, I came up with this Python 3 script which loops through the first 100 repositories and sets the hook to enabled:

import urllib.request, json

request = urllib.request.Request('http://stash.example.com/rest/api/1.0/repos?limit=100')
base64string = 'base64_encoded username:password'
request.add_header("Authorization","Basic %s" % base64string)
result = urllib.request.urlopen(request)
jsonresult = json.loads(result.read().decode('utf-8'))

for j in jsonresult['values']:
    print(j['slug'])
    enableHookUrl = "http://stash.example.com/rest/api/1.0/projects/%s/repos/%s/settings/hooks/com.atlassian.stash.stash-bundled-hooks:force-push-hook/enabled" %  (j['project']['key'], j['slug'])
    enableRequest = urllib.request.Request(enableHookUrl,data=b"")
    enableRequest.add_header("Authorization","Basic %s" % base64string)
    enableRequest.add_header("Content-Type", "application/json")
    enableRequest.get_method = lambda:'PUT'
    enableResult = urllib.request.urlopen(enableRequest)

Adam Downer April 13, 2014

I think this script would enable the hook on user repos as well. not sure you would want to do this.

1 vote
Alexey_Efimov
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 12, 2013

There are REST API to enable hook:

https://stash.acme.com/rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/settings/hooks/{hookKey}/enabled

Where:

  • {projectKey} -- one of you project
  • {repositorySlug} -- short name of repo
  • {hookKey} -- com.atlassian.stash.stash-bundled-hooks:force-push-hook (in your case)

From description:

Enable a repository hook for this repositories and optionally applying new configuration.

The authenticated user must have REPO_ADMIN permission for the specified repository to call this resource.

You can also use REST to get list of all repos/projects in your Stash.

0 votes
Faik Uygur January 20, 2015

I have used an open source python plugin written for Stash API:

https://github.com/RisingOak/stashy

import stashy
stash = stashy.connect("http://localhost:7990/stash", "admin", "admin")

stash.projects[PROJECT_KEY].repos[REPO_NAME].settings.hooks["com.atlassian.stash.stash-bundled-hooks:force-push-hook"].enable()

You can easily loop through the projects and the repos under those projects. After that, turning this script into a cron job seems to be the only viable solution.

 

 

0 votes
Bob Swift OSS (Bob Swift Atlassian Apps)
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
December 15, 2014

This is a bit late, but, I just saw this - it might help others:

You can use Stash Command Line Interface (CLI) action enableHook and combine that with runFromRepositoryList to hit everything. 

stash --action runFromProjectList --common "--action runFromRepositoryList --project @project@ --common \"--action enableHook --hook com.atlassian.stash.stash-bundled-hooks:force-push-hook --project @project@ --repository @repository@\" "
0 votes
Adam Downer April 13, 2014

As an alternative to the above, I have added a ruby version here with a few elements commented out. This one will only set the hook on the main repos, not users forks or other user repos as denoted by the '~' in the key. There is a line at the begining for retriving the repos details but I had trouble with this as it did not appear to be returning proper json to my ruby script (even though it is responding with 'application/json' content) but this is likely my bad coding rather than stash. enjoy

require 'net/http'
require 'open-uri'
require 'rubygems'
require 'json'

#content = open("http://stash.example.com/rest/api/1.0/repos?limit=10000").read
#json = JSON.parse(content)

jsonFile = File.read('repos.json')
json = JSON.parse(jsonFile)

json['values'].each do |value|
        puts value['id']
        if value['project']['key'].include? '~'
#               puts "This is a private project"
#       elsif value['origin']['project']['isPersonal'] == false
#                puts "key is: #{value['origin']['project']['key']}"
#                puts "repo is: #{value['origin']['slug']}"
        else
#               puts "key is: #{value['project']['key']}"
#               puts "repo is: #{value['slug']}"
                hookURL = "http://stash.example.com/rest/api/1.0/projects/#{value['project']['key']}/repos/#{value['slug']}/settings/hooks/com.atlassian.stash.stash-bundled-hooks:force-push-hook/enabled"
#               puts hookURL

                uri = URI.parse(hookURL)
                http = Net::HTTP.new(uri.host, uri.port)
                request = Net::HTTP::Put.new(uri.request_uri)
                request.basic_auth("user", "pass")
                response = http.request(request)
                puts response
        end
end

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events