Search in sources :

Example 1 with SCMRevision

use of jenkins.scm.api.SCMRevision in project gitea-plugin by jenkinsci.

the class GiteaPullSCMEvent method headsFor.

/**
 * {@inheritDoc}
 */
@NonNull
@Override
public Map<SCMHead, SCMRevision> headsFor(GiteaSCMSource source) {
    Map<SCMHead, SCMRevision> result = new HashMap<>();
    try (GiteaSCMSourceRequest request = new GiteaSCMSourceContext(null, SCMHeadObserver.none()).withTraits(source.getTraits()).newRequest(source, null)) {
        if (!request.isFetchPRs()) {
            return result;
        }
        final GiteaPullRequest p = getPayload().getPullRequest();
        if (p == null) {
            // the pull request has been deleted, sadly we have no way to determine where the PR was from
            // so we just blast hit with all potential cases and using dummy values.
            // the values are not important as the event consumers will be matching on SCMHead.getName()
            // and so will see that there is a new "head" for the old name, reconfirm the revision
            // and find that the head no longer exists... and our job is done!
            Set<ChangeRequestCheckoutStrategy> strategies = EnumSet.noneOf(ChangeRequestCheckoutStrategy.class);
            if (request.isFetchForkPRs()) {
                strategies.addAll(request.getForkPRStrategies());
            }
            if (request.isFetchOriginPRs()) {
                strategies.addAll(request.getOriginPRStrategies());
            }
            for (ChangeRequestCheckoutStrategy strategy : strategies) {
                result.put(new PullRequestSCMHead("PR-" + getPayload().getNumber() + (strategies.size() > 1 ? "-" + strategy.name().toLowerCase(Locale.ENGLISH) : ""), getPayload().getNumber(), new BranchSCMHead("dummy-name"), ChangeRequestCheckoutStrategy.MERGE, SCMHeadOrigin.DEFAULT, source.getRepoOwner(), source.getRepository(), "dummy-name"), null);
            }
        } else {
            String originOwner = p.getHead().getRepo().getOwner().getUsername();
            String originRepository = p.getHead().getRepo().getName();
            Set<ChangeRequestCheckoutStrategy> strategies = request.getPRStrategies(!StringUtils.equalsIgnoreCase(source.getRepoOwner(), originOwner) && StringUtils.equalsIgnoreCase(source.getRepository(), originRepository));
            for (ChangeRequestCheckoutStrategy strategy : strategies) {
                PullRequestSCMHead h = new PullRequestSCMHead("PR-" + p.getNumber() + (strategies.size() > 1 ? "-" + strategy.name().toLowerCase(Locale.ENGLISH) : ""), p.getNumber(), new BranchSCMHead(p.getBase().getRef()), strategy, StringUtils.equalsIgnoreCase(originOwner, source.getRepoOwner()) && StringUtils.equalsIgnoreCase(originRepository, source.getRepository()) ? SCMHeadOrigin.DEFAULT : new SCMHeadOrigin.Fork(originOwner + "/" + originRepository), originOwner, originRepository, p.getHead().getRef());
                result.put(h, getPayload().getAction() == GiteaPullRequestEventType.CLOSED ? null : new PullRequestSCMRevision(h, new BranchSCMRevision(h.getTarget(), p.getBase().getSha()), new BranchSCMRevision(new BranchSCMHead(h.getOriginName()), p.getHead().getSha())));
            }
        }
    } catch (IOException e) {
    // ignore
    }
    return result;
}
Also used : SCMHead(jenkins.scm.api.SCMHead) HashMap(java.util.HashMap) IOException(java.io.IOException) ChangeRequestCheckoutStrategy(jenkins.scm.api.mixin.ChangeRequestCheckoutStrategy) SCMRevision(jenkins.scm.api.SCMRevision) GiteaPullRequest(org.jenkinsci.plugin.gitea.client.api.GiteaPullRequest) NonNull(edu.umd.cs.findbugs.annotations.NonNull)

Example 2 with SCMRevision

use of jenkins.scm.api.SCMRevision in project gitea-plugin by jenkinsci.

the class GiteaSCMSource method retrieve.

@Override
protected void retrieve(SCMSourceCriteria criteria, @NonNull SCMHeadObserver observer, SCMHeadEvent<?> event, @NonNull final TaskListener listener) throws IOException, InterruptedException {
    try (GiteaConnection c = gitea().open()) {
        listener.getLogger().format("Looking up repository %s/%s%n", repoOwner, repository);
        giteaRepository = c.fetchRepository(repoOwner, repository);
        sshRemote = giteaRepository.getSshUrl();
        if (giteaRepository.isEmpty()) {
            listener.getLogger().format("Repository %s is empty%n", repository);
            return;
        }
        try (GiteaSCMSourceRequest request = new GiteaSCMSourceContext(criteria, observer).withTraits(getTraits()).newRequest(this, listener)) {
            request.setConnection(c);
            if (request.isFetchBranches()) {
                request.setBranches(c.fetchBranches(giteaRepository));
            }
            if (request.isFetchPRs()) {
                if (giteaRepository.isMirror()) {
                    listener.getLogger().format("%n  Ignoring pull requests as repository is a mirror...%n");
                } else {
                    request.setPullRequests(c.fetchPullRequests(giteaRepository));
                }
            }
            if (request.isFetchBranches()) {
                int count = 0;
                listener.getLogger().format("%n  Checking branches...%n");
                for (final GiteaBranch b : c.fetchBranches(giteaRepository)) {
                    count++;
                    listener.getLogger().format("%n    Checking branch %s%n", HyperlinkNote.encodeTo(UriTemplate.buildFromTemplate(giteaRepository.getHtmlUrl()).literal("/src").path("branch").build().set("branch", b.getName()).expand(), b.getName()));
                    if (request.process(new BranchSCMHead(b.getName()), new SCMSourceRequest.RevisionLambda<BranchSCMHead, BranchSCMRevision>() {

                        @NonNull
                        @Override
                        public BranchSCMRevision create(@NonNull BranchSCMHead head) throws IOException, InterruptedException {
                            return new BranchSCMRevision(head, b.getCommit().getId());
                        }
                    }, new SCMSourceRequest.ProbeLambda<BranchSCMHead, BranchSCMRevision>() {

                        @NonNull
                        @Override
                        public SCMSourceCriteria.Probe create(@NonNull BranchSCMHead head, @Nullable BranchSCMRevision revision) throws IOException, InterruptedException {
                            return createProbe(head, revision);
                        }
                    }, new SCMSourceRequest.Witness() {

                        @Override
                        public void record(@NonNull SCMHead head, SCMRevision revision, boolean isMatch) {
                            if (isMatch) {
                                listener.getLogger().format("    Met criteria%n");
                            } else {
                                listener.getLogger().format("    Does not meet criteria%n");
                            }
                        }
                    })) {
                        listener.getLogger().format("%n  %d branches were processed (query completed)%n", count);
                        return;
                    }
                }
                listener.getLogger().format("%n  %d branches were processed%n", count);
            }
            if (request.isFetchPRs() && !giteaRepository.isMirror() && !(request.getForkPRStrategies().isEmpty() && request.getOriginPRStrategies().isEmpty())) {
                int count = 0;
                listener.getLogger().format("%n  Checking pull requests...%n");
                for (final GiteaPullRequest p : c.fetchPullRequests(giteaRepository, EnumSet.of(GiteaIssueState.OPEN))) {
                    if (p == null) {
                        continue;
                    }
                    count++;
                    listener.getLogger().format("%n  Checking pull request %s%n", HyperlinkNote.encodeTo(UriTemplate.buildFromTemplate(giteaRepository.getHtmlUrl()).literal("/pulls").path("number").build().set("number", p.getNumber()).expand(), "#" + p.getNumber()));
                    String originOwner = p.getHead().getRepo().getOwner().getUsername();
                    String originRepository = p.getHead().getRepo().getName();
                    Set<ChangeRequestCheckoutStrategy> strategies = request.getPRStrategies(!StringUtils.equalsIgnoreCase(repoOwner, originOwner) && StringUtils.equalsIgnoreCase(repository, originRepository));
                    for (ChangeRequestCheckoutStrategy strategy : strategies) {
                        if (request.process(new PullRequestSCMHead("PR-" + p.getNumber() + (strategies.size() > 1 ? "-" + strategy.name().toLowerCase(Locale.ENGLISH) : ""), p.getNumber(), new BranchSCMHead(p.getBase().getRef()), strategy, StringUtils.equalsIgnoreCase(originOwner, repoOwner) && StringUtils.equalsIgnoreCase(originRepository, repository) ? SCMHeadOrigin.DEFAULT : new SCMHeadOrigin.Fork(originOwner + "/" + originRepository), originOwner, originRepository, p.getHead().getRef()), new SCMSourceRequest.RevisionLambda<PullRequestSCMHead, PullRequestSCMRevision>() {

                            @NonNull
                            @Override
                            public PullRequestSCMRevision create(@NonNull PullRequestSCMHead head) throws IOException, InterruptedException {
                                return new PullRequestSCMRevision(head, new BranchSCMRevision(head.getTarget(), p.getBase().getSha()), new BranchSCMRevision(new BranchSCMHead(head.getOriginName()), p.getHead().getSha()));
                            }
                        }, new SCMSourceRequest.ProbeLambda<PullRequestSCMHead, PullRequestSCMRevision>() {

                            @NonNull
                            @Override
                            public SCMSourceCriteria.Probe create(@NonNull PullRequestSCMHead h, @Nullable PullRequestSCMRevision r) throws IOException, InterruptedException {
                                return createProbe(h, r);
                            }
                        }, new SCMSourceRequest.Witness() {

                            @Override
                            public void record(@NonNull SCMHead head, SCMRevision revision, boolean isMatch) {
                                if (isMatch) {
                                    listener.getLogger().format("    Met criteria%n");
                                } else {
                                    listener.getLogger().format("    Does not meet criteria%n");
                                }
                            }
                        })) {
                            listener.getLogger().format("%n  %d pull requests were processed (query completed)%n", count);
                            return;
                        }
                    }
                }
                listener.getLogger().format("%n  %d pull requests were processed%n", count);
            }
        }
    }
}
Also used : GiteaConnection(org.jenkinsci.plugin.gitea.client.api.GiteaConnection) SCMSourceRequest(jenkins.scm.api.trait.SCMSourceRequest) SCMProbe(jenkins.scm.api.SCMProbe) NonNull(edu.umd.cs.findbugs.annotations.NonNull) SCMHead(jenkins.scm.api.SCMHead) GiteaBranch(org.jenkinsci.plugin.gitea.client.api.GiteaBranch) IOException(java.io.IOException) ChangeRequestCheckoutStrategy(jenkins.scm.api.mixin.ChangeRequestCheckoutStrategy) SCMHeadOrigin(jenkins.scm.api.SCMHeadOrigin) SCMRevision(jenkins.scm.api.SCMRevision) GiteaPullRequest(org.jenkinsci.plugin.gitea.client.api.GiteaPullRequest)

Example 3 with SCMRevision

use of jenkins.scm.api.SCMRevision in project gitea-plugin by jenkinsci.

the class GiteaSCMBuilder method build.

/**
 * {@inheritDoc}
 */
@NonNull
@Override
public GitSCM build() {
    final SCMHead h = head();
    final SCMRevision r = revision();
    try {
        withGiteaRemote();
        if (h instanceof PullRequestSCMHead) {
            PullRequestSCMHead head = (PullRequestSCMHead) h;
            if (head.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.MERGE) {
                // add the target branch to ensure that the revision we want to merge is also available
                String name = head.getTarget().getName();
                String localName = "remotes/" + remoteName() + "/" + name;
                Set<String> localNames = new HashSet<>();
                boolean match = false;
                String targetSrc = Constants.R_HEADS + name;
                String targetDst = Constants.R_REMOTES + remoteName() + "/" + name;
                for (RefSpec b : asRefSpecs()) {
                    String dst = b.getDestination();
                    assert dst.startsWith(Constants.R_REFS) : "All git references must start with refs/";
                    if (targetSrc.equals(b.getSource())) {
                        if (targetDst.equals(dst)) {
                            match = true;
                        } else {
                            // pick up the configured destination name
                            localName = dst.substring(Constants.R_REFS.length());
                            match = true;
                        }
                    } else {
                        localNames.add(dst.substring(Constants.R_REFS.length()));
                    }
                }
                if (!match) {
                    if (localNames.contains(localName)) {
                        // conflict with intended name
                        localName = "remotes/" + remoteName() + "/upstream-" + name;
                    }
                    if (localNames.contains(localName)) {
                        // conflict with intended alternative name
                        localName = "remotes/" + remoteName() + "/pr-" + head.getId() + "-upstream-" + name;
                    }
                    if (localNames.contains(localName)) {
                        // ok we're just going to mangle our way to something that works
                        Random entropy = new Random();
                        while (localNames.contains(localName)) {
                            localName = "remotes/" + remoteName() + "/pr-" + head.getId() + "-upstream-" + name + "-" + Integer.toHexString(entropy.nextInt(Integer.MAX_VALUE));
                        }
                    }
                    withRefSpec("+refs/heads/" + name + ":refs/" + localName);
                }
                withExtension(new MergeWithGitSCMExtension(localName, r instanceof PullRequestSCMRevision ? ((BranchSCMRevision) ((PullRequestSCMRevision) r).getTarget()).getHash() : null));
            }
            if (r instanceof PullRequestSCMRevision) {
                withRevision(((PullRequestSCMRevision) r).getOrigin());
            }
        }
        return super.build();
    } finally {
        withHead(h);
        withRevision(r);
    }
}
Also used : RefSpec(org.eclipse.jgit.transport.RefSpec) SCMHead(jenkins.scm.api.SCMHead) Random(java.util.Random) SCMRevision(jenkins.scm.api.SCMRevision) MergeWithGitSCMExtension(jenkins.plugins.git.MergeWithGitSCMExtension) HashSet(java.util.HashSet) NonNull(edu.umd.cs.findbugs.annotations.NonNull)

Example 4 with SCMRevision

use of jenkins.scm.api.SCMRevision in project gitea-plugin by jenkinsci.

the class GiteaNotifier method sendNotifications.

/**
 * Sends notifications to Bitbucket on Checkout (for the "In Progress" Status).
 */
private static void sendNotifications(Run<?, ?> build, TaskListener listener) throws IOException, InterruptedException {
    final SCMSource s = SCMSource.SourceByItem.findSource(build.getParent());
    if (!(s instanceof GiteaSCMSource)) {
        return;
    }
    GiteaSCMSource source = (GiteaSCMSource) s;
    if (new GiteaSCMSourceContext(null, SCMHeadObserver.none()).withTraits(source.getTraits()).notificationsDisabled()) {
        return;
    }
    String url;
    try {
        url = DisplayURLProvider.get().getRunURL(build);
    } catch (IllegalStateException e) {
        listener.getLogger().println("Can not determine Jenkins root URL. Commit status notifications are disabled until a root URL is" + " configured in Jenkins global configuration.");
        return;
    }
    Result result = build.getResult();
    GiteaCommitStatus status = new GiteaCommitStatus();
    status.setTargetUrl(url);
    status.setContext(build.getParent().getFullName());
    if (Result.SUCCESS.equals(result)) {
        status.setDescription("This commit looks good");
        status.setState(GiteaCommitState.SUCCESS);
    } else if (Result.UNSTABLE.equals(result)) {
        status.setDescription("This commit has test failures");
        status.setState(GiteaCommitState.FAILURE);
    } else if (Result.FAILURE.equals(result)) {
        status.setDescription("There was a failure building this commit");
        status.setState(GiteaCommitState.FAILURE);
    } else if (result != null) {
        // ABORTED etc.
        status.setDescription("Something is wrong with the build of this commit");
        status.setState(GiteaCommitState.ERROR);
    } else {
        status.setDescription("Build started...");
        status.setState(GiteaCommitState.PENDING);
    }
    SCMRevision revision = SCMRevisionAction.getRevision(source, build);
    String hash;
    if (revision instanceof BranchSCMRevision) {
        listener.getLogger().format("[Gitea] Notifying branch build status: %s %s%n", status.getState().name(), status.getDescription());
        hash = ((BranchSCMRevision) revision).getHash();
    } else if (revision instanceof PullRequestSCMRevision) {
        listener.getLogger().format("[Gitea] Notifying pull request build status: %s %s%n", status.getState().name(), status.getDescription());
        hash = ((PullRequestSCMRevision) revision).getOrigin().getHash();
    } else {
        // TODO tags
        return;
    }
    JobScheduledListener jsl = ExtensionList.lookup(QueueListener.class).get(JobScheduledListener.class);
    if (jsl != null) {
        // we are setting the status, so don't let the queue listener background thread change it to pending
        synchronized (jsl.resolving) {
            jsl.resolving.remove(build.getParent());
        }
    }
    try (GiteaConnection c = source.gitea().open()) {
        int tries = 3;
        while (true) {
            tries--;
            try {
                c.createCommitStatus(source.getRepoOwner(), source.getRepository(), hash, status);
                break;
            } catch (GiteaHttpStatusException e) {
                if (e.getStatusCode() == 500 && tries > 0) {
                    // server may be overloaded
                    continue;
                }
                throw e;
            }
        }
        listener.getLogger().format("[Gitea] Notified%n");
    }
}
Also used : GiteaHttpStatusException(org.jenkinsci.plugin.gitea.client.api.GiteaHttpStatusException) QueueListener(hudson.model.queue.QueueListener) GiteaCommitStatus(org.jenkinsci.plugin.gitea.client.api.GiteaCommitStatus) GiteaConnection(org.jenkinsci.plugin.gitea.client.api.GiteaConnection) SCMSource(jenkins.scm.api.SCMSource) Result(hudson.model.Result) SCMRevision(jenkins.scm.api.SCMRevision)

Aggregations

SCMRevision (jenkins.scm.api.SCMRevision)4 NonNull (edu.umd.cs.findbugs.annotations.NonNull)3 SCMHead (jenkins.scm.api.SCMHead)3 IOException (java.io.IOException)2 ChangeRequestCheckoutStrategy (jenkins.scm.api.mixin.ChangeRequestCheckoutStrategy)2 GiteaConnection (org.jenkinsci.plugin.gitea.client.api.GiteaConnection)2 GiteaPullRequest (org.jenkinsci.plugin.gitea.client.api.GiteaPullRequest)2 Result (hudson.model.Result)1 QueueListener (hudson.model.queue.QueueListener)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Random (java.util.Random)1 MergeWithGitSCMExtension (jenkins.plugins.git.MergeWithGitSCMExtension)1 SCMHeadOrigin (jenkins.scm.api.SCMHeadOrigin)1 SCMProbe (jenkins.scm.api.SCMProbe)1 SCMSource (jenkins.scm.api.SCMSource)1 SCMSourceRequest (jenkins.scm.api.trait.SCMSourceRequest)1 RefSpec (org.eclipse.jgit.transport.RefSpec)1 GiteaBranch (org.jenkinsci.plugin.gitea.client.api.GiteaBranch)1 GiteaCommitStatus (org.jenkinsci.plugin.gitea.client.api.GiteaCommitStatus)1