@@ -1090,7 +1090,7 @@ PREVIEW_BRANCH: ${{ needs.config.outputs.docs_preview_branch }}
10901090# ### 3. Python Package Configuration
10911091
10921092**`artifacts.python`** (string, default: `"auto"`)
1093- Controls Python package publishing to PyPI :
1093+ Controls Python package publishing to PyPI with **dual authentication support** :
10941094
10951095- `"auto"` : Publish if package files changed
10961096- `"force"` : Always publish regardless of changes
@@ -1108,6 +1108,209 @@ artifacts:
11081108 python: skip
11091109` ` `
11101110
1111+ # #### PyPI Authentication Methods
1112+
1113+ 
1114+ 
1115+
1116+ The template now supports **dual authentication methods** for PyPI package uploads, providing both modern security and backward compatibility :
1117+
1118+ **Authentication Configuration:**
1119+ ` ` ` yaml
1120+ # Enhanced project configuration (New)
1121+ python:
1122+ auth_method: "oidc" # or "token"
1123+ ` ` `
1124+
1125+ # ##### OIDC Authentication (Recommended) 🔒
1126+
1127+ **Benefits:**
1128+ - ✅ **Keyless Authentication** : No API tokens to manage or rotate
1129+ - ✅ **Enhanced Security** : Uses GitHub's OIDC identity tokens
1130+ - ✅ **Zero Secrets** : No repository secrets needed
1131+ - ✅ **PyPI Recommended** : Official PyPI recommendation for CI/CD
1132+
1133+ **Setup Requirements:**
1134+ 1. **Configure Trusted Publisher on PyPI** :
1135+ - Go to PyPI → Account Settings → Publishing
1136+ - Add GitHub as trusted publisher
1137+ - Repository : ` your-org/your-repo`
1138+ - Workflow : ` release.yml` (or your release workflow name)
1139+ - Environment : ` production` (optional)
1140+
1141+ 2. **Set Authentication Method** :
1142+ ` ` ` yaml
1143+ # In .github/tag_and_release/intent.yaml
1144+ python:
1145+ auth_method: "oidc" # Default, recommended
1146+ ` ` `
1147+
1148+ 3. **No Additional Setup** : OIDC works automatically! ✨
1149+
1150+ **How OIDC Works:**
1151+ ` ` ` mermaid
1152+ graph LR
1153+ A[GitHub Actions] --> B[Request OIDC Token]
1154+ B --> C[GitHub Issues Token]
1155+ C --> D[PyPI Validates Token]
1156+ D --> E[Package Published]
1157+
1158+ style A fill:#4CAF50
1159+ style E fill:#4CAF50
1160+ ` ` `
1161+
1162+ # ##### Token Authentication (Legacy) 🔑
1163+
1164+ **Benefits:**
1165+ - ✅ **Backward Compatible** : Works with existing PyPI token setups
1166+ - ✅ **Universal Support** : Works with all PyPI-compatible repositories
1167+ - ✅ **Simple Migration** : Easy transition from existing token-based workflows
1168+
1169+ **Setup Requirements:**
1170+ 1. **Generate API Tokens** :
1171+ - **Production**: [PyPI Account Settings](https://pypi.org/manage/account/token/) → Create new token
1172+ - **Staging**: [TestPyPI Account Settings](https://test.pypi.org/manage/account/token/) → Create new token
1173+
1174+ 2. **Add Repository Secrets** :
1175+ - `PYPI_API_TOKEN` : Your production PyPI API token
1176+ - `TEST_PYPI_API_TOKEN` : Your TestPyPI API token
1177+
1178+ 3. **Configure Authentication Method** :
1179+ ` ` ` yaml
1180+ # In .github/tag_and_release/intent.yaml
1181+ python:
1182+ auth_method: "token"
1183+ ` ` `
1184+
1185+ **Security Considerations:**
1186+ - 🔄 **Token Rotation** : Regularly rotate API tokens
1187+ - 🔒 **Secret Management** : Store tokens securely in GitHub repository secrets
1188+ - 🎯 **Scope Limitation** : Use project-scoped tokens when possible
1189+
1190+ # #### Authentication Configuration Examples
1191+
1192+ **Example 1: OIDC Authentication (Recommended)**
1193+ ` ` ` yaml
1194+ # Modern, secure, keyless authentication
1195+ python:
1196+ auth_method: "oidc"
1197+
1198+ artifacts:
1199+ python: "auto"
1200+
1201+ # No secrets needed - uses GitHub OIDC identity
1202+ ` ` `
1203+
1204+ **Example 2: Token Authentication (Legacy)**
1205+ ` ` ` yaml
1206+ # Traditional API token authentication
1207+ python:
1208+ auth_method: "token"
1209+
1210+ artifacts:
1211+ python: "auto"
1212+
1213+ # Requires repository secrets:
1214+ # - PYPI_API_TOKEN
1215+ # - TEST_PYPI_API_TOKEN
1216+ ` ` `
1217+
1218+ **Example 3: Mixed Environment Strategy**
1219+ ` ` ` yaml
1220+ # Development projects can use OIDC for simplicity
1221+ # Production projects might prefer token control
1222+ python:
1223+ auth_method: "oidc" # Easy setup for development
1224+
1225+ artifacts:
1226+ python: "auto"
1227+ ` ` `
1228+
1229+ # #### Authentication Method Comparison
1230+
1231+ | Feature | OIDC Authentication | Token Authentication |
1232+ |----------------------------|----------------------------------------------|----------------------------------------|
1233+ | **Security** | 🟢 Keyless, identity-based | 🟡 Token-based, requires rotation |
1234+ | **Setup Complexity** | 🟢 Simple (just configure trusted publisher) | 🟡 Moderate (generate + store tokens) |
1235+ | **Maintenance** | 🟢 Zero maintenance | 🟡 Regular token rotation needed |
1236+ | **PyPI Support** | 🟢 Official recommendation | 🟢 Universal support |
1237+ | **Secrets Required** | 🟢 None | 🔴 2 secrets (PYPI + TEST_PYPI tokens) |
1238+ | **Backward Compatibility** | 🟡 Modern PyPI feature | 🟢 Works everywhere |
1239+ | **Troubleshooting** | 🟢 Clear OIDC validation errors | 🟡 Token validation complexity |
1240+
1241+ # #### Authentication Workflow Architecture
1242+
1243+ The dual authentication system seamlessly integrates with the existing release architecture :
1244+
1245+ ` ` ` mermaid
1246+ graph TD
1247+ A[Release Workflow] --> B[Parse Project Config]
1248+ B --> C[Read python.auth_method]
1249+
1250+ C --> D{Authentication Method}
1251+ D -->|oidc| E[OIDC Authentication]
1252+ D -->|token| F[Token Authentication]
1253+
1254+ E --> G[GitHub OIDC Token]
1255+ F --> H[Repository Secrets]
1256+
1257+ G --> I[PyPI Trusted Publisher]
1258+ H --> J[PyPI API Validation]
1259+
1260+ I --> K[Package Published]
1261+ J --> K
1262+
1263+ style E fill:#4CAF50
1264+ style F fill:#2196F3
1265+ style K fill:#FF9800
1266+ ` ` `
1267+
1268+ **Implementation Details:**
1269+ - **Centralized Configuration**: Authentication method specified once in `intent.yaml`
1270+ - **Secret Forwarding**: Proper secret passing from calling workflows to reusable workflows
1271+ - **Conditional Logic**: Workflows automatically select authentication method
1272+ - **Error Handling**: Clear validation and error messages for missing tokens
1273+ - **Operation Summary**: Workflow reports which authentication method was used
1274+
1275+ # #### Migration Guide
1276+
1277+ **From Token to OIDC (Recommended)**:
1278+ 1. Set up PyPI Trusted Publisher for your repository
1279+ 2. Update `intent.yaml` :
1280+ ` ` ` yaml
1281+ python:
1282+ auth_method: "oidc" # Change from "token"
1283+ ` ` `
1284+ 3. Test with staging release workflow
1285+ 4. Optionally remove PyPI token secrets (but keep for rollback)
1286+
1287+ **From OIDC to Token** (if needed):
1288+ 1. Generate PyPI API tokens
1289+ 2. Add `PYPI_API_TOKEN` and `TEST_PYPI_API_TOKEN` to repository secrets
1290+ 3. Update `intent.yaml` :
1291+ ` ` ` yaml
1292+ python:
1293+ auth_method: "token" # Change from "oidc"
1294+ ` ` `
1295+ 4. Test with staging release workflow
1296+
1297+ # #### Troubleshooting Authentication
1298+
1299+ **OIDC Authentication Issues:**
1300+ - **Error**: `OIDC token validation failed`
1301+ - **Solution**: Verify PyPI Trusted Publisher configuration matches your repository and workflow
1302+ - **Check**: Repository name, workflow filename, and optional environment name
1303+
1304+ **Token Authentication Issues:**
1305+ - **Error**: `PyPI API token not found in secrets`
1306+ - **Solution**: Verify `PYPI_API_TOKEN` and `TEST_PYPI_API_TOKEN` are added to repository secrets
1307+ - **Check**: Token scope and expiration date
1308+
1309+ **General Authentication Debugging:**
1310+ - **Workflow Logs**: Check the Python package workflow step for detailed authentication logs
1311+ - **Operation Summary**: Each workflow reports which authentication method was used
1312+ - **Validation Workflow**: Test authentication setup with `release-validate.yml`
1313+
11111314# ### 4. Docker Image Configuration
11121315
11131316**`artifacts.docker`** (string, default: `"auto"`)
0 commit comments