Free lesson · LLMOps Engineering
AI ಪ್ರಾಜೆಕ್ಟ್ಗಳಿಗಾಗಿ trunk-based development ಅನ್ನು ಅಳವಡಿಸಿ
GKE ಮೇಲಿನ AI/ML ಪ್ರಾಜೆಕ್ಟ್ಗಳಿಗಾಗಿ ಅತ್ಯುತ್ತಮಗೊಳಿಸಿದ Git branching ತಂತ್ರವನ್ನು ನೀವು ಸ್ಥಾಪಿಸುತ್ತೀರಿ. main ಯಾವಾಗಲೂ deploy ಮಾಡಬಹುದಾದ ಸ್ಥಿತಿಯಲ್ಲಿರುವ trunk-based workflow ಅನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಿ. ಹೆಸರಿಸುವ ಸಂಪ್ರದಾಯಗಳೊಂದಿಗೆ ಅಲ್ಪಾವಧಿಯ feature branchಗಳನ್ನು ರಚಿಸಿ: feature/add-prompt-template, fix/embedding-pipeline, config/model-parameters. Branch ಜೀವನಚಕ್ರವನ್ನು ಅಳವಡಿಸಿ: main ನಿಂದ ರಚಿಸಿ, commitಗಳನ್ನು push ಮಾಡಿ, PR ತೆರೆಯಿರಿ, main ಗೆ ಮರಳಿ squash merge ಮಾಡಿ, branch ಅನ್ನು ಅಳಿಸಿ. ಡೀಫಾಲ್ಟ್ ಆಗಿ rebase ಬಳಸುವಂತೆ git ಅನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಿ (git config pull.rebase true). Prompt template ಬದಲಾವಣೆಯೊಂದಿಗೆ workflow ಅನ್ನು ಆರಂಭದಿಂದ ಕೊನೆಯವರೆಗೆ ಪ್ರದರ್ಶಿಸಿ.
Course: DevOps Foundations for GenAI Engineers · Chapter 1 · Git Workflows for AI Teams
Free to read — no subscription required.
ಪರಿಚಯ
ಒಂದು ವಾರದವರೆಗೆ ಡ್ರಿಫ್ಟ್ ಆಗುವ ಫೀಚರ್ ಬ್ರಾಂಚ್ಗಳಿಂದ ನೀವು ಪ್ರಾಂಪ್ಟ್ಗಳು, ಟ್ರೇನಿಂಗ್ JSONL ಮತ್ತು ಮಾಡೆಲ್ ಕಾನ್ಫಿಗ್ಗಳನ್ನು ಶಿಪ್ ಮಾಡಿದಾಗ, ಒಂದೇ ಫೈಲ್ಗೆ ಟ್ರೇನಿಂಗ್ ಸಾಲುಗಳನ್ನು ಸೇರಿಸಿದ ಅಥವಾ ವಿಭಿನ್ನ ಬ್ರಾಂಚ್ಗಳಲ್ಲಿ ಒಂದೇ ಪ್ರಾಂಪ್ಟ್ ಆವೃತ್ತಿಯನ್ನು ಬದಲಾಯಿಸಿದ ಇಬ್ಬರು ಇಂಜಿನಿಯರ್ಗಳ ಕೆಲಸವನ್ನು Git ಸಮನ್ವಯಗೊಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ ಎಂದು ಮರ್ಜ್ ಸಮಯದಲ್ಲಿ ನೀವು ಕಂಡುಕೊಳ್ಳುತ್ತೀರಿ. ಈ ಕಾನ್ಫ್ಲಿಕ್ಟ್ ಮೇಲ್ಮೈ ಮರ್ಜ್ ಮಾಡಲಾಗದಂತಹದ್ದು: ಪ್ರತಿ JSONL ಸಾಲೂ ಅರ್ಥದ ದೃಷ್ಟಿಯಿಂದ ಸ್ವತಂತ್ರವಾಗಿದೆ, ಮತ್ತು prompt registry ನಮೂದುಗಳು ಒಂದು ನಿರ್ದಿಷ್ಟ ಕ್ಷಣದ ಸತ್ಯಾಂಶಗಳು, ಮೂರು-ಮಾರ್ಗದ ಮರ್ಜ್ ಮಾಡಬಹುದಾದ ಪಠ್ಯವಲ್ಲ. ಬ್ರಾಂಚ್ಗಳನ್ನು 48 ಗಂಟೆಗಳನ್ನು ಮೀರಿ ಹಳೆಯದಾಗಲು ಬಿಡುವ ತಂಡಗಳು ಕಳೆದುಹೋದ ಸ್ಪ್ರಿಂಟ್ ದಿನಗಳು ಮತ್ತು ಕೆಟ್ಟ ಮರ್ಜ್ಗಳ ನಂತರ eval ಸ್ಕೋರ್ಗಳಲ್ಲಿ ಮೌನ ಹಿಂಜರಿತಗಳ (regressions) ರೂಪದಲ್ಲಿ ಈ ಬೆಲೆಯನ್ನು ತೆರುತ್ತವೆ.
ಈ ಪಾಠದ ಅಂತ್ಯದ ವೇಳೆಗೆ ನೀವು AI ಕೋಡ್ಬೇಸ್ನ ಮೇಲೆ ಟ್ರಂಕ್-ಆಧಾರಿತ ಶಿಸ್ತನ್ನು ಜಾರಿಗೊಳಿಸಲು ಸಮರ್ಥರಾಗುತ್ತೀರಿ: ಉದ್ದೇಶದ ಪ್ರಕಾರ ಬ್ರಾಂಚ್ಗಳಿಗೆ ಹೆಸರಿಡುವುದು (feat, data, fix, infra, deps), Git ಹುಕ್ ಮೂಲಕ ಪುಶ್ ಸಮಯದಲ್ಲಿ ಹೆಸರುಗಳು ಮತ್ತು ವಯಸ್ಸನ್ನು ಪರಿಶೀಲಿಸುವುದು, ಮತ್ತು ಪ್ರಾಂಪ್ಟ್ ಹಾಗೂ ಡೇಟಾ ಬದಲಾವಣೆಗಳು ಅಟಾಮಿಕ್ ಮತ್ತು bisect ಮಾಡಬಹುದಾದಂತೆ ಉಳಿಯಲು ಬ್ರಾಂಚ್ ಪ್ರಕಾರಕ್ಕೆ ಅನುಗುಣವಾಗಿ ಮರ್ಜ್ ಸ್ಟ್ರಾಟಜಿಯನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡುವುದು.
ಪ್ರಮುಖ ಪರಿಭಾಷೆ
- Trunk — ಯಾವಾಗಲೂ ಡಿಪ್ಲಾಯ್ ಮಾಡಬಹುದಾದ ಏಕೈಕ ಹಂಚಿಕೆಯ ಬ್ರಾಂಚ್ (ಸಾಮಾನ್ಯವಾಗಿ main); ಪ್ರತಿ ಕಮಿಟ್ ಸ್ಕೀಮಾ, ಮೌಲ್ಯಮಾಪನ ಮತ್ತು ಇನ್ಫ್ರಾಸ್ಟ್ರಕ್ಚರ್ ಪರಿಶೀಲನೆಯನ್ನು ಪ್ರಚೋದಿಸುತ್ತದೆ, ಆದ್ದರಿಂದ ಪ್ರಾಂಪ್ಟ್ಗಳು, ಮಾಡೆಲ್ಗಳು ಮತ್ತು ಕಾನ್ಫಿಗ್ಗಳಿಗೆ trunk ಸತ್ಯದ ಮೂಲವಾಗಿದೆ.
- Short-lived feature branch — trunk ಗೆ ಮರಳಿ ಮರ್ಜ್ ಆಗುವ ಮೊದಲು ಗರಿಷ್ಠ 48 ಗಂಟೆಗಳವರೆಗೆ ಮಾತ್ರ ಬದುಕುವ ಬ್ರಾಂಚ್; ಈ ಸಮಯದ ಮಿತಿಯೇ ಪ್ರಾಂಪ್ಟ್ ಮತ್ತು JSONL ಡ್ರಿಫ್ಟ್ನ್ನು ಯಾಂತ್ರಿಕವಾಗಿ ಪರಿಹರಿಸಬಹುದಾದಷ್ಟು ಚಿಕ್ಕದಾಗಿ ಇಡುತ್ತದೆ.
- Squash merge — ಫೀಚರ್ ಬ್ರಾಂಚ್ನಲ್ಲಿರುವ ಪ್ರತಿ ಕಮಿಟ್ನ್ನು trunk ಮೇಲೆ ಒಂದೇ ಅಟಾಮಿಕ್ ಕಮಿಟ್ ಆಗಿ ಕುಗ್ಗಿಸುತ್ತದೆ, ಇದರಿಂದ git bisect WIP ಸೇವ್ಗಳ ಬದಲು "add summarization prompt v3" ನಂತಹ ಅರ್ಥಪೂರ್ಣ ಘಟಕಗಳ ಮೇಲೆ ಇಳಿಯುತ್ತದೆ.
- Branch protection rule — ರಿಮೋಟ್ನಲ್ಲಿ (GitHub/GitLab) ಇರುವ ಸರ್ವರ್-ಸೈಡ್ ನೀತಿ, ಇದು ಬ್ರಾಂಚ್ ಪ್ಯಾಟರ್ನ್ಗೆ ಅನುಗುಣವಾಗಿ ಅಗತ್ಯ ಚೆಕ್ಗಳು ಮತ್ತು ಮರ್ಜ್ ಸ್ಟ್ರಾಟಜಿಯ ಮೇಲೆ ಮರ್ಜ್ಗಳನ್ನು ನಿಯಂತ್ರಿಸುತ್ತದೆ, ಆದ್ದರಿಂದ ಲೋಕಲ್ ಹುಕ್ನ್ನು ಬೈಪಾಸ್ ಮಾಡಿದಾಗಲೂ ನೀತಿ ಜಾರಿಯಲ್ಲಿರುತ್ತದೆ.
- Prompt registry — trunk ನಲ್ಲಿ ಟ್ರ್ಯಾಕ್ ಮಾಡಲಾದ JSON ಫೈಲ್ (ಉದಾ. prompt_registry.json), ಇದು ಪ್ರಾಂಪ್ಟ್ ID ಗಳನ್ನು ಆವೃತ್ತಿ ಸಂಖ್ಯೆಗಳು ಮತ್ತು ಫೈಲ್ ಪಥಗಳಿಗೆ ಮ್ಯಾಪ್ ಮಾಡುತ್ತದೆ; "ಪ್ರತಿ ಬ್ರಾಂಚ್ಗೆ ಒಂದೇ ಆವೃತ್ತಿ ಬದಲಾವಣೆ" ಎಂಬ ನಿಯಮವು ಹಿಂಜರಿತಗಳನ್ನು ಸುಲಭವಾಗಿ ಗುರುತಿಸುವಂತೆ ಮಾಡುತ್ತದೆ.
ಪರಿಕಲ್ಪನೆಗಳು
ಇಂಟಿಗ್ರೇಷನ್ನ್ನು ನಿರಂತರವಾಗಿ ಮತ್ತು ಪ್ರಾಂಪ್ಟ್/ಡೇಟಾ ಬದಲಾವಣೆಗಳನ್ನು ಅಟಾಮಿಕ್ ಆಗಿ ಮಾಡುವುದು ಗುರಿ. ಅಲ್ಲಿಗೆ ತಲುಪಲು ಮೂರು ಆಲೋಚನೆಗಳು ಒಟ್ಟುಗೂಡುತ್ತವೆ: ಉದ್ದೇಶವನ್ನು ಎನ್ಕೋಡ್ ಮಾಡುವ ಬ್ರಾಂಚ್ ವರ್ಗೀಕರಣ, ಡ್ರಿಫ್ಟ್ನ್ನು ಮಿತಿಗೊಳಿಸುವ 48-ಗಂಟೆಗಳ ಜೀವಿತಾವಧಿ, ಮತ್ತು ಆಡಿಟ್ ಸಾಮರ್ಥ್ಯವನ್ನು ಕಾಪಾಡುವ ವರ್ಗ-ಆಧಾರಿತ ಮರ್ಜ್ ಸ್ಟ್ರಾಟಜಿ. ಈ ಆಲೋಚನೆಗಳನ್ನು ಕಾರ್ಯರೂಪಕ್ಕೆ ತರುವ ಬ್ರಾಂಚ್ ವ್ಯಾಲಿಡೇಟರ್ ಮತ್ತು pre-push ಹುಕ್ನ್ನು ಕೋಡ್ನಲ್ಲಿ ಪ್ರದರ್ಶಿಸಲಾಗಿದೆ (ಕೋಡ್ ವಾಕ್ಥ್ರೂ ನೋಡಿ).
AI ಕೋಡ್ಬೇಸ್ಗಳಿಗೆ ಅಲ್ಪಾವಧಿಯ ಬ್ರಾಂಚ್ಗಳು ಏಕೆ ಮುಖ್ಯ
AI ರೆಪೊಸಿಟರಿಗಳು ದೀರ್ಘಾವಧಿಯ ಬ್ರಾಂಚ್ಗಳನ್ನು ಮುರಿಯುವ ಮೂರು ವರ್ಗದ ಆರ್ಟಿಫ್ಯಾಕ್ಟ್ಗಳನ್ನು ಹೊಂದಿರುತ್ತವೆ. ಪ್ರಾಂಪ್ಟ್ ಮತ್ತು ಕಾನ್ಫಿಗ್ ಫೈಲ್ಗಳು ಹಂಚಿಕೆಯ ಬ್ಲಾಕ್ಗಳಾಗಿದ್ದು, ಸಮಾನಾಂತರ ಎಡಿಟ್ಗಳು ಇಲ್ಲಿ ಘರ್ಷಿಸುತ್ತವೆ. JSONL ಟ್ರೇನಿಂಗ್ ಫೈಲ್ಗಳು ಸೇರ್ಪಡೆಯಿಂದ (append) ಬೆಳೆಯುತ್ತವೆ, ಮತ್ತು ವಿಭಿನ್ನ ಸಾಲುಗಳನ್ನು ಸೇರಿಸುವ ಎರಡು ಬ್ರಾಂಚ್ಗಳು Git ಗುರುತಿಸುವ ಆದರೆ ಸರಿಯಾಗಿ ಪರಿಹರಿಸಲಾಗದ ಅತಿಕ್ರಮಿಸುವ ಡಿಫ್ಗಳನ್ನು ಉತ್ಪಾದಿಸುತ್ತವೆ — ಪುನರುತ್ಪಾದನೆಗೆ ಸಾಲುಗಳ ಕ್ರಮ ಮುಖ್ಯ. ಅವಲಂಬನೆ ಗ್ರಾಫ್ಗಳು ದಟ್ಟವಾಗಿವೆ: ಸರ್ವಿಂಗ್ ಕಾನ್ಫಿಗ್ ಪ್ರೀಪ್ರೊಸೆಸಿಂಗ್ ಮೇಲೆ ಅವಲಂಬಿತ, ಅದು ಫೀಚರ್-ಸ್ಟೋರ್ ಸ್ಕೀಮಾದ ಮೇಲೆ ಅವಲಂಬಿತ, ಆದ್ದರಿಂದ ಈ ಮೂರರಲ್ಲಿ ಯಾವುದಾದರೂ ಪ್ರತ್ಯೇಕವಾಗಿ ವಿಕಸನಗೊಂಡರೆ ನೋವಿನ rebase ಖಚಿತ.
ಬ್ರಾಂಚ್ ಜೀವಿತಾವಧಿಯನ್ನು 48 ಗಂಟೆಗಳಿಗೆ ಸೀಮಿತಗೊಳಿಸುವುದು ಕಾನ್ಫ್ಲಿಕ್ಟ್ ವಿಂಡೋವನ್ನು ಕುಗ್ಗಿಸುತ್ತದೆ. ಪ್ರಗತಿಯಲ್ಲಿರುವ ಕೆಲಸವು ನಿಲ್ಲಿಸಿದ ಬ್ರಾಂಚ್ಗಳ ಬದಲು trunk ನಲ್ಲಿ ಫೀಚರ್ ಫ್ಲ್ಯಾಗ್ಗಳ ಹಿಂದೆ ಇರುತ್ತದೆ. Renovate ಮತ್ತು Dependabot PR ಗಳು ಸ್ವಚ್ಛವಾಗಿ ಇಳಿಯುತ್ತವೆ, ಏಕೆಂದರೆ ಅವು ಅನ್ವಯವಾಗುವ ಮೊದಲು ಆಳವಾದ rebase ಅಗತ್ಯವಿರುವಷ್ಟು ಹಳೆಯದಾದ ಯಾವುದೇ ಮಾನವ ಬ್ರಾಂಚ್ ಇರುವುದಿಲ್ಲ.
ಬ್ರಾಂಚ್ ವರ್ಗೀಕರಣವು ಉದ್ದೇಶವನ್ನು ಎನ್ಕೋಡ್ ಮಾಡುತ್ತದೆ
ಹೆಸರಿಸುವ ಸಂಪ್ರದಾಯವು ಬ್ರಾಂಚ್ ಹೆಸರುಗಳನ್ನು ಹುಕ್ಗಳು ಮತ್ತು CI ಗಾಗಿ ರೂಟ್ ಮಾಡಬಹುದಾದ ಮೆಟಾಡೇಟಾ ಆಗಿ ಪರಿವರ್ತಿಸುತ್ತದೆ. ಪ್ರತಿ ಬ್ರಾಂಚ್ ಪ್ರಕಾರವು ಬೇರೆ ಬೇರೆ ವ್ಯಾಲಿಡೇಷನ್ ಲೇನ್ನ್ನು ಪ್ರಚೋದಿಸುತ್ತದೆ: feat/prompt-* eval ಸೂಟ್ಗಳನ್ನು ಓಡಿಸುತ್ತದೆ, data/* ಸ್ಕೀಮಾ ಮತ್ತು ಸಾಲು-ಎಣಿಕೆ ಚೆಕ್ಗಳನ್ನು ಓಡಿಸುತ್ತದೆ, fix/* ಪೂರ್ಣ ರಿಗ್ರೆಷನ್ ಓಡಿಸುತ್ತದೆ, infra/* IaC plan/apply ಓಡಿಸುತ್ತದೆ, deps/* ಬಿಲ್ಡ್ + ಅವಲಂಬನೆ ಆಡಿಟ್ ಓಡಿಸುತ್ತದೆ.
ಮೂರು ಅಲ್ಪಾವಧಿಯ ಬ್ರಾಂಚ್ಗಳು ಒಂದೇ ಸ್ಪ್ರಿಂಟ್ ಚಕ್ರದೊಳಗೆ trunk ಗೆ ಮರಳಿ ಮರ್ಜ್ ಆಗುತ್ತವೆ. ಯಾವುದೇ ಬ್ರಾಂಚ್ ಮತ್ತೊಂದರೊಂದಿಗೆ ಒಂದು ಕೆಲಸದ ದಿನವನ್ನು ಮೀರಿ ಸಹ-ಅಸ್ತಿತ್ವದಲ್ಲಿರುವುದಿಲ್ಲ, ಇದೇ JSONL ಮತ್ತು ಪ್ರಾಂಪ್ಟ್ ಫೈಲ್ಗಳಲ್ಲಿ ನೋವಿನ ಮರ್ಜ್ ಕಾನ್ಫ್ಲಿಕ್ಟ್ಗಳನ್ನು ಉಂಟುಮಾಡುವ ಡ್ರಿಫ್ಟ್ನ್ನು ತಡೆಯುತ್ತದೆ.
Squash merge ಮತ್ತು merge commit ನಡುವಿನ ವ್ಯತ್ಯಾಸ
feat, data, fix ಮತ್ತು infra ಬ್ರಾಂಚ್ಗಳಿಗೆ squash merge ಡೀಫಾಲ್ಟ್ ಆಗಿದೆ, ಏಕೆಂದರೆ trunk ಅಟಾಮಿಕ್, bisect ಮಾಡಬಹುದಾದ ಬದಲಾವಣೆಗಳ ಸರಣಿಯಂತೆ ಓದಬೇಕು — "add summarization prompt v3" ಆಗಿರಬೇಕು, "wip" → "fix typo" → "actually fix it" ಆಗಿರಬಾರದು. deps/* ಅಡಿಯಲ್ಲಿರುವ ಬ್ರಾಂಚ್ಗಳು ಸ್ಪಷ್ಟ ವಿನಾಯಿತಿ: Renovate ಮತ್ತು Dependabot ಕಮಿಟ್ ಸಂದೇಶಗಳಲ್ಲಿ ರಚನಾತ್ಮಕ changelog ಮೆಟಾಡೇಟಾವನ್ನು (ಪ್ಯಾಕೇಜ್ ಹೆಸರು, ಆವೃತ್ತಿ ಶ್ರೇಣಿ, changelog URL) ಹುದುಗಿಸುತ್ತವೆ, ಅದನ್ನು ಡೌನ್ಸ್ಟ್ರೀಮ್ ಆಡಿಟ್ ಟೂಲಿಂಗ್ ಪಾರ್ಸ್ ಮಾಡುತ್ತದೆ, ಆದ್ದರಿಂದ ಆ ಬ್ರಾಂಚ್ಗಳು ನಿಜವಾದ merge commit ನೊಂದಿಗೆ ಮರ್ಜ್ ಆಗುತ್ತವೆ. ಮೊದಲ ನಾಲ್ಕು ಪ್ರಿಫಿಕ್ಸ್ಗಳಿಗೆ squash ಅಗತ್ಯವಾಗಿರುವಂತೆ ಮತ್ತು deps/* ಗೆ ಮಾತ್ರ merge commit ಗಳನ್ನು ಅನುಮತಿಸುವಂತೆ branch protection ಕಾನ್ಫಿಗರ್ ಮಾಡಿ.
ಪ್ರತಿ ಬ್ರಾಂಚ್ಗೆ ಒಂದೇ ಪ್ರಾಂಪ್ಟ್ ಬದಲಾವಣೆ
ಪ್ರತಿ ಫೀಚರ್ ಬ್ರಾಂಚ್ prompt_registry.json ನಲ್ಲಿ ನಿಖರವಾಗಿ ಒಂದು ಪ್ರಾಂಪ್ಟ್ ಆವೃತ್ತಿಯನ್ನು ಹೆಚ್ಚಿಸುತ್ತದೆ ಮತ್ತು ಅದರೊಂದಿಗೆ ತನ್ನ eval ಫಲಿತಾಂಶಗಳನ್ನು ಶಿಪ್ ಮಾಡುತ್ತದೆ. ಬ್ರಾಂಚ್ಗಳು ಚಿಕ್ಕವು ಮತ್ತು ವ್ಯಾಪ್ತಿ ಬಿಗಿಯಾಗಿರುವುದರಿಂದ, registry ಕಾನ್ಫ್ಲಿಕ್ಟ್ಗಳು ವಿಭಿನ್ನ ಕೀಗಳ ಮೇಲಿನ ಏಕಕಾಲಿಕ ಹೆಚ್ಚಳಗಳಿಗೆ ಸೀಮಿತವಾಗುತ್ತವೆ — 30-ಸೆಕೆಂಡಿನ ಸಮನ್ವಯ, ಅರ್ಧ-ದಿನದ ತನಿಖೆಯಲ್ಲ. ಡಿಪ್ಲಾಯ್ ನಂತರ eval ಮೆಟ್ರಿಕ್ ಕುಸಿದಾಗ, trunk ಮೇಲಿನ git log --oneline ನಿಖರವಾಗಿ ಒಂದು ಪ್ರಾಂಪ್ಟ್ ಬದಲಾವಣೆಯನ್ನು ತೋರಿಸುತ್ತದೆ.
ಕೋಡ್ ವಾಕ್ಥ್ರೂ
ಕೆಳಗಿನ ಎರಡು ಸ್ನಿಪ್ಪೆಟ್ಗಳು ಪರಿಕಲ್ಪನೆಗಳ ವಿಭಾಗದಿಂದ ಬ್ರಾಂಚ್ ವರ್ಗೀಕರಣ, 48-ಗಂಟೆಗಳ ಜೀವಿತಾವಧಿ ಮತ್ತು ಲೋಕಲ್ ಜಾರಿ ಪದರವನ್ನು ಕಾರ್ಯರೂಪಕ್ಕೆ ತರುತ್ತವೆ. ಮೊದಲನೆಯದು regex ಪ್ಯಾಟರ್ನ್ಗಳು ಮತ್ತು ವಯಸ್ಸಿನ ಚೆಕ್ನೊಂದಿಗೆ ವ್ಯಾಲಿಡೇಟರ್ನ್ನು ವ್ಯಾಖ್ಯಾನಿಸುತ್ತದೆ; ಎರಡನೆಯದು ಅದನ್ನು pre-push ಹುಕ್ಗೆ ಜೋಡಿಸುತ್ತದೆ, ಇದರಿಂದ ಹಳೆಯ ಅಥವಾ ಪ್ಯಾಟರ್ನ್ಗೆ ಹೊರತಾದ ಬ್ರಾಂಚ್ ರಿಮೋಟ್ಗೆ ತಲುಪುವ ಮೊದಲೇ ನೀತಿ ಜಾರಿಯಾಗುತ್ತದೆ.
Code snippetpython
1import re 2import subprocess 3from datetime import datetime, timezone 4from dataclasses import dataclass 5from typing import Optional 6 7BRANCH_PATTERNS = { 8 "feature": re.compile(r"^feat/(prompt|model|pipeline|serve)-[\w-]{3,50}$"), 9 "data": re.compile(r"^data/(training|eval|validation)-[\w-]{3,50}$"), 10 "fix": re.compile(r"^fix/[\w-]{3,50}$"), 11 "infra": re.compile(r"^infra/(gke|helm|terraform)-[\w-]{3,50}$"), 12 "deps": re.compile(r"^deps/(renovate|dependabot)-[\w-]{3,50}$"), 13} 14MAX_BRANCH_AGE_HOURS = 48 15 16@dataclass 17class BranchMetadata: 18 category: str 19 is_valid: bool 20 age_hours: Optional[float] = None 21 is_stale: bool = False 22 23def validate_branch_name(branch: str) -> BranchMetadata: 24 for category, pattern in BRANCH_PATTERNS.items(): 25 if pattern.match(branch): 26 return BranchMetadata(category=category, is_valid=True) 27 return BranchMetadata(category="unknown", is_valid=False) 28 29def get_branch_age_hours(branch: str) -> Optional[float]: 30 result = subprocess.run( 31 ["git", "log", "-1", "--format=%cI", branch], 32 capture_output=True, text=True, 33 ) 34 if result.returncode != 0: 35 return None 36 created = datetime.fromisoformat(result.stdout.strip()) 37 return (datetime.now(timezone.utc) - created).total_seconds() / 3600 38 39def enforce_branch_policy(branch: str) -> BranchMetadata: 40 metadata = validate_branch_name(branch) 41 if not metadata.is_valid: 42 return metadata 43 metadata.age_hours = get_branch_age_hours(branch) 44 if metadata.age_hours is not None and metadata.age_hours > MAX_BRANCH_AGE_HOURS: 45 metadata.is_stale = True 46 return metadata
BRANCH_PATTERNS ಪರಿಕಲ್ಪನೆಗಳ ವಿಭಾಗದ ವರ್ಗೀಕರಣವನ್ನು ಎನ್ಕೋಡ್ ಮಾಡುತ್ತದೆ: ಉಪವರ್ಗ ಟೋಕನ್ಗಳು (prompt, training, gke, ಇತ್ಯಾದಿ) ಇಂಜಿನಿಯರ್ಗಳು ಬ್ರಾಂಚ್ ಹೆಸರಿನಲ್ಲಿ ಉದ್ದೇಶವನ್ನು ಘೋಷಿಸುವಂತೆ ಒತ್ತಾಯಿಸುತ್ತವೆ. MAX_BRANCH_AGE_HOURS = 48 ನೀತಿಯ ನಿಯಂತ್ರಣ ಗುಬ್ಬಿ — ಇದನ್ನು ಹೆಚ್ಚಿಸುವುದು ಅಲ್ಪಾವಧಿಯ ಶಿಸ್ತನ್ನು ಸಡಿಲಗೊಳಿಸುತ್ತದೆ. enforce_branch_policy ಎರಡು ಚೆಕ್ಗಳನ್ನು ಸಂಯೋಜಿಸುತ್ತದೆ; get_branch_age_hours ಬ್ರಾಂಚ್ ತುದಿಯ committer ದಿನಾಂಕವನ್ನು (ISO 8601) ಓದಿ ಗಂಟೆಗಳನ್ನು float ಆಗಿ ಹಿಂತಿರುಗಿಸುತ್ತದೆ, ಮತ್ತು ಬ್ರಾಂಚ್ ಕಾಣೆಯಾಗಿದ್ದರೆ ದೋಷ ಎಸೆಯುವ ಬದಲು None ಹಿಂತಿರುಗಿಸುತ್ತದೆ.
Code snippetpython
1import sys 2import subprocess 3from branch_validator import enforce_branch_policy 4 5def get_current_branch() -> str: 6 result = subprocess.run( 7 ["git", "rev-parse", "--abbrev-ref", "HEAD"], 8 capture_output=True, text=True, 9 ) 10 return result.stdout.strip() 11 12def main() -> int: 13 branch = get_current_branch() 14 if branch == "main": 15 return 0 16 metadata = enforce_branch_policy(branch) 17 if not metadata.is_valid: 18 print(f"ERROR: '{branch}' does not match any allowed pattern.") 19 print("Allowed: feat/(prompt|model|pipeline|serve)-..., data/(training|eval|validation)-...,") 20 print(" fix/..., infra/(gke|helm|terraform)-..., deps/(renovate|dependabot)-...") 21 return 1 22 if metadata.is_stale: 23 print(f"WARNING: '{branch}' is {metadata.age_hours:.1f}h old; merge or delete.") 24 return 1 25 print(f"Branch policy OK: [{metadata.category}] {branch}") 26 return 0 27 28if __name__ == "__main__": 29 sys.exit(main())
ಈ ಹುಕ್ git rev-parse --abbrev-ref HEAD ಮೂಲಕ ಪ್ರಸ್ತುತ ಬ್ರಾಂಚ್ನ್ನು ಗುರುತಿಸುತ್ತದೆ, main ಮೇಲೆ ಶಾರ್ಟ್-ಸರ್ಕ್ಯೂಟ್ ಆಗುತ್ತದೆ ಇದರಿಂದ trunk ಗೆ CI ಮರ್ಜ್ ಕಮಿಟ್ಗಳು ಪ್ರಭಾವಿತವಾಗುವುದಿಲ್ಲ, ಮತ್ತು ಅಮಾನ್ಯ ಹೆಸರುಗಳು ಅಥವಾ ಹಳೆಯ ಬ್ರಾಂಚ್ಗಳು ಎರಡಕ್ಕೂ exit code 1 ಹಿಂತಿರುಗಿಸುತ್ತದೆ. ಇದನ್ನು .git/hooks/pre-push ಆಗಿ (ಅಥವಾ pre-commit ಫ್ರೇಮ್ವರ್ಕ್ನ pre-push ಹಂತದ ಮೂಲಕ) ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿ, ಮತ್ತು feat/*, data/*, fix/*, infra/* ಗೆ squash merge ಅಗತ್ಯವಾಗಿರುವಂತೆ ಹಾಗೂ deps/* ಗೆ ಮಾತ್ರ merge commit ಗಳನ್ನು ಅನುಮತಿಸುವ ಸರ್ವರ್-ಸೈಡ್ branch protection ನಿಯಮಗಳೊಂದಿಗೆ ಜೋಡಿಸಿ.
ಇದು ಕೆಲಸ ಮಾಡುತ್ತಿದೆ ಎಂದು ನಿಮಗೆ ತಿಳಿಯುವುದು ಹೀಗೆ: (1) wip-stuff ಪುಶ್ ಮಾಡಿದಾಗ ಅನುಮತಿಸಿದ ಪ್ಯಾಟರ್ನ್ಗಳ ಸಹಾಯ ಪಠ್ಯದೊಂದಿಗೆ ತಿರಸ್ಕರಿಸಲ್ಪಡುತ್ತದೆ, (2) 50-ಗಂಟೆ ಹಳೆಯ feat/prompt-foo ಪುಶ್ ಮಾಡಿದಾಗ ಗಂಟೆಗಳಲ್ಲಿ ವಯಸ್ಸಿನೊಂದಿಗೆ ತಿರಸ್ಕರಿಸಲ್ಪಡುತ್ತದೆ, (3) ಮಾನ್ಯವಾದ, ತಾಜಾ feat/prompt-foo ಪುಶ್ ಮಾಡಿದಾಗ OK ಸಾಲು ಮುದ್ರಿತವಾಗುತ್ತದೆ, ಮತ್ತು (4) trunk ಮೇಲಿನ prompt_registry.json ಮರ್ಜ್ ಆದ ಪ್ರತಿ ಬ್ರಾಂಚ್ಗೆ ನಿಖರವಾಗಿ ಒಂದು ಆವೃತ್ತಿ ಬದಲಾವಣೆಯನ್ನು ತೋರಿಸುತ್ತದೆ.
ಶಿಸ್ತು ಅನ್ವಯ
ಮಾಡಬೇಕಾದವು ಮತ್ತು ಮಾಡಬಾರದವು
ಮಾಡಬೇಕಾದವು
- feat/data/fix/infra ಬ್ರಾಂಚ್ಗಳನ್ನು squash-merge ಮಾಡಿ — WIP ಕಮಿಟ್ಗಳನ್ನು trunk ಮೇಲೆ ಒಂದೇ bisect ಮಾಡಬಹುದಾದ ಬದಲಾವಣೆಯಾಗಿ ಕುಗ್ಗಿಸುತ್ತದೆ, ಇದರಿಂದ eval ಹಿಂಜರಿತಗಳು ಒಂದೇ ಪ್ರಾಂಪ್ಟ್ ಅಥವಾ ಡೇಟಾ ಬದಲಾವಣೆಯನ್ನು ಸೂಚಿಸುತ್ತವೆ.
- deps/* ಬ್ರಾಂಚ್ಗಳಿಗೆ ಮಾತ್ರ merge commit ಗಳನ್ನು ಅನುಮತಿಸಿ — Renovate ಮತ್ತು Dependabot ಕಮಿಟ್ ಸಂದೇಶಗಳಲ್ಲಿ ಆಡಿಟ್ ಟೂಲಿಂಗ್ ಪಾರ್ಸ್ ಮಾಡುವ ರಚನಾತ್ಮಕ changelog ಮೆಟಾಡೇಟಾವನ್ನು ಹುದುಗಿಸುತ್ತವೆ; squash ಮಾಡುವುದು ಅದನ್ನು ನಾಶಪಡಿಸುತ್ತದೆ.
- ಪ್ರತಿ ಬ್ರಾಂಚ್ಗೆ ನಿಖರವಾಗಿ ಒಂದು ಪ್ರಾಂಪ್ಟ್ ಆವೃತ್ತಿಯನ್ನು ಬದಲಾಯಿಸಿ — prompt_registry.json ಕಾನ್ಫ್ಲಿಕ್ಟ್ಗಳನ್ನು ಸುಲಭವಾಗಿ ಇಡುತ್ತದೆ ಮತ್ತು trunk ಮೇಲಿನ git log --oneline ನ್ನು ನಿಖರ ಬದಲಾವಣೆ ಇತಿಹಾಸವಾಗಿಸುತ್ತದೆ.
ಮಾಡಬಾರದವು
- ಯಾವುದೇ ಬ್ರಾಂಚ್ನ್ನು 48 ಗಂಟೆಗಳನ್ನು ಮೀರಿ ಬದುಕಲು ಬಿಡಬೇಡಿ — JSONL ಸೇರ್ಪಡೆಗಳು ಮತ್ತು ಪ್ರಾಂಪ್ಟ್ ಎಡಿಟ್ಗಳು Git ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಪರಿಹರಿಸಲಾಗದ ಡ್ರಿಫ್ಟ್ನ್ನು ಸಂಗ್ರಹಿಸುತ್ತವೆ; rebase ಮಾಡಿ ಮರ್ಜ್ ಮಾಡಿ, ಅಥವಾ ಬ್ರಾಂಚ್ನ್ನು ಅಳಿಸಿ.
- ಹಂಚಿಕೆಯ ಬ್ರಾಂಚ್ಗಳನ್ನು force-push ಮಾಡಬೇಡಿ — ತಂಡದ ಸಹೋದ್ಯೋಗಿಗಳ ಕೈಕೆಳಗೆ ಇತಿಹಾಸವನ್ನು ಮರುಬರೆಯುವುದು ಅವರ rebase ಗಳನ್ನು ಮುರಿಯುತ್ತದೆ ಮತ್ತು ಟ್ರಂಕ್-ಆಧಾರಿತ ಅಭಿವೃದ್ಧಿ ಅವಲಂಬಿಸಿರುವ ಆಡಿಟ್ ಜಾಡನ್ನು ನಾಶಪಡಿಸುತ್ತದೆ.
- ಹಂಚಿಕೆಯ ಬ್ರಾಂಚ್ಗಳಲ್ಲಿ --no-verify ಬಳಸಿ pre-push ಹುಕ್ನ್ನು ಬೈಪಾಸ್ ಮಾಡಬೇಡಿ — ಹುಕ್ ಲೋಕಲ್ ಜಾರಿ ಪದರವಾಗಿದೆ; ಅದನ್ನು ಬಿಟ್ಟರೆ ಹಳೆಯ ಅಥವಾ ಪ್ಯಾಟರ್ನ್ಗೆ ಹೊರತಾದ ಹೆಸರುಗಳು ರಿಮೋಟ್ಗೆ ತಲುಪುತ್ತವೆ, ಮತ್ತು ಸರ್ವರ್-ಸೈಡ್ branch protection ಮಾತ್ರ ಏಕೈಕ ರಕ್ಷಣೆಯಾಗಿ ಉಳಿಯುತ್ತದೆ.
3 hands-on labs come with this lesson — real code, in a cloud IDE. Create a free account to run them. No card.
Free account · no card · straight to the labs
Or get the full path — from
Listen to this lesson
Audio overviews of this lesson's labs and its chapter, from GenBodha Bytes.
- Set up trunk-based branching strategyLab5 min
- Implement feature branch naming conventionsLab5 min
- Execute full branch lifecycle with squash mergeLab5 min
- Git Workflows for AI TeamsChapter overview22 min
More free lessons in DevOps Foundations for GenAI Engineers
- Ch 1Implement trunk-based development for AI projectsYou are here
- Ch 1Implement pre-commit hooks and automated dependency updates
- Ch 2Compare CI platforms: GitHub Actions vs Tekton vs Dagger
- Ch 2Configure CI to run on GKE self-hosted runners
- Ch 3Build optimized Docker images for AI applications
- Ch 3Automate image builds with GitHub Actions
- Ch 3Sign images with Cosign and enforce Binary Authorization on GKE