diff --git a/.github/actions/cpUtility-testing/action.yml b/.github/actions/cpUtility-testing/action.yml index 883763ccdc..a59ad5ac05 100644 --- a/.github/actions/cpUtility-testing/action.yml +++ b/.github/actions/cpUtility-testing/action.yml @@ -25,28 +25,28 @@ runs: using: "composite" steps: - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 #3.6.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 #v3.11.1 with: driver-opts: image=moby/buildkit:v0.15.1 - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: role-to-assume: ${{ inputs.snapshot-ecr-role }} aws-region: ${{ inputs.aws-region }} - name: Login to private staging ecr - uses: docker/login-action@v3 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0 with: registry: ${{ inputs.image_registry }} env: AWS_REGION: ${{ inputs.aws-region }} - name: Build image for testing - uses: docker/build-push-action@v5 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0 with: push: false build-args: "ADOT_JAVA_VERSION=${{ inputs.adot-java-version }}" @@ -60,7 +60,7 @@ runs: run: .github/scripts/test-adot-javaagent-image.sh "${{ inputs.image_uri_with_tag }}" "${{ inputs.adot-java-version }}" - name: Build and push image - uses: docker/build-push-action@v5 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0 with: push: true build-args: "ADOT_JAVA_VERSION=${{ inputs.adot-java-version }}" diff --git a/.github/actions/image_scan/action.yml b/.github/actions/image_scan/action.yml index eb19f78609..9469dd7021 100644 --- a/.github/actions/image_scan/action.yml +++ b/.github/actions/image_scan/action.yml @@ -26,7 +26,7 @@ runs: run: docker logout public.ecr.aws - name: Run Trivy vulnerability scanner on image - uses: aquasecurity/trivy-action@master + uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 #v0.33.1 with: image-ref: ${{ inputs.image-ref }} severity: ${{ inputs.severity }} diff --git a/.github/actions/patch-dependencies/action.yml b/.github/actions/patch-dependencies/action.yml index 55399a6a02..5591d8b1ea 100644 --- a/.github/actions/patch-dependencies/action.yml +++ b/.github/actions/patch-dependencies/action.yml @@ -64,14 +64,14 @@ runs: shell: bash - name: Build opentelemetry-java with tests - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@a8f75513eafdebd8141bd1cd4e30fcd194af8dfa #v2 if: ${{ env.patch_otel_java == 'true' && inputs.run_tests != 'false' }} with: arguments: build publishToMavenLocal build-root-directory: opentelemetry-java - name: Build opentelemetry-java - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@a8f75513eafdebd8141bd1cd4e30fcd194af8dfa #v2 if: ${{ env.patch_otel_java == 'true' && inputs.run_tests == 'false' }} with: arguments: publishToMavenLocal @@ -83,14 +83,14 @@ runs: shell: bash - name: Build opentelemetry-java-contrib with tests - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@a8f75513eafdebd8141bd1cd4e30fcd194af8dfa #v2 if: ${{ env.patch_otel_java_contrib == 'true' && inputs.run_tests != 'false' }} with: arguments: build publishToMavenLocal build-root-directory: opentelemetry-java-contrib - name: Build opentelemetry-java-contrib - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@a8f75513eafdebd8141bd1cd4e30fcd194af8dfa #v2 if: ${{ env.patch_otel_java_contrib == 'true' && inputs.run_tests == 'false' }} with: arguments: publishToMavenLocal @@ -102,14 +102,14 @@ runs: shell: bash - name: Build opentelemetry-java-instrumentation with tests - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@a8f75513eafdebd8141bd1cd4e30fcd194af8dfa #v2 if: ${{ env.patch_otel_java_instrumentation == 'true' && inputs.run_tests != 'false' }} with: arguments: check -x spotlessCheck publishToMavenLocal build-root-directory: opentelemetry-java-instrumentation - name: Build opentelemetry java instrumentation - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@a8f75513eafdebd8141bd1cd4e30fcd194af8dfa #v2 if: ${{ env.patch_otel_java_instrumentation == 'true' && inputs.run_tests == 'false' }} with: arguments: publishToMavenLocal @@ -118,4 +118,4 @@ runs: - name: cleanup opentelmetry-java-instrumentation run: rm -rf opentelemetry-java-instrumentation if: ${{ env.patch_otel_java_instrumentation == 'true' }} - shell: bash \ No newline at end of file + shell: bash diff --git a/.github/workflows/application-signals-e2e-test.yml b/.github/workflows/application-signals-e2e-test.yml index e436bc82df..1f369b8316 100644 --- a/.github/workflows/application-signals-e2e-test.yml +++ b/.github/workflows/application-signals-e2e-test.yml @@ -26,12 +26,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #5.0.0 with: role-to-assume: arn:aws:iam::${{ secrets.APPLICATION_SIGNALS_E2E_TEST_ACCOUNT_ID }}:role/${{ secrets.APPLICATION_SIGNALS_E2E_TEST_ROLE_NAME }} aws-region: us-east-1 - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #5.0.0 with: name: aws-opentelemetry-agent.jar diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 024cef746b..a7f246cc84 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -23,21 +23,21 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #5.0.0 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@16df4fbc19aea13d921737861d6c622bf3cefe23 #v3.30.3 with: languages: java - - uses: actions/setup-java@v4 + - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: java-version: 17 distribution: temurin - name: Cache local Maven repository - uses: actions/cache@v3 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: path: | ~/.m2/repository/io/opentelemetry/ @@ -50,12 +50,47 @@ jobs: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} gpg_password: ${{ secrets.GPG_PASSPHRASE }} - - uses: gradle/wrapper-validation-action@v1 + - uses: gradle/actions/wrapper-validation@ed408507eac070d1f99cc633dbcf757c94c7933a # v4.4.3 - name: Manually build to avoid autobuild failures - uses: gradle/gradle-build-action@v3 + uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 #v3.5.0 with: arguments: build - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@16df4fbc19aea13d921737861d6c622bf3cefe23 #v3.30.3 + + all-codeql-checks-pass: + runs-on: ubuntu-latest + needs: [analyze] + if: always() + steps: + - name: Checkout to get workflow file + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #5.0.0 + + - name: Check all jobs succeeded and none missing + run: | + # Check if all needed jobs succeeded + results='${{ toJSON(needs) }}' + if echo "$results" | jq -r '.[] | .result' | grep -v success; then + echo "Some jobs failed" + exit 1 + fi + + # Extract all job names from workflow (excluding this gate job) + all_jobs=$(yq eval '.jobs | keys | .[]' .github/workflows/codeql.yml | grep -v "all-codeql-checks-pass" | sort) + + # Extract job names from needs array + needed_jobs='${{ toJSON(needs) }}' + needs_list=$(echo "$needed_jobs" | jq -r 'keys[]' | sort) + + # Check if any jobs are missing from needs + missing_jobs=$(comm -23 <(echo "$all_jobs") <(echo "$needs_list")) + if [ -n "$missing_jobs" ]; then + echo "ERROR: Jobs missing from needs array in all-codeql-checks-pass:" + echo "$missing_jobs" + echo "Please add these jobs to the needs array of all-codeql-checks-pass" + exit 1 + fi + + echo "All CodeQL checks passed and no jobs missing from gate!" diff --git a/.github/workflows/owasp.yml b/.github/workflows/daily-scan.yml similarity index 85% rename from .github/workflows/owasp.yml rename to .github/workflows/daily-scan.yml index 54ce812326..e3a5e1b57d 100644 --- a/.github/workflows/owasp.yml +++ b/.github/workflows/daily-scan.yml @@ -24,24 +24,24 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo for dependency scan - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #5.0.0 with: fetch-depth: 0 - name: Set up Java for dependency scan - uses: actions/setup-java@v4 + uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: java-version: 17 distribution: 'temurin' - name: Configure AWS credentials for dependency scan - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #5.0.0 with: role-to-assume: ${{ secrets.SECRET_MANAGER_ROLE_ARN }} aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Get NVD API key for dependency scan - uses: aws-actions/aws-secretsmanager-get-secrets@v1 + uses: aws-actions/aws-secretsmanager-get-secrets@a9a7eb4e2f2871d30dc5b892576fde60a2ecc802 #v2.0.10 id: nvd_api_key with: secret-ids: ${{ secrets.NVD_API_KEY_SECRET_ARN }} @@ -51,7 +51,7 @@ jobs: uses: ./.github/actions/patch-dependencies - name: Build JAR - uses: gradle/gradle-build-action@v3 + uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 #v3.5.0 with: arguments: assemble -PlocalDocker=true @@ -76,6 +76,17 @@ jobs: if: ${{ steps.dep_scan.outcome != 'success' }} run: less dependency-check-report.html + - name: Configure AWS credentials for image scan + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #5.0.0 + with: + role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} + + - name: Login to Public ECR + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0 + with: + registry: public.ecr.aws + - name: Perform high image scan on v1 if: always() id: high_scan_v1 @@ -110,7 +121,7 @@ jobs: - name: Configure AWS Credentials for emitting metrics if: always() - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #5.0.0 with: role-to-assume: ${{ secrets.METRICS_ROLE_ARN }} aws-region: ${{ env.AWS_DEFAULT_REGION }} diff --git a/.github/workflows/docker-build-corretto-slim.yml b/.github/workflows/docker-build-corretto-slim.yml index ca7528e241..6c61ffdd3a 100644 --- a/.github/workflows/docker-build-corretto-slim.yml +++ b/.github/workflows/docker-build-corretto-slim.yml @@ -19,24 +19,24 @@ jobs: build-corretto: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: gradle/wrapper-validation-action@v1 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #5.0.0 + - uses: gradle/actions/wrapper-validation@ed408507eac070d1f99cc633dbcf757c94c7933a # v4.4.3 - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #5.0.0 with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Log in to AWS ECR - uses: docker/login-action@v3 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0 with: registry: public.ecr.aws - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 #3.6.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 #v3.11.1 - name: Build docker image - uses: docker/build-push-action@v5 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #6.18.0 with: push: true context: scripts/docker/corretto-slim diff --git a/.github/workflows/docker-build-smoke-tests-fake-backend.yml b/.github/workflows/docker-build-smoke-tests-fake-backend.yml index 7bcb06a6fe..3f69d1be43 100644 --- a/.github/workflows/docker-build-smoke-tests-fake-backend.yml +++ b/.github/workflows/docker-build-smoke-tests-fake-backend.yml @@ -20,14 +20,14 @@ jobs: build-docker: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #5.0.0 + - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: java-version: 17 distribution: 'temurin' # cache local patch outputs - name: Cache local Maven repository - uses: actions/cache@v3 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: path: | ~/.m2/repository/io/opentelemetry/ @@ -38,18 +38,18 @@ jobs: with: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} gpg_password: ${{ secrets.GPG_PASSPHRASE }} - - uses: gradle/wrapper-validation-action@v1 + - uses: gradle/actions/wrapper-validation@ed408507eac070d1f99cc633dbcf757c94c7933a # v4.4.3 - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #5.0.0 with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Log in to AWS ECR - uses: docker/login-action@v3 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0 with: registry: public.ecr.aws - name: Build and push docker image - uses: gradle/gradle-build-action@v3 + uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 #v3.5.0 with: arguments: :smoke-tests:fakebackend:jib diff --git a/.github/workflows/e2e-tests-app-with-java-agent.yml b/.github/workflows/e2e-tests-app-with-java-agent.yml index d09283cb8f..3c61ae4069 100644 --- a/.github/workflows/e2e-tests-app-with-java-agent.yml +++ b/.github/workflows/e2e-tests-app-with-java-agent.yml @@ -25,11 +25,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Java Instrumentation repository - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: fetch-depth: 0 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: java-version: 17 distribution: temurin @@ -37,7 +37,7 @@ jobs: # cache local patch outputs - name: Cache local Maven repository id: cache-local-maven-repo - uses: actions/cache@v3 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: path: | ~/.m2/repository/io/opentelemetry/ @@ -51,27 +51,27 @@ jobs: gpg_password: ${{ secrets.GPG_PASSPHRASE }} - name: Validate the checksums of Gradle Wrapper - uses: gradle/wrapper-validation-action@v1 + uses: gradle/actions/wrapper-validation@ed408507eac070d1f99cc633dbcf757c94c7933a #v4.4.3 - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #5.0.0 with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Log in to AWS ECR - uses: docker/login-action@v3 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0 with: registry: public.ecr.aws - name: Build and push agent and testing docker images with Gradle - uses: gradle/gradle-build-action@v3 + uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 with: arguments: jib env: COMMIT_HASH: ${{ inputs.image_tag }} - - uses: codecov/codecov-action@v3 + - uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 #v5.5.1 test_Spring_App_With_Java_Agent: name: Test Spring App with AWS OTel Java agent @@ -79,19 +79,19 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: java-version: 17 distribution: 'temurin' - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Log in to AWS ECR - uses: docker/login-action@v3 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0 with: registry: public.ecr.aws @@ -110,19 +110,19 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: java-version: 17 distribution: 'temurin' - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Log in to AWS ECR - uses: docker/login-action@v3 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0 with: registry: public.ecr.aws @@ -141,19 +141,19 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: java-version: 17 distribution: 'temurin' - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Log in to AWS ECR - uses: docker/login-action@v3 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0 with: registry: public.ecr.aws diff --git a/.github/workflows/e2e-tests-with-operator.yml b/.github/workflows/e2e-tests-with-operator.yml index ffacf0c74c..ba5a136b2f 100644 --- a/.github/workflows/e2e-tests-with-operator.yml +++ b/.github/workflows/e2e-tests-with-operator.yml @@ -34,11 +34,11 @@ jobs: build-sample-app: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: fetch-depth: 0 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: java-version: 17 distribution: temurin @@ -46,7 +46,7 @@ jobs: # cache local patch outputs - name: Cache local Maven repository id: cache-local-maven-repo - uses: actions/cache@v3 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: path: | ~/.m2/repository/io/opentelemetry/ @@ -60,20 +60,21 @@ jobs: gpg_password: ${{ secrets.GPG_PASSPHRASE }} - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Log in to AWS ECR - uses: docker/login-action@v3 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0 with: registry: public.ecr.aws - name: Build and push Sample-Apps without Auto-Instrumentation Agent - uses: gradle/gradle-build-action@v3 - with: - arguments: jibBuildWithoutAgent + uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 + + - name: Build and push Sample-Apps with Auto-Instrumentation Agent + run: jibBuildWithoutAgent env: COMMIT_HASH: ${{ inputs.image_tag }} @@ -84,20 +85,20 @@ jobs: test-case-batch-value: ${{ steps.set-batches.outputs.batch-values }} steps: - name: Checkout Testing Framework repository - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: repository: ${{ env.TESTING_FRAMEWORK_REPO }} path: testing-framework ref: ${{ inputs.test_ref }} - name: Checkout Java Instrumentation repository - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: fetch-depth: 0 path: aws-otel-java-instrumentation - name: Set up Go 1.x - uses: actions/setup-go@v5 + uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 #v6.0.0 with: go-version: '~1.18.9' @@ -126,24 +127,24 @@ jobs: steps: # required for versioning - name: Checkout Java Instrumentation repository - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: fetch-depth: 0 path: aws-otel-java-instrumentation - name: Set up JDK 11 - uses: actions/setup-java@v4 + uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'zulu' java-version: '11' - name: Set up terraform - uses: hashicorp/setup-terraform@v3 + uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd #v3.1.2 with: terraform_version: "~1.5" - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: role-to-assume: ${{ secrets.JAVA_INSTRUMENTATION_INTEG_TEST_ARN}} aws-region: us-west-2 @@ -151,7 +152,7 @@ jobs: role-duration-seconds: 14400 - name: Checkout Testing Framework repository - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: repository: ${{ env.TESTING_FRAMEWORK_REPO }} path: testing-framework diff --git a/.github/workflows/main-build.yml b/.github/workflows/main-build.yml index 30c74f3c87..58748ce379 100644 --- a/.github/workflows/main-build.yml +++ b/.github/workflows/main-build.yml @@ -22,24 +22,24 @@ jobs: name: Test patches applied to dependencies runs-on: aws-otel-java-instrumentation_ubuntu-latest_32-core steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: java-version: 17 distribution: temurin # vaadin 14 tests fail with node 18 - name: Set up Node - uses: actions/setup-node@v4 + uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 #v5.0.0 with: node-version: 16 # vaadin tests use pnpm - name: Cache pnpm modules - uses: actions/cache@v3 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: path: ~/.pnpm-store key: ${{ runner.os }}-test-cache-pnpm-modules - - uses: gradle/wrapper-validation-action@v1 + - uses: gradle/actions/wrapper-validation@ed408507eac070d1f99cc633dbcf757c94c7933a #v4.4.3 - uses: ./.github/actions/patch-dependencies with: run_tests: "true" @@ -54,17 +54,17 @@ jobs: staging_registry: ${{ steps.imageOutput.outputs.stagingRegistry }} staging_repository: ${{ steps.imageOutput.outputs.stagingRepository }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: fetch-depth: 0 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: java-version: 17 distribution: temurin # cache local patch outputs - name: Cache local Maven repository - uses: actions/cache@v3 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: path: | ~/.m2/repository/io/opentelemetry/ @@ -76,21 +76,21 @@ jobs: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} gpg_password: ${{ secrets.GPG_PASSPHRASE }} - - uses: gradle/wrapper-validation-action@v1 + - uses: gradle/actions/wrapper-validation@ed408507eac070d1f99cc633dbcf757c94c7933a #v4.4.3 - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Log in to AWS ECR - uses: docker/login-action@v3 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0 with: registry: public.ecr.aws - name: Build snapshot with Gradle - uses: gradle/gradle-build-action@v3 + uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 #v3.5.0 with: arguments: build integrationTests snapshot --stacktrace -PenableCoverage=true -PlocalDocker=true env: @@ -128,7 +128,7 @@ jobs: snapshot-ecr-role: ${{ secrets.JAVA_INSTRUMENTATION_SNAPSHOT_ECR }} - name: Upload to GitHub Actions - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 with: name: aws-opentelemetry-agent.jar path: otelagent/build/libs/aws-opentelemetry-agent-*.jar @@ -189,30 +189,30 @@ jobs: runs-on: ubuntu-latest needs: build steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: fetch-depth: 0 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: java-version: 23 distribution: 'temurin' - - uses: gradle/wrapper-validation-action@v1 + - uses: gradle/actions/wrapper-validation@ed408507eac070d1f99cc633dbcf757c94c7933a #v4.4.3 - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Log in to AWS ECR - uses: docker/login-action@v3 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0 with: registry: public.ecr.aws # cache local patch outputs - name: Cache local Maven repository id: cache-local-maven-repo - uses: actions/cache@v3 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: path: | ~/.m2/repository/io/opentelemetry/ @@ -222,17 +222,17 @@ jobs: run: docker pull public.ecr.aws/docker/library/amazoncorretto:23-alpine - name: Build snapshot with Gradle - uses: gradle/gradle-build-action@v3 + uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 #v3.5.0 with: arguments: contractTests -PlocalDocker=true application-signals-lambda-layer-build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: fetch-depth: 0 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: java-version: 17 distribution: 'temurin' @@ -241,12 +241,12 @@ jobs: run: | ./build-layer.sh - name: Upload layer zip to GitHub Actions - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 with: name: aws-opentelemetry-java-layer.zip path: lambda-layer/build/distributions/aws-opentelemetry-java-layer.zip - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: role-to-assume: arn:aws:iam::${{ secrets.APPLICATION_SIGNALS_E2E_TEST_ACCOUNT_ID }}:role/${{ secrets.APPLICATION_SIGNALS_E2E_TEST_ROLE_NAME }} aws-region: us-east-1 @@ -256,6 +256,7 @@ jobs: aws s3 cp ./build/distributions/aws-opentelemetry-java-layer.zip s3://adot-main-build-staging-jar/adot-java-lambda-layer-${{ github.run_id }}.zip application-signals-e2e-test: + name: "Application Signals E2E Test" needs: [build, application-signals-lambda-layer-build] uses: ./.github/workflows/application-signals-e2e-test.yml secrets: inherit @@ -269,7 +270,7 @@ jobs: if: always() steps: - name: Configure AWS Credentials for emitting metrics - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: role-to-assume: ${{ secrets.METRICS_ROLE_ARN }} aws-region: us-east-1 diff --git a/.github/workflows/nightly-upstream-snapshot-build.yml b/.github/workflows/nightly-upstream-snapshot-build.yml index c97db6704c..df2f4251dd 100644 --- a/.github/workflows/nightly-upstream-snapshot-build.yml +++ b/.github/workflows/nightly-upstream-snapshot-build.yml @@ -23,18 +23,18 @@ jobs: image_name: ${{ steps.imageOutput.outputs.imageName }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: fetch-depth: 0 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: java-version: 17 distribution: 'temurin' # cache local patch outputs - name: Cache local Maven repository - uses: actions/cache@v3 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 with: path: | ~/.m2/repository/io/opentelemetry/ @@ -46,21 +46,21 @@ jobs: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} gpg_password: ${{ secrets.GPG_PASSPHRASE }} - - uses: gradle/wrapper-validation-action@v1 + - uses: gradle/actions/wrapper-validation@ed408507eac070d1f99cc633dbcf757c94c7933a # v4.4.3 - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Log in to AWS ECR - uses: docker/login-action@v3 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0 with: registry: public.ecr.aws - name: Build snapshot with Gradle - uses: gradle/gradle-build-action@v3 + uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 #v3.5.0 with: arguments: build --stacktrace -PenableCoverage=true -PtestUpstreamSnapshots=true env: @@ -95,7 +95,7 @@ jobs: snapshot-ecr-role: ${{ secrets.JAVA_INSTRUMENTATION_SNAPSHOT_ECR }} - name: Upload to GitHub Actions - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 with: name: aws-opentelemetry-agent.jar path: otelagent/build/libs/aws-opentelemetry-agent-*.jar @@ -129,23 +129,23 @@ jobs: runs-on: ubuntu-latest needs: build steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: fetch-depth: 0 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: java-version: 23 distribution: 'temurin' - - uses: gradle/wrapper-validation-action@v1 + - uses: gradle/actions/wrapper-validation@ed408507eac070d1f99cc633dbcf757c94c7933a # v4.4.3 - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Log in to AWS ECR - uses: docker/login-action@v3 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0 with: registry: public.ecr.aws @@ -153,7 +153,7 @@ jobs: run: docker pull public.ecr.aws/docker/library/amazoncorretto:23-alpine - name: Build snapshot with Gradle - uses: gradle/gradle-build-action@v3 + uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 #v3.5.0 with: arguments: contractTests -PtestUpstreamSnapshots=true -PlocalDocker=true diff --git a/.github/workflows/patch-release-build.yml b/.github/workflows/patch-release-build.yml index 4cbc3965fa..064bbf90b9 100644 --- a/.github/workflows/patch-release-build.yml +++ b/.github/workflows/patch-release-build.yml @@ -37,14 +37,14 @@ jobs: name: Check out release branch # Will fail if there is no release branch yet or succeed otherwise continue-on-error: true - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: ref: ${{ steps.parse-release-branch.outputs.release-branch-name }} - id: checkout-release-tag name: Check out release tag # If there is already a release branch, the previous step succeeds and we don't run this or the next one. if: ${{ steps.checkout-release-branch.outcome == 'failure' }} - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: ref: ${{ steps.parse-release-branch.outputs.release-tag-name }} - name: Create release branch @@ -57,21 +57,21 @@ jobs: needs: prepare-release-branch steps: - name: Checkout release branch - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: ref: ${{ needs.prepare-release-branch.outputs.release-branch-name }} - - uses: actions/setup-java@v4 + - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: java-version: 17 distribution: 'temurin' - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Log in to AWS ECR - uses: docker/login-action@v3 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0 with: registry: public.ecr.aws @@ -88,33 +88,32 @@ jobs: # Trim whitespaces and cherrypick echo $word | sed 's/ *$//g' | sed 's/^ *//g' | git cherry-pick --stdin done - - name: Build release with Gradle - uses: gradle/gradle-build-action@v3 + uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 #v3.5.0 with: arguments: build integrationTests -PlocalDocker=true -Prelease.version=${{ github.event.inputs.version }} --stacktrace - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN_RELEASE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} - name: Log in to AWS ECR - uses: docker/login-action@v3 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0 with: registry: public.ecr.aws - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 #3.6.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 #v3.11.1 with: driver-opts: image=moby/buildkit:v0.15.1 - name: Build image for testing - uses: docker/build-push-action@v5 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0 with: push: false build-args: "ADOT_JAVA_VERSION=${{ github.event.inputs.version }}" @@ -128,7 +127,7 @@ jobs: run: .github/scripts/test-adot-javaagent-image.sh "${{ env.TEST_TAG }}" "${{ github.event.inputs.version }}" - name: Build and push image - uses: docker/build-push-action@v5 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0 with: push: true build-args: "ADOT_JAVA_VERSION=${{ github.event.inputs.version }}" @@ -138,7 +137,7 @@ jobs: public.ecr.aws/aws-observability/adot-autoinstrumentation-java:v${{ github.event.inputs.version }} - name: Build and Publish release with Gradle - uses: gradle/gradle-build-action@v3 + uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 #v3.5.0 with: arguments: build final closeAndReleaseSonatypeStagingRepository -Prelease.version=${{ github.event.inputs.version }} --stacktrace env: diff --git a/.github/workflows/post-release-version-bump.yml b/.github/workflows/post-release-version-bump.yml new file mode 100644 index 0000000000..646c85d2d8 --- /dev/null +++ b/.github/workflows/post-release-version-bump.yml @@ -0,0 +1,146 @@ +name: Post Release - Prepare Main for Next Development Cycle + +on: + workflow_dispatch: + inputs: + version: + description: 'Version number (e.g., 1.0.1)' + required: true + is_patch: + description: 'Is this a patch? (true or false)' + required: true + default: 'false' + +env: + AWS_DEFAULT_REGION: us-east-1 + +permissions: + id-token: write + contents: write + pull-requests: write + +jobs: + check-version: + runs-on: ubuntu-latest + steps: + - name: Checkout main + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + with: + ref: main + fetch-depth: 0 + + - name: Extract Major.Minor Version and setup Env variable + run: | + echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV + echo "MAJOR_MINOR=$(echo ${{ github.event.inputs.version }} | sed -E 's/([0-9]+\.[0-9]+)\.[0-9]+/\1/')" >> $GITHUB_ENV + + - name: Get current major.minor version from main branch + id: get_version + run: | + CURRENT_VERSION=$(grep '__version__' aws-opentelemetry-distro/src/amazon/opentelemetry/distro/version.py | sed -E 's/__version__ = "([0-9]+\.[0-9]+)\.[0-9]+.*"/\1/') + echo "CURRENT_MAJOR_MINOR_VERSION=$CURRENT_VERSION" >> $GITHUB_ENV + + - name: Set major and minor for current version + run: | + echo "CURRENT_MAJOR=$(echo $CURRENT_MAJOR_MINOR_VERSION | cut -d. -f1)" >> $GITHUB_ENV + echo "CURRENT_MINOR=$(echo $CURRENT_MAJOR_MINOR_VERSION | cut -d. -f2)" >> $GITHUB_ENV + + - name: Set major and minor for input version + run: | + echo "INPUT_MAJOR=$(echo $MAJOR_MINOR | cut -d. -f1)" >> $GITHUB_ENV + echo "INPUT_MINOR=$(echo $MAJOR_MINOR | cut -d. -f2)" >> $GITHUB_ENV + + - name: Compare major.minor version and skip if behind + run: | + if [ "$CURRENT_MAJOR" -gt "$INPUT_MAJOR" ] || { [ "$CURRENT_MAJOR" -eq "$INPUT_MAJOR" ] && [ "$CURRENT_MINOR" -gt "$INPUT_MINOR" ]; }; then + echo "Input version is behind main's current major.minor version, don't need to update major version" + exit 1 + fi + + + prepare-main: + runs-on: ubuntu-latest + needs: check-version + steps: + - name: Configure AWS credentials for BOT secrets + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 + with: + role-to-assume: ${{ secrets.AWS_ROLE_ARN_SECRETS_MANAGER }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} + + - name: Get Bot secrets + uses: aws-actions/aws-secretsmanager-get-secrets@a9a7eb4e2f2871d30dc5b892576fde60a2ecc802 #v2.0.10 + id: bot_secrets + with: + secret-ids: | + BOT_TOKEN ,${{ secrets.BOT_TOKEN_SECRET_ARN }} + parse-json-secrets: true + + - name: Setup Git + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + with: + fetch-depth: 0 + token: ${{ env.BOT_TOKEN_GITHUB_RW_PATOKEN }} + + - name: Configure Git + run: | + git config user.name "github-actions" + git config user.email "github-actions@github.com" + + - name: Extract Major.Minor Version and setup Env variable + run: | + echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV + echo "MAJOR_MINOR=$(echo ${{ github.event.inputs.version }} | sed -E 's/([0-9]+\.[0-9]+)\.[0-9]+/\1/')" >> $GITHUB_ENV + + - name: Determine release branch and checkout + run: | + RELEASE_BRANCH="release/v${MAJOR_MINOR}.x" + git fetch origin $RELEASE_BRANCH + git checkout -b "prepare-main-for-next-dev-cycle-${VERSION}" origin/$RELEASE_BRANCH + + - name: Update version to next development version in main + run: | + DEV_VERSION="${{ github.event.inputs.version }}.dev0" + sed -i'' -e "s/val adotVersion = \".*\"/val adotVersion = \"${DEV_VERSION}\"/" version.gradle.kts + VERSION="${{ github.event.inputs.version }}" + sed -i'' -e 's/adot-autoinstrumentation-java:v2.*"/adot-autoinstrumentation-java:v'$VERSION'"/' .github/workflows/daily-scan.yml + + # for patch releases, avoid merge conflict by manually resolving CHANGELOG with main + if [[ "${{ github.event.inputs.is_patch }}" == "true" ]]; then + # Copy the patch release entries + sed -n "/^## v${VERSION}/,/^## v[0-9]/p" CHANGELOG.md | sed '$d' > /tmp/patch_release_section.txt + git fetch origin main + git show origin/main:CHANGELOG.md > CHANGELOG.md + # Insert the patch release entries after Unreleased + awk -i inplace '/^## v[0-9]/ && !inserted { system("cat /tmp/patch_release_section.txt"); inserted=1 } {print}' CHANGELOG.md + fi + + git add version.gradle.kts + git add .github/workflows/daily-scan.yml + git add CHANGELOG.md + git commit -m "Prepare main for next development cycle: Update version to $DEV_VERSION" + git push --set-upstream origin "prepare-main-for-next-dev-cycle-${VERSION}" + + - name: Create Pull Request to main + env: + GITHUB_TOKEN: ${{ env.BOT_TOKEN_GITHUB_RW_PATOKEN }} + run: | + DEV_VERSION="${{ github.event.inputs.version }}.dev0" + gh pr create --title "Post release $VERSION: Update version to $DEV_VERSION" \ + --body "This PR prepares the main branch for the next development cycle by updating the version to $DEV_VERSION and updating the image version to be scanned to the latest released. + + This PR should only be merge when release for version v$VERSION is success. + + By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice." \ + --head prepare-main-for-next-dev-cycle-${VERSION} \ + --base main + + - name: Force our CHANGELOG to override merge conflicts + run: | + git merge origin/main || true + git checkout --ours CHANGELOG.md + git add CHANGELOG.md + if ! git diff --quiet --cached; then + git commit -m "Force our CHANGELOG to override merge conflicts" + git push origin "prepare-main-for-next-dev-cycle-${VERSION}" + fi \ No newline at end of file diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml index fd2d7cf2ae..08a7ded962 100644 --- a/.github/workflows/pr-build.yml +++ b/.github/workflows/pr-build.yml @@ -1,6 +1,12 @@ name: PR Build on: pull_request: + types: + - opened + - reopened + - synchronize + - labeled + - unlabeled branches: - main - "release/v*" @@ -8,30 +14,85 @@ env: TEST_TAG: public.ecr.aws/aws-observability/adot-autoinstrumentation-java:test-v2 jobs: + static-code-checks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + fetch-depth: 0 + + - name: Check CHANGELOG + if: always() + run: | + # Check if PR is from workflows bot or dependabot + if [[ "${{ github.event.pull_request.user.login }}" == "aws-application-signals-bot" ]]; then + echo "Skipping check: PR from aws-application-signals-bot" + exit 0 + fi + + if [[ "${{ github.event.pull_request.user.login }}" == "dependabot[bot]" ]]; then + echo "Skipping check: PR from dependabot" + exit 0 + fi + + # Check for skip changelog label + if echo '${{ toJSON(github.event.pull_request.labels.*.name) }}' | jq -r '.[]' | grep -q "skip changelog"; then + echo "Skipping check: skip changelog label found" + exit 0 + fi + + # Fetch base branch and check for CHANGELOG modifications + git fetch origin ${{ github.base_ref }} + if git diff --name-only origin/${{ github.base_ref }}..HEAD | grep -q "CHANGELOG.md"; then + echo "CHANGELOG.md entry found - check passed" + exit 0 + fi + + 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." + exit 1 + + - name: Check for versioned GitHub actions + if: always() + run: | + # Get changed GitHub workflow/action files + CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}..HEAD | grep -E "^\.github/(workflows|actions)/.*\.ya?ml$" || true) + + if [ -n "$CHANGED_FILES" ]; then + # Check for any versioned actions, excluding comments and this validation script + VIOLATIONS=$(grep -Hn "uses:.*@v" $CHANGED_FILES | grep -v "grep.*uses:.*@v" | grep -v "#.*@v" || true) + if [ -n "$VIOLATIONS" ]; then + echo "Found versioned GitHub actions. Use commit SHAs instead:" + echo "$VIOLATIONS" + exit 1 + fi + fi + + echo "No versioned actions found in changed files" + testpatch: name: Test patches applied to dependencies runs-on: aws-otel-java-instrumentation_ubuntu-latest_32-core steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: java-version: 17 distribution: temurin # vaadin 14 tests fail with node 18 - name: Set up Node - uses: actions/setup-node@v4 + uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 with: node-version: 16 # vaadin tests use pnpm - name: Cache pnpm modules - uses: actions/cache@v3 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 with: path: ~/.pnpm-store key: ${{ runner.os }}-test-cache-pnpm-modules - - uses: gradle/wrapper-validation-action@v1 + - uses: gradle/actions/wrapper-validation@ed408507eac070d1f99cc633dbcf757c94c7933a # v4.4.3 - uses: ./.github/actions/patch-dependencies with: @@ -54,14 +115,14 @@ jobs: # https://github.com/open-telemetry/opentelemetry-java/issues/4560 - os: ${{ startsWith(github.event.pull_request.base.ref, 'release/v') && 'windows-latest' || '' }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: java-version: 17 distribution: temurin - - uses: gradle/wrapper-validation-action@v1 + - uses: gradle/actions/wrapper-validation@ed408507eac070d1f99cc633dbcf757c94c7933a # v4.4.3 # Cleanup directories before proceeding with setup - name: Clean up old installations @@ -72,7 +133,7 @@ jobs: # cache local patch outputs - name: Cache local Maven repository - uses: actions/cache@v3 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: path: | ~/.m2/repository/io/opentelemetry/ @@ -83,7 +144,7 @@ jobs: if: ${{ matrix.os != 'windows-latest' }} # Skip patch on windows as it is not possible to build opentelemetry-java on windows - name: Build with Gradle with Integration tests - uses: gradle/gradle-build-action@v3 + uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 if: ${{ matrix.os == 'ubuntu-latest' }} with: arguments: build integrationTests --stacktrace -PenableCoverage=true -PlocalDocker=true @@ -93,7 +154,7 @@ jobs: ./gradlew build -p exporters/aws-distro-opentelemetry-xray-udp-span-exporter - name: Set up Java version for tests - uses: actions/setup-java@v4 + uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: java-version: 23 distribution: temurin @@ -103,13 +164,13 @@ jobs: run: docker pull public.ecr.aws/docker/library/amazoncorretto:23-alpine - name: Run contract tests - uses: gradle/gradle-build-action@v3 + uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 #v3.5.0 if: ${{ matrix.os == 'ubuntu-latest' }} with: arguments: contractTests -PlocalDocker=true -i - name: Set up Java version for image build - uses: actions/setup-java@v4 + uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: java-version: 17 distribution: temurin @@ -121,17 +182,17 @@ jobs: echo "ADOT_JAVA_VERSION=$(./gradlew printVersion -q )" >> $GITHUB_ENV - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 #3.6.0 if: ${{ matrix.os == 'ubuntu-latest' }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 #v3.11.1 with: driver-opts: image=moby/buildkit:v0.15.1 if: ${{ matrix.os == 'ubuntu-latest' }} - name: Build image for testing - uses: docker/build-push-action@v5 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0 if: ${{ matrix.os == 'ubuntu-latest' }} with: push: false @@ -154,20 +215,20 @@ jobs: run: .github/scripts/test-adot-javaagent-image.sh "${{ env.TEST_TAG }}" "${{ env.ADOT_JAVA_VERSION }}" - name: Build with Gradle - uses: gradle/gradle-build-action@v3 + uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 #v3.5.0 if: ${{ matrix.os != 'ubuntu-latest' && (hashFiles('.github/patches/opentelemetry-java*.patch') == '' || matrix.os != 'windows-latest' ) }} # build on windows as well unless a patch exists with: arguments: build --stacktrace -PenableCoverage=true - - uses: codecov/codecov-action@v3 + - uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 #v5.5.1 build-lambda: runs-on: ubuntu-latest steps: - name: Checkout Repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 - name: Setup Java - uses: actions/setup-java@v4 + uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: java-version: 17 distribution: temurin @@ -176,3 +237,37 @@ jobs: working-directory: lambda-layer run: ./build-layer.sh + all-pr-checks-pass: + runs-on: ubuntu-latest + needs: [static-code-checks, testpatch, build, build-lambda] + if: always() + steps: + - name: Checkout to get workflow file + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #5.0.0 + + - name: Check all jobs succeeded and none missing + run: | + # Check if all needed jobs succeeded + results='${{ toJSON(needs) }}' + if echo "$results" | jq -r '.[] | .result' | grep -v success; then + echo "Some jobs failed" + exit 1 + fi + + # Extract all job names from workflow (excluding this gate job) + all_jobs=$(yq eval '.jobs | keys | .[]' .github/workflows/pr-build.yml | grep -v "all-pr-checks-pass" | sort) + + # Extract job names from needs array + needed_jobs='${{ toJSON(needs) }}' + needs_list=$(echo "$needed_jobs" | jq -r 'keys[]' | sort) + + # Check if any jobs are missing from needs + missing_jobs=$(comm -23 <(echo "$all_jobs") <(echo "$needs_list")) + if [ -n "$missing_jobs" ]; then + echo "ERROR: Jobs missing from needs array in all-pr-checks-pass:" + echo "$missing_jobs" + echo "Please add these jobs to the needs array of all-pr-checks-pass" + exit 1 + fi + + echo "All checks passed and no jobs missing from gate!" diff --git a/.github/workflows/pre-release-prepare.yml b/.github/workflows/pre-release-prepare.yml new file mode 100644 index 0000000000..4ef8a0ed0a --- /dev/null +++ b/.github/workflows/pre-release-prepare.yml @@ -0,0 +1,114 @@ +name: Pre Release Prepare - Update Version and Create PR + +on: + workflow_dispatch: + inputs: + version: + description: 'Version number (e.g., 1.0.1)' + required: true + is_patch: + description: 'Is this a patch? (true or false)' + required: true + default: 'false' + +env: + AWS_DEFAULT_REGION: us-east-1 + +permissions: + contents: write + pull-requests: write + id-token: write + + +jobs: + update-version-and-create-pr: + runs-on: ubuntu-latest + steps: + - name: Configure AWS credentials for BOT secrets + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 + with: + role-to-assume: ${{ secrets.AWS_ROLE_ARN_SECRETS_MANAGER }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} + + - name: Get Bot secrets + uses: aws-actions/aws-secretsmanager-get-secrets@a9a7eb4e2f2871d30dc5b892576fde60a2ecc802 #v2.0.10 + id: bot_secrets + with: + secret-ids: | + BOT_TOKEN ,${{ secrets.BOT_TOKEN_SECRET_ARN }} + parse-json-secrets: true + + - name: Checkout main branch + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + with: + ref: 'main' + token: ${{ env.BOT_TOKEN_GITHUB_RW_PATOKEN }} + + - name: Setup Git + run: | + git config user.name "github-actions" + git config user.email "github-actions@github.com" + + - name: Extract Major.Minor Version and setup Env variable + run: | + echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV + echo "MAJOR_MINOR=$(echo ${{ github.event.inputs.version }} | sed -E 's/([0-9]+\.[0-9]+)\.[0-9]+/\1/')" >> $GITHUB_ENV + + - name: Create branches + run: | + IS_PATCH=${{ github.event.inputs.is_patch }} + if [[ "$IS_PATCH" != "true" && "$IS_PATCH" != "false" ]]; then + echo "Invalid input for IS_PATCH. Must be 'true' or 'false'." + exit 1 + fi + + + if git ls-remote --heads origin release/v${MAJOR_MINOR}.x | grep -q "release/v${MAJOR_MINOR}.x"; then + if [ "$IS_PATCH" = "true" ]; then + git fetch origin release/v${MAJOR_MINOR}.x + echo "Branch release/v${MAJOR_MINOR}.x already exists, checking out." + git checkout "release/v${MAJOR_MINOR}.x" + else + echo "Error, release series branch release/v${MAJOR_MINOR}.x exist for non-patch release" + echo "Check your input or branch" + exit 1 + fi + else + if [ "$IS_PATCH" = "true" ]; then + echo "Error, release series branch release/v${MAJOR_MINOR}.x NOT exist for patch release" + echo "Check your input or branch" + exit 1 + else + echo "Creating branch release/v${MAJOR_MINOR}.x." + git checkout -b "release/v${MAJOR_MINOR}.x" + git push origin "release/v${MAJOR_MINOR}.x" + fi + fi + + git checkout -b "v${VERSION}_release" + git push origin "v${VERSION}_release" + + - name: Update version in file + run: | + sed -i'' -e "s/val adotVersion = \".*\"/val adotVersion = \"${VERSION}\"/" version.gradle.kts + git commit -am "Update version to ${VERSION}" + git push origin "v${VERSION}_release" + + - name: Update CHANGELOG for release + if: github.event.inputs.is_patch != 'true' + run: | + sed -i "s/## Unreleased/## Unreleased\n\n## v${VERSION} - $(date +%Y-%m-%d)/" CHANGELOG.md + git add CHANGELOG.md + git commit -m "Update CHANGELOG for version ${VERSION}" + git push origin "v${VERSION}_release" + + - name: Create pull request against the release branch + env: + GITHUB_TOKEN: ${{ env.BOT_TOKEN_GITHUB_RW_PATOKEN }} + run: | + gh pr create --title "Pre-release: Update version to ${VERSION}" \ + --body "This PR updates the version to ${VERSION}. + + By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice." \ + --head v${{ github.event.inputs.version }}_release \ + --base release/v${MAJOR_MINOR}.x \ No newline at end of file diff --git a/.github/workflows/publish-status.yml b/.github/workflows/publish-status.yml index 1efeb9c04d..5159e2bddf 100644 --- a/.github/workflows/publish-status.yml +++ b/.github/workflows/publish-status.yml @@ -37,7 +37,7 @@ jobs: contents: read steps: - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: role-to-assume: ${{ secrets.roleArn }} aws-region: ${{ inputs.region }} diff --git a/.github/workflows/release-build.yml b/.github/workflows/release-build.yml index ce9d29ddc8..fb60d124e7 100644 --- a/.github/workflows/release-build.yml +++ b/.github/workflows/release-build.yml @@ -24,12 +24,30 @@ jobs: environment: Release runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + + - name: Check main build status + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + WORKFLOW_ID=$(gh api repos/${{ github.repository }}/actions/workflows --jq '.workflows[] | select(.name=="Java Agent Main Build") | .id') + LATEST_RUN=$(gh api repos/${{ github.repository }}/actions/workflows/$WORKFLOW_ID/runs --jq '[.workflow_runs[] | select(.head_branch=="${{ github.ref_name }}")] | sort_by(.created_at) | .[-1] | {conclusion, status}') + STATUS=$(echo "$LATEST_RUN" | jq -r '.status') + CONCLUSION=$(echo "$LATEST_RUN" | jq -r '.conclusion') + + if [ "$STATUS" = "in_progress" ] || [ "$STATUS" = "queued" ]; then + echo "Main build is still running (status: $STATUS). Cannot proceed with release." + exit 1 + elif [ "$CONCLUSION" != "success" ]; then + echo "Latest main build on branch ${{ github.ref_name }} conclusion: $CONCLUSION" + exit 1 + fi + echo "Main build succeeded, proceeding with release" + - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: java-version: 17 distribution: 'temurin' - - uses: gradle/wrapper-validation-action@v1 + - uses: gradle/actions/wrapper-validation@ed408507eac070d1f99cc633dbcf757c94c7933a # v4.4.3 - name: Publish patched dependencies to maven local uses: ./.github/actions/patch-dependencies @@ -38,53 +56,53 @@ jobs: gpg_password: ${{ secrets.GPG_PASSPHRASE }} - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} aws-region: ${{ env.AWS_PUBLIC_ECR_REGION }} - name: Log in to AWS ECR - uses: docker/login-action@v3 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0 with: registry: public.ecr.aws - name: Build release with Gradle - uses: gradle/gradle-build-action@v3 + uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 #v3.5.0 with: arguments: build integrationTests -PlocalDocker=true -Prelease.version=${{ github.event.inputs.version }} --stacktrace - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN_RELEASE }} aws-region: ${{ env.AWS_PUBLIC_ECR_REGION }} - name: Log in to AWS ECR - uses: docker/login-action@v3 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0 with: registry: public.ecr.aws - name: Configure AWS Credentials for Private ECR - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN_RELEASE }} aws-region: ${{ env.AWS_PRIVATE_ECR_REGION }} - name: Log in to AWS private ECR - uses: docker/login-action@v3 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0 with: registry: ${{ env.PRIVATE_REGISTRY }} - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 #3.6.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 #v3.11.1 with: driver-opts: image=moby/buildkit:v0.15.1 - name: Build image for testing - uses: docker/build-push-action@v5 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0 with: push: false build-args: "ADOT_JAVA_VERSION=${{ github.event.inputs.version }}" @@ -98,7 +116,7 @@ jobs: run: .github/scripts/test-adot-javaagent-image.sh "${{ env.TEST_TAG }}" "${{ github.event.inputs.version }}" - name: Build and push image - uses: docker/build-push-action@v5 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0 with: push: true build-args: "ADOT_JAVA_VERSION=${{ github.event.inputs.version }}" @@ -109,7 +127,7 @@ jobs: ${{ env.PRIVATE_REPOSITORY }}:v${{ github.event.inputs.version }} - name: Build and Publish release with Gradle - uses: gradle/gradle-build-action@v3 + uses: gradle/actions/setup-gradle@d9c87d481d55275bb5441eef3fe0e46805f9ef70 #v3.5.0 with: arguments: build final closeAndReleaseSonatypeStagingRepository -Prelease.version=${{ github.event.inputs.version }} --stacktrace env: diff --git a/.github/workflows/release-lambda.yml b/.github/workflows/release-lambda.yml index ede635ec91..37b100d7ce 100644 --- a/.github/workflows/release-lambda.yml +++ b/.github/workflows/release-lambda.yml @@ -41,9 +41,9 @@ jobs: echo "aws_regions_json=${MATRIX}" >> $GITHUB_OUTPUT - name: Checkout Repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: java-version: 17 distribution: 'temurin' @@ -54,7 +54,7 @@ jobs: ./build-layer.sh - name: Upload layer - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 with: name: aws-opentelemetry-java-layer.zip path: lambda-layer/build/distributions/aws-opentelemetry-java-layer.zip @@ -88,7 +88,7 @@ jobs: SECRET_KEY=${SECRET_KEY//-/_} echo "SECRET_KEY=${SECRET_KEY}" >> $GITHUB_ENV - - uses: aws-actions/configure-aws-credentials@v4.0.2 + - uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: role-to-assume: ${{ secrets[env.SECRET_KEY] }} role-duration-seconds: 1200 @@ -99,7 +99,7 @@ jobs: echo BUCKET_NAME=java-lambda-layer-${{ github.run_id }}-${{ matrix.aws_region }} | tee --append $GITHUB_ENV - name: download layer.zip - uses: actions/download-artifact@v4 + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: aws-opentelemetry-java-layer.zip @@ -140,7 +140,7 @@ jobs: - name: upload layer arn artifact if: ${{ success() }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 with: name: ${{ env.LAYER_NAME }}-${{ matrix.aws_region }} path: ${{ env.LAYER_NAME }}/${{ matrix.aws_region }} @@ -155,12 +155,10 @@ jobs: needs: publish-prod steps: - name: Checkout Repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 - - - uses: hashicorp/setup-terraform@v2 - + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + - uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd #v3.1.2 - name: download layerARNs - uses: actions/download-artifact@v4 + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: pattern: ${{ env.LAYER_NAME }}-* path: ${{ env.LAYER_NAME }} @@ -211,7 +209,7 @@ jobs: echo "}" >> ../layer_cdk cat ../layer_cdk - name: download aws-opentelemetry-java-layer.zip - uses: actions/download-artifact@v4 + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: aws-opentelemetry-java-layer.zip - name: rename to layer.zip diff --git a/.github/workflows/release-udp-exporter.yml b/.github/workflows/release-udp-exporter.yml index e200a7c3a9..30d1a2e4dc 100644 --- a/.github/workflows/release-udp-exporter.yml +++ b/.github/workflows/release-udp-exporter.yml @@ -26,10 +26,10 @@ jobs: needs: validate-udp-exporter-e2e-test steps: - name: Checkout Repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 - name: Set up Java - uses: actions/setup-java@v3 + uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/soak-testing.yml b/.github/workflows/soak-testing.yml index c007d3fb4e..2dcd07d709 100644 --- a/.github/workflows/soak-testing.yml +++ b/.github/workflows/soak-testing.yml @@ -63,7 +63,7 @@ jobs: run: | echo "TEST_DURATION_MINUTES=${{ github.event.inputs.test_duration_minutes || env.DEFAULT_TEST_DURATION_MINUTES }}" | tee --append $GITHUB_ENV; - name: Clone This Repo @ ${{ env.TARGET_SHA }} - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: ref: ${{ env.TARGET_SHA }} @@ -98,7 +98,7 @@ jobs: # MARK: - Run Performance Tests - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 # v5.0.0 with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} role-duration-seconds: 21600 # 6 Hours @@ -110,7 +110,7 @@ jobs: aws ecr-public get-login-password | docker login --username AWS --password-stdin public.ecr.aws - name: Build Sample App locally directly to the Docker daemon - uses: burrunan/gradle-cache-action@v1 + uses: burrunan/gradle-cache-action@4a07779efc8120348ea6dfd35314bc30a586eb0f #v3.0.1 with: arguments: jibDockerBuild env: @@ -210,7 +210,7 @@ jobs: git checkout main; [[ $HAS_RESULTS_ALREADY == true ]] - name: Graph and Report Performance Test Averages result - uses: benchmark-action/github-action-benchmark@v1 + uses: benchmark-action/github-action-benchmark@4bdcce38c94cec68da58d012ac24b7b1155efe8b #v1.20.7 continue-on-error: true id: check-failure-after-performance-tests with: @@ -230,7 +230,7 @@ jobs: gh-pages-branch: gh-pages benchmark-data-dir-path: soak-tests/per-commit-overall-results - name: Publish Issue if failed DURING Performance Tests - uses: JasonEtco/create-an-issue@v2 + uses: JasonEtco/create-an-issue@1b14a70e4d8dc185e5cc76d3bec9eab20257b2c5 # v2.9.2 if: ${{ github.event_name == 'schedule' && steps.check-failure-during-performance-tests.outcome == 'failure' }} env: @@ -241,7 +241,7 @@ jobs: filename: .github/auto-issue-templates/failure-during-soak_tests.md update_existing: true - name: Publish Issue if failed AFTER Performance Tests - uses: JasonEtco/create-an-issue@v2 + uses: JasonEtco/create-an-issue@1b14a70e4d8dc185e5cc76d3bec9eab20257b2c5 #v2.9.2 if: ${{ github.event_name == 'schedule' && steps.check-failure-after-performance-tests.outcome == 'failure' }} env: diff --git a/.github/workflows/stale-bot.yml b/.github/workflows/stale-bot.yml index 2104ad0b4f..49ddc47c00 100644 --- a/.github/workflows/stale-bot.yml +++ b/.github/workflows/stale-bot.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Mark the issues/pr - uses: actions/stale@v9 + uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f #10.0.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} #Github workflow will add a temporary token when executing the workflow with: diff --git a/.github/workflows/udp-exporter-e2e-test.yml b/.github/workflows/udp-exporter-e2e-test.yml index ead8a1f953..79a9af8a85 100644 --- a/.github/workflows/udp-exporter-e2e-test.yml +++ b/.github/workflows/udp-exporter-e2e-test.yml @@ -13,17 +13,17 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Repo @ SHA - ${{ github.sha }} - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Set up Java - uses: actions/setup-java@v3 + uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: java-version: '17' distribution: 'temurin' cache: 'gradle' - name: Configure AWS credentials for Testing Tracing - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 # v5.0.0 with: role-to-assume: ${{ secrets.XRAY_UDP_EXPORTER_TEST_ROLE }} aws-region: 'us-east-1' diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..95b00f9d78 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,19 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +> **Note:** This CHANGELOG was created starting after version 2.11.5. Earlier changes are not documented here. + +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: + +- add SigV4 authentication for HTTP exporter + ([#1019](https://github.com/aws-observability/aws-otel-java-instrumentation/pull/1019)) + +If your change does not need a CHANGELOG entry, add the "skip changelog" label to your PR. + +## Unreleased + +### Enhancements + +- Support X-Ray Trace Id extraction from Lambda Context object, and respect user-configured OTEL_PROPAGATORS in AWS Lamdba instrumentation + ([#1191](https://github.com/aws-observability/aws-otel-java-instrumentation/pull/1191)) ([#1218](https://github.com/aws-observability/aws-otel-java-instrumentation/pull/1218)) diff --git a/Dockerfile b/Dockerfile index 1390f9d2c5..6f05e46a31 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,7 +31,7 @@ ARG TARGETARCH RUN if [ $TARGETARCH = "amd64" ]; then rustup component add rustfmt && cargo fmt --check ; fi ## Audit dependencies -RUN if [ $TARGETARCH = "amd64" ]; then cargo install cargo-audit && cargo audit ; fi +RUN if [ $TARGETARCH = "amd64" ]; then cargo install cargo-audit --locked && cargo audit ; fi # Cross-compile based on the target platform. diff --git a/lambda-layer/otel-instrument b/lambda-layer/otel-instrument index 662520d8b4..06dd6f1ec6 100644 --- a/lambda-layer/otel-instrument +++ b/lambda-layer/otel-instrument @@ -2,7 +2,7 @@ export OTEL_INSTRUMENTATION_AWS_SDK_EXPERIMENTAL_SPAN_ATTRIBUTES=true -export OTEL_PROPAGATORS="${OTEL_PROPAGATORS:-baggage,xray,tracecontext}" +export OTEL_PROPAGATORS="${OTEL_PROPAGATORS:-baggage,tracecontext,xray}" export OTEL_SERVICE_NAME=${OTEL_SERVICE_NAME:-${AWS_LAMBDA_FUNCTION_NAME}} diff --git a/lambda-layer/patches/StreamHandlerInstrumentation.patch b/lambda-layer/patches/StreamHandlerInstrumentation.patch index c4d4751c89..58acda91cd 100644 --- a/lambda-layer/patches/StreamHandlerInstrumentation.patch +++ b/lambda-layer/patches/StreamHandlerInstrumentation.patch @@ -4,18 +4,18 @@ index 35d6b70ed6..b6a305178e 100644 +++ b/instrumentation/aws-lambda/aws-lambda-core-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdacore/v1_0/AwsLambdaInstrumentationModule.java @@ -6,17 +6,18 @@ package io.opentelemetry.javaagent.instrumentation.awslambdacore.v1_0; - + import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; -import static java.util.Collections.singletonList; import static net.bytebuddy.matcher.ElementMatchers.not; - + import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import java.util.Arrays; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; - + @AutoService(InstrumentationModule.class) public class AwsLambdaInstrumentationModule extends InstrumentationModule { + @@ -23,7 +23,7 @@ index 35d6b70ed6..b6a305178e 100644 super("aws-lambda-core", "aws-lambda-core-1.0", "aws-lambda"); } @@ -34,6 +35,8 @@ public class AwsLambdaInstrumentationModule extends InstrumentationModule { - + @Override public List typeInstrumentations() { - return singletonList(new AwsLambdaRequestHandlerInstrumentation()); @@ -32,9 +32,22 @@ index 35d6b70ed6..b6a305178e 100644 + new AwsLambdaRequestStreamHandlerInstrumentation()); } } +diff --git a/instrumentation/aws-lambda/aws-lambda-core-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdacore/v1_0/AwsLambdaRequestHandlerInstrumentation.java b/instrumentation/aws-lambda/aws-lambda-core-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdacore/v1_0/AwsLambdaRequestHandlerInstrumentation.java +index 93071e04d2..add9f64276 100644 +--- a/instrumentation/aws-lambda/aws-lambda-core-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdacore/v1_0/AwsLambdaRequestHandlerInstrumentation.java ++++ b/instrumentation/aws-lambda/aws-lambda-core-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdacore/v1_0/AwsLambdaRequestHandlerInstrumentation.java +@@ -68,7 +68,7 @@ public class AwsLambdaRequestHandlerInstrumentation implements TypeInstrumentati + @Advice.Local("otelContext") io.opentelemetry.context.Context otelContext, + @Advice.Local("otelScope") Scope otelScope) { + input = AwsLambdaRequest.create(context, arg, Collections.emptyMap()); +- io.opentelemetry.context.Context parentContext = functionInstrumenter().extract(input); ++ io.opentelemetry.context.Context parentContext = functionInstrumenter().extract(input, context); + + if (!functionInstrumenter().shouldStart(parentContext, input)) { + return; diff --git a/instrumentation/aws-lambda/aws-lambda-core-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdacore/v1_0/AwsLambdaRequestStreamHandlerInstrumentation.java b/instrumentation/aws-lambda/aws-lambda-core-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdacore/v1_0/AwsLambdaRequestStreamHandlerInstrumentation.java new file mode 100644 -index 0000000000..1c4ef1ac07 +index 0000000000..1a8fd8f986 --- /dev/null +++ b/instrumentation/aws-lambda/aws-lambda-core-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdacore/v1_0/AwsLambdaRequestStreamHandlerInstrumentation.java @@ -0,0 +1,98 @@ @@ -109,7 +122,7 @@ index 0000000000..1c4ef1ac07 + @Advice.Local("otelScope") Scope otelScope) { + + otelInput = AwsLambdaRequest.create(context, input, Collections.emptyMap()); -+ io.opentelemetry.context.Context parentContext = functionInstrumenter().extract(otelInput); ++ io.opentelemetry.context.Context parentContext = functionInstrumenter().extract(otelInput, context); + + if (!functionInstrumenter().shouldStart(parentContext, otelInput)) { + return; @@ -261,19 +274,19 @@ index 9e0e372241..2dd6051c23 100644 +++ b/instrumentation/aws-lambda/aws-lambda-events-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdaevents/v2_2/AwsLambdaInstrumentationModule.java @@ -6,11 +6,11 @@ package io.opentelemetry.javaagent.instrumentation.awslambdaevents.v2_2; - + import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; -import static java.util.Collections.singletonList; - + import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import java.util.Arrays; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; - + @@ -32,6 +32,8 @@ public class AwsLambdaInstrumentationModule extends InstrumentationModule { - + @Override public List typeInstrumentations() { - return singletonList(new AwsLambdaRequestHandlerInstrumentation()); @@ -282,9 +295,22 @@ index 9e0e372241..2dd6051c23 100644 + new AwsLambdaRequestStreamHandlerInstrumentation()); } } +diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdaevents/v2_2/AwsLambdaRequestHandlerInstrumentation.java b/instrumentation/aws-lambda/aws-lambda-events-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdaevents/v2_2/AwsLambdaRequestHandlerInstrumentation.java +index e059250807..1fa80c3735 100644 +--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdaevents/v2_2/AwsLambdaRequestHandlerInstrumentation.java ++++ b/instrumentation/aws-lambda/aws-lambda-events-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdaevents/v2_2/AwsLambdaRequestHandlerInstrumentation.java +@@ -70,7 +70,7 @@ public class AwsLambdaRequestHandlerInstrumentation implements TypeInstrumentati + } + input = AwsLambdaRequest.create(context, arg, headers); + io.opentelemetry.context.Context parentContext = +- AwsLambdaInstrumentationHelper.functionInstrumenter().extract(input); ++ AwsLambdaInstrumentationHelper.functionInstrumenter().extract(input, context); + + if (!AwsLambdaInstrumentationHelper.functionInstrumenter() + .shouldStart(parentContext, input)) { diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdaevents/v2_2/AwsLambdaRequestStreamHandlerInstrumentation.java b/instrumentation/aws-lambda/aws-lambda-events-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdaevents/v2_2/AwsLambdaRequestStreamHandlerInstrumentation.java new file mode 100644 -index 0000000000..f21a4a5526 +index 0000000000..ab6d9aa5ba --- /dev/null +++ b/instrumentation/aws-lambda/aws-lambda-events-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdaevents/v2_2/AwsLambdaRequestStreamHandlerInstrumentation.java @@ -0,0 +1,104 @@ @@ -353,7 +379,7 @@ index 0000000000..f21a4a5526 + @Advice.Local("otelMessageScope") Scope messageScope) { + otelInput = AwsLambdaRequest.create(context, input, Collections.emptyMap()); + io.opentelemetry.context.Context parentContext = -+ AwsLambdaInstrumentationHelper.functionInstrumenter().extract(otelInput); ++ AwsLambdaInstrumentationHelper.functionInstrumenter().extract(otelInput, context); + + if (!AwsLambdaInstrumentationHelper.functionInstrumenter() + .shouldStart(parentContext, otelInput)) { diff --git a/lambda-layer/patches/opentelemetry-java-instrumentation.patch b/lambda-layer/patches/opentelemetry-java-instrumentation.patch index cca35f0ed0..f0f7e0afe6 100644 --- a/lambda-layer/patches/opentelemetry-java-instrumentation.patch +++ b/lambda-layer/patches/opentelemetry-java-instrumentation.patch @@ -1,5 +1,49 @@ +diff --git a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/build.gradle.kts b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/build.gradle.kts +index 4fcb6700fd..e1a12093df 100644 +--- a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/build.gradle.kts ++++ b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/build.gradle.kts +@@ -5,11 +5,12 @@ plugins { + dependencies { + compileOnly("io.opentelemetry:opentelemetry-sdk") + compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure") ++ compileOnly(project(":muzzle")) + + compileOnly("com.google.auto.value:auto-value-annotations") + annotationProcessor("com.google.auto.value:auto-value") + +- library("com.amazonaws:aws-lambda-java-core:1.0.0") ++ library("com.amazonaws:aws-lambda-java-core:1.4.0") + + // We do lightweight parsing of JSON to extract HTTP headers from requests for propagation. + // This will be commonly needed even for users that don't use events, but luckily it's not too big. +diff --git a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/TracingRequestHandler.java b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/TracingRequestHandler.java +index 873040f66e..b38648e8cf 100644 +--- a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/TracingRequestHandler.java ++++ b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/TracingRequestHandler.java +@@ -66,7 +66,7 @@ public abstract class TracingRequestHandler implements RequestHandler headers = input.getHeaders(); if (input.getAwsContext() != null && input.getAwsContext().getClientContext() != null) { -@@ -59,23 +57,15 @@ public class AwsLambdaFunctionInstrumenter { +@@ -59,23 +58,15 @@ public class AwsLambdaFunctionInstrumenter { } } - + - return openTelemetry - .getPropagators() - .getTextMapPropagator() - .extract(Context.root(), headers, MapGetter.INSTANCE); -+ return ParentContextExtractor.extract(headers, this); ++ return ParentContextExtractor.extract(headers, this, lambdaContext); } - + - private enum MapGetter implements TextMapGetter> { - INSTANCE; - @@ -58,7 +105,7 @@ index 9341bf6f79..2208c3c482 100644 - } + public Context extract(Map headers, TextMapGetter> getter) { + ContextPropagationDebug.debugContextLeakIfEnabled(); - + - @Override - public String get(Map map, String s) { - return map.get(s.toLowerCase(Locale.ROOT)); @@ -71,10 +118,10 @@ index 9341bf6f79..2208c3c482 100644 } diff --git a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/ParentContextExtractor.java b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/ParentContextExtractor.java new file mode 100644 -index 0000000000..439ed0de07 +index 0000000000..6349d1bb29 --- /dev/null +++ b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/ParentContextExtractor.java -@@ -0,0 +1,77 @@ +@@ -0,0 +1,85 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 @@ -84,13 +131,12 @@ index 0000000000..439ed0de07 + +import static io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.MapUtils.lowercaseMap; + -+import io.opentelemetry.api.trace.Span; -+import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.propagation.TextMapGetter; -+import java.util.Collections; ++import io.opentelemetry.javaagent.tooling.muzzle.NoMuzzle; +import java.util.Locale; +import java.util.Map; ++import java.util.logging.Logger; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at @@ -98,44 +144,53 @@ index 0000000000..439ed0de07 + */ +public final class ParentContextExtractor { + ++ private static final Logger logger = Logger.getLogger(ParentContextExtractor.class.getName()); + private static final String AWS_TRACE_HEADER_ENV_KEY = "_X_AMZN_TRACE_ID"; + private static final String AWS_TRACE_HEADER_PROP = "com.amazonaws.xray.traceHeader"; + // lower-case map getter used for extraction + static final String AWS_TRACE_HEADER_PROPAGATOR_KEY = "x-amzn-trace-id"; ++ static boolean getXrayTraceIdMethodExists = true; + -+ static Context extract(Map headers, AwsLambdaFunctionInstrumenter instrumenter) { -+ Context parentContext = null; -+ String parentTraceHeader = getTraceHeader(); ++ static Context extract( ++ Map headers, ++ AwsLambdaFunctionInstrumenter instrumenter, ++ com.amazonaws.services.lambda.runtime.Context lambdaContext) { ++ Map mergedHeaders = lowercaseMap(headers); ++ String parentTraceHeader = getTraceHeader(lambdaContext); + if (parentTraceHeader != null) { -+ parentContext = instrumenter.extract( -+ Collections.singletonMap(AWS_TRACE_HEADER_PROPAGATOR_KEY, parentTraceHeader), -+ MapGetter.INSTANCE); ++ mergedHeaders.put(AWS_TRACE_HEADER_PROPAGATOR_KEY, parentTraceHeader); + } -+ if (!isValidAndSampled(parentContext)) { -+ // try http -+ parentContext = instrumenter.extract(lowercaseMap(headers), MapGetter.INSTANCE); -+ } -+ return parentContext; ++ return instrumenter.extract(mergedHeaders, MapGetter.INSTANCE); + } + -+ private static String getTraceHeader() { ++ @NoMuzzle ++ private static String getTraceHeader( ++ com.amazonaws.services.lambda.runtime.Context lambdaContext) { ++ String traceHeader = null; ++ ++ // Lambda Core dependency that is actually used by Lambda Runtime may be on an older version ++ // that does not have the `getXrayTraceId` method. If `NoSuchMethodError` occurs, we do not ++ // attempt invoking `getXrayTraceId` again. ++ if (getXrayTraceIdMethodExists) { ++ try { ++ traceHeader = lambdaContext.getXrayTraceId(); ++ } catch (NoSuchMethodError e) { ++ logger.fine("Failed to get X-Ray trace ID from lambdaContext: " + e); ++ getXrayTraceIdMethodExists = false; ++ } ++ } ++ if (traceHeader != null && !traceHeader.isEmpty()) { ++ return traceHeader; ++ } ++ + // Lambda propagates trace header by system property instead of environment variable from java17 -+ String traceHeader = System.getProperty(AWS_TRACE_HEADER_PROP); ++ traceHeader = System.getProperty(AWS_TRACE_HEADER_PROP); + if (traceHeader == null || traceHeader.isEmpty()) { + return System.getenv(AWS_TRACE_HEADER_ENV_KEY); + } + return traceHeader; + } + -+ private static boolean isValidAndSampled(Context context) { -+ if (context == null) { -+ return false; -+ } -+ Span parentSpan = Span.fromContext(context); -+ SpanContext parentSpanContext = parentSpan.getSpanContext(); -+ return (parentSpanContext.isValid() && parentSpanContext.isSampled()); -+ } -+ + private enum MapGetter implements TextMapGetter> { + INSTANCE; + @@ -152,12 +207,25 @@ index 0000000000..439ed0de07 + + private ParentContextExtractor() {} +} +diff --git a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/test/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/InstrumenterExtractionTest.java b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/test/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/InstrumenterExtractionTest.java +index cb19d1e568..12ed174bb2 100644 +--- a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/test/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/InstrumenterExtractionTest.java ++++ b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/test/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/InstrumenterExtractionTest.java +@@ -37,7 +37,7 @@ class InstrumenterExtractionTest { + + AwsLambdaRequest input = AwsLambdaRequest.create(awsContext, new HashMap<>(), new HashMap<>()); + +- Context extracted = instr.extract(input); ++ Context extracted = instr.extract(input, awsContext); + SpanContext spanContext = Span.fromContext(extracted).getSpanContext(); + assertThat(spanContext.getTraceId()).isEqualTo("4bf92f3577b34da6a3ce929d0e0e4736"); + assertThat(spanContext.getSpanId()).isEqualTo("00f067aa0ba902b7"); diff --git a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/test/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/ParentContextExtractorTest.java b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/test/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/ParentContextExtractorTest.java new file mode 100644 -index 0000000000..1fa0b6e536 +index 0000000000..4b0f354769 --- /dev/null +++ b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/test/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/ParentContextExtractorTest.java -@@ -0,0 +1,135 @@ +@@ -0,0 +1,375 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 @@ -166,13 +234,19 @@ index 0000000000..1fa0b6e536 +package io.opentelemetry.instrumentation.awslambdacore.v1_0.internal; + +import static org.assertj.core.api.Assertions.assertThat; ++import static org.mockito.Mockito.mock; ++import static org.mockito.Mockito.times; ++import static org.mockito.Mockito.verify; ++import static org.mockito.Mockito.when; + ++import com.amazonaws.services.lambda.runtime.Context; +import com.google.common.collect.ImmutableMap; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanContext; -+import io.opentelemetry.context.Context; +import io.opentelemetry.context.propagation.ContextPropagators; ++import io.opentelemetry.context.propagation.TextMapPropagator; ++import io.opentelemetry.contrib.awsxray.propagator.AwsXrayPropagator; +import io.opentelemetry.extension.trace.propagation.B3Propagator; +import java.util.Map; +import org.junit.jupiter.api.Test; @@ -190,12 +264,33 @@ index 0000000000..1fa0b6e536 +class ParentContextExtractorTest { + + @SystemStub final EnvironmentVariables environmentVariables = new EnvironmentVariables(); ++ @SystemStub final SystemProperties systemProperties = new SystemProperties(); + -+ private static final OpenTelemetry OTEL = ++ private static final OpenTelemetry OTEL_WITH_B3_PROPAGATOR = + OpenTelemetry.propagating(ContextPropagators.create(B3Propagator.injectingSingleHeader())); + -+ private static final AwsLambdaFunctionInstrumenter INSTRUMENTER = -+ AwsLambdaFunctionInstrumenterFactory.createInstrumenter(OTEL); ++ private static final AwsLambdaFunctionInstrumenter INSTRUMENTER_WITH_B3_PROPAGATOR = ++ AwsLambdaFunctionInstrumenterFactory.createInstrumenter(OTEL_WITH_B3_PROPAGATOR); ++ ++ // Only for new lambda context tests ++ private static final OpenTelemetry OTEL_WITH_B3_XRAY_PROPAGATORS = ++ OpenTelemetry.propagating( ++ ContextPropagators.create( ++ TextMapPropagator.composite( ++ B3Propagator.injectingSingleHeader(), AwsXrayPropagator.getInstance()))); ++ private static final OpenTelemetry OTEL_WITH_XRAY_B3_PROPAGATORS = ++ OpenTelemetry.propagating( ++ ContextPropagators.create( ++ TextMapPropagator.composite( ++ AwsXrayPropagator.getInstance(), B3Propagator.injectingSingleHeader()))); ++ ++ private static final AwsLambdaFunctionInstrumenter INSTRUMENTER_WITH_B3_XRAY_PROPAGATORS = ++ AwsLambdaFunctionInstrumenterFactory.createInstrumenter(OTEL_WITH_B3_XRAY_PROPAGATORS); ++ ++ private static final AwsLambdaFunctionInstrumenter INSTRUMENTER_WITH_XRAY_B3_PROPAGATORS = ++ AwsLambdaFunctionInstrumenterFactory.createInstrumenter(OTEL_WITH_XRAY_B3_PROPAGATORS); ++ ++ private static final Context mockLambdaContext = mock(Context.class); + + @Test + void shouldUseHttpIfAwsParentNotSampled() { @@ -213,7 +308,8 @@ index 0000000000..1fa0b6e536 + "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=0000000000000456;Sampled=0"); + + // when -+ Context context = ParentContextExtractor.extract(headers, INSTRUMENTER); ++ io.opentelemetry.context.Context context = ++ ParentContextExtractor.extract(headers, INSTRUMENTER_WITH_B3_PROPAGATOR, mockLambdaContext); + // then + Span span = Span.fromContext(context); + SpanContext spanContext = span.getSpanContext(); @@ -239,7 +335,9 @@ index 0000000000..1fa0b6e536 + "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=0000000000000456;Sampled=1"); + + // when -+ Context context = ParentContextExtractor.extract(headers, INSTRUMENTER); ++ io.opentelemetry.context.Context context = ++ ParentContextExtractor.extract( ++ headers, INSTRUMENTER_WITH_B3_XRAY_PROPAGATORS, mockLambdaContext); + // then + Span span = Span.fromContext(context); + SpanContext spanContext = span.getSpanContext(); @@ -262,7 +360,8 @@ index 0000000000..1fa0b6e536 + "true"); + + // when -+ Context context = ParentContextExtractor.extract(headers, INSTRUMENTER); ++ io.opentelemetry.context.Context context = ++ ParentContextExtractor.extract(headers, INSTRUMENTER_WITH_B3_PROPAGATOR, mockLambdaContext); + // then + Span span = Span.fromContext(context); + SpanContext spanContext = span.getSpanContext(); @@ -277,20 +376,229 @@ index 0000000000..1fa0b6e536 + // given + systemProperties.set( + "com.amazonaws.xray.traceHeader", -+ "Root=1-8a3c60f7-d188f8fa79d48a391a778fa7;Parent=0000000000000789;Sampled=0"); ++ "Root=1-8a3c60f7-d188f8fa79d48a391a778fa7;Parent=0000000000000789;Sampled=1"); ++ environmentVariables.set( ++ "_X_AMZN_TRACE_ID", ++ "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=0000000000000456;Sampled=1"); ++ ++ // when ++ io.opentelemetry.context.Context context = ++ ParentContextExtractor.extract( ++ ImmutableMap.of(), INSTRUMENTER_WITH_B3_XRAY_PROPAGATORS, mockLambdaContext); ++ // then ++ Span span = Span.fromContext(context); ++ SpanContext spanContext = span.getSpanContext(); ++ assertThat(spanContext.isValid()).isTrue(); ++ assertThat(spanContext.isValid()).isTrue(); ++ assertThat(spanContext.getSpanId()).isEqualTo("0000000000000789"); ++ assertThat(spanContext.getTraceId()).isEqualTo("8a3c60f7d188f8fa79d48a391a778fa7"); ++ } ++ ++ @Test ++ void shouldUseLambdaContextToExtractXrayTraceId() { ++ // given ++ Map headers = ImmutableMap.of(); ++ Context mockLambdaContextWithXrayTraceId = mock(Context.class); ++ when(mockLambdaContextWithXrayTraceId.getXrayTraceId()) ++ .thenReturn("Root=1-4fd0b613-1f19f39af59518d127b0cafe;Parent=0000000000000123;Sampled=1"); ++ ++ // when ++ io.opentelemetry.context.Context context = ++ ParentContextExtractor.extract( ++ headers, INSTRUMENTER_WITH_B3_XRAY_PROPAGATORS, mockLambdaContextWithXrayTraceId); ++ // then ++ Span span = Span.fromContext(context); ++ SpanContext spanContext = span.getSpanContext(); ++ assertThat(spanContext.isValid()).isTrue(); ++ assertThat(spanContext.getSpanId()).isEqualTo("0000000000000123"); ++ assertThat(spanContext.getTraceId()).isEqualTo("4fd0b6131f19f39af59518d127b0cafe"); ++ } ++ ++ @Test ++ void shouldPreferLambdaContextOverSystemProperty() { ++ // given ++ Map headers = ImmutableMap.of(); ++ Context mockLambdaContextWithXrayTraceId = mock(Context.class); ++ when(mockLambdaContextWithXrayTraceId.getXrayTraceId()) ++ .thenReturn("Root=1-4fd0b613-1f19f39af59518d127b0cafe;Parent=0000000000000123;Sampled=1"); ++ systemProperties.set( ++ "com.amazonaws.xray.traceHeader", ++ "Root=1-8a3c60f7-d188f8fa79d48a391a778fa7;Parent=0000000000000789;Sampled=1"); ++ ++ // when ++ io.opentelemetry.context.Context context = ++ ParentContextExtractor.extract( ++ headers, INSTRUMENTER_WITH_B3_XRAY_PROPAGATORS, mockLambdaContextWithXrayTraceId); ++ // then ++ Span span = Span.fromContext(context); ++ SpanContext spanContext = span.getSpanContext(); ++ assertThat(spanContext.isValid()).isTrue(); ++ assertThat(spanContext.getSpanId()).isEqualTo("0000000000000123"); ++ assertThat(spanContext.getTraceId()).isEqualTo("4fd0b6131f19f39af59518d127b0cafe"); ++ } ++ ++ @Test ++ void shouldPreferLambdaContextOverEnvVariable() { ++ // given ++ Map headers = ImmutableMap.of(); ++ Context mockLambdaContextWithXrayTraceId = mock(Context.class); ++ when(mockLambdaContextWithXrayTraceId.getXrayTraceId()) ++ .thenReturn("Root=1-4fd0b613-1f19f39af59518d127b0cafe;Parent=0000000000000123;Sampled=1"); ++ environmentVariables.set( ++ "_X_AMZN_TRACE_ID", ++ "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=0000000000000456;Sampled=1"); ++ ++ // when ++ io.opentelemetry.context.Context context = ++ ParentContextExtractor.extract( ++ headers, INSTRUMENTER_WITH_B3_XRAY_PROPAGATORS, mockLambdaContextWithXrayTraceId); ++ // then ++ Span span = Span.fromContext(context); ++ SpanContext spanContext = span.getSpanContext(); ++ assertThat(spanContext.isValid()).isTrue(); ++ assertThat(spanContext.getSpanId()).isEqualTo("0000000000000123"); ++ assertThat(spanContext.getTraceId()).isEqualTo("4fd0b6131f19f39af59518d127b0cafe"); ++ } ++ ++ @Test ++ void shouldPreferLambdaContextOverHttp() { ++ // given ++ Map headers = ++ ImmutableMap.of( ++ "X-b3-traceId", ++ "4fd0b6131f19f39af59518d127b0cafe", ++ "x-b3-spanid", ++ "0000000000000123", ++ "X-B3-Sampled", ++ "true"); ++ Context mockLambdaContextWithXrayTraceId = mock(Context.class); ++ when(mockLambdaContextWithXrayTraceId.getXrayTraceId()) ++ .thenReturn("Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=0000000000000456;Sampled=1"); ++ ++ // when ++ io.opentelemetry.context.Context context = ++ ParentContextExtractor.extract( ++ headers, INSTRUMENTER_WITH_B3_XRAY_PROPAGATORS, mockLambdaContextWithXrayTraceId); ++ // then ++ Span span = Span.fromContext(context); ++ SpanContext spanContext = span.getSpanContext(); ++ assertThat(spanContext.isValid()).isTrue(); ++ assertThat(spanContext.getSpanId()).isEqualTo("0000000000000456"); ++ assertThat(spanContext.getTraceId()).isEqualTo("8a3c60f7d188f8fa79d48a391a778fa6"); ++ } ++ ++ @Test ++ void shouldPreferHttpOverXrayIdSetByLambdaContext() { ++ // given ++ Map headers = ++ ImmutableMap.of( ++ "X-b3-traceId", ++ "4fd0b6131f19f39af59518d127b0cafe", ++ "x-b3-spanid", ++ "0000000000000123", ++ "X-B3-Sampled", ++ "true"); + environmentVariables.set( + "_X_AMZN_TRACE_ID", + "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=0000000000000456;Sampled=1"); ++ systemProperties.set( ++ "com.amazonaws.xray.traceHeader", ++ "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=0000000000000456;Sampled=1"); ++ Context mockLambdaContextWithXrayTraceId = mock(Context.class); ++ when(mockLambdaContextWithXrayTraceId.getXrayTraceId()) ++ .thenReturn("Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=0000000000000456;Sampled=1"); + + // when -+ Context context = ParentContextExtractor.extract(headers, INSTRUMENTER); ++ io.opentelemetry.context.Context context = ++ ParentContextExtractor.extract( ++ headers, INSTRUMENTER_WITH_XRAY_B3_PROPAGATORS, mockLambdaContextWithXrayTraceId); + // then + Span span = Span.fromContext(context); + SpanContext spanContext = span.getSpanContext(); + assertThat(spanContext.isValid()).isTrue(); + assertThat(spanContext.isValid()).isTrue(); ++ assertThat(spanContext.getSpanId()).isEqualTo("0000000000000123"); ++ assertThat(spanContext.getTraceId()).isEqualTo("4fd0b6131f19f39af59518d127b0cafe"); ++ } ++ ++ @Test ++ void shouldFallbackToSystemPropertyIfContextTraceIdIsNull() { ++ // given ++ Map headers = ImmutableMap.of(); ++ Context mockLambdaContextWithXrayTraceId = mock(Context.class); ++ when(mockLambdaContextWithXrayTraceId.getXrayTraceId()).thenReturn(null); ++ systemProperties.set( ++ "com.amazonaws.xray.traceHeader", ++ "Root=1-8a3c60f7-d188f8fa79d48a391a778fa7;Parent=0000000000000789;Sampled=1"); ++ ++ // when ++ io.opentelemetry.context.Context context = ++ ParentContextExtractor.extract( ++ headers, INSTRUMENTER_WITH_B3_XRAY_PROPAGATORS, mockLambdaContextWithXrayTraceId); ++ // then ++ Span span = Span.fromContext(context); ++ SpanContext spanContext = span.getSpanContext(); ++ assertThat(spanContext.isValid()).isTrue(); + assertThat(spanContext.getSpanId()).isEqualTo("0000000000000789"); -+ assertThat(spanContext.getTraceId()).isEqualTo("d188f8fa79d48a391a778fa7"); ++ assertThat(spanContext.getTraceId()).isEqualTo("8a3c60f7d188f8fa79d48a391a778fa7"); ++ } ++ ++ @Test ++ void shouldFallbackToSystemPropertyIfContextTraceIdIsEmptyString() { ++ // given ++ Map headers = ImmutableMap.of(); ++ Context mockLambdaContextWithXrayTraceId = mock(Context.class); ++ when(mockLambdaContextWithXrayTraceId.getXrayTraceId()).thenReturn(""); ++ systemProperties.set( ++ "com.amazonaws.xray.traceHeader", ++ "Root=1-8a3c60f7-d188f8fa79d48a391a778fa7;Parent=0000000000000789;Sampled=1"); ++ ++ // when ++ io.opentelemetry.context.Context context = ++ ParentContextExtractor.extract( ++ headers, INSTRUMENTER_WITH_B3_XRAY_PROPAGATORS, mockLambdaContextWithXrayTraceId); ++ // then ++ Span span = Span.fromContext(context); ++ SpanContext spanContext = span.getSpanContext(); ++ assertThat(spanContext.isValid()).isTrue(); ++ assertThat(spanContext.getSpanId()).isEqualTo("0000000000000789"); ++ assertThat(spanContext.getTraceId()).isEqualTo("8a3c60f7d188f8fa79d48a391a778fa7"); ++ } ++ ++ @Test ++ void shouldFallbackToSystemPropertyWhenNoSuchMethodErrorThrown() { ++ // given ++ Map headers = ImmutableMap.of(); ++ Context mockLambdaContextWithNoSuchMethodError = mock(Context.class); ++ when(mockLambdaContextWithNoSuchMethodError.getXrayTraceId()) ++ .thenThrow(new NoSuchMethodError("getXrayTraceId method not found")); ++ systemProperties.set( ++ "com.amazonaws.xray.traceHeader", ++ "Root=1-8a3c60f7-d188f8fa79d48a391a778fa7;Parent=0000000000000789;Sampled=1"); ++ ++ // Reset the static flag to ensure the method is attempted ++ ParentContextExtractor.getXrayTraceIdMethodExists = true; ++ ++ // when - call extract ++ io.opentelemetry.context.Context context = ++ ParentContextExtractor.extract( ++ headers, INSTRUMENTER_WITH_B3_XRAY_PROPAGATORS, mockLambdaContextWithNoSuchMethodError); ++ ++ // then ++ Span span = Span.fromContext(context); ++ SpanContext spanContext = span.getSpanContext(); ++ assertThat(spanContext.isValid()).isTrue(); ++ assertThat(spanContext.getSpanId()).isEqualTo("0000000000000789"); ++ assertThat(spanContext.getTraceId()).isEqualTo("8a3c60f7d188f8fa79d48a391a778fa7"); ++ // Verify getXrayTraceId was called only once ++ assertThat(ParentContextExtractor.getXrayTraceIdMethodExists).isFalse(); ++ verify(mockLambdaContextWithNoSuchMethodError, times(1)).getXrayTraceId(); ++ ++ // when - call extract again ++ ParentContextExtractor.extract( ++ headers, INSTRUMENTER_WITH_B3_XRAY_PROPAGATORS, mockLambdaContextWithNoSuchMethodError); ++ // Verify the call count of getXrayTraceId is still 1 ++ verify(mockLambdaContextWithNoSuchMethodError, times(1)).getXrayTraceId(); + } +} diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/AwsLambdaSqsInstrumenterFactory.java b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/AwsLambdaSqsInstrumenterFactory.java