nsg_jenkins vpress first commit

This commit is contained in:
thienqb123456
2024-12-23 16:57:36 +07:00
commit 6b2bc45f83
6 changed files with 1673 additions and 0 deletions
+228
View File
@@ -0,0 +1,228 @@
pipeline {
agent any
parameters {
choice(name: 'ENV', choices: ['uat', 'prod'], description: 'Choose Environment')
string(name: 'CI_JOB_BUILD_NUMBER', defaultValue: '', description: 'Build number of CI Job')
}
environment {
PROJECT_NAME = 'portal'
CI_JOB_NAME = 'CI_BE_PORTAL' // tên của job CI
CI_JOB_METADATA_FILENAME = "${PROJECT_NAME}_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 = 'v2'
ANSIBLE_FOLDER_PATH = '/srv/ansible_v2'
ANSIBLE_INVENTORY_PATH = "inventory/${params.ENV}.ini"
ANSIBLE_PLAYBOOK_PATH = 'playbooks/deploy_be.yml'
TELEGRAM_CHAT_ID = -4678013464
TELEGRAM_BOT_TOKEN = credentials('TELEGRAM_BOT_TOKEN')
}
stages {
stage('Retrieve Artifact From CI Job') {
steps {
script {
def ciJobBuildNumber = params.CI_JOB_BUILD_NUMBER
echo "Retrieving artifact from CI_JOB_BUILD_NUMBER: ${ciJobBuildNumber}"
def metadata = handleArtifactAndMetadata(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,
params.ENV,
env.PROJECT_NAME,
env.NEXUS_URL,
env.NEXUS_ARTIFACT_NAME,
env.NEXUS_CREDENTIALS_USR,
env.NEXUS_CREDENTIALS_PSW)
}
}
}
post {
always {
script {
def message = "Build : 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}\""
}
}
success {
script {
def message = "Build 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}\""
}
}
failure {
script {
def message = "Build 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}\""
}
}
}
}
def handleArtifactAndMetadata(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
}
}
//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
}
}
def triggerAnsible(
String sshAnsibleConnection,
String ansibleansibleFolderPath,
String inventoryPath,
String playbookPath,
String deployENV,
String projectName,
String nexusUrl,
String nexusArtifactName,
String nexusUsername,
String nexusPassword) {
try {
Integer result = sh(
script: """
ssh ${sshAnsibleConnection} "
cd ${ansibleansibleFolderPath} &&
ansible-playbook -i ${inventoryPath} ${playbookPath} \\
-e 'deploy_env=${deployENV} \\
project_name=${projectName} \\
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
}
}
+375
View File
@@ -0,0 +1,375 @@
pipeline {
agent any
environment {
GIT_CREDENTIALSID = 'd3de261f-8f1e-470b-b6d1-2fb4965e0129'
GIT_URL = 'http://work.gct.com.vn/anhln/ACP_2025.git'
GIT_BRANCH = 'main'
PROJECT_NAME = 'portal'
TRIGGER_JOB_NAME = 'CD_BE_PORTAL'
METADATA_FILENAME = "${PROJECT_NAME}_metadata.json"
NUGET_CONFIG_PATH = 'NuGet.config'
APPLICATIONCORE_PATH = 'Packages'
JENKINS_BUILD_FOLDER_PATH = 'Portal.WebApi'
JENKINS_PUBLISH_FOLDER_PATH = 'publish'
COMPRESSED_FILE_NAME = "${PROJECT_NAME}_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/${PROJECT_NAME}-backend"
GROUP_ID = 'vn.kinhtedothi'
ARTIFACT_ID = "${PROJECT_NAME}-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
}
stages {
stage('Checkout') {
steps {
// Checkout mã nguồn từ Gitea
checkoutFromGit(env.GIT_URL as String, env.GIT_CREDENTIALSID as String, env.GIT_BRANCH 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 {
try {
def buildResult = build job: "${TRIGGER_JOB_NAME}", parameters:[
string(name: 'ENV', value: 'uat'),
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 {
echo 'Pipeline failed!'
}
}
}
//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(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
}
}