From 36dbcb252e395645fb8a1a203936a8ac647fde27 Mon Sep 17 00:00:00 2001 From: Ricardo Zamora Date: Fri, 21 Jun 2024 11:01:59 -0700 Subject: [PATCH 01/24] repometrics cookiecutter developed --- tier2/repometrics/cookiecutter.json | 16 ++++++++ tier2/repometrics/hooks/post_gen_project.py | 41 +++++++++++++++++++ .../repometrics.json | 9 ++++ 3 files changed, 66 insertions(+) create mode 100644 tier2/repometrics/cookiecutter.json create mode 100644 tier2/repometrics/hooks/post_gen_project.py create mode 100644 tier2/repometrics/{{cookiecutter.project_type}}/repometrics.json diff --git a/tier2/repometrics/cookiecutter.json b/tier2/repometrics/cookiecutter.json new file mode 100644 index 0000000..871b2bf --- /dev/null +++ b/tier2/repometrics/cookiecutter.json @@ -0,0 +1,16 @@ +{ + "project_type" : ["Package", "Website", "Standards", "Libraries", "Data", "Apps", "Tools", "APIs"], + "user_input": ["Yes", "No"], + "project_fisma_level": ["Low", "Moderate", "High"], + "group": "CMS/OA/DSAC/CCSQ", + "subset_in_healthcare": "Policy,Operational", + "user_type": "Providers, Patients, Government", + "repository_host": ["Github.com", "GitHub ENT", "GitHub Cloud", "GitLab.com", "GitLab ENT", "GitLab ENT CCSQ"], + "__prompts__": { + "group": "Which group is the project part of?", + "subset_in_healthcare": "Which subset of healthcare does it belong to?", + "user_type": "Who are the intended users?", + "user_input": "Does the project accept user input? (e.g. allows user to query a database, allows login by users, etc.)", + "repository_host": "Where is the repository hosted?" + } +} \ No newline at end of file diff --git a/tier2/repometrics/hooks/post_gen_project.py b/tier2/repometrics/hooks/post_gen_project.py new file mode 100644 index 0000000..bff38a3 --- /dev/null +++ b/tier2/repometrics/hooks/post_gen_project.py @@ -0,0 +1,41 @@ +import os +import shutil +import time + +# Get working directory and repometrics file +current_dir = os.getcwd() +repometrics_file = "repometrics.json" +source_file = os.path.join(current_dir, repometrics_file) + +# Get parent directory, one level up from the current directory +parent_dir = os.path.abspath(os.path.join(current_dir, '..')) + +# Construct the destination path in the parent directory +destination_file = os.path.join(parent_dir, repometrics_file) + +# Attempt to move repometrics to parent directory +try: + shutil.move(source_file, destination_file) +except FileNotFoundError: + print(f"The file {source_file} does not exist.") +except PermissionError: + print(f"Permission denied: Unable to move the file {source_file}.") +except Exception as e: + print(f"An error occurred: {e}") + + +# Remove directory once repometrics file was successfully moved +os.chdir("..") +dir_name = "{{cookiecutter.project_type}}" + +try: + # Check if the directory exists + if os.path.exists(dir_name): + # Attempt to remove the directory + print(f"Directory '{dir_name}' has been removed.") + else: + print(f"Directory '{dir_name}' does not exist.") +except FileNotFoundError: + print(f"File not found: The directory '{dir_name}' does not exist.") +except Exception as e: + print(f"An error occurred: {e}") \ No newline at end of file diff --git a/tier2/repometrics/{{cookiecutter.project_type}}/repometrics.json b/tier2/repometrics/{{cookiecutter.project_type}}/repometrics.json new file mode 100644 index 0000000..fcf1041 --- /dev/null +++ b/tier2/repometrics/{{cookiecutter.project_type}}/repometrics.json @@ -0,0 +1,9 @@ +{ + "project_type": "{{ cookiecutter.project_type }}", + "user_input": "{{cookiecutter.user_input}}", + "project_fisma_level": "{{ cookiecutter.project_fisma_level }}", + "group": "{{cookiecutter.group}}", + "subset_in_healthcare": "{{cookiecutter.subset_in_healthcare}}", + "user_type": "{{cookiecutter.user_type}}", + "repository_host": "{{cookiecutter.repository_host}}" +} \ No newline at end of file From f57ca36814ab0e387972d52b32067f9a84eec045 Mon Sep 17 00:00:00 2001 From: Ricardo Zamora Date: Mon, 24 Jun 2024 18:44:55 -0700 Subject: [PATCH 02/24] nested cookiecutter, added remove directory function --- .../repometrics/cookiecutter.json | 0 .../repometrics/hooks/post_gen_project.py | 2 +- .../repometrics/{{cookiecutter.project_type}}/repometrics.json | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename tier2/{ => {{cookiecutter.project_slug}}}/repometrics/cookiecutter.json (100%) rename tier2/{ => {{cookiecutter.project_slug}}}/repometrics/hooks/post_gen_project.py (95%) rename tier2/{ => {{cookiecutter.project_slug}}}/repometrics/{{cookiecutter.project_type}}/repometrics.json (100%) diff --git a/tier2/repometrics/cookiecutter.json b/tier2/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json similarity index 100% rename from tier2/repometrics/cookiecutter.json rename to tier2/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json diff --git a/tier2/repometrics/hooks/post_gen_project.py b/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.py similarity index 95% rename from tier2/repometrics/hooks/post_gen_project.py rename to tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.py index bff38a3..a37085e 100644 --- a/tier2/repometrics/hooks/post_gen_project.py +++ b/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.py @@ -32,7 +32,7 @@ # Check if the directory exists if os.path.exists(dir_name): # Attempt to remove the directory - print(f"Directory '{dir_name}' has been removed.") + shutil.rmtree(dir_name) else: print(f"Directory '{dir_name}' does not exist.") except FileNotFoundError: diff --git a/tier2/repometrics/{{cookiecutter.project_type}}/repometrics.json b/tier2/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/repometrics.json similarity index 100% rename from tier2/repometrics/{{cookiecutter.project_type}}/repometrics.json rename to tier2/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/repometrics.json From e916590739f49a74c91ec3c81324869ac2cddfb6 Mon Sep 17 00:00:00 2001 From: Ricardo Zamora Date: Tue, 25 Jun 2024 10:31:48 -0700 Subject: [PATCH 03/24] added copy without render to parent cookiecutter --- tier2/cookiecutter.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tier2/cookiecutter.json b/tier2/cookiecutter.json index b159a65..49e483d 100644 --- a/tier2/cookiecutter.json +++ b/tier2/cookiecutter.json @@ -11,5 +11,6 @@ "__prompts__": { "create_repo": "Would you like to create a repo on github.com?", "receive_updates": "Would you like to receive updates from the DSACMS team via pull requests?" - } + }, + "_copy_without_render": ["repometrics"] } From 6809978d14f8c0af757a884bda61b41bf5778ea5 Mon Sep 17 00:00:00 2001 From: Ricardo Zamora Date: Wed, 26 Jun 2024 11:49:59 -0700 Subject: [PATCH 04/24] move repometrics to root project directory, delete subdir --- .../repometrics/hooks/post_gen_project.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.py b/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.py index a37085e..3262f27 100644 --- a/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.py +++ b/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.py @@ -8,7 +8,7 @@ source_file = os.path.join(current_dir, repometrics_file) # Get parent directory, one level up from the current directory -parent_dir = os.path.abspath(os.path.join(current_dir, '..')) +parent_dir = os.path.abspath(os.path.join(current_dir, '../..')) # Construct the destination path in the parent directory destination_file = os.path.join(parent_dir, repometrics_file) @@ -25,12 +25,12 @@ # Remove directory once repometrics file was successfully moved -os.chdir("..") -dir_name = "{{cookiecutter.project_type}}" +os.chdir("../..") +dir_name = "repometrics" try: # Check if the directory exists - if os.path.exists(dir_name): + if os.path.exists(dir_name) and os.path.isdir(dir_name): # Attempt to remove the directory shutil.rmtree(dir_name) else: From a19a4eb52f1bd5e80de7b30bd7111629dd6767ca Mon Sep 17 00:00:00 2001 From: Ricardo Zamora Date: Wed, 26 Jun 2024 13:59:39 -0700 Subject: [PATCH 05/24] add pass after directory deletion --- .../repometrics/hooks/post_gen_project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.py b/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.py index 3262f27..5c19edf 100644 --- a/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.py +++ b/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.py @@ -34,7 +34,7 @@ # Attempt to remove the directory shutil.rmtree(dir_name) else: - print(f"Directory '{dir_name}' does not exist.") + pass except FileNotFoundError: print(f"File not found: The directory '{dir_name}' does not exist.") except Exception as e: From c310a73ba1c8a1021bb230db0fffde575d709bbc Mon Sep 17 00:00:00 2001 From: Ricardo Zamora Date: Wed, 26 Jun 2024 15:02:40 -0700 Subject: [PATCH 06/24] add maturity model field and update readme --- README.md | 6 ++++++ .../repometrics/cookiecutter.json | 4 +++- .../{{cookiecutter.project_type}}/repometrics.json | 3 ++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cb1f1d7..68223f8 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,12 @@ If you know what tier you need, you can run the cookiecutter for an individual t cookiecutter https://github.com/DSACMS/repo-scaffolder --directory=tierX ``` +## Add Repometrics to your Project +To integrate repometrics into your new project, navigate to your project's directory and run the following cookiecutter command: +``` +cookiecutter . --directory=repometrics +``` + ## Existing Projects You can update existing projects with the repo scaffolder. Using the `-s` flag on cookiecutter will not overwrite existing files. Follow these steps: 1. Create a new branch in your repo diff --git a/tier2/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json b/tier2/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json index 871b2bf..291e002 100644 --- a/tier2/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json +++ b/tier2/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json @@ -6,11 +6,13 @@ "subset_in_healthcare": "Policy,Operational", "user_type": "Providers, Patients, Government", "repository_host": ["Github.com", "GitHub ENT", "GitHub Cloud", "GitLab.com", "GitLab ENT", "GitLab ENT CCSQ"], + "maturity_model_tier": "Tier2, Tier3, Tier4", "__prompts__": { "group": "Which group is the project part of?", "subset_in_healthcare": "Which subset of healthcare does it belong to?", "user_type": "Who are the intended users?", "user_input": "Does the project accept user input? (e.g. allows user to query a database, allows login by users, etc.)", - "repository_host": "Where is the repository hosted?" + "repository_host": "Where is the repository hosted?", + "maturity_model_tier": "What maturity model tier is your project classified as?" } } \ No newline at end of file diff --git a/tier2/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/repometrics.json b/tier2/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/repometrics.json index fcf1041..dcd70b0 100644 --- a/tier2/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/repometrics.json +++ b/tier2/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/repometrics.json @@ -5,5 +5,6 @@ "group": "{{cookiecutter.group}}", "subset_in_healthcare": "{{cookiecutter.subset_in_healthcare}}", "user_type": "{{cookiecutter.user_type}}", - "repository_host": "{{cookiecutter.repository_host}}" + "repository_host": "{{cookiecutter.repository_host}}", + "maturity_model_tier": "{{cookiecutter.maturity_model_tier}}" } \ No newline at end of file From acf04eba6793fcf46bbe32e17702c219b7d3dbe0 Mon Sep 17 00:00:00 2001 From: Ricardo Zamora Date: Wed, 26 Jun 2024 15:21:45 -0700 Subject: [PATCH 07/24] set maturity model field to multiple choice --- .../{{cookiecutter.project_slug}}/repometrics/cookiecutter.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tier2/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json b/tier2/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json index 291e002..67177ea 100644 --- a/tier2/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json +++ b/tier2/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json @@ -6,7 +6,7 @@ "subset_in_healthcare": "Policy,Operational", "user_type": "Providers, Patients, Government", "repository_host": ["Github.com", "GitHub ENT", "GitHub Cloud", "GitLab.com", "GitLab ENT", "GitLab ENT CCSQ"], - "maturity_model_tier": "Tier2, Tier3, Tier4", + "maturity_model_tier": ["tier2", "tier3", "tier4"], "__prompts__": { "group": "Which group is the project part of?", "subset_in_healthcare": "Which subset of healthcare does it belong to?", From 79314a9e3d1fdc62fea08e936fc8d24586135a19 Mon Sep 17 00:00:00 2001 From: Ricardo Zamora Date: Thu, 27 Jun 2024 14:16:20 -0700 Subject: [PATCH 08/24] rename repometrics to code, update post-gen --- .../repometrics/hooks/post_gen_project.py | 29 +++++++++---------- .../{repometrics.json => code.json} | 0 2 files changed, 13 insertions(+), 16 deletions(-) rename tier2/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/{repometrics.json => code.json} (100%) diff --git a/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.py b/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.py index 5c19edf..793cc84 100644 --- a/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.py +++ b/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.py @@ -1,19 +1,18 @@ import os import shutil -import time -# Get working directory and repometrics file +# Get working directory and code.json file +project_type = '{{cookiecutter.project_type}}' current_dir = os.getcwd() -repometrics_file = "repometrics.json" +repometrics_file = "code.json" source_file = os.path.join(current_dir, repometrics_file) # Get parent directory, one level up from the current directory -parent_dir = os.path.abspath(os.path.join(current_dir, '../..')) - +parent_dir = os.path.normpath(os.path.join(current_dir, '..')) # Construct the destination path in the parent directory destination_file = os.path.join(parent_dir, repometrics_file) -# Attempt to move repometrics to parent directory +# Attempt to move code.json to parent directory try: shutil.move(source_file, destination_file) except FileNotFoundError: @@ -24,18 +23,16 @@ print(f"An error occurred: {e}") -# Remove directory once repometrics file was successfully moved -os.chdir("../..") +# Remove directories once code.json file was successfully moved dir_name = "repometrics" +repometrics_dir = os.path.join(parent_dir, dir_name) +project_type_dir = os.path.join(parent_dir, project_type) try: - # Check if the directory exists - if os.path.exists(dir_name) and os.path.isdir(dir_name): - # Attempt to remove the directory - shutil.rmtree(dir_name) - else: - pass -except FileNotFoundError: - print(f"File not found: The directory '{dir_name}' does not exist.") + if os.path.isdir(repometrics_dir): + shutil.rmtree(repometrics_dir) + + if os.path.isdir(project_type_dir): + shutil.rmtree(project_type_dir) except Exception as e: print(f"An error occurred: {e}") \ No newline at end of file diff --git a/tier2/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/repometrics.json b/tier2/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/code.json similarity index 100% rename from tier2/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/repometrics.json rename to tier2/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/code.json From 5bd59c3194bd69cbecdc07b951dcf57c1aa8d755 Mon Sep 17 00:00:00 2001 From: Ricardo Zamora Date: Thu, 27 Jun 2024 14:45:05 -0700 Subject: [PATCH 09/24] cleaning code/content consistency --- .../repometrics/cookiecutter.json | 8 ++++---- .../{{cookiecutter.project_type}}/code.json | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tier2/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json b/tier2/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json index 67177ea..162b0a8 100644 --- a/tier2/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json +++ b/tier2/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json @@ -2,14 +2,14 @@ "project_type" : ["Package", "Website", "Standards", "Libraries", "Data", "Apps", "Tools", "APIs"], "user_input": ["Yes", "No"], "project_fisma_level": ["Low", "Moderate", "High"], - "group": "CMS/OA/DSAC/CCSQ", - "subset_in_healthcare": "Policy,Operational", + "group": "CMS/OA/DSAC", + "subset_in_healthcare": "Policy, Operational", "user_type": "Providers, Patients, Government", "repository_host": ["Github.com", "GitHub ENT", "GitHub Cloud", "GitLab.com", "GitLab ENT", "GitLab ENT CCSQ"], - "maturity_model_tier": ["tier2", "tier3", "tier4"], + "maturity_model_tier": ["1", "2", "3", "4"], "__prompts__": { "group": "Which group is the project part of?", - "subset_in_healthcare": "Which subset of healthcare does it belong to?", + "subset_in_healthcare": "Which subset of healthcare does the project belong to?", "user_type": "Who are the intended users?", "user_input": "Does the project accept user input? (e.g. allows user to query a database, allows login by users, etc.)", "repository_host": "Where is the repository hosted?", diff --git a/tier2/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/code.json b/tier2/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/code.json index dcd70b0..0841645 100644 --- a/tier2/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/code.json +++ b/tier2/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/code.json @@ -1,10 +1,10 @@ { "project_type": "{{ cookiecutter.project_type }}", - "user_input": "{{cookiecutter.user_input}}", + "user_input": "{{ cookiecutter.user_input }}", "project_fisma_level": "{{ cookiecutter.project_fisma_level }}", - "group": "{{cookiecutter.group}}", - "subset_in_healthcare": "{{cookiecutter.subset_in_healthcare}}", - "user_type": "{{cookiecutter.user_type}}", - "repository_host": "{{cookiecutter.repository_host}}", - "maturity_model_tier": "{{cookiecutter.maturity_model_tier}}" + "group": "{{ cookiecutter.group }}", + "subset_in_healthcare": "{{ cookiecutter.subset_in_healthcare }}", + "user_type": "{{ cookiecutter.user_type }}", + "repository_host": "{{ cookiecutter.repository_host }}", + "maturity_model_tier": "{{ cookiecutter.maturity_model_tier }}" } \ No newline at end of file From b8a8bfd1750261c05b2eb11cb6faff16d6ebb554 Mon Sep 17 00:00:00 2001 From: Ricardo Zamora Date: Fri, 28 Jun 2024 10:46:06 -0700 Subject: [PATCH 10/24] converted post-gen-proj to bash script --- .../repometrics/hooks/post_gen_project.py | 38 ------------------- .../repometrics/hooks/post_gen_project.sh | 33 ++++++++++++++++ 2 files changed, 33 insertions(+), 38 deletions(-) delete mode 100644 tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.py create mode 100644 tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.sh diff --git a/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.py b/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.py deleted file mode 100644 index 793cc84..0000000 --- a/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.py +++ /dev/null @@ -1,38 +0,0 @@ -import os -import shutil - -# Get working directory and code.json file -project_type = '{{cookiecutter.project_type}}' -current_dir = os.getcwd() -repometrics_file = "code.json" -source_file = os.path.join(current_dir, repometrics_file) - -# Get parent directory, one level up from the current directory -parent_dir = os.path.normpath(os.path.join(current_dir, '..')) -# Construct the destination path in the parent directory -destination_file = os.path.join(parent_dir, repometrics_file) - -# Attempt to move code.json to parent directory -try: - shutil.move(source_file, destination_file) -except FileNotFoundError: - print(f"The file {source_file} does not exist.") -except PermissionError: - print(f"Permission denied: Unable to move the file {source_file}.") -except Exception as e: - print(f"An error occurred: {e}") - - -# Remove directories once code.json file was successfully moved -dir_name = "repometrics" -repometrics_dir = os.path.join(parent_dir, dir_name) -project_type_dir = os.path.join(parent_dir, project_type) - -try: - if os.path.isdir(repometrics_dir): - shutil.rmtree(repometrics_dir) - - if os.path.isdir(project_type_dir): - shutil.rmtree(project_type_dir) -except Exception as e: - print(f"An error occurred: {e}") \ No newline at end of file diff --git a/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.sh b/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.sh new file mode 100644 index 0000000..7946bf2 --- /dev/null +++ b/tier2/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Change to the parent directory +cd .. + +# Define the repometrics directory to remove +dir_name="repometrics" + +# Check if repometrics directory exists and remove it +if [ -d "$dir_name" ]; then + rm -rf "$dir_name" +fi + +project_type="{{cookiecutter.project_type}}" +sub_project_dir="${project_type}" +repometrics_file="code.json" +parent_dir="./" + +if [ -f "${sub_project_dir}/${repometrics_file}" ]; then + # Move code.json file to parent directory + mv "${sub_project_dir}/${repometrics_file}" "${parent_dir}" + + # Check if the move was successful + if [ $? -eq 0 ]; then + # Remove the source directory + rm -rf "${sub_project_dir}" + + # Check if the deletion was successful + if [ $? -eq 0 ]; then + echo "Successfully generated code.json file." + fi + fi +fi \ No newline at end of file From b975b679a2e1709bfcb72236e5f638c29b0c13f4 Mon Sep 17 00:00:00 2001 From: Ricardo Zamora Date: Fri, 28 Jun 2024 19:30:41 -0700 Subject: [PATCH 11/24] add repometrics directory to tier3 --- tier3/cookiecutter.json | 3 +- .../repometrics/cookiecutter.json | 18 ++++++++++ .../repometrics/hooks/post_gen_project.sh | 33 +++++++++++++++++++ .../{{cookiecutter.project_type}}/code.json | 10 ++++++ 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 tier3/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json create mode 100644 tier3/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.sh create mode 100644 tier3/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/code.json diff --git a/tier3/cookiecutter.json b/tier3/cookiecutter.json index b159a65..49e483d 100644 --- a/tier3/cookiecutter.json +++ b/tier3/cookiecutter.json @@ -11,5 +11,6 @@ "__prompts__": { "create_repo": "Would you like to create a repo on github.com?", "receive_updates": "Would you like to receive updates from the DSACMS team via pull requests?" - } + }, + "_copy_without_render": ["repometrics"] } diff --git a/tier3/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json b/tier3/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json new file mode 100644 index 0000000..162b0a8 --- /dev/null +++ b/tier3/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json @@ -0,0 +1,18 @@ +{ + "project_type" : ["Package", "Website", "Standards", "Libraries", "Data", "Apps", "Tools", "APIs"], + "user_input": ["Yes", "No"], + "project_fisma_level": ["Low", "Moderate", "High"], + "group": "CMS/OA/DSAC", + "subset_in_healthcare": "Policy, Operational", + "user_type": "Providers, Patients, Government", + "repository_host": ["Github.com", "GitHub ENT", "GitHub Cloud", "GitLab.com", "GitLab ENT", "GitLab ENT CCSQ"], + "maturity_model_tier": ["1", "2", "3", "4"], + "__prompts__": { + "group": "Which group is the project part of?", + "subset_in_healthcare": "Which subset of healthcare does the project belong to?", + "user_type": "Who are the intended users?", + "user_input": "Does the project accept user input? (e.g. allows user to query a database, allows login by users, etc.)", + "repository_host": "Where is the repository hosted?", + "maturity_model_tier": "What maturity model tier is your project classified as?" + } +} \ No newline at end of file diff --git a/tier3/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.sh b/tier3/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.sh new file mode 100644 index 0000000..7946bf2 --- /dev/null +++ b/tier3/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Change to the parent directory +cd .. + +# Define the repometrics directory to remove +dir_name="repometrics" + +# Check if repometrics directory exists and remove it +if [ -d "$dir_name" ]; then + rm -rf "$dir_name" +fi + +project_type="{{cookiecutter.project_type}}" +sub_project_dir="${project_type}" +repometrics_file="code.json" +parent_dir="./" + +if [ -f "${sub_project_dir}/${repometrics_file}" ]; then + # Move code.json file to parent directory + mv "${sub_project_dir}/${repometrics_file}" "${parent_dir}" + + # Check if the move was successful + if [ $? -eq 0 ]; then + # Remove the source directory + rm -rf "${sub_project_dir}" + + # Check if the deletion was successful + if [ $? -eq 0 ]; then + echo "Successfully generated code.json file." + fi + fi +fi \ No newline at end of file diff --git a/tier3/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/code.json b/tier3/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/code.json new file mode 100644 index 0000000..0841645 --- /dev/null +++ b/tier3/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/code.json @@ -0,0 +1,10 @@ +{ + "project_type": "{{ cookiecutter.project_type }}", + "user_input": "{{ cookiecutter.user_input }}", + "project_fisma_level": "{{ cookiecutter.project_fisma_level }}", + "group": "{{ cookiecutter.group }}", + "subset_in_healthcare": "{{ cookiecutter.subset_in_healthcare }}", + "user_type": "{{ cookiecutter.user_type }}", + "repository_host": "{{ cookiecutter.repository_host }}", + "maturity_model_tier": "{{ cookiecutter.maturity_model_tier }}" +} \ No newline at end of file From 9ea0f2e77e16ba2ddb8d363ac7fbdef6cc54380a Mon Sep 17 00:00:00 2001 From: CreativeNick Date: Sat, 29 Jun 2024 14:25:50 -0700 Subject: [PATCH 12/24] slugified and added maintainer functionality for tier2 --- tier2/cookiecutter.json | 4 +- tier2/hooks/post_gen_project.py | 45 +++++++++++++++++++ .../.github/workflows/contributors.yml | 6 +++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/tier2/cookiecutter.json b/tier2/cookiecutter.json index b159a65..bbce4c8 100644 --- a/tier2/cookiecutter.json +++ b/tier2/cookiecutter.json @@ -8,8 +8,10 @@ "project_visibility": ["public", "internal", "private"], "create_repo": [true, false], "receive_updates": [true, false], + "add_maintainer": [true, false], "__prompts__": { "create_repo": "Would you like to create a repo on github.com?", - "receive_updates": "Would you like to receive updates from the DSACMS team via pull requests?" + "receive_updates": "Would you like to receive updates from the DSACMS team via pull requests?", + "add_maintainer": "Would you like to add a maintainer?" } } diff --git a/tier2/hooks/post_gen_project.py b/tier2/hooks/post_gen_project.py index 4b8f82f..67bcf30 100644 --- a/tier2/hooks/post_gen_project.py +++ b/tier2/hooks/post_gen_project.py @@ -6,6 +6,7 @@ DESCRIPTION = '{{cookiecutter.project_description}}' CREATE_REPO = '{{cookiecutter.create_repo}}' RECEIVE_UPDATES = '{{cookiecutter.receive_updates}}' +ADD_MAINTAINER = '{{cookiecutter.add_maintainer}}' def createGithubRepo(): subprocess.call(["git", "init", "-b", "main"]) @@ -30,8 +31,52 @@ def addTopic(): ] subprocess.call(gh_cli_command) +def addMaintainer(): + maintainers = [] + add_maintainer = True + while add_maintainer: + maintainer = {} + maintainer["role"] = input("Maintainer's Role (Reviewer, Approver, Maintainer): ").strip() + maintainer["name"] = input("Maintainer's Name: ").strip() + maintainer["github_username"] = input("Maintainer's GitHub Username: ").strip() + maintainer["affiliation"] = input("Maintainer's Affiliation (DSAC, CCSQ, CMMI, etc...): ").strip() + maintainers.append(maintainer) + + while True: + add_maintainer_input = input("Would you like to add another maintainer? (yes/no): ").strip().lower() + if add_maintainer_input in ("yes", "y", "no", "n"): + # If input is "yes" or "y", then add_maintainer is True and main loop continues, vise versa + add_maintainer = add_maintainer_input in ("yes", "y") + break + else: + print("\nInvalid response, please respond with: 'yes', 'y', 'no', or 'n'") + + maintainers_table = "" + for maintainer in maintainers: + maintainers_table += f"| {maintainer["role"]} | {maintainer["name"]}| {maintainer["github_username"]} | {maintainer["affiliation"]} |\n" + + proj_name = "{{ cookiecutter.project_name }}" + maintainers_file_path = f"../{proj_name}/MAINTAINERS.md" + + with open(maintainers_file_path, "r") as f: + lines = f.readlines() + + with open(maintainers_file_path, "w") as f: + in_table = False + for line in lines: + if "| {role} | {names} | {github usernames} | {affiliations}|" in line: + in_table = True + f.write(maintainers_table) # Replace placeholder line with new table of maintainers + elif in_table and line.strip() == "": + in_table = False + if not in_table: + f.write(line) + if CREATE_REPO == "True": createGithubRepo() if RECEIVE_UPDATES == "True": addTopic() + +if ADD_MAINTAINER == "True": + addMaintainer() \ No newline at end of file diff --git a/tier2/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml b/tier2/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml index 5e889b7..17ef91a 100644 --- a/tier2/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml +++ b/tier2/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml @@ -16,7 +16,9 @@ jobs: - name: Contribute List uses: akhilmhdh/contributors-readme-action@v2.3.10 env: + {% raw %} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + {% endraw %} with: # https://github.com/marketplace/actions/contribute-list#optional-parameters readme_path: MAINTAINERS.md @@ -41,14 +43,18 @@ jobs: OWNER=$(echo $GITHUB_REPOSITORY | cut -d'/' -f1) REPO=$(echo $GITHUB_REPOSITORY | cut -d'/' -f2) QUERY='query { repository(owner: \"'"$OWNER"'\", name: \"'"$REPO"'\") { collaborators { totalCount } } }' + {% raw %} CONTRIBUTORS=$(curl -s -X POST -H "Authorization: bearer ${{ secrets.GITHUB_TOKEN }}" -H "Content-Type: application/json" -d "{\"query\": \"$QUERY\"}" https://api.github.com/graphql | jq -r '.data.repository.collaborators.totalCount') + {% endraw %} echo "Total contributors: $CONTRIBUTORS" echo "contributors=$CONTRIBUTORS" >> $GITHUB_OUTPUT - name: Replace slug in MAINTAINERS.md with number of contributors # https://stackoverflow.com/questions/10613643/replace-a-unknown-string-between-two-known-strings-with-sed run: | + {% raw %} CONTRIBUTORS=${{ steps.get_contributors.outputs.contributors }} + {% endraw %} sed -i 's/.*/ '"$CONTRIBUTORS"' /g' MAINTAINERS.md - name: Commit and push changes From 8c99bb8ac0d4e25b568e4f20afbc5a393ee5eb6f Mon Sep 17 00:00:00 2001 From: Joe Gasiorek Date: Sun, 30 Jun 2024 11:52:28 -0700 Subject: [PATCH 13/24] Fix Jinja template problem with secrets in Github actions --- .../.github/workflows/contributors.yml | 6 ++++++ .../.github/workflows/contributors.yml | 6 ++++++ .../.github/workflows/contributors.yml | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/tier2/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml b/tier2/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml index 5e889b7..3ab38c5 100644 --- a/tier2/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml +++ b/tier2/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml @@ -16,7 +16,9 @@ jobs: - name: Contribute List uses: akhilmhdh/contributors-readme-action@v2.3.10 env: + {% raw %} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + {% endraw %} with: # https://github.com/marketplace/actions/contribute-list#optional-parameters readme_path: MAINTAINERS.md @@ -38,18 +40,22 @@ jobs: # https://docs.github.com/en/graphql/guides/forming-calls-with-graphql#communicating-with-graphql # CANNOT have newlines! run: | + {% raw %} OWNER=$(echo $GITHUB_REPOSITORY | cut -d'/' -f1) REPO=$(echo $GITHUB_REPOSITORY | cut -d'/' -f2) QUERY='query { repository(owner: \"'"$OWNER"'\", name: \"'"$REPO"'\") { collaborators { totalCount } } }' CONTRIBUTORS=$(curl -s -X POST -H "Authorization: bearer ${{ secrets.GITHUB_TOKEN }}" -H "Content-Type: application/json" -d "{\"query\": \"$QUERY\"}" https://api.github.com/graphql | jq -r '.data.repository.collaborators.totalCount') echo "Total contributors: $CONTRIBUTORS" echo "contributors=$CONTRIBUTORS" >> $GITHUB_OUTPUT + {% endraw %} - name: Replace slug in MAINTAINERS.md with number of contributors # https://stackoverflow.com/questions/10613643/replace-a-unknown-string-between-two-known-strings-with-sed run: | + {% raw %} CONTRIBUTORS=${{ steps.get_contributors.outputs.contributors }} sed -i 's/.*/ '"$CONTRIBUTORS"' /g' MAINTAINERS.md + {% endraw %} - name: Commit and push changes # https://github.com/orgs/community/discussions/26560#discussioncomment-3531273 diff --git a/tier3/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml b/tier3/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml index 5e889b7..3ab38c5 100644 --- a/tier3/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml +++ b/tier3/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml @@ -16,7 +16,9 @@ jobs: - name: Contribute List uses: akhilmhdh/contributors-readme-action@v2.3.10 env: + {% raw %} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + {% endraw %} with: # https://github.com/marketplace/actions/contribute-list#optional-parameters readme_path: MAINTAINERS.md @@ -38,18 +40,22 @@ jobs: # https://docs.github.com/en/graphql/guides/forming-calls-with-graphql#communicating-with-graphql # CANNOT have newlines! run: | + {% raw %} OWNER=$(echo $GITHUB_REPOSITORY | cut -d'/' -f1) REPO=$(echo $GITHUB_REPOSITORY | cut -d'/' -f2) QUERY='query { repository(owner: \"'"$OWNER"'\", name: \"'"$REPO"'\") { collaborators { totalCount } } }' CONTRIBUTORS=$(curl -s -X POST -H "Authorization: bearer ${{ secrets.GITHUB_TOKEN }}" -H "Content-Type: application/json" -d "{\"query\": \"$QUERY\"}" https://api.github.com/graphql | jq -r '.data.repository.collaborators.totalCount') echo "Total contributors: $CONTRIBUTORS" echo "contributors=$CONTRIBUTORS" >> $GITHUB_OUTPUT + {% endraw %} - name: Replace slug in MAINTAINERS.md with number of contributors # https://stackoverflow.com/questions/10613643/replace-a-unknown-string-between-two-known-strings-with-sed run: | + {% raw %} CONTRIBUTORS=${{ steps.get_contributors.outputs.contributors }} sed -i 's/.*/ '"$CONTRIBUTORS"' /g' MAINTAINERS.md + {% endraw %} - name: Commit and push changes # https://github.com/orgs/community/discussions/26560#discussioncomment-3531273 diff --git a/tier4/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml b/tier4/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml index 5e889b7..3ab38c5 100644 --- a/tier4/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml +++ b/tier4/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml @@ -16,7 +16,9 @@ jobs: - name: Contribute List uses: akhilmhdh/contributors-readme-action@v2.3.10 env: + {% raw %} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + {% endraw %} with: # https://github.com/marketplace/actions/contribute-list#optional-parameters readme_path: MAINTAINERS.md @@ -38,18 +40,22 @@ jobs: # https://docs.github.com/en/graphql/guides/forming-calls-with-graphql#communicating-with-graphql # CANNOT have newlines! run: | + {% raw %} OWNER=$(echo $GITHUB_REPOSITORY | cut -d'/' -f1) REPO=$(echo $GITHUB_REPOSITORY | cut -d'/' -f2) QUERY='query { repository(owner: \"'"$OWNER"'\", name: \"'"$REPO"'\") { collaborators { totalCount } } }' CONTRIBUTORS=$(curl -s -X POST -H "Authorization: bearer ${{ secrets.GITHUB_TOKEN }}" -H "Content-Type: application/json" -d "{\"query\": \"$QUERY\"}" https://api.github.com/graphql | jq -r '.data.repository.collaborators.totalCount') echo "Total contributors: $CONTRIBUTORS" echo "contributors=$CONTRIBUTORS" >> $GITHUB_OUTPUT + {% endraw %} - name: Replace slug in MAINTAINERS.md with number of contributors # https://stackoverflow.com/questions/10613643/replace-a-unknown-string-between-two-known-strings-with-sed run: | + {% raw %} CONTRIBUTORS=${{ steps.get_contributors.outputs.contributors }} sed -i 's/.*/ '"$CONTRIBUTORS"' /g' MAINTAINERS.md + {% endraw %} - name: Commit and push changes # https://github.com/orgs/community/discussions/26560#discussioncomment-3531273 From 1483e42d39e8d206bd4f6b3512944c12dd59937b Mon Sep 17 00:00:00 2001 From: Ricardo Zamora Date: Mon, 1 Jul 2024 10:08:03 -0700 Subject: [PATCH 14/24] added repometrics to tier4 --- tier4/cookiecutter.json | 3 +- .../repometrics/cookiecutter.json | 18 ++++++++++ .../repometrics/hooks/post_gen_project.sh | 33 +++++++++++++++++++ .../{{cookiecutter.project_type}}/code.json | 10 ++++++ 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 tier4/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json create mode 100644 tier4/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.sh create mode 100644 tier4/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/code.json diff --git a/tier4/cookiecutter.json b/tier4/cookiecutter.json index b159a65..49e483d 100644 --- a/tier4/cookiecutter.json +++ b/tier4/cookiecutter.json @@ -11,5 +11,6 @@ "__prompts__": { "create_repo": "Would you like to create a repo on github.com?", "receive_updates": "Would you like to receive updates from the DSACMS team via pull requests?" - } + }, + "_copy_without_render": ["repometrics"] } diff --git a/tier4/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json b/tier4/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json new file mode 100644 index 0000000..162b0a8 --- /dev/null +++ b/tier4/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json @@ -0,0 +1,18 @@ +{ + "project_type" : ["Package", "Website", "Standards", "Libraries", "Data", "Apps", "Tools", "APIs"], + "user_input": ["Yes", "No"], + "project_fisma_level": ["Low", "Moderate", "High"], + "group": "CMS/OA/DSAC", + "subset_in_healthcare": "Policy, Operational", + "user_type": "Providers, Patients, Government", + "repository_host": ["Github.com", "GitHub ENT", "GitHub Cloud", "GitLab.com", "GitLab ENT", "GitLab ENT CCSQ"], + "maturity_model_tier": ["1", "2", "3", "4"], + "__prompts__": { + "group": "Which group is the project part of?", + "subset_in_healthcare": "Which subset of healthcare does the project belong to?", + "user_type": "Who are the intended users?", + "user_input": "Does the project accept user input? (e.g. allows user to query a database, allows login by users, etc.)", + "repository_host": "Where is the repository hosted?", + "maturity_model_tier": "What maturity model tier is your project classified as?" + } +} \ No newline at end of file diff --git a/tier4/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.sh b/tier4/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.sh new file mode 100644 index 0000000..7946bf2 --- /dev/null +++ b/tier4/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Change to the parent directory +cd .. + +# Define the repometrics directory to remove +dir_name="repometrics" + +# Check if repometrics directory exists and remove it +if [ -d "$dir_name" ]; then + rm -rf "$dir_name" +fi + +project_type="{{cookiecutter.project_type}}" +sub_project_dir="${project_type}" +repometrics_file="code.json" +parent_dir="./" + +if [ -f "${sub_project_dir}/${repometrics_file}" ]; then + # Move code.json file to parent directory + mv "${sub_project_dir}/${repometrics_file}" "${parent_dir}" + + # Check if the move was successful + if [ $? -eq 0 ]; then + # Remove the source directory + rm -rf "${sub_project_dir}" + + # Check if the deletion was successful + if [ $? -eq 0 ]; then + echo "Successfully generated code.json file." + fi + fi +fi \ No newline at end of file diff --git a/tier4/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/code.json b/tier4/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/code.json new file mode 100644 index 0000000..0841645 --- /dev/null +++ b/tier4/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/code.json @@ -0,0 +1,10 @@ +{ + "project_type": "{{ cookiecutter.project_type }}", + "user_input": "{{ cookiecutter.user_input }}", + "project_fisma_level": "{{ cookiecutter.project_fisma_level }}", + "group": "{{ cookiecutter.group }}", + "subset_in_healthcare": "{{ cookiecutter.subset_in_healthcare }}", + "user_type": "{{ cookiecutter.user_type }}", + "repository_host": "{{ cookiecutter.repository_host }}", + "maturity_model_tier": "{{ cookiecutter.maturity_model_tier }}" +} \ No newline at end of file From a2515bbef91801f57cc62716d609e21198e7826f Mon Sep 17 00:00:00 2001 From: CreativeNick Date: Mon, 1 Jul 2024 15:15:54 -0700 Subject: [PATCH 15/24] Added MAINTAINERS.md functionality and slugification for all tiers --- tier2/cookiecutter.json | 30 +++---- tier3/cookiecutter.json | 26 +++--- tier3/hooks/post_gen_project.py | 86 +++++++++++++++++++ .../.github/workflows/contributors.yml | 6 ++ tier4/cookiecutter.json | 28 +++--- tier4/hooks/post_gen_project.py | 86 +++++++++++++++++++ .../.github/workflows/contributors.yml | 6 ++ 7 files changed, 228 insertions(+), 40 deletions(-) create mode 100644 tier3/hooks/post_gen_project.py create mode 100644 tier4/hooks/post_gen_project.py diff --git a/tier2/cookiecutter.json b/tier2/cookiecutter.json index bbce4c8..6e39c4a 100644 --- a/tier2/cookiecutter.json +++ b/tier2/cookiecutter.json @@ -1,17 +1,17 @@ { - "project_name": "My Project", - "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '_') }}", - "project_org": "DSACMS", - "project_repo_name": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}", - "project_description": "This is the project description, could match github.com repo description.", - "code_owners": "Git usernames of code owners; separated by commas.", - "project_visibility": ["public", "internal", "private"], - "create_repo": [true, false], - "receive_updates": [true, false], - "add_maintainer": [true, false], - "__prompts__": { - "create_repo": "Would you like to create a repo on github.com?", - "receive_updates": "Would you like to receive updates from the DSACMS team via pull requests?", - "add_maintainer": "Would you like to add a maintainer?" - } + "project_name": "My Project", + "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '_') }}", + "project_org": "DSACMS", + "project_repo_name": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}", + "project_description": "This is the project description, could match github.com repo description.", + "code_owners": "Git usernames of code owners; separated by commas.", + "project_visibility": ["public", "internal", "private"], + "create_repo": [true, false], + "receive_updates": [true, false], + "add_maintainer": [true, false], + "__prompts__": { + "create_repo": "Would you like to create a repo on github.com?", + "receive_updates": "Would you like to receive updates from the DSACMS team via pull requests?", + "add_maintainer": "Would you like to add a maintainer?" + } } diff --git a/tier3/cookiecutter.json b/tier3/cookiecutter.json index b159a65..ff91b24 100644 --- a/tier3/cookiecutter.json +++ b/tier3/cookiecutter.json @@ -1,15 +1,17 @@ { - "project_name": "My Project", - "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '_') }}", - "project_org": "DSACMS", - "project_repo_name": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}", - "project_description": "This is the project description, could match github.com repo description.", - "code_owners": "Git usernames of code owners; separated by commas.", - "project_visibility": ["public", "internal", "private"], - "create_repo": [true, false], - "receive_updates": [true, false], - "__prompts__": { - "create_repo": "Would you like to create a repo on github.com?", - "receive_updates": "Would you like to receive updates from the DSACMS team via pull requests?" + "project_name": "My Project", + "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '_') }}", + "project_org": "DSACMS", + "project_repo_name": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}", + "project_description": "This is the project description, could match github.com repo description.", + "code_owners": "Git usernames of code owners; separated by commas.", + "project_visibility": ["public", "internal", "private"], + "create_repo": [true, false], + "receive_updates": [true, false], + "add_maintainer": [true, false], + "__prompts__": { + "create_repo": "Would you like to create a repo on github.com?", + "receive_updates": "Would you like to receive updates from the DSACMS team via pull requests?", + "add_maintainer": "Would you like to add maintainers, approvers, and/or reviewers?" } } diff --git a/tier3/hooks/post_gen_project.py b/tier3/hooks/post_gen_project.py new file mode 100644 index 0000000..dc172b9 --- /dev/null +++ b/tier3/hooks/post_gen_project.py @@ -0,0 +1,86 @@ +import subprocess + +REPO_NAME = '{{ cookiecutter.project_repo_name }}' +ORG_NAME = '{{ cookiecutter.project_org }}' +VISIBILITY = '{{cookiecutter.project_visibility}}' +DESCRIPTION = '{{cookiecutter.project_description}}' +CREATE_REPO = '{{cookiecutter.create_repo}}' +RECEIVE_UPDATES = '{{cookiecutter.receive_updates}}' +ADD_MAINTAINER = '{{cookiecutter.add_maintainer}}' + +def createGithubRepo(): + subprocess.call(["git", "init", "-b", "main"]) + subprocess.call(["git", "add", "."]) + subprocess.call(["git", "commit", "-m", "first commit"]) + gh_cli_command = [ + "gh", "repo", "create", + f"{ORG_NAME}/{REPO_NAME}", + "--source=.", + f"--{VISIBILITY}", + "--push", + f"--description={DESCRIPTION}", + ] + subprocess.call(gh_cli_command) + subprocess.call(["git", "push", "--set-upstream", "origin", "main"]) + +def addTopic(): + gh_cli_command = [ + "gh", "repo", "edit", + f"{ORG_NAME}/{REPO_NAME}", + "--add-topic=dsacms-tier0", + ] + subprocess.call(gh_cli_command) + +# Helper function for addMaintainer() to get user input of usernames for Maintainer, Approver, and Reviewer +def get_usernames(role): + while True: + usernames = input(f"Enter the GitHub usernames of {role} (comma-separated): ").strip() + if usernames: + return [username.strip() for username in usernames.split(',')] + print("Please enter at least one username.") + +# Helper function for addMaintainer() to format list of usernames +def format_usernames(usernames): + return "".join(f"- @{username}\n" for username in usernames) + +def addMaintainer(): + maintainers = get_usernames("MAINTAINERS") + approvers = get_usernames("APPROVERS") + reviewers = get_usernames("REVIEWERS") + + maintainers_file_path = "MAINTAINERS.md" + + with open(maintainers_file_path, "r") as f: + lines = f.readlines() + + in_maintainers, in_approvers, in_reviewers = False, False, False + for i, line in enumerate(lines): + if line.strip() == "## Maintainers:": + in_maintainers = True + elif line.strip() == "## Approvers:": + in_approvers = True + elif line.strip() == "## Reviewers:": + in_reviewers = True + elif in_maintainers and line.strip() == "-": + lines[i] = format_usernames(maintainers) + in_maintainers = False + elif in_approvers and line.strip() == "-": + lines[i] = format_usernames(approvers) + in_approvers = False + elif in_reviewers and line.strip() == "-": + lines[i] = format_usernames(reviewers) + in_reviewers = False + + with open(maintainers_file_path, "w") as f: + f.writelines(lines) + + print("Maintainers, Approvers, and Reviewers have been added to MAINTAINERS.md") + +if CREATE_REPO == "True": + createGithubRepo() + +if RECEIVE_UPDATES == "True": + addTopic() + +if ADD_MAINTAINER == "True": + addMaintainer() diff --git a/tier3/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml b/tier3/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml index 5e889b7..3bd9c9b 100644 --- a/tier3/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml +++ b/tier3/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml @@ -16,7 +16,9 @@ jobs: - name: Contribute List uses: akhilmhdh/contributors-readme-action@v2.3.10 env: + {% raw %} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + {% endraw %} with: # https://github.com/marketplace/actions/contribute-list#optional-parameters readme_path: MAINTAINERS.md @@ -41,14 +43,18 @@ jobs: OWNER=$(echo $GITHUB_REPOSITORY | cut -d'/' -f1) REPO=$(echo $GITHUB_REPOSITORY | cut -d'/' -f2) QUERY='query { repository(owner: \"'"$OWNER"'\", name: \"'"$REPO"'\") { collaborators { totalCount } } }' + {% raw %} CONTRIBUTORS=$(curl -s -X POST -H "Authorization: bearer ${{ secrets.GITHUB_TOKEN }}" -H "Content-Type: application/json" -d "{\"query\": \"$QUERY\"}" https://api.github.com/graphql | jq -r '.data.repository.collaborators.totalCount') + {% end raw %} echo "Total contributors: $CONTRIBUTORS" echo "contributors=$CONTRIBUTORS" >> $GITHUB_OUTPUT - name: Replace slug in MAINTAINERS.md with number of contributors # https://stackoverflow.com/questions/10613643/replace-a-unknown-string-between-two-known-strings-with-sed run: | + {% raw %} CONTRIBUTORS=${{ steps.get_contributors.outputs.contributors }} + {% endraw %} sed -i 's/.*/ '"$CONTRIBUTORS"' /g' MAINTAINERS.md - name: Commit and push changes diff --git a/tier4/cookiecutter.json b/tier4/cookiecutter.json index b159a65..373faac 100644 --- a/tier4/cookiecutter.json +++ b/tier4/cookiecutter.json @@ -1,15 +1,17 @@ { - "project_name": "My Project", - "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '_') }}", - "project_org": "DSACMS", - "project_repo_name": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}", - "project_description": "This is the project description, could match github.com repo description.", - "code_owners": "Git usernames of code owners; separated by commas.", - "project_visibility": ["public", "internal", "private"], - "create_repo": [true, false], - "receive_updates": [true, false], - "__prompts__": { - "create_repo": "Would you like to create a repo on github.com?", - "receive_updates": "Would you like to receive updates from the DSACMS team via pull requests?" - } + "project_name": "My Project", + "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '_') }}", + "project_org": "DSACMS", + "project_repo_name": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}", + "project_description": "This is the project description, could match github.com repo description.", + "code_owners": "Git usernames of code owners; separated by commas.", + "project_visibility": ["public", "internal", "private"], + "create_repo": [true, false], + "receive_updates": [true, false], + "add_maintainer": [true, false], + "__prompts__": { + "create_repo": "Would you like to create a repo on github.com?", + "receive_updates": "Would you like to receive updates from the DSACMS team via pull requests?", + "add_maintainer": "Would you like to add maintainers, approvers, and/or reviewers?" + } } diff --git a/tier4/hooks/post_gen_project.py b/tier4/hooks/post_gen_project.py new file mode 100644 index 0000000..dc172b9 --- /dev/null +++ b/tier4/hooks/post_gen_project.py @@ -0,0 +1,86 @@ +import subprocess + +REPO_NAME = '{{ cookiecutter.project_repo_name }}' +ORG_NAME = '{{ cookiecutter.project_org }}' +VISIBILITY = '{{cookiecutter.project_visibility}}' +DESCRIPTION = '{{cookiecutter.project_description}}' +CREATE_REPO = '{{cookiecutter.create_repo}}' +RECEIVE_UPDATES = '{{cookiecutter.receive_updates}}' +ADD_MAINTAINER = '{{cookiecutter.add_maintainer}}' + +def createGithubRepo(): + subprocess.call(["git", "init", "-b", "main"]) + subprocess.call(["git", "add", "."]) + subprocess.call(["git", "commit", "-m", "first commit"]) + gh_cli_command = [ + "gh", "repo", "create", + f"{ORG_NAME}/{REPO_NAME}", + "--source=.", + f"--{VISIBILITY}", + "--push", + f"--description={DESCRIPTION}", + ] + subprocess.call(gh_cli_command) + subprocess.call(["git", "push", "--set-upstream", "origin", "main"]) + +def addTopic(): + gh_cli_command = [ + "gh", "repo", "edit", + f"{ORG_NAME}/{REPO_NAME}", + "--add-topic=dsacms-tier0", + ] + subprocess.call(gh_cli_command) + +# Helper function for addMaintainer() to get user input of usernames for Maintainer, Approver, and Reviewer +def get_usernames(role): + while True: + usernames = input(f"Enter the GitHub usernames of {role} (comma-separated): ").strip() + if usernames: + return [username.strip() for username in usernames.split(',')] + print("Please enter at least one username.") + +# Helper function for addMaintainer() to format list of usernames +def format_usernames(usernames): + return "".join(f"- @{username}\n" for username in usernames) + +def addMaintainer(): + maintainers = get_usernames("MAINTAINERS") + approvers = get_usernames("APPROVERS") + reviewers = get_usernames("REVIEWERS") + + maintainers_file_path = "MAINTAINERS.md" + + with open(maintainers_file_path, "r") as f: + lines = f.readlines() + + in_maintainers, in_approvers, in_reviewers = False, False, False + for i, line in enumerate(lines): + if line.strip() == "## Maintainers:": + in_maintainers = True + elif line.strip() == "## Approvers:": + in_approvers = True + elif line.strip() == "## Reviewers:": + in_reviewers = True + elif in_maintainers and line.strip() == "-": + lines[i] = format_usernames(maintainers) + in_maintainers = False + elif in_approvers and line.strip() == "-": + lines[i] = format_usernames(approvers) + in_approvers = False + elif in_reviewers and line.strip() == "-": + lines[i] = format_usernames(reviewers) + in_reviewers = False + + with open(maintainers_file_path, "w") as f: + f.writelines(lines) + + print("Maintainers, Approvers, and Reviewers have been added to MAINTAINERS.md") + +if CREATE_REPO == "True": + createGithubRepo() + +if RECEIVE_UPDATES == "True": + addTopic() + +if ADD_MAINTAINER == "True": + addMaintainer() diff --git a/tier4/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml b/tier4/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml index 5e889b7..17ef91a 100644 --- a/tier4/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml +++ b/tier4/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml @@ -16,7 +16,9 @@ jobs: - name: Contribute List uses: akhilmhdh/contributors-readme-action@v2.3.10 env: + {% raw %} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + {% endraw %} with: # https://github.com/marketplace/actions/contribute-list#optional-parameters readme_path: MAINTAINERS.md @@ -41,14 +43,18 @@ jobs: OWNER=$(echo $GITHUB_REPOSITORY | cut -d'/' -f1) REPO=$(echo $GITHUB_REPOSITORY | cut -d'/' -f2) QUERY='query { repository(owner: \"'"$OWNER"'\", name: \"'"$REPO"'\") { collaborators { totalCount } } }' + {% raw %} CONTRIBUTORS=$(curl -s -X POST -H "Authorization: bearer ${{ secrets.GITHUB_TOKEN }}" -H "Content-Type: application/json" -d "{\"query\": \"$QUERY\"}" https://api.github.com/graphql | jq -r '.data.repository.collaborators.totalCount') + {% endraw %} echo "Total contributors: $CONTRIBUTORS" echo "contributors=$CONTRIBUTORS" >> $GITHUB_OUTPUT - name: Replace slug in MAINTAINERS.md with number of contributors # https://stackoverflow.com/questions/10613643/replace-a-unknown-string-between-two-known-strings-with-sed run: | + {% raw %} CONTRIBUTORS=${{ steps.get_contributors.outputs.contributors }} + {% endraw %} sed -i 's/.*/ '"$CONTRIBUTORS"' /g' MAINTAINERS.md - name: Commit and push changes From c374e0eba101d45d9b58bde81d33da2bdad4b8ea Mon Sep 17 00:00:00 2001 From: Ricardo Zamora Date: Mon, 1 Jul 2024 15:55:38 -0700 Subject: [PATCH 16/24] add repometrics to tier 1 --- tier1/cookiecutter.json | 3 +- .../repometrics/cookiecutter.json | 18 ++++++++++ .../repometrics/hooks/post_gen_project.sh | 33 +++++++++++++++++++ .../{{cookiecutter.project_type}}/code.json | 10 ++++++ 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 tier1/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json create mode 100644 tier1/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.sh create mode 100644 tier1/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/code.json diff --git a/tier1/cookiecutter.json b/tier1/cookiecutter.json index d392afd..872e19c 100644 --- a/tier1/cookiecutter.json +++ b/tier1/cookiecutter.json @@ -10,5 +10,6 @@ "__prompts__": { "create_repo": "Would you like to create a repo on github.com?", "receive_updates": "Would you like to receive updates from the DSACMS team via pull requests?" - } + }, + "_copy_without_render": ["repometrics"] } diff --git a/tier1/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json b/tier1/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json new file mode 100644 index 0000000..162b0a8 --- /dev/null +++ b/tier1/{{cookiecutter.project_slug}}/repometrics/cookiecutter.json @@ -0,0 +1,18 @@ +{ + "project_type" : ["Package", "Website", "Standards", "Libraries", "Data", "Apps", "Tools", "APIs"], + "user_input": ["Yes", "No"], + "project_fisma_level": ["Low", "Moderate", "High"], + "group": "CMS/OA/DSAC", + "subset_in_healthcare": "Policy, Operational", + "user_type": "Providers, Patients, Government", + "repository_host": ["Github.com", "GitHub ENT", "GitHub Cloud", "GitLab.com", "GitLab ENT", "GitLab ENT CCSQ"], + "maturity_model_tier": ["1", "2", "3", "4"], + "__prompts__": { + "group": "Which group is the project part of?", + "subset_in_healthcare": "Which subset of healthcare does the project belong to?", + "user_type": "Who are the intended users?", + "user_input": "Does the project accept user input? (e.g. allows user to query a database, allows login by users, etc.)", + "repository_host": "Where is the repository hosted?", + "maturity_model_tier": "What maturity model tier is your project classified as?" + } +} \ No newline at end of file diff --git a/tier1/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.sh b/tier1/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.sh new file mode 100644 index 0000000..7946bf2 --- /dev/null +++ b/tier1/{{cookiecutter.project_slug}}/repometrics/hooks/post_gen_project.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Change to the parent directory +cd .. + +# Define the repometrics directory to remove +dir_name="repometrics" + +# Check if repometrics directory exists and remove it +if [ -d "$dir_name" ]; then + rm -rf "$dir_name" +fi + +project_type="{{cookiecutter.project_type}}" +sub_project_dir="${project_type}" +repometrics_file="code.json" +parent_dir="./" + +if [ -f "${sub_project_dir}/${repometrics_file}" ]; then + # Move code.json file to parent directory + mv "${sub_project_dir}/${repometrics_file}" "${parent_dir}" + + # Check if the move was successful + if [ $? -eq 0 ]; then + # Remove the source directory + rm -rf "${sub_project_dir}" + + # Check if the deletion was successful + if [ $? -eq 0 ]; then + echo "Successfully generated code.json file." + fi + fi +fi \ No newline at end of file diff --git a/tier1/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/code.json b/tier1/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/code.json new file mode 100644 index 0000000..0841645 --- /dev/null +++ b/tier1/{{cookiecutter.project_slug}}/repometrics/{{cookiecutter.project_type}}/code.json @@ -0,0 +1,10 @@ +{ + "project_type": "{{ cookiecutter.project_type }}", + "user_input": "{{ cookiecutter.user_input }}", + "project_fisma_level": "{{ cookiecutter.project_fisma_level }}", + "group": "{{ cookiecutter.group }}", + "subset_in_healthcare": "{{ cookiecutter.subset_in_healthcare }}", + "user_type": "{{ cookiecutter.user_type }}", + "repository_host": "{{ cookiecutter.repository_host }}", + "maturity_model_tier": "{{ cookiecutter.maturity_model_tier }}" +} \ No newline at end of file From d1cc615f4e57e2c262a6d4fb596402d9c136d7e1 Mon Sep 17 00:00:00 2001 From: CreativeNick Date: Tue, 2 Jul 2024 12:25:38 -0700 Subject: [PATCH 17/24] PR changes/fixes --- tier2/hooks/post_gen_project.py | 20 +++++++++----------- tier3/hooks/post_gen_project.py | 25 ++++++++----------------- tier4/hooks/post_gen_project.py | 2 +- 3 files changed, 18 insertions(+), 29 deletions(-) diff --git a/tier2/hooks/post_gen_project.py b/tier2/hooks/post_gen_project.py index 67bcf30..3d9dcbe 100644 --- a/tier2/hooks/post_gen_project.py +++ b/tier2/hooks/post_gen_project.py @@ -27,7 +27,7 @@ def addTopic(): gh_cli_command = [ "gh", "repo", "edit", f"{ORG_NAME}/{REPO_NAME}", - "--add-topic=dsacms-tier0", + "--add-topic=dsacms-tier2", ] subprocess.call(gh_cli_command) @@ -43,13 +43,15 @@ def addMaintainer(): maintainers.append(maintainer) while True: - add_maintainer_input = input("Would you like to add another maintainer? (yes/no): ").strip().lower() - if add_maintainer_input in ("yes", "y", "no", "n"): - # If input is "yes" or "y", then add_maintainer is True and main loop continues, vise versa - add_maintainer = add_maintainer_input in ("yes", "y") + add_maintainer_input = input("Would you like to add another maintainer? [Y/n]: ").strip().lower() + if add_maintainer_input in ("y", ""): # Empty string for just pressing Enter + add_maintainer = True + break + elif add_maintainer_input == "n": + add_maintainer = False break else: - print("\nInvalid response, please respond with: 'yes', 'y', 'no', or 'n'") + print("\nInvalid response, please respond with: 'y', 'n', or just press Enter for yes") maintainers_table = "" for maintainer in maintainers: @@ -62,14 +64,10 @@ def addMaintainer(): lines = f.readlines() with open(maintainers_file_path, "w") as f: - in_table = False for line in lines: if "| {role} | {names} | {github usernames} | {affiliations}|" in line: - in_table = True f.write(maintainers_table) # Replace placeholder line with new table of maintainers - elif in_table and line.strip() == "": - in_table = False - if not in_table: + else: f.write(line) if CREATE_REPO == "True": diff --git a/tier3/hooks/post_gen_project.py b/tier3/hooks/post_gen_project.py index dc172b9..0265e18 100644 --- a/tier3/hooks/post_gen_project.py +++ b/tier3/hooks/post_gen_project.py @@ -27,7 +27,7 @@ def addTopic(): gh_cli_command = [ "gh", "repo", "edit", f"{ORG_NAME}/{REPO_NAME}", - "--add-topic=dsacms-tier0", + "--add-topic=dsacms-tier3", ] subprocess.call(gh_cli_command) @@ -53,23 +53,14 @@ def addMaintainer(): with open(maintainers_file_path, "r") as f: lines = f.readlines() - in_maintainers, in_approvers, in_reviewers = False, False, False for i, line in enumerate(lines): - if line.strip() == "## Maintainers:": - in_maintainers = True - elif line.strip() == "## Approvers:": - in_approvers = True - elif line.strip() == "## Reviewers:": - in_reviewers = True - elif in_maintainers and line.strip() == "-": - lines[i] = format_usernames(maintainers) - in_maintainers = False - elif in_approvers and line.strip() == "-": - lines[i] = format_usernames(approvers) - in_approvers = False - elif in_reviewers and line.strip() == "-": - lines[i] = format_usernames(reviewers) - in_reviewers = False + if i + 1 < len(lines): + if line.strip() == "## Maintainers:" and lines[i+1].strip() == "-": + lines[i+1] = format_usernames(maintainers) + elif line.strip() == "## Approvers:" and lines[i+1].strip() == "-": + lines[i+1] = format_usernames(approvers) + elif line.strip() == "## Reviewers:" and lines[i+1].strip() == "-": + lines[i+1] = format_usernames(reviewers) with open(maintainers_file_path, "w") as f: f.writelines(lines) diff --git a/tier4/hooks/post_gen_project.py b/tier4/hooks/post_gen_project.py index dc172b9..2610f12 100644 --- a/tier4/hooks/post_gen_project.py +++ b/tier4/hooks/post_gen_project.py @@ -27,7 +27,7 @@ def addTopic(): gh_cli_command = [ "gh", "repo", "edit", f"{ORG_NAME}/{REPO_NAME}", - "--add-topic=dsacms-tier0", + "--add-topic=dsacms-tier4", ] subprocess.call(gh_cli_command) From eeba74f78985993f820490c8f1dd947564e58520 Mon Sep 17 00:00:00 2001 From: CreativeNick Date: Tue, 2 Jul 2024 12:53:46 -0700 Subject: [PATCH 18/24] PR bug fixes --- tier3/hooks/post_gen_project.py | 35 +++++++++++++++++++++------------ tier4/hooks/post_gen_project.py | 18 ++++++++--------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/tier3/hooks/post_gen_project.py b/tier3/hooks/post_gen_project.py index 0265e18..4f50201 100644 --- a/tier3/hooks/post_gen_project.py +++ b/tier3/hooks/post_gen_project.py @@ -32,7 +32,7 @@ def addTopic(): subprocess.call(gh_cli_command) # Helper function for addMaintainer() to get user input of usernames for Maintainer, Approver, and Reviewer -def get_usernames(role): +def getUsernames(role): while True: usernames = input(f"Enter the GitHub usernames of {role} (comma-separated): ").strip() if usernames: @@ -40,27 +40,36 @@ def get_usernames(role): print("Please enter at least one username.") # Helper function for addMaintainer() to format list of usernames -def format_usernames(usernames): - return "".join(f"- @{username}\n" for username in usernames) +def formatUsernames(usernames): + return "".join(f"- @{username.lstrip('@')}\n" for username in usernames) def addMaintainer(): - maintainers = get_usernames("MAINTAINERS") - approvers = get_usernames("APPROVERS") - reviewers = get_usernames("REVIEWERS") + maintainers = getUsernames("MAINTAINERS") + approvers = getUsernames("APPROVERS") + reviewers = getUsernames("REVIEWERS") maintainers_file_path = "MAINTAINERS.md" with open(maintainers_file_path, "r") as f: lines = f.readlines() + in_maintainers, in_approvers, in_reviewers = False, False, False for i, line in enumerate(lines): - if i + 1 < len(lines): - if line.strip() == "## Maintainers:" and lines[i+1].strip() == "-": - lines[i+1] = format_usernames(maintainers) - elif line.strip() == "## Approvers:" and lines[i+1].strip() == "-": - lines[i+1] = format_usernames(approvers) - elif line.strip() == "## Reviewers:" and lines[i+1].strip() == "-": - lines[i+1] = format_usernames(reviewers) + if line.strip() == "## Maintainers:": + in_maintainers = True + elif line.strip() == "## Approvers:": + in_approvers = True + elif line.strip() == "## Reviewers:": + in_reviewers = True + elif in_maintainers and line.strip() == "-": + lines[i] = formatUsernames(maintainers) + in_maintainers = False + elif in_approvers and line.strip() == "-": + lines[i] = formatUsernames(approvers) + in_approvers = False + elif in_reviewers and line.strip() == "-": + lines[i] = formatUsernames(reviewers) + in_reviewers = False with open(maintainers_file_path, "w") as f: f.writelines(lines) diff --git a/tier4/hooks/post_gen_project.py b/tier4/hooks/post_gen_project.py index 2610f12..778ad40 100644 --- a/tier4/hooks/post_gen_project.py +++ b/tier4/hooks/post_gen_project.py @@ -32,7 +32,7 @@ def addTopic(): subprocess.call(gh_cli_command) # Helper function for addMaintainer() to get user input of usernames for Maintainer, Approver, and Reviewer -def get_usernames(role): +def getUsernames(role): while True: usernames = input(f"Enter the GitHub usernames of {role} (comma-separated): ").strip() if usernames: @@ -40,13 +40,13 @@ def get_usernames(role): print("Please enter at least one username.") # Helper function for addMaintainer() to format list of usernames -def format_usernames(usernames): - return "".join(f"- @{username}\n" for username in usernames) +def formatUsernames(usernames): + return "".join(f"- @{username.lstrip('@')}\n" for username in usernames) def addMaintainer(): - maintainers = get_usernames("MAINTAINERS") - approvers = get_usernames("APPROVERS") - reviewers = get_usernames("REVIEWERS") + maintainers = getUsernames("MAINTAINERS") + approvers = getUsernames("APPROVERS") + reviewers = getUsernames("REVIEWERS") maintainers_file_path = "MAINTAINERS.md" @@ -62,13 +62,13 @@ def addMaintainer(): elif line.strip() == "## Reviewers:": in_reviewers = True elif in_maintainers and line.strip() == "-": - lines[i] = format_usernames(maintainers) + lines[i] = formatUsernames(maintainers) in_maintainers = False elif in_approvers and line.strip() == "-": - lines[i] = format_usernames(approvers) + lines[i] = formatUsernames(approvers) in_approvers = False elif in_reviewers and line.strip() == "-": - lines[i] = format_usernames(reviewers) + lines[i] = formatUsernames(reviewers) in_reviewers = False with open(maintainers_file_path, "w") as f: From 1a687a04dd625961b297ace16c840e52536d86b2 Mon Sep 17 00:00:00 2001 From: CreativeNick Date: Tue, 2 Jul 2024 14:23:02 -0700 Subject: [PATCH 19/24] Fix tier2 post_gen_project.py --- tier2/hooks/post_gen_project.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tier2/hooks/post_gen_project.py b/tier2/hooks/post_gen_project.py index 3d9dcbe..7f05844 100644 --- a/tier2/hooks/post_gen_project.py +++ b/tier2/hooks/post_gen_project.py @@ -37,21 +37,22 @@ def addMaintainer(): while add_maintainer: maintainer = {} maintainer["role"] = input("Maintainer's Role (Reviewer, Approver, Maintainer): ").strip() - maintainer["name"] = input("Maintainer's Name: ").strip() + github_username = input("Maintainer's GitHub Username: ").strip() + maintainer["github_username"] = github_username if github_username.startswith('@') else f'@{github_username}' maintainer["github_username"] = input("Maintainer's GitHub Username: ").strip() maintainer["affiliation"] = input("Maintainer's Affiliation (DSAC, CCSQ, CMMI, etc...): ").strip() maintainers.append(maintainer) while True: add_maintainer_input = input("Would you like to add another maintainer? [Y/n]: ").strip().lower() - if add_maintainer_input in ("y", ""): # Empty string for just pressing Enter + if add_maintainer_input in ("y", "yes", ""): # Empty string for just pressing Enter add_maintainer = True break - elif add_maintainer_input == "n": + elif add_maintainer_input in ("n", "no"): add_maintainer = False break else: - print("\nInvalid response, please respond with: 'y', 'n', or just press Enter for yes") + print("\nInvalid response, please respond with: 'y', 'yes', 'n', 'no', or just press Enter for yes") maintainers_table = "" for maintainer in maintainers: From ae5a2bd9cfbde710eed11d6c881bdf2c177cb3d3 Mon Sep 17 00:00:00 2001 From: CreativeNick Date: Wed, 3 Jul 2024 10:25:30 -0700 Subject: [PATCH 20/24] Update post_gen_project.py --- tier2/hooks/post_gen_project.py | 2 +- tier3/hooks/post_gen_project.py | 22 ++++++---------------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/tier2/hooks/post_gen_project.py b/tier2/hooks/post_gen_project.py index 7f05844..f64b35d 100644 --- a/tier2/hooks/post_gen_project.py +++ b/tier2/hooks/post_gen_project.py @@ -45,7 +45,7 @@ def addMaintainer(): while True: add_maintainer_input = input("Would you like to add another maintainer? [Y/n]: ").strip().lower() - if add_maintainer_input in ("y", "yes", ""): # Empty string for just pressing Enter + if add_maintainer_input in ("y", "yes", ""): add_maintainer = True break elif add_maintainer_input in ("n", "no"): diff --git a/tier3/hooks/post_gen_project.py b/tier3/hooks/post_gen_project.py index 4f50201..d0eb9ab 100644 --- a/tier3/hooks/post_gen_project.py +++ b/tier3/hooks/post_gen_project.py @@ -53,23 +53,13 @@ def addMaintainer(): with open(maintainers_file_path, "r") as f: lines = f.readlines() - in_maintainers, in_approvers, in_reviewers = False, False, False for i, line in enumerate(lines): - if line.strip() == "## Maintainers:": - in_maintainers = True - elif line.strip() == "## Approvers:": - in_approvers = True - elif line.strip() == "## Reviewers:": - in_reviewers = True - elif in_maintainers and line.strip() == "-": - lines[i] = formatUsernames(maintainers) - in_maintainers = False - elif in_approvers and line.strip() == "-": - lines[i] = formatUsernames(approvers) - in_approvers = False - elif in_reviewers and line.strip() == "-": - lines[i] = formatUsernames(reviewers) - in_reviewers = False + if line.strip() == "## Maintainers:" and i + 2 < len(lines) and lines[i + 2].strip() == "-": + lines[i + 2] = formatUsernames(maintainers) + elif line.strip() == "## Approvers:" and i + 1 < len(lines) and lines[i + 1].strip() == "-": + lines[i + 1] = formatUsernames(approvers) + elif line.strip() == "## Reviewers:" and i + 1 < len(lines) and lines[i + 1].strip() == "-": + lines[i + 1] = formatUsernames(reviewers) with open(maintainers_file_path, "w") as f: f.writelines(lines) From 70204817d2a28fbc82ab490e345c9153a78f79ab Mon Sep 17 00:00:00 2001 From: CreativeNick Date: Wed, 3 Jul 2024 10:36:53 -0700 Subject: [PATCH 21/24] Fix tier2 cookiecutter.json merge --- tier2/cookiecutter.json | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/tier2/cookiecutter.json b/tier2/cookiecutter.json index e3e1395..abdbba1 100644 --- a/tier2/cookiecutter.json +++ b/tier2/cookiecutter.json @@ -1,5 +1,4 @@ { -<<<<<<< nick/maintainers-slugify "project_name": "My Project", "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '_') }}", "project_org": "DSACMS", @@ -14,21 +13,6 @@ "create_repo": "Would you like to create a repo on github.com?", "receive_updates": "Would you like to receive updates from the DSACMS team via pull requests?", "add_maintainer": "Would you like to add a maintainer?" - } -======= - "project_name": "My Project", - "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '_') }}", - "project_org": "DSACMS", - "project_repo_name": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}", - "project_description": "This is the project description, could match github.com repo description.", - "code_owners": "Git usernames of code owners; separated by commas.", - "project_visibility": ["public", "internal", "private"], - "create_repo": [true, false], - "receive_updates": [true, false], - "__prompts__": { - "create_repo": "Would you like to create a repo on github.com?", - "receive_updates": "Would you like to receive updates from the DSACMS team via pull requests?" - }, - "_copy_without_render": ["repometrics"] ->>>>>>> dev + }, + "_copy_without_render": ["repometrics"] } From 13de57648fa7a7d2cfdab08c83d51c1aff92f3e7 Mon Sep 17 00:00:00 2001 From: CreativeNick Date: Wed, 3 Jul 2024 10:40:42 -0700 Subject: [PATCH 22/24] Update tier4 post_gen_project.py to match tier2 --- tier4/hooks/post_gen_project.py | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/tier4/hooks/post_gen_project.py b/tier4/hooks/post_gen_project.py index 778ad40..d24b7c8 100644 --- a/tier4/hooks/post_gen_project.py +++ b/tier4/hooks/post_gen_project.py @@ -53,23 +53,13 @@ def addMaintainer(): with open(maintainers_file_path, "r") as f: lines = f.readlines() - in_maintainers, in_approvers, in_reviewers = False, False, False for i, line in enumerate(lines): - if line.strip() == "## Maintainers:": - in_maintainers = True - elif line.strip() == "## Approvers:": - in_approvers = True - elif line.strip() == "## Reviewers:": - in_reviewers = True - elif in_maintainers and line.strip() == "-": - lines[i] = formatUsernames(maintainers) - in_maintainers = False - elif in_approvers and line.strip() == "-": - lines[i] = formatUsernames(approvers) - in_approvers = False - elif in_reviewers and line.strip() == "-": - lines[i] = formatUsernames(reviewers) - in_reviewers = False + if line.strip() == "## Maintainers:" and i + 2 < len(lines) and lines[i + 2].strip() == "-": + lines[i + 2] = formatUsernames(maintainers) + elif line.strip() == "## Approvers:" and i + 1 < len(lines) and lines[i + 1].strip() == "-": + lines[i + 1] = formatUsernames(approvers) + elif line.strip() == "## Reviewers:" and i + 1 < len(lines) and lines[i + 1].strip() == "-": + lines[i + 1] = formatUsernames(reviewers) with open(maintainers_file_path, "w") as f: f.writelines(lines) From 6ca3d249d22b9da064a2924bcbdf69638ff01e2e Mon Sep 17 00:00:00 2001 From: CreativeNick Date: Wed, 3 Jul 2024 10:50:58 -0700 Subject: [PATCH 23/24] Bugfixes for contributers.yml and tier2 post_gen_project.py --- tier2/hooks/post_gen_project.py | 2 +- .../.github/workflows/contributors.yml | 3 --- .../.github/workflows/contributors.yml | 3 --- .../.github/workflows/contributors.yml | 3 --- 4 files changed, 1 insertion(+), 10 deletions(-) diff --git a/tier2/hooks/post_gen_project.py b/tier2/hooks/post_gen_project.py index f64b35d..f07d69b 100644 --- a/tier2/hooks/post_gen_project.py +++ b/tier2/hooks/post_gen_project.py @@ -37,9 +37,9 @@ def addMaintainer(): while add_maintainer: maintainer = {} maintainer["role"] = input("Maintainer's Role (Reviewer, Approver, Maintainer): ").strip() + maintainer["name"] = input("Maintainer's Name: ").strip() github_username = input("Maintainer's GitHub Username: ").strip() maintainer["github_username"] = github_username if github_username.startswith('@') else f'@{github_username}' - maintainer["github_username"] = input("Maintainer's GitHub Username: ").strip() maintainer["affiliation"] = input("Maintainer's Affiliation (DSAC, CCSQ, CMMI, etc...): ").strip() maintainers.append(maintainer) diff --git a/tier2/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml b/tier2/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml index 28a3536..3ab38c5 100644 --- a/tier2/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml +++ b/tier2/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml @@ -44,9 +44,7 @@ jobs: OWNER=$(echo $GITHUB_REPOSITORY | cut -d'/' -f1) REPO=$(echo $GITHUB_REPOSITORY | cut -d'/' -f2) QUERY='query { repository(owner: \"'"$OWNER"'\", name: \"'"$REPO"'\") { collaborators { totalCount } } }' - {% raw %} CONTRIBUTORS=$(curl -s -X POST -H "Authorization: bearer ${{ secrets.GITHUB_TOKEN }}" -H "Content-Type: application/json" -d "{\"query\": \"$QUERY\"}" https://api.github.com/graphql | jq -r '.data.repository.collaborators.totalCount') - {% endraw %} echo "Total contributors: $CONTRIBUTORS" echo "contributors=$CONTRIBUTORS" >> $GITHUB_OUTPUT {% endraw %} @@ -56,7 +54,6 @@ jobs: run: | {% raw %} CONTRIBUTORS=${{ steps.get_contributors.outputs.contributors }} - {% endraw %} sed -i 's/.*/ '"$CONTRIBUTORS"' /g' MAINTAINERS.md {% endraw %} diff --git a/tier3/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml b/tier3/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml index 03908e9..3ab38c5 100644 --- a/tier3/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml +++ b/tier3/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml @@ -44,9 +44,7 @@ jobs: OWNER=$(echo $GITHUB_REPOSITORY | cut -d'/' -f1) REPO=$(echo $GITHUB_REPOSITORY | cut -d'/' -f2) QUERY='query { repository(owner: \"'"$OWNER"'\", name: \"'"$REPO"'\") { collaborators { totalCount } } }' - {% raw %} CONTRIBUTORS=$(curl -s -X POST -H "Authorization: bearer ${{ secrets.GITHUB_TOKEN }}" -H "Content-Type: application/json" -d "{\"query\": \"$QUERY\"}" https://api.github.com/graphql | jq -r '.data.repository.collaborators.totalCount') - {% end raw %} echo "Total contributors: $CONTRIBUTORS" echo "contributors=$CONTRIBUTORS" >> $GITHUB_OUTPUT {% endraw %} @@ -56,7 +54,6 @@ jobs: run: | {% raw %} CONTRIBUTORS=${{ steps.get_contributors.outputs.contributors }} - {% endraw %} sed -i 's/.*/ '"$CONTRIBUTORS"' /g' MAINTAINERS.md {% endraw %} diff --git a/tier4/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml b/tier4/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml index 28a3536..3ab38c5 100644 --- a/tier4/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml +++ b/tier4/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml @@ -44,9 +44,7 @@ jobs: OWNER=$(echo $GITHUB_REPOSITORY | cut -d'/' -f1) REPO=$(echo $GITHUB_REPOSITORY | cut -d'/' -f2) QUERY='query { repository(owner: \"'"$OWNER"'\", name: \"'"$REPO"'\") { collaborators { totalCount } } }' - {% raw %} CONTRIBUTORS=$(curl -s -X POST -H "Authorization: bearer ${{ secrets.GITHUB_TOKEN }}" -H "Content-Type: application/json" -d "{\"query\": \"$QUERY\"}" https://api.github.com/graphql | jq -r '.data.repository.collaborators.totalCount') - {% endraw %} echo "Total contributors: $CONTRIBUTORS" echo "contributors=$CONTRIBUTORS" >> $GITHUB_OUTPUT {% endraw %} @@ -56,7 +54,6 @@ jobs: run: | {% raw %} CONTRIBUTORS=${{ steps.get_contributors.outputs.contributors }} - {% endraw %} sed -i 's/.*/ '"$CONTRIBUTORS"' /g' MAINTAINERS.md {% endraw %} From cf39b03c53e582a906cf280937964d131a8891fa Mon Sep 17 00:00:00 2001 From: CreativeNick Date: Wed, 3 Jul 2024 10:57:14 -0700 Subject: [PATCH 24/24] Remove print statements for post_gen_project.py in tier3 and tier4 --- tier3/hooks/post_gen_project.py | 2 -- tier4/hooks/post_gen_project.py | 2 -- 2 files changed, 4 deletions(-) diff --git a/tier3/hooks/post_gen_project.py b/tier3/hooks/post_gen_project.py index d0eb9ab..e454ec3 100644 --- a/tier3/hooks/post_gen_project.py +++ b/tier3/hooks/post_gen_project.py @@ -64,8 +64,6 @@ def addMaintainer(): with open(maintainers_file_path, "w") as f: f.writelines(lines) - print("Maintainers, Approvers, and Reviewers have been added to MAINTAINERS.md") - if CREATE_REPO == "True": createGithubRepo() diff --git a/tier4/hooks/post_gen_project.py b/tier4/hooks/post_gen_project.py index d24b7c8..be99f62 100644 --- a/tier4/hooks/post_gen_project.py +++ b/tier4/hooks/post_gen_project.py @@ -64,8 +64,6 @@ def addMaintainer(): with open(maintainers_file_path, "w") as f: f.writelines(lines) - print("Maintainers, Approvers, and Reviewers have been added to MAINTAINERS.md") - if CREATE_REPO == "True": createGithubRepo()