diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketBuildStatusNotifications.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketBuildStatusNotifications.java index 9d961dbaa..5a667f793 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketBuildStatusNotifications.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketBuildStatusNotifications.java @@ -165,11 +165,6 @@ private static void createStatus(@NonNull Run build, @NonNull TaskListener } } - private static @CheckForNull BitbucketSCMSource findBitbucketSCMSource(Run build) { - SCMSource s = SCMSource.SourceByItem.findSource(build.getParent()); - return s instanceof BitbucketSCMSource ? (BitbucketSCMSource) s : null; - } - private static void sendNotifications(BitbucketSCMSource source, Run build, TaskListener listener) throws IOException, InterruptedException { BitbucketSCMSourceContext sourceContext = new BitbucketSCMSourceContext(null, @@ -244,7 +239,7 @@ public static class JobCheckOutListener extends SCMListener { @Override public void onCheckout(Run build, SCM scm, FilePath workspace, TaskListener listener, File changelogFile, SCMRevisionState pollingBaseline) throws Exception { - BitbucketSCMSource source = findBitbucketSCMSource(build); + BitbucketSCMSource source = BitbucketSCMSource.findForRun(build); if (source == null) { return; } @@ -277,7 +272,7 @@ public static class JobCompletedListener extends RunListener> { @Override public void onCompleted(Run build, TaskListener listener) { - BitbucketSCMSource source = findBitbucketSCMSource(build); + BitbucketSCMSource source = BitbucketSCMSource.findForRun(build); if (source == null) { return; } diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java index 88f3dd2ea..3fcdb92ce 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java @@ -48,6 +48,7 @@ import com.cloudbees.jenkins.plugins.bitbucket.server.client.BitbucketServerAPIClient; import com.cloudbees.jenkins.plugins.bitbucket.server.client.repository.BitbucketServerRepository; import com.cloudbees.plugins.credentials.CredentialsNameProvider; +import com.cloudbees.plugins.credentials.CredentialsProvider; import com.cloudbees.plugins.credentials.common.StandardCredentials; import com.damnhandy.uri.template.UriTemplate; import com.fasterxml.jackson.databind.util.StdDateFormat; @@ -62,6 +63,7 @@ import hudson.model.Action; import hudson.model.Actionable; import hudson.model.Item; +import hudson.model.Run; import hudson.model.TaskListener; import hudson.plugins.git.GitSCM; import hudson.scm.SCM; @@ -569,6 +571,8 @@ public void afterSave() { protected void retrieve(@CheckForNull SCMSourceCriteria criteria, @NonNull SCMHeadObserver observer, @CheckForNull SCMHeadEvent event, @NonNull TaskListener listener) throws IOException, InterruptedException { + + trackCredentialsUsage(); try (BitbucketSCMSourceRequest request = new BitbucketSCMSourceContext(criteria, observer) .withTraits(traits) .newRequest(this, listener)) { @@ -823,9 +827,19 @@ private void retrieveTags(final BitbucketSCMSourceRequest request) throws IOExce request.listener().getLogger().format("%n %d tags were processed%n", count); } + private void trackCredentialsUsage() { + final SCMSourceOwner owner = getOwner(); + if (owner != null) { + CredentialsProvider.track(owner, credentials()); + } + } + @Override protected SCMRevision retrieve(SCMHead head, TaskListener listener) throws IOException, InterruptedException { final BitbucketApi bitbucket = buildBitbucketClient(); + + trackCredentialsUsage(); + try { if (head instanceof PullRequestSCMHead) { PullRequestSCMHead h = (PullRequestSCMHead) head; @@ -1225,6 +1239,11 @@ public static void setEventDelaySeconds(int eventDelaySeconds) { BitbucketSCMSource.eventDelaySeconds = Math.min(300, Math.max(0, eventDelaySeconds)); } + public static BitbucketSCMSource findForRun(Run run) { + SCMSource s = SCMSource.SourceByItem.findSource(run.getParent()); + return s instanceof BitbucketSCMSource ? (BitbucketSCMSource) s : null; + } + private void initCloneLinks() { if (primaryCloneLinks == null) { BitbucketApi bitbucket = buildBitbucketClient(); diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/CredentialTrackingRunListener.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/CredentialTrackingRunListener.java new file mode 100644 index 000000000..920f4f1bc --- /dev/null +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/CredentialTrackingRunListener.java @@ -0,0 +1,27 @@ +package com.cloudbees.jenkins.plugins.bitbucket; + +import com.cloudbees.plugins.credentials.CredentialsProvider; +import hudson.Extension; +import hudson.model.Run; +import hudson.model.listeners.RunListener; + +/** + * Tracks the usage of credentials + */ +@Extension +public class CredentialTrackingRunListener extends RunListener> { + @Override + public void onInitialize(Run run) { + final BitbucketSCMSource source = BitbucketSCMSource.findForRun(run); + + if (source == null) { + return; + } + + final boolean usesSshCheckout = source.getTraits().stream().anyMatch(scmSourceTrait -> scmSourceTrait instanceof SSHCheckoutTrait); + + if (!usesSshCheckout) { + CredentialsProvider.track(run, source.credentials()); + } + } +}