27 au 29 mars 2013Vincent Massol, Oct2017
Creating your own project’s
Quality Dashboard
Agenda
• Why XWiki?
• Quality metrics to monitor
• Storing data in the wiki
• Caching to improve performance
• Send email ...
Why XWiki?
• A wiki but more importantly a web dev platform
• Reusing existing building blocks instead of starting from sc...
Quality metrics to monitor
• Context: Java development project
• Goal: Create a dashboard to monitor the following metrics...
27 au 29 mars 2013
Number of Tests
Jenkins Integration
Number of tests - Retrieval
• Using Jenkins REST API
{{groovy}}
def url = 'http://ci.xwiki.org/job/xwiki-commons/
lastSucc...
Storing Data locally
• Why?
• Performance reasons for viewing collected data
• Ability to graph evolution of metrics
• How...
Number of tests - Our goal
Number of tests - Class & Objects
Number of tests - Storing code
{{groovy}}
def url = 'http://ci.xwiki.org/job/xwiki-commons/lastSuccessfulBuild/testReport/...
Graph Macro
Number of tests - Graphing
{{groovy}}
def labels = []
def values = []
def records = services.query.xwql('select record.dat...
Number of tests - Scheduler Demo
Dashboard
• Dashboard Macro
{{dashboard/}}
Demo
27 au 29 mars 2013
Code bugs
SonarQube Integration
Code bugs - Retrieval
• Using SonarQube REST API
{{groovy}}
import groovy.json.JsonSlurper
def url = 'https://sonarcloud.i...
Code bugs - Results
Cache Macro
{{cache id="bugs" timeToLive="86400"}}
{{groovy}}
...
{{/groovy}}
{{/cache}}
• Example: cache of one day
Demo
Code bugs - Dashboard Demo
Send mail on condition
• Example: Send mail when # bugs > 10
• Using a Scheduler job for example or when fetching data
{{g...
27 au 29 mars 2013
Tracker Issues
JIRA Integration
Tracker Issues - JIRA Macro
• Using XWiki’s JIRA Macro
{{jira id="xwikiorg" style="table" source="jql"}}
category = 10000 ...
Tracker Issues - Dashboard
27 au 29 mars 2013
Commit Stats
GitHub Integration
Commit Stats
• Using XWiki’s GitHub Stats
Application
{{committers since="365" repositories="xwiki/*"
contributors="true" ...
Full Dashboard
Custom Skin
Q&A
• Going further: http://xwiki.org
Me
Prochain SlideShare
Chargement dans…5
×

Creating your own project's Quality Dashboard

180 vues

Publié le

Presentation held at Softshake 2017.

Shows how to use the XWiki open source project (http://xwiki.org) to develop a quality portal web site for your development projects. We'll start from a clean XWiki instance and configure it and write scripts to have the following features:

* Documentation for your project
* Display JIRA issues
* Display Sonar metrics
* Display Jenkins statuses
* Display Git statistics of your project
* Have an application to perform releases (checklist, release notes)
* Send alerts (mail, IRC, etc) when quality metric thresholds are reached

And more!

Publié dans : Technologie
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Creating your own project's Quality Dashboard

  1. 1. 27 au 29 mars 2013Vincent Massol, Oct2017 Creating your own project’s Quality Dashboard
  2. 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. 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. 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. 5. 27 au 29 mars 2013 Number of Tests Jenkins Integration
  6. 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. 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. 8. Number of tests - Our goal
  9. 9. Number of tests - Class & Objects
  10. 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. 11. Graph Macro
  12. 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. 13. Number of tests - Scheduler Demo
  14. 14. Dashboard • Dashboard Macro {{dashboard/}} Demo
  15. 15. 27 au 29 mars 2013 Code bugs SonarQube Integration
  16. 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. 17. Code bugs - Results
  18. 18. Cache Macro {{cache id="bugs" timeToLive="86400"}} {{groovy}} ... {{/groovy}} {{/cache}} • Example: cache of one day Demo
  19. 19. Code bugs - Dashboard Demo
  20. 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. 21. 27 au 29 mars 2013 Tracker Issues JIRA Integration
  22. 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. 23. Tracker Issues - Dashboard
  24. 24. 27 au 29 mars 2013 Commit Stats GitHub Integration
  25. 25. Commit Stats • Using XWiki’s GitHub Stats Application {{committers since="365" repositories="xwiki/*" contributors="true" inactives="false" type="list"/}}
  26. 26. Full Dashboard
  27. 27. Custom Skin
  28. 28. Q&A • Going further: http://xwiki.org Me

×