Ver código fonte

fix(action): implement save and restore cache actions with enhanced functionality

Co-authored-by: Copilot <copilot@github.com>
TheWildJames 4 meses atrás
pai
commit
5c265ae862

+ 167 - 0
.github/actions/restore-cache/action.yml

@@ -0,0 +1,167 @@
+name: 'Restore Cache'
+description: 'Restores cache from GitHub Releases based on provided keys and bucket'
+
+inputs:
+  cache_path:
+    description: 'Path where cache should be restored'
+    required: true
+    type: string
+  cache_key:
+    description: 'Primary key to restore cache'
+    required: true
+    type: string
+  restore_keys:
+    description: 'Multiline list of keys (fallback prefixes)'
+    required: false
+    type: string
+    default: ""
+  cache_bucket:
+    description: 'The tag name for the release (e.g., general-cache)'
+    required: true
+    default: 'general-cache'
+  compression_level:
+    description: 'Compression level (0-9). 0 = No compression, 1 = Fast, 19 = Best.'
+    required: false
+    type: number
+    default: 6
+
+runs:
+  using: 'composite'
+  steps:
+    - name: Detect and Download Cache
+      shell: bash
+      working-directory: ${{ github.workspace }}
+      env:
+        TARGET_REPO: "${{ github.repository }}"
+      run: |
+        TAG_NAME="${{ inputs.cache_bucket }}"
+        BASE_URL="https://github.com/${TARGET_REPO}/releases/download/$TAG_NAME"
+        ASSETS_URL="https://github.com/${TARGET_REPO}/releases/expanded_assets/$TAG_NAME"
+        
+        ARIA2_OPTS=(
+          "-x16" "-s16" "-k1M" "-j5" "--file-allocation=none"
+          "--header=User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
+          "--header=Accept: */*"
+          "--header=Connection: keep-alive"
+        )
+        
+        ARIA2_OPTS+=("--quiet" "--summary-interval=0" "--console-log-level=error")
+        
+        echo "::group:: Fetching Asset List"
+        HTTP_RESPONSE=$(curl -sL -A "Mozilla/5.0" -w "%{http_code}" "$ASSETS_URL" -o assets.html || echo "404")
+        
+        if [ "$HTTP_RESPONSE" -eq 200 ]; then
+          ALL_ASSETS=$(grep -oP "download/$TAG_NAME/\K[^\"' ]+" assets.html | sort -u || echo "")
+        else
+          echo "Status $HTTP_RESPONSE: Failed to fetch assets from scraper endpoint."
+          ALL_ASSETS=""
+        fi
+        rm -f assets.html
+        
+        if [ -z "$ALL_ASSETS" ]; then
+          echo "No assets found in bucket '$TAG_NAME'. Skipping search."
+          echo "::endgroup::"
+        else
+          echo "Successfully fetched asset list. Has $(echo "$ALL_ASSETS" | wc -l) assets."
+          echo "::endgroup::"
+          
+          SEARCH_LIST=$(printf "%s\n%s" "${{ inputs.cache_key }}" "${{ inputs.restore_keys }}" | sed '/^$/d')
+          
+          FOUND=false
+          while read -r KEY; do
+            [ -z "$KEY" ] && continue
+            echo "::group:: Searching Prefix: $KEY"
+            
+            MATCH=$(echo "$ALL_ASSETS" | grep "^cache-$KEY" | sort -r | head -n 1 || true)
+            
+            if [ -z "$MATCH" ]; then
+                echo "Not found."
+                echo "::endgroup::"
+                continue
+            fi
+            
+            BASE_FILENAME=$(echo "$MATCH" | sed -E 's/\.(tzst|tar)(\.part[a-z]{2})?$//')
+            EXT=$(echo "$MATCH" | grep -oP '\.(tzst|tar)' | head -n 1)
+            
+            [[ "$MATCH" == *".part"* ]] && IS_SPLIT=true || IS_SPLIT=false
+            [ "$EXT" = ".tzst" ] && COMPRESSED=true || COMPRESSED=false
+            FOUND=true
+            
+            echo "✅ Hit! Restoring $BASE_FILENAME$EXT"
+            echo "::endgroup::"
+            
+            echo "::group:: Downloading Cache"
+            
+            download_asset() {
+              local filename="$1"
+              local url="$2"
+              local max_retries=3
+              local attempt=1
+              
+              while [ $attempt -le $max_retries ]; do
+                echo "  Attempt $attempt: Downloading $filename..."
+                
+                if timeout 10m aria2c "${ARIA2_OPTS[@]}" --retry-wait=10 --max-tries=10 -o "$filename" "$url"; then
+                  return 0
+                fi
+                
+                echo "  ⚠️ Download failed or timed out. Retrying in 5s..."
+                sleep 5
+                attempt=$((attempt + 1))
+              done
+              return 1
+            }
+            
+            if [ "$IS_SPLIT" = "true" ]; then
+              for part in {a..z}{a..z}; do
+                PART_NAME="$BASE_FILENAME$EXT.part$part"
+                if echo "$ALL_ASSETS" | grep -q "^$PART_NAME$"; then
+                  if ! download_asset "$PART_NAME" "$BASE_URL/$PART_NAME"; then
+                    echo "::error::Failed to download $PART_NAME after multiple retries."
+                    exit 1
+                  fi
+                else break; fi
+              done
+            else
+              if ! download_asset "$BASE_FILENAME$EXT" "$BASE_URL/$BASE_FILENAME$EXT"; then
+                echo "::error::Failed to download $BASE_FILENAME$EXT after multiple retries."
+                exit 1
+              fi
+            fi
+            echo "::endgroup::"
+            
+            echo "::group:: Extracting Cache"
+            mkdir -p "${{ inputs.cache_path }}"
+            FINAL_ARCHIVE="$BASE_FILENAME$EXT"
+            EXTRACT_DIR="$(dirname "${{ inputs.cache_path }}")"
+            
+            extract_cache() {
+              local cmd="$1"
+              sh -c "$cmd" > /dev/null 2>&1
+            }
+            
+            if [ "$IS_SPLIT" = "true" ]; then
+              PARTS=$(ls "$FINAL_ARCHIVE.part"* | sort)
+              if [ "$COMPRESSED" = "true" ]; then
+                extract_cache "cat $PARTS | tar -I 'zstd -d -T0' -xvf - -C '$EXTRACT_DIR'"
+              else
+                extract_cache "cat $PARTS | tar -xvf - -C '$EXTRACT_DIR'"
+              fi
+              rm -f $PARTS
+            else
+              if [ "$COMPRESSED" = "true" ]; then
+                extract_cache "tar -I 'zstd -d -T0' -xvf '$FINAL_ARCHIVE' -C '$EXTRACT_DIR'"
+              else
+                extract_cache "tar -xvf '$FINAL_ARCHIVE' -C '$EXTRACT_DIR'"
+              fi
+              rm -f "$FINAL_ARCHIVE"
+            fi
+            echo "✅ Restore complete."
+            echo "::endgroup::"
+            break
+          done <<< "$SEARCH_LIST"
+          
+          if [ "$FOUND" = "false" ]; then
+              echo "⚠️ No cache matches found. Proceeding with fresh run."
+          fi
+        fi

+ 115 - 44
.github/actions/save-cache/action.yml

@@ -1,52 +1,123 @@
-name: 'Build Kernel'
-description: 'Builds kernel using legacy build.sh or Bazel (kleaf)'
+name: 'Save Cache'
+description: 'Archives and uploads cache to GitHub Releases with intelligent splitting and retry logic'
+
+inputs:
+  cache_path:
+    description: 'Path where cache is saved'
+    required: true
+    type: string
+  cache_key:
+    description: 'Unique key for the cache'
+    required: true
+    type: string
+  cache_bucket:
+    description: 'The tag name for the release (e.g., general-cache)'
+    required: true
+    default: 'general-cache'
+  compression_level:
+    description: 'Compression level (0-9). 0 = No compression, 1 = Fast, 19 = Best.'
+    required: false
+    type: number
+    default: 6
 
 runs:
-  using: composite
+  using: 'composite'
   steps:
-    - shell: bash
-      working-directory: ${{ github.workspace }}/kernel
+    - name: Archive, Split, and Upload Cache
+      shell: bash
+      env:
+        GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        TARGET_REPO: "${{ github.repository }}"
       run: |
-        set -euo pipefail
-        # Install ccache with ECS by cctv18
-        echo "Install ccache with ECS"
-        curl -LfsS --retry 5 --retry-delay 5 --retry-all-errors --connect-timeout 30 --tcp-fastopen -H "User-Agent: Mozilla/5.0" "https://github.com/WildKernels/kernel_patches/raw/refs/heads/main/ccache/ccache-x86-64" -o ccache
-        sudo cp -f ./ccache /usr/bin/ccache
-        sudo chmod +x /usr/bin/ccache
-        rm -f ./ccache
-        echo "/usr/lib/ccache" >> $GITHUB_PATH
-        export CCACHE_DIR="$GITHUB_WORKSPACE/.ccache"
-        export LDCACHE_DIR="${{ github.workspace }}/.ld_cache"
-        export CC="ccache clang"
-        export CXX="ccache clang++"
-        export HOSTCC="ccache clang"
-        export HOSTCXX="ccache clang++"
-        export CCACHE_MAXSIZE=10G
-        export CCACHE_COMPILERCHECK=content
-        export CCACHE_BASEDIR="$GITHUB_WORKSPACE"
-        export CCACHE_NOHASHDIR=true
-        export CCACHE_COMPRESSION=true
-        export CCACHE_COMPRESSION_LEVEL=3
-        export CCACHE_DIRECT=true
-        export CCACHE_FILE_CLONE=true
-        export CCACHE_INODE_CACHE=true
-        CCACHE_IS_KERNEL_COMPILING=true
-        export CCACHE_UMASK=002
-        export CCACHE_SLOPPINESS="file_macro,time_macros,include_file_mtime,include_file_ctime,pch_defines,system_headers,locale"
-        if ccache --help 2>&1 | grep -q 'depend_mode'; then
-          export CCACHE_DEPEND=true
+        # Archive, Split, and Upload Cache
+        git config user.name "github-actions[bot]"
+        git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+        
+        TAG_NAME="${{ inputs.cache_bucket }}"
+        BASE_FILENAME="cache-${{ inputs.cache_key }}"
+        
+        if [ "${{ inputs.compression_level }}" -eq 0 ]; then
+          FILENAME="$BASE_FILENAME.tar"
+        else
+          FILENAME="$BASE_FILENAME.tzst"
         fi
-        echo "✅ ccache environment variables set"
-        ccache -p
-        if [ -f "build/build.sh" ]; then
-          SKIP_MRPROPER=1 LTO=thin SKIP_EXT_MODULES=1 SKIP_CP_KERNEL_HDR=1 GKI_DEFCONFIG_FRAGMENT="$GITHUB_WORKSPACE/wild_gki.fragment" BUILD_CONFIG=common/build.config.gki.aarch64 CC="$CC" CXX="$CXX" build/build.sh
+        
+        echo "::group:: Checking Release State"
+        
+        git fetch --tags --force
+        
+        if ! git rev-parse "$TAG_NAME" >/dev/null 2>&1; then
+          echo "Tag '$TAG_NAME' not found. Creating backdated release..."
+          GIT_COMMITTER_DATE="2015-01-01T12:00:00" git tag -a "$TAG_NAME" -m "General Cache Storage"
+          if git push origin "$TAG_NAME" --force; then
+            gh release create "$TAG_NAME" --title "General Cache" --notes "Automated storage for build assets" --repo "$TARGET_REPO" || true
+          else
+            echo "Push failed, tag might have been created by a parallel job. Continuing..."
+          fi
         else
-          cp "$GITHUB_WORKSPACE/wild_gki.fragment" common/arch/arm64/configs/wild_gki.fragment
-          tools/bazel build --config=release --notrim --defconfig_fragment=//common:arch/arm64/configs/wild_gki.fragment --cache_dir=$GITHUB_WORKSPACE/kernel/.cache/bazel //common:kernel_aarch64
+          echo "Release '$TAG_NAME' already exists. Ready for upload."
         fi
-        echo "Clear Temporary cache files..."
-        ccache -c
+        echo "::endgroup::"
+        
+        echo "::group:: Archiving Path"
+        echo "Target: ${{ inputs.cache_path }}"
         
-        echo "Perform cache eviction!"
-        # 3h = 10800s using seconds to support older ccache
-        ccache --evict-older-than 10800s
+        if [ ! -d "${{ inputs.cache_path }}" ] && [ ! -f "${{ inputs.cache_path }}" ]; then
+          echo "⚠️ Target path not found. Skipping cache save."
+          echo "::endgroup::"
+        else
+          DIR_NAME=$(dirname "${{ inputs.cache_path }}")
+          BASE_NAME=$(basename "${{ inputs.cache_path }}")
+          
+          if [ "${{ inputs.compression_level }}" -eq 0 ]; then
+            tar --posix -h -cvf "$FILENAME" -C "$DIR_NAME" "$BASE_NAME" > /dev/null 2>&1
+          else
+            tar --posix -h -I "zstd -T0 -${{ inputs.compression_level }}" -cvf "$FILENAME" -C "$DIR_NAME" "$BASE_NAME" > /dev/null 2>&1
+          fi
+          
+          FILE_SIZE=$(stat -c%s "$FILENAME")
+          echo "Archive created: $FILENAME ($FILE_SIZE bytes)"
+          echo "::endgroup::"
+          
+          echo "::group:: Uploading Assets"
+          MAX_SIZE=2000000000 # ~1.86GB
+          
+          upload_with_retry() {
+            local file=$1
+            local max_attempts=3
+            for ((i=1; i<=max_attempts; i++)); do
+              echo "  Attempt $i for $file..."
+              
+              if timeout 10m gh release upload "$TAG_NAME" "$file" --clobber --repo "$TARGET_REPO" > /dev/null 2>&1; then
+                echo "  Successfully uploaded $file"
+                return 0
+              fi
+              
+              echo "  ⚠ Attempt $i failed or timed out. Retrying..."
+              sleep 5
+            done
+            return 1
+          }
+          
+          if [ "$FILE_SIZE" -gt "$MAX_SIZE" ]; then
+            echo "⚠ File > 2GB. Splitting..."
+            split -b 1500M -a 2 "$FILENAME" "${FILENAME}.part"
+            for part in "${FILENAME}".part*; do
+              echo "Uploading $part..."
+              if ! upload_with_retry "$part"; then
+                echo "::error::Failed to upload part $part after multiple attempts."
+                exit 1
+              fi
+              rm -f "$part"
+            done
+            rm -rf "$FILENAME"
+          else
+            echo "Uploading $FILENAME..."
+            if ! upload_with_retry "$FILENAME"; then
+              echo "::error::Failed to upload $FILENAME after multiple attempts."
+              exit 1
+            fi
+            rm -f "$FILENAME"
+          fi
+          echo "::endgroup::"
+        fi

+ 4 - 4
.github/workflows/build.yml

@@ -188,7 +188,7 @@ jobs:
 
 
     - name: Restore build caches (ccache, Bazel)
-      uses: ./action-source/.github/actions/cache/restore
+      uses: ./.github/actions/restore-cache
       with:
         cache_path: ${{ github.workspace }}/.ccache
         cache_key: buildcache-${{ inputs.kernel_version }}
@@ -198,7 +198,7 @@ jobs:
           buildcache-
 
     - name: Restore build caches (ccache, Bazel)
-      uses: ./action-source/.github/actions/cache/restore
+      uses: ./.github/actions/restore-cache
       with:
         cache_path: ${{ github.workspace }}/.ld_cache
         cache_key: buildcache-${{ inputs.kernel_version }}
@@ -224,7 +224,7 @@ jobs:
         ls -l .cache/bazel || true
 
     - name: Save ccache cache
-      uses: ./action-source/.github/actions/cache/save
+      uses: ./.github/actions/save-cache
       with:
         cache_path: ${{ github.workspace }}/.ccache
         cache_key: buildcache-${{ inputs.kernel_version }}
@@ -232,7 +232,7 @@ jobs:
         compression_level: 9
 
     - name: Save LTO LD cache
-      uses: ./action-source/.github/actions/cache/save
+      uses: ./.github/actions/save-cache
       with:
         cache_path: ${{ github.workspace }}/.ld_cache
         cache_key: buildcache-${{ inputs.kernel_version }}