Sunday, 13 January 2019

Installing .NET Core SDK for Azure Pipelines builds

How do you ensure that the correct version of .NET Core SDK is installed for your Azure Pipeline builds? You could install it manually on your build agents, but wouldn't it be better to automate it?

The .NET Core Tool Installer Task can be used for this, and if you don't change the version of the SDK that you require frequently, very often that's enough.

When you're developing .NET Core applications, you can indicate which version of the SDK you require to build with by using a global.json file.

Unfortunately, the Installer Task doesn't currently know about global.json, so you might feel like you're doubling up - specifying the required version not only in that file but also in the configuration of the Installer Task. Don't do that!

With a bit of PowerShell, that can be done.. Create a PowerShell Task that runs before the Installer task and use it to set a variable that can then be used by the following task(s).

If you're using YAML, the task definitions would look something like this:

steps:
- powershell: |
    $PathToGlobalJson = Join-Path -Path $Env:BUILD_SOURCESDIRECTORY -ChildPath "global.json"
    $GlobalJson = Get-Content -Raw -Path  $PathToGlobalJson | ConvertFrom-Json
    $Version= $GlobalJson.sdk.version
    
    Write-Host ("##vso[task.setvariable variable=SdkVersion;]$Version")
  displayName: 'Parse global.json'

- task: DotNetCoreInstaller@0
  displayName: 'Use .NET Core sdk $(SdkVersion)'
  inputs:
    version: '$(SdkVersion)'

Wednesday, 26 December 2018

2018 draws to a close..

Stone stairway, with sunlight casting shadows
2018 is almost done. It's the day after Christmas, about 38°C outside (just over 100°F in the old money - not uncommon for this time of year in Adelaide). As I sit here under the cooling, gentle breeze from the air conditioner, I've compiled some of my 2018 highlights. (Let me know in the comments if I've missed something obvious)

Work

RL Solutions are/have merged with Datix. No changes yet, other than getting to meet a couple of people from the Datix side (including from their Melbourne office).

Our Adelaide team also grew this year with some new hires. We do miss Tom (having lost him to Toronto), but we've managed to survive, and it was great to have him back for a week last month. A part from my coding and team lead responsibilities, Tom's move has meant I've picked up additional roles of office grocery/supplies organiser and local IT support.

One particular recent highlight was upgrading the office to a 1G fibre Internet connection, taking advantage of the 10G Adelaide initiative. That's been a huge win - bandwidth is essentially no longer a constraint on getting things done.

Tarts and fruit mince pies
Toronto sent a lovely Christmas present to the Adelaide office. Yum!

User Group

The Adelaide .NET User Group has finished on a positive note. We've had increased attendances the last few months which is really encouraging. We've also had a sponsor come on board, which means we can run meetings for free now that our pizza costs are covered.

People seated, watching a presentation


It would be great to have others join me in organising the group - it does concern me that I'm the 'single point of failure' at the moment.

In addition to monthly meetings, I'm looking forward to some announcements in the new year about a bigger developer event for Adelaide.

Presentations

Managed to do some user group talks locally as well as while I was in Toronto, but the highlight for the year was being picked to present as part of .NET Conf.

Travel

A bit less this year - two weeks in North America in March (Toronto for work and then Seattle/Redmond for the Microsoft MVP Summit). Coming down with a nauseous gastro-type bug for the last couple of days and the flight home was not a highlight. Definitely an incentive to remember good hand hygiene!

We also had a family holiday interstate and flew (instead of driving all the way). More costly, but quicker and less stressful.

Christmas

A significant time of year, and one I really enjoy. I have many happy memories of Christmases as a child, and I hope we're creating them for our kids now.

Our family traditions include taking part in our Church's Road to Christmas 'Bethlehem re-enactment', joining with friends to sing carols at a local hospital, attending a Christmas Eve church service, and then gathering with family for a meal on Christmas Day.

Bonus tip: My aunty told me that she buys a platter/plate from a 2nd hand shop for the food that she brings. That way she doesn't need to worry about having to remember to bring it home.

Turtles

We bought my son a turtle for his birthday the previous year. 'Nibbles' is now fast outgrowing his tank, so the current project is to build a pond out in the garden where he can live (the turtle, not my son!)

The pond shell/liner, redgum wood sleepers, a pump and filter, shade-cloth all add up to be a surprising amount. Not to mention the manual labour of digging the hole in the ground!

I think Nibbles will appreciate it when it's all done.
Person lowering a turtle into a pond
Nibbles the turtle, about to give the pond a test drive/swim

Sevenfold

That's the band I play in. We've had a few gigs this year, and might be doing some recording in 2019. I was sad when Jane (our violin/mandolin player) retired as that left me as the sole string player on 'Cello. I've had to pick up some of Jane's parts in some of our songs. Our last gig for the year was something a bit different (and special) - playing for Liz (who also sings in our band) as part of her service of ordination to become a Deacon.

David at a band soundcheck
Sound check, with Pete and Keith photo-bombing

When you're young, you sometimes dream about being a rock-star. Well that hasn't happened! But I do get to play instruments and sing on stage with good friends, and people seem to like our music, so while I'm not giving up my day job, it is a lot of fun.

Cycling

I try and get out for a ride when I can. Seemed to be less commute riding this year, but got out for a few Saturdays with the Mud, Sweat and Gears mob. Looking forward to the Tour Down Under in January and riding in the Challenge Tour with my Dad and my Son (3 generations of Gardiners) as well as brother-in-law James.
Bicycle sitting next to a fence, overlooking green rolling hills

Family

I tend not to post much about my family here. If you know me personally then I might have shared a bit more about how we're all going. Needless to say, the kids are growing up fast!

Thanks for reading, see you in 2019 :-)

David

Monday, 3 December 2018

Top 10 source code files by line count

What are the top 10 source code files (by number of lines)?

gci -Recurse *.cs -ErrorAction SilentlyContinue | % { $file = $_; Get-Content $_ | Measure-Object -Line | Add-Member File $_ -PassThru } | Sort-Object -Descending -Property Lines | Select-Object -First 10 -Property File, Lines

Note the use of Add-Member to capture the filename so we can display it in the output

Thursday, 25 October 2018

Migrating npm packages to Azure Artifacts

Azure Artifacts is the new name for VSTS Package Management. It's a "one stop shop" for storing NuGet, npm, Maven, Gradle and "Universal" packages.

I'd previously been using another private npm registry server and wanted to shift over to using the Azure Artifacts npm registry instead. As part of this move, I needed to somehow grab the packages that were currently stored in the old registry and then re-publish them to the Artifacts one. Here's how I did it. Artifacts do support configuring 'upstream' sources, but that's not really a long term solution for migration.

Downloading packages

npm pack "@myscope/mypackage@^1.2.3456" --registry http://my.oldnpmserver

You'll now have a file with a name similar to myscope-mypackage-1.2.3456.tgz

Repeat this for all the packages you need.

Re-publishing packages


First off, create a new file named .npmrc and enter in the details for your Artifacts registry url. If you have packages with scopes (like I did above), then add in those as well.

@myscope:registry=https://myorg.pkgs.visualstudio.com/_packaging/MyArtifacts/npm/registry/
registry=https://myorg.pkgs.visualstudio.com/_packaging/MyArtifacts/npm/registry/

always-auth=true

Azure Artifacts are password-protected, so you'll need to authenticate. Your options here are to either make use of the vsts-npm-auth tool or generate credentials that can be pasted into the .npmrc file. Click on the Connect to Feed button from the Azure Artifacts page in the DevOps portal to find out the details.

Now use npm publish to push all the .tgz files up to the Artifacts repository (with a bit of help from PowerShell)

Get-ChildItem *.tgz | ForEach-Object { npm publish $_ }

Saturday, 13 October 2018

A Jon Skeet Meetup retrospective

This week we hosted Jon Skeet at the Adelaide .NET User Group. Jon demonstrated some of the new language features coming in C# 8, and it was probably the biggest attendance we've had in a really, really long time.

Because we had so many registrations, I lined up some extra help with my two oldest kids (conveniently on school holidays). They helped set up the room, liaised with the pizza delivery guy, and helped pack up everything. I think they even found a few things familiar with Jon's use of Fibonacci sequences in one example and similarity of programming language features (my eldest daughter has been doing some Python coding at school).

Jon lives in the UK, and we're in Australia, so whilst we would have loved to have Jon in person, the next best thing was to have him present remotely. We've had remote presentations before using Google Hangouts, but this time I opted to use Skype (and made use of the new recording feature).
I don't use Skype a lot, but we got the call up and running without too much difficulty.

I set up a webcam in the meeting room, along with a boundary microphone (an MXL AC404 USB Conference Microphone). The intention is that the presenter can see the audience, and the boundary microphone allows people to comment and ask questions from a fair way away (eg. right at the back of the room) and still be heard. This seemed to work pretty well - people up the back were able to ask questions and Jon seemed to hear them ok. Jon's video feed was pretty good. I think our feed back might have been a bit jumpy, but for the most part I think it was ok.

I left it to the last minute to arrange for access to the WiFi network at our venue. I ended up using my phone's 4G data for the call, which worked well. It was only after we'd finished that I discovered that an email had come through just before the start of the meeting with the WiFi details. At least I've got them for next time.

We also picked up a meeting sponsor this month in Simon Cook from Encode Talent Management. Being able to not charge attendees (to cover the cost of pizza) was great, and hopefully this relationship might continue in the future.

Snapshot from Skype recording, showing Jon Skeet in top, audience in bottom


Skype notes:
  • The recording doesn't include the extra buttons/overlays/controls (which is good)
  • The recording will record a split-screen of web cams if they're both active. If you just want to have one webcam in the recording then you'll need to disable the other one. When screen sharing, then just that is recorded.
  • Taking a 'snapshot' follows similar rules as for recording. eg. a snapshot would include both webcams if they're active, or just the shared screen if one is being shared.
  • If the presenting person isn't using a headset, then to avoid echo it's probably best to mute the microphone (and just un-mute it for questions)
  • Making the overlay controls slide out of the way was inconsistent. Sometimes moving the mouse off the screen worked, but one time it didn't. Would be good to figure this out.
  • F11 makes Skype go full screen
  • Skype now supports NDI. This means it should be able to talk to software like OBS Studio if you wanted more control over broadcasting or recording. I don't know if the feed it sends is just the video/shared screen or if that also includes the control overlays etc.
Other notes:
  • Our regular room can hold a decent crowd if necessary.
  • People will eat as much pizza as there is available to eat
  • People don't drink much water (but this might change if it was warmer weather)
  • Organise wifi access earlier!
  • Windows 10 has simple video editing via the Photos app
The recording of Jon's talk is up on YouTube. I won't be giving up my day job to become a YouTube broadcaster anytime soon, but it's nice to have a record of a great presentation.


Thursday, 13 September 2018

Speaking at .NET Conf - Put your C#, VB and F# projects and packaging on a diet

I'm really exited to be selected as one of the community speakers for .NET Conf

Title slide for .NET Conf talk
.NET Conf is a free “virtual” conference organised by Microsoft and the .NET developer community that is streamed live around the world. Being virtual, it means organising travel and accommodation is remarkably easy!

My talk is titled “Put your C#, VB and F# projects and packaging on a diet”, drilling in to the new project system for .NET, and how you can use it even with old projects that target .NET Framework and it starts at 04:00 UTC on Friday 14th September (check local times). Go to https://www.dotnetconf.net/ to watch the live stream.

All the demos from my talk and links to other resources can be found in the Github repo https://github.com/flcdrg/project-system-diet

Monday, 27 August 2018

Converting a SQL Server .bacpac to a .dacpac

Microsoft SQL Server has two related portable file formats - the DACPAC and the BACPAC. Quoting Data-tier Applications:
A DAC is a self-contained unit of SQL Server database deployment that enables data-tier developers and database administrators to package SQL Server objects into a portable artifact called a DAC package, also known as a DACPAC.
A BACPAC is a related artifact that encapsulates the database schema as well as the data stored in the database.
When they say related, they're not kidding! Both of these files formats are based on the Open Packaging Conventions (a fancy way of saying it's a .zip file with some other bits), and cracking them open you discover that a bacpac file is basically a dacpac with a few extra files and a couple of different settings. Knowing this, it should be possible to manually convert a bacpac to a dacpac.

First, unzip the .bacpac file (using 7-zip, or rename to .zip and use Windows File Explorer’s Extract Archive).

Now do the following actions (you could do these programmatically if this is something you need to do repeatedly):
  1. Edit model.xml
    1. Change DataSchemaModel@SchemaVersion to 2.4
  2. Edit Origin.xml
    1. Change ContainsExportedData to false
    2. Change ModelSchemaVersion to 2.4
    3. Remove ExportStatistics
    4. Recalculate the SHA256 checksum for model.xml and update the value stored in Checksums/Checksum@Uri=’/model.xml’
  3. Remove directories _rels and Data
Now re-zip up the remaining files and change the file suffix back to .dacpac

To verify that the .dacpac is valid, try using SSMS with the Upgrade Data-tier Application wizard. Run it against any database and if you can proceed to without error to the "Review Upgrade Plan" step, you should be good to go.