promote_release
Move app releases between Google Play Console tracks like internal, alpha, beta, and production. Copy version codes and manage rollout percentages for staged releases.
Instructions
Promote a release from one track to another.
Copies version codes from source to destination. Common: internal→alpha→beta→production. Release notes/name are inherited unless overridden.
Args: package_name: Package name, e.g. com.example.myapp from_track: Source — "internal", "alpha", or "beta". to_track: Destination — "alpha", "beta", or "production". version_codes: Version codes to promote, e.g. [1234]. rollout_percentage: Rollout % at destination. Default 10%. Use 100 for full release. release_name: Optional name override. release_notes: Optional {lang: text} override, e.g. {"en-US": "New features"}.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| package_name | Yes | ||
| from_track | Yes | ||
| to_track | Yes | ||
| version_codes | Yes | ||
| rollout_percentage | No | ||
| release_name | No | ||
| release_notes | No |
Implementation Reference
- src/google_play_mcp/server.py:282-329 (handler)The MCP tool handler for "promote_release", which takes arguments and calls the underlying client's promote_release method.
def promote_release( package_name: str, from_track: str, to_track: str, version_codes: list[int], rollout_percentage: float = 10.0, release_name: str = "", release_notes: Optional[dict] = None, ) -> str: """Promote a release from one track to another. Copies version codes from source to destination. Common: internal→alpha→beta→production. Release notes/name are inherited unless overridden. Args: package_name: Package name, e.g. com.example.myapp from_track: Source — "internal", "alpha", or "beta". to_track: Destination — "alpha", "beta", or "production". version_codes: Version codes to promote, e.g. [1234]. rollout_percentage: Rollout % at destination. Default 10%. Use 100 for full release. release_name: Optional name override. release_notes: Optional {lang: text} override, e.g. {"en-US": "New features"}. """ try: notes = _notes_from_dict(release_notes) result = _publisher().promote_release( package_name=package_name, from_track=from_track, to_track=to_track, version_codes=version_codes, rollout_percentage=rollout_percentage, release_name=release_name or None, release_notes=notes, ) return json.dumps( { "success": True, "message": ( f"Version codes {version_codes} promoted from '{from_track}' " f"to '{to_track}' at {rollout_percentage}% rollout." ), "track": _format_track(result["track"]), "editId": result.get("commit", {}).get("editId"), }, indent=2, ) except Exception as exc: return json.dumps({"success": False, "error": str(exc)}, indent=2) - src/google_play_mcp/client.py:232-286 (handler)The implementation of the promote_release logic, which interacts with the Google Play Developer API to copy a release between tracks.
def promote_release( self, package_name: str, from_track: str, to_track: str, version_codes: List[int], rollout_percentage: float = 10.0, release_name: Optional[str] = None, release_notes: Optional[List[Dict[str, str]]] = None, ) -> Dict[str, Any]: """Copy a release from one track to another. Release notes and name are inherited from the source release unless overridden. rollout_percentage applies when to_track is production. """ if not (0 < rollout_percentage <= 100): raise ValueError("rollout_percentage must be > 0 and <= 100.") edit_id = self._create_edit(package_name) try: src_releases = self._get_track( package_name, edit_id, from_track ).get("releases", []) target_vcs = {str(vc) for vc in version_codes} src = next( ( r for r in src_releases if set(r.get("versionCodes", [])).intersection(target_vcs) ), None, ) notes = release_notes or (src.get("releaseNotes") if src else None) name = release_name or (src.get("name") if src else None) release: Dict[str, Any] = { "versionCodes": [str(vc) for vc in version_codes], "status": "completed" if rollout_percentage >= 100 else "inProgress", } if rollout_percentage < 100: release["userFraction"] = round(rollout_percentage / 100.0, 4) if name: release["name"] = name if notes: release["releaseNotes"] = notes updated_track = self._update_track( package_name, edit_id, to_track, {"track": to_track, "releases": [release]} ) commit = self._commit_edit(package_name, edit_id) return {"track": updated_track, "commit": commit} except Exception: self._delete_edit(package_name, edit_id) raise