Skip to content

Conversation

@jonathan343
Copy link
Contributor

@jonathan343 jonathan343 commented Jan 4, 2026

Note

These scripts are adapted from smithy-lang/smithy-python#552, with the addition of support for release summary entries (SUMMARY.json).

Summary

  • Add Python scripts for managing per-package changelogs in a structured, automation-friendly format.
  • Backfill changelog entries for existing client packages (aws-sdk-bedrock-runtime, aws-sdk-sagemaker-runtime-http2, aws-sdk-transcribe-streaming).

Changelog Tooling

This PR introduces three scripts under scripts/changelog/:

Script Purpose
new-entry.py Create individual changelog entries stored in .changes/next-release/
new-release.py Consolidate pending entries into a versioned JSON file (e.g., 0.3.0.json)
render.py Generate CHANGELOG.md from version JSON files using a Jinja2 template

Workflow

  1. Contributors add entries via new-entry.py --package <name> --type <type> --description "..."
  2. At release time, new-release.py consolidates entries into <version>.json
  3. render.py regenerates CHANGELOG.md from all version files

Test plan

  • Verify new-entry.py creates entries in the correct location
  • Verify new-release.py consolidates entries and cleans up next-release/
  • Verify render.py generates accurate CHANGELOG.md output
  • Confirm rendered changelogs match the JSON source data

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@jonathan343 jonathan343 marked this pull request as ready for review January 4, 2026 02:58
@jonathan343 jonathan343 requested a review from a team as a code owner January 4, 2026 02:58
Copy link

@ubaskota ubaskota left a comment

Choose a reason for hiding this comment

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

Overall looks good. I've added some comments. Please, let me know if you have any questions.

# Generate unique filename
timestamp = int(time.time() * 1_000_000)
unique_id = uuid.uuid4().hex
filename = f"{package_name}-{change_type}-{timestamp}-{unique_id}.json"
Copy link

Choose a reason for hiding this comment

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

For filename, timestamp is already in microseconds. Wouldn't that be enough? What is the benefit of adding uuid to it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Relying on timestamps alone will never really guarantee uniqueness since our infra will be creating changelog entries in rapid succession (and in parallel in the future). See the example below:

>>> timestamps = []
>>> for i in range(1000):
...     timestamp = int(time.time() * 1_000_000)
...     if timestamp in timestamps:
...         print("Found duplicate")
...     else:
...         timestamps.append(timestamp)
...         
Found duplicate
Found duplicate
Found duplicate

We could increase the precision, however, using uuid is more robust. I decided to include the timestamp in attempt to achieve natural ordering of changelog entries when rendering them out. However, that isn't really working right now and I'll handle it in a separate PR. It's more of a nice to have.

I'm gonna remove timestamp for now and only use uuid.

},
{
"type": "dependency",
"description": "**Updated**: `smithy_aws_core[eventstream, json]` from `~=0.2.0` to `~=0.3.0`."
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems like an odd thing to bold to begin with, and it is less readable (for me) in both JSON and markdown.

Not a huge thing, and we shouldn't change them retroactively, but if we are going to start using markdown syntax in changelog entries, we should agree on guidelines for when and how to apply them and record them in our contributing.md file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea, we can get something added in CONTRIBUTING.md. That should probably be done in a separate PR since there are non-changelog things we should also update it with.

I'm curious what about the bold syntax makes it less readable for you?

parser.add_argument(
"-t",
"--type",
# TODO: Remove the 'breaking' option once this project is stable.
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a thought- maybe we leave this in permanently? For minor "breaks" that we will continue to do that offer more benefit than pain to customers.

One example that may be upcoming in boto is switching to using standard instead of legacy retry mode.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not against it. I think there should be some confirmation that explains the effects of using breaking and that it should be used sparingly. Probably wouldn't hurt to add the same for a feature since they both result in minor bumps across the ecosystem.

I'll update to:

# TODO: Prompt the user for confirmation before allowing the 'breaking' or `feature` options.

entry_file.unlink()
removed_count += 1
except OSError as e:
print(f"Warning: Could not remove {entry_file}: {e}", file=sys.stderr)
Copy link
Contributor

Choose a reason for hiding this comment

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

The intention here is to ignore the error quietly and continue? Do you think it's possible that this error will get ignored and leave behind the entry file and duplicate the entry for the next release?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this would be a very rare case when this happens (if possible) because of how we're using this. I'll remove the try/except so if this does raise an error, our script and release process fail

- new-entry.py allows for creating entried for a specific package, type, and a description.
- new-release.py consolidates new entries into a versioned json file for preservation.
- render.py will generate a CHANGELOG.md file using the versioned json files and a jinja2 template.
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.

3 participants