Chapter 14Lesson 03~145 minutes

Workflow Triggers, Filters, Expressions, Contexts, Variables, Inputs, and Outputs: Configuration, Design Choices, and Tradeoffs

More triggers and variables do not automatically make automation more flexible; they often make its behavior harder to prove. This lesson focuses on design ownership: deciding which layer should filter work, which data class should hold a value, and when an output is a better contract than a file artifact or shared mutable state.

Design tradeoffsvars/env/secretsReusable workflowsArtifacts

Learning objectives

  • Choose between automatic event triggers, manual dispatch, reusable workflows, and external repository dispatch based on ownership and trust.
  • Choose between scheduler path filters and in-workflow conditions without creating missing required checks or unnecessary compute.
  • Classify values among vars, env, inputs, secrets, outputs, and artifacts.
  • Distinguish output contracts for small metadata from artifacts/files and explain their reliability/security implications.
  • Use a worked decision table to justify maintainability, security, reliability, compatibility, and cost.

Availability: All core decisions are learnable on GitHub.com Free/public repositories. Organization-level variables/secrets and environment policy vary by ownership, visibility, and plan; reusable-workflow access also depends on repository visibility and organization policy. The mandatory exercises do not require paid features.

1. Event trigger versus manual/reusable/external invocation

Choose a trigger by asking who owns the cause. If source change should always validate itself, use a repository event such as push or pull_request. If a human operator should decide when to run, use workflow_dispatch with a typed input schema. If another workflow owns the orchestration, use workflow_call. If an external system owns the cause, repository_dispatch can represent that event—but its payload is external input and the run still uses the workflow on the default branch.

Choice Good fit Primary governance question
Repository event CI, issue automation, release response Can an untrusted actor cause this event, and what permissions/secrets will the run get?
workflow_dispatch Operator-approved maintenance, diagnostics, controlled release step Who has write access to trigger it, and are inputs constrained enough?
workflow_call Shared reusable validation/deployment unit Who owns the called workflow version and its input/output contract?
repository_dispatch External build/test system or service integration Who can authenticate to create the dispatch, and how is client_payload validated?
schedule Periodic maintenance/reporting Is default-branch latest state the intended source, and what happens if execution is delayed?

2. Path filters versus in-job conditional logic

Scheduler filters prevent the run from being created. In-job conditions create the run and then skip selected jobs/steps. The former can reduce noise/compute; the latter leaves visible evidence and lets you publish a stable check name. That difference matters when branch protection requires a check.

Requirement Prefer Reason
Ignore a documentation-only workflow entirely Path filter No downstream governance requires a run/check.
Required CI check must always resolve Workflow triggers broadly; job logic narrows expensive work Avoid a filter-skipped required check remaining Pending.
Only release branches are relevant Branch filter Eligibility itself is part of policy.
Run lightweight validation always, expensive tests conditionally Job/step if: One run preserves full decision evidence.

Do not optimize Actions minutes by weakening the observability contract. First design the required evidence, then avoid unnecessary jobs within that contract.

3. vars versus env versus inputs versus secrets

Mechanism Owner / lifecycle Sensitive? Best use
env Workflow source code; workflow/job/step scope No Static workflow-local defaults and shell environment.
vars Repository/org/environment configuration No; values can be unmasked Operational non-sensitive config reused across workflows.
inputs Caller/operator supplied per invocation Treat as untrusted unless caller/control proves otherwise Parameters such as mode, target, Boolean feature choice.
secrets Repository/org/environment secret store Yes Credentials or sensitive values when no stronger short-lived identity is available.
GITHUB_TOKEN GitHub mints per workflow job Credential Repository API authentication with explicit least privilege.

“Not printed” does not make an env or vars value secret. Conversely, “stored in secrets” does not make arbitrary execution safe: code that can read a secret can intentionally exfiltrate it. Secret availability and runner/code trust must be designed together.

4. Outputs versus artifacts: metadata contract or file transfer?

Outputs are small strings attached to steps/jobs/reusable workflows and evaluated as part of the run graph. They are ideal for a version, digest, Boolean-like decision, artifact identifier, or generated name. Artifacts are stored files with retention, download, integrity, and permission concerns. Do not encode a binary or large JSON report into an output because it avoids learning artifact handling.

Need Mechanism Why
Pass image_digest to deploy job Job output Small scalar, direct dependency contract.
Pass compiled binary to test/deploy Artifact/package File identity and retention matter.
Share mutable “current mode” across jobs Avoid global mutable state; derive/output explicitly Reproducibility and causality are clearer.
Expose reusable workflow result to caller workflow output mapped from job output Explicit API contract across workflow boundary.

5. Typed inputs are UX and policy, not authorization

A choice input reduces typo space; a Boolean avoids string truthiness ambiguity; an environment input can select a GitHub environment. But input type does not authorize the action. Authorization comes from who may trigger the workflow, repository/environment policy, job permissions, and external-service identity. A caller who can choose production still must not automatically gain deployment authority.

on:
  workflow_dispatch:
    inputs:
      target:
        type: choice
        options: [staging, production]
        required: true

jobs:
  deploy:
    # Input chooses intent; environment policy governs authority.
    environment: ${{ inputs.target }}
    runs-on: ubuntu-latest

Environment governance is covered in Chapter 19. Here the key principle is separation: parameters describe requested behavior; permissions/protection rules decide whether the behavior is allowed.

6. Reusable workflows are versioned APIs

workflow_call turns a workflow file into a callable interface. Inputs and outputs are a schema. A caller can reference a reusable workflow from the same repository or an allowed external repository according to GitHub’s access rules. Treat the reusable workflow reference as a supply-chain dependency: production callers should deliberately select and review the version/reference they execute.

# Called workflow
on:
  workflow_call:
    inputs:
      test_level:
        type: string
        required: true
    outputs:
      report_id:
        value: ${{ jobs.validate.outputs.report_id }}

Do not use secrets as ordinary inputs. workflow_call has a separate secret contract, and nested reusable workflows require explicit forwarding/inheritance choices.

7. Worked scenario: Atlas Edge validation and release planning

Atlas Edge has a required PR validation, an optional expensive integration suite, a nightly dependency report, and a reusable release-preflight unit. Choose the control for each requirement.

Requirement Decision Maintainability / security / reliability rationale
Every PR gets a required validation result pull_request workflow broadly triggered Stable evidence; untrusted PR data treated as data; read-only token.
Integration suite only for service changes Conditional job based on a controlled change detector rather than filtering out the whole required workflow Required check still resolves; expensive compute is conditional.
Nightly dependency report schedule on default-branch workflow Time owns activation; result identity is current default-branch state.
Release-preflight shared across repositories Reviewed reusable workflow with typed input/output schema One maintained implementation; versioned dependency; centralized fixes.
External QA system requests a repository-side smoke test Optional repository_dispatch with narrow token/app and validated event type/payload Explicit external integration boundary rather than scraping UI.

Cost: avoid trigger storms and unnecessary jobs. Compatibility: verify GHES version before assuming newest GitHub.com syntax such as current typed-input or schedule features. Security: inputs and event payloads do not become trusted because they arrive through a structured context.

8. Anti-patterns and safer replacements

  • Anti-pattern: store a token in vars. Replace: secret or short-lived OIDC/App token, least privilege.
  • Anti-pattern: use path filters on a required workflow without testing check behavior. Replace: stable check-producing workflow and conditional expensive jobs.
  • Anti-pattern: parse a Boolean input as the string "true" everywhere. Replace: use typed inputs context.
  • Anti-pattern: pass large build results as outputs. Replace: artifact/package mechanisms with explicit identity.
  • Anti-pattern: let an external dispatch payload choose a shell command. Replace: allowlist typed event names/values and map them to fixed commands.

9. Lesson summary

The design goal is not fewer YAML lines; it is a smaller number of explicit contracts. Event contracts govern activation, variable classes govern configuration ownership, secret boundaries govern sensitive data, and output contracts govern forward data flow. A production workflow should make each contract reviewable without executing it.

Knowledge check

Why can a path filter be the wrong optimization for a required CI workflow?

Does a choice input authorize production deployment?

When should a value be a job output instead of an artifact?

Why treat a reusable workflow reference like a dependency?

Can configuration variables safely contain passwords if no step prints them?

Next lesson

Next: Workflow Triggers, Filters, Expressions, Contexts, Variables, Inputs, and Outputs: Diagnostics, Failure Modes, Security, and Performance

Further reading — current official GitHub sources

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.