{"id":36763,"date":"2018-05-23T15:11:22","date_gmt":"2018-05-23T19:11:22","guid":{"rendered":"https:\/\/blog.xamarin.com\/?p=36763"},"modified":"2018-05-23T15:11:22","modified_gmt":"2018-05-23T19:11:22","slug":"securing-versioning-xamarin-apps-with-mobilebuildtools","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/securing-versioning-xamarin-apps-with-mobilebuildtools\/","title":{"rendered":"Guest Post: Securing and Versioning Xamarin Apps with Mobile.BuildTools"},"content":{"rendered":"<p>\t\t\t\t<em><a href=\"https:\/\/twitter.com\/DanJSiegel\">Dan Siegel<\/a> is a Microsoft MVP, maintainer of the Prism Library, author of numerous dev tools and OSS libraries, leader of the San Diego Xamarin Dev\u2019s Meetup, and a Xamarin blogger. Dan works as a Cross-Platform and Cloud Consultant at AvantiPoint and has a passion for DevOps and automation.<\/em><\/p>\n<h2>Mobile.BuildTools<\/h2>\n<p>Writing mobile apps can be hard work. There is a long list of things to be set up for each project, in addition to the technical challenges that need to be overcome for the sake of security or to configure. The Mobile.BuildTools were born out of a desire to make DevOps easy and consistent to set up from one project to the next. The Build Tools aren\u2019t just another library to install to your project, and they don\u2019t add yet another dll that only adds to your final app size. Instead, they contain several tasks designed to make developing apps easier by training MSBuild to do some common DevOps tasks with some idea of whether you are building your app locally or on a CI Server. It also considers which CI Server you are building on for maximum efficiency.<\/p>\n<h2>Secrets<\/h2>\n<p>Secrets are the very heart of the Build Tools. Nearly every app has some concept of a secret or at least something that should not be checked into source control. It could be your App Secret from AppCenter, your App\u2019s Client Id for an OAuth provider, or perhaps it\u2019s just the URL for the backend API. Regardless of what specifically the variable is for, injecting these variables with configuration files is not something you can do for Mobile like you could with a conventional desktop or web project. Trying to make it easier for other developers to work on the project, build the project in CI, and prevent the accidental check-in of an actual value being used by a developer on your team can be challenging. <\/p>\n<p>Adding secrets to your app is as simple as adding a single JSON file to your project and then adding it to your .gitignore file. Even better is that secrets support string\u2019s, bool\u2019s, int\u2019s and double\u2019s opening up additional options of what you could potentially inject at build.<\/p>\n<p><code>.gitignore<\/code><\/p>\n<pre><code>secrets.json<\/code><\/pre>\n<p><code>Foo.cs<\/code><\/p>\n<pre class=\"lang:cs decode:true\"><code>using AwesomeApp.Helpers;\n\nnamespace AwesomeApp\n{\n    public class Foo\n    {\n        public void DoFoo()\n        {\n            if(Secrets.SomeBool)\n            {\n                Console.WriteLine(Secrets.SomeVar);\n            }\n        }\n    }\n}<\/code><\/pre>\n<p><code>secrets.json<\/code><\/p>\n<pre><code>{\n    \"SomeVar\": \"A Value\",\n    \"SomeBool\": true,\n    \"SomeInt\": 1,\n    \"SomeDouble\": 2.0\n}<\/code><\/pre>\n<h3>Build Server Secrets<\/h3>\n<p>The whole notion of adding a JSON file may sound nifty for local development, it is certainly an easy way to add constant values that you need in your code. At some point though your project won\u2019t be built in your local environment where you can just add a JSON file. Instead, you will need to support it being built as part of a CI build perhaps in VSTS or AppCenter. Working with App Secrets in your projects couldn\u2019t be easier in CI. By adding a variable prefixed with <code>Secret_<\/code>, the name following the prefix will be added to the JSON file, along with the value. Your Secrets class will be automatically generated without a single script as well.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Picture1.png\" alt=\"\" width=\"899\" height=\"479\" class=\"aligncenter size-full wp-image-37035\" \/><\/p>\n<h2>App Manifests<\/h2>\n<p>Sometimes secrets go beyond code, and they are a problem that you need to deal with in an app manifest. A perfect example of this is when using the [AppCenter Distribution SDK], you must update your Info.plist to include a custom URL Scheme that contains your App\u2019s AppCenter secret. <\/p>\n<p><code>Info.plist<\/code><\/p>\n<pre><code>CFBundleURLTypes\n\n    \n        CFBundleURLSchemes\n        \n            appcenter-$$APP_SECRET$$\n        \n    \n<\/code><\/pre>\n<p>(<a href=\"https:\/\/docs.microsoft.com\/en-us\/appcenter\/sdk\/distribute\/xamarin#23-for-ios-only-modify-your-infoplist\">Refer to Microsoft documentation App Center SDK -&gt; Modify your Infoplist<\/a>) <\/p>\n<p>This can be easily overcome by tokenizing your manifests as shown here. Of course, this isn\u2019t always practical to be developing with a tokenized Manifest as it could lead to an exception or you may have tokenized your Bundle Id. As a result, it opens up risks of accidentally checking in a value used during development. The solution is simple, exclude the manifest from source control, then place the tokenized version somewhere in your repo. The Build Tools will use conventions to locate your manifests and replace tokens from environment variables and then copy the missing manifest into your project. Similar to injecting Secrets, you simply need to add the prefix <code>Manifest_<\/code> for the Build Tools to locate the value of the replacement.<\/p>\n<h2>Advanced Tasks &amp; App Versioning<\/h2>\n<p>The Build Tools keep getting smarter. In fact, they are currently able to determine whether you are building on AppCenter, AppVeyor, Jenkins, or VSTS. For those brave enough to write create their own build tasks, you can benefit from this by conditionally executing some logic based on your build environment.<\/p>\n<p>The Build Tools uses this understanding of your environment in a few ways. To start it will assist you by copying your Android APK, and your iOS IPA and dSYM to an Artifacts directory under your Solution root folder. This makes it easy to locate your build artifacts. Copying these artifacts to the same directory doesn\u2019t always make sense though. For that reason, you\u2019ll find that the Build Tools when determines the build environment is VSTS, it will automatically adjust the copy directory to <code>$(Build.ArtifactStagingDirectory)<\/code>, and will disable the unnecessary task altogether on AppCenter.<\/p>\n<p>Building Mobile Apps also means that you need to think about Versioning. The chances are unless you are a Library author, you probably don\u2019t do much versioning. Versioning becomes critical though as you cannot submit version 1.0 to the AppStore multiple times. Automatic versioning though couldn\u2019t be easier than with the Build Tools as you can set it up to version every single build, only local builds, or only builds on a CI Server. You can also choose between using the timestamp or you can prefer to use the build number. In order to enable Automatic Versioning, you simply need to add a property to your project with the version format you prefer. By default, every build will then get a version number. <\/p>\n<table>\n<tr>\n<td><code>AutomaticVersionOffset<\/code><\/td>\n<td><code>0<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>AutomaticVersionEnvironment<\/code><\/td>\n<td><code>All<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>AutomaticVersionBehavior<\/code><\/td>\n<td><code>PreferBuildNumber<\/code> or <code>Timestamp<\/code><\/td>\n<\/tr>\n<\/table>\n<p><code>gistfile1.txt<\/code><\/p>\n<pre><code>\n\n\n  \n    Debug\n    iPhoneSimulator\n    8.0.30703\n    2.0\n    {9F0236FA-9A36-40CB-924F-4CA379E05CE1}\n    {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\n    Exe\n    Contoso.iOS\n    Resources\n    Contoso.iOS\n    \n    PreferBuildNumber\n  \n  \n <\/code><\/pre>\n<h2>SCSS for Xamarin Forms<\/h2>\n<p>CSS is undoubtedly one of the most powerful changes made to styling for XAML. While this is an exciting new enhancement to Xamarin.Forms, it also can quickly become hard to maintain on larger projects. The Build Tools provides an easy solution with bundled support for LibSass with SCSS stylesheets. Since LibSass is bundled there is no requirement that your machine needs Node or the Sass cli, it simply works by building your project. By using SCSS you get support for variables, functions and partial stylesheets making it easier to generate consistent styles in a manageable fashion. <\/p>\n<p>The Xamarin.Forms CSS spec allows you to generate styles that apply to all elements of a given type as well as derived types by prefacing the type with ^. This isn\u2019t actually valid CSS, and as a result, the LibSass compiler will not compile this. By updating your style as shown below to use either the \u2018any\u2019 or \u2018all\u2019 selector, you are able to write valid CSS and as a result, LibSass is able to compile to CSS. The Build Tools are then able to post-process the CSS to match the Xamarin.Forms spec. <\/p>\n<h2>Wrapping Up<\/h2>\n<p>It\u2019s easy to get started with the Mobile.BuildTools. <a href=\"https:\/\/github.com\/dansiegel\/AppCenter.DemoApp\">Head to GitHub<\/a> to see a fully working demo built on AppCenter without a single build script. <a href=\"https:\/\/github.com\/dansiegel\/Mobile.BuildTools\">Check out the project ReadMe<\/a> for more information on to set up custom configurations.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dan Siegel is a Microsoft MVP, maintainer of the Prism Library, author of numerous dev tools and OSS libraries, leader of the San Diego Xamarin Dev\u2019s Meetup, and a Xamarin blogger. Dan works as a Cross-Platform and Cloud Consultant at AvantiPoint and has a passion for DevOps and automation. Mobile.BuildTools Writing mobile apps can be [&hellip;]<\/p>\n","protected":false},"author":1964,"featured_media":39167,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[4],"class_list":["post-36763","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-xamarin-platform"],"acf":[],"blog_post_summary":"<p>Dan Siegel is a Microsoft MVP, maintainer of the Prism Library, author of numerous dev tools and OSS libraries, leader of the San Diego Xamarin Dev\u2019s Meetup, and a Xamarin blogger. Dan works as a Cross-Platform and Cloud Consultant at AvantiPoint and has a passion for DevOps and automation. Mobile.BuildTools Writing mobile apps can be [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/36763","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/1964"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=36763"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/36763\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media\/39167"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=36763"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=36763"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=36763"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}