如何在Azure为React应用创建拉取请求(PR)动态部署环境
React 应用 Azure PR 动态部署槽实现方案
你倾向的App Service部署槽方案完全可以适配React技术栈,只需在现有配置基础上补充React构建逻辑、静态站点适配规则和PR关闭删除触发逻辑即可,完整实现步骤如下:
1. 补充React应用构建阶段配置
在现有部署任务前增加构建阶段,完成React依赖安装、生产构建和产物打包:
jobs: - job: BuildReactApp displayName: "构建React应用产物" pool: vmImage: ubuntu-latest steps: - task: NodeTool@0 displayName: "指定Node.js版本" inputs: versionSpec: '18.x' # 匹配你项目兼容的Node版本 - script: | npm install npm run build displayName: "安装依赖并构建生产版本" workingDirectory: $(Build.SourcesDirectory) # 换成你React项目package.json所在的路径 # 可选:添加web.config解决React路由刷新404问题(适用于Windows运行环境的App Service) - script: | echo '<?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <rewrite> <rules> <rule name="React Routes" stopProcessing="true"> <match url=".*" /> <conditions logicalGrouping="MatchAll"> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /> </conditions> <action type="Rewrite" url="/" /> </rule> </rules> </rewrite> </system.webServer> </configuration>' > build/web.config displayName: "添加静态站点路由规则" workingDirectory: $(Build.SourcesDirectory) - task: ArchiveFiles@2 displayName: "打包构建产物" inputs: rootFolderOrFile: '$(Build.SourcesDirectory)/build' # 对应React build输出目录 includeRootFolder: false archiveType: 'zip' archiveFile: '$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip' replaceExistingArchive: true - task: PublishPipelineArtifact@1 displayName: "上传构建产物" inputs: targetPath: '$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip' artifact: '$(Build.BuildId)' publishLocation: 'Container'
2. 修正现有部署任务配置
你现有配置中存在部署槽名称与应用名不匹配的问题,调整后如下:
- deployment: DeployWebServiceApp displayName: "部署React应用到PR专属槽" environment: ${{parameters.environment}} pool: vmImage: ubuntu-latest dependsOn: BuildReactApp condition: eq(variables['Build.Reason'], 'PullRequest') # 仅PR触发时执行部署 strategy: runOnce: deploy: steps: - task: DownloadPipelineArtifact@2 displayName: '下载构建产物' inputs: artifactName: "$(Build.BuildId)" buildType: 'current' - task: AzureCLI@2 displayName: '创建PR专属部署槽' inputs: azureSubscription: "${{parameters.serviceConnection}}" scriptType: bash scriptLocation: inlineScript inlineScript: | # 判断槽是否存在,不存在则创建 slot_exists=$(az webapp deployment slot exists --name ${{parameters.appServiceName}} --resource-group ${{parameters.resourceGroupName}} --slot $(prLC) --query "exists" -o tsv) if [ "$slot_exists" != "true" ]; then az webapp deployment slot create --name ${{parameters.appServiceName}} --resource-group ${{parameters.resourceGroupName}} --slot $(prLC) --configuration-source ${{parameters.appServiceName}} fi - task: AzureRmWebAppDeployment@4 # 建议升级到V4版本兼容性更好 displayName: '部署React应用到对应槽' inputs: azureSubscription: "${{parameters.serviceConnection}}" appName: "${{parameters.appServiceName}}" DeployToSlotFlag: true ResourceGroupName: '${{parameters.resourceGroupName}}' SlotName: '$(prLC)' package: '$(Pipeline.Workspace)/$(Build.BuildId)/$(Build.BuildId).zip' RemoveAdditionalFilesFlag: true
3. 新增PR关闭时自动删除部署槽的流水线
单独配置一条触发条件为PR关闭的流水线,执行删除操作:
trigger: none pr: branches: include: - main # 对应你需要监听的目标分支 types: - Closed # 仅PR关闭时触发 jobs: - job: DeletePRSlot displayName: "删除PR专属部署槽" pool: vmImage: ubuntu-latest steps: - task: AzureCLI@2 displayName: '删除对应部署槽' inputs: azureSubscription: "${{parameters.serviceConnection}}" scriptType: bash scriptLocation: inlineScript inlineScript: | slot_exists=$(az webapp deployment slot exists --name ${{parameters.appServiceName}} --resource-group ${{parameters.resourceGroupName}} --slot $(prLC) --query "exists" -o tsv) if [ "$slot_exists" = "true" ]; then az webapp deployment slot delete --name ${{parameters.appServiceName}} --resource-group ${{parameters.resourceGroupName}} --slot $(prLC) fi
注意事项
- 需要提前在流水线变量中定义
prLC变量,取值为PR编号的小写格式,可通过prLC=$(echo $(System.PullRequest.PullRequestId) | tr '[:upper:]' '[:lower:]')生成 - 如果你的App Service用的是Linux静态站点方案,无需添加web.config,直接在应用配置中设置启动命令为
npx serve -s build即可
内容的提问来源于stack exchange,提问作者arunmmanoharan
相关产品推荐
相关产品推荐

