חזרה

הפעלה ידנית של Github actions מתוך גוגל סקריפט

כהמשך לפוסט על ניטור פעילות אתרים באמצעות Google scripts, הרחבה לשילוב עם פלטפורמה נוספת לצורך תיקון תקלות אוטומטי >>>


כהמשך לפוסט הזה בו פירטתי איך להשתמש ב-Google Apps scripts כדי לשלוח בקשות לאתר על מנת לוודא שהוא פעיל וללא תקלות, יצא לי להוסיף עוד רובד על העניין, והרי הכל לפניכם. בואו נתחיל מהתחלה:

הבעיה

הבלוג הזה, אם שמתם לב, רץ על פלטפורמת בלוגים שנקראת Ghost. בעיקרון - זה ממש כלי יעיל, מהיר ונוח מאוד - ולדעתי הרבה יותר טוב מוורדפרס והאיזור.
Ghost עובד בצורה כזו, שיש מערכת בשם "ערכת נושא" שהיא אחראית בערך על כל ההיבטים בבלוג, החל מהארכיטקטורה הבסיסית של הפוסטים, והיא זו שבפועל מנגישה לקורא, למשתמש, את הפוסט שהוא קורא כרגע. היא לוקחת את הפוסט שמאוחסן במסד הנתונים כטקסט בלתי קריא, והופכת אותו, לפי הכללים שמוגדרים לה והעיצובים וכו', לדף נקי ומסודר.

כל שינוי בעיצוב או במבנה (גם ה'תיכנותי') של האתר - קורה ב-Ghost דרך שינויים שעורכים בערכת הנושא.

ערכת הנושא בנויה מקבצי handlebars (סיומת hbs. וכמובן, קבצי CSS ו-JS) וכאן אפשר ללמוד הכל, בערך, על מה שאפשר להגדיר ולשנות בזה.

עד כאן.
מה שקרה אצלי, זה שמשום מה, האתר כאילו שכח מידי פעם את הקובץ של ערכת הנושא שהכנתי לו, וכאשר קורית כזו "שיכחה" - האתר מחזיר לכל מי שנכנס - סטטוס 503 - שגיאת תחזוקה - וכותב שהקובץ של ערכת הנושא לא נמצא.

בכל פעם שכזה דבר קרה, הסקריפט גוגל היה מתריע לי דרך המייל - כמו שרואים בפוסט הנ"ל - ומה שהיה עליי לעשות זה להיכנס לניהול של האתר, ולהעלות מחדש את קובץ ערכת הנושא, והכל מסתדר.

הייתי חייב למצוא משהו שיעשה את זה אוטומטי.

שימו לב - מי שהיה מזהה כל פעם את הנפילה באתר - היה הגוגל סקריפט הזכור.

הפתרון

לאחר דשדוש קצר, גיליתי את הדבר הזה.

מה שיש כאן זה בעצם "אפליקציית" גיטהב שבנו המפתחים של Ghost, שמאפשרת למפתחי ערכות נושא, לטעון אותן בצורה אוטומטית לאתר הרצוי, היישר מהגיטהב שבו נמצאת ערכת הנושא! הדבר מתבצע באמצעות שילוב של ה-API של פאנל הניהול Ghost, והפלטפורמה - היחסית חדשה - שנקראת Github actions - שמאפשרת להריץ פקודות ממגוון עצום של מערכות, על המאגרים והתוכן של המפתח בגיטהב.

כל העבודה מול Github actions מתבצעת על ידי קבצי הגדרות - yml - שצריך להניח בתוך התיקייה github/workflows. במאגר הרצוי, ובתוך הקבצים יש לכתוב את ההנחיות הרצויות ל-actions, והן מתבצעות אוטומטית.

באפליקציה הנוכחית - כך נראה קובץ ה-workflow של המאגר, בערך:

name: Deploy Theme

on:
  schedule:
    - cron:  '*/15 * * * *'
      
jobs:
  deploy:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@v2
      - name: Deploy Ghost Theme
        uses: TryGhost/action-deploy-theme@v1.4.0
        with:
          api-url: ${{ secrets.GHOST_ADMIN_API_URL }}
          api-key: ${{ secrets.GHOST_ADMIN_API_KEY }}
          theme-name: "casper-rtl"

בקטע של on: מגדירים פרמטר לזמן ההרצה של הפעולה. אפשר להריץ את הפעולה בצורה מתוזמנת, כלומר אחת ל-X דקות וכדו', ואפשר להריץ אותה בתגובה למגוון אירועים במאגר. כגון Pull requests או commits או אפילו לייקים וכו'. כאן אפשר לראות את כל האפשרויות.

בקטע jobs: זה כמובן הפעולה עצמה, על איזו מערכת היא תתבצע ומה בעצם היא תעשה, כמו כן ניתן לראות בסוף - את הפרמטרים והמשתנים שמועברים אליה - במקרה שלנו אלו אמצעי האימות מול ה-API של Ghost - ה-KEY וה-URL, שניהם מאוחסנים ב-secrets של המאגר. (אני מוסיף הסבר לעבודה עם האפליקציה הזו, כולל הסבר על דרך העבודה עם ה-API וה-secret. בסוף הפוסט).

ה-github actions הזה עובד מעולה. ואני החלטתי לנצל אותו לצרכיי - כך שאאחסן את ערכת הנושא בגיטהב, וה-action הזה יידחף אותה לאתר שלי כל פעם שאצטרך. אבל הבעיה שלי היתה עכשיו שאני צריך להריץ אותו ידנית - ברגע שמזוהית קריסה של האתר (עד עכשיו לא הבנתי מה גורם לזה 😕).

בשביל להריץ github action כזה בצורה ידנית, צריך להשתמש בהגדרה הזו בקטע on:

on:
  repository_dispatch:
    types: [event-message]

כאן אפשר לקרוא על הפרטים של זה.

ההגדרה הזו קובעת שגיטהב יחכה להודעה (מסוג מסוים) שמכילה את המילים "event-message" - ברגע שמתקבלת כזו הודעה ממני - הפקודות שב-Github action ירוצו.

כדי לשלוח כזו התראה-הודעה לגיטהב, אפשר להשתמש בכל כלי לביצוע פקודת POST בפרוטוקול HTTP. לדוגמא CURL או fetch ב-javascript.

דוגמא ל-CURL שישלח כזו הודעה לגיטהב (CURL זה כלי לשליחת בקשות במגוון של מערכות, כולל BASH - לינוקס או powershell):

curl -H "Accept: application/vnd.github.everest-preview+json" \
    -H "Authorization: token {my-token}" \
    --request POST \
    --data '{"event_type": "event-message"}' \
    https://api.github.com/repos/me/my-repo/dispatches

עם הנתונים הנכונים במקום {my-token} והכתובת הנכונה של הריפו.
את הטוקן אפשר להוציא בקלות כאן, לצורך העניין מספיקה כאן scope (הרשאה) על כל מה שתחת הכותרת repo.

כעת אם נרצה להמיר את הפקודה הזו ל-fetch של javascript - זה ייראה בערך כך:

var myHeaders = {
  "Authorization": "token {my-token}",
  "Accept": "application/vnd.github.everest-preview+json"
}
var requestOptions = {
  contentType: 'application/json',
  method: 'POST',
  headers: myHeaders,
  body: '{"event_type":"start-example-workflow"}',
};
fetch("https://api.github.com/repos/me/my-repo/dispatches", requestOptions);

הביצוע

כאשר מריצים את הפקודות הללו, מתחיל את פעולתו Github action - שמעלה את ערכת הנושא לאתר שלי.

כעת מה שאני צריך זה להכניס בגוגל סקריפט - שבודק את תקינות האתר - שברגע שהוא מקבל סטטוס 503 מהאתר - כלומר שיש בעיה עם הערכת נושא, יריץ את הפקודה הזו.

כאן ישנה בעיה קטנה. אמנם Google apps script מבוסס javascript, אבל ישנם המון חלקים שאינם קיימים בו. לדוגמא Fetch...
בגוגל סקריפט ישנו שירות תחליף ל-fetch, והשם שלו הוא UrlFetchApp. יש לו פרמטרים אחרים אותם ניתן לראות כאן. אחד מהפרמטרים ששונים בו מ-fetch רגיל הוא שה-body של הבקשה, מכונה "payload" במקום פשוט body.

לכן נצטרך לשנות כאן קצת את הבקשה, וכך בערך היא תיראה בגוגל סקריפט:

function run() {     
  var headers = {
    "Authorization": "token {my-token}",
    "Accept": "application/vnd.github.everest-preview+json",
    "content-Type": "application/json"
  };
  var options = {
    "headers": headers,
    "method" : "POST",
    "payload" : '{"event_type":"fix-website"}'
  };
  var response = UrlFetchApp.fetch("https://api.github.com/repos/me/reponame/dispatches", options);
}

כמובן שאני מגדיר בסקריפט - שהוסבר בפוסט הזה - תנאי שאם התשובה של בדיקת הסטטוס של האתר - איננה 200 (200 זו התשובה שאומרת 'הכל בסדר') - יריץ את הפונקציה הזו (()run).


יצירת המפתחות הנדרשים ב-Ghost:

אם ברצונכם להשתמש באופציה שהוזכרה כאן, להכניס בצורה אוטומטית לאתר שלכם את ערכת הנושא מגיטהב, תצטרכו להיכנס לפאנל הניהול של ה-Ghost שלכם > integrations ואז לחצו על add custom integration.

תנו לה שם, והעתיקו את המפתחות הבאים -

  • Admin API Key
  • API URL

לכו להגדרות של הריפו בגיטהב שם אתם מאחסנים  את ערכת הנושא, היכנסו ל-secrets, וצרו secret חדש עם השם GHOST_ADMIN_API_KEY, בתור ערך (value) הכניסו את ה-admin API key.

צרו secret נוסף עם השם GHOST_ADMIN_API_URL, בתור הערך שלו הכניסו את API URL.

מרגע שה-secrets מוגדרים - לא ניתן לראות אותם ולערוך יותר. רק למחוק.
כעת הסקריפט ישתמש ב-secrets בתור התעודות כניסה שלו לשימוש מול האתר שלכם, דרך ה-API.
עקבו אחרי הלוגים שנמצאים בטאב של github acions בריפו (הטאב actions) - וודאו שאין תקלות בקוד או טעויות ב-secrets, שימנעו מהפקודות לרוץ כראוי:

בדיקה של הלוג בגיטהב. הכל תקין

אם יש לכם שאלות, תוכלו לשאול אותי כאן דרך הדף 'צור קשר', או לפתוח issue בגיטהב.

הריפו של ה'פרוייקט' בגיטהב נמצא כאן 👇 מוזמנים!
יש כאן ערכת נושא בעברית ל-Ghost. זו הערכה עליה רץ האתר הנוכחי... בצורה אוטומטית כמובן 😉 Ghost RTL Repo


תודה ל-Dovid מפורום תחומים על ההארה בנוגע להבדל בין גוגל סקריפט ל-JS רגיל במבנה הפרמטרים של Fetch. לחצו כאן כדי לראות את הדיון.


אם יש לכם איזו שאלה ❔✨ או כל תגובה 💬, הארה 💡 והערה ❕ שהיא על הפוסט - אשמח מאוד! אם תכתבו אותה בהערות כאן למטה
פשוט להתחבר עם חשבון גיטהב ולהגיב 🎉