name: PLONDS Comparator concurrency: group: plonds-${{ github.event_name }}-${{ github.event.release.tag_name || github.event.inputs.tag || github.run_id }} cancel-in-progress: false on: release: types: - published - prereleased workflow_dispatch: inputs: tag: description: 'Release tag' required: true type: string baseline_tag: description: 'Optional baseline tag (auto-detected if omitted)' required: false type: string channel: description: 'Update channel' required: false type: choice default: stable options: - stable - preview compare_method: description: '比较方法' required: false type: choice default: file-compare options: - file-compare - commit-analyze hash_algorithm: description: '哈希算法(仅 file-compare 模式)' required: false type: choice default: sha256 options: - sha256 - md5 env: DOTNET_VERSION: '10.0.x' jobs: compare: runs-on: ubuntu-latest permissions: contents: write steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 submodules: recursive - name: Resolve release context shell: bash run: | set -euo pipefail if [[ "${{ github.event_name }}" == "release" ]]; then TAG="${{ github.event.release.tag_name }}" if [[ "${{ github.event.release.prerelease }}" == "true" ]]; then CHANNEL="preview" else CHANNEL="stable" fi BASELINE_TAG_INPUT="" COMPARE_METHOD="file-compare" HASH_ALGORITHM="sha256" else RAW_TAG="${{ github.event.inputs.tag }}" if [[ "${RAW_TAG}" == v* ]]; then TAG="${RAW_TAG}" else TAG="v${RAW_TAG}" fi CHANNEL="${{ github.event.inputs.channel }}" BASELINE_TAG_INPUT="${{ github.event.inputs.baseline_tag }}" COMPARE_METHOD="${{ github.event.inputs.compare_method }}" HASH_ALGORITHM="${{ github.event.inputs.hash_algorithm }}" fi echo "RELEASE_TAG=${TAG}" >> "$GITHUB_ENV" echo "RELEASE_VERSION=${TAG#v}" >> "$GITHUB_ENV" echo "RELEASE_CHANNEL=${CHANNEL}" >> "$GITHUB_ENV" echo "BASELINE_TAG_INPUT=${BASELINE_TAG_INPUT}" >> "$GITHUB_ENV" echo "COMPARE_METHOD=${COMPARE_METHOD}" >> "$GITHUB_ENV" echo "HASH_ALGORITHM=${HASH_ALGORITHM}" >> "$GITHUB_ENV" - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} dotnet-quality: preview - name: Build PLONDS tool run: dotnet build PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Tool/Plonds.Tool.csproj -c Release - name: Resolve baseline env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} shell: bash run: | set -euo pipefail BASELINE_TAG="" BASELINE_VERSION="" if [[ -n "$BASELINE_TAG_INPUT" ]]; then NORMALIZED="$BASELINE_TAG_INPUT" if [[ "$NORMALIZED" != v* ]]; then NORMALIZED="v$NORMALIZED"; fi if gh release view "$NORMALIZED" --repo "${{ github.repository }}" --json tagName >/dev/null 2>&1; then BASELINE_TAG="$NORMALIZED" BASELINE_VERSION="${NORMALIZED#v}" else echo "Specified baseline tag not found: $NORMALIZED" exit 1 fi else IS_PRERELEASE="$(gh release view "$RELEASE_TAG" --repo "${{ github.repository }}" --json isPrerelease --jq '.isPrerelease')" CANDIDATES="$(gh api "repos/${{ github.repository }}/releases?per_page=50" \ --jq ".[] | select(.draft == false and .prerelease == ${IS_PRERELEASE} and .tag_name != \"${RELEASE_TAG}\") | .tag_name")" for CANDIDATE in $CANDIDATES; do if gh release download "$CANDIDATE" -p "files-windows-x64.zip" -D /tmp/baseline-check --clobber 2>/dev/null; then BASELINE_TAG="$CANDIDATE" BASELINE_VERSION="${CANDIDATE#v}" rm -rf /tmp/baseline-check break fi done fi if [[ -n "$BASELINE_TAG" ]]; then echo "BASELINE_TAG=${BASELINE_TAG}" >> "$GITHUB_ENV" echo "BASELINE_VERSION=${BASELINE_VERSION}" >> "$GITHUB_ENV" echo "Resolved baseline: ${BASELINE_TAG}" else echo "No baseline found. This will be a full update." fi - name: Download payload zips env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} shell: bash run: | set -euo pipefail mkdir -p plonds-input gh release download "$RELEASE_TAG" -p "files-windows-x64.zip" -D plonds-input mv plonds-input/files-windows-x64.zip plonds-input/current-files-windows-x64.zip if [[ -n "$BASELINE_TAG" ]]; then gh release download "$BASELINE_TAG" -p "files-windows-x64.zip" -D /tmp/baseline-dl mv /tmp/baseline-dl/files-windows-x64.zip plonds-input/baseline-files-windows-x64.zip fi - name: Run build-delta (file-compare) if: env.COMPARE_METHOD == 'file-compare' shell: bash run: | set -euo pipefail mkdir -p plonds-output ARGS=( 'run' '--project' 'PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Tool/Plonds.Tool.csproj' '--configuration' 'Release' '--' 'build-delta' '--platform' 'windows-x64' '--current-version' "$RELEASE_VERSION" '--current-zip' "$PWD/plonds-input/current-files-windows-x64.zip" '--output-dir' "$PWD/plonds-output" '--channel' "$RELEASE_CHANNEL" '--hash-algorithm' "$HASH_ALGORITHM" ) if [[ -n "$BASELINE_TAG" ]]; then ARGS+=( '--baseline-version' "$BASELINE_VERSION" '--baseline-zip' "$PWD/plonds-input/baseline-files-windows-x64.zip" ) fi dotnet "${ARGS[@]}" - name: Run build-delta-from-commits (commit-analyze) if: env.COMPARE_METHOD == 'commit-analyze' shell: bash run: | set -euo pipefail mkdir -p plonds-output ARGS=( 'run' '--project' 'PenguinLogisticsOnlineNetworkDistributionSystem/src/Plonds.Tool/Plonds.Tool.csproj' '--configuration' 'Release' '--' 'build-delta-from-commits' '--platform' 'windows-x64' '--current-version' "$RELEASE_VERSION" '--current-zip' "$PWD/plonds-input/current-files-windows-x64.zip" '--output-dir' "$PWD/plonds-output" '--channel' "$RELEASE_CHANNEL" '--baseline-tag' "${BASELINE_TAG:-v0.0.0}" '--current-tag' "$RELEASE_TAG" '--hash-algorithm' "$HASH_ALGORITHM" ) if [[ -n "$BASELINE_TAG" ]]; then ARGS+=( '--baseline-version' "$BASELINE_VERSION" '--fallback-zip' "$PWD/plonds-input/baseline-files-windows-x64.zip" ) fi dotnet "${ARGS[@]}" - name: Validate output shell: bash run: | set -euo pipefail if [[ ! -f plonds-output/changed.zip ]]; then echo "Missing output: changed.zip" exit 1 fi if [[ ! -f plonds-output/PLONDS.json ]]; then echo "Missing output: PLONDS.json" exit 1 fi jq -e . plonds-output/PLONDS.json >/dev/null - name: Upload to GitHub Release env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} shell: bash run: | set -euo pipefail gh release upload "$RELEASE_TAG" plonds-output/changed.zip plonds-output/PLONDS.json --clobber - name: Persist run metadata shell: bash run: | mkdir -p plonds-run-metadata printf '%s' "$RELEASE_TAG" > plonds-run-metadata/tag.txt printf '%s' "$COMPARE_METHOD" >> plonds-run-metadata/tag.txt - name: Upload run metadata artifact uses: actions/upload-artifact@v4 with: name: plonds-run-metadata path: plonds-run-metadata/tag.txt if-no-files-found: error retention-days: 7