# SDK Publishing Guidelines

**Purpose:** Guidelines for publishing Python and TypeScript SDKs to package registries

---

## CRITICAL RULES BEFORE PUBLISHING

### Pre-Publishing Checklist

**NEVER publish without completing ALL of these steps:**

- [ ] All tests passing
- [ ] Code coverage meets minimum requirements
- [ ] Version number bumped correctly in ALL files
- [ ] CHANGELOG.md updated with release notes
- [ ] README.md examples tested and working
- [ ] No secrets, API keys, or tokens in code
- [ ] Git repository clean (no uncommitted changes)
- [ ] Code pushed to GitHub with version tag
- [ ] Tested in fresh virtual environment
- [ ] Developer experience validated

**Publishing is PERMANENT on PyPI - you cannot delete packages!**

---

## Python SDK Publishing (PyPI)

### Credentials
**Location:** `~/.pypirc` (local machine)

**Format:**
```ini
[distutils]
index-servers =
    pypi
    testpypi

[pypi]
username = __token__
password = pypi-[production-token]

[testpypi]
repository = https://test.pypi.org/legacy/
username = __token__
password = pypi-[test-token]
```

**Important:** Credentials are automatically loaded by `twine` from `~/.pypirc`

### Publishing Workflow

#### Step 1: Pre-Flight Testing
```bash
cd /path/to/your/python-sdk

# Create fresh virtual environment
python3 -m venv venv
source venv/bin/activate

# Install with dev dependencies
pip install -e ".[dev]"

# Run full test suite
pytest tests/ -v --cov=your_package --cov-report=term-missing
```

#### Step 2: Version Verification
Ensure version is bumped in ALL these files:
- `setup.py` or `pyproject.toml`: version field
- `your_package/__init__.py`: `__version__`
- `CHANGELOG.md`: New entry

#### Step 3: Build Distribution Packages
```bash
# Clean previous builds
rm -rf dist/ build/ *.egg-info

# Install build tools
pip install --upgrade build twine

# Build wheel and source distribution
python -m build

# Validate packages
twine check dist/*
```

#### Step 4: Test on Test PyPI (RECOMMENDED)
```bash
# Upload to Test PyPI (safe sandbox)
twine upload --repository testpypi dist/*

# Wait 1-2 minutes for indexing, then test installation
python3 -m venv /tmp/test_pypi_env
source /tmp/test_pypi_env/bin/activate
pip install --index-url https://test.pypi.org/simple/ \
    --extra-index-url https://pypi.org/simple/ \
    your-package==1.0.0
```

#### Step 5: Production PyPI Upload
```bash
# FINAL CHECK: Are you sure?
# - All tests passing?
# - Tested on Test PyPI?
# - Version correct in all files?
# - CHANGELOG updated?

# Upload to Production PyPI (PERMANENT - NO UNDO)
twine upload dist/*
```

#### Step 6: Post-Publishing
```bash
# Tag release in Git
git tag -a v1.0.0 -m "Release v1.0.0"
git push origin v1.0.0

# Create GitHub Release
gh release create v1.0.0 --title "v1.0.0" --notes "See CHANGELOG.md"
```

### Common Issues

**Issue:** `twine: command not found`
**Solution:** `pip install twine`

**Issue:** `HTTPError: 403 Forbidden`
**Solution:** Check credentials in `~/.pypirc` are correct

**Issue:** `File already exists`
**Solution:** Version already published - bump version number

**Issue:** Tests failing
**Solution:** DO NOT PUBLISH - fix tests first!

---

## TypeScript SDK Publishing (NPM)

### Credentials

```bash
# Method 1: Interactive login
npm login

# Method 2: Use auth token
npm config set //registry.npmjs.org/:_authToken=$NPM_TOKEN

# Verify authentication
npm whoami
```

### Publishing Workflow

#### Step 1: Pre-Flight Testing
```bash
cd /path/to/your/typescript-sdk

# Install dependencies
npm install

# Run tests
npm test

# Run linting
npm run lint
```

#### Step 2: Build Distribution
```bash
# Clean previous builds
npm run clean

# Build TypeScript
npm run build
```

#### Step 3: Version Bump
```bash
# Bump version (updates package.json automatically)
npm version patch  # 1.0.0 -> 1.0.1
npm version minor  # 1.0.0 -> 1.1.0
npm version major  # 1.0.0 -> 2.0.0
```

#### Step 4: Publish to NPM
```bash
# Dry run first (shows what will be published)
npm publish --dry-run

# Publish to NPM (scoped package requires --access public)
npm publish --access public

# Verify published package
npm view your-package version
```

#### Step 5: Post-Publishing
```bash
# Tag and push to Git
git tag -a v1.0.1 -m "Release v1.0.1"
git push origin v1.0.1

# Test installation
npm install your-package@1.0.1
```

---

## Version Numbering Guidelines

Follow **Semantic Versioning (SemVer)**: `MAJOR.MINOR.PATCH`

- **MAJOR** (1.0.0 -> 2.0.0): Breaking API changes
- **MINOR** (1.0.0 -> 1.1.0): New features, backward compatible
- **PATCH** (1.0.0 -> 1.0.1): Bug fixes, backward compatible

---

## Rollback Strategy

### PyPI (Python)
**Cannot delete packages from PyPI!**

Options:
1. **Yank release:** Hides from default searches but keeps downloadable
   - Via PyPI web interface: Manage -> Releases -> Yank
2. **Publish hotfix:** Release next patch with fixes immediately
3. **Add warning to README:** Document the issue

### NPM (TypeScript)
**Can unpublish within 72 hours** (discouraged)

```bash
# Unpublish specific version (within 72 hours)
npm unpublish your-package@1.0.1

# Deprecate version (preferred)
npm deprecate your-package@1.0.1 "Please upgrade to 1.0.2"
```

---

## Security Considerations

### Before Publishing
- [ ] No hardcoded API keys or secrets
- [ ] No `.env` files in package
- [ ] Check `.gitignore` and `.npmignore`
- [ ] Scan for sensitive data: `git grep -i "api.key\|secret\|password\|token"`

### After Publishing
- Monitor for security vulnerabilities
- Set up GitHub Dependabot alerts
- Regularly update dependencies

---

**Remember:** Publishing is PERMANENT. Test thoroughly before publishing!
