برای هر توسعهدهنده پایتونی که به انتشار منبع باز یا توزیع کتابخانههای داخلی اهمیت میدهد، فرآیند دستی بستهبندی و آپلود در PyPI یک گلوگاه جدی است. این کار مستعد خطا، خستهکننده و ایجادکننده اصطکاک در جریان توسعه است. با خودکارسازی این فرآیند با استفاده از GitHub Actions، Twine و نسخهبندی معنایی دقیق، میتوانید اطمینان حاصل کنید که هر انتشار، قابل تکرار، امن و فوری باشد.
پایپلاین انتشار مدرن
یک پایپلاین انتشار مستحکم، فراتر از آپلود فایلها عمل میکند؛ بلکه کد شما را اعتبارسنجی میکند، شماره نسخهها را به صورت خودکار مدیریت مینماید و اسرار (Secrets) را به صورت امن پردازش میکند. اجزای اصلی این خودکارسازی عبارتند از:
- GitHub Actions: موتوری که گردش کارها را بر رویدادهای خاصی، مانند ارسال یک برچسب (Tag) جدید، فعال میکند.
- Setuptools / Poetry / Hatch: ابزارهایی که فایلهای توزیع شما (sdist و bdist_wheel) را میسازند.
- Twine: ابزار قابل اعتماد برای آپلود بستهها به PyPI.
- نسخهبندی معنایی (SemVer): استانداردی که اطمینان حاصل میکند شماره نسخهها بازتابدهنده ماهیت تغییرات هستند (Major.Minor.Patch).
مرحله ۱: اعمال نسخهبندی معنایی
قبل از خودکارسازی، باید تعیین کنید که چگونه نسخهها افزایش مییابند. ما استفاده از الگوی versioneer یا تکیه بر برچسبهای Git را توصیه میکنیم. گردش کار تنها زمانی فعال میشود که برچسبی با الگوی v* ارسال شود. این اطمینان را فراهم میکند که شماره نسخهها به صورت خودکار توسط یک اجرای CI ایجاد نشوند، بلکه به صراحت توسط توسعهدهنده اعلام شوند.
مرحله ۲: پیکربندی گردش کار GitHub Actions
یک فایل در مسیر .github/workflows/publish.yml ایجاد کنید. این فایل YAML پایپلاین را تعریف میکند. گردش کار روی رویداد create اجرا خواهد شد، که به طور خاص برای برچسبها فیلتر شده است.
name: Publish Python Distribution to PyPI
on:
release:
types: [published]
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write # Use OIDC authentication
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build twine
- name: Build and publish
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: |
python -m build
twine upload dist/*
بهترین شیوههای امنیتی: استفاده از OIDC
مثال بالا از id-token: write و متغیرهای محیطی برای مدیریت توکنهای قدیمی استفاده میکند. با این حال، بهترین شیوه مدرن استفاده از OpenID Connect (OIDC) برای PyPI است. این امکان را به GitHub Actions میدهد تا هویت قابل اعتمادی را بدون ذخیره توکنهای API با عمر طولانی در اسرار مخزن شما، فرض کند. برای فعالسازی این مورد، باید یک ارائهدهنده OIDC را در تنظیمات پروژه PyPI خود پیکربندی کنید.
مرحله publish خود را به شرح زیر برای حداکثر امنیت بهروزرسانی کنید:
- name: Publish distribution to PyPI
run: twine upload dist/*
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
توجه: هنگام استفاده از OIDC، معمولاً نیازی به ذخیره رمز عبور در اسرار (secrets) ندارید. در عوض، مرحله actions/setup-python یا یک اکشن OIDC خاص، احراز هویت را به صورت پویا مدیریت میکند.
مرحله ۳: ساخت توزیع
در گردش کار، از python -m build استفاده میکنیم. این جایگزین مدرن برای setup.py sdist bdist_wheel است. این اطمینان را فراهم میکند که از build به صورت ایزوله از محیط محلی خود استفاده میکنید و تضمین میکند که فایلهای wheel دقیقاً همانطور که در یک کانتینر تمیز ساخته میشوند، ساخته شوند. این مرحله پوشه dist/ را تولید میکند که شامل هر دو توزیع منبع و wheel باینری است.
نتیجهگیری
خودکارسازی انتشارات بسته پایتون، یک کار دستی را به فرآیندی قابل اعتماد و قابل حسابرسی تبدیل میکند. با بهرهگیری از GitHub Actions، منطق انتشار را از ماشین محلی خود جدا میکنید. با استفاده از Twine و OIDC، استانداردهای امنیتی بالا را حفظ میکنید. در نهایت، با پایبندی به نسخهبندی معنایی از طریق برچسبهای Git، شفافیت را در مورد پایداری نرمافزار خود برای کاربران فراهم میکنید.
با پیادهسازی این گردش کار روی یک پروژه غیرحیاتی شروع کنید. آن را با ایجاد یک بسته آزمایشی در TestPyPI قبل از ارسال به مخزن اصلی آزمایش کنید. زمانی که پایپلاین شما پایدار شد،会发现 که انتشار ویژگیهای جدید به سادگی برچسبگذاری یک کامیت خواهد بود، به شما این امکان را میدهد که به جای مدیریت استقرار، بر نوشتن کد تمرکز کنید.