├── .github ├── CODEOWNERS ├── codecov.yml ├── renovate.json └── workflows │ ├── codecov.yml │ ├── jenkins-security-scan.yml │ └── release-drafter.yml ├── .gitignore ├── .gitpod.yml ├── .mvn ├── extensions.xml └── maven.config ├── CHANGELOG.adoc ├── Jenkinsfile ├── LICENSE ├── README.adoc ├── images ├── badge.png ├── examples │ ├── addBadge.png │ ├── addErrorBadge.png │ ├── addInfoBadge.png │ ├── addSummary.png │ └── addWarningBadge.png ├── markup-formatter.png └── summary.png ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── jenkinsci │ │ └── plugins │ │ └── badge │ │ ├── action │ │ ├── AbstractBadgeAction.java │ │ ├── BadgeAction.java │ │ ├── BadgeSummaryAction.java │ │ └── HtmlBadgeAction.java │ │ └── dsl │ │ ├── AbstractAddBadgeStep.java │ │ ├── AbstractRemoveBadgesStep.java │ │ ├── AbstractTaskListenerDescriptor.java │ │ ├── AddBadgeStep.java │ │ ├── AddErrorBadgeStep.java │ │ ├── AddHtmlBadgeStep.java │ │ ├── AddInfoBadgeStep.java │ │ ├── AddShortTextStep.java │ │ ├── AddSummaryStep.java │ │ ├── AddWarningBadgeStep.java │ │ ├── CreateSummaryStep.java │ │ ├── RemoveBadgesStep.java │ │ ├── RemoveHtmlBadgesStep.java │ │ └── RemoveSummariesStep.java └── resources │ ├── com │ └── jenkinsci │ │ └── plugins │ │ └── badge │ │ ├── action │ │ ├── BadgeAction │ │ │ └── badge.jelly │ │ ├── BadgeSummaryAction │ │ │ └── summary.jelly │ │ └── HtmlBadgeAction │ │ │ └── badge.jelly │ │ ├── assets.css │ │ └── dsl │ │ ├── AddBadgeStep │ │ ├── config.jelly │ │ ├── help-cssClass.html │ │ ├── help-icon.html │ │ ├── help-id.html │ │ ├── help-link.html │ │ ├── help-style.html │ │ ├── help-target.html │ │ ├── help-text.html │ │ └── help.html │ │ ├── AddErrorBadgeStep │ │ ├── config.jelly │ │ ├── help-id.html │ │ ├── help-link.html │ │ ├── help-target.html │ │ ├── help-text.html │ │ └── help.html │ │ ├── AddHtmlBadgeStep │ │ └── help.html │ │ ├── AddInfoBadgeStep │ │ ├── config.jelly │ │ ├── help-id.html │ │ ├── help-link.html │ │ ├── help-target.html │ │ ├── help-text.html │ │ └── help.html │ │ ├── AddShortTextStep │ │ └── help.html │ │ ├── AddSummaryStep │ │ ├── config.jelly │ │ ├── help-cssClass.html │ │ ├── help-icon.html │ │ ├── help-id.html │ │ ├── help-link.html │ │ ├── help-style.html │ │ ├── help-target.html │ │ ├── help-text.html │ │ └── help.html │ │ ├── AddWarningBadgeStep │ │ ├── config.jelly │ │ ├── help-id.html │ │ ├── help-link.html │ │ ├── help-target.html │ │ ├── help-text.html │ │ └── help.html │ │ ├── CreateSummaryStep │ │ └── help.html │ │ ├── RemoveBadgesStep │ │ ├── config.jelly │ │ ├── help-id.html │ │ └── help.html │ │ ├── RemoveHtmlBadgesStep │ │ └── help.html │ │ └── RemoveSummariesStep │ │ ├── config.jelly │ │ ├── help-id.html │ │ └── help.html │ └── index.jelly └── test ├── java └── com │ └── jenkinsci │ └── plugins │ └── badge │ ├── action │ ├── AbstractBadgeActionTest.java │ ├── ActionClassHierarchyTest.java │ ├── BadgeActionTest.java │ ├── BadgeSummaryActionTest.java │ ├── HtmlBadgeActionTest.java │ └── LegacyConfigurationTest.java │ └── dsl │ ├── AbstractAddBadgeStepTest.java │ ├── AbstractRemoveBadgesStepTest.java │ ├── AddBadgeStepTest.java │ ├── AddErrorBadgeStepTest.java │ ├── AddHtmlBadgeStepTest.java │ ├── AddInfoBadgeStepTest.java │ ├── AddSummaryStepTest.java │ ├── AddWarningBadgeStepTest.java │ ├── CreateSummaryStepTest.java │ ├── LegacyPipelineTest.java │ ├── RemoveBadgesStepTest.java │ ├── RemoveHtmlBadgesStepTest.java │ ├── RemoveSummariesStepTest.java │ ├── ShortTextStepTest.java │ ├── StepClassHierarchyTest.java │ └── UITest.java └── resources └── legacy-configuration ├── badge-action-borderColor-null.xml ├── badge-action-jenkins-color.xml ├── badge-action-jenkins.xml ├── badge-action-null.xml ├── badge-action.xml ├── summary-action-null.xml └── summary-action.xml /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @jenkinsci/badge-plugin-developers 2 | -------------------------------------------------------------------------------- /.github/codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | require_ci_to_pass: yes 3 | 4 | coverage: 5 | precision: 2 6 | round: down 7 | range: "70...100" 8 | 9 | parsers: 10 | gcov: 11 | branch_detection: 12 | conditional: yes 13 | loop: yes 14 | method: no 15 | macro: no 16 | 17 | comment: false 18 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "automerge": true, 4 | "extends": [ 5 | "config:recommended", 6 | ":semanticCommitsDisabled" 7 | ], 8 | "reviewers": [ 9 | "team:badge-plugin-developers" 10 | ], 11 | "labels": [ 12 | "dependencies" 13 | ], 14 | "rebaseWhen": "conflicted" 15 | } 16 | -------------------------------------------------------------------------------- /.github/workflows/codecov.yml: -------------------------------------------------------------------------------- 1 | name: 'Generate Coverage Report' 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | 9 | jobs: 10 | coverage: 11 | runs-on: ubuntu-latest 12 | name: Coverage on Ubuntu 13 | steps: 14 | - name: Set up JDK 17 and Maven 15 | uses: s4u/setup-maven-action@v1.18.0 16 | with: 17 | java-distribution: 'temurin' 18 | java-version: '17' 19 | - name: Generate coverage with JaCoCo 20 | run: mvn clean jacoco:prepare-agent test jacoco:report 21 | 22 | - name: Upload coverage to Codecov 23 | uses: codecov/codecov-action@v5 24 | with: 25 | token: ${{secrets.CODECOV_TOKEN}} 26 | file: ./target/site/jacoco/jacoco.xml 27 | -------------------------------------------------------------------------------- /.github/workflows/jenkins-security-scan.yml: -------------------------------------------------------------------------------- 1 | name: Jenkins Security Scan 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | types: [ opened, synchronize, reopened ] 9 | workflow_dispatch: 10 | 11 | permissions: 12 | security-events: write 13 | contents: read 14 | actions: read 15 | 16 | jobs: 17 | security-scan: 18 | uses: jenkins-infra/jenkins-security-scan/.github/workflows/jenkins-security-scan.yaml@v2 19 | with: 20 | java-cache: 'maven' # Optionally enable use of a build dependency cache. Specify 'maven' or 'gradle' as appropriate. 21 | # java-version: 21 # Optionally specify what version of Java to set up for the build, or remove to use a recent default. 22 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | # Automates creation of Release Drafts using Release Drafter 2 | # More Info: https://github.com/jenkinsci/.github/blob/master/.github/release-drafter.adoc 3 | name: Release Drafter 4 | 5 | on: 6 | push: 7 | branches: 8 | - master 9 | tags: 10 | - '*' 11 | 12 | jobs: 13 | update_release_draft: 14 | runs-on: ubuntu-latest 15 | steps: 16 | # Drafts your next Release notes as Pull Requests are merged into "main" 17 | - uses: release-drafter/release-drafter@v6 18 | with: 19 | # Publishes a new GH Release automatically once a tag gets pushed 20 | publish: startsWith(github.ref, "refs/tags") 21 | env: 22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .project 3 | .settings/ 4 | target/ 5 | work/ 6 | .idea 7 | *.iml 8 | .gradle 9 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | - init: mvn clean verify 3 | 4 | vscode: 5 | extensions: 6 | - bierner.markdown-preview-github-styles 7 | - vscjava.vscode-java-pack 8 | - redhat.java 9 | - vscjava.vscode-java-debug 10 | - vscjava.vscode-java-dependency 11 | - vscjava.vscode-java-test 12 | - vscjava.vscode-maven 13 | -------------------------------------------------------------------------------- /.mvn/extensions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | io.jenkins.tools.incrementals 4 | git-changelist-maven-extension 5 | 1.8 6 | 7 | 8 | -------------------------------------------------------------------------------- /.mvn/maven.config: -------------------------------------------------------------------------------- 1 | -Pconsume-incrementals 2 | -Pmight-produce-incrementals 3 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | /* 2 | See the documentation for more options: 3 | https://github.com/jenkins-infra/pipeline-library/ 4 | */ 5 | buildPlugin( 6 | forkCount: '1C', // Run parallel tests on ci.jenkins.io for lower costs, faster feedback 7 | useContainerAgent: true, // Set to `false` if you need to use Docker for containerized tests 8 | configurations: [ 9 | [platform: 'linux', jdk: 21], 10 | [platform: 'windows', jdk: 17], 11 | ]) 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2025, Badge Plugin Authors 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | [[badge-plugin]] 2 | = Badge Plugin 3 | :toc: macro 4 | :toclevels: 3 5 | :toc-title: 6 | 7 | image:https://ci.jenkins.io/job/Plugins/job/badge-plugin/job/master/badge/icon[Build Status,link=https://ci.jenkins.io/job/Plugins/job/badge-plugin/job/master/] 8 | image:https://codecov.io/gh/jenkinsci/badge-plugin/branch/master/graph/badge.svg[Codecov Coverage,link=https://codecov.io/gh/jenkinsci/badge-plugin] 9 | image:https://github.com/jenkinsci/badge-plugin/actions/workflows/jenkins-security-scan.yml/badge.svg[Jenkins Security Scan,link=https://github.com/jenkinsci/badge-plugin/actions/workflows/jenkins-security-scan.yml] 10 | 11 | image:https://img.shields.io/jenkins/plugin/i/badge.svg?color=blue&label=installations[Installations,link=https://stats.jenkins.io/pluginversions/badge.html] 12 | image:https://img.shields.io/github/contributors/jenkinsci/badge-plugin.svg?color=blue[Contributors,link=https://github.com/jenkinsci/badge-plugin/graphs/contributors] 13 | image:https://img.shields.io/github/release/jenkinsci/badge-plugin.svg?label=changelog[Changelog,link=https://github.com/jenkinsci/badge-plugin/releases/latest] 14 | 15 | == Introduction 16 | 17 | This plugin allows users to add badges and build summary entries from a pipeline. 18 | 19 | toc::[] 20 | 21 | == Changelog 22 | 23 | Since version 1.10 release notes are recorded in https://github.com/jenkinsci/badge-plugin/releases[GitHub Releases]. 24 | 25 | Changelogs for older releases can be found in the link:CHANGELOG.adoc[archive]. 26 | 27 | === Version 2.x 28 | 29 | Version 2.0 is a major rework of the original plugin and introduces lots of new features. 30 | More details on this can be found in the https://github.com/jenkinsci/badge-plugin/releases/tag/badge-2.0[Release Notes for 2.0]. 31 | 32 | === Version 1.x 33 | 34 | Legacy version that was originally forked from the https://plugins.jenkins.io/groovy-postbuild[Groovy Postbuild Plugin]. 35 | 36 | == Usage 37 | 38 | === Badges 39 | 40 | image::images/badge.png[Badge,height="250",align="center"] 41 | 42 | ==== addBadge 43 | 44 | This is the central pipeline step that allows users to add custom badges to their builds. A badge can either be an icon 45 | or text that can optionally be formatted as HTML rather than plain text. Users can also add links to the badges as well 46 | as styling to get the desired visual results. 47 | 48 | ===== Examples 49 | 50 | See https://www.jenkins.io/doc/pipeline/steps/badge/#addbadge-add-badge[Jenkins Pipeline Steps Reference] for detailed descriptions of the supported parameters, supported icon plugins, and styling options. 51 | 52 | [source,groovy] 53 | ---- 54 | 55 | // add a badge with an icon and text 56 | def badge = addBadge(icon: 'symbol-rocket plugin-ionicons-api', text: 'Launching ...') 57 | 58 | // update the icon and text during build time 59 | badge.setIcon('symbol-planet-outline plugin-ionicons-api') 60 | badge.setText('Lunar orbit reached, proceed landing maneuver ...') 61 | 62 | // update the icon and text during build time 63 | badge.setIcon('symbol-american-football-outline plugin-ionicons-api') 64 | badge.setText('Huston, we have touchdown!') 65 | 66 | // remove the badge 67 | removeBadges(id: badge.getId()) 68 | 69 | // add another badge with html formatted text and css style 70 | addBadge(text: 'Apollo 11 landed on the moon!', style: 'color: var(--success-color)') 71 | 72 | ---- 73 | 74 | image::images/examples/addBadge.png[AddBadge,height="250",align="center",title="Badges can be added, modified and removed during a build"] 75 | 76 | ==== addInfoBadge 77 | 78 | A convenience pipeline step that adds an `info` icon alongside a tooltip text and optional link. 79 | 80 | ===== Examples 81 | 82 | See https://www.jenkins.io/doc/pipeline/steps/badge/#addinfobadge-add-info-badge[Jenkins Pipeline Steps Reference] for detailed descriptions of the supported parameters. 83 | 84 | [source,groovy] 85 | ---- 86 | 87 | // add a badge with an info icon and text 88 | def badge = addInfoBadge(text: 'Launching in ...') 89 | 90 | // update the text during build time 91 | badge.setText('10 ...') 92 | badge.setText('9 ...') 93 | badge.setText('8 ...') 94 | 95 | ---- 96 | 97 | image::images/examples/addInfoBadge.png[AddInfoBadge,height="250",align="center",title="An info badge with icon and hover text"] 98 | 99 | ==== addWarningBadge 100 | 101 | A convenience pipeline step that adds a `warning` icon alongside a tooltip text and optional link. 102 | 103 | ===== Examples 104 | 105 | See https://www.jenkins.io/doc/pipeline/steps/badge/#addwarningbadge-add-warning-badge[Jenkins Pipeline Steps Reference] for detailed descriptions of the supported parameters. 106 | 107 | [source,groovy] 108 | ---- 109 | 110 | // add a badge with a warning icon, text and link 111 | addWarningBadge(text: 'Houston, we have a problem ...', link: 'https://youtu.be/2Q_ZzBGPdqE', target: '_blank') 112 | 113 | ---- 114 | 115 | image::images/examples/addWarningBadge.png[AddWarningBadge,height="250",align="center",title="A warning badge with icon and hover text"] 116 | 117 | ==== addErrorBadge 118 | 119 | A convenience pipeline step that adds an `error` icon alongside a tooltip text and optional link. 120 | 121 | ===== Examples 122 | 123 | See https://www.jenkins.io/doc/pipeline/steps/badge/#adderrorbadge-add-error-badge[Jenkins Pipeline Steps Reference] for detailed descriptions of the supported parameters. 124 | 125 | [source,groovy] 126 | ---- 127 | 128 | // add a badge with an error icon and text 129 | addErrorBadge(text: 'Transmission failed!') 130 | 131 | ---- 132 | 133 | image::images/examples/addErrorBadge.png[AddErrorBadge,height="250",align="center",title="An error badge with icon and hover text"] 134 | 135 | === Summaries 136 | 137 | image::images/summary.png[Summary,height="250",align="center"] 138 | 139 | ==== addSummary 140 | 141 | This pipeline step allows users to add custom summaries to their build overview. 142 | A summary can consist of an icon and text that can optionally be formatted as HTML rather than plain text. 143 | Users can also add links to the summary as well as styling to get the desired visual results. 144 | 145 | ===== Examples 146 | 147 | See https://www.jenkins.io/doc/pipeline/steps/badge/#addsummary-add-summary[Jenkins Pipeline Steps Reference] for detailed descriptions of the supported parameters. 148 | 149 | [source,groovy] 150 | ---- 151 | 152 | // add a summary with an icon, text and link 153 | addSummary(icon: 'symbol-home-outline plugin-ionicons-api', text: 'Test Chamber prepared', link: 'https://jenkins.io', target: "_blank") 154 | 155 | // add another summary with an icon and text 156 | def summary = addSummary(icon: 'symbol-people-outline plugin-ionicons-api', text: 'Looking for Test Subjects ...') 157 | 158 | // removes a summary 159 | removeSummaries(id: summary.getId()) 160 | 161 | // add another summary with an icon and formatted html as text 162 | addSummary(icon: 'symbol-aperture-outline plugin-ionicons-api', 163 | text: 'Results:
  • Test Chamber ready
  • Test Subject missing
  • ') 164 | 165 | ---- 166 | 167 | image::images/examples/addSummary.png[AddSummary,height="250",align="center",title="Summaries can be added, modified and removed during a build"] 168 | 169 | === Allow HTML in Badges and Summaries 170 | 171 | The Badge Plugin uses Jenkins Markup Formatter to sanitize HTML in badges and summaries. 172 | This ensures safety when using HTML for texts and prevents malicious injections. 173 | 174 | image::images/markup-formatter.png[Markup Formatter Configuration,height="250",align="center",title="The Markup Formatter can be configured under Manage Jenkins -> Security -> Markup Formatter"] 175 | -------------------------------------------------------------------------------- /images/badge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/badge-plugin/10f421756078364d9d4f0f0435fe8fc4c7da8ab0/images/badge.png -------------------------------------------------------------------------------- /images/examples/addBadge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/badge-plugin/10f421756078364d9d4f0f0435fe8fc4c7da8ab0/images/examples/addBadge.png -------------------------------------------------------------------------------- /images/examples/addErrorBadge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/badge-plugin/10f421756078364d9d4f0f0435fe8fc4c7da8ab0/images/examples/addErrorBadge.png -------------------------------------------------------------------------------- /images/examples/addInfoBadge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/badge-plugin/10f421756078364d9d4f0f0435fe8fc4c7da8ab0/images/examples/addInfoBadge.png -------------------------------------------------------------------------------- /images/examples/addSummary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/badge-plugin/10f421756078364d9d4f0f0435fe8fc4c7da8ab0/images/examples/addSummary.png -------------------------------------------------------------------------------- /images/examples/addWarningBadge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/badge-plugin/10f421756078364d9d4f0f0435fe8fc4c7da8ab0/images/examples/addWarningBadge.png -------------------------------------------------------------------------------- /images/markup-formatter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/badge-plugin/10f421756078364d9d4f0f0435fe8fc4c7da8ab0/images/markup-formatter.png -------------------------------------------------------------------------------- /images/summary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/badge-plugin/10f421756078364d9d4f0f0435fe8fc4c7da8ab0/images/summary.png -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | org.jenkins-ci.plugins 7 | plugin 8 | 5.17 9 | 10 | 11 | org.jenkins-ci.plugins 12 | badge 13 | ${revision}${changelist} 14 | hpi 15 | 16 | Badge 17 | Add Badges for a build and extend the build summary 18 | https://github.com/${gitHubRepo} 19 | 20 | 21 | 22 | The MIT license 23 | https://opensource.org/licenses/mit-license.php 24 | repo 25 | 26 | 27 | 28 | 29 | 30 | strangelookingnerd 31 | Daniel Krämer 32 | 33 | 34 | bakito 35 | Marc Brugger 36 | 37 | 38 | wolfs 39 | Stefan Wolf 40 | 41 | 42 | beryx 43 | Serban Iordache 44 | 45 | 46 | 47 | 48 | scm:git:https://github.com/${gitHubRepo}.git 49 | scm:git:git@github.com:${gitHubRepo}.git 50 | ${scmTag} 51 | https://github.com/${gitHubRepo} 52 | 53 | 54 | 55 | -SNAPSHOT 56 | jenkinsci/badge-plugin 57 | 2.0 58 | 59 | 2.479 60 | ${jenkins.baseline}.3 61 | 2.9 62 | Max 63 | Low 64 | false 65 | 66 | 67 | 68 | 69 | 70 | io.jenkins.tools.bom 71 | bom-${jenkins.baseline}.x 72 | 4862.vc32a_71c3e731 73 | pom 74 | import 75 | 76 | 77 | 78 | 79 | 80 | 81 | io.jenkins.plugins 82 | emoji-symbols-api 83 | 84 | 85 | io.jenkins.plugins 86 | ionicons-api 87 | 88 | 89 | org.jenkins-ci.plugins 90 | script-security 91 | 92 | 93 | org.jenkins-ci.plugins 94 | structs 95 | 96 | 97 | org.jenkins-ci.plugins.workflow 98 | workflow-step-api 99 | 100 | 101 | org.jenkins-ci.plugins 102 | antisamy-markup-formatter 103 | test 104 | 105 | 106 | org.jenkins-ci.plugins.workflow 107 | workflow-cps 108 | test 109 | 110 | 111 | org.jenkins-ci.plugins.workflow 112 | workflow-durable-task-step 113 | test 114 | 115 | 116 | org.jenkins-ci.plugins.workflow 117 | workflow-job 118 | test 119 | 120 | 121 | org.jenkins-ci.plugins.workflow 122 | workflow-step-api 123 | tests 124 | test 125 | 126 | 127 | org.jenkinsci.plugins 128 | pipeline-model-definition 129 | test 130 | 131 | 132 | org.mockito 133 | mockito-core 134 | test 135 | 136 | 137 | 138 | 139 | 140 | repo.jenkins-ci.org 141 | https://repo.jenkins-ci.org/public/ 142 | 143 | 144 | 145 | 146 | 147 | repo.jenkins-ci.org 148 | https://repo.jenkins-ci.org/public/ 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /src/main/java/com/jenkinsci/plugins/badge/action/BadgeAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.action; 25 | 26 | import hudson.model.BuildBadgeAction; 27 | import java.io.Serial; 28 | 29 | /** 30 | * Common action for badges. 31 | */ 32 | public class BadgeAction extends AbstractBadgeAction implements BuildBadgeAction { 33 | 34 | @Serial 35 | private static final long serialVersionUID = 1L; 36 | 37 | /** 38 | * @deprecated Use {@link BadgeAction#BadgeAction(String, String, String, String, String, String, String)} instead. 39 | */ 40 | @Deprecated(since = "2.8") 41 | public BadgeAction(String id, String icon, String text, String cssClass, String style, String link) { 42 | super(id, icon, text, cssClass, style, link); 43 | } 44 | 45 | public BadgeAction(String id, String icon, String text, String cssClass, String style, String link, String target) { 46 | super(id, icon, text, cssClass, style, link, target); 47 | } 48 | 49 | @Override 50 | public String getDisplayName() { 51 | return "Badge Action"; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/jenkinsci/plugins/badge/action/BadgeSummaryAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.action; 25 | 26 | import java.io.Serial; 27 | import org.apache.commons.lang.StringEscapeUtils; 28 | import org.apache.commons.lang.StringUtils; 29 | import org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.Whitelisted; 30 | 31 | /** 32 | * Common action for build summaries. 33 | */ 34 | public class BadgeSummaryAction extends AbstractBadgeAction { 35 | 36 | @Serial 37 | private static final long serialVersionUID = 1L; 38 | 39 | /** 40 | * @deprecated Use {@link BadgeSummaryAction#BadgeSummaryAction(String, String, String, String, String, String, String)} instead. 41 | */ 42 | @Deprecated(since = "2.8") 43 | public BadgeSummaryAction(String id, String icon, String text, String cssClass, String style, String link) { 44 | super(id, icon, text, cssClass, style, link); 45 | } 46 | 47 | public BadgeSummaryAction( 48 | String id, String icon, String text, String cssClass, String style, String link, String target) { 49 | super(id, icon, text, cssClass, style, link, target); 50 | } 51 | 52 | @Override 53 | public String getDisplayName() { 54 | return "Badge Summary Action"; 55 | } 56 | 57 | @Whitelisted 58 | @Deprecated(since = "2.0", forRemoval = true) 59 | public void appendText(String text) { 60 | appendText(text, false); 61 | } 62 | 63 | @Whitelisted 64 | @Deprecated(since = "2.0", forRemoval = true) 65 | public void appendText(String text, boolean escapeHtml) { 66 | if (escapeHtml) { 67 | text = StringEscapeUtils.escapeHtml(text); 68 | } 69 | setText(StringUtils.defaultString(getText()) + text); 70 | } 71 | 72 | @Whitelisted 73 | @Deprecated(since = "2.0", forRemoval = true) 74 | public void appendText(String text, boolean escapeHtml, boolean bold, boolean italic, String color) { 75 | String startTags = ""; 76 | String closeTags = ""; 77 | if (bold) { 78 | startTags += ""; 79 | closeTags += ""; 80 | } 81 | if (italic) { 82 | startTags += ""; 83 | closeTags += ""; 84 | } 85 | if (color != null) { 86 | startTags += ""; 87 | closeTags += ""; 88 | } 89 | if (escapeHtml) { 90 | text = StringEscapeUtils.escapeHtml(text); 91 | } 92 | setText(StringUtils.defaultString(getText()) + startTags + text + closeTags); 93 | } 94 | 95 | // LEGACY CODE 96 | @Deprecated(since = "2.0", forRemoval = true) 97 | private transient String summaryText; 98 | 99 | /** 100 | * @deprecated kept for backwards compatibility. 101 | * Translates pre 2.0 build.xml to latest format for backwards compatibility. 102 | * @return this instance 103 | */ 104 | @Serial 105 | @Override 106 | @Deprecated(since = "2.0", forRemoval = true) 107 | protected Object readResolve() { 108 | super.readResolve(); 109 | 110 | // field renamed 111 | if (summaryText != null) { 112 | setText(summaryText); 113 | } 114 | 115 | return this; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/main/java/com/jenkinsci/plugins/badge/action/HtmlBadgeAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.action; 25 | 26 | import hudson.model.Action; 27 | import hudson.model.BuildBadgeAction; 28 | import java.io.IOException; 29 | import java.io.Serial; 30 | import java.io.Serializable; 31 | import java.util.logging.Level; 32 | import java.util.logging.Logger; 33 | import jenkins.model.Jenkins; 34 | import org.kohsuke.stapler.export.Exported; 35 | import org.kohsuke.stapler.export.ExportedBean; 36 | 37 | /** 38 | * @deprecated replaced by {@link BadgeAction}. 39 | */ 40 | @ExportedBean(defaultVisibility = 2) 41 | @Deprecated(since = "2.0", forRemoval = true) 42 | public class HtmlBadgeAction implements BuildBadgeAction, Action, Serializable { 43 | 44 | @Serial 45 | private static final long serialVersionUID = 1L; 46 | 47 | private static final Logger LOGGER = Logger.getLogger(HtmlBadgeAction.class.getName()); 48 | 49 | private String id; 50 | private final String html; 51 | 52 | private HtmlBadgeAction(String html) { 53 | this.html = html; 54 | } 55 | 56 | public static HtmlBadgeAction createHtmlBadge(String html) { 57 | return new HtmlBadgeAction(html); 58 | } 59 | 60 | public void setId(String id) { 61 | this.id = id; 62 | } 63 | 64 | @Exported 65 | public String getId() { 66 | return id; 67 | } 68 | 69 | @Exported 70 | public String getHtml() { 71 | try { 72 | return Jenkins.get().getMarkupFormatter().translate(html); 73 | } catch (IOException ex) { 74 | LOGGER.log(Level.WARNING, "Error preparing HTML content for UI", ex); 75 | return "Error preparing HTML content for UI"; 76 | } 77 | } 78 | 79 | public String getRawHtml() { 80 | return html; 81 | } 82 | 83 | @Override 84 | public String getUrlName() { 85 | return ""; 86 | } 87 | 88 | @Override 89 | public String getDisplayName() { 90 | return ""; 91 | } 92 | 93 | @Override 94 | public String getIconFileName() { 95 | return null; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/com/jenkinsci/plugins/badge/dsl/AbstractAddBadgeStep.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import com.jenkinsci.plugins.badge.action.AbstractBadgeAction; 27 | import hudson.model.Run; 28 | import java.io.Serial; 29 | import java.util.ArrayList; 30 | import java.util.List; 31 | import org.apache.commons.lang.StringUtils; 32 | import org.jenkinsci.plugins.workflow.steps.Step; 33 | import org.jenkinsci.plugins.workflow.steps.StepContext; 34 | import org.jenkinsci.plugins.workflow.steps.SynchronousStepExecution; 35 | import org.kohsuke.stapler.DataBoundSetter; 36 | 37 | /** 38 | * Abstract class to add badges. 39 | */ 40 | public abstract class AbstractAddBadgeStep extends Step { 41 | 42 | private String id; 43 | private String icon; 44 | private String text; 45 | private String cssClass; 46 | private String style; 47 | private String link; 48 | private String target; 49 | 50 | protected AbstractAddBadgeStep( 51 | String id, String icon, String text, String cssClass, String style, String link, String target) { 52 | this.id = id; 53 | this.icon = icon; 54 | this.text = text; 55 | this.cssClass = cssClass; 56 | this.style = style; 57 | this.link = link; 58 | this.target = target; 59 | } 60 | 61 | @DataBoundSetter 62 | public void setId(String id) { 63 | this.id = id; 64 | } 65 | 66 | public String getId() { 67 | return id; 68 | } 69 | 70 | public String getIcon() { 71 | return icon; 72 | } 73 | 74 | @DataBoundSetter 75 | public void setIcon(String icon) { 76 | this.icon = icon; 77 | } 78 | 79 | public String getText() { 80 | return text; 81 | } 82 | 83 | @DataBoundSetter 84 | public void setText(String text) { 85 | this.text = text; 86 | } 87 | 88 | public String getCssClass() { 89 | return cssClass; 90 | } 91 | 92 | @DataBoundSetter 93 | public void setCssClass(String cssClass) { 94 | this.cssClass = cssClass; 95 | } 96 | 97 | public String getStyle() { 98 | return style; 99 | } 100 | 101 | @DataBoundSetter 102 | public void setStyle(String style) { 103 | this.style = style; 104 | } 105 | 106 | public String getLink() { 107 | return link; 108 | } 109 | 110 | @DataBoundSetter 111 | public void setLink(String link) { 112 | this.link = link; 113 | } 114 | 115 | public String getTarget() { 116 | return target; 117 | } 118 | 119 | @DataBoundSetter 120 | public void setTarget(String target) { 121 | this.target = target; 122 | } 123 | 124 | @Override 125 | public String toString() { 126 | List fields = new ArrayList<>(); 127 | 128 | if (getId() != null) { 129 | fields.add("id: '" + getId() + "'"); 130 | } 131 | if (getIcon() != null) { 132 | fields.add("icon: '" + getIcon() + "'"); 133 | } 134 | if (getText() != null) { 135 | fields.add("text: '" + getText() + "'"); 136 | } 137 | if (getCssClass() != null) { 138 | fields.add("cssClass: '" + getCssClass() + "'"); 139 | } 140 | if (getStyle() != null) { 141 | fields.add("style: '" + getStyle() + "'"); 142 | } 143 | if (getLink() != null) { 144 | fields.add("link: '" + getLink() + "'"); 145 | } 146 | if (getTarget() != null) { 147 | fields.add("target: '" + getTarget() + "'"); 148 | } 149 | return getDescriptor().getFunctionName() + "(" + StringUtils.join(fields, ", ") + ")"; 150 | } 151 | 152 | abstract static class Execution extends SynchronousStepExecution { 153 | 154 | @Serial 155 | private static final long serialVersionUID = 1L; 156 | 157 | private final String id; 158 | private final String icon; 159 | private final String text; 160 | private final String cssClass; 161 | private final String style; 162 | private final String link; 163 | private final String target; 164 | 165 | Execution( 166 | String id, 167 | String icon, 168 | String text, 169 | String cssClass, 170 | String style, 171 | String link, 172 | String target, 173 | StepContext context) { 174 | super(context); 175 | this.id = id; 176 | this.icon = icon; 177 | this.text = text; 178 | this.cssClass = cssClass; 179 | this.style = style; 180 | this.link = link; 181 | this.target = target; 182 | } 183 | 184 | @Override 185 | protected AbstractBadgeAction run() throws Exception { 186 | AbstractBadgeAction action = newAction(id, icon, text, cssClass, style, link, target); 187 | getContext().get(Run.class).addAction(action); 188 | return action; 189 | } 190 | 191 | protected abstract AbstractBadgeAction newAction( 192 | String id, String icon, String text, String cssClass, String style, String link, String target); 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/main/java/com/jenkinsci/plugins/badge/dsl/AbstractRemoveBadgesStep.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import com.jenkinsci.plugins.badge.action.AbstractBadgeAction; 27 | import hudson.model.Action; 28 | import hudson.model.Run; 29 | import java.io.Serial; 30 | import java.util.ArrayList; 31 | import java.util.List; 32 | import org.apache.commons.lang.StringUtils; 33 | import org.jenkinsci.plugins.workflow.steps.Step; 34 | import org.jenkinsci.plugins.workflow.steps.StepContext; 35 | import org.jenkinsci.plugins.workflow.steps.StepExecution; 36 | import org.jenkinsci.plugins.workflow.steps.SynchronousStepExecution; 37 | import org.kohsuke.stapler.DataBoundSetter; 38 | 39 | /** 40 | * Abstract class to remove badges. 41 | */ 42 | abstract class AbstractRemoveBadgesStep extends Step { 43 | 44 | private String id; 45 | 46 | protected AbstractRemoveBadgesStep(String id) { 47 | this.id = id; 48 | } 49 | 50 | @DataBoundSetter 51 | public void setId(String id) { 52 | this.id = id; 53 | } 54 | 55 | public String getId() { 56 | return id; 57 | } 58 | 59 | protected abstract Class getActionClass(); 60 | 61 | @Override 62 | public String toString() { 63 | List fields = new ArrayList<>(); 64 | 65 | if (getId() != null) { 66 | fields.add("id: '" + getId() + "'"); 67 | } 68 | 69 | return getDescriptor().getFunctionName() + "(" + StringUtils.join(fields, ", ") + ")"; 70 | } 71 | 72 | @Override 73 | public StepExecution start(StepContext context) { 74 | return new Execution(getId(), getActionClass(), context); 75 | } 76 | 77 | public static class Execution extends SynchronousStepExecution { 78 | 79 | @Serial 80 | private static final long serialVersionUID = 1L; 81 | 82 | private final String id; 83 | private final Class actionClass; 84 | 85 | Execution(String id, Class actionClass, StepContext context) { 86 | super(context); 87 | this.id = id; 88 | this.actionClass = actionClass; 89 | } 90 | 91 | @Override 92 | protected Void run() throws Exception { 93 | Run run = getContext().get(Run.class); 94 | run.getAllActions().stream().filter(this::matches).forEach(run::removeAction); 95 | return null; 96 | } 97 | 98 | private boolean matches(Action a) { 99 | return actionClass.isAssignableFrom(a.getClass()) 100 | && (id == null || id.equals(((AbstractBadgeAction) a).getId())); 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/com/jenkinsci/plugins/badge/dsl/AbstractTaskListenerDescriptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import hudson.model.Run; 27 | import hudson.model.TaskListener; 28 | import java.util.Set; 29 | import org.jenkinsci.plugins.workflow.steps.StepDescriptor; 30 | 31 | /** 32 | * Abstract task listener. 33 | */ 34 | abstract class AbstractTaskListenerDescriptor extends StepDescriptor { 35 | 36 | private static final Set> REQUIRED_CONTEXT = Set.of(Run.class, TaskListener.class); 37 | 38 | @Override 39 | public Set> getRequiredContext() { 40 | return REQUIRED_CONTEXT; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/jenkinsci/plugins/badge/dsl/AddBadgeStep.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import com.jenkinsci.plugins.badge.action.AbstractBadgeAction; 27 | import com.jenkinsci.plugins.badge.action.BadgeAction; 28 | import edu.umd.cs.findbugs.annotations.NonNull; 29 | import hudson.Extension; 30 | import org.apache.commons.lang.StringUtils; 31 | import org.jenkinsci.plugins.workflow.steps.StepContext; 32 | import org.jenkinsci.plugins.workflow.steps.StepExecution; 33 | import org.kohsuke.stapler.DataBoundConstructor; 34 | import org.kohsuke.stapler.DataBoundSetter; 35 | 36 | /** 37 | * Add a badge. 38 | */ 39 | public class AddBadgeStep extends AbstractAddBadgeStep { 40 | 41 | @DataBoundConstructor 42 | public AddBadgeStep() { 43 | this(null, null, null, null, null, null, null); 44 | } 45 | 46 | protected AddBadgeStep( 47 | String id, String icon, String text, String cssClass, String style, String link, String target) { 48 | super(id, icon, text, cssClass, style, link, target); 49 | } 50 | 51 | /** 52 | * @deprecated replaced by {@link #setStyle(String)}. 53 | */ 54 | @DataBoundSetter 55 | @Deprecated(since = "2.0", forRemoval = true) 56 | public void setColor(String color) { 57 | // translate old color to new field 58 | if (color != null) { 59 | String newStyle = ""; 60 | if (color.startsWith("jenkins-!-color")) { 61 | newStyle += "color: var(--" + color.replaceFirst("jenkins-!-color-", "") + ");"; 62 | } else if (color.startsWith("jenkins-!-")) { 63 | newStyle += "color: var(--" + color.replaceFirst("jenkins-!-", "") + ");"; 64 | } else { 65 | newStyle += "color: " + AbstractBadgeAction.getJenkinsColorStyle(color) + ";"; 66 | } 67 | setStyle(newStyle + StringUtils.defaultString(getStyle())); 68 | } 69 | } 70 | 71 | /** 72 | * @deprecated replaced by {@link #getStyle()}. 73 | */ 74 | @Deprecated(since = "2.0", forRemoval = true) 75 | public String getColor() { 76 | // translate new field to color 77 | return StringUtils.substringBetween(getStyle(), "color: ", ";"); 78 | } 79 | 80 | @Override 81 | public StepExecution start(StepContext context) { 82 | return new Execution( 83 | getId(), getIcon(), getText(), getCssClass(), getStyle(), getLink(), getTarget(), context) { 84 | 85 | @Override 86 | protected BadgeAction newAction( 87 | String id, String icon, String text, String cssClass, String style, String link, String target) { 88 | return new BadgeAction(id, icon, text, cssClass, style, link, target); 89 | } 90 | }; 91 | } 92 | 93 | @Extension 94 | public static class DescriptorImpl extends AbstractTaskListenerDescriptor { 95 | 96 | @Override 97 | public String getFunctionName() { 98 | return "addBadge"; 99 | } 100 | 101 | @NonNull 102 | @Override 103 | public String getDisplayName() { 104 | return "Add Badge"; 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/main/java/com/jenkinsci/plugins/badge/dsl/AddErrorBadgeStep.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import edu.umd.cs.findbugs.annotations.NonNull; 27 | import hudson.Extension; 28 | import io.jenkins.plugins.ionicons.Ionicons; 29 | import java.util.ArrayList; 30 | import java.util.List; 31 | import org.apache.commons.lang.StringUtils; 32 | import org.kohsuke.stapler.DataBoundConstructor; 33 | 34 | /** 35 | * Add an error badge. 36 | */ 37 | public class AddErrorBadgeStep extends AddBadgeStep { 38 | 39 | @DataBoundConstructor 40 | public AddErrorBadgeStep() { 41 | this(null, null, null, null); 42 | } 43 | 44 | protected AddErrorBadgeStep(String id, String text, String link, String target) { 45 | super(id, Ionicons.getIconClassName("remove-circle"), text, null, "color: var(--error-color)", link, target); 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | List fields = new ArrayList<>(); 51 | 52 | if (getId() != null) { 53 | fields.add("id: '" + getId() + "'"); 54 | } 55 | if (getText() != null) { 56 | fields.add("text: '" + getText() + "'"); 57 | } 58 | if (getLink() != null) { 59 | fields.add("link: '" + getLink() + "'"); 60 | } 61 | if (getTarget() != null) { 62 | fields.add("target: '" + getTarget() + "'"); 63 | } 64 | 65 | return getDescriptor().getFunctionName() + "(" + StringUtils.join(fields, ", ") + ")"; 66 | } 67 | 68 | @Extension 69 | public static class DescriptorImpl extends AbstractTaskListenerDescriptor { 70 | 71 | @Override 72 | public String getFunctionName() { 73 | return "addErrorBadge"; 74 | } 75 | 76 | @NonNull 77 | @Override 78 | public String getDisplayName() { 79 | return "Add Error Badge"; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/jenkinsci/plugins/badge/dsl/AddHtmlBadgeStep.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import com.jenkinsci.plugins.badge.action.HtmlBadgeAction; 27 | import edu.umd.cs.findbugs.annotations.NonNull; 28 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 29 | import hudson.Extension; 30 | import hudson.model.Run; 31 | import hudson.model.TaskListener; 32 | import java.io.PrintStream; 33 | import java.io.Serial; 34 | import org.jenkinsci.plugins.workflow.steps.Step; 35 | import org.jenkinsci.plugins.workflow.steps.StepContext; 36 | import org.jenkinsci.plugins.workflow.steps.StepExecution; 37 | import org.jenkinsci.plugins.workflow.steps.SynchronousStepExecution; 38 | import org.kohsuke.stapler.DataBoundConstructor; 39 | import org.kohsuke.stapler.DataBoundSetter; 40 | 41 | /** 42 | * Create a html badge. 43 | * 44 | * @deprecated replaced by {@link AddBadgeStep}. 45 | */ 46 | @Deprecated(since = "2.0", forRemoval = true) 47 | public class AddHtmlBadgeStep extends Step { 48 | 49 | private String id; 50 | private final String html; 51 | 52 | @DataBoundConstructor 53 | public AddHtmlBadgeStep(String html) { 54 | this.html = html; 55 | } 56 | 57 | @DataBoundSetter 58 | public void setId(String id) { 59 | this.id = id; 60 | } 61 | 62 | public String getId() { 63 | return id; 64 | } 65 | 66 | public String getHtml() { 67 | return html; 68 | } 69 | 70 | @Override 71 | public StepExecution start(StepContext context) { 72 | return new Execution(html, getId(), context); 73 | } 74 | 75 | @Extension 76 | @Deprecated(since = "2.0", forRemoval = true) 77 | public static class DescriptorImpl extends AbstractTaskListenerDescriptor { 78 | 79 | @Override 80 | public String getFunctionName() { 81 | return "addHtmlBadge"; 82 | } 83 | 84 | @NonNull 85 | @Override 86 | public String getDisplayName() { 87 | return "Add a HTML Badge"; 88 | } 89 | 90 | @Override 91 | public boolean isAdvanced() { 92 | return true; 93 | } 94 | } 95 | 96 | @Deprecated(since = "2.0", forRemoval = true) 97 | public static class Execution extends SynchronousStepExecution { 98 | 99 | @Serial 100 | private static final long serialVersionUID = 1L; 101 | 102 | @SuppressFBWarnings(value = "SE_TRANSIENT_FIELD_NOT_RESTORED", justification = "Only used when starting.") 103 | private final transient String html; 104 | 105 | @SuppressFBWarnings(value = "SE_TRANSIENT_FIELD_NOT_RESTORED", justification = "Only used when starting.") 106 | private final transient String id; 107 | 108 | Execution(String html, String id, StepContext context) { 109 | super(context); 110 | this.html = html; 111 | this.id = id; 112 | } 113 | 114 | @Override 115 | protected Void run() throws Exception { 116 | HtmlBadgeAction htmlBadge = HtmlBadgeAction.createHtmlBadge(html); 117 | htmlBadge.setId(id); 118 | getContext().get(Run.class).addAction(htmlBadge); 119 | 120 | TaskListener listener = getContext().get(TaskListener.class); 121 | PrintStream logger = listener.getLogger(); 122 | logger.println("Step 'addHtmlBadge' is deprecated - please consider using 'addBadge' instead."); 123 | 124 | return null; 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/com/jenkinsci/plugins/badge/dsl/AddInfoBadgeStep.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import edu.umd.cs.findbugs.annotations.NonNull; 27 | import hudson.Extension; 28 | import io.jenkins.plugins.ionicons.Ionicons; 29 | import java.util.ArrayList; 30 | import java.util.List; 31 | import org.apache.commons.lang.StringUtils; 32 | import org.kohsuke.stapler.DataBoundConstructor; 33 | 34 | /** 35 | * Add an error badge. 36 | */ 37 | public class AddInfoBadgeStep extends AddBadgeStep { 38 | 39 | @DataBoundConstructor 40 | public AddInfoBadgeStep() { 41 | this(null, null, null, null); 42 | } 43 | 44 | protected AddInfoBadgeStep(String id, String text, String link, String target) { 45 | super(id, Ionicons.getIconClassName("information-circle"), text, null, "color: var(--blue)", link, target); 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | List fields = new ArrayList<>(); 51 | 52 | if (getId() != null) { 53 | fields.add("id: '" + getId() + "'"); 54 | } 55 | if (getText() != null) { 56 | fields.add("text: '" + getText() + "'"); 57 | } 58 | if (getLink() != null) { 59 | fields.add("link: '" + getLink() + "'"); 60 | } 61 | if (getTarget() != null) { 62 | fields.add("target: '" + getTarget() + "'"); 63 | } 64 | 65 | return getDescriptor().getFunctionName() + "(" + StringUtils.join(fields, ", ") + ")"; 66 | } 67 | 68 | @Extension 69 | public static class DescriptorImpl extends AbstractTaskListenerDescriptor { 70 | 71 | @Override 72 | public String getFunctionName() { 73 | return "addInfoBadge"; 74 | } 75 | 76 | @NonNull 77 | @Override 78 | public String getDisplayName() { 79 | return "Add Info Badge"; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/jenkinsci/plugins/badge/dsl/AddSummaryStep.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import com.jenkinsci.plugins.badge.action.BadgeSummaryAction; 27 | import edu.umd.cs.findbugs.annotations.NonNull; 28 | import hudson.Extension; 29 | import org.jenkinsci.plugins.workflow.steps.StepContext; 30 | import org.jenkinsci.plugins.workflow.steps.StepExecution; 31 | import org.kohsuke.stapler.DataBoundConstructor; 32 | 33 | /** 34 | * Create a summary text. 35 | */ 36 | public class AddSummaryStep extends AddBadgeStep { 37 | 38 | @DataBoundConstructor 39 | public AddSummaryStep() { 40 | this(null, null, null, null, null, null, null); 41 | } 42 | 43 | protected AddSummaryStep( 44 | String id, String icon, String text, String cssClass, String style, String link, String target) { 45 | super(id, icon, text, cssClass, style, link, target); 46 | } 47 | 48 | @Override 49 | public StepExecution start(StepContext context) { 50 | return new Execution( 51 | getId(), getIcon(), getText(), getCssClass(), getStyle(), getLink(), getTarget(), context) { 52 | 53 | @Override 54 | protected BadgeSummaryAction newAction( 55 | String id, String icon, String text, String cssClass, String style, String link, String target) { 56 | return new BadgeSummaryAction(id, icon, text, cssClass, style, link, target); 57 | } 58 | }; 59 | } 60 | 61 | @Extension 62 | public static class DescriptorImpl extends AbstractTaskListenerDescriptor { 63 | 64 | @Override 65 | public String getFunctionName() { 66 | return "addSummary"; 67 | } 68 | 69 | @NonNull 70 | @Override 71 | public String getDisplayName() { 72 | return "Add Summary"; 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/jenkinsci/plugins/badge/dsl/AddWarningBadgeStep.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import edu.umd.cs.findbugs.annotations.NonNull; 27 | import hudson.Extension; 28 | import io.jenkins.plugins.ionicons.Ionicons; 29 | import java.util.ArrayList; 30 | import java.util.List; 31 | import org.apache.commons.lang.StringUtils; 32 | import org.kohsuke.stapler.DataBoundConstructor; 33 | 34 | /** 35 | * Add an error badge. 36 | */ 37 | public class AddWarningBadgeStep extends AddBadgeStep { 38 | 39 | @DataBoundConstructor 40 | public AddWarningBadgeStep() { 41 | this(null, null, null, null); 42 | } 43 | 44 | protected AddWarningBadgeStep(String id, String text, String link, String target) { 45 | super(id, Ionicons.getIconClassName("warning"), text, null, "color: var(--warning-color)", link, target); 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | List fields = new ArrayList<>(); 51 | 52 | if (getId() != null) { 53 | fields.add("id: '" + getId() + "'"); 54 | } 55 | if (getText() != null) { 56 | fields.add("text: '" + getText() + "'"); 57 | } 58 | if (getLink() != null) { 59 | fields.add("link: '" + getLink() + "'"); 60 | } 61 | if (getTarget() != null) { 62 | fields.add("target: '" + getTarget() + "'"); 63 | } 64 | 65 | return getDescriptor().getFunctionName() + "(" + StringUtils.join(fields, ", ") + ")"; 66 | } 67 | 68 | @Extension 69 | public static class DescriptorImpl extends AbstractTaskListenerDescriptor { 70 | 71 | @Override 72 | public String getFunctionName() { 73 | return "addWarningBadge"; 74 | } 75 | 76 | @NonNull 77 | @Override 78 | public String getDisplayName() { 79 | return "Add Warning Badge"; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/jenkinsci/plugins/badge/dsl/CreateSummaryStep.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import com.jenkinsci.plugins.badge.action.BadgeSummaryAction; 27 | import edu.umd.cs.findbugs.annotations.NonNull; 28 | import hudson.Extension; 29 | import hudson.model.Run; 30 | import hudson.model.TaskListener; 31 | import java.io.PrintStream; 32 | import java.io.Serial; 33 | import org.apache.commons.lang.StringUtils; 34 | import org.jenkinsci.plugins.workflow.steps.Step; 35 | import org.jenkinsci.plugins.workflow.steps.StepContext; 36 | import org.jenkinsci.plugins.workflow.steps.StepExecution; 37 | import org.jenkinsci.plugins.workflow.steps.SynchronousStepExecution; 38 | import org.kohsuke.stapler.DataBoundConstructor; 39 | import org.kohsuke.stapler.DataBoundSetter; 40 | 41 | /** 42 | * Create a summary text. 43 | * 44 | * @deprecated replaced by {@link AddBadgeStep}. 45 | */ 46 | @Deprecated(since = "2.0", forRemoval = true) 47 | public class CreateSummaryStep extends Step { 48 | 49 | private String id; 50 | private final String icon; 51 | private String text; 52 | 53 | @DataBoundConstructor 54 | public CreateSummaryStep(String icon) { 55 | this.icon = icon; 56 | } 57 | 58 | public String getId() { 59 | return id; 60 | } 61 | 62 | @DataBoundSetter 63 | public void setId(String id) { 64 | this.id = id; 65 | } 66 | 67 | public String getIcon() { 68 | return icon; 69 | } 70 | 71 | public String getText() { 72 | return text; 73 | } 74 | 75 | @DataBoundSetter 76 | public void setText(String text) { 77 | this.text = text; 78 | } 79 | 80 | @Override 81 | public StepExecution start(StepContext context) { 82 | return new Execution(icon, text, getId(), context); 83 | } 84 | 85 | @Extension 86 | @Deprecated(since = "2.0", forRemoval = true) 87 | public static class DescriptorImpl extends AbstractTaskListenerDescriptor { 88 | 89 | @Override 90 | public String getFunctionName() { 91 | return "createSummary"; 92 | } 93 | 94 | @NonNull 95 | @Override 96 | public String getDisplayName() { 97 | return "Create Summary"; 98 | } 99 | 100 | @Override 101 | public boolean isAdvanced() { 102 | return true; 103 | } 104 | } 105 | 106 | @Deprecated(since = "2.0", forRemoval = true) 107 | public static class Execution extends SynchronousStepExecution { 108 | 109 | @Serial 110 | private static final long serialVersionUID = 1L; 111 | 112 | private final String id; 113 | private final String icon; 114 | private final String text; 115 | 116 | Execution(String icon, String text, String id, StepContext context) { 117 | super(context); 118 | this.icon = icon; 119 | this.text = text; 120 | this.id = id; 121 | } 122 | 123 | @Override 124 | protected BadgeSummaryAction run() throws Exception { 125 | BadgeSummaryAction action = new BadgeSummaryAction(id, icon, null, null, null, null, null); 126 | if (StringUtils.isNotBlank(text)) { 127 | action.appendText(text); 128 | } 129 | getContext().get(Run.class).addAction(action); 130 | 131 | TaskListener listener = getContext().get(TaskListener.class); 132 | PrintStream logger = listener.getLogger(); 133 | logger.println("Step 'createSummary' is deprecated - please consider using 'addSummary' instead."); 134 | 135 | return action; 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/main/java/com/jenkinsci/plugins/badge/dsl/RemoveBadgesStep.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import com.jenkinsci.plugins.badge.action.AbstractBadgeAction; 27 | import com.jenkinsci.plugins.badge.action.BadgeAction; 28 | import edu.umd.cs.findbugs.annotations.NonNull; 29 | import hudson.Extension; 30 | import org.kohsuke.stapler.DataBoundConstructor; 31 | 32 | /** 33 | * Removes all badges or the badges with a given id. 34 | */ 35 | public class RemoveBadgesStep extends AbstractRemoveBadgesStep { 36 | 37 | @DataBoundConstructor 38 | public RemoveBadgesStep() { 39 | this(null); 40 | } 41 | 42 | protected RemoveBadgesStep(String id) { 43 | super(id); 44 | } 45 | 46 | @Override 47 | protected Class getActionClass() { 48 | return BadgeAction.class; 49 | } 50 | 51 | @Extension 52 | public static class DescriptorImpl extends AbstractTaskListenerDescriptor { 53 | 54 | @Override 55 | public String getFunctionName() { 56 | return "removeBadges"; 57 | } 58 | 59 | @NonNull 60 | @Override 61 | public String getDisplayName() { 62 | return "Remove Badges"; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/jenkinsci/plugins/badge/dsl/RemoveHtmlBadgesStep.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import com.jenkinsci.plugins.badge.action.HtmlBadgeAction; 27 | import edu.umd.cs.findbugs.annotations.NonNull; 28 | import hudson.Extension; 29 | import hudson.model.Action; 30 | import hudson.model.Run; 31 | import hudson.model.TaskListener; 32 | import java.io.PrintStream; 33 | import java.io.Serial; 34 | import org.jenkinsci.plugins.workflow.steps.Step; 35 | import org.jenkinsci.plugins.workflow.steps.StepContext; 36 | import org.jenkinsci.plugins.workflow.steps.StepExecution; 37 | import org.jenkinsci.plugins.workflow.steps.SynchronousStepExecution; 38 | import org.kohsuke.stapler.DataBoundConstructor; 39 | import org.kohsuke.stapler.DataBoundSetter; 40 | 41 | /** 42 | * Removes all html badges or the badges with a given id. 43 | * 44 | * @deprecated replaced by {@link RemoveBadgesStep}. 45 | */ 46 | @Deprecated(since = "2.0", forRemoval = true) 47 | public class RemoveHtmlBadgesStep extends Step { 48 | 49 | private String id; 50 | 51 | @DataBoundConstructor 52 | public RemoveHtmlBadgesStep() {} 53 | 54 | @DataBoundSetter 55 | public void setId(String id) { 56 | this.id = id; 57 | } 58 | 59 | public String getId() { 60 | return id; 61 | } 62 | 63 | protected Class getActionClass() { 64 | return HtmlBadgeAction.class; 65 | } 66 | 67 | @Extension 68 | public static class DescriptorImpl extends AbstractTaskListenerDescriptor { 69 | 70 | @Override 71 | public String getFunctionName() { 72 | return "removeHtmlBadges"; 73 | } 74 | 75 | @NonNull 76 | @Override 77 | public String getDisplayName() { 78 | return "Remove HTML Badges"; 79 | } 80 | 81 | @Override 82 | public boolean isAdvanced() { 83 | return true; 84 | } 85 | } 86 | 87 | @Override 88 | public StepExecution start(StepContext context) { 89 | return new Execution(context, getActionClass(), getId()); 90 | } 91 | 92 | public static class Execution extends SynchronousStepExecution { 93 | 94 | @Serial 95 | private static final long serialVersionUID = 1L; 96 | 97 | private final String id; 98 | private final Class actionClass; 99 | 100 | Execution(StepContext context, Class actionClass, String id) { 101 | super(context); 102 | this.actionClass = actionClass; 103 | this.id = id; 104 | } 105 | 106 | @Override 107 | protected Void run() throws Exception { 108 | Run run = getContext().get(Run.class); 109 | run.getAllActions().stream().filter(this::matches).forEach(run::removeAction); 110 | 111 | TaskListener listener = getContext().get(TaskListener.class); 112 | PrintStream logger = listener.getLogger(); 113 | logger.println( 114 | "Step 'removeHtmlBadges' is deprecated - please consider using 'addBadges' and 'removeBadges' instead."); 115 | 116 | return null; 117 | } 118 | 119 | private boolean matches(Action a) { 120 | return actionClass.isAssignableFrom(a.getClass()) 121 | && (id == null || id.equals(((HtmlBadgeAction) a).getId())); 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/com/jenkinsci/plugins/badge/dsl/RemoveSummariesStep.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import com.jenkinsci.plugins.badge.action.AbstractBadgeAction; 27 | import com.jenkinsci.plugins.badge.action.BadgeSummaryAction; 28 | import edu.umd.cs.findbugs.annotations.NonNull; 29 | import hudson.Extension; 30 | import org.kohsuke.stapler.DataBoundConstructor; 31 | 32 | /** 33 | * Removes all summaries or the summaries with a given id. 34 | */ 35 | public class RemoveSummariesStep extends AbstractRemoveBadgesStep { 36 | 37 | @DataBoundConstructor 38 | public RemoveSummariesStep() { 39 | this(null); 40 | } 41 | 42 | protected RemoveSummariesStep(String id) { 43 | super(id); 44 | } 45 | 46 | @Override 47 | protected Class getActionClass() { 48 | return BadgeSummaryAction.class; 49 | } 50 | 51 | @Extension 52 | public static class DescriptorImpl extends AbstractTaskListenerDescriptor { 53 | 54 | @Override 55 | public String getFunctionName() { 56 | return "removeSummaries"; 57 | } 58 | 59 | @NonNull 60 | @Override 61 | public String getDisplayName() { 62 | return "Remove Summaries"; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/action/BadgeAction/badge.jelly: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | ${it.text} 58 | 59 | 60 | 61 | 62 | 63 | 64 | ${it.text} 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/action/BadgeSummaryAction/summary.jelly: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | ${it.text} 49 | 50 | 51 | 52 | 53 | 54 | 55 | ${it.text} 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/action/HtmlBadgeAction/badge.jelly: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 27 | 28 | ${it.html} 29 | 30 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/assets.css: -------------------------------------------------------------------------------- 1 | .badge-text--background { 2 | display: inline-block; 3 | border-radius: 6px; 4 | font-size: 0.75rem; 5 | font-weight: 500; 6 | padding: 0 0.4rem !important; 7 | margin: 0 0.1rem 0 0; 8 | text-decoration: none; 9 | text-align: center; 10 | white-space: nowrap; 11 | vertical-align: middle; 12 | position: relative; 13 | } 14 | 15 | .badge-text--background::before { 16 | inset: -0px -0px; 17 | border-radius: 6px; 18 | background: currentColor; 19 | opacity: .2; 20 | content: ""; 21 | position: absolute; 22 | } 23 | 24 | .badge-text--background::after { 25 | inset: -5px -0px; 26 | box-shadow: 0 0 0 10px currentColor; 27 | opacity: 0; 28 | content: ""; 29 | position: absolute; 30 | } 31 | 32 | .badge-text--bordered { 33 | display: inline-block; 34 | border: 0.1rem solid currentColor; 35 | font-size: 0.75rem; 36 | font-weight: 500; 37 | padding: 0 0.2rem !important; 38 | margin: 0 0.1rem 0 0; 39 | text-decoration: none; 40 | text-align: center; 41 | white-space: nowrap; 42 | vertical-align: middle; 43 | position: relative; 44 | } -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddBadgeStep/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddBadgeStep/help-cssClass.html: -------------------------------------------------------------------------------- 1 |
    2 |

    3 | Optional CSS class for the badge. Classes will be applied to the enclosing <span> of a badge. 4 | User can also reference Jenkins built-in CSS classes such as icon-sm - see Jenkins Design Library for more details. 5 |

    6 |

    7 | This plugin includes pre-defined CSS classes for text only badges: 8 |

      9 |
    • badge-text--background - Adds colored background with rounded corners.
    • 10 |
    • badge-text--bordered - Adds border that is the same color as the text.
    • 11 |
    12 |

    13 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddBadgeStep/help-icon.html: -------------------------------------------------------------------------------- 1 |
    2 |

    3 | The plugin supports symbols from the Ionicons API as well as the Emoji Symbols API. 4 | More symbols can be added by installing additional plugins, such as Font Awesome API or IT Symbols API. 5 | Symbols from plugins are referenced as "symbol-icon-name plugin-plugin-name" and Jenkins Core icons as "icon-icon-name" or "symbol-icon-name" - see Jenkins Design Library for more details. 6 | For example, the following are all valid references to symbols: 7 |

      8 |
    • addBadge icon: 'symbol-alert-circle-outline plugin-ionicons-api', text: 'This is an alert symbol'
    • 9 |
    • addBadge icon: 'symbol-bar-chart-filled plugin-ionicons-api', text: 'This is a bar chart symbol'
    • 10 |
    • addBadge icon: 'symbol-emoji_sloth plugin-emoji-symbols-api', text: 'This is a sloth symbol'
    • 11 |
    • addBadge icon: 'symbol-solid/flag-checkered plugin-font-awesome-api', text: 'This is a checkered flag from font-awesome. Note the slash between the icon family and the name.
    • 12 |
    • addBadge icon: 'symbol-cube', text: 'This is a Jenkins Core symbol'
    • 13 |
    • addBadge icon: 'icon-gear', text: 'This is a Jenkins Core icon'
    • 14 |
    15 |

    16 | 17 |

    18 | The plugin allows you to also reference images from within Jenkins as well as relative and remote URL: 19 |

      20 |
    • addBadge icon: '/jenkins.png', text: 'This is a relative image'
    • 21 |
    • addBadge icon: 'https://foo.bar/icon.png', text: 'This is a remote icon'
    • 22 |
    • addBadge icon: 'blue.png', text: 'This is a icon from Jenkins'
    • 23 |
    24 |

    25 | 26 |

    27 | The plugin also supports the 16x16 icons that are offered by Jenkins. 28 | These icons are listed in the plugin documentation and are referenced as "image-name.gif". 29 | For example, the following are all valid references to icons included with the plugin: 30 |

      31 |
    • addBadge icon: 'aborted.gif', text: 'This is a aborted symbol'
    • 32 |
    • addBadge icon: 'folder-open.gif', text: 'This is a folder icon'
    • 33 |
    • addBadge icon: 'document_edit.gif', text: 'This is a document icon'
    • 34 |
    35 |

    36 |
    37 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddBadgeStep/help-id.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional identifier for the badge in case later operations in the Pipeline job need to delete it. 3 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddBadgeStep/help-link.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional URL that will be opened when the user clicks the badge. 3 | Can also be a relative path or mailto: reference. 4 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddBadgeStep/help-style.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional CSS style for the badge. Styles will be applied to the enclosing <span> of a badge. 3 | User can also reference Jenkins built-in styles such as color: var(--warning-color) - see Jenkins Design Library for more details. 4 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddBadgeStep/help-target.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional target frame that is used when http link is opened. 3 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddBadgeStep/help-text.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional text that will be displayed to the user as either short text or hover of an icon. 3 | Text can be plain text or HTML depending on the selected Markdown Formatter 4 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddBadgeStep/help.html: -------------------------------------------------------------------------------- 1 |
    2 |

    3 | Adds one or more badges to the current Pipeline build. 4 | Badges are symbols or icons with an optional text message and an optional clickable hyperlink. 5 | Badges are often used to provide a visual indicator of additional status information about a Pipeline build. 6 | Badges added by addBadge are displayed in the build history of the Pipeline job. 7 |

    8 | 9 |

    10 | The plugin supports symbols from the ionicons library through the ionicons-api-plugin. 11 | More symbols can be added by installing additional plugins, such as font-awesome-api-plugin or custom-folder-icon-plugin. 12 | Symbols from plugins are referenced as "symbol-icon-name plugin-plugin-name" and Jenkins Core icons as "icon-icon-name" or "symbol-icon-name". 13 | For example, the following are all valid references to symbols: 14 |

      15 |
    • addBadge icon: 'symbol-alert-circle-outline plugin-ionicons-api', text: 'This is an alert symbol'
    • 16 |
    • addBadge icon: 'symbol-bar-chart-filled plugin-ionicons-api', text: 'This is a bar chart symbol'
    • 17 |
    • addBadge icon: 'symbol-battery-half-sharp plugin-ionicons-api', text: 'This is a half filled battery symbol'
    • 18 |
    • addBadge icon: 'symbol-emoji_sloth plugin-emoji-symbols-api', text: 'This is a sloth symbol'
    • 19 |
    • addBadge icon: 'symbol-solid/flag-checkered plugin-font-awesome-api', text: 'This is a checkered flag from font-awesome. Note the slash between the icon family and the name.
    • 20 |
    • addBadge icon: 'symbol-cube', text: 'This is a Jenkins Core symbol'
    • 21 |
    • addBadge icon: 'icon-gear', text: 'This is a Jenkins Core icon'
    • 22 |
    23 |

    24 | 25 |

    26 | The plugin allows you to also reference images from within Jenkins as well as relative and remote URL: 27 |

      28 |
    • addBadge icon: '/jenkins.png', text: 'This is a relative image'
    • 29 |
    • addBadge icon: 'https://foo.bar/icon.png', text: 'This is a remote icon'
    • 30 |
    • addBadge icon: 'blue.png', text: 'This is a icon from Jenkins'
    • 31 |
    32 |

    33 | 34 |

    35 | The plugin includes icons as GIF images and also supports the 16x16 icons that are offered by Jenkins. 36 | These icons are listed in the plugin documentation and are referenced as "image-name.gif". 37 | For example, the following are all valid references to icons included with the plugin: 38 |

      39 |
    • addBadge icon: 'completed.gif', text: 'This is a completed symbol'
    • 40 |
    • addBadge icon: 'success.gif', text: 'This is a success icon'
    • 41 |
    • addBadge icon: 'warning.gif', text: 'This is a warning icon'
    • 42 |
    43 |

    44 | 45 | Example: Badge with completed icon 46 |

    47 | The following example adds a "completed" checkmark icon with the text, "This is completed": 48 |

    addBadge icon: 'completed.gif', text: 'This is completed'
    49 |

    50 | 51 | Example: Badge with alarm symbol 52 |

    53 | The following example adds an alarm symbol with the text, "This is alarming": 54 |

    addBadge icon: 'symbol-alarm-outline plugin-ionicons-api', text: 'This is alarming'
    55 |

    56 | 57 | Example: Badge with red bug symbol 58 |

    59 | The following example adds a red bug symbol with the text, "This is a red bug with a link", and a link: 60 |

    addBadge icon: 'symbol-bug plugin-ionicons-api', text: 'This is a red bug with a link', style: 'color: red', link: 'https://issues.jenkins.io/browse/JENKINS-59646', target: '_blank'
    61 |

    62 | 63 | Example: Text badge with CSS styles 64 |

    65 | The following example adds text only badge that uses included CSS styles: 66 |

    
    67 |     // Add shaded background color with rounded corners
    68 |     addBadge text: 'ok', style: 'color: var(--success-color)', cssClass: 'badge-text--background'
    69 |     // Add additional border around badge
    70 |     addBadge text: '1.0.0', cssClass: 'badge-text--background badge-text--bordered'
    71 |     
    72 |

    73 | 74 |
    75 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddErrorBadgeStep/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddErrorBadgeStep/help-id.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional identifier for the badge in case later operations in the Pipeline job need to delete it. 3 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddErrorBadgeStep/help-link.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional URL that will be opened when the user clicks the badge. 3 | Can also be a relative path or mailto: reference. 4 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddErrorBadgeStep/help-target.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional target frame that is used when http link is opened. 3 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddErrorBadgeStep/help-text.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional text that will be displayed to the user as either short text or hover of an icon. 3 | Text can be plain text or HTML depending on the selected Markdown Formatter 4 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddErrorBadgeStep/help.html: -------------------------------------------------------------------------------- 1 |
    2 |

    3 | Adds one or more error badges to the current Pipeline build. 4 | Error badges text messages with an icon and an optional clickable hyperlink. 5 | Error badges are often used to provide a visual indicator of additional status information about a Pipeline build. 6 | Error badges added by addErrorBadge are displayed in the build history of the Pipeline job. 7 |

    8 | 9 | Example: Badge with text 10 |

    11 | The following example adds an error badge with the text, "This is alarming": 12 |

    addErrorBadge text: 'This is alarming'
    13 |

    14 | 15 | Example: Badge with text and link 16 |

    17 | The following example adds an error badge with the text, "This is alarming" and a link: 18 |

    addErrorBadge text: 'This is alarming', link: 'https://issues.jenkins.io/browse/JENKINS-59646', target: '_blank'
    19 |

    20 |
    21 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddHtmlBadgeStep/help.html: -------------------------------------------------------------------------------- 1 |
    2 |

    3 | This step has been deprecated and should be replaced by addBadge. 4 |

    5 |
    6 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddInfoBadgeStep/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddInfoBadgeStep/help-id.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional identifier for the badge in case later operations in the Pipeline job need to delete it. 3 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddInfoBadgeStep/help-link.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional URL that will be opened when the user clicks the badge. 3 | Can also be a relative path or mailto: reference. 4 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddInfoBadgeStep/help-target.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional target frame that is used when http link is opened. 3 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddInfoBadgeStep/help-text.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional text that will be displayed to the user as either short text or hover of an icon. 3 | Text can be plain text or HTML depending on the selected Markdown Formatter 4 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddInfoBadgeStep/help.html: -------------------------------------------------------------------------------- 1 |
    2 |

    3 | Adds one or more info badges to the current Pipeline build. 4 | Info badges text messages with an icon and an optional clickable hyperlink. 5 | Info badges are often used to provide a visual indicator of additional status information about a Pipeline build. 6 | Info badges added by addInfoBadge are displayed in the build history of the Pipeline job. 7 |

    8 | 9 | Example: Badge with text 10 |

    11 | The following example adds an info badge with the text, "This is interesting": 12 |

    addInfoBadge text: 'This is interesting'
    13 |

    14 | 15 | Example: Badge with text and link 16 |

    17 | The following example adds an info badge with the text, "This is interesting" and a link: 18 |

    addInfoBadge text: 'This is interesting', link: 'https://plugins.jenkins.io/custom-folder-icon', target: '_blank'
    19 |

    20 |
    21 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddShortTextStep/help.html: -------------------------------------------------------------------------------- 1 |
    2 |

    3 | This step has been deprecated and should be replaced by addBadge. 4 |

    5 |
    6 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddSummaryStep/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddSummaryStep/help-cssClass.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional CSS class for the badge. Classes will be applied to the enclosing <span> of a summary. 3 | User can also reference Jenkins built-in CSS classes such as icon-sm - see Jenkins Design Library for more details. 4 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddSummaryStep/help-icon.html: -------------------------------------------------------------------------------- 1 |
    2 |

    3 | The plugin supports symbols from the Ionicons API as well as the Emoji Symbols API. 4 | More symbols can be added by installing additional plugins, such as Font Awesome API or IT Symbols API. 5 | Symbols from plugins are referenced as "symbol-icon-name plugin-plugin-name" and Jenkins Core icons as "icon-icon-name" or "symbol-icon-name" - see Jenkins Design Library for more details. 6 | For example, the following are all valid references to symbols: 7 |

      8 |
    • addSummary icon: 'symbol-alert-circle-outline plugin-ionicons-api', text: 'This is an alert symbol'
    • 9 |
    • addSummary icon: 'symbol-bar-chart-filled plugin-ionicons-api', text: 'This is a bar chart symbol'
    • 10 |
    • addSummary icon: 'symbol-emoji_sloth plugin-emoji-symbols-api', text: 'This is a sloth symbol'
    • 11 |
    • addSummary icon: 'symbol-solid/flag-checkered plugin-font-awesome-api', text: 'This is a checkered flag from font-awesome. Note the slash between the icon family and the name.
    • 12 |
    • addSummary icon: 'symbol-cube', text: 'This is a Jenkins Core symbol'
    • 13 |
    • addSummary icon: 'icon-gear', text: 'This is a Jenkins Core icon'
    • 14 |
    15 |

    16 | 17 |

    18 | The plugin allows you to also reference images from within Jenkins as well as relative and remote URL: 19 |

      20 |
    • addSummary icon: '/jenkins.png', text: 'This is a relative image'
    • 21 |
    • addSummary icon: 'https://foo.bar/icon.png', text: 'This is a remote icon'
    • 22 |
    • addSummary icon: 'blue.png', text: 'This is a icon from Jenkins'
    • 23 |
    24 |

    25 | 26 |

    27 | The plugin includes icons as GIF images and also supports the 16x16 icons that are offered by Jenkins. 28 | These icons are listed in the plugin documentation and are referenced as "image-name.gif". 29 | For example, the following are all valid references to icons that can be used with the plugin: 30 |

      31 |
    • addSummary icon: 'aborted.gif', text: 'This is a aborted symbol'
    • 32 |
    • addSummary icon: 'folder-open.gif', text: 'This is a folder icon'
    • 33 |
    • addSummary icon: 'document_edit.gif', text: 'This is a document icon'
    • 34 |
    35 |

    36 |
    37 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddSummaryStep/help-id.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional identifier for the summary in case later operations in the Pipeline job need to delete it. 3 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddSummaryStep/help-link.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional URL that will be opened when the user clicks the summary text. 3 | Can also be a relative path or mailto: reference. 4 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddSummaryStep/help-style.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional CSS style for the badge. Styles will be applied to the enclosing <span> of a summary. 3 | User can also reference Jenkins built-in styles such as color: var(--warning-color) - see Jenkins Design Library for more details. 4 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddSummaryStep/help-target.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional target frame that is used when http link is opened. 3 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddSummaryStep/help-text.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional text that will be displayed next to an icon. 3 | Text can be plain text or HTML depending on the selected Markdown Formatter 4 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddSummaryStep/help.html: -------------------------------------------------------------------------------- 1 |
    2 |

    3 | Adds one or more summaries to the current Pipeline build. 4 | Summaries are symbols or icons with an optional text message and an optional clickable hyperlink. 5 | Summaries are often used to provide a visual indicator of additional status information about a Pipeline build. 6 | Summaries added by addSummary are displayed in the build overview of the Pipeline job. 7 |

    8 | 9 |

    10 | The plugin supports symbols from the ionicons library through the ionicons-api-plugin. 11 | More symbols can be added by installing additional plugins, such as font-awesome-api-plugin or custom-folder-icon-plugin. 12 | Symbols from plugins are referenced as "symbol-icon-name plugin-plugin-name" and Jenkins Core icons as "icon-icon-name" or "symbol-icon-name". 13 | For example, the following are all valid references to symbols: 14 |

      15 |
    • addSummary icon: 'symbol-alert-circle-outline plugin-ionicons-api', text: 'This is an alert symbol'
    • 16 |
    • addSummary icon: 'symbol-bar-chart-filled plugin-ionicons-api', text: 'This is a bar chart symbol'
    • 17 |
    • addSummary icon: 'symbol-battery-half-sharp plugin-ionicons-api', text: 'This is a half filled battery symbol'
    • 18 |
    • addSummary icon: 'symbol-emoji_sloth plugin-emoji-symbols-api', text: 'This is a sloth symbol'
    • 19 |
    • addSummary icon: 'symbol-solid/flag-checkered plugin-font-awesome-api', text: 'This is a checkered flag from font-awesome. Note the slash between the icon family and the name.
    • 20 |
    • addSummary icon: 'symbol-cube', text: 'This is a Jenkins Core symbol'
    • 21 |
    • addSummary icon: 'icon-gear', text: 'This is a Jenkins Core icon'
    • 22 |
    23 |

    24 | 25 |

    26 | The plugin allows you to also reference images from within Jenkins as well as relative and remote URL: 27 |

      28 |
    • addSummary icon: '/jenkins.png', text: 'This is a relative image'
    • 29 |
    • addSummary icon: 'https://foo.bar/icon.png', text: 'This is a remote icon'
    • 30 |
    • addSummary icon: 'blue.png', text: 'This is a icon from Jenkins'
    • 31 |
    32 |

    33 | 34 |

    35 | The plugin includes icons as GIF images and also supports the 16x16 icons that are offered by Jenkins. 36 | These icons are listed in the plugin documentation and are referenced as "image-name.gif". 37 | For example, the following are all valid references to icons included with the plugin: 38 |

      39 |
    • addSummary icon: 'completed.gif', text: 'This is a completed symbol'
    • 40 |
    • addSummary icon: 'success.gif', text: 'This is a success icon'
    • 41 |
    • addSummary icon: 'warning.gif', text: 'This is a warning icon'
    • 42 |
    43 |

    44 | 45 | Example: Summary with completed icon 46 |

    47 | The following example adds a "completed" checkmark icon with the text, "This is completed": 48 |

    addSummary icon: 'completed.gif', text: 'This is completed'
    49 |

    50 | 51 | Example: Summary with alarm symbol 52 |

    53 | The following example adds an alarm symbol with the text, "This is alarming": 54 |

    addSummary icon: 'symbol-alarm-outline plugin-ionicons-api', text: 'This is alarming'
    55 |

    56 | 57 | Example: Summary with red bug symbol 58 |

    59 | The following example adds a red bug badge symbol the text, "This is a red bug with a link", and a link: 60 |

    addSummary icon: 'symbol-bug plugin-ionicons-api', text: 'This is a red bug with a link', style: 'color: red', link: 'https://issues.jenkins.io/browse/JENKINS-59646', target: '_blank'
    61 |

    62 | 63 |
    64 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddWarningBadgeStep/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddWarningBadgeStep/help-id.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional identifier for the badge in case later operations in the Pipeline job need to delete it. 3 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddWarningBadgeStep/help-link.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional URL that will be opened when the user clicks the badge. 3 | Can also be a relative path or mailto: reference. 4 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddWarningBadgeStep/help-target.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional target frame that is used when http link is opened. 3 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddWarningBadgeStep/help-text.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional text that will be displayed to the user as either short text or hover of an icon. 3 | Text can be plain text or HTML depending on the selected Markdown Formatter 4 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/AddWarningBadgeStep/help.html: -------------------------------------------------------------------------------- 1 |
    2 |

    3 | Adds one or more error badges to the current Pipeline build. 4 | Warning badges text messages with an icon and an optional clickable hyperlink. 5 | Warning badges are often used to provide a visual indicator of additional status information about a Pipeline build. 6 | Warning badges added by addWarningBadge are displayed in the build history of the Pipeline job. 7 |

    8 | 9 | Example: Badge with text 10 |

    11 | The following example adds a warning badge with the text, "This is alarming": 12 |

    addWarningBadge text: 'This is alarming'
    13 |

    14 | 15 | Example: Badge with text and link 16 |

    17 | The following example adds a warning badge with the text, "This is alarming" and a link: 18 |

    addWarningBadge text: 'This is alarming', link: 'https://issues.jenkins.io/browse/JENKINS-59646', target: '_blank'
    19 |

    20 |
    21 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/CreateSummaryStep/help.html: -------------------------------------------------------------------------------- 1 |
    2 |

    3 | This step has been deprecated and should be replaced by addSummary. 4 |

    5 |
    6 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/RemoveBadgesStep/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/RemoveBadgesStep/help-id.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional identifier for the badge to remove. 3 | If not set, all badges will be removed. 4 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/RemoveBadgesStep/help.html: -------------------------------------------------------------------------------- 1 |
    2 |

    3 | Removes badges with the given id from the Pipeline build. 4 | If no id is given, all badges will be removed from the Pipeline build. 5 |

    6 | 7 | Example: Remove badge with id 8 |

    9 | The following example removes a badge with the id, "test": 10 |

    removeBadges id: 'test'
    11 |

    12 | 13 | Example: Remove all badges 14 |

    15 | The following example removes all badges: 16 |

    removeBadges()
    17 |

    18 |
    19 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/RemoveHtmlBadgesStep/help.html: -------------------------------------------------------------------------------- 1 |
    2 |

    3 | This step has been deprecated and should be replaced by addBadge and removeBadges. 4 |

    5 |
    6 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/RemoveSummariesStep/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/RemoveSummariesStep/help-id.html: -------------------------------------------------------------------------------- 1 |
    2 | Optional identifier for the summary to remove. 3 | If not set, all summaries will be removed. 4 |
    -------------------------------------------------------------------------------- /src/main/resources/com/jenkinsci/plugins/badge/dsl/RemoveSummariesStep/help.html: -------------------------------------------------------------------------------- 1 |
    2 |

    3 | Removes summaries with the given id from the build overview. 4 | If no id is given, all summaries will be removed from the build overview. 5 |

    6 | 7 | Example: Remove summary with id 8 |

    9 | The following example removes a summary with the id, "test": 10 |

    removeSummaries id: 'test'
    11 |

    12 | 13 | Example: Remove all summaries 14 |

    15 | The following example removes all summaries: 16 |

    removeSummaries()
    17 |

    18 |
    19 | -------------------------------------------------------------------------------- /src/main/resources/index.jelly: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 27 |
    28 | Add Badges for a build and extend the build summary 29 |
    -------------------------------------------------------------------------------- /src/test/java/com/jenkinsci/plugins/badge/action/ActionClassHierarchyTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.action; 25 | 26 | import static org.junit.jupiter.api.Assertions.assertFalse; 27 | import static org.junit.jupiter.api.Assertions.assertTrue; 28 | 29 | import hudson.model.Action; 30 | import hudson.model.BuildBadgeAction; 31 | import org.junit.jupiter.api.Nested; 32 | import org.junit.jupiter.api.Test; 33 | 34 | class ActionClassHierarchyTest { 35 | 36 | @Nested 37 | class Badge { 38 | 39 | @Test 40 | void abstractBadgeAction() { 41 | assertTrue(Action.class.isAssignableFrom(AbstractBadgeAction.class)); 42 | assertFalse(BuildBadgeAction.class.isAssignableFrom(AbstractBadgeAction.class)); 43 | } 44 | 45 | @Test 46 | void badgeAction() { 47 | assertTrue(Action.class.isAssignableFrom(BadgeAction.class)); 48 | assertTrue(BuildBadgeAction.class.isAssignableFrom(BadgeAction.class)); 49 | assertTrue(AbstractBadgeAction.class.isAssignableFrom(BadgeAction.class)); 50 | } 51 | } 52 | 53 | @Nested 54 | class Summary { 55 | 56 | @Test 57 | void badgeSummaryAction() { 58 | assertTrue(Action.class.isAssignableFrom(BadgeSummaryAction.class)); 59 | assertFalse(BuildBadgeAction.class.isAssignableFrom(BadgeSummaryAction.class)); 60 | assertTrue(AbstractBadgeAction.class.isAssignableFrom(BadgeSummaryAction.class)); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/test/java/com/jenkinsci/plugins/badge/action/BadgeActionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.action; 25 | 26 | import static org.junit.jupiter.api.Assertions.assertNull; 27 | 28 | import org.junit.jupiter.api.Test; 29 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 30 | 31 | @WithJenkins 32 | class BadgeActionTest extends AbstractBadgeActionTest { 33 | 34 | @Override 35 | @Test 36 | @Deprecated 37 | void deprecatedConstructor() { 38 | BadgeAction action = new BadgeAction("id", "icon", "text", "cssClass", "style", "link"); 39 | assertNull(action.getTarget()); 40 | } 41 | 42 | @Override 43 | protected AbstractBadgeAction createAction( 44 | String id, String icon, String text, String cssClass, String style, String link, String target) { 45 | return new BadgeAction(id, icon, text, cssClass, style, link, target); 46 | } 47 | 48 | @Override 49 | protected String getDisplayName() { 50 | return "Badge Action"; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/com/jenkinsci/plugins/badge/action/BadgeSummaryActionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.action; 25 | 26 | import static org.junit.jupiter.api.Assertions.assertNull; 27 | 28 | import org.junit.jupiter.api.Test; 29 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 30 | 31 | @WithJenkins 32 | class BadgeSummaryActionTest extends AbstractBadgeActionTest { 33 | 34 | @Override 35 | @Test 36 | @Deprecated 37 | void deprecatedConstructor() { 38 | BadgeSummaryAction action = new BadgeSummaryAction("id", "icon", "text", "cssClass", "style", "link"); 39 | assertNull(action.getTarget()); 40 | } 41 | 42 | @Override 43 | protected AbstractBadgeAction createAction( 44 | String id, String icon, String text, String cssClass, String style, String link, String target) { 45 | return new BadgeSummaryAction(id, icon, text, cssClass, style, link, target); 46 | } 47 | 48 | @Override 49 | protected String getDisplayName() { 50 | return "Badge Summary Action"; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/com/jenkinsci/plugins/badge/action/HtmlBadgeActionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.action; 25 | 26 | import static org.junit.jupiter.api.Assertions.assertEquals; 27 | import static org.junit.jupiter.api.Assertions.assertNull; 28 | 29 | import edu.umd.cs.findbugs.annotations.NonNull; 30 | import hudson.markup.MarkupFormatter; 31 | import java.io.IOException; 32 | import java.io.Writer; 33 | import java.util.UUID; 34 | import org.junit.jupiter.api.BeforeAll; 35 | import org.junit.jupiter.api.Test; 36 | import org.jvnet.hudson.test.JenkinsRule; 37 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 38 | 39 | @WithJenkins 40 | @Deprecated(since = "2.0", forRemoval = true) 41 | class HtmlBadgeActionTest { 42 | 43 | private static JenkinsRule r; 44 | 45 | @BeforeAll 46 | static void setUp(JenkinsRule rule) { 47 | r = rule; 48 | } 49 | 50 | @Test 51 | void html() { 52 | HtmlBadgeAction action = HtmlBadgeAction.createHtmlBadge(null); 53 | assertEquals("", action.getHtml()); 54 | 55 | String html = UUID.randomUUID().toString(); 56 | action = HtmlBadgeAction.createHtmlBadge(html); 57 | assertEquals(html, action.getHtml()); 58 | 59 | MarkupFormatter formatter = new MarkupFormatter() { 60 | @Override 61 | public void translate(String markup, @NonNull Writer output) throws IOException { 62 | throw new IOException("Oh no!"); 63 | } 64 | }; 65 | r.jenkins.setMarkupFormatter(formatter); 66 | assertEquals( 67 | "Error preparing HTML content for UI", 68 | action.getHtml()); 69 | } 70 | 71 | @Test 72 | void urlName() { 73 | HtmlBadgeAction action = HtmlBadgeAction.createHtmlBadge(null); 74 | assertEquals("", action.getUrlName()); 75 | } 76 | 77 | @Test 78 | void displayName() { 79 | HtmlBadgeAction action = HtmlBadgeAction.createHtmlBadge(null); 80 | assertEquals("", action.getDisplayName()); 81 | } 82 | 83 | @Test 84 | void iconFileName() { 85 | HtmlBadgeAction action = HtmlBadgeAction.createHtmlBadge(null); 86 | assertNull(action.getIconFileName()); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/test/java/com/jenkinsci/plugins/badge/action/LegacyConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.action; 25 | 26 | import static org.junit.jupiter.api.Assertions.assertNotNull; 27 | import static org.junit.jupiter.api.Assertions.assertNull; 28 | 29 | import hudson.XmlFile; 30 | import java.io.File; 31 | import org.junit.jupiter.api.BeforeAll; 32 | import org.junit.jupiter.api.Test; 33 | import org.jvnet.hudson.test.JenkinsRule; 34 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 35 | 36 | @WithJenkins 37 | @Deprecated(since = "2.0", forRemoval = true) 38 | class LegacyConfigurationTest { 39 | 40 | private static JenkinsRule r; 41 | 42 | @BeforeAll 43 | static void setUp(JenkinsRule rule) { 44 | r = rule; 45 | } 46 | 47 | @Test 48 | void badgeAction() throws Exception { 49 | BadgeAction action = readConfiguration("badge-action.xml"); 50 | assertNotNull(action.getIcon()); 51 | assertNotNull(action.getStyle()); 52 | 53 | action = readConfiguration("badge-action-null.xml"); 54 | assertNull(action.getIcon()); 55 | assertNull(action.getStyle()); 56 | 57 | action = readConfiguration("badge-action-borderColor-null.xml"); 58 | assertNotNull(action.getStyle()); 59 | 60 | action = readConfiguration("badge-action-jenkins.xml"); 61 | assertNotNull(action.getStyle()); 62 | 63 | action = readConfiguration("badge-action-jenkins-color.xml"); 64 | assertNotNull(action.getStyle()); 65 | } 66 | 67 | @Test 68 | void badgeSummaryAction() throws Exception { 69 | BadgeSummaryAction action = readConfiguration("summary-action.xml"); 70 | assertNotNull(action.getText()); 71 | 72 | action = readConfiguration("summary-action-null.xml"); 73 | assertNull(action.getText()); 74 | } 75 | 76 | @SuppressWarnings("unchecked") 77 | private static T readConfiguration(String file) throws Exception { 78 | return (T) new XmlFile(new File("src/test/resources/legacy-configuration", file)).read(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/test/java/com/jenkinsci/plugins/badge/dsl/AbstractAddBadgeStepTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import static org.junit.jupiter.api.Assertions.*; 27 | 28 | import org.junit.jupiter.api.BeforeAll; 29 | import org.junit.jupiter.api.Test; 30 | import org.jvnet.hudson.test.JenkinsRule; 31 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 32 | 33 | @WithJenkins 34 | abstract class AbstractAddBadgeStepTest { 35 | 36 | protected static JenkinsRule r; 37 | 38 | @BeforeAll 39 | static void setUp(JenkinsRule rule) { 40 | r = rule; 41 | } 42 | 43 | @Test 44 | abstract void defaultConstructor(); 45 | 46 | @Test 47 | void id() { 48 | AbstractAddBadgeStep step = createStep(null, "icon", "text", "cssClass", "style", "link", "target"); 49 | assertNull(step.getId()); 50 | 51 | step = createStep("id", "icon", "text", "cssClass", "style", "link", "target"); 52 | assertEquals("id", step.getId()); 53 | 54 | step = createStep("", "icon", "text", "cssClass", "style", "link", "target"); 55 | assertEquals("", step.getId()); 56 | } 57 | 58 | @Test 59 | void icon() { 60 | AbstractAddBadgeStep step = createStep("id", null, "text", "cssClass", "style", "link", "target"); 61 | assertNull(step.getIcon()); 62 | 63 | step.setIcon(""); 64 | assertEquals("", step.getIcon()); 65 | 66 | step.setIcon("icon"); 67 | assertEquals("icon", step.getIcon()); 68 | } 69 | 70 | @Test 71 | void text() { 72 | AbstractAddBadgeStep step = createStep("id", "icon", null, "cssClass", "style", "link", "target"); 73 | assertNull(step.getText()); 74 | 75 | step.setText(""); 76 | assertEquals("", step.getText()); 77 | 78 | step.setText("text"); 79 | assertEquals("text", step.getText()); 80 | } 81 | 82 | @Test 83 | void cssClass() { 84 | AbstractAddBadgeStep step = createStep("id", "icon", "text", null, "style", "link", "target"); 85 | assertNull(step.getCssClass()); 86 | 87 | step.setCssClass(""); 88 | assertEquals("", step.getCssClass()); 89 | 90 | step.setCssClass("cssClass"); 91 | assertEquals("cssClass", step.getCssClass()); 92 | } 93 | 94 | @Test 95 | void style() { 96 | AbstractAddBadgeStep step = createStep("id", "icon", "text", "cssClass", null, "link", "target"); 97 | assertNull(step.getStyle()); 98 | 99 | step.setStyle(""); 100 | assertEquals("", step.getStyle()); 101 | 102 | step.setStyle("style"); 103 | assertEquals("style", step.getStyle()); 104 | } 105 | 106 | @Test 107 | void link() { 108 | AbstractAddBadgeStep step = createStep("id", "icon", "text", "cssClass", "style", null, "target"); 109 | assertNull(step.getLink()); 110 | 111 | step.setLink(""); 112 | assertEquals("", step.getLink()); 113 | 114 | step.setLink("link"); 115 | assertEquals("link", step.getLink()); 116 | } 117 | 118 | @Test 119 | void target() { 120 | AbstractAddBadgeStep step = createStep("id", "icon", "text", "cssClass", "style", "link", null); 121 | assertNull(step.getTarget()); 122 | 123 | step.setTarget(""); 124 | assertEquals("", step.getTarget()); 125 | 126 | step.setTarget("target"); 127 | assertEquals("target", step.getTarget()); 128 | } 129 | 130 | @Test 131 | void string() { 132 | AbstractAddBadgeStep step = createStep("id", "icon", "text", "cssClass", "style", "link", "target"); 133 | assertNotNull(step.toString()); 134 | assertTrue(step.toString().startsWith(step.getDescriptor().getFunctionName())); 135 | 136 | step = createStep(null, null, null, null, null, null, null); 137 | assertNotNull(step.toString()); 138 | assertEquals(step.getDescriptor().getFunctionName() + "()", step.toString()); 139 | } 140 | 141 | protected abstract AbstractAddBadgeStep createStep( 142 | String id, String icon, String text, String cssClass, String style, String link, String target); 143 | } 144 | -------------------------------------------------------------------------------- /src/test/java/com/jenkinsci/plugins/badge/dsl/AbstractRemoveBadgesStepTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import static org.junit.jupiter.api.Assertions.assertEquals; 27 | import static org.junit.jupiter.api.Assertions.assertNotNull; 28 | import static org.junit.jupiter.api.Assertions.assertNull; 29 | 30 | import org.junit.jupiter.api.BeforeAll; 31 | import org.junit.jupiter.api.Test; 32 | import org.jvnet.hudson.test.JenkinsRule; 33 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 34 | 35 | @WithJenkins 36 | abstract class AbstractRemoveBadgesStepTest { 37 | 38 | protected static JenkinsRule r; 39 | 40 | @BeforeAll 41 | static void setUp(JenkinsRule rule) { 42 | r = rule; 43 | } 44 | 45 | @Test 46 | abstract void defaultConstructor(); 47 | 48 | @Test 49 | void id() { 50 | AbstractRemoveBadgesStep step = createRemoveStep(null); 51 | assertNull(step.getId()); 52 | 53 | step = createRemoveStep("id"); 54 | assertEquals("id", step.getId()); 55 | 56 | step = createRemoveStep(""); 57 | assertEquals("", step.getId()); 58 | } 59 | 60 | @Test 61 | void string() { 62 | AbstractRemoveBadgesStep step = createRemoveStep("id"); 63 | assertNotNull(step.toString()); 64 | assertEquals(step.getDescriptor().getFunctionName() + "(id: '" + step.getId() + "')", step.toString()); 65 | 66 | step = createRemoveStep(null); 67 | assertNotNull(step.toString()); 68 | assertEquals(step.getDescriptor().getFunctionName() + "()", step.toString()); 69 | } 70 | 71 | protected abstract AbstractRemoveBadgesStep createRemoveStep(String id); 72 | } 73 | -------------------------------------------------------------------------------- /src/test/java/com/jenkinsci/plugins/badge/dsl/AddErrorBadgeStepTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import static org.junit.jupiter.api.Assertions.assertEquals; 27 | import static org.junit.jupiter.api.Assertions.assertNull; 28 | 29 | import org.junit.jupiter.api.Test; 30 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 31 | 32 | @WithJenkins 33 | class AddErrorBadgeStepTest extends AddBadgeStepTest { 34 | 35 | @Override 36 | @Test 37 | void defaultConstructor() { 38 | AbstractAddBadgeStep step = new AddErrorBadgeStep(); 39 | assertNull(step.getId()); 40 | assertEquals("symbol-remove-circle plugin-ionicons-api", step.getIcon()); 41 | assertNull(step.getText()); 42 | assertNull(step.getCssClass()); 43 | assertEquals("color: var(--error-color)", step.getStyle()); 44 | assertNull(step.getLink()); 45 | assertNull(step.getTarget()); 46 | } 47 | 48 | @Override 49 | @Test 50 | void icon() { 51 | AbstractAddBadgeStep step = createStep("id", null, "text", "cssClass", "style", "link", "target"); 52 | assertEquals("symbol-remove-circle plugin-ionicons-api", step.getIcon()); 53 | 54 | step = createStep("id", "", "text", "cssClass", "style", "link", "target"); 55 | assertEquals("symbol-remove-circle plugin-ionicons-api", step.getIcon()); 56 | 57 | step = createStep("id", "icon", "text", "cssClass", "style", "link", "target"); 58 | assertEquals("symbol-remove-circle plugin-ionicons-api", step.getIcon()); 59 | } 60 | 61 | @Override 62 | @Test 63 | void cssClass() { 64 | AbstractAddBadgeStep step = createStep("id", "icon", "text", null, "style", "link", "target"); 65 | assertNull(step.getCssClass()); 66 | 67 | step = createStep("id", "icon", "text", "", "style", "link", "target"); 68 | assertNull(step.getCssClass()); 69 | 70 | step = createStep("id", "icon", "text", "cssClass", "style", "link", "target"); 71 | assertNull(step.getCssClass()); 72 | } 73 | 74 | @Override 75 | @Test 76 | void style() { 77 | AbstractAddBadgeStep step = createStep("id", "icon", "text", "cssClass", null, "link", "target"); 78 | assertEquals("color: var(--error-color)", step.getStyle()); 79 | 80 | step = createStep("id", "icon", "text", "cssClass", "", "link", "target"); 81 | assertEquals("color: var(--error-color)", step.getStyle()); 82 | 83 | step = createStep("id", "icon", "text", "cssClass", "style", "link", "target"); 84 | assertEquals("color: var(--error-color)", step.getStyle()); 85 | } 86 | 87 | @Override 88 | protected AbstractAddBadgeStep createStep( 89 | String id, String icon, String text, String cssClass, String style, String link, String target) { 90 | return new AddErrorBadgeStep(id, text, link, target); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/test/java/com/jenkinsci/plugins/badge/dsl/AddHtmlBadgeStepTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import static org.junit.jupiter.api.Assertions.assertEquals; 27 | import static org.junit.jupiter.api.Assertions.assertNull; 28 | import static org.junit.jupiter.api.Assertions.assertTrue; 29 | 30 | import com.jenkinsci.plugins.badge.action.HtmlBadgeAction; 31 | import hudson.markup.RawHtmlMarkupFormatter; 32 | import hudson.model.BuildBadgeAction; 33 | import java.util.List; 34 | import java.util.UUID; 35 | import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; 36 | import org.jenkinsci.plugins.workflow.job.WorkflowJob; 37 | import org.jenkinsci.plugins.workflow.job.WorkflowRun; 38 | import org.junit.jupiter.api.BeforeAll; 39 | import org.junit.jupiter.api.Test; 40 | import org.jvnet.hudson.test.JenkinsRule; 41 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 42 | 43 | @WithJenkins 44 | @Deprecated(since = "2.0", forRemoval = true) 45 | class AddHtmlBadgeStepTest { 46 | 47 | private static JenkinsRule r; 48 | 49 | @BeforeAll 50 | static void setUp(JenkinsRule rule) { 51 | r = rule; 52 | } 53 | 54 | @Test 55 | void id() { 56 | AddHtmlBadgeStep step = new AddHtmlBadgeStep(null); 57 | assertNull(step.getId()); 58 | 59 | String id = UUID.randomUUID().toString(); 60 | step.setId(id); 61 | assertEquals(id, step.getId()); 62 | } 63 | 64 | @Test 65 | void html() { 66 | AddHtmlBadgeStep step = new AddHtmlBadgeStep(null); 67 | assertNull(step.getHtml()); 68 | 69 | String html = UUID.randomUUID().toString(); 70 | step = new AddHtmlBadgeStep(html); 71 | assertEquals(html, step.getHtml()); 72 | } 73 | 74 | @Test 75 | void deprecated() { 76 | AddHtmlBadgeStep step = new AddHtmlBadgeStep(null); 77 | assertTrue(step.getDescriptor().isAdvanced()); 78 | } 79 | 80 | @Test 81 | void addHtmlBadge() throws Exception { 82 | String html = UUID.randomUUID().toString(); 83 | testAddHtmlBadge(html, html); 84 | } 85 | 86 | @Test 87 | void addHtmlBadge_remove_script() throws Exception { 88 | r.jenkins.setMarkupFormatter(RawHtmlMarkupFormatter.INSTANCE); 89 | String uuid = UUID.randomUUID().toString(); 90 | String html = uuid + ""; 91 | testAddHtmlBadge(html, uuid); 92 | } 93 | 94 | private static void testAddHtmlBadge(String html, String expected) throws Exception { 95 | WorkflowJob p = r.createProject(WorkflowJob.class); 96 | 97 | String script = "addHtmlBadge(\"" + html + "\")"; 98 | 99 | p.setDefinition(new CpsFlowDefinition(script, true)); 100 | WorkflowRun b = r.assertBuildStatusSuccess(p.scheduleBuild2(0)); 101 | 102 | List badgeActions = b.getBadgeActions(); 103 | assertEquals(1, badgeActions.size()); 104 | 105 | HtmlBadgeAction action = (HtmlBadgeAction) badgeActions.get(0); 106 | assertEquals(expected, action.getHtml()); 107 | assertEquals(html, action.getRawHtml()); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/test/java/com/jenkinsci/plugins/badge/dsl/AddInfoBadgeStepTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import static org.junit.jupiter.api.Assertions.assertEquals; 27 | import static org.junit.jupiter.api.Assertions.assertNull; 28 | 29 | import org.junit.jupiter.api.Test; 30 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 31 | 32 | @WithJenkins 33 | class AddInfoBadgeStepTest extends AddBadgeStepTest { 34 | 35 | @Override 36 | @Test 37 | void defaultConstructor() { 38 | AbstractAddBadgeStep step = new AddInfoBadgeStep(); 39 | assertNull(step.getId()); 40 | assertEquals("symbol-information-circle plugin-ionicons-api", step.getIcon()); 41 | assertNull(step.getText()); 42 | assertNull(step.getCssClass()); 43 | assertEquals("color: var(--blue)", step.getStyle()); 44 | assertNull(step.getLink()); 45 | assertNull(step.getTarget()); 46 | } 47 | 48 | @Override 49 | @Test 50 | void icon() { 51 | AbstractAddBadgeStep step = createStep("id", null, "text", "cssClass", "style", "link", "target"); 52 | assertEquals("symbol-information-circle plugin-ionicons-api", step.getIcon()); 53 | 54 | step = createStep("id", "", "text", "cssClass", "style", "link", "target"); 55 | assertEquals("symbol-information-circle plugin-ionicons-api", step.getIcon()); 56 | 57 | step = createStep("id", "icon", "text", "cssClass", "style", "link", "target"); 58 | assertEquals("symbol-information-circle plugin-ionicons-api", step.getIcon()); 59 | } 60 | 61 | @Override 62 | @Test 63 | void cssClass() { 64 | AbstractAddBadgeStep step = createStep("id", "icon", "text", null, "style", "link", "target"); 65 | assertNull(step.getCssClass()); 66 | 67 | step = createStep("id", "icon", "text", "", "style", "link", "target"); 68 | assertNull(step.getCssClass()); 69 | 70 | step = createStep("id", "icon", "text", "cssClass", "style", "link", "target"); 71 | assertNull(step.getCssClass()); 72 | } 73 | 74 | @Override 75 | @Test 76 | void style() { 77 | AbstractAddBadgeStep step = createStep("id", "icon", "text", "cssClass", null, "link", "target"); 78 | assertEquals("color: var(--blue)", step.getStyle()); 79 | 80 | step = createStep("id", "icon", "text", "cssClass", "", "link", "target"); 81 | assertEquals("color: var(--blue)", step.getStyle()); 82 | 83 | step = createStep("id", "icon", "text", "cssClass", "style", "link", "target"); 84 | assertEquals("color: var(--blue)", step.getStyle()); 85 | } 86 | 87 | @Override 88 | protected AbstractAddBadgeStep createStep( 89 | String id, String icon, String text, String cssClass, String style, String link, String target) { 90 | return new AddInfoBadgeStep(id, text, link, target); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/test/java/com/jenkinsci/plugins/badge/dsl/AddSummaryStepTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import static org.junit.jupiter.api.Assertions.assertNull; 27 | 28 | import org.junit.jupiter.api.Test; 29 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 30 | 31 | @WithJenkins 32 | class AddSummaryStepTest extends AddBadgeStepTest { 33 | 34 | @Override 35 | @Test 36 | void defaultConstructor() { 37 | AbstractAddBadgeStep step = new AddSummaryStep(); 38 | assertNull(step.getId()); 39 | assertNull(step.getIcon()); 40 | assertNull(step.getText()); 41 | assertNull(step.getCssClass()); 42 | assertNull(step.getStyle()); 43 | assertNull(step.getLink()); 44 | assertNull(step.getTarget()); 45 | } 46 | 47 | @Override 48 | protected AbstractAddBadgeStep createStep( 49 | String id, String icon, String text, String cssClass, String style, String link, String target) { 50 | return new AddSummaryStep(id, icon, text, cssClass, style, link, target); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/com/jenkinsci/plugins/badge/dsl/AddWarningBadgeStepTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import static org.junit.jupiter.api.Assertions.assertEquals; 27 | import static org.junit.jupiter.api.Assertions.assertNull; 28 | 29 | import org.junit.jupiter.api.Test; 30 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 31 | 32 | @WithJenkins 33 | class AddWarningBadgeStepTest extends AddBadgeStepTest { 34 | 35 | @Override 36 | @Test 37 | void defaultConstructor() { 38 | AbstractAddBadgeStep step = new AddWarningBadgeStep(); 39 | assertNull(step.getId()); 40 | assertEquals("symbol-warning plugin-ionicons-api", step.getIcon()); 41 | assertNull(step.getText()); 42 | assertNull(step.getCssClass()); 43 | assertEquals("color: var(--warning-color)", step.getStyle()); 44 | assertNull(step.getLink()); 45 | assertNull(step.getTarget()); 46 | } 47 | 48 | @Override 49 | @Test 50 | void icon() { 51 | AbstractAddBadgeStep step = createStep("id", null, "text", "cssClass", "style", "link", "target"); 52 | assertEquals("symbol-warning plugin-ionicons-api", step.getIcon()); 53 | 54 | step = createStep("id", "", "text", "cssClass", "style", "link", "target"); 55 | assertEquals("symbol-warning plugin-ionicons-api", step.getIcon()); 56 | 57 | step = createStep("id", "icon", "text", "cssClass", "style", "link", "target"); 58 | assertEquals("symbol-warning plugin-ionicons-api", step.getIcon()); 59 | } 60 | 61 | @Override 62 | @Test 63 | void cssClass() { 64 | AbstractAddBadgeStep step = createStep("id", "icon", "text", null, "style", "link", "target"); 65 | assertNull(step.getCssClass()); 66 | 67 | step = createStep("id", "icon", "text", "", "style", "link", "target"); 68 | assertNull(step.getCssClass()); 69 | 70 | step = createStep("id", "icon", "text", "cssClass", "style", "link", "target"); 71 | assertNull(step.getCssClass()); 72 | } 73 | 74 | @Override 75 | @Test 76 | void style() { 77 | AbstractAddBadgeStep step = createStep("id", "icon", "text", "cssClass", null, "link", "target"); 78 | assertEquals("color: var(--warning-color)", step.getStyle()); 79 | 80 | step = createStep("id", "icon", "text", "cssClass", "", "link", "target"); 81 | assertEquals("color: var(--warning-color)", step.getStyle()); 82 | 83 | step = createStep("id", "icon", "text", "cssClass", "style", "link", "target"); 84 | assertEquals("color: var(--warning-color)", step.getStyle()); 85 | } 86 | 87 | @Override 88 | protected AbstractAddBadgeStep createStep( 89 | String id, String icon, String text, String cssClass, String style, String link, String target) { 90 | return new AddWarningBadgeStep(id, text, link, target); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/test/java/com/jenkinsci/plugins/badge/dsl/CreateSummaryStepTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import static java.util.UUID.randomUUID; 27 | import static org.junit.jupiter.api.Assertions.assertEquals; 28 | import static org.junit.jupiter.api.Assertions.assertNull; 29 | import static org.junit.jupiter.api.Assertions.assertTrue; 30 | 31 | import com.jenkinsci.plugins.badge.action.BadgeSummaryAction; 32 | import hudson.markup.RawHtmlMarkupFormatter; 33 | import java.util.List; 34 | import java.util.UUID; 35 | import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; 36 | import org.jenkinsci.plugins.workflow.job.WorkflowJob; 37 | import org.jenkinsci.plugins.workflow.job.WorkflowRun; 38 | import org.junit.jupiter.api.BeforeAll; 39 | import org.junit.jupiter.api.Test; 40 | import org.jvnet.hudson.test.JenkinsRule; 41 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 42 | 43 | @WithJenkins 44 | @Deprecated(since = "2.0", forRemoval = true) 45 | class CreateSummaryStepTest { 46 | 47 | private static JenkinsRule r; 48 | 49 | @BeforeAll 50 | static void setUp(JenkinsRule rule) { 51 | r = rule; 52 | } 53 | 54 | @Test 55 | void id() { 56 | CreateSummaryStep step = new CreateSummaryStep(null); 57 | assertNull(step.getId()); 58 | 59 | String id = UUID.randomUUID().toString(); 60 | step.setId(id); 61 | assertEquals(id, step.getId()); 62 | } 63 | 64 | @Test 65 | void icon() { 66 | CreateSummaryStep step = new CreateSummaryStep(null); 67 | assertNull(step.getIcon()); 68 | 69 | String icon = UUID.randomUUID().toString(); 70 | step = new CreateSummaryStep(icon); 71 | assertEquals(icon, step.getIcon()); 72 | } 73 | 74 | @Test 75 | void text() { 76 | CreateSummaryStep step = new CreateSummaryStep(null); 77 | assertNull(step.getText()); 78 | 79 | String text = UUID.randomUUID().toString(); 80 | step.setText(text); 81 | assertEquals(text, step.getText()); 82 | } 83 | 84 | @Test 85 | void deprecated() { 86 | CreateSummaryStep step = new CreateSummaryStep(null); 87 | assertTrue(step.getDescriptor().isAdvanced()); 88 | } 89 | 90 | @Test 91 | void createSummary_plain() throws Exception { 92 | String text = randomUUID().toString(); 93 | BadgeSummaryAction action = createSummary("summary.appendText('" + text + "')"); 94 | assertEquals(text, action.getText()); 95 | } 96 | 97 | @Test 98 | void createSummary_html_unescaped() throws Exception { 99 | r.jenkins.setMarkupFormatter(RawHtmlMarkupFormatter.INSTANCE); 100 | String text = randomUUID().toString(); 101 | BadgeSummaryAction action = createSummary("summary.appendText('
    • " + text + "
    ', false)"); 102 | assertEquals("
    • " + text + "
    ", action.getText()); 103 | } 104 | 105 | @Test 106 | void createSummary_html_unescaped_remove_script() throws Exception { 107 | r.jenkins.setMarkupFormatter(RawHtmlMarkupFormatter.INSTANCE); 108 | String text = randomUUID().toString(); 109 | String html = "
    • " + text + "
    "; 110 | BadgeSummaryAction action = createSummary("summary.appendText('" + html + "', false);"); 111 | assertEquals("
    • " + text + "
    ", action.getText()); 112 | } 113 | 114 | @Test 115 | void createSummary_html_escaped() throws Exception { 116 | r.jenkins.setMarkupFormatter(RawHtmlMarkupFormatter.INSTANCE); 117 | String text = randomUUID().toString(); 118 | BadgeSummaryAction action = createSummary("summary.appendText('
    • " + text + "
    ', true)"); 119 | assertEquals("<ul><li>" + text + "</li></ul>", action.getText()); 120 | } 121 | 122 | @Test 123 | void createSummary_all() throws Exception { 124 | r.jenkins.setMarkupFormatter(RawHtmlMarkupFormatter.INSTANCE); 125 | String text = randomUUID().toString(); 126 | BadgeSummaryAction action = createSummary("summary.appendText('" + text + "', false, true, true, 'grey')"); 127 | assertEquals("" + text + "", action.getText()); 128 | } 129 | 130 | @Test 131 | void createSummary_with_text() throws Exception { 132 | String icon = randomUUID().toString(); 133 | String text = randomUUID().toString(); 134 | 135 | WorkflowJob p = r.createProject(WorkflowJob.class); 136 | p.setDefinition(new CpsFlowDefinition( 137 | "def summary = createSummary(icon:\"" + icon + "\", text:\"" + text + "\")", true)); 138 | WorkflowRun b = r.assertBuildStatusSuccess(p.scheduleBuild2(0)); 139 | List summaryActions = b.getActions(BadgeSummaryAction.class); 140 | assertEquals(1, summaryActions.size()); 141 | 142 | BadgeSummaryAction action = summaryActions.get(0); 143 | assertTrue(action.getIcon().endsWith(icon)); 144 | assertEquals(text, action.getText()); 145 | } 146 | 147 | private static BadgeSummaryAction createSummary(String script) throws Exception { 148 | String icon = randomUUID().toString(); 149 | 150 | WorkflowJob p = r.createProject(WorkflowJob.class); 151 | p.setDefinition(new CpsFlowDefinition("def summary = createSummary(\"" + icon + "\")\n" + script, true)); 152 | WorkflowRun b = r.assertBuildStatusSuccess(p.scheduleBuild2(0)); 153 | List summaryActions = b.getActions(BadgeSummaryAction.class); 154 | assertEquals(1, summaryActions.size()); 155 | 156 | BadgeSummaryAction action = summaryActions.get(0); 157 | assertTrue(action.getIcon().endsWith(icon)); 158 | return action; 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /src/test/java/com/jenkinsci/plugins/badge/dsl/LegacyPipelineTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import static org.junit.jupiter.api.Assertions.assertAll; 27 | import static org.junit.jupiter.api.Assertions.assertEquals; 28 | 29 | import com.jenkinsci.plugins.badge.action.BadgeAction; 30 | import com.jenkinsci.plugins.badge.action.BadgeSummaryAction; 31 | import hudson.markup.RawHtmlMarkupFormatter; 32 | import hudson.model.BuildBadgeAction; 33 | import java.util.Arrays; 34 | import java.util.List; 35 | import java.util.stream.Stream; 36 | import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; 37 | import org.jenkinsci.plugins.workflow.job.WorkflowJob; 38 | import org.jenkinsci.plugins.workflow.job.WorkflowRun; 39 | import org.junit.jupiter.api.BeforeAll; 40 | import org.junit.jupiter.api.Test; 41 | import org.junit.jupiter.api.function.Executable; 42 | import org.jvnet.hudson.test.JenkinsRule; 43 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 44 | 45 | @WithJenkins 46 | @Deprecated(since = "2.0", forRemoval = true) 47 | class LegacyPipelineTest { 48 | 49 | private static JenkinsRule r; 50 | 51 | @BeforeAll 52 | static void setUp(JenkinsRule rule) { 53 | r = rule; 54 | } 55 | 56 | @Test 57 | void color() { 58 | List colors = Arrays.asList( 59 | "blue", "brown", "cyan", "green", "indigo", "orange", "pink", "purple", "red", "yellow", "white", 60 | "black"); 61 | Stream> palette = 62 | colors.stream().map(c -> Arrays.asList("'" + c + "'", "color: var(--" + c + ");")); 63 | Stream> paletteLight = 64 | colors.stream().map(c -> Arrays.asList("'light-" + c + "'", "color: var(--light-" + c + ");")); 65 | Stream> paletteDark = 66 | colors.stream().map(c -> Arrays.asList("'dark-" + c + "'", "color: var(--dark-" + c + ");")); 67 | 68 | List semantics = Arrays.asList( 69 | "accent", "text", "error", "warning", "success", "destructive", "build", "danger", "info"); 70 | Stream> semantic = 71 | semantics.stream().map(c -> Arrays.asList("'" + c + "'", "color: var(--" + c + "-color);")); 72 | 73 | Stream> other = Stream.of( 74 | Arrays.asList("'light-'", "color: light-;"), 75 | Arrays.asList("'dark-'", "color: dark-;"), 76 | Arrays.asList("'#ff0000'", "color: #ff0000;"), 77 | Arrays.asList("'tortoise'", "color: tortoise;"), 78 | Arrays.asList("'jenkins-!-color-red'", "color: var(--red);"), 79 | Arrays.asList("'jenkins-!-warning-color'", "color: var(--warning-color);"), 80 | Arrays.asList("''", "color: ;"), 81 | Arrays.asList("null", null)); 82 | 83 | assertAll("palette", colorTests(palette)); 84 | assertAll("palette-light", colorTests(paletteLight)); 85 | assertAll("palette-dark", colorTests(paletteDark)); 86 | assertAll("semantic", colorTests(semantic)); 87 | assertAll("other", colorTests(other)); 88 | } 89 | 90 | private static Stream colorTests(Stream> tests) { 91 | return tests.map(params -> () -> { 92 | WorkflowRun run = runJob("addBadge(color: " + params.get(0) + ")"); 93 | 94 | List badgeActions = run.getBadgeActions(); 95 | assertEquals(1, badgeActions.size()); 96 | 97 | BadgeAction action = (BadgeAction) badgeActions.get(0); 98 | assertEquals(params.get(1), action.getStyle()); 99 | }); 100 | } 101 | 102 | @Test 103 | void appendText() throws Exception { 104 | WorkflowRun run = runJob("createSummary(text: 'Test Text')"); 105 | 106 | List actions = run.getActions(BadgeSummaryAction.class); 107 | assertEquals(1, actions.size()); 108 | 109 | BadgeSummaryAction action = actions.get(0); 110 | assertEquals("Test Text", action.getText()); 111 | 112 | run = runJob("def summary = createSummary(text: 'Test Text')\n" + "summary.appendText(' More Text', true)"); 113 | 114 | actions = run.getActions(BadgeSummaryAction.class); 115 | assertEquals(1, actions.size()); 116 | 117 | action = actions.get(0); 118 | assertEquals("Test Text More Text", action.getText()); 119 | 120 | run = runJob("def summary = createSummary(text: 'Test Text')\n" + "summary.appendText(' More Text', false)"); 121 | 122 | actions = run.getActions(BadgeSummaryAction.class); 123 | assertEquals(1, actions.size()); 124 | 125 | action = actions.get(0); 126 | assertEquals("Test Text More Text", action.getText()); 127 | 128 | run = runJob( 129 | """ 130 | def summary = createSummary(text: 'Test Text') 131 | summary.appendText(' More Text', false, false, false, null) 132 | """); 133 | 134 | actions = run.getActions(BadgeSummaryAction.class); 135 | assertEquals(1, actions.size()); 136 | 137 | action = actions.get(0); 138 | assertEquals("Test Text More Text", action.getText()); 139 | 140 | r.jenkins.setMarkupFormatter(RawHtmlMarkupFormatter.INSTANCE); 141 | run = runJob( 142 | """ 143 | def summary = createSummary(text: 'Test Text') 144 | summary.appendText(' More Text', true, true, true, 'red') 145 | """); 146 | 147 | actions = run.getActions(BadgeSummaryAction.class); 148 | assertEquals(1, actions.size()); 149 | 150 | action = actions.get(0); 151 | assertEquals("Test Text More Text", action.getText()); 152 | } 153 | 154 | private static WorkflowRun runJob(String script) throws Exception { 155 | WorkflowJob project = r.createProject(WorkflowJob.class); 156 | project.setDefinition(new CpsFlowDefinition(script, true)); 157 | return r.assertBuildStatusSuccess(project.scheduleBuild2(0)); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/test/java/com/jenkinsci/plugins/badge/dsl/RemoveBadgesStepTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import static org.junit.jupiter.api.Assertions.assertEquals; 27 | import static org.junit.jupiter.api.Assertions.assertNull; 28 | 29 | import com.jenkinsci.plugins.badge.action.AbstractBadgeAction; 30 | import java.util.List; 31 | import java.util.UUID; 32 | import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; 33 | import org.jenkinsci.plugins.workflow.job.WorkflowJob; 34 | import org.jenkinsci.plugins.workflow.job.WorkflowRun; 35 | import org.junit.jupiter.api.Test; 36 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 37 | 38 | @WithJenkins 39 | class RemoveBadgesStepTest extends AbstractRemoveBadgesStepTest { 40 | 41 | @Override 42 | @Test 43 | void defaultConstructor() { 44 | AbstractRemoveBadgesStep step = new RemoveBadgesStep(); 45 | assertNull(step.getId()); 46 | } 47 | 48 | @Test 49 | void removeByIdInScriptedPipeline() throws Exception { 50 | String badgeId = UUID.randomUUID().toString(); 51 | AbstractAddBadgeStep addStep = createAddStep(badgeId); 52 | AbstractRemoveBadgesStep removeStep = createRemoveStep(badgeId); 53 | runRemoveJob(addStep, removeStep, 0, false, false); 54 | } 55 | 56 | @Test 57 | void removeByIdInScriptedPipelineInNode() throws Exception { 58 | String badgeId = UUID.randomUUID().toString(); 59 | AbstractAddBadgeStep addStep = createAddStep(badgeId); 60 | AbstractRemoveBadgesStep removeStep = createRemoveStep(badgeId); 61 | runRemoveJob(addStep, removeStep, 0, true, false); 62 | } 63 | 64 | @Test 65 | void removeByIdInDeclarativePipeline() throws Exception { 66 | String badgeId = UUID.randomUUID().toString(); 67 | AbstractAddBadgeStep addStep = createAddStep(badgeId); 68 | AbstractRemoveBadgesStep removeStep = createRemoveStep(badgeId); 69 | runRemoveJob(addStep, removeStep, 0, false, true); 70 | } 71 | 72 | @Test 73 | void removeAllInScriptedPipeline() throws Exception { 74 | String badgeId = UUID.randomUUID().toString(); 75 | AbstractAddBadgeStep addStep = createAddStep(badgeId); 76 | AbstractRemoveBadgesStep removeStep = createRemoveStep(null); 77 | runRemoveJob(addStep, removeStep, 0, false, false); 78 | } 79 | 80 | @Test 81 | void removeAllInScriptedPipelineInNode() throws Exception { 82 | String badgeId = UUID.randomUUID().toString(); 83 | AbstractAddBadgeStep addStep = createAddStep(badgeId); 84 | AbstractRemoveBadgesStep removeStep = createRemoveStep(null); 85 | runRemoveJob(addStep, removeStep, 0, true, false); 86 | } 87 | 88 | @Test 89 | void removeAllInDeclarativePipeline() throws Exception { 90 | String badgeId = UUID.randomUUID().toString(); 91 | AbstractAddBadgeStep addStep = createAddStep(badgeId); 92 | AbstractRemoveBadgesStep removeStep = createRemoveStep(null); 93 | runRemoveJob(addStep, removeStep, 0, false, true); 94 | } 95 | 96 | @Test 97 | void removeInvalidIdInScriptedPipeline() throws Exception { 98 | String badgeId = UUID.randomUUID().toString(); 99 | AbstractAddBadgeStep addStep = createAddStep(badgeId); 100 | AbstractRemoveBadgesStep removeStep = createRemoveStep(UUID.randomUUID().toString()); 101 | runRemoveJob(addStep, removeStep, 1, false, false); 102 | } 103 | 104 | @Test 105 | void removeInvalidIdInScriptedPipelineInNode() throws Exception { 106 | String badgeId = UUID.randomUUID().toString(); 107 | AbstractAddBadgeStep addStep = createAddStep(badgeId); 108 | AbstractRemoveBadgesStep removeStep = createRemoveStep(UUID.randomUUID().toString()); 109 | runRemoveJob(addStep, removeStep, 1, true, false); 110 | } 111 | 112 | @Test 113 | void removeInvalidIdInDeclarativePipeline() throws Exception { 114 | String badgeId = UUID.randomUUID().toString(); 115 | AbstractAddBadgeStep addStep = createAddStep(badgeId); 116 | AbstractRemoveBadgesStep removeStep = createRemoveStep(UUID.randomUUID().toString()); 117 | runRemoveJob(addStep, removeStep, 1, false, true); 118 | } 119 | 120 | protected void runRemoveJob( 121 | AbstractAddBadgeStep addStep, 122 | AbstractRemoveBadgesStep removeStep, 123 | int expected, 124 | boolean inNode, 125 | boolean declarativePipeline) 126 | throws Exception { 127 | WorkflowJob project = r.createProject(WorkflowJob.class); 128 | 129 | String script = addStep.toString() + "\n"; 130 | script += removeStep.toString(); 131 | 132 | if (inNode) { 133 | script = "node() { " + script + " }"; 134 | } 135 | 136 | if (declarativePipeline) { 137 | script = 138 | """ 139 | pipeline { 140 | agent any 141 | stages { 142 | stage('Testing') { 143 | steps { 144 | script { 145 | %s 146 | } 147 | } 148 | } 149 | } 150 | }""" 151 | .formatted(script); 152 | } 153 | 154 | project.setDefinition(new CpsFlowDefinition(script, true)); 155 | WorkflowRun run = r.assertBuildStatusSuccess(project.scheduleBuild2(0)); 156 | 157 | assertActionExists(run, expected); 158 | } 159 | 160 | protected void assertActionExists(WorkflowRun run, int expected) { 161 | List badgeActions = run.getActions(AbstractBadgeAction.class); 162 | assertEquals(expected, badgeActions.size()); 163 | } 164 | 165 | protected AbstractAddBadgeStep createAddStep(String id) { 166 | return new AddBadgeStep( 167 | id, 168 | "symbol-rocket plugin-ionicons-api", 169 | "Test Text", 170 | "icon-md", 171 | "color: green", 172 | "https://jenkins.io", 173 | "_blank"); 174 | } 175 | 176 | @Override 177 | protected AbstractRemoveBadgesStep createRemoveStep(String id) { 178 | return new RemoveBadgesStep(id); 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /src/test/java/com/jenkinsci/plugins/badge/dsl/RemoveHtmlBadgesStepTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import static org.junit.jupiter.api.Assertions.assertEquals; 27 | import static org.junit.jupiter.api.Assertions.assertTrue; 28 | 29 | import hudson.model.BuildBadgeAction; 30 | import java.util.List; 31 | import java.util.UUID; 32 | import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; 33 | import org.jenkinsci.plugins.workflow.job.WorkflowJob; 34 | import org.jenkinsci.plugins.workflow.job.WorkflowRun; 35 | import org.junit.jupiter.api.BeforeAll; 36 | import org.junit.jupiter.api.Test; 37 | import org.jvnet.hudson.test.JenkinsRule; 38 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 39 | 40 | @WithJenkins 41 | @Deprecated(since = "2.0", forRemoval = true) 42 | class RemoveHtmlBadgesStepTest { 43 | 44 | private static JenkinsRule r; 45 | 46 | @BeforeAll 47 | static void setUp(JenkinsRule rule) { 48 | r = rule; 49 | } 50 | 51 | @Test 52 | void removeById() throws Exception { 53 | String badgeId = UUID.randomUUID().toString(); 54 | AddHtmlBadgeStep addStep = createAddStep(badgeId); 55 | RemoveHtmlBadgesStep removeStep = createRemoveStep(badgeId); 56 | runRemoveJob(addStep, removeStep, 0); 57 | } 58 | 59 | @Test 60 | void removeAll() throws Exception { 61 | String badgeId = UUID.randomUUID().toString(); 62 | AddHtmlBadgeStep addStep = createAddStep(badgeId); 63 | RemoveHtmlBadgesStep removeStep = createRemoveStep(null); 64 | runRemoveJob(addStep, removeStep, 0); 65 | } 66 | 67 | @Test 68 | void removeInvalidId() throws Exception { 69 | String badgeId = UUID.randomUUID().toString(); 70 | AddHtmlBadgeStep addStep = createAddStep(badgeId); 71 | RemoveHtmlBadgesStep removeStep = createRemoveStep(UUID.randomUUID().toString()); 72 | runRemoveJob(addStep, removeStep, 1); 73 | } 74 | 75 | @Test 76 | void deprecated() { 77 | RemoveHtmlBadgesStep removeStep = createRemoveStep(null); 78 | assertTrue(removeStep.getDescriptor().isAdvanced()); 79 | } 80 | 81 | private static void runRemoveJob(AddHtmlBadgeStep addStep, RemoveHtmlBadgesStep removeStep, int expected) 82 | throws Exception { 83 | WorkflowJob project = r.createProject(WorkflowJob.class); 84 | 85 | String script = addStep.getDescriptor().getFunctionName() + "(" 86 | + (addStep.getId() != null ? "id: '" + addStep.getId() + "', " : "") + "html: '" + addStep.getHtml() 87 | + "')\n"; 88 | script += removeStep.getDescriptor().getFunctionName() + "(" 89 | + (removeStep.getId() != null ? "id: '" + removeStep.getId() + "'" : "") + ")"; 90 | 91 | project.setDefinition(new CpsFlowDefinition(script, true)); 92 | WorkflowRun run = r.assertBuildStatusSuccess(project.scheduleBuild2(0)); 93 | 94 | assertActionExists(run, expected); 95 | } 96 | 97 | private static void assertActionExists(WorkflowRun run, int expected) { 98 | List badgeActions = run.getBadgeActions(); 99 | assertEquals(expected, badgeActions.size()); 100 | } 101 | 102 | private static AddHtmlBadgeStep createAddStep(String id) { 103 | AddHtmlBadgeStep step = new AddHtmlBadgeStep("Test Text"); 104 | step.setId(id); 105 | return step; 106 | } 107 | 108 | private static RemoveHtmlBadgesStep createRemoveStep(String id) { 109 | RemoveHtmlBadgesStep step = new RemoveHtmlBadgesStep(); 110 | step.setId(id); 111 | return step; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/test/java/com/jenkinsci/plugins/badge/dsl/RemoveSummariesStepTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import static org.junit.jupiter.api.Assertions.assertNull; 27 | 28 | import org.junit.jupiter.api.Test; 29 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 30 | 31 | @WithJenkins 32 | class RemoveSummariesStepTest extends RemoveBadgesStepTest { 33 | 34 | @Override 35 | @Test 36 | void defaultConstructor() { 37 | AbstractRemoveBadgesStep step = new RemoveSummariesStep(); 38 | assertNull(step.getId()); 39 | } 40 | 41 | @Override 42 | protected AbstractAddBadgeStep createAddStep(String id) { 43 | return new AddSummaryStep( 44 | id, 45 | "symbol-rocket plugin-ionicons-api", 46 | "Test Text", 47 | "icon-md", 48 | "color: green", 49 | "https://jenkins.io", 50 | "_blank"); 51 | } 52 | 53 | @Override 54 | protected AbstractRemoveBadgesStep createRemoveStep(String id) { 55 | return new RemoveSummariesStep(id); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/test/java/com/jenkinsci/plugins/badge/dsl/ShortTextStepTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import static org.junit.jupiter.api.Assertions.assertEquals; 27 | import static org.junit.jupiter.api.Assertions.assertNull; 28 | import static org.junit.jupiter.api.Assertions.assertTrue; 29 | 30 | import com.jenkinsci.plugins.badge.action.BadgeAction; 31 | import hudson.model.BuildBadgeAction; 32 | import java.util.List; 33 | import java.util.Random; 34 | import java.util.UUID; 35 | import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; 36 | import org.jenkinsci.plugins.workflow.job.WorkflowJob; 37 | import org.jenkinsci.plugins.workflow.job.WorkflowRun; 38 | import org.junit.jupiter.api.BeforeAll; 39 | import org.junit.jupiter.api.Test; 40 | import org.jvnet.hudson.test.JenkinsRule; 41 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins; 42 | 43 | @WithJenkins 44 | @Deprecated(since = "2.0", forRemoval = true) 45 | class ShortTextStepTest { 46 | 47 | private static JenkinsRule r; 48 | 49 | @BeforeAll 50 | static void setUp(JenkinsRule rule) { 51 | r = rule; 52 | } 53 | 54 | @Test 55 | void text() { 56 | AddShortTextStep step = new AddShortTextStep(null); 57 | assertNull(step.getText()); 58 | 59 | String text = UUID.randomUUID().toString(); 60 | step = new AddShortTextStep(text); 61 | assertEquals(text, step.getText()); 62 | } 63 | 64 | @Test 65 | void color() { 66 | AddShortTextStep step = new AddShortTextStep(null); 67 | assertNull(step.getColor()); 68 | 69 | step.setColor("red"); 70 | assertEquals("red", step.getColor()); 71 | } 72 | 73 | @Test 74 | void background() { 75 | AddShortTextStep step = new AddShortTextStep(null); 76 | assertNull(step.getBackground()); 77 | 78 | step.setBackground("red"); 79 | assertEquals("red", step.getBackground()); 80 | } 81 | 82 | @Test 83 | void border() { 84 | AddShortTextStep step = new AddShortTextStep(null); 85 | assertNull(step.getBorder()); 86 | 87 | step.setBorder(1); 88 | assertEquals(1, step.getBorder()); 89 | } 90 | 91 | @Test 92 | void borderColor() { 93 | AddShortTextStep step = new AddShortTextStep(null); 94 | assertNull(step.getBorderColor()); 95 | 96 | step.setBorderColor("red"); 97 | assertEquals("red", step.getBorderColor()); 98 | } 99 | 100 | @Test 101 | void link() { 102 | AddShortTextStep step = new AddShortTextStep(null); 103 | assertNull(step.getLink()); 104 | 105 | step.setLink("https://jenkins.io"); 106 | assertEquals("https://jenkins.io", step.getLink()); 107 | } 108 | 109 | @Test 110 | void deprecated() { 111 | AddShortTextStep step = new AddShortTextStep(null); 112 | assertTrue(step.getDescriptor().isAdvanced()); 113 | } 114 | 115 | @Test 116 | void addShortText() throws Exception { 117 | String text = UUID.randomUUID().toString(); 118 | String color = UUID.randomUUID().toString(); 119 | String background = UUID.randomUUID().toString(); 120 | int border = new Random().nextInt(); 121 | String borderColor = UUID.randomUUID().toString(); 122 | String link = "http://" + UUID.randomUUID(); 123 | 124 | WorkflowJob p = r.createProject(WorkflowJob.class); 125 | p.setDefinition(new CpsFlowDefinition( 126 | "addShortText(text:\"" + text + "\", color:\"" + color + "\", background:\"" + background 127 | + "\", border:" + border + ", borderColor:\"" + borderColor + "\", link:\"" + link + "\")", 128 | true)); 129 | WorkflowRun b = r.assertBuildStatusSuccess(p.scheduleBuild2(0)); 130 | 131 | List badgeActions = b.getBadgeActions(); 132 | assertEquals(1, badgeActions.size()); 133 | 134 | BadgeAction action = (BadgeAction) badgeActions.get(0); 135 | assertEquals(text, action.getText()); 136 | assertNull(action.getIcon()); 137 | assertEquals(link, action.getLink()); 138 | } 139 | 140 | @Test 141 | void jenkinsColorStyle() throws Exception { 142 | String text = UUID.randomUUID().toString(); 143 | String color = "jenkins-!-color-red"; 144 | int border = 1; 145 | 146 | WorkflowJob p = r.createProject(WorkflowJob.class); 147 | p.setDefinition(new CpsFlowDefinition( 148 | "addShortText(text:\"" + text + "\", color:\"" + color + "\", border:\"" + border + "\")", true)); 149 | WorkflowRun b = r.assertBuildStatusSuccess(p.scheduleBuild2(0)); 150 | 151 | List badgeActions = b.getBadgeActions(); 152 | assertEquals(1, badgeActions.size()); 153 | 154 | BadgeAction action = (BadgeAction) badgeActions.get(0); 155 | assertEquals(text, action.getText()); 156 | assertEquals("border: 1px solid ;color: var(---red);", action.getStyle()); 157 | } 158 | 159 | @Test 160 | void jenkinsWarningStyle() throws Exception { 161 | String text = UUID.randomUUID().toString(); 162 | String color = "jenkins-!-warning-color"; 163 | int border = 1; 164 | 165 | WorkflowJob p = r.createProject(WorkflowJob.class); 166 | p.setDefinition(new CpsFlowDefinition( 167 | "addShortText(text:\"" + text + "\", color:\"" + color + "\", border:\"" + border + "\")", true)); 168 | WorkflowRun b = r.assertBuildStatusSuccess(p.scheduleBuild2(0)); 169 | 170 | List badgeActions = b.getBadgeActions(); 171 | assertEquals(1, badgeActions.size()); 172 | 173 | BadgeAction action = (BadgeAction) badgeActions.get(0); 174 | assertEquals(text, action.getText()); 175 | assertEquals("border: 1px solid ;color: var(--warning-color);", action.getStyle()); 176 | } 177 | 178 | @Test 179 | void addShortText_minimal() throws Exception { 180 | String text = UUID.randomUUID().toString(); 181 | 182 | WorkflowJob p = r.createProject(WorkflowJob.class); 183 | p.setDefinition(new CpsFlowDefinition("addShortText(text:\"" + text + "\")", true)); 184 | WorkflowRun b = r.assertBuildStatusSuccess(p.scheduleBuild2(0)); 185 | 186 | List badgeActions = b.getBadgeActions(); 187 | assertEquals(1, badgeActions.size()); 188 | 189 | BadgeAction action = (BadgeAction) badgeActions.get(0); 190 | assertEquals(text, action.getText()); 191 | assertNull(action.getIcon()); 192 | assertNull(action.getLink()); 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/test/java/com/jenkinsci/plugins/badge/dsl/StepClassHierarchyTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2025, Badge Plugin Authors 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.jenkinsci.plugins.badge.dsl; 25 | 26 | import static org.junit.jupiter.api.Assertions.assertTrue; 27 | 28 | import org.jenkinsci.plugins.workflow.steps.Step; 29 | import org.junit.jupiter.api.Nested; 30 | import org.junit.jupiter.api.Test; 31 | 32 | class StepClassHierarchyTest { 33 | 34 | @Nested 35 | class Badge { 36 | 37 | @Test 38 | void abstractAddBadgeStep() { 39 | assertTrue(Step.class.isAssignableFrom(AbstractAddBadgeStep.class)); 40 | } 41 | 42 | @Test 43 | void abstractRemoveBadgesStep() { 44 | assertTrue(Step.class.isAssignableFrom(AbstractRemoveBadgesStep.class)); 45 | } 46 | 47 | @Test 48 | void addBadgeStep() { 49 | assertTrue(Step.class.isAssignableFrom(AddBadgeStep.class)); 50 | assertTrue(AbstractAddBadgeStep.class.isAssignableFrom(AddBadgeStep.class)); 51 | } 52 | 53 | @Test 54 | void addErrorBadgeStep() { 55 | assertTrue(Step.class.isAssignableFrom(AddErrorBadgeStep.class)); 56 | assertTrue(AbstractAddBadgeStep.class.isAssignableFrom(AddErrorBadgeStep.class)); 57 | assertTrue(AddBadgeStep.class.isAssignableFrom(AddErrorBadgeStep.class)); 58 | } 59 | 60 | @Test 61 | void addInfoBadgeStep() { 62 | assertTrue(Step.class.isAssignableFrom(AddInfoBadgeStep.class)); 63 | assertTrue(AbstractAddBadgeStep.class.isAssignableFrom(AddInfoBadgeStep.class)); 64 | assertTrue(AddBadgeStep.class.isAssignableFrom(AddInfoBadgeStep.class)); 65 | } 66 | 67 | @Test 68 | void addWarningBadgeStep() { 69 | assertTrue(Step.class.isAssignableFrom(AddWarningBadgeStep.class)); 70 | assertTrue(AbstractAddBadgeStep.class.isAssignableFrom(AddWarningBadgeStep.class)); 71 | assertTrue(AddBadgeStep.class.isAssignableFrom(AddWarningBadgeStep.class)); 72 | } 73 | 74 | @Test 75 | void removeBadgesStep() { 76 | assertTrue(Step.class.isAssignableFrom(RemoveBadgesStep.class)); 77 | assertTrue(AbstractRemoveBadgesStep.class.isAssignableFrom(RemoveBadgesStep.class)); 78 | } 79 | } 80 | 81 | @Nested 82 | class Summary { 83 | 84 | @Test 85 | void addSummaryStep() { 86 | assertTrue(Step.class.isAssignableFrom(AddSummaryStep.class)); 87 | assertTrue(AbstractAddBadgeStep.class.isAssignableFrom(AddSummaryStep.class)); 88 | assertTrue(AddBadgeStep.class.isAssignableFrom(AddSummaryStep.class)); 89 | } 90 | 91 | @Test 92 | void removeSummariesStep() { 93 | assertTrue(Step.class.isAssignableFrom(RemoveSummariesStep.class)); 94 | assertTrue(AbstractRemoveBadgesStep.class.isAssignableFrom(RemoveSummariesStep.class)); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/test/resources/legacy-configuration/badge-action-borderColor-null.xml: -------------------------------------------------------------------------------- 1 | 2 | color 3 | background 4 | border 5 | -------------------------------------------------------------------------------- /src/test/resources/legacy-configuration/badge-action-jenkins-color.xml: -------------------------------------------------------------------------------- 1 | 2 | jenkins-!-color-value 3 | -------------------------------------------------------------------------------- /src/test/resources/legacy-configuration/badge-action-jenkins.xml: -------------------------------------------------------------------------------- 1 | 2 | jenkins-!-value-color 3 | -------------------------------------------------------------------------------- /src/test/resources/legacy-configuration/badge-action-null.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/test/resources/legacy-configuration/badge-action.xml: -------------------------------------------------------------------------------- 1 | 2 | iconPath 3 | color 4 | background 5 | border 6 | borderColor 7 | -------------------------------------------------------------------------------- /src/test/resources/legacy-configuration/summary-action-null.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/test/resources/legacy-configuration/summary-action.xml: -------------------------------------------------------------------------------- 1 | 2 | summaryText 3 | --------------------------------------------------------------------------------