c# - How can i automate symbol uploads to Xamarin.Insights or Microsoft Mobile Center for ios with Xamarin Projects? -
i figured else day ask question too, i'll go ahead , share solution, else has less work digging through mobile centers web api process working.
this how add build task csproj file of project:
<usingtask taskname="uploadsymbolstask" assemblyfile="fullpathtodll\buildtasks.dll" /> <target name="providediagnosticssymbols" aftertargets="copydsymfrommac"> <uploadsymbolstask dsymfolder="$(targetdir)nameofiosapp.app.dsym" insightsapikey="yourinsightskey" mobilecenterapikey="yourmobilecenterkey" mobilecenteruser="user" mobilecenterapplicationname="appname" /> </target> this build task need create:
using system; using system.collections.generic; using system.io; using system.io.compression; using system.linq; using system.net; using system.net.http; using system.text; using system.threading; using microsoft.build.framework; using microsoft.build.utilities; using newtonsoft.json; namespace buildtasks { public class uploadsymbolstask : task { [required] public string dsymfolder { get; set; } [required] public string insightsapikey { get; set; } [required] public string mobilecenterapikey { get; set; } [required] public string mobilecenterapplicationname { get; set; } [required] public string mobilecenteruser { get; set; } public override bool execute() { writelogmessage($"executing {nameof(uploadsymbolstask)}."); if (string.isnullorempty(insightsapikey)) { writelogmessage($"{nameof(insightsapikey)} can not empty."); return false; } if (string.isnullorempty(dsymfolder)) { writelogmessage($"{nameof(dsymfolder)} can not empty."); return false; } if (!directory.exists(dsymfolder)) { writelogmessage($"{nameof(dsymfolder)} not exist."); return false; } try { // curl -f "dsym=@yourappdsym.zip;type=application/zip" https://xaapi.xamarin.com/api/dsym?apikey=[yourapikey] var tmpfilename = path.gettempfilename(); // we're forcing temporary file name - gettempfile creates well, createfromdirectory crashes if exists. file.delete(tmpfilename); zipfile.createfromdirectory(dsymfolder, tmpfilename, compressionlevel.fastest, false); writelogmessage($" created tmp zipfile upload symbols @ \"{tmpfilename}\"."); executexamarininsightsupload(tmpfilename); var awaiter = system.threading.tasks.task.run(() => executemobilecenteruploadasync(tmpfilename)).getawaiter(); awaiter.getresult(); return true; } catch (exception e) { writelogmessage($"error occured: {e.tostring()}"); return false; } } private async system.threading.tasks.task executemobilecenteruploadasync(string filename) { writelogmessage(" uploading file mobile center api ..."); // https://docs.mobile.azure.com/api/#/crash // https://mobile.azure.com/users/user/apps/appname/crashes/symbols using (var client = new httpclient()) { client.defaultrequestheaders.tryaddwithoutvalidation("x-api-token", $"{mobilecenterapikey}"); writelogmessage(" retrieving upload id , destination ..."); var clientcallback = guid.newguid().tostring(); var postcontent = new stringcontent($"{{ \"symbol_type\" : \"apple\", \"client_callback\" : \"{clientcallback}\"}}", encoding.utf8, "application/json"); var cancellationtoken = new cancellationtokensource(timespan.fromminutes(5)).token; var symboluploadiniturl = $"https://api.mobile.azure.com/v0.1/apps/{mobilecenteruser}/{mobilecenterapplicationname}/symbol_uploads"; writelogmessage($" initializing symbol upload using {symboluploadiniturl} ..."); var uploadrequest = await client.postasync( symboluploadiniturl, postcontent, cancellationtoken); var symboluploadinitializeresult = jsonconvert.deserializeobject<mobilecenterstartsymboluploadresponse>(await uploadrequest.content.readasstringasync()); writelogmessage($" uploading symbol {symboluploadinitializeresult.symbol_upload_id} {symboluploadinitializeresult.upload_url} ..."); writelogmessage(" uploading file ..."); using (var filestream = new filestream(filename, filemode.open, fileaccess.read)) { using (var streamcontent = new streamcontent(filestream)) { client.defaultrequestheaders.tryaddwithoutvalidation("x-ms-blob-type", "blockblob"); var uploadresult = await client.putasync(symboluploadinitializeresult.upload_url, streamcontent); writelogmessage($" response: {uploadresult.statuscode}"); client.defaultrequestheaders.remove("x-ms-blob-type"); } } var symbolcommiturl = $"https://api.mobile.azure.com/v0.1/apps/{mobilecenteruser}/{mobilecenterapplicationname}/symbol_uploads/{symboluploadinitializeresult.symbol_upload_id}"; writelogmessage($" commiting upload using {symbolcommiturl} ..."); var commitrequestmessage = new httprequestmessage( new httpmethod("patch"), symbolcommiturl); commitrequestmessage.content = new stringcontent("{ \"status\" : \"committed\" }", encoding.utf8, "application/json"); using (var commitresponse = await client.sendasync( commitrequestmessage, new cancellationtokensource(timespan.fromminutes(5)).token)) { var responsecontent = await commitresponse.content.readasstringasync(); var commitresponsedeserialized = jsonconvert.deserializeobject<mobilecentersymboluploadresultresponse>(responsecontent); writelogmessage($" response: {commitresponsedeserialized.status}"); } writelogmessage(" done."); } } private void executexamarininsightsupload(string tmpfilename) { using (var client = new webclient()) { client.headers.add(httprequestheader.contenttype, "application/zip"); ; writelogmessage(" uploading file xamarin.insights api ..."); var response = client.uploadfile(new uri($"https://xaapi.xamarin.com/api/dsym?apikey={insightsapikey}", urikind.absolute), tmpfilename); writelogmessage($" response: {encoding.ascii.getstring(response)}"); writelogmessage(" done."); } } private void writelogmessage(string message) { log.logmessage(messageimportance.high, $"{datetime.now.tostring("t")} {message}"); } } public class mobilecenterstartsymboluploadresponse { public string symbol_upload_id { get; set; } public string upload_url { get; set; } public datetime expiration_date { get; set; } } public class mobilecentersymboluploadresultresponse { public string symbol_upload_id { get; set; } public string app_id { get; set; } public string status { get; set; } public string symbol_type { get; set; } public symbol[] symbols { get; set; } public string origin { get; set; } } public class symbol { public string symbol_id { get; set; } public string type { get; set; } public string app_id { get; set; } public string platform { get; set; } public string url { get; set; } public string origin { get; set; } public string[] alternate_symbol_ids { get; set; } public string status { get; set; } } }
Comments
Post a Comment