Successfully refactored the codebase to use the @rage-against-the-pixel/app-store-connect-api TypeScript SDK instead of manually crafting JWT tokens and making curl requests.
- Installed
@rage-against-the-pixel/app-store-connect-apipackage - Added to package.json dependencies
- Added
createAppStoreConnectClient()function in lib.ts - Reads .p8 key file and initializes AppStoreConnectClient
- Handles authentication automatically via the SDK
- Replaced manual curl POST request with
client.api.Certificates.certificatesCreateInstance() - Uses
CertificateType.DEVELOPMENTenum for type safety - Improved error handling with SDK's structured error responses
- Added null checks for optional response fields
- Replaced manual curl GET request with
client.api.Certificates.certificatesGetCollection() - Replaced manual curl DELETE request with
client.api.Certificates.certificatesDeleteInstance() - Uses SDK's typed responses for cleaner code
- Deleted entire
generateJwtToken()function (~70 lines) - Removed OpenSSL-based JWT signing logic
- SDK handles JWT generation internally using the
joselibrary
- All API calls now use TypeScript types from the SDK
- Proper enum usage for certificate types
- Better compile-time error checking
✅ Cleaner Code: Removed ~100 lines of manual JWT and curl logic ✅ Type Safety: Full TypeScript support with auto-generated types ✅ Better Errors: Structured error responses from SDK ✅ Maintainability: SDK auto-updates with Apple's OpenAPI spec ✅ Less Dependencies: No longer need manual OpenSSL JWT signing ✅ Reliability: SDK handles edge cases and API changes
- Before: ~1736kB compiled
- After: ~2958kB compiled (+1222kB due to SDK and jose library)
The size increase is acceptable given the benefits of type safety, maintainability, and reduced custom code.
- Test certificate creation with API key authentication
- Verify certificate appears in keychain
- Test post action cleanup
- Verify certificate is deleted from both keychain and App Store Connect
- Test error scenarios (invalid API key, network issues)
- Verify parallel job execution still works correctly