Changelog Generation
Relevant source files
The following files were used as context for generating this wiki page:
The Changelog Generation feature is a specialized component of the Versions Service designed to provide a consolidated historical record of changes between different software releases. Its primary purpose is to help FOSSBilling instances understand the cumulative changes they will receive when updating from a specific current version to the latest available release.
This system aggregates release notes directly from GitHub release data, processes them according to semantic versioning (SemVer) order, and delivers a unified markdown-formatted response. It serves as a critical bridge for administrators to evaluate the impact of updates spanning multiple version jumps.
Sources: README.md:20-22, src/services/versions/v1/README.md:1-5
Architectural Logic and Flow
Changelog generation relies on the ability to fetch, sort, and filter release metadata. The system uses a centralized loadReleases function which interacts with a KV-based cache (CACHE_KV) or fetches fresh data from the GitHub API if the cache is expired or empty.
Data Processing Pipeline
- Version Validation: The system first validates that the
:currentparameter provided by the user is a valid semantic version. - Release Retrieval: All release data is loaded into memory, either from the
gh-fossbilling-releasesKV store or a fresh GitHub API fetch. - Sorting: Releases are sorted in descending order using SemVer comparisons to ensure the most recent changes appear at the top.
- Filtering: The logic iterates through the sorted releases and appends the
changelog(GitHub release body) for every version that is strictly greater than the user's current version. - Aggregation: The loop breaks once it encounters a version equal to or less than the user's current version.
Sources: src/services/versions/v1/index.ts:182-212, src/services/versions/v1/index.ts:250-255
Generation Sequence Diagram
The following diagram illustrates the sequence of events when a client requests a consolidated changelog.
Explanation: This diagram shows the logic flow from the initial request to the final assembly of the joined changelog string.
Sources: src/services/versions/v1/index.ts:182-212, test/integration/versions/index.test.ts:38-55
API Endpoint Details
The changelog generation is exposed via a single GET endpoint.
GET /versions/v1/build_changelog/:current
| Parameter | Type | Description |
|---|---|---|
:current | String | The semantic version currently installed (e.g., 0.5.0). |
Successful Response Structure:
The response returns a standard API envelope where the result field contains the joined Markdown string.
{
"result": "## 0.6.0\n- New features...\n\n## 0.5.5\n- Bug fixes...",
"error_code": 0,
"message": null,
"stale": false
}
Sources: src/services/versions/v1/README.md:38-51, test/utils/test-types.ts:50-58
Key Data Structures
The generator consumes ReleaseDetails objects stored in a Releases map.
ReleaseDetails Schema
| Field | Type | Description |
|---|---|---|
version | string | The tag name or release name. |
released_on | string | ISO timestamp of publication. |
changelog | string | The raw markdown body from the GitHub release. |
is_prerelease | boolean | Indicates if the release is a draft or pre-release. |
If a release is found but the changelog field is empty or missing, the generator provides a fallback string: ## [version]\nThe changelogs for this release appear to be missing.
Sources: src/services/versions/v1/index.ts:200-203, test/utils/test-types.ts:74-83
Error Handling
The generation process includes specific error states to ensure API stability:
- Invalid Version (400): If the
:currentparameter failssemverValidcheck, the service returns a 400 error. - Service Unavailable (503): If the GitHub API fetch fails and there is no cached data available in KV, a 503 response is returned indicating that releases cannot be retrieved.
- Empty Result: If the
:currentversion is already the latest version, theresultfield will contain an empty string.
Sources: src/services/versions/v1/index.ts:191-197, test/services/versions/v1/index.test.ts:223-233, src/services/versions/v1/README.md:69-78
Implementation Snippet
The core logic for iterating through releases and building the changelog is implemented in src/services/versions/v1/index.ts.
// src/services/versions/v1/index.ts:182-212
registerCachedRoute("/build_changelog/:current", async (c) => {
const current = c.req.param("current");
const result = await loadReleases(c);
const releases = result.releases;
if (!current || !semverValid(current)) {
c.status(400);
return c.json({ result: null, error_code: 400, message: `'${current}' is not a valid semantic version.` });
}
const sortedReleaseKeys = Object.keys(releases).sort((a, b) => semverCompare(b, a));
const completedChangelog: string[] = [];
for (const version of sortedReleaseKeys) {
if (semverGt(version, current)) {
let changelog = releases[version].changelog;
if (!changelog) {
changelog = `## ${version}\nThe changelogs for this release appear to be missing.`;
}
completedChangelog.push(changelog);
} else {
break;
}
}
const assembledChangelog = completedChangelog.join("\n");
return c.json(buildSuccessResponse(assembledChangelog, result.source));
});
Sources: src/services/versions/v1/index.ts:182-212
Summary
Changelog Generation is a utility within the FOSSBilling API that streamlines the update process for end-users. By programmatically aggregating release notes from GitHub and applying SemVer-aware filtering, it provides a comprehensive view of changes relevant to a specific installation's upgrade path. The reliance on CACHE_KV ensures high performance and resilience against GitHub API rate limits or outages.