diff --git a/.gitea/workflows/windows-build.yml b/.gitea/workflows/windows-build.yml index 8937591..aa4d9de 100644 --- a/.gitea/workflows/windows-build.yml +++ b/.gitea/workflows/windows-build.yml @@ -14,6 +14,7 @@ jobs: uses: actions/checkout@v4 with: submodules: recursive + fetch-depth: 0 - name: Install dependencies run: | @@ -49,21 +50,32 @@ jobs: run: | dependencies="$(x86_64-w64-mingw32-objdump -p build-win/bin/gitree.exe | sed -n 's/.*DLL Name: //p')" printf '%s\n' "$dependencies" + if printf '%s\n' "$dependencies" | grep -Eqi 'lib(gcc|stdc\+\+|winpthread).*\.dll'; then echo "The executable still depends on a MinGW runtime DLL." exit 1 fi + - name: Generate EXE name + run: | + repo_name="$(basename "${GITEA_REPOSITORY}")" + short_sha="$(printf '%s' "${GITEA_SHA}" | cut -c1-7)" + + exe_name="${repo_name}-windows-x64-${GITEA_RUN_NUMBER}-${short_sha}.exe" + + echo "EXE_NAME=${exe_name}" >> "$GITHUB_ENV" + echo "ARTIFACT_NAME=${repo_name}-windows-x64-${GITEA_RUN_NUMBER}-${short_sha}" >> "$GITHUB_ENV" + - name: Prepare artifact run: | mkdir -p dist - cp build-win/bin/gitree.exe dist/Gitree-windows-x64.exe + cp build-win/bin/gitree.exe "dist/${EXE_NAME}" - name: Upload Windows build uses: actions/upload-artifact@v3 with: - name: Gitree-windows-x64 - path: dist/Gitree-windows-x64.exe + name: ${{ env.ARTIFACT_NAME }} + path: dist/${{ env.EXE_NAME }} if-no-files-found: error - name: Create prod release @@ -80,15 +92,101 @@ jobs: exit 1 fi + git fetch --tags --force + short_sha="$(printf '%s' "$GITEA_SHA" | cut -c1-7)" tag="prod-${GITEA_RUN_NUMBER}-${short_sha}" api="${GITEA_SERVER_URL%/}/api/v1/repos/${GITEA_REPOSITORY}" + repo_url="${GITEA_SERVER_URL%/}/${GITEA_REPOSITORY}" + + previous_tag="$( + curl --fail-with-body --silent --show-error \ + -H "Authorization: token ${GITEA_TOKEN}" \ + "${api}/releases?limit=50" | + jq -r '[.[] | select(.tag_name | startswith("prod-"))][0].tag_name // empty' + )" + + if [ -n "$previous_tag" ]; then + range="${previous_tag}..${GITEA_SHA}" + echo "Generating release notes from ${previous_tag} to ${GITEA_SHA}" + else + range="${GITEA_SHA}" + echo "No previous prod release found. Generating release notes from current commit." + fi + + { + echo "Automated Windows release from the prod branch." + echo + + if [ -n "$previous_tag" ]; then + echo "## Changes since ${previous_tag}" + else + echo "## Changes" + fi + + echo + + commit_count="$(git rev-list --count "$range")" + + if [ "$commit_count" -eq 0 ]; then + echo "- No commits found since the previous release." + else + git log "$range" \ + --reverse \ + --pretty=format:'%H%x1f%s' | + while IFS="$(printf '\037')" read -r hash subject; do + short="$(printf '%s' "$hash" | cut -c1-7)" + echo "- ([${short}](${repo_url}/commit/${hash})) ${subject}" + done + fi + + echo + echo "## Authors" + echo + echo "Sorted by total lines added or removed." + echo + + git log "$range" --numstat --format='author:%an <%ae>' | + awk ' + /^author:/ { + author = substr($0, 8) + next + } + + NF >= 3 { + added = ($1 == "-" ? 0 : $1) + removed = ($2 == "-" ? 0 : $2) + + adds[author] += added + dels[author] += removed + churn[author] += added + removed + } + + END { + for (a in churn) { + printf "%d\t%d\t%d\t%s\n", churn[a], adds[a], dels[a], a + } + } + ' | + sort -nr | + while IFS="$(printf '\t')" read -r total added removed author; do + echo "- ${author} — ${total} lines changed (+${added} / -${removed})" + done + } > release-notes.md payload="$(jq -n \ --arg tag "$tag" \ --arg sha "$GITEA_SHA" \ - --arg name "Gitree ${tag}" \ - '{tag_name: $tag, target_commitish: $sha, name: $name, body: "Automated Windows release from the prod branch.", draft: false, prerelease: false}')" + --arg name "${ARTIFACT_NAME}" \ + --rawfile body release-notes.md \ + '{ + tag_name: $tag, + target_commitish: $sha, + name: $name, + body: $body, + draft: false, + prerelease: false + }')" release="$(curl --fail-with-body --silent --show-error \ -X POST \ @@ -96,10 +194,11 @@ jobs: -H "Content-Type: application/json" \ --data "$payload" \ "${api}/releases")" + release_id="$(printf '%s' "$release" | jq -er '.id')" curl --fail-with-body --silent --show-error \ -X POST \ -H "Authorization: token ${GITEA_TOKEN}" \ - -F "attachment=@dist/Gitree-windows-x64.exe" \ - "${api}/releases/${release_id}/assets?name=Gitree-windows-x64.exe" + -F "attachment=@dist/${EXE_NAME}" \ + "${api}/releases/${release_id}/assets?name=${EXE_NAME}" \ No newline at end of file