Merge "Add jenkins jobConfigHistory plugin"
diff --git a/Dockerfile b/Dockerfile
index 74fab9f..3cf4aac 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -36,10 +36,10 @@
# jenkins version being bundled in this docker image
ARG JENKINS_VERSION
-ENV JENKINS_VERSION ${JENKINS_VERSION:-2.52}
+ENV JENKINS_VERSION ${JENKINS_VERSION:-2.83}
# jenkins.war checksum, download will be validated using it
-ARG JENKINS_SHA=7a78fc8b3f1eacd45891d052f7fa03471a60b9df52213b4ee948e05834cffc38
+ARG JENKINS_SHA=7f99c4ae050a1733390578145b8490bfe5d09f0132067bf05d18f2b6be953d8e
# Can be used to customize where jenkins.war get downloaded from
ARG JENKINS_URL=https://repo.jenkins-ci.org/public/org/jenkins-ci/main/jenkins-war/${JENKINS_VERSION}/jenkins-war-${JENKINS_VERSION}.war
@@ -75,20 +75,22 @@
COPY theme /usr/share/jenkins/ref/userContent/theme
RUN JENKINS_UC_DOWNLOAD=http://archives.jenkins-ci.org /usr/local/bin/install-plugins.sh \
- ansicolor \
artifactory \
build-blocker-plugin \
build-monitor-plugin \
build-user-vars-plugin \
categorized-view \
+ copyartifact \
description-setter \
discard-old-build \
docker-workflow \
email-ext \
+ envinject \
extended-choice-parameter \
extensible-choice-parameter \
gerrit-trigger \
git \
+ github \
heavy-job \
jobConfigHistory \
ldap \
@@ -97,11 +99,13 @@
monitoring \
permissive-script-security \
pipeline-utility-steps \
+ prometheus \
rebuild \
simple-theme-plugin \
slack \
+ ssh-agent \
test-stability \
- timestamper \
+ throttle-concurrents \
workflow-cps \
workflow-remote-loader \
workflow-scm-step
diff --git a/theme/js/ansi_up.js b/theme/js/ansi_up.js
new file mode 100644
index 0000000..f24c0b6
--- /dev/null
+++ b/theme/js/ansi_up.js
@@ -0,0 +1,334 @@
+/* ansi_up.js
+ * author : Dru Nelson
+ * license : MIT
+ * http://github.com/drudru/ansi_up
+ */
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['exports'], factory);
+ } else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {
+ // CommonJS
+ factory(exports);
+ } else {
+ // Browser globals
+ var exp = {};
+ factory(exp);
+ root.AnsiUp = exp.default;
+ }
+}(this, function (exports) {
+"use strict";
+function rgx(tmplObj) {
+ var subst = [];
+ for (var _i = 1; _i < arguments.length; _i++) {
+ subst[_i - 1] = arguments[_i];
+ }
+ var regexText = tmplObj.raw[0];
+ var wsrgx = /^\s+|\s+\n|\s+#[\s\S]+?\n/gm;
+ var txt2 = regexText.replace(wsrgx, '');
+ return new RegExp(txt2, 'm');
+}
+var AnsiUp = (function () {
+ function AnsiUp() {
+ this.VERSION = "2.0.2";
+ this.ansi_colors = [
+ [
+ { rgb: [0, 0, 0], class_name: "ansi-black" },
+ { rgb: [187, 0, 0], class_name: "ansi-red" },
+ { rgb: [0, 187, 0], class_name: "ansi-green" },
+ { rgb: [187, 187, 0], class_name: "ansi-yellow" },
+ { rgb: [0, 0, 187], class_name: "ansi-blue" },
+ { rgb: [187, 0, 187], class_name: "ansi-magenta" },
+ { rgb: [0, 187, 187], class_name: "ansi-cyan" },
+ { rgb: [255, 255, 255], class_name: "ansi-white" }
+ ],
+ [
+ { rgb: [85, 85, 85], class_name: "ansi-bright-black" },
+ { rgb: [255, 85, 85], class_name: "ansi-bright-red" },
+ { rgb: [0, 255, 0], class_name: "ansi-bright-green" },
+ { rgb: [255, 255, 85], class_name: "ansi-bright-yellow" },
+ { rgb: [85, 85, 255], class_name: "ansi-bright-blue" },
+ { rgb: [255, 85, 255], class_name: "ansi-bright-magenta" },
+ { rgb: [85, 255, 255], class_name: "ansi-bright-cyan" },
+ { rgb: [255, 255, 255], class_name: "ansi-bright-white" }
+ ]
+ ];
+ this.htmlFormatter = {
+ transform: function (fragment, instance) {
+ var txt = fragment.text;
+ if (txt.length === 0)
+ return txt;
+ if (instance._escape_for_html)
+ txt = instance.old_escape_for_html(txt);
+ if (!fragment.bright && fragment.fg === null && fragment.bg === null)
+ return txt;
+ var styles = [];
+ var classes = [];
+ var fg = fragment.fg;
+ var bg = fragment.bg;
+ if (fg === null && fragment.bright)
+ fg = instance.ansi_colors[1][7];
+ if (!instance._use_classes) {
+ if (fg)
+ styles.push("color:rgb(" + fg.rgb.join(',') + ")");
+ if (bg)
+ styles.push("background-color:rgb(" + bg.rgb + ")");
+ }
+ else {
+ if (fg) {
+ if (fg.class_name !== 'truecolor') {
+ classes.push(fg.class_name + "-fg");
+ }
+ else {
+ styles.push("color:rgb(" + fg.rgb.join(',') + ")");
+ }
+ }
+ if (bg) {
+ if (bg.class_name !== 'truecolor') {
+ classes.push(bg.class_name + "-bg");
+ }
+ else {
+ styles.push("background-color:rgb(" + bg.rgb.join(',') + ")");
+ }
+ }
+ }
+ var class_string = '';
+ var style_string = '';
+ if (classes.length)
+ class_string = " class=\"" + classes.join(' ') + "\"";
+ if (styles.length)
+ style_string = " style=\"" + styles.join(';') + "\"";
+ return "<span" + class_string + style_string + ">" + txt + "</span>";
+ },
+ compose: function (segments, instance) {
+ return segments.join("");
+ }
+ };
+ this.textFormatter = {
+ transform: function (fragment, instance) {
+ return fragment.text;
+ },
+ compose: function (segments, instance) {
+ return segments.join("");
+ }
+ };
+ this.setup_256_palette();
+ this._use_classes = false;
+ this._escape_for_html = true;
+ this.bright = false;
+ this.fg = this.bg = null;
+ this._buffer = '';
+ }
+ Object.defineProperty(AnsiUp.prototype, "use_classes", {
+ get: function () {
+ return this._use_classes;
+ },
+ set: function (arg) {
+ this._use_classes = arg;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(AnsiUp.prototype, "escape_for_html", {
+ get: function () {
+ return this._escape_for_html;
+ },
+ set: function (arg) {
+ this._escape_for_html = arg;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ AnsiUp.prototype.setup_256_palette = function () {
+ var _this = this;
+ this.palette_256 = [];
+ this.ansi_colors.forEach(function (palette) {
+ palette.forEach(function (rec) {
+ _this.palette_256.push(rec);
+ });
+ });
+ var levels = [0, 95, 135, 175, 215, 255];
+ for (var r = 0; r < 6; ++r) {
+ for (var g = 0; g < 6; ++g) {
+ for (var b = 0; b < 6; ++b) {
+ var col = { rgb: [levels[r], levels[g], levels[b]], class_name: 'truecolor' };
+ this.palette_256.push(col);
+ }
+ }
+ }
+ var grey_level = 8;
+ for (var i = 0; i < 24; ++i, grey_level += 10) {
+ var gry = { rgb: [grey_level, grey_level, grey_level], class_name: 'truecolor' };
+ this.palette_256.push(gry);
+ }
+ };
+ AnsiUp.prototype.old_escape_for_html = function (txt) {
+ return txt.replace(/[&<>]/gm, function (str) {
+ if (str === "&")
+ return "&";
+ if (str === "<")
+ return "<";
+ if (str === ">")
+ return ">";
+ });
+ };
+ AnsiUp.prototype.old_linkify = function (txt) {
+ return txt.replace(/(https?:\/\/[^\s]+)/gm, function (str) {
+ return "<a href=\"" + str + "\">" + str + "</a>";
+ });
+ };
+ AnsiUp.prototype.detect_incomplete_ansi = function (txt) {
+ return !(/.*?[\x40-\x7e]/.test(txt));
+ };
+ AnsiUp.prototype.detect_incomplete_link = function (txt) {
+ var found = false;
+ for (var i = txt.length - 1; i > 0; i--) {
+ if (/\s|\x1B/.test(txt[i])) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ if (/(https?:\/\/[^\s]+)/.test(txt))
+ return 0;
+ else
+ return -1;
+ }
+ var prefix = txt.substr(i + 1, 4);
+ if (prefix.length === 0)
+ return -1;
+ if ("http".indexOf(prefix) === 0)
+ return (i + 1);
+ };
+ AnsiUp.prototype.ansi_to = function (txt, formatter) {
+ var pkt = this._buffer + txt;
+ this._buffer = '';
+ var raw_text_pkts = pkt.split(/\x1B\[/);
+ if (raw_text_pkts.length === 1)
+ raw_text_pkts.push('');
+ this.handle_incomplete_sequences(raw_text_pkts);
+ var first_chunk = this.with_state(raw_text_pkts.shift());
+ var blocks = new Array(raw_text_pkts.length);
+ for (var i = 0, len = raw_text_pkts.length; i < len; ++i) {
+ blocks[i] = (formatter.transform(this.process_ansi(raw_text_pkts[i]), this));
+ }
+ if (first_chunk.text.length > 0)
+ blocks.unshift(formatter.transform(first_chunk, this));
+ return formatter.compose(blocks, this);
+ };
+ AnsiUp.prototype.ansi_to_html = function (txt) {
+ return this.ansi_to(txt, this.htmlFormatter);
+ };
+ AnsiUp.prototype.ansi_to_text = function (txt) {
+ return this.ansi_to(txt, this.textFormatter);
+ };
+ AnsiUp.prototype.with_state = function (text) {
+ return { bright: this.bright, fg: this.fg, bg: this.bg, text: text };
+ };
+ AnsiUp.prototype.handle_incomplete_sequences = function (chunks) {
+ var last_chunk = chunks[chunks.length - 1];
+ if ((last_chunk.length > 0) && this.detect_incomplete_ansi(last_chunk)) {
+ this._buffer = "\x1B[" + last_chunk;
+ chunks.pop();
+ chunks.push('');
+ }
+ else {
+ if (last_chunk.slice(-1) === "\x1B") {
+ this._buffer = "\x1B";
+ console.log("raw", chunks);
+ chunks.pop();
+ chunks.push(last_chunk.substr(0, last_chunk.length - 1));
+ console.log(chunks);
+ console.log(last_chunk);
+ }
+ if (chunks.length === 2 &&
+ chunks[1] === "" &&
+ chunks[0].slice(-1) === "\x1B") {
+ this._buffer = "\x1B";
+ last_chunk = chunks.shift();
+ chunks.unshift(last_chunk.substr(0, last_chunk.length - 1));
+ }
+ }
+ };
+ AnsiUp.prototype.process_ansi = function (block) {
+ if (!this._sgr_regex) {
+ this._sgr_regex = (_a = ["\n ^ # beginning of line\n ([!<-?]?) # a private-mode char (!, <, =, >, ?)\n ([d;]*) # any digits or semicolons\n ([ -/]? # an intermediate modifier\n [@-~]) # the command\n ([sS]*) # any text following this CSI sequence\n "], _a.raw = ["\n ^ # beginning of line\n ([!\\x3c-\\x3f]?) # a private-mode char (!, <, =, >, ?)\n ([\\d;]*) # any digits or semicolons\n ([\\x20-\\x2f]? # an intermediate modifier\n [\\x40-\\x7e]) # the command\n ([\\s\\S]*) # any text following this CSI sequence\n "], rgx(_a));
+ }
+ var matches = block.match(this._sgr_regex);
+ if (!matches) {
+ return this.with_state(block);
+ }
+ var orig_txt = matches[4];
+ if (matches[1] !== '' || matches[3] !== 'm') {
+ return this.with_state(orig_txt);
+ }
+ var sgr_cmds = matches[2].split(';');
+ while (sgr_cmds.length > 0) {
+ var sgr_cmd_str = sgr_cmds.shift();
+ var num = parseInt(sgr_cmd_str, 10);
+ if (isNaN(num) || num === 0) {
+ this.fg = this.bg = null;
+ this.bright = false;
+ }
+ else if (num === 1) {
+ this.bright = true;
+ }
+ else if (num === 22) {
+ this.bright = false;
+ }
+ else if (num === 39) {
+ this.fg = null;
+ }
+ else if (num === 49) {
+ this.bg = null;
+ }
+ else if ((num >= 30) && (num < 38)) {
+ var bidx = this.bright ? 1 : 0;
+ this.fg = this.ansi_colors[bidx][(num - 30)];
+ }
+ else if ((num >= 90) && (num < 98)) {
+ this.fg = this.ansi_colors[1][(num - 90)];
+ }
+ else if ((num >= 40) && (num < 48)) {
+ this.bg = this.ansi_colors[0][(num - 40)];
+ }
+ else if ((num >= 100) && (num < 108)) {
+ this.bg = this.ansi_colors[1][(num - 100)];
+ }
+ else if (num === 38 || num === 48) {
+ if (sgr_cmds.length > 0) {
+ var is_foreground = (num === 38);
+ var mode_cmd = sgr_cmds.shift();
+ if (mode_cmd === '5' && sgr_cmds.length > 0) {
+ var palette_index = parseInt(sgr_cmds.shift(), 10);
+ if (palette_index >= 0 && palette_index <= 255) {
+ if (is_foreground)
+ this.fg = this.palette_256[palette_index];
+ else
+ this.bg = this.palette_256[palette_index];
+ }
+ }
+ if (mode_cmd === '2' && sgr_cmds.length > 2) {
+ var r = parseInt(sgr_cmds.shift(), 10);
+ var g = parseInt(sgr_cmds.shift(), 10);
+ var b = parseInt(sgr_cmds.shift(), 10);
+ if ((r >= 0 && r <= 255) && (g >= 0 && g <= 255) && (b >= 0 && b <= 255)) {
+ var c = { rgb: [r, g, b], class_name: 'truecolor' };
+ if (is_foreground)
+ this.fg = c;
+ else
+ this.bg = c;
+ }
+ }
+ }
+ }
+ }
+ return this.with_state(orig_txt);
+ var _a;
+ };
+ return AnsiUp;
+}());
+//# sourceMappingURL=ansi_up.js.map
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.default = AnsiUp;
+}));
\ No newline at end of file
diff --git a/theme/mirantis.js b/theme/mirantis.js
index e69de29..d838b85 100644
--- a/theme/mirantis.js
+++ b/theme/mirantis.js
@@ -0,0 +1,58 @@
+
+// ------ Jenkins ANSI color pure JS plugin https://github.com/jakubjosef/jenkins-ansi-color-js ------ //
+function DOMReady(fn) {
+ if (document.attachEvent ? document.readyState === "complete" : document.readyState !== "loading") {
+ fn();
+ } else {
+ document.addEventListener('DOMContentLoaded', fn);
+ }
+}
+
+function addScript(src, callback, async) {
+ var s = document.createElement('script');
+ s.setAttribute('src', src);
+ s.onload = callback;
+ if (async) s.async = true
+ document.body.appendChild(s);
+}
+
+DOMReady(function() {
+ var consoleOutputSelector = ".console-output";
+ if (document.querySelector(consoleOutputSelector)) {
+ // init ansi colors
+ addScript("/userContent/theme/js/ansi_up.js", function() {
+ var ansiUp = new AnsiUp,
+ $console = document.querySelector(consoleOutputSelector),
+ entities = {
+ 'amp': '&',
+ 'apos': '\'',
+ '#x27': '\'',
+ '#x2F': '/',
+ '#39': '\'',
+ '#47': '/',
+ 'lt': '<',
+ 'gt': '>',
+ 'nbsp': ' ',
+ 'quot': '"'
+ },
+ decodeHTMLEntities = function(text) {
+ return text.replace(/&([^;]+);/gm, function(match, entity) {
+ return entities[entity] || match
+ })
+ },
+ colorizeFn = function() {
+ $console.innerHTML = decodeHTMLEntities(ansiUp.ansi_to_html($console.innerHTML));
+ };
+
+ colorizeFn();
+ // create prototype.js global ajax handle responder
+ Ajax.Responders.register({
+ onComplete: function(req, res) {
+ if (req.body.indexOf("start=") != -1 && res.status==200 && res.responseText != "") {
+ colorizeFn();
+ }
+ }
+ });
+ }, true);
+ }
+});
\ No newline at end of file