# 📦 Publishing Irene Cipher to PyPI - Complete Guide

## Prerequisites Checklist

Before publishing, ensure you have:

- [ ] **PyPI account** - Create at https://pypi.org/account/register/
- [ ] **TestPyPI account** (optional but recommended) - https://test.pypi.org/account/register/
- [ ] **GitHub repository** (optional but recommended for CI/CD)
- [ ] **Rust toolchain** installed (1.70+)
- [ ] **Python 3.8+** installed
- [ ] **maturin** installed (`pip install maturin`)

---

## Step 1: Pre-Publication Checklist

### 1.1 Update Repository URLs

The project currently has placeholder URLs. Update these files:

**Cargo.toml** (line 8):
```toml
repository = "https://github.com/YOUR_USERNAME/irene-cipher"
```

**pyproject.toml** (lines 32-34):
```toml
[project.urls]
Homepage = "https://github.com/YOUR_USERNAME/irene-cipher"
Repository = "https://github.com/YOUR_USERNAME/irene-cipher"
Documentation = "https://github.com/YOUR_USERNAME/irene-cipher#readme"
```

**README.md**: Search and replace all instances of `yourusername` with your actual username.

### 1.2 Verify Package Metadata

Check that these are correct in `pyproject.toml`:
- `name = "irene-cipher"`
- `version = "0.1.0"`
- `authors`
- `description`
- `keywords`
- `classifiers`

### 1.3 Final Testing

```bash
# Clean previous builds
rm -rf target/wheels target/release dist/

# Run all tests
cargo test
python test_irene_cipher.py
python examples.py

# Format and lint
cargo fmt --check
cargo clippy -- -D warnings

# Security audit
cargo audit
```

---

## Step 2: Build the Package

### 2.1 Build Locally (Quick Test)

```bash
# Build for your current platform
maturin build --release

# Output will be in target/wheels/
ls -lh target/wheels/
```

### 2.2 Test the Wheel Locally

```bash
# Create a test environment
python -m venv test_env
source test_env/bin/activate  # On Windows: test_env\Scripts\activate

# Install the wheel
pip install target/wheels/irene_cipher-0.1.0-*.whl

# Test it
python -c "import irene_cipher; print('Success!')"
python quickstart.py

# Clean up
deactivate
rm -rf test_env
```

---

## Step 3: Set Up PyPI Authentication

### Option A: API Token (Recommended)

1. **Create API token** on PyPI:
   - Go to https://pypi.org/manage/account/token/
   - Click "Add API token"
   - Name: "irene-cipher-upload"
   - Scope: "Entire account" (or specific project after first upload)
   - Copy the token (starts with `pypi-...`)

2. **Store token securely**:

```bash
# Option 1: Environment variable
export MATURIN_PYPI_TOKEN="pypi-YOUR_TOKEN_HERE"

# Option 2: Use keyring (more secure)
pip install keyring
python -c "import keyring; keyring.set_password('https://upload.pypi.org/legacy/', '__token__', 'pypi-YOUR_TOKEN_HERE')"
```

### Option B: Username/Password (Legacy)

```bash
# Configure credentials
cat > ~/.pypirc << EOF
[pypi]
username = __token__
password = pypi-YOUR_TOKEN_HERE
EOF

chmod 600 ~/.pypirc
```

---

## Step 4: Test on TestPyPI First (Recommended)

TestPyPI is a separate instance of PyPI for testing. **Highly recommended before real PyPI!**

### 4.1 Create TestPyPI Token

1. Go to https://test.pypi.org/manage/account/token/
2. Create token (same as PyPI)
3. Store it:

```bash
export MATURIN_TESTPYPI_TOKEN="pypi-YOUR_TEST_TOKEN_HERE"
```

### 4.2 Build and Publish to TestPyPI

```bash
# Build the wheel
maturin build --release

# Upload to TestPyPI
maturin upload --repository testpypi target/wheels/*

# Or in one command:
maturin publish --repository testpypi
```

### 4.3 Test Installation from TestPyPI

```bash
# Create fresh environment
python -m venv test_testpypi
source test_testpypi/bin/activate

# Install from TestPyPI
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ irene-cipher

# Test it
python -c "import irene_cipher; print(irene_cipher.generate_key().hex())"

# Clean up
deactivate
rm -rf test_testpypi
```

If everything works, proceed to real PyPI!

---

## Step 5: Publish to PyPI (Production)

### 5.1 Final Pre-Flight Check

```bash
# Verify version is correct
grep "version" Cargo.toml pyproject.toml

# Verify tests pass
cargo test && python test_irene_cipher.py

# Verify package builds
maturin build --release
```

### 5.2 Publish to PyPI

**Option A: Build and upload separately**

```bash
# Build wheels for your platform
maturin build --release

# Upload to PyPI
maturin upload target/wheels/*

# Enter your PyPI credentials when prompted
# Or it will use MATURIN_PYPI_TOKEN if set
```

**Option B: Build and publish in one command**

```bash
# Set token
export MATURIN_PYPI_TOKEN="pypi-YOUR_TOKEN_HERE"

# Build and publish
maturin publish

# This builds and uploads in one step
```

### 5.3 Verify Publication

1. **Check PyPI page**: https://pypi.org/project/irene-cipher/
2. **Test installation**:

```bash
# Fresh environment
python -m venv test_pypi
source test_pypi/bin/activate

# Install from PyPI
pip install irene-cipher

# Test
python -c "import irene_cipher; print('✓ Published successfully!')"
python -c "import irene_cipher; ct = irene_cipher.encrypt_text('test', 'pass'); print('✓ Works!')"

# Clean up
deactivate
rm -rf test_pypi
```

---

## Step 6: Multi-Platform Wheels (Advanced)

For production, you should provide wheels for all platforms:

### Option A: Using GitHub Actions (Recommended)

The project already has `.github/workflows/release.yml` configured!

1. **Push to GitHub**:
```bash
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/YOUR_USERNAME/irene-cipher.git
git push -u origin main
```

2. **Create a GitHub Release**:
```bash
# Tag the release
git tag v0.1.0
git push origin v0.1.0

# Or create release via GitHub UI
```

3. **GitHub Actions will automatically**:
   - Build wheels for Windows, macOS, Linux
   - Test on Python 3.8-3.12
   - Upload to PyPI

4. **Add PyPI token to GitHub Secrets**:
   - Go to repository Settings → Secrets → Actions
   - Add secret: `PYPI_API_TOKEN` = your PyPI token
   - GitHub Actions will use this automatically

### Option B: Manual Multi-Platform Build

**On Linux** (using Docker):
```bash
docker pull quay.io/pypa/manylinux2014_x86_64
docker run --rm -v $(pwd):/io quay.io/pypa/manylinux2014_x86_64 bash -c "
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && \
    source $HOME/.cargo/env && \
    cd /io && \
    pip install maturin && \
    maturin build --release
"
```

**On macOS**:
```bash
# Build universal2 wheel (Intel + Apple Silicon)
maturin build --release --target universal2-apple-darwin
```

**On Windows**:
```bash
# Build for Windows
maturin build --release
```

Then upload all wheels:
```bash
maturin upload target/wheels/*
```

---

## Step 7: Post-Publication

### 7.1 Verify Installation

Test on different platforms:

```bash
# Linux
pip install irene-cipher

# macOS
pip install irene-cipher

# Windows
pip install irene-cipher
```

### 7.2 Update Documentation

Create a GitHub release with:
- Version number (v0.1.0)
- Changelog (from CHANGELOG.md)
- Installation instructions
- Breaking changes (if any)

### 7.3 Announce

- Update README.md with PyPI badge
- Tweet/blog post (optional)
- Share on Reddit/HN (optional)

---

## Troubleshooting

### "Package already exists"

You can't overwrite an existing version on PyPI. You must:
1. Bump version in `Cargo.toml` and `pyproject.toml`
2. Rebuild and republish

### "401 Unauthorized"

- Check your PyPI token is correct
- Verify token has upload permissions
- Try deleting and recreating token

### "Wheel build failed"

- Ensure Rust is installed: `rustc --version`
- Update Rust: `rustup update`
- Check error messages carefully

### "Module not found after install"

- Verify wheel installed: `pip show irene-cipher`
- Check Python version compatibility
- Try: `pip install --force-reinstall irene-cipher`

### "ImportError: DLL load failed" (Windows)

- Install Visual C++ Redistributable
- Download from: https://aka.ms/vs/17/release/vc_redist.x64.exe

---

## Quick Reference Commands

### Test Locally
```bash
maturin develop --release
python test_irene_cipher.py
```

### Build Wheel
```bash
maturin build --release
```

### Publish to TestPyPI
```bash
maturin publish --repository testpypi
```

### Publish to PyPI
```bash
export MATURIN_PYPI_TOKEN="pypi-YOUR_TOKEN"
maturin publish
```

### Install from PyPI
```bash
pip install irene-cipher
```

---

## Automated Publishing with GitHub Actions

The project includes `.github/workflows/release.yml` that automatically:

1. **Builds wheels** for all platforms
2. **Tests** on Python 3.8-3.12
3. **Publishes to PyPI** on release

**To use**:

1. Add `PYPI_API_TOKEN` to GitHub repository secrets
2. Create a GitHub release (or push a tag)
3. GitHub Actions handles the rest!

```bash
# Create and push tag
git tag v0.1.0
git push origin v0.1.0

# Or create release via GitHub UI
```

---

## Version Updates (Future Releases)

When releasing a new version:

1. **Update version** in:
   - `Cargo.toml`: `version = "0.2.0"`
   - `pyproject.toml`: `version = "0.2.0"`

2. **Update CHANGELOG.md**:
   ```markdown
   ## [0.2.0] - 2026-02-15
   
   ### Added
   - New feature X
   
   ### Fixed
   - Bug Y
   ```

3. **Commit and tag**:
   ```bash
   git add Cargo.toml pyproject.toml CHANGELOG.md
   git commit -m "Bump version to 0.2.0"
   git tag v0.2.0
   git push origin main v0.2.0
   ```

4. **Publish**:
   ```bash
   maturin publish
   ```

---

## Security Considerations

### Before Publishing

- [ ] No hardcoded secrets in code
- [ ] No sensitive data in tests
- [ ] All dependencies are from trusted sources
- [ ] `cargo audit` shows no vulnerabilities
- [ ] Security policy (SECURITY.md) is up to date

### API Token Security

- **Never commit tokens** to git
- **Use environment variables** or keyring
- **Limit token scope** to specific project if possible
- **Rotate tokens** periodically
- **Revoke old tokens** after use

---

## Success! 🎉

Once published, your package will be available at:

- **PyPI**: https://pypi.org/project/irene-cipher/
- **Install**: `pip install irene-cipher`
- **Documentation**: Your GitHub README

**Next Steps**:
1. Monitor PyPI download stats
2. Respond to issues on GitHub
3. Plan next release
4. Consider professional security audit

---

## Quick Start Summary

**Absolute minimum to publish**:

```bash
# 1. Get PyPI token from https://pypi.org/manage/account/token/

# 2. Set token
export MATURIN_PYPI_TOKEN="pypi-YOUR_TOKEN"

# 3. Build and publish
maturin publish

# Done! Check https://pypi.org/project/irene-cipher/
```

**Recommended workflow**:

```bash
# 1. Test on TestPyPI first
maturin publish --repository testpypi

# 2. Test installation
pip install --index-url https://test.pypi.org/simple/ irene-cipher

# 3. If good, publish to real PyPI
maturin publish

# 4. Verify
pip install irene-cipher
```

---

Need help? Check [BUILDING.md](BUILDING.md) or open a GitHub issue!
