From 976946a1f62622ff2f297d9a3222d0c827b90e8c Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 5 Aug 2021 13:55:31 +0200 Subject: [PATCH 1/6] tools: Add update_changelog.py helper to tools directory This new helper script takes a branch name as input, then fetches `CHANGELOG.md` from that branch in the upstream mixxxdj/mixxx repo, converts the changelog into sphinx's ReStructured Text format and writes it to `source/chapters/appendix/version_history.py`. This makes keeping the manual repository changelog in sync with the code repository changelog much easier and will allow automation in the future. --- requirements.txt | 2 + tools/update_changelog.py | 77 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100755 tools/update_changelog.py diff --git a/requirements.txt b/requirements.txt index a129f0c1af..a840e65813 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,9 @@ sphinx sphinx-intl graphviz +m2r2 markupsafe +requests transifex-client sphinxcontrib-svg2pdfconverter sphinx-rtd-theme==0.5.2 diff --git a/tools/update_changelog.py b/tools/update_changelog.py new file mode 100755 index 0000000000..9f7c5bb705 --- /dev/null +++ b/tools/update_changelog.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +import argparse +import os +import re + +import m2r2 +import requests + + +TEMPLATE = """ +.. This is a generated file. Do not edit it manually, because it is updated + automatically via tools/update_changelog.py. + +.. include:: /shortcuts.rstext + +.. _appendix-version-history: + +{content} + +.. seealso:: For an overview of previous versions, `take a look + `_ at the timeline. +""" + + +def fetch_changelog(branch): + r = requests.get( + "https://raw.githubusercontent.com/mixxxdj/mixxx/" + f"{branch}/CHANGELOG.md" + ) + r.raise_for_status() + return r.text + + +def changelog_to_rst(changelog): + # Replace headline with "Version History" + changelog = re.sub( + "^# Changelog$", + "# Version History", + changelog, + flags=re.MULTILINE | re.IGNORECASE, + ) + + # Ensure that all launchpad issues are hyperlinks + changelog = re.sub( + r"(?!\[)\blp:?(?P\d+)\b(?!\])", + r"[lp:\g](https://bugs.launchpad.net/mixxx/+bug/\g)", + changelog, + ) + + # Ensure that all GitHub PRs are hyperlinks + changelog = re.sub( + r"(?!\[)#\b(?P\d+)\b(?!\])", + r"[#\g](https://github.com/mixxxdj/mixxx/pull/\g)", + changelog, + ) + + return TEMPLATE.lstrip().format(content=m2r2.convert(changelog)) + + +def main(argv=None): + parser = argparse.ArgumentParser() + parser.add_argument("-b", "--branch", required=True) + args = parser.parse_args(argv) + + changelog = fetch_changelog(args.branch) + changelog = changelog_to_rst(changelog) + + path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "../source/chapters/appendix/version_history.rst", + ) + with open(path, mode="w") as fp: + fp.write(changelog) + + +if __name__ == "__main__": + main() From b02d4b1336b5165fb61a79ebc1934ee6e6390e81 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 5 Aug 2021 14:26:20 +0200 Subject: [PATCH 2/6] CI: Add workflow to update changelog and rebuild on repo dispatch This workflow can be triggered using a personal access token (PAT) with the `public_repo` scope. $ curl -H "Accept: application/vnd.github.v3+json" \ -H "Authorization: token " \ --request POST \ --data '{"event_type": "update-changelog", "client_payload": {"branch": "2.3"}}' \ https://api.github.com/repos/mixxxdj/manual/dispatches It will then run `tools/update_changelog.py` and if any files were changed, it will commit these changes and then trigger rebuild of the manual. For the latter to work, a `MIXXXBOT_CHANGELOG_AUTOUPDATER_PAT` repository secret needs to be present, because the default `GITHUB_TOKEN` doesn't suffice. --- .github/workflows/build.yml | 12 +++++---- .github/workflows/changelog.yml | 46 +++++++++++++++++++++++++++++++++ requirements-changelog.txt | 2 ++ requirements.txt | 2 -- 4 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/changelog.yml create mode 100644 requirements-changelog.txt diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 99deaa13b0..d8be9683c2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,12 +6,14 @@ on: branches: - "main" - "[0-9]+.[0-9]+" + repository_dispatch: + types: rebuild jobs: build-html: name: HTML runs-on: ubuntu-latest - if: github.event_name == 'push' + if: github.event_name == 'push' || github.event_name == 'repository_dispatch' steps: - uses: actions/checkout@v2 with: @@ -62,7 +64,7 @@ jobs: - name: Install Python dependencies run: pip install --upgrade -r requirements.txt - name: Set up SSH Agent - if: github.event_name == 'push' && env.SSH_PRIVATE_KEY != null + if: (github.event_name == 'push' || github.event_name == 'repository_dispatch') && env.SSH_PRIVATE_KEY != null env: SSH_AUTH_SOCK: /tmp/ssh_agent.sock SSH_PRIVATE_KEY: ${{ secrets.DOWNLOADS_HOSTGATOR_DOT_MIXXX_DOT_ORG_KEY }} @@ -74,15 +76,15 @@ jobs: ssh-keyscan "${SSH_HOST}" >> "${HOME}/.ssh/known_hosts" echo "SSH_AUTH_SOCK=${SSH_AUTH_SOCK}" >> "${GITHUB_ENV}" - name: Build PDF manual - if: github.event_name != 'push' || env.SSH_AUTH_SOCK == null + if: (github.event_name != 'push' || github.event_name != 'repository_dispatch') && env.SSH_AUTH_SOCK == null run: | sphinx-build -b latex -q -j $(nproc) -Dlatex_engine=xelatex source build make -C build LATEXMKOPTS="-f -interaction=nonstopmode -pdf -xelatex" all-pdf - name: Build PDF manual in all languages - if: github.event_name == 'push' && env.SSH_AUTH_SOCK != null + if: (github.event_name == 'push' || github.event_name == 'repository_dispatch') && env.SSH_AUTH_SOCK != null run: sh build_pdf.sh - name: Deploy PDF manuals to download server - if: github.event_name == 'push' && env.SSH_AUTH_SOCK != null + if: (github.event_name == 'push' || github.event_name == 'repository_dispatch') && env.SSH_AUTH_SOCK != null run: rsync --verbose --recursive --checksum --times --delay-updates "build/pdf/" "${SSH_USER}@${SSH_HOST}:${DESTDIR}/" env: DESTDIR: public_html/downloads/manual diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml new file mode 100644 index 0000000000..ca838e566d --- /dev/null +++ b/.github/workflows/changelog.yml @@ -0,0 +1,46 @@ +name: Changelog + +on: + repository_dispatch: + types: update-changelog + +jobs: + update-changelog: + name: Update Changelog + runs-on: ubuntu-latest + steps: + - name: Event Information + run: echo "Event '${{ github.event.action }}' received from '${{ github.event.client_payload.repository }}'" + - name: Check out repository + uses: actions/checkout@v2 + with: + ref: ${{ github.event.client_payload.branch }} + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.9 + - name: Install Python dependencies + run: pip install -r requirements-changelog.txt + - name: Update Changelog + run: tools/update_changelog.py -b "${{ github.event.client_payload.branch }}" + - name: Check if changes any changes were made + run: echo "GIT_DIRTY=$(git diff --quiet ; printf "%d" "$?")" >> "${GITHUB_ENV}" + - uses: EndBug/add-and-commit@v7 + if: env.GIT_DIRTY != null && env.GIT_DIRTY != '0' + with: + branch: ${{ github.event.client_payload.branch }} + add: "source/chapters/appendix/version_history.rst" + message: "appendix/version_history: Update changelog for ${{ github.event.client_payload.branch }} branch" + author_name: mixxxbot + author_email: bot@mixxx.org + push: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Trigger Rebuild + uses: peter-evans/repository-dispatch@v1 + if: env.GIT_DIRTY != null && env.GIT_DIRTY != '0' && env.MIXXXBOT_TOKEN != null + with: + token: ${{ env.MIXXXBOT_TOKEN }} + event-type: rebuild + env: + MIXXXBOT_TOKEN: ${{ secrets.MIXXXBOT_CHANGELOG_AUTOUPDATER_PAT }} diff --git a/requirements-changelog.txt b/requirements-changelog.txt new file mode 100644 index 0000000000..ec86c23ff8 --- /dev/null +++ b/requirements-changelog.txt @@ -0,0 +1,2 @@ +m2r2 +requests diff --git a/requirements.txt b/requirements.txt index a840e65813..a129f0c1af 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,7 @@ sphinx sphinx-intl graphviz -m2r2 markupsafe -requests transifex-client sphinxcontrib-svg2pdfconverter sphinx-rtd-theme==0.5.2 From e21c0e914542356e0a6c52a3648d6283a4a9d3ed Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 18 Aug 2021 12:18:46 +0200 Subject: [PATCH 3/6] CI: Add description for changelog workflow as a comment --- .github/workflows/changelog.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index ca838e566d..d158954d64 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -7,6 +7,15 @@ on: jobs: update-changelog: name: Update Changelog + # This job fetches the `CHANGELOG.md` from the corresponding branch in the + # mixxxdj/mixxx repository and uses it to update the `version_history.rst` + # file. If the file was changed, the change is committed and a + # rebuild/redeployment of the manual is triggered. + # + # This job is not run on changes to the manual repo. Instead, it's + # triggered by a repository dispatch hook that gets triggered by a + # corresponding workflow in the mixxxdj/mixxx repository whenever the + # CHANGELOG.md is changed. runs-on: ubuntu-latest steps: - name: Event Information From 3eed8098531b019e712015764e849c691fa1a1a3 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 18 Aug 2021 12:19:10 +0200 Subject: [PATCH 4/6] tools/update_changelog.py: Add some comments to improve readability --- tools/update_changelog.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/update_changelog.py b/tools/update_changelog.py index 9f7c5bb705..ddf673dc32 100755 --- a/tools/update_changelog.py +++ b/tools/update_changelog.py @@ -23,6 +23,7 @@ def fetch_changelog(branch): + """ Fetch CHANGELOG.md from branch of mixxxdj/mixxx repository. """ r = requests.get( "https://raw.githubusercontent.com/mixxxdj/mixxx/" f"{branch}/CHANGELOG.md" @@ -32,6 +33,7 @@ def fetch_changelog(branch): def changelog_to_rst(changelog): + """ Convert changelog to RST format used by sphinx. """ # Replace headline with "Version History" changelog = re.sub( "^# Changelog$", @@ -62,9 +64,11 @@ def main(argv=None): parser.add_argument("-b", "--branch", required=True) args = parser.parse_args(argv) + # Fetch changelog and convert to RST changelog = fetch_changelog(args.branch) changelog = changelog_to_rst(changelog) + # Write changelog to version_history.rst file path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "../source/chapters/appendix/version_history.rst", From a10f31a43db482b2dd6563bd3d10aec380360bcf Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 1 Sep 2021 14:21:32 +0200 Subject: [PATCH 5/6] tools/update_changelog.py: Move link fixing to mixxx repo This is now part of https://github.com/mixxxdj/mixxx/pull/4256. --- tools/update_changelog.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/tools/update_changelog.py b/tools/update_changelog.py index ddf673dc32..29f8d8f324 100755 --- a/tools/update_changelog.py +++ b/tools/update_changelog.py @@ -42,20 +42,6 @@ def changelog_to_rst(changelog): flags=re.MULTILINE | re.IGNORECASE, ) - # Ensure that all launchpad issues are hyperlinks - changelog = re.sub( - r"(?!\[)\blp:?(?P\d+)\b(?!\])", - r"[lp:\g](https://bugs.launchpad.net/mixxx/+bug/\g)", - changelog, - ) - - # Ensure that all GitHub PRs are hyperlinks - changelog = re.sub( - r"(?!\[)#\b(?P\d+)\b(?!\])", - r"[#\g](https://github.com/mixxxdj/mixxx/pull/\g)", - changelog, - ) - return TEMPLATE.lstrip().format(content=m2r2.convert(changelog)) From 5097ab79e827eb1fb72bc703693f3238aa915785 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 1 Sep 2021 14:24:30 +0200 Subject: [PATCH 6/6] appendix: Rename "Version History" to "Changelog" As requested here: https://github.com/mixxxdj/manual/pull/422#discussion_r699019704 --- source/chapters/appendix.rst | 2 +- .../{version_history.rst => changelog.rst} | 6 +++--- tools/update_changelog.py | 15 +++------------ 3 files changed, 7 insertions(+), 16 deletions(-) rename source/chapters/appendix/{version_history.rst => changelog.rst} (99%) diff --git a/source/chapters/appendix.rst b/source/chapters/appendix.rst index 1c32cb6a4e..cc82a84474 100644 --- a/source/chapters/appendix.rst +++ b/source/chapters/appendix.rst @@ -11,4 +11,4 @@ Appendix appendix/commandline_dev_tools appendix/mixxx_controls appendix/additional_resources - appendix/version_history + appendix/changelog diff --git a/source/chapters/appendix/version_history.rst b/source/chapters/appendix/changelog.rst similarity index 99% rename from source/chapters/appendix/version_history.rst rename to source/chapters/appendix/changelog.rst index 4de9ede209..f7b8da3da1 100644 --- a/source/chapters/appendix/version_history.rst +++ b/source/chapters/appendix/changelog.rst @@ -1,9 +1,9 @@ .. include:: /shortcuts.rstext -.. _appendix-version-history: +.. _appendix-changelog: -Version History -=============== +Changelog +========= 2.3.0 ----- diff --git a/tools/update_changelog.py b/tools/update_changelog.py index 29f8d8f324..7aa7086b05 100755 --- a/tools/update_changelog.py +++ b/tools/update_changelog.py @@ -1,7 +1,6 @@ #!/usr/bin/env python3 import argparse import os -import re import m2r2 import requests @@ -13,7 +12,7 @@ .. include:: /shortcuts.rstext -.. _appendix-version-history: +.. _appendix-changelog: {content} @@ -34,14 +33,6 @@ def fetch_changelog(branch): def changelog_to_rst(changelog): """ Convert changelog to RST format used by sphinx. """ - # Replace headline with "Version History" - changelog = re.sub( - "^# Changelog$", - "# Version History", - changelog, - flags=re.MULTILINE | re.IGNORECASE, - ) - return TEMPLATE.lstrip().format(content=m2r2.convert(changelog)) @@ -54,10 +45,10 @@ def main(argv=None): changelog = fetch_changelog(args.branch) changelog = changelog_to_rst(changelog) - # Write changelog to version_history.rst file + # Write changelog to changelog.rst file path = os.path.join( os.path.dirname(os.path.abspath(__file__)), - "../source/chapters/appendix/version_history.rst", + "../source/chapters/appendix/changelog.rst", ) with open(path, mode="w") as fp: fp.write(changelog)