ci(deploy): 改为 GitHub Webhook 触发部署

This commit is contained in:
admin committed 2026-10-20 14:23:31 +08:00
1 parent 69bfe3ce0e
commit 469630e7da
11 files changed
+267 -78

No files matched your search

+74
View File
@@ -0,0 +1,74 @@
import hashlib
import hmac
import json
import unittest
from unittest.mock import patch
from deploy_webhook import create_app
class WebhookTest(unittest.TestCase):
def setUp(self):
self.process = None
self.app = create_app({
"TESTING": True,
"WEBHOOK_SECRET": "webhook-secret",
"REPOSITORY": "KingHWJ/WeReadBoard",
"BRANCH": "master",
"PROJECT_DIR": "/srv/weread",
"DEPLOY_SCRIPT": "deploy.sh",
})
self.client = self.app.test_client()
@staticmethod
def signed(payload):
body = json.dumps(payload, separators=(",", ":")).encode()
signature = hmac.new(b"webhook-secret", body, hashlib.sha256).hexdigest()
return body, {
"Content-Type": "application/json",
"X-GitHub-Event": "push",
"X-Hub-Signature-256": f"sha256={signature}",
}
def test_health_is_available(self):
self.assertEqual(self.client.get("/health").status_code, 200)
def test_invalid_signature_is_rejected(self):
response = self.client.post(
"/github/webhook",
data=b"{}",
headers={"X-GitHub-Event": "push", "X-Hub-Signature-256": "sha256=bad"},
)
self.assertEqual(response.status_code, 401)
@patch("deploy_webhook.subprocess.Popen")
def test_only_matching_master_push_starts_deployment(self, popen):
payload = {"ref": "refs/heads/master", "repository": {"full_name": "KingHWJ/WeReadBoard"}}
body, headers = self.signed(payload)
response = self.client.post("/github/webhook", data=body, headers=headers)
self.assertEqual(response.status_code, 202)
self.assertEqual(response.json["status"], "accepted")
popen.assert_called_once()
self.assertEqual(popen.call_args.args[0], ["/srv/weread/deploy.sh"])
@patch("deploy_webhook.subprocess.Popen")
def test_dev_push_does_not_start_deployment(self, popen):
payload = {"ref": "refs/heads/dev", "repository": {"full_name": "KingHWJ/WeReadBoard"}}
body, headers = self.signed(payload)
response = self.client.post("/github/webhook", data=body, headers=headers)
self.assertEqual(response.status_code, 202)
popen.assert_not_called()
@patch("deploy_webhook.subprocess.Popen")
def test_duplicate_push_is_not_started_while_deploying(self, popen):
popen.return_value.poll.return_value = None
payload = {"ref": "refs/heads/master", "repository": {"full_name": "KingHWJ/WeReadBoard"}}
body, headers = self.signed(payload)
self.assertEqual(self.client.post("/github/webhook", data=body, headers=headers).json["status"], "accepted")
response = self.client.post("/github/webhook", data=body, headers=headers)
self.assertEqual(response.json["status"], "already_deploying")
popen.assert_called_once()
if __name__ == "__main__":
unittest.main()