Skip to content

wxharry/pipex

Repository files navigation

Pipex CLI Tool

Pipex is a TypeScript CLI tool for parsing, validating, and dry-running CI workflows locally. It targets GitHub Actions-style workflows with a modular parser and execution engine designed to support multiple CI platforms.

Key Features

  • Tolerant Parser: Parses GitHub Actions workflows with warnings for missing fields and supports reusable workflows (uses: jobs don't require runs-on).
  • Dry-run Executor: Simulates job/step execution respecting dependencies (needs:), evaluates conditional expressions (if:), and records mock results without running actual commands.
  • Flexible Evaluator: Supports nested and flattened dot-path context resolution (e.g., steps.cache.outputs.hit or "steps.cache.outputs.hit": true).
  • Config-driven Testing: Load context variables from JSON config files to control condition evaluation.
  • Reporter: Output execution results in CLI (colored, human-readable) or JSON formats.
  • Structured Warnings: Parser warnings available programmatically via parsePipelineWithWarnings.

Installation

Clone the repository and install dependencies:

npm install

Build the TypeScript source:

npm run build

Usage

Parse a Workflow

Parse and display workflow structure with warnings:

node dist/cli/index.js parse [workflow-file]

Example:

node dist/cli/index.js parse .github/workflows/ci.yml

Validate a Workflow

Validate workflow syntax, dependencies, and best practices:

node dist/cli/index.js validate [workflow-file]

Run Dry-run Execution

Execute workflow in dry-run mode (simulates execution without running commands):

node dist/cli/index.js run [options]

Options:

  • -f, --file <path> - Path to workflow YAML file (default: .github/workflows/ci.yml)
  • -c, --config <path> - Path to JSON config file for context variables
  • -r, --report <mode> - Report mode: cli (default) or json
  • --no-dry-run - Placeholder for actual execution (not implemented)

Default discovery:

  • When --file is omitted, the CLI searches .github/workflows/** recursively and uses the first .yml/.yaml file found.
  • If none are found, the command exits with an error.

Example with config:

node dist/cli/index.js run --file test.yaml --config testConfig.json --report cli

Config File Format

Create a JSON config file to provide context variables for condition evaluation:

{
  "env": {
    "NODE_ENV": "production",
    "TEST": "yes"
  },
  "secrets": {
    "API_KEY": "test-key"
  },
  "steps.cacheNodeModules.outputs.cache-hit": "true"
}

Supported Config Properties:

  • env: Environment variables (accessible as env.VAR_NAME)
  • secrets: Secret values (accessible as secrets.SECRET_NAME)
  • mockOutputs: Mock output values for expressions
  • Flattened dot keys: Any top-level key with dots (e.g., "steps.job.outputs.value": "data") is expanded into nested context

Dot-path Resolution:

The evaluator supports flexible resolution:

  • Nested: { steps: { cache: { outputs: { hit: true } } } }
  • Flattened at root: { "steps.cache.outputs.hit": true }
  • Mixed: { steps: { "cache.outputs.hit": true } }

All forms resolve correctly in expressions like ${{ steps.cache.outputs.hit == true }}.

Parser Behavior

The parser handles workflows tolerantly:

  • Reusable workflow jobs (containing uses:) can omit runs-on - a warning is logged.
  • Normal jobs (containing steps:) must have runs-on or an error is thrown.
  • Missing or malformed optional fields produce warnings rather than errors.
  • Step if conditions are parsed and passed to the executor as strings.

Reusable Workflow Job

jobs:
  deploy:
    uses: org/repo/.github/workflows/deploy.yml@main
    with:
      env: production

This is valid and will not require runs-on.

Executor (Dry-run)

The executor simulates workflow execution:

  • Resolves job execution order using topological sort (respects needs: dependencies).
  • Evaluates step if: conditions and marks steps as success, skipped, or unknown.
  • Records mock outputs without executing actual commands.
  • Detects circular dependencies and reports errors.

Step Condition Evaluation:

  • if: true → step executes (mocked success)
  • if: false → step skipped
  • if: ${{ env.MISSING }} → unknown (variable not found in context)

Reporter

Two output modes:

  • CLI: Human-friendly colored output with job/step hierarchy and status symbols (✔ success, ↷ skipped, ? unknown, ✖ error).
  • JSON: Machine-readable structured output with all job and step states.

Example CLI output:

Job: main [mocked]
  ✔ Cache node modules - success
  ↷ Get npm cache directory path - skipped
    [Dry-run] Step skipped due to condition
  ✔ Run tests - success

Testing

Run the test suite:

npm test

Run specific test file:

npx jest src/evaluator/__tests__/index.test.ts

Tests cover:

  • Parser (workflow parsing, if conditions, reusable workflows)
  • Executor (dependency resolution, condition evaluation, dry-run simulation)
  • Evaluator (expression parsing, dot-path resolution, context lookups)
  • Reporter (CLI and JSON formatting)
  • Config loader (flattened key expansion, env overrides)

Programmatic Usage

import { parsePipelineWithWarnings } from './src/parser';
import { PipelineExecutor } from './src/executor';
import { Reporter } from './src/reporter';

(async () => {
  const { model, warnings } = await parsePipelineWithWarnings('.github/workflows/ci.yml');
  
  if (warnings.length > 0) {
    console.warn('Parser warnings:', warnings);
  }

  const executor = new PipelineExecutor({
    context: {
      env: { NODE_ENV: 'test' },
      'steps.cache.outputs.hit': 'true'
    }
  });

  const state = await executor.execute(model);
  const reporter = new Reporter('cli');
  console.log(reporter.report(state));
})();

Extensibility

The parser is modular:

  • To support other CI platforms (GitLab, CircleCI, Bitbucket), create an adapter that converts the platform's workflow format into the PipelineModel interface.
  • Reuse the Evaluator, Executor, and Reporter modules without modification.

Contributing

Contributions welcome! Please open an issue or submit a pull request.

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published