Generate formatted release histories from Jira, GitHub, GitLab, YAML, or JSON sources.

CLI utility and Ruby API for generating structured release notes and changelog documents from various issue-tracking platforms or YAML definitions into plaintext drafts (AsciiDoc, Markdown, YAML) and rich-text output (HTML and PDF).

Note
This README serves as the both landing page and documentation for Version 0.1.1.
Important
This repository is for the 0.1.1 version of ReleaseHx. NOT ALL FEATURES are available.

Overview

Generate lightweight drafts and rich-text output for your Release Notes or Changelog documents using simple commands with powerful results!

Example Workflow

Your workflow might look like this example:

  1. Check for issues with missing release notes. Looks for issues marked release_note_needed or similar.

    rhx 2.1.0 --check
    > Missing required release notes:
    > - JIRA-3412: Fix the thing (JoePSmith)
    > - JIRA-3482: Add this cool thing (RaeMDoe)
  2. While you are waiting for Joe and Rae to get their outstanding notes entered into Jira…​ retrieve Jira issues for version 2.1.0. rhx 2.1.0 --yaml

    Note
    You can edit your Release Notes in Markdown or AsciiDoc files, or in YAML files with AsciiDoc or Markdown text formatting. Whatever you prefer.
  3. When Joe and Rae finally post their notes…​ append them to the YAML doc.

    rhx 2.1.0 --append
  4. Generate a Markdown variant to your website source directory.

    rhx 2.1.0 --md
  5. Generate a PDF to a documents archive.

    rhx 2.1.0 --pdf

And you’re ready to publish in HTML and PDF format!

ReleaseHx can accommodate numerous permutations of workflows. It is adaptable by design, but if you are just starting or revamping your ReleaseNotes/Changelog setup, there is a recommended strategy/workflow, as well.

Powerful Potential

Numerous backends enable flexible conversions from any source format to HTML or PDF output.

ReleaseHx can convert data into content through various processes, which you can adapt to your preferred workflow.

API → Markdown/AsciiDoc/YAML → HTML/PDF

OR, use your Markdown/AsciiDoc-based static-site generator (SSG) to perform the final enrichment to HTML!

Features

ReleaseHx is already packed with capabilities.

  • Generate Release Notes and/or Changelogs from your Issues tracker or Git*.

  • Source in Jira, GitHub, GitLab, Git commits*, or our special YAML syntax: RHYML.

  • Readily configurable to use your Issue Management API.

  • Draft in Markdown, AsciiDoc, or YAML.

  • Render to HTML or PDF with Asciidoctor, Pandoc, and other converters.

  • Use Docker to run ReleaseHx in any environment.

  • Customize output with Liquid templates.

  • Configure output without touching templates using advanced settings (low-code).

  • Ensure qualifying issues all have release notes.

  • Link-back from notes or Changelog entries to issues and Git commits.

  • Use Git to track changes in your release history documents.

  • Auto-update drafts with late-breaking release notes (RHYML only).

  • Group and sort entries by issue type, subject component, or various tags.

  • Invoke labels/tags such as breaking, deprecation, experimental, highlight, and internal.

  • Use Issue labels or checkboxes to indicate Changelog inclusion or Release Note requirement.

  • Use as a CLI or as a Ruby API.

  • Run a local MCP server (rhx-mcp) so AI agents can better aid in using ReleaseHx.

  • Extend by configuring a custom API client and issue mapping.

  • Convert changelog summaries to past-tense with the pasterize filter.

  • Full support for Jira v3 API with ADF conversion to Markdown/AsciiDoc.

* Sourcing issues in Git commits is not yet available but is planned for a future (pre-1.0) version.

You can begin editing in YAML and update the file without losing changes, then generate a final draft in Markdown or AsciiDoc.

rhx 2.1.0 --yml
rhx 2.1.0 --append
rhx 2.1.0 --adoc

The second line adds any late-arriving issues from the cloud. The third line uses that .yml file to generate a .adoc file, but you can go directly from YAML to HTML or PDF as well as drafting in Markdown.

Getting Started

To use ReleaseHx in your own projects, you will need either Ruby or Docker. Use either the rhx CLI utility or the ReleaseHx Ruby API.

The only other prerequisite is possibly Git, if wish to draw any content/metadata from Git commits.

Non-Ruby Users Setup

If you are not already a Ruby user, the rhx utility may be best used from our Docker image.

Note
You will need Docker Desktop installed directly on MacOS or with WSL2 backend on Windows. For Linux, use the Docker Engine install docs if you’re not already using Docker.

With Docker installed and running…​

  1. Pull the Docker image.

    docker pull docopslab/releasehx
  2. Run the rhx command.

    docker run -it --rm --user $(id -u):$(id -g) -v $(pwd):/workdir docopslab/releasehx rhx

    This mounts your local directory to be writeable by the Docker container. Everything after rhx accepts the standard arguments and options of the ReleaseHx utility.

Tip

Optionally alias the base Docker command.

alias rhx='docker run -it --rm --user $(id -u):$(id -g) -v $(pwd):/workdir docopslab/releasehx rhx'

Try the demo configs and data to get a feel for how ReleaseHx works.

Ruby Users Setup

ReleaseHx can be installed as a Ruby gem, for either CLI or API usage.

Option 1: System-wide installation
gem install releasehx
Option 2: Project installation
  1. Add the following line to your Gemfile:

    gem 'releasehx'
  2. Install the gem.

    bundle install
  3. Use bundle exec rhx to execute.

MCP Server Setup (Optional)

ReleaseHx provides an experimental interface for model context protocol (MCP) service over STDIO (local “server”). This should save considerably on the resources required for your preferred LLM client/agent system to learn and use ReleaseHx.

Note
This experimental MCP server focuses on aiding application configuration of your ReleaseHx instance. It does not provide assistance for command-line actions or other configurations such as RHYML mapping.

For your LLM client (such as Copilot, Claude Code, Codex, Cursor, etc) to interact with this service, it must be configured using a general MCP syntax. This data is usually added to a mcp.json file or another object.

Generic MCP config (global gem install)
{
  "servers": {
    "releasehx": {
      "command": "rhx-mcp"
    }
  }
}
Generic MCP config (Docker)

Use the Docker image for maximum compatibility across environments. This is the recommended approach for most users.

{
  "servers": {
    "releasehx": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "docopslab/releasehx:latest", "rhx-mcp"]
    }
  }
}
VS Code MCP configuration (Docker)

Create or update ~/.config/Code/User/mcp.json (Linux/Mac) or %APPDATA%\Code\User\mcp.json (Windows).

{
  "servers": {
    "releasehx": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "docopslab/releasehx:latest", "rhx-mcp"]
    }
  }
}
VS Code MCP configuration (global gem install)

If you have ReleaseHx installed globally (gem install releasehx), you can use this simpler configuration:

{
  "servers": {
    "releasehx": {
      "command": "rhx-mcp"
    }
  }
}
Local repo MCP config (Bundler + cwd)
{
  "servers": {
    "releasehx-dev": {
      "command": "bundle",
      "args": ["exec", "rhx-mcp"],
      "cwd": "/path/to/releasehx"
    }
  }
}
Note

If your MCP client does not honor cwd, bundle exec rhx-mcp will fail with "Could not locate Gemfile". Install the gem globally (gem install releasehx) and use command: rhx-mcp.

Configuration Basics

Once installed, you will need to configure ReleaseHx to connect to your issue-management service (IMS) and to define how you want to organize your release history output.

In fact, ReleaseHx has three different forms of “configuration”: the application config, the API-client config, and the issue-mapping config.

application config

The main, central settings, split into nested groups like api, sources, tags, modes, rhyml. By default, these are set in the file at ./.releasehx.yml in your application repo. See the Application Configuration Reference for complete details on available properties.

API-client config

This YAML file enables custom configurations of unsupported issue-management system APIs. See Custom REST API Client Configuration for details.

Note
To use an alternate config file, provide a path at runtime using --config PATH/TO/FILE. Ex: rhx 1.1.0 --config confs/releasehx.yml.

If you are ready to set up your remote issue management system’s API, skip to Establishing Issues Source.

Otherwise, the ReleaseHX Demo may be a good way to understand how everything comes together.

MCP Server Usage (AI Config Assistance)

The rhx-mcp command starts a local MCP server that exposes ReleaseHx configuration resources for AI clients over STDIO. MCP is still new, so use the setup guidance below.

Resources
releasehx://agent/guide

Short guide for agent usage and navigation.

releasehx://config/sample

Sample config tree with defaults and comments.

releasehx://config/schema

Authoritative CFGYML definition.

releasehx://config/reference.json

JSON reference document for tooling.

releasehx://config/reference.adoc

AsciiDoc reference document.

Tool
config.reference.get

Accepts a JSON Pointer (example: /properties/origin) and returns the reference entry.

Choose how to run the MCP server:

Docker (recommended)
docker run -i --rm docopslab/releasehx:latest rhx-mcp
Bundled gem
bundle exec rhx-mcp
Global gem
rhx-mcp
MCP Troubleshooting

If your MCP server isn’t working in VS Code or Copilot:

  1. Verify Docker image exists: Run docker images | grep releasehx to confirm the image is available.

  2. Test MCP server manually: Run the following to verify the server responds:

    echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | docker run -i --rm docopslab/releasehx:latest rhx-mcp

    You should see a JSON response with "serverInfo":{"name":"releasehx-mcp"}

  3. Check VS Code MCP config: Ensure ~/.config/Code/User/mcp.json exists and uses the correct command format (see examples above).

  4. Restart VS Code: After changing mcp.json, restart VS Code completely for changes to take effect.

  5. Check VS Code logs: Open Output panel (Ctrl+Shift+U) and look for errors related to MCP or the releasehx server.

Tip

Ask your agent to read releasehx://agent/guide first. Then have it consult releasehx://config/sample as a table of contents before using config.reference.get.

Demo Repo Setup

If you want to play around with ReleaseHx before connecting it to your own Issues source via API, use the DocOps/releasehx-demo repository as instructed in this section.

Alternately, skip to Establishing Issues Source to begin configuring your own project/environment.

Tip
We recommend performing the demo steps to get a feel for the project.
Important
This demo assumes you have either installed ReleaseHx with gem install releasehx or you have aliased the docker run command prefix to rhx, as instructed in Non-Ruby Users Setup.
  1. Clone the demo repository.

    git clone git@github.com:DocOps/releasehx-demo.git
  2. Change to the new repo directory.

    cd releasehx-demo
  3. Install ReleaseHx and dependencies.

    bundle install
  4. Run the rhx command with special arguments. For example:

    bundle exec rhx 1.1.0 --config configs/jira-customfield.yml --api-data _payloads/jira-customfield-note-1.1.0.json --md demo-1.1.0.md

    Prepend bundle exec if using the local project Ruby installation.

In this example, the jira-customfield-note-1.1.0.json file fills in for the version 1.1.0 issue tickets in a Jira project, drafting them as a local Markdown file.

The demo repo contains several JSON files that simulate the data returned by the Jira, GitHub, and GitLab APIs.

Table 1. Demo data versions in _payloads/ directory
File path Note field Tags source

jira-customfield-note-1.1.0.json

custom field

labels

jira-description-note-1.1.0.json

description field

labels

github-1.0.0-issues.json

description field

labels

github-checkbox-tags-1.1.0.json

description field

checkboxes

github-label-tags-1.1.0.json

description field

labels

github-live-actual.json

description field

labels

gitlab-checkbox-tags-1.1.0.json

description field

checkboxes

gitlab-label-tags-1.1.0.json

description field

labels

generic-1.1.1.json

description field

labels

generic-1.1.2.json

description field

labels

generic-1.2.0.json

description field

labels

The demo repository also comes with a number of configuration arrangements, which you may switch to or freely edit.

Table 2. Demo Configurations in configs/

jira-customfield.yml

Release Notes and Changelog, default sort

jira-description.yml

Uses description field instead of custom field for release notes

jira-customfield-resorted.yml

Same content as jira-customfield.yml, differently sorted

jira-customfield-changelog.yml

Changelog only

jira-customfield-heavy.yml

Feature-rich configuration with extensive customization

github-basic.yml

Release Notes and Changelog, default sort

github-label-tags.yml

GitHub configuration using issue labels for categorization

gitlab-basic.yml

Release Notes and Changelog, default sort

gitlab-label-tags.yml

GitLab configuration using issue labels for categorization

kitchen-sink.yml

Fully loaded configuration demonstrating all available features

Try the following series of commands and steps to see ReleaseHx in action.

Note

These commands assume global installation or an aliased Docker run command. They effectively run after alias assignment like:

  1. Check for issues missing release notes.

    rhx 1.1.0 --config configs/jira-customfield.yml --api-data _payloads/jira-customfield-note-1.1.0.json --check

    Out of the box, there are two issues in the jira-customfield-note-1.1.0.json file that are marked release_note_needed yet have no release note filled out.

  2. Generate a YAML draft.

    rhx 1.1.0 --config configs/jira-customfield.yml --api-data _payloads/jira-customfield-note-1.1.0.json --yaml
  3. Edit the YAML draft in any way, then save.

  4. Add release notes to the two issues that were missing them in _payloads/jira-customfield-note-1.1.0.json.

  5. Update the YAML draft with the new issues.

    rhx 1.1.0 --config configs/jira-customfield.yml --api-data _payloads/jira-customfield-note-1.1.0.json --append
  6. Generate a Markdown draft.

    rhx 1.1.0 --config configs/jira-customfield.yml --api-data _payloads/jira-customfield-note-1.1.0.json --md
  7. Edit the Markdown draft in any way.

  8. Generate HTML and PDF output.

    rhx 1.1.0 --config configs/jira-customfield.yml --api-data _payloads/jira-customfield-note-1.1.0.json --html --pdf

For more on the demo repo, visit its README at https://github.com/DocOps/releasehx-demo.

Custom Configuration

Your own application will require at least some customization. Once configured, the commands you use day-to-day, or release-to-release, will become relatively simple.

Tip

If you use an LLM client to code, consider having it engage with ReleaseHx’s built-in MCP service.

If any of the demo configs seems like the right arrangement for you, copy it to your project directory and modify it to further suit your needs.

Example — copy a demo config and rename it to default
cp releasehx-demo/configs/github-basic.yml ./.releasehx.yml

See the Application Configuration Reference for an annotated list of available settings.

Recommended Release History Strategy

If you came here without a strong opinion about how to approach managing and publishing a Release History, read our Recommended Strategy for Release Documentation.

If that’s tl;dr, here are some key points:

Recommended output
  • Publish a unified document called something like Release History, with entries for each sequential release of your product.

  • Publish a Changelog or Change Log containing summaries for all user-facing product changes.

  • Publish a Release Notes section containing an entry for any user-facing product change that requires explanation or deserves special highlighting.

Manage issues like so
  • Use the summary/title field of your issue-management system as the draft Changelog entry.

  • Use a custom field (Jira) or the issue body to designate and draft a release note.

  • Use labels in your issue-management system to “tag” issues as belonging in the Changelog or needing a release note draft.

  • Use rhx <v.r.sn> --check to ensure all issues with a release note requirement have a release note.

Use these procedures for each version
  • Generate and edit a YAML draft of your Release History until all release notes are drafted.

  • Generate a final draft in the format you use for the rest of your docs.

  • Publish your Release History to your website or other distribution channels.

For a more-thorough breakdown, see Recommended Strategy for Release Documentation.

ReleaseHx is flexible enough to conform to nearly any series of steps you may already be following. This is merely the recommended approach.

Establishing Issues Source

ReleaseHx is source agnostic. Your release history can start in any of the following sources:

For each instance of ReleaseHx, you will need to configure one source or combination of sources from which to derive Changelog and Release Note content and metadata.

The three cloud services (Jira, GitHub, GitLab) are configured similarly.

Example API configuration in ./.releasehx.yml
api:
  from: jira
  href: https://jira.example.com/rest/api/2
Note
If you wish to configure an API other than Jira, GitHub, or GitLab, see Custom API.

REST API Authentication

ReleaseHx uses platform-specific environment variables for API authentication. Set the appropriate variables for your platform:

GitHub Authentication
export GITHUB_TOKEN="ghp_your_personal_access_token"
Creating a GitHub Token
  1. Go to GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)

  2. Click "Generate new token (classic)"

  3. Select scopes: repo (required), read:org (optional but recommended)

  4. Copy and set the token as shown above

GitLab Authentication
export GITLAB_TOKEN="glpat-your_personal_access_token"
Creating a GitLab Token
  1. Go to GitLab → User Settings → Access Tokens

  2. Create token with read_api scope

  3. Copy and set the token as shown above

Jira Authentication
export Jira_USERNAME="your.email@company.com"
export Jira_API_TOKEN="your_api_token"

Note the capitalization: Jira_USERNAME and Jira_API_TOKEN (not JIRA_*).

Creating a Jira API Token
  1. Go to https://id.atlassian.com/manage-profile/security/api-tokens

  2. Click "Create API token"

  3. Use your Atlassian account email as Jira_USERNAME

  4. Copy the token and set as Jira_API_TOKEN

Making Environment Variables Permanent
Tip

To make environment variables permanent, add them to your shell profile:

echo 'export GITHUB_TOKEN=ghp_your_token' >> ~/.zshrc
source ~/.zshrc
Testing API Authentication

Test your API setup using the authentication test suite:

ruby specs/tests/api-auth-test.rb

This validates that your tokens work and can fetch issues from the configured repositories/projects.

Security Considerations
Important
  • Never commit API tokens to version control

  • Use tokens with minimal required permissions

  • Rotate tokens regularly

  • Consider using separate tokens for testing vs. production

For detailed API setup instructions and troubleshooting, see API Integration Setup Guide.

Advanced Environment Variable Configuration

ReleaseHx uses a layered approach to environment variable handling that provides flexibility for both simple setups and advanced configurations:

  1. App Configuration Layer (config.origin.auth.*)

  2. Standard Environment Variables (RELEASEHX_API_*)

  3. Service-specific Environment Variables (GITHUB_TOKEN, GITLAB_TOKEN, etc.)

  4. Default Values (in API client definitions)

    Standard ReleaseHx variables

    ReleaseHx defines these standard environment variable names as defaults:

    export RELEASEHX_API_KEY="your_api_token"        # API key/token
    export RELEASEHX_API_USER="your_username"        # Username (for Jira)
    export RELEASEHX_API_ORG="your_organization"     # Organization
    Configuration override

    You can override which environment variables to use in your app configuration:

    api:
      from: github
      auth:
        key_env: GITHUB_TOKEN      # Use GitHub-specific variable instead
    Template Variable Access

    API client templates access environment variables using this pattern:

    # Primary: Use configured environment variable name
    {{ env[origin.auth.key_env] }}
    
    # Fallback: Use service-specific environment variable
    {{ env[origin.auth.key_env] | default: env.GITHUB_TOKEN }}

This layered approach ensures compatibility with both standardized ReleaseHx environment variables and existing service-specific naming conventions.

Jira Issues

ReleaseHx can connect to the Jira REST API to fetch issues that match the release version.

The Issue summary field is used to draft the Changelog/title, and a custom field called release_note is used for the Release note.

Tip
Alternatively, configure your custom field with [conf_ppty_conversions_note_custom_field].

In Jira, what ReleaseHx calls “tags” can be assigned using either Jira labels or checkbox custom fields.

ADF (Atlassian Document Format) Support

ReleaseHx provides full support for Jira’s ADF format used in Jira Cloud API.

Issue descriptions and custom fields return rich text content in ADF (JSON format). ReleaseHx automatically detects ADF and converts it to Markdown, which can then be further converted to AsciiDoc, HTML, or PDF.

Supported ADF Elements
  • Text formatting (bold, italic, code, links, strikethrough)

  • Paragraphs and headings (headings excluded from release notes by default)

  • Lists (bullet lists, ordered lists, task lists, including nested lists)

  • Code blocks with language syntax

  • Blockquotes

  • Panels (converted to AsciiDoc admonitions: NOTE, TIP, WARNING, CAUTION)

  • Tables (converted to AsciiDoc/Markdown tables)

  • Hard breaks and horizontal rules

Configuration for ADF
Configure note extraction
origin:
  source: jira

sources:
  note_heading: "Release Note"  # For description-based extraction
  # OR
  note_custom_field: customfield_10039  # For custom field-based

For description-based release notes, use sources.note_heading to specify the heading that marks the release note section (e.g., "Release Note", "Draft Release Note"). The converter will extract everything after that heading until the next same-level heading.

For custom field-based release notes, the entire ADF content in the custom field is converted to Markdown. No heading extraction is performed.

See releasehx-demo repository for working examples with ADF payloads and configurations.

GitHub Issues

ReleaseHx can connect to the GitHub Issues API to fetch issues from the release version.

The issue title field is used to draft the Changelog/title, and any text in the body that follows text like # Release Note is used for the Release note.

In GitHub, what ReleaseHx calls “tags” can be assigned using labels or checkboxes embedded after the Release Note text.

GitLab Issues

ReleaseHx can connect to the GitLab Issues API to fetch issues from the release version.

The issue title field is used to draft the Changelog/title, and any text in the body that follows text like # Release Note is used for the Release note.

In GitLab, what ReleaseHx calls “tags” can be assigned using labels or checkboxes embedded after the Release Note text.

Custom API

ReleaseHx is extensible. While it officially supports Jira, GitHub, and GitLab, you can configure it to connect to any issue-tracking system with a REST API.

Use the application config file to designate an API endpoint and any required authentication. Then provide a mapping file at _mappings/<api_from_name>.yml (or the path configured at [conf_ppty_paths_mappings_dir]) to define the data conversion to RHYML.

RHYML

Use a locally stored YAML file as the source of your Release History and Changelog content. This is essentially the same document that is drafted from a REST API source by the --yaml flag for the rhx command.

Note
RHYML is referred to as an API source throughout most ReleaseHx documentation, even though it is not a remote/HTTP API.

All issues associated with a given release are nested together under a work: property without further hierarchy. Since the entries are data, they can be organized here however you wish, then re-sorted upon generating a Markdown or AsciiDoc draft, or going directly to PDF or HTML.

The advantage of this method is working without an API. Contributors can simply add their notes to a unified file via Git, and that file can be edited in place.

The RHYML content can be connected to Issues and Git commits, but only tangentially. The summary and note content needs to be listed in the YAML document. Links back to the source issue or commit are possible but optional.

Usage

ReleaseHx can either be used as a command-line tool or as a Ruby library. In both cases it can be powerfully configured with regard to its source matter and its output formats.

We will first look at what ReleaseHx can do, then we will explore how to make ReleaseHx achieve these goals.

Terminology

ReleaseHx settles on some “terms of art” to describe its various components and operations. Let’s examine these in order to reduce confusion.

Text Transformation Terms

draft/drafting

The process of creating a file in lightweight markup format, such as AsciiDoc, Markdown, or YAMLL, which is intended to be manually edited by the user. Drafting operations happen to use templates to render output, but we use the term draft whenever the output format is lightweight markup intended for manual editing.

enrich/enrichment

These terms describe the process of turning data or a draft into a rich-text output format, such as HTML or PDF.

Some utilities consider this “rendering”, but render is a term hard-coded into Liquid and Tilt operations, so we use it to describe the act of generating text with a templating engine. Likewise, the term “convert” is integral to Asciidoctor and Pandoc operations, and we don’t want to confuse them.

render/rendering

The final step in converting a template (such as Liquid and ERB) into its target format (such as Markdown, AsciiDoc, or HTML). Render operations transform textual content but do not necessarily change formats. The focus is on the process, not the output.

In ReleaseHx, you will see this mostly in the context of templated configuration fields and the like, even though drafting operations all technically involve rendering.

convert/conversion

Generally the transformation from one file format to another. We reserve these terms for specific use with respect to third-party tools such as Asciidoctor and Pandoc. Converters read standardized markup to produce a wide variety of outputs. This typically means converting Markdown or AsciiDoc to HTML or PDF, but it is also used to refer to transforming Markdown to AsciiDoc and other such operations.

Issues, Changes, Versions, and Releases

We use the term issues to describe the tasks tracked by your cloud-based issue-management system (IMS), such as Jira or GitHub Issues.

A change is the ReleaseHx term for the report that something is changed in the subject product.

ReleaseHx uses issue to refer to the state in the source/API, and change to refer to the record of a product change in RHYML — the Release History YAML-based Modeling Language. Issues get turned into changes, a subtle but important difference.

Likewise, version and release are somewhat interchangeable. Version is the associative reference, typically the way software changes are identified in Git (branch), GitHub Issues (milestone) or Jira (fixVersion).

Whereas release is more of the concept of a revision of the subject product, and it is represented by a property in RHYML listed in an Array called releases.

Typically, ReleaseHx refers to a release as the subject of a “Release History”, and version or version code is the way a release is identified.

A code is the literal string used to identify a version or release. In RHYML, code is the property of a release that identifies the version.

API and Source Disambiguation

REST API

A remote, HTTP-based service, in our case used as the source for issue data. In certain contexts, this is shorthanded as simply API.

ReleaseHx API

The Ruby library that provides the ReleaseHx functionality for downstream Ruby applications, including the rhx CLI (command-line interface).

source

In ReleaseHx parlance, this is the means, location, and format of the data that will be used to generate a Release History. Typically a REST API, this could also be a local YAML file or a Git repository.

API client

A local utility or component that is able to connect to a REST API and retrieve data from it.

Output Strategy

You can output ReleaseHx-generated histories as HTML or PDF, each with styling capabilities.

Other options include which history types to output: Changelog, Release Notes, or hybrid. If outputting both sequentially, in which order, and what exactly to include in each resource.

Note
If all you ever want to report is a 1-line summary of changes, you just need a Changelog.

Some logic rules that may help you decide:

Upstream/Source rules
  1. Any issue with a Release Note entry will also be included in the Changelog.

  2. For issues with no Release Note entry, a changelog label or checkbox is needed for inclusion.

Output rules/policies
  1. Changelog entries will link to any corresponding release note.

  2. Changelogs and Release Notes sections may be organized and ordered distinctly.

  3. The entries within each section (Changelog or Release Notes) may be arranged and sorted according to different rules.

Output Configuration

For designating what to output, the following blocks or properties in the config file are relevant:

history

This block defines the overall document and establishes defaults that apply to notes and changelog sections.

notes

This block defines the Release Notes output.

changelog

This block defines the Changelog output.

Output Templating

Place templates in the directory established in paths.templates_dir in the config (defaults to ./_templates).

Templates replace their namesakes built into the ReleaseHx application or API.

By default, ReleaseHx expects templates to be formatted in Liquid, but it uses the Jekyll-enhanced Liquid 4. See [templating] for details.

Sourcing Strategy

Where will your release history content come from, and in what format(s) will you edit it?

Issue-tracking Source

If your team uses a supported issue-management system (Jira, GitHub Issues, or GitLab Issues), you will almost certainly wish to integrate that platform.

Additionally, assuming your team uses Git, you may wish to derive content from Git commits. This is only the case if your commit messages are suited to including drafts of release notes or changelog entries, which is fairly rare.

Generally, you will derive change summaries, notes, and metadata from your IMS, but hybrid sourcing (with Git) is readily configurable. Since you operate ReleaseHx in your product repository, it uses Git directly on your system rather than relying on your cloud-hosted Git service.

Local Flat-file Source

Once the relevant “issues” have been derived from your API or Git, they become “changes” in ReleaseHx terminology, and they are held as a data object in RHYML format.

At this point, these changes can be converted to YAML, Markdown, or AsciiDoc so you can tinker with them. This process is called “drafting” — it compiles your changes into one document.

The recommended procedure is to use YAML at this phase. Only the YAML format maintains the changes as data and as a single source of truth. If you make a change in the RHYML/YAML document, you can still readily convert to Markdown or AsciiDoc at any point.

Edit-at-source method

However, if you are confident in the overall shape of your issues at the source, drafting directly to Markdown or AsciiDoc, or even converting directly to HTML or PDF, are available options.

Indeed, if you wish to do all of your editing in the IMS interface, this is the way to go. You can generate Markdown or HTML, review, and make further changes to the IMS issues, then re-fetch and generate anew.

Recommended Strategy for Release Documentation

We stand behind the following design principles, but ReleaseHx can enable all this and more.

We highly recommend the sites keep a changelog and Common Changelog for guidance.

For guidance on Release Notes authoring, check out ReleasePad’s “Complete Guide” and ProdPad’s “How-to” article, and this Digital.gov essay.

Publish a unified document called something like Release History, with entries for each sequential release of your product.

The constituent documents, Changelog and Release Notes, are both part of the Release History. The recommended order is Changelog first, Release Notes second, with links from applicable Changelog entries to corresponding Release Notes.

The hybrid strategy would basically be an annotated Changelog, where every designated summary is listed with relevant metadata and a release note, when available.

Publish a Changelog or Change Log containing summaries for all user-facing product changes.

Any and all changes that affect users must be listed here.

A separate, more complete changelog can be published for developers, with issues marked internal also displayed, possibly annotated as such. Using rhx <v.r.sn> --md --internal will include internal issues in the (Markdown) draft.

Publish a Release Notes section containing an entry for any user-facing product change that requires explanation or deserves special highlighting.

The general rule of thumb is that any change that is not obvious from its summary should have a release note.

Release notes can be fairly involved, including short bulleted lists or tables. Anything longer than a few sentences or a short list or table should link to documentation or a release appendix.

Use the summary/title field of your issue-management system as the draft Changelog entry.

Alternatively, use the first line of Git commits or the release-note body as the Changelog entry draft.

If original entries are in present tense or imperative, you can use the [conf_ppty_rhyml_pasterize_summ] property to convert verbs to past tense.

Use a custom field (Jira) or the issue body to designate and draft a release note.

A distinct field is optimal, but on any platform you can demarcate release-note content with a comment like <!-- release note --> or a heading like ## Release note.

Use labels in your issue-management system to “tag” issues as belonging in the Changelog or needing a release note draft.

Jira supports custom checkboxes, and GitHub/GitLab enable Markdown checboxes, all of which ReleaseHx can scan.

Also mark issues with tags like breaking, deprecation, experimental, highlight, and internal.

Use rhx <v.r.sn> --check to ensure all issues with a release note requirement have a release note.

As long as you have marked relevant issues with the release_note_needed tag, you can use the --check option to ensure all issues with that tag have a release note.

The exact tag is configurable at [conf_ppty_tags_release_note_needed].

Generate and edit a YAML draft of your Release History until all release notes are drafted.

This means generating an RHYML document and editing it in place if release notes are still streaming in from the IMS. Use --append to integrate last-minute release notes before generating a final draft.

Generate a final draft in the format you use for the rest of your docs.

When all the release notes have been added, generate a final draft in your preferred lightweight markup format. This is the best place to perform a final once-over and see the content more or less as it will be published.

Generate rich-text drafts as needed. These are easy to overwrite.

Publish your Release History to your website or other distribution channels.

ReleaseHx makes it possible to generate full web pages, but you probably want to situate the content in your static-site generator.

If you wish to edit in one markup format (Markdown or AsciiDoc) but your SSG expects the other format, you can use the flags --html --no-wrap --frontmatter to generate the innards of a page, which most SSGs can publish wrapped in an HTML layout.

These recommendations are of course flexible, but they largely reflect the default setup for a minimally configured ReleaseHx instance. The more your structure and policies deviate from these basic tenets, the more configuration you will need to do.

But ReleaseHx can probably handle your customizations.

CI/CD Strategy Caveats

If your team works in a continuous-deployment environment, you may wish to maintain one ongoing Release History.

To do so, modify your API request template with some logical filter, and always use the --append option, drafting to YAML.

Continuous deployment environments will likely get better treatment in this application prior to the 1.0 release. I just don’t have enough experience with them to predict the optimal workflow.

Note
DocOps Labs' YAML-extension framework (SGYML) will support serializing large Arrays like one might have for an ongoing changelog.

The rhx Utility

For usage outside (or within) a Ruby development environment, ReleaseHx provides the rhx command-line tool.

Help screen
Usage: rhx VERSION|FILE [options]

Options:
  --md [PATH]            Draft to Markdown
  --adoc, --ad [PATH]    Draft to AsciiDoc
  --yaml, --yml [PATH]   Draft to YAML
  --html [PATH]          Enrich to HTML
  --pdf [PATH]           Enrich to PDF
  --output-dir PATH      Establish base target path for generated files
  --api-data PATH        Ingest from a JSON file instead of REST response

  --config PATH          Config location (default: ././.releasehx.yml)
  --mapping PATH         Alternate API mapping location
  --payload PATH         Store payload as JSON file at PATH or default
  --fetch                Refresh data from source
  --append               Add any new issues to the end of local YAML source
  --over, --force        Overwrite any existing files without prompting
  --check, --scan        Find issues with missing release note
  --empty, -e [RULE]     Set/reverse policy on issues "awaiting notes"
  --internal             Include issues marked internal or likewise
  --[no-]wrap            Enrich HTML with/out head and body tags
  --[no-]frontmatter     Enrich or draft with/out frontmatter

  --manpage, --man       Show the full manpage documentation
  --verbose              Express each step to console
  --debug                Express each step and show inferred states
  --debug-dump           Complete debugging with raw data
  --quiet                Suppress all output, including warnings
  --version              Display the ReleaseHx version code

See Full CLI Options Reference for detailed descriptions of each option.

Potential Workflows

ReleaseHx enables several workflow combinations for drafting and enriching release histories.

API → Markdown
API → Markdown → HTML
API → Markdown → PDF
API → AsciiDoc
API → AsciiDoc → HTML
API → AsciiDoc → PDF
API → YAML     → HTML
API → YAML     → AsciiDoc → HTML
API → YAML     → AsciiDoc → PDF
API → YAML     → Markdown → HTML
API → YAML     → Markdown → PDF

The API element of the above workflows could be a RHYML file, in which case the API → YAML conversions are unnecessary, as the YAML step in those workflows is a proper RHYML document already.

Why RHYML drafts?

Some reasons you might wish to use RHYML (YAML) drafts as an interim state:

If you expect late-arriving issues, but you want to get started copy editing the ones that exist.

Going directly from YAML to HTML gives more control over the final output, as Markdown and even AsciiDoc are quite limited in the semantic HTML they can produce.

You may even come to prefer editing serialized short content in YAML, as I have.

Most of the workflow cases can be executed using fairly straightforward command combinations.

Take this API → Markdown → HTML/PDF workflow for instance:

  1. Ensure all release notes are added in the IMS source.

    rhx 2.1.0 --check
  2. Create a Markdown draft from API data.

    rhx 2.1.0 --md
  3. Edit and save the Markdown draft.

  4. Enrich HTML and PDF files from the Markdown draft.

    rhx 2.1.0 --html --pdf

But for cases where you wish to draft/edit in YAML and then in Markdown or AsciiDoc, such as API → YAML → AsciiDoc → HTML/PDF, the following series of steps is exemplary:

  1. Create a YAML draft from API data.

    rhx 2.1.0 --yaml
  2. Edit and save the YAML draft.

  3. Add any newly annotated issues to the end of the YAML draft.

    rhx 2.1.0 --append
  4. Create an AsciiDoc draft from the YAML draft.

    rhx 2.1.0 --adoc
    Note
    ReleaseHx looks for 2.1.0.yml and creates an AsciiDoc draft like 2.1.0.adoc.
  5. Edit that draft as AsciiDoc and save.

  6. Enrich HTML and PDF from the AsciiDoc draft.

    rhx 2.1.0 --html --pdf
    Note
    ReleaseHx finds both 2.1.0.yml and 2.1.0.adoc, choosing the latter.

It is also possible to source directly in RHYML files and draft to Markdown or AsciiDoc or else directly to HTML/PDF.

CLI Sourcing Priority

Certain CLI arguments and options will take precedence over others, especially in determining what sources are actively used during a given operation.

ReleaseHx determines the data source using the following priority order, where higher priority options override lower priority ones:

Table 3. Source Determination Priority (Highest to Lowest)
Priority Source Type How Determined

1

Local YAML file

File path argument ends with .yml or .yaml

2

JSON data file

--api-data PATH option provided

3

REST API

Configuration origin.source set to github, gitlab, or jira

4

Default API

Configuration origin.source defaults to json (requires --api-data)

Source Override Examples
Uses configured API (from config)
rhx 1.2.0 --md
Overrides to use JSON file instead
rhx 1.2.0 --api-data issues.json --md
Overrides to use YAML file instead
rhx _drafts/1.2.0.yml --md
File extension determines source type directly
rhx my-issues.yml --md
API data option forces JSON source
rhx 1.2.0 --api-data cached-issues.json --md
Source Determination Logic

The source determination follows this logic in CLI#determine_payload_type:

  1. File Extension Check: If the identifier (first argument) ends with .yml or .yaml, use YAML source.

  2. CLI Option Check: If --api-data option is provided, use JSON source.

  3. Default to API: Otherwise, use the REST API source (determined by configuration).

This allows users to override the configured default source at runtime while maintaining predictable behavior based on file extensions.

Full CLI Options Reference

The following options are available for the releasehx/rhx commands.

--adoc, --ad [PATH]

Draft to AsciiDoc. Outputs to <drafts_dir>/<file_template> or <PATH>.

Where <drafts_dir> is the value of paths.drafts_dir in the config, and <template> is the value of templates.drafts_filename in the config.

--api-data PATH

Ingest from a JSON file instead of REST response. Point to any local JSON source file that is formatted like a response payload for your configured API (see [conf_ppty_origin_source]); this overrides the normal REST request even if --fetch is argued (though a warning will appear if you pass both options).

--append

Add any new issues to the end of local YAML source.

When drafting in YAML, adds new issues to the end of the file. Be sure to save edits before appending.

--check, --scan

Find issues with missing release note. Scans issues for those missing release notes and reports findings.

--config PATH

Config location (default: ././.releasehx.yml). Use the configuration file at the specified path instead of the default location (./.releasehx.yml).

--debug

Express each step and show inferred states. Conveys all INFO and DEBUG messages.

--debug-dump

Complete debugging with raw data. Includes all INFO and DEBUG output, as well as raw data objects.

--empty, -e [RULE]

Set/reverse policy on issues "awaiting notes".

Argue a specific drafting policy, or argue the “opposite” policy, for handling issues that are marked as release_note_needed but no note is provided. Set a specific rule (skip, empty, dump, or ai`) to have ReleaseHx include the issue when converting issues to changes, even if no expected note content has been added.

Using -e dump will draft the issue with the entire issue body and commit message as the note content, for any qualifying change entry. Whereas -e ai will use generative AI to draft note properties from issue body and commit message.

Otherwise use just --empty or -e to toggle between skip and empty, if either of those is your default in [conf_ppty_rhyml_empty_notes]. If your default is blank, dump, or ai, using --empty or -e with no argument will toggle a skip policy.

--fetch

Refresh data from source.

Retrieves fresh data rather than using cached/draft files when converting to HTML/PDF. Typically used like:

rhx 1.1.0 --fetch --html

The fetch procedure does write a cached RHYML document before generating final output.

--frontmatter, --no-frontmatter

Enrich or draft with/out frontmatter. When generating drafts or enriching to HTML output, include (--frontmatter) or exclude (--no-frontmatter) frontmatter.

--html [PATH]

Enrich to HTML. Writes to <output_path>/<file_template> or <PATH>.

--internal

Include issues marked internal or likewise. Include issues marked as internal or similarly restricted when drafting content. Has no effect on enrichment operations.

--api-data PATH

Ingest from a JSON file instead of REST response. For API responses, this option saves the payload as PATH. During normal output generating, this option writes a copy of RHYML object to PATH.

--md [PATH]

Draft to Markdown. Outputs to <drafts_dir>/<file_template> or <PATH>.

Where <drafts_dir> is the value of paths.drafts_dir in the config, and <template> is the value of templates.drafts_filename in the config.

--manpage, --man

Show the full manpage documentation. Includes this options reference and other documentation, all in the terminal.

Tip
Use q to quit back to prompt.
--mapping

Alternate API mapping location. File must be a valid RHYML mapping config, usually stored at _mapping/<apiname>.yaml.

The mapping base directory can be changed in [conf_ppty_paths_mappings_dir], but this option must include a complete relative or absolute path.

--payload [PATH]

Store payload as JSON file at PATH or default If no path is argued, defaults to that set in [conf_ppty_paths_payloads_dir].

--output-dir DIRECTORY

Establish base target path for generated files.

--over, --force

Overwrite any existing files without prompting. When writing files, overwrite existing files without prompting for confirmation.

--pdf [PATH]

Enriches to PDF from default or designated source. Writes to <output_path>/<file_template> or <PATH>.

--scan, --check

Find issues with missing release note. Scans issues for those missing release notes and reports findings..

--verbose

Express each step to console during execution.

--version

Display the ReleaseHx version code.

--wrap, --no-wrap

Enrich HTML with/out head and body tags. When enriching to HTML, include (--wrap) or exclude (--no-wrap) the <head> and <body> tags and their content. For use when the opposite value is set in the config file ([conf_ppty_modes_wrapped]).

--quiet

Suppress all output, including warnings.

--yaml, --yml [PATH]

Draft to YAML. Outputs to <drafts_dir>/<file_template> or <PATH>.

Where <drafts_dir> is the value of paths.drafts_dir in the config, and <template> is the value of templates.drafts_filename in the config.

Advanced RHYML

The RHYML syntax is designed specifically for tracking product changes and collecting them as “releases”.

RHYML is also designed particularly for YAML so it can be read, edited, and even authored by humans, including non-programmers.

A complete Release History is a collection of planned product releases as, including patch releases, so RHYML has blocks for major/minor releases and for their subordinate patch releases.

The basic RHYML structure is:

releases: # Optional key to contain multiple releases
  - # Array (sequence) of releases
    code: 1.2.1 # Required key for an individual release
    date: 2025-07-21 # Optional key for release date
    memo: |
      A note of any length, formatted as Markdown (default) or AsciiDoc (configured).
    changes:    # Required key for Array of changes
      -         # Array (seqence) of changes
        chid: 1234 # change ID
        tick: ACME-API-5678 # issue ticket ID
        hash: abcdef0123456789abcdef0123456789abcdef01
        type: feature
        part: auth
        summ: Added new user-authentication flow
        note: |
          The login process now supports multi-factor authentication and single sign-on options.
          Users will need to re-authenticate on their next login to set up these new security features.
        tags: # issue labels
          - breaking
          - highlight

However, here we will focus on the matter that ReleaseHx deals with: individual, sequential releases, which are identically structured whether for major/minor or patch releases, and changes that make up a release entry.

Note
Ruby developers: This YAML representation of the RHYML data structure has a Ruby-native counterpart, documented at .

Release Entries

The two required properties for a release are code (version ID) and changes, but a release can also have a date and a memo.

code

The version identifier string. (Required.)

date

A proper date formatted as YYYY-MM-DD.

memo

An open text field for any description of the release you wish to appear in the overall release entry. Memos can be formatted with Markdown or AsciiDoc. This format must be set either in an individual RHYML file or configured at [conf_ppty_rhyml_markup].

changes

Every valid Release object must contain an Array containing at least one change entry. (Required.)

Change Entries

A release may include any number of changes (including zero). Within each “change” entry, the following properties are available:

chid

The change identifier. This is a contiguous String (no spaces) that MUST be among all changes in its own release and is recommended to be universally unique (across all releases).

tick

The issue ticket number for the change.

hash

The commit hash for the change.

type

The type of change. Must be registered in the types block of the config.

part

The component, interface, feature, or aspect of the product affected by the change. Must be registered in the parts block of the config.

Note
If more than one part is affected, use the parts property instead.
parts

When more than one component, interface, feature, or aspect of the product is affected by the change, and you wish all such “parts” to be noted, use this property instead of part. All items must be listed in the parts block of the config.

summ

A brief summary of the change. Typically used as the Changelog entry.

head

The headline for a release note, if the value of the summ property is not preferred. In standard templates, the headline placeholder looks for a head property but falls back to summ.

note

A note about the change. May include markup formatting.

tags

An array of tags associated with the change. Each must be registered in the tags block of the config. Several tags are registered by default, but you can add as many as you like.

links

A list of documentation or marketing links for the change. The xref and href properties are mutually exclusive; href will supersede.

lead

The primary contributor to the change. Associated with a username in the Issues system.

auths

An array of contributors to the change. Each item must have a user property that matches a username in the Issues system, and may have a memo property to describe the user’s role or involvement in the change.

Application Configuration Reference

These pertain the to the main configuration file, which is defined specifically for your application of ReleaseHx. By default, the application config is found at ./.releasehx.yml.

The full configuration reference is published at {releasehx_docs_www}/config-reference.

Sample Application Configurations

ReleaseHx comes with a complete default configuration file as well as a series of sample configs.

The complete default config file displays default values with commented descriptions of all available properties.

The various sample configurations stored in the demo repository may be a good start toward establishing your own setup.

Environment Variables in ReleaseHx

The only stated environment variables intended to work with ReleaseHx at this time are those related to user or project private data, mainly for integrating with AIs.

Most settings for customizing a given instance (application) of ReleaseHx are stored in the config.

See REST API Authentication for details on how to set up authentication for the REST API client.

Custom REST API Client Configuration

ReleaseHx’s API connections are extensible. As long as you can map the JSON payload returned by your preferred issue-management system provider, you are welcome to add it.

Note
A new API client probably also means a new issue-mapping configuration.
Tip
If you use a standard Jira, GitHub Issues, or GitLab Issues setup, you should NOT have to alter this file.
Note
If you add a non-standard API, please consider contributing it upstream to the ReleaseHx project.

ReleaseHx connects to all upstream REST APIs via YAML-based client configurations.

For reference, the official configs for the three supported REST APIs are at jira.yml, github.yml, and gitlab.yml.

To override any of these or to add your own, place a file at .releasehx/rest/clients/<hostslug>.yml. Make sure it conforms to the schema defined in specs/data/api-client-schema.yaml.

A custom API client configuration has a few main sections:

parameters

Defines the parameters that the client accepts, such as the project ID or the version number.

headers

Defines the HTTP headers to be sent with each request, such as the Content-Type or Authorization headers.

requests

Defines the API requests that the client can make. Each request has a verb (ex: get, post), a path (which can be a Liquid template), and a params section that maps the request parameters to the API parameters.

You can use Liquid templating in the path and params sections to create dynamic requests. For example, you can use {{ version }} to insert the release version into the request path.

Regular Expression Pattern Support

ReleaseHx supports two ways to specify regular expression patterns when called for in configuration and mapping files.

The traditional regular expression literal format:

+

note_pattern: '/## Release Notes\n(?<note>.*?)(?=\n##|\z)/ms'

Pattern Flags

Common flags used with ReleaseHx patterns:

m (multi-line)

Makes ^ and $ match line boundaries instead of just start/end of string. Important for matching within paragraphs.

s (dotall)

Makes dot (.) match newlines. Often needed for note extraction across paragraphs.

i (case insensitive)

Makes pattern case-insensitive. Rarely needed in ReleaseHx patterns.

Example Usage

All these are equivalent and will match a Release Note heading and capture its content:

Example traditional /pattern/flags
note_pattern: '/## Release Notes?\n(?<note>.*?)(?=\n##|\z)/ms'
Example %r{} syntax
note_pattern: '%r{## Release Notes?\n(?<note>.*?)(?=\n##|\z)}ms'
Example plain pattern
note_pattern: '## Release Notes?\n(?<note>.*?)(?=\n##|\z)'

The RegexpUtils module will normalize any of these formats and apply the appropriate flags.

Custom Source-to-RHYML Mapping

Another YAML-based format introduced by ReleaseHx is the mapping between (1) the payload from any cloud-based issue-management system (IMS) API and (2) the universal RHYML format. This procedure turns remote issues into local RHYML changes.

The data associated with issues is translated, property-by-property, to its RHYML equivalent, all according to a YAML file.

Similarly to REST API client configs, initial/default files exist for the major platforms (Jira, GitHub, and GitLab), but these will almost certainly need some customization to suit your particular IMS setup.

Tip
If you are just getting started with a project, you might consider using the default mapping to Define how your issue management system is set up; they mostly hue to defaults from each cloud service.
Important
This mapping case is strictly between the cloud service’s payload and the generic RHYML data model. Most configuration of output (for drafting or enriching), is handled in the main application config file.

For reference, the official mapping configs for the three supported REST APIs are at:

To override any of these or to add your own, place a file at .releasehx/rest/mappings/<hostslug>.yml.

A mapping file has two main parts: a $config block and a set of field mappings.

$config

This block defines the path_lang (either jmespath or jsonpath) used to traverse the API payload and a changes_array_path which is the path to the array of issues within the payload.

Field Mappings

Each subsequent top-level key in the mapping file corresponds to a field in the RHYML change object (ex: tick, summ, note). Each mapping specifies how to derive the value for that RHYML field from the source issue payload. This is done using a path and an optional tplt (template) or ruby script.

  • path: An expression in the declared path_lang (jmespath or jsonpath) to extract the raw value from the issue payload.

  • tplt: A Liquid template to format the extracted value. The extracted value is available as the {{ path }} variable.

  • ruby: A Ruby script to perform more complex transformations. The extracted value is available in the path local variable.

Sandboxed Ruby Transformations

The ruby key provides a powerful way to perform complex data transformations using a secure, sandboxed Ruby environment. This sandbox is powered by the SchemaGraphy::SafeTransform class, which ensures that only an explicit allowlist of safe methods and language features can be used.

Execution Context

Within the ruby script, the following variables are available:

  • path:: The value extracted by the corresponding path expression for the current field.

  • issue:: The full JSON object for the issue being processed.

  • config:: The complete application configuration hash.

Available Helper Methods

You can use a combination of standard Ruby methods and custom helpers within the script. All method calls are validated against a strict allowlist.

Table 4. Allowed Methods
Method Description

dig_path(obj, *keys)

Safely traverses a nested Hash or Array using a dot-separated path string.

is_a?(obj, klass)

Checks the class of an object. klass must be one of Array, Hash, String, Integer, etc.

inspect(obj)

Returns a string representation of an object for debugging.

reduce(array, initial, &block)

A safe wrapper around Ruby’s reduce method.

String Methods

downcase, upcase, capitalize, strip, split, sub, gsub, start_with?, end_with?

Enumerable Methods

map, select, reject, any?, uniq, compact, include?, empty?, size

Operators

+, -, *, /, %, ==, !=, <, >, , >=

Example

The following example demonstrates how to extract a "part" from a list of labels in the path variable.

part:
  path: labels[].name
  ruby: |
    labels = is_a?(path, Array) ? path : [path]
    part_labels = labels.select { |label| label.downcase.start_with?('part:') }
    part_labels.map { |label| label.sub(/^part:/i, '') }.first

By creating a custom mapping file, you can adapt ReleaseHx to work with any issue tracker that provides a JSON-based REST API.

Alternate Mappings for Legacy API Structures

In some cases, the default mappings for supported APIs may not match your particular issue management setup. This commonly occurs when:

  • Your GitHub Issues don’t use native issue types, relying instead on labels like type:bug, type:feature, or just bug and feature.

  • Your GitLab instance has a non-standard label taxonomy.

  • You need to extract data from different API response fields

ReleaseHx addresses this through alternate mapping configurations that override the default field extraction logic.

GitHub Legacy Label-based Type Extraction

The most common alternate mapping need is for GitHub repositories that don’t use native issue types, instead relying on label-based type classification.

For example, if your GitHub issues use labels like:

  • type:bug for bug fixes

  • type:feature for new features

  • type:enhancement for improvements

Your ReleaseHx application will need an alternate mapping because the default GitHub mapping expects native issue_type.name fields.

An example alternate mapping for label-based GitHub type extraction can be found at:

This mapping includes Ruby logic to:

  • Extract types from labels[].name instead of issue_type.name

  • Match label values against configured type definitions

  • Handle label prefixes (ex: type:, kind:) configured in your application

Configuration Changes for Alternate Mappings

When using alternate mappings, you may also need to adjust your application configuration:

Label Prefixes

If your labels use prefixes like type:bug, configure the appropriate prefix in your config:

types:
  label_prefix: 'type:'  # Strip 'type:' from labels like 'type:bug'
  bug:
    slug: bug
    text: Bug Fix
    head: Bug Fixes
Parts Extraction

Similar configuration may be needed for parts/components:

parts:
  label_prefix: 'part:'  # Handle labels like 'part:api', 'part:ui'
  database:
    head: database
    text: Database
  ui:
    head: User Interface
    text: UI
Using Alternate Mappings

To use an alternate mapping:

  1. Place your custom mapping file in the appropriate directory (ex: _mappings/github.yaml) in your ReleaseHx application.

  2. Adjust your application configuration for any label prefixes or field differences

  3. Test with representative payload data to ensure proper extraction

The demo repository contains working examples of these alternate mappings alongside their corresponding configurations and test payloads.

Note
ReleaseHx by default looks for a mapping file that matches the name of the API you are using. If [conf_ppty_origin_source] is set to github, ReleaseHx will first check if you have an override at _mappings/github.yaml before using the default github.yaml built into the application.
Note
The custom mappings path can be set using [conf_ppty_paths_mappings_dir] setting.

Templating Guide

ReleaseHx generally uses enhanced Liquid 4 templates to generate new files and content from RHYML and configuration data.

Notably, it employs Jekyll’s extended tags and filters, as well as some additional tag and several filters provided by Sourcerer.

Here we document the custom filters added by the Sourcerer module and ReleaseHx itself.

Advanced Template Configuration

Before messing with Liquid templates at all, try experimenting with the advanced configuration features available for manipulating the output of your drafts and enriched output.

Using the ReleaseHx config file, you can manipulate:

  • the order in which Changelog and Release Notes sections appear, or if either does not appear at all

  • the inclusion or exclusion of internal changes, experimental features, or breaking changes

  • the formatting of section headers, entry headlines, and metadata fields

  • the sorting and grouping of entries by type, component, contributor, or tags

  • the presence and formatting of links to issues, commits, or external documentation

  • the use of custom “frames” for release notes and changelog entries

  • the display of contributor information, such as lead developer

  • the configuration of frontmatter

  • lots more!

Most of this can be manipulated using the following sections: [conf_ppty_history], [conf_ppty_changelog], [conf_ppty_notes], [conf_ppty_links], as well as within change-metadata config blocks, where you can alter labels, icons, and such: [conf_ppty_types], [conf_ppty_parts], [conf_ppty_tags].

The various sample configurations found in the demo repository illustrate many of these options.

A complete sample config displays default values and commented descriptions of all available properties.

Custom Liquid Tags

ReleaseHx uses Jekyll’s version of the include tag, rather than Liquid’s. It also supports Jekyll’s include_relative tag.

This works essentially like Liquid 5’s render tag, which is not available in ReleaseHx.

ReleaseHx supports a tag called embed which takes no arguments and works exactly like Liquid’s include tag. The embedded file has access to all the variables in the parent template and passes any newly created or modified variables back to affect any subsequent content in the parent template.

Custom Liquid Filters

These filters can be added to Liquid’s prime list of filters and Jekyll’s extended filters. Jekyll filters always supercede same-named Liquid filters, including where.

plusify

Replace double line breaks (\n\n) with \n+\n.

example

{{ note | plusify }}

md_to_asciidoc

Uses Kramdown-AsciiDoc (Kramdoc) to convert Markdown to AsciiDoc.

arguments
wrap

How to handle line wrapping. Can be 'preserve', 'ventilate', or 'none'. The ventilate option presents places all sentences on their own lines.

example

{{ note | md_to_asciidoc: "ventilate" }}

render

Renders a string as a Liquid template with the provided variables.

arguments
vars

A Map (Hash) of variables to pass to the template.

example

{{ note | render: vars }}

indent

Indents each line of the input by the specified number of spaces.

arguments
spaces

The number of spaces to indent by.

line1

If true, also indents the first line.

example

{{ note | indent: 2, true }}

sgyml_type

Returns a string representing the SGYML kind and class of the input, separated by a colon (:).

Response will be one of the following:

  • Null:nil

  • Scalar:String

  • Scalar:Number

  • Scalar:DateTime

  • Scalar:Boolean

  • Compound:Array

  • Compound:ArrayList

  • Compound:ArrayTable

  • Compound:Map

  • Compound:MapTable

  • unknown:unknown

example

{{ id | type_check }}

ruby_class

Returns the Ruby class name of the input.

example

{{ id | ruby_class }}

demarkupify

Simplifies any Markdown and AsciiDoc syntax in the inline input.

Strips * and _ quotes, simplifies "` and '` quotes and UTF-8 curly quotes, and removes all backticks. example::: {{ note | demarkupify }}

pasterize

Converts select verbs in the input from present/imperative to past tense.

Replaces common terms like add/adds with added, fix/fixes with fixed, build/builds with built, etc. example::: {{ summary | pasterize }}

inspect_yaml

Returns a YAML representation of the input for debugging purposes.

example

{{ changes | inspect_yaml }}

Troubleshooting

Common issues and solutions for ReleaseHx configuration and content generation problems.

Empty or Missing Content

"Transformed N changes" but no content appears

Symptoms

ReleaseHx reports successful data transformation (ex:, INFO: Transformed 5 changes for release 1.1.0) but generated files contain only headers and template text with no actual issue content.

Root Cause

Invalid sort configuration syntax in notes: or changelog: sections.

Solution

Check your config’s sort: arrays for invalid grouping1/grouping2/grouping3 syntax.

Invalid sort configuration
# Will cause empty content
sort:
  - 'part:grouping1'
  - 'type:grouping2'
Correct sort configuration
sort:
  - 'part:group'
  - 'type:group'

"All mapped changes were nil after transformation"

Symptoms

ReleaseHx cannot transform any data from the API payload.

Root Cause

Incorrect tag filtering excluding all issues, or mapping/payload mismatch.

Solution
  1. Check tags._exclude lists - never exclude release_note_needed (workflow flag)

  2. Verify the payload file exists and matches the expected API format

  3. Ensure custom mappings are correctly specified with --mapping option

  4. Test with a simpler config without complex tag filtering

Template Processing Issues

Liquid syntax errors during template rendering

Symptoms

Errors like Liquid::SyntaxError or Liquid::Error when generating drafts or enriched output.

Root Cause

Syntax errors in custom Liquid templates.

Solution
  1. Validate Liquid syntax using online validators or IDE plugins

  2. Test templates with minimal content to isolate issues

  3. Review Jekyll’s Liquid documentation for supported tags and filters

APIs

Documntation for th ReleaseHx, SchemaGraphy, and Sourcerer APIs is available at: