Show telemetry notice on install instead of first run (#832)

Move the telemetry opt-out notice from a runtime banner (shown on first
CLI command) to the install script so users see it exactly once at
install time. Remove the Notices JSON persistence that tracked whether
the banner had been shown.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jake Cooper 2026-04-03 18:45:07 +09:00 committed by GitHub
parent b5130a3c4e
commit 15e738f2fa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 6 additions and 56 deletions

View file

@ -522,3 +522,6 @@ _/j L l\_! _//^---^\\_
EOF EOF
printf "$NO_COLOR" printf "$NO_COLOR"
info "Railway collects anonymous CLI usage data to improve the developer experience."
info "You can opt out anytime: ${BOLD}railway telemetry disable${NO_COLOR} or ${BOLD}RAILWAY_NO_TELEMETRY=1${NO_COLOR}"

View file

@ -105,8 +105,6 @@ async fn handle_update_task(
async fn main() -> Result<()> { async fn main() -> Result<()> {
let args = build_args().try_get_matches(); let args = build_args().try_get_matches();
let check_updates_handle = if std::io::stdout().is_terminal() { let check_updates_handle = if std::io::stdout().is_terminal() {
telemetry::show_notice_if_needed();
let update = UpdateCheck::read().unwrap_or_default(); let update = UpdateCheck::read().unwrap_or_default();
if let Some(latest_version) = update.latest_version { if let Some(latest_version) = update.latest_version {

View file

@ -1,58 +1,7 @@
use colored::Colorize;
use crate::client::{GQLClient, post_graphql}; use crate::client::{GQLClient, post_graphql};
use crate::config::Configs; use crate::config::Configs;
use crate::gql::mutations::{self, cli_event_track}; use crate::gql::mutations::{self, cli_event_track};
#[derive(serde::Serialize, serde::Deserialize, Default)]
#[serde(rename_all = "camelCase")]
struct Notices {
telemetry_notice_shown: bool,
}
impl Notices {
fn path() -> Option<std::path::PathBuf> {
dirs::home_dir().map(|h| h.join(".railway/notices.json"))
}
fn read() -> Self {
Self::path()
.and_then(|p| std::fs::read_to_string(p).ok())
.and_then(|s| serde_json::from_str(&s).ok())
.unwrap_or_default()
}
fn write(&self) {
if let Some(path) = Self::path() {
let _ = serde_json::to_string(self)
.ok()
.map(|contents| std::fs::write(path, contents));
}
}
}
pub fn show_notice_if_needed() {
if is_telemetry_disabled() {
return;
}
let notices = Notices::read();
if notices.telemetry_notice_shown {
return;
}
eprintln!(
"{}\nYou can opt out by running `railway telemetry disable` or by setting RAILWAY_NO_TELEMETRY=1 in your environment.\n{}",
"Railway now collects CLI usage data to improve the developer experience.".bold(),
format!("Learn more: {}", "https://docs.railway.com/cli/telemetry").dimmed(),
);
Notices {
telemetry_notice_shown: true,
}
.write();
}
pub struct CliTrackEvent { pub struct CliTrackEvent {
pub command: String, pub command: String,
pub sub_command: Option<String>, pub sub_command: Option<String>,