Archived
f4abfe6fdc
Belated rename commit for foundation/el-ui — was missed in the workspace-wide crates→vessels pass earlier today. Same structural intent as the rename in the other repos: 'crates' is the Rust word, 'vessel' is El's, and the directory rename is the marker that this slot holds an El buildable unit even if its current contents are still Rust pending port. Plus the El ports themselves — manifest.el + src/main.el per sub- vessel (el-aop, el-auth, el-config, el-i18n, el-identity, el-layout, el-platform, el-publish, el-secrets, el-services, el-style, el-ui- compiler). The ui-compiler is a stub: elc only emits C right now; generating browser-target JS/Wasm is the biggest open language gap and gets its own project. Until then, el-ui-compiler emits a JS module that throws elc.backend_missing so callers fail loudly. Cross-repo path dependencies in Cargo.toml updated to vessels/.
125 lines
4.1 KiB
Rust
125 lines
4.1 KiB
Rust
//! Google Play Developer API publisher.
|
|
//!
|
|
//! Models the Google Play Developer API calls. Stubs the actual HTTP.
|
|
//!
|
|
//! API reference: https://developers.google.com/android-publisher
|
|
|
|
use crate::{
|
|
config::{GoogleConfig, PublishConfig},
|
|
metadata::StoreMetadata,
|
|
PublishError, PublishOutcome, PublishResult,
|
|
};
|
|
|
|
/// Publishes app bundles to Google Play Store.
|
|
pub struct GooglePublisher {
|
|
pub google_config: GoogleConfig,
|
|
pub publish_config: PublishConfig,
|
|
}
|
|
|
|
impl GooglePublisher {
|
|
pub fn new(publish_config: PublishConfig) -> PublishResult<Self> {
|
|
let google_config = publish_config.google.clone().ok_or_else(|| {
|
|
PublishError::Config("no [publish.google] section in manifest.el".into())
|
|
})?;
|
|
Ok(Self { google_config, publish_config })
|
|
}
|
|
|
|
/// Create a new edit session on Google Play.
|
|
///
|
|
/// In production: POST https://androidpublisher.googleapis.com/v3/applications/{packageName}/edits
|
|
pub fn create_edit(&self) -> PublishResult<String> {
|
|
// TODO: OAuth2 authentication via service account JSON
|
|
let edit_id = format!("edit-{}", self.publish_config.build_number);
|
|
Ok(edit_id)
|
|
}
|
|
|
|
/// Upload an AAB (Android App Bundle) to an edit session.
|
|
///
|
|
/// In production: POST .../edits/{editId}/bundles (multipart upload)
|
|
pub fn upload_bundle(
|
|
&self,
|
|
edit_id: &str,
|
|
aab_path: &str,
|
|
) -> PublishResult<u32> {
|
|
let _ = (edit_id, aab_path);
|
|
// Returns the version code of the uploaded bundle
|
|
Ok(self.publish_config.build_number)
|
|
}
|
|
|
|
/// Assign a bundle to a track.
|
|
///
|
|
/// In production: PUT .../edits/{editId}/tracks/{track}
|
|
pub fn assign_to_track(
|
|
&self,
|
|
edit_id: &str,
|
|
version_code: u32,
|
|
track: &str,
|
|
rollout_fraction: f64,
|
|
) -> PublishResult<()> {
|
|
let _ = (edit_id, version_code, track, rollout_fraction);
|
|
if !matches!(track, "internal" | "alpha" | "beta" | "production") {
|
|
return Err(PublishError::Config(format!(
|
|
"unknown Google Play track: '{}'. Use internal/alpha/beta/production",
|
|
track
|
|
)));
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Upload store listing (metadata) for a locale.
|
|
///
|
|
/// In production: PATCH .../edits/{editId}/listings/{language}
|
|
pub fn upload_listing(
|
|
&self,
|
|
edit_id: &str,
|
|
locale: &str,
|
|
metadata: &StoreMetadata,
|
|
) -> PublishResult<()> {
|
|
let _ = (edit_id, locale, metadata);
|
|
Ok(())
|
|
}
|
|
|
|
/// Commit an edit (makes the changes live).
|
|
///
|
|
/// In production: POST .../edits/{editId}:commit
|
|
pub fn commit_edit(&self, edit_id: &str) -> PublishResult<String> {
|
|
// Returns the resulting version code
|
|
Ok(format!("{}-committed", edit_id))
|
|
}
|
|
|
|
/// Update rollout percentage for a track (for staged rollouts).
|
|
pub fn update_rollout(&self, track: &str, percent: u8) -> PublishResult<()> {
|
|
if percent > 100 {
|
|
return Err(PublishError::Config(format!(
|
|
"rollout percent {} exceeds 100",
|
|
percent
|
|
)));
|
|
}
|
|
let _ = (track, percent);
|
|
// TODO: PATCH .../tracks/{track} with rollout fraction
|
|
Ok(())
|
|
}
|
|
|
|
/// Full publish flow: create edit → upload bundle → assign to track → commit.
|
|
pub fn publish(&self, aab_path: &str) -> PublishResult<PublishOutcome> {
|
|
let metadata = StoreMetadata::load_from_dir(&self.publish_config.metadata_dir)?;
|
|
let edit_id = self.create_edit()?;
|
|
let version_code = self.upload_bundle(&edit_id, aab_path)?;
|
|
|
|
let track = &self.google_config.track;
|
|
let rollout_fraction = self
|
|
.publish_config
|
|
.rollout
|
|
.as_ref()
|
|
.map(|r| r.initial_percent as f64 / 100.0)
|
|
.unwrap_or(1.0);
|
|
|
|
self.assign_to_track(&edit_id, version_code, track, rollout_fraction)?;
|
|
self.upload_listing(&edit_id, "en-US", &metadata)?;
|
|
let commit_id = self.commit_edit(&edit_id)?;
|
|
|
|
Ok(PublishOutcome::new("google", &self.publish_config, track)
|
|
.with_submission_id(commit_id))
|
|
}
|
|
}
|