4

image.png

background

In the last round of optimization, by optimizing some construction tools and processes, we optimized the construction time to about 4 minutes, and the overall release time was optimized from 15 minutes to about 8 minutes. There is a big improvement, but there is still room for improvement.

After some thinking and testing, a technical solution was given and implemented in the WMS business. The results are as follows:

image.png

Compared with the original process, the publishing time has been reduced from 8 minutes to about 1-2 minutes.

Below I mainly introduce the details of the plan, summarize the problems encountered in the transformation process, and hope to be helpful to everyone.

text

Overall scheme design

1. Existing Architecture

image.png

Inadequate existing architecture:

Every time you execute jenkins, you have to restart the construction and packaging operations, which is very time-consuming. Jenkins does not retain the packaging results, so operations such as rollback cannot be performed.

There are a lot of ineffective and time-consuming builds in the current build process that can be removed, such as using docker to package images, but they are useless for this project.

Architecture improvements

image.png

CI/CD pre-packaged

After the MR, CI will be triggered to execute the build task. The build process takes about 2 minutes. After the build is successful, the corresponding result will be pushed to the corresponding branch for storage.

During the Jenkins build phase, the packaged results are directly retrieved from the corresponding branch and pushed to the static resource server. This process is very fast, and the release can be completed within 1 minute.

It should be noted that: Since it is built in gitlab, some environmental information, such as CID, will be missing at this time.

This parameter is not used for some special logic in the WMS service, so it has no effect. If the project needs to use the CID, additional processing is required.

Publish and rollback

image.png

The release process directly releases the result branch packaged by gitlab CICD, which is reflected in the jenkins process, which is equivalent to just copying a copy of the result content to the target static server for rollback operation and packaging the previous tag of the build-release branch directly.

After uat and release are released, the resources will be tagged and saved in gitlab. One tag corresponds to one resource, and rapid rollback can be achieved with the help of lasg_tag.

Specific implementation steps

  1. Modify deploy.json and .gitlab-ci.yml
 "project_dir_depth": 2, 
"project_name": "wmsuiv2",
"module_name": "static", 
"build": {
"commands": ["echo 'deploy websitestatic'"], 
"upload_static": {
  "static_dir": "dist", "enable_cdn": false
},
"docker_image": {
"base_image": "harbor.shopeemobile.com/shopee/nodejs-base:14",
"dependent_libraries_files": [],
"run_commands": ["pip install -U shopee-deploy-common"]
// ...

// .gitlab-ci.yml

 image: harbor.shopeemobile.com/shopee/nodejs-base:14

variables:
env: '${CI_COMMIT_REF_NAME}' ENV: '${CI_COMMIT_REF_NAME}'

stages:
build

build:
stage: build 
rules:
if: $CI_COMMIT_REF_NAME == 'uat' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == null
if: $CI_COMMIT_REF_NAME == 'release' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == null
if: $CI_COMMIT_REF_NAME =~ /version\/release-(.*)$/ && $CI_PIPELINE_SOURCE == 'web' variables:
GITLAB_URL: 'https://gitlab-ci-token:${CI_JOB_TOKEN}@git.garena.com/shopee/bg-logistics/tianlu/fe/wms-ui.git' GITLAB_W_URL: 'https://${USERNAME}:${PERSONAL_ACCESS_TOKEN}@git.garena.com/shopee/bg-logistics/tianlu/fe/wms-
ui.git' script:
echo "CI_COMMIT_BRANCH:${CI_COMMIT_BRANCH};CI_COMMIT_TAG:${CI_COMMIT_TAG}; CI_DEFAULT_BRANCH:${CI_DEFAULT_BRANCH};CI_MERGE_REQUEST_TARGET_BRANCH_NAME=${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}"
npm install --registry=https://npm.shopee.io
echo "[sys] npm install [finish]"
npm run build
echo "[sys] npm run build [finish]"
if [[ "$CI_COMMIT_REF_NAME" =~ ^version/release-.*$ ]]; then
TARGET_BRANCH="temp/build-staging"
else
TARGET_BRANCH="temp/build-${CI_COMMIT_REF_NAME}"
fi
git clone -b ${TARGET_BRANCH} ${GITLAB_URL}
cd wms-ui/
echo "TARGET_BRANCH:${TARGET_BRANCH}"
echo "CI_COMMIT_REF_NAME:${CI_COMMIT_REF_NAME}"
git config --global user.name "wms.frontend"
git config --global user.email "wms.frontend@shopee.com"
rm -rf ./dist
cp -rf ../dist .
git add .
git commit -am "git ci push" -q
git push ${GITLAB_W_URL} ${TARGET_BRANCH}
echo "[sys] git push to ${TARGET_BRANCH} [successful]"
if [[ "$CI_COMMIT_REF_NAME" == "release" ]]; then
TAG="tag-$(date +%y%m%d-v%H%M)"
echo -e "[sys] tag name ${TAG}"
git tag ${TAG}
git push ${GITLAB_W_URL} ${TAG}
echo "[push succcessful]"
fi

After this process is completed, the following operations:

  1. Create the corresponding branch

Take the test branch as an example, pull a new branch from the test branch: build-test, which is used to store the packaging results.

In this branch, only three files/folders are kept: deploy, dist, .gitignore, and all other contents are deleted.

Among them, deploy is used to read build scripts for jenkins;

The dist directory is the subsequent packaging product of gitlab CI/CD;
.gitignore is the directory and file that needs to be excluded from submission;

pay attention:
/dist cannot be ignored in .gitignore.

In the project settings, turn off the reject unverified users option, otherwise the push will fail.

image.png

Other details:

  • The image must remain the same as the jenkins script configuration
  • You need to use gitlab-ci-token to pull the code in the script command. The Push phase must depend on the build phase. The application scope is uat, release, version/release-xxx branches. The first two are automatically triggered when the code is combined, and the version branch It needs to be triggered manually at CI/C -> pipeline -> click the 'run pipeline' button

Cross-account submission steps:

Add the public account wms.frontend to the project and set it as maintainer. (Public account application address: link, WMS project team has already applied, no additional application is required) Use wms.frontend to log in, Access Tokens in the edit profile of the personal account Create a Personal Access Token, get username and token.

Save the username and token to the variables under the CI/CD of the corresponding project, so that the verification information can be obtained through the variable ${username} in the cicd script. Then before git push, the git config account needs to be configured as public account information, so that you can use his token to submit operations.
image.png

After completing the above configuration, MR will automatically execute the build and push the result.

image.png

At this point, the first step is completed, and then the publishing task is created in DMS.

The only difference from the existing process is the chosen build branch.

image.png

Taking test as an example, the existing process selects the test branch, and the new process needs to select the temp/build-test branch. After all, in this process, jenkins only makes a copy of the files in the temp/build-test branch, and Push static files to the server.

At this point, the transformation is complete.

image.png

Last but not least:

After merging, it will take about 2 minutes to build. If you go to jenkins to publish at this time, the old build results may be published. Although this is not destructive, it is not in line with expectations.

The corresponding measures are:

Add seatalk message group notification. After the construction is completed, remind the relevant publishers to complete the release.

Bottom line measures:

If an extreme situation causes gitlab to fail to complete the build, you can also change back to the original configuration and follow the original process.

Steps:

Reset deploy.json and .gitlabyml and merge into corresponding branches.
Just build the original branch (test, uat, release) in Jenkins.

Think and Extend

There is a time difference between construction and release. When this problem occurs, it is possible to communicate with the DMS team, open a message notification capability, and automatically complete this process to reduce dependence on people.

The way to add robot notifications is not complicated. The implementation is as follows:

 // ...
- >
sh -c "curl -i -X POST -H 'Content-Type: application/json' -d '{\"tag\":\"text\",\"text\":{\"content\": \" WMS-UI FE:${TAG}\"}}' https://openapi.seatalk.io/webhook/group/${groudId}"
- fi
// ...

Summarize

The traditional release and rollback relies on one build. The core idea of this solution is: 借助第三方存储,保存打包产物,以此减少构建时间。

There are many similar solutions, and it is not only this solution, which will not be extended here.

This article has been covered so much, I hope it can give you some inspiration, thank you.

If I am wrong, please correct me, thank you.


皮小蛋
8k 声望12.8k 粉丝

积跬步,至千里。