Skip to content

Releases: noxify/gitlab-ci-builder

v1.6.0

03 Jan 00:33
42812da

Choose a tag to compare

Minor Changes

  • e53a7c1: Added pipeline simulation feature and improved remote extends handling

    Simulation Features:

    • Added simulate CLI command to simulate GitLab CI pipeline execution
    • Added PipelineSimulator class for rule evaluation and job filtering
    • Support for branch, tag, and merge request pipeline simulation
    • Multiple output formats: summary, table, JSON, YAML, and text
    • Predefined CI variables automatically set based on context
    • Comprehensive integration and E2E test coverage

    Remote Extends Improvements:

    • Added mergeRemoteExtends global option to control remote extends resolution
    • Fixed remote extends resolution for accurate pipeline simulation
    • Better handling of remote includes and templates

    Documentation & Testing:

    • Enhanced CLI documentation with predefined variables table
    • Added error handling documentation for remote includes
    • Added "Common Pitfalls & Best Practices" section
    • Improved JSDoc coverage for all public APIs

v1.5.0

18 Dec 18:52
b5c6c71

Choose a tag to compare

Minor Changes

  • b6d0966: Add child pipeline visualization and fluent API support

    New Features:

    • Added childPipeline() method to define child pipelines via callback API
    • Added writeYamlFiles() method to automatically write parent and all child pipeline YAML files
    • Child pipelines are now fully visualized in Mermaid diagrams, ASCII trees, and stage tables
    • Child pipelines defined via callback are tracked and don't require filesystem access for visualization

    API Changes:

    • Added ChildPipelineConfig interface to track child pipeline configurations
    • Extended PipelineState with childPipelines map and getter methods
    • Added public getters to ConfigBuilder: jobs, templates, stages, jobOptionsMap
    • Extended VisualizationParams with trackedChildPipelines parameter
    • Enhanced extractChildPipelines to prioritize tracked configs over file system parsing

    Visualization Enhancements:

    • generateMermaidDiagram shows child pipelines as subgraphs with dotted trigger edges
    • generateAsciiTree displays child pipelines with 🔀 indicator
    • generateStageTable includes child pipeline jobs with separator rows and proper indentation
    • Added TriggerInfo interface to track trigger configurations in ExtendsGraphNode
    • Extended buildExtendsGraph to extract trigger information from job definitions

    Example:

    config.childPipeline(
      "trigger:deploy",
      (child) => {
        child.stages("deploy")
        child.job("deploy:prod", { script: ["./deploy.sh"] })
        return child
      },
      {
        strategy: "depend",
        outputPath: "ci/deploy-pipeline.yml",
      },
    )
    
    await config.writeYamlFiles(".")
    // Writes: .gitlab-ci.yml + ci/deploy-pipeline.yml

v1.4.2

24 Nov 19:50
0cfb9a3

Choose a tag to compare

Patch Changes

  • ac8da01: Add "Limitations" section to README

v1.4.1

24 Nov 19:35
515bff0

Choose a tag to compare

Patch Changes

  • 2b79ae0: Add comprehensive JSDoc documentation across the entire codebase
    • Added detailed JSDoc comments to all public APIs and internal functions
    • Included practical examples for complex methods
    • Added @see references linking to official GitLab CI/CD documentation
    • Documented all helper functions in importer, resolver, serializer, and visualization modules
    • Enhanced PipelineState class methods with parameter descriptions and usage examples
    • Improved documentation for TypeScript AST generation utilities

v1.4.0

24 Nov 18:43
7ff5e1a

Choose a tag to compare

Minor Changes

  • 87c99cf: Improve visualization rendering with professional libraries
    • Replace custom ASCII tree rendering with oo-ascii-tree for better box-drawing characters
    • Replace custom table rendering with climt for professional CLI tables
      • Change table layout from horizontal to vertical (Stage | Job columns)
      • Display one job per row with full ext ends chains

v1.3.0

24 Nov 16:34
cc1e7fe

Choose a tag to compare

Minor Changes

  • 280e33e: Add CLI visualization tool for GitLab CI pipelines

    • New gitlab-ci-builder command-line tool with visualize subcommand
    • Supports multiple input formats: local YAML files and remote URLs
    • Three visualization formats:
      • Mermaid diagram: Interactive flowchart visualization
      • ASCII tree: Text-based dependency tree
      • Stage table: Organized view by pipeline stages
    • Built-in support for extends resolution and dependency analysis
    • Easy to use: npx @noxify/gitlab-ci-builder visualize .gitlab-ci.yml

    CLI Usage

    # Visualize local YAML file (all formats)
    gitlab-ci-builder visualize .gitlab-ci.yml
    
    # Show only Mermaid diagram
    gitlab-ci-builder visualize .gitlab-ci.yml -f mermaid
    
    # Visualize remote pipeline
    gitlab-ci-builder visualize https://gitlab.com/my-org/my-project/-/raw/main/.gitlab-ci.yml
    
    # Show ASCII tree without stages
    gitlab-ci-builder visualize pipeline.yml -f ascii --show-stages=false

    Programmatic Usage

    Using YAML

    import { visualizeYaml } from "@noxify/gitlab-ci-builder"
    
    const yamlContent = `
    stages: [build, test]
    build:
      stage: build
      script: npm run build
    `
    
    const result = await visualizeYaml(yamlContent, { format: "all" })
    console.log(result.mermaid) // Mermaid diagram
    console.log(result.ascii) // ASCII tree
    console.log(result.table) // Stage table

    Using ConfigBuilder - Show only local jobs

    import { ConfigBuilder } from "@noxify/gitlab-ci-builder"
    
    const config = new ConfigBuilder()
      .stages("build", "test", "deploy")
      .template(".base", { image: "node:22" })
      .extends(".base", "build", { stage: "build", script: ["npm run build"] })
      .extends(".base", "test", { stage: "test", script: ["npm test"] })
    
    // Generate visualizations directly from ConfigBuilder
    const mermaid = config.generateMermaidDiagram({ showStages: true })
    const ascii = config.generateAsciiTree({ showRemotes: true })
    const table = config.generateStageTable()
    
    console.log(mermaid)
    console.log(ascii)
    console.log(table)

    Using ConfigBuilder - Resolve also configured includes

    import { ConfigBuilder, visualizeYaml } from "@noxify/gitlab-ci-builder"
    
    const config = new ConfigBuilder()
      .include({ remote: "https://custom-gitlab-host.com/org/branch/spec.yml" })
      .stages("build", "test", "deploy")
      .template(".base", { image: "node:22" })
      .extends(".base", "build", { stage: "build", script: ["npm run build"] })
      .extends(".base", "test", { stage: "test", script: ["npm test"] })
    
    const yaml = config.toYaml()
    const result = await visualizeYaml(yaml, {
      format: "all",
      // Optional: Authentication for private repositories
      gitlabToken: process.env.GITLAB_TOKEN,
      // Optional: GitLab host URL for project/template includes (default: https://gitlab.com)
      gitlabUrl: "https://custom-gitlab-host.com",
    })
    
    console.log(result.mermaid)
    console.log(result.ascii)
    console.log(result.table)

v1.2.0

24 Nov 12:41
6866625

Choose a tag to compare

Minor Changes

  • 712ec0d: Fluent Job Builder API

    New Feature: Fluent Job Builder API

    Added a powerful fluent builder interface for defining jobs and templates with chainable methods:

    New Methods:

    • addJob(name) - Create a new job with fluent builder interface
    • addTemplate(name) - Create a new template with fluent builder interface

    JobBuilder Methods:
    Common properties:

    • stage(stage) - Set job stage
    • extends(extend) - Set extends
    • image(image) - Set image
    • script(script) - Set script
    • beforeScript(script) - Set before_script
    • afterScript(script) - Set after_script
    • services(services) - Set services
    • cache(cache) - Set cache
    • artifacts(artifacts) - Set artifacts
    • setVariables(vars) - Set job variables
    • environment(env) - Set environment
    • when(when) - Set when condition
    • rules(rules) - Set rules
    • needs(needs) - Set needs
    • tags(tags) - Set tags
    • allowFailure(bool) - Set allow_failure
    • timeout(timeout) - Set timeout
    • retry(retry) - Set retry
    • parallel(parallel) - Set parallel
    • trigger(trigger) - Set trigger
    • coverage(pattern) - Set coverage pattern
    • dependencies(deps) - Set dependencies
    • resourceGroup(group) - Set resource_group
    • release(release) - Set release
    • interruptible(bool) - Set interruptible
    • idTokens(tokens) - Set id_tokens

    Utility methods:

    • set(props) - Bulk set multiple properties at once
    • jobOptions(opts) - Set job options (remote, mergeExtends, etc.)
    • remote(bool) - Mark job as remote
    • mergeExtends(bool) - Control extends merging
    • resolveTemplatesOnly(bool) - Control template resolution
    • done() - Finalize job and return to ConfigBuilder

    Auto-Return Behavior:
    When you call addJob() or addTemplate() from a JobBuilder, the previous job is automatically saved and a new builder is returned:

    const config = new ConfigBuilder()
    
    // Fluent API with auto-return
    config
      .stages("build", "test", "deploy")
      .addTemplate(".node")
      .image("node:20")
      .cache({ paths: ["node_modules/"] })
      .addJob("test")
      .stage("test")
      .extends(".node")
      .script(["npm test"])
      .addJob("build")
      .stage("build")
      .extends(".node")
      .script(["npm run build"])
      .addJob("deploy")
      .stage("deploy")
      .extends("build")
      .script(["kubectl apply -f k8s/"])
      .when("manual")
      .done()
    
    // Or use done() to explicitly return to ConfigBuilder
    config
      .addJob("lint")
      .stage("test")
      .script(["npm run lint"])
      .done()
      .addJob("format")
      .stage("test")
      .script(["npm run format:check"])
      .done()
    
    // Bulk property updates with set()
    config
      .addJob("complex")
      .set({
        stage: "test",
        image: "node:20",
        script: ["npm test"],
        cache: { paths: ["node_modules/"] },
        artifacts: { paths: ["coverage/"] },
      })
      .done()

    Benefits:

    • Type-safe: Full TypeScript support with autocomplete
    • Readable: Clear, declarative pipeline definitions
    • Flexible: Mix with existing job() and template() methods
    • Convenient: Auto-return behavior reduces boilerplate
    • Powerful: All job properties supported with dedicated methods

    This fluent API is especially useful for complex pipelines with many jobs, making the code more maintainable and easier to read.

  • 712ec0d: Graph Visualization

    New Features: Graph Visualization

    Added powerful visualization capabilities to analyze and visualize extends relationships in your GitLab CI pipelines:

    New Methods:

    • getExtendsGraph() - Get the extends dependency graph for programmatic access
    • generateMermaidDiagram(options?) - Generate Mermaid diagram for documentation/GitHub
    • generateAsciiTree(options?) - Generate ASCII tree for terminal output
    • generateStageTable(options?) - Generate CLI table with stages as columns

    Visualization Options:

    • showRemote: boolean - Show remote jobs with 🌐 indicator
    • showStages: boolean - Include job stages in output
    • highlightCycles: boolean - Highlight circular dependencies if detected

    Example Usage:

    const config = new ConfigBuilder()
    // ... configure your pipeline ...
    
    // Generate individual visualizations
    const mermaid = config.generateMermaidDiagram({ showStages: true })
    const ascii = config.generateAsciiTree({ showRemote: true })
    const table = config.generateStageTable()
    
    console.log(mermaid) // Mermaid diagram
    console.log(ascii) // ASCII tree
    console.log(table) // Stage table

    This feature is especially useful for:

    • Documenting complex CI configurations
    • Debugging extends chains and dependencies
    • Understanding job relationships at a glance
    • Detecting circular dependencies visually
  • 712ec0d: Enhanced Validation API

    New Feature: Enhanced Validation API

    Added dedicated validation methods for better control over pipeline validation:

    New Methods:

    • validate() - Validate pipeline and throw errors if validation fails (logs warnings to console)
    • safeValidate() - Validate pipeline without throwing errors, returns validation result with { valid, errors, warnings }

    Enhanced Methods:

    • getPlainObject(options?) - Now accepts { skipValidation?: boolean } option to skip validation when you've already validated separately
    • toJSON(options?) - Now accepts { skipValidation?: boolean } option
    • toYaml(options?) - Now accepts { skipValidation?: boolean } option

    Breaking Changes:

    • finalize() is now private - use safeValidate() for programmatic validation or validate() for validation that throws errors

    Usage Examples:

    // Standard validation (throws on error)
    config.validate()
    const pipeline = config.getPlainObject({ skipValidation: true })
    
    // Safe validation (no throw)
    const result = config.safeValidate()
    if (!result.valid) {
      console.error("Validation errors:", result.errors)
      return
    }
    if (result.warnings.length > 0) {
      console.warn("Warnings:", result.warnings)
    }
    const pipeline = config.getPlainObject({ skipValidation: true })
    
    // Quick validation (default behavior)
    const pipeline = config.getPlainObject() // validates automatically

    Benefits:

    • Separation of concerns: Validation is now separate from pipeline retrieval
    • Better error handling: safeValidate() enables programmatic error handling without try/catch
    • Performance: Skip validation when using multiple output methods (toYaml(), toJSON(), etc.)
    • Flexible: Choose between throwing (validate()) or returning errors (safeValidate())

v1.1.1

24 Nov 10:10
f482b95

Choose a tag to compare

Patch Changes

  • 118f5d4: Fixed extends resolution behavior with resolveTemplatesOnly: true

    Previously, when resolveTemplatesOnly: true was set (the default), ALL extends were removed after merging, including normal jobs and remote references that should have been preserved.

    Old behavior (incorrect):

    • Templates (.prefix) were merged ✅
    • Normal jobs (without .) were merged ❌ (should stay in extends)
    • Remote jobs were merged ❌ (should stay in extends)
    • Unknown/external jobs were merged ❌ (should stay in extends)

    New behavior (correct):

    • Templates (.prefix) are merged ✅
    • Normal jobs (without .) remain in extends ✅
    • Remote jobs remain in extends ✅
    • Unknown/external jobs remain in extends ✅

    This fix enables proper GitLab CI template composition patterns, particularly for shallow jobs that use remote: true to reference jobs from other configurations without merging them.

v1.1.0

22 Nov 16:26
90c02e9

Choose a tag to compare

Minor Changes

  • a04d3ff: Add comprehensive test infrastructure for GitLab CI templates with local YAML storage and improve type safety for rules array access
    • Add test helper utilities for GitLab template round-trip testing
    • Add 22 official GitLab CI templates as local test fixtures
    • Add integration tests for language templates (19 tests)
    • Add integration tests for infrastructure templates (3 tests)
    • Add integration tests for browser performance artifacts (2 tests)
    • Add support for spec with inputs (GitLab CI/CD components)
    • Add integration tests for multi-document YAML with OpenTofu component
    • Add interpolation support for schema fields that can contain GitLab CI/CD variables
    • Fix TypeScript type errors in test assertions for rules array access by adding proper type guards
    • Remove 'pages' from reserved job names (it's a valid GitLab Pages job name)
    • Reorganize tests into unit and integration directories

v1.0.0

22 Nov 13:44
c75bd58

Choose a tag to compare

Major Changes

  • 05df231: Major Release: Improved Type Safety and GitLab CI Compatibility

    This release brings significant improvements to type safety, extends resolution, and compatibility with complex GitLab CI configurations.

    Breaking Changes

    Architecture Refactoring

    The internal architecture has been completely refactored for better type safety and reliability:

    • Type System: Job definitions now use explicit input/output types (JobDefinitionInput, JobDefinitionNormalized, JobDefinitionOutput) instead of a single JobDefinition type. This provides better IntelliSense support and catches errors at compile time.
    • Extends Resolution: Completely rewritten extends resolution with proper topological sorting, cycle detection, and merge strategies that match GitLab CI's behavior.
    • State Management: New internal PipelineState model for cleaner separation of concerns and better maintainability.

    What This Means for You

    If you're using TypeScript, you may need to update type annotations that reference the old JobDefinition type. However, the public API remains the same - all existing code using ConfigBuilder should continue to work without changes.

    What's New

    Enhanced GitLab CI Compatibility

    • Complex Script Support: Full support for multiline scripts with shell operators, heredocs, and GitLab CI variables

      config.job("release", {
        before_script: [
          "npm ci --cache .npm --prefer-offline",
          `{
            echo "@\${CI_PROJECT_ROOT_NAMESPACE}:registry=\${CI_API_V4_URL}/projects/\${CI_PROJECT_ID}/packages/npm/"
            echo "\${CI_API_V4_URL#https?}/projects/\${CI_PROJECT_ID}/packages/npm/:_authToken=\${CI_JOB_TOKEN}"
          } | tee -a .npmrc`,
        ],
      })
    • Array Syntax Normalization: Single-element arrays in extends are now properly normalized to strings, matching GitLab CI's behavior

      # Input YAML
      job:
        extends: [.base]  # Single-element array
      
      # Now correctly outputs
      job:
        extends: .base    # Normalized to string
    • Parallel Matrix Support: Fixed schema to accept string, number, and array values for parallel.matrix, supporting all GitLab CI patterns

      config.job("test", {
        parallel: {
          matrix: [
            { NODE_VERSION: "18" }, // String values ✓
            { PARALLEL_COUNT: 3 }, // Number values ✓
            { BROWSERS: ["chrome", "firefox"] }, // Array values ✓
          ],
        },
      })

    Import/Export Improvements

    • Variable Preservation: GitLab CI variables like ${CI_COMMIT_BRANCH} are now correctly preserved during YAML import/export cycles
    • Template Literal Escaping: Fixed double-escaping bug in generated TypeScript code for multiline scripts

    Better Type Safety

    • Explicit Types: All pipeline components now have well-defined input and output types
    • Union Type Handling: Improved type guards for properties that can be strings or objects (like environment, cache, needs)
    • Better IntelliSense: More accurate autocomplete and type checking in your IDE

    Testing & Quality

    • 241 tests covering all functionality
    • 86%+ test coverage with comprehensive real-world use case tests
    • New test suites for:
      • Complex script handling with GitLab CI variables
      • Merge strategies and extends resolution
      • Pipeline state management
      • Real-world deployment scenarios

    Migration Guide

    For most users, no changes are required. However, if you have TypeScript code that references internal types:

    Before:

    import type { JobDefinition } from "@noxify/gitlab-ci-builder"
    const job: JobDefinition = { ... }

    After:

    import type { JobDefinitionInput } from "@noxify/gitlab-ci-builder"
    const job: JobDefinitionInput = { ... }

    The public API (ConfigBuilder methods, import/export functions) remains fully compatible with previous versions.