nsg_jenkins vpress first commit
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
pipeline {
|
||||
agent any
|
||||
parameters {
|
||||
choice(name: 'ENV', choices: ['uat', 'prod'], description: 'Choose Environment')
|
||||
}
|
||||
environment {
|
||||
JOB_BUILD_NAME = 'CI_FE_ACP' // tên của job build code
|
||||
METADATA_FILENAME = "${params.ENV}_metadata.json" // tên file metadata đã được lưu từ job build code
|
||||
|
||||
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'
|
||||
|
||||
NEXUS_CREDENTIALS = credentials('Nexus_credential')
|
||||
PROJECT_NAME = 'acp'
|
||||
ANSIBLE_SSH_CONNECTION = 'root@103.166.183.172 -p 24700'
|
||||
|
||||
ANSIBLE_FOLDER_PATH = '/srv/ansible_v2'
|
||||
ANSIBLE_INVENTORY_PATH = "inventory/${params.ENV}.ini"
|
||||
ANSIBLE_PLAYBOOK_PATH = 'playbooks/deploy_fe.yml'
|
||||
|
||||
TELEGRAM_CHAT_ID = -4678013464
|
||||
TELEGRAM_BOT_TOKEN = credentials('TELEGRAM_BOT_TOKEN')
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Fetch Metadata File From Job Build') {
|
||||
steps {
|
||||
script {
|
||||
def metadata = handleArtifactAndMetadata(env.JOB_BUILD_NAME, env.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}\""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//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 handleArtifactAndMetadata(String jobBuildName, String metadataFilename) {
|
||||
try {
|
||||
// Sao chép artifact từ dự án khác
|
||||
copyArtifacts projectName: jobBuildName,
|
||||
filter: metadataFilename,
|
||||
target: '.'
|
||||
|
||||
// Kiểm tra sự tồn tại của file metadata
|
||||
if (!fileExists(metadataFilename)) {
|
||||
error "File '${metadataFilename}' after copyArtifacts!"
|
||||
}
|
||||
|
||||
// Đọ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 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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
pipeline {
|
||||
agent any
|
||||
parameters {
|
||||
choice(name: 'ENV', choices: ['uat', 'prod'], description: 'Choose Environment')
|
||||
}
|
||||
environment {
|
||||
GIT_CREDENTIALSID = 'b03f36c4-bba3-4764-94ca-b620651b2a68'
|
||||
GIT_URL = 'http://work.gct.com.vn/anhln/NSG_2025.git'
|
||||
GIT_BRANCH = 'main'
|
||||
|
||||
TRIGGER_JOB_NAME = 'CD_FE_ACP'
|
||||
METADATA_FILENAME = "${params.ENV}_metadata.json"
|
||||
|
||||
NUXT_BUILD_FOLDER_PATH = "${env.WORKSPACE}"
|
||||
OUTPUT_FOLDER_PATH = '.output' // đường dẫn đến .output (sau khi build xong)
|
||||
COMMAND_NUXT_INSTALL = 'npm install' //command install dependencies
|
||||
COMMAND_NUXT_BUILD_UAT = 'yarn linux-builder' // command build
|
||||
COMMAND_NUXT_BUILD_PROD = 'yarn linux-builder:production' // command build
|
||||
|
||||
COMPRESSED_FILE_NAME = "${params.ENV}_output.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/acp-frontend'
|
||||
GROUP_ID = 'vn.kinhtedothi'
|
||||
ARTIFACT_ID = "${params.ENV}-acp-frontend"
|
||||
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('Install Dependencies') {
|
||||
steps {
|
||||
script {
|
||||
installDependencies(env.NUXT_BUILD_FOLDER_PATH as String, env.COMMAND_NUXT_INSTALL as String)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Build') {
|
||||
steps {
|
||||
script {
|
||||
switch (params.ENV) {
|
||||
case 'uat':
|
||||
env.COMMAND_NUXT_BUILD = COMMAND_NUXT_BUILD_UAT
|
||||
break
|
||||
case 'prod':
|
||||
env.COMMAND_NUXT_BUILD = COMMAND_NUXT_BUILD_PROD
|
||||
break
|
||||
default:
|
||||
error "Unsupported environment: ${params.ENV}"
|
||||
}
|
||||
buildProject(env.NUXT_BUILD_FOLDER_PATH as String, env.COMMAND_NUXT_BUILD 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
success {
|
||||
echo "metadataFileName: ${env.METADATA_FILENAME}"
|
||||
archiveArtifacts artifacts: "${env.METADATA_FILENAME}", allowEmptyArchive: false
|
||||
|
||||
build job: "${TRIGGER_JOB_NAME}", parameters: [
|
||||
string(name: 'ENV', value: 'uat') ] }
|
||||
|
||||
failure {
|
||||
echo 'Pipeline failed!'
|
||||
}
|
||||
always {
|
||||
echo 'Pipeline execution finished.'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Thienvv- hàm checkout git
|
||||
void checkoutFromGit(String gitUrl, String credentialsId, String branch) {
|
||||
echo 'Start checkoutFromGit'
|
||||
try {
|
||||
checkout([$class : 'GitSCM',
|
||||
userRemoteConfigs: [[url: gitUrl, credentialsId: credentialsId]],
|
||||
branches : [[name: "*/${branch}"]]])
|
||||
} catch (Exception e) {
|
||||
echo "[ERROR] Unexpected error: ${e.message}"
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
// Thienvv - hàm installDependencies
|
||||
void installDependencies(String buildFolderPath, String command) {
|
||||
echo 'Start installDependencies'
|
||||
try {
|
||||
if (!fileExists(buildFolderPath)) {
|
||||
error "buildFolderPath is not exist : ${buildFolderPath}"
|
||||
}
|
||||
|
||||
dir("${buildFolderPath}") {
|
||||
Integer result = sh(script: "${command}", returnStatus: true)
|
||||
|
||||
echo "result:${result}"
|
||||
|
||||
if (result == 0) {
|
||||
echo 'install Dependencies successfully.'
|
||||
} else {
|
||||
error "install Dependencies failed with status: ${result}"
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
error "Restore failed: ${e.message}"
|
||||
}
|
||||
}
|
||||
|
||||
//Thienvv - build project
|
||||
void buildProject(String buildFolderPath, String command) {
|
||||
echo 'Start buildProject'
|
||||
try {
|
||||
if (!fileExists(buildFolderPath)) {
|
||||
error "buildFolderPath is not exist : ${buildFolderPath}"
|
||||
}
|
||||
// Build dự án Nuxt.js
|
||||
dir("${buildFolderPath}") {
|
||||
Integer result = sh(script: "${command}", returnStatus: true)
|
||||
|
||||
echo "result:${result}"
|
||||
|
||||
if (result == 0) {
|
||||
echo 'Build Project successfully'
|
||||
} else {
|
||||
error "Build Project failed, status: ${result}"
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
error "Build Project failed: ${e.message}"
|
||||
}
|
||||
}
|
||||
|
||||
//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 "compressItems completed successfully: ${compressedFilePath}"
|
||||
} else {
|
||||
error "compressItems 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
|
||||
}
|
||||
}
|
||||
|
||||
void 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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user