Skip to content

Commit d1a406f

Browse files
authored
Merge branch 'main' into zhaez/merge-releases
2 parents f1c94fd + c3e7ba5 commit d1a406f

File tree

9 files changed

+181
-37
lines changed

9 files changed

+181
-37
lines changed

.github/workflows/daily-scan.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ jobs:
9595
id: high_scan
9696
uses: ./.github/actions/image_scan
9797
with:
98-
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-python:v0.12.0"
98+
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-python:v0.12.1"
9999
severity: 'CRITICAL,HIGH'
100100
logout: 'false'
101101

@@ -104,7 +104,7 @@ jobs:
104104
id: low_scan
105105
uses: ./.github/actions/image_scan
106106
with:
107-
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-python:v0.12.0"
107+
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-python:v0.12.1"
108108
severity: 'MEDIUM,LOW,UNKNOWN'
109109
logout: 'false'
110110

.github/workflows/post-release-version-bump.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ on:
66
version:
77
description: 'Version number (e.g., 1.0.1)'
88
required: true
9+
is_patch:
10+
description: 'Is this a patch? (true or false)'
11+
required: true
12+
default: 'false'
913

1014
env:
1115
AWS_DEFAULT_REGION: us-east-1
@@ -100,8 +104,22 @@ jobs:
100104
sed -i 's/__version__ = ".*"/__version__ = "'$DEV_VERSION'"/' aws-opentelemetry-distro/src/amazon/opentelemetry/distro/version.py
101105
VERSION="${{ github.event.inputs.version }}"
102106
sed -i 's/python:v.*"/python:v'$VERSION'"/' .github/workflows/daily-scan.yml
107+
108+
# for patch releases, avoid merge conflict by manually resolving CHANGELOG with main
109+
if [[ "${{ github.event.inputs.is_patch }}" == "true" ]]; then
110+
# Copy the patch release entries
111+
sed -n "/^## v${VERSION}/,/^## v[0-9]/p" CHANGELOG.md | sed '$d' > /tmp/patch_release_section.txt
112+
113+
git fetch origin main
114+
git show origin/main:CHANGELOG.md > CHANGELOG.md
115+
116+
# Insert the patch release entries after Unreleased
117+
awk -i inplace '/^## v[0-9]/ && !inserted { system("cat /tmp/patch_release_section.txt"); inserted=1 } {print}' CHANGELOG.md
118+
fi
119+
103120
git add aws-opentelemetry-distro/src/amazon/opentelemetry/distro/version.py
104121
git add .github/workflows/daily-scan.yml
122+
git add CHANGELOG.md
105123
git commit -m "Prepare main for next development cycle: Update version to $DEV_VERSION"
106124
git push --set-upstream origin "prepare-main-for-next-dev-cycle-${VERSION}"
107125
@@ -118,3 +136,13 @@ jobs:
118136
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice." \
119137
--head prepare-main-for-next-dev-cycle-${VERSION} \
120138
--base main
139+
140+
- name: Force our CHANGELOG to override merge conflicts
141+
run: |
142+
git merge origin/main || true
143+
git checkout --ours CHANGELOG.md
144+
git add CHANGELOG.md
145+
if ! git diff --quiet --cached; then
146+
git commit -m "Force our CHANGELOG to override merge conflicts"
147+
git push origin "prepare-main-for-next-dev-cycle-${VERSION}"
148+
fi

.github/workflows/pr-build.yml

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
name: Python Instrumentation PR Build
22
on:
33
pull_request:
4+
types:
5+
- opened
6+
- reopened
7+
- synchronize
8+
- labeled
9+
- unlabeled
410
branches:
511
- main
612
- "release/v*"
@@ -10,6 +16,42 @@ permissions:
1016
contents: read
1117

1218
jobs:
19+
changelog-check:
20+
runs-on: ubuntu-latest
21+
steps:
22+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #5.0.0
23+
with:
24+
fetch-depth: 0
25+
26+
- name: Check CHANGELOG
27+
run: |
28+
# Check if PR is from workflows bot or dependabot
29+
if [[ "${{ github.event.pull_request.user.login }}" == "aws-application-signals-bot" ]]; then
30+
echo "Skipping check: PR from aws-application-signals-bot"
31+
exit 0
32+
fi
33+
34+
if [[ "${{ github.event.pull_request.user.login }}" == "dependabot[bot]" ]]; then
35+
echo "Skipping check: PR from dependabot"
36+
exit 0
37+
fi
38+
39+
# Check for skip changelog label
40+
if echo '${{ toJSON(github.event.pull_request.labels.*.name) }}' | jq -r '.[]' | grep -q "skip changelog"; then
41+
echo "Skipping check: skip changelog label found"
42+
exit 0
43+
fi
44+
45+
# Fetch base branch and check for CHANGELOG modifications
46+
git fetch origin ${{ github.base_ref }}
47+
if git diff --name-only origin/${{ github.base_ref }}..HEAD | grep -q "CHANGELOG.md"; then
48+
echo "CHANGELOG.md entry found - check passed"
49+
exit 0
50+
fi
51+
52+
echo "It looks like you didn't add an entry to CHANGELOG.md. If this change affects the SDK behavior, please update CHANGELOG.md and link this PR in your entry. If this PR does not need a CHANGELOG entry, you can add the 'Skip Changelog' label to this PR."
53+
exit 1
54+
1355
build:
1456
runs-on: ubuntu-latest
1557
strategy:
@@ -18,7 +60,7 @@ jobs:
1860
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
1961
steps:
2062
- name: Checkout Repo @ SHA - ${{ github.sha }}
21-
uses: actions/checkout@v4
63+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #5.0.0
2264

2365
- name: Build Wheel and Image Files
2466
uses: ./.github/actions/artifacts_build
@@ -40,8 +82,8 @@ jobs:
4082
runs-on: ubuntu-latest
4183
steps:
4284
- name: Checkout Repo @ SHA - ${{ github.sha }}
43-
uses: actions/checkout@v4
44-
- uses: actions/setup-python@v5
85+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #5.0.0
86+
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c #v6.0.0
4587
if: ${{ matrix.language == 'python' }}
4688
with:
4789
python-version: '3.x'
@@ -63,7 +105,7 @@ jobs:
63105
tox-environment: ["spellcheck", "lint"]
64106
steps:
65107
- name: Checkout Repo @ SHA - ${{ github.sha }}
66-
uses: actions/checkout@v4
108+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #5.0.0
67109

68110
- name: Install libsnappy-dev
69111
if: ${{ matrix.tox-environment == 'lint' }}
@@ -84,19 +126,19 @@ jobs:
84126
runs-on: ubuntu-latest
85127
steps:
86128
- name: Checkout Repo @ SHA - ${{ github.sha }}
87-
uses: actions/checkout@v4
129+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #5.0.0
88130

89131
- name: Gradle validation
90-
uses: gradle/wrapper-validation-action@v1
132+
uses: gradle/actions/wrapper-validation@ed408507eac070d1f99cc633dbcf757c94c7933a #4.4.3
91133

92134
- name: Set up Java
93-
uses: actions/setup-java@v4
135+
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0
94136
with:
95137
java-version: 17
96138
distribution: temurin
97139

98140
- name: Setup Gradle
99-
uses: gradle/gradle-build-action@v3
141+
uses: gradle/actions/setup-gradle@ed408507eac070d1f99cc633dbcf757c94c7933a #4.4.3
100142

101143
- name: Build with Gradle
102144
run: cd performance-tests; ./gradlew spotlessCheck

.github/workflows/pre-release-prepare.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,13 @@ jobs:
9494
git commit -am "Update version to ${VERSION}"
9595
git push origin "v${VERSION}_release"
9696
97+
- name: Update CHANGELOG for release
98+
run: |
99+
sed -i "s/## Unreleased/## Unreleased\n\n## v${VERSION} - $(date +%Y-%m-%d)/" CHANGELOG.md
100+
git add CHANGELOG.md
101+
git commit -m "Update CHANGELOG for version ${VERSION}"
102+
git push origin "v${VERSION}_release"
103+
97104
- name: Create pull request against the release branch
98105
env:
99106
GITHUB_TOKEN: ${{ env.BOT_TOKEN_GITHUB_RW_PATOKEN }}

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
> **Note:** This CHANGELOG was created starting from version 0.12.0. Earlier changes are not documented here.
6+
7+
For any change that affects end users of this package, please add an entry under the **Unreleased** section. Briefly summarize the change and provide the link to the PR. Example:
8+
- add GenAI attribute support for Amazon Bedrock models
9+
([#300](https://github.com/aws-observability/aws-otel-python-instrumentation/pull/300))
10+
11+
If your change does not need a CHANGELOG entry, add the "skip changelog" label to your PR.
12+
13+
## Unreleased

aws-opentelemetry-distro/src/amazon/opentelemetry/distro/patches/_instrumentation_patch.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def apply_instrumentation_patches() -> None:
6767
from amazon.opentelemetry.distro.patches._starlette_patches import _apply_starlette_instrumentation_patches
6868

6969
# Starlette auto-instrumentation v0.54b includes a strict dependency version check
70-
# This restriction was removed in v1.34.0/0.55b0. Applying temporary patch for Genesis launch
70+
# This restriction was removed in v1.34.0/0.55b0. Applying temporary patch for Bedrock AgentCore launch
7171
# TODO: Remove patch after syncing with upstream v1.34.0 or later
7272
_apply_starlette_instrumentation_patches()
7373

aws-opentelemetry-distro/src/amazon/opentelemetry/distro/patches/_starlette_patches.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from logging import Logger, getLogger
55
from typing import Collection
66

7+
from amazon.opentelemetry.distro._utils import is_agent_observability_enabled
8+
79
_logger: Logger = getLogger(__name__)
810

911

@@ -18,6 +20,7 @@ def _apply_starlette_instrumentation_patches() -> None:
1820
"""
1921
try:
2022
# pylint: disable=import-outside-toplevel
23+
from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware
2124
from opentelemetry.instrumentation.starlette import StarletteInstrumentor
2225

2326
# Patch starlette dependencies version check
@@ -28,6 +31,25 @@ def patched_instrumentation_dependencies(self) -> Collection[str]:
2831
# Apply the patch
2932
StarletteInstrumentor.instrumentation_dependencies = patched_instrumentation_dependencies
3033

34+
# pylint: disable=line-too-long
35+
# Patch to exclude http receive/send ASGI event spans from Bedrock AgentCore,
36+
# this Middleware instrumentation is injected internally by Starlette Instrumentor, see:
37+
# https://github.com/open-telemetry/opentelemetry-python-contrib/blob/51da0a766e5d3cbc746189e10c9573163198cfcd/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py#L573
38+
#
39+
# Issue for tracking a feature to customize this setting within Starlette:
40+
# https://github.com/open-telemetry/opentelemetry-python-contrib/issues/3725
41+
if is_agent_observability_enabled():
42+
original_init = OpenTelemetryMiddleware.__init__
43+
44+
def patched_init(self, app, **kwargs):
45+
original_init(self, app, **kwargs)
46+
if hasattr(self, "exclude_receive_span"):
47+
self.exclude_receive_span = True
48+
if hasattr(self, "exclude_send_span"):
49+
self.exclude_send_span = True
50+
51+
OpenTelemetryMiddleware.__init__ = patched_init
52+
3153
_logger.debug("Successfully patched Starlette instrumentation_dependencies method")
3254
except Exception as exc: # pylint: disable=broad-except
3355
_logger.warning("Failed to apply Starlette instrumentation patches: %s", exc)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
# SPDX-License-Identifier: Apache-2.0
33

4-
__version__ = "0.12.0.dev0"
4+
__version__ = "0.12.1.dev0"

aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/patches/test_starlette_patches.py

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,63 @@ class TestStarlettePatch(TestCase):
1212
@patch("amazon.opentelemetry.distro.patches._starlette_patches._logger")
1313
def test_starlette_patch_applied_successfully(self, mock_logger):
1414
"""Test that the Starlette instrumentation patch is applied successfully."""
15-
# Create a mock StarletteInstrumentor class
16-
mock_instrumentor_class = MagicMock()
17-
mock_instrumentor_class.__name__ = "StarletteInstrumentor"
18-
19-
# Create a mock module
20-
mock_starlette_module = MagicMock()
21-
mock_starlette_module.StarletteInstrumentor = mock_instrumentor_class
22-
23-
# Mock the import
24-
with patch.dict("sys.modules", {"opentelemetry.instrumentation.starlette": mock_starlette_module}):
25-
# Apply the patch
26-
_apply_starlette_instrumentation_patches()
27-
28-
# Verify the instrumentation_dependencies method was replaced
29-
self.assertTrue(hasattr(mock_instrumentor_class, "instrumentation_dependencies"))
30-
31-
# Test the patched method returns the expected value
32-
mock_instance = MagicMock()
33-
result = mock_instrumentor_class.instrumentation_dependencies(mock_instance)
34-
self.assertEqual(result, ("starlette >= 0.13",))
35-
36-
# Verify logging
37-
mock_logger.debug.assert_called_once_with(
38-
"Successfully patched Starlette instrumentation_dependencies method"
39-
)
15+
for agent_enabled in [True, False]:
16+
with self.subTest(agent_enabled=agent_enabled):
17+
with patch.dict("os.environ", {"AGENT_OBSERVABILITY_ENABLED": "true" if agent_enabled else "false"}):
18+
# Create a mock StarletteInstrumentor class
19+
mock_instrumentor_class = MagicMock()
20+
mock_instrumentor_class.__name__ = "StarletteInstrumentor"
21+
22+
def create_middleware_class():
23+
class MockMiddleware:
24+
def __init__(self, app, **kwargs):
25+
pass
26+
27+
return MockMiddleware
28+
29+
mock_middleware_class = create_middleware_class()
30+
31+
mock_starlette_module = MagicMock()
32+
mock_starlette_module.StarletteInstrumentor = mock_instrumentor_class
33+
34+
mock_asgi_module = MagicMock()
35+
mock_asgi_module.OpenTelemetryMiddleware = mock_middleware_class
36+
37+
with patch.dict(
38+
"sys.modules",
39+
{
40+
"opentelemetry.instrumentation.starlette": mock_starlette_module,
41+
"opentelemetry.instrumentation.asgi": mock_asgi_module,
42+
},
43+
):
44+
# Apply the patch
45+
_apply_starlette_instrumentation_patches()
46+
47+
# Verify the instrumentation_dependencies method was replaced
48+
self.assertTrue(hasattr(mock_instrumentor_class, "instrumentation_dependencies"))
49+
50+
# Test the patched method returns the expected value
51+
mock_instance = MagicMock()
52+
result = mock_instrumentor_class.instrumentation_dependencies(mock_instance)
53+
self.assertEqual(result, ("starlette >= 0.13",))
54+
55+
mock_middleware_instance = MagicMock()
56+
mock_middleware_instance.exclude_receive_span = False
57+
mock_middleware_instance.exclude_send_span = False
58+
mock_middleware_class.__init__(mock_middleware_instance, "app")
59+
60+
# Test middleware patching sets exclude flags
61+
if agent_enabled:
62+
self.assertTrue(mock_middleware_instance.exclude_receive_span)
63+
self.assertTrue(mock_middleware_instance.exclude_send_span)
64+
else:
65+
self.assertFalse(mock_middleware_instance.exclude_receive_span)
66+
self.assertFalse(mock_middleware_instance.exclude_send_span)
67+
68+
# Verify logging
69+
mock_logger.debug.assert_called_with(
70+
"Successfully patched Starlette instrumentation_dependencies method"
71+
)
4072

4173
@patch("amazon.opentelemetry.distro.patches._starlette_patches._logger")
4274
def test_starlette_patch_handles_import_error(self, mock_logger):

0 commit comments

Comments
 (0)