Microsoft at Open Source Summit Europe 2024: Driving collaboration and innovation
Connect with other open source enthusiasts at Open Source Summit Europe 2024…
Two facts are generally true for software releases. One, as users, we wish software releases came with better release notes, and two, we hate creating release notes when it’s our turn to ship software updates. Creating release notes requires someone to go back in time to the last release, gathering the relevant information, and compiling it into a document to share with users. This can be quite a challenge and very time consuming. Wouldn’t it be nice to automate this process?
In this blog post, I’ll walk you through an application I created to automate release note generation for source code hosted in GitHub using Azure Functions. This walk-through highlights the services used for the application and comes with a sample repo so that you can create your own generator and explore ways to enhance your workflow.
Azure Functions and GitHub webhooks make it easy to merge your GitHub workflow with serverless solutions. This inspired the creation of the GitHub Release Notes Generator, an application written in C# that creates neatly formatted release notes, using GitHub, Azure Functions, and Azure Storage, to shave time off of your release process and ensure all relevant information reaches your team and users.
Serverless applications are event-driven, so something needs to happen to make your code run, and one of the benefits of this is that you’re only paying for the time your application runs. This makes Azure Functions a good fit for the generator. Functions are hosted within a function app, which provides a central area for configuring general settings and key management for all functions. When a new release is created in the selected GitHub repository, a GitHub webhook function executes code to create the release notes.
This results in writing less code: configuration for all functions happens in one place, and the functions themselves have bindings, which allow your functions to interact with additional Azure services or external ones, such as the GitHub webhook. After creating the function app and function, there is very minimal setup to make sure the webhook is set up for the proper GitHub event and repository.
The function now can be updated to generate the notes. Since GitHub uses Markdown for documentation in repositories and releases, the generator also uses markdown and creates a markdown file with relevant release information. Azure blob storage provides a managed solution for unstructured data, such as markdown files of varying sizes and will scale as more releases are created. The end result is a file store available for distributed access or serving to a browser. Using the Azure Storage API, the generator creates the markdown file, then appends additional information about the release. With a storage account you can create a blob container, where the release notes will live.
When a release is created, its specific details can be found in the webhook’s HTTP response. The response includes information about the event and additional metadata about the repository, which is where the generator sets the file name as the release name and header. It also appends the release’s body to the file.
Here I extract the name and body of the new release from the webhook response and set the release name as the file name:
public static async Task Run(HttpRequestMessage req, TraceWriter log) { // Get request body dynamic data = await req.Content.ReadAsAsync<object>(); // Extract github release data from request body string releaseBody = data?.release?.body; string releaseName = data?.release?.name; //Connect to storage account CloudStorageAccount storageAccount = CloudStorageAccount.Parse(Environment.GetEnvironmentVariable("StorageAccountConnectionString")); var blobClient = storageAccount.CreateCloudBlobClient(); var container = blobClient.GetContainerReference("releases"); //Set name of file var blob = container.GetBlockBlobReference(releaseName + ".md" ); }
It’s not possible to include all of the Issues and Pull Request history with this event alone, so we’ll need to get some additional information about the repository through the Octokit.NET API. This requires some minimal setup in the GitHub website by creating a new OAuth app, then using the app’s name to access the API. The function uses the API with a date qualifier to get the last two weeks’ closed Issues and merged Pull Requests.
Here I get issues and pull requests from GitHub through the Octokit.NET API:
public static async Task<string> GetReleaseDetails(IssueTypeQualifier type) { //Connect to client with OAuth App var github = new GitHubClient(new ProductHeaderValue(Environment.GetEnvironmentVariable("ReleaseNotes"))); var twoWeeks = DateTime.Now.Subtract(TimeSpan.FromDays(14)); var request = new SearchIssuesRequest(); //Find Issues or PRs closed within the past 14 days in specified Repo request.Repos.Add(Environment.GetEnvironmentVariable("Repo")); request.Type = type; request.Closed = new DateRange(twoWeeks, SearchQualifierOperator.GreaterThan); }
Azure Functions are a quick and straightforward way to create your own customizable serverless workflows. Working with external services, such as GitHub, requires minimal setup with webhooks and makes getting started fast and manageable. The release notes generator is just one of several possible tools to do this, and its sample code is a good start if you’re interested in exploring possibilities that work for you.
The sample includes instructions for building your own generator from scratch or deploying it from your Azure subscription. Once you’ve got your own notes generator up and running, be sure to visit the docs and samples to see what else you can do with serverless applications.
GitHub Release Notes Generator
An introduction to Azure Functions
Create a function triggered by a GitHub webhook
Serverless apps: Architecture, patterns and Azure implementation (e-book)