首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多分支pipleline的Jenkins声明管道

多分支pipleline的Jenkins声明管道
EN

Code Review用户
提问于 2019-09-08 20:00:09
回答 1查看 341关注 0票数 2

我正在为一个基于php的项目在jenkins中设置、自动构建和部署作业。我想对我的Jenkinsfile做一些反馈。特别是在并行化方面,(我认为)大量使用sh和站点配置的最佳实践(一堆包含的文件会更好吗?)

代码语言:javascript
复制
#!groovy
//TODO: SSH-steps? https://jenkins.io/blog/2019/02/06/ssh-steps-for-jenkins-pipeline/
//TODO: move some stuff to shared library for ease of use https://jenkins.io/doc/book/pipeline/shared-libraries/
node{
     switch (env.BRANCH_NAME) {
        case "Production":
            echo "Production is not yet implemented"
            //DEPLOY_DIR          = ""

            //SITE_TITLE          = ""
            //SITE_NAME           = ""
            //SITE_FQDN           = ""
            //DEFAULT_FROM_EMAIL  = ""
            //SESSION_NAME        = ""

            //MYSQL_HOSTNAME      = ""
            //MYSQL_DB_NAME       = ""
            //MYSQL_USERNAME      = ""
            //MYSQL_PASSWORD      = ""

            //SSH_SERVER_NAME     = ""
            //SSH_USERNAME        = ""

            break
        case "Development":
        case "development":
            DEPLOY_DIR          = "/var/www/somesite_dev"

            SITE_TITLE          = "blablabla"
            SITE_NAME           = "blablabla.dev.mydomain.dk"
            SITE_FQDN           = "blablabla.dev.mydomain.dk"
            DEFAULT_FROM_EMAIL  = "dev@mydaomain.dk"
            SESSION_NAME        = "TestSession"

            MYSQL_HOSTNAME      = "localhost"
            MYSQL_DB_NAME       = "somedb"
            MYSQL_USERNAME      = "uname"
            MYSQL_PASSWORD      = "p@sswørd" //TODO Move to Jenkins credential management

            SSH_SERVER_NAME     = "ssh.mydomain.dk"
            SSH_USERNAME        = "jenkins"
            break
        case "Test":
            DEPLOY_DIR          = "/var/www/somesite_test"

            SITE_TITLE          = "blablabla"
            SITE_NAME           = "blablabla.test.mydomain.dk"
            SITE_FQDN           = "blablabla.test.mydomain.dk"
            DEFAULT_FROM_EMAIL  = "test@mydaomain.dk"
            SESSION_NAME        = "DevSession"

            MYSQL_HOSTNAME      = "localhost"
            MYSQL_DB_NAME       = "somedb"
            MYSQL_USERNAME      = "uname"
            MYSQL_PASSWORD      = "p@sswørd" //TODO Move to Jenkins credential management

            SSH_SERVER_NAME     = "ssh.mydomain.dk"
            SSH_USERNAME        = "jenkins"
            break
        default:
            echo "$BRANCH_NAME Does not yet have a configuration."
            break
    }   
}
pipeline {
    agent any
    environment {
        SOURCE_DIR="${WORKSPACE}/src"
        BACKUP_FNAME="/tmp/BACKUP-${SITE_NAME}-${(new java.text.SimpleDateFormat("yyyy-MM-dd-HHmm")).format((new Date()))}.tar.gz"
    }
    triggers {
        bitbucketPush()
        pollSCM('') // empty cron expression string
    }

    stages {
        stage ('Staging'){
            environment {
                TEMPLATE_FILE="globals.template.inc.php"
                CONFIG_FILE="globals.inc.php"
            }
            steps {
                echo "Cleanup build artifacts"
                //remove build folder
                sh 'rm -R -f ${WORKSPACE}/build'
                echo "Prepare for build"
                //re-create folders
                sh 'mkdir ${WORKSPACE}/build ${WORKSPACE}/build/api ${WORKSPACE}/build/coverage ${WORKSPACE}/build/logs ${WORKSPACE}/build/pdepend ${WORKSPACE}/build/phpdox'
                echo "Running composer"
                sh "composer install -o -d ${SOURCE_DIR}"
                echo "Building config file ${SOURCE_DIR}/${CONFIG_FILE}"
                script {
                    def inptext = readFile file: "${SOURCE_DIR}/${TEMPLATE_FILE}" 
                    //save deploydate
                    def deployDate = (new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm")).format((new Date()))                    
                    inptext = inptext.replaceAll(~/¤SITE_TITLE¤/, "${SITE_TITLE}")
                    inptext = inptext.replaceAll(~/¤SITE_NAME¤/, "${SITE_NAME}")
                    inptext = inptext.replaceAll(~/¤SITE_FQDN¤/, "${SITE_FQDN}")
                    inptext = inptext.replaceAll(~/¤DEFAULT_FROM_EMAIL¤/, "${DEFAULT_FROM_EMAIL}")
                    inptext = inptext.replaceAll(~/¤SESSION_NAME¤/, "${SESSION_NAME}")
                    inptext = inptext.replaceAll(~/¤MYSQL_HOSTNAME¤/, "${MYSQL_HOSTNAME}")
                    inptext = inptext.replaceAll(~/¤MYSQL_DB_NAME¤/, "${MYSQL_DB_NAME}")
                    inptext = inptext.replaceAll(~/¤MYSQL_USERNAME¤/, "${MYSQL_USERNAME}")
                    inptext = inptext.replaceAll(~/¤MYSQL_PASSWORD¤/, "${MYSQL_PASSWORD}")
                    inptext = inptext.replaceAll(~/¤DEPLOY_DATE¤/, "${deployDate}")
                    inptext = inptext.replaceAll(~/¤GIT_BRANCH¤/, "${env.GIT_BRANCH}")
                    inptext = inptext.replaceAll(~/¤GIT_COMMIT¤/, "${env.GIT_COMMIT}")
                    //inptext = inptext.replaceAll(~/¤GIT_TAG¤/, "${sh(returnStdout: true, script: "git -C . describe --tags").trim()}")
                    writeFile file: "${SOURCE_DIR}/${CONFIG_FILE}", text: inptext
                }
            }
        }
        stage ('Testing, Static Analysis & documenting'){
            parallel {
                stage ("Count LOC"){
                    steps {
                        //    echo "Running Lint"
                        //    sh "find . -path ./src/vendor -prune -o -type f -name '*.php' -print0 | xargs -0 -n1 -P4 php -l -n | (! grep -v \"No syntax errors detected\" )"
                        echo "Running phploc"
                        sh "./src/vendor/phploc/phploc/phploc --exclude=./src/vendor --no-interaction --quiet --log-csv=./build/logs/loc.csv src tests"

                        echo "Running sloc"
                        sh "sloccount --duplicates --wide --details . > ./build/logs/sloccount.sc  2>/dev/null"
                    }
                }
                stage ("Copy-Paste Detection"){
                    steps{
                        echo "Running copy-paste detection"
                        sh "./src/vendor/sebastian/phpcpd/phpcpd --fuzzy . --exclude src/vendor --log-pmd ./build/logs/phpcpd.xml || true"
                    }
                }
                stage ("Mess Detection"){
                    steps{
                        echo "Running mess detection on code"
                        sh "./src/vendor/phpmd/phpmd/src/bin/phpmd src xml phpmd_ruleset.xml --reportfile ./build/logs/phpmd_code.xml --exclude vendor,build --ignore-violations-on-exit --suffixes php"
                        //echo "Running mess detection on tests"
                        //sh "./src/vendor/phpmd/phpmd/src/bin/phpmd tests xml codesize,cleancode,unusedcode,naming --reportfile ./build/logs/phpmd_tests.xml --suffixes php"
                    }
                }
                stage ("Testing"){
                    steps{
                        echo "Running PHPUnit w/o code coverage"
                        sh "./src/vendor/phpunit/phpunit/phpunit --configuration phpunit-quick.xml" 
                    }
                }
                //echo "Running PHP Codesniffer"
                //sh "phpcs --report=checkstyle --report-file=./build/logs/checkstyle.xml --standard=PSR2 --extensions=php --ignore=autoload.php ./src ./tests"

                //TODO: phpdox 

                // TODO: set up reporting
                // https://wiki.jenkins.io/display/JENKINS/Plot+Plugin
                // https://stackoverflow.com/a/48001251/1725871
            }
        }
        stage ("Deploy") {
            environment {
                SSH_TUNNEL_PORT=3309
            }
            parallel {
                stage ("Deploy code") {
                    agent any
                    steps {
                        echo "Deploying via SSH  on ${SSH_SERVER_NAME}:${DEPLOY_DIR}"
                        //TODO: rename backup file
                        sh "ssh ${SSH_USERNAME}@${SSH_SERVER_NAME} tar -cvpzf ${BACKUP_FNAME} ${DEPLOY_DIR}/* "
                        sh "ssh ${SSH_USERNAME}@${SSH_SERVER_NAME} rm -R -f ${DEPLOY_DIR}/*"
                        sh "scp -rpC ${SOURCE_DIR}/* ${SSH_USERNAME}@${SSH_SERVER_NAME}:${DEPLOY_DIR}"
                        //TODO: delete backup on success
                    }
                }
                stage ("Deploy DB changes") {
                    agent any //liquibase
                    steps {
                        echo "Create SSH tunnel"
                        sh "ssh -M -S deploy-control-socket -fnNT -L ${SSH_TUNNEL_PORT}:localhost:3306 ${SSH_USERNAME}@${SSH_SERVER_NAME}"

                        echo "Check tunnel"
                        sh "ssh -S deploy-control-socket -O check ${SSH_USERNAME}@${SSH_SERVER_NAME}"

                        echo "Sync liquibase"
                        sh "liquibase --driver=com.mysql.cj.jdbc.Driver --changeLogFile=${WORKSPACE}/resources/database/db.changelog-1.1.xml --url=\"jdbc:mysql://127.0.0.1:${SSH_TUNNEL_PORT}/${MYSQL_DB_NAME}?autoReconnect=true&useSSL=false&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC\" --username=${MYSQL_USERNAME} --password=${MYSQL_PASSWORD} update"

                        echo "Close SSH tunnel to ${SSH_SERVER_NAME}"
                        sh "ssh -S deploy-control-socket -O exit ${SSH_USERNAME}@${SSH_SERVER_NAME}"
                    }
                }
            }
        }
    }
    post {
        always {
            //archiveArtifacts artifacts: 'build/libs/**/*.jar', fingerprint: true
            junit "build/logs/junit.xml"

            sloccountPublish encoding: '', pattern: ''
            // warnings-ng https://github.com/jenkinsci/warnings-ng-plugin/blob/master/doc/Documentation.md
            recordIssues enabledForFailure: true, tool: cpd(pattern: 'build/logs/phpcpd.xml')
            recordIssues enabledForFailure: true, tool: pmdParser(pattern: 'build/logs/phpmd_code.xml')
        }
        //https://jenkins.io/doc/pipeline/tour/post/
        success {
            echo 'Successful build. Well done'
        }
        unstable {
            echo 'Unstable Build. Check test cases'
        }
        failure {
            echo 'I failed :('
        }
        changed {
            echo 'Things were different before...'
        }
    }
}  
EN

回答 1

Code Review用户

发布于 2019-09-22 19:26:01

我在备份和复制部分发现了一个固有的缺陷。即

代码语言:javascript
复制
sh "ssh ${SSH_USERNAME}@${SSH_SERVER_NAME} tar -cvpzf ${BACKUP_FNAME} ${DEPLOY_DIR}/*"
sh "ssh ${SSH_USERNAME}@${SSH_SERVER_NAME} rm -R -f ${DEPLOY_DIR}/*"

,它与本地mashine和https://stackoverflow.com/questions/22222838/shell-script-calling-ssh-how-to-interpret-wildcard-on-remote-server上的星号相同。

焦油的解决方案很简单:

代码语言:javascript
复制
sh "ssh ${SSH_USERNAME}@${SSH_SERVER_NAME} tar -cvpzf ${BACKUP_FNAME} ${DEPLOY_DIR}"

rm的解决方案更加困难。我已经考虑过ssh步骤插件,但我希望在我尝试之前能更好地确定它是否能工作.

现在,我正在查看设置了rsync标志的--DELETE

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/227689

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档