راهنمای کاربردی مفاهیم GitLab CI/CD؛ از Runner تا Variables

در دنیای توسعه نرم‌افزار، صرفاً نوشتن کد و قرار دادن آن در یک مخزن Git برای تحویل یک محصول نرم‌افزاری کافی نیست. تیم‌های توسعه باید بتوانند فرایندهایی مانند بررسی کد، اجرای تست‌ها، ساخت نسخه نهایی و انتشار نرم‌افزار را با کمترین دخالت انسانی و بیشترین اطمینان انجام دهند. اینجاست که GitLab CI/CD به یکی از ابزارهای مهم در چرخه توسعه نرم‌افزار و پیاده‌سازی رویکرد DevOps تبدیل می‌شود.

GitLab امکانات متعددی برای خودکارسازی فرایند توسعه در اختیار تیم‌ها قرار می‌دهد؛ اما استفاده مؤثر از این امکانات مستلزم شناخت دقیق مفاهیم GitLab CI/CD است. اصطلاحاتی مانند Runner، Variables، Pipeline، Job، Stage، Artifacts و Environments ممکن است در ابتدا پیچیده به نظر برسند، اما هرکدام وظیفه مشخصی در فرایند خودکارسازی دارند.

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

در این مقاله، مهم‌ترین مفاهیم GitLab CI/CD را از پایه تا سطح کاربردی بررسی می‌کنیم تا علاوه بر شناخت هر قابلیت، ارتباط آن‌ها با یکدیگر و نحوه استفاده از آن‌ها در پروژه‌های واقعی را نیز درک کنید.

۱. GitLab CI/CD چیست و چه کاربردی دارد؟

برای درک بهتر مفاهیم GitLab CI/CD، ابتدا باید با مفهوم CI/CD آشنا شویم. CI/CD مجموعه‌ای از روش‌ها و فرایندهای خودکار است که به تیم‌های توسعه کمک می‌کند تغییرات نرم‌افزار را با سرعت، دقت و اطمینان بیشتری آزمایش و منتشر کنند.

CI مخفف Continuous Integration و به معنای یکپارچه‌سازی مداوم است. در این روش، توسعه‌دهندگان تغییرات خود را به‌صورت مستمر در مخزن مشترک کد قرار می‌دهند. پس از هر تغییر، فرایندهایی مانند بررسی کد، اجرای تست‌ها و شناسایی خطاها به‌صورت خودکار انجام می‌شوند.

CD دو مفهوم مرتبط دارد:

  • Continuous Delivery: آماده نگه‌داشتن نسخه‌های نرم‌افزار برای انتشار؛ به‌طوری‌که نسخه تأییدشده بتواند با یک اقدام کنترل‌شده منتشر شود.
  • Continuous Deployment: انتشار خودکار تغییرات تأییدشده در محیط عملیاتی، بدون نیاز به تأیید دستی هر نسخه.

GitLab CI/CD مجموعه ابزارهایی است که این فرایندها را در محیط GitLab پیاده‌سازی می‌کند.

چرا استفاده از GitLab CI/CD اهمیت دارد؟

استفاده از این قابلیت‌ها فقط برای شرکت‌های بزرگ یا پروژه‌های پیچیده نیست. حتی یک تیم کوچک توسعه نیز می‌تواند با راه‌اندازی یک Pipeline ساده، بسیاری از فعالیت‌های تکراری خود را خودکار کند.

مهم‌ترین مزایای آن عبارت‌اند از:

  • کاهش خطاهای انسانی در فرایند انتشار نرم‌افزار.
  • شناسایی سریع مشکلات کد پیش از ورود به محیط عملیاتی.
  • کاهش زمان موردنیاز برای Build و Deployment.
  • ایجاد یک فرایند استاندارد برای تمام اعضای تیم.
  • امکان ثبت و بررسی تاریخچه اجرای عملیات.
  • افزایش قابلیت اطمینان در انتشار نسخه‌های جدید.
  • فراهم کردن امکان توسعه و استقرار مداوم.

۲. اجزای اصلی GitLab CI/CD چگونه با یکدیگر کار می‌کنند؟

برای درک کامل مفاهیم GitLab CI/CD بهتر است ابتدا ارتباط اجزای اصلی آن را بشناسیم. این اجزا مستقل از یکدیگر نیستند و هرکدام بخشی از یک فرایند مشترک را مدیریت می‌کنند.

مهم‌ترین اجزای این ساختار عبارت‌اند از:

مفهوم وظیفه
Pipeline مدیریت مجموعه فرایندهای خودکار
Job اجرای یک وظیفه مشخص
Stage دسته‌بندی مراحل اجرای Jobها
Runner اجرای دستورات و وظایف
Variables نگهداری تنظیمات و مقادیر موردنیاز
Artifacts ذخیره خروجی Jobها
Cache نگهداری فایل‌ها برای افزایش سرعت اجرا
Environment معرفی محیط‌های استقرار نرم‌افزار
Rules تعیین شرایط اجرای Jobها
Executor مشخص کردن محیط اجرای Job

برای مثال، زمانی که توسعه‌دهنده کد جدیدی را به مخزن ارسال می‌کند، GitLab می‌تواند یک Pipeline ایجاد کند. این Pipeline شامل چند Stage است و هر Stage یک یا چند Job دارد. سپس GitLab Runner وظایف مربوط به هر Job را اجرا می‌کند. در طول اجرا نیز Variables برای انتقال تنظیمات و Artifacts برای نگهداری خروجی‌ها استفاده می‌شوند.

در ادامه هرکدام از این مفاهیم GitLab CI/CD را دقیق‌تر بررسی می‌کنیم.

۳. GitLab Pipeline چیست؟

Pipeline یکی از بنیادی‌ترین مفاهیم GitLab CI/CD است. Pipeline مجموعه‌ای از عملیات خودکار است که با یک رویداد مشخص آغاز می‌شود و وظایف تعریف‌شده در آن را تا پایان اجرا می‌کند.

این رویداد می‌تواند یکی از موارد زیر باشد:

  • ارسال Commit جدید به مخزن.
  • ایجاد یا به‌روزرسانی Merge Request.
  • ایجاد یک Tag جدید.
  • اجرای دستی Pipeline.
  • رسیدن زمان یک اجرای زمان‌بندی‌شده.
  • فعال شدن Pipeline توسط یک پروژه یا Pipeline دیگر.

هر Pipeline می‌تواند شامل چندین مرحله و تعداد زیادی Job باشد. ترتیب اجرای این وظایف نیز بر اساس تنظیمات فایل پیکربندی مشخص می‌شود.

انواع Pipeline در GitLab

GitLab از ساختارهای مختلفی برای مدیریت Pipeline پشتیبانی می‌کند.

Basic Pipeline: ساده‌ترین ساختار است که در آن Jobها بر اساس Stageهای تعریف‌شده اجرا می‌شوند.

Merge Request Pipeline: زمانی اجرا می‌شود که تغییرات در قالب یک Merge Request ثبت یا به‌روزرسانی شوند. این قابلیت برای بررسی تغییرات پیش از ادغام در شاخه اصلی کاربرد دارد.

Scheduled Pipeline: برای اجرای خودکار فرایندها در زمان‌های مشخص استفاده می‌شود؛ برای مثال اجرای تست‌های دوره‌ای یا تهیه گزارش.

Parent-Child Pipeline: برای تقسیم Pipelineهای بزرگ به چند Pipeline کوچک‌تر استفاده می‌شود.

Multi-Project Pipeline: امکان اتصال فرایندهای CI/CD چند پروژه مختلف را فراهم می‌کند.

انتخاب نوع Pipeline به ساختار پروژه، تعداد تیم‌ها و پیچیدگی فرایند توسعه بستگی دارد.

۴. GitLab Job چیست؟

Job کوچک‌ترین واحد اجرایی در یک Pipeline محسوب می‌شود. هر Job یک وظیفه مشخص دارد و مجموعه‌ای از دستورات را اجرا می‌کند.

برای مثال، در یک پروژه نرم‌افزاری می‌توان Jobهای زیر را تعریف کرد:

  • Install Dependencies: نصب وابستگی‌های پروژه.
  • Lint: بررسی استانداردهای کدنویسی.
  • Test: اجرای تست‌های نرم‌افزار.
  • Build: ساخت نسخه قابل انتشار برنامه.
  • Deploy: انتقال نسخه جدید به سرور.

هر Job در فایل .gitlab-ci.yml تعریف می‌شود و برای اجرا به یک Runner نیاز دارد.

ساختار یک Job

یک Job ساده می‌تواند به شکل زیر تعریف شود:

run-tests:
  script:
    - echo "Running tests"
    - npm test

در این مثال، نام Job برابر با run-tests است و دستورات موجود در بخش script به ترتیب اجرا می‌شوند.

هر Job می‌تواند تنظیمات اختصاصی داشته باشد؛ از جمله:

  • Stage مربوط به Job.
  • متغیرهای محیطی اختصاصی.
  • Image مورد استفاده.
  • Runner موردنیاز.
  • شرایط اجرای Job.
  • مدت‌زمان مجاز برای اجرا.
  • فایل‌های خروجی و Cache.

نکته مهم این است که Jobها به‌صورت مستقل تعریف می‌شوند و در صورت فراهم بودن شرایط، می‌توانند به‌صورت موازی اجرا شوند.

۵. GitLab Stage چیست؟

Stage برای دسته‌بندی Jobها و تعیین ترتیب کلی اجرای آن‌ها استفاده می‌شود. در واقع، Stage مشخص می‌کند که هر گروه از عملیات در کدام بخش از Pipeline قرار بگیرد.

برای مثال، یک Pipeline معمولی می‌تواند سه Stage اصلی داشته باشد:

  1. Build
  2. Test
  3. Deploy

در این ساختار، ابتدا Jobهای مربوط به Build اجرا می‌شوند. پس از موفقیت Jobهای این مرحله، GitLab سراغ Stage مربوط به Test می‌رود و در نهایت عملیات Deploy انجام می‌شود.

تفاوت Stage و Job

این دو مفهوم از مهم‌ترین مفاهیم GitLab CI/CD هستند که نباید با یکدیگر اشتباه گرفته شوند.

Stage یک مرحله کلی از فرایند است؛ اما Job وظیفه‌ای مشخص در آن مرحله محسوب می‌شود.

برای مثال، Stage مربوط به Test می‌تواند شامل چند Job مختلف باشد:

  • Unit Test
  • Integration Test
  • Security Scan
  • Code Quality Check

در حالت عادی، Jobهای یک Stage در صورت وجود Runnerهای کافی می‌توانند به‌صورت موازی اجرا شوند؛ اما Stage بعدی تا تکمیل موفق Jobهای Stage قبلی منتظر می‌ماند.

۶. GitLab Runner چیست و چگونه کار می‌کند؟

GitLab Runner یکی از مهم‌ترین اجزای اجرایی در مفاهیم GitLab CI/CD است. وظیفه اصلی Runner دریافت و اجرای Jobهایی است که توسط GitLab تعریف شده‌اند.

به زبان ساده، GitLab نقش مدیریت و برنامه‌ریزی فرایندها را بر عهده دارد و Runner مسئول اجرای واقعی دستورات است.

برای مثال، فرض کنید Pipeline پروژه شما شامل نصب پکیج‌ها، اجرای تست‌ها و ساخت یک نسخه جدید از نرم‌افزار است. GitLab این وظایف را تعریف می‌کند؛ اما برای اجرای دستورات، باید یک Runner در دسترس باشد.

Runner به GitLab متصل می‌شود، Jobهای قابل اجرا را دریافت می‌کند، دستورات را اجرا می‌کند و نتیجه را به GitLab گزارش می‌دهد.

انواع GitLab Runner

Runnerها بر اساس محدوده دسترسی و نحوه استفاده به چند گروه تقسیم می‌شوند.

Project Runner

این Runner به یک پروژه مشخص اختصاص داده می‌شود. برای پروژه‌هایی که نیازمندی‌های اجرایی خاص یا تنظیمات مستقل دارند، گزینه مناسبی است.

Group Runner

این نوع Runner در سطح یک Group تعریف می‌شود و پروژه‌های زیرمجموعه آن Group می‌توانند از آن استفاده کنند.

Instance Runner

این Runner در سطح کل GitLab Instance تعریف می‌شود و با توجه به تنظیمات دسترسی، می‌تواند در اختیار پروژه‌های مختلف قرار بگیرد.

Executor چیست؟

یکی دیگر از مفاهیم مهم GitLab CI/CD، Executor است. Executor مشخص می‌کند دستورات یک Job در چه محیطی اجرا شوند.

مهم‌ترین Executorها عبارت‌اند از:

۱. Shell Executor

دستورات مستقیماً روی سیستم‌عاملی اجرا می‌شوند که GitLab Runner روی آن نصب شده است.

این روش راه‌اندازی ساده‌ای دارد، اما جداسازی محدودی میان Jobها ایجاد می‌کند. به همین دلیل برای اجرای کدهای غیرقابل اعتماد یا پروژه‌های متعدد با سطح دسترسی متفاوت، انتخاب مناسبی نیست.

۲. Docker Executor

هر Job در یک Container اجرا می‌شود. این روش امکان استفاده از Imageهای مختلف را فراهم می‌کند و وابستگی‌های پروژه را از سیستم میزبان جدا نگه می‌دارد.

برای مثال، یک Job می‌تواند از Image مربوط به Node.js استفاده کند و Job دیگر با Image مربوط به Python اجرا شود.

۳. Kubernetes Executor

در این روش، هر Job در قالب یک Pod در Kubernetes اجرا می‌شود. این ساختار برای زیرساخت‌های بزرگ، محیط‌های Cloud Native و سیستم‌هایی که به مقیاس‌پذیری نیاز دارند مناسب است.

۴. SSH Executor

در این ساختار، دستورات از طریق SSH روی یک سیستم راه دور اجرا می‌شوند. این Executor همچنان در دسترس است، اما در وضعیت نگهداری قرار دارد و برای پروژه‌های جدید معمولاً گزینه‌های فعال‌تر پیشنهاد می‌شوند.

Runner Tags چیست؟

Tagها برای مشخص کردن Runner مناسب هر Job استفاده می‌شوند.

فرض کنید در زیرساخت خود سه Runner دارید:

  • Runner مخصوص Linux
  • Runner مخصوص Windows
  • Runner مخصوص Docker

می‌توانید برای هر Runner یک Tag تعریف کنید و در Job موردنظر همان Tag را مشخص کنید.

windows-build:
  tags:
    - windows
  script:
    - echo "Building on Windows"

در این مثال، GitLab فقط Runnerهایی را برای اجرای Job در نظر می‌گیرد که Tag موردنیاز را داشته باشند و سایر شرایط اجرایی نیز برقرار باشد.

نکته: اگر Job دارای Tag باشد و هیچ Runner واجد شرایطی آن Tag را نداشته باشد، Job در وضعیت Pending باقی می‌ماند.

۷. GitLab Variables چیست و چه کاربردی دارد؟

GitLab Variables یکی از کاربردی‌ترین مفاهیم GitLab CI/CD است. متغیرها برای نگهداری اطلاعات و تنظیماتی استفاده می‌شوند که در زمان اجرای Job به آن‌ها نیاز داریم.

فرض کنید یک پروژه باید روی چند سرور مختلف مستقر شود. آدرس سرور، نام کاربری، مسیر نصب و اطلاعات اتصال ممکن است در محیط‌های مختلف متفاوت باشند.

به‌جای قرار دادن این اطلاعات به‌صورت مستقیم در دستورات، می‌توان آن‌ها را به‌عنوان Variables تعریف کرد.

برای مثال:

variables:
  APP_ENV: "production"
  DEPLOY_PATH: "/var/www/html"

deploy:
  script:
    - echo "Deploying to $APP_ENV"
    - echo "Path: $DEPLOY_PATH"

در این مثال، مقادیر متغیرها در دستورات Job استفاده می‌شوند.

انواع GitLab Variables

متغیرها می‌توانند در سطوح مختلف تعریف شوند.

Project Variables

این متغیرها در سطح یک پروژه تعریف می‌شوند و در Jobهای واجد شرایط همان پروژه قابل استفاده هستند.

مسیر تعریف آن‌ها:

Settings > CI/CD > Variables

Group Variables

این متغیرها در سطح Group تعریف می‌شوند و می‌توانند در پروژه‌های زیرمجموعه آن مورد استفاده قرار بگیرند.

این قابلیت برای سازمان‌هایی که چندین پروژه مرتبط دارند بسیار کاربردی است؛ زیرا دیگر نیازی نیست اطلاعات مشترک در تک‌تک پروژه‌ها تعریف شوند.

Instance Variables

این متغیرها در سطح کل GitLab Instance تعریف می‌شوند و مدیر سیستم می‌تواند آن‌ها را برای استفاده در پروژه‌ها و گروه‌های مختلف مدیریت کند.

YAML Variables

این متغیرها مستقیماً در فایل .gitlab-ci.yml تعریف می‌شوند و می‌توانند در سطح کل Pipeline یا یک Job مشخص مورد استفاده قرار بگیرند.

Protected Variables چیست؟

گاهی اطلاعاتی مانند کلیدهای دسترسی به سرور Production یا Tokenهای حساس نباید در اختیار تمام Pipelineها قرار بگیرند.

Protected Variables برای محدود کردن دسترسی به متغیرها استفاده می‌شوند. با فعال کردن این گزینه، متغیر فقط در Pipelineهای واجد شرایط که روی Protected Branchها یا Protected Tagها اجرا می‌شوند در دسترس خواهد بود.

این قابلیت به‌خصوص برای جلوگیری از دسترسی غیرضروری به اطلاعات حساس در شاخه‌های توسعه اهمیت دارد.

Masked Variables چیست؟

Masked Variables برای جلوگیری از نمایش مقادیر حساس در Job Logها استفاده می‌شوند.

برای مثال، اگر یک Token در زمان اجرای Job به خروجی Log ارسال شود، GitLab در شرایط پشتیبانی‌شده مقدار آن را با عبارت [MASKED] جایگزین می‌کند.

البته Mask کردن به معنای محافظت کامل از اطلاعات نیست. یک اسکریپت مخرب همچنان ممکن است تلاش کند اطلاعات حساس را به مقصد دیگری ارسال کند.

بنابراین، Masking باید در کنار کنترل دسترسی، بررسی کد و محدود کردن سطح دسترسی Runner استفاده شود.

File Variables چیست؟

گاهی اطلاعات موردنیاز برنامه صرفاً یک مقدار متنی نیستند؛ بلکه باید در قالب فایل در اختیار Job قرار بگیرند.

برای مثال:

  • فایل Private Key
  • فایل Certificate
  • فایل تنظیمات اتصال
  • فایل احراز هویت سرویس‌ها

در این شرایط می‌توان از متغیرهایی با نوع File استفاده کرد. GitLab محتوای متغیر را در یک فایل موقت قرار می‌دهد و مسیر فایل را در اختیار Job می‌گذارد.

این روش برای کار با فایل‌های حساس در فرایندهای خودکارسازی کاربرد زیادی دارد.

۸. فایل gitlab-ci.yml چیست؟

فایل .gitlab-ci.yml قلب تنظیمات GitLab CI/CD محسوب می‌شود. در این فایل مشخص می‌کنیم چه Pipelineهایی ایجاد شوند، چه Jobهایی اجرا شوند، هر Job به کدام Stage تعلق داشته باشد و چه تنظیماتی برای اجرای آن موردنیاز است.

این فایل در مسیر اصلی مخزن پروژه قرار می‌گیرد و از ساختار YAML استفاده می‌کند.

برخی از مهم‌ترین Keywordهای این فایل عبارت‌اند از:

Keyword کاربرد
stages تعریف مراحل Pipeline
script تعیین دستورات اجرایی
image انتخاب Docker Image
services تعریف سرویس‌های جانبی
variables تعریف متغیرها
tags انتخاب Runner مناسب
artifacts ذخیره خروجی Job
cache ذخیره فایل‌های قابل استفاده مجدد
rules تعیین شرایط اجرای Job
needs تعریف وابستگی بین Jobها
before_script اجرای دستورات پیش از Script
after_script اجرای دستورات پس از Script
environment تعیین محیط استقرار

یکی از مزایای این ساختار، امکان نگهداری تنظیمات Pipeline در کنار کد پروژه است. در نتیجه، تغییرات مربوط به فرایند CI/CD نیز مانند سایر تغییرات نرم‌افزار قابل بررسی و نسخه‌بندی خواهند بود.

۹. GitLab Artifacts و Cache چه تفاوتی دارند؟

در پروژه‌های واقعی، Jobها معمولاً فایل‌هایی تولید می‌کنند که ممکن است در مراحل بعدی موردنیاز باشند. GitLab برای مدیریت این فایل‌ها از دو قابلیت مهم به نام‌های Artifacts و Cache استفاده می‌کند.

با وجود شباهت ظاهری، کاربرد این دو کاملاً متفاوت است.

GitLab Artifacts

Artifacts فایل‌ها و خروجی‌هایی هستند که در نتیجه اجرای یک Job تولید می‌شوند و می‌توان آن‌ها را برای استفاده در Jobهای بعدی یا دانلود از رابط GitLab ذخیره کرد.

برای مثال:

  • فایل‌های Build شده برنامه.
  • گزارش تست‌ها.
  • گزارش Code Coverage.
  • فایل‌های خروجی کامپایل.
  • گزارش‌های بررسی امنیتی.

نمونه تنظیم:

build:
  stage: build
  script:
    - npm install
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 7 days

در این مثال، پوشه dist/ به‌عنوان Artifact ذخیره می‌شود و پس از هفت روز منقضی خواهد شد.

GitLab Cache

Cache برای ذخیره فایل‌هایی استفاده می‌شود که در اجراهای بعدی می‌توان دوباره از آن‌ها استفاده کرد.

برای مثال، نصب وابستگی‌های یک پروژه ممکن است زمان زیادی بگیرد. اگر این وابستگی‌ها Cache شوند، در اجرای بعدی نیازی به دانلود مجدد تمام فایل‌ها نخواهد بود.

نمونه تنظیم:

cache:
  key: node-modules
  paths:
    - node_modules/

در این حالت، فایل‌های پوشه node_modules/ برای استفاده مجدد Cache می‌شوند.

تفاوت اصلی Artifacts و Cache

برای انتخاب صحیح میان این دو قابلیت باید هدف استفاده از فایل‌ها را مشخص کنید.

  • Artifacts برای نگهداری خروجی‌های تولیدشده توسط Job مناسب است.
  • Cache برای افزایش سرعت اجرا و نگهداری وابستگی‌های قابل استفاده مجدد کاربرد دارد.
  • Artifacts معمولاً بین Jobهای یک Pipeline منتقل می‌شوند.
  • Cache می‌تواند در اجراهای بعدی Pipeline نیز مورد استفاده قرار بگیرد.
  • Cache نباید به‌عنوان محل نگهداری مطمئن و دائمی خروجی‌های مهم در نظر گرفته شود.

۱۰. GitLab Environments چیست؟

Environment در GitLab نشان‌دهنده محیطی است که نرم‌افزار در آن مستقر می‌شود.

در فرایند توسعه معمولاً چند محیط مختلف وجود دارد. برای مثال:

  • Development: محیط توسعه.
  • Testing: محیط آزمایش.
  • Staging: محیط پیش از انتشار نهایی.
  • Production: محیط عملیاتی.

با استفاده از Environments می‌توان وضعیت استقرار نرم‌افزار را در محیط‌های مختلف مدیریت و پیگیری کرد.

برای مثال، می‌توان Job مربوط به Deploy را به Environment با نام production متصل کرد تا GitLab اطلاعات مربوط به انتشار نسخه‌های جدید را ثبت کند.

Dynamic Environments

علاوه بر محیط‌های ثابت، GitLab از محیط‌های پویا نیز پشتیبانی می‌کند.

یکی از کاربردهای مهم این قابلیت، Review Apps است. در این روش، برای هر Branch یا Merge Request می‌توان یک محیط آزمایشی مستقل ایجاد کرد.

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

این قابلیت در تیم‌هایی که چندین توسعه‌دهنده به‌صورت هم‌زمان روی یک پروژه کار می‌کنند بسیار مفید است.

۱۱. GitLab Rules و Needs چه کاربردی دارند؟

برای ساخت Pipelineهای حرفه‌ای، فقط تعریف Job و Stage کافی نیست. باید بتوانیم شرایط اجرای Jobها و وابستگی میان آن‌ها را نیز کنترل کنیم.

GitLab برای این کار امکاناتی مانند Rules و Needs را ارائه می‌دهد.

Rules

Rules مشخص می‌کند یک Job تحت چه شرایطی اجرا شود یا از Pipeline حذف شود.

برای مثال، ممکن است بخواهیم Job مربوط به انتشار نسخه Production فقط هنگام ثبت تغییرات در شاخه اصلی اجرا شود.

deploy-production:
  stage: deploy
  script:
    - echo "Deploying production"
  rules:
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
      when: manual

در این مثال، Job فقط در شرایط مشخص‌شده ایجاد می‌شود و برای شروع اجرای آن نیز تأیید دستی لازم است.

Rules می‌تواند بر اساس Branch، Tag، متغیرها و شرایط مختلف تعریف شود.

Needs

در حالت عادی، GitLab اجرای Stageها را به ترتیب مشخص‌شده مدیریت می‌کند. اما گاهی برخی Jobها به تمام عملیات Stage قبلی وابسته نیستند.

با استفاده از needs می‌توان وابستگی دقیق Jobها را مشخص کرد تا یک Job پس از تکمیل وابستگی‌های موردنیاز خود اجرا شود؛ حتی اگر سایر Jobهای Stageهای قبلی هنوز در حال اجرا باشند.

این قابلیت باعث کاهش زمان اجرای Pipeline می‌شود.

برای مثال، اگر یک پروژه دارای دو بخش مستقل Backend و Frontend باشد، می‌توان Build و Test هر بخش را به‌صورت موازی اجرا کرد و نیازی به انتظار غیرضروری برای تکمیل تمام عملیات نداشت.

۱۲. یک نمونه عملی از ساخت Pipeline در GitLab

اکنون که با مهم‌ترین مفاهیم GitLab CI/CD آشنا شدیم، می‌توانیم یک نمونه ساده اما کاربردی از Pipeline ایجاد کنیم.

فرض کنید یک پروژه مبتنی بر Node.js داریم و می‌خواهیم سه عملیات اصلی را خودکار کنیم:

  1. ساخت نسخه پروژه.
  2. اجرای تست‌ها.
  3. انتشار نسخه نهایی.

ابتدا فایل .gitlab-ci.yml را در مسیر اصلی پروژه ایجاد می‌کنیم:

stages:
  - build
  - test
  - deploy

variables:
  NODE_ENV: "production"

build-app:
  stage: build
  image: node:22
  tags:
    - docker
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 7 days

test-app:
  stage: test
  image: node:22
  tags:
    - docker
  script:
    - npm ci
    - npm test

deploy-app:
  stage: deploy
  tags:
    - docker
  script:
    - echo "Deploying application..."
  environment:
    name: production
  rules:
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
      when: manual

بررسی عملکرد Pipeline

در این مثال، هر بخش وظیفه مشخصی دارد.

مرحله Build: ابتدا Job با نام build-app اجرا می‌شود. این Job از Image مربوط به Node.js استفاده می‌کند، وابستگی‌های پروژه را نصب می‌کند و سپس عملیات Build را انجام می‌دهد.

در پایان، پوشه dist/ به‌عنوان Artifact ذخیره می‌شود.

مرحله Test: پس از موفقیت مرحله Build، Job مربوط به تست اجرا می‌شود. در این مرحله تست‌های تعریف‌شده در پروژه بررسی می‌شوند.

مرحله Deploy: در نهایت، Job مربوط به انتشار نرم‌افزار ایجاد می‌شود. این Job فقط در شاخه اصلی در دسترس است و برای اجرای آن باید به‌صورت دستی اقدام کرد.

این مثال برای نمایش ساختار و ارتباط اجزای Pipeline است. دستور Deploy در آن صرفاً یک پیام چاپ می‌کند و برای انتشار واقعی باید دستورات انتقال فایل، اتصال امن به سرور یا ابزار استقرار موردنظر به آن اضافه شوند.

۱۳. نکات امنیتی و بهترین روش‌های استفاده از GitLab CI/CD

در پروژه‌های واقعی، Pipelineها ممکن است به سرورها، پایگاه‌های داده، Registryها و سرویس‌های خارجی دسترسی داشته باشند. بنابراین، امنیت یکی از مهم‌ترین موضوعات در طراحی مفاهیم GitLab CI/CD است.

رعایت نکات زیر می‌تواند احتمال بروز مشکلات امنیتی را کاهش دهد.

مدیریت صحیح اطلاعات حساس

اطلاعاتی مانند Password، Access Token، SSH Private Key و اطلاعات اتصال به پایگاه داده را مستقیماً داخل فایل .gitlab-ci.yml قرار ندهید.

بهتر است این اطلاعات از طریق Variables یا سیستم‌های مدیریت Secrets در اختیار Job قرار بگیرند.

استفاده از Protected Variables

متغیرهای حساس مربوط به محیط Production را تا حد امکان به شاخه‌ها و Tagهای محافظت‌شده محدود کنید.

همچنین برای متغیرهایی که فقط در یک محیط استفاده می‌شوند، Environment Scope مناسب تعریف کنید.

جداسازی Runnerها

برای پروژه‌هایی که سطح اعتماد متفاوتی دارند، استفاده از Runnerهای مجزا می‌تواند امنیت را افزایش دهد.

به‌خصوص Runnerهایی که به منابع حساس زیرساخت دسترسی دارند، نباید بدون کنترل در اختیار پروژه‌های غیرقابل اعتماد قرار بگیرند.

انتخاب Executor مناسب

انتخاب Executor باید بر اساس نوع پروژه و نیازمندی‌های امنیتی انجام شود.

Docker و Kubernetes معمولاً امکانات بهتری برای جداسازی محیط اجرای Jobها فراهم می‌کنند؛ البته امنیت آن‌ها به تنظیمات صحیح و نحوه مدیریت دسترسی‌ها وابسته است.

محدود کردن دسترسی‌ها

هر Job باید فقط به منابعی دسترسی داشته باشد که برای انجام وظیفه خود نیاز دارد.

برای مثال، یک Job مربوط به اجرای تست نباید الزاماً به کلید SSH سرور Production دسترسی داشته باشد.

کنترل فایل‌های خروجی

برای Artifacts زمان انقضا مشخص کنید و از نگهداری غیرضروری فایل‌های حساس در خروجی Jobها جلوگیری کنید.

همچنین Job Logها را از نظر افشای اطلاعات حساس بررسی کنید.

۱۴. مشکلات رایج GitLab CI/CD و روش عیب‌یابی آن‌ها

حتی با تنظیم صحیح Pipeline ممکن است برخی Jobها اجرا نشوند یا در میانه فرایند با خطا مواجه شوند. شناخت مشکلات رایج، بخش مهمی از یادگیری مفاهیم GitLab CI/CD است.

۱. Job در وضعیت Pending باقی می‌ماند.

یکی از دلایل رایج این مشکل، نبود Runner واجد شرایط است.

موارد زیر را بررسی کنید:

  • آیا Runner فعال است؟
  • آیا Runner به پروژه دسترسی دارد؟
  • آیا Tagهای Job با Tagهای Runner مطابقت دارند؟
  • آیا Runner اجازه اجرای Jobهای Protected را دارد؟
  • آیا ظرفیت اجرای هم‌زمان Runner تکمیل شده است؟

۲. خطای Pipeline Configuration دریافت می‌کنید.

این مشکل معمولاً به دلیل اشتباه در ساختار YAML یا استفاده نادرست از Keywordها رخ می‌دهد.

Indentation، نام Stageها و ساختار تعریف Jobها را بررسی کنید. همچنین می‌توانید از CI Lint برای اعتبارسنجی فایل استفاده کنید.

۳. متغیرهای محیطی در Job قابل دسترسی نیستند.

اگر یک Variable تعریف شده اما در زمان اجرا در دسترس نیست، موارد زیر را بررسی کنید:

  • آیا نام متغیر صحیح است؟
  • آیا متغیر در سطح درست تعریف شده است؟
  • آیا Protected بودن آن مانع دسترسی Pipeline شده است؟
  • آیا Environment Scope با محیط Job مطابقت دارد؟
  • آیا متغیر دیگری با همان نام مقدار آن را تغییر داده است؟

۴. فایل‌های Artifacts در Job بعدی وجود ندارند.

مسیر تعریف‌شده در بخش artifacts:paths باید صحیح باشد و فایل موردنظر واقعاً توسط Job تولید شده باشد.

همچنین اگر از needs استفاده می‌کنید، باید تنظیمات دریافت Artifact از Jobهای وابسته را بررسی کنید.

۵. Pipeline بیش از حد طول می‌کشد.

برای کاهش زمان اجرا می‌توانید اقدامات زیر را انجام دهید:

  • از Cache برای وابستگی‌ها استفاده کنید.
  • Jobهای مستقل را موازی اجرا کنید.
  • از needs برای حذف انتظارهای غیرضروری استفاده کنید.
  • از Docker Imageهای سبک‌تر استفاده کنید.
  • دستورات تکراری را از Jobهای مختلف حذف کنید.
  • منابع CPU و RAM Runnerها را متناسب با حجم کار تنظیم کنید.

۱۵. پرسش‌های متداول درباره مفاهیم GitLab CI/CD

در این بخش به سؤالاتی پاسخ می‌دهیم که معمولاً هنگام شروع کار با GitLab CI/CD مطرح می‌شوند.

آیا برای استفاده از GitLab CI/CD حتماً باید GitLab Runner نصب کنیم؟

برای اجرای Jobها به Runner نیاز دارید. می‌توانید از Runnerهای موجود و مجاز استفاده کنید یا یک Runner اختصاصی روی سرور یا زیرساخت خود راه‌اندازی کنید. در GitLab Self-Managed نیز امکان مدیریت کامل زیرساخت Runnerها وجود دارد.

آیا می‌توان چند GitLab Runner برای یک پروژه داشت؟

بله. یک پروژه می‌تواند به چند Runner دسترسی داشته باشد. این کار برای اجرای Jobهای مختلف روی سیستم‌عامل‌ها، Executorها و زیرساخت‌های متفاوت کاربرد دارد.

تفاوت GitLab Runner و GitLab CI/CD چیست؟

GitLab CI/CD مجموعه قابلیت‌های مدیریت و خودکارسازی فرایند توسعه نرم‌افزار است؛ اما GitLab Runner مؤلفه‌ای است که دستورات تعریف‌شده در Jobها را اجرا می‌کند.

آیا GitLab Variables برای نگهداری Password مناسب هستند؟

بله، می‌توان از Variables برای نگهداری اطلاعات حساس استفاده کرد؛ اما باید از قابلیت‌هایی مانند Masked، Hidden و Protected به‌درستی استفاده شود. برای اطلاعات بسیار حساس و زیرساخت‌های مهم، استفاده از External Secrets Manager نیز توصیه می‌شود.

آیا GitLab CI/CD فقط برای پروژه‌های مبتنی بر Docker کاربرد دارد؟

خیر. Docker تنها یکی از گزینه‌های اجرای Jobها است. بسته به نیاز پروژه می‌توان از Executorهای مختلف مانند Shell، Docker یا Kubernetes استفاده کرد.

آیا می‌توان Deployment را به‌صورت دستی انجام داد؟

بله. با استفاده از تنظیماتی مانند when: manual می‌توان Jobهای مشخصی را به تأیید و اجرای دستی وابسته کرد. این روش برای انتشار نسخه‌های Production بسیار کاربردی است.

تفاوت Cache و Artifacts در GitLab چیست؟

Cache برای استفاده مجدد از فایل‌ها و افزایش سرعت Pipeline به کار می‌رود؛ درحالی‌که Artifacts خروجی تولیدشده توسط Job را برای دانلود یا انتقال به مراحل بعدی نگهداری می‌کند.

نتیجه‌گیری

شناخت مفاهیم GitLab CI/CD یکی از مهارت‌های کاربردی برای توسعه‌دهندگان، مهندسان DevOps و مدیران زیرساخت است. این مفاهیم به شما کمک می‌کنند فرایند توسعه و انتشار نرم‌افزار را از مجموعه‌ای از فعالیت‌های دستی و پراکنده به یک ساختار خودکار، قابل کنترل و قابل تکرار تبدیل کنید.

در این مقاله با مهم‌ترین اجزای این ساختار آشنا شدیم؛ از Pipeline، Job و Stage گرفته تا GitLab Runner، Executor، Variables، Artifacts، Cache و Environments. همچنین نحوه ارتباط این اجزا و یک نمونه عملی از پیاده‌سازی Pipeline را بررسی کردیم.

برای شروع، پیشنهاد می‌شود ابتدا یک Runner راه‌اندازی کنید، یک فایل .gitlab-ci.yml ساده بسازید و فرایند Build و Test پروژه خود را خودکار کنید. پس از تسلط بر این مراحل، می‌توانید به‌تدریج قابلیت‌هایی مانند مدیریت Secrets، Deployment خودکار، Runnerهای اختصاصی و Pipelineهای موازی را به پروژه اضافه کنید.

در نهایت، هدف اصلی استفاده از این قابلیت‌ها صرفاً خودکارسازی چند دستور نیست؛ بلکه ایجاد یک فرایند استاندارد برای تحویل نرم‌افزار با سرعت بیشتر، خطای کمتر و قابلیت اطمینان بالاتر است.

اگر تجربه استفاده از GitLab CI/CD را دارید، دیدگاه خود را درباره نحوه استفاده از Runnerها، Variables و سایر قابلیت‌های آن با ما به اشتراک بگذارید. همچنین پیشنهاد می‌کنیم برای تکمیل دانش خود در حوزه DevOps، سایر مقالات مرتبط با Git، Docker، Kubernetes و Continuous Integration را مطالعه کنید.

آشنایی با مفاهیم GitLab CI/CD و اجزای آن

آشنایی با مفاهیم GitLab CI/CD و اجزای آن

arman

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *