Files
git.stella-ops.org/docs/cicd/workflow-triggers.md

27 KiB

Workflow Triggers & Dependencies

Complete reference for CI/CD workflow triggering rules and dependency chains.


Trigger Types Overview

1. Push Triggers

Workflows triggered by commits pushed to branches.

on:
  push:
    branches: [main, develop]     # Branch filter
    paths:                        # Path filter (optional)
      - 'src/**'
    paths-ignore:                 # Exclude paths (optional)
      - 'docs/**'
    tags:                         # Tag filter (for releases)
      - 'v*'

2. Pull Request Triggers

Workflows triggered by PR events.

on:
  pull_request:
    branches: [main, develop]     # Target branch filter
    types: [opened, synchronize, reopened]  # Event types
    paths:
      - 'src/**'

3. Schedule Triggers

Cron-based scheduled execution.

on:
  schedule:
    - cron: '0 5 * * *'   # Daily at 5 AM UTC
    - cron: '0 2 * * 0'   # Weekly Sunday at 2 AM UTC

4. Manual Triggers

On-demand workflow execution with inputs.

on:
  workflow_dispatch:
    inputs:
      environment:
        type: choice
        options: [staging, production]
      dry_run:
        type: boolean
        default: false

5. Workflow Call (Reusable)

Called by other workflows.

on:
  workflow_call:
    inputs:
      category:
        type: string
        required: true

Complete Trigger Matrix

PR-Gating Workflows (Always Run on PR)

Workflow Branches Path Filters Purpose
test-matrix.yml main !docs/**, !*.md Unit, Architecture, Contract, Integration, Security, Golden tests
build-test-deploy.yml main, develop src/**, docs/**, scripts/** Build verification
policy-lint.yml main docs/policy/**, src/Cli/** Policy file validation
sast-scan.yml main, develop src/**, *.cs, *.ts, Dockerfile* Static security analysis
docs.yml - docs/**, scripts/render_docs.py Documentation validation
integration-tests-gate.yml main, develop src/**, src/__Tests/** Extended integration

Main Branch Only Workflows

Workflow Trigger Condition Purpose
build-test-deploy.yml → deploy github.ref == 'refs/heads/main' Deploy to staging
integration-tests-gate.yml → corpus-validation github.ref == 'refs/heads/main' Ground truth validation
coverage-report After integration tests on main Full coverage analysis

Tag-Triggered Workflows

Workflow Tag Pattern Example Purpose
release-suite.yml suite-* suite-2026.04 Ubuntu-style suite release
release.yml v* v2025.12.1, v2025.12.0-edge Version bundle release
module-publish.yml module-*-v* module-authority-v1.2.3 Per-module publishing

Scheduled Workflows

Workflow Schedule (UTC) Frequency Purpose
nightly-regression.yml 0 2 * * * Daily 2 AM Full regression suite
dependency-security-scan.yml 0 2 * * 0 Sunday 2 AM Vulnerability audit
renovate.yml 0 3,15 * * * Daily 3 AM & 3 PM Dependency updates
sast-scan.yml 30 3 * * 1 Monday 3:30 AM Weekly deep scan
migration-test.yml 30 4 * * * Daily 4:30 AM Migration validation
build-test-deploy.yml 0 5 * * * Daily 5 AM Extended build tests
test-matrix.yml 0 5 * * * Daily 5 AM Extended test categories

Manual-Only Workflows

Workflow Inputs Purpose
cli-build.yml rids, config, sign Multi-platform CLI builds
scanner-determinism.yml - Verify scanner reproducibility
cross-platform-determinism.yml - Cross-OS build verification
rollback.yml environment, service, version Emergency rollback
promote.yml from_env, to_env, version Environment promotion

Dependency Chains

Build → Test → Deploy Pipeline

┌─────────────────────────────────────────────────────────────────┐
│                    build-test-deploy.yml                         │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  profile-validation ─────────────────────────────────┐          │
│       │                                              │          │
│       ▼                                              │          │
│  build-test ─────────────────────────────────────────┤          │
│       │ (CLI, Concelier, Authority, Scanner, etc.)   │          │
│       │                                              │          │
│       ▼                                              │          │
│  quality-gates ──────────────────────────────────────┤          │
│       │ (Reachability, TTFS, Performance SLOs)       │          │
│       │                                              │          │
│       ▼                                              │          │
│  security-testing (PR label or schedule) ────────────┤          │
│       │                                              │          │
│       ▼                                              │          │
│  sealed-mode-ci ─────────────────────────────────────┤          │
│       │                                              │          │
│       ▼                                              │          │
│  docs ───────────────────────────────────────────────┤          │
│       │                                              │          │
│       ▼                                              │          │
│  scanner-perf ───────────────────────────────────────┘          │
│       │                                                         │
│       ▼                                                         │
│  deploy (main branch only OR workflow_dispatch)                 │
│       │                                                         │
│       ▼                                                         │
│  summary                                                        │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Test Matrix Pipeline

┌─────────────────────────────────────────────────────────────────┐
│                      test-matrix.yml                             │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  discover ─────────────────────────────────────────────────┐    │
│       │ (Find all *.Tests.csproj files)                    │    │
│       │                                                    │    │
│       ├───▶ pr-gating-tests (Matrix: 5 categories)         │    │
│       │         ├── Unit                                   │    │
│       │         ├── Architecture                           │    │
│       │         ├── Contract                               │    │
│       │         ├── Security                               │    │
│       │         └── Golden                                 │    │
│       │                                                    │    │
│       ├───▶ integration (PostgreSQL service)               │    │
│       │                                                    │    │
│       └───▶ extended-tests (schedule or manual)            │    │
│                 ├── Performance                            │    │
│                 ├── Benchmark                              │    │
│                 ├── AirGap                                 │    │
│                 ├── Chaos                                  │    │
│                 ├── Determinism                            │    │
│                 ├── Resilience                             │    │
│                 └── Observability                          │    │
│                                                    │       │    │
│       ◀────────────────────────────────────────────┘       │    │
│       │                                                    │    │
│       ▼                                                    │    │
│  summary ◀─────────────────────────────────────────────────┘    │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Suite Release Pipeline

┌─────────────────────────────────────────────────────────────────┐
│                    release-suite.yml                             │
│                  (suite-* tag OR manual)                         │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  parse-tag (if push event) ────────────────────────────────┐    │
│       │                                                    │    │
│       ▼                                                    │    │
│  validate ─────────────────────────────────────────────────┤    │
│       │                                                    │    │
│       ▼                                                    │    │
│  test-gate (optional, skip with skip_tests=true) ──────────┤    │
│       │                                                    │    │
│       ├───▶ build-modules (Matrix: 9 modules)              │    │
│       │         ├── Authority                              │    │
│       │         ├── Scanner                                │    │
│       │         ├── Concelier                              │    │
│       │         ├── Excititor                              │    │
│       │         ├── SbomService                            │    │
│       │         ├── EvidenceLocker                         │    │
│       │         ├── Policy                                 │    │
│       │         ├── Attestor                               │    │
│       │         └── VexLens                                │    │
│       │                                                    │    │
│       ├───▶ build-containers (Matrix: 9 images)            │    │
│       │                                                    │    │
│       ├───▶ build-cli (Matrix: 5 runtimes)                 │    │
│       │         ├── linux-x64                              │    │
│       │         ├── linux-arm64                            │    │
│       │         ├── win-x64                                │    │
│       │         ├── osx-x64                                │    │
│       │         └── osx-arm64                              │    │
│       │                                                    │    │
│       └───▶ build-helm                                     │    │
│                                                            │    │
│       ◀────────────────────────────────────────────────────┘    │
│       │                                                         │
│       ▼                                                         │
│  release-manifest ─────────────────────────────────────────┐    │
│       │                                                    │    │
│       ├───▶ generate-changelog                             │    │
│       ├───▶ generate-suite-docs                            │    │
│       └───▶ generate-compose                               │    │
│                                                            │    │
│       ◀────────────────────────────────────────────────────┘    │
│       │                                                         │
│       ▼                                                         │
│  create-release ───────────────────────────────────────────┐    │
│       │                                                    │    │
│       ▼                                                    │    │
│  commit-docs ──────────────────────────────────────────────┤    │
│       │                                                    │    │
│       ▼                                                    │    │
│  summary ◀─────────────────────────────────────────────────┘    │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Conditional Execution Patterns

Branch-Based Conditions

# Deploy only on main branch
deploy:
  if: github.ref == 'refs/heads/main'

# Run on main or develop
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop'

# Skip on release branches
if: "!startsWith(github.ref, 'refs/heads/release/')"

Event-Based Conditions

# Different behavior based on trigger
steps:
  - name: Full scan (schedule)
    if: github.event_name == 'schedule'
    run: ./scan.sh --full

  - name: Quick scan (PR)
    if: github.event_name == 'pull_request'
    run: ./scan.sh --quick

Input-Based Conditions

# Run extended tests if requested
extended-tests:
  if: >-
    github.event_name == 'schedule' ||
    github.event.inputs.include_performance == 'true' ||
    github.event.inputs.include_benchmark == 'true'

Failure-Based Conditions

# Run cleanup on failure
cleanup:
  if: failure()

# Run notification always
notify:
  if: always()

# Run only on success
deploy:
  if: success()

Complex Conditions

# Deploy gate: multiple conditions
deploy:
  if: >-
    needs.build-test.result == 'success' &&
    needs.docs.result == 'success' &&
    needs.scanner-perf.result == 'success' &&
    ((github.event_name == 'push' && github.ref == 'refs/heads/main') ||
     github.event_name == 'workflow_dispatch')

Path Filters Reference

Common Path Patterns

Pattern Matches Example Files
src/** All source code src/Scanner/Program.cs
docs/** All documentation docs/api/openapi.yaml
*.md Root markdown README.md, CHANGELOG.md
**/*.csproj All project files src/Cli/StellaOps.Cli.csproj
devops/** DevOps config devops/helm/values.yaml
.gitea/workflows/** Workflow files .gitea/workflows/test-matrix.yml

Path Filter Examples

# Source code changes only
paths:
  - 'src/**'
  - '!src/**/*.md'    # Exclude markdown in src

# Documentation only
paths:
  - 'docs/**'
  - '*.md'
  - 'scripts/render_docs.py'

# Security-relevant files
paths:
  - 'src/**/*.cs'
  - 'src/**/*.csproj'
  - '**/Dockerfile*'
  - '.gitea/workflows/sast-scan.yml'

# Dependency files
paths:
  - 'src/Directory.Packages.props'
  - '**/package.json'
  - '**/package-lock.json'
  - '**/*.csproj'

Tag Patterns Reference

Semantic Version Tags

# Standard releases
tags:
  - 'v*'           # v1.0.0, v2025.12.1, v2025.12.0-edge

# Channel-specific
tags:
  - 'v*-edge'      # v2025.12.0-edge
  - 'v*-stable'    # v2025.12.0-stable
  - 'v*-lts'       # v2025.12.0-lts

Suite Tags

tags:
  - 'suite-*'      # suite-2026.04, suite-2026.10

Module Tags

tags:
  - 'module-*-v*'  # module-authority-v1.2.3
                   # module-scanner-v2.0.0
                   # module-cli-v3.1.0

Workflow Inputs Reference

Common Input Types

workflow_dispatch:
  inputs:
    # String input
    version:
      description: 'Version to release'
      required: true
      type: string

    # Choice input
    environment:
      description: 'Target environment'
      type: choice
      options:
        - staging
        - production
      default: staging

    # Boolean input
    dry_run:
      description: 'Run without making changes'
      type: boolean
      default: false

    # Multi-select (via string)
    rids:
      description: 'Runtime identifiers (comma-separated)'
      type: string
      default: 'linux-x64,linux-arm64,win-x64'

Accessing Inputs

steps:
  - name: Use input
    run: |
      echo "Version: ${{ github.event.inputs.version }}"
      echo "Environment: ${{ inputs.environment }}"

      if [[ "${{ inputs.dry_run }}" == "true" ]]; then
        echo "Dry run mode"
      fi

Best Practices

1. Minimize PR Workflow Duration

# Use path filters to skip irrelevant runs
paths-ignore:
  - 'docs/**'
  - '*.md'
  - 'LICENSE'

# Use concurrency to cancel outdated runs
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

2. Fail Fast for Critical Issues

strategy:
  fail-fast: true   # Stop all jobs if one fails
  matrix:
    category: [Unit, Integration, Security]

3. Use Matrix for Parallel Execution

strategy:
  matrix:
    include:
      - category: Unit
        timeout: 20
      - category: Integration
        timeout: 45

4. Preserve Artifacts

- uses: actions/upload-artifact@v4
  with:
    name: test-results-${{ matrix.category }}
    path: ./TestResults
    retention-days: 14   # PR artifacts
    # retention-days: 90  # Release artifacts

5. Use Conditional Steps

- name: Deploy (main only)
  if: github.ref == 'refs/heads/main'
  run: ./deploy.sh

- name: Notify on failure
  if: failure()
  run: ./notify-slack.sh

Troubleshooting Triggers

Workflow Not Running

  1. Check branch protection rules - Ensure workflow runs are allowed
  2. Verify path filters - File changes must match paths patterns
  3. Check if conditions - Job may be skipped by condition
  4. Review concurrency settings - May be cancelled by concurrent run

Workflow Running Unexpectedly

  1. Check paths-ignore - May need to exclude more paths
  2. Review schedule - Cron schedule may overlap with events
  3. Check tag patterns - Tag may match unexpected pattern

Schedule Not Triggering

  1. Verify cron syntax - Use crontab.guru
  2. Check workflow file location - Must be on default branch
  3. Review repository activity - Inactive repos may have schedules disabled

Trigger Decision Tree

Use this decision tree to determine which workflows run for each event:

On PUSH to branch:
│
├── Is branch main/develop?
│   ├── YES → Run Category A (PR-Gating) + B (Main-Only) + affected C (Module)
│   └── NO (feature branch) → Skip CI (rely on PR workflow)
│
On PULL REQUEST:
│
├── Check changed paths
│   ├── docs/** only → Skip all (or run docs.yml only)
│   ├── src/** changed → Run Category A + affected C modules
│   └── *.csproj or *.props changed → Run Category A + B (full infrastructure)
│
On TAG push:
│
├── Match tag pattern
│   ├── suite-* → release-suite.yml
│   ├── module-*-v* → module-publish.yml
│   ├── service-*-v* → service-release.yml
│   ├── v*.*.* → containers-multiarch.yml + cli-build.yml
│   └── Other → Ignore
│
On SCHEDULE:
│
└── Run Category E pipelines per cron schedule

Smart Dependency Cascading

When shared libraries change, dependent module tests must also run:

Dependency Graph

SHARED LIBRARY                    TRIGGERS TESTS FOR
─────────────────────────────────────────────────────────────────
StellaOps.Cryptography*       →   ALL modules (security-critical)
                                  - Scanner, Attestor, Authority
                                  - EvidenceLocker, Signer
                                  - AirGap, Offline tests
                                  - Security test suite

StellaOps.Evidence*           →   Scanner, Attestor, EvidenceLocker
StellaOps.Provenance          →   ExportCenter, SbomService

StellaOps.Infrastructure.*    →   ALL integration tests
StellaOps.Postgres*               (database-dependent modules)

StellaOps.Replay*             →   Scanner, Determinism tests
StellaOps.Determinism             Replay module tests

StellaOps.Verdict             →   Policy, RiskEngine, ReachGraph
StellaOps.DeltaVerdict

StellaOps.Plugin              →   Authority, Scanner, Concelier
                                  (plugin-based modules)

Directory.Build.props         →   ALL modules (build config)
Directory.Packages.props          ALL tests
nuget.config

Cascade Implementation

Each workflow includes paths from its dependencies:

# Example: scanner-ci.yml with cascading
name: Scanner CI
on:
  push:
    branches: [main]
    paths:
      # Direct module paths
      - 'src/Scanner/**'
      - 'src/BinaryIndex/**'
      # Shared library dependencies (cascading)
      - 'src/__Libraries/StellaOps.Evidence*/**'
      - 'src/__Libraries/StellaOps.Cryptography*/**'
      - 'src/__Libraries/StellaOps.Replay*/**'
      - 'src/__Libraries/StellaOps.Provenance/**'
      # Infrastructure (triggers full test)
      - 'Directory.Build.props'
      - 'Directory.Packages.props'

Cascade Matrix Quick Reference

When This Changes Run These Tests
src/__Libraries/StellaOps.Cryptography*/** Scanner, Attestor, Authority, Evidence, Signer, AirGap, Security
src/__Libraries/StellaOps.Evidence*/** Scanner, Attestor, EvidenceLocker, Export
src/__Libraries/StellaOps.Infrastructure*/** ALL integration tests
src/__Libraries/StellaOps.Replay*/** Scanner, Determinism, Replay
src/__Libraries/StellaOps.Verdict/** Policy, RiskEngine, ReachGraph
src/__Libraries/StellaOps.Plugin/** Authority, Scanner, Concelier
Directory.Build.props ALL modules

Master Trigger Configuration

Complete Workflow Trigger Table

Workflow Feature Branch PR Main Push Tag Schedule
Category A: PR-Gating
build-test-deploy.yml Daily
test-matrix.yml Daily
determinism-gate.yml
policy-lint.yml * *
sast-scan.yml Weekly
secrets-scan.yml
dependency-license-gate.yml *
Category B: Main-Only
container-scan.yml * Daily
integration-tests-gate.yml
api-governance.yml * *
aoc-guard.yml * *
provenance-check.yml
Category C: Module-Specific
scanner-*.yml * *
concelier-*.yml * *
authority-*.yml * *
findings-ledger-ci.yml * *
evidence-locker.yml (manual)
[all module-*.yml] * *
Category D: Release
release-suite.yml suite-*
module-publish.yml module--v
service-release.yml service--v
release.yml v*
cli-build.yml (manual)
containers-multiarch.yml (manual)
rollback.yml (manual)
promote.yml (manual)
Category E: Scheduled
nightly-regression.yml 2AM
dependency-security-scan.yml * Sun 2AM
container-scan.yml * 4AM
renovate.yml 3AM/3PM
migration-test.yml 4:30AM

Legend: = with path filter, = always, = never*