Merge pull request #4 from johndoe6345789/copilot/document-known-limitations-strategy

Add formal limitations specification and gwt doctor diagnostic command
This commit is contained in:
2025-12-27 03:33:16 +00:00
committed by GitHub
8 changed files with 987 additions and 5 deletions

345
LIMITATIONS.md Normal file
View File

@@ -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: **MediumHigh**
- 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.

View File

@@ -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

View File

@@ -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"

View File

@@ -0,0 +1 @@
.

View File

@@ -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

View File

@@ -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/

View File

@@ -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

View File

@@ -6,6 +6,9 @@
#include <QCoreApplication>
#include <QTextStream>
#include <QDebug>
#include <QProcess>
#include <QFile>
#include <QFileInfo>
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 <repo> List workflows in a repository" << Qt::endl;
out << " run <repo> <wf> 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