 Hey everyone, welcome to another episode of Visual Studio Toolbox. I'm Donovan Brown here with my good friend James Montemagno. He's going to tell us about his newfound love for Visual Studio Team Services. Now James, you got to tell me, so what changed your mind? What was it? I don't know. Sometimes when you're stuck, you know when you go on a plane trip with someone that you just met for the first time, you're like, yeah, let's just go take a random trip, maybe down to South America for two weeks. It's a common occurrence. Yes. When you do that and that person happens to be the principal PM, and then now principal Cloud Developer Advocate for all of DevOps at Microsoft, you soak in a lot of knowledge. Nice. Now over the last few years of doing mobile development, I've fallen in love with just a DevOps type pipeline for mobile applications. The first time I did it, it blew my mind. Like I just pushed code, it built, and I always thought of it more of automating things. Then I learned it's not just automating things, it's adding this value to not only developer, but also to the product and to our end users. Absolutely. So what's interesting is when I was on the road show with you, going around talking to developers, talking to customers, and starting to use VSTS more, I just realized how powerful it was and I could literally do anything. While I'm not a command line person, I can definitely run Bash scripts, PowerShell scripts, and then I realized I can use it only for my mobile apps, I can use it for the full pipeline to deploy, which actually then blew my mind. Like where I just have it, I build it, I have an app, and now I can do anything with it. I can put it on the App Store, I can put it in Test Flight, I can put it on App Center, I can distribute it anywhere. So not only was it going on the road with you that I learned a lot, but I just started using it. The more I use it, the more I was like, yes, yes, yes. Then I ran into these things, I wish I could do this. Donovan, a very smart man, told me, hey, if you can do it at the command line, you can do it in VSTS. Exactly. I said, that's great, but I want a task, I want something pretty. I started learning, so then I learned naturally the next step, which was how do you extend Visual Studio Team Services. So that's my passion and now it's taking it to another level. Yeah, I did the same thing. I remember when I wrote for my first task, because I'm all about the pretty drag and drop task. But I don't want 15, run this PowerShell, run this PowerShell. To me, it's just like, I want to see exactly what you're doing. I want that task to just be able to put in a few parameters or maybe none at all, and you just do what you're designed to do. So extensions are just so freaking powerful. What I love about them is that every time I go and look for an extension, there's more than there were the last time, because more and more people are realizing, if you know Node.js or you know PowerShell, you can write one of these things. It's really, really simple. So it sounds like you've written some of them to solve some problems or challenges that you found when you were moving your pipeline to VSTS. Yeah. So specifically what I did is I wanted, I'm a mobile guy obviously, like I love doing Xamarin development, iOS, Android, Windows, and what I kind of figured out is well, VSTS has tons of great built-in tasks to build, sign, and deploy your app. There was other parts missing that usually people think of as the command line, which is replacing and updating the version number, the one that's a required, one that's updated every single time, but also the human readable. And when you do serious production applications, you're doing other things like replacing the package identifier. So maybe you have a development certificate with a production certificate, but the IDs are different or you want to display a different name. And these are things that I thought were super essential that there had to be a task. But I had the shell scripts, I'd already done this. Like I literally did it at the command line, and inside my VSTS I would see command line, command line, command line, command line. I was like, that's ugly. Like it works, but it doesn't make me all warm and fuzzy. Exactly. Right? It doesn't make me feel good. And then it doesn't make other people feel good because they can't do it, they gotta go learn. So in the form of open source, I crowdsourced this initiative to say, hey, I have all these scripts to do iOS and Android specific version bumping, app identifier replacing and a bunch of really cool things. Let's jam on this and make them a VSTS tasks. Awesome. So not only myself, but Andrew, this really awesome guy from the community came together. We not only converted my bash scripts to PowerShell core scripts that they could run everywhere, even if you want to run it like locally. Yeah. But then we convert them to TypeScript. Nice. So that now they're across platform VSTS tasks that's public that anyone can use, not only Xamarin developers, but iOS, Android, native developers, any app because it's just looking at a file and then updating things. And it sounds like they're very opinionated towards mobile that makes them easier to use because it could be Xamarin, it could be iOS, it could be native, but it's like, I know what that file's name is, I know what the format is. So I'm even easier to use because I know exactly what I'm designed to do, which makes it really good. There are some general purpose tasks for versioning, but you need regular expressions. It doesn't really, it doesn't makes no assumptions of the file shape or anatomy. So therefore they're a little bit harder to configure because you have to then teach it what to do. And it sounds like yours are more like, no, these are purpose built for mobile. They're really, really easy to use. Yeah, they really are. And that was my idea and dream of it because I know how Android works. I know how iOS works. And actually on each platform, there's helpers. Like Apple actually gives a P list buddy type application that ships on Mac OS to install Xcode. So I can leverage existing official tooling to essentially run these commands. So that way, if something changes in the next version, I don't have to update my task. It's calling the official tooling. Gotcha. So it knows exactly what to do and the same thing on Android. I know what an Android manifest looks like. Where in the past, I have to like put special characters and tokens that be swapped out. To me, it didn't feel super clean in the mobile landscape. I understand. It felt great in the.net ecosystem and I still use them. But for me, I was like, I want to type in Android into my tasks and find my Android tasks. I understand. So that's why we really optimize them. And then that way, if those platforms evolve, we can add platform specific features too. I think that's what's really neat is as Android or iOS grow, I might want to add new specific tasks just for that that doesn't have anything to do with versioning or numbers at all. Yeah, because if you look at Visual Studio Team Services from build and release, it's also not very opinionated. It's like, give me your task and I will run them. Your task can do whatever they want and they can do them on any platform. I'm going to look right at the screen. Any language, any platform. You've heard me say this over and over again and people still don't believe me, which is why I only do Java demos now. I'm like, I can do this for any language in any platform and we can also do it for mobile. Just give us the task and we'll run it. I'm also very much like you. I know I can do it from the command line and I can have all these Bash or PowerShell scripts, but it seems intimidating almost when you see that build definition. You want to see those, I personally want to see those really nice, specific tasks with a nice cool logo that lets me feel warm and fuzzy, that that's for Android or that's for iOS. And it helps also when you onboard someone new because they can see, they know exactly what it looks like. That Android icon looks like an Android icon and it has the name, it has little hint bubbles. That's why I built them. Cool, so show us how it works. Yes, exactly. So I'm here inside of Visual Studio Team Services and this is my Xamarin show app. It's just an Android and iOS app. So it actually just here inside of Team Explorer, inside my solution explorer. So I push all my code, just Android, iOS and a UI test project. So I haven't added anything to it. So this may look like your existing ones because you don't have my new tasks to build and restore my Android app. Here I sign and align it. I install my Apple certificates from our library which are right over here. So I upload everything to our secure storage which is super cool. It is. And then I build my iOS app. I copy some files and then I have another phase which is running on Windows because it doesn't care over here. That's gonna build up my UI tests and then copy those so I can then test them before deploying anywhere. Right, I wanna double click on this real quick. What you just described was we're at this little border here is this is a completely separate phase that is running on a completely different agent. Can you drop down this agent queue for me over here? Yeah, right here. And what's so powerful here is that now inside of Visual Studio Team Services we actually offer you every platform as a cloud hosted build. You can do Windows, you can do Mac and you can do Linux all from one. It's just incredible. So you don't have to worry about how do I go set up my build machine for Mac? How do I go set up my build machine for Linux? How do I go set up my build machine for Windows? They're there. And you can have a phase because this phase is very specific to running on Mac and your process defaults to Mac and then you were able to override that in the second phase saying, nope, this phase can run on Windows. So let's just go ahead and utilize that instead. Exactly, yeah. That was my plan of it is since iOS apps have to be built on a Mac hardware, just boom, leverage the host to Mac. So now what I wanna do is I want to extend this and I want to bump the version number and update the package information for iOS and Android. So that's where the extensions come in. So over here I could browse the marketplace. So I have that open over here. So this is the marketplace. And like you said, we could just search for version. I figure we just go from scratch, installing and everything. So we can see there's tons of version stuff, version, version, version, you are correct. And then you'll see this one, which is mobile app tasks for Android and iOS. And these are those specific tasks that I built. So there's four tasks, two for Android, two for iOS. They do the same thing, but they're specific to the platform because they're running platform code and then different icons. So yeah, it makes it easier to distinguish. Yeah, and also the inputs are a little bit different because they're different things. So here I can say get it for free and we're gonna go ahead and install this into my Visual Studio Team Services account. So everyone will have access to this over there. And also that download button is for anyone who's using Team Foundation Server on-prem, you do not have to be using VSTS to use a lot of these great extensions. You just click on download, you're gonna get a file that you can then import into your Team Foundation Server on-premise and still use the same extensions that we were using for VSTS as well. So now I can come over here and I don't know if I have to refresh, let's see, totally have to refresh. I'm gonna refresh my list here. Exactly. I was like, maybe. So what I wanna do is I click on my phase one because I wanna essentially update and replace the version numbers and the identifiers for both iOS and Android. So it's the very first thing I wanna do. Before I do anything, I don't need anything else to run because if those fail, something else is wrong. You get the source, let's modify the versions and let's then go forward. And now look if I type in Android. We get these nice, pretty Android manifest package name and Android manifest version numbers tasks. And the same thing here, if I go for iOS, we have iOS build version numbers and bundle identifiers. So we're just gonna add both of these. Let me go ahead and drag and drop these up here. Let's do that there. There we go. Let me go ahead and do iOS again. So it was version numbers, identifiers. We'll do the same for Android. There. Up, up, up, up. Cool. So we'll need some information because things are required. So over here it says I need your iOS info P list. See, it's very specific. So I'm gonna go and browse in this code specifically for the info P list, boom. And I wanna go ahead and zoom in over here so you can kinda see what's going on. Is I realized that people may be, this happened to me, this is why this feature is here. We'll know that there's a version code, a version name. Version code is what is specific that has to be incremented every single time. Every single time. So what I do is I default to the build ID. I just say, VSTS gives me a build ID that is unique with every single build. So let's leverage that. Now you may be wondering, what is this version code offset? It's a good question. I am very wondering that very much. So sometimes you may have been building this manually before even putting in CI. Or you may be bringing in from another CI system. So if build ID is one, you're not just gonna go query up 100 builds. We can then make this 100. And it will automatically add 100 to the build ID. Yes. Yes, you've been burned by that. And what you're seeing there with the dollar sign open print and close print is the syntax that we use in VSTS to be able to replace variables. And those variables, anything that has like a build dot is something that's generated automatically for us. And we're just saying, hey, I know there's gonna be something called a build ID. Give that to me and use that value here in its place, which is great. Yeah, now I default to this 1.0 build ID. So you have a unique identifier for the version shortcode. But I'm actually gonna use a different built in one here, which is the build number. Yes. Now the build number actually comes from the options. And there's a few ways of doing that. But my default here is actually what I just showed you, which is 1.0.build ID. So that way I can just make them the same. I don't have to hard code that. And then this way what's nice is if I wanna do version two, I come into one place and it will automatically update. So I have to go into every single task that was my mind there. So there's a few ways of doing that. And you and I have discussed that before. So let's go ahead and change a few other things. I'm gonna go ahead and copy a few things over here. So this is gonna be the same exact info P list. But now I can replace the bundle identifier, which is what you upload to the store. And that has to match the provisioning profile. Okay. So I'm gonna say com.refractored.zamarin show. Cause that's what's in my actual provisioning profile. Okay. And then you can optionally, I try to bundle the functionality together. Cause over here you could optionally do the version name. Or if you left it blank it wouldn't touch it. Okay. So over here, if you wanna update the bundle name, which is what the name of your app is, you can then come in here and say Xamarin show and it'll replace that, but not required. Okay. And then we're gonna do the same thing over here for Android. So it's very, very similar, but I'm going to go into my Android project. And what I like what you're doing here is you're actually browsing your actual source console. So I don't have to rememberize or know how to type in the actual path. I can simply just go and visually grab the file that I want to manipulate. Exactly. So I'm gonna come over here, do 100 as my offset just so we're synced up and I'll just go ahead and copy and paste this over here. Okay. But notice that it's exactly the same. So you have a version code offset, a version name, and I have nice little things. It says, hey, you can leave this blank. It'll use your version name, which is the token in the Android manifest. And I try to be really descriptive of what is this gonna do? Right, and I like to give the flexibility where if I really wanna manage that from code in my repository, I could do that by manipulating that XML file versus me actually having to come to my build or my release to change those values. Exactly. Got it. Yeah. So now we can come back over here. I'm gonna do the same thing, com.refractored.zamarin.show, and I'll say Xamarin.show. Now in each of them I have an optional here, which is print file. I like this for debugging purposes and essentially it'll print the file before and after. So that way you can see what actually happened. So if you don't trust me, you can see exactly what's gonna happen. I'm gonna refractored. There we go. So this way you know exactly what's happening. And since all my builds are private, it's fine, there's nothing really personal in there, but you can turn that off and it won't print the file ahead or after. So up to you, and that's literally, it will print off before and after. Gotcha. And that's it. I mean, it's super straightforward to the point and you know exactly what's gonna happen. It's gonna bump the version numbers, change the identifiers, bump the versions, change the package name. And now we can build in queue on our hosted Mac here. And do me a favor, scroll down to the bottom here for a second on this one. Just wanted to make sure you didn't actually, perfect. Yeah, I thought you might have added two at the bottom, but you did perfect. So everything is gonna work great. Yeah, so what's important here too is why I'm doing it first is remember, I am now modifying the source code after it's synced down. So I'm not like checking code in or anything like that. And that's important because for as a developer, I don't wanna have to change, like ideally these files should very rarely change in source code, but I want this to happen every time. And if you actually had to commit them back after every build, I'd have to do a pool as a developer, which would be annoying, right? And what's really nice is using something like the build ID, which is guaranteed to be unique. I no longer have to manipulate those. I do the same thing when I do NuGet packages or NPM packages. It's really nice to be able to use the variables from VSTS to up my versions and never have to do it manually, which is great. Exactly, and that really is the key, is exactly what you just said, which is I really never, ever, ever want to check in code just to bump a version number. Like that's just kind of, to me, feels not again, warm and fuzzy. Yeah, some people like that, and you've given them the flexibility by letting them leave things blank. And again, it's like find out what feels good for you. And I've used a funny combination where you can bump the version, but it's still guaranteed to be unique because I read what's in your file and then I add onto it the build ID and then I set that to be your build number. There you go. There's so much flexibility of what you can do to make it fit you like a glove. And that's why you, you just tell me what you want it to be, right? Exactly. You tell me and I'll do it. That's awesome. So now we can actually look at these. So if I tap on the bump version number here, we can go through the specifics. So this is iOS. So we can see beforehand, the display name was XamarinShow.iOS. The version numbers are all 1.0. If I scroll down, we'll see some debug output where I read in what the numbers were, what the build version offsets were here. And this one here is going to replace the final output here, which is now right here. So that was the before. Here's me actually executing. You can see the commands. So I do a lot of debugging here of the new 104.75, which is the short version code and 5.75, which the user never sees. So that's there. If I come over to the identifier, we're going to see that, hey, look at this. This is the second one. So now it's actually updated because it's not 1.0. It's the new file, it's the same file. And then if I scroll down even further, we'll see that way down inside of our, where is it at? It's going to change that. Identifier right here. Yeah, so there's our new identifier. That's being there, refractor.com. So that way it actually builds and signs. Same thing over here on Android, guess what? We'll see a different output. We have our old version code, new version codes. And then down here, the manifest is very small. So if I actually scroll over, we can see that the old package name was the Xamarin show. Here's our new version codes that we just set. And then we're going to change the package down in the next tab. Exactly. Got it. So I scroll back over, look at the package name, scroll all the way down and over. We're going to see that, boom, our package names are all gravy. Our version codes are the same. The same as the previous one. Now every single time that we push any code, our versions will be unique. The, our QA department can see that version number. Exactly. We can assign it back because guess what? The build number is 1.0475. Which matches what you do. Which matches. See what I did there? Exactly. Exactly. So I like to do that. So it's right there and ready to go. And it's all synchronized up. This is fantastic. Man I'm glad to see that it only took me two weeks of traveling with you to get you to see the magic of business team services. Which is actually a shorter time. I've been doing this for years. And still people don't see it. So it's glad to see that it rubbed off and you're starting to see the power of what this platform can do. And I think of it more of a platform than anything else. Because the sky is the limit. If you can dream it, you can build it, you can run it, and you can do it inside of VSTS. And it wasn't hard. In fact, the last thing I wanted to show you is that it's all open source. So this entire task, I've been taking issues and comments back from people. So all of the source code is inside of my GitHub page of VSTS mobile tasks. Awesome, a blog post associated with this too. So I'll give you the links for the show notes below. Perfect. But what's really cool is this is not only a great extension that people can contribute to, but it's a great reference extension. Perfect. Because the hardest part for me getting started was I can read the documentation and see how to build one. But what happens when I want to package four different tasks up into a single package? So what we have here, and everything is built inside of VS Code. So I use TypeScript, so I have the TypeScript compiler, and I'm about to do a blog on how I built these too, because I fell, I wouldn't say I fell in love with TypeScript and JavaScript, because I'm a C Sharp developer, but it actually helped a lot. I'm so glad I didn't have to write tons of JavaScript. So I did slightly fall in love with TypeScript. That's another show. But I do love me some VS Code. So over here what you're going to see when you come into here is we have these tasks. So each of them have their own folder. You can look specifically at my VS extension JSON. You can see how I structured these with my targets. And what I love under these tasks is that when you come in, you can see the icon, the tasks name, and you can see the PowerShell, Bash, and TypeScript version. Right, now what I want to be real clear here is that when you're writing an extension, you do not have to write it three times. Like you've done them a favor. No, actually it's kind of neat because you now give them an example of how they can write it in any of these different languages and utilize it. But for those who are watching who are interested in writing their own tasks, don't think, oh my God, I have to write this three times. If you only wrote it using TypeScript, and you don't even have to use TypeScript, if you prefer just writing it in pure JavaScript, you can, you only have to write it once and it will run on all three platforms. So I love the fact that you've shown me how to do it in all three languages, but I don't want people to think that they have to write it in all three languages. That's true. And this will show you how we bring in some libraries in here. And the reason I do this is because in my old form, I had PowerShell and BashScript. So I said, well, why throw those away? Let's just show people if that's, if they're running it locally or want to do something, it's there for them. Right, you just leverage what you've already invested in, which is fantastic. Exactly. So this is really great because I really love that you can just come, browse the code, and in fact TypeScript's not that different from C-Sharp. Or C-Sharp, exactly, the syntax is very similar. And in fact, if you look at the tasks that we have here, you'll notice that I'm compiling it and actually shipping the JavaScript version. Absolutely. So it's not like I'm shipping a magical TypeScript version. I just decided to build it in TypeScript because it's more C-Sharpy. It does, and it gives you strong typing and syntax, yeah, syntax, typing. It's virtually nice. But it's all here. This is awesome. Well, James, I want to thank you so much for coming and showing us your new found love and appreciation for Visual Studio Team Services. I hope you guys enjoyed the show and we'll see you next time. Thanks.