Use Dev Proxy in CI/CD scenarios
Using Dev Proxy in CI/CD scenarios is a great way to test your applications in a controlled environment. When you combine Dev Proxy with tests that generate API requests in your application, you can cover a wide range of scenarios: from ensuring that your app doesn't use shadow- or nonproduction APIs to checking that it uses minimal Microsoft Graph permissions. While the exact configuration steps vary depending on your CI/CD system, here are some general principles that you should follow.
Configure your runner
When you use Dev Proxy on your local machine, it runs interactively, waiting for you to control it by pressing keys. When you run it in a CI/CD pipeline, you can't control it with keys. To instruct Dev Proxy that it should run non-interactively, set the CI
environment to 1
or true
.
Note
Most CI/CD runners already have the CI
environment variable set. However, if you're using a custom runner, you might need to set it manually.
When Dev Proxy detects the CI
environment variable, it doesn't wait for key presses. You can then stop Dev Proxy gracefully by sending a SIGINT
signal to the process. Closing Dev Proxy gracefully is necessary when you record requests and want Dev Proxy to analyze them using its reporting plugins. Without the CI
environment variable, Dev Proxy would wait for you to press Ctrl+C. The only way to stop it would be to forcefully close its process using kill -9
or kill -KILL
, which stops Dev Proxy immediately and prevents it from analyzing the recorded requests.
Install Dev Proxy
In most cases, your runner doesn't have Dev Proxy installed. So before you can use Dev Proxy, you need to install it. The installation steps depend on the operating system that your runner uses.
Tip
To speed up your pipeline, consider caching the Dev Proxy installation folder. This way, you won't need to download the Dev Proxy every time you run your pipeline. For the exact steps, refer to the documentation of your CI/CD system.
When installing Dev Proxy in a CI/CD setup, you'll likely want to pin the version of Dev Proxy that you install. Pinning the version ensures that your pipeline uses the same version of Dev Proxy every time you run it. The exact steps to pin a version depend on the operating system of your runner. Here's an example of how you can pin the version of Dev Proxy on a Linux-based runner:
# install Dev Proxy v0.18.0
bash -c "$(curl -sL https://aka.ms/devproxy/setup.sh)" -- v0.18.0
Run Dev Proxy from a script
When you run Dev Proxy in a CI/CD pipeline, you need to start it from a script. Starting Dev Proxy from a script is necessary, because to close Dev Proxy gracefully, you need to send a SIGINT
signal to its process. Closing a process using SIGINT
is possible only from a script with job control enabled. If you start Dev Proxy directly from your CI/CD system, the Dev Proxy process ignores the SIGINT
signal, and keeps running.
Here's an example of a bash script with job control enabled that starts Dev Proxy:
# enable job control so that we can send SIGINT to Dev Proxy
set -m
# the rest of the script using Dev Proxy
Run Dev Proxy
After installing Dev Proxy, you need to start it. When starting Dev Proxy in a CI/CD pipeline it's important, that you start it in the background. Otherwise, your pipeline is blocked until you stop Dev Proxy.
If you're using a Linux-based runner, you can start Dev Proxy in the background by adding &
at the end of the command, for example ./devproxy/devproxy &
.
Wait for Dev Proxy to start
When you start Dev Proxy in the background, your script continues executing immediately. However, Dev Proxy needs some time to start. To ensure that Dev Proxy is ready before you start running your tests, wait for it to start. To wait for Dev Proxy to start, log its output to a file, and then check if Dev Proxy is listening for web requests, for example:
# log file path
log_file=devproxy.log
# start Dev Proxy in the background
# log Dev Proxy output to the log file
# log stdout and stderr to the file
./devproxy/devproxy > $log_file 2>&1 &
# store the Dev Proxy process ID
proxy_pid=$!
# wait for init
echo "Waiting for Dev Proxy to start..."
while true; do
if grep -q "Listening on 127.0.0.1:8000" $log_file; then
break
fi
sleep 1
done
# the rest of your script
Record requests
If you want to analyze API requests issued by your app, start Dev Proxy in the recording mode. You can start Dev Proxy with recording, using the --record
command-line argument, for example:
./devproxy/devproxy --record
Stop Dev Proxy
After you're done with your tests, stop Dev Proxy, by sending a SIGINT
signal to it. You can send the SIGINT
signal using the kill
command, for example:
kill -INT $proxy_pid
After you stop the Dev Proxy process, it can take a moment for it to fully close. This is especially the case, when you configure Dev Proxy to analyze recorded requests. To ensure that Dev Proxy finished processing the recorded requests, wait for the process to close, for example:
echo "Waiting for Dev Proxy to complete..."
while true; do
if grep -q -e "DONE" -e "No requests to process" -e "An error occurred in a plugin" $log_file; then
break
fi
sleep 1
done
When all recording plugins finish running, Dev Proxy prints the DONE
message to the output. If there were no requests to process, Dev Proxy prints the No requests to process
message. If an error occurred in a plugin, Dev Proxy prints the An error occurred in a plugin
message. When you see any of these messages, you can be sure that Dev Proxy finished processing the recorded requests.
Example script
Here's an example of a bash script that starts Dev Proxy, waits for it to start, runs tests, records requests, and stops Dev Proxy:
# enable job control so that we can send SIGINT to Dev Proxy
set -m
log_file=devproxy.log
echo "Starting Dev Proxy..."
# start Dev Proxy in the background
# log Dev Proxy output to the log file
# log stdout and stderr to the file
./devproxy/devproxy --record > $log_file 2>&1 &
proxy_pid=$!
# wait for init
echo "Waiting for Dev Proxy to start..."
while true; do
if grep -q "Recording" $log_file; then
break
fi
sleep 1
done
# From: https://www.eliostruyf.com/playwright-microsoft-dev-proxy-github-actions/
# setup certificates
echo "Export the Dev Proxy's Root Certificate"
openssl pkcs12 -in ~/.config/dev-proxy/rootCert.pfx -clcerts -nokeys -out dev-proxy-ca.crt -passin pass:""
echo "Installing certutil..."
sudo apt install libnss3-tools
echo "Adding certificate to the NSS database for Chromium..."
mkdir -p $HOME/.pki/nssdb
certutil --empty-password -d $HOME/.pki/nssdb -N
certutil -d sql:$HOME/.pki/nssdb -A -t "CT,," -n dev-proxy-ca.crt -i dev-proxy-ca.crt
echo "Certificate trusted."
echo "Running Playwright tests..."
npm test
# send SIGINT to Dev Proxy to close it gracefully
echo "Stopping Dev Proxy..."
kill -INT $proxy_pid
echo "Waiting for Dev Proxy to complete..."
while true; do
if grep -q -e "DONE" -e "No requests to process" -e "An error occurred in a plugin" $log_file; then
break
fi
sleep 1
done