--- /dev/null
+########
+lfCommon
+########
+
+Common functions to be used by other scripts.
+
+Functions
+=========
+
+installPythonTools
+------------------
+
+This should be run before most jobs, in order to install commonly-used python tools.
+
+jacocoNojava
+------------
+
+Workaround for Jenkins not being able to find Java in JaCoCo runs.
+
+updateJavaAlternatives
+----------------------
+
+Runs a script to ensure that the preferred version of Java is installed and is
+the default when java commands are executed.
+
+:Required parameters:
+
+ :javaVersion: The version of java to set as the default, e.g. "openjdk11".
+
+sigulSignDir
+------------
+
+Signs the specified directory as a single artifact.
+
+:Required parameters:
+
+ :signDir: Path to directory to be signed (absolute path, or relative to
+ the current working directory).
+ :signMode: Serial or parallel. If left blank, the default (serial) is used.
--- /dev/null
+##########
+lfDefaults
+##########
+
+Usage
+=====
+
+These are default values for variables that are frequently used by functions
+and scripts within the pipeline library. Calling lfDefaults() will return a map
+of the default values. If combining with a user-specified config map, the
+user-specified values should be on the right-hand side of the addition, as this
+will be the values used in case of a collision.
+
+.. code-block:: groovy
+
+ def defaults = lfDefaults()
+ def config = [:]
+
+ if (body) {
+ body.resolveStrategy = Closure.DELEGATE_FIRST
+ body.delegate = config
+ body()
+ }
+
+ config = defaults + config
--- /dev/null
+######
+lfJava
+######
+
+Parameters
+==========
+
+:Required Parameters:
+
+ :mvnSettings: Jenkins ID of maven settings file to be used by this job
+
+:Optional Parameters:
+
+ :javaVersion: Java version to use for Maven build
+ :mvnGlobalSettings: Override default global-settings filename
+ :mvnGoals: String with maven goals to execute
+ :mvnVersion: Maven version to use in build
+
+Usage
+=====
+
+Calling lfJava will prep the agent and then execute a maven build, using the
+mvnGoals specified. If the branch is "master" or "main", the maven-deploy script will
+be called, deploying artifacts to maven. If triggered by a comment containing
+the keyword "stage", the maven-stage script will be run to sign and stage
+artifacts for release.
--- /dev/null
+---
+features:
+ - |
+ The lfJava global var introduces functionality equivalent to the global-jjb
+ jobs for maven-verify, maven-merge, and maven-stage. This will test new
+ patch/pull requests, test and deploy artifacts upon merge, and stage artifacts
+ for release.
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0
+//
+// Copyright (c) 2019 Intel Corporation
+// Copyright (c) 2020 The Linux Foundation
+//
+// 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.
+
+import com.homeaway.devtools.jenkins.testing.JenkinsPipelineSpecification
+
+public class LFCommonSpec extends JenkinsPipelineSpecification {
+
+ def lfCommon = null
+
+ def setup() {
+ lfCommon = loadPipelineScriptForTest("vars/lfCommon.groovy")
+ }
+
+ def "Test lfCommon [Should] call expected script [When] methods are called" () {
+ setup:
+ lfCommon.getBinding().setVariable('WORKSPACE', '/w/test/job/1')
+ explicitlyMockPipelineStep("withEnv")
+ getPipelineMock("libraryResource")("shell/python-tools-install.sh") >> {
+ return "python-tools-install"
+ }
+ getPipelineMock("libraryResource")("shell/update-java-alternatives.sh") >> {
+ return "update-java-alternatives"
+ }
+ getPipelineMock("libraryResource")("shell/sigul-configuration.sh") >> {
+ return "sigul-configuration"
+ }
+ getPipelineMock("libraryResource")("shell/sigul-install.sh") >> {
+ return "sigul-install"
+ }
+ when:
+ lfCommon.installPythonTools()
+ then:
+ 1 * getPipelineMock("sh").call([script:"python-tools-install"])
+ when:
+ lfCommon.jacocoNojava()
+ then:
+ 1 * getPipelineMock("sh").call("mkdir -p /w/test/job/1/target/classes /w/test/job/1/jacoco/classes")
+ when:
+ lfCommon.updateJavaAlternatives("openjdk11")
+ then:
+ 1 * getPipelineMock("sh").call([script:
+ "SET_JDK_VERSION=openjdk11" + "\n" +
+ "update-java-alternatives"
+ ])
+ when:
+ lfCommon.sigulSignDir(".", "parallel")
+ then:
+ 1 * getPipelineMock('withEnv').call(_) >> { _arguments ->
+ def envArgs = [
+ "SIGN_DIR=.",
+ "SIGN_MODE=parallel"
+ ]
+ assert envArgs == _arguments[0][0]
+ }
+ 1 * getPipelineMock("sh").call([script:"sigul-configuration" + "\n" + "sigul-install"])
+ }
+}
def setup() {
lfInfraShipLogs = loadPipelineScriptForTest('vars/lfInfraShipLogs.groovy')
- explicitlyMockPipelineVariable('out')
+ explicitlyMockPipelineVariable('lfCommon')
}
def "Test lfInfraShipLogs [Should] throw exception [When] logSettingsFile is null" () {
getPipelineMock("libraryResource")('shell/create-netrc.sh') >> {
return 'create-netrc'
}
- getPipelineMock("libraryResource")('shell/python-tools-install.sh') >> {
- return 'python-tools-install'
- }
getPipelineMock("libraryResource")('shell/sudo-logs.sh') >> {
return 'sudo-logs'
}
getPipelineMock("libraryResource")('shell/logs-clear-credentials.sh') >> {
return 'logs-clear-credentials'
}
+ getPipelineMock("lfCommon.installPythonTools").call(_) >> null
when: 'Only LOGS_SERVER defined'
lfInfraShipLogs.getBinding().setVariable('LOGS_SERVER', 'MyLogServer')
lfInfraShipLogs.getBinding().setVariable('S3_BUCKET', '')
assert envArgs == _arguments[0][0]
}
1 * getPipelineMock('sh').call([script:'create-netrc'])
- 1 * getPipelineMock('sh').call([script:'python-tools-install'])
1 * getPipelineMock('sh').call([script:'sudo-logs'])
1 * getPipelineMock('sh').call([script:'job-cost'])
1 * getPipelineMock('sh').call([script:'logs-deploy'])
assert envArgs == _arguments[0][0]
}
1 * getPipelineMock('sh').call([script:'create-netrc'])
- 1 * getPipelineMock('sh').call([script:'python-tools-install'])
1 * getPipelineMock('sh').call([script:'sudo-logs'])
1 * getPipelineMock('sh').call([script:'job-cost'])
1 * getPipelineMock('sh').call([script:'logs-deploy'])
assert envArgs == _arguments[0][0]
}
1 * getPipelineMock('sh').call([script:'create-netrc'])
- 1 * getPipelineMock('sh').call([script:'python-tools-install'])
1 * getPipelineMock('sh').call([script:'sudo-logs'])
1 * getPipelineMock('sh').call([script:'job-cost'])
1 * getPipelineMock('sh').call([script:'logs-deploy'])
assert envArgs == _arguments[0][0]
}
0 * getPipelineMock('sh').call([script:'create-netrc'])
- 0 * getPipelineMock('sh').call([script:'python-tools-install'])
0 * getPipelineMock('sh').call([script:'sudo-logs'])
0 * getPipelineMock('sh').call([script:'job-cost'])
0 * getPipelineMock('sh').call([script:'logs-deploy'])
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0
+//
+// Copyright (c) 2021 The Linux Foundation
+//
+// 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.
+
+import com.homeaway.devtools.jenkins.testing.JenkinsPipelineSpecification
+
+public class LFJavaSpec extends JenkinsPipelineSpecification {
+
+ def lfJava = null
+ def defaults = [
+ javaVersion: "openjdk11",
+ mvnGoals: "clean install",
+ mvnVersion: "mvn35",
+ mvnGlobalSettings: "testGlobalConfig",
+ mvnSettings: "testConfig",
+ ]
+
+ def setup() {
+ lfJava = loadPipelineScriptForTest('vars/lfJava.groovy')
+ explicitlyMockPipelineVariable('lfCommon')
+ explicitlyMockPipelineVariable('lfDefaults')
+ }
+
+ def "Test lfJava [Should] throw exception [When] mvnSettings is null" () {
+ setup:
+ when:
+ lfJava({mvnSettings = null})
+ then:
+ thrown Exception
+ }
+
+ def "Test lfJava [Should] build maven [When] called" () {
+ setup:
+ explicitlyMockPipelineStep('withMaven')
+ getPipelineMock('lfDefaults.call')() >> {
+ return defaults
+ }
+ getPipelineMock("libraryResource")('shell/python-tools-install.sh') >> {
+ return 'python-tools-install'
+ }
+ getPipelineMock("lfCommon.installPythonTools").call(_) >> null
+ getPipelineMock("lfCommon.jacocoNojava").call(_) >> null
+ when:
+ lfJava()
+ then:
+ 1 * getPipelineMock('withMaven').call(_) >> { _arguments ->
+ // Keys are different, but all config values in withMaven should
+ // match what we passed.
+ _arguments[0][0].values().each { i ->
+ assert defaults.values().contains(i)
+ }
+ }
+ 1 * getPipelineMock('sh').call("mvn clean install")
+ }
+
+ def "Test lfJava [Should] build & deploy maven [When] branch == 'master'" () {
+ setup:
+ explicitlyMockPipelineStep("withMaven")
+ getPipelineMock("lfDefaults.call")() >> {
+ return defaults
+ }
+ getPipelineMock("libraryResource")("shell/python-tools-install.sh") >> {
+ return "python-tools-install"
+ }
+ getPipelineMock("lfCommon.installPythonTools").call(_) >> null
+ getPipelineMock("lfCommon.jacocoNojava").call(_) >> null
+
+ explicitlyMockPipelineStep("mavenDeploy")
+ lfJava.getBinding().setVariable("env", ["GIT_BRANCH": "master"])
+
+ getPipelineMock("libraryResource")("shell/common-variables.sh") >> {
+ return "common-variables"
+ }
+ getPipelineMock("libraryResource")("shell/maven-deploy.sh") >> {
+ return "maven-deploy"
+ }
+ when:
+ lfJava()
+ then:
+ 2 * getPipelineMock('withMaven').call(_) >> { _arguments ->
+ // Keys are different, but all config values in withMaven should
+ // match what we passed.
+ _arguments[0][0].values().each { i ->
+ assert defaults.values().contains(i)
+ }
+ }
+ 1 * getPipelineMock('sh').call("mvn clean install")
+ 1 * getPipelineMock('sh').call([script: "common-variables" + "\n" + "maven-deploy"])
+ }
+
+ def "Test lfJava [Should] build & stage maven [When] comment contains 'stage'" () {
+ setup:
+ explicitlyMockPipelineStep("withMaven")
+ getPipelineMock('lfDefaults.call')() >> {
+ return defaults
+ }
+ getPipelineMock("libraryResource")('shell/python-tools-install.sh') >> {
+ return 'python-tools-install'
+ }
+ getPipelineMock("lfCommon.installPythonTools").call(_) >> null
+ getPipelineMock("lfCommon.jacocoNojava").call(_) >> null
+
+ explicitlyMockPipelineStep("mavenStage")
+ lfJava.getBinding().setVariable("env", ["GITHUB_COMMENT": "stage-release"])
+
+ getPipelineMock("libraryResource")("shell/common-variables.sh") >> {
+ return "common-variables"
+ }
+ getPipelineMock("libraryResource")("shell/maven-stage.sh") >> {
+ return "maven-stage"
+ }
+ when:
+ lfJava()
+ then:
+ 2 * getPipelineMock('withMaven').call(_) >> { _arguments ->
+ // Keys are different, but all config values in withMaven should
+ // match what we passed.
+ _arguments[0][0].values().each { i ->
+ assert defaults.values().contains(i)
+ }
+ }
+ 1 * getPipelineMock('sh').call("mvn clean install")
+ 1 * getPipelineMock('sh').call([script: "common-variables" + "\n" + "maven-stage"])
+ }
+}
[testenv:pre-commit]
description = Precommit checks for black, gitlint, etc.
deps = pre-commit
+passenv = HOME
commands =
pre-commit run --all-files --show-diff-on-failure
pre-commit run gitlint --hook-stage commit-msg --commit-msg-filename .git/COMMIT_EDITMSG
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0
+//
+// Copyright (c) 2021 The Linux Foundation
+//
+// 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.
+
+/**
+ * Common functions
+ */
+
+// Replaces lf-infra-pre-build
+def installPythonTools() {
+ sh(script: libraryResource('shell/python-tools-install.sh'))
+}
+
+// Replaces lf-jacoco-nojava-workaround
+def jacocoNojava() {
+ sh("mkdir -p $WORKSPACE/target/classes $WORKSPACE/jacoco/classes")
+}
+
+def updateJavaAlternatives(javaVersion) {
+ bashScript = [
+ "SET_JDK_VERSION=$javaVersion",
+ libraryResource('shell/update-java-alternatives.sh')
+ ].join("\n")
+ sh(script: bashScript)
+ // TODO: Inject /tmp/java.env
+}
+
+def sigulSignDir(signDir, signMode) {
+ if (signMode == "") {
+ signMode = "serial"
+ }
+ configFileProvider([
+ configFile(fileId: 'sigul-config', variable: 'SIGUL_CONFIG'),
+ configFile(fileId: 'sigul-password', variable: 'SIGUL_PASSWORD'),
+ configFile(fileId: 'sigul-pki', variable: 'SIGUL_PKI')
+ ]) {
+ configAndInstall = [
+ libraryResource('shell/sigul-configuration.sh'),
+ libraryResource('shell/sigul-install.sh')
+ ].join("\n")
+ withEnv([
+ "SIGN_DIR=$signDir",
+ "SIGN_MODE=$signMode"
+ ]) {
+ sh(script: configAndInstall)
+ }
+ sh(script: libraryResource('shell/sigul-configuration-cleanup.sh'))
+ }
+}
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0
+//
+// Copyright (c) 2021 The Linux Foundation
+//
+// 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.
+
+/**
+ * Provides default values for common variables within the library.
+ *
+ */
+def call(body) {
+ def defaults = [
+ lftoolsVersion: "<1.0.0",
+ packerVersion: "1.7.2",
+ jenkinsSshCredential: "jenkins-ssh",
+ buildDaysToKeep: 30,
+ buildTimeout: 60,
+ archiveArtifacts: "",
+ javaVersion: "openjdk11",
+
+ mvnGoals: "clean install",
+ mvnVersion: "mvn35",
+ mvnGlobalSettings: "global-settings",
+ ]
+ return defaults
+}
sh(script: libraryResource('shell/create-netrc.sh'))
}
- echo 'Running shell/python-tools-install.sh'
- sh(script: libraryResource('shell/python-tools-install.sh'))
+ lfCommon.installPythonTools()
echo 'Running shell/sudo-logs.sh'
sh(script: libraryResource('shell/sudo-logs.sh'))
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0
+//
+// Copyright (c) 2021 The Linux Foundation
+//
+// 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.
+
+/**
+ * Method to run Java jobs.
+ * Required body values:
+ * * mvnSettings: Maven settings config file ID
+ * Optional body values (should be defined in lfDefaults):
+ * * javaVersion
+ * * mvnGlobalSettings
+ * * mvnGoals
+ * * mvnVersion
+ *
+ * @param body Config values to be provided in the form "key = value".
+ */
+def call(body) {
+ // Evaluate the body block and collect configuration into the object
+ def defaults = lfDefaults()
+ def config = [:]
+
+ if (body) {
+ body.resolveStrategy = Closure.DELEGATE_FIRST
+ body.delegate = config
+ body()
+ }
+
+ // For duplicate keys, Groovy will use the right hand map's values.
+ config = defaults + config
+
+ if (!config.mvnSettings) {
+ throw new Exception("Maven settings file id (mvnSettings) is " +
+ "required for lfJava function.")
+ }
+
+ ////////////////////////
+ // Default parameters //
+ ////////////////////////
+ archiveArtifacts = """**/*.log
+**/hs_err_*.log
+**/target/**/feature.xml
+**/target/failsafe-reports/failsafe-summary.xml
+**/target/surefire-reports/*-output.txt"""
+
+ lfCommon.installPythonTools()
+ lfCommon.jacocoNojava()
+
+ withMaven(
+ maven: config.mvnVersion,
+ jdk: config.javaVersion,
+ mavenSettingsConfig: config.mvnSettings,
+ globalMavenSettingsConfig: config.mvnGlobalSettings,
+ ) {
+ sh "mvn ${config.mvnGoals}"
+ }
+
+ if (env.GIT_BRANCH == "main" || env.GIT_BRANCH == "master") {
+ mavenDeploy(config)
+ }
+
+ // TODO: Make this generic, rather than Github-specific. A function in
+ // lfCommon that will take comments from different providers and check them
+ // would be ideal.
+ if (env.GITHUB_COMMENT =~ /stage/) {
+ mavenStage(config)
+ }
+}
+
+def mavenDeploy(config) {
+ deployScript = [
+ libraryResource('shell/common-variables.sh'),
+ libraryResource('shell/maven-deploy.sh')
+ ].join("\n")
+
+ withMaven(
+ maven: config.mvnVersion,
+ jdk: config.javaVersion,
+ mavenSettingsConfig: config.mvnSettings,
+ globalMavenSettingsConfig: config.mvnGlobalSettings,
+ ) {
+ sh(script: deployScript)
+ }
+}
+
+def mavenStage(config) {
+ lfCommon.sigulSignDir(".", "")
+ stageScript = [
+ libraryResource('shell/common-variables.sh'),
+ libraryResource('shell/maven-stage.sh')
+ ].join("\n")
+
+ withMaven(
+ maven: config.mvnVersion,
+ jdk: config.javaVersion,
+ mavenSettingsConfig: config.mvnSettings,
+ globalMavenSettingsConfig: config.mvnGlobalSettings,
+ ) {
+ sh(script: stageScript)
+ }
+}