mirror of
https://github.com/bahdotsh/wrkflw.git
synced 2025-12-30 00:47:00 +01:00
Compare commits
8 Commits
feature/se
...
fix/php-wo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8fc6dcaa6c | ||
|
|
3f7bd30cca | ||
|
|
960f7486a2 | ||
|
|
cb936cd1af | ||
|
|
625b8111f1 | ||
|
|
b2b6e9e08d | ||
|
|
86660ae573 | ||
|
|
886c415fa7 |
25
.github/workflows/release.yml
vendored
25
.github/workflows/release.yml
vendored
@@ -42,7 +42,30 @@ jobs:
|
||||
cargo install git-cliff --force
|
||||
|
||||
- name: Generate Changelog
|
||||
run: git-cliff --latest --output CHANGELOG.md
|
||||
run: |
|
||||
# Debug: Show current state
|
||||
echo "Current ref: ${{ github.ref_name }}"
|
||||
echo "Input version: ${{ github.event.inputs.version }}"
|
||||
echo "All tags:"
|
||||
git tag --sort=-version:refname | head -10
|
||||
|
||||
# Generate changelog from the current tag to the previous version tag
|
||||
CURRENT_TAG="${{ github.event.inputs.version || github.ref_name }}"
|
||||
PREVIOUS_TAG=$(git tag --sort=-version:refname | grep "^v" | head -2 | tail -1)
|
||||
|
||||
echo "Current tag: $CURRENT_TAG"
|
||||
echo "Previous tag: $PREVIOUS_TAG"
|
||||
|
||||
if [ -n "$PREVIOUS_TAG" ] && [ "$PREVIOUS_TAG" != "$CURRENT_TAG" ]; then
|
||||
echo "Generating changelog for range: $PREVIOUS_TAG..$CURRENT_TAG"
|
||||
git-cliff --tag "$CURRENT_TAG" "$PREVIOUS_TAG..$CURRENT_TAG" --output CHANGELOG.md
|
||||
else
|
||||
echo "Generating latest changelog for tag: $CURRENT_TAG"
|
||||
git-cliff --tag "$CURRENT_TAG" --latest --output CHANGELOG.md
|
||||
fi
|
||||
|
||||
echo "Generated changelog:"
|
||||
cat CHANGELOG.md
|
||||
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
|
||||
26
Cargo.lock
generated
26
Cargo.lock
generated
@@ -2545,7 +2545,7 @@ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
||||
|
||||
[[package]]
|
||||
name = "wrkflw"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"bollard",
|
||||
"chrono",
|
||||
@@ -2592,7 +2592,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wrkflw-evaluator"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"colored",
|
||||
"serde_yaml",
|
||||
@@ -2602,7 +2602,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wrkflw-executor"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bollard",
|
||||
@@ -2632,7 +2632,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wrkflw-github"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"regex",
|
||||
@@ -2646,7 +2646,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wrkflw-gitlab"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"regex",
|
||||
@@ -2661,7 +2661,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wrkflw-logging"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"once_cell",
|
||||
@@ -2672,7 +2672,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wrkflw-matrix"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"indexmap 2.8.0",
|
||||
"serde",
|
||||
@@ -2683,7 +2683,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wrkflw-models"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -2693,7 +2693,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wrkflw-parser"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"jsonschema",
|
||||
"serde",
|
||||
@@ -2707,7 +2707,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wrkflw-runtime"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"futures",
|
||||
@@ -2726,7 +2726,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wrkflw-ui"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"crossterm 0.26.1",
|
||||
@@ -2748,7 +2748,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wrkflw-utils"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"nix",
|
||||
"serde",
|
||||
@@ -2758,7 +2758,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wrkflw-validators"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_yaml",
|
||||
|
||||
@@ -5,7 +5,7 @@ members = [
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
edition = "2021"
|
||||
description = "A GitHub Actions workflow validator and executor"
|
||||
documentation = "https://github.com/bahdotsh/wrkflw"
|
||||
|
||||
@@ -12,9 +12,9 @@ categories.workspace = true
|
||||
|
||||
[dependencies]
|
||||
# Internal crates
|
||||
wrkflw-models = { path = "../models", version = "0.6.0" }
|
||||
wrkflw-validators = { path = "../validators", version = "0.6.0" }
|
||||
wrkflw-models = { path = "../models", version = "0.7.0" }
|
||||
wrkflw-validators = { path = "../validators", version = "0.7.0" }
|
||||
|
||||
# External dependencies
|
||||
colored.workspace = true
|
||||
serde_yaml.workspace = true
|
||||
serde_yaml.workspace = true
|
||||
|
||||
@@ -12,12 +12,12 @@ categories.workspace = true
|
||||
|
||||
[dependencies]
|
||||
# Internal crates
|
||||
wrkflw-models = { path = "../models", version = "0.6.0" }
|
||||
wrkflw-parser = { path = "../parser", version = "0.6.0" }
|
||||
wrkflw-runtime = { path = "../runtime", version = "0.6.0" }
|
||||
wrkflw-logging = { path = "../logging", version = "0.6.0" }
|
||||
wrkflw-matrix = { path = "../matrix", version = "0.6.0" }
|
||||
wrkflw-utils = { path = "../utils", version = "0.6.0" }
|
||||
wrkflw-models = { path = "../models", version = "0.7.0" }
|
||||
wrkflw-parser = { path = "../parser", version = "0.7.0" }
|
||||
wrkflw-runtime = { path = "../runtime", version = "0.7.0" }
|
||||
wrkflw-logging = { path = "../logging", version = "0.7.0" }
|
||||
wrkflw-matrix = { path = "../matrix", version = "0.7.0" }
|
||||
wrkflw-utils = { path = "../utils", version = "0.7.0" }
|
||||
|
||||
# External dependencies
|
||||
async-trait.workspace = true
|
||||
|
||||
@@ -840,6 +840,14 @@ impl DockerRuntime {
|
||||
working_dir: &Path,
|
||||
volumes: &[(&Path, &Path)],
|
||||
) -> Result<ContainerOutput, ContainerError> {
|
||||
// First, try to pull the image if it's not available locally
|
||||
if let Err(e) = self.pull_image_inner(image).await {
|
||||
wrkflw_logging::warning(&format!(
|
||||
"Failed to pull image {}: {}. Attempting to continue with existing image.",
|
||||
image, e
|
||||
));
|
||||
}
|
||||
|
||||
// Collect environment variables
|
||||
let mut env: Vec<String> = env_vars
|
||||
.iter()
|
||||
|
||||
@@ -526,9 +526,64 @@ async fn prepare_action(
|
||||
}
|
||||
}
|
||||
|
||||
// GitHub action: use standard runner image
|
||||
// In a real implementation, you'd need to clone the repo at the specified version
|
||||
Ok("node:16-buster-slim".to_string())
|
||||
// GitHub action: determine appropriate image based on action type
|
||||
let image = determine_action_image(&action.repository);
|
||||
Ok(image)
|
||||
}
|
||||
|
||||
/// Determine the appropriate Docker image for a GitHub action
|
||||
fn determine_action_image(repository: &str) -> String {
|
||||
// Handle specific well-known actions
|
||||
match repository {
|
||||
// PHP setup actions
|
||||
repo if repo.starts_with("shivammathur/setup-php") => {
|
||||
"composer:latest".to_string() // Use composer image which includes PHP and composer
|
||||
}
|
||||
|
||||
// Python setup actions
|
||||
repo if repo.starts_with("actions/setup-python") => "python:3.11-slim".to_string(),
|
||||
|
||||
// Node.js setup actions
|
||||
repo if repo.starts_with("actions/setup-node") => "node:20-slim".to_string(),
|
||||
|
||||
// Java setup actions
|
||||
repo if repo.starts_with("actions/setup-java") => "eclipse-temurin:17-jdk".to_string(),
|
||||
|
||||
// Go setup actions
|
||||
repo if repo.starts_with("actions/setup-go") => "golang:1.21-slim".to_string(),
|
||||
|
||||
// .NET setup actions
|
||||
repo if repo.starts_with("actions/setup-dotnet") => {
|
||||
"mcr.microsoft.com/dotnet/sdk:7.0".to_string()
|
||||
}
|
||||
|
||||
// Rust setup actions
|
||||
repo if repo.starts_with("actions-rs/toolchain")
|
||||
|| repo.starts_with("dtolnay/rust-toolchain") =>
|
||||
{
|
||||
"rust:latest".to_string()
|
||||
}
|
||||
|
||||
// Docker/container actions
|
||||
repo if repo.starts_with("docker/") => "docker:latest".to_string(),
|
||||
|
||||
// AWS actions
|
||||
repo if repo.starts_with("aws-actions/") => "amazon/aws-cli:latest".to_string(),
|
||||
|
||||
// Default to Node.js for most GitHub actions (checkout, upload-artifact, etc.)
|
||||
_ => {
|
||||
// Check if it's a common core GitHub action that should use a more complete environment
|
||||
if repository.starts_with("actions/checkout")
|
||||
|| repository.starts_with("actions/upload-artifact")
|
||||
|| repository.starts_with("actions/download-artifact")
|
||||
|| repository.starts_with("actions/cache")
|
||||
{
|
||||
"catthehacker/ubuntu:act-latest".to_string() // Use act runner image for core actions
|
||||
} else {
|
||||
"node:16-buster-slim".to_string() // Default for other actions
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn execute_job_batch(
|
||||
@@ -1536,8 +1591,9 @@ async fn execute_step(ctx: StepExecutionContext<'_>) -> Result<StepResult, Execu
|
||||
// Check if this is a cargo command
|
||||
let is_cargo_cmd = run.trim().starts_with("cargo");
|
||||
|
||||
// Convert command string to array of string slices
|
||||
let cmd_parts: Vec<&str> = run.split_whitespace().collect();
|
||||
// For complex shell commands, use bash to execute them properly
|
||||
// This handles quotes, pipes, redirections, and command substitutions correctly
|
||||
let cmd_parts = vec!["bash", "-c", run];
|
||||
|
||||
// Convert environment variables to the required format
|
||||
let env_vars: Vec<(&str, &str)> = step_env
|
||||
|
||||
@@ -12,7 +12,7 @@ categories.workspace = true
|
||||
|
||||
[dependencies]
|
||||
# Internal crates
|
||||
wrkflw-models = { path = "../models", version = "0.6.0" }
|
||||
wrkflw-models = { path = "../models", version = "0.7.0" }
|
||||
|
||||
# External dependencies from workspace
|
||||
serde.workspace = true
|
||||
|
||||
@@ -12,7 +12,7 @@ categories.workspace = true
|
||||
|
||||
[dependencies]
|
||||
# Internal crates
|
||||
wrkflw-models = { path = "../models", version = "0.6.0" }
|
||||
wrkflw-models = { path = "../models", version = "0.7.0" }
|
||||
|
||||
# External dependencies
|
||||
lazy_static.workspace = true
|
||||
|
||||
@@ -12,7 +12,7 @@ categories.workspace = true
|
||||
|
||||
[dependencies]
|
||||
# Internal crates
|
||||
wrkflw-models = { path = "../models", version = "0.6.0" }
|
||||
wrkflw-models = { path = "../models", version = "0.7.0" }
|
||||
|
||||
# External dependencies
|
||||
chrono.workspace = true
|
||||
|
||||
@@ -12,7 +12,7 @@ categories.workspace = true
|
||||
|
||||
[dependencies]
|
||||
# Internal crates
|
||||
wrkflw-models = { path = "../models", version = "0.6.0" }
|
||||
wrkflw-models = { path = "../models", version = "0.7.0" }
|
||||
|
||||
# External dependencies
|
||||
indexmap.workspace = true
|
||||
|
||||
@@ -14,4 +14,4 @@ categories.workspace = true
|
||||
serde.workspace = true
|
||||
serde_yaml.workspace = true
|
||||
serde_json.workspace = true
|
||||
thiserror.workspace = true
|
||||
thiserror.workspace = true
|
||||
|
||||
@@ -12,8 +12,8 @@ categories.workspace = true
|
||||
|
||||
[dependencies]
|
||||
# Internal crates
|
||||
wrkflw-models = { path = "../models", version = "0.6.0" }
|
||||
wrkflw-matrix = { path = "../matrix", version = "0.6.0" }
|
||||
wrkflw-models = { path = "../models", version = "0.7.0" }
|
||||
wrkflw-matrix = { path = "../matrix", version = "0.7.0" }
|
||||
|
||||
# External dependencies
|
||||
jsonschema.workspace = true
|
||||
|
||||
@@ -12,8 +12,8 @@ categories.workspace = true
|
||||
|
||||
[dependencies]
|
||||
# Internal crates
|
||||
wrkflw-models = { path = "../models", version = "0.6.0" }
|
||||
wrkflw-logging = { path = "../logging", version = "0.6.0" }
|
||||
wrkflw-models = { path = "../models", version = "0.7.0" }
|
||||
wrkflw-logging = { path = "../logging", version = "0.7.0" }
|
||||
|
||||
# External dependencies
|
||||
async-trait.workspace = true
|
||||
@@ -23,7 +23,7 @@ serde_yaml.workspace = true
|
||||
tempfile = "3.9"
|
||||
tokio.workspace = true
|
||||
futures = "0.3"
|
||||
wrkflw-utils = { path = "../utils", version = "0.6.0" }
|
||||
wrkflw-utils = { path = "../utils", version = "0.7.0" }
|
||||
which = "4.4"
|
||||
regex = "1.10"
|
||||
thiserror = "1.0"
|
||||
|
||||
@@ -12,12 +12,12 @@ categories.workspace = true
|
||||
|
||||
[dependencies]
|
||||
# Internal crates
|
||||
wrkflw-models = { path = "../models", version = "0.6.0" }
|
||||
wrkflw-evaluator = { path = "../evaluator", version = "0.6.0" }
|
||||
wrkflw-executor = { path = "../executor", version = "0.6.0" }
|
||||
wrkflw-logging = { path = "../logging", version = "0.6.0" }
|
||||
wrkflw-utils = { path = "../utils", version = "0.6.0" }
|
||||
wrkflw-github = { path = "../github", version = "0.6.0" }
|
||||
wrkflw-models = { path = "../models", version = "0.7.0" }
|
||||
wrkflw-evaluator = { path = "../evaluator", version = "0.7.0" }
|
||||
wrkflw-executor = { path = "../executor", version = "0.7.0" }
|
||||
wrkflw-logging = { path = "../logging", version = "0.7.0" }
|
||||
wrkflw-utils = { path = "../utils", version = "0.7.0" }
|
||||
wrkflw-github = { path = "../github", version = "0.7.0" }
|
||||
|
||||
# External dependencies
|
||||
chrono.workspace = true
|
||||
|
||||
@@ -189,6 +189,25 @@ fn run_tui_event_loop(
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle help overlay scrolling
|
||||
if app.show_help {
|
||||
match key.code {
|
||||
KeyCode::Up | KeyCode::Char('k') => {
|
||||
app.scroll_help_up();
|
||||
continue;
|
||||
}
|
||||
KeyCode::Down | KeyCode::Char('j') => {
|
||||
app.scroll_help_down();
|
||||
continue;
|
||||
}
|
||||
KeyCode::Esc | KeyCode::Char('?') => {
|
||||
app.show_help = false;
|
||||
continue;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
match key.code {
|
||||
KeyCode::Char('q') => {
|
||||
// Exit and clean up
|
||||
@@ -223,6 +242,8 @@ fn run_tui_event_loop(
|
||||
} else {
|
||||
app.scroll_logs_up();
|
||||
}
|
||||
} else if app.selected_tab == 3 {
|
||||
app.scroll_help_up();
|
||||
} else if app.selected_tab == 0 {
|
||||
app.previous_workflow();
|
||||
} else if app.selected_tab == 1 {
|
||||
@@ -240,6 +261,8 @@ fn run_tui_event_loop(
|
||||
} else {
|
||||
app.scroll_logs_down();
|
||||
}
|
||||
} else if app.selected_tab == 3 {
|
||||
app.scroll_help_down();
|
||||
} else if app.selected_tab == 0 {
|
||||
app.next_workflow();
|
||||
} else if app.selected_tab == 1 {
|
||||
|
||||
@@ -42,6 +42,9 @@ pub struct App {
|
||||
pub log_search_matches: Vec<usize>, // Indices of logs that match the search
|
||||
pub log_search_match_idx: usize, // Current match index for navigation
|
||||
|
||||
// Help tab scrolling
|
||||
pub help_scroll: usize, // Scrolling position for help content
|
||||
|
||||
// Background log processing
|
||||
pub log_processor: LogProcessor,
|
||||
pub processed_logs: Vec<ProcessedLogEntry>,
|
||||
@@ -207,6 +210,7 @@ impl App {
|
||||
log_filter_level: Some(LogFilterLevel::All),
|
||||
log_search_matches: Vec::new(),
|
||||
log_search_match_idx: 0,
|
||||
help_scroll: 0,
|
||||
|
||||
// Background log processing
|
||||
log_processor: LogProcessor::new(),
|
||||
@@ -807,6 +811,18 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
// Scroll help content up
|
||||
pub fn scroll_help_up(&mut self) {
|
||||
self.help_scroll = self.help_scroll.saturating_sub(1);
|
||||
}
|
||||
|
||||
// Scroll help content down
|
||||
pub fn scroll_help_down(&mut self) {
|
||||
// The help content has a fixed number of lines, so we set a reasonable max
|
||||
const MAX_HELP_SCROLL: usize = 30; // Adjust based on help content length
|
||||
self.help_scroll = (self.help_scroll + 1).min(MAX_HELP_SCROLL);
|
||||
}
|
||||
|
||||
// Update progress for running workflows
|
||||
pub fn update_running_workflow_progress(&mut self) {
|
||||
if let Some(idx) = self.current_execution {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Help overlay rendering
|
||||
use ratatui::{
|
||||
backend::CrosstermBackend,
|
||||
layout::Rect,
|
||||
layout::{Constraint, Direction, Layout, Rect},
|
||||
style::{Color, Modifier, Style},
|
||||
text::{Line, Span},
|
||||
widgets::{Block, BorderType, Borders, Paragraph, Wrap},
|
||||
@@ -9,11 +9,22 @@ use ratatui::{
|
||||
};
|
||||
use std::io;
|
||||
|
||||
// Render the help tab
|
||||
pub fn render_help_tab(f: &mut Frame<CrosstermBackend<io::Stdout>>, area: Rect) {
|
||||
let help_text = vec![
|
||||
// Render the help tab with scroll support
|
||||
pub fn render_help_content(
|
||||
f: &mut Frame<CrosstermBackend<io::Stdout>>,
|
||||
area: Rect,
|
||||
scroll_offset: usize,
|
||||
) {
|
||||
// Split the area into columns for better organization
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
|
||||
.split(area);
|
||||
|
||||
// Left column content
|
||||
let left_help_text = vec![
|
||||
Line::from(Span::styled(
|
||||
"Keyboard Controls",
|
||||
"🗂 NAVIGATION",
|
||||
Style::default()
|
||||
.fg(Color::Cyan)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
@@ -21,35 +32,391 @@ pub fn render_help_tab(f: &mut Frame<CrosstermBackend<io::Stdout>>, area: Rect)
|
||||
Line::from(""),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"Tab",
|
||||
"Tab / Shift+Tab",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Switch between tabs"),
|
||||
]),
|
||||
// More help text would follow...
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"1-4 / w,x,l,h",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Jump to specific tab"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"↑/↓ or k/j",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Navigate lists"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"Enter",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Select/View details"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"Esc",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Back/Exit help"),
|
||||
]),
|
||||
Line::from(""),
|
||||
Line::from(Span::styled(
|
||||
"🚀 WORKFLOW MANAGEMENT",
|
||||
Style::default()
|
||||
.fg(Color::Green)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
)),
|
||||
Line::from(""),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"Space",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Toggle workflow selection"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"r",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Run selected workflows"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"a",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Select all workflows"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"n",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Deselect all workflows"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"Shift+R",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Reset workflow status"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"t",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Trigger remote workflow"),
|
||||
]),
|
||||
Line::from(""),
|
||||
Line::from(Span::styled(
|
||||
"🔧 EXECUTION MODES",
|
||||
Style::default()
|
||||
.fg(Color::Magenta)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
)),
|
||||
Line::from(""),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"e",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Toggle emulation mode"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"v",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Toggle validation mode"),
|
||||
]),
|
||||
Line::from(""),
|
||||
Line::from(vec![Span::styled(
|
||||
"Runtime Modes:",
|
||||
Style::default()
|
||||
.fg(Color::White)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
)]),
|
||||
Line::from(vec![
|
||||
Span::raw(" • "),
|
||||
Span::styled("Docker", Style::default().fg(Color::Blue)),
|
||||
Span::raw(" - Container isolation (default)"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
Span::raw(" • "),
|
||||
Span::styled("Podman", Style::default().fg(Color::Blue)),
|
||||
Span::raw(" - Rootless containers"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
Span::raw(" • "),
|
||||
Span::styled("Emulation", Style::default().fg(Color::Red)),
|
||||
Span::raw(" - Process mode (UNSAFE)"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
Span::raw(" • "),
|
||||
Span::styled("Secure Emulation", Style::default().fg(Color::Yellow)),
|
||||
Span::raw(" - Sandboxed processes"),
|
||||
]),
|
||||
];
|
||||
|
||||
let help_widget = Paragraph::new(help_text)
|
||||
// Right column content
|
||||
let right_help_text = vec![
|
||||
Line::from(Span::styled(
|
||||
"📄 LOGS & SEARCH",
|
||||
Style::default()
|
||||
.fg(Color::Blue)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
)),
|
||||
Line::from(""),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"s",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Toggle log search"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"f",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Toggle log filter"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"c",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Clear search & filter"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"n",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Next search match"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"↑/↓",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Scroll logs/Navigate"),
|
||||
]),
|
||||
Line::from(""),
|
||||
Line::from(Span::styled(
|
||||
"ℹ️ TAB OVERVIEW",
|
||||
Style::default()
|
||||
.fg(Color::White)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
)),
|
||||
Line::from(""),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"1. Workflows",
|
||||
Style::default()
|
||||
.fg(Color::Cyan)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Browse & select workflows"),
|
||||
]),
|
||||
Line::from(vec![Span::raw(" • View workflow files")]),
|
||||
Line::from(vec![Span::raw(" • Select multiple for batch execution")]),
|
||||
Line::from(vec![Span::raw(" • Trigger remote workflows")]),
|
||||
Line::from(""),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"2. Execution",
|
||||
Style::default()
|
||||
.fg(Color::Green)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Monitor job progress"),
|
||||
]),
|
||||
Line::from(vec![Span::raw(" • View job status and details")]),
|
||||
Line::from(vec![Span::raw(" • Enter job details with Enter")]),
|
||||
Line::from(vec![Span::raw(" • Navigate step execution")]),
|
||||
Line::from(""),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"3. Logs",
|
||||
Style::default()
|
||||
.fg(Color::Blue)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - View execution logs"),
|
||||
]),
|
||||
Line::from(vec![Span::raw(" • Search and filter logs")]),
|
||||
Line::from(vec![Span::raw(" • Real-time log streaming")]),
|
||||
Line::from(vec![Span::raw(" • Navigate search results")]),
|
||||
Line::from(""),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"4. Help",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - This comprehensive guide"),
|
||||
]),
|
||||
Line::from(""),
|
||||
Line::from(Span::styled(
|
||||
"🎯 QUICK ACTIONS",
|
||||
Style::default().fg(Color::Red).add_modifier(Modifier::BOLD),
|
||||
)),
|
||||
Line::from(""),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"?",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Toggle help overlay"),
|
||||
]),
|
||||
Line::from(vec![
|
||||
Span::styled(
|
||||
"q",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::raw(" - Quit application"),
|
||||
]),
|
||||
Line::from(""),
|
||||
Line::from(Span::styled(
|
||||
"💡 TIPS",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
)),
|
||||
Line::from(""),
|
||||
Line::from(vec![
|
||||
Span::raw("• Use "),
|
||||
Span::styled("emulation mode", Style::default().fg(Color::Red)),
|
||||
Span::raw(" when containers"),
|
||||
]),
|
||||
Line::from(vec![Span::raw(" are unavailable or for quick testing")]),
|
||||
Line::from(""),
|
||||
Line::from(vec![
|
||||
Span::raw("• "),
|
||||
Span::styled("Secure emulation", Style::default().fg(Color::Yellow)),
|
||||
Span::raw(" provides sandboxing"),
|
||||
]),
|
||||
Line::from(vec![Span::raw(" for untrusted workflows")]),
|
||||
Line::from(""),
|
||||
Line::from(vec![
|
||||
Span::raw("• Use "),
|
||||
Span::styled("validation mode", Style::default().fg(Color::Green)),
|
||||
Span::raw(" to check"),
|
||||
]),
|
||||
Line::from(vec![Span::raw(" workflows without execution")]),
|
||||
Line::from(""),
|
||||
Line::from(vec![
|
||||
Span::raw("• "),
|
||||
Span::styled("Preserve containers", Style::default().fg(Color::Blue)),
|
||||
Span::raw(" on failure"),
|
||||
]),
|
||||
Line::from(vec![Span::raw(" for debugging (Docker/Podman only)")]),
|
||||
];
|
||||
|
||||
// Apply scroll offset to the content
|
||||
let left_help_text = if scroll_offset < left_help_text.len() {
|
||||
left_help_text.into_iter().skip(scroll_offset).collect()
|
||||
} else {
|
||||
vec![Line::from("")]
|
||||
};
|
||||
|
||||
let right_help_text = if scroll_offset < right_help_text.len() {
|
||||
right_help_text.into_iter().skip(scroll_offset).collect()
|
||||
} else {
|
||||
vec![Line::from("")]
|
||||
};
|
||||
|
||||
// Render left column
|
||||
let left_widget = Paragraph::new(left_help_text)
|
||||
.block(
|
||||
Block::default()
|
||||
.borders(Borders::ALL)
|
||||
.border_type(BorderType::Rounded)
|
||||
.title(Span::styled(" Help ", Style::default().fg(Color::Yellow))),
|
||||
.title(Span::styled(
|
||||
" WRKFLW Help - Controls & Features ",
|
||||
Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
)),
|
||||
)
|
||||
.wrap(Wrap { trim: true });
|
||||
|
||||
f.render_widget(help_widget, area);
|
||||
// Render right column
|
||||
let right_widget = Paragraph::new(right_help_text)
|
||||
.block(
|
||||
Block::default()
|
||||
.borders(Borders::ALL)
|
||||
.border_type(BorderType::Rounded)
|
||||
.title(Span::styled(
|
||||
" Interface Guide & Tips ",
|
||||
Style::default()
|
||||
.fg(Color::Cyan)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
)),
|
||||
)
|
||||
.wrap(Wrap { trim: true });
|
||||
|
||||
f.render_widget(left_widget, chunks[0]);
|
||||
f.render_widget(right_widget, chunks[1]);
|
||||
}
|
||||
|
||||
// Render a help overlay
|
||||
pub fn render_help_overlay(f: &mut Frame<CrosstermBackend<io::Stdout>>) {
|
||||
pub fn render_help_overlay(f: &mut Frame<CrosstermBackend<io::Stdout>>, scroll_offset: usize) {
|
||||
let size = f.size();
|
||||
|
||||
// Create a slightly smaller centered modal
|
||||
let width = size.width.min(60);
|
||||
let height = size.height.min(20);
|
||||
// Create a larger centered modal to accommodate comprehensive help content
|
||||
let width = (size.width * 9 / 10).min(120); // Use 90% of width, max 120 chars
|
||||
let height = (size.height * 9 / 10).min(40); // Use 90% of height, max 40 lines
|
||||
let x = (size.width - width) / 2;
|
||||
let y = (size.height - height) / 2;
|
||||
|
||||
@@ -60,10 +427,32 @@ pub fn render_help_overlay(f: &mut Frame<CrosstermBackend<io::Stdout>>) {
|
||||
height,
|
||||
};
|
||||
|
||||
// Create a clear background
|
||||
// Create a semi-transparent dark background for better visibility
|
||||
let clear = Block::default().style(Style::default().bg(Color::Black));
|
||||
f.render_widget(clear, size);
|
||||
|
||||
// Render the help content
|
||||
render_help_tab(f, help_area);
|
||||
// Add a border around the entire overlay for better visual separation
|
||||
let overlay_block = Block::default()
|
||||
.borders(Borders::ALL)
|
||||
.border_type(BorderType::Double)
|
||||
.style(Style::default().bg(Color::Black).fg(Color::White))
|
||||
.title(Span::styled(
|
||||
" Press ? or Esc to close help ",
|
||||
Style::default()
|
||||
.fg(Color::Gray)
|
||||
.add_modifier(Modifier::ITALIC),
|
||||
));
|
||||
|
||||
f.render_widget(overlay_block, help_area);
|
||||
|
||||
// Create inner area for content
|
||||
let inner_area = Rect {
|
||||
x: help_area.x + 1,
|
||||
y: help_area.y + 1,
|
||||
width: help_area.width.saturating_sub(2),
|
||||
height: help_area.height.saturating_sub(2),
|
||||
};
|
||||
|
||||
// Render the help content with scroll support
|
||||
render_help_content(f, inner_area, scroll_offset);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ use std::io;
|
||||
pub fn render_ui(f: &mut Frame<CrosstermBackend<io::Stdout>>, app: &mut App) {
|
||||
// Check if help should be shown as an overlay
|
||||
if app.show_help {
|
||||
help_overlay::render_help_overlay(f);
|
||||
help_overlay::render_help_overlay(f, app.help_scroll);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ pub fn render_ui(f: &mut Frame<CrosstermBackend<io::Stdout>>, app: &mut App) {
|
||||
}
|
||||
}
|
||||
2 => logs_tab::render_logs_tab(f, app, main_chunks[1]),
|
||||
3 => help_overlay::render_help_tab(f, main_chunks[1]),
|
||||
3 => help_overlay::render_help_content(f, main_chunks[1], app.help_scroll),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ pub fn render_status_bar(f: &mut Frame<CrosstermBackend<io::Stdout>>, app: &App,
|
||||
"[No logs to display]"
|
||||
}
|
||||
}
|
||||
3 => "[?] Toggle help overlay",
|
||||
3 => "[↑/↓] Scroll help [?] Toggle help overlay",
|
||||
_ => "",
|
||||
};
|
||||
status_items.push(Span::styled(
|
||||
|
||||
@@ -12,7 +12,7 @@ categories.workspace = true
|
||||
|
||||
[dependencies]
|
||||
# Internal crates
|
||||
wrkflw-models = { path = "../models", version = "0.6.0" }
|
||||
wrkflw-models = { path = "../models", version = "0.7.0" }
|
||||
|
||||
# External dependencies
|
||||
serde.workspace = true
|
||||
|
||||
@@ -12,8 +12,8 @@ categories.workspace = true
|
||||
|
||||
[dependencies]
|
||||
# Internal crates
|
||||
wrkflw-models = { path = "../models", version = "0.6.0" }
|
||||
wrkflw-matrix = { path = "../matrix", version = "0.6.0" }
|
||||
wrkflw-models = { path = "../models", version = "0.7.0" }
|
||||
wrkflw-matrix = { path = "../matrix", version = "0.7.0" }
|
||||
|
||||
# External dependencies
|
||||
serde.workspace = true
|
||||
|
||||
@@ -12,18 +12,18 @@ license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
# Workspace crates
|
||||
wrkflw-models = { path = "../models", version = "0.6.0" }
|
||||
wrkflw-executor = { path = "../executor", version = "0.6.0" }
|
||||
wrkflw-github = { path = "../github", version = "0.6.0" }
|
||||
wrkflw-gitlab = { path = "../gitlab", version = "0.6.0" }
|
||||
wrkflw-logging = { path = "../logging", version = "0.6.0" }
|
||||
wrkflw-matrix = { path = "../matrix", version = "0.6.0" }
|
||||
wrkflw-parser = { path = "../parser", version = "0.6.0" }
|
||||
wrkflw-runtime = { path = "../runtime", version = "0.6.0" }
|
||||
wrkflw-ui = { path = "../ui", version = "0.6.0" }
|
||||
wrkflw-utils = { path = "../utils", version = "0.6.0" }
|
||||
wrkflw-validators = { path = "../validators", version = "0.6.0" }
|
||||
wrkflw-evaluator = { path = "../evaluator", version = "0.6.0" }
|
||||
wrkflw-models = { path = "../models", version = "0.7.0" }
|
||||
wrkflw-executor = { path = "../executor", version = "0.7.0" }
|
||||
wrkflw-github = { path = "../github", version = "0.7.0" }
|
||||
wrkflw-gitlab = { path = "../gitlab", version = "0.7.0" }
|
||||
wrkflw-logging = { path = "../logging", version = "0.7.0" }
|
||||
wrkflw-matrix = { path = "../matrix", version = "0.7.0" }
|
||||
wrkflw-parser = { path = "../parser", version = "0.7.0" }
|
||||
wrkflw-runtime = { path = "../runtime", version = "0.7.0" }
|
||||
wrkflw-ui = { path = "../ui", version = "0.7.0" }
|
||||
wrkflw-utils = { path = "../utils", version = "0.7.0" }
|
||||
wrkflw-validators = { path = "../validators", version = "0.7.0" }
|
||||
wrkflw-evaluator = { path = "../evaluator", version = "0.7.0" }
|
||||
|
||||
# External dependencies
|
||||
clap.workspace = true
|
||||
@@ -62,4 +62,4 @@ path = "src/lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "wrkflw"
|
||||
path = "src/main.rs"
|
||||
path = "src/main.rs"
|
||||
|
||||
@@ -1,71 +1,179 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Simple script to publish all wrkflw crates to crates.io in dependency order
|
||||
# Enhanced script to manage versions and publish all wrkflw crates using cargo-workspaces
|
||||
|
||||
set -e
|
||||
|
||||
DRY_RUN=${1:-""}
|
||||
# Parse command line arguments
|
||||
COMMAND=${1:-""}
|
||||
VERSION_TYPE=${2:-""}
|
||||
DRY_RUN=""
|
||||
|
||||
if [[ "$DRY_RUN" == "--dry-run" ]]; then
|
||||
echo "🧪 DRY RUN: Testing wrkflw crates publication"
|
||||
else
|
||||
echo "🚀 Publishing wrkflw crates to crates.io"
|
||||
fi
|
||||
show_help() {
|
||||
echo "Usage: $0 <command> [options]"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " version <type> Update versions across workspace"
|
||||
echo " Types: patch, minor, major"
|
||||
echo " publish Publish all crates to crates.io"
|
||||
echo " release <type> Update versions and publish (combines version + publish)"
|
||||
echo " help Show this help message"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --dry-run Test without making changes (for publish/release)"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 version minor # Bump to 0.7.0"
|
||||
echo " $0 publish --dry-run # Test publishing"
|
||||
echo " $0 release minor --dry-run # Test version bump + publish"
|
||||
echo " $0 release patch # Release patch version"
|
||||
}
|
||||
|
||||
# Check if we're logged in to crates.io
|
||||
if [ ! -f ~/.cargo/credentials.toml ] && [ ! -f ~/.cargo/credentials ]; then
|
||||
echo "❌ Not logged in to crates.io. Please run: cargo login <your-token>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Publication order (respecting dependencies)
|
||||
CRATES=(
|
||||
"models"
|
||||
"logging"
|
||||
"utils"
|
||||
"matrix"
|
||||
"validators"
|
||||
"github"
|
||||
"gitlab"
|
||||
"parser"
|
||||
"runtime"
|
||||
"evaluator"
|
||||
"executor"
|
||||
"ui"
|
||||
"wrkflw"
|
||||
)
|
||||
|
||||
echo "📦 Publishing crates in dependency order..."
|
||||
|
||||
for crate in "${CRATES[@]}"; do
|
||||
if [[ "$DRY_RUN" == "--dry-run" ]]; then
|
||||
echo "Testing $crate..."
|
||||
cd "crates/$crate"
|
||||
cargo publish --dry-run --allow-dirty
|
||||
echo "✅ $crate dry-run successful"
|
||||
else
|
||||
echo "Publishing $crate..."
|
||||
cd "crates/$crate"
|
||||
cargo publish --allow-dirty
|
||||
echo "✅ Published $crate"
|
||||
fi
|
||||
cd - > /dev/null
|
||||
|
||||
# Small delay to avoid rate limiting (except for the last crate and in dry-run)
|
||||
if [[ "$crate" != "wrkflw" ]] && [[ "$DRY_RUN" != "--dry-run" ]]; then
|
||||
echo " Waiting 10 seconds to avoid rate limits..."
|
||||
sleep 10
|
||||
# Parse dry-run flag from any position
|
||||
for arg in "$@"; do
|
||||
if [[ "$arg" == "--dry-run" ]]; then
|
||||
DRY_RUN="--dry-run"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$DRY_RUN" == "--dry-run" ]]; then
|
||||
echo "🎉 All crates passed dry-run tests!"
|
||||
echo ""
|
||||
echo "To actually publish, run:"
|
||||
echo " ./publish_crates.sh"
|
||||
else
|
||||
echo "🎉 All crates published successfully!"
|
||||
echo ""
|
||||
echo "Users can now install wrkflw with:"
|
||||
echo " cargo install wrkflw"
|
||||
case "$COMMAND" in
|
||||
"help"|"-h"|"--help"|"")
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
"version")
|
||||
if [[ -z "$VERSION_TYPE" ]]; then
|
||||
echo "❌ Error: Version type required (patch, minor, major)"
|
||||
echo ""
|
||||
show_help
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
"publish")
|
||||
# publish command doesn't need version type
|
||||
;;
|
||||
"release")
|
||||
if [[ -z "$VERSION_TYPE" ]]; then
|
||||
echo "❌ Error: Version type required for release (patch, minor, major)"
|
||||
echo ""
|
||||
show_help
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "❌ Error: Unknown command '$COMMAND'"
|
||||
echo ""
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check if cargo-workspaces is installed
|
||||
if ! command -v cargo-workspaces &> /dev/null; then
|
||||
echo "❌ cargo-workspaces not found. Installing..."
|
||||
cargo install cargo-workspaces
|
||||
fi
|
||||
|
||||
# Check if we're logged in to crates.io (only for publish operations)
|
||||
if [[ "$COMMAND" == "publish" ]] || [[ "$COMMAND" == "release" ]]; then
|
||||
if [ ! -f ~/.cargo/credentials.toml ] && [ ! -f ~/.cargo/credentials ]; then
|
||||
echo "❌ Not logged in to crates.io. Please run: cargo login <your-token>"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Function to update versions
|
||||
update_versions() {
|
||||
local version_type=$1
|
||||
echo "🔄 Updating workspace versions ($version_type)..."
|
||||
|
||||
if [[ "$DRY_RUN" == "--dry-run" ]]; then
|
||||
echo "🧪 DRY RUN: Simulating version update"
|
||||
echo ""
|
||||
echo "Current workspace version: $(grep '^version =' Cargo.toml | cut -d'"' -f2)"
|
||||
echo "Would execute: cargo workspaces version $version_type"
|
||||
echo ""
|
||||
echo "This would update all crates and their internal dependencies."
|
||||
echo "✅ Version update simulation completed (no changes made)"
|
||||
else
|
||||
cargo workspaces version "$version_type"
|
||||
echo "✅ Versions updated successfully"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to test build
|
||||
test_build() {
|
||||
echo "🔨 Testing workspace build..."
|
||||
if cargo build --workspace; then
|
||||
echo "✅ Workspace builds successfully"
|
||||
else
|
||||
echo "❌ Build failed. Please fix errors before publishing."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to publish crates
|
||||
publish_crates() {
|
||||
echo "📦 Publishing crates to crates.io..."
|
||||
|
||||
if [[ "$DRY_RUN" == "--dry-run" ]]; then
|
||||
echo "🧪 DRY RUN: Testing publication"
|
||||
cargo workspaces publish --dry-run
|
||||
echo "✅ All crates passed dry-run tests!"
|
||||
echo ""
|
||||
echo "To actually publish, run:"
|
||||
echo " $0 publish"
|
||||
else
|
||||
cargo workspaces publish
|
||||
echo "🎉 All crates published successfully!"
|
||||
echo ""
|
||||
echo "Users can now install wrkflw with:"
|
||||
echo " cargo install wrkflw"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to show changelog info
|
||||
show_changelog_info() {
|
||||
echo "📝 Changelog will be generated automatically by GitHub Actions workflow"
|
||||
}
|
||||
|
||||
# Execute commands based on the operation
|
||||
case "$COMMAND" in
|
||||
"version")
|
||||
update_versions "$VERSION_TYPE"
|
||||
show_changelog_info
|
||||
;;
|
||||
"publish")
|
||||
test_build
|
||||
publish_crates
|
||||
;;
|
||||
"release")
|
||||
echo "🚀 Starting release process..."
|
||||
echo ""
|
||||
|
||||
# Step 1: Update versions
|
||||
update_versions "$VERSION_TYPE"
|
||||
|
||||
# Step 2: Test build
|
||||
test_build
|
||||
|
||||
# Step 3: Show changelog info
|
||||
show_changelog_info
|
||||
|
||||
# Step 4: Publish (if not dry-run)
|
||||
if [[ "$DRY_RUN" != "--dry-run" ]]; then
|
||||
echo ""
|
||||
read -p "🤔 Continue with publishing? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
publish_crates
|
||||
else
|
||||
echo "⏸️ Publishing cancelled. To publish later, run:"
|
||||
echo " $0 publish"
|
||||
fi
|
||||
else
|
||||
echo ""
|
||||
publish_crates
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
Reference in New Issue
Block a user