Files
py-wikijs/docs/deployment.md
Claude c18d00cd47 build: Add PyPI package deployment support
Complete package deployment configuration for PyPI publishing:

- Add MANIFEST.in to control package distribution
  - Include LICENSE, README, requirements files
  - Include docs/ and examples/ directories
  - Include type stub marker (py.typed)
  - Exclude test files and development artifacts

- Fix dependency specification
  - Add pydantic[email] for email validation support
  - Required for User model EmailStr fields
  - Update both requirements.txt and pyproject.toml

- Create comprehensive deployment documentation
  - docs/deployment.md - Complete PyPI publishing guide
    - Pre-deployment checklist
    - Build and test procedures
    - PyPI upload instructions
    - Troubleshooting guide
    - CI/CD automation examples
  - DEPLOYMENT_READY.md - Deployment status summary
    - What's included in distributions
    - Verification test results
    - Quick deployment steps
    - PyPI vs Gitea comparison

Package is now 100% ready for PyPI deployment:
 Builds successfully (sdist + wheel)
 Installs correctly with all dependencies
 Imports work without errors
 All files properly included
 Complete documentation provided

Testing:
- Successfully built wikijs_python_sdk-0.1.0.tar.gz (134 KB)
- Successfully built wikijs_python_sdk-0.1.0-py3-none-any.whl (66 KB)
- Verified installation and imports work correctly
- All dependencies resolve properly

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 20:13:51 +00:00

534 lines
11 KiB
Markdown

# Deployment Guide - Publishing py-wikijs to PyPI
**Last Updated**: October 2025
**Target Audience**: Maintainers and release managers
---
## 📋 Overview
This guide covers how to build, test, and publish the `wikijs-python-sdk` package to PyPI (Python Package Index).
---
## ✅ Pre-Deployment Checklist
### 1. Code Quality
- [ ] All tests pass (`pytest`)
- [ ] Code coverage ≥85% (`pytest --cov`)
- [ ] Linting passes (`black`, `flake8`, `mypy`)
- [ ] Security scan passes (`bandit`)
- [ ] No critical bugs in issue tracker
### 2. Documentation
- [ ] README.md is up to date
- [ ] CHANGELOG.md has release notes
- [ ] API documentation is current
- [ ] Examples are tested and working
- [ ] Compatibility guide is accurate
### 3. Version Management
- [ ] Version bumped in `wikijs/version.py`
- [ ] CHANGELOG.md updated with new version
- [ ] Git tag created for release
- [ ] No uncommitted changes
### 4. Legal & Metadata
- [ ] LICENSE file present (MIT)
- [ ] setup.py metadata correct
- [ ] pyproject.toml metadata correct
- [ ] Author information accurate
---
## 🔧 Prerequisites
### Required Tools
```bash
# Install build and publishing tools
pip install --upgrade pip
pip install build twine
```
### PyPI Account Setup
1. **Create PyPI Account**: https://pypi.org/account/register/
2. **Create API Token**:
- Go to https://pypi.org/manage/account/
- Click "Add API token"
- Name: `wikijs-python-sdk-upload`
- Scope: Entire account (or specific project after first upload)
3. **Save Token Securely**: Store in password manager or environment variable
### Configure PyPI Credentials
**Option 1: Using .pypirc file** (Recommended for local development)
```bash
# Create ~/.pypirc
cat > ~/.pypirc << 'EOF'
[distutils]
index-servers =
pypi
testpypi
[pypi]
username = __token__
password = pypi-AgEIcHlwaS5vcmc...YOUR-TOKEN-HERE...
[testpypi]
repository = https://test.pypi.org/legacy/
username = __token__
password = pypi-AgENdGVzdC5weXBp...YOUR-TEST-TOKEN-HERE...
EOF
chmod 600 ~/.pypirc
```
**Option 2: Using environment variables** (Recommended for CI/CD)
```bash
export TWINE_USERNAME=__token__
export TWINE_PASSWORD=pypi-AgEIcHlwaS5vcmc...YOUR-TOKEN-HERE...
```
---
## 📦 Building the Package
### 1. Clean Previous Builds
```bash
# Remove old build artifacts
rm -rf build/ dist/ *.egg-info wikijs_python_sdk.egg-info
# Verify clean state
git status
```
### 2. Update Version
```bash
# Edit wikijs/version.py
__version__ = "0.2.0" # Update version number
__version_info__ = (0, 2, 0)
```
### 3. Update CHANGELOG
```markdown
# Edit docs/CHANGELOG.md
## [0.2.0] - 2025-10-XX
### Added
- New feature descriptions
- API additions
### Changed
- Modified functionality
### Fixed
- Bug fixes
```
### 4. Build Distributions
```bash
# Build both source distribution (sdist) and wheel
python -m build
# This creates:
# - dist/wikijs_python_sdk-X.Y.Z.tar.gz (source distribution)
# - dist/wikijs_python_sdk-X.Y.Z-py3-none-any.whl (wheel)
```
### 5. Verify Build Contents
```bash
# Check source distribution contents
tar -tzf dist/wikijs_python_sdk-*.tar.gz | head -30
# Check wheel contents
python -m zipfile -l dist/wikijs_python_sdk-*-py3-none-any.whl | head -30
# Verify required files are included:
# - LICENSE
# - README.md
# - requirements.txt
# - docs/
# - examples/
# - wikijs/ (all source code)
# - wikijs/py.typed (type stub marker)
```
---
## 🧪 Testing the Package
### 1. Validate Package Metadata
```bash
# Check package metadata for errors
python -m twine check dist/*
# Should show:
# Checking dist/wikijs_python_sdk-X.Y.Z.tar.gz: PASSED
# Checking dist/wikijs_python_sdk-X.Y.Z-py3-none-any.whl: PASSED
```
### 2. Test Local Installation
```bash
# Create a test virtual environment
python -m venv test-env
source test-env/bin/activate # On Windows: test-env\Scripts\activate
# Install from wheel
pip install dist/wikijs_python_sdk-*-py3-none-any.whl
# Test import
python -c "from wikijs import WikiJSClient, __version__; print(f'Version: {__version__}')"
# Test basic functionality
python << 'EOF'
from wikijs import WikiJSClient
from wikijs.models import PageCreate
# This should not error (will fail at connection, which is expected)
try:
client = WikiJSClient('https://example.com', auth='test-key')
print("✅ Client instantiation successful")
except Exception as e:
print(f"❌ Error: {e}")
EOF
# Cleanup
deactivate
rm -rf test-env
```
### 3. Test on TestPyPI (Optional but Recommended)
```bash
# Upload to TestPyPI first
python -m twine upload --repository testpypi dist/*
# Install from TestPyPI
pip install --index-url https://test.pypi.org/simple/ \
--extra-index-url https://pypi.org/simple/ \
wikijs-python-sdk
# Test the installation
python -c "from wikijs import WikiJSClient; print('TestPyPI install successful')"
```
---
## 🚀 Publishing to PyPI
### 1. Final Pre-Publish Checks
```bash
# Ensure you're on the main branch
git checkout main
# Ensure everything is committed
git status
# Tag the release
git tag v0.2.0
git push origin v0.2.0
```
### 2. Upload to PyPI
```bash
# Upload to production PyPI
python -m twine upload dist/*
# You'll see output like:
# Uploading distributions to https://upload.pypi.org/legacy/
# Uploading wikijs_python_sdk-0.2.0-py3-none-any.whl
# Uploading wikijs_python_sdk-0.2.0.tar.gz
# View at:
# https://pypi.org/project/wikijs-python-sdk/0.2.0/
```
### 3. Verify Publication
```bash
# Visit PyPI page
# https://pypi.org/project/wikijs-python-sdk/
# Test installation from PyPI
pip install wikijs-python-sdk
# Verify version
python -c "from wikijs import __version__; print(__version__)"
```
---
## 🔄 Post-Publication Tasks
### 1. Update Documentation
- [ ] Update README.md installation instructions
- [ ] Update GitHub releases page
- [ ] Announce release in community channels
- [ ] Update project status badges
### 2. Git Housekeeping
```bash
# Create GitHub release
# Go to: https://github.com/l3ocho/py-wikijs/releases/new
# - Tag version: v0.2.0
# - Release title: v0.2.0 - Release Name
# - Description: Copy from CHANGELOG.md
# - Attach dist/ files
# Merge release branch if applicable
git checkout main
git merge release/v0.2.0
git push origin main
```
### 3. Prepare for Next Development Cycle
```bash
# Bump to next development version
# Edit wikijs/version.py
__version__ = "0.3.0-dev"
git add wikijs/version.py
git commit -m "chore: bump version to 0.3.0-dev"
git push
```
---
## 🐛 Troubleshooting
### Build Failures
**Problem**: `FileNotFoundError: requirements.txt`
```bash
# Solution: Ensure MANIFEST.in includes requirements.txt
# Check MANIFEST.in contents:
cat MANIFEST.in
```
**Problem**: Missing documentation in package
```bash
# Solution: Update MANIFEST.in to include docs
recursive-include docs *.md
```
### Upload Failures
**Problem**: `403 Forbidden - Invalid or non-existent authentication information`
```bash
# Solution: Check your API token
# 1. Verify token is correct in ~/.pypirc
# 2. Ensure token has upload permissions
# 3. Try using environment variables instead
export TWINE_USERNAME=__token__
export TWINE_PASSWORD=your-token-here
python -m twine upload dist/*
```
**Problem**: `400 File already exists`
```bash
# Solution: You cannot re-upload the same version
# 1. Increment version in wikijs/version.py
# 2. Rebuild: python -m build
# 3. Upload again: python -m twine upload dist/*
```
**Problem**: Package name already taken
```bash
# Solution: Choose a different package name
# 1. Update name in setup.py and pyproject.toml
# 2. Rebuild package
# Note: wikijs-python-sdk is our chosen name
```
### Installation Issues
**Problem**: `ModuleNotFoundError` after install
```bash
# Solution: Check dependencies are installed
pip show wikijs-python-sdk
pip install wikijs-python-sdk[all] # Install all optional deps
```
**Problem**: Import errors with type hints
```bash
# Solution: Ensure py.typed file is in package
# Check if included: python -m zipfile -l dist/*.whl | grep py.typed
```
---
## 📊 Package Statistics
### Size Guidelines
- **Wheel**: Should be < 100 KB for SDK
- **Source**: Should be < 200 KB including docs
- **Total dependencies**: Keep minimal
```bash
# Check package sizes
ls -lh dist/
# Check dependency tree
pip install pipdeptree
pipdeptree -p wikijs-python-sdk
```
### Download Stats
After publication, monitor package metrics:
- **PyPI Stats**: https://pypistats.org/packages/wikijs-python-sdk
- **GitHub Stats**: Stars, forks, watchers
- **Issue Tracker**: Open issues, response time
---
## 🔐 Security Best Practices
### 1. Protect API Tokens
- Never commit tokens to git
- Use `.gitignore` for `.pypirc`
- Rotate tokens periodically
- Use scoped tokens (project-specific)
### 2. Package Security
```bash
# Run security scan before publishing
pip install safety
safety check --file requirements.txt
# Scan for vulnerabilities
bandit -r wikijs/
```
### 3. Signing Releases (Optional)
```bash
# Sign the release with GPG
gpg --detach-sign -a dist/wikijs_python_sdk-0.2.0.tar.gz
# Upload signatures
python -m twine upload dist/* --sign
```
---
## 📝 Checklist Summary
### Pre-Release
- [ ] Tests pass
- [ ] Version bumped
- [ ] CHANGELOG updated
- [ ] Documentation current
### Build
- [ ] Clean build environment
- [ ] Build succeeds
- [ ] Package validated
- [ ] Local test passes
### Publish
- [ ] TestPyPI upload (optional)
- [ ] PyPI upload
- [ ] Installation verified
- [ ] Package page checked
### Post-Release
- [ ] Git tag created
- [ ] GitHub release published
- [ ] Documentation updated
- [ ] Community notified
---
## 📞 Support
### Resources
- **PyPI Help**: https://pypi.org/help/
- **Packaging Guide**: https://packaging.python.org/
- **Twine Docs**: https://twine.readthedocs.io/
### Getting Help
- PyPI Support: https://pypi.org/help/#feedback
- GitHub Issues: https://github.com/l3ocho/py-wikijs/issues
- Packaging Discourse: https://discuss.python.org/c/packaging/
---
## 🎓 Additional Notes
### Automated Publishing (CI/CD)
For automated releases via GitHub Actions:
```yaml
# .github/workflows/publish.yml
name: Publish to PyPI
on:
release:
types: [published]
jobs:
pypi-publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install dependencies
run: |
pip install build twine
- name: Build package
run: python -m build
- name: Publish to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: twine upload dist/*
```
### Alternative: Using Trusted Publishing
Modern approach (no API tokens needed):
1. Configure trusted publisher on PyPI
2. Use OIDC token from GitHub Actions
3. More secure, no secrets needed
See: https://docs.pypi.org/trusted-publishers/
---
**Last Updated**: October 2025
**Maintainer**: leomiranda
For questions about deployment, open an issue on GitHub.