Study guide
6.1 Action Versioning, Semantic Releases & Tagging
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
6.1 Action Versioning, Semantic Releases & Tagging
Key Takeaways Explain This Topic AI
Action versioning follows Semantic Versioning (SemVer 2.0.0) format vMAJOR.MINOR.PATCH (e.g., v1.2.3 ), where breaking changes mandate incrementing the MAJOR version identifier.
The major tag floating pattern dynamically moves mutable major tags (such as v1 or v2 ) to point to the latest stable minor/patch commit SHA, allowing consumers to receive security and bug fixes automatically.
Commit SHA pinning ( uses: actions/checkout@b4ffde65f46336ab851b4c731e846067756f7004 # v4.1.1 ) represents the ultimate security posture by providing cryptographic immutability against tag mutation, account takeovers, and supply chain attacks.
Release automation workflows streamline SemVer releases by compiling TypeScript distribution bundles ( dist/index.js ), drafting GitHub Releases, and atomically force-updating major floating tags.
Action authors can formally deprecate entire actions or specific runtime versions using the deprecationMessage: property in action.yml , triggering visible warning annotations in consuming runner execution logs.
Last updated: August 2026
Action Versioning, Semantic Releases & Tagging
When authoring and distributing custom GitHub Actions—whether for internal enterprise consumption or the public GitHub Marketplace—establishing a robust release and versioning strategy is essential. Workflows consuming your actions depend on predictable behavior, non-breaking updates, and cryptographic integrity.
Understanding how GitHub Actions resolves Git references ( @v1 , @v1.2.3 , @main , @<commit-sha> ) and mastering release automation patterns is a core competency tested on the GitHub Actions Certification (GH-200) examination.
1. Semantic Versioning (SemVer 2.0.0) in Actions
GitHub Actions strongly recommends that action authors adhere to Semantic Versioning 2.0.0 ( vMAJOR.MINOR.PATCH ). Each segment communicates specific compatibility guarantees to consuming workflows: v 1 . 4 . 2
- │ │ │
- │ │ └─── PATCH: Backwards-compatible bug fixes and security patches
- │ └─────── MINOR: Backwards-compatible new features, inputs, or outputs
- └─────────── MAJOR: Incompatible API changes, breaking inputs, or runtime shifts
- Version Increment Rules for Actions
Increment Type Triggering Scenarios in GitHub Actions Example Consumer Impact
MAJOR ( v1.0.0 → v2.0.0 ) • Renaming or deleting an existing required/optional input .; • Removing or changing the format of an existing output .; • Upgrading execution runtime (e.g., node16 → node20 ).; • Changing minimum runner OS requirements. Breaking: Consuming workflows referencing v1 will fail if upgraded without updating workflow inputs/outputs.
MINOR ( v1.1.0 → v1.2.0 ) • Adding a new optional input with a safe default.; • Introducing a new output .; • Adding support for an additional operating system. Non-Breaking: Workflows referencing v1 or v1.1 benefit from new features without configuration changes.
PATCH ( v1.2.1 → v1.2.2 ) • Fixing an internal logic bug in execution scripts.; • Updating internal npm/pip dependencies for CVE fixes.; • Performance optimizations without API changes. Non-Breaking: Transparent fix automatically received by consumers tracking v1 or v1.2 .
2. The Major Tag Floating Pattern
The standard distribution pattern endorsed by GitHub is the Major Tag Floating Pattern . Under this pattern, the action maintainer publishes exact immutable semantic release tags (e.g., v1.0.0 , v1.0.1 , v1.1.0 ) while simultaneously maintaining a mutable major tag (e.g., v1 ) that always points to the latest commit SHA within that major version. Commit Graph & Tag Movement:
- [Commit A] ─── (tag: v1.0.0, tag: v1)
- │
- [Commit B] ─── (tag: v1.0.1, tag: v1) <-- v1 moved forward to Commit B
- │
- [Commit C] ─── (tag: v1.1.0, tag: v1) <-- v1 moved forward to Commit C
- │
- [Commit D] ─── (tag: v2.0.0, tag: v2) <-- Breaking change: new v2 tag created
- │
- [Commit E] ─── (tag: v1.1.1, tag: v1) <-- Patch backported to v1: v1 moved to Commit E
- How Consumers Reference the Action
Consumers can choose their desired balance between stability and automated updates:
uses: actions/checkout@v4 : Recommended standard. Automatically receives all non-breaking features ( v4.1.0 ), bug fixes, and security patches ( v4.1.2 ) without requiring manual workflow edits.
uses: actions/checkout@v4.1.1 : Strict SemVer pinning. Pins to a specific minor/patch release. Will not automatically receive subsequent patch fixes.
uses: actions/checkout@main : Anti-pattern for production. Tracks the development branch tip. Unstable, untested commits or breaking development changes can instantly break consuming CI/CD pipelines.
Moving Tags via Git CLI
To move a major floating tag manually after creating a patch release: # 1. Create and push the specific patch tag
- git tag -a v1.2.3 -m "Release version 1.2.3"
- git push origin v1.2.3
- # 2. Force-update the major floating tag locally and remotely
- git tag -fa v1 -m "Update floating major tag v1 to v1.2.3"
- git push origin v1 --force
- 3. Commit SHA Pinning: The Ultimate Security Posture
While floating major tags provide developer convenience, Git tags are mutable references . An attacker who compromises a developer's GitHub account, an organization's personal access token (PAT), or a third-party repository maintainer account could force-push an existing tag (e.g., v3 ) to point to malicious code designed to exfiltrate secrets or backdoor production builds.
To achieve maximum supply chain security, enterprise security frameworks (such as OpenSSF Scorecard and SLSA) mandate Full 40-character Commit SHA Pinning for all third-party actions. # ✅ SECURE: Cryptographically immutable SHA pinning with human-readable comment
steps:
- name: Check out repository
- uses: actions/checkout@b4ffde65f46336ab851b4c731e846067756f7004 # v4.1.1
- name: Setup Node.js
- uses: actions/setup-node@60edb5dd545a775178f525247059d6427f4f91a9 # v4.0.2
with:
- node-version: '20'
- Comparison of Action Referencing Strategies
Reference Strategy Example Syntax Security Level Maintenance Overhead Automatic Fixes?
- Branch Ref uses: actions/checkout@main 🔴 Critical Risk Low (Always latest) Yes (and breaking changes)
- Floating Major Tag uses: actions/checkout@v4 🟡 Moderate Risk (Tag mutation) Low Yes (Minor and patch updates)
Exact SemVer Tag uses: actions/checkout@v4.1.1 🟡 Moderate Risk (Tag mutation) Medium (Manual tag bumps) No (Requires manual update)
Full Commit SHA uses: actions/checkout@b4ff... 🟢 Maximum Security (Immutable) Low (when using Dependabot) No (Dependabot opens PRs)
Tip
Automating SHA Updates: When pinning actions by full commit SHA, enable Dependabot version updates in .github/dependabot.yml with package-ecosystem: "github-actions" . Dependabot automatically detects new action releases, opens PRs with updated commit SHAs, and maintains the inline # vX.Y.Z version comments.
4. Automating Tag Releases with Workflows
Action maintainers automate the compilation, packaging, and tag-moving process using GitHub Actions itself. Because JavaScript actions require bundled dependencies ( dist/index.js ) to be checked into Git, a release workflow ensures that builds are compiled and tags are synced atomically. name: Release Action Version
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+' # Trigger on SemVer tags like v1.2.3
permissions:
contents: write
jobs:
publish-release:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
- uses: actions/setup-node@v4
with:
- node-version: '20'
- cache: 'npm'
- name: Install dependencies and compile bundle
- run: |
- npm ci
- npm run build # Bundles src/ into dist/index.js via @vercel/ncc
- name: Extract Major Version
- id: version
- run: |
- TAG_NAME="${{ github.ref_name }}"
- MAJOR_TAG=$(echo "$TAG_NAME" | cut -d. -f1)
- echo "major_tag=$MAJOR_TAG" >> $GITHUB_OUTPUT
- name: Update Floating Major Tag
- run: |
- git config user.name "github-actions[bot]"
- git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -fa "${{ steps.version.outputs.major_tag }}" -m "Update ${{ steps.version.outputs.major_tag }} to ${{ github.ref_name }}"
- git push origin "${{ steps.version.outputs.major_tag }}" --force
- 5. Deprecating Actions and Runtime Versions
As actions evolve, authors must retire legacy versions, runtime targets, or entire repositories without breaking existing builds abruptly. GitHub Actions provides native deprecation mechanisms in action.yml . name: 'Legacy Cloud Deployer'
- description: 'Deploys artifacts to legacy storage endpoints'
- # ⚠️ Deprecation message displayed as warning in runner logs
deprecationMessage: 'This action version is deprecated. Please migrate to my-org/cloud-deploy@v2 before December 2026.'
inputs:
api-key:
- description: 'API authorization key'
- required: true
runs:
- using: 'node20'
- main: 'dist/index.js'
- Deprecation Display & Runtime Migrations
Runner Warning: When a workflow step executes an action containing deprecationMessage: , the runner displays the message as a prominent warning annotation in the workflow summary and execution log.
Runtime Deprecation: When GitHub phases out older Node runtimes (e.g., node12 , node16 ), actions specifying deprecated runtimes trigger automatic runner warnings. Maintainers must update runs.using to supported runtimes (such as node20 ) and release a new major version.