mirror of
https://github.com/KingHWJ/WeReadBoard.git
synced 2026-11-03 18:24:58 +08:00
ci(deploy): 改为 GitHub Webhook 触发部署
This commit is contained in:
1 parent
69bfe3ce0e
commit
469630e7da
11 files changed
+267
-78
No files matched your search
@@ -8,16 +8,16 @@ if ! grep -q '^ - master$' "$WORKFLOW"; then
|
||||
echo "部署工作流尚未监听 master"
|
||||
exit 1
|
||||
fi
|
||||
if grep -q '^ - dev$' "$WORKFLOW"; then
|
||||
echo "部署工作流仍监听 dev"
|
||||
if ! grep -q 'deploy_webhook.py' "$ROOT_DIR/deploy/weread-webhook.service"; then
|
||||
echo "Webhook systemd 服务未配置"
|
||||
exit 1
|
||||
fi
|
||||
if ! grep -q '^ group: deploy-master$' "$WORKFLOW"; then
|
||||
echo "部署并发组尚未切换到 master"
|
||||
if ! grep -q 'DEFAULT_BRANCH = "master"' "$ROOT_DIR/deploy_webhook.py"; then
|
||||
echo "Webhook 未固定 master 分支"
|
||||
exit 1
|
||||
fi
|
||||
if ! grep -q '^ DEPLOY_BRANCH: master$' "$WORKFLOW"; then
|
||||
echo "手动部署分支尚未固定为 master"
|
||||
if grep -q 'SERVER_SSH_KEY\|ssh -i' "$WORKFLOW"; then
|
||||
echo "验证工作流仍包含服务器 SSH 部署"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -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()
|
||||
Reference in new issue
Block a user