release.yml 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. name: release
  2. on:
  3. workflow_run:
  4. workflows: [test]
  5. branches: [master]
  6. types: [completed]
  7. jobs:
  8. release:
  9. runs-on: ubuntu-22.04
  10. # need to manually check for a couple things
  11. # - tests passed?
  12. # - we are the most recent commit on master?
  13. if: ${{github.event.workflow_run.conclusion == 'success' &&
  14. github.event.workflow_run.head_sha == github.sha}}
  15. steps:
  16. - uses: actions/checkout@v2
  17. with:
  18. ref: ${{github.event.workflow_run.head_sha}}
  19. # need workflow access since we push branches
  20. # containing workflows
  21. token: ${{secrets.BOT_TOKEN}}
  22. # need all tags
  23. fetch-depth: 0
  24. # try to get results from tests
  25. - uses: dawidd6/action-download-artifact@v2
  26. continue-on-error: true
  27. with:
  28. workflow: ${{github.event.workflow_run.name}}
  29. run_id: ${{github.event.workflow_run.id}}
  30. name: sizes
  31. path: sizes
  32. - uses: dawidd6/action-download-artifact@v2
  33. continue-on-error: true
  34. with:
  35. workflow: ${{github.event.workflow_run.name}}
  36. run_id: ${{github.event.workflow_run.id}}
  37. name: cov
  38. path: cov
  39. - uses: dawidd6/action-download-artifact@v2
  40. continue-on-error: true
  41. with:
  42. workflow: ${{github.event.workflow_run.name}}
  43. run_id: ${{github.event.workflow_run.id}}
  44. name: bench
  45. path: bench
  46. - name: find-version
  47. run: |
  48. # rip version from lfs.h
  49. LFS_VERSION="$(grep -o '^#define LFS_VERSION .*$' lfs.h \
  50. | awk '{print $3}')"
  51. LFS_VERSION_MAJOR="$((0xffff & ($LFS_VERSION >> 16)))"
  52. LFS_VERSION_MINOR="$((0xffff & ($LFS_VERSION >> 0)))"
  53. # find a new patch version based on what we find in our tags
  54. LFS_VERSION_PATCH="$( \
  55. ( git describe --tags --abbrev=0 \
  56. --match="v$LFS_VERSION_MAJOR.$LFS_VERSION_MINOR.*" \
  57. || echo 'v0.0.-1' ) \
  58. | awk -F '.' '{print $3+1}')"
  59. # found new version
  60. LFS_VERSION="v$LFS_VERSION_MAJOR`
  61. `.$LFS_VERSION_MINOR`
  62. `.$LFS_VERSION_PATCH"
  63. echo "LFS_VERSION=$LFS_VERSION"
  64. echo "LFS_VERSION=$LFS_VERSION" >> $GITHUB_ENV
  65. echo "LFS_VERSION_MAJOR=$LFS_VERSION_MAJOR" >> $GITHUB_ENV
  66. echo "LFS_VERSION_MINOR=$LFS_VERSION_MINOR" >> $GITHUB_ENV
  67. echo "LFS_VERSION_PATCH=$LFS_VERSION_PATCH" >> $GITHUB_ENV
  68. # try to find previous version?
  69. - name: find-prev-version
  70. continue-on-error: true
  71. run: |
  72. LFS_PREV_VERSION="$(git describe --tags --abbrev=0 --match 'v*')"
  73. echo "LFS_PREV_VERSION=$LFS_PREV_VERSION"
  74. echo "LFS_PREV_VERSION=$LFS_PREV_VERSION" >> $GITHUB_ENV
  75. # try to find results from tests
  76. - name: collect-table
  77. run: |
  78. # previous results to compare against?
  79. [ -n "$LFS_PREV_VERSION" ] && curl -sS \
  80. "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/`
  81. `status/$LFS_PREV_VERSION?per_page=100" \
  82. | jq -re 'select(.sha != env.GITHUB_SHA) | .statuses[]' \
  83. >> prev-statuses.json \
  84. || true
  85. # build table for GitHub
  86. declare -A table
  87. # sizes table
  88. i=0
  89. j=0
  90. for c in "" readonly threadsafe migrate error-asserts
  91. do
  92. # per-config results
  93. c_or_default=${c:-default}
  94. c_camel=${c_or_default^}
  95. table[$i,$j]=$c_camel
  96. ((j+=1))
  97. for s in code stack struct
  98. do
  99. f=sizes/thumb${c:+-$c}.$s.csv
  100. [ -e $f ] && table[$i,$j]=$( \
  101. export PREV="$(jq -re '
  102. select(.context == "'"sizes (thumb${c:+, $c}) / $s"'").description
  103. | capture("(?<prev>[0-9∞]+)").prev' \
  104. prev-statuses.json || echo 0)"
  105. ./scripts/summary.py $f --max=stack_limit -Y \
  106. | awk '
  107. NR==2 {$1=0; printf "%s B",$NF}
  108. NR==2 && ENVIRON["PREV"]+0 != 0 {
  109. printf " (%+.1f%%)",100*($NF-ENVIRON["PREV"])/ENVIRON["PREV"]
  110. }' \
  111. | sed -e 's/ /\&nbsp;/g')
  112. ((j+=1))
  113. done
  114. ((j=0, i+=1))
  115. done
  116. # coverage table
  117. i=0
  118. j=4
  119. for s in lines branches
  120. do
  121. table[$i,$j]=${s^}
  122. ((j+=1))
  123. f=cov/cov.csv
  124. [ -e $f ] && table[$i,$j]=$( \
  125. export PREV="$(jq -re '
  126. select(.context == "'"cov / $s"'").description
  127. | capture("(?<prev>[0-9\\.]+)").prev' \
  128. prev-statuses.json || echo 0)"
  129. ./scripts/cov.py -u $f -f$s -Y \
  130. | awk -F '[ /%]+' -v s=$s '
  131. NR==2 {$1=0; printf "%.1f%% of %d %s",$4,$3,s}
  132. NR==2 && ENVIRON["PREV"]+0 != 0 {
  133. printf " (%+.1f%%)",$4-ENVIRON["PREV"]
  134. }' \
  135. | sed -e 's/ /\&nbsp;/g')
  136. ((j=4, i+=1))
  137. done
  138. # benchmark table
  139. i=3
  140. j=4
  141. for s in readed proged erased
  142. do
  143. table[$i,$j]=${s^}
  144. ((j+=1))
  145. f=bench/bench.csv
  146. [ -e $f ] && table[$i,$j]=$( \
  147. export PREV="$(jq -re '
  148. select(.context == "'"bench / $s"'").description
  149. | capture("(?<prev>[0-9]+)").prev' \
  150. prev-statuses.json || echo 0)"
  151. ./scripts/summary.py $f -f$s=bench_$s -Y \
  152. | awk '
  153. NR==2 {$1=0; printf "%s B",$NF}
  154. NR==2 && ENVIRON["PREV"]+0 != 0 {
  155. printf " (%+.1f%%)",100*($NF-ENVIRON["PREV"])/ENVIRON["PREV"]
  156. }' \
  157. | sed -e 's/ /\&nbsp;/g')
  158. ((j=4, i+=1))
  159. done
  160. # build the actual table
  161. echo "| | Code | Stack | Structs | | Coverage |" >> table.txt
  162. echo "|:--|-----:|------:|--------:|:--|---------:|" >> table.txt
  163. for ((i=0; i<6; i++))
  164. do
  165. echo -n "|" >> table.txt
  166. for ((j=0; j<6; j++))
  167. do
  168. echo -n " " >> table.txt
  169. [[ i -eq 2 && j -eq 5 ]] && echo -n "**Benchmarks**" >> table.txt
  170. echo -n "${table[$i,$j]}" >> table.txt
  171. echo -n " |" >> table.txt
  172. done
  173. echo >> table.txt
  174. done
  175. cat table.txt
  176. # find changes from history
  177. - name: collect-changes
  178. run: |
  179. [ -n "$LFS_PREV_VERSION" ] || exit 0
  180. # use explicit link to github commit so that release notes can
  181. # be copied elsewhere
  182. git log "$LFS_PREV_VERSION.." \
  183. --grep='^Merge' --invert-grep \
  184. --format="format:[\`%h\`](`
  185. `https://github.com/$GITHUB_REPOSITORY/commit/%h) %s" \
  186. > changes.txt
  187. echo "CHANGES:"
  188. cat changes.txt
  189. # create and update major branches (vN and vN-prefix)
  190. - name: create-major-branches
  191. run: |
  192. # create major branch
  193. git branch "v$LFS_VERSION_MAJOR" HEAD
  194. # create major prefix branch
  195. git config user.name ${{secrets.BOT_USER}}
  196. git config user.email ${{secrets.BOT_EMAIL}}
  197. git fetch "https://github.com/$GITHUB_REPOSITORY.git" \
  198. "v$LFS_VERSION_MAJOR-prefix" || true
  199. ./scripts/changeprefix.py --git "lfs" "lfs$LFS_VERSION_MAJOR"
  200. git branch "v$LFS_VERSION_MAJOR-prefix" $( \
  201. git commit-tree $(git write-tree) \
  202. $(git rev-parse --verify -q FETCH_HEAD | sed -e 's/^/-p /') \
  203. -p HEAD \
  204. -m "Generated v$LFS_VERSION_MAJOR prefixes")
  205. git reset --hard
  206. # push!
  207. git push --atomic origin \
  208. "v$LFS_VERSION_MAJOR" \
  209. "v$LFS_VERSION_MAJOR-prefix"
  210. # build release notes
  211. - name: create-release
  212. run: |
  213. # create release and patch version tag (vN.N.N)
  214. # only draft if not a patch release
  215. [ -e table.txt ] && export TABLES="$(cat table.txt)"
  216. [ -e changes.txt ] && export CHANGES="$(cat changes.txt)"
  217. curl -sS -X POST -H "authorization: token ${{secrets.BOT_TOKEN}}" \
  218. "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/releases" \
  219. -d "$(jq -n '{
  220. tag_name: env.LFS_VERSION,
  221. name: env.LFS_VERSION | rtrimstr(".0"),
  222. target_commitish: "${{github.event.workflow_run.head_sha}}",
  223. draft: env.LFS_VERSION | endswith(".0"),
  224. body: [env.TABLES, env.CHANGES | select(.)] | join("\n\n")
  225. }' | tee /dev/stderr)"