Skip to content

Authenticate PyPI uploads with API tokens - #227

Merged
gomezzz merged 1 commit into
releasefrom
ci/pypi-token-auth
Aug 22, 2026
Merged

gomezzz merged 1 commit into
releasefrom
ci/pypi-token-auth

Conversation

@gomezzz

@gomezzz gomezzz commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

Description

The 0.2.1 testpypi upload built and transferred the 16.1 MB wheel fine, then died on HTTPError: 403 Forbidden from https://test.pypi.org/legacy/.

Cause: both deploy workflows authenticate with TWINE_USERNAME/TWINE_PASSWORD set from the PYPI_USERNAME / PYPI_PASSWORD secrets. PyPI and Test PyPI have since removed password-based uploads entirely — API tokens are the only accepted credential. The 403 is the server rejecting the scheme, not the package.

This switches both workflows to the supported form (the same one torchquad uses): the literal user __token__ with an API token as the password. Test PyPI and PyPI are separate services with separate accounts, so they get separate token secrets instead of the single shared pair.

  • deploy_to_test_pypi.yml -> secrets.TEST_PYPI_TOKEN
  • deploy_to_pypi.yml -> secrets.PYPI_TOKEN

Related to #224

Important

This needs two new repository secrets before either workflow can upload:

Secret Created at Scope
TEST_PYPI_TOKEN https://test.pypi.org/manage/account/token/ project paseos (or account-wide for the first upload)
PYPI_TOKEN https://pypi.org/manage/account/token/ project paseos

Paste the token including its pypi- prefix. The old PYPI_USERNAME / PYPI_PASSWORD secrets are unused after this and can be deleted.

Test plan

  • Add TEST_PYPI_TOKEN and PYPI_TOKEN repository secrets
  • Run Upload Python Package to testpypi on release and confirm it uploads paseos 0.2.1
  • pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple paseos

Both deploy workflows sent PYPI_USERNAME/PYPI_PASSWORD, but (Test)PyPI
removed password-based uploads, so twine got a bare 403 Forbidden after a
successful build and upload transfer.

Switch to the only supported scheme: the literal user '__token__' with an
API token as the password. Test PyPI and PyPI are separate services with
separate accounts, so they need separate token secrets rather than the one
shared credential pair used before.
@github-actions

Copy link
Copy Markdown

Overall Coverage

Coverage Report
FileStmtsMissCoverMissing
__init__.py33197%48
paseos.py1471292%67–68, 153–154, 214, 229, 247, 256, 274, 305, 313, 316
activities
   activity_manager.py43393%46, 74, 156
   activity_processor.py59198%91
   activity_runner.py621084%80–81, 84, 104, 108–109, 112–113, 122, 125
actors
   actor_builder.py1853283%24–25, 27, 30, 33, 223–225, 256–258, 312, 316–317, 320–321, 342, 344–345, 348–349, 488, 545, 573, 585–586, 588–589, 596–597, 604–605
   base_actor.py1281886%82, 104, 120, 167, 207–209, 230, 239, 256, 277, 283–286, 292, 307, 362
   ground_station_actor.py15380%47, 51, 53
   spacecraft_actor.py60198%122
central_body
   central_body.py65592%68, 177–178, 186–187
   is_in_line_of_sight.py581279%107–108, 110, 112–117, 124, 168, 188
   mesh_between_points.py35294%64, 72
   sphere_between_points.py26869%35, 37–38, 48, 50–51, 63–64
communication
   find_next_window.py200100% 
   get_communication_window.py23291%38, 64
geometric_model
   geometric_model.py281643%32, 34–38, 47, 49, 61, 76, 78–79, 92–93, 101–102
power
   charge_model.py16194%50
   discharge_model.py7186%34
   power_device_type.py40100% 
radiation
   radiation_model.py320100% 
tests
   activity_test.py56395%92, 95–96
   actor_builder_test.py630100% 
   advance_time_test.py170100% 
   communication_window_test.py48198%177
   custom_propagator_test.py250100% 
   custom_property_test.py230100% 
   default_cfg_test.py90100% 
   eclipse_test.py10190%20
   event_based_test.py230100% 
   import_test.py6183%13
   init_test.py8188%16
   line_of_sight_test.py62494%143–146
   mesh_test.py119397%119, 137, 145
   multiple_instance_test.py120100% 
   operations_monitor_test.py310100% 
   power_test.py290100% 
   radiation_test.py590100% 
   test_utils.py170100% 
   thermal_model_test.py30197%70
   time_multiplier_test.py260100% 
   visualization_test.py18194%30
thermal
   thermal_model.py750100% 
utils
   check_cfg.py611870%31, 40, 46, 60–62, 67, 70–72, 75–77, 80–82, 98, 103
   load_default_cfg.py90100% 
   operations_monitor.py71396%127–128, 130
   reference_frame.py40100% 
   set_log_level.py60100% 
visualization
   animation.py18667%28–31, 36, 45
   plot.py9367%29–30, 32
   space_animation.py2152389%109–110, 125, 148–149, 183, 207, 214, 220, 330, 353–355, 360, 369–370, 374, 410, 416–417, 448, 462, 473
TOTAL220519791% 

Tests Skipped Failures Errors Time
38 0 💤 0 ❌ 0 🔥 3m 54s ⏱️

@gomezzz
gomezzz merged commit b6b014e into release Aug 22, 2026
2 checks passed
@gomezzz
gomezzz deleted the ci/pypi-token-auth branch August 22, 2026 10:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant