Updates after the day-long updater overhaul:
- The csproj no longer has <UpdateInterval>7</UpdateInterval>; v1.2.9
switched to <UpdatePeriodically>false</UpdatePeriodically>, so the
VSTO runtime checks the .vsto manifest on every Outlook startup.
Both PROJECT-BRIEFING.md ("How releases work") and
AUTO-UPDATE-SETUP.md (section 5) now describe the on-startup model
instead of the weekly-poll model that was never operationally true.
- AUTO-UPDATE-SETUP.md also gets two new notes that came out of today:
what the "בדוק עדכונים" button can and can't do (informational only,
pointing at the in-process-update impossibility memo), and the
one-time uninstall+reinstall required when a developer's machine has
a dev-cert install that can't auto-update across to the prod cert.
No code change; no tag.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
20 KiB
מערכת עדכון אוטומטי — מדריך הקמה לצוות תשתיות
מסמך זה מסביר מה צריך להקים פעם אחת כדי שתוסף Klear ל-Outlook יוכל להתעדכן אוטומטית אצל כל עורכי הדין במשרד, וכיצד לשחרר עדכון חדש לאחר ההקמה.
קהל היעד: צוות תשתיות / DevOps / IT אדמין במרקוס-לוו. זמן הקמה משוער: 4-6 שעות פעם אחת. שחרור עדכון חדש לאחר ההקמה: 30 שניות (push tag) + 2-3 דקות (CI).
1. סקירת ארכיטקטורה
המנגנון מבוסס על ClickOnce — טכנולוגיה של Microsoft שמאפשרת ל-Outlook להתקין ולעדכן תוסף VSTO מ-URL חיצוני, כמו עדכון אוטומטי של אפליקציה.
┌──────────────────┐ git tag v1.0.1 ┌─────────────────────┐
│ מפתח (Chaim) ├──────────────────► │ Gitea repository │
└──────────────────┘ └──────────┬──────────┘
│
push event│
▼
┌─────────────────────┐
│ Windows Build Runner │ (VM ב-Coolify)
│ • restore + build │
│ • sign DLLs │
│ • mage → .vsto │
└──────────┬──────────┘
│ rsync
▼
┌─────────────────────┐
│ platform.dev │ (nginx)
│ /outlook-addin/ │
│ ├─ OutlookAddin.vsto
│ └─ Application Files/
└──────────┬──────────┘
│ HTTPS poll (כל 7 ימים)
▼
┌─────────────────────┐
│ 10 מחשבי עורכי דין │
│ ClickOnce + Outlook │
└─────────────────────┘
הצדדים:
- CI runner — מכונת Windows שבונה את הפרויקט, חותם את הקבצים, ומריץ את
mage.exeשיוצר את ה-.vstomanifest. - שרת הפצה — nginx שמשרת קבצים סטטיים תחת
/outlook-addin/. - תעודת חתימה — תעודת Code-Signing (self-signed) שצריכה להיות מותקנת כ-Trusted Publisher בכל מחשב לקוח, אחרת ClickOnce ידחה את ההתקנה.
- GPO — מנגנון Active Directory להפצת התעודה אוטומטית.
- Infisical — מאחסן את הסודות (cert thumbprint, SSH key, webhook URL).
- Mattermost — מתריע בהצלחה/כישלון לערוץ
#git-verelasim.
2. דרישות מקדימות
לפני שמתחילים, וודאו שיש לכם:
- גישת Admin ל-Coolify ב-
coolify.marcus-law.co.il(להקמת VM) - גישת root ל-
platform.dev.marcus-law.co.il - תפקיד Domain Admin ב-Active Directory (להפצת GPO)
- גישת Admin ל-Gitea ב-
gitea.dev.marcus-law.co.il - גישת Admin ל-Infisical (פרויקט
outlook-addin) - Webhook ל-Mattermost בערוץ
#git-verelasim - שם משתמש + סיסמה של חשבון EspoCRM Admin (להנפקת API keys ללקוחות)
3. שלבי הקמה (חד-פעמיים)
3.1 — הקמת Windows Build Runner
מטרה: VM שמריץ Gitea Actions runner ויכול לבנות פרויקטי VSTO.
-
ב-Coolify → צור VM חדש: Windows 11 Pro, 4 vCPU / 8 GB RAM / 80 GB דיסק.
-
התחבר ל-VM ב-RDP.
-
התקן את הכלים הבאים (כולם בחינם):
# Visual Studio Build Tools 2022 — כולל workloads נדרשים winget install Microsoft.VisualStudio.2022.BuildTools ` --override "--passive --wait --add Microsoft.VisualStudio.Workload.Office --add Microsoft.VisualStudio.Workload.ManagedDesktop --includeRecommended" # .NET Framework 4.8 Developer Pack (מספק mage.exe) winget install Microsoft.DotNet.Framework.DeveloperPack_4 # Windows 10 SDK (signtool.exe) winget install Microsoft.WindowsSDK.10.0.22621 # Git winget install Git.Git # NuGet CLI (לפעולות restore לפרויקטי .NET Framework legacy) choco install nuget.commandline -y # WSL Ubuntu — דרוש ל-rsync ב-CI workflow wsl --install -d Ubuntu -
הורד את
act_runner(Gitea Actions runner) מ-https://gitea.com/gitea/act_runner/releases. -
רשום את ה-runner ל-Gitea שלכם:
.\act_runner.exe register ` --no-interactive ` --instance https://gitea.dev.marcus-law.co.il ` --token <token-from-gitea-admin> ` --name "winbuild-01" ` --labels "windows" -
התקן את ה-runner כשירות Windows כדי שירוץ ברקע:
.\act_runner.exe daemon install net start act_runner -
ודא שהוא מופיע ב-Gitea:
https://gitea.dev.marcus-law.co.il/-/admin/runnersעם status online.
3.2 — יצירת תעודת Code-Signing
מטרה: תעודה שחותמת על קבצי DLL/EXE/manifest. ClickOnce ידרוש שהיא מותקנת כ-Trusted Publisher אצל הלקוחות.
ב-PowerShell על ה-Build Runner (כ-Administrator):
# יצירת תעודה לתקופה של 3 שנים
$cert = New-SelfSignedCertificate `
-Subject "CN=Marcus-Law Klear" `
-Type CodeSigningCert `
-CertStoreLocation Cert:\CurrentUser\My `
-NotAfter (Get-Date).AddYears(3) `
-KeyAlgorithm RSA `
-KeyLength 2048
# ה-thumbprint שצריך לשמור ב-Infisical
$thumbprint = $cert.Thumbprint
Write-Host "Thumbprint: $thumbprint"
# יצא PFX (כולל המפתח הפרטי — לגיבוי, **שמור באמצעי מאובטח**)
$pfxPassword = ConvertTo-SecureString -String "<password-חזק>" -Force -AsPlainText
Export-PfxCertificate -Cert $cert -FilePath C:\codesign.pfx -Password $pfxPassword
# יצא רק את החלק הציבורי (CER) — זה מה שמפיצים ללקוחות
Export-Certificate -Cert $cert -FilePath C:\codesign.cer
חשוב: שמור גיבוי של
codesign.pfx+ הסיסמה בכספת. אם המכונה תאבד, תצטרך אותם כדי להמשיך לחתום בעתיד באותה תעודה (אם תיצור חדשה, כל הלקוחות יקבלו "Unknown Publisher" עד שתפיץ את החדשה דרך GPO).
3.3 — שמירת סודות ב-Infisical
ב-Infisical, בפרויקט outlook-addin, environment prod (או dev אם אין הפרדה):
| שם המפתח | ערך | הערה |
|---|---|---|
CODESIGN_THUMBPRINT |
ה-$thumbprint משלב 3.2 |
מחרוזת hex של 40 תווים |
CODESIGN_PFX_BASE64 |
[Convert]::ToBase64String([IO.File]::ReadAllBytes("C:\codesign.pfx")) |
base64 של ה-PFX — לגיבוי בלבד, ה-CI לא משתמש בו ישירות |
CODESIGN_PASSWORD |
הסיסמה של ה-PFX | למקרה של בנייה ממכונה אחרת |
PLATFORM_DEV_SSH_KEY |
base64 של מפתח SSH פרטי (ed25519) שיש לו גישת write ל-/var/www/outlook-addin/ ב-platform.dev |
ייצור: ssh-keygen -t ed25519, אחר כך [Convert]::ToBase64String([IO.File]::ReadAllBytes("$HOME\.ssh\id_ed25519")) |
MATTERMOST_WEBHOOK_RELEASES |
URL של webhook לערוץ #git-verelasim |
מ-Mattermost → Integrations → Incoming Webhooks |
3.4 — הגדרת Gitea Actions Secrets
ב-Gitea: כנס לרפו espocrm-extensions/OutlookAddin → Settings → Actions → Secrets.
צור secret עבור כל אחד מהמפתחות שלמעלה (אותם שמות בדיוק):
CODESIGN_THUMBPRINTPLATFORM_DEV_SSH_KEYMATTERMOST_WEBHOOK_RELEASES
(שני האחרים, CODESIGN_PFX_BASE64 ו-CODESIGN_PASSWORD, לא נדרשים ב-CI כל עוד ה-PFX כבר מותקן ב-Cert:\CurrentUser\My של ה-Build Runner).
3.5 — הגדרת nginx ב-platform.dev
מטרה: השרת שעורכי הדין יורידו ממנו את ההתקנה והעדכונים.
התחבר ל-platform.dev.marcus-law.co.il כ-root:
# צור תיקייה
sudo mkdir -p /var/www/outlook-addin
sudo chown -R www-data:www-data /var/www/outlook-addin
# הוסף את משתמש ה-SSH של ה-CI לקובץ authorized_keys
sudo mkdir -p /root/.ssh
echo "ssh-ed25519 AAAA… klear-ci@build-runner" >> /root/.ssh/authorized_keys
sudo chmod 600 /root/.ssh/authorized_keys
צור קובץ /etc/nginx/sites-available/outlook-addin.conf:
server {
listen 443 ssl http2;
server_name platform.dev.marcus-law.co.il;
ssl_certificate /etc/letsencrypt/live/platform.dev.marcus-law.co.il/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/platform.dev.marcus-law.co.il/privkey.pem;
location /outlook-addin/ {
alias /var/www/outlook-addin/;
autoindex off;
# MIME types שדרושים ל-ClickOnce
types {
application/x-ms-application application;
application/x-ms-manifest manifest;
application/octet-stream vsto;
application/octet-stream deploy;
}
# לא לכאש — חייבים לקבל את הגרסה הכי חדשה
add_header Cache-Control "no-cache, must-revalidate";
}
}
הפעל:
sudo ln -s /etc/nginx/sites-available/outlook-addin.conf /etc/nginx/sites-enabled/
sudo nginx -t # ודא שאין שגיאה תחבירית
sudo systemctl reload nginx
בדוק שהשרת עונה (גם אם אין עוד תוכן):
curl -I https://platform.dev.marcus-law.co.il/outlook-addin/
# צריך לקבל 403 או 404 — לא 502 או SSL error
3.6 — הפצת תעודת חתימה ל-10 מחשבי עורכי הדין דרך GPO
מטרה: כל מחשב לקוח חייב לסמוך על תעודת Marcus-Law Klear, אחרת ClickOnce ידחה את ההתקנה עם אזהרת "Unknown Publisher".
-
העתק את
codesign.cerמשלב 3.2 לתיקיית SYSVOL:\\marcus-law.local\SYSVOL\marcus-law.local\Scripts\certs\codesign.cer -
פתח Group Policy Management Console (
gpmc.msc) על שרת Active Directory. -
צור או ערוך GPO בשם "Klear Code-Signing Certificate" ושייך אותו ל-OU של עורכי הדין (לדוגמה
OU=Attorneys,DC=marcus-law,DC=local). -
ב-GPO Editor, נווט אל:
Computer Configuration → Policies → Windows Settings → Security Settings → Public Key Policies -
קליק ימני על Trusted Publishers → Import… → בחר את
codesign.cer. -
חזור על אותה פעולה תחת Trusted Root Certification Authorities (כי זו תעודה self-signed שלא חתומה ע"י CA אמיתי).
-
דחוף את ה-GPO לכל המכונות:
# מ-Domain Controller Invoke-Command -ComputerName (Get-ADComputer -Filter * -SearchBase "OU=Attorneys,DC=marcus-law,DC=local").Name -ScriptBlock { gpupdate /force } -
ודא במחשב אחד של עורך-דין:
certutil -store -user TrustedPublisher | findstr /C:"Marcus-Law Klear"אם רואים
CN=Marcus-Law Klear— מוכן. אם לא — ה-GPO לא הגיע, נסהgpupdate /forceשוב.
4. שחרור גרסה ראשונה (v1.0.0)
לאחר שכל ההקמה הסתיימה, השחרור הראשון:
# במכונה של המפתח, אחרי שכל הקוד ב-main:
git tag v1.0.0
git push origin v1.0.0
מה קורה ברקע:
- Gitea Actions מתחיל job בשם
publishעל runnerwindows. - הוא בונה ב-Release, חותם, מריץ mage עם גרסה
1.0.0.0. - מעלה ל-
platform.dev:/var/www/outlook-addin/. - שולח הודעה ל-Mattermost בערוץ
#git-verelasim:📦 OutlookAddin v1.0.0 משוחרר — https://platform.dev.marcus-law.co.il/outlook-addin/OutlookAddin.vsto
מעקב: ראה את ה-job ב-https://gitea.dev.marcus-law.co.il/espocrm-extensions/OutlookAddin/actions. אמור להסתיים תוך 2-3 דקות. אם נכשל — קליק על השלב הכושל ובדוק את הלוג.
בדיקת קצה:
- ב-Edge / Chrome פתח
https://platform.dev.marcus-law.co.il/outlook-addin/OutlookAddin.vsto— אמור להראות XML. - במחשב נקי של עורך-דין (או VM לבדיקות):
- הורד את
setup.exeאו פתח אתOutlookAddin.vstoישירות. - אמור להופיע דיאלוג ClickOnce בלי אזהרת "Unknown Publisher" (כי ה-GPO הפיץ את התעודה).
- אשר התקנה → תוסף נטען ב-Outlook → רואים את כפתור "Klear" בריבון.
- הורד את
5. שחרור עדכון חדש (יום-יום)
לאחר שינויי קוד, החזרה לפעולה:
# 1. ודא שכל השינויים ב-main
git status # אמור להיות clean
git pull --rebase
# 2. בחר מספר גרסה לפי semver
# - תיקון באג → v1.0.X (PATCH)
# - פיצ'ר חדש קטן → v1.X.0 (MINOR)
# - שינוי שובר תאימות לאחור → vX.0.0 (MAJOR)
git tag v1.0.1
git push origin v1.0.1
ה-CI ירוץ אוטומטית כמו בשחרור הראשון.
אצל הלקוחות:
- ה־VSTO runtime בודק את ה-
.vstomanifest בכל פתיחה של Outlook (משוחזר מ-<UpdatePeriodically>false</UpdatePeriodically>ב-csproj החל מ-v1.2.9; קודם זה היה פעם ב-7 ימים). הבדיקה היא GET של ~6KB, ~100ms — בלתי מורגש בזמן הטעינה. - ה-CI מציב
/p:MinimumRequiredVersion=<tag>בכל build, אז מיד כשהבדיקה מזהה גרסה חדשה — ההתקנה נכפית בלי דיאלוג. - תרגום מעשי: 30 שניות אחרי
git push --tagsה-CI מסיים → תוך 2-3 דקות החבילה נדחפת ל-CDN → בכניסה הבאה של כל אחד מהלקוחות ל-Outlook הוא רץ על הגרסה החדשה. בלי שום פעולה ידנית מצידם. - הכפתור "בדוק עדכונים" בהגדרות רק מודיע ("זמינה גרסה X — סגור ופתח Outlook"). הוא לא יכול להתקין מתוך תהליך Outlook רץ —
VSTOInstaller.exeלא יכול לדרוס DLLs נעולים, וה-ApplicationDeployment API נכשל ב-TrustNotGrantedExceptionבהקשר VSTO. ההתקנה תמיד קורית רק דרך ה-runtime בעלייה של Outlook. [פירוט בזיכרון: feedback_vsto_updater_api.md] - תקלה נדירה — לקוח שהותקן ידנית עם dev cert (
HP-OFFICE1\<user>, publicKeyToken41d8d795775ea8cb) לא יכול לעבור auto-update לגרסת prod cert (Marcus-Law OutlookAddin, publicKeyTokenc68d2b4c25051c5b) — ClickOnce מתייחס אליהן כשתי אפליקציות שונות. פעם אחת: Apps & Features → uninstall של MarcusLaw.OutlookAddin → התקנה חדשה מ-https://platform.dev.marcus-law.co.il/outlook-addin/OutlookAddin.vsto. אחרי זה auto-update עובד.
6. ניטור ופתרון תקלות
Mattermost notifications
#git-verelasim— מקבל הודעת הצלחה/כישלון לכל release.- אם כישלון — הקישור בהודעה לוקח ישר ל-Gitea Actions log.
לוגי הקלינט
אם לקוח מתלונן שהעדכון לא הגיע:
%LOCALAPPDATA%\MarcusLaw\OutlookAddin\logs\addin-YYYYMMDD.log
שורת AddInHost starting up מופיעה בכל פתיחת Outlook עם הגרסה הנוכחית.
בדיקה שהגרסה החדשה אכן בשרת
curl -s https://platform.dev.marcus-law.co.il/outlook-addin/OutlookAddin.vsto | grep -E "(version|application)"
אמור להציג את הגרסה החדשה.
Rollback מהיר
אם גרסה שוחררה ויש בה באג קריטי:
# על platform.dev (כ-root)
cd /var/www/outlook-addin
# העבר את הגרסה הבעייתית הצידה
sudo mv "Application Files/OutlookAddin_1_0_1_0" "_quarantine_1_0_1_0"
# החזר את ה-.vsto לגרסה הקודמת
# (קל יותר: דחוף תיוג חדש v1.0.2 שמחזיר את הקוד הקודם)
git revert <commit-של-הבאג>
git tag v1.0.2
git push origin main v1.0.2
ה-CI יבנה אוטומטית את v1.0.2 ותוך 7 ימים כל הלקוחות יחזרו אחורה.
כשלים נפוצים
| שגיאה | סיבה | פתרון |
|---|---|---|
signtool: Failed (0x80092004) |
התעודה לא ב-Cert:\CurrentUser\My ב-Build Runner |
התקן את ה-PFX שוב במכונה |
mage: not recognized |
חסר .NET Framework 4.8 Developer Pack | התקן מ-winget לפי שלב 3.1 |
Permission denied (publickey) ב-rsync |
SSH key לא נכנס ל-authorized_keys על platform.dev | חזור על שלב 3.5 והוסף את הציבורי |
| לקוח מקבל "Unknown Publisher" | GPO לא הפיץ את התעודה למחשב הזה | gpupdate /force במחשב הלקוח |
| לקוח לא מקבל עדכון אחרי 7 ימים | ה-ClickOnce cache תקוע | rundll32 dfshim.dll,CleanOnlineAppCache ופתח שוב |
7. בדיקה אם ההקמה הצליחה
עברו את הצ'קליסט הזה אחרי הקמה ראשונית:
- CI runner מופיע online ב-Gitea Admin
- שלושת ה-secrets קיימים ב-Gitea Actions Settings
curl https://platform.dev.marcus-law.co.il/outlook-addin/חוזר 200/403 (לא 502 / connection refused)certutil -store -user TrustedPublisherבמחשב לקוח מציגMarcus-Law Klear- Mattermost incoming webhook עובד — בדוק עם
curl -X POST -d '{"text":"test"}' <webhook-url> git tag v0.0.1-test && git push origin v0.0.1-testמפעיל את ה-CI workflow- ה-job מסתיים בירוק תוך 5 דקות
- מחיקת הטאג הניסיוני אחרי:
git push --delete origin v0.0.1-test && git tag -d v0.0.1-test
8. תחזוקה תקופתית
| משימה | תדירות |
|---|---|
| חידוש תעודת חתימה (אחרי 3 שנים) | פעם ב-3 שנים — לפני התפוגה תעודה חדשה צריכה GPO חדש |
| חידוש Let's Encrypt לתעודה של platform.dev | אוטומטי, אבל לבדוק שה-cron פועל |
| עדכון VS Build Tools / Windows SDK ב-runner | כל 6 חודשים |
ניקוי גרסאות ישנות מ-/var/www/outlook-addin/Application Files/ |
לאחר שכל הלקוחות עברו (אופציונלי, חוסך מקום) |
9. מסמכים קשורים
docs/PROJECT-BRIEFING.md— סקירת הפרויקט (תכנון מקורי)docs/ARCHITECTURE.md— ארכיטקטורת התוסף (לא ה-CI)docs/IT-SETUP.md— מדריך IT באנגלית (כולל פירוט API keys ב-EspoCRM)docs/ONBOARDING.md— מדריך לעורך-הדין (לקצה — לא לכם).gitea/workflows/build.yml— הגדרת CI עצמה (הקובץ שמריץ את הכל)tools/install-protocol.ps1— סקריפט לרישוםoutlookaddin://במחשבי הלקוח (אופציונלי)
10. קשר ועזרה
- בעיות עם הקוד עצמו: chaim@marcus-law.co.il
- בעיות CI / nginx / GPO: צוות תשתיות פנימי
- חירום (כל הלקוחות תקועים): roll-back מיידי לפי סעיף 6, ואז דחיפת תיקון