SlideShare una empresa de Scribd logo
1 de 28
Descargar para leer sin conexión
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 on conditions
• Custom skin
• Q&A
Let’s do this live!
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)
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)
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/
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
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)
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/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
Graph Macro
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
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.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
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
{{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}}
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 AND priority = blocker AND resolution = open
{{/jira}}
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" inactives="false" type="list"/}}
Full Dashboard
Custom Skin
Q&A
• Going further: http://xwiki.org
Me

Más contenido relacionado

La actualidad más candente

Nikolay Kozhukharenko ''Component driven development how to guide''
Nikolay Kozhukharenko ''Component driven development how to guide''Nikolay Kozhukharenko ''Component driven development how to guide''
Nikolay Kozhukharenko ''Component driven development how to guide''
OdessaJS Conf
 
From MySQL to MongoDB at Wordnik (Tony Tam)
From MySQL to MongoDB at Wordnik (Tony Tam)From MySQL to MongoDB at Wordnik (Tony Tam)
From MySQL to MongoDB at Wordnik (Tony Tam)
MongoSF
 

La actualidad más candente (20)

BizSpark SF Lightning Talk: "Automated Testing (Unit, Integration and Systems...
BizSpark SF Lightning Talk: "Automated Testing (Unit, Integration and Systems...BizSpark SF Lightning Talk: "Automated Testing (Unit, Integration and Systems...
BizSpark SF Lightning Talk: "Automated Testing (Unit, Integration and Systems...
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDB
 
jclouds overview
jclouds overviewjclouds overview
jclouds overview
 
Fetch data from form
Fetch data from formFetch data from form
Fetch data from form
 
"Ускорение сборки большого проекта на Objective-C + Swift" Иван Бондарь (Avito)
"Ускорение сборки большого проекта на Objective-C + Swift" Иван Бондарь (Avito)"Ускорение сборки большого проекта на Objective-C + Swift" Иван Бондарь (Avito)
"Ускорение сборки большого проекта на Objective-C + Swift" Иван Бондарь (Avito)
 
The Ring programming language version 1.9 book - Part 74 of 210
The Ring programming language version 1.9 book - Part 74 of 210The Ring programming language version 1.9 book - Part 74 of 210
The Ring programming language version 1.9 book - Part 74 of 210
 
Sbt for mere mortals
Sbt for mere mortalsSbt for mere mortals
Sbt for mere mortals
 
Node.js Introduction
Node.js IntroductionNode.js Introduction
Node.js Introduction
 
Developing XWiki
Developing XWikiDeveloping XWiki
Developing XWiki
 
Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...
Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...
Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...
 
クリーンアーキテクチャーを強制する方法を考えてみた(N番煎じ) #すえなみチャンス暑気払い
クリーンアーキテクチャーを強制する方法を考えてみた(N番煎じ) #すえなみチャンス暑気払いクリーンアーキテクチャーを強制する方法を考えてみた(N番煎じ) #すえなみチャンス暑気払い
クリーンアーキテクチャーを強制する方法を考えてみた(N番煎じ) #すえなみチャンス暑気払い
 
Nikolay Kozhukharenko ''Component driven development how to guide''
Nikolay Kozhukharenko ''Component driven development how to guide''Nikolay Kozhukharenko ''Component driven development how to guide''
Nikolay Kozhukharenko ''Component driven development how to guide''
 
.NET Conf 2019 - Indexing and searching NuGet.org with Azure Functions and Se...
.NET Conf 2019 - Indexing and searching NuGet.org with Azure Functions and Se....NET Conf 2019 - Indexing and searching NuGet.org with Azure Functions and Se...
.NET Conf 2019 - Indexing and searching NuGet.org with Azure Functions and Se...
 
Linq
LinqLinq
Linq
 
Nodejs intro
Nodejs introNodejs intro
Nodejs intro
 
Introduction to node.js
Introduction to node.jsIntroduction to node.js
Introduction to node.js
 
Icinga Camp Bangalore - Icinga2 API use cases and BlueJeans Inc.
Icinga Camp Bangalore - Icinga2 API use cases and BlueJeans Inc.Icinga Camp Bangalore - Icinga2 API use cases and BlueJeans Inc.
Icinga Camp Bangalore - Icinga2 API use cases and BlueJeans Inc.
 
Velocity NYC 2016 - Containers @ Netflix
Velocity NYC 2016 - Containers @ NetflixVelocity NYC 2016 - Containers @ Netflix
Velocity NYC 2016 - Containers @ Netflix
 
Streaming Data with scalaz-stream
Streaming Data with scalaz-streamStreaming Data with scalaz-stream
Streaming Data with scalaz-stream
 
From MySQL to MongoDB at Wordnik (Tony Tam)
From MySQL to MongoDB at Wordnik (Tony Tam)From MySQL to MongoDB at Wordnik (Tony Tam)
From MySQL to MongoDB at Wordnik (Tony Tam)
 

Similar a Creating your own project's Quality Dashboard

Similar a Creating your own project's Quality Dashboard (20)

Intellias CQRS Framework
Intellias CQRS FrameworkIntellias CQRS Framework
Intellias CQRS Framework
 
Improving Your Selenium WebDriver Tests - Belgium testing days_2016
Improving Your Selenium WebDriver Tests - Belgium testing days_2016Improving Your Selenium WebDriver Tests - Belgium testing days_2016
Improving Your Selenium WebDriver Tests - Belgium testing days_2016
 
Surviving UI Automation Armageddon with BELLATRIX.pptx
Surviving UI Automation Armageddon with BELLATRIX.pptxSurviving UI Automation Armageddon with BELLATRIX.pptx
Surviving UI Automation Armageddon with BELLATRIX.pptx
 
Docker & ECS: Secure Nearline Execution
Docker & ECS: Secure Nearline ExecutionDocker & ECS: Secure Nearline Execution
Docker & ECS: Secure Nearline Execution
 
Building XWiki
Building XWikiBuilding XWiki
Building XWiki
 
Quick start with AngularJS
Quick start with AngularJSQuick start with AngularJS
Quick start with AngularJS
 
How to use the new Domino Query Language
How to use the new Domino Query LanguageHow to use the new Domino Query Language
How to use the new Domino Query Language
 
Learning with F#
Learning with F#Learning with F#
Learning with F#
 
Interactive Kafka Streams
Interactive Kafka StreamsInteractive Kafka Streams
Interactive Kafka Streams
 
Web based automation testing on Node.js environment
Web based automation testing on Node.js environmentWeb based automation testing on Node.js environment
Web based automation testing on Node.js environment
 
Exploring an API with Blocks
Exploring an API with BlocksExploring an API with Blocks
Exploring an API with Blocks
 
jQuery On Rails
jQuery On RailsjQuery On Rails
jQuery On Rails
 
WinAppDriver Development
WinAppDriver DevelopmentWinAppDriver Development
WinAppDriver Development
 
Geek Sync I Learn to Troubleshoot Query Performance in Analysis Services
Geek Sync I Learn to Troubleshoot Query Performance in Analysis ServicesGeek Sync I Learn to Troubleshoot Query Performance in Analysis Services
Geek Sync I Learn to Troubleshoot Query Performance in Analysis Services
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
Tdd
TddTdd
Tdd
 
Protractor Tutorial Quality in Agile 2015
Protractor Tutorial Quality in Agile 2015Protractor Tutorial Quality in Agile 2015
Protractor Tutorial Quality in Agile 2015
 
J query module1
J query module1J query module1
J query module1
 
MSFT Dumaguete 061616 - Building High Performance Apps
MSFT Dumaguete 061616 - Building High Performance AppsMSFT Dumaguete 061616 - Building High Performance Apps
MSFT Dumaguete 061616 - Building High Performance Apps
 
Deep dive into SoapUI
Deep dive into SoapUIDeep dive into SoapUI
Deep dive into SoapUI
 

Más de Vincent Massol

XWiki: wiki collaboration as an alternative to Confluence and Sharepoint
XWiki: wiki collaboration as an alternative to Confluence and SharepointXWiki: wiki collaboration as an alternative to Confluence and Sharepoint
XWiki: wiki collaboration as an alternative to Confluence and Sharepoint
Vincent Massol
 
Evolutions XWiki 2012/2013
Evolutions XWiki 2012/2013Evolutions XWiki 2012/2013
Evolutions XWiki 2012/2013
Vincent Massol
 

Más de Vincent Massol (20)

XWiki Testing with TestContainers
XWiki Testing with TestContainersXWiki Testing with TestContainers
XWiki Testing with TestContainers
 
Advanced Java Testing @ POSS 2019
Advanced Java Testing @ POSS 2019Advanced Java Testing @ POSS 2019
Advanced Java Testing @ POSS 2019
 
New types of tests for Java projects
New types of tests for Java projectsNew types of tests for Java projects
New types of tests for Java projects
 
Configuration Testing with Docker & TestContainers
Configuration Testing with Docker & TestContainersConfiguration Testing with Docker & TestContainers
Configuration Testing with Docker & TestContainers
 
New types of tests for Java projects
New types of tests for Java projectsNew types of tests for Java projects
New types of tests for Java projects
 
What's new in XWiki 9.x and 10.x
What's new in XWiki 9.x and 10.xWhat's new in XWiki 9.x and 10.x
What's new in XWiki 9.x and 10.x
 
QDashboard 1.2
QDashboard 1.2QDashboard 1.2
QDashboard 1.2
 
XWiki: wiki collaboration as an alternative to Confluence and Sharepoint
XWiki: wiki collaboration as an alternative to Confluence and SharepointXWiki: wiki collaboration as an alternative to Confluence and Sharepoint
XWiki: wiki collaboration as an alternative to Confluence and Sharepoint
 
XWiki Status - July 2015
XWiki Status - July 2015XWiki Status - July 2015
XWiki Status - July 2015
 
XWiki SAS development practices
XWiki SAS development practicesXWiki SAS development practices
XWiki SAS development practices
 
XWiki SAS: An open source company
XWiki SAS: An open source companyXWiki SAS: An open source company
XWiki SAS: An open source company
 
XWiki: A web dev runtime for writing web apps @ FOSDEM 2014
XWiki: A web dev runtime for writing web apps @ FOSDEM 2014XWiki: A web dev runtime for writing web apps @ FOSDEM 2014
XWiki: A web dev runtime for writing web apps @ FOSDEM 2014
 
XWiki Rendering @ FOSDEM 2014
XWiki Rendering @ FOSDEM 2014XWiki Rendering @ FOSDEM 2014
XWiki Rendering @ FOSDEM 2014
 
Implementing Quality on a Java Project
Implementing Quality on a Java ProjectImplementing Quality on a Java Project
Implementing Quality on a Java Project
 
Implementing Quality on Java projects (Short version)
Implementing Quality on Java projects (Short version)Implementing Quality on Java projects (Short version)
Implementing Quality on Java projects (Short version)
 
Implementing quality in Java projects
Implementing quality in Java projectsImplementing quality in Java projects
Implementing quality in Java projects
 
Implementing Quality on Java projects
Implementing Quality on Java projectsImplementing Quality on Java projects
Implementing Quality on Java projects
 
Combining open source ethics with private interests
Combining open source ethics with private interestsCombining open source ethics with private interests
Combining open source ethics with private interests
 
Evolutions XWiki 2012/2013
Evolutions XWiki 2012/2013Evolutions XWiki 2012/2013
Evolutions XWiki 2012/2013
 
Developing XWiki
Developing XWikiDeveloping XWiki
Developing XWiki
 

Último

Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
panagenda
 
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider  Progress from Awareness to Implementation.pptxTales from a Passkey Provider  Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
FIDO Alliance
 

Último (20)

Generative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdfGenerative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdf
 
ERP Contender Series: Acumatica vs. Sage Intacct
ERP Contender Series: Acumatica vs. Sage IntacctERP Contender Series: Acumatica vs. Sage Intacct
ERP Contender Series: Acumatica vs. Sage Intacct
 
The Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightThe Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and Insight
 
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsContinuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
 
Design and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data ScienceDesign and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data Science
 
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
 
State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!
 
WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024
 
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
 
AI mind or machine power point presentation
AI mind or machine power point presentationAI mind or machine power point presentation
AI mind or machine power point presentation
 
Portal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russePortal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russe
 
JavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate GuideJavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate Guide
 
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider  Progress from Awareness to Implementation.pptxTales from a Passkey Provider  Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
 
Intro to Passkeys and the State of Passwordless.pptx
Intro to Passkeys and the State of Passwordless.pptxIntro to Passkeys and the State of Passwordless.pptx
Intro to Passkeys and the State of Passwordless.pptx
 
UiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overviewUiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overview
 
Working together SRE & Platform Engineering
Working together SRE & Platform EngineeringWorking together SRE & Platform Engineering
Working together SRE & Platform Engineering
 
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfThe Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
 
Overview of Hyperledger Foundation
Overview of Hyperledger FoundationOverview of Hyperledger Foundation
Overview of Hyperledger Foundation
 
Introduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptxIntroduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptx
 
Using IESVE for Room Loads Analysis - UK & Ireland
Using IESVE for Room Loads Analysis - UK & IrelandUsing IESVE for Room Loads Analysis - UK & Ireland
Using IESVE for Room Loads Analysis - UK & Ireland
 

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
  • 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
  • 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"/}}
  • 28. Q&A • Going further: http://xwiki.org Me