diff --git a/tier0/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py b/tier0/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py index ef677b7e..7ecaa2dd 100644 --- a/tier0/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py +++ b/tier0/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py @@ -2,19 +2,30 @@ import shutil import json import os -import shutil +from datetime import datetime, timezone def get_date_fields(): # Run git commands and capture as string output = subprocess.run(['git', 'log', '--date=iso', '--pretty=%cI', '--max-parents=0', '-n', '1'], capture_output=True, text=True) - + # Store string and strip of leading / trailing whitespace date = output.stdout.strip() + + # Parse the git timestamp and convert to UTC + git_date = datetime.fromisoformat(date) + utc_date = git_date.astimezone(timezone.utc) + created_date = utc_date.strftime('%Y-%m-%dT%H:%M:%SZ') + + # Generate current UTC timestamps using the new recommended method + current_utc = datetime.now(timezone.utc) + current_timestamp = current_utc.strftime('%Y-%m-%dT%H:%M:%SZ') # Create a dictionary for date information to be pushed to JSON - date_information = {"created": f"{date}", - "lastModified": "{% now 'utc', '%Y-%m-%dT%H:%M:%S%z' %}", - "metadataLastUpdated": "{% now 'utc', '%Y-%m-%dT%H:%M:%S%z' %}"} + date_information = { + "created": created_date, + "lastModified": current_timestamp, + "metadataLastUpdated": current_timestamp + } return date_information @@ -77,20 +88,26 @@ def update_code_json(json_file_path): data['laborHours'] = None # Check if usageType is an exemption - if data['permissions']['usageType'].startswith('exempt'): + contains_exempt = any("exempt" in item for item in data['permissions']['usageType']) + if contains_exempt: exemption_text = prompt_exemption_text(data['permissions']['usageType']) data['permissions']['exemptionText'] = exemption_text else: del data['permissions']['exemptionText'] # Format multi-select options - multi_select_fields = ["platforms", "categories", "languages", "tags", "feedbackMechanisms", "projects", "systems", "upstream", "subsetInHealthcare", "userType"] + multi_select_fields = ["platforms", "categories", "languages", "contractNumber", "tags", "projects", "systems", "subsetInHealthcare", "userType"] for field in multi_select_fields: data[field] = format_multi_select_fields(data[field][0]) # Format integer fields if data['reuseFrequency']['forks'].isdigit(): data['reuseFrequency']['forks'] = int(data['reuseFrequency']['forks']) + if data['reuseFrequency']['clones'].isdigit(): + data['reuseFrequency']['clones'] = int(data['reuseFrequency']['clones']) + + data['localisation'] = eval(data['localisation']) + data['userInput'] = eval(data['userInput']) # Update the JSON with open(json_file_path, 'w') as file: diff --git a/tier0/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json b/tier0/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json index c9a45f5f..ceefd273 100644 --- a/tier0/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json +++ b/tier0/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json @@ -6,11 +6,12 @@ "permissions": { "licenses": [ { - "URL": "LICENSE", - "name": "{{ cookiecutter.license }}" + "name": "{{ cookiecutter.license }}", + "URL": "{{cookiecutter.license_url}}" + } ], - "usageType": "{{ cookiecutter.usage_type }}", + "usageType": [ "{{ cookiecutter.usage_type }}" ], "exemptionText": "" }, "organization": "Centers for Medicare & Medicaid Services", @@ -20,21 +21,24 @@ "vcs": "{{ cookiecutter.vcs }}", "laborHours": [""], "reuseFrequency": { - "forks": "{{ cookiecutter.forks }}" + "forks": "{{ cookiecutter.forks }}", + "clones": "{{ cookiecutter.clones }}" }, "platforms": [ "{{ cookiecutter.platforms }}" ], "categories": [ "{{ cookiecutter.categories }}" ], "softwareType": "{{ cookiecutter.software_type }}", "languages": [ "{{ cookiecutter.languages }}" ], "maintenance": "{{ cookiecutter.maintenance }}", - "contractNumber": "{{ cookiecutter.contract_number }}", + "contractNumber": [ "{{ cookiecutter.contract_number }}" ], + "SBOM": "{{ cookiecutter.sbom }}", "date": [""], "tags": [ "{{ cookiecutter.tags }}" ], "contact": { "email": "{{ cookiecutter.contact_email }}", "name": "{{ cookiecutter.contact_name }}" }, - "feedbackMechanisms": ["{{ cookiecutter.feedback_mechanisms }}"], + "feedbackMechanism": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/issues", + "AIUseCaseID": "{{ cookiecutter.ai_use_case_id }}", "localisation": "{{ cookiecutter.localisation }}", "repositoryType": "{{ cookiecutter.repository_type }}", "userInput": "{{ cookiecutter.user_input }}", @@ -42,7 +46,6 @@ "group": "{{ cookiecutter.group }}", "projects": ["{{ cookiecutter.projects }}"], "systems": ["{{ cookiecutter.systems }}"], - "upstream": ["{{ cookiecutter.upstream }}"], "subsetInHealthcare": ["{{ cookiecutter.subset_in_healthcare }}"], "userType": ["{{ cookiecutter.user_type }}"], "maturityModelTier": 0 diff --git a/tier0/{{cookiecutter.project_slug}}/.github/cookiecutter.json b/tier0/{{cookiecutter.project_slug}}/.github/cookiecutter.json index ebc86a63..633db723 100644 --- a/tier0/{{cookiecutter.project_slug}}/.github/cookiecutter.json +++ b/tier0/{{cookiecutter.project_slug}}/.github/cookiecutter.json @@ -4,33 +4,35 @@ "project_org": "{{ cookiecutter.project_org }}", "description": "A short description of the project.", "long_description": "A longer description of the project.", - "status": ["ideation", "development", "alpha", "beta", "release candidate", "production", "archival"], - "license": ["CC0-1.0", "Apache-2.0", "MIT", "MPL-2.0", "GPL-2.0-only", "GPL-3.0-only", "GPL-3.0-or-later", "LGPL-2.1-only", "LGPL-3.0-only", "BSD-2-Clause", "BSD-3-Clause", "EPL-2.0", "Other"], - "usage_type" : ["openSource", "governmentWideReuse", "exemptByLaw", "exemptByNationalSecurity", "exemptByAgencySystem", "exemptByAgencyMission", "exemptByCIO", "exemptByPolicyDate"], - "repository_host": ["github.com/CMSgov", "github.com/CMS-Enterprise", "github.com/DSACMS", "github.cms.gov", "CCSQ GitHub"], + "status": ["Ideation", "Development", "Alpha", "Beta", "Release Candidate", "Production", "Archival"], + "license": ["CC0-1.0", "Apache-2.0", "MIT", "MPL-2.0", "GPL-2.0-only", "GPL-3.0-only", "GPL-3.0-or-later", "LGPL-2.1-only", "LGPL-3.0-only", "BSD-2-Clause", "BSD-3-Clause", "EPL-2.0", "Other", "None"], + "license_url": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/blob/main/LICENSE", + "usage_type" : ["openSource", "governmentWideReuse", "exemptByNationalSecurity", "exemptByNationalIntelligence", "exemptByFOIA", "exemptByEAR", "exemptByITAR", "exemptByTSA", "exemptByClassifiedInformation", "exemptByPrivacyRisk", "exemptByIPRestriction", "exemptByAgencySystem", "exemptByAgencyMission", "exemptByCIO", "exemptByPolicyDate"], + "repository_host": ["github.com/CMSgov", "github.com/CMS-Enterprise", "github.com/Enterprise-CMCS", "github.com/DSACMS", "github.cms.gov", "CCSQ GitHub"], "repository_visibility": ["public", "private"], "vcs": ["git", "hg", "svn", "rcs", "bzr"], "forks": 0, + "clones": 0, "platforms": "web, windows, mac, linux, ios, android, other", "categories": "healthcare", "software_type":["standalone/mobile", "standalone/iot", "standalone/desktop", "standalone/web", "standalone/backend", "standalone/other", "addon", "library", "configurationFiles"], "languages": "", "maintenance": ["internal", "contract", "community", "none"], - "contract_number": 0, + "contract_number": "", + "sbom": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/network/dependencies", "tags": "dsacms-tier0", "contact_email": "opensource@cms.hhs.gov", "contact_name": "CMS Open Source Program Office", - "feedback_mechanisms": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/issues", - "localisation": ["true", "false"], - "repository_type" : ["Package", "Website", "Standards", "Libraries", "Data", "Apps", "Tools", "APIs", "Docs"], - "user_input": ["Yes", "No"], - "fisma_level": ["Low", "Moderate", "High"], + "ai_use_case_id": "0", + "localisation": [true, false], + "repository_type" : ["package", "website", "standards", "libraries", "data", "apps", "tools", "APIs"], + "user_input": [true, false], + "fisma_level": ["low", "moderate", "high"], "group": "CMS/OA/DSAC", "projects": "", "systems": "", - "upstream": "", - "subset_in_healthcare": "Policy, Operational, Medicare, Medicaid", - "user_type": "Providers, Patients, Government", + "subset_in_healthcare": "policy, operational, medicare, medicaid", + "user_type": "providers, patients, government", "__prompts__": { "project_name": "What is the name of the project or software?", "project_repo_name": "What is the name of the repository?", @@ -39,20 +41,23 @@ "long_description": "Provide longer description of the software, between 150 and 10000 chars. It is meant to provide an overview of the capabilities of the software for a potential user.", "status": "What is the status of the project?", "license": "What license is the project under?", + "license_url": "What is the URL to the license?", "usage_type": "What is the usage type for this project? For more information on each option, visit github.com/DSACMS/gov-codejson", "repository_host": "Where is the repository hosted?", "vcs": "What version control system is used?", "forks": "How many forks does the repository have?", + "clones": "How many clones does the repository have?", "platforms": "What platform does the software runs on? Separate items by commas.", "categories": "What categories best describes the project? Separate items by commas. List of categories here: https://yml.publiccode.tools/categories-list.html?highlight=categories", "software_type": "What type of software is the project?", "languages": "What programming language(s) is the software written in? Separate items by commas.", "maintenance": "How is the software maintained?", - "contract_number": "What is the contractor number of the project?", + "contract_number": "What is the contractor number(s) of the project? Separate items by commas.", + "sbom": "Provide a link to the SBOM of the repository. If the software does not have a SBOM, enter 'None'.", "tags": "Provide a list of tags to describe the software for search. Separate items by commas.", "contact_name": "A point of contact is needed for the project. What is the name of the point of contact?", "contact_email": "What is email address of the point of contact?", - "feedback_mechanisms": "What are methods a repository receives feedback from the community (e.g. URL to GitHub repository issues page, website, email)", + "ai_use_case_id": "What is the software's ID in the AI Use Case Inventory? If the software is not listed in the inventory, enter '0'.", "localisation": "Does the software support multiple spoken languages?", "repository_type": "What type of repository is this project?", "user_input": "Does the project accept user input? (e.g. allows user to query a database, allows login by users, upload files, etc.)", @@ -60,8 +65,7 @@ "group": "Which group at CMS is the project part of?", "projects": "What project is the repository associated with? Separate items by commas.", "systems": "What systems does the repository use or interface with? Separate items by commas.", - "upstream": "What upstream dependencies does the repository use? Separate items by commas.", - "subset_in_healthcare": "Which subset of healthcare does the project belong to?", - "user_type": "Who are the intended users?" + "subset_in_healthcare": "Which subset of healthcare does the project belong to? Separate items by commas.", + "user_type": "Who are the intended users? Separate items by commas." } } \ No newline at end of file diff --git a/tier1/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py b/tier1/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py index ef677b7e..7ecaa2dd 100644 --- a/tier1/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py +++ b/tier1/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py @@ -2,19 +2,30 @@ import shutil import json import os -import shutil +from datetime import datetime, timezone def get_date_fields(): # Run git commands and capture as string output = subprocess.run(['git', 'log', '--date=iso', '--pretty=%cI', '--max-parents=0', '-n', '1'], capture_output=True, text=True) - + # Store string and strip of leading / trailing whitespace date = output.stdout.strip() + + # Parse the git timestamp and convert to UTC + git_date = datetime.fromisoformat(date) + utc_date = git_date.astimezone(timezone.utc) + created_date = utc_date.strftime('%Y-%m-%dT%H:%M:%SZ') + + # Generate current UTC timestamps using the new recommended method + current_utc = datetime.now(timezone.utc) + current_timestamp = current_utc.strftime('%Y-%m-%dT%H:%M:%SZ') # Create a dictionary for date information to be pushed to JSON - date_information = {"created": f"{date}", - "lastModified": "{% now 'utc', '%Y-%m-%dT%H:%M:%S%z' %}", - "metadataLastUpdated": "{% now 'utc', '%Y-%m-%dT%H:%M:%S%z' %}"} + date_information = { + "created": created_date, + "lastModified": current_timestamp, + "metadataLastUpdated": current_timestamp + } return date_information @@ -77,20 +88,26 @@ def update_code_json(json_file_path): data['laborHours'] = None # Check if usageType is an exemption - if data['permissions']['usageType'].startswith('exempt'): + contains_exempt = any("exempt" in item for item in data['permissions']['usageType']) + if contains_exempt: exemption_text = prompt_exemption_text(data['permissions']['usageType']) data['permissions']['exemptionText'] = exemption_text else: del data['permissions']['exemptionText'] # Format multi-select options - multi_select_fields = ["platforms", "categories", "languages", "tags", "feedbackMechanisms", "projects", "systems", "upstream", "subsetInHealthcare", "userType"] + multi_select_fields = ["platforms", "categories", "languages", "contractNumber", "tags", "projects", "systems", "subsetInHealthcare", "userType"] for field in multi_select_fields: data[field] = format_multi_select_fields(data[field][0]) # Format integer fields if data['reuseFrequency']['forks'].isdigit(): data['reuseFrequency']['forks'] = int(data['reuseFrequency']['forks']) + if data['reuseFrequency']['clones'].isdigit(): + data['reuseFrequency']['clones'] = int(data['reuseFrequency']['clones']) + + data['localisation'] = eval(data['localisation']) + data['userInput'] = eval(data['userInput']) # Update the JSON with open(json_file_path, 'w') as file: diff --git a/tier1/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json b/tier1/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json index 1b5f0bf5..87fa9090 100644 --- a/tier1/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json +++ b/tier1/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json @@ -6,11 +6,12 @@ "permissions": { "licenses": [ { - "URL": "LICENSE", - "name": "{{ cookiecutter.license }}" + "name": "{{ cookiecutter.license }}", + "URL": "{{cookiecutter.license_url}}" + } ], - "usageType": "{{ cookiecutter.usage_type }}", + "usageType": [ "{{ cookiecutter.usage_type }}" ], "exemptionText": "" }, "organization": "Centers for Medicare & Medicaid Services", @@ -20,21 +21,24 @@ "vcs": "{{ cookiecutter.vcs }}", "laborHours": [""], "reuseFrequency": { - "forks": "{{ cookiecutter.forks }}" + "forks": "{{ cookiecutter.forks }}", + "clones": "{{ cookiecutter.clones }}" }, "platforms": [ "{{ cookiecutter.platforms }}" ], "categories": [ "{{ cookiecutter.categories }}" ], "softwareType": "{{ cookiecutter.software_type }}", "languages": [ "{{ cookiecutter.languages }}" ], "maintenance": "{{ cookiecutter.maintenance }}", - "contractNumber": "{{ cookiecutter.contract_number }}", + "contractNumber": [ "{{ cookiecutter.contract_number }}" ], + "SBOM": "{{ cookiecutter.sbom }}", "date": [""], "tags": [ "{{ cookiecutter.tags }}" ], "contact": { "email": "{{ cookiecutter.contact_email }}", "name": "{{ cookiecutter.contact_name }}" }, - "feedbackMechanisms": ["{{ cookiecutter.feedback_mechanisms }}"], + "feedbackMechanism": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/issues", + "AIUseCaseID": "{{ cookiecutter.ai_use_case_id }}", "localisation": "{{ cookiecutter.localisation }}", "repositoryType": "{{ cookiecutter.repository_type }}", "userInput": "{{ cookiecutter.user_input }}", @@ -42,7 +46,6 @@ "group": "{{ cookiecutter.group }}", "projects": ["{{ cookiecutter.projects }}"], "systems": ["{{ cookiecutter.systems }}"], - "upstream": ["{{ cookiecutter.upstream }}"], "subsetInHealthcare": ["{{ cookiecutter.subset_in_healthcare }}"], "userType": ["{{ cookiecutter.user_type }}"], "maturityModelTier": 1 diff --git a/tier1/{{cookiecutter.project_slug}}/.github/cookiecutter.json b/tier1/{{cookiecutter.project_slug}}/.github/cookiecutter.json index 27e8a34d..633db723 100644 --- a/tier1/{{cookiecutter.project_slug}}/.github/cookiecutter.json +++ b/tier1/{{cookiecutter.project_slug}}/.github/cookiecutter.json @@ -4,33 +4,35 @@ "project_org": "{{ cookiecutter.project_org }}", "description": "A short description of the project.", "long_description": "A longer description of the project.", - "status": ["ideation", "development", "alpha", "beta", "release candidate", "production", "archival"], - "license": ["CC0-1.0", "Apache-2.0", "MIT", "MPL-2.0", "GPL-2.0-only", "GPL-3.0-only", "GPL-3.0-or-later", "LGPL-2.1-only", "LGPL-3.0-only", "BSD-2-Clause", "BSD-3-Clause", "EPL-2.0", "Other"], - "usage_type" : ["openSource", "governmentWideReuse", "exemptByLaw", "exemptByNationalSecurity", "exemptByAgencySystem", "exemptByAgencyMission", "exemptByCIO", "exemptByPolicyDate"], - "repository_host": ["github.com/CMSgov", "github.com/CMS-Enterprise", "github.com/DSACMS", "github.cms.gov", "CCSQ GitHub"], + "status": ["Ideation", "Development", "Alpha", "Beta", "Release Candidate", "Production", "Archival"], + "license": ["CC0-1.0", "Apache-2.0", "MIT", "MPL-2.0", "GPL-2.0-only", "GPL-3.0-only", "GPL-3.0-or-later", "LGPL-2.1-only", "LGPL-3.0-only", "BSD-2-Clause", "BSD-3-Clause", "EPL-2.0", "Other", "None"], + "license_url": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/blob/main/LICENSE", + "usage_type" : ["openSource", "governmentWideReuse", "exemptByNationalSecurity", "exemptByNationalIntelligence", "exemptByFOIA", "exemptByEAR", "exemptByITAR", "exemptByTSA", "exemptByClassifiedInformation", "exemptByPrivacyRisk", "exemptByIPRestriction", "exemptByAgencySystem", "exemptByAgencyMission", "exemptByCIO", "exemptByPolicyDate"], + "repository_host": ["github.com/CMSgov", "github.com/CMS-Enterprise", "github.com/Enterprise-CMCS", "github.com/DSACMS", "github.cms.gov", "CCSQ GitHub"], "repository_visibility": ["public", "private"], "vcs": ["git", "hg", "svn", "rcs", "bzr"], "forks": 0, + "clones": 0, "platforms": "web, windows, mac, linux, ios, android, other", "categories": "healthcare", "software_type":["standalone/mobile", "standalone/iot", "standalone/desktop", "standalone/web", "standalone/backend", "standalone/other", "addon", "library", "configurationFiles"], "languages": "", "maintenance": ["internal", "contract", "community", "none"], - "contract_number": 0, - "tags": "dsacms-tier1", + "contract_number": "", + "sbom": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/network/dependencies", + "tags": "dsacms-tier0", "contact_email": "opensource@cms.hhs.gov", "contact_name": "CMS Open Source Program Office", - "feedback_mechanisms": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/issues", - "localisation": ["true", "false"], - "repository_type" : ["Package", "Website", "Standards", "Libraries", "Data", "Apps", "Tools", "APIs", "Docs"], - "user_input": ["Yes", "No"], - "fisma_level": ["Low", "Moderate", "High"], + "ai_use_case_id": "0", + "localisation": [true, false], + "repository_type" : ["package", "website", "standards", "libraries", "data", "apps", "tools", "APIs"], + "user_input": [true, false], + "fisma_level": ["low", "moderate", "high"], "group": "CMS/OA/DSAC", "projects": "", "systems": "", - "upstream": "", - "subset_in_healthcare": "Policy, Operational, Medicare, Medicaid", - "user_type": "Providers, Patients, Government", + "subset_in_healthcare": "policy, operational, medicare, medicaid", + "user_type": "providers, patients, government", "__prompts__": { "project_name": "What is the name of the project or software?", "project_repo_name": "What is the name of the repository?", @@ -39,20 +41,23 @@ "long_description": "Provide longer description of the software, between 150 and 10000 chars. It is meant to provide an overview of the capabilities of the software for a potential user.", "status": "What is the status of the project?", "license": "What license is the project under?", + "license_url": "What is the URL to the license?", "usage_type": "What is the usage type for this project? For more information on each option, visit github.com/DSACMS/gov-codejson", "repository_host": "Where is the repository hosted?", "vcs": "What version control system is used?", "forks": "How many forks does the repository have?", + "clones": "How many clones does the repository have?", "platforms": "What platform does the software runs on? Separate items by commas.", "categories": "What categories best describes the project? Separate items by commas. List of categories here: https://yml.publiccode.tools/categories-list.html?highlight=categories", "software_type": "What type of software is the project?", "languages": "What programming language(s) is the software written in? Separate items by commas.", "maintenance": "How is the software maintained?", - "contract_number": "What is the contractor number of the project?", + "contract_number": "What is the contractor number(s) of the project? Separate items by commas.", + "sbom": "Provide a link to the SBOM of the repository. If the software does not have a SBOM, enter 'None'.", "tags": "Provide a list of tags to describe the software for search. Separate items by commas.", "contact_name": "A point of contact is needed for the project. What is the name of the point of contact?", "contact_email": "What is email address of the point of contact?", - "feedback_mechanisms": "What are methods a repository receives feedback from the community (e.g. URL to GitHub repository issues page, website, email)", + "ai_use_case_id": "What is the software's ID in the AI Use Case Inventory? If the software is not listed in the inventory, enter '0'.", "localisation": "Does the software support multiple spoken languages?", "repository_type": "What type of repository is this project?", "user_input": "Does the project accept user input? (e.g. allows user to query a database, allows login by users, upload files, etc.)", @@ -60,8 +65,7 @@ "group": "Which group at CMS is the project part of?", "projects": "What project is the repository associated with? Separate items by commas.", "systems": "What systems does the repository use or interface with? Separate items by commas.", - "upstream": "What upstream dependencies does the repository use? Separate items by commas.", - "subset_in_healthcare": "Which subset of healthcare does the project belong to?", - "user_type": "Who are the intended users?" + "subset_in_healthcare": "Which subset of healthcare does the project belong to? Separate items by commas.", + "user_type": "Who are the intended users? Separate items by commas." } } \ No newline at end of file diff --git a/tier2/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py b/tier2/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py index 45677b3d..30c8e9b5 100644 --- a/tier2/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py +++ b/tier2/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py @@ -2,19 +2,30 @@ import shutil import json import os -import shutil +from datetime import datetime, timezone def get_date_fields(): # Run git commands and capture as string output = subprocess.run(['git', 'log', '--date=iso', '--pretty=%cI', '--max-parents=0', '-n', '1'], capture_output=True, text=True) - + # Store string and strip of leading / trailing whitespace date = output.stdout.strip() + + # Parse the git timestamp and convert to UTC + git_date = datetime.fromisoformat(date) + utc_date = git_date.astimezone(timezone.utc) + created_date = utc_date.strftime('%Y-%m-%dT%H:%M:%SZ') + + # Generate current UTC timestamps using the new recommended method + current_utc = datetime.now(timezone.utc) + current_timestamp = current_utc.strftime('%Y-%m-%dT%H:%M:%SZ') # Create a dictionary for date information to be pushed to JSON - date_information = {"created": f"{date}", - "lastModified": "{% now 'utc', '%Y-%m-%dT%H:%M:%S%z' %}", - "metadataLastUpdated": "{% now 'utc', '%Y-%m-%dT%H:%M:%S%z' %}"} + date_information = { + "created": created_date, + "lastModified": current_timestamp, + "metadataLastUpdated": current_timestamp + } return date_information @@ -77,20 +88,26 @@ def update_code_json(json_file_path): data['laborHours'] = None # Check if usageType is an exemption - if data['permissions']['usageType'].startswith('exempt'): + contains_exempt = any("exempt" in item for item in data['permissions']['usageType']) + if contains_exempt: exemption_text = prompt_exemption_text(data['permissions']['usageType']) data['permissions']['exemptionText'] = exemption_text else: del data['permissions']['exemptionText'] # Format multi-select options - multi_select_fields = ["platforms", "categories", "languages", "tags", "feedbackMechanisms", "projects", "systems", "upstream", "subsetInHealthcare", "userType"] + multi_select_fields = ["platforms", "categories", "languages", "contractNumber", "tags", "projects", "systems", "subsetInHealthcare", "userType"] for field in multi_select_fields: data[field] = format_multi_select_fields(data[field][0]) # Format integer fields if data['reuseFrequency']['forks'].isdigit(): data['reuseFrequency']['forks'] = int(data['reuseFrequency']['forks']) + if data['reuseFrequency']['clones'].isdigit(): + data['reuseFrequency']['clones'] = int(data['reuseFrequency']['clones']) + + data['localisation'] = eval(data['localisation']) + data['userInput'] = eval(data['userInput']) # Update the JSON with open(json_file_path, 'w') as file: diff --git a/tier2/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json b/tier2/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json index 204cc1c2..4dd40bab 100644 --- a/tier2/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json +++ b/tier2/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json @@ -6,11 +6,12 @@ "permissions": { "licenses": [ { - "URL": "LICENSE", - "name": "{{ cookiecutter.license }}" + "name": "{{ cookiecutter.license }}", + "URL": "{{cookiecutter.license_url}}" + } ], - "usageType": "{{ cookiecutter.usage_type }}", + "usageType": [ "{{ cookiecutter.usage_type }}" ], "exemptionText": "" }, "organization": "Centers for Medicare & Medicaid Services", @@ -20,21 +21,24 @@ "vcs": "{{ cookiecutter.vcs }}", "laborHours": [""], "reuseFrequency": { - "forks": "{{ cookiecutter.forks }}" + "forks": "{{ cookiecutter.forks }}", + "clones": "{{ cookiecutter.clones }}" }, "platforms": [ "{{ cookiecutter.platforms }}" ], "categories": [ "{{ cookiecutter.categories }}" ], "softwareType": "{{ cookiecutter.software_type }}", "languages": [ "{{ cookiecutter.languages }}" ], "maintenance": "{{ cookiecutter.maintenance }}", - "contractNumber": "{{ cookiecutter.contract_number }}", + "contractNumber": [ "{{ cookiecutter.contract_number }}" ], + "SBOM": "{{ cookiecutter.sbom }}", "date": [""], "tags": [ "{{ cookiecutter.tags }}" ], "contact": { "email": "{{ cookiecutter.contact_email }}", "name": "{{ cookiecutter.contact_name }}" }, - "feedbackMechanisms": ["{{ cookiecutter.feedback_mechanisms }}"], + "feedbackMechanism": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/issues", + "AIUseCaseID": "{{ cookiecutter.ai_use_case_id }}", "localisation": "{{ cookiecutter.localisation }}", "repositoryType": "{{ cookiecutter.repository_type }}", "userInput": "{{ cookiecutter.user_input }}", @@ -42,7 +46,6 @@ "group": "{{ cookiecutter.group }}", "projects": ["{{ cookiecutter.projects }}"], "systems": ["{{ cookiecutter.systems }}"], - "upstream": ["{{ cookiecutter.upstream }}"], "subsetInHealthcare": ["{{ cookiecutter.subset_in_healthcare }}"], "userType": ["{{ cookiecutter.user_type }}"], "maturityModelTier": 2 diff --git a/tier2/{{cookiecutter.project_slug}}/.github/cookiecutter.json b/tier2/{{cookiecutter.project_slug}}/.github/cookiecutter.json index 5e9b1bed..633db723 100644 --- a/tier2/{{cookiecutter.project_slug}}/.github/cookiecutter.json +++ b/tier2/{{cookiecutter.project_slug}}/.github/cookiecutter.json @@ -1,36 +1,38 @@ { - "project_name": "{{ cookiecutter.project_name}}", + "project_name": "{{ cookiecutter.project_name }}", "project_repo_name": "{{ cookiecutter.project_repo_name }}", "project_org": "{{ cookiecutter.project_org }}", "description": "A short description of the project.", "long_description": "A longer description of the project.", - "status": ["ideation", "development", "alpha", "beta", "release candidate", "production", "archival"], - "license": ["CC0-1.0", "Apache-2.0", "MIT", "MPL-2.0", "GPL-2.0-only", "GPL-3.0-only", "GPL-3.0-or-later", "LGPL-2.1-only", "LGPL-3.0-only", "BSD-2-Clause", "BSD-3-Clause", "EPL-2.0", "Other"], - "usage_type" : ["openSource", "governmentWideReuse", "exemptByLaw", "exemptByNationalSecurity", "exemptByAgencySystem", "exemptByAgencyMission", "exemptByCIO", "exemptByPolicyDate"], - "repository_host": ["github.com/CMSgov", "github.com/CMS-Enterprise", "github.com/DSACMS", "github.cms.gov", "CCSQ GitHub"], + "status": ["Ideation", "Development", "Alpha", "Beta", "Release Candidate", "Production", "Archival"], + "license": ["CC0-1.0", "Apache-2.0", "MIT", "MPL-2.0", "GPL-2.0-only", "GPL-3.0-only", "GPL-3.0-or-later", "LGPL-2.1-only", "LGPL-3.0-only", "BSD-2-Clause", "BSD-3-Clause", "EPL-2.0", "Other", "None"], + "license_url": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/blob/main/LICENSE", + "usage_type" : ["openSource", "governmentWideReuse", "exemptByNationalSecurity", "exemptByNationalIntelligence", "exemptByFOIA", "exemptByEAR", "exemptByITAR", "exemptByTSA", "exemptByClassifiedInformation", "exemptByPrivacyRisk", "exemptByIPRestriction", "exemptByAgencySystem", "exemptByAgencyMission", "exemptByCIO", "exemptByPolicyDate"], + "repository_host": ["github.com/CMSgov", "github.com/CMS-Enterprise", "github.com/Enterprise-CMCS", "github.com/DSACMS", "github.cms.gov", "CCSQ GitHub"], "repository_visibility": ["public", "private"], "vcs": ["git", "hg", "svn", "rcs", "bzr"], "forks": 0, + "clones": 0, "platforms": "web, windows, mac, linux, ios, android, other", "categories": "healthcare", "software_type":["standalone/mobile", "standalone/iot", "standalone/desktop", "standalone/web", "standalone/backend", "standalone/other", "addon", "library", "configurationFiles"], "languages": "", "maintenance": ["internal", "contract", "community", "none"], - "contract_number": 0, - "tags": "dsacms-tier2", + "contract_number": "", + "sbom": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/network/dependencies", + "tags": "dsacms-tier0", "contact_email": "opensource@cms.hhs.gov", "contact_name": "CMS Open Source Program Office", - "feedback_mechanisms": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/issues", - "localisation": ["true", "false"], - "repository_type" : ["Package", "Website", "Standards", "Libraries", "Data", "Apps", "Tools", "APIs", "Docs"], - "user_input": ["Yes", "No"], - "fisma_level": ["Low", "Moderate", "High"], + "ai_use_case_id": "0", + "localisation": [true, false], + "repository_type" : ["package", "website", "standards", "libraries", "data", "apps", "tools", "APIs"], + "user_input": [true, false], + "fisma_level": ["low", "moderate", "high"], "group": "CMS/OA/DSAC", "projects": "", "systems": "", - "upstream": "", - "subset_in_healthcare": "Policy, Operational, Medicare, Medicaid", - "user_type": "Providers, Patients, Government", + "subset_in_healthcare": "policy, operational, medicare, medicaid", + "user_type": "providers, patients, government", "__prompts__": { "project_name": "What is the name of the project or software?", "project_repo_name": "What is the name of the repository?", @@ -39,20 +41,23 @@ "long_description": "Provide longer description of the software, between 150 and 10000 chars. It is meant to provide an overview of the capabilities of the software for a potential user.", "status": "What is the status of the project?", "license": "What license is the project under?", + "license_url": "What is the URL to the license?", "usage_type": "What is the usage type for this project? For more information on each option, visit github.com/DSACMS/gov-codejson", "repository_host": "Where is the repository hosted?", "vcs": "What version control system is used?", "forks": "How many forks does the repository have?", + "clones": "How many clones does the repository have?", "platforms": "What platform does the software runs on? Separate items by commas.", "categories": "What categories best describes the project? Separate items by commas. List of categories here: https://yml.publiccode.tools/categories-list.html?highlight=categories", "software_type": "What type of software is the project?", "languages": "What programming language(s) is the software written in? Separate items by commas.", "maintenance": "How is the software maintained?", - "contract_number": "What is the contractor number of the project?", + "contract_number": "What is the contractor number(s) of the project? Separate items by commas.", + "sbom": "Provide a link to the SBOM of the repository. If the software does not have a SBOM, enter 'None'.", "tags": "Provide a list of tags to describe the software for search. Separate items by commas.", "contact_name": "A point of contact is needed for the project. What is the name of the point of contact?", "contact_email": "What is email address of the point of contact?", - "feedback_mechanisms": "What are methods a repository receives feedback from the community (e.g. URL to GitHub repository issues page, website, email)", + "ai_use_case_id": "What is the software's ID in the AI Use Case Inventory? If the software is not listed in the inventory, enter '0'.", "localisation": "Does the software support multiple spoken languages?", "repository_type": "What type of repository is this project?", "user_input": "Does the project accept user input? (e.g. allows user to query a database, allows login by users, upload files, etc.)", @@ -60,8 +65,7 @@ "group": "Which group at CMS is the project part of?", "projects": "What project is the repository associated with? Separate items by commas.", "systems": "What systems does the repository use or interface with? Separate items by commas.", - "upstream": "What upstream dependencies does the repository use? Separate items by commas.", - "subset_in_healthcare": "Which subset of healthcare does the project belong to?", - "user_type": "Who are the intended users?" + "subset_in_healthcare": "Which subset of healthcare does the project belong to? Separate items by commas.", + "user_type": "Who are the intended users? Separate items by commas." } } \ No newline at end of file diff --git a/tier3/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py b/tier3/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py index ea2bc849..f175d80a 100644 --- a/tier3/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py +++ b/tier3/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py @@ -2,19 +2,30 @@ import shutil import json import os -import shutil +from datetime import datetime, timezone def get_date_fields(): # Run git commands and capture as string output = subprocess.run(['git', 'log', '--date=iso', '--pretty=%cI', '--max-parents=0', '-n', '1'], capture_output=True, text=True) - + # Store string and strip of leading / trailing whitespace date = output.stdout.strip() + + # Parse the git timestamp and convert to UTC + git_date = datetime.fromisoformat(date) + utc_date = git_date.astimezone(timezone.utc) + created_date = utc_date.strftime('%Y-%m-%dT%H:%M:%SZ') + + # Generate current UTC timestamps using the new recommended method + current_utc = datetime.now(timezone.utc) + current_timestamp = current_utc.strftime('%Y-%m-%dT%H:%M:%SZ') # Create a dictionary for date information to be pushed to JSON - date_information = {"created": f"{date}", - "lastModified": "{% now 'utc', '%Y-%m-%dT%H:%M:%S%z' %}", - "metadataLastUpdated": "{% now 'utc', '%Y-%m-%dT%H:%M:%S%z' %}"} + date_information = { + "created": created_date, + "lastModified": current_timestamp, + "metadataLastUpdated": current_timestamp + } return date_information @@ -77,20 +88,26 @@ def update_code_json(json_file_path): data['laborHours'] = None # Check if usageType is an exemption - if data['permissions']['usageType'].startswith('exempt'): + contains_exempt = any("exempt" in item for item in data['permissions']['usageType']) + if contains_exempt: exemption_text = prompt_exemption_text(data['permissions']['usageType']) data['permissions']['exemptionText'] = exemption_text else: del data['permissions']['exemptionText'] # Format multi-select options - multi_select_fields = ["platforms", "categories", "languages", "tags", "feedbackMechanisms", "projects", "systems", "upstream", "subsetInHealthcare", "userType"] + multi_select_fields = ["platforms", "categories", "languages", "contractNumber", "tags", "projects", "systems", "subsetInHealthcare", "userType"] for field in multi_select_fields: data[field] = format_multi_select_fields(data[field][0]) # Format integer fields if data['reuseFrequency']['forks'].isdigit(): data['reuseFrequency']['forks'] = int(data['reuseFrequency']['forks']) + if data['reuseFrequency']['clones'].isdigit(): + data['reuseFrequency']['clones'] = int(data['reuseFrequency']['clones']) + + data['localisation'] = eval(data['localisation']) + data['userInput'] = eval(data['userInput']) # Update the JSON with open(json_file_path, 'w') as file: diff --git a/tier3/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json b/tier3/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json index 6ad69f7e..30d916a8 100644 --- a/tier3/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json +++ b/tier3/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json @@ -6,11 +6,12 @@ "permissions": { "licenses": [ { - "URL": "LICENSE", - "name": "{{ cookiecutter.license }}" + "name": "{{ cookiecutter.license }}", + "URL": "{{cookiecutter.license_url}}" + } ], - "usageType": "{{ cookiecutter.usage_type }}", + "usageType": [ "{{ cookiecutter.usage_type }}" ], "exemptionText": "" }, "organization": "Centers for Medicare & Medicaid Services", @@ -20,21 +21,24 @@ "vcs": "{{ cookiecutter.vcs }}", "laborHours": [""], "reuseFrequency": { - "forks": "{{ cookiecutter.forks }}" + "forks": "{{ cookiecutter.forks }}", + "clones": "{{ cookiecutter.clones }}" }, "platforms": [ "{{ cookiecutter.platforms }}" ], "categories": [ "{{ cookiecutter.categories }}" ], "softwareType": "{{ cookiecutter.software_type }}", "languages": [ "{{ cookiecutter.languages }}" ], "maintenance": "{{ cookiecutter.maintenance }}", - "contractNumber": "{{ cookiecutter.contract_number }}", + "contractNumber": [ "{{ cookiecutter.contract_number }}" ], + "SBOM": "{{ cookiecutter.sbom }}", "date": [""], "tags": [ "{{ cookiecutter.tags }}" ], "contact": { "email": "{{ cookiecutter.contact_email }}", "name": "{{ cookiecutter.contact_name }}" }, - "feedbackMechanisms": ["{{ cookiecutter.feedback_mechanisms }}"], + "feedbackMechanism": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/issues", + "AIUseCaseID": "{{ cookiecutter.ai_use_case_id }}", "localisation": "{{ cookiecutter.localisation }}", "repositoryType": "{{ cookiecutter.repository_type }}", "userInput": "{{ cookiecutter.user_input }}", @@ -42,7 +46,6 @@ "group": "{{ cookiecutter.group }}", "projects": ["{{ cookiecutter.projects }}"], "systems": ["{{ cookiecutter.systems }}"], - "upstream": ["{{ cookiecutter.upstream }}"], "subsetInHealthcare": ["{{ cookiecutter.subset_in_healthcare }}"], "userType": ["{{ cookiecutter.user_type }}"], "maturityModelTier": 3 diff --git a/tier3/{{cookiecutter.project_slug}}/.github/cookiecutter.json b/tier3/{{cookiecutter.project_slug}}/.github/cookiecutter.json index d19ce687..633db723 100644 --- a/tier3/{{cookiecutter.project_slug}}/.github/cookiecutter.json +++ b/tier3/{{cookiecutter.project_slug}}/.github/cookiecutter.json @@ -1,36 +1,38 @@ { "project_name": "{{ cookiecutter.project_name }}", - "project_repo_name": "{{ cookiecutter.project_repo_name }}", + "project_repo_name": "{{ cookiecutter.project_repo_name }}", "project_org": "{{ cookiecutter.project_org }}", "description": "A short description of the project.", "long_description": "A longer description of the project.", - "status": ["ideation", "development", "alpha", "beta", "release candidate", "production", "archival"], - "license": ["CC0-1.0", "Apache-2.0", "MIT", "MPL-2.0", "GPL-2.0-only", "GPL-3.0-only", "GPL-3.0-or-later", "LGPL-2.1-only", "LGPL-3.0-only", "BSD-2-Clause", "BSD-3-Clause", "EPL-2.0", "Other"], - "usage_type" : ["openSource", "governmentWideReuse", "exemptByLaw", "exemptByNationalSecurity", "exemptByAgencySystem", "exemptByAgencyMission", "exemptByCIO", "exemptByPolicyDate"], - "repository_host": ["github.com/CMSgov", "github.com/CMS-Enterprise", "github.com/DSACMS", "github.cms.gov", "CCSQ GitHub"], + "status": ["Ideation", "Development", "Alpha", "Beta", "Release Candidate", "Production", "Archival"], + "license": ["CC0-1.0", "Apache-2.0", "MIT", "MPL-2.0", "GPL-2.0-only", "GPL-3.0-only", "GPL-3.0-or-later", "LGPL-2.1-only", "LGPL-3.0-only", "BSD-2-Clause", "BSD-3-Clause", "EPL-2.0", "Other", "None"], + "license_url": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/blob/main/LICENSE", + "usage_type" : ["openSource", "governmentWideReuse", "exemptByNationalSecurity", "exemptByNationalIntelligence", "exemptByFOIA", "exemptByEAR", "exemptByITAR", "exemptByTSA", "exemptByClassifiedInformation", "exemptByPrivacyRisk", "exemptByIPRestriction", "exemptByAgencySystem", "exemptByAgencyMission", "exemptByCIO", "exemptByPolicyDate"], + "repository_host": ["github.com/CMSgov", "github.com/CMS-Enterprise", "github.com/Enterprise-CMCS", "github.com/DSACMS", "github.cms.gov", "CCSQ GitHub"], "repository_visibility": ["public", "private"], "vcs": ["git", "hg", "svn", "rcs", "bzr"], "forks": 0, + "clones": 0, "platforms": "web, windows, mac, linux, ios, android, other", "categories": "healthcare", "software_type":["standalone/mobile", "standalone/iot", "standalone/desktop", "standalone/web", "standalone/backend", "standalone/other", "addon", "library", "configurationFiles"], "languages": "", "maintenance": ["internal", "contract", "community", "none"], - "contract_number": 0, - "tags": "dsacms-tier3", + "contract_number": "", + "sbom": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/network/dependencies", + "tags": "dsacms-tier0", "contact_email": "opensource@cms.hhs.gov", "contact_name": "CMS Open Source Program Office", - "feedback_mechanisms": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/issues", - "localisation": ["true", "false"], - "repository_type" : ["Package", "Website", "Standards", "Libraries", "Data", "Apps", "Tools", "APIs", "Docs"], - "user_input": ["Yes", "No"], - "fisma_level": ["Low", "Moderate", "High"], + "ai_use_case_id": "0", + "localisation": [true, false], + "repository_type" : ["package", "website", "standards", "libraries", "data", "apps", "tools", "APIs"], + "user_input": [true, false], + "fisma_level": ["low", "moderate", "high"], "group": "CMS/OA/DSAC", "projects": "", "systems": "", - "upstream": "", - "subset_in_healthcare": "Policy, Operational, Medicare, Medicaid", - "user_type": "Providers, Patients, Government", + "subset_in_healthcare": "policy, operational, medicare, medicaid", + "user_type": "providers, patients, government", "__prompts__": { "project_name": "What is the name of the project or software?", "project_repo_name": "What is the name of the repository?", @@ -39,20 +41,23 @@ "long_description": "Provide longer description of the software, between 150 and 10000 chars. It is meant to provide an overview of the capabilities of the software for a potential user.", "status": "What is the status of the project?", "license": "What license is the project under?", + "license_url": "What is the URL to the license?", "usage_type": "What is the usage type for this project? For more information on each option, visit github.com/DSACMS/gov-codejson", "repository_host": "Where is the repository hosted?", "vcs": "What version control system is used?", "forks": "How many forks does the repository have?", + "clones": "How many clones does the repository have?", "platforms": "What platform does the software runs on? Separate items by commas.", "categories": "What categories best describes the project? Separate items by commas. List of categories here: https://yml.publiccode.tools/categories-list.html?highlight=categories", "software_type": "What type of software is the project?", "languages": "What programming language(s) is the software written in? Separate items by commas.", "maintenance": "How is the software maintained?", - "contract_number": "What is the contractor number of the project?", + "contract_number": "What is the contractor number(s) of the project? Separate items by commas.", + "sbom": "Provide a link to the SBOM of the repository. If the software does not have a SBOM, enter 'None'.", "tags": "Provide a list of tags to describe the software for search. Separate items by commas.", "contact_name": "A point of contact is needed for the project. What is the name of the point of contact?", "contact_email": "What is email address of the point of contact?", - "feedback_mechanisms": "What are methods a repository receives feedback from the community (e.g. URL to GitHub repository issues page, website, email)", + "ai_use_case_id": "What is the software's ID in the AI Use Case Inventory? If the software is not listed in the inventory, enter '0'.", "localisation": "Does the software support multiple spoken languages?", "repository_type": "What type of repository is this project?", "user_input": "Does the project accept user input? (e.g. allows user to query a database, allows login by users, upload files, etc.)", @@ -60,8 +65,7 @@ "group": "Which group at CMS is the project part of?", "projects": "What project is the repository associated with? Separate items by commas.", "systems": "What systems does the repository use or interface with? Separate items by commas.", - "upstream": "What upstream dependencies does the repository use? Separate items by commas.", - "subset_in_healthcare": "Which subset of healthcare does the project belong to?", - "user_type": "Who are the intended users?" + "subset_in_healthcare": "Which subset of healthcare does the project belong to? Separate items by commas.", + "user_type": "Who are the intended users? Separate items by commas." } } \ No newline at end of file diff --git a/tier4/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py b/tier4/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py index ea2bc849..f175d80a 100644 --- a/tier4/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py +++ b/tier4/{{cookiecutter.project_slug}}/.github/codejson/hooks/post_gen_project.py @@ -2,19 +2,30 @@ import shutil import json import os -import shutil +from datetime import datetime, timezone def get_date_fields(): # Run git commands and capture as string output = subprocess.run(['git', 'log', '--date=iso', '--pretty=%cI', '--max-parents=0', '-n', '1'], capture_output=True, text=True) - + # Store string and strip of leading / trailing whitespace date = output.stdout.strip() + + # Parse the git timestamp and convert to UTC + git_date = datetime.fromisoformat(date) + utc_date = git_date.astimezone(timezone.utc) + created_date = utc_date.strftime('%Y-%m-%dT%H:%M:%SZ') + + # Generate current UTC timestamps using the new recommended method + current_utc = datetime.now(timezone.utc) + current_timestamp = current_utc.strftime('%Y-%m-%dT%H:%M:%SZ') # Create a dictionary for date information to be pushed to JSON - date_information = {"created": f"{date}", - "lastModified": "{% now 'utc', '%Y-%m-%dT%H:%M:%S%z' %}", - "metadataLastUpdated": "{% now 'utc', '%Y-%m-%dT%H:%M:%S%z' %}"} + date_information = { + "created": created_date, + "lastModified": current_timestamp, + "metadataLastUpdated": current_timestamp + } return date_information @@ -77,20 +88,26 @@ def update_code_json(json_file_path): data['laborHours'] = None # Check if usageType is an exemption - if data['permissions']['usageType'].startswith('exempt'): + contains_exempt = any("exempt" in item for item in data['permissions']['usageType']) + if contains_exempt: exemption_text = prompt_exemption_text(data['permissions']['usageType']) data['permissions']['exemptionText'] = exemption_text else: del data['permissions']['exemptionText'] # Format multi-select options - multi_select_fields = ["platforms", "categories", "languages", "tags", "feedbackMechanisms", "projects", "systems", "upstream", "subsetInHealthcare", "userType"] + multi_select_fields = ["platforms", "categories", "languages", "contractNumber", "tags", "projects", "systems", "subsetInHealthcare", "userType"] for field in multi_select_fields: data[field] = format_multi_select_fields(data[field][0]) # Format integer fields if data['reuseFrequency']['forks'].isdigit(): data['reuseFrequency']['forks'] = int(data['reuseFrequency']['forks']) + if data['reuseFrequency']['clones'].isdigit(): + data['reuseFrequency']['clones'] = int(data['reuseFrequency']['clones']) + + data['localisation'] = eval(data['localisation']) + data['userInput'] = eval(data['userInput']) # Update the JSON with open(json_file_path, 'w') as file: diff --git a/tier4/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json b/tier4/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json index b053c60c..2e9edaf4 100644 --- a/tier4/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json +++ b/tier4/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json @@ -6,11 +6,12 @@ "permissions": { "licenses": [ { - "URL": "LICENSE", - "name": "{{ cookiecutter.license }}" + "name": "{{ cookiecutter.license }}", + "URL": "{{cookiecutter.license_url}}" + } ], - "usageType": "{{ cookiecutter.usage_type }}", + "usageType": [ "{{ cookiecutter.usage_type }}" ], "exemptionText": "" }, "organization": "Centers for Medicare & Medicaid Services", @@ -20,21 +21,24 @@ "vcs": "{{ cookiecutter.vcs }}", "laborHours": [""], "reuseFrequency": { - "forks": "{{ cookiecutter.forks }}" + "forks": "{{ cookiecutter.forks }}", + "clones": "{{ cookiecutter.clones }}" }, "platforms": [ "{{ cookiecutter.platforms }}" ], "categories": [ "{{ cookiecutter.categories }}" ], "softwareType": "{{ cookiecutter.software_type }}", "languages": [ "{{ cookiecutter.languages }}" ], "maintenance": "{{ cookiecutter.maintenance }}", - "contractNumber": "{{ cookiecutter.contract_number }}", + "contractNumber": [ "{{ cookiecutter.contract_number }}" ], + "SBOM": "{{ cookiecutter.sbom }}", "date": [""], "tags": [ "{{ cookiecutter.tags }}" ], "contact": { "email": "{{ cookiecutter.contact_email }}", "name": "{{ cookiecutter.contact_name }}" }, - "feedbackMechanisms": ["{{ cookiecutter.feedback_mechanisms }}"], + "feedbackMechanism": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/issues", + "AIUseCaseID": "{{ cookiecutter.ai_use_case_id }}", "localisation": "{{ cookiecutter.localisation }}", "repositoryType": "{{ cookiecutter.repository_type }}", "userInput": "{{ cookiecutter.user_input }}", @@ -42,7 +46,6 @@ "group": "{{ cookiecutter.group }}", "projects": ["{{ cookiecutter.projects }}"], "systems": ["{{ cookiecutter.systems }}"], - "upstream": ["{{ cookiecutter.upstream }}"], "subsetInHealthcare": ["{{ cookiecutter.subset_in_healthcare }}"], "userType": ["{{ cookiecutter.user_type }}"], "maturityModelTier": 4 diff --git a/tier4/{{cookiecutter.project_slug}}/.github/cookiecutter.json b/tier4/{{cookiecutter.project_slug}}/.github/cookiecutter.json index b5710a91..633db723 100644 --- a/tier4/{{cookiecutter.project_slug}}/.github/cookiecutter.json +++ b/tier4/{{cookiecutter.project_slug}}/.github/cookiecutter.json @@ -1,36 +1,38 @@ { "project_name": "{{ cookiecutter.project_name }}", - "project_repo_name": "{{ cookiecutter.project_repo_name }}", + "project_repo_name": "{{ cookiecutter.project_repo_name }}", "project_org": "{{ cookiecutter.project_org }}", "description": "A short description of the project.", "long_description": "A longer description of the project.", - "status": ["ideation", "development", "alpha", "beta", "release candidate", "production", "archival"], - "license": ["CC0-1.0", "Apache-2.0", "MIT", "MPL-2.0", "GPL-2.0-only", "GPL-3.0-only", "GPL-3.0-or-later", "LGPL-2.1-only", "LGPL-3.0-only", "BSD-2-Clause", "BSD-3-Clause", "EPL-2.0", "Other"], - "usage_type" : ["openSource", "governmentWideReuse", "exemptByLaw", "exemptByNationalSecurity", "exemptByAgencySystem", "exemptByAgencyMission", "exemptByCIO", "exemptByPolicyDate"], - "repository_host": ["github.com/CMSgov", "github.com/CMS-Enterprise", "github.com/DSACMS", "github.cms.gov", "CCSQ GitHub"], + "status": ["Ideation", "Development", "Alpha", "Beta", "Release Candidate", "Production", "Archival"], + "license": ["CC0-1.0", "Apache-2.0", "MIT", "MPL-2.0", "GPL-2.0-only", "GPL-3.0-only", "GPL-3.0-or-later", "LGPL-2.1-only", "LGPL-3.0-only", "BSD-2-Clause", "BSD-3-Clause", "EPL-2.0", "Other", "None"], + "license_url": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/blob/main/LICENSE", + "usage_type" : ["openSource", "governmentWideReuse", "exemptByNationalSecurity", "exemptByNationalIntelligence", "exemptByFOIA", "exemptByEAR", "exemptByITAR", "exemptByTSA", "exemptByClassifiedInformation", "exemptByPrivacyRisk", "exemptByIPRestriction", "exemptByAgencySystem", "exemptByAgencyMission", "exemptByCIO", "exemptByPolicyDate"], + "repository_host": ["github.com/CMSgov", "github.com/CMS-Enterprise", "github.com/Enterprise-CMCS", "github.com/DSACMS", "github.cms.gov", "CCSQ GitHub"], "repository_visibility": ["public", "private"], "vcs": ["git", "hg", "svn", "rcs", "bzr"], "forks": 0, + "clones": 0, "platforms": "web, windows, mac, linux, ios, android, other", "categories": "healthcare", "software_type":["standalone/mobile", "standalone/iot", "standalone/desktop", "standalone/web", "standalone/backend", "standalone/other", "addon", "library", "configurationFiles"], "languages": "", "maintenance": ["internal", "contract", "community", "none"], - "contract_number": 0, - "tags": "dsacms-tier4", + "contract_number": "", + "sbom": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/network/dependencies", + "tags": "dsacms-tier0", "contact_email": "opensource@cms.hhs.gov", "contact_name": "CMS Open Source Program Office", - "feedback_mechanisms": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/issues", - "localisation": ["true", "false"], - "repository_type" : ["Package", "Website", "Standards", "Libraries", "Data", "Apps", "Tools", "APIs", "Docs"], - "user_input": ["Yes", "No"], - "fisma_level": ["Low", "Moderate", "High"], + "ai_use_case_id": "0", + "localisation": [true, false], + "repository_type" : ["package", "website", "standards", "libraries", "data", "apps", "tools", "APIs"], + "user_input": [true, false], + "fisma_level": ["low", "moderate", "high"], "group": "CMS/OA/DSAC", "projects": "", "systems": "", - "upstream": "", - "subset_in_healthcare": "Policy, Operational, Medicare, Medicaid", - "user_type": "Providers, Patients, Government", + "subset_in_healthcare": "policy, operational, medicare, medicaid", + "user_type": "providers, patients, government", "__prompts__": { "project_name": "What is the name of the project or software?", "project_repo_name": "What is the name of the repository?", @@ -39,20 +41,23 @@ "long_description": "Provide longer description of the software, between 150 and 10000 chars. It is meant to provide an overview of the capabilities of the software for a potential user.", "status": "What is the status of the project?", "license": "What license is the project under?", + "license_url": "What is the URL to the license?", "usage_type": "What is the usage type for this project? For more information on each option, visit github.com/DSACMS/gov-codejson", "repository_host": "Where is the repository hosted?", "vcs": "What version control system is used?", "forks": "How many forks does the repository have?", + "clones": "How many clones does the repository have?", "platforms": "What platform does the software runs on? Separate items by commas.", "categories": "What categories best describes the project? Separate items by commas. List of categories here: https://yml.publiccode.tools/categories-list.html?highlight=categories", "software_type": "What type of software is the project?", "languages": "What programming language(s) is the software written in? Separate items by commas.", "maintenance": "How is the software maintained?", - "contract_number": "What is the contractor number of the project?", + "contract_number": "What is the contractor number(s) of the project? Separate items by commas.", + "sbom": "Provide a link to the SBOM of the repository. If the software does not have a SBOM, enter 'None'.", "tags": "Provide a list of tags to describe the software for search. Separate items by commas.", "contact_name": "A point of contact is needed for the project. What is the name of the point of contact?", "contact_email": "What is email address of the point of contact?", - "feedback_mechanisms": "What are methods a repository receives feedback from the community (e.g. URL to GitHub repository issues page, website, email)", + "ai_use_case_id": "What is the software's ID in the AI Use Case Inventory? If the software is not listed in the inventory, enter '0'.", "localisation": "Does the software support multiple spoken languages?", "repository_type": "What type of repository is this project?", "user_input": "Does the project accept user input? (e.g. allows user to query a database, allows login by users, upload files, etc.)", @@ -60,8 +65,7 @@ "group": "Which group at CMS is the project part of?", "projects": "What project is the repository associated with? Separate items by commas.", "systems": "What systems does the repository use or interface with? Separate items by commas.", - "upstream": "What upstream dependencies does the repository use? Separate items by commas.", - "subset_in_healthcare": "Which subset of healthcare does the project belong to?", - "user_type": "Who are the intended users?" + "subset_in_healthcare": "Which subset of healthcare does the project belong to? Separate items by commas.", + "user_type": "Who are the intended users? Separate items by commas." } } \ No newline at end of file