Skip to content
Apothem
المرجع

بيان تثبيت الاعتماديات

سياسة الإعلان عن الاعتماديات تغطي نطاقات بيئة تشغيل Python، وأدوات التطوير، وملفات قفل أدوات الإصدار، والحدود الدنيا للإصدارات المُصادَق عليها لكل سطح بناء.

الموقف المُصادَق عليه لكيفية إعلان Apothem عن الاعتماديات وتثبيتها وقفلها. الجمهور: المساهمون والمستهلكون في المصبّ ممّن يحتاجون إلى فهم نموذج قابلية إعادة الإنتاج.

الموقف

Apothem هو واجهة سطر أوامر Python بمجموعة صغيرة من اعتماديات وقت التشغيل، إضافةً إلى سلسلة أدوات أكبر للتطوير والتدقيق والإصدار والتوثيق. تستخدم اعتماديات وقت التشغيل حدودًا دنيا متحفظة في pyproject.toml؛ ويُودِع الموقع site/package-lock.json؛ وتُثبَّت GitHub Actions بـSHA غير قابل للتغيير مع تعليقات الإصدار، وتُرقَّى عبر Dependabot.

الصنفالإعلانسياسة القفل
اعتماديات وقت تشغيل Python[project.dependencies] في pyproject.tomlنطاقات بحد أدنى للمستخدمين؛ ولا يأتي مع الحزمة أي قفل لوقت تشغيل Python. ويُثبِّت CI إغلاقًا مقفولًا بالتجزئة لهذه الاعتماديات (انظر أقفال اعتماديات CI)
أدوات التطوير / الأمانextras الخاصة بـ[project.optional-dependencies]نطاقات بحد أدنى، باستثناء ruff وmypy، إذ يُثبِّت extra dev كلًّا منهما تثبيتًا دقيقًا على الإصدار الذي يُشغِّله CI (انظر أقفال أدوات CI بخصوص ruff)؛ ويُثبِّت CI مكوّنات extra dev من إغلاق مقفول بالتجزئة (انظر أقفال اعتماديات CI)
أدوات الإصدارscripts/release/requirements-build-linux.txt لسير عمل الإصدار؛ وextra release في [project.optional-dependencies] لعمليات البناء المحليةمقفولة بالتجزئة لسير عمل الإصدار؛ مُولَّدة من إغلاق أدوات الإصدار. أما extra release فنطاق بحد أدنى
pip في CIscripts/ci/requirements-ci-pip.txtمقفول بالتجزئة: تثبيت واحد pip==X.Y.Z مع تجزئتَي حزمتَي wheel وsdist، ويُثبِّته بـ--require-hashes -r كلُّ سير عمل يُرقّي pip. يقترح Dependabot الترقيات ويعيد كتابة التجزئات؛ ويُبقي scripts/dev/check_pip_pin_drift.py التثبيت على pip 26.2 أو أحدث
أقفال اعتماديات CIscripts/ci/requirements-ci-dev.txt و-runtime.txt و-test.txt و-prereqs.txtإغلاقات موحَّدة لكل المنصات مقفولة بالتجزئة، تُولَّد بـuv pip compile من pyproject.toml (ومن متطلبات المضيف المسبقة للمحرّك في حالة -prereqs.txt) بحسب تاريخ قفل مطروحًا منه مهلة انتظار مدتها 7 أيام، ويُسجَّل كلاهما في كل ملف، وتُثبَّت بـ--require-hashes -r (والحزمة نفسها بـ--no-deps -e .). يختبر CI الإصدارات المقفولة إلى أن يعيد scripts/dev/refresh_ci_locks.py توليدها؛ ويدقّق pip-audit.yml أسبوعيًا أحدث الإصدارات المسموح بها، ويدقّق الأقفال أيضًا. ويفشل tests/scripts/test_ci_locks_fresh.py عندما يكفّ قفل عن تلبية مدخلاته
أقفال أدوات CIscripts/ci/requirements-ci-ruff.txt و-bandit.txt و-pip-audit.txt و-pip-licenses.txt و-pre-commit.txtإغلاق واحد مقفول بالتجزئة لكل أداة يُشغِّلها سير العمل، يُولِّده السكربت نفسه من مواصفة دقيقة في scripts/dev/ci_lock_table.py، بتاريخ القفل ومهلة الانتظار نفسيهما، ويُثبَّت بـ--require-hashes -r. ولا يذكر أي سير عمل إصدارَ أداة. يحتاج pre-commit إلى Python 3.11 أو أحدث، وكذلك قفله، ويُولَّد قفل pip-audit لـ3.11 أيضًا، لأن أحدث إصدار من filelock يدعم 3.10 عليه تنبيهات أمنية لم تُصلَح. ولا يُثبِّت pip أيُّ قفل سوى قفل pip في CI
موقع التوثيقsite/package.jsonsite/package-lock.json مُودَع ويستهلكه npm ci
مُحزِّم VS Codetools/vsce/package.jsontools/vsce/package-lock.json مُودَع؛ وتُشغِّل مهام الإصدار والنشر npm ci --ignore-scripts
واجهات سطر أوامر الأدوات المضيفة لاختبار القنوات السريعtools/channel-smoke/package.jsontools/channel-smoke/package-lock.json مُودَع ويستهلكه npm ci
GitHub Actionsمراجع uses: مُثبَّتة بـSHA مع تعليقات الإصداريقترح Dependabot تحديثات أسبوعية؛ وتحمل الاستثناءات علامات action-pinning-exempt:

مصادقة الإصدار

السطحالحالة المُصادَق عليهاالمسوّغ
اعتماديات وقت التشغيلتعيش الحدود الدنيا الحالية في pyproject.toml ضمن [project.dependencies]حدود دنيا مستقرّة حالية مُصادَق عليها قبل الإصدار؛ ولا يوجد مُعيق CVE معروف لوقت التشغيل
أدوات التطويرتعيش الحدود الدنيا الحالية في الإضافة dev من pyproject.toml؛ وفيها التثبيتان الدقيقان لـruff وmypyأحدث الحدود الدنيا المستقرّة المُصادَق عليها قبل الإصدار؛ ويُثبَّت كلٌّ من ruff وmypy على إصدار واحد للخطافات وCI والمساهمين، ويُثبِّت خطاف mypy المكتباتِ التي يسردها على إصداراتها في قفل dev، ويفشل tests/scripts/test_ci_tool_locks.py عند أي اختلاف بينها
أدوات الأمانتعيش الحدود الدنيا الحالية في الإضافة security من pyproject.tomlحدود دنيا حالية للماسحات مُصادَق عليها قبل الإصدار
أدوات الإصداريعيش الإغلاق المقفول بالتجزئة في scripts/release/requirements-build-linux.txtيُثبِّت سير عمل الإصدار بـ--require-hashes؛ وتشترط السكربتات المحلية وجود build مسبقًا بدلًا من تثبيت اعتماديات متحركة بصمت
pip في CIيعيش التثبيت المقفول بالتجزئة في scripts/ci/requirements-ci-pip.txtيسدّ pip 26.2 أو أحدث الثغرة CVE-2026-13346؛ ويُثبِّته سير العمل بـ--require-hashes، فيُطابَق التنزيل مع تجزئته المنشورة
أقفال اعتماديات CIتعيش الإغلاقات المقفولة بالتجزئة في scripts/ci/requirements-ci-{dev,runtime,test,prereqs}.txtيُثبِّتها سير العمل بـ--require-hashes؛ ويُسجِّل كلٌّ منها تاريخ قفله ومهلة الانتظار والتاريخ الفاصل، ويُبقيها اختبار الحداثة متوافقة مع pyproject.toml
أقفال أدوات CIتعيش الإغلاقات المقفولة بالتجزئة في scripts/ci/requirements-ci-{ruff,bandit,pip-audit,pip-licenses,pre-commit}.txtيُثبِّتها سير العمل بـ--require-hashes دون أن يذكر أي إصدار للأدوات؛ وتعيش المواصفات في scripts/dev/ci_lock_table.py، ويطابق تاريخ القفل ومهلة الانتظار والتاريخ الفاصل ما في أقفال الاعتماديات
أدوات التوثيقتعيش النطاقات الحالية في site/package.json، ويعيش الحلّ الدقيق في site/package-lock.jsonلا يُرجِع npm outdated أي اعتمادية توثيق متقادمة بعد تحديث ملف القفل
GitHub Actionsتُستبقى تثبيتات SHA الموجودة للإصدار الحالي؛ ويبقى سير عمل SLSA القابل لإعادة الاستخدام الاستثناءَ الموثَّق المُثبَّت بوسم، ويحمل تعليقَ action-pinning-exempt: في release.ymlإعادة تشغيل CI العام خضراء؛ وتُترَك عمدًا ترقيات الإصدارات الرئيسية الواسعة لـactions إلى طلبات سحب أتمتة الاعتماديات، لتفادي اضطراب سطح الإصدار
تحزيم npmيعمل سير عمل publish-npm.yml عند دفع الوسم v*.*.*، مع workflow_dispatch بديلًا احتياطيًاالحزمة npm العامة الوحيدة هي @ahmed-g-gad/apothem؛ وينتظر النشر موافقة المُشغِّل على بيئة release، وتُمنَح هذه الموافقة بعد اجتياز scripts/release/check-release-ready.sh

القفل

تُولَّد ملفات قفل Python الخاصة بالمساهمين عند الطلب ولا تُودَع، لأن إغلاق وقت تشغيل Apothem صغير، ولأن واجهة سطر الأوامر تدعم عدة إصدارات فرعية من Python. ويُستثنى CI من ذلك، إذ يُثبِّت الملفات المقفولة بالتجزئة في scripts/ci/: أربعة أقفال اعتماديات (requirements-ci-dev.txt و-runtime.txt و-test.txt و-prereqs.txt)، وقفل واحد لكل أداة يُشغِّلها سير العمل (-ruff.txt و-bandit.txt و-pip-audit.txt و-pip-licenses.txt و-pre-commit.txt). ويُولِّد python scripts/dev/refresh_ci_locks.py الملفات التسعة كلها بحسب تاريخ قفل مطروحًا منه مهلة انتظار مدتها 7 أيام تطابق مهلة Dependabot، فيختبر CI الإصدارات التي مضى على نشرها أسبوع على الأقل في تاريخ القفل، ويُقدِّمها تحديث الملفات إلى إصدارات أحدث. ويُسجِّل كل ملف تاريخ القفل ومهلة الانتظار والتاريخ الفاصل الناتج، ويُعيد --check إنتاج ذلك التاريخ الفاصل. ويحتاج إصلاح أمني عاجل أحدث من مهلة الانتظار إلى تشغيل تحديث بـ--cooldown-days 0، أو إلى استثناء من مهلة الانتظار لحزمته في scripts/dev/ci_lock_table.py يرفع المهلة عن تلك الحزمة وحدها. ويدقّق التشغيل الأسبوعي لـpip-audit.yml أحدث الإصدارات التي يسمح بها pyproject.toml إضافةً إلى الأقفال التسعة، ويستعلم خدمة OSV عن التنبيهات الأمنية. ويواصل المساهمون التثبيت بـpip install -e ".[dev]".

# Astral uv:
uv pip install -e ".[dev,security,release]"
uv pip freeze > requirements.dev.lock

# pip-tools:
pip-compile --extra=dev --extra=security --extra=release -o requirements.dev.lock pyproject.toml

# Plain pip:
pip install -e ".[dev,security,release]"
pip freeze > requirements.dev.lock

أما الموقع فمختلف: يُودَع site/package-lock.json ويستخدم CI الأمر npm ci، فيكون لموقع التوثيق الناتج إغلاق Node قابل لإعادة الإنتاج.

المسوّغ

  • لماذا تثبيت بالنطاقات لـPython؟ تدعم واجهة سطر الأوامر مصفوفة Python واسعة، لذا يحتفظ pyproject.toml بحدود دنيا متحفظة. ويُثبِّت CI إغلاقات مقفولة بالتجزئة لهذه النطاقات، يُحدِّثها القائم على صيانة المشروع بـscripts/dev/refresh_ci_locks.py (والوتيرة المقصودة أسبوعية)، ويحلّ التشغيل الأسبوعي لـpip-audit.yml أحدث الإصدارات المسموح بها ليكشف المشكلات مع الأدوات الحالية.
  • لماذا قفل Node مُودَع؟ الموقع مُنتَج ساكن منشور؛ ويمنح ملف القفل عمليات بناء npm ci حتمية لذلك السطح العام.
  • لماذا Actions مُثبَّتة بـSHA؟ الوسوم قابلة للتغيير؛ أما SHA فغير قابلة للتغيير. يقترح Dependabot ترقيات SHA ويعيد كتابة كل تعليق إصدار، بينما تُسجِّل بوابة الإصدار أي تأجيل مقصود.
  • ما لا تلمسه أداة التحديث الآلية. تغطي تحديثات الإصدارات في Dependabot (.github/dependabot.yml) تثبيتات GitHub Actions، وملف قفل الموقع، وملف قفل مُحزِّم vsce (tools/vsce)، وملف قفل واجهات سطر أوامر الأدوات المضيفة الذي يُثبِّته اختبار القنوات السريع (tools/channel-smoke)، وpip المقفول بالتجزئة الذي يُثبِّته CI (scripts/ci/requirements-ci-pip.txt)، وخطافات pre-commit. والملفات التسعة الأخرى في scripts/ci إغلاقاتٌ يُعاد توليدها كاملةً بـscripts/dev/refresh_ci_locks.py، ولا يُثبِّت أيٌّ منها pip، وتقتصر تحديثات الإصدارات في Dependabot لذلك المجلد على pip. أما الحدود الدنيا لوقت التشغيل في pyproject.toml، ومتطلبات الإصدار المقفولة بالتجزئة، والإغلاق المُضمَّن في src/apothem/_vendor/vendor.txt، وخطافات pre-commit المُثبَّتة بالتوازي مع pyproject.toml، فتُحدَّث يدويًا، لأن ترقية تثبيت منفرد ستكسر الملفات التي تتوافق معها. وخطافا ruff وmypy اثنان منها: يفشل tests/scripts/test_ci_tool_locks.py إلى أن يحمل التثبيت الدقيق لـruff في pyproject.toml وrev الخطاف وقفل ruff وقفل dev إصدارًا واحدًا، وإلى أن يطابق التثبيت الدقيق لـmypy وrev خطاف mypy والمكتبات التي يسردها ذلك الخطاف قفلَ dev. لذا يُكيَّف يدويًا أي طلب سحب أمني من Dependabot لأيٍّ من الأداتين. يتبع الإصدار الرئيسي لـ@types/node في الموقع الحدَّ الأدنى لـNode (engines و.nvmrc، Node 22)، فلا يقترح Dependabot إلا تحديثاته الفرعية والتصحيحية؛ ارفع ذلك الإصدار الرئيسي مع الحد الأدنى معًا. تترك تحديثات الإصدارات كتل overrides في npm دون مساس. أما تحديثات الأمان في Dependabot فتظل تغطي كل بيان، لذا قد يقترح طلب سحب أمني أحد هذه التثبيتات، أو ينقل تجاوزًا؛ فكيِّفه يدويًا أو أغلقه.
  • دمج طلب سحب من Dependabot. يأخذ الدمج الافتراضي بالضغط (squash) في المستودع عنوانَ طلب السحب. وبعض عناوين Dependabot، ومعظمها عناوين مُجمَّعة تُسمّي مجلدًا، تتجاوز سطر موضوع الضغط البالغ 72 حرفًا؛ ويُسمّيها فحص PR Title، ويُصلحها تغيير العنوان. ولا يُشغِّل طلب السحب الذي يغيّر ملف قفل أداة أي مهمة من ci.yml، لذا يدقّقه سير عمل تدقيق npm ويُثبِّته، ويُحزِّم امتداد VS Code لملف قفل vsce ويُشغِّل اختبارات إصدار vsce، ويعمل سير عمل اختبار القنوات السريع لملف قفل channel-smoke. ويُشغِّل سير عمل Markdown Lint خطاف markdownlint على طلب سحب خطافات pre-commit؛ أما الخطافات الأخرى فلا تُختبَر في CI، لذا شغِّل pre-commit run --all-files على فرعه قبل دمجه.

On this page