Вы можете отслеживать удачные и неудачные Дженкинс строит из мерзавца обязана связана CA AgileCentral (Rally) артефактов с помощью Git connector и Jenkins plugin до тех пор, как указует на то же хранилище, и фиксация в мерзавце упоминает FormattedID из соответствующего артефакта.
Ниже приведен пример Java, основанный на Rally API Toolkit For Java. Независимо от выбора инструментария, языка и т. Д. Это базовая объектная модель WS API, которая обеспечивает доступ к этим данным. Я ограничил запрос Build с помощью CreationDate. Среди других полей объекта Build я собираю коллекцию наборов. Каждый элемент этой коллекции является ссылкой на объект «Изменение». Соединитель Git создает объекты «Обновления» в CA Agile Central (Rally). Каждый объект «Набор» имеет поле коллекции Artfacts и поле «Изменение коллекции». Каждый элемент коллекции артефактов является ссылкой на артефакт ралли, например. пользователь история, дефект. Извлекая PathAndFilename для каждого объекта Change, вы получаете связанный исходный файл. Теперь мы можем отслеживать неудачную сборку для конкретной истории фиксации, файла и пользователя.
Это скриншот с выхода консоли, созданного кодом Java ниже. В конце концов вы можете представить данные более привлекательно. В этом примере показано, что сборки и коммиты могут быть отслежены до истоков пользователей или дефектов через WS API.
Отдельные запросы часто необходимы для гидратации collections in WS API. Поскольку данные Build и Cangesets могут быть большими, привязка этих запросов по некоторым критериям, например. CreationDate сделает это быстрее.
public class GetBuildData {
public static void main(String[] args) throws Exception {
String host = "https://rally1.rallydev.com";
String apiKey = "_abc123";
String applicationName = "NickM:GetBuildData";
String workspaceRef = "/workspace/12345";
String projectRef = "/project/1346";
RallyRestApi restApi = null;
try {
String dateString = "2016-05-12";
restApi = new RallyRestApi(new URI(host),apiKey);
restApi.setApplicationName(applicationName);
QueryRequest buildRequest = new QueryRequest("Build");
buildRequest.setFetch(new Fetch("Status,Message,Start,Uri,Changesets"));
buildRequest.setQueryFilter(new QueryFilter("CreationDate", ">", dateString));
buildRequest.setWorkspace(workspaceRef);
buildRequest.setProject(projectRef);
QueryResponse buildResponse = restApi.query(buildRequest);
for (int i=0; i<buildResponse.getTotalResultCount();i++){
JsonObject buildObj = buildResponse.getResults().get(i).getAsJsonObject();
System.out.println("Build Status: " + buildObj.get("Status") +
"\n Build Message: " + buildObj.get("Message") +
"\n Build Start: " + buildObj.get("Start") +
"\n Build Uri: " + buildObj.get("Uri"));
JsonObject changesetsCollection = buildObj.get("Changesets").getAsJsonObject();
QueryRequest changesetsRequest = new QueryRequest(changesetsCollection);
changesetsRequest.setFetch(new Fetch("Artifacts","Changes", "Revision"));
changesetsRequest.setLimit(1000);
QueryResponse changesetsResponse = restApi.query(changesetsRequest);
for (int j=0; j<changesetsResponse.getTotalResultCount();j++) {
JsonObject changesetObj = changesetsResponse.getResults().get(j).getAsJsonObject();
System.out.println("\nChangeset Revision: " + changesetObj.get("Revision"));
JsonObject artifactsCollection = changesetObj.get("Artifacts").getAsJsonObject();
QueryRequest artifactsRequest = new QueryRequest(artifactsCollection);
artifactsRequest.setFetch(new Fetch("FormattedID"));
QueryResponse artifactsResponse = restApi.query(artifactsRequest);
for (int k=0; k<artifactsResponse.getTotalResultCount();k++) {
JsonObject artifactObj = artifactsResponse.getResults().get(k).getAsJsonObject();
System.out.println("\nArtifact FormattedID: " + artifactObj.get("FormattedID"));
}
JsonObject changesCollection = changesetObj.get("Changes").getAsJsonObject();
QueryRequest changesRequest = new QueryRequest(changesCollection);
changesRequest.setWorkspace(workspaceRef);
changesRequest.setProject(projectRef);
changesRequest.setFetch(new Fetch("PathAndFilename"));
QueryResponse changesResponse = restApi.query(changesRequest);
for (int l=0; l<changesResponse.getTotalResultCount();l++) {
JsonObject changeObj = changesResponse.getResults().get(l).getAsJsonObject();
System.out.println("Change PathAndFilename: " + changeObj.get("PathAndFilename"));
}
}
System.out.println("--------------------------------");
}
} finally {
if (restApi != null) {
restApi.close();
}
}
}
}
Если вы хотите отобразить сборки данных внутри Agile Central (ралли) AppSDK2.1 Javascript приложение может быть развернуто в пользовательской странице. Вот простой пример, чтобы начать с:
<!DOCTYPE html>
<html>
<head>
<title>Builds by Date</title>
<script type="text/javascript" src="/apps/2.1/sdk.js"></script>
<script type="text/javascript">
Rally.onReady(function() {
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
this.add({
xtype: 'component',
itemId: 'datepick',
html: 'pick a date:',
width: 100,
margin: 10
},
{
xtype: 'rallydatepicker',
showToday: false,
contentEl: Ext.ComponentQuery.query('#datepick')[0],
margin: 10,
handler: function(picker, date) {
this.getBuilds(date);
},
scope:this
},
{
xtype: 'container',
itemId: 'gridContainer'
});
},
getBuilds:function(date){
var formattedDate = Rally.util.DateTime.formatWithDefault(date, this.getContext());
Ext.ComponentQuery.query('#datepick')[0].update((formattedDate) + '<br /> selected');
if (this.down('rallygrid')) {
Ext.ComponentQuery.query('#gridContainer')[0].remove(Ext.ComponentQuery.query('#buildsGrid')[0], true);
}
this.down('#gridContainer').add({
xtype: 'rallygrid',
itemId: 'buildsGrid',
columnCfgs: [
'Status',
'Message',
'Start',
'Uri',
'Changesets'
],
storeConfig: {
model: 'build',
filters:[
{
property: 'CreationDate',
operator: '>=',
value: Rally.util.DateTime.toIsoString(date,true)
}
]
}
});
}
});
Rally.launchApp('CustomApp', {
name:"Builds by Date",
parentRepos:""
});
});
</script>
<style type="text/css">
.app {
/* Add app styles here */
}
</style>
</head>
<body>
</body>
</html>