diff --git a/.github/workflows/main-build.yml b/.github/workflows/main-build.yml
index 1b8715f4..3db6794d 100644
--- a/.github/workflows/main-build.yml
+++ b/.github/workflows/main-build.yml
@@ -9,6 +9,11 @@ on:
required: false
type: string
default: Dev
+ ref:
+ description: 'The branch, tag or SHA to checkout'
+ required: false
+ type: string
+ default: ''
workflow_dispatch: # be able to run the workflow on demand
push:
branches:
@@ -31,6 +36,8 @@ jobs:
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
+ with:
+ ref: ${{ inputs.ref || github.sha }}
- name: Setup .NET
uses: actions/setup-dotnet@d4c94342e560b34958eacfc5d055d21461ed1c5d #v5.0.0
@@ -89,6 +96,7 @@ jobs:
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
with:
fetch-depth: 0
+ ref: ${{ inputs.ref || github.sha }}
- name: Build in Docker container
run: |
@@ -108,6 +116,8 @@ jobs:
environment: ${{ inputs.environment }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
+ with:
+ ref: ${{ inputs.ref || github.sha }}
- name: Setup .NET
uses: actions/setup-dotnet@d4c94342e560b34958eacfc5d055d21461ed1c5d #v5.0.0
@@ -134,6 +144,7 @@ jobs:
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
with:
fetch-depth: 0
+ ref: ${{ inputs.ref || github.sha }}
- name: Build in Docker container
run: |
@@ -158,6 +169,8 @@ jobs:
os: [windows-2022, ubuntu-latest]
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
+ with:
+ ref: ${{ inputs.ref || github.sha }}
- name: Build and scan Linux images
if: runner.os == 'Linux'
diff --git a/.github/workflows/nightly-build.yml b/.github/workflows/nightly-build.yml
new file mode 100644
index 00000000..0ec1cb9f
--- /dev/null
+++ b/.github/workflows/nightly-build.yml
@@ -0,0 +1,132 @@
+name: Nightly Upstream Snapshot Build
+
+on:
+ schedule:
+ - cron: "21 3 * * *"
+ workflow_dispatch:
+ push:
+ branches:
+ - zhaez/nightly-build
+
+permissions:
+ contents: write
+ pull-requests: write
+ id-token: write
+
+env:
+ BRANCH_NAME: nightly-dependency-updates
+ AWS_DEFAULT_REGION: us-east-1
+
+jobs:
+ update-and-create-pr:
+ runs-on: ubuntu-latest
+ outputs:
+ has_changes: ${{ steps.check_changes.outputs.has_changes }}
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
+ with:
+ fetch-depth: 0
+ token: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Configure git
+ run: |
+ git config --local user.email "action@github.com"
+ git config --local user.name "GitHub Action"
+
+ - name: Check out dependency update branch
+ run: |
+ if git ls-remote --exit-code --heads origin "$BRANCH_NAME"; then
+ echo "Branch $BRANCH_NAME already exists, checking out..."
+ git checkout "$BRANCH_NAME"
+ else
+ echo "Branch $BRANCH_NAME does not exist, creating new branch..."
+ git checkout -b "$BRANCH_NAME"
+ fi
+
+ - name: Set up Python
+ uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c #v6.0.0
+ with:
+ python-version: '3.11'
+
+ - name: Install Python dependencies
+ run: pip install requests
+
+ - name: Update dependencies
+ run: python3 scripts/update_dependencies.py
+
+ - name: Check for changes and commit
+ id: check_changes
+ run: |
+ if git diff --quiet; then
+ echo "No dependency updates needed"
+ echo "has_changes=false" >> $GITHUB_OUTPUT
+ else
+ echo "Dependencies were updated"
+ echo "has_changes=true" >> $GITHUB_OUTPUT
+
+ git add src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWS.Distro.OpenTelemetry.AutoInstrumentation.csproj build/Build.cs
+ git commit -m "chore: update OpenTelemetry dependencies to latest versions"
+ git push origin "$BRANCH_NAME"
+ fi
+
+ - name: Create or update PR
+ if: steps.check_changes.outputs.has_changes == 'true'
+ run: |
+ PR_BODY="Automated update of OpenTelemetry dependencies to their latest available versions.
+
+ **Check for breaking changes:**
+ - [opentelemetry-dotnet releases](https://github.com/open-telemetry/opentelemetry-dotnet/releases)
+ - [opentelemetry-dotnet-contrib releases](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/releases)"
+
+ if gh pr view "$BRANCH_NAME" --json state --jq '.state' 2>/dev/null | grep -q "OPEN"; then
+ echo "Open PR already exists, updating description..."
+ gh pr edit "$BRANCH_NAME" --body "$PR_BODY"
+ else
+ echo "Creating new PR..."
+ gh pr create \
+ --title "Nightly dependency update: OpenTelemetry packages to latest versions" \
+ --body "$PR_BODY" \
+ --base main \
+ --head "$BRANCH_NAME"
+ fi
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ build-and-test:
+ needs: update-and-create-pr
+ if: needs.update-and-create-pr.outputs.has_changes == 'true'
+ uses: ./.github/workflows/main-build.yml
+ secrets: inherit
+ permissions:
+ id-token: write
+ contents: write
+ with:
+ caller-workflow-name: nightly-build
+ environment: Dev
+ ref: nightly-dependency-updates
+
+ publish-nightly-build-status:
+ name: "Publish Nightly Build Status"
+ needs: [update-and-create-pr, build-and-test]
+ runs-on: ubuntu-latest
+ if: always()
+ steps:
+ - name: Configure AWS Credentials for emitting metrics
+ uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0
+ with:
+ role-to-assume: ${{ secrets.MONITORING_ROLE_ARN }}
+ aws-region: ${{ env.AWS_DEFAULT_REGION }}
+
+ - name: Publish nightly build status
+ run: |
+ if [[ "${{ needs.build-and-test.result }}" == "skipped" ]]; then
+ echo "Build was skipped (no changes), not publishing metric"
+ else
+ value="${{ needs.build-and-test.result == 'success' && '0.0' || '1.0'}}"
+ aws cloudwatch put-metric-data --namespace 'ADOT/GitHubActions' \
+ --metric-name Failure \
+ --dimensions repository=${{ github.repository }},branch=${{ github.ref_name }},workflow=nightly_build \
+ --value $value
+ fi
diff --git a/build/Build.cs b/build/Build.cs
index 98b046e8..571bdea7 100644
--- a/build/Build.cs
+++ b/build/Build.cs
@@ -12,7 +12,7 @@
internal partial class Build : NukeBuild
{
- private const string OpenTelemetryAutoInstrumentationDefaultVersion = "v1.11.0";
+ private const string OpenTelemetryAutoInstrumentationDefaultVersion = "v1.12.0";
private static readonly AbsolutePath TestNuGetPackageApps = NukeBuild.RootDirectory / "test" / "test-applications" / "nuget-package";
[Solution("AWS.Distro.OpenTelemetry.AutoInstrumentation.sln")]
diff --git a/scripts/update_dependencies.py b/scripts/update_dependencies.py
new file mode 100644
index 00000000..8b04f05a
--- /dev/null
+++ b/scripts/update_dependencies.py
@@ -0,0 +1,217 @@
+#!/usr/bin/env python3
+
+import requests
+import re
+import sys
+import xml.etree.ElementTree as ET
+
+def get_latest_versions_from_github():
+ """Get the latest versions from GitHub releases."""
+ try:
+ print("Fetching releases from opentelemetry-dotnet...")
+ dotnet_response = requests.get(
+ 'https://api.github.com/repos/open-telemetry/opentelemetry-dotnet/releases?per_page=50',
+ timeout=30
+ )
+ dotnet_response.raise_for_status()
+
+ print("Fetching releases from opentelemetry-dotnet-contrib...")
+ contrib_response = requests.get(
+ 'https://api.github.com/repos/open-telemetry/opentelemetry-dotnet-contrib/releases?per_page=100',
+ timeout=30
+ )
+ contrib_response.raise_for_status()
+
+ dotnet_releases = dotnet_response.json()
+ contrib_releases = contrib_response.json()
+
+ print(f"Found {len(dotnet_releases)} dotnet releases")
+ print(f"Found {len(contrib_releases)} contrib releases")
+
+ versions = {}
+
+ # Process opentelemetry-dotnet releases (core packages)
+ for release in dotnet_releases:
+ if release.get('prerelease', False):
+ continue # Skip pre-releases
+
+ tag_name = release['tag_name']
+ # Core releases are typically tagged as "v1.9.0" or "core-1.9.0"
+ version_match = re.match(r'^(?:v|core-)?(\d+\.\d+\.\d+)$', tag_name)
+ if version_match and 'core' not in versions:
+ versions['core'] = version_match.group(1)
+ print(f"Found core version: {versions['core']}")
+ break # Take the first (latest) stable release
+
+ # Process opentelemetry-dotnet-contrib releases
+ # Map package names to their release tag prefixes
+ package_mappings = {
+ 'OpenTelemetry.Extensions.AWS': 'Extensions.AWS',
+ 'OpenTelemetry.Resources.AWS': 'Resources.AWS',
+ 'OpenTelemetry.Instrumentation.AspNetCore': 'Instrumentation.AspNetCore',
+ 'OpenTelemetry.Instrumentation.AspNet': 'Instrumentation.AspNet',
+ 'OpenTelemetry.Instrumentation.AWSLambda': 'Instrumentation.AWS', # Maps to AWS releases
+ 'OpenTelemetry.Instrumentation.Http': 'Instrumentation.Http',
+ 'OpenTelemetry.Sampler.AWS': 'Sampler.AWS',
+ 'OpenTelemetry.SemanticConventions': 'SemanticConventions'
+ }
+
+ for release in contrib_releases:
+ if release.get('prerelease', False):
+ continue # Skip pre-releases
+
+ tag_name = release['tag_name']
+ # Parse contrib releases like "Instrumentation.AspNetCore-1.12.0"
+ match = re.match(r'^(.+)-(\d+\.\d+\.\d+)$', tag_name)
+ if match:
+ component_name = match.group(1)
+ version = match.group(2)
+
+ # Find packages that map to this component
+ for package_name, expected_component in package_mappings.items():
+ if component_name == expected_component and package_name not in versions:
+ versions[package_name] = version
+ print(f"Found {package_name}: {version}")
+
+ return versions
+
+ except requests.RequestException as request_error:
+ print(f"Warning: Could not get GitHub releases: {request_error}")
+ return {}
+
+def get_latest_dotnet_instrumentation_version():
+ """Get the latest version of opentelemetry-dotnet-instrumentation from GitHub releases."""
+ try:
+ response = requests.get(
+ 'https://api.github.com/repos/open-telemetry/opentelemetry-dotnet-instrumentation/releases/latest',
+ timeout=30
+ )
+ response.raise_for_status()
+
+ release_data = response.json()
+ tag_name = release_data['tag_name']
+
+ return tag_name
+
+ except requests.RequestException as request_error:
+ print(f"Warning: Could not get latest dotnet-instrumentation version: {request_error}")
+ return None
+
+def update_csproj_file(file_path, github_versions):
+ """Update OpenTelemetry package versions in a .csproj file."""
+ try:
+ with open(file_path, 'r', encoding='utf-8') as f:
+ content = f.read()
+
+ updated = False
+
+ # Package categorization
+ core_packages = [
+ 'OpenTelemetry',
+ 'OpenTelemetry.Api',
+ 'OpenTelemetry.Exporter.OpenTelemetryProtocol',
+ 'OpenTelemetry.Extensions.Propagators'
+ ]
+
+ # Find and update PackageReference elements using regex
+ def update_package_version(match):
+ nonlocal updated
+ package_name = match.group(1)
+ current_version = match.group(2)
+
+ # Only update OpenTelemetry packages
+ if not package_name.startswith('OpenTelemetry'):
+ return match.group(0)
+
+ latest_version = None
+
+ # Try to get version from GitHub releases only
+ if package_name in core_packages and 'core' in github_versions:
+ latest_version = github_versions['core']
+ elif package_name in github_versions:
+ latest_version = github_versions[package_name]
+ else:
+ # Skip packages not found in GitHub (likely only have pre-releases)
+ print(f"Skipping {package_name} - no stable release found in GitHub")
+ return match.group(0)
+
+ if latest_version and current_version != latest_version:
+ updated = True
+ print(f"Updated {package_name}: {current_version} → {latest_version}")
+ return f''
+ elif latest_version:
+ print(f"{package_name} already at latest version: {latest_version}")
+
+ return match.group(0)
+
+ # Use regex to find and replace PackageReference elements
+ pattern = r''
+ new_content = re.sub(pattern, update_package_version, content)
+
+ if updated:
+ with open(file_path, 'w', encoding='utf-8') as f:
+ f.write(new_content)
+ print("Dependencies updated successfully")
+ return True
+ else:
+ print("No OpenTelemetry dependencies needed updating")
+ return False
+
+ except (OSError, IOError) as file_error:
+ print(f"Error updating dependencies: {file_error}")
+ sys.exit(1)
+
+def update_build_cs_file(file_path):
+ """Update the openTelemetryAutoInstrumentationDefaultVersion in Build.cs."""
+ try:
+ latest_version = get_latest_dotnet_instrumentation_version()
+ if not latest_version:
+ print("Could not get latest dotnet-instrumentation version")
+ return False
+
+ with open(file_path, 'r', encoding='utf-8') as input_file:
+ content = input_file.read()
+
+ pattern = r'private const string OpenTelemetryAutoInstrumentationDefaultVersion = "v[^"]*";'
+ replacement = f'private const string OpenTelemetryAutoInstrumentationDefaultVersion = "{latest_version}";'
+
+ if re.search(pattern, content):
+ new_content = re.sub(pattern, replacement, content)
+
+ if new_content != content:
+ with open(file_path, 'w', encoding='utf-8') as output_file:
+ output_file.write(new_content)
+ print(f"Updated OpenTelemetryAutoInstrumentationDefaultVersion to {latest_version}")
+ return True
+ else:
+ print(f"OpenTelemetryAutoInstrumentationDefaultVersion already at latest version: {latest_version}")
+ return False
+ else:
+ print("Could not find OpenTelemetryAutoInstrumentationDefaultVersion in Build.cs")
+ return False
+
+ except (OSError, IOError) as file_error:
+ print(f"Error updating Build.cs: {file_error}")
+ sys.exit(1)
+
+def main():
+ print("Getting latest versions from GitHub releases...")
+ github_versions = get_latest_versions_from_github()
+
+ if not github_versions:
+ print("No versions found from GitHub releases, exiting")
+ return
+
+ print("Found versions:", github_versions)
+
+ csproj_path = 'src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWS.Distro.OpenTelemetry.AutoInstrumentation.csproj'
+ build_cs_path = 'build/Build.cs'
+
+ csproj_updated = update_csproj_file(csproj_path, github_versions)
+ build_cs_updated = update_build_cs_file(build_cs_path)
+
+ if not csproj_updated and not build_cs_updated:
+ print("No updates were made")
+
+if __name__ == '__main__':
+ main()
diff --git a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWS.Distro.OpenTelemetry.AutoInstrumentation.csproj b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWS.Distro.OpenTelemetry.AutoInstrumentation.csproj
index c11c31f4..56b059b7 100644
--- a/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWS.Distro.OpenTelemetry.AutoInstrumentation.csproj
+++ b/src/AWS.Distro.OpenTelemetry.AutoInstrumentation/AWS.Distro.OpenTelemetry.AutoInstrumentation.csproj
@@ -21,17 +21,17 @@
-
-
-
+
+
+
-
-
+
+
-
+