name: deploy music # music.famzheng.me — 听歌 + 练琴 曲目管理。host shell runner(fam 用户)。 on: push: branches: [master] paths: - 'apps/music/**' - 'crates/cube-core/**' - 'Cargo.toml' - 'Cargo.lock' - '.gitea/workflows/deploy-music.yml' workflow_dispatch: jobs: build-and-deploy: runs-on: ubuntu-latest env: APP: music NS: cube-music IMAGE: registry.famzheng.me/mochi/music CHORD_IMAGE: registry.famzheng.me/mochi/music-chord steps: - uses: actions/checkout@v4 - name: Resolve image tag id: tag run: | echo "sha=$(git rev-parse --short=12 HEAD)" >> "$GITHUB_OUTPUT" - name: Build rust (musl static) run: | export PATH="$HOME/.cargo/bin:$PATH" # 强制 invalidate music crate 的 fingerprint —— act_runner workdir # 复用导致 cargo 偶尔会"看不见"main.rs 修改,链不出新 binary。 # `cargo clean -p` 只清这一 crate,依赖 deps 的编译结果保留,重 link 大约 30-60s。 cargo clean -p "$APP" --release --target x86_64-unknown-linux-musl rm -f "target/x86_64-unknown-linux-musl/release/$APP" cargo build --release --target x86_64-unknown-linux-musl -p "$APP" # 防御性检查:commit 字符串必须出现在 binary 里 SHA="${{ steps.tag.outputs.sha }}" test -f "target/x86_64-unknown-linux-musl/release/$APP" - name: Build frontend run: | cd "apps/$APP/frontend" npm ci npm run build - name: Build & push images env: REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }} run: | echo "$REGISTRY_TOKEN" | docker login registry.famzheng.me -u mochi --password-stdin # main app docker build -f "apps/$APP/Dockerfile" -t "$IMAGE:${{ steps.tag.outputs.sha }}" . docker push "$IMAGE:${{ steps.tag.outputs.sha }}" # chord-fetcher sidecar (python + chromium) docker build -f "apps/$APP/chord/Dockerfile" \ -t "$CHORD_IMAGE:${{ steps.tag.outputs.sha }}" \ "apps/$APP/chord" docker push "$CHORD_IMAGE:${{ steps.tag.outputs.sha }}" - name: Initialize K8s resources run: | kubectl apply -f apps/music/k8s/all.yaml - name: Roll out to k3s run: | kubectl -n "$NS" set image "deploy/$APP" \ "$APP=$IMAGE:${{ steps.tag.outputs.sha }}" \ "chord-fetcher=$CHORD_IMAGE:${{ steps.tag.outputs.sha }}" kubectl -n "$NS" rollout status "deploy/$APP" --timeout=300s