Copilot commented on code in PR #7123: URL: https://github.com/apache/incubator-kie/pull/7123#discussion_r4229460540
########## .ci/jenkins/Jenkinsfile.103xplus.promote: ########## @@ -0,0 +1,293 @@ +/* + * 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. + */ + +// 10.3.x+ promote pipeline — mirrors Jenkinsfile.promote with 10.3+ specifics: +// - 'Create release' stage uses Nexus nexus-staging:release (same as old) +// - 'Tag final release' stage delegates to 05-tag-release.sh (tags the +// approved RC commit, not the branch tip as the old pipeline did) +// - 'Upload drools binaries and documentation' stage retained for main stream + +import org.jenkinsci.plugins.workflow.libs.Library +@Library('jenkins-pipeline-shared-libraries')_ + +import org.kie.jenkins.MavenCommand + +deployProperties = [:] +pipelineProperties = [:] + +pipeline { + agent { + docker { + image env.AGENT_DOCKER_BUILDER_IMAGE + args env.AGENT_DOCKER_BUILDER_ARGS + label util.avoidFaultyNodes() + } + } + + options { + timestamps() + timeout(time: 180, unit: 'MINUTES') + } + + environment { + DROOLS_CI_EMAIL_TO = credentials("${JENKINS_EMAIL_CREDS_ID}") + } + + stages { + stage('Initialization') { + steps { + script { + cleanWs() + + if (params.DISPLAY_NAME != '') { + currentBuild.displayName = params.DISPLAY_NAME + } + + readDeployProperties() + + assert getProjectVersion() + assert getBuildBranch() == util.getReleaseBranchFromVersion(getProjectVersion()) + } + } + } + + stage('Merge deploy PR') { + // NOTE: tagLatest() removed here intentionally. + // In the 103xplus flow the final release tag is created by the + // separate "Tag final release" stage below, which delegates to + // 05-tag-release.sh so the tag always points to the approved + // RC commit — NOT the current branch tip. Calling tagLatest() + // here would create a duplicate tag at the wrong commit. + steps { + script { + dir(getRepoName()) { + approveAndMergePR(getDeployPrLink()) + checkoutRepo() + } + } + } + } + + stage('Create release') { + steps { + script { + dir(getRepoName()) { + checkoutRepo() + if (githubscm.isReleaseExist(getGitTag(), getGitAuthorCredsId())) { + githubscm.deleteRelease(getGitTag(), getGitAuthorPushCredsId()) + } + githubscm.createReleaseWithGeneratedReleaseNotes(getGitTag(), getBuildBranch(), githubscm.getPreviousTagFromVersion(getGitTag()), getGitAuthorPushCredsId()) + githubscm.updateReleaseBody(getGitTag(), getGitAuthorPushCredsId()) + } + } + } + } + + stage('Tag final release') { + // Delegate final-tag creation to 05-tag-release.sh so the release tag + // always points to the approved RC commit — NOT the current branch tip. + // This matches the documented strategy: the R commit lives under the RC + // tag only; the development branch is never disturbed. + when { + expression { return getGitTag()?.trim() } + } + steps { + withCredentials([ + sshUserPrivateKey(credentialsId: env.GIT_AUTHOR_PUSH_CREDS_ID, keyFileVariable: 'GIT_SSH_KEY') + ]) { + script { + dir(getRepoName()) { + sh """#!/usr/bin/env bash + set -euo pipefail + # Fetch the RC tag so the script can resolve it. + git fetch origin "refs/tags/${getGitTag()}:refs/tags/${getGitTag()}" + chmod +x script/release/05-tag-release.sh + ./script/release/05-tag-release.sh --rc-tag "${getGitTag()}" --push + """ + } + } + } + } + } Review Comment: `05-tag-release.sh` expects an RC tag (e.g. `10.3.0-rc2`) as `--rc-tag`, but `getGitTag()` defaults to `getProjectVersion()` when `params.GIT_TAG` is empty. That default will pass a non-RC tag value (e.g. `10.3.0`) into `--rc-tag`, which will fail or behave incorrectly. Make `GIT_TAG` (or a renamed `RC_TAG`) mandatory for this stage and/or change the getter to avoid defaulting to the project version when the value is specifically used as an RC tag. ########## .ci/jenkins/Jenkinsfile.103xplus.promote: ########## @@ -0,0 +1,293 @@ +/* + * 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. + */ + +// 10.3.x+ promote pipeline — mirrors Jenkinsfile.promote with 10.3+ specifics: +// - 'Create release' stage uses Nexus nexus-staging:release (same as old) +// - 'Tag final release' stage delegates to 05-tag-release.sh (tags the +// approved RC commit, not the branch tip as the old pipeline did) +// - 'Upload drools binaries and documentation' stage retained for main stream + +import org.jenkinsci.plugins.workflow.libs.Library +@Library('jenkins-pipeline-shared-libraries')_ + +import org.kie.jenkins.MavenCommand + +deployProperties = [:] +pipelineProperties = [:] + +pipeline { + agent { + docker { + image env.AGENT_DOCKER_BUILDER_IMAGE + args env.AGENT_DOCKER_BUILDER_ARGS + label util.avoidFaultyNodes() + } + } + + options { + timestamps() + timeout(time: 180, unit: 'MINUTES') + } + + environment { + DROOLS_CI_EMAIL_TO = credentials("${JENKINS_EMAIL_CREDS_ID}") + } + + stages { + stage('Initialization') { + steps { + script { + cleanWs() + + if (params.DISPLAY_NAME != '') { + currentBuild.displayName = params.DISPLAY_NAME + } + + readDeployProperties() + + assert getProjectVersion() + assert getBuildBranch() == util.getReleaseBranchFromVersion(getProjectVersion()) + } + } + } + + stage('Merge deploy PR') { + // NOTE: tagLatest() removed here intentionally. + // In the 103xplus flow the final release tag is created by the + // separate "Tag final release" stage below, which delegates to + // 05-tag-release.sh so the tag always points to the approved + // RC commit — NOT the current branch tip. Calling tagLatest() + // here would create a duplicate tag at the wrong commit. + steps { + script { + dir(getRepoName()) { + approveAndMergePR(getDeployPrLink()) + checkoutRepo() + } + } + } + } + + stage('Create release') { + steps { + script { + dir(getRepoName()) { + checkoutRepo() + if (githubscm.isReleaseExist(getGitTag(), getGitAuthorCredsId())) { + githubscm.deleteRelease(getGitTag(), getGitAuthorPushCredsId()) + } + githubscm.createReleaseWithGeneratedReleaseNotes(getGitTag(), getBuildBranch(), githubscm.getPreviousTagFromVersion(getGitTag()), getGitAuthorPushCredsId()) + githubscm.updateReleaseBody(getGitTag(), getGitAuthorPushCredsId()) + } + } + } + } + + stage('Tag final release') { + // Delegate final-tag creation to 05-tag-release.sh so the release tag + // always points to the approved RC commit — NOT the current branch tip. + // This matches the documented strategy: the R commit lives under the RC + // tag only; the development branch is never disturbed. + when { + expression { return getGitTag()?.trim() } + } + steps { + withCredentials([ + sshUserPrivateKey(credentialsId: env.GIT_AUTHOR_PUSH_CREDS_ID, keyFileVariable: 'GIT_SSH_KEY') + ]) { + script { + dir(getRepoName()) { + sh """#!/usr/bin/env bash + set -euo pipefail + # Fetch the RC tag so the script can resolve it. + git fetch origin "refs/tags/${getGitTag()}:refs/tags/${getGitTag()}" + chmod +x script/release/05-tag-release.sh + ./script/release/05-tag-release.sh --rc-tag "${getGitTag()}" --push + """ + } + } + } Review Comment: Same as the release pipeline: `sshUserPrivateKey(..., keyFileVariable: 'GIT_SSH_KEY')` alone doesn’t ensure `git fetch` / `git push` uses that key. This can break both the `git fetch origin ...` and the `--push` inside `05-tag-release.sh`. Use `sshagent([env.GIT_AUTHOR_PUSH_CREDS_ID])` or set `GIT_SSH_COMMAND` to reference `$GIT_SSH_KEY` within the `sh` block so Git operations are authenticated reliably. ########## .ci/jenkins/project/Jenkinsfile.103xplus.release: ########## @@ -0,0 +1,134 @@ +/* + * 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. + */ + +pipeline { + agent { + label 'ubuntu' + } + + options { + timestamps() + timeout(time: 360, unit: 'MINUTES') + } + + parameters { + string(name: 'RELEASE_VERSION', defaultValue: '10.3.0', description: 'Exact release version, e.g. 10.3.0', trim: true) + string(name: 'TAG_NAME', defaultValue: '10.3.0-rc1', description: 'RC or Release tag name, e.g. 10.3.0-rc1', trim: true) + booleanParam(name: 'SKIP_TESTS', defaultValue: true, description: 'Skip running tests during reactor build') + booleanParam(name: 'DEPLOY', defaultValue: true, description: 'Deploy artifacts to Apache Nexus staging') + string(name: 'STAGING_URL', defaultValue: '', description: 'Custom Nexus staging URL (optional)') + booleanParam(name: 'PUSH_TAG', defaultValue: true, description: 'Push the git tag to origin') + string(name: 'EXTRA_MAVEN_OPTS', defaultValue: '', description: 'Extra Maven CLI options to pass to build.sh') + booleanParam(name: 'DRY_RUN', defaultValue: false, description: 'Dry run without making remote git or staging changes') + booleanParam(name: 'SEND_NOTIFICATION', defaultValue: false, description: 'Send a notification on CI channel when pipeline finishes') + } + + environment { + DROOLS_CI_EMAIL_TO = credentials("${JENKINS_EMAIL_CREDS_ID}") + } + + stages { + stage('Initialize & Validate') { + steps { + script { + assert params.RELEASE_VERSION : 'RELEASE_VERSION parameter is mandatory' + assert params.TAG_NAME : 'TAG_NAME parameter is mandatory' + currentBuild.displayName = "Release ${params.RELEASE_VERSION} (${params.TAG_NAME})" + } + } + } + + stage('Execute Release Scripts') { + steps { + // MAVEN_SETTINGS_CONFIG_FILE_ID is a Jenkins Config File ID, not a + // secret credential — it must be injected via configFileProvider, + // which writes it to a temp path and exposes MAVEN_SETTINGS_FILE. + // GPG_PASSPHRASE_CREDS_ID and GIT_AUTHOR_PUSH_CREDS_ID are real + // credentials and use withCredentials. + configFileProvider([configFile(fileId: env.MAVEN_SETTINGS_CONFIG_FILE_ID, variable: 'MAVEN_SETTINGS_FILE')]) { + withCredentials([ + string(credentialsId: env.GPG_PASSPHRASE_CREDS_ID, variable: 'MAVEN_GPG_PASSPHRASE'), + sshUserPrivateKey(credentialsId: env.GIT_AUTHOR_PUSH_CREDS_ID, keyFileVariable: 'GIT_SSH_KEY') + ]) { + script { + // Configure Git identity for the R commit. + sh """#!/usr/bin/env bash + set -euo pipefail + git config user.email "${env.GIT_AUTHOR_EMAIL ?: '[email protected]'}" + git config user.name "${env.GIT_AUTHOR ?: 'Apache KIE Release Bot'}" + """ + + // Build the argv array safely — each parameter is a + // separate shell word, no string concatenation or eval. + def releaseArgs = [ + './script/release/release-all.sh', + '--version', params.RELEASE_VERSION, + '--tag', params.TAG_NAME + ] + if (params.SKIP_TESTS) releaseArgs << '--skip-tests' + if (params.DEPLOY) releaseArgs << '--deploy' + if (params.STAGING_URL?.trim()) releaseArgs += ['--staging-url', params.STAGING_URL.trim()] + if (params.PUSH_TAG) releaseArgs << '--push-tag' + if (params.EXTRA_MAVEN_OPTS?.trim()) releaseArgs += ['--maven-opts', params.EXTRA_MAVEN_OPTS.trim()] + if (params.DRY_RUN) releaseArgs << '--dry-run' + + // MAVEN_SETTINGS_FILE is injected by configFileProvider above. + // MAVEN_GPG_PASSPHRASE is already in env from withCredentials + // and is read by the GPG plugin directly (not a CLI arg). + withEnv(["MAVEN_SETTINGS=${MAVEN_SETTINGS_FILE}"]) { + sh """#!/usr/bin/env bash + set -euo pipefail + chmod +x script/release/*.sh + ${releaseArgs.collect { "'${it.replace("'", "'\\''")}'" }.join(' ')} + """ Review Comment: The pipeline binds an SSH private key to `GIT_SSH_KEY`, but `git push` inside `release-all.sh`/`02-rc-commit.sh` won’t automatically use that key. As written, `--push-tag` can fail due to missing SSH agent / SSH command configuration. Fix by using `sshagent([env.GIT_AUTHOR_PUSH_CREDS_ID])` around the script execution, or exporting `GIT_SSH_COMMAND=ssh -i \"$GIT_SSH_KEY\" -o IdentitiesOnly=yes` (and any required known_hosts handling) so Git consistently uses the injected key. ########## .ci/jenkins/Jenkinsfile.103xplus.promote: ########## @@ -0,0 +1,293 @@ +/* + * 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. + */ + +// 10.3.x+ promote pipeline — mirrors Jenkinsfile.promote with 10.3+ specifics: +// - 'Create release' stage uses Nexus nexus-staging:release (same as old) +// - 'Tag final release' stage delegates to 05-tag-release.sh (tags the +// approved RC commit, not the branch tip as the old pipeline did) +// - 'Upload drools binaries and documentation' stage retained for main stream + +import org.jenkinsci.plugins.workflow.libs.Library +@Library('jenkins-pipeline-shared-libraries')_ + +import org.kie.jenkins.MavenCommand + +deployProperties = [:] +pipelineProperties = [:] + +pipeline { + agent { + docker { + image env.AGENT_DOCKER_BUILDER_IMAGE + args env.AGENT_DOCKER_BUILDER_ARGS + label util.avoidFaultyNodes() + } + } + + options { + timestamps() + timeout(time: 180, unit: 'MINUTES') + } + + environment { + DROOLS_CI_EMAIL_TO = credentials("${JENKINS_EMAIL_CREDS_ID}") + } + + stages { + stage('Initialization') { + steps { + script { + cleanWs() + + if (params.DISPLAY_NAME != '') { + currentBuild.displayName = params.DISPLAY_NAME + } + + readDeployProperties() + + assert getProjectVersion() + assert getBuildBranch() == util.getReleaseBranchFromVersion(getProjectVersion()) + } + } + } + + stage('Merge deploy PR') { + // NOTE: tagLatest() removed here intentionally. + // In the 103xplus flow the final release tag is created by the + // separate "Tag final release" stage below, which delegates to + // 05-tag-release.sh so the tag always points to the approved + // RC commit — NOT the current branch tip. Calling tagLatest() + // here would create a duplicate tag at the wrong commit. + steps { + script { + dir(getRepoName()) { + approveAndMergePR(getDeployPrLink()) + checkoutRepo() + } + } + } + } + + stage('Create release') { + steps { + script { + dir(getRepoName()) { + checkoutRepo() + if (githubscm.isReleaseExist(getGitTag(), getGitAuthorCredsId())) { + githubscm.deleteRelease(getGitTag(), getGitAuthorPushCredsId()) + } + githubscm.createReleaseWithGeneratedReleaseNotes(getGitTag(), getBuildBranch(), githubscm.getPreviousTagFromVersion(getGitTag()), getGitAuthorPushCredsId()) + githubscm.updateReleaseBody(getGitTag(), getGitAuthorPushCredsId()) + } + } + } + } + + stage('Tag final release') { + // Delegate final-tag creation to 05-tag-release.sh so the release tag + // always points to the approved RC commit — NOT the current branch tip. + // This matches the documented strategy: the R commit lives under the RC + // tag only; the development branch is never disturbed. + when { + expression { return getGitTag()?.trim() } + } + steps { + withCredentials([ + sshUserPrivateKey(credentialsId: env.GIT_AUTHOR_PUSH_CREDS_ID, keyFileVariable: 'GIT_SSH_KEY') + ]) { + script { + dir(getRepoName()) { + sh """#!/usr/bin/env bash + set -euo pipefail + # Fetch the RC tag so the script can resolve it. + git fetch origin "refs/tags/${getGitTag()}:refs/tags/${getGitTag()}" + chmod +x script/release/05-tag-release.sh + ./script/release/05-tag-release.sh --rc-tag "${getGitTag()}" --push + """ + } + } + } + } + } + + stage('Upload drools binaries and documentation') { + when { + expression { return isMainStream() } + } + steps { + script { + configFileProvider([configFile(fileId: env.MAVEN_SETTINGS_CONFIG_FILE_ID, variable: 'MAVEN_SETTINGS_FILE')]) { + getMavenCommand() + .withOptions(env.DROOLS_BUILD_MVN_OPTS ? [ env.DROOLS_BUILD_MVN_OPTS ] : []) + .withOptions(env.BUILD_MVN_OPTS_CURRENT ? [ env.BUILD_MVN_OPTS_CURRENT ] : []) + .inDirectory(getRepoName()) + .skipTests(true) + .withProperty('full') + .withSettingsXmlFile(MAVEN_SETTINGS_FILE) + .run('clean install') + } + uploadFileMgmt(getRepoName()) + } + } + } + } + post { + unsuccessful { + sendNotification() + } + cleanup { + script { + util.cleanNode() + } + } + } +} + +void sendNotification() { + if (params.SEND_NOTIFICATION) { + mailer.sendMarkdownTestSummaryNotification('Promote', "[${getBuildBranch()}] Drools", [env.DROOLS_CI_EMAIL_TO]) + } else { + echo 'No notification sent per configuration' + } +} + +////////////////////////////////////////////////////////////////////////////// +// Deployment properties +////////////////////////////////////////////////////////////////////////////// + +void readDeployProperties() { + String deployUrl = params.DEPLOY_BUILD_URL + if (deployUrl != '') { + if (!deployUrl.endsWith('/')) { + deployUrl += '/' + } + sh "wget ${deployUrl}artifact/${PROPERTIES_FILE_NAME} -O ${PROPERTIES_FILE_NAME}" + deployProperties = readProperties file: PROPERTIES_FILE_NAME + // echo all properties + echo deployProperties.collect { entry -> "${entry.key}=${entry.value}" }.join('\n') + } +} + +boolean hasDeployProperty(String key) { + return deployProperties[key] != null +} + +String getDeployProperty(String key) { + if (hasDeployProperty(key)) { + return deployProperties[key] + } + return '' +} + +String getParamOrDeployProperty(String paramKey, String deployPropertyKey) { + if (params[paramKey] != '') { + return params[paramKey] + } + return getDeployProperty(deployPropertyKey) +} + +////////////////////////////////////////////////////////////////////////////// +// Getter / Setter +////////////////////////////////////////////////////////////////////////////// + +String getRepoName() { + return env.REPO_NAME +} + +String getProjectVersion() { + return getParamOrDeployProperty('PROJECT_VERSION', 'project.version') +} + +String getGitTag() { + return params.GIT_TAG != '' ? params.GIT_TAG : getProjectVersion() Review Comment: `05-tag-release.sh` expects an RC tag (e.g. `10.3.0-rc2`) as `--rc-tag`, but `getGitTag()` defaults to `getProjectVersion()` when `params.GIT_TAG` is empty. That default will pass a non-RC tag value (e.g. `10.3.0`) into `--rc-tag`, which will fail or behave incorrectly. Make `GIT_TAG` (or a renamed `RC_TAG`) mandatory for this stage and/or change the getter to avoid defaulting to the project version when the value is specifically used as an RC tag. ########## script/release/03-build.sh: ########## @@ -0,0 +1,98 @@ +#!/usr/bin/env bash +# +# 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. +# + +set -euo pipefail + +# Builds the Apache KIE repo for a release (skipping tests by default). +# +# Because drools, optaplanner, kogito-runtimes, and kogito-apps now all live in +# the same reactor, a single `mvn clean install` is enough. +# +# Usage: +# ./script/release/03-build.sh [--skip-tests] [--maven-opts <opts>] +# +# Flags: +# --skip-tests Skip all tests (default: tests are run) +# --maven-opts <opts> Extra Maven options appended to the command +# +# Examples: +# ./script/release/03-build.sh --skip-tests +# ./script/release/03-build.sh --skip-tests --maven-opts "-T 4" + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" + +SKIP_TESTS=false +# Extra Maven opts stored as an array so spaces inside individual opts are +# preserved correctly (avoids unquoted word-splitting and command injection). +EXTRA_MVN_OPTS=() Review Comment: The comment claims spaces inside individual opts are preserved, but `read -a` with `IFS=' '` does not honor shell-style quoting. For example, `--maven-opts '-Dfoo=\"a b\"'` will be split into multiple args incorrectly. Either adjust the contract/docs to state quoting isn’t supported, or change the interface to accept repeated `--maven-opt <singleOpt>` flags (so Jenkins/Groovy can pass each option as its own argv token without needing parsing). ########## script/release/upload_filemgmt.sh: ########## @@ -0,0 +1,127 @@ +#!/usr/bin/env bash +# +# 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. +# + +set -euo pipefail + +# Uploads Drools release binaries and documentation to the Apache file +# management server (people.apache.org) via SSH/rsync. +# +# Called by Jenkinsfile.103xplus.promote (and the original Jenkinsfile.promote) +# inside an sshagent('drools-filemgmt') block, so SSH authentication is already +# in the agent — no credential parameters needed here. +# +# Usage: +# ./script/release/upload_filemgmt.sh <release-version> +# +# Examples: +# ./script/release/upload_filemgmt.sh 10.3.0 +# +# Environment variables (all have defaults): +# FILEMGMT_HOST Remote host (default: people.apache.org) +# FILEMGMT_BASE_PATH Remote base path (default: /home/drools/filemgmt) +# DRY_RUN Set to 'true' to print commands without running them + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" + +RELEASE_VERSION="${1:-}" + +if [[ -z "${RELEASE_VERSION}" ]]; then + echo "ERROR: release version argument is required." + echo "Usage: $0 <release-version>" + echo " e.g. $0 10.3.0" + exit 1 +fi + +FILEMGMT_HOST="${FILEMGMT_HOST:-people.apache.org}" +FILEMGMT_BASE_PATH="${FILEMGMT_BASE_PATH:-/home/drools/filemgmt}" +DRY_RUN="${DRY_RUN:-false}" + +# Derive major.minor stream (e.g. 10.3.0 → 10.3) +STREAM="$(echo "${RELEASE_VERSION}" | sed 's/^\([0-9]*\.[0-9]*\)\..*/\1/')" + +REMOTE_BINARIES_DIR="${FILEMGMT_BASE_PATH}/docs_htdocs/drools/release/${STREAM}.x" +REMOTE_DOCS_DIR="${FILEMGMT_BASE_PATH}/docs_htdocs/kogito/release/${STREAM}.x" Review Comment: The script header and Jenkins stage indicate this uploads 'Drools release binaries and documentation', but docs are uploaded under a `kogito` path while binaries go under `drools`. If these docs are meant to be Drools release docs, the remote docs directory should be under the Drools tree as well; if they’re intentionally Kogito docs, then the script name/comments (and Jenkins stage label) should be updated to avoid publishing to the wrong site tree. ########## script/release/upload_filemgmt.sh: ########## @@ -0,0 +1,127 @@ +#!/usr/bin/env bash +# +# 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. +# + +set -euo pipefail + +# Uploads Drools release binaries and documentation to the Apache file +# management server (people.apache.org) via SSH/rsync. Review Comment: The script header and Jenkins stage indicate this uploads 'Drools release binaries and documentation', but docs are uploaded under a `kogito` path while binaries go under `drools`. If these docs are meant to be Drools release docs, the remote docs directory should be under the Drools tree as well; if they’re intentionally Kogito docs, then the script name/comments (and Jenkins stage label) should be updated to avoid publishing to the wrong site tree. ########## script/release/03-build.sh: ########## @@ -0,0 +1,98 @@ +#!/usr/bin/env bash +# +# 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. +# + +set -euo pipefail + +# Builds the Apache KIE repo for a release (skipping tests by default). +# +# Because drools, optaplanner, kogito-runtimes, and kogito-apps now all live in +# the same reactor, a single `mvn clean install` is enough. +# +# Usage: +# ./script/release/03-build.sh [--skip-tests] [--maven-opts <opts>] +# +# Flags: +# --skip-tests Skip all tests (default: tests are run) +# --maven-opts <opts> Extra Maven options appended to the command +# +# Examples: +# ./script/release/03-build.sh --skip-tests +# ./script/release/03-build.sh --skip-tests --maven-opts "-T 4" + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" + +SKIP_TESTS=false +# Extra Maven opts stored as an array so spaces inside individual opts are +# preserved correctly (avoids unquoted word-splitting and command injection). +EXTRA_MVN_OPTS=() + +while [[ $# -gt 0 ]]; do + case $1 in + --skip-tests) + SKIP_TESTS=true + shift + ;; + --maven-opts) + # Accept a single-argument "extra opts" string and split it safely + # into array elements using read. No eval or command substitution. + IFS=' ' read -r -a _extra <<< "${2:-}" + EXTRA_MVN_OPTS+=("${_extra[@]}") + shift 2 Review Comment: The comment claims spaces inside individual opts are preserved, but `read -a` with `IFS=' '` does not honor shell-style quoting. For example, `--maven-opts '-Dfoo=\"a b\"'` will be split into multiple args incorrectly. Either adjust the contract/docs to state quoting isn’t supported, or change the interface to accept repeated `--maven-opt <singleOpt>` flags (so Jenkins/Groovy can pass each option as its own argv token without needing parsing). ########## script/release/05-tag-release.sh: ########## @@ -0,0 +1,129 @@ +#!/usr/bin/env bash +# +# 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. +# + +set -euo pipefail + +# Promotes an approved RC tag to the final release tag (AUTOMATION F). +# +# After the community vote passes on an RC (e.g. 10.3.0-rc2), this script +# creates the final release tag pointing to the same commit: +# +# git tag 10.3.0 10.3.0-rc2 +# +# By default the tag is created locally only. Pass --push to publish it. +# +# Usage: +# ./script/release/05-tag-release.sh --rc-tag <rc-tag> [--push] [--dry-run] +# +# Examples: +# ./script/release/05-tag-release.sh --rc-tag 10.3.0-rc2 +# ./script/release/05-tag-release.sh --rc-tag 10.3.0-rc2 --push + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" + +RC_TAG="" +PUSH=false +DRY_RUN=false + +while [[ $# -gt 0 ]]; do + case $1 in + --rc-tag) + RC_TAG="${2:-}" + shift 2 + ;; + --push) + PUSH=true + shift + ;; + --dry-run) + DRY_RUN=true + shift + ;; + *) + echo "Unknown option: $1" + echo "Usage: $0 --rc-tag <rc-tag> [--push] [--dry-run]" + exit 1 + ;; + esac +done + +if [[ -z "${RC_TAG}" ]]; then + echo "ERROR: --rc-tag is required." + echo "Usage: $0 --rc-tag 10.3.0-rc2 [--push]" + exit 1 +fi + Review Comment: If `--rc-tag` is passed a value that doesn’t end in `-rc<N>` (e.g. `10.3.0`), `RELEASE_TAG` will equal `RC_TAG`, and the later `git tag -a \"${RELEASE_TAG}\" \"${RC_TAG}\" ...` will attempt to create a tag with the same name as an existing one. Add an explicit validation that `RC_TAG` matches the expected `*-rc[0-9]+` format and emit a clear error message if it doesn’t. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
