Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions .github/DEPLOYMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# GitHub Pages 部署说明

本项目已配置自动部署 Blazor WebAssembly 应用到 GitHub Pages。

## 启用 GitHub Pages

### 步骤 1: 配置 Pages 设置
1. 进入仓库 **Settings** 页面
2. 在左侧菜单找到 **Pages** 选项
3. 在 **Source** 下拉框选择 **GitHub Actions**
4. 保存设置

### 步骤 2: 触发部署
部署会在以下情况自动触发:
- 推送到 `main` 分支
- 推送到 `copilot/add-room-management-capabilities` 分支
- 手动触发(Actions 标签 → "Deploy Web App to GitHub Pages" → "Run workflow")

## 查看部署状态

1. 进入仓库的 **Actions** 标签
2. 查看 "Deploy Web App to GitHub Pages" 工作流
3. 点击最新的运行查看详细日志

## 访问部署的应用

部署成功后,应用将在以下地址可用:
```
https://<username>.github.io/Audio3A_CSharp/
```

例如:`https://gmij.github.io/Audio3A_CSharp/`

## 工作流说明

工作流文件:`.github/workflows/deploy-web.yml`

### 构建步骤
1. **Checkout** - 检出代码
2. **Setup .NET** - 安装 .NET 8 SDK
3. **Restore** - 恢复 Web 项目依赖
4. **Build** - 构建 Release 版本
5. **Publish** - 发布 Blazor 应用
6. **Change base-tag** - 修改 index.html 的 base 标签以适配 GitHub Pages 子路径
7. **Copy 404.html** - 复制 404.html 用于 SPA 路由支持
8. **Add .nojekyll** - 添加 .nojekyll 文件防止 Jekyll 处理
9. **Upload artifact** - 上传构建产物

### 部署步骤
1. **Deploy to GitHub Pages** - 部署到 GitHub Pages

### SPA 路由支持

Blazor WebAssembly 是单页应用(SPA),所有路由都在客户端处理。为了在 GitHub Pages 上正确支持客户端路由:

1. **404.html** - 当用户直接访问子路由(如 `/Audio3A_CSharp/rooms`)时,GitHub Pages 会返回 404 错误。404.html 会捕获这个请求并重定向到 index.html,同时保留原始路径。

2. **index.html 重定向脚本** - index.html 中的脚本会检测从 404.html 传来的重定向参数,并使用 `history.replaceState` 恢复原始 URL,这样 Blazor Router 就能正确处理路由。

3. **base 标签** - 设置为 `/Audio3A_CSharp/` 确保所有资源路径正确。

这种方案使得用户可以:
- 直接访问任何页面 URL(如 `https://gmij.github.io/Audio3A_CSharp/rooms`)
- 刷新页面不会丢失当前路由
- 在应用内导航正常工作

## 本地测试部署构建

```bash
# 1. 恢复依赖
dotnet restore samples/Audio3A.Web/Audio3A.Web.csproj

# 2. 构建 Release 版本
dotnet build samples/Audio3A.Web/Audio3A.Web.csproj --configuration Release --no-restore

# 3. 发布应用
dotnet publish samples/Audio3A.Web/Audio3A.Web.csproj -c Release -o ./publish --nologo

# 4. 修改 base 标签(用于 GitHub Pages)
sed -i 's/<base href="\/" \/>/<base href="\/Audio3A_CSharp\/" \/>/g' ./publish/wwwroot/index.html

# 5. 添加 .nojekyll 文件
touch ./publish/wwwroot/.nojekyll

# 6. 查看发布结果
ls -la ./publish/wwwroot/
```

## 故障排查

### 部署失败
1. 检查 Actions 日志中的错误信息
2. 确保 Pages 设置正确(Source: GitHub Actions)
3. 确保仓库有 Pages 权限

### 应用无法访问
1. 检查 URL 是否正确(包含仓库名称)
2. 等待几分钟让部署完全生效
3. 清除浏览器缓存并刷新

### 页面显示空白
1. 检查浏览器控制台的错误信息
2. 确认 base 标签路径正确
3. 检查资源文件是否正确加载

## 注意事项

- **base 标签**:GitHub Pages 部署的应用需要修改 base 标签以匹配子路径
- **.nojekyll**:添加此文件防止 Jekyll 处理 Blazor 文件
- **API 访问**:发布的 Web 应用为静态文件,需要配置 API 地址到实际的后端服务

## 相关文档

- [GitHub Pages 文档](https://docs.github.com/pages)
- [Blazor WebAssembly 部署](https://learn.microsoft.com/aspnet/core/blazor/host-and-deploy/webassembly)
- [GitHub Actions 工作流语法](https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions)
61 changes: 61 additions & 0 deletions .github/workflows/deploy-web.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Deploy Web App to GitHub Pages

on:
push:
branches: [ main, copilot/add-room-management-capabilities ]
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: "pages"
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x

- name: Restore Web App dependencies
run: dotnet restore samples/Audio3A.Web/Audio3A.Web.csproj

- name: Build Web App
run: dotnet build samples/Audio3A.Web/Audio3A.Web.csproj --configuration Release --no-restore

- name: Publish Web App
run: dotnet publish samples/Audio3A.Web/Audio3A.Web.csproj -c Release -o release --nologo

- name: Change base-tag in index.html for GitHub Pages
run: sed -i 's/<base href="\/" \/>/<base href="\/Audio3A_CSharp\/" \/>/g' release/wwwroot/index.html

- name: Copy 404.html for SPA routing
run: cp release/wwwroot/404.html release/wwwroot/404.html || echo "404.html already exists"

- name: Add .nojekyll file
run: touch release/wwwroot/.nojekyll

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: release/wwwroot

deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
75 changes: 75 additions & 0 deletions Audio3A.sln
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{0AB3BF05
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Audio3A.Tests", "tests\Audio3A.Tests\Audio3A.Tests.csproj", "{F3700569-916D-414D-A16B-C7DD2DE34404}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Audio3A.RoomManagement", "src\Audio3A.RoomManagement\Audio3A.RoomManagement.csproj", "{90AB03DE-806D-437D-8B62-E6F9D79A2FB3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Audio3A.RoomDemo", "samples\Audio3A.RoomDemo\Audio3A.RoomDemo.csproj", "{79760786-404E-4F1A-905C-8EE535F2AA78}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Audio3A.RoomManagement.Tests", "tests\Audio3A.RoomManagement.Tests\Audio3A.RoomManagement.Tests.csproj", "{5E462363-0AE5-424D-9C96-DE6DFD7B445B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Audio3A.Web", "samples\Audio3A.Web\Audio3A.Web.csproj", "{D6473D6A-EC85-41A1-BDB4-9015D9F3119E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Audio3A.WebApi", "samples\Audio3A.WebApi\Audio3A.WebApi.csproj", "{70DB5914-D560-454B-8C04-BBD2233CE8A4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -61,6 +71,66 @@ Global
{F3700569-916D-414D-A16B-C7DD2DE34404}.Release|x64.Build.0 = Release|Any CPU
{F3700569-916D-414D-A16B-C7DD2DE34404}.Release|x86.ActiveCfg = Release|Any CPU
{F3700569-916D-414D-A16B-C7DD2DE34404}.Release|x86.Build.0 = Release|Any CPU
{90AB03DE-806D-437D-8B62-E6F9D79A2FB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{90AB03DE-806D-437D-8B62-E6F9D79A2FB3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{90AB03DE-806D-437D-8B62-E6F9D79A2FB3}.Debug|x64.ActiveCfg = Debug|Any CPU
{90AB03DE-806D-437D-8B62-E6F9D79A2FB3}.Debug|x64.Build.0 = Debug|Any CPU
{90AB03DE-806D-437D-8B62-E6F9D79A2FB3}.Debug|x86.ActiveCfg = Debug|Any CPU
{90AB03DE-806D-437D-8B62-E6F9D79A2FB3}.Debug|x86.Build.0 = Debug|Any CPU
{90AB03DE-806D-437D-8B62-E6F9D79A2FB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{90AB03DE-806D-437D-8B62-E6F9D79A2FB3}.Release|Any CPU.Build.0 = Release|Any CPU
{90AB03DE-806D-437D-8B62-E6F9D79A2FB3}.Release|x64.ActiveCfg = Release|Any CPU
{90AB03DE-806D-437D-8B62-E6F9D79A2FB3}.Release|x64.Build.0 = Release|Any CPU
{90AB03DE-806D-437D-8B62-E6F9D79A2FB3}.Release|x86.ActiveCfg = Release|Any CPU
{90AB03DE-806D-437D-8B62-E6F9D79A2FB3}.Release|x86.Build.0 = Release|Any CPU
{79760786-404E-4F1A-905C-8EE535F2AA78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{79760786-404E-4F1A-905C-8EE535F2AA78}.Debug|Any CPU.Build.0 = Debug|Any CPU
{79760786-404E-4F1A-905C-8EE535F2AA78}.Debug|x64.ActiveCfg = Debug|Any CPU
{79760786-404E-4F1A-905C-8EE535F2AA78}.Debug|x64.Build.0 = Debug|Any CPU
{79760786-404E-4F1A-905C-8EE535F2AA78}.Debug|x86.ActiveCfg = Debug|Any CPU
{79760786-404E-4F1A-905C-8EE535F2AA78}.Debug|x86.Build.0 = Debug|Any CPU
{79760786-404E-4F1A-905C-8EE535F2AA78}.Release|Any CPU.ActiveCfg = Release|Any CPU
{79760786-404E-4F1A-905C-8EE535F2AA78}.Release|Any CPU.Build.0 = Release|Any CPU
{79760786-404E-4F1A-905C-8EE535F2AA78}.Release|x64.ActiveCfg = Release|Any CPU
{79760786-404E-4F1A-905C-8EE535F2AA78}.Release|x64.Build.0 = Release|Any CPU
{79760786-404E-4F1A-905C-8EE535F2AA78}.Release|x86.ActiveCfg = Release|Any CPU
{79760786-404E-4F1A-905C-8EE535F2AA78}.Release|x86.Build.0 = Release|Any CPU
{5E462363-0AE5-424D-9C96-DE6DFD7B445B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5E462363-0AE5-424D-9C96-DE6DFD7B445B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E462363-0AE5-424D-9C96-DE6DFD7B445B}.Debug|x64.ActiveCfg = Debug|Any CPU
{5E462363-0AE5-424D-9C96-DE6DFD7B445B}.Debug|x64.Build.0 = Debug|Any CPU
{5E462363-0AE5-424D-9C96-DE6DFD7B445B}.Debug|x86.ActiveCfg = Debug|Any CPU
{5E462363-0AE5-424D-9C96-DE6DFD7B445B}.Debug|x86.Build.0 = Debug|Any CPU
{5E462363-0AE5-424D-9C96-DE6DFD7B445B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5E462363-0AE5-424D-9C96-DE6DFD7B445B}.Release|Any CPU.Build.0 = Release|Any CPU
{5E462363-0AE5-424D-9C96-DE6DFD7B445B}.Release|x64.ActiveCfg = Release|Any CPU
{5E462363-0AE5-424D-9C96-DE6DFD7B445B}.Release|x64.Build.0 = Release|Any CPU
{5E462363-0AE5-424D-9C96-DE6DFD7B445B}.Release|x86.ActiveCfg = Release|Any CPU
{5E462363-0AE5-424D-9C96-DE6DFD7B445B}.Release|x86.Build.0 = Release|Any CPU
{D6473D6A-EC85-41A1-BDB4-9015D9F3119E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D6473D6A-EC85-41A1-BDB4-9015D9F3119E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D6473D6A-EC85-41A1-BDB4-9015D9F3119E}.Debug|x64.ActiveCfg = Debug|Any CPU
{D6473D6A-EC85-41A1-BDB4-9015D9F3119E}.Debug|x64.Build.0 = Debug|Any CPU
{D6473D6A-EC85-41A1-BDB4-9015D9F3119E}.Debug|x86.ActiveCfg = Debug|Any CPU
{D6473D6A-EC85-41A1-BDB4-9015D9F3119E}.Debug|x86.Build.0 = Debug|Any CPU
{D6473D6A-EC85-41A1-BDB4-9015D9F3119E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D6473D6A-EC85-41A1-BDB4-9015D9F3119E}.Release|Any CPU.Build.0 = Release|Any CPU
{D6473D6A-EC85-41A1-BDB4-9015D9F3119E}.Release|x64.ActiveCfg = Release|Any CPU
{D6473D6A-EC85-41A1-BDB4-9015D9F3119E}.Release|x64.Build.0 = Release|Any CPU
{D6473D6A-EC85-41A1-BDB4-9015D9F3119E}.Release|x86.ActiveCfg = Release|Any CPU
{D6473D6A-EC85-41A1-BDB4-9015D9F3119E}.Release|x86.Build.0 = Release|Any CPU
{70DB5914-D560-454B-8C04-BBD2233CE8A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{70DB5914-D560-454B-8C04-BBD2233CE8A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{70DB5914-D560-454B-8C04-BBD2233CE8A4}.Debug|x64.ActiveCfg = Debug|Any CPU
{70DB5914-D560-454B-8C04-BBD2233CE8A4}.Debug|x64.Build.0 = Debug|Any CPU
{70DB5914-D560-454B-8C04-BBD2233CE8A4}.Debug|x86.ActiveCfg = Debug|Any CPU
{70DB5914-D560-454B-8C04-BBD2233CE8A4}.Debug|x86.Build.0 = Debug|Any CPU
{70DB5914-D560-454B-8C04-BBD2233CE8A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{70DB5914-D560-454B-8C04-BBD2233CE8A4}.Release|Any CPU.Build.0 = Release|Any CPU
{70DB5914-D560-454B-8C04-BBD2233CE8A4}.Release|x64.ActiveCfg = Release|Any CPU
{70DB5914-D560-454B-8C04-BBD2233CE8A4}.Release|x64.Build.0 = Release|Any CPU
{70DB5914-D560-454B-8C04-BBD2233CE8A4}.Release|x86.ActiveCfg = Release|Any CPU
{70DB5914-D560-454B-8C04-BBD2233CE8A4}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -69,5 +139,10 @@ Global
{A69AE121-65C6-4820-B8A1-0CB47D1FF0AA} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
{B2996C6C-D71D-48A0-B440-4DA15B20D1F4} = {5D20AA90-6969-D8BD-9DCD-8634F4692FDA}
{F3700569-916D-414D-A16B-C7DD2DE34404} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
{90AB03DE-806D-437D-8B62-E6F9D79A2FB3} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
{79760786-404E-4F1A-905C-8EE535F2AA78} = {5D20AA90-6969-D8BD-9DCD-8634F4692FDA}
{5E462363-0AE5-424D-9C96-DE6DFD7B445B} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
{D6473D6A-EC85-41A1-BDB4-9015D9F3119E} = {5D20AA90-6969-D8BD-9DCD-8634F4692FDA}
{70DB5914-D560-454B-8C04-BBD2233CE8A4} = {5D20AA90-6969-D8BD-9DCD-8634F4692FDA}
EndGlobalSection
EndGlobal
Loading
Loading