1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[779],{2346:function(e,s,i){(window.__NEXT_P=window.__NEXT_P||[]).push(["/docs/github-guide",function(){return i(6989)}])},6989:function(e,s,i){"use strict";i.r(s),i.d(s,{default:function(){return o}});var n=i(5893),c=i(7294),r=i(4666),l=i(7289),a=i.n(l),t=i(837),d=i(6167);function o(){return(0,c.useEffect)(()=>{document.querySelectorAll("pre code").forEach(e=>{t.Z.highlightElement(e)})},[]),(0,n.jsx)(r.Z,{seo:{title:"Git & GitHub Workflow",description:"Git & GitHub workflow, branching model, roles and best practices for firmware teams. Version 4.0.",keywords:"git, github, version control, workflow, branching, collaboration, firmware"},children:(0,n.jsxs)("div",{className:a().docPage,children:[(0,n.jsxs)("nav",{className:a().breadcrumb,children:[(0,n.jsx)("a",{href:"/docs",children:"Documentation"}),(0,n.jsx)("span",{className:a().separator,children:"â"}),(0,n.jsx)("span",{children:"GitHub Workflow"})]}),(0,n.jsxs)("article",{className:a().docContent,children:[(0,n.jsxs)("div",{className:a().docHeader,children:[(0,n.jsx)("span",{className:a().docIcon,children:"\uD83D\uDC19"}),(0,n.jsxs)("div",{children:[(0,n.jsx)("h1",{className:a().docTitle,children:"Git & GitHub Workflow"}),(0,n.jsx)("p",{className:a().docSubtitle,children:"Team Guidelines \xb7 Version 4.0 \xb7 Last Updated: October 2025"})]})]}),(0,n.jsxs)("div",{className:a().tableOfContents,children:[(0,n.jsx)("h3",{children:"Contents"}),(0,n.jsxs)("ul",{children:[(0,n.jsx)("li",{children:(0,n.jsx)("a",{href:"#purpose",children:"Purpose"})}),(0,n.jsx)("li",{children:(0,n.jsx)("a",{href:"#naming",children:"Repository Naming & Structure"})}),(0,n.jsx)("li",{children:(0,n.jsx)("a",{href:"#branching",children:"Branching Model"})}),(0,n.jsx)("li",{children:(0,n.jsx)("a",{href:"#roles",children:"Roles & Responsibilities"})}),(0,n.jsx)("li",{children:(0,n.jsx)("a",{href:"#versioning",children:"Versioning & Releases"})}),(0,n.jsx)("li",{children:(0,n.jsx)("a",{href:"#submodules",children:"Git Submodules"})}),(0,n.jsx)("li",{children:(0,n.jsx)("a",{href:"#best-practices",children:"Best Practices"})}),(0,n.jsx)("li",{children:(0,n.jsx)("a",{href:"#security",children:"Security & Access Matrix"})})]})]}),(0,n.jsxs)("section",{id:"purpose",children:[(0,n.jsx)("h2",{children:"1. Purpose"}),(0,n.jsxs)("p",{children:["This document defines the ",(0,n.jsx)("strong",{children:"standard Git & GitHub workflow"})," for all firmware teams. It ensures code integrity, traceability, and predictable release management across projects by clearly defining repository structure, branching and merging strategies, and role-based responsibilities (Admin / Manager / Developer)."]})]}),(0,n.jsxs)("section",{id:"naming",children:[(0,n.jsx)("h2",{children:"2. Repository Naming and Structure"}),(0,n.jsx)("h3",{children:"Naming Convention"}),(0,n.jsxs)("table",{className:a().componentsTable,children:[(0,n.jsx)("thead",{children:(0,n.jsxs)("tr",{children:[(0,n.jsx)("th",{children:"Type"}),(0,n.jsx)("th",{children:"Naming Format"}),(0,n.jsx)("th",{children:"Example"})]})}),(0,n.jsxs)("tbody",{children:[(0,n.jsxs)("tr",{children:[(0,n.jsx)("td",{children:"Firmware source code"}),(0,n.jsx)("td",{children:(0,n.jsx)("code",{children:"projectname-fw"})}),(0,n.jsx)("td",{children:(0,n.jsx)("code",{children:"sensorhub-fw"})})]}),(0,n.jsxs)("tr",{children:[(0,n.jsx)("td",{children:"Documentation"}),(0,n.jsx)("td",{children:(0,n.jsx)("code",{children:"projectname-doc"})}),(0,n.jsx)("td",{children:(0,n.jsx)("code",{children:"sensorhub-doc"})})]}),(0,n.jsxs)("tr",{children:[(0,n.jsx)("td",{children:"Shared library"}),(0,n.jsx)("td",{children:(0,n.jsx)("code",{children:"libname-fwlib"})}),(0,n.jsx)("td",{children:(0,n.jsx)("code",{children:"motorctrl-fwlib"})})]}),(0,n.jsxs)("tr",{children:[(0,n.jsx)("td",{children:"Test or simulation"}),(0,n.jsx)("td",{children:(0,n.jsx)("code",{children:"projectname-test"})}),(0,n.jsx)("td",{children:(0,n.jsx)("code",{children:"sensorhub-test"})})]})]})]}),(0,n.jsxs)("div",{className:a().tipBox,children:[(0,n.jsx)("strong",{children:"\uD83D\uDCCB Important:"})," All documentation (system design, field test logs, hardware specs) lives in a dedicated ",(0,n.jsx)("code",{children:"projectname-doc"})," repository. Do not commit binaries, SDKs, build artifacts, or secrets."]}),(0,n.jsx)("h3",{children:"Repository Folder Layout"}),(0,n.jsxs)("div",{className:a().example,children:[(0,n.jsx)("div",{className:a().exampleLabel,children:"â
Standard Project Structure"}),(0,n.jsx)("pre",{children:(0,n.jsx)("code",{children:"projectname-fw/\nâ\nâââ docs/ # Developer-facing notes\nâââ src/ # Firmware source\nâââ include/ # Headers\nâââ build/ # Build scripts (no compiled outputs)\nâââ tools/ # Flas
1hing or analysis utilities\nâââ tests/ # Unit/integration tests\nâââ .gitignore\nâââ README.md\nâââ LICENSE\nâââ CHANGELOG.md"})})]})]}),(0,n.jsxs)("section",{id:"branching",children:[(0,n.jsx)("h2",{children:"3. Branching Model Overview"}),(0,n.jsxs)("div",{className:a().flowDiagram,children:[(0,n.jsx)("strong",{children:"Flow:"})," ",(0,n.jsx)("code",{children:"feature"})," / ",(0,n.jsx)("code",{children:"bugfix"})," branches â",(0,n.jsx)("strong",{children:" development"})," â",(0,n.jsx)("strong",{children:" staging"})," â",(0,n.jsx)("strong",{children:" production"})]}),(0,n.jsx)("h3",{children:"Main Branches"}),(0,n.jsxs)("table",{className:a().componentsTable,children:[(0,n.jsx)("thead",{children:(0,n.jsxs)("tr",{children:[(0,n.jsx)("th",{children:"Branch"}),(0,n.jsx)("th",{children:"Purpose"}),(0,n.jsx)("th",{children:"Access"})]})}),(0,n.jsxs)("tbody",{children:[(0,n.jsxs)("tr",{children:[(0,n.jsx)("td",{children:(0,n.jsx)("strong",{children:"development"})}),(0,n.jsx)("td",{children:"Active development branch. All new work starts here."}),(0,n.jsx)("td",{children:"All Developers"})]}),(0,n.jsxs)("tr",{children:[(0,n.jsx)("td",{children:(0,n.jsx)("strong",{children:"staging"})}),(0,n.jsx)("td",{children:"Integration and field-testing branch."}),(0,n.jsx)("td",{children:"Managers only"})]}),(0,n.jsxs)("tr",{children:[(0,n.jsx)("td",{children:(0,n.jsx)("strong",{children:"production"})}),(0,n.jsx)("td",{children:"Stable, released firmware in production."}),(0,n.jsx)("td",{children:"Admins & Managers"})]})]})]}),(0,n.jsx)("h3",{children:"Developer Branches"}),(0,n.jsxs)("div",{className:a().branchingRules,children:[(0,n.jsxs)("div",{className:a().ruleItem,children:[(0,n.jsx)("span",{className:a().ruleIcon,children:"\uD83D\uDCCC"}),(0,n.jsxs)("div",{children:["All development must have a ",(0,n.jsx)("strong",{children:"basis"})," (work item, user story, feature or task)"]})]}),(0,n.jsxs)("div",{className:a().ruleItem,children:[(0,n.jsx)("span",{className:a().ruleIcon,children:"â±ï¸"}),(0,n.jsxs)("div",{children:["Feature branches should be ",(0,n.jsx)("strong",{children:"short-lived"})," (aim to merge within two weeks)"]})]}),(0,n.jsxs)("div",{className:a().ruleItem,children:[(0,n.jsx)("span",{className:a().ruleIcon,children:"\uD83D\uDC64"}),(0,n.jsxs)("div",{children:["Each developer should have ",(0,n.jsx)("strong",{children:"only one active branch"})," assigned to them where possible"]})]})]}),(0,n.jsxs)("div",{className:a().example,children:[(0,n.jsx)("div",{className:a().exampleLabel,children:"Branch Naming Examples"}),(0,n.jsx)("pre",{children:(0,n.jsx)("code",{children:"feature/feature-name\nbugfix/ISSUE-123\nhotfix/critical-security-patch\ndocs/update-api-documentation"})})]}),(0,n.jsxs)("div",{className:a().warningBox,children:[(0,n.jsx)("strong",{children:"â ï¸ Note on Master:"})," Do NOT push directly to ",(0,n.jsx)("code",{children:"master"})," unless you are a repository maintainer. Maintain strict protection rules."]})]}),(0,n.jsxs)("section",{id:"roles",children:[(0,n.jsx)("h2",{children:"4. Roles, Responsibilities & Permissions"}),(0,n.jsxs)("div",{className:a().rolesGrid,children:[(0,n.jsxs)("div",{className:a().roleCard+" "+a().roleAdmin,children:[(0,n.jsx)("h3",{children:"\uD83D\uDD10 Admin"}),(0,n.jsx)("p",{className:a().roleDescription,children:"Responsible for overall integrity of repositories"}),(0,n.jsxs)("div",{className:a().responsibilities,children:[(0,n.jsx)("h4",{children:"Responsibilities:"}),(0,n.jsxs)("ul",{children:[(0,n.jsx)("li",{children:"Create and configure repositories"}),(0,n.jsx)("li",{children:"Enforce branch protections"}),(0,n.jsx)("li",{children:"Manage teams and CI/CD pipelines"}),(0,n.jsxs)("li",{children:["Approve merges to ",(0,n.jsx)("code",{children:"production"})]}),(0,n.jsx)("li",{children:"Maintain security policies (2FA, signed commits)"}),(0,n.jsx)("li",{children:"Ensure no secrets in repos"})]})]})]}),(0,n.jsxs)("div",{className:a().roleCard+" "+a().roleManager,children:[(0,n.jsx)("h3",{children:"\uD83D\uDC54 Manager / Maintainer"}),(0,n.jsx)("p",{className:a().roleDescription,children:"Acts as technical lead for the project"}),(0,n.jsxs)("div",{className:a().responsibilities,children:[(0,n.jsx)("h4",{children:"Responsibilities:"}),(0,n.jsxs)("ul",{children:[(0,n.jsxs)("li",{children:["Review PRs to ",(0,n.jsx)("code",{children:"development"})]}),(0,n.jsxs)("li",{children:["Integrate stable work into ",(0,n.jsx)("code",{children:"staging"})]}),(0,n.jsx)("li",{children:"Maintain changelogs"}),(0,n.jsx)("li",{children:"Supervise testing cycles"}),(0,n.jsx)("li",{children:"Tag releases"}),(0,n.jsx)("li",{children:"Coordinate with developers"})]})]})]}),(0,n.jsxs)("div",{className:a().roleCard+" "+a().roleDeveloper,children:[(0,n.jsx)("h3",{children:"\uD83D\uDCBB Developer"}),(0,n.jsx)("p",{className:a().roleDescription,children:"Builds, tests, and submits code via pull requests"}),(0,n.jsxs)("div",{className:a().responsibilities,children:[(0,n.jsx)("h4",{children:"Typical Workflow:"}),(0,n.jsxs)("div",{className:a().example,children:[(0,n.jsx)("div",{className:a().exampleLabel,children:"Developer Workflow"}),(0,n.jsx)("pre",{children:(0,n.jsx)("code",{children:"git checkout -b feature/add-usb-bootloader\n\n# work locally, commit often\n\ngit fetch origin\ngit merge origin/development\ngit push origin feature/add-usb-bootloader\n\n# open PR -> development"})})]})]})]})]})]}),(0,n.jsxs)("section",{id:"versioning",children:[(0,n.jsx)("h2",{children:"5. Versioning & Releases"}),(0,n.jsx)("h3",{children:"Semantic Versioning"}),(0,n.jsxs)("p",{children:["Use semantic versioning: ",(0,n.jsx)("strong",{children:"MAJOR.MINOR.PATCH"})," (e.g., ",(0,n.jsx)("code",{children:"v2.1.0"}),")"]}),(0,n.jsx)("div",{className:a().versionBox,children:(0,n.jsxs)("div",{className:a().versionExample,children:[(0,n.jsx)("div",{className:a().versionNumber,children:"v2.1.0"}),(0,n.jsxs)("div",{className:a().versionBreakdown,children:[(0,n.jsxs)("div",{className:a().versionPart,children:[(0,n.jsx)("strong",{children:"2"})," ",(0,n.jsx)("span",{children:"MAJOR"}),(0,n.jsx)("p",{children:"Breaking changes, incompatible API changes"})]}),(0,n.jsxs)("div",{className:a().versionPart,children:[(0,n.jsx)("strong",{children:"1"})," ",(0,n.jsx)("span",{children:"MINOR"}),(0,n.jsx)("p",{children:"New features, backward compatible"})]}),(0,n.jsxs)("div",{className:a().versionPart,children:[(0,n.jsx)("strong",{children:"0"})," ",(0,n.jsx)("span",{children:"PATCH"}),(0,n.jsx)("p",{children:"Bug fixes, backward compatible"})]})]})]})}),(0,n.jsx)("h3",{children:"Release Process"}),(0,n.jsxs)("div",{className:a().example,children:[(0,n.jsx)("div",{className:a().exampleLabel,children:"Creating a Release"}),(0,n.jsx)("pre",{children:(0,n.jsx)("code",{children:'git tag -a v2.1.0 -m "Release v2.1.0 â New USB stack"\ngit push origin v2.1.0'})})]}),(0,n.jsxs)("div",{className:a().tipBox,children:[(0,n.jsx)("strong",{children:"\uD83D\uDCE6 Release Artifacts:"})," Attach binaries in GitHub Releases (not in repo), and update ",(0,n.jsx)("code",{children:"CHA
1NGELOG.md"})," with release notes."]}),(0,n.jsx)("h3",{children:"CHANGELOG.md Format"}),(0,n.jsxs)("div",{className:a().example,children:[(0,n.jsx)("div",{className:a().exampleLabel,children:"â
CHANGELOG.md Example"}),(0,n.jsx)("pre",{children:(0,n.jsx)("code",{children:"# Changelog\n\n## [2.1.0] - 2025-11-06\n\n### Added\n- New USB bootloader support\n- Over-the-air (OTA) update capability\n- Temperature calibration interface\n\n### Changed\n- Improved WiFi reconnection logic\n- Optimized power consumption in sleep mode\n\n### Fixed\n- Sensor timeout issue in low-power mode\n- Memory leak in MQTT client\n\n## [2.0.0] - 2025-10-15\n\n### Breaking Changes\n- Changed API for sensor configuration\n- Removed deprecated functions from v1.x\n\n### Added\n- RTOS support with FreeRTOS\n- Multi-sensor support"})})]})]}),(0,n.jsxs)("section",{id:"submodules",children:[(0,n.jsx)("h2",{children:"6. Git Submodules"}),(0,n.jsxs)("p",{children:["Use ",(0,n.jsx)("strong",{children:"submodules"})," for shared libraries intended for reuse across projects. This keeps common code synchronized and version-controlled."]}),(0,n.jsx)("h3",{children:"Adding a Submodule"}),(0,n.jsxs)("div",{className:a().example,children:[(0,n.jsx)("div",{className:a().exampleLabel,children:"Add Shared Library"}),(0,n.jsx)("pre",{children:(0,n.jsx)("code",{children:'# Add submodule to your project\ngit submodule add https://github.com/yourorg/motorctrl-fwlib lib/motorctrl\n\n# Commit the submodule reference\ngit commit -m "Add motorctrl library as submodule"'})})]}),(0,n.jsx)("h3",{children:"Cloning with Submodules"}),(0,n.jsxs)("div",{className:a().example,children:[(0,n.jsx)("div",{className:a().exampleLabel,children:"Clone Project with Submodules"}),(0,n.jsx)("pre",{children:(0,n.jsx)("code",{children:"# Option 1: Clone and init submodules in one command\ngit clone --recurse-submodules https://github.com/yourorg/project-fw\n\n# Option 2: Clone first, then init submodules\ngit clone https://github.com/yourorg/project-fw\ncd project-fw\ngit submodule init\ngit submodule update"})})]}),(0,n.jsx)("h3",{children:"Updating Submodules"}),(0,n.jsxs)("div",{className:a().example,children:[(0,n.jsx)("div",{className:a().exampleLabel,children:"Update to Latest Submodule Version"}),(0,n.jsx)("pre",{children:(0,n.jsx)("code",{children:'# Enter submodule directory\ncd lib/motorctrl\n\n# Pull latest changes\ngit pull origin main\n\n# Return to main project\ncd ../..\n\n# Commit the submodule update\ngit add lib/motorctrl\ngit commit -m "Update motorctrl library to v1.5.0"\ngit push'})})]}),(0,n.jsxs)("div",{className:a().tipBox,children:[(0,n.jsx)("strong",{children:"\uD83D\uDCA1 Important:"})," Update the submodule and commit the change in the container repo when the submodule HEAD changes. This ensures everyone gets the correct version."]})]}),(0,n.jsxs)("section",{id:"best-practices",children:[(0,n.jsx)("h2",{children:"7. Best Practices & Common Pitfalls"}),(0,n.jsx)("h3",{children:"â
Do's"}),(0,n.jsxs)("div",{className:a().practiceList,children:[(0,n.jsxs)("div",{className:a().practiceItem,children:[(0,n.jsx)("div",{className:a().practiceIcon,children:"â
"}),(0,n.jsxs)("div",{children:[(0,n.jsxs)("strong",{children:["Keep ",(0,n.jsx)("code",{children:"development"})," clean and buildable"]}),(0,n.jsx)("p",{children:"Every commit to development should compile and pass basic tests"})]})]}),(0,n.jsxs)("div",{className:a().practiceItem,children:[(0,n.jsx)("div",{className:a().practiceIcon,children:"â
"}),(0,n.jsxs)("div",{children:[(0,n.jsxs)("strong",{children:["Use ",(0,n.jsx)("code",{children:".gitignore"})," aggressively"]}),(0,n.jsx)("p",{children:"Exclude build outputs, IDE files, OS-specific files, and temporary files"})]})]}),(0,n.jsxs)("div",{className:a().practiceItem,children:[(0,n.jsx)("div",{className:a().practiceIcon,children:"â
"}),(0,n.jsxs)("div",{children:[(0,n.jsx)("strong",{children:"Write atomic commits and meaningful messages"}),(0,n.jsx)("p",{children:"Each commit should represent one logical change with clear description"})]})]}),(0,n.jsxs)("div",{className:a().practiceItem,children:[(0,n.jsx)("div",{className:a().practiceIcon,children:"â
"}),(0,n.jsxs)("div",{children:[(0,n.jsx)("strong",{children:"Pull before push"}),(0,n.jsx)("p",{children:"Always fetch and merge latest changes before pushing your work"})]})]}),(0,n.jsxs)("div",{className:a().practiceItem,children:[(0,n.jsx)("div",{className:a().practiceIcon,children:"â
"}),(0,n.jsxs)("div",{children:[(0,n.jsx)("strong",{children:"Review before merging"}),(0,n.jsx)("p",{children:"All code must be reviewed by at least one other team member"})]})]})]}),(0,n.jsx)("h3",{children:"\uD83D\uDEAB Don'ts"}),(0,n.jsxs)("div",{className:a().practiceList,children:[(0,n.jsxs)("div",{className:a().practiceItem+" "+a().dontItem,children:[(0,n.jsx)("div",{className:a().practiceIcon,children:"\uD83D\uDEAB"}),(0,n.jsxs)("div",{children:[(0,n.jsx)("strong",{children:"Don't force-push shared branches"}),(0,n.jsx)("p",{children:"Force pushing rewrites history and breaks collaboration"})]})]}),(0,n.jsxs)("div",{className:a().practiceItem+" "+a().dontItem,children:[(0,n.jsx)("div",{className:a().practiceIcon,children:"\uD83D\uDEAB"}),(0,n.jsxs)("div",{children:[(0,n.jsx)("strong",{children:"Don't commit binaries, SDKs, or secrets"}),(0,n.jsx)("p",{children:"Use .gitignore and environment variables for configuration"})]})]}),(0,n.jsxs)("div",{className:a().practiceItem+" "+a().dontItem,children:[(0,n.jsx)("div",{className:a().practiceIcon,children:"\uD83D\uDEAB"}),(0,n.jsxs)("div",{children:[(0,n.jsx)("strong",{children:"Don't merge unreviewed or untested code"}),(0,n.jsx)("p",{children:"All PRs must pass review and CI/CD checks before merging"})]})]}),(0,n.jsxs)("div",{className:a().practiceItem+" "+a().dontItem,children:[(0,n.jsx)("div",{className:a().practiceIcon,children:"\uD83D\uDEAB"}),(0,n.jsxs)("div",{children:[(0,n.jsx)("strong",{children:"Don't push directly to protected branches"}),(0,n.jsx)("p",{children:"Use pull requests for all changes to development, staging, and production"})]})]})]}),(0,n.jsx)("h3",{children:".gitignore Template"}),(0,n.jsxs)("div",{className:a().example,children:[(0,n.jsx)("div",{className:a().exampleLabel,children:"â
Firmware .gitignore"}),(0,n.jsx)("pre",{children:(0,n.jsx)("code",{children:"# Build outputs\nbuild/\n*.bin\n*.hex\n*.elf\n*.map\n\n# IDE files\n.vscode/\n.idea/\n*.code-workspace\n\n# OS files\n.DS_Store\
1nThumbs.db\n\n# Temporary files\n*.tmp\n*.log\n*.swp\n\n# Secrets\nsecrets.h\nconfig_local.h\n*.key\n*.pem"})})]})]}),(0,n.jsxs)("section",{id:"security",children:[(0,n.jsx)("h2",{children:"8. Security & Access Matrix"}),(0,n.jsxs)("table",{className:a().accessMatrix,children:[(0,n.jsx)("thead",{children:(0,n.jsxs)("tr",{children:[(0,n.jsx)("th",{children:"Role"}),(0,n.jsx)("th",{children:"Create Repos"}),(0,n.jsx)("th",{children:"Merge to Dev"}),(0,n.jsx)("th",{children:"Merge to Staging"}),(0,n.jsx)("th",{children:"Merge to Production"}),(0,n.jsx)("th",{children:"Tag Releases"}),(0,n.jsx)("th",{children:"Manage Access"})]})}),(0,n.jsxs)("tbody",{children:[(0,n.jsxs)("tr",{children:[(0,n.jsx)("td",{children:(0,n.jsx)("strong",{children:"Admin"})}),(0,n.jsx)("td",{className:a().allowed,children:"â
"}),(0,n.jsx)("td",{className:a().warning,children:"â ï¸"}),(0,n.jsx)("td",{className:a().allowed,children:"â
"}),(0,n.jsx)("td",{className:a().allowed,children:"â
"}),(0,n.jsx)("td",{className:a().allowed,children:"â
"}),(0,n.jsx)("td",{className:a().allowed,children:"â
"})]}),(0,n.jsxs)("tr",{children:[(0,n.jsx)("td",{children:(0,n.jsx)("strong",{children:"Manager"})}),(0,n.jsx)("td",{className:a().denied,children:"â"}),(0,n.jsx)("td",{className:a().allowed,children:"â
"}),(0,n.jsx)("td",{className:a().allowed,children:"â
"}),(0,n.jsx)("td",{className:a().warning,children:"â
(with Admin)"}),(0,n.jsx)("td",{className:a().allowed,children:"â
"}),(0,n.jsx)("td",{className:a().denied,children:"â"})]}),(0,n.jsxs)("tr",{children:[(0,n.jsx)("td",{children:(0,n.jsx)("strong",{children:"Developer"})}),(0,n.jsx)("td",{className:a().denied,children:"â"}),(0,n.jsx)("td",{className:a().warning,children:"â
(via PR)"}),(0,n.jsx)("td",{className:a().denied,children:"â"}),(0,n.jsx)("td",{className:a().denied,children:"â"}),(0,n.jsx)("td",{className:a().denied,children:"â"}),(0,n.jsx)("td",{className:a().denied,children:"â"})]})]})]}),(0,n.jsx)("h3",{children:"Security Best Practices"}),(0,n.jsxs)("div",{className:a().securityList,children:[(0,n.jsxs)("div",{className:a().securityItem,children:[(0,n.jsx)("span",{className:a().secIcon,children:"\uD83D\uDD10"}),(0,n.jsxs)("div",{children:[(0,n.jsx)("strong",{children:"Enable 2FA"}),(0,n.jsx)("p",{children:"Require two-factor authentication for all team members"})]})]}),(0,n.jsxs)("div",{className:a().securityItem,children:[(0,n.jsx)("span",{className:a().secIcon,children:"âï¸"}),(0,n.jsxs)("div",{children:[(0,n.jsx)("strong",{children:"Signed Commits"}),(0,n.jsx)("p",{children:"Use GPG signing to verify commit authenticity"})]})]}),(0,n.jsxs)("div",{className:a().securityItem,children:[(0,n.jsx)("span",{className:a().secIcon,children:"\uD83D\uDD12"}),(0,n.jsxs)("div",{children:[(0,n.jsx)("strong",{children:"No Secrets in Repos"}),(0,n.jsx)("p",{children:"Use environment variables or secret management tools"})]})]}),(0,n.jsxs)("div",{className:a().securityItem,children:[(0,n.jsx)("span",{className:a().secIcon,children:"\uD83D\uDEE1ï¸"}),(0,n.jsxs)("div",{children:[(0,n.jsx)("strong",{children:"Branch Protection Rules"}),(0,n.jsx)("p",{children:"Require PR reviews, passing CI, and up-to-date branches"})]})]})]})]}),(0,n.jsxs)("div",{className:a().quickReference,children:[(0,n.jsx)("h3",{children:"\uD83C\uDFAF Quick Reference: Developer Daily Workflow"}),(0,n.jsxs)("div",{className:a().workflowSteps,children:[(0,n.jsxs)("div",{className:a().workflowStep,children:[(0,n.jsx)("div",{className:a().stepNum,children:"1"}),(0,n.jsx)("strong",{children:"Start Day"}),(0,n.jsx)("code",{children:"git pull origin development"})]}),(0,n.jsxs)("div",{className:a().workflowStep,children:[(0,n.jsx)("div",{className:a().stepNum,children:"2"}),(0,n.jsx)("strong",{children:"Create Branch"}),(0,n.jsx)("code",{children:"git checkout -b feature/my-work"})]}),(0,n.jsxs)("div",{className:a().workflowStep,children:[(0,n.jsx)("div",{className:a().stepNum,children:"3"}),(0,n.jsx)("strong",{children:"Develop"}),(0,n.jsx)("code",{children:'git add . && git commit -m "message"'})]}),(0,n.jsxs)("div",{className:a().workflowStep,children:[(0,n.jsx)("div",{className:a().stepNum,children:"4"}),(0,n.jsx)("strong",{children:"Stay Updated"}),(0,n.jsx)("code",{children:"git merge origin/development"})]}),(0,n.jsxs)("div",{className:a().workflowStep,children:[(0,n.jsx)("div",{className:a().stepNum,children:"5"}),(0,n.jsx)("strong",{children:"Push & PR"}),(0,n.jsx)("code",{children:"git push -u origin feature/my-work"})]})]})]}),(0,n.jsxs)("div",{className:a().docFooter,children:[(0,n.jsx)("a",{href:"/docs",className:a().backButton,children:"â Back to Documentation"}),(0,n.jsxs)("div",{className:a().footerLinks,children:[(0,n.jsx)("a",{href:"/docs/firmware-style-guide",children:"Firmware Guide â"}),(0,n.jsx)("a",{href:"/docs/project-development",children:"Project Development â"})]})]})]})]})})}t.Z.registerLanguage("bash",d.Z)},7289:function(e){e.exports={docPage:"DocPage_docPage__Qdsb4",breadcrumb:"DocPage_breadcrumb__J54Sd",separator:"DocPage_separator__RKcGr",docHeader:"DocPage_docHeader__Y5C98",docIcon:"DocPage_docIcon__jns7y",docTitle:"DocPage_docTitle__K2QE1",docSubtitle:"DocPage_docSubtitle__jvYcE",tableOfContents:"DocPage_tableOfContents__lTOVr",docContent:"DocPage_docContent___JVCh",fadeIn:"DocPage_fadeIn__oCpdc",example:"DocPage_example__iWkJJ",exampleLabel:"DocPage_exampleLabel___BUAw",bad:"DocPage_bad__SUOUD",tipBox:"DocPage_tipBox__pivBg",phaseCard:"DocPage_phaseCard__xDbAh",timeline:"DocPage_timeline__cVOtJ",timelineItem:"DocPage_timelineItem__Xh2OD",timelineIcon:"DocPage_timelineIcon__n5z4u",architectureBox:"DocPage_architectureBox__oZO9i",componentsTable:"DocPage_componentsTable__4evXF",commandList:"DocPage_commandList__XMqKF",commandItem:"DocPage_commandItem__E0Fki",practiceList:"DocPage_practiceList___jCBW",practiceItem:"DocPage_practiceItem__aeeTC",practiceIcon:"DocPage_practiceIcon___T55f",processSteps:"DocPage_processSteps__8NKDu",processStep:"DocPage_processStep__8iOC8",stepNumber:"DocPage_stepNumber__bcwDY",testingGrid:"DocPage_testingGrid__fy0DQ",testCard:"DocPage_testCard__2m3Iz",checklist:"DocPage_checklist__eo9ry",checklistItem:"DocPage_checklistItem__g3gi5",versionBox:"DocPage_versionBox__j_3MR",docTypes:"DocPage_docTypes__ysoJy",docTypeCard:"DocPage_docTypeCard__t_fUt",quickReference:"DocPage_quickReference__2Ob7N",lifecycle:"DocPage_lifecycle__o1Jn7",lifecycleStep:"DocPage_lifecycleStep___Hfxq",arrow:"DocPage_arrow__GyFWa",docFooter:"DocPage_docFooter__OKnmC",backButton:"DocPage_backButton___9nTA",footerLinks:"DocPage_footerLinks__o2_Ky",sourceReference:"DocPage_sourceReference__QYJC7",spaceRules:"DocPage_spaceRules__7dH9F",ruleItem:"DocPage_ruleItem__INlCN",ruleIcon:"DocPage_ruleIcon__rBXja",namingGrid:"DocPage_namingGrid__4MvtC",namingCard:"DocPage_namingCard__AqJ33",returnConvention:"DocPage_returnConvention__4FOYH",returnItem:"DocPage_returnItem__KXs5c",returnValue:"DocPage_returnValue__e7L7Z",success:"DocPage_success__gsx4s",failure:"DocPage_failure__4RupB",guidelineList:"DocPage_guidelineList__9DhBd",guidelineItem:"DocPage_guidelineItem__FrM0w",guidelineIcon:"DocPage_guidelineIcon__F7mso",includeOrder:"DocPage_includeOrder__5IIXw",includeStep:"DocPage_includeStep__U9lrM",stepNum:"DocPage_stepNum__bf5yp",referenceList:"DocPage_referenceList__bZvf1",referenceLink:"DocPage_referenceLink__nG0Ym",refIcon:"DocPage_refIcon__BlaPa",checklistGrid:"DocPage_checklistGrid__w3i2R",checkItem:"DocPage_checkItem__wAwsr",flowDiagram:"DocPage_flowDiagram__q8lq_",branchingRules:"DocPage_branchingRules__LQ8s0",warningBox:"DocPage_warningBox__xr7zI",rolesGrid:"DocPage_rolesGrid__7b28v",roleCard:"DocPage_roleCard__n3q8k",roleAdmin:"DocPage_roleAdmin__ng1_L",roleManager:"DocPage_roleManager__cya5o",roleDeveloper:"DocPage_roleDeveloper__mFzHr",roleDescription:"DocPage_roleDescription__MTUpm",responsibilities:"DocPage_responsibilities___sap8",accessMatrix:"DocPage_accessMatrix__o6_Sv",allowed:"DocPage_allowed__3ZEkk",denied:"DocPage_denied__CBXX3",warning:"DocPage_warning__oYMcS",securityList:"DocPage_securityList__DoI2m",securityItem:"DocPage_securityItem__47lG9",secIcon:"DocPage_secIcon__23LMY",versionExample:"DocPage_versionExample__H4_5K",versionNumber:"DocPage_versionNumber__Do4Rl",versionBreakdown:"DocPage_versionBreakdown__2q7rk",ver
1sionPart:"DocPage_versionPart__i0fD8",workflowSteps:"DocPage_workflowSteps__Ljrx5",workflowStep:"DocPage_workflowStep__ZqtK5",dontItem:"DocPage_dontItem__yB1e_"}},6167:function(e,s,i){"use strict";function n(e){let s=e.regex,i={};Object.assign(i,{className:"variable",variants:[{begin:s.concat(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},{begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[i]}]}]});let n={className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},c=e.inherit(e.COMMENT(),{match:[/(^|\s)/,/#.*$/],scope:{2:"comment"}}),r={begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,className:"string"})]}},l={className:"string",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,i,n]};n.contains.push(l);let a={begin:/\$?\(\(/,end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,i]},t=e.SHEBANG({binary:"(fish|bash|zsh|sh|csh|ksh|tcsh|dash|scsh)",relevance:10}),d={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{name:"Bash",aliases:["sh","zsh"],keywords:{$pattern:/\b[a-z][a-z0-9._-]+\b/,keyword:["if","then","else","elif","fi","time","for","while","until","in","do","done","case","esac","coproc","function","select"],literal:["true","false"],built_in:["break","cd","continue","eval","exec","exit","export","getopts","hash","pwd","readonly","return","shift","test","times","trap","umask","unset","alias","bind","builtin","caller","command","declare","echo","enable","help","let","local","logout","mapfile","printf","read","readarray","source","sudo","type","typeset","ulimit","unalias","set","shopt","autoload","bg","bindkey","bye","cap","chdir","clone","comparguments","compcall","compctl","compdescribe","compfiles","compgroups","compquote","comptags","comptry","compvalues","dirs","disable","disown","echotc","echoti","emulate","fc","fg","float","functions","getcap","getln","history","integer","jobs","kill","limit","log","noglob","popd","print","pushd","pushln","rehash","sched","setcap","setopt","stat","suspend","ttyctl","unfunction","unhash","unlimit","unsetopt","vared","wait","whence","where","which","zcompile","zformat","zftp","zle","zmodload","zparseopts","zprof","zpty","zregexparse","zsocket","zstyle","ztcp","chcon","chgrp","chown","chmod","cp","dd","df","dir","dircolors","ln","ls","mkdir","mkfifo","mknod","mktemp","mv","realpath","rm","rmdir","shred","sync","touch","truncate","vdir","b2sum","base32","base64","cat","cksum","comm","csplit","cut","expand","fmt","fold","head","join","md5sum","nl","numfmt","od","paste","ptx","pr","sha1sum","sha224sum","sha256sum","sha384sum","sha512sum","shuf","sort","split","sum","tac","tail","tr","tsort","unexpand","uniq","wc","arch","basename","chroot","date","dirname","du","echo","env","expr","factor","groups","hostid","id","link","logname","nice","nohup","nproc","pathchk","pinky","printenv","printf","pwd","readlink","runcon","seq","sleep","stat","stdbuf","stty","tee","test","timeout","tty","uname","unlink","uptime","users","who","whoami","yes"]},contains:[t,e.SHEBANG(),d,a,c,r,{match:/(\/[a-z._-]+)+/},l,{match:/\\"/},{className:"string",begin:/'/,end:/'/},{match:/\\'/},i]}}i.d(s,{Z:function(){return n}})}},function(e){e.O(0,[632,666,95,888,774,179],function(){return e(e.s=2346)}),_N_E=e.O()}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.