diff options
author | Aleksi Hietanen <aleksi@vaadin.com> | 2016-11-02 13:43:52 +0200 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2016-11-02 12:03:33 +0000 |
commit | ad406f7986e22b98d1622b444f67544c43e5d4c2 (patch) | |
tree | 3e6ee902b55ba845b1f03108cabc10034f13fd67 /scripts | |
parent | c8e83ca3b02bdacf0b1a7182d9809e6acd7854b5 (diff) | |
download | vaadin-framework-ad406f7986e22b98d1622b444f67544c43e5d4c2.tar.gz vaadin-framework-ad406f7986e22b98d1622b444f67544c43e5d4c2.zip |
Initial version for new combined build, testing and staging report script
Change-Id: I93c34fc289df6afa5adaea89fcdb1b7f5e494cae
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/GenerateBuildTestAndStagingReport.py | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/scripts/GenerateBuildTestAndStagingReport.py b/scripts/GenerateBuildTestAndStagingReport.py new file mode 100644 index 0000000000..7b69b9825b --- /dev/null +++ b/scripts/GenerateBuildTestAndStagingReport.py @@ -0,0 +1,161 @@ +import argparse, requests, json, subprocess, re + +def createTableRow(*columns): + html = "<tr>" + for column in columns: + html += "<td>" + column + "</td>" + return html + "</tr>" + + +def getBuildStatusHtml(): + build_steps_request_string = "http://{}/app/rest/problemOccurrences?locator=build:{}".format(args.teamcityUrl, args.buildId) + build_steps_request = requests.get(build_steps_request_string, auth=(args.teamcityUser, args.teamcityPassword), headers={'Accept':'application/json'}) + if build_steps_request.status_code != 200: + return createTableRow(traffic_light.format(color="black"), "Build status: unable to retrieve status of build") + else: + build_steps_json = build_steps_request.json() + if build_steps_json["count"] == 0: + return createTableRow(traffic_light.format(color="green"), "Build status: all build steps successful") + else: + return createTableRow(traffic_light.format(color="red"), "Build status: there are failing build steps, <a href={}>check the build report</a>".format(args.buildResultUrl)) + +def getTestStatusHtml(): + test_failures_request_string = "http://{}/app/rest/testOccurrences?locator=build:{},status:FAILURE".format(args.teamcityUrl, args.buildId) + test_failures_request = requests.get(test_failures_request_string, auth=(args.teamcityUser, args.teamcityPassword), headers={'Accept':'application/json'}) + if test_failures_request.status_code != 200: + return createTableRow(traffic_light.format(color="black"), "Test status: unable to retrieve status of tests") + else: + test_failures_json = test_failures_request.json() + if test_failures_json["count"] == 0: + return createTableRow(traffic_light.format(color="green"), "Test status: all tests passing") + else: + return createTableRow(traffic_light.format(color="red"), "Test status: there are " + str(test_failures_json["count"]) + " failing tests") +""" + if "testOccurrence" in test_failures_json: + ret += "<p> Failures:" + ret += "<ul>" + for test_failure in test_failures_json["testOccurrence"]: + ret += "<li><a href=\"http://" + args.teamcityUrl + test_failure["href"] + "\">" + test_failure["name"] + "</a></li>" + return ret +""" + +def getDirs(url): + page = requests.get(url) + # files = tree.xpath('//tr/td/a/text()') + files = re.findall('<a href=.*>(.*)</a>', page.text) + dirs = filter(lambda x: x.endswith('/'), files) + return list(map(lambda x: x.replace('/', ''), dirs)) + +def dirTree(url): + dirs = getDirs(url) + result = [] + for d in dirs: + result.append(d) + subDirs = list(map(lambda x: d + '/' + x, dirTree(url + '/' + d))) + result.extend(subDirs) + return result + +def getAllowedArtifactPaths(allowedArtifacts): + result = [] + for artifact in allowedArtifacts: + parts = artifact.split('/', 1) + result.append(parts[0]) + if len(parts) > 1: + subart = getAllowedArtifactPaths([ parts[1] ]) + subArtifacts = list(map(lambda x: parts[0] + '/' + x, subart)) + result.extend(subArtifacts) + return result + +def checkStagingContents(url, allowedArtifacts): + dirs = dirTree(url) + allowedDirs = getAllowedArtifactPaths(allowedArtifacts) + return set(dirs) == set(allowedDirs) + +def getStagingContentsHtml(repoUrl, allowedArtifacts, name): + if checkStagingContents(repoUrl, allowedArtifacts): + return createTableRow(traffic_light.format(color="green"), "No extra artifacts found in the {} staging repository".format(name)) + else: + return createTableRow(traffic_light.format(color="red"), "Extra artifacts found in the {} staging repository".format(name)) + +def completeArtifactName(artifactId, version): + return 'com/vaadin/' + artifactId + '/' + version + +def completeArtifactNames(artifactIds, version): + return list(map(lambda x: completeArtifactName(x, version), artifactIds)) + +parser = argparse.ArgumentParser() +parser.add_argument("version", type=str, help="Vaadin version that was just built") +parser.add_argument("buildResultUrl", type=str, help="URL for the build result page") + +parser.add_argument("teamcityUser", type=str, help="Teamcity username to use") +parser.add_argument("teamcityPassword", type=str, help="Password for given teamcity username") + +parser.add_argument("teamcityUrl", type=str, help="Address to the teamcity server") +parser.add_argument("buildId", type=str, help="ID of the build to generate this report for") + +parser.add_argument("frameworkRepoUrl", type=str, help="URL to the framework staging repository") +parser.add_argument("archetypeRepoUrl", type=str, help="URL to the archetype staging repository") +parser.add_argument("pluginRepoUrl", type=str, help="URL to the plugin staging repository") +args = parser.parse_args() + +allowedPluginArtifacts = completeArtifactNames([ 'vaadin-maven-plugin' ], args.version) +allowedArchetypeArtifacts = completeArtifactNames([ 'vaadin-archetype-application', 'vaadin-archetype-application-multimodule', 'vaadin-archetype-application-example', 'vaadin-archetype-widget', 'vaadin-archetype-liferay-portlet' ], args.version) +allowedFrameworkArtifacts = completeArtifactNames([ 'vaadin-root', 'vaadin-bom', 'vaadin-shared', 'vaadin-server', 'vaadin-client', 'vaadin-client-compiler', 'vaadin-client-compiled', 'vaadin-push', 'vaadin-themes', 'vaadin-widgets', 'vaadin-compatibility-shared', 'vaadin-compatibility-server', 'vaadin-compatibility-client', 'vaadin-compatibility-client-compiled', 'vaadin-compatibility-themes' ], args.version) + +content = "<html><head></head><body><table>" +traffic_light = "<svg width=\"20px\" height=\"20px\" style=\"padding-right:5px\"><circle cx=\"10\" cy=\"10\" r=\"10\" fill=\"{color}\"/></svg>" + +# Build step status +content += getBuildStatusHtml() + +# Test failures +content += getTestStatusHtml() + +# Missing @since tags +try: + p1 = subprocess.Popen(['find', '.', '-name', '*.java'], stdout=subprocess.PIPE) + p2 = subprocess.Popen(['xargs', 'egrep', '-n', '@since ?$'], stdin=p1.stdout, stdout=subprocess.PIPE) + missing = subprocess.check_output(['egrep', '-v', '/(test|tests|target)/'], stdin=p2.stdout) + content += createTableRow(traffic_light.format(color="red"), "Empty @since:<br><pre>%s</pre>" % (missing)) + +except subprocess.CalledProcessError as e: + if e.returncode == 1: + content += createTableRow(traffic_light.format(color="green"), "No empty @since") + else: + raise e + +# framework repo: verify pending-release tickets have milestones + +content += getStagingContentsHtml(args.frameworkRepoUrl, allowedFrameworkArtifacts, "framework") +content += getStagingContentsHtml(args.archetypeRepoUrl, allowedArchetypeArtifacts, "archetype") +content += getStagingContentsHtml(args.pluginRepoUrl, allowedPluginArtifacts, "plugin") + +# Next steps +content += createTableRow("", "<a href=\"http://r2d2.devnet.vaadin.com/repository/download/Vaadin80_Releases_BuildTestAndStageRelease/{}:id/release-notes/release-notes.html\">Check release notes</a>".format(args.buildId)) +content += createTableRow("", "<a href=\"http://r2d2.devnet.vaadin.com/repository/download/Vaadin80_Releases_BuildTestAndStageRelease/{}:id/apidiff/\">Check API diff</a>".format(args.buildId)) + +# create milestone for next release +content += createTableRow("", "<a href=\"https://dev.vaadin.com/milestone?action=new\">Create milestone for nex release</a>") +# closed fixed tickets without a milestone +content += createTableRow("", "<a href=\"https://dev.vaadin.com/query?status=closed&component=Core+Framework&resolution=fixed&milestone=!Vaadin {version}&col=id&col=summary&col=component&col=status&col=type&col=priority&col=milestone&order=priority\">Closed fixed tickets without milestone {version}</a>".format(version=args.version)) +# closed tickets with milestone +content += createTableRow("", "<a href=\"https://dev.vaadin.com/query?status=closed&component=Core+Framework&resolution=fixed&milestone=Vaadin {version}&col=id&col=summary&col=component&col=milestone&col=status&col=type\">Closed tickets with milestone {version}</a>".format(version=args.version)) +# pending release tickets with milestone +content += createTableRow("", "<a href=\"https://dev.vaadin.com/query?status=pending-release&component=Core+Framework&resolution=fixed&milestone=Vaadin {version}&col=id&col=summary&col=component&col=milestone&col=status&col=type\">Pending-release tickets with milestone {version}</a>".format(version=args.version)) +# pending release tickets without milestone +content += createTableRow("", "<a href=\"https://dev.vaadin.com/query?status=pending-release&milestone=\">Pending-release tickets without milestone</a>") + +content += createTableRow("", "<h2>Preparations before publishing</h2>") +# close trac milestone +content += createTableRow("", "<a href=\"https://dev.vaadin.com/milestone/Vaadin {version}\">Close Trac Milestone</a>".format(version=args.version)) +# verify pending release tickets still have milestone +content += createTableRow("", "<a href=\"https://dev.vaadin.com/query?status=pending-release&component=Core+Framework&resolution=fixed&col=id&col=summary&col=component&col=milestone&col=status&col=type\">Verify pending release tickets still have milestone {version}</a>".format(version=args.version)) +# add version to trac +content += createTableRow("", "<a href=\"https://dev.vaadin.com/admin/ticket/versions\">Add version {version} to Trac".format(version=args.version)) + + +content += "</table></body></html>" +f = open("report.html", 'w') +f.write(content) + + |