From 4b360e4d711909f80120847d931b4863aa4ece5b Mon Sep 17 00:00:00 2001 From: rudra-iitm Date: Mon, 23 Dec 2024 14:32:06 +0530 Subject: [PATCH 1/3] Add support for optional README path flag to list and track parts used more easily in README. --- README.md | 14 ++++++++ action.yml | 35 ++++++++++++++++---- updatesnap/updatesnapyaml.py | 62 ++++++++++++++++++++++++++++++++++-- 3 files changed, 101 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a57983e..d5a2ef6 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,20 @@ To include this feature as a github worflow you need to pass an optional input i ./updatesnap/updatesnapyaml.py --github-user GITHUB_USER --github-token GITHUB_TOKEN --version-schema VERSION_SCHEMA https://github.com/ubuntu/gnome-calculator.git ``` +This tool can also be used to list the parts defined in the YAML file directly within the README for easier tracking. + +Ensure your README file contains the following comment block where you want the parts to be listed: +``` + + + +``` + +To use this functionality locally, run the following command: +``` +./updatesnap/updatesnapyaml.py --github-user GITHUB_USER --github-token GITHUB_TOKEN --readme-path README_PATH https://github.com/ubuntu/gnome-calculator.git +``` + ### How Snap Version Automation Works The snap version automation feature functions by extracting version information from the designated section labeled as `adopt-info`. Subsequently, it automatically updates the version of the primary snap. This versioning scheme consists of two components: diff --git a/action.yml b/action.yml index 17262db..e4c8749 100644 --- a/action.yml +++ b/action.yml @@ -21,6 +21,9 @@ inputs: yaml-path: description: 'Path to the YAML file' required: false + readme-path: + description: 'Path to the README file' + required: false # Outputs generated by running this action. outputs: @@ -32,6 +35,7 @@ outputs: env: IS_CHANGE: false IS_VERSION_CHANGE: false + IS_README_CHANGE: false # The jobs description defining a composite action runs: @@ -50,7 +54,15 @@ runs: - name: run updatesnapyaml id: updatesnapyaml run: | - ./desktop-snaps/updatesnap/updatesnapyaml.py --github-user $GITHUB_USER --github-token $GITHUB_TOKEN ${VERSION_SCHEMA:+--version-schema $VERSION_SCHEMA} ${ROCK_VERSION_SCHEMA:+--rock-version-schema $ROCK_VERSION_SCHEMA} ${YAML_PATH:+--yaml-path $YAML_PATH} https://github.com/${{ github.repository }} + ./desktop-snaps/updatesnap/updatesnapyaml.py \ + --github-user $GITHUB_USER \ + --github-token $GITHUB_TOKEN \ + ${VERSION_SCHEMA:+--version-schema $VERSION_SCHEMA} \ + ${ROCK_VERSION_SCHEMA:+--rock-version-schema $ROCK_VERSION_SCHEMA} \ + ${YAML_PATH:+--yaml-path $YAML_PATH} \ + ${README_PATH:+--readme-path $README_PATH} \ + https://github.com/${{ github.repository }} + # Make sure to put the updated snapcraft.yaml file in the right location if it lives in a snap directory if [ -f version_file ]; then echo "IS_VERSION_CHANGE=true" >> $GITHUB_ENV @@ -66,12 +78,18 @@ runs: mv output_file snapcraft.yaml fi fi + # Make sure to put the updated README file in the right location + if [ -f readme_output ] && [ -n "$README_PATH" ]; then + echo "IS_README_CHANGE=true" >> $GITHUB_ENV + mv readme_output "$README_PATH" + fi env: GITHUB_USER: ubuntu GITHUB_TOKEN: ${{ inputs.token }} VERSION_SCHEMA: ${{ inputs.version-schema }} ROCK_VERSION_SCHEMA: ${{ inputs.rock-version-schema }} YAML_PATH: ${{ inputs.yaml-path }} + README_PATH: ${{ inputs.readme-path }} shell: bash # Step to remove the desktop-snaps folder so that when we commit changes in another repo, the desktop-snaps folder is not committed there. @@ -82,24 +100,27 @@ runs: # If there was a change detected, then let's commit the changes - name: Commit files - if: ${{ env.IS_CHANGE || env.IS_VERSION_CHANGE}} + if: ${{ env.IS_CHANGE || env.IS_VERSION_CHANGE || env.IS_README_CHANGE }} run: | set -x git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" commit_msg="Update tag" - if [ $IS_VERSION_CHANGE = true ] && [ $IS_CHANGE = false ]; then + if [ "$IS_README_CHANGE" = true ] && [ "$IS_VERSION_CHANGE" = true ] && [ "$IS_CHANGE" = true ]; then + commit_msg="Update README, snap version, and tag" + elif [ "$IS_VERSION_CHANGE" = true ] && [ "$IS_CHANGE" = true ]; then + commit_msg="Update snap version and tag" + elif [ "$IS_VERSION_CHANGE" = true ]; then commit_msg="Update snap version" - fi - if [ $IS_VERSION_CHANGE = true ] && [ $IS_CHANGE = true ]; then - commit_msg="Update snap version/tag" + elif [ "$IS_README_CHANGE" = true ]; then + commit_msg="Update README" fi git commit -a -m "$commit_msg" shell: bash # If there was a change detected, then let's push the changes - name: Push changes - if: ${{ env.IS_CHANGE || env.IS_VERSION_CHANGE }} + if: ${{ env.IS_CHANGE || env.IS_VERSION_CHANGE || env.IS_README_CHANGE }} uses: ad-m/github-push-action@master env: GITHUB_USER: ubuntu diff --git a/updatesnap/updatesnapyaml.py b/updatesnap/updatesnapyaml.py index b201f2a..9372c2c 100755 --- a/updatesnap/updatesnapyaml.py +++ b/updatesnap/updatesnapyaml.py @@ -5,6 +5,7 @@ import sys import argparse import logging +import re from SnapModule.snapmodule import Snapcraft, Github from SnapModule.manageYAML import ManageYAML from SnapVersionModule.snap_version_module import is_version_update, is_rock_version_update @@ -63,9 +64,54 @@ def get_yaml_file(self, project_url, yaml_path): data = None return data + def get_readme_file(self, project_url, readme_path): + """ Searches in a project for the 'README' file and + returns its contents """ + try: + data = self._github.get_file(project_url, readme_path) + except (ValueError, ConnectionError): + data = None + return data -def main(): - """ Main code """ + def update_readme(self, project_url, parts, readme_path): + """ + Updates the to + sections in the README with the updated part list. + """ + if readme_path is None: + return + + readme_data = self.get_readme_file(project_url, readme_path) + if not readme_data: + print('Failed to get the README file.', file=sys.stderr) + sys.exit(1) + readme_content = readme_data.decode('utf-8') + + parts_contents = "\n".join([ + f" - {part['name']} " + f"{part['updates'][0]['name'] if part['updates'] else part['version'][0]}" + for part in parts if part + ]) + formatted_contents = f"## Included Components\n{parts_contents}" + updated_readme = re.sub( + r"\n.*?\n", + f"\n" + f"{formatted_contents}\n" + f"", + readme_content, + flags=re.DOTALL + ) + + if updated_readme != readme_content: + print("Updating README file", file=sys.stderr) + with open('readme_output', 'w', encoding="utf8") as readme_output_file: + readme_output_file.write(updated_readme) + else: + print("No updates available for README file", file=sys.stderr) + + +def parse_args(): + """ Parses command-line arguments for the script. """ parser = argparse.ArgumentParser(prog='Update Snap YAML', description='Find the lastest source' ' versions for snap files and generates a new snapcraft.yaml.') @@ -79,9 +125,17 @@ def main(): help='Version schema of rock repository') parser.add_argument('--yaml-path', action='store', default=None, help='Path to the yaml file') + parser.add_argument('--readme-path', action='store', default=None, + help='Path of the README file parts will be listed.') parser.add_argument('--verbose', action='store_true', default=False) parser.add_argument('project', default='.', help='The project URI') - arguments = parser.parse_args(sys.argv[1:]) + + return parser.parse_args(sys.argv[1:]) + + +def main(): + """ Main code """ + arguments = parse_args() if arguments.project == '.': print('A project URI is mandatory', file=sys.stderr) @@ -128,6 +182,8 @@ def main(): version_data['data'] = f"source-tag: '{part['updates'][0]['name']}'" has_update = True + manager.update_readme(arguments.project, parts, arguments.readme_path) + logging.basicConfig(level=logging.INFO) if (is_version_update(snap, manager_yaml, arguments, has_update) or is_rock_version_update(snap, manager_yaml, arguments, has_update) or has_update): From b04ac3c10291cad0851a7bcf10daa9fb913e1694 Mon Sep 17 00:00:00 2001 From: rudra-iitm Date: Tue, 7 Jan 2025 21:55:19 +0530 Subject: [PATCH 2/3] Better help msg for readme-path arg --- updatesnap/updatesnapyaml.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/updatesnap/updatesnapyaml.py b/updatesnap/updatesnapyaml.py index 9372c2c..b9f3c0d 100755 --- a/updatesnap/updatesnapyaml.py +++ b/updatesnap/updatesnapyaml.py @@ -126,7 +126,7 @@ def parse_args(): parser.add_argument('--yaml-path', action='store', default=None, help='Path to the yaml file') parser.add_argument('--readme-path', action='store', default=None, - help='Path of the README file parts will be listed.') + help='Path to the README.md file where the parts and their version will be listed.') parser.add_argument('--verbose', action='store_true', default=False) parser.add_argument('project', default='.', help='The project URI') From b612244003ef9bbf0ca2544da90aef0ca369ee85 Mon Sep 17 00:00:00 2001 From: rudra-iitm Date: Tue, 7 Jan 2025 22:59:38 +0530 Subject: [PATCH 3/3] Added precheck for README update markers --- updatesnap/updatesnapyaml.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/updatesnap/updatesnapyaml.py b/updatesnap/updatesnapyaml.py index b9f3c0d..81b3143 100755 --- a/updatesnap/updatesnapyaml.py +++ b/updatesnap/updatesnapyaml.py @@ -87,6 +87,13 @@ def update_readme(self, project_url, parts, readme_path): sys.exit(1) readme_content = readme_data.decode('utf-8') + if ( + "\n" not in readme_content + or "" not in readme_content + ): + print("The required markers are missing in the README file.", file=sys.stderr) + return + parts_contents = "\n".join([ f" - {part['name']} " f"{part['updates'][0]['name'] if part['updates'] else part['version'][0]}" @@ -126,7 +133,8 @@ def parse_args(): parser.add_argument('--yaml-path', action='store', default=None, help='Path to the yaml file') parser.add_argument('--readme-path', action='store', default=None, - help='Path to the README.md file where the parts and their version will be listed.') + help='Path to the README.md file where the parts' + 'and their version will be listed.') parser.add_argument('--verbose', action='store_true', default=False) parser.add_argument('project', default='.', help='The project URI')