Skip to content

Jenkins & Vue.js 发布 pipeline

🏷️ Jenkins Vue.js

主要流程是从 git 仓库获取 vue.js 源码,然后使用 Node.jsnpm 命令行打包,最后通过 ssh 发布到线上环境。

配置 Node.js

插件管理 中安装 NodeJS Plugin 插件,之后在 全局工具配置 中新增一个 Node.js 的安装。会在第一次构建 Job 时自动执行这个安装。

groovy
tools {
    nodejs "nodejs"
}

拉取代码

具体方法可以参考 这篇博客2.5 从版本库拉取 pipeline 部分。

groovy
git credentialsId: '3a38c8cc-2a3c-4b8e-b904-c23325397b2c', url: 'https://git-server/group/a-project.git'

安装项目依赖包

通过执行 shell 脚本安装依赖包,其中单独安装 core-js@2.6.5 包是因为出现了 core-js/modules/es6.array.find in ./src/utils/code.js 之类的异常。

groovy
sh '''
npm install --registry=https://registry.npm.taobao.org
npm install core-js@2.6.5 --save --registry=https://registry.npm.taobao.org
'''

发布项目

其中 packagepackage.json 中配置的 scripts ,本质上运行的是 vue-cli-service 命令(vue-cli-service build --dest dist/prod)。

groovy
sh '''npm run package'''

上传到服务器

这里通过 ssh 上传到服务器,需要安装 Publish Over SSH 插件,之后在 系统配置Publish over SSH 部分配置密钥和服务器(其中服务器可以配置多个)。

  • Passphrase:密钥文件的密码,未设置密码可以置空
  • Path to key:密钥文件在 jenkins 服务器上的位置(如:/var/lib/jenkins/a-private-ssh-key.ppk
  • SSH Servers
    • Name:配置的服务器名称,后面脚本中会用到
    • Hostname:服务器地址
    • Username:用户名
    • Remote Directory:默认的远程根目录,上传时的参数路径就是相对于这个目录下的路径

下面是通过 jenkins 自带的 流水线语法 工具生成的示例代码,其功能是将工作目录下的 dist/prod 子目录中的所有文件上传到服务器 Remote Directory 下的 /app/a-application 目录中(不要忘记配置 removePrefix 属性,否则目录结构会不对)。

groovy
sshPublisher(publishers: [sshPublisherDesc(configName: 'ssh-config-name', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/app/a-application', remoteDirectorySDF: false, removePrefix: 'dist/prod', sourceFiles: 'dist/prod/**')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])

完整的 pipeline 示例

下面是完整的发布脚本,以供参考。

groovy
pipeline {
    agent any

    tools {
        nodejs "nodejs"
    }

    stages {
        stage('Pull') {
            steps {
                git credentialsId: '3a38c8cc-2a3c-4b8e-b904-c23325397b2c', url: 'https://git-server/group/a-project.git'
            }
        }

        stage('Install') {
            steps {
                sh '''
                npm install --registry=https://registry.npm.taobao.org
                npm install core-js@2.6.5 --save --registry=https://registry.npm.taobao.org
                '''
            }
        }

        stage('Build') {
            steps {
                script {
                    if (params.env == 'all' || params.env == 'online-test') {
                        sh '''npm run onlinetest'''
                    }

                    if (params.env == 'all' || params.env == 'online-test') {
                        sh '''npm run package'''
                    }
                }
            }
        }

        stage('Upload') {
            steps {
                script {
                    if (params.env == 'all' || params.env == 'online-test') {
                        sshPublisher(publishers: [sshPublisherDesc(configName: 'ssh-config-name', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/app/a-application-test', remoteDirectorySDF: false, removePrefix: 'dist/prod', sourceFiles: 'dist/prod/**')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
                    }
                    if (params.env == 'all' || params.env == 'product') {
                        sshPublisher(publishers: [sshPublisherDesc(configName: 'ssh-config-name', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/app/a-application', remoteDirectorySDF: false, removePrefix: 'dist/prod', sourceFiles: 'dist/prod/**')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
                    }
                }
            }
        }
    }
}