actions_github/
context.rs1use std::{env, fs, path::Path};
11
12use crate::error::ActionsError;
13use json::JsonValue;
14
15#[derive(Debug, Clone)]
20pub struct Context {
21 pub payload: JsonValue,
22 pub event_name: String,
23 pub sha: String,
24 pub ref_: String,
25 pub workflow: String,
26 pub action: String,
27 pub actor: String,
28 pub job: String,
29 pub run_attempt: u8,
30 pub run_number: u8,
31 pub run_id: u128,
32 pub api_url: String,
33 pub server_url: String,
34 pub graphql_url: String,
35 pub repo: Repo,
36}
37
38#[derive(Debug, Clone)]
39pub struct Repo {
41 pub owner: String,
42 pub repo: String,
43}
44
45pub fn get_context() -> Result<Context, ActionsError> {
56 let mut payload: JsonValue = JsonValue::Null;
57
58 if let Ok(github_event_path) = env::var("GITHUB_EVENT_PATH") {
59 if Path::new(&github_event_path).exists() {
60 match fs::read_to_string(&github_event_path) {
61 Ok(content) => match json::parse(&content) {
62 Ok(parsed_json) => payload = parsed_json,
63 Err(err) => println!("Failed to parse JSON: {}", err),
64 },
65 Err(err) => println!("Failed to read file: {}", err),
66 }
67 } else {
68 println!("GITHUB_EVENT_PATH {} does not exist", github_event_path)
69 }
70 }
71
72 let repo: Repo = get_repo(&payload)?;
73
74 Ok(Context {
75 payload,
76 event_name: get_env("GITHUB_EVENT_NAME")?,
77 sha: get_env("GITHUB_SHA")?,
78 ref_: get_env("GITHUB_REF")?,
79 workflow: get_env("GITHUB_WORKFLOW")?,
80 action: get_env("GITHUB_ACTION")?,
81 actor: get_env("GITHUB_ACTOR")?,
82 job: get_env("GITHUB_JOB")?,
83 run_attempt: get_env("GITHUB_RUN_ATTEMPT")?.parse::<u8>().unwrap(),
84 run_number: get_env("GITHUB_RUN_NUMBER")?.parse::<u8>().unwrap(),
85 run_id: get_env("GITHUB_RUN_ID")?.parse::<u128>().unwrap(),
86 api_url: get_env_or("GITHUB_API_URL", "https://api.github.com"),
87 server_url: get_env_or("GITHUB_SERVER_URL", "https://github.com"),
88 graphql_url: get_env_or("GITHUB_GRAPHQL_URL", "https://api.github.com/graphql"),
89 repo,
90 })
91}
92
93fn get_env(var_name: &str) -> Result<String, ActionsError> {
94 match env::var(var_name) {
95 Ok(var) => Ok(var),
96 Err(_) => Err(ActionsError::Context(var_name.to_string())),
97 }
98}
99
100fn get_env_or(var_name: &str, default: &str) -> String {
101 match env::var(var_name) {
102 Ok(var) => var,
103 Err(_) => default.to_string(),
104 }
105}
106
107fn get_repo(payload: &JsonValue) -> Result<Repo, ActionsError> {
108 if let Ok(repository) = env::var("GITHUB_REPOSITORY") {
110 let owner_repo = repository.split('/').collect::<Vec<&str>>();
111
112 return Ok(Repo {
113 owner: owner_repo[0].to_string(),
114 repo: owner_repo[1].to_string(),
115 });
116 }
117
118 let owner = payload["repository"]["login"]["login"].clone();
119 let repo = payload["repository"]["name"].clone();
120
121 if owner.is_null() || repo.is_null() {
122 Err(ActionsError::Context(
123 "context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'"
124 .to_string(),
125 ))
126 } else {
127 Ok(Repo {
128 owner: owner.to_string(),
129 repo: repo.to_string(),
130 })
131 }
132}