---
phase: 13-cicd
plan: 02
type: execute
wave: 1
depends_on: []
files_modified: [.github/workflows/release.yml]
autonomous: false

user_setup:
  - service: pypi
    why: "Trusted publishing requires PyPI project configuration"
    env_vars: []
    dashboard_config:
      - task: "Create PyPI project (first-time only)"
        location: "https://pypi.org/manage/projects/ -> Your projects"
        notes: "Project 'gitsl' will be created on first publish, OR create manually"
      - task: "Add trusted publisher"
        location: "PyPI project -> Settings -> Publishing -> Add a new publisher"
        notes: |
          Configure with:
          - Owner: <your-github-username-or-org>
          - Repository: gitsl
          - Workflow name: release.yml
          - Environment: pypi

must_haves:
  truths:
    - "Tagged release (v*) triggers PyPI publish workflow"
    - "Package is built as wheel and sdist"
    - "Publishing uses OIDC trusted publishing (no API tokens)"
    - "Package appears on PyPI after successful workflow"
  artifacts:
    - path: ".github/workflows/release.yml"
      provides: "Release workflow with PyPI trusted publishing"
      contains: "pypa/gh-action-pypi-publish"
  key_links:
    - from: ".github/workflows/release.yml"
      to: "pypi.org"
      via: "OIDC trusted publishing"
      pattern: "id-token: write"
    - from: ".github/workflows/release.yml"
      to: "python -m build"
      via: "package build step"
      pattern: "python -m build"
---

<objective>
Create GitHub Actions release workflow for PyPI publishing

Purpose: Automate package publishing to PyPI when version tags are pushed, using secure OIDC trusted publishing without storing API tokens.

Output: `.github/workflows/release.yml` that builds and publishes on v* tags
</objective>

<execution_context>
@~/.claude/get-shit-done/workflows/execute-plan.md
@~/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/13-cicd/13-RESEARCH.md
@.planning/phases/12-packaging/12-01-SUMMARY.md
@pyproject.toml
</context>

<tasks>

<task type="auto">
  <name>Task 1: Create release workflow with build job</name>
  <files>.github/workflows/release.yml</files>
  <action>
Create `.github/workflows/release.yml` with:

**Trigger configuration:**
```yaml
name: Release

on:
  push:
    tags:
      - 'v*'  # Matches v1.0.0, v2.0.0-beta, etc.
```

**Build job:**
```yaml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'

      - name: Install build dependencies
        run: pip install build

      - name: Build package
        run: python -m build

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: dist
          path: dist/
```

This creates both wheel (.whl) and source distribution (.tar.gz) in the dist/ directory.
  </action>
  <verify>File `.github/workflows/release.yml` exists with valid YAML: `python -c "import yaml; yaml.safe_load(open('.github/workflows/release.yml'))"`</verify>
  <done>Release workflow created with build job producing wheel and sdist artifacts</done>
</task>

<task type="auto">
  <name>Task 2: Add publish job with trusted publishing</name>
  <files>.github/workflows/release.yml</files>
  <action>
Add the publish job after the build job:

```yaml
  publish:
    needs: build
    runs-on: ubuntu-latest
    environment: pypi
    permissions:
      id-token: write  # MANDATORY for trusted publishing

    steps:
      - name: Download artifacts
        uses: actions/download-artifact@v4
        with:
          name: dist
          path: dist/

      - name: Publish to PyPI
        uses: pypa/gh-action-pypi-publish@release/v1
```

**Critical requirements for trusted publishing:**
1. `permissions: id-token: write` - Required for OIDC token
2. `environment: pypi` - Must match the environment name configured in PyPI
3. No additional authentication configuration needed - pypa/gh-action-pypi-publish handles OIDC

**Note:** This will fail until PyPI trusted publisher is configured (see user_setup in frontmatter).
  </action>
  <verify>Workflow contains `id-token: write` permission and `pypa/gh-action-pypi-publish` action</verify>
  <done>Publish job added with OIDC trusted publishing configuration</done>
</task>

<task type="checkpoint:human-verify" gate="blocking">
  <what-built>
Release workflow for PyPI publishing using trusted publishing (OIDC)

The workflow will:
1. Trigger on `v*` tags (e.g., `git tag v1.0.0 && git push --tags`)
2. Build wheel and sdist using `python -m build`
3. Publish to PyPI using OIDC (no API tokens)
  </what-built>
  <how-to-verify>
Before the release workflow can succeed, you need to configure PyPI trusted publisher:

1. **If project doesn't exist on PyPI yet:**
   - Go to https://pypi.org/manage/account/publishing/
   - Add a "pending publisher" with:
     - PyPI Project Name: `gitsl`
     - Owner: `<your-github-username-or-org>`
     - Repository name: `gitsl`
     - Workflow name: `release.yml`
     - Environment name: `pypi`

2. **If project already exists on PyPI:**
   - Go to https://pypi.org/manage/project/gitsl/settings/publishing/
   - Add publisher with same settings as above

3. **Create GitHub environment:**
   - Go to GitHub repo -> Settings -> Environments
   - Create environment named `pypi`
   - No secrets needed (OIDC handles auth)

4. **Test the release:**
   - Create and push a tag: `git tag v1.0.0 && git push --tags`
   - Watch the Actions tab for the Release workflow
   - Verify package appears at https://pypi.org/project/gitsl/
  </how-to-verify>
  <resume-signal>Type "pypi configured" after setting up trusted publisher, or describe any issues</resume-signal>
</task>

</tasks>

<verification>
1. `.github/workflows/release.yml` exists and has valid YAML
2. Workflow triggers only on `v*` tags
3. Build job creates wheel and sdist artifacts
4. Publish job uses `pypa/gh-action-pypi-publish@release/v1`
5. Publish job has `permissions: id-token: write`
6. Publish job has `environment: pypi`
7. No API tokens or secrets referenced
</verification>

<success_criteria>
- CI-04: Release workflow publishes to PyPI on version tag (workflow structure verified)
- CI-05: Trusted publishing configured (id-token: write permission present)
- PACK-02: `pip install gitsl` works after first release (verified after human completes PyPI setup)
</success_criteria>

<output>
After completion, create `.planning/phases/13-cicd/13-02-SUMMARY.md`
</output>
