From a2ddedb7444b5ac7cdd14b850d9a336710b63de5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 27 Dec 2025 03:25:19 +0000 Subject: [PATCH] Add LIMITATIONS.md and gwt doctor command - Created comprehensive LIMITATIONS.md documenting all v1 limitations with categories, resolution paths, and workarounds - Implemented 'gwt doctor' CLI command to check system and workflow compatibility - Updated README.md to reference LIMITATIONS.md - Updated USAGE.md with doctor command documentation and examples - Added example workflow demonstrating known limitations Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com> --- LIMITATIONS.md | 345 +++++++++++++++++++++++++ README.md | 16 +- USAGE.md | 28 ++ examples/workflow-with-limitations.yml | 75 ++++++ include/cli/CommandHandler.h | 1 + src/cli/CommandHandler.cpp | 209 +++++++++++++++ 6 files changed, 669 insertions(+), 5 deletions(-) create mode 100644 LIMITATIONS.md create mode 100644 examples/workflow-with-limitations.yml 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..037f3e1 100644 --- a/README.md +++ b/README.md @@ -102,11 +102,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/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..6e0096a 100644 --- a/src/cli/CommandHandler.cpp +++ b/src/cli/CommandHandler.cpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include namespace gwt { namespace cli { @@ -35,6 +37,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 +58,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 +156,209 @@ 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& job : workflow.jobs) { + if (!job.needs.isEmpty()) { + for (const QString& dep : job.needs) { + bool found = false; + for (const auto& otherJob : workflow.jobs) { + if (otherJob.id == dep) { + found = true; + break; + } + } + if (!found) { + hasValidDeps = false; + out << "✗ Error: Job '" << job.id << "' depends on non-existent job '" << dep << "'" << Qt::endl; + errors++; + issues++; + } + } + } + } + + if (hasValidDeps && workflow.jobs.size() > 1) { + bool hasDeps = false; + for (const auto& job : workflow.jobs) { + 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