فرایند انتشار نسخه و نصب و راه اندازی آن در سرور مخصوصا در مرحله ی توسعه ی نرم افزار، کاری تکراری و زمان بر است که توسعه دهنده با هر تغییر در سورس کد می بایست تمام مراحل را تکرار کند، بدین صورت که بعد از تغییر مورد نظر کد را کامپایل کرده، به سرور منتقل کند، نسخه ی اجرایی قبلی را متوقف کند و نسخه جدید را اجرا کند.

در این مطلب آموزشی برای یک برنامه نوشته شده با فریمورک اسپرینگ ( Spring Framework)؛ به عنوان نمونه؛ Continuous Deployment ساده یا به عبارت بهتر روشی برای نسخه گذاری اتوماتیک بر روی سرور شرح داده می شود تا توسعه دهنده برای نسخه گذاری فقط لازم باشد کد خود را بروی سرور push کند و تمام مراحل تکراری بعدی بصورت اتوماتیک انجام شود و نسخه ی برنامه ی در حال اجرا بروی سرور اتوماتیک بروز گردد.
به چه ابزاری نیاز داریم؟
دقت داشته باشید که برای استفاده از این روش محدود به Spring framework نیستید و با کمی تغییر می توانید این روش را برای هر سورس کد دیگری استفاده کنید.
اولین قدم راه اندازی git روی سیستم خود به عنوان توسعه دهنده است که احتمالا این کار را از قبل انجام داده اید، در غیر اینصورت به کمک دستورات زیر:
$ git init $ git add
به پروژه ی خود git را اضافه می کنیم.
سپس به سرور متصل شده و یک git repository در سرور راه اندازی می کنیم، جهت خلاصه کردن آموزش صرفا به صورت خیلی ساده یک repository در سرور ایجاد می کنیم:
$ mkdir /home/amir/myrepo $ cd /home/amir/myrepo $ git init
سپس این repository را به عنوان remote repository به پروژه ی لوکال خود معرفی می کنیم:
$ git remote add origin ssh://[serverUser]@[serverIp]:/home/amir/myrepo
در صورتیکه در روند push کردن تغییرات با خطای زیر مواجه شدید:
remote: error: refusing to update checked out branch: refs/heads/master
احتمالا دستور زیر مشکل را حل خواهد کرد:
git config receive.denyCurrentBranch ignore
تا اینجای کار یک repository در سرور خود ایجاد کرده ایم تا با push کردن بتوانید نسخه ی سورس کد موجود در سرور را بروز کنیم.
در قدم بعدی به کمک قابلیت git hooks اتوماتیک کردن روند نسخه گذاری را کامل تر می کنیم:
قلاب ها (hooks) در git اسکریپت هایی هستند که در مراحل یا رویدادهای مختلف git اجرا می شوند. در اینجا hookی تعریف می کنیم تا بعد از ایجاد تغییرات در repository سرور این اسکریپت اجرا شود.
قبل از انجام اینکار اجازه دهید یک فولدر جهت قراردادن نسخه ی کامپایل شده ی کد ایجاد می کنیم:
$ mkdir /home/amir/deploy
و تغییر کوچکی در برنامه ی spring ی خود دهیم:
SpringApplication app = new SpringApplication(Jhip4App.class); app.addListeners(new ApplicationPidFileWriter());
با اینجام اینکار به برنامه یک Listener از جنس ApplicationPidFileWriter اضافه می کنیم تا هنگام اجرای برنامه PID یا شناسه پروسه برنامه را در یک فایل (application.pid) ذخیره کند.
و با دستور زیر فایل hook را جهت ویرایش باز می کنیم:
$ nano /home/amir/myrepo/.git/hooks/post-receive $ chmod ug+x /home/amir/myrepo/.git/hooks/*
و اسکریپت زیر را داخل آن قرار می دهیم:
#!/bin/bash DEPLOY="/home/amir/deploy" GIT_DIR="/home/amir/myrepo" BRANCH="master" while read oldrev newrev ref do # only checking out the master (or whatever branch you would like to deploy) if [ "$ref" = "refs/heads/$BRANCH" ]; then echo "Ref $ref received. Deploying ${BRANCH} branch to production..." git --work-tree=$GIT_DIR --git-dir=$GIT_DIR/.git checkout -f $BRANCH echo "try to package..." $GIT_DIR/mvnw -f $GIT_DIR/pom.xml package -Dmaven.test.skip=true echo "try to move jar file to depoly folder" \cp -fR $GIT_DIR/target/jhip-4-0.0.1-SNAPSHOT.jar $DEPLOY/app.jar echo "try to shutdown app" kill $(cat $DEPLOY/application.pid) echo "try to run application..." nohup java -jar $DEPLOY/app.jar & else echo "Ref $ref received. Doing nothing: only the ${BRANCH} branch may be deployed on this server." fi done
اسکریپ بالا چه می کند؟
اگر تغییر اعمال شده روی شاخه یا Branch مورد نظر (در اینجا master) باشد:
به همین سادگی و بدون نیاز به راه اندازی CI/CD پیچیده، مراحل نسخه گذاری مخصوصا در فاز توسعه نرم افزار را می توان اتوماتیک کرد.