Copyright (c) 2026 MindMesh Academy. All rights reserved. This content is proprietary and may not be reproduced or distributed without permission.

5.3.2. Versioning and Release Strategy

💡 First Principle: Consumers pin at the precision they can tolerate — SHA, exact version, or major tag — so a maintainer's job is to publish releases whose meaning matches semantic versioning, letting each consumer choose between automatic fixes and frozen behavior.

Consumer pinExampleGets updatesRisk
Full commit SHA@a1b2c3… (40 chars)Never (manual bump)Lowest — immutable, but you own upgrades
Exact version tag@v1.2.3Never (unless tag moves)Low with immutable actions; tag-mutable otherwise
Major version tag@v1Patches and minors automaticallyModerate — you trust the maintainer's semver
Branch@mainEvery push❌ Highest — arbitrary code, never do this

The classic maintainer convention pairs an immutable release tag (v1.2.3) with a moving major tag (v1) re-pointed at each compatible release, so consumers on @v1 receive fixes automatically. Publish releases through GitHub Releases with real release notes, treat any change to action.yml inputs or outputs as potentially breaking, and use deprecationMessage to warn before removing an input rather than deleting it outright.

Two forces are reshaping this. Immutable actions (5.1.2) freeze published versions, which sits in tension with re-pointing a major tag — the direction of travel is publishing new versions rather than mutating old references. And security guidance increasingly pushes consumers toward SHA pinning (6.1.4), which shifts upgrade responsibility to them and makes automated dependency updates (Dependabot understands Actions references and will bump pinned SHAs with the version in a comment) part of the expected workflow.

Runtime deprecations are the other maintenance burden with an exam angle: GitHub periodically retires Node majors on runners, and actions declaring runs.using: node16 began emitting warnings and then failing as support ended. Keeping runs.using current — and testing against the current runner images (3.2.3) — is part of maintaining a published action.

⚠️ Exam Trap: @main (or any branch) is never an acceptable pin for a third-party action — it means "whatever that branch contains at run time." Even @v1 accepts the maintainer's future changes. The security-correct answer for untrusted actions is a full commit SHA; the convenience answer for first-party actions is a major tag.

Reflection Question: You maintain an action and want consumers to receive security patches without action on their part, while a regulated consumer wants byte-frozen behavior. Explain how a single release can satisfy both, and which pin each chooses.

See how it connects
Alvin Varughese
Written byAlvin Varughese
Founder18 professional certifications