|
@@ -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:
|
|
runs:
|
|
|
- using: composite
|
|
|
|
|
|
|
+ using: 'composite'
|
|
|
steps:
|
|
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: |
|
|
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
|
|
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
|
|
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
|
|
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
|