動(dòng)手實(shí)踐:美化 Jenkins 報(bào)告插件的用戶界面

本文首發(fā)于: Jenkins 中文社區(qū)

原文鏈接 作者:Ullrich Hafner

譯者:wenjunzhangp

動(dòng)手實(shí)踐:美化 Jenkins 報(bào)告插件的用戶界面

進(jìn)來看看,關(guān)于 Jenkins 新的 UI 插件介紹以及他們的教程、用法都在這里了

封面圖

對于 Jenkins 而言,可以使用大量插件來可視化各種構(gòu)建步驟的結(jié)果。有一些插件可用于呈現(xiàn)測試結(jié)果、代碼覆蓋率、靜態(tài)分析等。所有這些插件通常都會(huì)獲取給定構(gòu)建步驟的構(gòu)建結(jié)果,并在用戶界面中顯示它們。為了呈現(xiàn)這些細(xì)節(jié),大多數(shù)插件使用靜態(tài) HTML 頁面,因?yàn)檫@種類型的用戶界面是 Jenkins 自 2007 年成立以來的標(biāo)準(zhǔn)可視化。

為了改善這些插件的外觀和用戶體驗(yàn),有必要向前發(fā)展并合并一些現(xiàn)代 Java Script 庫和組件。由于 Blue Ocean 的開發(fā)已經(jīng)停止(請參閱Jenkins mailing list post),因此插件作者需要自己決定,哪些 UI 技術(shù)可幫助完成該任務(wù)。但是,現(xiàn)代 UI 組件的種類繁多,以至于只挑選一小部分被證明是有用的并且與 Jenkins 基礎(chǔ) Web 技術(shù)兼容的組件是有意義的。而且,合并這樣一個(gè)新組件的初始設(shè)置相當(dāng)大,因此如果該工作僅需要執(zhí)行一次,將會(huì)有很大的幫助。

本指南介紹了一些 UI 組件,以后所有插件作者都可以使用這些 UI 組件,從而為 Jenkins 中的報(bào)告提供豐富的用戶界面。為了簡化這些庫在 Jenkins 作為基于 Java 的 Web 應(yīng)用程序的上下文中的使用,這些 Java Script 庫和組件已打包為普通的 Jenkins 插件。

在以下各小節(jié)中,將逐步介紹這些新組件。為了了解如何使用這些組件的插件,我將演示新功能,同時(shí)使用新的用戶界面增強(qiáng)現(xiàn)有的Forensics Plugin。由于 Warnings Next Generation 插件也使用這些新組件,因此您可以在warnings 插件的文檔中或在我們的公共ci.jenkins.io 實(shí)例中看到其他示例,這些示例已經(jīng)在 warnings 插件的詳細(xì)信息視圖中使用了這些組件。

新的用戶界面插件

新的 Jenkins 插件提供了以下 UI 組件:

  • jquery3-api-plugin:為 Jenkins 插件提供jQuery 3。如其首頁所述,jQuery 是一個(gè)快速、小型且功能豐富的 JavaScript 庫。借助易于使用的 API(可在多種瀏覽器中使用),使 HTML 文檔的遍歷和操作、事件處理、動(dòng)畫和 Ajax 等事情變得更加簡單。兼具多功能性和可擴(kuò)展性,jQuery 改變了數(shù)百萬人編寫 JavaScript 的方式。
  • bootstrap4-api-plugin:為 Jenkins 插件提供Bootstrap 4。Bootstrap 自稱是世界上最流行的前端組件庫,用于在 Web 上構(gòu)建響應(yīng)式,移動(dòng)優(yōu)先的項(xiàng)目。它是一個(gè)用于使用 HTML、CSS 和 JS 開發(fā)的開源工具包。開發(fā)人員可以使用他們的 Sass 變量和 mixins、響應(yīng)式柵格系統(tǒng)、大量的預(yù)構(gòu)建組件以及基于 jQuery 構(gòu)建的強(qiáng)大插件,快速構(gòu)建其思想原型或整個(gè)應(yīng)用程序。
  • data-tables-api-plugin:提供 Jenkins 插件的數(shù)據(jù)表格。DataTables 是 jQuery Javascript 庫的插件。這是一個(gè)高度靈活的工具,建立在逐步增強(qiáng)的基礎(chǔ)上,可將所有這些高級功能添加到任何 HTML 表中:
    • 上一頁,下一頁和頁面導(dǎo)航
    • 通過文本搜索過濾結(jié)果
    • 一次按多列對數(shù)據(jù)排序
    • DOM、Javascript、Ajax、服務(wù)器端處理
    • 簡單主題化
    • 手機(jī)端兼容友好
  • echarts-api-plugin:為 Jenkins 插件提供ECharts。ECharts 是一種開放源代碼的 JavaScript 可視化工具,用于創(chuàng)建直觀、交互式和高度可定制的圖表。它可以在 PC 和移動(dòng)設(shè)備上流暢運(yùn)行,并且與大多數(shù)現(xiàn)代 Web 瀏覽器兼容。
  • font-awesome-api-plugin:為 Jenkins 插件提供Font Awesome。Font Awesome 具有矢量圖標(biāo)和社交徽標(biāo),號稱是網(wǎng)絡(luò)上最受歡迎的圖標(biāo)集和工具包。目前,它包含 1,500 多個(gè)免費(fèi)圖標(biāo)。
  • popper-api-plugin:為 Jenkins 插件提供Popper.js。Popper 只需一行代碼即可輕松定位工具提示,彈出窗口或其他任何內(nèi)容。
  • plugin-util-api-plugin:這個(gè)小插件提供了一些幫助程序和基類,以簡化 Jenkins 中報(bào)告程序的創(chuàng)建。該插件還提供了一組體系結(jié)構(gòu)規(guī)則,這些規(guī)則可以包含在插件的體系結(jié)構(gòu)測試套件中。

POM 文件必要的改變

為了使用這些插件,您需要將它們作為依賴項(xiàng)添加到插件 pom 中。您可以使用以下代碼段將其全部添加:

pom.xml
<project>

 [...]

  <properties>
    <plugin-util-api.version>1.0.2</plugin-util-api.version>
    <font-awesome-api.version>5.12.0-7</font-awesome-api.version>
    <bootstrap4-api.version>4.4.1-10</bootstrap4-api.version>
    <echarts-api.version>4.6.0-8</echarts-api.version>
    <data-tables-api.version>1.10.20-13</data-tables-api.version>
    [...]
  </properties>

  <dependencies>
    <dependency>
      <groupId>io.jenkins.plugins</groupId>
      <artifactId>plugin-util-api</artifactId>
      <version>${plugin-util-api.version}</version>
    </dependency>
    <dependency>
      <groupId>io.jenkins.plugins</groupId>
      <artifactId>font-awesome-api</artifactId>
      <version>${font-awesome-api.version}</version>
    </dependency>
    <dependency>
      <groupId>io.jenkins.plugins</groupId>
      <artifactId>bootstrap4-api</artifactId>
      <version>${bootstrap4-api.version}</version>
    </dependency>
    <dependency>
      <groupId>io.jenkins.plugins</groupId>
      <artifactId>echarts-api</artifactId>
      <version>${echarts-api.version}</version>
    </dependency>
    <dependency>
      <groupId>io.jenkins.plugins</groupId>
      <artifactId>data-tables-api</artifactId>
      <version>${data-tables-api.version}</version>
    </dependency>
    [...]
  </dependencies>

  [...]

</project>

或者,您可以查看Warnings Next Generation 插件Forensics API 插件的 POM 文件,它們已經(jīng)使用了這些插件。

報(bào)告的總體結(jié)構(gòu)

在本節(jié)中,我將解釋 Jenkins 設(shè)計(jì)的一些基礎(chǔ)知識,即 Java 模型和相關(guān)的用戶界面元素。如果您已經(jīng)熟悉如何實(shí)現(xiàn)報(bào)告插件的相應(yīng)擴(kuò)展點(diǎn)(請參閱 Jenkins 開發(fā)人員指南中的可擴(kuò)展性部分),則可以跳過本節(jié),直接進(jìn)入第3.1節(jié)。

Jenkins 使用圖 1所示的靜態(tài)對象模型結(jié)構(gòu)來組織項(xiàng)目。

jenkins-design

Jenkins 用戶界面中的頂級項(xiàng)目是工作(至少是我們感興趣的頂級項(xiàng)目)。Jenkins 包含多個(gè)不同類型的任務(wù)(自由式任務(wù)、Maven任務(wù)、流水線等)。

這些任務(wù)中的每一個(gè)都包含任意數(shù)量的構(gòu)建(或更確切地說,是運(yùn)行)。每個(gè)版本均由其唯一的版本號標(biāo)識。Jenkins 插件可以將結(jié)果附加到這些版本中,例如生成工件、測試結(jié)果、分析報(bào)告等。為了附加這樣的結(jié)果,插件在技術(shù)上需要實(shí)現(xiàn)并創(chuàng)建存儲(chǔ)這些結(jié)果的操作。

這些 Java 對象在幾種不同的視圖中可視化,以下各節(jié)將對其進(jìn)行詳細(xì)描述。顯示所有可用任務(wù)的頂級視圖如圖 2所示。

jobs

插件還可以在這些視圖中提供 UI 元素,但這超出了本指南的范圍。

每個(gè)任務(wù)都有一個(gè)詳細(xì)視圖,插件可以在其中擴(kuò)展相應(yīng)的擴(kuò)展點(diǎn)并提供摘要框和趨勢圖。通常,在工作級別上不需要報(bào)告者摘要框,因此我僅更詳細(xì)地描述趨勢圖,請參見第5.5.2節(jié)。

job

每個(gè)版本也都有一個(gè)詳細(xì)視圖。在這里,插件可以提供類似于“工作詳細(xì)信息”視圖的框的摘要框。通常,插件在這里僅顯示簡短摘要,并提供指向詳細(xì)結(jié)果的鏈接,有關(guān)示例,請參見圖 4。

build

視圖層次結(jié)構(gòu)中的最后一個(gè)元素實(shí)際上是一個(gè)專用視圖,它顯示特定插件的結(jié)果。例如,有些視圖可顯示測試結(jié)果,分析結(jié)果等。完全由給定的插件決定應(yīng)在此處顯示哪些元素。在接下來的幾節(jié)中,我將介紹一些新的 UI 組件,這些組件可用于以愉悅的方式顯示相應(yīng)的結(jié)果。

擴(kuò)展 Jenkins 對象模型

由于報(bào)告程序通常以類似的方式構(gòu)成,因此我用一些其他元素?cái)U(kuò)展了 Jenkins 的原始對象模型(參見圖 1),因此創(chuàng)建或?qū)崿F(xiàn)新的報(bào)告程序插件將更加簡單。這個(gè)新模型如圖 5所示。中心元素是構(gòu)建操作,它將存儲(chǔ)插件報(bào)告程序的結(jié)果。此操作將附加到每個(gè)內(nèi)部版本,并將為報(bào)告者保存(并保留)結(jié)果。每個(gè)動(dòng)作的詳細(xì)數(shù)據(jù)將自動(dòng)存儲(chǔ)在其他文件中,因此,如果用戶從不要求提供詳細(xì)信息,則 Jenkins 的內(nèi)存占用空間可以保持較小。另外,該動(dòng)作還用于簡化項(xiàng)目動(dòng)作和趨勢圖的創(chuàng)建,請參見第5.5.2節(jié)。

Git Forensics 插件

本教程中的元素將全部在新的Forensics API 插件中使用(實(shí)際上,該插件不是新的,它是Warnings Next Generation插件的依賴項(xiàng))。您可以下載插件內(nèi)容,并詳細(xì)了解如何在實(shí)踐中使用這些新組件?;蛘?,您可以更改此插件,只是為了了解如何對這些新組件進(jìn)行參數(shù)設(shè)置。

如果您將 Git 用作源代碼管理系統(tǒng),則此插件將以犯罪現(xiàn)場代碼的樣式(Adam Tornhill,2013 年 11 月)挖掘存儲(chǔ)庫,以確定所包含源代碼文件的統(tǒng)計(jì)信息:

  • 提交總數(shù)
  • 不同作者總數(shù)
  • 創(chuàng)建時(shí)間
  • 最后一次編輯時(shí)間

該插件提供了一個(gè)新的步驟(或發(fā)布后的發(fā)布者)該步驟開始了存儲(chǔ)庫挖掘并將收集的信息存儲(chǔ)在 Jenkins 操作中(請參見圖 5)。然后,您將獲得一個(gè)新的構(gòu)建摘要,該摘要顯示掃描文件的總數(shù)(趨勢和構(gòu)建結(jié)果)。從這里,您可以導(dǎo)航到詳細(xì)信息視圖,該視圖在可以簡單排序和過濾的表中顯示掃描的文件。您還將獲得一些餅圖,這些餅圖顯示提交歷史記錄的重要方面。

請注意,插件的此功能仍是概念證明:此步驟的性能在很大程度上取決于 Git 存儲(chǔ)庫的大小和提交次數(shù)。當(dāng)前,它會(huì)掃描每個(gè)版本中的整個(gè)存儲(chǔ)庫。在不久的將來,我希望找到一個(gè)有志于用增量掃描儀替代這種愚蠢算法的志愿者。

引入新的 UI 組件

第 3 節(jié)所述,詳細(xì)信息視圖特定于插件。顯示的內(nèi)容以及這些元素的顯示方式取決于各個(gè)插件作者。因此,在接下來的部分中,我將提供一些示例和新概念,插件可以將這些示例和新概念用作其自身內(nèi)容的構(gòu)建塊。

現(xiàn)代化圖標(biāo)

Jenkins 插件通常不經(jīng)常使用圖標(biāo)。大多數(shù)插件都提供了操作圖標(biāo),僅此而已。如果您打算在其他地方使用圖標(biāo),那么插件作者將自己留著:推薦的 Tango 圖標(biāo)集已有 10 多年的歷史了,如今太有限了。有幾個(gè)選項(xiàng)可用,但最受歡迎的是Font Awesome Icon Set。它提供超過 1500 個(gè)遵循相同設(shè)計(jì)準(zhǔn)則的免費(fèi)圖標(biāo):

font-awesome

為了在插件中使用 Font Awesome 圖標(biāo),您只需要依賴于相應(yīng)的font-awesome-api-plugin即可。然后,您可以在果凍視圖中使用新標(biāo)簽svg-icon來使用任何實(shí)心圖標(biāo):

index.jelly
1 <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:l="/lib/layout" xmlns:fa="/font-awesome">
2
3 [...]
4 <fa:svg-icon name="check-double" class="no-issues-banner"/>
5 [...]
6
7 </j:jelly>

如果要使用 Java 代碼生成視圖,則也可以使用SvgTag類為此類圖標(biāo)生成 HTML 標(biāo)記。

柵格布局

目前,Jenkins 在所有視圖中都包含 Boostrap 柵格系統(tǒng)的舊版本和補(bǔ)丁版本(24 列)。該版本與 Boostrap4 或任何依賴 Bootstrap4 的 JS 庫不兼容。為了使用 Bootstrap4 功能,我們需要用補(bǔ)丁版本替換 Jenkins 提供的layout.jelly文件,該文件不會(huì)加載損壞的柵格系統(tǒng)。我打算創(chuàng)建一個(gè)PR,以修復(fù) Jenkins 核心中的柵格,但這將需要一些時(shí)間。在此之前,您將需要使用 Boostrap4 插件提供的layout.jelly,請參見下文。

首先要確定的是,哪些元素應(yīng)顯示在插件頁面上以及每個(gè)元素應(yīng)占用多少空間。通常,所有可見組件都使用簡單的柵格映射到可用空間上。在 Jenkins 視圖中,我們具有固定的頁眉和頁腳以及左側(cè)的導(dǎo)航欄(水平空間的20%)。屏幕的其余部分可由詳細(xì)信息視圖使用。為了簡化剩余空間中元素的分布,我們使用Bootstrap 的柵格系統(tǒng)。

grid

這意味著,一個(gè)視圖被分為 12 列和任意數(shù)量的行。此柵格系統(tǒng)易于使用(但足夠復(fù)雜,還可以支持精美的屏幕布局)-我在這里不做詳細(xì)介紹,請參考Bootstrap 文檔。

對于取證詳細(xì)視圖,我們使用兩行兩列的簡單柵格。由于列數(shù)始終為 12,因此我們需要?jiǎng)?chuàng)建兩個(gè)寬列以填充 6 個(gè)標(biāo)準(zhǔn)列。為了在我們的插件中創(chuàng)建這樣的視圖,我們需要?jiǎng)?chuàng)建一個(gè)以果凍文件和相應(yīng)的 Java 視圖模型對象形式給出的視圖。以下代碼段顯示了具有這種布局的視圖:

index.jelly
1 <?jelly escape-by-default='true'?>
2 <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:l="/lib/layout" xmlns:bs="/bootstrap">
3
4   <bs:layout title="${it.displayName}" norefresh="true"> 
5       <st:include it="${it.owner}" page="sidepanel.jelly"/>
6       <l:main-panel>
7           <st:adjunct includes="io.jenkins.plugins.bootstrap4"/> 
8           <div class="fluid-container"> 
9
10              <div class="row py-3"> 
11                  <div class="col-6">
12                      Content of column 1 in row 1
13                  </div>
14                  <div class="col-6"> 
15                      Content of column 2 in row 1
16                  </div>
17              </div>
18          
19              <div class="row py-3"> 
20                  <div class="col">
21                      Content of row 2
22                  </div>
23              </div>
24
25          </div>
26      </l:main-panel>
27  </bs:layout>
28 </j:jelly>

  1. 使用基于 Bootstrap 的自定義布局:由于 Jenkins 核心包含舊版本的 Bootstrap,因此我們需要替換標(biāo)準(zhǔn)的 layout.jelly 文件。
  2. 導(dǎo)入 Bootstrap4:使用輔助概念完成 JS 和 CSS 組件的導(dǎo)入,這是在 Jenkins 的 Stapler Web 框架中引用靜態(tài)資源的首選方式。
  3. 整個(gè)視圖將被放入一個(gè)充滿整個(gè)屏幕(寬度為100%)的流體容器中。
  4. 視圖的新行由類row指定。附加類py-3定義了用于此行的填充,有關(guān)更多詳細(xì)信息,請參見Bootstrap Spacing
  5. 由于 Bootstrap 會(huì)自動(dòng)將一行分成 12 個(gè)相等大小的列,因此我們在此定義第一列應(yīng)占據(jù)這 12 列中的 6 列。您也可以省略詳細(xì)編號,然后 Bootstrap 將自動(dòng)在可用空間中分發(fā)內(nèi)容。請注意,在大多數(shù)情況下這不是您想要的。
  6. 第二列使用剩余空間,即 12 列中的 6 列。
  7. 第二行使用與第一行相同的布局。
  8. 第 1 行只有一列,它將填滿整個(gè)可用空間。

您還可以根據(jù)屏幕的實(shí)際可見大小為一行指定不同的列布局。這有助于改善大屏幕的布局。在警告插件中,您將找到一個(gè)示例:在小型設(shè)備上,有一張可見的卡片可以在輪播中顯示一張餅圖。 如果要在較大的設(shè)備上打開同一頁面,則會(huì)并排顯示兩個(gè)餅圖,并且輪播會(huì)被隱藏。

卡片

當(dāng)將插件信息顯示為一個(gè)塊時(shí),通常會(huì)顯示純文本元素。通常,這將導(dǎo)致某些無關(guān)緊要的網(wǎng)頁。為了創(chuàng)建一個(gè)更具吸引力的界面,在具有邊框、標(biāo)題、圖標(biāo)等的卡片中顯示此類信息是有意義的。為了創(chuàng)建這樣的Bootstrap 卡片,新的Bootstrap 插件提供了一個(gè)小的果凍標(biāo)簽,該標(biāo)簽簡化了插件的此任務(wù)??梢酝ㄟ^以下方式在果凍視圖中輕松創(chuàng)建此類卡片:

1 <bs:card title="${%Card Title}" fontAwesomeIcon="icon-name">
2 Content of the card
3 </bs:card>

圖 8中顯示了此類卡的示例。上排的卡片包含餅圖,這些餅圖顯示了整個(gè)存儲(chǔ)庫中作者和提交數(shù)量的分布。底部的卡在數(shù)據(jù)表中顯示詳細(xì)信息??梢暬粌H限于圖表或表格,您可以在其中顯示任何類型的 HTML 內(nèi)容。您可以在這些卡中顯示插件的任何圖標(biāo),但是建議使用現(xiàn)有的Font Awesome圖標(biāo)之一,以在 Jenkins 的插件生態(tài)系統(tǒng)中獲得一致的外觀。

card

注意,卡片的大小由網(wǎng)格配置決定,請參見第 5.2 節(jié)。

表格

用于顯示插件詳細(xì)信息的常見 UI 元素是表格控件。大多數(shù)插件(和 Jenkins 核心)通常使用純 HTML 表格。但是,如果表格應(yīng)顯示大量行,則使用像DataTables這樣的更復(fù)雜的控件更有意義。使用此基于 JS 的表控件可免費(fèi)提供其他功能:

  • 通過文本搜索過濾結(jié)果
  • 提供結(jié)果集的分頁
  • 一次按多列排序數(shù)據(jù)
  • 使用 Ajax 調(diào)用獲取表行
  • 根據(jù)屏幕分辨率顯示和隱藏列

為了在視圖中使用DataTables,有兩個(gè)選項(xiàng),您可以裝飾現(xiàn)有的靜態(tài) HTML 表(請參見第 5.4.1 節(jié))或使用 Ajax 填充表內(nèi)容(請參見第 5.4.2 節(jié))。

靜態(tài) HTML 內(nèi)容的表格

使用 DataTables 的最簡單方法是創(chuàng)建一個(gè)靜態(tài) HTML 表格,只需調(diào)用 datatable 的構(gòu)造函數(shù)即可對其進(jìn)行修飾。這種方法在 Java 和 Jelly 方面不涉及任何特殊處理,因此我認(rèn)為只需遵循 DataTables 文檔中的示例即可。只需確保在您的 Jelly 文件中構(gòu)建了表之后,您需要使用以下代碼裝飾表:

<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" >

  <st:adjunct includes="io.jenkins.plugins.jquery3"/>
  <st:adjunct includes="io.jenkins.plugins.data-tables"/>

  [...]

    <div class="table-responsive">
        <table class="table table-hover table-striped display" id="id">
            [...]
        </table>
    </div>

  [...]
  <script>
     $('#id').DataTable(); 
  </script>

</j:jelly>

  1. 用您的 HTML 表格元素的 ID 替換上面代碼中的 ID

到目前為止,在 Forensics 插件中還沒有使用過此類靜態(tài)表格,但是您可以查看警告插件中顯示固定警告的表,以了解如何裝飾此類表

具有基于動(dòng)態(tài)模型內(nèi)容的表

盡管靜態(tài) HTML 表格易于實(shí)現(xiàn),但它們有一些限制。因此,遵循更復(fù)雜的方法是有意義的。通常,用戶界面中的表是通過使用相應(yīng)的表(和行)模型定義的。自 Java 成立以來,Java Swing 成功地提供了這樣的表模型概念。我也為 Jenkins 和 DataTables 修改了這些概念。為了在 Jenkins 視圖中創(chuàng)建表,插件需要提供一個(gè)表模型類,該類提供以下信息:

  • 表的 ID(因?yàn)橐晥D中可能有多個(gè)表)
  • 列的模型(即列的編號,類型和標(biāo)題標(biāo)簽)
  • 表格的內(nèi)容(即各個(gè)行對象)

您可以在 Forensics 插件中找到此類表格的示例:此處的表格列出了 Git 存儲(chǔ)庫中的文件以及相應(yīng)的提交統(tǒng)計(jì)信息(作者數(shù)量、提交數(shù)量、最后修改、首次提交)。該表的屏幕截圖如圖 9所示。

table

為了在 Jenkins 中創(chuàng)建這樣的表,您需要?jiǎng)?chuàng)建一個(gè)從TableModel派生的表模型類。在圖 10中,顯示了取證插件中相應(yīng)類的圖。

table-model

表格欄模型

表格模型類定義的第一件事是通過創(chuàng)建相應(yīng)的TableColumn實(shí)例來創(chuàng)建可用列的模型。對于每一列,您需要指定標(biāo)題標(biāo)簽和應(yīng)在相應(yīng)列中顯示的 bean 屬性的名稱(行元素實(shí)際上是 Java bean:每一列將顯示此類 bean 的一個(gè)獨(dú)特屬性,請參閱下一節(jié))。您可以通過簡單地提供基于StringInteger的列來使用任何受支持的列類型。

表格行內(nèi)容

此外,表模型類提供行的內(nèi)容。此getRows()方法將使用 Ajax 調(diào)用異步調(diào)用。通常,此方法僅返回 Java Bean 實(shí)例的列表,該列表提供每一列的屬性(請參見上一節(jié))。這些對象將自動(dòng)轉(zhuǎn)換為 JSON 對象數(shù)組,這是 DataTables API 所需的基本數(shù)據(jù)結(jié)構(gòu)。您可以在ForensicsTableModel類的取證插件的 Git 存儲(chǔ)庫中找到一個(gè)可以正常工作的示例表模型實(shí)現(xiàn)。

為了在插件視圖中使用這樣的表,您需要使用新的table標(biāo)簽在關(guān)聯(lián)的 Jelly 文件中創(chuàng)建表:

index.jelly
<j:jelly xmlns:j="jelly:core" xmlns:dt="/data-tables" >
    [...]
    <st:adjunct includes="io.jenkins.plugins.data-tables"/>

    <dt:table model="${it.getTableModel('id')}"/> 
    [...]
</j:jelly>

  1. 用自己的 ID 替換上面代碼的 ID

您需要為表提供的唯一參數(shù)是 model,它通常是對應(yīng)的 Jenkins 視圖模型類的一部分(此對象在視圖中用${it}引用)。為了將對應(yīng)的 Jenkins 視圖模型類與表連接,視圖模型類需要實(shí)現(xiàn)AsyncTableContentProvider接口。甚至更簡單,讓您的視圖模型類派生自DefaultAsyncTableContentProvider。此關(guān)系是必需的,以便 Jenkins 可以自動(dòng)創(chuàng)建和綁定 Ajax 調(diào)用的代理,該代理將在創(chuàng)建 HTML 頁面后自動(dòng)填充表內(nèi)容。

如果將所有這些部分放在一起,則需要定義一個(gè)類似于 Forensics 插件的模型的模型,如圖 11所示。

forensics-view-model

如在圖 5中已經(jīng)描述的,插件需要將BuildAction附加到每個(gè)構(gòu)建。Forensics 插件將ForensicBuildAction附加到構(gòu)建。該操作存儲(chǔ)一個(gè)RepositoryStatistics實(shí)例,該實(shí)例包含給定構(gòu)建的存儲(chǔ)庫結(jié)果。該操作將所有 Stapler 請求委派給新的Stapler 代理實(shí)例,因此我們可以使該操作清除用戶界面代碼。然后,此ForensicsViewModel類充當(dāng)視圖模型,為文件index.jelly給出的相應(yīng) Jelly 視圖提供服務(wù)器端模型。

雖然這種方法在第一眼看上去很復(fù)雜,但是您會(huì)看到實(shí)際的實(shí)現(xiàn)部分很小。基本類已經(jīng)提供了大多數(shù)樣板代碼,您只需要實(shí)現(xiàn)一些方法即可。使用此概念還提供了一些其他功能,這些功能是 DataTables 插件的一部分:

  • 列的順序會(huì)自動(dòng)保存在瀏覽器本地存儲(chǔ)中。
  • 分頁大小會(huì)自動(dòng)保存在瀏覽器本地存儲(chǔ)中。
  • 僅當(dāng)表格可見時(shí)才實(shí)際調(diào)用 Ajax 調(diào)用。因此,如果選項(xiàng)卡中隱藏了幾個(gè)表,則僅按需加載內(nèi)容,從而減少了要傳輸?shù)臄?shù)據(jù)量。
  • 有一個(gè)選項(xiàng)可用于提供其他詳細(xì)信息行,該行可以用 + 符號擴(kuò)展,有關(guān)詳細(xì)信息,請參閱warnings plugin table。

圖表

插件報(bào)告程序通常還會(huì)報(bào)告從構(gòu)建到構(gòu)建的某種趨勢。到目前為止,Jenkins 核心僅提供了一個(gè)非常有限的概念來呈現(xiàn)諸如趨勢圖之類的趨勢。Jenkins 核心提供的JFreeChart框架是服務(wù)器端渲染引擎,可將圖表創(chuàng)建為靜態(tài) PNG 圖像,并將其包含在任務(wù)和詳細(xì)信息頁面中。如今,有幾個(gè)功能強(qiáng)大的基于 JS 的圖表庫可供使用,它們在客戶端完成相同的工作(實(shí)際上甚至做得更好)。這樣做的好處是可以在每個(gè)客戶端上自定義這些圖表,而不會(huì)影響服務(wù)器性能。此外,您還可以免費(fèi)獲得許多其他功能(例如縮放,動(dòng)畫等)。此外,這些圖表庫不僅支持典型的構(gòu)建趨勢圖,而且還支持許多其他圖表類型,可用于改善插件的用戶體驗(yàn)。這些圖表庫之一是ECharts:該庫具有強(qiáng)大的 API,并且實(shí)際上支持一個(gè)人可以想象的每種圖表類型。您可以在庫的示例頁面上獲得一些功能印象。

為了使用這些圖表,可以通過導(dǎo)入相應(yīng)的 JS 文件并在相應(yīng)的 Jelly 文件中定義圖表來嵌入使用該庫的圖表。盡管這已經(jīng)很好地工作了,但是從詹金斯的構(gòu)建結(jié)果中為這些圖表提供相應(yīng)的模型仍然有些麻煩。因此,我添加了功能強(qiáng)大的 Java API,可幫助在 Java 端為這些圖表創(chuàng)建模型。該 API 提供以下功能:

  • 根據(jù)構(gòu)建結(jié)果的集合創(chuàng)建趨勢圖。
  • 將圖表類型與聚合分開,以簡化圖表模型的單元測試。
  • 在內(nèi)部版本號或內(nèi)部版本日期之間切換 X 軸的類型(自動(dòng)匯總當(dāng)天記錄的結(jié)果)。
  • 將 Java 模型自動(dòng)轉(zhuǎn)換為 JS 端所需的 JSON 模型。
  • 支持餅圖和折線圖(更多內(nèi)容即將推出)。

這些圖表可以在項(xiàng)目頁面中用作趨勢圖(請參見圖 3),也可以在插件的詳細(xì)信息視圖中用作信息圖(請參見第 5 節(jié))。

餅狀圖

一個(gè)簡單但仍然有用的圖表是一個(gè)餅圖,它說明了插件數(shù)據(jù)的數(shù)字比例。在 Forensics 插件中,我使用此圖表來顯示 Git 存儲(chǔ)庫中源代碼文件的作者或提交數(shù)量的數(shù)字比例(請參見圖 8)。在警告插件中,我使用此圖表顯示新警告,突出警告或固定警告的數(shù)字比例,請參見圖 12。

pie

為了在您的詳細(xì)信息視圖中包括這樣的圖表,您可以使用提供的pie-chart標(biāo)簽。在以下代碼片段中,您可以看到此標(biāo)簽的使用情況(嵌入在 Bootstrap 卡片中,請參見第 5.3 節(jié)):

index.jelly
1 <?jelly escape-by-default='true'?>
2   <j:jelly xmlns:j="jelly:core"  xmlns:c="/charts" xmlns:bs="/bootstrap">
3
4   [...]
5   <bs:card title="${%Number of authors}" fontAwesomeIcon="users">
6       <c:pie-chart id="authors" model="${it.authorsModel}" height="256" />
7   </bs:card>
8   [...]
9
10 </j:jelly>

您需要為此圖表提供唯一的 ID 和相應(yīng)的模型值。該模型必須是對應(yīng)的PieChartModel實(shí)例的 JSON 表示形式??梢允褂靡韵聨仔衼韯?chuàng)建這樣的模型:

ViewModel.java
1 [...]
2 PieChartModel model = new PieChartModel("Title");
3
4 model.add(new PieData("Segment 1 name", 10), Palette.RED);
5 model.add(new PieData("Segment 2 name", 15), Palette.GREEN);
6 model.add(new PieData("Segment 3 name", 20), Palette.YELLOW);
7
8 String json = new JacksonFacade().toJson(model);
9 [...]  

任務(wù)級別視圖上的趨勢圖

為了顯示在任務(wù)頁面上呈現(xiàn)折線圖的趨勢(請參見圖 3),您需要提供一個(gè)所謂的浮動(dòng)框(存儲(chǔ)在任務(wù)操作的floatBox.jelly文件中(請參見第 3 節(jié)))。該文件的內(nèi)容非常簡單,僅包含一個(gè)trend-chart標(biāo)簽:

floatingBox.jelly
1 <?jelly escape-by-default='true'?>
2 <j:jelly xmlns:j="jelly:core" xmlns:c="/charts">
3
4   <c:trend-chart it="${from}" title="${%SCM Files Count Trend}" enableLinks="true"/>
5
6 </j:jelly>

在 Java 方面,需要在JobAction的相應(yīng)子類(浮動(dòng)框的所有者)中提供圖表的模型。由于趨勢圖的計(jì)算在服務(wù)器端也非常昂貴(需要從磁盤讀取多個(gè)構(gòu)建,并且需要計(jì)算有趣的數(shù)據(jù)點(diǎn)),因此該過程已放入單獨(dú)的后臺任務(wù)中。一旦計(jì)算完成,將通過 Ajax 調(diào)用顯示結(jié)果。為了為插件作者隱藏這些詳細(xì)信息,您應(yīng)該簡單地從相應(yīng)的AsyncTrendJobAction類派生JobAction類,該類已經(jīng)包含樣板代碼。因此,您的靜態(tài)插件對象模型實(shí)際上會(huì)變得有些復(fù)雜:

chart-model

基本上,您需要實(shí)現(xiàn)LinesChartModel 方法 createChartModel()來創(chuàng)建折線圖。該方法的實(shí)現(xiàn)非常簡單,因?yàn)榇蠖鄶?shù)艱苦的工作都是由庫提供的:從最新的構(gòu)建開始,您將使用構(gòu)建動(dòng)作的迭代器進(jìn)行調(diào)用。迭代器從一個(gè)版本開始構(gòu)建,直到?jīng)]有更多可用結(jié)果為止(或已達(dá)到要考慮的最大構(gòu)建數(shù)量)。在插件中實(shí)現(xiàn)的最重要的事情是如何為給定的BuildAction計(jì)算數(shù)據(jù)點(diǎn)。這是取證插件中此類SeriesBuilder實(shí)現(xiàn)的示例:

FilesCountSeriesBuilder.java
1 package io.jenkins.plugins.forensics.miner;
2
3 import java.util.HashMap;
4 import java.util.Map;
5
6 import edu.hm.hafner.echarts.SeriesBuilder;
7
8 /**
9  * Builds one x-axis point for the series of a line chart showing the number of files in the repository.
10 *
11 * @author Ullrich Hafner
12 */
13 public class FilesCountSeriesBuilder extends SeriesBuilder<ForensicsBuildAction> {
14      static final String TOTALS_KEY = "total";
15
16      @Override
17      protected Map<String, Integer> computeSeries(final ForensicsBuildAction current) {
18          Map<String, Integer> series = new HashMap<>();
19          series.put(TOTALS_KEY, current.getNumberOfFiles());
20          return series;
21      }
22 }

您不僅限于單個(gè)折線圖。您可以在一個(gè)圖表中顯示多條線,可以顯示堆疊的值,甚至可以顯示某些值之間的差異。您也可以查看charts of the warnings plugin,以詳細(xì)了解其中一些功能。

trend-lines
trend-stacked

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容