use std::time::Duration;
use crate::contract::schema::Adapter;
use crate::protocol::release::{BuildArtifacts, DryRunReport, PlannedCommand, PublishReceipt};
use super::{make_receipt, run_all, AdapterError, AdapterTarget, EffectCtx, ReleaseAdapter};
pub struct NodeAdapter {
adapter: Adapter,
}
impl NodeAdapter {
#[must_use]
pub fn new(adapter: Adapter) -> Self {
debug_assert!(matches!(
adapter,
Adapter::ReleasePlease | Adapter::Changesets | Adapter::NpmPublish
));
Self { adapter }
}
}
impl ReleaseAdapter for NodeAdapter {
fn adapter(&self) -> Adapter {
self.adapter
}
fn dry_run(
&self,
_ctx: &EffectCtx<'_>,
_t: &AdapterTarget,
) -> Result<DryRunReport, AdapterError> {
let (planned_commands, notes) = match self.adapter {
Adapter::Changesets => (
vec![PlannedCommand::new("changeset", &["status", "--verbose"])],
vec![],
),
Adapter::ReleasePlease => (
vec![PlannedCommand::new(
"release-please",
&["release-pr", "--dry-run"],
)],
vec!["release-please publishes on merge via CI, not from this host".to_string()],
),
_ => (
vec![PlannedCommand::new("npm", &["publish", "--dry-run"])],
vec![],
),
};
Ok(DryRunReport {
adapter: self.adapter,
planned_commands,
notes,
})
}
fn build(
&self,
ctx: &EffectCtx<'_>,
t: &AdapterTarget,
) -> Result<BuildArtifacts, AdapterError> {
run_all(ctx, &[PlannedCommand::new("npm", &["pack"])])?;
Ok(BuildArtifacts {
adapter: self.adapter,
artifacts: vec![format!("{}-{}.tgz", t.package, t.version)],
notes: vec![],
})
}
fn publish(
&self,
ctx: &EffectCtx<'_>,
t: &AdapterTarget,
) -> Result<PublishReceipt, AdapterError> {
let cmds = match self.adapter {
Adapter::Changesets => vec![PlannedCommand::new("changeset", &["publish"])],
Adapter::ReleasePlease => {
vec![PlannedCommand::new("release-please", &["github-release"])]
}
_ => vec![PlannedCommand::new("npm", &["publish"])],
};
run_all(ctx, &cmds)?;
let remote_url = Some(format!(
"https://www.npmjs.com/package/{}/v/{}",
t.package, t.version
));
Ok(make_receipt(ctx, t, None, remote_url))
}
fn timeout(&self) -> Duration {
Duration::from_secs(600)
}
}