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
Community moderators have prevented the ability to post new answers.
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 ");
}
}
}
Does this run correctly if the pull request is merged on the web interface with the "Merge" button?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.