diff --git a/README.md b/README.md index a48589de..f756601a 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,11 @@ Provides implementation of Pipeline apis for Jenkins pipeline and multi-branch j ## blueocean-web -Web infrastructure that glues Jenkins and Blue Ocean plugin together on the /blue endpoint. +Core Web infrastructure that bootstraps BlueOcean UI and integrates REST API core blueocean-rest. +## blueocean-analytics-tools + +Plugin to inject analytics tools as HTML header in blueocean UI. # Building and running diff --git a/blueocean-analytics-tools/LICENSE.txt b/blueocean-analytics-tools/LICENSE.txt new file mode 100644 index 00000000..26cfa52a --- /dev/null +++ b/blueocean-analytics-tools/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2016 CloudBees Inc and a number of other of contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/blueocean-analytics-tools/README.md b/blueocean-analytics-tools/README.md new file mode 100644 index 00000000..622a6568 --- /dev/null +++ b/blueocean-analytics-tools/README.md @@ -0,0 +1,21 @@ +> Analytics Tools to be injected in to BlueOcean UI + +# RollBar + +* Enable RollBar + +RollBar is disabled by default. Use BLUEOCEAN_ROLLBAR_ENABLED JVM property to enable. + +```` +mvn hpi:run -DBLUEOCEAN_ROLLBAR_ENABLED=true +```` + + +## Usage ... + + try { + foo(); + $blueocean_Rollbar.debug('foo() called'); + } catch (e) { + $blueocean_Rollbar.error('Problem calling foo()', e); + } diff --git a/blueocean-analytics-tools/gulpfile.js b/blueocean-analytics-tools/gulpfile.js new file mode 100644 index 00000000..4379b842 --- /dev/null +++ b/blueocean-analytics-tools/gulpfile.js @@ -0,0 +1,7 @@ +var builder = require('@jenkins-cd/js-builder'); + +// +// Create the rollbar bundle. +// See https://github.com/jenkinsci/js-builder +// +builder.bundle('src/main/js/rollbar.js'); diff --git a/blueocean-analytics-tools/package.json b/blueocean-analytics-tools/package.json new file mode 100644 index 00000000..5668df5b --- /dev/null +++ b/blueocean-analytics-tools/package.json @@ -0,0 +1,20 @@ +{ + "name": "blueocean-analytics-tools", + "version": "0.0.1", + "description": "Analytics tools that gets injected in BlueOcean UI", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Vivek Pandey (https://github.com/vivek)", + "license": "MIT", + "dependencies": { + "@jenkins-cd/js-modules": "0.0.5", + "rollbar-browser": "1.9.1" + }, + "devDependencies": { + "@jenkins-cd/js-builder": "0.0.35", + "babel-eslint": "^6.1.2", + "gulp": "3.9.1", + "eslint-plugin-react": "^5.0.1" + } +} diff --git a/blueocean-analytics-tools/pom.xml b/blueocean-analytics-tools/pom.xml new file mode 100644 index 00000000..7ed8e3c0 --- /dev/null +++ b/blueocean-analytics-tools/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + + io.jenkins.blueocean + blueocean-parent + 1.0-alpha-5-SNAPSHOT + + + blueocean-analytics-tools + hpi + + BlueOcean :: Analytics Tools + https://wiki.jenkins-ci.org/display/JENKINS/Blue+Ocean+Plugin + + + + ${project.groupId} + blueocean-web + + + diff --git a/blueocean-analytics-tools/src/main/java/io/jenkins/blueocean/analyticstools/AnalyticsTools.java b/blueocean-analytics-tools/src/main/java/io/jenkins/blueocean/analyticstools/AnalyticsTools.java new file mode 100644 index 00000000..7b0b68dd --- /dev/null +++ b/blueocean-analytics-tools/src/main/java/io/jenkins/blueocean/analyticstools/AnalyticsTools.java @@ -0,0 +1,22 @@ +package io.jenkins.blueocean.analyticstools; + +import hudson.Extension; +import io.jenkins.blueocean.BluePageDecorator; +import jenkins.model.Jenkins; + +/** + * @author Vivek Pandey + */ +@Extension(ordinal = 10) +public class AnalyticsTools extends BluePageDecorator { + + public boolean isRollBarEnabled(){ + return Boolean.getBoolean("BLUEOCEAN_ROLLBAR_ENABLED"); + } + + + /** gives Blueocean plugin version. blueocean-web being core module is looked at to determine the version */ + public String getBlueOceanPluginVersion(){ + return Jenkins.getInstance().getPlugin("blueocean-web").getWrapper().getVersion(); + } +} diff --git a/blueocean-analytics-tools/src/main/js/rollbar.js b/blueocean-analytics-tools/src/main/js/rollbar.js new file mode 100644 index 00000000..717472be --- /dev/null +++ b/blueocean-analytics-tools/src/main/js/rollbar.js @@ -0,0 +1,59 @@ +function getConfigAttribute(name) { + var headElements = document.getElementsByTagName('head'); + if (headElements.length === 1) { + return headElements[0].getAttribute(name); + } + return undefined; +} + +function normalizeURL(location) { + var normalizedUrl = 'http://anon.blueocean.io' + location; + var rootUrl = getConfigAttribute('data-rooturl'); + if (rootUrl && location.startsWith(rootUrl)) { + normalizedUrl = 'http://anon.blueocean.io' + location.substring(rootUrl.length - 1, location.length); + } + return normalizedUrl; +} + +var transformer = function (payload) { + payload.data.request.user_ip = '0.0.0.0'; + payload.data.request.url = normalizeURL(window.location.pathname); +}; + +// +// Configure rollbar ... +// See https://github.com/rollbar/rollbar.js/tree/master/examples/browserify +// + +var _rollbarConfig = { + accessToken: '81f3134dedf44871b9cc0a347b1313df', + captureUncaught: true, + code_version: window.$blueocean_pluginVersion, // see header.jelly + source_map_enabled: true, + guess_uncaught_frames: true, + transform: transformer +}; + +var rollbarBrowser = require('rollbar-browser'); +var Rollbar = rollbarBrowser.init(_rollbarConfig); + +// Looking at docs (https://github.com/rollbar/rollbar.js/tree/master/examples/browserify) +// it seems like they stuff it into a global. We are trying hard not to do that +// under any circumstances, but maybe this is an exception if it's only going to be +// used in a closed/controlled env. +// +// Soooo .... lets export it to global for now, but as $blueocean_Rollbar ... +// + +window.$blueocean_Rollbar = Rollbar; + +// +// Usage ... +// +//try { +// foo(); +// $blueocean_Rollbar.debug('foo() called'); +//} catch (e) { +// $blueocean_Rollbar.error('Problem calling foo()', e); +//} + diff --git a/blueocean-analytics-tools/src/main/resources/index.jelly b/blueocean-analytics-tools/src/main/resources/index.jelly new file mode 100644 index 00000000..66696cb0 --- /dev/null +++ b/blueocean-analytics-tools/src/main/resources/index.jelly @@ -0,0 +1,4 @@ + +
+ BlueOcean Analytics Tools plugin +
diff --git a/blueocean-analytics-tools/src/main/resources/io/jenkins/blueocean/analyticstools/AnalyticsTools/header.jelly b/blueocean-analytics-tools/src/main/resources/io/jenkins/blueocean/analyticstools/AnalyticsTools/header.jelly new file mode 100644 index 00000000..482a9a76 --- /dev/null +++ b/blueocean-analytics-tools/src/main/resources/io/jenkins/blueocean/analyticstools/AnalyticsTools/header.jelly @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/blueocean-plugin/pom.xml b/blueocean-plugin/pom.xml index 430d81a7..8cf55030 100644 --- a/blueocean-plugin/pom.xml +++ b/blueocean-plugin/pom.xml @@ -44,6 +44,11 @@ blueocean-pipeline-api-impl + + ${project.groupId} + blueocean-analytics-tools + + ${project.groupId} @@ -107,6 +112,7 @@ linkHPI('blueocean-commons'); linkHPI('blueocean-rest-impl'); linkHPI('blueocean-pipeline-api-impl') + linkHPI('blueocean-analytics-tools') diff --git a/blueocean-web/src/main/java/io/jenkins/blueocean/BlueOceanUI.java b/blueocean-web/src/main/java/io/jenkins/blueocean/BlueOceanUI.java index c48e9988..4a21c334 100644 --- a/blueocean-web/src/main/java/io/jenkins/blueocean/BlueOceanUI.java +++ b/blueocean-web/src/main/java/io/jenkins/blueocean/BlueOceanUI.java @@ -2,6 +2,8 @@ package io.jenkins.blueocean; import hudson.ExtensionList; +import java.util.List; + /** * Root of Blue Ocean UI * @@ -34,4 +36,8 @@ public class BlueOceanUI { public String getUrlBase() { return urlBase; } + + public List getPageDecorators(){ + return BluePageDecorator.all(); + } } diff --git a/blueocean-web/src/main/java/io/jenkins/blueocean/BluePageDecorator.java b/blueocean-web/src/main/java/io/jenkins/blueocean/BluePageDecorator.java new file mode 100644 index 00000000..fdfe4bf2 --- /dev/null +++ b/blueocean-web/src/main/java/io/jenkins/blueocean/BluePageDecorator.java @@ -0,0 +1,61 @@ +package io.jenkins.blueocean; + +import hudson.Extension; +import hudson.ExtensionList; +import hudson.ExtensionPoint; + +/** + * Participates in the rendering of HTML pages for all pages of Hudson. + * + *

+ * This class provides a few hooks to augument the HTML generation process of Hudson, across + * all the HTML pages that Hudson delivers. + * + *

+ * For example, if you'd like to add a Google Analytics stat to Hudson, then you need to inject + * a small script fragment to all Hudson pages. This extension point provides a means to do that. + * + *

Life-cycle

+ *

+ * Plugins that contribute this extension point + * should implement a new decorator and put {@link Extension} on the class. + * + *

Associated Views

+ * + * + *

header.jelly

+ *

+ * This page is added right before the </head> tag. Convenient place for additional stylesheet, <meta> tags, etc. + * + *

+ * <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler">
+ *     <script>
+ *         //your JS code
+ *     </script>
+ * </j:jelly>
+ * 
+ * + *

httpHeaders.jelly

+ * + * For example, this httpHeader.jelly adds HTTP X-MY-HEADER + * + *
+ *
+ * <?jelly escape-by-default='true'?>
+ * <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler">
+ *    <st:header name="X-MY-HEADER" value="${it.someValue}"/>
+ * </j:jelly>
+ *
+ * 
+ *

+ * This is a generalization of the X-Jenkins header that aids auto-discovery. + * This fragment can write additional <st:header name="..." value="..." /> tags that go along with it. + * + * @author Vivek Pandey + */ +public abstract class BluePageDecorator implements ExtensionPoint { + + public static ExtensionList all() { + return ExtensionList.lookup(BluePageDecorator.class); + } +} diff --git a/blueocean-web/src/main/resources/io/jenkins/blueocean/BlueOceanUI/index.jelly b/blueocean-web/src/main/resources/io/jenkins/blueocean/BlueOceanUI/index.jelly index 76283452..75749425 100644 --- a/blueocean-web/src/main/resources/io/jenkins/blueocean/BlueOceanUI/index.jelly +++ b/blueocean-web/src/main/resources/io/jenkins/blueocean/BlueOceanUI/index.jelly @@ -1,6 +1,11 @@ + + + + + @@ -29,6 +34,11 @@ + + + + + diff --git a/pom.xml b/pom.xml index 447cdbe5..7099b83c 100644 --- a/pom.xml +++ b/pom.xml @@ -105,6 +105,7 @@ blueocean-dashboard blueocean-personalization blueocean-plugin + blueocean-analytics-tools @@ -172,6 +173,12 @@ ${project.version} + + ${project.groupId} + blueocean-analytics-tools + ${project.version} + + ${project.groupId} blueocean-plugin