action.yml 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. name: 'Save Cache'
  2. description: ''
  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 (e.g., general-cache)'
  14. required: true
  15. default: 'general-cache'
  16. github_token:
  17. description: 'GitHub Token'
  18. required: true
  19. compression_level:
  20. description: 'Compression level (0-9). 0 = No compression, 1 = Fast, 19 = Best.'
  21. required: false
  22. type: number
  23. default: 6
  24. working_dir:
  25. description: 'Path where .git folder exists (use only if you clone multiple repos)'
  26. required: false
  27. type: string
  28. debug:
  29. description: 'Enable Logs'
  30. required: false
  31. type: boolean
  32. default: false
  33. runs:
  34. using: 'composite'
  35. steps:
  36. - name: Archive, Split, and Upload Cache
  37. shell: bash
  38. env:
  39. GH_TOKEN: ${{ inputs.github_token }}
  40. TARGET_REPO: "${{ github.repository }}"
  41. run: |
  42. # Archive, Split, and Upload Cache
  43. if [ "${{ inputs.debug }}" = "true" ]; then set -x; fi
  44. if [ "${{ inputs.working_dir }}" != "" ]; then
  45. cd "${{ inputs.working_dir }}"
  46. fi
  47. git config user.name "github-actions[bot]"
  48. git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
  49. TAG_NAME="${{ inputs.cache_bucket }}"
  50. BASE_FILENAME="cache-${{ inputs.cache_key }}"
  51. if [ "${{ inputs.compression_level }}" -eq 0 ]; then
  52. FILENAME="$BASE_FILENAME.tar"
  53. else
  54. FILENAME="$BASE_FILENAME.tzst"
  55. fi
  56. echo "::group:: Checking Release State"
  57. git fetch --tags --force
  58. if ! git rev-parse "$TAG_NAME" >/dev/null 2>&1; then
  59. echo "Tag '$TAG_NAME' not found. Creating backdated release..."
  60. GIT_COMMITTER_DATE="2015-01-01T12:00:00" git tag -a "$TAG_NAME" -m "General Cache Storage"
  61. if git push origin "$TAG_NAME" --force; then
  62. gh release create "$TAG_NAME" --title "General Cache" --notes "Automated storage for build assets" --repo "$TARGET_REPO" || true
  63. else
  64. echo "Push failed, tag might have been created by a parallel job. Continuing..."
  65. fi
  66. else
  67. echo "Release '$TAG_NAME' already exists. Ready for upload."
  68. fi
  69. echo "::endgroup::"
  70. echo "::group:: Archiving Path"
  71. echo "Target: ${{ inputs.cache_path }}"
  72. if [ ! -d "${{ inputs.cache_path }}" ] && [ ! -f "${{ inputs.cache_path }}" ]; then
  73. echo "⚠️ Target path not found. Skipping cache save."
  74. echo "::endgroup::"
  75. else
  76. DIR_NAME=$(dirname "${{ inputs.cache_path }}")
  77. BASE_NAME=$(basename "${{ inputs.cache_path }}")
  78. if [ "${{ inputs.debug }}" = "true" ]; then
  79. if [ "${{ inputs.compression_level }}" -eq 0 ]; then
  80. tar --posix -h -cvf "$FILENAME" -C "$DIR_NAME" "$BASE_NAME"
  81. else
  82. tar --posix -h -I "zstd -T0 -${{ inputs.compression_level }}" -cvf "$FILENAME" -C "$DIR_NAME" "$BASE_NAME"
  83. fi
  84. else
  85. if [ "${{ inputs.compression_level }}" -eq 0 ]; then
  86. tar --posix -h -cvf "$FILENAME" -C "$DIR_NAME" "$BASE_NAME" > /dev/null 2>&1
  87. else
  88. tar --posix -h -I "zstd -T0 -${{ inputs.compression_level }}" -cvf "$FILENAME" -C "$DIR_NAME" "$BASE_NAME" > /dev/null 2>&1
  89. fi
  90. fi
  91. FILE_SIZE=$(stat -c%s "$FILENAME")
  92. echo "Archive created: $FILENAME ($FILE_SIZE bytes)"
  93. echo "::endgroup::"
  94. echo "::group:: Uploading Assets"
  95. MAX_SIZE=2000000000 # ~1.86GB
  96. upload_with_retry() {
  97. local file=$1
  98. local max_attempts=3
  99. for ((i=1; i<=max_attempts; i++)); do
  100. echo " Attempt $i for $file..."
  101. if [ "${{ inputs.debug }}" = "true" ]; then
  102. if timeout 10m gh release upload "$TAG_NAME" "$file" --clobber --repo "$TARGET_REPO"; then
  103. echo " Successfully uploaded $file"
  104. return 0
  105. fi
  106. else
  107. if timeout 10m gh release upload "$TAG_NAME" "$file" --clobber --repo "$TARGET_REPO" > /dev/null 2>&1; then
  108. echo " Successfully uploaded $file"
  109. return 0
  110. fi
  111. fi
  112. echo " ⚠ Attempt $i failed or timed out. Retrying..."
  113. sleep 5
  114. done
  115. return 1
  116. }
  117. if [ "$FILE_SIZE" -gt "$MAX_SIZE" ]; then
  118. echo "⚠ File > 2GB. Splitting..."
  119. split -b 1500M -a 2 "$FILENAME" "${FILENAME}.part"
  120. for part in "${FILENAME}".part*; do
  121. echo "Uploading $part..."
  122. if ! upload_with_retry "$part"; then
  123. echo "::error::Failed to upload part $part after multiple attempts."
  124. exit 1
  125. fi
  126. rm -f "$part"
  127. done
  128. rm -rf "$FILENAME"
  129. else
  130. echo "Uploading $FILENAME..."
  131. if ! upload_with_retry "$FILENAME"; then
  132. echo "::error::Failed to upload $FILENAME after multiple attempts."
  133. exit 1
  134. fi
  135. rm -f "$FILENAME"
  136. fi
  137. echo "::endgroup::"
  138. fi