├── .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 | }
--------------------------------------------------------------------------------