Study guide

5.1 Action Architecture & action.yml Specification

GitHub Actions Certification GH-200

Track your progress as you read

Finished sections get a check mark.

1 Chapter 1: Introduction & Exam Overview

1.1 Exam Structure, Format & Scoring 1.2 GitHub Actions Architecture & Core Mental Model 1.3 Hands-On Preparation & Exam Day Strategy

2 Chapter 2: Workflow Triggers & Event Architecture

2.1 Webhook & Code Events: push, pull_request, and pull_request_target 2.2 Scheduled & Manual Triggers: schedule, workflow_dispatch, and repository_dispatch 2.3 Release, Issue, and Dynamic Lifecycle Events 2.4 Branch, Tag, and Path Filtering Patterns

3 Chapter 3: Jobs, Matrix Strategies & Execution Control

3.1 Job Anatomy, Step Execution & Job Dependencies (needs) 3.2 Contexts, Expressions & Functions 3.3 Environment Variables & Workflow Commands 3.4 Matrix Strategies & Multi-Platform Builds 3.5 YAML Anchors, Aliases & Merge Keys

4 Chapter 4: Reusable Workflows & Troubleshooting

4.1 Authoring & Calling Reusable Workflows (workflow_call) 4.2 Comparing Reusable Workflows, Composite Actions & Starter Workflows 4.3 Troubleshooting Workflow Runs & Debug Logging 4.4 Concurrency Controls & Status Check Functions

5 Chapter 5: Authoring Custom Actions

5.1 Action Architecture & action.yml Specification 5.2 Authoring Composite Actions 5.3 Building JavaScript Actions 5.4 Building Docker Container Actions

6 Chapter 6: Action Distribution, Marketplace & Advanced Action Types

6.1 Action Versioning, Semantic Releases & Tagging 6.2 Publishing Actions to GitHub Marketplace 6.3 Service Containers & Network Topology 6.4 actions/github-script & Workflow Tooling

7 Chapter 7: Runner Infrastructure & Self-Hosted Runners

7.1 GitHub-Hosted Runners & Larger Runners 7.2 Self-Hosted Runner Setup, Architecture & Communication 7.3 Self-Hosted Runner Security & Ephemeral Runners 7.4 Runner Groups, Labels & Organization Routing

8 Chapter 8: Enterprise Governance, Policies & Environments

8.1 Enterprise & Organization Action Policies 8.2 Environments, Protection Rules & Deployment Approvals 8.3 Repository Rulesets, Required Status Checks & Governance 8.4 Usage Limits, Billing Multipliers & Usage Metrics

9 Chapter 9: Secrets, Permissions & OIDC Cloud Authentication

9.1 Encrypted Secrets Architecture & Scopes 9.2 GITHUB_TOKEN & Least Privilege Configuration 9.3 OpenID Connect (OIDC) & Workload Identity Federation 9.4 Script Injection Prevention & Secure Workflow Patterns

10 Chapter 10: Supply Chain Hardening & Performance Optimization

10.1 Supply Chain Hardening: SHA Pinning, Dependabot & Artifact Attestations 10.2 Caching Dependencies with `actions/cache` 10.3 Artifacts Management & Job Handoff 10.4 Workflow Performance, Cost Optimization & Architecture Review

5.1 Action Architecture & action.yml Specification

Key Takeaways Explain This Topic AI

The action.yml (or action.yaml) metadata manifest is the mandatory declarative contract defining an action's name, description, inputs, outputs, branding, and execution runtime (runs.using).

GitHub Actions supports three distinct action execution models: JavaScript actions (Node.js runtime), Docker container actions (Linux container runtime), and Composite actions (multi-step shell and action pipelines).

Action inputs support validation keys including description, required, default, and deprecationMessage, while outputs define values mapped from execution steps or runtime code.

Actions can be published in dedicated public or private repositories (referenced via owner/repo@ref) or stored in subdirectories of a workflow repository (referenced locally via uses: ./.github/actions/my-action).

The branding block configures visual metadata for GitHub Marketplace, specifying a Feather icon and background badge color.

Last updated: August 2026

Action Architecture & action.yml Specification

In GitHub Actions, Actions represent the smallest reusable unit of computational work within a workflow step. While workflows orchestrate jobs and execution graphs, actions encapsulate specialized logic—such as configuring a toolchain, compiling binaries, interacting with the GitHub REST API, scanning container images, or publishing deployment artifacts.

Authoring custom actions allows organizations to standardize CI/CD patterns, eliminate boilerplate code across repositories, encapsulate security policies, and share automated solutions across the broader GitHub ecosystem. On the GitHub Actions Certification (GH-200) exam, custom action authoring accounts for a substantial portion of Domain 3 ("Author and Maintain Actions"). Candidates must demonstrate deep mastery of metadata schemas, runtime engine selection, and referencing syntax.

1. The Action Manifest: action.yml

Every custom action requires a metadata manifest file named either action.yml or action.yaml placed in the root of the action's repository or within a dedicated subfolder. This file is written in YAML syntax and defines the contract between the action author and the workflow caller. +-----------------------------------------------------------------------------+

  • | ACTION.YML MANIFEST ARCHITECTURE |
  • | |
  • | +---------------------------------------------------------------------+ |
  • | | METADATA IDENTIFIERS | |
  • | | - name: 'Enterprise Security Linter' | |
  • | | - author: 'DevOps Security Team' | |
  • | | - description: 'Audits source code for credential leaks and CVEs' | |
  • | +---------------------------------------------------------------------+ |
  • | | |
  • | v |
  • | +----------------------------------+----------------------------------+ |
  • | | | | |
  • | v v v |
  • | +--------------------+ +--------------------+ +--------------------+ |
  • | | INPUTS DEFINITION | | OUTPUTS DEFINITION | | BRANDING DEFINITION| |
  • | | - target-path | | - scan-status | | - icon: 'shield' | |
  • | | - fail-on-critical | | - vulnerabilities | | - color: 'red' | |
  • | +--------------------+ +--------------------+ +--------------------+ |
  • | | |
  • | v |
  • | +---------------------------------------------------------------------+ |
  • | | EXECUTION ENGINE: runs.using | |
  • | | - 'composite' (Combines run / uses steps) | |
  • | | - 'node20' (Executes JavaScript bundle on Node 20 runtime) | |
  • | | - 'docker' (Builds or pulls Linux container image) | |
  • | +---------------------------------------------------------------------+ |
  • +-----------------------------------------------------------------------------+
  • Top-Level Manifest Keys

Key Required Type Description & Purpose

name Yes String The human-readable name of the action displayed in workflow logs and the GitHub Marketplace.

author No String The name of the individual developer or organization maintaining the action.

description Yes String A detailed summary explaining what the action does, its prerequisites, and its operational behavior.

inputs No Object Defines the input parameters accepted by the action, including data types, defaults, and requirements.

outputs No Object Defines the output variables produced by the action and exposed to subsequent workflow steps.

runs Yes Object Configures the underlying execution engine, runtime environment, entrypoint scripts, and lifecycle hooks.

branding No Object Customizes the visual badge icon and background color when published to the GitHub Marketplace.

  • 2. Deep Dive: inputs and outputs Schema
  • Parameterizing with inputs

The inputs: map defines parameters callers can pass via the with: keyword in a workflow step. Each input key supports four configuration parameters: inputs:

api-token:

  • description: 'Authentication token for API communication'
  • required: true

scan-mode:

  • description: 'Scanning mode verbosity'
  • required: false
  • default: 'standard'

legacy-flag:

  • description: 'Deprecated flag replaced by scan-mode'
  • required: false
  • deprecationMessage: 'The legacy-flag input is deprecated. Use scan-mode instead.'

description (Required): Clear explanation of the input's purpose and expected values.

required (Optional, Boolean): If true , the caller workflow step must provide this input; if omitted, GitHub Actions aborts the job before execution with a validation error. Defaults to false .

default (Optional, String): The fallback value injected if the caller does not supply this input. Note that all defaults in action.yml are interpreted as strings.

deprecationMessage (Optional, String): When a workflow supplies this input, the runner logs a warning annotation containing this message, informing developers to migrate to a newer parameter.

Declaring outputs

The outputs: block registers data generated during execution for use downstream: outputs:

scan-passed:

  • description: 'Boolean flag indicating whether the security scan succeeded'
  • value: ${{ steps.audit-step.outputs.passed }} # Mandatory for composite actions

findings-count:

  • description: 'Total number of detected vulnerabilities'
  • value: ${{ steps.audit-step.outputs.total_cves }}

Important

For Composite Actions , the value: parameter is mandatory for every output in action.yml . It binds the action's public output key to a specific internal step's output ( ${{ steps.<step_id>.outputs.<output_key> }} ). For JavaScript and Docker actions, outputs are registered dynamically at runtime via the core SDK or $GITHUB_OUTPUT .

3. The branding Block for GitHub Marketplace

If you publish an action to the GitHub Marketplace, the branding block defines the visual badge rendered on the listing: branding:

  • icon: 'shield'
  • color: 'purple'

icon : Must match an official Feather icon name (e.g., activity , alert-circle , archive , award , box , check-circle , cloud , code , cpu , database , download , file-text , git-branch , globe , layers , lock , package , play , server , shield , terminal , tool , upload-cloud , zap ).

color : Restricted to standard Marketplace badge colors: white , yellow , blue , green , orange , red , purple , or gray-dark .

4. Comparing the Three Action Types

GitHub Actions supports three distinct runtime paradigms under runs.using : +-----------------------------------------------------------------------------+

  • | COMPARISON OF ACTION EXECUTION TYPES |
  • | |
  • | +-----------------------+-----------------------+---------------------+ |
  • | | JAVASCRIPT ACTION | COMPOSITE ACTION | DOCKER ACTION | |
  • | +-----------------------+-----------------------+---------------------+ |
  • | | - runs.using: 'node20'| - runs.using: 'comp..'| - runs.using: 'doc..'| |
  • | | - Native Node runtime | - Multiple run/uses | - Linux container | |
  • | | - Linux, macOS, Win | - Linux, macOS, Win | - Linux ONLY | |
  • | | - Sub-second startup | - Sub-second startup | - Container pull/bld| |
  • | | - Bundled dist/index | - Shell scripts | - System tooling | |
  • | +-----------------------+-----------------------+---------------------+ |
  • +-----------------------------------------------------------------------------+
  • Comprehensive Action Types Comparison Matrix
  • Characteristic JavaScript Actions Composite Actions Docker Container Actions
  • runs.using Identifier 'node20' 'composite' 'docker'
  • Operating System Support Linux, macOS, Windows Linux, macOS, Windows Linux ONLY (Fails on macOS/Windows)

Startup Overhead Extremely Low (< 1 second) Extremely Low (< 1 second) High (Image pull or local docker build )

Execution Speed Very Fast (Direct Node.js execution) Fast (Executes native shell processes) Moderate (Container namespace isolation)

Runtime Environment Node.js 20 bundled on runner Host runner shell ( bash , pwsh , etc.) Custom Linux image ( Dockerfile / registry)

Dependency Management Pre-bundled via @vercel/ncc Uses tools pre-installed on runner Packaged inside the container filesystem

Nested Actions Support No (Uses Octokit / Node libraries) Yes (Can execute uses: steps) No (Executes container entrypoint)

Lifecycle Hooks ( pre / post ) Yes ( pre , main , post ) No Yes ( pre-entrypoint , post-entrypoint )

Primary Use Cases API integrations, PR bots, fast logic Multi-step workflow scripts, reusable setups Heavy CLI toolchains, C/Rust, custom OS packages

5. Referencing Custom Actions in Workflows

Workflows invoke custom actions using the uses: keyword. Actions can be consumed from external repositories or from within the local repository.

Referencing Remote Actions steps:

  • # Pinned to a major release tag
  • name: Run Security Audit
  • uses: enterprise-org/security-linter@v2

with:

scan-mode: 'deep'

  • # Pinned to an immutable commit SHA (Recommended for security)
  • name: Run Build Action
  • uses: enterprise-org/builder-action@8a7b9c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b
  • # Stored in a repository subdirectory
  • name: Run Sub-Action
  • uses: enterprise-org/monorepo/actions/setup-db@v1
  • Referencing Local Actions

When an action is authored inside the same repository as the workflow (often in .github/actions/ ), use relative directory paths starting with ./ : jobs:

ci:

runs-on: ubuntu-latest

steps:

  • # 1. You MUST check out the repository first so local files exist on the runner
  • name: Checkout Repository Code
  • uses: actions/checkout@v4
  • # 2. Invoke local action using relative path
  • name: Execute In-Tree Linter
  • uses: ./.github/actions/custom-linter

with:

target-path: './src'

Caution

The Local Action Checkout Requirement: When using uses: ./.github/actions/my-action , the runner looks for the action definition on the runner's local filesystem at $GITHUB_WORKSPACE/.github/actions/my-action . If you do not run actions/checkout before calling a local action, the directory does not exist, and the step fails immediately with Action directory does not exist .