Strange error disallow my .NET core application to start

Today I cloned in my workstation a .NET core application that works perfectly on my laptop, but when I started it I got this error

An attempt was made to access a socket in a way forbidden by its access permissions

I’ve spent almost 10 minutes to find why my netsh rule is not working (I work with a user that is not administrator of the machine) and finally, by frustration I opened Visual Studio with administrator user, just to verify that the error is still there.

For whatever reason (I’ve not time to investigate right now) port 21000 is somewhat blocked by some firewall rule apparently, because it is free, but kesterel is continuing giving me that error even if runs as admin.

Changing port solved the issue, but left me puzzled :/

Gian Maria.

Release software with GitHub actions and GitVersion

One of the nice aspect of GitHub actions is that you can automate stuff simply with command line tools. If you want to do continuous release of your software and you want to use GitVersion tool to determine a unique SemVer version from the history, here is the sequence of steps.

1) Iinstall/update gitversion tool with commandline tools
2) Run GitVersio to determine SemVer numbers
3) Issue a standard build/test using SemVerNumbers of step 2
4) If tests are ok, use dotnet publish command (with SemVer numbers) to publish software
5) Zip and upload publish result
6) It the branch is Master publish a GitHub release of your software.

Automating your CI pipeline using only CommandLine tools makes your build not dependent on the Engine you are using.

I’ve done such small exercise on a public project you can found here (https://github.com/AlkampferOpenSource/StupidFirewallManager) and it is composed by two command line tools, one is server version the other is the client.

Complete workflow definition can be found here (https://github.com/AlkampferOpenSource/StupidFirewallManager/blob/master/.github/workflows/dotnetcore.yml).

In this example I’m simply using some open source tasks to automate the whole process with GitHub Actions. The first step is being sure that right version of DotNetCore Sdk is used, and that GitVersion tool is installed.

    steps:
    - uses: actions/checkout@v1
      
    - name: Fetch all history for all tags and branches
      run: git fetch --prune
    
    - name: Setup .NET Core
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: '5.0.100-preview.1.20155.7'  

    - name: Install GitVersion
      uses: gittools/actions/gitversion/setup@v0.9
      with:
          versionSpec: '5.1.x'

The cool part is that I do not need to have anything preinstalled on the machine that runs the action, everything will be downloaded and installed by action definition. In this specific example my software is build with a pre-release of .NET Sdk (5.0.100-preview), a tooling that probably is not preinstalled in the action machine, but thanks to the capability of GitHub actions I can simply require installation on the fly before compiling everything. 

Being able to install required toolchain directly from Action definition allows you to run your action on public available GitHub agents.

Point 2 is achieved simply running GitVersion tool (installed from point 1) with a dedicated action. Another cool part of GitHub action is that you can simply refer custom action directly from your definition, no need to install anything.

- name: Use GitVersion
      id: gitversion # step id used as reference for output values
      uses: gittools/actions/gitversion/execute@v0.9
    - run: |
        echo "Major: ${{ steps.gitversion.outputs.major }}"
        echo "Minor: ${{ steps.gitversion.outputs.minor }}"
        echo "Patch: ${{ steps.gitversion.outputs.patch }}"
        echo "PreReleaseTag: ${{ steps.gitversion.outputs.preReleaseTag }}"
        echo "PreReleaseTagWithDash: ${{ steps.gitversion.outputs.preReleaseTagWithDash }}"
        echo "PreReleaseLabel: ${{ steps.gitversion.outputs.preReleaseLabel }}"
        echo "PreReleaseNumber: ${{ steps.gitversion.outputs.preReleaseNumber }}"
        echo "WeightedPreReleaseNumber: ${{ steps.gitversion.outputs.weightedPreReleaseNumber }}"
        echo "BuildMetaData: ${{ steps.gitversion.outputs.buildMetaData }}"
        echo "BuildMetaDataPadded: ${{ steps.gitversion.outputs.buildMetaDataPadded }}"
        echo "FullBuildMetaData: ${{ steps.gitversion.outputs.fullBuildMetaData }}"
        echo "MajorMinorPatch: ${{ steps.gitversion.outputs.majorMinorPatch }}"
        echo "SemVer: ${{ steps.gitversion.outputs.semVer }}"
        echo "LegacySemVer: ${{ steps.gitversion.outputs.legacySemVer }}"
        echo "LegacySemVerPadded: ${{ steps.gitversion.outputs.legacySemVerPadded }}"
        echo "AssemblySemVer: ${{ steps.gitversion.outputs.assemblySemVer }}"
        echo "AssemblySemFileVer: ${{ steps.gitversion.outputs.assemblySemFileVer }}"
        echo "FullSemVer: ${{ steps.gitversion.outputs.fullSemVer }}"
        echo "InformationalVersion: ${{ steps.gitversion.outputs.informationalVersion }}"
        echo "BranchName: ${{ steps.gitversion.outputs.branchName }}"
        echo "Sha: ${{ steps.gitversion.outputs.sha }}"
        echo "ShortSha: ${{ steps.gitversion.outputs.shortSha }}"
        echo "NuGetVersionV2: ${{ steps.gitversion.outputs.nuGetVersionV2 }}"
        echo "NuGetVersion: ${{ steps.gitversion.outputs.nuGetVersion }}"
        echo "NuGetPreReleaseTagV2: ${{ steps.gitversion.outputs.nuGetPreReleaseTagV2 }}"
        echo "NuGetPreReleaseTag: ${{ steps.gitversion.outputs.nuGetPreReleaseTag }}"
        echo "VersionSourceSha: ${{ steps.gitversion.outputs.versionSourceSha }}"
        echo "CommitsSinceVersionSource: ${{ steps.gitversion.outputs.commitsSinceVersionSource }}"
        echo "CommitsSinceVersionSourcePadded: ${{ steps.gitversion.outputs.commitsSinceVersionSourcePadded }}"
        echo "CommitDate: ${{ steps.gitversion.outputs.commitDate }}"

Point 3 requires only a run of dotnet restore followed by a dotnet test, to verify that code compiles and all tests are green.

    - name: Restore nuget with dotnet
      run: dotnet restore src/StupidFirewallManager.sln
           
    - name: dotnet tests
      run: dotnet test src/StupidFirewallManager.sln /p:AssemblyVersion=${{ steps.gitversion.outputs.assemblySemFileVer }} /p:FileVersion=${{ steps.gitversion.outputs.assemblySemFileVer }} /p:InformationalVersion=${{ steps.gitversion.outputs.Sha }}

A special mention is made to dotnet test parameters, where I specified AssemblyVersion, FileVersion and InformationalVersion directly from command line, using the SemVer number of GitVersion as assembly and file version, but full SHA for informational version.

You have various method to choose version number of the software during build phase, with full Framework you are forced to modify attributes in AssemblyInfo.cs (or AssemblyInfo.vb) before issuing the build. That options is available in GitVersion with UpdateAssemblyInfo options, but it is really clumsy because it does not gave you the ability to choose exactly what number goes in InformationalVersion, that, in my opinion, is most important of all the three. This is why in the past I’ve always use a PowerShell version to update AssemblyInfo.cs.

To be fair, GitVersion does an excellent work in updating AssemblyInfo.cs, but I’ve found a couple of problems, the first is that it actually only Updates the attributes, so you should not forget to insert an AssemblyInformationalVersion in your source code. The second problem is that it uses a too long name for that value, something like 0.5.0-alpha.11+Branch.develop.Sha.21fa38932256d7b64661e6363982dda39eb48b23. While it contains the Sha of the repository, that in my opinion is the most important value, it should be at first position of the string, due to limiting space you have when you look at file property in windows (Figure 5).

Using full Git Sha as informational version gives you the exact version of the code used to produce that artifacts. No way to alter the code and have the same Git Sha makes that number really important and usually it is the only information you need as Informational Version.

Points 4 and 5 are a simple set of Publish/compress/upload artifacts steps, made easy by the presence of 7zip in all machines (thanks Giulio for pointing me in the right direction).

    - name: dotnet publish server
      run: dotnet publish src/StupidFirewallManager/StupidFirewallManager.csproj --configuration release /p:AssemblyVersion=${{ steps.gitversion.outputs.assemblySemFileVer }} /p:FileVersion=${{ steps.gitversion.outputs.assemblySemFileVer }} /p:InformationalVersion=${{ steps.gitversion.outputs.Sha }}

    - name: dotnet publish client
      run: dotnet publish src/StupidFirewallManager.Client/StupidFirewallManager.Client.csproj --configuration release /p:AssemblyVersion=${{ steps.gitversion.outputs.assemblySemFileVer }} /p:FileVersion=${{ steps.gitversion.outputs.assemblySemFileVer }} /p:InformationalVersion=${{ steps.gitversion.outputs.Sha }}
    
    - name: 7Zip client
      run: 7z a -t7z -mx=9 client.7z ./src/StupidFirewallManager.Client/bin/release/netcoreapp5.0/publish/
    
    - name: 7Zip server
      run: 7z a -t7z -mx=9 server.7z ./src/StupidFirewallManager/bin/release/netcoreapp5.0/publish/

    - uses: actions/upload-artifact@v1
      with:
        name: "StupidFirewallManagerServer-${{ steps.gitversion.outputs.fullSemVer }}"
        path: server.7z

    - uses: actions/upload-artifact@v1
      with:
        name: "StupidFirewallManagerClient-${{ steps.gitversion.outputs.fullSemVer }}"
        path: client.7z

I’ve chosen to always create 7zip file with the same name (client.7z and server.7z) but when it is time to upload to pipeline as artifacts, it is nice to change name and give a full SemVer number. As you can verify, since we are in .NET Core, I was able to specify Assembly, File and Informational version directly in command line, without any need to have attributes in AssemblyInfo.cs files. An approach that I really like and prefer (no file to search and modify before the build).

In Figure 1 you can finally find how the artifacts are named in Action run summary page.

Artifacts uploaded by action run, you can notice the full semver.

Figure 1: Artifacts uploaded by action run, you can notice the full semver.

For final step (release) I’ve chosen to use a custom action to publish file on GitHub release and to automatically create release if no one with that name was created. I know that there are now official actions (from GitHub team) but this custom action worked perfectly in the past and it is still perfectly working today, so why change.

    - name: Upload server binaries to release
      if: contains(github.ref, 'master')
      uses: svenstaro/upload-release-action@v1-release
      with:
        repo_token: ${{ secrets.GITHUB_TOKEN }}
        file: server.7z
        asset_name: Server.7z
        tag: "${{ steps.gitversion.outputs.fullSemVer }}"
        overwrite: true
        
    - name: Upload client binaries to release
      if: contains(github.ref, 'master')
      uses: svenstaro/upload-release-action@v1-release
      with:
        repo_token: ${{ secrets.GITHUB_TOKEN }}
        file: client.7z
        asset_name: Client.7z
        tag: "${{ steps.gitversion.outputs.fullSemVer }}"
        overwrite: true

The only peculiarity of these two steps is the if clause, that allows me to ask Action engine to run this step only if the the ref is master. If you look at execution steps of a branch different from master, those two steps are not executed.

Action ran on branch different from master, upload release steps are skipped

Figure 2: Action ran on branch different from master, upload release steps are skipped

If you instead look at logs from an execution of master branch, the two steps are executed. As usual the name of the release is taken from SemVer numbers returned by GitVersion.

image

Figure 3: Publish artifacts to a standard GitHub release output

After the action ran on master, you should see a brand new release of your Repository, containing not only source code, but also published artifacts. As you can see, I’ve decided to upload artifacts with current name (server.7z and client.7z) because number was already present in Release Number

image

Figure 4: Release created by action run for branch master.

You can choose to release whatever branch you like, usually you release hotfix, release and master branch, but you can always grab the artifacts directly from action run output, so I’ve opted to create a real release only from master and stable version.

As final check you should download the release and verify that AssemblyVersion, FileVersion and InformationalVersion were correctly set in the assembly. As you can see in Figure 5 my released software was correctly marked with the correct version.

Versioning of the assembly is present and correct

Figure 5: Versioning of the assembly is present and correct

This last check is especially important, not only for software that will be release with Nuget Packages, but also for executable, because it can immediately tells you the exact version and the exact source code that was used to compile that specific version of the software.

Gian Maria.

Publish artifacts in GitHub actions

GitHub action is perfect to automate simple build workflow and can also be used to publish “releases” of our software. While we can do actions to publish on cloud or elsewhere, what I appreciate from a tool is: allow me to make simple things with simple workflow.

While I appreciate being able to obtain complex result and indeed, sometimes we evaluate products on the ability to fulfill complex scenario, often we forgot about the simple things. Is it true that, if a product allows me to solve complex scenarios, it will surely allow me to solve simple scenario, but I wonder about the complexity.

To automate a complex build and release workflow, currently I’d prefer Azure DevOps pipelines, but if I have a simple tool or library opensource on GitHub, quickly creating an action is the simplest way to go.

GitHub actions is still in its infancy and while it probably lack the ability to orchestrate complex workflows, it makes extremely simple to publish something, especially if the source uses command line tooling lile .NET core.

Here it is a small piece of GH action where I publish two distinct .NET core projects and then upload as artifact attachment to action run result.

    - name: dotnet publish server
      run: dotnet publish src/StupidFirewallManager/StupidFirewallManager.csproj --configuration release

    - name: dotnet publish client
      run: dotnet publish src/StupidFirewallManager.Client/StupidFirewallManager.Client.csproj --configuration release

    - uses: actions/upload-artifact@v1
      with:
        name: Publish server
        path: src/StupidFirewallManager/bin/release/netcoreapp3.1/publish

    - uses: actions/upload-artifact@v1
      with:
        name: Publish client
        path: src/StupidFirewallManager.Client/bin/release/netcoreapp3.1/publish

As you can see I can use dotnet publish commanline to simple publish software written in .NET core, then using actions/upload-artifact@v1 I can publish artifact to the action result.

SNAGHTML4b1e49

Figure 1: Artifacts attached to execution actions, simply downloadable from the UI.

With a simple task I can simply upload folders with build/publish result as execution artifacts, and I can simply download the result from the web interface. Artifacts are downloadable also from action run summary page.

image

Figure 2: Artifacts of the build in the summary page of action run.

Few lines of YAML, push on GH and you have each build to allow download of artifacts. Simple thing made simple.

Gian Maria

How to configure Visual Studio as Diff and Merge tool for Git

After almost six years, the post on How to configure diff and merge tool in Visual Studio Git Tools is still read by people that found it useful, but it is now really really old and needs to be updated.

That post was written when Visual Studio 2012 was the latest version and the integration with Git was still really young, made with an external plugin made by Microsoft and with really basic support. If you use Visual Studio 2017 or greater, you can simply go to to Team Explorer and open settings of the repository.

image

figure 1: Git repository settings inside Visual Studio Team Explorer

Settings pane contains a specific section for Git, where you can configure settings for the current repository or Global settings, valid for all repository of current user.

image

Figure 2: Git settings inside Visual Studio

If you open Repository Settings usually you find that no specific diff and merge tool is set. Merge and Diff configurations are typical settings that are made at User level and not for each single repository.

image

Figure 3: Diff and Merge tool configuration inside Visual Studio.

As you can see, in Figure 3 no diff or merge tool was set for the current repository, this means that it will use the default one for the user (in my situation is none). If you use only Visual Studio this settings is not so useful, if you have a conflict during merge or rebase visual studio will automatically show conflicts and guide you during merging.

If you are inside Visual Studio it will handle diff and merge automatically, even if it is not configured as Diff or Merge Tool. The rationale behind this choice is: If you are inside a tool (like VS) that has full support for diff and merge, the tool will automatically present you with diff and merge capabilities without checking repo configuration.

This happens because when you open a Git Repository, Visual Studio monitors the status of the Repository and, if some operation has unresolved conflicts, it shows the situation to the user, without the need to do anything. The settings in Figure 3 is useful only if you are operating with some other tool or with command line, if you got a conflict during an operation started from any other tool (GUI or command line) the procedure is:
1) Opening VS
2) from VS Team Explorer localize local git repository and open it
3) go to team explorer changes pane to start resolving conflicts

If you configured instead VS as diff and tool you can simply issue a git mergetool command and everything is done automatically without any user intervention. But to be honest, latest VS git integration is really good and it is surely better to manually open local repository. As an example, if you are doing a rebase from commandline and you got conflicts, it is better to manually open VS, solve the conflict, then continue rebase operation inside VS. If you got further conflicts, you do not need to wait for VS to reopen with git mergetool command.

But if you really want to configure VS as Diff and Merge tool, if you press “Use Visual Studio” button (Figure 3) you can modify your local gitconfig. The net result is similar to what I suggested on my old post, VS just adds the six sections for diff and merge in config file.

image

Figure 4: Git diff and merge section as saved from Visual Studio 2019 preview

If Visual Studio is your tool of choice I simply suggest you to configure it globally (file is named %userprofile%\.gitconfig) so you can invoke Merge tool from everywhere and have Visual Studio to handle everything.

Gian Maria.

Unable to Sysprep Windows 10 due to Candy Crush …

I was trying to sysprep a Windows 10 virtual machine hosted in Hyper-V but I got error messages like

Package CandyCrush.. was installed for a user, but not provisioned …

It turns out that Win 10 standard installer installs some application from the store that conflicts with sysprep. Now I need to uninstall one by one and to speedup the process I suggest you to use Get-AppxPackage powershell commandlet.

As an example to uninstall every application called Candy you can issue

Get-AppxPackage –Allusers *Candy* | Remove-AppxPackage

After you uninstalled all unwanted application you should be able to sysprep your Widnows 10 machine.

Gian Maria.