Releasing the actions

This repository is a monorepo of actions: several independently-consumed actions are served from one repo. To let downstream projects pin a specific version — and let Dependabot propose bumps — each action is released under its own path-prefixed tag.

Tag scheme

The tag prefix is the action's leaf directory name, which is also the prefix a consumer repeats in the @ref:

Action (consumed path)Tag prefixExample tag
allowlist-checkallowlist-checkallowlist-check/v1.2.3
pelicanpelicanpelican/v1.2.3
stash/savesavesave/v1.2.3
stash/restorerestorerestore/v1.2.3

For every X.Y.Z release we also move a major tag (<prefix>/vN) to the same commit, so consumers can track a major line if they prefer.

This leaf-name prefix scheme is the format Dependabot's github_actions ecosystem understands for monorepos (dependabot/dependabot-core#11286, added specifically for this repo). Dependabot filters candidate tags by the prefix, so save/* and restore/* bump independently.

How a release happens (automatic)

Releases are cut automatically by .github/workflows/release-actions.yml on every push to main that touches an action's files. The workflow runs scripts/release_actions.py, which:

  1. Diffs the pushed range and maps changed files to the affected action(s). A change under stash/shared/ releases both stash actions, since they import that shared code at runtime.
  2. Picks the bump type (see below).
  3. For each affected action, computes the next version from the newest existing <prefix>/vX.Y.Z tag (the first release seeds v1.0.0), creates the annotated tag and moves the <prefix>/vN major tag.

Tags only — no GitHub Releases

A release here is a pair of git tags and nothing else. No GitHub Release object is created.

That is deliberate: Dependabot‘s github_actions ecosystem discovers versions by listing tags and filtering them by prefix, so a Release is not part of any path a consumer or a bump PR depends on. The only thing its absence costs is the “Release notes” section of Dependabot’s PR body, which is cosmetic.

If GitHub Releases are wanted later, they can be added on top of the existing tags without disturbing them.

Choosing the bump

The bump defaults to patch. Raise or suppress it per PR:

Signal (PR label or commit-message token)Effect
nonepatch (default)
release:minor / [minor]minor
release:major / [major]major
release:skip / [skip release]no release cut

Labels take precedence over commit-message tokens; release:major wins over release:minor.

Cutting a release manually

Use the Run workflow button on the Release actions workflow (workflow_dispatch) to release out-of-band — for example to seed the very first tags or to force a specific bump:

  • action — a single tag prefix (allowlist-check, pelican, save, restore). Leave empty to auto-detect from the latest commit.
  • bumppatch, minor or major.

Testing the release logic

The version math and changed-action detection are pure functions with unit tests:

uv run pytest scripts/test_release_actions.py

A dry run (no --apply, so nothing is tagged or pushed) prints what would be released:

python3 scripts/release_actions.py \
  --repo apache/infrastructure-actions --action restore --bump minor