# Publishing to PyPI

This guide describes how to publish the `arc-deploy` CLI tool to PyPI.

## Prerequisites

### 1. Install uv

```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```

Verify installation:
```bash
uv --version
```

### 2. Configure PyPI Credentials

#### Method 1: API Token (Recommended)

**Test PyPI (Staging)**:
1. Visit https://test.pypi.org/manage/account/token/
2. Create a new API token
3. Set environment variable:
   ```bash
   export UV_PUBLISH_TOKEN="pypi-..."  # Test PyPI token
   ```

**Production PyPI**:
1. Visit https://pypi.org/manage/account/token/
2. Create a new API token
3. Set environment variable:
   ```bash
   export UV_PUBLISH_TOKEN="pypi-..."  # Production PyPI token
   ```

#### Method 2: .pypirc File

Create `~/.pypirc`:
```ini
[distutils]
index-servers =
    pypi
    testpypi

[pypi]
username = __token__
password = pypi-your-token-here

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

Set permissions:
```bash
chmod 600 ~/.pypirc
```

---

## Publishing Workflow

### Step 1: Update Version

Edit `src/arc_deploy/__init__.py`:
```python
__version__ = "0.2.0"  # Update version
```

Edit `pyproject.toml`:
```toml
[project]
version = "0.2.0"  # Keep consistent
```

**Versioning Rules (SemVer)**:
- `0.1.0` → `0.1.1`: Bug fix
- `0.1.0` → `0.2.0`: New feature (backwards compatible)
- `0.1.0` → `1.0.0`: Major change (breaking)

### Step 2: Commit Changes

```bash
git add src/arc_deploy/__init__.py pyproject.toml
git commit -m "chore: bump version to 0.2.0"
git tag v0.2.0
git push origin main --tags
```

### Step 3: Test Build

```bash
cd cli

# Clean old files
rm -rf dist/ build/ *.egg-info

# Build package
uv build

# Check artifacts
ls -lh dist/
```

Expect output:
```
arc_deploy-0.2.0-py3-none-any.whl
arc_deploy-0.2.0.tar.gz
```

### Step 4: Publish to Test PyPI

```bash
./publish.sh
# Or manually
uv publish --publish-url https://test.pypi.org/legacy/
```

### Step 5: Test Installation

```bash
# Create temporary venv
uv venv test-env
source test-env/bin/activate

# Install from Test PyPI
uv pip install --index-url https://test.pypi.org/simple/ arc-deploy

# Test commands
arc-deploy --help
arc-deploy list-services --config examples/monorepo/deploy.yaml

# Cleanup
deactivate
rm -rf test-env
```

### Step 6: Publish to Production PyPI

After verifying tests pass:

```bash
./publish.sh prod
# Or manually
uv publish
```

### Step 7: Verify Release

Check PyPI page:
- https://pypi.org/project/arc-deploy/

Test installation:
```bash
pip install arc-deploy
arc-deploy --help
```

---

## Common Commands

### Local Development Install

```bash
cd cli

# Install in editable mode
uv pip install -e .

# Test command
arc-deploy --help
```

### Build Only

```bash
uv build
```

### Check Package Metadata

```bash
uv pip show arc-deploy
```

### Uninstall

```bash
uv pip uninstall arc-deploy
```

---

## Publishing Checklist

- [ ] Version updated (`__init__.py` and `pyproject.toml`)
- [ ] Code committed and tagged
- [ ] Local tests passed
- [ ] Dependencies correct
- [ ] Build successful
- [ ] Test PyPI installation verified
- [ ] CLI tool works correctly
- [ ] `README.md` content accurate (used for PyPI page)

---

## Troubleshooting

### 1. uv not found

**Error**: `command not found: uv`

**Fix**:
```bash
export PATH="$HOME/.local/bin:$PATH"
```

### 2. Auth Failure

**Error**: `HTTP Error 403: Invalid or non-existent authentication information`

**Fix**:
1. Check API token correctness
2. Ensure username is `__token__`
3. Verify env var: `echo $UV_PUBLISH_TOKEN`

### 3. Version Conflict

**Error**: `File already exists`

**Fix**: Bump version number (PyPI prevents overwriting).

### 4. Build Failure

**Error**: `ERROR: Could not build wheels`

**Fix**:
Check `pyproject.toml` syntax and `src/` structure.

---

## Automation (Optional)

### GitHub Actions

`.github/workflows/publish.yml`:

```yaml
name: Publish to PyPI

on:
  release:
    types: [published]

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Install uv
        run: curl -LsSf https://astral.sh/uv/install.sh | sh

      - name: Build
        run: |
          cd cli
          uv build

      - name: Publish
        env:
          UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
        run: |
          cd cli
          uv publish
```

---

## Quick Reference

```bash
# Build
uv build

# Publish to Test PyPI
uv publish --publish-url https://test.pypi.org/legacy/

# Publish to Production
uv publish

# Using Script
./publish.sh        # Test PyPI
./publish.sh prod   # Production
```
