Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions .github/codejson/cookiecutter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{
"project_name": "cms-bb2-node-sdk",
"project_repo_name": "cms-bb2-node-sdk",
"project_org": "CMSgov",
"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"],
"repository_visibility": ["public", "private"],
"vcs": ["git", "hg", "svn", "rcs", "bzr"],
"forks": 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",
"contact_email": "opensource@cms.hhs.gov",
"contact_name": "CMS Open Source Program Office",
"feedback_mechanisms": "https://github.com/CMSgov/cms-bb2-node-sdk/issues",
"localisation": ["true", "false"],
"repository_type" : ["Package", "Website", "Standards", "Libraries", "Data", "Apps", "Tools", "APIs", "Docs"],
"user_input": ["Yes", "No"],
"fisma_level": ["Low", "Moderate", "High"],
"group": "CMS/OA/DSAC",
"projects": "",
"systems": "",
"upstream": "",
"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?",
"project_org": "What CMS GitHub organization is it under?",
"description": "Provide a short description of the software. It should be a single line containing a single sentence. Maximum 150 characters are allowed.",
"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?",
"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?",
"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?",
"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)",
"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.)",
"fisma_level": "What FISMA level is this project classified as? Learn more: https://security.cms.gov/learn/federal-information-security-modernization-act-fisma#perform-system-risk-categorization",
"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?"
}
}
139 changes: 139 additions & 0 deletions .github/codejson/hooks/post_gen_project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import subprocess
import shutil
import json
import os
import shutil

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()

# 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' %}"}

return date_information

def get_scc_labor_hours():
if shutil.which('scc') is not None:
try:
#Run scc and load results into a dictionary
#assuming we are in the .git directory of the repo
cmd = ['scc', '..', '--format', 'json2', '--exclude-file']

# Currently only supports specific files
files_to_exclude = [
"checks.yml,auto-changelog.yml,contributors.yml,repoStructure.yml,code.json,checklist.md,checklist.pdf,README.md,CONTRIBUTING.md,LICENSE,repolinter.json,SECURITY.md,CODE_OF_CONDUCT.md,CODEOWNERS.md,COMMUNITY.md,GOVERNANCE.md"
]

cmd.extend(files_to_exclude)

d = json.loads(subprocess.run(cmd,check=True, capture_output=True).stdout)

l_hours = d['estimatedScheduleMonths'] * 730.001

return round(l_hours,2)

except (subprocess.CalledProcessError, KeyError) as e:
print(e)
return None
else:
print("scc (https://github.com/boyter/scc) not found on system")

#Otherwise just use previous value as a default value.
return None

def prompt_exemption_text(exemptionType):
print(f"ℹ️ You have selected {exemptionType} for your Usage Type.")
return input("Please provide a one or two sentence justification for the exemption used. For more information on Usage Type, visit github.com/DSACMS/gov-codejson: ")

def format_multi_select_fields(text):
if text == "":
return []

new_text = text.split(",")

new_text = [text.strip() for text in new_text]

return new_text

def update_code_json(json_file_path):
# Read the JSON
with open(json_file_path, 'r') as file:
data = json.load(file)

# Add date_information and labor hours to the JSON
data['date'] = get_date_fields()

# Calculate labor hours
hours = get_scc_labor_hours()
if hours:
data['laborHours'] = hours
else:
data['laborHours'] = None

# Check if usageType is an exemption
if data['permissions']['usageType'].startswith('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"]
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'])

# Update the JSON
with open(json_file_path, 'w') as file:
json.dump(data, file, indent = 2)

def main():
try:
# Change to the parent directory
os.chdir('..')

# Define the codejson directory to remove
dir_name = "codejson"

# Check if codejson directory exists and remove it
if os.path.exists(dir_name):
shutil.rmtree(dir_name)

# Get the project name from cookiecutter
sub_project_dir = "{{cookiecutter.project_name}}"
codejson_file = "code.json"
project_root_dir = os.path.abspath('..')

json_file_path = os.path.join(sub_project_dir, codejson_file)

if os.path.exists(json_file_path):
# Move code.json file to parent directory
new_json_path = os.path.join(project_root_dir, codejson_file)
shutil.move(json_file_path, new_json_path)

# Remove the source directory
shutil.rmtree(sub_project_dir)

# Update the json with date and scc information
update_code_json(new_json_path)
print("Succesfully generated code.json file!")

else:
print(f"Error: {codejson_file} not found in {sub_project_dir}")

except OSError as error:
print(f"Error during OS operations: {error}")
except shutil.Error as error:
print(f"Error during shutil operations: {error}")

if __name__ == "__main__":
main()
5 changes: 5 additions & 0 deletions .github/codejson/hooks/pre_prompt.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

echo -e "⚙️ Welcome to the code.json cookiecutter CLI."
echo -e "📝 We will assist you with creating a code.json file to store metadata of your project."
echo -e "ℹ️ Visit www.github.com/DSACMS/gov-codejson for more information."
49 changes: 49 additions & 0 deletions .github/codejson/{{cookiecutter.project_name}}/code.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "{{ cookiecutter.project_name }}",
"description": "{{ cookiecutter.description }}",
"longDescription": "{{ cookiecutter.long_description }}",
"status": "{{ cookiecutter.status }}",
"permissions": {
"licenses": [
{
"URL": "LICENSE",
"name": "{{ cookiecutter.license }}"
}
],
"usageType": "{{ cookiecutter.usage_type }}",
"exemptionText": ""
},
"organization": "Centers for Medicare & Medicaid Services",
"repositoryURL": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}",
"repositoryHost": "{{ cookiecutter.repository_host }}",
"repositoryVisibility": "{{ cookiecutter.repository_visibility}}",
"vcs": "{{ cookiecutter.vcs }}",
"laborHours": [""],
"reuseFrequency": {
"forks": "{{ cookiecutter.forks }}"
},
"platforms": [ "{{ cookiecutter.platforms }}" ],
"categories": [ "{{ cookiecutter.categories }}" ],
"softwareType": "{{ cookiecutter.software_type }}",
"languages": [ "{{ cookiecutter.languages }}" ],
"maintenance": "{{ cookiecutter.maintenance }}",
"contractNumber": "{{ cookiecutter.contract_number }}",
"date": [""],
"tags": [ "{{ cookiecutter.tags }}" ],
"contact": {
"email": "{{ cookiecutter.contact_email }}",
"name": "{{ cookiecutter.contact_name }}"
},
"feedbackMechanisms": ["{{ cookiecutter.feedback_mechanisms }}"],
"localisation": "{{ cookiecutter.localisation }}",
"repositoryType": "{{ cookiecutter.repository_type }}",
"userInput": "{{ cookiecutter.user_input }}",
"fismaLevel": "{{ cookiecutter.fisma_level }}",
"group": "{{ cookiecutter.group }}",
"projects": ["{{ cookiecutter.projects }}"],
"systems": ["{{ cookiecutter.systems }}"],
"upstream": ["{{ cookiecutter.upstream }}"],
"subsetInHealthcare": ["{{ cookiecutter.subset_in_healthcare }}"],
"userType": ["{{ cookiecutter.user_type }}"],
"maturityModelTier": 3
}
15 changes: 15 additions & 0 deletions .github/workflows/auto-changelog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Changelog
on:
release:
types:
- created
jobs:
changelog:
runs-on: ubuntu-latest
steps:
- name: "Auto Generate changelog"
uses: heinrichreimer/action-github-changelog-generator@v2.3
with:

token: ${{ secrets.GITHUB_TOKEN }}

78 changes: 78 additions & 0 deletions .github/workflows/contributors.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: Update Contributors Information

on:
workflow_dispatch: {}
schedule:
# Weekly on Saturdays.
- cron: "30 1 * * 6"
push:
branches: [main]

jobs:
update-contributors:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Update contributor list
id: contrib_list
uses: akhilmhdh/contributors-readme-action@v2.3.10
env:

GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

with:
readme_path: COMMUNITY.md
use_username: false
commit_message: "update contributors information"

- name: Get contributors count
id: get_contributors
env:

GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


run: |
OWNER=$(echo $GITHUB_REPOSITORY | cut -d'/' -f1)
REPO=$(echo $GITHUB_REPOSITORY | cut -d'/' -f2)
QUERY='query { repository(owner: \"'"$OWNER"'\", name: \"'"$REPO"'\") { collaborators { totalCount } } }'

CONTRIBUTORS=$(gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/$OWNER/$REPO/contributors?per_page=100" | \
jq '[.[] | select(.type != "Bot" and (.login | test("\\[bot\\]$") | not) and (.login | test("-bot$") | not))] | length')

echo "Total contributors: $CONTRIBUTORS"
echo "contributors=$CONTRIBUTORS" >> $GITHUB_OUTPUT


- name: Update COMMUNITY.md
run: |

CONTRIBUTORS="${{ steps.get_contributors.outputs.contributors }}"


perl -i -pe 's/(<!--CONTRIBUTOR COUNT START-->).*?(<!--CONTRIBUTOR COUNT END-->)/$1 '"$CONTRIBUTORS"' $2/' COMMUNITY.md

git config user.name 'github-actions[bot]'
git config user.email 'github-actions[bot]@users.noreply.github.com'
git add COMMUNITY.md
git commit -m "update contributors count to $CONTRIBUTORS" || exit 0

- name: Push protected
uses: CasperWA/push-protected@v2
with:

token: ${{ secrets.PUSH_TO_PROTECTED_BRANCH }}


branch: main
15 changes: 15 additions & 0 deletions .github/workflows/gitleaks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Check for Secrets
on:
pull_request:
push:

jobs:
scan-for-secrets:
name: Run gitleaks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with: {fetch-depth: 0}

- name: Check for GitLeaks
uses: gacts/gitleaks@v1
17 changes: 17 additions & 0 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title = "BB2-PYTHON-SDK Gitleaks Config"

[extend]
# useDefault will extend the base configuration with the default gitleaks config:
# https://github.com/zricethezav/gitleaks/blob/master/config/gitleaks.toml
useDefault = true

[allowlist]
# Recommended practice is to add your secrets to a regexes array,
# not to a commits array.
regexTarget = "match"
description = "whitelist public and test secrets"
regexes = [
'''a''',
'''v''',
'''c''',
]
Loading