Atlassian Plugin Install



On this page

Summary

This is a tool to help automate installing plugins (add-ons) on Atlassian servers. It is a selenium based approach and can be fragile with respect to UI changes in the application or UPM. We have tried to minimize those exposures.

  • Drives a UPM browser interface (Selenium)

  • Installs obr (first choice) or jar

  • Finds most likely obr or jar found in a directory list defaulting to target and current directory

  • Can install directly from Marketplace using one or more marketplace keys (comma separated list)

  • Alias support - see below

  • Support standard install plugin set (based on gint.properties aliases set)

    • Use -DmpKey=all

Dependencies

  1. Supports latest versions of Confluence (5.2+), JIRA (6.0+), and Bamboo (5.3+). Stash support will come later.

  2. Needs later versions of UPM.

Code

piui.gant
/* * Copyright (c) 2014 Appfire Technologies, LLC. * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ /** * Selenium script to install a plugin from a file or url or marketplace. * This uses a browser (firefox by default) specified by -Dbrowser=... (firefox, safari, chrome, ie) * See HELP section below */ @Grab(group='org.swift.tools', module='gint', version='2.1.0') @Grab(group='org.seleniumhq.selenium', module='selenium-java', version='2.43.0') @Grab(group='org.seleniumhq.selenium', module='selenium-firefox-driver', version='2.43.0') @Grab(group='org.seleniumhq.selenium', module='selenium-chrome-driver', version='2.43.0') @Grab(group='org.seleniumhq.selenium', module='selenium-safari-driver', version='2.43.0') @Grab(group='org.seleniumhq.selenium', module='selenium-ie-driver', version='2.43.0') // not tested import org.swift.tools.* import org.openqa.selenium.* includeTool << Helper // helper utilities includeTool << SeleniumHelperForAtlassian includeTool << Gint message 'help', """\n This will try to do the right thing with minimal parameters by using standard project defaults. Parameters: server: required - either direct server url or extended lookup value (via gint.properties) user: optional - server login credentials defaulting to admin password: optional - server login credentials defaulting to admin application: optional - Atlassian application name like confluence, jira; defaults to looking for appropriate server or mpKey text indicators plugin: optional - file name or url path; if not provided, a search for an obr (first) or jar (second) will be done in directory list mpKey: optional - comma separated list of marketplace keys or aliases, takes precedence over plugin; ALL special value for all matching aliases version: optional - marketplace version build number, only use if you need something other than latest version directory: optional - place to look for an obr or jar file; if not provided target and current directory are searched aliasNamePattern: optional - allows for mpKey alias names in gint.properties to map to mp keys aliasValuePattern: optional - subset mpKeys by value to restrict to a particular application (for instance) when doing ALL processing Examples: ${this.getClass().getName()} -Dserver=http://imac2.local:1990 -DmpKey=org.swift.confluence.wiki ${this.getClass().getName()} -Dserver=http://imac2.local:1990 -DmpKey=csot -Dapplication=jira ${this.getClass().getName()} -Dserver=http://imac2.local:1990 -Duser=xxx -Dpassword=xxx ${this.getClass().getName()} -Dserver=confluenceCli3 -Dplugin=downloads/bobswift-wiki-markup-1.3.0-SNAPSHOT.jar \n """ // mp key aliases are provided in a resource based gint.properties so you can use mpKey=all // resourceDirectory = '/sde/tools/src/main/resources' // for tools, this is a better directory than the itest default gint.initialize(this) // required, standard selenium test name gint.setStopOnFail() // stop if some of the initial validation fails setDefaultTarget('install') def parameters = [ serverRaw: helper.getRequiredParameterValue('server'), // raw input without extended lookup used for application determination server: helper.getParameterValueWithExtendedLookup('server'), application: helper.getParameterValue('application'), plugin: helper.getParameterValue('plugin'), mpKey: helper.getParameterValue('mpKey')?.toLowerCase(), version: helper.getParameterValue('version'), directory: helper.getParameterValue('directory'), pollingCount: helper.getParameterValue('pollingCount', 24) // local systems should complete install < 2 minutes = 24*5 seconds ] if (parameters.application == null) { def convertedMpKey = helper.getParameterValue('mp_' + parameters.mpKey) // do a default conversion and see if that help figure out the application parameters.application = seleniumHelper.findApplication([parameters.server, parameters.serverRaw, parameters.mpKey, convertedMpKey]) } parameters += [ aliasNamePattern: helper.getParameterValue('aliasNamePattern', 'mp_(.*)'), // default, just use the portion after mp_ for the alias aliasValuePattern: helper.getParameterValue('aliasValuePattern', parameters.application == null ? null : /.*${parameters.application}.*/), // for ALL processing ] helper.vLogWithFormat('parameters', parameters) // It is much better to pre-validate parameters as much as possible BEFORE going to selenium and it failing after a long period of time // If there is bad input, this will cause the test to fail prior to setup validatedParameters = seleniumHelper.getValidatedInstallParameters(parameters) helper.logWithFormat('install', validatedParameters) // Selenium clean up target(name: 'final', description: 'Close the driver at the final stage of the script', prehook: [], posthook: []) { seleniumHelper.close() } gint.addSetUp([ seleniumHelper.getInitializeTestcase(), // Selenium initialize seleniumHelper.getLoginTestcase(server: parameters.server, application: parameters.application, adminLogin: true) ]) if (validatedParameters.mpKeySet == null) { gint.add( name: 'install', description: 'Go to UPM and find upload link', inline: { testcase -> seleniumHelper.installPlugin(validatedParameters) } ) } else { // this means that all installs will be attempted even if there is one of the installs fail. validatedParameters.mpKeySet.each { mpKey -> gint.setStopOnFail(false) // now we want to continue even if one fails gint.add( name: 'install_' + mpKey, description: 'install for marketplace key: ' + mpKey, group: 'install', inline: { seleniumHelper.installPlugin(validatedParameters + [mpKeySet: null, mpKey: mpKey]) }, ) } } gint.add( name: 'simulate', description: 'Output what would be installed if the install was run normally.', // helps with testing validate inline: { testcase -> if (validatedParameters.plugin != null) { message 'simulate', validatedParameters.plugin } validatedParameters.mpKeySet.each { mpKey -> message 'simulate', mpKey } return true } ) gint.finalizeTest() // required

Aliases

Aliases make it easier by not having to remember their marketplace key. Need something like the following in your gint.properties file. A separate gint.properties file in your src/main/resources directory is the most convenient.

Built-in Aliases





Example Aliases

src/main/resources/gint.properties
# Marketplace key aliases - map project key to mp key for plugins. # Note that the alias is the part AFTER mp_. So reference is cache, run, navigation etc.... # Used for piui at least mp_bclip = org.swift.bamboo.acli mp_bgtp = org.swift.bamboo.groovy mp_cache = org.swift.confluence.cache mp_ccli = org.swift.confluence.acli mp_cmsp = org.swift.confluence.macrosecurity mp_codepro = com.appfire.confluence.codepro mp_csot = org.swift.jira.cot mp_cvp = org.swift.confluence.visio mp_cw = org.swift.jira.cw mp_cwp = org.swift.confluence.wiki mp_flash = org.swift.confluence.flash mp_gviz = com.atlassian.confluence.extra.graphviz mp_html = org.swift.confluence.html mp_jclip = org.swift.jira.acli mp_jcpp = org.swift.jira.clone-plus mp_markdown = org.swift.confluence.markdown mp_run = org.swift.confluence.run mp_sclip = org.swift.stash.acli mp_scrp = org.swift.confluence.script mp_sql = org.swift.confluence.sql mp_tbl = org.swift.confluence.table mp_xl = org.swift.confluence.excel ## Use confluence in the value for any so it will be selected for all processing ## 3rd party and used in tests - confluence, source editor is just a convenience mp_content-formatting = com.adaptavist.confluence.contentFormattingMacros mp_linking = net.customware.confluence.plugin.linking mp_reporting = net.customware.confluence.plugin.reporting mp_navigation = com.pentec.confluence.navigation mp_metadata = org.andya.confluence.plugins.metadata mp_confluence3rdParty = content-formatting, linking, reporting, navigation, metadata, source-editor, questions, confluence ## 3rd party and used in tests - jira mp_jira-suite-utilities = com.googlecode.jira-suite-utilities mp_jira3rdParty = jira-suite-utilities, agile, service-desk



© 2005 -2024 gint.org