├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── actions.md ├── addingFile │ ├── action.yml │ └── lintInput.sh ├── extendJSON │ ├── action.yml │ └── resolve.py ├── fileUpdater │ ├── action.yml │ └── update.sh ├── findRepos │ ├── action.yml │ └── find.sh ├── pull_request_template.md └── workflows │ ├── addFilesToRepos.yml │ ├── auto-changelog.yml │ ├── autoMergeMainIntoDev.yml │ ├── checklistMarkdownToPDF.yml │ ├── contributors.yml │ ├── extendJSONFile.yml │ ├── gitleaks.yml │ ├── repoHygieneCheck.yml │ ├── updateCodeJSON.yml │ └── updateStringInRepos.yml ├── .gitignore ├── CHANGELOG.md ├── CODEOWNERS.md ├── CODE_OF_CONDUCT.md ├── COMMUNITY.md ├── COMMUNITY_GUIDELINES.md ├── CONTRIBUTING.md ├── GOVERNANCE.md ├── LICENSE ├── README.md ├── SECURITY.md ├── assets ├── css │ └── styles.css ├── images │ ├── auto-generator.svg │ ├── cms-white.svg │ ├── dsacms.svg │ ├── flowchart.png │ ├── form-generator.svg │ ├── hhs-white.svg │ ├── index-generator.svg │ ├── maturity-model-trees-graphic-horizontal.png │ ├── metrics.svg │ ├── repo-scaffolder.svg │ ├── repolinter-results.png │ ├── repolinter.svg │ ├── tier0-tree.svg │ ├── tier1-tree.svg │ ├── tier2-tree.svg │ ├── tier3-tree.svg │ └── tier4-tree.svg └── js │ ├── main.js │ └── quizHandler.js ├── code.json ├── docs └── .github-directory.md ├── index.html ├── maturity-model-tiers.md ├── maturity-model-tiers.pdf ├── release-guidelines-template.md ├── requirements.txt ├── tier-determiner.py ├── tier0 ├── README.md ├── cookiecutter.json ├── hooks │ ├── post_gen_project.py │ └── pre_prompt.sh └── {{cookiecutter.project_slug}} │ ├── .github │ ├── ISSUE_TEMPLATE │ │ └── code_json_request.md │ ├── codejson │ │ ├── hooks │ │ │ ├── post_gen_project.py │ │ │ └── pre_prompt.sh │ │ └── {{cookiecutter.project_name}} │ │ │ └── code.json │ └── cookiecutter.json │ ├── COMMUNITY.md │ ├── LICENSE │ ├── README.md │ └── repolinter.json ├── tier1 ├── README.md ├── checklist.md ├── checklist.pdf ├── cookiecutter.json ├── hooks │ ├── post_gen_project.py │ └── pre_prompt.sh └── {{cookiecutter.project_slug}} │ ├── .github │ ├── ISSUE_TEMPLATE │ │ └── code_json_request.md │ ├── codejson │ │ ├── hooks │ │ │ ├── post_gen_project.py │ │ │ └── pre_prompt.sh │ │ └── {{cookiecutter.project_name}} │ │ │ └── code.json │ ├── cookiecutter.json │ └── workflows │ │ ├── gitleaks.yml │ │ └── repoHygieneCheck.yml │ ├── COMMUNITY.md │ ├── CONTRIBUTING.md │ ├── LICENSE │ ├── README.md │ ├── SECURITY.md │ └── repolinter.json ├── tier2 ├── README.md ├── checklist.md ├── checklist.pdf ├── cookiecutter.json ├── hooks │ ├── post_gen_project.py │ └── pre_prompt.sh └── {{cookiecutter.project_slug}} │ ├── .github │ ├── CODEOWNERS.md │ ├── ISSUE_TEMPLATE │ │ ├── add_team_request.md │ │ ├── code_json_request.md │ │ └── outside_collaborator_request.md │ ├── codejson │ │ ├── hooks │ │ │ ├── post_gen_project.py │ │ │ └── pre_prompt.sh │ │ └── {{cookiecutter.project_name}} │ │ │ └── code.json │ ├── cookiecutter.json │ └── workflows │ │ ├── auto-changelog.yml │ │ ├── contributors.yml │ │ ├── gitleaks.yml │ │ └── repoHygieneCheck.yml │ ├── CODE_OF_CONDUCT.md │ ├── COMMUNITY.md │ ├── CONTRIBUTING.md │ ├── LICENSE │ ├── README.md │ ├── SECURITY.md │ └── repolinter.json ├── tier3 ├── README.md ├── checklist.md ├── checklist.pdf ├── cookiecutter.json ├── hooks │ ├── post_gen_project.py │ └── pre_prompt.sh └── {{cookiecutter.project_slug}} │ ├── .github │ ├── CODEOWNERS.md │ ├── ISSUE_TEMPLATE │ │ ├── add_team_request.md │ │ ├── code_json_request.md │ │ └── outside_collaborator_request.md │ ├── codejson │ │ ├── hooks │ │ │ ├── post_gen_project.py │ │ │ └── pre_prompt.sh │ │ └── {{cookiecutter.project_name}} │ │ │ └── code.json │ ├── cookiecutter.json │ └── workflows │ │ ├── auto-changelog.yml │ │ ├── contributors.yml │ │ ├── gitleaks.yml │ │ ├── repoHygieneCheck.yml │ │ └── repoStructure.yml │ ├── CODE_OF_CONDUCT.md │ ├── COMMUNITY.md │ ├── CONTRIBUTING.md │ ├── GOVERNANCE.md │ ├── LICENSE │ ├── README.md │ ├── SECURITY.md │ └── repolinter.json └── tier4 ├── README.md ├── checklist.md ├── checklist.pdf ├── cookiecutter.json ├── hooks ├── post_gen_project.py └── pre_prompt.sh └── {{cookiecutter.project_slug}} ├── .github ├── CODEOWNERS.md ├── ISSUE_TEMPLATE │ ├── add_team_request.md │ ├── code_json_request.md │ └── outside_collaborator_request.md ├── codejson │ ├── hooks │ │ ├── post_gen_project.py │ │ └── pre_prompt.sh │ └── {{cookiecutter.project_name}} │ │ └── code.json ├── cookiecutter.json └── workflows │ ├── auto-changelog.yml │ ├── contributors.yml │ ├── gitleaks.yml │ ├── repoHygieneCheck.yml │ └── repoStructure.yml ├── CODE_OF_CONDUCT.md ├── COMMUNITY.md ├── CONTRIBUTING.md ├── GOVERNANCE.md ├── LICENSE ├── README.md ├── SECURITY.md └── repolinter.json /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/actions.md: -------------------------------------------------------------------------------- 1 | # Reusable Actions 2 | 3 | This repository contains resusable actions and workflow to push updates to repositories. 4 | 5 | ## Finding Repos (Action) 6 | The [find repos action](https://github.com/DSACMS/repo-scaffolder/blob/main/.github/findRepos/action.yml) takes a [github topic](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/classifying-your-repository-with-topics) and a [github org](https://docs.github.com/en/organizations/collaborating-with-groups-in-organizations/about-organizations) as input. It 7 | then queries the github apis with these values to find the repos. 8 | 9 | ## Updating Files 10 | The [updateStringInRepos](https://github.com/DSACMS/repo-scaffolder/blob/main/.github/workflows/updateStringInRepos.yml) workflow takes a github topic, github org, a string to find, a string to replace the found string with, and a file to find that string in. Then it raises a pull request in the repos it finds with the string in that file. It can be triggered from this repo using the [workflow dispatch](https://docs.github.com/en/actions/using-workflows/manually-running-a-workflow#running-a-workflow). This workflow can be used as a reusable workflow. 11 | 12 | ## Adding Files 13 | The [addFilesToRepos](https://github.com/DSACMS/repo-scaffolder/blob/main/.github/workflows/addFilesToRepos.yml) workflow takes a github topic, github org, and a file to add to the repo. It then raises a pull request in the repos it finds with the file to add. It can be triggered from this repo using the [workflow dispatch](https://docs.github.com/en/actions/using-workflows/manually-running-a-workflow#running-a-workflow). This workflow can be used as a reusable workflow. 14 | 15 | ## Resolve Extended JSON Files 16 | The [extendJSON](https://github.com/DSACMS/repo-scaffolder/blob/main/.github/workflows/extendJSONFile.yml) workflow takes the path of the desired repolinter.json. It then computes all of the rules in all of the references JSON files in the `extends` tag and updates them to the proper tier before returning the info as one JSON file. It returns the contents of the file via environment variable in the same way that the findRepos one does. It can be triggered from this repo using the [workflow dispatch](https://docs.github.com/en/actions/using-workflows/manually-running-a-workflow#running-a-workflow). This workflow can be used as a reusable workflow. -------------------------------------------------------------------------------- /.github/addingFile/action.yml: -------------------------------------------------------------------------------- 1 | name: 'addingFiles' 2 | 3 | description: 'Adds files to git' 4 | 5 | inputs: 6 | files: 7 | description: File or folder to add 8 | required: true 9 | commit-message: 10 | description: Commit message when raising pr 11 | default: "chore: adding files" 12 | required: false 13 | branch-name: 14 | description: Branch name when raising pr 15 | default: chore/add-files 16 | required: false 17 | title: 18 | description: Title of raised pr 19 | default: 'chore: adding files' 20 | required: false 21 | body: 22 | description: Body of raised pr 23 | default: Adding files 24 | required: false 25 | labels: 26 | description: Lavels for pr (separated by new line) 27 | default: automated pr 28 | required: false 29 | token: 30 | description: Access token to push and raise pr 31 | required: true 32 | 33 | 34 | runs: 35 | using: 'composite' 36 | steps: 37 | - name: Check file or folder exists 38 | run: | 39 | ${{ github.action_path }}/lintInput.sh ${{ inputs.files }} 40 | shell: bash 41 | - name: Checkout target repository 42 | uses: actions/checkout@v4 43 | with: 44 | repository: ${{ inputs.repository }} 45 | ref: main 46 | fetch-depth: 0 47 | token: ${{ inputs.token }} 48 | - name: Checkout scaffolder inside target 49 | uses: actions/checkout@v4 50 | with: 51 | path: scaffolder 52 | - name: Configure git 53 | run: | 54 | git config user.name 'Github Action' 55 | git config user.email 'github-action@users.noreply.github.com' 56 | shell: bash 57 | - name: Copy over files 58 | run: | 59 | cp -R scaffolder/${{ inputs.files }} ./ 60 | rm -rf scaffolder 61 | ls 62 | git add --all 63 | shell: bash 64 | - name: Create pull request 65 | uses: peter-evans/create-pull-request@v5 66 | with: 67 | token: ${{ inputs.token }} 68 | commit-message: ${{ inputs.commit-message }} 69 | branch: ${{ inputs.branch-name }} 70 | delete-branch: true 71 | title: ${{ inputs.title }} 72 | body: | 73 | ${{ inputs.body }} 74 | labels: | 75 | ${{ inputs.labels }} 76 | -------------------------------------------------------------------------------- /.github/addingFile/lintInput.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | location=$1 4 | 5 | if test -f $location; then 6 | echo "File exists." 7 | elif test -d $location; then 8 | echo "Directory exists." 9 | else 10 | echo "error: file or direcoty not found: " $1 >&2; exit 1 11 | fi 12 | -------------------------------------------------------------------------------- /.github/extendJSON/action.yml: -------------------------------------------------------------------------------- 1 | name: 'extendJSONRepolinter' 2 | 3 | description: 'Returns raw JSON given a file that uses the extends key' 4 | 5 | inputs: 6 | url_to_json: 7 | description: 'URL to JSON file' 8 | default: 'https://raw.githubusercontent.com/DSACMS/repo-scaffolder/main/tier1/%7B%7Bcookiecutter.project_slug%7D%7D/repolinter.json' 9 | required: true 10 | type: string 11 | outputs: 12 | raw-json: 13 | description: 'JSON of the file' 14 | value: ${{ steps.resolve-step.outputs.RAW_JSON }} 15 | 16 | runs: 17 | using: 'composite' 18 | steps: 19 | - uses: actions/setup-python@v4 20 | with: 21 | python-version: '3.9' 22 | 23 | - name: Install dependencies 24 | shell: bash 25 | run: pip install pydash 26 | 27 | - name: Extend JSON and write to env 28 | id: resolve-step 29 | run: | 30 | extended=$(python3 ${{ github.action_path }}/resolve.py ${{ inputs.url_to_json }}) 31 | echo $extended 32 | echo "RAW_JSON="$extended"" >> $GITHUB_OUTPUT 33 | shell: bash -------------------------------------------------------------------------------- /.github/extendJSON/resolve.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import json 3 | import pydash 4 | from urllib.request import urlopen, Request 5 | 6 | def get_json_dict_from_url(url): 7 | 8 | r = Request(url,headers={"Accept":"application/json"}) 9 | 10 | with urlopen(r) as response: 11 | #print(response.status) 12 | #print(response.read().decode()) 13 | text = response.read().decode() 14 | return json.loads(text) 15 | 16 | #recursively resolve json file data. 17 | def resolve_extended_json_file(file_data_dict): 18 | #print(file_data_dict) 19 | 20 | if 'extends' not in file_data_dict.keys(): 21 | #print("Got here.") 22 | #print(file_data_dict) 23 | return file_data_dict 24 | 25 | #fetch the dict that is in the 'extends' tag 26 | superJsonDict = get_json_dict_from_url(file_data_dict['extends']) 27 | 28 | del file_data_dict['extends'] 29 | 30 | resolve = resolve_extended_json_file(superJsonDict) 31 | 32 | pydash.merge(resolve, file_data_dict) 33 | 34 | resolve['rules'].update(file_data_dict) 35 | resolve['rules'].pop('axioms') 36 | resolve['rules'].pop('$schema') 37 | resolve['rules'].pop('version') 38 | resolve['rules'].pop('rules') 39 | 40 | return resolve 41 | 42 | #Grab base url 43 | baseUrl = sys.argv[1] 44 | 45 | print(json.dumps(resolve_extended_json_file(get_json_dict_from_url(baseUrl)))) -------------------------------------------------------------------------------- /.github/fileUpdater/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Update' 2 | 3 | description: 'Update strings' 4 | 5 | inputs: 6 | find: 7 | description: String to replace 8 | required: true 9 | replace: 10 | description: Replacement string 11 | required: true 12 | repository: 13 | description: Repository to update 14 | required: true 15 | file: 16 | description: File to replace in 17 | required: true 18 | commit-message: 19 | description: Commit message when raising pr 20 | default: "chore: updated string" 21 | required: false 22 | branch-name: 23 | description: Branch name when raising pr 24 | default: chore/update-string 25 | required: false 26 | title: 27 | description: Title of raised pr 28 | default: 'chore: updated string' 29 | required: false 30 | body: 31 | description: Body of raised pr 32 | default: Updated string 33 | required: false 34 | labels: 35 | description: Lavels for pr (separated by new line) 36 | default: automated pr 37 | required: false 38 | token: 39 | description: Access token to push and raise pr 40 | required: true 41 | 42 | runs: 43 | using: 'composite' 44 | steps: 45 | - name: Checkout target repository 46 | uses: actions/checkout@v4 47 | with: 48 | repository: ${{ inputs.repository }} 49 | ref: main 50 | fetch-depth: 0 51 | token: ${{ inputs.token }} 52 | - name: Checkout scaffolder inside target 53 | uses: actions/checkout@v4 54 | with: 55 | path: scaffolder 56 | - name: Update files 57 | run: | 58 | scaffolder/.github/fileUpdater/update.sh ${{ inputs.find }} ${{ inputs.replace }} ${{ inputs.file }} 59 | rm -rf scaffolder 60 | shell: bash 61 | - name: Create pull request 62 | uses: peter-evans/create-pull-request@v5 63 | with: 64 | token: ${{ inputs.token }} 65 | commit-message: ${{ inputs.commit-message }} 66 | branch: ${{ inputs.branch-name }} 67 | delete-branch: true 68 | title: ${{ inputs.title }} 69 | body: | 70 | ${{ inputs.body }} 71 | labels: | 72 | ${{ inputs.labels }} -------------------------------------------------------------------------------- /.github/fileUpdater/update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | filename=$3 4 | search=$1 5 | replace=$2 6 | 7 | sed -i -e "s/$search/$replace/g" $filename -------------------------------------------------------------------------------- /.github/findRepos/action.yml: -------------------------------------------------------------------------------- 1 | name: 'githubApiFindRepos' 2 | 3 | description: 'Returns list of repos from github api given a query' 4 | 5 | inputs: 6 | query: 7 | description: Query for github api (for example topic:xyz) 8 | required: true 9 | org: 10 | description: Org to search for repos in (for example DSACMS) 11 | required: true 12 | token: 13 | description: Token to query github api 14 | required: true 15 | 16 | runs: 17 | using: 'composite' 18 | steps: 19 | - name: Checkout Action 20 | uses: actions/checkout@v4 21 | - name: Query Github Api 22 | run: | 23 | repos=$(${{ github.action_path }}/find.sh ${{ inputs.query }} ${{ inputs.org }} ${{ inputs.token }}) 24 | echo $repos 25 | echo "repo="$repos"" >> $GITHUB_ENV 26 | shell: bash -------------------------------------------------------------------------------- /.github/findRepos/find.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | query=$1 4 | org=$2 5 | token=$3 6 | 7 | curl -s -H "Authorization: token $token" GET https://api.github.com/search/repositories?q=org:$org+$query >> apiJson.json 8 | total_count=$(jq '.total_count' apiJson.json) 9 | if [ -z "$total_count" ]; then 10 | cat apiJson.json 11 | echo "error: Error fetching from github api" >&2; exit 1 12 | fi 13 | if [ "$total_count" -eq "0" ]; then 14 | cat apiJson.json 15 | echo "error: no repos found for topic" >&2; exit 1 16 | fi 17 | 18 | repoStr=$(jq '.items' apiJson.json | jq '.[0].full_name') 19 | repoStr="$repoStr" 20 | output=["$repoStr"] 21 | for (( i=1; i<=$total_count-1; i++)); do 22 | repo=$(jq '.items' apiJson.json | jq '.['$i'].full_name') 23 | output=$(echo $output | jq --argjson r $repo '. + [$r]') 24 | done 25 | 26 | echo $output -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 12 | 13 | ## module-name: One line description of your change (less than 72 characters) 14 | 15 | ## Problem 16 | 17 | Explain the context and why you're making that change. What is the problem 18 | you're trying to solve? In some cases there is not a problem and this can be 19 | thought of being the motivation for your change. 20 | 21 | ## Solution 22 | 23 | Describe the modifications you've done. 24 | 25 | ## Result 26 | 27 | What will change as a result of your pull request? Note that sometimes this 28 | section is unnecessary because it is self-explanatory based on the solution. 29 | 30 | Some important notes regarding the summary line: 31 | 32 | * Describe what was done; not the result 33 | * Use the active voice 34 | * Use the present tense 35 | * Capitalize properly 36 | * Do not end in a period — this is a title/subject 37 | * Prefix the subject with its scope 38 | 39 | ## Test Plan 40 | 41 | (Write your test plan here. If you changed any code, please provide us with 42 | clear instructions on how you verified your changes work.) 43 | -------------------------------------------------------------------------------- /.github/workflows/addFilesToRepos.yml: -------------------------------------------------------------------------------- 1 | name: Add files to repos 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | query: 7 | description: 'Query for github API' 8 | default: 'topic:x' 9 | required: true 10 | org: 11 | description: 'Org to search for repos in' 12 | default: 'DSACMS' 13 | required: true 14 | files: 15 | description: 'File or folders to add' 16 | default: 'tier1/LICENSE' 17 | required: true 18 | 19 | env: 20 | repo: "" 21 | 22 | jobs: 23 | find-repos: 24 | runs-on: ubuntu-latest 25 | name: Find repos and generate matrix 26 | steps: 27 | - name: Checkout Action 28 | uses: actions/checkout@v4 29 | - name: Find repos 30 | uses: ./.github/findRepos 31 | with: 32 | query: ${{ github.event.inputs.query }} 33 | org: ${{ github.event.inputs.org }} 34 | token: ${{ secrets.pat }} 35 | outputs: 36 | matrix: ${{ env.repo }} 37 | 38 | add-files: 39 | runs-on: ubuntu-latest 40 | name: Add files 41 | needs: [find-repos] 42 | strategy: 43 | matrix: 44 | repo: ${{ fromJSON(needs.find-repos.outputs.matrix ) }} 45 | steps: 46 | - name: Checkout Action 47 | uses: actions/checkout@v4 48 | - name: Update file 49 | uses: ./.github/addingFile 50 | with: 51 | repository: ${{ matrix.repo }} 52 | files: ${{ github.event.inputs.files }} 53 | token: ${{ secrets.pat }} 54 | - name: Checkout Action again to stop post error 55 | uses: actions/checkout@v4 -------------------------------------------------------------------------------- /.github/workflows/auto-changelog.yml: -------------------------------------------------------------------------------- 1 | name: Changelog 2 | on: 3 | release: 4 | types: 5 | - created 6 | jobs: 7 | changelog: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: "Auto Generate changelog" 11 | uses: heinrichreimer/action-github-changelog-generator@v2.3 12 | with: 13 | token: ${{ secrets.GITHUB_TOKEN }} 14 | -------------------------------------------------------------------------------- /.github/workflows/autoMergeMainIntoDev.yml: -------------------------------------------------------------------------------- 1 | name: Merge main into dev 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | update-dev: 10 | permissions: write-all 11 | name: update-dev 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | with: 16 | fetch-depth: 0 17 | - run: | 18 | git config user.name 'GitHub Actions' 19 | git config user.email 'actions@users.noreply.github.com' 20 | git checkout dev 21 | git merge main 22 | echo "Done with merge" 23 | - name: Push to dev 24 | uses: CasperWA/push-protected@v2 25 | with: 26 | token: ${{ secrets.GITHUB_TOKEN }} 27 | branch: dev -------------------------------------------------------------------------------- /.github/workflows/checklistMarkdownToPDF.yml: -------------------------------------------------------------------------------- 1 | name: Converting outbound checklists from .md to .pdf 2 | on: 3 | pull_request: 4 | types: [opened, synchronize] 5 | # Paths can be used to only trigger actions when you have edited checklist files 6 | branches: 7 | - 'dev' 8 | paths: 9 | - 'tier*/checklist.md' 10 | 11 | jobs: 12 | get-changed-directories: 13 | name: Get changed directories 14 | runs-on: ubuntu-latest 15 | outputs: 16 | tiers: ${{ steps.list-dirs.outputs.tiers }} 17 | steps: 18 | - name: Checkout code 19 | uses: actions/checkout@v4 20 | with: 21 | fetch-depth: 2 22 | - name: Get changed directories 23 | id: get-dirs 24 | uses: tj-actions/changed-files@v45 25 | with: 26 | dir_names: "true" 27 | dir_names_include_files: 'checklist.md' 28 | - name: List all changed tier directories 29 | id: list-dirs 30 | env: 31 | ALL_CHANGED_FILES: ${{ steps.get-dirs.outputs.all_changed_files }} 32 | run: | 33 | # Obtain changed tier directories and format into array 34 | DIRS=$(echo "$ALL_CHANGED_FILES" | grep -oE 'tier[1-4]'| grep -oE 'tier[^ /]*' | sort -u | sed 's/^/"/; s/$/"/' | paste -sd, -) 35 | echo "$DIRS" 36 | 37 | # Output the array 38 | TIER_DIRS="[$DIRS]" 39 | echo "$TIER_DIRS" 40 | 41 | echo "tiers=$TIER_DIRS" >> "$GITHUB_OUTPUT" 42 | 43 | convert-to-pdf: 44 | name: Build PDF 45 | runs-on: ubuntu-latest 46 | needs: get-changed-directories 47 | permissions: 48 | contents: write 49 | strategy: 50 | max-parallel: 1 51 | matrix: 52 | tier: ${{ fromJSON(needs.get-changed-directories.outputs.tiers) }} # List of changed tier directories 53 | steps: 54 | - uses: actions/checkout@v4 55 | with: 56 | ref: ${{ github.head_ref }} 57 | - name: Generate PDF for ${{ matrix.tier }} 58 | uses: baileyjm02/markdown-to-pdf@v1 59 | with: 60 | input_path: ${{ matrix.tier }}/checklist.md 61 | images_dir: assets 62 | image_import: ../assets 63 | output_dir: ${{ matrix.tier }}/ 64 | build_html: false 65 | - name: Commit and push ${{ matrix.tier }} PDF 66 | uses: stefanzweifel/git-auto-commit-action@v5 67 | with: 68 | commit_message: "Updated ${{ matrix.tier }} checklist pdf" 69 | env: 70 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 71 | -------------------------------------------------------------------------------- /.github/workflows/contributors.yml: -------------------------------------------------------------------------------- 1 | name: Update Contributors Information 2 | 3 | on: 4 | workflow_dispatch: {} 5 | schedule: 6 | # Weekly on Saturdays. 7 | - cron: "30 1 * * 6" 8 | push: 9 | branches: [main] 10 | 11 | jobs: 12 | update-contributors: 13 | runs-on: ubuntu-latest 14 | permissions: 15 | contents: write 16 | pull-requests: write 17 | 18 | steps: 19 | - name: Checkout repository 20 | uses: actions/checkout@v4 21 | with: 22 | fetch-depth: 0 23 | 24 | - name: Update contributor list 25 | id: contrib_list 26 | uses: akhilmhdh/contributors-readme-action@v2.3.10 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | with: 30 | readme_path: COMMUNITY.md 31 | use_username: false 32 | commit_message: "update contributors information" 33 | 34 | - name: Get contributors count 35 | id: get_contributors 36 | env: 37 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 38 | 39 | run: | 40 | OWNER=$(echo $GITHUB_REPOSITORY | cut -d'/' -f1) 41 | REPO=$(echo $GITHUB_REPOSITORY | cut -d'/' -f2) 42 | QUERY='query { repository(owner: \"'"$OWNER"'\", name: \"'"$REPO"'\") { collaborators { totalCount } } }' 43 | 44 | CONTRIBUTORS=$(gh api \ 45 | -H "Accept: application/vnd.github+json" \ 46 | -H "X-GitHub-Api-Version: 2022-11-28" \ 47 | "/repos/$OWNER/$REPO/contributors?per_page=100" | \ 48 | jq '[.[] | select(.type != "Bot" and (.login | test("\\[bot\\]$") | not) and (.login | test("-bot$") | not))] | length') 49 | 50 | echo "Total contributors: $CONTRIBUTORS" 51 | echo "contributors=$CONTRIBUTORS" >> $GITHUB_OUTPUT 52 | 53 | - name: Update COMMUNITY.md 54 | run: | 55 | CONTRIBUTORS="${{ steps.get_contributors.outputs.contributors }}" 56 | 57 | perl -i -pe 's/().*?()/$1 '"$CONTRIBUTORS"' $2/' COMMUNITY.md 58 | 59 | git config user.name 'github-actions[bot]' 60 | git config user.email 'github-actions[bot]@users.noreply.github.com' 61 | git add COMMUNITY.md 62 | git commit -m "update contributors count to $CONTRIBUTORS" || exit 0 63 | 64 | - name: Push protected 65 | uses: CasperWA/push-protected@v2 66 | with: 67 | token: ${{ secrets.GITHUB_TOKEN }} 68 | 69 | branch: main 70 | -------------------------------------------------------------------------------- /.github/workflows/extendJSONFile.yml: -------------------------------------------------------------------------------- 1 | name: Extend JSON 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | url_to_json: 7 | description: 'URL to JSON file' 8 | default: 'https://raw.githubusercontent.com/DSACMS/repo-scaffolder/main/tier1/%7B%7Bcookiecutter.project_slug%7D%7D/repolinter.json' 9 | required: true 10 | type: string 11 | workflow_call: 12 | inputs: 13 | url_to_json: 14 | description: 'URL to JSON file' 15 | default: 'https://raw.githubusercontent.com/DSACMS/repo-scaffolder/main/tier1/%7B%7Bcookiecutter.project_slug%7D%7D/repolinter.json' 16 | required: true 17 | type: string 18 | outputs: 19 | raw-json: 20 | description: 'JSON of the file' 21 | value: ${{ jobs.extend-json.outputs.raw-json }} 22 | 23 | jobs: 24 | extend-json: 25 | runs-on: ubuntu-latest 26 | name: Extend JSON file with extends property 27 | outputs: 28 | raw-json: ${{ steps.extend-json.outputs.raw-json }} 29 | steps: 30 | - name: Checkout repository 31 | uses: actions/checkout@v4 32 | with: 33 | repository: DSACMS/repo-scaffolder 34 | ref: main 35 | path: workflows 36 | - name: Extend JSON 37 | id: extend-json 38 | uses: ./workflows/.github/extendJSON 39 | with: 40 | url_to_json: ${{ inputs.url_to_json }} -------------------------------------------------------------------------------- /.github/workflows/gitleaks.yml: -------------------------------------------------------------------------------- 1 | name: Check for Secrets 2 | on: 3 | pull_request: 4 | push: 5 | 6 | jobs: 7 | scan-for-secrets: 8 | name: Run gitleaks 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | with: { fetch-depth: 0 } 13 | 14 | - name: Check for GitLeaks 15 | uses: gacts/gitleaks@v1 16 | -------------------------------------------------------------------------------- /.github/workflows/repoHygieneCheck.yml: -------------------------------------------------------------------------------- 1 | name: "Repository Hygiene Check" 2 | on: 3 | push: 4 | branches: 5 | - 'main' 6 | workflow_dispatch: 7 | 8 | jobs: 9 | check-first-run: 10 | name: Check For First Run 11 | runs-on: ubuntu-latest 12 | outputs: 13 | should_run: ${{ steps.check.outputs.should_run }} 14 | permissions: 15 | contents: read 16 | pull-requests: write 17 | steps: 18 | - uses: actions/checkout@v4 19 | - id: check 20 | run: | 21 | # If manually triggered, always run 22 | 23 | if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then 24 | echo "should_run=true" >> $GITHUB_OUTPUT 25 | exit 0 26 | 27 | fi 28 | 29 | # Check if initialization label exists 30 | 31 | has_label=$(gh label list --json name | jq '.[] | select(.name=="repolinter-initialized")') 32 | 33 | if [[ -z "$has_label" ]]; then 34 | # First time - create label and allow run 35 | gh label create repolinter-initialized --description "Marks repo as having run initial repolinter check" 36 | echo "should_run=true" >> $GITHUB_OUTPUT 37 | else 38 | echo "should_run=false" >> $GITHUB_OUTPUT 39 | 40 | fi 41 | env: 42 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 43 | 44 | resolve-repolinter-json: 45 | name: Get Repolinter Config 46 | needs: check-first-run 47 | if: needs.check-first-run.outputs.should_run == 'true' 48 | uses: DSACMS/repo-scaffolder/.github/workflows/extendJSONFile.yml@main 49 | with: 50 | url_to_json: 'https://raw.githubusercontent.com/DSACMS/repo-scaffolder/main/tier3/%7B%7Bcookiecutter.project_slug%7D%7D/repolinter.json' 51 | 52 | repolinter-checks: 53 | name: Tier 3 Checks 54 | needs: [check-first-run, resolve-repolinter-json] 55 | if: needs.check-first-run.outputs.should_run == 'true' 56 | runs-on: ubuntu-latest 57 | permissions: 58 | contents: write 59 | pull-requests: write 60 | env: 61 | RAW_JSON: ${{ needs.resolve-repolinter-json.outputs.raw-json }} 62 | steps: 63 | - uses: actions/checkout@v4 64 | - run: echo $RAW_JSON > repolinter.json 65 | - uses: DSACMS/repolinter-action@main 66 | with: 67 | config_file: 'repolinter.json' 68 | output_type: 'pull-request' 69 | pull_request_labels: 'repolinter-initialized, cms-oss, cms-gov' 70 | token: ${{ secrets.REPOLINTER_AUTO_TOKEN }} 71 | -------------------------------------------------------------------------------- /.github/workflows/updateCodeJSON.yml: -------------------------------------------------------------------------------- 1 | name: Update Code.json 2 | on: 3 | workflow_dispatch: 4 | 5 | permissions: 6 | contents: write 7 | pull-requests: write 8 | 9 | jobs: 10 | update-code-json: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout Repository 14 | uses: actions/checkout@v4 15 | with: 16 | fetch-depth: 0 17 | 18 | - name: Setup Node.js 19 | uses: actions/setup-node@v4 20 | with: 21 | node-version: '20' 22 | 23 | - name: Setup Go 24 | uses: actions/setup-go@v5 25 | with: 26 | go-version: '1.22' 27 | 28 | - name: Install SCC 29 | run: go install github.com/boyter/scc/v3@latest 30 | 31 | - name: Update code.json 32 | uses: DSACMS/automated-codejson-generator@main 33 | with: 34 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/updateStringInRepos.yml: -------------------------------------------------------------------------------- 1 | name: Update string 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | query: 7 | description: 'Query from github API' 8 | default: 'topic:x' 9 | required: true 10 | org: 11 | description: 'Org to search for repos in' 12 | default: 'DSACMS' 13 | required: true 14 | find: 15 | description: 'String to search for' 16 | default: 'x' 17 | required: true 18 | replace: 19 | description: 'Replacement string' 20 | default: 'y' 21 | required: true 22 | file: 23 | description: 'File to replace in' 24 | default: 'CONTRIBUTING.md' 25 | 26 | env: 27 | repo: "" 28 | 29 | jobs: 30 | find-repos: 31 | runs-on: ubuntu-latest 32 | name: Find repos and generate matrix 33 | steps: 34 | - name: Checkout Action 35 | uses: actions/checkout@v4 36 | - name: Find repos 37 | uses: ./.github/findRepos 38 | with: 39 | query: ${{ github.event.inputs.query }} 40 | org: ${{ github.event.inputs.org }} 41 | token: ${{ secrets.pat }} 42 | outputs: 43 | matrix: ${{ env.repo }} 44 | 45 | update: 46 | runs-on: ubuntu-latest 47 | name: Update file 48 | needs: [find-repos] 49 | strategy: 50 | matrix: 51 | repo: ${{ fromJSON(needs.find-repos.outputs.matrix ) }} 52 | steps: 53 | - name: Checkout Action 54 | uses: actions/checkout@v4 55 | - name: Update file 56 | uses: ./.github/fileUpdater 57 | with: 58 | repository: ${{ matrix.repo }} 59 | find: ${{ github.event.inputs.find }} 60 | replace: ${{ github.event.inputs.replace }} 61 | file: ${{ github.event.inputs.file }} 62 | token: ${{ secrets.pat }} 63 | - name: Checkout Action again to stop post error 64 | uses: actions/checkout@v4 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Files ignored because they're binary/unnecessary 2 | .DS_STORE 3 | # Files/Dirs ignored because they're secret/internal only 4 | id_rsa 5 | secrets_repo/ 6 | internal_only_repo/ 7 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /CODEOWNERS.md: -------------------------------------------------------------------------------- 1 | # Code Owners 2 | 3 | [@decause-gov](https://github.com/decause-gov) 4 | [@natalialuzuriaga](https://github.com/natalialuzuriaga) 5 | [@IsaacMilarky](https://github.com/IsaacMilarky) 6 | [@sachin-panayil](https://github.com/sachin-panayil) 7 | [@DinneK](https://github.com/DinneK) 8 | 9 | ## Repository Domains 10 | 11 | - Repository Templates in `/tier*/` [@natalialuzuriaga](https://github.com/natalialuzuriaga) [@sachin-panayil](https://github.com/sachin-panayil) [@IsaacMilarky](https://github.com/IsaacMilarky) 12 | - Outbound Checklists in `/tier*/checklist.md` [@natalialuzuriaga](https://github.com/natalialuzuriaga) 13 | - GitHub Actions in `/.github` [@sachin-panayil](https://github.com/sachin-panayil) [@IsaacMilarky](https://github.com/IsaacMilarky) [@natalialuzuriaga](https://github.com/natalialuzuriaga) 14 | 15 | ## Shoutouts 16 | 17 | [@usdigitalresponse](https://github.com/usdigitalresponse) 18 | 19 | - [@aprilselby88](https://github.com/aprilselby88) 20 | - [@vantuyls](https://github.com/vantuyls) 21 | - [@sgarciahelguera](https://github.com/sgarciahelguera) 22 | 23 | Thank you [US Digital Response](https://www.usdigitalresponse.org/) Team for your support creating this repository! 24 | 25 | [Coding It Forward Fellows](https://codingitforward.com/fellowship) 26 | 27 | - [@Firebird1029](https://github.com/Firebird1029) 28 | - [@CreativeNick](https://github.com/CreativeNick) 29 | - [@RicardoZamora01](https://github.com/RicardoZamora01) 30 | 31 | # Questions? 32 | 33 | Email opensource@cms.hhs.gov 34 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. 4 | 5 | We are committed to making participation in this project a harassment-free experience for everyone, regardless of the level of experience, gender, gender identity, expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 6 | 7 | Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. 8 | 9 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned with this Code of Conduct. 10 | 11 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers at opensource@cms.hhs.gov. 12 | 13 | This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/) 14 | 15 | ## Acknowledgements 16 | 17 | This CODE_OF_CONDUCT.md was originally forked from the [United States Digital Service](https://usds.gov) [Justice40](https://thejustice40.com) open source [repository](https://github.com/usds/justice40-tool), and we would like to acknowledge and thank the community for their contributions. 18 | -------------------------------------------------------------------------------- /COMMUNITY_GUIDELINES.md: -------------------------------------------------------------------------------- 1 | # repo-scaffolder Open Source Community Guidelines 2 | 3 | This document contains principles and guidelines for participating in the repo-scaffolder open source community. 4 | 5 | ## Principles 6 | 7 | These principles guide our data, product, and process decisions, architecture, and approach. 8 | 9 | - Open means transparent and participatory. 10 | - We take a modular and modern approach to software development. 11 | - We build open-source software and open-source process. 12 | - We value ease of implementation. 13 | - Fostering community includes building capacity and making our software and processes accessible to participants with diverse backgrounds and skillsets. 14 | - Data (and data science) is as important as software and process. We build open data sets where possible. 15 | - We strive for transparency for algorithms and places we might be introducing bias. 16 | 17 | ## Community Guidelines 18 | 19 | All community members are expected to adhere to our [Code of Conduct](CODE_OF_CONDUCT.md). 20 | 21 | Information on contributing to this repository is available in our [Contributing file](CONTRIBUTING.md). 22 | 23 | When participating in the repo-scaffolder open source community conversations and spaces, we ask individuals to follow the following guidelines: 24 | 25 | - When joining a conversation for the first time, please introduce yourself by providing a brief intro that includes: 26 | - your related organization (if applicable) 27 | - your pronouns 28 | - your superpower, and how you hope to use it for {{ cookiecutter.project_name }} 29 | - Embrace a culture of learning, and educate each other. We are all entering this conversation from different starting points and with different backgrounds. There are no dumb questions. 30 | - Take space and give space. We strive to create an equitable environment in which all are welcome and able to participate. We hope individuals feel comfortable voicing their opinions and providing contributions and will do our best to recognize and make space for individuals who may be struggling to find space here. Likewise, we expect individuals to recognize when they are taking up significant space and take a step back to allow room for others. 31 | 32 | - Be respectful. 33 | - Default to positive. Assume others' contributions are legitimate and valuable and that they are made with good intention. 34 | 35 | ## Acknowledgements 36 | 37 | This COMMUNITY_GUIDELINES.md was originally forked from the [United States Digital Service](https://usds.gov) [Justice40](https://thejustice40.com) open source [repository](https://github.com/usds/justice40-tool), and we would like to acknowledge and thank the community for their contributions. 38 | -------------------------------------------------------------------------------- /GOVERNANCE.md: -------------------------------------------------------------------------------- 1 | # Governance 2 | 3 | 4 | 5 | This project is governed by our [Community Guidelines](COMMUNITY_GUIDELINES.md) and [Code of Conduct](CODE_OF_CONDUCT.md). 6 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security and Responsible Disclosure Policy 2 | 3 | The Centers for Medicare & Medicaid Services is committed to ensuring the security of the American public by protecting their information from unwarranted disclosure. We want security researchers to feel comfortable reporting vulnerabilities they have discovered so we can fix them and keep our users safe. We developed our disclosure policy to reflect our values and uphold our sense of responsibility to security researchers who share their expertise with us in good faith. 4 | 5 | *Submit a vulnerability:* Vulnerability reports can be submitted through [Bugcrowd](https://bugcrowd.com/cms-vdp). Reports may be submitted anonymously. If you share contact information, we will acknowledge receipt of your report within 3 business days. 6 | 7 | Review the HHS Disclosure Policy and websites in scope: 8 | [https://www.hhs.gov/vulnerability-disclosure-policy/index.html](https://www.hhs.gov/vulnerability-disclosure-policy/index.html). 9 | 10 | This policy describes *what systems and types of research* are covered under this 11 | policy, *how to send* us vulnerability reports, and *how long* we ask security 12 | researchers to wait before publicly disclosing vulnerabilities. 13 | -------------------------------------------------------------------------------- /assets/images/auto-generator.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/images/cms-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/images/flowchart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSACMS/repo-scaffolder/d09dcd042f0ea31a044e70e6f7ede97a7cf48d64/assets/images/flowchart.png -------------------------------------------------------------------------------- /assets/images/form-generator.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/images/index-generator.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/images/maturity-model-trees-graphic-horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSACMS/repo-scaffolder/d09dcd042f0ea31a044e70e6f7ede97a7cf48d64/assets/images/maturity-model-trees-graphic-horizontal.png -------------------------------------------------------------------------------- /assets/images/metrics.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/images/repo-scaffolder.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/images/repolinter-results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSACMS/repo-scaffolder/d09dcd042f0ea31a044e70e6f7ede97a7cf48d64/assets/images/repolinter-results.png -------------------------------------------------------------------------------- /assets/images/repolinter.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/js/quizHandler.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", function () { 2 | const form = document.querySelector(".usa-form"); 3 | const formContainer = document.querySelector(".form-container"); 4 | const resultsContainer = document.querySelector(".results"); 5 | const treeGraphic = document.querySelector(".tree-graphic"); 6 | const tierResult = document.querySelector(".tier-result"); 7 | 8 | if (!form) return; 9 | 10 | form.addEventListener("submit", function (event) { 11 | event.preventDefault(); 12 | 13 | const checkedValues = Array.from( 14 | document.querySelectorAll("input[name='tier-determiner']:checked") 15 | ).map((input) => input.value); 16 | 17 | console.log("Selected answers:", checkedValues); 18 | 19 | // Tier selection logic 20 | let tier; 21 | let name; 22 | if (!checkedValues.includes("contributors")) { 23 | tier = "0"; 24 | name = "Private Repository" 25 | } else if (!checkedValues.includes("release")) { 26 | tier = "0"; 27 | name = "Private Repository" 28 | } 29 | else if (!checkedValues.includes("work")) { 30 | tier = "1"; 31 | name = "One-Time Release" 32 | } 33 | else if (!checkedValues.includes("maintain")) { 34 | tier = "2"; 35 | name = "Close Collaboration" 36 | } 37 | else if (!checkedValues.includes("roadmap")) { 38 | tier = "3"; 39 | name = "Working in Public" 40 | } 41 | else { 42 | tier = "4"; 43 | name = "Community Governance" 44 | } 45 | 46 | // Display results 47 | formContainer.style.display = "none"; 48 | resultsContainer.style.display = "block"; 49 | treeGraphic.src = `./assets/images/tier${tier}-tree.svg`; 50 | treeGraphic.alt = `Tier ${tier} Tree`; 51 | tierResult.innerHTML = `Your project is: Tier ${tier} - ${name}
52 | 53 | Learn more about this maturity model tier 54 | 55 | `; 56 | }); 57 | }); 58 | 59 | function uncheckAllCheckboxes() { 60 | const checkboxes = document.querySelectorAll(".usa-checkbox__input"); 61 | checkboxes.forEach((checkbox) => { 62 | checkbox.checked = false; 63 | }); 64 | } 65 | 66 | function handleClick(event) { 67 | const formContainer = document.querySelector(".form-container"); 68 | const resultsContainer = document.querySelector(".results"); 69 | 70 | event.preventDefault(); 71 | uncheckAllCheckboxes(); // Clear input 72 | 73 | resultsContainer.style.display = "none"; 74 | formContainer.style.display = "block"; 75 | } -------------------------------------------------------------------------------- /code.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "repo-scaffolder", 3 | "description": "Templates and commandline tools for creating repositories for US Federal open source projects ", 4 | "longDescription": "repo-scaffolder assists project teams with creating repositories that adhere to repository hygiene standards. It provides file templates detailing project information, contributing guidance, maintainer roles, project metadata, community involvement, feedback mechanisms, governance, security policies, and more. ", 5 | "status": "Production", 6 | "permissions": { 7 | "license": [ 8 | { 9 | "name": "CC0 1.0 Universal", 10 | "URL": "https://github.com/DSACMS/repo-scaffolder/blob/main/LICENSE" 11 | } 12 | ], 13 | "usageType": "openSource", 14 | "exemptionText": "" 15 | }, 16 | "organization": "Centers for Medicare & Medicaid Services", 17 | "repositoryURL": "https://github.com/DSACMS/repo-scaffolder", 18 | "vcs": "git", 19 | "laborHours": 5940, 20 | "platforms": ["web", "windows", "mac", "linux"], 21 | "categories": ["data-collection", "it-asset-management", "knowledge-management"], 22 | "softwareType": "standalone/backend", 23 | "languages": [ 24 | "Python" 25 | ], 26 | "maintenance": "internal", 27 | "date": { 28 | "created": "2023-10-05T18:06:51Z", 29 | "lastModified": "2025-02-10T19:51:24Z", 30 | "metaDataLastUpdated": "2025-02-10T19:52:18.683Z" 31 | }, 32 | "tags": ["repository", "codejson", "cookiecutter"], 33 | "contact": { 34 | "email": "opensource@cms.hhs.gov", 35 | "name": "CMS Open Source Team" 36 | }, 37 | "localisation": false, 38 | "repositoryType": "tools", 39 | "userInput": false, 40 | "fismaLevel": "Low", 41 | "group": "CMS/OA/DSAC", 42 | "subsetInHealthcare": "Operational", 43 | "userType": "Government", 44 | "repositoryHost": "github.com/DSACMS", 45 | "maturityModelTier": 3, 46 | "projectType": "Tools" 47 | } 48 | -------------------------------------------------------------------------------- /docs/.github-directory.md: -------------------------------------------------------------------------------- 1 | # `.github` directory 2 | 3 | The .github directory in repository templates contains files and workflows designed to support project teams with development, documentation, and repository hygiene. This includes GitHub Actions workflows for automated tasks, metadata files for project information, and more. 4 | 5 | ## Workflows 6 | 7 | Located in .**github/workflows**, the OSPO has created GitHub Actions workflows to assist project teams with development and documentation upkeep for repository hygiene. 8 | 9 | | File Name | Tier 0 | Tier 1 | Tier 2 | Tier 3 | Tier 4 | Description | 10 | | :------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----- | :----- | :----- | :----- | :----- | :----------------------------------------------- | 11 | | [auto-changelog.yml](https://github.com/DSACMS/repo-scaffolder/blob/main/tier3/%7B%7Bcookiecutter.project_slug%7D%7D/.github/workflows/auto-changelog.yml) | | | ✔️ | ✔️ | ✔️ | Auto-generates a CHANGELOG.md | 12 | | [repoHygieneCheck.yml](https://github.com/DSACMS/repo-scaffolder/blob/main/tier3/%7B%7Bcookiecutter.project_slug%7D%7D/.github/workflows/repoHygieneCheck.yml) | | ✔️ | ✔️ | ✔️ | ✔️ | Performs repolinter checks | 13 | | [contributors.yml](https://github.com/DSACMS/repo-scaffolder/blob/main/tier3/%7B%7Bcookiecutter.project_slug%7D%7D/.github/workflows/contributors.yml) | | | ✔️ | ✔️ | ✔️ | Generates a list of contributors in COMMUNITY.md | 14 | | [gitleaks.yml](https://github.com/DSACMS/repo-scaffolder/blob/main/tier3/%7B%7Bcookiecutter.project_slug%7D%7D/.github/workflows/gitleaks.yml) | | ✔️ | ✔️ | ✔️ | ✔️ | Scans for secrets upon each push or PR | 15 | | [repoStructure.yml](https://github.com/DSACMS/repo-scaffolder/blob/main/tier3/%7B%7Bcookiecutter.project_slug%7D%7D/.github/workflows/repoStructure.yml) | | | | ✔️ | ✔️ | Generates repo structure in README.md | 16 | 17 | ## Project Metadata: Adding code.json to your repository using cookiecutter 18 | 19 | Located in `.github/codejson` are files needed to add metadata to your repository using cookiecutter. Follow these set of [instructions](https://github.com/DSACMS/repo-scaffolder?tab=readme-ov-file#metadata-collection-using-codejson) to create code.json. 20 | 21 | ## Files 22 | 23 | `.github` contains additional files that can be helpful to add to your repository. 24 | 25 | | File Name | Tier 0 | Tier 1 | Tier 2 | Tier 3 | Tier 4 | Description | 26 | | :------------------------------------------------------------------------------------------------------------------------------------- | :----- | :----- | :----- | :----- | :----- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 27 | | [CODEOWNERS.md](https://github.com/DSACMS/repo-scaffolder/blob/main/tier3/%7B%7Bcookiecutter.project_slug%7D%7D/.github/CODEOWNERS.md) | | | ✔️ | ✔️ | ✔️ | A file used to define who is responsible for specific parts of the codebase. Learn more in [GitHub Docs](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners). | 28 | 29 | ## Help Desk Requests 30 | 31 | Located in `.github/ISSUE_TEMPLATES` are issue templates to make requests for repository access and metadata updates. Requests are managed by the repository admins and organization owners. 32 | 33 | | File Name | Description | 34 | | ------------------------------- | ------------------------------------------------------ | 35 | | add_team_request.md | Request team to be added to repository | 36 | | outside_collaborator_request.md | Request outside collaborator to be added to repository | 37 | | code_json_request.md | Request updates to code.json | 38 | -------------------------------------------------------------------------------- /maturity-model-tiers.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSACMS/repo-scaffolder/d09dcd042f0ea31a044e70e6f7ede97a7cf48d64/maturity-model-tiers.pdf -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | cookiecutter==2.6.0 2 | -------------------------------------------------------------------------------- /tier-determiner.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | 3 | @dataclass 4 | class Prompt: 5 | question: str 6 | answer: bool = None 7 | 8 | def print_tier_description(tier=None): 9 | tier_descriptions = { 10 | 0: "💡 Tier 0 - Private Repository: Private, experimental projects typically maintained by a single developer; often prototypes or example code", 11 | 1: "💡 Tier 1 - One-Time Release: A project with no plans for updates or ongoing maintenance from its original author(s).", 12 | 2: "💡 Tier 2 - Close Collaboration: Collaborative project shared across small teams or departments, typically using innersource practices.", 13 | 3: "💡 Tier 3 - Working in Public: Public-facing project open to external contributions, developed by CMS or its contractors for official use", 14 | 4: "💡 Tier 4 - Community Governance: Fully open-source project with community-led governance and broad public collaboration." 15 | } 16 | 17 | if tier is None: 18 | for description in tier_descriptions.values(): 19 | print(description) 20 | elif tier in tier_descriptions: 21 | print(tier_descriptions[tier]) 22 | else: 23 | print(f"Invalid tier number: {tier}") 24 | 25 | def main(): 26 | # Intro text to repo-scaffolder 27 | print("\n👋 Welcome to the repo-scaffolder CLI.") 28 | print("⚙️ We will assist you with creating a repository.\n") 29 | 30 | print("🌱 The OSPO follows a maturity model framework to classify projects according to their open source journey:") 31 | print_tier_description() 32 | print("ℹ️ Visit https://github.com/DSACMS/repo-scaffolder/blob/main/maturity-model-tiers.md for more information.\n") 33 | 34 | print("\n📝 Answer the following questions to identify the maturity model tier of your project.") 35 | 36 | print("****************************************\n") 37 | 38 | prompts = { 39 | "CONTRIBUTORS": Prompt("Does your project have more than one contributor?"), 40 | "RELEASE": Prompt("Do you plan on shipping more than one release?"), 41 | "WORK": Prompt("Do you plan on having other individuals/teams outside the agency work with you?"), 42 | "MAINTAIN": Prompt("Do you plan on having other individuals/teams outside the agency maintain the project with you?"), 43 | "ROADMAP": Prompt("Do you plan on having other individuals/teams outside the agency plan the development roadmap with you?") 44 | } 45 | 46 | # Obtain answers 47 | for key, prompt in prompts.items(): 48 | while True: 49 | response = input(f"{prompt.question} [y/n]: ").strip().lower() 50 | if response in ["y", "yes"]: 51 | prompt.answer = True 52 | break 53 | elif response in ["n", "no"]: 54 | prompt.answer = False 55 | break 56 | else: 57 | print("Please answer y or n.") 58 | 59 | # Determine tier 60 | if not prompts["CONTRIBUTORS"].answer: 61 | tier = 0 62 | elif not prompts["RELEASE"].answer: 63 | tier = 0 64 | elif not prompts["WORK"].answer: 65 | tier = 1 66 | elif not prompts["MAINTAIN"].answer: 67 | tier = 2 68 | elif not prompts["ROADMAP"].answer: 69 | tier = 3 70 | else: 71 | tier = 4 72 | 73 | # Output results 74 | print(f"\n****************************************") 75 | print(f"\n📚 Your project is classified as: Tier {tier}") 76 | print_tier_description(tier) 77 | print(f"ℹ️ Visit https://github.com/DSACMS/repo-scaffolder/blob/main/tier{tier} for more information about the maturity model tier.") 78 | 79 | # Provide next steps 80 | print(f"⚙️ Next, create your Tier {tier} repository by running the command below:") 81 | print(f" cookiecutter https://github.com/DSACMS/repo-scaffolder --directory=tier{tier}\n") 82 | 83 | 84 | if __name__ == "__main__": 85 | main() -------------------------------------------------------------------------------- /tier0/README.md: -------------------------------------------------------------------------------- 1 | # Tier 0: Private Repository 2 | 3 | ## What is a Tier 0 Project? 4 | 5 | A **Tier 0** project is an **experimental or historical** repository that is **private** and generally used by a single developer or a small group. It typically includes working projects, example scripts, or early prototypes that serve as a foundation for future work or experimentation. This type of project is not shared publicly and often remains private due to its preliminary or incomplete nature. 6 | 7 | The main purpose of a Tier 0 project is to provide a space for initial development, exploration, and testing. These repositories generally lack formal documentation or governance structures that are typical of more mature projects. 8 | 9 | ### Key Characteristics of a Tier 0 Project: 10 | 11 | - **Private** and often limited to individual or small team access. 12 | - Primarily **experimental or developmental** in nature. 13 | 14 | --- 15 | 16 | ## Files for a Tier 0 Project 17 | 18 | Although these projects are private, there are specific files that are required and recommended to include in the repository as part of the CMS Open Source Program Office's repository hygiene guidelines and standards. 19 | 20 | | **File** | **Requirement** | **Description** | 21 | | ----------------- | --------------- | --------------------------------------------------------------------------------------------------------------------------- | 22 | | `LICENSE` | Mandatory | Defines the licensing terms under which the project is distributed. | 23 | | `code.json` | Mandatory | Contains project metadata following government requirements. | 24 | | `README.md` | Mandatory | Provides an overview of the project, including its purpose, setup instructions, or any relevant notes for the developer(s). | 25 | | `COMMUNITY.md` | Mandatory | Lists project team members and points of contact. | 26 | | `SECURITY.md` | Recommended | Outlines the agency's security policies, including how to report security issues or vulnerabilities in the code. | 27 | | `CONTRIBUTING.md` | Recommended | Guidelines for contributing, useful if the project is later opened to collaborators or transitioned to a public repository. | 28 | 29 | For more information about sections and content within the files above, please visit [maturity-model-tiers.md](https://github.com/DSACMS/repo-scaffolder/blob/main/maturity-model-tiers.md). 30 | 31 | ## .github directory 32 | 33 | The .github directory includes various files such as GitHub action workflows, code.json metadata cookiecutter creation, and issue templates. For more information, please visit the [.github-directory.md]([../docs/.github-directory.md). 34 | 35 | ## Repository Hygiene using repolinter 36 | 37 | As part of maintaining repository hygiene, repolinter is used to identify missing files and information. `repolinter.json` defines a set of checks that verify the existence of these files in your repository. To run repolinter, execute the following command from the root directory: 38 | 39 | ``` 40 | repolinter lint . 41 | ``` 42 | 43 | A GitHub action is also available for running repolinter checks. For more information, please visit [README.md](https://github.com/DSACMS/repo-scaffolder?tab=readme-ov-file#identify-missing-files-and-information-using-repolinter). 44 | -------------------------------------------------------------------------------- /tier0/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_name": "My Project", 3 | "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '_') }}", 4 | "project_org": "DSACMS", 5 | "project_repo_name": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}", 6 | "project_description": "This is the project description, could match github.com repo description.", 7 | "project_visibility": ["public", "internal", "private"], 8 | "create_repo": [true, false], 9 | "receive_updates": [true, false], 10 | "add_team": [true, false], 11 | "__prompts__": { 12 | "create_repo": "Would you like to create a repo on github.com?", 13 | "receive_updates": "Would you like to receive updates from the DSACMS team via pull requests?", 14 | "add_team": "Would you like to add project team members to COMMUNITY.md?" 15 | }, 16 | "_copy_without_render": [".github/codejson"] 17 | } -------------------------------------------------------------------------------- /tier0/hooks/post_gen_project.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import shutil 3 | import os 4 | 5 | REPO_NAME = '{{ cookiecutter.project_repo_name }}' 6 | ORG_NAME = '{{ cookiecutter.project_org }}' 7 | VISIBILITY = '{{cookiecutter.project_visibility}}' 8 | DESCRIPTION = '{{cookiecutter.project_description}}' 9 | CREATE_REPO = '{{cookiecutter.create_repo}}' 10 | RECEIVE_UPDATES = '{{cookiecutter.receive_updates}}' 11 | ADD_TEAM = '{{cookiecutter.add_team}}' 12 | 13 | def createGithubRepo(): 14 | gh_cli_command = [ 15 | "gh", "repo", "create", 16 | f"{ORG_NAME}/{REPO_NAME}", 17 | "--source=.", 18 | f"--{VISIBILITY}", 19 | "--push", 20 | f"--description={DESCRIPTION}", 21 | ] 22 | subprocess.call(gh_cli_command) 23 | subprocess.call(["git", "push", "--set-upstream", "origin", "main"]) 24 | 25 | def addTopic(): 26 | gh_cli_command = [ 27 | "gh", "repo", "edit", 28 | f"{ORG_NAME}/{REPO_NAME}", 29 | "--add-topic=dsacms-tier0", 30 | ] 31 | subprocess.call(gh_cli_command) 32 | 33 | def addTeam(): 34 | team = [] 35 | add_member = True 36 | while add_member: 37 | member = {} 38 | member["role"] = input("Project Member's Role (Engineer, Project Lead, COR, etc...): ").strip() 39 | member["name"] = input("Project Member's Name: ").strip() 40 | member["affiliation"] = input("Project Member's Affiliation (DSAC, CCSQ, CMMI, etc...): ").strip() 41 | team.append(member) 42 | 43 | while True: 44 | add_member_input = input("Would you like to add another project member? [Y/n]: ").strip().lower() 45 | if add_member_input in ("y", "yes", ""): 46 | add_member = True 47 | break 48 | elif add_member_input in ("n", "no"): 49 | add_member = False 50 | break 51 | else: 52 | print("\nInvalid response, please respond with: 'y', 'yes', 'n', 'no', or just press Enter for yes") 53 | 54 | team_table = "" 55 | for member in team: 56 | team_table += f"| {member["role"]} | {member["name"]} | {member["affiliation"]} |\n" 57 | 58 | community_file_path = f"COMMUNITY.md" 59 | 60 | with open(community_file_path, "r") as f: 61 | lines = f.readlines() 62 | 63 | with open(community_file_path, "w") as f: 64 | for line in lines: 65 | if "| {role} | {names} | {affiliations} |" in line: 66 | f.write(team_table) # Replace placeholder line with new table of project team members 67 | else: 68 | f.write(line) 69 | 70 | def moveCookiecutterFile(): 71 | original_dir = os.getcwd() 72 | 73 | try: 74 | github_dir = os.path.join(original_dir, ".github") 75 | os.chdir(github_dir) 76 | 77 | source_path = "cookiecutter.json" 78 | destination_dir = "codejson" 79 | destination_path = os.path.join(destination_dir, "cookiecutter.json") 80 | 81 | shutil.move(source_path, destination_path) 82 | 83 | finally: 84 | # Moves back to project dir 85 | os.chdir(original_dir) 86 | 87 | def main(): 88 | if ADD_TEAM == "True": 89 | addTeam() 90 | 91 | moveCookiecutterFile() 92 | 93 | subprocess.call(["git", "init", "-b", "main"]) 94 | subprocess.call(["git", "add", "."]) 95 | subprocess.call(["git", "commit", "-m", "initial commit"]) 96 | 97 | if CREATE_REPO == "True": 98 | createGithubRepo() 99 | 100 | if RECEIVE_UPDATES == "True": 101 | addTopic() 102 | 103 | print(f"\n****************************************") 104 | print(f"\n✅ {REPO_NAME} has successfully been created!\n") 105 | 106 | 107 | if __name__ == "__main__": 108 | main() 109 | -------------------------------------------------------------------------------- /tier0/hooks/pre_prompt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "\n⚙️ Welcome to the repo-scaffolder cookiecutter CLI." 4 | echo -e "📝 We will assist you with creating a Tier 0 repository." 5 | echo -e "ℹ️ Visit https://github.com/DSACMS/repo-scaffolder/tree/main/tier0 for more information.\n" 6 | echo -e "****************************************\n" -------------------------------------------------------------------------------- /tier0/{{cookiecutter.project_slug}}/.github/ISSUE_TEMPLATE/code_json_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: code.json Update Request 3 | about: Request updates to code.json 4 | title: '[CODE.JSON]: ' 5 | labels: ['code-json-update'] 6 | assignees: '' 7 | --- 8 | 9 | ## Code.json Update Request 10 | 11 | Thank you for helping maintain accurate code.json information for this project! This data helps track open source projects across the organization and ensures compliance with federal open source policies. 12 | 13 | ### Which field would you like to update? 14 | 15 | 16 | 17 | - [ ] name 18 | - [ ] description 19 | - [ ] longDescription 20 | - [ ] status 21 | - [ ] permissions 22 | - [ ] organization 23 | - [ ] repositoryURL 24 | - [ ] vcs 25 | - [ ] laborHours 26 | - [ ] platforms 27 | - [ ] categories 28 | - [ ] softwareType 29 | - [ ] languages 30 | - [ ] maintenance 31 | - [ ] date 32 | - [ ] tags 33 | - [ ] contact information 34 | - [ ] localisation 35 | - [ ] repositoryType 36 | - [ ] userInput 37 | - [ ] fismaLevel 38 | - [ ] group 39 | - [ ] subsetInHealthcare 40 | - [ ] userType 41 | - [ ] repositoryHost 42 | - [ ] maturityModelTier 43 | - [ ] Other (please specify below) 44 | 45 | --- 46 | 47 | ### Please describe the changes needed 48 | 49 | 50 | 51 | ### Additional Context 52 | 53 | 54 | 55 | --- 56 | 57 | ### Helpful Resources 58 | 59 | - [Generate your code.json entry](https://dsacms.github.io/codejson-generator/) - Use this form to generate a valid code.json 60 | - [code.json Guidance](https://github.com/DSACMS/gov-codejson/tree/main/docs) - Documentation on code.json 61 | -------------------------------------------------------------------------------- /tier0/{{cookiecutter.project_slug}}/.github/codejson/hooks/pre_prompt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "⚙️ Welcome to the code.json cookiecutter CLI." 4 | echo -e "📝 We will assist you with creating a code.json file to store metadata of your project." 5 | echo -e "ℹ️ Visit www.github.com/DSACMS/gov-codejson for more information." 6 | -------------------------------------------------------------------------------- /tier0/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{ cookiecutter.project_name }}", 3 | "description": "{{ cookiecutter.description }}", 4 | "longDescription": "{{ cookiecutter.long_description }}", 5 | "status": "{{ cookiecutter.status }}", 6 | "permissions": { 7 | "licenses": [ 8 | { 9 | "URL": "LICENSE", 10 | "name": "{{ cookiecutter.license }}" 11 | } 12 | ], 13 | "usageType": "{{ cookiecutter.usage_type }}", 14 | "exemptionText": "" 15 | }, 16 | "organization": "Centers for Medicare & Medicaid Services", 17 | "repositoryURL": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}", 18 | "repositoryHost": "{{ cookiecutter.repository_host }}", 19 | "repositoryVisibility": "{{ cookiecutter.repository_visibility}}", 20 | "vcs": "{{ cookiecutter.vcs }}", 21 | "laborHours": [""], 22 | "reuseFrequency": { 23 | "forks": "{{ cookiecutter.forks }}" 24 | }, 25 | "platforms": [ "{{ cookiecutter.platforms }}" ], 26 | "categories": [ "{{ cookiecutter.categories }}" ], 27 | "softwareType": "{{ cookiecutter.software_type }}", 28 | "languages": [ "{{ cookiecutter.languages }}" ], 29 | "maintenance": "{{ cookiecutter.maintenance }}", 30 | "contractNumber": "{{ cookiecutter.contract_number }}", 31 | "date": [""], 32 | "tags": [ "{{ cookiecutter.tags }}" ], 33 | "contact": { 34 | "email": "{{ cookiecutter.contact_email }}", 35 | "name": "{{ cookiecutter.contact_name }}" 36 | }, 37 | "feedbackMechanisms": ["{{ cookiecutter.feedback_mechanisms }}"], 38 | "localisation": "{{ cookiecutter.localisation }}", 39 | "repositoryType": "{{ cookiecutter.repository_type }}", 40 | "userInput": "{{ cookiecutter.user_input }}", 41 | "fismaLevel": "{{ cookiecutter.fisma_level }}", 42 | "group": "{{ cookiecutter.group }}", 43 | "projects": ["{{ cookiecutter.projects }}"], 44 | "systems": ["{{ cookiecutter.systems }}"], 45 | "upstream": ["{{ cookiecutter.upstream }}"], 46 | "subsetInHealthcare": ["{{ cookiecutter.subset_in_healthcare }}"], 47 | "userType": ["{{ cookiecutter.user_type }}"], 48 | "maturityModelTier": 0 49 | } -------------------------------------------------------------------------------- /tier0/{{cookiecutter.project_slug}}/.github/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_name": "{{ cookiecutter.project_name }}", 3 | "project_repo_name": "{{ cookiecutter.project_repo_name }}", 4 | "project_org": "{{ cookiecutter.project_org }}", 5 | "description": "A short description of the project.", 6 | "long_description": "A longer description of the project.", 7 | "status": ["ideation", "development", "alpha", "beta", "release candidate", "production", "archival"], 8 | "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"], 9 | "usage_type" : ["openSource", "governmentWideReuse", "exemptByLaw", "exemptByNationalSecurity", "exemptByAgencySystem", "exemptByAgencyMission", "exemptByCIO", "exemptByPolicyDate"], 10 | "repository_host": ["github.com/CMSgov", "github.com/CMS-Enterprise", "github.com/DSACMS", "github.cms.gov", "CCSQ GitHub"], 11 | "repository_visibility": ["public", "private"], 12 | "vcs": ["git", "hg", "svn", "rcs", "bzr"], 13 | "forks": 0, 14 | "platforms": "web, windows, mac, linux, ios, android, other", 15 | "categories": "healthcare", 16 | "software_type":["standalone/mobile", "standalone/iot", "standalone/desktop", "standalone/web", "standalone/backend", "standalone/other", "addon", "library", "configurationFiles"], 17 | "languages": "", 18 | "maintenance": ["internal", "contract", "community", "none"], 19 | "contract_number": 0, 20 | "tags": "dsacms-tier0", 21 | "contact_email": "opensource@cms.hhs.gov", 22 | "contact_name": "CMS Open Source Program Office", 23 | "feedback_mechanisms": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/issues", 24 | "localisation": ["true", "false"], 25 | "repository_type" : ["Package", "Website", "Standards", "Libraries", "Data", "Apps", "Tools", "APIs", "Docs"], 26 | "user_input": ["Yes", "No"], 27 | "fisma_level": ["Low", "Moderate", "High"], 28 | "group": "CMS/OA/DSAC", 29 | "projects": "", 30 | "systems": "", 31 | "upstream": "", 32 | "subset_in_healthcare": "Policy, Operational, Medicare, Medicaid", 33 | "user_type": "Providers, Patients, Government", 34 | "__prompts__": { 35 | "project_name": "What is the name of the project or software?", 36 | "project_repo_name": "What is the name of the repository?", 37 | "project_org": "What CMS GitHub organization is it under?", 38 | "description": "Provide a short description of the software. It should be a single line containing a single sentence. Maximum 150 characters are allowed.", 39 | "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.", 40 | "status": "What is the status of the project?", 41 | "license": "What license is the project under?", 42 | "usage_type": "What is the usage type for this project? For more information on each option, visit github.com/DSACMS/gov-codejson", 43 | "repository_host": "Where is the repository hosted?", 44 | "vcs": "What version control system is used?", 45 | "forks": "How many forks does the repository have?", 46 | "platforms": "What platform does the software runs on? Separate items by commas.", 47 | "categories": "What categories best describes the project? Separate items by commas. List of categories here: https://yml.publiccode.tools/categories-list.html?highlight=categories", 48 | "software_type": "What type of software is the project?", 49 | "languages": "What programming language(s) is the software written in? Separate items by commas.", 50 | "maintenance": "How is the software maintained?", 51 | "contract_number": "What is the contractor number of the project?", 52 | "tags": "Provide a list of tags to describe the software for search. Separate items by commas.", 53 | "contact_name": "A point of contact is needed for the project. What is the name of the point of contact?", 54 | "contact_email": "What is email address of the point of contact?", 55 | "feedback_mechanisms": "What are methods a repository receives feedback from the community (e.g. URL to GitHub repository issues page, website, email)", 56 | "localisation": "Does the software support multiple spoken languages?", 57 | "repository_type": "What type of repository is this project?", 58 | "user_input": "Does the project accept user input? (e.g. allows user to query a database, allows login by users, upload files, etc.)", 59 | "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", 60 | "group": "Which group at CMS is the project part of?", 61 | "projects": "What project is the repository associated with? Separate items by commas.", 62 | "systems": "What systems does the repository use or interface with? Separate items by commas.", 63 | "upstream": "What upstream dependencies does the repository use? Separate items by commas.", 64 | "subset_in_healthcare": "Which subset of healthcare does the project belong to?", 65 | "user_type": "Who are the intended users?" 66 | } 67 | } -------------------------------------------------------------------------------- /tier0/{{cookiecutter.project_slug}}/COMMUNITY.md: -------------------------------------------------------------------------------- 1 | # COMMUNITY.md 2 | 3 | {{ cookiecutter.project_repo_name }} is supported by a dedicated team of individuals fulfilling various roles to ensure its success, security, and alignment with government standards and agency goals. 4 | 5 | ## Project Members 6 | 7 | 10 | 11 | | Role | Name | Affiliation | 12 | | :----- | :------ | :------------- | 13 | | {role} | {names} | {affiliations} | 14 | -------------------------------------------------------------------------------- /tier0/{{cookiecutter.project_slug}}/README.md: -------------------------------------------------------------------------------- 1 | # {{ cookiecutter.project_name }} 2 | 3 | {{ cookiecutter.project_description }} 4 | 5 | ## About the Project 6 | 7 | **{project_statement}** 8 | 9 | 12 | 13 | 16 | 17 | 20 | 21 | 24 | 25 | 30 | 31 | 43 | 44 | 50 | 51 | 58 | 59 | 75 | 76 | ## Policies 77 | 78 | ### Open Source Policy 79 | 80 | We adhere to the [CMS Open Source Policy](https://github.com/CMSGov/cms-open-source-policy). If you have any questions, just [shoot us an email](mailto:opensource@cms.hhs.gov). 81 | 82 | ### Security and Responsible Disclosure Policy 83 | 84 | _Submit a vulnerability:_ Vulnerability reports can be submitted through [Bugcrowd](https://bugcrowd.com/cms-vdp). Reports may be submitted anonymously. If you share contact information, we will acknowledge receipt of your report within 3 business days. 85 | 86 | ### Software Bill of Materials (SBOM) 87 | 88 | A Software Bill of Materials (SBOM) is a formal record containing the details and supply chain relationships of various components used in building software. 89 | 90 | In the spirit of [Executive Order 14028 - Improving the Nation's Cyber Security](https://www.gsa.gov/technology/it-contract-vehicles-and-purchasing-programs/information-technology-category/it-security/executive-order-14028), a SBOM for this repository is provided here: https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/network/dependencies. 91 | 92 | For more information and resources about SBOMs, visit: https://www.cisa.gov/sbom. 93 | 94 | ## Public domain 95 | 96 | This project is in the public domain within the United States, and copyright and related rights in the work worldwide are waived through the [CC0 1.0 Universal public domain dedication](https://creativecommons.org/publicdomain/zero/1.0/) as indicated in [LICENSE](LICENSE). 97 | 98 | All contributions to this project will be released under the CC0 dedication. By submitting a pull request or issue, you are agreeing to comply with this waiver of copyright interest. 99 | -------------------------------------------------------------------------------- /tier1/README.md: -------------------------------------------------------------------------------- 1 | # Tier 1: One-Time Release 2 | 3 | ## What is a Tier 1 Project? 4 | 5 | A **Tier 1** project refers to an **informational or historical** project that has been **released publicly**. However, it does **not** have planned future updates or maintenance by the original authors or contributors. These projects typically include code samples, prototypes, public documentation, or other types of resources that are made available for use but won't receive ongoing updates or active development. 6 | 7 | The main purpose of a Tier 1 project is to share knowledge and provide information from past work. Though available for public consumption, the project is **not expected to evolve or expand** in the future. Contributors may not engage in continuous development or issue resolution. 8 | 9 | ### Key Characteristics of a Tier 1 Project: 10 | 11 | - **Publicly released** without planned future development or maintenance. 12 | - Primarily **informational or historical** in nature. 13 | - May still provide value to the community, but it is not actively worked on. 14 | 15 | --- 16 | 17 | ## Files for a Tier 1 Project 18 | 19 | There are specific files that are required and recommended to include in the repository as part of the CMS Open Source Program Office's repository hygiene guidelines and standards. 20 | 21 | | **File** | **Requirement** | **Description** | 22 | | ----------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | 23 | | `LICENSE` | Mandatory | Defines the licensing terms under which the project is distributed. | 24 | | `code.json` | Mandatory | Contains project metadata following government requirements. | 25 | | `README.md` | Mandatory | Provides a comprehensive overview of the project, including its purpose, how to install or use it, and any relevant information for users or developers. | 26 | | `COMMUNITY.md` | Mandatory | Lists project team members and points of contact. | 27 | | `SECURITY.md` | Mandatory | Outlines the agency's security policies, including how to report security issues or vulnerabilities in the code. | 28 | | `CONTRIBUTING.md` | Recommended | Offers guidelines for contributing to the project, including code standards, how to submit issues, and creating pull requests. | 29 | 30 | For more information about required sections and content within the files above, please visit [maturity-model-tiers.md](https://github.com/DSACMS/repo-scaffolder/blob/main/maturity-model-tiers.md). 31 | 32 | ## .github directory 33 | 34 | The .github directory includes various files such as GitHub action workflows, code.json metadata cookiecutter creation, and issue templates. For more information, please visit the [.github-directory.md]([../docs/.github-directory.md). 35 | 36 | ## Repository Hygiene using repolinter 37 | 38 | As part of maintaining repository hygiene, repolinter is used to identify missing files and information. `repolinter.json` defines a set of checks that verify the existence of these files in your repository. To run repolinter, execute the following command from the root directory: 39 | 40 | ``` 41 | repolinter lint . 42 | ``` 43 | 44 | A GitHub action is also available for running repolinter checks. For more information, please visit [README.md](https://github.com/DSACMS/repo-scaffolder?tab=readme-ov-file#identify-missing-files-and-information-using-repolinter). 45 | -------------------------------------------------------------------------------- /tier1/checklist.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSACMS/repo-scaffolder/d09dcd042f0ea31a044e70e6f7ede97a7cf48d64/tier1/checklist.pdf -------------------------------------------------------------------------------- /tier1/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_name": "My Project", 3 | "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '_') }}", 4 | "project_org": "DSACMS", 5 | "project_repo_name": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}", 6 | "project_description": "This is the project description, could match github.com repo description.", 7 | "project_visibility": ["public", "internal", "private"], 8 | "create_repo": [true, false], 9 | "receive_updates": [true, false], 10 | "add_team": [true, false], 11 | "__prompts__": { 12 | "create_repo": "Would you like to create a repo on github.com?", 13 | "receive_updates": "Would you like to receive updates from the DSACMS team via pull requests?", 14 | "add_team": "Would you like to add project team members to COMMUNITY.md?" 15 | }, 16 | "_copy_without_render": [".github/codejson"] 17 | } 18 | -------------------------------------------------------------------------------- /tier1/hooks/post_gen_project.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import shutil 3 | import os 4 | 5 | REPO_NAME = '{{ cookiecutter.project_repo_name }}' 6 | ORG_NAME = '{{ cookiecutter.project_org }}' 7 | VISIBILITY = '{{cookiecutter.project_visibility}}' 8 | DESCRIPTION = '{{cookiecutter.project_description}}' 9 | CREATE_REPO = '{{cookiecutter.create_repo}}' 10 | RECEIVE_UPDATES = '{{cookiecutter.receive_updates}}' 11 | ADD_TEAM = '{{cookiecutter.add_team}}' 12 | 13 | def createGithubRepo(): 14 | gh_cli_command = [ 15 | "gh", "repo", "create", 16 | f"{ORG_NAME}/{REPO_NAME}", 17 | "--source=.", 18 | f"--{VISIBILITY}", 19 | "--push", 20 | f"--description={DESCRIPTION}", 21 | ] 22 | subprocess.call(gh_cli_command) 23 | subprocess.call(["git", "push", "--set-upstream", "origin", "main"]) 24 | 25 | def addTopic(): 26 | gh_cli_command = [ 27 | "gh", "repo", "edit", 28 | f"{ORG_NAME}/{REPO_NAME}", 29 | "--add-topic=dsacms-tier1", 30 | ] 31 | subprocess.call(gh_cli_command) 32 | 33 | def addTeam(): 34 | team = [] 35 | add_member = True 36 | while add_member: 37 | member = {} 38 | member["role"] = input("Project Member's Role (Engineer, Project Lead, COR, etc...): ").strip() 39 | member["name"] = input("Project Member's Name: ").strip() 40 | member["affiliation"] = input("Project Member's Affiliation (DSAC, CCSQ, CMMI, etc...): ").strip() 41 | team.append(member) 42 | 43 | while True: 44 | add_member_input = input("Would you like to add another project member? [Y/n]: ").strip().lower() 45 | if add_member_input in ("y", "yes", ""): 46 | add_member = True 47 | break 48 | elif add_member_input in ("n", "no"): 49 | add_member = False 50 | break 51 | else: 52 | print("\nInvalid response, please respond with: 'y', 'yes', 'n', 'no', or just press Enter for yes") 53 | 54 | team_table = "" 55 | for member in team: 56 | team_table += f"| {member["role"]} | {member["name"]} | {member["affiliation"]} |\n" 57 | 58 | community_file_path = f"COMMUNITY.md" 59 | 60 | with open(community_file_path, "r") as f: 61 | lines = f.readlines() 62 | 63 | with open(community_file_path, "w") as f: 64 | for line in lines: 65 | if "| {role} | {names} | {affiliations} |" in line: 66 | f.write(team_table) # Replace placeholder line with new table of project team members 67 | else: 68 | f.write(line) 69 | 70 | def moveCookiecutterFile(): 71 | original_dir = os.getcwd() 72 | 73 | try: 74 | github_dir = os.path.join(original_dir, ".github") 75 | os.chdir(github_dir) 76 | 77 | source_path = "cookiecutter.json" 78 | destination_dir = "codejson" 79 | destination_path = os.path.join(destination_dir, "cookiecutter.json") 80 | 81 | shutil.move(source_path, destination_path) 82 | 83 | finally: 84 | # Moves back to project dir 85 | os.chdir(original_dir) 86 | 87 | def main(): 88 | if ADD_TEAM == "True": 89 | addTeam() 90 | 91 | moveCookiecutterFile() 92 | 93 | subprocess.call(["git", "init", "-b", "main"]) 94 | subprocess.call(["git", "add", "."]) 95 | subprocess.call(["git", "commit", "-m", "initial commit"]) 96 | 97 | if CREATE_REPO == "True": 98 | createGithubRepo() 99 | 100 | if RECEIVE_UPDATES == "True": 101 | addTopic() 102 | 103 | print(f"\n****************************************") 104 | print(f"\n✅ {REPO_NAME} has successfully been created!\n") 105 | 106 | if __name__ == "__main__": 107 | main() 108 | -------------------------------------------------------------------------------- /tier1/hooks/pre_prompt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "⚙️ Welcome to the repo-scaffolder cookiecutter CLI." 4 | echo -e "📝 We will assist you with creating a Tier 1 repository." 5 | echo -e "ℹ️ Visit https://github.com/DSACMS/repo-scaffolder/tree/main/tier1 for more information.\n" 6 | echo -e "****************************************\n" -------------------------------------------------------------------------------- /tier1/{{cookiecutter.project_slug}}/.github/ISSUE_TEMPLATE/code_json_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: code.json Update Request 3 | about: Request updates to code.json 4 | title: '[CODE.JSON]: ' 5 | labels: ['code-json-update'] 6 | assignees: '' 7 | --- 8 | 9 | ## Code.json Update Request 10 | 11 | Thank you for helping maintain accurate code.json information for this project! This data helps track open source projects across the organization and ensures compliance with federal open source policies. 12 | 13 | ### Which field would you like to update? 14 | 15 | 16 | 17 | - [ ] name 18 | - [ ] description 19 | - [ ] longDescription 20 | - [ ] status 21 | - [ ] permissions 22 | - [ ] organization 23 | - [ ] repositoryURL 24 | - [ ] vcs 25 | - [ ] laborHours 26 | - [ ] platforms 27 | - [ ] categories 28 | - [ ] softwareType 29 | - [ ] languages 30 | - [ ] maintenance 31 | - [ ] date 32 | - [ ] tags 33 | - [ ] contact information 34 | - [ ] localisation 35 | - [ ] repositoryType 36 | - [ ] userInput 37 | - [ ] fismaLevel 38 | - [ ] group 39 | - [ ] subsetInHealthcare 40 | - [ ] userType 41 | - [ ] repositoryHost 42 | - [ ] maturityModelTier 43 | - [ ] Other (please specify below) 44 | 45 | --- 46 | 47 | ### Please describe the changes needed 48 | 49 | 50 | 51 | ### Additional Context 52 | 53 | 54 | 55 | --- 56 | 57 | ### Helpful Resources 58 | 59 | - [Generate your code.json entry](https://dsacms.github.io/codejson-generator/) - Use this form to generate a valid code.json 60 | - [code.json Guidance](https://github.com/DSACMS/gov-codejson/tree/main/docs) - Documentation on code.json 61 | -------------------------------------------------------------------------------- /tier1/{{cookiecutter.project_slug}}/.github/codejson/hooks/pre_prompt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "⚙️ Welcome to the code.json cookiecutter CLI." 4 | echo -e "📝 We will assist you with creating a code.json file to store metadata of your project." 5 | echo -e "ℹ️ Visit www.github.com/DSACMS/gov-codejson for more information." 6 | -------------------------------------------------------------------------------- /tier1/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{ cookiecutter.project_name }}", 3 | "description": "{{ cookiecutter.description }}", 4 | "longDescription": "{{ cookiecutter.long_description }}", 5 | "status": "{{ cookiecutter.status }}", 6 | "permissions": { 7 | "licenses": [ 8 | { 9 | "URL": "LICENSE", 10 | "name": "{{ cookiecutter.license }}" 11 | } 12 | ], 13 | "usageType": "{{ cookiecutter.usage_type }}", 14 | "exemptionText": "" 15 | }, 16 | "organization": "Centers for Medicare & Medicaid Services", 17 | "repositoryURL": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}", 18 | "repositoryHost": "{{ cookiecutter.repository_host }}", 19 | "repositoryVisibility": "{{ cookiecutter.repository_visibility}}", 20 | "vcs": "{{ cookiecutter.vcs }}", 21 | "laborHours": [""], 22 | "reuseFrequency": { 23 | "forks": "{{ cookiecutter.forks }}" 24 | }, 25 | "platforms": [ "{{ cookiecutter.platforms }}" ], 26 | "categories": [ "{{ cookiecutter.categories }}" ], 27 | "softwareType": "{{ cookiecutter.software_type }}", 28 | "languages": [ "{{ cookiecutter.languages }}" ], 29 | "maintenance": "{{ cookiecutter.maintenance }}", 30 | "contractNumber": "{{ cookiecutter.contract_number }}", 31 | "date": [""], 32 | "tags": [ "{{ cookiecutter.tags }}" ], 33 | "contact": { 34 | "email": "{{ cookiecutter.contact_email }}", 35 | "name": "{{ cookiecutter.contact_name }}" 36 | }, 37 | "feedbackMechanisms": ["{{ cookiecutter.feedback_mechanisms }}"], 38 | "localisation": "{{ cookiecutter.localisation }}", 39 | "repositoryType": "{{ cookiecutter.repository_type }}", 40 | "userInput": "{{ cookiecutter.user_input }}", 41 | "fismaLevel": "{{ cookiecutter.fisma_level }}", 42 | "group": "{{ cookiecutter.group }}", 43 | "projects": ["{{ cookiecutter.projects }}"], 44 | "systems": ["{{ cookiecutter.systems }}"], 45 | "upstream": ["{{ cookiecutter.upstream }}"], 46 | "subsetInHealthcare": ["{{ cookiecutter.subset_in_healthcare }}"], 47 | "userType": ["{{ cookiecutter.user_type }}"], 48 | "maturityModelTier": 1 49 | } -------------------------------------------------------------------------------- /tier1/{{cookiecutter.project_slug}}/.github/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_name": "{{ cookiecutter.project_name }}", 3 | "project_repo_name": "{{ cookiecutter.project_repo_name }}", 4 | "project_org": "{{ cookiecutter.project_org }}", 5 | "description": "A short description of the project.", 6 | "long_description": "A longer description of the project.", 7 | "status": ["ideation", "development", "alpha", "beta", "release candidate", "production", "archival"], 8 | "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"], 9 | "usage_type" : ["openSource", "governmentWideReuse", "exemptByLaw", "exemptByNationalSecurity", "exemptByAgencySystem", "exemptByAgencyMission", "exemptByCIO", "exemptByPolicyDate"], 10 | "repository_host": ["github.com/CMSgov", "github.com/CMS-Enterprise", "github.com/DSACMS", "github.cms.gov", "CCSQ GitHub"], 11 | "repository_visibility": ["public", "private"], 12 | "vcs": ["git", "hg", "svn", "rcs", "bzr"], 13 | "forks": 0, 14 | "platforms": "web, windows, mac, linux, ios, android, other", 15 | "categories": "healthcare", 16 | "software_type":["standalone/mobile", "standalone/iot", "standalone/desktop", "standalone/web", "standalone/backend", "standalone/other", "addon", "library", "configurationFiles"], 17 | "languages": "", 18 | "maintenance": ["internal", "contract", "community", "none"], 19 | "contract_number": 0, 20 | "tags": "dsacms-tier1", 21 | "contact_email": "opensource@cms.hhs.gov", 22 | "contact_name": "CMS Open Source Program Office", 23 | "feedback_mechanisms": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/issues", 24 | "localisation": ["true", "false"], 25 | "repository_type" : ["Package", "Website", "Standards", "Libraries", "Data", "Apps", "Tools", "APIs", "Docs"], 26 | "user_input": ["Yes", "No"], 27 | "fisma_level": ["Low", "Moderate", "High"], 28 | "group": "CMS/OA/DSAC", 29 | "projects": "", 30 | "systems": "", 31 | "upstream": "", 32 | "subset_in_healthcare": "Policy, Operational, Medicare, Medicaid", 33 | "user_type": "Providers, Patients, Government", 34 | "__prompts__": { 35 | "project_name": "What is the name of the project or software?", 36 | "project_repo_name": "What is the name of the repository?", 37 | "project_org": "What CMS GitHub organization is it under?", 38 | "description": "Provide a short description of the software. It should be a single line containing a single sentence. Maximum 150 characters are allowed.", 39 | "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.", 40 | "status": "What is the status of the project?", 41 | "license": "What license is the project under?", 42 | "usage_type": "What is the usage type for this project? For more information on each option, visit github.com/DSACMS/gov-codejson", 43 | "repository_host": "Where is the repository hosted?", 44 | "vcs": "What version control system is used?", 45 | "forks": "How many forks does the repository have?", 46 | "platforms": "What platform does the software runs on? Separate items by commas.", 47 | "categories": "What categories best describes the project? Separate items by commas. List of categories here: https://yml.publiccode.tools/categories-list.html?highlight=categories", 48 | "software_type": "What type of software is the project?", 49 | "languages": "What programming language(s) is the software written in? Separate items by commas.", 50 | "maintenance": "How is the software maintained?", 51 | "contract_number": "What is the contractor number of the project?", 52 | "tags": "Provide a list of tags to describe the software for search. Separate items by commas.", 53 | "contact_name": "A point of contact is needed for the project. What is the name of the point of contact?", 54 | "contact_email": "What is email address of the point of contact?", 55 | "feedback_mechanisms": "What are methods a repository receives feedback from the community (e.g. URL to GitHub repository issues page, website, email)", 56 | "localisation": "Does the software support multiple spoken languages?", 57 | "repository_type": "What type of repository is this project?", 58 | "user_input": "Does the project accept user input? (e.g. allows user to query a database, allows login by users, upload files, etc.)", 59 | "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", 60 | "group": "Which group at CMS is the project part of?", 61 | "projects": "What project is the repository associated with? Separate items by commas.", 62 | "systems": "What systems does the repository use or interface with? Separate items by commas.", 63 | "upstream": "What upstream dependencies does the repository use? Separate items by commas.", 64 | "subset_in_healthcare": "Which subset of healthcare does the project belong to?", 65 | "user_type": "Who are the intended users?" 66 | } 67 | } -------------------------------------------------------------------------------- /tier1/{{cookiecutter.project_slug}}/.github/workflows/gitleaks.yml: -------------------------------------------------------------------------------- 1 | name: Check for Secrets 2 | on: 3 | pull_request: 4 | push: 5 | 6 | jobs: 7 | scan-for-secrets: 8 | name: Run gitleaks 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | with: {fetch-depth: 0} 13 | 14 | - name: Check for GitLeaks 15 | uses: gacts/gitleaks@v1 -------------------------------------------------------------------------------- /tier1/{{cookiecutter.project_slug}}/.github/workflows/repoHygieneCheck.yml: -------------------------------------------------------------------------------- 1 | name: "Repository Hygiene Check" 2 | on: 3 | push: 4 | branches: 5 | - 'main' 6 | workflow_dispatch: 7 | 8 | jobs: 9 | check-first-run: 10 | name: Check For First Run 11 | runs-on: ubuntu-latest 12 | outputs: 13 | {% raw %} 14 | should_run: ${{ steps.check.outputs.should_run }} 15 | {% endraw %} 16 | permissions: 17 | contents: read 18 | pull-requests: write 19 | steps: 20 | - uses: actions/checkout@v4 21 | - id: check 22 | run: | 23 | # If manually triggered, always run 24 | {% raw %} 25 | if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then 26 | {% endraw %} 27 | echo "should_run=true" >> $GITHUB_OUTPUT 28 | exit 0 29 | fi 30 | 31 | # Check if initialization label exists 32 | has_label=$(gh label list --json name | jq '.[] | select(.name=="repolinter-initialized")') 33 | 34 | if [[ -z "$has_label" ]]; then 35 | # First time - create label and allow run 36 | gh label create repolinter-initialized --description "Marks repo as having run initial repolinter check" 37 | echo "should_run=true" >> $GITHUB_OUTPUT 38 | else 39 | echo "should_run=false" >> $GITHUB_OUTPUT 40 | fi 41 | env: 42 | {% raw %} 43 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 44 | {% endraw %} 45 | 46 | resolve-repolinter-json: 47 | name: Get Repolinter Config 48 | needs: check-first-run 49 | {% raw %} 50 | if: needs.check-first-run.outputs.should_run == 'true' 51 | {% endraw %} 52 | uses: DSACMS/repo-scaffolder/.github/workflows/extendJSONFile.yml@main 53 | with: 54 | url_to_json: 'https://raw.githubusercontent.com/DSACMS/repo-scaffolder/main/tier1/%7B%7Bcookiecutter.project_slug%7D%7D/repolinter.json' 55 | 56 | repolinter-checks: 57 | name: Tier 1 Checks 58 | needs: [check-first-run, resolve-repolinter-json] 59 | {% raw %} 60 | if: needs.check-first-run.outputs.should_run == 'true' 61 | {% endraw %} 62 | runs-on: ubuntu-latest 63 | permissions: 64 | contents: write 65 | pull-requests: write 66 | env: 67 | {% raw %} 68 | RAW_JSON: ${{ needs.resolve-repolinter-json.outputs.raw-json }} 69 | {% endraw %} 70 | steps: 71 | - uses: actions/checkout@v4 72 | - run: echo $RAW_JSON > repolinter.json 73 | - uses: DSACMS/repolinter-action@main 74 | with: 75 | config_file: 'repolinter.json' 76 | output_type: 'pull-request' 77 | pull_request_labels: 'repolinter-initialized, cms-oss, cms-gov' 78 | {% raw %} 79 | token: ${{ secrets.REPOLINTER_AUTO_TOKEN }} 80 | {% endraw %} -------------------------------------------------------------------------------- /tier1/{{cookiecutter.project_slug}}/COMMUNITY.md: -------------------------------------------------------------------------------- 1 | # COMMUNITY.md 2 | 3 | {{ cookiecutter.project_repo_name }} is supported by a dedicated team of individuals fulfilling various roles to ensure its success, security, and alignment with government standards and agency goals. 4 | 5 | ## Project Members 6 | 7 | 10 | 11 | | Role | Name | Affiliation | 12 | | :----- | :------ | :------------- | 13 | | {role} | {names} | {affiliations} | 14 | -------------------------------------------------------------------------------- /tier1/{{cookiecutter.project_slug}}/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | 16 | ## Getting Started 17 | 18 | 19 | 20 | ### Building dependencies 21 | 22 | 23 | 24 | ### Building the Project 25 | 26 | 27 | 28 | 44 | 45 | 50 | 51 | 61 | 62 | ### Issues 63 | 64 | 85 | 86 | 94 | 95 | ## Policies 96 | 97 | ### Open Source Policy 98 | 99 | We adhere to the [CMS Open Source 100 | Policy](https://github.com/CMSGov/cms-open-source-policy). If you have any 101 | questions, just [shoot us an email](mailto:opensource@cms.hhs.gov). 102 | 103 | ### Security and Responsible Disclosure Policy 104 | 105 | *Submit a vulnerability:* Vulnerability reports can be submitted through [Bugcrowd](https://bugcrowd.com/cms-vdp). Reports may be submitted anonymously. If you share contact information, we will acknowledge receipt of your report within 3 business days. 106 | 107 | For more information about our Security, Vulnerability, and Responsible Disclosure Policies, see [SECURITY.md](SECURITY.md). 108 | 109 | ## Public domain 110 | 111 | This project is in the public domain within the United States, and copyright and related rights in the work worldwide are waived through the [CC0 1.0 Universal public domain dedication](https://creativecommons.org/publicdomain/zero/1.0/) as indicated in [LICENSE](LICENSE). 112 | 113 | All contributions to this project will be released under the CC0 dedication. By submitting a pull request or issue, you are agreeing to comply with this waiver of copyright interest. 114 | -------------------------------------------------------------------------------- /tier1/{{cookiecutter.project_slug}}/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security and Responsible Disclosure Policy 2 | 3 | The Centers for Medicare & Medicaid Services is committed to ensuring the security of the American public by protecting their information from unwarranted disclosure. We want security researchers to feel comfortable reporting vulnerabilities they have discovered so we can fix them and keep our users safe. We developed our disclosure policy to reflect our values and uphold our sense of responsibility to security researchers who share their expertise with us in good faith. 4 | 5 | *Submit a vulnerability:* Vulnerability reports can be submitted through [Bugcrowd](https://bugcrowd.com/cms-vdp). Reports may be submitted anonymously. If you share contact information, we will acknowledge receipt of your report within 3 business days. 6 | 7 | Review the HHS Disclosure Policy and websites in scope: 8 | [https://www.hhs.gov/vulnerability-disclosure-policy/index.html](https://www.hhs.gov/vulnerability-disclosure-policy/index.html). 9 | 10 | This policy describes *what systems and types of research* are covered under this 11 | policy, *how to send* us vulnerability reports, and *how long* we ask security 12 | researchers to wait before publicly disclosing vulnerabilities. -------------------------------------------------------------------------------- /tier1/{{cookiecutter.project_slug}}/repolinter.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "https://raw.githubusercontent.com/DSACMS/repo-scaffolder/main/tier0/%7B%7Bcookiecutter.project_slug%7D%7D/repolinter.json", 3 | "$schema": "https://raw.githubusercontent.com/todogroup/repolinter/master/rulesets/schema.json", 4 | "version": 2, 5 | "axioms": { 6 | "linguist": "language", 7 | "licensee": "license", 8 | "packagers": "packager" 9 | }, 10 | "rules": { 11 | "security-file-exists": { 12 | "level": "error" 13 | }, 14 | "readme-contains-core-team": { 15 | "level": "error" 16 | }, 17 | "readme-contains-development-and-software-delivery-lifecycle": { 18 | "level": "warning" 19 | }, 20 | "readme-contains-contributing": { 21 | "level": "warning" 22 | }, 23 | "readme-contains-codeowners": { 24 | "level": "warning" 25 | }, 26 | "readme-contains-feedback": { 27 | "level": "warning" 28 | }, 29 | "readme-contains-project-vision": { 30 | "level": "off" 31 | }, 32 | "contributing-contains-getting-started": { 33 | "level": "error" 34 | }, 35 | "contributing-contains-building-dependencies": { 36 | "level": "error" 37 | }, 38 | "contributing-contains-building-the-project": { 39 | "level": "error" 40 | }, 41 | "contributing-contains-writing-issues": { 42 | "level": "error" 43 | }, 44 | "contributing-contains-policies": { 45 | "level": "error" 46 | }, 47 | "contributing-contains-open-source-policy": { 48 | "level": "error" 49 | }, 50 | "contributing-contains-security-and-responsible-disclosure-policy": { 51 | "level": "error" 52 | }, 53 | "contributing-contains-public-domain": { 54 | "level": "error" 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /tier2/README.md: -------------------------------------------------------------------------------- 1 | # Tier 2: Close Collaboration 2 | 3 | ## What is a Tier 2 Project? 4 | 5 | A **Tier 2** project is a **collaborative effort** that typically occurs within a team or operational division (OpDiv). The project follows an **innersource working style**, where internal teams collaborate using open source best practices but within the confines of a private or internal environment. The project is not meant for broad public contribution but rather for **internal collaboration**. 6 | 7 | Innersource projects often allow different teams within the same organization to contribute, fostering collaboration and code-sharing internally while maintaining control over external access. 8 | 9 | ### Key Characteristics of a Tier 2 Project: 10 | 11 | - Focuses on **collaborating within a smaller team** or internal group. 12 | - Utilizes **innersource practices**, where internal teams work collaboratively on code, borrowing from open source workflows but keeping the work within the organization. 13 | - Projects may be shared among internal stakeholders or divisions. 14 | - **Not necessarily accepting contributions** from the broader community. 15 | 16 | --- 17 | 18 | ## Files for a Tier 2 Project 19 | 20 | There are specific files that are required and recommended to include in the repository as part of the CMS Open Source Program Office's repository hygiene guidelines and standards. 21 | 22 | | **File** | **Requirement** | **Description** | 23 | | -------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | 24 | | `LICENSE` | Mandatory | Defines the licensing terms under which the project is distributed. | 25 | | `code.json` | Mandatory | Contains project metadata following government requirements. | 26 | | `README.md` | Mandatory | Provides a comprehensive overview of the project, including its purpose, how to install or use it, and any relevant information for users or developers. | 27 | | `COMMUNITY.md` | Mandatory | Lists project team members and points of contact. | 28 | | `SECURITY.md` | Mandatory | Outlines the agency's security policies, including how to report security issues or vulnerabilities in the code. | 29 | | `CONTRIBUTING.md` | Mandatory | Offers guidelines for contributing to the project, including code standards, how to submit issues, and creating pull requests. | 30 | | `CODE_OF_CONDUCT.md` | Mandatory | Establishes guidelines for professional and respectful behavior to foster a collaborative environment. | 31 | 32 | For more information about required sections and content within the files above, please visit [maturity-model-tiers.md](https://github.com/DSACMS/repo-scaffolder/blob/main/maturity-model-tiers.md). 33 | 34 | ## .github directory 35 | 36 | The .github directory includes various files such as GitHub action workflows, code.json metadata cookiecutter creation, and issue templates. For more information, please visit the [.github-directory.md]([../docs/.github-directory.md). 37 | 38 | ## Repository Hygiene using repolinter 39 | 40 | As part of maintaining repository hygiene, repolinter is used to identify missing files and information. `repolinter.json` defines a set of checks that verify the existence of these files in your repository. To run repolinter, execute the following command from the root directory: 41 | 42 | ``` 43 | repolinter lint . 44 | ``` 45 | 46 | A GitHub action is also available for running repolinter checks. For more information, please visit [README.md](https://github.com/DSACMS/repo-scaffolder?tab=readme-ov-file#identify-missing-files-and-information-using-repolinter). 47 | -------------------------------------------------------------------------------- /tier2/checklist.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSACMS/repo-scaffolder/d09dcd042f0ea31a044e70e6f7ede97a7cf48d64/tier2/checklist.pdf -------------------------------------------------------------------------------- /tier2/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_name": "My Project", 3 | "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '_') }}", 4 | "project_org": "DSACMS", 5 | "project_repo_name": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}", 6 | "project_description": "This is the project description, could match github.com repo description.", 7 | "code_owners": "", 8 | "project_visibility": ["public", "internal", "private"], 9 | "create_repo": [true, false], 10 | "receive_updates": [true, false], 11 | "add_team": [true, false], 12 | "__prompts__": { 13 | "code_owners": "Would you like to add a CODEOWNERS.md to get notified on repository updates? If so, please provide the usernames separated by commas.", 14 | "create_repo": "Would you like to create a repo on github.com?", 15 | "receive_updates": "Would you like to receive updates from the DSACMS team via pull requests?", 16 | "add_team": "Would you like to add project team members to COMMUNITY.md?" 17 | }, 18 | "_copy_without_render": [".github/codejson"] 19 | } 20 | -------------------------------------------------------------------------------- /tier2/hooks/post_gen_project.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import shutil 3 | import os 4 | 5 | REPO_NAME = '{{ cookiecutter.project_repo_name }}' 6 | ORG_NAME = '{{ cookiecutter.project_org }}' 7 | VISIBILITY = '{{cookiecutter.project_visibility}}' 8 | DESCRIPTION = '{{cookiecutter.project_description}}' 9 | CREATE_REPO = '{{cookiecutter.create_repo}}' 10 | RECEIVE_UPDATES = '{{cookiecutter.receive_updates}}' 11 | ADD_TEAM = '{{cookiecutter.add_team}}' 12 | 13 | def createGithubRepo(): 14 | gh_cli_command = [ 15 | "gh", "repo", "create", 16 | f"{ORG_NAME}/{REPO_NAME}", 17 | "--source=.", 18 | f"--{VISIBILITY}", 19 | "--push", 20 | f"--description={DESCRIPTION}", 21 | ] 22 | subprocess.call(gh_cli_command) 23 | subprocess.call(["git", "push", "--set-upstream", "origin", "main"]) 24 | 25 | def addTopic(): 26 | gh_cli_command = [ 27 | "gh", "repo", "edit", 28 | f"{ORG_NAME}/{REPO_NAME}", 29 | "--add-topic=dsacms-tier2", 30 | ] 31 | subprocess.call(gh_cli_command) 32 | 33 | def addTeam(): 34 | team = [] 35 | add_member = True 36 | while add_member: 37 | member = {} 38 | member["role"] = input("Project Member's Role (Engineer, Project Lead, COR, etc...): ").strip() 39 | member["name"] = input("Project Member's Name: ").strip() 40 | member["affiliation"] = input("Project Member's Affiliation (DSAC, CCSQ, CMMI, etc...): ").strip() 41 | team.append(member) 42 | 43 | while True: 44 | add_member_input = input("Would you like to add another project member? [Y/n]: ").strip().lower() 45 | if add_member_input in ("y", "yes", ""): 46 | add_member = True 47 | break 48 | elif add_member_input in ("n", "no"): 49 | add_member = False 50 | break 51 | else: 52 | print("\nInvalid response, please respond with: 'y', 'yes', 'n', 'no', or just press Enter for yes") 53 | 54 | team_table = "" 55 | for member in team: 56 | team_table += f"| {member["role"]} | {member["name"]} | {member["affiliation"]} |\n" 57 | 58 | community_file_path = f"COMMUNITY.md" 59 | 60 | with open(community_file_path, "r") as f: 61 | lines = f.readlines() 62 | 63 | with open(community_file_path, "w") as f: 64 | for line in lines: 65 | if "| {role} | {names} | {affiliations} |" in line: 66 | f.write(team_table) # Replace placeholder line with new table of project team members 67 | else: 68 | f.write(line) 69 | 70 | def moveCookiecutterFile(): 71 | original_dir = os.getcwd() 72 | 73 | try: 74 | github_dir = os.path.join(original_dir, ".github") 75 | os.chdir(github_dir) 76 | 77 | source_path = "cookiecutter.json" 78 | destination_dir = "codejson" 79 | destination_path = os.path.join(destination_dir, "cookiecutter.json") 80 | 81 | shutil.move(source_path, destination_path) 82 | 83 | finally: 84 | # Moves back to project dir 85 | os.chdir(original_dir) 86 | 87 | def main(): 88 | if ADD_TEAM == "True": 89 | addTeam() 90 | 91 | moveCookiecutterFile() 92 | 93 | subprocess.call(["git", "init", "-b", "main"]) 94 | subprocess.call(["git", "add", "."]) 95 | subprocess.call(["git", "commit", "-m", "initial commit"]) 96 | 97 | if CREATE_REPO == "True": 98 | createGithubRepo() 99 | 100 | if RECEIVE_UPDATES == "True": 101 | addTopic() 102 | 103 | print(f"\n****************************************") 104 | print(f"\n✅ {REPO_NAME} has successfully been created!\n") 105 | 106 | if __name__ == "__main__": 107 | main() -------------------------------------------------------------------------------- /tier2/hooks/pre_prompt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "⚙️ Welcome to the repo-scaffolder cookiecutter CLI." 4 | echo -e "📝 We will assist you with creating a Tier 2 repository." 5 | echo -e "ℹ️ Visit https://github.com/DSACMS/repo-scaffolder/tree/main/tier2 for more information.\n" 6 | echo -e "****************************************\n" -------------------------------------------------------------------------------- /tier2/{{cookiecutter.project_slug}}/.github/CODEOWNERS.md: -------------------------------------------------------------------------------- 1 | # Code Owners 2 | 3 | 4 | 5 | {% set code_owners = cookiecutter.code_owners.split(',') %} 6 | {% for item in code_owners %}- {{ item }} 7 | {% endfor %} 8 | 9 | ## Repo Domains 10 | 11 | 32 | 33 | /docs/ {Git usernames of documentation owners} 34 | /frontend/ {Git usernames of frontend owners} 35 | -------------------------------------------------------------------------------- /tier2/{{cookiecutter.project_slug}}/.github/ISSUE_TEMPLATE/add_team_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Add Team to Repository Request Ticket 3 | about: Ticket for requesting team to be added to repository 4 | title: "[REQUEST]: " 5 | labels: # TODO: Add labels for categorization of requests 6 | assignees: # TODO: Add organization owner or help desk team 7 | --- 8 | 9 | ## Request a New Team to be Added to a Repository 10 | 11 | Please fill out the form below to request a new team to be added to a repository. 12 | 13 | ### Information Required 14 | 15 | Team Name: 16 | Reason for Access: 17 | 18 | ### Additional Notes (Optional) 19 | 20 | 21 | -------------------------------------------------------------------------------- /tier2/{{cookiecutter.project_slug}}/.github/ISSUE_TEMPLATE/code_json_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: code.json Update Request 3 | about: Request updates to code.json 4 | title: '[CODE.JSON]: ' 5 | labels: ['code-json-update'] 6 | assignees: '' 7 | --- 8 | 9 | ## Code.json Update Request 10 | 11 | Thank you for helping maintain accurate code.json information for this project! This data helps track open source projects across the organization and ensures compliance with federal open source policies. 12 | 13 | ### Which field would you like to update? 14 | 15 | 16 | 17 | - [ ] name 18 | - [ ] description 19 | - [ ] longDescription 20 | - [ ] status 21 | - [ ] permissions 22 | - [ ] organization 23 | - [ ] repositoryURL 24 | - [ ] vcs 25 | - [ ] laborHours 26 | - [ ] platforms 27 | - [ ] categories 28 | - [ ] softwareType 29 | - [ ] languages 30 | - [ ] maintenance 31 | - [ ] date 32 | - [ ] tags 33 | - [ ] contact information 34 | - [ ] localisation 35 | - [ ] repositoryType 36 | - [ ] userInput 37 | - [ ] fismaLevel 38 | - [ ] group 39 | - [ ] subsetInHealthcare 40 | - [ ] userType 41 | - [ ] repositoryHost 42 | - [ ] maturityModelTier 43 | - [ ] Other (please specify below) 44 | 45 | --- 46 | 47 | ### Please describe the changes needed 48 | 49 | 50 | 51 | ### Additional Context 52 | 53 | 54 | 55 | --- 56 | 57 | ### Helpful Resources 58 | 59 | - [Generate your code.json entry](https://dsacms.github.io/codejson-generator/) - Use this form to generate a valid code.json 60 | - [code.json Guidance](https://github.com/DSACMS/gov-codejson/tree/main/docs) - Documentation on code.json 61 | -------------------------------------------------------------------------------- /tier2/{{cookiecutter.project_slug}}/.github/ISSUE_TEMPLATE/outside_collaborator_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Outside Collaborator Repository Access Request Ticket 3 | about: Ticket for requesting outside collaborator to be added to repository 4 | title: "[REQUEST]: " 5 | labels: # TODO: Add labels for categorization of requests 6 | assignees: # TODO: Add organization owner or help desk team 7 | --- 8 | 9 | ## Request an outside collaborator to be added to repository 10 | 11 | For individuals that are not members of the {{ cookiecutter.project_org }} GitHub organization, these outside collaborators can request access to a repository. Fill out this issue to file the request or make a pull request to the `COMMUNITY.md` file, then a repository admin will grant access. 12 | 13 | ### Information Required 14 | 15 | Name of individual: 16 | GitHub username: 17 | Role in project: 18 | Role in repository according to COMMUNITY.md (Maintainer, Approver, Reviewer): 19 | 20 | ### Additional Notes (Optional) 21 | 22 | 23 | -------------------------------------------------------------------------------- /tier2/{{cookiecutter.project_slug}}/.github/codejson/hooks/pre_prompt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "⚙️ Welcome to the code.json cookiecutter CLI." 4 | echo -e "📝 We will assist you with creating a code.json file to store metadata of your project." 5 | echo -e "ℹ️ Visit www.github.com/DSACMS/gov-codejson for more information." 6 | -------------------------------------------------------------------------------- /tier2/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{ cookiecutter.project_name }}", 3 | "description": "{{ cookiecutter.description }}", 4 | "longDescription": "{{ cookiecutter.long_description }}", 5 | "status": "{{ cookiecutter.status }}", 6 | "permissions": { 7 | "licenses": [ 8 | { 9 | "URL": "LICENSE", 10 | "name": "{{ cookiecutter.license }}" 11 | } 12 | ], 13 | "usageType": "{{ cookiecutter.usage_type }}", 14 | "exemptionText": "" 15 | }, 16 | "organization": "Centers for Medicare & Medicaid Services", 17 | "repositoryURL": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}", 18 | "repositoryHost": "{{ cookiecutter.repository_host }}", 19 | "repositoryVisibility": "{{ cookiecutter.repository_visibility}}", 20 | "vcs": "{{ cookiecutter.vcs }}", 21 | "laborHours": [""], 22 | "reuseFrequency": { 23 | "forks": "{{ cookiecutter.forks }}" 24 | }, 25 | "platforms": [ "{{ cookiecutter.platforms }}" ], 26 | "categories": [ "{{ cookiecutter.categories }}" ], 27 | "softwareType": "{{ cookiecutter.software_type }}", 28 | "languages": [ "{{ cookiecutter.languages }}" ], 29 | "maintenance": "{{ cookiecutter.maintenance }}", 30 | "contractNumber": "{{ cookiecutter.contract_number }}", 31 | "date": [""], 32 | "tags": [ "{{ cookiecutter.tags }}" ], 33 | "contact": { 34 | "email": "{{ cookiecutter.contact_email }}", 35 | "name": "{{ cookiecutter.contact_name }}" 36 | }, 37 | "feedbackMechanisms": ["{{ cookiecutter.feedback_mechanisms }}"], 38 | "localisation": "{{ cookiecutter.localisation }}", 39 | "repositoryType": "{{ cookiecutter.repository_type }}", 40 | "userInput": "{{ cookiecutter.user_input }}", 41 | "fismaLevel": "{{ cookiecutter.fisma_level }}", 42 | "group": "{{ cookiecutter.group }}", 43 | "projects": ["{{ cookiecutter.projects }}"], 44 | "systems": ["{{ cookiecutter.systems }}"], 45 | "upstream": ["{{ cookiecutter.upstream }}"], 46 | "subsetInHealthcare": ["{{ cookiecutter.subset_in_healthcare }}"], 47 | "userType": ["{{ cookiecutter.user_type }}"], 48 | "maturityModelTier": 2 49 | } -------------------------------------------------------------------------------- /tier2/{{cookiecutter.project_slug}}/.github/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_name": "{{ cookiecutter.project_name}}", 3 | "project_repo_name": "{{ cookiecutter.project_repo_name }}", 4 | "project_org": "{{ cookiecutter.project_org }}", 5 | "description": "A short description of the project.", 6 | "long_description": "A longer description of the project.", 7 | "status": ["ideation", "development", "alpha", "beta", "release candidate", "production", "archival"], 8 | "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"], 9 | "usage_type" : ["openSource", "governmentWideReuse", "exemptByLaw", "exemptByNationalSecurity", "exemptByAgencySystem", "exemptByAgencyMission", "exemptByCIO", "exemptByPolicyDate"], 10 | "repository_host": ["github.com/CMSgov", "github.com/CMS-Enterprise", "github.com/DSACMS", "github.cms.gov", "CCSQ GitHub"], 11 | "repository_visibility": ["public", "private"], 12 | "vcs": ["git", "hg", "svn", "rcs", "bzr"], 13 | "forks": 0, 14 | "platforms": "web, windows, mac, linux, ios, android, other", 15 | "categories": "healthcare", 16 | "software_type":["standalone/mobile", "standalone/iot", "standalone/desktop", "standalone/web", "standalone/backend", "standalone/other", "addon", "library", "configurationFiles"], 17 | "languages": "", 18 | "maintenance": ["internal", "contract", "community", "none"], 19 | "contract_number": 0, 20 | "tags": "dsacms-tier2", 21 | "contact_email": "opensource@cms.hhs.gov", 22 | "contact_name": "CMS Open Source Program Office", 23 | "feedback_mechanisms": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/issues", 24 | "localisation": ["true", "false"], 25 | "repository_type" : ["Package", "Website", "Standards", "Libraries", "Data", "Apps", "Tools", "APIs", "Docs"], 26 | "user_input": ["Yes", "No"], 27 | "fisma_level": ["Low", "Moderate", "High"], 28 | "group": "CMS/OA/DSAC", 29 | "projects": "", 30 | "systems": "", 31 | "upstream": "", 32 | "subset_in_healthcare": "Policy, Operational, Medicare, Medicaid", 33 | "user_type": "Providers, Patients, Government", 34 | "__prompts__": { 35 | "project_name": "What is the name of the project or software?", 36 | "project_repo_name": "What is the name of the repository?", 37 | "project_org": "What CMS GitHub organization is it under?", 38 | "description": "Provide a short description of the software. It should be a single line containing a single sentence. Maximum 150 characters are allowed.", 39 | "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.", 40 | "status": "What is the status of the project?", 41 | "license": "What license is the project under?", 42 | "usage_type": "What is the usage type for this project? For more information on each option, visit github.com/DSACMS/gov-codejson", 43 | "repository_host": "Where is the repository hosted?", 44 | "vcs": "What version control system is used?", 45 | "forks": "How many forks does the repository have?", 46 | "platforms": "What platform does the software runs on? Separate items by commas.", 47 | "categories": "What categories best describes the project? Separate items by commas. List of categories here: https://yml.publiccode.tools/categories-list.html?highlight=categories", 48 | "software_type": "What type of software is the project?", 49 | "languages": "What programming language(s) is the software written in? Separate items by commas.", 50 | "maintenance": "How is the software maintained?", 51 | "contract_number": "What is the contractor number of the project?", 52 | "tags": "Provide a list of tags to describe the software for search. Separate items by commas.", 53 | "contact_name": "A point of contact is needed for the project. What is the name of the point of contact?", 54 | "contact_email": "What is email address of the point of contact?", 55 | "feedback_mechanisms": "What are methods a repository receives feedback from the community (e.g. URL to GitHub repository issues page, website, email)", 56 | "localisation": "Does the software support multiple spoken languages?", 57 | "repository_type": "What type of repository is this project?", 58 | "user_input": "Does the project accept user input? (e.g. allows user to query a database, allows login by users, upload files, etc.)", 59 | "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", 60 | "group": "Which group at CMS is the project part of?", 61 | "projects": "What project is the repository associated with? Separate items by commas.", 62 | "systems": "What systems does the repository use or interface with? Separate items by commas.", 63 | "upstream": "What upstream dependencies does the repository use? Separate items by commas.", 64 | "subset_in_healthcare": "Which subset of healthcare does the project belong to?", 65 | "user_type": "Who are the intended users?" 66 | } 67 | } -------------------------------------------------------------------------------- /tier2/{{cookiecutter.project_slug}}/.github/workflows/auto-changelog.yml: -------------------------------------------------------------------------------- 1 | name: Changelog 2 | on: 3 | release: 4 | types: 5 | - created 6 | jobs: 7 | changelog: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: "Auto Generate changelog" 11 | uses: heinrichreimer/action-github-changelog-generator@v2.3 12 | with: 13 | {% raw %} 14 | token: ${{ secrets.GITHUB_TOKEN }} 15 | {% endraw %} -------------------------------------------------------------------------------- /tier2/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml: -------------------------------------------------------------------------------- 1 | name: Update Contributors Information 2 | 3 | on: 4 | workflow_dispatch: {} 5 | schedule: 6 | # Weekly on Saturdays. 7 | - cron: "30 1 * * 6" 8 | push: 9 | branches: [main] 10 | 11 | jobs: 12 | update-contributors: 13 | runs-on: ubuntu-latest 14 | permissions: 15 | contents: write 16 | pull-requests: write 17 | 18 | steps: 19 | - name: Checkout repository 20 | uses: actions/checkout@v4 21 | with: 22 | fetch-depth: 0 23 | 24 | - name: Update contributor list 25 | id: contrib_list 26 | uses: akhilmhdh/contributors-readme-action@v2.3.10 27 | env: 28 | {% raw %} 29 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 30 | {% endraw %} 31 | with: 32 | readme_path: COMMUNITY.md 33 | use_username: false 34 | commit_message: "update contributors information" 35 | 36 | - name: Get contributors count 37 | id: get_contributors 38 | env: 39 | {% raw %} 40 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 41 | {% endraw %} 42 | 43 | run: | 44 | OWNER=$(echo $GITHUB_REPOSITORY | cut -d'/' -f1) 45 | REPO=$(echo $GITHUB_REPOSITORY | cut -d'/' -f2) 46 | QUERY='query { repository(owner: \"'"$OWNER"'\", name: \"'"$REPO"'\") { collaborators { totalCount } } }' 47 | 48 | CONTRIBUTORS=$(gh api \ 49 | -H "Accept: application/vnd.github+json" \ 50 | -H "X-GitHub-Api-Version: 2022-11-28" \ 51 | "/repos/$OWNER/$REPO/contributors?per_page=100" | \ 52 | jq '[.[] | select(.type != "Bot" and (.login | test("\\[bot\\]$") | not) and (.login | test("-bot$") | not))] | length') 53 | 54 | echo "Total contributors: $CONTRIBUTORS" 55 | echo "contributors=$CONTRIBUTORS" >> $GITHUB_OUTPUT 56 | 57 | 58 | - name: Update COMMUNITY.md 59 | run: | 60 | {% raw %} 61 | CONTRIBUTORS="${{ steps.get_contributors.outputs.contributors }}" 62 | {% endraw %} 63 | 64 | perl -i -pe 's/().*?()/$1 '"$CONTRIBUTORS"' $2/' COMMUNITY.md 65 | 66 | git config user.name 'github-actions[bot]' 67 | git config user.email 'github-actions[bot]@users.noreply.github.com' 68 | git add COMMUNITY.md 69 | git commit -m "update contributors count to $CONTRIBUTORS" || exit 0 70 | 71 | - name: Push protected 72 | uses: CasperWA/push-protected@v2 73 | with: 74 | {% raw %} 75 | token: ${{ secrets.PUSH_TO_PROTECTED_BRANCH }} 76 | {% endraw %} 77 | 78 | branch: main -------------------------------------------------------------------------------- /tier2/{{cookiecutter.project_slug}}/.github/workflows/gitleaks.yml: -------------------------------------------------------------------------------- 1 | name: Check for Secrets 2 | on: 3 | pull_request: 4 | push: 5 | 6 | jobs: 7 | scan-for-secrets: 8 | name: Run gitleaks 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | with: {fetch-depth: 0} 13 | 14 | - name: Check for GitLeaks 15 | uses: gacts/gitleaks@v1 -------------------------------------------------------------------------------- /tier2/{{cookiecutter.project_slug}}/.github/workflows/repoHygieneCheck.yml: -------------------------------------------------------------------------------- 1 | name: "Repository Hygiene Check" 2 | on: 3 | push: 4 | branches: 5 | - 'main' 6 | workflow_dispatch: 7 | 8 | jobs: 9 | check-first-run: 10 | name: Check For First Run 11 | runs-on: ubuntu-latest 12 | outputs: 13 | {% raw %} 14 | should_run: ${{ steps.check.outputs.should_run }} 15 | {% endraw %} 16 | permissions: 17 | contents: read 18 | pull-requests: write 19 | steps: 20 | - uses: actions/checkout@v4 21 | - id: check 22 | run: | 23 | # If manually triggered, always run 24 | {% raw %} 25 | if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then 26 | {% endraw %} 27 | echo "should_run=true" >> $GITHUB_OUTPUT 28 | exit 0 29 | fi 30 | 31 | # Check if initialization label exists 32 | has_label=$(gh label list --json name | jq '.[] | select(.name=="repolinter-initialized")') 33 | 34 | if [[ -z "$has_label" ]]; then 35 | # First time - create label and allow run 36 | gh label create repolinter-initialized --description "Marks repo as having run initial repolinter check" 37 | echo "should_run=true" >> $GITHUB_OUTPUT 38 | else 39 | echo "should_run=false" >> $GITHUB_OUTPUT 40 | fi 41 | env: 42 | {% raw %} 43 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 44 | {% endraw %} 45 | 46 | resolve-repolinter-json: 47 | name: Get Repolinter Config 48 | needs: check-first-run 49 | {% raw %} 50 | if: needs.check-first-run.outputs.should_run == 'true' 51 | {% endraw %} 52 | uses: DSACMS/repo-scaffolder/.github/workflows/extendJSONFile.yml@main 53 | with: 54 | url_to_json: 'https://raw.githubusercontent.com/DSACMS/repo-scaffolder/main/tier2/%7B%7Bcookiecutter.project_slug%7D%7D/repolinter.json' 55 | 56 | repolinter-checks: 57 | name: Tier 2 Checks 58 | needs: [check-first-run, resolve-repolinter-json] 59 | {% raw %} 60 | if: needs.check-first-run.outputs.should_run == 'true' 61 | {% endraw %} 62 | runs-on: ubuntu-latest 63 | permissions: 64 | contents: write 65 | pull-requests: write 66 | env: 67 | {% raw %} 68 | RAW_JSON: ${{ needs.resolve-repolinter-json.outputs.raw-json }} 69 | {% endraw %} 70 | steps: 71 | - uses: actions/checkout@v4 72 | - run: echo $RAW_JSON > repolinter.json 73 | - uses: DSACMS/repolinter-action@main 74 | with: 75 | config_file: 'repolinter.json' 76 | output_type: 'pull-request' 77 | pull_request_labels: 'repolinter-initialized, cms-oss, cms-gov' 78 | {% raw %} 79 | token: ${{ secrets.REPOLINTER_AUTO_TOKEN }} 80 | {% endraw %} -------------------------------------------------------------------------------- /tier2/{{cookiecutter.project_slug}}/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. 4 | 5 | We are committed to making participation in this project a harassment-free experience for everyone, regardless of the level of experience, gender, gender identity, expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 6 | 7 | Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. 8 | 9 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned with this Code of Conduct. 10 | 11 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers at opensource@cms.hhs.gov. 12 | 13 | This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/) 14 | 15 | ## Acknowledgements 16 | 17 | This CODE_OF_CONDUCT.md was originally forked from the [United States Digital Service](https://usds.gov) [Justice40](https://thejustice40.com) open source [repository](https://github.com/usds/justice40-tool), and we would like to acknowledge and thank the community for their contributions. 18 | -------------------------------------------------------------------------------- /tier2/{{cookiecutter.project_slug}}/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security and Responsible Disclosure Policy 2 | 3 | The Centers for Medicare & Medicaid Services is committed to ensuring the security of the American public by protecting their information from unwarranted disclosure. We want security researchers to feel comfortable reporting vulnerabilities they have discovered so we can fix them and keep our users safe. We developed our disclosure policy to reflect our values and uphold our sense of responsibility to security researchers who share their expertise with us in good faith. 4 | 5 | *Submit a vulnerability:* Vulnerability reports can be submitted through [Bugcrowd](https://bugcrowd.com/cms-vdp). Reports may be submitted anonymously. If you share contact information, we will acknowledge receipt of your report within 3 business days. 6 | 7 | Review the HHS Disclosure Policy and websites in scope: 8 | [https://www.hhs.gov/vulnerability-disclosure-policy/index.html](https://www.hhs.gov/vulnerability-disclosure-policy/index.html). 9 | 10 | This policy describes *what systems and types of research* are covered under this 11 | policy, *how to send* us vulnerability reports, and *how long* we ask security 12 | researchers to wait before publicly disclosing vulnerabilities. -------------------------------------------------------------------------------- /tier2/{{cookiecutter.project_slug}}/repolinter.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "https://raw.githubusercontent.com/DSACMS/repo-scaffolder/main/tier1/%7B%7Bcookiecutter.project_slug%7D%7D/repolinter.json", 3 | "$schema": "https://raw.githubusercontent.com/todogroup/repolinter/master/rulesets/schema.json", 4 | "version": 2, 5 | "axioms": { 6 | "linguist": "language", 7 | "licensee": "license", 8 | "packagers": "packager" 9 | }, 10 | "rules": { 11 | "contributing-file-exists": { 12 | "level": "error" 13 | }, 14 | "code-of-conduct-file-exists": { 15 | "level": "error" 16 | }, 17 | "community-guidelines-file-exists": { 18 | "level": "error" 19 | }, 20 | "readme-contains-project-vision": { 21 | "level": "error" 22 | }, 23 | "readme-contains-project-mission": { 24 | "level": "error" 25 | }, 26 | "readme-contains-agency-mission": { 27 | "level": "error" 28 | }, 29 | "readme-contains-team-mission": { 30 | "level": "error" 31 | }, 32 | "readme-contains-core-team": { 33 | "level": "error" 34 | }, 35 | "readme-contains-documentation-index": { 36 | "level": "warning" 37 | }, 38 | "readme-contains-repository-structure": { 39 | "level": "warning" 40 | }, 41 | "readme-contains-development-and-software-delivery-lifecycle": { 42 | "level": "warning" 43 | }, 44 | "readme-contains-local-development": { 45 | "level": "error" 46 | }, 47 | "readme-contains-coding-style-and-linters": { 48 | "level": "error" 49 | }, 50 | "readme-contains-branching-model": { 51 | "level": "warning" 52 | }, 53 | "readme-contains-contributing": { 54 | "level": "error" 55 | }, 56 | "readme-contains-codeowners": { 57 | "level": "error" 58 | }, 59 | "readme-contains-community": { 60 | "level": "error" 61 | }, 62 | "readme-contains-community-guidelines": { 63 | "level": "error" 64 | }, 65 | "readme-contains-governance": { 66 | "level": "warning" 67 | }, 68 | "readme-contains-feedback": { 69 | "level": "warning" 70 | }, 71 | "readme-contains-glossary": { 72 | "level": "warning" 73 | }, 74 | "contributing-contains-how-to-contribute": { 75 | "level": "error" 76 | }, 77 | "contributing-contains-getting-started": { 78 | "level": "error" 79 | }, 80 | "contributing-contains-team-specific-guidelines": { 81 | "level": "warning" 82 | }, 83 | "contributing-contains-building-dependencies": { 84 | "level": "error" 85 | }, 86 | "contributing-contains-building-the-project": { 87 | "level": "error" 88 | }, 89 | "contributing-contains-workflow-and-branching": { 90 | "level": "error" 91 | }, 92 | "contributing-contains-testing-conventions": { 93 | "level": "warning" 94 | }, 95 | "contributing-contains-coding-style-and-linters": { 96 | "level": "error" 97 | }, 98 | "contributing-contains-writing-issues": { 99 | "level": "error" 100 | }, 101 | "contributing-contains-writing-pull-requests": { 102 | "level": "warning" 103 | }, 104 | "contributing-contains-reviewing-pull-requests": { 105 | "level": "warning" 106 | }, 107 | "contributing-contains-shipping-releases": { 108 | "level": "warning" 109 | }, 110 | "contributing-contains-documentation": { 111 | "level": "warning" 112 | }, 113 | "contributing-contains-policies": { 114 | "level": "error" 115 | }, 116 | "contributing-contains-open-source-policy": { 117 | "level": "error" 118 | }, 119 | "contributing-contains-security-and-responsible-disclosure-policy": { 120 | "level": "error" 121 | }, 122 | "contributing-contains-public-domain": { 123 | "level": "error" 124 | }, 125 | "community-contains-table-of-project-members": { 126 | "level": "error" 127 | }, 128 | "community-contains-roles-and-responsibilities": { 129 | "level": "warning" 130 | }, 131 | "community-contains-maintainers-list": { 132 | "level": "warning" 133 | }, 134 | "community-contains-approvers-list": { 135 | "level": "warning" 136 | }, 137 | "community-contains-reviewers-list": { 138 | "level": "warning" 139 | }, 140 | "community-contains-contributors": { 141 | "level": "warning" 142 | }, 143 | "community-contains-alumni": { 144 | "level": "warning" 145 | }, 146 | "community-contains-principles": { 147 | "level": "error" 148 | }, 149 | "community-contains-community-guidelines": { 150 | "level": "error" 151 | }, 152 | "community-contains-acknowledgements": { 153 | "level": "error" 154 | }, 155 | "code-of-conduct-contains-contributor-code-of-conduct": { 156 | "level": "error" 157 | }, 158 | "code-of-conduct-contains-acknowledgements": { 159 | "level": "error" 160 | } 161 | } 162 | } -------------------------------------------------------------------------------- /tier3/README.md: -------------------------------------------------------------------------------- 1 | # Tier 3: Working in Public 2 | 3 | ## What is a Tier 3 Project? 4 | 5 | A **Tier 3** project is an **open collaboration** effort where the work is conducted in public. The project is led by smaller, semi-open teams but encourages **limited external contributions**. The work is typically **open source**, but the direction and maintenance of the project are CMS-led, controlled by a smaller group or team, rather than a large, decentralized community. Tier 3 projects may be public-facing tools, utilities, or websites, where external contributions are welcomed but managed closely by the core team. 6 | 7 | ### Key Characteristics of a Tier 3 Project: 8 | 9 | - **Collaborative in public**, where the work is open to external stakeholders. 10 | - Led by a **CMS team** (often organizational or tool-specific). 11 | - Accepts **limited contributions from external sources**, typically following specific guidelines. 12 | - Publicly accessible code and documentation. 13 | - Maintenance and decision-making are generally led by CMS. 14 | 15 | --- 16 | 17 | ## Files for a Tier 3 Project 18 | 19 | There are specific files that are required and recommended to include in the repository as part of the CMS Open Source Program Office's repository hygiene guidelines and standards. 20 | 21 | | **File** | **Requirement** | **Description** | 22 | | -------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | 23 | | `LICENSE` | Mandatory | Defines the licensing terms under which the project is distributed. | 24 | | `code.json` | Mandatory | Contains project metadata following government requirements. | 25 | | `README.md` | Mandatory | Provides a comprehensive overview of the project, including its purpose, how to install or use it, and any relevant information for users or developers. | 26 | | `COMMUNITY.md` | Mandatory | Lists project team members and points of contact with detailed roles and responsibilities. | 27 | | `SECURITY.md` | Mandatory | Outlines the agency's security policies, including how to report security issues or vulnerabilities in the code. | 28 | | `CONTRIBUTING.md` | Mandatory | Offers guidelines for contributing to the project, including code standards, how to submit issues, and creating pull requests. | 29 | | `CODE_OF_CONDUCT.md` | Mandatory | Establishes guidelines for acceptable behavior within the community, setting expectations for how contributors should interact in a respectful and collaborative manner. | 30 | | `GOVERNANCE.md` | Recommended | Describes the governance model of the project, such as decision-making processes and rules for contributing. It ensures a transparent process for managing the project. | 31 | 32 | For more information about required sections and content within the files above, please visit [maturity-model-tiers.md](https://github.com/DSACMS/repo-scaffolder/blob/main/maturity-model-tiers.md). 33 | 34 | ## .github directory 35 | 36 | The .github directory includes various files such as GitHub action workflows, code.json metadata cookiecutter creation, and issue templates. For more information, please visit the [.github-directory.md]([../docs/.github-directory.md). 37 | 38 | ## Repository Hygiene using repolinter 39 | 40 | As part of maintaining repository hygiene, repolinter is used to identify missing files and information. `repolinter.json` defines a set of checks that verify the existence of these files in your repository. To run repolinter, execute the following command from the root directory: 41 | 42 | ``` 43 | repolinter lint . 44 | ``` 45 | 46 | A GitHub action is also available for running repolinter checks. For more information, please visit [README.md](https://github.com/DSACMS/repo-scaffolder?tab=readme-ov-file#identify-missing-files-and-information-using-repolinter). 47 | -------------------------------------------------------------------------------- /tier3/checklist.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSACMS/repo-scaffolder/d09dcd042f0ea31a044e70e6f7ede97a7cf48d64/tier3/checklist.pdf -------------------------------------------------------------------------------- /tier3/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_name": "My Project", 3 | "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '_') }}", 4 | "project_org": "DSACMS", 5 | "project_repo_name": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}", 6 | "project_description": "This is the project description, could match github.com repo description.", 7 | "code_owners": "", 8 | "project_visibility": ["public", "internal", "private"], 9 | "create_repo": [true, false], 10 | "receive_updates": [true, false], 11 | "add_team": [true, false], 12 | "add_maintainer": [true, false], 13 | "__prompts__": { 14 | "code_owners": "Would you like to add a CODEOWNERS.md to get notified on repository updates? If so, please provide the usernames separated by commas.", 15 | "create_repo": "Would you like to create a repo on github.com?", 16 | "receive_updates": "Would you like to receive updates from the DSACMS team via pull requests?", 17 | "add_team": "Would you like to add project team members to COMMUNITY.md?", 18 | "add_maintainer": "Would you like to add maintainers, approvers, and/or reviewers to COMMUNITY.md?" 19 | }, 20 | "_copy_without_render": [".github/codejson"] 21 | } 22 | -------------------------------------------------------------------------------- /tier3/hooks/pre_prompt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "⚙️ Welcome to the repo-scaffolder cookiecutter CLI." 4 | echo -e "📝 We will assist you with creating a Tier 3 repository." 5 | echo -e "ℹ️ Visit https://github.com/DSACMS/repo-scaffolder/tree/main/tier3 for more information.\n" 6 | echo -e "****************************************\n" -------------------------------------------------------------------------------- /tier3/{{cookiecutter.project_slug}}/.github/CODEOWNERS.md: -------------------------------------------------------------------------------- 1 | # Code Owners 2 | 3 | 4 | 5 | {% set code_owners = cookiecutter.code_owners.split(',') %} 6 | {% for item in code_owners %}- {{ item }} 7 | {% endfor %} 8 | 9 | ## Repo Domains 10 | 11 | 32 | 33 | /docs/ {Git usernames of documentation owners} 34 | /frontend/ {Git usernames of frontend owners} 35 | -------------------------------------------------------------------------------- /tier3/{{cookiecutter.project_slug}}/.github/ISSUE_TEMPLATE/add_team_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Add Team to Repository Request Ticket 3 | about: Ticket for requesting team to be added to repository 4 | title: "[REQUEST]: " 5 | labels: # TODO: Add labels for categorization of requests 6 | assignees: # TODO: Add organization owner or help desk team 7 | --- 8 | 9 | ## Request a New Team to be Added to a Repository 10 | 11 | Please fill out the form below to request a new team to be added to a repository. 12 | 13 | ### Information Required 14 | 15 | Team Name: 16 | Reason for Access: 17 | 18 | ### Additional Notes (Optional) 19 | 20 | 21 | -------------------------------------------------------------------------------- /tier3/{{cookiecutter.project_slug}}/.github/ISSUE_TEMPLATE/code_json_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: code.json Update Request 3 | about: Request updates to code.json 4 | title: '[CODE.JSON]: ' 5 | labels: ['code-json-update'] 6 | assignees: '' 7 | --- 8 | 9 | ## Code.json Update Request 10 | 11 | Thank you for helping maintain accurate code.json information for this project! This data helps track open source projects across the organization and ensures compliance with federal open source policies. 12 | 13 | ### Which field would you like to update? 14 | 15 | 16 | 17 | - [ ] name 18 | - [ ] description 19 | - [ ] longDescription 20 | - [ ] status 21 | - [ ] permissions 22 | - [ ] organization 23 | - [ ] repositoryURL 24 | - [ ] vcs 25 | - [ ] laborHours 26 | - [ ] platforms 27 | - [ ] categories 28 | - [ ] softwareType 29 | - [ ] languages 30 | - [ ] maintenance 31 | - [ ] date 32 | - [ ] tags 33 | - [ ] contact information 34 | - [ ] localisation 35 | - [ ] repositoryType 36 | - [ ] userInput 37 | - [ ] fismaLevel 38 | - [ ] group 39 | - [ ] subsetInHealthcare 40 | - [ ] userType 41 | - [ ] repositoryHost 42 | - [ ] maturityModelTier 43 | - [ ] Other (please specify below) 44 | 45 | --- 46 | 47 | ### Please describe the changes needed 48 | 49 | 50 | 51 | ### Additional Context 52 | 53 | 54 | 55 | --- 56 | 57 | ### Helpful Resources 58 | 59 | - [Generate your code.json entry](https://dsacms.github.io/codejson-generator/) - Use this form to generate a valid code.json 60 | - [code.json Guidance](https://github.com/DSACMS/gov-codejson/tree/main/docs) - Documentation on code.json 61 | -------------------------------------------------------------------------------- /tier3/{{cookiecutter.project_slug}}/.github/ISSUE_TEMPLATE/outside_collaborator_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Outside Collaborator Repository Access Request Ticket 3 | about: Ticket for requesting outside collaborator to be added to repository 4 | title: "[REQUEST]: " 5 | labels: # TODO: Add labels for categorization of requests 6 | assignees: # TODO: Add organization owner or help desk team 7 | --- 8 | 9 | ## Request an outside collaborator to be added to repository 10 | 11 | For individuals that are not members of the {{ cookiecutter.project_org }} GitHub organization, these outside collaborators can request access to a repository. Fill out this issue to file the request or make a pull request to the `COMMUNITY.md` file, then a repository admin will grant access. 12 | 13 | ### Information Required 14 | 15 | Name of individual: 16 | GitHub username: 17 | Role in project: 18 | Role in repository according to COMMUNITY.md (Maintainer, Approver, Reviewer): 19 | 20 | ### Additional Notes (Optional) 21 | 22 | 23 | -------------------------------------------------------------------------------- /tier3/{{cookiecutter.project_slug}}/.github/codejson/hooks/pre_prompt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "⚙️ Welcome to the code.json cookiecutter CLI." 4 | echo -e "📝 We will assist you with creating a code.json file to store metadata of your project." 5 | echo -e "ℹ️ Visit www.github.com/DSACMS/gov-codejson for more information." 6 | -------------------------------------------------------------------------------- /tier3/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{ cookiecutter.project_name }}", 3 | "description": "{{ cookiecutter.description }}", 4 | "longDescription": "{{ cookiecutter.long_description }}", 5 | "status": "{{ cookiecutter.status }}", 6 | "permissions": { 7 | "licenses": [ 8 | { 9 | "URL": "LICENSE", 10 | "name": "{{ cookiecutter.license }}" 11 | } 12 | ], 13 | "usageType": "{{ cookiecutter.usage_type }}", 14 | "exemptionText": "" 15 | }, 16 | "organization": "Centers for Medicare & Medicaid Services", 17 | "repositoryURL": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}", 18 | "repositoryHost": "{{ cookiecutter.repository_host }}", 19 | "repositoryVisibility": "{{ cookiecutter.repository_visibility}}", 20 | "vcs": "{{ cookiecutter.vcs }}", 21 | "laborHours": [""], 22 | "reuseFrequency": { 23 | "forks": "{{ cookiecutter.forks }}" 24 | }, 25 | "platforms": [ "{{ cookiecutter.platforms }}" ], 26 | "categories": [ "{{ cookiecutter.categories }}" ], 27 | "softwareType": "{{ cookiecutter.software_type }}", 28 | "languages": [ "{{ cookiecutter.languages }}" ], 29 | "maintenance": "{{ cookiecutter.maintenance }}", 30 | "contractNumber": "{{ cookiecutter.contract_number }}", 31 | "date": [""], 32 | "tags": [ "{{ cookiecutter.tags }}" ], 33 | "contact": { 34 | "email": "{{ cookiecutter.contact_email }}", 35 | "name": "{{ cookiecutter.contact_name }}" 36 | }, 37 | "feedbackMechanisms": ["{{ cookiecutter.feedback_mechanisms }}"], 38 | "localisation": "{{ cookiecutter.localisation }}", 39 | "repositoryType": "{{ cookiecutter.repository_type }}", 40 | "userInput": "{{ cookiecutter.user_input }}", 41 | "fismaLevel": "{{ cookiecutter.fisma_level }}", 42 | "group": "{{ cookiecutter.group }}", 43 | "projects": ["{{ cookiecutter.projects }}"], 44 | "systems": ["{{ cookiecutter.systems }}"], 45 | "upstream": ["{{ cookiecutter.upstream }}"], 46 | "subsetInHealthcare": ["{{ cookiecutter.subset_in_healthcare }}"], 47 | "userType": ["{{ cookiecutter.user_type }}"], 48 | "maturityModelTier": 3 49 | } -------------------------------------------------------------------------------- /tier3/{{cookiecutter.project_slug}}/.github/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_name": "{{ cookiecutter.project_name }}", 3 | "project_repo_name": "{{ cookiecutter.project_repo_name }}", 4 | "project_org": "{{ cookiecutter.project_org }}", 5 | "description": "A short description of the project.", 6 | "long_description": "A longer description of the project.", 7 | "status": ["ideation", "development", "alpha", "beta", "release candidate", "production", "archival"], 8 | "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"], 9 | "usage_type" : ["openSource", "governmentWideReuse", "exemptByLaw", "exemptByNationalSecurity", "exemptByAgencySystem", "exemptByAgencyMission", "exemptByCIO", "exemptByPolicyDate"], 10 | "repository_host": ["github.com/CMSgov", "github.com/CMS-Enterprise", "github.com/DSACMS", "github.cms.gov", "CCSQ GitHub"], 11 | "repository_visibility": ["public", "private"], 12 | "vcs": ["git", "hg", "svn", "rcs", "bzr"], 13 | "forks": 0, 14 | "platforms": "web, windows, mac, linux, ios, android, other", 15 | "categories": "healthcare", 16 | "software_type":["standalone/mobile", "standalone/iot", "standalone/desktop", "standalone/web", "standalone/backend", "standalone/other", "addon", "library", "configurationFiles"], 17 | "languages": "", 18 | "maintenance": ["internal", "contract", "community", "none"], 19 | "contract_number": 0, 20 | "tags": "dsacms-tier3", 21 | "contact_email": "opensource@cms.hhs.gov", 22 | "contact_name": "CMS Open Source Program Office", 23 | "feedback_mechanisms": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/issues", 24 | "localisation": ["true", "false"], 25 | "repository_type" : ["Package", "Website", "Standards", "Libraries", "Data", "Apps", "Tools", "APIs", "Docs"], 26 | "user_input": ["Yes", "No"], 27 | "fisma_level": ["Low", "Moderate", "High"], 28 | "group": "CMS/OA/DSAC", 29 | "projects": "", 30 | "systems": "", 31 | "upstream": "", 32 | "subset_in_healthcare": "Policy, Operational, Medicare, Medicaid", 33 | "user_type": "Providers, Patients, Government", 34 | "__prompts__": { 35 | "project_name": "What is the name of the project or software?", 36 | "project_repo_name": "What is the name of the repository?", 37 | "project_org": "What CMS GitHub organization is it under?", 38 | "description": "Provide a short description of the software. It should be a single line containing a single sentence. Maximum 150 characters are allowed.", 39 | "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.", 40 | "status": "What is the status of the project?", 41 | "license": "What license is the project under?", 42 | "usage_type": "What is the usage type for this project? For more information on each option, visit github.com/DSACMS/gov-codejson", 43 | "repository_host": "Where is the repository hosted?", 44 | "vcs": "What version control system is used?", 45 | "forks": "How many forks does the repository have?", 46 | "platforms": "What platform does the software runs on? Separate items by commas.", 47 | "categories": "What categories best describes the project? Separate items by commas. List of categories here: https://yml.publiccode.tools/categories-list.html?highlight=categories", 48 | "software_type": "What type of software is the project?", 49 | "languages": "What programming language(s) is the software written in? Separate items by commas.", 50 | "maintenance": "How is the software maintained?", 51 | "contract_number": "What is the contractor number of the project?", 52 | "tags": "Provide a list of tags to describe the software for search. Separate items by commas.", 53 | "contact_name": "A point of contact is needed for the project. What is the name of the point of contact?", 54 | "contact_email": "What is email address of the point of contact?", 55 | "feedback_mechanisms": "What are methods a repository receives feedback from the community (e.g. URL to GitHub repository issues page, website, email)", 56 | "localisation": "Does the software support multiple spoken languages?", 57 | "repository_type": "What type of repository is this project?", 58 | "user_input": "Does the project accept user input? (e.g. allows user to query a database, allows login by users, upload files, etc.)", 59 | "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", 60 | "group": "Which group at CMS is the project part of?", 61 | "projects": "What project is the repository associated with? Separate items by commas.", 62 | "systems": "What systems does the repository use or interface with? Separate items by commas.", 63 | "upstream": "What upstream dependencies does the repository use? Separate items by commas.", 64 | "subset_in_healthcare": "Which subset of healthcare does the project belong to?", 65 | "user_type": "Who are the intended users?" 66 | } 67 | } -------------------------------------------------------------------------------- /tier3/{{cookiecutter.project_slug}}/.github/workflows/auto-changelog.yml: -------------------------------------------------------------------------------- 1 | name: Changelog 2 | on: 3 | release: 4 | types: 5 | - created 6 | jobs: 7 | changelog: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: "Auto Generate changelog" 11 | uses: heinrichreimer/action-github-changelog-generator@v2.3 12 | with: 13 | {% raw %} 14 | token: ${{ secrets.GITHUB_TOKEN }} 15 | {% endraw %} -------------------------------------------------------------------------------- /tier3/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml: -------------------------------------------------------------------------------- 1 | name: Update Contributors Information 2 | 3 | on: 4 | workflow_dispatch: {} 5 | schedule: 6 | # Weekly on Saturdays. 7 | - cron: "30 1 * * 6" 8 | push: 9 | branches: [main] 10 | 11 | jobs: 12 | update-contributors: 13 | runs-on: ubuntu-latest 14 | permissions: 15 | contents: write 16 | pull-requests: write 17 | 18 | steps: 19 | - name: Checkout repository 20 | uses: actions/checkout@v4 21 | with: 22 | fetch-depth: 0 23 | 24 | - name: Update contributor list 25 | id: contrib_list 26 | uses: akhilmhdh/contributors-readme-action@v2.3.10 27 | env: 28 | {% raw %} 29 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 30 | {% endraw %} 31 | with: 32 | readme_path: COMMUNITY.md 33 | use_username: false 34 | commit_message: "update contributors information" 35 | 36 | - name: Get contributors count 37 | id: get_contributors 38 | env: 39 | {% raw %} 40 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 41 | {% endraw %} 42 | 43 | run: | 44 | OWNER=$(echo $GITHUB_REPOSITORY | cut -d'/' -f1) 45 | REPO=$(echo $GITHUB_REPOSITORY | cut -d'/' -f2) 46 | QUERY='query { repository(owner: \"'"$OWNER"'\", name: \"'"$REPO"'\") { collaborators { totalCount } } }' 47 | 48 | CONTRIBUTORS=$(gh api \ 49 | -H "Accept: application/vnd.github+json" \ 50 | -H "X-GitHub-Api-Version: 2022-11-28" \ 51 | "/repos/$OWNER/$REPO/contributors?per_page=100" | \ 52 | jq '[.[] | select(.type != "Bot" and (.login | test("\\[bot\\]$") | not) and (.login | test("-bot$") | not))] | length') 53 | 54 | echo "Total contributors: $CONTRIBUTORS" 55 | echo "contributors=$CONTRIBUTORS" >> $GITHUB_OUTPUT 56 | 57 | 58 | - name: Update COMMUNITY.md 59 | run: | 60 | {% raw %} 61 | CONTRIBUTORS="${{ steps.get_contributors.outputs.contributors }}" 62 | {% endraw %} 63 | 64 | perl -i -pe 's/().*?()/$1 '"$CONTRIBUTORS"' $2/' COMMUNITY.md 65 | 66 | git config user.name 'github-actions[bot]' 67 | git config user.email 'github-actions[bot]@users.noreply.github.com' 68 | git add COMMUNITY.md 69 | git commit -m "update contributors count to $CONTRIBUTORS" || exit 0 70 | 71 | - name: Push protected 72 | uses: CasperWA/push-protected@v2 73 | with: 74 | {% raw %} 75 | token: ${{ secrets.PUSH_TO_PROTECTED_BRANCH }} 76 | {% endraw %} 77 | 78 | branch: main -------------------------------------------------------------------------------- /tier3/{{cookiecutter.project_slug}}/.github/workflows/gitleaks.yml: -------------------------------------------------------------------------------- 1 | name: Check for Secrets 2 | on: 3 | pull_request: 4 | push: 5 | 6 | jobs: 7 | scan-for-secrets: 8 | name: Run gitleaks 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | with: {fetch-depth: 0} 13 | 14 | - name: Check for GitLeaks 15 | uses: gacts/gitleaks@v1 -------------------------------------------------------------------------------- /tier3/{{cookiecutter.project_slug}}/.github/workflows/repoHygieneCheck.yml: -------------------------------------------------------------------------------- 1 | name: "Repository Hygiene Check" 2 | on: 3 | push: 4 | branches: 5 | - 'main' 6 | workflow_dispatch: 7 | 8 | jobs: 9 | check-first-run: 10 | name: Check For First Run 11 | runs-on: ubuntu-latest 12 | outputs: 13 | {% raw %} 14 | should_run: ${{ steps.check.outputs.should_run }} 15 | {% endraw %} 16 | permissions: 17 | contents: read 18 | pull-requests: write 19 | steps: 20 | - uses: actions/checkout@v4 21 | - id: check 22 | run: | 23 | # If manually triggered, always run 24 | {% raw %} 25 | if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then 26 | {% endraw %} 27 | echo "should_run=true" >> $GITHUB_OUTPUT 28 | exit 0 29 | fi 30 | 31 | # Check if initialization label exists 32 | has_label=$(gh label list --json name | jq '.[] | select(.name=="repolinter-initialized")') 33 | 34 | if [[ -z "$has_label" ]]; then 35 | # First time - create label and allow run 36 | gh label create repolinter-initialized --description "Marks repo as having run initial repolinter check" 37 | echo "should_run=true" >> $GITHUB_OUTPUT 38 | else 39 | echo "should_run=false" >> $GITHUB_OUTPUT 40 | fi 41 | env: 42 | {% raw %} 43 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 44 | {% endraw %} 45 | 46 | resolve-repolinter-json: 47 | name: Get Repolinter Config 48 | needs: check-first-run 49 | {% raw %} 50 | if: needs.check-first-run.outputs.should_run == 'true' 51 | {% endraw %} 52 | uses: DSACMS/repo-scaffolder/.github/workflows/extendJSONFile.yml@main 53 | with: 54 | url_to_json: 'https://raw.githubusercontent.com/DSACMS/repo-scaffolder/main/tier3/%7B%7Bcookiecutter.project_slug%7D%7D/repolinter.json' 55 | 56 | repolinter-checks: 57 | name: Tier 3 Checks 58 | needs: [check-first-run, resolve-repolinter-json] 59 | {% raw %} 60 | if: needs.check-first-run.outputs.should_run == 'true' 61 | {% endraw %} 62 | runs-on: ubuntu-latest 63 | permissions: 64 | contents: write 65 | pull-requests: write 66 | env: 67 | {% raw %} 68 | RAW_JSON: ${{ needs.resolve-repolinter-json.outputs.raw-json }} 69 | {% endraw %} 70 | steps: 71 | - uses: actions/checkout@v4 72 | - run: echo $RAW_JSON > repolinter.json 73 | - uses: DSACMS/repolinter-action@main 74 | with: 75 | config_file: 'repolinter.json' 76 | output_type: 'pull-request' 77 | pull_request_labels: 'repolinter-initialized, cms-oss, cms-gov' 78 | {% raw %} 79 | token: ${{ secrets.REPOLINTER_AUTO_TOKEN }} 80 | {% endraw %} -------------------------------------------------------------------------------- /tier3/{{cookiecutter.project_slug}}/.github/workflows/repoStructure.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | workflow_dispatch: 6 | 7 | jobs: 8 | populate-repo-structure: 9 | runs-on: ubuntu-latest 10 | name: Update repo structure in README.md 11 | permissions: 12 | contents: write 13 | pull-requests: write 14 | steps: 15 | - name: Checkout repository 16 | uses: actions/checkout@v4 17 | 18 | - name: Populate repository structure with tree command 19 | # https://stackoverflow.com/questions/29613304/is-it-possible-to-escape-regex-metacharacters-reliably-with-sed 20 | # https://stackoverflow.com/questions/407523/escape-a-string-for-a-sed-replace-pattern 21 | run: | 22 | quoteSubst() { 23 | IFS= read -d '' -r < <(sed -e ':a' -e '$!{N;ba' -e '}' -e 's/[&/\]/\\&/g; s/\n/\\&/g' <<<"$1") 24 | printf %s "${REPLY%$'\n'}" 25 | } 26 | TREE_OUTPUT=$(tree -d) 27 | sed -i 's//\n```plaintext\n'"$(quoteSubst $TREE_OUTPUT)"'\n```\n/g' README.md 28 | 29 | - name: Commit and push changes 30 | # https://github.com/orgs/community/discussions/26560#discussioncomment-3531273 31 | # commit changes, but if no changes exist, then exit cleanly 32 | run: | 33 | git config user.name 'github-actions[bot]' 34 | git config user.email 'github-actions[bot]@users.noreply.github.com' 35 | git add README.md 36 | git commit -m "BOT: Update repo structure in README.md" || exit 0 37 | git push 38 | -------------------------------------------------------------------------------- /tier3/{{cookiecutter.project_slug}}/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. 4 | 5 | We are committed to making participation in this project a harassment-free experience for everyone, regardless of the level of experience, gender, gender identity, expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 6 | 7 | Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. 8 | 9 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned with this Code of Conduct. 10 | 11 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers at opensource@cms.hhs.gov. 12 | 13 | This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/) 14 | 15 | ## Acknowledgements 16 | 17 | This CODE_OF_CONDUCT.md was originally forked from the [United States Digital Service](https://usds.gov) [Justice40](https://thejustice40.com) open source [repository](https://github.com/usds/justice40-tool), and we would like to acknowledge and thank the community for their contributions. -------------------------------------------------------------------------------- /tier3/{{cookiecutter.project_slug}}/GOVERNANCE.md: -------------------------------------------------------------------------------- 1 | # Governance 2 | 3 | 5 | 6 | This project is governed by our [Community Guidelines](COMMUNITY.md) and [Code of Conduct](CODE_OF_CONDUCT.md). 7 | -------------------------------------------------------------------------------- /tier3/{{cookiecutter.project_slug}}/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security and Responsible Disclosure Policy 2 | 3 | The Centers for Medicare & Medicaid Services is committed to ensuring the security of the American public by protecting their information from unwarranted disclosure. We want security researchers to feel comfortable reporting vulnerabilities they have discovered so we can fix them and keep our users safe. We developed our disclosure policy to reflect our values and uphold our sense of responsibility to security researchers who share their expertise with us in good faith. 4 | 5 | *Submit a vulnerability:* Vulnerability reports can be submitted through [Bugcrowd](https://bugcrowd.com/cms-vdp). Reports may be submitted anonymously. If you share contact information, we will acknowledge receipt of your report within 3 business days. 6 | 7 | Review the HHS Disclosure Policy and websites in scope: 8 | [https://www.hhs.gov/vulnerability-disclosure-policy/index.html](https://www.hhs.gov/vulnerability-disclosure-policy/index.html). 9 | 10 | This policy describes *what systems and types of research* are covered under this 11 | policy, *how to send* us vulnerability reports, and *how long* we ask security 12 | researchers to wait before publicly disclosing vulnerabilities. -------------------------------------------------------------------------------- /tier3/{{cookiecutter.project_slug}}/repolinter.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "https://raw.githubusercontent.com/DSACMS/repo-scaffolder/main/tier2/%7B%7Bcookiecutter.project_slug%7D%7D/repolinter.json", 3 | "$schema": "https://raw.githubusercontent.com/todogroup/repolinter/master/rulesets/schema.json", 4 | "version": 2, 5 | "axioms": { 6 | "linguist": "language", 7 | "licensee": "license", 8 | "packagers": "packager" 9 | }, 10 | "rules": { 11 | "readme-contains-documentation-index": { 12 | "level": "error" 13 | }, 14 | "readme-contains-repository-structure": { 15 | "level": "error" 16 | }, 17 | "readme-contains-development-and-software-delivery-lifecycle": { 18 | "level": "error" 19 | }, 20 | "readme-contains-branching-model": { 21 | "level": "error" 22 | }, 23 | "readme-contains-feedback": { 24 | "level": "error" 25 | }, 26 | "readme-contains-glossary": { 27 | "level": "warning" 28 | }, 29 | "contributing-contains-team-specific-guidelines": { 30 | "level": "error" 31 | }, 32 | "contributing-contains-testing-conventions": { 33 | "level": "error" 34 | }, 35 | "contributing-contains-writing-pull-requests": { 36 | "level": "error" 37 | }, 38 | "contributing-contains-reviewing-pull-requests": { 39 | "level": "error" 40 | }, 41 | "contributing-contains-shipping-releases": { 42 | "level": "warning" 43 | }, 44 | "contributing-contains-documentation": { 45 | "level": "error" 46 | }, 47 | "community-contains-roles-and-responsibilities": { 48 | "level": "error" 49 | }, 50 | "community-contains-maintainers-list": { 51 | "level": "error" 52 | }, 53 | "community-contains-approvers-list": { 54 | "level": "error" 55 | }, 56 | "community-contains-reviewers-list": { 57 | "level": "error" 58 | }, 59 | "community-contains-contributors": { 60 | "level": "error" 61 | }, 62 | "community-contains-alumni": { 63 | "level": "warning" 64 | }, 65 | "governance-file-exists": { 66 | "level": "warning" 67 | }, 68 | "governance-contains-governance": { 69 | "level": "warning" 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /tier4/README.md: -------------------------------------------------------------------------------- 1 | # Tier 4: Community Governance 2 | 3 | ## What is a Tier 4 Project? 4 | 5 | A **Tier 4** project is a fully **open and collaborative** project that operates under a **community governance model**. In Tier 4 projects, the focus is on **collaborating broadly with the public**, and the project is often either **donated** to or **stewarded** by an external community. The governance structure is **open** and welcomes input from a wide range of contributors, typically from outside the original development team. 6 | 7 | ### Key Characteristics of a Tier 4 Project: 8 | 9 | - **Broad public collaboration** with contributions welcomed from the community. 10 | - **Community-led governance**, where decisions are made transparently, often with input from various stakeholders. 11 | - **Mature open-source project**, typically with a well-defined governance structure to guide development, maintenance, and project direction. 12 | 13 | --- 14 | 15 | ## Files for a Tier 4 Project 16 | 17 | There are specific files that are required to include in the repository as part of the CMS Open Source Program Office's repository hygiene guidelines and standards. 18 | 19 | | **File** | **Requirement** | **Description** | 20 | | -------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | 21 | | `LICENSE` | Mandatory | Defines the licensing terms under which the project is distributed. | 22 | | `code.json` | Mandatory | Contains project metadata following government requirements. | 23 | | `README.md` | Mandatory | Provides a comprehensive overview of the project, including its purpose, how to install or use it, and any relevant information for users or developers. | 24 | | `COMMUNITY.md` | Mandatory | Lists project team members and points of contact with detailed roles and responsibilities. | 25 | | `SECURITY.md` | Mandatory | Outlines the agency's security policies, including how to report security issues or vulnerabilities in the code. | 26 | | `CONTRIBUTING.md` | Mandatory | Offers guidelines for contributing to the project, including code standards, how to submit issues, and creating pull requests. | 27 | | `CODE_OF_CONDUCT.md` | Mandatory | Establishes guidelines for acceptable behavior within the community, setting expectations for how contributors should interact in a respectful and collaborative manner. | 28 | | `GOVERNANCE.md` | Mandatory | Describes the governance model of the project, such as decision-making processes and rules for contributing. It ensures a transparent process for managing the project. | 29 | 30 | For more information about required sections and content within the files above, please visit [maturity-model-tiers.md](https://github.com/DSACMS/repo-scaffolder/blob/main/maturity-model-tiers.md). 31 | 32 | ## .github directory 33 | 34 | The .github directory includes various files such as GitHub action workflows, code.json metadata cookiecutter creation, and issue templates. For more information, please visit the [.github-directory.md]([../docs/.github-directory.md). 35 | 36 | ## Repository Hygiene using repolinter 37 | 38 | As part of maintaining repository hygiene, repolinter is used to identify missing files and information. `repolinter.json` defines a set of checks that verify the existence of these files in your repository. To run repolinter, execute the following command from the root directory: 39 | 40 | ``` 41 | repolinter lint . 42 | ``` 43 | 44 | A GitHub action is also available for running repolinter checks. For more information, please visit [README.md](https://github.com/DSACMS/repo-scaffolder?tab=readme-ov-file#identify-missing-files-and-information-using-repolinter). 45 | -------------------------------------------------------------------------------- /tier4/checklist.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSACMS/repo-scaffolder/d09dcd042f0ea31a044e70e6f7ede97a7cf48d64/tier4/checklist.pdf -------------------------------------------------------------------------------- /tier4/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_name": "My Project", 3 | "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '_') }}", 4 | "project_org": "DSACMS", 5 | "project_repo_name": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}", 6 | "project_description": "This is the project description, could match github.com repo description.", 7 | "code_owners": "", 8 | "project_visibility": ["public", "internal", "private"], 9 | "create_repo": [true, false], 10 | "receive_updates": [true, false], 11 | "add_team": [true, false], 12 | "add_maintainer": [true, false], 13 | "__prompts__": { 14 | "code_owners": "Would you like to add a CODEOWNERS.md to get notified on repository updates? If so, please provide the usernames separated by commas.", 15 | "create_repo": "Would you like to create a repo on github.com?", 16 | "receive_updates": "Would you like to receive updates from the DSACMS team via pull requests?", 17 | "add_team": "Would you like to add project team members to COMMUNITY.md?", 18 | "add_maintainer": "Would you like to add maintainers, approvers, and/or reviewers to COMMUNITY.md?" 19 | }, 20 | "_copy_without_render": [".github/codejson"] 21 | } 22 | -------------------------------------------------------------------------------- /tier4/hooks/pre_prompt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "⚙️ Welcome to the repo-scaffolder cookiecutter CLI." 4 | echo -e "📝 We will assist you with creating a Tier 4 repository." 5 | echo -e "ℹ️ Visit https://github.com/DSACMS/repo-scaffolder/tree/main/tier4 for more information.\n" 6 | echo -e "****************************************\n" -------------------------------------------------------------------------------- /tier4/{{cookiecutter.project_slug}}/.github/CODEOWNERS.md: -------------------------------------------------------------------------------- 1 | # Code Owners 2 | 3 | 4 | 5 | {% set code_owners = cookiecutter.code_owners.split(',') %} 6 | {% for item in code_owners %}- {{ item }} 7 | {% endfor %} 8 | 9 | ## Repo Domains 10 | 11 | 32 | 33 | /docs/ {Git usernames of documentation owners} 34 | /frontend/ {Git usernames of frontend owners} 35 | -------------------------------------------------------------------------------- /tier4/{{cookiecutter.project_slug}}/.github/ISSUE_TEMPLATE/add_team_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Add Team to Repository Request Ticket 3 | about: Ticket for requesting team to be added to repository 4 | title: "[REQUEST]: " 5 | labels: # TODO: Add labels for categorization of requests 6 | assignees: # TODO: Add organization owner or help desk team 7 | --- 8 | 9 | ## Request a New Team to be Added to a Repository 10 | 11 | Please fill out the form below to request a new team to be added to a repository. 12 | 13 | ### Information Required 14 | 15 | Team Name: 16 | Reason for Access: 17 | 18 | ### Additional Notes (Optional) 19 | 20 | 21 | -------------------------------------------------------------------------------- /tier4/{{cookiecutter.project_slug}}/.github/ISSUE_TEMPLATE/code_json_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: code.json Update Request 3 | about: Request updates to code.json 4 | title: '[CODE.JSON]: ' 5 | labels: ['code-json-update'] 6 | assignees: '' 7 | --- 8 | 9 | ## Code.json Update Request 10 | 11 | Thank you for helping maintain accurate code.json information for this project! This data helps track open source projects across the organization and ensures compliance with federal open source policies. 12 | 13 | ### Which field would you like to update? 14 | 15 | 16 | 17 | - [ ] name 18 | - [ ] description 19 | - [ ] longDescription 20 | - [ ] status 21 | - [ ] permissions 22 | - [ ] organization 23 | - [ ] repositoryURL 24 | - [ ] vcs 25 | - [ ] laborHours 26 | - [ ] platforms 27 | - [ ] categories 28 | - [ ] softwareType 29 | - [ ] languages 30 | - [ ] maintenance 31 | - [ ] date 32 | - [ ] tags 33 | - [ ] contact information 34 | - [ ] localisation 35 | - [ ] repositoryType 36 | - [ ] userInput 37 | - [ ] fismaLevel 38 | - [ ] group 39 | - [ ] subsetInHealthcare 40 | - [ ] userType 41 | - [ ] repositoryHost 42 | - [ ] maturityModelTier 43 | - [ ] Other (please specify below) 44 | 45 | --- 46 | 47 | ### Please describe the changes needed 48 | 49 | 50 | 51 | ### Additional Context 52 | 53 | 54 | 55 | --- 56 | 57 | ### Helpful Resources 58 | 59 | - [Generate your code.json entry](https://dsacms.github.io/codejson-generator/) - Use this form to generate a valid code.json 60 | - [code.json Guidance](https://github.com/DSACMS/gov-codejson/tree/main/docs) - Documentation on code.json 61 | -------------------------------------------------------------------------------- /tier4/{{cookiecutter.project_slug}}/.github/ISSUE_TEMPLATE/outside_collaborator_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Outside Collaborator Repository Access Request Ticket 3 | about: Ticket for requesting outside collaborator to be added to repository 4 | title: "[REQUEST]: " 5 | labels: # TODO: Add labels for categorization of requests 6 | assignees: # TODO: Add organization owner or help desk team 7 | --- 8 | 9 | ## Request an outside collaborator to be added to repository 10 | 11 | For individuals that are not members of the {{ cookiecutter.project_org }} GitHub organization, these outside collaborators can request access to a repository. Fill out this issue to file the request or make a pull request to the `COMMUNITY.md` file, then a repository admin will grant access. 12 | 13 | ### Information Required 14 | 15 | Name of individual: 16 | GitHub username: 17 | Role in project: 18 | Role in repository according to COMMUNITY.md (Maintainer, Approver, Reviewer): 19 | 20 | ### Additional Notes (Optional) 21 | 22 | 23 | -------------------------------------------------------------------------------- /tier4/{{cookiecutter.project_slug}}/.github/codejson/hooks/pre_prompt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "⚙️ Welcome to the code.json cookiecutter CLI." 4 | echo -e "📝 We will assist you with creating a code.json file to store metadata of your project." 5 | echo -e "ℹ️ Visit www.github.com/DSACMS/gov-codejson for more information." 6 | -------------------------------------------------------------------------------- /tier4/{{cookiecutter.project_slug}}/.github/codejson/{{cookiecutter.project_name}}/code.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{ cookiecutter.project_name }}", 3 | "description": "{{ cookiecutter.description }}", 4 | "longDescription": "{{ cookiecutter.long_description }}", 5 | "status": "{{ cookiecutter.status }}", 6 | "permissions": { 7 | "licenses": [ 8 | { 9 | "URL": "LICENSE", 10 | "name": "{{ cookiecutter.license }}" 11 | } 12 | ], 13 | "usageType": "{{ cookiecutter.usage_type }}", 14 | "exemptionText": "" 15 | }, 16 | "organization": "Centers for Medicare & Medicaid Services", 17 | "repositoryURL": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}", 18 | "repositoryHost": "{{ cookiecutter.repository_host }}", 19 | "repositoryVisibility": "{{ cookiecutter.repository_visibility}}", 20 | "vcs": "{{ cookiecutter.vcs }}", 21 | "laborHours": [""], 22 | "reuseFrequency": { 23 | "forks": "{{ cookiecutter.forks }}" 24 | }, 25 | "platforms": [ "{{ cookiecutter.platforms }}" ], 26 | "categories": [ "{{ cookiecutter.categories }}" ], 27 | "softwareType": "{{ cookiecutter.software_type }}", 28 | "languages": [ "{{ cookiecutter.languages }}" ], 29 | "maintenance": "{{ cookiecutter.maintenance }}", 30 | "contractNumber": "{{ cookiecutter.contract_number }}", 31 | "date": [""], 32 | "tags": [ "{{ cookiecutter.tags }}" ], 33 | "contact": { 34 | "email": "{{ cookiecutter.contact_email }}", 35 | "name": "{{ cookiecutter.contact_name }}" 36 | }, 37 | "feedbackMechanisms": ["{{ cookiecutter.feedback_mechanisms }}"], 38 | "localisation": "{{ cookiecutter.localisation }}", 39 | "repositoryType": "{{ cookiecutter.repository_type }}", 40 | "userInput": "{{ cookiecutter.user_input }}", 41 | "fismaLevel": "{{ cookiecutter.fisma_level }}", 42 | "group": "{{ cookiecutter.group }}", 43 | "projects": ["{{ cookiecutter.projects }}"], 44 | "systems": ["{{ cookiecutter.systems }}"], 45 | "upstream": ["{{ cookiecutter.upstream }}"], 46 | "subsetInHealthcare": ["{{ cookiecutter.subset_in_healthcare }}"], 47 | "userType": ["{{ cookiecutter.user_type }}"], 48 | "maturityModelTier": 4 49 | } -------------------------------------------------------------------------------- /tier4/{{cookiecutter.project_slug}}/.github/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_name": "{{ cookiecutter.project_name }}", 3 | "project_repo_name": "{{ cookiecutter.project_repo_name }}", 4 | "project_org": "{{ cookiecutter.project_org }}", 5 | "description": "A short description of the project.", 6 | "long_description": "A longer description of the project.", 7 | "status": ["ideation", "development", "alpha", "beta", "release candidate", "production", "archival"], 8 | "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"], 9 | "usage_type" : ["openSource", "governmentWideReuse", "exemptByLaw", "exemptByNationalSecurity", "exemptByAgencySystem", "exemptByAgencyMission", "exemptByCIO", "exemptByPolicyDate"], 10 | "repository_host": ["github.com/CMSgov", "github.com/CMS-Enterprise", "github.com/DSACMS", "github.cms.gov", "CCSQ GitHub"], 11 | "repository_visibility": ["public", "private"], 12 | "vcs": ["git", "hg", "svn", "rcs", "bzr"], 13 | "forks": 0, 14 | "platforms": "web, windows, mac, linux, ios, android, other", 15 | "categories": "healthcare", 16 | "software_type":["standalone/mobile", "standalone/iot", "standalone/desktop", "standalone/web", "standalone/backend", "standalone/other", "addon", "library", "configurationFiles"], 17 | "languages": "", 18 | "maintenance": ["internal", "contract", "community", "none"], 19 | "contract_number": 0, 20 | "tags": "dsacms-tier4", 21 | "contact_email": "opensource@cms.hhs.gov", 22 | "contact_name": "CMS Open Source Program Office", 23 | "feedback_mechanisms": "https://github.com/{{ cookiecutter.project_org }}/{{ cookiecutter.project_repo_name }}/issues", 24 | "localisation": ["true", "false"], 25 | "repository_type" : ["Package", "Website", "Standards", "Libraries", "Data", "Apps", "Tools", "APIs", "Docs"], 26 | "user_input": ["Yes", "No"], 27 | "fisma_level": ["Low", "Moderate", "High"], 28 | "group": "CMS/OA/DSAC", 29 | "projects": "", 30 | "systems": "", 31 | "upstream": "", 32 | "subset_in_healthcare": "Policy, Operational, Medicare, Medicaid", 33 | "user_type": "Providers, Patients, Government", 34 | "__prompts__": { 35 | "project_name": "What is the name of the project or software?", 36 | "project_repo_name": "What is the name of the repository?", 37 | "project_org": "What CMS GitHub organization is it under?", 38 | "description": "Provide a short description of the software. It should be a single line containing a single sentence. Maximum 150 characters are allowed.", 39 | "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.", 40 | "status": "What is the status of the project?", 41 | "license": "What license is the project under?", 42 | "usage_type": "What is the usage type for this project? For more information on each option, visit github.com/DSACMS/gov-codejson", 43 | "repository_host": "Where is the repository hosted?", 44 | "vcs": "What version control system is used?", 45 | "forks": "How many forks does the repository have?", 46 | "platforms": "What platform does the software runs on? Separate items by commas.", 47 | "categories": "What categories best describes the project? Separate items by commas. List of categories here: https://yml.publiccode.tools/categories-list.html?highlight=categories", 48 | "software_type": "What type of software is the project?", 49 | "languages": "What programming language(s) is the software written in? Separate items by commas.", 50 | "maintenance": "How is the software maintained?", 51 | "contract_number": "What is the contractor number of the project?", 52 | "tags": "Provide a list of tags to describe the software for search. Separate items by commas.", 53 | "contact_name": "A point of contact is needed for the project. What is the name of the point of contact?", 54 | "contact_email": "What is email address of the point of contact?", 55 | "feedback_mechanisms": "What are methods a repository receives feedback from the community (e.g. URL to GitHub repository issues page, website, email)", 56 | "localisation": "Does the software support multiple spoken languages?", 57 | "repository_type": "What type of repository is this project?", 58 | "user_input": "Does the project accept user input? (e.g. allows user to query a database, allows login by users, upload files, etc.)", 59 | "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", 60 | "group": "Which group at CMS is the project part of?", 61 | "projects": "What project is the repository associated with? Separate items by commas.", 62 | "systems": "What systems does the repository use or interface with? Separate items by commas.", 63 | "upstream": "What upstream dependencies does the repository use? Separate items by commas.", 64 | "subset_in_healthcare": "Which subset of healthcare does the project belong to?", 65 | "user_type": "Who are the intended users?" 66 | } 67 | } -------------------------------------------------------------------------------- /tier4/{{cookiecutter.project_slug}}/.github/workflows/auto-changelog.yml: -------------------------------------------------------------------------------- 1 | name: Changelog 2 | on: 3 | release: 4 | types: 5 | - created 6 | jobs: 7 | changelog: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: "Auto Generate changelog" 11 | uses: heinrichreimer/action-github-changelog-generator@v2.3 12 | with: 13 | {% raw %} 14 | token: ${{ secrets.GITHUB_TOKEN }} 15 | {% endraw %} -------------------------------------------------------------------------------- /tier4/{{cookiecutter.project_slug}}/.github/workflows/contributors.yml: -------------------------------------------------------------------------------- 1 | name: Update Contributors Information 2 | 3 | on: 4 | workflow_dispatch: {} 5 | schedule: 6 | # Weekly on Saturdays. 7 | - cron: "30 1 * * 6" 8 | push: 9 | branches: [main] 10 | 11 | jobs: 12 | update-contributors: 13 | runs-on: ubuntu-latest 14 | permissions: 15 | contents: write 16 | pull-requests: write 17 | 18 | steps: 19 | - name: Checkout repository 20 | uses: actions/checkout@v4 21 | with: 22 | fetch-depth: 0 23 | 24 | - name: Update contributor list 25 | id: contrib_list 26 | uses: akhilmhdh/contributors-readme-action@v2.3.10 27 | env: 28 | {% raw %} 29 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 30 | {% endraw %} 31 | with: 32 | readme_path: COMMUNITY.md 33 | use_username: false 34 | commit_message: "update contributors information" 35 | 36 | - name: Get contributors count 37 | id: get_contributors 38 | env: 39 | {% raw %} 40 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 41 | {% endraw %} 42 | 43 | run: | 44 | OWNER=$(echo $GITHUB_REPOSITORY | cut -d'/' -f1) 45 | REPO=$(echo $GITHUB_REPOSITORY | cut -d'/' -f2) 46 | QUERY='query { repository(owner: \"'"$OWNER"'\", name: \"'"$REPO"'\") { collaborators { totalCount } } }' 47 | 48 | CONTRIBUTORS=$(gh api \ 49 | -H "Accept: application/vnd.github+json" \ 50 | -H "X-GitHub-Api-Version: 2022-11-28" \ 51 | "/repos/$OWNER/$REPO/contributors?per_page=100" | \ 52 | jq '[.[] | select(.type != "Bot" and (.login | test("\\[bot\\]$") | not) and (.login | test("-bot$") | not))] | length') 53 | 54 | echo "Total contributors: $CONTRIBUTORS" 55 | echo "contributors=$CONTRIBUTORS" >> $GITHUB_OUTPUT 56 | 57 | 58 | - name: Update COMMUNITY.md 59 | run: | 60 | {% raw %} 61 | CONTRIBUTORS="${{ steps.get_contributors.outputs.contributors }}" 62 | {% endraw %} 63 | 64 | perl -i -pe 's/().*?()/$1 '"$CONTRIBUTORS"' $2/' COMMUNITY.md 65 | 66 | git config user.name 'github-actions[bot]' 67 | git config user.email 'github-actions[bot]@users.noreply.github.com' 68 | git add COMMUNITY.md 69 | git commit -m "update contributors count to $CONTRIBUTORS" || exit 0 70 | 71 | - name: Push protected 72 | uses: CasperWA/push-protected@v2 73 | with: 74 | {% raw %} 75 | token: ${{ secrets.PUSH_TO_PROTECTED_BRANCH }} 76 | {% endraw %} 77 | 78 | branch: main -------------------------------------------------------------------------------- /tier4/{{cookiecutter.project_slug}}/.github/workflows/gitleaks.yml: -------------------------------------------------------------------------------- 1 | name: Check for Secrets 2 | on: 3 | pull_request: 4 | push: 5 | 6 | jobs: 7 | scan-for-secrets: 8 | name: Run gitleaks 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | with: {fetch-depth: 0} 13 | 14 | - name: Check for GitLeaks 15 | uses: gacts/gitleaks@v1 -------------------------------------------------------------------------------- /tier4/{{cookiecutter.project_slug}}/.github/workflows/repoHygieneCheck.yml: -------------------------------------------------------------------------------- 1 | name: "Repository Hygiene Check" 2 | on: 3 | push: 4 | branches: 5 | - 'main' 6 | workflow_dispatch: 7 | 8 | jobs: 9 | check-first-run: 10 | name: Check For First Run 11 | runs-on: ubuntu-latest 12 | outputs: 13 | {% raw %} 14 | should_run: ${{ steps.check.outputs.should_run }} 15 | {% endraw %} 16 | permissions: 17 | contents: read 18 | pull-requests: write 19 | steps: 20 | - uses: actions/checkout@v4 21 | - id: check 22 | run: | 23 | # If manually triggered, always run 24 | {% raw %} 25 | if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then 26 | {% endraw %} 27 | echo "should_run=true" >> $GITHUB_OUTPUT 28 | exit 0 29 | fi 30 | 31 | # Check if initialization label exists 32 | has_label=$(gh label list --json name | jq '.[] | select(.name=="repolinter-initialized")') 33 | 34 | if [[ -z "$has_label" ]]; then 35 | # First time - create label and allow run 36 | gh label create repolinter-initialized --description "Marks repo as having run initial repolinter check" 37 | echo "should_run=true" >> $GITHUB_OUTPUT 38 | else 39 | echo "should_run=false" >> $GITHUB_OUTPUT 40 | fi 41 | env: 42 | {% raw %} 43 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 44 | {% endraw %} 45 | 46 | resolve-repolinter-json: 47 | name: Get Repolinter Config 48 | needs: check-first-run 49 | {% raw %} 50 | if: needs.check-first-run.outputs.should_run == 'true' 51 | {% endraw %} 52 | uses: DSACMS/repo-scaffolder/.github/workflows/extendJSONFile.yml@main 53 | with: 54 | url_to_json: 'https://raw.githubusercontent.com/DSACMS/repo-scaffolder/main/tier4/%7B%7Bcookiecutter.project_slug%7D%7D/repolinter.json' 55 | 56 | repolinter-checks: 57 | name: Tier 4 Checks 58 | needs: [check-first-run, resolve-repolinter-json] 59 | {% raw %} 60 | if: needs.check-first-run.outputs.should_run == 'true' 61 | {% endraw %} 62 | runs-on: ubuntu-latest 63 | permissions: 64 | contents: write 65 | pull-requests: write 66 | env: 67 | {% raw %} 68 | RAW_JSON: ${{ needs.resolve-repolinter-json.outputs.raw-json }} 69 | {% endraw %} 70 | steps: 71 | - uses: actions/checkout@v4 72 | - run: echo $RAW_JSON > repolinter.json 73 | - uses: DSACMS/repolinter-action@main 74 | with: 75 | config_file: 'repolinter.json' 76 | output_type: 'pull-request' 77 | pull_request_labels: 'repolinter-initialized, cms-oss, cms-gov' 78 | {% raw %} 79 | token: ${{ secrets.REPOLINTER_AUTO_TOKEN }} 80 | {% endraw %} -------------------------------------------------------------------------------- /tier4/{{cookiecutter.project_slug}}/.github/workflows/repoStructure.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | workflow_dispatch: 6 | 7 | jobs: 8 | populate-repo-structure: 9 | runs-on: ubuntu-latest 10 | name: Update repo structure in README.md 11 | permissions: 12 | contents: write 13 | pull-requests: write 14 | steps: 15 | - name: Checkout repository 16 | uses: actions/checkout@v4 17 | 18 | - name: Populate repository structure with tree command 19 | # https://stackoverflow.com/questions/29613304/is-it-possible-to-escape-regex-metacharacters-reliably-with-sed 20 | # https://stackoverflow.com/questions/407523/escape-a-string-for-a-sed-replace-pattern 21 | run: | 22 | quoteSubst() { 23 | IFS= read -d '' -r < <(sed -e ':a' -e '$!{N;ba' -e '}' -e 's/[&/\]/\\&/g; s/\n/\\&/g' <<<"$1") 24 | printf %s "${REPLY%$'\n'}" 25 | } 26 | TREE_OUTPUT=$(tree -d) 27 | sed -i 's//\n```plaintext\n'"$(quoteSubst $TREE_OUTPUT)"'\n```\n/g' README.md 28 | 29 | - name: Commit and push changes 30 | # https://github.com/orgs/community/discussions/26560#discussioncomment-3531273 31 | # commit changes, but if no changes exist, then exit cleanly 32 | run: | 33 | git config user.name 'github-actions[bot]' 34 | git config user.email 'github-actions[bot]@users.noreply.github.com' 35 | git add README.md 36 | git commit -m "BOT: Update repo structure in README.md" || exit 0 37 | git push 38 | -------------------------------------------------------------------------------- /tier4/{{cookiecutter.project_slug}}/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. 4 | 5 | We are committed to making participation in this project a harassment-free experience for everyone, regardless of the level of experience, gender, gender identity, expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 6 | 7 | Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. 8 | 9 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned with this Code of Conduct. 10 | 11 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers at opensource@cms.hhs.gov. 12 | 13 | This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/) 14 | 15 | ## Acknowledgements 16 | 17 | This CODE_OF_CONDUCT.md was originally forked from the [United States Digital Service](https://usds.gov) [Justice40](https://thejustice40.com) open source [repository](https://github.com/usds/justice40-tool), and we would like to acknowledge and thank the community for their contributions. -------------------------------------------------------------------------------- /tier4/{{cookiecutter.project_slug}}/GOVERNANCE.md: -------------------------------------------------------------------------------- 1 | # Governance 2 | 3 | 5 | 6 | This project is governed by our [Community Guidelines](COMMUNITY.md) and [Code of Conduct](CODE_OF_CONDUCT.md). 7 | -------------------------------------------------------------------------------- /tier4/{{cookiecutter.project_slug}}/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security and Responsible Disclosure Policy 2 | 3 | The Centers for Medicare & Medicaid Services is committed to ensuring the security of the American public by protecting their information from unwarranted disclosure. We want security researchers to feel comfortable reporting vulnerabilities they have discovered so we can fix them and keep our users safe. We developed our disclosure policy to reflect our values and uphold our sense of responsibility to security researchers who share their expertise with us in good faith. 4 | 5 | *Submit a vulnerability:* Vulnerability reports can be submitted through [Bugcrowd](https://bugcrowd.com/cms-vdp). Reports may be submitted anonymously. If you share contact information, we will acknowledge receipt of your report within 3 business days. 6 | 7 | Review the HHS Disclosure Policy and websites in scope: 8 | [https://www.hhs.gov/vulnerability-disclosure-policy/index.html](https://www.hhs.gov/vulnerability-disclosure-policy/index.html). 9 | 10 | This policy describes *what systems and types of research* are covered under this 11 | policy, *how to send* us vulnerability reports, and *how long* we ask security 12 | researchers to wait before publicly disclosing vulnerabilities. -------------------------------------------------------------------------------- /tier4/{{cookiecutter.project_slug}}/repolinter.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "https://raw.githubusercontent.com/DSACMS/repo-scaffolder/main/tier3/%7B%7Bcookiecutter.project_slug%7D%7D/repolinter.json", 3 | "$schema": "https://raw.githubusercontent.com/todogroup/repolinter/master/rulesets/schema.json", 4 | "version": 2, 5 | "axioms": { 6 | "linguist": "language", 7 | "licensee": "license", 8 | "packagers": "packager" 9 | }, 10 | "rules": { 11 | "readme-contains-glossary": { 12 | "level": "error" 13 | }, 14 | "contributing-contains-shipping-releases": { 15 | "level": "error" 16 | }, 17 | "community-contains-alumni": { 18 | "level": "error" 19 | }, 20 | "governance-file-exists": { 21 | "level": "error" 22 | }, 23 | "governance-contains-governance": { 24 | "level": "error" 25 | }, 26 | "readme-contains-agency-mission": { 27 | "level": "off" 28 | }, 29 | "readme-contains-team-mission": { 30 | "level": "off" 31 | } 32 | } 33 | } --------------------------------------------------------------------------------