znt/misc/ci/Jenkinsfile

660 lines
24 KiB
Groovy
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

library 'z-common@feat-241129'
library 'z-zentaopms@feat-241129'
pipeline {
agent {
kubernetes {
inheritFrom "xuanim"
yamlFile 'misc/ci/normal.yaml'
}
}
options {
skipDefaultCheckout()
parallelsAlwaysFailFast()
overrideIndexTriggers(false)
quietPeriod 900
}
parameters {
separator(name: "action", sectionHeader: "构建动作")
choice choices: ['auto', 'snapshot', 'release'], description: '构建包类型(快照或发版)', name: 'build_kind'
string defaultValue: "open,biz,max,ipd", description: '发布产品', name: 'publish_exts', trim: true
booleanParam defaultValue: true, description: '构建源码', name: 'source_build'
booleanParam defaultValue: true, description: '构建一键安装包', name: 'publish_zbox'
booleanParam defaultValue: true, description: '构建镜像', name: 'publish_image'
separator(name: "replay", sectionHeader: "仓库切换")
string description: '指定一个构建Id用于回放', name: 'REPLAY_ID', trim: true
string description: '指定企业版分支, 也可以是 tag 或者 commit', name: 'zentaoext_version', trim: true
string description: '指定旗舰版分支, 也可以是 tag 或者 commit', name: 'zentaomax_version', trim: true
string description: '指定IPD版分支, 也可以是 tag 或者 commit', name: 'zentaoipd_version', trim: true
string description: '指定喧喧分支', name: 'xuanxuan_version', trim: true
string description: '指定开源版全量降级 revision', name: 'fulldown_pms_version', trim: true
string description: '指定收费版全量降级 revision', name: 'fulldown_ext_version', trim: true
separator(name: "other", sectionHeader: "其它")
booleanParam defaultValue: true, description: '制作英文版', name: 'publish_en'
booleanParam defaultValue: false, description: '调试模式', name: 'DEBUG'
booleanParam defaultValue: true, description: '是否删除测试脚本', name: 'delete_test'
}
environment {
TZ="Asia/Shanghai"
GIT_HTTP_USER_AGENT="gitfox/pipeline"
ZENTAO_RELEASE_PATH = "${WORKSPACE}/release"
XUANXUAN_SRC_PATH = "${WORKSPACE}/xuansrc"
SRC_ZDOO_PATH = "${WORKSPACE}/zdoo"
SRC_ZDOOEXT_PATH = "${WORKSPACE}/zdooext"
SRC_ZENTAOEXT_PATH = "${WORKSPACE}/zentaoext"
MIRROR = "true"
// 默认从job参数里读取打开后覆盖
PUBLISH_ZIP = "${params.publish_zip}"
PUBLISH_IMAGE = "${params.publish_image}"
PUBLISH_ZBOX = "${params.publish_zbox}"
PUBLISH_ENGLISH = "${params.publish_en}"
DELETE_TEST = "${params.delete_test}"
}
stages {
stage("Basic Build") {
when {
anyOf {
buildingTag()
not {
triggeredBy 'BranchEventCause'
}
}
}
agent {
kubernetes {
inheritFrom "zentao-package-test build-docker xuanim"
yamlFile 'misc/ci/basic-build.yaml'
}
}
stages {
stage("Pull pms") {
steps {
checkout scm
script {
def triggeredBy = currentBuild.getBuildCauses()
println "Build triggered by: ${triggeredBy}"
env.GIT_URL = sh(returnStdout: true, script: 'git config --get remote.origin.url').trim()
env.GIT_COMMIT = sh(returnStdout: true, script: 'git rev-parse HEAD').trim()
def j = job.newJob()
env.GIT_BRANCH = j.getBranchById(env.GIT_COMMIT)
zentaopms.setupStaticEnv()
zentaopms.setupEnvAfterCheckout()
zCheckout([
[name: "xuansrc", subDir: true, url: "https://${env.GITFOX_HOST}/git/xuan/xuanxuan.git", credentialsId: "gitfox-zcorp-cc-ci-robot", branchs: ["${params.xuanxuan_version}", j.getReplaySHA("xuanxuan"), "${env.XUANVERSION}"] ],
[name: "zentaoext", subDir: true, url: "https://${env.GITFOX_HOST}/git/${env.ZENTAOEXT_GIT_REPO}.git", credentialsId: "gitfox-zcorp-cc-ci-robot", branchs: ["${params.zentaoext_version}", j.getReplaySHA("zentaoext"), "${env.ZENTAOEXT_VERSION}", "${env.GIT_BRANCH}"] ],
[name: "zentaomax", subDir: true, url: "https://${env.GITFOX_HOST}/git/zentao/zentaomax.git", credentialsId: "gitfox-zcorp-cc-ci-robot", branchs: ["${params.zentaomax_version}", j.getReplaySHA("zentaomax"), "${env.ZENTAOMAX_VERSION}", "${env.GIT_BRANCH}"] ],
[name: "zentaoipd", subDir: true, url: "https://${env.GITFOX_HOST}/git/zentao/zentaoipd.git", credentialsId: "gitfox-zcorp-cc-ci-robot", branchs: ["${params.zentaoipd_version}", j.getReplaySHA("zentaoipd"), "${env.ZENTAOIPD_VERSION}", "${env.GIT_BRANCH}"] ],
[name: "downRepo", subDir: true, url: "https://${env.GITFOX_HOST}/git/${env.DOWNGRADE_GIT_REPO}.git", credentialsId: "gitfox-zcorp-cc-ci-robot", branchs: ["${params.fulldown_pms_version}", j.getReplaySHA("${env.DOWNGRADE_GIT_REPO}"), "downgrade/${env.GIT_BRANCH}/src"] ],
[name: "downRepoExt", subDir: true, url: "https://${env.GITFOX_HOST}/git/${env.DOWNGRADE_EXT_GIT_REPO}.git", credentialsId: "gitfox-zcorp-cc-ci-robot", branchs: ["${params.fulldown_ext_version}", j.getReplaySHA("${env.DOWNGRADE_EXT_GIT_REPO}"), "downgrade/${env.GIT_BRANCH}/src"] ]
])
zentaopms.setupEnvAfterCheckoutExt()
stash includes: 'misc/*.php', name: 'misc'
}
}
}
stage("Setup Global Env") {
steps {
sh 'env'
script {
def j = job.newJob()
j.SaveHeadReport('./.head.md')
// send start msg
def mdPath = "start.md"
j.SaveStartReport(mdPath)
ximNotify(title: "开始构建禅道", contentFile: mdPath, contentHeaderFile: './.head.md')
}
}
}
stage("Build") {
when { expression { return params.source_build } }
stages {
stage("make ciCommon") {
steps {
withCredentials([gitUsernamePassword(credentialsId: 'git-jenkins-bot-http',gitToolName: 'git-tool')]) {
container('package') {
sh 'mkdir -pv ${ZENTAO_RELEASE_PATH} && chown 1000:1000 ${ZENTAO_RELEASE_PATH}'
sh 'git config --global pull.ff only'
sh 'git config --global --add safe.directory $PWD/xuansrc'
sh 'git config --global --add safe.directory $PWD/zentaoext'
sh 'git config --global --add safe.directory $PWD/downRepo'
sh 'git config --global --add safe.directory $PWD/downRepoExt'
sh 'test -d $PWD/zentaoext/zentaomax && rm -rf $PWD/zentaoext/zentaomax'
sh 'test -d $PWD/zentaoext/zentaoipd && rm -rf $PWD/zentaoext/zentaoipd'
sh 'mv $PWD/zentaomax $PWD/zentaoext/'
sh 'mv $PWD/zentaoipd $PWD/zentaoext/'
sh 'git config --global --add safe.directory $PWD/zentaoext/zentaomax'
sh 'git config --global --add safe.directory $PWD/zentaoext/zentaoipd'
// sh 'cp -av ${ZENTAO_BUILD_PATH}/adminer www/'
sh 'pwd && ls -l && make ciCommon'
}
}
}
}
stage("增量降级") {
steps {
container('package') {
echo "GIT_BRANCH in jenkinsfile is ${env.GIT_BRANCH}"
sh 'rm -rf $PWD/zentaopms/lib/vendor/rector'
sh '${ZENTAO_BUILD_PATH}/script/downgrade/diffDowngrade.sh -c $PWD/misc -r $PWD/zentaopms -b ${GIT_BRANCH} -d downRepo -i -s -o "$ZENTAO_RELEASE_PATH" -p "$DOWNGRADE_VERSIONS" api extension framework lib module/*'
sh 'test ! -f ${ZENTAO_RELEASE_PATH}/downgradeReport.html'
}
}
post {
failure {
script { downgrade.increaseErrReport() }
}
}
}
stage("zentaoext") {
stages {
stage("基础包") {
steps {
container('package') {
sh 'cd $SRC_ZENTAOEXT_PATH && make build'
}
}
}
stage("降级") {
steps {
container('package') {
sh '${ZENTAO_BUILD_PATH}/script/downgrade/diffDowngrade.sh -c $PWD/misc -r $ZENTAO_BUILD_PATH/zentaoext -b ${GIT_BRANCH} -d downRepoExt -i -s -m -n zentaoext -o "$ZENTAO_BUILD_PATH" -p $DOWNGRADE_VERSIONS'
sh 'cd $SRC_ZENTAOEXT_PATH && make merge-source-all'
}
}
}
stage("加密合并") {
steps {
container('package') {
sh 'cd $SRC_ZENTAOEXT_PATH && make encrypt-all'
sh 'cd $SRC_ZENTAOEXT_PATH && make merge-encrypt-all'
}
}
}
stage("xuan") {
steps {
container('package') {
sh 'cd $SRC_ZENTAOEXT_PATH && make xuan'
sh 'cd $SRC_ZENTAOEXT_PATH && make encrypt-xuan UUID=`uuidgen`'
}
}
}
}
}
stage("中转") {
steps {
container('package') {
sh 'ls -l ${ZENTAO_BUILD_PATH}'
sh 'ls -l ${ZENTAO_RELEASE_PATH}'
sh 'cp ${ZENTAO_BUILD_PATH}/zentao*.zip ./'
sh 'cp ${ZENTAO_BUILD_PATH}/docker/Dockerfile.release.ext ./Dockerfile.release.ext'
}
container('docker') {
sh 'docker build --pull -t ${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG} -f Dockerfile.release.ext ${ZENTAO_RELEASE_PATH}'
sh 'docker push ${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}'
}
script {
// 仅制作开源版时不上传收费版相关源码
if (params.publish_exts!="open") {
buildPkg.uploadSource("php8.1", ["php0.0", "php8.4", "php8.1", "php7.0", "php7.1", "php7.2_7.4"])
}
}
}
}
}
} // End Build
}
}
stage("Publish") {
environment {
OUTPUT_PKG_PATH = "${ZENTAO_RELEASE_PATH}/output"
}
stages {
stage("Merge and Upload") {
when { expression { return params.source_build } }
matrix {
agent {
kubernetes {
containerTemplate {
name "package"
image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}"
command "sleep"
args "99d"
}
yamlFile 'misc/ci/publish-zip.yaml'
}
}
options {
skipDefaultCheckout()
}
axes {
axis {
name "ZLANG"
values "cn", "en"
}
axis {
name "PHPVERSION"
values "php7.0", "php7.1", "php7.2_7.4", "k8s.php7.2_7.4", "php8.1", "k8s.php8.1", "php8.4"
}
}
excludes {
exclude {
axis {
name 'ZLANG'
values 'en'
}
axis {
name "PHPVERSION"
values "k8s.php7.2_7.4", "k8s.php8.1"
}
}
}
stages {
stage("ZIP") {
when {
anyOf {
environment name: 'ZLANG', value: 'cn'
expression { return env.ZLANG=="en" && env.PUBLISH_ENGLISH=="true" }
}
}
environment {
ARTIFACT_NAME = """${sh(
returnStdout: true,
script: 'test ${ZLANG} = cn && echo -n zentao || echo -n ZenTaoALM'
).trim()}"""
INT_FLAG = """${sh(
returnStdout: true,
script: 'test ${ZLANG} = cn && echo -n "int." || echo -n ""'
).trim()}"""
}
stages {
stage("package zip") {
steps{
echo "${env.ZLANG} <=> ${env.PHPVERSION}"
container('package') {
sh 'mkdir $ZENTAO_RELEASE_PATH'
sh '${ZENTAO_BUILD_PATH}/package.sh zip'
sh 'mkdir $OUTPUT_PKG_PATH'
}
}
}
stage("upload zip") {
steps {
sh 'mkdir ${OUTPUT_PKG_PATH}/${ZT_PMS_MAIN_VERSION}'
sh 'cp ${ZENTAO_RELEASE_PATH}/base.zip ${OUTPUT_PKG_PATH}/${ZT_PMS_MAIN_VERSION}/${ARTIFACT_NAME}-${PMS_VERSION}-${PHPVERSION}.zip'
// sh 'cp ${ZENTAO_RELEASE_PATH}/base.tar.xz ${OUTPUT_PKG_PATH}/${ZT_PMS_MAIN_VERSION}/${ARTIFACT_NAME}-${PMS_VERSION}-${PHPVERSION}.tar.xz'
script {
buildPkg.uploadPMS(env.PHPVERSION)
buildPkg.doUploadExt()
}
}
} // End upload zip
stage("syspack") {
when {
environment name: 'BUILD_KIND', value: 'release'
}
steps{
script {
buildPkg.buildRpmAndDeb()
}
}
}
} // end stages
} // end stage frame
} // End matrix stages
} // End matrix
} // End Merge and Upload Max
stage("Notice ZIP") {
when { expression { return params.source_build } }
steps {
checkout scmGit(branches: [[name: "main"]],
extensions: [cloneOption(depth: 2, noTags: false, reference: '', shallow: true)],
userRemoteConfigs: [[credentialsId: 'gitfox-zcorp-cc-ci-robot', url: "https://${env.GITFOX_HOST}/git/ci/zentao-package.git"]]
)
container('xuanimbot') {
sh './gen_build_report.sh > success.md'
}
script {
def j = job.newJob()
j.SaveHeadReport('./.head.md')
ximNotify(title: "禅道源码包构建成功", contentFile: "success.md", contentHeaderFile: './.head.md')
}
}
}
stage("Zbox") {
when { expression { return params.publish_zbox } }
environment {
// printf "$PKG_URL_FORMATTER" pmsPack ZenTaoPMS 18.5 ZenTaoPMS-18.5-php8.1.zip
PKG_URL_FORMATTER = """${sh(
returnStdout: true,
script: "echo ${ARTIFACT_PROTOCOL}://${ARTIFACT_HOST}/repository/${ARTIFACT_REPOSITORY}/zentao/%s/`echo ${ARTIFACT_SUBGROUP} | tr . /`/%s/%s/%s"
).trim()}"""
}
stages {
stage("Package") {
parallel {
stage("Zbox win") {
agent {
kubernetes {
inheritFrom "code-sign"
yamlFile 'misc/ci/publish-zbox.yaml'
}
}
stages() {
stage("Prepare") {
steps {
checkout scmGit(branches: [[name: "main"]],
extensions: [cloneOption(depth: 2, noTags: false, reference: '', shallow: true)],
userRemoteConfigs: [[credentialsId: 'gitfox-zcorp-cc-ci-robot', url: "https://${env.GITFOX_HOST}/git/ci/zbox-builder.git"]]
)
unstash 'misc'
}
}
stage("Build") {
steps {
withCredentials([string(credentialsId: 'osslsigncode-cert', variable: 'CODE_SIGN_CERT')]) {
container('osslsigncode') {
sh 'echo -ne $CODE_SIGN_CERT | base64 -d > .codesign.p12'
}
}
script {
buildZboxWin.doBuild()
buildZboxWin.doUploadInternal()
}
}
}
}
} // End Zbox win
stage("Zbox linux") {
agent {
kubernetes {
yamlFile 'misc/ci/publish-zbox.yaml'
}
}
stages() {
stage("Prepare") {
steps {
checkout scmGit(branches: [[name: "main"]],
extensions: [cloneOption(depth: 2, noTags: false, reference: '', shallow: true)],
userRemoteConfigs: [[credentialsId: 'gitfox-zcorp-cc-ci-robot', url: "https://${env.GITFOX_HOST}/git/ci/zbox-builder.git"]]
)
unstash 'misc'
}
}
stage("Build") {
steps {
script {
buildZboxLinux.doBuild()
// buildZboxLinux.test()
buildZboxLinux.doUploadInternal()
}
}
}
}
} // End Zbox linux
stage("制作tar.xz包") {
when {
environment name: 'BUILD_KIND', value: 'release'
}
agent {
kubernetes {
inheritFrom "zentao-package"
yamlFile 'misc/ci/publish-zbox.yaml'
}
}
steps {
container('package') {
sh 'mkdir -p $OUTPUT_PKG_PATH'
}
script {
buildPkg.doConvertTarXz()
}
}
}
} // End parallel
}
stage("Notice zbox") {
steps {
checkout scmGit(branches: [[name: "main"]],
extensions: [cloneOption(depth: 2, noTags: false, reference: '', shallow: true)],
userRemoteConfigs: [[credentialsId: 'gitfox-zcorp-cc-ci-robot', url: "https://${env.GITFOX_HOST}/git/ci/zbox-builder.git"]]
)
sh 'script/lib/gen_report.sh > zbox-success.md'
script {
def j = job.newJob()
j.SaveHeadReport('./.head.md')
ximNotify(title: "禅道一键安装包构建成功", contentFile: "zbox-success.md", contentHeaderFile: './.head.md')
}
}
}
}
} // End Zbox
stage("Docker Image") {
when { expression { return params.publish_image } }
agent {
kubernetes {
inheritFrom "dind2 xuanim"
yamlFile 'misc/ci/publish-image.yaml'
}
}
environment {
CI_BUILD_PUBLIC_IMAGE="true"
PKG_URL_FORMATTER = """${sh(
returnStdout: true,
script: "echo ${ARTIFACT_PROTOCOL}://${ARTIFACT_HOST}/repository/${ARTIFACT_REPOSITORY}/zentao/%s/`echo ${ARTIFACT_SUBGROUP} | tr . /`/%s/%s/%s"
).trim()}"""
INSTALL_GOSS_TOOLS="true"
DEBUG="0" // set to int for dgoss
CNE_API_TOKEN = credentials('demo-zentaopass-cne-token')
}
steps {
checkout scmGit(branches: [[name: "main"]],
extensions: [cloneOption(depth: 2, noTags: false, reference: '', shallow: true)],
userRemoteConfigs: [[credentialsId: 'gitfox-zcorp-cc-ci-robot', url: "https://${env.GITFOX_HOST}/git/app/zentao.git"]]
)
script {
dockerBuildx(host=env.REGISTRY_HOST, credentialsId=env.DOCKER_CREDENTIALS_ID) {
stage("prepare") {
sh "apk --no-cache add curl make bash jq git tzdata"
sh "make markdown-init"
}
stage("docker build") {
if (env.PUBLISH_OPEN=="true") {
sh 'make build'
sh 'make test-open'
sh 'make build74'
sh 'make test74-open'
}
if (env.PUBLISH_BIZ=="true") {
sh 'make build-biz'
sh 'make test-biz'
sh 'make test-biz-k8s'
sh 'make build-biz-k8s'
sh 'make build74-biz'
sh 'make test74-biz'
sh 'make test74-biz-k8s'
sh 'make build74-biz-k8s'
}
if (env.PUBLISH_MAX=="true") {
sh 'make test-max'
sh 'make build-max'
sh 'make test-max-k8s'
sh 'make build-max-k8s'
sh 'make test74-max'
sh 'make build74-max'
sh 'make test74-max-k8s'
sh 'make build74-max-k8s'
}
if (env.PUBLISH_IPD=="true") {
sh 'make test-ipd'
sh 'make build-ipd'
sh 'make test-ipd-k8s'
sh 'make build-ipd-k8s'
sh 'make test74-ipd'
sh 'make build74-ipd'
sh 'make test74-ipd-k8s'
sh 'make build74-ipd-k8s'
}
sh 'make markdown-render > ./report.md'
}
}
}
script {
def j = job.newJob()
j.SaveHeadReport('./.head.md')
ximNotify(title: "禅道镜像构建成功", contentFile: "report.md", contentHeaderFile: './.head.md')
// if (env.BUILD_KIND=='release') {
// stage("离线镜像包") {
// offlineImage.save()
// offlineImage.release()
// }
// }
if (env.DEPLOY_ZENTAOPAAS=='true') {
deploy.upgradePaas(env.ZENTAOPAAS_SERVER, env.CNE_API_TOKEN)
ximNotify(title: "禅道平台版DEMO部署成功", content: "访问地址 ["+env.ZENTAOPAAS_SERVER+"]("+env.ZENTAOPAAS_SERVER+")")
}
}
}
} // End Docker Image
stage("Push Version") {
when { environment name:'BUILD_KIND', value:'release' }
steps {
checkout scmGit(branches: [[name: "main"]],
extensions: [cloneOption(depth: 2, noTags: false, reference: '', shallow: true)],
userRemoteConfigs: [[credentialsId: 'gitfox-zcorp-cc-ci-robot', url: "https://${env.GITFOX_HOST}/git/ci/zentao-package.git"]]
)
container('xuanimbot') {
sh './script/push_zentao_version.sh'
}
}
}
stage("Upload rongpm") {
agent {
kubernetes {
inheritFrom "zentao-package-test xuanim"
yamlFile 'misc/ci/normal.yaml'
}
}
when {
allOf {
environment name:'BUILD_KIND', value:'release'
}
beforeAgent true
}
steps {
script {
checkout scmGit(branches: [[name: "main"]],
extensions: [cloneOption(depth: 2, noTags: false, reference: '', shallow: true)],
userRemoteConfigs: [[credentialsId: 'gitfox-zcorp-cc-ci-robot', url: "https://${env.GITFOX_HOST}/git/web/rongpm.git"]]
)
container('package') {
sh 'mkdir -p output/rongpm/${PMS_VERSION}'
sh 'cd output/rongpm/${PMS_VERSION} && php7.2 $WORKSPACE/system/bin/buildpractice.php && rm -rf rongpm'
}
}
}
} // End Upload rongpm
}
} // end publish
}
post {
failure {
ximNotify(title: "禅道构建失败", content: "请点击查看详情")
}
}
}