Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 56 additions & 52 deletions .gitlab/package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -181,67 +181,71 @@ publish-wheels-to-s3:
tags: ["arch:amd64"]
image: registry.ddbuild.io/images/mirror/amazon/aws-cli:2.4.29
stage: package
needs:
- job: "ddtrace package"
artifacts: true
needs: [ "ddtrace package", "package version" ]
variables:
BUCKET: dd-trace-py-builds
script:
- set -euo pipefail
- shopt -s nullglob
# Find wheels
- WHEELS=(pywheels/*.whl)
- |
if [ ${#WHEELS[@]} -eq 0 ]; then
echo "No wheels found in pywheels/"; exit 1
fi
- echo "Found ${#WHEELS[@]} wheel(s):"
- printf ' - %s\n' "${WHEELS[@]}"
script: |
set -euo pipefail
shopt -s nullglob

# Upload all wheels to commit prefix and pipeline-id prefix
- aws s3 cp --recursive --exclude "*" --include "*.whl" pywheels "s3://${BUCKET}/${CI_COMMIT_SHA}/"
- aws s3 cp --recursive --exclude "*" --include "*.whl" pywheels "s3://${BUCKET}/${CI_PIPELINE_ID}/"
# Find wheels
WHEELS=(pywheels/*.whl)
if [ ${#WHEELS[@]} -eq 0 ]; then echo "No wheels found in pywheels/"; exit 1; fi
echo "Found ${#WHEELS[@]} wheel(s):"
printf ' - %s\n' "${WHEELS[@]}"

- |
S3_BASE_COMMIT="https://${BUCKET}.s3.amazonaws.com/${CI_COMMIT_SHA}"
S3_BASE_PIPE="https://${BUCKET}.s3.amazonaws.com/${CI_PIPELINE_ID}"
# Upload wheels to S3
aws s3 cp --recursive --exclude "*" --include "*.whl" pywheels "s3://${BUCKET}/${CI_COMMIT_SHA}/"
aws s3 cp --recursive --exclude "*" --include "*.whl" pywheels "s3://${BUCKET}/${CI_PIPELINE_ID}/"

generate_index_html() {
local outfile="$1"
{
echo "<!DOCTYPE html><html lang=\"en\"><body>"
for w in "${WHEELS[@]}"; do
fname="$(basename "$w")"
enc_fname="${fname//+/%2B}"
echo "<a href=\"${enc_fname}\">${fname}</a><br>"
done
echo "</body></html>"
} > "${outfile}"
}
# Generate and upload helper scripts and index for commit
S3_BASE_COMMIT="https://${BUCKET}.s3.amazonaws.com/${CI_COMMIT_SHA}"
.gitlab/scripts/generate-s3-helper-scripts.sh "${S3_BASE_COMMIT}" "commit"
.gitlab/scripts/generate-index-html.sh "commit"
aws s3 cp "commit.download.sh" "s3://${BUCKET}/${CI_COMMIT_SHA}/download.sh" --content-type text/x-shellscript
aws s3 cp "commit.install.sh" "s3://${BUCKET}/${CI_COMMIT_SHA}/install.sh" --content-type text/x-shellscript
aws s3 cp "commit.index.html" "s3://${BUCKET}/${CI_COMMIT_SHA}/index.html" --content-type text/html

# Generate both minimal indexes
generate_index_html "index.commit.html"
generate_index_html "index.pipeline.html"
# Generate and upload helper scripts and index for pipeline
S3_BASE_PIPE="https://${BUCKET}.s3.amazonaws.com/${CI_PIPELINE_ID}"
.gitlab/scripts/generate-s3-helper-scripts.sh "${S3_BASE_PIPE}" "pipeline"
.gitlab/scripts/generate-index-html.sh "pipeline"
aws s3 cp "pipeline.download.sh" "s3://${BUCKET}/${CI_PIPELINE_ID}/download.sh" --content-type text/x-shellscript
aws s3 cp "pipeline.install.sh" "s3://${BUCKET}/${CI_PIPELINE_ID}/install.sh" --content-type text/x-shellscript
aws s3 cp "pipeline.index.html" "s3://${BUCKET}/${CI_PIPELINE_ID}/index.html" --content-type text/html

# Upload to each S3 prefix
aws s3 cp "index.commit.html" "s3://${BUCKET}/${CI_COMMIT_SHA}/index.html" --content-type text/html
aws s3 cp "index.pipeline.html" "s3://${BUCKET}/${CI_PIPELINE_ID}/index.html" --content-type text/html
# Branch uploads (if on main or release branch)
if [ "${CI_COMMIT_BRANCH:-}" = "main" ] || [[ "${CI_COMMIT_BRANCH:-}" =~ ^[0-9]+\.[0-9]+$ ]]; then
aws s3 cp --recursive --exclude "*" --include "*.whl" pywheels "s3://${BUCKET}/${CI_COMMIT_BRANCH}/"

# Print the clickable URLs
COMMIT_INDEX_URL="${S3_BASE_COMMIT}/index.html"
PIPE_INDEX_URL="${S3_BASE_PIPE}/index.html"
echo "S3 index (commit): ${COMMIT_INDEX_URL}"
echo "S3 index (pipeline): ${PIPE_INDEX_URL}"
S3_BASE_BRANCH="https://${BUCKET}.s3.amazonaws.com/${CI_COMMIT_BRANCH}"
.gitlab/scripts/generate-s3-helper-scripts.sh "${S3_BASE_BRANCH}" "branch"
.gitlab/scripts/generate-index-html.sh "branch"
aws s3 cp "branch.download.sh" "s3://${BUCKET}/${CI_COMMIT_BRANCH}/download.sh" --content-type text/x-shellscript
aws s3 cp "branch.install.sh" "s3://${BUCKET}/${CI_COMMIT_BRANCH}/install.sh" --content-type text/x-shellscript
aws s3 cp "branch.index.html" "s3://${BUCKET}/${CI_COMMIT_BRANCH}/index.html" --content-type text/html
fi

# Also publish to branch path if on main or a release branch
if [ "${CI_COMMIT_BRANCH:-}" = "main" ] || [[ "${CI_COMMIT_BRANCH:-}" =~ ^[0-9]+\.[0-9]+$ ]]; then
echo "Publishing to ${CI_COMMIT_BRANCH}/ path"
aws s3 cp --recursive --exclude "*" --include "*.whl" pywheels "s3://${BUCKET}/${CI_COMMIT_BRANCH}/"
generate_index_html "index.branch.html"
aws s3 cp "index.branch.html" "s3://${BUCKET}/${CI_COMMIT_BRANCH}/index.html" --content-type text/html
BRANCH_INDEX_URL="https://${BUCKET}.s3.amazonaws.com/${CI_COMMIT_BRANCH}/index.html"
echo "S3 index (branch): ${BRANCH_INDEX_URL}"
fi
# Print all URLs at the end (after noisy aws s3 cp commands)
echo ""
echo "=== Artifacts published to S3 ==="
echo ""
echo "Commit artifacts:"
echo " Index: ${S3_BASE_COMMIT}/index.html"
echo " Download: ${S3_BASE_COMMIT}/download.sh"
echo " Install: ${S3_BASE_COMMIT}/install.sh"
echo ""
echo "Pipeline artifacts:"
echo " Index: ${S3_BASE_PIPE}/index.html"
echo " Download: ${S3_BASE_PIPE}/download.sh"
echo " Install: ${S3_BASE_PIPE}/install.sh"
if [ "${CI_COMMIT_BRANCH:-}" = "main" ] || [[ "${CI_COMMIT_BRANCH:-}" =~ ^[0-9]+\.[0-9]+$ ]]; then
echo ""
echo "Branch artifacts (${CI_COMMIT_BRANCH}):"
echo " Index: ${S3_BASE_BRANCH}/index.html"
echo " Download: ${S3_BASE_BRANCH}/download.sh"
echo " Install: ${S3_BASE_BRANCH}/install.sh"
fi

# Extract package version from pyproject.toml and save to dotenv artifact
"package version":
Expand Down
33 changes: 33 additions & 0 deletions .gitlab/scripts/generate-index-html.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -euo pipefail

# Usage: generate-index-html.sh <output_prefix>
# Example: generate-index-html.sh "commit"

if [ $# -ne 1 ]; then
echo "Usage: $0 <output_prefix>" >&2
exit 1
fi

OUTPUT_PREFIX="$1"

# Find all wheels
WHEELS=(pywheels/*.whl)
if [ ${#WHEELS[@]} -eq 0 ]; then
echo "ERROR: No wheels found in pywheels/" >&2
exit 1
fi

# Generate index.html
{
echo '<!DOCTYPE html><html lang="en"><body>'
for w in "${WHEELS[@]}"; do
fname="$(basename "$w")"
# URL-encode special characters (especially +)
enc_fname="${fname//+/%2B}"
echo "<a href=\"${enc_fname}\">${fname}</a><br>"
done
echo "</body></html>"
} > "${OUTPUT_PREFIX}.index.html"

echo "Generated ${OUTPUT_PREFIX}.index.html"
121 changes: 121 additions & 0 deletions .gitlab/scripts/generate-s3-helper-scripts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#!/usr/bin/env bash
set -euo pipefail

# Usage: generate-s3-helper-scripts.sh <s3_base_url> <output_prefix>
# Example: generate-s3-helper-scripts.sh "https://dd-trace-py-builds.s3.amazonaws.com/main" "main"

if [ $# -ne 2 ]; then
echo "Usage: $0 <s3_base_url> <output_prefix>" >&2
exit 1
fi

S3_BASE_URL="$1"
OUTPUT_PREFIX="$2"

if [ -z "${PACKAGE_VERSION:-}" ]; then
echo "Error: PACKAGE_VERSION environment variable is not set." >&2
exit 1
fi
echo "Detected version: ${PACKAGE_VERSION}"

# Generate download.sh
cat > "${OUTPUT_PREFIX}.download.sh" << 'DOWNLOAD_SCRIPT_EOF'
#!/usr/bin/env bash
set -euo pipefail

# Parse arguments
DEST_DIR="."
PIP_ARGS=""

while [[ $# -gt 0 ]]; do
case $1 in
--dest)
DEST_DIR="$2"
shift 2
;;
--python-version)
PIP_ARGS="$PIP_ARGS --python-version $2"
shift 2
;;
--platform)
PIP_ARGS="$PIP_ARGS --platform $2"
shift 2
;;
*)
echo "Unknown option: $1" >&2
echo "Usage: $0 [--dest DIR] [--python-version VERSION] [--platform PLATFORM]" >&2
exit 1
;;
esac
done

# Download wheel
echo "Downloading ddtrace==VERSION_PLACEHOLDER from S3_URL_PLACEHOLDER/index.html"
pip download --no-index --no-deps \
--find-links S3_URL_PLACEHOLDER/index.html \
ddtrace==VERSION_PLACEHOLDER \
$PIP_ARGS \
-d "${DEST_DIR}"

echo "Downloaded to ${DEST_DIR}"
DOWNLOAD_SCRIPT_EOF

# Replace placeholders in download.sh
sed -i.bak \
-e "s|S3_URL_PLACEHOLDER|${S3_BASE_URL}|g" \
-e "s|VERSION_PLACEHOLDER|${PACKAGE_VERSION}|g" \
"${OUTPUT_PREFIX}.download.sh"
rm "${OUTPUT_PREFIX}.download.sh.bak"

# Generate install.sh
cat > "${OUTPUT_PREFIX}.install.sh" << 'INSTALL_SCRIPT_EOF'
#!/usr/bin/env bash
set -euo pipefail

# Parse arguments
PIP_ARGS=""

while [[ $# -gt 0 ]]; do
case $1 in
--python-version)
PIP_ARGS="$PIP_ARGS --python-version $2"
shift 2
;;
--platform)
PIP_ARGS="$PIP_ARGS --platform $2"
shift 2
;;
*)
echo "Unknown option: $1" >&2
echo "Usage: $0 [--python-version VERSION] [--platform PLATFORM]" >&2
exit 1
;;
esac
done

# Create temp directory and ensure cleanup
TMP_DIR=$(mktemp -d)
trap "rm -rf '${TMP_DIR}'" EXIT

# Download and install
echo "Downloading ddtrace==VERSION_PLACEHOLDER from S3_URL_PLACEHOLDER/index.html"
pip download --no-index --no-deps \
--find-links S3_URL_PLACEHOLDER/index.html \
ddtrace==VERSION_PLACEHOLDER \
$PIP_ARGS \
-d "${TMP_DIR}"

echo "Installing ddtrace==VERSION_PLACEHOLDER"
pip install "${TMP_DIR}"/ddtrace-*.whl

echo "Successfully installed ddtrace==VERSION_PLACEHOLDER"
INSTALL_SCRIPT_EOF

# Replace placeholders in install.sh
sed -i.bak \
-e "s|S3_URL_PLACEHOLDER|${S3_BASE_URL}|g" \
-e "s|VERSION_PLACEHOLDER|${PACKAGE_VERSION}|g" \
"${OUTPUT_PREFIX}.install.sh"
rm "${OUTPUT_PREFIX}.install.sh.bak"

echo "Generated ${OUTPUT_PREFIX}.download.sh and ${OUTPUT_PREFIX}.install.sh"