- 
                Notifications
    You must be signed in to change notification settings 
- Fork 27
Add nightly dependency bump workflow #479
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
e74800c
              7252cb3
              e56456b
              c2d895d
              6cc475d
              e9c78dd
              7349738
              ca80bbb
              cdbfea2
              feb2005
              d9d2dfe
              e2a6c4c
              b074e69
              3fb046f
              351813e
              9d57171
              9f0ebbb
              60b627a
              1544468
              a6d58c1
              e84deb6
              51a9ee0
              957024b
              076e529
              30d7d0a
              f3b7a09
              5182877
              9efd150
              5ebbe34
              1b56b75
              2f26b9c
              0329b09
              4db8d3e
              84706be
              d9d3a9a
              1357fc8
              74c6fb4
              f5ba036
              8b05265
              dda3ac0
              63b72f3
              1c7bdf3
              bb66be4
              692abde
              12cc0e5
              e7fb5f7
              15e4550
              b1b4a87
              3c9440b
              e6b52b3
              5e1171d
              45ea16d
              6c7b4bd
              a1c81dc
              2846429
              831ed16
              9fe4fee
              8642b0f
              2c189df
              daac532
              6d7edc4
              fae0a59
              c9445a6
              da1bcd6
              8e6aa2b
              bc28671
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the workflow should be: 
 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So only create/update PR if main build passes? But then if it fails (most likely b/c of breaking changes), there's no PR to work off of? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, new job  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it, I will run build-and-test first and then link/add the result in the PR description. See new PR #528 | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,176 @@ | ||
| name: Nightly Upstream Snapshot Build | ||
|         
                  thpierce marked this conversation as resolved.
              Show resolved
            Hide resolved | ||
| description: This workflow checks for new upstream versions of OpenTelemetry dependencies, creates a PR to update them, and builds and tests the new changes. | ||
|  | ||
| on: | ||
| schedule: | ||
| - cron: "21 3 * * *" | ||
| workflow_dispatch: | ||
| push: | ||
| branches: | ||
| - zhaez/nightly-build | ||
|  | ||
| env: | ||
| AWS_DEFAULT_REGION: us-east-1 | ||
| BRANCH_NAME: nightly-dependency-updates | ||
|  | ||
| permissions: | ||
| id-token: write | ||
| contents: write | ||
| pull-requests: write | ||
|  | ||
| jobs: | ||
| update-dependencies: | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| has_changes: ${{ steps.check_changes.outputs.has_changes }} | ||
| otel_python_version: ${{ steps.get_versions.outputs.otel_python_version }} | ||
| otel_contrib_version: ${{ steps.get_versions.outputs.otel_contrib_version }} | ||
| aws_sdk_ext_version: ${{ steps.get_versions.outputs.opentelemetry_sdk_extension_aws_version }} | ||
| aws_xray_prop_version: ${{ steps.get_versions.outputs.opentelemetry_propagator_aws_xray_version }} | ||
| breaking_changes_info: ${{ steps.breaking_changes.outputs.breaking_changes_info }} | ||
|  | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #5.0.0 | ||
| with: | ||
| fetch-depth: 0 | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
|  | ||
| - name: Set up Python | ||
| uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c #v6.0.0 | ||
| with: | ||
| python-version: '3.x' | ||
|  | ||
| - name: Install build tools | ||
| run: | | ||
| python -m pip install --upgrade pip | ||
| pip install toml requests packaging | ||
|  | ||
| - name: Get latest upstream versions | ||
| id: get_versions | ||
| run: python scripts/get_upstream_versions.py | ||
|  | ||
| - name: Check for breaking changes | ||
| id: breaking_changes | ||
| env: | ||
| OTEL_PYTHON_VERSION: ${{ steps.get_versions.outputs.otel_python_version }} | ||
| OTEL_CONTRIB_VERSION: ${{ steps.get_versions.outputs.otel_contrib_version }} | ||
|         
                  thpierce marked this conversation as resolved.
              Show resolved
            Hide resolved | ||
| run: python scripts/find_breaking_changes.py | ||
|  | ||
| - name: Setup Git | ||
| run: | | ||
| git config user.name "github-actions" | ||
| git config user.email "[email protected]" | ||
|  | ||
| - 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: Update dependencies | ||
| env: | ||
| OTEL_PYTHON_VERSION: ${{ steps.get_versions.outputs.otel_python_version }} | ||
| OTEL_CONTRIB_VERSION: ${{ steps.get_versions.outputs.otel_contrib_version }} | ||
| OPENTELEMETRY_SDK_EXTENSION_AWS_VERSION: ${{ steps.get_versions.outputs.opentelemetry_sdk_extension_aws_version }} | ||
| OPENTELEMETRY_PROPAGATOR_AWS_XRAY_VERSION: ${{ steps.get_versions.outputs.opentelemetry_propagator_aws_xray_version }} | ||
| run: python 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 . | ||
| git commit -m "chore: update OpenTelemetry dependencies to ${{ steps.get_versions.outputs.otel_python_version }}/${{ steps.get_versions.outputs.otel_contrib_version }}" | ||
| git push origin "$BRANCH_NAME" | ||
| fi | ||
|  | ||
| build-and-test: | ||
| needs: update-dependencies | ||
| if: needs.update-dependencies.outputs.has_changes == 'true' | ||
| uses: ./.github/workflows/main-build.yml | ||
| secrets: inherit | ||
| permissions: | ||
| id-token: write | ||
| contents: read | ||
| with: | ||
| ref: nightly-dependency-updates | ||
|  | ||
| create-pr: | ||
| needs: [update-dependencies, build-and-test] | ||
| if: always() && needs.update-dependencies.outputs.has_changes == 'true' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #5.0.0 | ||
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
|  | ||
| - name: Create or update PR | ||
| run: | | ||
| BUILD_STATUS="${{ needs.build-and-test.result }}" | ||
| BUILD_EMOJI="${{ needs.build-and-test.result == 'success' && '✅' || '❌' }}" | ||
| BUILD_LINK="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" | ||
|  | ||
| PR_BODY="Automated update of OpenTelemetry dependencies. | ||
|  | ||
| **Build Status:** ${BUILD_EMOJI} [${BUILD_STATUS}](${BUILD_LINK}) | ||
|  | ||
| **Updated versions:** | ||
| - [OpenTelemetry Python](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v${{ needs.update-dependencies.outputs.otel_python_version }}): ${{ needs.update-dependencies.outputs.otel_python_version }} | ||
| - [OpenTelemetry Contrib](https://github.com/open-telemetry/opentelemetry-python-contrib/releases/tag/v${{ needs.update-dependencies.outputs.otel_contrib_version }}): ${{ needs.update-dependencies.outputs.otel_contrib_version }} | ||
| - [opentelemetry-sdk-extension-aws](https://pypi.org/project/opentelemetry-sdk-extension-aws/${{ needs.update-dependencies.outputs.aws_sdk_ext_version }}/): ${{ needs.update-dependencies.outputs.aws_sdk_ext_version }} | ||
| - [opentelemetry-propagator-aws-xray](https://pypi.org/project/opentelemetry-propagator-aws-xray/${{ needs.update-dependencies.outputs.aws_xray_prop_version }}/): ${{ needs.update-dependencies.outputs.aws_xray_prop_version }} | ||
|  | ||
| **Upstream releases with breaking changes:** | ||
| Note: the mechanism to detect upstream breaking changes is not perfect. Be sure to check all new releases and understand if any additional changes need to be addressed. | ||
|  | ||
| ${{ needs.update-dependencies.outputs.breaking_changes_info }}" | ||
|  | ||
| 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 ${{ needs.update-dependencies.outputs.otel_python_version }}/${{ needs.update-dependencies.outputs.otel_contrib_version }}" \ | ||
| --body "$PR_BODY" \ | ||
| --base main \ | ||
| --head "$BRANCH_NAME" | ||
| fi | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
|  | ||
| publish-nightly-build-status: | ||
| name: "Publish Nightly Build Status" | ||
| needs: [ update-dependencies, build-and-test ] | ||
| runs-on: ubuntu-latest | ||
| if: always() | ||
| steps: | ||
| - name: Configure AWS Credentials for emitting metrics | ||
| uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #5.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'}}" | ||
|         
                  thpierce marked this conversation as resolved.
              Show resolved
            Hide resolved | ||
| 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 | ||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| #!/usr/bin/env python3 | ||
| # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|  | ||
| import os | ||
| import re | ||
| import sys | ||
|  | ||
| import requests | ||
| from packaging import version | ||
|  | ||
|  | ||
| def get_current_version_from_pyproject(): | ||
| """Extract current OpenTelemetry versions from pyproject.toml.""" | ||
| try: | ||
| with open("aws-opentelemetry-distro/pyproject.toml", "r", encoding="utf-8") as file: | ||
| content = file.read() | ||
|  | ||
| # Find first opentelemetry-api version (core version) | ||
| api_match = re.search(r'"opentelemetry-api == ([^"]*)"', content) | ||
| current_core_version = api_match.group(1) if api_match else None | ||
|  | ||
| # Find first opentelemetry-distro version (contrib version) | ||
| distro_match = re.search(r'"opentelemetry-distro == ([^"]*)"', content) | ||
| current_contrib_version = distro_match.group(1) if distro_match else None | ||
|  | ||
| return current_core_version, current_contrib_version | ||
|  | ||
| except (OSError, IOError) as error: | ||
| print(f"Error reading current versions: {error}") | ||
| return None, None | ||
|  | ||
|  | ||
| def get_releases_with_breaking_changes(repo, current_version, new_version): | ||
| """Get releases between current and new version that mention breaking changes.""" | ||
| try: | ||
| response = requests.get(f"https://api.github.com/repos/open-telemetry/{repo}/releases", timeout=30) | ||
| response.raise_for_status() | ||
|  | ||
| releases = response.json() | ||
| breaking_releases = [] | ||
|  | ||
| for release in releases: | ||
| release_version = release["tag_name"].lstrip("v") | ||
|  | ||
| # Check if this release is between current and new version | ||
| try: | ||
| if version.parse(release_version) > version.parse(current_version) and version.parse( | ||
|         
                  thpierce marked this conversation as resolved.
              Show resolved
            Hide resolved | ||
| release_version | ||
| ) <= version.parse(new_version): | ||
|  | ||
| # Check if release notes have breaking changes header or bold text | ||
| body = release.get("body", "") | ||
| if re.search(r"^(#+|\*\*)\s*breaking changes", body, re.MULTILINE | re.IGNORECASE): | ||
| breaking_releases.append( | ||
| { | ||
| "version": release_version, | ||
| "name": release["name"], | ||
| "url": release["html_url"], | ||
| "body": release.get("body", ""), | ||
| } | ||
| ) | ||
| except (ValueError, KeyError) as parse_error: | ||
| print(f"Warning: Skipping release {release.get('name', 'unknown')} due to error: {parse_error}") | ||
| continue | ||
|  | ||
| return breaking_releases | ||
|  | ||
| except requests.RequestException as request_error: | ||
| print(f"Error: Could not get releases for {repo}: {request_error}") | ||
| sys.exit(1) | ||
|  | ||
|  | ||
| def main(): | ||
| new_core_version = os.environ.get("OTEL_PYTHON_VERSION") | ||
| new_contrib_version = os.environ.get("OTEL_CONTRIB_VERSION") | ||
|  | ||
| if not new_core_version or not new_contrib_version: | ||
| print("Error: OTEL_PYTHON_VERSION and OTEL_CONTRIB_VERSION environment variables required") | ||
| sys.exit(1) | ||
|  | ||
| current_core_version, current_contrib_version = get_current_version_from_pyproject() | ||
|  | ||
| if not current_core_version or not current_contrib_version: | ||
| print("Could not determine current versions") | ||
| sys.exit(1) | ||
|  | ||
| print("Checking for breaking changes:") | ||
| print(f"Core: {current_core_version} → {new_core_version}") | ||
| print(f"Contrib: {current_contrib_version} → {new_contrib_version}") | ||
|  | ||
| # Check both repos for breaking changes | ||
| core_breaking = get_releases_with_breaking_changes("opentelemetry-python", current_core_version, new_core_version) | ||
| contrib_breaking = get_releases_with_breaking_changes( | ||
| "opentelemetry-python-contrib", current_contrib_version, new_contrib_version | ||
| ) | ||
|         
                  thpierce marked this conversation as resolved.
              Show resolved
            Hide resolved | ||
|  | ||
| # Output for GitHub Actions | ||
| breaking_info = "" | ||
|  | ||
| if core_breaking: | ||
| breaking_info += "**opentelemetry-python:**\n" | ||
| for release in core_breaking: | ||
| breaking_info += f"- [{release['name']}]({release['url']})\n" | ||
|  | ||
| if contrib_breaking: | ||
| breaking_info += "\n**opentelemetry-python-contrib:**\n" | ||
| for release in contrib_breaking: | ||
| breaking_info += f"- [{release['name']}]({release['url']})\n" | ||
|  | ||
| # Set GitHub output | ||
| if os.environ.get("GITHUB_OUTPUT"): | ||
| with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output_file: | ||
| output_file.write(f"breaking_changes_info<<EOF\n{breaking_info}EOF\n") | ||
|  | ||
|  | ||
| if __name__ == "__main__": | ||
| main() | ||
Uh oh!
There was an error while loading. Please reload this page.