Multibranch Pipeline

Problems

Like database product, it runs on multi-platform, but for software enginner they may only works on one platform, how they could identify their code works on all platform? manually build the various platforms? NO!

Solution

Most people would know we can use Jenkins pipeline, they may create multi Jenkins job for different stuation.

How to do it in an elegant way, I would want to share how to use multibranch pipeline to achieve.

  1. When create a pull request, auto parallel start simple build.
  2. Reviewers can decide whether to merge base on build results.
  3. After code merged, auto start full build.

Read More

Code Coverage tools of C/C++

Code Coverage is a measurement of how many lines, statements, or blocks of your code are tested using your suite of automated tests. It’s an essential metric to understand the quality of your QA efforts.

Code coverage shows you how much of your application is not covered by automated tests and is therefore vulnerable to defects. it is typically measured in percentage values – the closer to 100%, the better.

When you’re trying to demonstrate test coverage to your higher-ups, code coverage tools (and other tools of the trade, of course) come in quite useful.

List of Code Coverage Tools

| Tools | Support Language | Cost | Partners |
|—|—|—|—|—|
| Squish Coco | C, C++, C#, SystemC, Tcl and QML | Not disclosed |Botom of this page Selected Clients|
| BullseyeCoverage | C, C++ |$800 for 1-year license and up | |
| Testwell| C, C++, C#, Java| Not disclosed| |
| Parasoft C/C++test |C, C++ | Not disclosed | partners |
| VECTOR Code Coverage | C, C++ | Not disclosed (free trial available)| partners |
|JaCoCo| Java | Open Source| Most famous code coverage tool in Java area |

GitSCM clone code don't display branch

最近遇到一个 regression bug,是产品完成构建之后,build commit number 不对,显示的 HEAD 而不是常见的 97b34931ac HASH number,这是什么原因呢?
我检查了 build 脚本没有发现问题,branch 的输出是正确的,那我怀疑是引入 Jenkins 的原因,果然登录到远程的 agent 上去查看分支名称如下:

C:\workspace\blog>git branch
* (HEAD detached at 97b3493)

果然问题出在了 Jenkins 上。这个问题有简单办法解决,就是直接使用git命令来clone代码,而不使用Git插件

git clone --depth 1 -b u2opensrc https://username:"passwowrd"@git.github.com/scm/blog.git blog

这种方式固然简单,不会出错,但它是明码显示,我岂能容忍这种不堪的处理方式吗?肯定还是要在 Git 插件上找到解决办法的。
随后google一下,果然有遇到和我一样问题的人,问题链接 这里

他说他做了很多调查,还跟专业的 Jenkins 人士联系,试了很多次,最后找到这个办法

checkout([$class: 'GitSCM', branches: [[name: '*/feature/*']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'LocalBranch', localBranch: "**"]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '99f978af-XXXX-XXXX-8147-2cf8f69ef864', url: 'http://TFS_SERVER:8080/tfs/DefaultCollection/Product/_git/Project']]])

主要是在 extensions:[] 中加入这句 [$class: ‘LocalBranch’, localBranch: “**”]

这是 Jenkins 的 Bug 吗?带着这个疑问随后通过 Pipeline Syntax,找到 checkout: Check out from version control,在 Additional Behaviours 里有 Check out to specific local branch 这个配置项

If given, checkout the revision to build as HEAD on this branch.
If selected, and its value is an empty string or “**”, then the branch name is computed from the remote branch without the origin. In that case, a remote branch origin/master will be checked out to a local branch named master, and a remote branch origin/develop/new-feature will be checked out to a local branch named develop/newfeature.

看介绍原来 Jenkins 自带这个设置,只是它不是默认选项,所以才遇到刚才那个问题。随后选择这个设置,然后填入”**”,然后生成 Pipeline 脚本,就跟上面的脚本一样了。

通过参数化上传文件到 FTP 服务器

实现 CI/CD 过程中,常常需要将构建好的 build 上传到一个公共的服务器,供测试、开发来获取最新的 build。如何上传 build 成果物到 FTP server,又不想把 FTP server登录的用户名和密码存在脚本里,想做这样的参数化如何实现呢?

upload_to_ftp.bat [hostname] [username] [password] [local_path] [remote_pat]

Read More

Automatically commit code by Jenkins

When we need to release a product, we should change copyright, build version, release month, release note…
How to modify multiple files automatically?
I used a Jenkins pipeline project, the project is parameterized(string parameter) and regular expressions to implement.

  1. Here is the string parameter for copyright:

    • Name: copyright

    • Default Value: 1995—2019

    • Description: Copyright format:1995—2019

      stage('change copyrigh') {
      steps {
      sh label: '', script: 'sed -i -E "s/(1995—[0-9]{4})/${copyright}/" 1033/AutoRun.ini'
      }
      }
  2. Here is the string parameter for build version:

    • Name: build_version

    • Default Value: 1.2.2.1002

    • Description: build version format: 1.2.2.1002

      stage('change build version') {
      steps {
      sh label: '', script: 'sed -i -E "s/([0-9].[0-9].[0-9].[0-9]{4})/${build_version}/" 1033/AutoRun.ini'
      }
      }
  3. Here is the string parameter for build version:

    • Name: release_month

    • Default Value: May 2019

    • Description: release month format: May 2019

      stage('change release month') {
      steps {
      sh label: '', script: '''
      sed -i -E "s/([a-z]* 20[0-9]{2})/${release_month}/" 1033/AutoRun.ini
      sed -i -E "s/([a-z]* 20[0-9]{2})/${release_month}/" 1033/MainMenu.ini
      '''
      }
      }
  4. push change to Git

    stage('git push to Git') {
    steps {
    sshagent(['8dd766ba-ac0f-4302-afa8-bee59c726dee']) {
    sh("git add 1033/AutoRun.ini")
    sh("git add 1033/MainMenu.ini")
    sh("git commit -m 'Bld # ${build_version}'")
    sh("git push -u origin master")
    }
    }
    }
  5. Whole Jenkins Pipeline looks like:

    pipeline {
    agent {
    label 'master'
    }

    stages{
    stage('git clone') {
    steps{
    git branch: 'master',
    credentialsId: '8dd766ba-ac0f-4302-afa8-bee59c726dee',
    url: 'git@github.com:shenxianpeng/blog.git'
    }
    }

    stage('change copyrigh') {
    steps {
    sh label: '', script: 'sed -i -E "s/(1995—[0-9]{4})/${copyright}/" 1033/AutoRun.ini'
    }
    }

    stage('change release month') {
    steps {
    sh label: '', script: '''
    sed -i -E "s/([a-z]* 20[0-9]{2})/${release_month}/" 1033/AutoRun.ini
    sed -i -E "s/([a-z]* 20[0-9]{2})/${release_month}/" 1033/MainMenu.ini
    '''
    }
    }

    stage('change build version') {
    steps {
    sh label: '', script: 'sed -i -E "s/([0-9].[0-9].[0-9].[0-9]{4})/${build_version}/" 1033/AutoRun.ini'
    }
    }

    stage('git push to Git') {
    steps {
    sshagent(['8dd766ba-ac0f-4302-afa8-bee59c726dee']) {
    sh("git add 1033/AutoRun.ini")
    sh("git add 1033/MainMenu.ini")
    sh("git commit -m 'Bld # ${build_version}'")
    sh("git push -u origin master")
    }
    }
    }
    }
    }

Jenkins Linux agent configuration

Prepare Java runtime

Check if had installed java

$ java -version
openjdk version "1.8.0_65"
OpenJDK Runtime Environment (build 1.8.0_65-b17)
OpenJDK 64-Bit Server VM (build 25.65-b01, mixed mode)

if not Here is an article telling you how to install it

Create Node

1. Jenkins home page->Manage Node->New Node, such as window-build-machine

2. List Linux agent settings

Items Settings
Name Linux-build-machine
Description used for Linux build
of executors 1
Remote root directory /home/agent
Labels Linux, build
Usage Use this node as much as possible
Launch method Launch agent agents via SSH
Host 192.168.1.112
Credentials username/password
Host Key Verification Strategy Manually trusted key Verification Strategy
Availability Keep this agent online as much as paossible

3. How to set credentials

credentials configuration
Domain Global credentials (unrestricted)
Kind Username with password
Scope Global(Jenkins, nodes, items, all child items, etc)
Username root
Password mypassword
Description Linux agent username & password

4. Save then Connect

Remoting version: 3.29
This is a Unix agent
Evacuated stdout
Agent successfully connected and online
SSHLauncher{host='192.168.1.112', port=22, credentialsId='d1cbab74-823d-41aa-abb7-8584859503d0', jvmOptions='', javaPath='/usr/bin/java',
prefixStartSlaveCmd='', suffixStartSlaveCmd='', launchTimeoutSeconds=210, maxNumRetries=10, retryWaitTime=15,
sshHostKeyVerificationStrategy=hudson.plugins.sshslaves.verifiers.ManuallyTrustedKeyVerificationStrategy, tcpNoDelay=true, trackCredentials=true}
[05/11/19 01:33:37] [SSH] Opening SSH connection to 192.168.1.112:22.
[05/11/19 01:33:37] [SSH] SSH host key matches key seen previously for this host. Connection will be allowed.
[05/11/19 01:33:37] [SSH] Authentication successful.
[05/11/19 01:33:37] [SSH] The remote user's environment is:

Troubleshooting

Problem how to fix
[04/22/19 23:15:07] [SSH] WARNING: No entry currently exists in the Known Hosts file for this host. Connections will be denied until this new host and its associated key is added to the Known Hosts file. ssh-keyscan HOSTNAME >> known_hosts
/var/lib/jenkins/.ssh/known_hosts [SSH] No Known Hosts file was found at /var/lib/jenkins/.ssh/known_hosts. changing the Host key verification strategy in LAUNCH METHOD from “Known Hosts file verification strategy” to “Manually trusted key verification strategy”

Jenkins Windows agent configuration

Prepare Java runtime

1. Download Java

2. Configure Java Windows path

JAVA_HOME=C:\Program Files\Java\jdk1.8.0_201
CLASSPATH=.;%JAVA_HOME%\lib;%JAVA_HOME%\jre\lib

Create Node

1. Jenkins home page->Manage Node->New Node, such as window-build-machine

2. List windows agent settings

Items Settings
Name window-build-machine
Description used for windows build
of executors 1
Remote root directory C:\agent
Labels windows, build
Usage Use this node as much as possible
Launch method Let Jenkins control this Windows slave as a Windows service
Administrator user name .\Administrator
Password mypassword
Host 192.168.1.111
Run service as Use Administrator account given above
Availability Keep this agent online as much as paossible

3. Save then Connect

[2019-05-11 01:32:50] [windows-slaves] Connecting to 192.168.1.111
Checking if Java exists
java -version returned 1.8.0.
[2019-05-11 01:32:50] [windows-slaves] Copying jenkins-slave.xml
[2019-05-11 01:32:50] [windows-slaves] Copying slave.jar
[2019-05-11 01:32:50] [windows-slaves] Starting the service
[2019-05-11 01:32:50] [windows-slaves] Waiting for the service to become ready
[2019-05-11 01:32:55] [windows-slaves] Connecting to port 52,347
<===[JENKINS REMOTING CAPACITY]===>Remoting version: 3.29
This is a Windows agent
Agent successfully connected and online

Troubleshooting

No. Problem how to fix
1 ERROR: Message not found for errorCode: 0xC00000AC need to install JDK, and config JAVA environment variable
2 how to fix add windows node as Windows service error JENKINS-16418
3 org.jinterop.dcom.common.JIException: Message not found for errorCode: 0x00000005 HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432Node\CLSID {72C24DD5-D70A-438B-8A42-98424B88AFB8}
HKEY_CLASSES_ROOT\CLSID{76A64158-CB41-11D1-8B02-00600806D9B6}
Launch ‘regedit’ (as Administrator)
Find (Ctrl+F) the following registry key: “{72C24DD5-D70A-438B-8A42-98424B88AFB8}” in HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432Node\CLSID\
Right click and select ‘Permissions’, Change owner to administrators group (Advanced…).
Change permissions for administrators group. Grant Full Control
Change owner back to TrustedInstaller (user is “NT Service\TrustedInstaller” on local machine)
Repeat the steps above for HKEY_CLASSES_ROOT\CLSID {76A64158-CB41-11D1-8B02-00600806D9B6}
Restart Remote Registry Service (Administrative Tools / Services)
4 ERROR: Unexpected error in launching an agent. This is probably a bug in Jenkins Login remote machine and open Services find jenkinsslave-C__agent
Set startup type: Automatic
Log On: select This account, type correct account and password
start jenkinsslave-C__agent
5 Caused by: org.jinterop.dcom.common.JIRuntimeException: Message not found for errorCode: 0x800703FA Slave under domain account
If your slave is running under a domain account and you get an error code 0x800703FA, change a group policy:
open the group policy editor (gpedit.msc)
go to Computer Configuration->Administrative Templates->System-> UserProfiles, “Do not forcefully unload the user registry at user logoff”
Change the setting from “Not Configured” to “Enabled”, which disables the new User Profile Service feature (‘DisableForceUnload’ is the value added to the registry)
6 more connect jenkins agent problem on windows … please refer to this link https://github.com/jenkinsci/windows-slaves-plugin/blob/master/docs/troubleshooting.adoc
7 ERROR: Message not found for errorCode: 0xC0000001 Caused by: jcifs.smb.SmbException: Failed to connect: 0.0.0.0<00>/10.xxx.xxx.xxx need to enable SMB1
Search in the start menu for ‘Turn Windows features on or off’ and open it.
Search for ‘SMB1.0/CIFS File Sharing Support’ in the list of optional features that appears, and select the checkbox next to it.
Click OK and Windows will add the selected feature. You’ll be asked to restart your computer as part of this process