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}