[CloudBees CI] JENKINS-56109: Change Jenkins configuration UI from tables to divs


The CloudBees CI release includes JENKINS-56109: Change Jenkins configuration UI from tables to divs. Jenkins core changed its layout form from ‘table’ to ‘div’ in 2.264.


Jenkins’s jelly framework generated a lot of of tables, which sometimes do not render correctly when changing the window’s size. These tables are very mobile hostile. The UI it generates is also not in line with modern UIs. See JENKINS-56109 for more details.

Expected symptoms of regressions

All plugins which are tier 1, or tier 2 are expected to work properly. However, there might be tier 3 plugins which might not work correctly.

The main symptoms are tables not rendering correctly or form submission failures. In case that an affected plugin is configurable under Manage Jenkins » Configure System, you might not be able to save the Jenkins Global Configuration until the affected plugin is either updated, or disabled - depending if there is already a plugin release compatible with the change. In the same way, if the plugin is configurable at Job level, jobs might not be able to be reconfigurable until the problem is fixed by either, disabling the plugin or updating the plugin to a compatible version.

Some plugins are known to be broken. The Jenkins Community is tracking the status of these plugin using this EPIC.

Apart of the effort from the Jenkins community, the CloudBees support team has gone through the full plugin list provided by the community and has verified the status of each plugin, providing a PR to fix the underlaying issue when possible.

The Appendix A of this document contains the status of each of the plugins which are impacted by this change and its current status at 23rd of April 2021.


This change is present since the 2.277.1 line in all products listed below. And issues might be seen when you upgrade from a version prior to CloudBees CI 2.277.1.


As a general rule, to avoid any issues related to this change, and any other problem in the March release, it is suggested to:
1. Make sure Beekeeper is configured to upgrade CAP plugins. For this, ensure that the option Manage Jenkins » Beekeeper Upgrade Assistant » CAP Configuration » Allow automatic upgrades of plugins on restart is enabled
2. Upgrade all the plugins listed under Manage Jenkins » Manage Plugins (Updates tab)
3. Run the Groovy script from the Appendix B under Manage Jenkins » Script Console and check if there is still any plugin with a specific issue.

Appendix A. Plugins known to be incompatible with the tabs to divs change at the time of release

PluginStatusProvided PRComments
coverityOBSOLETE JENKINS-62855 As per https://plugins.jenkins.io/coverity/ This plugin is no longer maintained. The functionality has been migrated onto the new Synopsys Coverity Jenkins plugin.
multiple-scmsOBSOLETE This plugin has been marked as deprecated. In general, this means that this plugin is either obsolete, no longer being developed, or may no longer work
multi-slave-config-pluginOBSOLETE Last time it was releases was 5 years ago. This plugin should not be used
perforceOBSOLETE This plugin is deprecated. It was superseded by P4 plugin
deployit-pluginINCOMPATIBLEhttps://github.com/jenkinsci/xldeploy-plugin/pull/72Not compatible until PR is merged and released by the maintainer.
google-container-registry-authINCOMPATIBLE There is not currently a fix.
hp-application-automation-toolsINCOMPATIBLEhttps://github.com/jenkinsci/hpe-application-automation-tools-plugin/pull/377Not compatible until PR is merged and released by the maintainer.
joinINCOMPATIBLEhttps://github.com/jenkinsci/join-plugin/pull/16Not compatible. PR is merged but not released yet by the maintainer.
openstack-cloudINCOMPATIBLE There is not currently a fix.
performanceINCOMPATIBLE There is not currently a fix.
scriptlerINCOMPATIBLE There is not currently a fix.
teamconcertINCOMPATIBLE There is not currently a fix.
tfsINCOMPATIBLE There is not currently a fix. JENKINS-64241, and Distribution of this plugin has been suspended due to unresolved security vulnerabilities
xldeploy-pluginINCOMPATIBLEhttps://github.com/jenkinsci/xldeploy-plugin/pull/72/filesNot compatible until PR is merged and released by the maintainer.
rebuildCOMPATIBLE Compatible since 1.32
authorize-projectCOMPATIBLE Compatible since 1.4.0
createjobadvancedCOMPATIBLE Compatible since 1.9.0
custom-tools-pluginCOMPATIBLE Compatible since 0.8
cvsCOMPATIBLE Compatible since 2.18
gerrit-triggerCOMPATIBLE Compatible since 2.32.1
gitlab-pluginCOMPATIBLEhttps://github.com/jenkinsci/gitlab-plugin/pull/1109Compatible since 1.5.20
http_requestCOMPATIBLEhttps://github.com/jenkinsci/http-request-plugin/pull/52Compatible since 1.8.27
plotCOMPATIBLE Compatible since 2.1.9
PrioritySorterCOMPATIBLEhttps://github.com/jenkinsci/priority-sorter-plugin/pull/53Compatible since 4.0.0
publish-over-dropboxCOMPATIBLEhttps://github.com/jenkinsci/publish-over-dropbox-plugin/pull/4Compatible since 1.3.0
publish-over-ftpCOMPATIBLEhttps://github.com/jenkinsci/publish-over-ftp-plugin/pull/9Compatible since 1.16

Appendix B. Health check Groovy script

import hudson.util.VersionNumber

def plugins = [
        'coverity': [version: null, status: 'obsolete', fix: ''],
        'multiple-scms': [version: null, status: 'obsolete', fix: ''],
        'perforce': [version: null, status: 'obsolete', fix: ''],
        'multi-slave-config-plugin': [version: null, status: 'obsolete', fix: ''],
        'join': [version: null, status: 'incompatible', fix: 'https://github.com/jenkinsci/join-plugin/pull/16'],
        'publish-over-ftp': [version: new VersionNumber('1.16'), status: 'incompatible', fix: 'https://github.com/jenkinsci/publish-over-ftp-plugin/pull/9'],
        'publish-over-dropbox': [version: new VersionNumber('1.3.0'), status: 'incompatible', fix: 'https://github.com/jenkinsci/publish-over-dropbox-plugin/pull/4'],
        'deployit-plugin': [version: null, status: 'incompatible', fix: 'https://github.com/jenkinsci/xldeploy-plugin/pull/72'],
        'gitlab-plugin': [version: new VersionNumber('1.5.20'), status: 'incompatible', fix: 'https://github.com/jenkinsci/gitlab-plugin/pull/1109'],
        'hp-application-automation-tools-plugin': [version: null, status: 'incompatible', fix: 'https://github.com/jenkinsci/hpe-application-automation-tools-plugin/pull/377'],
        'PrioritySorter': [version: new VersionNumber('4.0.0'), status: 'incompatible', fix: 'https://github.com/jenkinsci/priority-sorter-plugin/pull/53'],
        'xldeploy-plugin': [version: null, status: 'incompatible', fix: 'https://github.com/jenkinsci/xldeploy-plugin/pull/72/files'],
        'google-container-registry-auth': [version: null, status: 'incompatible', fix: ''],
        'openstack-cloud': [version: null, status: 'incompatible', fix: ''],
        'performance': [version: null, status: 'incompatible', fix: ''],
        'scriptler': [version: null, status: 'incompatible', fix: ''],
        'teamconcert': [version: null, status: 'incompatible', fix: ''],
        'tfs': [version: null, status: 'incompatible', fix: ''],
        'rebuild': [version: new VersionNumber('1.32'), status: 'incompatible', fix: ''],
        'cvs': [version: new VersionNumber('2.18'), status: 'incompatible', fix: ''],
        'authorize-project': [version: new VersionNumber('1.4.0'), status: 'incompatible', fix: ''],
        'plot': [version: new VersionNumber('2.1.9'), status: 'incompatible', fix: ''],
        'gerrit-trigger': [version: new VersionNumber('2.32.1'), status: 'incompatible', fix: ''],
        'createjobadvanced': [version: new VersionNumber('1.9.0'), status: 'incompatible', fix: ''],
        'custom-tools-plugin': [version: new VersionNumber('0.8'), status: 'incompatible', fix: '']

println "------------------------- Legend -------------------------"
println "obsolete: The plugin should not be used anymore. No test was performed at all."
println "incompatible: The plugin is not compatible and should be removed"
println "------------------------- List of issues -------------------------"

Jenkins.get().pluginManager.plugins.findAll({plugins.containsKey(it.shortName)}).each {
    def pluginIssue = plugins.get(it.shortName)

    if (pluginIssue.version == null || it.isOlderThan(pluginIssue.version)) {
        print "[WARNING] '${it.displayName}' status is ${pluginIssue.status}"
        if (pluginIssue.version) {
            print " but there is new version with a fix ${pluginIssue.version}"
        } else if (!pluginIssue.fix.isEmpty()) {
            print " but there is PR with the fix ${pluginIssue.fix}"

println "-------------------------"

Have more questions?


Please sign in to leave a comment.