Skip to content

Commit ed13492

Browse files
ezhang6811thpierce
andauthored
Cherry-pick release workflow updates (#504)
*Issue #, if available:* *Description of changes:* Applied #461 and #487 to the release/v0.12.x branch. 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 1029710 commit ed13492

File tree

2 files changed

+301
-256
lines changed

2 files changed

+301
-256
lines changed

.github/workflows/release-build.yml

Lines changed: 301 additions & 17 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,56 @@ 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+
env:
85+
AWS_REGIONS: ${{ github.event.inputs.aws_region }}
86+
run: |
87+
IFS=',' read -ra REGIONS <<< "$AWS_REGIONS"
88+
MATRIX="["
89+
for region in "${REGIONS[@]}"; do
90+
trimmed_region=$(echo "$region" | xargs)
91+
MATRIX+="\"$trimmed_region\","
92+
done
93+
MATRIX="${MATRIX%,}]"
94+
echo ${MATRIX}
95+
echo "aws_regions_json=${MATRIX}" >> $GITHUB_OUTPUT
96+
- name: Checkout Repo @ SHA - ${{ github.sha }}
97+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
98+
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c #v6.0.0
99+
with:
100+
python-version: '3.x'
101+
- name: Build layers
102+
working-directory: lambda-layer/src
103+
run: |
104+
./build-lambda-layer.sh
105+
pip install tox
106+
tox
107+
- name: upload layer
108+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2
109+
with:
110+
name: layer.zip
111+
path: lambda-layer/src/build/aws-opentelemetry-python-layer.zip
112+
113+
publish-sdk:
114+
needs: [build-sdk, build-layer]
115+
runs-on: ubuntu-latest
116+
steps:
117+
- name: Checkout Repo @ SHA - ${{ github.sha }}
118+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
119+
63120
- name: Configure AWS credentials for PyPI secrets
64121
uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0
65122
with:
@@ -102,20 +159,25 @@ jobs:
102159
- name: Install twine
103160
run: pip install twine
104161

162+
- name: Download SDK artifact
163+
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0
164+
with:
165+
name: ${{ env.ARTIFACT_NAME }}
166+
105167
- name: Publish to TestPyPI
106168
env:
107169
TWINE_USERNAME: '__token__'
108170
TWINE_PASSWORD: ${{ env.TEST_PYPI_TOKEN_API_TOKEN }}
109171
run: |
110-
twine upload --repository testpypi --skip-existing --verbose dist/${{ env.ARTIFACT_NAME }}
172+
twine upload --repository testpypi --skip-existing --verbose ${{ env.ARTIFACT_NAME }}
111173
112174
# Publish to prod PyPI
113175
- name: Publish to PyPI
114176
env:
115177
TWINE_USERNAME: '__token__'
116178
TWINE_PASSWORD: ${{ env.PROD_PYPI_TOKEN_API_TOKEN }}
117179
run: |
118-
twine upload --skip-existing --verbose dist/${{ env.ARTIFACT_NAME }}
180+
twine upload --skip-existing --verbose ${{ env.ARTIFACT_NAME }}
119181
120182
# Publish to public ECR
121183
- name: Build and push public ECR image
@@ -138,29 +200,251 @@ jobs:
138200
platforms: linux/amd64,linux/arm64
139201
tags: |
140202
${{ env.RELEASE_PRIVATE_REPOSITORY }}:v${{ github.event.inputs.version }}
203+
204+
publish-layer-prod:
205+
runs-on: ubuntu-latest
206+
needs: [build-layer, publish-sdk]
207+
strategy:
208+
matrix:
209+
aws_region: ${{ fromJson(needs.build-layer.outputs.aws_regions_json) }}
210+
steps:
211+
- name: role arn
212+
env:
213+
LEGACY_COMMERCIAL_REGIONS: ${{ env.LEGACY_COMMERCIAL_REGIONS }}
214+
run: |
215+
LEGACY_COMMERCIAL_REGIONS_ARRAY=(${LEGACY_COMMERCIAL_REGIONS//,/ })
216+
FOUND=false
217+
for REGION in "${LEGACY_COMMERCIAL_REGIONS_ARRAY[@]}"; do
218+
if [[ "$REGION" == "${{ matrix.aws_region }}" ]]; then
219+
FOUND=true
220+
break
221+
fi
222+
done
223+
if [ "$FOUND" = true ]; then
224+
echo "Found ${{ matrix.aws_region }} in LEGACY_COMMERCIAL_REGIONS"
225+
SECRET_KEY="LAMBDA_LAYER_RELEASE"
226+
else
227+
echo "Not found ${{ matrix.aws_region }} in LEGACY_COMMERCIAL_REGIONS"
228+
SECRET_KEY="${{ matrix.aws_region }}_LAMBDA_LAYER_RELEASE"
229+
fi
230+
SECRET_KEY=${SECRET_KEY//-/_}
231+
echo "SECRET_KEY=${SECRET_KEY}" >> $GITHUB_ENV
232+
- uses: aws-actions/configure-aws-credentials@a03048d87541d1d9fcf2ecf528a4a65ba9bd7838 #v5.0.0
233+
with:
234+
role-to-assume: ${{ secrets[env.SECRET_KEY] }}
235+
role-duration-seconds: 1200
236+
aws-region: ${{ matrix.aws_region }}
237+
- name: Get s3 bucket name for release
238+
run: |
239+
echo BUCKET_NAME=python-lambda-layer-${{ github.run_id }}-${{ matrix.aws_region }} | tee --append $GITHUB_ENV
240+
- name: download layer.zip
241+
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0
242+
with:
243+
name: layer.zip
244+
- name: publish
245+
run: |
246+
aws s3 mb s3://${{ env.BUCKET_NAME }}
247+
aws s3 cp aws-opentelemetry-python-layer.zip s3://${{ env.BUCKET_NAME }}
248+
layerARN=$(
249+
aws lambda publish-layer-version \
250+
--layer-name ${{ env.LAYER_NAME }} \
251+
--content S3Bucket=${{ env.BUCKET_NAME }},S3Key=aws-opentelemetry-python-layer.zip \
252+
--compatible-runtimes python3.10 python3.11 python3.12 python3.13 \
253+
--compatible-architectures "arm64" "x86_64" \
254+
--license-info "Apache-2.0" \
255+
--description "AWS Distro of OpenTelemetry Lambda Layer for Python Runtime" \
256+
--query 'LayerVersionArn' \
257+
--output text
258+
)
259+
echo $layerARN
260+
echo "LAYER_ARN=${layerARN}" >> $GITHUB_ENV
261+
mkdir ${{ env.LAYER_NAME }}
262+
echo $layerARN > ${{ env.LAYER_NAME }}/${{ matrix.aws_region }}
263+
cat ${{ env.LAYER_NAME }}/${{ matrix.aws_region }}
264+
- name: public layer
265+
run: |
266+
layerVersion=$(
267+
aws lambda list-layer-versions \
268+
--layer-name ${{ env.LAYER_NAME }} \
269+
--query 'max_by(LayerVersions, &Version).Version'
270+
)
271+
aws lambda add-layer-version-permission \
272+
--layer-name ${{ env.LAYER_NAME }} \
273+
--version-number $layerVersion \
274+
--principal "*" \
275+
--statement-id publish \
276+
--action lambda:GetLayerVersion
277+
- name: upload layer arn artifact
278+
if: ${{ success() }}
279+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2
280+
with:
281+
name: ${{ env.LAYER_NAME }}-${{ matrix.aws_region }}
282+
path: ${{ env.LAYER_NAME }}/${{ matrix.aws_region }}
283+
- name: clean s3
284+
if: always()
285+
run: |
286+
aws s3 rb --force s3://${{ env.BUCKET_NAME }}
141287
142-
- name: Get SHA256 checksum of wheel file
143-
id: get_sha256
288+
generate-lambda-release-note:
289+
runs-on: ubuntu-latest
290+
needs: publish-layer-prod
291+
outputs:
292+
layer-note: ${{ steps.layer-note.outputs.layer-note }}
293+
steps:
294+
- name: Checkout Repo @ SHA - ${{ github.sha }}
295+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
296+
- uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd #v3.1.2
297+
- name: download layerARNs
298+
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0
299+
with:
300+
pattern: ${{ env.LAYER_NAME }}-*
301+
path: ${{ env.LAYER_NAME }}
302+
merge-multiple: true
303+
- name: show layerARNs
304+
run: |
305+
for file in ${{ env.LAYER_NAME }}/*
306+
do
307+
echo $file
308+
cat $file
309+
done
310+
- name: generate layer-note
311+
id: layer-note
312+
working-directory: ${{ env.LAYER_NAME }}
313+
run: |
314+
echo "| Region | Layer ARN |" >> ../layer-note
315+
echo "| ---- | ---- |" >> ../layer-note
316+
for file in *
317+
do
318+
read arn < $file
319+
echo "| " $file " | " $arn " |" >> ../layer-note
320+
done
321+
cd ..
322+
{
323+
echo "layer-note<<EOF"
324+
cat layer-note
325+
echo "EOF"
326+
} >> $GITHUB_OUTPUT
327+
cat layer-note
328+
- name: generate tf layer
329+
working-directory: ${{ env.LAYER_NAME }}
330+
run: |
331+
echo "locals {" >> ../layer_arns.tf
332+
echo " sdk_layer_arns = {" >> ../layer_arns.tf
333+
for file in *
334+
do
335+
read arn < $file
336+
echo " \""$file"\" = \""$arn"\"" >> ../layer_arns.tf
337+
done
338+
cd ..
339+
echo " }" >> layer_arns.tf
340+
echo "}" >> layer_arns.tf
341+
terraform fmt layer_arns.tf
342+
cat layer_arns.tf
343+
- name: generate layer ARN constants for CDK
344+
working-directory: ${{ env.LAYER_NAME }}
345+
run: |
346+
echo "{" > ../layer_cdk
347+
for file in *; do
348+
read arn < "$file"
349+
echo " \"$file\": \"$arn\"," >> ../layer_cdk
350+
done
351+
echo "}" >> ../layer_cdk
352+
cat ../layer_cdk
353+
354+
publish-github:
355+
needs: generate-lambda-release-note
356+
runs-on: ubuntu-latest
357+
steps:
358+
- name: Checkout Repo @ SHA - ${{ github.sha }}
359+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
360+
361+
- name: Download SDK artifact
362+
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0
363+
with:
364+
name: ${{ env.ARTIFACT_NAME }}
365+
366+
- name: Download layer.zip artifact
367+
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0
368+
with:
369+
name: layer.zip
370+
371+
- name: Rename layer file
144372
run: |
145-
shasum -a 256 dist/${{ env.ARTIFACT_NAME }} | sed "s|dist/||" > ${{ env.ARTIFACT_NAME }}.sha256
373+
cp aws-opentelemetry-python-layer.zip layer.zip
146374
147375
# Publish to GitHub releases
148376
- name: Create GH release
149377
id: create_release
150378
env:
151-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
379+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
380+
VERSION: ${{ github.event.inputs.version }}
152381
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
382+
# Extract all dependencies from pyproject.toml
383+
DEPS=$(python3 -c "
384+
import re
385+
with open('aws-opentelemetry-distro/pyproject.toml', 'r') as f:
386+
content = f.read()
387+
deps_match = re.search(r'dependencies\s*=\s*\[(.*?)\]', content, re.DOTALL)
388+
if deps_match:
389+
deps_content = deps_match.group(1)
390+
dep_lines = re.findall(r'\"([^\"]+)\"', deps_content)
391+
formatted_deps = []
392+
for dep_line in dep_lines:
393+
if ' == ' in dep_line:
394+
package, version = dep_line.split(' == ', 1)
395+
formatted_deps.append(f'- \`{package}\` - {version}')
396+
else:
397+
formatted_deps.append(f'- \`{dep_line}\`')
398+
print('\n'.join(formatted_deps))
399+
")
400+
401+
# Extract CHANGELOG entries for this version
402+
CHANGELOG_ENTRIES=$(python3 -c "
403+
import re, os
404+
version = os.environ['VERSION']
405+
with open('CHANGELOG.md', 'r') as f:
406+
content = f.read()
407+
version_pattern = rf'## v{re.escape(version)}.*?\n(.*?)(?=\n## |\Z)'
408+
version_match = re.search(version_pattern, content, re.DOTALL)
409+
if version_match:
410+
entries = version_match.group(1).strip()
411+
if entries:
412+
print(entries)
413+
")
414+
415+
# Create release notes
416+
cat > release_notes.md << EOF
417+
$(if [ -n "$CHANGELOG_ENTRIES" ]; then echo "## What's Changed"; echo "$CHANGELOG_ENTRIES"; echo ""; fi)
418+
419+
## Upstream Components
420+
421+
$DEPS
422+
423+
## Release Artifacts
424+
425+
This release publishes to public ECR and PyPi.
426+
* See ADOT Python auto-instrumentation Docker image v$VERSION in our public ECR repository:
427+
https://gallery.ecr.aws/aws-observability/adot-autoinstrumentation-python
428+
* See version $VERSION in our PyPi repository:
429+
https://pypi.org/project/aws-opentelemetry-distro/
430+
431+
## Lambda Layer
432+
433+
This release includes the AWS OpenTelemetry Lambda Layer for Python version $VERSION-$(echo $GITHUB_SHA | cut -c1-7).
434+
435+
Lambda Layer ARNs:
436+
${{ needs.generate-lambda-release-note.outputs.layer-note }}
437+
EOF
438+
439+
shasum -a 256 ${{ env.ARTIFACT_NAME }} > ${{ env.ARTIFACT_NAME }}.sha256
440+
shasum -a 256 layer.zip > layer.zip.sha256
158441
159442
gh release create --target "$GITHUB_REF_NAME" \
160-
--title "Release v${{ github.event.inputs.version }}" \
443+
--title "Release v$VERSION" \
444+
--notes-file release_notes.md \
161445
--draft \
162-
"v${{ github.event.inputs.version }}" \
163-
dist/${{ env.ARTIFACT_NAME }} \
446+
"v$VERSION" \
447+
${{ env.ARTIFACT_NAME }} \
164448
${{ env.ARTIFACT_NAME }}.sha256 \
165-
layer_artifact/layer.zip \
166-
layer_artifact/layer.zip.sha256
449+
layer.zip \
450+
layer.zip.sha256

0 commit comments

Comments
 (0)