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 ~