Skip to content

Commit

Permalink
temp
Browse files Browse the repository at this point in the history
  • Loading branch information
OmarTawfik committed Jul 30, 2024
1 parent 90d9414 commit dd1e806
Show file tree
Hide file tree
Showing 8 changed files with 254 additions and 175 deletions.
57 changes: 34 additions & 23 deletions crates/infra/cli/src/commands/publish/cargo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ use std::iter::once;
use std::path::Path;

use anyhow::Result;
use clap::Parser;
use infra_utils::cargo::CargoWorkspace;
use infra_utils::commands::Command;
use infra_utils::git::TemporaryChangeset;
use infra_utils::paths::PathExtensions;
use itertools::Itertools;

use crate::utils::DryRun;

const USER_FACING_CRATES: &[&str] = &[
// Sorted by dependency order (from dependencies to dependents):
"metaslang_cst",
Expand All @@ -16,36 +19,44 @@ const USER_FACING_CRATES: &[&str] = &[
"slang_solidity",
];

pub fn publish_cargo(dry_run: bool) -> Result<()> {
let mut changeset = TemporaryChangeset::new(
"infra/cargo-publish",
"prepare Cargo packages for publishing",
)?;
#[derive(Clone, Debug, Parser)]
pub struct CargoController {
#[command(flatten)]
dry_run: DryRun,
}

impl CargoController {
pub fn execute(&self) -> Result<()> {
let mut changeset = TemporaryChangeset::new(
"infra/cargo-publish",
"prepare Cargo packages for publishing",
)?;

let mut changed_crates = vec![];
let mut changed_crates = vec![];

for crate_name in USER_FACING_CRATES {
if prepare_for_publish(crate_name, &mut changeset)? {
changed_crates.push(crate_name);
for crate_name in USER_FACING_CRATES {
if prepare_for_publish(crate_name, &mut changeset)? {
changed_crates.push(crate_name);
}
}
}

if changed_crates.is_empty() {
println!("No crates to publish.");
return Ok(());
}
if changed_crates.is_empty() {
println!("No crates to publish.");
return Ok(());
}

update_cargo_lock(&mut changeset)?;
update_cargo_lock(&mut changeset)?;

changeset.commit_changes()?;
changeset.commit_changes()?;

for crate_name in &changed_crates {
run_cargo_publish(crate_name, dry_run)?;
}
for crate_name in &changed_crates {
run_cargo_publish(crate_name, self.dry_run)?;
}

changeset.revert_changes()?;
changeset.revert_changes()?;

Ok(())
Ok(())
}
}

fn prepare_for_publish(crate_name: &str, changeset: &mut TemporaryChangeset) -> Result<bool> {
Expand Down Expand Up @@ -111,13 +122,13 @@ fn update_cargo_lock(changeset: &mut TemporaryChangeset) -> Result<()> {
Ok(())
}

fn run_cargo_publish(crate_name: &str, dry_run: bool) -> Result<()> {
fn run_cargo_publish(crate_name: &str, dry_run: DryRun) -> Result<()> {
let mut command = Command::new("cargo")
.arg("publish")
.property("--package", crate_name)
.flag("--all-features");

if dry_run {
if dry_run.get() {
command = command.flag("--dry-run");
}

Expand Down
154 changes: 81 additions & 73 deletions crates/infra/cli/src/commands/publish/changesets/mod.rs
Original file line number Diff line number Diff line change
@@ -1,96 +1,104 @@
//! This repository versions and releases all its artifacts together, generating the same changelog.
//! Unfortunately, changesets does not support combining changelogs from multiple packages into one.
//!
//! So, we let changesets bump the version of the single NPM package we ship, and generate its changelog.
//! Then our build process copies the new version and the single changelog to other packages and crates.
//!
//! Additionally, changesets can only bump versions of packages in the root workspace.
//! However, NAPI platform-specific packages cannot be added to the workspace, because other platforms will fail "npm install".
//! So we have to bump the versions over ourselves anyways.
use anyhow::Result;
use clap::Parser;
use infra_utils::cargo::CargoWorkspace;
use infra_utils::commands::Command;
use infra_utils::paths::{FileWalker, PathExtensions};

use crate::toolchains::napi::{NapiConfig, NapiResolver};

/// This repository versions and releases all its artifacts together, generating the same changelog.
/// Unfortunately, changesets does not support combining changelogs from multiple packages into one.
///
/// So, we let changesets bump the version of the single NPM package we ship, and generate its changelog.
/// Then our build process copies the new version and the single changelog to other packages and crates.
///
/// Additionally, changesets can only bump versions of packages in the root workspace.
/// However, NAPI platform-specific packages cannot be added to the workspace, because other platforms will fail "npm install".
/// So we have to bump the versions over ourselves anyways.
pub fn publish_changesets() -> Result<()> {
let resolver = NapiResolver::Solidity;
let package_dir = resolver.main_package_dir();

let package_version = NapiConfig::local_version(&package_dir)?;
println!("Package version: {package_version}");

let workspace_version = CargoWorkspace::local_version()?;
println!("Workspace version: {workspace_version}");

assert_eq!(
package_version, workspace_version,
"Package version does not match workspace version."
);

// This command will:
// 1) Consume/delete any changeset files currently in "$REPO_ROOT/.changeset"
// 2) Update the CHANGELOG.md file for the NPM package.
// 3) Bump the version in its package.json accordingly.

Command::new("changeset").arg("version").run()?;

let updated_version = NapiConfig::local_version(&package_dir)?;
println!("Updated version: {updated_version}");

if package_version == updated_version {
println!("No version changes. Skipping.");
return Ok(());
}
#[derive(Clone, Debug, Parser)]
pub struct ChangesetsController {}

impl ChangesetsController {
#[allow(clippy::unused_self)] // for compatibility with other controllers:
pub fn execute(&self) -> Result<()> {
let resolver = NapiResolver::Solidity;
let package_dir = resolver.main_package_dir();

let package_version = NapiConfig::local_version(&package_dir)?;
println!("Package version: {package_version}");

// Format the updated package files:
let workspace_version = CargoWorkspace::local_version()?;
println!("Workspace version: {workspace_version}");

let package_dir = resolver.main_package_dir();
Command::new("prettier")
.property("--write", package_dir.unwrap_str())
.run()?;
assert_eq!(
package_version, workspace_version,
"Package version does not match workspace version."
);

// Update NPM lock file:
// This command will:
// 1) Consume/delete any changeset files currently in "$REPO_ROOT/.changeset"
// 2) Update the CHANGELOG.md file for the NPM package.
// 3) Bump the version in its package.json accordingly.

Command::new("npm")
.arg("install")
.flag("--package-lock-only")
.run()?;
Command::new("changeset").arg("version").run()?;

let updated_version = NapiConfig::local_version(&package_dir)?;
println!("Updated version: {updated_version}");

if package_version == updated_version {
println!("No version changes. Skipping.");
return Ok(());
}

// Update Cargo workspace:
// Format the updated package files:

println!("Updating Cargo workspace version.");
CargoWorkspace::update_version(&updated_version)?;
let package_dir = resolver.main_package_dir();
Command::new("prettier")
.property("--write", package_dir.unwrap_str())
.run()?;

// Update Cargo lock file:
// Update NPM lock file:

Command::new("cargo")
.arg("update")
.flag("--workspace")
.run()?;
Command::new("npm")
.arg("install")
.flag("--package-lock-only")
.run()?;

// Update other CHANGELOG files:
// Update Cargo workspace:

let source_changelog = package_dir.join("CHANGELOG.md");
println!("Updating Cargo workspace version.");
CargoWorkspace::update_version(&updated_version)?;

for destination_changelog in FileWalker::from_repo_root().find(["**/CHANGELOG.md"])? {
if source_changelog != destination_changelog {
println!("Updating: {destination_changelog:?}");
std::fs::copy(&source_changelog, &destination_changelog)?;
// Update Cargo lock file:

Command::new("cargo")
.arg("update")
.flag("--workspace")
.run()?;

// Update other CHANGELOG files:

let source_changelog = package_dir.join("CHANGELOG.md");

for destination_changelog in FileWalker::from_repo_root().find(["**/CHANGELOG.md"])? {
if source_changelog != destination_changelog {
println!("Updating: {destination_changelog:?}");
std::fs::copy(&source_changelog, &destination_changelog)?;
}
}
}

Command::new("git")
.args(["stash", "push"])
.flag("--include-untracked")
.property("--message", "applied changesets")
.run()?;
Command::new("git")
.args(["stash", "push"])
.flag("--include-untracked")
.property("--message", "applied changesets")
.run()?;

println!();
println!("Source files are now updated with the new version, and stored in a 'git stash'.");
println!("The calling CI workflow will now use this stash to create a PR if needed.");
println!();
println!();
println!("Source files are now updated with the new version, and stored in a 'git stash'.");
println!("The calling CI workflow will now use this stash to create a PR if needed.");
println!();

Ok(())
Ok(())
}
}
50 changes: 30 additions & 20 deletions crates/infra/cli/src/commands/publish/github_release/mod.rs
Original file line number Diff line number Diff line change
@@ -1,39 +1,49 @@
use std::path::Path;

use anyhow::Result;
use clap::Parser;
use infra_utils::cargo::CargoWorkspace;
use infra_utils::github::GitHub;
use infra_utils::paths::PathExtensions;
use itertools::Itertools;
use markdown::{Block, Span};
use semver::Version;

pub fn publish_github_release(dry_run: bool) -> Result<()> {
let current_version = CargoWorkspace::local_version()?;
println!("Current version: {current_version}");
use crate::utils::DryRun;

let previous_version = GitHub::latest_release_version()?;
println!("Latest published version: {previous_version}");
#[derive(Clone, Debug, Parser)]
pub struct GithubReleaseController {
#[command(flatten)]
dry_run: DryRun,
}

if current_version == previous_version {
println!("Skipping release, since the workspace version is already published.");
return Ok(());
}
impl GithubReleaseController {
pub fn execute(&self) -> Result<()> {
let current_version = CargoWorkspace::local_version()?;
println!("Current version: {current_version}");

let notes = extract_latest_changelogs(&current_version, &previous_version)?;
let tag_name = format!("v{current_version}");
let previous_version = GitHub::latest_release_version()?;
println!("Latest published version: {previous_version}");

println!("Creating release '{tag_name}' with contents:");
println!();
println!("{}", notes.lines().map(|l| format!(" │ {l}")).join("\n"));
println!();
if current_version == previous_version {
println!("Skipping release, since the workspace version is already published.");
return Ok(());
}

if dry_run {
println!("Skipping release, because of the dry run.");
return Ok(());
}
let notes = extract_latest_changelogs(&current_version, &previous_version)?;
let tag_name = format!("v{current_version}");

GitHub::create_new_release(tag_name, notes)
println!("Creating release '{tag_name}' with contents:");
println!();
println!("{}", notes.lines().map(|l| format!(" │ {l}")).join("\n"));
println!();

if self.dry_run.get() {
return Ok(());
}

GitHub::create_new_release(tag_name, notes)
}
}

fn extract_latest_changelogs(
Expand Down
32 changes: 30 additions & 2 deletions crates/infra/cli/src/commands/publish/mkdocs/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,35 @@
use anyhow::Result;
use clap::{Parser, ValueEnum};
use infra_utils::cargo::CargoWorkspace;

use crate::toolchains::mkdocs::Mkdocs;
use crate::utils::DryRun;

pub fn publish_mkdocs(dry_run: bool) -> Result<()> {
Mkdocs::publish(dry_run)
#[derive(Clone, Debug, Parser)]
pub struct MkdocsController {
/// The target version to publish.
#[arg(long)]
target: PublishTarget,

#[command(flatten)]
dry_run: DryRun,
}

#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, ValueEnum)]
enum PublishTarget {
MainBranch,
LatestRelease,
}

impl MkdocsController {
pub fn execute(&self) -> Result<()> {
let (version, alias) = match self.target {
PublishTarget::MainBranch => ("main".to_string(), None),
PublishTarget::LatestRelease => {
(CargoWorkspace::local_version()?.to_string(), Some("latest"))
}
};

Mkdocs::publish(&version, alias, self.dry_run)
}
}
Loading

0 comments on commit dd1e806

Please sign in to comment.