ci_detective/
circle.rs

1use env;
2
3/// Circle CI
4///
5/// # References
6///
7/// - <https://circleci.com/docs/1.0/environment-variables/>
8/// - <https://github.com/codecov/codecov-bash/blob/8b76995ad4a95a61cecd4b049a448a402d91d197/codecov#L548-L568>
9#[derive(Clone, Debug)]
10#[cfg_attr(feature = "nightly", non_exhaustive)]
11pub struct Circle {
12    /// The username or organization name of the project being tested,
13    /// i.e. `foo` in `circleci.com/gh/foo/bar/123`
14    project_username: String,
15    /// The repository name of the project being tested,
16    /// i.e. `bar` in `circleci.com/gh/foo/bar/123`
17    project_reponame: String,
18    /// The name of the Git branch being tested, e.g. `master`,
19    /// if the build is running for a branch.
20    branch: Option<String>,
21    /// The name of the git tag being tested, e.g. `release-v1.5.4`,
22    /// if the build is running [for a tag](https://circleci.com/docs/1.0/configuration/#tags).
23    tag: Option<String>,
24    /// The SHA1 of the commit being tested.
25    sha1: String,
26    /// A link to the homepage for the current repository,
27    /// for example, `https://github.com/circleci/frontend`.
28    repository_url: String,
29    /// A link to GitHub’s comparison view for this push.
30    /// Not present for builds that are triggered by GitHub pushes.
31    compare_url: Option<String>,
32    /// A permanent link to the current build,
33    /// for example, `https://circleci.com/gh/circleci/frontend/933`.
34    build_url: String,
35    /// The build number, same as in `circleci.com/gh/foo/bar/123`
36    build_num: usize,
37    /// The build number of the previous build, same as in `circleci.com/gh/foo/bar/123`
38    previous_build_num: Option<usize>,
39    /// Comma-separated list of pull requests this build is a part of.
40    pull_requests: Option<String>,
41    /// If this build is part of only one pull request, its URL will be populated here. If there was
42    /// more than one pull request, it will contain one of the pull request URLs (picked randomly).
43    pull_request: Option<String>,
44    /// The directory whose contents are automatically saved as
45    /// [build artifacts](https://circleci.com/docs/1.0/build-artifacts/).
46    artifacts: String,
47    /// The GitHub login of the user who either pushed the code
48    /// to GitHub or triggered the build from the UI/API.
49    username: String,
50    /// The directory whose contents are automatically processed as
51    /// [JUnit test metadata](https://circleci.com/docs/1.0/test-metadata/).
52    test_reports: String,
53    /// When the build is a part of a pull request from a fork,
54    /// The username of the owner of the fork.
55    pr_username: Option<String>,
56    /// When the build is a part of a pull request from a fork,
57    /// The name of the repository the pull request was submitted from.
58    pr_reponame: Option<String>,
59    /// When the build is a part of a pull request from a fork,
60    /// The number of the pull request this build forms part of.
61    pr_number: Option<usize>,
62    /// The total number of nodes across which the current test is running.
63    node_total: usize,
64    /// The index (0-based) of the current node.
65    node_index: usize,
66    /// The build image this build runs on.
67    build_image: String,
68    non_exhaustive: (),
69}
70
71impl Circle {
72    /// Construct this provider's information from the environment.
73    pub fn from_env() -> Option<Self> {
74        if !(env("CI")? == "true" && env("CIRCLECI")? == "true") {
75            return None;
76        }
77
78        Some(Circle {
79            project_username: env("CIRCLE_PROJECT_USERNAME")?,
80            project_reponame: env("CIRCLE_PROJECT_REPONAME")?,
81            branch: env("CIRCLE_BRANCH"),
82            tag: env("CIRCLE_TAG"),
83            sha1: env("CIRCLE_SHA1")?,
84            repository_url: env("CIRCLE_REPOSITORY_URL")?,
85            compare_url: env("CIRCLE_COMPARE_URL"),
86            build_url: env("CIRCLE_BUILD_URL")?,
87            build_num: env("CIRCLE_BUILD_NUM")?.parse().ok()?,
88            previous_build_num: env("CIRCLE_PREVIOUS_BUILD_NUM").and_then(|it| it.parse().ok()),
89            pull_requests: env("CI_PULL_REQUESTS"),
90            pull_request: env("CI_PULL_REQUEST"),
91            artifacts: env("CIRCLE_ARTIFACTS")?,
92            username: env("CIRCLE_USERNAME")?,
93            test_reports: env("CIRCLE_TEST_REPORTS")?,
94            pr_username: env("CIRCLE_PR_USERNAME"),
95            pr_reponame: env("CIRCLE_PR_REPONAME"),
96            pr_number: env("CIRCLE_PR_NUMBER").and_then(|it| it.parse().ok()),
97            node_total: env("CIRCLE_NODE_TOTAL")?.parse().ok()?,
98            node_index: env("CIRCLE_NODE_INDEX")?.parse().ok()?,
99            build_image: env("CIRCLE_BUILD_IMAGE")?,
100            non_exhaustive: (),
101        })
102    }
103}