name: Update changelog.md on Release on: release: types: [published, created, edited, deleted] workflow_dispatch: inputs: reason: description: 'Reason for manual trigger' required: false default: 'Manual update' jobs: update-file: runs-on: ubuntu-latest steps: - name: Checkout Repository uses: actions/checkout@v4 - name: Get all releases and update changelog.md file run: | # Initialize some values changelog_path="docs/changelog.md" gh release list --exclude-drafts --json tagName,name,isLatest,isPrerelease --limit 1000000 > releases.txt declare -r number_of_releases=$(cat releases.txt | grep -Po '"tagName"' | wc --lines) # Clear the contents of changelog file echo "" > $changelog_path # Write some Initial Content to changelog file echo "# Changelog" >> $changelog_path echo "" >> $changelog_path echo "WinUtil change log received from GitHub Releases, it's autogenerated using GitHub Actions." >> $changelog_path echo "" >> $changelog_path echo "> [!WARNING]" >> $changelog_path echo "> This file **SHOULD NOT** be edited directly, any PRs that tries changing it directly will either be requested on not changing it, or it'll get rejected." >> $changelog_path echo "" >> $changelog_path # Make array for git tag names tag_arr=() cat releases.txt | grep -Po '"tagName":\s*.*?[^\\]"' | awk -F ':' '{print $2}' | sed s/\"//g > tags_list.txt while read -r line; do tag_arr+=("$line") done < tags_list.txt # Make array for releases names name_arr=() cat releases.txt | grep -Po '"name":\s*.*?[^\\]"' | awk -F ':' '{print $2}' | sed s/\"//g > releases_names_list.txt while read -r line; do name_arr+=("$line") done < releases_names_list.txt # Make array for isPrerelease isprerelease_arr=() cat releases.txt | grep -Po '"isPrerelease":\s*(false|true)' | awk -F ':' '{print $2}' | sed s/\"//g > isprerelease_list.txt while read -r line; do isprerelease_arr+=("$line") done < isprerelease_list.txt # Make array for isLatest islatest_arr=() cat releases.txt | grep -Po '"isLatest":\s*(false|true)' | awk -F ':' '{print $2}' | sed s/\"//g > islatest_list.txt while read -r line; do islatest_arr+=("$line") done < islatest_list.txt # Debug Output echo "Tag Array: " ${tag_arr[@]} echo "Array Length: " ${#tag_arr[@]} echo "" echo "Release Name Array: " ${name_arr[@]} echo "Array Length: " ${#name_arr[@]} echo "" echo "IsPrerelease Array: " ${isprerelease_arr[@]} echo "Array Length: " ${#isprerelease_arr[@]} echo "" echo "IsLatest Array: " ${islatest_arr[@]} echo "Array Length: " ${#islatest_arr[@]} echo "" # Exit when this impossible condition is met (just to be safe) if [[ ! (${#tag_arr[@]}==${#name_arr[@]} && ${#tag_arr[@]}==${#isprerelease_arr[@]} && ${#tag_arr[@]}==${#islatest_arr[@]} ) ]] ; then echo "Impossible Condition has been met, the Name Array Length Does Not match Tag Array Length, exiting..." exit 1 fi # Main loop that does the heavy lifting (Content Generation) for (( i=0; i<${number_of_releases}; i++ )); do # The Variables to use on each iteration tag=${tag_arr[$i]} name=${name_arr[$i]} isprerelease=${isprerelease_arr[$i]} islatest=${islatest_arr[$i]} body=$(gh release view "$tag" --json body --jq .body) || { echo "Failed to fetch release body for $tag"; exit 1; } # The generation of changelog file contents echo "# $name" >> $changelog_path echo "" >> $changelog_path echo "$body" >> $changelog_path echo "" >> $changelog_path done env: GH_TOKEN: ${{ github.token }} - name: Commit and Push Changes env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | git config --global user.name 'github-actions[bot]' git config --global user.email 'github-actions[bot]@users.noreply.github.com' git add docs/changelog.md git diff --quiet && git diff --staged --quiet || (git commit -m "Update changelog.md with all releases" && git push)