Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
JENKINS-43507: Script to capture pre- and post- upgrade state of Multibranch projects and organization folders
println("Organization folder last scan");
println("=============================");
println();
for (def i in Jenkins.instance.allItems) {
if (i instanceof jenkins.branch.OrganizationFolder) {
println("${i.fullName}: ${i.computation.timestamp.format('yyyy-MM-dd HH:mm:ss z')} ${i.computation.result}");
}
}
println();
println("Multibranch project last index and builds");
println("=========================================");
println();
for (def i in Jenkins.instance.allItems) {
if (i instanceof jenkins.branch.MultiBranchProject) {
def f = i.projectFactory;
println("${i.fullName}: ${i.computation.timestamp.format('yyyy-MM-dd HH:mm:ss z')} ${i.computation.result}");
for (def j in i.items) {
println(" ${j.name}: #${j.lastBuild.number} ${j.lastBuild.timestamp.format('yyyy-MM-dd HH:mm:ss z')} ${j.lastBuild.result}");
println(" causes: ${j.lastBuild.causes}");
println(" revision: ${f.getRevision(j)}");
}
}
}
println();
println("Organization folder configurations");
println("==================================");
println();
for (def i in Jenkins.instance.allItems) {
if (i instanceof jenkins.branch.OrganizationFolder) {
println("${i.fullName}:");
println();
for (def s in i.navigators) {
println(Items.XSTREAM2.toXML(s));
}
println();
}
}
println("Multibranch project configurations");
println("==================================");
println();
for (def i in Jenkins.instance.allItems) {
if (i instanceof jenkins.branch.MultiBranchProject) {
println("${i.fullName}:");
println();
for (def s in i.sources) {
println(Items.XSTREAM2.toXML(s.source));
}
def f = i.projectFactory;
for (def j in i.items) {
println();
println(" ${j.name}:");
println(" ${Items.XSTREAM2.toXML(f.getRevision(j)).replaceAll('\n','\n ')}");
}
println();
}
}
@stephenc
Copy link
Author

stephenc commented Jun 19, 2017

If you run this script you should get output something like the following:

Organization folder last scan
=============================

cloudbeers: 2017-06-19 05:23:00 UTC SUCCESS
...

Multibranch project last index and builds
=========================================

bb-c/demo-2017-03: 2017-06-19 07:13:24 UTC SUCCESS
  master: #1 2017-06-08 14:52:16 UTC SUCCESS
      causes: [jenkins.branch.BranchIndexingCause@511a448f]
      revision: 67188f81e06f884a196a87b52f3cda2408659285
...

Organization folder configurations
==================================

bb-c:

<com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMNavigator plugin="cloudbees-bitbucket-branch-source@2.1.2">
  <repoOwner>cloudbeers</repoOwner>
  <credentialsId>bitbucket-cloud</credentialsId>
  <checkoutCredentialsId>SAME</checkoutCredentialsId>
  <pattern>.*</pattern>
  <autoRegisterHooks>false</autoRegisterHooks>
  <sshPort>-1</sshPort>
  <includes>*</includes>
  <excludes></excludes>
</com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMNavigator>

cloudbeers:

<org.jenkinsci.plugins.github__branch__source.GitHubSCMNavigator plugin="github-branch-source@2.0.6">
  <repoOwner>cloudbeers</repoOwner>
  <scanCredentialsId>github</scanCredentialsId>
  <checkoutCredentialsId>SAME</checkoutCredentialsId>
  <pattern>.*</pattern>
  <buildOriginBranch>true</buildOriginBranch>
  <buildOriginBranchWithPR>true</buildOriginBranchWithPR>
  <buildOriginPRMerge>false</buildOriginPRMerge>
  <buildOriginPRHead>false</buildOriginPRHead>
  <buildForkPRMerge>true</buildForkPRMerge>
  <buildForkPRHead>false</buildForkPRHead>
</org.jenkinsci.plugins.github__branch__source.GitHubSCMNavigator>

...

Multibranch project configurations
==================================

bb-c/demo-2017-03:

<com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSource plugin="cloudbees-bitbucket-branch-source@2.1.2">
  <id>com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMNavigator::https://bitbucket.org::cloudbeers::demo-2017-03</id>
  <credentialsId>bitbucket-cloud</credentialsId>
  <checkoutCredentialsId>SAME</checkoutCredentialsId>
  <repoOwner>cloudbeers</repoOwner>
  <repository>demo-2017-03</repository>
  <includes>*</includes>
  <excludes></excludes>
  <autoRegisterHook>false</autoRegisterHook>
  <sshPort>-1</sshPort>
  <repositoryType>GIT</repositoryType>
</com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSource>

  master:
    <jenkins.plugins.git.AbstractGitSCMSource_-SCMRevisionImpl plugin="git@3.3.0">
      <head class="com.cloudbees.jenkins.plugins.bitbucket.BranchSCMHead" plugin="cloudbees-bitbucket-branch-source@2.1.2">
        <name>master</name>
        <repositoryType>GIT</repositoryType>
      </head>
      <hash>67188f81e06f884a196a87b52f3cda2408659285</hash>
    </jenkins.plugins.git.AbstractGitSCMSource_-SCMRevisionImpl>

cloudbeers/advanced:

<org.jenkinsci.plugins.github__branch__source.GitHubSCMSource plugin="github-branch-source@2.0.6">
  <id>org.jenkinsci.plugins.github_branch_source.GitHubSCMNavigator::https://api.github.com::cloudbeers::advanced</id>
  <checkoutCredentialsId>SAME</checkoutCredentialsId>
  <scanCredentialsId>github</scanCredentialsId>
  <repoOwner>cloudbeers</repoOwner>
  <repository>advanced</repository>
  <includes>*</includes>
  <excludes></excludes>
  <buildOriginBranch>true</buildOriginBranch>
  <buildOriginBranchWithPR>true</buildOriginBranchWithPR>
  <buildOriginPRMerge>false</buildOriginPRMerge>
  <buildOriginPRHead>false</buildOriginPRHead>
  <buildForkPRMerge>true</buildForkPRMerge>
  <buildForkPRHead>false</buildForkPRHead>
</org.jenkinsci.plugins.github__branch__source.GitHubSCMSource>

  master:
    <jenkins.plugins.git.AbstractGitSCMSource_-SCMRevisionImpl plugin="git@3.3.0">
      <head class="org.jenkinsci.plugins.github_branch_source.BranchSCMHead" plugin="github-branch-source@2.0.6">
        <name>master</name>
      </head>
      <hash>be584b471c5ff905cda3ccacf8201a654669fa0f</hash>
    </jenkins.plugins.git.AbstractGitSCMSource_-SCMRevisionImpl>

...

Before upgrading:

  1. Ensure that all organization folders and all standalone multibranch projects have a recent (ideally in the last hour) index / scan.
  2. Run this script in the script console. Capture the whole of the output and save it in a text file (call it pre-upgrade.txt).
  3. Upgrade the plugins and restart Jenkins.
  4. Run this script in the script console. Capture the whole of the output and save it in a text file (call it post-upgrade.txt).
  5. Trigger rescans on all organization folders and all standalone multibranch projects.
  6. Wait for the build queue to finish building (ideally only scanning / indexing was triggered)
  7. Run this script in the script console. Capture the whole of the output and save it in a text file (call it post-rescan.txt).

Now if you do a diff of the pre-upgrade.txt and the post-rescan.txt. We are looking for jobs that were rebuilt unnecessarily.
These jobs will show up in the Multibranch project last index and builds section. You are looking for the build number to increase, e.g. if you see:

$ diff -u pre-upgrade.txt post-rescan.txt 
--- pre-upgrade.txt	2017-06-19 14:24:28.000000000 +0100
+++ post-rescan.txt	2017-06-19 14:26:33.000000000 +0100

...
 
-bb-c/demo-2017-03: 2017-06-19 07:13:24 UTC SUCCESS
-  master: #1 2017-06-08 14:52:16 UTC SUCCESS
+bb-c/demo-2017-03: 2017-06-19 08:13:24 UTC SUCCESS
+  master: #2 2017-06-19 08:14:32 UTC SUCCESS
       causes: [jenkins.branch.BranchIndexingCause@511a448f]
       revision: 67188f81e06f884a196a87b52f3cda2408659285

This looks like an unnecessary rebuild as the revision remained unchanged, whereas with

$ diff -u pre-upgrade.txt post-rescan.txt 
--- pre-upgrade.txt	2017-06-19 14:24:28.000000000 +0100
+++ post-rescan.txt	2017-06-19 14:26:33.000000000 +0100

...
 
-bb-c/demo-2017-03: 2017-06-19 07:13:24 UTC SUCCESS
-  master: #1 2017-06-08 14:52:16 UTC SUCCESS
+bb-c/demo-2017-03: 2017-06-19 08:13:24 UTC SUCCESS
+  master: #2 2017-06-19 08:14:32 UTC SUCCESS
       causes: [jenkins.branch.BranchIndexingCause@511a448f]
-      revision: 67188f81e06f884a196a87b52f3cda2408659285
+      revision: d33e9557ed5b3ead60a1cc239bc8c916705c062c

The revision changed between the scans, so a rebuild is expected.

If there are any unexpected rebuilds, then we need to pull out the pre and post configuration snippets of the corresponding multibranch project, e.g. (for the above example it looks like):

bb-c/demo-2017-03:

<com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSource plugin="cloudbees-bitbucket-branch-source@2.1.2">
  <id>com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMNavigator::https://bitbucket.org::cloudbeers::demo-2017-03</id>
  <credentialsId>bitbucket-cloud</credentialsId>
  <checkoutCredentialsId>SAME</checkoutCredentialsId>
  <repoOwner>cloudbeers</repoOwner>
  <repository>demo-2017-03</repository>
  <includes>*</includes>
  <excludes></excludes>
  <autoRegisterHook>false</autoRegisterHook>
  <sshPort>-1</sshPort>
  <repositoryType>GIT</repositoryType>
</com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSource>

and the same for the branch specific revision:

  master:
    <jenkins.plugins.git.AbstractGitSCMSource_-SCMRevisionImpl plugin="git@3.3.0">
      <head class="org.jenkinsci.plugins.github_branch_source.BranchSCMHead" plugin="github-branch-source@2.0.6">
        <name>master</name>
      </head>
      <hash>be584b471c5ff905cda3ccacf8201a654669fa0f</hash>
    </jenkins.plugins.git.AbstractGitSCMSource_-SCMRevisionImpl>

That should be sufficient information to allow the rebuild to be confirmed as necessary or unnecessary and should allow a reproducible test case to be added to the corresponding branch source plugin.

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment