This is an automated email from the ASF dual-hosted git repository.
rantunes pushed a commit to branch main
in repository
https://gitbox.apache.org/repos/asf/incubator-kie-tools-temporary-rnd-do-not-use.git
The following commit(s) were added to refs/heads/main by this push:
new e0ddf0386c CI - Jenkins shared scripts (#21)
e0ddf0386c is described below
commit e0ddf0386ca5bac2ff3eafbd6f84fed58f6b5315
Author: Rodrigo Antunes <[email protected]>
AuthorDate: Thu Nov 23 16:29:57 2023 -0300
CI - Jenkins shared scripts (#21)
* CI - Jenkins shared scripts
* Update openshift get route utility
---
.ci/jenkins/shared-scripts/buildUtils.groovy | 110 +++++++++++++
.ci/jenkins/shared-scripts/chromeStoreUtils.groovy | 52 ++++++
.ci/jenkins/shared-scripts/dockerUtils.groovy | 32 ++++
.ci/jenkins/shared-scripts/githubUtils.groovy | 180 +++++++++++++++++++++
.ci/jenkins/shared-scripts/openShiftUtils.groovy | 77 +++++++++
.ci/jenkins/shared-scripts/pipelineVars.groovy | 20 +++
.ci/jenkins/shared-scripts/zipUtils.groovy | 37 +++++
7 files changed, 508 insertions(+)
diff --git a/.ci/jenkins/shared-scripts/buildUtils.groovy
b/.ci/jenkins/shared-scripts/buildUtils.groovy
new file mode 100644
index 0000000000..9a01314af9
--- /dev/null
+++ b/.ci/jenkins/shared-scripts/buildUtils.groovy
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/**
+* Start Docker in Docker (DinD)
+*/
+def startDockerInDocker() {
+ sh '''#!/bin/bash -el
+ sudo entrypoint.sh
+ sudo service dbus start
+ '''.trim()
+}
+
+/**
+* Start Xvfb X server required for KIE-Tools E2E tests
+*/
+def startXvfb() {
+ sh '''#!/bin/bash -el
+ Xvfb :99 -screen 0 1920x1080x24 > /dev/null 2>&1 &
+ '''.trim()
+}
+
+/**
+* Start Fluxbox window manager required for KIE-Tools E2E tests
+*/
+def startFluxbox() {
+ sh '''#!/bin/bash -el
+ fluxbox -display :99 > /dev/null 2>&1 &
+ '''.trim()
+}
+
+/**
+* Setup PNPM parameters for building KIE-Tools
+*/
+def setupPnpm() {
+ sh """#!/bin/bash -el
+ pnpm config set network-timeout 1000000
+ pnpm -r exec 'bash' '-c' 'mkdir .mvn'
+ pnpm -r exec 'bash' '-c' 'echo -B > .mvn/maven.config'
+ pnpm -r exec 'bash' '-c' 'echo -ntp >> .mvn/maven.config'
+ pnpm -r exec 'bash' '-c' 'echo -Xmx2g > .mvn/jvm.config'
+ pnpm -F *-image exec sed -i
's/\\("build:prod.*".*\\)podman:build\\(.*\\)/\\1docker:build\\2/g' package.json
+ """.trim()
+}
+
+/**
+* PNPM Bootsrap
+*/
+def pnpmBootstrap(String filters = '') {
+ sh """#!/bin/bash -el
+ pnpm bootstrap ${filters}
+ """.trim()
+}
+
+/**
+* PNPM build all packages
+*/
+def pnpmBuildFull(Integer workspaceConcurrency = 1) {
+ sh """#!/bin/bash -el
+ pnpm -r --workspace-concurrency=${workspaceConcurrency} build:prod
+ """.trim()
+}
+
+/**
+* PNPM build a set of packages
+*/
+def pnpmBuild(String filters, Integer workspaceConcurrency = 1) {
+ sh """#!/bin/bash -el
+ pnpm ${filters} --workspace-concurrency=${workspaceConcurrency} build:prod
+ """.trim()
+}
+
+/**
+* Start KIE-Tools required services for build and test
+*/
+def startRequiredServices() {
+ startDockerInDocker()
+ startXvfb()
+ startFluxbox()
+}
+
+/**
+* @return String build datetime - format (%Y-%m-%d %T)
+*/
+def buildDateTime() {
+ return sh(script: "echo `date +'%Y-%m-%d %T'`", returnStdout: true).trim()
+}
+
+/**
+* @return String the Apache Jenkins agent nodes with higher capacity (builds22
to builds40)
+**/
+def apacheAgentLabels() {
+ return (22..40).collect{"builds$it"}.join(' || ')
+}
+
+return this;
diff --git a/.ci/jenkins/shared-scripts/chromeStoreUtils.groovy
b/.ci/jenkins/shared-scripts/chromeStoreUtils.groovy
new file mode 100644
index 0000000000..610df262af
--- /dev/null
+++ b/.ci/jenkins/shared-scripts/chromeStoreUtils.groovy
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/**
+* Upload an extension to Chrome Store
+*
+* @return String status
+*/
+def uploadExtension(String chromeStoreCredentialsId, String
chromeStoreRefreshTokenCredentialsId, String file, String extensionId) {
+ withCredentials([usernamePassword(credentialsId: chromeStoreCredentialsId,
usernameVariable: 'CLIENT_ID', passwordVariable: 'CLIENT_SECRET')]) {
+ withCredentials([string(credentialsId:
"${pipelineVars.chromeStoreRefreshTokenCredentialsId}", variable:
'REFRESH_TOKEN')]) {
+ accessToken = sh(returnStdout: true, script: "curl -X POST -fsS
\"https://oauth2.googleapis.com/token\" -d
\"client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&refresh_token=${REFRESH_TOKEN}&grant_type=refresh_token\"
| jq -r '.access_token'").trim()
+ uploadResponse = sh(returnStdout: true, script: "curl -X PUT -sS
\"https://www.googleapis.com/upload/chromewebstore/v1.1/items/${extensionId}\"
-H \"Authorization: Bearer ${accessToken}\" -H \"x-goog-api-version:2\" -T
${file}").trim()
+
+ return sh(returnStdout: true, script: "echo \"${uploadResponse}\"
| jq -r '.uploadState'").trim()
+ }
+ }
+}
+
+/**
+* Publish an extension to Chrome Store
+*
+* @return String status
+*/
+def publishExtension(String chromeStoreCredentialsId, String
chromeStoreRefreshTokenCredentialsId, String extensionId) {
+ withCredentials([usernamePassword(credentialsId:
"${pipelineVars.chromeStoreCredentialsId}", usernameVariable: 'CLIENT_ID',
passwordVariable: 'CLIENT_SECRET')]) {
+ withCredentials([string(credentialsId:
"${pipelineVars.chromeStoreRefreshTokenCredentialsId}", variable:
'REFRESH_TOKEN')]) {
+ script {
+ accessToken = sh(returnStdout: true, script: "curl -X POST
-fsS \"https://oauth2.googleapis.com/token\" -d
\"client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&refresh_token=${REFRESH_TOKEN}&grant_type=refresh_token\"
| jq -r '.access_token'").trim()
+ publishResponse = sh(returnStdout: true, script: "curl -X POST
-sS
\"https://www.googleapis.com/chromewebstore/v1.1/items/${extensionId}/publish\"
-H \"Authorization: Bearer ${accessToken}\" -H \"x-goog-api-version:2\" -H
\"Content-Length:\"").trim()
+
+ return sh(returnStdout: true, script: "echo
\"${publishResponse}\" | jq -r '.status | .[0]'").trim()
+ }
+ }
+ }
+}
+
+return this;
diff --git a/.ci/jenkins/shared-scripts/dockerUtils.groovy
b/.ci/jenkins/shared-scripts/dockerUtils.groovy
new file mode 100644
index 0000000000..9f78c06dac
--- /dev/null
+++ b/.ci/jenkins/shared-scripts/dockerUtils.groovy
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/**
+* Push an image to a given registry
+*/
+def pushImageToRegistry(String registry, String image, String tags, String
credentialsId) {
+ withCredentials([usernamePassword(credentialsId: credentialsId,
usernameVariable: 'REGISTRY_USER', passwordVariable: 'REGISTRY_PWD')]) {
+ sh "set +x && docker login -u $REGISTRY_USER -p $REGISTRY_PWD
$registry"
+ tagList = tags.split(' ')
+ for (tag in tagList) {
+ sh "docker push $registry/$image:$tag"
+ }
+ sh 'docker logout'
+ }
+}
+
+return this;
diff --git a/.ci/jenkins/shared-scripts/githubUtils.groovy
b/.ci/jenkins/shared-scripts/githubUtils.groovy
new file mode 100644
index 0000000000..b5378ab021
--- /dev/null
+++ b/.ci/jenkins/shared-scripts/githubUtils.groovy
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/**
+* Create a Github release
+*
+* @return String with the release information
+*/
+def createRelease(String repository, String name, String tag, String commit,
Boolean draft, Boolean preRelease, String credentialsId) {
+ withCredentials([string(credentialsId: credentialsId, variable:
'GITHUB_TOKEN')]) {
+ response = sh returnStdout: true, script: """
+ set +x
+ curl -L \
+ -X POST \
+ -H "Accept: application/vnd.github+json" \
+ -H "Authorization: Bearer ${GITHUB_TOKEN}" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ https://api.github.com/repos/${repository}/releases \
+ -d '{"tag_name": "${tag}", "target_commitish": "${commit}", "name":
"${name}", "draft": ${draft}, "prerelease": ${preRelease}'
+ """.trim()
+
+ return response
+ }
+}
+
+/**
+* Fetch a Github Release by tag
+*
+* @return String with the release information
+*/
+def fetchRelease(String repository, String tag, String credentialsId) {
+ withCredentials([string(credentialsId: credentialsId, variable:
'GITHUB_TOKEN')]) {
+ response = sh returnStdout: true, script: """
+ set +x
+ curl -L \
+ -H "Accept: application/vnd.github+json" \
+ -H "Authorization: Bearer ${GITHUB_TOKEN}" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ https://api.github.com/repos/${repository}/releases/tags/${tag}
+ """.trim()
+
+ return response
+ }
+}
+
+/**
+* Upload an asset to a GitHub release
+*
+* @return String with the release asset information
+*/
+def uploadReleaseAsset(String uploadUrl, String assetPath, String assetName,
String assetContentType, String credentialsId) {
+ withCredentials([string(credentialsId: credentialsId, variable:
'GITHUB_TOKEN')]) {
+ response = sh returnStdout: true, script: """
+ set +x
+ curl -L \
+ -X POST \
+ -H "Accept: application/vnd.github+json" \
+ -H "Authorization: Bearer ${GITHUB_TOKEN}" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ -H "Content-Type: ${assetContentType}" \
+ "${uploadUrl}?name=${assetName}" \
+ --data-binary "@${assetPath}"
+ """.trim()
+
+ return response
+ }
+}
+
+/**
+* Set build status
+*/
+def commitStatus(String repository, String commit, String context, String
state, String jobUrl) {
+ withCredentials([string(credentialsId: credentialsId, variable:
'GITHUB_TOKEN')]) {
+ response = sh returnStdout: true, script: """
+ set +x
+ curl -L \
+ -X POST \
+ -H "Accept: application/vnd.github+json" \
+ -H "Authorization: Bearer ${GITHUB_TOKEN}" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ https://api.github.com/repos/${repository}/statuses/${commit} \
+ -d
'{"state":"${state}","target_url":"${jobUrl}","description":"${message}","context":"${context}"}'
+ """.trim()
+
+ return response
+ }
+}
+
+/**
+* Parse an release upload asset url to remove unecessary strings
+*/
+def parseReleaseAssetUploadUrl(String uploadUrl) {
+ return uploadUrl.replace('{?name,label}', '')
+}
+
+/**
+* Checkout a github repository using GitSCM class
+*/
+def checkoutRepo(String url, String branch, String credentialsId) {
+ checkout([$class: 'GitSCM',
+ branches: [[name: "${branch}"]],
+ doGenerateSubmoduleConfigurations: false,
+ extensions: [[$class: 'CleanCheckout']],
+ submoduleCfg: [],
+ userRemoteConfigs: [[credentialsId: credentialsId, url: "${url}"]]
+ ])
+}
+
+/**
+* Perform a squashed merge on a local repository
+*/
+def squashedMerge(String author, String branch, String url) {
+ sh """#!/bin/bash -el
+ git config --global user.email "[email protected]"
+ git config --global user.name "KIE Tools Bot (kiegroup)"
+ git remote add ${author} ${url}
+ git fetch ${author} ${branch}
+ git merge --squash ${author}/${branch}
+ git commit --no-edit
+ """.trim()
+}
+
+/**
+* Checkout a github repository and perform a squashed merge on a local
repository
+*/
+def checkoutRepoSquashedMerge(String author, String branch, String url, String
targetBranch, String targetUrl, String credentialsId) {
+ checkoutRepo(targetUrl, targetBranch, credentialsId)
+ if (author && branch && url) {
+ squashedMerge(author, branch, url)
+ } else {
+ echo 'Skip squashed merge, not a pull request'
+ }
+}
+
+/**
+* @return the Github repository slug (org/repo) from an URL
+*/
+def getRepoSlug(String url) {
+ tokens = url.tokenize('/')
+ org = tokens[tokens.size()-4]
+ repo = tokens[tokens.size()-3]
+
+ return "${org}/${repo}"
+}
+
+/**
+* @return the files changed in the last commit
+*/
+def getChangesetLastCommit() {
+ changeset = sh returnStdout: true, script: '''
+ git diff --name-only HEAD HEAD~1
+ '''.trim()
+
+ return changeset
+}
+
+/**
+* @return if a given file is in the changeset of the last commit
+*/
+def fileIsInChangeset(String file) {
+ changeset = getChangesetLastCommit()
+
+ return changeset.contains(file)
+}
+
+return this;
diff --git a/.ci/jenkins/shared-scripts/openShiftUtils.groovy
b/.ci/jenkins/shared-scripts/openShiftUtils.groovy
new file mode 100644
index 0000000000..729c4d7671
--- /dev/null
+++ b/.ci/jenkins/shared-scripts/openShiftUtils.groovy
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/**
+* Create or update an existing application in a Openshift cluster
+*/
+def createOrUpdateApp(String project, String appName, String imageTag, String
imageUrl, String partOf, String deploymentIcon, String credentialsId, String
deploymentEnvVarsPath='./deployment.env') {
+ withCredentials([usernamePassword(credentialsId: credentialsId,
usernameVariable: 'OS_SERVER', passwordVariable: 'OS_TOKEN')]) {
+ sh 'set +x && oc login --token=$OS_TOKEN --server=$OS_SERVER
--insecure-skip-tls-verify'
+ sh """#!/bin/bash -el
+ oc project ${project}
+
+ if [ ! -f ${deploymentEnvVarsPath} ]; then
+ echo "ENV file does not exist"
+ touch ${deploymentEnvVarsPath}
+ fi
+
+ if ! oc get deploy ${appName} > /dev/null 2>&1; then
+ echo "Create the app '${appName}'"
+
+ oc create imagestream ${appName}
+ oc import-image ${appName}:${imageTag} --from=${imageUrl} --confirm
+ oc tag ${appName}:${imageTag} ${appName}:latest
+
+ oc label imagestreams/${appName} app=${appName}
+ oc label imagestreams/${appName}
app.kubernetes.io/component=${appName}
+ oc label imagestreams/${appName}
app.kubernetes.io/instance=${appName}
+ oc label imagestreams/${appName} app.kubernetes.io/part-of=${partOf}
+
+ oc new-app ${appName}:latest --name=${appName}
--env-file=${deploymentEnvVarsPath}
+ oc create route edge --service=${appName}
+
+ oc label services/${appName} app.kubernetes.io/part-of=${partOf}
+ oc label routes/${appName} app.kubernetes.io/part-of=${partOf}
+ oc label deployments/${appName} app.kubernetes.io/part-of=${partOf}
+ oc label deployments/${appName}
app.openshift.io/runtime=${deploymentIcon}
+ else
+ echo "App '${appName}' already exists. Update the ImageStream
instead."
+ oc tag -d ${appName}:latest
+ oc import-image ${appName}:${imageTag} --from=${imageUrl} --confirm
+ oc tag ${appName}:${imageTag} ${appName}:latest
+ cat ${deploymentEnvVarsPath} | oc set env deploy/${appName} -
+ fi
+ """.trim()
+ sh 'oc logout'
+ }
+}
+
+/**
+* @return String route to the OpenShift application
+*/
+def getAppRoute(String project, String appName, String credentialsId) {
+ withCredentials([usernamePassword(credentialsId: credentialsId,
usernameVariable: 'OS_SERVER', passwordVariable: 'OS_TOKEN')]) {
+ sh 'set +x && oc login --token=$OS_TOKEN --server=$OS_SERVER
--insecure-skip-tls-verify'
+ sh "oc project ${project}"
+ route = sh(returnStdout: true, script: "oc get route ${appName} -o
jsonpath='{.spec.host}'").trim()
+ sh 'oc logout'
+
+ return "https://${route}"
+ }
+}
+
+return this;
diff --git a/.ci/jenkins/shared-scripts/pipelineVars.groovy
b/.ci/jenkins/shared-scripts/pipelineVars.groovy
new file mode 100644
index 0000000000..c278e882aa
--- /dev/null
+++ b/.ci/jenkins/shared-scripts/pipelineVars.groovy
@@ -0,0 +1,20 @@
+class PipelineVars implements Serializable {
+
+ String githubRepositoryOrg = 'apache';
+ String githubRepositoryName =
'incubator-kie-tools-temporary-rnd-do-not-use';
+ String githubRepositorySlug =
'apache/incubator-kie-tools-temporary-rnd-do-not-use';
+
+ String quayPushCredentialsId = 'quay-io-kie-tools-token';
+ String openshiftCredentialsId = 'openshift-kie-tools-token';
+ String kieToolsBotGithubCredentialsId = 'kie-tools-bot-gh';
+ String kieToolsBotGithubTokenCredentialsId = 'kie-tools-bot-gh-token';
+ String kieToolsGithubCodeQLTokenCredentialsId =
'kie-tools-gh-codeql-token';
+ String chromeStoreCredentialsId = 'kie-tools-chome-store';
+ String chromeStoreRefreshTokenCredentialsId =
'kie-tools-chome-store-refresh-token';
+ String npmTokenCredentialsId = 'kie-tools-npm-token';
+
+ String defaultArtifactsTempDir = 'artifacts-tmp';
+
+}
+
+return new PipelineVars();
diff --git a/.ci/jenkins/shared-scripts/zipUtils.groovy
b/.ci/jenkins/shared-scripts/zipUtils.groovy
new file mode 100644
index 0000000000..1521ce5312
--- /dev/null
+++ b/.ci/jenkins/shared-scripts/zipUtils.groovy
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/**
+* Compress a build artifact to a zip file
+*/
+def zipArtifact(String filePath, String patterns) {
+ sh """#!/bin/bash -el
+ output_empty_zip () { echo UEsFBgAAAAAAAAAAAAAAAAAAAAAAAA== | base64 -d; }
+ zip -r ${filePath} ${patterns} || output_empty_zip > ${filePath}
+ """.trim()
+}
+
+/**
+* Unzip an build artifact
+*/
+def unzipArtifact(String filePath, String targetDir) {
+ sh """#!/bin/bash -el
+ unzip ${filePath} -d ${targetDir}
+ """.trim()
+}
+
+return this;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]