diff --git a/.woodpecker/ci.yml b/.woodpecker/ci.yml index fa972e7..98b5baa 100644 --- a/.woodpecker/ci.yml +++ b/.woodpecker/ci.yml @@ -1,5 +1,10 @@ when: - - event: [push, manual] + - event: pull_request + - event: push + branch: master + - event: push + branch: main + - event: manual labels: ci: domain-linux-native @@ -13,45 +18,22 @@ clone: from_secret: gitea_clone_webdrop lfs: false -steps: - prefetch-dependencies: - image: bash - commands: - - mkdir -p "$HOME/.cache/woodpecker/webdrop/npm" "$HOME/.cache/woodpecker/webdrop/nuget" - - cd packages/core - - npm ci --cache "$HOME/.cache/woodpecker/webdrop/npm" --prefer-offline --no-audit - - cd ../../web - - npm ci --cache "$HOME/.cache/woodpecker/webdrop/npm" --prefer-offline --no-audit - - cd .. - - NUGET_PACKAGES="$HOME/.cache/woodpecker/webdrop/nuget" dotnet restore server/WebDrop.slnx - - api-contract: +steps: + prefetch-dependencies: + image: bash + commands: + - mkdir -p "$HOME/.cache/woodpecker/webdrop/nuget" + - NUGET_PACKAGES="$HOME/.cache/woodpecker/webdrop/nuget" dotnet restore server/WebDrop.slnx + + api-contract: image: bash commands: - node scripts/check-api-contract.mjs - core-and-web: - image: bash - depends_on: [prefetch-dependencies] - commands: - - cd packages/core - - npm run typecheck - - npm test - - npm run vectors:check - - npm run build - - web: - image: bash - depends_on: [prefetch-dependencies] - commands: - - cd web - - npm run typecheck - - npm run lint:css - - npm test - - npm run build - - server: - image: bash - depends_on: [prefetch-dependencies] - commands: - - NUGET_PACKAGES="$HOME/.cache/woodpecker/webdrop/nuget" dotnet test server/WebDrop.slnx --configuration Release --verbosity minimal --no-restore + server: + image: bash + depends_on: [prefetch-dependencies] + when: + - evaluate: 'not (CI_COMMIT_MESSAGE contains "[SKIP TESTS]")' + commands: + - NUGET_PACKAGES="$HOME/.cache/woodpecker/webdrop/nuget" dotnet test server/WebDrop.slnx --configuration Release --verbosity minimal --no-restore diff --git a/.woodpecker/dev-image.yml b/.woodpecker/dev-image.yml new file mode 100644 index 0000000..bb1f52d --- /dev/null +++ b/.woodpecker/dev-image.yml @@ -0,0 +1,50 @@ +when: + - event: push + branch: master + evaluate: 'CI_COMMIT_MESSAGE contains "[CI]"' + - event: push + branch: main + evaluate: 'CI_COMMIT_MESSAGE contains "[CI]"' + +labels: + ci: domain-linux-native + platform: linux/amd64 + +clone: + - name: git + image: woodpeckerci/plugin-git:2.9.3 + settings: + remote: + from_secret: gitea_clone_webdrop + lfs: false + +depends_on: + - ci + - web-build + +concurrency: 1 + +steps: + publish-dev-image: + image: bash + environment: + ZOT_USERNAME: + from_secret: registry_username + ZOT_PASSWORD: + from_secret: registry_password + ZOT_REGISTRY: 192.168.2.162:5000 + commands: + - set -euo pipefail + - ': "${WOODPECKER_BACKEND_LOCAL_TEMP_DIR:=$HOME/woodpecker/work}"' + - buildah_store="$(dirname "$WOODPECKER_BACKEND_LOCAL_TEMP_DIR")/buildah-cache/webdrop" + - mkdir -p "$buildah_store/storage" "$buildah_store/run" + - 'buildah() { command buildah --root "$buildah_store/storage" --runroot "$buildah_store/run" "$@"; }' + - printf '%s' "$ZOT_PASSWORD" | buildah login --tls-verify=false "$ZOT_REGISTRY" --username "$ZOT_USERNAME" --password-stdin + - trap 'buildah logout "$ZOT_REGISTRY" >/dev/null 2>&1 || true' EXIT + - sha="${CI_COMMIT_SHA:0:7}" + - image="$ZOT_REGISTRY/justme/webdrop-api:dev-$sha" + - dev_image="$ZOT_REGISTRY/justme/webdrop-api:dev" + - buildah bud --layers --network host --format docker --platform linux/amd64 --tag "$image" --file server/Dockerfile . + - buildah tag "$image" "$dev_image" + - buildah push --tls-verify=false "$image" "docker://$image" + - buildah push --tls-verify=false "$dev_image" "docker://$dev_image" diff --git a/.woodpecker/release-backend.yml b/.woodpecker/release-backend.yml index 3648110..3eb4c83 100644 --- a/.woodpecker/release-backend.yml +++ b/.woodpecker/release-backend.yml @@ -29,12 +29,13 @@ steps: release-checks: image: bash commands: - - release_tag="${CI_COMMIT_TAG:-${RELEASE_TAG:-}}" - - test -n "$release_tag" - - node scripts/check-api-contract.mjs "$release_tag" - - mkdir -p "$HOME/.cache/woodpecker/webdrop/nuget" - - NUGET_PACKAGES="$HOME/.cache/woodpecker/webdrop/nuget" dotnet restore server/WebDrop.slnx - - NUGET_PACKAGES="$HOME/.cache/woodpecker/webdrop/nuget" dotnet test server/WebDrop.slnx --configuration Release --verbosity minimal --no-restore + - release_tag="${CI_COMMIT_TAG:-${RELEASE_TAG:-}}" + - test -n "$release_tag" + - node scripts/check-api-contract.mjs "$release_tag" + - bash scripts/ci-frontend.sh + - mkdir -p "$HOME/.cache/woodpecker/webdrop/nuget" + - NUGET_PACKAGES="$HOME/.cache/woodpecker/webdrop/nuget" dotnet restore server/WebDrop.slnx + - NUGET_PACKAGES="$HOME/.cache/woodpecker/webdrop/nuget" dotnet test server/WebDrop.slnx --configuration Release --verbosity minimal --no-restore publish-backend: image: bash @@ -55,9 +56,9 @@ steps: - printf '%s' "$ZOT_PASSWORD" | buildah login --tls-verify=false "$ZOT_REGISTRY" --username "$ZOT_USERNAME" --password-stdin - trap 'buildah logout "$ZOT_REGISTRY" >/dev/null 2>&1 || true' EXIT - image="$ZOT_REGISTRY/justme/webdrop-api:$release_tag" - - latest_image="$ZOT_REGISTRY/justme/webdrop-api:latest" - - buildah bud --layers --network host --format docker --platform linux/amd64 --tag "$image" --file server/Dockerfile . - - buildah tag "$image" "$latest_image" - - buildah push --tls-verify=false "$image" "docker://$image" + - latest_image="$ZOT_REGISTRY/justme/webdrop-api:latest" + - buildah bud --layers --network host --format docker --platform linux/amd64 --tag "$image" --file server/Dockerfile . + - buildah tag "$image" "$latest_image" + - buildah push --tls-verify=false "$image" "docker://$image" - buildah push --tls-verify=false "$latest_image" "docker://$latest_image" diff --git a/.woodpecker/web-build.yml b/.woodpecker/web-build.yml new file mode 100644 index 0000000..3c5619d --- /dev/null +++ b/.woodpecker/web-build.yml @@ -0,0 +1,25 @@ +when: + - event: pull_request + - event: push + branch: master + - event: push + branch: main + - event: manual + +labels: + ci: domain-linux-native + platform: linux/amd64 + +clone: + - name: git + image: woodpeckerci/plugin-git:2.9.3 + settings: + remote: + from_secret: gitea_clone_webdrop + lfs: false + +steps: + web-build: + image: bash + commands: + - bash scripts/ci-frontend.sh diff --git a/docs/deployment.md b/docs/deployment.md index 93e5dda..58ceb43 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -36,7 +36,11 @@ CAPTCHA_SECRET= ## Woodpecker CI -`.woodpecker/ci.yml` 在 push 和手动运行时执行 API 契约、Core、Web、服务端检查;每次 push 都会构建前端。`.woodpecker/release-backend.yml` 响应 `vMAJOR.MINOR.PATCH` SemVer tag;也可手动运行并传入 `RELEASE_TAG`(例如 `v0.1.0`)。测试通过后用 Linux native agent 的 Buildah 构建并推送同名后端镜像 tag。两者都通过 Woodpecker secret `gitea_clone_webdrop` 从 `https://git.oeo.one` 克隆公开仓库。 +`.woodpecker/ci.yml` 在默认分支 push、pull request 和手动运行时执行 API 契约与服务端检查;`.woodpecker/web-build.yml` 同时执行 Core 测试向量、类型检查、Web CSS lint、测试和构建。两个 workflow 独立运行,让前后端验证并行。默认分支当前为 `master`,配置也兼容迁移后的 `main`。 + +默认分支每次 push 和 PR 都会跑常规检查。提交信息含 `[SKIP TESTS]` 时只跳过服务端测试;API 契约检查和前端/Core 检查照常运行。提交信息含 `[CI]` 时,`.woodpecker/dev-image.yml` 会等 `ci` 和 `web-build` 都通过后,构建并推送带提交 SHA 的开发镜像以及可变 `dev` 标签。开发镜像不会覆盖 release tag 或 `latest`。 + +`.woodpecker/release-backend.yml` 响应 `vMAJOR.MINOR.PATCH` SemVer tag;也可手动运行并传入 `RELEASE_TAG`(例如 `v0.1.0`)。发布 workflow 会重新执行 Core、Web 和服务端完整检查,全部通过后才用 Linux native agent 的 Buildah 构建并推送后端镜像 tag 与 `latest`。所有 workflow 都通过 Woodpecker secret `gitea_clone_webdrop` 从 `https://git.oeo.one` 克隆公开仓库。 两条流水线固定到 `ci: domain-linux-native` 的 `linux/amd64` Agent;该主机需要 Node 24、.NET 10 和 Buildah。release job 在 `WOODPECKER_BACKEND_LOCAL_TEMP_DIR` 对应的持久目录缓存 Buildah 层,Dockerfile 单独缓存 NuGet restore 层。Gitea webhook 走同 Docker 网络中的 `woodpecker-server:8000`,代码 clone 走公网 Git 域名。 diff --git a/scripts/ci-frontend.sh b/scripts/ci-frontend.sh new file mode 100644 index 0000000..92dea7e --- /dev/null +++ b/scripts/ci-frontend.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +npm_cache="${NPM_CONFIG_CACHE:-$HOME/.cache/woodpecker/webdrop/npm}" +mkdir -p "$npm_cache" + +cd "$repo_root/packages/core" +npm ci --cache "$npm_cache" --prefer-offline --no-audit +npm run typecheck +npm test +npm run vectors:check +npm run build + +cd "$repo_root/web" +npm ci --cache "$npm_cache" --prefer-offline --no-audit +npm run typecheck +npm run lint:css +npm test +npm run build