Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
- uses: FerrFlow-Org/Benchmarks@v2
with:
type: micro
github-token: ${{ secrets.GITHUB_TOKEN }}
ferrflow-token: ${{ secrets.GITHUB_TOKEN }}

benchmark:
name: Benchmark
Expand All @@ -75,7 +75,7 @@ jobs:
- uses: FerrFlow-Org/Benchmarks@v2
with:
type: full
github-token: ${{ secrets.GITHUB_TOKEN }}
ferrflow-token: ${{ secrets.GITHUB_TOKEN }}

release:
name: Release
Expand Down
2 changes: 1 addition & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ pub fn init(format: Option<ConfigFileFormat>) -> Result<()> {
println!("Run: ferrflow check");

if config.workspace.telemetry {
telemetry::send_event("init", None, None, None);
telemetry::send_event(telemetry::EventType::Init, None, None, None);
}

Ok(())
Expand Down
18 changes: 16 additions & 2 deletions src/monorepo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub fn check(config_path: Option<&Path>, verbose: bool) -> Result<()> {
let result = run_release_logic(&root, &config, true, verbose);

if config.workspace.telemetry {
telemetry::send_event("check", None, None, None);
telemetry::send_event(telemetry::EventType::Check, None, None, None);
}

result
Expand Down Expand Up @@ -274,6 +274,15 @@ fn run_release_logic(root: &Path, config: &Config, dry_run: bool, verbose: bool)
auto_stage_new_files(&repo, &before, &mut files_to_commit);
}

if config.workspace.telemetry {
telemetry::send_event(
telemetry::EventType::VersionBump,
Some(&pkg.name),
Some(&new_version),
None,
);
}

let body = build_section(&new_version, &commits);
tags_to_create.push((
tag.clone(),
Expand Down Expand Up @@ -450,7 +459,12 @@ fn run_release_logic(root: &Path, config: &Config, dry_run: bool, verbose: bool)

if config.workspace.telemetry {
for (_, _, _, pkg_name, version) in &tags_to_create {
telemetry::send_event("release", Some(pkg_name), Some(version), None);
telemetry::send_event(
telemetry::EventType::Release,
Some(pkg_name),
Some(version),
None,
);
}
}

Expand Down
129 changes: 126 additions & 3 deletions src/telemetry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,20 @@ use serde::Serialize;

const DEFAULT_API_URL: &str = "https://api.ferrflow.com";

#[derive(Debug, Clone, Copy, Serialize)]
#[serde(rename_all = "snake_case")]
#[allow(dead_code)]
pub enum EventType {
Check,
Release,
VersionBump,
Init,
Error,
}

#[derive(Serialize)]
struct EventPayload {
event_type: String,
event_type: EventType,
#[serde(skip_serializing_if = "Option::is_none")]
package_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
Expand All @@ -25,7 +36,7 @@ fn api_url() -> String {
}

pub fn send_event(
event_type: &str,
event_type: EventType,
package_name: Option<&str>,
package_version: Option<&str>,
metadata: Option<serde_json::Value>,
Expand All @@ -35,7 +46,7 @@ pub fn send_event(
}

let payload = EventPayload {
event_type: event_type.to_string(),
event_type,
package_name: package_name.map(String::from),
package_version: package_version.map(String::from),
metadata,
Expand All @@ -51,3 +62,115 @@ pub fn send_event(
.send_json(&payload);
});
}

#[cfg(test)]
mod tests {
use super::*;

unsafe fn set_env(key: &str, val: &str) {
unsafe { std::env::set_var(key, val) }
}

unsafe fn unset_env(key: &str) {
unsafe { std::env::remove_var(key) }
}

#[test]
fn event_type_serializes_to_snake_case() {
assert_eq!(
serde_json::to_string(&EventType::Check).unwrap(),
"\"check\""
);
assert_eq!(
serde_json::to_string(&EventType::Release).unwrap(),
"\"release\""
);
assert_eq!(
serde_json::to_string(&EventType::VersionBump).unwrap(),
"\"version_bump\""
);
assert_eq!(serde_json::to_string(&EventType::Init).unwrap(), "\"init\"");
assert_eq!(
serde_json::to_string(&EventType::Error).unwrap(),
"\"error\""
);
}

#[test]
fn payload_skips_none_fields() {
let payload = EventPayload {
event_type: EventType::Check,
package_name: None,
package_version: None,
metadata: None,
};
let json = serde_json::to_value(&payload).unwrap();
assert!(!json.as_object().unwrap().contains_key("package_name"));
assert!(!json.as_object().unwrap().contains_key("package_version"));
assert!(!json.as_object().unwrap().contains_key("metadata"));
}

#[test]
fn payload_includes_present_fields() {
let payload = EventPayload {
event_type: EventType::Release,
package_name: Some("my-pkg".into()),
package_version: Some("1.0.0".into()),
metadata: None,
};
let json = serde_json::to_value(&payload).unwrap();
assert_eq!(json["event_type"], "release");
assert_eq!(json["package_name"], "my-pkg");
assert_eq!(json["package_version"], "1.0.0");
}

#[test]
fn disabled_by_env_var() {
unsafe {
for val in &["false", "0", "off", "no", "FALSE", "Off", "NO"] {
set_env("FERRFLOW_TELEMETRY", val);
assert!(!is_enabled(), "should be disabled for {val}");
}
unset_env("FERRFLOW_TELEMETRY");
}
}

#[test]
fn enabled_by_default() {
unsafe { unset_env("FERRFLOW_TELEMETRY") };
assert!(is_enabled());
}

#[test]
fn enabled_when_set_to_true() {
unsafe {
set_env("FERRFLOW_TELEMETRY", "true");
assert!(is_enabled());
unset_env("FERRFLOW_TELEMETRY");
}
}

#[test]
fn api_url_defaults() {
unsafe { unset_env("FERRFLOW_API_URL") };
assert_eq!(api_url(), "https://api.ferrflow.com");
}

#[test]
fn api_url_from_env() {
unsafe {
set_env("FERRFLOW_API_URL", "http://localhost:3000");
assert_eq!(api_url(), "http://localhost:3000");
unset_env("FERRFLOW_API_URL");
}
}

#[test]
fn send_event_noop_when_disabled() {
unsafe {
set_env("FERRFLOW_TELEMETRY", "false");
send_event(EventType::Check, None, None, None);
unset_env("FERRFLOW_TELEMETRY");
}
}
}
Loading