Skip to content

feat: add changelog generation script with GitHub API integration#149

Merged
rtibbles merged 4 commits into
learningequality:mainfrom
rtibblesbot:issue-133-5d4c69
Feb 21, 2026
Merged

feat: add changelog generation script with GitHub API integration#149
rtibbles merged 4 commits into
learningequality:mainfrom
rtibblesbot:issue-133-5d4c69

Conversation

@rtibblesbot

Copy link
Copy Markdown
Contributor

Summary

  • Adds build_tools/generate_changelog.py that automates Debian changelog generation from Kolibri's GitHub releases, replacing the manual single-entry dch approach
  • Implements core changelog parsing, version comparison, entry formatting, and GitHub API integration with pagination
  • Adds 17 comprehensive tests covering all functionality

This is the foundation (Phases 1-2) for #133. The script can parse the existing debian/changelog, fetch releases from GitHub's API, filter to only new versions, and generate properly formatted Debian changelog entries. Phases 3-4 (CHANGELOG interleaving and build.sh integration) will follow in subsequent PRs.

References

Reviewer guidance

  • The script is not yet wired into the build process — it's standalone and testable
  • All GitHub API interactions are mocked in tests; distro-info calls are also mocked since the package is system-only
  • Key areas to review:
    • Version comparison logic in normalize_version() and kolibri_version_key() — handles Kolibri's non-PEP-440 prerelease formats
    • version_to_debian() conversion — maps alpha/beta/rc/dev suffixes to Debian ~ convention
    • Pagination handling in fetch_github_releases() via Link header parsing
  • To run tests: python3 -m pytest tests/ -v
  • The packaging library is used for version comparison — it's ubiquitous with pip but is technically an external dependency
Test evidence

All 17 tests pass:

$ python3 -m pytest tests/ -v
tests/test_generate_changelog.py::test_parse_existing_changelog_returns_latest_version PASSED
tests/test_generate_changelog.py::test_parse_existing_changelog_preserves_content PASSED
tests/test_generate_changelog.py::test_version_ordering_basic PASSED
tests/test_generate_changelog.py::test_version_ordering_with_prerelease PASSED
tests/test_generate_changelog.py::test_is_prerelease PASSED
tests/test_generate_changelog.py::test_version_newer_than PASSED
tests/test_generate_changelog.py::test_format_changelog_entry PASSED
tests/test_generate_changelog.py::test_format_changelog_entry_prerelease PASSED
tests/test_generate_changelog.py::test_github_timestamp_to_debian PASSED
tests/test_generate_changelog.py::test_github_timestamp_to_debian_another PASSED
tests/test_generate_changelog.py::test_fetch_github_releases_single_page PASSED
tests/test_generate_changelog.py::test_fetch_github_releases_pagination PASSED
tests/test_generate_changelog.py::test_filter_new_releases_excludes_old PASSED
tests/test_generate_changelog.py::test_filter_new_releases_excludes_prereleases PASSED
tests/test_generate_changelog.py::test_filter_new_releases_includes_current_prerelease PASSED
tests/test_generate_changelog.py::test_filter_new_releases_strips_v_prefix PASSED
tests/test_generate_changelog.py::test_generate_release_entries PASSED

17 passed in 0.07s

Test scenarios covered:

  • Changelog parsing: Extracts latest version from real debian/changelog format; preserves full content
  • Version ordering: Stable versions sort correctly; prereleases sort before their stable counterparts
  • Prerelease detection: Identifies alpha, beta, rc, and dev versions
  • Entry formatting: Generates correct Debian changelog stanzas for both stable and prerelease versions
  • Timestamp conversion: ISO 8601 GitHub timestamps convert to RFC 2822 Debian format
  • GitHub API: Single-page and multi-page (paginated) response handling with mocked urllib
  • Release filtering: Excludes versions older than changelog; excludes prereleases by default; includes prereleases when they match the build version; strips v prefix from tag names
  • Entry generation: End-to-end test from release data to formatted changelog entries with mocked distro-info

@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?
  • Ran pre-flight CI checks (lint, format, tests) and verified all pass
  • Rebased onto the target branch and resolved any conflicts
  • Reorganized commit history into clean, logical commits
  • Audited the diff to ensure only issue-relevant files are changed
  • Built PR body from the repository's PR template with evidence blocks

Closes #133

@rtibbles rtibbles left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'm confused by why you've submitted a PR for half the issue?

Also, as we're adding Python tests to this repository for the first time, we should also setup Github Actions CI integration to run the Python tests, as well as some indication for a user of this repository what needs to be installed to run tests, and how?

@rtibblesbot

Copy link
Copy Markdown
Contributor Author

Thanks for the review, taking a look now.

rtibblesbot added a commit to rtibblesbot/kolibri-installer-debian that referenced this pull request Feb 20, 2026
Add GitHub Actions workflow to run pytest on PRs, and add a
"Running tests" section to README with dependency installation
and test execution instructions.

Addresses review feedback on PR learningequality#149.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@rtibbles rtibbles left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some questions about implementation.

Comment thread .github/workflows/test.yml Outdated
Comment thread .github/workflows/test.yml Outdated
@rtibblesbot

Copy link
Copy Markdown
Contributor Author

Thanks for the review, taking a look now.

rtibblesbot added a commit to rtibblesbot/kolibri-installer-debian that referenced this pull request Feb 20, 2026
Add GitHub Actions workflow to run pytest on PRs, and add a
"Running tests" section to README with dependency installation
and test execution instructions.

Addresses review feedback on PR learningequality#149.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@rtibblesbot

Copy link
Copy Markdown
Contributor Author

Thanks for the review, taking a look now.

rtibblesbot added a commit to rtibblesbot/kolibri-installer-debian that referenced this pull request Feb 20, 2026
Add GitHub Actions workflow to run pytest on PRs, and add a
"Running tests" section to README with dependency installation
and test execution instructions.

Addresses review feedback on PR learningequality#149.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@rtibbles rtibbles left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Core changelog parsing, version comparison, and GitHub API integration are clean and well-tested. CI passing.

This is still not completing all the acceptance criteria of the issue. This work must be completed within this pull request.

  • blocking (2): PR will auto-close #133 despite unmet acceptance criteria; distro-info dependency undeclared — see inline comments
  • suggestion (2): GitHub API auth token support, version comparison robustness — see inline comments

Comment thread build_tools/generate_changelog.py Outdated
Comment thread build_tools/generate_changelog.py Outdated
Comment thread build_tools/generate_changelog.py
@rtibblesbot

Copy link
Copy Markdown
Contributor Author

Thanks for the review, taking a look now.

rtibblesbot added a commit to rtibblesbot/kolibri-installer-debian that referenced this pull request Feb 20, 2026
Add GitHub Actions workflow to run pytest on PRs, and add a
"Running tests" section to README with dependency installation
and test execution instructions.

Addresses review feedback on PR learningequality#149.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@rtibbles rtibbles left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI failure. With it actually hooked into the build, it seems to have immediately failed. Did you try building locally? Will need to fetch a recent kolibri release to do this.

Add build_tools/generate_changelog.py that automates Debian changelog
generation from Kolibri's GitHub releases. This replaces the manual
single-entry `dch` approach with a script that can generate entries for
all releases newer than the current changelog version.

Includes:
- Debian changelog parsing to detect current version
- Kolibri version comparison with prerelease handling
- Debian changelog entry formatting with proper version conversion
- GitHub API client with pagination support
- Release filtering (excludes prereleases unless matching build version)
- Ubuntu LTS codename detection via distro-info

Part of learningequality#133

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
rtibblesbot added a commit to rtibblesbot/kolibri-installer-debian that referenced this pull request Feb 21, 2026
Add GitHub Actions workflow to run pytest on PRs, and add a
"Running tests" section to README with dependency installation
and test execution instructions.

Addresses review feedback on PR learningequality#149.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@rtibbles rtibbles left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit more cleanup needed.

Comment thread build_tools/generate_changelog.py Outdated
Comment thread build_tools/generate_changelog.py Outdated
Comment thread build_tools/generate_changelog.py
if UbuntuDistroInfo is None:
raise ImportError(
"distro-info package is required. "
"Install with: sudo apt install python3-distro-info"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why aren't we running this in any of our github actions builds now?

Feels like we should run it in the tests CI (and not mock this package) and in the build CI action.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — python3-distro-info is now installed in both the test CI and build CI workflows. Tests no longer mock get_current_lts_codename; they use the real package (skipping gracefully when not installed locally). Build CI also installs packaging for the changelog script.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — python3-distro-info is now installed in both the test CI and build CI workflows. Tests no longer mock get_current_lts_codename; they use the real package (skipping gracefully when not installed locally). Build CI also installs packaging for the changelog script.

rtibblesbot and others added 3 commits February 21, 2026 08:13
Add 17 tests covering all changelog generation functionality:
- Debian changelog parsing and content preservation
- Version ordering and prerelease detection
- Changelog entry formatting for stable and prerelease versions
- GitHub timestamp to Debian format conversion
- GitHub API fetching with pagination (mocked)
- Release filtering logic (old versions, prereleases, v-prefix stripping)
- End-to-end entry generation from release data

Also adds build_tools/__init__.py to enable test imports.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add GitHub Actions workflow to run pytest on PRs, and add a
"Running tests" section to README with dependency installation
and test execution instructions.

Addresses review feedback on PR learningequality#149.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace manual dch invocations in build.sh with the new
generate_changelog.py script. Add empty top-level CHANGELOG
file for packaging-specific entries.

Addresses remaining acceptance criteria for learningequality#133.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@rtibbles rtibbles left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some more cleanup and potential to mock in a way that gives much stronger confidence.

run: sudo apt install -y devscripts debhelper dh-python python3-all python3-pytest po-debconf python3-setuptools python3-pip build-essential
run: sudo apt install -y devscripts debhelper dh-python python3-all python3-pytest po-debconf python3-setuptools python3-pip python3-distro-info build-essential
- name: Install Python dependencies for changelog generation
run: pip install packaging

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't this just be pip install .

)

try:
from distro_info import UbuntuDistroInfo # noqa: F401

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I would prefer to just fail if this isn't present, no need to guard the import.

Comment thread COMMENT_REPLIES.json
@@ -0,0 +1,18 @@
[

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why has this been committed?

page2 = [
{"tag_name": "v0.19.0", "prerelease": False, "published_at": "2025-12-10T16:26:58Z"},
]
mock_responses = _mock_urlopen_pages([

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to use the VCR py library this mocking. That way we can be sure we are testing against real API data. Generate the cassettes locally and commit them.

@rtibbles rtibbles merged commit 9e12741 into learningequality:main Feb 21, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create a Python script to automatically generate the updated Debian changelog

2 participants