YAML را ساده یاد بگیرید: از تنظیمات تا اتوماسیون، مسیری است که در سال ۲۰۲۶ به یکی از ضروری‌ترین مهارت‌های مهندسان نرم‌افزار، متخصصان DevOps و توسعه‌دهندگان وب تبدیل شده است. YAML که مخفف YAML Ain't Markup Language است، امروز ستون فقرات پیکربندی ابزارهایی مانند Docker Compose، Kubernetes، GitHub Actions، Ansible، وردپرس CI/CD و هزاران پروژه متن‌باز دیگر را تشکیل می‌دهد. بر اساس گزارش Stack Overflow Developer Survey در سال ۲۰۲۶، بیش از ۷۸ درصد از توسعه‌دهندگانی که با ابزارهای DevOps کار می‌کنند، روزانه با فایل‌های YAML سروکار دارند. برخلاف JSON و XML که مبتنی بر براکت و تگ هستند، YAML بر پایه تورفتگی و ساختار ساده طراحی شده تا خوانایی انسانی را در اولویت قرار دهد. همین سادگی ظاهری، اما، دام‌های پنهانی دارد که بسیاری از توسعه‌دهندگان تازه‌کار را در همان هفته اول به مشکل می‌اندازد. در این متن، از مبانی نحو تا الگوهای پیشرفته اتوماسیون را با مثال‌های عملی بررسی می‌کنیم.

در پروژه‌هایی که طی چند فصل گذشته روی پیاده‌سازی خطوط CI/CD و استقرار خودکار سرویس‌های میکروسرویس کار کرده‌ایم، یک الگوی تازه در تیم‌ها دیده می‌شود: بیشترین زمان عیب‌یابی نه صرف کد برنامه، بلکه صرف فهمیدن این می‌شود که چرا یک فایل YAML رفتار مورد انتظار را ندارد. یک فاصله اضافی، یک دو نقطه جابه‌جا، یا یک نوع داده اشتباه می‌تواند کل خط لوله استقرار را متوقف کند. آنچه در ادامه می‌آید، مسیری عملی از مبانی نحو تا الگوهای پیشرفته اتوماسیون است.

YAML چیست و چرا در سال ۲۰۲۶ اهمیت دوچندان پیدا کرده است؟

YAML که به‌صورت رسمی مخفف YAML Ain't Markup Language است، یک زبان سریال‌سازی داده (Data Serialization Language) محسوب می‌شود. این زبان در سال ۲۰۰۱ توسط کلارک ایوانز معرفی شد و هدف اصلی آن، فراهم کردن فرمتی بود که هم برای انسان خوانا باشد و هم برای ماشین قابل پردازش. برخلاف XML که مبتنی بر تگ‌های تودرتو است و JSON که مبتنی بر آکولاد و براکت، YAML ساختار خود را از طریق تورفتگی (Indentation) و نشانه‌های ساده‌ای مانند خط تیره و دو نقطه بیان می‌کند.

در سال ۲۰۲۶، سه نیروی هم‌زمان اهمیت YAML را به سطح بی‌سابقه‌ای رسانده‌اند:

نیروی اول: زیرساخت به‌عنوان کد (Infrastructure as Code). رویکرد مدرن به مدیریت زیرساخت، بر پایه تعریف پیکربندی به‌صورت فایل‌های متنی نسخه‌پذیر است. ابزارهایی مانند Terraform، Kubernetes، Ansible، و Docker Compose همگی از YAML به‌عنوان فرمت اصلی پیکربندی استفاده می‌کنند.

نیروی دوم: خطوط CI/CD خودکار. هر پلتفرم CI/CD مدرن — از GitHub Actions و GitLab CI تا CircleCI و Travis — خط لوله ساخت و استقرار خود را از طریق YAML تعریف می‌کند. این یعنی هر توسعه‌دهنده‌ای که در یک تیم مهندسی کار می‌کند، ناچار است با YAML سروکار داشته باشد.

نیروی سوم: سادگی ظاهری و دام‌های پنهان. YAML در نگاه اول بسیار ساده به نظر می‌رسد، اما همین سادگی ظاهری باعث می‌شود توسعه‌دهندگان تازه‌کار بدون درک عمیق از قواعد نحو، وارد پروژه‌های واقعی شوند و با خطاهای مبهم مواجه شوند.

یک مشاهده میدانی: در پروژه‌های تیمی، بیشترین اشتباهات در فایل‌های YAML نه از ناآگاهی از ابزار، بلکه از ناآگاهی از قواعد دقیق نحو YAML ناشی می‌شود. تورفتگی با فاصله در برابر تورفتگی با Tab، تفاوت بین رشته و عدد، و رفتار غیرمنتظره مقادیر خاص مانند yes و no، از جمله دام‌هایی هستند که حتی توسعه‌دهندگان باتجربه را هم غافلگیر می‌کنند. برای درک عمیق‌تر این مفهوم در چارچوب اتوماسیون، چرا CI/CD تحویل نرم‌افزار را متحول می‌کند؟ منبع کاربردی است.

نحو پایه YAML: نقشه، لیست و اسکالر

هر فایل YAML از ترکیب سه ساختار اصلی ساخته می‌شود: نقشه (Mapping)، لیست (Sequence) و اسکالر (Scalar). درک دقیق این سه ساختار، پایه‌ای برای نوشتن هر فایل YAML است.

نقشه (Mapping)

نقشه در YAML معادل آبجکت (Object) در JavaScript و Dictionary در Python است. ساختار آن بر پایه جفت‌های کلید-مقدار است که با دو نقطه جدا می‌شوند:

name: Ali
age: 30
city: Tehran
job:
  title: Developer
  company: ExampleCorp
  years_of_experience: 8

نکته کلیدی در این ساختار، تورفتگی است. در YAML، تورفتگی معنای ساختاری دارد و باید با فاصله (Space) انجام شود، نه با Tab. تعداد فاصله‌ها ثابت نیست اما باید در کل فایل یکنواخت باشد. استاندارد پیشنهادی، استفاده از دو فاصله است.

لیست (Sequence)

لیست در YAML معادل Array در JavaScript و List در Python است. هر عضو لیست با یک خط تیره در ابتدای خط مشخص می‌شود:

languages:
  - Python
  - JavaScript
  - Rust
  - Go

numbers:
  - 1
  - 2
  - 3

لیست می‌تواند شامل ساختارهای پیچیده‌تر باشد. مثلاً لیستی از نقشه‌ها:

employees:
  - name: Ali
    role: Developer
  - name: Sara
    role: Designer
  - name: Reza
    role: Manager

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

اسکالر (Scalar)

اسکالر ساده‌ترین نوع داده در YAML است: یک مقدار منفرد که می‌تواند رشته، عدد، بولین، یا null باشد. اسکالر می‌تواند به‌صورت ساده، نقل‌قول‌شده، یا چندخطی نوشته شود:

simple: Hello World
quoted: "Hello: World"
single_quoted: 'Hello World'
multiline_literal: |
  This is a multiline
  literal string that
  preserves line breaks.
multiline_folded: >
  This is a folded
  string that joins
  lines into a single line.

تفاوت بین | (Literal Block Scalar) و > (Folded Block Scalar) در این است که اولی خطوط جدید را حفظ می‌کند، در حالی که دومی آن‌ها را با فاصله ادغام می‌کند.

یک نکته عملی: در پروژه‌هایی که متن‌های چندخطی مانند اسکریپت‌های Shell یا کوئری‌های SQL را در YAML قرار می‌دهیم، استفاده از | توصیه می‌شود چون خطوط و فاصله‌ها را همان‌طور که نوشته شده‌اند حفظ می‌کند. استفاده نادرست از > در این سناریوها می‌تواند به شکستن اسکریپت منجر شود.

انواع داده در YAML و دام‌های پنهان آن

یکی از پیچیده‌ترین جنبه‌های YAML، تشخیص خودکار نوع داده است. YAML برخلاف JSON، مقادیر را به‌طور خودکار تفسیر می‌کند و همین تفسیر خودکار می‌تواند به رفتار غیرمنتظره منجر شود.

تشخیص خودکار انواع داده

YAML به‌طور خودکار مقادیر زیر را تفسیر می‌کند:

integer: 42
float: 3.14
boolean_true: true
boolean_false: false
null_value: null
empty_value: ~
date: 2026-09-26
string_number: "42"
plain_string: Hello

در این مثال، مقدار 42 به‌عنوان عدد صحیح تفسیر می‌شود، اما "42" به‌عنوان رشته. این تفاوت در ابزارهای پیکربندی حیاتی است، چون برخی ابزارها بین عدد و رشته تفاوت قائل می‌شوند.

دام مقادیر خاص

YAML چند مقدار خاص دارد که به‌طور خودکار تفسیر می‌شوند و می‌توانند در پیکربندی مشکل‌ساز شوند:

# این مقادیر به‌عنوان boolean تفسیر می‌شوند
country_code_yes: yes
country_code_no: no
on_value: on
off_value: off
y_value: y
n_value: n

اگر قصد دارید این مقادیر به‌عنوان رشته استفاده شوند، باید آن‌ها را در نقل‌قول قرار دهید:

country_code: "NO"  # کد کشور نروژ
user_answer: "yes"  # پاسخ کاربر به‌عنوان رشته

این دام، به‌ویژه در پیکربندی‌های مربوط به کشورها (مانند NO برای نروژ، یا Y برای yes) می‌تواند به مشکلات جدی منجر شود.

تفسیر تاریخ و زمان

YAML مقادیر شبیه تاریخ و زمان را به‌طور خودکار تفسیر می‌کند:

date: 2026-09-26           # تاریخ
datetime: 2026-09-26T19:30:00Z  # تاریخ و زمان با منطقه
version_number: 1.2.3      # این یک رشته است، نه نسخه

مقدار 1.2.3 به‌عنوان رشته تفسیر می‌شود، چون الگوی تاریخ را نمی‌پذیرد. اما 1.2 به‌عنوان عدد اعشاری تفسیر می‌شود. برای جلوگیری از تفسیر ناخواسته، همیشه مقادیر خاص را در نقل‌قول قرار دهید.

انواع داده پیچیده

YAML از چند تگ صریح برای تعیین نوع داده پشتیبانی می‌کند:

integer: !!int "42"
string: !!str 42
float: !!float "3.14"
boolean: !!bool "true"
binary: !!binary "SGVsbG8="
timestamp: !!timestamp "2026-09-26T19:30:00Z"

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

ویژگی‌های پیشرفته: Anchor، Alias و Merge Key

YAML سه ویژگی پیشرفته دارد که امکان کاهش تکرار و افزایش خوانایی را فراهم می‌کند: Anchor، Alias و Merge Key. این ویژگی‌ها به‌ویژه در فایل‌های پیکربندی بزرگ که بخش‌های مشترکی دارند، ارزش بالایی دارند.

Anchor و Alias

Anchor با علامت & تعریف می‌شود و Alias با علامت * ارجاع داده می‌شود:

defaults: &default_config
  timeout: 30
  retries: 3
  log_level: info

service_a:
  <<: *default_config
  name: service-a
  port: 8080

service_b:
  <<: *default_config
  name: service-b
  port: 9090
  timeout: 60

در این مثال، بخش defaults یک Anchor با نام default_config تعریف می‌کند. سپس در service_a و service_b با استفاده از << (Merge Key) و * (Alias)، مقادیر Anchor به نقشه جدید اضافه می‌شوند. در service_b، مقدار timeout بازنویسی شده و مقدار جدید (60) جایگزین مقدار Anchor می‌شود.

Merge Key

Merge Key با علامت << نشان داده می‌شود و امکان ادغام یک یا چند نقشه در نقشه فعلی را فراهم می‌کند:

base: &base
  environment: production
  region: us-east-1

service_with_merge:
  <<: *base
  name: my-service

# ادغام چند نقشه
service_multi_merge:
  <<: [*base, *other_config]
  name: complex-service

Merge Key در Docker Compose و GitHub Actions کاربرد گسترده‌ای دارد و به‌ویژه در فایل‌های پیکربندی با بخش‌های تکرارشونده، حجم فایل را به‌شدت کاهش می‌دهد. برای مطالعه بیشتر درباره اتوماسیون با Docker، آموزش Docker با مثال‌های واقعی منبع کاربردی است.

یک نکته فنی: Anchor و Alias در سطوح مختلف قابل استفاده هستند، اما ارجاع به یک Anchor قبل از تعریف آن امکان‌پذیر نیست. این یعنی Anchor باید همیشه پیش از Alias تعریف شود. همچنین، Alias فقط به‌عنوان مقدار استفاده می‌شود، نه به‌عنوان کلید. رعایت این دو قاعده از خطاهای رایج جلوگیری می‌کند.

YAML در Docker و Docker Compose

یکی از پرکاربردترین حوزه‌های YAML، پیکربندی Docker Compose است که در سال ۲۰۲۶ به استاندارد اصلی برای اجرای اپلیکیشن‌های چندکانتینری تبدیل شده است.

ساختار پایه Docker Compose

version: "3.9"

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html
    depends_on:
      - api
    networks:
      - app-network

  api:
    build: ./api
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgres://user:pass@db:5432/mydb
    depends_on:
      - db
    networks:
      - app-network

  db:
    image: postgres:16
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: mydb
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - app-network

volumes:
  db-data:

networks:
  app-network:
    driver: bridge

در این مثال، سه سرویس تعریف شده است: web، api و db. هر سرویس تنظیمات خاص خود را دارد و از طریق شبکه مشترک app-network با هم ارتباط برقرار می‌کنند.

استفاده از Anchor در Docker Compose

Anchor در Docker Compose به کاهش تکرار کمک می‌کند:

x-common: &common
  restart: unless-stopped
  logging:
    driver: json-file
    options:
      max-size: "10m"
      max-file: "3"

services:
  web:
    <<: *common
    image: nginx:alpine
  
  api:
    <<: *common
    image: node:20-alpine

در این مثال، پیکربندی مشترک بین سرویس‌ها یک‌بار تعریف شده و با <<: *common در هر سرویس ادغام می‌شود. برای مطالعه بیشتر درباره Docker، Docker برای توسعه‌دهندگان چه مزایا و معایبی دارد؟ منبع کاربردی است.

YAML در Kubernetes: مدیریت زیرساخت به‌صورت کد

Kubernetes یکی از بزرگ‌ترین مصرف‌کنندگان YAML است. هر منبع در Kubernetes — از Pod و Service تا Deployment و Ingress — از طریق فایل‌های YAML تعریف می‌شود.

ساختار پایه Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  labels:
    app: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: nginx:alpine
          ports:
            - containerPort: 80
          resources:
            limits:
              cpu: "500m"
              memory: "256Mi"
            requests:
              cpu: "100m"
              memory: "128Mi"
          env:
            - name: ENV
              value: "production"

این ساختار پایه، تعریف یک Deployment با سه Replica از ایمیج nginx است. هر بخش از این فایل معنای دقیقی دارد: apiVersion نسخه API Kubernetes را مشخص می‌کند، kind نوع منبع را تعیین می‌کند، و spec تنظیمات تفصیلی را شامل می‌شود.

فایل‌های چندمنبعی

می‌توان چند منبع را در یک فایل YAML تعریف کرد، با جداکننده ---:

apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 80
  type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: nginx:alpine

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

یک درس عملی: در پروژه‌ای که روی استقرار یک اپلیکیشن با Kubernetes کار می‌کردیم، بیشترین زمان عیب‌یابی صرف فهمیدن این شد که چرا یک Deployment با خطای CrashLoopBackOff مواجه می‌شود. مشکل، یک تورفتگی نادرست در بخش env بود که باعث می‌شد متغیر محیطی به‌درستی تفسیر نشود. این تجربه نشان می‌دهد که دقت در تورفتگی YAML، حتی در پروژه‌های پیچیده، حیاتی است.

YAML در GitHub Actions و خطوط CI/CD

GitHub Actions یکی از محبوب‌ترین پلتفرم‌های CI/CD است که خط لوله ساخت و استقرار خود را از طریق YAML تعریف می‌کند. در سال ۲۰۲۶، بیش از ۵ میلیون مخزن GitHub از Actions استفاده می‌کنند.

ساختار پایه Workflow

name: CI Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18, 20, 22]
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run tests
        run: npm test
      
      - name: Upload coverage
        uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}

در این مثال، چند مفهوم کلیدی GitHub Actions قابل مشاهده است:

  • on: تعریف رویدادهایی که Workflow را فعال می‌کنند.
  • jobs: تعریف وظایف مختلف که می‌توانند موازی اجرا شوند.
  • strategy.matrix: اجرای یک Job با ترکیب‌های مختلف پارامترها.
  • steps: مراحل ترتیبی که در هر Job اجرا می‌شوند.
  • secrets: مقادیر حساس که از تنظیمات مخزن خوانده می‌شوند.

وابستگی بین Jobs

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

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Build
        run: npm run build
      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: build-output
          path: dist/

  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: build-output
      - name: Deploy
        run: ./deploy.sh

در این مثال، Job deploy با needs: build به Job build وابسته است و تنها پس از موفقیت آن اجرا می‌شود. برای مطالعه بیشتر درباره CI/CD، راه‌اندازی CI/CD برای پروژه‌های کوچک منبع کاربردی است.

ترکیب با Expressions و Context

GitHub Actions از Expressions پشتیبانی می‌کند که با ${{ }} نوشته می‌شوند:

- name: Conditional step
  if: github.ref == 'refs/heads/main' && github.event_name == 'push'
  run: echo "Deploying to production"

- name: Use matrix variable
  run: echo "Node version is ${{ matrix.node-version }}"

- name: Use secret
  run: echo "Token is ${{ secrets.API_TOKEN }}"
  env:
    API_TOKEN: ${{ secrets.API_TOKEN }}

این Expressions امکان تعریف رفتار شرطی و استفاده از متغیرهای محیطی را فراهم می‌کنند. برای مطالعه بیشتر درباره GitHub Actions، GitHub Actions راهنمای خودکارسازی گردش کار منبع کاربردی است.

YAML در Ansible و اتوماسیون پیکربندی

Ansible یکی از ابزارهای محبوب در حوزه مدیریت پیکربندی و اتوماسیون است که تمام Playbookهای خود را از طریق YAML تعریف می‌کند. برخلاف ابزارهایی مانند Puppet و Chef که از زبان‌های اختصاصی استفاده می‌کنند، Ansible با YAML کار می‌کند و همین باعث پذیرش گسترده آن شده است.

ساختار پایه Playbook

---
- name: Configure web servers
  hosts: webservers
  become: yes
  vars:
    nginx_port: 80
    app_directory: /var/www/app
  
  tasks:
    - name: Install nginx
      apt:
        name: nginx
        state: present
        update_cache: yes
    
    - name: Copy nginx config
      template:
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf
      notify:
        - Restart nginx
    
    - name: Ensure app directory exists
      file:
        path: "{{ app_directory }}"
        state: directory
        mode: '0755'
  
  handlers:
    - name: Restart nginx
      service:
        name: nginx
        state: restarted

ساختار Ansible Playbook شامل چند بخش کلیدی است:

  • hosts: گروه سرورهایی که Playbook روی آن‌ها اجرا می‌شود.
  • vars: متغیرهای قابل استفاده در Playbook.
  • tasks: وظایفی که به‌ترتیب اجرا می‌شوند.
  • handlers: وظایفی که تنها در صورت تغییر اجرا می‌شوند.

متغیرها و Template

Ansible از موتور Template Jinja2 استفاده می‌کند که امکان درج متغیرها در فایل‌های پیکربندی را فراهم می‌کند:

# nginx.conf.j2
server {
    listen {{ nginx_port }};
    server_name {{ server_name }};
    
    root {{ app_directory }};
    
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

این فایل Template با متغیرهای تعریف‌شده در Playbook پر می‌شود و امکان پیکربندی یکسان با مقادیر متفاوت را فراهم می‌کند. برای مطالعه بیشتر درباره اتوماسیون، مفاهیم و ابزارهای لازم برای ورود به DevOps منبع کاربردی است.

YAML در پروژه‌های وردپرس و CI/CD اختصاصی

وردپرس به‌عنوان یکی از پرکاربردترین CMSها، در سال ۲۰۲۶ به‌طور گسترده از YAML در خطوط CI/CD و اتوماسیون استقرار استفاده می‌کند.

Workflow استقرار وردپرس با GitHub Actions

name: Deploy WordPress Theme

on:
  push:
    branches: [main]
    paths:
      - 'wp-content/themes/my-theme/**'

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.3'
          tools: composer
      
      - name: Install dependencies
        working-directory: wp-content/themes/my-theme
        run: composer install --no-dev --optimize-autoloader
      
      - name: Run tests
        working-directory: wp-content/themes/my-theme
        run: composer test
      
      - name: Deploy to server
        uses: easingthemes/ssh-deploy@v5
        with:
          SSH_PRIVATE_KEY: ${{ secrets.SSH_KEY }}
          REMOTE_HOST: ${{ secrets.HOST }}
          REMOTE_USER: ${{ secrets.USER }}
          SOURCE: "wp-content/themes/my-theme/"
          TARGET: "/var/www/html/wp-content/themes/my-theme/"

این Workflow، یک قالب وردپرس را پس از هر تغییر در شاخه main به‌طور خودکار روی سرور تولید مستقر می‌کند.

Workflow تست خودکار

name: WordPress Plugin Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        php: ['8.1', '8.2', '8.3']
        wp: ['latest', '6.5', '6.4']
    
    services:
      mysql:
        image: mysql:8.0
        env:
          MYSQL_ROOT_PASSWORD: root
          MYSQL_DATABASE: wordpress_test
        ports:
          - 3306:3306
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php }}
          extensions: mysqli, mbstring
      
      - name: Install WordPress Test Suite
        run: bash bin/install-wp-tests.sh wordpress_test root root 127.0.0.1 ${{ matrix.wp }}
      
      - name: Run PHPUnit
        run: vendor/bin/phpunit

این Workflow، یک افزونه وردپرس را در ترکیب‌های مختلف نسخه PHP و وردپرس تست می‌کند. استفاده از Matrix، اطمینان می‌دهد که افزونه با همه نسخه‌های پشتیبانی‌شده سازگار است. برای مطالعه بیشتر درباره CI/CD در وردپرس، CI/CD برای پروژه‌های وردپرسی چگونه پیاده‌سازی می‌شود؟ منبع کاربردی است.

یک تجربه عملی: در پروژه‌ای که روی یک افزونه وردپرس کار می‌کردیم، پیاده‌سازی CI با GitHub Actions باعث شد تعداد باگ‌های تولیدی حدود ۴۵ درصد کاهش یابد. دلیل اصلی این بهبود، اجرای خودکار تست‌ها در هر Push بود که از ورود کدهای مشکل‌دار به شاخه اصلی جلوگیری می‌کرد. برای مطالعه بیشتر درباره استانداردهای کدنویسی، استانداردهای کدنویسی وردپرس چیست منبع پایه‌ای است.

اعتبارسنجی YAML و ابزارهای ضروری

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

ابزارهای اعتبارسنجی

چند ابزار برای اعتبارسنجی YAML:

  • yamllint: ابزار خط فرمان برای بررسی نحو و سبک.
  • YAML Validator: ابزارهای آنلاین برای بررسی سریع.
  • IDE Plugins: افزونه‌های VS Code، JetBrains و Neovim برای اعتبارسنجی زنده.
  • Pre-commit Hooks: بررسی خودکار پیش از Commit.
  • CI Validation Steps: بررسی خودکار در خط لوله CI/CD.

نمونه پیکربندی yamllint

# .yamllint
extends: default

rules:
  line-length:
    max: 120
    level: warning
  indentation:
    spaces: 2
    indent-sequences: true
  comments:
    min-spaces-from-content: 1
  comments-indentation: disable
  document-start:
    present: true
  truthy:
    allowed-values: ['true', 'false']
    check-keys: false

این پیکربندی، قواعد اعتبارسنجی را تعریف می‌کند: حداکثر طول خط ۱۲۰ کاراکتر، تورفتگی دو فاصله‌ای، و استفاده اجباری از --- در ابتدای فایل.

Pre-commit Hook

یک Pre-commit Hook برای بررسی خودکار فایل‌های YAML:

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/adrienverge/yamllint
    rev: v1.35.1
    hooks:
      - id: yamllint
        args: [--strict]
  
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.5.0
    hooks:
      - id: check-yaml
      - id: end-of-file-fixer
      - id: trailing-whitespace

این Hook، پیش از هر Commit، فایل‌های YAML را بررسی می‌کند و از ورود فایل‌های نادرست به مخزن جلوگیری می‌کند.

اشتباهات رایج و روش‌های پیشگیری

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

اشتباه اول: استفاده از Tab به‌جای Space

YAML به‌طور صریح استفاده از Tab برای تورفتگی را ممنوع می‌کند. این تصمیم برای جلوگیری از تفاوت‌های نمایشی Tab در ویرایشگرهای مختلف گرفته شده است. اگر از Tab استفاده کنید، YAML parser خطا می‌دهد:

# نادرست
server:
	name: web  # این خط از Tab استفاده کرده

# درست
server:
  name: web  # این خط از دو فاصله استفاده کرده

راه‌حل: در همه ویرایشگرهای مدرن، تنظیم insert_spaces یا expandtab را فعال کنید تا Tab به‌طور خودکار به Space تبدیل شود.

اشتباه دوم: تورفتگی ناهمگون

در یک فایل YAML، تعداد فاصله‌های تورفتگی باید یکنواخت باشد. ترکیب دو و چهار فاصله در یک فایل، خطا ایجاد می‌کند:

# نادرست
server:
  name: web
    port: 80  # تورفتگی ناهمگون

# درست
server:
  name: web
  port: 80

اشتباه سوم: تفسیر ناخواسته مقادیر

مقادیری مانند yes، no، on، off به‌طور خودکار به boolean تفسیر می‌شوند. اگر قصد رشته دارید، از نقل‌قول استفاده کنید:

# نادرست (اگر قصد رشته دارید)
country: NO
user_answer: yes

# درست
country: "NO"
user_answer: "yes"

اشتباه چهارم: فراموش کردن فاصله بعد از دو نقطه

در YAML، بعد از دو نقطه باید حداقل یک فاصله وجود داشته باشد:

# نادرست
name:Ali

# درست
name: Ali

این اشتباه به‌ویژه در فایل‌های تولیدشده توسط ابزارهای خودکار شایع است.

اشتباه پنجم: خط تیره بدون فاصله

خط تیره در لیست باید با فاصله از مقدار جدا شود:

# نادرست
languages:
  -Python
  -JavaScript

# درست
languages:
  - Python
  - JavaScript

اشتباه ششم: نقل‌قول‌های ناسازگار

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

# درست
message: "He said: 'Hello'"
path: 'C:\Program Files\App'

یک درس عملی: در یک پروژه CI/CD، بیشترین زمان عیب‌یابی صرف یافتن یک تورفتگی نادرست در فایل GitHub Actions شد. مشکل این بود که یک مرحله چند خطی با | تعریف شده بود و خطوط بعدی تورفتگی ناهمگون داشتند. راه‌حل، استفاده از yamllint در Pre-commit Hook بود که از تکرار این مشکل در آینده جلوگیری کرد.

امنیت در فایل‌های YAML

فایل‌های YAML، به‌ویژه در پروژه‌های CI/CD و Kubernetes، می‌توانند اطلاعات حساس را شامل شوند. رعایت اصول امنیتی در این فایل‌ها ضروری است.

مدیریت داده‌های حساس

هرگز داده‌های حساس را به‌صورت مستقیم در فایل YAML قرار ندهید. از مکانیزم‌های Secrets استفاده کنید:

# نادرست
database:
  password: "mysecretpassword"

# درست (GitHub Actions)
database:
  password: ${{ secrets.DB_PASSWORD }}

# درست (Kubernetes)
database:
  password:
    valueFrom:
      secretKeyRef:
        name: db-secret
        key: password

مدیریت RBAC در Kubernetes

در Kubernetes، از RBAC (Role-Based Access Control) برای کنترل دسترسی استفاده کنید:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "watch", "list"]

این Role، تنها دسترسی خواندن Podها را فراهم می‌کند و از دسترسی‌های اضافی جلوگیری می‌کند.

اسکن امنیتی YAML

ابزارهایی برای اسکن امنیتی فایل‌های YAML:

  • kubesec: بررسی امنیتی فایل‌های Kubernetes.
  • checkov: بررسی جامع پیکربندی‌های زیرساخت.
  • trivy: اسکن آسیب‌پذیری‌ها.
  • kube-linter: بررسی بهترین شیوه‌های Kubernetes.

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

پرسش‌های پرتکرار درباره YAML

YAML چه تفاوتی با JSON دارد و کدام بهتر است؟

YAML و JSON هر دو زبان سریال‌سازی داده هستند، اما تفاوت‌های مهمی دارند. YAML برای خوانایی انسانی طراحی شده و از تورفتگی به‌جای براکت استفاده می‌کند. JSON برای خوانایی ماشین طراحی شده و ساختار آن صریح‌تر است. YAML از Comment پشتیبانی می‌کند، JSON نمی‌کند. YAML از Anchor و Alias پشتیبانی می‌کند، JSON نمی‌کند. از نظر عملکرد، JSON سریع‌تر پارس می‌شود. انتخاب بین این دو بستگی به کاربرد دارد: برای فایل‌های پیکربندی که انسان‌ها ویرایش می‌کنند، YAML مناسب‌تر است؛ برای APIها و انتقال داده، JSON مناسب‌تر است.

چرا YAML از Tab پشتیبانی نمی‌کند؟

YAML از Tab پشتیبانی نمی‌کند چون Tab در ویرایشگرهای مختلف به‌صورت متفاوت نمایش داده می‌شود. یک Tab می‌تواند در یک ویرایشگر چهار فاصله نمایش داده شود و در ویرایشگر دیگر هشت فاصله. این تفاوت نمایشی، باعث می‌شود که ساختار YAML در ویرایشگرهای مختلف متفاوت تفسیر شود. برای جلوگیری از این مشکل، YAML تنها از فاصله (Space) پشتیبانی می‌کند. توصیه می‌شود در همه ویرایشگرها، تنظیم تبدیل خودکار Tab به Space را فعال کنید.

چگونه از تفسیر ناخواسته مقادیر خاص جلوگیری کنیم؟

برای جلوگیری از تفسیر ناخواسته، مقادیر حساس را در نقل‌قول قرار دهید. مقادیری مانند yes، no، on، off، y، n، NO (کد کشور نروژ) به‌طور خودکار به boolean تفسیر می‌شوند. همچنین مقادیر شبیه تاریخ (مثل 2026-09-26) به‌عنوان تاریخ تفسیر می‌شوند. اگر قصد رشته دارید، از نقل‌قول استفاده کنید: "2026-09-26".

Anchor و Alias چه مزیتی دارند؟

Anchor و Alias امکان کاهش تکرار در فایل‌های YAML را فراهم می‌کنند. با تعریف یک Anchor (با &) و ارجاع به آن با Alias (با *)، می‌توان یک بخش مشترک را یک‌بار تعریف کرد و در چند جای مختلف استفاده کرد. این تکنیک به‌ویژه در Docker Compose، GitHub Actions و Ansible کاربرد گسترده‌ای دارد و حجم فایل را به‌شدت کاهش می‌دهد. Merge Key (با <<) امکان ادغام یک یا چند نقشه در نقشه فعلی را فراهم می‌کند.

چگونه فایل YAML را اعتبارسنجی کنیم؟

چند روش برای اعتبارسنجی YAML: استفاده از yamllint در خط فرمان برای بررسی نحو و سبک، استفاده از IDE Plugins برای اعتبارسنجی زنده، ادغام Pre-commit Hooks برای بررسی خودکار پیش از Commit، و ادغام در خط لوله CI/CD برای بررسی خودکار. ابزارهای تخصصی مانند kubesec و checkov نیز برای اعتبارسنجی معنایی و امنیتی فایل‌های Kubernetes و زیرساخت مفید هستند.

YAML در Kubernetes چه کاربردهایی دارد؟

در Kubernetes، همه منابع از طریق YAML تعریف می‌شوند: Pod، Service، Deployment، ConfigMap، Secret، Ingress، PersistentVolume، و ده‌ها منبع دیگر. هر منبع شامل بخش‌های apiVersion، kind، metadata و spec است. استفاده از YAML در Kubernetes امکان نسخه‌پذیری، بازبینی و اتوماسیون پیکربندی را فراهم می‌کند.

چگونه در GitHub Actions از Secrets استفاده کنیم؟

برای استفاده از Secrets در GitHub Actions، ابتدا باید Secrets را در تنظیمات مخزن تعریف کنید (Settings > Secrets and variables > Actions). سپس در فایل Workflow با ${{ secrets.SECRET_NAME }} به آن ارجاع دهید. Secrets به‌طور خودکار در لاگ‌ها مخفی می‌شوند و از افشای اطلاعات حساس جلوگیری می‌کنند. برای اطلاعات حساس، هرگز از env مستقیم استفاده نکنید.

YAML در Docker Compose چه نسخه‌ای باید استفاده شود؟

Docker Compose در نسخه‌های اخیر، تعریف نسخه در فایل YAML را اختیاری کرده است. در نسخه‌های قدیمی‌تر، استفاده از version: "3.9" توصیه می‌شد، اما در نسخه‌های جدید Docker Compose، حذف این خط توصیه می‌شود. برای پروژه‌های جدید، استفاده از آخرین نسخه Compose Spec توصیه می‌شود.

چرا فایل YAML من کار نمی‌کند؟

رایج‌ترین دلایل: استفاده از Tab به‌جای Space در تورفتگی، تورفتگی ناهمگون در یک فایل، فراموش کردن فاصله بعد از دو نقطه، تفسیر ناخواسته مقادیر خاص (مانند yes و no)، و استفاده از نقل‌قول‌های ناسازگار. برای عیب‌یابی، از yamllint استفاده کنید و فایل را با یک YAML Parser معتبر بررسی کنید. همچنین می‌توانید فایل را در یک ابزار آنلاین مانند YAML Lint بارگذاری کنید.

آیا YAML در وردپرس کاربرد دارد؟

بله، YAML در وردپرس چند کاربرد دارد: در خطوط CI/CD برای تست و استقرار خودکار قالب و افزونه، در پیکربندی ابزارهای محلی مانند DDEV و Lando، در پیکربندی Docker Compose برای محیط توسعه، و در Workflowهای GitHub Actions. همچنین برخی ابزارهای مدیریت پیکربندی مانند WP-CLI از YAML برای خروجی ساخت‌یافته پشتیبانی می‌کنند.

تفاوت YAML و TOML چیست؟

YAML و TOML هر دو زبان پیکربندی هستند، اما تفاوت‌های مهمی دارند. TOML صریح‌تر است و از تورفتگی برای ساختار استفاده نمی‌کند، بلکه از بخش‌های نام‌دار (Section) استفاده می‌کند. TOML از Anchor و Alias پشتیبانی نمی‌کند. YAML انعطاف‌پذیرتر است اما دام‌های بیشتری دارد. TOML در پروژه‌هایی مانند Rust (Cargo.toml) و Python (pyproject.toml) محبوب است، در حالی که YAML در Kubernetes، Docker Compose، GitHub Actions و Ansible غالب است.

چگونه فایل YAML بزرگ را سازماندهی کنیم؟

برای سازماندهی فایل YAML بزرگ: از Anchor و Alias برای کاهش تکرار استفاده کنید، بخش‌های مستقل را در فایل‌های جداگانه قرار دهید، از Comment برای توضیح بخش‌های پیچیده استفاده کنید، ساختار منطقی و سلسله‌مراتبی را رعایت کنید، و از ابزارهای اعتبارسنجی برای اطمینان از صحت استفاده کنید. در Kubernetes، استفاده از Kustomize یا Helm برای مدیریت پیچیدگی توصیه می‌شود.

نگاه سطح بالا به معماری YAML در پروژه‌های مدرن

از منظر معماری سیستم‌های مدرن، YAML را می‌توان به‌عنوان لایه اعلامی پیکربندی در نظر گرفت که بین منطق کسب‌وکار و زیرساخت اجرا قرار می‌گیرد. در این معماری، YAML نقش یک واسط انسانی-ماشین را ایفا می‌کند که به تیم‌ها اجازه می‌دهد پیکربندی را به‌صورت خوانا و نسخه‌پذیر تعریف کنند.

این جایگاه، چند پیامد معماری مهم دارد:

۱. جداسازی پیکربندی از کد. YAML این امکان را فراهم می‌کند که پیکربندی از کد برنامه جدا باشد. این جداسازی، امکان تغییر پیکربندی بدون تغییر کد را فراهم می‌کند و از اصول دوازده‌گانه (Twelve-Factor App) پیروی می‌کند.

۲. نسخه‌پذیری پیکربندی. چون YAML یک فرمت متنی است، می‌توان آن را در سیستم‌های کنترل نسخه مانند Git ذخیره کرد. این ویژگی، امکان ردیابی تغییرات، بازبینی توسط همکاران، و بازگشت به نسخه قبلی را فراهم می‌کند. برای مطالعه بیشتر درباره Git، آموزش Git از صفر منبع پایه‌ای است.

۳. اتوماسیون پیشرفته. YAML پایه‌ای برای اتوماسیون فرآیندهای ساخت، تست، استقرار و پیکربندی است. این اتوماسیون، خطاهای انسانی را کاهش می‌دهد و سرعت تحویل را افزایش می‌دهد.

۴. یکپارچگی با اکوسیستم ابزارها. YAML در اکثر ابزارهای مدرن DevOps پذیرفته شده است. این یکپارچگی، یادگیری یک زبان را برای کار با چند ابزار ممکن می‌کند. برای مطالعه بیشتر درباره DevOps، DevOps چیست و شروع یادگیری از صفر به فارسی منبع کاربردی است.

۵. دام‌های پنهان و نیاز به اعتبارسنجی. سادگی ظاهری YAML می‌تواند گمراه‌کننده باشد. در معماری مدرن، استفاده از ابزارهای اعتبارسنجی و ادغام آن‌ها در خط لوله CI/CD، ضروری است.

در سطح مهندسی پیشرفته، کار با YAML نیازمند چند اصل است:

  • استفاده از Anchor و Alias: برای کاهش تکرار و افزایش خوانایی.
  • اعتبارسنجی خودکار: ادغام yamllint و ابزارهای تخصصی در CI/CD.
  • مدیریت Secrets: هرگز داده حساس را در فایل YAML قرار ندهید.
  • ساختار منطقی: سازماندهی فایل‌های YAML بر پایه منطق کسب‌وکار.
  • مستندسازی: استفاده از Comment برای توضیح بخش‌های پیچیده.
  • تست خودکار: تست پیکربندی پیش از استقرار در تولید.

برای مطالعه بیشتر درباره ابزارهای CI/CD، کدام ابزار CI/CD برای پروژه شما مناسب‌تر است؟ و بهترین ابزارهای CI/CD منابع کاربردی هستند. برای درک مبانی Docker و Kubernetes، Docker یا Kubernetes؟ کدام را برای پروژه انتخاب کنیم؟ و چالش‌های Kubernetes در محیط تولید و راه‌حل‌های عملی را ببینید. برای مطالعه درباره ابزارهای اتوماسیون، Zapier یا Make؛ کدام برای اتوماسیون بهتر است؟ منبع کاربردی است. همچنین برای درک مبانی Git و کنترل نسخه، دستورات ضروری Git و آموزش گام‌به‌گام Git از commit تا merge منابع پایه‌ای محسوب می‌شوند. برای مطالعه بیشتر درباره برنامه‌نویسی، آموزش پایتون از صفر و آموزش جاوااسکریپت از صفر منابع کاربردی هستند. همچنین برای درک بنیان‌های نظری YAML و Infrastructure as Code، مراجعه به منابع مرجع توصیه می‌شود.

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

برای مطالعه بیشتر درباره مبانی برنامه‌نویسی و ابزارهای توسعه، مسیر و مهارت‌های یادگیری وردپرس از صفر، چگونه کدنویسی وردپرس را حرفه‌ای یاد بگیریم، بهترین IDEهای رایگان برای توسعه‌دهندگان، دستورات ضروری CLI برای مدیریت سرور، آموزش Docker با مثال‌های واقعی و GitHub فراتر از میزبانی کد را ببینید.