├── chucktcplugin-server ├── src │ └── main │ │ ├── resources │ │ ├── buildServerResources │ │ │ ├── _chuck_happy.jpg │ │ │ ├── _chuck_sad.jpg │ │ │ ├── Chuck.jsp │ │ │ └── quotes.txt │ │ └── META-INF │ │ │ └── build-server-plugin-chucktcplugin.xml │ │ └── java │ │ └── chucktcplugin │ │ ├── ChuckBuildPageExtension.java │ │ └── ChuckProjectPageExtension.java └── pom.xml ├── teamcity-plugin.xml ├── README.md ├── pom.xml └── LICENSE.txt /chucktcplugin-server/src/main/resources/buildServerResources/_chuck_happy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbf256/teamcity-chuck-plugin/HEAD/chucktcplugin-server/src/main/resources/buildServerResources/_chuck_happy.jpg -------------------------------------------------------------------------------- /chucktcplugin-server/src/main/resources/buildServerResources/_chuck_sad.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbf256/teamcity-chuck-plugin/HEAD/chucktcplugin-server/src/main/resources/buildServerResources/_chuck_sad.jpg -------------------------------------------------------------------------------- /chucktcplugin-server/src/main/resources/META-INF/build-server-plugin-chucktcplugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /teamcity-plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Chuck-Norris 5 | Chuck Norris 6 | 0.5.4 7 | Chuck Norris will check your builds and approves or disapproves them 8 | http://github.com/dbf256/teamcity-chuck-plugin 9 | dbf256@gmail.com 10 | 11 | Alexey Moskvin 12 | http://github.com/dbf256 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Chuck Norris Teamcity plugin. 2 | 3 | 4 | Chuck Norris will inspect all your builds and approve or disapprove them. If build fails and Chuck disapproves it 5 | you should fix it ASAP, remember about the roundhouse kick. Chuck is displayed at project or build pages. 6 | Inspired by Jenkins Chuck Norris plugin (https://wiki.jenkins-ci.org/display/JENKINS/ChuckNorris+Plugin). 7 | 8 | ## Install 9 | Build from source or download latest version here: https://plugins.jetbrains.com/plugin/9060-chuck-norris. After it use this guide to install plugin: https://www.jetbrains.com/help/teamcity/installing-additional-plugins.html 10 | 11 | ## Screenshots 12 | 13 | #### Project page: all builds are ok 14 | ![1](http://i.imgur.com/RHmKUpH.png) 15 | 16 | #### Project page: one of the builds fails 17 | ![2](http://i.imgur.com/M2ymev6.png) 18 | 19 | #### Build page for failed build 20 | ![3](http://i.imgur.com/C31McbA.png) 21 | -------------------------------------------------------------------------------- /chucktcplugin-server/src/main/resources/buildServerResources/Chuck.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="props" tagdir="/WEB-INF/tags/props" %> 2 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | "/> 13 | ${message} 14 | 15 | 16 | "/> 17 | ${message} 18 | 19 | 20 |
21 | -------------------------------------------------------------------------------- /chucktcplugin-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | chucktcplugin 6 | chucktcplugin 7 | 0.5.4 8 | 9 | chucktcplugin-server 10 | jar 11 | 12 | 13 | 14 | org.jetbrains.teamcity 15 | server-api 16 | ${teamcity-version} 17 | provided 18 | 19 | 20 | 21 | org.jetbrains.teamcity 22 | server-web-api 23 | ${teamcity-version} 24 | war 25 | provided 26 | 27 | 28 | 29 | org.jetbrains.teamcity 30 | tests-support 31 | ${teamcity-version} 32 | test 33 | 34 | 35 | 36 | 37 | 38 | 39 | org.apache.maven.plugins 40 | maven-compiler-plugin 41 | 42 | 1.8 43 | 1.8 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | chucktcplugin 5 | chucktcplugin 6 | 0.5.4 7 | pom 8 | 9 | 2020.1 10 | 11 | 12 | 13 | JetBrains 14 | https://download.jetbrains.com/teamcity-repository 15 | 16 | 17 | 18 | 19 | JetBrains 20 | https://download.jetbrains.com/teamcity-repository 21 | 22 | 23 | 24 | 25 | 26 | org.jetbrains.teamcity 27 | teamcity-sdk-maven-plugin 28 | 0.4.1 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | org.jetbrains.teamcity 38 | teamcity-sdk-maven-plugin 39 | 0.4.1 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | chucktcplugin-server 49 | build 50 | 51 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Alexey Moskvin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | ----- 24 | 25 | Images are based on the images from Jenkins Chuck Norris plugin 26 | (https://wiki.jenkins-ci.org/display/JENKINS/ChuckNorris+Plugin) 27 | 28 | /** 29 | * Copyright (c) 2009 Cliffano Subagio 30 | * 31 | * Permission is hereby granted, free of charge, to any person obtaining a copy 32 | * of this software and associated documentation files (the "Software"), to deal 33 | * in the Software without restriction, including without limitation the rights 34 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 35 | * copies of the Software, and to permit persons to whom the Software is 36 | * furnished to do so, subject to the following conditions: 37 | * 38 | * The above copyright notice and this permission notice shall be included in 39 | * all copies or substantial portions of the Software. 40 | * 41 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 42 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 43 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 44 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 45 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 46 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 47 | * THE SOFTWARE. 48 | */ 49 | 50 | ----- 51 | 52 | Chuck Norris facts were taken from http://codesqueeze.com/the-ultimate-top-25-chuck-norris-the-programmer-jokes/ 53 | and permission was provided by the owner of the blog - Max Pool 54 | 55 | -------------------------------------------------------------------------------- /chucktcplugin-server/src/main/java/chucktcplugin/ChuckBuildPageExtension.java: -------------------------------------------------------------------------------- 1 | package chucktcplugin; 2 | 3 | import jetbrains.buildServer.controllers.BuildDataExtensionUtil; 4 | import jetbrains.buildServer.log.Loggers; 5 | import jetbrains.buildServer.serverSide.SBuild; 6 | import jetbrains.buildServer.serverSide.SBuildServer; 7 | import jetbrains.buildServer.web.openapi.PagePlaces; 8 | import jetbrains.buildServer.web.openapi.PlaceId; 9 | import jetbrains.buildServer.web.openapi.PluginDescriptor; 10 | import jetbrains.buildServer.web.openapi.SimplePageExtension; 11 | import org.apache.commons.io.IOUtils; 12 | import org.jetbrains.annotations.NotNull; 13 | 14 | import javax.servlet.http.HttpServletRequest; 15 | import java.io.IOException; 16 | import java.util.List; 17 | import java.util.Map; 18 | import java.util.Random; 19 | 20 | 21 | public class ChuckBuildPageExtension extends SimplePageExtension { 22 | 23 | private SBuildServer buildServer; 24 | private List quotes; 25 | private PluginDescriptor pluginDescriptor; 26 | 27 | public ChuckBuildPageExtension(PagePlaces pagePlaces, PluginDescriptor pluginDescriptor, SBuildServer buildServer) { 28 | super(pagePlaces, PlaceId.BUILD_RESULTS_FRAGMENT, "chucktcpluginBuild", pluginDescriptor.getPluginResourcesPath("Chuck.jsp")); 29 | register(); 30 | this.buildServer = buildServer; 31 | this.pluginDescriptor = pluginDescriptor; 32 | try { 33 | this.quotes = (List)IOUtils.readLines( 34 | getClass().getResourceAsStream("/buildServerResources/quotes.txt"), "UTF-8" 35 | ); 36 | } catch (IOException e) { 37 | Loggers.SERVER.error("Failed to load quotes", e); 38 | } 39 | } 40 | 41 | @Override 42 | public boolean isAvailable(@NotNull HttpServletRequest request) { 43 | SBuild build = getBuild(request); 44 | return build != null && build.isFinished(); 45 | } 46 | 47 | @Override 48 | public void fillModel(@NotNull Map model, @NotNull HttpServletRequest request) { 49 | 50 | SBuild build = getBuild(request); 51 | model.put("chuckHappy", build.getBuildStatus().isSuccessful()); 52 | model.put("sadImage", pluginDescriptor.getPluginResourcesPath("_chuck_sad.jpg")); 53 | model.put("happyImage", pluginDescriptor.getPluginResourcesPath("_chuck_happy.jpg")); 54 | String quote = quotes.get((new Random()).nextInt(quotes.size())); 55 | 56 | if (build.getBuildStatus().isSuccessful()) { 57 | model.put("message", "Chuck Norris approves build #" + build.getBuildNumber() + " and remember that " + quote); 58 | } else { 59 | model.put("message", "Chuck Norris disapproves build #" + build.getBuildNumber() + " and remember that " + quote); 60 | } 61 | } 62 | 63 | private SBuild getBuild(HttpServletRequest request) { 64 | return BuildDataExtensionUtil.retrieveBuild(request, buildServer); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /chucktcplugin-server/src/main/java/chucktcplugin/ChuckProjectPageExtension.java: -------------------------------------------------------------------------------- 1 | package chucktcplugin; 2 | 3 | import jetbrains.buildServer.log.Loggers; 4 | import jetbrains.buildServer.serverSide.*; 5 | import jetbrains.buildServer.web.openapi.PagePlaces; 6 | import jetbrains.buildServer.web.openapi.PlaceId; 7 | import jetbrains.buildServer.web.openapi.PluginDescriptor; 8 | import jetbrains.buildServer.web.openapi.SimplePageExtension; 9 | import org.apache.commons.io.IOUtils; 10 | import org.jetbrains.annotations.NotNull; 11 | 12 | import javax.servlet.http.HttpServletRequest; 13 | import java.io.IOException; 14 | import java.util.*; 15 | 16 | public class ChuckProjectPageExtension extends SimplePageExtension { 17 | private SBuildServer buildServer; 18 | private List quotes; 19 | private PluginDescriptor pluginDescriptor; 20 | 21 | public ChuckProjectPageExtension(PagePlaces pagePlaces, PluginDescriptor pluginDescriptor, SBuildServer buildServer) { 22 | super(pagePlaces, PlaceId.PROJECT_FRAGMENT, "chucktcpluginProject", pluginDescriptor.getPluginResourcesPath("Chuck.jsp")); 23 | register(); 24 | this.buildServer = buildServer; 25 | this.pluginDescriptor = pluginDescriptor; 26 | try { 27 | this.quotes = (List) IOUtils.readLines( 28 | getClass().getResourceAsStream("/buildServerResources/quotes.txt"), "UTF-8" 29 | ); 30 | } catch (IOException e) { 31 | Loggers.SERVER.error("Failed to load quotes", e); 32 | } 33 | } 34 | 35 | @Override 36 | public boolean isAvailable(@NotNull HttpServletRequest request) { 37 | return true; 38 | } 39 | 40 | @Override 41 | public void fillModel(@NotNull Map model, @NotNull HttpServletRequest request) { 42 | Set fails = new HashSet<>(); 43 | String projectId = request.getParameter("projectId"); 44 | SProject project = buildServer.getProjectManager().findProjectByExternalId(projectId); 45 | for (SBuildType buildType : project.getBuildTypes()) { 46 | List builds = buildType.getHistory(); 47 | if (!builds.isEmpty()) { 48 | SFinishedBuild lastBuild = builds.iterator().next(); 49 | if (!lastBuild.getBuildStatus().isSuccessful()) { 50 | fails.add(buildType.getName()); 51 | } 52 | } 53 | } 54 | 55 | model.put("chuckHappy", fails.isEmpty()); 56 | model.put("sadImage", pluginDescriptor.getPluginResourcesPath("_chuck_sad.jpg")); 57 | model.put("happyImage", pluginDescriptor.getPluginResourcesPath("_chuck_happy.jpg")); 58 | String quote = quotes.get((new Random()).nextInt(quotes.size())) ; 59 | 60 | if (fails.isEmpty()) { 61 | model.put("message", "Chuck Norris approves all your builds for " + project.getName() + " and remember that " + quote); 62 | } else { 63 | model.put("message", "Chuck Norris disapproves builds for " + String.join(", ", fails) + " and remember that " + quote); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /chucktcplugin-server/src/main/resources/buildServerResources/quotes.txt: -------------------------------------------------------------------------------- 1 | when Chuck Norris throws exceptions, it’s across the room. 2 | all arrays Chuck Norris declares are of infinite size, because Chuck Norris knows no bounds. 3 | Chuck Norris doesn’t have disk latency because the hard drive knows to hurry the hell up. 4 | Chuck Norris writes code that optimizes itself. 5 | Chuck Norris can’t test for equality because he has no equal. 6 | Chuck Norris doesn’t need garbage collection because he doesn’t call .Dispose(), he calls .DropKick(). 7 | Chuck Norris’s first program was kill -9. 8 | Chuck Norris burst the dot com bubble. 9 | all browsers support the hex definitions #chuck and #norris for the colors black and blue. 10 | MySpace actually isn’t your space, it’s Chuck’s (he just lets you use it). 11 | Chuck Norris can write infinite recursion functions…and have them return. 12 | Chuck Norris can solve the Towers of Hanoi in one move. 13 | the only pattern Chuck Norris knows is God Object. 14 | Chuck Norris finished World of Warcraft. 15 | project managers never ask Chuck Norris for estimations…ever. 16 | Chuck Norris doesn’t use web standards as the web will conform to him. 17 | “It works on my machine” always holds true for Chuck Norris. 18 | Chuck Norris doesn’t do Burn Down charts, he does Smack Down charts. 19 | Chuck Norris can delete the Recycling Bin. 20 | Chuck Norris’s beard can type 140 wpm. 21 | Chuck Norris can unit test entire applications with a single assert. 22 | Chuck Norris doesn’t bug hunt as that signifies a probability of failure, he goes bug killing. 23 | Chuck Norris’s keyboard doesn’t have a Ctrl key because nothing controls Chuck Norris. 24 | when Chuck Norris is web surfing websites get the message “Warning: Internet Explorer has deemed this user to be malicious or dangerous. Proceed?”. 25 | Chuck Norris can overflow your stack just by looking at it. 26 | to Chuck Norris, everything contains a vulnerability. 27 | Chuck Norris doesn’t need sudo, he just types “Chuck Norris” before his commands. 28 | Chuck Norris doesn’t use strongly-typed languages. He uses strong languages. 29 | the class object inherits from Chuck Norris. 30 | for Chuck Norris, NP-Hard = O(1). 31 | Chuck Norris solved the Travelling Salesman problem in O(1) time. Here’s the pseudo-code: Break salesman into N pieces. Kick each piece to a different city. 32 | Chuck Norris compresses his files by doing a flying round house kick to the hard drive. 33 | Chuck Norris once won a game of connect four in 3 moves. 34 | no one has ever pair-programmed with Chuck Norris and lived to tell about it. 35 | Chuck Norris doesn’t need Google. Google needs Chuck Norris. 36 | Chuck Norris can order programs run faster. 37 | Chuck Norris does not sort, he orders. 38 | Chuck Norris does infinite loops in 4 seconds. 39 | Chuck Norris doesn’t need garbage collection, his objects knows when they are not wanted. 40 | Chuck Norris can brute force anything in constant time. 41 | when Chuck Norris dereferences NULL pointers, he always gets what he wants. 42 | Chuck Norris does pair programming on his own. 43 | Chuck Norris never get locking wrong. His programs are too afraid to deadlock. 44 | Chuck Norris doesn’t need a debugger, he just stares down the bug until the code confesses. 45 | Chuck Norris can access private methods. 46 | no statement can catch the ChuckNorrisException. 47 | Chuck Norris can write multi-threaded applications with a single thread. 48 | there is no Esc key on Chuck Norris’ keyboard, because no one escapes Chuck Norris. 49 | Chuck Norris can binary search unsorted data. 50 | Chuck Norris doesn’t needs try-catch, exceptions are too afraid to raise. 51 | Chuck Norris went out of an infinite loop. 52 | Chuck Norris can read all encrypted data, because nothing can hide from Chuck Norris. 53 | Chuck Norris hosting is 101% uptime guaranteed. 54 | Chuck Norris compresses his files by doing a flying round house kick to the hard drive. 55 | Chick Norris solved the halting problem. 56 | Chuck Norris can retrieve anything from /dev/null. 57 | Chuck Norris does not sort, he orders. 58 | Product Owners never argue with Chuck Norris after he demonstrates the DropKick feature. 59 | Chuck Norris can write to ROM. 60 | Wi-Fi searches Chuck Norris. 61 | Chuck Norris can perform a DoS attack by looking at a system. --------------------------------------------------------------------------------