Tại dự án của mình, source sẻ có hai bộ, một bộ sẻ được để ở Code commit phục vụ cho việc deploy, bộ còn lại ở Gitlab được đặt trong local network phục vụ cho việc scan code bằng Sonar, Blackduck và Coverity.
Mỗi khi cần deploy thì mình cần phải đồng bộ source giữa Gitlab và Code commit.
Giải pháp
Mình sẽ dùng Jenkins để đồng bộ source, phía khách hàng muốn sử dụng tài khoảng riêng cho từng môi trường, thì mỗi tài khoảng sẽ có một repo Code commit tương tứng, và các cặp user/pass tương ứng.
Phần pipelne sẽ bao gồm các bước như pull code từ Gitlab về, sau đó clear source như thư mục .git, pakage-lock.json … vv, sau đó sẻ commit và push lên Code commit bằng user/pass dành cho môi tường đó.
Luồng đồng bộ
Ở Gitlab sẽ có bốn nhánh là dev, testing, staging và master.
Hai nhánh dev và testing sẽ được đồng bộ tới repo Code commit với nhánh dev và master của tài khoảng dev.
Nhánh staging sẽ được động bộ tới nhánh master của repo Code commit tài khoảng stag.
Nhánh master sẽ được động bộ tới nhánh master của repo Code commit tài khoảng prod.
Cấu hình Credentials
Mình sẽ tạo ba Credentials tương ứng với ba repo Code commit trong Jenkins.
Tạo Downtream Job
Mình sẽ tạo một Job riêng biệt để làm nhiệm vũ sync source lên Code commit.
Validate branch function
Dựa vào luồng đồng bộ ở trên hàm này có nhiệm vụ sẽ trả về git url tương ứng với giá trị nhánh đưa vào, ví dụ mình đưa vào nhánh dev, thì hàm sẽ trả về “git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/dev-backend -b dev”
@NonCPS
def validateRemoteRepo(MICRO_REPO_BRANCH){
map_branch_repo = [
dev: "git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/dev-backend -b dev",
testing: "git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/dev-backend -b master",
staging: "git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/stg-backend -b master",
master: "git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/prod-backend -b master"
]
if(!map_branch_repo[MICRO_REPO_BRANCH]){
throw new RuntimeException(MICRO_REPO_BRANCH + " Not Match!!");
} else {
return map_branch_repo[MICRO_REPO_BRANCH];
}
}
Validate account function
Hàm này có tác dụng trả về credential tương ứng với nhánh đưa vào, ví dụ mình đưa vào nhánh dev thì hàm sẽ trả về account “codecommit.dev”
@NonCPS
def validateAccount(BRANCH){
map_account = [
dev: "codecommit.dev",
testing: "codecommit.dev",
staging: "codecommit.stg",
master: "codecommit.prod"
]
if(!map_account_repo[MICRO_REPO_BRANCH]){
throw new RuntimeException(MICRO_REPO_BRANCH + " Not Match!!");
} else {
return map_account_repo[MICRO_REPO_BRANCH];
}
}
Parameter
Mình khởi tạo param để truyền các giá trị như Gitlab url, Giltlab branch để các hàm xử lý.
parameters {
string(name: 'GITLAB_REPO')
string(name: 'GITLAB_BRANCH')
}
Clone repo Code commit
Mình sẽ clone repo Code commit về, xóa source trong đó đi.
stage('Clone Codecommit'){
steps{
dir("${env.WORKSPACE}") {
script {
if(fileExists("backend"))
{
powershell "Remove-Item 'backend"
}
def codecommit_url = validateRemoteRepo("${gitlab_branch}")
def codecommit_acc = validateAccount("${gitlab_branch}")
withCredentials([usernamePassword(credentialsId: "${codecommit_acc}", usernameVariable: 'USER', passwordVariable:'PASS')]) {
env.encodedPass=URLEncoder.encode(PASS, "UTF-8")
powershell """
git config --global user.email 'ci@vm.com'
git config --global user.name 'jenkins-ci'
git clone https://$USER:$encodedPass@${codecommit_url} backend
"""
powershell "Remove-Item 'backend/src"
}
}
}
}
}
Clone source Gitlab, clear, commit and push
Tiếp theo mình clone source Giltab, sau đó tiền hành clear source và move source vào thư mục của repo Code commit, commit và push.
stage('Clone Gitlab'){
steps{
dir("${env.WORKSPACE}/backend") {
script {
withCredentials([usernamePassword(credentialsId: "${credentialID}", usernameVariable: 'USER', passwordVariable:'PASS')]) {
env.encodedPass=URLEncoder.encode(PASS, "UTF-8")
powershell """
git config --global user.email 'ci@aap-k.com'
git config --global user.name 'jenkins-ci'
git clone https://$USER:$encodedPass@${gitlab_repo} -b ${gitlab_branch} git_temp
"""
}
}
}
}
}
stage('Clear and sync'){
steps{
dir("${env.WORKSPACE}/backend") {
script {
powershell "Remove-Item 'git_temp/src/package-lock.json'"
powershell "Move-Item -Path 'git_temp/src' -Destination 'src'"
powershell "Remove-Item 'git_temp'"
}
}
}
}
stage('Push'){
steps{
dir("${env.WORKSPACE}/backend") {
script {
bat """ git add .
git commit -m "new update"
git push origin """
}
}
}
}
Trigger Job
Ở Job chín (Job thực hiện sacn code, ..) mình sẽ thêm phần trigger dowstream job
stage {
steps {
build job: "Sync_source",
parameters [
string(name: 'GITLAB_REPO', value: '$gitlab_url'),
string(name: 'GITLAB_BRANCH', value: '$gitlab_branch')
]
}
}
Param gitlab_branch mình sẽ dùng một plugin để chọn nhánh thông qua menu xổ xuống.