From a1cc0ee2bf69006ec5c7ab486d35dd0a10e3f5cd Mon Sep 17 00:00:00 2001 From: lincube Date: Thu, 28 May 2026 20:07:03 +0800 Subject: [PATCH] =?UTF-8?q?changed.PLONDS=E5=90=AF=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...plonds-build.yml => plonds-comparator.yml} | 4 +- ...{ddss-rollback.yml => plonds-rollback.yml} | 24 ++++----- .../{ddss-publish.yml => plonds-uploader.yml} | 54 +++++++++---------- .../pdc-incremental-migration/checklist.md | 16 ------ .trae/specs/pdc-incremental-migration/spec.md | 48 ----------------- .../specs/pdc-incremental-migration/tasks.md | 21 -------- .../Update/PendingUpdateDetector.cs | 16 +++--- .../Update/PlondsUpdateApplier.cs | 6 +-- .../Update/UpdateManifest.cs | 2 +- .../Update/UpdateState.cs | 1 - .../Services/Update/UpdateInstallGateway.cs | 4 +- .../Services/UpdateSettingsValues.cs | 8 +-- .../ViewModels/UpdateSettingsViewModel.cs | 6 +-- ...sBuildOptions.cs => PlondsBuildOptions.cs} | 2 +- ...estBuilder.cs => PlondsManifestBuilder.cs} | 22 ++++---- ...{DdssAssetEntry.cs => PlondsAssetEntry.cs} | 4 +- .../{DdssManifest.cs => PlondsManifest.cs} | 4 +- ...dssMirrorEntry.cs => PlondsMirrorEntry.cs} | 2 +- .../src/Plonds.Tool/Program.cs | 12 ++--- docs/auto_commit_md/20260512_563f12ca.md | 8 +-- 20 files changed, 85 insertions(+), 179 deletions(-) rename .github/workflows/{plonds-build.yml => plonds-comparator.yml} (98%) rename .github/workflows/{ddss-rollback.yml => plonds-rollback.yml} (85%) rename .github/workflows/{ddss-publish.yml => plonds-uploader.yml} (89%) delete mode 100644 .trae/specs/pdc-incremental-migration/checklist.md delete mode 100644 .trae/specs/pdc-incremental-migration/spec.md delete mode 100644 .trae/specs/pdc-incremental-migration/tasks.md rename PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Core/Publishing/{DdssBuildOptions.cs => PlondsBuildOptions.cs} (82%) rename PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Core/Publishing/{DdssManifestBuilder.cs => PlondsManifestBuilder.cs} (71%) rename PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/{DdssAssetEntry.cs => PlondsAssetEntry.cs} (56%) rename PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/{DdssManifest.cs => PlondsManifest.cs} (58%) rename PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/{DdssMirrorEntry.cs => PlondsMirrorEntry.cs} (63%) diff --git a/.github/workflows/plonds-build.yml b/.github/workflows/plonds-comparator.yml similarity index 98% rename from .github/workflows/plonds-build.yml rename to .github/workflows/plonds-comparator.yml index 8eb99ff..8d97aa7 100644 --- a/.github/workflows/plonds-build.yml +++ b/.github/workflows/plonds-comparator.yml @@ -1,4 +1,4 @@ -name: PLONDS +name: PLONDS Comparator concurrency: group: plonds-${{ github.event_name }}-${{ github.event.release.tag_name || github.event.inputs.tag || github.run_id }} @@ -87,13 +87,11 @@ jobs: env: UPDATE_PRIVATE_KEY_PEM: ${{ secrets.UPDATE_PRIVATE_KEY_PEM }} PLONDS_SIGNING_KEY: ${{ secrets.PLONDS_SIGNING_KEY }} - PDC_SIGNING_KEY: ${{ secrets.PDC_SIGNING_KEY }} shell: bash run: | set -euo pipefail KEY="${PLONDS_SIGNING_KEY:-}" if [[ -z "$KEY" ]]; then KEY="${UPDATE_PRIVATE_KEY_PEM:-}"; fi - if [[ -z "$KEY" ]]; then KEY="${PDC_SIGNING_KEY:-}"; fi if [[ -z "$KEY" ]]; then echo "No signing key is configured." exit 1 diff --git a/.github/workflows/ddss-rollback.yml b/.github/workflows/plonds-rollback.yml similarity index 85% rename from .github/workflows/ddss-rollback.yml rename to .github/workflows/plonds-rollback.yml index c8dacd7..ae49749 100644 --- a/.github/workflows/ddss-rollback.yml +++ b/.github/workflows/plonds-rollback.yml @@ -1,4 +1,4 @@ -name: DDSS Rollback +name: PLONDS Rollback on: workflow_dispatch: @@ -26,7 +26,7 @@ jobs: contents: read concurrency: - group: ddss-rollback-${{ github.event.inputs.channel }} + group: plonds-rollback-${{ github.event.inputs.channel }} cancel-in-progress: false steps: @@ -63,7 +63,7 @@ jobs: echo "RELEASE_CHANNEL=${CHANNEL}" >> "$GITHUB_ENV" echo "S3_PUBLIC_BASE_URL=${PUBLIC_BASE}" >> "$GITHUB_ENV" echo "S3_BASE_URL=${PUBLIC_BASE}/releases/${TAG}/assets" >> "$GITHUB_ENV" - echo "DDSS_CHANNEL_POINTER_KEY=lanmountain/update/meta/channels/${CHANNEL}/ddss-latest.json" >> "$GITHUB_ENV" + echo "PLONDS_CHANNEL_POINTER_KEY=lanmountain/update/meta/channels/${CHANNEL}/plonds-latest.json" >> "$GITHUB_ENV" - name: Validate rollback target assets env: @@ -77,7 +77,7 @@ jobs: run: | set -euo pipefail - for name in ddss.json ddss.json.sig; do + for name in plonds.json plonds.json.sig; do key="lanmountain/update/releases/${RELEASE_TAG}/assets/${name}" aws --endpoint-url "$S3_ENDPOINT" --region "$AWS_REGION" s3api head-object \ --bucket "$S3_BUCKET" \ @@ -90,10 +90,10 @@ jobs: set -euo pipefail mkdir -p rollback-output - pointer_file="rollback-output/ddss-latest.json" + pointer_file="rollback-output/plonds-latest.json" - manifest_url="${S3_BASE_URL}/ddss.json" - sig_url="${S3_BASE_URL}/ddss.json.sig" + manifest_url="${S3_BASE_URL}/plonds.json" + sig_url="${S3_BASE_URL}/plonds.json.sig" version="${RELEASE_TAG#v}" updated_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)" @@ -125,22 +125,22 @@ jobs: run: | set -euo pipefail - pointer_file="rollback-output/ddss-latest.json" + pointer_file="rollback-output/plonds-latest.json" aws --endpoint-url "$S3_ENDPOINT" --region "$AWS_REGION" s3api put-object \ --bucket "$S3_BUCKET" \ - --key "$DDSS_CHANNEL_POINTER_KEY" \ + --key "$PLONDS_CHANNEL_POINTER_KEY" \ --body "$pointer_file" aws --endpoint-url "$S3_ENDPOINT" --region "$AWS_REGION" s3api head-object \ --bucket "$S3_BUCKET" \ - --key "$DDSS_CHANNEL_POINTER_KEY" >/dev/null + --key "$PLONDS_CHANNEL_POINTER_KEY" >/dev/null - curl -fsSI "$S3_PUBLIC_BASE_URL/meta/channels/${RELEASE_CHANNEL}/ddss-latest.json" >/dev/null + curl -fsSI "$S3_PUBLIC_BASE_URL/meta/channels/${RELEASE_CHANNEL}/plonds-latest.json" >/dev/null - name: Print rollback summary shell: bash run: | set -euo pipefail echo "Rolled back channel '${RELEASE_CHANNEL}' to '${RELEASE_TAG}'." - echo "Pointer: ${S3_PUBLIC_BASE_URL}/meta/channels/${RELEASE_CHANNEL}/ddss-latest.json" + echo "Pointer: ${S3_PUBLIC_BASE_URL}/meta/channels/${RELEASE_CHANNEL}/plonds-latest.json" diff --git a/.github/workflows/ddss-publish.yml b/.github/workflows/plonds-uploader.yml similarity index 89% rename from .github/workflows/ddss-publish.yml rename to .github/workflows/plonds-uploader.yml index ee76ab6..396d169 100644 --- a/.github/workflows/ddss-publish.yml +++ b/.github/workflows/plonds-uploader.yml @@ -1,13 +1,13 @@ -name: DDSS +name: PLONDS Publisher concurrency: - group: ddss-${{ github.event_name }}-${{ github.event.workflow_run.id || github.event.inputs.tag || github.run_id }} + group: plonds-${{ github.event_name }}-${{ github.event.workflow_run.id || github.event.inputs.tag || github.run_id }} cancel-in-progress: false on: workflow_run: workflows: - - PLONDS + - PLONDS Comparator types: - completed workflow_dispatch: @@ -61,7 +61,7 @@ jobs: CHANNEL="stable" fi echo "RELEASE_CHANNEL=${CHANNEL}" >> "$GITHUB_ENV" - echo "DDSS_CHANNEL_POINTER_KEY=lanmountain/update/meta/channels/${CHANNEL}/ddss-latest.json" >> "$GITHUB_ENV" + echo "PLONDS_CHANNEL_POINTER_KEY=lanmountain/update/meta/channels/${CHANNEL}/plonds-latest.json" >> "$GITHUB_ENV" PUBLIC_BASE="${{ vars.S3_PUBLIC_BASE_URL }}" if [[ -z "$PUBLIC_BASE" ]]; then PUBLIC_BASE="https://cn-nb1.rains3.com/lmdesktop/lanmountain/update" @@ -80,13 +80,11 @@ jobs: env: UPDATE_PRIVATE_KEY_PEM: ${{ secrets.UPDATE_PRIVATE_KEY_PEM }} PLONDS_SIGNING_KEY: ${{ secrets.PLONDS_SIGNING_KEY }} - PDC_SIGNING_KEY: ${{ secrets.PDC_SIGNING_KEY }} shell: bash run: | set -euo pipefail KEY="${PLONDS_SIGNING_KEY:-}" if [[ -z "$KEY" ]]; then KEY="${UPDATE_PRIVATE_KEY_PEM:-}"; fi - if [[ -z "$KEY" ]]; then KEY="${PDC_SIGNING_KEY:-}"; fi if [[ -z "$KEY" ]]; then echo "No signing key is configured." exit 1 @@ -141,7 +139,7 @@ jobs: for file in release-assets/*; do [[ -f "$file" ]] || continue name="$(basename "$file")" - if [[ "$name" == "ddss.json" || "$name" == "ddss.json.sig" ]]; then + if [[ "$name" == "plonds.json" || "$name" == "plonds.json.sig" ]]; then continue fi key="lanmountain/update/releases/${RELEASE_TAG}/assets/${name}" @@ -211,21 +209,21 @@ jobs: --metadata "sha256=$sha256" done - - name: Build DDSS manifest + - name: Build PLONDS manifest shell: bash run: | set -euo pipefail - mkdir -p ddss-output + mkdir -p plonds-output dotnet run --project PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Tool/Plonds.Tool.csproj --configuration Release -- \ - build-ddss \ + build-plonds \ --release-tag "$RELEASE_TAG" \ --assets-dir release-assets \ - --output-dir ddss-output \ + --output-dir plonds-output \ --private-key "$UPDATE_PRIVATE_KEY_PATH" \ --repository "${{ github.repository }}" \ --s3-base-url "$S3_BASE_URL" - - name: Validate DDSS asset references in Rainyun S3 + - name: Validate PLONDS asset references in Rainyun S3 env: AWS_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY }} AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_KEY }} @@ -236,12 +234,12 @@ jobs: shell: bash run: | set -euo pipefail - keys=$(jq -r '.assets[]?.mirrors[]?.url // empty' ddss-output/ddss.json \ + keys=$(jq -r '.assets[]?.mirrors[]?.url // empty' plonds-output/plonds.json \ | sed -n 's#^.*/lanmountain/update/\(.*\)$#lanmountain/update/\1#p' \ | sort -u) if [[ -z "$keys" ]]; then - echo "No S3-backed asset URLs found in ddss.json" + echo "No S3-backed asset URLs found in plonds.json" exit 1 fi @@ -252,15 +250,15 @@ jobs: --key "$key" >/dev/null done <<< "$keys" - - name: Upload DDSS manifest to release + - name: Upload PLONDS manifest to release env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} shell: bash run: | set -euo pipefail - gh release upload "$RELEASE_TAG" ddss-output/ddss.json ddss-output/ddss.json.sig --clobber + gh release upload "$RELEASE_TAG" plonds-output/plonds.json plonds-output/plonds.json.sig --clobber - - name: Upload DDSS manifest to Rainyun S3 staging + - name: Upload PLONDS manifest to Rainyun S3 staging env: AWS_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY }} AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_KEY }} @@ -271,7 +269,7 @@ jobs: shell: bash run: | set -euo pipefail - for file in ddss-output/ddss.json ddss-output/ddss.json.sig; do + for file in plonds-output/plonds.json plonds-output/plonds.json.sig; do name="$(basename "$file")" key="lanmountain/update/releases/${RELEASE_TAG}/assets/${name}" sha256="$(sha256sum "$file" | awk '{print $1}')" @@ -282,11 +280,11 @@ jobs: --metadata "sha256=$sha256" done - - name: Prepare DDSS channel pointer + - name: Prepare PLONDS channel pointer shell: bash run: | set -euo pipefail - pointer_file="ddss-output/ddss-latest.json" + pointer_file="plonds-output/plonds-latest.json" cat > "$pointer_file" <<'JSON' { "schemaVersion": 1, @@ -301,8 +299,8 @@ jobs: } JSON - manifest_url="${S3_BASE_URL}/ddss.json" - sig_url="${S3_BASE_URL}/ddss.json.sig" + manifest_url="${S3_BASE_URL}/plonds.json" + sig_url="${S3_BASE_URL}/plonds.json.sig" version="${RELEASE_TAG#v}" updated_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)" @@ -315,7 +313,7 @@ jobs: jq -e . "$pointer_file" >/dev/null - - name: Atomically publish DDSS channel pointer + - name: Atomically publish PLONDS channel pointer env: AWS_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY }} AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_KEY }} @@ -326,8 +324,8 @@ jobs: shell: bash run: | set -euo pipefail - pointer_file="ddss-output/ddss-latest.json" - staging_key="lanmountain/update/releases/${RELEASE_TAG}/assets/ddss-latest.json" + pointer_file="plonds-output/plonds-latest.json" + staging_key="lanmountain/update/releases/${RELEASE_TAG}/assets/plonds-latest.json" aws --endpoint-url "$S3_ENDPOINT" --region "$AWS_REGION" s3api put-object \ --bucket "$S3_BUCKET" \ @@ -336,14 +334,14 @@ jobs: aws --endpoint-url "$S3_ENDPOINT" --region "$AWS_REGION" s3api put-object \ --bucket "$S3_BUCKET" \ - --key "$DDSS_CHANNEL_POINTER_KEY" \ + --key "$PLONDS_CHANNEL_POINTER_KEY" \ --body "$pointer_file" aws --endpoint-url "$S3_ENDPOINT" --region "$AWS_REGION" s3api head-object \ --bucket "$S3_BUCKET" \ - --key "$DDSS_CHANNEL_POINTER_KEY" >/dev/null + --key "$PLONDS_CHANNEL_POINTER_KEY" >/dev/null - curl -fsSI "$S3_PUBLIC_BASE_URL/meta/channels/${RELEASE_CHANNEL}/ddss-latest.json" >/dev/null + curl -fsSI "$S3_PUBLIC_BASE_URL/meta/channels/${RELEASE_CHANNEL}/plonds-latest.json" >/dev/null - name: Verify Rainyun S3 PLONDS output env: diff --git a/.trae/specs/pdc-incremental-migration/checklist.md b/.trae/specs/pdc-incremental-migration/checklist.md deleted file mode 100644 index d53b8a5..0000000 --- a/.trae/specs/pdc-incremental-migration/checklist.md +++ /dev/null @@ -1,16 +0,0 @@ -# Checklist - -- [x] `release.yml` does not invoke Velopack. -- [x] `plonds-build.yml` uploads app payload artifacts and generates PloNDS delta/static outputs. -- [x] S3 output path is rooted at `lanmountain/update/` (no system version prefix). -- [x] CI workflow expects `repo/`, `meta/`, `manifests/`, and `installers/` outputs after a release run. -- [x] Host update source keeps compatibility (`pdc`/`stcn` normalize to active PloNDS source). -- [x] Host can persist PloNDS payload into launcher incoming directory. -- [x] Launcher can apply PloNDS FileMap payload with signature/hash verification. -- [x] Legacy signed `files.json + update.zip` path still works as compatibility fallback. -- [x] Launcher keeps rollback-capable deployments after successful update. -- [x] Manual rollback returns a structured failure when the snapshot source directory is missing. -- [ ] CI run attached proving all release matrix jobs pass. -- [x] N-1 -> N incremental update verified locally on Windows x64. -- [ ] N-1 -> N incremental update verified on Windows x86 and Linux x64. -- [x] Rollback regression tests attached in `LanMountainDesktop.Tests`. diff --git a/.trae/specs/pdc-incremental-migration/spec.md b/.trae/specs/pdc-incremental-migration/spec.md deleted file mode 100644 index 16a549b..0000000 --- a/.trae/specs/pdc-incremental-migration/spec.md +++ /dev/null @@ -1,48 +0,0 @@ -# PDC Incremental Update Migration - -## Goal - -Replace VeloPack-based incremental packaging with a unified PDC FileMap + object-repo pipeline, while keeping Launcher installation, rollback, and update orchestration ownership unchanged. - -## Stage 1 (Completed) - -- Release workflow removed VeloPack-based release packaging. -- Signed FileMap path was restored as an interim release mechanism. -- Host/Launcher fallback behavior stayed compatible with `files.json + files.json.sig + update.zip`. - -## Stage 2 (Current Implementation Target) - -- Use GitHub Actions PloNDS static publishing as the active incremental path. -- Keep `phainon.yml` for future PDCC parity, but do not rely on PDCC for the current release flow. -- Promote PloNDS-distributed FileMap/object-repo as the primary incremental path. -- Keep GitHub Release installers and metadata as parallel distribution. -- Keep Launcher state machine ownership (`.current/.partial/.destroy` + snapshots). -- Check updates in order: NS3/PloNDS static source, GitHub Release PloNDS assets, then GitHub full installer. -- S3 object root is fixed to `lanmountain/update/` with no update-system version prefix. -- Public object URLs come from `S3_PUBLIC_BASE_URL`; do not infer them from `S3_ENDPOINT` and `S3_BUCKET`. - -Expected S3 layout: - - `lanmountain/update/repo/sha256//` - - `lanmountain/update/meta/channels///latest.json` - - `lanmountain/update/meta/distributions/.json` - - `lanmountain/update/manifests//plonds-filemap.json` - - `lanmountain/update/manifests//plonds-filemap.json.sig` - - `lanmountain/update/installers///*` - -## Acceptance - -- `release.yml` contains no Velopack steps; PloNDS static publishing is handled by `plonds-build.yml` and `ddss-publish.yml`. -- Release jobs keep building installers for Windows x64/x86, Linux x64, and macOS. -- PloNDS metadata + FileMap + object repo are published under `lanmountain/update/`. -- Host can consume the NS3/PloNDS static payload and fallback to GitHub when unavailable. -- Launcher can apply both: - - legacy signed `files.json + update.zip` - - PloNDS FileMap object-repo payload. -- Rollback semantics keep both automatic failure rollback and manual rollback after a successful update. - -## Deprecated Notes - -- The following interim outputs are compatibility-only (not the long-term primary path): - - `files-windows-x64.json` / `.sig` / `update-windows-x64.zip` - - `files-windows-x86.json` / `.sig` / `update-windows-x86.zip` - - `files-linux-x64.json` / `.sig` / `update-linux-x64.zip` diff --git a/.trae/specs/pdc-incremental-migration/tasks.md b/.trae/specs/pdc-incremental-migration/tasks.md deleted file mode 100644 index f195f02..0000000 --- a/.trae/specs/pdc-incremental-migration/tasks.md +++ /dev/null @@ -1,21 +0,0 @@ -# Tasks - -- [x] Remove VeloPack packaging from release workflow. -- [x] Keep signed FileMap path as interim compatibility fallback. -- [x] Remove launcher/runtime Velopack branching. -- [x] Add `phainon.yml` for PDCC publish configuration. -- [ ] Add PDCC installation + publish steps in `release.yml` (deferred; active path is GitHub Actions PloNDS static publish). -- [x] Upload app payload artifacts for PloNDS delta generation in release build jobs. -- [x] Publish PloNDS metadata + sha256 object repo to S3 path root `lanmountain/update/`. -- [x] Mirror installers to `lanmountain/update/installers///`. -- [x] Keep update source compatibility (`pdc`/`stcn` normalize to active PloNDS source). -- [x] Add PloNDS static payload model into host update check result. -- [x] Add host download path for PloNDS payload (`plonds-filemap.json` + signature + object repo). -- [x] Add launcher PloNDS FileMap apply path with rollback-compatible semantics. -- [x] Keep old `files.json + update.zip` path behind compatibility fallback. -- [x] Keep rollback deployment directories after successful apply and prune by bounded retention. -- [x] Return structured failure when manual rollback snapshot source is missing. -- [x] Verify static S3 layout, filemap/signature, distribution, latest pointer, and at least one object in CI workflows. -- [x] Add regression tests for PloNDS success rollback, hash-failure auto rollback, missing rollback source, static NS3 manifest, and manifest field mapping. -- [ ] Attach live CI run proving the full release matrix passes. -- [ ] Verify N-1 -> N incremental update on Windows x86 and Linux x64 in release artifacts. diff --git a/LanMountainDesktop.Launcher/Update/PendingUpdateDetector.cs b/LanMountainDesktop.Launcher/Update/PendingUpdateDetector.cs index 4f20f22..bc6da53 100644 --- a/LanMountainDesktop.Launcher/Update/PendingUpdateDetector.cs +++ b/LanMountainDesktop.Launcher/Update/PendingUpdateDetector.cs @@ -12,23 +12,23 @@ internal sealed class PendingUpdateDetector( { if (File.Exists(paths.PlondsFileMapPath) && File.Exists(paths.PlondsSignaturePath)) { - var pdcFileMapText = File.ReadAllText(paths.PlondsFileMapPath); - var pdcFileMap = JsonSerializer.Deserialize(pdcFileMapText, AppJsonContext.Default.PlondsFileMap); - if (pdcFileMap is null) + var plondsFileMapText = File.ReadAllText(paths.PlondsFileMapPath); + var plondsFileMap = JsonSerializer.Deserialize(plondsFileMapText, AppJsonContext.Default.PlondsFileMap); + if (plondsFileMap is null) { return UpdateEngineResults.Failed("update.check", "invalid_manifest", "plonds-filemap.json is invalid."); } - var pdcVerified = signatureVerifier.Verify( + var plondsVerified = signatureVerifier.Verify( paths.PlondsFileMapPath, paths.PlondsSignaturePath, UpdateEnginePaths.PlondsSignatureFileName); - if (!pdcVerified.Success) + if (!plondsVerified.Success) { - return UpdateEngineResults.Failed("update.check", "signature_failed", pdcVerified.Message); + return UpdateEngineResults.Failed("update.check", "signature_failed", plondsVerified.Message); } - var pdcMetadata = PlondsManifestParser.LoadMetadata(paths.PlondsUpdateMetadataPath); + var plondsMetadata = PlondsManifestParser.LoadMetadata(paths.PlondsUpdateMetadataPath); return new LauncherResult { Success = true, @@ -36,7 +36,7 @@ internal sealed class PendingUpdateDetector( Code = "available", Message = "Pending PLONDS update is available.", CurrentVersion = deploymentLocator.GetCurrentVersion(), - TargetVersion = PlondsManifestParser.ResolveTargetVersion(pdcFileMap, pdcMetadata) + TargetVersion = PlondsManifestParser.ResolveTargetVersion(plondsFileMap, plondsMetadata) }; } diff --git a/LanMountainDesktop.Launcher/Update/PlondsUpdateApplier.cs b/LanMountainDesktop.Launcher/Update/PlondsUpdateApplier.cs index a6dc7f8..32586c8 100644 --- a/LanMountainDesktop.Launcher/Update/PlondsUpdateApplier.cs +++ b/LanMountainDesktop.Launcher/Update/PlondsUpdateApplier.cs @@ -39,11 +39,11 @@ internal sealed class PlondsUpdateApplier( return UpdateEngineResults.Failed("update.apply", "invalid_manifest", "No PLONDS file entries were found."); } - var pdcMetadata = PlondsManifestParser.LoadMetadata(paths.PlondsUpdateMetadataPath); + var plondsMetadata = PlondsManifestParser.LoadMetadata(paths.PlondsUpdateMetadataPath); var currentDeployment = deploymentLocator.FindCurrentDeploymentDirectory(); var currentVersion = deploymentLocator.GetCurrentVersion(); var sourceVersion = string.IsNullOrWhiteSpace(currentVersion) ? "0.0.0" : currentVersion; - var expectedSourceVersion = PlondsManifestParser.ResolveSourceVersion(fileMap, pdcMetadata); + var expectedSourceVersion = PlondsManifestParser.ResolveSourceVersion(fileMap, plondsMetadata); if (!string.IsNullOrWhiteSpace(expectedSourceVersion) && !string.Equals(expectedSourceVersion, sourceVersion, StringComparison.OrdinalIgnoreCase)) { @@ -53,7 +53,7 @@ internal sealed class PlondsUpdateApplier( $"PLONDS update requires source version {expectedSourceVersion} but current is {sourceVersion}."); } - var targetVersion = PlondsManifestParser.ResolveTargetVersion(fileMap, pdcMetadata); + var targetVersion = PlondsManifestParser.ResolveTargetVersion(fileMap, plondsMetadata); if (string.IsNullOrWhiteSpace(targetVersion)) { targetVersion = sourceVersion; diff --git a/LanMountainDesktop.Shared.Contracts/Update/UpdateManifest.cs b/LanMountainDesktop.Shared.Contracts/Update/UpdateManifest.cs index 0c37626..3d627db 100644 --- a/LanMountainDesktop.Shared.Contracts/Update/UpdateManifest.cs +++ b/LanMountainDesktop.Shared.Contracts/Update/UpdateManifest.cs @@ -15,7 +15,7 @@ public sealed record UpdateManifest( IReadOnlyList? InstallerMirrors, IReadOnlyDictionary Metadata) { - public bool IsDelta => Kind is UpdatePayloadKind.DeltaPlonds or UpdatePayloadKind.DeltaLegacy; + public bool IsDelta => Kind is UpdatePayloadKind.DeltaPlonds; public long EstimatedDeltaBytes { diff --git a/LanMountainDesktop.Shared.Contracts/Update/UpdateState.cs b/LanMountainDesktop.Shared.Contracts/Update/UpdateState.cs index 7262b1c..336895d 100644 --- a/LanMountainDesktop.Shared.Contracts/Update/UpdateState.cs +++ b/LanMountainDesktop.Shared.Contracts/Update/UpdateState.cs @@ -22,7 +22,6 @@ public enum UpdatePhase public enum UpdatePayloadKind { DeltaPlonds, - DeltaLegacy, FullInstaller } diff --git a/LanMountainDesktop/Services/Update/UpdateInstallGateway.cs b/LanMountainDesktop/Services/Update/UpdateInstallGateway.cs index 122ace8..22bb49d 100644 --- a/LanMountainDesktop/Services/Update/UpdateInstallGateway.cs +++ b/LanMountainDesktop/Services/Update/UpdateInstallGateway.cs @@ -37,7 +37,7 @@ internal sealed class UpdateInstallGateway return new InstallResult(false, lockError, false, lockErrorCode); } - if (payloadKind is UpdatePayloadKind.DeltaPlonds or UpdatePayloadKind.DeltaLegacy) + if (payloadKind is UpdatePayloadKind.DeltaPlonds) { var launched = LaunchLauncherForApplyUpdate(launcherRoot); if (!launched) @@ -108,7 +108,7 @@ internal sealed class UpdateInstallGateway return false; } - var expectedKind = payloadKind is UpdatePayloadKind.DeltaLegacy or UpdatePayloadKind.DeltaPlonds ? "delta" : "full"; + var expectedKind = payloadKind is UpdatePayloadKind.DeltaPlonds ? "delta" : "full"; if (!string.Equals(deploymentLock.Kind, expectedKind, StringComparison.OrdinalIgnoreCase)) { errorCode = "lock_conflict"; diff --git a/LanMountainDesktop/Services/UpdateSettingsValues.cs b/LanMountainDesktop/Services/UpdateSettingsValues.cs index 303a2da..f0aafa7 100644 --- a/LanMountainDesktop/Services/UpdateSettingsValues.cs +++ b/LanMountainDesktop/Services/UpdateSettingsValues.cs @@ -15,11 +15,7 @@ public static class UpdateSettingsValues // NOTE: keep constant name for compatibility with existing call sites. public const string DownloadSourcePlonds = "plonds-api"; - public const string DownloadSourcePdc = DownloadSourcePlonds; public const string DownloadSourceStcn = DownloadSourcePlonds; - public const string LegacyDownloadSourcePlonds = "pdc"; - public const string LegacyDownloadSourcePdc = LegacyDownloadSourcePlonds; - public const string LegacyDownloadSourceStcn = "stcn"; public const string DownloadSourceGitHub = "github"; public const string DownloadSourceGhProxy = "gh-proxy"; public const string PlondsStaticBaseUrlEnvironmentVariable = "LANMOUNTAIN_UPDATE_BASE_URL"; @@ -62,12 +58,12 @@ public static class UpdateSettingsValues public static string NormalizeDownloadSource(string? value) { - if (string.Equals(value, LegacyDownloadSourcePlonds, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(value, "pdc", StringComparison.OrdinalIgnoreCase)) { return DownloadSourcePlonds; } - if (string.Equals(value, LegacyDownloadSourceStcn, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(value, "stcn", StringComparison.OrdinalIgnoreCase)) { return DownloadSourcePlonds; } diff --git a/LanMountainDesktop/ViewModels/UpdateSettingsViewModel.cs b/LanMountainDesktop/ViewModels/UpdateSettingsViewModel.cs index 8057bfb..7982748 100644 --- a/LanMountainDesktop/ViewModels/UpdateSettingsViewModel.cs +++ b/LanMountainDesktop/ViewModels/UpdateSettingsViewModel.cs @@ -99,7 +99,7 @@ public sealed partial class UpdateSettingsViewModel : ViewModelBase, IDisposable [ObservableProperty] private bool _forceReinstall; [ObservableProperty] private string _selectedUpdateChannelValue = UpdateSettingsValues.ChannelStable; - [ObservableProperty] private string _selectedUpdateSourceValue = UpdateSettingsValues.DownloadSourcePdc; + [ObservableProperty] private string _selectedUpdateSourceValue = UpdateSettingsValues.DownloadSourcePlonds; [ObservableProperty] private string _selectedUpdateModeValue = UpdateSettingsValues.ModeSilentDownload; [ObservableProperty] private double _downloadThreadsSliderValue = UpdateSettingsValues.DefaultDownloadThreads; @@ -220,7 +220,7 @@ public sealed partial class UpdateSettingsViewModel : ViewModelBase, IDisposable LatestVersionText = report.LatestVersion ?? string.Empty; PublishedAtText = report.PublishedAt?.ToLocalTime().ToString("g", CultureInfo.CurrentCulture) ?? string.Empty; UpdateTypeText = GetUpdateTypeText(report.PayloadKind); - IsDeltaUpdate = report.PayloadKind is UpdatePayloadKind.DeltaPlonds or UpdatePayloadKind.DeltaLegacy; + IsDeltaUpdate = report.PayloadKind is UpdatePayloadKind.DeltaPlonds; StatusMessage = report.LatestVersion is null ? GetUpdateAvailableStatusText(string.Empty) : string.Format(CultureInfo.CurrentCulture, L("settings.update.status_available_format", "New version {0} is available. Click Download and Install."), report.LatestVersion); @@ -627,7 +627,7 @@ public sealed partial class UpdateSettingsViewModel : ViewModelBase, IDisposable return payloadKind switch { - UpdatePayloadKind.DeltaPlonds or UpdatePayloadKind.DeltaLegacy => L("settings.update.type_delta", "Incremental Update"), + UpdatePayloadKind.DeltaPlonds => L("settings.update.type_delta", "Incremental Update"), UpdatePayloadKind.FullInstaller => L("settings.update.type_reinstall", "Reinstall"), _ => string.Empty }; diff --git a/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Core/Publishing/DdssBuildOptions.cs b/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Core/Publishing/PlondsBuildOptions.cs similarity index 82% rename from PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Core/Publishing/DdssBuildOptions.cs rename to PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Core/Publishing/PlondsBuildOptions.cs index 8f6fe9b..366115e 100644 --- a/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Core/Publishing/DdssBuildOptions.cs +++ b/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Core/Publishing/PlondsBuildOptions.cs @@ -1,6 +1,6 @@ namespace Plonds.Core.Publishing; -public sealed record DdssBuildOptions( +public sealed record PlondsBuildOptions( string ReleaseTag, string AssetsDirectory, string OutputRoot, diff --git a/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Core/Publishing/DdssManifestBuilder.cs b/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Core/Publishing/PlondsManifestBuilder.cs similarity index 71% rename from PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Core/Publishing/DdssManifestBuilder.cs rename to PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Core/Publishing/PlondsManifestBuilder.cs index 36c36c8..5e1c429 100644 --- a/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Core/Publishing/DdssManifestBuilder.cs +++ b/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Core/Publishing/PlondsManifestBuilder.cs @@ -3,18 +3,18 @@ using Plonds.Shared.Models; namespace Plonds.Core.Publishing; -public sealed class DdssManifestBuilder +public sealed class PlondsManifestBuilder { private readonly RsaFileSigner _signer = new(); - public string Build(DdssBuildOptions options) + public string Build(PlondsBuildOptions options) { ArgumentNullException.ThrowIfNull(options); var assetsDirectory = Path.GetFullPath(options.AssetsDirectory); if (!Directory.Exists(assetsDirectory)) { - throw new DirectoryNotFoundException($"DDSS assets directory not found: {assetsDirectory}"); + throw new DirectoryNotFoundException($"PLONDS assets directory not found: {assetsDirectory}"); } var assetEntries = Directory @@ -22,14 +22,14 @@ public sealed class DdssManifestBuilder .Where(static path => { var name = Path.GetFileName(path); - return !name.Equals("ddss.json", StringComparison.OrdinalIgnoreCase) - && !name.Equals("ddss.json.sig", StringComparison.OrdinalIgnoreCase); + return !name.Equals("plonds.json", StringComparison.OrdinalIgnoreCase) + && !name.Equals("plonds.json.sig", StringComparison.OrdinalIgnoreCase); }) .OrderBy(static path => Path.GetFileName(path), StringComparer.OrdinalIgnoreCase) .Select(path => BuildAssetEntry(path, options.Repository, options.ReleaseTag, options.S3BaseUrl)) .ToArray(); - var manifest = new DdssManifest( + var manifest = new PlondsManifest( FormatVersion: "1.0", ReleaseTag: options.ReleaseTag, GeneratedAt: DateTimeOffset.UtcNow, @@ -37,28 +37,28 @@ public sealed class DdssManifestBuilder var outputRoot = Path.GetFullPath(options.OutputRoot); Directory.CreateDirectory(outputRoot); - var manifestPath = Path.Combine(outputRoot, "ddss.json"); + var manifestPath = Path.Combine(outputRoot, "plonds.json"); PayloadUtilities.WriteJson(manifestPath, manifest); _signer.SignFile(manifestPath, options.PrivateKeyPath, manifestPath + ".sig"); return manifestPath; } - private static DdssAssetEntry BuildAssetEntry(string assetPath, string repository, string releaseTag, string? s3BaseUrl) + private static PlondsAssetEntry BuildAssetEntry(string assetPath, string repository, string releaseTag, string? s3BaseUrl) { var fileName = Path.GetFileName(assetPath); - var mirrors = new List + var mirrors = new List { new("github", $"https://github.com/{repository}/releases/download/{releaseTag}/{Uri.EscapeDataString(fileName)}") }; if (!string.IsNullOrWhiteSpace(s3BaseUrl)) { - mirrors.Add(new DdssMirrorEntry( + mirrors.Add(new PlondsMirrorEntry( "s3", $"{s3BaseUrl.TrimEnd('/')}/{Uri.EscapeDataString(fileName)}")); } - return new DdssAssetEntry( + return new PlondsAssetEntry( AssetId: fileName, FileName: fileName, Sha256: PayloadUtilities.ComputeSha256(assetPath), diff --git a/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/DdssAssetEntry.cs b/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/PlondsAssetEntry.cs similarity index 56% rename from PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/DdssAssetEntry.cs rename to PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/PlondsAssetEntry.cs index f1710f3..69f1473 100644 --- a/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/DdssAssetEntry.cs +++ b/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/PlondsAssetEntry.cs @@ -1,8 +1,8 @@ namespace Plonds.Shared.Models; -public sealed record DdssAssetEntry( +public sealed record PlondsAssetEntry( string AssetId, string FileName, string Sha256, long Size, - IReadOnlyList Mirrors); + IReadOnlyList Mirrors); diff --git a/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/DdssManifest.cs b/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/PlondsManifest.cs similarity index 58% rename from PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/DdssManifest.cs rename to PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/PlondsManifest.cs index 94ccc59..4fa67b8 100644 --- a/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/DdssManifest.cs +++ b/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/PlondsManifest.cs @@ -1,7 +1,7 @@ namespace Plonds.Shared.Models; -public sealed record DdssManifest( +public sealed record PlondsManifest( string FormatVersion, string ReleaseTag, DateTimeOffset GeneratedAt, - IReadOnlyList Assets); + IReadOnlyList Assets); diff --git a/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/DdssMirrorEntry.cs b/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/PlondsMirrorEntry.cs similarity index 63% rename from PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/DdssMirrorEntry.cs rename to PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/PlondsMirrorEntry.cs index 77af7f4..afcbd43 100644 --- a/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/DdssMirrorEntry.cs +++ b/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Shared/Models/PlondsMirrorEntry.cs @@ -1,5 +1,5 @@ namespace Plonds.Shared.Models; -public sealed record DdssMirrorEntry( +public sealed record PlondsMirrorEntry( string Type, string Url); diff --git a/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Tool/Program.cs b/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Tool/Program.cs index 871f47d..bf49bd0 100644 --- a/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Tool/Program.cs +++ b/PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Tool/Program.cs @@ -38,8 +38,8 @@ internal static class PlondsCli case "build-index": RunBuildIndex(options); return Task.FromResult(0); - case "build-ddss": - RunBuildDdss(options); + case "build-plonds": + RunBuildPlonds(options); return Task.FromResult(0); default: Console.Error.WriteLine($"Unknown command: {command}"); @@ -157,10 +157,10 @@ internal static class PlondsCli Console.WriteLine(manifestPath); } - private static void RunBuildDdss(Dictionary options) + private static void RunBuildPlonds(Dictionary options) { - var builder = new DdssManifestBuilder(); - var manifestPath = builder.Build(new DdssBuildOptions( + var builder = new PlondsManifestBuilder(); + var manifestPath = builder.Build(new PlondsBuildOptions( ReleaseTag: Require(options, "release-tag"), AssetsDirectory: Require(options, "assets-dir"), OutputRoot: Require(options, "output-dir"), @@ -215,7 +215,7 @@ internal static class PlondsCli Console.WriteLine(" pack-payload --source-dir --output-zip "); Console.WriteLine(" build-delta --platform --current-version --current-tag --current-zip --output-dir --private-key [--baseline-tag ] [--baseline-version ] [--baseline-zip ] [--is-full-payload] [--static-output-dir ] [--update-base-url ]"); Console.WriteLine(" build-index --release-tag --version --platform-summaries-dir --output-dir --private-key [--channel ]"); - Console.WriteLine(" build-ddss --release-tag --assets-dir --output-dir --private-key --repository [--s3-base-url ]"); + Console.WriteLine(" build-plonds --release-tag --assets-dir --output-dir --private-key --repository [--s3-base-url ]"); Console.WriteLine(" sign --manifest --private-key [--output ]"); Console.WriteLine(" generate --current-version --current-dir --platform --output-dir [--previous-version ] [--previous-dir ]"); Console.WriteLine(" publish --version --app-artifacts-root --installer-artifacts-root --output-dir --private-key [--baseline-root ]"); diff --git a/docs/auto_commit_md/20260512_563f12ca.md b/docs/auto_commit_md/20260512_563f12ca.md index b9adfb5..3c1d302 100644 --- a/docs/auto_commit_md/20260512_563f12ca.md +++ b/docs/auto_commit_md/20260512_563f12ca.md @@ -31,7 +31,7 @@ | Category | Count | Files | |----------|-------|-------| -| CI/CD Workflows | 3 | `ddss-publish.yml`, `ddss-rollback.yml`, `plonds-build.yml` | +| CI/CD Workflows | 3 | `plonds-uploader.yml`, `plonds-rollback.yml`, `plonds-comparator.yml` | | Shared Contracts | 3 | `DeploymentLock.cs`, `UpdatePaths.cs`, `UpdateState.cs` | | Launcher | 2 | `AppJsonContext.cs`, `UpdateModels.cs` | | Services | 7 | `UpdateEngineService.cs`, `DeploymentLockService.cs`, `UpdateDownloadEngine.cs`, `UpdateInstallGateway.cs`, `UpdateOrchestrator.cs`, `UpdateWorkflowService.cs`, `WindowPassthroughService.cs` | @@ -49,7 +49,7 @@ ### 1. CI/CD Workflows Enhancement -#### `.github/workflows/ddss-publish.yml` (+106 lines) +#### `.github/workflows/plonds-uploader.yml` (+106 lines) **Purpose:** Enhanced deployment publishing workflow **Key Changes:** @@ -58,7 +58,7 @@ - Added atomic channel pointer publishing - Improved deployment pipeline reliability -#### `.github/workflows/ddss-rollback.yml` (+146 lines) — **NEW** +#### `.github/workflows/plonds-rollback.yml` (+146 lines) — **NEW** **Purpose:** Automated rollback workflow **Key Features:** @@ -66,7 +66,7 @@ - Emergency deployment recovery - Version rollback automation -#### `.github/workflows/plonds-build.yml` (+5 lines) +#### `.github/workflows/plonds-comparator.yml` (+5 lines) **Changes:** - Adjusted build concurrency settings - Updated release event triggers