Skip to content

Commit 2299f33

Browse files
committed
ci(docker): 并行构建 + GHA 层缓存,大幅缩短镜像构建时间
- docker-image.yml 拆分 backend/web 并行 job,互不排队 - 两个 workflow 的 build-push-action 全部接入 Buildx GHA 缓存 (scope=backend/web 跨 workflow 共享,首次冷启动后复用 apt/pip/restore/npm 层) - 后端 Dockerfile 移除 build+publish 双重编译,改为单次 dotnet publish --no-restore - 版本提取由 pwsh 冷启动(约16s)改为 bash(约1s) - .dockerignore 排除 docs/tests/scripts 等非构建目录, 避免其变动打碎 COPY . . 缓存层
1 parent c542453 commit 2299f33

4 files changed

Lines changed: 82 additions & 31 deletions

File tree

‎.dockerignore‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,18 @@ data/
2424
**/values.dev.yaml
2525
LICENSE
2626
README.md
27+
# 以下目录不参与镜像构建;排除后其变动不会打碎 COPY . . 的缓存层
28+
docs/
29+
img/
30+
tests/
31+
scripts/
32+
DatabaseQuery/
33+
.github/
34+
.plan/
35+
.claude/
36+
.serena/
37+
.spec-workflow/
38+
.next-cowork/
39+
compose.yaml
40+
compose.pgsql.yaml
41+
Makefile

‎.github/workflows/docker-image.yml‎

Lines changed: 56 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ on:
33
workflow_dispatch:
44
push:
55
branches: [ main ]
6+
67
jobs:
7-
build:
8+
# 后端与前端镜像并行构建,互不阻塞
9+
backend:
810
runs-on: ubuntu-latest
911
steps:
1012
- uses: actions/checkout@v4
@@ -21,31 +23,21 @@ jobs:
2123

2224
- name: Extract version from Directory.Packages.props
2325
id: get_version
24-
shell: pwsh
26+
shell: bash
2527
run: |
26-
$ErrorActionPreference = 'Stop'
27-
[xml]$xml = Get-Content -Raw 'Directory.Packages.props'
28-
$pg = $xml.Project.PropertyGroup
29-
$versionTemplate = [string]$pg.Version
30-
if ([string]::IsNullOrWhiteSpace($versionTemplate)) { throw 'Version not found in Directory.Packages.props' }
31-
$props = @{}
32-
foreach ($n in $pg.ChildNodes) {
33-
if ($n.NodeType -eq [System.Xml.XmlNodeType]::Element) {
34-
$props[$n.Name] = [string]$n.InnerText
35-
}
36-
}
37-
$props['TimeStamp'] = (Get-Date -AsUTC).ToString('yyyyMMdd')
38-
$unresolved = New-Object System.Collections.Generic.List[string]
39-
$finalVersion = [regex]::Replace($versionTemplate, '\$\(([A-Za-z0-9_.-]+)\)', {
40-
param($m)
41-
$name = $m.Groups[1].Value
42-
if ($props.ContainsKey($name) -and -not [string]::IsNullOrWhiteSpace($props[$name])) { $props[$name] } else { $unresolved.Add($name) | Out-Null; '' }
43-
})
44-
if ($unresolved.Count -gt 0) { Write-Host "[warn] Unresolved version tokens -> $($unresolved -join ', ')" }
45-
if ([string]::IsNullOrWhiteSpace($finalVersion)) { throw 'Resolved version is empty' }
46-
"version=$finalVersion" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
47-
Write-Host "Version template: $versionTemplate"
48-
Write-Host "Final version: $finalVersion"
28+
version="$(sed -n 's/.*<Version>\(.*\)<\/Version>.*/\1/p' Directory.Packages.props | head -1 | tr -d '[:space:]')"
29+
if [ -z "$version" ]; then
30+
echo "Version not found in Directory.Packages.props" >&2
31+
exit 1
32+
fi
33+
case "$version" in
34+
*'$('*)
35+
echo "Unresolved version token in template: $version" >&2
36+
exit 1
37+
;;
38+
esac
39+
echo "version=$version" >> "$GITHUB_OUTPUT"
40+
echo "Final version: $version"
4941
5042
- name: Build and push opendeepwiki
5143
uses: docker/build-push-action@v5
@@ -56,10 +48,47 @@ jobs:
5648
push: true
5749
provenance: false
5850
sbom: false
51+
# GHA 层缓存:apt/pip、restore、编译层在多次构建间复用
52+
# scope 与 release.yml 保持一致,可跨 workflow 共享缓存
53+
cache-from: type=gha,scope=backend
54+
cache-to: type=gha,mode=max,scope=backend
5955
tags: |
6056
crpi-j9ha7sxwhatgtvj4.cn-shenzhen.personal.cr.aliyuncs.com/open-deepwiki/opendeepwiki:latest
6157
crpi-j9ha7sxwhatgtvj4.cn-shenzhen.personal.cr.aliyuncs.com/open-deepwiki/opendeepwiki:${{ steps.get_version.outputs.version }}
6258
59+
web:
60+
runs-on: ubuntu-latest
61+
steps:
62+
- uses: actions/checkout@v4
63+
64+
- name: Set up Docker Buildx
65+
uses: docker/setup-buildx-action@v3
66+
67+
- name: Login to Docker Registry
68+
uses: docker/login-action@v3
69+
with:
70+
registry: crpi-j9ha7sxwhatgtvj4.cn-shenzhen.personal.cr.aliyuncs.com
71+
username: ${{ secrets.DOCKER_USERNAME }}
72+
password: ${{ secrets.DOCKER_PASSWORD }}
73+
74+
- name: Extract version from Directory.Packages.props
75+
id: get_version
76+
shell: bash
77+
run: |
78+
version="$(sed -n 's/.*<Version>\(.*\)<\/Version>.*/\1/p' Directory.Packages.props | head -1 | tr -d '[:space:]')"
79+
if [ -z "$version" ]; then
80+
echo "Version not found in Directory.Packages.props" >&2
81+
exit 1
82+
fi
83+
case "$version" in
84+
*'$('*)
85+
echo "Unresolved version token in template: $version" >&2
86+
exit 1
87+
;;
88+
esac
89+
echo "version=$version" >> "$GITHUB_OUTPUT"
90+
echo "Final version: $version"
91+
6392
- name: Build and push opendeepwiki-web
6493
uses: docker/build-push-action@v5
6594
with:
@@ -69,6 +98,8 @@ jobs:
6998
push: true
7099
provenance: false
71100
sbom: false
101+
cache-from: type=gha,scope=web
102+
cache-to: type=gha,mode=max,scope=web
72103
tags: |
73104
crpi-j9ha7sxwhatgtvj4.cn-shenzhen.personal.cr.aliyuncs.com/open-deepwiki/opendeepwiki-web:latest
74105
crpi-j9ha7sxwhatgtvj4.cn-shenzhen.personal.cr.aliyuncs.com/open-deepwiki/opendeepwiki-web:${{ steps.get_version.outputs.version }}

‎.github/workflows/release.yml‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ jobs:
7878
push: true
7979
provenance: false
8080
sbom: false
81+
cache-from: type=gha,scope=backend
82+
cache-to: type=gha,mode=max,scope=backend
8183
tags: |
8284
crpi-j9ha7sxwhatgtvj4.cn-shenzhen.personal.cr.aliyuncs.com/open-deepwiki/opendeepwiki:latest
8385
crpi-j9ha7sxwhatgtvj4.cn-shenzhen.personal.cr.aliyuncs.com/open-deepwiki/opendeepwiki:${{ steps.get_version.outputs.version }}
@@ -91,6 +93,8 @@ jobs:
9193
push: true
9294
provenance: false
9395
sbom: false
96+
cache-from: type=gha,scope=web
97+
cache-to: type=gha,mode=max,scope=web
9498
tags: |
9599
crpi-j9ha7sxwhatgtvj4.cn-shenzhen.personal.cr.aliyuncs.com/open-deepwiki/opendeepwiki-web:latest
96100
crpi-j9ha7sxwhatgtvj4.cn-shenzhen.personal.cr.aliyuncs.com/open-deepwiki/opendeepwiki-web:${{ steps.get_version.outputs.version }}
@@ -134,6 +138,8 @@ jobs:
134138
push: true
135139
provenance: false
136140
sbom: false
141+
cache-from: type=gha,scope=backend
142+
cache-to: type=gha,mode=max,scope=backend
137143
tags: |
138144
crpi-j9ha7sxwhatgtvj4.cn-shenzhen.personal.cr.aliyuncs.com/open-deepwiki/opendeepwiki:latest
139145
crpi-j9ha7sxwhatgtvj4.cn-shenzhen.personal.cr.aliyuncs.com/open-deepwiki/opendeepwiki:${{ steps.get_version.outputs.version }}
@@ -147,6 +153,8 @@ jobs:
147153
push: true
148154
provenance: false
149155
sbom: false
156+
cache-from: type=gha,scope=web
157+
cache-to: type=gha,mode=max,scope=web
150158
tags: |
151159
crpi-j9ha7sxwhatgtvj4.cn-shenzhen.personal.cr.aliyuncs.com/open-deepwiki/opendeepwiki-web:latest
152160
crpi-j9ha7sxwhatgtvj4.cn-shenzhen.personal.cr.aliyuncs.com/open-deepwiki/opendeepwiki-web:${{ steps.get_version.outputs.version }}

‎src/OpenDeepWiki/Dockerfile‎

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,10 @@ COPY ["src/EFCore/OpenDeepWiki.Postgresql/OpenDeepWiki.Postgresql.csproj", "src/
2424
RUN dotnet restore "src/OpenDeepWiki/OpenDeepWiki.csproj"
2525
COPY . .
2626
WORKDIR "/src/src/OpenDeepWiki"
27-
RUN dotnet build "./OpenDeepWiki.csproj" -c $BUILD_CONFIGURATION -o /app/build
28-
29-
FROM build AS publish
30-
ARG BUILD_CONFIGURATION=Release
31-
RUN dotnet publish "./OpenDeepWiki.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
27+
# publish 自带编译;--no-restore 复用上方 restore 层,整个流程只编译一次
28+
RUN dotnet publish "./OpenDeepWiki.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false --no-restore
3229

3330
FROM base AS final
3431
WORKDIR /app
35-
COPY --from=publish /app/publish .
32+
COPY --from=build /app/publish .
3633
ENTRYPOINT ["dotnet", "OpenDeepWiki.dll"]

0 commit comments

Comments
 (0)