Skip to content

Releases: adaouat/heraut

v1.0.0

13 Jun 17:39
Immutable release. Only release title and notes can be modified.
v1.0.0
b276fa8

Choose a tag to compare

🚀 Features

  • (app) Check runtime --env checks the env's effective platforms - (74ae0e1) by @bchatard

    RuntimeCheck's Platforms section only ever read cfg.Release.Platforms,
    so heraut check runtime --env <env> (and bare heraut check --env <env>) silently ignored an environment's release.platforms override.

    RuntimeCheck gains an env parameter and resolves the effective platform
    list with the same replace semantics as buildReleasePipelineConfig and
    hasEffectivePlatforms (T89): the env's release.platforms replaces the
    root list wholesale when non-empty, otherwise the root list is checked.
    internal/cmd/check.go reads the root --env flag and threads it through
    runRuntimeCheck for both the bare check and check runtime commands.

    Roadmap:docs/tasks/roadmap.md -> T100 Co-Authored-By:Claude Fable 5 noreply@anthropic.com

  • (config) Validate tag_pattern requires git-cliff generator - (bcd9467) by @bchatard

    tag_pattern is a git-cliff-only field — communique and cocogitto
    silently ignore it. Gate it in validateContentDriver the same way
    tickets is gated, so a non-git-cliff generator paired with tag_pattern
    now fails heraut check config with an actionable hint instead of being
    silently dropped.

    The single check covers top-level changelog/release.notes and their
    per-env equivalents, since MergeContentDriver (ADR-0019) already
    resolves each per-env driver to its effective (generator, tag_pattern)
    pair before validation runs.

    Roadmap:docs/tasks/roadmap.md -> T97 Co-Authored-By:Claude Fable 5 noreply@anthropic.com

  • (scaffold) Warn before dropping unsupported settings on init update - (1a0f3f9) by @bchatard

    The "Update it?" flow in heraut init regenerates .heraut.yml from
    ConfigToAnswers/GenerateYAML, which don't round-trip tickets,
    remote_metadata, release.assets, per-platform base_url/draft/prerelease,
    or per-env changelog/release overrides. Previously this loss was silent.

    Add scaffold.DroppedFields to detect any of these in the loaded config
    and print a warning (with the affected YAML paths) before the wizard
    runs, so the user can decide whether to continue. Export
    config.DefaultBaseURL so the base_url check can ignore type defaults
    filled in by normalizePlatforms.

    Roadmap:docs/tasks/roadmap.md -> T99 Co-Authored-By:Claude Fable 5 noreply@anthropic.com

🐛 Bug Fixes

  • (cmd) Unify --version override validation across release/changelog - (e269720) by @bchatard

    heraut release rejected valid CalVer and pre-release --version overrides
    via a SemVer-only regex, while heraut changelog --version validated
    nothing. NewResolver already treats --version as an opaque string with
    zero shape validation (StaticResolver), and spec 03 documents no shape
    restriction.

    Drop the SemVer regex and add tagfmt.ValidateVersionOverride /
    app.ValidateVersionOverride — non-empty, no whitespace, otherwise
    format-agnostic (mirrors ValidateBuildID minus the "/" ban, since a full
    tag override may contain one). Apply identically to both commands.

    Roadmap:docs/tasks/roadmap.md -> T90 Co-Authored-By:Claude Fable 5 noreply@anthropic.com

  • (cmd) Align check/version validation, no-config, and exit codes - (d2406b6) by @bchatard

    Three consistency fixes:

    • version next/current now run config.Validate before resolving, so
      per-env misconfigs (e.g. promotion cycles) print the same path/hint
      output as check config and exit Config, instead of surfacing as raw
      resolver errors deep in the perenv promotion logic.

    • Bare heraut check degrades like check runtime when no config
      file exists (warns and proceeds with cfg = nil) instead of hard
      failing, so it works the same as running each subcommand
      individually in a config-less directory.

    • Bare heraut check now classifies its exit code by what failed:
      Config if the config section had errors (even if runtime/cliff also
      failed), Runtime otherwise.

    Roadmap:docs/tasks/roadmap.md -> T98 Co-Authored-By:Claude Fable 5 noreply@anthropic.com

  • (cmd/release) Inherit root platforms when env release omits platforms - (1b5283e) by @bchatard

    hasEffectivePlatforms returned false whenever an env's release: block
    was non-nil but set no platforms (e.g. notes-only override), even
    though buildReleasePipelineConfig correctly falls back to the root
    platform list in that case. Align the guard with the builder's merge
    semantics: env platforms replace root only when non-empty.

    Roadmap:docs/tasks/roadmap.md -> T89 Co-Authored-By:Claude Fable 5 noreply@anthropic.com

  • (pipeline) Push only the resolved tag, not all local tags - (8e08976) by @bchatard

    Both pipelines ran git push origin --tags, which publishes every local
    tag including stale or experimental ones. Add gitHelper.pushTag(tag) and
    use it to push result.Tag explicitly. Align the changelog pipeline's
    "Push tags" step naming with the release pipeline's "Push tag", and have
    dry-run output name the exact tag being pushed.

    Roadmap:docs/tasks/roadmap.md -> T93 Co-Authored-By:Claude Fable 5 noreply@anthropic.com

  • (platforms/gitlab) Inject token_env into release-time glab calls - (bd0bcb9) by @bchatard

    CreateRelease and UploadAssets passed only hostEnv(), so a custom
    token_env (or a self-hosted instance with its own token, ADR-0025's
    motivating scenario) would pass heraut check runtime but fail at
    glab release create/upload time. Mirror checkAPIAuth's and
    GitHub's tokenEnvSlice()+hostEnv() composition.

    Roadmap:docs/tasks/roadmap.md -> T88 Co-Authored-By:Claude Fable 5 noreply@anthropic.com

  • (versioning/perenv) Skip pre-release tags in semver-per-env BumpAuto - (938b911) by @bchatard

    tagfmt.ParseVersion's {version} capture is a greedy .+ with no
    pre-release filter, so a tag like dev/1.3.0-rc.1 parses to bare
    "1.3.0-rc.1" unfiltered. Without versionsort.suffix, git can sort that
    tag above dev/1.2.3, making it currentVersion — and BumpVersion's
    strconv.Atoi on the "0-rc.1" patch segment fails, the same "invalid
    patch" mode T92 fixed for plain semver.

    Export semver.IsBareVersion and apply it in perenv.resolveAuto's
    shared tag-filter loop. The loop is shared with calver-per-env, but
    IsBareVersion accepts any 3-part all-integer version and
    calver.BumpFromDate already does its own per-tag skip, so this is a
    no-op there.

    Roadmap:docs/tasks/roadmap.md -> T103 Co-Authored-By:Claude Fable 5 noreply@anthropic.com

  • (versioning/semver) Anchor breaking-change bang to commit type prefix - (f4a8e9e) by @bchatard

    isBreaking matched "!:" anywhere in the subject, so a fix commit whose
    description happens to contain "!: " (e.g. "fix: handle the foo!: token")
    triggered a spurious major bump. Anchor the bang to the conventional-commit
    type/optional-scope prefix instead.

    Also recognize the hyphenated BREAKING-CHANGE: footer as a synonym of
    BREAKING CHANGE:, per Conventional Commits 1.0.

    Roadmap:docs/tasks/roadmap.md -> T91 Co-Authored-By:Claude Fable 5 noreply@anthropic.com

  • (versioning/semver) Skip pre-release tags when resolving current version - (3e4b71a) by @bchatard

    Without versionsort.suffix configured, git's default version:refname tag
    sort orders a pre-release tag (e.g. v1.3.0-rc.1) above its release
    (v1.2.3), so resolveAuto picked the pre-release as the current tag and
    BumpVersion failed parsing its "-rc.1" suffix.

    resolveAuto now walks the sorted tags and picks the first whose bare form
    is a plain MAJOR.MINOR.PATCH (new isBareVersion helper), mirroring the
    CalVer resolver's skip-unparsable-tag pattern. Falls back to
    initial_version if every matching tag is non-conforming. Documented in a
    new "Pre-release tags" subsection of spec 04.

    Also adds T102 (spec 04's bump-determination table doesn't reflect T91's
    anchored "!" / BREAKING-CHANGE: synonym) and T103 (semver-per-env's
    BumpAuto may hit the same pre-release-tag issue via perenv.resolveAuto)
    as follow-up roadmap tasks discovered during this work.

    Roadmap:docs/tasks/roadmap.md -> T92 Co-Authored-By:Claude Fable 5 noreply@anthropic.com

🚜 Refactor

  • (config) Extract shared EffectivePlatforms helper (T105) - (f9ec386) by @bchatard

    internal/app/pipeline.go (buildReleasePipelineConfig), internal/cmd/release.go
    (hasEffectivePlatforms, T89), and internal/app/check.go (RuntimeCheck, T100)
    each independently implemented the same env/root release-platforms merge
    rule. config.EffectivePlatforms is now the single implementation; the cmd
    and app call sites delegate to it.

    Roadmap:docs/tasks/roadmap.md -> T105

  • Hygiene pass — drop T-id comments, dedupe iota, unify case - ([8413f47](https://github.com/adaouat/he...

Read more

v0.31.0

12 Jun 20:34
Immutable release. Only release title and notes can be modified.
v0.31.0
997a6b8

Choose a tag to compare

🚀 Features

  • (app) One heraut check runtime Platforms row per configured entry - (6bdc4b4) by @bchatard

    RuntimeCheck now dispatches one Platforms row per release.platforms
    entry, labeled by the entry's configured name, running each entry's
    full Check() (binary + token + project/repository + API auth). With
    no platforms configured, falls back to a binary-only probe of glab
    and gh. Removes configuredPlatforms/findPlatformCfg, which assumed at
    most one entry per platform type.

    Roadmap:docs/tasks/roadmap.md → T86

  • (config) Require unique platform name, allow self-hosted base_url - (2d6f2f6) by @bchatard

    Adds a required name field to release.platforms entries (unique per
    list scope) and lifts ADR-0020's "self-hosted hosts are not yet
    supported" gate on base_url — both are prerequisites for publishing to
    two instances of the same platform type (ADR-0025).

    Roadmap:docs/tasks/roadmap.md → T83

  • (platforms/github) Support self-hosted instances via GH_HOST - (c113508) by @bchatard

    Name() now returns the configured platform name, ReleaseURL() honors
    base_url, and CreateRelease/UploadAssets/Check inject GH_HOST and
    GH_ENTERPRISE_TOKEN when base_url targets a non-default (GHES) host.
    Actions-token autologin is skipped for self-hosted instances in favor
    of the configured token.

    Roadmap:docs/tasks/roadmap.md → T85

  • (platforms/gitlab) Support self-hosted instances via GITLAB_HOST - (3bfdb06) by @bchatard

    Name() now returns the configured platform name, ReleaseURL() honors
    base_url, and CreateRelease/UploadAssets/Check inject GITLAB_HOST when
    base_url targets a non-default host. CI autologin is skipped for
    self-hosted instances in favor of the configured token.

    Roadmap:docs/tasks/roadmap.md → T84

📚 Documentation

  • (adr) Add ADR-0025, supersede ADR-0020 (multi-instance platforms) - (b3ae621) by @bchatard

    ADR-0025 documents the lifted base_url gate, per-platform CLI host
    targeting (GH_HOST/GITLAB_HOST/GH_ENTERPRISE_TOKEN), the required
    unique name field, and the restructured heraut check runtime
    Platforms section delivered by T83-T86. Spec 05 gains the self-hosted
    / multi-instance subsection and the name field in both platform
    examples.

    Roadmap:docs/tasks/roadmap.md → T87

  • (app) Clarify Platforms section dispatch order in RuntimeCheck - (e47b250) by @bchatard

    The previous comment described the old fixed glab→gh dispatch order,
    which T86 replaced with one row per configured release.platforms entry
    (falling back to the binary-only probe only when none are configured).

  • (plans) Add multi-instance platforms implementation plan - (4f9eb70) by @bchatard

    Implementation plan for T83-T87 (ADR-0025, multi-instance
    same-platform releases), executed via subagent-driven development.

    Roadmap:docs/tasks/roadmap.md → T83-T87

  • Design spec for multi-instance same-platform releases - (2b3e99b) by @bchatard

    Adds a future-ideas entry and design spec covering name-based platform
    disambiguation, lifting the ADR-0020 base_url gate, and per-invocation
    GH_HOST/GITLAB_HOST targeting for self-hosted instances.

🎨 Styling

  • (app) Drop unneeded loop variable copy in check.go - (60b3e9d) by @bchatard

    Go 1.22+ gives each for-range iteration its own variable, so the
    bin := bin copy added by T86 was redundant.

Commit Statistics

  • 9 commit(s) contributed to the release.
  • 0 day(s) passed between the first and last commit.
  • 9 commit(s) parsed as conventional.
  • 0 linked issue(s) detected in commits.

v0.30.2

12 Jun 05:12
Immutable release. Only release title and notes can be modified.
v0.30.2
e04c31c

Choose a tag to compare

🐛 Bug Fixes

  • (deps) Bump forge to v0.16.0 - (56d38f7) by @bchatard

    Pulls in forge's whatsnew rendering fixes: dropped glamour's
    terminal-querying "auto" style (which fell back to raw markdown when
    the terminal didn't answer), added $PAGER support, and fixed a
    double-print bug when the pager exits non-zero.

Commit Statistics

  • 1 commit(s) contributed to the release.
  • 0 day(s) passed between the first and last commit.
  • 1 commit(s) parsed as conventional.
  • 0 linked issue(s) detected in commits.
  • 1 day(s) passed between releases.

v0.30.1

11 Jun 16:39
Immutable release. Only release title and notes can be modified.
v0.30.1
4a33f54

Choose a tag to compare

🎨 Styling

  • Gofmt -s on calver parser_test - (e5ec535) by @bchatard

    Struct-field alignment that gofmt -s wants but golangci-lint (CI) doesn't enforce —
    the lone pre-existing go_fmt failure surfaced by 'hk check --all', a prerequisite for
    adding the hk lint gate to CI.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

⚙️ Miscellaneous Tasks

  • Run the full hk linter set in CI (hadolint, actionlint, typos, …) - (0906de5) by @bchatard

    The reusable ci job only runs golangci-lint; hk's other linters (hadolint,
    actionlint, yamlfmt, typos, pkl, go fmt) were enforced only by the local pre-commit
    hook (staged files, bypassable). Add an hk job running 'hk check --all --check
    --skip-step golangci_lint' so they're enforced server-side. hk's per-step file
    selection scopes each linter — hadolint only touches the Dockerfile, so it runs only
    when relevant without a fragile required-check path filter.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

  • Fix shellcheck findings in release.yml run blocks - (c8cb125) by @bchatard

    The new hk CI job (actionlint -> shellcheck) flagged unquoted variable
    expansions in release.yml. Quote $FRESH_BIN, $GITHUB_ENV, and
    $GITHUB_OUTPUT (SC2086). The imagetools create command intentionally
    relies on word splitting / globbing for multiple -t tags and digest
    files, so suppress SC2046 there with an explanatory comment.

    Co-Authored-By:Claude Sonnet 4.6 noreply@anthropic.com

Commit Statistics

  • 3 commit(s) contributed to the release.
  • 0 day(s) passed between the first and last commit.
  • 3 commit(s) parsed as conventional.
  • 0 linked issue(s) detected in commits.

v0.30.0

11 Jun 13:01
Immutable release. Only release title and notes can be modified.
v0.30.0
551f2a7

Choose a tag to compare

🚀 Features

  • (app) Propagate tickets config onto content drivers - (10410fa) by @bchatard

    withEnvDerivations now carries cfg.Tickets onto the changelog/release-notes driver
    clones (the same clone point as remote_metadata), so the gitcliff generator can
    inject link_parsers. Part of T80.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

  • (config) Add tickets field for issue-tracker links - (770c318) by @bchatard

    Top-level tickets list ([]Ticket{Pattern, URL}) parsed from .heraut.yml, plus the
    programmatic ContentDriver.Tickets carrier the app layer will populate. Part of T79.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

  • (config) Validate tickets (regex, {ticket} url, git-cliff only) - (a159801) by @bchatard

    validateTickets:each pattern compiles as a regex, each url is an absolute http(s)
    URL containing {ticket}, and tickets require the git-cliff generator (the only one
    with a link mechanism). Part of T79. Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

  • (config) Add tickets to schema + sample + fixtures - (0de6706) by @bchatard

    Expose the tickets array in schema.json (pattern + url, both required), document
    it in docs/heraut.sample.yml, and add valid + invalid schema fixtures (the invalid
    one omits the required url). Part of T82.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

  • (generators/gitcliff) Inject ticket link_parsers into effective config - (cc1925d) by @bchatard

    effectiveConfig now chains injectLinkParsers after the heading postprocessor: each
    ticket becomes a git-cliff { pattern, href } entry — pattern wrapped in a capture
    group only when it has none (so {ticket}->$1 is the URL value), appended to any
    existing [git].link_parsers. Part of T80.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

  • (generators/gitcliff) Render ticket links in changelog and release notes - (98f83e1) by @bchatard

    Both print_commit macros append commit.links after the PR segment as
    ( TICKET ). Verified against the real git-cliff: subject and footer (Refs:)
    tickets both render with clean whitespace, location-independent. Part of T81.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

📚 Documentation

  • (plans) Add ticket-linking design spec - (6dee113) by @bchatard

    Approved brainstorming design: first-class .heraut.yml ticket linking via a
    top-level tickets list, injected into git-cliff's link_parsers (location-
    independent — subject/body/footer), rendered in both changelog and release notes.
    git-cliff only; append-only; {ticket} maps to the first capture group (or full
    match) so label vs URL value can differ (e.g. GH-123 → /issues/123).

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

  • (plans) Add ticket-linking implementation plan - (d33f307) by @bchatard

    Seven TDD tasks (config field, validation, link_parsers injection, driver
    propagation, both templates, schema/sample/fixtures, ADR/spec/roadmap) for T79,
    each with failing test, implementation, and commit steps.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

  • (roadmap) Add Phase 15 — ticket linking (T79–T82) - (dfc44c5) by @bchatard

    New phase tracking the ticket-linking feature: config surface + validation (T79),
    link_parsers injection + driver propagation (T80), template rendering (T81), and
    schema/sample/ADR/spec (T82).

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

  • ADR-0024 ticket linking; document tickets; complete T79–T82 - (485c07a) by @bchatard

    Record the link_parsers-over-commit_preprocessors decision (ADR-0024), document the
    tickets config in spec 02, and flip Phase 15 (T79–T82) to done with completion notes.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

Commit Statistics

  • 10 commit(s) contributed to the release.
  • 0 day(s) passed between the first and last commit.
  • 10 commit(s) parsed as conventional.
  • 0 linked issue(s) detected in commits.

v0.29.0

11 Jun 08:25
Immutable release. Only release title and notes can be modified.
v0.29.0
36d1392

Choose a tag to compare

🚀 Features

  • (cmd) Add --build to heraut release for build-id release flows - (280b29d) by @bchatard

    Mirror heraut changelog --build: --build requires --version, the value is
    validated via app.ValidateBuildID, and it is passed to NewResolver, which renders
    {build} into the tag and returns a StaticResolver. The release pipeline consumes
    result.Tag unchanged, so no pipeline/resolver change is needed — the build path
    already existed (deferred from T52). Build-id teams can now run a full release
    (changelog -> tag -> publish) per CI build. release-per-build is allowed freely:
    passing both --version and --build is already a deliberate, scripted opt-in.

    Closes T57.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

🐛 Bug Fixes

  • (generators/gitcliff) Render New Contributors from any platform's remote - (316ce84) by @bchatard

    The embedded release-notes template only read gitlab.contributors, so non-GitLab
    repos never rendered the New Contributors section. Extract a print_contributors
    macro and call it once over the first-time contributors concat'd across all five
    remote namespaces (gitlab/github/gitea/bitbucket/azure_devops). The single call
    over a merged list keeps git-cliff's proven single-block whitespace — verified
    against the real CLI for the empty, single-platform, and multi-platform cases (no
    blank-line regression).

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

📚 Documentation

  • (roadmap) Mark T68 done (checkbox lag; work landed in ADR-0021) - (7061e89) by @bchatard

    T68's decision and PoC were completed and documented in its Done note (the
    context-injection shape resolved in ADR-0021, dependents T69/T71a/T71b already
    done) — only the heading checkbox was never flipped. Flip it. T57 is now the
    single open roadmap task.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

  • (roadmap) Complete T57 (heraut release --build) - (d86c09b) by @bchatard

    Flip T57 to done with a completion note: mirrored changelog --build, no
    pipeline change (resolver already handled build), release-per-build allowed
    freely. Roadmap is now fully resolved — no open tasks.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

  • (specs) Document heraut release --build (T57) - (3e8e37a) by @bchatard

    Flip the {build} support table — heraut release --build is now supported, not
    changelog-only — add the release example, the --build flag to the release command
    reference, and note that release-per-build (one platform release per build) is
    intentional and unguarded.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

🎨 Styling

  • (generators/gitcliff) Drop redundant version heading from release notes - (c977f61) by @bchatard

    Release notes are attached to a GitHub/GitLab release whose header already shows
    the tag/version and date, so the '## [version] - date' line in the body was pure
    duplication. Drop it (the changelog template keeps its heading — that file
    accumulates every release). Also pack the macro definitions (whitespace-only).
    Verified against the real git-cliff: config accepted, contributors render across
    all platforms, no output regression (one leading blank line is git-cliff
    structural with an empty header, and invisible on the rendered release page).

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

⚙️ Miscellaneous Tasks

  • Keep CHANGELOG.md in Docker build context for the whatsnew embed - (acac7b6) by @bchatard

    changelog.go embeds CHANGELOG.md into the binary (//go:embed, 09fe57c) for the
    whatsnew offline fallback, so the Dockerfile's COPY . . + go build needs the file
    present. The .dockerignore '*.md' rule was excluding it, breaking the image build
    with 'pattern CHANGELOG.md: no matching files found'. Add a !CHANGELOG.md
    exception; other .md files stay ignored.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

Commit Statistics

  • 7 commit(s) contributed to the release.
  • 0 day(s) passed between the first and last commit.
  • 7 commit(s) parsed as conventional.
  • 0 linked issue(s) detected in commits.
  • 1 day(s) passed between releases.

v0.28.0

10 Jun 14:12
Immutable release. Only release title and notes can be modified.
v0.28.0
40af989

Choose a tag to compare

[0.28.0] - 2026-06-10

🚀 Features

  • (whatsnew) Embed CHANGELOG.md as the offline fallback - (09fe57c) by @bchatard

    Adds a root package embedding CHANGELOG.md into a string (the embed must live
    at the repo root to reach the file) and passes it to WhatsNewConfig.Changelog,
    so whatsnew renders the bundled changelog when GitHub is unreachable and the
    cache is cold (forge ADR-0012 tier D).

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

💼 Other

  • (deps) Bump forge to v0.15.0 - (93cee93) by @bchatard

    Brings WhatsNewConfig.Changelog (forge ADR-0012 tier D) for the embedded
    changelog offline fallback.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

Commit Statistics

  • 2 commit(s) contributed to the release.
  • 0 day(s) passed between the first and last commit.
  • 2 commit(s) parsed as conventional.
  • 0 linked issue(s) detected in commits.

v0.27.0

10 Jun 13:20
Immutable release. Only release title and notes can be modified.
v0.27.0
4d7e49a

Choose a tag to compare

[0.27.0] - 2026-06-10

🚀 Features

  • (cmd) Add whatsnew command, adopt forge's shared hint wiring - (9457530) by @bchatard

    Registers updatecheck.WhatsNewCommand (heraut whatsnew shows the release-note
    span newer than the running build), and collapses the update-hint PostRun to a
    single updatecheck.Hinter{…}.PostRun() using the shared CacheFile("heraut") —
    dropping the hand-rolled timeout/cache-path block (forge M11/ADR-0012).

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

💼 Other

  • (deps) Bump forge to v0.13.0 - (6a4f278) by @bchatard

    Brings updatecheck.WhatsNewCommand (forge ADR-0012 tier C) for the whatsnew
    wiring, plus the tier A changelog pointer in the upgrade hint.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

  • (deps) Bump forge to v0.14.0 - (b36f93a) by @bchatard

    Brings updatecheck.CacheFile + Hinter.PostRun (forge M11) for the shared
    update-hint wiring, alongside WhatsNewCommand for the whatsnew command.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

Commit Statistics

  • 3 commit(s) contributed to the release.
  • 0 day(s) passed between the first and last commit.
  • 3 commit(s) parsed as conventional.
  • 0 linked issue(s) detected in commits.

v0.26.0

10 Jun 11:57
Immutable release. Only release title and notes can be modified.
v0.26.0
0fe6ae6

Choose a tag to compare

[0.26.0] - 2026-06-10

🚀 Features

  • (app) Propagate remote_metadata policy + report cliff degrade - (a465871) by @bchatard

    withEnvDerivations now carries the top-level remote_metadata policy onto the
    changelog/release-notes drivers so the pipeline generators honour it. CheckCliff
    gains the policy (applied to a driver copy, never mutating the caller's) and
    returns whether it degraded to --offline; heraut check surfaces that in the
    cliff detail line (valid → valid (offline — remote metadata unavailable)).
    Part of T78.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

  • (cmd) Add --offline flag forcing remote_metadata: disabled - (2dffbe0) by @bchatard

    Persistent --offline flag overrides the configured remote_metadata policy to
    disabled for a single run (no remote PR/MR metadata API calls). Wired into
    release, changelog, and the check / check cliff commands via applyOfflineOverride
    after config load. Part of T78.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

  • (config) Add remote_metadata policy field + validation - (b9a467c) by @bchatard

    Top-level remote_metadata governs whether content generators fetch PR/MR
    metadata (author handle, PR number) from the platform API to enrich
    changelog/release-notes: required | optional | disabled, empty resolving to
    optional. Enum-validated. A programmatic ContentDriver.RemoteMetadata field
    carries the effective policy onto each driver for the generator to honour
    (set by the app layer, mirroring HeadingVersionPattern). Part of T78.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

  • (config) Add remote_metadata to schema.json + sample + fixtures - (7aa259f) by @bchatard

    Expose the remote_metadata enum (required | optional | disabled, default
    optional) in schema.json for IDE validation, document it in docs/heraut.sample.yml,
    and add valid + invalid schema fixtures (the invalid one asserts the enum is
    enforced). Keeps the schema/sample/field in sync per the config rules. Part of T78.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

  • (generators/gitcliff) Honor remote_metadata policy via --offline - (e14c020) by @bchatard

    git-cliff fetches PR metadata (and panics on failure) whenever the templates
    reference commit.remote.*. Route Generate and CheckCliff through a policy-aware
    runCliff: 'disabled' always passes --offline; 'required' never does (a remote
    failure stays fatal); 'optional' (default) tries online then retries with
    --offline on any failure, exposing Degraded() so callers can warn. If the
    offline retry also fails the original online error surfaces, so a genuine
    config error still bubbles up. Part of T78.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

  • (pipeline) Surface remote-metadata degrade as a step sub-result - (7c682e1) by @bchatard

    When a generator falls back to --offline because the remote metadata fetch
    failed (remote_metadata: optional), the changelog/release-notes step now carries
    a 'remote metadata unavailable — PR authors/numbers omitted' sub-result, so the
    omission is visible during release/changelog runs. Generators report it via an
    optional Degraded() interface the pipeline type-asserts, keeping the pipeline
    decoupled from the concrete generator. Part of T78.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

📚 Documentation

  • (adr) Add ADR-0023 remote-metadata policy; complete roadmap T78 - (fb22f0a) by @bchatard

    Record the remote_metadata decision (top-level tri-state, default optional,
    backed by git-cliff --offline, retry-on-failure for optional, --offline flag) and
    its reconciliation with ADR-0022. Index it in the ADR README and flip T78 to done
    with a completion note.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

  • (adr) Record why the CLI override is boolean --offline (ADR-0023) - (e93cb06) by @bchatard

    Capture the decision to keep --offline as a boolean escape hatch rather than a
    --remote-metadata mirror of the config key (git-cliff precedent + heraut's
    runtime-flag convention + YAGNI), so it is not re-litigated later.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

  • (roadmap) Add T78 — remote_metadata policy for git-cliff enrichment - (9680617) by @bchatard

    Captures the durable opt-out for git-cliff's remote-metadata fetch: a
    top-level tri-state policy (required | optional | disabled, default optional)
    governing both changelog and release-notes generation, backed by git-cliff's
    --offline flag. The optional default degrades + warns on fetch failure, fixing
    the tokenless-panic residual out of the box. Follows the ci: GITHUB_TOKEN patch
    that authenticates the fetch in CI.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

⚙️ Miscellaneous Tasks

  • Authenticate git-cliff GitHub API calls in release workflow - (cc8f128) by @bchatard

    heraut's changelog/release-notes generation shells out to git-cliff, which
    fetches PR metadata from the GitHub API to populate commit.remote.username and
    commit.remote.pr_number. git-cliff reads GITHUB_TOKEN, not GH_TOKEN (which only
    gh/glab consume), so the Preflight and Release steps were calling the API
    unauthenticated — hitting GitHub's 60/hr shared-IP rate limit and panicking with
    a 403 (exit 101). Export GITHUB_TOKEN to both steps so the calls authenticate
    against the 1000/hr limit.

    Co-Authored-By:Claude Opus 4.8 noreply@anthropic.com

Commit Statistics

  • 10 commit(s) contributed to the release.
  • 0 day(s) passed between the first and last commit.
  • 10 commit(s) parsed as conventional.
  • 0 linked issue(s) detected in commits.

v0.25.1

10 Jun 05:19
Immutable release. Only release title and notes can be modified.
v0.25.1
84c8672

Choose a tag to compare

[0.25.1] - 2026-06-10

🐛 Bug Fixes

💼 Other

  • (deps) Bump forge to v0.11.1 - (82dd26c) by @bchatard

    Tracks the latest forge tag (carries forge's own golang.org/x/sys
    v0.45.0 CVE bump; heraut already pinned x/sys v0.45.0 directly, so no
    effective change there). go.mod/go.sum only.

    Co-Authored-By:Claude Sonnet 4.6 noreply@anthropic.com

🚜 Refactor

  • Align forge/log import alias to forgelog - (14750f4) by @bchatard

    Rename the forge/log alias flog → forgelog so it matches the family's
    forge convention (forgeui, forgeexec) and the alias bifrost uses.
    No behaviour change.

    Co-Authored-By:Claude Sonnet 4.6 noreply@anthropic.com

Commit Statistics

  • 3 commit(s) contributed to the release.
  • 0 day(s) passed between the first and last commit.
  • 3 commit(s) parsed as conventional.
  • 0 linked issue(s) detected in commits.
  • 1 day(s) passed between releases.