release.yml 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  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-18.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: results
  31. path: results
  32. - name: find-version
  33. run: |
  34. # rip version from lfs.h
  35. LFS_VERSION="$(grep -o '^#define LFS_VERSION .*$' lfs.h \
  36. | awk '{print $3}')"
  37. LFS_VERSION_MAJOR="$((0xffff & ($LFS_VERSION >> 16)))"
  38. LFS_VERSION_MINOR="$((0xffff & ($LFS_VERSION >> 0)))"
  39. # find a new patch version based on what we find in our tags
  40. LFS_VERSION_PATCH="$( \
  41. ( git describe --tags --abbrev=0 \
  42. --match="v$LFS_VERSION_MAJOR.$LFS_VERSION_MINOR.*" \
  43. || echo 'v0.0.-1' ) \
  44. | awk -F '.' '{print $3+1}')"
  45. # found new version
  46. LFS_VERSION="v$LFS_VERSION_MAJOR`
  47. `.$LFS_VERSION_MINOR`
  48. `.$LFS_VERSION_PATCH"
  49. echo "LFS_VERSION=$LFS_VERSION"
  50. echo "LFS_VERSION=$LFS_VERSION" >> $GITHUB_ENV
  51. echo "LFS_VERSION_MAJOR=$LFS_VERSION_MAJOR" >> $GITHUB_ENV
  52. echo "LFS_VERSION_MINOR=$LFS_VERSION_MINOR" >> $GITHUB_ENV
  53. echo "LFS_VERSION_PATCH=$LFS_VERSION_PATCH" >> $GITHUB_ENV
  54. # try to find previous version?
  55. - name: find-prev-version
  56. continue-on-error: true
  57. run: |
  58. LFS_PREV_VERSION="$(git describe --tags --abbrev=0 --match 'v*')"
  59. echo "LFS_PREV_VERSION=$LFS_PREV_VERSION"
  60. echo "LFS_PREV_VERSION=$LFS_PREV_VERSION" >> $GITHUB_ENV
  61. # try to find results from tests
  62. - name: collect-results
  63. run: |
  64. # previous results to compare against?
  65. [ -n "$LFS_PREV_VERSION" ] && curl -sS \
  66. "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/`
  67. `status/$LFS_PREV_VERSION" \
  68. | jq -re 'select(.sha != env.GITHUB_SHA) | .statuses[]' \
  69. >> prev-results.json \
  70. || true
  71. # unfortunately these each have their own format
  72. [ -e results/code-thumb.csv ] && ( \
  73. export PREV="$(jq -re '
  74. select(.context == "results / code").description
  75. | capture("Code size is (?<result>[0-9]+)").result' \
  76. prev-results.json || echo 0)"
  77. ./scripts/code.py -u results/code-thumb.csv -s | awk '
  78. NR==2 {printf "Code size,%d B",$2}
  79. NR==2 && ENVIRON["PREV"]+0 != 0 {
  80. printf " (%+.1f%%)",100*($2-ENVIRON["PREV"])/ENVIRON["PREV"]}
  81. NR==2 {printf "\n"}' \
  82. >> results.csv)
  83. [ -e results/code-thumb-readonly.csv ] && ( \
  84. export PREV="$(jq -re '
  85. select(.context == "results / code (readonly)").description
  86. | capture("Code size is (?<result>[0-9]+)").result' \
  87. prev-results.json || echo 0)"
  88. ./scripts/code.py -u results/code-thumb-readonly.csv -s | awk '
  89. NR==2 {printf "Code size (readonly),%d B",$2}
  90. NR==2 && ENVIRON["PREV"]+0 != 0 {
  91. printf " (%+.1f%%)",100*($2-ENVIRON["PREV"])/ENVIRON["PREV"]}
  92. NR==2 {printf "\n"}' \
  93. >> results.csv)
  94. [ -e results/code-thumb-threadsafe.csv ] && ( \
  95. export PREV="$(jq -re '
  96. select(.context == "results / code (threadsafe)").description
  97. | capture("Code size is (?<result>[0-9]+)").result' \
  98. prev-results.json || echo 0)"
  99. ./scripts/code.py -u results/code-thumb-threadsafe.csv -s | awk '
  100. NR==2 {printf "Code size (threadsafe),%d B",$2}
  101. NR==2 && ENVIRON["PREV"]+0 != 0 {
  102. printf " (%+.1f%%)",100*($2-ENVIRON["PREV"])/ENVIRON["PREV"]}
  103. NR==2 {printf "\n"}' \
  104. >> results.csv)
  105. [ -e results/code-thumb-migrate.csv ] && ( \
  106. export PREV="$(jq -re '
  107. select(.context == "results / code (migrate)").description
  108. | capture("Code size is (?<result>[0-9]+)").result' \
  109. prev-results.json || echo 0)"
  110. ./scripts/code.py -u results/code-thumb-migrate.csv -s | awk '
  111. NR==2 {printf "Code size (migrate),%d B",$2}
  112. NR==2 && ENVIRON["PREV"]+0 != 0 {
  113. printf " (%+.1f%%)",100*($2-ENVIRON["PREV"])/ENVIRON["PREV"]}
  114. NR==2 {printf "\n"}' \
  115. >> results.csv)
  116. [ -e results/coverage.csv ] && ( \
  117. export PREV="$(jq -re '
  118. select(.context == "results / coverage").description
  119. | capture("Coverage is (?<result>[0-9\\.]+)").result' \
  120. prev-results.json || echo 0)"
  121. ./scripts/coverage.py -u results/coverage.csv -s | awk -F '[ /%]+' '
  122. NR==2 {printf "Coverage,%.1f%% of %d lines",$4,$3}
  123. NR==2 && ENVIRON["PREV"]+0 != 0 {
  124. printf " (%+.1f%%)",$4-ENVIRON["PREV"]}
  125. NR==2 {printf "\n"}' \
  126. >> results.csv)
  127. # transpose to GitHub table
  128. [ -e results.csv ] || exit 0
  129. awk -F ',' '
  130. {label[NR]=$1; value[NR]=$2}
  131. END {
  132. for (r=1; r<=NR; r++) {printf "| %s ",label[r]}; printf "|\n";
  133. for (r=1; r<=NR; r++) {printf "|:--"}; printf "|\n";
  134. for (r=1; r<=NR; r++) {printf "| %s ",value[r]}; printf "|\n"}' \
  135. results.csv > results.txt
  136. echo "RESULTS:"
  137. cat results.txt
  138. # find changes from history
  139. - name: collect-changes
  140. run: |
  141. [ -n "$LFS_PREV_VERSION" ] || exit 0
  142. # use explicit link to github commit so that release notes can
  143. # be copied elsewhere
  144. git log "$LFS_PREV_VERSION.." \
  145. --grep='^Merge' --invert-grep \
  146. --format="format:[\`%h\`](`
  147. `https://github.com/$GITHUB_REPOSITORY/commit/%h) %s" \
  148. > changes.txt
  149. echo "CHANGES:"
  150. cat changes.txt
  151. # create and update major branches (vN and vN-prefix)
  152. - name: create-major-branches
  153. run: |
  154. # create major branch
  155. git branch "v$LFS_VERSION_MAJOR" HEAD
  156. # create major prefix branch
  157. git config user.name ${{secrets.BOT_USER}}
  158. git config user.email ${{secrets.BOT_EMAIL}}
  159. git fetch "https://github.com/$GITHUB_REPOSITORY.git" \
  160. "v$LFS_VERSION_MAJOR-prefix" || true
  161. ./scripts/prefix.py "lfs$LFS_VERSION_MAJOR"
  162. git branch "v$LFS_VERSION_MAJOR-prefix" $( \
  163. git commit-tree $(git write-tree) \
  164. $(git rev-parse --verify -q FETCH_HEAD | sed -e 's/^/-p /') \
  165. -p HEAD \
  166. -m "Generated v$LFS_VERSION_MAJOR prefixes")
  167. git reset --hard
  168. # push!
  169. git push --atomic origin \
  170. "v$LFS_VERSION_MAJOR" \
  171. "v$LFS_VERSION_MAJOR-prefix"
  172. # build release notes
  173. - name: create-release
  174. run: |
  175. # create release and patch version tag (vN.N.N)
  176. # only draft if not a patch release
  177. [ -e results.txt ] && export RESULTS="$(cat results.txt)"
  178. [ -e changes.txt ] && export CHANGES="$(cat changes.txt)"
  179. curl -sS -X POST -H "authorization: token ${{secrets.BOT_TOKEN}}" \
  180. "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/releases" \
  181. -d "$(jq -n '{
  182. tag_name: env.LFS_VERSION,
  183. name: env.LFS_VERSION | rtrimstr(".0"),
  184. target_commitish: "${{github.event.workflow_run.head_sha}}",
  185. draft: env.LFS_VERSION | endswith(".0"),
  186. body: [env.RESULTS, env.CHANGES | select(.)] | join("\n\n")}' \
  187. | tee /dev/stderr)"