• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lpenz / github-workflows-update / 16634235856

30 Jul 2025 09:31PM UTC coverage: 44.828% (-1.0%) from 45.818%
16634235856

push

github

invalid-email-address
Fix new warnings about not using variables in format

0 of 4 new or added lines in 2 files covered. (0.0%)

4 existing lines in 2 files now uncovered.

117 of 261 relevant lines covered (44.83%)

1.42 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.79
/src/updater/github.rs
1
// Copyright (C) 2022 Leandro Lisboa Penz <lpenz@lpenz.org>
2
// This file is subject to the terms and conditions defined in
3
// file 'LICENSE', which is part of this source code package.
4

5
use reqwest::header::USER_AGENT;
6
use tracing::instrument;
7
use url::Url;
8

9
use crate::error::Error;
10
use crate::error::Result;
11
use crate::version::Version;
12

13
#[instrument(level = "debug")]
14
async fn get_json(url: &Url) -> Result<serde_json::Value> {
15
    let client = reqwest::Client::new();
16
    let mut builder = client.get(url.as_str());
17
    builder = builder.header(USER_AGENT, "reqwest");
18
    builder = builder.header("Accept", "application/vnd.github.v3+json");
19
    if let Ok(token) = std::env::var("PERSONAL_TOKEN") {
20
        builder = builder.header("Authorization", format!("token {token}"));
21
    }
22
    let response = builder.send().await?;
23
    if !response.status().is_success() {
24
        return Err(Error::HttpError(url.clone(), response.status()));
25
    }
26
    Ok(response.json::<serde_json::Value>().await?)
27
}
28

29
#[instrument(level = "debug")]
30
fn parse_versions(data: serde_json::Value) -> Result<Vec<Version>> {
31
    let re_ref = regex::Regex::new(r"^refs/tags/(?P<version>.+)$").unwrap();
32
    data.as_array()
33
        .ok_or_else(|| Error::JsonParsing("invalid type for layer object list".into()))?
×
34
        .iter()
35
        .map(|tag_obj| {
4✔
36
            tag_obj
4✔
37
                .as_object()
4✔
38
                .ok_or_else(|| Error::JsonParsing("invalid type for tag object".into()))?
4✔
39
                .get("ref")
4✔
40
                .ok_or_else(|| Error::JsonParsing("ref field not found in tag object".into()))
4✔
41
                .map(|ref_value| {
4✔
42
                    let version_str = ref_value.as_str().ok_or_else(|| {
4✔
43
                        Error::JsonParsing("invalid type for ref field in tag object".into())
×
UNCOV
44
                    })?;
×
45
                    let m = re_ref.captures(version_str).ok_or_else(|| {
4✔
46
                        Error::JsonParsing(format!(
×
NEW
47
                            "could not match github ref {version_str} to tag regex"
×
48
                        ))
×
UNCOV
49
                    })?;
×
50
                    let version_str = m.name("version").unwrap().as_str();
4✔
51
                    Version::new(version_str)
4✔
52
                        .ok_or_else(|| Error::VersionParsing(version_str.into()))
4✔
53
                })?
4✔
54
        })
4✔
55
        .collect::<Result<Vec<Version>>>()
56
}
57

58
#[instrument(level = "debug")]
59
pub async fn get_versions(url: &Url) -> Result<Vec<Version>> {
60
    let data = get_json(url).await?;
61
    let versions = parse_versions(data)?;
62
    Ok(versions)
63
}
64

65
#[test]
66
fn test_docker_parse_versions() -> Result<()> {
1✔
67
    let json_str = r#"
1✔
68
[
1✔
69
  {
1✔
70
    "ref": "refs/tags/v0.1",
1✔
71
    "node_id": "REF_kwDOHcsoLq5yZWZzL3RhZ3MvdjAuMQ",
1✔
72
    "url": "https://api.github.com/repos/lpenz/ghworkflow-rust/git/refs/tags/v0.1",
1✔
73
    "object": {
1✔
74
      "sha": "ca550057e88e5885030e756b90bd040ad7840cee",
1✔
75
      "type": "commit",
1✔
76
      "url": "https://api.github.com/repos/lpenz/ghworkflow-rust/git/commits/ca550057e88e5885030e756b90bd040ad7840cee"
1✔
77
    }
1✔
78
  },
1✔
79
  {
1✔
80
    "ref": "refs/tags/0.2",
1✔
81
    "node_id": "REF_kwDOHcsoLq5yZWZzL3RhZ3MvdjAuMg",
1✔
82
    "url": "https://api.github.com/repos/lpenz/ghworkflow-rust/git/refs/tags/v0.2",
1✔
83
    "object": {
1✔
84
      "sha": "2b80e7d13e4b1738a17887b4d66143433267cea6",
1✔
85
      "type": "commit",
1✔
86
      "url": "https://api.github.com/repos/lpenz/ghworkflow-rust/git/commits/2b80e7d13e4b1738a17887b4d66143433267cea6"
1✔
87
    }
1✔
88
  },
1✔
89
  {
1✔
90
    "ref": "refs/tags/latest",
1✔
91
    "node_id": "REF_kwDOHcsoLq5yZWZzL3RhZ3MvdjAuMw",
1✔
92
    "url": "https://api.github.com/repos/lpenz/ghworkflow-rust/git/refs/tags/v0.3",
1✔
93
    "object": {
1✔
94
      "sha": "c7d367f5f10a2605aa43a540f9f88177d5fa12ac",
1✔
95
      "type": "commit",
1✔
96
      "url": "https://api.github.com/repos/lpenz/ghworkflow-rust/git/commits/c7d367f5f10a2605aa43a540f9f88177d5fa12ac"
1✔
97
    }
1✔
98
  },
1✔
99
  {
1✔
100
    "ref": "refs/tags/v0.4",
1✔
101
    "node_id": "REF_kwDOHcsoLq5yZWZzL3RhZ3MvdjAuNA",
1✔
102
    "url": "https://api.github.com/repos/lpenz/ghworkflow-rust/git/refs/tags/v0.4",
1✔
103
    "object": {
1✔
104
      "sha": "04bb04c23563d3302fe6ca0c2b832e9e67c47d58",
1✔
105
      "type": "commit",
1✔
106
      "url": "https://api.github.com/repos/lpenz/ghworkflow-rust/git/commits/04bb04c23563d3302fe6ca0c2b832e9e67c47d58"
1✔
107
    }
1✔
108
  }
1✔
109
]
1✔
110
"#;
1✔
111
    let json_value: serde_json::Value = serde_json::from_str(json_str)?;
1✔
112
    let mut versions = parse_versions(json_value)?.into_iter().collect::<Vec<_>>();
1✔
113
    versions.sort();
1✔
114
    let versions = versions
1✔
115
        .into_iter()
1✔
116
        .map(|v| format!("{}", v))
4✔
117
        .collect::<Vec<_>>();
1✔
118
    assert_eq!(versions, ["latest", "v0.1", "0.2", "v0.4"]);
1✔
119
    Ok(())
1✔
120
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc