-
-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a Tool to connect to Google Play #5
Labels
enhancement
New feature or request
Comments
As discussed here is a basic implementation I have been using: ReleaseMetadata.cs public class ReleaseMetadata
{
public string BundleFilePath { get; }
public string PackageName { get; }
public string ReleaseNotesFilePath { get; }
public string SecretsFilePath { get; }
public string TrackName { get; }
public string Version { get; }
public long VersionCode { get; }
public ReleaseMetadata(
string bundleFilePath,
string packageName,
string releaseNotesFilePath,
string trackName,
string version,
long versionCode,
string secretsFilePath)
{
this.BundleFilePath = bundleFilePath;
this.PackageName = packageName;
this.ReleaseNotesFilePath = releaseNotesFilePath;
this.TrackName = trackName;
this.Version = version;
this.VersionCode = versionCode;
this.SecretsFilePath = secretsFilePath;
}
} Upload method private static async Task Run(ReleaseMetadata releaseMetadata)
{
var credential = GoogleCredential
.FromFile(releaseMetadata.SecretsFilePath)
.CreateScoped(AndroidPublisherService.Scope.Androidpublisher);
var service = new AndroidPublisherService(new BaseClientService.Initializer
{
ApplicationName = "App Uploader",
HttpClientInitializer = credential
});
var appEdit = new AppEdit();
// Request an insert.
await Console.Out.WriteLineAsync("Creating Edits.Insert");
var insertRequest =
await service.Edits.Insert(appEdit, releaseMetadata.PackageName).ExecuteAsync();
var editId = insertRequest.Id;
// Upload the bundle
await using var fileStream = new FileStream(releaseMetadata.BundleFilePath, FileMode.Open, FileAccess.Read);
await Console.Out.WriteLineAsync("Uploading bundle file");
var uploadResult = await service.Edits.Bundles.Upload(releaseMetadata.PackageName, editId, fileStream, "").UploadAsync();
if (uploadResult.Status != UploadStatus.Completed)
{
await Console.Error.WriteLineAsync($"ERROR: Upload status '{uploadResult.Status}' with exception '{uploadResult.Exception}'");
return;
}
// Set up the next release.
await Console.Out.WriteLineAsync("Creating new Track release");
var currentTrack = await service.Edits.Tracks.Get(releaseMetadata.PackageName, editId, releaseMetadata.TrackName).ExecuteAsync();
var versionCodes = new List<long?> { releaseMetadata.VersionCode };
await using var releaseNotesStream = new FileStream(releaseMetadata.ReleaseNotesFilePath, FileMode.Open, FileAccess.Read);
using var streamReader = new StreamReader(releaseNotesStream);
var releaseNotes = await streamReader.ReadToEndAsync();
if (releaseNotes.Length > 500)
{
await Console.Out.WriteLineAsync("WARNING: truncated the release notes");
// Yuck!!
releaseNotes = releaseNotes.Substring(0, 500);
}
// Currently relies on having manually released initially
var newReleaseTrack = new TrackRelease
{
CountryTargeting = currentTrack.Releases.First().CountryTargeting,
Name = $"{releaseMetadata.VersionCode}({releaseMetadata.Version})",
VersionCodes = versionCodes,
ReleaseNotes = new List<LocalizedText> { new LocalizedText { Language = "en-GB", Text = releaseNotes } },
Status = "completed"
};
currentTrack.Releases.Clear();
currentTrack.Releases.Add(newReleaseTrack);
await Console.Out.WriteLineAsync($"Updating track '{releaseMetadata.TrackName}'");
await service.Edits.Tracks.Update(currentTrack, releaseMetadata.PackageName, editId, releaseMetadata.TrackName).ExecuteAsync();
// Job done
await Console.Out.WriteLineAsync("Committing release");
await service.Edits.Commit(releaseMetadata.PackageName, editId).ExecuteAsync();
}
} Usage private async static Task Main(string[] args)
{
var assembly = Assembly.GetExecutingAssembly();
var fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
Console.Error.WriteLine($"Running Google.Play.Uploader {fvi.ProductVersion}");
// TODO: Better argument parsing
var bundleFilePath = args[0];
var packageName = args[1];
var trackName = args[2];
var releaseNotesFilePath = args[3];
var version = args[4];
var versionCode = long.Parse(args[5]);
var secretsFilePath = args[6];
Console.Error.WriteLine($"Uploading Android bundle: '{bundleFilePath}' for package name: '{packageName}' to Google Play");
var releaseMetadata = new ReleaseMetadata(
bundleFilePath,
packageName,
releaseNotesFilePath,
trackName,
version,
versionCode,
secretsFilePath);
try
{
await Run(releaseMetadata);
}
catch (Exception ex)
{
Console.Error.WriteLine("ERROR: " + ex.Message);
// Make sure TeamCity observes the failure.
Environment.Exit(-1);
}
} This doesn't take care of handling localised release notes. |
I'm also very happy to add the implementation but thought I'd show something |
Yeah looks like a good start. If localization (see what I did there) is a big deal someone can PR it... but should be easy enough to adapt something like: public interface IHazGooglePlayDeployment : IHazArtifacts
{
[Parameter("Defines the Google Play Track to deploy to")]
GooglePlayTrack GooglePlayTrack => TryGetValue(() => GooglePlayTrack) ?? GooglePlayTrack.Internal;
[Parameter("Secrets file to connect to Google Play"), Secret]
string GooglePlaySecrets => TryGetValue(() => GooglePlaySecrets);
Target GooglePlayDeploy => _ => _
.Requires(() => GooglePlaySecrets)
.Executes(async () =>
{
var aab = ArtifactsDirectory.GlobFiles("**/*-Signed.aab").FirstOrDefault();
aab.NotNull().FileExists();
// Pull the aab apart for the AndroidManifest and read the Manifest for the Version/Version Code
// Do release
});
}
public class GooglePlayTrack : Enumeration
{
public static GooglePlayTrack Internal = new() { Value = nameof(Internal) };
public static GooglePlayTrack Alpha = new() { Value = nameof(Alpha) };
public static GooglePlayTrack Beta = new() { Value = nameof(Beta) };
public static GooglePlayTrack Production = new() { Value = nameof(Production) };
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Description
Add a tool to make it easy to connect to Google Play to deploy generated Android App Bundles.
The text was updated successfully, but these errors were encountered: