Releases: jonathanrainer/ghafmt
Release list
Nightly Build (nightly.20260829.8a60211)
Automated nightly build from 8a6021127a5a607d5dfe2b245970f9d4c66fe8bf.
Docker Image
docker pull ghcr.io/jonathanrainer/ghafmt:nightly
0.1.5 (2026-04-26)
Fixes
- update rust crate similar to v3 (#105) (01d3132)
- update rust crate similar to v3.1.0 (#124) (e27377b)
- update rust crate clap to v4.6.1 (#131) (bf34b0e)
- ensure that adding blank lines between steps doesn't bleed into other areas (#136) (6ca7fad)
Project Infrastructure
- Extend dependency changeset workflow to cover Dependabot PRs in addition to Renovate, and rename the workflow file
accordingly. (0c91c3c)
Dependencies
- Bump rand from 0.9.2 to 0.9.4 (0c91c3c)
- chore(deps): update taiki-e/install-action action to v2.75.18 (d919609)
- chore(deps): update apple-actions/import-codesign-certs action to v7 (ee2c850)
- chore(deps): update taiki-e/install-action action to v2.75.19 (6a89723)
- chore(deps): update taiki-e/install-action action to v2.75.22 (45901f3)
Docker Image
docker pull ghcr.io/jonathanrainer/ghafmt:0.1.5
docker pull ghcr.io/jonathanrainer/ghafmt:latest
0.1.4 (2026-03-25)
Fixes
Fix strategy-sorter warning on expression-valued matrix fields
strategy-sorter now silently skips include, exclude, and dimension
keys whose values are GitHub Actions expressions (e.g.
${{ fromJSON(inputs.platforms) }}), rather than emitting a
TypeMismatch: expected sequence, got non-sequence warning.
Docker Image
docker pull ghcr.io/jonathanrainer/ghafmt:0.1.4
docker pull ghcr.io/jonathanrainer/ghafmt:latest
0.1.3 (2026-03-24)
Fixes
Store version in the action
Remove the version input and instead hardcode ACTION_VERSION as an env var
in the download step, kept in lockstep with Cargo.toml via a new Knope step
that updates it automatically during release preparation. (9209263)
Docker Image
docker pull ghcr.io/jonathanrainer/ghafmt:0.1.3
docker pull ghcr.io/jonathanrainer/ghafmt:latest
0.1.2 (2026-03-24)
Fixes
Fix action mode flag and remove redundant version input
Fix the --mode flag construction in the composite action so users can pass
mode: check rather than mode: mode=check.
Remove the version input and derive the binary version directly from
github.action_ref, keeping the action version and binary version in lockstep. (57b11a1)
Project Infrastructure
Fix release tag creation and remove yq workaround
Use a fine-grained PAT (RELEASE_PAT) for the knope release step so that
tag creation is not blocked by the repository ruleset restricting ref
creation for the default GITHUB_TOKEN.
Remove the set-cargo-version yq TOML-output workaround now that the
ubuntu-24.04-arm runner image ships a yq version with full TOML support. (c10672c)
Docker Image
docker pull ghcr.io/jonathanrainer/ghafmt:0.1.2
docker pull ghcr.io/jonathanrainer/ghafmt:latest
0.1.1 (2026-03-24)
Fixes
Fix step ID references in bare if: conditions not being updated
When a step ID was renamed (e.g. cache-thing → cache_thing), references
to that ID in if: conditions written without ${{ }} delimiters were left
unchanged, producing a broken workflow.
GitHub Actions allows if: fields to omit the expression wrapper, so
if: steps.cache-thing.outputs.cache-hit != 'true' is valid. The reference
updater now processes /if paths regardless of whether they contain ${{. (453bd89)
Project Infrastructure
Regenerate Cargo.lock during prepare-release
Added a cargo update -p ghafmt step to the prepare-release workflow so
that Cargo.lock reflects the new version before the release commit is made. (a05b484)
Harden workflows ahead of making repository public
Add explicit permissions: contents: read to all read-only jobs in
code_checks.yml, workflow_checks.yml, and the setup job in
nightly_build.yml, so that a default-permissions change cannot silently
grant write access.
Fix nightly_build.yml to upload artifacts/ghafmt-* instead of
artifacts/* to the nightly release, excluding the Docker layer-cache
artifact that would otherwise appear as a spurious release asset. (e104571)
Dependencies
- chore(deps): update taiki-e/install-action action to v2.69.7 (b52b460)
- chore(deps): update taiki-e/install-action action to v2.69.8 (cb38611)
Docker Image
docker pull ghcr.io/jonathanrainer/ghafmt:0.1.1
docker pull ghcr.io/jonathanrainer/ghafmt:latest
0.1.0 (2026-03-23)
Features
Action metadata file formatting
ghafmt now detects and formats GitHub Actions action metadata files
(action.yml / action.yaml) in addition to workflow files.
Supported action types
- Composite actions (
runs.using: composite) — top-level key ordering,
runskey ordering, step key ordering, alphabeticalwithsorting inside
steps, alphabeticalinputs/outputssorting with idiomatic per-entry key
ordering,brandingkey ordering, and snake_case enforcement on step IDs - JavaScript actions (
runs.using: node20/node24) — top-level key
ordering,runskey ordering (using → pre → pre-if → main → post → post-if), alphabeticalinputs/outputssorting - Docker container actions (
runs.using: docker) — top-level key
ordering,runskey ordering (using → image → args → env → pre-entrypoint → entrypoint → post-entrypoint), alphabetical
inputs/outputssorting
Files that cannot be identified as a workflow or action pass through
with presentation transforms only (blank lines, variable spacing).
Cross-platform binary builds
Pre-built binaries for aarch64-apple-darwin and x86_64-unknown-linux-musl
are now attached to each GitHub Release as assets. Support for
aarch64-unknown-linux-musl and x86_64-pc-windows-msvc is planned for
future releases. (247bd28)
Docker image published to GHCR
ghafmt is now available as a Docker image on GitHub Container Registry:
docker pull ghcr.io/jonathanrainer/ghafmt:latest
Nightly builds are also published as ghcr.io/jonathanrainer/ghafmt:nightly. (097523e)
GitHub Action
ghafmt is now available as a composite GitHub Action:
- uses: jonathanrainer/ghafmt@v0.2.0
with:
path: .github/workflows/
mode: checkSupports Linux x86_64, Linux ARM64, and macOS ARM64 and Intel. (90ca03b)
macOS Intel binary builds
Pre-built binaries for x86_64-apple-darwin (macOS Intel) are now included in
each GitHub Release, cross-compiled from the ARM64 runner using Apple's clang. (839d6cb)
macOS binary signing and notarization
Released macOS binaries are now signed with a Developer ID Application certificate and notarized
with Apple, so Gatekeeper no longer blocks them on download.
Signing and notarization is implemented as a composite action
(.github/actions/sign-and-notarize) following the existing set-cargo-version pattern, and
is called from the build artifacts workflow for macOS targets only. It runs exclusively on main
so signing credentials are never exposed during PR or feature branch builds. (638ec79)
Refactor: split main.rs, improve CLI, harden stdin reading
Structural changes
main.rshas been split into focused modules:src/lib.rs— orchestration andFormatterResultsrc/cli.rs— Clap argument definitionssrc/commands/— one file per mode (check,format,write,list), sharing aCommandtraitsrc/fs.rs—expand_paths,atomic_write, stdin reading
Bug fixes
read_from_stdinpreviously usedtake(LIMIT)to cap reads but then checkedn > LIMIT, a guard that could never
fire. The function now probes for an overflow byte after reading, correctly detecting inputs that exceed the limit
while accepting files of exactly the limit size.
Dependencies
- Added
atomic-write-file— replaces the hand-rolled temp-file-then-rename implementation ofatomic_write. - Added
patharg— typedInputArgenum wrapping file paths and stdin (-). - Added
strum_macros— derive-based enum string conversions for CLI mode/colour variants.
Tests
- Added unit tests for
read_with_limit(under limit, exactly at limit, over limit) andatomic_write(overwrites
rather than appends). (809abb2)
Fixes
Acknowledgements, licence detection fix & changeset detection
Added an Acknowledgements section to the README crediting @pantoniou
for libfyaml and @0k for the fyaml Rust bindings.
Added a LICENSE symlink pointing to LICENSE-MIT so that GitHub's licence detector
correctly identifies the repository licence rather than reporting it as unknown.
Updated the pre-commit hooks to detect if a changeset exists on the branch,
just to save time forgetting one on PRs (3f8595e)
Pre-commit hooks
A .pre-commit-config.yaml is now provided for local development. It runs
clippy, cargo deny, actionlint, and ghafmt (from source) as opt-in pre-commit
checks. (ce899c8)
Add README, CONTRIBUTING, and MIT/Apache-2.0 dual license
Adds a README with usage examples, CI integration snippets, and a before/after
example. Adds CONTRIBUTING.md with dev setup and transformer guide. Switches
license from GPL-3.0-only to MIT OR Apache-2.0. (490bf69)
Bring in libfyaml comment-handling fixes and related Rust improvements
Integrates fixes from the restructured jonathanrainer/libfyaml fork and
adds the Rust-side presentation work that depends on them.
Features
- Add
TopLevelCommentSpacerpresentation transformer: inserts a blank line
before any block of standalone top-level comments (col 0) that follows
content at a deeper indentation level, covering end-of-file comments and
other top-level comment blocks not preceded by a known top-level key
Bug fixes
insert_blank_line_before_comment_blockgains amax_comment_indent
parameter; when set, a comment preceded by an indent deeper than the
threshold is treated as content rather than part of the preceding comment
block, preventing the scan from skipping deeply-nested comments that belong
to the previous section- Fix
TopLevelCommentSpacernot triggering on inline right-hand comments:
only inserts a blank line when the preceding event is aLinebreak, so
comments that appear on the same line as a value are correctly ignored (7d783e2)
Code review fixes and improvements
Address findings from a review of the codebase.
Bug fixes
- Fix typo in
FilterSorter:on/pull_request_targe/branches-ignore→
on/pull_request_target/branches-ignore, which was silently skipping that
sort path - Remove
outputsandsecretsfromWorkflowDispatchSorter; those keys
belong toworkflow_callonly and were being incorrectly sorted - Fix
Rename::Ord/PartialOrd/Eq/PartialEqimpls inCaseEnforcerthat
compared only depth, violating theEq/Ordcontract; sorting is now done
viasort_by_keywithReverseon depth - Reject
stdin (-)with--mode=list, consistent with the existing
--mode=writerestriction; produces a structured error via the same
StdinCannotBeUsedWithListvariant
Refactoring
- Replace ad-hoc
eprintln!calls for early validation errors inGhafmt::run
with structuredErrorvariants rendered throughrender_error, so colour
mode is respected and diagnostics are consistent - Extract
build_handlerandrender_erroraspub(crate)free functions;
remove them from theCommandtrait entirely — callers use the free functions
directly - Simplify
FormatterResult: replaceoriginal: Option<String>+ accessor
method with a plainpub(crate) original: Stringfield - Change
Ghafmt::runsignature frommut selfto&mut self - Pre-compute static key-ordering
Vec<String>fields in transformer struct
constructors instead of allocating on everyprocess()call; affected
transformers:TopLevelSorter,JobSorter,StepSorter,ConcurrencySorter,
StrategySorter,ContainerSorter,RunsOnSorter,EnvironmentSorter,
WorkflowCallSorter - Change
sort_mapping_at_pathandclassify_renamessignatures to accept
&[T]instead of&Vec<T> - Make the
WorkflowProcessortransformer pipeline injectable via
WorkflowProcessor::new(Vec<Box<dyn StructureTransformer>>)with a
Defaultimpl that builds the standard pipeline; removes the need for a
test-only constructor - Derive
CopyonStateenums inJobsBlankLinesandStepsBlankLines;
remove now-redundant.clone()calls at match sites - Remove stale
#[allow(unused_assignments)]fromerrors.rs - Fix
--colourflag spelling in the CLI integration test (was--color,
causing the test to pass vacuously against a clap parse error)
Tests
- Add unit tests for
source_windowandline_col_to_byte_offsetinerrors.rs - Add integration tests for
WorkflowProcessorerror recovery: failed
transformer emits a warning, document is restored, and subsequent transformers
still run - Add
list_mode_rejects_stdinCLI integration test - Add
pull_request_target_branches_ignore_sortedregression test inFilterSorter - Remove duplicate
multi_job_comments_between_stepstest case inStepsBlankLines(5fd7503)
Fix --check silent failure and multi-file error message
--check now prints a unified diff to stderr for each file that differs from its
formatted form, instead of silently exiting 1. The no-flag multi-file error message
now mentions --check and --list alongside --write. (4d2689b)
Fix Docker build failure due to missing musl headers
The Docker build was failing because bindgen (used by fyaml-sys) invoked clang with the
default glibc include paths, causing a fatal error when it couldn't find
bits/libc-header-start.h.
Fixed by setting BINDGEN_EXTRA_CLANG_ARGS=--sysroot=/usr/local/musl/${RUST_MUSL_CROSS_TARGET}
in the cargo build step, pointing clang at the musl sysroot already bundled in the
rust-musl-cross image. This works for both linux/amd64 and linux/arm64 targets. (f569f76)
Fix folded scalars emitting extra blank lines
When a string value used a >/>-/>+ folded scalar an extra trailing blank line
would be emitted af...