Skip to content

Commit cbc1a4e

Browse files
ezhang6811thpierce
andauthored
Merge SDK and Lambda Releases (#461)
*Issue #, if available:* *Description of changes:* We plan to consolidate our ADOT SDK and Lambda layer releases for future versions. This PR merges the Lambda release workflow into the main release workflow, and publishes the layer artifacts and ARN notes to the same Github release as the SDK. The release build workflow also now includes the SDK release notes with our upstream Otel dependency versions to eliminate the manual effort needed when updating release notes. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. --------- Co-authored-by: Thomas Pierce <[email protected]>
1 parent d6c6cb1 commit cbc1a4e

File tree

2 files changed

+276
-254
lines changed

2 files changed

+276
-254
lines changed

.github/workflows/release-build.yml

Lines changed: 276 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ on:
55
version:
66
description: The version to tag the release with, e.g., 1.2.0
77
required: true
8+
aws_region:
9+
description: 'Deploy lambda layer to aws regions'
10+
required: true
11+
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'
812

913
env:
1014
AWS_DEFAULT_REGION: us-east-1
@@ -15,13 +19,16 @@ env:
1519
RELEASE_PRIVATE_REGISTRY: 020628701572.dkr.ecr.us-west-2.amazonaws.com
1620
PACKAGE_NAME: aws-opentelemetry-distro
1721
ARTIFACT_NAME: aws_opentelemetry_distro-${{ github.event.inputs.version }}-py3-none-any.whl
22+
# 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.
23+
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
24+
LAYER_NAME: AWSOpenTelemetryDistroPython
1825

1926
permissions:
2027
id-token: write
2128
contents: write
2229

2330
jobs:
24-
build:
31+
build-sdk:
2532
environment: Release
2633
runs-on: ubuntu-latest
2734
steps:
@@ -60,6 +67,54 @@ jobs:
6067
# release the artifacts. adot java for reference:
6168
# https://github.com/aws-observability/aws-otel-java-instrumentation/tree/93870a550ac30988fbdd5d3bf1e8f9f1b37916f5/smoke-tests
6269

70+
- name: Upload SDK artifact
71+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2
72+
with:
73+
name: ${{ env.ARTIFACT_NAME }}
74+
path: dist/${{ env.ARTIFACT_NAME }}
75+
76+
build-layer:
77+
needs: build-sdk
78+
runs-on: ubuntu-latest
79+
outputs:
80+
aws_regions_json: ${{ steps.set-matrix.outputs.aws_regions_json }}
81+
steps:
82+
- name: Set up regions matrix
83+
id: set-matrix
84+
run: |
85+
IFS=',' read -ra REGIONS <<< "${{ github.event.inputs.aws_region }}"
86+
MATRIX="["
87+
for region in "${REGIONS[@]}"; do
88+
trimmed_region=$(echo "$region" | xargs)
89+
MATRIX+="\"$trimmed_region\","
90+
done
91+
MATRIX="${MATRIX%,}]"
92+
echo ${MATRIX}
93+
echo "aws_regions_json=${MATRIX}" >> $GITHUB_OUTPUT
94+
- name: Checkout Repo @ SHA - ${{ github.sha }}
95+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
96+
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c #v6.0.0
97+
with:
98+
python-version: '3.x'
99+
- name: Build layers
100+
working-directory: lambda-layer/src
101+
run: |
102+
./build-lambda-layer.sh
103+
pip install tox
104+
tox
105+
- name: upload layer
106+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2
107+
with:
108+
name: layer.zip
109+
path: lambda-layer/src/build/aws-opentelemetry-python-layer.zip
110+
111+
publish-sdk:
112+
needs: [build-sdk, build-layer]
113+
runs-on: ubuntu-latest
114+
steps:
115+
- name: Checkout Repo @ SHA - ${{ github.sha }}
116+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
117+
63118
- name: Configure AWS credentials for PyPI secrets
64119
uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0
65120
with:
@@ -102,20 +157,25 @@ jobs:
102157
- name: Install twine
103158
run: pip install twine
104159

160+
- name: Download SDK artifact
161+
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0
162+
with:
163+
name: ${{ env.ARTIFACT_NAME }}
164+
105165
- name: Publish to TestPyPI
106166
env:
107167
TWINE_USERNAME: '__token__'
108168
TWINE_PASSWORD: ${{ env.TEST_PYPI_TOKEN_API_TOKEN }}
109169
run: |
110-
twine upload --repository testpypi --skip-existing --verbose dist/${{ env.ARTIFACT_NAME }}
170+
twine upload --repository testpypi --skip-existing --verbose ${{ env.ARTIFACT_NAME }}
111171
112172
# Publish to prod PyPI
113173
- name: Publish to PyPI
114174
env:
115175
TWINE_USERNAME: '__token__'
116176
TWINE_PASSWORD: ${{ env.PROD_PYPI_TOKEN_API_TOKEN }}
117177
run: |
118-
twine upload --skip-existing --verbose dist/${{ env.ARTIFACT_NAME }}
178+
twine upload --skip-existing --verbose ${{ env.ARTIFACT_NAME }}
119179
120180
# Publish to public ECR
121181
- name: Build and push public ECR image
@@ -138,29 +198,230 @@ jobs:
138198
platforms: linux/amd64,linux/arm64
139199
tags: |
140200
${{ env.RELEASE_PRIVATE_REPOSITORY }}:v${{ github.event.inputs.version }}
201+
202+
publish-layer-prod:
203+
runs-on: ubuntu-latest
204+
needs: [build-layer, publish-sdk]
205+
strategy:
206+
matrix:
207+
aws_region: ${{ fromJson(needs.build-layer.outputs.aws_regions_json) }}
208+
steps:
209+
- name: role arn
210+
env:
211+
LEGACY_COMMERCIAL_REGIONS: ${{ env.LEGACY_COMMERCIAL_REGIONS }}
212+
run: |
213+
LEGACY_COMMERCIAL_REGIONS_ARRAY=(${LEGACY_COMMERCIAL_REGIONS//,/ })
214+
FOUND=false
215+
for REGION in "${LEGACY_COMMERCIAL_REGIONS_ARRAY[@]}"; do
216+
if [[ "$REGION" == "${{ matrix.aws_region }}" ]]; then
217+
FOUND=true
218+
break
219+
fi
220+
done
221+
if [ "$FOUND" = true ]; then
222+
echo "Found ${{ matrix.aws_region }} in LEGACY_COMMERCIAL_REGIONS"
223+
SECRET_KEY="LAMBDA_LAYER_RELEASE"
224+
else
225+
echo "Not found ${{ matrix.aws_region }} in LEGACY_COMMERCIAL_REGIONS"
226+
SECRET_KEY="${{ matrix.aws_region }}_LAMBDA_LAYER_RELEASE"
227+
fi
228+
SECRET_KEY=${SECRET_KEY//-/_}
229+
echo "SECRET_KEY=${SECRET_KEY}" >> $GITHUB_ENV
230+
- uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0
231+
with:
232+
role-to-assume: ${{ secrets[env.SECRET_KEY] }}
233+
role-duration-seconds: 1200
234+
aws-region: ${{ matrix.aws_region }}
235+
- name: Get s3 bucket name for release
236+
run: |
237+
echo BUCKET_NAME=python-lambda-layer-${{ github.run_id }}-${{ matrix.aws_region }} | tee --append $GITHUB_ENV
238+
- name: download layer.zip
239+
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0
240+
with:
241+
name: layer.zip
242+
- name: publish
243+
run: |
244+
aws s3 mb s3://${{ env.BUCKET_NAME }}
245+
aws s3 cp aws-opentelemetry-python-layer.zip s3://${{ env.BUCKET_NAME }}
246+
layerARN=$(
247+
aws lambda publish-layer-version \
248+
--layer-name ${{ env.LAYER_NAME }} \
249+
--content S3Bucket=${{ env.BUCKET_NAME }},S3Key=aws-opentelemetry-python-layer.zip \
250+
--compatible-runtimes python3.10 python3.11 python3.12 python3.13 \
251+
--compatible-architectures "arm64" "x86_64" \
252+
--license-info "Apache-2.0" \
253+
--description "AWS Distro of OpenTelemetry Lambda Layer for Python Runtime" \
254+
--query 'LayerVersionArn' \
255+
--output text
256+
)
257+
echo $layerARN
258+
echo "LAYER_ARN=${layerARN}" >> $GITHUB_ENV
259+
mkdir ${{ env.LAYER_NAME }}
260+
echo $layerARN > ${{ env.LAYER_NAME }}/${{ matrix.aws_region }}
261+
cat ${{ env.LAYER_NAME }}/${{ matrix.aws_region }}
262+
- name: public layer
263+
run: |
264+
layerVersion=$(
265+
aws lambda list-layer-versions \
266+
--layer-name ${{ env.LAYER_NAME }} \
267+
--query 'max_by(LayerVersions, &Version).Version'
268+
)
269+
aws lambda add-layer-version-permission \
270+
--layer-name ${{ env.LAYER_NAME }} \
271+
--version-number $layerVersion \
272+
--principal "*" \
273+
--statement-id publish \
274+
--action lambda:GetLayerVersion
275+
- name: upload layer arn artifact
276+
if: ${{ success() }}
277+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2
278+
with:
279+
name: ${{ env.LAYER_NAME }}-${{ matrix.aws_region }}
280+
path: ${{ env.LAYER_NAME }}/${{ matrix.aws_region }}
281+
- name: clean s3
282+
if: always()
283+
run: |
284+
aws s3 rb --force s3://${{ env.BUCKET_NAME }}
285+
286+
generate-lambda-release-note:
287+
runs-on: ubuntu-latest
288+
needs: publish-layer-prod
289+
outputs:
290+
layer-note: ${{ steps.layer-note.outputs.layer-note }}
291+
steps:
292+
- name: Checkout Repo @ SHA - ${{ github.sha }}
293+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
294+
- uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd #v3.1.2
295+
- name: download layerARNs
296+
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0
297+
with:
298+
pattern: ${{ env.LAYER_NAME }}-*
299+
path: ${{ env.LAYER_NAME }}
300+
merge-multiple: true
301+
- name: show layerARNs
302+
run: |
303+
for file in ${{ env.LAYER_NAME }}/*
304+
do
305+
echo $file
306+
cat $file
307+
done
308+
- name: generate layer-note
309+
id: layer-note
310+
working-directory: ${{ env.LAYER_NAME }}
311+
run: |
312+
echo "| Region | Layer ARN |" >> ../layer-note
313+
echo "| ---- | ---- |" >> ../layer-note
314+
for file in *
315+
do
316+
read arn < $file
317+
echo "| " $file " | " $arn " |" >> ../layer-note
318+
done
319+
cd ..
320+
{
321+
echo "layer-note<<EOF"
322+
cat layer-note
323+
echo "EOF"
324+
} >> $GITHUB_OUTPUT
325+
cat layer-note
326+
- name: generate tf layer
327+
working-directory: ${{ env.LAYER_NAME }}
328+
run: |
329+
echo "locals {" >> ../layer_arns.tf
330+
echo " sdk_layer_arns = {" >> ../layer_arns.tf
331+
for file in *
332+
do
333+
read arn < $file
334+
echo " \""$file"\" = \""$arn"\"" >> ../layer_arns.tf
335+
done
336+
cd ..
337+
echo " }" >> layer_arns.tf
338+
echo "}" >> layer_arns.tf
339+
terraform fmt layer_arns.tf
340+
cat layer_arns.tf
341+
- name: generate layer ARN constants for CDK
342+
working-directory: ${{ env.LAYER_NAME }}
343+
run: |
344+
echo "{" > ../layer_cdk
345+
for file in *; do
346+
read arn < "$file"
347+
echo " \"$file\": \"$arn\"," >> ../layer_cdk
348+
done
349+
echo "}" >> ../layer_cdk
350+
cat ../layer_cdk
351+
352+
publish-github:
353+
needs: generate-lambda-release-note
354+
runs-on: ubuntu-latest
355+
steps:
356+
- name: Checkout Repo @ SHA - ${{ github.sha }}
357+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
358+
359+
- name: Download SDK artifact
360+
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0
361+
with:
362+
name: ${{ env.ARTIFACT_NAME }}
363+
364+
- name: Download layer.zip artifact
365+
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0
366+
with:
367+
name: layer.zip
141368

142-
- name: Get SHA256 checksum of wheel file
143-
id: get_sha256
369+
- name: Rename layer file
144370
run: |
145-
shasum -a 256 dist/${{ env.ARTIFACT_NAME }} | sed "s|dist/||" > ${{ env.ARTIFACT_NAME }}.sha256
371+
cp aws-opentelemetry-python-layer.zip layer.zip
146372
147373
# Publish to GitHub releases
148374
- name: Create GH release
149375
id: create_release
150376
env:
151-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
377+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
152378
run: |
153-
# Download layer.zip from existing latest tagged SDK release note
154-
LATEST_SDK_VERSION=$(gh release list --repo "aws-observability/aws-otel-python-instrumentation" --json tagName,isLatest -q 'map(select(.isLatest==true)) | .[0].tagName')
155-
mkdir -p layer_artifact
156-
gh release download "$LATEST_SDK_VERSION" --repo "aws-observability/aws-otel-python-instrumentation" --pattern "layer.zip" --dir layer_artifact
157-
shasum -a 256 layer_artifact/layer.zip > layer_artifact/layer.zip.sha256
379+
# Extract all dependencies from pyproject.toml
380+
DEPS=$(python3 -c "
381+
import re
382+
with open('aws-opentelemetry-distro/pyproject.toml', 'r') as f:
383+
content = f.read()
384+
deps_match = re.search(r'dependencies\s*=\s*\[(.*?)\]', content, re.DOTALL)
385+
if deps_match:
386+
deps_content = deps_match.group(1)
387+
dep_lines = re.findall(r'\"([^\"]+)\"', deps_content)
388+
formatted_deps = []
389+
for dep_line in dep_lines:
390+
if ' == ' in dep_line:
391+
package, version = dep_line.split(' == ', 1)
392+
formatted_deps.append(f'- \`{package}\` - {version}')
393+
else:
394+
formatted_deps.append(f'- \`{dep_line}\`')
395+
print('\n'.join(formatted_deps))
396+
")
397+
398+
# Create release notes
399+
cat > release_notes.md << EOF
400+
This release contains the following upstream components:
401+
402+
$DEPS
403+
404+
This release also publishes to public ECR and PyPi.
405+
* See ADOT Python auto-instrumentation Docker image v${{ github.event.inputs.version }} in our public ECR repository:
406+
https://gallery.ecr.aws/aws-observability/adot-autoinstrumentation-python
407+
* See version ${{ github.event.inputs.version }} in our PyPi repository:
408+
https://pypi.org/project/aws-opentelemetry-distro/
409+
410+
This release also includes the AWS OpenTelemetry Lambda Layer for Python version ${{ github.event.inputs.version }}-$(echo $GITHUB_SHA | cut -c1-7).
411+
412+
Lambda Layer ARNs:
413+
${{ needs.generate-lambda-release-note.outputs.layer-note }}
414+
EOF
415+
416+
shasum -a 256 ${{ env.ARTIFACT_NAME }} > ${{ env.ARTIFACT_NAME }}.sha256
417+
shasum -a 256 layer.zip > layer.zip.sha256
158418
159419
gh release create --target "$GITHUB_REF_NAME" \
160420
--title "Release v${{ github.event.inputs.version }}" \
421+
--notes-file release_notes.md \
161422
--draft \
162423
"v${{ github.event.inputs.version }}" \
163-
dist/${{ env.ARTIFACT_NAME }} \
424+
${{ env.ARTIFACT_NAME }} \
164425
${{ env.ARTIFACT_NAME }}.sha256 \
165-
layer_artifact/layer.zip \
166-
layer_artifact/layer.zip.sha256
426+
layer.zip \
427+
layer.zip.sha256

0 commit comments

Comments
 (0)