mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-10-02 14:44:42 +00:00
Move release-related code to their own module (#3501)
This commit is contained in:
parent
fe25980e53
commit
74c1f13e1f
@ -10,12 +10,11 @@ Usage: xtask <COMMAND>
|
|||||||
Commands:
|
Commands:
|
||||||
build Build-related subcommands
|
build Build-related subcommands
|
||||||
run Run-related subcommands
|
run Run-related subcommands
|
||||||
bump-version Bump the version of the specified package(s)
|
release Release-related subcommands
|
||||||
ci Perform (parts of) the checks done in CI
|
ci Perform (parts of) the checks done in CI
|
||||||
fmt-packages Format all packages in the workspace with rustfmt
|
fmt-packages Format all packages in the workspace with rustfmt
|
||||||
lint-packages Lint all packages in the workspace with clippy
|
lint-packages Lint all packages in the workspace with clippy
|
||||||
publish Attempt to publish the specified package
|
semver-check Semver Checks
|
||||||
tag-releases Generate git tags for all new package releases
|
|
||||||
check-changelog Check the changelog for packages
|
check-changelog Check the changelog for packages
|
||||||
help Print this message or the help of the given subcommand(s)
|
help Print this message or the help of the given subcommand(s)
|
||||||
|
|
||||||
|
@ -488,8 +488,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
changelog.finalize(
|
changelog.finalize(
|
||||||
Package::EspHal,
|
Package::EspHal,
|
||||||
semver::Version::new(0, 2, 0),
|
&semver::Version::new(0, 2, 0),
|
||||||
jiff::Timestamp::now(),
|
"2025-05-08 08:36-04".parse().unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let expected = "# Changelog
|
let expected = "# Changelog
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{Result, bail};
|
||||||
use clap::Args;
|
use clap::Args;
|
||||||
use esp_metadata::Chip;
|
use esp_metadata::Chip;
|
||||||
|
|
||||||
pub use self::{build::*, bump_version::*, check_changelog::*, run::*, semver_check::*};
|
pub use self::{build::*, check_changelog::*, release::*, run::*};
|
||||||
use crate::{cargo::CargoAction, Package};
|
use crate::{Package, cargo::CargoAction};
|
||||||
|
|
||||||
mod build;
|
mod build;
|
||||||
mod bump_version;
|
|
||||||
mod check_changelog;
|
mod check_changelog;
|
||||||
|
mod release;
|
||||||
mod run;
|
mod run;
|
||||||
mod semver_check;
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Subcommand Arguments
|
// Subcommand Arguments
|
||||||
|
34
xtask/src/commands/release.rs
Normal file
34
xtask/src/commands/release.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
use clap::Subcommand;
|
||||||
|
|
||||||
|
pub mod bump_version;
|
||||||
|
pub mod publish;
|
||||||
|
pub mod semver_check;
|
||||||
|
pub mod tag_releases;
|
||||||
|
|
||||||
|
pub use bump_version::*;
|
||||||
|
pub use publish::*;
|
||||||
|
pub use semver_check::*;
|
||||||
|
pub use tag_releases::*;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Subcommands
|
||||||
|
|
||||||
|
#[derive(Debug, Subcommand)]
|
||||||
|
pub enum Release {
|
||||||
|
/// Bump the version of the specified package(s).
|
||||||
|
///
|
||||||
|
/// This command will, for each specified package:
|
||||||
|
/// - Verify that the crate can be released (e.g. it doesn't refer to git
|
||||||
|
/// dependencies)
|
||||||
|
/// - Update the version in `Cargo.toml` files
|
||||||
|
/// - Update the version in dependencies' `Cargo.toml` files
|
||||||
|
/// - Check if the changelog can be finalized
|
||||||
|
/// - Update the version in the changelog
|
||||||
|
/// - Replaces `{{currentVersion}}` markers in source files and the
|
||||||
|
/// migration guide.
|
||||||
|
BumpVersion(BumpVersionArgs),
|
||||||
|
/// Attempt to publish the specified package.
|
||||||
|
Publish(PublishArgs),
|
||||||
|
/// Generate git tags for all new package releases.
|
||||||
|
TagReleases(TagReleasesArgs),
|
||||||
|
}
|
53
xtask/src/commands/release/publish.rs
Normal file
53
xtask/src/commands/release/publish.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use anyhow::{Result, bail};
|
||||||
|
use clap::Args;
|
||||||
|
|
||||||
|
use crate::{Package, cargo::CargoArgsBuilder, windows_safe_path};
|
||||||
|
|
||||||
|
#[derive(Debug, Args)]
|
||||||
|
pub struct PublishArgs {
|
||||||
|
/// Package to publish (performs a dry-run by default).
|
||||||
|
#[arg(value_enum)]
|
||||||
|
package: Package,
|
||||||
|
|
||||||
|
/// Do not pass the `--dry-run` argument, actually try to publish.
|
||||||
|
#[arg(long)]
|
||||||
|
no_dry_run: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn publish(workspace: &Path, args: PublishArgs) -> Result<()> {
|
||||||
|
let package_name = args.package.to_string();
|
||||||
|
let package_path = windows_safe_path(&workspace.join(&package_name));
|
||||||
|
|
||||||
|
use Package::*;
|
||||||
|
let mut publish_args = match args.package {
|
||||||
|
Examples | HilTest | QaTest => {
|
||||||
|
bail!(
|
||||||
|
"Invalid package '{}' specified, this package should not be published!",
|
||||||
|
args.package
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
EspBacktrace | EspHal | EspHalEmbassy | EspIeee802154 | EspLpHal | EspPrintln
|
||||||
|
| EspRiscvRt | EspStorage | EspWifi | XtensaLxRt => vec!["--no-verify"],
|
||||||
|
|
||||||
|
_ => vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
if !args.no_dry_run {
|
||||||
|
publish_args.push("--dry-run");
|
||||||
|
}
|
||||||
|
|
||||||
|
let builder = CargoArgsBuilder::default()
|
||||||
|
.subcommand("publish")
|
||||||
|
.args(&publish_args);
|
||||||
|
|
||||||
|
let args = builder.build();
|
||||||
|
log::debug!("{args:#?}");
|
||||||
|
|
||||||
|
// Execute `cargo publish` command from the package root:
|
||||||
|
crate::cargo::run(&args, &package_path)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
75
xtask/src/commands/release/tag_releases.rs
Normal file
75
xtask/src/commands/release/tag_releases.rs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
use std::{path::Path, process::Command};
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use clap::Args;
|
||||||
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
|
use crate::{Package, package_version};
|
||||||
|
|
||||||
|
#[derive(Debug, Args)]
|
||||||
|
pub struct TagReleasesArgs {
|
||||||
|
/// Package(s) to tag.
|
||||||
|
#[arg(long, value_enum, value_delimiter = ',', default_values_t = Package::iter())]
|
||||||
|
packages: Vec<Package>,
|
||||||
|
|
||||||
|
/// Actually try and create the tags
|
||||||
|
#[arg(long)]
|
||||||
|
no_dry_run: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tag_releases(workspace: &Path, mut args: TagReleasesArgs) -> Result<()> {
|
||||||
|
args.packages.sort();
|
||||||
|
|
||||||
|
#[derive(serde::Serialize)]
|
||||||
|
struct DocumentationItem {
|
||||||
|
name: String,
|
||||||
|
tag: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut created = Vec::new();
|
||||||
|
for package in args.packages {
|
||||||
|
// If a package does not require documentation, this also means that it is not
|
||||||
|
// published (maybe this function needs a better name), so we can skip tagging
|
||||||
|
// it:
|
||||||
|
if !package.is_published() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let version = package_version(workspace, package)?;
|
||||||
|
let tag = package.tag(&version);
|
||||||
|
|
||||||
|
if args.no_dry_run {
|
||||||
|
let output = Command::new("git")
|
||||||
|
.arg("tag")
|
||||||
|
.arg(&tag)
|
||||||
|
.current_dir(workspace)
|
||||||
|
.output()?;
|
||||||
|
|
||||||
|
if output.stderr.is_empty() {
|
||||||
|
log::info!("Created tag '{tag}'");
|
||||||
|
} else {
|
||||||
|
let err = String::from_utf8_lossy(&output.stderr);
|
||||||
|
let err = err.trim_start_matches("fatal: ");
|
||||||
|
log::warn!("{}", err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log::info!("Would create '{tag}' if `--no-dry-run` was passed.")
|
||||||
|
}
|
||||||
|
created.push(DocumentationItem {
|
||||||
|
name: package.to_string(),
|
||||||
|
tag,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if args.no_dry_run {
|
||||||
|
log::info!("Created {} tags", created.len());
|
||||||
|
log::info!("IMPORTANT: Don't forget to push the tags to the correct remote!");
|
||||||
|
}
|
||||||
|
|
||||||
|
log::info!(
|
||||||
|
"Documentation workflow input for these packages:\r\n\r\n {:#}",
|
||||||
|
serde_json::to_string(&created)?
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -1,18 +1,17 @@
|
|||||||
use std::{
|
use std::{
|
||||||
fs,
|
fs,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
process::Command,
|
|
||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{Result, bail};
|
||||||
use clap::{Args, Parser};
|
use clap::{Args, Parser};
|
||||||
use esp_metadata::{Chip, Config};
|
use esp_metadata::{Chip, Config};
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
use xtask::{
|
use xtask::{
|
||||||
|
Package,
|
||||||
cargo::{CargoAction, CargoArgsBuilder},
|
cargo::{CargoAction, CargoArgsBuilder},
|
||||||
commands::*,
|
commands::*,
|
||||||
Package,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -26,19 +25,10 @@ enum Cli {
|
|||||||
/// Run-related subcommands
|
/// Run-related subcommands
|
||||||
#[clap(subcommand)]
|
#[clap(subcommand)]
|
||||||
Run(Run),
|
Run(Run),
|
||||||
|
/// Release-related subcommands
|
||||||
|
#[clap(subcommand)]
|
||||||
|
Release(Release),
|
||||||
|
|
||||||
/// Bump the version of the specified package(s).
|
|
||||||
///
|
|
||||||
/// This command will, for each specified package:
|
|
||||||
/// - Verify that the crate can be released (e.g. it doesn't refer to git
|
|
||||||
/// dependencies)
|
|
||||||
/// - Update the version in `Cargo.toml` files
|
|
||||||
/// - Update the version in dependencies' `Cargo.toml` files
|
|
||||||
/// - Check if the changelog can be finalized
|
|
||||||
/// - Update the version in the changelog
|
|
||||||
/// - Replaces `{{currentVersion}}` markers in source files and the
|
|
||||||
/// migration guide.
|
|
||||||
BumpVersion(BumpVersionArgs),
|
|
||||||
/// Perform (parts of) the checks done in CI
|
/// Perform (parts of) the checks done in CI
|
||||||
Ci(CiArgs),
|
Ci(CiArgs),
|
||||||
/// Format all packages in the workspace with rustfmt
|
/// Format all packages in the workspace with rustfmt
|
||||||
@ -46,10 +36,6 @@ enum Cli {
|
|||||||
FmtPackages(FmtPackagesArgs),
|
FmtPackages(FmtPackagesArgs),
|
||||||
/// Lint all packages in the workspace with clippy
|
/// Lint all packages in the workspace with clippy
|
||||||
LintPackages(LintPackagesArgs),
|
LintPackages(LintPackagesArgs),
|
||||||
/// Attempt to publish the specified package.
|
|
||||||
Publish(PublishArgs),
|
|
||||||
/// Generate git tags for all new package releases.
|
|
||||||
TagReleases(TagReleasesArgs),
|
|
||||||
/// Semver Checks
|
/// Semver Checks
|
||||||
SemverCheck(SemverCheckArgs),
|
SemverCheck(SemverCheckArgs),
|
||||||
/// Check the changelog for packages.
|
/// Check the changelog for packages.
|
||||||
@ -89,28 +75,6 @@ struct LintPackagesArgs {
|
|||||||
fix: bool,
|
fix: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Args)]
|
|
||||||
struct PublishArgs {
|
|
||||||
/// Package to publish (performs a dry-run by default).
|
|
||||||
#[arg(value_enum)]
|
|
||||||
package: Package,
|
|
||||||
|
|
||||||
/// Do not pass the `--dry-run` argument, actually try to publish.
|
|
||||||
#[arg(long)]
|
|
||||||
no_dry_run: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Args)]
|
|
||||||
struct TagReleasesArgs {
|
|
||||||
/// Package(s) to tag.
|
|
||||||
#[arg(long, value_enum, value_delimiter = ',', default_values_t = Package::iter())]
|
|
||||||
packages: Vec<Package>,
|
|
||||||
|
|
||||||
/// Actually try and create the tags
|
|
||||||
#[arg(long)]
|
|
||||||
no_dry_run: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Args)]
|
#[derive(Debug, Args)]
|
||||||
struct CheckChangelogArgs {
|
struct CheckChangelogArgs {
|
||||||
/// Package(s) to tag.
|
/// Package(s) to tag.
|
||||||
@ -156,12 +120,16 @@ fn main() -> Result<()> {
|
|||||||
Run::Tests(args) => tests(&workspace, args, CargoAction::Run),
|
Run::Tests(args) => tests(&workspace, args, CargoAction::Run),
|
||||||
},
|
},
|
||||||
|
|
||||||
Cli::BumpVersion(args) => bump_version(&workspace, args),
|
// Release-related subcommands:
|
||||||
|
Cli::Release(release) => match release {
|
||||||
|
Release::BumpVersion(args) => bump_version(&workspace, args),
|
||||||
|
Release::TagReleases(args) => tag_releases(&workspace, args),
|
||||||
|
Release::Publish(args) => publish(&workspace, args),
|
||||||
|
},
|
||||||
|
|
||||||
Cli::Ci(args) => run_ci_checks(&workspace, args),
|
Cli::Ci(args) => run_ci_checks(&workspace, args),
|
||||||
Cli::FmtPackages(args) => fmt_packages(&workspace, args),
|
Cli::FmtPackages(args) => fmt_packages(&workspace, args),
|
||||||
Cli::LintPackages(args) => lint_packages(&workspace, args),
|
Cli::LintPackages(args) => lint_packages(&workspace, args),
|
||||||
Cli::Publish(args) => publish(&workspace, args),
|
|
||||||
Cli::TagReleases(args) => tag_releases(&workspace, args),
|
|
||||||
Cli::SemverCheck(args) => semver_checks(&workspace, args),
|
Cli::SemverCheck(args) => semver_checks(&workspace, args),
|
||||||
Cli::CheckChangelog(args) => check_changelog(&workspace, &args.packages, args.normalize),
|
Cli::CheckChangelog(args) => check_changelog(&workspace, &args.packages, args.normalize),
|
||||||
}
|
}
|
||||||
@ -304,42 +272,6 @@ fn lint_package(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn publish(workspace: &Path, args: PublishArgs) -> Result<()> {
|
|
||||||
let package_name = args.package.to_string();
|
|
||||||
let package_path = xtask::windows_safe_path(&workspace.join(&package_name));
|
|
||||||
|
|
||||||
use Package::*;
|
|
||||||
let mut publish_args = match args.package {
|
|
||||||
Examples | HilTest | QaTest => {
|
|
||||||
bail!(
|
|
||||||
"Invalid package '{}' specified, this package should not be published!",
|
|
||||||
args.package
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
EspBacktrace | EspHal | EspHalEmbassy | EspIeee802154 | EspLpHal | EspPrintln
|
|
||||||
| EspRiscvRt | EspStorage | EspWifi | XtensaLxRt => vec!["--no-verify"],
|
|
||||||
|
|
||||||
_ => vec![],
|
|
||||||
};
|
|
||||||
|
|
||||||
if !args.no_dry_run {
|
|
||||||
publish_args.push("--dry-run");
|
|
||||||
}
|
|
||||||
|
|
||||||
let builder = CargoArgsBuilder::default()
|
|
||||||
.subcommand("publish")
|
|
||||||
.args(&publish_args);
|
|
||||||
|
|
||||||
let args = builder.build();
|
|
||||||
log::debug!("{args:#?}");
|
|
||||||
|
|
||||||
// Execute `cargo publish` command from the package root:
|
|
||||||
xtask::cargo::run(&args, &package_path)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run_ci_checks(workspace: &Path, args: CiArgs) -> Result<()> {
|
fn run_ci_checks(workspace: &Path, args: CiArgs) -> Result<()> {
|
||||||
println!("::add-matcher::.github/rust-matchers.json");
|
println!("::add-matcher::.github/rust-matchers.json");
|
||||||
|
|
||||||
@ -506,60 +438,3 @@ fn run_ci_checks(workspace: &Path, args: CiArgs) -> Result<()> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tag_releases(workspace: &Path, mut args: TagReleasesArgs) -> Result<()> {
|
|
||||||
args.packages.sort();
|
|
||||||
|
|
||||||
#[derive(serde::Serialize)]
|
|
||||||
struct DocumentationItem {
|
|
||||||
name: String,
|
|
||||||
tag: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut created = Vec::new();
|
|
||||||
for package in args.packages {
|
|
||||||
// If a package does not require documentation, this also means that it is not
|
|
||||||
// published (maybe this function needs a better name), so we can skip tagging
|
|
||||||
// it:
|
|
||||||
if !package.is_published() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let version = xtask::package_version(workspace, package)?;
|
|
||||||
let tag = package.tag(&version);
|
|
||||||
|
|
||||||
if args.no_dry_run {
|
|
||||||
let output = Command::new("git")
|
|
||||||
.arg("tag")
|
|
||||||
.arg(&tag)
|
|
||||||
.current_dir(workspace)
|
|
||||||
.output()?;
|
|
||||||
|
|
||||||
if output.stderr.is_empty() {
|
|
||||||
log::info!("Created tag '{tag}'");
|
|
||||||
} else {
|
|
||||||
let err = String::from_utf8_lossy(&output.stderr);
|
|
||||||
let err = err.trim_start_matches("fatal: ");
|
|
||||||
log::warn!("{}", err);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log::info!("Would create '{tag}' if `--no-dry-run` was passed.")
|
|
||||||
}
|
|
||||||
created.push(DocumentationItem {
|
|
||||||
name: package.to_string(),
|
|
||||||
tag,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if args.no_dry_run {
|
|
||||||
log::info!("Created {} tags", created.len());
|
|
||||||
log::info!("IMPORTANT: Don't forget to push the tags to the correct remote!");
|
|
||||||
}
|
|
||||||
|
|
||||||
log::info!(
|
|
||||||
"Documentation workflow input for these packages:\r\n\r\n {:#}",
|
|
||||||
serde_json::to_string(&created)?
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user