Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
517437b
Merge pull request #1081 from RocketPy-Team/master
Gui-FernandesBR Jul 22, 2026
9ccc804
DOC: Update Changelog for PR #1081
github-actions[bot] Jul 22, 2026
b8e063f
Merge pull request #1082 from RocketPy-Team/enh/llm-changelog-automation
Gui-FernandesBR Jul 24, 2026
725041c
DOC: update changelog for PR #1082
github-actions[bot] Jul 24, 2026
8b01b34
ENH: Resolve pressure_ISA discretization bounds TODO (#1056)
Gui-FernandesBR Jul 26, 2026
1691119
ENH: Add native Meteomatics API support to the Environment class (#1079)
Gui-FernandesBR Aug 1, 2026
2cca437
DOC: make the CustomSampler examples answer to their seed (#1097)
thc1006 Aug 8, 2026
f40f18e
CI: force software rendering to fix flaky VTK off-screen bus error (#…
wuisabel-gif Aug 8, 2026
335834d
BUG: rocket with a late-starting thrust curve never leaves the rail (…
wuisabel-gif Aug 8, 2026
d74bf3f
BUG: fly the parachute the simulation sampled (#1098)
thc1006 Aug 8, 2026
3656d2a
MNT: do not let one Python version cancel the other in the slow matri…
thc1006 Aug 8, 2026
cb909f2
ENH: Add Qodo PR-Agent workflow using Google Gemini (#1089)
Gui-FernandesBR Aug 8, 2026
235dc6e
DOC: update changelog for PR #1089
github-actions[bot] Aug 8, 2026
a586750
CI: build the docs for pull requests into develop as well (#1104)
thc1006 Aug 8, 2026
6d66bde
BUG: give each CustomSampler its own stream instead of the model's seed
thc1006 Aug 8, 2026
6211dbb
BUG: make the sampler key collision-free and the shared case order-free
thc1006 Aug 8, 2026
412c313
BUG: seed a shared generator once between its samplers, not once each
thc1006 Aug 8, 2026
06949e7
BUG: name the sampler when its generator refuses the seed
thc1006 Aug 8, 2026
1e0e149
MNT: reset the group itself, and stop the example filling a cache it …
thc1006 Aug 8, 2026
cb5dca7
DOC: say what owning a seed group means
thc1006 Aug 8, 2026
e775846
DOC: add the changelog entry for this branch
thc1006 Aug 8, 2026
4b187cd
MNT: declare dependency floors the package can actually run on (#1108)
thc1006 Aug 8, 2026
6224be7
BUG: accept the callable parachute triggers the docstring promises (#…
thc1006 Aug 8, 2026
6487992
Merge remote-tracking branch 'origin/develop' into tmp-1102
Gui-FernandesBR Aug 8, 2026
9593b1d
Merge pull request #1102 from thc1006/bug/custom-sampler-seed-groups
Gui-FernandesBR Aug 8, 2026
dbdb061
ENH: Add simplified opening shock force estimation (#1092)
ArthurJWH Aug 8, 2026
fa467c8
Merge remote-tracking branch 'origin/develop' into dev-merge-1102
Gui-FernandesBR Aug 8, 2026
2ff425c
DOC: add the changelog entries the fork-PR bug dropped
Gui-FernandesBR Aug 8, 2026
cbafd72
Raise the sampler type check rather than asserting it
thc1006 Aug 8, 2026
25271f4
Validation in stochastic/ that survives python -O (#1111)
thc1006 Aug 8, 2026
8e4ed99
ENH: Support for Open-Meteo API in the `Environment` class (#1119)
Gui-FernandesBR Aug 11, 2026
60ae36d
DOC: update changelog for PR #1119
github-actions[bot] Aug 11, 2026
1812e08
MNT: the docker/ files still use the paths they had before the 2024 m…
sujeito-operator Aug 12, 2026
bf55788
Fix operating_temperature init values (#1118)
vapsik Aug 12, 2026
235487c
CI: make the Gemini PR reviewer actually review (#1140)
Gui-FernandesBR Aug 12, 2026
a4a61c6
DOC: update changelog for PR #1140
github-actions[bot] Aug 12, 2026
d21abde
ENH: StochasticFreeFormFins for Monte Carlo simulations (#1117)
Gui-FernandesBR Aug 12, 2026
5eae273
DOC: update changelog for PR #1117
github-actions[bot] Aug 12, 2026
364214b
BUG: Restore UTC fallback without timezonefinder (#1143)
ting-hong-shieh Aug 13, 2026
e00a07e
ENH: add tube-fin aerodynamic surface (#1144)
ting-hong-shieh Aug 13, 2026
999552c
CI: keep per-matrix coverage artifacts and fail Codecov errors (#1088…
thatrandomasiandev Aug 14, 2026
cb6106a
BUG: seed parachute pressure noise with per-instance RNG (#1091) (#1134)
thatrandomasiandev Aug 14, 2026
13d887c
CI: run the changelog job for pull requests from forks (#1112)
thc1006 Aug 14, 2026
6a6910d
DOC: correct Flight aerodynamic moment units (#1149)
ting-hong-shieh Aug 14, 2026
9d4726d
DOC: tighten the comments that came with the sampler seed groups (#1154)
thc1006 Aug 14, 2026
718b96b
TST: use UTC for the HRRR forecast date (#1153)
ting-hong-shieh Aug 14, 2026
4b53bf1
BUG: report missing impact roots explicitly (#1147) (#1148)
ting-hong-shieh Aug 14, 2026
62aa0f9
TST: cover controller behavior and reporting (#1152)
ting-hong-shieh Aug 14, 2026
2f9a44b
TST: cover Function unit conversions (#1157)
ting-hong-shieh Aug 14, 2026
1d04bcc
TST: cover geospatial extent conversions (#1158)
ting-hong-shieh Aug 14, 2026
3e16c9f
MNT: let pylint use every core it is given (#1163)
thc1006 Aug 14, 2026
5a71eb9
BUG: stop dict_generator from sampling initial_solution (#1109) (#1122)
thatrandomasiandev Aug 15, 2026
f8b6a5e
TST: cover attitude conversion helpers (#1159)
ting-hong-shieh Aug 15, 2026
a1ae329
CI: measure coverage on develop, not only on pull requests (#1162)
thc1006 Aug 15, 2026
772480d
DOC: fix RST indentation in dict_generator notes
Gui-FernandesBR Aug 15, 2026
e39f09d
BUG: evaluate parachute triggers once per time node (#1086) (#1121)
thatrandomasiandev Aug 15, 2026
8b79c2c
ENH: Create ensembles from user-defined profiles (#1141)
ting-hong-shieh Aug 15, 2026
7edbbc8
BUG: skip scalar statistics for structured Monte Carlo results (#1145…
ting-hong-shieh Aug 15, 2026
f604534
BUG: apply wind factors to the ensemble member that was selected (#1160)
thc1006 Aug 15, 2026
76cab5a
BUG: build Monte Carlo flights with the configuration they were given…
thc1006 Aug 15, 2026
6c15649
DOC: document multivariable drag inputs (#1142)
ting-hong-shieh Aug 15, 2026
5257298
TST: add Defiance example flight acceptance test (#1156)
ting-hong-shieh Aug 15, 2026
2ce0ad6
BUG: serialize numpy SeedSequence for sensor seeds (#1087) (#1124)
thatrandomasiandev Aug 15, 2026
be195d4
TST: cover confidence ellipse helpers (#1165)
ting-hong-shieh Aug 15, 2026
c006a0d
BUG: draw the eccentricities again, whichever way they were added (#1…
thc1006 Aug 15, 2026
60ed40f
ENH: compute rocket static margin lazily (#780) (#1135)
thatrandomasiandev Aug 15, 2026
8ba1f2f
BUG: write MonteCarlo input and output rows atomically (#1110) (#1125)
thatrandomasiandev Aug 15, 2026
826531b
ENH: add Flight post-step callback across all phases (#758) (#1128)
thatrandomasiandev Aug 15, 2026
ffb5a58
ENH: model unbonded solid-motor grain CM shift (#340) (#1138)
thatrandomasiandev Aug 15, 2026
dc5f81f
BUG: refuse to run a Monte Carlo over a results file it cannot write …
thc1006 Aug 15, 2026
24861fd
ENH: list NOAA atmosphere datasets and fetch latest (#660) (#1136)
thatrandomasiandev Aug 15, 2026
1dd2365
DOC: add SIL parachute ejection integration example (#524) (#1131)
thatrandomasiandev Aug 15, 2026
df06506
fix: accept numpy integer types as Parachute trigger (#1116)
abhi-0203 Aug 15, 2026
74fc8ad
BUG: draw each declared eccentricity once per simulation (#1168)
thc1006 Aug 15, 2026
7822ab1
ENH: support fixed-time parachute deployment triggers (#437) (#1133)
thatrandomasiandev Aug 15, 2026
1b87124
Fix spurious ValueError from floating-point roundoff at exact tank de…
arocketcat Aug 15, 2026
4263fa9
BUG: sample StochasticFlight inputs once per simulation (#1090) (#1126)
thatrandomasiandev Aug 15, 2026
e5df3fa
DOC: backfill the Unreleased changelog entries the automation missed …
ting-hong-shieh Aug 19, 2026
7e785a6
TST: run the EnvironmentAnalysis tests in the default suite (#1176)
ting-hong-shieh Aug 19, 2026
3a75eac
MNT: install contextily with the other optional requirements (#1179)
ting-hong-shieh Sep 8, 2026
d457bf8
TST: cover the rocket and Monte Carlo plot branches (#1178)
ting-hong-shieh Sep 9, 2026
799761b
BUG: correct the nozzle gyration tensor parallel axis term (#1188)
thc1006 Sep 9, 2026
3bd6505
ENH: plot flight center-of-pressure evolution (#954) (#1130)
thatrandomasiandev Sep 9, 2026
95ca752
BUG: accept the seed type a Monte Carlo worker is handed (#1181)
thc1006 Sep 9, 2026
b50bda8
Update official team logos (black and white) (#1183)
shmuelnasc Sep 9, 2026
7f2ad3f
Fixed sensor.accelerometer gravity sign for `consider_gravity = True`…
vapsik Sep 9, 2026
fa38028
BUG: reject live RNG objects as Sensor seeds (#1174)
myungjunlee Sep 9, 2026
06bdb4b
BUG: give each StochasticRocket component its own random stream (#1170)
thc1006 Sep 9, 2026
8f3a9ce
BUG: keep stochastic nominal values stable across reseeds (#1169)
thc1006 Sep 9, 2026
bc3fe73
MNT: store ref_factor on rocket aero surface components (#561) (#1129)
thatrandomasiandev Sep 9, 2026
d864d4d
BUG: make a failing Monte Carlo worker say so (#1182)
thc1006 Sep 9, 2026
0923d8a
BUG: re-raise KeyboardInterrupt after an interrupted Monte Carlo run …
ting-hong-shieh Sep 11, 2026
88aed5a
ENH: cache downloaded atmosphere netCDF datasets (#654) (#1137)
thatrandomasiandev Sep 14, 2026
9fbf3a3
ENH: add Folium interactive flight trajectory map (#963) (#1132)
thatrandomasiandev Sep 14, 2026
ebe1b77
ENH: Implement 3-DOF Single Rail Button Flight Phase (Tip-off Analysi…
Rafit345 Sep 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions .github/workflows/codecov.yml → .codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ coverage:
target: auto
threshold: 1%
base: auto
flags:
- unit
# No `flags:` on purpose. This used to scope the status to a `unit` flag
# that no upload has ever tagged, so Codecov resolved it over an empty
# flag set and the gate measured nothing. The reports test_pytest.yaml
# sends are unit + doctest + integration + acceptance combined, so there
# is no honest flag to name here.
paths:
- "rocketpy"
# advanced settings
Expand All @@ -29,7 +32,6 @@ coverage:
- develop
if_ci_failed: error # success, failure, error, ignore
only_pulls: false
flags:
- "unit"
# See the note on project.default above: no upload tags a `unit` flag.
paths:
- "rocketpy"
2 changes: 1 addition & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
- [ ] Docs have been reviewed and added / updated
- [ ] Lint (`black rocketpy/ tests/`) has passed locally
- [ ] All tests (`pytest tests -m slow --runslow`) have passed locally
- [ ] `CHANGELOG.md` has been updated (if relevant)
- `CHANGELOG.md` — no action needed; an LLM workflow auto-updates it after merge

## Current behavior
<!-- Describe current behavior or link to an issue. -->
Expand Down
179 changes: 179 additions & 0 deletions .github/scripts/test_update_changelog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
#!/usr/bin/env python3
"""Self-contained tests for update_changelog.py.

Runs without network or the ``google-genai`` package (the LLM import in the
script is lazy). Exercises the deterministic pieces that keep the changelog
safe: section splitting, duplicate detection, prefix handling, the fallback
classifier, and the validator that guards LLM output.

Run locally with either:
python .github/scripts/test_update_changelog.py
pytest .github/scripts/test_update_changelog.py
"""

import os
import sys

sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

import update_changelog as uc # noqa: E402

SAMPLE = """\
# RocketPy Change Log

## [Unreleased] - yyyy-mm-dd

### Added

### Changed

### Fixed

## [v1.13.0] - 2026-07-21

### Added

- ENH: something old [#100](https://github.com/RocketPy-Team/RocketPy/pull/100)
"""


def test_split_roundtrips():
before, block, after = uc.split_changelog(SAMPLE)
assert before + block + after == SAMPLE
assert block.startswith("## [Unreleased]")
assert "## [v1.13.0]" not in block
assert "## [v1.13.0]" in after


def test_already_present():
_, block, after = uc.split_changelog(SAMPLE)
assert uc.already_present(after, 100) is True
assert uc.already_present(block, 100) is False
assert uc.already_present(block, 999) is False


def test_detect_prefix():
assert uc.detect_prefix("BUG: fix a thing") == "BUG"
assert uc.detect_prefix("BUG/MNT: pre-release review fixes") == "BUG/MNT"
assert uc.detect_prefix("Add a shiny feature") is None


def test_no_double_prefix():
# The historical bug: a title already carrying a prefix must not gain another.
entry = uc.build_entry("BUG/MNT: pre-release fixes", 1074, "ENH", "BUG/MNT")
assert entry.startswith("- BUG/MNT: pre-release fixes ")
assert "ENH:" not in entry
assert "[#1074](https://github.com/RocketPy-Team/RocketPy/pull/1074)" in entry


def test_build_entry_adds_prefix_when_missing():
entry = uc.build_entry("Add a shiny feature", 200, "ENH", None)
assert entry.startswith("- ENH: Add a shiny feature ")


def test_fallback_routing():
# Bug label -> Fixed
section, prefix, _ = uc.fallback_section_and_prefix("Fix crash", "Bug,Flight")
assert section == "### Fixed" and prefix == "BUG"
# Refactor label -> Changed
section, _, _ = uc.fallback_section_and_prefix("Tidy internals", "Refactor")
assert section == "### Changed"
# Existing prefix wins the routing even without a matching label
section, prefix, existing = uc.fallback_section_and_prefix("BUG: oops", "")
assert section == "### Fixed" and existing == "BUG"
# Default
section, prefix, _ = uc.fallback_section_and_prefix("New capability", "Enhancement")
assert section == "### Added" and prefix == "ENH"


def test_fallback_update_inserts_once_under_right_section():
_, block, _ = uc.split_changelog(SAMPLE)
updated = uc.fallback_update(block, "BUG: fix a thing", 321, "Bug")
assert updated.count("[#321]") == 1
fixed = updated.split("### Fixed", 1)[1]
assert "- BUG: fix a thing" in fixed
# Not misplaced under Added.
added = updated.split("### Added", 1)[1].split("### Changed", 1)[0]
assert "[#321]" not in added


def test_ensure_section_inserts_in_canonical_order():
_, block, _ = uc.split_changelog(SAMPLE)
# SAMPLE has Added/Changed/Fixed but no Removed subsection.
lines = uc.ensure_section(block.splitlines(keepends=True), "### Removed")
joined = "".join(lines)
# Removed must sit after Changed and before Fixed.
assert (
joined.index("### Changed")
< joined.index("### Removed")
< joined.index("### Fixed")
)


def test_validator_accepts_good_output():
_, block, _ = uc.split_changelog(SAMPLE)
good = block.replace(
"### Fixed\n",
"### Fixed\n\n- BUG: fix it [#500](https://github.com/RocketPy-Team/RocketPy/pull/500)\n",
)
assert uc.validate_llm_block(block, good, 500) is None


def test_validator_rejects_dropped_entry():
old = block_with_entry()
# New block loses the pre-existing entry.
new = "## [Unreleased] - yyyy-mm-dd\n\n### Fixed\n\n- BUG: new [#500](https://github.com/RocketPy-Team/RocketPy/pull/500)\n\n"
assert uc.validate_llm_block(old, new, 500) is not None


def test_validator_rejects_missing_new_ref():
_, block, _ = uc.split_changelog(SAMPLE)
assert uc.validate_llm_block(block, block, 500) is not None # no new ref at all


def test_validator_rejects_leaked_version_header():
_, block, _ = uc.split_changelog(SAMPLE)
leaked = (
"## [Unreleased] - yyyy-mm-dd\n\n### Fixed\n\n"
"- BUG: x [#500](https://github.com/RocketPy-Team/RocketPy/pull/500)\n\n"
"## [v1.13.0] - 2026-07-21\n"
)
assert uc.validate_llm_block(block, leaked, 500) is not None


def test_validator_rejects_runaway_growth():
_, block, _ = uc.split_changelog(SAMPLE)
huge = (
"## [Unreleased] - yyyy-mm-dd\n\n### Fixed\n\n"
"- BUG: x [#500](https://github.com/RocketPy-Team/RocketPy/pull/500)\n"
+ ("x" * (uc.MAX_BLOCK_GROWTH + 50))
)
assert uc.validate_llm_block(block, huge, 500) is not None


def block_with_entry():
return (
"## [Unreleased] - yyyy-mm-dd\n\n### Added\n\n"
"- ENH: keep me [#200](https://github.com/RocketPy-Team/RocketPy/pull/200)\n\n"
"### Fixed\n\n"
)


def _run_all():
tests = [
v for k, v in sorted(globals().items()) if k.startswith("test_") and callable(v)
]
failures = 0
for test in tests:
try:
test()
print(f" ok {test.__name__}")
except AssertionError as exc:
failures += 1
print(f" FAIL {test.__name__}: {exc}")
print(f"\n{len(tests) - failures}/{len(tests)} passed")
return 1 if failures else 0


if __name__ == "__main__":
sys.exit(_run_all())
Loading
Loading