steps.rs

  1use gh_workflow::*;
  2
  3pub fn checkout_repo() -> Step<Use> {
  4    named::uses(
  5        "actions",
  6        "checkout",
  7        "11bd71901bbe5b1630ceea73d27597364c9af683", // v4
  8    )
  9}
 10
 11pub fn setup_pnpm() -> Step<Use> {
 12    named::uses(
 13        "pnpm",
 14        "action-setup",
 15        "fe02b34f77f8bc703788d5817da081398fad5dd2", // v4.0.0
 16    )
 17    .add_with(("version", "9"))
 18}
 19
 20pub mod danger {
 21    use super::*;
 22
 23    pub fn setup_node() -> Step<Use> {
 24        named::uses(
 25            "actions",
 26            "setup-node",
 27            "49933ea5288caeca8642d1e84afbd3f7d6820020", // v4
 28        )
 29        .add_with(("node-version", "20"))
 30        .add_with(("cache", "pnpm"))
 31        .add_with(("cache-dependency-path", "script/danger/pnpm-lock.yaml"))
 32    }
 33
 34    pub fn install_deps() -> Step<Run> {
 35        named::run("pnpm install --dir script/danger")
 36    }
 37
 38    pub fn run() -> Step<Run> {
 39        named::run("pnpm run --dir script/danger danger ci")
 40            // This GitHub token is not used, but the value needs to be here to prevent
 41            // Danger from throwing an error.
 42            .add_env(("GITHUB_TOKEN", "not_a_real_token"))
 43            // All requests are instead proxied through an instance of
 44            // https://github.com/maxdeviant/danger-proxy that allows Danger to securely
 45            // authenticate with GitHub while still being able to run on PRs from forks.
 46            .add_env((
 47                "DANGER_GITHUB_API_BASE_URL",
 48                "https://danger-proxy.fly.dev/github",
 49            ))
 50    }
 51}
 52
 53pub mod nix {
 54    use indoc::indoc;
 55
 56    use crate::tasks::workflows::vars;
 57
 58    use super::*;
 59
 60    // on our macs we manually install nix. for some reason the cachix action is running
 61    // under a non-login /bin/bash shell which doesn't source the proper script to add the
 62    // nix profile to PATH, so we manually add them here
 63    pub fn set_path() -> Step<Run> {
 64        named::run(indoc! {r#"
 65            echo "/nix/var/nix/profiles/default/bin" >> "$GITHUB_PATH"
 66            echo "/Users/administrator/.nix-profile/bin" >> "$GITHUB_PATH"
 67        "#})
 68    }
 69
 70    pub fn install_nix() -> Step<Use> {
 71        named::uses(
 72            "cachix",
 73            "install-nix-action",
 74            "02a151ada4993995686f9ed4f1be7cfbb229e56f", // v31
 75        )
 76        .add_with(("github_access_token", vars::GITHUB_TOKEN))
 77    }
 78
 79    pub fn cachix_action(cachix_filter: &str) -> Step<Use> {
 80        named::uses(
 81            "cachix",
 82            "cachix-action",
 83            "0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad", // v16
 84        )
 85        .add_with(("name", "zed"))
 86        .add_with(("authToken", vars::CACHIX_AUTH_TOKEN))
 87        .add_with(("pushFilter", cachix_filter))
 88        .add_with(("cachixArgs", "-v"))
 89    }
 90
 91    pub fn build(flake_output: &str) -> Step<Run> {
 92        named::run(&format!(
 93            "nix build .#{} -L --accept-flake-config",
 94            flake_output
 95        ))
 96    }
 97
 98    pub fn limit_store() -> Step<Run> {
 99        named::run(indoc! {r#"
100            if [ "$(du -sm /nix/store | cut -f1)" -gt 50000 ]; then
101                nix-collect-garbage -d || true
102            fi"#
103        })
104    }
105}
106
107// (janky) helpers to generate steps with a name that corresponds
108// to the name of the calling function.
109mod named {
110    use gh_workflow::*;
111
112    pub(super) fn uses(owner: &str, repo: &str, ref_: &str) -> Step<Use> {
113        Step::new(function_name(1)).uses(owner, repo, ref_)
114    }
115
116    pub(super) fn run(script: &str) -> Step<Run> {
117        Step::new(function_name(1))
118            .run(script)
119            .shell("bash -euxo pipefail {0}")
120    }
121
122    fn function_name(i: usize) -> String {
123        let mut name = "<unknown>".to_string();
124        let mut count = 0;
125        backtrace::trace(|frame| {
126            if count < i + 3 {
127                count += 1;
128                return true;
129            }
130            backtrace::resolve_frame(frame, |cb| {
131                if let Some(s) = cb.name() {
132                    name = s.to_string()
133                }
134            });
135            false
136        });
137        name.split("::")
138            .skip_while(|s| s != &"steps")
139            .collect::<Vec<_>>()
140            .join("::")
141    }
142}