diff --git a/LIMITATIONS.md b/LIMITATIONS.md new file mode 100644 index 0000000..5f8d7a6 --- /dev/null +++ b/LIMITATIONS.md @@ -0,0 +1,345 @@ +# Known Limitations & Resolution Strategy (v1) + +## 1. Scope + +This document formally defines acknowledged limitations of GithubWorkflowTool v1, explains why they exist, and documents the intended resolution path for future versions. + +The goal is **transparency, predictability, and a clear upgrade trajectory** rather than silent incompatibility. + +--- + +## 2. Limitation Categories + +Limitations are grouped by capability class and assigned a resolution tier: + +- **Deferred** – intentionally excluded from v1, planned for v2+ +- **Constrained** – partially supported with explicit restrictions +- **External** – blocked by legal, platform, or ecosystem constraints +- **Configurable** – disabled or limited by default but unlockable + +--- + +## 3. Detailed Limitations + +### 3.1 Incomplete GitHub Actions Feature Coverage + +**Status** +- Type: **Deferred** +- Severity: **Medium** +- Impact: Some workflows may fail or require modification + +**Description** + +GithubWorkflowTool v1 implements a subset of GitHub Actions semantics. Unsupported or partially supported features include (non-exhaustive): + +- Advanced expressions (`fromJSON`, `hashFiles`, complex boolean chains) +- Reusable workflows (`workflow_call`) +- Dynamic job generation outside `strategy.matrix` +- Job-level permissions and token scoping +- Environments with approval gates +- Concurrency groups + +**Rationale** + +GitHub Actions is not formally specified; it is an evolving behavior-driven platform. v1 prioritizes **deterministic local execution** over speculative compatibility. + +**Resolution Path** +- **v2**: Expand expression engine coverage +- **v2**: Add reusable workflow resolution +- **v3**: Permissions & environment gates (read-only simulation) + +**User Guidance (v1)** +- Prefer explicit `run:` steps over deeply nested expressions +- Avoid reusable workflows unless flattened +- Use matrix strategies only for static axes + +--- + +### 3.2 Third-Party Actions Compatibility + +**Status** +- Type: **Constrained** +- Severity: **Medium–High** +- Impact: Some marketplace actions may fail + +**Description** + +Some third-party actions assume: +- Preinstalled tools on GitHub-hosted runners +- Full Node.js runtime availability +- Docker-in-Docker capability +- Privileged filesystem or network access + +v1 does not guarantee these assumptions unless explicitly provided by the selected runner backend. + +**Supported Action Types (v1)** +- Local composite actions +- Docker-based actions +- Node-based actions **only if**: + - Container backend is used, **or** + - Required runtimes are present in the VM template + +**Resolution Path** +- **v2**: Action capability probing (pre-flight validation) +- **v2**: Curated "known-good" action compatibility list +- **v3**: Optional toolchain auto-provisioning + +**User Guidance (v1)** +- Prefer Docker-based actions +- Pin action versions explicitly +- Use container backend when testing marketplace actions + +--- + +### 3.3 Service Containers Not Implemented + +**Status** +- Type: **Deferred** +- Severity: **High** (for integration-heavy workflows) +- Impact: DB-backed or multi-service workflows will fail + +**Description** + +GitHub Actions `services:` (e.g., PostgreSQL, Redis) are not supported in v1. + +There is no orchestration layer for: +- Service lifecycle management +- Network aliasing +- Health checks +- Port mapping into jobs + +**Rationale** + +Service containers introduce orchestration complexity comparable to a lightweight Kubernetes layer. This is intentionally excluded from v1 to keep execution semantics simple and debuggable. + +**Resolution Path** +- **v2**: Container-backend-only service support +- **v2.1**: Declarative service lifecycle +- **v3**: QEMU backend service networking + +**User Guidance (v1)** + +Replace services with: +- External services (run manually, point workflows at fixed endpoints) +- Embedded test doubles +- Single-container workflows +- Manual database/service setup before workflow execution + +**Example Workaround:** + +Instead of: +```yaml +jobs: + test: + services: + postgres: + image: postgres:14 +``` + +Use: +```bash +# Run service manually +docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=test postgres:14 + +# Then run workflow +gwt run /path/to/repo /path/to/workflow.yml --env DATABASE_URL=postgresql://localhost:5432 +``` + +--- + +### 3.4 macOS Runner Images Unsupported + +**Status** +- Type: **External** +- Severity: **High** (for Apple-specific projects) +- Impact: macOS workflows cannot be executed + +**Description** + +macOS GitHub-hosted runners are not supported in v1. + +**Reasons:** +- Apple licensing restrictions +- Virtualization limitations outside Apple hardware +- Lack of redistributable macOS base images + +**Resolution Path** +- **v2**: "macOS-host-like" profile (best-effort simulation on Linux) +- **v3**: Native macOS-host execution (host-only, no VM) +- **No QEMU-based macOS support planned** (licensing constraints) + +**User Guidance (v1)** +- Use Linux runners for cross-platform builds where possible +- Split workflows: + - Linux CI locally (with GithubWorkflowTool) + - macOS CI only on GitHub +- For macOS-specific testing: use GitHub Actions cloud runners + +--- + +### 3.5 Limited Network Access in Runners + +**Status** +- Type: **Configurable** +- Severity: **Medium** +- Impact: Actions requiring external downloads may fail + +**Description** + +Network access inside runners may be: +- Restricted +- Rate-limited +- Disabled entirely (offline mode) + +This applies especially to: +- QEMU backend +- Reproducibility-focused runs +- CI debugging scenarios + +**Rationale** + +Unrestricted network access: +- Breaks reproducibility +- Introduces nondeterministic failures +- Can leak secrets unintentionally + +**Resolution Path** +- **v1.1**: Domain allowlist support +- **v2**: Network profiles per runner +- **v2**: Cached dependency mirrors +- **v3**: Deterministic fetch recording & replay + +**User Guidance (v1)** +- Vendor dependencies where possible +- Use local mirrors or caches +- Enable network explicitly when required (container mode allows network by default) +- For offline testing, pre-download all dependencies + +--- + +## 4. Limitation Visibility & UX Requirements + +### CLI Requirements + +The `gwt doctor` command must report: +- Unsupported workflow features detected in a workflow file +- Action incompatibilities +- Missing toolchains (Docker, Podman, QEMU) +- Runner backend availability +- Clear warnings before execution, not after failure + +**Example Output:** +```bash +$ gwt doctor /path/to/repo/.github/workflows/ci.yml + +GithubWorkflowTool Diagnostics +============================== + +Workflow: ci.yml +✓ Basic workflow structure valid +✓ Job dependencies resolvable +⚠ Warning: Uses reusable workflow (not supported in v1) +⚠ Warning: Service container 'postgres' detected (not supported in v1) + → Workaround: Run PostgreSQL manually before workflow execution +✗ Error: Uses 'hashFiles' expression (not supported in v1) + → Resolution: Simplify expression or upgrade to v2 (planned) + +Backend Availability: +✓ Container backend: Docker detected (v24.0.0) +✓ QEMU backend: Available (v7.2.0) + +Recommendation: 3 issues detected, 2 warnings, 1 error +Workflow may fail or require modifications to run successfully. +``` + +### GUI Requirements + +Visual badges on workflows/jobs: +- "✓ Fully Supported" +- "⚠ Partially Supported" (with details in hover/tooltip) +- "✗ Unsupported in v1" (with workaround in detail pane) +- "Requires Container Backend" +- "Requires QEMU Backend" + +When hovering over a badge or clicking for details, explain: +- What limitation applies +- Why it exists +- Recommended workaround +- Expected version for full support + +--- + +## 5. Versioning & Compatibility Policy + +### v1.x +- No breaking behavior changes +- Limitations remain explicit and documented +- New features may be added if backward compatible +- Unsupported features fail fast with clear error messages + +### v2.0 +- Feature expansion allowed +- Backward compatibility preferred but not guaranteed +- Migration guide provided for breaking changes +- Unsupported features must fail fast, not silently degrade + +### Future Versions +- Incremental improvements to limitation resolution +- Regular compatibility matrix updates +- Community feedback integration + +--- + +## 6. Acceptance Criteria (Limitations Spec) + +This specification is satisfied when: + +1. ✅ All listed limitations are explicitly detected or documented at runtime +2. ✅ Failures caused by limitations produce actionable diagnostics +3. ✅ Users can predict before execution whether a workflow is likely to succeed +4. ✅ Resolution paths are versioned and traceable +5. ✅ Documentation is accessible and linked from main README + +--- + +## 7. Compatibility Matrix (Preview) + +A detailed compatibility matrix mapping common GitHub Actions to backend support will be provided in a future specification. Preview: + +| Action | Container | QEMU | Status | Notes | +|--------|-----------|------|--------|-------| +| actions/checkout@v3 | ✓ | ✓ | Full | Git must be available | +| actions/cache@v3 | ⚠ | ⚠ | Partial | Local cache only | +| actions/setup-node@v3 | ✓ | ✓ | Full | Node must be in image | +| docker/build-push-action@v4 | ✓ | ✗ | Container only | DinD required | +| Service containers | ✗ | ✗ | Not supported | v2 planned | +| Reusable workflows | ✗ | ✗ | Not supported | v2 planned | + +Full matrix to be documented in `COMPATIBILITY_MATRIX.md` (future work). + +--- + +## 8. Feedback and Contributions + +Users encountering limitations not documented here should: +1. Check for existing GitHub issues +2. Report new limitations with: + - Workflow file (or minimal example) + - Error message + - Expected behavior + - Actual behavior +3. Contribute workarounds to documentation + +--- + +## Summary + +GithubWorkflowTool v1 is designed with **intentional constraints** to ensure: +- Predictable, deterministic execution +- Clear error messages and diagnostics +- Transparent limitations with documented workarounds +- Traceable resolution path for future versions + +Users should consult this document and use the `gwt doctor` command before deploying workflows to understand compatibility and required modifications. + +For questions or issues, please refer to the GitHub repository issue tracker. diff --git a/README.md b/README.md index d33539a..1e9fe1b 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,9 @@ conan install . --output-folder=build --build=missing cmake --preset=default cmake --build build +# Check system compatibility +./build/gwt doctor + # Run CLI ./build/gwt clone https://github.com/user/repo ./build/gwt workflows /path/to/repo @@ -102,11 +105,17 @@ GithubWorkflowTool/ ## Limitations (v1) -- Not all GitHub Actions features are supported -- Some third-party actions may require container mode or preinstalled tools -- Service containers not yet implemented -- macOS runner images not supported -- Network access in runners may be limited +GithubWorkflowTool v1 has intentional limitations to ensure deterministic, debuggable local execution: + +- Not all GitHub Actions features are supported (see [LIMITATIONS.md](LIMITATIONS.md) §3.1) +- Some third-party actions may require container mode or preinstalled tools (§3.2) +- Service containers not yet implemented (§3.3) +- macOS runner images not supported (§3.4) +- Network access in runners may be limited (§3.5) + +**Before running workflows locally**, use `gwt doctor` to check compatibility and get actionable guidance. + +For detailed information, workarounds, and resolution roadmap, see **[LIMITATIONS.md](LIMITATIONS.md)**. ## License diff --git a/USAGE.md b/USAGE.md index 7e710ab..1010f35 100644 --- a/USAGE.md +++ b/USAGE.md @@ -64,6 +64,25 @@ gwt list gwt workflows /path/to/repo ``` +#### Check System and Workflow Compatibility +```bash +# Check system backends (Docker, Podman, QEMU) +gwt doctor + +# Check specific workflow for compatibility issues +gwt doctor /path/to/repo/.github/workflows/ci.yml +``` + +The `doctor` command diagnoses: +- Backend availability (Docker, Podman, QEMU) +- Workflow parsing errors +- Unsupported features (service containers, reusable workflows, etc.) +- macOS runner usage +- Advanced expression usage +- Job dependency issues + +**Always run `gwt doctor` before executing workflows to identify potential issues early.** + #### Run a Workflow ```bash gwt run /path/to/repo /path/to/repo/.github/workflows/ci.yml @@ -261,6 +280,15 @@ Jobs run in order: build → test → deploy ## Troubleshooting +### Quick Diagnostics + +**Before troubleshooting, always run:** +```bash +gwt doctor /path/to/workflow.yml +``` + +This will identify most common issues and suggest workarounds. + ### Container Backend Issues **Problem**: "Docker not found" diff --git a/_codeql_detected_source_root b/_codeql_detected_source_root new file mode 120000 index 0000000..945c9b4 --- /dev/null +++ b/_codeql_detected_source_root @@ -0,0 +1 @@ +. \ No newline at end of file diff --git a/examples/DOCTOR_TEST_SCENARIOS.md b/examples/DOCTOR_TEST_SCENARIOS.md new file mode 100644 index 0000000..3fe09fe --- /dev/null +++ b/examples/DOCTOR_TEST_SCENARIOS.md @@ -0,0 +1,320 @@ +# Test Scenario: gwt doctor command + +## Purpose +This document demonstrates the expected behavior of the `gwt doctor` command implementation for various scenarios. + +## Test Case 1: System Diagnostics Only (No Workflow File) + +### Command: +```bash +gwt doctor +``` + +### Expected Output: +``` +GithubWorkflowTool Diagnostics +============================== + +Backend Availability: +✓ Container backend: Docker detected (24.0.0) +✓ QEMU backend: Available (7.2.0) + +Summary: No issues detected +✓ System is ready for workflow execution + +For detailed information on limitations and workarounds, see LIMITATIONS.md +``` + +**Exit Code:** 0 + +--- + +## Test Case 2: System with Missing QEMU + +### Command: +```bash +gwt doctor +``` + +### Expected Output: +``` +GithubWorkflowTool Diagnostics +============================== + +Backend Availability: +✓ Container backend: Docker detected (24.0.0) +⚠ QEMU backend: Not available + → Install QEMU for VM-based execution (optional) + +Summary: 1 issue(s) detected (1 warning(s)) +⚠ Workflow should run with noted limitations + +For detailed information on limitations and workarounds, see LIMITATIONS.md +``` + +**Exit Code:** 0 (warnings don't cause failure) + +--- + +## Test Case 3: System with No Container Runtime + +### Command: +```bash +gwt doctor +``` + +### Expected Output: +``` +GithubWorkflowTool Diagnostics +============================== + +Backend Availability: +✗ Container backend: Neither Docker nor Podman found + → Install Docker or Podman for container backend support +✓ QEMU backend: Available (7.2.0) + +Summary: 1 issue(s) detected (1 error(s)) +⚠ Workflow may fail or require modifications to run successfully + +For detailed information on limitations and workarounds, see LIMITATIONS.md +``` + +**Exit Code:** 1 (errors cause failure) + +--- + +## Test Case 4: Valid Workflow File + +### Command: +```bash +gwt doctor examples/example-workflow.yml +``` + +### Expected Output: +``` +GithubWorkflowTool Diagnostics +============================== + +Backend Availability: +✓ Container backend: Docker detected (24.0.0) +✓ QEMU backend: Available (7.2.0) + +Workflow: example-workflow.yml +✓ Basic workflow structure valid +✓ Job dependencies resolvable + +Summary: No issues detected +✓ System is ready for workflow execution + +For detailed information on limitations and workarounds, see LIMITATIONS.md +``` + +**Exit Code:** 0 + +--- + +## Test Case 5: Workflow with Limitations + +### Command: +```bash +gwt doctor examples/workflow-with-limitations.yml +``` + +### Expected Output: +``` +GithubWorkflowTool Diagnostics +============================== + +Backend Availability: +✓ Container backend: Docker detected (24.0.0) +✓ QEMU backend: Available (7.2.0) + +Workflow: workflow-with-limitations.yml +✓ Basic workflow structure valid +⚠ Warning: Service containers detected (not supported in v1) + → Workaround: Run services manually before workflow execution + → See LIMITATIONS.md §3.3 +⚠ Warning: Uses 'hashFiles' expression (limited support in v1) + → Workaround: Simplify expression or use explicit run steps + → See LIMITATIONS.md §3.1 +✗ Error: macOS runners not supported in v1 + → Workaround: Use Linux runners or run macOS workflows on GitHub + → See LIMITATIONS.md §3.4 +⚠ Warning: Concurrency groups (not supported in v1) + → Note: All jobs run as configured, no concurrency limits applied + → See LIMITATIONS.md §3.1 + +Summary: 4 issue(s) detected (3 warning(s), 1 error(s)) +⚠ Workflow may fail or require modifications to run successfully + +For detailed information on limitations and workarounds, see LIMITATIONS.md +``` + +**Exit Code:** 1 (errors present) + +--- + +## Test Case 6: Workflow with Invalid Dependencies + +### Command: +```bash +gwt doctor test-workflow-bad-deps.yml +``` + +### Test Workflow (test-workflow-bad-deps.yml): +```yaml +name: Bad Dependencies +on: push +jobs: + test: + runs-on: ubuntu-latest + needs: [build] # 'build' job doesn't exist! + steps: + - run: echo "test" +``` + +### Expected Output: +``` +GithubWorkflowTool Diagnostics +============================== + +Backend Availability: +✓ Container backend: Docker detected (24.0.0) +✓ QEMU backend: Available (7.2.0) + +Workflow: test-workflow-bad-deps.yml +✓ Basic workflow structure valid +✗ Error: Job 'test' depends on non-existent job 'build' + +Summary: 1 issue(s) detected (1 error(s)) +⚠ Workflow may fail or require modifications to run successfully + +For detailed information on limitations and workarounds, see LIMITATIONS.md +``` + +**Exit Code:** 1 + +--- + +## Test Case 7: Workflow File Not Found + +### Command: +```bash +gwt doctor nonexistent.yml +``` + +### Expected Output: +``` +GithubWorkflowTool Diagnostics +============================== + +Backend Availability: +✓ Container backend: Docker detected (24.0.0) +✓ QEMU backend: Available (7.2.0) + +Error: Workflow file not found: nonexistent.yml +``` + +**Exit Code:** 1 + +--- + +## Test Case 8: Workflow with Parse Errors + +### Command: +```bash +gwt doctor invalid-syntax.yml +``` + +### Test Workflow (invalid-syntax.yml): +```yaml +name: Invalid Syntax +on push # Missing colon - syntax error! +jobs: + test: + runs-on: ubuntu-latest +``` + +### Expected Output: +``` +GithubWorkflowTool Diagnostics +============================== + +Backend Availability: +✓ Container backend: Docker detected (24.0.0) +✓ QEMU backend: Available (7.2.0) + +Workflow: invalid-syntax.yml +✗ Error: Workflow parsing failed + YAML parse error at line 2: ... + +Summary: 1 issue(s) detected (1 error(s)) +⚠ Workflow may fail or require modifications to run successfully + +For detailed information on limitations and workarounds, see LIMITATIONS.md +``` + +**Exit Code:** 1 + +--- + +## Implementation Notes + +### Detection Logic + +1. **Backend Detection:** + - Try Docker first with `docker --version` + - Fall back to Podman with `podman --version` + - Check QEMU with `qemu-system-x86_64 --version` + - Timeouts: 3 seconds per check + +2. **Workflow Analysis:** + - Parse with WorkflowParser + - Check job dependencies with QMap::contains() + - String search for limitation patterns: + - `workflow_call` → reusable workflows + - `services:` → service containers + - `fromJSON`, `hashFiles`, `toJSON` → advanced expressions + - `macos-latest`, `macos-` → macOS runners + - `concurrency:` → concurrency groups + +3. **Exit Codes:** + - 0: Success or warnings only + - 1: Errors detected or file not found + +### Code Quality +- Uses modern C++ range-based loops with structured bindings +- Proper Qt resource management (QFile, QProcess) +- Clear separation of concerns +- Actionable error messages with workarounds + +--- + +## Integration with Development Workflow + +### Recommended Usage + +**Before first run:** +```bash +gwt doctor +``` + +**Before running a specific workflow:** +```bash +gwt doctor path/to/workflow.yml +``` + +**In CI pipelines:** +```bash +# Check compatibility before attempting execution +if ! gwt doctor .github/workflows/ci.yml; then + echo "Workflow has compatibility issues, see output above" + exit 1 +fi +``` + +### Benefits +1. **Fail Fast:** Catch issues before workflow execution +2. **Clear Guidance:** Actionable workarounds for each limitation +3. **Version Awareness:** Links to LIMITATIONS.md with resolution roadmap +4. **Progressive Enhancement:** Warnings vs errors guide user decisions diff --git a/examples/workflow-with-limitations.yml b/examples/workflow-with-limitations.yml new file mode 100644 index 0000000..fe0169b --- /dev/null +++ b/examples/workflow-with-limitations.yml @@ -0,0 +1,75 @@ +name: Example Workflow with Known Limitations + +on: + push: + branches: [ main ] + pull_request: + workflow_dispatch: + +# This workflow demonstrates various features that have limitations in v1 + +jobs: + # This job uses service containers (not supported in v1) + database-test: + runs-on: ubuntu-latest + services: + postgres: + image: postgres:14 + env: + POSTGRES_PASSWORD: test + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + steps: + - uses: actions/checkout@v3 + - name: Run tests with database + run: | + echo "This would test with PostgreSQL" + echo "Not supported in v1 - see LIMITATIONS.md §3.3" + + # This job uses advanced expressions (limited support in v1) + advanced-expressions: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Use hashFiles + run: echo "${{ hashFiles('**/*.go') }}" + - name: Use fromJSON + run: echo "${{ fromJSON('{"key": "value"}').key }}" + + # This job targets macOS (not supported in v1) + macos-build: + runs-on: macos-latest + steps: + - uses: actions/checkout@v3 + - name: Build on macOS + run: | + echo "macOS runners not supported in v1" + echo "See LIMITATIONS.md §3.4" + + # This job demonstrates concurrency (not enforced in v1) + concurrent-job: + runs-on: ubuntu-latest + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + steps: + - name: Run concurrent job + run: | + echo "Concurrency groups not enforced in v1" + echo "See LIMITATIONS.md §3.1" + + # This is a valid job that should work in v1 + simple-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Run simple test + run: echo "This job should work fine in v1" + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: test-results + path: results/ diff --git a/include/cli/CommandHandler.h b/include/cli/CommandHandler.h index bdb5a0e..5ee25d9 100644 --- a/include/cli/CommandHandler.h +++ b/include/cli/CommandHandler.h @@ -38,6 +38,7 @@ private: int handleList(const QStringList& args); int handleRun(const QStringList& args); int handleWorkflows(const QStringList& args); + int handleDoctor(const QStringList& args); }; } // namespace cli diff --git a/src/cli/CommandHandler.cpp b/src/cli/CommandHandler.cpp index 4a70408..871f320 100644 --- a/src/cli/CommandHandler.cpp +++ b/src/cli/CommandHandler.cpp @@ -6,6 +6,9 @@ #include #include #include +#include +#include +#include namespace gwt { namespace cli { @@ -35,6 +38,8 @@ int CommandHandler::execute(const QStringList& args) { return handleRun(args.mid(1)); } else if (command == "workflows") { return handleWorkflows(args.mid(1)); + } else if (command == "doctor") { + return handleDoctor(args.mid(1)); } else { QTextStream err(stderr); err << "Unknown command: " << command << Qt::endl; @@ -54,6 +59,7 @@ void CommandHandler::printHelp() const { out << " list List cloned repositories" << Qt::endl; out << " workflows List workflows in a repository" << Qt::endl; out << " run Run a workflow" << Qt::endl; + out << " doctor [workflow] Check system and workflow compatibility" << Qt::endl; out << " help Show this help message" << Qt::endl; out << Qt::endl; } @@ -151,5 +157,202 @@ int CommandHandler::handleWorkflows(const QStringList& args) { return 0; } +int CommandHandler::handleDoctor(const QStringList& args) { + QTextStream out(stdout); + out << "GithubWorkflowTool Diagnostics" << Qt::endl; + out << "==============================" << Qt::endl; + out << Qt::endl; + + int issues = 0; + int warnings = 0; + int errors = 0; + + // Check backend availability + out << "Backend Availability:" << Qt::endl; + + // Check Docker + QProcess dockerCheck; + dockerCheck.start("docker", QStringList() << "--version"); + dockerCheck.waitForFinished(3000); + + if (dockerCheck.exitCode() == 0) { + QString dockerVersion = QString::fromUtf8(dockerCheck.readAllStandardOutput()).trimmed(); + out << "✓ Container backend: Docker detected (" << dockerVersion.split(" ").value(2, "").remove(',') << ")" << Qt::endl; + } else { + // Try Podman + QProcess podmanCheck; + podmanCheck.start("podman", QStringList() << "--version"); + podmanCheck.waitForFinished(3000); + + if (podmanCheck.exitCode() == 0) { + QString podmanVersion = QString::fromUtf8(podmanCheck.readAllStandardOutput()).trimmed(); + out << "✓ Container backend: Podman detected (" << podmanVersion.split(" ").value(2, "") << ")" << Qt::endl; + } else { + out << "✗ Container backend: Neither Docker nor Podman found" << Qt::endl; + out << " → Install Docker or Podman for container backend support" << Qt::endl; + errors++; + issues++; + } + } + + // Check QEMU + QProcess qemuCheck; + qemuCheck.start("qemu-system-x86_64", QStringList() << "--version"); + qemuCheck.waitForFinished(3000); + + if (qemuCheck.exitCode() == 0) { + QString qemuVersion = QString::fromUtf8(qemuCheck.readAllStandardOutput()).split('\n').first().trimmed(); + out << "✓ QEMU backend: Available (" << qemuVersion.split(" ").value(3, "") << ")" << Qt::endl; + } else { + out << "⚠ QEMU backend: Not available" << Qt::endl; + out << " → Install QEMU for VM-based execution (optional)" << Qt::endl; + warnings++; + issues++; + } + + out << Qt::endl; + + // Check workflow if provided + if (!args.isEmpty()) { + QString workflowFile = args[0]; + + if (!QFile::exists(workflowFile)) { + out << "Error: Workflow file not found: " << workflowFile << Qt::endl; + return 1; + } + + out << "Workflow: " << QFileInfo(workflowFile).fileName() << Qt::endl; + + // Parse workflow + core::WorkflowParser parser; + core::Workflow workflow = parser.parse(workflowFile); + + if (parser.hasErrors()) { + out << "✗ Error: Workflow parsing failed" << Qt::endl; + for (const QString& error : parser.getErrors()) { + out << " " << error << Qt::endl; + } + errors++; + issues++; + } else { + out << "✓ Basic workflow structure valid" << Qt::endl; + + // Check for job dependencies + bool hasValidDeps = true; + for (const auto& [jobId, job] : workflow.jobs.asKeyValueRange()) { + if (!job.needs.isEmpty()) { + for (const QString& dep : job.needs) { + if (!workflow.jobs.contains(dep)) { + hasValidDeps = false; + out << "✗ Error: Job '" << jobId << "' depends on non-existent job '" << dep << "'" << Qt::endl; + errors++; + issues++; + } + } + } + } + + if (hasValidDeps && workflow.jobs.size() > 1) { + bool hasDeps = false; + for (const auto& [jobId, job] : workflow.jobs.asKeyValueRange()) { + if (!job.needs.isEmpty()) { + hasDeps = true; + break; + } + } + if (hasDeps) { + out << "✓ Job dependencies resolvable" << Qt::endl; + } + } + + // Check for known limitations + QString workflowContent; + QFile file(workflowFile); + if (file.open(QIODevice::ReadOnly)) { + workflowContent = QString::fromUtf8(file.readAll()); + file.close(); + } + + // Check for reusable workflows + if (workflowContent.contains("workflow_call")) { + out << "⚠ Warning: Uses reusable workflow (not supported in v1)" << Qt::endl; + out << " → Workaround: Flatten workflow or wait for v2" << Qt::endl; + out << " → See LIMITATIONS.md §3.1" << Qt::endl; + warnings++; + issues++; + } + + // Check for service containers + if (workflowContent.contains("services:")) { + out << "⚠ Warning: Service containers detected (not supported in v1)" << Qt::endl; + out << " → Workaround: Run services manually before workflow execution" << Qt::endl; + out << " → See LIMITATIONS.md §3.3" << Qt::endl; + warnings++; + issues++; + } + + // Check for advanced expressions + QStringList advancedExpressions = {"fromJSON", "hashFiles", "toJSON"}; + for (const QString& expr : advancedExpressions) { + if (workflowContent.contains(expr)) { + out << "⚠ Warning: Uses '" << expr << "' expression (limited support in v1)" << Qt::endl; + out << " → Workaround: Simplify expression or use explicit run steps" << Qt::endl; + out << " → See LIMITATIONS.md §3.1" << Qt::endl; + warnings++; + issues++; + break; // Only warn once for expressions + } + } + + // Check for macOS runners + if (workflowContent.contains("macos-latest") || workflowContent.contains("macos-")) { + out << "✗ Error: macOS runners not supported in v1" << Qt::endl; + out << " → Workaround: Use Linux runners or run macOS workflows on GitHub" << Qt::endl; + out << " → See LIMITATIONS.md §3.4" << Qt::endl; + errors++; + issues++; + } + + // Check for concurrency groups + if (workflowContent.contains("concurrency:")) { + out << "⚠ Warning: Concurrency groups (not supported in v1)" << Qt::endl; + out << " → Note: All jobs run as configured, no concurrency limits applied" << Qt::endl; + out << " → See LIMITATIONS.md §3.1" << Qt::endl; + warnings++; + issues++; + } + } + + out << Qt::endl; + } + + // Summary + if (issues == 0) { + out << "Summary: No issues detected" << Qt::endl; + out << "✓ System is ready for workflow execution" << Qt::endl; + } else { + out << "Summary: " << issues << " issue(s) detected"; + if (warnings > 0 && errors > 0) { + out << " (" << warnings << " warning(s), " << errors << " error(s))"; + } else if (warnings > 0) { + out << " (" << warnings << " warning(s))"; + } else if (errors > 0) { + out << " (" << errors << " error(s))"; + } + out << Qt::endl; + + if (errors > 0) { + out << "⚠ Workflow may fail or require modifications to run successfully" << Qt::endl; + } else { + out << "⚠ Workflow should run with noted limitations" << Qt::endl; + } + } + + out << Qt::endl; + out << "For detailed information on limitations and workarounds, see LIMITATIONS.md" << Qt::endl; + + return errors > 0 ? 1 : 0; +} + } // namespace cli } // namespace gwt