diff --git a/cf-invocation-log.json b/cf-invocation-log.json new file mode 100644 index 0000000..7149d3f --- /dev/null +++ b/cf-invocation-log.json @@ -0,0 +1,118 @@ +{ + "level": "info", + "message": "POST https://larkstack.s3anjia.workers.dev/github/webhook", + "$workers": { + "event": { + "request": { + "cf": { + "requestHeaderNames": {}, + "isEUCountry": false, + "httpProtocol": "HTTP/1.1", + "requestPriority": "", + "colo": "IAD", + "asOrganization": "GitHub, Inc.", + "country": "US", + "city": "Leesburg", + "continent": "NA", + "region": "Virginia", + "regionCode": "VA", + "timezone": "America/New_York", + "longitude": "-77.5636", + "latitude": "39.11566", + "postalCode": "20177", + "metroCode": "511", + "tlsVersion": "TLSv1.3", + "tlsCipher": "AEAD-AES128-GCM-SHA256", + "tlsClientRandom": "+w8WZeAhCovPci0/3GFmszXY3jfe3nEWwx2l4NT4J2U=", + "tlsClientCiphersSha1": "QrF6UadKW3vtNOqdNqbd4frxxxE=", + "tlsClientExtensionsSha1": "VmypJ9I6O+wlbe1dI9qycuZ4Ywg=", + "tlsClientExtensionsSha1Le": "i+zMiC3iuMzkwC9CUcQV4FcnRkg=", + "tlsExportedAuthenticator": { + "clientHandshake": "77910242563aa7d14879cf3b1534bed9e43f22eef840f7b3851526bbcfc32150", + "serverHandshake": "21d88c6b40c965b9d6af5bb879c01b0cea27b328ab0c5464814ec095406584a9", + "clientFinished": "8b4d71c983838af31d0ade49daa0cf583933e5661af4d10cb0f33a9c44445a5f", + "serverFinished": "064b180b10b435539ce352f276f7b99ed1ac650dee294154ed1ec2e132df3fbe" + }, + "tlsClientHelloLength": "1508", + "tlsClientAuth": { + "certPresented": "0", + "certVerified": "NONE", + "certRevoked": "0", + "certIssuerDN": "", + "certSubjectDN": "", + "certIssuerDNRFC2253": "", + "certSubjectDNRFC2253": "", + "certIssuerDNLegacy": "", + "certSubjectDNLegacy": "", + "certSerial": "", + "certIssuerSerial": "", + "certSKI": "", + "certIssuerSKI": "", + "certFingerprintSHA1": "", + "certFingerprintSHA256": "", + "certNotBefore": "", + "certNotAfter": "" + }, + "verifiedBotCategory": "", + "edgeRequestKeepAliveStatus": 1, + "clientTcpRtt": 0, + "asn": 36459 + }, + "url": "https://larkstack.s3anjia.workers.dev/github/webhook", + "method": "POST", + "headers": { + "accept": "*/*", + "accept-encoding": "gzip, br", + "cf-connecting-ip": "140.82.115.74", + "cf-ipcountry": "US", + "cf-ray": "9d786898f833e5fb", + "cf-visitor": "{\"scheme\":\"https\"}", + "connection": "Keep-Alive", + "content-length": "15800", + "content-type": "application/x-www-form-urlencoded", + "host": "larkstack.s3anjia.workers.dev", + "user-agent": "GitHub-Hookshot/1cdf727", + "x-forwarded-proto": "https", + "x-github-delivery": "77b6ba42-1879-11f1-998c-66012c8e9b6f", + "x-github-event": "push", + "x-github-hook-id": "599108526", + "x-github-hook-installation-target-id": "1165295701", + "x-github-hook-installation-target-type": "repository", + "x-hub-signature": "sha1=d67ed5c997c7e81192508c0087beac7cb5339903", + "x-hub-signature-256": "sha256=3c7b9321d0ec9454e01c2c9e95522d528b2a5e0b15bdf770b0efa974672ae43e", + "x-real-ip": "140.82.115.74" + }, + "path": "/github/webhook" + }, + "rayId": "9d786898f833e5fb", + "response": { + "status": 200 + } + }, + "diagnosticsChannelEvents": [], + "truncated": false, + "scriptName": "larkstack", + "outcome": "ok", + "eventType": "fetch", + "executionModel": "stateless", + "scriptVersion": { + "id": "eb2de6a9-9ab9-4134-ad69-a911fa127dc6" + }, + "requestId": "9d786898f833e5fb", + "cpuTimeMs": 19, + "wallTimeMs": 20 + }, + "$metadata": { + "id": "01KJYRD6X8AVMQC4YP02ZJPZBK", + "requestId": "9d786898f833e5fb", + "trigger": "POST /github/webhook", + "service": "larkstack", + "level": "info", + "message": "POST https://larkstack.s3anjia.workers.dev/github/webhook", + "account": "554e131b095636ce2be18cf4fb288502", + "type": "cf-worker-event", + "fingerprint": "169b57411ee99ad9ffca9e35af5f8119", + "origin": "fetch", + "messageTemplate": "POST https://larkstack.s3anjia.workers.dev/github/webhook" + } +} \ No newline at end of file diff --git a/src/config.rs b/src/config.rs index dbf0a57..d3357f2 100644 --- a/src/config.rs +++ b/src/config.rs @@ -92,9 +92,9 @@ impl LarkConfig { .secret("LARK_GITHUB_WEBHOOK_URL") .map(|s| s.to_string()) .unwrap_or_default(), - app_id: env.var("LARK_APP_ID").ok().map(|v| v.to_string()), + app_id: env.secret("LARK_APP_ID").ok().map(|s| s.to_string()), app_secret: env.secret("LARK_APP_SECRET").ok().map(|s| s.to_string()), - github_app_id: env.var("LARK_GITHUB_APP_ID").ok().map(|v| v.to_string()), + github_app_id: env.secret("LARK_GITHUB_APP_ID").ok().map(|s| s.to_string()), github_app_secret: env .secret("LARK_GITHUB_APP_SECRET") .ok() diff --git a/src/debounce_do.rs b/src/debounce_do.rs index 8776452..a77064b 100644 --- a/src/debounce_do.rs +++ b/src/debounce_do.rs @@ -89,8 +89,8 @@ impl DurableObject for DebounceObject { let card = crate::sinks::lark::cards::build_lark_card(&event); let webhook_url = self .env - .var("LARK_WEBHOOK_URL") - .map(|v| v.to_string()) + .secret("LARK_WEBHOOK_URL") + .map(|s| s.to_string()) .unwrap_or_default(); if !webhook_url.is_empty() { crate::sinks::lark::webhook::send_lark_card(&http, &webhook_url, &card).await; diff --git a/src/sources/github/handler.rs b/src/sources/github/handler.rs index 45b088c..a972236 100644 --- a/src/sources/github/handler.rs +++ b/src/sources/github/handler.rs @@ -26,12 +26,10 @@ use octocrab::models::webhook_events::{ use crate::{ config::{AppState, GitHubConfig}, dispatch, - event::{CommitSummary, Event}, + event::Event, }; -use super::utils::{branch_from_ref, verify_github_signature}; - -const MAX_COMMITS: usize = 5; +use super::utils::verify_github_signature; // --------------------------------------------------------------------------- // Shared thin structs (used by both native and cf-worker) @@ -155,26 +153,6 @@ mod thin { pub html_url: String, } - #[derive(Deserialize)] - pub struct PushPayload { - pub r#ref: String, - pub commits: Vec, - pub pusher: CommitUser, - pub compare: String, - } - - #[derive(Deserialize)] - pub struct Commit { - pub id: String, - pub message: String, - pub author: CommitUser, - } - - #[derive(Deserialize)] - pub struct CommitUser { - pub name: String, - } - #[derive(Deserialize)] pub struct WorkflowRunPayload { pub action: String, @@ -293,7 +271,6 @@ async fn dispatch_native( handle_pull_request(state, github, repo, *payload).await } WebhookEventPayload::Issues(payload) => handle_issues(state, github, repo, *payload).await, - WebhookEventPayload::Push(payload) => handle_push(state, repo, *payload).await, WebhookEventPayload::WorkflowRun(payload) => { handle_workflow_run(state, repo, *payload).await } @@ -433,42 +410,6 @@ async fn handle_issues( StatusCode::OK } -#[cfg(feature = "native")] -async fn handle_push( - state: &Arc, - repo: &str, - payload: octocrab::models::webhook_events::payload::PushWebhookEventPayload, -) -> StatusCode { - let branch = branch_from_ref(&payload.r#ref); - if !is_protected_branch(branch) { - info!("ignoring push to non-protected branch: {branch}"); - return StatusCode::OK; - } - info!( - "GitHub push to {repo}@{branch}: {} commit(s)", - payload.commits.len() - ); - let commits: Vec = payload - .commits - .iter() - .take(MAX_COMMITS) - .map(|c| CommitSummary { - sha_short: c.id.chars().take(7).collect(), - message_line: c.message.lines().next().unwrap_or("").to_string(), - author: c.author.user.name.clone(), - }) - .collect(); - let event = Event::BranchPush { - repo: repo.to_string(), - branch: branch.to_string(), - pusher: payload.pusher.user.name.clone(), - commits, - compare_url: payload.compare.to_string(), - }; - dispatch::dispatch_github(&event, state, None).await; - StatusCode::OK -} - #[cfg(feature = "native")] async fn handle_workflow_run( state: &Arc, @@ -542,14 +483,8 @@ async fn dispatch_cf( handle_issues_cf(state, github, repo, payload).await } "push" => { - let payload: thin::PushPayload = match serde_json::from_slice(body) { - Ok(p) => p, - Err(e) => { - warn!("failed to parse push payload: {e}"); - return StatusCode::OK; - } - }; - handle_push_cf(state, repo, payload).await + info!("ignoring push event (not subscribed)"); + StatusCode::OK } "workflow_run" => { let payload: thin::WorkflowRunPayload = match serde_json::from_slice(body) { @@ -718,42 +653,6 @@ async fn handle_issues_cf( StatusCode::OK } -#[cfg(feature = "cf-worker")] -async fn handle_push_cf( - state: &Arc, - repo: &str, - payload: thin::PushPayload, -) -> StatusCode { - let branch = branch_from_ref(&payload.r#ref); - if !is_protected_branch(branch) { - info!("ignoring push to non-protected branch: {branch}"); - return StatusCode::OK; - } - info!( - "GitHub push to {repo}@{branch}: {} commit(s)", - payload.commits.len() - ); - let commits: Vec = payload - .commits - .iter() - .take(MAX_COMMITS) - .map(|c| CommitSummary { - sha_short: c.id.chars().take(7).collect(), - message_line: c.message.lines().next().unwrap_or("").to_string(), - author: c.author.name.clone(), - }) - .collect(); - let event = Event::BranchPush { - repo: repo.to_string(), - branch: branch.to_string(), - pusher: payload.pusher.name.clone(), - commits, - compare_url: payload.compare.clone(), - }; - dispatch::dispatch_github(&event, state, None).await; - StatusCode::OK -} - // --------------------------------------------------------------------------- // Shared inner dispatch helpers (workflow_run / secret_scanning / dependabot) // Both native and cf-worker extract inner data as serde_json::Value, then @@ -858,11 +757,3 @@ async fn dispatch_dependabot( dispatch::dispatch_github(&event, state, None).await; StatusCode::OK } - -// --------------------------------------------------------------------------- -// Helpers -// --------------------------------------------------------------------------- - -fn is_protected_branch(branch: &str) -> bool { - matches!(branch, "main" | "master") || branch.starts_with("release") -} diff --git a/src/sources/github/utils.rs b/src/sources/github/utils.rs index 4383c51..27fb797 100644 --- a/src/sources/github/utils.rs +++ b/src/sources/github/utils.rs @@ -10,9 +10,3 @@ pub fn verify_github_signature(secret: &str, body: &[u8], header_value: &str) -> }; crate::utils::verify_hmac_sha256(secret, body, hex_sig) } - -/// Extracts the short branch name from a full git ref -/// (e.g. `"refs/heads/main"` → `"main"`). -pub fn branch_from_ref(git_ref: &str) -> &str { - git_ref.strip_prefix("refs/heads/").unwrap_or(git_ref) -}