From 01a33213b8b4605571dfebf329e16a025802c215 Mon Sep 17 00:00:00 2001 From: Noah Date: Sun, 30 Aug 2026 15:00:16 +0000 Subject: [PATCH] =?UTF-8?q?ci:=20=E4=BF=AE=E5=A4=8D=E5=8F=91=E5=B8=83?= =?UTF-8?q?=E4=B8=8E=20CI=20=E5=B7=A5=E4=BD=9C=E6=B5=81=E7=9A=84=E6=9D=83?= =?UTF-8?q?=E9=99=90=E3=80=81=E6=AD=BB=E4=BB=A3=E7=A0=81=E5=8F=8A=E4=BE=9B?= =?UTF-8?q?=E5=BA=94=E9=93=BE=E9=97=AE=E9=A2=98=20(#1679)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit release.yml: - Windows 归档条件比较 matrix.os 与 windows-2019 永远为假,实际 依赖 MSYS 的 .exe 兜底才能工作,改为按 runner.os 判断 - publish 归档循环中 exe 变量不重置,目录顺序变化时会污染后续平台 - 替换已归档的 actions-rs/toolchain、actions-rs/cargo,改用 dtolnay/rust-toolchain 与 cross;checkout@v2(node12 已下线)升 v4 - 弃用的 ::set-output 改为 GITHUB_OUTPUT - 顶层收紧为 contents: read,仅 publish 任务授予写权限 ci.yml: - tag 触发从 '*' 收紧为 v[0-9]+.[0-9]+.[0-9]+,任意 tag 不再能 触发 PyPI 正式发布 - setup-node@v3 升 v4 docker-publish.yml: - 顶层 packages: write 会授予 pull_request 触发的 test 任务,收紧 为顶层只读、build/merge 任务单独授予 - 移除 buildx 已弃用的 install: true;docker-compose v1 命令改为 compose v2 子命令 docs-publish.yml:补 paths 过滤与显式权限。 Termux-publish.yml:setup-node@v3 升 v4。 新增 test.yml:PR 与 master push 运行 cargo test -p biliup -p biliup-cli -p danmaku,合并前有真实测试门禁。 Dockerfile:FFmpeg 从滚动的 latest tag 改为固定 autobuild 版本并 强制 SHA-256 校验,下载被篡改或损坏时构建失败。 docker-compose.yml:占位符 等使解析必然失败,改为 带默认值的环境变量;移除已废弃的 version 字段。 新增 .dockerignore:排除 .git、构建产物及本地数据库/凭据/日志, 避免进入构建上下文。 --- .dockerignore | 25 ++++++++++++++ .github/workflows/Termux-publish.yml | 2 +- .github/workflows/ci.yml | 14 ++++---- .github/workflows/docker-publish.yml | 14 +++++--- .github/workflows/docs-publish.yml | 12 +++++-- .github/workflows/release.yml | 51 ++++++++++++++++------------ .github/workflows/test.yml | 30 ++++++++++++++++ Dockerfile | 7 +++- docker-compose.yml | 9 ++--- 9 files changed, 124 insertions(+), 40 deletions(-) create mode 100644 .dockerignore create mode 100644 .github/workflows/test.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..3498e58 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,25 @@ +# 版本控制与 CI +.git +.github + +# 构建产物(镜像内会重新构建) +target +node_modules +.next +out +dist +tauri-app/node_modules +tauri-app/src-tauri/target + +# 本地运行时数据与凭据,绝不能进入构建上下文 +data +*.sqlite3 +*.sqlite3-* +cookies.json +*.log +.env.local +.env.*.local + +# 文档站与桌面端与镜像无关 +docs +tauri-app diff --git a/.github/workflows/Termux-publish.yml b/.github/workflows/Termux-publish.yml index 52609a0..1370ca0 100644 --- a/.github/workflows/Termux-publish.yml +++ b/.github/workflows/Termux-publish.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: '20' - name: Build frontend diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 511c0b0..b32b1a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,9 @@ on: - main - master tags: - - '*' + # 只有严格的版本号 tag 才触发构建与 PyPI 发布, + # 避免测试/拼错 tag 误发正式包 + - 'v[0-9]+.[0-9]+.[0-9]+' pull_request: workflow_dispatch: @@ -45,7 +47,7 @@ jobs: target: ppc64le steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: '20' - name: Build frontend @@ -90,7 +92,7 @@ jobs: target: armv7 steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: '20' - name: Build frontend @@ -131,7 +133,7 @@ jobs: target: x86 steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: '20' - name: Build frontend @@ -175,7 +177,7 @@ jobs: target: aarch64 steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: '20' - name: Build frontend @@ -207,7 +209,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: '20' - name: Build frontend diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index f340c21..5add8ac 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -13,9 +13,10 @@ on: # Run tests for any PRs. pull_request: +# 顶层只保留读权限:test 任务会在 pull_request 事件下检出并构建 +# PR 代码,不应持有 packages 写权限 permissions: contents: read - packages: write env: IMAGE_NAME: ghcr.io/biliup/caution @@ -47,8 +48,9 @@ jobs: - name: Run tests run: | if [ -f docker-compose.test.yml ]; then - docker-compose --file docker-compose.test.yml build - docker-compose --file docker-compose.test.yml run sut + # runner 已移除 docker-compose v1,统一使用 compose v2 子命令 + docker compose --file docker-compose.test.yml build + docker compose --file docker-compose.test.yml run sut else docker build \ --build-arg repo_url=$REPO_URL \ @@ -62,6 +64,9 @@ jobs: name: Build for ${{ matrix.platform }} runs-on: ${{ matrix.runner }} if: github.event_name == 'push' + permissions: + contents: read + packages: write strategy: matrix: include: @@ -78,7 +83,6 @@ jobs: uses: docker/setup-buildx-action@v3 with: driver-opts: network=host - install: true - name: Login to GitHub Container Registry uses: docker/login-action@v3 @@ -131,6 +135,8 @@ jobs: needs: build runs-on: ubuntu-latest if: github.event_name == 'push' + permissions: + packages: write steps: - name: Download digests diff --git a/.github/workflows/docs-publish.yml b/.github/workflows/docs-publish.yml index d199cd8..567b85b 100644 --- a/.github/workflows/docs-publish.yml +++ b/.github/workflows/docs-publish.yml @@ -3,11 +3,16 @@ name: Zola on GitHub Pages on: push: branches: - - master + - master paths: - docs/** pull_request: - + paths: + - docs/** + +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest @@ -27,6 +32,9 @@ jobs: build_and_deploy: runs-on: ubuntu-latest if: github.ref == 'refs/heads/master' + permissions: + # 推送 gh-pages 分支需要写权限 + contents: write steps: - name: Checkout main uses: actions/checkout@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b0230a2..a42e8de 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,6 +14,9 @@ env: # REPO_NAME: spectralops/rust-ci-release-template # BREW_TAP: jondot/homebrew-tap +permissions: + contents: read + jobs: dist: name: Dist @@ -69,39 +72,37 @@ jobs: steps: - name: Checkout sources - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: submodules: true - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: '20' - name: Build frontend run: | npm install npm run build - - name: Install ${{ matrix.rust }} toolchain - uses: actions-rs/toolchain@v1 + - name: Install stable toolchain + uses: dtolnay/rust-toolchain@stable with: - profile: minimal - toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - override: true + targets: ${{ matrix.target }} + + # actions-rs/cargo 已归档多年,改用 cross 官方安装方式 + - name: Install cross + if: matrix.cross + uses: taiki-e/install-action@v2 + with: + tool: cross - name: Run cargo test if: matrix.build != 'aarch64-macos' - uses: actions-rs/cargo@v1 - with: - use-cross: ${{ matrix.cross }} - command: test - args: --release --locked --target ${{ matrix.target }} -p biliup + shell: bash + run: ${{ matrix.cross && 'cross' || 'cargo' }} test --release --locked --target ${{ matrix.target }} -p biliup - name: Build release binary - uses: actions-rs/cargo@v1 - with: - use-cross: ${{ matrix.cross }} - command: build - args: --release --locked --target ${{ matrix.target }} --bin biliup + shell: bash + run: ${{ matrix.cross && 'cross' || 'cargo' }} build --release --locked --target ${{ matrix.target }} --bin biliup - name: Strip release binary (linux and macos) if: matrix.build == 'x86_64-linux' || matrix.build == 'x86_64-macos' @@ -120,7 +121,8 @@ jobs: shell: bash run: | mkdir dist - if [ "${{ matrix.os }}" = "windows-2019" ]; then + # 按运行器操作系统判断,matrix.os 的取值(windows-latest)永远不等于 windows-2019 + if [ "${{ runner.os }}" = "Windows" ]; then cp "target/${{ matrix.target }}/release/$BIN_NAME.exe" "dist/" else cp "target/${{ matrix.target }}/release/$BIN_NAME" "dist/" @@ -135,9 +137,12 @@ jobs: name: Publish needs: [dist] runs-on: ubuntu-latest + permissions: + # 向 Release 上传产物需要写权限 + contents: write steps: - name: Checkout sources - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: submodules: false @@ -153,7 +158,7 @@ jobs: if [[ $GITHUB_REF == refs/tags/v* ]]; then name=${GITHUB_REF:10} fi - echo ::set-output name=val::$name + echo "val=$name" >> "$GITHUB_OUTPUT" echo TAG=$name >> $GITHUB_ENV id: tagname @@ -168,6 +173,8 @@ jobs: for dir in bins-* ; do platform=${dir#"bins-"} + # 每次迭代重置,否则 exe 会从 windows 平台泄漏到后续平台 + exe="" if [[ $platform =~ "windows" ]]; then exe=".exe" fi @@ -196,4 +203,4 @@ jobs: - name: Extract version id: extract-version run: | - printf "::set-output name=%s::%s\n" tag-name "${GITHUB_REF#refs/tags/}" \ No newline at end of file + echo "tag-name=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..e5a36fa --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,30 @@ +name: Test + +on: + push: + branches: + - master + pull_request: + +permissions: + contents: read + +jobs: + rust: + name: Rust tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '20' + # biliup-cli 通过 rust-embed 嵌入 out/ 前端产物,需要先构建 + - name: Build frontend + run: | + npm install + npm run build + - name: Install stable toolchain + uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + - name: Run tests + run: cargo test --locked -p biliup -p biliup-cli -p danmaku diff --git a/Dockerfile b/Dockerfile index 32e296d..a6e9a71 100644 --- a/Dockerfile +++ b/Dockerfile @@ -80,13 +80,17 @@ RUN set -eux; \ apt-mark manual curl wget; \ \ arch="$(dpkg --print-architecture)"; arch="${arch##*-}"; \ - url='https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-n8.1-latest-'; \ + # 固定 FFmpeg 到确定版本并校验 SHA-256: + # latest 是滚动 tag,资产每日重建,既不可复现也无法防篡改 + url='https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2026-08-29-13-12/ffmpeg-n8.1.2-50-g1a748fe2cd-'; \ case "$arch" in \ 'amd64') \ url="${url}linux64-gpl-8.1.tar.xz"; \ + sha256='be243f2520d6e7e92c82b015ed72a3f5b57c7970801c0d51f031457122653c76'; \ ;; \ 'arm64') \ url="${url}linuxarm64-gpl-8.1.tar.xz"; \ + sha256='0df9277976f71f36b31a4de9f6657a1fbbf32ce2273594c18f19b92fbbbde1ce'; \ ;; \ *) \ useApt=true; \ @@ -99,6 +103,7 @@ RUN set -eux; \ ; \ else \ wget -O ffmpeg.tar.xz "$url" --progress=dot:giga; \ + echo "$sha256 ffmpeg.tar.xz" | sha256sum -c -; \ tar -xJf ffmpeg.tar.xz -C /usr/local --strip-components=1; \ rm -rf \ /usr/local/doc \ diff --git a/docker-compose.yml b/docker-compose.yml index c0b9ab7..6b06e0b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,12 +1,13 @@ -version: '3' services: biliup: image: ghcr.io/biliup/caution:latest container_name: biliup restart: unless-stopped ports: - - "::19159" + # 可通过环境变量覆盖宿主机端口,例如 BILIUP_PORT=8080 docker compose up -d + - "${BILIUP_PORT:-19159}:19159" volumes: - - /path/to/save_folder:/opt + # 录播与数据保存目录,默认使用当前目录下的 data/ + - ${BILIUP_DATA:-./data}:/opt # 容器内必须监听 0.0.0.0,否则上面的端口映射无法转发进容器 - command: server --bind 0.0.0.0 --auth \ No newline at end of file + command: server --bind 0.0.0.0 --auth