עמוד המסירה מציג פסק זמן ו-Jenkins לא רושם דבר, וזה הסימן לחיבור שמעולם לא הגיע. GitHub שולח webhook כבקשת HTTP POST יוצאת מהתשתית שלו אל payload URL שהגדרתם. VPN מגן על Jenkins בכך שהוא דוחה בדיוק סוג כזה של חיבור. שום דבר לא שבור בשני הצדדים. הבעיה היא בכיוון הבקשה.

מה המסירה בעצם מנסה לעשות

GitHub מפענח את שם המארח ב-payload URL ומתחבר אליו מהאינטרנט הציבורי. אם אותו URL מצביע על כתובת פרטית, או על שם שמתפענח רק בתוך הרשת שלכם, הניסיון נכשל לפני שנשלחת בקשה כלשהי. אם הוא מצביע על שם ציבורי שהקצה שלכם משליך, הניסיון במקום זאת מסתיים בפסק זמן.

ההבחנה הזו חשובה לאבחון. כשל DNS ופורט מסונן נראים שניהם כאילו דבר לא קרה בצד של Jenkins, ושניהם מופיעים ב-GitHub כמסירה כושלת עם סיבה שונה מצורפת. קראו את הסיבה הזו לפני שאתם משנים את ה-URL.

מנהרה שמחייגת החוצה לא יוצרת מאזין. זה החלק שאנשים מצפים שיעבוד אחרת.

שלוש דרכים לתקן את כיוון החיבור

כל פתרון משנה מי יוזם את החיבור, ויש רק שלוש צורות.

ApproachWho initiatesWhat you give up
Relay serviceAn outbound client inside the networkA third party sees every payload
Reverse tunnel or ingressThe public edge, into a controlled listenerAn inbound surface you must secure
Runner or pollingThe agent, outbound to GitHubInstant delivery, replaced by a schedule

תשאול הוא הפחות אלגנטי והקל לתפעול. relay שומר על משוב כמעט מיידי בלי לפתוח פורט. runner הוא בדרך כלל התשובה הנכונה כאשר סודיות ה-payload שוללת צד שלישי, כי המשימה יכולה לרוץ על מכונה שכבר יושבת בתוך הרשת.

בחרו לפי מה שאתם יכולים לתפעל, לא לפי מה שנשמע מודרני.

העבירו מסירה החוצה עם smee

צרו ערוץ בשירות ה-relay ושמרו את ה-URL שלו. בתוך הרשת, התקינו את הלקוח והעבירו מסירות לנתיב ש-Jenkins מצפה לו. ה-payload URL בהגדרות המאגר הופך ל-URL של הערוץ, כשסוג התוכן מוגדר ל-application/json.

sudo npm install --global smee-client
smee -u CHANNEL_URL --path /github-webhook/ --port 8080

שלושה פרטים מכריעים אם זה יעבוד. הנתיב חייב להתאים למה ש-Jenkins מצפה לאירועי GitHub, שברירת המחדל שלו היא /github-webhook/. Jenkins חייב להאזין בפורט שנתתם ללקוח. וה-Jenkins URL שמוגדר במשימה חייב להתיישב עם הנתיב הזה, אחרת האירוע מגיע ואז נזרק.

חוסר התאמה בקו הנטוי בסוף מייצר 404 שנראה כמו כשל מסירה ואינו כזה.

להריץ אותו כך שישרוד את השבוע

לקוח בחזית מת עם הטרמינל, וה-webhooks עובדים יום ואז נעצרים. תנו לו unit עם Restart=always, הריצו אותו כמשתמש Jenkins, וקראו את ה-journal אחרי המסירה האמיתית הראשונה. דווקא הצעד האחרון הזה מפריד בין relay עובד ל-relay מוגדר.

[Unit]
Description=smee webhook relay
After=network.target

[Service]
Type=simple
Restart=always
RestartSec=2
User=jenkins
ExecStart=/usr/bin/smee -u CHANNEL_URL --path /github-webhook/ --port 8080

[Install]
WantedBy=multi-user.target

בדקו עם push אמיתי ולא עם כפתור שידור חוזר. שידור חוזר מפעיל את ה-payload השמור של ה-relay, לא את הנתיב מ-GitHub לערוץ שלכם, ולכן הוא יכול לעבור בעוד המסירה החיה עדיין נכשלת.

התריעו כאשר ה-unit נעצר. relay שנפל שקט מעצם הבנייה, והשקט הוא בדיוק מה שאתם כבר מאבחנים.

מה ה-relay יכול לראות, ומתי לא להשתמש בו

relay מסיים את ה-payload, ולכן הוא רואה שמות מאגרים, נתוני commit וכל מה שהאירוע נושא. התייחסו ל-URL של הערוץ כנקודת קצה ציבורית. החזיקו את ה-secret token של Jenkins מוגדר כדי שמסירות מזויפות יידחו, והגבילו את ה-token ש-Jenkins משתמש בו למינימום הנדרש.

אם סודיות ה-payload שוללת זאת, runner באחסון עצמי או מנהרה הפוכה מאומתת היא התשובה.

relay הוא עכשיו תשתית, ומגיעה לו אותה סקירה כמו ה-build שהוא מפעיל. סובבו את הערוץ אם הוא דולף, ורשמו את התאריך שבו אימתתם לאחרונה מסירה חיה. שימו את התאריך הזה ב-runbook ליד ה-URL של הערוץ. relay שאיש לא סקר במשך שנה הוא נקודת קצה ציבורית שאין לה בעלים.

מאמרים קשורים