
واجهة سطر أوامر بلغة Python تقوم بإنشاء مستودعات GitHub مع إعدادات افتراضية آمنة — حماية الفروع، Dependabot، فحص الأسرار، وفحص أمني قبل التنفيذ — مطبقة تلقائيًا.
إنشاء مستودعات GitHub مع إعدادات افتراضية آمنة تُطبق تلقائيًا. يستبدل قائمة التحقق من الإعدادات بعد الإنشاء التي تستغرق خمس دقائق بأمر واحد.``` gh-safe-repo create <owner/repo>
حماية الفرع، العلامات غير القابلة للتغيير، Dependabot، صلاحيات الإجراءات المقيدة، فحص الأسرار مع حماية الدفع، وتعطيل الويكي والمشاريع — كلها تم تكوينها قبل كتابة أول سطر من الكود الخاص بك.
gh-safe-repo قيد التطوير النشط. يعمل بشكل جيد لحالة الاستخدام المتمثلة في إنشاء مستودع جديد بإعدادات افتراضية آمنة. أعمل على تحسين خيارات واجهة سطر الأوامر لتتوافق بشكل أفضل مع توقعات المستخدمين. توقع تغييرات جوهرية حتى نصل إلى نقطة أقوم فيها بإصدار الإصدارات وتكون التكامل المستمر/النشر المستمر مستقرة. ✌️
---
## جدول المحتويات
- [لماذا](#why)
- [ما الذي يغيره](#what-it-changes)
- [المتطلبات](#requirements)
- [التثبيت](#installation)
- [بدء سريع](#quick-start)
- [مرجع واجهة سطر الأوامر](#cli-reference)
- [مخرجات التشغيل التجريبي / الخطة](#dry-run--plan-output)
- [وضع الإصلاح (تدقيق المستودعات الموجودة)](#fix-mode-audit-existing-repos)
- [نسخ المستودعات (`--from`)](#mirroring-repos---from)
- [إنشاء مستودع من دليل محلي (`--local`)](#creating-a-repo-from-a-local-directory---local)
- [ماسح الأمان قبل التشغيل](#pre-flight-security-scanner)
- [فحص مستقل](#standalone-scan)
- [إخفاء النتائج الإيجابية الكاذبة](#suppressing-false-positives)
- [التكوين](#configuration)
- [قيود خطة GitHub](#github-plan-limitations)
- [كيف يعمل](#how-it-works)
- [التطوير](#development)
---
## لماذا
إعدادات المستودع الافتراضية في GitHub محسّنة من أجل سهولة الاكتشاف والمرونة، وليس الأمان. كل مستودع جديد يأتي مع:
- تمكين الويكي والمشاريع (سطح هجوم، حتى لو لم يتم استخدامها)
- السماح بعمليات الدمج (تاريخ فوضوي، لكن ليس القلق الرئيسي)
- لا توجد حماية للفرع (أي شخص لديه صلاحيات كتابة يمكنه الدفع مباشرة إلى `main`)
- لا توجد تنبيهات Dependabot
- إجراءات GitHub بصلاحيات كتابة إلى المستودع
- الإجراءات مسموح لها بالموافقة على طلبات السحب
إصلاح كل هذا يدويًا يستغرق دقائق لكل مستودع ويسهل نسيانه. يطبق `gh-safe-repo` مجموعة افتراضية رأيوية ولكنها عملية في دفعة واحدة، مع معاينة للخطة حتى تعرف بالضبط ما الذي سيتغير قبل حدوث أي شيء.
---
## ما الذي يغيره
### إعدادات المستودع
| الإعداد | الافتراضي في GitHub | الافتراضي الآمن | ملاحظات |
|---|---|---|---|
| الرؤية | عام | **خاص** | استخدم `--public` للتجاوز |
| الويكي | ممكّن | **معطل** | |
| المشاريع | ممكّن | **معطل** | |
| المشكلات | ممكّن | ممكّن | |
| حذف الفرع عند الدمج | غير مفعل | غير مفعل | اضبط على `true` في التكوين للتنظيف التلقائي |
| السماح بعمليات دمج الدمج | مفعل | مفعل | اضبط على `false` في التكوين لـ squash-only |
| السماح بعملية دمج squash | مفعل | مفعل | |
| السماح بعملية دمج rebase | مفعل | مفعل | |
### إجراءات GitHub
| الإعداد | الافتراضي في GitHub | الافتراضي الآمن |
|---|---|---|
| الإجراءات المسموح بها | الكل | **محدد** (المملوكة من GitHub + المنشئين الموثوقين؛ قابل للتخصيص) |
| صلاحيات سير العمل الافتراضية | قراءة/كتابة | **للقراءة فقط** |
| يمكن للإجراءات الموافقة على طلبات السحب | نعم | **لا** |
| طلب تثبيت SHA | لا | **نعم** (يجب أن تثبت سير العمل الإجراءات إلى SHA commit، وليس علامة قابلة للتغيير) |
| سياسة الموافقة على طلبات سحب الفروع المتفرعة | المساهمون الجدد لأول مرة في GitHub | **جميع المساهمين الخارجيين** — طلب الموافقة قبل تشغيل CI لسير العمل الخاص بطلبات السحب المتفرعة. الخيارات: حسابات GitHub الجديدة فقط (الإعداد الافتراضي لـ GitHub)، المساهمون الجدد في المستودع، أو جميع طلبات السحب المتفرعة (الأكثر أمانًا) |
### حماية الفرع (المستودعات العامة، أو أي مستودع على خطة مدفوعة)
| القاعدة | القيمة |
|---|---|
| طلب طلب سحب قبل الدمج | نعم |
| عدد المراجعات المعتمدة المطلوبة | 1 |
| تجاهل المراجعات القديمة عند الدفع | نعم |
| طلب حل المحادثات | نعم |
| السماح بدفع القوي | لا |
| السماح بحذف الفرع | لا |
| تطبيق على المسؤولين | لا (يسمح لأدوات المالك بالدفع) |
يتم تطبيق حماية الفرع عبر **واجهة برمجة تطبيقات Rulesets** افتراضيًا (`use_rulesets = true`): قاعدة واحدة `gh-safe-repo defaults` تغطي كل فرع مُكوّن وتعبر عن "يمكن للمسؤولين التجاوز" من خلال ممثل تجاوز بدلاً من علم `enforce_admins` الكلاسيكي. اضبط `use_rulesets = false` للمسار الكلاسيكي القديم لكل فرع (يُحتفظ به لدورة إصدار واحدة).
**ترحيل مستودع موجود من الحماية الكلاسيكية:** إذا اكتشف `fix` حماية فرع كلاسيكية على مستودع، فإنه يرفض تحويلها إلى قاعدة ruleset ما لم تمرر `--migrate-branch-protection`. القواعد الكلاسيكية فقط ليس لها ما يعادلها في قاعدة ruleset التي تبنيها هذه الأداة وسيتم إسقاطها بصمت خلاف ذلك — الفجوات المعروفة:
- `required_status_checks` — فحوصات CI المطلوبة ليست نموذجية في جسم قاعدة ruleset.
- `restrictions` (قيود الدفع حسب المستخدم/الفريق) — تتعامل Rulesets مع هذا بشكل مختلف عبر ممثلين تجاوز؛ ليست خريطة 1:1.
- الاختلاف لكل فرع — لا يمكن لقاعدة ruleset ذات شرط مشترك واحد التعبير عن قواعد مختلفة لـ `master` مقابل `main`.
مع العلم، يقوم `fix` بإنشاء/تحديث قاعدة ruleset ثم يحذف الحماية الكلاسيكية على كل فرع بحيث لا تتراكم الطبقتان.
### حماية العلامات (المستودعات العامة، أو أي مستودع على خطة مدفوعة)
تنشئ حماية العلامات قاعدة Ruleset في GitHub تستهدف جميع العلامات (`*` افتراضيًا، قابل للتكوين عبر `protected_tags`). يتم فرض القواعد التالية:
| قاعدة قاعدة Ruleset | مفروضة؟ | ملاحظات |
|---|---|---|
| تقييد الإنشاءات | لا | |
| **تقييد التحديثات** | **نعم** | يمنع إعادة كتابة / دفع القوي للعلامات |
| **تقييد الحذف** | **نعم** | يمنع `git push --delete` للعلامات |
| طلب تاريخ خطي | لا | |
| طلب نجاح النشر | لا | |
| طلب التوقيع على الالتزامات | لا | |
| طلب اجتياز فحوصات الحالة | لا | |
| حظر دفع القوي | لا | |
مسؤولو المستودع موجودون في قائمة التجاوز (متسق مع الإعداد الافتراضي `enforce_admins = false` لحماية الفرع). يعمل فقط على المستودعات العامة أو خطط GitHub المدفوعة (نفس القيد مثل حماية الفرع). المستودعات الخاصة ذات الخطة المجانية سترى هذا مُتجاهلاً في مخرجات الخطة.
### الأمان
| الميزة | السلوك |
|---|---|
| تنبيهات Dependabot | ممكّنة (المستودعات العامة / الخطط المدفوعة) |
| تحديثات أمان Dependabot | ممكّنة (تفتح تلقائيًا طلبات سحب للتبعيات الضعيفة) |
| فحص الأسرار | تلقائي على المستودعات العامة؛ ممكّن على الخطط الخاصة المدفوعة |
| حماية الدفع | ممكّنة (تمنع الالتزامات التي تحتوي على أسرار مدعومة) |
| الإبلاغ عن الثغرات الخاصة | ممكّن (يسمح لباحثي الأمن بالإبلاغ بشكل خاص) |
| رسم بياني للتبعيات | تلقائي على المستودعات العامة؛ لا توجد واجهة برمجة تطبيقات REST للخاص (واجهة مستخدم فقط) |
---
## المتطلبات
- Python 3.8+
- [`gh` CLI](https://cli.github.com/) مثبت ومصدق (`gh auth login`)، **أو** `GITHUB_TOKEN` مضبوط في بيئتك
- لـ `--local` / `--from` (التي تدفع أو تستنسخ الكود): يجب إعداد بيانات اعتماد git الخاصة بك — إما مفتاح SSH محمل في `ssh-agent` (عندما يكون `gh config get git_protocol` هو `ssh`) أو مساعد بيانات اعتماد HTTPS (`gh auth setup-git` يكوّن واحدًا تلقائيًا). لا يتم استخدام رمز OAuth لـ git push، لذا يتم دفع ملفات سير العمل (`.github/workflows/*`) دون الحاجة إلى نطاق `workflow` في OAuth.
- [`uv`](https://docs.astral.sh/uv/) للتثبيت من المصدر (موصى به)
- `truffleHog` v3 (اختياري — يستخدمه الماسح قبل التشغيل؛ يتم اكتشافه تلقائيًا من PATH، أو يعمل عبر podman/docker؛ يتراجع إلى التعبيرات العادية إذا لم يكن أي منهما متاحًا)
---
## التثبيت
### من المصدر باستخدام uv (موصى به)```bash
git clone https://github.com/your-username/gh-safe-repo
cd gh-safe-repo
uv tool install .
هذا يقوم بتثبيت gh-safe-repo في بيئة أدوات uv ويضيفه إلى PATH الخاص بك.
git clone https://github.com/your-username/gh-safe-repo cd gh-safe-repo uv sync # creates .venv ./gh-safe-repo create <owner/repo>
### تحقق```bash
gh-safe-repo --help
gh-safe-repo create <owner/repo>
gh-safe-repo create <owner/repo> --dry-run
gh-safe-repo create <owner/repo> --public
gh-safe-repo create <owner/repo> --from <owner/source>
gh-safe-repo create <owner/pub> --from <owner/priv> --public
gh-safe-repo create <owner/repo> --local ~/projects/myapp
gh-safe-repo create <owner/repo> --local ~/projects/myapp --public
gh-safe-repo fix <owner/repo>
gh-safe-repo fix <owner/repo> --dry-run
gh-safe-repo fix <owner/repo> --yes
gh-safe-repo scan . gh-safe-repo scan ~/projects/myapp
## مرجع CLI```
gh-safe-repo create <owner/repo> [OPTIONS]
gh-safe-repo fix <owner/repo> [OPTIONS]
gh-safe-repo scan <path> [OPTIONS]
تتطلب جميع الأوامر التي تتفاعل مع GitHub صيغة owner/repo (مثل myuser/my-repo). بالنسبة لـ create، يتم التحقق من المالك مقابل حساب GitHub المُوثق لديك لمنع الأخطاء على الأنظمة متعددة الحسابات. بالنسبة لـ fix، يلزم الحصول على أذونات مسؤول في المستودع المستهدف بدلاً من ذلك، مما يسمح لك بإصلاح المستودعات المملوكة للمؤسسات أو الحسابات الأخرى حيث لديك صلاحيات مسؤول.
create — إنشاء مستودع جديدcreate عادي (بدون --local/--from) يقوم بتهيئة المستودع بحيث يوجد فرع افتراضي لحماية الفرع، ثم يزيل ملف README.md المُنشأ تلقائيًا حتى يبدأ المستودع الجديد نظيفًا. قم بتعيين auto_init = true في التكوين للاحتفاظ بملف README بدلاً من ذلك. --local/--from يدفعان تاريخك الخاص ولا ينشئان ملف README أبدًا.
fix — تدقيق وإصلاح مستودع موجودscan — فحص محلي للأسرار| الخيار | الوصف |
|---|---|
--config [PATH] | مسار ملف التكوين؛ --config فقط يستخدم الإعدادات الافتراضية المضمنة فقط |
--debug | إظهار تفاصيل الماسح الضوئي |
رمز الخروج هو 0 إذا لم تكن هناك نتائج حرجة، و1 إذا تم العثور على نتائج حرجة.
يظهر --dry-run بالضبط ما سيفعله gh-safe-repo، دون إجراء أي تغييرات أو استدعاءات API. استخدمه قبل التشغيل الفعلي. ادمجه مع --json للحصول على مخرجات خطة قابلة للقراءة آليًا:```bash
gh-safe-repo create <owner/repo> --dry-run --json
gh-safe-repo fix <owner/repo> --dry-run --json
عندما يكون `--json` نشطًا، يتم كتابة الخطة إلى stdout ككائن JSON وتذهب جميع الرسائل الأخرى (التقدم، التحذيرات، تذييل "Dry run") إلى stderr، بحيث يكون الإخراج نظيفًا للأنابيب أو البرمجة النصية.```
$ gh-safe-repo create <owner/repo> --dry-run
Plan for my-project (private)
Category Action Setting Value
──────────────────────────────────────────────────────────────────
Repository ADD repository my-project (private)
Repository ADD has_wiki false
Repository ADD has_projects false
Actions ADD default_workflow_permissions read
Actions ADD can_approve_pull_request_reviews false
Branch Protection SKIP branch_protection Not available for private repos on free plan
Security SKIP dependabot_alerts Not available for private repos on free plan
1 setting skipped (GitHub plan limitation).
Dry run — no changes made.
ألوان الإجراءات:
| الإجراء | المعنى |
|---|
مخرجات JSON (--json):```json
{
"changes": [
{ "type": "add", "category": "repository", "key": "has_wiki", "old": null, "new": false, "reason": null },
{ "type": "skip", "category": "branch_protection", "key": "branch_protection", "old": null, "new": null, "reason": "Not available for private repos on free plan" }
],
"summary": { "add": 5, "skip": 2 }
}
`summary` يتضمن فقط الأنواع الموجودة في الخطة. يجب على المستهلكين استخدام `.get("delete", 0)` إلخ. بدلاً من افتراض وجود جميع المفاتيح الأربعة.
---
## وضع الإصلاح (تدقيق المستودعات الحالية)
يقارن `fix` الإعدادات الحالية لمستودع موجود مع الإعدادات الافتراضية الآمنة ويطبق أي تصحيحات. لا يوجد فحص للأسرار — `fix` هو فقط حول إعدادات المستودع.```bash
# See what's out of compliance
gh-safe-repo fix <owner/repo> --dry-run
# Apply missing safe defaults
gh-safe-repo fix <owner/repo>
# Apply without confirmation prompt (scripting/batch use)
gh-safe-repo fix <owner/repo> --yes
وضع الإصلاح:
UPDATE للإعدادات المتغيرة و SKIP للإعدادات التي تبلغ بالفعل القيمة المرغوبة (كشف عدم التأثير — لا يقوم أبدًا بإجراء استدعاءات API من شأنها تغيير شيء)--yes)يتم تطبيق التغييرات الفعلية فقط — يتم عرض الإعدادات التي تبلغ بالفعل القيمة المرغوبة كـ SKIP ولا تولد أي استدعاءات API.
--from)--from ينسخ مستودعًا موجودًا إلى مستودع جديد بإعدادات آمنة افتراضية. يعمل مع الوجهات الخاصة والعامة على حد سواء:```bash
gh-safe-repo create <owner/repo> --from <owner/source>
gh-safe-repo create <owner/pub> --from <owner/priv> --public
**ما يحدث، بالترتيب:**
1. يتم التحقق من بيانات اعتماد git الخاصة بك لـ `github.com` مسبقًا (استقصاء SSH عندما يكون `gh config get git_protocol` هو `ssh`؛ يتم الوثوق بـ HTTPS)، لذا فإن المفتاح المفقود يفشل بسرعة قبل إنشاء أي مستودع
2. يتم استنساخ المستودع المصدر محليًا (استنساخ كامل، بدون `--depth`، حتى يتمكن truffleHog من تجاوز سجل الالتزامات الكامل)
3. يتم تشغيل [الماسح الضوئي الأمني الأولي](#pre-flight-security-scanner) على الاستنساخ المحلي
4. تقوم بمراجعة النتائج والتأكيد (أو الإنهاء)
5. يتم إنشاء مستودع جديد (خاص افتراضيًا، أو عام مع `--public`)
6. يتم تطبيق أذونات الإجراءات والإعدادات الأمنية (Dependabot، فحص الأسرار، حماية الدفع)
7. يتم عكس السجل الكامل: `git clone --mirror` + `git push --mirror`
8. يتم تطبيق حماية الفرع والعلامة (بعد دفع الكود، حتى يكون الفرع الهدف موجودًا)
إذا كشف الفحص عن مشكلة وقمت بالإنهاء، فلن يتم نسخ أي كود إلى GitHub.
> **ملاحظة:** يستخدم `--from` تنسيق `owner/repo` لكل من المصدر والوجهة.
---
## إنشاء مستودع من دليل محلي (`--local`)
`--local PATH` هو النظير المحلي إلى GitHub لـ `--from`. يقوم بإنشاء مستودع GitHub جديد ويدفع الكود من مستودع git محلي. يجب أن يكون `PATH` مستودع git مهيأ (`git init` أو استنساخ).```bash
gh-safe-repo create <owner/repo> --local ~/projects/myapp
gh-safe-repo create <owner/repo> --local ~/projects/myapp --public
ما يحدث، بالترتيب:
github.com مقدمًا (فحص SSH عندما يكون gh config get git_protocol هو ssh؛ ويتم الوثوق بـ HTTPS)، لذا فإن المفتاح المفقود يفشل بسرعة قبل إنشاء أي مستودعpush --all --tags (جميع الفروع والوسوم)origin إلى المستودع المحلي الأصلي مشيرًا إلى رابط GitHub الجديد، ويتم تكوين تتبع الفرع الحالي لأعلى الدفق — لذا يعمل git push و git pull فورًا دون إعداد إضافي.كلا الخيارين --local و --from يعملان مع المستودعات الخاصة والعامة. وهما متعارضان.
يتم استخدام الفرع الافتراضي المحلي (عبر git -C PATH symbolic-ref HEAD) لتوجيه قواعد حماية الفرع، لذا تصل الحماية إلى الفرع الصحيح حتى لو لم يكن main.
نصيحة: قم بتشغيل
gh-safe-repo scan PATHأولاً إذا كنت تريد فحص النتائج دون إنشاء أي شيء.
يعمل الماسح محليًا ولا يرسل الكود إلى GitHub أبدًا. استخدمه بشكل مستقل قبل أي دفع، أو يعمل تلقائيًا كجزء من سير العمل --from و --local.
gh-safe-repo scan .
gh-safe-repo scan ~/projects/myapp
رمز الخروج هو `0` إذا لم يتم العثور على نتائج حرجة، و `1` إذا تم العثور على نتائج حرجة — بحيث يتكامل بسلاسة مع الأوامر الأخرى:```bash
gh-safe-repo scan . && git push
التكوين الكامل لـ [pre_flight_scan] ينطبق: banned_strings، max_file_size_mb، trufflehog_mode، إلخ.
gh-safe-repo يختار تلقائياً أفضل ماسح ضوئي متاح باستخدام سلسلة اكتشاف من ثلاث خطوات:
trufflehog --version، ويتحقق من أنه الإصدار v3، ويستخدمه. إذا كان الإصدار v2 أو إصدار غير معروف، يطبع تحذيراً وينتقل إلى الخطوة 2.ghcr.io/trufflesecurity/trufflehog:latest) باستخدام podman run أو docker run، مع تثبيت مسح المسار للقراءة فقط بنفس المسار المطلق بحيث تكون مسارات إخراج JSON متطابقة مع التشغيل المحلي.يظهر الماسح الضوئي المختار في رأس "تشغيل الفحص الأمني قبل الرحلة..." وفي إدخال SCAN في جدول الخطة، على سبيل المثال:``` Running pre-flight security scan... (truffleHog v3.93.4) Running pre-flight security scan... (truffleHog via podman) Running pre-flight security scan... (regex only — see warning above)
متغيرات البيئة التي يحترمها مسار الحاوية: `CONTAINER_RUNTIME` لتجاوز اختيار وقت التشغيل (مثل `CONTAINER_RUNTIME=docker`)، و`TRUFFLEHOG_IMAGE` لتثبيت علامة صورة محددة.
### تشغيل truffleHog عبر podman أو Docker (بدون تثبيت محلي)
لا يلزم إعداد يدوي. يكتشف `gh-safe-repo` podman أو docker تلقائيًا (الخطوة 2 أعلاه) ويشغل truffleHog في حاوية مع عمليات تحميل الحجم الصحيحة. يتم احترام متغيرات البيئة `CONTAINER_RUNTIME` و`TRUFFLEHOG_IMAGE`.
يتم توفير غلاف شل (`tools/trufflehog`) و`Containerfile` لبناء صورة محلية مثبتة في [`tools/`](https://github.com/ariesq/gh-safe-repo/blob/HEAD/tools/README.md) للمستخدمين الذين يرغبون في توفر truffleHog المستند إلى الحاوية على مستوى النظام، أو الذين يحتاجون إلى صورة معزولة (air-gapped).
### المراجعة التفاعلية```
Pre-flight scan: my-private-project
CRITICAL my_private_project/config.py:12 AWS Access Key ID
[redacted]
WARNING my_private_project/setup.py:3 Email address
author_email="[email protected]"
1 critical finding, 1 warning.
Critical findings detected. Continue anyway? [y/N]:
N). يجب عليك كتابة y صراحةً للمتابعة.Y). اضغط Enter للمتابعة أو اكتب n للإجهاض.يتم حذف الأسرار في المخرجات. تظهر عناوين البريد الإلكتروني والـ TODOs السطر المطابق.
يتم تخطي أدلة القطع الأثرية للبناء (node_modules, __pycache__, .venv, venv, dist, build) افتراضيًا للحفاظ على سرعة الفحص. في مستودعات git، يكون هذا التخطي مشروطًا: قبل حذف دليل، يقوم الماسح بتشغيل git ls-files -- <dir> للتحقق مما إذا كانت أي ملفات بداخله متعقبة. إذا كانت كذلك، يتم فحص الدليل بشكل طبيعي.
هذا يعني أن أشجار node_modules أو dist الملتزمة — غير معتادة، ولكنها تحدث — لا يتم تفويتها بصمت. تستمر الأدلة غير الملتزمة (الحالة الطبيعية) في التخطي كما كان من قبل.
لا يزال يتم طباعة تحذير عند العثور على أدلة فرعية SKIP_DIRS في مستودع مصدر مستنسخ، لأن وجودها قد يشير إلى أن محتوى أكثر من المتوقع قد تم التزامه.
يسمح لك مفتاحا تكوين بقمع النتائج المعروفة بأنها آمنة دون تعطيل فئات الفحص بأكملها.
scan_exclude_paths — تخطي الملفات أو الأدلة بالكامل. القيم هي أنماط regex مفصولة بسطر جديد/فاصلة مطابقة لمسار الملف النسبي. يتم استبعاد الملف المطابق من كل فحص: الأسرار، رسائل البريد الإلكتروني، TODOs، الملفات الكبيرة، واكتشاف ملفات سياق الذكاء الاصطناعي. يتم أيضًا تمرير نفس الأنماط إلى truffleHog عبر --exclude-paths، لذا تكون التغطية متسقة بغض النظر عن محرك الفحص النشط.```ini
[pre_flight_scan]
scan_exclude_paths = docs/api.github.com.json tests/fixtures/
**`exclude_emails`** — قم بإخفاء نتائج البريد الإلكتروني لعناوين أو نطاقات محددة. القيم مفصولة بأسطر جديدة أو فواصل، غير حساسة لحالة الأحرف. المدخلات التي تبدأ بـ `@` تطابق جميع رسائل البريد الإلكتروني في ذلك النطاق؛ وإلا يجب أن يطابق المدخل العنوان الكامل تمامًا. ينطبق على نتائج شجرة العمل وتاريخ git معًا.```ini
[pre_flight_scan]
# Suppress bot addresses and placeholder domains
exclude_emails = [email protected], [email protected], @example.com
[pre_flight_scan] scan_for_secrets = true scan_for_emails = true scan_for_todos = true max_file_size_mb = 100
عند العثور على سلاسل محظورة أو ملفات سياق الذكاء الاصطناعي، يقوم الماسح الضوئي بطباعة أمر `git filter-repo` جاهز للتشغيل لإزالتها من تاريخ المستودع المصدر قبل إعادة التشغيل.
---
## الإعدادات
يبحث `gh-safe-repo` عن الإعدادات بهذا الترتيب (أول تطابق يفوز):
1. **`--config PATH`** — تجاوز صريح
2. **`./gh-safe-repo.ini`** — دليل العمل الحالي
3. **`$XDG_CONFIG_HOME/gh-safe-repo/gh-safe-repo.ini`** — الافتراضي هو `~/.config` عندما لا يتم تعيين `$XDG_CONFIG_HOME`
`--config` المجرد (بدون مسار) يتجاوز البحث عن الملف بالكامل ويستخدم الإعدادات الافتراضية المضمنة فقط.
جميع القيم لها إعدادات افتراضية آمنة — لا حاجة لملف إعدادات للبدء.
يتم تضمين مثال إعدادات مشروح بالكامل في المستودع باسم `gh-safe-repo.ini.example`. انسخه للبدء:```bash
# User-level config (XDG)
mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/gh-safe-repo"
cp gh-safe-repo.ini.example "${XDG_CONFIG_HOME:-$HOME/.config}/gh-safe-repo/gh-safe-repo.ini"
# Or project-level config (current directory)
cp gh-safe-repo.ini.example ./gh-safe-repo.ini
[repo]
private = true
has_wiki = false has_projects = false has_issues = true
delete_branch_on_merge = false
allow_squash_merge = true allow_merge_commit = true allow_rebase_merge = true
create leaves an initialized README in the new repo.auto_init = false
[actions]
allowed_actions = selected
github_owned_allowed = true # actions maintained by GitHub (e.g. actions/checkout) verified_allowed = true # actions from Marketplace verified creators
default_workflow_permissions = read
can_approve_pull_request_reviews = false
sha_pinning_required = true
[branch_protection]
protected_branch = main
require_pull_request = true
required_approving_reviews = 1
dismiss_stale_reviews = true
require_conversation_resolution = true
enforce_admins = false
allow_force_pushes = false
allow_deletions = false
use_rulesets = true
[tag_protection]
protected_tags = *
prevent_tag_deletion = true
prevent_tag_update = true
[security]
enable_dependabot_alerts = true
enable_dependabot_security_updates = true
enable_private_vulnerability_reporting = true
enable_secret_scanning_push_protection = true
[pre_flight_scan] scan_for_secrets = true scan_for_emails = true scan_for_todos = true
max_file_size_mb = 100
[git_transport]
workflow token scope to pushworkflow scope intentionally.---
## قيود خطة GitHub
بعض الميزات متاحة فقط حسب رؤية المستودع وخطة GitHub الخاصة بك.
| الميزة | Free + Public | Free + Private | Pro/Team + Private |
|---|:---:|:---:|:---:|
| حماية الفرع / مجموعات القواعد | نعم | لا | نعم |
| حماية العلامات (مجموعات القواعد) | نعم | لا | نعم |
| تنبيهات Dependabot | نعم | لا | نعم |
| تحديثات الأمان من Dependabot | نعم | لا | نعم |
| فحص الأسرار | تلقائي | لا | نعم |
| حماية الدفع | نعم | لا | نعم |
| الإبلاغ الخاص عن الثغرات | نعم | نعم | نعم |
| رسم بياني للتبعيات | تلقائي | لا | نعم |
يكتشف `gh-safe-repo` مستوى خطتك ورؤية المستودع في وقت التشغيل. تظهر الميزات غير المتاحة كـ `SKIP` في مخرجات الخطة مع سبب واضح — لا تفشل الأداة بصمت.
---
## كيف يعمل```
gh-safe-repo create <owner/repo>
│
├─ Parse owner/repo, validate owner matches authenticated user (create only)
├─ Load config (./gh-safe-repo.ini or $XDG_CONFIG_HOME/gh-safe-repo/gh-safe-repo.ini)
├─ Apply CLI flag overrides (--public, etc.)
├─ Authenticate via gh CLI or GITHUB_TOKEN
├─ GET /user → owner login + plan level (single cached call)
│
├─ Build plan (each plugin compares desired vs. current state)
│ ├─ RepositoryPlugin → repo creation + basic settings
│ ├─ ActionsPlugin → allowed actions, workflow permissions, SHA pinning
│ ├─ BranchProtectionPlugin → Rulesets API (default; classic if use_rulesets = false)
│ ├─ SecurityPlugin → Dependabot, secret scanning, push protection, private vuln reporting
│ └─ TagProtectionPlugin → immutable tags via Rulesets API
│
├─ Print plan table
│
└─ Apply (unless --dry-run)
├─ POST /user/repos
├─ PATCH /repos/{owner}/{repo} (settings)
├─ PUT /repos/{owner}/{repo}/actions/permissions/workflow
├─ POST/PATCH /repos/{owner}/{repo}/rulesets (branch protection; default)
│ or PUT /repos/{owner}/{repo}/branches/main/protection (if use_rulesets = false)
├─ PUT /repos/{owner}/{repo}/vulnerability-alerts
├─ PUT /repos/{owner}/{repo}/automated-security-fixes
├─ PUT /repos/{owner}/{repo}/private-vulnerability-reporting
├─ PATCH /repos/{owner}/{repo} (security_and_analysis: push protection)
├─ POST /repos/{owner}/{repo}/rulesets (tag protection ruleset)
├─ git clone --mirror + git push --mirror (if --from)
└─ git clone <local> + git push --all --tags (if --local, git repo)
or git init + add -A + commit + push (if --local, plain dir)
كل فئة من الإعدادات هي فئة إضافة مستقلة بذاتها (gh_safe_repo/plugins/). كل إضافة:
Plan (قائمة من كائنات Change: إضافة / تحديث / حذف / تخطي)هذا يعني أن وضع التدقيق ووضع الإنشاء يستخدمان نفس مسار التخطيط/التطبيق. الفرق الوحيد هو ما إذا كانت الحالة الحالية تُجلب من مستودع موجود أو تُفترض أنها الإعدادات الافتراضية لـ GitHub.
تحل استدعاءات API الرمز المميز بهذا الترتيب:
GITHUB_TOKEN — يتيح لك استهداف حساب معين دون تبديل جلسة gh النشطة (وهو الاعتماد الوحيد المطلوب في CI)gh auth token — أيًا كان ما تم إعداده بواسطة gh auth loginيتم تمرير الرموز المميزة إلى عمليات gh api الفرعية كـ GH_TOKEN في بيئة العملية الفرعية ولا يتم تسجيلها أبدًا.
عمليات Git (--local / --from push واستنساخ) تستخدم بيانات اعتماد Git الخاصة بك — مفتاح SSH أو مساعد بيانات الاعتماد — افتراضيًا، وليس رمز API. في البيئات التي لا تحتوي على أي منهما (مثل CI باستخدام GITHUB_TOKEN فقط)، ترجع الأداة إلى الدفع عبر HTTPS باستخدام الرمز المميز في عنوان URL؛ يُتحكم في هذا بواسطة إعداد [git_transport] mode (راجع مرجع الإعدادات). لا تتم كتابة عناوين URL التي تحمل رموزًا مميزة أبدًا في ملف .git/config الخاص بمستودعك ويتم حجبها من جميع المخرجات.
جميع استدعاءات GitHub API تتم عبر gh api باستخدام subprocess. هذا يحافظ على المصادقة بالكامل داخل CLI gh — لا رمز إدارة الرمز المميز، لا تدفق OAuth، لا تثبيت إصدار PyGithub. يتم تمرير نصوص طلبات JSON عبر --input - (التيار القياسي)، وليس عبر علامات --field.
git clone https://github.com/your-username/gh-safe-repo cd gh-safe-repo uv sync # creates .venv, installs pytest
uv run pytest tests/ -v
./gh-safe-repo create <owner/repo> --dry-run
uv tool install .
انظر [`tests/README.md`](https://github.com/ariesq/gh-safe-repo/blob/HEAD/tests/README.md) للحصول على أوصاف ملفات الاختبار، واتفاقيات المحاكاة، وكيفية إضافة اختبارات جديدة.
### هيكل المشروع```
gh-safe-repo/
├── gh-safe-repo # Thin launcher (entry point for direct use)
├── gh_safe_repo/ # Package — see gh_safe_repo/README.md for internals
│ ├── cli.py # Subparser dispatch (create, fix, scan)
│ ├── commands/ # Subcommand implementations
│ │ ├── _common.py # Shared helpers, CLIContext, plan formatting
│ │ ├── create.py # create subcommand
│ │ ├── fix.py # fix subcommand
│ │ └── scan.py # scan subcommand
│ └── plugins/ # Settings plugins (one per category)
├── pyproject.toml # Build config, entry points
├── gh-safe-repo.ini.example # Fully annotated example config
└── tests/
أنظر إلى gh_safe_repo/README.md للحصول على خريطة الوحدة، وهندسة الإضافات، ودليل لإضافة إعدادات جديدة.
لا توجد تبعيات وقت التشغيل. كل شيء يستخدم مكتبة Python القياسية (argparse, configparser, subprocess, json, re). لا تقم بإضافة حزم طرف ثالث دون مناقشة.
pytest هي التبعية الوحيدة للتطوير، معلنة كمدخل [dependency-groups] أصلي لـ UV في pyproject.toml.
تمت دراسة هذه المشاريع أثناء التصميم وأثرت على بنية gh-safe-repo. إنها أدوات متميزة بنطاق ونماذج مستخدم مختلفة — راجع docs/LEARNINGS.md للحصول على ملاحظات فنية مفصلة حول كيفية تكييف الأنماط.
github/safe-settings — تطبيق GitHub على مستوى المؤسسة (Node.js/Probot) يفرض إعدادات المستودع من تكوين مركزي. مصدر نمط هندسة الإضافات (فئة واحدة لكل فئة إعداد، جلب → فرق → تطبيق) ونهج المقارنة mergeDeep.
repository-settings/app — متغير أبسط لكل مستودع من safe-settings، أيضًا Node.js/Probot. قدم مرجعًا أنظف لنمط الإضافة الأساسي Diffable.
nicholasgasior/gh-repo-settings — امتداد لسطر الأوامر مكتوب بلغة Go مع سير عمل plan/apply. الإلهام الأساسي لنمط غلاف العملية الفرعية gh api وتصميم مخرجات خطة التشغيل الجاف.
| الخيار | الوصف |
|---|
--public | الإنشاء كمستودع عام (الافتراضي: خاص) |
--local PATH | دفع التعليمات البرمجية من مستودع git محلي إلى المستودع الجديد. يقوم بإجراء فحص مسبق أولاً. متعارض مع --from. |
--from OWNER/REPO | نسخ التعليمات البرمجية من مستودع موجود إلى المستودع الجديد. يقوم بإجراء فحص مسبق. متعارض مع --local. |
--yes / -y | تخطي موجه التأكيد والتطبيق فورًا (للاستخدام في البرمجة النصية/الدفعات) |
--dry-run | طباعة الخطة دون إجراء أي تغييرات |
--json | إخراج الخطة بتنسيق JSON إلى الإخراج القياسي بدلاً من جدول ANSI |
--config [PATH] | مسار ملف التكوين؛ --config فقط يستخدم الإعدادات الافتراضية المضمنة فقط |
--debug | طباعة كل استدعاء API والاستجابة |
| الخيار | الوصف |
|---|
--yes / -y | تخطي موجه التأكيد والتطبيق فورًا (للاستخدام في البرمجة النصية/الدفعات) |
--dry-run | عرض فرق الإعدادات دون تطبيق التغييرات |
--json | إخراج الخطة بتنسيق JSON إلى الإخراج القياسي بدلاً من جدول ANSI |
--config [PATH] | مسار ملف التكوين؛ --config فقط يستخدم الإعدادات الافتراضية المضمنة فقط |
--debug | طباعة كل استدعاء API والاستجابة، بالإضافة إلى هوية المستودع التي تم حلها (المعرف، الاسم الكامل، نوع المالك) |
ADD (أخضر) | إعداد جديد يتم تطبيقه |
UPDATE (أصفر) | إعداد موجود يتم تغييره (وضع التدقيق) |
DELETE (أحمر) | إعداد يتم إزالته |
SKIP (معتم) | لا حاجة لإجراء — القيمة المطلوبة موجودة بالفعل، أو الميزة غير متاحة في خطتك/مجموعة الرؤية الخاصة بك |
| الفئة | الخطورة | أمثلة |
|---|
| الأسرار المضمنة في النص | حرجة | مفاتيح AWS (AKIA…)، رموز GitHub (ghp_…, github_pat_…)، المفاتيح الخاصة، روابط قواعد البيانات |
| السلاسل المحظورة | حرجة | أي سلاسل حرفية تقوم بتكوينها (أسماء مستخدمين، أسماء مضيفات داخلية، أسماء رمزية) |
| ملفات سياق AI | حرجة | CLAUDE.md، AGENTS.md، .cursorrules، copilot-instructions.md، .cursor/ — قد تحتوي على ملاحظات تطوير داخلية؛ قد يكون تاريخ git أكثر حساسية من الإصدار الحالي |
| عناوين البريد الإلكتروني | تحذير | أي نمط [email protected] في شجرة العمل وتاريخ git |
| الملفات الكبيرة | تحذير | الملفات التي تتجاوز حد الحجم المكوّن (الافتراضي: 100 ميجابايت) |
| تعليقات TODO/FIXME | معلومات | # TODO، # FIXME، # HACK، # XXX |