AppVeyor Enterprise is now available

Posted on October 03, 2017

Today we are excited to announce immediate availability of AppVeyor Enterprise!

AppVeyor is being used by more than 50,000 developers and we’ve run 10,000,000+ builds. As many companies had been asking about the possibility of installing AppVeyor behind their firewalls we started looking into just that. AppVeyor was originally born as a cloud product and tied to Azure. During the past few years we’ve been refactoring and maturing the AppVeyor codebase to fit into an on-premise scenario, and it is finally here!

AppVeyor Enterprise benefits:

  • Clean isolated environment for every build. Each new build runs on a new pristine VM which is immediately deleted afterwards to keep your costs low. This is the feature that we’ve been evangelizing from the very beginning and which we think sets AppVeyor apart from other products.

  • Multiple clouds to provision build VMs. You can run builds in different clouds (Azure, Google, Amazon) or on a Hyper-V server. On ci.appveyor.com we’re distributing load between clouds and we have multi-zone failover configurations and switch cloud providers depending on build image. All this cool stuff is available to you now!

  • Works with any language/stack. You can easily configure build projects with versioned AppVeyor YAML. We’ve gathered so much knowledge from the AppVeyor community and now you can use all these recipes for your own projects!

  • Works with your source control. AppVeyor can fetch the code from GitHub, Bitbucket, GitLab, Kiln or any other regular Git, Mercurial or SVN repository.

  • Built-in deployment. With AppVeyor Enterprise you can build once and promote the same package to multiple deployment environments. Hosted AppVeyor has been used by customers more than 1,200,000 times to deploy their applications.

  • Pricing for the cloud era. With AppVeyor Enterprise you can complete your test suite faster and with less cost. You get unlimited clouds, unlimited concurrent jobs, unlimited build and deploy agents. Pricing is based on the size of your team and starts from $300/month per 10 users.

Request your free trial of AppVeyor Enterprise today!

Best regards,
AppVeyor team

Follow us on Twitter: @appveyor

Sharing configuration between branches in appveyor.yml

Posted on August 01, 2017

The problem

There are two options to have branch-specific configuration with appveyor.yml:

  1. Commit appveyor.yml into each branch with branch-specific settings.
  2. Use Conditional build configuration where appveyor.yml has a list of configurations for different branches.

The problem with 1st approach is merging as you are overriding appveyor.yml in the base branch with one from the branch being merged.

2nd approach requires appveyor.yml of the following format:

# configuration for "master" branch
# build in Release mode and deploy to Azure
-
  branches:
    only:
      - master

  configuration: Release

  deploy:
    provider: AzureCS
    ...

# configuration for all branches starting from "dev-"
# build in Debug mode and deploy locally for testing
-
  branches:
    only:
      - /dev-.*/

  configuration: Debug

  deploy:
    provider: Local
    ...

# "fall back" configuration for all other branches
# no "branches" section defined
# do not deploy at all
-
  configuration: Debug

While this approach works great in the most cases there is one inconvenience though - with large configuration and many branches appveyor.yml becomes really unmanageable and error-prone as you have to repeat (copy-paste) entire configuration for every branch.

The solution

We just deployed an update to AppVeyor that allows sharing common configuration between branches in a single appveyor.yml!

There is new for node with a list of branch-specific configurations overriding common configuration defined on the top most level, for example:


# common configuration for ALL branches
environment:
  MY_VAR1: value-A

init:
- do_something_on_init.cmd

install:
- do_something_on_install.cmd

configuration: Debug

# here we are going to override common configuration
for:

# override settings for `master` branch
-
  branches:
    only:
      - master

  configuration: Release

  deploy:
    provider: FTP
    ...

# override settings for `dev-*` branches
-
  branches:
    only:
      - /dev-.*/

  environment:
    MY_VAR2: value-B

  deploy:
    provider: Local
    ...

In the example above we define environment, init and install sections for all branches as well as stating that default configuration is Debug. Then, for master branch we override default settings by changing configuration to Release and adding deployment with FTP provider. For dev-* branches we define a second environment variable MY_VAR2 and enable deployment to Local environment.

Configuration merging rules:

  • Scalar values such as image, version, configuration, platform, etc. defined on branch level override default ones;
  • Script sections such init, install, before_build, test_script, etc. defined on branch level override default ones;
  • Environment variables defined in environment sections are merged (new) and overridden (existing);
  • Build matrix defined on branch level merges with default one;
  • deploy, artifacts, notifications section can be either overridden or extended.

For example, consider the following configuration:

artifacts:
- path: bin

deploy:
- provider: Local
  ...

notifications:
- provider: Email
  ...

for:
  branches:
    only:
      - master

  artifacts:
  - path: docs

  deploy: off

  notifications:
    provider: Slack
    ...

In the example above we do the following:

  • For master branch we adding docs folder to artifacts definition, so both bin and docs folders collected. Both default and branch-specific collections were merged.
  • For master branch we disable any deployment. off or none on branch-level clears default collection.
  • For master branch we replace all notifications on default level with a single Slack notification.

Best regards,
AppVeyor team

Follow us on Twitter: @appveyor

CodeCov Test Coverage Integration

Posted on March 17, 2017

This is a guest post by Cedd Burge, Software Developer Lead at RES.

CodeCov visualises code coverage and can enforce standards via GitHub and AppVeyor. More information is available on CodeCov.io.

This post is written from the point of view of someone (me) who is already proficient in C# and unit testing, but was new to AppVeyor and integrating CodeCov with GitHub.

It contains from scratch steps to run CodeCov test coverage on a sample C# project using GitHub, AppVeyor, OpenCover and XUnit. You can look at the repo I created to test this post if you get stuck.

Create a new GitHub Repo

If you are new to GitHub, see this getting started guide, otherwise simply create a new repo (YourRepositoryName from now on) and git clone it somewhere convenient.

Create a new System Under Test (SUT) project and a new Test project

In my version of Visual Studio (Community 2015), you can do this by clicking on “File - New - Project” on the main menu, then “Class Library” from “Templates - Visual C#”. Give it a interesting name, which I will assume to be YourSUTProjectName for the rest of this post.

Repeat this for the test project, which I will assume to be YourTestProjectName.

Add the xunit, xunit.runner.visualstudio and xunit.runner.console nuget packages to your test project.

Add an XUnit test to YourTestProjectName and the corresponding thing under test to YourSUTProjectName, or copy and paste mine.

Run this test to make sure it passes.

Setup AppVeyor Integration

You will need to link an AppVeyor account to your GitHub one, so let’s do that:

  • Navigate to your repo in GitHub
  • Click “Settings” on the repo
  • Click “Integrations and services”
  • Click “Browse Directory”
  • Click “AppVeyor”
  • Click “Configure”
  • Click “Grant Access”

Now Log in to AppVeyor.com, probably using your GitHub account

  • Click “Projects”
  • Click “New Project”
  • Choose YourRepositoryName and click “Add”

Sign up with CodeCov

  • Go to https://codecov.io/ and click “Sign up with GitHub”
  • Click “Add new repository” and choose YourRepositoryName.
  • Make a note of the Upload token (YourUploadToken from now on)

Run Coverage Analysis Locally

When working with AppVeyor, it always makes sense to test on your own computer first. The feedback is immediate and you iterate very quickly. It takes a lot longer to modify the appveyor.yml file, push it and wait for a build to go through. Also, if it works locally but doesn’t work on AppVeyor, you know the problem is a configuration difference between your computer and the AppVeyor environment (eg a different version of msbuild).

However, this step is not required, so skip to “Run Coverage Analysis on AppVeyor” if you wish.

CodeCov.io is a tool for visualising and integrating coverage data, which we need to create. We will use OpenCover to do this.

Analyse

Add the OpenCover nuget package to the solution (which will install OpenCover.Console.exe, probably in packages\OpenCover.4.6.519\tools) and then run the following in a command window.

  • YourTestDLL is the relative path to the dll for your test project, eg. Tests\bin\Debug\tests.dll
  • -register[:user] asks OpenCover to register the code coverage profiler under HKEY_CURRENT_USER, which doesn’t require the user to have administrative permissions.
  • -target: asks OpenCover to run XUnit
  • -targetargs: are arguments that OpenCover passes to XUnit
  • -output: is the file to contain the coverage results
  • YourSUTNamepace, YourTestNamespace are the namespaces for your Test and SystemUnderTest projects. If these filters aren’t specified OpenCover will try and analyse everything, including the XUnit dlls.
packages\OpenCover.4.6.519\tools\OpenCover.Console.exe -register:user -target:"packages\xunit.runner.console.2.2.0\tools\xunit.console.x86.exe" -targetargs:"YourTestDLL -noshadow" -output:".\coverage.xml" -filter:"+[YourSUTNamepace*]* -[YourTestNamespace*]*"

Upload

Run the following on a PowerShell command line. This talks to CodeCov and downloads a bash script to upload the coverage.

Invoke-WebRequest -Uri 'https://codecov.io/bash' -OutFile codecov.sh

Then you can run the following in a Bash command line (You can use Git Bash on Windows). YourUploadToken is the CodeCov token that you took a note of earlier, or available on the project settings page on CodeCov (eg https://codecov.io/gh/YourGitHubUserName/YourRepositoryName/settings)

codecov.sh -f "coverage.xml" -t YourUploadToken

The output will show a url with the results (eg https://codecov.io/gh/YourGitHubUserName/YourRepositoryName)

Run Coverage Analysis on AppVeyor

Now that the coverage upload is working locally, we can run it on AppVeyor.

Add and commit an appveyor.yml file to the root of the repository as below.

  • YourSolution is the relative path of the .sln file to build (eg codecov-on-appveyor.sln)
  • YourUploadToken is not required if you are uploading from a public repo with AppVeyor, but is included in case you are using a private repo.
  • %xunit20%. XUnit is installed on the AppVeyor build environment by default, and AppVeyor provide the %xunit20% environment variable for the installation path.
before_build:
 - nuget restore
build_script:
 - msbuild /verbosity:quiet "YourSolution"
test_script:
 - .\packages\OpenCover.4.6.519\tools\OpenCover.Console.exe -register:user -target:"%xunit20%\xunit.console.x86.exe" -targetargs:"YourTestDll -noshadow" -output:"coverage.xml" -filter:"+[YourSUTNamepace*]* -[YourTestNamespace*]*"
after_test:
  - ps: |
      $env:PATH = 'C:\msys64\usr\bin;' + $env:PATH
      Invoke-WebRequest -Uri 'https://codecov.io/bash' -OutFile codecov.sh
      bash codecov.sh -f "coverage.xml" -t YourUploadToken

Add Coverage Graphics to the Repository

There are various badges and graphs available. Click on your project in CodeCov, then “Settings” and “Badge” (eg https://codecov.io/gh/YourGitHubUserName/YourRepositoryName/settings/badge) to see what’s available.

Copy and paste a code snippet from this in to your README.md, such as this one Code Coverage Badge.

You can look at my readme for example badges

Integrate CodeCov with Pull Requests

CodeCov automatically integrates with GitHub pull requests (as long as you signed up to CodeCov via your GitHub account) which you can see on this pull request.

It will show some statistics, such as the increase or decrease in coverage, and by default will fail the build if coverage decreases. You can configure this with a ‘codecov.yml’ file in the root of your repository.

Install the browser plugin

There is a CodeCov browser plugin, for all reputable browsers, that adds coverage when browsing GitHub.com. Code is highlighted in red / green, and a coverage percentage is shown.

Conclusions

It can be difficult keeping control of test coverage for a project, especially with distributed and transient team structures. The combination of GitHub, AppVeyor OpenCover and CodeCov make it very easy to visualise the coverage, and allow you to enforce standards to ensure that it improves over time.

Best regards,
Cedd Burge

Follow Cedd on Twitter: @cuddlyburger
Follow AppVeyor on Twitter: @appveyor

SonarQube Analysis

Posted on December 23, 2016

This is a guest post by Cedd Burge, Software Developer Lead at RES. Last updated and verified working December 2020.

SonarQube / SonarSource analyzes code, highlights quality issues and calculates metrics such as technical debt. More information is available on SonarSource.com.

This post is written from the point of view of someone (me) who is already proficient in C#, and had used SonarQube, but was new to AppVeyor and integrating SonarQube with GitHub.

It contains from scratch steps to run the SonarQube analysis on a sample project and to publish the results to SonarCloud.io. You can look at the repo I created to test this post if you get stuck.

Create a new GitHub repository

If you are new to GitHub, see this getting started guide, otherwise simply create a new repo and git clone it somewhere convenient.

Create a new project

In my version of Visual Studio (Community 2017), you can do this by clicking on “File - New - Project” on the main menu, then one of the Class Library options (.NET Framework for example) from the “Visual C#” section. Give it a interesting name, which I will assume to be YourProjectName for the rest of this post.

Add some code that has some quality issues (e.g. a variable that is declared but never used). You can use the the full list of SonarQube C# issues for inspiration. Alternatively you can copy and paste some of mine.

Install the Sonar Visual Studio Plugin. This highlights quality issues in your code as you type and gives you a chance to fix them before committing.

Integrate GitHub with AppVeyor

Log in to AppVeyor.com, probably using your GitHub account

  • Click “Projects”
  • Click “New Project”
  • Choose your GitHub repository and click “Add”

Sign up with SonarQube and generate an Authentication Token

Run SonarQube Analysis Locally

When working with AppVeyor, it always makes sense to test on your own computer first. The feedback is immediate and you iterate very quickly. It takes a lot longer to modify the appveyor.yml file, push it and wait for a build to go through. Also, if it works locally but doesn’t work on AppVeyor, you know the problem is a configuration difference between your computer and the AppVeyor environment (e.g. a different version of msbuild).

Instead of committing SonarQube executables to the repo, we will download them during the build using Chocolatey.

Install chocolatey

  • Install Chocolatey from an administrator command prompt / powershell.
  • Close the command prompt

Install SonarQube MSBuild Runner

  • Open a new administrator command prompt / powershell.
  • choco install "sonarscanner-msbuild-net46" -y

Analyze and upload to SonarQube

SonarScanner.MSBuild.exe begin /k:"**YourUniqueProjectName**" /d:"sonar.host.url=https://sonarqube.com" /d:"sonar.login=**YourSonarQubeToken**" /o:"**YourSonarQubeOrganisationKey**"
"**YourPathToMSBuild**\MSBuild.exe" "**YourProjectName**.sln"
SonarScanner.MSBuild.exe end /d:"sonar.login=**YourSonarQubeToken**"

YourUniqueProjectName can be anything you like, as long as it is unique.

When finished, you will be able to see the results at sonarcloud.io/. If it isn’t working, make sure you are using MSBuild 14 and Java 1.8 or later. The SonarQube Getting Started page is excellent if you need to troubleshoot.

Run SonarQube Analysis on AppVeyor

Now that this is working locally, we can run it on AppVeyor.

Add and commit an appveyor.yml file to the root of the repository as follows

before_build:
 - nuget restore
build_script:
 - choco install "sonarscanner-msbuild-net46" -y
 - SonarScanner.MSBuild.exe begin /k:"**YourUniqueProjectName**" /d:"sonar.host.url=https://sonarcloud.io" /o:"**YourSonarQubeOrganisationKey**" /d:"sonar.login=**YourSonarQubeToken**"
 - msbuild /verbosity:quiet "**YourProjectName**.sln"
 - SonarScanner.MSBuild.exe end /d:"sonar.login=**YourSonarQubeToken**"

Again, you can check the results at sonarcloud.io.

It is possible that the default version of Java on the build machine is different to the one required by SonarQube, in which case SonarQube will show an error. In this case add the correct version of Java to the path in the build_script, as below.

...
build_script:
 - set JAVA_HOME=C:\Program Files\Java\jdk11
 - set PATH=%JAVA_HOME%\bin;%PATH%
...

Add a SonarQube badge to the repo

There are are variety of badges available. If you navigate to your project on SonarCloud there is a “Get Project Badges” button. It’s a bit hard to find but is on the bottom right of the page at the time of writing.

To add a standard Quality Gate Statusbadge, add the following to readme.md.

[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=**YourUniqueProjectName**&metric=alert_status)](https://sonarcloud.io/dashboard?id=**YourUniqueProjectName**)

Integrate SonarQube with Pull Requests

SonarQube can analyze Pull Requests for quality issues, but sadly this feature is no longer in the free version. You can see more on the Sonar Website.

Wrapping Up

SonarQube is maturing fast and is becoming industry standard, and happily it is easy to integrate Open Source projects with the publicly available SonarQube server and AppVeyor. The Sonar Visual Studio Plugin is fantastic at spotting problems before you commit them, and the (paid for) pull request integration allows you to control the quality of contributions.

Best regards,
Cedd Burge

Follow Cedd on Twitter: @cuddlyburger
Follow AppVeyor on Twitter: @appveyor

Creating a Signed and ZipAligned APK (for Google Play) from Xamarin

Posted on November 22, 2016

Introduction

This is a guest post by Cedd Burge, Software Developer Lead at RES.

This post is written from the point of view of someone (me) who is already proficient in C#, but was new to Xamarin, Mobile phone development, and AppVeyor.

It contains from scratch steps to create a Xamarin Android application (in Visual Studio), to build it on AppVeyor and to publish it to the Play Store. You can look at the repo I created to test this post if you get stuck.

First, install Xamarin from https://www.xamarin.com/download.

Create a new repository on GitHub

If you are new to GitHub, see this getting started guide, otherwise simply create a new repo and git clone it somewhere convenient.

Create a new Xamarin Portable Class Library (PCL) project

In my version of Visual Studio (Community 2015), this is done by clicking “File - New - Project” on the main menu and then selecting “Blank App (Xamarin.Forms Portable)” from “Templates - Visual C# - Cross-Platform”. Give it a interesting name, which I will assume to be YourAppName for the rest of this post.

Run the app!

Select the YourAppName.Droid project and run it. This should show the bare bones app in an emulator.

If you have Hyper-V enabled (maybe you use Docker), then you might get an Deployment Error when doing this. Disable Hyper-V and restart your machine to fix this.

You might also run in to compile errors due to ridiculous dependency weirdness.

Create APK file manually

To tell Google about your app, you have to make some changes to the Properties\AndroidManifest.xml file of the YourAppName.Droid project.

  • Add a package="com.yourappname" (or similar) attribute to the root manifest node. The package name must be unique on Google Play and must follow normal java package name conventions. Most people use their url in reverse (eg com.yourappname instead of yourappname.com) and stick to lower case.
  • Add an android:versionCode="1" attribute to the root manifest node. This is an integer and it must be incremented every time you upload an apk on Google Play.
  • Add an android:versionName="0.1 attribute to the root manifest node. This value can be anything you like and is displayed in Google Play.
  • Change the label attribute on the application node to YourAppName.

Visual studio has some tools to create an APK, and they seem to be in constant churn, but at the time of writing, the process is as follows.

  • Change the “Build Configuration” to “App Store”.
  • Select the YourAppName.droid project and click “Build - Archive” from the main menu.
  • The archive manager window will appear and build your app.
  • Click “Distribute”, which will pop up the Distribute window.
  • Initially you won’t have a signing identity, so click on the green plus button and fill in the details to create one.
  • Once created, double click on it and note where it is on disk (YourKeyStoreFilename from now on)
  • Click “Save As” to create an APK.

Upload the APK to Google Play

  • Create a Developer Account on Google Play Developer Console (this costs $25)
  • Click “Add New Application” and add YourAppName
  • Upload the APK that you saved in the previous step

Publish the App on Google Play (probably just to Alpha or Beta)

There are some requirements when publishing an application to Google Play, and these are likely to change, but happily google tells you what they all are. If you click on “Why can’t I publish?”, near the top right corner of the page, you will get a list of things to do.

It’s all simple stuff that can be done within the Developer Console. Some screenshots and pictures are required. If you just want to get a test version up quickly, then feel free to use mine temporarily.

There are a lot of optional things you can do as well, which can be worthwhile if you want to publish a killer app. The Google Launch Checklist, is comprehensive, but takes a long time to read.

Automate APK creation locally

When working with appveyor, it always makes sense to test on your own computer first. The feedback is immediate and you iterate very quickly. It takes a lot longer to modify the appveyor.yml file, push it and wait for a build to go through. Also, if it works locally but doesn’t work on AppVeyor, you know the problem is a configuration difference between your computer and the AppVeyor environment (eg a different version of msbuild).

Being as we are making a new version of the apk, we need to increment android:versionCode in Properties/AndroidManifest.xml.

There are some Xamarin MSBuild targets, which we can use to create a Signed and ZipAligned apk as below.

There are 2 passwords required in the command because java KeyStores can contain multiple Alias’. So the first password is to access the KeyStore, and the second one is to access the specific alias. Visual studio hides this complexity from you and assigns the same password to both places.

I do a lot of work in GIT Bash, but this statement only works in Batch (the windows command line), I think because of parameter escaping.

MSBuild "/t:SignAndroidPackage" "/p:Configuration=Release" "/p:AndroidKeyStore=true" "/p:AndroidSigningKeyAlias=YourKeyAlias" "/p:AndroidSigningKeyPass=YourKeyStorePassword" "/p:AndroidSigningKeyStore=YourKeyStoreFilename" "/p:AndroidSigningStorePass=YourKeyStorePassword" "YourAppName.csproj"

This will create com.yourappname-Signed.apk in the bin\release folder. Upload this to Google Play to make sure that everything is working properly.

Automate APK creation on AppVeyor

You will need to link an AppVeyor account to your GitHub one, so let’s do that:

  • Navigate to your repo in GitHub
  • Click “Settings” on the repo
  • Click “Integrations and services”
  • Click “Browse Directory”
  • Click “AppVeyor”
  • Click “Configure”
  • Click “Grant Access”

Now Log in to AppVeyor.com, probably using your GitHub account

  • Click “Projects”
  • Click “New Project”
  • Choose your GitHub repository and click “Add”

MSBuild needs to access your KeyStore file in order to sign the apk, so copy YourKeyStoreFilename in to the folder of YourAppName.Droid project (called YourKeyStoreLocalFilename from now on).

When we created the apk from the command line, we entered in some passwords, and we obviously can’t save these passwords to a public Git repository. Happily AppVeyor have thought of this, and you can convert passwords in to tokens that can be exposed publicly.

To do this click AccountEncrypt YAML from the drop down menu. Enter YourKeyStorePassword in to “Value to encrypt” and click “Encrypt”. AppVeyor will then display a token which you can use in place of the real value.

Now that we have everything we need, add an appveyor.yml file to the root of your repository as below. Note that YourLocalKeyStoreFilename is relative to the csproj file being built (the YourAppName.Droid folder below).

environment:
  keystore-password:
    secure: DSwAr4fYt3Q35Sjob5qAN5uj # YourPassword for keystore
before_build:
  - nuget restore
build_script:
  - msbuild "/t:SignAndroidPackage" "/p:Configuration=Release" "/p:AndroidKeyStore=true" "/p:AndroidSigningKeyAlias=YourKeyAlias" "/p:AndroidSigningKeyPass=%keystore-password%" "/p:AndroidSigningKeyStore=YourLocalKeyStoreFilename" "/p:AndroidSigningStorePass=%keystore-password%"  "YourAppName.Droid\YourAppName.csproj"
artifacts:
  - path: YourAppName.Droid\bin\Release\com.yourappname-Signed.apk

Remember to update android:versionCode and then push to GitHub. This will trigger a build on AppVeyor. The build_script section will call msbuild to create the signed and zipaligned apk file, and the artifacts section will archive the apk file so we can download it later.

Go to AppVeyor.com, click on your project, click on “Artifacts”, download the apk file, and then upload it to google to check that everything has worked properly.

Conclusion

There is a lot to learn to get everything working, and I couldn’t find a single source for all of these things, but having done it once, the process is actually quite simple, and the tools and services involved are generally a pleasure to work with.

Best regards,
Cedd Burge

Follow Cedd on Twitter: @cuddlyburger
Follow AppVeyor on Twitter: @appveyor