Skip to content

Commit b70ac93

Browse files
committed
Add self-update functionality
- Add 'update' command to check for and install latest release - Use self_update crate for GitHub release integration - Update version to 0.2.0 - Update README and CHANGELOG with update instructions Users can now run 'cohort-tracker update' to automatically update to the latest version from GitHub releases.
1 parent a509e0b commit b70ac93

File tree

7 files changed

+75
-1
lines changed

7 files changed

+75
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Releases are tagged with the date in YYYY.MM.DD format (e.g., v2026.01.19).
77
## [Unreleased]
88

99
### Added
10+
- Self-update functionality with `update` command
11+
- Automatic version checking (checks GitHub for latest release)
1012

1113
### Changed
1214

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "cohort-tracker"
3-
version = "0.1.0"
3+
version = "0.2.0"
44
edition = "2021"
55

66
[dependencies]
@@ -21,6 +21,7 @@ chrono = "0.4"
2121
async-trait = "0.1"
2222
async-stream = "0.3"
2323
futures-util = "0.3"
24+
self_update = "0.41"
2425

2526
[dev-dependencies]
2627
tempfile = "3.8"

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ cargo run -- status
7070

7171
# Start the dashboard
7272
make serve
73+
74+
# Update to the latest version
75+
cargo run -- update
7376
```
7477

7578
## Common Commands
@@ -87,6 +90,9 @@ cargo run -- list
8790
# Activate/deactivate classes
8891
cargo run -- activate data-analysis-pathway-module-1-aug-2
8992
cargo run -- deactivate old-class-name
93+
94+
# Update to latest version
95+
cargo run -- update
9096
```
9197

9298
## Documentation

src/cli.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ pub enum Commands {
6464
#[arg(long)]
6565
mentors: Option<String>,
6666
},
67+
68+
/// Update to the latest version
69+
Update,
6770
}
6871

6972
pub async fn handle_init(email: String, password: String, api_base: String) -> Result<()> {

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ pub mod db;
55
pub mod lms;
66
pub mod models;
77
pub mod sync;
8+
pub mod update;

src/main.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ async fn main() -> Result<()> {
3737
cli::Commands::Import { students, mentors } => {
3838
cli::handle_import(students, mentors).await?;
3939
}
40+
cli::Commands::Update => {
41+
cohort_tracker::update::perform_update().await?;
42+
}
4043
}
4144

4245
Ok(())

src/update.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
use anyhow::Result;
2+
use serde::Deserialize;
3+
4+
const REPO_OWNER: &str = "cj-taylor";
5+
const REPO_NAME: &str = "codeyou-cohort-tracker";
6+
const CURRENT_VERSION: &str = env!("CARGO_PKG_VERSION");
7+
8+
#[derive(Debug, Deserialize)]
9+
struct Release {
10+
tag_name: String,
11+
}
12+
13+
pub async fn check_for_updates() -> Result<Option<String>> {
14+
let client = reqwest::Client::new();
15+
let url = format!(
16+
"https://api.github.com/repos/{}/{}/releases/latest",
17+
REPO_OWNER, REPO_NAME
18+
);
19+
20+
let response = client
21+
.get(&url)
22+
.header("User-Agent", "cohort-tracker")
23+
.send()
24+
.await?;
25+
26+
if !response.status().is_success() {
27+
return Ok(None);
28+
}
29+
30+
let release: Release = response.json().await?;
31+
32+
// Compare versions - if tag is different from current, there's an update
33+
if release.tag_name != format!("v{}", CURRENT_VERSION) {
34+
Ok(Some(release.tag_name))
35+
} else {
36+
Ok(None)
37+
}
38+
}
39+
40+
pub async fn perform_update() -> Result<()> {
41+
println!("Checking for updates...");
42+
43+
let status = self_update::backends::github::Update::configure()
44+
.repo_owner(REPO_OWNER)
45+
.repo_name(REPO_NAME)
46+
.bin_name("cohort-tracker")
47+
.current_version(CURRENT_VERSION)
48+
.build()?
49+
.update()?;
50+
51+
if status.updated() {
52+
println!("✓ Updated to version {}", status.version());
53+
} else {
54+
println!("Already up to date (version {})", CURRENT_VERSION);
55+
}
56+
57+
Ok(())
58+
}

0 commit comments

Comments
 (0)