name: CI/CD Pipeline on: push: branches: ["main"] tags: ["v*"] # Triggers production deployment whenever a version tag is pushed pull_request: branches: ["main"] jobs: # --------------------------------------------------------------------------- # Stage 1: Quality Control & Automated Verification # --------------------------------------------------------------------------- test: name: Verify Pack Integrity runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install Testing Environment run: | python -m pip install --upgrade pip pip install pytest - name: Execute Code Audit run: python -m pytest tests/ -v # --------------------------------------------------------------------------- # Stage 2: Production Build & Multi-Platform Distribution # --------------------------------------------------------------------------- publish: name: Production Release (PyPI & Gitea) needs: test if: startsWith(github.ref, 'refs/tags/v') # Strictly run only for tagged versions runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v4 - name: Set up Production Python uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install Modern Build Toolchain run: | python -m pip install --upgrade pip pip install build twine - name: Compile Distribution Assets (PEP 517) # This automatically handles whatever package name is configured inside pyproject.toml run: python -m build - name: Publish Package to PyPI env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} # Uses your org-level token safely run: twine upload --skip-existing dist/* - name: Generate Automated Gitea Release uses: actions/github-script@v7 with: script: | const fs = require('fs'); const path = require('path'); // Extract tag context const tagName = context.ref.replace('refs/tags/', ''); // Create the Gitea Release container const release = await github.rest.repos.createRelease({ owner: context.repo.owner, repo: context.repo.repo, tag_name: tagName, name: `Release ${tagName}`, body: `Automated distribution release for version ${tagName}. Verified by system tests.`, draft: false, prerelease: false }); // Read and attach compiled distribution files (.whl and .tar.gz) const distDir = './dist'; const files = fs.readdirSync(distDir); for (const file of files) { const filePath = path.join(distDir, file); const fileData = fs.readFileSync(filePath); await github.rest.repos.uploadReleaseAsset({ owner: context.repo.owner, repo: context.repo.repo, release_id: release.data.id, name: file, data: fileData }); console.log(`Successfully attached asset: ${file}`); }