- Create a Git repository (not TFVC) in VSTS, possibly with a new Team Project, up to you.
- Create your app in Android Studio and add it to the Git repository.
- Create your Key Store (or import an existing one) with Android Studio.
- In order to be able to sign your APK and deploy it (with any tool, but in this case VSTS), you'll need the following 3 pieces of information:
- The Key Store password
- The Key alias
- The Key password
- Ensure that you've imported the "Manifest Versioning Build Tasks" extension to your VSTS account from the VSTS Marketplace.
- Configure and execute an automated build for your application using the default steps provided by VSTS when creating a new build by applying the Android build template.
- Add to the default build templae a "Manifest Versioning Build Tasks" step to automatically generate your application version from the build.
- In your Google account, do the following:
- Ensure that you've gone to the Google Play Console page and created a Developer Page.
- Once you've created the Service Account below, you'll need to come back here to the Play Console and grant access with "RELEASE MANAGEMENT" permissions, ensuring that you also have the "Release manager" role selected.
- ENSURE THAT YOU'VE COMPLETED ALL THE WARNINGS IN THE NAVIGATION PANE IN THE GOOGLE PLAY CONSOLE, OTHERWISE YOU WON'T BE ABLE TO ROLL-OUT ANY OF YOUR RELEASES.
- Ensure that you've gone to the Google API Console and created a Service Account for publishing your app to the Google Play store.
- NOTE: You'll need to export your key in JSON format so that the email and key fields within the JSON object can be used to configure your Google Play endpoint in VSTS
- Ensure that you've imported the Microsoft "Google Play" extension into your VSTS account from the Marketplace.
- Configure your automated Release in VSTS. Execute the following steps:
- Add an "Android Signing" step to your release to sign one of the *unsigned* APKs from your build.
- Add a "Google Play - Release" step to your release. You'll need the keystore information mentioned above, as well as the keystore *.jks file to upload to VSTS in the "Google Play - Release" step.
- Now that your release is configured, you'll have to to a manual build on your developer (just once) to product a signed APK with the keystore, and then manually upload the signed APK file to the Google Play Console to an Alpha release in order to associate your applicationId (in the ApplicationManifest.xml app manifest file) to your product in the Play Store.
Showing posts with label microsoft. Show all posts
Showing posts with label microsoft. Show all posts
Saturday, January 20, 2018
General workflow for publishing an Android app to the Google Play store when developing with VSTS
Thursday, May 26, 2016
Troubleshooting the dreaded "The build directory of the test run either does not exist or access permission is required." error message in Microsoft Test Manager
Our company is starting to use the Microsoft Test Manager a lot more to manage our testing, both manual and automated. Additionally, we've recently started on creating some new Test Controllers and Test Agents with an exotic network configuration. On one of these new Test Controllers, I've started creating Lab test runs, and been getting the error message "The build directory of the test run either does not exist or access permission is required." When you Google this error message, you get what's described in this post on MSDN. In my case, this was the former problem: the account under which the test controller was running couldn't see the build folder.
After reading that last statement, you might say "well, why didn't you check to make sure that the drop folder was in the place it should have been ?". And, I did. Sort of. Due to our network configuration and aliases, my user could see it on the expected place at the alias in my portion of the network, but the user under which the Test Controller was running (not the tests themselves as configured in the Microsoft Test Manager, but instead the Test Controller software, they're not the same user) couldn't because we have some synchronization going on. Once I logged on to the machine on which the Test Controller service was running ** AS THE USER UNDER WHICH THE TEST CONTROLLER WAS RUNNING ** and went to the network alias myself, I could finally see that the synchronization between the locations on the network that had the same alias wasn't running and the build that I expected to be there was in fact not running.
Problem solved.
After reading that last statement, you might say "well, why didn't you check to make sure that the drop folder was in the place it should have been ?". And, I did. Sort of. Due to our network configuration and aliases, my user could see it on the expected place at the alias in my portion of the network, but the user under which the Test Controller was running (not the tests themselves as configured in the Microsoft Test Manager, but instead the Test Controller software, they're not the same user) couldn't because we have some synchronization going on. Once I logged on to the machine on which the Test Controller service was running ** AS THE USER UNDER WHICH THE TEST CONTROLLER WAS RUNNING ** and went to the network alias myself, I could finally see that the synchronization between the locations on the network that had the same alias wasn't running and the build that I expected to be there was in fact not running.
Problem solved.
Monday, April 27, 2015
A little gotcha with the Microsoft Task Parallel Library (TPL) Dataflow library
I've recently started using the Microsoft TPL Dataflow library in order to help improve the performance of some of our product's scheduled jobs. However, today, I ran into a little gotcha that's pretty important. When you're linking one block to another block, you must always ensure that the source block links to at least one target block that accepts its messages, otherwise it'll most likely deadlock!
Tuesday, April 30, 2013
Creating a logging service using the Microsoft Enterprise Library Logging Application Block
As part of my recent foray into creating various Windows services, I've come across the need for logging (like all serious apps do) and decided to use the Microsoft Enterprise Library Logging Application Block. We used it at a previous company and it got very good reviews from the developers there who used it. Unfortunately, all of the tutorials out there are a bit useless when it comes to doing anything real with the Logging Application Block, like using custom configuration. Fortunately, it was easy enough to figure out how to get customized configuration of logging working just by looking in the assembly and writing some unit tests to experiment.
For my needs, I like to keep all of my configuration as compartmentalized as possible. To that end, I usually end up using .NET Configuration files on a per-assembly basis. Fortunately, this works very well with the Logging Application Block because you can configure logging with arbitrary Configuration files. To get custom logging working easily in Visual Studio, do the following:
- Open Visual Studio (I'm using 2010)
- Install NuGet from the Extension Manager, if you haven't already.
- Install EnterpriseLibrary.Config from the Extension Manager if you haven't already.
- Create your solution and project that requires logging.
- If your project (web or application) comes with a .config file already (i.e. Web.config or App.config respectively) you can use that, otherwise, you can create an app.config file for the assembly in which you're creating your logging service.
- Once you've figured out which app.config (or Web.config) file you're going to be using (i.e. the same assembly where you're placing your logging class, right click on the .config file. You should see an 'Edit configuration file' entry with an orange logo (provided by the add-in installed in Step 3 above).
- Follow any other tutorial out there on the internet for configuring the Logging Application Block. (repeating such information here would be redundant and pointless). There's one such article here.
- Now that you've got your configuration, create a class to be your logging service wrapper.
- Figure out where your application config file is going to end up after your application is built.
- In your logging service wrapper, create a Microsoft.Practices.EnterpriseLibrary.Common.Configuration.FileConfigurationSource, giving the configuration file path as the sole parameter to the constructor.
- Create a new Microsoft.Practices.EnterpriseLibrary.Logging.LogWriterFactory, providing the FileConfigurationSource you just created as the sole parameter. You'll probably want to store this as a static object, because we only need a single factory.
- For each instance of your logging service, use this static factory that you've created to create a LogWriter.
- Implement whatever methods you need to wrap the logging service.
- You're done.
Your code should now look something like the following :
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Text;
using Interfaces;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Support.Extensions;
///
/// A logging services that uses the Microsoft Enterprise Patterns and
/// Practices library to provide logging support.
///
public class MicrosoftPracticesLoggingService : ILoggingService
{
///
/// The log writer factory
///
private static readonly LogWriterFactory LogWriterFactory;
///
/// Initializes the class.
///
static MicrosoftPracticesLoggingService()
{
string configFilePath = typeof(MicrosoftPracticesLoggingService).Assembly.GetCodeBaseFile().FullName + ".config";
if (File.Exists(configFilePath) == false)
{
throw new InvalidOperationException(String.Format("Configuration file could not be found at '{0}'", configFilePath));
}
FileConfigurationSource configSource = new FileConfigurationSource(configFilePath);
LogWriterFactory = new LogWriterFactory(configSource);
}
///
/// The log writer used by this service to write to logs.
///
private readonly LogWriter logWriter;
///
/// Initializes a new instance of the class.
///
public MicrosoftPracticesLoggingService()
{
this.logWriter = LogWriterFactory.Create();
}
#region Implementation of ILoggingService
///
[SuppressMessage("Microsoft.StyleCop.CSharp.DocumentationRules", "SA1604:ElementDocumentationMustHaveSummary", Justification = "InheritDoc")]
[SuppressMessage("Microsoft.StyleCop.CSharp.DocumentationRules", "SA1611:ElementParametersMustBeDocumented", Justification = "InheritDoc")]
public void LogException(Exception ex, string messageFormat, params object[] parameters)
{
if (ex == null)
{
throw new ArgumentNullException("ex");
}
if (messageFormat == null)
{
throw new ArgumentNullException("messageFormat");
}
StringBuilder messageBuilder = new StringBuilder();
messageBuilder.AppendFormat(messageFormat, parameters).AppendLine();
messageBuilder.AppendLine(ex.StackTrace);
if (ex.InnerException != null)
{
Exception root = ex;
while (root.InnerException != null)
{
root = root.InnerException;
}
messageBuilder.AppendLine("Caused by:");
messageBuilder.AppendLine(root.StackTrace);
}
LogEntry logEntry = new LogEntry
{
Message = messageBuilder.ToString(),
Severity = TraceEventType.Error
};
this.logWriter.Write(logEntry);
}
#endregion
}
Friday, October 01, 2010
Event models in Silverlight vs WPF
To really understand the event model in Microsoft's Silverlight / WPF frameworks, you need to start off with a proper mental model. You can think of the root XML element in a XAML object as being at ground level. Each successive child XML element goes deeper into the ground. With that in mind, there's two terms that are used in both of these frameworks to describe how event handlers propagate between objects : Bubbling and Tunneling. With Tunneling, event handlers start at the root XML element, and "tunnel" deeper into the "earth" (your control stack) until they get to the original source of the element, which is your controls. With Bubbling, event handlers start at the original source of the element (your control which initiated the event), and then "bubble up" to the root control. We use the earth analogy because the terminology goes hand in hand with gravity : tunnelling follows gravity, like digging into the earth, and bubbling goes against gravity, like a bubble coming up to the surface from the bottom of the ocean. I never really had a clear mental model of the Silverlight / WPF event models until right now.
With all that said, there are some differences between Silverlight and WPF that turn out to be very important when it comes to implementing your event handlers, and maintaining compatibility between the two. The biggest difference is that WPF supports both Bubbling and Tunneling events, whereas Silverlights supports only Bubbling events. Keep this in mind if you're designing desktop applications that you might want to port over to web applications at some point
With all that said, there are some differences between Silverlight and WPF that turn out to be very important when it comes to implementing your event handlers, and maintaining compatibility between the two. The biggest difference is that WPF supports both Bubbling and Tunneling events, whereas Silverlights supports only Bubbling events. Keep this in mind if you're designing desktop applications that you might want to port over to web applications at some point
Friday, September 17, 2010
Editing your file system mappings for TFS paths
So, as you may or may not know, when using Microsoft Team Foundation Server for version control, TFS maps remote project paths into local file system patmhs for checkout, etc. As I learned today, there are times when you check out the wrong path, and/or map it to the wrong path in the file system. If you ever need to modify or just nuke your file system mappings in TFS, here's how you go about doing it :
Once you've selected your workspace in the dialog that comes up (you'll likely only have one anyway), click on :
... and then select the folder to file system mappings that you want to remove, or create whatever new file system mappings you want right there.
Team Explorer -> Source Control (double click) -> Workspaces (dropdown) -> Workspaces ...
Once you've selected your workspace in the dialog that comes up (you'll likely only have one anyway), click on :
Edit ... -> Working Folders
... and then select the folder to file system mappings that you want to remove, or create whatever new file system mappings you want right there.
Starting a new job ... and a new philosophy
Ok, so I've left my previous employer and started at a new job. This means new domains of knowledge, new tools, and new people. My new employer is a Microsoft-exclusive shop, for almost every aspect of their software. If you've read this blog in any significant amount in the past, you'll know that I'm really not a Microsoft fan. In fact, I hate almost everything that's ever come out of Redmond, because for the most part it's deficient in how it's been engineered, and not as usable as other products out on the market (or even a lot of open source products). Therefore, the tone of this blog is probably going to change somewhat, and I'll be ranting and raving like a lunatic on things I'm learning about dealing with Microsoft products more often. It's going to be interesting.
Wednesday, May 05, 2010
My hatred of Microsoft is justified ... yet again
There are two different schools of thought when it comes to being a vendor of very large software used by millions of people :
I've noticed from my own personal experiences that Apple tends to take the former attitude, whereas Microsoft tends to take the latter attitude. In the end, someone (probably you) is going to get screwed over at some point, it's just a matter of how you want it to happen. As a consumer, I generally like Apple products, so on my personal technology front, I choose the former. As a software developer, I'm forced by business constraints to accept the latter. The specific circumstances that bring me to mention this :
Today I was working with version 4.0 of the .NET framework, the very latest (and supposedly greatest) from Microsoft, along with the very latest version of their Visual Studio (2010) software. I'm also using these with WPF (the Windows Presentation Foundation) to create an application for my employer. For various reasons, I had to go back and refactor some old code, part of which required opening log files for viewing within the application. In order to open a file in WPF, you must use the OpenFileDialog class that comes with the Windows Forms library, which has been around since Windows 2000 (if not earlier, I'm admittedly not as familiar with the lifecycle of this technology as I could be). If you're a developer on the Windows platform, or even just an observant user, you'll have noticed that on the OpenFileDialog there's a Places bar on the left hand side of the dialog that provides common places for storing files, some of which are very general and will require some drilling down into subfolders to find what you actually want. I wanted to be able to add a place to this bar so that users of the application (company employees who work as technicians out on job sites) could have a direct link to the typical directory used to store log files on their machine.
It turns out that adding a folder to the places bar is obscenely difficult, and must be done through registry hacks. My question is this (directed squarely at the developers at Microsoft responsible for writing the GUI controls, specifically these dialogs) : what the hell was going through your head that would make you think that the way you've implemented these dialogs is a good thing ? It's obscenely hard on developers to customize the generalized tools that you've given them, and this in turn makes it hard on users of that software to use the software made by developers bound by these stupid and seemingly arbitrary constraints. I find myself growing increasingly frustrated by stupid decisions of the Microsoft developers that seem obviously poor when you look at them from the perspective of a framework user. These poor decisions are costing me a lot in terms of time I have to spent developing around these decisions and researching alternatives. It's now no wonder to me how other companies can make absurd sums of money off of controls designed as work arounds for the short-sightedness of Microsoft's developers, and frankly, it's quite depressing.
- Move your software forward as often as possible, even if a few customers have to suffer lack of backward compatibility
- Move your software forward as little as possible, even if a few customers have to suffer lack of innovation
I've noticed from my own personal experiences that Apple tends to take the former attitude, whereas Microsoft tends to take the latter attitude. In the end, someone (probably you) is going to get screwed over at some point, it's just a matter of how you want it to happen. As a consumer, I generally like Apple products, so on my personal technology front, I choose the former. As a software developer, I'm forced by business constraints to accept the latter. The specific circumstances that bring me to mention this :
Today I was working with version 4.0 of the .NET framework, the very latest (and supposedly greatest) from Microsoft, along with the very latest version of their Visual Studio (2010) software. I'm also using these with WPF (the Windows Presentation Foundation) to create an application for my employer. For various reasons, I had to go back and refactor some old code, part of which required opening log files for viewing within the application. In order to open a file in WPF, you must use the OpenFileDialog class that comes with the Windows Forms library, which has been around since Windows 2000 (if not earlier, I'm admittedly not as familiar with the lifecycle of this technology as I could be). If you're a developer on the Windows platform, or even just an observant user, you'll have noticed that on the OpenFileDialog there's a Places bar on the left hand side of the dialog that provides common places for storing files, some of which are very general and will require some drilling down into subfolders to find what you actually want. I wanted to be able to add a place to this bar so that users of the application (company employees who work as technicians out on job sites) could have a direct link to the typical directory used to store log files on their machine.
It turns out that adding a folder to the places bar is obscenely difficult, and must be done through registry hacks. My question is this (directed squarely at the developers at Microsoft responsible for writing the GUI controls, specifically these dialogs) : what the hell was going through your head that would make you think that the way you've implemented these dialogs is a good thing ? It's obscenely hard on developers to customize the generalized tools that you've given them, and this in turn makes it hard on users of that software to use the software made by developers bound by these stupid and seemingly arbitrary constraints. I find myself growing increasingly frustrated by stupid decisions of the Microsoft developers that seem obviously poor when you look at them from the perspective of a framework user. These poor decisions are costing me a lot in terms of time I have to spent developing around these decisions and researching alternatives. It's now no wonder to me how other companies can make absurd sums of money off of controls designed as work arounds for the short-sightedness of Microsoft's developers, and frankly, it's quite depressing.
Sunday, April 04, 2010
WTF ?! Windows (as of Vista) no longer supports multiple different monitors!? WHY ????
Apparently, as of Windows Vista and later, Windows no longer supports multiple video cards that don't use the same driver!! Why ? I use a Radeon and a Matrox QID to drive 6 displays on my development box, and this just entirely fucks me over. At best, I can only use four of my displays now, and that's only going to be when Matrox gets off their lazy ass and releases a Windows 7 driver for their QID LP PCIe video cards. I'm so disappointed with what's a complete step backward for Microsoft. Epic fail, Microsoft.
Friday, December 11, 2009
Generating XML objects from a schema in .NET
In my last job, I frequently made use of the JAXB library provided with the Java SDK for object de/serialization. I chose to generate my schemata from objects back then because I started off with the business objects and I knew how I wanted to serialize them to XML. Now I have the reverse situation, and I'm using a new language. As it turns out, generating classes from XML schema is dead easy : use the xsd.exe tool. It comes with .NET.
Monday, May 26, 2008
How to recurlively delete a folder and its contents in PowerShell
The command :
The really sad thing is that I googled this and there are no sites that explicitly state how to do this. The comparable command in bash :
Yet one more reason I hate Microsoft and PowerShell in particular.
Remove-Item -recurse -force [directory name]
The really sad thing is that I googled this and there are no sites that explicitly state how to do this. The comparable command in bash :
rm -rf [directory name]
Yet one more reason I hate Microsoft and PowerShell in particular.
Wednesday, January 30, 2008
Beginning with SQL Server
Given changes in the environment in which our business does it's business, I've had to start learning to use SQL Server and various other Microsoft technologies lately. A quick note on connecting to a foreign SQL Server instance (ie another company's ...) :
- Create an alias for the database so that Enterprise Manager has something to work with
- Open up the Client Network Utility which should be included in the Start menu programs group for your SQL Server installation.
Start -> Programs -> Microsoft SQL Server -> Client Network Utility -> Alias (tab) -> Add... (button).
Under 'Server alias' enter an easy to remember name for the connection. Under 'Network libraries' select the TCP/IP option. Under 'Connection parameters' enter the DNS name or IP address under 'Server name' of the server you wish to connect to. Change the option for 'Dynamically determine port' if the server you're attempting to connect to doesn't run under the standard port of 1433 for SQL Server. Hit 'Ok' to save your settings, then 'Ok' to close out of the Client Network Utility.
- Create a new SQL Server Registration to add your SQL Server instance to the Enterprise Manager
- Open Enterprise Manager. It should be in the same programs group in the start menu as the Client Network Utility. Once open, create a new SQL Server Group if you haven't already got one (or haven't got one that you want to add your new SQL Server instance to). Then add a new SQL Server Registration. You should be prompted by a Wizard at this point. (If you're not, then you've probably already disabled the Wizard and don't need to be reading this tutorial.) In the wizard, click on 'Next' to proceed to the SQL Server selection screen. Under the list of available servers, you should see the alias you just created in the previous step. Select it and click on 'Add >' to add it to the list of added servers, and then click on 'Next'. After this, you should be prompted for credentials, and the rest is pretty self explanatory.
Subscribe to:
Posts (Atom)