33use crate :: team_api:: TeamApi ;
44use std:: cmp:: Ordering ;
55
6- use crate :: crates_io:: api:: { CratesIoApi , TrustedPublishingGitHubConfig } ;
6+ use crate :: crates_io:: api:: { CratesIoApi , CratesIoOwner , OwnerKind , TrustedPublishingGitHubConfig } ;
77use anyhow:: Context ;
88use secrecy:: SecretString ;
99use std:: collections:: BTreeMap ;
@@ -78,6 +78,7 @@ impl SyncCratesIo {
7878
7979 // Note: we currently only support one trusted publishing configuration per crate
8080 for ( krate, desired) in & self . crates {
81+ // Sync trusted publishing configs
8182 let mut configs = self
8283 . crates_io_api
8384 . list_trusted_publishing_github_configs ( & krate. 0 )
@@ -113,6 +114,7 @@ impl SyncCratesIo {
113114 // Non-matching configs should be deleted
114115 config_diffs. extend ( configs. into_iter ( ) . map ( ConfigDiff :: Delete ) ) ;
115116
117+ // Sync "trusted publishing only" crate option
116118 let trusted_publish_only_expected = desired. trusted_publishing_only ;
117119 let crates_io_crate = self
118120 . crates_io_api
@@ -124,11 +126,28 @@ impl SyncCratesIo {
124126 value : trusted_publish_only_expected,
125127 } ) ;
126128 }
129+
130+ // Sync crate owners
131+ let owners = self
132+ . crates_io_api
133+ . list_crate_owners ( & krate. 0 )
134+ . with_context ( || anyhow:: anyhow!( "Cannot list crate owners of {krate}" ) ) ?;
135+ // Make sure that the only user owner is `rust-lang-owner`
136+ let user_owners = owners
137+ . into_iter ( )
138+ . filter ( |owner| match owner. kind {
139+ OwnerKind :: User => owner. login != "rust-lang-owner" ,
140+ OwnerKind :: Team => false ,
141+ } )
142+ . collect :: < Vec < _ > > ( ) ;
143+ crate_diffs. push ( CrateDiff :: RemoveOwners {
144+ krate : krate. to_string ( ) ,
145+ owners : user_owners,
146+ } )
127147 }
128148
129149 // We want to apply deletions first, and only then create new configs, to ensure that we
130- // don't try to create a duplicate config where e.g. only the environment differs, which
131- // would be an error in crates.io.
150+ // don't try to create a duplicate config where e.g. only the environment differs.
132151 config_diffs. sort_by ( |a, b| match & ( a, b) {
133152 ( ConfigDiff :: Delete ( _) , ConfigDiff :: Create ( _) ) => Ordering :: Less ,
134153 ( ConfigDiff :: Create ( _) , ConfigDiff :: Delete ( _) ) => Ordering :: Greater ,
@@ -237,7 +256,14 @@ impl std::fmt::Display for ConfigDiff {
237256}
238257
239258enum CrateDiff {
240- SetTrustedPublishingOnly { krate : String , value : bool } ,
259+ SetTrustedPublishingOnly {
260+ krate : String ,
261+ value : bool ,
262+ } ,
263+ RemoveOwners {
264+ krate : String ,
265+ owners : Vec < CratesIoOwner > ,
266+ } ,
241267}
242268
243269impl CrateDiff {
@@ -246,6 +272,9 @@ impl CrateDiff {
246272 Self :: SetTrustedPublishingOnly { krate, value } => sync
247273 . crates_io_api
248274 . set_trusted_publishing_only ( krate, * value) ,
275+ CrateDiff :: RemoveOwners { krate, owners } => {
276+ sync. crates_io_api . delete_crate_owners ( krate, owners)
277+ }
249278 }
250279 }
251280}
@@ -259,6 +288,9 @@ impl std::fmt::Display for CrateDiff {
259288 " Setting trusted publishing only option for krate `{krate}` to `{value}`" ,
260289 ) ?;
261290 }
291+ CrateDiff :: RemoveOwners { krate, owners } => {
292+ writeln ! ( f, " Removing owner(s) `{owners:?}` from krate `{krate}`" ) ?;
293+ }
262294 }
263295 Ok ( ( ) )
264296 }
0 commit comments