@@ -3,97 +3,224 @@ name: Deploy (Windows)
33on :
44 workflow_call :
55 inputs :
6- azure_location :
7- description : ' Azure Location For Deployment'
8- required : false
9- default : ' australiaeast'
10- type : string
11- resource_group_name :
12- description : ' Resource Group Name (Optional)'
13- required : false
14- default : ' '
15- type : string
16- waf_enabled :
17- description : ' Enable WAF'
18- required : false
19- default : false
20- type : boolean
21- EXP :
22- description : ' Enable EXP'
23- required : false
24- default : false
25- type : boolean
26- build_docker_image :
27- description : ' Build And Push Docker Image (Optional)'
28- required : false
29- default : false
30- type : boolean
31- existing_webapp_url :
32- description : ' Existing WebApp URL (Skips Deployment)'
33- required : false
34- default : ' '
35- type : string
36- AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID :
37- description : ' Log Analytics Workspace ID (Optional)'
38- required : false
39- default : ' '
40- type : string
41- AZURE_EXISTING_AI_PROJECT_RESOURCE_ID :
42- description : ' AI Project Resource ID (Optional)'
43- required : false
44- default : ' '
45- type : string
46- docker_image_tag :
47- description : ' Docker image tag to deploy'
48- required : false
49- default : ' '
50- type : string
51- outputs :
52- WEB_APPURL :
53- description : ' Web App URL'
54- value : ${{ jobs.deploy.outputs.WEB_APPURL }}
55- RESOURCE_GROUP_NAME :
56- description : ' Resource Group Name'
57- value : ${{ jobs.deploy.outputs.RESOURCE_GROUP_NAME }}
58- AZURE_LOCATION :
59- description : ' Azure Location'
60- value : ${{ jobs.deploy.outputs.AZURE_LOCATION }}
61- AZURE_ENV_OPENAI_LOCATION :
62- description : ' Azure OpenAI Location'
63- value : ${{ jobs.deploy.outputs.AZURE_ENV_OPENAI_LOCATION }}
64- ENV_NAME :
65- description : ' Environment Name'
66- value : ${{ jobs.deploy.outputs.ENV_NAME }}
67- IMAGE_TAG :
68- description : ' Image tag used for deployment'
69- value : ${{ jobs.deploy.outputs.IMAGE_TAG }}
70- QUOTA_FAILED :
71- description : ' Quota failure flag'
72- value : ${{ jobs.deploy.outputs.QUOTA_FAILED }}
73-
74- jobs :
75- deploy :
76- runs-on : windows-latest
77- outputs :
78- WEB_APPURL : ${{ steps.set_outputs.outputs.WEB_APPURL }}
79- RESOURCE_GROUP_NAME : ${{ steps.set_outputs.outputs.RESOURCE_GROUP_NAME }}
80- AZURE_LOCATION : ${{ steps.set_outputs.outputs.AZURE_LOCATION }}
81- AZURE_ENV_OPENAI_LOCATION : ${{ steps.set_outputs.outputs.AZURE_ENV_OPENAI_LOCATION }}
82- ENV_NAME : ${{ steps.set_outputs.outputs.ENV_NAME }}
83- IMAGE_TAG : ${{ steps.set_outputs.outputs.IMAGE_TAG }}
84- QUOTA_FAILED : ${{ steps.set_outputs.outputs.QUOTA_FAILED }}
85- steps :
86- - name : Checkout
87- uses : actions/checkout@v4
88-
89- - name : Set outputs (placeholder)
90- id : set_outputs
91- shell : pwsh
92- run : |
93- $webUrl = if ([string]::IsNullOrEmpty('${{ inputs.existing_webapp_url }}')) { 'https://example.containers.app' } else { '${{ inputs.existing_webapp_url }}' }
94- echo "WEB_APPURL=$webUrl" >> $env:GITHUB_OUTPUT
95- echo "RESOURCE_GROUP_NAME=${{ inputs.resource_group_name }}" >> $env:GITHUB_OUTPUT
96- echo "AZURE_LOCATION=${{ inputs.azure_location }}" >> $env:GITHUB_OUTPUT
6+ jobs :
7+ deploy :
8+ runs-on : windows-latest
9+ outputs :
10+ WEB_APPURL : ${{ steps.set-outputs.outputs.WEB_APPURL }}
11+ RESOURCE_GROUP_NAME : ${{ steps.set-outputs.outputs.RESOURCE_GROUP_NAME }}
12+ AZURE_LOCATION : ${{ steps.set-outputs.outputs.AZURE_LOCATION }}
13+ AZURE_ENV_OPENAI_LOCATION : ${{ steps.set-outputs.outputs.AZURE_ENV_OPENAI_LOCATION }}
14+ ENV_NAME : ${{ steps.set-outputs.outputs.ENV_NAME }}
15+ IMAGE_TAG : ${{ steps.set-outputs.outputs.IMAGE_TAG }}
16+ QUOTA_FAILED : ${{ steps.set-outputs.outputs.QUOTA_FAILED }}
17+ steps :
18+ - name : Checkout
19+ name : Deploy (Windows)
20+
21+ on :
22+ workflow_call :
23+ inputs :
24+ azure_location :
25+ description : ' Azure Location For Deployment'
26+ required : false
27+ default : ' australiaeast'
28+ type : string
29+ resource_group_name :
30+ description : ' Resource Group Name (Optional)'
31+ required : false
32+ default : ' '
33+ type : string
34+ waf_enabled :
35+ description : ' Enable WAF'
36+ required : false
37+ default : false
38+ type : boolean
39+ EXP :
40+ description : ' Enable EXP'
41+ required : false
42+ default : false
43+ type : boolean
44+ build_docker_image :
45+ description : ' Build And Push Docker Image (Optional)'
46+ required : false
47+ default : false
48+ type : boolean
49+ existing_webapp_url :
50+ description : ' Existing WebApp URL (Skips Deployment)'
51+ required : false
52+ default : ' '
53+ type : string
54+ AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID :
55+ description : ' Log Analytics Workspace ID (Optional)'
56+ required : false
57+ default : ' '
58+ type : string
59+ AZURE_EXISTING_AI_PROJECT_RESOURCE_ID :
60+ description : ' AI Project Resource ID (Optional)'
61+ required : false
62+ default : ' '
63+ type : string
64+ docker_image_tag :
65+ description : ' Docker image tag to deploy'
66+ required : false
67+ default : ' '
68+ type : string
69+ outputs :
70+ WEB_APPURL :
71+ description : ' Web App URL'
72+ value : ${{ jobs.deploy.outputs.WEB_APPURL }}
73+ RESOURCE_GROUP_NAME :
74+ description : ' Resource Group Name'
75+ value : ${{ jobs.deploy.outputs.RESOURCE_GROUP_NAME }}
76+ AZURE_LOCATION :
77+ description : ' Azure Location'
78+ value : ${{ jobs.deploy.outputs.AZURE_LOCATION }}
79+ AZURE_ENV_OPENAI_LOCATION :
80+ description : ' Azure OpenAI Location'
81+ value : ${{ jobs.deploy.outputs.AZURE_ENV_OPENAI_LOCATION }}
82+ ENV_NAME :
83+ description : ' Environment Name'
84+ value : ${{ jobs.deploy.outputs.ENV_NAME }}
85+ IMAGE_TAG :
86+ description : ' Image tag used for deployment'
87+ value : ${{ jobs.deploy.outputs.IMAGE_TAG }}
88+ QUOTA_FAILED :
89+ description : ' Quota failure flag'
90+ value : ${{ jobs.deploy.outputs.QUOTA_FAILED }}
91+
92+ jobs :
93+ deploy :
94+ runs-on : windows-latest
95+ outputs :
96+ WEB_APPURL : ${{ steps.final.outputs.WEB_APPURL }}
97+ RESOURCE_GROUP_NAME : ${{ steps.final.outputs.RESOURCE_GROUP_NAME }}
98+ AZURE_LOCATION : ${{ steps.final.outputs.AZURE_LOCATION }}
99+ AZURE_ENV_OPENAI_LOCATION : ${{ steps.final.outputs.AZURE_ENV_OPENAI_LOCATION }}
100+ ENV_NAME : ${{ steps.final.outputs.ENV_NAME }}
101+ IMAGE_TAG : ${{ steps.final.outputs.IMAGE_TAG }}
102+ QUOTA_FAILED : ${{ steps.final.outputs.QUOTA_FAILED }}
103+ steps :
104+ - name : Checkout
105+ uses : actions/checkout@v4
106+
107+ - name : Install Azure CLI
108+ shell : pwsh
109+ run : |
110+ Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows -OutFile installazurecli.ps1
111+ pwsh -File ./installazurecli.ps1
112+ az --version
113+
114+ - name : Install Azure Developer CLI (azd)
115+ shell : pwsh
116+ run : |
117+ Invoke-WebRequest -Uri https://aka.ms/install-azd.ps1 -OutFile install-azd.ps1
118+ pwsh -File ./install-azd.ps1
119+ azd version
120+
121+ - name : Azure Login (Service Principal)
122+ shell : pwsh
123+ run : |
124+ az login --service-principal -u "${{ secrets.AZURE_CLIENT_ID }}" -p "${{ secrets.AZURE_CLIENT_SECRET }}" --tenant "${{ secrets.AZURE_TENANT_ID }}"
125+ az account set --subscription "${{ secrets.AZURE_SUBSCRIPTION_ID }}"
126+ azd auth login --client-id "${{ secrets.AZURE_CLIENT_ID }}" --client-secret "${{ secrets.AZURE_CLIENT_SECRET }}" --tenant-id "${{ secrets.AZURE_TENANT_ID }}"
127+ azd config set defaults.subscription "${{ secrets.AZURE_SUBSCRIPTION_ID }}"
128+
129+ - name : Initialize Deployment Context
130+ id : init
131+ shell : pwsh
132+ run : |
133+ $azureLocation = "${{ inputs.azure_location }}"
134+ $resourceGroup = "${{ inputs.resource_group_name }}"
135+ if ([string]::IsNullOrWhiteSpace($resourceGroup)) { $resourceGroup = "byo-copilot-${{ github.run_id }}-${{ github.run_number }}" }
136+ $envName = "byo-${{ github.run_id }}-${{ github.run_number }}"
137+ echo "AZURE_LOCATION=$azureLocation" >> $env:GITHUB_ENV
138+ echo "RESOURCE_GROUP_NAME=$resourceGroup" >> $env:GITHUB_ENV
139+ echo "ENV_NAME=$envName" >> $env:GITHUB_ENV
140+
141+ - name : Create/Select azd Environment
142+ shell : pwsh
143+ run : |
144+ $envName = "$env:ENV_NAME"
145+ $envs = azd env list | ConvertFrom-Json
146+ $exists = $false
147+ if ($envs) { $exists = $envs.environments | Where-Object { $_.name -eq $envName } }
148+ if ($exists) { azd env select $envName } else {
149+ azd env new $envName --no-prompt
150+ azd env set AZURE_RESOURCE_GROUP "$env:RESOURCE_GROUP_NAME"
151+ azd env set AZURE_SUBSCRIPTION_ID "${{ secrets.AZURE_SUBSCRIPTION_ID }}"
152+ azd env set AZURE_LOCATION "$env:AZURE_LOCATION"
153+ }
154+ if ("${{ inputs.AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID }}" -ne "") { azd env set AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID "${{ inputs.AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID }}" }
155+ if ("${{ inputs.AZURE_EXISTING_AI_PROJECT_RESOURCE_ID }}" -ne "") { azd env set AZURE_EXISTING_AI_PROJECT_RESOURCE_ID "${{ inputs.AZURE_EXISTING_AI_PROJECT_RESOURCE_ID }}" }
156+
157+ - name : Quota Check (simplified)
158+ id : quota
159+ shell : pwsh
160+ run : |
161+ echo "QUOTA_FAILED=false" >> $env:GITHUB_ENV
162+
163+ - name : Deploy with azd up
164+ if : ${{ inputs.existing_webapp_url == '' }}
165+ shell : pwsh
166+ run : |
167+ azd up --no-prompt
168+
169+ - name : Extract Outputs
170+ id : extract
171+ shell : pwsh
172+ run : |
173+ $values = azd env get-values
174+ $webUrl = ($values | Select-String '^WEBAPP_URL=' | ForEach-Object { $_.ToString().Split('=')[1] })
175+ if (-not $webUrl) { $webUrl = ($values | Select-String '^WEB_APPURL=' | ForEach-Object { $_.ToString().Split('=')[1] }) }
176+ echo "WEB_APPURL=$webUrl" >> $env:GITHUB_ENV
177+ echo "IMAGE_TAG=${{ inputs.docker_image_tag }}" >> $env:GITHUB_ENV
178+
179+ - name : Finalize outputs
180+ id : final
181+ shell : pwsh
182+ run : |
183+ echo "WEB_APPURL=$env:WEB_APPURL" >> $env:GITHUB_OUTPUT
184+ echo "RESOURCE_GROUP_NAME=$env:RESOURCE_GROUP_NAME" >> $env:GITHUB_OUTPUT
185+ echo "AZURE_LOCATION=$env:AZURE_LOCATION" >> $env:GITHUB_OUTPUT
186+ echo "AZURE_ENV_OPENAI_LOCATION=$env:AZURE_LOCATION" >> $env:GITHUB_OUTPUT
187+ echo "ENV_NAME=$env:ENV_NAME" >> $env:GITHUB_OUTPUT
188+ echo "IMAGE_TAG=$env:IMAGE_TAG" >> $env:GITHUB_OUTPUT
189+ echo "QUOTA_FAILED=$env:QUOTA_FAILED" >> $env:GITHUB_OUTPUT
190+ if ([string]::IsNullOrWhiteSpace("${{ steps.outputs.outputs.WEB_APPURL }}")) { exit 0 }
191+ $rg = "$env:RESOURCE_GROUP_NAME"
192+ $appName = ("${{ steps.outputs.outputs.WEB_APPURL }}" -replace '^https?://', '' -replace '/.*$', '')
193+ $principalId = az webapp identity show -g $rg -n $appName --query principalId -o tsv
194+ $acrName = "${{ secrets.ACR_TEST_LOGIN_SERVER }}".Split('.')[0]
195+ $acrId = az acr show --name $acrName --query id -o tsv
196+ az role assignment create --assignee $principalId --role "AcrPull" --scope $acrId
197+
198+ - name : Set Container Image (optional)
199+ if : ${{ inputs.build_docker_image == true && inputs.docker_image_tag != '' }}
200+ shell : pwsh
201+ run : |
202+ $acr = "${{ secrets.ACR_TEST_LOGIN_SERVER }}"
203+ $tag = "${{ inputs.docker_image_tag }}"
204+ $full = "$acr/webapp:$tag"
205+ $rg = "$env:RESOURCE_GROUP_NAME"
206+ $appName = ("${{ steps.outputs.outputs.WEB_APPURL }}" -replace '^https?://', '' -replace '/.*$', '')
207+ az webapp config container set --name $appName --resource-group $rg --docker-custom-image-name $full --docker-registry-server-url "https://$acr"
208+ az webapp restart --name $appName --resource-group $rg
209+
210+ - name : Install SQL Tools (sqlcmd)
211+ shell : pwsh
212+ run : |
213+ Set-ExecutionPolicy Bypass -Scope Process -Force
214+ winget install --id Microsoft.AzureDataCLI -e --source winget || Write-Host "Azure Data CLI via winget optional"
215+ winget install --id Microsoft.Sqlcmd -e --source winget || Write-Host "sqlcmd via winget optional"
216+
217+ - name : Post-deploy: Sample data import (optional)
218+ shell : pwsh
219+ run : |
220+ if (Test-Path "infra/scripts/process_sample_data_v2.sh") {
221+ bash "infra/scripts/process_sample_data_v2.sh" "$env:RESOURCE_GROUP_NAME" "${{ secrets.AZURE_CLIENT_ID }}"
222+ }
223+
97224 echo "AZURE_ENV_OPENAI_LOCATION=${{ inputs.azure_location }}" >> $env:GITHUB_OUTPUT
98225 echo "ENV_NAME=env-${{ github.run_id }}" >> $env:GITHUB_OUTPUT
99226 echo "IMAGE_TAG=${{ inputs.docker_image_tag }}" >> $env:GITHUB_OUTPUT
0 commit comments