diff --git a/landing-page/assets/css/styles.css b/landing-page/assets/css/styles.css new file mode 100644 index 00000000..6909c1f3 --- /dev/null +++ b/landing-page/assets/css/styles.css @@ -0,0 +1,789 @@ +/* Base Styles */ +:root { + --cms-blue: #015390; + --cms-gold: #f3ce3b; + --cms-bright-blue: #009ad0; + --cms-orange: #d76c35; + --cms-red-orange: #cf4f27; + --cms-dark-red: #941f2e; + --cms-magenta: #961d56; + --cms-yellow: #d6aa2a; + --cms-green: #80ab40; + + --cms-dark-blue: #013b63; + --cms-light-blue: #e5f3fa; + + --white: #ffffff; + --gray-light: #f1f1f1; + --gray: #d6d7d9; + --gray-dark: #323a45; + --text: #212121; + + /* Functional Colors */ + --primary: var(--cms-blue); + --primary-dark: var(--cms-dark-blue); + --secondary: var(--cms-bright-blue); + --accent: var(--cms-gold); + --focus-color: var(--cms-bright-blue); + --banner-bg: #f0f0f0; + --footer-dark: #1b1b1b; + --footer-lighter: #3d4551; + } + + /* Global reset and defaults */ + * { + box-sizing: border-box; + margin: 0; + padding: 0; + } + + body { + font-family: 'Public Sans', 'Segoe UI', sans-serif; + line-height: 1.6; + color: var(--text); + background-color: #f9f9fa; + } + + .container, .grid-container { + max-width: 1200px; + margin: 0 auto; + padding: 0 20px; + } + + /* Layout utilities */ + .grid-row { + display: flex; + flex-wrap: wrap; + } + + .grid-gap-lg { + gap: 2rem; + } + + .tablet\:grid-col-6 { + flex-basis: 50%; + } + + /* Accessibility */ + .skip-link { + position: absolute; + top: -40px; + left: 0; + background: var(--primary-dark); + color: var(--white); + padding: 8px; + z-index: 100; + text-decoration: none; + transition: top 0.3s; + } + + .skip-link:focus { + top: 0; + } + + .sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; + } + + /* Focus styles for better accessibility */ + :focus:not(:focus-visible) { + outline: none !important; + } + + :focus-visible { + outline: 3px solid var(--focus-color) !important; + outline-offset: 3px; + } + + a:focus-visible, + button:focus-visible, + [tabindex="0"]:focus-visible { + outline: 3px solid var(--cms-bright-blue); + outline-offset: 3px; + } + + /* Feedback Banner */ + .feedback-banner { + font-family: 'Public Sans', 'Segoe UI', sans-serif; + font-size: 1rem; + background-color: var(--banner-bg); + position: fixed; + top: 0; + width: 100%; + z-index: 101; + } + + /* USA Banner */ + .usa-banner { + font-family: 'Public Sans', 'Segoe UI', sans-serif; + font-size: 1rem; + background-color: var(--banner-bg); + position: fixed; + top: 0; + width: 100%; + z-index: 101; + } + + .usa-banner__header { + padding: 0.5rem 0; + font-size: 0.8rem; + } + + .usa-banner__header-flag { + float: left; + margin-right: 0.5rem; + width: 16px; + } + + .usa-banner__header-text, + .usa-banner__header-action { + margin: 0; + display: inline; + font-size: 0.8rem; + } + + .usa-banner__header-action { + margin-left: 0.5rem; + } + + .usa-banner__button { + background-color: transparent; + border: 0; + font-weight: 400; + padding: 0; + text-align: left; + font-size: 0.8rem; + color: var(--primary); + cursor: pointer; + display: inline-block; + margin-left: 0.5rem; + text-decoration: underline; + } + + .usa-banner__content { + background-color: var(--banner-bg); + display: hidden; + padding: 1rem; + font-size: 0.9rem; + } + + .usa-banner__guidance { + display: flex; + align-items: center; + padding: 0.5rem 0; + } + + .usa-banner__icon { + width: 40px; + height: 40px; + margin-right: 1rem; + } + + .usa-banner__lock-image { + width: 1em; + height: 1em; + display: inline-block; + vertical-align: middle; + } + + /* CMS Header */ + .cms-header { + background-color: var(--white); + padding: 15px 0; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + position: fixed; + width: 100%; + z-index: 100; + border-bottom: 1px solid var(--gray); + top: 24px; + transition: top 0.3s; + } + + .header-content { + display: flex; + justify-content: space-between; + align-items: center; + } + + .cms-logo { + margin-right: 2rem; + } + + .cms-logo img { + height: 50px; + } + + .project-logo { + color: var(--cms-blue); + font-size: 36px; + font-weight: 700; + display: flex; + align-items: center; + text-decoration: none; + margin-right: auto; + } + + .project-logo img { + height: 50px; + margin-right: 10px; + } + + /* Navigation */ + nav ul { + display: flex; + list-style: none; + } + + nav ul li { + margin-left: 30px; + } + + nav ul li a { + color: var(--cms-blue); + text-decoration: none; + font-weight: 500; + transition: color 0.3s; + padding: 8px; + } + + nav ul li a:hover { + color: var(--cms-bright-blue); + } + + nav ul li a[aria-current="page"] { + color: var(--cms-bright-blue); + border-bottom: 2px solid var(--cms-bright-blue); + } + + /* Mobile Menu */ + .menu-toggle { + display: none; + background: transparent; + border: none; + cursor: pointer; + padding: 8px; + } + + .icon-bar { + display: block; + width: 25px; + height: 3px; + margin: 5px auto; + background-color: var(--cms-blue); + } + + /* Hero Section */ + .hero { + background: linear-gradient(135deg, var(--cms-blue) 0%, var(--cms-dark-blue) 100%); + color: var(--white); + padding: 160px 0 80px; + text-align: center; + } + + .hero h1 { + font-size: 2.5rem; + margin-bottom: 20px; + font-weight: 700; + } + + .hero p { + font-size: 1.2rem; + max-width: 700px; + margin: 0 auto 30px; + } + + /* Buttons */ + .btn { + display: inline-block; + background-color: var(--cms-red-orange); + color: var(--white); + padding: 12px 24px; + border-radius: 4px; + text-decoration: none; + font-weight: 600; + transition: background-color 0.3s; + } + + .btn:hover { + background-color: var(--cms-dark-red); + } + + .btn-outline { + background-color: transparent; + border: 2px solid var(--white); + margin-left: 15px; + } + + .btn-outline:hover { + background-color: rgba(255, 255, 255, 0.1); + } + + /* Section Styles */ + .section-title { + text-align: center; + margin-bottom: 60px; + } + + .section-title h2 { + font-size: 2.25rem; + color: var(--cms-blue); + margin-bottom: 15px; + } + + .section-title p { + color: var(--gray-dark); + max-width: 1000px; + margin: 0 auto; + font-size: 1.1rem; + } + + /* Section: Features */ + .features { + padding: 80px 0; + background-color: var(--white); + } + + .features-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 30px; + } + + .feature-card { + background-color: var(--white); + border-radius: 8px; + overflow: hidden; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); + transition: transform 0.3s, box-shadow 0.3s; + } + + .feature-card:hover { + transform: translateY(-5px); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); + } + + .feature-icon { + height: 160px; + display: flex; + align-items: center; + justify-content: center; + background-color: var(--cms-blue); + color: var(--white); + font-size: 3rem; + } + + .feature-content { + padding: 24px; + } + + .feature-content h3 { + font-size: 1.5rem; + margin-bottom: 16px; + color: var(--cms-blue); + } + + .feature-content p { + font-size: 1rem; + line-height: 1.6; + color: var(--gray-dark); + } + + /* Section: Maturity Models */ + + .documentation { + padding: 80px 0; + background-color: var(--cms-light-blue); + } + + .quiz { + padding-top: 20px; + } + + @media (min-width: 30em) { + .usa-form { + max-width: 80rem !important; + } + } + + /* Section: Repository Templates */ + + .repository-templates { + padding: 80px 0; + background-color: var(--white); + } + + .usa-legend { + max-width: 80rem !important; + } + + .code { + background-color: var(--cms-light-blue); + padding: 10px; + } + + /* Card styles */ + + .feature-card { + background-color: var(--white); + border-radius: 8px; + overflow: hidden; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); + transition: transform 0.3s, box-shadow 0.3s; + height: 100%; + display: flex; + flex-direction: column; + } + + .feature-card:hover { + transform: translateY(-5px); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); + } + + .feature-content { + padding: 24px; + flex-grow: 1; + display: flex; + flex-direction: column; + } + + .doc-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 24px; + } + + .doc-card { + background-color: var(--white); + border-radius: 8px; + padding: 24px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); + transition: transform 0.3s, box-shadow 0.3s; + } + + .doc-card:hover { + transform: translateY(-5px); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); + } + + .doc-card h3 { + font-size: 1.3rem; + margin-bottom: 12px; + color: var(--cms-blue); + } + + .doc-card p { + color: var(--gray-dark); + margin-bottom: 16px; + font-size: 1rem; + } + + .doc-link { + color: var(--cms-blue); + text-decoration: none; + font-weight: 600; + display: inline-flex; + align-items: center; + } + + .doc-link:hover { + color: var(--cms-bright-blue); + text-decoration: underline; + } + + .doc-link span { + margin-left: 6px; + } + + /* Call to Action */ + .cta { + background-color: var(--cms-blue); + color: var(--white); + padding: 80px 0; + text-align: center; + margin-bottom: 0; + } + + .cta h2 { + font-size: 2.25rem; + margin-bottom: 20px; + } + + .cta p { + font-size: 1.2rem; + max-width: 700px; + margin: 0 auto 30px; + } + + /* Footer */ + .usa-footer { + background-color: var(--cms-blue); + margin-top: 0; + } + + .footer-section-bottom { + background-color: var(--footer-lighter); + padding: 2rem 0; + } + + .bg-base-darker { + background-color: var(--footer-lighter); + } + + .footer-simple-content { + width: 100%; + padding: 0.5rem 0; + } + + .footer-text { + color: white; + font-size: 1rem; + line-height: 1.6; + margin: 0.5rem 0; + } + + .footer-link { + color: white; + text-decoration: underline; + } + + .footer-link:hover { + text-decoration: none; + } + + /* USA Identifier */ + .usa-identifier { + background-color: var(--footer-dark); + color: white; + font-family: 'Public Sans', 'Segoe UI', sans-serif; + } + + .usa-identifier__section { + padding: 1.5rem 0; + } + + .usa-identifier__container { + max-width: 1200px; + margin: 0 auto; + padding: 0 1rem; + } + + .usa-identifier__section--masthead { + background-color: var(--footer-dark); + } + + .cms-identifier { + display: flex; + align-items: flex-start; + gap: 1rem; + } + + .cms-logos { + display: flex; + align-items: center; + } + + .cms-logo-link { + text-decoration: none; + display: block; + } + + .cms-logo-link:first-child { + margin-right: 1rem; + } + + .cms-logo-img { + height: 3rem; + width: auto; + } + + .cms-identity { + line-height: 1.5; + } + + .cms-domain { + font-weight: 700; + font-size: 1.2rem; + margin: 0; + color: white; + } + + .cms-disclaimer { + margin: 0; + font-size: 1rem; + color: white; + } + + .cms-disclaimer a { + color: white; + text-decoration: underline; + } + + .cms-disclaimer a:hover { + text-decoration: none; + } + + .usa-identifier__section--required-links { + background-color: var(--footer-dark); + } + + .footer-links-wrapper { + display: flex; + flex-wrap: wrap; + justify-content: flex-start; + gap: 2rem; + padding: 1rem 0; + } + + .footer-links-group { + display: flex; + flex-direction: column; + gap: 1rem; + min-width: 160px; + } + + .usa-identifier__required-link { + color: white; + text-decoration: underline; + font-size: 0.9rem; + } + + .usa-identifier__required-link:hover { + text-decoration: none; + } + + .usa-identifier__section--usagov { + padding: 1rem 0; + background-color: var(--footer-dark); + } + + .usagov-container { + display: flex; + align-items: center; + gap: 0.5rem; + } + + .usagov-text { + margin: 0; + color: white; + font-size: 1rem; + } + + .usagov-link { + color: white; + text-decoration: underline; + font-size: 1rem; + } + + .usagov-link:hover { + text-decoration: none; + } + + /* Responsive styles */ + @media (max-width: 768px) { + /* Mobile menu */ + .menu-toggle { + display: block; + } + + nav ul { + display: none; + position: absolute; + top: 100%; + left: 0; + width: 100%; + background-color: var(--white); + flex-direction: column; + padding: 20px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + } + + nav ul.show { + display: flex; + } + + nav ul li { + margin: 10px 0; + } + + /* Layout adjustments */ + .header-content { + flex-wrap: wrap; + } + + .hero { + padding: 240px 0 60px; + } + + .hero h1 { + font-size: 2rem; + } + + /* Button adjustments */ + .cta-buttons { + display: flex; + flex-direction: column; + align-items: center; + } + + .btn { + margin: 10px 0; + width: 100%; + max-width: 250px; + text-align: center; + } + + .btn-outline { + margin-left: 0; + } + + /* Section and title adjustments */ + .section-title h2 { + font-size: 1.8rem; + } + + .cms-logo img { + height: 40px; + } + + /* Footer responsive */ + .footer-links-wrapper { + flex-direction: column; + gap: 1.5rem; + } + + .cms-identifier { + flex-direction: column; + } + + .cms-logos { + margin-bottom: 1rem; + } + + .usagov-container { + flex-direction: column; + align-items: flex-start; + } + + .footer-links-group { + width: 100%; + } + } + + /* High contrast mode support */ + @media (forced-colors: active) { + .btn, .feature-card, .doc-card, .tool-card { + border: 1px solid CanvasText; + } + + .feature-icon, .tool-header { + border-bottom: 1px solid CanvasText; + } + } \ No newline at end of file diff --git a/landing-page/assets/images/auto-generator.svg b/landing-page/assets/images/auto-generator.svg new file mode 100644 index 00000000..34274c4a --- /dev/null +++ b/landing-page/assets/images/auto-generator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/landing-page/assets/images/cms-white.svg b/landing-page/assets/images/cms-white.svg new file mode 100644 index 00000000..cf03fc21 --- /dev/null +++ b/landing-page/assets/images/cms-white.svg @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/landing-page/assets/images/dsacms.svg b/landing-page/assets/images/dsacms.svg new file mode 100644 index 00000000..1bae8645 --- /dev/null +++ b/landing-page/assets/images/dsacms.svg @@ -0,0 +1,529 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/landing-page/assets/images/form-generator.svg b/landing-page/assets/images/form-generator.svg new file mode 100644 index 00000000..544f64db --- /dev/null +++ b/landing-page/assets/images/form-generator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/landing-page/assets/images/hhs-white.svg b/landing-page/assets/images/hhs-white.svg new file mode 100644 index 00000000..6a573a03 --- /dev/null +++ b/landing-page/assets/images/hhs-white.svg @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/landing-page/assets/images/index-generator.svg b/landing-page/assets/images/index-generator.svg new file mode 100644 index 00000000..b365d618 --- /dev/null +++ b/landing-page/assets/images/index-generator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/landing-page/assets/images/metrics.svg b/landing-page/assets/images/metrics.svg new file mode 100644 index 00000000..ca9bdda7 --- /dev/null +++ b/landing-page/assets/images/metrics.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/landing-page/assets/images/repo-scaffolder.svg b/landing-page/assets/images/repo-scaffolder.svg new file mode 100644 index 00000000..0e7fb94d --- /dev/null +++ b/landing-page/assets/images/repo-scaffolder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/landing-page/assets/images/repolinter.svg b/landing-page/assets/images/repolinter.svg new file mode 100644 index 00000000..75e07c1a --- /dev/null +++ b/landing-page/assets/images/repolinter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/landing-page/assets/js/main.js b/landing-page/assets/js/main.js new file mode 100644 index 00000000..c23ce932 --- /dev/null +++ b/landing-page/assets/js/main.js @@ -0,0 +1,135 @@ +document.addEventListener('DOMContentLoaded', function () { + + // // Federal banner opening functionality + // const bannerButton = document.querySelector('.usa-banner__button'); + // const bannerContent = document.getElementById('gov-banner'); + // const cmsHeader = document.querySelector('.cms-header'); + // let bannerExpanded = false; + + // if (bannerButton && bannerContent) { + // bannerContent.style.display = 'none'; + + // bannerButton.addEventListener('click', function () { + // bannerExpanded = !bannerExpanded; + // this.setAttribute('aria-expanded', bannerExpanded); + + // // hacky but only way i got this to expand and close with the custom banner + // if (bannerExpanded) { + // bannerContent.style.display = 'block'; + // if (cmsHeader) { + // cmsHeader.style.top = bannerContent.offsetHeight + 24 + 'px'; + // } + // } else { + // bannerContent.style.display = 'none'; + // if (cmsHeader) { + // cmsHeader.style.top = '24px'; + // } + // } + // }); + // } + + // Mobile menu toggle + const menuToggle = document.querySelector('.menu-toggle'); + const mainMenu = document.getElementById('main-menu'); + + if (menuToggle && mainMenu) { + menuToggle.addEventListener('click', function () { + const expanded = this.getAttribute('aria-expanded') === 'true' || false; + this.setAttribute('aria-expanded', !expanded); + mainMenu.classList.toggle('show'); + }); + + document.addEventListener('click', function (e) { + if (!menuToggle.contains(e.target) && !mainMenu.contains(e.target) && mainMenu.classList.contains('show')) { + mainMenu.classList.remove('show'); + menuToggle.setAttribute('aria-expanded', 'false'); + } + }); + } + + // Add smooth scrolling for anchor links + document.querySelectorAll('a[href^="#"]').forEach(anchor => { + anchor.addEventListener('click', function (e) { + e.preventDefault(); + + const target = document.querySelector(this.getAttribute('href')); + + if (target) { + // Adjust the scroll position to account for the fixed header + const headerHeight = document.querySelector('.cms-header').offsetHeight; + const targetPosition = target.getBoundingClientRect().top + window.scrollY; + const offsetPosition = targetPosition - headerHeight; + + window.scrollTo({ + top: offsetPosition, + behavior: 'smooth' + }); + } + }); + }); + + // Keyboard navigation for cards + const cards = document.querySelectorAll('.feature-card, .doc-card'); + cards.forEach(card => { + card.setAttribute('tabindex', '0'); + + card.addEventListener('keydown', function (e) { + if (e.key === 'Enter') { + e.preventDefault(); + const link = this.querySelector('a'); + if (link) { + link.click(); + } + } + }); + }); + + // // dynamic nav bar based on scroll position + // const sections = document.querySelectorAll('section[id]'); + // const navItems = document.querySelectorAll('nav ul li a'); + + // function setActiveNavItem() { + // const scrollPosition = window.scrollY; + // const headerHeight = document.querySelector('header').offsetHeight; + // const bannerHeight = document.querySelector('.usa-banner').offsetHeight; + // const totalOffset = headerHeight + bannerHeight; + + // navItems.forEach(item => { + // item.removeAttribute('aria-current'); + // }); + + // const documentationSection = document.getElementById('documentation'); + + // if (scrollPosition < (documentationSection.offsetTop - totalOffset - 100)) { + // navItems.forEach(item => { + // if (item.getAttribute('href') === '#hero') { + // item.setAttribute('aria-current', 'page'); + // } + // }); + // return; + // } + // let currentSection = null; + + // sections.forEach(section => { + // if (section.id === 'hero') return; + + // const sectionTop = section.offsetTop - totalOffset - 100; + // const sectionBottom = sectionTop + section.offsetHeight; + + // if (scrollPosition >= sectionTop && scrollPosition < sectionBottom) { + // currentSection = section.id; + // } + // }); + + // if (currentSection) { + // navItems.forEach(item => { + // if (item.getAttribute('href') === '#' + currentSection) { + // item.setAttribute('aria-current', 'page'); + // } + // }); + // } + // } + + // window.addEventListener('scroll', setActiveNavItem); + // setActiveNavItem(); +}); \ No newline at end of file diff --git a/landing-page/assets/js/quizHandler.js b/landing-page/assets/js/quizHandler.js new file mode 100644 index 00000000..c7312143 --- /dev/null +++ b/landing-page/assets/js/quizHandler.js @@ -0,0 +1,72 @@ +document.addEventListener("DOMContentLoaded", function () { + const form = document.querySelector(".usa-form"); + const formContainer = document.querySelector(".form-container"); + const resultsContainer = document.querySelector(".results"); + const tierResult = document.querySelector(".tier-result"); + + if (!form) return; + + form.addEventListener("submit", function (event) { + event.preventDefault(); + + const checkedValues = Array.from( + document.querySelectorAll("input[name='tier-determiner']:checked") + ).map((input) => input.value); + + console.log("Selected answers:", checkedValues); + + // Tier selection logic + let tier; + let name; + if (!checkedValues.includes("contributors")) { + tier = "0"; + name = "Private Repository" + } else if (!checkedValues.includes("release")){ + tier = "0"; + name = "Private Repository" + } + else if (!checkedValues.includes("work")){ + tier = "1"; + name = "One-Time Release" + } + else if (!checkedValues.includes("maintain")){ + tier = "2"; + name = "Close Collaboration" + } + else if (!checkedValues.includes("roadmap")){ + tier = "3"; + name = "Working in Public" + } + else { + tier = "4"; + name = "Community Governance" + } + + // Display results + formContainer.style.display = "none"; + resultsContainer.style.display = "block"; + tierResult.innerHTML = `Your project is: Tier ${tier} - ${name}
+ + Learn more about this maturity model tier + + `; + }); + }); + + function uncheckAllCheckboxes() { + const checkboxes = document.querySelectorAll(".usa-checkbox__input"); + checkboxes.forEach((checkbox) => { + checkbox.checked = false; + }); + } + + function handleClick(event) { + const formContainer = document.querySelector(".form-container"); + const resultsContainer = document.querySelector(".results"); + + event.preventDefault(); + uncheckAllCheckboxes(); // Clear input + + resultsContainer.style.display = "none"; + formContainer.style.display = "block"; + } \ No newline at end of file diff --git a/landing-page/index.html b/landing-page/index.html new file mode 100644 index 00000000..382708b8 --- /dev/null +++ b/landing-page/index.html @@ -0,0 +1,545 @@ + + + + + + repo-scaffolder | Centers for Medicare & Medicaid Services + + + + + + + + + + + + +
+
+
+

+ Work in progress. We welcome questions and suggestions β€” + give us feedback. +

+
+
+
+ + + + +
+ + +
+
+

Creating Open Source Projects in CMS Ecosystem

+ +
+
+ + +
+
+
+

What is repo-scaffolder?

+

A suite of tools for creating new repositories that align with repository hygiene standards and best practices in US Federal open source development.

+
+ +
+
+ +
+

Maturity Models

+

A framework to evaluate and categorize open source repositories based on their composition and goals

+
+
+
+ +
+

Repository Templates

+

A foundation for building repositories that are well-documented, clean, and adhere to repository hygiene standards and best practices

+
+
+
+ +
+

Outbound Checklists

+

A review process to reduce risk and improve quality when releasing open source projects

+
+
+
+
+
+ + +
+
+
+

Maturity Models

+

Our maturity model framework is designed to evaluate and categorize open source repositories based on their composition and goals. This framework consists of five tiers, each representing different stages of a project's development practices, collaboration scope, community engagement, and governance structure. +

+
+ Learn More +
+
+ +

+ Tier Definitions +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LevelNamePurposeDescription
Tier 0 + Private Repository + Experimental/HistoricalProject is private, usually with a single developer. Typically working projects, example code, and early prototypes.
Tier 1 + One-Time Release + Information/HistoricalProject released publicly, but without planned future activity or maintenance from original author(s)
Tier 2Close CollaborationCollaborate with smaller, mostly internal teamsProject within a team or Operational Division (OpDiv), Internal Repo for Innersource-style work.
Tier 3Working in PublicCollaborate in the Open with smaller, semi-open teamsProject developed Open Source by CMS or a CMS contractor, public website hosted on GitHub, tool or utility used in CMS official business by the public. Limited external contribution, CMS-led (by choice or by statute).
Tier 4Community GovernanceCollaborate broadly in publicProject donated to or stewarded by an external community, open standard that welcomes public input, mature open source project that purposefully develops an open governance structure.
+
+ +
+

What is my project's maturity model tier?

+
+
+
+ Answer the series of questions below to determine the maturity model tier of your project: +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+ + +
+ + +
+
+
+

Repository Templates

+

Each maturity model tier requires specific files and documentation such as: project information, security policies, licensing details, and contribution guidelines. This documentation creates transparency, enables collaboration, and supports sustainability.

+
+ +
+
+
+

Repository File Requirements by Tier

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileDescriptionTier 0Tier 1Tier 2Tier 3Tier 4
LICENSEDefines the licensing terms under which the project is distributed.MMMMM
code.jsonContains project metadata following legislative requirements.MMMMM
README.mdProvides a comprehensive overview of the project, including its purpose, how to install or use it, and any relevant information for users or developers.MMMMM
COMMUNITY.mdLists project team members and points of contact with detailed roles and responsibilities.MMMMM
SECURITY.mdOutlines the agency's security policies, including how to report security issues or vulnerabilities in the code.RMMMM
CONTRIBUTING.mdOffers guidelines for contributing to the project, including code standards, how to submit issues, and creating pull requests.RRMMM
CODE_OF_CONDUCT.mdEstablishes guidelines for acceptable behavior within the community, setting expectations for how contributors should interact in a respectful and collaborative manner.NNMMM
GOVERNANCE.mdDescribes the governance model of the project, such as decision-making processes and rules for contributing. It ensures a transparent process for managing the project.NNNRM
+
+
+ +

Legend

+ + + + + + + + + + + + + + + + + + + + +
LevelDescription
MMandatory
RRecommended
NNot Recommended
+
+
+ Learn more about file content requirements +
+
+ +

Get started!

+

Create a repository using our cookiecutter CLI by running the command below, replacing X with the tier number:

+
+
cookiecutter https://github.com/DSACMS/repo-scaffolder --directory=tierX
+
+
+ +

Managing your Repository

+

repo-scaffolder includes a suite of tools to help maintain and manage your repository throughout development.

+
+
+
+

Cookiecutter

+

Create new repositories using file templates as your starting point.

+ View docs +
+
+

Repolinter

+

Identify missing files and content.

+ View docs +
+
+

Metadata

+

Create and update metadata in code.json using cookiecutter and GitHub Actions.

+ View docs +
+
+

Workflows

+

Automated GitHub Action jobs to keep your repository updated.

+ View docs +
+
+
+
+ + +
+
+
+

Outbound Checklists

+

A review process to approve CMS-developed software to be released as open source.

+
+ Learn More +
+ +
+
+

Benefits & Risks

+

Evaluate cost savings, development benefits, and potential security, financial, and privacy risks of open sourcing the repository.

+
+
+

Code Review

+

Ensure code quality and security through analysis and testing with open source tools.

+
+
+

Repository Hygiene

+

Include required files, sections, and documentation in the repository to meet hygiene standards.

+ View files +
+
+

Metadata

+

Store metadata on the project, as part of the Federal Source Code Policy and the agency’s software inventory tracking initiatives.

+ View code.json +
+
+

Flip the Switch!

+

After passing outbound review, the repository is officially ready to be public and shared with the greater community.

+
+
+
+
+ + +
+
+

Ready to create an open source repository?

+

Use the templates and tools here!

+ View on GitHub +
+
+
+ + + + +
+
+
+
+ +
+

cms.gov

+

+ An official website of the Department of Health and Human Services and the + Centers for Medicare and Medicaid Services +

+
+
+
+
+ +
+
+
+
Looking for U.S. government information and services?
+ Visit USA.gov +
+
+
+
+ + \ No newline at end of file