name: release on: workflow_run: workflows: [test] branches: [master] types: [completed] defaults: run: shell: bash -euv -o pipefail {0} jobs: release: runs-on: ubuntu-latest # need to manually check for a couple things # - tests passed? # - we are the most recent commit on master? if: ${{github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_sha == github.sha}} steps: - uses: actions/checkout@v4 with: ref: ${{github.event.workflow_run.head_sha}} # need workflow access since we push branches # containing workflows token: ${{secrets.BOT_TOKEN}} # need all tags fetch-depth: 0 # try to get results from tests - uses: actions/download-artifact@v4 continue-on-error: true with: github-token: ${{secrets.GITHUB_TOKEN}} run-id: ${{github.event.workflow_run.id}} pattern: '{sizes,sizes-*}' merge-multiple: true path: sizes - uses: actions/download-artifact@v4 continue-on-error: true with: github-token: ${{secrets.GITHUB_TOKEN}} run-id: ${{github.event.workflow_run.id}} pattern: '{cov,cov-*}' merge-multiple: true path: cov - uses: actions/download-artifact@v4 continue-on-error: true with: github-token: ${{secrets.GITHUB_TOKEN}} run-id: ${{github.event.workflow_run.id}} pattern: '{bench,bench-*}' merge-multiple: true path: bench - name: find-version run: | # rip version from lfs.h LFS_VERSION="$(grep -o '^#define LFS_VERSION .*$' lfs.h \ | awk '{print $3}')" LFS_VERSION_MAJOR="$((0xffff & ($LFS_VERSION >> 16)))" LFS_VERSION_MINOR="$((0xffff & ($LFS_VERSION >> 0)))" # find a new patch version based on what we find in our tags LFS_VERSION_PATCH="$( \ ( git describe --tags --abbrev=0 \ --match="v$LFS_VERSION_MAJOR.$LFS_VERSION_MINOR.*" \ || echo 'v0.0.-1' ) \ | awk -F '.' '{print $3+1}')" # found new version LFS_VERSION="v$LFS_VERSION_MAJOR` `.$LFS_VERSION_MINOR` `.$LFS_VERSION_PATCH" echo "LFS_VERSION=$LFS_VERSION" echo "LFS_VERSION=$LFS_VERSION" >> $GITHUB_ENV echo "LFS_VERSION_MAJOR=$LFS_VERSION_MAJOR" >> $GITHUB_ENV echo "LFS_VERSION_MINOR=$LFS_VERSION_MINOR" >> $GITHUB_ENV echo "LFS_VERSION_PATCH=$LFS_VERSION_PATCH" >> $GITHUB_ENV # try to find previous version? - name: find-prev-version continue-on-error: true run: | LFS_PREV_VERSION="$( \ git describe --tags --abbrev=0 --match 'v*' \ || true)" echo "LFS_PREV_VERSION=$LFS_PREV_VERSION" echo "LFS_PREV_VERSION=$LFS_PREV_VERSION" >> $GITHUB_ENV # try to find results from tests - name: create-table run: | # previous results to compare against? [ -n "$LFS_PREV_VERSION" ] && curl -sS \ "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/status/$LFS_PREV_VERSION` `?per_page=100" \ | jq -re 'select(.sha != env.GITHUB_SHA) | .statuses[]' \ >> prev-status.json \ || true # build table for GitHub declare -A table # sizes table i=0 j=0 for c in "" readonly threadsafe multiversion migrate error-asserts do # per-config results c_or_default=${c:-default} c_camel=${c_or_default^} table[$i,$j]=$c_camel ((j+=1)) for s in code stack structs do f=sizes/thumb${c:+-$c}.$s.csv [ -e $f ] && table[$i,$j]=$( \ export PREV="$(jq -re ' select(.context == "'"sizes (thumb${c:+, $c}) / $s"'").description | capture("(?[0-9∞]+)").prev' \ prev-status.json || echo 0)" ./scripts/summary.py $f --max=stack_limit -Y \ | awk ' NR==2 {$1=0; printf "%s B",$NF} NR==2 && ENVIRON["PREV"]+0 != 0 { printf " (%+.1f%%)",100*($NF-ENVIRON["PREV"])/ENVIRON["PREV"] }' \ | sed -e 's/ /\ /g') ((j+=1)) done ((j=0, i+=1)) done # coverage table i=0 j=4 for s in lines branches do table[$i,$j]=${s^} ((j+=1)) f=cov/cov.csv [ -e $f ] && table[$i,$j]=$( \ export PREV="$(jq -re ' select(.context == "'"cov / $s"'").description | capture("(?[0-9]+)/(?[0-9]+)") | 100*((.prev_a|tonumber) / (.prev_b|tonumber))' \ prev-status.json || echo 0)" ./scripts/cov.py -u $f -f$s -Y \ | awk -F '[ /%]+' -v s=$s ' NR==2 {$1=0; printf "%d/%d %s",$2,$3,s} NR==2 && ENVIRON["PREV"]+0 != 0 { printf " (%+.1f%%)",$4-ENVIRON["PREV"] }' \ | sed -e 's/ /\ /g') ((j=4, i+=1)) done # benchmark table i=3 j=4 for s in readed proged erased do table[$i,$j]=${s^} ((j+=1)) f=bench/bench.csv [ -e $f ] && table[$i,$j]=$( \ export PREV="$(jq -re ' select(.context == "'"bench / $s"'").description | capture("(?[0-9]+)").prev' \ prev-status.json || echo 0)" ./scripts/summary.py $f -f$s=bench_$s -Y \ | awk ' NR==2 {$1=0; printf "%s B",$NF} NR==2 && ENVIRON["PREV"]+0 != 0 { printf " (%+.1f%%)",100*($NF-ENVIRON["PREV"])/ENVIRON["PREV"] }' \ | sed -e 's/ /\ /g') ((j=4, i+=1)) done # build the actual table echo "| | Code | Stack | Structs | | Coverage |" >> table.txt echo "|:--|-----:|------:|--------:|:--|---------:|" >> table.txt for ((i=0; i<6; i++)) do echo -n "|" >> table.txt for ((j=0; j<6; j++)) do echo -n " " >> table.txt [[ i -eq 2 && j -eq 5 ]] && echo -n "**Benchmarks**" >> table.txt echo -n "${table[$i,$j]:-}" >> table.txt echo -n " |" >> table.txt done echo >> table.txt done cat table.txt # find changes from history - name: create-changes run: | [ -n "$LFS_PREV_VERSION" ] || exit 0 # use explicit link to github commit so that release notes can # be copied elsewhere git log "$LFS_PREV_VERSION.." \ --grep='^Merge' --invert-grep \ --format="format:[\`%h\`](` `https://github.com/$GITHUB_REPOSITORY/commit/%h) %s" \ > changes.txt echo "CHANGES:" cat changes.txt # create and update major branches (vN and vN-prefix) - name: create-major-branches run: | # create major branch git branch "v$LFS_VERSION_MAJOR" HEAD # create major prefix branch git config user.name ${{secrets.BOT_USER}} git config user.email ${{secrets.BOT_EMAIL}} git fetch "https://github.com/$GITHUB_REPOSITORY.git" \ "v$LFS_VERSION_MAJOR-prefix" || true ./scripts/changeprefix.py --git "lfs" "lfs$LFS_VERSION_MAJOR" git branch "v$LFS_VERSION_MAJOR-prefix" $( \ git commit-tree $(git write-tree) \ $(git rev-parse --verify -q FETCH_HEAD | sed -e 's/^/-p /') \ -p HEAD \ -m "Generated v$LFS_VERSION_MAJOR prefixes") git reset --hard # push! git push --atomic origin \ "v$LFS_VERSION_MAJOR" \ "v$LFS_VERSION_MAJOR-prefix" # build release notes - name: create-release run: | # create release and patch version tag (vN.N.N) # only draft if not a patch release touch release.txt [ -e table.txt ] && cat table.txt >> release.txt echo >> release.txt [ -e changes.txt ] && cat changes.txt >> release.txt cat release.txt curl -sS -X POST -H "authorization: token ${{secrets.BOT_TOKEN}}" \ "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/releases" \ -d "$(jq -n --rawfile release release.txt '{ tag_name: env.LFS_VERSION, name: env.LFS_VERSION | rtrimstr(".0"), target_commitish: "${{github.event.workflow_run.head_sha}}", draft: env.LFS_VERSION | endswith(".0"), body: $release, }' | tee /dev/stderr)"