Today we are going to create dynamic development environments with our PR’s/Pull Requests in GitHub. A year and a half ago, with Azure DevOps, we showed a similar, but much more complicated sample, of how to dynamically create an environment with each PR – and clean up after it. We are pleased to share, this is a LOT simpler to implement with GitHub Actions.
Why is this important?
When working on a new feature, having a environment to safely test and develop the feature – without affecting the rest of the development team, is a major win. Ultimately, this solution will help give us more confidence that we can make the changes we need to, while also giving us a place to test those changes before merging back into the main branch.
How does this work?
First, we start with our existing workflow. Each job to deploy an environment is straight forward. Running on the main trunk (line 31), each job logs into Azure and deploys our infrastructure as code to setup services, and then deploy our code to each resource group – however, this sample is just creating a resource group:

Chained together, our workflow is straight forward, creating a build (testing it), and then deploying artifacts with a build->dev->QA->prod workflow.

In Azure, we can see the resource group that was created for each environment:

Now we will add a PR (Pull Request) job to our workflow. This is essentially identical to our other deployment jobs, with the exception of the if condition on line 17- this only runs if triggered by a PR, and then on line 26, creates a resource group name with that PR.

Creating a new pull request, this is what our GitHub Actions workflow looks like:

We also see our new resource group in Azure, named after our PR. If we had created an Azure web app, we might browse to our application at myapp-pr11-eus-webapp.azurewebsites.net.

Closing the Pull Request
Once the pull request is closed (completed or abandoned), we need to delete the resource group. In Azure DevOps, we did this with a webhook. That is also possible in GitHub- but then this is extra code we have to write, host and then configure. GitHub Actions has another way! In the “on” trigger (lines 3-5), we can capture the pull request closed event. Then in our job, we can log into Azure and remove the corresponding pull request.

Meanwhile, the main build runs on the main branch, and progressively deploying to each environment, skipping the PR job.

Note that if we had other resources to clean up we should script them too – in our SamLearnsAzure example, we had identities in AAD, DNS in GoDaddy, certificates, etc – it’s a good idea to ensure we can undo everything we created, and not leave a bit of a mess behind.
Wrap-up
Today we reviewed a very simple example to create a new environment for a feature branch and PR, taking advantage of the cloud and dynamic environments. If we follow best practices and have short lived feature branches, the cost in the cloud is minimal.
References
- The demo repository: https://github.com/samsmithnz/DynamicPullRequests
- GitHub Actions pull request triggers: https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows#pull_request
- Featured image credit: https://i1.wp.com/git-for-windows.github.io/img/git_logo.png?resize=296%2C296&ssl=1
4 comments