action.yml 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. name: 'Archive Cache'
  2. description: 'Create cache archive and prepare for upload'
  3. inputs:
  4. cache_path:
  5. description: 'Path where cache is saved'
  6. required: true
  7. type: string
  8. cache_key:
  9. description: 'Unique key for the cache'
  10. required: true
  11. type: string
  12. cache_bucket:
  13. description: 'The tag name for the release'
  14. required: true
  15. default: 'general-cache'
  16. compression_level:
  17. description: 'Compression level (0-9)'
  18. required: false
  19. type: number
  20. default: 6
  21. working_dir:
  22. description: 'Path where .git folder exists'
  23. required: false
  24. type: string
  25. debug:
  26. description: 'Enable Logs'
  27. required: false
  28. type: boolean
  29. default: false
  30. runs:
  31. using: 'composite'
  32. steps:
  33. - name: Archive and Split Cache
  34. shell: bash
  35. env:
  36. GH_TOKEN: ${{ inputs.github_token }}
  37. TARGET_REPO: "${{ github.repository }}"
  38. run: |
  39. set -euo pipefail
  40. if [ "${{ inputs.working_dir }}" != "" ]; then
  41. cd "${{ inputs.working_dir }}"
  42. fi
  43. git config user.name "github-actions[bot]"
  44. git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
  45. TAG_NAME="${{ inputs.cache_bucket }}"
  46. BASE_FILENAME="cache-${{ inputs.cache_key }}"
  47. if [ "${{ inputs.compression_level }}" -eq 0 ]; then
  48. FILENAME="$BASE_FILENAME.tar"
  49. else
  50. FILENAME="$BASE_FILENAME.tzst"
  51. fi
  52. # Check release state
  53. git fetch --tags --force
  54. if ! git rev-parse "$TAG_NAME" >/dev/null 2>&1; then
  55. echo "Creating release: $TAG_NAME"
  56. GIT_COMMITTER_DATE="2015-01-01T12:00:00" git tag -a "$TAG_NAME" -m "General Cache Storage"
  57. git push origin "$TAG_NAME" --force || true
  58. gh release create "$TAG_NAME" --title "General Cache" --notes "Automated storage for build assets" --prerelease --repo "$TARGET_REPO" || true
  59. fi
  60. # Check if path exists
  61. if [ ! -d "${{ inputs.cache_path }}" ] && [ ! -f "${{ inputs.cache_path }}" ]; then
  62. echo "[!] Target path not found. Skipping cache save."
  63. exit 0
  64. fi
  65. DIR_NAME=$(dirname "${{ inputs.cache_path }}")
  66. BASE_NAME=$(basename "${{ inputs.cache_path }}")
  67. if [ "${{ inputs.debug }}" = "true" ]; then
  68. if [ "${{ inputs.compression_level }}" -eq 0 ]; then
  69. tar --posix -h -cvf "$FILENAME" -C "$DIR_NAME" "$BASE_NAME"
  70. else
  71. tar --posix -h -I "zstd -T0 -${{ inputs.compression_level }}" -cvf "$FILENAME" -C "$DIR_NAME" "$BASE_NAME"
  72. fi
  73. else
  74. if [ "${{ inputs.compression_level }}" -eq 0 ]; then
  75. tar --posix -h -cvf "$FILENAME" -C "$DIR_NAME" "$BASE_NAME" > /dev/null 2>&1
  76. else
  77. tar --posix -h -I "zstd -T0 -${{ inputs.compression_level }}" -cvf "$FILENAME" -C "$DIR_NAME" "$BASE_NAME" > /dev/null 2>&1
  78. fi
  79. fi
  80. FILE_SIZE=$(stat -c%s "$FILENAME")
  81. echo "Archive created: $FILENAME ($FILE_SIZE bytes)"
  82. # Determine if splitting is needed
  83. MAX_SIZE=2000000000
  84. chunk_size="1500M"
  85. split_required=false
  86. if [ "$FILE_SIZE" -gt "$MAX_SIZE" ]; then
  87. split_required=true
  88. fi
  89. if [ "$split_required" = "true" ]; then
  90. echo "Splitting into ${chunk_size} chunks..."
  91. split -b "$chunk_size" -a 2 "$FILENAME" "${FILENAME}.part"
  92. NEW_PARTS=(${FILENAME}.part*)
  93. NEW_PARTS_COUNT=${#NEW_PARTS[@]}
  94. echo "Split complete, $NEW_PARTS_COUNT parts created"
  95. # Remove old single-file asset if switching to split parts
  96. ALL_ASSETS=$(curl -sL -A "Mozilla/5.0" -w "%{http_code}" "https://github.com/${TARGET_REPO}/releases/expanded_assets/$TAG_NAME" -o assets.html 2>/dev/null || echo "0")
  97. if [ "$ALL_ASSETS" = "200" ]; then
  98. ALL_ASSETS=$(grep -oP "download/$TAG_NAME/\K[\"' ]+" assets.html 2>/dev/null || echo "")
  99. if echo "$ALL_ASSETS" | grep -xF "${FILENAME}" >/dev/null 2>&1; then
  100. gh release delete-asset "$TAG_NAME" "${FILENAME}" --repo "$TARGET_REPO" -y || true
  101. fi
  102. # Clean up excess trailing parts from previous builds
  103. OLD_PARTS=$(echo "$ALL_ASSETS" | grep -F "${FILENAME}.part" 2>/dev/null || echo "")
  104. if [ -n "$OLD_PARTS" ]; then
  105. OLD_PARTS_COUNT=$(echo "$OLD_PARTS" | wc -l)
  106. if [ "$OLD_PARTS_COUNT" -gt "$NEW_PARTS_COUNT" ]; then
  107. EXT_PARTS=$(echo "$OLD_PARTS" | awk -v skip="$NEW_PARTS_COUNT" 'NR>skip')
  108. for asset in $EXT_PARTS; do
  109. gh release delete-asset "$TAG_NAME" "$asset" --repo "$TARGET_REPO" -y || true
  110. done
  111. fi
  112. fi
  113. fi
  114. rm -f assets.html
  115. else
  116. # Remove old split parts if new build fits in a single file
  117. ALL_ASSETS=$(curl -sL -A "Mozilla/5.0" -w "%{http_code}" "https://github.com/${TARGET_REPO}/releases/expanded_assets/$TAG_NAME" -o assets.html 2>/dev/null || echo "0")
  118. if [ "$ALL_ASSETS" = "200" ]; then
  119. OLD_PARTS=$(grep -F "${FILENAME}.part" assets.html 2>/dev/null || echo "")
  120. if [ -n "$OLD_PARTS" ]; then
  121. while read -r asset; do
  122. [ -z "$asset" ] && continue
  123. gh release delete-asset "$TAG_NAME" "$asset" --repo "$TARGET_REPO" -y || true
  124. done <<< "$OLD_PARTS"
  125. fi
  126. fi
  127. rm -f assets.html
  128. fi
  129. echo "CACHE_FILE=$FILENAME" >> $GITHUB_OUTPUT
  130. echo "CACHE_SPLIT=$split_required" >> $GITHUB_OUTPUT
  131. echo "CACHE_PARTS=${NEW_PARTS_COUNT:-1}" >> $GITHUB_OUTPUT