如何检索Java web应用程序的更改列表?
我有一个SpringBoot应用程序,我想有一个页面,列出最近的版本号和它包含的更改列表。我使用Rally、git和Jenkins,但除了手动更新HTML或db表之外,我想知道是否还有更自动化的方法来检索这些信息如何检索Java web应用程序的更改列表?,java,spring-mvc,jenkins,rally,Java,Spring Mvc,Jenkins,Rally,我有一个SpringBoot应用程序,我想有一个页面,列出最近的版本号和它包含的更改列表。我使用Rally、git和Jenkins,但除了手动更新HTML或db表之外,我想知道是否还有更自动化的方法来检索这些信息 任何人都可以在应用程序中分享他们在网页上列出这些信息的方法吗 如果将/api/json?pretty=true附加到Jenkins中作业URL的末尾,您可以看到作业本身的json输出,这可以引导您找到最新的版本号。此外,这将引导您找到最新构建的URL,该URL(再次添加/api/jso
任何人都可以在应用程序中分享他们在网页上列出这些信息的方法吗 如果将
/api/json?pretty=true
附加到Jenkins中作业URL的末尾,您可以看到作业本身的json输出,这可以引导您找到最新的版本号。此外,这将引导您找到最新构建的URL,该URL(再次添加/api/json?pretty=true
)可以引导您找到变更集的json列表(以及相应的提交消息)
你甚至不需要进入拉力赛!:-)
您可以使用JSON封送和
RestTemplate
Spring类从Spring应用程序中使用该JSON。如果在Jenkins中的作业URL末尾附加/api/JSON?pretty=true
,您可以看到作业本身的JSON输出,这可以引导您找到最新的版本号。此外,这将引导您找到最新构建的URL,该URL(再次添加/api/json?pretty=true
)可以引导您找到变更集的json列表(以及相应的提交消息)
你甚至不需要进入拉力赛!:-)
您可以使用JSON封送和
RestTemplate
Spring类从Spring应用程序中使用该JSON。您可以通过使用和跟踪成功和失败的Jenkins构建,从git提交到相关的CA AgileCentral(Rally)工件,只要两者指向同一个存储库,git中的提交提到相关工件的FormattedID
下面是一个基于的Java示例。无论选择何种工具包、语言等,都是底层对象模型提供了对这些数据的访问。我通过CreationDate限制了生成查询。在构建对象上的其他字段中,我获取变更集集合。该集合的每个元素都是对变更集对象的引用。Git连接器在CA Agile Central(Rally)中创建变更集对象。每个变更集对象都有Artfacts集合字段和Changes集合字段。工件集合的每个元素都是集合工件的引用,例如用户故事、缺陷。通过获取每个更改对象上的PathAndFilename,可以获得关联的源文件。
现在,我们可以将失败的构建跟踪到特定的提交、文件和用户故事
这是下面Java代码创建的控制台输出的屏幕截图。最终,您可能希望以更具视觉吸引力的方式呈现数据。此示例仅显示构建和提交可以通过WS-API跟踪到用户故事或缺陷
通常需要单独的请求才能完成。由于Build和Cangesets数据可能很大,因此通过某些条件(例如CreationDate)绑定这些查询将使其更快
公共类GetBuildData{
公共静态void main(字符串[]args)引发异常{
字符串主机=”https://rally1.rallydev.com";
字符串apiKey=“_abc123”;
字符串applicationName=“NickM:GetBuildData”;
字符串workspaceRef=“/workspace/12345”;
字符串projectRef=“/project/1346”;
RallyRestApi restApi=null;
试一试{
String dateString=“2016-05-12”;
restApi=new-RallyRestApi(新URI(主机),apiKey);
restApi.setApplicationName(applicationName);
QueryRequest buildRequest=新QueryRequest(“构建”);
setFetch(新的Fetch(“状态、消息、开始、Uri、变更集”);
setQueryFilter(新的QueryFilter(“CreationDate”,“>”,dateString));
buildRequest.setWorkspace(workspaceRef);
buildRequest.setProject(projectRef);
QueryResponse buildResponse=restApi.query(buildRequest);
对于(int i=0;i,您可以通过使用和跟踪从git提交到相关CA AgileCentral(Rally)工件的成功和失败的Jenkins构建,只要两者都指向相同的存储库,并且git中的提交提到相关工件的FormattedID
这是一个基于的Java示例。无论选择何种工具包、语言等,都是底层对象模型提供对该数据的访问。我通过CreationDate限制生成查询。在生成对象上的其他字段中,我获取变更集集合。该集合的每个元素都是对变更集对象的引用。Git connector c在CA Agile Central(Rally)中创建变更集对象。每个变更集对象都有Artfacts集合字段和Changes集合字段。工件集合的每个元素都是对Rally工件的引用,例如用户故事、缺陷。通过获取每个变更对象上的PathAndFilename,可以获得关联的源文件。
现在,我们可以将失败的构建跟踪到特定的提交、文件和用户故事
这是下面Java代码创建的控制台输出的屏幕截图。最终,您可能希望以更具视觉吸引力的方式显示数据。此示例仅显示构建和提交可以通过WS-API跟踪到用户故事或缺陷
通常需要单独的请求才能添加水合物。由于生成和存储集数据可能很大,因此根据某些条件(例如CreationDate)绑定这些查询将使其更快
公共类GetBuildData{
公共静态void main(字符串[]args)引发异常{
字符串主机=”https://rally1.rallydev.com";
字符串apiKey=“_abc123”;
字符串applicationName=“NickM:GetBuildData”;
字符串workspaceRef=“/workspace/12345”;
字符串projectRef=“/project/1346”;
RallyRestApi restApi=null;
试一试{
String dateString=“2016-05-12”;
restApi=new-RallyRestApi(新URI(主机),apiKey);
restApi.setApplicati
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();
}
}
}
}
<!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>