🐧 Linux TippsDebian 11 Long Term Support reaches end-of-life(31.08.2026 um 02:00 Uhr)
🐧 Linux TippsUpdated Debian 13: 13.7 released(12.09.2026 um 02:00 Uhr)
🕵️ SicherheitslückenUSN-8741-1: Flatpak vulnerabilities(10.09.2026 um 10:44 Uhr)
🕵️ SicherheitslückenUSN-8742-1: Netty vulnerability(10.09.2026 um 11:01 Uhr)
🕵️ SicherheitslückenUSN-8737-2: GNU C Library vulnerabilities(10.09.2026 um 13:25 Uhr)
🕵️ SicherheitslückenUSN-8743-1: PHP vulnerabilities(10.09.2026 um 13:48 Uhr)
🕵️ SicherheitslückenUSN-8744-1: Python vulnerabilities(10.09.2026 um 15:53 Uhr)
🐧 Linux TippsUSN-8748-1: Linux kernel (NVIDIA) vulnerabilities(10.09.2026 um 17:32 Uhr)
🕵️ SicherheitslückenUSN-8745-1: KissFFT vulnerabilities(10.09.2026 um 17:36 Uhr)
🕵️ SicherheitslückenUSN-8746-1: libEBML vulnerability(10.09.2026 um 17:48 Uhr)
🐧 Linux TippsDebian 11 Long Term Support reaches end-of-life(31.08.2026 um 02:00 Uhr)
🐧 Linux TippsUpdated Debian 13: 13.7 released(12.09.2026 um 02:00 Uhr)
🕵️ SicherheitslückenUSN-8741-1: Flatpak vulnerabilities(10.09.2026 um 10:44 Uhr)
🕵️ SicherheitslückenUSN-8742-1: Netty vulnerability(10.09.2026 um 11:01 Uhr)
🕵️ SicherheitslückenUSN-8737-2: GNU C Library vulnerabilities(10.09.2026 um 13:25 Uhr)
🕵️ SicherheitslückenUSN-8743-1: PHP vulnerabilities(10.09.2026 um 13:48 Uhr)
🕵️ SicherheitslückenUSN-8744-1: Python vulnerabilities(10.09.2026 um 15:53 Uhr)
🐧 Linux TippsUSN-8748-1: Linux kernel (NVIDIA) vulnerabilities(10.09.2026 um 17:32 Uhr)
🕵️ SicherheitslückenUSN-8745-1: KissFFT vulnerabilities(10.09.2026 um 17:36 Uhr)
🕵️ SicherheitslückenUSN-8746-1: libEBML vulnerability(10.09.2026 um 17:48 Uhr)

🔧 Programmierung 🕛 vor 3 Monaten 6 Min Lesezeit
0

Verify That Your GitHub Actions Deployment Actually Landed on the Server

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht




How to Verify?



GitHub Actions said ✅ Success. The server disagreed.



We kept running into a subtle CI/CD problem: after pushing to main, GitHub marked the deployment as successful — but checking the server revealed the old code was still there. No error. No alert.

Just stale code running in production.



This article walks through the root cause, and the two-part fix we implemented: lock detection and commit SHA verification.







The Setup



Our deployment architecture uses a webhook-based approach (no SSH):



GitHub Actions → HTTP POST → deploy.php on server → runs deploy.sh



Why webhooks instead of SSH? Our hosting provider (Hypernode) IP-whitelists SSH access. GitHub Actions runs on dynamic Azure IPs that get blocked. Port 443 (HTTPS) has no such restriction.



The workflow looks like this:




CODE
- name: Trigger deploy on server
run: |
response=$(curl -s -w "\n%{http_code}" \
-X POST https://www.yoursite.nl/deploy.php \
-H "X-Deploy-Token: ${{ secrets.DEPLOY_WEBHOOK_TOKEN }}" \
--max-time 300)

code=$(echo "$response" | tail -n 1)
if [ "$code" != "200" ]; then
echo "❌ Deployment failed (HTTP $code)"
exit 1
fi
echo "✅ Deployment successful"






And deploy.php runs deploy.sh synchronously:




CODE
exec("bash {$script} 2>&1", $output, $exit);
echo implode("\n", $output) . "\n";
http_response_code($exit === 0 ? 200 : 500);






Looks solid, right? The exec() call is blocking — PHP waits for deploy.sh to finish before responding. So GitHub should always get an accurate result.



Mostly, yes. But there's one case where it silently lies.






The Root Cause: Silent Lock Skips



deploy.sh uses a lock file to prevent concurrent deployments:




CODE
LOCK_FILE="/tmp/mysite-deploy.lock"

if [ -f "$LOCK_FILE" ]; then
log "ERROR: Deployment already in progress. Aborting."
exit 1
fi

touch "$LOCK_FILE"
trap "rm -f $LOCK_FILE" EXIT






When a second push happens while a deploy is already running:




  1. Second deploy hits deploy.php

  2. deploy.sh finds lock file → exit 1

  3. deploy.php returns HTTP 500

  4. GitHub Actions sees 500 → ❌ marks as failed



That part is actually fine. But here's the subtle problem: the first deploy might fail mid-way (network hiccup on git fetch, OOM kill, timeout), leaving the lock file behind. Now every subsequent

deploy silently skips, deploy.sh exits 1, deploy.php returns 500 — and depending on how your workflow handles the response, you might see a misleading result.



Worse: even when deploys succeed, there was no proof of what commit actually landed. We had to manually SSH in and check file timestamps or grep for a known string. That's not sustainable.





The Fix: Two Parts



Part 1 — Return 423 When Locked



Instead of letting deploy.sh handle the lock silently, detect it in deploy.php first and return a meaningful HTTP status:




CODE
$lockFile = '/tmp/mysite-deploy.lock';
if (file_exists($lockFile)) {
http_response_code(423);
echo "LOCKED: Deployment already in progress. Try again shortly.\n";
exit;
}

exec("bash {$script} 2>&1", $output, $exit);
echo implode("\n", $output) . "\n";
http_response_code($exit === 0 ? 200 : 500);






HTTP 423 Locked is semantically correct here — it's a standard status code meaning "the resource is currently locked."



Update the workflow to treat 423 as a distinct failure:




CODE
if [ "$code" = "423" ]; then
echo "⚠️ Deploy locked — previous deploy still running"
exit 1
fi
if
[ "$code" != "200" ]; then
echo "❌ Deployment failed (HTTP $code)"
exit 1
fi






Now you get a clear signal in CI instead of a generic failure or false success.






Part 2 — Write a Version File, Verify the SHA



At the end of deploy.sh, after all steps complete successfully, write the deployed commit SHA to a public file:




CODE
# After git reset --hard, capture the SHA
DEPLOYED_COMMIT=$(git rev-parse HEAD)
log "✓ Code updated (commit: $DEPLOYED_COMMIT)"

# ... composer install, yarn build, artisan commands ...

# At the very end, write version file
echo "$DEPLOYED_COMMIT $(date -u +%Y-%m-%dT%H:%M:%SZ)" > public/version.txt
log "✓ Version file written: $DEPLOYED_COMMIT"






This file is written after git clean (which would delete it) and before deploy.sh exits — so by the time deploy.php returns 200, version.txt is already on disk with the correct SHA.



Add it to .gitignore so it never gets accidentally committed:



public/version.txt






Part 3 — Verify in GitHub Actions



Add a verification step after the webhook trigger:




CODE
- name: Trigger deploy on server
run: |
# ... existing webhook call ...

- name: Verify deployment landed
run: |
EXPECTED="${{ github.sha }}"
echo "Expected SHA: $EXPECTED"

for i in $(seq 1 20); do
sleep 15
DEPLOYED=$(curl -sf "https://www.yoursite.nl/version.txt" 2>/dev/null | awk '{print $1}')
echo "Attempt $i/20: server=${DEPLOYED:-none}"
if [ "$DEPLOYED" = "$EXPECTED" ]; then
echo "✅ Deploy confirmed on server: $DEPLOYED"
exit 0
fi
done

echo "❌ Deploy verification FAILED after 5 minutes"
echo "Expected: $EXPECTED"
echo "Got: ${DEPLOYED:-no response from server}"
exit 1






This polls version.txt every 15 seconds for up to 5 minutes. Since our deploy.php uses synchronous exec(), the deploy is already finished by the time this step runs — so the first poll (15 seconds in)

almost always matches immediately.





Results



Here's what the GitHub Actions log looks like after the fix:




CODE
Run EXPECTED="6f250fe1a2b9bb11ea826325a8a486b25279dfb1"
Waiting for deploy to complete on server...
Expected SHA: 6f250fe1a2b9bb11ea826325a8a486b25279dfb1
Attempt 1/20: server=6f250fe1a2b9bb11ea826325a8a486b25279dfb1
✅ Deploy confirmed on server: 6f250fe1a2b9bb11ea826325a8a486b25279dfb1






Confirmed on attempt 1 — no waiting needed.



You can also verify manually any time:




CODE
curl -s https://www.yoursite.nl/version.txt
# 6f250fe1a2b9bb11ea826325a8a486b25279dfb1 2026-05-28T03:41:30Z









Why Not Just Use git log on the Server?



You could SSH in and run git log -1 — but that requires SSH access from CI (blocked for us), a separate monitoring job, or manual checks. The version.txt approach works over plain HTTPS with no

credentials, from anywhere, including your browser.



It also separates concerns: GitHub Actions verifies the outcome, not the process. Even if the internals of deploy.sh change, the verification contract stays the same — "does the server report the right

SHA?"









CODE
Summary

┌──────────────────────────────────────────────────┬───────────────────────────────────────┐
│ Problem │ Fix │
├──────────────────────────────────────────────────┼───────────────────────────────────────┤
│ No signal when deploy is locked │ deploy.php returns HTTP 423 │
├──────────────────────────────────────────────────┼───────────────────────────────────────┤
│ No proof of what commit landed │ deploy.sh writes public/version.txt │
├──────────────────────────────────────────────────┼───────────────────────────────────────┤
│ GitHub shows success without server confirmation │ GitHub Actions polls and verifies SHA │
└──────────────────────────────────────────────────┴───────────────────────────────────────┘






Three small changes. Zero new dependencies. Works with any stack that can serve a static file over HTTP.

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Debian 11 Long Term Support reaches end-of-life
1 Quelle
Updated Debian 13: 13.7 released
1 Quelle
USN-8741-1: Flatpak vulnerabilities
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Verify That Your GitHub Actions Deployment Actually Landed on the Server

Thematisch verwandte Begriffe: Verify, That, Your, GitHub · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...