CI/CD لـ Rust: أتمتة البناء والنشر من الصفر

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

لماذا يستحق مشروع Rust الخاص بك CI/CD حقيقي؟

\n\n

تخيل: أنت تكتب بلغة Rust، المترجم هو أفضل صديق لك، مدقق الاقتراض (borrow checker) لا يسمح لك بالاسترخاء، والكود يعمل بسرعة البرق. ولكن بمجرد أن تصل إلى مرحلة النشر، ينتهي السحر. تشغيل الاختبارات يدويًا، البناء على الجهاز المحلي، رفع الملف الثنائي إلى الخادم عبر SCP - هذا طريق إلى لا شيء. خاصة عندما يكبر المشروع ويظهر مطور ثانٍ في الفريق.

\n\n

CI/CD (التكامل المستمر / النشر المستمر) ليست مجرد كلمة طنانة. إنه نظام يتولى المهام الروتينية: تشغيل الاختبارات، التحقق من نمط الكود، بناء نسخة الإصدار وإرسالها إلى حيث يجب أن تعمل. بالنسبة لـ Rust، مع تركيزها على الموثوقية والأداء، فإن أتمتة البناء هي امتداد طبيعي لفلسفة اللغة.

\n\n

في هذه المقالة، سنقوم بإعداد خط أنابيب CI/CD لتطبيق Rust من الصفر باستخدام GitHub Actions. ستتعلم كيفية تنظيم الاختبار، التحليل البرمجي، بناء الملفات الثنائية لمنصات مختلفة والنشر. كل ذلك مع أمثلة كود حقيقية يمكنك نسخها إلى مشروعك.

\n\n

ماذا سنقوم بأتمتته؟

\n\n

قبل كتابة الكود، دعنا نحدد أهدافنا. سيقوم خط الأنابيب الخاص بنا بأربعة أشياء:

\n\n
    \n
  • التحليل البرمجي والتنسيق - لضمان مطابقة الكود لمعايير Rust وعدم احتوائه على أخطاء نموذجية.
  • \n
  • الاختبار - تشغيل جميع اختبارات الوحدة واختبارات التكامل إن وجدت.
  • \n
  • بناء الملف الثنائي - ترجمة نسخة محسنة (release).
  • \n
  • النشر - تحميل القطعة المُنشأة إلى الخادم أو إلى إصدارات GitHub.
  • \n
\n\n

كل هذا سيحدث تلقائيًا مع كل دفع إلى الفرع main أو عند إنشاء طلب سحب (pull request). يبدو كالسحر؟ في الواقع، إنها مجرد ملفات YAML وبضع أوامر Cargo.

\n\n

الخطوة 1: إعداد المشروع

\n\n

على سبيل المثال، سنأخذ خادم ويب بسيط باستخدام Actix-web. لكن خط الأنابيب عالمي: يناسب أي مشروع Rust، سواء كان أداة CLI، مكتبة أو خدمة مصغرة.

\n\n

لننشئ مشروعًا جديدًا:

\n\n
cargo new rust-ci-cd-demo --bin\ncd rust-ci-cd-demo
\n\n

أضف التبعيات في Cargo.toml:

\n\n
[dependencies]\nactix-web = "4"\nserde = { version = "1", features = ["derive"] }
\n\n

وكود بسيط في src/main.rs:

\n\n
use actix_web::{get, App, HttpResponse, HttpServer, Responder};\n\n#[get("/")]\nasync fn hello() -> impl Responder {\n    HttpResponse::Ok().body("Hello from Rust CI/CD!")\n}\n\n#[actix_web::main]\nasync fn main() -> std::io::Result<()> {\n    HttpServer::new(|| {\n        App::new().service(hello)\n    })\n    .bind(("0.0.0.0", 8080))?\n    .run()\n    .await\n}
\n\n

أضف اختبارًا بسيطًا في src/main.rs (في أسفل الملف):

\n\n
#[cfg(test)]\nmod tests {\n    use actix_web::{test, App, web};\n    use crate::hello;\n\n    #[actix_web::test]\n    async fn test_hello_endpoint() {\n        let app = test::init_service(App::new().service(hello)).await;\n        let req = test::TestRequest::get().uri("/").to_request();\n        let resp = test::call_service(&app, req).await;\n        assert!(resp.status().is_success());\n    }\n}
\n\n

كل شيء جاهز. الآن الجزء الممتع - إعداد CI/CD.

\n\n

الخطوة 2: إنشاء سير عمل GitHub Actions

\n\n

GitHub Actions هي أداة CI/CD مدمجة في GitHub. تعمل بناءً على ملفات YAML الموجودة في دليل .github/workflows/. لننشئه:

\n\n
mkdir -p .github/workflows\ntouch .github/workflows/ci.yml
\n\n

افتح ci.yml وابدأ في كتابة خط الأنابيب. سنسميه "Rust CI/CD Pipeline".

\n\n

المشغل الأساسي والبيئة

\n\n
name: Rust CI/CD Pipeline\n\non:\n  push:\n    branches: [ main ]\n  pull_request:\n    branches: [ main ]\n\nenv:\n  CARGO_TERM_CO                

المدونات

توصيات الكتب