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
22pub struct GhOutput {
23    pub backing_var: String,
24    pub is_secret: bool,
25    pub is_object: bool,
26}
27
28#[derive(Clone)]
29pub struct GhToRust {
30    pub raw_name: String,
31    pub backing_var: String,
32    pub is_secret: bool,
33    pub is_object: bool,
34}
35
36#[derive(Clone)]
37pub struct RustToGh {
38    pub raw_name: String,
39    pub backing_var: String,
40    pub is_object: bool,
41}
42
43pub struct GhContextVarReader<'a, S> {
44    pub ctx: NodeCtx<'a>,
45    pub _state: std::marker::PhantomData<S>,
46}
47
48impl<S> GhContextVarReader<'_, S> {
49    fn read_var<T: Serialize + DeserializeOwned>(
50        &self,
51        var_name: impl AsRef<str>,
52        is_secret: bool,
53        is_object: bool,
54    ) -> ReadVar<T> {
55        let (var, write_var) = self.ctx.new_prefixed_var("");
56        let write_var = write_var.claim(&mut StepCtx {
57            backend: self.ctx.backend.clone(),
58        });
59        let var_state = GhToRust {
60            raw_name: var_name.as_ref().to_string(),
61            backing_var: write_var.backing_var,
62            is_secret,
63            is_object,
64        };
65        let gh_to_rust = vec![var_state];
66
67        self.ctx.backend.borrow_mut().on_emit_gh_step(
68            &format!("🌼 read {}", var_name.as_ref()),
69            "",
70            BTreeMap::new(),
71            None,
72            BTreeMap::new(),
73            BTreeMap::new(),
74            gh_to_rust,
75            Vec::new(),
76        );
77        var
78    }
79}
80
81impl<'a> GhContextVarReader<'a, state::Root> {
82    /// Access variables that are globally available `github.repository`, `github.workspace`, etc.
83    pub fn global(self) -> GhContextVarReader<'a, state::Global> {
84        GhContextVarReader {
85            ctx: self.ctx,
86            _state: std::marker::PhantomData,
87        }
88    }
89
90    /// Access variables that are only available in the context of a GitHub event. `github.event.pull_request`, etc.
91    pub fn event(self) -> GhContextVarReader<'a, state::Event> {
92        GhContextVarReader {
93            ctx: self.ctx,
94            _state: std::marker::PhantomData,
95        }
96    }
97
98    /// Access a secret
99    pub fn secret(self, secret: GhUserSecretVar) -> ReadVar<String> {
100        self.read_var(format!("secrets.{}", secret.0), true, false)
101    }
102}
103
104impl GhContextVarReader<'_, state::Global> {
105    /// `github.repository`
106    pub fn repository(self) -> ReadVar<String> {
107        self.read_var("github.repository", false, false)
108    }
109
110    /// `runner.temp`
111    pub fn runner_temp(self) -> ReadVar<String> {
112        self.read_var("runner.temp", false, false)
113    }
114
115    /// `github.workspace`
116    pub fn workspace(self) -> ReadVar<String> {
117        self.read_var("github.workspace", false, false)
118    }
119
120    /// `github.token`
121    pub fn token(self) -> ReadVar<String> {
122        self.read_var("github.token", true, false)
123    }
124}
125
126impl GhContextVarReader<'_, state::Event> {
127    /// `github.event.pull_request`
128    pub fn pull_request(self) -> ReadVar<Option<GhContextVarReaderEventPullRequest>> {
129        self.read_var("github.event.pull_request", false, true)
130    }
131}