كيفية توصيل GitLab و Pantheon وتحسين سير عمل Drupal و WordPress

كيفية توصيل GitLab و Pantheon وتحسين سير عمل Drupal و WordPress
يشرح ضيفنا ، مصمم أدوات المطورين من Pantheon ، كيفية أتمتة عمليات نشر WordPress باستخدام GitLab CI / CD.

В البانتيون أنا في علاقات مطورين ، لذلك أبحث دائمًا عن طرق جديدة لمساعدة مطوري WordPress و Drupal في حل مشكلات أتمتة سير العمل. للقيام بذلك ، أحب تجربة الأدوات الجديدة ودمجها مع بعضها البعض للعمل بفعالية.

غالبًا ما أرى المطورين يعانون من خادم مرحلي واحد.

ممتع للغاية - في انتظار دورك في استخدام خادم وسيط أو إرسال عنوان URL للعملاء يحمل علامة: "انظر هنا ، ولكن لا تنظر هنا بعد."

بيئات multidev - إحدى أدوات Pantheon الرائعة - حل هذه المشكلة ، لأنه باستخدامها يمكنك إنشاء بيئات لفروع Git عند الطلب. كل بيئة متعددة الأنظمة لها عنوان URL وقاعدة بيانات خاصة بها ، بحيث يمكن للمطورين العمل ، والتحقق من الجودة ، والحصول على الموافقة دون الخطو في أعقاب بعضهم البعض.

لكن ليس لدى Pantheon أدوات للتحكم في الإصدار أو التكامل والنشر المستمر (CI / CD). لكنها منصة مرنة يمكنك من خلالها دمج أي أدوات.

لقد لاحظت أيضًا أن الفرق تستخدم بعض الأدوات للتطوير ، وأخرى للبناء والنشر.

على سبيل المثال ، لديهم أدوات مختلفة للتحكم في الإصدار و CI / CD. يجب عليك العبث والتبديل بين الأدوات لتحرير التعليمات البرمجية وتشخيص المشاكل.

في GitLab هناك مجموعة كاملة من أدوات التطوير: التحكم في الإصدار ، والتذاكر ، وطلبات الدمج ، وخطوط أنابيب CI / CD الأفضل في فئتها ، وسجل الحاوية وأشياء من هذا القبيل. لم أجد بعد تطبيقًا لديه الكثير لإدارة سير عمل التطوير.

أنا أحب الأتمتة ، لذلك تعلمت كيفية توصيل Pantheon بـ GitLab بحيث يتم نشر الالتزام بالفرع الرئيسي في GitLab في بيئة التطوير الرئيسية في Pantheon. يمكن لطلبات دمج GitLab أيضًا إنشاء التعليمات البرمجية ونشرها في بيئات multidev في Pantheon.

في هذا الدليل ، سأوضح لك كيفية إعداد اتصال بين GitLab و Pantheon وتحسين سير عمل WordPress و Drupal.

بالطبع كان ذلك ممكنا، عكس مستودع GitLab، لكننا سنفعل كل شيء باستخدام الأقلام للتعمق فيه جيت لاب CI وفي المستقبل ، استخدم هذه الأداة ليس فقط للنشر.

مقدمة

بالنسبة لهذا المنشور ، عليك أن تفهم أن Pantheon يقسم كل موقع إلى ثلاثة عناصر: التعليمات البرمجية وقاعدة البيانات والملفات.

يشتمل الرمز على ملفات CMS مثل core ، والإضافات ، وموضوعات WordPress. تتم إدارة هذه الملفات بواسطة مستودعات Gitاستضافتها Pantheon ، مما يعني أنه يمكننا نشر كود من GitLab إلى Pantheon باستخدام Git.
تسمى الملفات الموجودة في Pantheon ملفات الوسائط ، أي صور الموقع. عادةً ما يتم تحميلها بواسطة المستخدمين ويتجاهلها Git.

إنشاء حساب مجاني، تعلم المزيد عن سير عمل البانتيون أو قم بالتسجيل في العرض التوضيحي في pantheon.io.

الافتراضات

يسمى مشروع My Pantheon و GitLab pantheon-gitlab-blog-demo. يجب أن يكون اسم المشروع فريدًا. هنا سنعمل مع موقع WordPress. يمكنك تناول دروبال ، لكنك ستحتاج إلى تغيير شيء ما.

سأستخدم سطر أوامر Gitويمكنك العمل فيها واجهة المستخدم الرسومية، أذا أردت.

أنشئ مشروعًا

للبدء ، نخلق مشروع جيت لاب (وسوف نعود إلى هذا في وقت لاحق).

الآن إنشاء موقع WordPress على Pantheon. ثم قم بتثبيت WordPress للوحة التحكم الخاصة بالموقع.

إذا كانت يديك تتشوق لتغيير شيء ما ، على سبيل المثال ، أزل المكونات الإضافية وأضفها ، فكن صبورًا. الموقع غير متصل بعد بـ GitLab ، ونريد أن تمر جميع تغييرات التعليمات البرمجية عبر GitLab.

بمجرد تثبيت WordPress ، ارجع إلى لوحة معلومات Pantheon وقم بتغيير وضع التطوير إلى Git.

كيفية توصيل GitLab و Pantheon وتحسين سير عمل Drupal و WordPress

الالتزام الأولي في GitLab

أنت الآن بحاجة إلى نقل كود WordPress الأولي من موقع Pantheon إلى GitLab. للقيام بذلك ، نقوم باستنساخ الكود من مستودع Git في موقع Pantheon محليًا ، ثم إرساله إلى مستودع GitLab.

لجعلها أسهل وأكثر أمانًا ، أضف مفتاح SSH إلى Pantheon ولن ندخل كلمة المرور في كل مرة نقوم فيها باستنساخ مستودع Pantheon Git. في نفس الوقت بالفعل أضف مفتاح SSH إلى GitLab.

للقيام بذلك ، نقوم باستنساخ موقع Pantheon محليًا عن طريق نسخ الأمر من حقل Clone with Git في لوحة معلومات الموقع.

كيفية توصيل GitLab و Pantheon وتحسين سير عمل Drupal و WordPress
إذا كنت بحاجة إلى مساعدة ، اقرأ الوثائق البدء مع Git for Pantheon.

الآن دعونا نتغير git remote originللإشارة إلى GitLab بدلاً من Pantheon. يمكن إنجازه командой git remote.

دعنا نذهب إلى مشروع GitLab ونسخ عنوان URL للمستودع من القائمة المنسدلة Clone في صفحة تفاصيل المشروع. لنحدد خيار Clone with SSH ، لأننا قمنا بالفعل بتكوين مفتاح SSH.

كيفية توصيل GitLab و Pantheon وتحسين سير عمل Drupal و WordPress

بشكل افتراضي git remote للحصول على نسخة محلية من مستودع الكود - origin. يمكن تغيير هذا من git remote set-url origin [URL репозитория GitLab]، حيث نقوم بإدخال عنوان URL الفعلي بدلاً من الأقواس.

أخيرًا ، نطلق git push origin master --forceلدفع كود WordPress من موقع Pantheon إلى GitLab.

خيار --force مطلوب مرة واحدة فقط. ثم في فرق git push لن يمتلكها GitLab.

قم بإعداد بيانات الاعتماد والمتغيرات

هل تتذكر كيف أضفنا مفتاح SSH محليًا لتسجيل الدخول إلى Pantheon و GitLab؟ يمكن استخدام رمز SSH لترخيص GitLab و Pantheon.

لدى GitLab وثائق رائعة. دعنا نرى راجع القسم الخاص بمفاتيح SSH عند استخدام منفذ Docker في المستند حول استخدام مفاتيح SSH مع GitLab CI / CD.

سنكمل الآن أول خطوتين: أنشئ زوج مفاتيح SSH جديدًا محليًا باستخدام ssh-keygen وأضف المفتاح الخاص كمتغير إلى المشروع.

ثم سنضع SSH_PRIVATE_KEY كيف متغير بيئة GitLab CI / CD في إعدادات المشروع.
في الخطوتين الثالثة والرابعة ، سننشئ ملفًا .gitlab-ci.yml بمحتوى مثل هذا:

before_script:
  # See https://docs.gitlab.com/ee/ci/ssh_keys/README.html
  - eval $(ssh-agent -s)
  - echo "$SSH_PRIVATE_KEY" | tr -d 'r' | ssh-add - > /dev/null
  - mkdir -p $HOME/.ssh && echo "StrictHostKeyChecking no" >> "$HOME/.ssh/config"
  - git config --global user.email "$GITLAB_USER_EMAIL"
  - git config --global user.name "Gitlab CI"

حتى نلتزم بالملف .gitlab-ci.yml، إذًا ستحتاج إلى إضافة شيء آخر إليها.

الآن قم بالخطوة الخامسة و أضف المفتاح العام الذي أنشأته في الخطوة الأولى إلى الخدمات التي تريد الوصول إليها في بيئة الإنشاء.

في حالتنا ، نريد الوصول إلى Pantheon من GitLab. اتبع التعليمات الواردة في مستند بانثيون إضافة مفتاح SSH إلى Pantheon ونفّذ هذه الخطوة.

تذكر: SSH مغلق في GitLab ، مفتوح في Pantheon.

لنقم بإعداد عدد قليل من متغيرات البيئة. الأول يسمى PANTHEON_SITE. قيمته هي اسم موقع Pantheon على جهازك.

يتم سرد الاسم الموجود على الجهاز في نهاية أمر Clone with Git. لقد قمت بالفعل باستنساخ الموقع محليًا ، لذلك سيكون هذا هو اسم الدليل للمستودع المحلي.

كيفية توصيل GitLab و Pantheon وتحسين سير عمل Drupal و WordPress

بعد ذلك ، قم بتعيين متغير البيئة PANTHEON_GIT_URL. هذا هو عنوان URL لمستودع Git الخاص بموقع Pantheon الذي استخدمناه بالفعل.

ندخل فقط عنوان URL الخاص بمستودع SSH ، بدون git clone واسم الموقع على الجهاز في النهاية.

تفو. تم ذلك ، والآن يمكننا إنهاء ملفنا .gitlab-ci.yml.

قم بإنشاء مهمة نشر

ما سنفعله باستخدام GitLab CI في البداية مشابه جدًا لما فعلناه مع مستودعات Git في الماضي. لكن هذه المرة ، دعنا نضيف مستودع Pantheon كمصدر ثانٍ عن بعد لـ Git ، ثم نرسل الكود من GitLab إلى Pantheon.

للقيام بذلك ، قم بتعيين مرحلة deploy и مهمة deploy:dev، لأننا سننتشر في بيئة التطوير في بانثيون. نتيجة لذلك ، الملف .gitlab-ci.yml سوف تبدو مثل هذا:

stages:
- deploy

before_script:
  # See https://docs.gitlab.com/ee/ci/ssh_keys/README.html
  - eval $(ssh-agent -s)
  - echo "$SSH_PRIVATE_KEY" | tr -d 'r' | ssh-add - > /dev/null
  - mkdir -p $HOME/.ssh && echo "StrictHostKeyChecking no" >> "$HOME/.ssh/config"
  - git config --global user.email "$GITLAB_USER_EMAIL"
  - git config --global user.name "Gitlab CI"

deploy:dev:
  stage: deploy
  environment:
    name: dev
    url: https://dev-$PANTHEON_SITE.pantheonsite.io/
  script:
    - git remote add pantheon $PANTHEON_GIT_URL
    - git push pantheon master --force
  only:
    - master

المتغيرات SSH_PRIVATE_KEY, PANTHEON_SITE и PANTHEON_GIT_URL يجب أن تبدو مألوفة - لقد أنشأنا متغيرات البيئة هذه من قبل. باستخدام هذه المتغيرات ، سنتمكن من استخدام القيم الموجودة في الملف .gitlab-ci.yml مرات عديدة ، وتحتاج فقط إلى تحديثها في مكان واحد.

أخيرًا ، قم بإضافة الملف والتزامه ودفعه .gitlab-ci.yml على جيتلاب.

التحقق من النشر

إذا فعلنا كل شيء بشكل صحيح ، المهمة deploy:dev سيتم تشغيله بنجاح في GitLab CI / CD ودفع الالتزام .gitlab-ci.yml في البانثيون. دعنا نلقي نظرة.

كيفية توصيل GitLab و Pantheon وتحسين سير عمل Drupal و WordPress

كيفية توصيل GitLab و Pantheon وتحسين سير عمل Drupal و WordPress

كيفية توصيل GitLab و Pantheon وتحسين سير عمل Drupal و WordPress

تقديم طلب دمج الفروع إلى بانثيون

هنا سوف نستخدم ميزة Pantheon المفضلة لدي - مولتيديفحيث يمكنك إنشاء بيئات Pantheon إضافية لفروع Git عند الطلب.

الوصول إلى multidev محدود، لذلك يمكن حذف هذا القسم. ولكن إذا كان لديك وصول ، يمكنك تحسين الأداء بشكل جدي من خلال إعداد الإنشاء التلقائي لبيئات multidev على Pantheon من طلبات دمج GitLab.

أولاً ، لنقم بإنشاء فرع Git جديد محليًا باستخدام git checkout -b multidev-support. الآن دعنا نغير شيئًا ما .gitlab-ci.yml.

أود تضمين رقم طلب الدمج في اسم بيئة Pantheon. على سبيل المثال ، طلب الدمج الأول هو mr-1، ثانية - mr-2 إلخ.

طلب الدمج يتغير لذا نحتاج إلى تحديد أسماء فروع Pantheon ديناميكيًا. في GitLab ، إنه سهل - تحتاج إلى استخدامه متغيرات البيئة المحددة مسبقًا.

يمكن أن نتخذها $CI_MERGE_REQUEST_IIDلتحديد رقم طلب الدمج. دعنا نطبق كل هذا جنبًا إلى جنب مع متغيرات البيئة العالمية التي حددناها سابقًا ونضيف نشرًا جديدًا: مهمة multidev في نهاية الملف .gitlab-ci.yml.

deploy:multidev:
  stage: deploy
  environment:
    name: multidev/mr-$CI_MERGE_REQUEST_IID
    url: https://mr-$CI_MERGE_REQUEST_IID-$PANTHEON_SITE.pantheonsite.io/
  script:
    # Checkout the merge request source branch
    - git checkout $CI_COMMIT_REF_NAME
    # Add the Pantheon git repository as an additional remote
    - git remote add pantheon $PANTHEON_GIT_URL
    # Push the merge request source branch to Pantheon
    - git push pantheon $CI_COMMIT_REF_NAME:mr-$CI_MERGE_REQUEST_IID --force
  only:
    - merge_requests

ستكون مماثلة لمهمتنا deploy:dev، فقط الفرع يذهب إلى البانثيون ، لا master.

لقد أضفنا والتزمنا بالملف المحدث .gitlab-ci.yml، والآن ادفع فرعًا جديدًا إلى GitLab باستخدام git push -u origin multidev-support.

لنقم الآن بإنشاء طلب دمج جديد من الفرع multidev-supportبالضغط إنشاء طلب دمج.

كيفية توصيل GitLab و Pantheon وتحسين سير عمل Drupal و WordPress

بعد إنشاء طلب دمج ، ننظر في كيفية تنفيذ مهمة CI / CD deploy:multidev.

كيفية توصيل GitLab و Pantheon وتحسين سير عمل Drupal و WordPress

انظر - تم إرسال فرع جديد إلى بانثيون. ولكن إذا انتقلنا إلى قسم multidev على لوحة معلومات موقع Pantheon ، فلن نرى البيئة الجديدة هناك

كيفية توصيل GitLab و Pantheon وتحسين سير عمل Drupal و WordPress

دعنا نلقي نظرة على قسم فروع Git.

كيفية توصيل GitLab و Pantheon وتحسين سير عمل Drupal و WordPress

نتيجة لذلك ، فرعنا mr-1 وصلت إلى البانثيون. خلق بيئة من الفرع mr-1.

كيفية توصيل GitLab و Pantheon وتحسين سير عمل Drupal و WordPress

لقد أنشأنا بيئة multidev ، والآن دعنا نعود إلى GitLab ونلقي نظرة على القسم العمليات> البيئات. سنرى مداخل ل dev и mr-1.

هذا لأننا أضفنا إدخالاً environment بالاسم name и url في مهام CI / CD. إذا نقرنا على أيقونة البيئة المفتوحة ، فسننتقل إلى عنوان URL لبيئة multidev على Pantheon.

أتمتة إنشاء multidev

من حيث المبدأ ، يمكنك التوقف هنا وتذكر فقط إنشاء بيئة multidev لكل طلب دمج ، ولكن يمكن أتمتة هذه العملية.

يحتوي Pantheon على أداة سطر أوامر نهايةحيث يمكنك العمل مع النظام الأساسي تلقائيًا. يسمح لك Terminus بإنشاء بيئات multidev من سطر الأوامر - مثالي لـ جيت لاب CI.

نحتاج إلى طلب دمج جديد لاختبار ذلك. إنشاء فرع جديد مع git checkout -b auto-multidev-creation.

لاستخدام Terminus في مهام GitLab CI / CD ، تحتاج إلى رمز مميز لجهاز للمصادقة مع Terminus وصورة حاوية Terminus.

إنشاء رمز مميز لآلة البانثيون، احفظه في مكان آمن وأضفه كمتغير بيئة عالمي في GitLab بالاسم PANTHEON_MACHINE_TOKEN.

إذا نسيت كيفية إضافة متغيرات بيئة GitLab ، فارجع إلى المكان الذي حددناه PANTHEON_SITE.

قم بإنشاء Dockerfile مع Terminus

إذا كنت لا تستخدم Docker أو لا تحب الملفات Dockerfileالتقط صورتي registry.gitlab.com/ataylorme/pantheon-gitlab-blog-demo:latest وتخطي هذا القسم.

لدى GitLab سجل حاوية، حيث يمكننا بناء واستضافة Dockerfile لمشروعنا. لنقم بإنشاء Dockerfile مع Terminus للعمل مع Pantheon.

Terminus هي أداة سطر أوامر PHP ، لذلك لنبدأ بصورة PHP. أقوم بتثبيت Terminus عبر Composer ، لذا سأستخدم صورة Docker Composer الرسمية. نخلق Dockerfile في دليل المستودع المحلي بالمحتوى التالي:

# Use the official Composer image as a parent image
FROM composer:1.8

# Update/upgrade apk
RUN apk update
RUN apk upgrade

# Make the Terminus directory
RUN mkdir -p /usr/local/share/terminus

# Install Terminus 2.x with Composer
RUN /usr/bin/env COMPOSER_BIN_DIR=/usr/local/bin composer -n --working-dir=/usr/local/share/terminus require pantheon-systems/terminus:"^2"

اتبع التعليمات الخاصة ببناء وإرسال الصور من القسم بناء الصور ودفعها в وثائق تسجيل الحاويةلتجميع صورة من Dockerfile وتقديمه إلى GitLab.

افتتاح القسم سجل في مشروع جيت لاب. إذا سار كل شيء وفقًا للخطة ، فستكون صورتنا موجودة. اكتب رابطًا لعلامة الصورة - نحتاجها للملف .gitlab-ci.yml.

كيفية توصيل GitLab و Pantheon وتحسين سير عمل Drupal و WordPress

قسم script في المهمة deploy:multidev يبدأ في النمو ، لذلك دعنا ننقله إلى ملف منفصل. قم بإنشاء ملف جديد private/multidev-deploy.sh:

#!/bin/bash

# Store the mr- environment name
export PANTHEON_ENV=mr-$CI_MERGE_REQUEST_IID

# Authenticate with Terminus
terminus auth:login --machine-token=$PANTHEON_MACHINE_TOKEN

# Checkout the merge request source branch
git checkout $CI_COMMIT_REF_NAME

# Add the Pantheon Git repository as an additional remote
git remote add pantheon $PANTHEON_GIT_URL

# Push the merge request source branch to Pantheon
git push pantheon $CI_COMMIT_REF_NAME:$PANTHEON_ENV --force

# Create a function for determining if a multidev exists
TERMINUS_DOES_MULTIDEV_EXIST()
{
    # Stash a list of Pantheon multidev environments
    PANTHEON_MULTIDEV_LIST="$(terminus multidev:list ${PANTHEON_SITE} --format=list --field=id)"

    while read -r multiDev; do
        if [[ "${multiDev}" == "$1" ]]
        then
            return 0;
        fi
    done <<< "$PANTHEON_MULTIDEV_LIST"

    return 1;
}

# If the mutltidev doesn't exist
if ! TERMINUS_DOES_MULTIDEV_EXIST $PANTHEON_ENV
then
    # Create it with Terminus
    echo "No multidev for $PANTHEON_ENV found, creating one..."
    terminus multidev:create $PANTHEON_SITE.dev $PANTHEON_ENV
else
    echo "The multidev $PANTHEON_ENV already exists, skipping creating it..."
fi

النص موجود في دليل خاص و لا يسمح بالوصول إلى الويب إلى بانثيون. لدينا برنامج نصي لمنطقنا متعدد الوسائط. لنقم بتحديث القسم الآن deploy:multidev ملف .gitlab-ci.ymlلجعلها تبدو كالتالي:

deploy:multidev:
  stage: deploy
  environment:
    name: multidev/mr-$CI_MERGE_REQUEST_IID
    url: https://mr-$CI_MERGE_REQUEST_IID-$PANTHEON_SITE.pantheonsite.io/
  script:
    # Run the multidev deploy script
    - "/bin/bash ./private/multidev-deploy.sh"
  only:
    - merge_requests

نحتاج إلى التأكد من تنفيذ مهامنا في الصورة المخصصة التي تم إنشاؤها ، لذلك دعونا نضيف تعريفًا image مع عنوان URL للتسجيل بتنسيق .gitlab-ci.yml. نتيجة لذلك ، لدينا مثل هذا الملف .gitlab-ci.yml:

image: registry.gitlab.com/ataylorme/pantheon-gitlab-blog-demo:latest

stages:
- deploy

before_script:
  # See https://docs.gitlab.com/ee/ci/ssh_keys/README.html
  - eval $(ssh-agent -s)
  - echo "$SSH_PRIVATE_KEY" | tr -d 'r' | ssh-add - > /dev/null
  - mkdir -p $HOME/.ssh && echo "StrictHostKeyChecking no" >> "$HOME/.ssh/config"
  - git config --global user.email "$GITLAB_USER_EMAIL"
  - git config --global user.name "Gitlab CI"

deploy:dev:
  stage: deploy
  environment:
    name: dev
    url: https://dev-$PANTHEON_SITE.pantheonsite.io/
  script:
    - git remote add pantheon $PANTHEON_GIT_URL
    - git push pantheon master --force
  only:
    - master

deploy:multidev:
  stage: deploy
  environment:
    name: multidev/mr-$CI_MERGE_REQUEST_IID
    url: https://mr-$CI_MERGE_REQUEST_IID-$PANTHEON_SITE.pantheonsite.io/
  script:
    # Run the multidev deploy script
    - "/bin/bash ./private/multidev-deploy.sh"
  only:
    - merge_requests

أضف والتزم وأرسل private/multidev-deploy.sh и .gitlab-ci.yml. نعود الآن إلى GitLab وننتظر حتى تكتمل مهمة CI / CD. تحلى بالصبر: يمكن أن يستغرق إنشاء multidev عدة دقائق.

ثم نذهب لإلقاء نظرة على قائمة multidev في البانثيون. يا معجزة! بيئة multidev mr-2 موجود هنا.

كيفية توصيل GitLab و Pantheon وتحسين سير عمل Drupal و WordPress

اختتام

استمتع فريقي كثيرًا عندما بدأنا في فتح طلبات الدمج وإنشاء البيئات تلقائيًا.

باستخدام الأدوات القوية لـ GitLab و Pantheon ، يمكنك توصيل GitLab بـ Pantheon تلقائيًا.

نظرًا لأننا نستخدم GitLab CI / CD ، فسيكون لسير العمل لدينا مجال للنمو. إليك بعض الأفكار لتبدأ بها:

اكتب رأيك في GitLab و Pantheon والأتمتة.

ملاحظة: هل تعلم أن Terminus ، أداة سطر أوامر Pantheon ، يمكن تمديدها عبر المكونات الإضافية?

لقد قمنا في Pantheon بعمل جيد في الإصدار 2 من البرنامج المساعد لأدوات بناء Terminus مع دعم GitLab. إذا كنت لا ترغب في العبث بالإعداد لكل مشروع ، فجرّب هذا المكون الإضافي وساعدنا في اختبار الإصدار التجريبي من الإصدار 2. لفريق Terminus build:project:create ما عليك سوى رمز بانثيون ورمز GitLab المميز. ستنشر أحد نماذج المشاريع باستخدام Composer والاختبار الآلي ، وإنشاء مشروع جديد في GitLab ، وهو موقع Pantheon جديد ، وربطها باستخدام متغيرات البيئة ومفاتيح SSH.

نبذة عن الكاتب

ينشئ Andrew Taylor أدوات للمطورين في البانتيون.

المصدر: www.habr.com

إضافة تعليق