diff --git a/.github/workflows/release-build.yml b/.github/workflows/release-build.yml index 91990b21..edf5d3a5 100644 --- a/.github/workflows/release-build.yml +++ b/.github/workflows/release-build.yml @@ -5,6 +5,10 @@ on: version: description: The version to tag the release with, e.g., 1.2.0 required: true + aws_region: + description: 'Deploy lambda layer to aws regions' + required: true + default: 'us-east-1, us-east-2, us-west-1, us-west-2, ap-south-1, ap-northeast-3, ap-northeast-2, ap-southeast-1, ap-southeast-2, ap-northeast-1, ca-central-1, eu-central-1, eu-west-1, eu-west-2, eu-west-3, eu-north-1, sa-east-1, af-south-1, ap-east-1, ap-south-2, ap-southeast-3, ap-southeast-4, eu-central-2, eu-south-1, eu-south-2, il-central-1, me-central-1, me-south-1, ap-southeast-5, ap-southeast-7, mx-central-1, ca-west-1, cn-north-1, cn-northwest-1' env: AWS_DEFAULT_REGION: us-east-1 @@ -15,13 +19,17 @@ env: RELEASE_PRIVATE_REPOSITORY: 020628701572.dkr.ecr.us-west-2.amazonaws.com/adot-autoinstrumentation-dotnet RELEASE_PRIVATE_REGISTRY: 020628701572.dkr.ecr.us-west-2.amazonaws.com RELEASE_PRIVATE_S3: s3://adot-autoinstrumentation-dotnet-staging + # Legacy list of commercial regions to deploy to. New regions should NOT be added here, and instead should be added to the `aws_region` default input to the workflow. + LEGACY_COMMERCIAL_REGIONS: us-east-1, us-east-2, us-west-1, us-west-2, ap-south-1, ap-northeast-3, ap-northeast-2, ap-southeast-1, ap-southeast-2, ap-northeast-1, ca-central-1, eu-central-1, eu-west-1, eu-west-2, eu-west-3, eu-north-1, sa-east-1 + LAYER_NAME: AWSOpenTelemetryDistroDotNet permissions: id-token: write contents: write jobs: - build-and-upload: + build-sdk: + environment: Release strategy: fail-fast: false matrix: @@ -30,125 +38,90 @@ jobs: secrets: inherit with: caller-workflow-name: 'release_build_workflow' - - release: - needs: [build-and-upload, build-release-nuget] - environment: Release - runs-on: ubuntu-latest + + build-layer: + needs: build-sdk + strategy: + fail-fast: false + matrix: + aws-region: [ 'us-east-1' ] + uses: ./.github/workflows/main-build.yml + secrets: inherit + with: + caller-workflow-name: 'release_lambda_workflow' + + # We want to build and release nuget first so that if it fails, it fails before publishing to private ECR + # since deleting from Private ECR is not possible. + build-release-nuget: + needs: [build-sdk, build-layer] + runs-on: windows-latest + strategy: + fail-fast: true steps: - - name: Checkout Contrib Repo @ SHA - ${{ github.sha }} + - name: Checkout repository uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + + - name: Install dependencies + run: dotnet restore .\src\AWS.Distro.OpenTelemetry.AutoInstrumentation /p:_IsPacking=true - - name: Download Linux x64 Artifact - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 - with: - name: aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip - path: ./artifacts/linux/x64 - - - name: Download Linux arm64 Artifact - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 - with: - name: aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-arm64.zip - path: ./artifacts/linux/arm64 - - - name: Download Windows Artifact - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 - with: - name: aws-distro-opentelemetry-dotnet-instrumentation-windows.zip - path: ./artifacts/windows - - - name: Download Linux X64 MUSL Artifact - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 - with: - name: aws-distro-opentelemetry-dotnet-instrumentation-linux-musl-x64.zip - path: ./artifacts/linux/x64-musl + - name: Build solution + run: > + dotnet build .\src\AWS.Distro.OpenTelemetry.AutoInstrumentation + /p:Configuration=Release + --no-restore - - name: Download Linux arm64 MUSL Artifact - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - name: Assume signer role + uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: - name: aws-distro-opentelemetry-dotnet-instrumentation-linux-musl-arm64.zip - path: ./artifacts/linux/arm64-musl + role-to-assume: ${{ secrets.AWS_ARTIFACT_ACCESS_ROLE_ARN }} + aws-region: ${{ env.AWS_SIGNING_KEY_REGION }} - - name: Download bash installation script - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 - with: - name: aws-otel-dotnet-install.sh - path: ./installationScripts + - name: Invoke Signing script + env: + UNSIGNED_BUCKET: ${{ secrets.AWS_UNSIGNED_BUCKET_NAME }} + SIGNED_BUCKET: ${{ secrets.AWS_SIGNED_BUCKET_NAME }} + #TODO: There is probably a better way to pass in a list of paths as a single parameter to the script. + run: | + .\buildtools\sign_files.ps1 -Filters AWS.Distro.OpenTelemetry.AutoInstrumentation.dll -Recurse -Path .\src\AWS.Distro.OpenTelemetry.AutoInstrumentation\bin\Release + .\buildtools\sign_files.ps1 -Filters OpenTelemetry.Instrumentation.AWS.dll -Recurse -Path .\src\AWS.Distro.OpenTelemetry.AutoInstrumentation\bin\Release + .\buildtools\sign_files.ps1 -Filters AWS.OpenTelemetry.Exporter.Otlp.Udp.dll -Recurse -Path .\src\AWS.Distro.OpenTelemetry.AutoInstrumentation\bin\Release + + - name: Pack nugets + run: > + dotnet pack + .\src\AWS.Distro.OpenTelemetry.AutoInstrumentation + /p:Version=${{github.event.inputs.version}} + --no-build + -c Release + -o .\Deployment\nuget-packages - - name: Download psm1 installation script - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - name: Upload nugets to this GitHub Action run as an artifact + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 with: - name: AWS.Otel.DotNet.Auto.psm1 - path: ./installationScripts + name: nuget-packages.zip + path: Deployment/nuget-packages/ - - name: Configure AWS credentials for Private S3 Bucket + - name: Assume nuget role 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: Upload to Private S3 Bucket - run: | - PREFIX="Release_v${{github.event.inputs.version}}" - - find ./artifacts/ -name "*.zip" | while read file; do - base=$(basename "$file") - aws s3 cp "$file" "${{ env.RELEASE_PRIVATE_S3 }}/$PREFIX/$base" - done - aws s3 cp ./installationScripts/aws-otel-dotnet-install.sh "${{ env.RELEASE_PRIVATE_S3 }}/$PREFIX/aws-otel-dotnet-install.sh" - aws s3 cp ./installationScripts/AWS.Otel.DotNet.Auto.psm1 "${{ env.RELEASE_PRIVATE_S3 }}/$PREFIX/AWS.Otel.DotNet.Auto.psm1" - - # Publish to GitHub releases - - name: Create GH release - id: create_release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token - run: | - gh release create --target "$GITHUB_REF_NAME" \ - --title "Release v${{ github.event.inputs.version }}" \ - --draft \ - "v${{ github.event.inputs.version }}" \ - --notes "Release Verions v${{ github.event.inputs.version }}" + role-to-assume: ${{ secrets.NUGET_ACCESS_ROLE_ARN }} + aws-region: ${{ env.AWS_SIGNING_KEY_REGION }} - - name: Upload artifacts and checksum to release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - PREFIX="Release_v${{github.event.inputs.version}}_" + - name: Push packages to Nuget.org + run: > + $nugetKey = aws secretsmanager get-secret-value + --secret-id ${{ secrets.NUGET_SECRETS_ID }} + --region ${{ env.AWS_SIGNING_KEY_REGION }} + --output text + --query SecretString | ConvertFrom-Json - find ./artifacts/ -name "*.zip" | while read file; do - base=$(basename "$file") - cp "$file" "$base" - shasum -a 256 $base > $base.sha256 - gh release upload "v${{ github.event.inputs.version }}" \ - $base \ - $base.sha256 \ - --clobber - done - shasum -a 256 ./installationScripts/aws-otel-dotnet-install.sh | sed "s|./installationScripts/||" > aws-otel-dotnet-install.sh.sha256 - shasum -a 256 ./installationScripts/AWS.Otel.DotNet.Auto.psm1 | sed "s|./installationScripts/||" > AWS.Otel.DotNet.Auto.psm1.sha256 - gh release upload "v${{ github.event.inputs.version }}" \ - ./installationScripts/aws-otel-dotnet-install.sh \ - aws-otel-dotnet-install.sh.sha256 \ - --clobber - gh release upload "v${{ github.event.inputs.version }}" \ - ./installationScripts/AWS.Otel.DotNet.Auto.psm1 \ - AWS.Otel.DotNet.Auto.psm1.sha256 \ - --clobber - # Download layer.zip from existing latest tagged SDK release note - LATEST_SDK_VERSION=$(gh release list --repo "aws-observability/aws-otel-dotnet-instrumentation" --json tagName,isLatest -q 'map(select(.isLatest==true)) | .[0].tagName') - mkdir -p layer_artifact - gh release download "$LATEST_SDK_VERSION" --repo "aws-observability/aws-otel-dotnet-instrumentation" --pattern "layer.zip" --dir layer_artifact - shasum -a 256 layer_artifact/layer.zip > layer_artifact/layer.zip.sha256 - gh release upload "v${{ github.event.inputs.version }}" \ - layer_artifact/layer.zip \ - layer_artifact/layer.zip.sha256 \ - --clobber + nuget push + .\Deployment\nuget-packages\*.nupkg + -Source https://api.nuget.org/v3/index.json + -ApiKey $nugetKey.Key release-image: - # We want to build and release nuget first so that if it fails, it fails before publishing to private ECR - # since deleting from Private ECR is not possible. - needs: [release, build-release-nuget] + needs: build-release-nuget runs-on: ${{ matrix.os }} strategy: matrix: @@ -158,9 +131,6 @@ jobs: steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 - - - - name: Configure AWS credentials for public ECR uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: @@ -234,7 +204,7 @@ jobs: shell: powershell release-multi-platform-image: - needs: [release-image] + needs: release-image runs-on: ubuntu-latest steps: - name: Configure AWS credentials for private ECR @@ -271,71 +241,325 @@ jobs: docker manifest inspect ${{ env.RELEASE_PUBLIC_REPOSITORY }}:v${{ github.event.inputs.version }} docker manifest push ${{ env.RELEASE_PUBLIC_REPOSITORY }}:v${{ github.event.inputs.version }} - build-release-nuget: - runs-on: windows-latest + setup-regions-matrix: + runs-on: ubuntu-latest + needs: release-multi-platform-image + outputs: + aws_regions_json: ${{ steps.set-matrix.outputs.aws_regions_json }} + steps: + - name: Set up regions matrix + id: set-matrix + run: | + IFS=',' read -ra REGIONS <<< "${{ github.event.inputs.aws_region }}" + MATRIX="[" + for region in "${REGIONS[@]}"; do + trimmed_region=$(echo "$region" | xargs) + MATRIX+="\"$trimmed_region\"," + done + MATRIX="${MATRIX%,}]" + echo ${MATRIX} + echo "aws_regions_json=${MATRIX}" >> $GITHUB_OUTPUT + - name: Checkout Repo @ SHA - ${{ github.sha }} + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + publish-layer-prod: + runs-on: ubuntu-latest + needs: setup-regions-matrix strategy: - fail-fast: true + matrix: + aws_region: ${{ fromJson(needs.setup-regions-matrix.outputs.aws_regions_json) }} + steps: + - name: role arn + env: + LEGACY_COMMERCIAL_REGIONS: ${{ env.LEGACY_COMMERCIAL_REGIONS }} + run: | + LEGACY_COMMERCIAL_REGIONS_ARRAY=(${LEGACY_COMMERCIAL_REGIONS//,/ }) + FOUND=false + for REGION in "${LEGACY_COMMERCIAL_REGIONS_ARRAY[@]}"; do + if [[ "$REGION" == "${{ matrix.aws_region }}" ]]; then + FOUND=true + break + fi + done + if [ "$FOUND" = true ]; then + echo "Found ${{ matrix.aws_region }} in LEGACY_COMMERCIAL_REGIONS" + SECRET_KEY="LAMBDA_LAYER_RELEASE" + else + echo "Not found ${{ matrix.aws_region }} in LEGACY_COMMERCIAL_REGIONS" + SECRET_KEY="${{ matrix.aws_region }}_LAMBDA_LAYER_RELEASE" + fi + SECRET_KEY=${SECRET_KEY//-/_} + echo "SECRET_KEY=${SECRET_KEY}" >> $GITHUB_ENV + - uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 + with: + role-to-assume: ${{ secrets[env.SECRET_KEY] }} + role-duration-seconds: 1200 + aws-region: ${{ matrix.aws_region }} + - name: Get s3 bucket name for release + run: | + echo BUCKET_NAME=dotnet-lambda-layer-${{ github.run_id }}-${{ matrix.aws_region }} | tee --append $GITHUB_ENV + - name: Download Linux x64 Artifact + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + with: + name: aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip + - name: publish + run: | + aws s3 mb s3://${{ env.BUCKET_NAME }} + aws s3 cp aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip s3://${{ env.BUCKET_NAME }} + layerARN=$( + aws lambda publish-layer-version \ + --layer-name ${{ env.LAYER_NAME }} \ + --content S3Bucket=${{ env.BUCKET_NAME }},S3Key=aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip \ + --compatible-runtimes dotnet8 \ + --compatible-architectures "x86_64" \ + --license-info "Apache-2.0" \ + --description "AWS Distro of OpenTelemetry Lambda Layer for .Net Runtime v${{ github.event.inputs.version }}" \ + --query 'LayerVersionArn' \ + --output text + ) + echo $layerARN + echo "LAYER_ARN=${layerARN}" >> $GITHUB_ENV + mkdir ${{ env.LAYER_NAME }} + echo $layerARN > ${{ env.LAYER_NAME }}/${{ matrix.aws_region }} + cat ${{ env.LAYER_NAME }}/${{ matrix.aws_region }} + - name: public layer + run: | + layerVersion=$( + aws lambda list-layer-versions \ + --layer-name ${{ env.LAYER_NAME }} \ + --query 'max_by(LayerVersions, &Version).Version' + ) + aws lambda add-layer-version-permission \ + --layer-name ${{ env.LAYER_NAME }} \ + --version-number $layerVersion \ + --principal "*" \ + --statement-id publish \ + --action lambda:GetLayerVersion + - name: upload layer arn artifact + if: ${{ success() }} + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 + with: + name: ${{ env.LAYER_NAME }}-${{ matrix.aws_region }} + path: ${{ env.LAYER_NAME }}/${{ matrix.aws_region }} + - name: clean s3 + if: always() + run: | + aws s3 rb --force s3://${{ env.BUCKET_NAME }} + generate-lambda-release-note: + runs-on: ubuntu-latest + needs: publish-layer-prod + outputs: + layer-note: ${{ steps.layer-note.outputs.layer-note }} + steps: + - name: Checkout Repo @ SHA - ${{ github.sha }} + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + - uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd #v3.1.2 + - name: download layerARNs + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + with: + pattern: ${{ env.LAYER_NAME }}-* + path: ${{ env.LAYER_NAME }} + merge-multiple: true + - name: show layerARNs + run: | + for file in ${{ env.LAYER_NAME }}/* + do + echo $file + cat $file + done + - name: generate layer-note + id: layer-note + working-directory: ${{ env.LAYER_NAME }} + run: | + echo "| Region | Layer ARN |" >> ../layer-note + echo "| ---- | ---- |" >> ../layer-note + for file in * + do + read arn < $file + echo "| " $file " | " $arn " |" >> ../layer-note + done + cd .. + { + echo "layer-note<> $GITHUB_OUTPUT + cat layer-note + - name: generate tf layer + working-directory: ${{ env.LAYER_NAME }} + run: | + echo "locals {" >> ../layer_arns.tf + echo " sdk_layer_arns = {" >> ../layer_arns.tf + for file in * + do + read arn < $file + echo " \""$file"\" = \""$arn"\"" >> ../layer_arns.tf + done + cd .. + echo " }" >> layer_arns.tf + echo "}" >> layer_arns.tf + terraform fmt layer_arns.tf + cat layer_arns.tf + - name: generate layer ARN constants for CDK + working-directory: ${{ env.LAYER_NAME }} + run: | + echo "{" > ../layer_cdk + for file in *; do + read arn < "$file" + echo " \"$file\": \"$arn\"," >> ../layer_cdk + done + echo "}" >> ../layer_cdk + cat ../layer_cdk + publish-github: + needs: generate-lambda-release-note + runs-on: ubuntu-latest steps: - - name: Checkout repository + - name: Checkout Contrib Repo @ SHA - ${{ github.sha }} uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + + - name: Download Linux x64 Artifact + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + with: + name: aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip + path: ./artifacts/linux/x64 - - name: Install dependencies - run: dotnet restore .\src\AWS.Distro.OpenTelemetry.AutoInstrumentation /p:_IsPacking=true + - name: Change name to layer.zip + run: cp ./artifacts/linux/x64/aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip layer.zip - - name: Build solution - run: > - dotnet build .\src\AWS.Distro.OpenTelemetry.AutoInstrumentation - /p:Configuration=Release - --no-restore + - name: Download Linux arm64 Artifact + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + with: + name: aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-arm64.zip + path: ./artifacts/linux/arm64 - - name: Assume signer role - uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 + - name: Download Windows Artifact + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: - role-to-assume: ${{ secrets.AWS_ARTIFACT_ACCESS_ROLE_ARN }} - aws-region: ${{ env.AWS_SIGNING_KEY_REGION }} + name: aws-distro-opentelemetry-dotnet-instrumentation-windows.zip + path: ./artifacts/windows - - name: Invoke Signing script - env: - UNSIGNED_BUCKET: ${{ secrets.AWS_UNSIGNED_BUCKET_NAME }} - SIGNED_BUCKET: ${{ secrets.AWS_SIGNED_BUCKET_NAME }} - #TODO: There is probably a better way to pass in a list of paths as a single parameter to the script. - run: | - .\buildtools\sign_files.ps1 -Filters AWS.Distro.OpenTelemetry.AutoInstrumentation.dll -Recurse -Path .\src\AWS.Distro.OpenTelemetry.AutoInstrumentation\bin\Release - .\buildtools\sign_files.ps1 -Filters OpenTelemetry.Instrumentation.AWS.dll -Recurse -Path .\src\AWS.Distro.OpenTelemetry.AutoInstrumentation\bin\Release - .\buildtools\sign_files.ps1 -Filters AWS.OpenTelemetry.Exporter.Otlp.Udp.dll -Recurse -Path .\src\AWS.Distro.OpenTelemetry.AutoInstrumentation\bin\Release - - - name: Pack nugets - run: > - dotnet pack - .\src\AWS.Distro.OpenTelemetry.AutoInstrumentation - /p:Version=${{github.event.inputs.version}} - --no-build - -c Release - -o .\Deployment\nuget-packages + - name: Download Linux X64 MUSL Artifact + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + with: + name: aws-distro-opentelemetry-dotnet-instrumentation-linux-musl-x64.zip + path: ./artifacts/linux/x64-musl - - name: Upload nugets to this GitHub Action run as an artifact - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 + - name: Download Linux arm64 MUSL Artifact + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: - name: nuget-packages.zip - path: Deployment/nuget-packages/ + name: aws-distro-opentelemetry-dotnet-instrumentation-linux-musl-arm64.zip + path: ./artifacts/linux/arm64-musl - - name: Assume nuget role + - name: Download bash installation script + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + with: + name: aws-otel-dotnet-install.sh + path: ./installationScripts + + - name: Download psm1 installation script + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + with: + name: AWS.Otel.DotNet.Auto.psm1 + path: ./installationScripts + + - name: Configure AWS credentials for Private S3 Bucket uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 with: - role-to-assume: ${{ secrets.NUGET_ACCESS_ROLE_ARN }} - aws-region: ${{ env.AWS_SIGNING_KEY_REGION }} + role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} - - name: Push packages to Nuget.org - run: > - $nugetKey = aws secretsmanager get-secret-value - --secret-id ${{ secrets.NUGET_SECRETS_ID }} - --region ${{ env.AWS_SIGNING_KEY_REGION }} - --output text - --query SecretString | ConvertFrom-Json + - name: Upload to Private S3 Bucket + run: | + PREFIX="Release_v${{github.event.inputs.version}}" - nuget push - .\Deployment\nuget-packages\*.nupkg - -Source https://api.nuget.org/v3/index.json - -ApiKey $nugetKey.Key \ No newline at end of file + find ./artifacts/ -name "*.zip" | while read file; do + base=$(basename "$file") + aws s3 cp "$file" "${{ env.RELEASE_PRIVATE_S3 }}/$PREFIX/$base" + done + aws s3 cp ./installationScripts/aws-otel-dotnet-install.sh "${{ env.RELEASE_PRIVATE_S3 }}/$PREFIX/aws-otel-dotnet-install.sh" + aws s3 cp ./installationScripts/AWS.Otel.DotNet.Auto.psm1 "${{ env.RELEASE_PRIVATE_S3 }}/$PREFIX/AWS.Otel.DotNet.Auto.psm1" + + # Publish to GitHub releases + - name: Create GH release + id: create_release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token + run: | + # Extract version from Build.cs + OTEL_INSTRUMENTATION_VERSION=$(grep "OpenTelemetryAutoInstrumentationDefaultVersion = " build/Build.cs | sed 's/.*= "\(.*\)";/\1/' | sed 's/^v//') + + # Extract CHANGELOG entries for this version + CHANGELOG_ENTRIES=$(python3 -c " + import re + with open('CHANGELOG.md', 'r') as f: + content = f.read() + version_pattern = r'## v${{ github.event.inputs.version }}.*?\n(.*?)(?=\n## |\Z)' + version_match = re.search(version_pattern, content, re.DOTALL) + if version_match: + entries = version_match.group(1).strip() + if entries: + print(entries) + ") + + # Create release notes + cat > release_notes.md << EOF + $(if [ -n "$CHANGELOG_ENTRIES" ]; then echo "## What's Changed"; echo "$CHANGELOG_ENTRIES"; echo ""; fi) + + ## Upstream Components + + - \`OpenTelemetry .NET Auto Instrumentation\` - $OTEL_INSTRUMENTATION_VERSION + + ## Release Artifacts + + This release publishes to public ECR and NuGet. + * See ADOT .NET auto-instrumentation Docker image v${{ github.event.inputs.version }} in our public ECR repository: + https://gallery.ecr.aws/aws-observability/adot-autoinstrumentation-dotnet + * See version ${{ github.event.inputs.version }} in our NuGet repository: + https://www.nuget.org/packages/AWS.Distro.OpenTelemetry.AutoInstrumentation + + ## Lambda Layer + + This release includes the AWS OpenTelemetry Lambda Layer for .NET version ${{ github.event.inputs.version }}-$(git rev-parse --short HEAD). + + Lambda Layer ARNs: + ${{ needs.generate-lambda-release-note.outputs.layer-note }} + EOF + + gh release create --target "$GITHUB_REF_NAME" \ + --title "Release v${{ github.event.inputs.version }}" \ + --draft \ + "v${{ github.event.inputs.version }}" \ + --notes-file release_notes.md + + - name: Upload artifacts and checksum to release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + PREFIX="Release_v${{github.event.inputs.version}}_" + + find ./artifacts/ -name "*.zip" | while read file; do + base=$(basename "$file") + cp "$file" "$base" + shasum -a 256 $base > $base.sha256 + gh release upload "v${{ github.event.inputs.version }}" \ + $base \ + $base.sha256 \ + --clobber + done + shasum -a 256 ./installationScripts/aws-otel-dotnet-install.sh | sed "s|./installationScripts/||" > aws-otel-dotnet-install.sh.sha256 + shasum -a 256 ./installationScripts/AWS.Otel.DotNet.Auto.psm1 | sed "s|./installationScripts/||" > AWS.Otel.DotNet.Auto.psm1.sha256 + gh release upload "v${{ github.event.inputs.version }}" \ + ./installationScripts/aws-otel-dotnet-install.sh \ + aws-otel-dotnet-install.sh.sha256 \ + --clobber + gh release upload "v${{ github.event.inputs.version }}" \ + ./installationScripts/AWS.Otel.DotNet.Auto.psm1 \ + AWS.Otel.DotNet.Auto.psm1.sha256 \ + --clobber + + shasum -a 256 layer.zip > layer.zip.sha256 + gh release upload "v${{ github.event.inputs.version }}" \ + layer.zip \ + layer.zip.sha256 \ + --clobber \ No newline at end of file diff --git a/.github/workflows/release-lambda.yml b/.github/workflows/release-lambda.yml deleted file mode 100644 index 4ed3c336..00000000 --- a/.github/workflows/release-lambda.yml +++ /dev/null @@ -1,235 +0,0 @@ -name: Release Lambda layer - -on: - workflow_dispatch: - inputs: - version: - description: The version to tag the lambda release with, e.g., 1.2.0 - required: true - aws_region: - description: 'Deploy to aws regions' - required: true - default: 'us-east-1, us-east-2, us-west-1, us-west-2, ap-south-1, ap-northeast-3, ap-northeast-2, ap-southeast-1, ap-southeast-2, ap-northeast-1, ca-central-1, eu-central-1, eu-west-1, eu-west-2, eu-west-3, eu-north-1, sa-east-1, af-south-1, ap-east-1, ap-south-2, ap-southeast-3, ap-southeast-4, eu-central-2, eu-south-1, eu-south-2, il-central-1, me-central-1, me-south-1, ap-southeast-5, ap-southeast-7, mx-central-1, ca-west-1, cn-north-1, cn-northwest-1' - -env: - # Legacy list of commercial regions to deploy to. New regions should NOT be added here, and instead should be added to the `aws_region` default input to the workflow. - LEGACY_COMMERCIAL_REGIONS: us-east-1, us-east-2, us-west-1, us-west-2, ap-south-1, ap-northeast-3, ap-northeast-2, ap-southeast-1, ap-southeast-2, ap-northeast-1, ca-central-1, eu-central-1, eu-west-1, eu-west-2, eu-west-3, eu-north-1, sa-east-1 - LAYER_NAME: AWSOpenTelemetryDistroDotNet - -permissions: - id-token: write - contents: write - -jobs: - build-and-upload: - strategy: - fail-fast: false - matrix: - aws-region: [ 'us-east-1' ] - uses: ./.github/workflows/main-build.yml - secrets: inherit - with: - caller-workflow-name: 'release_lambda_workflow' - environment: 'Release' - - setup-regions-matrix: - runs-on: ubuntu-latest - outputs: - aws_regions_json: ${{ steps.set-matrix.outputs.aws_regions_json }} - steps: - - name: Set up regions matrix - id: set-matrix - run: | - IFS=',' read -ra REGIONS <<< "${{ github.event.inputs.aws_region }}" - MATRIX="[" - for region in "${REGIONS[@]}"; do - trimmed_region=$(echo "$region" | xargs) - MATRIX+="\"$trimmed_region\"," - done - MATRIX="${MATRIX%,}]" - echo ${MATRIX} - echo "aws_regions_json=${MATRIX}" >> $GITHUB_OUTPUT - - name: Checkout Repo @ SHA - ${{ github.sha }} - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 - - publish-prod: - runs-on: ubuntu-latest - needs: [build-and-upload, setup-regions-matrix] - strategy: - matrix: - aws_region: ${{ fromJson(needs.setup-regions-matrix.outputs.aws_regions_json) }} - steps: - - name: role arn - env: - LEGACY_COMMERCIAL_REGIONS: ${{ env.LEGACY_COMMERCIAL_REGIONS }} - run: | - LEGACY_COMMERCIAL_REGIONS_ARRAY=(${LEGACY_COMMERCIAL_REGIONS//,/ }) - FOUND=false - for REGION in "${LEGACY_COMMERCIAL_REGIONS_ARRAY[@]}"; do - if [[ "$REGION" == "${{ matrix.aws_region }}" ]]; then - FOUND=true - break - fi - done - if [ "$FOUND" = true ]; then - echo "Found ${{ matrix.aws_region }} in LEGACY_COMMERCIAL_REGIONS" - SECRET_KEY="LAMBDA_LAYER_RELEASE" - else - echo "Not found ${{ matrix.aws_region }} in LEGACY_COMMERCIAL_REGIONS" - SECRET_KEY="${{ matrix.aws_region }}_LAMBDA_LAYER_RELEASE" - fi - SECRET_KEY=${SECRET_KEY//-/_} - echo "SECRET_KEY=${SECRET_KEY}" >> $GITHUB_ENV - - uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0 - with: - role-to-assume: ${{ secrets[env.SECRET_KEY] }} - role-duration-seconds: 1200 - aws-region: ${{ matrix.aws_region }} - - name: Get s3 bucket name for release - run: | - echo BUCKET_NAME=dotnet-lambda-layer-${{ github.run_id }}-${{ matrix.aws_region }} | tee --append $GITHUB_ENV - - name: Download Linux x64 Artifact - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 - with: - name: aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip - - name: publish - run: | - aws s3 mb s3://${{ env.BUCKET_NAME }} - aws s3 cp aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip s3://${{ env.BUCKET_NAME }} - layerARN=$( - aws lambda publish-layer-version \ - --layer-name ${{ env.LAYER_NAME }} \ - --content S3Bucket=${{ env.BUCKET_NAME }},S3Key=aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip \ - --compatible-runtimes dotnet8 \ - --compatible-architectures "x86_64" \ - --license-info "Apache-2.0" \ - --description "AWS Distro of OpenTelemetry Lambda Layer for .Net Runtime v${{ github.event.inputs.version }}" \ - --query 'LayerVersionArn' \ - --output text - ) - echo $layerARN - echo "LAYER_ARN=${layerARN}" >> $GITHUB_ENV - mkdir ${{ env.LAYER_NAME }} - echo $layerARN > ${{ env.LAYER_NAME }}/${{ matrix.aws_region }} - cat ${{ env.LAYER_NAME }}/${{ matrix.aws_region }} - - name: public layer - run: | - layerVersion=$( - aws lambda list-layer-versions \ - --layer-name ${{ env.LAYER_NAME }} \ - --query 'max_by(LayerVersions, &Version).Version' - ) - aws lambda add-layer-version-permission \ - --layer-name ${{ env.LAYER_NAME }} \ - --version-number $layerVersion \ - --principal "*" \ - --statement-id publish \ - --action lambda:GetLayerVersion - - name: upload layer arn artifact - if: ${{ success() }} - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 - with: - name: ${{ env.LAYER_NAME }}-${{ matrix.aws_region }} - path: ${{ env.LAYER_NAME }}/${{ matrix.aws_region }} - - name: clean s3 - if: always() - run: | - aws s3 rb --force s3://${{ env.BUCKET_NAME }} - generate-release-note: - runs-on: ubuntu-latest - needs: publish-prod - steps: - - name: Checkout Repo @ SHA - ${{ github.sha }} - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 - - uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd #v3.1.2 - - name: download layerARNs - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 - with: - pattern: ${{ env.LAYER_NAME }}-* - path: ${{ env.LAYER_NAME }} - merge-multiple: true - - name: show layerARNs - run: | - for file in ${{ env.LAYER_NAME }}/* - do - echo $file - cat $file - done - - name: generate layer-note - working-directory: ${{ env.LAYER_NAME }} - run: | - echo "| Region | Layer ARN |" >> ../layer-note - echo "| ---- | ---- |" >> ../layer-note - for file in * - do - read arn < $file - echo "| " $file " | " $arn " |" >> ../layer-note - done - cat ../layer-note - - name: generate tf layer - working-directory: ${{ env.LAYER_NAME }} - run: | - echo "locals {" >> ../layer_arns.tf - echo " sdk_layer_arns = {" >> ../layer_arns.tf - for file in * - do - read arn < $file - echo " \""$file"\" = \""$arn"\"" >> ../layer_arns.tf - done - cd .. - echo " }" >> layer_arns.tf - echo "}" >> layer_arns.tf - terraform fmt layer_arns.tf - cat layer_arns.tf - - name: generate layer ARN constants for CDK - working-directory: ${{ env.LAYER_NAME }} - run: | - echo "{" > ../layer_cdk - for file in *; do - read arn < "$file" - echo " \"$file\": \"$arn\"," >> ../layer_cdk - done - echo "}" >> ../layer_cdk - cat ../layer_cdk - - name: Download Linux x64 Artifact - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 - with: - name: aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip - - name: Change name to layer.zip - run: mv aws-distro-opentelemetry-dotnet-instrumentation-linux-glibc-x64.zip layer.zip - - name: Get commit hash - id: commit - run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT - - name: Create Release Notes - run: | - echo "AWS OpenTelemetry Lambda Layer for DotNet version ${{ github.event.inputs.version }}-${{ steps.commit.outputs.sha_short }}" > release_notes.md - echo "" >> release_notes.md - echo "" >> release_notes.md - echo "See new Lambda Layer ARNs:" >> release_notes.md - echo "" >> release_notes.md - cat layer-note >> release_notes.md - echo "" >> release_notes.md - echo "Notes:" >> release_notes.md - - name: Create GH release - id: create_release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token - run: | - gh release create --target "$GITHUB_REF_NAME" \ - --title "Release lambda-v${{ github.event.inputs.version }}-${{ steps.commit.outputs.sha_short }}" \ - --notes-file release_notes.md \ - --draft \ - "lambda-v${{ github.event.inputs.version }}-${{ steps.commit.outputs.sha_short }}" \ - layer_arns.tf layer.zip - echo Removing release_notes.md ... - rm -f release_notes.md - - name: Upload layer.zip and SHA-256 checksum to SDK Release Notes (tagged with latest) - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - LATEST_SDK_VERSION=$(gh release list --repo "aws-observability/aws-otel-dotnet-instrumentation" --json tagName,isLatest -q 'map(select(.isLatest==true)) | .[0].tagName') - # Generate SHA-256 checksum for layer.zip - shasum -a 256 layer.zip > layer.zip.sha256 - # Upload layer.zip and its checksum to the latest SDK release note - gh release upload "$LATEST_SDK_VERSION" layer.zip layer.zip.sha256 --repo "aws-observability/aws-otel-dotnet-instrumentation" --clobber - echo "✅ layer.zip successfully uploaded to $LATEST_SDK_VERSION in the upstream repo!"