مقدمه
هنگام کار بر روی یک پروژه با چندین توسعه دهنده، زمانی که یک نفر به یک مخزن فشار می آورد و سپس دیگری شروع به ایجاد تغییرات در نسخه قدیمی کد می کند، می تواند خسته کننده باشد. اشتباهاتی مانند این زمان باعث می شود که تنظیم یک اسکریپت برای همگام نگه داشتن مخازن شما ارزشمند باشد. شما همچنین می توانید این روش را در یک محیط تولید اعمال کنید تا رفع فوری و سایر تغییرات را سریع انجام دهید.
در حالی که راه حل های دیگری برای تکمیل این کار خاص وجود دارد، نوشتن اسکریپت خود یک گزینه انعطاف پذیر است که فضایی را برای سفارشی سازی در آینده باقی می گذارد.
GitHub به شما امکان می دهد وب هوک ها را برای مخازن خود پیکربندی کنید، که رویدادهایی هستند که درخواست های HTTP را هنگام وقوع رویدادها ارسال می کنند. به عنوان مثال، می توانید از یک وب هوک استفاده کنید تا زمانی که شخصی درخواست کشش ایجاد می کند یا کد جدیدی را فشار می دهد، به شما اطلاع می دهد.
در این راهنما شما یک سرور Node.js ایجاد خواهید کرد که هر زمان که شما یا شخص دیگری کد را به GitHub فشار میدهد، به اعلان وب هوک GitHub گوش میدهد. این اسکریپت به طور خودکار یک مخزن را در یک سرور راه دور با جدیدترین نسخه کد به روز می کند و نیازی به ورود به سرور برای انجام تعهدات جدید را از بین می برد.
پیش نیازها
- یک سرور اوبونتو راه اندازی شده از جمله یک کاربر غیر ریشه با امتیازات sudo و فایروال.
- Git روی دستگاه محلی شما نصب شده باشد.
- Node.js و npm با استفاده از PPA رسمی روی سرور راه دور نصب شده باشد.
- یک مخزن در Github که حاوی کد پروژه شما است.
مرحله 1 – راه اندازی Webhook
ما با پیکربندی یک هوک برای مخزن شما شروع می کنیم. این مرحله مهم است زیرا بدون آن، Github نمیداند چه رویدادهایی را در صورت وقوع اتفاقات ارسال کند، یا آنها را به کجا ارسال کند. ابتدا webhook را ایجاد می کنیم و سپس سروری را ایجاد می کنیم که به درخواست های آن پاسخ دهد.
به حساب GitHub خود وارد شوید و به مخزنی که می خواهید نظارت کنید بروید. روی برگه تنظیمات در نوار منوی بالای صفحه مخزن خود کلیک کنید، سپس روی Webhooks در منوی ناوبری سمت چپ کلیک کنید. روی Add Webhook در گوشه سمت راست کلیک کنید و در صورت درخواست رمز عبور حساب خود را وارد کنید. صفحه ای را می بینید که شبیه این است:
- در قسمت URL Payload، http://your_server_ip:8080 را وارد کنید. این آدرس و پورت سرور Node.js است که به زودی خواهیم نوشت.
- نوع محتوا را به application/json تغییر دهید. اسکریپتی که ما می نویسیم انتظار داده های JSON را دارد و نمی تواند انواع داده های دیگر را درک کند.
- برای Secret، یک رمز عبور مخفی برای این وب هوک وارد کنید. شما از این راز در سرور Node.js خود برای تأیید اعتبار درخواستها و اطمینان از ارسال آنها از GitHub استفاده خواهید کرد.
- برای اینکه کدام رویدادها میخواهید این وب هوک را فعال کنند، فقط رویداد فشار را انتخاب کنید. ما فقط به رویداد push نیاز داریم زیرا در آن زمان کد به روز می شود و باید با سرور ما همگام شود.
- چک باکس Active را انتخاب کنید.
- فیلدها را مرور کنید و برای ایجاد آن روی Add webhook کلیک کنید.
پینگ در ابتدا ناموفق خواهد بود، اما مطمئن باشید که وب هوک شما اکنون پیکربندی شده است. حالا بیایید مخزن را در سرور کلون کنیم.
مرحله 2 – کلون کردن مخزن به سرور
اسکریپت ما می تواند یک مخزن را به روز کند، اما نمی تواند در ابتدا مخزن را راه اندازی کند، بنابراین اکنون این کار را انجام خواهیم داد. وارد سرور خود شوید:
ssh sammy@your_server_ip
مطمئن شوید که در فهرست اصلی خود هستید. سپس از Git برای کلون کردن مخزن خود استفاده کنید. حتماً نام کاربری GitHub خود را با sammy و نام پروژه Github خود را با hello_hapi جایگزین کنید.
cd
git clone https://github.com/sammy/hello_hapi.git
با این کار یک دایرکتوری جدید حاوی پروژه شما ایجاد می شود. در مرحله بعد از این دایرکتوری استفاده خواهید کرد.
با کلون شدن پروژه خود، می توانید اسکریپت webhook را ایجاد کنید.
مرحله 3 – ایجاد اسکریپت Webhook
بیایید سرور خود را برای گوش دادن به درخواستهای وب هوک از GitHub ایجاد کنیم. ما یک اسکریپت Node.js مینویسیم که یک وب سرور را روی پورت 8080 راهاندازی میکند. سرور به درخواستهای وب هوک گوش میدهد، رازی را که ما مشخص کردهایم تأیید میکند و آخرین نسخه کد را از GitHub میکشد.
به فهرست اصلی خود بروید:
cd ~
یک دایرکتوری جدید برای اسکریپت وب هوک خود به نام NodeWebhooks ایجاد کنید:
mkdir ~/NodeWebhooks
سپس به دایرکتوری جدید بروید:
cd ~/NodeWebhooks
یک فایل جدید به نام webhook.js در دایرکتوری NodeWebhooks ایجاد کنید.
nano webhook.js
این دو خط را به اسکریپت اضافه کنید:
/* Your codevar secret = "your_secret_here";
var repo = "/home/sammy/hello_hapi";... */
خط اول متغیری را برای نگه داشتن راز ایجاد شده در مرحله 1 تعریف می کند که تأیید می کند درخواست ها از GitHub می آیند. خط دوم متغیری را تعریف می کند که مسیر کامل مخزن مورد نظر برای به روز رسانی را روی دیسک محلی شما نگه می دارد. این باید به مخزنی که در مرحله 2 بررسی کرده اید اشاره کند.
در مرحله بعد، این خطوط را اضافه کنید که کتابخانههای http و کریپتو را به اسکریپت وارد میکنند. ما از اینها برای ایجاد وب سرور خود و هش راز استفاده می کنیم تا بتوانیم آن را با آنچه از GitHub دریافت می کنیم مقایسه کنیم:
let http = require('http');
let crypto = require('crypto');
در مرحله بعد، کتابخانه child_process را اضافه کنید تا بتوانید دستورات پوسته را از اسکریپت خود اجرا کنید:
const exec = require('child_process').exec;
در مرحله بعد، این کد را اضافه کنید تا یک وب سرور جدید تعریف کنید که درخواست های وب هوک GitHub را مدیریت می کند و اگر یک درخواست معتبر باشد، نسخه جدید کد را پایین می آورد:
http.createServer(function (req, res) {
req.on('data', function(chunk) {
let sig = "sha1=" + crypto.createHmac('sha1', secret).update(chunk.toString()).digest('hex');
if (req.headers['x-hub-signature'] == sig) {
exec('cd ' + repo + ' && git pull');
}
});
res.end();
}).listen(8080);
تابع http.createServer() یک وب سرور را در پورت 8080 راه اندازی می کند که به درخواست های دریافتی از Github گوش می دهد. برای اهداف امنیتی، ما تأیید میکنیم که راز گنجانده شده در درخواست با رمزی که هنگام ایجاد webhook در مرحله 1 مشخص کردهایم مطابقت دارد. این راز در هدر x-hub-signature به عنوان یک رشته هش شده SHA1 ارسال میشود، بنابراین ما راز خود را هش میکنیم. و آن را با آنچه که GitHub برای ما ارسال می کند مقایسه کنید.
اگر درخواست معتبر باشد، یک فرمان پوسته را برای به روز رسانی مخزن محلی خود با استفاده از git pull اجرا می کنیم.
اسکریپت تکمیل شده به شکل زیر است:
const secret = "your_secret_here";
const repo = "~/your_repo_path_here/";
const http = require('http');
const crypto = require('crypto');
const exec = require('child_process').exec;
http.createServer(function (req, res) {
req.on('data', function(chunk) {
let sig = "sha1=" + crypto.createHmac('sha1', secret).update(chunk.toString()).digest('hex');
if (req.headers['x-hub-signature'] == sig) {
exec('cd ' + repo + ' && git pull');
}
});
res.end();
}).listen(8080);
اگر راهنمای تنظیم اولیه سرور را دنبال کردید، باید به این وب سرور اجازه دهید تا با اجازه دادن به ترافیک در پورت 8080 با وب خارجی ارتباط برقرار کند:
sudo ufw allow 8080/tcp
اکنون که اسکریپت ما در جای خود قرار دارد، بیایید مطمئن شویم که به درستی کار می کند.
مرحله 4 – تست Webhook
ما می توانیم وب هوک خود را با استفاده از node برای اجرای آن در خط فرمان آزمایش کنیم. اسکریپت را شروع کنید و روند را در ترمینال خود باز بگذارید:
cd ~/NodeWebhooks
nodejs webhook.js
به صفحه پروژه خود در Github.com بازگردید. روی برگه تنظیمات در نوار منوی بالای صفحه مخزن خود کلیک کنید و سپس روی Webhooks در منوی ناوبری سمت چپ کلیک کنید. روی ویرایش در کنار وبی هوکی که در مرحله 1 راه اندازی کرده اید کلیک کنید. همانطور که در تصویر زیر نشان داده شده است، به پایین بروید تا بخش تحویل های اخیر را ببینید:
سه نقطه را در سمت راست فشار دهید تا دکمه تحویل مجدد ظاهر شود. در حالی که سرور گره در حال اجرا است، برای ارسال مجدد درخواست، روی Redelive کلیک کنید. پس از تأیید اینکه می خواهید درخواست را ارسال کنید، یک پاسخ موفقیت آمیز خواهید دید. این با یک کد پاسخ 200 OK پس از تحویل مجدد پینگ نشان داده می شود.
اکنون میتوانیم اطمینان حاصل کنیم که اسکریپت ما در پسزمینه اجرا میشود و در بوت شروع میشود. استفاده از CTRL+C سرور وب هوک گره را متوقف می کند.
مرحله 5 – نصب Webhook به عنوان یک سرویس Systemd
systemd مدیر وظیفه اوبونتو برای کنترل خدمات است. ما سرویسی را راه اندازی خواهیم کرد که به ما امکان می دهد اسکریپت وب هوک خود را در هنگام بوت شروع کنیم و از دستورات systemd برای مدیریت آن مانند هر سرویس دیگری استفاده کنیم.
با ایجاد یک فایل سرویس جدید شروع کنید:
sudo nano /etc/systemd/system/webhook.service
پیکربندی زیر را به فایل سرویس اضافه کنید که به systemd میگوید چگونه اسکریپت را اجرا کند. این به Systemd می گوید که کجا اسکریپت گره ما را پیدا کند و سرویس ما را توضیح می دهد.
مطمئن شوید که نام کاربری خود را جایگزین سامی کنید.
[Unit]
Description=Github webhook
After=network.target
[Service]
Environment=NODE_PORT=8080
Type=simple
User=sammy
ExecStart=/usr/bin/nodejs /home/sammy/NodeWebhooks/webhook.js
Restart=on-failure
[Install]
WantedBy=multi-user.target
سرویس جدید را فعال کنید تا با بوت شدن سیستم شروع شود:
sudo systemctl enable webhook.service
اکنون سرویس را شروع کنید:
sudo systemctl start webhook
اطمینان حاصل کنید که سرویس شروع شده است:
sudo systemctl status webhook
خروجی زیر را مشاهده خواهید کرد که نشان می دهد سرویس فعال است:
Output
● webhook.service - Github webhook
Loaded: loaded (/etc/systemd/system/webhook.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2018-08-17 19:28:41 UTC; 6s ago
Main PID: 9912 (nodejs)
Tasks: 6
Memory: 7.6M
CPU: 95ms
CGroup: /system.slice/webhook.service
└─9912 /usr/bin/nodejs /home/sammy/NodeWebhooks/webhook.js
اکنون می توانید commit های جدید را به مخزن خود فشار دهید و تغییرات را در سرور خود مشاهده کنید.
از دستگاه دسکتاپ خود، مخزن را شبیه سازی کنید:
git clone https://github.com/sammy/hello_hapi.git
یکی از فایل های موجود در مخزن را تغییر دهید. سپس فایل را commit کرده و کد خود را به GitHub فشار دهید.
git add index.js
git commit -m "Update index file"
git push origin master
وب هوک فعال می شود و تغییرات شما در سرور شما ظاهر می شود.
نتیجه
شما یک اسکریپت Node.js راه اندازی کرده اید که به طور خودکار commit های جدید را در یک مخزن راه دور مستقر می کند. می توانید از این فرآیند برای تنظیم مخازن اضافی که می خواهید نظارت کنید استفاده کنید. حتی میتوانید آن را طوری پیکربندی کنید که وقتی مخزن خود را فشار میدهید، یک وبسایت یا برنامه را برای تولید پیادهسازی کنید.