跳转至

Jenkins-整合-前端项目

前端项目构建流程
image-20240731154951331

找到开源项目做测试(分离前端代码)

RuoYi-Cloud 是一个 Java EE 分布式微服务架构平台,基于经典技术组合(Spring Boot、Spring Cloud & Alibaba、Vue、Element),内置模块如:部门管理、角色用户、菜单及按钮授权、数据权限、系统参数、日志管理、代码生成等。在线定时任务配置;支持集群,支持多数据源。

https://doc.ruoyi.vip/ruoyi-cloud/

拉取 ruoyi-cloud 项目代码

拉取 ruoyi 代码
git clone https://gitee.com/y_project/RuoYi-Cloud

Gitea 配置

创建前端仓库

创建前端仓库
image-20240731113717898

将仓库 clone 到本地

git clone git@<host>.com:test/ruoyi-ui.git && cd ruoyi-ui

添加 ruoyi 前端代码和编写 Jenkinsfile

切换 dev 分支,并推送代码
git checkcout -b dev-1
cp -r ../RuoYi-Cloud/ruoyi-ui/. .
vim Jenkinsfile
编写 Jenkinsfile 文件
properties([
    parameters ([
        choice(name: 'service_name', choices: ['ruoyi'], description: '部署项目集名称,必须使用小写'),
        choice(name: 'serviceStack', choices: ['fe'], description: '部署项目的前端标识'),
        string(name: 'TAG_NAME', defaultValue: '', description:'tag 发布线上必填参数,格式v24.1.1(v主版本号.次版本号.补丁版本号)')
    ])
])

pipeline {

    agent any

    environment {
        // harbor 相关信息
        harbor_docker_host=credentials('harbor_docker_host') // harbor 镜像仓库地址
        harbor_docker_name=credentials('harbor_docker_name') // harbor 镜像仓库用户名
        harbor_docker_passwd=credentials('harbor_docker_passwd') // harbor 镜像仓库密钥

        // 触发 Jenkins 部署任务密钥
        deploy_datarc_token=credentials('deploy_datarc_token') 

        // sonar 相关信息
        SonarQube_HOST=credentials('SonarQube_HOST') // sonar 地址
        SonarQube_TOKEN=credentials('SonarQube_TOKEN') // sonar 认证密钥
    }

    stages {


        stage('=== 检测是否为生产环境标签,设置 TAG_NAME ===') {
            // 定义步骤
            steps {
                script {
                    // 检查 TAG_NAME 是否为正式环境匹配正则表达式,如果不是则设置 TAG_NAME = BRANCH_NAME (系统参数)
                    if (!params.TAG_NAME || !(params.TAG_NAME =~ /^v.*/)) {
                    env.TAG_NAME = BRANCH_NAME
                    // BRANCH_NAME 分支名称(系统参数)
                    }
                }
            }
        }

        stage('=== 打印构建信息===') {
            // 定义步骤
            steps {
                script {
                    // 输出当前分支名或标签名
                    echo "发布服务为 ${service_name}, 发布 ${serviceStack} 代码, 发布分支为 ${BRANCH_NAME},服务标签为 ${TAG_NAME}"
                }
            }
        }


        stage('=== 安装依赖 ===') {
            when {
                anyOf {
                    branch "dev"
                    branch "rc"
                    expression{ return params.TAG_NAME =~ /v.*/ }
                }
            }
            steps {
                sh 'npm install --registry=https://registry.npmmirror.com'
            }
        }

        stage('=== 代码编译 ===') {
            when {
                anyOf {
                    branch "dev"
                    branch "rc"
                    expression{ return params.TAG_NAME =~ /v.*/ }

                }
            }
            steps {
                sh 'npm run build:prod'
                // 检查构建是否成功,可以根据输出或文件是否存在进行判断
                script {
                    def buildSuccess = fileExists('dist/') // 假设构建产物在 dist 目录下
                    if (!buildSuccess) {
                        error 'Build failed, no production files found.'
                    }
                }
            }
        }


        stage('=== 检测代码质量 ===') {
            when {
                anyOf {
                    branch "dev"
                    branch "rc"
                    expression{ return params.TAG_NAME =~ /v.*/ }
                }
            }
            steps {
                sh '/usr/local/sonar/bin/sonar-scanner -Dsonar.host.url=${SonarQube_HOST}  -Dsonar.sources=./ -Dsonar.projectname=${service_name}-${serviceStack} -Dsonar.projectKey=${service_name}-${serviceStack} -Dsonar.java.binaries=target/classes -Dsonar.java.test.binaries=target/test-classes -Dsonar.java.surefire.report=target/surefire-reports -Dsonar.token=${SonarQube_TOKEN} -Dsonar.sourceEncoding=UTF-8 -Dsonar.branch.name=${TAG_NAME}'
            }
        }

        stage('=== Docker 镜像构建 ===') {
            when {
                anyOf {
                    branch "dev"
                    branch "rc"
                    expression{ return params.TAG_NAME =~ /v.*/ }
                }
            }
            steps {
                // 构建 Docker 镜像
                sh 'docker build -t datarc:latest .'
            }
        }


        stage('=== Docker 镜像上传 ===') {
            when {
                anyOf {
                    branch "dev"
                    branch "rc"
                    expression{ return params.TAG_NAME =~ /v.*/ }
                }
            }
            steps {
                // ${harbor_docker_host}/${service_name}/${service_name}-${serviceStack}:${TAG_NAME}
                sh 'echo "${harbor_docker_passwd}" | docker login ${harbor_docker_host}  -u ${harbor_docker_name} --password-stdin'
                sh 'docker tag datarc:latest ${harbor_docker_host}/${service_name}/${service_name}-${serviceStack}:${TAG_NAME}'
                sh 'docker push ${harbor_docker_host}/${service_name}/${service_name}-${serviceStack}:${TAG_NAME}'
                sh 'docker logout ${harbor_docker_host}'
            }
        }


        stage('=== 触发部署 ===') {
            when {
                anyOf {
                    branch "dev"
                    branch "rc"
                }
            }
            steps {
              sh 'curl -X POST http://192.168.1.99:8080/job/Jenkins-Gitea-CI/job/cd-iceberg/job/main/buildWithParameters -d "service_name=${service_name}" -d "serviceStack=${serviceStack}" -d "BRANCH_NAME=${BRANCH_NAME}" -d "TAG_NAME=${TAG_NAME}" --user ${deploy_datarc_token}'
            }
        }
}

    post {
      always {
        cleanWs deleteDirs: true, patterns: [[pattern: '*', type: 'INCLUDE']]
      }
    }
}

推送至远程仓库

git add .
git commit -m "chore: 上传前端代码 v1 版本"
git push origin dev-1

请求合并

创建从 dev-1 合并到 dev 分支
image-20240731122623080

合并请求

合并请求 并点击详情跳转至 Jenkins
image-20240731122802582

查看 Jenkins 效果

Jenkins 会自动执行 Jenkinsfile 中定义的阶段
image-20240731123002962

查看 Sonar Qube 效果

检测到是 dev 分支、在 dev 分支中查看结果
image-20240731123144260

查看 harbor 镜像仓库 效果

查看 harbor 镜像仓库发现多了 dev tag 的镜像
image-20240731123457006

只有当分支是 dev rc main 的时候才会触发构建代码等操作。