jenkinsjenkins-pluginsjenkins-groovyjenkins-cli

Extract Last Commit Activity Information


I am using the below code in the Jenkins console to extract a list of all users known to Jenkins

import hudson.model.User
def users = User.getAll()
for (User u : users) {   
    def userid = u.getId()
    def fullname = u.getFullName()
    println("User ID - " + userid + ", Full Name - " + fullname)   
} 

As far as I know, this hudson.model.User module does not contain any of the "Last Commit Activity" as shown on the asynchpeople API page here - https://JenkinsURL/asynchPeople/

If you look at the asynchPeople URL for a Jenkins instance, it contains User ID, Name, Last Commit Activity and which pipeline the commit was on. I am looking to extract all this information from a script/plugin/pipeline rather than navigating to the URL for a manual extraction

I have looked through the documentation but cannot find any reference to the "Last Commit Activity" so I am not sure how this is generated by Jenkins. https://javadoc.jenkins-ci.org/hudson/model/User.html

Does anyone know how to extract this information please? Thanks!


Solution

  • Yes, your observation is correct, the commit activity is always bound to a build/run, hence it's not maintained within the User object. When you go to the asynchPeople page the data is crunched together dynamically. So there is no direct way(Unless you call the API http://localhost:8080/asynchPeople/api/xml) Hence you can use the following code to get this data.

    import hudson.model.View.UserInfo;
    import hudson.util.RunList;
    import jenkins.scm.RunWithSCM;
    import hudson.scm.ChangeLogSet;
    
    def jen = Jenkins.instance
    
    Collection<TopLevelItem> items = jen.items;
    
    Map<User, UserInfo> users = new HashMap<>();
    Set<User> modified = new HashSet<>();
    
    for (Item item : items) {
        for (Job<?, ?> job : item.getAllJobs()) {
            RunList<? extends Run<?, ?>> builds = job.getBuilds();
            int buildCount = 0;
            for (Run<?, ?> r : builds) {
                if (!(r instanceof RunWithSCM)) {
                    continue;
                }
    
                RunWithSCM<?, ?> runWithSCM = (RunWithSCM<?, ?>) r;
                for (ChangeLogSet<? extends ChangeLogSet.Entry> c : runWithSCM.getChangeSets()) {
                    for (ChangeLogSet.Entry entry : c) {
                        User user = entry.getAuthor();
                        UserInfo info = users.get(user);
                        if (info == null) {
                            UserInfo userInfo = new UserInfo(user, job, r.getTimestamp());
                            users.put(user, userInfo);
                            modified.add(user);
    
                        } else if (info.getLastChange().before(r.getTimestamp())) {
                            info.project = job;
                            info.lastChange = r.getTimestamp();
                            modified.add(user);
    
                        }
                    }
                }
            }
        }
    }
    
    
    users.each { key, val ->
        println "UserName : " + val.getUser() + " ,CommitActivity: " + val.getLastChangeTimeString() + " ,ProjectName: " + val.getJob().getFullDisplayName() + " ,URL: " + val.getJob().getUrl()
    }
    

    Above is exactly what Jenkins does to get this data. Take a look at this.