Compare commits
39 Commits
e4943e4ddf
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 186eada028 | |||
| 282e6436c8 | |||
| 4f3efba232 | |||
| f39fa26ba8 | |||
| 57bc24c792 | |||
| 80f0a992b4 | |||
| 33e24203f0 | |||
| 3f3e4fa53b | |||
| b61ee6a5e0 | |||
| f21f26115f | |||
| f9f21ba937 | |||
| 4b2f75c5a5 | |||
| 5ad8047ce4 | |||
| 35a3d78ef1 | |||
| 5388c2ca6f | |||
| 949a18af95 | |||
| ef47b28f63 | |||
| c422a0caff | |||
| bdcdbf0c2f | |||
| b4832fdb97 | |||
| 87de8b0ee2 | |||
| 705b70d189 | |||
| 31f82f9e5e | |||
| 4785b99e76 | |||
| 02c34eb722 | |||
| e979c36b0c | |||
| 20d6065d36 | |||
| 1044024e65 | |||
| 69b50258c1 | |||
| 27c4b620e4 | |||
| 2b0143e2f9 | |||
| 976f9ff37e | |||
| 722580786c | |||
| 1e2a845a27 | |||
| f642dec5f5 | |||
| 70b7590269 | |||
| df992aa54e | |||
| e5f1d5c4c4 | |||
| 11caa6f492 |
@@ -1,30 +1,47 @@
|
|||||||
pipeline {
|
pipeline {
|
||||||
agent any
|
agent any
|
||||||
parameters {
|
parameters {
|
||||||
choice(name: 'ENV', choices: ['prod', 'uat'], description: 'Choose Environment')
|
choice(name: 'ENV', choices: ['uat', 'production'], description: 'Choose Environment')
|
||||||
string(name: 'CI_JOB_BUILD_NUMBER', defaultValue: '', description: 'Build number of CI Job')
|
string(name: 'CI_JOB_BUILD_NUMBER', defaultValue: '', description: 'Build number of CI Job')
|
||||||
}
|
}
|
||||||
environment {
|
environment {
|
||||||
PROJECT_NAME = 'acp'
|
PROJECT_NAME = 'acp'
|
||||||
CI_JOB_NAME = 'CI_BE_ACP' // tên của job build code
|
CI_UAT_JOB_NAME = 'CI-UAT-BE-ACP' // tên của job build code mt uat
|
||||||
CI_JOB_METADATA_FILENAME = "${PROJECT_NAME}_metadata.json" // tên file metadata đã được lưu từ ci job
|
CI_PRODUCTION_JOB_NAME = 'CI-PRODUCTION-BE-ACP' // tên của job build code mt production
|
||||||
|
|
||||||
GIT_PAT_CREDENTIALS_ID = 'd3de261f-8f1e-470b-b6d1-2fb4965e0129' // Id của Personal Access Token lưu trên jenkins
|
CI_JOB_METADATA_FILENAME = "${PROJECT_NAME}_${params.ENV}_metadata.json" // tên file metadata đã được lưu từ ci job
|
||||||
GIT_ANSIBLE_URL = 'work.gct.com.vn/thienvv/nsg_ansible.git'
|
|
||||||
GIT_ANSIBLE_BRANCH = 'v2'
|
|
||||||
|
|
||||||
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
||||||
|
|
||||||
ANSIBLE_SSH_CONNECTION = 'root@103.166.183.172 -p 24700'
|
ANSIBLE_SSH_CONNECTION = 'root@103.166.183.172 -p 24700'
|
||||||
|
GIT_PAT_CREDENTIALS_ID = 'd3de261f-8f1e-470b-b6d1-2fb4965e0129' // Id của Personal Access Token lưu trên jenkins
|
||||||
|
GIT_ANSIBLE_URL = 'work.gct.com.vn/thienvv/nsg_ansible.git'
|
||||||
|
GIT_ANSIBLE_BRANCH = 'v3'
|
||||||
|
|
||||||
ANSIBLE_FOLDER_PATH = '/srv/ansible_v2'
|
ANSIBLE_FOLDER_PATH = '/srv/ansible_v3'
|
||||||
ANSIBLE_INVENTORY_PATH = "inventory/${params.ENV}.ini"
|
ANSIBLE_PLAYBOOK_PATH = 'playbooks/backend/deploy_acp_backend.yml'
|
||||||
ANSIBLE_PLAYBOOK_PATH = 'playbooks/deploy_be.yml'
|
|
||||||
|
SLACK_TOKEN = credentials('SLACK_TOKEN')
|
||||||
|
|
||||||
TELEGRAM_CHAT_ID = -4678013464
|
|
||||||
TELEGRAM_BOT_TOKEN = credentials('TELEGRAM_BOT_TOKEN')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
|
stage('Set up') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
if (params.ENV == 'uat') {
|
||||||
|
env.ANSIBLE_INVENTORY_PATH = 'inventory/uat/hosts.ini'
|
||||||
|
env.CI_JOB_NAME = CI_UAT_JOB_NAME
|
||||||
|
} else if (params.ENV == 'production') {
|
||||||
|
env.ANSIBLE_INVENTORY_PATH = 'inventory/production/hosts.ini'
|
||||||
|
env.CI_JOB_NAME = CI_PRODUCTION_JOB_NAME
|
||||||
|
}
|
||||||
|
echo "ANSIBLE_INVENTORY_PATH is set to: ${env.ANSIBLE_INVENTORY_PATH}"
|
||||||
|
echo "CI_JOB_NAME is set to: ${env.CI_JOB_NAME}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stage('Retrieve Artifact Metadata From CI Job') {
|
stage('Retrieve Artifact Metadata From CI Job') {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
@@ -63,8 +80,6 @@ pipeline {
|
|||||||
env.ANSIBLE_FOLDER_PATH,
|
env.ANSIBLE_FOLDER_PATH,
|
||||||
env.ANSIBLE_INVENTORY_PATH,
|
env.ANSIBLE_INVENTORY_PATH,
|
||||||
env.ANSIBLE_PLAYBOOK_PATH,
|
env.ANSIBLE_PLAYBOOK_PATH,
|
||||||
params.ENV,
|
|
||||||
env.PROJECT_NAME,
|
|
||||||
env.NEXUS_URL,
|
env.NEXUS_URL,
|
||||||
env.NEXUS_ARTIFACT_NAME,
|
env.NEXUS_ARTIFACT_NAME,
|
||||||
env.NEXUS_CREDENTIALS_USR,
|
env.NEXUS_CREDENTIALS_USR,
|
||||||
@@ -79,14 +94,16 @@ pipeline {
|
|||||||
}
|
}
|
||||||
success {
|
success {
|
||||||
script {
|
script {
|
||||||
def message = "Deploy thành công : API - Môi trường ${params.ENV} - Dự án ${env.PROJECT_NAME}, ${currentBuild.fullDisplayName}\n${env.BUILD_URL}"
|
def message = "✅ Deploy thành công : API - Môi trường ${params.ENV} - Dự án ${env.PROJECT_NAME}, ${currentBuild.fullDisplayName}\n${env.BUILD_URL}"
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
failure {
|
failure {
|
||||||
script {
|
script {
|
||||||
def message = "Deploy thất bại: API - Môi trường ${params.ENV} - Dự án ${env.PROJECT_NAME}, ${currentBuild.fullDisplayName}\n${env.BUILD_URL}"
|
def message = "❌ Deploy thất bại: API - Môi trường ${params.ENV} - Dự án ${env.PROJECT_NAME}, ${currentBuild.fullDisplayName}\n${env.BUILD_URL}"
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -188,8 +205,6 @@ def triggerAnsible(
|
|||||||
String ansibleansibleFolderPath,
|
String ansibleansibleFolderPath,
|
||||||
String inventoryPath,
|
String inventoryPath,
|
||||||
String playbookPath,
|
String playbookPath,
|
||||||
String deployENV,
|
|
||||||
String projectName,
|
|
||||||
String nexusUrl,
|
String nexusUrl,
|
||||||
String nexusArtifactName,
|
String nexusArtifactName,
|
||||||
String nexusUsername,
|
String nexusUsername,
|
||||||
@@ -201,9 +216,7 @@ def triggerAnsible(
|
|||||||
ssh ${sshAnsibleConnection} "
|
ssh ${sshAnsibleConnection} "
|
||||||
cd ${ansibleansibleFolderPath} &&
|
cd ${ansibleansibleFolderPath} &&
|
||||||
ansible-playbook -i ${inventoryPath} ${playbookPath} \\
|
ansible-playbook -i ${inventoryPath} ${playbookPath} \\
|
||||||
-e 'deploy_env=${deployENV} \\
|
-e 'nexus_url=${nexusUrl} \\
|
||||||
project_name=${projectName} \\
|
|
||||||
nexus_url=${nexusUrl} \\
|
|
||||||
artifact_name=${nexusArtifactName} \\
|
artifact_name=${nexusArtifactName} \\
|
||||||
nexus_username=${nexusUsername} \\
|
nexus_username=${nexusUsername} \\
|
||||||
nexus_password=${nexusPassword}' -vvvv
|
nexus_password=${nexusPassword}' -vvvv
|
||||||
|
|||||||
@@ -0,0 +1,378 @@
|
|||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
options { disableConcurrentBuilds(abortPrevious: true) }
|
||||||
|
environment {
|
||||||
|
GIT_CREDENTIALSID = 'd3de261f-8f1e-470b-b6d1-2fb4965e0129'
|
||||||
|
GIT_URL = 'http://work.gct.com.vn/anhln/ACP_2025.git'
|
||||||
|
GIT_BRANCH_NAME = 'production-acp'
|
||||||
|
|
||||||
|
ENV = 'production'
|
||||||
|
PROJECT_NAME = 'acp'
|
||||||
|
|
||||||
|
METADATA_FILENAME = "${PROJECT_NAME}_${env.ENV}_metadata.json"
|
||||||
|
TRIGGER_JOB_NAME = 'CD_BE_ACP'
|
||||||
|
|
||||||
|
NUGET_CONFIG_PATH = 'NuGet.config'
|
||||||
|
APPLICATIONCORE_PATH = 'Packages'
|
||||||
|
JENKINS_BUILD_FOLDER_PATH = 'Acp.WebApi'
|
||||||
|
JENKINS_PUBLISH_FOLDER_PATH = "${PROJECT_NAME}-${env.ENV}-publish"
|
||||||
|
|
||||||
|
COMPRESSED_FILE_NAME = "${PROJECT_NAME}_${env.ENV}_publish.zip" // tên file nén
|
||||||
|
COMPRESSED_FILE_PATH = "${env.WORKSPACE }/${COMPRESSED_FILE_NAME}"
|
||||||
|
|
||||||
|
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
||||||
|
|
||||||
|
NEXUS_REPO_URL = "https://nexus.gct.com.vn/repository/${env.ENV}-acp-backend"
|
||||||
|
GROUP_ID = 'vn.kinhtedothi'
|
||||||
|
ARTIFACT_ID = 'acp-backend-api'
|
||||||
|
PACKAGING = 'zip'
|
||||||
|
VERSION = '1.0.0' // Phiên bản cơ bản
|
||||||
|
|
||||||
|
TIMESTAMP = new Date().format('yyyyMMdd.HH', TimeZone.getTimeZone('UTC'))
|
||||||
|
FULL_VERSION = "${env.VERSION}-${env.TIMESTAMP}-${env.BUILD_NUMBER}" // Tạo phiên bản hoàn chỉnh
|
||||||
|
|
||||||
|
SLACK_TOKEN = credentials('SLACK_TOKEN')
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Checkout') {
|
||||||
|
steps {
|
||||||
|
// Checkout mã nguồn từ Gitea
|
||||||
|
checkoutFromGit(env.GIT_URL as String, env.GIT_CREDENTIALSID as String, env.GIT_BRANCH_NAME as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Clear Nuget caches') {
|
||||||
|
steps {
|
||||||
|
// Xóa cache của NuGet
|
||||||
|
clearNuGetCaches()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Setup Nuget.Config') {
|
||||||
|
steps {
|
||||||
|
// Thiết lập tệp NuGet.config
|
||||||
|
setupNuGetConfig(env.APPLICATIONCORE_PATH as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Restore') {
|
||||||
|
steps {
|
||||||
|
// Gọi hàm để thực hiện restore
|
||||||
|
restoreNuGetPackages(env.JENKINS_BUILD_FOLDER_PATH as String , env.NUGET_CONFIG_PATH as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Clean & Build') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
cleanProject(env.JENKINS_BUILD_FOLDER_PATH as String)
|
||||||
|
buildProject(env.JENKINS_BUILD_FOLDER_PATH as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Publish') {
|
||||||
|
steps {
|
||||||
|
publishProject(env.JENKINS_BUILD_FOLDER_PATH as String, env.JENKINS_PUBLISH_FOLDER_PATH as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Package (Compress Publish Files)') {
|
||||||
|
steps {
|
||||||
|
compressItems(env.COMPRESSED_FILE_PATH, env.JENKINS_PUBLISH_FOLDER_PATH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Upload to Nexus') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
String groupPath = env.GROUP_ID.replace('.', '/')
|
||||||
|
env.NEXUS_URL = "${env.NEXUS_REPO_URL}/${groupPath}/${env.ARTIFACT_ID}/${env.VERSION}"
|
||||||
|
env.NEXUS_ARTIFACT_NAME = "${env.ARTIFACT_ID}-${env.FULL_VERSION}.${env.PACKAGING}"
|
||||||
|
|
||||||
|
String nexusUploadUrl = "${env.NEXUS_URL}/${env.NEXUS_ARTIFACT_NAME}"
|
||||||
|
|
||||||
|
uploadToNexus(
|
||||||
|
env.NEXUS_CREDENTIALS_USR,
|
||||||
|
env.NEXUS_CREDENTIALS_PSW,
|
||||||
|
env.COMPRESSED_FILE_PATH,
|
||||||
|
nexusUploadUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Create Metadata File') {
|
||||||
|
steps {
|
||||||
|
createMetadataFile(
|
||||||
|
env.METADATA_FILENAME,
|
||||||
|
env.GROUP_ID,
|
||||||
|
env.ARTIFACT_ID,
|
||||||
|
env.VERSION,
|
||||||
|
env.NEXUS_URL,
|
||||||
|
env.NEXUS_ARTIFACT_NAME)
|
||||||
|
echo "metadataFileName: ${env.METADATA_FILENAME}"
|
||||||
|
archiveArtifacts artifacts: "${env.METADATA_FILENAME}", allowEmptyArchive: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
always {
|
||||||
|
echo 'Pipeline execution finished.'
|
||||||
|
}
|
||||||
|
success {
|
||||||
|
echo "Job '${env.JOB_NAME}' completed successfully. Attempting to trigger Job '${TRIGGER_JOB_NAME}'..."
|
||||||
|
script {
|
||||||
|
def message = "✅Build thành công : API - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n${env.BUILD_URL} \n Đang tiến hành Deploy...!"
|
||||||
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
failure {
|
||||||
|
script {
|
||||||
|
def message = "❌Build thất bại: API - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n Kiểm tra tại đây ${env.BUILD_URL}."
|
||||||
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv- hàm checkout git
|
||||||
|
void checkoutFromGit(String gitUrl, String credentialsId, String branch) {
|
||||||
|
try {
|
||||||
|
echo 'Start checkoutFromGit'
|
||||||
|
|
||||||
|
checkout([$class : 'GitSCM',
|
||||||
|
userRemoteConfigs: [[url: gitUrl, credentialsId: credentialsId]],
|
||||||
|
branches : [[name: "*/${branch}"]]])
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv- clear nuget caches
|
||||||
|
void clearNuGetCaches() {
|
||||||
|
try {
|
||||||
|
// Xóa cache của NuGet
|
||||||
|
Integer result = sh(script: 'dotnet nuget locals all --clear', returnStatus: true)
|
||||||
|
|
||||||
|
echo "result:${result}"
|
||||||
|
|
||||||
|
// Kiểm tra trạng thái trả về
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'NuGet caches cleared successfully.'
|
||||||
|
} else {
|
||||||
|
error "Failed to clear NuGet caches with status: ${result}"
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - Hàm set up file Nuget.config để restore các package dependencies
|
||||||
|
void setupNuGetConfig(String applicationCorePath) {
|
||||||
|
try {
|
||||||
|
writeFile file: 'NuGet.config', text: """<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
|
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||||
|
<add key="Package source" value="${applicationCorePath}" />
|
||||||
|
</packageSources>
|
||||||
|
</configuration>"""
|
||||||
|
|
||||||
|
// Kiểm tra xem tệp đã được ghi thành công
|
||||||
|
if (fileExists('NuGet.config')) {
|
||||||
|
echo 'NuGet.config has been created successfully.'
|
||||||
|
} else {
|
||||||
|
error 'Failed to create NuGet.config.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Thienvv - Định nghĩa hàm để restore các gói NuGet
|
||||||
|
// Thienvv - Định nghĩa hàm để restore các gói NuGet
|
||||||
|
void restoreNuGetPackages(String restorePath, String nugetConfigPath) {
|
||||||
|
echo 'Starting NuGet packages restore...'
|
||||||
|
try {
|
||||||
|
if (!fileExists(restorePath)) {
|
||||||
|
error "restorePath is not exist : ${restorePath}"
|
||||||
|
}
|
||||||
|
if (!fileExists(nugetConfigPath)) {
|
||||||
|
error "nugetConfigPath is not exist : ${nugetConfigPath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Thực hiện restore các gói NuGet cần thiết
|
||||||
|
Integer result = sh(script: "dotnet restore ${restorePath} --configfile ${nugetConfigPath}", returnStatus: true)
|
||||||
|
|
||||||
|
// Kiểm tra kết quả trả về
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'NuGet packages restored successfully.'
|
||||||
|
} else {
|
||||||
|
error "Restore NuGet packages failed with exit code: ${result}. Check NuGet config and restore path."
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - clean project dotnet
|
||||||
|
void cleanProject(String buildPath) {
|
||||||
|
echo 'Start cleanProject'
|
||||||
|
try {
|
||||||
|
if (!fileExists(buildPath)) {
|
||||||
|
error "buildPath is not exist : ${buildPath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer result = sh(script: "dotnet clean ${buildPath}", returnStatus: true)
|
||||||
|
|
||||||
|
echo "result:${result}"
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'Clean Project successfully'
|
||||||
|
} else {
|
||||||
|
error 'Clean Projectfailed'
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - build project dotnet
|
||||||
|
void buildProject(String buildPath) {
|
||||||
|
echo 'Start buildProject'
|
||||||
|
try {
|
||||||
|
if (!fileExists(buildPath)) {
|
||||||
|
error "buildPath is not exist : ${buildPath}"
|
||||||
|
}
|
||||||
|
Integer result = sh(script: "dotnet build ${buildPath} -c Release", returnStatus: true)
|
||||||
|
|
||||||
|
echo "result:${result}"
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'Build Project successfully'
|
||||||
|
} else {
|
||||||
|
error 'Build Project failed'
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - package/publish project dotnet
|
||||||
|
void publishProject(String buildPath, String publishFolderPath) {
|
||||||
|
echo 'Start publishProject'
|
||||||
|
try {
|
||||||
|
if (!fileExists(buildPath)) {
|
||||||
|
error "buildPath is not exist : ${buildPath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer result = sh(script: "dotnet publish ${buildPath} -c Release -o ${publishFolderPath}",
|
||||||
|
returnStatus: true)
|
||||||
|
|
||||||
|
echo "result : ${result}"
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'Publish Project successfully'
|
||||||
|
} else {
|
||||||
|
error 'Publish Project failed'
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - nén file
|
||||||
|
void compressItems(String compressedFilePath, String parentFolderPath) {
|
||||||
|
echo "Starting compression of the entire folder into a zip file : ${compressedFilePath}"
|
||||||
|
try {
|
||||||
|
if (fileExists(compressedFilePath)) {
|
||||||
|
echo "Old ZIP file exists. Deleting: ${compressedFilePath}"
|
||||||
|
sh "rm -f ${compressedFilePath}"
|
||||||
|
} else {
|
||||||
|
echo 'No old ZIP file found.'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fileExists(parentFolderPath)) {
|
||||||
|
error "parentFolderPath is not exist : ${parentFolderPath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
dir(parentFolderPath) {
|
||||||
|
// Thực hiện lệnh zip để nén tất cả các file trong thư mục
|
||||||
|
Integer result = sh(script: "zip -r ${compressedFilePath} * ", returnStatus: true)
|
||||||
|
|
||||||
|
// Kiểm tra kết quả
|
||||||
|
if (result == 0) {
|
||||||
|
echo "Compression completed successfully: ${compressedFilePath}"
|
||||||
|
} else {
|
||||||
|
error "Compression failed with exit code: ${result}."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void uploadToNexus(String nexusUsername, String nexusPassword, String compressedFilePath, String uploadUrl) {
|
||||||
|
echo "Starting upload ${compressedFilePath} To Nexus"
|
||||||
|
try {
|
||||||
|
// Truyền các biến môi trường vào lệnh sh mà không lộ ra trong log
|
||||||
|
String result = sh(script: """
|
||||||
|
curl -u ${nexusUsername}:${nexusPassword} --upload-file ${compressedFilePath} ${uploadUrl} -w '%{http_code}'
|
||||||
|
""", returnStdout: true).trim()
|
||||||
|
|
||||||
|
if (result == '200' || result == '201') {
|
||||||
|
echo 'uploadToNexus successfully'
|
||||||
|
} else {
|
||||||
|
error "uploadToNexus failed, HTTP status: ${result}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def createMetadataFile(
|
||||||
|
String metadataFileName,
|
||||||
|
String groupId,
|
||||||
|
String artifactId,
|
||||||
|
String version,
|
||||||
|
String nexusUrl,
|
||||||
|
String nexusArtifactName) {
|
||||||
|
echo 'Starting create metadata file'
|
||||||
|
try {
|
||||||
|
// Tạo metadata
|
||||||
|
metadata = [
|
||||||
|
groupId: groupId,
|
||||||
|
artifactId: artifactId,
|
||||||
|
version: version,
|
||||||
|
nexusUrl: nexusUrl,
|
||||||
|
nexusArtifactName: nexusArtifactName
|
||||||
|
]
|
||||||
|
|
||||||
|
// Ghi metadata vào file JSON
|
||||||
|
writeJSON file: "${metadataFileName}", json: metadata
|
||||||
|
|
||||||
|
if (!fileExists(metadataFileName)) {
|
||||||
|
error "metadataFileName is not exist : ${metadataFileName}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,24 +4,25 @@ pipeline {
|
|||||||
environment {
|
environment {
|
||||||
GIT_CREDENTIALSID = 'd3de261f-8f1e-470b-b6d1-2fb4965e0129'
|
GIT_CREDENTIALSID = 'd3de261f-8f1e-470b-b6d1-2fb4965e0129'
|
||||||
GIT_URL = 'http://work.gct.com.vn/anhln/ACP_2025.git'
|
GIT_URL = 'http://work.gct.com.vn/anhln/ACP_2025.git'
|
||||||
GIT_BRANCH = 'main'
|
GIT_BRANCH_NAME = 'uat-acp'
|
||||||
|
|
||||||
|
ENV = 'uat'
|
||||||
PROJECT_NAME = 'acp'
|
PROJECT_NAME = 'acp'
|
||||||
|
|
||||||
METADATA_FILENAME = "${PROJECT_NAME}_metadata.json"
|
METADATA_FILENAME = "${PROJECT_NAME}_${env.ENV}_metadata.json"
|
||||||
TRIGGER_JOB_NAME = 'CD_BE_ACP'
|
TRIGGER_JOB_NAME = 'CD_BE_ACP'
|
||||||
|
|
||||||
NUGET_CONFIG_PATH = 'NuGet.config'
|
NUGET_CONFIG_PATH = 'NuGet.config'
|
||||||
APPLICATIONCORE_PATH = 'Packages'
|
APPLICATIONCORE_PATH = 'Packages'
|
||||||
JENKINS_BUILD_FOLDER_PATH = 'Acp.WebApi'
|
JENKINS_BUILD_FOLDER_PATH = 'Acp.WebApi'
|
||||||
JENKINS_PUBLISH_FOLDER_PATH = "${PROJECT_NAME}-publish"
|
JENKINS_PUBLISH_FOLDER_PATH = "${PROJECT_NAME}-${env.ENV}-publish"
|
||||||
|
|
||||||
COMPRESSED_FILE_NAME = "${PROJECT_NAME}_publish.zip" // tên file nén
|
COMPRESSED_FILE_NAME = "${PROJECT_NAME}_${env.ENV}_publish.zip" // tên file nén
|
||||||
COMPRESSED_FILE_PATH = "${env.WORKSPACE }/${COMPRESSED_FILE_NAME}"
|
COMPRESSED_FILE_PATH = "${env.WORKSPACE }/${COMPRESSED_FILE_NAME}"
|
||||||
|
|
||||||
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
||||||
|
|
||||||
NEXUS_REPO_URL = 'https://nexus.gct.com.vn/repository/acp-backend'
|
NEXUS_REPO_URL = "https://nexus.gct.com.vn/repository/${env.ENV}-acp-backend"
|
||||||
GROUP_ID = 'vn.kinhtedothi'
|
GROUP_ID = 'vn.kinhtedothi'
|
||||||
ARTIFACT_ID = 'acp-backend-api'
|
ARTIFACT_ID = 'acp-backend-api'
|
||||||
PACKAGING = 'zip'
|
PACKAGING = 'zip'
|
||||||
@@ -30,15 +31,15 @@ pipeline {
|
|||||||
TIMESTAMP = new Date().format('yyyyMMdd.HH', TimeZone.getTimeZone('UTC'))
|
TIMESTAMP = new Date().format('yyyyMMdd.HH', TimeZone.getTimeZone('UTC'))
|
||||||
FULL_VERSION = "${env.VERSION}-${env.TIMESTAMP}-${env.BUILD_NUMBER}" // Tạo phiên bản hoàn chỉnh
|
FULL_VERSION = "${env.VERSION}-${env.TIMESTAMP}-${env.BUILD_NUMBER}" // Tạo phiên bản hoàn chỉnh
|
||||||
|
|
||||||
TELEGRAM_CHAT_ID = -4678013464
|
SLACK_TOKEN = credentials('SLACK_TOKEN')
|
||||||
TELEGRAM_BOT_TOKEN = credentials('TELEGRAM_BOT_TOKEN')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
stage('Checkout') {
|
stage('Checkout') {
|
||||||
steps {
|
steps {
|
||||||
// Checkout mã nguồn từ Gitea
|
// Checkout mã nguồn từ Gitea
|
||||||
checkoutFromGit(env.GIT_URL as String, env.GIT_CREDENTIALSID as String, env.GIT_BRANCH as String)
|
checkoutFromGit(env.GIT_URL as String, env.GIT_CREDENTIALSID as String, env.GIT_BRANCH_NAME as String)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,13 +125,14 @@ pipeline {
|
|||||||
success {
|
success {
|
||||||
echo "Job '${env.JOB_NAME}' completed successfully. Attempting to trigger Job '${TRIGGER_JOB_NAME}'..."
|
echo "Job '${env.JOB_NAME}' completed successfully. Attempting to trigger Job '${TRIGGER_JOB_NAME}'..."
|
||||||
script {
|
script {
|
||||||
def message = "Build thành công : API - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n${env.BUILD_URL} \n Đang tiến hành Deploy...!"
|
def message = "✅Build thành công : API - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n${env.BUILD_URL} \n Đang tiến hành Deploy...!"
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
}
|
}
|
||||||
script {
|
script {
|
||||||
try {
|
try {
|
||||||
def buildResult = build job: "${TRIGGER_JOB_NAME}", parameters:[
|
def buildResult = build job: "${TRIGGER_JOB_NAME}", parameters:[
|
||||||
string(name: 'ENV', value: 'uat'),
|
string(name: 'ENV', value: env.ENV),
|
||||||
string(name: 'CI_JOB_BUILD_NUMBER', value: env.BUILD_NUMBER)
|
string(name: 'CI_JOB_BUILD_NUMBER', value: env.BUILD_NUMBER)
|
||||||
],
|
],
|
||||||
propagate: false
|
propagate: false
|
||||||
@@ -146,8 +148,9 @@ pipeline {
|
|||||||
}
|
}
|
||||||
failure {
|
failure {
|
||||||
script {
|
script {
|
||||||
def message = "Build thất bại: API - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n Kiểm tra tại đây ${env.BUILD_URL}."
|
def message = "❌Build thất bại: API - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n Kiểm tra tại đây ${env.BUILD_URL}."
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,15 @@
|
|||||||
pipeline {
|
pipeline {
|
||||||
agent any
|
agent any
|
||||||
parameters {
|
parameters {
|
||||||
choice(name: 'ENV', choices: ['prod', 'uat'], description: 'Choose Environment')
|
choice(name: 'ENV', choices: ['uat', 'production'], description: 'Choose Environment')
|
||||||
|
choice(name: 'PORTAL_NAME', choices: ['ktdt', 'hnt'], description: 'Choose Portal')
|
||||||
string(name: 'CI_JOB_BUILD_NUMBER', defaultValue: '', description: 'Build number of CI Job')
|
string(name: 'CI_JOB_BUILD_NUMBER', defaultValue: '', description: 'Build number of CI Job')
|
||||||
}
|
}
|
||||||
environment {
|
environment {
|
||||||
PROJECT_NAME = 'portal'
|
PROJECT_NAME = 'portal'
|
||||||
|
CI_UAT_JOB_NAME = 'CI-UAT-BE-PORTAL' // tên của job build code mt uat
|
||||||
CI_JOB_NAME = 'CI_BE_PORTAL' // tên của job CI
|
CI_PRODUCTION_JOB_NAME = 'CI-PRODUCTION-BE-PORTAL' // tên của job build code mt production
|
||||||
CI_JOB_METADATA_FILENAME = "${PROJECT_NAME}_metadata.json" // tên file metadata đã được lưu từ ci job
|
CI_JOB_METADATA_FILENAME = "${PROJECT_NAME}_${params.ENV}_metadata.json" // tên file metadata đã được lưu từ ci job
|
||||||
|
|
||||||
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
||||||
|
|
||||||
@@ -16,17 +17,39 @@ pipeline {
|
|||||||
|
|
||||||
GIT_PAT_CREDENTIALS_ID = 'd3de261f-8f1e-470b-b6d1-2fb4965e0129' // Id của Personal Access Token lưu trên jenkins
|
GIT_PAT_CREDENTIALS_ID = 'd3de261f-8f1e-470b-b6d1-2fb4965e0129' // Id của Personal Access Token lưu trên jenkins
|
||||||
GIT_ANSIBLE_URL = 'work.gct.com.vn/thienvv/nsg_ansible.git'
|
GIT_ANSIBLE_URL = 'work.gct.com.vn/thienvv/nsg_ansible.git'
|
||||||
GIT_ANSIBLE_BRANCH = 'v2'
|
GIT_ANSIBLE_BRANCH = 'v3'
|
||||||
|
|
||||||
ANSIBLE_FOLDER_PATH = '/srv/ansible_v2'
|
ANSIBLE_FOLDER_PATH = '/srv/ansible_v3'
|
||||||
ANSIBLE_INVENTORY_PATH = "inventory/${params.ENV}.ini"
|
|
||||||
ANSIBLE_PLAYBOOK_PATH = 'playbooks/deploy_be.yml'
|
SLACK_TOKEN = credentials('SLACK_TOKEN')
|
||||||
|
|
||||||
TELEGRAM_CHAT_ID = -4678013464
|
|
||||||
TELEGRAM_BOT_TOKEN = credentials('TELEGRAM_BOT_TOKEN')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
|
stage('Set up') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
if (params.ENV == 'uat') {
|
||||||
|
env.ANSIBLE_INVENTORY_PATH = 'inventory/uat/hosts.ini'
|
||||||
|
env.CI_JOB_NAME = CI_UAT_JOB_NAME
|
||||||
|
} else if (params.ENV == 'production') {
|
||||||
|
env.ANSIBLE_INVENTORY_PATH = 'inventory/production/hosts.ini'
|
||||||
|
env.CI_JOB_NAME = CI_PRODUCTION_JOB_NAME
|
||||||
|
}
|
||||||
|
echo "ANSIBLE_INVENTORY_PATH is set to: ${env.ANSIBLE_INVENTORY_PATH}"
|
||||||
|
echo "CI_JOB_NAME is set to: ${env.CI_JOB_NAME}"
|
||||||
|
|
||||||
|
if (params.PORTAL_NAME == 'ktdt') {
|
||||||
|
env.ANSIBLE_PLAYBOOK_PATH = 'playbooks/backend/deploy_ktdt_portal_backend.yml'
|
||||||
|
} else if (params.PORTAL_NAME == 'hnt') {
|
||||||
|
env.ANSIBLE_PLAYBOOK_PATH = 'playbooks/backend/deploy_hnt_portal_backend.yml'
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "ANSIBLE_PLAYBOOK_PATH is set to: ${env.ANSIBLE_PLAYBOOK_PATH}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stage('Retrieve Artifact From CI Job') {
|
stage('Retrieve Artifact From CI Job') {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
@@ -65,8 +88,6 @@ pipeline {
|
|||||||
env.ANSIBLE_FOLDER_PATH,
|
env.ANSIBLE_FOLDER_PATH,
|
||||||
env.ANSIBLE_INVENTORY_PATH,
|
env.ANSIBLE_INVENTORY_PATH,
|
||||||
env.ANSIBLE_PLAYBOOK_PATH,
|
env.ANSIBLE_PLAYBOOK_PATH,
|
||||||
params.ENV,
|
|
||||||
env.PROJECT_NAME,
|
|
||||||
env.NEXUS_URL,
|
env.NEXUS_URL,
|
||||||
env.NEXUS_ARTIFACT_NAME,
|
env.NEXUS_ARTIFACT_NAME,
|
||||||
env.NEXUS_CREDENTIALS_USR,
|
env.NEXUS_CREDENTIALS_USR,
|
||||||
@@ -81,14 +102,16 @@ pipeline {
|
|||||||
}
|
}
|
||||||
success {
|
success {
|
||||||
script {
|
script {
|
||||||
def message = "Deploy thành công : API - Môi trường ${params.ENV} - Dự án ${env.PROJECT_NAME}, ${currentBuild.fullDisplayName}\n${env.BUILD_URL}"
|
def message = "✅Deploy thành công : API - Môi trường ${params.ENV} - Dự án ${env.PROJECT_NAME} - Portal_Name ${params.PORTAL_NAME}, ${currentBuild.fullDisplayName}\n${env.BUILD_URL}"
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
failure {
|
failure {
|
||||||
script {
|
script {
|
||||||
def message = "Deploy thất bại: API - Môi trường ${params.ENV} - Dự án ${env.PROJECT_NAME}, ${currentBuild.fullDisplayName}\n${env.BUILD_URL}"
|
def message = "❌Deploy thất bại: API - Môi trường ${params.ENV} - Dự án ${env.PROJECT_NAME} - Portal_Name ${params.PORTAL_NAME}, ${currentBuild.fullDisplayName}\n${env.BUILD_URL}"
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,8 +212,6 @@ def triggerAnsible(
|
|||||||
String ansibleansibleFolderPath,
|
String ansibleansibleFolderPath,
|
||||||
String inventoryPath,
|
String inventoryPath,
|
||||||
String playbookPath,
|
String playbookPath,
|
||||||
String deployENV,
|
|
||||||
String projectName,
|
|
||||||
String nexusUrl,
|
String nexusUrl,
|
||||||
String nexusArtifactName,
|
String nexusArtifactName,
|
||||||
String nexusUsername,
|
String nexusUsername,
|
||||||
@@ -202,9 +223,7 @@ def triggerAnsible(
|
|||||||
ssh ${sshAnsibleConnection} "
|
ssh ${sshAnsibleConnection} "
|
||||||
cd ${ansibleansibleFolderPath} &&
|
cd ${ansibleansibleFolderPath} &&
|
||||||
ansible-playbook -i ${inventoryPath} ${playbookPath} \\
|
ansible-playbook -i ${inventoryPath} ${playbookPath} \\
|
||||||
-e 'deploy_env=${deployENV} \\
|
-e 'nexus_url=${nexusUrl} \\
|
||||||
project_name=${projectName} \\
|
|
||||||
nexus_url=${nexusUrl} \\
|
|
||||||
artifact_name=${nexusArtifactName} \\
|
artifact_name=${nexusArtifactName} \\
|
||||||
nexus_username=${nexusUsername} \\
|
nexus_username=${nexusUsername} \\
|
||||||
nexus_password=${nexusPassword}' -vvvv
|
nexus_password=${nexusPassword}' -vvvv
|
||||||
|
|||||||
@@ -0,0 +1,380 @@
|
|||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
options { disableConcurrentBuilds(abortPrevious: true) }
|
||||||
|
environment {
|
||||||
|
GIT_CREDENTIALSID = 'd3de261f-8f1e-470b-b6d1-2fb4965e0129'
|
||||||
|
GIT_URL = 'http://work.gct.com.vn/anhln/ACP_2025.git'
|
||||||
|
GIT_BRANCH_NAME = 'production-portal'
|
||||||
|
|
||||||
|
ENV = 'production'
|
||||||
|
PROJECT_NAME = 'portal'
|
||||||
|
|
||||||
|
METADATA_FILENAME = "${PROJECT_NAME}_${env.ENV}_metadata.json"
|
||||||
|
TRIGGER_JOB_NAME = 'CD_BE_PORTAL'
|
||||||
|
|
||||||
|
NUGET_CONFIG_PATH = 'NuGet.config'
|
||||||
|
APPLICATIONCORE_PATH = 'Packages'
|
||||||
|
JENKINS_BUILD_FOLDER_PATH = 'Portal.WebApi'
|
||||||
|
JENKINS_PUBLISH_FOLDER_PATH = "${PROJECT_NAME}-${env.ENV}-publish"
|
||||||
|
|
||||||
|
COMPRESSED_FILE_NAME = "${PROJECT_NAME}_${env.ENV}_publish.zip" // tên file nén
|
||||||
|
COMPRESSED_FILE_PATH = "${env.WORKSPACE }/${COMPRESSED_FILE_NAME}"
|
||||||
|
|
||||||
|
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
||||||
|
|
||||||
|
NEXUS_REPO_URL = "https://nexus.gct.com.vn/repository/${env.ENV}-portal-backend"
|
||||||
|
GROUP_ID = 'vn.kinhtedothi'
|
||||||
|
ARTIFACT_ID = 'portal-backend-api'
|
||||||
|
PACKAGING = 'zip'
|
||||||
|
VERSION = '1.0.0' // Phiên bản cơ bản
|
||||||
|
|
||||||
|
TIMESTAMP = new Date().format('yyyyMMdd.HH', TimeZone.getTimeZone('UTC'))
|
||||||
|
FULL_VERSION = "${env.VERSION}-${env.TIMESTAMP}-${env.BUILD_NUMBER}" // Tạo phiên bản hoàn chỉnh
|
||||||
|
|
||||||
|
SLACK_TOKEN = credentials('SLACK_TOKEN')
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Checkout') {
|
||||||
|
steps {
|
||||||
|
// Checkout mã nguồn từ Gitea
|
||||||
|
checkoutFromGit(env.GIT_URL as String, env.GIT_CREDENTIALSID as String, env.GIT_BRANCH_NAME as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Clear Nuget caches') {
|
||||||
|
steps {
|
||||||
|
// Xóa cache của NuGet
|
||||||
|
clearNuGetCaches()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Setup Nuget.Config') {
|
||||||
|
steps {
|
||||||
|
// Thiết lập tệp NuGet.config
|
||||||
|
setupNuGetConfig(env.APPLICATIONCORE_PATH as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Restore') {
|
||||||
|
steps {
|
||||||
|
// Gọi hàm để thực hiện restore
|
||||||
|
restoreNuGetPackages(env.JENKINS_BUILD_FOLDER_PATH as String , env.NUGET_CONFIG_PATH as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Clean & Build') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
cleanProject(env.JENKINS_BUILD_FOLDER_PATH as String)
|
||||||
|
buildProject(env.JENKINS_BUILD_FOLDER_PATH as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Publish') {
|
||||||
|
steps {
|
||||||
|
publishProject(env.JENKINS_BUILD_FOLDER_PATH as String, env.JENKINS_PUBLISH_FOLDER_PATH as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Package (Compress Publish Files)') {
|
||||||
|
steps {
|
||||||
|
compressItems(env.COMPRESSED_FILE_PATH, env.JENKINS_PUBLISH_FOLDER_PATH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Upload to Nexus') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
String groupPath = env.GROUP_ID.replace('.', '/')
|
||||||
|
env.NEXUS_URL = "${env.NEXUS_REPO_URL}/${groupPath}/${env.ARTIFACT_ID}/${env.VERSION}"
|
||||||
|
env.NEXUS_ARTIFACT_NAME = "${env.ARTIFACT_ID}-${env.FULL_VERSION}.${env.PACKAGING}"
|
||||||
|
|
||||||
|
String nexusUploadUrl = "${env.NEXUS_URL}/${env.NEXUS_ARTIFACT_NAME}"
|
||||||
|
|
||||||
|
uploadToNexus(
|
||||||
|
env.NEXUS_CREDENTIALS_USR,
|
||||||
|
env.NEXUS_CREDENTIALS_PSW,
|
||||||
|
env.COMPRESSED_FILE_PATH,
|
||||||
|
nexusUploadUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Create Metadata File') {
|
||||||
|
steps {
|
||||||
|
createMetadataFile(
|
||||||
|
env.METADATA_FILENAME,
|
||||||
|
env.GROUP_ID,
|
||||||
|
env.ARTIFACT_ID,
|
||||||
|
env.VERSION,
|
||||||
|
env.NEXUS_URL,
|
||||||
|
env.NEXUS_ARTIFACT_NAME)
|
||||||
|
|
||||||
|
echo "metadataFileName: ${env.METADATA_FILENAME}"
|
||||||
|
archiveArtifacts artifacts: "${env.METADATA_FILENAME}", allowEmptyArchive: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
always {
|
||||||
|
echo 'Pipeline execution finished.'
|
||||||
|
}
|
||||||
|
success {
|
||||||
|
echo "Job '${env.JOB_NAME}' completed successfully. Attempting to trigger Job '${TRIGGER_JOB_NAME}'..."
|
||||||
|
script {
|
||||||
|
def message = "✅Build thành công : API - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n${env.BUILD_URL} \n Đang tiến hành Deploy...!"
|
||||||
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
failure {
|
||||||
|
failure {
|
||||||
|
script {
|
||||||
|
def message = "❌Build thất bại: API - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n Kiểm tra tại đây ${env.BUILD_URL}."
|
||||||
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv- hàm checkout git
|
||||||
|
void checkoutFromGit(String gitUrl, String credentialsId, String branch) {
|
||||||
|
try {
|
||||||
|
echo 'Start checkoutFromGit'
|
||||||
|
|
||||||
|
checkout([$class : 'GitSCM',
|
||||||
|
userRemoteConfigs: [[url: gitUrl, credentialsId: credentialsId]],
|
||||||
|
branches : [[name: "*/${branch}"]]])
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv- clear nuget caches
|
||||||
|
void clearNuGetCaches() {
|
||||||
|
try {
|
||||||
|
// Xóa cache của NuGet
|
||||||
|
Integer result = sh(script: 'dotnet nuget locals all --clear', returnStatus: true)
|
||||||
|
|
||||||
|
echo "result:${result}"
|
||||||
|
|
||||||
|
// Kiểm tra trạng thái trả về
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'NuGet caches cleared successfully.'
|
||||||
|
} else {
|
||||||
|
error "Failed to clear NuGet caches with status: ${result}"
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - Hàm set up file Nuget.config để restore các package dependencies
|
||||||
|
void setupNuGetConfig(String applicationCorePath) {
|
||||||
|
try {
|
||||||
|
writeFile file: 'NuGet.config', text: """<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
|
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||||
|
<add key="Package source" value="${applicationCorePath}" />
|
||||||
|
</packageSources>
|
||||||
|
</configuration>"""
|
||||||
|
|
||||||
|
// Kiểm tra xem tệp đã được ghi thành công
|
||||||
|
if (fileExists('NuGet.config')) {
|
||||||
|
echo 'NuGet.config has been created successfully.'
|
||||||
|
} else {
|
||||||
|
error 'Failed to create NuGet.config.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Thienvv - Định nghĩa hàm để restore các gói NuGet
|
||||||
|
void restoreNuGetPackages(String restorePath, String nugetConfigPath) {
|
||||||
|
echo 'Starting NuGet packages restore...'
|
||||||
|
try {
|
||||||
|
if (!fileExists(restorePath)) {
|
||||||
|
error "restorePath is not exist : ${restorePath}"
|
||||||
|
}
|
||||||
|
if (!fileExists(nugetConfigPath)) {
|
||||||
|
error "nugetConfigPath is not exist : ${nugetConfigPath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Thực hiện restore các gói NuGet cần thiết
|
||||||
|
Integer result = sh(script: "dotnet restore ${restorePath} --configfile ${nugetConfigPath}", returnStatus: true)
|
||||||
|
|
||||||
|
// Kiểm tra kết quả trả về
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'NuGet packages restored successfully.'
|
||||||
|
} else {
|
||||||
|
error "Restore NuGet packages failed with exit code: ${result}. Check NuGet config and restore path."
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - clean project dotnet
|
||||||
|
void cleanProject(String buildPath) {
|
||||||
|
echo 'Start cleanProject'
|
||||||
|
try {
|
||||||
|
if (!fileExists(buildPath)) {
|
||||||
|
error "buildPath is not exist : ${buildPath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer result = sh(script: "dotnet clean ${buildPath}", returnStatus: true)
|
||||||
|
|
||||||
|
echo "result:${result}"
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'Clean Project successfully'
|
||||||
|
} else {
|
||||||
|
error 'Clean Projectfailed'
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - build project dotnet
|
||||||
|
void buildProject(String buildPath) {
|
||||||
|
echo 'Start buildProject'
|
||||||
|
try {
|
||||||
|
if (!fileExists(buildPath)) {
|
||||||
|
error "buildPath is not exist : ${buildPath}"
|
||||||
|
}
|
||||||
|
Integer result = sh(script: "dotnet build ${buildPath} -c Release", returnStatus: true)
|
||||||
|
|
||||||
|
echo "result:${result}"
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'Build Project successfully'
|
||||||
|
} else {
|
||||||
|
error 'Build Project failed'
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - package/publish project dotnet
|
||||||
|
void publishProject(String buildPath, String publishFolderPath) {
|
||||||
|
echo 'Start publishProject'
|
||||||
|
try {
|
||||||
|
if (!fileExists(buildPath)) {
|
||||||
|
error "buildPath is not exist : ${buildPath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer result = sh(script: "dotnet publish ${buildPath} -c Release -o ${publishFolderPath}",
|
||||||
|
returnStatus: true)
|
||||||
|
|
||||||
|
echo "result : ${result}"
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'Publish Project successfully'
|
||||||
|
} else {
|
||||||
|
error 'Publish Project failed'
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - nén file
|
||||||
|
void compressItems(String compressedFilePath, String parentFolderPath) {
|
||||||
|
echo "Starting compression of the entire folder into a zip file : ${compressedFilePath}"
|
||||||
|
try {
|
||||||
|
if (fileExists(compressedFilePath)) {
|
||||||
|
echo "Old ZIP file exists. Deleting: ${compressedFilePath}"
|
||||||
|
sh "rm -f ${compressedFilePath}"
|
||||||
|
} else {
|
||||||
|
echo 'No old ZIP file found.'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fileExists(parentFolderPath)) {
|
||||||
|
error "parentFolderPath is not exist : ${parentFolderPath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
dir(parentFolderPath) {
|
||||||
|
// Thực hiện lệnh zip để nén tất cả các file trong thư mục
|
||||||
|
Integer result = sh(script: "zip -r ${compressedFilePath} * ", returnStatus: true)
|
||||||
|
|
||||||
|
// Kiểm tra kết quả
|
||||||
|
if (result == 0) {
|
||||||
|
echo "Compression completed successfully: ${compressedFilePath}"
|
||||||
|
} else {
|
||||||
|
error "Compression failed with exit code: ${result}."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void uploadToNexus(String nexusUsername, String nexusPassword, String compressedFilePath, String uploadUrl) {
|
||||||
|
echo "Starting upload ${compressedFilePath} To Nexus"
|
||||||
|
try {
|
||||||
|
// Truyền các biến môi trường vào lệnh sh mà không lộ ra trong log
|
||||||
|
String result = sh(script: """
|
||||||
|
curl -u ${nexusUsername}:${nexusPassword} --upload-file ${compressedFilePath} ${uploadUrl} -w '%{http_code}'
|
||||||
|
""", returnStdout: true).trim()
|
||||||
|
|
||||||
|
if (result == '200' || result == '201') {
|
||||||
|
echo 'uploadToNexus successfully'
|
||||||
|
} else {
|
||||||
|
error "uploadToNexus failed, HTTP status: ${result}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def createMetadataFile(
|
||||||
|
String metadataFileName,
|
||||||
|
String groupId,
|
||||||
|
String artifactId,
|
||||||
|
String version,
|
||||||
|
String nexusUrl,
|
||||||
|
String nexusArtifactName) {
|
||||||
|
echo 'Starting create metadata file'
|
||||||
|
try {
|
||||||
|
// Tạo metadata
|
||||||
|
metadata = [
|
||||||
|
groupId: groupId,
|
||||||
|
artifactId: artifactId,
|
||||||
|
version: version,
|
||||||
|
nexusUrl: nexusUrl,
|
||||||
|
nexusArtifactName: nexusArtifactName
|
||||||
|
]
|
||||||
|
|
||||||
|
// Ghi metadata vào file JSON
|
||||||
|
writeJSON file: "${metadataFileName}", json: metadata
|
||||||
|
|
||||||
|
if (!fileExists(metadataFileName)) {
|
||||||
|
error "metadataFileName is not exist : ${metadataFileName}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
-15
@@ -4,42 +4,41 @@ pipeline {
|
|||||||
environment {
|
environment {
|
||||||
GIT_CREDENTIALSID = 'd3de261f-8f1e-470b-b6d1-2fb4965e0129'
|
GIT_CREDENTIALSID = 'd3de261f-8f1e-470b-b6d1-2fb4965e0129'
|
||||||
GIT_URL = 'http://work.gct.com.vn/anhln/ACP_2025.git'
|
GIT_URL = 'http://work.gct.com.vn/anhln/ACP_2025.git'
|
||||||
GIT_BRANCH = 'main'
|
GIT_BRANCH_NAME = 'uat-portal'
|
||||||
|
|
||||||
|
ENV = 'uat'
|
||||||
PROJECT_NAME = 'portal'
|
PROJECT_NAME = 'portal'
|
||||||
|
|
||||||
|
METADATA_FILENAME = "${PROJECT_NAME}_${env.ENV}_metadata.json"
|
||||||
TRIGGER_JOB_NAME = 'CD_BE_PORTAL'
|
TRIGGER_JOB_NAME = 'CD_BE_PORTAL'
|
||||||
|
|
||||||
METADATA_FILENAME = "${PROJECT_NAME}_metadata.json"
|
|
||||||
|
|
||||||
NUGET_CONFIG_PATH = 'NuGet.config'
|
NUGET_CONFIG_PATH = 'NuGet.config'
|
||||||
APPLICATIONCORE_PATH = 'Packages'
|
APPLICATIONCORE_PATH = 'Packages'
|
||||||
JENKINS_BUILD_FOLDER_PATH = 'Portal.WebApi'
|
JENKINS_BUILD_FOLDER_PATH = 'Portal.WebApi'
|
||||||
JENKINS_PUBLISH_FOLDER_PATH = 'publish'
|
JENKINS_PUBLISH_FOLDER_PATH = "${PROJECT_NAME}-${env.ENV}-publish"
|
||||||
|
|
||||||
COMPRESSED_FILE_NAME = "${PROJECT_NAME}_publish.zip" // tên file nén
|
COMPRESSED_FILE_NAME = "${PROJECT_NAME}_${env.ENV}_publish.zip" // tên file nén
|
||||||
COMPRESSED_FILE_PATH = "${env.WORKSPACE }/${COMPRESSED_FILE_NAME}"
|
COMPRESSED_FILE_PATH = "${env.WORKSPACE }/${COMPRESSED_FILE_NAME}"
|
||||||
|
|
||||||
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
||||||
|
|
||||||
NEXUS_REPO_URL = "https://nexus.gct.com.vn/repository/${PROJECT_NAME}-backend"
|
NEXUS_REPO_URL = "https://nexus.gct.com.vn/repository/${env.ENV}-portal-backend"
|
||||||
GROUP_ID = 'vn.kinhtedothi'
|
GROUP_ID = 'vn.kinhtedothi'
|
||||||
ARTIFACT_ID = "${PROJECT_NAME}-backend-api"
|
ARTIFACT_ID = 'portal-backend-api'
|
||||||
PACKAGING = 'zip'
|
PACKAGING = 'zip'
|
||||||
VERSION = '1.0.0' // Phiên bản cơ bản
|
VERSION = '1.0.0' // Phiên bản cơ bản
|
||||||
|
|
||||||
TIMESTAMP = new Date().format('yyyyMMdd.HH', TimeZone.getTimeZone('UTC'))
|
TIMESTAMP = new Date().format('yyyyMMdd.HH', TimeZone.getTimeZone('UTC'))
|
||||||
FULL_VERSION = "${env.VERSION}-${env.TIMESTAMP}-${env.BUILD_NUMBER}" // Tạo phiên bản hoàn chỉnh
|
FULL_VERSION = "${env.VERSION}-${env.TIMESTAMP}-${env.BUILD_NUMBER}" // Tạo phiên bản hoàn chỉnh
|
||||||
|
|
||||||
TELEGRAM_CHAT_ID = -4678013464
|
SLACK_TOKEN = credentials('SLACK_TOKEN')
|
||||||
TELEGRAM_BOT_TOKEN = credentials('TELEGRAM_BOT_TOKEN')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
stage('Checkout') {
|
stage('Checkout') {
|
||||||
steps {
|
steps {
|
||||||
// Checkout mã nguồn từ Gitea
|
// Checkout mã nguồn từ Gitea
|
||||||
checkoutFromGit(env.GIT_URL as String, env.GIT_CREDENTIALSID as String, env.GIT_BRANCH as String)
|
checkoutFromGit(env.GIT_URL as String, env.GIT_CREDENTIALSID as String, env.GIT_BRANCH_NAME as String)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,16 +125,21 @@ pipeline {
|
|||||||
success {
|
success {
|
||||||
echo "Job '${env.JOB_NAME}' completed successfully. Attempting to trigger Job '${TRIGGER_JOB_NAME}'..."
|
echo "Job '${env.JOB_NAME}' completed successfully. Attempting to trigger Job '${TRIGGER_JOB_NAME}'..."
|
||||||
script {
|
script {
|
||||||
def message = "Build thành công : API - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n${env.BUILD_URL} \n Đang tiến hành Deploy...!"
|
def message = "✅Build thành công : API - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n${env.BUILD_URL} \n Đang tiến hành Deploy...!"
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
}
|
}
|
||||||
script {
|
script {
|
||||||
|
def portalNames = ['ktdt', 'hnt']
|
||||||
try {
|
try {
|
||||||
|
for (portal in portalNames) {
|
||||||
build job: "${TRIGGER_JOB_NAME}", parameters:[
|
build job: "${TRIGGER_JOB_NAME}", parameters:[
|
||||||
string(name: 'ENV', value: 'uat'),
|
string(name: 'ENV', value: env.ENV),
|
||||||
|
string(name: 'PORTAL_NAME', value: portal),
|
||||||
string(name: 'CI_JOB_BUILD_NUMBER', value: env.BUILD_NUMBER)
|
string(name: 'CI_JOB_BUILD_NUMBER', value: env.BUILD_NUMBER)
|
||||||
], propagate: false
|
], propagate: false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
echo "[ERROR] Failed to trigger job: ${TRIGGER_JOB_NAME}. Error: ${e.message}"
|
echo "[ERROR] Failed to trigger job: ${TRIGGER_JOB_NAME}. Error: ${e.message}"
|
||||||
throw e
|
throw e
|
||||||
@@ -146,8 +150,8 @@ pipeline {
|
|||||||
failure {
|
failure {
|
||||||
failure {
|
failure {
|
||||||
script {
|
script {
|
||||||
def message = "Build thất bại: API - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n Kiểm tra tại đây ${env.BUILD_URL}."
|
def message = "❌Build thất bại: API - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n Kiểm tra tại đây ${env.BUILD_URL}."
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,246 @@
|
|||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
parameters {
|
||||||
|
choice(name: 'ENV', choices: ['uat', 'production'], description: 'Choose Environment')
|
||||||
|
choice(name: 'PORTAL_NAME', choices: ['ktdt', 'hnt'], description: 'Choose Portal')
|
||||||
|
string(name: 'CI_JOB_BUILD_NUMBER', defaultValue: '', description: 'Build number of CI Job')
|
||||||
|
}
|
||||||
|
environment {
|
||||||
|
PROJECT_NAME = 'resource'
|
||||||
|
|
||||||
|
CI_UAT_JOB_NAME = 'CI-UAT-BE-RESOURCE' // tên của job build code mt uat
|
||||||
|
CI_PRODUCTION_JOB_NAME = 'CI-PRODUCTION-BE-RESOURCE' // tên của job build code mt production
|
||||||
|
|
||||||
|
CI_JOB_METADATA_FILENAME = "${PROJECT_NAME}_${params.ENV}_metadata.json" // tên file metadata đã được lưu từ ci job
|
||||||
|
|
||||||
|
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
||||||
|
|
||||||
|
ANSIBLE_SSH_CONNECTION = 'root@103.166.183.172 -p 24700'
|
||||||
|
|
||||||
|
GIT_PAT_CREDENTIALS_ID = 'd3de261f-8f1e-470b-b6d1-2fb4965e0129' // Id của Personal Access Token lưu trên jenkins
|
||||||
|
GIT_ANSIBLE_URL = 'work.gct.com.vn/thienvv/nsg_ansible.git'
|
||||||
|
GIT_ANSIBLE_BRANCH = 'v3'
|
||||||
|
|
||||||
|
ANSIBLE_FOLDER_PATH = '/srv/ansible_v3'
|
||||||
|
|
||||||
|
SLACK_TOKEN = credentials('SLACK_TOKEN')
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Set up') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
if (params.ENV == 'uat') {
|
||||||
|
env.ANSIBLE_INVENTORY_PATH = 'inventory/uat/hosts.ini'
|
||||||
|
env.CI_JOB_NAME = CI_UAT_JOB_NAME
|
||||||
|
} else if (params.ENV == 'production') {
|
||||||
|
env.ANSIBLE_INVENTORY_PATH = 'inventory/production/hosts.ini'
|
||||||
|
env.CI_JOB_NAME = CI_PRODUCTION_JOB_NAME
|
||||||
|
}
|
||||||
|
echo "ANSIBLE_INVENTORY_PATH is set to: ${env.ANSIBLE_INVENTORY_PATH}"
|
||||||
|
echo "CI_JOB_NAME is set to: ${env.CI_JOB_NAME}"
|
||||||
|
|
||||||
|
if (params.PORTAL_NAME == 'ktdt') {
|
||||||
|
env.ANSIBLE_PLAYBOOK_PATH = 'playbooks/backend/deploy_ktdt_resource_backend.yml'
|
||||||
|
} else if (params.PORTAL_NAME == 'hnt') {
|
||||||
|
env.ANSIBLE_PLAYBOOK_PATH = 'playbooks/backend/deploy_hnt_resource_backend.yml'
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "ANSIBLE_PLAYBOOK_PATH is set to: ${env.ANSIBLE_PLAYBOOK_PATH}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Retrieve Artifact Metadata From CI Job') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
def ciJobBuildNumber = params.CI_JOB_BUILD_NUMBER
|
||||||
|
echo "Retrieving artifact from CI_JOB_BUILD_NUMBER: ${ciJobBuildNumber}"
|
||||||
|
|
||||||
|
def metadata = retrieveArtifactMetadataFromCIJOB(env.CI_JOB_NAME, ciJobBuildNumber, CI_JOB_METADATA_FILENAME)
|
||||||
|
|
||||||
|
env.NEXUS_URL = metadata.nexusUrl
|
||||||
|
echo "env.NEXUS_URL : ${env.NEXUS_URL}"
|
||||||
|
|
||||||
|
env.NEXUS_ARTIFACT_NAME = metadata.nexusArtifactName
|
||||||
|
echo "env.NEXUS_ARTIFACT_NAME : ${env.NEXUS_ARTIFACT_NAME}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Checkout Ansible Code Git ') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
checkoutFromGit(
|
||||||
|
env.ANSIBLE_SSH_CONNECTION,
|
||||||
|
env.GIT_ANSIBLE_URL,
|
||||||
|
env.GIT_PAT_CREDENTIALS_ID,
|
||||||
|
env.GIT_ANSIBLE_BRANCH,
|
||||||
|
env.ANSIBLE_FOLDER_PATH
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Deploy with Ansible') {
|
||||||
|
steps {
|
||||||
|
triggerAnsible(
|
||||||
|
env.ANSIBLE_SSH_CONNECTION,
|
||||||
|
env.ANSIBLE_FOLDER_PATH,
|
||||||
|
env.ANSIBLE_INVENTORY_PATH,
|
||||||
|
env.ANSIBLE_PLAYBOOK_PATH,
|
||||||
|
env.NEXUS_URL,
|
||||||
|
env.NEXUS_ARTIFACT_NAME,
|
||||||
|
env.NEXUS_CREDENTIALS_USR,
|
||||||
|
env.NEXUS_CREDENTIALS_PSW)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
always {
|
||||||
|
echo 'Pipeline execution finished.'
|
||||||
|
}
|
||||||
|
success {
|
||||||
|
script {
|
||||||
|
def message = "✅Deploy thành công : API - Môi trường ${params.ENV} - Dự án ${env.PROJECT_NAME}- Portal_Name ${params.PORTAL_NAME}, ${currentBuild.fullDisplayName}\n${env.BUILD_URL}"
|
||||||
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
failure {
|
||||||
|
script {
|
||||||
|
def message = "❌Deploy thất bại: API - Môi trường ${params.ENV} - Dự án ${env.PROJECT_NAME} - Portal_Name ${params.PORTAL_NAME}, ${currentBuild.fullDisplayName}\n${env.BUILD_URL}"
|
||||||
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv- hàm checkout git code ansible về máy ansible
|
||||||
|
def checkoutFromGit(
|
||||||
|
String ansibleSSHConnection,
|
||||||
|
String gitUrl,
|
||||||
|
String gitAnsibleCredentialsId,
|
||||||
|
String branch,
|
||||||
|
String ansibleFolderPath) {
|
||||||
|
try {
|
||||||
|
// kiểm tra đã tồn tại code ansible trên thư mục của máy ansible
|
||||||
|
Boolean repoExists = sh(
|
||||||
|
script: """
|
||||||
|
ssh -v ${ansibleSSHConnection} \\
|
||||||
|
' [ -d ${ansibleFolderPath}/.git ] && echo '1' || echo '0' '
|
||||||
|
""",
|
||||||
|
returnStdout: true
|
||||||
|
).trim() == '1'
|
||||||
|
|
||||||
|
withCredentials([usernamePassword(
|
||||||
|
credentialsId: gitAnsibleCredentialsId,
|
||||||
|
usernameVariable: 'GIT_USERNAME',
|
||||||
|
passwordVariable: 'GIT_PAT')]) {
|
||||||
|
if (repoExists) { // nếu tồn tại source code ansible rồi thì pull về
|
||||||
|
echo "Repository already exists on ${ansibleFolderPath}. Pulling latest changes..."
|
||||||
|
|
||||||
|
Integer result = sh(script: """
|
||||||
|
ssh -v ${ansibleSSHConnection} \\
|
||||||
|
'cd ${ansibleFolderPath} && \\
|
||||||
|
git reset --hard && \\
|
||||||
|
git clean -fd && \\
|
||||||
|
git fetch origin && \\
|
||||||
|
git checkout ${branch} && \\
|
||||||
|
git pull origin ${branch} -vvvv '
|
||||||
|
""", returnStatus: true)
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'Pull ansible code successfully'
|
||||||
|
} else {
|
||||||
|
error "Pull ansible code failed, status: ${result}"
|
||||||
|
}
|
||||||
|
} else { //nếu chưa tồn tại code ansible
|
||||||
|
Integer result = sh(script: """
|
||||||
|
ssh -v ${ansibleSSHConnection} \\
|
||||||
|
'git clone --branch ${branch} http://${GIT_USERNAME}@${gitUrl} ${ansibleFolderPath} -vvvv '
|
||||||
|
""", returnStatus: true)
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'Clone ansible code successfully'
|
||||||
|
} else {
|
||||||
|
error "Clone ansible code failed, status: ${result}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Hàm lấy artifact metadata file từ CI job
|
||||||
|
def retrieveArtifactMetadataFromCIJOB(String ciJobName, String ciJobBuildNumber, String metadataFilename) {
|
||||||
|
try {
|
||||||
|
def selector = null
|
||||||
|
|
||||||
|
if (ciJobBuildNumber != '') { // nếu ciJobBuildNumber khác rỗng thì
|
||||||
|
selector = [$class: 'SpecificBuildSelector', buildNumber: ciJobBuildNumber] // selector = ciJobBuildNumber
|
||||||
|
} else { //còn nếu ciJobBuildNumber = rỗng thì
|
||||||
|
selector = lastSuccessful() //selector = build thành công gần nhất
|
||||||
|
}
|
||||||
|
// Sao chép artifact từ dự án khác
|
||||||
|
copyArtifacts projectName: ciJobName,
|
||||||
|
selector: selector,
|
||||||
|
filter: metadataFilename,
|
||||||
|
target: '.'
|
||||||
|
|
||||||
|
// Kiểm tra sự tồn tại của file metadata
|
||||||
|
if (!fileExists(metadataFilename)) {
|
||||||
|
error "File ${metadataFilename} not found after copyArtifacts!"
|
||||||
|
} else {
|
||||||
|
echo "File ${metadataFilename} successfully copied."
|
||||||
|
}
|
||||||
|
|
||||||
|
// Đọc dữ liệu từ file JSON
|
||||||
|
def metadata = readJSON file: metadataFilename
|
||||||
|
|
||||||
|
return metadata
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def triggerAnsible(
|
||||||
|
String sshAnsibleConnection,
|
||||||
|
String ansibleansibleFolderPath,
|
||||||
|
String inventoryPath,
|
||||||
|
String playbookPath,
|
||||||
|
String nexusUrl,
|
||||||
|
String nexusArtifactName,
|
||||||
|
String nexusUsername,
|
||||||
|
String nexusPassword) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Integer result = sh(
|
||||||
|
script: """
|
||||||
|
ssh ${sshAnsibleConnection} "
|
||||||
|
cd ${ansibleansibleFolderPath} &&
|
||||||
|
ansible-playbook -i ${inventoryPath} ${playbookPath} \\
|
||||||
|
-e ' nexus_url=${nexusUrl} \\
|
||||||
|
artifact_name=${nexusArtifactName} \\
|
||||||
|
nexus_username=${nexusUsername} \\
|
||||||
|
nexus_password=${nexusPassword}' -vvvv
|
||||||
|
"
|
||||||
|
""",
|
||||||
|
returnStatus: true
|
||||||
|
)
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'triggerAnsible successfully'
|
||||||
|
} else {
|
||||||
|
error "triggerAnsible failed, status: ${result}"
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,379 @@
|
|||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
options { disableConcurrentBuilds(abortPrevious: true) }
|
||||||
|
environment {
|
||||||
|
GIT_CREDENTIALSID = 'd3de261f-8f1e-470b-b6d1-2fb4965e0129'
|
||||||
|
GIT_URL = 'http://work.gct.com.vn/anhln/ACP_2025.git'
|
||||||
|
GIT_BRANCH_NAME = 'production-resource'
|
||||||
|
|
||||||
|
ENV = 'production'
|
||||||
|
PROJECT_NAME = 'resource'
|
||||||
|
|
||||||
|
METADATA_FILENAME = "${PROJECT_NAME}_${env.ENV}_metadata.json"
|
||||||
|
TRIGGER_JOB_NAME = 'CD-BE-RESOURCE'
|
||||||
|
|
||||||
|
NUGET_CONFIG_PATH = 'NuGet.config'
|
||||||
|
APPLICATIONCORE_PATH = 'Packages'
|
||||||
|
JENKINS_BUILD_FOLDER_PATH = 'Resource.WebApi'
|
||||||
|
JENKINS_PUBLISH_FOLDER_PATH = "${PROJECT_NAME}-${env.ENV}-publish"
|
||||||
|
|
||||||
|
COMPRESSED_FILE_NAME = "${PROJECT_NAME}_${env.ENV}_publish.zip" // tên file nén
|
||||||
|
COMPRESSED_FILE_PATH = "${env.WORKSPACE }/${COMPRESSED_FILE_NAME}"
|
||||||
|
|
||||||
|
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
||||||
|
|
||||||
|
NEXUS_REPO_URL = "https://nexus.gct.com.vn/repository/${env.ENV}-resource-backend"
|
||||||
|
GROUP_ID = 'vn.kinhtedothi'
|
||||||
|
ARTIFACT_ID = 'resource-backend-api'
|
||||||
|
PACKAGING = 'zip'
|
||||||
|
VERSION = '1.0.0' // Phiên bản cơ bản
|
||||||
|
|
||||||
|
TIMESTAMP = new Date().format('yyyyMMdd.HH', TimeZone.getTimeZone('UTC'))
|
||||||
|
FULL_VERSION = "${env.VERSION}-${env.TIMESTAMP}-${env.BUILD_NUMBER}" // Tạo phiên bản hoàn chỉnh
|
||||||
|
|
||||||
|
SLACK_TOKEN = credentials('SLACK_TOKEN')
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Checkout') {
|
||||||
|
steps {
|
||||||
|
// Checkout mã nguồn từ Gitea
|
||||||
|
checkoutFromGit(env.GIT_URL as String, env.GIT_CREDENTIALSID as String, env.GIT_BRANCH_NAME as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Clear Nuget caches') {
|
||||||
|
steps {
|
||||||
|
// Xóa cache của NuGet
|
||||||
|
clearNuGetCaches()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Setup Nuget.Config') {
|
||||||
|
steps {
|
||||||
|
// Thiết lập tệp NuGet.config
|
||||||
|
setupNuGetConfig(env.APPLICATIONCORE_PATH as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Restore') {
|
||||||
|
steps {
|
||||||
|
// Gọi hàm để thực hiện restore
|
||||||
|
restoreNuGetPackages(env.JENKINS_BUILD_FOLDER_PATH as String , env.NUGET_CONFIG_PATH as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Clean & Build') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
cleanProject(env.JENKINS_BUILD_FOLDER_PATH as String)
|
||||||
|
buildProject(env.JENKINS_BUILD_FOLDER_PATH as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Publish') {
|
||||||
|
steps {
|
||||||
|
publishProject(env.JENKINS_BUILD_FOLDER_PATH as String, env.JENKINS_PUBLISH_FOLDER_PATH as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Package (Compress Publish Files)') {
|
||||||
|
steps {
|
||||||
|
compressItems(env.COMPRESSED_FILE_PATH, env.JENKINS_PUBLISH_FOLDER_PATH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Upload to Nexus') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
String groupPath = env.GROUP_ID.replace('.', '/')
|
||||||
|
env.NEXUS_URL = "${env.NEXUS_REPO_URL}/${groupPath}/${env.ARTIFACT_ID}/${env.VERSION}"
|
||||||
|
env.NEXUS_ARTIFACT_NAME = "${env.ARTIFACT_ID}-${env.FULL_VERSION}.${env.PACKAGING}"
|
||||||
|
|
||||||
|
String nexusUploadUrl = "${env.NEXUS_URL}/${env.NEXUS_ARTIFACT_NAME}"
|
||||||
|
|
||||||
|
uploadToNexus(
|
||||||
|
env.NEXUS_CREDENTIALS_USR,
|
||||||
|
env.NEXUS_CREDENTIALS_PSW,
|
||||||
|
env.COMPRESSED_FILE_PATH,
|
||||||
|
nexusUploadUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Create Metadata File') {
|
||||||
|
steps {
|
||||||
|
createMetadataFile(
|
||||||
|
env.METADATA_FILENAME,
|
||||||
|
env.GROUP_ID,
|
||||||
|
env.ARTIFACT_ID,
|
||||||
|
env.VERSION,
|
||||||
|
env.NEXUS_URL,
|
||||||
|
env.NEXUS_ARTIFACT_NAME)
|
||||||
|
echo "metadataFileName: ${env.METADATA_FILENAME}"
|
||||||
|
archiveArtifacts artifacts: "${env.METADATA_FILENAME}", allowEmptyArchive: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
always {
|
||||||
|
echo 'Pipeline execution finished.'
|
||||||
|
}
|
||||||
|
success {
|
||||||
|
echo "Job '${env.JOB_NAME}' completed successfully. Attempting to trigger Job '${TRIGGER_JOB_NAME}'..."
|
||||||
|
script {
|
||||||
|
def message = "✅Build thành công : API - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n${env.BUILD_URL} \n Đang tiến hành Deploy...!"
|
||||||
|
// sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
||||||
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
failure {
|
||||||
|
script {
|
||||||
|
def message = "❌Build thất bại: API - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n Kiểm tra tại đây ${env.BUILD_URL}."
|
||||||
|
// sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
||||||
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv- hàm checkout git
|
||||||
|
void checkoutFromGit(String gitUrl, String credentialsId, String branch) {
|
||||||
|
try {
|
||||||
|
echo 'Start checkoutFromGit'
|
||||||
|
|
||||||
|
checkout([$class : 'GitSCM',
|
||||||
|
userRemoteConfigs: [[url: gitUrl, credentialsId: credentialsId]],
|
||||||
|
branches : [[name: "*/${branch}"]]])
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv- clear nuget caches
|
||||||
|
void clearNuGetCaches() {
|
||||||
|
try {
|
||||||
|
// Xóa cache của NuGet
|
||||||
|
Integer result = sh(script: 'dotnet nuget locals all --clear', returnStatus: true)
|
||||||
|
|
||||||
|
echo "result:${result}"
|
||||||
|
|
||||||
|
// Kiểm tra trạng thái trả về
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'NuGet caches cleared successfully.'
|
||||||
|
} else {
|
||||||
|
error "Failed to clear NuGet caches with status: ${result}"
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - Hàm set up file Nuget.config để restore các package dependencies
|
||||||
|
void setupNuGetConfig(String applicationCorePath) {
|
||||||
|
try {
|
||||||
|
writeFile file: 'NuGet.config', text: """<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
|
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||||
|
<add key="Package source" value="${applicationCorePath}" />
|
||||||
|
</packageSources>
|
||||||
|
</configuration>"""
|
||||||
|
|
||||||
|
// Kiểm tra xem tệp đã được ghi thành công
|
||||||
|
if (fileExists('NuGet.config')) {
|
||||||
|
echo 'NuGet.config has been created successfully.'
|
||||||
|
} else {
|
||||||
|
error 'Failed to create NuGet.config.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Thienvv - Định nghĩa hàm để restore các gói NuGet
|
||||||
|
// Thienvv - Định nghĩa hàm để restore các gói NuGet
|
||||||
|
void restoreNuGetPackages(String restorePath, String nugetConfigPath) {
|
||||||
|
echo 'Starting NuGet packages restore...'
|
||||||
|
try {
|
||||||
|
if (!fileExists(restorePath)) {
|
||||||
|
error "restorePath is not exist : ${restorePath}"
|
||||||
|
}
|
||||||
|
if (!fileExists(nugetConfigPath)) {
|
||||||
|
error "nugetConfigPath is not exist : ${nugetConfigPath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Thực hiện restore các gói NuGet cần thiết
|
||||||
|
Integer result = sh(script: "dotnet restore ${restorePath} --configfile ${nugetConfigPath}", returnStatus: true)
|
||||||
|
|
||||||
|
// Kiểm tra kết quả trả về
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'NuGet packages restored successfully.'
|
||||||
|
} else {
|
||||||
|
error "Restore NuGet packages failed with exit code: ${result}. Check NuGet config and restore path."
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - clean project dotnet
|
||||||
|
void cleanProject(String buildPath) {
|
||||||
|
echo 'Start cleanProject'
|
||||||
|
try {
|
||||||
|
if (!fileExists(buildPath)) {
|
||||||
|
error "buildPath is not exist : ${buildPath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer result = sh(script: "dotnet clean ${buildPath}", returnStatus: true)
|
||||||
|
|
||||||
|
echo "result:${result}"
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'Clean Project successfully'
|
||||||
|
} else {
|
||||||
|
error 'Clean Projectfailed'
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - build project dotnet
|
||||||
|
void buildProject(String buildPath) {
|
||||||
|
echo 'Start buildProject'
|
||||||
|
try {
|
||||||
|
if (!fileExists(buildPath)) {
|
||||||
|
error "buildPath is not exist : ${buildPath}"
|
||||||
|
}
|
||||||
|
Integer result = sh(script: "dotnet build ${buildPath} -c Release", returnStatus: true)
|
||||||
|
|
||||||
|
echo "result:${result}"
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'Build Project successfully'
|
||||||
|
} else {
|
||||||
|
error 'Build Project failed'
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - package/publish project dotnet
|
||||||
|
void publishProject(String buildPath, String publishFolderPath) {
|
||||||
|
echo 'Start publishProject'
|
||||||
|
try {
|
||||||
|
if (!fileExists(buildPath)) {
|
||||||
|
error "buildPath is not exist : ${buildPath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer result = sh(script: "dotnet publish ${buildPath} -c Release -o ${publishFolderPath}",
|
||||||
|
returnStatus: true)
|
||||||
|
|
||||||
|
echo "result : ${result}"
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'Publish Project successfully'
|
||||||
|
} else {
|
||||||
|
error 'Publish Project failed'
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - nén file
|
||||||
|
void compressItems(String compressedFilePath, String parentFolderPath) {
|
||||||
|
echo "Starting compression of the entire folder into a zip file : ${compressedFilePath}"
|
||||||
|
try {
|
||||||
|
if (fileExists(compressedFilePath)) {
|
||||||
|
echo "Old ZIP file exists. Deleting: ${compressedFilePath}"
|
||||||
|
sh "rm -f ${compressedFilePath}"
|
||||||
|
} else {
|
||||||
|
echo 'No old ZIP file found.'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fileExists(parentFolderPath)) {
|
||||||
|
error "parentFolderPath is not exist : ${parentFolderPath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
dir(parentFolderPath) {
|
||||||
|
// Thực hiện lệnh zip để nén tất cả các file trong thư mục
|
||||||
|
Integer result = sh(script: "zip -r ${compressedFilePath} * ", returnStatus: true)
|
||||||
|
|
||||||
|
// Kiểm tra kết quả
|
||||||
|
if (result == 0) {
|
||||||
|
echo "Compression completed successfully: ${compressedFilePath}"
|
||||||
|
} else {
|
||||||
|
error "Compression failed with exit code: ${result}."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void uploadToNexus(String nexusUsername, String nexusPassword, String compressedFilePath, String uploadUrl) {
|
||||||
|
echo "Starting upload ${compressedFilePath} To Nexus"
|
||||||
|
try {
|
||||||
|
// Truyền các biến môi trường vào lệnh sh mà không lộ ra trong log
|
||||||
|
String result = sh(script: """
|
||||||
|
curl -u ${nexusUsername}:${nexusPassword} --upload-file ${compressedFilePath} ${uploadUrl} -w '%{http_code}'
|
||||||
|
""", returnStdout: true).trim()
|
||||||
|
|
||||||
|
if (result == '200' || result == '201') {
|
||||||
|
echo 'uploadToNexus successfully'
|
||||||
|
} else {
|
||||||
|
error "uploadToNexus failed, HTTP status: ${result}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def createMetadataFile(
|
||||||
|
String metadataFileName,
|
||||||
|
String groupId,
|
||||||
|
String artifactId,
|
||||||
|
String version,
|
||||||
|
String nexusUrl,
|
||||||
|
String nexusArtifactName) {
|
||||||
|
echo 'Starting create metadata file'
|
||||||
|
try {
|
||||||
|
// Tạo metadata
|
||||||
|
metadata = [
|
||||||
|
groupId: groupId,
|
||||||
|
artifactId: artifactId,
|
||||||
|
version: version,
|
||||||
|
nexusUrl: nexusUrl,
|
||||||
|
nexusArtifactName: nexusArtifactName
|
||||||
|
]
|
||||||
|
|
||||||
|
// Ghi metadata vào file JSON
|
||||||
|
writeJSON file: "${metadataFileName}", json: metadata
|
||||||
|
|
||||||
|
if (!fileExists(metadataFileName)) {
|
||||||
|
error "metadataFileName is not exist : ${metadataFileName}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,392 @@
|
|||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
options { disableConcurrentBuilds(abortPrevious: true) }
|
||||||
|
environment {
|
||||||
|
GIT_CREDENTIALSID = 'd3de261f-8f1e-470b-b6d1-2fb4965e0129'
|
||||||
|
GIT_URL = 'http://work.gct.com.vn/anhln/ACP_2025.git'
|
||||||
|
GIT_BRANCH_NAME = 'uat-resource'
|
||||||
|
|
||||||
|
ENV = 'uat'
|
||||||
|
PROJECT_NAME = 'resource'
|
||||||
|
|
||||||
|
METADATA_FILENAME = "${PROJECT_NAME}_${env.ENV}_metadata.json"
|
||||||
|
TRIGGER_JOB_NAME = 'CD-BE-RESOURCE'
|
||||||
|
|
||||||
|
NUGET_CONFIG_PATH = 'NuGet.config'
|
||||||
|
APPLICATIONCORE_PATH = 'Packages'
|
||||||
|
JENKINS_BUILD_FOLDER_PATH = 'Resource.WebApi'
|
||||||
|
JENKINS_PUBLISH_FOLDER_PATH = "${PROJECT_NAME}-${env.ENV}-publish"
|
||||||
|
|
||||||
|
COMPRESSED_FILE_NAME = "${PROJECT_NAME}_${env.ENV}_publish.zip" // tên file nén
|
||||||
|
COMPRESSED_FILE_PATH = "${env.WORKSPACE }/${COMPRESSED_FILE_NAME}"
|
||||||
|
|
||||||
|
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
||||||
|
|
||||||
|
NEXUS_REPO_URL = "https://nexus.gct.com.vn/repository/${env.ENV}-resource-backend"
|
||||||
|
GROUP_ID = 'vn.kinhtedothi'
|
||||||
|
ARTIFACT_ID = 'resource-backend-api'
|
||||||
|
PACKAGING = 'zip'
|
||||||
|
VERSION = '1.0.0' // Phiên bản cơ bản
|
||||||
|
|
||||||
|
TIMESTAMP = new Date().format('yyyyMMdd.HH', TimeZone.getTimeZone('UTC'))
|
||||||
|
FULL_VERSION = "${env.VERSION}-${env.TIMESTAMP}-${env.BUILD_NUMBER}" // Tạo phiên bản hoàn chỉnh
|
||||||
|
|
||||||
|
SLACK_TOKEN = credentials('SLACK_TOKEN')
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Checkout') {
|
||||||
|
steps {
|
||||||
|
// Checkout mã nguồn từ Gitea
|
||||||
|
checkoutFromGit(env.GIT_URL as String, env.GIT_CREDENTIALSID as String, env.GIT_BRANCH_NAME as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Clear Nuget caches') {
|
||||||
|
steps {
|
||||||
|
// Xóa cache của NuGet
|
||||||
|
clearNuGetCaches()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Setup Nuget.Config') {
|
||||||
|
steps {
|
||||||
|
// Thiết lập tệp NuGet.config
|
||||||
|
setupNuGetConfig(env.APPLICATIONCORE_PATH as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Restore') {
|
||||||
|
steps {
|
||||||
|
// Gọi hàm để thực hiện restore
|
||||||
|
restoreNuGetPackages(env.JENKINS_BUILD_FOLDER_PATH as String , env.NUGET_CONFIG_PATH as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Clean & Build') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
cleanProject(env.JENKINS_BUILD_FOLDER_PATH as String)
|
||||||
|
buildProject(env.JENKINS_BUILD_FOLDER_PATH as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Publish') {
|
||||||
|
steps {
|
||||||
|
publishProject(env.JENKINS_BUILD_FOLDER_PATH as String, env.JENKINS_PUBLISH_FOLDER_PATH as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Package (Compress Publish Files)') {
|
||||||
|
steps {
|
||||||
|
compressItems(env.COMPRESSED_FILE_PATH, env.JENKINS_PUBLISH_FOLDER_PATH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Upload to Nexus') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
String groupPath = env.GROUP_ID.replace('.', '/')
|
||||||
|
env.NEXUS_URL = "${env.NEXUS_REPO_URL}/${groupPath}/${env.ARTIFACT_ID}/${env.VERSION}"
|
||||||
|
env.NEXUS_ARTIFACT_NAME = "${env.ARTIFACT_ID}-${env.FULL_VERSION}.${env.PACKAGING}"
|
||||||
|
|
||||||
|
String nexusUploadUrl = "${env.NEXUS_URL}/${env.NEXUS_ARTIFACT_NAME}"
|
||||||
|
|
||||||
|
uploadToNexus(
|
||||||
|
env.NEXUS_CREDENTIALS_USR,
|
||||||
|
env.NEXUS_CREDENTIALS_PSW,
|
||||||
|
env.COMPRESSED_FILE_PATH,
|
||||||
|
nexusUploadUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Create Metadata File') {
|
||||||
|
steps {
|
||||||
|
createMetadataFile(
|
||||||
|
env.METADATA_FILENAME,
|
||||||
|
env.GROUP_ID,
|
||||||
|
env.ARTIFACT_ID,
|
||||||
|
env.VERSION,
|
||||||
|
env.NEXUS_URL,
|
||||||
|
env.NEXUS_ARTIFACT_NAME)
|
||||||
|
echo "metadataFileName: ${env.METADATA_FILENAME}"
|
||||||
|
archiveArtifacts artifacts: "${env.METADATA_FILENAME}", allowEmptyArchive: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
always {
|
||||||
|
echo 'Pipeline execution finished.'
|
||||||
|
}
|
||||||
|
success {
|
||||||
|
echo "Job '${env.JOB_NAME}' completed successfully. Attempting to trigger Job '${TRIGGER_JOB_NAME}'..."
|
||||||
|
script {
|
||||||
|
def message = "✅Build thành công : API - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n${env.BUILD_URL} \n Đang tiến hành Deploy...!"
|
||||||
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
}
|
||||||
|
script {
|
||||||
|
try {
|
||||||
|
def buildResult = build job: "${TRIGGER_JOB_NAME}", parameters:[
|
||||||
|
string(name: 'ENV', value: env.ENV),
|
||||||
|
string(name: 'CI_JOB_BUILD_NUMBER', value: env.BUILD_NUMBER)
|
||||||
|
],
|
||||||
|
propagate: false
|
||||||
|
if (buildResult.result != 'SUCCESS') {
|
||||||
|
echo "[WARNING] Job 2 failed with result: ${buildResult.result}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
echo "[ERROR] Failed to trigger job: ${TRIGGER_JOB_NAME}. Error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
failure {
|
||||||
|
script {
|
||||||
|
def message = "❌Build thất bại: API - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n Kiểm tra tại đây ${env.BUILD_URL}."
|
||||||
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv- hàm checkout git
|
||||||
|
void checkoutFromGit(String gitUrl, String credentialsId, String branch) {
|
||||||
|
try {
|
||||||
|
echo 'Start checkoutFromGit'
|
||||||
|
|
||||||
|
checkout([$class : 'GitSCM',
|
||||||
|
userRemoteConfigs: [[url: gitUrl, credentialsId: credentialsId]],
|
||||||
|
branches : [[name: "*/${branch}"]]])
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv- clear nuget caches
|
||||||
|
void clearNuGetCaches() {
|
||||||
|
try {
|
||||||
|
// Xóa cache của NuGet
|
||||||
|
Integer result = sh(script: 'dotnet nuget locals all --clear', returnStatus: true)
|
||||||
|
|
||||||
|
echo "result:${result}"
|
||||||
|
|
||||||
|
// Kiểm tra trạng thái trả về
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'NuGet caches cleared successfully.'
|
||||||
|
} else {
|
||||||
|
error "Failed to clear NuGet caches with status: ${result}"
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - Hàm set up file Nuget.config để restore các package dependencies
|
||||||
|
void setupNuGetConfig(String applicationCorePath) {
|
||||||
|
try {
|
||||||
|
writeFile file: 'NuGet.config', text: """<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
|
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||||
|
<add key="Package source" value="${applicationCorePath}" />
|
||||||
|
</packageSources>
|
||||||
|
</configuration>"""
|
||||||
|
|
||||||
|
// Kiểm tra xem tệp đã được ghi thành công
|
||||||
|
if (fileExists('NuGet.config')) {
|
||||||
|
echo 'NuGet.config has been created successfully.'
|
||||||
|
} else {
|
||||||
|
error 'Failed to create NuGet.config.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Thienvv - Định nghĩa hàm để restore các gói NuGet
|
||||||
|
// Thienvv - Định nghĩa hàm để restore các gói NuGet
|
||||||
|
void restoreNuGetPackages(String restorePath, String nugetConfigPath) {
|
||||||
|
echo 'Starting NuGet packages restore...'
|
||||||
|
try {
|
||||||
|
if (!fileExists(restorePath)) {
|
||||||
|
error "restorePath is not exist : ${restorePath}"
|
||||||
|
}
|
||||||
|
if (!fileExists(nugetConfigPath)) {
|
||||||
|
error "nugetConfigPath is not exist : ${nugetConfigPath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Thực hiện restore các gói NuGet cần thiết
|
||||||
|
Integer result = sh(script: "dotnet restore ${restorePath} --configfile ${nugetConfigPath}", returnStatus: true)
|
||||||
|
|
||||||
|
// Kiểm tra kết quả trả về
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'NuGet packages restored successfully.'
|
||||||
|
} else {
|
||||||
|
error "Restore NuGet packages failed with exit code: ${result}. Check NuGet config and restore path."
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - clean project dotnet
|
||||||
|
void cleanProject(String buildPath) {
|
||||||
|
echo 'Start cleanProject'
|
||||||
|
try {
|
||||||
|
if (!fileExists(buildPath)) {
|
||||||
|
error "buildPath is not exist : ${buildPath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer result = sh(script: "dotnet clean ${buildPath}", returnStatus: true)
|
||||||
|
|
||||||
|
echo "result:${result}"
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'Clean Project successfully'
|
||||||
|
} else {
|
||||||
|
error 'Clean Projectfailed'
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - build project dotnet
|
||||||
|
void buildProject(String buildPath) {
|
||||||
|
echo 'Start buildProject'
|
||||||
|
try {
|
||||||
|
if (!fileExists(buildPath)) {
|
||||||
|
error "buildPath is not exist : ${buildPath}"
|
||||||
|
}
|
||||||
|
Integer result = sh(script: "dotnet build ${buildPath} -c Release", returnStatus: true)
|
||||||
|
|
||||||
|
echo "result:${result}"
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'Build Project successfully'
|
||||||
|
} else {
|
||||||
|
error 'Build Project failed'
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - package/publish project dotnet
|
||||||
|
void publishProject(String buildPath, String publishFolderPath) {
|
||||||
|
echo 'Start publishProject'
|
||||||
|
try {
|
||||||
|
if (!fileExists(buildPath)) {
|
||||||
|
error "buildPath is not exist : ${buildPath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer result = sh(script: "dotnet publish ${buildPath} -c Release -o ${publishFolderPath}",
|
||||||
|
returnStatus: true)
|
||||||
|
|
||||||
|
echo "result : ${result}"
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
echo 'Publish Project successfully'
|
||||||
|
} else {
|
||||||
|
error 'Publish Project failed'
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thienvv - nén file
|
||||||
|
void compressItems(String compressedFilePath, String parentFolderPath) {
|
||||||
|
echo "Starting compression of the entire folder into a zip file : ${compressedFilePath}"
|
||||||
|
try {
|
||||||
|
if (fileExists(compressedFilePath)) {
|
||||||
|
echo "Old ZIP file exists. Deleting: ${compressedFilePath}"
|
||||||
|
sh "rm -f ${compressedFilePath}"
|
||||||
|
} else {
|
||||||
|
echo 'No old ZIP file found.'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fileExists(parentFolderPath)) {
|
||||||
|
error "parentFolderPath is not exist : ${parentFolderPath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
dir(parentFolderPath) {
|
||||||
|
// Thực hiện lệnh zip để nén tất cả các file trong thư mục
|
||||||
|
Integer result = sh(script: "zip -r ${compressedFilePath} * ", returnStatus: true)
|
||||||
|
|
||||||
|
// Kiểm tra kết quả
|
||||||
|
if (result == 0) {
|
||||||
|
echo "Compression completed successfully: ${compressedFilePath}"
|
||||||
|
} else {
|
||||||
|
error "Compression failed with exit code: ${result}."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void uploadToNexus(String nexusUsername, String nexusPassword, String compressedFilePath, String uploadUrl) {
|
||||||
|
echo "Starting upload ${compressedFilePath} To Nexus"
|
||||||
|
try {
|
||||||
|
// Truyền các biến môi trường vào lệnh sh mà không lộ ra trong log
|
||||||
|
String result = sh(script: """
|
||||||
|
curl -u ${nexusUsername}:${nexusPassword} --upload-file ${compressedFilePath} ${uploadUrl} -w '%{http_code}'
|
||||||
|
""", returnStdout: true).trim()
|
||||||
|
|
||||||
|
if (result == '200' || result == '201') {
|
||||||
|
echo 'uploadToNexus successfully'
|
||||||
|
} else {
|
||||||
|
error "uploadToNexus failed, HTTP status: ${result}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def createMetadataFile(
|
||||||
|
String metadataFileName,
|
||||||
|
String groupId,
|
||||||
|
String artifactId,
|
||||||
|
String version,
|
||||||
|
String nexusUrl,
|
||||||
|
String nexusArtifactName) {
|
||||||
|
echo 'Starting create metadata file'
|
||||||
|
try {
|
||||||
|
// Tạo metadata
|
||||||
|
metadata = [
|
||||||
|
groupId: groupId,
|
||||||
|
artifactId: artifactId,
|
||||||
|
version: version,
|
||||||
|
nexusUrl: nexusUrl,
|
||||||
|
nexusArtifactName: nexusArtifactName
|
||||||
|
]
|
||||||
|
|
||||||
|
// Ghi metadata vào file JSON
|
||||||
|
writeJSON file: "${metadataFileName}", json: metadata
|
||||||
|
|
||||||
|
if (!fileExists(metadataFileName)) {
|
||||||
|
error "metadataFileName is not exist : ${metadataFileName}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
echo "[ERROR] Unexpected error: ${e.message}"
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,32 +1,43 @@
|
|||||||
pipeline {
|
pipeline {
|
||||||
agent any
|
agent any
|
||||||
parameters {
|
parameters {
|
||||||
choice(name: 'ENV', choices: ['prod', 'uat'], description: 'Choose Environment')
|
choice(name: 'ENV', choices: ['uat', 'production'], description: 'Choose Environment')
|
||||||
string(name: 'CI_JOB_BUILD_NUMBER', defaultValue: '', description: 'Build number of CI Job')
|
string(name: 'CI_JOB_BUILD_NUMBER', defaultValue: '', description: 'Build number of CI Job')
|
||||||
}
|
}
|
||||||
environment {
|
environment {
|
||||||
PROJECT_NAME = 'acp'
|
PROJECT_NAME = 'acp'
|
||||||
CI_JOB_NAME_UAT = 'CI-UAT-FE-ACP' // tên của job build code môi trường uat
|
CI_JOB_NAME_UAT = 'CI-UAT-FE-ACP' // tên của job build code môi trường uat
|
||||||
CI_JOB_NAME_PROD = 'CI-PROD-FE-ACP' // tên của job build code môi trường prod
|
CI_JOB_NAME_PRODUCTION = 'CI-PRODUCTION-FE-ACP' // tên của job build code môi trường beta
|
||||||
|
|
||||||
CI_JOB_METADATA_FILENAME = "${params.ENV}_${PROJECT_NAME}_metadata.json" // tên file metadata đã được lưu từ job build code
|
CI_JOB_METADATA_FILENAME = "${params.ENV}_${PROJECT_NAME}_metadata.json" // tên file metadata đã được lưu từ job build code
|
||||||
|
|
||||||
GIT_PAT_CREDENTIALS_ID = 'b03f36c4-bba3-4764-94ca-b620651b2a68' // Id của Personal Access Token lưu trên jenkins
|
GIT_PAT_CREDENTIALS_ID = 'b03f36c4-bba3-4764-94ca-b620651b2a68' // Id của Personal Access Token lưu trên jenkins
|
||||||
GIT_ANSIBLE_URL = 'work.gct.com.vn/thienvv/nsg_ansible.git'
|
GIT_ANSIBLE_URL = 'work.gct.com.vn/thienvv/nsg_ansible.git'
|
||||||
GIT_ANSIBLE_BRANCH = 'v2'
|
GIT_ANSIBLE_BRANCH = 'v3'
|
||||||
|
|
||||||
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
||||||
ANSIBLE_SSH_CONNECTION = 'root@103.166.183.172 -p 24700'
|
ANSIBLE_SSH_CONNECTION = 'root@103.166.183.172 -p 24700'
|
||||||
|
|
||||||
ANSIBLE_FOLDER_PATH = '/srv/ansible_v2'
|
ANSIBLE_FOLDER_PATH = '/srv/ansible_v3'
|
||||||
ANSIBLE_INVENTORY_PATH = "inventory/${params.ENV}.ini"
|
ANSIBLE_PLAYBOOK_PATH = 'playbooks/frontend/deploy_acp_frontend.yml'
|
||||||
ANSIBLE_PLAYBOOK_PATH = 'playbooks/deploy_fe.yml'
|
|
||||||
|
|
||||||
TELEGRAM_CHAT_ID = -4678013464
|
SLACK_TOKEN = credentials('SLACK_TOKEN')
|
||||||
TELEGRAM_BOT_TOKEN = credentials('TELEGRAM_BOT_TOKEN')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
|
stage('Set up') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
if (params.ENV == 'uat') {
|
||||||
|
env.ANSIBLE_INVENTORY_PATH = 'inventory/uat/hosts.ini'
|
||||||
|
} else if (params.ENV == 'production') {
|
||||||
|
env.ANSIBLE_INVENTORY_PATH = 'inventory/production/hosts.ini'
|
||||||
|
}
|
||||||
|
echo "ANSIBLE_INVENTORY_PATH is set to: ${env.ANSIBLE_INVENTORY_PATH}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stage('Retrieve Artifact Metadata From CI Job') {
|
stage('Retrieve Artifact Metadata From CI Job') {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
@@ -34,8 +45,8 @@ pipeline {
|
|||||||
case 'uat':
|
case 'uat':
|
||||||
env.CI_JOB_NAME = env.CI_JOB_NAME_UAT
|
env.CI_JOB_NAME = env.CI_JOB_NAME_UAT
|
||||||
break
|
break
|
||||||
case 'prod':
|
case 'production':
|
||||||
env.CI_JOB_NAME = env.CI_JOB_NAME_PROD
|
env.CI_JOB_NAME = env.CI_JOB_NAME_PRODUCTION
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
error "Unsupported environment: ${params.ENV}"
|
error "Unsupported environment: ${params.ENV}"
|
||||||
@@ -79,8 +90,6 @@ pipeline {
|
|||||||
env.ANSIBLE_FOLDER_PATH,
|
env.ANSIBLE_FOLDER_PATH,
|
||||||
env.ANSIBLE_INVENTORY_PATH,
|
env.ANSIBLE_INVENTORY_PATH,
|
||||||
env.ANSIBLE_PLAYBOOK_PATH,
|
env.ANSIBLE_PLAYBOOK_PATH,
|
||||||
params.ENV,
|
|
||||||
env.PROJECT_NAME,
|
|
||||||
env.NEXUS_URL,
|
env.NEXUS_URL,
|
||||||
env.NEXUS_ARTIFACT_NAME,
|
env.NEXUS_ARTIFACT_NAME,
|
||||||
env.NEXUS_CREDENTIALS_USR,
|
env.NEXUS_CREDENTIALS_USR,
|
||||||
@@ -95,14 +104,16 @@ pipeline {
|
|||||||
}
|
}
|
||||||
success {
|
success {
|
||||||
script {
|
script {
|
||||||
def message = "Deploy thành công : FRONTEND - Môi trường ${params.ENV} - Dự án ${env.PROJECT_NAME}, ${currentBuild.fullDisplayName}\n${env.BUILD_URL}"
|
def message = "✅Deploy thành công : FRONTEND - Môi trường ${params.ENV} - Dự án ${env.PROJECT_NAME}, ${currentBuild.fullDisplayName}\n${env.BUILD_URL}"
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
failure {
|
failure {
|
||||||
script {
|
script {
|
||||||
def message = "Deploy thất bại: FRONTEND - Môi trường ${params.ENV} - Dự án ${env.PROJECT_NAME}, ${currentBuild.fullDisplayName}\n${env.BUILD_URL}"
|
def message = "❌Deploy thất bại: FRONTEND - Môi trường ${params.ENV} - Dự án ${env.PROJECT_NAME}, ${currentBuild.fullDisplayName}\n${env.BUILD_URL}"
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,8 +215,6 @@ def triggerAnsible(
|
|||||||
String ansibleansibleFolderPath,
|
String ansibleansibleFolderPath,
|
||||||
String inventoryPath,
|
String inventoryPath,
|
||||||
String playbookPath,
|
String playbookPath,
|
||||||
String deployENV,
|
|
||||||
String projectName,
|
|
||||||
String nexusUrl,
|
String nexusUrl,
|
||||||
String nexusArtifactName,
|
String nexusArtifactName,
|
||||||
String nexusUsername,
|
String nexusUsername,
|
||||||
@@ -217,9 +226,7 @@ def triggerAnsible(
|
|||||||
ssh ${sshAnsibleConnection} "
|
ssh ${sshAnsibleConnection} "
|
||||||
cd ${ansibleansibleFolderPath} &&
|
cd ${ansibleansibleFolderPath} &&
|
||||||
ansible-playbook -i ${inventoryPath} ${playbookPath} \\
|
ansible-playbook -i ${inventoryPath} ${playbookPath} \\
|
||||||
-e 'deploy_env=${deployENV} \\
|
-e 'nexus_url=${nexusUrl} \\
|
||||||
project_name=${projectName} \\
|
|
||||||
nexus_url=${nexusUrl} \\
|
|
||||||
artifact_name=${nexusArtifactName} \\
|
artifact_name=${nexusArtifactName} \\
|
||||||
nexus_username=${nexusUsername} \\
|
nexus_username=${nexusUsername} \\
|
||||||
nexus_password=${nexusPassword}' -vvvv
|
nexus_password=${nexusPassword}' -vvvv
|
||||||
|
|||||||
+10
-8
@@ -7,14 +7,14 @@ pipeline {
|
|||||||
GIT_BRANCH = 'main'
|
GIT_BRANCH = 'main'
|
||||||
|
|
||||||
PROJECT_NAME = 'acp'
|
PROJECT_NAME = 'acp'
|
||||||
ENV = 'prod'
|
ENV = 'production'
|
||||||
TRIGGER_JOB_NAME = 'CD_FE_ACP'
|
TRIGGER_JOB_NAME = 'CD_FE_ACP'
|
||||||
METADATA_FILENAME = "${env.ENV}_${PROJECT_NAME}_metadata.json"
|
METADATA_FILENAME = "${env.ENV}_${PROJECT_NAME}_metadata.json"
|
||||||
|
|
||||||
NUXT_BUILD_FOLDER_PATH = "${env.WORKSPACE}"
|
NUXT_BUILD_FOLDER_PATH = "${env.WORKSPACE}"
|
||||||
OUTPUT_FOLDER_PATH = "${env.ENV}-${PROJECT_NAME}-output" //thư mục .output (sau khi build xong)
|
OUTPUT_FOLDER_PATH = "${env.ENV}-${PROJECT_NAME}-output" //thư mục .output (sau khi build xong)
|
||||||
COMMAND_NUXT_INSTALL = 'npm install' //command install dependencies
|
COMMAND_NUXT_INSTALL = 'npm install' //command install dependencies
|
||||||
COMMAND_NUXT_BUILD = "NITRO_OUTPUT=${OUTPUT_FOLDER_PATH} yarn linux-builder:production" // command build MT prod
|
COMMAND_NUXT_BUILD = "NITRO_OUTPUT=${OUTPUT_FOLDER_PATH} yarn linux-builder:beta" // command build MT prod
|
||||||
|
|
||||||
COMPRESSED_FILE_NAME = "${env.ENV}_${PROJECT_NAME}_output.zip" // tên file nén
|
COMPRESSED_FILE_NAME = "${env.ENV}_${PROJECT_NAME}_output.zip" // tên file nén
|
||||||
COMPRESSED_FILE_PATH = "${env.WORKSPACE }/${COMPRESSED_FILE_NAME}"
|
COMPRESSED_FILE_PATH = "${env.WORKSPACE }/${COMPRESSED_FILE_NAME}"
|
||||||
@@ -29,8 +29,8 @@ pipeline {
|
|||||||
TIMESTAMP = new Date().format('yyyyMMdd.HH', TimeZone.getTimeZone('UTC'))
|
TIMESTAMP = new Date().format('yyyyMMdd.HH', TimeZone.getTimeZone('UTC'))
|
||||||
FULL_VERSION = "${env.VERSION}-${env.TIMESTAMP}-${env.BUILD_NUMBER}" // Tạo phiên bản hoàn chỉnh
|
FULL_VERSION = "${env.VERSION}-${env.TIMESTAMP}-${env.BUILD_NUMBER}" // Tạo phiên bản hoàn chỉnh
|
||||||
|
|
||||||
TELEGRAM_CHAT_ID = -4678013464
|
SLACK_TOKEN = credentials('SLACK_TOKEN')
|
||||||
TELEGRAM_BOT_TOKEN = credentials('TELEGRAM_BOT_TOKEN')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
@@ -103,8 +103,9 @@ pipeline {
|
|||||||
success {
|
success {
|
||||||
echo "Job '${env.JOB_NAME}' completed successfully. Attempting to trigger Job '${TRIGGER_JOB_NAME}'..."
|
echo "Job '${env.JOB_NAME}' completed successfully. Attempting to trigger Job '${TRIGGER_JOB_NAME}'..."
|
||||||
script {
|
script {
|
||||||
def message = "Build thành công : FRONTEND - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n${env.BUILD_URL} \n Đang tiến hành Deploy...!"
|
def message = "✅Build thành công : FRONTEND - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n${env.BUILD_URL} \n Đang tiến hành Deploy...!"
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
}
|
}
|
||||||
script {
|
script {
|
||||||
try {
|
try {
|
||||||
@@ -125,8 +126,9 @@ pipeline {
|
|||||||
}
|
}
|
||||||
failure {
|
failure {
|
||||||
script {
|
script {
|
||||||
def message = "Build thất bại: FRONTEND - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n Kiểm tra tại đây ${env.BUILD_URL}."
|
def message = "❌Build thất bại: FRONTEND - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n Kiểm tra tại đây ${env.BUILD_URL}."
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,8 +29,7 @@ pipeline {
|
|||||||
TIMESTAMP = new Date().format('yyyyMMdd.HH', TimeZone.getTimeZone('UTC'))
|
TIMESTAMP = new Date().format('yyyyMMdd.HH', TimeZone.getTimeZone('UTC'))
|
||||||
FULL_VERSION = "${env.VERSION}-${env.TIMESTAMP}-${env.BUILD_NUMBER}" // Tạo phiên bản hoàn chỉnh
|
FULL_VERSION = "${env.VERSION}-${env.TIMESTAMP}-${env.BUILD_NUMBER}" // Tạo phiên bản hoàn chỉnh
|
||||||
|
|
||||||
TELEGRAM_CHAT_ID = -4678013464
|
SLACK_TOKEN = credentials('SLACK_TOKEN')
|
||||||
TELEGRAM_BOT_TOKEN = credentials('TELEGRAM_BOT_TOKEN')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
@@ -106,8 +105,8 @@ pipeline {
|
|||||||
success {
|
success {
|
||||||
echo "Job '${env.JOB_NAME}' completed successfully. Attempting to trigger Job '${TRIGGER_JOB_NAME}'..."
|
echo "Job '${env.JOB_NAME}' completed successfully. Attempting to trigger Job '${TRIGGER_JOB_NAME}'..."
|
||||||
script {
|
script {
|
||||||
def message = "Build thành công : FRONTEND - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n${env.BUILD_URL} \n Đang tiến hành Deploy...!"
|
def message = "✅Build thành công : FRONTEND - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n${env.BUILD_URL} \n Đang tiến hành Deploy...!"
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
}
|
}
|
||||||
script {
|
script {
|
||||||
try {
|
try {
|
||||||
@@ -128,8 +127,9 @@ pipeline {
|
|||||||
}
|
}
|
||||||
failure {
|
failure {
|
||||||
script {
|
script {
|
||||||
def message = "Build thất bại: FRONTEND - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n Kiểm tra tại đây ${env.BUILD_URL}."
|
def message = "❌Build thất bại: FRONTEND - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n Kiểm tra tại đây ${env.BUILD_URL}."
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +1,51 @@
|
|||||||
pipeline {
|
pipeline {
|
||||||
agent any
|
agent any
|
||||||
parameters {
|
parameters {
|
||||||
choice(name: 'ENV', choices: ['prod', 'uat'], description: 'Choose Environment')
|
choice(name: 'ENV', choices: ['uat', 'production'], description: 'Choose Environment')
|
||||||
|
choice(name: 'PORTAL_NAME', choices: ['ktdt', 'hnt'], description: 'Choose SITE NAME')
|
||||||
string(name: 'CI_JOB_BUILD_NUMBER', defaultValue: '', description: 'Build number of CI Job')
|
string(name: 'CI_JOB_BUILD_NUMBER', defaultValue: '', description: 'Build number of CI Job')
|
||||||
}
|
}
|
||||||
environment {
|
environment {
|
||||||
PROJECT_NAME = 'portal'
|
PROJECT_NAME = 'portal'
|
||||||
CI_JOB_NAME_UAT = 'CI-UAT-FE-PORTAL' // tên của job build code môi trường uat
|
CI_JOB_NAME_UAT = 'CI-UAT-FE-PORTAL' // tên của job build code môi trường uat
|
||||||
CI_JOB_NAME_PROD = 'CI-PROD-FE-PORTAL' // tên của job build code môi trường prod
|
CI_JOB_NAME_PRODUCTION = 'CI-PRODUCTION-FE-PORTAL' // tên của job build code môi trường prod
|
||||||
|
|
||||||
CI_JOB_METADATA_FILENAME = "${params.ENV}_${PROJECT_NAME}_metadata.json" // tên file metadata đã được lưu từ job build code
|
CI_JOB_METADATA_FILENAME = "${env.ENV}_${env.PROJECT_NAME}_${params.PORTAL_NAME}_metadata.json" // tên file metadata đã được lưu từ job build code
|
||||||
|
|
||||||
GIT_PAT_CREDENTIALS_ID = 'b03f36c4-bba3-4764-94ca-b620651b2a68' // Id của Personal Access Token lưu trên jenkins
|
|
||||||
GIT_ANSIBLE_URL = 'work.gct.com.vn/thienvv/nsg_ansible.git'
|
|
||||||
GIT_ANSIBLE_BRANCH = 'v2'
|
|
||||||
|
|
||||||
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
||||||
ANSIBLE_SSH_CONNECTION = 'root@103.166.183.172 -p 24700'
|
ANSIBLE_SSH_CONNECTION = 'root@103.166.183.172 -p 24700'
|
||||||
|
|
||||||
ANSIBLE_FOLDER_PATH = '/srv/ansible_v2'
|
GIT_PAT_CREDENTIALS_ID = 'b03f36c4-bba3-4764-94ca-b620651b2a68' // Id của Personal Access Token lưu trên jenkins
|
||||||
ANSIBLE_INVENTORY_PATH = "inventory/${params.ENV}.ini"
|
GIT_ANSIBLE_URL = 'work.gct.com.vn/thienvv/nsg_ansible.git'
|
||||||
ANSIBLE_PLAYBOOK_PATH = 'playbooks/deploy_fe_portal.yml'
|
GIT_ANSIBLE_BRANCH = 'v3'
|
||||||
|
|
||||||
TELEGRAM_CHAT_ID = -4678013464
|
ANSIBLE_FOLDER_PATH = '/srv/ansible_v3'
|
||||||
TELEGRAM_BOT_TOKEN = credentials('TELEGRAM_BOT_TOKEN')
|
|
||||||
|
SLACK_TOKEN = credentials('SLACK_TOKEN')
|
||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
|
stage('Set up') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
if (params.ENV == 'uat') {
|
||||||
|
env.ANSIBLE_INVENTORY_PATH = 'inventory/uat/hosts.ini'
|
||||||
|
} else if (params.ENV == 'production') {
|
||||||
|
env.ANSIBLE_INVENTORY_PATH = 'inventory/production/hosts.ini'
|
||||||
|
}
|
||||||
|
echo "ANSIBLE_INVENTORY_PATH is set to: ${env.ANSIBLE_INVENTORY_PATH}"
|
||||||
|
|
||||||
|
if (params.PORTAL_NAME == 'ktdt') {
|
||||||
|
env.ANSIBLE_PLAYBOOK_PATH = 'playbooks/frontend/deploy_ktdt_portal_frontend.yml'
|
||||||
|
} else if (params.PORTAL_NAME == 'hnt') {
|
||||||
|
env.ANSIBLE_PLAYBOOK_PATH = 'playbooks/frontend/deploy_hnt_portal_frontend.yml'
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "ANSIBLE_PLAYBOOK_PATH is set to: ${env.ANSIBLE_PLAYBOOK_PATH}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stage('Retrieve Artifact Metadata From CI Job') {
|
stage('Retrieve Artifact Metadata From CI Job') {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
@@ -34,8 +53,8 @@ pipeline {
|
|||||||
case 'uat':
|
case 'uat':
|
||||||
env.CI_JOB_NAME = env.CI_JOB_NAME_UAT
|
env.CI_JOB_NAME = env.CI_JOB_NAME_UAT
|
||||||
break
|
break
|
||||||
case 'prod':
|
case 'production':
|
||||||
env.CI_JOB_NAME = env.CI_JOB_NAME_PROD
|
env.CI_JOB_NAME = env.CI_JOB_NAME_PRODUCTION
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
error "Unsupported environment: ${params.ENV}"
|
error "Unsupported environment: ${params.ENV}"
|
||||||
@@ -79,8 +98,6 @@ pipeline {
|
|||||||
env.ANSIBLE_FOLDER_PATH,
|
env.ANSIBLE_FOLDER_PATH,
|
||||||
env.ANSIBLE_INVENTORY_PATH,
|
env.ANSIBLE_INVENTORY_PATH,
|
||||||
env.ANSIBLE_PLAYBOOK_PATH,
|
env.ANSIBLE_PLAYBOOK_PATH,
|
||||||
params.ENV,
|
|
||||||
env.PROJECT_NAME,
|
|
||||||
env.NEXUS_URL,
|
env.NEXUS_URL,
|
||||||
env.NEXUS_ARTIFACT_NAME,
|
env.NEXUS_ARTIFACT_NAME,
|
||||||
env.NEXUS_CREDENTIALS_USR,
|
env.NEXUS_CREDENTIALS_USR,
|
||||||
@@ -95,14 +112,14 @@ pipeline {
|
|||||||
}
|
}
|
||||||
success {
|
success {
|
||||||
script {
|
script {
|
||||||
def message = "Deploy thành công : FRONTEND - Môi trường ${params.ENV} - Dự án ${env.PROJECT_NAME}, ${currentBuild.fullDisplayName}\n${env.BUILD_URL}"
|
def message = "✅Deploy thành công : FRONTEND - Môi trường ${params.ENV} - Dự án ${env.PROJECT_NAME} - Portal_Name ${params.PORTAL_NAME}, ${currentBuild.fullDisplayName}\n${env.BUILD_URL}"
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
failure {
|
failure {
|
||||||
script {
|
script {
|
||||||
def message = "Deploy thất bại: FRONTEND - Môi trường ${params.ENV} - Dự án ${env.PROJECT_NAME}, ${currentBuild.fullDisplayName}\n${env.BUILD_URL}"
|
def message = "❌Deploy thất bại: FRONTEND - Môi trường ${params.ENV} - Dự án ${env.PROJECT_NAME} - Portal_Name ${params.PORTAL_NAME}, ${currentBuild.fullDisplayName}\n${env.BUILD_URL}"
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,8 +221,6 @@ def triggerAnsible(
|
|||||||
String ansibleansibleFolderPath,
|
String ansibleansibleFolderPath,
|
||||||
String inventoryPath,
|
String inventoryPath,
|
||||||
String playbookPath,
|
String playbookPath,
|
||||||
String deployENV,
|
|
||||||
String projectName,
|
|
||||||
String nexusUrl,
|
String nexusUrl,
|
||||||
String nexusArtifactName,
|
String nexusArtifactName,
|
||||||
String nexusUsername,
|
String nexusUsername,
|
||||||
@@ -217,9 +232,7 @@ def triggerAnsible(
|
|||||||
ssh ${sshAnsibleConnection} "
|
ssh ${sshAnsibleConnection} "
|
||||||
cd ${ansibleansibleFolderPath} &&
|
cd ${ansibleansibleFolderPath} &&
|
||||||
ansible-playbook -i ${inventoryPath} ${playbookPath} \\
|
ansible-playbook -i ${inventoryPath} ${playbookPath} \\
|
||||||
-e 'deploy_env=${deployENV} \\
|
-e 'nexus_url=${nexusUrl} \\
|
||||||
project_name=${projectName} \\
|
|
||||||
nexus_url=${nexusUrl} \\
|
|
||||||
artifact_name=${nexusArtifactName} \\
|
artifact_name=${nexusArtifactName} \\
|
||||||
nexus_username=${nexusUsername} \\
|
nexus_username=${nexusUsername} \\
|
||||||
nexus_password=${nexusPassword}' -vvvv
|
nexus_password=${nexusPassword}' -vvvv
|
||||||
|
|||||||
+41
-16
@@ -1,43 +1,67 @@
|
|||||||
pipeline {
|
pipeline {
|
||||||
agent any
|
agent any
|
||||||
options { disableConcurrentBuilds(abortPrevious: true) }
|
options { disableConcurrentBuilds(abortPrevious: true) }
|
||||||
|
parameters {
|
||||||
|
choice(name: 'PORTAL_NAME', choices: ['ktdt', 'hnt'], description: 'Choose PORTAL NAME')
|
||||||
|
}
|
||||||
environment {
|
environment {
|
||||||
GIT_CREDENTIALSID = 'b03f36c4-bba3-4764-94ca-b620651b2a68'
|
GIT_CREDENTIALSID = 'b03f36c4-bba3-4764-94ca-b620651b2a68'
|
||||||
GIT_URL = 'http://work.gct.com.vn/anhln/PORTAL_2025.git'
|
GIT_URL = 'http://work.gct.com.vn/anhln/PORTAL_2025.git'
|
||||||
GIT_BRANCH = 'main'
|
|
||||||
|
|
||||||
ENV = 'prod'
|
GIT_KTDT_BRANCH = 'beta_kinhtedothi'
|
||||||
|
GIT_HNT_BRANCH = 'beta_hanoitimes'
|
||||||
|
|
||||||
|
ENV = 'production'
|
||||||
PROJECT_NAME = 'portal'
|
PROJECT_NAME = 'portal'
|
||||||
|
|
||||||
TRIGGER_JOB_NAME = 'CD-FE-PORTAL'
|
TRIGGER_JOB_NAME = 'CD-FE-PORTAL'
|
||||||
METADATA_FILENAME = "${env.ENV}_${env.PROJECT_NAME}_metadata.json"
|
METADATA_FILENAME = "${env.ENV}_${env.PROJECT_NAME}_${params.PORTAL_NAME}_metadata.json"
|
||||||
|
|
||||||
NUXT_BUILD_FOLDER_PATH = "${env.WORKSPACE}"
|
NUXT_BUILD_FOLDER_PATH = "${env.WORKSPACE}"
|
||||||
OUTPUT_FOLDER_PATH = ".output" //thư mục .output (sau khi build xong)
|
OUTPUT_FOLDER_PATH = "${env.ENV}-${env.PROJECT_NAME}-${params.PORTAL_NAME}-output" //thư mục .output
|
||||||
COMMAND_NUXT_INSTALL = 'npm install' //command install dependencies
|
|
||||||
COMMAND_NUXT_BUILD = "yarn build:production" // command build MT prod
|
|
||||||
|
|
||||||
COMPRESSED_FILE_NAME = "${env.ENV}_${env.PROJECT_NAME}_output.zip" // tên file nén
|
COMMAND_NUXT_INSTALL = 'npm install' //command install dependencies
|
||||||
|
COMMAND_NUXT_BUILD = "NITRO_OUTPUT=${env.OUTPUT_FOLDER_PATH} yarn build:beta" // command build
|
||||||
|
|
||||||
|
COMPRESSED_FILE_NAME = "${env.ENV}_${env.PROJECT_NAME}_${params.PORTAL_NAME}_output.zip" // tên file nén
|
||||||
COMPRESSED_FILE_PATH = "${env.WORKSPACE }/${env.COMPRESSED_FILE_NAME}"
|
COMPRESSED_FILE_PATH = "${env.WORKSPACE }/${env.COMPRESSED_FILE_NAME}"
|
||||||
|
|
||||||
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
||||||
NEXUS_REPO_URL = "https://nexus.gct.com.vn/repository/${env.ENV}-${env.PROJECT_NAME}-frontend"
|
NEXUS_REPO_URL = "https://nexus.gct.com.vn/repository/${env.ENV}-${env.PROJECT_NAME}-frontend"
|
||||||
GROUP_ID = 'vn.kinhtedothi'
|
GROUP_ID = 'vn.kinhtedothi'
|
||||||
ARTIFACT_ID = "${env.ENV}-${env.PROJECT_NAME}-frontend"
|
ARTIFACT_ID = "${env.ENV}-${env.PROJECT_NAME}-${params.PORTAL_NAME}-frontend"
|
||||||
PACKAGING = 'zip'
|
PACKAGING = 'zip'
|
||||||
VERSION = '1.0.0' // Phiên bản cơ bản
|
VERSION = '1.0.0' // Phiên bản cơ bản
|
||||||
|
|
||||||
TIMESTAMP = new Date().format('yyyyMMdd.HH', TimeZone.getTimeZone('UTC'))
|
TIMESTAMP = new Date().format('yyyyMMdd.HH', TimeZone.getTimeZone('UTC'))
|
||||||
FULL_VERSION = "${env.VERSION}-${env.TIMESTAMP}-${env.BUILD_NUMBER}" // Tạo phiên bản hoàn chỉnh
|
FULL_VERSION = "${env.VERSION}-${env.TIMESTAMP}-${env.BUILD_NUMBER}" // Tạo phiên bản hoàn chỉnh
|
||||||
|
|
||||||
TELEGRAM_CHAT_ID = -4678013464
|
SLACK_TOKEN = credentials('SLACK_TOKEN')
|
||||||
TELEGRAM_BOT_TOKEN = credentials('TELEGRAM_BOT_TOKEN')
|
|
||||||
|
}
|
||||||
|
stages {
|
||||||
|
stage('Configure GIT_BRANCH') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
switch (params.PORTAL_NAME) {
|
||||||
|
case 'ktdt':
|
||||||
|
env.GIT_BRANCHO = env.GIT_KTDT_BRANCH
|
||||||
|
break
|
||||||
|
case 'hnt':
|
||||||
|
env.GIT_BRANCHO = env.GIT_HNT_BRANCH
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
error "Unsupported PORTAL_NAME: ${params.PORTAL_NAME}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo "Branch được thiết lập là: ${env.GIT_BRANCHO}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
|
||||||
stage('Checkout') {
|
stage('Checkout') {
|
||||||
steps {
|
steps {
|
||||||
// Checkout mã nguồn từ Gitea
|
// Checkout mã nguồn từ Gitea
|
||||||
checkoutFromGit(env.GIT_URL as String, env.GIT_CREDENTIALSID as String, env.GIT_BRANCH as String)
|
checkoutFromGit(env.GIT_URL as String, env.GIT_CREDENTIALSID as String, env.GIT_BRANCHO as String)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,13 +130,14 @@ pipeline {
|
|||||||
success {
|
success {
|
||||||
echo "Job '${env.JOB_NAME}' completed successfully. Attempting to trigger Job '${TRIGGER_JOB_NAME}'..."
|
echo "Job '${env.JOB_NAME}' completed successfully. Attempting to trigger Job '${TRIGGER_JOB_NAME}'..."
|
||||||
script {
|
script {
|
||||||
def message = "Build thành công : FRONTEND - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n${env.BUILD_URL} \n Đang tiến hành Deploy...!"
|
def message = "✅Build thành công : FRONTEND - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} - Portal_Name ${params.PORTAL_NAME}- \n ${currentBuild.fullDisplayName}\n${env.BUILD_URL} \n Đang tiến hành Deploy...!"
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
}
|
}
|
||||||
script {
|
script {
|
||||||
try {
|
try {
|
||||||
def buildResult = build job: "${TRIGGER_JOB_NAME}", parameters:[
|
def buildResult = build job: "${TRIGGER_JOB_NAME}", parameters:[
|
||||||
string(name: 'ENV', value: env.ENV),
|
string(name: 'ENV', value: env.ENV),
|
||||||
|
string(name: 'PORTAL_NAME', value: params.PORTAL_NAME),
|
||||||
string(name: 'CI_JOB_BUILD_NUMBER', value: env.BUILD_NUMBER)
|
string(name: 'CI_JOB_BUILD_NUMBER', value: env.BUILD_NUMBER)
|
||||||
],
|
],
|
||||||
propagate: false
|
propagate: false
|
||||||
@@ -128,8 +153,8 @@ pipeline {
|
|||||||
}
|
}
|
||||||
failure {
|
failure {
|
||||||
script {
|
script {
|
||||||
def message = "Build thất bại: FRONTEND - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n Kiểm tra tại đây ${env.BUILD_URL}."
|
def message = "❌Build thất bại: FRONTEND - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} - Portal_Name ${params.PORTAL_NAME} - \n ${currentBuild.fullDisplayName}\n Kiểm tra tại đây ${env.BUILD_URL}."
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,42 +1,67 @@
|
|||||||
pipeline {
|
pipeline {
|
||||||
agent any
|
agent any
|
||||||
options { disableConcurrentBuilds(abortPrevious: true) }
|
options { disableConcurrentBuilds(abortPrevious: true) }
|
||||||
|
parameters {
|
||||||
|
choice(name: 'PORTAL_NAME', choices: ['ktdt', 'hnt'], description: 'Choose PORTAL NAME')
|
||||||
|
}
|
||||||
environment {
|
environment {
|
||||||
GIT_CREDENTIALSID = 'b03f36c4-bba3-4764-94ca-b620651b2a68'
|
GIT_CREDENTIALSID = 'b03f36c4-bba3-4764-94ca-b620651b2a68'
|
||||||
GIT_URL = 'http://work.gct.com.vn/anhln/PORTAL_2025.git'
|
GIT_URL = 'http://work.gct.com.vn/anhln/PORTAL_2025.git'
|
||||||
GIT_BRANCH = 'main'
|
|
||||||
|
GIT_KTDT_BRANCH = 'uat_kinhtedothi'
|
||||||
|
GIT_HNT_BRANCH = 'uat_hanoitimes'
|
||||||
|
|
||||||
ENV = 'uat'
|
ENV = 'uat'
|
||||||
PROJECT_NAME = 'portal'
|
PROJECT_NAME = 'portal'
|
||||||
|
|
||||||
TRIGGER_JOB_NAME = 'CD-FE-PORTAL'
|
TRIGGER_JOB_NAME = 'CD-FE-PORTAL'
|
||||||
METADATA_FILENAME = "${env.ENV}_${env.PROJECT_NAME}_metadata.json"
|
METADATA_FILENAME = "${env.ENV}_${env.PROJECT_NAME}_${params.PORTAL_NAME}_metadata.json"
|
||||||
|
|
||||||
NUXT_BUILD_FOLDER_PATH = "${env.WORKSPACE}"
|
NUXT_BUILD_FOLDER_PATH = "${env.WORKSPACE}"
|
||||||
OUTPUT_FOLDER_PATH = ".output" //thư mục .output (sau khi build xong)
|
OUTPUT_FOLDER_PATH = "${env.ENV}-${env.PROJECT_NAME}-${params.PORTAL_NAME}-output" //thư mục .output
|
||||||
COMMAND_NUXT_INSTALL = 'npm install' //command install dependencies
|
|
||||||
COMMAND_NUXT_BUILD = "yarn build" // command build MT uat
|
|
||||||
|
|
||||||
COMPRESSED_FILE_NAME = "${env.ENV}_${env.PROJECT_NAME}_output.zip" // tên file nén
|
COMMAND_NUXT_INSTALL = 'npm install' //command install dependencies
|
||||||
|
COMMAND_NUXT_BUILD = "NITRO_OUTPUT=${env.OUTPUT_FOLDER_PATH} yarn build" // command build MT uat
|
||||||
|
|
||||||
|
COMPRESSED_FILE_NAME = "${env.ENV}_${env.PROJECT_NAME}_${params.PORTAL_NAME}_output.zip" // tên file nén
|
||||||
COMPRESSED_FILE_PATH = "${env.WORKSPACE }/${env.COMPRESSED_FILE_NAME}"
|
COMPRESSED_FILE_PATH = "${env.WORKSPACE }/${env.COMPRESSED_FILE_NAME}"
|
||||||
|
|
||||||
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
||||||
NEXUS_REPO_URL = "https://nexus.gct.com.vn/repository/${env.ENV}-${env.PROJECT_NAME}-frontend"
|
NEXUS_REPO_URL = "https://nexus.gct.com.vn/repository/${env.ENV}-${env.PROJECT_NAME}-frontend"
|
||||||
GROUP_ID = 'vn.kinhtedothi'
|
GROUP_ID = 'vn.kinhtedothi'
|
||||||
ARTIFACT_ID = "${env.ENV}-${env.PROJECT_NAME}-frontend"
|
ARTIFACT_ID = "${env.ENV}-${env.PROJECT_NAME}-${params.PORTAL_NAME}-frontend"
|
||||||
PACKAGING = 'zip'
|
PACKAGING = 'zip'
|
||||||
VERSION = '1.0.0' // Phiên bản cơ bản
|
VERSION = '1.0.0' // Phiên bản cơ bản
|
||||||
|
|
||||||
TIMESTAMP = new Date().format('yyyyMMdd.HH', TimeZone.getTimeZone('UTC'))
|
TIMESTAMP = new Date().format('yyyyMMdd.HH', TimeZone.getTimeZone('UTC'))
|
||||||
FULL_VERSION = "${env.VERSION}-${env.TIMESTAMP}-${env.BUILD_NUMBER}" // Tạo phiên bản hoàn chỉnh
|
FULL_VERSION = "${env.VERSION}-${env.TIMESTAMP}-${env.BUILD_NUMBER}" // Tạo phiên bản hoàn chỉnh
|
||||||
|
|
||||||
TELEGRAM_CHAT_ID = -4678013464
|
SLACK_TOKEN = credentials('SLACK_TOKEN')
|
||||||
TELEGRAM_BOT_TOKEN = credentials('TELEGRAM_BOT_TOKEN')
|
|
||||||
}
|
}
|
||||||
stages {
|
stages {
|
||||||
|
stage('Configure GIT_BRANCH') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
switch (params.PORTAL_NAME) {
|
||||||
|
case 'ktdt':
|
||||||
|
env.GIT_BRANCHO = env.GIT_KTDT_BRANCH
|
||||||
|
break
|
||||||
|
case 'hnt':
|
||||||
|
env.GIT_BRANCHO = env.GIT_HNT_BRANCH
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
error "Unsupported PORTAL_NAME: ${params.PORTAL_NAME}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo "Branch được thiết lập là: ${env.GIT_BRANCHO}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stage('Checkout') {
|
stage('Checkout') {
|
||||||
steps {
|
steps {
|
||||||
// Checkout mã nguồn từ Gitea
|
// Checkout mã nguồn từ Gitea
|
||||||
checkoutFromGit(env.GIT_URL as String, env.GIT_CREDENTIALSID as String, env.GIT_BRANCH as String)
|
checkoutFromGit(env.GIT_URL as String, env.GIT_CREDENTIALSID as String, env.GIT_BRANCHO as String)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,14 +130,16 @@ pipeline {
|
|||||||
success {
|
success {
|
||||||
echo "Job '${env.JOB_NAME}' completed successfully. Attempting to trigger Job '${TRIGGER_JOB_NAME}'..."
|
echo "Job '${env.JOB_NAME}' completed successfully. Attempting to trigger Job '${TRIGGER_JOB_NAME}'..."
|
||||||
script {
|
script {
|
||||||
def message = "Build thành công : FRONTEND - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n${env.BUILD_URL} \n Đang tiến hành Deploy...!"
|
def message = "✅Build thành công : FRONTEND - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} - Portal_Name ${params.PORTAL_NAME} \n ${currentBuild.fullDisplayName}\n${env.BUILD_URL} \n Đang tiến hành Deploy...!"
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
}
|
}
|
||||||
script {
|
script {
|
||||||
try {
|
try {
|
||||||
def buildResult = build job: "${TRIGGER_JOB_NAME}", parameters:[
|
def buildResult = build job: "${TRIGGER_JOB_NAME}", parameters:[
|
||||||
string(name: 'ENV', value: env.ENV),
|
string(name: 'ENV', value: env.ENV),
|
||||||
string(name: 'CI_JOB_BUILD_NUMBER', value: env.BUILD_NUMBER)
|
string(name: 'PORTAL_NAME', value: params.PORTAL_NAME),
|
||||||
|
string(name: 'CI_JOB_BUILD_NUMBER', value: env.BUILD_NUMBER),
|
||||||
|
|
||||||
],
|
],
|
||||||
propagate: false
|
propagate: false
|
||||||
if (buildResult.result != 'SUCCESS') {
|
if (buildResult.result != 'SUCCESS') {
|
||||||
@@ -127,8 +154,8 @@ pipeline {
|
|||||||
}
|
}
|
||||||
failure {
|
failure {
|
||||||
script {
|
script {
|
||||||
def message = "Build thất bại: FRONTEND - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} \n ${currentBuild.fullDisplayName}\n Kiểm tra tại đây ${env.BUILD_URL}."
|
def message = "❌Build thất bại: FRONTEND - Môi trường ${env.ENV} - Dự án ${env.PROJECT_NAME} - Site ${params.PORTAL_NAME} \n ${currentBuild.fullDisplayName}\n Kiểm tra tại đây ${env.BUILD_URL}."
|
||||||
sh "curl -s -X POST https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage -d chat_id=${env.TELEGRAM_CHAT_ID} -d text=\"${message}\""
|
sh """curl -X POST -H 'Content-type: application/json' --data '{"text":"${message}"}' https://hooks.slack.com/services/T08TS987F4N/B08TS9SC2QN/${SLACK_TOKEN}"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user