Octopus Deploy comes to AppVeyor

Posted on April 05, 2018

This is a guest post by Robert Erez (Twitter: @no_erez), Program Manager at Octopus Deploy.

Continous Delivery in the cloud with Octopus and AppVeyor

The fantastic team at AppVeyor have recently added built-in support for pushing and deploying your projects (.NET, Java, JavaScript etc) with Octopus Deploy. What is Octopus Deploy I hear you ask? Octopus Deploy is a friendly deployment automation tool that makes it easy to automate your application deployments in a fast, repeatable and reliable manner. Octopus takes over where your build server ends, enabling you to easily automate even the most complicated application deployments, whether on-prem or in the cloud. Deploying your application through environments like DEV, TEST and PRODUCTION requires the assurance that the each releases are identical where it counts, but with configuration that can be injected to change from environment to environment.

Let's take a look at how this new partnership between AppVeyor and Octopus Deploy can help you build a complete devliery pipeline in the cloud.

The public OctopusSamples/RandomQuotes-aspmvc4 repository provides a basic ASP.NET MVC app to display a bunch of wise quotes. Our goal is to set up a delivery pipeline to deploy this website to our IIS server for both a staging and then production environment.

AppVeyor Octopus Plugin

Starting with the build of our project, I've added the OctopusSamples/RandomQuotes-aspmvc4 GitHub repository as the source of a new AppVeyor project.

Build & Pack

Looking at the build phase, you should notice the new Package Applications for Octopus Deployment:

AppVeyor Build Step

This flag ensures that once the build has completed, the contents are zipped up into a package that can be pushed to Octopus Deploy. Although Octopus will accept any NuGet, zip, or tar package this flag will use the octo.exe tool to create a zip, named using the application name and version.

Advanced features in Octopus-like Channels allow you to configure custom rules to prevent pre-release versioned packages from getting pushed to production, or ensure that version requirements are met for any linked packages as part of that deployment.

Push

In the Deployment configuration of the AppVeyor project, select the new Octopus Deploy deployment provider. This feature performs all the appropriate calls to pass the package into Octopus and create a related Octopus Release.

In Octopus, a Release ensures that each versioned build artifact will progress through its various environment phases with the same snapshotted deployment process, even if that project process is modified while the release is progressing. Reliable, repeatable deployments are our mantra.

AppVeyor Deployment Step

After adding your Octopus Server URL and API Key, tick the Push Packages option to allow AppVeyor to auto-detect the Octopus package built in the previous step. AppVeyor will then push the package to the Octopus built-in NuGet feed. Although Octopus supports automatic release creation when a new package is available, in this scenario we will trigger it through AppVeyor. Click the Create Release checkbox and provide the name of the project, RandomQuotes which we will later set-up in Octopus and which AppVeyor will programmatically trigger. Octopus was built API first and as such every feature and behavior can be configured and triggered via HTTP endpoints to integrate into any existing CI/CD pipeline!).

With our AppVeyor build pipeline set up, let's now jump into our Octopus Server and get this website deployed.

Continuing Deployment Through Octopus

With a dead simple Octopus Server installation (which, can naturally itself be automated) we are ready to add our new RandomQuotes project through the Octopus Web Portal. Hosted Octopus is an exciting new option which will be available soon that allows you to use Octopus Deploy without any on-premise infrastructure. We will manage your servers for you!

Octopus Projects

After configuring our infrastructure, go to the Projects section, click Add Project, and give it the name RandomQuotes that we specified earlier in our AppVeyor deploy step. This project contains all the deployment steps and configuration variables that define how this application is deployed.

For our simple deployment scenario, we will first go to the Process section and add a new IIS step. Octopus will handle all the complicated interactions to configure our IIS website with just a few inputs from us. There is a wide range of pre-built steps available for use in almost any deployment, so you don't need to write (or support) a single line of code. On top of this, we have an active community library with 100's more, and you can build and share your own steps between teams.

Octopus Deploy Steps

You can also include custom scripts in a variety of languages if you have a process in mind that doesn't quite fit any of the provided steps.

Deployment Step Details

After selecting the Deploy to IIS step, we will add a few settings to provide Octopus information to enable creating and configuring the IIS website.

Octopus Deploy IIS

Setting the Role under Execution Plan defines which machine(s) the website will be deployed to. A discussion on how Octopus can handle multiple environments each with different machine roles is a discussion in itself which we skip over in this demo. Check out our docs for more details.

Next, we will configure which package will be used for this step. Using the built-in feed (which AppVeyor will be pushing to) we can provide the PackageId RandomQuotes.

Configuring the website itself, which, at its simplest consists of setting just two additional values. The Website name and the AppPool. For this example, we will host both Staging and Production on the same machine (not the best idea for a real project), so we will provide a different website name based on the environment being deployed. The #{Octopus.Environment.Name} section of the name will be replaced at deploy time with the name of the environment.

Variables

This introduces us to one of the other awesome features of Octopus Deploy, variables. Using a templating syntax, you can provide configuration values, scripts, or even packages that all make use of variables that can be provided from Octopus itself or even user defined! In addition to the Website Name we have also decided to provide a different binding port between Staging and Production. This value #{CustomPort} is set in the Variables section of the project and can be scoped to a different value based on various combinations of deployment contexts like environment, machine or tenant, to name just a few.

Octopus Deploy variables

A common pattern is to define variables in Octopus for the different environments which are replaced in configuration files used by the application at run time. Using them during the deployment process opens up a wide range of advanced scenarios.

For our RandomQuotes project, we have a config transformation file for each of our environments. The Web.Production.config transformation that looks like:

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <appSettings>
    <add key="ReleaseVersion" value="#{Octopus.Release.Number}" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
    <add key="EnvironmentName" value="#{Octopus.Environment.Name}" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
    <add key="BackgroundColor" value="#1e8822" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
  </appSettings>
  <system.web>
    <compilation xdt:Transform="RemoveAttributes(debug)" />
  </system.web>
</configuration>

Notice the value for ReleaseVersion includes a template pattern During a deployment. (jump to the end of this post if you can't stand the suspense and what to see what this looks like).

Commit and Enjoy

We now have our automated CI/CD pipeline configured. When we commit a change to our project, AppVeyor will automatically pick up the changes, build the project, and push it to our Octopus Server. From this point on, Octopus Deploy takes over and deploys it to our staging environment. Once we are happy with this release, we can deploy to production with the click of a button. The same built package that has been tested will then be pushed to our production environment using new values provided by our variables.

Logs Together

When the deployment occurs, Octopus will apply any web.config transformations in your project and perform variable replacements so that the same built artifact is run in each environment, ensuring that the code that you test is the code that you run in production.

Staging

Deployed Staging

With the staging version of our application available we can inspect and test it before kicking off a deployment to production...

Running Deployment

Production

Deployed Production

Notice how the transformation has been applied changing the colour of the navbar, while the port and other variables have been updated based on the environment being deployed to.

AppVeyor + Octopus = Deploy Any Time

AppVeyor in combination with Octopus Deploy offers a new and exciting way to automate your continuous delivery pipeline in a repeatable, reliable manner. Say goodbye to hand rolled custom scripting solutions which break down at 5pm on a Friday. Flex the powers of AppVeyor's new feature today with a free Octopus trial.

Happy Deployments!

AppVeyor for Linux

Posted on March 06, 2018

Dear AppVeyor friends,

We’d like to thank you for building and testing your awesome Windows applications on AppVeyor! Your trust and support have always been driving us to evolve the service.

Today, we want to give you twice as much value with the addition of Linux platform! Now you can run your builds side-by-side on Ubuntu and Windows images.

It’s not a weekend project and we have a strong commitment to make AppVeyor a full-featured cross platform solution.

Evolved from our Windows offering, AppVeyor for Linux has some unique features:

  • Connect multiple version control systems: GitHub, Bitbucket, GitLab, VSTS, Kiln and any other Git, Mercurial or Subversion repository.
  • Configure CI for your projects via UI or in dot-file.
  • Full sudo access to VM running build.
  • Promoted deployments - build once and deploy the same packages to multiple environments.
  • Official out-of-the-box .NET Core support - automatic build, test and packaging of .NET Core projects. Proof: build, config, website - dedicated blog post is coming!
  • SQL Server 2017 for Linux.
  • Bash and PowerShell Core for controlling build flow.
  • Single configuration file for both Windows and Linux builds.
  • Docker support.
  • Built-in NuGet server.

How to get started

AppVeyor for Linux is currently in private beta, available by request. To participate in beta just reply to this message and provide your AppVeyor account details.

We have prepared a Getting started with AppVeyor for Linux guide where you can also find a list of supported features and pre-installed software.

Pricing

Perhaps what is most amazing about the addition of this new Linux platform is that it will not affect our low pricing! Once out of beta, the new Ubuntu image will be available to every account, free or paid. However, Premium accounts with two or more concurrent jobs will benefit the most as they will be able to run their tests on two platforms simultaneously.

Enjoy!

Best regards,
AppVeyor team

Follow us on Twitter: @appveyor

Scheduled builds for free accounts

Posted on November 08, 2017

Builds run on schedule is a feature we’ve been offering since early days of AppVeyor. It works great for many private and OSS projects. However, over the time we started noticing that there are a lot of “abandoned” projects with maintainers once configured scheduled builds and then leaving them running for the same commit over and over again.

Starting today we are making scheduled builds an optional feature for free accounts which is disabled by default. Paid accounts will continue to have scheduled builds enabled by default.

If you are the maintainer of OSS project and your CI workflow requires scheduled builds contact AppVeyor team and briefly describe your needs to request this feature.

Best regards,
AppVeyor team

Follow us on Twitter: @appveyor

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 incovenience 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