Hace unos días compartí contigo cómo desplegar código en un App Service con private endpoint desde fuera de su red usando la extensión Onedeploy Hoy quiero mostrarte cómo integrar esta implementación en un flujo de GitHub Actions.
El flujo
Para este ejemplo he utilizado el mismo código de ejemplo que usé en el artículo anterior, pero puedes obviamente usar cualquier otro. En su repositorio he creado el siguiente flujo:
name: Build and deploy in internalweb
on:
push:
branches:
- main
workflow_dispatch:
env:
PACKAGE_NAME: todo-web
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: '6.0.x'
include-prerelease: true
- name: Build with dotnet
run: dotnet build --configuration Release
- name: dotnet publish
run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/myapp
- name: Upload artifact for deployment job
uses: actions/upload-artifact@v2
with:
name: .net-app
path: ${{env.DOTNET_ROOT}}/myapp
deploy:
runs-on: ubuntu-latest
needs: build
steps:
- name: Download artifact from build job
uses: actions/download-artifact@v2
with:
name: .net-app
path: myapp
- name: Azure Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Zip up the app
run: |
cd myapp
zip -r ../myapp.zip .
- name: Upload the zip to Azure
uses: azure/CLI@v1
with:
azcliversion: 2.33.1
inlineScript: |
FULL_PACKAGE_NAME=${{ env.PACKAGE_NAME }}-${{ github.sha }}
echo "Package name: $FULL_PACKAGE_NAME"
az storage blob upload --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --container-name packages --name $FULL_PACKAGE_NAME.zip --file myapp.zip
- name: Get date after 30 minutes
id: date
run: |
echo "::set-output name=date::$(date -d "30 minutes" +%Y-%m-%dT%H:%MZ)"
- name: Azure CLI script
id: deployment
uses: azure/CLI@v1
with:
azcliversion: 2.33.1
inlineScript: |
FULL_PACKAGE_NAME=${{ env.PACKAGE_NAME }}-${{ github.sha }}
STORAGE_ACCOUNT_KEY=$(az storage account keys list --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --resource-group ${{ secrets.RESOURCE_GROUP }} --query "[0].value" --output tsv)
SAS=$(az storage account generate-sas --permissions rl --account-name ${{ secrets.STORAGE_ACCOUNT_NAME }} --account-key $STORAGE_ACCOUNT_KEY --services b --resource-types co --expiry ${{ steps.date.outputs.date }} -o tsv)
ZIP_URL="https://${{ secrets.STORAGE_ACCOUNT_NAME }}.blob.core.windows.net/packages/$FULL_PACKAGE_NAME.zip?$SAS"
SUBSCRIPTION_ID=$(az account show --query id --output tsv)
SITE_URI="https://management.azure.com/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${{ secrets.RESOURCE_GROUP }}/providers/Microsoft.Web/sites/${{ secrets.WEBAPP_NAME }}/extensions/onedeploy?api-version=2020-12-01"
az rest --method PUT \
--uri $SITE_URI \
--body '{
"properties": {
"packageUri": "'"${ZIP_URL}"'",
"type": "zip",
"ignorestack": false,
"clean": true,
"restart": false
}
}'
echo "::set-output name=deployment::$SITE_URI"
- name: Check if the deployment success
uses: azure/CLI@v1
with:
azcliversion: 2.33.1
inlineScript: |
echo "Install jq"
apk add jq
while true; do
STATUS=$(az rest --method GET --uri ${{ steps.deployment.outputs.deployment }} | jq '.value[0].properties.provisioningState')
if [[ "$STATUS" == "\"Succeeded\"" ]]; then
echo "Deployment succeeded"
break
elif [[ "$STATUS" == "\"Failed\"" ]]; then
echo "Deployment failed"
exit 1
else
echo "Deployment state: $STATUS..."
sleep 5
fi
done
Como ves, existe un primer trabajo, build, donde genero el paquete que quiero desplegar y en el apartado deploy es donde uso el mismo mecanismo mostrado en el artículo anterior, pero adaptado a GitHub Actions:
- Descargo el paquete generado en el paso anterior.
- Inicio sesión en Azure, con las credenciales almacenadas previamente en el secreto AZURE_CREDENTIALS.
- Hago un zip con el contenido del paquete.
- Lo subo a la cuenta de almacenamiento desde la que la extensión lo descargará.
- Genero una fecha con 30 minutos de más.
- Genero un SAS token, lo adjunto a la URL del paquete y lo utilizo como parte del body con el que llamo a la API REST para ejecutar el despliegue.
- Compruebo cada 5 segundos si el despliegue ha terminado satisfactoriamente, si ha fallado o continua.
¡Saludos!