Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Stash plugin for that triggers a remote script when the Pull Request is merged.

Robert L. April 24, 2014

I'm looking for plugin or example code similar to External Hook plugin that triggers the external script after the Pull Request is merged. The External Hook plugin works great, but only when changes are pushed into Stash by git client.

Thank you,

Robert

1 answer

1 accepted

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

0 votes
Answer accepted
Robert L. April 27, 2014

Using some code I worked on in the past I have wrote a java class that does the job. Disclaimer, I'm not an advanced programmer, so this code may have some bugs and can probably be optimized.

PostReceiveRepositoryHook Class creates post-receive hook that triggers script after the code update is merged to branch. It works both with updates pushed via git push and merged pull requests.

- Create Stash plugin with post receive hook module and use the class below

- Set script path in the hook configuration. If Stash on Windows make sure to use double backslash

- Plugin will pass three arguments to the script: Stash Project Name, Repo Name and the branch that was just updated.

************************************************************

import com.atlassian.stash.hook.repository.*; //default
import com.atlassian.stash.repository.*; //default
import com.atlassian.stash.setting.*; //default
import com.atlassian.stash.repository.RefChange;
import com.atlassian.stash.repository.RefChangeType;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import java.net.URL; //default
import java.util.Collection; //default
import java.io.UnsupportedEncodingException;
import java.net.URLConnection;
import java.net.URLEncoder;

public class PostReceiveRepositoryHook implements AsyncPostReceiveRepositoryHook, RepositorySettingsValidator
{
private static final String REFS_HEADS = "refs/heads/";

}

@Override
public void postReceive(RepositoryHookContext context, Collection<RefChange> refChanges) {
String script = context.getSettings().getString("script");
String branch = urlEncode(Joiner.on(",").join(getUpdateBranches(refChanges)));
String repoName = context.getRepository().getSlug();
String projectKey = context.getRepository().getProject().getKey();
if (branch != null) {
try {
Process process = Runtime.getRuntime().exec(script + " " + projectKey + " " + repoName + " " + branch);

} catch (Exception e) {
e.printStackTrace();
}
}
}

private static String urlEncode(String string) {
try {
return URLEncoder.encode(string, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}


private Iterable<String> getUpdateBranches(Collection<RefChange> refChanges) {
return Iterables.transform(Iterables.filter(refChanges, new Predicate<RefChange>() {
@Override
public boolean apply(RefChange input) {
// We only care about non-deleted branches
return input.getType() != RefChangeType.DELETE && input.getRefId().startsWith(REFS_HEADS);
}
}), new Function<RefChange, String>() {
@Override
public String apply(RefChange input) {
return input.getRefId().replace(REFS_HEADS, "");
}
});
}


@Override
public void validate(Settings settings, SettingsValidationErrors errors, Repository repository) {
if (settings.getString("script", "").isEmpty()) {
errors.addFieldError("script", "Required Field empty - Script ");
}
}
}

Balázs Szakmáry
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.
April 27, 2014

Does this run correctly if the pull request is merged on the web interface with the "Merge" button?

Robert L. April 27, 2014

Yes, that was actually my use case.

TAGS
AUG Leaders

Atlassian Community Events