devops practice: continuous integration with teamcity

What problems have been solved?


Fast ci cd;


Team collaboration efficiency is higher, faster integration, faster delivery; Take gitops mode;





Mainstream CICD process:





teamcity architecture:

Installation mode


docker installation is fast

Install the server side

mkdir -p /data/teamcity_server/datadir  /data/teamcity/logs


docker run -it --name teamcity-server \
-v /data/teamcity_server/datadir:/data/teamcity_server/datadir \
-v /data/teamcity_server/logs:/opt/teamcity/logs \
-p 8111:8111 \
jetbrains/teamcity-server:EAP

Then get the access url, which will be used later when installing the client.


For example, here is: http://172.31.12.168:8111




The default hsqldb is selected for the database. As long as the mounted directory is not lost, the data also exists after reinstallation;

Install client side

mkdir -p /data/teamcity_agent/conf
chmod -R 777 /data/teamcity_agent/conf

docker run -it -e SERVER_URL="http://172.31.12.168:8111"  \
    -v /data/teamcity_agent/conf:/data/teamcity_agent/conf  \
    jetbrains/teamcity-agent:EAP


Multiple can be installed;


However, the professional version is limited to 3, so for later traversal, there should be no more than 3 clients at most!


After installation, you need to authorize the agent on the server side to use it.


Add notes directly to the client pool.


![file](https://img2020.cnblogs.com/other/268922/202111/268922-20211130080823805-1397778791.png)
Then you can join the client pool of the server. The execution of the built task can be performed according to the parallelism of 3.

![file](https://img2020.cnblogs.com/other/268922/202111/268922-20211130080824337-1757792331.png)

It can also be deployed physically without the problem of docker kernel.


The physical version of the client installation package can be downloaded from this location. Modify the configuration parameters in combination with the document;

The main modifications are the server address of the server and the application name of the client;
Location: / data/team_agent4/conf/buildAgent.properties


Start instruction:. / bin/agent.sh start

Then it can be used after authorization on the server.

First use experience


CI and CD process of a backend project:
The following is the practice process:





Create project





Then paste in your gitlab or github warehouse address;


Fill in an account and password with read-only permission.


Configure CICD composition script

1. Back end jar package

2 dozen backend docker images

3 front end npm packaging



4 front end image production

5 push front-end and back-end images to the image warehouse

6 publish to k8s environment

7 Launch nail notification to project group

Overall kotlin code

package _Self.buildTypes

import jetbrains.buildServer.configs.kotlin.v2019_2.*
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.MavenBuildStep
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.dockerCommand
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.maven
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.nodeJS
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.script
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs

object Build : BuildType({
    name = "appBuild"
    description = "structure"

    allowExternalStatus = true
    artifactRules = "app-tp/start/target/app-tp.jar => app-tp.jar"
    publishArtifacts = PublishMode.SUCCESSFUL

    vcs {
        root(HttpGitlabH3yunComHermesSystemAppTpGitRefsHeadsMaster)

        showDependenciesChanges = true
    }

    steps {
        maven {
            name = "hit jar package"
            goals = "clean install -Dmaven.test.skip=true -U"
            pomLocation = "app-tp/pom.xml"
            runnerArgs = "-Dmaven.test.failure.ignore=true"
            workingDir = "app-tp"
            userSettingsSelection = "my nexus to configure"
            localRepoScope = MavenBuildStep.RepositoryScope.MAVEN_DEFAULT
            isIncremental = true
            jdkHome = "%env.JDK_18%"
            dockerImagePlatform = MavenBuildStep.ImagePlatform.Linux
            dockerPull = true
        }
        dockerCommand {
            name = "Make backend docker image"
            commandType = build {
                source = file {
                    path = "app-tp/app.Dockerfile"
                }
                namesAndTags = "registry.cn-shenzhen.aliyuncs.com/cloudpivot/app-tp:tptest"
                commandArgs = "--pull"
            }
        }
        nodeJS {
            name = "front end npm pack"
            shellScript = """
                cd front-tp
                npm install
                npm run build
            """.trimIndent()
            dockerPull = true
        }
        dockerCommand {
            name = "Production front end docker image"
            commandType = build {
                source = file {
                    path = "front-tp/front.Dockerfile"
                }
                namesAndTags = "registry.cn-shenzhen.aliyuncs.com/cloudpivot/front-tp:tptest"
                commandArgs = "--pull"
            }
        }
        script {
            name = "Login push to remote image warehouse"
            scriptContent = """
                docker login -u="aaaa" -p xxxxyun registry.cn-shenzhen.aliyuncs.com
                
                echo "Push to remote warehouse"
                docker push registry.cn-shenzhen.aliyuncs.com/cloudpivot/app-tp:tptest
                docker push registry.cn-shenzhen.aliyuncs.com/cloudpivot/front-tp:tptest
                
                echo "Delete local mirror===Save disk space===="
                docker images | grep app-tp | awk '{print ${'$'}3 }' | xargs docker rmi
                docker images | grep front-tp | awk '{print ${'$'}3 }' | xargs docker rmi
            """.trimIndent()
        }
        script {
            name = "to update k8s environment"
            scriptContent = """
                cd %system.teamcity.build.checkoutDir%
                cd deploy
                sh app_tp_deploy.sh
                sh front_tp_deploy.sh
            """.trimIndent()
        }
        script {
            name = "Push nail notification to project group"
            scriptContent = """
                url='https://oapi.dingtalk.com/robot/send?access_token=b0dc2aee487a842dd5648566ade86xxxxxxx'
                programe=Technology management platform
                server=tptest.cloudpivot.cn
                content=%teamcity.build.branch%
                buildInfo=%vcsroot.useAlternates%
                 
                function sendDingtalk(){
                    curl ${'$'}{1} \
                       -H 'Content-Type: application/json' \
                       -d "
                      {\"msgtype\": \"text\", 
                        \"text\": {
                            \"content\": \"Message content:project-${'$'}{2},domain name-${'$'}{3},branch-${'$'}{4} Update content-${'$'}{5}\"
                         },
                         \"isAtAll\": true, 
                      }"
                }
                
                sendDingtalk ${'$'}{url} ${'$'}{programe} ${'$'}{server} ${'$'}{content} ${'$'}{content} ${'$'}{buildInfo}
            """.trimIndent()
        }
    }

    triggers {
        vcs {
            branchFilter = "+:refs/heads/test"
        }
    }
})

Summary


teamcity professional version is limited to 3 execution clients and 100 build configurations, which is suitable for small teams;




The user experience is quite good, the interface is quite good-looking.


Automatically detect code changes and build; (can greatly improve CI efficiency)



For example, if a modification is pushed to a branch, it is directly released to the integration test environment.



pk


(after a function is developed, it will be merged into the integration test branch, and then released to the CICD system point. When encountering problems, it will stir up a pool of gulls and herons)






More elegant.

Nailing message notification


Pull a nail group and add a robot:











After completion, you can get the notification token:


https://oapi.dingtalk.com/robot/send?access_token=c30f5008258474da14e65d3141536953b79df3bf3ab64f33a583e83165b19665

Prepared shell script:

url='https://oapi.dingtalk.com/robot/send?access_token=c30f5008258474da14e65d3141536953b79df3bf3ab64f33a583e83165b19665'
programe=Technology management platform
server=tptest.cloudpivot.cn
content='Program interrupt'
 
function sendDingtalk(){
    curl ${1} \
       -H 'Content-Type: application/json' \
       -d "
      {\"msgtype\": \"text\", 
        \"text\": {
            \"content\": \"Message content:project-${2},Service address-${3},Update content-${4}\"
         },
         \"isAtAll\": true, 
      }"
}

sendDingtalk ${url} ${programe} ${server} ${content}




Practical examples:

url='https://oapi.dingtalk.com/robot/send?access_token=b0dc2aee487a842dd5648566ade86e2217dac868c0ffdcab5138cb7eab163978'
programe=Technology management platform
server=tptest.cloudpivot.cn
content=%teamcity.build.branch%
buildInfo=%vcsroot.useAlternates%
 
function sendDingtalk(){
    curl ${1} \
       -H 'Content-Type: application/json' \
       -d "
      {\"msgtype\": \"text\", 
        \"text\": {
            \"content\": \"Message content:project-${2},domain name-${3},branch-${4} Update content-${5}\"
         },
         \"isAtAll\": true, 
      }"
}

sendDingtalk ${url} ${programe} ${server} ${content} ${content} ${buildInfo}


Screenshot of notification effect:

Material Science


User manual: (English materials are required)


https://www.jetbrains.com/help/teamcity/2021.1/configure-and-run-your-first-build.html


team city Tour (must see Chinese materials)
https://developer.aliyun.com/article/738443


teamcity building process of Tencent cloud: (the privilege container solves the problem that docker agent cannot mirror)
https://blog.csdn.net/sD7O95O/article/details/88264986

Nailing robot notification document:
https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq

After the program starts, notify the nail group through the shell:
https://blog.csdn.net/weixin_37836950/article/details/107924910

Originality is not easy, attention is valuable, and the forwarding price is higher! Reprint please indicate the source, let us exchange what we need and make common progress, welcome communication.

Tags: Java

Posted on Mon, 29 Nov 2021 20:15:08 -0500 by desmi