In the last article, we introduced the process of building from zero to integrating into GitLab. Those of you who read the previous article will know that we pre-commit the code before it is submitted. If the code fails the single test, it cannot be submitted. We need a strong control from the server side; The merge request that fails the single test cannot be merged, and a message prompt is given to the member that fails the single test, including email prompt and communication tool prompt (eg: enterprise wechat, Cloud home, dingding).

1. Planned configuration of gITLab unit test pipeline

In our last article, we introduced that assembly is automatically performed once per attack, which is configured in a YML configuration file with the only parameter of each stage. If only parameter is configured to schedules, the timing of assembly execution can be customized. Is it daily, weekly, or n times a day?

Attached here is the configuration that is executed at 10 o ‘clock and 24 o ‘clock each working day:

Cycle period: 0, 12,24 * * 1-5

Configuration that the pipeline must pass before code merging

With this configuration, merge requests that fail a single test cannot be merged.

3. Email notification and nail notification

3.1 Email notification this function is relatively simple, only need simple configuration in gitLab;

3.2 Next, we will introduce the message notification of Dingding and wechat (including all members and specific submitting members).

First of all, we must have a certain understanding of Wehook. We will not introduce it too much here. If you do not know, you can ask Baidu.

We need to create and start a custom robot in a group (Dingding, Yunjia) and get its corresponding Webhook address: ****

Now that we have the Webhook address, we need to add a message notification job to YML

  notify-job:  stage: notify  image: node:13  script:    - chmod +x py/Notify.py; ./py/Notify.py $MERGE_URL ${JOB_URL} $CI_COMMIT_REF_NAME $SONAR_CHECK_URL;  when: on_failure
Copy the code

Note: This message notifies the job only if the previous job fails. Normally, executing a Python script requires a Python image, so I did this by adding the following command at the top of the script: #! The/usr/bin/env python; Let Python scripts execute directly like SHELL scripts

Jobs in the same stage can be executed in parallel as long as the gitlab-runner config.toml configuration is set to a concurrent value greater than 1, when: On_failure: If a previous job fails, it will be triggered. How do we know which job failed? After a lot of research, I couldn’t find a good parameter/method, but I finally found an artifact that could be used for communication between different jobs by writing a file after executing the script for each job and uploading the file if the job failed. The job notified in the message reads the contents of the uploaded file to determine which job failed

sonarqube-check:  before_script:    - echo "FAIL" > .job_status  stage: test  image: sonarsource/sonar-scanner-cli:latest  script:      - sonar-scanner -Dsonar.projectKey=${CI_PROJECT_NAME} -Dsonar.sourceEncoding=UTF-8 -Dsonar.java.binaries=. -Dsonar.java.source=11 -Dsonar.pullrequest.branch=${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} -Dsonar.pullrequest.key=${CI_MERGE_REQUEST_IID} -Dsonar.pullrequest.base=${CI_MERGE_REQUEST_TARGET_BRANCH_NAME} -Dsonar.projectDescription=${CI_PROJECT_TITLE} -Dsonar.links.homepage=${CI_PROJECT_URL} -Dsonar.java.binaries=target/classes -Dsonar.java.test.binaries=target/test-classes -Dsonar.java.surefire.report=target/surefire-reports -Dsonar.gitlab.ref_name=${CI_COMMIT_REF_NAME} -Dsonar.gitlab.commit_sha=${CI_COMMIT_SHA} -Dsonar.gitlab.project_id=${CI_PROJECT_PATH} -Dsonar.pullrequest.gitlab.repositorySlug=$CI_PROJECT_ID -Dsonar.qualitygate.wait=true      - echo "SUCCESS" > .job_status  only:    - merge_requests  artifacts:    paths:      - .job_status    when: on_failure    expire_in: 30 mins 4 secnotify-job:  stage: notify  image: node:13  script:    - if [ "$(cat .job_status)" == FAIL ]; then chmod +x py/NoticeToYZJ.py; ./py/NoticeToYZJ.py sonarqube-check $MERGE_URL ${JOB_URL} $CI_COMMIT_REF_NAME $SONAR_CHECK_URL; fi  only:    - merge_requests  when: on_failure
Copy the code

In fact, we can find that every job has before_script, after_script and after_script, and after_script executes whether the job fails or succeeds. We can take advantage of this feature to send failure messages for each job

unit-test:  before_script:    - echo "FAIL" > .job_status  script:    - rm -rf node_modules    - unzip -q node_modules.zip    - npm run test:ci    - echo "SUCCESS" > .job_status  stage: test  only:    - merge_requests  image: node:13  artifacts:    paths:      - coverage/lcov-report/  coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'  after_script:    - if [ "$(cat .job_status)" == FAIL ]; then chmod +x py/NoticeToYZJ.py; ./py/NoticeToYZJ.py ${CI_JOB_NAME} $MERGE_URL ${JOB_URL} $CI_COMMIT_REF_NAME $SONAR_CHECK_URL; fi
Copy the code

After the job is added, let’s start writing the message notification script. Here we implement two ways of notifying everyone and notifying specific message notification objects:

One: Inform everyone

#! /usr/bin/env python# This Python file uses the following encoding: utf-8import reimport osimport urllib2import jsonimport sys def getData(job_name, job_url, branch_name, sonar_check_url): if job_name == 'unit-test': return { "content": '@ all' + '\ n' + '# #' + 'unit test failure warning:' + '# #' + '\ n' + 'branches: % s' % branch_name +' \ n '+' to check the link: %s' %job_url + '\n' } elif job_name == 'sonarqube-check': return { "content": '@ all' + '\ n' + '# #' + 'code scanning failure warning:' + '# #' + '\ n' + 'branches: % s' % branch_name +' \ n '+' to check the link: %s' %sonar_check_url + '\n' } else: return None def getContent(): content = (os.popen("git log --pretty=format:\"%an-&%h-&%s\" -1 ").read()).split("-&") return content def doNotify(content): print(sys.argv) global sonar_check_url, job_name, job_url, commit_url, branch_name, name, shortcodenum, explain, posturl, headers, request job_name = sys.argv[1] commit_url = sys.argv[2] job_url = sys.argv[3] branch_name = sys.argv[4] sonar_check_url = sys.argv[5] name = content[0] shortcodenum = content[1] explain = content[2] posturl = "*****" data = getData(job_name, job_url, branch_name, sonar_check_url) string_textMsg1 = json.dumps(data) request = urllib2.Request(posturl) request.add_header('Content-Type', 'application/json; charset=utf-8') urllib2.urlopen(request, string_textMsg1) if __name__ == "__main__": string_textMsg = {} content = getContent() doNotify(content)Copy the code

A: Notify a specific person

#! /usr/bin/env python# This Python file uses the following encoding: utf-8import reimport osimport urllib2import jsonimport syssys.path.append("/py")import globalVar as globalVar def get_data(name, job_name, job_url, branch_name, shortcodenum, explain, phone, sonar_check_url): if job_name == 'unit-test': return { "content": '# #' + 'unit test failure warning:' + '# #' + '\ n' + 'head: % s' % name +' \ n '+' submit branches: % s' % branch_name + '\ n' + 'submit SHA: Shortcodenum + % s' % '\ n' + 'to submit information: % s' % explain +' \ n '+' view links: % s' % job_url + '\ n', "notifyParams" : [{" type ": "mobiles", "values": [ phone ] }] } elif job_name == 'sonarqube-check': return { "content": '# #' + 'code scanning failure warning:' + '# #' + '\ n' + 'head: % s' % name +' \ n '+' submit branches: % s' % branch_name + '\ n' + 'submit SHA: Shortcodenum + % s' % '\ n' + 'to submit information: % s' % explain +' \ n '+' view links: % s' % sonar_check_url + '\ n', "notifyParams" : [{" type ": "mobiles", "values": [ phone ] }] } else: return Nonedef get_content(): content = (os.popen("git log --pretty=format:\"%an-&%h-&%s\" -1 ").read()).split("-&") return content def post_notify(content): print(sys.argv, content) global sonar_check_url, job_name, job_url, commit_url, branch_name, name, shortcodenum, explain, webhookurl, headers job_name = sys.argv[1] commit_url = sys.argv[2] job_url = sys.argv[3] branch_name = sys.argv[4] sonar_check_url = sys.argv[5] name = content[0] shortcodenum = content[1] explain = content[2] webhookurl = "***webhookurl" for i in globalVar.gitlabMembers: global phone if i["name"] == name: phone = i["phone"] data = get_data(name, job_name, job_url, branch_name, shortcodenum, explain, phone, sonar_check_url) string_textMsg = json.dumps(data) request = urllib2.Request(webhookurl) request.add_header('Content-Type', 'application/json; charset=utf-8') urllib2.urlopen(request, string_textMsg) if __name__ == "__main__": string_textMsg = {} content = get_content() post_notify(content)Copy the code

Well, here is the end of the article, I do this piece of news notification process is also encountered some pits, have a problem or have a better implementation of the students welcome to exchange ~