Просмотр исходного кода

Add checksum creation/upload in cache-save and checksum verification in cache-restore

TheWildJames 4 месяцев назад
Родитель
Сommit
2420cc28b1
2 измененных файлов с 80 добавлено и 8 удалено
  1. 61 8
      .github/actions/cache-restore/action.yml
  2. 19 0
      .github/actions/cache-save/action.yml

+ 61 - 8
.github/actions/cache-restore/action.yml

@@ -239,29 +239,72 @@ runs:
               # Create a concatenated archive file but keep parts until extraction succeeds
               cat "${PARTS_ARRAY[@]}" > "$FINAL_ARCHIVE"
 
+              # Attempt to fetch checksum asset (FILENAME.sha256) and verify before extracting
+              CHECKSUM_FILE="$FINAL_ARCHIVE.sha256"
+              EXPECTED_SUM=""
+              if command -v gh >/dev/null 2>&1; then
+                if gh release view "$TAG_NAME" --repo "$TARGET_REPO" >/dev/null 2>&1; then
+                  if gh release download "$TAG_NAME" --repo "$TARGET_REPO" --pattern "$CHECKSUM_FILE" -D . >/dev/null 2>&1; then
+                    if [ -s "$CHECKSUM_FILE" ]; then
+                      EXPECTED_SUM=$(awk '{print $1}' "$CHECKSUM_FILE" || true)
+                      echo "Found checksum for $FINAL_ARCHIVE: $EXPECTED_SUM"
+                    fi
+                  fi
+                fi
+              fi
+
               MAX_EXTRACT_ATTEMPTS=3
               attempt=1
               extracted=false
               while [ $attempt -le $MAX_EXTRACT_ATTEMPTS ]; do
                 echo "Attempting extraction (attempt $attempt/$MAX_EXTRACT_ATTEMPTS)"
-                if [ "$COMPRESSED" = "true" ]; then
-                  if tar -I "zstd -d -T0" -xf "$FINAL_ARCHIVE" -C "$EXTRACT_DIR"; then
+
+                # If we have an expected checksum, verify it
+                if [ -n "$EXPECTED_SUM" ]; then
+                  if command -v sha256sum >/dev/null 2>&1; then
+                    ACTUAL_SUM=$(sha256sum "$FINAL_ARCHIVE" | awk '{print $1}') || ACTUAL_SUM=""
+                  else
+                    ACTUAL_SUM=$(openssl dgst -sha256 "$FINAL_ARCHIVE" | awk '{print $2}') || ACTUAL_SUM=""
+                  fi
+                  echo "  actual=$ACTUAL_SUM expected=$EXPECTED_SUM"
+                  if [ -n "$ACTUAL_SUM" ] && [ "$ACTUAL_SUM" != "$EXPECTED_SUM" ]; then
+                    echo "  ⚠️ Checksum mismatch (will re-download parts)"
+                    extracted=false
+                  else
+                    echo "  Checksum OK or not provided, proceeding to extract"
                     extracted=true
-                    break
                   fi
                 else
-                  if tar -xf "$FINAL_ARCHIVE" -C "$EXTRACT_DIR"; then
-                    extracted=true
-                    break
+                  echo "  No checksum available, proceeding to extraction"
+                  extracted=true
+                fi
+
+                if [ "$extracted" = "true" ]; then
+                  if [ "$COMPRESSED" = "true" ]; then
+                    if tar -I "zstd -d -T0" -xf "$FINAL_ARCHIVE" -C "$EXTRACT_DIR"; then
+                      extracted=true
+                      break
+                    else
+                      extracted=false
+                    fi
+                  else
+                    if tar -xf "$FINAL_ARCHIVE" -C "$EXTRACT_DIR"; then
+                      extracted=true
+                      break
+                    else
+                      extracted=false
+                    fi
                   fi
                 fi
 
-                echo "Extraction failed (possible truncated download)."
+                echo "Extraction failed (possible truncated download or checksum mismatch)."
                 if [ $attempt -lt $MAX_EXTRACT_ATTEMPTS ]; then
                   echo "Re-downloading split parts and retrying..."
-                  # redownload each part (overwrite)
+                  # remove concatenated before re-download
+                  rm -f "$FINAL_ARCHIVE"
                   for part_file in "${PARTS_ARRAY[@]}"; do
                     echo "  Re-downloading $part_file"
+                    rm -f "$part_file"
                     if ! download_asset "$part_file" "$BASE_URL/$part_file"; then
                       echo "::error::Failed to re-download $part_file"
                       exit 1
@@ -269,6 +312,16 @@ runs:
                   done
                   # rebuild concatenated archive
                   cat "${PARTS_ARRAY[@]}" > "$FINAL_ARCHIVE"
+                  # re-fetch checksum if available
+                  if command -v gh >/dev/null 2>&1; then
+                    rm -f "$CHECKSUM_FILE"
+                    gh release download "$TAG_NAME" --repo "$TARGET_REPO" --pattern "$CHECKSUM_FILE" -D . >/dev/null 2>&1 || true
+                    if [ -s "$CHECKSUM_FILE" ]; then
+                      EXPECTED_SUM=$(awk '{print $1}' "$CHECKSUM_FILE" || true)
+                    else
+                      EXPECTED_SUM=""
+                    fi
+                  fi
                 fi
                 attempt=$((attempt+1))
               done

+ 19 - 0
.github/actions/cache-save/action.yml

@@ -202,6 +202,14 @@ runs:
           
           FILE_SIZE=$(stat -c%s "$FILENAME")
           echo "Archive created: $FILENAME ($FILE_SIZE bytes)"
+          # Create SHA256 checksum and upload alongside the archive/parts
+          if command -v sha256sum >/dev/null 2>&1; then
+            sha256sum "$FILENAME" | awk '{print $1}' > "$FILENAME.sha256"
+          else
+            # fallback using openssl
+            openssl dgst -sha256 "$FILENAME" | awk '{print $2}' > "$FILENAME.sha256" || true
+          fi
+          echo "Checksum written: $FILENAME.sha256"
           echo "::endgroup::"
           
           echo "::group:: [$((idx+1))/${#PATHS_ARRAY[@]}] Uploading Assets ($CACHE_BUCKET)"
@@ -235,6 +243,11 @@ runs:
               fi
               rm -f "$part"
             done
+            # Upload checksum for the original archive
+            echo "  Uploading checksum $FILENAME.sha256..."
+            if ! upload_with_retry "$FILENAME.sha256" "$TAG_NAME"; then
+              echo "::warning::Failed to upload checksum $FILENAME.sha256"
+            fi
             rm -rf "$FILENAME"
           else
             echo "  File size: $((FILE_SIZE / 1024 / 1024))MB"
@@ -242,7 +255,13 @@ runs:
             if ! upload_with_retry "$FILENAME" "$TAG_NAME"; then
               echo "::warning::Failed to upload $FILENAME after 3 attempts. The cache will not be available for next run."
             fi
+            # Upload checksum alongside the archive
+            echo "  Uploading checksum $FILENAME.sha256..."
+            if ! upload_with_retry "$FILENAME.sha256" "$TAG_NAME"; then
+              echo "::warning::Failed to upload checksum $FILENAME.sha256"
+            fi
             rm -f "$FILENAME"
+            rm -f "$FILENAME.sha256"
           fi
           echo "::endgroup::"
         done