Skip to content

Build And Upload Distributor #5

Build And Upload Distributor

Build And Upload Distributor #5

name: Build And Upload Distributor
env:
CWA_GITHUB_TEST_REPO_NAME: "aws/amazon-cloudwatch-agent-test"
CWA_GITHUB_TEST_REPO_BRANCH: "fix/msiexec-hang-qn-norestart"
CHECKOUT_ROOT_DIR: "test"
SSM_DISTRIBUTOR_VERSION_LIMIT: 25
on:
workflow_dispatch:
inputs:
BucketKey:
# e.g. s3://<bucket>/integration-test/binary/<SHA>"
# e.g. s3://<bucket>/nonprod
# e.g. s3://<bucket>/release
description: "S3 URI to upload artifacts into."
required: true
type: string
PackageBucketKey:
description: "Integration tests put the MSI and PKG in a different bucket path than the binaries."
required: true
type: string
Region:
description: "Region to upload binaries"
required: false
type: string
default: "us-west-2"
TerraformAWSAssumeRole:
description: "Role to assume to upload artifacts"
required: true
type: string
Bucket:
description: "Bucket to upload the artifacts to"
required: true
type: string
DistributorName:
description: "SSM Distributor document name"
required: true
type: string
workflow_call:
inputs:
BucketKey:
# e.g. s3://<bucket>/integration-test/binary/<SHA>"
# e.g. s3://<bucket>/nonprod
# e.g. s3://<bucket>/release
description: "S3 URI to upload artifacts into."
required: true
type: string
PackageBucketKey:
description: "Integration tests put the MSI and PKG in a different bucket path than the binaries."
required: true
type: string
Region:
description: "Region to upload binaries"
required: false
type: string
default: "us-west-2"
TerraformAWSAssumeRole:
description: "Role to assume to upload artifacts"
required: true
type: string
Bucket:
description: "Bucket to upload the artifacts to"
required: true
type: string
DistributorName:
description: "SSM Distributor document name"
required: true
type: string
jobs:
AgentVersion:
name: 'AgentVersion'
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
outputs:
agent-version: ${{ steps.version.outputs.version }}
should-build: ${{ steps.check.outputs.should-build }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
fetch-depth: 0
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4.3.1
with:
role-to-assume: ${{ inputs.TerraformAWSAssumeRole }}
aws-region: ${{ inputs.Region }}
- name: Free up disk space
run: .github/scripts/free-disk-space.sh
- name: Agent Version
id: version
env:
INPUT_BUCKET: ${{ inputs.Bucket }}
INPUT_BUCKET_KEY: ${{ inputs.BucketKey }}
run: |
aws s3 cp "s3://$INPUT_BUCKET/$INPUT_BUCKET_KEY/CWAGENT_VERSION" .
echo "version=$(cat CWAGENT_VERSION)" >> "$GITHUB_OUTPUT"
- name: Check if SSM distributor version already exists
id: check
env:
INPUT_DISTRIBUTOR_NAME: ${{ inputs.DistributorName }}
INPUT_REGION: ${{ inputs.Region }}
AGENT_VERSION: ${{ steps.version.outputs.version }}
run: |
VERSION_EXISTS=$(aws ssm list-document-versions \
--name "$INPUT_DISTRIBUTOR_NAME" \
--region "$INPUT_REGION" \
--no-paginate \
--query "DocumentVersions[?VersionName=='$AGENT_VERSION']" \
--output text 2>/dev/null || true)
if [ -n "$VERSION_EXISTS" ]; then
echo "should-build=false" >> "$GITHUB_OUTPUT"
echo "Version $AGENT_VERSION already exists, skipping build"
else
echo "should-build=true" >> "$GITHUB_OUTPUT"
fi
PackageLinux:
name: 'PackageLinux'
runs-on: ubuntu-latest
needs: [AgentVersion]
if: needs.AgentVersion.outputs.should-build == 'true'
permissions:
id-token: write
contents: read
strategy:
matrix:
arch: [amd64, arm64]
env:
SOURCE_S3_PATH: s3://${{ inputs.Bucket }}/${{ inputs.BucketKey }}/linux/${{ matrix.arch }}
DESTINATION_S3_PATH: s3://${{ inputs.Bucket }}/${{ inputs.PackageBucketKey }}/linux/${{ matrix.arch }}/${{ needs.AgentVersion.outputs.agent-version }}
WORKING_DIRECTORY: distributor/linux/${{ matrix.arch }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
repository: ${{env.CWA_GITHUB_TEST_REPO_NAME}}
ref: ${{ env.CWA_GITHUB_TEST_REPO_BRANCH }}
path: ${{ env.CHECKOUT_ROOT_DIR }}
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4.3.1
with:
role-to-assume: ${{ inputs.TerraformAWSAssumeRole }}
aws-region: ${{ inputs.Region }}
- name: Prepare Linux package
run: |
mkdir -p "$WORKING_DIRECTORY"
aws s3 cp "$SOURCE_S3_PATH/amazon-cloudwatch-agent.rpm" "$WORKING_DIRECTORY/"
aws s3 cp "$SOURCE_S3_PATH/amazon-cloudwatch-agent.deb" "$WORKING_DIRECTORY/"
cp "${{ env.CHECKOUT_ROOT_DIR }}/packaging/linux/install.sh" "$WORKING_DIRECTORY/"
cp "${{ env.CHECKOUT_ROOT_DIR }}/packaging/linux/uninstall.sh" "$WORKING_DIRECTORY/"
cp "${{ env.CHECKOUT_ROOT_DIR }}/packaging/linux/detect-system.sh" "$WORKING_DIRECTORY/"
- name: Create manifest JSON
env:
INPUT_DISTRIBUTOR_NAME: ${{ inputs.DistributorName }}
MATRIX_ARCH: ${{ matrix.arch }}
AGENT_VERSION: ${{ needs.AgentVersion.outputs.agent-version }}
run: |
cat > "$WORKING_DIRECTORY/manifest.json" << EOF
{
"name": "$INPUT_DISTRIBUTOR_NAME",
"platform": "linux",
"architecture": "$MATRIX_ARCH",
"version": "$AGENT_VERSION"
}
EOF
- name: Zip
run: zip -j AmazonCloudWatchAgent.zip "$WORKING_DIRECTORY"/*
- name: Upload zip
run: aws s3 cp AmazonCloudWatchAgent.zip "$DESTINATION_S3_PATH/AmazonCloudWatchAgent.zip"
- name: Calculate checksum
run: echo "$(sha256sum AmazonCloudWatchAgent.zip | cut -d' ' -f1)" > checksum.txt
- name: Upload checksum
run: aws s3 cp checksum.txt "$DESTINATION_S3_PATH/checksum.txt"
PackageDarwin:
name: 'PackageDarwin'
runs-on: ubuntu-latest
needs: [AgentVersion]
if: needs.AgentVersion.outputs.should-build == 'true'
permissions:
id-token: write
contents: read
strategy:
matrix:
arch: [amd64, arm64]
env:
SOURCE_S3_PATH: s3://${{ inputs.Bucket }}/${{ inputs.PackageBucketKey }}/${{ matrix.arch }}
DESTINATION_S3_PATH: s3://${{ inputs.Bucket }}/${{ inputs.PackageBucketKey }}/darwin/${{ matrix.arch }}/${{ needs.AgentVersion.outputs.agent-version }}
WORKING_DIRECTORY: distributor/darwin/${{ matrix.arch }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
repository: ${{env.CWA_GITHUB_TEST_REPO_NAME}}
ref: ${{ env.CWA_GITHUB_TEST_REPO_BRANCH }}
path: ${{ env.CHECKOUT_ROOT_DIR }}
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4.3.1
with:
role-to-assume: ${{ inputs.TerraformAWSAssumeRole }}
aws-region: ${{ inputs.Region }}
- name: Prepare macOS package
run: |
mkdir -p "$WORKING_DIRECTORY"
aws s3 cp "$SOURCE_S3_PATH/amazon-cloudwatch-agent.pkg" "$WORKING_DIRECTORY/"
cp "${{ env.CHECKOUT_ROOT_DIR }}/packaging/darwin/install.sh" "$WORKING_DIRECTORY/"
cp "${{ env.CHECKOUT_ROOT_DIR }}/packaging/darwin/uninstall.sh" "$WORKING_DIRECTORY/"
- name: Create manifest JSON
env:
INPUT_DISTRIBUTOR_NAME: ${{ inputs.DistributorName }}
MATRIX_ARCH: ${{ matrix.arch }}
AGENT_VERSION: ${{ needs.AgentVersion.outputs.agent-version }}
run: |
cat > "$WORKING_DIRECTORY/manifest.json" << EOF
{
"name": "$INPUT_DISTRIBUTOR_NAME",
"platform": "mac_os_x",
"architecture": "$MATRIX_ARCH",
"version": "$AGENT_VERSION"
}
EOF
- name: Zip
run: zip -j AmazonCloudWatchAgent.zip "$WORKING_DIRECTORY"/*
- name: Upload zip
run: aws s3 cp AmazonCloudWatchAgent.zip "$DESTINATION_S3_PATH/AmazonCloudWatchAgent.zip"
- name: Calculate checksum
run: echo "$(sha256sum AmazonCloudWatchAgent.zip | cut -d' ' -f1)" > checksum.txt
- name: Upload checksum
run: aws s3 cp checksum.txt "$DESTINATION_S3_PATH/checksum.txt"
PackageWindows:
name: 'PackageWindows'
runs-on: ubuntu-latest
needs: [AgentVersion]
if: needs.AgentVersion.outputs.should-build == 'true'
permissions:
id-token: write
contents: read
env:
SOURCE_S3_PATH: s3://${{ inputs.Bucket }}/${{ inputs.PackageBucketKey }}
DESTINATION_S3_PATH: s3://${{ inputs.Bucket }}/${{ inputs.PackageBucketKey }}/windows/amd64/${{ needs.AgentVersion.outputs.agent-version }}
WORKING_DIRECTORY: distributor/windows/amd64
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
repository: ${{env.CWA_GITHUB_TEST_REPO_NAME}}
ref: ${{ env.CWA_GITHUB_TEST_REPO_BRANCH }}
path: ${{ env.CHECKOUT_ROOT_DIR }}
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4.3.1
with:
role-to-assume: ${{ inputs.TerraformAWSAssumeRole }}
aws-region: ${{ inputs.Region }}
- name: Prepare Windows package
run: |
mkdir -p "$WORKING_DIRECTORY"
aws s3 cp "$SOURCE_S3_PATH/amazon-cloudwatch-agent.msi" "$WORKING_DIRECTORY/"
cp "${{ env.CHECKOUT_ROOT_DIR }}/packaging/windows/install.ps1" "$WORKING_DIRECTORY/"
cp "${{ env.CHECKOUT_ROOT_DIR }}/packaging/windows/uninstall.ps1" "$WORKING_DIRECTORY/"
- name: Create manifest JSON
env:
INPUT_DISTRIBUTOR_NAME: ${{ inputs.DistributorName }}
AGENT_VERSION: ${{ needs.AgentVersion.outputs.agent-version }}
run: |
cat > "$WORKING_DIRECTORY/manifest.json" << EOF
{
"name": "$INPUT_DISTRIBUTOR_NAME",
"platform": "windows",
"architecture": "amd64",
"version": "$AGENT_VERSION"
}
EOF
- name: Zip
run: zip -j AmazonCloudWatchAgent.zip "$WORKING_DIRECTORY"/*
- name: Upload zip
run: aws s3 cp AmazonCloudWatchAgent.zip "$DESTINATION_S3_PATH/AmazonCloudWatchAgent.zip"
- name: Calculate checksum
run: echo "$(sha256sum AmazonCloudWatchAgent.zip | cut -d' ' -f1)" > checksum.txt
- name: Upload checksum
run: aws s3 cp checksum.txt "$DESTINATION_S3_PATH/checksum.txt"
UploadDistributor:
name: 'UploadDistributor'
runs-on: ubuntu-latest
needs: [AgentVersion, PackageLinux, PackageDarwin, PackageWindows]
if: needs.AgentVersion.outputs.should-build == 'true'
permissions:
id-token: write
contents: read
env:
AGENT_VERSION: ${{ needs.AgentVersion.outputs.agent-version }}
S3_PATH: s3://${{ inputs.Bucket }}/${{ inputs.PackageBucketKey }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
repository: ${{env.CWA_GITHUB_TEST_REPO_NAME}}
ref: ${{ env.CWA_GITHUB_TEST_REPO_BRANCH }}
path: ${{ env.CHECKOUT_ROOT_DIR }}
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4.3.1
with:
role-to-assume: ${{ inputs.TerraformAWSAssumeRole }}
aws-region: ${{ inputs.Region }}
- name: Download checksums
run: |
mkdir -p checksum/{windows/amd64,linux/{amd64,arm64},darwin/{amd64,arm64}}
aws s3 cp "$S3_PATH/windows/amd64/$AGENT_VERSION/checksum.txt" checksum/windows/amd64/
aws s3 cp "$S3_PATH/linux/amd64/$AGENT_VERSION/checksum.txt" checksum/linux/amd64/
aws s3 cp "$S3_PATH/linux/arm64/$AGENT_VERSION/checksum.txt" checksum/linux/arm64/
aws s3 cp "$S3_PATH/darwin/amd64/$AGENT_VERSION/checksum.txt" checksum/darwin/amd64/
aws s3 cp "$S3_PATH/darwin/arm64/$AGENT_VERSION/checksum.txt" checksum/darwin/arm64/
- name: Create manifest JSON
run: |
export WINDOWS_AMD64_SHA=$(cat checksum/windows/amd64/checksum.txt)
export LINUX_AMD64_SHA=$(cat checksum/linux/amd64/checksum.txt)
export LINUX_ARM64_SHA=$(cat checksum/linux/arm64/checksum.txt)
export DARWIN_AMD64_SHA=$(cat checksum/darwin/amd64/checksum.txt)
export DARWIN_ARM64_SHA=$(cat checksum/darwin/arm64/checksum.txt)
envsubst < "${{ env.CHECKOUT_ROOT_DIR }}/packaging/manifest.json" > manifest.json
- name: Upload manifest JSON to S3
run: aws s3 cp manifest.json "$S3_PATH/manifest.json"
- name: Check if distributor exists
id: check-distributor
env:
INPUT_DISTRIBUTOR_NAME: ${{ inputs.DistributorName }}
INPUT_REGION: ${{ inputs.Region }}
run: |
if aws ssm describe-document --name "$INPUT_DISTRIBUTOR_NAME" --region "$INPUT_REGION" 2>/dev/null; then
echo "exists=true" >> "$GITHUB_OUTPUT"
else
echo "exists=false" >> "$GITHUB_OUTPUT"
fi
- name: Create distributor
if: steps.check-distributor.outputs.exists == 'false'
env:
INPUT_DISTRIBUTOR_NAME: ${{ inputs.DistributorName }}
INPUT_REGION: ${{ inputs.Region }}
AGENT_VERSION: ${{ needs.AgentVersion.outputs.agent-version }}
run: |
aws ssm create-document \
--name "$INPUT_DISTRIBUTOR_NAME" \
--content file://manifest.json \
--attachments Key="SourceUrl",Values="$S3_PATH" \
--version-name "$AGENT_VERSION" \
--document-type Package \
--region "$INPUT_REGION"
- name: Remove oldest if limit hit
if: steps.check-distributor.outputs.exists == 'true'
env:
INPUT_DISTRIBUTOR_NAME: ${{ inputs.DistributorName }}
INPUT_REGION: ${{ inputs.Region }}
run: |
VERSION_COUNT=$(aws ssm list-document-versions --name "$INPUT_DISTRIBUTOR_NAME" --region "$INPUT_REGION" --no-paginate --query 'length(DocumentVersions)' --output text)
if [ "$VERSION_COUNT" -ge "${{ env.SSM_DISTRIBUTOR_VERSION_LIMIT }}" ]; then
OLDEST_VERSION=$(aws ssm list-document-versions --name "$INPUT_DISTRIBUTOR_NAME" --region "$INPUT_REGION" --no-paginate --query 'DocumentVersions[-1].DocumentVersion' --output text)
echo "Deleting oldest version: $OLDEST_VERSION"
aws ssm delete-document --name "$INPUT_DISTRIBUTOR_NAME" --document-version "$OLDEST_VERSION" --region "$INPUT_REGION"
fi
- name: Update distributor
if: steps.check-distributor.outputs.exists == 'true'
env:
INPUT_DISTRIBUTOR_NAME: ${{ inputs.DistributorName }}
INPUT_REGION: ${{ inputs.Region }}
AGENT_VERSION: ${{ needs.AgentVersion.outputs.agent-version }}
run: |
aws ssm update-document \
--name "$INPUT_DISTRIBUTOR_NAME" \
--content file://manifest.json \
--attachments Key="SourceUrl",Values="$S3_PATH" \
--version-name "$AGENT_VERSION" \
--document-version "\$LATEST" \
--region "$INPUT_REGION"
- name: Verify distributor
uses: nick-fields/retry@14672906e672a08bd6eeb15720e9ed3ce869cdd4 # v2.9.0
env:
INPUT_DISTRIBUTOR_NAME: ${{ inputs.DistributorName }}
INPUT_REGION: ${{ inputs.Region }}
with:
max_attempts: 6
timeout_minutes: 5
retry_wait_seconds: 10
command: |
STATUS=$(aws ssm describe-document --name "$INPUT_DISTRIBUTOR_NAME" --region "$INPUT_REGION" --query 'Document.Status' --output text)
if [ "$STATUS" != "Active" ]; then
echo "Error: Document status is $STATUS, expected Active"
exit 1
fi
echo "Document is Active"
- name: Update default version
env:
INPUT_DISTRIBUTOR_NAME: ${{ inputs.DistributorName }}
INPUT_REGION: ${{ inputs.Region }}
run: |
CURRENT_DEFAULT=$(aws ssm describe-document --name "$INPUT_DISTRIBUTOR_NAME" --region "$INPUT_REGION" --query 'Document.DefaultVersion' --output text)
LATEST_VERSION=$(aws ssm describe-document --name "$INPUT_DISTRIBUTOR_NAME" --region "$INPUT_REGION" --query 'Document.LatestVersion' --output text)
if [ "$CURRENT_DEFAULT" != "$LATEST_VERSION" ]; then
aws ssm update-document-default-version \
--name "$INPUT_DISTRIBUTOR_NAME" \
--document-version "$LATEST_VERSION" \
--region "$INPUT_REGION"
else
echo "Default version already matches latest version"
fi