package com.mhackner.bamboo;

import com.atlassian.bamboo.chains.Chain;
import com.atlassian.bamboo.chains.ChainExecution;
import com.atlassian.bamboo.plugins.git.GitHubRepository;
import com.atlassian.bamboo.repository.RepositoryDefinition;
import com.atlassian.bamboo.security.EncryptionService;
import com.atlassian.bamboo.util.Narrow;
import com.atlassian.sal.api.ApplicationProperties;

import org.apache.commons.lang.StringUtils;
import org.kohsuke.github.GHCommitState;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GitHub;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;

public abstract class AbstractGitHubStatusAction {

    private static final Logger log = LoggerFactory.getLogger(AbstractGitHubStatusAction.class);

    private final ApplicationProperties applicationProperties;
    private final EncryptionService encryptionService;

    public AbstractGitHubStatusAction(ApplicationProperties applicationProperties,
                                      EncryptionService encryptionService) {
        this.applicationProperties = applicationProperties;
        this.encryptionService = encryptionService;
    }

    void updateStatus(GHCommitState status, Chain chain, ChainExecution chainExecution) {
        String disabled = chain.getBuildDefinition().getCustomConfiguration()
                .get("custom.gitHubStatus.disabled");
        if (Boolean.parseBoolean(disabled)) {
            return;
        }

        List<RepositoryDefinition> repos = chain.getEffectiveRepositoryDefinitions();
        if (repos.size() != 1) {
            log.warn("Wanted 1 repo but found {}. Not updating GitHub status.", repos.size());
            return;
        }

        RepositoryDefinition repoDefinition = repos.get(0);
        GitHubRepository repo = Narrow.downTo(repoDefinition.getRepository(),
                GitHubRepository.class);
        if (repo == null) {
            log.info("Repo {} is not a GitHub repo.", repoDefinition.getName());
            return;
        }

        String sha = chainExecution.getBuildChanges().getVcsRevisionKey(repoDefinition.getId());

        @SuppressWarnings("deprecation")
        String url = String.format("%s/browse/%s",
                StringUtils.removeEnd(applicationProperties.getBaseUrl(), "/"),
                chainExecution.getPlanResultKey());

        setStatus(status, sha, url, repo.getUsername(),
                encryptionService.decrypt(repo.getEncryptedPassword()),
                repo.getRepository());
    }

    private static void setStatus(GHCommitState status, String sha, String url, String user,
                                  String pass, String repo) {
        try {
            GitHub gitHub = GitHub.connectUsingPassword(user, pass);
            GHRepository repository = gitHub.getRepository(repo);
            repository.createCommitStatus(sha, status, url, null);
            log.info("GitHub status for commit {} set to {}.", sha, status);
        } catch (IOException ex) {
            log.error("Failed to update GitHub status", ex);
        }
    }

}

@@ -2866,16 +2866,71 @@
 (repo);%0A
+            sha = repository.getCommit(sha).getSHA1();%0A
         

Normalize SHA to 40 characters so custom revisions work