Skip to main content

ossctl_core/release/adapters/
go.rs

1//! Go ecosystem adapter: `goreleaser`.
2//!
3//! Go modules are consumed straight from a pushed git tag (there is no upload to
4//! a mutable registry), so a "publish" here is `GoReleaser` building and attaching
5//! artifacts to the GitHub Release; module availability is fronted by the
6//! immutable module proxy. `verify` uses the default [`RegistryQuery`] path
7//! against `proxy.golang.org`.
8
9use std::time::Duration;
10
11use crate::contract::schema::Adapter;
12use crate::protocol::release::{BuildArtifacts, DryRunReport, PlannedCommand, PublishReceipt};
13
14use super::{make_receipt, run_all, AdapterError, AdapterTarget, EffectCtx, ReleaseAdapter};
15
16/// The go release adapter, operating as `goreleaser`.
17pub struct GoAdapter {
18    adapter: Adapter,
19}
20
21impl GoAdapter {
22    /// Construct for the resolved `goreleaser` adapter identity.
23    #[must_use]
24    pub fn new(adapter: Adapter) -> Self {
25        debug_assert!(matches!(adapter, Adapter::Goreleaser));
26        Self { adapter }
27    }
28}
29
30impl ReleaseAdapter for GoAdapter {
31    fn adapter(&self) -> Adapter {
32        self.adapter
33    }
34
35    fn dry_run(
36        &self,
37        _ctx: &EffectCtx<'_>,
38        _t: &AdapterTarget,
39    ) -> Result<DryRunReport, AdapterError> {
40        Ok(DryRunReport {
41            adapter: self.adapter,
42            planned_commands: vec![PlannedCommand::new(
43                "goreleaser",
44                &["release", "--snapshot", "--clean", "--skip=publish"],
45            )],
46            notes: vec![],
47        })
48    }
49
50    fn build(
51        &self,
52        ctx: &EffectCtx<'_>,
53        _t: &AdapterTarget,
54    ) -> Result<BuildArtifacts, AdapterError> {
55        run_all(
56            ctx,
57            &[PlannedCommand::new(
58                "goreleaser",
59                &["build", "--snapshot", "--clean"],
60            )],
61        )?;
62        // SKELETON: a production build reads dist/artifacts.json for the exact
63        // per-platform binary set.
64        Ok(BuildArtifacts {
65            adapter: self.adapter,
66            artifacts: vec!["dist/".to_string()],
67            notes: vec![],
68        })
69    }
70
71    fn publish(
72        &self,
73        ctx: &EffectCtx<'_>,
74        t: &AdapterTarget,
75    ) -> Result<PublishReceipt, AdapterError> {
76        // PER-TARGET IRREVERSIBLE (attaches artifacts to the GitHub Release).
77        run_all(
78            ctx,
79            &[PlannedCommand::new("goreleaser", &["release", "--clean"])],
80        )?;
81        Ok(make_receipt(ctx, t, None, None))
82    }
83
84    fn timeout(&self) -> Duration {
85        Duration::from_secs(900)
86    }
87}