Skip to content
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
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
11 changes: 11 additions & 0 deletions .github/scripts/draft-change-log-entries.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ echo
echo "### Migration notes"
echo
echo

# Add breaking changes and deprecations sections
if [[ -z $range ]]; then
labeled_range="HEAD"
else
labeled_range="$range"
fi

"$(dirname "$0")/extract-labeled-prs.sh" "$labeled_range"
echo

echo "### 🌟 New javaagent instrumentation"
echo
echo
Expand Down
78 changes: 78 additions & 0 deletions .github/scripts/extract-labeled-prs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/bin/bash -e

# This script extracts PRs with "breaking change" and "deprecation" labels for the given version range
# Usage: extract-labeled-prs.sh [git-range]
# If no range is provided, it uses HEAD

range="${1:-HEAD}"

if [[ "$range" == "HEAD" ]]; then
# Get all commits from HEAD
commits=$(git log --reverse --pretty=format:"%H %s" HEAD)
else
# Get commits in the specified range
commits=$(git log --reverse --pretty=format:"%H %s" "$range")
fi

# Initialize tracking variables
breaking_changes=""
deprecations=""
breaking_changes_found=false
deprecations_found=false

# Process each commit to find PRs with specified labels
while IFS= read -r line; do
if [[ -z "$line" ]]; then
continue
fi

# Extract PR number from commit message
if [[ $line =~ \(#([0-9]+)\)$ ]]; then
pr_number="${BASH_REMATCH[1]}"
commit_subject=$(echo "$line" | cut -d' ' -f2- | sed 's/ (#[0-9]*)$//')

# Get PR labels using GitHub CLI
if pr_labels=$(gh pr view "$pr_number" --json labels --jq '.labels[].name' 2>/dev/null); then
# Check for breaking change label
if echo "$pr_labels" | grep -q "^breaking change$"; then
breaking_changes_found=true
breaking_changes+="- $commit_subject"$'\n'" ([#$pr_number](https://github.com/open-telemetry/opentelemetry-java-instrumentation/pull/$pr_number))"$'\n'$'\n'
fi

# Check for deprecation label
if echo "$pr_labels" | grep -q "^deprecation$"; then
deprecations_found=true
deprecations+="- $commit_subject"$'\n'" ([#$pr_number](https://github.com/open-telemetry/opentelemetry-java-instrumentation/pull/$pr_number))"$'\n'$'\n'
fi
fi
fi
done <<< "$commits"

# Output breaking changes section
if [[ "$breaking_changes_found" == "true" ]]; then
echo "### ⚠️ Breaking Changes"
echo
echo -n "$breaking_changes"
fi

# Output deprecations section
if [[ "$deprecations_found" == "true" ]]; then
echo "### 🚫 Deprecations"
echo
echo -n "$deprecations"
fi

# Output "no changes" messages if needed
if [[ "$breaking_changes_found" == "false" ]]; then
echo "### ⚠️ Breaking Changes"
echo
echo "*No breaking changes in this release.*"
echo
fi

if [[ "$deprecations_found" == "false" ]]; then
echo "### 🚫 Deprecations"
echo
echo "*No deprecations in this release.*"
echo
fi
57 changes: 57 additions & 0 deletions .github/scripts/format-release-notes.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/bin/bash -e

# Format changelog section for GitHub release notes
# Usage: format-release-notes.sh <changelog_section_file> <output_file>

changelog_section="$1"
output_file="$2"

if [[ -z "$changelog_section" || -z "$output_file" ]]; then
echo "Usage: format-release-notes.sh <changelog_section_file> <output_file>"
exit 1
fi

if [[ ! -f "$changelog_section" ]]; then
echo "Error: Changelog section file '$changelog_section' not found"
exit 1
fi

{
# Add breaking changes section if it exists
if grep -q "### ⚠️ Breaking Changes" "$changelog_section"; then
cat << 'EOF'

## 🚨 IMPORTANT: Breaking Changes

This release contains breaking changes. Please review the changes below:

EOF

# Extract breaking changes section, format for release notes
sed -n '/### ⚠️ Breaking Changes/,/^### /p' "$changelog_section" | sed '$d' | \
perl -0pe 's/(?<!\n)\n *(?!\n)(?![-*] )(?![1-9]+\. )/ /g'

echo -e "\n---\n"
fi

# Add deprecations section if it exists
if grep -q "### 🚫 Deprecations" "$changelog_section"; then
cat << 'EOF'

## 🚫 Deprecations

This release includes deprecations. Please review the changes below and plan for future updates:

EOF

# Extract deprecations section, format for release notes
sed -n '/### 🚫 Deprecations/,/^### /p' "$changelog_section" | sed '$d' | \
perl -0pe 's/(?<!\n)\n *(?!\n)(?![-*] )(?![1-9]+\. )/ /g'

echo -e "\n---\n"
fi

# the complex perl regex is needed because markdown docs render newlines as soft wraps
# while release notes render them as line breaks
perl -0pe 's/(?<!\n)\n *(?!\n)(?![-*] )(?![1-9]+\. )/ /g' "$changelog_section"
} > "$output_file"
112 changes: 112 additions & 0 deletions .github/workflows/pr-automation-comments.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
name: PR Automation Comments
on:
pull_request:
types: [labeled]

permissions:
pull-requests: write

jobs:
comment-on-breaking-change:
if: contains(github.event.label.name, 'breaking change')
runs-on: ubuntu-latest
steps:
- name: Comment on PR
uses: actions/github-script@v7
with:
script: |
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});

// Check if we've already commented about breaking changes
const botComment = comments.find(comment =>
comment.user.login === 'github-actions[bot]' &&
comment.body.includes('⚠️ Breaking Change Documentation Required')
);

if (!botComment) {
const commentBody = [
"## ⚠️ Breaking Change Documentation Required",
"",
"This PR has been labeled as a **breaking change**. Please ensure you provide the following information:",
"",
"### Migration Notes Required",
"Please add detailed migration notes to help users understand:",
"- What is changing and why",
"- How to update their code/configuration",
"- Any alternative approaches if applicable",
"- Code examples showing before/after usage",
"",
"### Checklist",
"- [ ] Migration notes added to the PR description",
"- [ ] Breaking change is documented in the changelog entry for the next release",
"- [ ] Consider if this change requires a major version bump",
"",
"Your migration notes will be included in the release notes to help users upgrade smoothly. The more detailed and helpful they are, the better the user experience will be.",
"",
"---",
"*This comment was automatically generated because the `breaking change` label was applied to this PR.*"
].join("\n");

await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: commentBody
});
}

comment-on-deprecation:
if: contains(github.event.label.name, 'deprecation')
runs-on: ubuntu-latest
steps:
- name: Comment on PR
uses: actions/github-script@v7
with:
script: |
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});

// Check if we've already commented about deprecation
const botComment = comments.find(comment =>
comment.user.login === 'github-actions[bot]' &&
comment.body.includes('📋 Deprecation Notice')
);

if (!botComment) {
const commentBody = [
"## 📋 Deprecation Notice",
"",
"This PR has been labeled as a **deprecation**. Please ensure you provide the following information:",
"",
"### 📝 Deprecation Details Required",
"Please add details to help users understand:",
"- What is being deprecated and why",
"- What should be used instead (if applicable)",
"- Timeline for removal (if known)",
"- Any migration guidance",
"",
"### 📋 Checklist",
"- [ ] Deprecation details added to the PR description",
"- [ ] Deprecation is documented in the changelog entry for the next release",
"- [ ] Consider adding deprecation warnings in code/documentation",
"",
"Your deprecation notes will be included in the release notes to help users prepare for future changes.",
"",
"---",
"*This comment was automatically generated because the `deprecation` label was applied to this PR.*"
].join("\n");

await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: commentBody
});
}
6 changes: 2 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,8 @@ jobs:
sed -n "0,/^## Version $VERSION /d;/^## Version /q;p" CHANGELOG.md \
> /tmp/CHANGELOG_SECTION.md

# the complex perl regex is needed because markdown docs render newlines as soft wraps
# while release notes render them as line breaks
perl -0pe 's/(?<!\n)\n *(?!\n)(?![-*] )(?![1-9]+\. )/ /g' /tmp/CHANGELOG_SECTION.md \
>> /tmp/release-notes.txt
# Format changelog section for release notes (includes breaking changes handling)
.github/scripts/format-release-notes.sh /tmp/CHANGELOG_SECTION.md /tmp/release-notes.txt

# conditional block not indented because of the heredoc
if [[ $VERSION == *.0 ]]; then
Expand Down
29 changes: 29 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,35 @@ Before submitting new features or changes to current functionality, it is recomm
[open an issue](https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/new)
and discuss your ideas or propose the changes you wish to make.


## Breaking Changes

When your PR introduces a breaking change:

* Add the `breaking change` label to your PR
Copy link
Member

Choose a reason for hiding this comment

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

most contributors can't add labels to their PRs

Copy link
Member Author

Choose a reason for hiding this comment

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

i've added some comment automation for this

* Provide migration notes in the PR description:
- What is changing and why
- How users should update their code/configuration
- Code examples showing before/after usage (if applicable)

**When to Use:**

* API changes that break backward compatibility
* Configuration changes that require user action
* Behavioral changes that might affect existing users
* Removal of deprecated features

## Deprecations

When your PR deprecates functionality:

* Add the `deprecation` label to your PR
* Provide deprecation details in the PR description:
- What is being deprecated and why
- What should be used instead (if applicable)
- Timeline for removal (if known)
- Any migration guidance
Comment on lines 31 to 40
Copy link
Contributor

Choose a reason for hiding this comment

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

Not directly related to this PR, but I wonder how we would apply this in practice, for examples with the changes we plan for 3.0 like metrics semconv stability.

  • we usually introduce a config option, where the default is to keep current behavior before 3.0
  • when the next major happens, we switch the default of the config option and remove the config option, which is effectively a breaking change.

The second step should be labelled with breaking change.

However, should the 1st step be labelled as deprecation because we introduce a config option that we know will be removed in the future ? Or do we need to plan a separate deprecation process to review config options between introducing the new config option and removing it ? The downside of doing this in a separate step is that it would be easy to miss something.

Copy link
Member Author

Choose a reason for hiding this comment

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

Or do we need to plan a separate deprecation process to review config options between introducing the new config option and removing it

it does feel a bit different from the standard approach, i guess i just assumed 3.0 would be the breaking change, and we'd provide a new config for them to revert back if they wanted.

Not directly related to this PR

i do think it would be great for us to figure this out and include that in this documentation, I don't think we currently have any official docs on deprecation strategies in this repo


## Building

This project requires Java 21 to build and run tests. Newer JDK's may work, but this version is used in CI.
Expand Down
2 changes: 2 additions & 0 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ the second Monday of the month (roughly a few days after the monthly minor relea
- Merge a pull request to `main` updating the `CHANGELOG.md`.
- The heading for the unreleased entries should be `## Unreleased`.
- Use `.github/scripts/draft-change-log-entries.sh` as a starting point for writing the change log.
- The script will automatically include a "Breaking Changes" section for PRs labeled with `breaking change`.
- The script will automatically include a "Deprecations" section for PRs labeled with `deprecation`.
- Run the [Prepare release branch workflow](https://github.com/open-telemetry/opentelemetry-java-instrumentation/actions/workflows/prepare-release-branch.yml).
- Press the "Run workflow" button, and leave the default branch `main` selected.
- Review and merge the two pull requests that it creates
Expand Down