Advertisement

Creating your own project's Quality Dashboard

CTO, Software Developer at XWiki
Oct. 28, 2017
Advertisement

More Related Content

Advertisement
Advertisement

Creating your own project's Quality Dashboard

  1. 27 au 29 mars 2013Vincent Massol, Oct2017 Creating your own project’s Quality Dashboard
  2. Agenda • Why XWiki? • Quality metrics to monitor • Storing data in the wiki • Caching to improve performance • Send email on conditions • Custom skin • Q&A Let’s do this live!
  3. Why XWiki? • A wiki but more importantly a web dev platform • Reusing existing building blocks instead of starting from scratch • Live site and thus easy to test • Will use the following features of XWiki • Scripting (especially Groovy) • Graph Macro • Dashboard Macro • Scheduler feature • JIRA Macro • GitHub Stats Application • L&F customisation • And more (authentication, permissions, etc)
  4. Quality metrics to monitor • Context: Java development project • Goal: Create a dashboard to monitor the following metrics • Number of tests (from Jenkins) • Number of code bugs (from SonarQube) • Open Blocker issues from the issue tracker (from JIRA) • (for fun) Committer stats (from GitHub)
  5. 27 au 29 mars 2013 Number of Tests Jenkins Integration
  6. Number of tests - Retrieval • Using Jenkins REST API {{groovy}} def url = 'http://ci.xwiki.org/job/xwiki-commons/ lastSuccessfulBuild/testReport/api/xml? pretty=true&depth=-1'.toURL().text def root = new XmlSlurper().parseText(url) println "Tests for XWiki Commons: ${root.totalCount}" {{/groovy}} Demo
  7. Storing Data locally • Why? • Performance reasons for viewing collected data • Ability to graph evolution of metrics • How? • Create data structure (XClass) • Script to import data from remote sites and store them in wiki pages (XObjects = instances of XClass) • Scheduler job to run it every day (for example)
  8. Number of tests - Our goal
  9. Number of tests - Class & Objects
  10. Number of tests - Storing code {{groovy}} def url = 'http://ci.xwiki.org/job/xwiki-commons/lastSuccessfulBuild/testReport/api/xml? pretty=true&depth=-1'.toURL().text def root = new XmlSlurper().parseText(url) def count = root.totalCount // Compute new doc name def countQuery = 'from doc.object(Quality.Jenkins.TestNumberClass) as record' def recordCount = services.query.xwql(countQuery).count() def newRecordReference = "Quality.Jenkins.Data.Count${recordCount + 1}" // Only create a new record if none exist for today's date def date = new Date() date.clearTime() def existQuery = 'from doc.object(Quality.Jenkins.TestNumberClass) as record where record.date = :date' def todayCount = services.query.xwql(existQuery).bindValue('date', date).count() if (todayCount == 0) { def recordDoc = xwiki.getDocument(newRecordReference) def object = recordDoc.newObject('Quality.Jenkins.TestNumberClass') object.set('date', date.format('dd/MM/yyyy')) object.set('count', count.text()) recordDoc.save() } {{/groovy}} Demo
  11. Graph Macro
  12. Number of tests - Graphing {{groovy}} def labels = [] def values = [] def records = services.query.xwql('select record.date, record.count, doc.fullName from Document doc, doc.object(Quality.Jenkins.TestNumberClass) as record order by record.date').execute() records.each() { labels.add(it[0].toString().split(' ')[0]) values.add(it[1]) } println '{{chartjs type="line"}}' println '{' println " "labels": [${labels.collect{'"' + it + '"'}.join(',')}]," println " "datasets": [{"data": [${values.join(',')}]}]" println '}' println '{{/chartjs}}' {{/groovy}} Demo
  13. Number of tests - Scheduler Demo
  14. Dashboard • Dashboard Macro {{dashboard/}} Demo
  15. 27 au 29 mars 2013 Code bugs SonarQube Integration
  16. Code bugs - Retrieval • Using SonarQube REST API {{groovy}} import groovy.json.JsonSlurper def url = 'https://sonarcloud.io/api/issues/search? componentRoots=org.xwiki.commons%3Axwiki- commons&types=BUG&statuses=OPEN'.toURL().text def root = new JsonSlurper().parseText(url) println '|=Severity|=Component|=Message|=Line' root.issues.each() { issue -> println "|${issue.severity}|${issue.project} - $ {issue.subProject} - $ {StringUtils.substringAfterLast(issue.component, '/')}|$ {issue.message}|${issue.line}" } {{/groovy}} Demo
  17. Code bugs - Results
  18. Cache Macro {{cache id="bugs" timeToLive="86400"}} {{groovy}} ... {{/groovy}} {{/cache}} • Example: cache of one day Demo
  19. Code bugs - Dashboard Demo
  20. Send mail on condition • Example: Send mail when # bugs > 10 • Using a Scheduler job for example or when fetching data {{groovy}} […] if (root.issues.size() >= 10) { def message = services.mailsender.createMessage( "vincent@massol.net", "Alert: too many bugs!") message.addPart("text/plain", "text content") services.mailsender.send([message], 'database') } {{/groovy}}
  21. 27 au 29 mars 2013 Tracker Issues JIRA Integration
  22. Tracker Issues - JIRA Macro • Using XWiki’s JIRA Macro {{jira id="xwikiorg" style="table" source="jql"}} category = 10000 AND priority = blocker AND resolution = open {{/jira}}
  23. Tracker Issues - Dashboard
  24. 27 au 29 mars 2013 Commit Stats GitHub Integration
  25. Commit Stats • Using XWiki’s GitHub Stats Application {{committers since="365" repositories="xwiki/*" contributors="true" inactives="false" type="list"/}}
  26. Full Dashboard
  27. Custom Skin
  28. Q&A • Going further: http://xwiki.org Me
Advertisement