Publishing a custom Azure Pipelines release task
Tags: azurepipelines, cloudflare, devops, showdev
Published: 2019-06-20 12:09:21

---
title: Publishing a custom Azure Pipelines release task
published: true
tags: azure-pipelines,cloudflare,devops,showdev
canonical_url: http://staffordwilliams.com/blog/2019/05/19/publishing-a-custom-azure-pipeline-release-task/
---

I wanted to clear my Cloudflare cache during an Azure Pipeline deployment. Cloudflare offers a REST API to do this, but rather than poke around with scripts I decided to see how I could instead write a custom task to do this and publish it on the Visual Studio market place.

## Get the extension

The extension is [free on Visual Studio Marketplace](%5Bhere%5D(https://marketplace.visualstudio.com/items?itemName=staff0rd.tfx-cloudflare-purge)) and it’s [open source on github](https://github.com/staff0rd/tfx-cloudflare-purge). Here’s a screenshot of how it looks in a Azure DevOps:

 ![Screenshot of Purge Cache for Cloudflare release task](http://staffordwilliams.com/assets/purge-for-cloudflare.png)

## How I built it

I followed a great [walk-through on docs.microsoft](https://docs.microsoft.com/en-us/azure/devops/extend/develop/add-build-task?view=azure-devops). I like that the instructions promote typescript and testing, though I’m not going to write tests for such a small task.

Another netizen [already pointed out](https://www.david-tec.com/2018/06/clear-the-cloudflare-cache-as-part-of-a-release-in-visual-studio-team-services-vsts/) that I would need to query first the Cloudflare REST API to translate a zone name into a zone id, and then request the purge. I turned those instructions into [typescript](https://github.com/staff0rd/tfx-cloudflare-purge/blob/master/cloudflarePurge/index.ts), compiled to javascript, and bundled this javascript as a vsix extensiion using `tfx-cli`.

Over all [the code](https://github.com/staff0rd/tfx-cloudflare-purge) is very simple. The structure is as follows:

- /[vss-extension.json](https://github.com/staff0rd/tfx-cloudflare-purge/blob/master/vss-extension.json)
  - Extension manifest, defines basic information about what the extenion does. [Reference docs](https://docs.microsoft.com/en-us/azure/devops/extend/develop/manifest?view=azure-devops).
- /images/extension-icon.png 
  - Icon representing the extension
- /cloudflarePurge/[index.ts](https://github.com/staff0rd/tfx-cloudflare-purge/blob/master/cloudflarePurge/index.ts)
  - The code that the task will execute. I haven’t written TypeScript since before v2 so I suspect the error handling could be more elegantly written with async or similar.
- /cloudflarePurge/[task.json](https://github.com/staff0rd/tfx-cloudflare-purge/blob/master/cloudflarePurge/task.json)
  - Defines how the task’s configuration options will be rendered and which scripts will execute at build time. [Reference docs](https://github.com/Microsoft/azure-pipelines-task-lib/blob/master/tasks.schema.json)

If we were just using javascript with no dependencies, that would be it. However we’re using typescript so we also have;

- /cloudflarePurge/index.js 
  - `tsc` output (generated)
- /cloudflarePurge/[package.json](https://github.com/staff0rd/tfx-cloudflare-purge/blob/master/cloudflarePurge/package.json)
  - nodejs dependencies
- /cloudflarePurge/[tsconfig.json](https://github.com/staff0rd/tfx-cloudflare-purge/blob/master/cloudflarePurge/tsconfig.json)
  - typescript config

Once this is in place I packaged the extension with:

```
npx tfx-cli extension create --rev-version --manifest-globs vss-extension.json
```

## Publishing

Publishing was a little odd - to publish publicly your Visual Studio Marketplace account needs to be approved as a publisher by someone at Microsoft. This was accomplished by entering some details about who I was and clicking a Request Approval (or similar) button. I got an approval and a you’re now approved email from someone at Microsoft about two days later.

Prior to being approved, the marketplace will block the uploading of any extension that has `public:true` set. Post-approval the uploader pointed out I need to include an `overview.md` on a public extension. However, you can point content/details in your `vss-extension.json` at, say, `README.md` to resolve this issue:

```
"content": {
    "details": {
        "path": "README.md"
    } 
},
```

## That’s it!

Overall it was pretty simple to execute custom code within an Azure Pipeline release and package it into an extension. From here I’d like to look into how such a task can be called by an Azure Pipeline yaml build, and, to auto-deploy updates to this task to the marketplace on commit - a colleague of mine has [a post on this](https://blog.raph.ws/2018/03/build-and-release-pipeline-for-your-own-custom-vsts-tasks/).