- 5 aliases מותאמים שמקצרים תהליכי עבודה חוזרים לפקודה אחת
- סקריפט אוטומציה מלא שמנהל PRs, issues ו-labels מהטרמינל
- שליטה ב-gh api — גישה ישירה לכל endpoint של GitHub API עם REST ו-GraphQL
- יכולת JQ — סינון ופרסור JSON בשורה אחת עם דפוסים שימושיים
- סקריפט release — יצירת release אוטומטי עם tag, changelog ו-notifications
- extension מותאם — תוסף gh שבניתם מאפס שמדפיס סטטיסטיקות ריפו
- סקריפט issue triage — אוטומציית triage שמוסיפה labels ו-assignees
- מילון מונחים — 12 מונחי CLI חיוניים שתשתמשו בהם כל יום
- תוכלו ליצור aliases מותאמים (פשוטים, עם פרמטרים, ועם shell) שמקצרים תהליכי עבודה חוזרים לפקודה אחת
- תוכלו לגשת ל-GitHub API ישירות דרך
gh api— גם REST וגם GraphQL — עם JQ filtering - תוכלו לבנות סקריפט שלם שמאטמט תהליך מקצה לקצה: PR creation, labeling, assignment, ו-CI monitoring
- תוכלו להתקין וליצור gh extensions — תוספים מהקהילה ותוספים מותאמים שבניתם
- תוכלו לנטר GitHub Actions workflows בזמן אמת מהטרמינל בלי לפתוח דפדפן
- פרקים קודמים: אין חובה, אבל פרק 1 (Actions) עוזר להבין את
gh run - כלים: GitHub CLI מותקן (גרסה 2.60+), מאומת עם
gh auth login - חשבון: חשבון GitHub עם לפחות ריפוזיטורי אחד (אפילו ריק)
- ידע: שימוש בסיסי בטרמינל — מה זה pipe (
|), redirect (>), ומשתני סביבה
מאיפה באנו: בפרק 1 (Actions) בנינו CI/CD workflows שרצים אוטומטית. מה הפרק הזה מוסיף: שליטה מהטרמינל — ניטור של אותם workflows בזמן אמת עם gh run, ניהול PRs ו-issues בלי דפדפן, ואוטומציות scripting שמקשרות הכל. לאן ממשיכים: ה-aliases והסקריפטים שתבנו פה ילוו אתכם לאורך כל הקורס. בפרק 3 (Pages) נשתמש ב-CLI לפריסה, ובפרק 8 (API & Webhooks) נרחיב את יכולות ה-gh api שנלמד כאן.
- CLI
- Command Line Interface — ממשק שורת פקודה. GitHub CLI (gh) הוא הכלי הרשמי של GitHub לטרמינל
- Alias
- קיצור מותאם לפקודה ארוכה — נוצר עם
gh alias set. חוסך הקלדה חוזרת - Shell Alias
- alias שמריץ פקודת shell מלאה עם pipes, לולאות ולוגיקה — נוצר עם
gh alias set --shell - JQ
- שפת שאילתות ל-JSON — מסננת, ממפה ומעצבת נתונים. מובנית ב-gh דרך
--jq - REST API
- ממשק תכנותי מבוסס HTTP — קריאות GET, POST, PATCH, DELETE ל-endpoints ספציפיים
- GraphQL
- שפת שאילתות ל-API — מבקשים בדיוק את השדות שצריכים, בקריאה אחת
- Extension
- תוסף ל-gh שמרחיב יכולות — מותקן מהקהילה או שבניתם בעצמכם
- PAT
- Personal Access Token — מפתח אישי לגישה ל-API. ב-gh, ה-token מנוהל אוטומטית
- Rate Limit
- מגבלת קריאות ל-API — 5,000 קריאות לשעה עם אימות. בלי אימות: 60
- Pagination
- חלוקת תוצאות לדפים כשיש הרבה תוצאות. ב-gh:
--paginateמטפל אוטומטית - OAuth
- פרוטוקול אימות שמאפשר גישה ל-API בלי חשיפת סיסמה — כך gh auth עובד
- Pipe
- העברת פלט מפקודה אחת לקלט של אחרת עם
|— הבסיס לשרשור פקודות בטרמינל
2.1 מעבר לבסיס — מה רוב המפתחים לא יודעים
שאלו מפתח ממוצע מה הוא יודע על GitHub CLI ותקבלו שתי פקודות: gh pr create ו-gh repo clone. אולי גם gh pr view אם הוא מתקדם. זה כמו להכיר רק Copy ו-Paste ב-Excel ולחשוב שמיצית את הפוטנציאל.
האמת היא שמתחת לשטח יש קרחון שלם של יכולות שרוב המפתחים אף פעם לא נוגעים בהן. GitHub CLI עבר מהפכה שקטה בשנים האחרונות — מכלי פשוט ליצירת PRs לפלטפורמה מלאה שמאפשרת לעשות כמעט כל דבר שאפשר לעשות ב-GitHub.com, ולעשות אותו מהר יותר:
- Aliases — קיצורים מותאמים שהופכים תהליך של 5 פקודות לפקודה אחת. ברמה הפשוטה זה קיצור שם, ברמה המתקדמת זה shell script שלם
- gh api — גישה ישירה לכל endpoint של GitHub API, בלי curl ובלי token ידני. כולל GraphQL. כולל pagination אוטומטי. כולל JQ מובנה
- JQ filtering — סינון JSON בשורה אחת, מובנה ישירות ב-gh. לא צריך להתקין jq בנפרד (אם כי אפשר)
- Extensions — אקוסיסטם שלם של תוספים מהקהילה, כולל gh-dash (dashboard אינטראקטיבי), gh-poi (ניקוי branches), ועוד מאות. ואפשר לבנות extensions משלכם
- Scripting — אוטומציות שלמות שמנהלות ריפוזיטורים, issues, PRs ו-releases. הדפוס הבסיסי: שליפה, עיבוד, פעולה — והכל בכמה שורות shell
הנתון הכי מפתיע: לפי הסקר השנתי של GitHub, רק כ-15% מהמפתחים שמשתמשים ב-gh CLI ממצים יותר מ-20% מהיכולות שלו. ב-85% המפתחים, השימוש מוגבל לפקודות הבסיסיות. הפער הזה הוא ההזדמנות שלכם.
בפרק הזה נחקור את כל הרבדים האלה, צעד אחרי צעד. בסוף הפרק, הטרמינל יהיה הממשק הראשי שלכם ל-GitHub — ותתפלאו איך עבדתם בלי זה.
לפני שמתחילים — בדקו שאתם מוכנים. הריצו את שלוש הפקודות הבאות:
# בדיקת גרסה — צריך 2.60 ומעלה
gh --version
# בדיקת אימות — צריך להיות logged in
gh auth status
# רשימת aliases — כנראה ריק. בקרוב נמלא
gh alias list
אם gh לא מותקן: brew install gh (macOS), winget install GitHub.cli (Windows), או sudo apt install gh (Linux). אחרי ההתקנה: gh auth login ועקבו אחרי ההוראות.
אם הגרסה ישנה: gh upgrade (או brew upgrade gh / winget upgrade GitHub.cli).
מה נכסה בפרק הזה
הפרק בנוי בצורה הדרגתית — מתחילים מדברים פשוטים ומתקדמים:
- Aliases (סעיף 2.2) — נתחיל מהקל ביותר. קיצורים מותאמים שאפשר ליצור ב-10 שניות ולהשתמש מיד. שלוש רמות — מפשוט למורכב.
- gh api (סעיף 2.3) — נפתח את הדלת לכל ה-API של GitHub. REST ו-GraphQL, עם דוגמאות מעשיות שתוכלו להריץ מיד.
- JQ (סעיף 2.4) — נלמד לסנן JSON כמו מקצוענים. ספר המתכונים שנבנה כאן ילווה אתכם הרבה אחרי הפרק.
- PR, Issue, Repo (סעיף 2.5) — מחזורי חיים מלאים מהטרמינל. כל מה שעושים ב-GitHub.com, ב-CLI.
- gh run (סעיף 2.6) — ניטור CI/CD בזמן אמת. חיבור ישיר למה שלמדנו בפרק 1.
- Scripting (סעיף 2.7) — שם הכל מתחבר. סקריפטים שמשלבים את כל מה שלמדנו לאוטומציות אמיתיות.
- Extensions (סעיף 2.8) — תוספים מהקהילה ויצירת extensions משלכם.
- אוטומציות מורכבות (סעיף 2.9) — שני תרחישים מהעולם האמיתי שמשלבים הכל.
מוכנים? בואו נתחיל מהדבר שישנה לכם את החיים מיד — aliases.
2.2 Aliases — קיצורים מותאמים אישית
alias ב-gh הוא בדיוק מה שנשמע: שם קצר שמחליף פקודה ארוכה. אבל ב-gh יש שלוש רמות של aliases, מפשוט למורכב, וההבדל ביניהן הוא קריטי.
רמה 1 — alias פשוט
ברמה הבסיסית ביותר, alias הוא פשוט שם חדש לפקודה קיימת. זה חוסך הקלדה ומפשט פקודות ארוכות:
# הפקודה המקורית — 42 תווים:
gh pr list --state open --assignee @me
# אחרי alias — 10 תווים:
gh alias set my-prs 'pr list --state open --assignee @me'
gh my-prs
# עוד דוגמאות:
gh alias set my-issues 'issue list --assignee @me --state open'
gh alias set repos 'repo list --limit 20 --sort updated'
זה פשוט, אבל כבר חוסך זמן משמעותי ביום-יום. כל פקודה שאתם מריצים יותר מפעמיים ביום צריכה להיות alias.
רמה 2 — alias עם פרמטרים
פרמטרים הופכים את ה-alias לגמיש — אתם מעבירים ארגומנטים שמשתנים בכל הרצה:
# $1 הוא הארגומנט הראשון שתעבירו
gh alias set pr-for 'pr list --search "author:$1"'
# שימוש:
gh pr-for octocat # PRs של octocat
gh pr-for nadav # PRs של nadav
# alias עם שני פרמטרים:
gh alias set find-issue 'issue list --label "$1" --state "$2"'
# שימוש:
gh find-issue bug open # issues פתוחים עם label "bug"
gh find-issue enhancement closed # issues סגורים עם label "enhancement"
הפרמטרים $1, $2, $3 מחליפים את הארגומנטים שתעבירו. זה מספיק לרוב המקרים.
רמה 3 — shell alias עם pipes ולוגיקה
הרמה הכי חזקה. --shell אומר ל-gh שהפקודה היא shell script, לא פקודת gh רגילה. זה פותח דלת לכל מה ש-shell יכול לעשות — pipes, לולאות, תנאים, ופקודות חיצוניות:
# alias שמריץ shell command מלא
gh alias set --shell stale-issues \
'gh issue list --json number,title,updatedAt \
--jq ".[] | select(now - (.updatedAt | fromdateiso8601) > 30*24*3600) | \"#\(.number) \(.title)\""'
# alias שמשלב כמה פקודות gh
gh alias set --shell pr-stats \
'echo "Open PRs: $(gh pr list --json number --jq \"length\")"
echo "My PRs: $(gh pr list --json number --assignee @me --jq \"length\")"
echo "Draft PRs: $(gh pr list --json isDraft --jq \"[.[] | select(.isDraft)] | length\")"'
# alias עם תנאי
gh alias set --shell safe-merge \
'PR=$1
STATUS=$(gh pr checks "$PR" --json state --jq ".[].state" | sort -u)
if echo "$STATUS" | grep -q "FAILURE"; then
echo "Cannot merge — CI failed"
else
gh pr merge "$PR" --squash --delete-branch
fi'
shell aliases הם חזקים, אבל דורשים זהירות. כל טעות בתחביר shell תגרום ל-alias לא לעבוד, וה-debugging לא תמיד פשוט. כלל אצבע:
- רמה 1 — כשאתם רוצים רק לקצר פקודה קיימת. פשוט ומהיר.
- רמה 2 — כשהפקודה צריכה להיות גמישה (פרמטרים משתנים). הכי נפוץ ביום-יום.
- רמה 3 — כשצריכים לוגיקה (תנאים, לולאות, שילוב פקודות). חזק אבל מורכב. אם ה-alias ארוך מ-3 שורות, שקלו להפוך אותו לסקריפט נפרד.
ניהול aliases
ה-aliases שלכם נשמרים בקובץ קונפיגורציה של gh. אפשר לנהל אותם כך:
# רשימת כל ה-aliases שהגדרתם
gh alias list
# מחיקת alias
gh alias delete my-prs
# ייבוא aliases מקובץ YAML (שיתוף עם צוות!)
gh alias import aliases.yml
# צפייה בהגדרת alias ספציפי
gh alias list | grep my-prs
טיפ למתקדמים — גיבוי ושיתוף aliases: כל ה-aliases נשמרים בקובץ ~/.config/gh/config.yml (או %APPDATA%\GitHub CLI\config.yml ב-Windows). אפשר לייצא אותם עם gh alias list, לשמור בקובץ YAML ב-dotfiles repo, ולייבא במכונה חדשה עם gh alias import aliases.yml. כך תוכלו:
- לשחזר את כל ה-aliases שלכם בכל מכונה חדשה עם פקודה אחת
- לשתף aliases עם חברי צוות — כולם עובדים עם אותם קיצורים
- לגרסן את ה-aliases שלכם ב-Git — ככה יש לכם היסטוריה של שינויים
דוגמה לקובץ aliases.yml:
# aliases.yml — Team aliases
my-prs: pr list --state open --assignee @me
my-issues: issue list --assignee @me --state open
repos: repo list --limit 20 --sort updated
חמשת ה-aliases שכל מפתח צריך
אלה ה-aliases שנשמרים אצלי ואני משתמש בהם כל יום:
# 1. PRs שמחכים לי
gh alias set my-prs 'pr list --state open --assignee @me'
# 2. יצירת PR מהירה
gh alias set --shell quick-pr \
'gh pr create --title "$1" --body "Auto-created via CLI" --assignee @me'
# 3. צפייה ב-CI של ה-PR הנוכחי
gh alias set --shell ci \
'gh pr checks $(gh pr view --json number --jq .number)'
# 4. ניקוי branches ממוזגים
gh alias set --shell cleanup \
'git branch --merged main | grep -v main | xargs -r git branch -d && echo "Cleaned!"'
# 5. דוח יומי
gh alias set --shell daily \
'echo "=== My Open PRs ==="
gh pr list --assignee @me --json number,title --jq ".[] | \"#\(.number) \(.title)\""
echo ""
echo "=== My Open Issues ==="
gh issue list --assignee @me --json number,title --jq ".[] | \"#\(.number) \(.title)\""'
צרו את שלושת ה-aliases הראשונים שלכם. העתיקו והריצו:
# alias 1: PRs שלי
gh alias set my-prs 'pr list --state open --assignee @me'
# alias 2: issues שלי
gh alias set my-issues 'issue list --assignee @me --state open'
# alias 3: יצירת PR מהירה
gh alias set --shell quick-pr \
'gh pr create --title "$1" --body "Auto-created via CLI" --assignee @me'
# בדקו שהם נוצרו:
gh alias list
אם הריפוזיטורי שלכם ריק, gh my-prs יחזיר רשימה ריקה. זה בסדר — העיקר שהפקודה עובדת בלי שגיאה.
עכשיו shell alias שבודק CI status:
gh alias set --shell ci-status \
'echo "Last 5 workflow runs:"
gh run list --limit 5 --json status,name,conclusion \
--jq ".[] | \"\(.name): \(.status) (\(.conclusion // \"running\"))\""'
# נסו:
gh ci-status
אם אין לכם workflows (לא עשיתם את פרק 1), תקבלו רשימה ריקה. זה בסדר.
לעולם אל תקראו ל-alias בשם של פקודה קיימת. gh alias set pr ... ידרוס את gh pr המקורי ותאבדו גישה לכל תת-הפקודות שלו. כלל אצבע: תמיד השתמשו בשמות ייחודיים עם מקף — my-prs, quick-pr, ci-status. בדקו תמיד עם gh help <name> שהשם לא תפוס לפני שיוצרים alias.
2.3 gh api — כל ה-API של GitHub בפקודה אחת
gh api הוא הכלי החבוי הכי חזק ב-gh. בזמן שרוב המפתחים משתמשים ב-gh בשביל פקודות מוכנות כמו gh pr list, מי שמכיר gh api יכול לגשת לכל דבר שה-GitHub API מציע — כולל endpoints שאין להם פקודת gh ייעודית.
למה gh api ולא curl?
בואו נשווה שליפת מידע על ריפוזיטורי ב-curl מול gh api:
# curl — ארוך, מסורבל, חושף token:
curl -H "Authorization: Bearer ghp_xxxxxxxxxxxx" \
-H "Accept: application/vnd.github+json" \
https://api.github.com/repos/octocat/Hello-World
# gh api — קצר, מאובטח, אוטומטי:
gh api repos/octocat/Hello-World
ההבדל דרמטי, וזה רק ההתחלה. הנה היתרונות המלאים:
- אימות אוטומטי — gh api משתמש ב-token שכבר הגדרתם ב-
gh auth. אף פעם לא צריכים לחשוף PAT בפקודה - URL קצר — לא צריך
https://api.github.com/, רק את הנתיב:repos/owner/repo - Pagination אוטומטי — הוסיפו
--paginateוהוא יביא את כל הדפים בשבילכם, בלי לנהל Link headers - JQ מובנה —
--jqמסנן את ה-JSON ישירות, בלי pipe חיצוני - HTTP methods מובנים —
-X POST,-f field=value— הכל עובד חלק - Template variables —
{owner}/{repo}מוחלפים אוטומטית לפי ה-repo הנוכחי
REST API — דוגמאות בסיסיות
# קבלת מידע על ריפוזיטורי
gh api repos/{owner}/{repo}
# רשימת collaborators
gh api repos/{owner}/{repo}/collaborators
# יצירת issue
gh api repos/{owner}/{repo}/issues -f title="Bug report" -f body="Details here"
# עדכון issue (הוספת label)
gh api repos/{owner}/{repo}/issues/42/labels -f "labels[]=bug" -f "labels[]=priority"
# מחיקת branch
gh api repos/{owner}/{repo}/git/refs/heads/old-branch -X DELETE
# רשימת כל ה-releases
gh api repos/{owner}/{repo}/releases --paginate --jq '.[].tag_name'
POST, PATCH, DELETE — כתיבה ל-API
ברירת המחדל של gh api היא GET. לפעולות כתיבה, משתמשים ב-flags:
# POST — יצירה (ברירת מחדל כשיש -f)
gh api repos/{owner}/{repo}/issues \
-f title="New issue" \
-f body="Created via gh api" \
-f "labels[]=enhancement"
# PATCH — עדכון
gh api repos/{owner}/{repo}/issues/42 \
-X PATCH \
-f state="closed" \
-f state_reason="completed"
# PUT — הוספת collaborator
gh api repos/{owner}/{repo}/collaborators/username \
-X PUT \
-f permission="push"
# DELETE — מחיקה
gh api repos/{owner}/{repo}/issues/42/labels/bug -X DELETE
GraphQL עם gh api
GitHub מציע שני APIs: REST ו-GraphQL. gh api graphql מאפשר לשלוח שאילתות GraphQL שמחזירות בדיוק את מה שצריכים — בלי שדות מיותרים:
# שאילתת GraphQL בסיסית — 5 ריפוזיטורים אחרונים
gh api graphql -f query='
query {
viewer {
login
repositories(first: 5, orderBy: {field: UPDATED_AT, direction: DESC}) {
nodes { name stargazerCount }
}
}
}'
# שאילתה עם משתנים — חיפוש PRs של משתמש
gh api graphql -f query='
query($owner: String!, $repo: String!) {
repository(owner: $owner, name: $repo) {
pullRequests(first: 10, states: OPEN) {
nodes {
number
title
author { login }
createdAt
}
}
}
}' -f owner="{owner}" -f repo="{repo}"
מתי GraphQL ומתי REST? זה תלוי בצורך שלכם:
- GraphQL עדיף כשצריכים נתונים מכמה מקורות בקריאה אחת — למשל, PRs עם reviews שלהם ו-checks status, הכל בשאילתה אחת. ב-REST זה דורש 3 קריאות נפרדות
- GraphQL עדיף כשצריכים רק שדות ספציפיים — REST מחזיר את כל השדות, GraphQL מחזיר בדיוק מה שביקשתם. פחות data transfer = מהיר יותר
- REST פשוט יותר לפעולות כתיבה — יצירת issue, עדכון PR, הוספת label. התחביר של mutations ב-GraphQL מסורבל יותר
- REST קל יותר ללמוד — endpoints ושיטות HTTP פשוטות. GraphQL דורש ללמוד שפת שאילתות
כלל אצבע: התחילו עם REST. עברו ל-GraphQL רק כשנתקלתם במגבלה — יותר מדי קריאות, שדות חסרים, או ביצועים איטיים.
| קריטריון | gh api | curl + PAT | Octokit (SDK) |
|---|---|---|---|
| מתאים ל- | שאילתות מהירות, scripting, אוטומציות | debugging, one-offs, CI environments | אפליקציות, GitHub Apps, קוד production |
| אימות | אוטומטי (gh auth) | ידני (PAT ב-header) | PAT או GitHub App credentials |
| JQ מובנה | כן (--jq) | לא (pipe ל-jq חיצוני) | לא (עיבוד בקוד) |
| Pagination | --paginate (אוטומטי) | ידני (Link headers) | אוטומטי (SDK method) |
| שפת תכנות | Shell / Bash | כל שפה | JavaScript / TypeScript / Ruby |
| מתי לבחור | כשעובדים מהטרמינל | כשאין gh זמין | כשבונים אפליקציה |
כלל אצבע: אם אתם בטרמינל — gh api. אם אתם בקוד — Octokit. אם אתם ב-CI בלי gh — curl + PAT.
הריצו את שלוש הקריאות הבאות ובדקו שאתם מקבלים תוצאות:
# 1. פרטי הריפוזיטורי שלכם (החליפו {owner}/{repo})
gh api repos/{owner}/{repo} --jq '{name: .name, stars: .stargazers_count, language: .language}'
# 2. רשימת branches
gh api repos/{owner}/{repo}/branches --jq '.[].name'
# 3. בדיקת rate limit — כמה קריאות נשארו
gh api rate_limit --jq '.rate | "Used: \(.used)/\(.limit), Reset: \(.reset | strftime("%H:%M:%S"))"'
שימו לב כמה מהיר זה לעומת פתיחת הדפדפן, ניווט לריפוזיטורי, וחיפוש המידע הזה.
יש מגבלת 5,000 קריאות API לשעה עם אימות (ו-60 בלי אימות). זה נשמע הרבה, אבל סקריפט עם לולאה שרצה על 500 issues כבר אוכל 500 קריאות. הוסיפו sleep 0.5 בין קריאות בלולאות, או השתמשו ב-GraphQL שאוסף כמה שדות בקריאה אחת. תמיד בדקו עם gh api rate_limit --jq '.rate' כמה קריאות נשארו.
2.4 JQ — סינון ופרסור JSON כמו קסם
כמעט כל פלט של gh הוא JSON. בלי סינון, תקבלו מסה של נתונים שקשה לקרוא. JQ היא השפה שמסננת, ממפה ומעצבת JSON — וב-gh היא מובנית ישירות דרך --jq.
חשבו על JQ כ-SQL של JSON. כמו ש-SQL מאפשר לשלוף, לסנן ולמיין נתונים ממסד נתונים, JQ עושה את אותו הדבר עם JSON. ברגע שתלמדו 5-6 דפוסים בסיסיים, תוכלו לענות על כמעט כל שאלה שיש לכם על הנתונים שחוזרים מ-GitHub.
שתי דרכים לעבוד עם JQ ב-gh
דרך 1: --jq (מובנה — הכי נפוצה ומומלצת):
# שמות כל ה-PRs הפתוחים
gh pr list --json title --jq '.[].title'
# PRs שנוצרו על ידי משתמש ספציפי
gh pr list --json title,author --jq '.[] | select(.author.login == "octocat") | .title'
# פורמט מותאם — מספר + כותרת
gh pr list --json number,title --jq '.[] | "#\(.number) \(.title)"'
דרך 2: --json + pipe ל-jq חיצוני:
# כשצריכים JQ מתקדם יותר (sort_by, group_by, וכו')
gh pr list --json title,createdAt | jq 'sort_by(.createdAt) | reverse | .[0:5]'
# קיבוץ issues לפי label
gh issue list --json number,labels | jq 'group_by(.labels[0].name) | .[] | {label: .[0].labels[0].name, count: length}'
מתי --jq ומתי pipe? בשביל סינון בסיסי, --jq מספיק ועדיף (פחות תלויות). כש-pipe ל-jq חיצוני, יש גישה לפונקציות מתקדמות יותר כמו group_by ו-env.
ספר המתכונים — דפוסי JQ חיוניים
אלה הדפוסים שתשתמשו בהם שוב ושוב:
# 1. בחירת שדה אחד מכל אלמנט
--jq '.[].name'
# 2. בחירת כמה שדות
--jq '.[] | {name: .name, stars: .stargazers_count}'
# 3. סינון עם select
--jq '.[] | select(.state == "open")'
--jq '.[] | select(.labels | length > 0)'
--jq '.[] | select(.title | test("fix"; "i"))' # regex case-insensitive
# 4. פורמט מותאם (string interpolation)
--jq '.[] | "#\(.number): \(.title) [\(.author.login)]"'
# 5. ספירה
--jq 'length' # כמה אלמנטים
--jq '[.[] | select(.state == "open")] | length' # כמה פתוחים
# 6. מיון
--jq 'sort_by(.stargazerCount) | reverse' # מיון יורד
--jq 'sort_by(.createdAt)' # מיון לפי תאריך
# 7. חיתוך — רק N ראשונים
--jq '.[0:5]' # 5 ראשונים
--jq 'sort_by(.updatedAt) | reverse | .[0:3]' # 3 אחרונים
# 8. שרשור פעולות
--jq '[.[] | select(.state == "open")] | sort_by(.createdAt) | .[0] | "#\(.number) \(.title)"'
| דרך | מתי להשתמש | דוגמה | יתרונות |
|---|---|---|---|
--jq | סינון מובנה — רוב המקרים | --jq '.[].name' | מהיר, בלי תלויות חיצוניות |
--json + pipe ל-jq | עיבוד מתקדם (group_by, env) | --json fields | jq '...' | גישה לכל פונקציות jq |
--template | פורמט טקסט מורכב (Go templates) | --template '{{.Name}}' | שליטה מלאה בפורמט |
--json (בלי סינון) | debugging — רואים הכל | --json number,title | רואים את כל השדות הזמינים |
כלל אצבע: התחילו עם --jq. עברו ל-pipe + jq רק כשנתקלתם במגבלה. --template כמעט אף פעם לא צריך.
נסו את שרשרת הדפוסים — מפשוט למורכב:
# שלב 1: כל ה-PRs הפתוחים — רק מספר ושם
gh pr list --json number,title --jq '.[] | "#\(.number) \(.title)"'
# שלב 2: כמה PRs פתוחים יש?
gh pr list --json number --jq 'length'
# שלב 3: ה-PR הכי ישן (לפי תאריך יצירה)
gh pr list --json number,title,createdAt --jq 'sort_by(.createdAt) | .[0] | "#\(.number) \(.title) (created: \(.createdAt[:10]))"'
אם אין PRs, נסו על issues: gh issue list --json ...
שאילתה מתקדמת — הריפוזיטורים שלכם מדורגים לפי כוכבים:
gh api user/repos --paginate --jq \
'sort_by(.stargazers_count) | reverse | .[:5] | .[] | "\(.full_name): \(.stargazers_count) stars"'
נסו גם: gh api user/repos --paginate --jq '[.[] | select(.language == "JavaScript")] | length' — כמה ריפוזיטורים של JavaScript יש לכם?
2.5 gh pr, gh issue, gh repo — השליטה המלאה
שלוש קבוצות הפקודות המרכזיות של gh CLI הן pr, issue ו-repo. כל אחת מנהלת מחזור חיים שלם — מיצירה ועד סגירה. אלה הפקודות שתשתמשו בהן הכי הרבה ביום-יום, הרבה יותר מ-gh api או scripting. נעבור על כל קבוצה בפירוט, עם כל הפקודות החשובות, flags שימושיים, ודוגמאות מעשיות שתוכלו להריץ מיד.
gh pr — מחזור חיים מלא של Pull Request
זו קבוצת הפקודות שהכי משתמשים בה ביום-יום. כל שלב במחזור החיים של PR — מיצירה, דרך review, ועד merge — אפשר לעשות מהטרמינל. זה לא רק יותר מהיר — זה גם מאפשר אוטומציה. מה שלוקח 2 דקות בדפדפן (פתיחת tab, ניווט לריפו, לחיצה על New PR, מילוי פרטים, לחיצה על Create) לוקח 5 שניות ב-CLI.
מחזור חיים מלא של PR:
# שלב 1: יצירת PR
gh pr create --title "feat: add login page" --body "Description of changes"
gh pr create --fill # מלא אוטומטית מ-commits
gh pr create --draft # יצירת draft PR
gh pr create --reviewer user1,user2 # עם reviewers מיידית
gh pr create --label "feature" --milestone "v2.0" # עם label ו-milestone
# שלב 2: סקירה וניהול
gh pr list --state open # רשימת PRs פתוחים
gh pr view 42 # צפייה ב-PR ספציפי
gh pr view 42 --web # פתיחה בדפדפן
gh pr checkout 42 # checkout ל-branch של ה-PR
gh pr diff 42 # צפייה בשינויים
gh pr checks 42 # סטטוס CI
# שלב 3: Code review
gh pr review 42 --approve # אישור
gh pr review 42 --request-changes --body "Please fix X" # בקשת שינויים
gh pr review 42 --comment --body "Looks good overall" # הערה
# שלב 4: מיזוג
gh pr merge 42 --squash --delete-branch # squash merge + מחיקת branch
gh pr merge 42 --rebase # rebase merge
gh pr merge 42 --merge # merge commit
# פעולות נוספות
gh pr ready 42 # הפיכת draft ל-ready
gh pr edit 42 --add-label "priority" # הוספת label
gh pr edit 42 --add-reviewer octocat # הוספת reviewer
gh pr close 42 # סגירה בלי merge
שימו לב לעוצמה של gh pr create --fill — הוא לוקח את ה-commit messages ומשתמש בהם ככותרת ותיאור של ה-PR אוטומטית. אם ה-commits שלכם כתובים טוב, זה חוסך את הצורך לכתוב תיאור מחדש.
טיפ נוסף: gh pr checkout 42 עושה את מה ש-git לבד לא יכול — הוא יודע לעשות checkout ל-PR מ-fork אחר, לא רק מ-branches מקומיים. זה שימושי במיוחד ל-maintainers שרוצים לבדוק PR מ-contributor חיצוני.
gh issue — ניהול issues מקצה לקצה
# יצירה
gh issue create --title "Bug: login fails" --label bug
gh issue create --title "Feature: dark mode" --label enhancement --assignee @me
gh issue create --template bug_report # שימוש ב-issue template
# סינון וחיפוש
gh issue list --label bug --assignee @me # סינון לפי label ו-assignee
gh issue list --state closed --limit 10 # 10 issues סגורים אחרונים
gh issue list --search "login in:title" # חיפוש טקסט חופשי
gh issue list --milestone "v2.0" # issues לפי milestone
# ניהול
gh issue view 15 # צפייה
gh issue close 15 --reason completed # סגירה עם סיבה
gh issue reopen 15 # פתיחה מחדש
gh issue pin 15 # הצמדה (pinning)
gh issue unpin 15 # הסרת הצמדה
gh issue transfer 15 other-repo # העברה לריפו אחר
gh issue edit 15 --add-label "in-progress" # הוספת label
gh issue edit 15 --add-assignee user1 # הוספת assignee
# הערות
gh issue comment 15 --body "Working on this" # הוספת הערה
gh issue develop 15 --base main # יצירת branch עבור issue
שימו לב לפקודה gh issue develop 15 --base main — היא יוצרת branch חדש מקושר ל-issue. כשתפתחו PR מה-branch הזה, GitHub יקשר אותו אוטומטית ל-issue. כשה-PR ימוזג, ה-issue ייסגר אוטומטית. זה pattern חזק שחוסך עבודה ידנית.
עוד פקודה שרבים לא מכירים: gh issue pin מצמידה issue לראש הרשימה ב-GitHub.com. שימושי ל-issues חשובים שאתם רוצים שכולם יראו — כמו roadmap או contributing guidelines.
gh repo — ניהול ריפוזיטורים
# יצירה
gh repo create my-project --public --clone # יצירה + clone
gh repo create my-project --private --add-readme # עם README
gh repo create org/project --team developers # בארגון, עם צוות
# Clone ו-Fork
gh repo clone owner/repo # clone
gh repo fork owner/repo --clone # fork + clone מקומי
gh repo fork owner/repo --clone --remote # fork + clone + remote
# מידע וצפייה
gh repo view # מידע על הריפו הנוכחי
gh repo view owner/repo # מידע על ריפו אחר
gh repo view --web # פתיחה בדפדפן
# ניהול
gh repo rename new-name # שינוי שם
gh repo edit --default-branch main # שינוי branch ברירת מחדל
gh repo edit --enable-issues=false # כיבוי issues
gh repo archive # ארכוב (הפיכה ל-readonly)
gh repo delete --confirm # מחיקה (!)
# רשימות
gh repo list # הריפוזיטורים שלי
gh repo list --source --no-archived --limit 30 # רק מקור, לא ארכיון
gh repo list org-name --limit 50 # ריפוזיטורים של ארגון
בצעו מחזור PR מלא מהטרמינל — מיצירת branch ועד merge (או סגירה):
# 1. צרו branch חדש
git checkout -b test-cli-workflow
# 2. צרו קובץ ו-commit
echo "# CLI Workflow Test" > cli-test.md
git add cli-test.md
git commit -m "test: CLI workflow demo"
# 3. דחפו ל-remote
git push -u origin test-cli-workflow
# 4. צרו PR
gh pr create --title "test: CLI workflow demo" --body "Created entirely from the terminal"
# 5. בדקו סטטוס CI (אם יש workflow)
gh pr checks
# 6. צפו ב-PR בדפדפן לוידוא
gh pr view --web
# 7. סגרו את ה-PR (זה רק תרגול)
gh pr close --comment "Test completed"
כל התהליך צריך לקחת פחות מדקה — ובלי לפתוח דפדפן אפילו פעם אחת (חוץ מצעד 6 שהוא אופציונלי).
חלק מהפקודות הן בלתי הפיכות. gh repo delete מוחק ריפוזיטורי לצמיתות — כולל כל ה-issues, PRs, wiki, ו-actions history. gh pr merge ממזג ואין undo פשוט. לפני כל פעולה הרסנית: בדקו עם gh pr view או gh repo view שאתם על הריפו/PR הנכון. אם זמין, הוסיפו --dry-run.
2.6 gh run — ניטור Actions מהטרמינל
בפרק 1 בנינו workflows עם GitHub Actions — CI/CD pipelines שבודקים קוד, מריצים tests, ופורסים אוטומטית. אבל עד עכשיו, כדי לראות אם ה-workflow עבר, היינו צריכים לפתוח את הדפדפן ולנווט לטאב Actions. עכשיו נלמד לנטר את כל זה מהטרמינל — בזמן אמת, בלי לצאת מהקונטקסט של העבודה. אם לא עשיתם את פרק 1, לא נורא — תוכלו לחזור לסעיף הזה אחרי שתגדירו workflow ראשון.
הפקודות הבסיסיות
# רשימת הרצות אחרונות
gh run list # כל ההרצות
gh run list --workflow ci.yml # רק workflow ספציפי
gh run list --limit 5 # 5 אחרונות
gh run list --status failure # רק כשלונות
gh run list --branch main # רק ב-main
# צפייה בהרצה ספציפית
gh run view 12345 # פרטי הרצה
gh run view 12345 --log # לוגים מלאים
gh run view 12345 --log-failed # לוגים רק של מה שנכשל
gh run view --web # פתיחה בדפדפן
# צפייה בזמן אמת — הפקודה הכי שימושית
gh run watch # צפייה ב-run האחרון
gh run watch 12345 # צפייה ב-run ספציפי
# הרצה מחדש
gh run rerun 12345 # הרצה מחדש מלאה
gh run rerun 12345 --failed # רק jobs שנכשלו (!)
gh run rerun 12345 --debug # עם debug logging
# Artifacts
gh run download 12345 # הורדת כל ה-artifacts
gh run download 12345 -n my-artifact # artifact ספציפי
הזרימה האידיאלית — push, watch, fix, rerun
ככה נראה workflow טיפוסי של מפתח שמשתמש ב-gh run:
# 1. דחפתם קוד
git push origin main
# 2. מצאו את ה-run שהתחיל
gh run list --limit 1
# 3. צפו בו בזמן אמת
gh run watch
# 4. אם נכשל — ראו מה נכשל
gh run view --log-failed
# 5. תקנו את הקוד, דחפו שוב
git push origin main
# 6. או — הריצו מחדש רק את מה שנכשל
gh run rerun --failed
הקסם הוא ב-gh run watch — זה פותח תצוגה חיה בטרמינל שמתעדכנת כל כמה שניות, עם סטטוס של כל job. כמו לצפות ב-progress bar, אבל ב-CI/CD. כשכל ה-jobs עוברים, תראו סטטוס ירוק ותוכלו להמשיך לעבוד. אם משהו נכשל, gh run view --log-failed מראה לכם בדיוק מה קרה — בלי לנווט דרך ממשק הוובוי, ללחוץ על job, ואז על step, ואז לגלול. הכל מגיע ישירות לטרמינל.
עוד יתרון משמעותי: gh run rerun --failed מריץ מחדש רק את ה-jobs שנכשלו, לא את כל ה-workflow. אם יש לכם matrix build עם 10 jobs ו-2 נכשלו, זה מריץ רק את ה-2 — חוסך זמן ו-Actions minutes.
דפוסים מתקדמים — שילוב עם scripting
# alias שדוחף ומיד צופה
gh alias set --shell push-watch \
'git push origin HEAD && sleep 2 && gh run watch'
# בדיקה אם ה-CI האחרון עבר
gh alias set --shell ci-ok \
'STATUS=$(gh run list --limit 1 --json conclusion --jq ".[0].conclusion")
if [ "$STATUS" = "success" ]; then
echo "CI passed"
else
echo "CI failed: $STATUS"
exit 1
fi'
אם יש לכם workflow מוגדר (מפרק 1), דחפו שינוי וצפו:
# דחפו שינוי (אפילו קטן)
echo "# Updated $(date)" >> README.md
git add README.md && git commit -m "docs: trigger CI" && git push
# מיד אחרי — צפו ב-run
gh run watch
תראו את ה-workflow רץ בזמן אמת בטרמינל — עם סטטוס של כל job. לחצו Ctrl+C כדי לצאת מהצפייה.
אם אין לכם workflow, נסו: gh run list — גם אם הרשימה ריקה, הפקודה עצמה צריכה לעבוד.
2.7 Scripting Patterns — אוטומציות עם gh
הכוח האמיתי של gh CLI מתגלה כשמשלבים אותו עם shell scripting. עד עכשיו ראינו פקודות בודדות — alias שמריץ פקודה אחת, שאילתת API שמחזירה נתונים, סינון JQ שמעצב פלט. עכשיו נחבר את הכל לסקריפטים שלמים שמבצעים תהליכים מורכבים אוטומטית.
הדפוס הבסיסי הוא תמיד אותו דבר: שליפה, עיבוד, פעולה. שולפים נתונים מ-GitHub (עם gh list או gh api), מעבדים אותם עם JQ (סינון, מיון, בחירת שדות), ומבצעים פעולה על כל אלמנט (עם while read ו-gh edit / gh api). נראה חמישה דפוסים שמכסים כמעט כל תרחיש.
דפוס 1 — לולאה פשוטה על issues
#!/bin/bash
set -euo pipefail
# הוספת label "needs-triage" לכל issue פתוח בלי label
gh issue list --json number,labels --jq \
'.[] | select(.labels | length == 0) | .number' | \
while read -r num; do
gh issue edit "$num" --add-label "needs-triage"
echo "Labeled issue #$num"
done
מה קורה פה? בואו נפרק את זה שורה אחרי שורה:
gh issue list --json number,labels— שולף את כל ה-issues הפתוחים עם מספר ו-labels בפורמט JSON--jq '.[] | select(.labels | length == 0) | .number'— מסנן רק issues בלי labels, ומוציא רק את המספרwhile read -r num— לולאה שרצה על כל מספר שחוזר מהצינור (pipe)gh issue edit "$num" --add-label "needs-triage"— מוסיף label ל-issue הספציפי
הדפוס הזה — שליפת JSON, סינון עם JQ, לולאה עם פעולה — חוזר בכל סקריפט. ברגע שתבינו אותו, תוכלו לבנות כל אוטומציה.
דפוס 2 — batch operations על PRs
#!/bin/bash
set -euo pipefail
# סגירת כל PRs ישנים (יותר מ-90 יום)
CUTOFF=$(date -d "90 days ago" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -v-90d +%Y-%m-%dT%H:%M:%SZ)
gh pr list --json number,createdAt --jq \
".[] | select(.createdAt < \"$CUTOFF\") | .number" | \
while read -r num; do
gh pr close "$num" --comment "Auto-closed: stale PR (90+ days with no activity)"
echo "Closed PR #$num"
sleep 0.5 # מניעת rate limit
done
דפוס 3 — pipeline מלא (שליפה, עיבוד, הצגה)
#!/bin/bash
set -euo pipefail
# דוח contributors מדורג
echo "=== Top 10 Contributors ==="
gh api repos/{owner}/{repo}/contributors --paginate \
--jq '.[] | "\(.login): \(.contributions) commits"' | \
sort -t: -k2 -rn | head -10
echo ""
echo "=== Repo Stats ==="
gh api repos/{owner}/{repo} --jq \
'"Stars: \(.stargazers_count) | Forks: \(.forks_count) | Issues: \(.open_issues_count)"'
דפוס 4 — תנאים ולוגיקה
#!/bin/bash
set -euo pipefail
# Auto-assign issues לפי label
gh issue list --state open --json number,labels --jq \
'.[] | {num: .number, labels: [.labels[].name]}' | jq -c '.' | \
while read -r issue; do
NUM=$(echo "$issue" | jq -r '.num')
LABELS=$(echo "$issue" | jq -r '.labels[]')
if echo "$LABELS" | grep -q "bug"; then
gh issue edit "$NUM" --add-assignee "bug-team-lead"
echo "#$NUM (bug) -> assigned to bug-team-lead"
elif echo "$LABELS" | grep -q "feature"; then
gh issue edit "$NUM" --add-assignee "feature-team-lead"
echo "#$NUM (feature) -> assigned to feature-team-lead"
fi
done
דפוס 5 — Error handling נכון
#!/bin/bash
set -euo pipefail
# סקריפט עם error handling מלא
LOG_FILE="/tmp/gh-automation-$(date +%Y%m%d).log"
log() {
echo "[$(date +%H:%M:%S)] $*" | tee -a "$LOG_FILE"
}
# בדיקת prerequisites
if ! gh auth status &>/dev/null; then
log "ERROR: Not authenticated. Run 'gh auth login' first."
exit 1
fi
REPO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner' 2>/dev/null)
if [ -z "$REPO" ]; then
log "ERROR: Not in a git repository."
exit 1
fi
log "Starting automation for $REPO"
# פעולה עם retry
perform_with_retry() {
local cmd="$1"
local max_retries=3
local attempt=1
while [ $attempt -le $max_retries ]; do
if eval "$cmd" 2>/dev/null; then
return 0
fi
log "WARN: Attempt $attempt failed, retrying..."
attempt=$((attempt + 1))
sleep 2
done
log "ERROR: Failed after $max_retries attempts: $cmd"
return 1
}
# שימוש
gh issue list --json number --jq '.[].number' | \
while read -r num; do
perform_with_retry "gh issue edit $num --add-label needs-review" && \
log "Labeled #$num" || \
log "Failed to label #$num"
done
log "Automation complete. Log: $LOG_FILE"
| קריטריון | Alias | Script (bash) | Extension |
|---|---|---|---|
| אורך | 1-3 שורות | 4-100 שורות | כל גודל |
| מורכבות | פקודה אחת או pipe פשוט | לולאות, תנאים, error handling | CLI מלא עם flags, help, versions |
| שיתוף | קובץ YAML (gh alias import) | קובץ bash (git repo) | gh extension install (GitHub) |
| מתי לבחור | קיצור פקודה חוזרת | אוטומציה עם לוגיקה | כלי שרוצים לשתף עם הקהילה |
| דוגמה | gh my-prs | ./triage.sh | gh my-stats |
כלל אצבע: התחילו תמיד מ-alias. אם ה-alias נהיה מסובך (יותר מ-3 שורות) — העבירו לסקריפט. אם הסקריפט שימושי גם לאחרים — הפכו ל-extension.
כתבו את הלולאה הראשונה שלכם. העתיקו והריצו:
# דוח issues — מספר, כותרת, labels
gh issue list --json number,title,labels --jq \
'.[] | "#\(.number) \(.title) [\(.labels | map(.name) | join(", "))]"'
אם עבד — הוסיפו pipe ל-wc -l כדי לספור כמה issues יש לכם. זה הדפוס הבסיסי: שליפה, עיבוד, הצגה.
כתבו סקריפט בשם pr-report.sh שמדפיס דוח PRs מפורט:
- צרו קובץ
pr-report.shעם#!/bin/bashו-set -euo pipefailבראש - הוסיפו שורה שמדפיסה כמה PRs פתוחים יש (
gh pr list --json number --jq 'length') - הוסיפו רשימת PRs עם מספר, כותרת, author ותאריך יצירה
- הוסיפו שורה שמוצאת את ה-PR הכי ותיק (הישן ביותר)
- הוסיפו
chmod +x pr-report.shוהריצו
פתרון לבדיקה עצמית:
#!/bin/bash
set -euo pipefail
echo "=== PR Report for $(gh repo view --json nameWithOwner --jq '.nameWithOwner') ==="
echo ""
COUNT=$(gh pr list --json number --jq 'length')
echo "Open PRs: $COUNT"
echo ""
if [ "$COUNT" -gt 0 ]; then
echo "--- PR List ---"
gh pr list --json number,title,author,createdAt --jq \
'.[] | "#\(.number) \(.title) by \(.author.login) (\(.createdAt[:10]))"'
echo ""
echo "--- Oldest PR ---"
gh pr list --json number,title,createdAt --jq \
'sort_by(.createdAt) | .[0] | "#\(.number) \(.title) (created \(.createdAt[:10]))"'
else
echo "No open PRs!"
fi
כתבו סקריפט auto-pr.sh שמבצע את כל תהליך ה-PR בפקודה אחת:
- מקבל כפרמטר ראשון את שם ה-branch (
$1) וכפרמטר שני את כותרת ה-PR ($2) - יוצר branch חדש (
git checkout -b $1) - עושה commit לכל הקבצים שנערכו (
git add -A && git commit) - דוחף ל-remote (
git push -u origin $1) - יוצר PR עם הכותרת שהתקבלה (
gh pr create) - מוסיף label אוטומטי (
gh pr edit --add-label) - מדפיס את ה-URL של ה-PR
טיפים:
- הוסיפו בדיקה ב-
ifשיש staged changes לפני ה-commit - השתמשו ב-
set -euo pipefailבתחילת הסקריפט - שמרו את ה-PR number מ-
gh pr create --json number --jq '.number'
תמיד הוסיפו set -euo pipefail בתחילת כל סקריפט. בלי זה: (1) set -e — שגיאה בפקודה אחת לא עוצרת את הסקריפט, והפקודות הבאות רצות על נתונים שגויים. (2) set -u — משתנה לא מוגדר לא מחזיר שגיאה ומוחלף בריק. (3) set -o pipefail — שגיאה באמצע pipe לא נתפסת. שלושת אלה ביחד מונעים את רוב הבאגים בסקריפטי shell.
2.8 Extensions — הרחבת gh עם תוספים
Extensions הם תוספים שמרחיבים את gh עם יכולות שלא קיימות בגרסה הבסיסית. כל extension מוסיף פקודת gh חדשה — כאילו היא חלק מהכלי המקורי. יש מאות extensions מהקהילה, מ-dashboards אינטראקטיביים דרך כלי ניקוי branches ועד generators של changelogs. והחלק הכי טוב: ליצור extension משלכם זה עניין של דקות, לא ימים.
Extension יכול להיות כתוב בכל שפה — Bash, Go, Python, Ruby, ואפילו compiled binary. כשמתקינים extension, gh מוריד אותו ל-directory מיוחד ומנגיש אותו כפקודה. אין צורך ב-PATH ידני או קונפיגורציה — הכל אוטומטי.
מציאה והתקנה של extensions
# חיפוש extension לפי מילת מפתח
gh extension search dashboard
gh extension search changelog
gh extension search "branch cleanup"
# התקנה
gh extension install dlvhdr/gh-dash # dashboard אינטראקטיבי (TUI)
gh extension install seachicken/gh-poi # ניקוי branches ממוזגים
gh extension install vilmibm/gh-changelog # יצירת changelog אוטומטי
gh extension install mislav/gh-branch # ניהול branches מתקדם
gh extension install gennaro-tedesco/gh-f # fuzzy finder לריפו
# שימוש — פשוט מריצים
gh dash # פותח dashboard
gh poi # מנקה branches ישנים
gh changelog # מייצר changelog
gh f # fuzzy find
ניהול extensions מותקנים
# רשימת כל ה-extensions המותקנים
gh extension list
# עדכון extension ספציפי
gh extension upgrade gh-dash
# עדכון כל ה-extensions בבת אחת
gh extension upgrade --all
# הסרה
gh extension remove gh-dash
Extensions מומלצים
| Extension | פקודה | מה זה עושה | למי מתאים |
|---|---|---|---|
dlvhdr/gh-dash | gh dash | Dashboard אינטראקטיבי (TUI) לניהול PRs ו-issues | כולם |
seachicken/gh-poi | gh poi | ניקוי branches ממוזגים שכבר לא צריך | כולם |
vilmibm/gh-changelog | gh changelog | יצירת changelog אוטומטי מ-PRs ו-commits | maintainers |
mislav/gh-branch | gh branch | ניהול branches מתקדם — fuzzy search, checkout | מי שעובד עם הרבה branches |
github/gh-copilot | gh copilot | Copilot CLI — explain ו-suggest מהטרמינל | מי שיש לו Copilot |
התקינו את gh-dash — ה-extension הכי פופולרי. זה dashboard אינטראקטיבי שמציג PRs ו-issues:
gh extension install dlvhdr/gh-dash
gh dash
זה יפתח ממשק TUI (Text User Interface) עשיר בטרמינל. אפשר לנווט עם חצים, לפתוח PR עם Enter, לראות diff, ולנהל reviews — הכל בלי דפדפן. לחצו q כדי לצאת.
יצירת extension משלכם
יצירת extension ב-gh היא פשוטה להפתיע. בבסיסו, extension הוא פשוט סקריפט executable שמתחיל ב-gh-. אפשר לכתוב אותו ב-Bash, Go, Python, או כל שפה אחרת.
# 1. יצירת extension חדש (Bash)
gh extension create my-stats
cd gh-my-stats
# 2. זה יצר מבנה תיקיות עם קובץ gh-my-stats
# ערכו אותו:
#!/bin/bash
# gh-my-stats — Extension שמציג סטטיסטיקות ריפו
set -euo pipefail
REPO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner' 2>/dev/null)
if [ -z "$REPO" ]; then
echo "Error: not in a git repository"
exit 1
fi
echo "=== Stats for $REPO ==="
echo ""
# נתונים בסיסיים
gh api repos/{owner}/{repo} --jq \
'"Stars: \(.stargazers_count)
Forks: \(.forks_count)
Watchers: \(.subscribers_count)
Language: \(.language)
License: \(.license.spdx_id // "None")"'
echo ""
# PRs ו-Issues
echo "Open PRs: $(gh pr list --json number --jq 'length')"
echo "Open Issues: $(gh issue list --json number --jq 'length')"
echo ""
# Top 5 contributors
echo "--- Top 5 Contributors ---"
gh api repos/{owner}/{repo}/contributors --jq \
'.[:5] | .[] | " \(.login): \(.contributions) commits"'
# 3. הפכו ל-executable
chmod +x gh-my-stats
# 4. התקינו מהתיקייה המקומית
gh extension install .
# 5. עכשיו אפשר להשתמש
gh my-stats
שימו לב למבנה: extension הוא פשוט קובץ executable שמתחיל ב-gh-. כשמריצים gh my-stats, gh מחפש קובץ בשם gh-my-stats בתיקיית ה-extensions ומריץ אותו. כל מה שהסקריפט מדפיס ל-stdout נראה למשתמש.
אם ה-extension עובד טוב ואתם רוצים לשתף אותו עם הקהילה:
# צרו ריפוזיטורי ב-GitHub (שם חייב להתחיל ב-gh-)
gh repo create gh-my-stats --public --source . --push
# עכשיו כולם יכולים להתקין:
# gh extension install your-username/gh-my-stats
צרו extension בשם gh-health שבודק את "בריאות" הריפוזיטורי:
- הריצו
gh extension create health - ערכו את הסקריפט כדי שיבדוק:
- כמה PRs פתוחים יותר מ-7 ימים (ישנים)
- כמה issues בלי label
- כמה issues בלי assignee
- האם יש README.md
- האם יש LICENSE
- הוסיפו "ציון בריאות" (0-100) על בסיס הבדיקות
- התקינו מקומית עם
gh extension install . - הריצו
gh healthובדקו את הפלט
בונוס: פרסמו את ה-extension ב-GitHub repo ציבורי.
2.9 אוטומציות מורכבות — Release ו-Issue Triage
עכשיו שיש לנו aliases, gh api, JQ, scripting ו-extensions — הגיע הזמן לשלב הכל לאוטומציות מורכבות שפותרות בעיות אמיתיות. הסעיפים הקודמים נתנו לנו את חלקי הלגו; עכשיו נבנה מהם מבנים שלמים.
נראה שני תרחישים שכל מפתח או maintainer נתקל בהם באופן קבוע: release workflow (שחרור גרסה) ו-issue triage (מיון issues). שני התרחישים האלה כוללים כמה צעדים שחוזרים על עצמם, דורשים זהירות, וקל לטעות בהם ידנית — בדיוק סוג המשימות שכדאי לאטמט.
אוטומציה 1: Release workflow מלא
Release הוא תהליך שמערב כמה צעדים מוגדרים: יצירת tag, דחיפה ל-remote, יצירת release עם changelog, ולפעמים גם עדכון documentation ושליחת התראות. כשעושים את זה ידנית, קל לשכוח צעד (למשל, לשכוח לדחוף את ה-tag), או לעשות טעות (למשל, ליצור tag על branch לא נכון). סקריפט release אוטומטי מצמצם את כל התהליך לפקודה אחת ומבטיח שכל הצעדים מתבצעים בסדר הנכון עם הבדיקות הנכונות:
#!/bin/bash
set -euo pipefail
# release.sh — Release automation
# שימוש: ./release.sh 1.2.0
VERSION=$1
if [ -z "$VERSION" ]; then
echo "Usage: ./release.sh "
echo "Example: ./release.sh 1.2.0"
exit 1
fi
# בדיקה שאנחנו על main
BRANCH=$(git branch --show-current)
if [ "$BRANCH" != "main" ]; then
echo "Error: Must be on 'main' branch (currently on '$BRANCH')"
exit 1
fi
# בדיקה שאין שינויים לא שמורים
if ! git diff --quiet HEAD; then
echo "Error: Uncommitted changes. Commit or stash first."
exit 1
fi
echo "Creating release v${VERSION}..."
# יצירת tag
git tag -a "v${VERSION}" -m "Release v${VERSION}"
echo " Tag v${VERSION} created"
# דחיפה
git push origin main --tags
echo " Pushed to remote"
# יצירת release עם changelog אוטומטי
gh release create "v${VERSION}" \
--title "Release v${VERSION}" \
--generate-notes \
--latest
echo " Release created"
# הדפסת URL
URL=$(gh release view "v${VERSION}" --json url --jq '.url')
echo ""
echo "Release v${VERSION} published!"
echo "URL: $URL"
שימו לב לבדיקות בתחילת הסקריפט — הן מונעות טעויות נפוצות. בלעדיהן, אפשר בטעות ליצור release מ-branch לא נכון, או עם שינויים לא שמורים שלא ייכנסו ל-release. זה דוגמה מצוינת ל-"defensive scripting" — הסקריפט מגן על עצמו מפני שגיאות אנוש.
עכשיו במקום תהליך ידני של 5-10 דקות (שבמהלכו אפשר לשכוח צעד), זה שורה אחת:
./release.sh 1.2.0
ואם רוצים לשלב את הסקריפט עם GitHub Actions — אפשר ליצור workflow dispatch שמקבל את מספר הגרסה כ-input ומריץ את אותם צעדים. בפרק 8 (API & Webhooks) נראה איך לעשות את זה.
אוטומציה 2: Issue triage אוטומטי
ריפוזיטורים פעילים צוברים issues בקצב מהיר — ללא label, בלי assignee, ובלי אף אחד שטיפל בהם. אחרי כמה שבועות יש עשרות (או מאות) issues לא מטופלים, ואי אפשר להבין מה דחוף ומה לא. סקריפט triage אוטומטי עובר על כל ה-issues, מסווג אותם, מקצה אחראיים, ומסמן issues ישנים. במקום לבזבז שעה בשבוע על triage ידני, הסקריפט עושה את זה ב-30 שניות:
#!/bin/bash
set -euo pipefail
# triage.sh — Issue triage automation
echo "=== Issue Triage for $(gh repo view --json nameWithOwner --jq '.nameWithOwner') ==="
echo "Started at $(date)"
echo ""
TOTAL=0
# 1. Issues בלי label — סימון ל-triage
echo "--- Unlabeled Issues ---"
gh issue list --json number,labels --jq \
'.[] | select(.labels | length == 0) | .number' | \
while read -r num; do
gh issue edit "$num" --add-label "needs-triage"
echo " #$num -> needs-triage"
TOTAL=$((TOTAL + 1))
done
# 2. Issues עם label "bug" בלי assignee — הקצאה אוטומטית
echo ""
echo "--- Unassigned Bugs ---"
gh issue list --label bug --json number,assignees --jq \
'.[] | select(.assignees | length == 0) | .number' | \
while read -r num; do
gh issue edit "$num" --add-assignee @me
echo " #$num -> assigned to me"
TOTAL=$((TOTAL + 1))
done
# 3. Issues ישנים מאוד (יותר מ-180 יום) — הוספת label "stale"
echo ""
echo "--- Stale Issues (180+ days) ---"
CUTOFF=$(date -d "180 days ago" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -v-180d +%Y-%m-%dT%H:%M:%SZ)
gh issue list --json number,updatedAt --jq \
".[] | select(.updatedAt < \"$CUTOFF\") | .number" | \
while read -r num; do
gh issue edit "$num" --add-label "stale"
gh issue comment "$num" --body "This issue has been open for 180+ days without activity. Marking as stale."
echo " #$num -> stale"
TOTAL=$((TOTAL + 1))
done
echo ""
echo "=== Triage complete ==="
echo "Processed actions: $TOTAL"
שילוב: Alias שמפעיל את הסקריפטים
הדבר האחרון שנעשה הוא לחבר את הסקריפטים ל-aliases. למה? כי aliases זמינים מכל ריפוזיטורי — לא צריכים שהסקריפט יהיה בתיקייה הנוכחית. שמרו את הסקריפטים במקום קבוע (למשל ~/scripts/) והפנו אליהם מ-aliases:
# alias ל-release
gh alias set --shell release \
'bash ~/scripts/release.sh "$1"'
# alias ל-triage
gh alias set --shell triage \
'bash ~/scripts/triage.sh'
# שימוש:
gh release 1.2.0
gh triage
צרו סקריפט release.sh משלכם שעושה את כל הצעדים:
- מקבל מספר גרסה כפרמטר (
$1) - מוודא שאנחנו על branch
main - מוודא שאין uncommitted changes
- יוצר annotated tag (
git tag -a) - דוחף ל-remote
- יוצר release עם
--generate-notes - מדפיס URL של ה-release
בונוס: הוסיפו flag --pre-release שיוצר pre-release (עם gh release create --prerelease).
2.10 סיכום ומבט קדימה
- Aliases — שלוש רמות (פשוט, פרמטרים, shell) שהופכות תהליכים חוזרים לפקודה אחת. ה-5 aliases שהגדרנו הם הבסיס לעבודה יומיומית
- gh api — גישה ישירה לכל endpoint של GitHub API, גם REST וגם GraphQL. אימות אוטומטי, pagination, ו-JQ מובנה. עדיף על curl כמעט תמיד
- JQ — שפת הסינון שהופכת JSON גולמי לפלט שימושי. דפוסי select, map, sort ו-string interpolation מכסים 95% מהמקרים
- gh pr / issue / repo — מחזור חיים מלא מהטרמינל. מיצירה דרך review ועד merge/close. הפקודות הכי שימושיות: create, list, view, merge, edit
- gh run — ניטור GitHub Actions בזמן אמת.
gh run watchהיא הפקודה הכי חזקה — צופים ב-CI בלי דפדפן - Scripting — הדפוס "שליפה, עיבוד, פעולה" הוא הבסיס לכל אוטומציה.
set -euo pipefailחובה בכל סקריפט - Extensions — אקוסיסטם שלם של תוספים (gh-dash, gh-poi, gh-changelog) ויכולת ליצור extension משלכם תוך דקות
- אוטומציות מורכבות — שילוב של aliases + scripting + extensions יוצר כלים כמו release automation ו-issue triage אוטומטי
צרו את ה-alias my-prs עכשיו — gh alias set my-prs 'pr list --state open --assignee @me' — והתחילו כל בוקר עם gh my-prs. זה לוקח 10 שניות להגדרה וחוסך דקות כל יום. ברגע שתרגישו את הקסם של alias אחד, תרצו עוד — וזה הצעד הראשון לשליטה מלאה מהטרמינל.
- מה ההבדל בין alias רגיל (
gh alias set) ל-shell alias (gh alias set --shell)? מתי משתמשים בכל אחד? - למה
gh apiעדיף עלcurlלשאילתות GitHub? ציינו לפחות 3 יתרונות. - מה עושה
--paginateב-gh api? למה זה חשוב כשמשלפים רשימות ארוכות? - כתבו ביטוי JQ שמסנן רק issues פתוחים ומדפיס את המספר והכותרת שלהם בפורמט
#42 title. - מה הפקודה לצפייה בזמן אמת ב-GitHub Actions workflow run? מה קורה אם ה-run נכשל — איך רואים מה נכשל ואיך מריצים מחדש?
- יומית (בוקר):
gh my-prs— בדקו PRs שמחכים לכם.gh my-issues— בדקו issues פתוחים שלכם - יומית (אחרי push):
gh run watch— ודאו ש-CI עובר. אם נכשל:gh run view --log-failed - יומית (לפני merge):
gh pr checks— ודאו שכל הבדיקות עברו לפני מיזוג - שבועית: הריצו את סקריפט ה-triage — וודאו שאין issues ללא label או assignee
- שבועית:
gh poi(או cleanup alias) — ניקוי branches ממוזגים שכבר לא צריך - חודשית:
gh extension upgrade --all— עדכנו extensions לגרסאות אחרונות - חודשית: סקרו את ה-aliases שלכם — יש כאלה שלא השתמשתם בהם? מחקו. חסר alias? הוסיפו
- ☐ בדקתי ש-gh מותקן ומאומת (
gh --version,gh auth status) - ☐ יצרתי alias פשוט (
gh alias set my-prs) - ☐ יצרתי alias עם פרמטרים (
$1) - ☐ יצרתי shell alias עם
--shell - ☐ ביצעתי קריאת
gh apiראשונה (REST) - ☐ ניסיתי GraphQL עם
gh api graphql - ☐ סיננתי JSON עם
--jq(select, map, string interpolation) - ☐ ביצעתי מחזור PR מלא מהטרמינל (create, view, close/merge)
- ☐ ניטרתי workflow עם
gh run watch(או בדקתי ש-gh run listעובד) - ☐ כתבתי סקריפט דוח PRs (
pr-report.sh) - ☐ כתבתי סקריפט אוטומציה (
auto-pr.shאו triage) - ☐ התקנתי extension (
gh-dash) - ☐ יצרתי extension מותאם (
gh-my-statsאוgh-health) - ☐ יש לי לפחות 5 aliases מוגדרים (
gh alias list)
מה ללמוד הלאה
הפרק הזה כיסה את הבסיס והבינוני של gh CLI. מכאן יש כמה כיוונים להמשיך:
- gh Codespaces — ניהול סביבות פיתוח בענן מהטרמינל.
gh codespace create,gh codespace ssh - gh Projects — ניהול project boards (v2) מהטרמינל.
gh project list,gh project item-add - gh Secret — ניהול secrets של ריפוזיטורי וארגון.
gh secret set,gh secret list - gh Variable — ניהול environment variables.
gh variable set - Advanced scripting — שילוב gh עם כלים כמו fzf (fuzzy finder), tmux (terminal multiplexer), ו-notify-send (notifications)
את כל אלה תוכלו לחקור לבד — עם הבסיס שבניתם בפרק הזה, כל פקודת gh חדשה תיראה מוכרת.
בפרק הבא: נלמד להקים אתרים חינמיים עם GitHub Pages — ונשתמש ב-Actions (פרק 1) ו-CLI (הפרק הנוכחי) כדי לפרסם אותם אוטומטית. אם יצרתם aliases בפרק הזה, הם כבר יעזרו לכם שם.