action.yml 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. name: 'Show Cache Stats'
  2. description: 'Displays statistics for ccache and Bazel remote cache to help analyze cache performance and hit rates'
  3. inputs:
  4. clear_stats:
  5. description: 'Whether to clear ccache stats after displaying (default: true)'
  6. required: true
  7. type: boolean
  8. default: true
  9. runs:
  10. using: 'composite'
  11. steps:
  12. - name: Define cache summary helper
  13. shell: bash
  14. working-directory: ${{ github.workspace }}
  15. run: |
  16. set -euo pipefail
  17. echo "๐Ÿ” DEBUG: cache-stats action started"
  18. echo "๐Ÿ” DEBUG: inputs.clear_stats=${{ inputs.clear_stats }}"
  19. echo "๐Ÿ” DEBUG: github.workspace=${{ github.workspace }}"
  20. cat > /tmp/cache_summary.sh <<'EOF'
  21. summarize_dir() {
  22. local path="$1"
  23. local top_n=${2:-10}
  24. local sub_n=${3:-5}
  25. if [ ! -e "$path" ]; then
  26. echo "Path $path not found"
  27. return
  28. fi
  29. echo "---------------"
  30. echo "Summary: $path"
  31. du -sh "$path" || true
  32. echo "Top ${top_n} entries at top level:"
  33. du -h --max-depth=1 "$path" 2>/dev/null | sort -hr | head -n "$top_n" || true
  34. echo "Showing up to ${sub_n} entries one level deeper for the largest top-level items:"
  35. while read -r line; do
  36. entry_path=$(echo "$line" | awk '{print $2}')
  37. [ -z "$entry_path" ] && continue
  38. if [ "$entry_path" = "$path" ]; then
  39. continue
  40. fi
  41. echo "-> $entry_path :"
  42. du -h --max-depth=1 "$entry_path" 2>/dev/null | sort -hr | head -n "$sub_n" || true
  43. done < <(du -h --max-depth=1 "$path" 2>/dev/null | sort -hr | head -n "$top_n")
  44. echo "---------------"
  45. }
  46. EOF
  47. - name: Show ccache Stats
  48. shell: bash
  49. working-directory: ${{ github.workspace }}
  50. run: |
  51. set -euo pipefail
  52. echo "===================="
  53. echo "=== ccache stats ==="
  54. echo "===================="
  55. echo "๐Ÿ” DEBUG: Starting ccache stats collection"
  56. if ! command -v ccache >/dev/null 2>&1; then
  57. echo "๐Ÿ” DEBUG: ccache command not found"
  58. echo "โš ๏ธ ccache not installed, skipping ccache stats"
  59. echo "===================="
  60. exit 0
  61. fi
  62. echo "๐Ÿ” DEBUG: ccache command found at: $(which ccache)"
  63. # Get ccache version
  64. CCACHE_VERSION=$(ccache --version | head -1)
  65. echo "๐Ÿ” DEBUG: ccache version: $CCACHE_VERSION"
  66. # Check ccache directory
  67. echo "๐Ÿ” DEBUG: Checking ccache directory: /home/runner/.ccache"
  68. if [ -d /home/runner/.ccache ]; then
  69. echo "๐Ÿ” DEBUG: ccache directory exists"
  70. echo "๐Ÿ” DEBUG: ccache directory size: $(du -sh /home/runner/.ccache 2>/dev/null | cut -f1)"
  71. echo "๐Ÿ” DEBUG: ccache directory file count: $(find /home/runner/.ccache -type f 2>/dev/null | wc -l)"
  72. else
  73. echo "๐Ÿ” DEBUG: ccache directory does NOT exist"
  74. fi
  75. echo "๐Ÿ” DEBUG: Running ccache -s (statistics)"
  76. ccache -s || true
  77. echo "๐Ÿ” DEBUG: ccache -s completed"
  78. echo "====================="
  79. echo "=== ccache config ==="
  80. echo "====================="
  81. echo "๐Ÿ” DEBUG: Running ccache -p (config)"
  82. ccache -p || true
  83. echo "๐Ÿ” DEBUG: ccache -p completed"
  84. echo "====================="
  85. echo "๐Ÿ” DEBUG: Running ccache -s for stats parsing"
  86. STATS="$(ccache -s)"
  87. echo "๐Ÿ” DEBUG: Raw ccache stats captured"
  88. echo "๐Ÿ” DEBUG: Parsing ccache statistics"
  89. echo "๐Ÿ” DEBUG: Raw STATS (first 10 lines):"
  90. echo "$STATS" | head -n 10
  91. CACHEABLE=$(echo "$STATS" | awk '/Cacheable calls:/ {
  92. match($0, /[0-9]+/);
  93. print substr($0, RSTART, RLENGTH)
  94. }' | head -n1)
  95. echo "๐Ÿ” DEBUG: CACHEABLE=$CACHEABLE"
  96. HITS=$(echo "$STATS" | awk '/^[[:space:]]*Hits:/ {
  97. match($0, /[0-9]+/);
  98. print substr($0, RSTART, RLENGTH)
  99. }' | head -n1)
  100. echo "๐Ÿ” DEBUG: HITS=$HITS"
  101. DIRECT=$(echo "$STATS" | awk '/Direct:/ {
  102. match($0, /[0-9]+/);
  103. print substr($0, RSTART, RLENGTH)
  104. }' | head -n1)
  105. echo "๐Ÿ” DEBUG: DIRECT=$DIRECT"
  106. echo "๐Ÿ” DEBUG: Calculating hit rates"
  107. echo "๐Ÿ” DEBUG: CACHEABLE=${CACHEABLE:-0}, HITS=${HITS:-0}, DIRECT=${DIRECT:-0}"
  108. if [ "${CACHEABLE:-0}" -gt 0 ]; then
  109. HIT_RATE=$(awk -v h="${HITS:-0}" -v c="$CACHEABLE" 'BEGIN{printf "%.1f", (h/c)*100}')
  110. DIRECT_RATE=$(awk -v d="${DIRECT:-0}" -v c="$CACHEABLE" 'BEGIN{printf "%.1f", (d/c)*100}')
  111. echo "๐Ÿ” DEBUG: Calculated HIT_RATE=$HIT_RATE%, DIRECT_RATE=$DIRECT_RATE%"
  112. else
  113. HIT_RATE="0.0"
  114. DIRECT_RATE="0.0"
  115. echo "๐Ÿ” DEBUG: CACHEABLE is 0, setting rates to 0.0%"
  116. fi
  117. echo "hit_rate=${HIT_RATE}%"
  118. echo "direct_rate=${DIRECT_RATE}%"
  119. echo "๐Ÿ” DEBUG: Hit rates output complete"
  120. echo "๐Ÿ” DEBUG: clear_stats check: ${{ inputs.clear_stats }}"
  121. if [ "${{ inputs.clear_stats }}" = "true" ]; then
  122. echo "๐Ÿ” DEBUG: Clearing ccache stats (ccache -z)"
  123. echo "=== ccache reset ==="
  124. echo "====================="
  125. ccache -z || true
  126. echo "๐Ÿ” DEBUG: ccache -z completed"
  127. echo "====================="
  128. # Touch all files to prevent LRU eviction of freshly restored cache
  129. echo "๐Ÿ” DEBUG: Checking if ccache directory needs atime update"
  130. if [ -d /home/runner/.ccache ] && find /home/runner/.ccache -type f -print -quit 2>/dev/null | grep -q .; then
  131. echo "๐Ÿ” DEBUG: ccache directory has files, updating atime"
  132. echo "Updating ccache atime to prevent cache eviction..."
  133. echo "๐Ÿ” DEBUG: Executing find touch command for ccache files"
  134. find /home/runner/.ccache -type f -exec touch -t $(date -d "1 day ago" +%Y%m%d%H%M) {} +
  135. echo "โœ… ccache atime updated"
  136. echo "๐Ÿ” DEBUG: ccache atime update completed"
  137. else
  138. echo "๐Ÿ” DEBUG: Skipping ccache atime update (directory empty or missing)"
  139. fi
  140. else
  141. echo "๐Ÿ” DEBUG: clear_stats is false, keeping ccache stats for next run"
  142. echo "Keeping ccache stats for next run"
  143. fi
  144. echo "๐Ÿ” DEBUG: ccache stats section complete"
  145. - name: Show ccache folder Stats
  146. shell: bash
  147. working-directory: ${{ github.workspace }}
  148. run: |
  149. set -euo pipefail
  150. echo "๐Ÿ” DEBUG: ccache folder stats section started"
  151. # shellcheck disable=SC1091
  152. source /tmp/cache_summary.sh
  153. echo "๐Ÿ” DEBUG: cache_summary.sh loaded successfully"
  154. echo "๐Ÿ” DEBUG: Calling summarize_dir for /home/runner/.ccache with top_n=10, sub_n=5"
  155. echo "==============="
  156. echo "=== .ccache ==="
  157. echo "==============="
  158. summarize_dir /home/runner/.ccache 10 5 || true
  159. echo "๐Ÿ” DEBUG: ccache folder stats section complete"
  160. - name: Show Bazel Cache folder Stats
  161. shell: bash
  162. working-directory: ${{ github.workspace }}
  163. run: |
  164. set -euo pipefail
  165. echo "๐Ÿ” DEBUG: Bazel cache folder stats section started"
  166. # shellcheck disable=SC1091
  167. source /tmp/cache_summary.sh
  168. echo "๐Ÿ” DEBUG: cache_summary.sh loaded successfully"
  169. echo "๐Ÿ” DEBUG: Calling summarize_dir for /home/runner/.cache/bazel with top_n=10, sub_n=5"
  170. echo "===================="
  171. echo "=== .cache/bazel ==="
  172. echo "===================="
  173. summarize_dir /home/runner/.cache/bazel 10 5 || true
  174. echo "๐Ÿ” DEBUG: Bazel cache folder stats section complete"
  175. echo "๐Ÿ” DEBUG: cache-stats action finished successfully"