flowey_core/node/
github_context.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Core types and traits used to read GitHub context variables.
5
6use crate::node::ClaimVar;
7use crate::node::GhUserSecretVar;
8use crate::node::NodeCtx;
9use crate::node::ReadVar;
10use crate::node::StepCtx;
11use crate::node::spec::GhContextVarReaderEventPullRequest;
12use serde::Serialize;
13use serde::de::DeserializeOwned;
14use std::collections::BTreeMap;
15
16pub mod state {
17    pub enum Root {}
18    pub enum Global {}
19    pub enum Event {}
20}
21
22#[derive(Clone)]
23pub struct GhVarState {
24    pub raw_name: Option<String>,
25    pub backing_var: String,
26    pub is_secret: bool,
27    pub is_object: bool,
28}
29
30pub struct GhContextVarReader<'a, S> {
31    pub ctx: NodeCtx<'a>,
32    pub _state: std::marker::PhantomData<S>,
33}
34
35impl<S> GhContextVarReader<'_, S> {
36    fn read_var<T: Serialize + DeserializeOwned>(
37        &self,
38        var_name: impl AsRef<str>,
39        is_secret: bool,
40        is_object: bool,
41    ) -> ReadVar<T> {
42        let (var, write_var) = self.ctx.new_maybe_secret_var(is_secret, "");
43        let write_var = write_var.claim(&mut StepCtx {
44            backend: self.ctx.backend.clone(),
45        });
46        let var_state = GhVarState {
47            raw_name: Some(var_name.as_ref().to_string()),
48            backing_var: write_var.backing_var,
49            is_secret: write_var.is_secret,
50            is_object,
51        };
52        let gh_to_rust = vec![var_state];
53
54        self.ctx.backend.borrow_mut().on_emit_gh_step(
55            &format!("🌼 read {}", var_name.as_ref()),
56            "",
57            BTreeMap::new(),
58            None,
59            BTreeMap::new(),
60            BTreeMap::new(),
61            gh_to_rust,
62            Vec::new(),
63        );
64        var
65    }
66}
67
68impl<'a> GhContextVarReader<'a, state::Root> {
69    /// Access variables that are globally available `github.repository`, `github.workspace`, etc.
70    pub fn global(self) -> GhContextVarReader<'a, state::Global> {
71        GhContextVarReader {
72            ctx: self.ctx,
73            _state: std::marker::PhantomData,
74        }
75    }
76
77    /// Access variables that are only available in the context of a GitHub event. `github.event.pull_request`, etc.
78    pub fn event(self) -> GhContextVarReader<'a, state::Event> {
79        GhContextVarReader {
80            ctx: self.ctx,
81            _state: std::marker::PhantomData,
82        }
83    }
84
85    /// Access a secret
86    pub fn secret(self, secret: GhUserSecretVar) -> ReadVar<String> {
87        self.read_var(format!("secrets.{}", secret.0), true, false)
88    }
89}
90
91impl GhContextVarReader<'_, state::Global> {
92    /// `github.repository`
93    pub fn repository(self) -> ReadVar<String> {
94        self.read_var("github.repository", false, false)
95    }
96
97    /// `runner.temp`
98    pub fn runner_temp(self) -> ReadVar<String> {
99        self.read_var("runner.temp", false, false)
100    }
101
102    /// `github.workspace`
103    pub fn workspace(self) -> ReadVar<String> {
104        self.read_var("github.workspace", false, false)
105    }
106
107    /// `github.token`
108    pub fn token(self) -> ReadVar<String> {
109        self.read_var("github.token", true, false)
110    }
111}
112
113impl GhContextVarReader<'_, state::Event> {
114    /// `github.event.pull_request`
115    pub fn pull_request(self) -> ReadVar<Option<GhContextVarReaderEventPullRequest>> {
116        self.read_var("github.event.pull_request", false, true)
117    }
118}