Skip to content

Releases: jonathanrainer/ghafmt

Nightly Build (nightly.20260829.8a60211)

Choose a tag to compare

@github-actions github-actions released this 29 Aug 05:44
8a60211

Automated nightly build from 8a6021127a5a607d5dfe2b245970f9d4c66fe8bf.

Docker Image

docker pull ghcr.io/jonathanrainer/ghafmt:nightly

0.1.5 (2026-04-26)

Choose a tag to compare

@jonathanrainer jonathanrainer released this 26 Apr 16:02
070608d

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)

Choose a tag to compare

@jonathanrainer jonathanrainer released this 25 Mar 14:03
4b5f68e

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.

Fixes #88. (83f66d2)

Docker Image

docker pull ghcr.io/jonathanrainer/ghafmt:0.1.4
docker pull ghcr.io/jonathanrainer/ghafmt:latest

0.1.3 (2026-03-24)

Choose a tag to compare

@jonathanrainer jonathanrainer released this 24 Mar 17:14
33100c4

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)

Choose a tag to compare

@jonathanrainer jonathanrainer released this 24 Mar 16:52
7faef2e

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)

Choose a tag to compare

@jonathanrainer jonathanrainer released this 24 Mar 13:20
c10672c

Fixes

Fix step ID references in bare if: conditions not being updated

When a step ID was renamed (e.g. cache-thingcache_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)

Choose a tag to compare

@github-actions github-actions released this 23 Mar 06:40
270f1c8

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,
    runs key ordering, step key ordering, alphabetical with sorting inside
    steps, alphabetical inputs/outputs sorting with idiomatic per-entry key
    ordering, branding key ordering, and snake_case enforcement on step IDs
  • JavaScript actions (runs.using: node20 / node24) — top-level key
    ordering, runs key ordering (using → pre → pre-if → main → post → post-if), alphabetical inputs/outputs sorting
  • Docker container actions (runs.using: docker) — top-level key
    ordering, runs key ordering (using → image → args → env → pre-entrypoint → entrypoint → post-entrypoint), alphabetical
    inputs/outputs sorting

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: check

Supports 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.rs has been split into focused modules:
    • src/lib.rs — orchestration and FormatterResult
    • src/cli.rs — Clap argument definitions
    • src/commands/ — one file per mode (check, format, write, list), sharing a Command trait
    • src/fs.rsexpand_paths, atomic_write, stdin reading

Bug fixes

  • read_from_stdin previously used take(LIMIT) to cap reads but then checked n > 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 of atomic_write.
  • Added patharg — typed InputArg enum 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) and atomic_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 TopLevelCommentSpacer presentation 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_block gains a max_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 TopLevelCommentSpacer not triggering on inline right-hand comments:
    only inserts a blank line when the preceding event is a Linebreak, 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 outputs and secrets from WorkflowDispatchSorter; those keys
    belong to workflow_call only and were being incorrectly sorted
  • Fix Rename::Ord/PartialOrd/Eq/PartialEq impls in CaseEnforcer that
    compared only depth, violating the Eq/Ord contract; sorting is now done
    via sort_by_key with Reverse on depth
  • Reject stdin (-) with --mode=list, consistent with the existing
    --mode=write restriction; produces a structured error via the same
    StdinCannotBeUsedWithList variant

Refactoring

  • Replace ad-hoc eprintln! calls for early validation errors in Ghafmt::run
    with structured Error variants rendered through render_error, so colour
    mode is respected and diagnostics are consistent
  • Extract build_handler and render_error as pub(crate) free functions;
    remove them from the Command trait entirely — callers use the free functions
    directly
  • Simplify FormatterResult: replace original: Option<String> + accessor
    method with a plain pub(crate) original: String field
  • Change Ghafmt::run signature from mut self to &mut self
  • Pre-compute static key-ordering Vec<String> fields in transformer struct
    constructors instead of allocating on every process() call; affected
    transformers: TopLevelSorter, JobSorter, StepSorter, ConcurrencySorter,
    StrategySorter, ContainerSorter, RunsOnSorter, EnvironmentSorter,
    WorkflowCallSorter
  • Change sort_mapping_at_path and classify_renames signatures to accept
    &[T] instead of &Vec<T>
  • Make the WorkflowProcessor transformer pipeline injectable via
    WorkflowProcessor::new(Vec<Box<dyn StructureTransformer>>) with a
    Default impl that builds the standard pipeline; removes the need for a
    test-only constructor
  • Derive Copy on State enums in JobsBlankLines and StepsBlankLines;
    remove now-redundant .clone() calls at match sites
  • Remove stale #[allow(unused_assignments)] from errors.rs
  • Fix --colour flag 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_window and line_col_to_byte_offset in errors.rs
  • Add integration tests for WorkflowProcessor error recovery: failed
    transformer emits a warning, document is restored, and subsequent transformers
    still run
  • Add list_mode_rejects_stdin CLI integration test
  • Add pull_request_target_branches_ignore_sorted regression test in FilterSorter
  • Remove duplicate multi_job_comments_between_steps test case in StepsBlankLines (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...

Read more