Skip to main content

flowey_lib_common/
attest_build_provenance.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Generate GitHub build provenance attestations for a set of files.
5
6use flowey::node::prelude::*;
7
8flowey_request! {
9    pub struct Request {
10        pub files: ReadVar<Vec<(PathBuf, Option<String>)>>,
11        pub done: WriteVar<SideEffect>,
12    }
13}
14
15new_simple_flow_node!(struct Node);
16
17impl SimpleFlowNode for Node {
18    type Request = Request;
19
20    fn imports(_ctx: &mut ImportCtx<'_>) {}
21
22    fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
23        let Request { files, done } = request;
24        let subject_paths = files.map(ctx, |files| {
25            files
26                .into_iter()
27                .map(|(path, _)| path.to_string_lossy().into_owned())
28                .collect::<Vec<_>>()
29                .join("\n")
30        });
31
32        let attested = if matches!(ctx.backend(), FlowBackend::Github) {
33            ctx.emit_gh_step(
34                "Attest release artifacts",
35                "actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6",
36            )
37            .with("subject-path", subject_paths)
38            .requires_permission(GhPermission::Contents, GhPermissionValue::Read)
39            .requires_permission(GhPermission::IdToken, GhPermissionValue::Write)
40            .requires_permission(GhPermission::Attestations, GhPermissionValue::Write)
41            .requires_permission(GhPermission::ArtifactMetadata, GhPermissionValue::Write)
42            .finish(ctx)
43        } else {
44            ctx.emit_rust_step("(stub) attest release artifacts", |ctx| {
45                subject_paths.claim(ctx);
46                |_rt| {
47                    log::warn!("not running in GitHub Actions, so no attestation was generated");
48                    Ok(())
49                }
50            })
51        };
52
53        ctx.emit_side_effect_step([attested], [done]);
54        Ok(())
55    }
56}